File gnome-control-center-display-scale.patch of Package gnome-control-center

commit 6513e7cbab2c56c4b3f2188340bd38d4d9643af1
Author: David Reveman <davidr@novell.com>
Date:   Tue Aug 11 18:51:28 2009 -0400

    Add display scale support.

diff --git a/capplets/display/display-capplet.glade b/capplets/display/display-capplet.glade
index 5e5bd85..d73ab62 100644
--- a/capplets/display/display-capplet.glade
+++ b/capplets/display/display-capplet.glade
@@ -274,6 +274,34 @@
 	      </child>
 
 	      <child>
+		<widget class="GtkLabel" id="label5">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">S_cale:</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">3</property>
+		  <property name="right_attach">4</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options">shrink|fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
 		<widget class="GtkLabel" id="label3">
 		  <property name="visible">True</property>
 		  <property name="label" translatable="yes">Re_fresh rate:</property>
@@ -346,6 +374,22 @@
 	      </child>
 
 	      <child>
+		<widget class="GtkComboBox" id="scale_combo">
+		  <property name="visible">True</property>
+		  <property name="add_tearoffs">False</property>
+		  <property name="focus_on_click">True</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">4</property>
+		  <property name="right_attach">5</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options">expand|shrink|fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
 		<widget class="GtkComboBox" id="refresh_combo">
 		  <property name="visible">True</property>
 		  <property name="add_tearoffs">False</property>
diff --git a/capplets/display/xrandr-capplet.c b/capplets/display/xrandr-capplet.c
index de082af..ea07ff1 100644
--- a/capplets/display/xrandr-capplet.c
+++ b/capplets/display/xrandr-capplet.c
@@ -24,6 +24,7 @@
 #include <glade/glade.h>
 #include <string.h>
 #include <stdlib.h>
+#include <math.h>
 #include "scrollarea.h"
 #define GNOME_DESKTOP_USE_UNSTABLE_API
 #include <libgnomeui/gnome-rr.h>
@@ -53,6 +54,7 @@ struct App
     GtkWidget      *monitor_off_radio;
     GtkListStore   *resolution_store;
     GtkWidget	   *resolution_combo;
+    GtkWidget	   *scale_combo;
     GtkWidget	   *refresh_combo;
     GtkWidget	   *rotation_combo;
     GtkWidget	   *panel_checkbox;
@@ -569,6 +571,85 @@ rebuild_resolution_combo (App *app)
 }
 
 static void
+rebuild_scale_combo (App *app)
+{
+    typedef struct
+    {
+	int width;
+	int height;
+	const char * name;
+    } ScaleInfo;
+    static const ScaleInfo scales[] = {
+	{ 0, 0, N_("None") },
+/*	{ 800, 600, N_("800 x 600") }, */
+	{ 1024, 768, N_("1024 x 768") },
+	{ 1024, 900, N_("1024 x 900") },
+/*	{ 1280, 1024, N_("1280 x 1024") } */
+    };
+    const char *selection;
+    GnomeRRTransform current;
+    int i;
+    double best = 0.1;
+
+    clear_combo (app->scale_combo);
+
+    if (!app->current_output || !app->current_output->on)
+    {
+	gtk_widget_set_sensitive (app->scale_combo, FALSE);
+	return;
+    }
+
+    g_assert (app->current_output != NULL);
+
+    gtk_widget_set_sensitive (app->scale_combo, TRUE);
+
+    current = app->current_output->transform;
+
+    selection = NULL;
+    for (i = 0; i < G_N_ELEMENTS (scales); ++i)
+    {
+	const ScaleInfo *info = &(scales[i]);
+	GnomeRRTransform transform = {
+	    {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	    }
+	};
+	double diff = 0.0;
+	int    j, k;
+
+	if (info->width && info->height)
+	{
+	    transform.transform[0][0] = (double) info->width /
+		app->current_output->width;
+	    transform.transform[1][1] = (double) info->height /
+		app->current_output->height;
+	}
+
+	app->current_output->transform = transform;
+
+	add_key (app->scale_combo, info->name,
+		 info->width, info->height, 0, -1);
+
+	for (j = 0; j < 3; j++)
+	    for (k = 0; k < 3; k++)
+		diff += fabs (transform.transform[j][k] - current.transform[j][k]);
+
+	if (diff < best)
+	{
+	    selection = info->name;
+	    best = diff;
+	}
+    }
+
+    app->current_output->transform = current;
+
+    if (!(selection && combo_select (app->scale_combo, selection)))
+	combo_select (app->scale_combo, N_("None"));
+}
+
+static void
 rebuild_gui (App *app)
 {
     gboolean sensitive;
@@ -589,6 +670,7 @@ rebuild_gui (App *app)
     rebuild_current_monitor_label (app);
     rebuild_on_off_radios (app);
     rebuild_resolution_combo (app);
+    rebuild_scale_combo (app);
     rebuild_rate_combo (app);
     rebuild_rotation_combo (app);
 
@@ -743,6 +825,32 @@ realign_outputs_after_resolution_change (App *app, GnomeOutputInfo *output_that_
 }
 
 static void
+update_scale (App *app)
+{
+    int width;
+    int height;
+
+    if (!app->current_output)
+	return;
+
+    if (get_mode (app->scale_combo, &width, &height, NULL, NULL))
+    {
+	if (width && height)
+        {
+	    app->current_output->transform.transform[0][0] = (double)
+               width / app->current_output->width;
+           app->current_output->transform.transform[1][1] = (double)
+               height / app->current_output->height;
+        }
+        else
+        {
+            app->current_output->transform.transform[0][0] = 1.0;
+            app->current_output->transform.transform[1][1] = 1.0;
+        }
+    }
+}
+
+static void
 on_resolution_changed (GtkComboBox *box, gpointer data)
 {
     App *app = data;
@@ -771,6 +879,18 @@ on_resolution_changed (GtkComboBox *box, gpointer data)
 
     rebuild_rate_combo (app);
     rebuild_rotation_combo (app);
+    rebuild_scale_combo (app);
+    update_scale (app);
+
+    foo_scroll_area_invalidate (FOO_SCROLL_AREA (app->area));
+}
+
+static void
+on_scale_changed (GtkComboBox *box, gpointer data)
+{
+    App *app = data;
+
+    update_scale (app);
 
     foo_scroll_area_invalidate (FOO_SCROLL_AREA (app->area));
 }
@@ -1661,7 +1781,7 @@ make_text_combo (GtkWidget *widget, int sort_column)
 }
 
 static void
-compute_virtual_size_for_configuration (GnomeRRConfig *config, int *ret_width, int *ret_height)
+compute_virtual_size_for_configuration (App *app, GnomeRRConfig *config, int *ret_width, int *ret_height)
 {
     int i;
     int width, height;
@@ -1670,14 +1790,44 @@ compute_virtual_size_for_configuration (GnomeRRConfig *config, int *ret_width, i
 
     for (i = 0; config->outputs[i] != NULL; i++)
     {
-	GnomeOutputInfo *output;
+	GnomeOutputInfo *info;
+	GnomeRROutput   *output;
 
-	output = config->outputs[i];
+	info = config->outputs[i];
+	output = gnome_rr_screen_get_output_by_name (app->screen, info->name);
 
-	if (output->on)
+	if (info->on && output)
 	{
-	    width = MAX (width, output->x + output->width);
-	    height = MAX (height, output->y + output->height);
+	    GnomeRRMode **modes = gnome_rr_output_list_modes (output);
+	    int         j;
+
+	    for (j = 0; modes[j] != NULL; ++j)
+	    {
+		GnomeRRMode *mode = modes[i];
+		int         width, height;
+
+		width  = gnome_rr_mode_get_width (mode);
+		height = gnome_rr_mode_get_height (mode);
+
+		if (width == info->width && height == info->height)
+		{
+		    int x, y, w, h;
+		    int x1, y1, x2, y2;
+
+		    gnome_rr_mode_geometry (mode,
+					    info->rotation,
+					    &info->transform,
+					    &x1, &y1, &x2, &y2);
+
+		    x = info->x + x1;
+		    y = info->y + y1;
+		    w = x2 - x1;
+		    h = y2 - y1;
+
+		    width = MAX (width, x + w);
+		    height = MAX (height, y + h);
+		}
+	    }
 	}
     }
 
@@ -1692,7 +1842,7 @@ check_required_virtual_size (App *app)
     int min_width, max_width;
     int min_height, max_height;
 
-    compute_virtual_size_for_configuration (app->current_configuration, &req_width, &req_height);
+    compute_virtual_size_for_configuration (app, app->current_configuration, &req_width, &req_height);
 
     gnome_rr_screen_get_ranges (app->screen, &min_width, &max_width, &min_height, &max_height);
 
@@ -2088,6 +2238,10 @@ run_application (App *app)
     g_signal_connect (app->resolution_combo, "changed",
 		      G_CALLBACK (on_resolution_changed), app);
 
+    app->scale_combo = glade_xml_get_widget (xml, "scale_combo");
+    g_signal_connect (app->scale_combo, "changed",
+		      G_CALLBACK (on_scale_changed), app);
+
     app->refresh_combo = glade_xml_get_widget (xml, "refresh_combo");
     g_signal_connect (app->refresh_combo, "changed",
 		      G_CALLBACK (on_rate_changed), app);
@@ -2118,6 +2272,7 @@ run_application (App *app)
     g_signal_connect (app->rotate_tablet_checkbox, "toggled", G_CALLBACK (rotate_tablet_toggled_cb), app);
 
     make_text_combo (app->resolution_combo, 4);
+    make_text_combo (app->scale_combo, 4);
     make_text_combo (app->refresh_combo, 3);
     make_text_combo (app->rotation_combo, -1);
 
openSUSE Build Service is sponsored by