aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/Xserver/Xext/sync.c
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2018-07-03 14:43:26 +0200
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2018-07-03 15:26:15 +0200
commit14f734873d2b2c5d96d563482384a996c50f1068 (patch)
tree7adf68ffc91becd374a3a2ffe5f633f928932745 /nx-X11/programs/Xserver/Xext/sync.c
parent72f11ee838e67757e235e7216fb82679cc3f7d67 (diff)
downloadnx-libs-14f734873d2b2c5d96d563482384a996c50f1068.tar.gz
nx-libs-14f734873d2b2c5d96d563482384a996c50f1068.tar.bz2
nx-libs-14f734873d2b2c5d96d563482384a996c50f1068.zip
Backport IDLETIME system counter to nx-X11 Xserver.
This resolves issues with non-starting mate-screensaver which relies on the IDLETIME API these days. This commit backports the following X.org Xserver commits: commit a2e67a6412386782cb8b644b86a5744591397d45 Author: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com> Date: Mon Dec 6 11:24:01 2010 +1100 IDLETIME: Fix edge-case in IdleTimeBlockHandler Ensure that if we're called exactly on the threshold of a NegativeTransition trigger that we reshedule to pick up an idle time over the threshold. Signed-off-by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com> Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Keith Packard <keithp@keithp.com> commit 1f4fb0225b278d1cf4145aebeb0bdd23dc8f62d5 Author: Adam Jackson <ajax@redhat.com> Date: Wed Dec 10 16:13:20 2008 -0500 xsync: Fix wakeup storm in idletime counter. Wakeup scheduling only considered the threshold values, and not whether the trigger was edge or level. See also: https://bugzilla.redhat.com/show_bug.cgi?id=474586 http://svn.gnome.org/viewvc/gnome-screensaver/trunk/src/test-idle-ext.c?view=markup commit 0f9e89b4e309e570d7d366489d250ca2143f0ad7 Author: Fredrik Höglund <fredrik@kde.org> Date: Tue Aug 14 22:47:49 2007 +0200 Fix the value comparisons in the IDLETIME wakeup handler. LessThan/GreaterThan comparisons were used in the wakeup handler, and LessOrEqual/GreaterOrEqual in the block handler. Change it to use LessOrEqual/GreaterOrEqual in both functions, since this is what XSyncNegativeComparison and XSyncPositiveComparison imply. commit 7e2c935920cafadbd87c351f1a3239932864fb90 Author: Fredrik Höglund <fredrik@kde.org> Date: Fri May 18 20:06:14 2007 +0200 Add a new IDLETIME system sync counter. This counter exposes the time in milliseconds since the last input event. Clients such as screen savers and power managers can set an alarm on this counter to find out when the idle time reaches a certain value, without having to poll the server. Backport-to-NX-by: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
Diffstat (limited to 'nx-X11/programs/Xserver/Xext/sync.c')
-rw-r--r--nx-X11/programs/Xserver/Xext/sync.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/Xext/sync.c b/nx-X11/programs/Xserver/Xext/sync.c
index e90e35db9..a0711b77a 100644
--- a/nx-X11/programs/Xserver/Xext/sync.c
+++ b/nx-X11/programs/Xserver/Xext/sync.c
@@ -240,6 +240,11 @@ SyncInitServerTime(
void
);
+static void
+SyncInitIdleTime(
+ void
+);
+
static void
SyncResetProc(
ExtensionEntry * /* extEntry */
@@ -2365,6 +2370,7 @@ SyncExtensionInit(void)
* because there is always a servertime counter.
*/
SyncInitServerTime();
+ SyncInitIdleTime();
#ifdef DEBUG
fprintf(stderr, "Sync Extension %d.%d\n",
@@ -2485,3 +2491,156 @@ SyncInitServerTime()
ServertimeQueryValue, ServertimeBracketValues);
pnext_time = NULL;
}
+
+
+/*
+ * IDLETIME implementation
+ */
+
+static SyncCounter *IdleTimeCounter;
+static XSyncValue *pIdleTimeValueLess;
+static XSyncValue *pIdleTimeValueGreater;
+
+static void
+IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return)
+{
+ CARD32 idle = GetTimeInMillis() - lastDeviceEventTime.milliseconds;
+ XSyncIntsToValue (pValue_return, idle, 0);
+}
+
+static void
+IdleTimeBlockHandler (pointer env, struct timeval **wt, pointer LastSelectMask)
+{
+ XSyncValue idle, old_idle;
+ SyncTriggerList *list = IdleTimeCounter->pTriglist;
+ SyncTrigger *trig;
+
+ if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
+ return;
+
+ old_idle = IdleTimeCounter->value;
+ IdleTimeQueryValue (NULL, &idle);
+ IdleTimeCounter->value = idle; /* push, so CheckTrigger works */
+
+ if (pIdleTimeValueLess &&
+ XSyncValueLessOrEqual (idle, *pIdleTimeValueLess))
+ {
+ /*
+ * We've been idle for less than the threshold value, and someone
+ * wants to know about that, but now we need to know whether they
+ * want level or edge trigger. Check the trigger list against the
+ * current idle time, and if any succeed, bomb out of select()
+ * immediately so we can reschedule.
+ */
+
+ for (list = IdleTimeCounter->pTriglist; list; list = list->next) {
+ trig = list->pTrigger;
+ if (trig->CheckTrigger(trig, old_idle)) {
+ AdjustWaitForDelay(wt, 0);
+ break;
+ }
+ }
+
+ /*
+ * We've been called exactly on the idle time, but we have a
+ * NegativeTransition trigger which requires a transition from an
+ * idle time greater than this. Schedule a wakeup for the next
+ * millisecond so we won't miss a transition.
+ */
+ if (XSyncValueEqual (idle, *pIdleTimeValueLess))
+ AdjustWaitForDelay(wt, 1);
+ }
+ else if (pIdleTimeValueGreater)
+ {
+ /*
+ * There's a threshold in the positive direction. If we've been
+ * idle less than it, schedule a wakeup for sometime in the future.
+ * If we've been idle more than it, and someone wants to know about
+ * that level-triggered, schedule an immediate wakeup.
+ */
+ unsigned long timeout = -1;
+
+ if (XSyncValueLessThan (idle, *pIdleTimeValueGreater)) {
+ XSyncValue value;
+ Bool overflow;
+
+ XSyncValueSubtract (&value, *pIdleTimeValueGreater,
+ idle, &overflow);
+ timeout = min(timeout, XSyncValueLow32 (value));
+ } else {
+ for (list = IdleTimeCounter->pTriglist; list; list = list->next) {
+ trig = list->pTrigger;
+ if (trig->CheckTrigger(trig, old_idle)) {
+ timeout = min(timeout, 0);
+ break;
+ }
+ }
+ }
+
+ AdjustWaitForDelay (wt, timeout);
+ }
+
+ IdleTimeCounter->value = old_idle; /* pop */
+}
+
+static void
+IdleTimeWakeupHandler (pointer env,
+ int rc,
+ pointer LastSelectMask)
+{
+ XSyncValue idle;
+
+ if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
+ return;
+
+ IdleTimeQueryValue (NULL, &idle);
+
+ if ((pIdleTimeValueGreater &&
+ XSyncValueGreaterOrEqual (idle, *pIdleTimeValueGreater)) ||
+ (pIdleTimeValueLess &&
+ XSyncValueLessOrEqual (idle, *pIdleTimeValueLess)))
+ {
+ SyncChangeCounter (IdleTimeCounter, idle);
+ }
+}
+
+static void
+IdleTimeBracketValues (pointer pCounter,
+ CARD64 *pbracket_less,
+ CARD64 *pbracket_greater)
+{
+ Bool registered = (pIdleTimeValueLess || pIdleTimeValueGreater);
+
+ if (registered && !pbracket_less && !pbracket_greater)
+ {
+ RemoveBlockAndWakeupHandlers(IdleTimeBlockHandler,
+ IdleTimeWakeupHandler,
+ NULL);
+ }
+ else if (!registered && (pbracket_less || pbracket_greater))
+ {
+ RegisterBlockAndWakeupHandlers(IdleTimeBlockHandler,
+ IdleTimeWakeupHandler,
+ NULL);
+ }
+
+ pIdleTimeValueGreater = pbracket_greater;
+ pIdleTimeValueLess = pbracket_less;
+}
+
+static void
+SyncInitIdleTime (void)
+{
+ CARD64 resolution;
+ XSyncValue idle;
+
+ IdleTimeQueryValue (NULL, &idle);
+ XSyncIntToValue (&resolution, 4);
+
+ IdleTimeCounter = SyncCreateSystemCounter ("IDLETIME", idle, resolution,
+ XSyncCounterUnrestricted,
+ IdleTimeQueryValue,
+ IdleTimeBracketValues);
+
+ pIdleTimeValueLess = pIdleTimeValueGreater = NULL;
+}