[gnome-settings-daemon] orientation: Use new orientation property from udev



commit 0f7da239f1330d079897698068994b35749484ee
Author: Bastien Nocera <hadess hadess net>
Date:   Mon Jun 6 18:20:05 2011 +0100

    orientation: Use new orientation property from udev
    
    Instead of needing to poke at X devices ourselves.
    
    Now we just read the new orientation from the
    ID_INPUT_ACCELEROMETER_ORIENTATION property, and rotate the
    screen if it's changed from the previous value.
    
    This requires a newer version of udev, currently only in git,
    but shortly in version 172. See also:
    http://git.kernel.org/?p=linux/hotplug/udev.git;a=commit;h=24569e24dc94a7cffb8031eb0055e8d06cbdcb72
    
    https://bugzilla.gnome.org/show_bug.cgi?id=650603

 plugins/orientation/Makefile.am                    |   21 +--
 plugins/orientation/gsd-orientation-calc.c         |   99 ------
 plugins/orientation/gsd-orientation-calc.h         |   45 ---
 plugins/orientation/gsd-orientation-manager.c      |  313 ++++++++------------
 plugins/orientation/test-orientation-calculation.c |   48 ---
 5 files changed, 122 insertions(+), 404 deletions(-)
---
diff --git a/plugins/orientation/Makefile.am b/plugins/orientation/Makefile.am
index a8c319b..1b12ff2 100644
--- a/plugins/orientation/Makefile.am
+++ b/plugins/orientation/Makefile.am
@@ -1,25 +1,10 @@
 plugin_name = orientation
 
-noinst_PROGRAMS = test-orientation-calculation test-orientation
-
-test_orientation_calculation_SOURCES =	\
-	gsd-orientation-calc.c		\
-	gsd-orientation-calc.h		\
-	test-orientation-calculation.c
-
-test_orientation_calculation_CFLAGS =	\
-	$(PLUGIN_CFLAGS)		\
-	$(SETTINGS_PLUGIN_CFLAGS)	\
-	$(AM_CFLAGS)
-
-test_orientation_calculation_LDADD =	\
-	$(SETTINGS_PLUGIN_LIBS)
+noinst_PROGRAMS = test-orientation
 
 test_orientation_SOURCES =		\
 	gsd-orientation-manager.h	\
 	gsd-orientation-manager.c	\
-	gsd-orientation-calc.c		\
-	gsd-orientation-calc.h		\
 	test-orientation.c
 
 test_orientation_CFLAGS =					\
@@ -46,9 +31,7 @@ liborientation_la_SOURCES = 		\
 	gsd-orientation-plugin.h	\
 	gsd-orientation-plugin.c	\
 	gsd-orientation-manager.h	\
-	gsd-orientation-manager.c	\
-	gsd-orientation-calc.c		\
-	gsd-orientation-calc.h
+	gsd-orientation-manager.c
 
 liborientation_la_CPPFLAGS = \
 	-I$(top_srcdir)/gnome-settings-daemon		\
diff --git a/plugins/orientation/gsd-orientation-manager.c b/plugins/orientation/gsd-orientation-manager.c
index 34870e4..aa5de08 100644
--- a/plugins/orientation/gsd-orientation-manager.c
+++ b/plugins/orientation/gsd-orientation-manager.c
@@ -28,7 +28,6 @@
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 #include <gudev/gudev.h>
-#include <X11/extensions/XInput2.h>
 
 #define GNOME_DESKTOP_USE_UNSTABLE_API
 #include <libgnome-desktop/gnome-rr.h>
@@ -36,7 +35,14 @@
 #include "gsd-input-helper.h"
 #include "gnome-settings-profile.h"
 #include "gsd-orientation-manager.h"
-#include "gsd-orientation-calc.h"
+
+typedef enum {
+        ORIENTATION_UNDEFINED,
+        ORIENTATION_NORMAL,
+        ORIENTATION_BOTTOM_UP,
+        ORIENTATION_LEFT_UP,
+        ORIENTATION_RIGHT_UP
+} OrientationUp;
 
 #define GSD_ORIENTATION_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_ORIENTATION_MANAGER, GsdOrientationManagerPrivate))
 
@@ -46,7 +52,7 @@ struct GsdOrientationManagerPrivate
 
         /* Accelerometer */
         char *sysfs_path;
-        int device_id;
+        OrientationUp prev_orientation;
 
         /* DBus */
         GDBusNodeInfo   *introspection_data;
@@ -58,18 +64,8 @@ struct GsdOrientationManagerPrivate
         GUdevClient *client;
         GSettings *settings;
         gboolean orientation_lock;
-
-        OrientationUp prev_orientation;
-        int prev_x, prev_y, prev_z;
-
-        guint orient_timeout_id;
-        guint num_checks;
 };
 
-/* The maximum number of times we'll poll the X/Y/Z values
- * to check for changes */
-#define MAX_CHECKS 5
-
 #define CONF_SCHEMA "org.gnome.settings-daemon.peripherals.touchscreen"
 #define ORIENTATION_LOCK_KEY "orientation-lock"
 
@@ -128,7 +124,6 @@ gsd_orientation_manager_init (GsdOrientationManager *manager)
 {
         manager->priv = GSD_ORIENTATION_MANAGER_GET_PRIVATE (manager);
         manager->priv->prev_orientation = ORIENTATION_UNDEFINED;
-        manager->priv->device_id = -1;
 }
 
 static GnomeRRRotation
@@ -148,6 +143,57 @@ orientation_to_rotation (OrientationUp    orientation)
         }
 }
 
+static OrientationUp
+orientation_from_string (const char *orientation)
+{
+        if (g_strcmp0 (orientation, "normal") == 0)
+                return ORIENTATION_NORMAL;
+        if (g_strcmp0 (orientation, "bottom-up") == 0)
+                return ORIENTATION_BOTTOM_UP;
+        if (g_strcmp0 (orientation, "left-up") == 0)
+                return ORIENTATION_LEFT_UP;
+        if (g_strcmp0 (orientation, "right-up") == 0)
+                return ORIENTATION_RIGHT_UP;
+
+        return ORIENTATION_UNDEFINED;
+}
+
+static const char *
+orientation_to_string (OrientationUp o)
+{
+        switch (o) {
+        case ORIENTATION_UNDEFINED:
+                return "undefined";
+        case ORIENTATION_NORMAL:
+                return "normal";
+        case ORIENTATION_BOTTOM_UP:
+                return "bottom-up";
+        case ORIENTATION_LEFT_UP:
+                return "left-up";
+        case ORIENTATION_RIGHT_UP:
+                return "right-up";
+        default:
+                g_assert_not_reached ();
+        }
+}
+
+static OrientationUp
+get_orientation_from_device (GUdevDevice *dev)
+{
+        const char *value;
+
+        value = g_udev_device_get_property (dev, "ID_INPUT_ACCELEROMETER_ORIENTATION");
+        if (value == NULL) {
+                g_debug ("Couldn't find orientation for accelerometer %s",
+                         g_udev_device_get_sysfs_path (dev));
+                return ORIENTATION_UNDEFINED;
+        }
+        g_debug ("Found orientation '%s' for accelerometer %s",
+                 value, g_udev_device_get_sysfs_path (dev));
+
+        return orientation_from_string (value);
+}
+
 static void
 on_xrandr_action_call_finished (GObject               *source_object,
                                 GAsyncResult          *res,
@@ -174,8 +220,8 @@ do_xrandr_action (GsdOrientationManager *manager,
                   GnomeRRRotation        rotation)
 {
         GsdOrientationManagerPrivate *priv = manager->priv;
-	GTimeVal tv;
-	gint64 timestamp;
+        GTimeVal tv;
+        gint64 timestamp;
 
         if (priv->connection == NULL || priv->xrandr_proxy == NULL) {
                 g_warning ("No existing D-Bus connection trying to handle XRANDR keys");
@@ -187,8 +233,8 @@ do_xrandr_action (GsdOrientationManager *manager,
                 return;
         }
 
-	g_get_current_time (&tv);
-	timestamp = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+        g_get_current_time (&tv);
+        timestamp = tv.tv_sec * 1000 + tv.tv_usec / 1000;
 
         priv->cancellable = g_cancellable_new ();
 
@@ -202,66 +248,6 @@ do_xrandr_action (GsdOrientationManager *manager,
                            manager);
 }
 
-static gboolean
-get_current_values (GsdOrientationManager *manager,
-                    int                   *x,
-                    int                   *y,
-                    int                   *z)
-{
-        int n_devices;
-        XIDeviceInfo *info;
-        XIValuatorClassInfo *v;
-
-        gdk_error_trap_push ();
-
-        info = XIQueryDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), manager->priv->device_id, &n_devices);
-        if (info == NULL) {
-                gdk_error_trap_pop_ignored ();
-                return FALSE;
-        }
-        gdk_error_trap_pop_ignored ();
-
-        /* Should be XIValuatorClass type
-         * as we already detected that */
-        v = (XIValuatorClassInfo *) info->classes[0];
-        *x = v->value;
-
-        v = (XIValuatorClassInfo *) info->classes[1];
-        *y = v->value;
-
-        v = (XIValuatorClassInfo *) info->classes[2];
-        *z = v->value;
-
-        XIFreeDeviceInfo (info);
-
-        return TRUE;
-}
-
-static gboolean
-update_current_orientation (GsdOrientationManager *manager,
-                            int x, int y, int z)
-{
-        OrientationUp orientation;
-
-        g_debug ("Got values: %d, %d, %d", x, y, z);
-
-        orientation = gsd_orientation_calc (manager->priv->prev_orientation,
-                                            x, y, z);
-        g_debug ("New orientation: %s (prev: %s)",
-                 gsd_orientation_to_string (orientation),
-                 gsd_orientation_to_string (manager->priv->prev_orientation));
-
-        if (orientation == manager->priv->prev_orientation)
-                return FALSE;
-
-        manager->priv->prev_orientation = orientation;
-
-        g_debug ("Orientation changed to '%s', switching screen rotation",
-                 gsd_orientation_to_string (manager->priv->prev_orientation));
-
-        return TRUE;
-}
-
 static void
 do_rotation (GsdOrientationManager *manager)
 {
@@ -281,50 +267,6 @@ do_rotation (GsdOrientationManager *manager)
         do_xrandr_action (manager, rotation);
 }
 
-static gboolean
-check_value_change_cb (GsdOrientationManager *manager)
-{
-        int x, y, z;
-
-        g_debug ("checking for changed X/Y/Z, %d/%d", manager->priv->num_checks, MAX_CHECKS);
-
-        if (get_current_values (manager, &x, &y, &z) == FALSE) {
-                g_warning ("Failed to get X/Y/Z values from device '%d'", manager->priv->device_id);
-                manager->priv->orient_timeout_id = 0;
-                return FALSE;
-        }
-
-        if (x != manager->priv->prev_x ||
-            y != manager->priv->prev_y ||
-            z != manager->priv->prev_z) {
-                manager->priv->num_checks = 0;
-
-                /* We have updated values */
-                if (update_current_orientation (manager, x, y, z)) {
-                        do_rotation (manager);
-                }
-
-                set_device_enabled (manager->priv->device_id, FALSE);
-
-                manager->priv->orient_timeout_id = 0;
-
-                return FALSE;
-        }
-
-        /* If we've already checked the device MAX_CHECKS
-         * times, then we don't really want to keep spinning */
-        if (manager->priv->num_checks > MAX_CHECKS) {
-                manager->priv->num_checks = 0;
-                set_device_enabled (manager->priv->device_id, FALSE);
-                manager->priv->orient_timeout_id = 0;
-                return FALSE;
-        }
-
-        manager->priv->num_checks++;
-
-        return TRUE;
-}
-
 static void
 client_uevent_cb (GUdevClient           *client,
                   gchar                 *action,
@@ -332,6 +274,7 @@ client_uevent_cb (GUdevClient           *client,
                   GsdOrientationManager *manager)
 {
         const char *sysfs_path;
+        OrientationUp orientation;
 
         sysfs_path = g_udev_device_get_sysfs_path (device);
         g_debug ("Received uevent '%s' from '%s'", action, sysfs_path);
@@ -347,48 +290,14 @@ client_uevent_cb (GUdevClient           *client,
 
         g_debug ("Received an event from the accelerometer");
 
-        if (manager->priv->orient_timeout_id > 0)
-                return;
-
-        /* Save the current value */
-        if (get_current_values (manager,
-                                &manager->priv->prev_x,
-                                &manager->priv->prev_y,
-                                &manager->priv->prev_z) == FALSE) {
-                g_warning ("Failed to get current values");
-                return;
-        }
+        orientation = get_orientation_from_device (device);
+        if (orientation != manager->priv->prev_orientation) {
+                manager->priv->prev_orientation = orientation;
+                g_debug ("Orientation changed to '%s', switching screen rotation",
+                         orientation_to_string (manager->priv->prev_orientation));
 
-        if (set_device_enabled (manager->priv->device_id, TRUE) == FALSE) {
-                g_warning ("Failed to re-enabled device '%d'", manager->priv->device_id);
-                return;
+                do_rotation (manager);
         }
-
-        manager->priv->orient_timeout_id = g_timeout_add
-                (150, (GSourceFunc) check_value_change_cb, manager);
-}
-
-static char *
-get_sysfs_path (GsdOrientationManager *manager,
-                const char            *device_node)
-{
-        GUdevDevice *device, *parent;
-        char *sysfs_path;
-
-        device = g_udev_client_query_by_device_file (manager->priv->client,
-                                                     device_node);
-        if (device == NULL)
-                return NULL;
-
-        parent = g_udev_device_get_parent (device);
-        g_object_unref (device);
-        if (parent == NULL)
-                return NULL;
-
-        sysfs_path = g_strdup (g_udev_device_get_sysfs_path (parent));
-        g_object_unref (parent);
-
-        return sysfs_path;
 }
 
 static void
@@ -460,11 +369,50 @@ on_bus_gotten (GObject               *source_object,
                           manager);
 }
 
+static GUdevDevice *
+get_accelerometer (GUdevClient *client)
+{
+        GList *list, *l;
+        GUdevDevice *ret, *parent;
+
+        /* Look for a device with the ID_INPUT_ACCELEROMETER=1 property */
+        ret = NULL;
+        list = g_udev_client_query_by_subsystem (client, "input");
+        for (l = list; l != NULL; l = l->next) {
+                GUdevDevice *dev;
+
+                dev = l->data;
+                if (g_udev_device_get_property_as_boolean (dev, "ID_INPUT_ACCELEROMETER")) {
+                        ret = dev;
+                        continue;
+                }
+                g_object_unref (dev);
+        }
+        g_list_free (list);
+
+        if (ret == NULL)
+                return NULL;
+
+        /* Now walk up to the parent */
+        parent = g_udev_device_get_parent (ret);
+        if (parent == NULL)
+                return ret;
+
+        if (g_udev_device_get_property_as_boolean (parent, "ID_INPUT_ACCELEROMETER")) {
+                g_object_unref (ret);
+                ret = parent;
+        } else {
+                g_object_unref (parent);
+        }
+
+        return ret;
+}
+
 static gboolean
 gsd_orientation_manager_idle_cb (GsdOrientationManager *manager)
 {
         const char * const subsystems[] = { "input", NULL };
-        char *device_node;
+        GUdevDevice *dev;
 
         gnome_settings_profile_start (NULL);
 
@@ -473,35 +421,24 @@ gsd_orientation_manager_idle_cb (GsdOrientationManager *manager)
         g_signal_connect (G_OBJECT (manager->priv->settings), "changed::orientation-lock",
                           G_CALLBACK (orientation_lock_changed_cb), manager);
 
-        if (!accelerometer_is_present (&device_node,
-                                       &manager->priv->device_id)) {
+        manager->priv->client = g_udev_client_new (subsystems);
+        dev = get_accelerometer (manager->priv->client);
+        if (dev == NULL) {
                 g_debug ("Did not find an accelerometer");
                 return FALSE;
         }
-        g_debug ("Found accelerometer at '%s' (%d)",
-                 device_node,
-                 manager->priv->device_id);
+        manager->priv->sysfs_path = g_strdup (g_udev_device_get_sysfs_path (dev));
+        g_debug ("Found accelerometer at sysfs path '%s'", manager->priv->sysfs_path);
 
-	/* Start process of owning a D-Bus name */
+        manager->priv->prev_orientation = get_orientation_from_device (dev);
+        g_object_unref (dev);
+
+        /* Start process of owning a D-Bus name */
         g_bus_get (G_BUS_TYPE_SESSION,
                    NULL,
                    (GAsyncReadyCallback) on_bus_gotten,
                    manager);
 
-        manager->priv->client = g_udev_client_new (subsystems);
-
-        manager->priv->sysfs_path = get_sysfs_path (manager, device_node);
-
-        if (manager->priv->sysfs_path == NULL) {
-                g_debug ("Could not find sysfs path for '%s'", device_node);
-                g_free (device_node);
-                return FALSE;
-        }
-        g_debug ("Found accelerometer at sysfs path '%s'", manager->priv->sysfs_path);
-        g_free (device_node);
-
-        set_device_enabled (manager->priv->device_id, FALSE);
-
         g_signal_connect (G_OBJECT (manager->priv->client), "uevent",
                           G_CALLBACK (client_uevent_cb), manager);
 
@@ -531,11 +468,6 @@ gsd_orientation_manager_stop (GsdOrientationManager *manager)
 
         g_debug ("Stopping orientation manager");
 
-        if (p->orient_timeout_id > 0) {
-                g_source_remove (p->orient_timeout_id);
-                p->orient_timeout_id = 0;
-        }
-
         if (p->settings) {
                 g_object_unref (p->settings);
                 p->settings = NULL;
@@ -546,11 +478,6 @@ gsd_orientation_manager_stop (GsdOrientationManager *manager)
                 p->sysfs_path = NULL;
         }
 
-        if (p->device_id > 0) {
-                set_device_enabled (p->device_id, TRUE);
-                p->device_id = -1;
-        }
-
         if (p->introspection_data) {
                 g_dbus_node_info_unref (p->introspection_data);
                 p->introspection_data = NULL;



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