/* $Id: display_plugin.c 24641 2007-01-20 15:44:58Z benny $ */ /*- * Copyright (c) 2003-2006 Benedikt Meurer * * 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; You may only use version 2 of the License, * you have no option to use any other 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #include #include #include #ifdef USE_XRANDR #include #include #endif #ifdef USE_XF86VM #include #endif #include #include #include #include /* this seems to be a sane value */ #define BORDER 6 /* */ #define GAMMA_MIN 0.1 #define GAMMA_MAX 10.0 /* */ #define RCDIR "mcs_settings" #define OLDRCDIR "settings" #define CHANNEL "display" #define RCFILE "display.xml" #define DEFAULT_RES -1 /* */ #define CONFIRM_TIMEOUT 15 /* */ enum { NAME_COLUMN, SIZE_COLUMN, RATE_COLUMN, N_COLUMNS }; /* settings */ static int sizeIndex = DEFAULT_RES; static int rateIndex = DEFAULT_RES; static int redValue = 100; static int greenValue = 100; static int blueValue = 100; static gboolean syncGamma = TRUE; #ifdef USE_XRANDR static int default_size = 0; static int default_rate = 0; #endif /* supported extensions */ static gboolean haveXrandr = FALSE; static gboolean haveXxf86vm = FALSE; /* */ typedef struct _Itf Itf; struct _Itf { McsPlugin *plugin; GtkWidget *dialog; GtkWidget *treeview; GtkListStore *store; GtkWidget *rscale; GtkWidget *gscale; GtkWidget *bscale; GtkWidget *synctoggle; int original_size; int original_rate; int original_rgamma; int original_ggamma; int original_bgamma; gboolean original_sync; }; /* static prototypes */ static void run_dialog (McsPlugin *); static gboolean save_settings (McsPlugin * plugin); #ifdef USE_XRANDR /* */ static void change_size_and_rate (XRRScreenConfiguration * sc, int size, int rate) { Rotation current_rotation; int current_rate; int current_size; gdk_error_trap_push (); current_rate = XRRConfigCurrentRate (sc); current_size = XRRConfigCurrentConfiguration (sc, ¤t_rotation); if (gdk_error_trap_pop ()) { g_warning ("display_plugin: Unable to query current display resolution"); return; } if (size == current_size && rate == current_rate) { /* nothing to do here */ return; } gdk_error_trap_push (); XRRSetScreenConfigAndRate (GDK_DISPLAY (), sc, GDK_ROOT_WINDOW (), (SizeID) size, current_rotation, rate, CurrentTime); XSync (GDK_DISPLAY (), False); if (gdk_error_trap_pop ()) { g_warning ("display_plugin: Unable to configure display resolution"); return; } } static gboolean confirm_timeout_cb (gpointer user_data) { gint timeout; GtkWidget *msgdlg = user_data; timeout = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (msgdlg), "timeout")); if (!--timeout) { gtk_dialog_response (GTK_DIALOG (msgdlg), GTK_RESPONSE_NO); return FALSE; } gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (msgdlg), _("Old settings will be restored in %d seconds"), timeout); g_object_set_data (G_OBJECT (msgdlg), "timeout", GINT_TO_POINTER (timeout)); return TRUE; } static gboolean confirm_display_mode (GtkWidget * parent) { GtkWidget *msgdlg; gint response; guint timeout_id; msgdlg = gtk_message_dialog_new (GTK_WINDOW (parent), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("Display settings have been changed.\n" "Would you like to keep these settings?")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (msgdlg), _("Previous settings will be restored in %d seconds"), CONFIRM_TIMEOUT); gtk_window_set_position (GTK_WINDOW (msgdlg), GTK_WIN_POS_CENTER_ALWAYS); g_object_set_data (G_OBJECT (msgdlg), "timeout", GINT_TO_POINTER (CONFIRM_TIMEOUT)); timeout_id = g_timeout_add (1000, confirm_timeout_cb, msgdlg); response = gtk_dialog_run (GTK_DIALOG (msgdlg)); g_source_remove (timeout_id); gtk_widget_destroy (msgdlg); return response == GTK_RESPONSE_YES; } #endif #ifdef USE_XF86VM /* */ static void change_gamma (double red, double green, double blue) { XF86VidModeGamma gamma; gamma.red = red / 100.0; gamma.green = green / 100.0; gamma.blue = blue / 100.0; gdk_error_trap_push (); XF86VidModeSetGamma (GDK_DISPLAY (), DefaultScreen (GDK_DISPLAY ()), &gamma); if (gdk_error_trap_pop ()) { g_warning ("display_plugin: Unable to configure display gamma correction"); return; } } #endif /* */ McsPluginInitResult mcs_plugin_init (McsPlugin * plugin) { #ifdef USE_XRANDR XRRScreenConfiguration *sc; #endif McsSetting *setting; gchar *rcfile, *path; #if defined(USE_XF86VM) || defined(USE_XRANDR) int major; int minor; #endif xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8"); /* read settings channel from file */ path = g_build_filename ("xfce4", RCDIR, RCFILE, NULL); rcfile = xfce_resource_lookup (XFCE_RESOURCE_CONFIG, path); if (!rcfile) { rcfile = xfce_get_userfile(OLDRCDIR, RCFILE, NULL); } if (g_file_test (rcfile, G_FILE_TEST_EXISTS)) { mcs_manager_add_channel_from_file(plugin->manager, CHANNEL, rcfile); } else { mcs_manager_add_channel(plugin->manager, CHANNEL); } g_free(path); g_free(rcfile); if ((setting = mcs_manager_setting_lookup (plugin->manager, "XDisplay/size", CHANNEL)) != NULL) { sizeIndex = setting->data.v_int; } else { mcs_manager_set_int (plugin->manager, "XDisplay/size", CHANNEL, sizeIndex); } if ((setting = mcs_manager_setting_lookup (plugin->manager, "XDisplay/rate", CHANNEL)) != NULL) { rateIndex = setting->data.v_int; } else { mcs_manager_set_int (plugin->manager, "XDisplay/rate", CHANNEL, rateIndex); } if ((setting = mcs_manager_setting_lookup (plugin->manager, "XDisplay/rgamma", CHANNEL)) != NULL) { redValue = setting->data.v_int; } else { mcs_manager_set_int (plugin->manager, "XDisplay/rgamma", CHANNEL, redValue); } if ((setting = mcs_manager_setting_lookup (plugin->manager, "XDisplay/ggamma", CHANNEL)) != NULL) { greenValue = setting->data.v_int; } else { mcs_manager_set_int (plugin->manager, "XDisplay/ggamma", CHANNEL, greenValue); } if ((setting = mcs_manager_setting_lookup (plugin->manager, "XDisplay/bgamma", CHANNEL)) != NULL) { blueValue = setting->data.v_int; } else { mcs_manager_set_int (plugin->manager, "XDisplay/bgamma", CHANNEL, blueValue); } if ((setting = mcs_manager_setting_lookup (plugin->manager, "XDisplay/syncGamma", CHANNEL)) != NULL) { syncGamma = setting->data.v_int; } else { mcs_manager_set_int (plugin->manager, "XDisplay/syncGamma", CHANNEL, syncGamma); } #ifdef USE_XRANDR if (XRRQueryVersion (GDK_DISPLAY (), &major, &minor)) { if ((sc = XRRGetScreenInfo (GDK_DISPLAY (), GDK_ROOT_WINDOW ()))) { Rotation current_rotation; gdk_error_trap_push (); /* Save default values */ default_size = XRRConfigCurrentConfiguration (sc, ¤t_rotation); default_rate = XRRConfigCurrentRate (sc); if (!gdk_error_trap_pop ()) { if (sizeIndex >= 0 && rateIndex >= 0) { /* restore resolution and rate */ change_size_and_rate (sc, sizeIndex, rateIndex); } else { sizeIndex = default_size; rateIndex = default_rate; } /* remember that we can use the Xrandr extension */ haveXrandr = TRUE; } XRRFreeScreenConfigInfo (sc); } } #endif #ifdef USE_XF86VM if (XF86VidModeQueryVersion (GDK_DISPLAY (), &major, &minor)) { /* sync the gamma settings */ if (syncGamma) { redValue = greenValue = blueValue = (redValue + greenValue + blueValue) / 3; } /* restore gamma settings */ change_gamma (redValue, greenValue, blueValue); /* remember that we can use the XF86VidMode extension */ haveXxf86vm = TRUE; } #endif plugin->plugin_name = g_strdup ("display"); /* the button label in the xfce-mcs-manager dialog */ plugin->caption = g_strdup (Q_ ("Button Label|Display")); plugin->run_dialog = run_dialog; plugin->icon = xfce_themed_icon_load ("xfce4-display", 48); if (G_LIKELY (plugin->icon != NULL)) g_object_set_data_full (G_OBJECT (plugin->icon), "mcs-plugin-icon-name", g_strdup ("xfce4-display"), g_free); #if 0 /* I fail to see why we need to save the options here, during startup... */ save_settings (plugin); #endif return (MCS_PLUGIN_INIT_OK); } /* */ static gboolean save_settings (McsPlugin * plugin) { gboolean result = FALSE; gchar *rcfile, *path; path = g_build_filename ("xfce4", RCDIR, RCFILE, NULL); rcfile = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, path, TRUE); if (G_LIKELY (rcfile != NULL)) { result = mcs_manager_save_channel_to_file (plugin->manager, CHANNEL, rcfile); g_free(rcfile); } g_free(path); return (result); } #ifdef USE_XRANDR /* */ static void changedCB (GtkTreeSelection * selection, Itf * itf) { XRRScreenConfiguration *sc; GtkTreeModel *store; GtkTreeIter iter; int newsize, newrate; gboolean is_default; /* If new resolution is rejected, we get called * again while restoring the old resolution */ static guint recursion_count = 0; if (!gtk_tree_selection_get_selected (selection, &store, &iter)) return; recursion_count++; gtk_tree_model_get (store, &iter, SIZE_COLUMN, &newsize, RATE_COLUMN, &newrate, -1); /* apply settings */ sc = XRRGetScreenInfo (GDK_DISPLAY (), GDK_ROOT_WINDOW ()); change_size_and_rate (sc, newsize, newrate); XRRFreeScreenConfigInfo (sc); if (recursion_count > 1) { recursion_count--; return; } is_default = ( newsize == default_size && newrate == default_rate ); if (!is_default && !(newsize == itf->original_size && newrate == itf->original_rate)) { if (!confirm_display_mode (itf->dialog)) { /* Restore previous */ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { do { gtk_tree_model_get (store, &iter, RATE_COLUMN, &newrate, SIZE_COLUMN, &newsize, -1); if (newrate == rateIndex && newsize == sizeIndex) { gtk_tree_selection_select_iter (selection, &iter); break; } } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter)); } } } if (newsize != sizeIndex || newrate != rateIndex) { sizeIndex = newsize; rateIndex = newrate; mcs_manager_set_int (itf->plugin->manager, "XDisplay/rate", CHANNEL, is_default ? DEFAULT_RES : newrate); mcs_manager_set_int (itf->plugin->manager, "XDisplay/size", CHANNEL, is_default ? DEFAULT_RES : newsize); mcs_manager_notify (itf->plugin->manager, CHANNEL); save_settings (itf->plugin); } recursion_count--; } #endif #ifdef USE_XF86VM /* */ static void redChangedCB (GtkRange * range, Itf * itf) { double value; value = gtk_range_get_value (range); redValue = (int) (value * 100); /* sync the other slides */ if (syncGamma) { if (greenValue * 100.0 != value) gtk_range_set_value (GTK_RANGE (itf->gscale), value); if (blueValue * 100.0 != value) gtk_range_set_value (GTK_RANGE (itf->bscale), value); } /* apply settings */ change_gamma (redValue, greenValue, blueValue); /* and remember the settings */ mcs_manager_set_int (itf->plugin->manager, "XDisplay/rgamma", CHANNEL, redValue); mcs_manager_notify (itf->plugin->manager, CHANNEL); save_settings (itf->plugin); } /* */ static void greenChangedCB (GtkRange * range, Itf * itf) { double value; value = gtk_range_get_value (range); greenValue = (int) (value * 100); /* sync the other slides */ if (syncGamma) { if (redValue * 100.0 != value) gtk_range_set_value (GTK_RANGE (itf->rscale), value); if (blueValue * 100.0 != value) gtk_range_set_value (GTK_RANGE (itf->bscale), value); } /* apply settings */ change_gamma (redValue, greenValue, blueValue); /* and remember the settings */ mcs_manager_set_int (itf->plugin->manager, "XDisplay/ggamma", CHANNEL, greenValue); mcs_manager_notify (itf->plugin->manager, CHANNEL); save_settings (itf->plugin); } /* */ static void blueChangedCB (GtkRange * range, Itf * itf) { double value; value = gtk_range_get_value (range); blueValue = (int) (value * 100); /* sync the other slides */ if (syncGamma) { if (redValue * 100.0 != value) gtk_range_set_value (GTK_RANGE (itf->rscale), value); if (greenValue * 100.0 != value) gtk_range_set_value (GTK_RANGE (itf->gscale), value); } /* apply settings */ change_gamma (redValue, greenValue, blueValue); /* and remember the settings */ mcs_manager_set_int (itf->plugin->manager, "XDisplay/bgamma", CHANNEL, blueValue); mcs_manager_notify (itf->plugin->manager, CHANNEL); save_settings (itf->plugin); } /* */ static void syncGammaChangedCB (GtkToggleButton * button, Itf * itf) { gint value; syncGamma = gtk_toggle_button_get_active (button); if (syncGamma) { value = (redValue + greenValue + blueValue) / 3; gtk_range_set_value (GTK_RANGE (itf->rscale), value / 100.0); gtk_range_set_value (GTK_RANGE (itf->gscale), value / 100.0); gtk_range_set_value (GTK_RANGE (itf->bscale), value / 100.0); } mcs_manager_set_int (itf->plugin->manager, "XDisplay/syncGamma", CHANNEL, syncGamma); mcs_manager_notify (itf->plugin->manager, CHANNEL); save_settings (itf->plugin); } #endif /* !USE_XF86VM */ /* */ static void responseCB (GtkWidget * widget, gint response, Itf * itf) { switch (response) { case GTK_RESPONSE_CANCEL: { /* revert settings */ if (haveXrandr) { #ifdef USE_XRANDR GtkTreeIter iter; if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (itf->store), &iter)) { gint size, rate; do { gtk_tree_model_get (GTK_TREE_MODEL (itf->store), &iter, SIZE_COLUMN, &size, RATE_COLUMN, &rate, -1 ); if (size == itf->original_size && rate == itf->original_rate) { GtkTreePath *path; path = gtk_tree_model_get_path (GTK_TREE_MODEL (itf->store), &iter); gtk_tree_view_set_cursor (GTK_TREE_VIEW (itf->treeview), path, 0, FALSE); gtk_tree_path_free (path); } } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (itf->store), &iter)); } #endif /* !USE_XRANDR */ } if (haveXxf86vm) { #ifdef USE_XF86VM gint rgamma, ggamma, bgamma; rgamma = itf->original_rgamma; ggamma = itf->original_ggamma; bgamma = itf->original_bgamma; if (itf->original_sync) { rgamma = ggamma = bgamma = (rgamma + ggamma + bgamma) / 3; } gtk_range_set_value (GTK_RANGE (itf->rscale), rgamma / 100); gtk_range_set_value (GTK_RANGE (itf->gscale), ggamma / 100); gtk_range_set_value (GTK_RANGE (itf->bscale), bgamma / 100); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (itf->synctoggle), itf->original_sync); #endif /* !USE_XF86VM */ } } break; default: gtk_widget_destroy (itf->dialog); } } /* */ static void run_dialog (McsPlugin * plugin) { GtkTreeSelection *selection; GtkListStore *store; GtkWidget *revert; GtkWidget *close; GtkWidget *hbox; GtkWidget *align; GtkWidget *frame; GtkWidget *vbox; GtkWidget *treeview; GtkWidget *scrollwin; GtkWidget *table; GtkWidget *rlabel; GtkWidget *glabel; GtkWidget *blabel; GtkWidget *checkbox; GtkWidget *dialog; GtkWidget *rscale; GtkWidget *gscale; GtkWidget *bscale; static Itf *itf = NULL; if (itf != NULL) { gtk_window_present (GTK_WINDOW (itf->dialog)); return; } xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8"); itf = g_new( Itf, 1 ); itf->plugin = plugin; itf->dialog = dialog = xfce_titled_dialog_new_with_buttons (_("Display Preferences"), NULL, GTK_DIALOG_NO_SEPARATOR, NULL); gtk_window_set_icon_name (GTK_WINDOW (dialog), "xfce4-display"); g_signal_connect_swapped (G_OBJECT (dialog), "destroy", G_CALLBACK (g_free), itf); g_signal_connect (G_OBJECT (dialog), "destroy", G_CALLBACK (gtk_widget_destroyed), &itf); /* action widgets */ gtk_button_box_set_layout (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), GTK_BUTTONBOX_EDGE); revert = gtk_button_new_from_stock (GTK_STOCK_REVERT_TO_SAVED); gtk_dialog_add_action_widget (GTK_DIALOG (dialog), revert, GTK_RESPONSE_CANCEL); close = gtk_button_new_from_stock (GTK_STOCK_CLOSE); gtk_dialog_add_action_widget (GTK_DIALOG (dialog), close, GTK_RESPONSE_CLOSE); GTK_WIDGET_SET_FLAGS (close, GTK_CAN_DEFAULT); gtk_widget_grab_default (close); gtk_widget_grab_focus (close); gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); g_signal_connect (dialog, "response", G_CALLBACK (responseCB), itf); /* */ hbox = gtk_hbox_new (FALSE, BORDER); gtk_container_set_border_width (GTK_CONTAINER (hbox), BORDER); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0); /* */ align = gtk_alignment_new (0, 0, 0, 0); gtk_widget_set_size_request (align, BORDER, BORDER); gtk_box_pack_start (GTK_BOX (hbox), align, FALSE, TRUE, 0); /* resolution settings */ vbox = gtk_vbox_new (FALSE, BORDER); gtk_container_set_border_width (GTK_CONTAINER (vbox), BORDER); frame = xfce_create_framebox_with_content (_("Resolution"), vbox); gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); /* create the surrounding scrolled window */ scrollwin = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_IN); gtk_box_pack_start (GTK_BOX (vbox), scrollwin, TRUE, TRUE, 0); /* create store */ itf->store = store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_BOOLEAN); /* create tree view */ itf->treeview = treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); gtk_widget_set_size_request (treeview, -1, 200); gtk_container_add (GTK_CONTAINER (scrollwin), treeview); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); /* create treeview columns */ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), gtk_tree_view_column_new_with_attributes ("", gtk_cell_renderer_text_new (), "text", NAME_COLUMN, NULL)); if (haveXrandr) { #ifdef USE_XRANDR XRRScreenConfiguration *sc; Rotation current_rotation; XRRScreenSize *sizes; int nsizes, i, j; int current_rate; int current_size; GtkTreePath *path; GtkTreeIter iter; sc = XRRGetScreenInfo (GDK_DISPLAY (), GDK_ROOT_WINDOW ()); /* XXX */ g_assert (sc != NULL); sizes = XRRConfigSizes (sc, &nsizes); current_rate = XRRConfigCurrentRate (sc); current_size = XRRConfigCurrentConfiguration (sc, ¤t_rotation); /* Add default entry */ gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, NAME_COLUMN, "Default", SIZE_COLUMN, default_size, RATE_COLUMN, default_rate, DEFAULT_RES); path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); gtk_tree_view_set_cursor (GTK_TREE_VIEW (treeview), path, 0, FALSE); gtk_tree_path_free (path); /* fill store */ for (i = 0; i < nsizes; i++) { gchar *buffer; short *rates; int nrates; /* query rates for this size */ rates = XRRConfigRates (sc, i, &nrates); for (j = 0; j < nrates; j++) { buffer = g_strdup_printf (_("%dx%d@%d"), sizes[i].width, sizes[i].height, (int) rates[j]); if (i != default_size || rates[j] != default_rate) { gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, NAME_COLUMN, buffer, SIZE_COLUMN, (int) i, RATE_COLUMN, (int) rates[j], -1); if (i == current_size && rates[j] == current_rate) { path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); gtk_tree_view_set_cursor (GTK_TREE_VIEW (treeview), path, 0, FALSE); gtk_tree_path_free (path); } } g_free (buffer); } } /* no longer needed */ XRRFreeScreenConfigInfo (sc); /* connect the changed callback */ g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (changedCB), itf); /* Store values to revert to */ itf->original_size = current_size; itf->original_rate = current_rate; #endif /* !USE_XRANDR */ } else { /* * either no XRandr support compiled in, or no Xrandr * available for the display we are running on */ gtk_widget_set_sensitive (treeview, FALSE); } /* treeview now keeps a reference on the backstore */ g_object_unref (G_OBJECT (store)); /* gamma settings */ vbox = gtk_vbox_new (FALSE, BORDER); gtk_container_set_border_width (GTK_CONTAINER (vbox), BORDER); frame = xfce_create_framebox_with_content (_("Gamma correction"), vbox); gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); /* */ table = gtk_table_new (3, 3, FALSE); gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0); /* Red */ rlabel = gtk_label_new (_("Red")); gtk_table_attach (GTK_TABLE (table), rlabel, 0, 1, 0, 1, GTK_FILL, GTK_FILL, BORDER, BORDER); itf->rscale = rscale = gtk_vscale_new_with_range (GAMMA_MIN, GAMMA_MAX, 0.01); gtk_range_set_inverted (GTK_RANGE (rscale), TRUE); gtk_range_set_value (GTK_RANGE (rscale), redValue / 100.0); gtk_scale_set_digits (GTK_SCALE (rscale), 2); gtk_scale_set_draw_value (GTK_SCALE (rscale), TRUE); gtk_scale_set_value_pos (GTK_SCALE (rscale), GTK_POS_BOTTOM); gtk_table_attach (GTK_TABLE (table), rscale, 0, 1, 1, 2, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); /* Green */ glabel = gtk_label_new (_("Green")); gtk_table_attach (GTK_TABLE (table), glabel, 1, 2, 0, 1, GTK_FILL, GTK_FILL, BORDER, BORDER); itf->gscale = gscale = gtk_vscale_new_with_range (GAMMA_MIN, GAMMA_MAX, 0.01); gtk_range_set_value (GTK_RANGE (gscale), greenValue / 100.0); gtk_range_set_inverted (GTK_RANGE (gscale), TRUE); gtk_scale_set_digits (GTK_SCALE (gscale), 2); gtk_scale_set_draw_value (GTK_SCALE (gscale), TRUE); gtk_scale_set_value_pos (GTK_SCALE (gscale), GTK_POS_BOTTOM); gtk_table_attach (GTK_TABLE (table), gscale, 1, 2, 1, 2, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); /* Blue */ blabel = gtk_label_new (_("Blue")); gtk_table_attach (GTK_TABLE (table), blabel, 2, 3, 0, 1, GTK_FILL, GTK_FILL, BORDER, BORDER); itf->bscale = bscale = gtk_vscale_new_with_range (GAMMA_MIN, GAMMA_MAX, 0.01); gtk_range_set_value (GTK_RANGE (bscale), blueValue / 100.0); gtk_range_set_inverted (GTK_RANGE (bscale), TRUE); gtk_scale_set_digits (GTK_SCALE (bscale), 2); gtk_scale_set_draw_value (GTK_SCALE (bscale), TRUE); gtk_scale_set_value_pos (GTK_SCALE (bscale), GTK_POS_BOTTOM); gtk_table_attach (GTK_TABLE (table), bscale, 2, 3, 1, 2, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); /* */ itf->synctoggle = checkbox = gtk_check_button_new_with_label (_("Sync sliders")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox), syncGamma); gtk_table_attach (GTK_TABLE (table), checkbox, 0, 3, 2, 3, GTK_FILL, GTK_FILL, 0, BORDER); #ifdef USE_XF86VM if (haveXxf86vm) { /* Store values to revert to */ itf->original_rgamma = redValue; itf->original_ggamma = greenValue; itf->original_bgamma = blueValue; itf->original_sync = syncGamma; g_signal_connect (G_OBJECT (rscale), "value-changed", G_CALLBACK (redChangedCB), itf); g_signal_connect (G_OBJECT (gscale), "value-changed", G_CALLBACK (greenChangedCB), itf); g_signal_connect (G_OBJECT (bscale), "value-changed", G_CALLBACK (blueChangedCB), itf); g_signal_connect (G_OBJECT (checkbox), "toggled", G_CALLBACK (syncGammaChangedCB), itf); } else #endif { gtk_widget_set_sensitive (rlabel, FALSE); gtk_widget_set_sensitive (rscale, FALSE); gtk_widget_set_sensitive (glabel, FALSE); gtk_widget_set_sensitive (gscale, FALSE); gtk_widget_set_sensitive (blabel, FALSE); gtk_widget_set_sensitive (bscale, FALSE); gtk_widget_set_sensitive (checkbox, FALSE); } /* */ gtk_widget_realize (dialog); gdk_x11_window_set_user_time(GTK_WIDGET (dialog)->window, gdk_x11_get_server_time (GTK_WIDGET (dialog)->window)); gtk_widget_show_all (dialog); } /* */ MCS_PLUGIN_CHECK_INIT