Merge lp:~bbboson/ubuntu/precise/gnome-control-center/fix-for-1236612 into lp:ubuntu/precise-updates/gnome-control-center

Proposed by Madper Xie
Status: Merged
Merge reported by: Sebastien Bacher
Merged at revision: not available
Proposed branch: lp:~bbboson/ubuntu/precise/gnome-control-center/fix-for-1236612
Merge into: lp:ubuntu/precise-updates/gnome-control-center
Diff against target: 902 lines (+854/-0)
6 files modified
.pc/applied-patches (+1/-0)
.pc/sound-fix-potential-memory-corruption.patch/panels/sound/gvc-sound-theme-chooser.c (+833/-0)
debian/changelog (+6/-0)
debian/patches/series (+1/-0)
debian/patches/sound-fix-potential-memory-corruption.patch (+12/-0)
panels/sound/gvc-sound-theme-chooser.c (+1/-0)
To merge this branch: bzr merge lp:~bbboson/ubuntu/precise/gnome-control-center/fix-for-1236612
Reviewer Review Type Date Requested Status
Sebastien Bacher Approve
Review via email: mp+225776@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Sebastien Bacher (seb128) wrote :

Thanks, the vcs to use is lp:~ubuntu-desktop/gnome-control-center/precise (see debian/control), I've merged there and uploaded for you

review: Approve
Revision history for this message
Sebastien Bacher (seb128) wrote :

(could you make the bug SRU compliant, see https://wiki.ubuntu.com/StableReleaseUpdates)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.pc/applied-patches'
--- .pc/applied-patches 2014-04-02 10:52:39 +0000
+++ .pc/applied-patches 2014-07-07 05:56:11 +0000
@@ -44,3 +44,4 @@
44use_rfkill_airplane_mode.patch44use_rfkill_airplane_mode.patch
45more-power-suspend-options.patch45more-power-suspend-options.patch
46fix-input-device-bar-status.patch46fix-input-device-bar-status.patch
47sound-fix-potential-memory-corruption.patch
4748
=== added directory '.pc/sound-fix-potential-memory-corruption.patch'
=== added file '.pc/sound-fix-potential-memory-corruption.patch/.timestamp'
=== added directory '.pc/sound-fix-potential-memory-corruption.patch/panels'
=== added directory '.pc/sound-fix-potential-memory-corruption.patch/panels/sound'
=== added file '.pc/sound-fix-potential-memory-corruption.patch/panels/sound/gvc-sound-theme-chooser.c'
--- .pc/sound-fix-potential-memory-corruption.patch/panels/sound/gvc-sound-theme-chooser.c 1970-01-01 00:00:00 +0000
+++ .pc/sound-fix-potential-memory-corruption.patch/panels/sound/gvc-sound-theme-chooser.c 2014-07-07 05:56:11 +0000
@@ -0,0 +1,833 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
4 * Copyright (C) 2008 William Jon McCann
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22#include "config.h"
23
24#include <stdlib.h>
25#include <stdio.h>
26#include <unistd.h>
27#include <utime.h>
28#include <errno.h>
29
30#include <glib.h>
31#include <glib/gi18n-lib.h>
32#include <gtk/gtk.h>
33#include <canberra-gtk.h>
34#include <libxml/tree.h>
35
36#include <gsettings-desktop-schemas/gdesktop-enums.h>
37
38#include "gvc-sound-theme-chooser.h"
39#include "sound-theme-file-utils.h"
40
41#define GVC_SOUND_THEME_CHOOSER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_SOUND_THEME_CHOOSER, GvcSoundThemeChooserPrivate))
42
43struct GvcSoundThemeChooserPrivate
44{
45 GtkWidget *treeview;
46 GtkWidget *selection_box;
47 GSettings *settings;
48 GSettings *sound_settings;
49 char *current_theme;
50 char *current_parent;
51};
52
53static void gvc_sound_theme_chooser_class_init (GvcSoundThemeChooserClass *klass);
54static void gvc_sound_theme_chooser_init (GvcSoundThemeChooser *sound_theme_chooser);
55static void gvc_sound_theme_chooser_finalize (GObject *object);
56
57G_DEFINE_TYPE (GvcSoundThemeChooser, gvc_sound_theme_chooser, GTK_TYPE_VBOX)
58
59#define KEY_SOUNDS_SCHEMA "org.gnome.desktop.sound"
60#define EVENT_SOUNDS_KEY "event-sounds"
61#define INPUT_SOUNDS_KEY "input-feedback-sounds"
62#define SOUND_THEME_KEY "theme-name"
63
64#define WM_SCHEMA "org.gnome.desktop.wm.preferences"
65#define AUDIO_BELL_KEY "audible-bell"
66
67#define DEFAULT_ALERT_ID "__default"
68#define CUSTOM_THEME_NAME "__custom"
69#define NO_SOUNDS_THEME_NAME "__no_sounds"
70#define DEFAULT_THEME "ubuntu"
71
72enum {
73 THEME_DISPLAY_COL,
74 THEME_IDENTIFIER_COL,
75 THEME_PARENT_ID_COL,
76 THEME_NUM_COLS
77};
78
79enum {
80 ALERT_DISPLAY_COL,
81 ALERT_IDENTIFIER_COL,
82 ALERT_SOUND_TYPE_COL,
83 ALERT_NUM_COLS
84};
85
86enum {
87 SOUND_TYPE_UNSET,
88 SOUND_TYPE_OFF,
89 SOUND_TYPE_DEFAULT_FROM_THEME,
90 SOUND_TYPE_BUILTIN,
91 SOUND_TYPE_CUSTOM
92};
93
94#define GVC_SOUND_SOUND (xmlChar *) "sound"
95#define GVC_SOUND_NAME (xmlChar *) "name"
96#define GVC_SOUND_FILENAME (xmlChar *) "filename"
97
98/* Adapted from yelp-toc-pager.c */
99static xmlChar *
100xml_get_and_trim_names (xmlNodePtr node)
101{
102 xmlNodePtr cur;
103 xmlChar *keep_lang = NULL;
104 xmlChar *value;
105 int j, keep_pri = INT_MAX;
106
107 const gchar * const * langs = g_get_language_names ();
108
109 value = NULL;
110
111 for (cur = node->children; cur; cur = cur->next) {
112 if (! xmlStrcmp (cur->name, GVC_SOUND_NAME)) {
113 xmlChar *cur_lang = NULL;
114 int cur_pri = INT_MAX;
115
116 cur_lang = xmlNodeGetLang (cur);
117
118 if (cur_lang) {
119 for (j = 0; langs[j]; j++) {
120 if (g_str_equal (cur_lang, langs[j])) {
121 cur_pri = j;
122 break;
123 }
124 }
125 } else {
126 cur_pri = INT_MAX - 1;
127 }
128
129 if (cur_pri <= keep_pri) {
130 if (keep_lang)
131 xmlFree (keep_lang);
132 if (value)
133 xmlFree (value);
134
135 value = xmlNodeGetContent (cur);
136
137 keep_lang = cur_lang;
138 keep_pri = cur_pri;
139 } else {
140 if (cur_lang)
141 xmlFree (cur_lang);
142 }
143 }
144 }
145
146 /* Delete all GVC_SOUND_NAME nodes */
147 cur = node->children;
148 while (cur) {
149 xmlNodePtr this = cur;
150 cur = cur->next;
151 if (! xmlStrcmp (this->name, GVC_SOUND_NAME)) {
152 xmlUnlinkNode (this);
153 xmlFreeNode (this);
154 }
155 }
156
157 return value;
158}
159
160static void
161populate_model_from_node (GvcSoundThemeChooser *chooser,
162 GtkTreeModel *model,
163 xmlNodePtr node)
164{
165 xmlNodePtr child;
166 xmlChar *filename;
167 xmlChar *name;
168
169 filename = NULL;
170 name = xml_get_and_trim_names (node);
171 for (child = node->children; child; child = child->next) {
172 if (xmlNodeIsText (child)) {
173 continue;
174 }
175
176 if (xmlStrcmp (child->name, GVC_SOUND_FILENAME) == 0) {
177 filename = xmlNodeGetContent (child);
178 } else if (xmlStrcmp (child->name, GVC_SOUND_NAME) == 0) {
179 /* EH? should have been trimmed */
180 }
181 }
182
183 if (filename != NULL && name != NULL) {
184 gtk_list_store_insert_with_values (GTK_LIST_STORE (model),
185 NULL,
186 G_MAXINT,
187 ALERT_IDENTIFIER_COL, filename,
188 ALERT_DISPLAY_COL, name,
189 ALERT_SOUND_TYPE_COL, _("Built-in"),
190 -1);
191 }
192
193 xmlFree (filename);
194 xmlFree (name);
195}
196
197static void
198populate_model_from_file (GvcSoundThemeChooser *chooser,
199 GtkTreeModel *model,
200 const char *filename)
201{
202 xmlDocPtr doc;
203 xmlNodePtr root;
204 xmlNodePtr child;
205 gboolean exists;
206
207 exists = g_file_test (filename, G_FILE_TEST_EXISTS);
208 if (! exists) {
209 return;
210 }
211
212 doc = xmlParseFile (filename);
213 if (doc == NULL) {
214 return;
215 }
216
217 root = xmlDocGetRootElement (doc);
218
219 for (child = root->children; child; child = child->next) {
220 if (xmlNodeIsText (child)) {
221 continue;
222 }
223 if (xmlStrcmp (child->name, GVC_SOUND_SOUND) != 0) {
224 continue;
225 }
226
227 populate_model_from_node (chooser, model, child);
228 }
229
230 xmlFreeDoc (doc);
231}
232
233static void
234populate_model_from_dir (GvcSoundThemeChooser *chooser,
235 GtkTreeModel *model,
236 const char *dirname)
237{
238 GDir *d;
239 const char *name;
240
241 d = g_dir_open (dirname, 0, NULL);
242 if (d == NULL) {
243 return;
244 }
245
246 while ((name = g_dir_read_name (d)) != NULL) {
247 char *path;
248
249 if (! g_str_has_suffix (name, ".xml")) {
250 continue;
251 }
252
253 path = g_build_filename (dirname, name, NULL);
254 populate_model_from_file (chooser, model, path);
255 g_free (path);
256 }
257}
258
259static gboolean
260save_alert_sounds (GvcSoundThemeChooser *chooser,
261 const char *id)
262{
263 const char *sounds[3] = { "bell-terminal", "bell-window-system", NULL };
264 char *path;
265
266 if (strcmp (id, DEFAULT_ALERT_ID) == 0) {
267 delete_old_files (sounds);
268 delete_disabled_files (sounds);
269 } else {
270 delete_old_files (sounds);
271 delete_disabled_files (sounds);
272 add_custom_file (sounds, id);
273 }
274
275 /* And poke the directory so the theme gets updated */
276 path = custom_theme_dir_path (NULL);
277 if (utime (path, NULL) != 0) {
278 g_warning ("Failed to update mtime for directory '%s': %s",
279 path, g_strerror (errno));
280 }
281 g_free (path);
282
283 return FALSE;
284}
285
286
287static void
288update_alert_model (GvcSoundThemeChooser *chooser,
289 const char *id)
290{
291 GtkTreeModel *model;
292 GtkTreeIter iter;
293
294 model = gtk_tree_view_get_model (GTK_TREE_VIEW (chooser->priv->treeview));
295 gtk_tree_model_get_iter_first (model, &iter);
296 do {
297 char *this_id;
298
299 gtk_tree_model_get (model, &iter,
300 ALERT_IDENTIFIER_COL, &this_id,
301 -1);
302
303 if (strcmp (this_id, id) == 0) {
304 GtkTreeSelection *selection;
305
306 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (chooser->priv->treeview));
307 gtk_tree_selection_select_iter (selection, &iter);
308 }
309
310 g_free (this_id);
311 } while (gtk_tree_model_iter_next (model, &iter));
312}
313
314static void
315save_theme_name (GvcSoundThemeChooser *chooser,
316 const char *theme_name)
317{
318 /* If the name is empty, use "freedesktop" */
319 if (theme_name == NULL || *theme_name == '\0') {
320 theme_name = DEFAULT_THEME;
321 }
322
323 /* special case for no sounds */
324 if (strcmp (theme_name, NO_SOUNDS_THEME_NAME) == 0) {
325 g_settings_set_boolean (chooser->priv->sound_settings, EVENT_SOUNDS_KEY, FALSE);
326 return;
327 } else {
328 g_settings_set_boolean (chooser->priv->sound_settings, EVENT_SOUNDS_KEY, TRUE);
329 }
330
331 g_settings_set_string (chooser->priv->sound_settings, SOUND_THEME_KEY, theme_name);
332}
333
334static gboolean
335load_theme_file (const char *path,
336 char **parent)
337{
338 GKeyFile *file;
339 gboolean hidden;
340
341 file = g_key_file_new ();
342 if (g_key_file_load_from_file (file, path, G_KEY_FILE_KEEP_TRANSLATIONS, NULL) == FALSE) {
343 g_key_file_free (file);
344 return FALSE;
345 }
346 /* Don't add hidden themes to the list */
347 hidden = g_key_file_get_boolean (file, "Sound Theme", "Hidden", NULL);
348 if (!hidden) {
349 /* Save the parent theme, if there's one */
350 if (parent != NULL) {
351 *parent = g_key_file_get_string (file,
352 "Sound Theme",
353 "Inherits",
354 NULL);
355 }
356 }
357
358 g_key_file_free (file);
359
360 return TRUE;
361}
362
363static gboolean
364load_theme_name (const char *name,
365 char **parent)
366{
367 const char * const *data_dirs;
368 const char *data_dir;
369 char *path;
370 guint i;
371 gboolean res;
372
373 data_dir = g_get_user_data_dir ();
374 path = g_build_filename (data_dir, "sounds", name, "index.theme", NULL);
375 res = load_theme_file (path, parent);
376 g_free (path);
377 if (res)
378 return TRUE;
379
380 data_dirs = g_get_system_data_dirs ();
381 for (i = 0; data_dirs[i] != NULL; i++) {
382 path = g_build_filename (data_dirs[i], "sounds", name, "index.theme", NULL);
383 res = load_theme_file (path, parent);
384 g_free (path);
385 if (res)
386 return TRUE;
387 }
388
389 return FALSE;
390}
391
392static void
393update_alert (GvcSoundThemeChooser *chooser,
394 const char *alert_id)
395{
396 gboolean is_custom;
397 gboolean is_default;
398 gboolean add_custom;
399 gboolean remove_custom;
400
401 is_custom = strcmp (chooser->priv->current_theme, CUSTOM_THEME_NAME) == 0;
402 is_default = strcmp (alert_id, DEFAULT_ALERT_ID) == 0;
403
404 /* So a few possibilities:
405 * 1. Named theme, default alert selected: noop
406 * 2. Named theme, alternate alert selected: create new custom with sound
407 * 3. Custom theme, default alert selected: remove sound and possibly custom
408 * 4. Custom theme, alternate alert selected: update custom sound
409 */
410 add_custom = FALSE;
411 remove_custom = FALSE;
412 if (! is_custom && is_default) {
413 /* remove custom just in case */
414 remove_custom = TRUE;
415 } else if (! is_custom && ! is_default) {
416 if (chooser->priv->current_parent)
417 create_custom_theme (chooser->priv->current_parent);
418 else
419 create_custom_theme (DEFAULT_THEME);
420 save_alert_sounds (chooser, alert_id);
421 add_custom = TRUE;
422 } else if (is_custom && is_default) {
423 save_alert_sounds (chooser, alert_id);
424 /* after removing files check if it is empty */
425 if (custom_theme_dir_is_empty ()) {
426 remove_custom = TRUE;
427 }
428 } else if (is_custom && ! is_default) {
429 save_alert_sounds (chooser, alert_id);
430 }
431
432 if (add_custom) {
433 save_theme_name (chooser, CUSTOM_THEME_NAME);
434 } else if (remove_custom) {
435 delete_custom_theme_dir ();
436 if (is_custom) {
437 save_theme_name (chooser, chooser->priv->current_parent);
438 }
439 }
440
441 update_alert_model (chooser, alert_id);
442}
443
444static void
445play_preview_for_id (GvcSoundThemeChooser *chooser,
446 const char *id)
447{
448 g_return_if_fail (id != NULL);
449
450 /* special case: for the default item on custom themes
451 * play the alert for the parent theme */
452 if (strcmp (id, DEFAULT_ALERT_ID) == 0) {
453 if (chooser->priv->current_parent != NULL) {
454 ca_gtk_play_for_widget (GTK_WIDGET (chooser), 0,
455 CA_PROP_APPLICATION_NAME, _("Sound Preferences"),
456 CA_PROP_EVENT_ID, "bell-window-system",
457 CA_PROP_CANBERRA_XDG_THEME_NAME, chooser->priv->current_parent,
458 CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"),
459 CA_PROP_CANBERRA_CACHE_CONTROL, "never",
460 CA_PROP_APPLICATION_ID, "org.gnome.VolumeControl",
461#ifdef CA_PROP_CANBERRA_ENABLE
462 CA_PROP_CANBERRA_ENABLE, "1",
463#endif
464 NULL);
465 } else {
466 ca_gtk_play_for_widget (GTK_WIDGET (chooser), 0,
467 CA_PROP_APPLICATION_NAME, _("Sound Preferences"),
468 CA_PROP_EVENT_ID, "bell-window-system",
469 CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"),
470 CA_PROP_CANBERRA_CACHE_CONTROL, "never",
471 CA_PROP_APPLICATION_ID, "org.gnome.VolumeControl",
472#ifdef CA_PROP_CANBERRA_ENABLE
473 CA_PROP_CANBERRA_ENABLE, "1",
474#endif
475 NULL);
476 }
477 } else {
478 ca_gtk_play_for_widget (GTK_WIDGET (chooser), 0,
479 CA_PROP_APPLICATION_NAME, _("Sound Preferences"),
480 CA_PROP_MEDIA_FILENAME, id,
481 CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"),
482 CA_PROP_CANBERRA_CACHE_CONTROL, "never",
483 CA_PROP_APPLICATION_ID, "org.gnome.VolumeControl",
484#ifdef CA_PROP_CANBERRA_ENABLE
485 CA_PROP_CANBERRA_ENABLE, "1",
486#endif
487 NULL);
488
489 }
490}
491
492static void
493on_treeview_selection_changed (GtkTreeSelection *selection,
494 GvcSoundThemeChooser *chooser)
495{
496 GtkTreeModel *model;
497 GtkTreeIter iter;
498 char *id;
499
500 if (chooser->priv->treeview == NULL) {
501 return;
502 }
503
504 model = gtk_tree_view_get_model (GTK_TREE_VIEW (chooser->priv->treeview));
505
506 if (gtk_tree_selection_get_selected (selection, &model, &iter) == FALSE) {
507 return;
508 }
509
510 id = NULL;
511 gtk_tree_model_get (model, &iter,
512 ALERT_IDENTIFIER_COL, &id,
513 -1);
514 if (id == NULL) {
515 return;
516 }
517
518 play_preview_for_id (chooser, id);
519 update_alert (chooser, id);
520 g_free (id);
521}
522
523static gboolean
524on_treeview_button_pressed (GtkTreeView *treeview,
525 GdkEventButton *event,
526 GvcSoundThemeChooser *chooser)
527{
528 GtkTreeSelection *selection;
529 GtkTreePath *path;
530
531 selection = gtk_tree_view_get_selection (treeview);
532 if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (treeview),
533 event->x, event->y, &path, NULL, NULL, NULL) == FALSE) {
534 return FALSE;
535 }
536
537 if (gtk_tree_selection_path_is_selected (selection, path) == FALSE) {
538 gtk_tree_path_free (path);
539 return FALSE;
540 }
541 gtk_tree_path_free (path);
542
543 on_treeview_selection_changed (selection, chooser);
544
545 return FALSE;
546}
547
548static GtkWidget *
549create_alert_treeview (GvcSoundThemeChooser *chooser)
550{
551 GtkListStore *store;
552 GtkWidget *treeview;
553 GtkCellRenderer *renderer;
554 GtkTreeViewColumn *column;
555 GtkTreeSelection *selection;
556
557 treeview = gtk_tree_view_new ();
558 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
559 g_signal_connect (treeview,
560 "button-press-event",
561 G_CALLBACK (on_treeview_button_pressed),
562 chooser);
563
564 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
565 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
566 g_signal_connect (selection,
567 "changed",
568 G_CALLBACK (on_treeview_selection_changed),
569 chooser);
570
571 /* Setup the tree model, 3 columns:
572 * - display name
573 * - sound id
574 * - sound type
575 */
576 store = gtk_list_store_new (ALERT_NUM_COLS,
577 G_TYPE_STRING,
578 G_TYPE_STRING,
579 G_TYPE_STRING);
580
581 gtk_list_store_insert_with_values (store,
582 NULL,
583 G_MAXINT,
584 ALERT_IDENTIFIER_COL, DEFAULT_ALERT_ID,
585 ALERT_DISPLAY_COL, _("Default"),
586 ALERT_SOUND_TYPE_COL, _("From theme"),
587 -1);
588
589 populate_model_from_dir (chooser, GTK_TREE_MODEL (store), SOUND_SET_DIR);
590
591 gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
592 GTK_TREE_MODEL (store));
593
594 renderer = gtk_cell_renderer_text_new ();
595 column = gtk_tree_view_column_new_with_attributes (_("Name"),
596 renderer,
597 "text", ALERT_DISPLAY_COL,
598 NULL);
599 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
600
601 return treeview;
602}
603
604static int
605get_file_type (const char *sound_name,
606 char **linked_name)
607{
608 char *name, *filename;
609
610 *linked_name = NULL;
611
612 name = g_strdup_printf ("%s.disabled", sound_name);
613 filename = custom_theme_dir_path (name);
614 g_free (name);
615
616 if (g_file_test (filename, G_FILE_TEST_IS_REGULAR) != FALSE) {
617 g_free (filename);
618 return SOUND_TYPE_OFF;
619 }
620 g_free (filename);
621
622 /* We only check for .ogg files because those are the
623 * only ones we create */
624 name = g_strdup_printf ("%s.ogg", sound_name);
625 filename = custom_theme_dir_path (name);
626 g_free (name);
627
628 if (g_file_test (filename, G_FILE_TEST_IS_SYMLINK) != FALSE) {
629 *linked_name = g_file_read_link (filename, NULL);
630 g_free (filename);
631 return SOUND_TYPE_CUSTOM;
632 }
633 g_free (filename);
634
635 return SOUND_TYPE_BUILTIN;
636}
637
638static void
639update_alerts_from_theme_name (GvcSoundThemeChooser *chooser,
640 const char *name)
641{
642 if (strcmp (name, CUSTOM_THEME_NAME) != 0) {
643 /* reset alert to default */
644 update_alert (chooser, DEFAULT_ALERT_ID);
645 } else {
646 int sound_type;
647 char *linkname;
648
649 linkname = NULL;
650 sound_type = get_file_type ("bell-terminal", &linkname);
651 g_debug ("Found link: %s", linkname);
652 if (sound_type == SOUND_TYPE_CUSTOM) {
653 update_alert (chooser, linkname);
654 }
655 }
656}
657
658static void
659update_theme (GvcSoundThemeChooser *chooser)
660{
661 gboolean events_enabled;
662 char *last_theme;
663
664 events_enabled = g_settings_get_boolean (chooser->priv->sound_settings, EVENT_SOUNDS_KEY);
665
666 last_theme = chooser->priv->current_theme;
667 if (events_enabled) {
668 chooser->priv->current_theme = g_settings_get_string (chooser->priv->sound_settings, SOUND_THEME_KEY);
669 } else {
670 chooser->priv->current_theme = g_strdup (NO_SOUNDS_THEME_NAME);
671 }
672
673 if (g_strcmp0 (last_theme, chooser->priv->current_theme) != 0) {
674 g_free (chooser->priv->current_parent);
675 if (load_theme_name (chooser->priv->current_theme,
676 &chooser->priv->current_parent) == FALSE) {
677 g_free (chooser->priv->current_theme);
678 chooser->priv->current_theme = g_strdup (DEFAULT_THEME);
679 load_theme_name (DEFAULT_THEME,
680 &chooser->priv->current_parent);
681 }
682 }
683 g_free (last_theme);
684
685 gtk_widget_set_sensitive (chooser->priv->selection_box, events_enabled);
686
687 update_alerts_from_theme_name (chooser, chooser->priv->current_theme);
688}
689
690static GObject *
691gvc_sound_theme_chooser_constructor (GType type,
692 guint n_construct_properties,
693 GObjectConstructParam *construct_params)
694{
695 GObject *object;
696 GvcSoundThemeChooser *self;
697
698 object = G_OBJECT_CLASS (gvc_sound_theme_chooser_parent_class)->constructor (type, n_construct_properties, construct_params);
699
700 self = GVC_SOUND_THEME_CHOOSER (object);
701
702 update_theme (self);
703
704 return object;
705}
706
707static void
708gvc_sound_theme_chooser_class_init (GvcSoundThemeChooserClass *klass)
709{
710 GObjectClass *object_class = G_OBJECT_CLASS (klass);
711
712 object_class->constructor = gvc_sound_theme_chooser_constructor;
713 object_class->finalize = gvc_sound_theme_chooser_finalize;
714
715 g_type_class_add_private (klass, sizeof (GvcSoundThemeChooserPrivate));
716}
717
718static void
719on_sound_settings_changed (GSettings *settings,
720 const char *key,
721 GvcSoundThemeChooser *chooser)
722{
723 if (strcmp (key, EVENT_SOUNDS_KEY) == 0) {
724 update_theme (chooser);
725 } else if (strcmp (key, SOUND_THEME_KEY) == 0) {
726 update_theme (chooser);
727 } else if (strcmp (key, INPUT_SOUNDS_KEY) == 0) {
728 update_theme (chooser);
729 }
730}
731
732static void
733on_audible_bell_changed (GSettings *settings,
734 const char *key,
735 GvcSoundThemeChooser *chooser)
736{
737 update_theme (chooser);
738}
739
740static void
741setup_list_size_constraint (GtkWidget *widget,
742 GtkWidget *to_size)
743{
744 GtkRequisition req;
745 int max_height;
746
747 /* constrain height to be the tree height up to a max */
748 max_height = (gdk_screen_get_height (gtk_widget_get_screen (widget))) / 4;
749
750 gtk_widget_get_preferred_size (to_size, NULL, &req);
751
752 gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (widget),
753 MIN (req.height, max_height));
754}
755
756static void
757gvc_sound_theme_chooser_init (GvcSoundThemeChooser *chooser)
758{
759 GtkWidget *box;
760 GtkWidget *label;
761 GtkWidget *scrolled_window;
762 GtkWidget *alignment;
763 char *str;
764
765 chooser->priv = GVC_SOUND_THEME_CHOOSER_GET_PRIVATE (chooser);
766
767 chooser->priv->settings = g_settings_new (WM_SCHEMA);
768 chooser->priv->sound_settings = g_settings_new (KEY_SOUNDS_SCHEMA);
769
770 str = g_strdup_printf ("<b>%s</b>", _("C_hoose an alert sound:"));
771 chooser->priv->selection_box = box = gtk_frame_new (str);
772 g_free (str);
773 label = gtk_frame_get_label_widget (GTK_FRAME (box));
774 gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
775 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
776 gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_NONE);
777
778 alignment = gtk_alignment_new (0, 0, 1, 1);
779 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 0, 0);
780 gtk_container_add (GTK_CONTAINER (alignment), box);
781 gtk_box_pack_start (GTK_BOX (chooser), alignment, TRUE, TRUE, 6);
782
783 alignment = gtk_alignment_new (0, 0, 1, 1);
784 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 0, 0);
785 gtk_container_add (GTK_CONTAINER (box), alignment);
786
787 chooser->priv->treeview = create_alert_treeview (chooser);
788 gtk_label_set_mnemonic_widget (GTK_LABEL (label), chooser->priv->treeview);
789
790 scrolled_window = gtk_scrolled_window_new (NULL, NULL);
791 setup_list_size_constraint (scrolled_window, chooser->priv->treeview);
792
793 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
794 GTK_POLICY_NEVER,
795 GTK_POLICY_AUTOMATIC);
796 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
797 GTK_SHADOW_IN);
798 gtk_container_add (GTK_CONTAINER (scrolled_window), chooser->priv->treeview);
799 gtk_container_add (GTK_CONTAINER (alignment), scrolled_window);
800
801 g_signal_connect (G_OBJECT (chooser->priv->sound_settings), "changed",
802 G_CALLBACK (on_sound_settings_changed), chooser);
803 g_signal_connect (chooser->priv->settings, "changed::" AUDIO_BELL_KEY,
804 G_CALLBACK (on_audible_bell_changed), chooser);
805}
806
807static void
808gvc_sound_theme_chooser_finalize (GObject *object)
809{
810 GvcSoundThemeChooser *sound_theme_chooser;
811
812 g_return_if_fail (object != NULL);
813 g_return_if_fail (GVC_IS_SOUND_THEME_CHOOSER (object));
814
815 sound_theme_chooser = GVC_SOUND_THEME_CHOOSER (object);
816
817 if (sound_theme_chooser->priv != NULL) {
818 g_object_unref (sound_theme_chooser->priv->settings);
819 g_object_unref (sound_theme_chooser->priv->sound_settings);
820 }
821
822 G_OBJECT_CLASS (gvc_sound_theme_chooser_parent_class)->finalize (object);
823}
824
825GtkWidget *
826gvc_sound_theme_chooser_new (void)
827{
828 GObject *chooser;
829 chooser = g_object_new (GVC_TYPE_SOUND_THEME_CHOOSER,
830 "spacing", 6,
831 NULL);
832 return GTK_WIDGET (chooser);
833}
0834
=== modified file 'debian/changelog'
--- debian/changelog 2014-04-02 10:52:39 +0000
+++ debian/changelog 2014-07-07 05:56:11 +0000
@@ -1,3 +1,9 @@
1gnome-control-center (1:3.4.2-0ubuntu0.13.3) precise; urgency=medium
2
3 * sound: fix potential memory corruption (LP: #1236612)
4
5 -- Madper Xie <madper.xie@canonical.com> Mon, 07 Jul 2014 13:41:57 +0800
6
1gnome-control-center (1:3.4.2-0ubuntu0.13.2) precise; urgency=medium7gnome-control-center (1:3.4.2-0ubuntu0.13.2) precise; urgency=medium
28
3 * Disable the input/output bar when no input/output devices (LP: #1291862)9 * Disable the input/output bar when no input/output devices (LP: #1291862)
410
=== modified file 'debian/patches/series'
--- debian/patches/series 2014-04-02 10:52:39 +0000
+++ debian/patches/series 2014-07-07 05:56:11 +0000
@@ -44,3 +44,4 @@
44use_rfkill_airplane_mode.patch44use_rfkill_airplane_mode.patch
45more-power-suspend-options.patch45more-power-suspend-options.patch
46fix-input-device-bar-status.patch46fix-input-device-bar-status.patch
47sound-fix-potential-memory-corruption.patch
4748
=== added file 'debian/patches/sound-fix-potential-memory-corruption.patch'
--- debian/patches/sound-fix-potential-memory-corruption.patch 1970-01-01 00:00:00 +0000
+++ debian/patches/sound-fix-potential-memory-corruption.patch 2014-07-07 05:56:11 +0000
@@ -0,0 +1,12 @@
1Index: gnome-control-center/panels/sound/gvc-sound-theme-chooser.c
2===================================================================
3--- gnome-control-center.orig/panels/sound/gvc-sound-theme-chooser.c 2014-07-07 12:40:00.839504000 +0800
4+++ gnome-control-center/panels/sound/gvc-sound-theme-chooser.c 2014-07-07 12:48:15.822986459 +0800
5@@ -672,6 +672,7 @@
6
7 if (g_strcmp0 (last_theme, chooser->priv->current_theme) != 0) {
8 g_free (chooser->priv->current_parent);
9+ chooser->priv->current_parent = NULL;
10 if (load_theme_name (chooser->priv->current_theme,
11 &chooser->priv->current_parent) == FALSE) {
12 g_free (chooser->priv->current_theme);
013
=== modified file 'panels/sound/gvc-sound-theme-chooser.c'
--- panels/sound/gvc-sound-theme-chooser.c 2012-02-15 23:16:31 +0000
+++ panels/sound/gvc-sound-theme-chooser.c 2014-07-07 05:56:11 +0000
@@ -672,6 +672,7 @@
672672
673 if (g_strcmp0 (last_theme, chooser->priv->current_theme) != 0) {673 if (g_strcmp0 (last_theme, chooser->priv->current_theme) != 0) {
674 g_free (chooser->priv->current_parent);674 g_free (chooser->priv->current_parent);
675 chooser->priv->current_parent = NULL;
675 if (load_theme_name (chooser->priv->current_theme,676 if (load_theme_name (chooser->priv->current_theme,
676 &chooser->priv->current_parent) == FALSE) {677 &chooser->priv->current_parent) == FALSE) {
677 g_free (chooser->priv->current_theme);678 g_free (chooser->priv->current_theme);

Subscribers

People subscribed via source and target branches

to all changes: