X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=driver%2Ftimers.c;h=bb950d8133ab2e5c7fe1367c2ca44d90ec1a0a0a;hb=ccbc9f87eb59497b23bd0424ee1ed20ad7c7db54;hp=b8c3e91ede3b1153d20e925661ebe4024539668b;hpb=258170f6204e23da06f272ffda1f4504b6ae2eaf;p=xscreensaver diff --git a/driver/timers.c b/driver/timers.c index b8c3e91e..bb950d81 100644 --- a/driver/timers.c +++ b/driver/timers.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1991-1993 Jamie Zawinski +/* xscreensaver, Copyright (c) 1991-1995 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -9,18 +9,32 @@ * implied warranty. */ +/* #define DEBUG_TIMERS */ + #include #include #include #include #include -#ifdef HAVE_XIDLE +#ifdef HAVE_XIDLE_EXTENSION #include -#endif +#endif /* HAVE_XIDLE_EXTENSION */ + +#ifdef HAVE_SAVER_EXTENSION +#include +extern int saver_ext_event_number; +extern Window server_saver_window; +#endif /* HAVE_SAVER_EXTENSION */ #include "xscreensaver.h" +#if __STDC__ +# define P(x)x +#else +#define P(x)() +#endif + extern XtAppContext app; Time cycle; @@ -28,14 +42,15 @@ Time timeout; Time pointer_timeout; Time notice_events_timeout; -extern Bool use_xidle; +extern Bool use_xidle_extension; +extern Bool use_saver_extension; extern Bool dbox_up_p; extern Bool locked_p; extern Window screensaver_window; -extern Bool handle_clientmessage P((/*XEvent *, Bool*/)); +extern Bool handle_clientmessage P((XEvent *, Bool)); -static time_t last_activity_time; /* for non-XIdle mode */ +static time_t last_activity_time; /* for when we have no server extensions */ static XtIntervalId timer_id = 0; static XtIntervalId check_pointer_timer_id = 0; XtIntervalId cycle_id = 0; @@ -66,9 +81,13 @@ idle_timer (junk1, junk2) static void +#if __STDC__ +notice_events (Window window, Bool top_p) +#else notice_events (window, top_p) Window window; Bool top_p; +#endif { XWindowAttributes attrs; unsigned long events; @@ -97,7 +116,8 @@ notice_events (window, top_p) if (top_p && verbose_p && (events & KeyPressMask)) { /* Only mention one window per tree (hack hack). */ - printf ("%s: selected KeyPress on 0x%X\n", progname, window); + printf ("%s: selected KeyPress on 0x%lX\n", progname, + (unsigned long) window); top_p = False; } @@ -121,6 +141,7 @@ BadWindow_ehandler (dpy, error) may have been destroyed <30 seconds after it was created. */ if (error->error_code == BadWindow || + error->error_code == BadMatch || error->error_code == BadDrawable) return 0; XmuPrintDefaultErrorMessage (dpy, error, stderr); @@ -130,7 +151,7 @@ BadWindow_ehandler (dpy, error) void notice_events_timer (closure, timer) XtPointer closure; - void *timer; + XtIntervalId *timer; { Window window = (Window) closure; int (*old_handler) (); @@ -163,7 +184,13 @@ cycle_timer (junk1, junk2) kill_screenhack (); spawn_screenhack (False); } - cycle_id = XtAppAddTimeOut (app, how_long, (XtTimerCallbackProc)cycle_timer, 0); + cycle_id = XtAppAddTimeOut (app, how_long, cycle_timer, 0); + +#ifdef DEBUG_TIMERS + if (verbose_p) + printf ("%s: starting cycle_timer (%ld, %ld)\n", + progname, how_long, cycle_id); +#endif } @@ -181,22 +208,31 @@ activate_lock_timer (junk1, junk2) /* Call this when user activity (or "simulated" activity) has been noticed. */ static void -reset_timers () +reset_timers P((void)) { + if (use_saver_extension) + return; + #ifdef DEBUG_TIMERS if (verbose_p) - printf ("%s: restarting idle_timer (%d, %d)\n", + printf ("%s: restarting idle_timer (%ld, %ld)\n", progname, timeout, timer_id); #endif XtRemoveTimeOut (timer_id); - timer_id = XtAppAddTimeOut (app, timeout, (XtTimerCallbackProc)idle_timer, 0); + timer_id = XtAppAddTimeOut (app, timeout, idle_timer, 0); if (cycle_id) abort (); +#ifdef DEBUG_TIMERS + if (verbose_p) + printf ("%s: starting idle_timer (%ld, %ld)\n", + progname, timeout, timer_id); +#endif + last_activity_time = time ((time_t *) 0); } -/* When we aren't using XIdle, this timer is used to periodically wake up - and poll the mouse position, which is possibly more reliable than +/* When we aren't using a server extension, this timer is used to periodically + wake up and poll the mouse position, which is possibly more reliable than selecting motion events on every window. */ static void @@ -212,12 +248,11 @@ check_pointer_timer (closure, this_timer) int root_x, root_y, x, y; unsigned int mask; XtIntervalId *timerP = (XtIntervalId *) closure; -#ifdef HAVE_XIDLE - if (use_xidle) + + if (use_xidle_extension || use_saver_extension) abort (); -#endif - *timerP = XtAppAddTimeOut (app, pointer_timeout, (XtTimerCallbackProc)check_pointer_timer, + *timerP = XtAppAddTimeOut (app, pointer_timeout, check_pointer_timer, closure); XQueryPointer (dpy, screensaver_window, &root, &child, @@ -251,10 +286,18 @@ sleep_until_idle (until_idle_p) if (until_idle_p) { - timer_id = XtAppAddTimeOut (app, timeout, (XtTimerCallbackProc)idle_timer, 0); -#ifdef HAVE_XIDLE - if (! use_xidle) + if (!use_saver_extension) + { + /* Wake up periodically to ask the server if we are idle. */ + timer_id = XtAppAddTimeOut (app, timeout, idle_timer, 0); +#ifdef DEBUG_TIMERS + if (verbose_p) + printf ("%s: starting idle_timer (%ld, %ld)\n", + progname, timeout, timer_id); #endif + } + + if (!use_xidle_extension && !use_saver_extension) /* start polling the mouse position */ check_pointer_timer (&check_pointer_timer_id, 0); } @@ -268,8 +311,8 @@ sleep_until_idle (until_idle_p) if (until_idle_p) { Time idle; -#ifdef HAVE_XIDLE - if (use_xidle) +#ifdef HAVE_XIDLE_EXTENSION + if (use_xidle_extension) { if (! XGetIdleTime (dpy, &idle)) { @@ -279,14 +322,33 @@ sleep_until_idle (until_idle_p) } } else -#endif /* HAVE_XIDLE */ - idle = 1000 * (last_activity_time - time ((time_t *) 0)); +#endif /* HAVE_XIDLE_EXTENSION */ +#ifdef HAVE_SAVER_EXTENSION + if (use_saver_extension) + { + /* We don't need to do anything in this case - the synthetic + event isn't necessary, as we get sent specific events + to wake us up. */ + idle = 0; + } + else +#endif /* HAVE_SAVER_EXTENSION */ + { + idle = 1000 * (last_activity_time - time ((time_t *) 0)); + } if (idle >= timeout) goto DONE; - else - timer_id = XtAppAddTimeOut (app, timeout - idle, - (XtTimerCallbackProc)idle_timer, 0); + else if (!use_saver_extension) + { + timer_id = XtAppAddTimeOut (app, timeout - idle, + idle_timer, 0); +#ifdef DEBUG_TIMERS + if (verbose_p) + printf ("%s: starting idle_timer (%ld, %ld)\n", + progname, timeout - idle, timer_id); +#endif /* DEBUG_TIMERS */ + } } break; @@ -296,11 +358,18 @@ sleep_until_idle (until_idle_p) break; case CreateNotify: -#ifdef HAVE_XIDLE - if (! use_xidle) -#endif - XtAppAddTimeOut (app, notice_events_timeout, (XtTimerCallbackProc)notice_events_timer, - (XtPointer) event.xcreatewindow.window); + if (!use_xidle_extension && !use_saver_extension) + { + XtAppAddTimeOut (app, notice_events_timeout, notice_events_timer, + (XtPointer) event.xcreatewindow.window); +#ifdef DEBUG_TIMERS + if (verbose_p) + printf ("%s: starting notice_events_timer for 0x%X (%lu)\n", + progname, + (unsigned int) event.xcreatewindow.window, + notice_events_timeout); +#endif /* DEBUG_TIMERS */ + } break; case KeyPress: @@ -316,7 +385,7 @@ sleep_until_idle (until_idle_p) printf ("%s: MotionNotify at %s\n", progname, timestring ()); else if (event.xany.type == KeyPress) printf ("%s: KeyPress seen on 0x%X at %s\n", progname, - event.xkey.window, timestring ()); + (unsigned int) event.xkey.window, timestring ()); } #endif @@ -328,7 +397,59 @@ sleep_until_idle (until_idle_p) break; default: - XtDispatchEvent (&event); + +#ifdef HAVE_SAVER_EXTENSION + if (event.type == saver_ext_event_number) + { + XScreenSaverNotifyEvent *sevent = + (XScreenSaverNotifyEvent *) &event; + if (sevent->state == ScreenSaverOn) + { +# ifdef DEBUG_TIMERS + if (verbose_p) + printf ("%s: ScreenSaverOn event received at %s\n", + progname, timestring ()); +# endif /* DEBUG_TIMERS */ + + /* Get the "real" server window out of the way as soon + as possible. */ + if (server_saver_window && + window_exists_p (dpy, server_saver_window)) + XUnmapWindow (dpy, server_saver_window); + + if (sevent->kind != ScreenSaverExternal) + { +# ifdef DEBUG_TIMERS + fprintf (stderr, + "%s: ScreenSaverOn event wasn't of type External!\n", + progname); +# endif /* DEBUG_TIMERS */ + } + + if (until_idle_p) + goto DONE; + } + else if (sevent->state == ScreenSaverOff) + { +# ifdef DEBUG_TIMERS + if (verbose_p) + printf ("%s: ScreenSaverOff event received at %s\n", + progname, timestring ()); +# endif /* DEBUG_TIMERS */ + if (!until_idle_p) + goto DONE; + } +# ifdef DEBUG_TIMERS + else if (verbose_p) + printf ("%s: unknown ScreenSaver event received at %s\n", + progname, timestring ()); +# endif /* DEBUG_TIMERS */ + } + else + +#endif /* HAVE_SAVER_EXTENSION */ + + XtDispatchEvent (&event); } } DONE: