update install for ubuntu 11.04
[ozzloy@gmail.com/oble] / idle_x11.cpp
1 /*
2 * Copyright © 2009 Christopher Eby <kreed@kreed.org>
3 *
4 * This file is part of Inertia.
5 *
6 * Inertia is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Library General Public License as
8 * published by the Free Software Foundation, either version 3 of
9 * the License, or (at your option) any later version.
10 *
11 * Inertia is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 *
15 * See <http://www.gnu.org/licenses/> for the full license text.
16 */
17
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <string.h>
21
22 #include <X11/Xlib.h>
23 #include <X11/extensions/sync.h>
24 #include <X11/extensions/scrnsaver.h>
25
26 static Display *dpy = NULL;
27
28 static void get_alarm(XSyncAlarm *alarm, XSyncCounter counter, XSyncTestType type, XSyncValue value)
29 {
30 XSyncAlarmAttributes attrs;
31
32 XSyncValue delta;
33 XSyncIntToValue(&delta, 0);
34
35 static const unsigned long flags = XSyncCACounter | XSyncCATestType | XSyncCAValue | XSyncCADelta;
36
37 attrs.trigger.counter = counter;
38 attrs.trigger.test_type = type;
39 attrs.trigger.wait_value = value;
40 attrs.delta = delta;
41
42 if (*alarm)
43 XSyncChangeAlarm(dpy, *alarm, flags, &attrs);
44 else
45 *alarm = XSyncCreateAlarm(dpy, flags, &attrs);
46 }
47
48 static void die(const char *errstr)
49 {
50 fputs(errstr, stderr);
51 fflush(stderr);
52 exit(EXIT_FAILURE);
53 }
54
55 bool wait_for_idle_time(int idle_time)
56 {
57 static int xsync_event_base;
58 static XSyncAlarm idle_alarm = None;
59 static XSyncAlarm reset_alarm = None;
60 static XSyncCounter idle = None;
61 static XSyncValue idle_timeout;
62
63 if (idle == None) {
64 if (!(dpy = XOpenDisplay(NULL)))
65 die("Could not open X11 display; exiting.\n");
66
67 int dummy;
68 if (!XQueryExtension(dpy, "XTEST", &dummy, &dummy, &dummy))
69 die("XTEST extension not available; cannot reset idle time\n");
70
71 int xsync_error_base;
72 int xsync_major = SYNC_MAJOR_VERSION;
73 int xsync_minor = SYNC_MINOR_VERSION;
74
75 if (!XSyncQueryExtension(dpy, &xsync_event_base, &xsync_error_base) || !XSyncInitialize(dpy, &xsync_major, &xsync_minor))
76 die("No XSync extension; exiting.\n");
77
78 int i;
79 XSyncSystemCounter *counters = XSyncListSystemCounters(dpy, &i);
80 while (i--)
81 if (!strcmp(counters[i].name, "IDLETIME"))
82 idle = counters[i].counter;
83 XSyncFreeSystemCounterList(counters);
84
85 if (idle == None)
86 die("No IDLETIME counter! xorg-server 1.3 and higher should support it. Exiting.\n");
87
88 XSyncIntToValue(&idle_timeout, idle_time * 1000);
89 get_alarm(&idle_alarm, idle, XSyncPositiveComparison, idle_timeout);
90 }
91
92 XEvent ev;
93
94 while (!XNextEvent(dpy, &ev)) {
95 if (ev.type == xsync_event_base + XSyncAlarmNotify) {
96 XSyncAlarmNotifyEvent *e = (XSyncAlarmNotifyEvent*)&ev;
97
98 if (e->alarm == idle_alarm) {
99 int overflow;
100 XSyncValue reset_timeout;
101 XSyncValue minus_one;
102
103 XSyncIntToValue(&minus_one, -1);
104 XSyncValueAdd(&reset_timeout, e->counter_value, minus_one, &overflow);
105 get_alarm(&reset_alarm, idle, XSyncNegativeComparison, reset_timeout);
106
107 return true;
108 } else if (e->alarm == reset_alarm) {
109 get_alarm(&idle_alarm, idle, XSyncPositiveComparison, idle_timeout);
110 }
111 }
112 }
113
114 return false;
115 }
116
117 void reset_idle_time()
118 {
119 if (!dpy) {
120 if (!(dpy = XOpenDisplay(NULL))) {
121 fputs("Could not open X11 display.\n", stderr);
122 return;
123 }
124 }
125
126 XScreenSaverSuspend(dpy, True);
127 XSync(dpy, False);
128 XScreenSaverSuspend(dpy, False);
129 XSync(dpy, False);
130 }