[gnome-control-center] display: Move GnomeRRLabeler here



commit e35a109d299011b800cb085f3d57ad7c012ed6dc
Author: Bastien Nocera <hadess hadess net>
Date:   Wed Nov 21 22:13:44 2012 +0100

    display: Move GnomeRRLabeler here
    
    And rename to CcRRLabeler.

 panels/display/Makefile.am        |    2 +
 panels/display/cc-display-panel.c |   21 +-
 panels/display/cc-rr-labeler.c    |  601 +++++++++++++++++++++++++++++++++++++
 panels/display/cc-rr-labeler.h    |   64 ++++
 4 files changed, 678 insertions(+), 10 deletions(-)
---
diff --git a/panels/display/Makefile.am b/panels/display/Makefile.am
index dc3aec2..4d2a484 100644
--- a/panels/display/Makefile.am
+++ b/panels/display/Makefile.am
@@ -19,6 +19,8 @@ libdisplay_la_SOURCES =		\
 	display-module.c	\
 	cc-display-panel.c	\
 	cc-display-panel.h	\
+	cc-rr-labeler.c		\
+	cc-rr-labeler.h		\
 	scrollarea.c		\
 	scrollarea.h		\
 	$(MARSHALFILES)
diff --git a/panels/display/cc-display-panel.c b/panels/display/cc-display-panel.c
index 7e24033..b7bb8f2 100644
--- a/panels/display/cc-display-panel.c
+++ b/panels/display/cc-display-panel.c
@@ -31,12 +31,13 @@
 #define GNOME_DESKTOP_USE_UNSTABLE_API
 #include <libgnome-desktop/gnome-rr.h>
 #include <libgnome-desktop/gnome-rr-config.h>
-#include <libgnome-desktop/gnome-rr-labeler.h>
 #include <gdk/gdkx.h>
 #include <X11/Xlib.h>
 #include <glib/gi18n.h>
 #include <gdesktop-enums.h>
 
+#include "cc-rr-labeler.h"
+
 CC_PANEL_REGISTER (CcDisplayPanel, cc_display_panel)
 
 #define DISPLAY_PANEL_PRIVATE(o) \
@@ -68,7 +69,7 @@ struct _CcDisplayPanelPrivate
 {
   GnomeRRScreen       *screen;
   GnomeRRConfig  *current_configuration;
-  GnomeRRLabeler *labeler;
+  CcRRLabeler *labeler;
   GnomeRROutputInfo         *current_output;
 
   GSettings      *clock_settings;
@@ -177,7 +178,7 @@ cc_display_panel_finalize (GObject *object)
                                      self->priv->focus_id);
     }
 
-  gnome_rr_labeler_hide (self->priv->labeler);
+  cc_rr_labeler_hide (self->priv->labeler);
   g_object_unref (self->priv->labeler);
 
   G_OBJECT_CLASS (cc_display_panel_parent_class)->finalize (object);
@@ -261,13 +262,13 @@ on_screen_changed (GnomeRRScreen *scr,
   self->priv->current_output = NULL;
 
   if (self->priv->labeler) {
-    gnome_rr_labeler_hide (self->priv->labeler);
+    cc_rr_labeler_hide (self->priv->labeler);
     g_object_unref (self->priv->labeler);
   }
 
-  self->priv->labeler = gnome_rr_labeler_new (self->priv->current_configuration);
+  self->priv->labeler = cc_rr_labeler_new (self->priv->current_configuration);
   if (gtk_widget_has_focus (self->priv->panel))
-     gnome_rr_labeler_show (self->priv->labeler);
+     cc_rr_labeler_show (self->priv->labeler);
 
   select_current_output_from_dialog_position (self);
 }
@@ -638,7 +639,7 @@ rebuild_current_monitor_label (CcDisplayPanel *self)
         tmp = g_strdup (gnome_rr_output_info_get_display_name (self->priv->current_output));
 
       str = g_strdup_printf ("<b>%s</b>", tmp);
-      gnome_rr_labeler_get_rgba_for_output (self->priv->labeler, self->priv->current_output, &color);
+      cc_rr_labeler_get_rgba_for_output (self->priv->labeler, self->priv->current_output, &color);
       use_color = TRUE;
       g_free (tmp);
     }
@@ -2030,7 +2031,7 @@ paint_output (CcDisplayPanel *self, cairo_t *cr, int i)
   cairo_rectangle (cr, x, y, w * scale + 0.5, h * scale + 0.5);
   cairo_clip_preserve (cr);
 
-  gnome_rr_labeler_get_rgba_for_output (self->priv->labeler, output, &output_color);
+  cc_rr_labeler_get_rgba_for_output (self->priv->labeler, output, &output_color);
   r = output_color.red;
   g = output_color.green;
   b = output_color.blue;
@@ -2515,9 +2516,9 @@ dialog_toplevel_focus_changed (GtkWindow      *window,
   if (self->priv->labeler == NULL)
     return;
   if (gtk_window_has_toplevel_focus (window))
-    gnome_rr_labeler_show (self->priv->labeler);
+    cc_rr_labeler_show (self->priv->labeler);
   else
-    gnome_rr_labeler_hide (self->priv->labeler);
+    cc_rr_labeler_hide (self->priv->labeler);
 }
 
 static void
diff --git a/panels/display/cc-rr-labeler.c b/panels/display/cc-rr-labeler.c
new file mode 100644
index 0000000..28926ee
--- /dev/null
+++ b/panels/display/cc-rr-labeler.c
@@ -0,0 +1,601 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * cc-rr-labeler.c - Utility to label monitors to identify them
+ * while they are being configured.
+ *
+ * Copyright 2008, Novell, Inc.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Federico Mena-Quintero <federico novell com>
+ */
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#include <X11/Xproto.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <gdk/gdkx.h>
+
+#include "cc-rr-labeler.h"
+
+struct _CcRRLabelerPrivate {
+	GnomeRRConfig *config;
+
+	int num_outputs;
+
+	GdkRGBA *palette;
+	GtkWidget **windows;
+
+	GdkScreen  *screen;
+	Atom        workarea_atom;
+};
+
+enum {
+	PROP_0,
+	PROP_CONFIG,
+	PROP_LAST
+};
+
+G_DEFINE_TYPE (CcRRLabeler, cc_rr_labeler, G_TYPE_OBJECT);
+
+static void cc_rr_labeler_finalize (GObject *object);
+static void setup_from_config (CcRRLabeler *labeler);
+
+static GdkFilterReturn
+screen_xevent_filter (GdkXEvent      *xevent,
+		      GdkEvent       *event,
+		      CcRRLabeler *labeler)
+{
+	XEvent *xev;
+
+	xev = (XEvent *) xevent;
+
+	if (xev->type == PropertyNotify &&
+	    xev->xproperty.atom == labeler->priv->workarea_atom) {
+		/* update label positions */
+		if (labeler->priv->windows != NULL) {
+			cc_rr_labeler_hide (labeler);
+			cc_rr_labeler_show (labeler);
+		}
+	}
+
+	return GDK_FILTER_CONTINUE;
+}
+
+static void
+cc_rr_labeler_init (CcRRLabeler *labeler)
+{
+	GdkWindow *gdkwindow;
+
+	labeler->priv = G_TYPE_INSTANCE_GET_PRIVATE (labeler, GNOME_TYPE_RR_LABELER, CcRRLabelerPrivate);
+
+	labeler->priv->workarea_atom = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+						    "_NET_WORKAREA",
+						    True);
+
+	labeler->priv->screen = gdk_screen_get_default ();
+	/* code is not really designed to handle multiple screens so *shrug* */
+	gdkwindow = gdk_screen_get_root_window (labeler->priv->screen);
+	gdk_window_add_filter (gdkwindow, (GdkFilterFunc) screen_xevent_filter, labeler);
+	gdk_window_set_events (gdkwindow, gdk_window_get_events (gdkwindow) | GDK_PROPERTY_CHANGE_MASK);
+}
+
+static void
+cc_rr_labeler_set_property (GObject *gobject, guint property_id, const GValue *value, GParamSpec *param_spec)
+{
+	CcRRLabeler *self = CC_RR_LABELER (gobject);
+
+	switch (property_id) {
+	case PROP_CONFIG:
+		self->priv->config = GNOME_RR_CONFIG (g_value_dup_object (value));
+		return;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, param_spec);
+	}
+}
+
+static GObject *
+cc_rr_labeler_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)
+{
+	CcRRLabeler *self = (CcRRLabeler*) G_OBJECT_CLASS (cc_rr_labeler_parent_class)->constructor (type, n_construct_properties, construct_properties);
+
+	setup_from_config (self);
+
+	return (GObject*) self;
+}
+
+static void
+cc_rr_labeler_class_init (CcRRLabelerClass *klass)
+{
+	GObjectClass *object_class;
+
+	g_type_class_add_private (klass, sizeof (CcRRLabelerPrivate));
+
+	object_class = (GObjectClass *) klass;
+
+	object_class->set_property = cc_rr_labeler_set_property;
+	object_class->finalize = cc_rr_labeler_finalize;
+	object_class->constructor = cc_rr_labeler_constructor;
+
+	g_object_class_install_property (object_class, PROP_CONFIG, g_param_spec_object ("config",
+											 "Configuration",
+											 "RandR configuration to label",
+											 GNOME_TYPE_RR_CONFIG,
+											 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+											 G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+}
+
+static void
+cc_rr_labeler_finalize (GObject *object)
+{
+	CcRRLabeler *labeler;
+	GdkWindow      *gdkwindow;
+
+	labeler = CC_RR_LABELER (object);
+
+	gdkwindow = gdk_screen_get_root_window (labeler->priv->screen);
+	gdk_window_remove_filter (gdkwindow, (GdkFilterFunc) screen_xevent_filter, labeler);
+
+	if (labeler->priv->config != NULL) {
+		g_object_unref (labeler->priv->config);
+	}
+
+	if (labeler->priv->windows != NULL) {
+		cc_rr_labeler_hide (labeler);
+		g_free (labeler->priv->windows);
+	}
+
+	g_free (labeler->priv->palette);
+
+	G_OBJECT_CLASS (cc_rr_labeler_parent_class)->finalize (object);
+}
+
+static int
+count_outputs (GnomeRRConfig *config)
+{
+	int i;
+	GnomeRROutputInfo **outputs = gnome_rr_config_get_outputs (config);
+
+	for (i = 0; outputs[i] != NULL; i++)
+		;
+
+	return i;
+}
+
+static void
+make_palette (CcRRLabeler *labeler)
+{
+	/* The idea is that we go around an hue color wheel.  We want to start
+	 * at red, go around to green/etc. and stop at blue --- because magenta
+	 * is evil.  Eeeeek, no magenta, please!
+	 *
+	 * Purple would be nice, though.  Remember that we are watered down
+	 * (i.e. low saturation), so that would be like Like berries with cream.
+	 * Mmmmm, berries.
+	 */
+	double start_hue;
+	double end_hue;
+	int i;
+
+	g_assert (labeler->priv->num_outputs > 0);
+
+	labeler->priv->palette = g_new (GdkRGBA, labeler->priv->num_outputs);
+
+	start_hue = 0.0; /* red */
+	end_hue   = 2.0/3; /* blue */
+
+	for (i = 0; i < labeler->priv->num_outputs; i++) {
+		double h, s, v;
+		double r, g, b;
+
+		h = start_hue + (end_hue - start_hue) / labeler->priv->num_outputs * i;
+		s = 1.0 / 3;
+		v = 1.0;
+
+		gtk_hsv_to_rgb (h, s, v, &r, &g, &b);
+
+		labeler->priv->palette[i].red   = r;
+		labeler->priv->palette[i].green = g;
+		labeler->priv->palette[i].blue  = b;
+		labeler->priv->palette[i].alpha  = 1.0;
+	}
+}
+
+static void
+rounded_rectangle (cairo_t *cr,
+                   gint     x,
+                   gint     y,
+                   gint     width,
+                   gint     height,
+                   gint     x_radius,
+                   gint     y_radius)
+{
+	gint x1, x2;
+	gint y1, y2;
+	gint xr1, xr2;
+	gint yr1, yr2;
+
+	x1 = x;
+	x2 = x1 + width;
+	y1 = y;
+	y2 = y1 + height;
+
+	x_radius = MIN (x_radius, width / 2.0);
+	y_radius = MIN (y_radius, width / 2.0);
+
+	xr1 = x_radius;
+	xr2 = x_radius / 2.0;
+	yr1 = y_radius;
+	yr2 = y_radius / 2.0;
+
+	cairo_move_to    (cr, x1 + xr1, y1);
+	cairo_line_to    (cr, x2 - xr1, y1);
+	cairo_curve_to   (cr, x2 - xr2, y1, x2, y1 + yr2, x2, y1 + yr1);
+	cairo_line_to    (cr, x2, y2 - yr1);
+	cairo_curve_to   (cr, x2, y2 - yr2, x2 - xr2, y2, x2 - xr1, y2);
+	cairo_line_to    (cr, x1 + xr1, y2);
+	cairo_curve_to   (cr, x1 + xr2, y2, x1, y2 - yr2, x1, y2 - yr1);
+	cairo_line_to    (cr, x1, y1 + yr1);
+	cairo_curve_to   (cr, x1, y1 + yr2, x1 + xr2, y1, x1 + xr1, y1);
+	cairo_close_path (cr);
+}
+
+#define LABEL_WINDOW_EDGE_THICKNESS 2
+#define LABEL_WINDOW_PADDING 12
+/* Look for panel-corner in:
+ * http://git.gnome.org/browse/gnome-shell/tree/data/theme/gnome-shell.css
+ * to match the corner radius */
+#define LABEL_CORNER_RADIUS 6 + LABEL_WINDOW_EDGE_THICKNESS
+
+static void
+label_draw_background_and_frame (GtkWidget *widget, cairo_t *cr, gboolean for_shape)
+{
+	GdkRGBA shape_color = { 0, 0, 0, 1 };
+	GdkRGBA *rgba;
+	GtkAllocation allocation;
+
+	rgba = g_object_get_data (G_OBJECT (widget), "rgba");
+	gtk_widget_get_allocation (widget, &allocation);
+
+	cairo_save (cr);
+	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+	/* edge outline */
+	if (for_shape)
+		gdk_cairo_set_source_rgba (cr, &shape_color);
+	else
+		cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
+
+	rounded_rectangle (cr,
+	                   LABEL_WINDOW_EDGE_THICKNESS / 2.0,
+	                   LABEL_WINDOW_EDGE_THICKNESS / 2.0,
+	                   allocation.width - LABEL_WINDOW_EDGE_THICKNESS,
+	                   allocation.height - LABEL_WINDOW_EDGE_THICKNESS,
+	                   LABEL_CORNER_RADIUS, LABEL_CORNER_RADIUS);
+	cairo_set_line_width (cr, LABEL_WINDOW_EDGE_THICKNESS);
+	cairo_stroke (cr);
+
+	/* fill */
+	if (for_shape) {
+		gdk_cairo_set_source_rgba (cr, &shape_color);
+	} else {
+		rgba->alpha = 0.75;
+		gdk_cairo_set_source_rgba (cr, rgba);
+	}
+
+	rounded_rectangle (cr,
+	                   LABEL_WINDOW_EDGE_THICKNESS,
+	                   LABEL_WINDOW_EDGE_THICKNESS,
+	                   allocation.width - LABEL_WINDOW_EDGE_THICKNESS * 2,
+	                   allocation.height - LABEL_WINDOW_EDGE_THICKNESS * 2,
+	                   LABEL_CORNER_RADIUS - LABEL_WINDOW_EDGE_THICKNESS / 2.0,
+			   LABEL_CORNER_RADIUS - LABEL_WINDOW_EDGE_THICKNESS / 2.0);
+	cairo_fill (cr);
+
+	cairo_restore (cr);
+}
+
+static void
+maybe_update_shape (GtkWidget *widget)
+{
+	cairo_t *cr;
+	cairo_surface_t *surface;
+	cairo_region_t *region;
+
+	/* fallback to XShape only for non-composited clients */
+	if (gtk_widget_is_composited (widget)) {
+		gtk_widget_shape_combine_region (widget, NULL);
+		return;
+	}
+
+	surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
+						     CAIRO_CONTENT_COLOR_ALPHA,
+						     gtk_widget_get_allocated_width (widget),
+						     gtk_widget_get_allocated_height (widget));
+
+	cr = cairo_create (surface);
+	label_draw_background_and_frame (widget, cr, TRUE);
+	cairo_destroy (cr);
+
+	region = gdk_cairo_region_create_from_surface (surface);
+	gtk_widget_shape_combine_region (widget, region);
+
+	cairo_surface_destroy (surface);
+	cairo_region_destroy (region);
+}
+
+static gboolean
+label_window_draw_event_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
+{
+	if (gtk_widget_is_composited (widget)) {
+		/* clear any content */
+		cairo_save (cr);
+		cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+		cairo_set_source_rgba (cr, 0, 0, 0, 0);
+		cairo_paint (cr);
+		cairo_restore (cr);
+	}
+
+	maybe_update_shape (widget);
+	label_draw_background_and_frame (widget, cr, FALSE);
+
+	return FALSE;
+}
+
+static void
+position_window (CcRRLabeler  *labeler,
+		 GtkWidget       *window,
+		 int              x,
+		 int              y)
+{
+	GdkRectangle    workarea;
+	GdkRectangle    monitor;
+	int             monitor_num;
+
+	monitor_num = gdk_screen_get_monitor_at_point (labeler->priv->screen, x, y);
+	gdk_screen_get_monitor_workarea (labeler->priv->screen, monitor_num, &workarea);
+	gdk_screen_get_monitor_geometry (labeler->priv->screen,
+                                         monitor_num,
+                                         &monitor);
+	gdk_rectangle_intersect (&monitor, &workarea, &workarea);
+
+	gtk_window_move (GTK_WINDOW (window), workarea.x, workarea.y);
+}
+
+static void
+label_window_realize_cb (GtkWidget *widget)
+{
+	cairo_region_t *region;
+
+	/* make the whole window ignore events */
+	region = cairo_region_create ();
+	gtk_widget_input_shape_combine_region (widget, region);
+	cairo_region_destroy (region);
+
+	maybe_update_shape (widget);
+}
+
+static void
+label_window_composited_changed_cb (GtkWidget *widget, CcRRLabeler *labeler)
+{
+	if (gtk_widget_get_realized (widget))
+		maybe_update_shape (widget);
+}
+
+static GtkWidget *
+create_label_window (CcRRLabeler *labeler, GnomeRROutputInfo *output, GdkRGBA *rgba)
+{
+	GtkWidget *window;
+	GtkWidget *widget;
+	char *str;
+	const char *display_name;
+	GdkRGBA black = { 0, 0, 0, 1.0 };
+	int x, y;
+	GdkScreen *screen;
+	GdkVisual *visual;
+
+	window = gtk_window_new (GTK_WINDOW_POPUP);
+	gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_TOOLTIP);
+	gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
+	gtk_widget_set_app_paintable (window, TRUE);
+	screen = gtk_widget_get_screen (window);
+	visual = gdk_screen_get_rgba_visual (screen);
+
+	if (visual != NULL)
+		gtk_widget_set_visual (window, visual);
+
+	gtk_container_set_border_width (GTK_CONTAINER (window), LABEL_WINDOW_PADDING + LABEL_WINDOW_EDGE_THICKNESS);
+
+	/* This is semi-dangerous.  The color is part of the labeler->palette
+	 * array.  Note that in cc_rr_labeler_finalize(), we are careful to
+	 * free the palette only after we free the windows.
+	 */
+	g_object_set_data (G_OBJECT (window), "rgba", rgba);
+
+	g_signal_connect (window, "draw",
+			  G_CALLBACK (label_window_draw_event_cb), labeler);
+	g_signal_connect (window, "realize",
+			  G_CALLBACK (label_window_realize_cb), labeler);
+	g_signal_connect (window, "composited-changed",
+			  G_CALLBACK (label_window_composited_changed_cb), labeler);
+
+	if (gnome_rr_config_get_clone (labeler->priv->config)) {
+		/* Keep this string in sync with gnome-control-center/capplets/display/xrandr-capplet.c:get_display_name() */
+
+		/* Translators:  this is the feature where what you see on your
+		 * laptop's screen is the same as your external projector.
+		 * Here, "Mirrored" is being used as an adjective.  For example,
+		 * the Spanish translation could be "Pantallas en Espejo".
+		 */
+		display_name = _("Mirrored Displays");
+	} else
+		display_name = gnome_rr_output_info_get_display_name (output);
+
+	str = g_strdup_printf ("<b>%s</b>", display_name);
+	widget = gtk_label_new (NULL);
+	gtk_label_set_markup (GTK_LABEL (widget), str);
+	g_free (str);
+
+	/* Make the label explicitly black.  We don't want it to follow the
+	 * theme's colors, since the label is always shown against a light
+	 * pastel background.  See bgo#556050
+	 */
+	gtk_widget_override_color (widget,
+				   gtk_widget_get_state_flags (widget),
+				   &black);
+
+	gtk_container_add (GTK_CONTAINER (window), widget);
+
+	/* Should we center this at the top edge of the monitor, instead of using the upper-left corner? */
+	gnome_rr_output_info_get_geometry (output, &x, &y, NULL, NULL);
+	position_window (labeler, window, x, y);
+
+	gtk_widget_show_all (window);
+
+	return window;
+}
+
+static void
+setup_from_config (CcRRLabeler *labeler)
+{
+	labeler->priv->num_outputs = count_outputs (labeler->priv->config);
+
+	make_palette (labeler);
+
+	cc_rr_labeler_show (labeler);
+}
+
+/**
+ * cc_rr_labeler_new:
+ * @config: Configuration of the screens to label
+ *
+ * Create a GUI element that will display colored labels on each connected monitor.
+ * This is useful when users are required to identify which monitor is which, e.g. for
+ * for configuring multiple monitors.
+ * The labels will be shown by default, use cc_rr_labeler_hide to hide them.
+ *
+ * Returns: A new #CcRRLabeler
+ */
+CcRRLabeler *
+cc_rr_labeler_new (GnomeRRConfig *config)
+{
+	g_return_val_if_fail (GNOME_IS_RR_CONFIG (config), NULL);
+
+	return g_object_new (GNOME_TYPE_RR_LABELER, "config", config, NULL);
+}
+
+/**
+ * cc_rr_labeler_show:
+ * @labeler: A #CcRRLabeler
+ *
+ * Show the labels.
+ */
+void
+cc_rr_labeler_show (CcRRLabeler *labeler)
+{
+	int i;
+	gboolean created_window_for_clone;
+	GnomeRROutputInfo **outputs;
+
+	g_return_if_fail (GNOME_IS_RR_LABELER (labeler));
+
+	if (labeler->priv->windows != NULL)
+		return;
+
+	labeler->priv->windows = g_new (GtkWidget *, labeler->priv->num_outputs);
+
+	created_window_for_clone = FALSE;
+
+	outputs = gnome_rr_config_get_outputs (labeler->priv->config);
+
+	for (i = 0; i < labeler->priv->num_outputs; i++) {
+		if (!created_window_for_clone && gnome_rr_output_info_is_active (outputs[i])) {
+			labeler->priv->windows[i] = create_label_window (labeler, outputs[i], labeler->priv->palette + i);
+
+			if (gnome_rr_config_get_clone (labeler->priv->config))
+				created_window_for_clone = TRUE;
+		} else
+			labeler->priv->windows[i] = NULL;
+	}
+}
+
+/**
+ * cc_rr_labeler_hide:
+ * @labeler: A #CcRRLabeler
+ *
+ * Hide ouput labels.
+ */
+void
+cc_rr_labeler_hide (CcRRLabeler *labeler)
+{
+	int i;
+	CcRRLabelerPrivate *priv;
+
+	g_return_if_fail (GNOME_IS_RR_LABELER (labeler));
+
+	priv = labeler->priv;
+
+	if (priv->windows == NULL)
+		return;
+
+	for (i = 0; i < priv->num_outputs; i++)
+		if (priv->windows[i] != NULL) {
+			gtk_widget_destroy (priv->windows[i]);
+			priv->windows[i] = NULL;
+	}
+	g_free (priv->windows);
+	priv->windows = NULL;
+}
+
+/**
+ * cc_rr_labeler_get_rgba_for_output:
+ * @labeler: A #CcRRLabeler
+ * @output: Output device (i.e. monitor) to query
+ * @rgba_out: (out): Color of selected monitor.
+ *
+ * Get the color used for the label on a given output (monitor).
+ */
+void
+cc_rr_labeler_get_rgba_for_output (CcRRLabeler *labeler, GnomeRROutputInfo *output, GdkRGBA *rgba_out)
+{
+	int i;
+	GnomeRROutputInfo **outputs;
+
+	g_return_if_fail (GNOME_IS_RR_LABELER (labeler));
+	g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (output));
+	g_return_if_fail (rgba_out != NULL);
+
+	outputs = gnome_rr_config_get_outputs (labeler->priv->config);
+
+	for (i = 0; i < labeler->priv->num_outputs; i++)
+		if (outputs[i] == output) {
+			*rgba_out = labeler->priv->palette[i];
+			return;
+		}
+
+	g_warning ("trying to get the color for unknown GnomeOutputInfo %p; returning magenta!", output);
+
+	rgba_out->red   = 1.0;
+	rgba_out->green = 0;
+	rgba_out->blue  = 1.0;
+	rgba_out->alpha  = 1.0;
+}
diff --git a/panels/display/cc-rr-labeler.h b/panels/display/cc-rr-labeler.h
new file mode 100644
index 0000000..fdecf29
--- /dev/null
+++ b/panels/display/cc-rr-labeler.h
@@ -0,0 +1,64 @@
+/* gnome-rr-labeler.h - Utility to label monitors to identify them
+ * while they are being configured.
+ *
+ * Copyright 2008, Novell, Inc.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Federico Mena-Quintero <federico novell com>
+ */
+
+#ifndef CC_RR_LABELER_H
+#define CC_RR_LABELER_H
+
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include <libgnome-desktop/gnome-rr-config.h>
+
+#define GNOME_TYPE_RR_LABELER            (cc_rr_labeler_get_type ())
+#define CC_RR_LABELER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_RR_LABELER, CcRRLabeler))
+#define CC_RR_LABELER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GNOME_TYPE_RR_LABELER, CcRRLabelerClass))
+#define GNOME_IS_RR_LABELER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_RR_LABELER))
+#define GNOME_IS_RR_LABELER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GNOME_TYPE_RR_LABELER))
+#define CC_RR_LABELER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  GNOME_TYPE_RR_LABELER, CcRRLabelerClass))
+
+typedef struct _CcRRLabeler CcRRLabeler;
+typedef struct _CcRRLabelerClass CcRRLabelerClass;
+typedef struct _CcRRLabelerPrivate CcRRLabelerPrivate;
+
+struct _CcRRLabeler {
+	GObject parent;
+
+	/*< private >*/
+	CcRRLabelerPrivate *priv;
+};
+
+struct _CcRRLabelerClass {
+	GObjectClass parent_class;
+};
+
+GType cc_rr_labeler_get_type (void);
+
+CcRRLabeler *cc_rr_labeler_new (GnomeRRConfig *config);
+
+void cc_rr_labeler_show (CcRRLabeler *labeler);
+
+void cc_rr_labeler_hide (CcRRLabeler *labeler);
+
+void cc_rr_labeler_get_rgba_for_output (CcRRLabeler *labeler, GnomeRROutputInfo *output, GdkRGBA *rgba_out);
+
+#endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]