diff --git a/ChangeLog b/ChangeLog index 7ba8a35bb..fd1c71419 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2000-10-08 Bradford Hovinen + + * configure.in (CFLAGS): Update list of Makefiles + + * capplets/Makefile.am (always_built_SUBDIRS): Build new + sound-properties-capplet rather than old one + 2000-10-06 Bradford Hovinen * configure.in (AC_OUTPUT): Update list of Makefiles diff --git a/capplets/Makefile.am b/capplets/Makefile.am index 94f9cf570..5240493e9 100644 --- a/capplets/Makefile.am +++ b/capplets/Makefile.am @@ -1,6 +1,6 @@ always_built_SUBDIRS = desktop-links new-mouse-properties \ new-screensaver-properties new-background-properties \ - theme-switcher sound-properties new-bell-properties \ + theme-switcher new-sound-properties new-bell-properties \ new-ui-properties url-properties gnome-edit-properties \ session-properties wm-properties new-keyboard-properties \ mime-type diff --git a/capplets/sound/ChangeLog b/capplets/sound/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/capplets/sound/Makefile.am b/capplets/sound/Makefile.am new file mode 100644 index 000000000..5c0f9bc69 --- /dev/null +++ b/capplets/sound/Makefile.am @@ -0,0 +1,37 @@ +Applicationsdir = $(datadir)/control-center/Desktop +Applications_DATA = \ + sound-properties.desktop + +Gladedir = $(datadir)/control-center-data +Glade_DATA = \ + sound-properties.glade + +EXTRA_DIST = ChangeLog $(Applications_DATA) $(Glade_DATA) + +INCLUDES = \ + -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ + -DGNOME_ICONDIR=\""${prefix}/share/pixmaps"\" \ + -DG_LOG_DOMAIN=\"sound-properties\" \ + -DGLADE_DATADIR=\""$(Gladedir)"\" \ + $(GNOME_INCLUDEDIR) \ + $(XML_CFLAGS) \ + $(LIBGLADE_CFLAGS) \ + -I$(top_srcdir)/ \ + -I$(top_srcdir)/intl \ + -I$(top_srcdir)/libcapplet + +bin_PROGRAMS = sound-properties-capplet + +sound_properties_capplet_SOURCES = \ + prefs-widget.c prefs-widget.h \ + preferences.c preferences.h \ + main.c + +sound_properties_capplet_LDADD = \ + $(GNOME_LIBDIR) \ + $(GNOMEUI_LIBS) \ + $(ORBIT_LIBS) \ + $(GNOME_XML_LIB) \ + $(LIBGLADE_LIBS) \ + -lgdk_pixbuf \ + ../../libcapplet/libcapplet.la diff --git a/capplets/sound/main.c b/capplets/sound/main.c new file mode 100644 index 000000000..205bf40a1 --- /dev/null +++ b/capplets/sound/main.c @@ -0,0 +1,188 @@ +/* -*- mode: c; style: linux -*- */ + +/* main.c + * Copyright (C) 2000 Helix Code, Inc. + * + * Written by Bradford Hovinen (hovinen@helixcode.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include + +#include + +#include "preferences.h" +#include "prefs-widget.h" + +static Preferences *prefs; +static Preferences *old_prefs; +static PrefsWidget *prefs_widget; + +static void +ok_cb (GtkWidget *widget) +{ + preferences_save (prefs); + preferences_apply_now (prefs); +} + +static void +cancel_cb (GtkWidget *widget) +{ + preferences_save (old_prefs); + preferences_apply_now (old_prefs); +} + +static void +setup_capplet_widget (void) +{ + preferences_freeze (prefs); + + prefs_widget = PREFS_WIDGET (prefs_widget_new (prefs)); + + gtk_signal_connect (GTK_OBJECT (prefs_widget), "ok", + GTK_SIGNAL_FUNC (ok_cb), NULL); + gtk_signal_connect (GTK_OBJECT (prefs_widget), "cancel", + GTK_SIGNAL_FUNC (cancel_cb), NULL); + + gtk_widget_show_all (GTK_WIDGET (prefs_widget)); + + preferences_thaw (prefs); +} + +static void +do_get_xml (void) +{ + Preferences *prefs; + xmlDocPtr doc; + + prefs = PREFERENCES (preferences_new ()); + preferences_load (prefs); + doc = preferences_write_xml (prefs); + xmlDocDump (stdout, doc); + gtk_object_destroy (GTK_OBJECT (prefs)); +} + +static void +do_set_xml (void) +{ + Preferences *prefs; + xmlDocPtr doc; + char *buffer; + int len = 0; + + while (!feof (stdin)) { + if (!len) buffer = g_new (char, 16384); + else buffer = g_renew (char, buffer, len + 16384); + fread (buffer + len, 1, 16384, stdin); + len += 16384; + } + + doc = xmlParseMemory (buffer, strlen (buffer)); + + prefs = preferences_read_xml (doc); + + if (prefs) + preferences_save (prefs); + else + g_warning ("Error while reading the screensaver config file"); +} + +int +main (int argc, char **argv) +{ + GnomeClient *client; + GnomeClientFlags flags; + gint token, res; + gchar *restart_args[3]; + + /* For efence */ + free (malloc (1024)); + + bindtextdomain (PACKAGE, GNOMELOCALEDIR); + textdomain (PACKAGE); + + glade_gnome_init (); + res = gnome_capplet_init ("sound-properties", + VERSION, argc, argv, NULL, + 0, NULL); + + if (res < 0) { + g_error ("Could not initialize the capplet."); + } + else if (res == 3) { + do_get_xml (); + return 0; + } + else if (res == 4) { + do_set_xml (); + return 0; + } + + client = gnome_master_client (); + flags = gnome_client_get_flags (client); + + if (flags & GNOME_CLIENT_IS_CONNECTED) { + token = gnome_startup_acquire_token + ("GNOME_SOUND_PROPERTIES", + gnome_client_get_id (client)); + + if (token) { + gnome_client_set_priority (client, 20); + gnome_client_set_restart_style (client, + GNOME_RESTART_ANYWAY); + restart_args[0] = argv[0]; + restart_args[1] = "--init-session-settings"; + restart_args[2] = NULL; + gnome_client_set_restart_command (client, 2, + restart_args); + } else { + gnome_client_set_restart_style (client, + GNOME_RESTART_NEVER); + } + } else { + token = 1; + } + + gnome_window_icon_set_default_from_file + (GNOME_ICONDIR"/~icon~"); + + prefs = PREFERENCES (preferences_new ()); + preferences_load (prefs); + + if (token) { + preferences_apply_now (prefs); + } + + if (!res) { + old_prefs = PREFERENCES (preferences_clone (prefs)); + setup_capplet_widget (); + + capplet_gtk_main (); + } + + return 0; +} diff --git a/capplets/sound/preferences.c b/capplets/sound/preferences.c new file mode 100644 index 000000000..d64e3192f --- /dev/null +++ b/capplets/sound/preferences.c @@ -0,0 +1,916 @@ +/* -*- mode: c; style: linux -*- */ + +/* preferences.c + * Copyright (C) 2000 Helix Code, Inc. + * + * Written by Bradford Hovinen , + * Elliot Lee + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include +#include + +#include "preferences.h" + +static GtkObjectClass *parent_class; + +typedef struct _triple_t { gpointer a; gpointer b; gpointer c; } triple_t; + +static void preferences_init (Preferences *prefs); +static void preferences_class_init (PreferencesClass *class); + +static gint xml_read_int (xmlNodePtr node, + gchar *propname); +static xmlNodePtr xml_write_int (gchar *name, + gchar *propname, + gint number); + +static gint apply_timeout_cb (Preferences *prefs); + +static void read_sound_events_from_xml (xmlNodePtr events_node, + GTree *tree); +static xmlNodePtr write_sound_events_to_xml (GTree *events); + +static void read_path (Preferences *prefs, + const char *path); + +static void reload_esd_samples (const char *config_path); +static void reload_all_esd_samples (void); + +static Category *category_new (void); +static void category_destroy (Category *category); +static Category *category_clone (Category *category); + +static xmlNodePtr category_write_xml (Category *category); +static Category *category_read_xml (xmlNodePtr event_node); + +static SoundEvent *sound_event_new (void); +static void sound_event_destroy (SoundEvent *event); +static SoundEvent *sound_event_clone (SoundEvent *event); + +static void sound_event_set_file (SoundEvent *event, gchar *file); + +static xmlNodePtr sound_event_write_xml (SoundEvent *event); +static SoundEvent *sound_event_read_xml (xmlNodePtr event_node); + +static void start_esd (void); + +guint +preferences_get_type (void) +{ + static guint preferences_type = 0; + + if (!preferences_type) { + GtkTypeInfo preferences_info = { + "Preferences", + sizeof (Preferences), + sizeof (PreferencesClass), + (GtkClassInitFunc) preferences_class_init, + (GtkObjectInitFunc) preferences_init, + (GtkArgSetFunc) NULL, + (GtkArgGetFunc) NULL + }; + + preferences_type = + gtk_type_unique (gtk_object_get_type (), + &preferences_info); + } + + return preferences_type; +} + +static void +preferences_init (Preferences *prefs) +{ + prefs->frozen = FALSE; + prefs->categories = g_tree_new ((GCompareFunc) strcmp); + prefs->cat_byfile = g_tree_new ((GCompareFunc) strcmp); +} + +static void +preferences_class_init (PreferencesClass *class) +{ + GtkObjectClass *object_class; + + object_class = (GtkObjectClass *) class; + object_class->destroy = preferences_destroy; + + parent_class = + GTK_OBJECT_CLASS (gtk_type_class (gtk_object_get_type ())); +} + +GtkObject * +preferences_new (void) +{ + GtkObject *object; + + object = gtk_type_new (preferences_get_type ()); + + return object; +} + +static gint +tree_clone_cb (gchar *cat_name, Category *category, GTree *new_tree) +{ + Category *new_cat; + + new_cat = category_clone (category); + g_tree_insert (new_tree, new_cat->file, new_cat); + + return 0; +} + +GtkObject * +preferences_clone (Preferences *prefs) +{ + GtkObject *object; + Preferences *new_prefs; + + g_return_val_if_fail (prefs != NULL, NULL); + g_return_val_if_fail (IS_PREFERENCES (prefs), NULL); + + object = preferences_new (); + + new_prefs = PREFERENCES (object); + new_prefs->enable_esd = prefs->enable_esd; + new_prefs->enable_sound_events = prefs->enable_sound_events; + + g_tree_traverse (prefs->categories, (GTraverseFunc) tree_clone_cb, + G_IN_ORDER, new_prefs->categories); + + return object; +} + +static gint +tree_destroy_cb (gchar *cat_name, Category *category) +{ + category_destroy (category); + return 0; +} + +void +preferences_destroy (GtkObject *object) +{ + Preferences *prefs; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_PREFERENCES (object)); + + prefs = PREFERENCES (object); + + if (prefs->categories) { + g_tree_traverse (prefs->categories, + (GTraverseFunc) tree_destroy_cb, + G_IN_ORDER, NULL); + g_tree_destroy (prefs->categories); + } + + if (prefs->cat_byfile) + g_tree_destroy (prefs->cat_byfile); + + parent_class->destroy (object); +} + +void +preferences_load (Preferences *prefs) +{ + gchar *ctmp; + + g_return_if_fail (prefs != NULL); + g_return_if_fail (IS_PREFERENCES (prefs)); + + prefs->enable_esd = + gnome_config_get_bool + ("/sound/system/settings/start_esd=false"); + prefs->enable_sound_events = + gnome_config_get_bool + ("/sound/system/settings/event_sounds=false"); + + ctmp = gnome_config_file ("/sound/events"); + if (ctmp != NULL) { + read_path (prefs, ctmp); + g_free (ctmp); + } + + ctmp = gnome_util_home_file ("sound/events"); + if (ctmp != NULL) { + read_path (prefs, ctmp); + g_free (ctmp); + } +} + +static gint +event_save_cb (gchar *event_name, SoundEvent *event, Category *category) +{ + gchar *str; + + str = g_strconcat ("/sound/events/", category->file, "/", + event->name, "/file", NULL); + gnome_config_set_string (str, event->file); + g_free (str); + + return 0; +} + +static gint +tree_save_cb (gchar *cat_name, Category *category) +{ + g_tree_traverse (category->events, (GTraverseFunc) event_save_cb, + G_IN_ORDER, category); + return 0; +} + +void +preferences_save (Preferences *prefs) +{ + g_return_if_fail (prefs != NULL); + g_return_if_fail (IS_PREFERENCES (prefs)); + + gnome_config_set_bool ("/sound/system/settings/start_esd", + prefs->enable_esd); + gnome_config_set_bool ("/sound/system/settings/event_sounds", + prefs->enable_sound_events && + prefs->enable_esd); + + g_tree_traverse (prefs->categories, (GTraverseFunc) tree_save_cb, + G_IN_ORDER, NULL); + + gnome_config_sync (); +} + +void +preferences_changed (Preferences *prefs) +{ + if (prefs->frozen) return; + + if (prefs->timeout_id) + gtk_timeout_remove (prefs->timeout_id); + +/* prefs->timeout_id = gtk_timeout_add (1000, */ +/* (GtkFunction) apply_timeout_cb, */ +/* prefs); */ +} + +void +preferences_apply_now (Preferences *prefs) +{ + g_return_if_fail (prefs != NULL); + g_return_if_fail (IS_PREFERENCES (prefs)); + + if (prefs->timeout_id) + gtk_timeout_remove (prefs->timeout_id); + + prefs->timeout_id = 0; + + if (prefs->enable_esd && gnome_sound_connection < 0) + start_esd (); + + if (prefs->enable_esd && prefs->enable_sound_events) + reload_all_esd_samples (); +} + +void +preferences_freeze (Preferences *prefs) +{ + g_return_if_fail (prefs != NULL); + g_return_if_fail (IS_PREFERENCES (prefs)); + + prefs->frozen = TRUE; +} + +void +preferences_thaw (Preferences *prefs) +{ + g_return_if_fail (prefs != NULL); + g_return_if_fail (IS_PREFERENCES (prefs)); + + prefs->frozen = FALSE; +} + +Preferences * +preferences_read_xml (xmlDocPtr xml_doc) +{ + Preferences *prefs; + xmlNodePtr root_node, node; + + prefs = PREFERENCES (preferences_new ()); + + root_node = xmlDocGetRootElement (xml_doc); + + if (strcmp (root_node->name, "sound-properties")) + return NULL; + + for (node = root_node->childs; node; node = node->next) { + if (!strcmp (node->name, "enable-esd")) + prefs->enable_esd = TRUE; + else if (!strcmp (node->name, "enable-sound-events")) + prefs->enable_sound_events = TRUE; + else if (!strcmp (node->name, "categories")) + read_sound_events_from_xml (node, prefs->categories); + } + + return prefs; +} + +xmlDocPtr +preferences_write_xml (Preferences *prefs) +{ + xmlDocPtr doc; + xmlNodePtr node; + + doc = xmlNewDoc ("1.0"); + + node = xmlNewDocNode (doc, NULL, "sound-properties", NULL); + + if (prefs->enable_esd) + xmlNewChild (node, NULL, "enable-esd", NULL); + if (prefs->enable_sound_events) + xmlNewChild (node, NULL, "enable-sound-events", NULL); + + xmlAddChild (node, write_sound_events_to_xml (prefs->categories)); + + xmlDocSetRootElement (doc, node); + + return doc; +} + +static gint +tree_cb (gchar *key, Category *category, triple_t *triple) +{ + return ((CategoryCallback) triple->b) (PREFERENCES (triple->a), + category->description, + triple->c); +} + +void +preferences_foreach_category (Preferences *prefs, CategoryCallback cb, + gpointer data) +{ + triple_t p; + + g_return_if_fail (prefs != NULL); + g_return_if_fail (IS_PREFERENCES (prefs)); + g_return_if_fail (cb != NULL); + + p.a = prefs; p.b = cb; p.c = data; + g_tree_traverse (prefs->categories, (GTraverseFunc) tree_cb, + G_IN_ORDER, &p); +} + +static int +event_tree_cb (gchar *key, SoundEvent *event, triple_t *triple) +{ + return ((EventCallback) triple->b) (PREFERENCES (triple->a), event, + triple->c); +} + +void +preferences_foreach_event (Preferences *prefs, gchar *cat_name, + EventCallback cb, gpointer data) +{ + Category *category; + triple_t p; + + g_return_if_fail (prefs != NULL); + g_return_if_fail (IS_PREFERENCES (prefs)); + g_return_if_fail (cat_name != NULL); + g_return_if_fail (cb != NULL); + + category = g_tree_lookup (prefs->categories, cat_name); + if (category == NULL) return; + + p.a = prefs; p.b = cb; p.c = data; + g_tree_traverse (category->events, (GTraverseFunc) event_tree_cb, + G_IN_ORDER, &p); +} + +static void +read_sound_events_from_xml (xmlNodePtr events_node, GTree *tree) +{ + xmlNodePtr node; + Category *category; + + for (node = events_node->childs; node; node = node->next) { + if (!strcmp (node->name, "category")) { + category = category_read_xml (node); + g_tree_insert (tree, category->description, category); + } + } +} + +static gint +tree_write_cb (gchar *cat_name, Category *category, xmlNodePtr node) +{ + xmlAddChild (node, category_write_xml (category)); + return 0; +} + +static xmlNodePtr +write_sound_events_to_xml (GTree *events) +{ + xmlNodePtr node; + + g_return_val_if_fail (events != NULL, NULL); + + node = xmlNewNode (NULL, "categories"); + g_tree_traverse (events, (GTraverseFunc) tree_write_cb, + G_IN_ORDER, node); + return node; +} + +static void +read_path (Preferences *prefs, const char *path) +{ + DIR *dirh; + Category *new_cat; + SoundEvent *new_event; + char *sample_name, *ctmp, *prefix; + gpointer event_iter; + struct dirent *dent; + gboolean is_new, event_is_new; + + dirh = opendir (path); + + if (dirh == NULL) + return; + + while ((dent = readdir (dirh))) { + if (!strcmp (dent->d_name, ".") + || !strcmp (dent->d_name, "..")) + continue; + + prefix = g_strdup_printf ("=%s/%s=", path, dent->d_name); + gnome_config_push_prefix (prefix); + + new_cat = g_tree_lookup (prefs->cat_byfile, dent->d_name); + + if (new_cat != NULL) { + is_new = FALSE; + } else { + is_new = TRUE; + new_cat = category_new (); + new_cat->file = g_strdup (dent->d_name); + new_cat->description = + gnome_config_get_translated_string + ("__section_info__/description"); + } + + event_iter = gnome_config_init_iterator_sections (prefix); + g_free (prefix); + + while ((event_iter = gnome_config_iterator_next + (event_iter, &sample_name, NULL))) + { + if (!strcmp (sample_name, "__section_info__")) { + g_free (sample_name); + continue; + } + + new_event = g_tree_lookup (new_cat->events, + sample_name); + + if (new_event != NULL) { + event_is_new = FALSE; + } else { + event_is_new = TRUE; + new_event = sound_event_new (); + new_event->name = sample_name; + new_event->category = new_cat; + ctmp = g_strdup_printf + ("%s/description", sample_name); + new_event->description = + gnome_config_get_translated_string + (ctmp); + g_free (ctmp); + } + + prefix = g_strdup_printf ("%s/file", sample_name); + sound_event_set_file (new_event, + gnome_config_get_string + (prefix)); + g_free (prefix); + + if (event_is_new) { + g_tree_insert (new_cat->events, sample_name, + new_event); + } else { + g_free(sample_name); + } + } + + gnome_config_pop_prefix(); + + if (is_new && new_cat->description != NULL) { + g_tree_insert (prefs->categories, new_cat->description, + new_cat); + g_tree_insert (prefs->cat_byfile, new_cat->file, + new_cat); + } + else if (is_new) { + category_destroy (new_cat); + } + } + + closedir(dirh); +} + +static void +reload_esd_samples(const char *config_path) +{ + DIR *dirh; + char *category_name, *sample_name, *sample_file, *ctmp; + gpointer event_iter; + struct dirent *dent; + GString *tmpstr; + + dirh = opendir(config_path); + if(!dirh) + return; + + tmpstr = g_string_new(NULL); + + while((dent = readdir(dirh))) { + /* ignore no-good dir entries. + We ignore "gnome" because the system sounds are listed in there. + */ + + if (!strcmp(dent->d_name, ".") + || !strcmp(dent->d_name, "..")) + continue; + + g_string_sprintf(tmpstr, "=%s/%s=", config_path, dent->d_name); + + gnome_config_push_prefix(tmpstr->str); + + category_name = dent->d_name; + ctmp = strstr(category_name, ".soundlist"); + if(ctmp) *ctmp = '\0'; + + event_iter = gnome_config_init_iterator_sections(tmpstr->str); + while((event_iter = gnome_config_iterator_next(event_iter, + &sample_name, NULL))) { + if(!strcmp(sample_name, "__section_info__")) { + g_free(sample_name); + continue; + } + + g_string_sprintf(tmpstr, "%s/file", sample_name); + sample_file = gnome_config_get_string(tmpstr->str); + + if(!sample_file || !*sample_file) { + g_free(sample_file); + g_free(sample_name); + continue; + } + + if(*sample_file != '/') { + char *tmp = gnome_sound_file(sample_file); + g_free(sample_file); + sample_file = tmp; + } + + if(sample_file) { + int sid; + + g_string_sprintf(tmpstr, "%s/%s", category_name, sample_name); + + /* We need to free up the old sample, because + esd allows multiple samples with the same name, + putting memory to waste. */ + sid = esd_sample_getid(gnome_sound_connection, tmpstr->str); + if(sid >= 0) + esd_sample_free(gnome_sound_connection, sid); + + sid = gnome_sound_sample_load(tmpstr->str, sample_file); + + if(sid < 0) + g_warning("Couldn't load sound file %s as sample %s", + sample_file, tmpstr->str); + } + + g_free(sample_name); + g_free(sample_file); + } + + gnome_config_pop_prefix(); + } + closedir(dirh); + + g_string_free(tmpstr, TRUE); +} + +static void +reload_all_esd_samples(void) +{ + char *val; + val = gnome_config_file("/sound/events"); + if(val) { + reload_esd_samples(val); + g_free(val); + } + val = gnome_util_home_file("/sound/events"); + if(val) { + reload_esd_samples(val); + g_free(val); + } +} + +static Category * +category_new (void) +{ + Category *category; + + category = g_new0 (Category, 1); + category->events = g_tree_new ((GCompareFunc) strcmp); + + return category; +} + +static int +events_tree_destroy_cb (gchar *event_name, SoundEvent *event) +{ + sound_event_destroy (event); + return 0; +} + +static void +category_destroy (Category *category) +{ + g_tree_traverse (category->events, + (GTraverseFunc) events_tree_destroy_cb, G_IN_ORDER, + NULL); + g_tree_destroy (category->events); + + if (category->description) + g_free (category->description); + g_free (category->file); + g_free (category); +} + +static int +event_tree_clone_cb (gchar *event_name, SoundEvent *event, GTree *new_tree) +{ + g_tree_insert (new_tree, event_name, sound_event_clone (event)); + return 0; +} + +static Category * +category_clone (Category *category) +{ + Category *new_cat; + + g_return_val_if_fail (category != NULL, NULL); + + new_cat = category_new (); + if (category->file != NULL) + new_cat->file = g_strdup (category->file); + if (category->description != NULL) + new_cat->description = g_strdup (category->description); + + g_tree_traverse (category->events, + (GTraverseFunc) event_tree_clone_cb, G_IN_ORDER, + new_cat->events); + + return new_cat; +} + +static Category * +category_read_xml (xmlNodePtr cat_node) +{ + Category *category; + xmlNodePtr node; + GList *list_head = NULL, *list_tail = NULL; + SoundEvent *event; + + g_return_val_if_fail (cat_node != NULL, NULL); + g_return_val_if_fail (strcmp (cat_node->name, "category"), NULL); + + category = category_new (); + + category->file = xmlGetProp (cat_node, "file"); + category->description = xmlGetProp (cat_node, "description"); + + for (node = cat_node->childs; node; node = node->next) { + if (!strcmp (node->name, "event")) { + event = sound_event_read_xml (node); + list_tail = g_list_append (list_tail, event); + if (list_head == NULL) + list_head = list_tail; + else + list_tail = list_tail->next; + } + } + + return category; +} + +static int +event_tree_write_xml_cb (gchar *event_name, SoundEvent *event, + xmlNodePtr node) +{ + xmlAddChild (node, sound_event_write_xml (event)); + return 0; +} + + +static xmlNodePtr +category_write_xml (Category *category) +{ + xmlNodePtr node; + + g_return_val_if_fail (category != NULL, NULL); + + node = xmlNewNode (NULL, "category"); + xmlNewProp (node, "file", category->file); + xmlNewProp (node, "description", category->description); + + g_tree_traverse (category->events, + (GTraverseFunc) event_tree_write_xml_cb, G_IN_ORDER, + node); + + return node; +} + +static SoundEvent * +sound_event_new (void) +{ + return g_new0 (SoundEvent, 1); +} + +static SoundEvent * +sound_event_clone (SoundEvent *event) +{ + SoundEvent *new_event; + + g_return_val_if_fail (event != NULL, NULL); + g_return_val_if_fail (event->category != NULL, NULL); + g_return_val_if_fail (event->name != NULL, NULL); + + new_event = sound_event_new (); + new_event->category = event->category; + new_event->name = g_strdup (event->name); + if (event->file != NULL) + new_event->file = g_strdup (event->file); + + return new_event; +} + +static void +sound_event_destroy (SoundEvent *event) +{ + g_return_if_fail (event != NULL); + + if (event->name) g_free (event->name); + if (event->file) g_free (event->file); + g_free (event); +} + +static void +sound_event_set_file (SoundEvent *event, gchar *file) +{ + g_return_if_fail (event != NULL); + + if (event->file) + g_free (event->file); + event->file = file; +} + +static xmlNodePtr +sound_event_write_xml (SoundEvent *event) +{ + xmlNodePtr node; + + g_return_val_if_fail (event != NULL, NULL); + g_return_val_if_fail (event->category != NULL, NULL); + g_return_val_if_fail (event->name != NULL, NULL); + + node = xmlNewNode (NULL, "event"); + xmlNewChild (node, NULL, "name", event->name); + + if (event->file != NULL) + xmlNewChild (node, NULL, "file", event->file); + + return node; +} + +static SoundEvent * +sound_event_read_xml (xmlNodePtr event_node) +{ + SoundEvent *event; + xmlNodePtr node; + + if (strcmp (event_node->name, "event")) + return NULL; + + event = sound_event_new (); + + for (node = event_node->childs; node; node = node->next) { + if (!strcmp (node->name, "name")) + event->name = g_strdup (xmlNodeGetContent (node)); + else if (!strcmp (node->name, "file")) + event->file = g_strdup (xmlNodeGetContent (node)); + } + + return event; +} + +/* Read a numeric value from a node */ + +static gint +xml_read_int (xmlNodePtr node, char *propname) +{ + char *text; + + if (propname == NULL) + text = xmlNodeGetContent (node); + else + text = xmlGetProp (node, propname); + + if (text == NULL) + return 0; + else + return atoi (text); +} + +/* Write out a numeric value in a node */ + +static xmlNodePtr +xml_write_int (gchar *name, gchar *propname, gint number) +{ + xmlNodePtr node; + gchar *str; + + g_return_val_if_fail (name != NULL, NULL); + + str = g_strdup_printf ("%d", number); + + node = xmlNewNode (NULL, name); + + if (propname == NULL) + xmlNodeSetContent (node, str); + else + xmlSetProp (node, propname, str); + + g_free (str); + + return node; +} + +static gint +apply_timeout_cb (Preferences *prefs) +{ + preferences_apply_now (prefs); + + return TRUE; +} + +static void +start_esd (void) +{ +#ifdef HAVE_ESD + int esdpid; + static const char *esd_cmdline[] = {"esd", "-nobeeps", NULL}; + char *tmpargv[3]; + char argbuf[32]; + time_t starttime; + GnomeClient *client = gnome_master_client (); + + esdpid = gnome_execute_async(NULL, 2, (char **)esd_cmdline); + g_snprintf(argbuf, sizeof(argbuf), "%d", esdpid); + tmpargv[0] = "kill"; tmpargv[1] = argbuf; tmpargv[2] = NULL; + gnome_client_set_shutdown_command(client, 2, tmpargv); + starttime = time(NULL); + gnome_sound_init(NULL); + while(gnome_sound_connection < 0 + && ((time(NULL) - starttime) < 4)) + { +#ifdef HAVE_USLEEP + usleep(1000); +#endif + gnome_sound_init(NULL); + } +#endif +} diff --git a/capplets/sound/preferences.h b/capplets/sound/preferences.h new file mode 100644 index 000000000..4fce1aea4 --- /dev/null +++ b/capplets/sound/preferences.h @@ -0,0 +1,111 @@ +/* -*- mode: c; style: linux -*- */ + +/* preferences.h + * Copyright (C) 2000 Helix Code, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __PREFERENCES_H +#define __PREFERENCES_H + +#include + +#include + +#define CATEGORY(obj) ((Category *) (obj)) + +typedef struct _Category Category; + +struct _Category +{ + gchar *description; + gchar *file; + GTree *events; +}; + +#define SOUND_EVENT(obj) ((SoundEvent *) (obj)) + +typedef struct _SoundEvent SoundEvent; + +struct _SoundEvent +{ + Category *category; + gchar *name; + gchar *file; + gchar *description; +}; + +#define PREFERENCES(obj) GTK_CHECK_CAST (obj, preferences_get_type (), Preferences) +#define PREFERENCES_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, preferences_get_type (), PreferencesClass) +#define IS_PREFERENCES(obj) GTK_CHECK_TYPE (obj, preferences_get_type ()) + +typedef struct _Preferences Preferences; +typedef struct _PreferencesClass PreferencesClass; + +typedef int (*CategoryCallback) (Preferences *, gchar *, gpointer data); +typedef int (*EventCallback) (Preferences *, SoundEvent *, gpointer data); + +struct _Preferences +{ + GtkObject object; + + gboolean frozen; + guint timeout_id; + + gboolean enable_esd; + gboolean enable_sound_events; + + /* private */ + + /* Each node is a linked list of SoundEvents in the category */ + GTree *categories; + GTree *cat_byfile; +}; + +struct _PreferencesClass +{ + GtkObjectClass klass; +}; + +guint preferences_get_type (void); + +GtkObject *preferences_new (void); +GtkObject *preferences_clone (Preferences *prefs); +void preferences_destroy (GtkObject *object); + +void preferences_load (Preferences *prefs); +void preferences_save (Preferences *prefs); +void preferences_changed (Preferences *prefs); +void preferences_apply_now (Preferences *prefs); + +void preferences_freeze (Preferences *prefs); +void preferences_thaw (Preferences *prefs); + +Preferences *preferences_read_xml (xmlDocPtr xml_doc); +xmlDocPtr preferences_write_xml (Preferences *prefs); + +void preferences_foreach_category (Preferences *prefs, + CategoryCallback cb, + gpointer data); +void preferences_foreach_event (Preferences *prefs, + gchar *category, + EventCallback cb, + gpointer data); + +#endif /* __PREFERENCES_H */ diff --git a/capplets/sound/prefs-widget.c b/capplets/sound/prefs-widget.c new file mode 100644 index 000000000..4aeb14fb1 --- /dev/null +++ b/capplets/sound/prefs-widget.c @@ -0,0 +1,433 @@ +/* -*- mode: c; style: linux -*- */ + +/* prefs-widget.c + * Copyright (C) 2000 Helix Code, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "prefs-widget.h" + +#define WID(str) (glade_xml_get_widget (prefs_widget->dialog_data, str)) + +enum { + ARG_0, + ARG_PREFERENCES +}; + +typedef struct _pair_t { gpointer a; gpointer b; } pair_t; + +static CappletWidgetClass *parent_class; + +static void prefs_widget_init (PrefsWidget *prefs_widget); +static void prefs_widget_class_init (PrefsWidgetClass *class); + +static void prefs_widget_set_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); +static void prefs_widget_get_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); + +static void read_preferences (PrefsWidget *prefs_widget, + Preferences *prefs); + +static int place_category_cb (Preferences *prefs, + gchar *name, + PrefsWidget *prefs_widget); +static int place_event_cb (Preferences *prefs, + SoundEvent *event, + pair_t *p); + +static void set_events_toggle_sensitive (PrefsWidget *prefs_widget, + gboolean s); +static void set_events_tab_sensitive (PrefsWidget *prefs_widget, + gboolean s); + +static void play_button_clicked_cb (GtkButton *button, + PrefsWidget *prefs_widget); +static void enable_toggled_cb (GtkToggleButton *tb, + PrefsWidget *prefs_widget); +static void events_toggled_cb (GtkToggleButton *tb, + PrefsWidget *prefs_widget); +static void events_tree_select_cb (GtkCTree *ctree, + GtkCTreeNode *row, + gint column, + PrefsWidget *prefs_widget); +static void sound_file_entry_changed_cb (GtkEntry *entry, + PrefsWidget *prefs_widget); + +guint +prefs_widget_get_type (void) +{ + static guint prefs_widget_type = 0; + + if (!prefs_widget_type) { + GtkTypeInfo prefs_widget_info = { + "PrefsWidget", + sizeof (PrefsWidget), + sizeof (PrefsWidgetClass), + (GtkClassInitFunc) prefs_widget_class_init, + (GtkObjectInitFunc) prefs_widget_init, + (GtkArgSetFunc) NULL, + (GtkArgGetFunc) NULL + }; + + prefs_widget_type = + gtk_type_unique (capplet_widget_get_type (), + &prefs_widget_info); + } + + return prefs_widget_type; +} + +static void +prefs_widget_init (PrefsWidget *prefs_widget) +{ + GtkWidget *widget; + GtkWidget *play_pixmap, *play_button, *label, *hbox; + gchar *audio_icon_name; + GdkPixbuf *pixbuf; + GdkPixmap *pixmap; + GdkBitmap *mask; + + gtk_window_set_default_size (GTK_WINDOW (CAPPLET_WIDGET + (prefs_widget)->dialog), + 500, 350); + + prefs_widget->dialog_data = + glade_xml_new (GLADE_DATADIR "/sound-properties.glade", + "prefs_widget"); + + widget = glade_xml_get_widget (prefs_widget->dialog_data, + "prefs_widget"); + gtk_container_add (GTK_CONTAINER (prefs_widget), widget); + + audio_icon_name = gnome_pixmap_file ("gnome-audio2.png"); + pixbuf = gdk_pixbuf_new_from_file (audio_icon_name); + gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &mask, 1); + gtk_pixmap_set (GTK_PIXMAP (WID ("audio_icon")), pixmap, mask); + + play_button = WID ("play_button"); + hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL); + play_pixmap = gnome_stock_pixmap_widget (play_button, + GNOME_STOCK_PIXMAP_VOLUME); + gtk_box_pack_start (GTK_BOX (hbox), play_pixmap, FALSE, TRUE, 0); + label = gtk_label_new (_("Play")); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0); + gtk_container_add (GTK_CONTAINER (play_button), hbox); + + prefs_widget->events_tree = GTK_CTREE (WID ("events_tree")); + + glade_xml_signal_connect_data (prefs_widget->dialog_data, + "play_button_clicked_cb", + GTK_SIGNAL_FUNC + (play_button_clicked_cb), prefs_widget); + glade_xml_signal_connect_data (prefs_widget->dialog_data, + "enable_toggled_cb", + GTK_SIGNAL_FUNC (enable_toggled_cb), + prefs_widget); + glade_xml_signal_connect_data (prefs_widget->dialog_data, + "events_toggled_cb", + GTK_SIGNAL_FUNC (events_toggled_cb), + prefs_widget); + glade_xml_signal_connect_data (prefs_widget->dialog_data, + "events_tree_select_cb", + GTK_SIGNAL_FUNC (events_tree_select_cb), + prefs_widget); + glade_xml_signal_connect_data (prefs_widget->dialog_data, + "sound_file_entry_changed_cb", + GTK_SIGNAL_FUNC + (sound_file_entry_changed_cb), + prefs_widget); +} + +static void +prefs_widget_class_init (PrefsWidgetClass *class) +{ + GtkObjectClass *object_class; + + gtk_object_add_arg_type ("PrefsWidget::preferences", + GTK_TYPE_POINTER, + GTK_ARG_READWRITE, + ARG_PREFERENCES); + + object_class = GTK_OBJECT_CLASS (class); + object_class->set_arg = prefs_widget_set_arg; + object_class->get_arg = prefs_widget_get_arg; + + parent_class = CAPPLET_WIDGET_CLASS + (gtk_type_class (capplet_widget_get_type ())); +} + +static void +prefs_widget_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + PrefsWidget *prefs_widget; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_PREFS_WIDGET (object)); + + prefs_widget = PREFS_WIDGET (object); + + switch (arg_id) { + case ARG_PREFERENCES: + if (prefs_widget->prefs) + gtk_object_unref (GTK_OBJECT (prefs_widget->prefs)); + + prefs_widget->prefs = GTK_VALUE_POINTER (*arg); + + if (prefs_widget->prefs) { + gtk_object_ref (GTK_OBJECT (prefs_widget->prefs)); + read_preferences (prefs_widget, prefs_widget->prefs); + } + + break; + + default: + g_warning ("Bad argument set"); + break; + } +} + +static void +prefs_widget_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + PrefsWidget *prefs_widget; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_PREFS_WIDGET (object)); + + prefs_widget = PREFS_WIDGET (object); + + switch (arg_id) { + case ARG_PREFERENCES: + GTK_VALUE_POINTER (*arg) = prefs_widget->prefs; + break; + + default: + g_warning ("Bad argument get"); + break; + } +} + +GtkWidget * +prefs_widget_new (Preferences *prefs) +{ + g_return_val_if_fail (prefs == NULL || IS_PREFERENCES (prefs), NULL); + + return gtk_widget_new (prefs_widget_get_type (), + "preferences", prefs, + NULL); +} + +void +prefs_widget_set_preferences (PrefsWidget *prefs_widget, Preferences *prefs) +{ + g_return_if_fail (prefs_widget != NULL); + g_return_if_fail (IS_PREFS_WIDGET (prefs_widget)); + g_return_if_fail (prefs != NULL); + g_return_if_fail (IS_PREFERENCES (prefs)); + + gtk_object_set (GTK_OBJECT (prefs_widget), "preferences", prefs, NULL); +} + +static void +read_preferences (PrefsWidget *prefs_widget, Preferences *prefs) +{ + g_return_if_fail (prefs_widget != NULL); + g_return_if_fail (IS_PREFS_WIDGET (prefs_widget)); + g_return_if_fail (prefs != NULL); + g_return_if_fail (IS_PREFERENCES (prefs)); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON + (WID ("enable_toggle")), + prefs->enable_esd); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON + (WID ("events_toggle")), + prefs->enable_sound_events); + + set_events_toggle_sensitive (prefs_widget, + prefs_widget->prefs->enable_esd); + + preferences_foreach_category (prefs, + (CategoryCallback) place_category_cb, + prefs_widget); +} + +static int +place_category_cb (Preferences *prefs, gchar *name, PrefsWidget *prefs_widget) +{ + GtkCTreeNode *node; + gchar *row[2]; + pair_t p; + + row[0] = name; + row[1] = NULL; + + node = gtk_ctree_insert_node (prefs_widget->events_tree, NULL, NULL, + row, 8, NULL, NULL, NULL, NULL, FALSE, + TRUE); + + p.a = node; p.b = prefs_widget; + preferences_foreach_event (prefs, name, + (EventCallback) place_event_cb, &p); + + return 0; +} + +static int +place_event_cb (Preferences *prefs, SoundEvent *event, pair_t *p) +{ + GtkCTreeNode *event_node; + PrefsWidget *prefs_widget; + gchar *row[2]; + + row[0] = event->description; + row[1] = event->file; + + prefs_widget = PREFS_WIDGET (p->b); + + event_node = gtk_ctree_insert_node (prefs_widget->events_tree, + p->a, NULL, row, 8, NULL, NULL, + NULL, NULL, TRUE, FALSE); + + gtk_ctree_node_set_row_data (prefs_widget->events_tree, + event_node, event); + + return 0; +} + +static void +set_events_toggle_sensitive (PrefsWidget *prefs_widget, gboolean s) +{ + g_return_if_fail (prefs_widget != NULL); + g_return_if_fail (IS_PREFS_WIDGET (prefs_widget)); + + gtk_widget_set_sensitive (WID ("events_toggle"), s); + + set_events_tab_sensitive (prefs_widget, s && + prefs_widget->prefs->enable_sound_events); +} + +static void +set_events_tab_sensitive (PrefsWidget *prefs_widget, gboolean s) +{ + g_return_if_fail (prefs_widget != NULL); + g_return_if_fail (IS_PREFS_WIDGET (prefs_widget)); + + gtk_widget_set_sensitive (WID ("events_tab"), s); + gtk_widget_set_sensitive (WID ("events_tab_label"), s); +} + +static void +play_button_clicked_cb (GtkButton *button, PrefsWidget *prefs_widget) +{ + g_return_if_fail (prefs_widget != NULL); + g_return_if_fail (IS_PREFS_WIDGET (prefs_widget)); + + if (prefs_widget->current_event != NULL) + gnome_sound_play (prefs_widget->current_event->file); +} + +static void +enable_toggled_cb (GtkToggleButton *tb, PrefsWidget *prefs_widget) +{ + g_return_if_fail (prefs_widget != NULL); + g_return_if_fail (IS_PREFS_WIDGET (prefs_widget)); + g_return_if_fail (prefs_widget->prefs != NULL); + g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs)); + g_return_if_fail (tb != NULL); + g_return_if_fail (GTK_IS_TOGGLE_BUTTON (tb)); + + prefs_widget->prefs->enable_esd = gtk_toggle_button_get_active (tb); + set_events_toggle_sensitive (prefs_widget, + prefs_widget->prefs->enable_esd); + + preferences_changed (prefs_widget->prefs); + capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE); +} + +static void +events_toggled_cb (GtkToggleButton *tb, PrefsWidget *prefs_widget) +{ + g_return_if_fail (prefs_widget != NULL); + g_return_if_fail (IS_PREFS_WIDGET (prefs_widget)); + g_return_if_fail (prefs_widget->prefs != NULL); + g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs)); + g_return_if_fail (tb != NULL); + g_return_if_fail (GTK_IS_TOGGLE_BUTTON (tb)); + + prefs_widget->prefs->enable_sound_events = + gtk_toggle_button_get_active (tb); + + set_events_tab_sensitive (prefs_widget, + prefs_widget->prefs->enable_esd && + prefs_widget->prefs->enable_sound_events); + + preferences_changed (prefs_widget->prefs); + capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE); +} + +static void +events_tree_select_cb (GtkCTree *ctree, GtkCTreeNode *row, + gint column, PrefsWidget *prefs_widget) +{ + g_return_if_fail (prefs_widget != NULL); + g_return_if_fail (IS_PREFS_WIDGET (prefs_widget)); + g_return_if_fail (prefs_widget->prefs != NULL); + g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs)); + + prefs_widget->selected_node = row; + prefs_widget->current_event = gtk_ctree_node_get_row_data (ctree, row); + + if (prefs_widget->current_event != NULL) + gtk_entry_set_text + (GTK_ENTRY (WID ("sound_entry")), + prefs_widget->current_event->file); +} + +static void +sound_file_entry_changed_cb (GtkEntry *entry, PrefsWidget *prefs_widget) +{ + g_return_if_fail (prefs_widget != NULL); + g_return_if_fail (IS_PREFS_WIDGET (prefs_widget)); + g_return_if_fail (prefs_widget->prefs != NULL); + g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs)); + + if (prefs_widget->current_event != NULL) { + if (prefs_widget->current_event->file != NULL) + g_free (prefs_widget->current_event->file); + prefs_widget->current_event->file = + g_strdup (gtk_entry_get_text (entry)); + gtk_ctree_node_set_text (prefs_widget->events_tree, + prefs_widget->selected_node, 1, + prefs_widget->current_event->file); + + preferences_changed (prefs_widget->prefs); + capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), + TRUE); + } +} diff --git a/capplets/sound/prefs-widget.h b/capplets/sound/prefs-widget.h new file mode 100644 index 000000000..38bbd4d0e --- /dev/null +++ b/capplets/sound/prefs-widget.h @@ -0,0 +1,64 @@ +/* -*- mode: c; style: linux -*- */ + +/* prefs-widget.h + * Copyright (C) 2000 Helix Code, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __PREFS_WIDGET_H +#define __PREFS_WIDGET_H + +#include +#include +#include + +#include "preferences.h" + +#define PREFS_WIDGET(obj) GTK_CHECK_CAST (obj, prefs_widget_get_type (), PrefsWidget) +#define PREFS_WIDGET_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, prefs_widget_get_type (), PrefsWidgetClass) +#define IS_PREFS_WIDGET(obj) GTK_CHECK_TYPE (obj, prefs_widget_get_type ()) + +typedef struct _PrefsWidget PrefsWidget; +typedef struct _PrefsWidgetClass PrefsWidgetClass; + +struct _PrefsWidget +{ + CappletWidget capplet_widget; + + Preferences *prefs; + GladeXML *dialog_data; + GtkCTree *events_tree; + + SoundEvent *current_event; + GtkCTreeNode *selected_node; +}; + +struct _PrefsWidgetClass +{ + CappletWidgetClass parent_class; +}; + +guint prefs_widget_get_type (void); + +GtkWidget *prefs_widget_new (Preferences *prefs); + +void prefs_widget_set_preferences (PrefsWidget *prefs_widget, + Preferences *prefs); + +#endif /* __PREFS_WIDGET_H */ diff --git a/capplets/sound/sound-properties.desktop b/capplets/sound/sound-properties.desktop new file mode 100644 index 000000000..75a9cab8c --- /dev/null +++ b/capplets/sound/sound-properties.desktop @@ -0,0 +1,60 @@ +[Desktop Entry] +Name=Sound +Name[pt_BR]=Som +Name[ca]=Propietats del so +Name[cs]=Zvuk +Name[da]=Lydhændelser +Name[de]=Klang +Name[el]=Éäéüôçôåò ôïõ ¹÷ïõ +Name[es]=Propiedades Sonidos +Name[et]=Heli +Name[hu]=Hang +Name[fi]=Ääni +Name[fr]=Effets sonores +Name[gl]=Son +Name[it]=Audio +Name[ja]=¥µ¥¦¥ó¥É +Name[ko]=¼Ò¸® +Name[lt]=Garsas +Name[no]=Lyd +Name[pl]=D¼wiêk +Name[pt]=Propriedades de Som +Name[ru]=ú×ÕË +Name[sv]=Ljud +Name[sl]=Zvok +Name[tr]=Ses +Name[uk]=ú×ÕË +Name[wa]=Sons do sistinme +Name[zh_TW.Big5]=Án­µ +Name[zh_CN.GB2312]=ÉùÒô +Comment=Configure GNOME's use of sound. +Comment[ca]=Configurar els sons de GNOME. +Comment[cs]=Konfigurace zvukových parametrù Gnome. +Comment[da]=Indstil GNOMEs brug af lyd +Comment[de]=GNOMEs Systemklänge bearbeiten +Comment[el]=Ñýèìéóç ôùí ÉäéïôÞôùí ôïõ ¹÷ïõ óôï GNOME +Comment[es]=Configurar los sonidos de GNOME +Comment[et]=GNOME helide häälestus +Comment[fi]=GNOMEn ääniasetukset +Comment[hu]=A GNOME hangjai +Comment[fr]=Configuration des effets sonores de GNOME +Comment[gl]=Configurar o son de GNOME +Comment[it]=Impostazioni dell'audio +Comment[ja]=GNOME¤Î¥µ¥¦¥ó¥ÉÍøÍѤ˴ؤ¹¤ëÀßÄê +Comment[ko]=±×³ð¿¡¼­ »ç¿ëÇÒ ¼Ò¸® ¼³Á¤ +Comment[lt]=Nustatyti, kaip GNOME naudoja garsà +Comment[no]=Konfigurér bruk av lyd i GNOME. +Comment[pl]=Konfiguracja d¼wiêku w GNOME +Comment[pt]=Configurar o uso de som no GNOME +Comment[ru]=ïÐÒÅÄÅÌÉÔØ ËÁË GNOME ÉÓÐÏÌØÚÕÅÔ Ú×ÕË +Comment[sl]=Nastavi GNOME-ovo uporabo zvoka. +Comment[sv]=Välj ljud för GNOME. +Comment[tr]=GNOME'un ses kullanýmý ayarlarý +Comment[uk]=îÁÌÁÛÔÕ×ÁÎÎÑ ×ÉËÏÒÉÓÔÁÎÎÑ Ú×ÕËÕ × GNOME +Comment[wa]=Apontyî les sons eployis pa GNOME po les evinmints do sistinme +Comment[zh_TW.Big5]=³]©w GNOME ©Ò¥Îªº­µ®Ä +Comment[zh_CN.GB2312]=É趨 GNOME ËùÓõÄÒôЧ +Exec=sound-properties +Icon=gnome-audio2.png +Terminal=0 +Type=Application diff --git a/capplets/sound/sound-properties.glade b/capplets/sound/sound-properties.glade new file mode 100644 index 000000000..b89fbbd2b --- /dev/null +++ b/capplets/sound/sound-properties.glade @@ -0,0 +1,293 @@ + + + + + New-sound-properties + new-sound-properties + + src + pixmaps + C + True + True + + + + GtkWindow + window1 + window1 + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + 500 + 350 + True + True + False + + + GtkNotebook + prefs_widget + True + True + True + GTK_POS_TOP + False + 2 + 2 + False + + + GtkVBox + vbox1 + 5 + False + 5 + + + GtkPixmap + audio_icon + 0 + 0.5 + 0 + 0 + True + + 0 + False + False + + + + + GtkFrame + frame1 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + False + True + + + + GtkVBox + vbox2 + 5 + False + 5 + + + GtkCheckButton + enable_toggle + True + + toggled + enable_toggled_cb + Sun, 08 Oct 2000 01:49:56 GMT + + + False + True + + 0 + False + False + + + + + GtkCheckButton + events_toggle + True + + toggled + events_toggled_cb + Sun, 08 Oct 2000 01:50:13 GMT + + + False + True + + 0 + False + False + + + + + + + + GtkLabel + Notebook:tab + label1 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkTable + events_tab + 5 + 2 + 2 + False + 5 + 5 + + + GtkScrolledWindow + scrolledwindow1 + GTK_POLICY_NEVER + GTK_POLICY_ALWAYS + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + 2 + 0 + 1 + 0 + 0 + True + True + False + False + True + True + + + + GtkCTree + events_tree + True + + tree_select_row + events_tree_select_cb + Sun, 08 Oct 2000 02:20:09 GMT + + 2 + 185,80 + GTK_SELECTION_SINGLE + True + GTK_SHADOW_IN + + + GtkLabel + CTree:title + label3 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + CTree:title + label4 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + + + GtkButton + play_button + True + + clicked + play_button_clicked_cb + Sun, 08 Oct 2000 01:50:34 GMT + + + 0 + 1 + 1 + 2 + 0 + 0 + False + False + False + False + False + False + + + + Placeholder + + + + + GnomeFileEntry + sound_file_entry + 10 + False + False + + 1 + 2 + 1 + 2 + 0 + 0 + True + False + False + False + True + False + + + + GtkEntry + GnomeEntry:entry + sound_entry + True + + changed + sound_file_entry_changed_cb + Sun, 08 Oct 2000 01:49:31 GMT + + True + True + 0 + + + + + + + GtkLabel + Notebook:tab + events_tab_label + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + + diff --git a/configure.in b/configure.in index d43cd32ce..b349a1b99 100644 --- a/configure.in +++ b/configure.in @@ -95,9 +95,9 @@ capplets/new-keyboard-properties/Makefile capplets/new-mouse-properties/Makefile capplets/new-screensaver-properties/Makefile capplets/new-screensaver-properties/screensavers/Makefile +capplets/new-sound-properties/Makefile capplets/new-ui-properties/Makefile capplets/session-properties/Makefile -capplets/sound-properties/Makefile capplets/theme-switcher/Makefile capplets/url-properties/Makefile capplets/gnome-edit-properties/Makefile