+ return 0;
+}
+
+
+static XErrorHandler old_handler = 0;
+static Bool got_badwindow = False;
+static int
+BadWindow_ehandler (Display *dpy, XErrorEvent *error)
+{
+ /* When we notice a window being created, we spawn a timer that waits
+ 30 seconds or so, and then selects events on that window. This error
+ handler is used so that we can cope with the fact that the window
+ may have been destroyed <30 seconds after it was created.
+ */
+ if (error->error_code == BadWindow)
+ {
+ got_badwindow = True;
+ return 0;
+ }
+ else
+ {
+ fprintf (stderr, "%s: ", progname);
+ return (*old_handler) (dpy, error);
+ }
+}
+
+
+static int
+xscreensaver_command_response (Display *dpy, Window window)
+{
+ int fd = ConnectionNumber (dpy);
+ int timeout = 10;
+ int status;
+ fd_set fds;
+ struct timeval tv;
+
+ while (1)
+ {
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ memset(&tv, 0, sizeof(tv));
+ tv.tv_sec = timeout;
+ status = select (fd+1, &fds, 0, &fds, &tv);
+
+ if (status < 0)
+ {
+ char buf[1024];
+ sprintf (buf, "%s: waiting for reply", progname);
+ perror (buf);
+ return status;
+ }
+ else if (status == 0)
+ {
+ fprintf (stderr, "%s: no response to command.\n", progname);
+ return -1;
+ }
+ else
+ {
+ XEvent event;
+ XNextEvent (dpy, &event);
+ switch (event.xany.type) {
+ case PropertyNotify:
+ if (event.xproperty.state == PropertyNewValue &&
+ event.xproperty.atom == XA_SCREENSAVER_RESPONSE)
+ {
+ Status st2;
+ Atom type;
+ int format;
+ unsigned long nitems, bytesafter;
+ char *msg = 0;
+
+ old_handler = XSetErrorHandler (BadWindow_ehandler);
+ XSync (dpy, False);
+
+ st2 = XGetWindowProperty (dpy, window,
+ XA_SCREENSAVER_RESPONSE,
+ 0, 1024, True,
+ AnyPropertyType,
+ &type, &format, &nitems, &bytesafter,
+ (unsigned char **) &msg);
+
+ if (got_badwindow)
+ {
+ fprintf (stdout,
+ "%s: xscreensaver window has been deleted.\n",
+ progname);
+ return 0;
+ }
+
+ if (st2 == Success && type != None)
+ {
+ if (type != XA_STRING || format != 8)
+ {
+ fprintf (stderr,
+ "%s: unrecognized response property.\n",
+ progname);
+ if (msg) XFree (msg);
+ return -1;
+ }
+ else if (!msg || (msg[0] != '+' && msg[0] != '-'))
+ {
+ fprintf (stderr,
+ "%s: unrecognized response message.\n",
+ progname);
+ if (msg) XFree (msg);
+ return -1;
+ }
+ else
+ {
+ int ret = (msg[0] == '+' ? 0 : -1);
+ fprintf ((ret < 0 ? stderr : stdout),
+ "%s: %s\n",
+ progname,
+ msg+1);
+ XFree (msg);
+ return ret;
+ }
+ }
+ }
+ break;
+
+ default:
+ fprintf (stderr, "%s: got unexpected response event %d.\n",
+ progname, event.xany.type);
+ return -1;
+ break;
+ }
+ }
+ }