[gnome-settings-daemon] orientation: Poll for value changes on accelorometer
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon] orientation: Poll for value changes on accelorometer
- Date: Fri, 3 Jun 2011 00:24:10 +0000 (UTC)
commit 0dff9d119e651426f966c2747f19ea695a56caa0
Author: Bastien Nocera <hadess hadess net>
Date: Fri Jun 3 01:17:34 2011 +0100
orientation: Poll for value changes on accelorometer
We can't easily check for XI2 events happening solely on the
accelerometer, so instead, we'll poll the accelerometer device
a few times to look for value changes in its properties.
We currently look every 150 msecs, 5 times in a row, and only
when we receive events through udev that the device has changed.
Usually, we'll get the new state at the first attempt, which means
we can ask for XRandR to switch us within 200 msecs.
plugins/orientation/gsd-orientation-manager.c | 92 +++++++++++++++++++-----
1 files changed, 73 insertions(+), 19 deletions(-)
---
diff --git a/plugins/orientation/gsd-orientation-manager.c b/plugins/orientation/gsd-orientation-manager.c
index 3d6f1b0..e58e483 100644
--- a/plugins/orientation/gsd-orientation-manager.c
+++ b/plugins/orientation/gsd-orientation-manager.c
@@ -42,10 +42,17 @@ struct GsdOrientationManagerPrivate
guint start_idle_id;
char *sysfs_path;
int device_id;
- OrientationUp prev_orientation;
GUdevClient *client;
+ 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
+
static void gsd_orientation_manager_class_init (GsdOrientationManagerClass *klass);
static void gsd_orientation_manager_init (GsdOrientationManager *orientation_manager);
static void gsd_orientation_manager_finalize (GObject *object);
@@ -130,15 +137,11 @@ get_current_values (GsdOrientationManager *manager,
}
static gboolean
-update_current_orientation (GsdOrientationManager *manager)
+update_current_orientation (GsdOrientationManager *manager,
+ int x, int y, int z)
{
OrientationUp orientation;
- int x, y, z;
- 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);
- return FALSE;
- }
g_debug ("Got values: %d, %d, %d", x, y, z);
orientation = gsd_orientation_calc (manager->priv->prev_orientation,
@@ -158,6 +161,46 @@ update_current_orientation (GsdOrientationManager *manager)
return TRUE;
}
+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);
+ 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)) {
+ /* FIXME: call into XRandR plugin */
+ }
+
+ set_device_enabled (manager->priv->device_id, FALSE);
+
+ 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);
+ return FALSE;
+ }
+
+ manager->priv->num_checks++;
+
+ return TRUE;
+}
+
static void
client_uevent_cb (GUdevClient *client,
gchar *action,
@@ -177,16 +220,24 @@ client_uevent_cb (GUdevClient *client,
g_debug ("Received an event from the accelerometer");
- if (set_device_enabled (manager->priv->device_id, TRUE) == FALSE) {
- g_warning ("Failed to re-enabled device '%d'", manager->priv->device_id);
+ 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;
}
- if (update_current_orientation (manager)) {
- /* FIXME: call into XRandR plugin */
+ if (set_device_enabled (manager->priv->device_id, TRUE) == FALSE) {
+ g_warning ("Failed to re-enabled device '%d'", manager->priv->device_id);
+ return;
}
- set_device_enabled (manager->priv->device_id, FALSE);
+ g_timeout_add (150, (GSourceFunc) check_value_change_cb, manager);
}
static char *
@@ -204,7 +255,7 @@ get_sysfs_path (GsdOrientationManager *manager,
parent = g_udev_device_get_parent (device);
g_object_unref (device);
if (parent == NULL)
- return NULL;
+ return NULL;
sysfs_path = g_strdup (g_udev_device_get_sysfs_path (parent));
g_object_unref (parent);
@@ -241,8 +292,6 @@ gsd_orientation_manager_idle_cb (GsdOrientationManager *manager)
g_debug ("Found accelerometer at sysfs path '%s'", manager->priv->sysfs_path);
g_free (device_node);
- set_device_enabled (manager->priv->device_id, TRUE);
- update_current_orientation (manager);
set_device_enabled (manager->priv->device_id, FALSE);
g_signal_connect (G_OBJECT (manager->priv->client), "uevent",
@@ -271,15 +320,20 @@ 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->sysfs_path) {
g_free (p->sysfs_path);
p->sysfs_path = NULL;
}
- if (p->device_id > 0) {
- set_device_enabled (p->device_id, TRUE);
- p->device_id = -1;
- }
+ if (p->device_id > 0) {
+ set_device_enabled (p->device_id, TRUE);
+ p->device_id = -1;
+ }
if (p->client) {
g_object_unref (p->client);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]