X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=driver%2Fremote.c;h=e05c93e4d0ad478455d866d189dc79765e1449b8;hp=26c855584f81d7f70e7893f53b84025f8adc8d22;hb=72c1f4c1dc6ab07fe121a327ff1c30bf51ef74c1;hpb=c596d1306f5f92f7eab76224d3b049980a14adcb diff --git a/driver/remote.c b/driver/remote.c index 26c85558..e05c93e4 100644 --- a/driver/remote.c +++ b/driver/remote.c @@ -41,8 +41,8 @@ ERROR! you must not include vroot.h in this file extern char *progname; extern Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_RESPONSE; -extern Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_TIME; -extern Atom XA_VROOT, XA_SELECT, XA_DEMO; +extern Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_STATUS, XA_EXIT; +extern Atom XA_VROOT, XA_SELECT, XA_DEMO, XA_BLANK, XA_LOCK; static XErrorHandler old_handler = 0; @@ -99,6 +99,7 @@ find_screensaver_window (Display *dpy, char **version) */ XSync (dpy, False); if (old_handler) abort(); + got_badwindow = False; old_handler = XSetErrorHandler (BadWindow_ehandler); status = XGetWindowProperty (dpy, kids[i], XA_SCREENSAVER_VERSION, @@ -110,7 +111,10 @@ find_screensaver_window (Display *dpy, char **version) old_handler = 0; if (got_badwindow) - status = BadWindow; + { + status = BadWindow; + got_badwindow = False; + } if (status == Success && type != None) { @@ -119,8 +123,6 @@ find_screensaver_window (Display *dpy, char **version) return kids[i]; } } - fprintf (stderr, "%s: no screensaver is running on display %s\n", progname, - DisplayString (dpy)); return 0; } @@ -137,13 +139,21 @@ send_xscreensaver_command (Display *dpy, Atom command, long arg, *window_ret = window; if (!window) - return -1; + { + if (command == XA_EXIT) + return 1; + + /* Don't print this if xscreensaver is already dead. */ + fprintf (stderr, "%s: no screensaver is running on display %s\n", + progname, DisplayString (dpy)); + return -1; + } /* Select for property change events, so that we can read the response. */ XGetWindowAttributes (dpy, window, &xgwa); XSelectInput (dpy, window, xgwa.your_event_mask | PropertyChangeMask); - if (command == XA_SCREENSAVER_TIME || + if (command == XA_SCREENSAVER_STATUS || command == XA_SCREENSAVER_VERSION) { XClassHint hint; @@ -165,7 +175,7 @@ send_xscreensaver_command (Display *dpy, Atom command, long arg, fprintf (stdout, "%s %s", hint.res_class, v); - if (command != XA_SCREENSAVER_TIME) + if (command != XA_SCREENSAVER_STATUS) { fprintf (stdout, "\n"); } @@ -174,38 +184,83 @@ send_xscreensaver_command (Display *dpy, Atom command, long arg, Atom type; int format; unsigned long nitems, bytesafter; - unsigned char *data = 0; - Bool active_p = False; + CARD32 *data = 0; - if (XGetWindowProperty (dpy, window, XA_VROOT, - 0, 0, False, XA_WINDOW, + if (XGetWindowProperty (dpy, + RootWindow (dpy, 0), + XA_SCREENSAVER_STATUS, + 0, 999, False, XA_INTEGER, &type, &format, &nitems, &bytesafter, - &data) + (unsigned char **) &data) == Success - && type != None) - active_p = True; - - if (data) free (data); - data = 0; - - if (XGetWindowProperty (dpy, window, - XA_SCREENSAVER_TIME, - 0, 1, False, XA_INTEGER, - &type, &format, &nitems, &bytesafter, - &data) - == Success - && type == XA_INTEGER + && type && data) { - CARD32 time32 = *((CARD32 *)data); - time_t tt = (time_t) time32; - - if (active_p) - fprintf (stdout, ": screen blanked since "); - else + Atom blanked; + time_t tt; + char *s; + + if (type != XA_INTEGER || nitems < 3) + { + STATUS_LOSE: + if (data) free (data); + fprintf (stdout, "\n"); + fflush (stdout); + fprintf (stderr, "%s: bad status format on root window.\n", + progname); + return -1; + } + + blanked = (Atom) data[0]; + tt = (time_t) data[1]; + + if (tt <= (time_t) 666000000L) /* early 1991 */ + goto STATUS_LOSE; + + if (blanked == XA_BLANK) + fputs (": screen blanked since ", stdout); + else if (blanked == XA_LOCK) + fputs (": screen locked since ", stdout); + else if (blanked == 0) /* suggestions for a better way to phrase this are welcome. */ - fprintf (stdout, ": screen non-blanked since "); - fprintf (stdout, "%s", ctime(&tt)); + fputs (": screen non-blanked since ", stdout); + else + /* `blanked' has an unknown value - fail. */ + goto STATUS_LOSE; + + s = ctime(&tt); + if (s[strlen(s)-1] == '\n') + s[strlen(s)-1] = 0; + fputs (s, stdout); + + { + int nhacks = nitems - 2; + Bool any = False; + int i; + for (i = 0; i < nhacks; i++) + if (data[i + 2] > 0) + { + any = True; + break; + } + + if (any && nhacks == 1) + fprintf (stdout, " (hack #%d)\n", data[2]); + else if (any) + { + fprintf (stdout, " (hacks: "); + for (i = 0; i < nhacks; i++) + { + fprintf (stdout, "#%d", data[2 + i]); + if (i != nhacks-1) + fputs (", ", stdout); + } + fputs (")\n", stdout); + } + else + fputs ("\n", stdout); + } + if (data) free (data); } else @@ -213,9 +268,8 @@ send_xscreensaver_command (Display *dpy, Atom command, long arg, if (data) free (data); fprintf (stdout, "\n"); fflush (stdout); - fprintf (stderr, "%s: no time on window 0x%x (%s %s).\n", - progname, (unsigned int) window, - hint.res_class, (v ? v : "???")); + fprintf (stderr, "%s: no saver status on root window.\n", + progname); return -1; } } @@ -261,7 +315,8 @@ send_xscreensaver_command (Display *dpy, Atom command, long arg, static int -xscreensaver_command_response (Display *dpy, Window window, Bool verbose_p) +xscreensaver_command_response (Display *dpy, Window window, + Bool verbose_p, Bool exiting_p) { int fd = ConnectionNumber (dpy); int timeout = 10; @@ -318,10 +373,13 @@ xscreensaver_command_response (Display *dpy, Window window, Bool verbose_p) if (got_badwindow) { - fprintf (stdout, - "%s: xscreensaver window has been deleted.\n", + if (exiting_p) + return 0; + + fprintf (stderr, + "%s: xscreensaver window unexpectedly deleted.\n", progname); - return 0; + return -1; } if (st2 == Success && type != None) @@ -366,10 +424,12 @@ xscreensaver_command (Display *dpy, Atom command, long arg, Bool verbose_p) Window w = 0; int status = send_xscreensaver_command (dpy, command, arg, &w); if (status == 0) - status = xscreensaver_command_response (dpy, w, verbose_p); + status = xscreensaver_command_response (dpy, w, verbose_p, + (command == XA_EXIT)); + fflush (stdout); fflush (stderr); - return status; + return (status < 0 ? status : 0); }