[PATCH v2 9/9] Xext: Add per-device SyncCounters

Peter Hutterer peter.hutterer at who-t.net
Wed Mar 14 21:10:30 PDT 2012


Previously, we only had one idle alarm that was triggered for all devices,
whenever the user used any device, came back from suspend, etc.

Add system SyncCounters for each device (named "DEVICEIDLETIME x", with x
being the device id) that trigger on that device only. This allows for
enabling/disabling devices based on interaction with other devices.

Popular use-case: disable the touchpad when the keyboard just above the
touchpad stops being idle.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
---
Changes to v1:
- adapt to SysCounterGetPrivate
- adapt to SysCounterList being a linked list

 Xext/sync.c        |   48 +++++++++++++++++++++++++++++++++++++++++++-----
 Xext/syncsrv.h     |    3 +++
 dix/devices.c      |    8 ++++++++
 include/inputstr.h |    2 ++
 4 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/Xext/sync.c b/Xext/sync.c
index 5479381..c2f6573 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -70,6 +70,7 @@ PERFORMANCE OF THIS SOFTWARE.
 #include "syncsrv.h"
 #include "syncsdk.h"
 #include "protocol-versions.h"
+#include "inputstr.h"
 
 #include <stdio.h>
 #if !defined(WIN32)
@@ -2715,12 +2716,22 @@ SyncInitServerTime(void)
 typedef struct {
     XSyncValue *value_less;
     XSyncValue *value_greater;
+    int deviceid;
 } IdleCounterPriv;
 
 static void
 IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return)
 {
-    CARD32 idle = GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds;
+    int deviceid;
+    CARD32 idle;
+
+    if (pCounter) {
+        SyncCounter *counter = pCounter;
+        IdleCounterPriv *priv = SysCounterGetPrivate(counter);
+        deviceid = priv->deviceid;
+    } else
+        deviceid = XIAllDevices;
+    idle = GetTimeInMillis() - lastDeviceEventTime[deviceid].milliseconds;
     XSyncIntsToValue (pValue_return, idle, 0);
 }
 
@@ -2813,7 +2824,7 @@ IdleTimeWakeupHandler (pointer pCounter, int rc, pointer LastSelectMask)
     if (!less && !greater)
 	return;
 
-    IdleTimeQueryValue (NULL, &idle);
+    IdleTimeQueryValue (pCounter, &idle);
 
     if ((greater && XSyncValueGreaterOrEqual (idle, *greater)) ||
         (less && XSyncValueLessOrEqual (idle, *less)))
@@ -2849,8 +2860,8 @@ IdleTimeBracketValues (pointer pCounter, CARD64 *pbracket_less,
     priv->value_less    = pbracket_less;
 }
 
-static void
-SyncInitIdleTime (void)
+static SyncCounter*
+init_system_idle_counter(const char *name, int deviceid)
 {
     CARD64 resolution;
     XSyncValue idle;
@@ -2860,12 +2871,39 @@ SyncInitIdleTime (void)
     IdleTimeQueryValue (NULL, &idle);
     XSyncIntToValue (&resolution, 4);
 
-    idle_time_counter = SyncCreateSystemCounter("IDLETIME", idle, resolution,
+    idle_time_counter = SyncCreateSystemCounter(name, idle, resolution,
 						XSyncCounterUnrestricted,
 						IdleTimeQueryValue,
 						IdleTimeBracketValues);
 
+    priv->deviceid = deviceid;
     priv->value_less = priv->value_greater = NULL;
 
     idle_time_counter->pSysCounterInfo->private = priv;
+
+    return idle_time_counter;
+}
+
+static void
+SyncInitIdleTime (void)
+{
+    init_system_idle_counter("IDLETIME", XIAllDevices);
 }
+
+SyncCounter*
+SyncInitDeviceIdleTime(DeviceIntPtr dev)
+{
+    char timer_name[64];
+    sprintf(timer_name, "DEVICEIDLETIME %d", dev->id);
+
+    return init_system_idle_counter(timer_name, dev->id);
+}
+
+void SyncRemoveDeviceIdleTime(SyncCounter *counter)
+{
+    /* ResetProc frees the list before devices are shutdown and try to
+     * delete their counters again */
+    if (!xorg_list_is_empty(&SysCounterList))
+        xorg_list_del(&counter->pSysCounterInfo->entry);
+}
+
diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h
index 27b533c..84c7aee 100644
--- a/Xext/syncsrv.h
+++ b/Xext/syncsrv.h
@@ -139,4 +139,7 @@ extern void SyncDestroySystemCounter(
 );
 
 extern void SyncExtensionInit(void);
+
+extern SyncCounter *SyncInitDeviceIdleTime(DeviceIntPtr dev);
+extern void SyncRemoveDeviceIdleTime(SyncCounter *counter);
 #endif /* _SYNCSRV_H_ */
diff --git a/dix/devices.c b/dix/devices.c
index 7478ad6..a488d41 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -87,6 +87,7 @@ SOFTWARE.
 #include "enterleave.h" /* for EnterWindow() */
 #include "xserver-properties.h"
 #include "xichangehierarchy.h" /* For XISendDeviceHierarchyEvent */
+#include "syncsrv.h"
 
 /** @file
  * This file handles input device-related stuff.
@@ -419,9 +420,13 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent)
 
     RecalculateMasterButtons(dev);
 
+    /* initialise an idle timer for this device*/
+    dev->idle_counter = SyncInitDeviceIdleTime(dev);
+
     return TRUE;
 }
 
+
 /**
  * Switch a device off through the driver and push it onto the off_devices
  * list. A device will not send events while disabled. All clients are
@@ -447,6 +452,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
     if (*prev != dev)
 	return FALSE;
 
+    SyncRemoveDeviceIdleTime(dev->idle_counter);
+    dev->idle_counter = NULL;
+
     /* float attached devices */
     if (IsMaster(dev))
     {
diff --git a/include/inputstr.h b/include/inputstr.h
index 86db811..7517b8e 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -606,6 +606,8 @@ typedef struct _DeviceIntRec {
 
     /* XTest related master device id */
     int xtest_master_id;
+
+    struct _SyncCounter *idle_counter;
 } DeviceIntRec;
 
 typedef struct {
-- 
1.7.7.6



More information about the xorg-devel mailing list