a958cb4
commit 7e2c935920cafadbd87c351f1a3239932864fb90
a958cb4
Author: Fredrik Höglund <fredrik@kde.org>
a958cb4
Date:   Fri May 18 20:06:14 2007 +0200
a958cb4
a958cb4
    Add a new IDLETIME system sync counter.
a958cb4
    
a958cb4
    This counter exposes the time in milliseconds since the last
a958cb4
    input event. Clients such as screen savers and power managers
a958cb4
    can set an alarm on this counter to find out when the idle time
a958cb4
    reaches a certain value, without having to poll the server.
a958cb4
a958cb4
diff --git a/Xext/sync.c b/Xext/sync.c
a958cb4
index c5441a1..6fc2dcc 100644
a958cb4
--- a/Xext/sync.c
a958cb4
+++ b/Xext/sync.c
a958cb4
@@ -243,6 +243,11 @@ SyncInitServerTime(
a958cb4
     void
a958cb4
 );
a958cb4
 
a958cb4
+static void
a958cb4
+SyncInitIdleTime(
a958cb4
+    void
a958cb4
+);
a958cb4
+
a958cb4
 static void 
a958cb4
 SyncResetProc(
a958cb4
     ExtensionEntry * /* extEntry */
a958cb4
@@ -2400,6 +2405,7 @@ SyncExtensionInit(INITARGS)
a958cb4
      * because there is always a servertime counter.
a958cb4
      */
a958cb4
     SyncInitServerTime();
a958cb4
+    SyncInitIdleTime();
a958cb4
 
a958cb4
 #ifdef DEBUG
a958cb4
     fprintf(stderr, "Sync Extension %d.%d\n",
a958cb4
@@ -2520,3 +2526,116 @@ SyncInitServerTime(void)
a958cb4
 			    ServertimeQueryValue, ServertimeBracketValues);
a958cb4
     pnext_time = NULL;
a958cb4
 }
a958cb4
+
a958cb4
+
a958cb4
+
a958cb4
+/*
a958cb4
+ * IDLETIME implementation
a958cb4
+ */
a958cb4
+
a958cb4
+static pointer IdleTimeCounter;
a958cb4
+static XSyncValue *pIdleTimeValueLess;
a958cb4
+static XSyncValue *pIdleTimeValueGreater;
a958cb4
+
a958cb4
+static void
a958cb4
+IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return)
a958cb4
+{
a958cb4
+    CARD32 idle = GetTimeInMillis() - lastDeviceEventTime.milliseconds;
a958cb4
+    XSyncIntsToValue (pValue_return, idle, 0);
a958cb4
+}
a958cb4
+
a958cb4
+static void
a958cb4
+IdleTimeBlockHandler (pointer env,
a958cb4
+                      struct timeval **wt,
a958cb4
+                      pointer LastSelectMask)
a958cb4
+{
a958cb4
+    XSyncValue idle;
a958cb4
+
a958cb4
+    if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
a958cb4
+	return;
a958cb4
+
a958cb4
+    IdleTimeQueryValue (NULL, &idle);
a958cb4
+
a958cb4
+    if (pIdleTimeValueLess &&
a958cb4
+        XSyncValueLessOrEqual (idle, *pIdleTimeValueLess))
a958cb4
+    {
a958cb4
+	AdjustWaitForDelay (wt, 0);
a958cb4
+    }
a958cb4
+    else if (pIdleTimeValueGreater)
a958cb4
+    {
a958cb4
+	unsigned long timeout = 0;
a958cb4
+
a958cb4
+	if (XSyncValueLessThan (idle, *pIdleTimeValueGreater))
a958cb4
+	{
a958cb4
+	    XSyncValue value;
a958cb4
+	    Bool overflow;
a958cb4
+
a958cb4
+	    XSyncValueSubtract (&value, *pIdleTimeValueGreater,
a958cb4
+	                        idle, &overflow);
a958cb4
+	    timeout = XSyncValueLow32 (value);
a958cb4
+	}
a958cb4
+
a958cb4
+	AdjustWaitForDelay (wt, timeout);
a958cb4
+    }
a958cb4
+}
a958cb4
+
a958cb4
+static void
a958cb4
+IdleTimeWakeupHandler (pointer env,
a958cb4
+                       int rc,
a958cb4
+                       pointer LastSelectMask)
a958cb4
+{
a958cb4
+    XSyncValue idle;
a958cb4
+
a958cb4
+    if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
a958cb4
+	return;
a958cb4
+
a958cb4
+    IdleTimeQueryValue (NULL, &idle);
a958cb4
+
a958cb4
+    if ((pIdleTimeValueGreater &&
a958cb4
+         XSyncValueGreaterThan (idle, *pIdleTimeValueGreater)) ||
a958cb4
+        (pIdleTimeValueLess && XSyncValueLessThan (idle, *pIdleTimeValueLess)))
a958cb4
+    {
a958cb4
+	SyncChangeCounter (IdleTimeCounter, idle);
a958cb4
+    }
a958cb4
+}
a958cb4
+
a958cb4
+static void
a958cb4
+IdleTimeBracketValues (pointer pCounter,
a958cb4
+                       CARD64 *pbracket_less,
a958cb4
+                       CARD64 *pbracket_greater)
a958cb4
+{
a958cb4
+    Bool registered = (pIdleTimeValueLess || pIdleTimeValueGreater);
a958cb4
+
a958cb4
+    if (registered && !pbracket_less && !pbracket_greater)
a958cb4
+    {
a958cb4
+	RemoveBlockAndWakeupHandlers(IdleTimeBlockHandler,
a958cb4
+	                             IdleTimeWakeupHandler,
a958cb4
+	                             NULL);
a958cb4
+    }
a958cb4
+    else if (!registered && (pbracket_less || pbracket_greater))
a958cb4
+    {
a958cb4
+	RegisterBlockAndWakeupHandlers(IdleTimeBlockHandler,
a958cb4
+	                               IdleTimeWakeupHandler,
a958cb4
+	                               NULL);
a958cb4
+    }
a958cb4
+
a958cb4
+    pIdleTimeValueGreater = pbracket_greater;
a958cb4
+    pIdleTimeValueLess    = pbracket_less;
a958cb4
+}
a958cb4
+
a958cb4
+static void
a958cb4
+SyncInitIdleTime (void)
a958cb4
+{
a958cb4
+    CARD64 resolution;
a958cb4
+    XSyncValue idle;
a958cb4
+
a958cb4
+    IdleTimeQueryValue (NULL, &idle);
a958cb4
+    XSyncIntToValue (&resolution, 4);
a958cb4
+
a958cb4
+    IdleTimeCounter = SyncCreateSystemCounter ("IDLETIME", idle, resolution,
a958cb4
+                                               XSyncCounterUnrestricted,
a958cb4
+                                               IdleTimeQueryValue,
a958cb4
+                                               IdleTimeBracketValues);
a958cb4
+
a958cb4
+    pIdleTimeValueLess = pIdleTimeValueGreater = NULL;
a958cb4
+}