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