http://ftp.x.org/contrib/applications/xscreensaver-3.17.tar.gz
[xscreensaver] / driver / remote.c
index 31d4580cef1886604958892e6142226310eebcc1..26c855584f81d7f70e7893f53b84025f8adc8d22 100644 (file)
 #include <stdlib.h>
 #include <sys/time.h>
 #include <sys/types.h>
-#include <sys/select.h>
+
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif /* HAVE_SYS_SELECT_H */
 
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
@@ -47,11 +50,6 @@ 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;
@@ -60,6 +58,7 @@ BadWindow_ehandler (Display *dpy, XErrorEvent *error)
   else
     {
       fprintf (stderr, "%s: ", progname);
+      if (!old_handler) abort();
       return (*old_handler) (dpy, error);
     }
 }
@@ -90,14 +89,30 @@ find_screensaver_window (Display *dpy, char **version)
       int format;
       unsigned long nitems, bytesafter;
       char *v;
-
-      if (XGetWindowProperty (dpy, kids[i],
-                             XA_SCREENSAVER_VERSION,
-                             0, 200, False, XA_STRING,
-                             &type, &format, &nitems, &bytesafter,
-                             (unsigned char **) &v)
-         == Success
-         && type != None)
+      int status;
+
+      /* We're walking the list of root-level windows and trying to find
+         the one that has a particular property on it.  We need to trap
+         BadWindows errors while doing this, because it's possible that
+         some random window might get deleted in the meantime.  (That
+         window won't have been the one we're looking for.)
+       */
+      XSync (dpy, False);
+      if (old_handler) abort();
+      old_handler = XSetErrorHandler (BadWindow_ehandler);
+      status = XGetWindowProperty (dpy, kids[i],
+                                   XA_SCREENSAVER_VERSION,
+                                   0, 200, False, XA_STRING,
+                                   &type, &format, &nitems, &bytesafter,
+                                   (unsigned char **) &v);
+      XSync (dpy, False);
+      XSetErrorHandler (old_handler);
+      old_handler = 0;
+
+      if (got_badwindow)
+        status = BadWindow;
+
+      if (status == Success && type != None)
        {
          if (version)
            *version = v;
@@ -288,15 +303,18 @@ xscreensaver_command_response (Display *dpy, Window window, Bool verbose_p)
              unsigned long nitems, bytesafter;
              char *msg = 0;
 
-             old_handler = XSetErrorHandler (BadWindow_ehandler);
              XSync (dpy, False);
-
+              if (old_handler) abort();
+             old_handler = XSetErrorHandler (BadWindow_ehandler);
              st2 = XGetWindowProperty (dpy, window,
                                        XA_SCREENSAVER_RESPONSE,
                                        0, 1024, True,
                                        AnyPropertyType,
                                        &type, &format, &nitems, &bytesafter,
                                        (unsigned char **) &msg);
+             XSync (dpy, False);
+              XSetErrorHandler (old_handler);
+              old_handler = 0;
 
              if (got_badwindow)
                {
@@ -369,6 +387,8 @@ server_xscreensaver_version (Display *dpy,
 
   if (version_ret)
     *version_ret = 0;
+  if (user_ret)
+    *user_ret = 0;
   if (host_ret)
     *host_ret = 0;