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