/* DESCRIPTION : This function is called when an adjustment changes. * BEHAVIOR : Updates the key given as parameter to the new value of the * adjustment. * PRE : Non-Null data corresponding to the int config key to modify. */ void adjustment_changed (GtkAdjustment *adj, gpointer data) { gchar *key = NULL; key = (gchar *) data; if (gm_conf_get_int (key) != (int) gtk_adjustment_get_value (adj)) gm_conf_set_int (key, (int) gtk_adjustment_get_value (adj)); }
/* DESCRIPTION : This function is called when an int option menu changes. * BEHAVIOR : Updates the key given as parameter to the new value of the * int option menu. * PRE : Non-Null data corresponding to int the config key to modify. */ void int_option_menu_changed (GtkWidget *option_menu, gpointer data) { gchar *key = NULL; unsigned int current_value = 0; unsigned int i = 0; key = (gchar *) data; i = gtk_combo_box_get_active (GTK_COMBO_BOX (option_menu)); current_value = gm_conf_get_int (key); if (i != current_value) gm_conf_set_int (key, i); }
/* The class */ Opal::Sip::EndPoint::EndPoint (Opal::CallManager & _manager, Ekiga::ServiceCore& core): SIPEndPoint (_manager), manager (_manager) { boost::shared_ptr<Ekiga::ChatCore> chat_core = core.get<Ekiga::ChatCore> ("chat-core"); protocol_name = "sip"; uri_prefix = "sip:"; listen_port = gm_conf_get_int (SIP_KEY "listen_port"); listen_port = (listen_port > 0 ? listen_port : 5060); dialect = boost::shared_ptr<SIP::Dialect>(new SIP::Dialect (core, boost::bind (&Opal::Sip::EndPoint::send_message, this, _1, _2))); chat_core->add_dialect (dialect); /* Timeouts */ SetAckTimeout (PTimeInterval (0, 32)); SetPduCleanUpTimeout (PTimeInterval (0, 1)); SetInviteTimeout (PTimeInterval (0, 60)); SetNonInviteTimeout (PTimeInterval (0, 6)); SetRetryTimeouts (500, 4000); SetMaxRetries (8); /* Start listener */ set_listen_port (listen_port); /* Update the User Agent */ SetUserAgent ("Ekiga/" PACKAGE_VERSION); /* Ready to take calls */ manager.AddRouteEntry("sip:.* = pc:*"); manager.AddRouteEntry("pc:.* = sip:<da>"); /* NAT Binding */ SetNATBindingRefreshMethod (SIPEndPoint::Options); }
/* The main () */ int main (int argc, char ** argv, char ** /*envp*/) { GOptionContext *context = NULL; Ekiga::ServiceCorePtr service_core(new Ekiga::ServiceCore); gchar *path = NULL; gchar *url = NULL; int debug_level = 0; /* Globals */ #ifndef WIN32 if (!XInitThreads ()) exit (1); #endif #if !GLIB_CHECK_VERSION(2,36,0) g_type_init (); #endif #if !GLIB_CHECK_VERSION(2,32,0) g_thread_init(); #endif /* GTK+ initialization */ gtk_init (&argc, &argv); #ifndef WIN32 signal (SIGPIPE, SIG_IGN); #endif /* Gettext initialization */ path = g_build_filename (DATA_DIR, "locale", NULL); textdomain (GETTEXT_PACKAGE); bindtextdomain (GETTEXT_PACKAGE, path); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); g_free (path); /* Application name */ g_set_application_name (_("Ekiga Softphone")); #ifndef WIN32 setenv ("PULSE_PROP_application.name", _("Ekiga Softphone"), true); #endif /* initialize platform-specific code */ gm_platform_init (); #ifdef WIN32 // plugins (i.e. the audio/video ptlib/opal codecs) are searched in ./plugins chdir (win32_datadir ()); #endif /* Configuration backend initialization */ gm_conf_init (); /* Arguments initialization */ GOptionEntry arguments [] = { { "debug", 'd', 0, G_OPTION_ARG_INT, &debug_level, N_("Prints debug messages in the console (level between 1 and 8)"), NULL }, { "call", 'c', 0, G_OPTION_ARG_STRING, &url, N_("Makes Ekiga call the given URI"), NULL }, { NULL, 0, 0, (GOptionArg)0, NULL, NULL, NULL } }; context = g_option_context_new (NULL); g_option_context_add_main_entries (context, arguments, PACKAGE_NAME); g_option_context_set_help_enabled (context, TRUE); g_option_context_add_group (context, gtk_get_option_group (TRUE)); g_option_context_parse (context, &argc, &argv, NULL); g_option_context_free (context); #ifndef WIN32 char* text_label = g_strdup_printf ("%d", debug_level); setenv ("PTLIB_TRACE_CODECS", text_label, TRUE); g_free (text_label); #else char* text_label = g_strdup_printf ("PTLIB_TRACE_CODECS=%d", debug_level); _putenv (text_label); g_free (text_label); if (debug_level != 0) { std::string desk_path = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); if (!desk_path.empty ()) std::freopen((desk_path + "\\ekiga-stderr.txt").c_str (), "w", stderr); } #endif #if PTRACING if (debug_level != 0) PTrace::Initialise (PMAX (PMIN (8, debug_level), 0), NULL, PTrace::Timestamp | PTrace::Thread | PTrace::Blocks | PTrace::DateAndTime); #endif #ifdef HAVE_DBUS if (!ekiga_dbus_claim_ownership ()) { ekiga_dbus_client_show (); if (url != NULL) ekiga_dbus_client_connect (url); exit (0); } #endif /* Ekiga initialisation */ // should come *after* ptrace initialisation, to track codec loading for ex. GnomeMeeting instance; Ekiga::Runtime::init (); engine_init (service_core, argc, argv); PTRACE (1, "Ekiga version " << MAJOR_VERSION << "." << MINOR_VERSION << "." << BUILD_NUMBER); #ifdef EKIGA_REVISION PTRACE (1, "Ekiga git revision: " << EKIGA_REVISION); #endif PTRACE (1, "PTLIB version " << PTLIB_VERSION); PTRACE (1, "OPAL version " << OPAL_VERSION); #if defined HAVE_XV || defined HAVE_DX PTRACE (1, "Accelerated rendering support enabled"); #else PTRACE (1, "Accelerated rendering support disabled"); #endif #ifdef HAVE_DBUS PTRACE (1, "DBUS support enabled"); #else PTRACE (1, "DBUS support disabled"); #endif #ifdef HAVE_GCONF PTRACE (1, "GConf support enabled"); #else PTRACE (1, "GConf support disabled"); #endif boost::shared_ptr<GtkFrontend> gtk_frontend = service_core->get<GtkFrontend>("gtk-frontend"); GtkWidget *main_window = GTK_WIDGET (gtk_frontend->get_main_window ()); const int schema_version = MAJOR_VERSION * 1000 + MINOR_VERSION * 10 + BUILD_NUMBER; int crt_version = gm_conf_get_int (GENERAL_KEY "version"); if (crt_version < schema_version) { gmconf_upgrade_version (); // show the assistant if there is no config file if (crt_version == 0) gtk_widget_show_all (GTK_WIDGET (gtk_frontend->get_assistant_window ())); /* Update the version number */ gm_conf_set_int (GENERAL_KEY "version", schema_version); } /* Show the main window */ gtk_widget_show (main_window); /* Call the given host if needed */ if (url) { boost::shared_ptr<Ekiga::CallCore> call_core = service_core->get<Ekiga::CallCore> ("call-core"); call_core->dial (url); } #ifdef HAVE_DBUS EkigaDBusComponent *dbus_component = ekiga_dbus_component_new (*service_core); #endif // from now on, things should have taken their final place service_core->close (); /* The GTK loop */ gtk_main (); #ifdef HAVE_DBUS g_object_unref (dbus_component); #endif /* Exit Ekiga */ GnomeMeeting::Process ()->Exit (); service_core.reset (); Ekiga::Runtime::quit (); /* Save and shutdown the configuration */ gm_conf_save (); gm_conf_shutdown (); /* deinitialize platform-specific code */ gm_platform_shutdown (); return 0; }
/* The functions */ void gnomemeeting_conf_upgrade () { gchar *conf_url = NULL; int version = 0; version = gm_conf_get_int (GENERAL_KEY "version"); /* Install the sip:, h323: and callto: GNOME URL Handlers */ conf_url = gm_conf_get_string ("/desktop/gnome/url-handlers/callto/command"); if (!conf_url || !strcmp (conf_url, "gnomemeeting -c \"%s\"")) { gm_conf_set_string ("/desktop/gnome/url-handlers/callto/command", "ekiga -c \"%s\""); gm_conf_set_bool ("/desktop/gnome/url-handlers/callto/needs_terminal", false); gm_conf_set_bool ("/desktop/gnome/url-handlers/callto/enabled", true); } g_free (conf_url); conf_url = gm_conf_get_string ("/desktop/gnome/url-handlers/h323/command"); if (!conf_url || !strcmp (conf_url, "gnomemeeting -c \"%s\"")) { gm_conf_set_string ("/desktop/gnome/url-handlers/h323/command", "ekiga -c \"%s\""); gm_conf_set_bool ("/desktop/gnome/url-handlers/h323/needs_terminal", false); gm_conf_set_bool ("/desktop/gnome/url-handlers/h323/enabled", true); } g_free (conf_url); conf_url = gm_conf_get_string ("/desktop/gnome/url-handlers/sip/command"); if (!conf_url || !strcmp (conf_url, "gnomemeeting -c \"%s\"")) { gm_conf_set_string ("/desktop/gnome/url-handlers/sip/command", "ekiga -c \"%s\""); gm_conf_set_bool ("/desktop/gnome/url-handlers/sip/needs_terminal", false); gm_conf_set_bool ("/desktop/gnome/url-handlers/sip/enabled", true); } g_free (conf_url); /* New full name key */ conf_url = gm_conf_get_string (PERSONAL_DATA_KEY "full_name"); if (!conf_url || (conf_url && !strcmp (conf_url, ""))) { gchar *fullname = NULL; gchar *firstname = gm_conf_get_string (PERSONAL_DATA_KEY "firstname"); gchar *lastname = gm_conf_get_string (PERSONAL_DATA_KEY "lastname"); if (firstname && lastname && strcmp (firstname, "") && strcmp (lastname, "")) { fullname = g_strdup_printf ("%s %s", firstname, lastname); gm_conf_set_string (PERSONAL_DATA_KEY "firstname", ""); gm_conf_set_string (PERSONAL_DATA_KEY "lastname", ""); gm_conf_set_string (PERSONAL_DATA_KEY "full_name", fullname); g_free (fullname); } g_free (firstname); g_free (lastname); } g_free (conf_url); /* diamondcard is now set at sip.diamondcard.us */ GSList *accounts = gm_conf_get_string_list ("/apps/" PACKAGE_NAME "/protocols/accounts_list"); GSList *accounts_iter = accounts; while (accounts_iter) { PString acct = (gchar *) accounts_iter->data; acct.Replace ("eugw.ast.diamondcard.us", "sip.diamondcard.us", TRUE); g_free (accounts_iter->data); accounts_iter->data = g_strdup ((const char *) acct); accounts_iter = g_slist_next (accounts_iter); } gm_conf_set_string_list ("/apps/" PACKAGE_NAME "/protocols/accounts_list", accounts); g_slist_foreach (accounts, (GFunc) g_free, NULL); g_slist_free (accounts); /* Audio devices */ gchar *plugin = NULL; gchar *device = NULL; gchar *new_device = NULL; plugin = gm_conf_get_string (AUDIO_DEVICES_KEY "plugin"); if (plugin && strcmp (plugin, "")) { device = gm_conf_get_string (AUDIO_DEVICES_KEY "input_device"); new_device = g_strdup_printf ("%s (PTLIB/%s)", device, plugin); gm_conf_set_string (AUDIO_DEVICES_KEY "plugin", ""); gm_conf_set_string (AUDIO_DEVICES_KEY "input_device", new_device); g_free (device); g_free (new_device); device = gm_conf_get_string (AUDIO_DEVICES_KEY "output_device"); new_device = g_strdup_printf ("%s (PTLIB/%s)", device, plugin); gm_conf_set_string (AUDIO_DEVICES_KEY "plugin", ""); gm_conf_set_string (AUDIO_DEVICES_KEY "output_device", new_device); g_free (device); g_free (new_device); device = gm_conf_get_string (SOUND_EVENTS_KEY "output_device"); new_device = g_strdup_printf ("%s (PTLIB/%s)", device, plugin); gm_conf_set_string (SOUND_EVENTS_KEY "plugin", ""); gm_conf_set_string (SOUND_EVENTS_KEY "output_device", new_device); g_free (device); g_free (new_device); } g_free (plugin); /* Video devices */ plugin = gm_conf_get_string (VIDEO_DEVICES_KEY "plugin"); if (plugin && strcmp (plugin, "")) { device = gm_conf_get_string (VIDEO_DEVICES_KEY "input_device"); new_device = g_strdup_printf ("%s (PTLIB/%s)", device, plugin); gm_conf_set_string (VIDEO_DEVICES_KEY "plugin", ""); gm_conf_set_string (VIDEO_DEVICES_KEY "input_device", new_device); g_free (device); g_free (new_device); } g_free (plugin); }
GtkWidget * gnome_prefs_int_option_menu_new (GtkWidget *table, const gchar *label_txt, const gchar **options, const gchar *conf_key, const gchar *tooltip, int row) { GnomePrefsWindow *gpw = NULL; GtkWidget *label = NULL; GtkWidget *option_menu = NULL; GtkListStore *list_store = NULL; GtkCellRenderer *renderer = NULL; GtkTreeIter iter; gboolean writable = FALSE; int history = -1; int cpt = 0; writable = gm_conf_is_key_writable (conf_key); label = gtk_label_new_with_mnemonic (label_txt); if (!writable) gtk_widget_set_sensitive (GTK_WIDGET (label), FALSE); gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); option_menu = gtk_combo_box_new_with_model (GTK_TREE_MODEL (list_store)); if (!writable) gtk_widget_set_sensitive (GTK_WIDGET (option_menu), FALSE); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (option_menu), renderer, FALSE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (option_menu), renderer, "text", COLUMN_STRING_TRANSLATED, NULL); g_object_set (G_OBJECT (renderer), "ellipsize-set", TRUE, "ellipsize", PANGO_ELLIPSIZE_END, "width-chars", 45, NULL); gtk_label_set_mnemonic_widget (GTK_LABEL (label), option_menu); history = gm_conf_get_int (conf_key); while (options [cpt]) { gtk_list_store_append (GTK_LIST_STORE (list_store), &iter); gtk_list_store_set (GTK_LIST_STORE (list_store), &iter, COLUMN_STRING_RAW, options [cpt], COLUMN_STRING_TRANSLATED, gettext (options [cpt]), -1); cpt++; } gtk_combo_box_set_active (GTK_COMBO_BOX (option_menu), history); gtk_table_attach (GTK_TABLE (table), option_menu, 1, 2, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); gpw = (GnomePrefsWindow *) g_object_get_data (G_OBJECT (table), "gpw"); if (gpw && tooltip) gtk_widget_set_tooltip_text (option_menu, tooltip); g_signal_connect (option_menu, "changed", G_CALLBACK (int_option_menu_changed), (gpointer) conf_key); gm_conf_notifier_add (conf_key, int_option_menu_changed_nt, (gpointer) option_menu); gtk_widget_show_all (table); return option_menu; }
void gnome_prefs_range_new (GtkWidget *table, const gchar *label1_txt, GtkWidget **spin1, const gchar *label2_txt, GtkWidget **spin2, const gchar *label3_txt, const gchar *spin1_conf_key, const gchar *spin2_conf_key, const gchar *spin1_tooltip, const gchar *spin2_tooltip, double spin1_min, double spin2_min, double spin1_max, double spin2_max, double spins_step, int row) { GnomePrefsWindow *gpw = NULL; int val1 = 0, val2 = 0; gboolean writable = FALSE; GtkWidget *hbox = NULL; GtkAdjustment *adj1 = NULL; GtkWidget *spin_button1 = NULL; GtkWidget *spin_button2 = NULL; GtkAdjustment *adj2 = NULL; GtkWidget *label = NULL; writable = (gm_conf_is_key_writable (spin1_conf_key) && gm_conf_is_key_writable (spin2_conf_key)); hbox = gtk_hbox_new (FALSE, 0); label = gtk_label_new_with_mnemonic (label1_txt); if (!writable) gtk_widget_set_sensitive (GTK_WIDGET (label), FALSE); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 1 * 2); val1 = gm_conf_get_int (spin1_conf_key); adj1 = (GtkAdjustment *) gtk_adjustment_new (val1, spin1_min, spin1_max, spins_step, 2.0, 1.0); spin_button1 = gtk_spin_button_new (adj1, 1.0, 0); if (!writable) gtk_widget_set_sensitive (GTK_WIDGET (spin_button1), FALSE); gtk_box_pack_start (GTK_BOX (hbox), spin_button1, FALSE, FALSE, 1 * 2); label = gtk_label_new_with_mnemonic (label2_txt); if (!writable) gtk_widget_set_sensitive (GTK_WIDGET (label), FALSE); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 1 * 2); val2 = gm_conf_get_int (spin2_conf_key); adj2 = (GtkAdjustment *) gtk_adjustment_new (val2, spin2_min, spin2_max, spins_step, 2.0, 1.0); spin_button2 = gtk_spin_button_new (adj2, 1.0, 0); if (!writable) gtk_widget_set_sensitive (GTK_WIDGET (spin_button2), FALSE); gtk_box_pack_start (GTK_BOX (hbox), spin_button2, FALSE, FALSE, 1 * 2); label = gtk_label_new_with_mnemonic (label3_txt); if (!writable) gtk_widget_set_sensitive (GTK_WIDGET (label), FALSE); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 1 * 2); gtk_table_attach (GTK_TABLE (table), hbox, 0, 1, row, row+1, (GtkAttachOptions) (NULL), (GtkAttachOptions) (NULL), 0, 0); gpw = (GnomePrefsWindow *) g_object_get_data (G_OBJECT (table), "gpw"); if (gpw && spin1_tooltip && spin2_tooltip) { gtk_widget_set_tooltip_text (spin_button1, spin1_tooltip); gtk_widget_set_tooltip_text (spin_button2, spin2_tooltip); } g_signal_connect (adj1, "value-changed", G_CALLBACK (adjustment_changed), (gpointer) spin1_conf_key); gm_conf_notifier_add (spin1_conf_key, adjustment_changed_nt, (gpointer) adj1); g_signal_connect (adj2, "value-changed", G_CALLBACK (adjustment_changed), (gpointer) spin2_conf_key); gm_conf_notifier_add (spin2_conf_key, adjustment_changed_nt, (gpointer) adj2); if (spin1) *spin1 = spin_button1; if (spin2) *spin2 = spin_button2; }
GtkWidget * gnome_prefs_spin_new (GtkWidget *table, const gchar *label_txt, const gchar *conf_key, const gchar *tooltip, double min, double max, double step, int row, const gchar *label_txt2, gboolean box) { GnomePrefsWindow *gpw = NULL; GtkWidget *hbox = NULL; GtkAdjustment *adj = NULL; GtkWidget *label = NULL; GtkWidget *spin_button = NULL; gboolean writable = FALSE; writable = gm_conf_is_key_writable (conf_key); if (box) hbox = gtk_hbox_new (FALSE, 0); label = gtk_label_new_with_mnemonic (label_txt); if (!writable) gtk_widget_set_sensitive (GTK_WIDGET (label), FALSE); if (box) gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 1 * 2); else gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); adj = (GtkAdjustment *) gtk_adjustment_new (gm_conf_get_int (conf_key), min, max, step, 10.0, 0.0); spin_button = gtk_spin_button_new (adj, 1.0, 0); if (!writable) gtk_widget_set_sensitive (GTK_WIDGET (spin_button), FALSE); if (box) gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 1 * 2); else gtk_table_attach (GTK_TABLE (table), spin_button, 1, 2, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); if (box && label_txt2) { label = gtk_label_new_with_mnemonic (label_txt2); if (!writable) gtk_widget_set_sensitive (GTK_WIDGET (label), FALSE); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 1 * 2); } if (box) { guint ncols; g_object_get (G_OBJECT (table), "n-columns", &ncols, NULL); gtk_table_attach (GTK_TABLE (table), hbox, 0, ncols, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); } gpw = (GnomePrefsWindow *) g_object_get_data (G_OBJECT (table), "gpw"); if (gpw && tooltip) gtk_widget_set_tooltip_text (spin_button, tooltip); g_signal_connect (adj, "value-changed", G_CALLBACK (adjustment_changed), (gpointer) conf_key); gm_conf_notifier_add (conf_key, adjustment_changed_nt, (gpointer) adj); gtk_widget_show_all (table); return spin_button; }
GtkWidget * gnome_prefs_scale_new (GtkWidget *table, const gchar *down_label_txt, const gchar *up_label_txt, const gchar *conf_key, const gchar *tooltip, double min, double max, double step, int row) { GnomePrefsWindow *gpw = NULL; GtkWidget *hbox = NULL; GtkAdjustment *adj = NULL; GtkWidget *label = NULL; GtkWidget *hscale = NULL; gboolean writable = FALSE; writable = gm_conf_is_key_writable (conf_key); hbox = gtk_hbox_new (FALSE, 0); label = gtk_label_new_with_mnemonic (down_label_txt); if (!writable) gtk_widget_set_sensitive (GTK_WIDGET (label), FALSE); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 1 * 2); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); adj = (GtkAdjustment *) gtk_adjustment_new (gm_conf_get_int (conf_key), min, max, step, 2.0, 1.0); hscale = gtk_hscale_new (adj); gtk_scale_set_draw_value (GTK_SCALE (hscale), FALSE); gtk_widget_set_size_request (GTK_WIDGET (hscale), 150, -1); if (!writable) gtk_widget_set_sensitive (GTK_WIDGET (hscale), FALSE); gtk_box_pack_start (GTK_BOX (hbox), hscale, FALSE, FALSE, 1 * 2); label = gtk_label_new_with_mnemonic (up_label_txt); if (!writable) gtk_widget_set_sensitive (GTK_WIDGET (label), FALSE); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 1 * 2); gtk_table_attach (GTK_TABLE (table), hbox, 0, 1, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); gpw = (GnomePrefsWindow *) g_object_get_data (G_OBJECT (table), "gpw"); if (gpw && tooltip) gtk_widget_set_tooltip_text (hscale, tooltip); g_signal_connect (adj, "value-changed", G_CALLBACK (adjustment_changed), (gpointer) conf_key); gm_conf_notifier_add (conf_key, adjustment_changed_nt, (gpointer) adj); gtk_widget_show_all (table); return hscale; }