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