summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2003-04-23 15:01:16 +0000
committerAlexander Larsson <alexl@src.gnome.org>2003-04-23 15:01:16 +0000
commit2ff82733227428136ed9d8978ab54cf2e0a5a235 (patch)
tree996e560f21a7058565ba22593edeb70831a7a149
parent826fd514fc4c7c764063392e833a0eec5f6cc47b (diff)
downloadgnome-control-center-2ff82733227428136ed9d8978ab54cf2e0a5a235.tar.gz
Initial import. UI not fully polished yet.
2003-04-23 Alexander Larsson <alexl@redhat.com> * .cvsignore: * display-capplet.png: * display-properties.desktop.in: * main.c: * Makefile.am: Initial import. UI not fully polished yet. 2003-04-23 Alexander Larsson <alexl@redhat.com> * capplets/Makefile.am: * configure.in: * capplets/display/* Check for XRandR support. Add display capplet.
-rw-r--r--ChangeLog8
-rw-r--r--capplets/Makefile.am12
-rw-r--r--capplets/display/.cvsignore6
-rw-r--r--capplets/display/Makefile.am26
-rw-r--r--capplets/display/display-capplet.pngbin0 -> 4353 bytes
-rw-r--r--capplets/display/display-properties.desktop.in13
-rw-r--r--capplets/display/main.c778
-rw-r--r--configure.in26
8 files changed, 865 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index fb1ca0306..e7a67388d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2003-04-23 Alexander Larsson <alexl@redhat.com>
+
+ * capplets/Makefile.am:
+ * configure.in:
+ * capplets/display/*
+ Check for XRandR support.
+ Add display capplet.
+
2003-03-21 Guntupalli Karunakar <karunakar@freedomink.org>
* configure.in: Added "ml" in ALL_LINGUAS.
diff --git a/capplets/Makefile.am b/capplets/Makefile.am
index 5db9da3c8..b370bbafd 100644
--- a/capplets/Makefile.am
+++ b/capplets/Makefile.am
@@ -3,12 +3,18 @@ always_built_SUBDIRS = \
default-applications desktop-links font \
background keyboard mouse sound \
file-types theme-switcher ui-properties \
- keybindings network windows
+ keybindings network windows
-SUBDIRS = $(always_built_SUBDIRS)
+if HAVE_RANDR
+randr_SUBDIRS = display
+else
+randr_SUBDIRS =
+endif
+
+SUBDIRS = $(always_built_SUBDIRS) $(randr_SUBDIRS)
DIST_SUBDIRS = \
- $(always_built_SUBDIRS)
+ $(always_built_SUBDIRS) display
diff --git a/capplets/display/.cvsignore b/capplets/display/.cvsignore
new file mode 100644
index 000000000..b0d2b5028
--- /dev/null
+++ b/capplets/display/.cvsignore
@@ -0,0 +1,6 @@
+Makefile
+Makefile.in
+.deps
+.libs
+gnome-display-properties
+display-properties.desktop
diff --git a/capplets/display/Makefile.am b/capplets/display/Makefile.am
new file mode 100644
index 000000000..e179722b5
--- /dev/null
+++ b/capplets/display/Makefile.am
@@ -0,0 +1,26 @@
+bin_PROGRAMS = gnome-display-properties
+
+gnome_display_properties_LDADD = $(DISPLAY_CAPPLET_LIBS) $(top_builddir)/capplets/common/libcommon.la
+gnome_display_properties_SOURCES = \
+ main.c
+gnome_display_properties_LDFLAGS = -export-dynamic
+
+@INTLTOOL_DESKTOP_RULE@
+
+iconsdir = $(GNOMECC_ICONS_DIR)
+icons_DATA = display-capplet.png
+
+desktop_iconsdir = $(datadir)/pixmaps
+desktop_icons_DATA = display-capplet.png
+
+desktopdir = $(GNOMECC_DESKTOP_DIR)
+Desktop_in_files = display-properties.desktop.in
+desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop)
+
+INCLUDES = $(DISPLAY_CAPPLET_CFLAGS) \
+ $(GNOMECC_CAPPLETS_CFLAGS) \
+ -DGLADEDIR=\""$(gladedir)"\" \
+ -DPIXMAPDIR=\""$(pixmapdir)"\"
+
+CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES)
+EXTRA_DIST = $(Desktop_in_files) $(icons_DATA)
diff --git a/capplets/display/display-capplet.png b/capplets/display/display-capplet.png
new file mode 100644
index 000000000..90c25fb76
--- /dev/null
+++ b/capplets/display/display-capplet.png
Binary files differ
diff --git a/capplets/display/display-properties.desktop.in b/capplets/display/display-properties.desktop.in
new file mode 100644
index 000000000..80fdd2d45
--- /dev/null
+++ b/capplets/display/display-properties.desktop.in
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Encoding=UTF-8
+_Name=Screen Resolution
+_Comment=Change screen resolution
+Exec=gnome-display-properties
+Icon=display-capplet.png
+Terminal=false
+Type=Application
+StartupNotify=true
+Categories=GNOME;Settings;Appearance;
+X-GNOME-Bugzilla-Bugzilla=GNOME
+X-GNOME-Bugzilla-Product=control-center
+X-GNOME-Bugzilla-Component=display properties
diff --git a/capplets/display/main.c b/capplets/display/main.c
new file mode 100644
index 000000000..fe892d6a1
--- /dev/null
+++ b/capplets/display/main.c
@@ -0,0 +1,778 @@
+#include <config.h>
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <gconf/gconf-client.h>
+#include <glade/glade.h>
+#include <gdk/gdkx.h>
+
+#include <X11/extensions/Xrandr.h>
+
+#include "capplet-util.h"
+
+#define REVERT_COUNT 20
+
+struct ScreenInfo {
+ int current_width;
+ int current_height;
+ SizeID current_size;
+ short current_rate;
+ Rotation current_rotation;
+
+ XRRScreenConfiguration *config;
+ XRRScreenSize *sizes;
+ int n_sizes;
+
+ GtkWidget *resolution_widget;
+ GtkWidget *rate_widget;
+};
+
+struct DisplayInfo {
+ int n_screens;
+ struct ScreenInfo *screens;
+
+ GtkWidget *per_computer_check;
+ gboolean was_per_computer;
+};
+
+
+struct DisplayInfo *
+read_display_info (GdkDisplay *display)
+{
+ struct DisplayInfo *info;
+ struct ScreenInfo *screen_info;
+ GdkScreen *screen;
+ GdkWindow *root_window;
+ int i;
+
+ info = g_new (struct DisplayInfo, 1);
+ info->n_screens = gdk_display_get_n_screens (display);
+ info->screens = g_new (struct ScreenInfo, info->n_screens);
+
+ for (i = 0; i < info->n_screens; i++)
+ {
+ screen = gdk_display_get_screen (display, i);
+
+ screen_info = &info->screens[i];
+ screen_info->current_width = gdk_screen_get_width (screen);
+ screen_info->current_height = gdk_screen_get_height (screen);
+
+ root_window = gdk_screen_get_root_window (screen);
+ screen_info->config = XRRGetScreenInfo (gdk_x11_display_get_xdisplay (display),
+ gdk_x11_drawable_get_xid (GDK_DRAWABLE (root_window)));
+
+ screen_info->current_rate = XRRConfigCurrentRate (screen_info->config);
+ screen_info->current_size = XRRConfigCurrentConfiguration (screen_info->config, &screen_info->current_rotation);
+ screen_info->sizes = XRRConfigSizes (screen_info->config, &screen_info->n_sizes);
+ }
+
+ return info;
+}
+
+static int
+get_current_resolution (struct ScreenInfo *screen_info)
+{
+ GtkWidget *menu;
+ GList *children;
+ GList *child;
+ int i;
+
+ i = gtk_option_menu_get_history (GTK_OPTION_MENU (screen_info->resolution_widget));
+ menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (screen_info->resolution_widget));
+ children = gtk_container_get_children (GTK_CONTAINER (menu));
+ child = g_list_nth (children, i);
+
+ if (child != NULL)
+ return GPOINTER_TO_INT (g_object_get_data (child->data, "screen_nr"));
+ else
+ return 0;
+}
+
+static int
+get_current_rate (struct ScreenInfo *screen_info)
+{
+ GtkWidget *menu;
+ GList *children;
+ GList *child;
+ int i;
+
+ i = gtk_option_menu_get_history (GTK_OPTION_MENU (screen_info->rate_widget));
+ menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (screen_info->rate_widget));
+ children = gtk_container_get_children (GTK_CONTAINER (menu));
+ child = g_list_nth (children, i);
+
+ if (child != NULL)
+ return GPOINTER_TO_INT (g_object_get_data (child->data, "rate"));
+ else
+ return 0;
+}
+
+static gboolean
+apply_config (struct DisplayInfo *info)
+{
+ int i;
+ GdkDisplay *display;
+ Display *xdisplay;
+ GdkScreen *screen;
+ gboolean changed;
+
+ display = gdk_display_get_default ();
+ xdisplay = gdk_x11_display_get_xdisplay (display);
+
+ changed = FALSE;
+ for (i = 0; i < info->n_screens; i++)
+ {
+ struct ScreenInfo *screen_info = &info->screens[i];
+ Status status;
+ GdkWindow *root_window;
+ int new_res, new_rate;
+
+ screen = gdk_display_get_screen (display, i);
+ root_window = gdk_screen_get_root_window (screen);
+
+ new_res = get_current_resolution (screen_info);
+ new_rate = get_current_rate (screen_info);
+
+ if (new_res != screen_info->current_size ||
+ new_rate != screen_info->current_rate)
+ {
+ changed = TRUE;
+ status = XRRSetScreenConfigAndRate (xdisplay,
+ screen_info->config,
+ gdk_x11_drawable_get_xid (GDK_DRAWABLE (root_window)),
+ new_res,
+ screen_info->current_rotation,
+ new_rate,
+ GDK_CURRENT_TIME);
+ }
+ }
+
+ return changed;
+}
+
+static int
+revert_config (struct DisplayInfo *info)
+{
+ int i;
+ GdkDisplay *display;
+ Display *xdisplay;
+ GdkScreen *screen;
+
+ display = gdk_display_get_default ();
+ xdisplay = gdk_x11_display_get_xdisplay (display);
+
+ for (i = 0; i < info->n_screens; i++)
+ {
+ struct ScreenInfo *screen_info = &info->screens[i];
+ Status status;
+ GdkWindow *root_window;
+
+ screen = gdk_display_get_screen (display, i);
+ root_window = gdk_screen_get_root_window (screen);
+
+ status = XRRSetScreenConfigAndRate (xdisplay,
+ screen_info->config,
+ gdk_x11_drawable_get_xid (GDK_DRAWABLE (root_window)),
+ screen_info->current_size,
+ screen_info->current_rotation,
+ screen_info->current_rate,
+ GDK_CURRENT_TIME);
+ }
+ return 0;
+}
+
+static GtkWidget *
+wrap_in_label (GtkWidget *child, char *text)
+{
+ GtkWidget *vbox, *hbox;
+ GtkWidget *label;
+ char *str;
+
+ vbox = gtk_vbox_new (FALSE, 6);
+ label = 0;
+
+ label = gtk_label_new ("");
+
+ str = g_strdup_printf ("<b>%s</b>", text);
+ gtk_label_set_markup (GTK_LABEL (label), str);
+ g_free (str);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_widget_show (label);
+ gtk_box_pack_start (GTK_BOX (vbox),
+ label,
+ FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new (FALSE, 0);
+
+ label = gtk_label_new (" ");
+ gtk_widget_show (label);
+ gtk_box_pack_start (GTK_BOX (hbox),
+ label,
+ FALSE, FALSE, 0);
+
+ gtk_box_pack_start (GTK_BOX (hbox),
+ child,
+ TRUE, TRUE, 0);
+
+ gtk_widget_show (hbox);
+
+ gtk_box_pack_start (GTK_BOX (vbox),
+ hbox,
+ FALSE, FALSE, 0);
+
+ gtk_widget_show (vbox);
+
+ return vbox;
+}
+
+static gboolean
+show_resolution (int width, int height)
+{
+ if (width >= 800 && height >= 600)
+ return TRUE;
+
+ if (width == 640 && height == 480)
+ return TRUE;
+
+ return FALSE;
+}
+
+static void
+generate_rate_menu (struct ScreenInfo *screen_info)
+{
+ GtkWidget *menu;
+ GtkWidget *menuitem;
+ short *rates;
+ int nrates, i;
+ int size_nr;
+ char *str;
+ int closest_rate_nr;
+
+ gtk_option_menu_remove_menu (GTK_OPTION_MENU (screen_info->rate_widget));
+
+ menu = gtk_menu_new ();
+
+ size_nr = get_current_resolution (screen_info);
+
+ closest_rate_nr = -1;
+ rates = XRRConfigRates (screen_info->config, size_nr, &nrates);
+ for (i = 0; i < nrates; i++)
+ {
+ str = g_strdup_printf (_("%d Hz"), rates[i]);
+
+ if ((closest_rate_nr < 0) ||
+ (ABS (rates[i] - screen_info->current_rate) <
+ ABS (rates[closest_rate_nr] - screen_info->current_rate)))
+ closest_rate_nr = i;
+
+ menuitem = gtk_menu_item_new_with_label (str);
+
+ g_object_set_data (G_OBJECT (menuitem), "rate", GINT_TO_POINTER ((int)rates[i]));
+
+ g_free (str);
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ }
+
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (screen_info->rate_widget), menu);
+ gtk_option_menu_set_history (GTK_OPTION_MENU (screen_info->rate_widget),
+ closest_rate_nr);
+}
+
+static void
+resolution_changed_callback (GtkWidget *optionmenu,
+ struct ScreenInfo *screen_info)
+{
+ generate_rate_menu (screen_info);
+}
+
+static GtkWidget *
+create_resolution_menu (struct ScreenInfo *screen_info)
+{
+ GtkWidget *optionmenu;
+ GtkWidget *menu;
+ GtkWidget *menuitem;
+ int i, item, current_item;
+ XRRScreenSize *sizes;
+ char *str;
+ SizeID current_size;
+ Rotation rot;
+
+ screen_info->resolution_widget = optionmenu = gtk_option_menu_new ();
+
+ menu = gtk_menu_new ();
+
+ current_size = XRRConfigCurrentConfiguration (screen_info->config, &rot);
+
+ current_item = 0;
+ item = 0;
+ sizes = screen_info->sizes;
+ for (i = 0; i < screen_info->n_sizes; i++)
+ {
+ if (i == current_size || show_resolution (sizes[i].width, sizes[i].height))
+ {
+ str = g_strdup_printf ("%dx%d", sizes[i].width, sizes[i].height);
+
+ if (i == current_size)
+ current_item = item;
+
+ menuitem = gtk_menu_item_new_with_label (str);
+
+ g_object_set_data (G_OBJECT (menuitem), "screen_nr", GINT_TO_POINTER (i));
+
+ g_free (str);
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ item++;
+ }
+ }
+
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);
+ gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu),
+ current_item);
+
+ g_signal_connect (optionmenu, "changed",
+ G_CALLBACK (resolution_changed_callback), screen_info);
+
+ gtk_widget_show (optionmenu);
+ return optionmenu;
+}
+
+static GtkWidget *
+create_rate_menu (struct ScreenInfo *screen_info)
+{
+ GtkWidget *optionmenu;
+
+ screen_info->rate_widget = optionmenu = gtk_option_menu_new ();
+
+ generate_rate_menu (screen_info);
+
+ gtk_widget_show (optionmenu);
+ return optionmenu;
+}
+
+static GtkWidget *
+create_screen_widgets (struct ScreenInfo *screen_info, int nr, gboolean no_header)
+{
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *option_menu;
+ char *str;
+
+ table = gtk_table_new (2, 2, FALSE);
+
+ gtk_table_set_row_spacings ( GTK_TABLE (table), 6);
+ gtk_table_set_col_spacings ( GTK_TABLE (table), 12);
+
+ label = gtk_label_new (_("Resolution:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_widget_show (label);
+ gtk_table_attach (GTK_TABLE (table),
+ label,
+ 0, 1,
+ 0, 1,
+ GTK_FILL, 0,
+ 0, 0);
+
+ option_menu = create_resolution_menu (screen_info);
+ gtk_table_attach (GTK_TABLE (table),
+ option_menu,
+ 1, 2,
+ 0, 1,
+ GTK_FILL | GTK_EXPAND, 0,
+ 0, 0);
+
+ label = gtk_label_new (_("Refresh rate:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_widget_show (label);
+ gtk_table_attach (GTK_TABLE (table),
+ label,
+ 0, 1,
+ 1, 2,
+ GTK_FILL, 0,
+ 0, 0);
+ gtk_widget_show (table);
+
+ option_menu = create_rate_menu (screen_info);
+ gtk_table_attach (GTK_TABLE (table),
+ option_menu,
+ 1, 2,
+ 1, 2,
+ GTK_FILL | GTK_EXPAND, 0,
+ 0, 0);
+
+ if (nr == 0)
+ str = g_strdup (_("Default Settings"));
+ else
+ str = g_strdup_printf (_("Screen %d Settings\n"), nr+1);
+ return wrap_in_label (table, str);
+
+ g_free (str);
+}
+
+
+static GtkWidget *
+create_dialog (struct DisplayInfo *info)
+{
+ GtkWidget *dialog;
+ GtkWidget *screen_widget;
+ GtkWidget *per_computer_check;
+ int i;
+ GtkWidget *wrapped;
+ GConfClient *client;
+ char *key;
+ char *resolution;
+ char *str;
+#ifdef HOST_NAME_MAX
+ char hostname[HOST_NAME_MAX + 1];
+#else
+ char hostname[256];
+#endif
+
+ dialog = gtk_dialog_new_with_buttons (_("Screen Resolution Preferences"),
+ NULL,
+ GTK_DIALOG_NO_SEPARATOR,
+ "gtk-apply",
+ GTK_RESPONSE_APPLY,
+ "gtk-help",
+ GTK_RESPONSE_HELP,
+ NULL);
+
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
+ gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 12);
+ capplet_set_icon (dialog, "display-capplet.png");
+
+ for (i = 0; i < info->n_screens; i++)
+ {
+ screen_widget = create_screen_widgets (&info->screens[i], i, info->n_screens == 1);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+ screen_widget, FALSE, FALSE, 0);
+ gtk_widget_show (screen_widget);
+ }
+
+ per_computer_check = NULL;
+ info->was_per_computer = FALSE;
+ if (gethostname (hostname, sizeof (hostname)) == 0 &&
+ strcmp (hostname, "localhost") != 0 &&
+ strcmp (hostname, "localhost.localdomain") != 0)
+ {
+
+ str = g_strdup_printf (_("Make default for this _computer (%s) only"), hostname);
+ per_computer_check = gtk_check_button_new_with_mnemonic (str);
+
+ /* If we previously set the resolution specifically for this hostname, default
+ to it on */
+ client = gconf_client_get_default ();
+ key = g_strconcat ("/desktop/gnome/screen/", hostname, "/0/resolution",NULL);
+ resolution = gconf_client_get_string (client, key, NULL);
+ g_free (resolution);
+ g_free (key);
+ g_object_unref (client);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (per_computer_check),
+ resolution != NULL);
+ info->was_per_computer = resolution != NULL;
+
+ gtk_widget_show (per_computer_check);
+
+ wrapped = wrap_in_label (per_computer_check, _("Options"));
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+ wrapped, FALSE, FALSE, 0);
+ gtk_widget_show (wrapped);
+ }
+
+ info->per_computer_check = per_computer_check;
+
+ return dialog;
+}
+
+struct TimeoutData {
+ int time;
+ GtkLabel *label;
+ GtkDialog *dialog;
+ gboolean timed_out;
+};
+
+char *
+timeout_string (int time)
+{
+ return g_strdup_printf (_("Testing the new settings. If you don't respond in %d seconds the previous settings will be restored."), time);
+}
+
+gboolean
+save_timeout_callback (gpointer _data)
+{
+ struct TimeoutData *data = _data;
+ char *str;
+
+ data->time--;
+
+ if (data->time == 0)
+ {
+ gtk_dialog_response (data->dialog, GTK_RESPONSE_NO);
+ data->timed_out = TRUE;
+ return FALSE;
+ }
+
+ str = timeout_string (data->time);
+ gtk_label_set_text (data->label, str);
+ g_free (str);
+
+ return TRUE;
+}
+
+static int
+run_revert_dialog (struct DisplayInfo *info,
+ GtkWidget *parent)
+{
+ GtkWidget *dialog;
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *label_sec;
+ GtkWidget *image;
+ int res;
+ struct TimeoutData timeout_data;
+ guint timeout;
+ char *str;
+
+ dialog = gtk_dialog_new ();
+ gtk_window_set_transient_for (GTK_WINDOW (dialog),
+ GTK_WINDOW (parent));
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
+ gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+ gtk_window_set_title (GTK_WINDOW (dialog), "");
+
+ label = gtk_label_new (NULL);
+ str = g_strdup_printf ("<b>%s</b>", _("Do you want to keep this resolution?"));
+ gtk_label_set_markup (GTK_LABEL (label), str);
+ g_free (str);
+ image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
+ gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
+
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ gtk_label_set_selectable (GTK_LABEL (label), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+ str = timeout_string (REVERT_COUNT);
+ label_sec = gtk_label_new (str);
+ g_free (str);
+ gtk_label_set_line_wrap (GTK_LABEL (label_sec), TRUE);
+ gtk_label_set_selectable (GTK_LABEL (label_sec), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (label_sec), 0.0, 0.5);
+
+ hbox = gtk_hbox_new (FALSE, 6);
+ vbox = gtk_vbox_new (FALSE, 6);
+
+ gtk_box_pack_start (GTK_BOX (vbox), label,
+ TRUE, TRUE, 0);
+
+ gtk_box_pack_start (GTK_BOX (vbox), label_sec,
+ TRUE, TRUE, 0);
+
+ gtk_box_pack_start (GTK_BOX (hbox), image,
+ FALSE, FALSE, 0);
+
+ gtk_box_pack_start (GTK_BOX (hbox), vbox,
+ TRUE, TRUE, 0);
+
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+ hbox,
+ FALSE, FALSE, 0);
+
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ _("Use _previous resolution"),
+ GTK_RESPONSE_NO,
+ _("_Keep resolution"),
+ GTK_RESPONSE_YES,
+ NULL);
+
+ gtk_widget_show_all (hbox);
+
+ timeout_data.time = REVERT_COUNT;
+ timeout_data.label = GTK_LABEL (label_sec);
+ timeout_data.dialog = GTK_DIALOG (dialog);
+ timeout_data.timed_out = FALSE;
+
+ timeout = g_timeout_add (1000,
+ save_timeout_callback,
+ &timeout_data);
+
+ res = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (!timeout_data.timed_out)
+ g_source_remove (timeout);
+
+ gtk_widget_destroy (dialog);
+
+ return res == GTK_RESPONSE_YES;
+}
+
+static void
+save_to_gconf (struct DisplayInfo *info, gboolean save_computer, gboolean clear_computer)
+{
+ GConfClient *client;
+ gboolean res;
+#ifdef HOST_NAME_MAX
+ char hostname[HOST_NAME_MAX + 1];
+#else
+ char hostname[256];
+#endif
+ char *path, *key, *str;
+ int i;
+
+ gethostname (hostname, sizeof(hostname));
+
+ client = gconf_client_get_default ();
+
+ if (clear_computer)
+ {
+ for (i = 0; i < info->n_screens; i++)
+ {
+ key = g_strdup_printf ("/desktop/gnome/screen/%s/%d/resolution",
+ hostname, i);
+ gconf_client_unset (client, key, NULL);
+ g_free (key);
+ key = g_strdup_printf ("/desktop/gnome/screen/%s/%d/rate",
+ hostname, i);
+ gconf_client_unset (client, key, NULL);
+ g_free (key);
+ }
+ }
+
+ if (save_computer)
+ {
+ path = g_strconcat ("/desktop/gnome/screen/",
+ hostname,
+ "/",
+ NULL);
+ }
+ else
+ path = g_strdup ("/desktop/gnome/screen/default/");
+
+ for (i = 0; i < info->n_screens; i++)
+ {
+ struct ScreenInfo *screen_info = &info->screens[i];
+ int new_res, new_rate;
+
+ new_res = get_current_resolution (screen_info);
+ new_rate = get_current_rate (screen_info);
+
+ key = g_strdup_printf ("%s%d/resolution", path, i);
+ str = g_strdup_printf ("%dx%d",
+ screen_info->sizes[new_res].width,
+ screen_info->sizes[new_res].height);
+
+ res = gconf_client_set_string (client, key, str, NULL);
+ g_free (str);
+ g_free (key);
+
+ key = g_strdup_printf ("%s%d/rate", path, i);
+ res = gconf_client_set_int (client, key, new_rate, NULL);
+ g_free (key);
+ }
+
+ g_free (path);
+ g_object_unref (client);
+}
+
+static void
+cb_dialog_response (GtkDialog *dialog, gint response_id, struct DisplayInfo *info)
+{
+ gboolean save_computer, clear_computer;
+
+ switch (response_id)
+ {
+ case GTK_RESPONSE_DELETE_EVENT:
+ gtk_main_quit ();
+ break;
+ case GTK_RESPONSE_HELP:
+ /* FIXME: This needs to be changed to the right section
+ * when the docs have been written. */
+ capplet_help (GTK_WINDOW (dialog),
+ "wgoscustdesk.xml",
+ "goscustdesk-38");
+ break;
+ case GTK_RESPONSE_APPLY:
+ save_computer = info->per_computer_check != NULL && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (info->per_computer_check));
+ clear_computer = !save_computer && info->was_per_computer;
+
+ if (apply_config (info))
+ {
+ if (!run_revert_dialog (info, GTK_WIDGET (dialog)))
+ {
+ revert_config (info);
+ return;
+ }
+ }
+
+ save_to_gconf (info, save_computer, clear_computer);
+ gtk_main_quit ();
+ break;
+ }
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int major, minor;
+ int event_base, error_base;
+ GdkDisplay *display;
+ GtkWidget *dialog;
+ struct DisplayInfo *info;
+ Display *xdisplay;
+
+ bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ gnome_program_init ("gnome-display-properties", VERSION,
+ LIBGNOMEUI_MODULE, argc, argv,
+ GNOME_PARAM_APP_DATADIR, GNOMECC_DATA_DIR,
+ NULL);
+
+ display = gdk_display_get_default ();
+ xdisplay = gdk_x11_display_get_xdisplay (display);
+
+ if (!XRRQueryExtension (xdisplay, &event_base, &error_base) ||
+ XRRQueryVersion (xdisplay, &major, &minor) == 0)
+ {
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ _("The Xserver doesn't support the XRandR extension, runtime resolution changes aren't possible."));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ exit (0);
+ }
+
+ if (major != 1 || minor < 1)
+ {
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ _("The version of the XRandR extension is incompatible with this program, runtime resolution changes aren't possible."));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ exit (0);
+ }
+
+ info = read_display_info (display);
+
+ dialog = create_dialog (info);
+
+ g_signal_connect (G_OBJECT (dialog),
+ "response",
+ G_CALLBACK (cb_dialog_response), info);
+
+ gtk_widget_show (dialog);
+
+ gtk_main ();
+
+ return 0;
+}
diff --git a/configure.in b/configure.in
index ba70e6a40..29fe13b31 100644
--- a/configure.in
+++ b/configure.in
@@ -47,6 +47,7 @@ AC_SUBST(XF86MISC_LIBS)
AC_CHECK_HEADERS(X11/extensions/XKB.h)
CPPFLAGS=$savecppflags
+
dnl ==============================================
dnl Check that we meet the dependencies
dnl ==============================================
@@ -72,7 +73,26 @@ if $PKG_CONFIG --exists xft ; then
fi
PKG_CHECK_MODULES(FONT_CAPPLET, $COMMON_MODULES $xft_modules)
-
+
+dnl
+dnl Check for XRandR, needed for display capplet
+dnl
+
+have_randr=no
+AC_CHECK_LIB(Xrandr, XRRUpdateConfiguration,
+ [AC_CHECK_HEADER(X11/extensions/Xrandr.h,
+ have_randr=yes
+ RANDR_LIBS="-lXrandr -lXrender"
+ AC_DEFINE(HAVE_RANDR, 1, Have the Xrandr extension library),
+ :, [#include <X11/Xlib.h>])], : ,
+ -lXrandr -lXrender $x_libs)
+AM_CONDITIONAL(HAVE_RANDR, [test $have_randr = yes])
+
+PKG_CHECK_MODULES(DISPLAY_CAPPLET, $COMMON_MODULES)
+
+DISPLAY_CAPPLET_LIBS="$DISPLAY_CAPPLET_LIBS $RANDR_LIBS"
+
+
CAPPLET_LIBS="$CAPPLET_LIBS $x_libs"
GNOMECC_LIBS="$GNOMECC_LIBS $x_libs"
GNOME_SETTINGS_DAEMON_LIBS="$GNOME_SETTINGS_DAEMON_LIBS $x_libs"
@@ -168,6 +188,9 @@ AC_SUBST(SOUND_CAPPLET_LIBS)
AC_SUBST(FONT_CAPPLET_CFLAGS)
AC_SUBST(FONT_CAPPLET_LIBS)
+AC_SUBST(DISPLAY_CAPPLET_CFLAGS)
+AC_SUBST(DISPLAY_CAPPLET_LIBS)
+
AC_SUBST(GNOMECC_CFLAGS)
AC_SUBST(GNOMECC_LIBS)
@@ -249,6 +272,7 @@ capplets/common/Makefile
capplets/background/Makefile
capplets/default-applications/Makefile
capplets/desktop-links/Makefile
+capplets/display/Makefile
capplets/file-types/Makefile
capplets/file-types/libuuid/Makefile
capplets/font/Makefile