~ubuntu-branches/ubuntu/saucy/gnome-settings-daemon/saucy-proposed

« back to all changes in this revision

Viewing changes to .pc/git_sound_not_polling.patch/plugins/sound/gsd-sound-manager.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha, Tim Lunn, Jeremy Bicha, Rico Tzschichholz
  • Date: 2013-09-09 10:21:09 UTC
  • mfrom: (1.1.64)
  • Revision ID: package-import@ubuntu.com-20130909102109-t2zyyll79urcfz56
Tags: 3.8.5-0ubuntu1
[ Tim Lunn ]
* Refreshed patches
* debian/patches: 
  - fix_media_keys_on_unity.patch:
    Use legacy media keys keygrabber when running Unity
  - git_revert_remove_automount_helper.patch: bring back the automount
    helper, revert upstream commit and port to dbus session tracking.
  - fix_screenshots_on_unity.patch: bring back support for screenshots
    via gnome-screenshot when using unity.
  - ubuntu-lid-close-suspend.patch:
     Reimplement support for setting lid close suspend actions
  - ubuntu-fix-desktop-file.patch: Autostart in Unity too
  - fix_input_switching_on_unity.patch: Bring back support for input
    switching under Unity
  - 63_gnome_disable_background_plugin.patch: Disable loading
    of background plugin for GNOME session (LP: #1219148)

* Dropped obsolete patches:
  - power-check-null-devices.patch, Dropped: Applied in new version
  - 51_lock_screen_on_suspend.patch, Superseded by handling this key
    in gnome-screensaver. With that, g-screensaver mirrors what's
    done in g-shell, and avoids patching settings-daemon.
* gnome-settings-daemon.gsettings-override:
  - Update switch input source keys for 3.8

[ Jeremy Bicha ]
* New upstream release (LP: #1219486)
  - Two-finger scrolling enabled by default (LP: #1217166)
  - But use edge scrolling if two-finger scrolling isn't
    available (LP: #1221367)
  - Fix Super+Space switch-input-source shortcut in Unity (LP: #1201679)
* debian/control.in:
  - Bump minimum glib, gsettings-desktop-schemas, gnome-desktop3, gtk,
    libpulse, and libwacom
  - Build-depend on librsvg2-dev
  - This update needs changes to gnome-control-center so break older
    versions
* Refreshed patches
* revert_background_dropping.patch:
  - Don't drop the background plugin yet, GNOME Fallback & Unity
    still need it (when Nautilus isn't handling the desktop)
* Dropped obsolete patches:
  - bugzilla_segfault_dpms.patch: Applied in new version
  - 47_delay_pa_connect_to_idle.patch: Applied in new version
  - power-no-fallback-notifications.patch: Applied in new version
  - 60_unity_hide_status_icon.patch
  - 61_unity_use_application_indicator.patch
  - 63_unity_start_mounter.patch
  - logind_support.patch
  - and patches backported from 3.8
* Disabled patch that need to be rewritten or dropped:
  - 48_register_client_before_idle_callbacks.patch
* debian/patches/touchscreen_rotation.patch:
  - Updated with latest version from bugzilla
* debian/patches/git_revert_hardcoded_input_methods.patch:
  - Add patch from git (and also applied in Fedora 19) to not hardcode
    input methods based on the current locale

[ Rico Tzschichholz ]
* debian/patches:
  - 16_use_synchronous_notifications.patch: Refreshed

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2
 
 *
3
 
 * Copyright (C) 2008 Lennart Poettering <lennart@poettering.net>
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 
 *
19
 
 */
20
 
 
21
 
#include "config.h"
22
 
 
23
 
#include <sys/types.h>
24
 
#include <sys/wait.h>
25
 
#include <stdlib.h>
26
 
#include <stdio.h>
27
 
#include <unistd.h>
28
 
#include <string.h>
29
 
#include <errno.h>
30
 
#include <signal.h>
31
 
 
32
 
#include <locale.h>
33
 
 
34
 
#include <glib.h>
35
 
#include <glib/gi18n.h>
36
 
#include <gtk/gtk.h>
37
 
#include <pulse/pulseaudio.h>
38
 
 
39
 
#include "gsd-sound-manager.h"
40
 
#include "gnome-settings-profile.h"
41
 
 
42
 
#define GSD_SOUND_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SOUND_MANAGER, GsdSoundManagerPrivate))
43
 
 
44
 
struct GsdSoundManagerPrivate
45
 
{
46
 
        GSettings *settings;
47
 
        GList     *monitors;
48
 
        guint      timeout;
49
 
};
50
 
 
51
 
static void gsd_sound_manager_class_init (GsdSoundManagerClass *klass);
52
 
static void gsd_sound_manager_init (GsdSoundManager *sound_manager);
53
 
static void gsd_sound_manager_finalize (GObject *object);
54
 
 
55
 
G_DEFINE_TYPE (GsdSoundManager, gsd_sound_manager, G_TYPE_OBJECT)
56
 
 
57
 
static gpointer manager_object = NULL;
58
 
 
59
 
static void
60
 
sample_info_cb (pa_context *c, const pa_sample_info *i, int eol, void *userdata)
61
 
{
62
 
        pa_operation *o;
63
 
 
64
 
        if (!i)
65
 
                return;
66
 
 
67
 
        g_debug ("Found sample %s", i->name);
68
 
 
69
 
        /* We only flush those samples which have an XDG sound name
70
 
         * attached, because only those originate from themeing  */
71
 
        if (!(pa_proplist_gets (i->proplist, PA_PROP_EVENT_ID)))
72
 
                return;
73
 
 
74
 
        g_debug ("Dropping sample %s from cache", i->name);
75
 
 
76
 
        if (!(o = pa_context_remove_sample (c, i->name, NULL, NULL))) {
77
 
                g_debug ("pa_context_remove_sample (): %s", pa_strerror (pa_context_errno (c)));
78
 
                return;
79
 
        }
80
 
 
81
 
        pa_operation_unref (o);
82
 
 
83
 
        /* We won't wait until the operation is actually executed to
84
 
         * speed things up a bit.*/
85
 
}
86
 
 
87
 
static void
88
 
flush_cache (void)
89
 
{
90
 
        pa_mainloop *ml = NULL;
91
 
        pa_context *c = NULL;
92
 
        pa_proplist *pl = NULL;
93
 
        pa_operation *o = NULL;
94
 
 
95
 
        g_debug ("Flushing sample cache");
96
 
 
97
 
        if (!(ml = pa_mainloop_new ())) {
98
 
                g_debug ("Failed to allocate pa_mainloop");
99
 
                goto fail;
100
 
        }
101
 
 
102
 
        if (!(pl = pa_proplist_new ())) {
103
 
                g_debug ("Failed to allocate pa_proplist");
104
 
                goto fail;
105
 
        }
106
 
 
107
 
        pa_proplist_sets (pl, PA_PROP_APPLICATION_NAME, PACKAGE_NAME);
108
 
        pa_proplist_sets (pl, PA_PROP_APPLICATION_VERSION, PACKAGE_VERSION);
109
 
        pa_proplist_sets (pl, PA_PROP_APPLICATION_ID, "org.gnome.SettingsDaemon");
110
 
 
111
 
        if (!(c = pa_context_new_with_proplist (pa_mainloop_get_api (ml), PACKAGE_NAME, pl))) {
112
 
                g_debug ("Failed to allocate pa_context");
113
 
                goto fail;
114
 
        }
115
 
 
116
 
        pa_proplist_free (pl);
117
 
        pl = NULL;
118
 
 
119
 
        if (pa_context_connect (c, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL) < 0) {
120
 
                g_debug ("pa_context_connect(): %s", pa_strerror (pa_context_errno (c)));
121
 
                goto fail;
122
 
        }
123
 
 
124
 
        /* Wait until the connection is established */
125
 
        while (pa_context_get_state (c) != PA_CONTEXT_READY) {
126
 
 
127
 
                if (!PA_CONTEXT_IS_GOOD (pa_context_get_state (c))) {
128
 
                        g_debug ("Connection failed: %s", pa_strerror (pa_context_errno (c)));
129
 
                        goto fail;
130
 
                }
131
 
 
132
 
                if (pa_mainloop_iterate (ml, TRUE, NULL) < 0) {
133
 
                        g_debug ("pa_mainloop_iterate() failed");
134
 
                        goto fail;
135
 
                }
136
 
        }
137
 
 
138
 
        /* Enumerate all cached samples */
139
 
        if (!(o = pa_context_get_sample_info_list (c, sample_info_cb, NULL))) {
140
 
                g_debug ("pa_context_get_sample_info_list(): %s", pa_strerror (pa_context_errno (c)));
141
 
                goto fail;
142
 
        }
143
 
 
144
 
        /* Wait until our operation is finished and there's nothing
145
 
         * more queued to send to the server */
146
 
        while (pa_operation_get_state (o) == PA_OPERATION_RUNNING || pa_context_is_pending (c)) {
147
 
 
148
 
                if (!PA_CONTEXT_IS_GOOD (pa_context_get_state (c))) {
149
 
                        g_debug ("Connection failed: %s", pa_strerror (pa_context_errno (c)));
150
 
                        goto fail;
151
 
                }
152
 
 
153
 
                if (pa_mainloop_iterate (ml, TRUE, NULL) < 0) {
154
 
                        g_debug ("pa_mainloop_iterate() failed");
155
 
                        goto fail;
156
 
                }
157
 
        }
158
 
 
159
 
        g_debug ("Sample cache flushed");
160
 
 
161
 
fail:
162
 
        if (o) {
163
 
                pa_operation_cancel (o);
164
 
                pa_operation_unref (o);
165
 
        }
166
 
 
167
 
        if (c) {
168
 
                pa_context_disconnect (c);
169
 
                pa_context_unref (c);
170
 
        }
171
 
 
172
 
        if (pl)
173
 
                pa_proplist_free (pl);
174
 
 
175
 
        if (ml)
176
 
                pa_mainloop_free (ml);
177
 
}
178
 
 
179
 
static gboolean
180
 
flush_cb (GsdSoundManager *manager)
181
 
{
182
 
        flush_cache ();
183
 
        manager->priv->timeout = 0;
184
 
        return FALSE;
185
 
}
186
 
 
187
 
static void
188
 
trigger_flush (GsdSoundManager *manager)
189
 
{
190
 
 
191
 
        if (manager->priv->timeout)
192
 
                g_source_remove (manager->priv->timeout);
193
 
 
194
 
        /* We delay the flushing a bit so that we can coalesce
195
 
         * multiple changes into a single cache flush */
196
 
        manager->priv->timeout = g_timeout_add (500, (GSourceFunc) flush_cb, manager);
197
 
}
198
 
 
199
 
static void
200
 
settings_changed_cb (GSettings       *settings,
201
 
                     const char      *key,
202
 
                     GsdSoundManager *manager)
203
 
{
204
 
        trigger_flush (manager);
205
 
}
206
 
 
207
 
static void
208
 
register_config_callback (GsdSoundManager *manager)
209
 
{
210
 
        manager->priv->settings = g_settings_new ("org.gnome.desktop.sound");
211
 
        g_signal_connect (G_OBJECT (manager->priv->settings), "changed",
212
 
                          G_CALLBACK (settings_changed_cb), manager);
213
 
}
214
 
 
215
 
static void
216
 
file_monitor_changed_cb (GFileMonitor *monitor,
217
 
                         GFile *file,
218
 
                         GFile *other_file,
219
 
                         GFileMonitorEvent event,
220
 
                         GsdSoundManager *manager)
221
 
{
222
 
        g_debug ("Theme dir changed");
223
 
        trigger_flush (manager);
224
 
}
225
 
 
226
 
static gboolean
227
 
register_directory_callback (GsdSoundManager *manager,
228
 
                             const char *path,
229
 
                             GError **error)
230
 
{
231
 
        GFile *f;
232
 
        GFileMonitor *m;
233
 
        gboolean succ = FALSE;
234
 
 
235
 
        g_debug ("Registering directory monitor for %s", path);
236
 
 
237
 
        f = g_file_new_for_path (path);
238
 
 
239
 
        m = g_file_monitor_directory (f, 0, NULL, error);
240
 
 
241
 
        if (m != NULL) {
242
 
                g_signal_connect (m, "changed", G_CALLBACK (file_monitor_changed_cb), manager);
243
 
 
244
 
                manager->priv->monitors = g_list_prepend (manager->priv->monitors, m);
245
 
 
246
 
                succ = TRUE;
247
 
        }
248
 
 
249
 
        g_object_unref (f);
250
 
 
251
 
        return succ;
252
 
}
253
 
 
254
 
gboolean
255
 
gsd_sound_manager_start (GsdSoundManager *manager,
256
 
                         GError **error)
257
 
{
258
 
        guint i;
259
 
        const gchar * const * dirs;
260
 
        char *p;
261
 
 
262
 
        g_debug ("Starting sound manager");
263
 
        gnome_settings_profile_start (NULL);
264
 
 
265
 
        /* We listen for change of the selected theme ... */
266
 
        register_config_callback (manager);
267
 
 
268
 
        /* ... and we listen to changes of the theme base directories
269
 
         * in $HOME ...*/
270
 
        p = g_build_filename (g_get_user_data_dir (), "sounds", NULL);
271
 
        register_directory_callback (manager, p, NULL);
272
 
        g_free (p);
273
 
 
274
 
        /* ... and globally. */
275
 
        dirs = g_get_system_data_dirs ();
276
 
        for (i = 0; dirs[i] != NULL; i++) {
277
 
                p = g_build_filename (dirs[i], "sounds", NULL);
278
 
                register_directory_callback (manager, p, NULL);
279
 
                g_free (p);
280
 
        }
281
 
 
282
 
        gnome_settings_profile_end (NULL);
283
 
 
284
 
        return TRUE;
285
 
}
286
 
 
287
 
void
288
 
gsd_sound_manager_stop (GsdSoundManager *manager)
289
 
{
290
 
        g_debug ("Stopping sound manager");
291
 
 
292
 
        if (manager->priv->settings != NULL) {
293
 
                g_object_unref (manager->priv->settings);
294
 
                manager->priv->settings = NULL;
295
 
        }
296
 
 
297
 
        if (manager->priv->timeout) {
298
 
                g_source_remove (manager->priv->timeout);
299
 
                manager->priv->timeout = 0;
300
 
        }
301
 
 
302
 
        while (manager->priv->monitors) {
303
 
                g_file_monitor_cancel (G_FILE_MONITOR (manager->priv->monitors->data));
304
 
                g_object_unref (manager->priv->monitors->data);
305
 
                manager->priv->monitors = g_list_delete_link (manager->priv->monitors, manager->priv->monitors);
306
 
        }
307
 
}
308
 
 
309
 
static GObject *
310
 
gsd_sound_manager_constructor (
311
 
                GType type,
312
 
                guint n_construct_properties,
313
 
                GObjectConstructParam *construct_properties)
314
 
{
315
 
        GsdSoundManager *m;
316
 
 
317
 
        m = GSD_SOUND_MANAGER (G_OBJECT_CLASS (gsd_sound_manager_parent_class)->constructor (
318
 
                                                           type,
319
 
                                                           n_construct_properties,
320
 
                                                           construct_properties));
321
 
 
322
 
        return G_OBJECT (m);
323
 
}
324
 
 
325
 
static void
326
 
gsd_sound_manager_dispose (GObject *object)
327
 
{
328
 
        GsdSoundManager *manager;
329
 
 
330
 
        manager = GSD_SOUND_MANAGER (object);
331
 
 
332
 
        gsd_sound_manager_stop (manager);
333
 
 
334
 
        G_OBJECT_CLASS (gsd_sound_manager_parent_class)->dispose (object);
335
 
}
336
 
 
337
 
static void
338
 
gsd_sound_manager_class_init (GsdSoundManagerClass *klass)
339
 
{
340
 
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
341
 
 
342
 
        object_class->constructor = gsd_sound_manager_constructor;
343
 
        object_class->dispose = gsd_sound_manager_dispose;
344
 
        object_class->finalize = gsd_sound_manager_finalize;
345
 
 
346
 
        g_type_class_add_private (klass, sizeof (GsdSoundManagerPrivate));
347
 
}
348
 
 
349
 
static void
350
 
gsd_sound_manager_init (GsdSoundManager *manager)
351
 
{
352
 
        manager->priv = GSD_SOUND_MANAGER_GET_PRIVATE (manager);
353
 
}
354
 
 
355
 
static void
356
 
gsd_sound_manager_finalize (GObject *object)
357
 
{
358
 
        GsdSoundManager *sound_manager;
359
 
 
360
 
        g_return_if_fail (object != NULL);
361
 
        g_return_if_fail (GSD_IS_SOUND_MANAGER (object));
362
 
 
363
 
        sound_manager = GSD_SOUND_MANAGER (object);
364
 
 
365
 
        g_return_if_fail (sound_manager->priv);
366
 
 
367
 
        G_OBJECT_CLASS (gsd_sound_manager_parent_class)->finalize (object);
368
 
}
369
 
 
370
 
GsdSoundManager *
371
 
gsd_sound_manager_new (void)
372
 
{
373
 
        if (manager_object) {
374
 
                g_object_ref (manager_object);
375
 
        } else {
376
 
                manager_object = g_object_new (GSD_TYPE_SOUND_MANAGER, NULL);
377
 
                g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object);
378
 
        }
379
 
 
380
 
        return GSD_SOUND_MANAGER (manager_object);
381
 
}