[gnome-settings-daemon] wacom: apply display rotation to device



commit ecb0e2d0b15c732007a611258fd3d916953c0b7c
Author: Olivier Fourdan <ofourdan redhat com>
Date:   Wed May 16 16:41:57 2012 +0200

    wacom: apply display rotation to device
    
    When an output is mapped to a device, match the device rotation
    with the output (bug #668547).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=668547

 plugins/wacom/gsd-wacom-device.c    |   76 +++++++++++++++++++++++++++++++++++
 plugins/wacom/gsd-wacom-device.h    |    5 ++
 plugins/wacom/gsd-wacom-manager.c   |   46 +++++++++++++++++++++
 plugins/xrandr/Makefile.am          |    2 +
 plugins/xrandr/gsd-xrandr-manager.c |   54 +++++++++++++++++++++++++
 5 files changed, 183 insertions(+), 0 deletions(-)
---
diff --git a/plugins/wacom/gsd-wacom-device.c b/plugins/wacom/gsd-wacom-device.c
index 6390b0b..0d865cc 100644
--- a/plugins/wacom/gsd-wacom-device.c
+++ b/plugins/wacom/gsd-wacom-device.c
@@ -47,6 +47,17 @@
 #define WACOM_ERASER_SCHEMA "org.gnome.settings-daemon.peripherals.wacom.eraser"
 #define WACOM_BUTTON_SCHEMA "org.gnome.settings-daemon.peripherals.wacom.tablet-button"
 
+static struct {
+	GnomeRRRotation  rotation;
+	GsdWacomRotation rotation_wacom;
+	const gchar     *rotation_string;
+} rotation_table[] = {
+	{ GNOME_RR_ROTATION_0,   GSD_WACOM_ROTATION_NONE, "none" },
+	{ GNOME_RR_ROTATION_90,  GSD_WACOM_ROTATION_CCW,  "ccw"  },
+	{ GNOME_RR_ROTATION_180, GSD_WACOM_ROTATION_HALF, "half" },
+	{ GNOME_RR_ROTATION_270, GSD_WACOM_ROTATION_CW,   "cw"   }
+};
+
 static WacomDeviceDatabase *db = NULL;
 
 struct GsdWacomStylusPrivate
@@ -716,6 +727,18 @@ set_display_by_output (GsdWacomDevice  *device,
 	g_free (o_serial_s);
 }
 
+static GsdWacomRotation
+get_rotation_wacom (GnomeRRRotation rotation)
+{
+        guint i;
+
+        for (i = 0; i < G_N_ELEMENTS (rotation_table); i++) {
+                if (rotation_table[i].rotation & rotation)
+                        return (rotation_table[i].rotation_wacom);
+        }
+        g_assert_not_reached ();
+}
+
 void
 gsd_wacom_device_set_display (GsdWacomDevice *device,
                               int             monitor)
@@ -871,6 +894,31 @@ gsd_wacom_device_get_display_matrix (GsdWacomDevice *device, float matrix[NUM_EL
 	return TRUE;
 }
 
+GsdWacomRotation
+gsd_wacom_device_get_display_rotation (GsdWacomDevice *device)
+{
+	GError *error = NULL;
+	GnomeRRScreen *rr_screen;
+	GnomeRROutput *rr_output;
+	GnomeRRRotation rotation = GNOME_RR_ROTATION_0;
+
+	rr_screen = gnome_rr_screen_new (gdk_screen_get_default (), &error);
+	if (rr_screen == NULL) {
+		g_warning ("Failed to create GnomeRRScreen: %s", error->message);
+		g_error_free (error);
+		return -1;
+	}
+
+	rr_output = find_output (rr_screen, device);
+	if (rr_output) {
+		GnomeRRCrtc *crtc = gnome_rr_output_get_crtc (rr_output);
+		rotation = gnome_rr_crtc_get_current_rotation (crtc);
+	}
+	g_object_unref (rr_screen);
+
+	return get_rotation_wacom (rotation);
+}
+
 static void
 add_stylus_to_device (GsdWacomDevice *device,
 		      const char     *settings_path,
@@ -1746,6 +1794,34 @@ gsd_wacom_device_get_button (GsdWacomDevice   *device,
 	}
 }
 
+GsdWacomRotation
+gsd_wacom_device_rotation_name_to_type (const char *rotation)
+{
+        guint i;
+
+	g_return_val_if_fail (rotation != NULL, GSD_WACOM_ROTATION_NONE);
+
+        for (i = 0; i < G_N_ELEMENTS (rotation_table); i++) {
+                if (strcmp (rotation_table[i].rotation_string, rotation) == 0)
+                        return (rotation_table[i].rotation_wacom);
+        }
+
+	return GSD_WACOM_ROTATION_NONE;
+}
+
+const char *
+gsd_wacom_device_rotation_type_to_name (GsdWacomRotation type)
+{
+        guint i;
+
+        for (i = 0; i < G_N_ELEMENTS (rotation_table); i++) {
+                if (rotation_table[i].rotation_wacom == type)
+                        return (rotation_table[i].rotation_string);
+        }
+
+	return "none";
+}
+
 GsdWacomDevice *
 gsd_wacom_device_create_fake (GsdWacomDeviceType  type,
 			      const char         *name,
diff --git a/plugins/wacom/gsd-wacom-device.h b/plugins/wacom/gsd-wacom-device.h
index b59493d..59c4b27 100644
--- a/plugins/wacom/gsd-wacom-device.h
+++ b/plugins/wacom/gsd-wacom-device.h
@@ -23,6 +23,7 @@
 #define __GSD_WACOM_DEVICE_MANAGER_H
 
 #include <glib-object.h>
+#include "gsd-enums.h"
 
 G_BEGIN_DECLS
 
@@ -128,6 +129,7 @@ void     gsd_wacom_device_set_display         (GsdWacomDevice    *device,
 gint     gsd_wacom_device_get_display_monitor (GsdWacomDevice *device);
 gboolean gsd_wacom_device_get_display_matrix  (GsdWacomDevice *device,
                                                float           matrix[NUM_ELEMS_MATRIX]);
+GsdWacomRotation gsd_wacom_device_get_display_rotation (GsdWacomDevice *device);
 
 GsdWacomDevice * gsd_wacom_device_new              (GdkDevice *device);
 GList          * gsd_wacom_device_list_styli       (GsdWacomDevice *device);
@@ -153,6 +155,9 @@ GsdWacomTabletButton *gsd_wacom_device_get_button   (GsdWacomDevice   *device,
 						     GtkDirectionType *dir);
 int gsd_wacom_device_set_next_mode                  (GsdWacomDevice *device,
 						     int             group_id);
+GsdWacomRotation gsd_wacom_device_rotation_name_to_type (const char *rotation);
+const char     * gsd_wacom_device_rotation_type_to_name (GsdWacomRotation type);
+
 
 /* Helper and debug functions */
 GsdWacomDevice * gsd_wacom_device_create_fake (GsdWacomDeviceType  type,
diff --git a/plugins/wacom/gsd-wacom-manager.c b/plugins/wacom/gsd-wacom-manager.c
index 3619adf..709fbc5 100644
--- a/plugins/wacom/gsd-wacom-manager.c
+++ b/plugins/wacom/gsd-wacom-manager.c
@@ -233,10 +233,48 @@ set_area (GsdWacomDevice  *device,
         g_variant_unref (value);
 }
 
+/* Returns the rotation to apply a device relative to the current rotation of the output */
+static GsdWacomRotation
+get_relative_rotation (GsdWacomRotation device_rotation,
+                       GsdWacomRotation output_rotation)
+{
+	GsdWacomRotation rotations[] = { GSD_WACOM_ROTATION_HALF,
+	                                 GSD_WACOM_ROTATION_CW,
+	                                 GSD_WACOM_ROTATION_NONE,
+	                                 GSD_WACOM_ROTATION_CCW };
+	guint i;
+
+	if (device_rotation == output_rotation)
+		return GSD_WACOM_ROTATION_NONE;
+
+	if (output_rotation == GSD_WACOM_ROTATION_NONE)
+		return device_rotation;
+
+	for (i = 0; i < G_N_ELEMENTS (rotations); i++){
+		if (device_rotation == rotations[i])
+			break;
+	}
+
+	if (output_rotation == GSD_WACOM_ROTATION_HALF)
+		return rotations[(i + G_N_ELEMENTS (rotations) - 2) % G_N_ELEMENTS (rotations)];
+
+	if (output_rotation == GSD_WACOM_ROTATION_CW)
+		return rotations[(i + G_N_ELEMENTS (rotations) - 1) % G_N_ELEMENTS (rotations)];
+
+	if (output_rotation == GSD_WACOM_ROTATION_CCW)
+		return rotations[(i + 1) % G_N_ELEMENTS (rotations)];
+
+	/* fallback */
+	return GSD_WACOM_ROTATION_NONE;
+}
+
 static void
 set_display (GsdWacomDevice  *device,
              GVariant        *value)
 {
+        GsdWacomRotation  device_rotation;
+	GsdWacomRotation  output_rotation;
+	GSettings        *settings;
         float matrix[NUM_ELEMS_MATRIX];
         PropertyHelper property = {
                 .name   = "Coordinate Transformation Matrix",
@@ -251,6 +289,14 @@ set_display (GsdWacomDevice  *device,
         g_debug ("Applying matrix to device...");
         wacom_set_property (device, &property);
 
+        /* Compute rotation to apply relative to the output */
+	settings = gsd_wacom_device_get_settings (device);
+	device_rotation = g_settings_get_enum (settings, KEY_ROTATION);
+	output_rotation = gsd_wacom_device_get_display_rotation (device);
+
+        /* Apply display rotation to device */
+        set_rotation (device, get_relative_rotation (device_rotation, output_rotation));
+
         g_variant_unref (value);
 }
 
diff --git a/plugins/xrandr/Makefile.am b/plugins/xrandr/Makefile.am
index 1b677bb..223fac4 100644
--- a/plugins/xrandr/Makefile.am
+++ b/plugins/xrandr/Makefile.am
@@ -51,6 +51,7 @@ libxrandr_la_CFLAGS =			\
 	$(PLUGIN_CFLAGS)		\
 	$(XRANDR_CFLAGS)		\
 	$(SETTINGS_PLUGIN_CFLAGS)	\
+	$(WACOM_CFLAGS)			\
 	$(AM_CFLAGS)
 
 libxrandr_la_LDFLAGS = 			\
@@ -59,6 +60,7 @@ libxrandr_la_LDFLAGS = 			\
 libxrandr_la_LIBADD  =					\
 	$(top_builddir)/plugins/common/libcommon.la	\
 	$(XRANDR_LIBS)					\
+	$(WACOM_LIBS)					\
 	$(SETTINGS_PLUGIN_LIBS)
 
 plugin_in_files =			\
diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 67372e4..7a8c2cf 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -47,6 +47,10 @@
 #include <libgnome-desktop/gnome-rr.h>
 #include <libgnome-desktop/gnome-rr-labeler.h>
 
+#ifdef HAVE_WACOM
+#include <libwacom/libwacom.h>
+#endif /* HAVE_WACOM */
+
 #include "gsd-enums.h"
 #include "gsd-input-helper.h"
 #include "gnome-settings-profile.h"
@@ -118,6 +122,10 @@ struct GsdXrandrManagerPrivate
 
         /* Last time at which we got a "screen got reconfigured" event; see on_randr_event() */
         guint32 last_config_timestamp;
+
+#ifdef HAVE_WACOM
+        WacomDeviceDatabase *wacom_db;
+#endif /* HAVE_WACOM */
 };
 
 static const GnomeRRRotation possible_rotations[] = {
@@ -1507,6 +1515,40 @@ get_rotation_index (GnomeRRRotation rotation)
         g_assert_not_reached ();
 }
 
+static gboolean
+is_wacom_tablet_device (GsdXrandrManager *mgr,
+                        XDeviceInfo      *device_info)
+{
+#ifdef HAVE_WACOM
+        GsdXrandrManagerPrivate *priv = mgr->priv;
+        gchar       *device_node;
+        WacomDevice *wacom_device;
+        gboolean     is_tablet = FALSE;
+
+        if (priv->wacom_db == NULL)
+                priv->wacom_db = libwacom_database_new ();
+
+        device_node = xdevice_get_device_node (device_info->id);
+        if (device_node == NULL)
+                return FALSE;
+
+        wacom_device = libwacom_new_from_path (priv->wacom_db, device_node, FALSE, NULL);
+        g_free (device_node);
+        if (wacom_device == NULL) {
+                g_free (device_node);
+                return FALSE;
+        }
+        is_tablet = libwacom_has_touch (wacom_device) &&
+                    libwacom_is_builtin (wacom_device);
+
+        libwacom_destroy (wacom_device);
+
+        return is_tablet;
+#else  /* HAVE_WACOM */
+        return FALSE;
+#endif /* HAVE_WACOM */
+}
+
 static void
 rotate_touchscreens (GsdXrandrManager *mgr,
                      GnomeRRRotation   rotation)
@@ -1527,6 +1569,11 @@ rotate_touchscreens (GsdXrandrManager *mgr,
         rot_idx = get_rotation_index (rotation);
 
         for (i = 0; i < n_devices; i++) {
+                if (is_wacom_tablet_device  (mgr, &device_info[i])) {
+                        g_debug ("Not rotating tablet device '%s'", device_info[i].name);
+                        continue;
+                }
+
                 if (device_info_is_touchscreen (&device_info[i])) {
                         XDevice *device;
                         char c = evdev_rotations[rot_idx].axes_swap;
@@ -2049,6 +2096,13 @@ gsd_xrandr_manager_stop (GsdXrandrManager *manager)
                 manager->priv->connection = NULL;
         }
 
+#ifdef HAVE_WACOM
+        if (manager->priv->wacom_db != NULL) {
+                libwacom_database_destroy (manager->priv->wacom_db);
+                manager->priv->wacom_db = NULL;
+        }
+#endif /* HAVE_WACOM */
+
         log_open ();
         log_msg ("STOPPING XRANDR PLUGIN\n------------------------------------------------------------\n");
         log_close ();



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