Mercurial > pidgin.yaz
comparison src/idle.c @ 1026:5bad25457843
[gaim-migrate @ 1036]
X-Idle support. Thanks bryner and bmiller!
Both of you guys sent me similar patches :)
committer: Tailor Script <tailor@pidgin.im>
author | Rob Flynn <gaim@robflynn.com> |
---|---|
date | Thu, 26 Oct 2000 07:22:32 +0000 |
parents | 2846a03bda67 |
children | a375efb2884e |
comparison
equal
deleted
inserted
replaced
1025:84a5d80e52f1 | 1026:5bad25457843 |
---|---|
1 #if 0 | 1 /* |
2 //---------------------------------------------------------------------------- | 2 * gaim |
3 // This is a somewhat modified kscreensaver. | |
4 // The original copyright notice follows | |
5 // | |
6 //---------------------------------------------------------------------------- | |
7 // | |
8 // KDE screensavers | |
9 // | |
10 // This module is a heavily modified xautolock. | |
11 // The orignal copyright notice follows | |
12 // | |
13 | |
14 /***************************************************************************** | |
15 * | 3 * |
16 * xautolock | 4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> |
17 * ========= | |
18 * | 5 * |
19 * Authors : S. De Troch (SDT) + M. Eyckmans (MCE) | 6 * This program is free software; you can redistribute it and/or modify |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
20 * | 10 * |
21 * Date : 22/07/90 | 11 * This program is distributed in the hope that it will be useful, |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
22 * | 15 * |
23 * --------------------------------------------------------------------------- | 16 * You should have received a copy of the GNU General Public License |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 * | 19 * |
25 * Copyright 1990, 1992-1995 by S. De Troch and MCE. | |
26 * | |
27 * Permission to use, copy, modify and distribute this software and the | |
28 * supporting documentation without fee is hereby granted, provided that | |
29 * | |
30 * 1 : Both the above copyright notice and this permission notice | |
31 * appear in all copies of both the software and the supporting | |
32 * documentation. | |
33 * 2 : No financial profit is made out of it. | |
34 * | |
35 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
36 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO | |
37 * EVENT SHALL THEY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL | |
38 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA | |
39 * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
40 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
41 * PERFORMANCE OF THIS SOFTWARE. | |
42 * | |
43 *****************************************************************************/ | |
44 | |
45 | |
46 | |
47 /* | |
48 * Have a guess what this does... | |
49 * ============================== | |
50 * | |
51 * Warning for swm & tvtwm users : xautolock should *not* be compiled | |
52 * with vroot.h, because it needs to know the real root window. | |
53 */ | 20 */ |
54 | 21 |
55 #ifdef HAVE_CONFIG_H | 22 #ifdef HAVE_CONFIG_H |
56 #include <config.h> | 23 #include "../config.h" |
24 #endif | |
25 #include <time.h> | |
26 #include <stdio.h> | |
27 #include <unistd.h> | |
28 #include <aim.h> | |
29 | |
30 #ifdef USE_SCREENSAVER | |
31 #include <X11/Xlib.h> | |
32 #include <X11/Xutil.h> | |
33 #include <X11/extensions/scrnsaver.h> | |
34 #endif /* USE_SCREENSAVER */ | |
35 | |
36 #include "multi.h" | |
37 #include "gaim.h" | |
38 | |
39 | |
40 gint check_idle(struct gaim_connection *gc) | |
41 { | |
42 time_t t; | |
43 #ifdef USE_SCREENSAVER | |
44 static XScreenSaverInfo *mit_info = NULL; | |
45 Display *d = XOpenDisplay((char*)NULL); | |
46 time_t idle_time; | |
57 #endif | 47 #endif |
58 | 48 |
59 #if defined(hpux) || defined (__hpux) | 49 /* Not idle, really... :) */ |
60 #ifndef _HPUX_SOURCE | 50 update_all_buddies(); |
61 #define _HPUX_SOURCE | |
62 #endif /* _HPUX_SOURCE */ | |
63 #endif /* hpux || __hpux */ | |
64 | 51 |
65 #include <stdio.h> | 52 plugin_event(event_blist_update, 0, 0, 0, 0); |
66 #include <string.h> | 53 |
67 #include <ctype.h> | 54 time(&t); |
68 | 55 |
69 #ifdef VMS | 56 if (report_idle == 0) |
70 #include <ssdef.h> | 57 return TRUE; |
71 #include <processes.h> /* really needed? */ | 58 /* |
72 #endif /* VMS */ | 59 if (gc->is_idle) { |
60 fprintf (stderr, "\tgc->is_idle\n"); | |
61 return TRUE; | |
62 } | |
63 */ | |
73 | 64 |
74 #include <X11/Xlib.h> | 65 #ifdef USE_SCREENSAVER |
75 #include <X11/Xatom.h> | 66 if (report_idle == IDLE_SCREENSAVER) { |
76 #include <X11/Xresource.h> | 67 if (mit_info == NULL) { |
68 mit_info = XScreenSaverAllocInfo (); | |
69 } | |
70 XScreenSaverQueryInfo (d, DefaultRootWindow(d), mit_info); | |
71 idle_time = (mit_info->idle)/1000; | |
72 } else | |
73 #endif /* USE_SCREENSAVER */ | |
74 idle_time = t - gc->lastsent; | |
77 | 75 |
78 #include <time.h> | 76 if (idle_time > 600) { /* 10 minutes! */ |
79 #include <signal.h> | 77 serv_set_idle(gc, idle_time); |
80 #include <sys/wait.h> | 78 gc->is_idle = 1; |
81 #include <sys/types.h> | 79 } else |
80 serv_touch_idle(gc); | |
82 | 81 |
83 #ifdef HAVE_SYS_M_WAIT_H | 82 return TRUE; |
84 #include <sys/m_wait.h> | |
85 #endif | |
86 | |
87 #ifdef HAVE_MALLOC_H | |
88 #include <malloc.h> | |
89 #endif | |
90 | |
91 #ifdef HAVE_UNISTD_H | |
92 #include <unistd.h> | |
93 #endif | |
94 #include <stdlib.h> | |
95 | |
96 #include <gdk/gdkx.h> | |
97 #include <gtk/gtk.h> | |
98 #include "gaim.h" | |
99 | |
100 void initAutoLock(); | |
101 void cleanupAutoLock(); | |
102 | |
103 /* | |
104 * Usefull macros and customization stuff | |
105 * ====================================== | |
106 */ | |
107 #define PP(x) x | |
108 | |
109 #ifdef VMS | |
110 #define ALL_OK 1 /* for use by exit () */ | |
111 #define PROBLEMS SS$_ABORT | |
112 /* for use by exit () */ | |
113 #else /* VMS */ | |
114 #define ALL_OK 0 /* for use by exit () */ | |
115 #define PROBLEMS 1 /* for use by exit () */ | |
116 #endif /* VMS */ | |
117 | |
118 | |
119 #define CREATION_DELAY 30 /* should be > 10 and | |
120 < min (45,(MIN_MINUTES*30)) */ | |
121 #define TIME_CHANGE_LIMIT 120 /* if the time changes by more | |
122 than x secs then we will | |
123 assume someone has changed | |
124 date or machine has suspended */ | |
125 | |
126 | |
127 #ifndef HasVFork | |
128 #define vfork fork | |
129 #endif /* HasVFork */ | |
130 | |
131 #define Error0(str) fprintf (stderr, str) | |
132 #define SetTrigger(delta) trigger = time ((time_t*) NULL) + delta | |
133 | |
134 static caddr_t ch_ptr; /* this is dirty */ | |
135 #define Skeleton(t,s) (ch_ptr = (Caddrt) malloc ((Unsigned) s), \ | |
136 (ch_ptr == (Caddrt) NULL) \ | |
137 ? (Error0 ("Out of memory.\n"), \ | |
138 exit (PROBLEMS), \ | |
139 /*NOTREACHED*/ (t*) NULL \ | |
140 ) \ | |
141 : (t*) ch_ptr \ | |
142 ) \ | |
143 | |
144 #define New(tp) Skeleton (tp, sizeof (tp)) | |
145 | |
146 | |
147 | |
148 /* | |
149 * New types | |
150 * ========= | |
151 */ | |
152 #if defined (apollo) || defined (news1800) | |
153 typedef int (*XErrorHandler) PP((Display*, | |
154 XErrorEvent*)); | |
155 #endif /* apollo || news1800 */ | |
156 | |
157 #if defined (news1800) || defined (sun386) | |
158 typedef int pid_t; | |
159 #endif /* news1800 || sun386*/ | |
160 | |
161 #ifdef VMS | |
162 typedef long pid_t; | |
163 #endif /* VMS */ | |
164 | |
165 #define Void void /* no typedef because of VAX */ | |
166 typedef int Int; | |
167 typedef char Char; | |
168 typedef char* String; | |
169 typedef int Boolean; | |
170 typedef caddr_t Caddrt; | |
171 typedef unsigned int Unsigned; | |
172 typedef unsigned long Huge; | |
173 | |
174 typedef struct QueueItem_ | |
175 { | |
176 Window window; /* as it says */ | |
177 time_t creationtime; /* as it says */ | |
178 struct QueueItem_* next; /* as it says */ | |
179 struct QueueItem_* prev; /* as it says */ | |
180 } aQueueItem, *QueueItem; | |
181 | |
182 typedef struct Queue_ | |
183 { | |
184 struct QueueItem_* head; /* as it says */ | |
185 struct QueueItem_* tail; /* as it says */ | |
186 } aQueue, *Queue; | |
187 | |
188 | |
189 /* | |
190 * Function declarations | |
191 * ===================== | |
192 */ | |
193 #if defined(news1800) | |
194 extern Void* malloc PP((Unsigned)); | |
195 #endif /* news1800 */ | |
196 | |
197 static int EvaluateCounter PP((Display*)); | |
198 static int QueryPointer PP((Display*, int)); | |
199 static int ProcessEvents PP((Display*, Queue, int)); | |
200 static Queue NewQueue PP((Void)); | |
201 static Void AddToQueue PP((Queue, Window)); | |
202 static Void ProcessQueue PP((Queue, Display*, time_t)); | |
203 static Void SelectEvents PP((Display*, Window, Boolean)); | |
204 | |
205 | |
206 /* | |
207 * Global variables | |
208 * ================ | |
209 */ | |
210 static time_t trigger = 0; /* as it says */ | |
211 static time_t time_limit = IDLE_REPORT_TIME; /* as it says */ | |
212 | |
213 /* | |
214 * Functions related to the window queue | |
215 * ===================================== | |
216 * | |
217 * Function for creating a new queue | |
218 * --------------------------------- | |
219 */ | |
220 static Queue NewQueue () | |
221 | |
222 { | |
223 Queue queue; /* return value */ | |
224 | |
225 queue = New (aQueue); | |
226 queue->tail = New (aQueueItem); | |
227 queue->head = New (aQueueItem); | |
228 | |
229 queue->tail->next = queue->head; | |
230 queue->head->prev = queue->tail; | |
231 queue->tail->prev = queue->head->next = (QueueItem) NULL; | |
232 | |
233 return queue; | |
234 } | |
235 | |
236 | |
237 /* | |
238 * Function for adding an item to a queue | |
239 * -------------------------------------- | |
240 */ | |
241 static Void AddToQueue (Queue queue, Window window) | |
242 { | |
243 QueueItem newq; /* new item */ | |
244 | |
245 newq = New (aQueueItem); | |
246 | |
247 newq->window = window; | |
248 newq->creationtime = time ((time_t*) NULL); | |
249 newq->next = queue->tail->next; | |
250 newq->prev = queue->tail; | |
251 queue->tail->next->prev = newq; | |
252 queue->tail->next = newq; | |
253 } | |
254 | |
255 /* | |
256 * Function for processing those entries that are old enough | |
257 * --------------------------------------------------------- | |
258 */ | |
259 static Void ProcessQueue (Queue queue, Display *d, time_t age) | |
260 { | |
261 QueueItem current; /* as it says */ | |
262 time_t now; /* as it says */ | |
263 | |
264 time (&now); | |
265 current = queue->head->prev; | |
266 | |
267 while ( current->prev && current->creationtime + age < now ) | |
268 { | |
269 SelectEvents (d, current->window, False); | |
270 current = current->prev; | |
271 free (current->next); | |
272 } | |
273 | |
274 current->next = queue->head; | |
275 queue->head->prev = current; | |
276 } | |
277 | |
278 | |
279 static Void FreeQueue( Queue queue ) | |
280 { | |
281 QueueItem current; /* as it says */ | |
282 | |
283 current = queue->head->prev; | |
284 | |
285 while ( current->prev ) | |
286 { | |
287 current = current->prev; | |
288 free(current->next); | |
289 } | |
290 | |
291 free(current); | |
292 free(queue); | |
293 } | |
294 | |
295 | |
296 /* | |
297 * Functions related to (the lack of) user activity | |
298 * ================================================ | |
299 * | |
300 * Function for processing the event queue | |
301 * --------------------------------------- | |
302 */ | |
303 static int ProcessEvents (Display *d, Queue queue, int until_idle) | |
304 { | |
305 XEvent event; /* as it says */ | |
306 | |
307 /* | |
308 * Read whatever is available for reading. | |
309 */ | |
310 while (XPending (d)) | |
311 { | |
312 if (XCheckMaskEvent (d, SubstructureNotifyMask, &event)) | |
313 { | |
314 if ((event.type == CreateNotify) && until_idle) | |
315 { | |
316 AddToQueue (queue, event.xcreatewindow.window); | |
317 } | |
318 } | |
319 else | |
320 { | |
321 XNextEvent (d, &event); | |
322 } | |
323 | |
324 | |
325 /* | |
326 * Reset the counter if and only if the event is a KeyPress | |
327 * event *and* was not generated by XSendEvent (). | |
328 */ | |
329 if ( event.type == KeyPress && !event.xany.send_event ) | |
330 { | |
331 if (!until_idle) /* We've become un-idle */ | |
332 return 1; | |
333 SetTrigger (time_limit); | |
334 } | |
335 } | |
336 | |
337 | |
338 /* | |
339 * Check the window queue for entries that are older than | |
340 * CREATION_DELAY seconds. | |
341 */ | |
342 ProcessQueue (queue, d, (time_t) CREATION_DELAY); | |
343 return 0; | |
344 } | |
345 | |
346 | |
347 /* | |
348 * Function for monitoring pointer movements | |
349 * ----------------------------------------- | |
350 */ | |
351 static int QueryPointer (Display *d, int until_idle) | |
352 { | |
353 Window dummy_w; /* as it says */ | |
354 Int dummy_c; /* as it says */ | |
355 Unsigned mask; /* modifier mask */ | |
356 Int root_x; /* as it says */ | |
357 Int root_y; /* as it says */ | |
358 Int i; /* loop counter */ | |
359 static Window root; /* root window the pointer is on */ | |
360 static Screen* screen; /* screen the pointer is on */ | |
361 static Unsigned prev_mask = 0; /* as it says */ | |
362 static Int prev_root_x = -1; /* as it says */ | |
363 static Int prev_root_y = -1; /* as it says */ | |
364 static Boolean first_call = TRUE; /* as it says */ | |
365 | |
366 | |
367 /* | |
368 * Have a guess... | |
369 */ | |
370 if (first_call) | |
371 { | |
372 first_call = FALSE; | |
373 root = DefaultRootWindow (d); | |
374 screen = ScreenOfDisplay (d, DefaultScreen (d)); | |
375 } | |
376 | |
377 | |
378 /* | |
379 * Find out whether the pointer has moved. Using XQueryPointer for this | |
380 * is gross, but it also is the only way never to mess up propagation | |
381 * of pointer events. | |
382 * | |
383 * Remark : Unlike XNextEvent(), XPending () doesn't notice if the | |
384 * connection to the server is lost. For this reason, earlier | |
385 * versions of xautolock periodically called XNoOp (). But | |
386 * why not let XQueryPointer () do the job for us, since | |
387 * we now call that periodically anyway? | |
388 */ | |
389 if (!XQueryPointer (d, root, &root, &dummy_w, &root_x, &root_y, | |
390 &dummy_c, &dummy_c, &mask)) | |
391 { | |
392 /* | |
393 * Pointer has moved to another screen, so let's find out which one. | |
394 */ | |
395 for (i = -1; ++i < ScreenCount (d); ) | |
396 { | |
397 if (root == RootWindow (d, i)) | |
398 { | |
399 screen = ScreenOfDisplay (d, i); | |
400 break; | |
401 } | |
402 } | |
403 } | |
404 | |
405 if ( root_x != prev_root_x | |
406 || root_y != prev_root_y | |
407 || mask != prev_mask | |
408 ) | |
409 { | |
410 prev_root_x = root_x; | |
411 prev_root_y = root_y; | |
412 prev_mask = mask; | |
413 SetTrigger (time_limit); | |
414 if (!until_idle) | |
415 return 1; | |
416 } | |
417 | |
418 return 0; | |
419 | |
420 } | |
421 | |
422 /* | |
423 * Function for deciding whether to lock | |
424 * ------------------------------------- | |
425 */ | |
426 static int EvaluateCounter (Display *d) | |
427 { | |
428 time_t now = 0; /* as it says */ | |
429 | |
430 /* | |
431 * Now trigger the notifier if required. | |
432 */ | |
433 time (&now); | |
434 | |
435 /* | |
436 * Finally fire up the locker if time has come. | |
437 */ | |
438 if (now >= trigger) | |
439 { | |
440 SetTrigger (time_limit); | |
441 return TRUE; | |
442 } | |
443 | |
444 return FALSE; | |
445 } | |
446 | |
447 /* | |
448 * Function for selecting events on a tree of windows | |
449 * -------------------------------------------------- | |
450 */ | |
451 static Void SelectEvents (Display *d, Window window, Boolean substructure_only) | |
452 { | |
453 Window root; /* root window of this window */ | |
454 Window parent; /* parent of this window */ | |
455 Window* children; /* children of this window */ | |
456 Unsigned nof_children = 0; /* number of children */ | |
457 Unsigned i; /* loop counter */ | |
458 XWindowAttributes attribs; /* attributes of the window */ | |
459 | |
460 | |
461 /* | |
462 * Start by querying the server about parent and child windows. | |
463 */ | |
464 if (!XQueryTree (d, window, &root, &parent, &children, &nof_children)) | |
465 { | |
466 return; | |
467 } | |
468 | |
469 | |
470 /* | |
471 * Build the appropriate event mask. The basic idea is that we don't | |
472 * want to interfere with the normal event propagation mechanism if | |
473 * we don't have to. | |
474 */ | |
475 if (substructure_only) | |
476 { | |
477 XSelectInput (d, window, SubstructureNotifyMask); | |
478 } | |
479 else | |
480 { | |
481 if (parent == None) /* the *real* rootwindow */ | |
482 { | |
483 attribs.all_event_masks = | |
484 attribs.do_not_propagate_mask = KeyPressMask; | |
485 } | |
486 else if (XGetWindowAttributes (d, window, &attribs) == 0) | |
487 { | |
488 return; | |
489 } | |
490 | |
491 XSelectInput (d, window, SubstructureNotifyMask | |
492 | ( ( attribs.all_event_masks | |
493 | attribs.do_not_propagate_mask) | |
494 & KeyPressMask)); | |
495 } | |
496 | |
497 | |
498 /* | |
499 * Now do the same thing for all children. | |
500 */ | |
501 for (i = 0; i < nof_children; ++i) | |
502 { | |
503 SelectEvents (d, children[i], substructure_only); | |
504 } | |
505 | |
506 if (nof_children) XFree ((Char*) children); | |
507 } | |
508 | |
509 | |
510 int catchFalseAlarms( Display *d, XErrorEvent *x ) | |
511 { | |
512 return 0; | |
513 } | |
514 | |
515 Queue windowQueue; | |
516 Window hiddenWin; /* hidden window */ | |
517 | |
518 void initAutoLock() | |
519 { | |
520 Display* d; /* display pointer */ | |
521 Window r; /* root window */ | |
522 Int s; /* screen index */ | |
523 XSetWindowAttributes attribs; /* for dummy window */ | |
524 int (*oldHandler)(Display *, XErrorEvent *); | |
525 | |
526 d = GDK_DISPLAY(); | |
527 | |
528 oldHandler = XSetErrorHandler( catchFalseAlarms ); | |
529 XSync (d, 0); | |
530 | |
531 windowQueue = NewQueue (); | |
532 | |
533 for (s = -1; ++s < ScreenCount (d); ) | |
534 { | |
535 AddToQueue (windowQueue, r = RootWindowOfScreen (ScreenOfDisplay (d, s))); | |
536 SelectEvents (d, r, True); | |
537 } | |
538 | |
539 /* | |
540 * Get ourselves a dummy window in order to allow display and/or | |
541 * session managers etc. to use XKillClient() on us (e.g. xdm when | |
542 * not using XDMCP). | |
543 * | |
544 * I'm not sure whether the window needs to be mapped for xdm, but | |
545 * the default set up Sun uses for OpenWindows and olwm definitely | |
546 * requires it to be mapped. | |
547 */ | |
548 attribs.override_redirect = True; | |
549 hiddenWin = XCreateWindow (d, DefaultRootWindow (d), -100, -100, 1, 1, 0, | |
550 CopyFromParent, InputOnly, CopyFromParent, CWOverrideRedirect, | |
551 &attribs); | |
552 | |
553 XMapWindow (d, hiddenWin ); | |
554 | |
555 XSetErrorHandler( oldHandler ); | |
556 } | |
557 | |
558 /* I don't think this should be needed, but leaving the code here | |
559 in case I change my mind. */ | |
560 /* | |
561 void cleanupAutoLock() | |
562 { | |
563 int (*oldHandler)(Display *, XErrorEvent *); | |
564 oldHandler = XSetErrorHandler( catchFalseAlarms ); | |
565 | |
566 FreeQueue( windowQueue ); | |
567 XDestroyWindow( GDK_DISPLAY(), hiddenWin ); | |
568 XSetErrorHandler( oldHandler ); | |
569 } | |
570 */ | |
571 | |
572 /* | |
573 * Main function | |
574 * ------------- | |
575 */ | |
576 void waitIdle( int timeout, int until_idle ) | |
577 { | |
578 Display* d; /* display pointer */ | |
579 int (*oldHandler)(Display *, XErrorEvent *); | |
580 time_t now, prev; | |
581 | |
582 time_limit = timeout; | |
583 | |
584 d = GDK_DISPLAY(); | |
585 | |
586 oldHandler = XSetErrorHandler( catchFalseAlarms ); | |
587 | |
588 SetTrigger (time_limit); | |
589 | |
590 time(&prev); | |
591 | |
592 /* | |
593 * Main event loop. | |
594 */ | |
595 while ( 1 ) | |
596 { | |
597 if (ProcessEvents (d, windowQueue, until_idle)) | |
598 break; | |
599 if (QueryPointer (d, until_idle)) | |
600 break; | |
601 | |
602 if (until_idle) { | |
603 time(&now); | |
604 | |
605 if ((now > prev && now - prev > TIME_CHANGE_LIMIT) || | |
606 (prev > now && prev - now > TIME_CHANGE_LIMIT+1)) | |
607 { | |
608 /* the time has changed in one large jump. This could be because the | |
609 date was changed, or the machine was suspended. We'll just | |
610 reset the triger. */ | |
611 SetTrigger (time_limit); | |
612 } | |
613 | |
614 prev = now; | |
615 | |
616 if ( EvaluateCounter (d) ) | |
617 break; | |
618 } | |
619 | |
620 /* | |
621 * It seems that, on some operating systems (VMS to name just one), | |
622 * sleep () can be vastly inaccurate: sometimes 60 calls to sleep (1) | |
623 * add up to only 30 seconds or even less of sleeping. Therefore, | |
624 * as of patchlevel 9 we no longer rely on it for keeping track of | |
625 * time. The only reason why we still call it, is to make xautolock | |
626 * (which after all uses a busy-form-of-waiting algorithm), less | |
627 * processor hungry. | |
628 */ | |
629 sleep (1); | |
630 } | |
631 | |
632 XSetErrorHandler( oldHandler ); | |
633 | 83 |
634 } | 84 } |
635 | |
636 void idle_main(pid_t gaimpid) { | |
637 initAutoLock(); | |
638 while (1) { | |
639 waitIdle(IDLE_REPORT_TIME, 1); | |
640 kill(gaimpid, SIGALRM); | |
641 sleep(1); /* Just to be safe */ | |
642 waitIdle(1, 0); | |
643 kill(gaimpid, SIGALRM); | |
644 } | |
645 } | |
646 | |
647 | |
648 #endif |