ftp://ftp.swin.edu.au/slackware/slackware-9.1/source/xap/xscreensaver/xscreensaver...
[xscreensaver] / hacks / screenhack.c
index 2dfd9781856d302045f56d5fc894b2deccd9c6f2..79a58cde9792e2d0c5fdcf29403742d11c69e1cc 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992, 1995, 1997, 1998, 2001, 2002
+/* xscreensaver, Copyright (c) 1992, 1995, 1997, 1998, 2001, 2002, 2003
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
 #include "version.h"
 #include "vroot.h"
 
+#ifndef _XSCREENSAVER_VROOT_H_
+# error Error!  You have an old version of vroot.h!  Check -I args.
+#endif /* _XSCREENSAVER_VROOT_H_ */
+
 #ifndef isupper
 # define isupper(c)  ((c) >= 'A' && (c) <= 'Z')
 #endif
@@ -338,6 +342,36 @@ visual_warning (Screen *screen, Window window, Visual *visual, Colormap cmap,
 }
 
 
+static void
+fix_fds (void)
+{
+  /* Bad Things Happen if stdin, stdout, and stderr have been closed
+     (as by the `sh incantation "attraction >&- 2>&-").  When you do
+     that, the X connection gets allocated to one of these fds, and
+     then some random library writes to stderr, and random bits get
+     stuffed down the X pipe, causing "Xlib: sequence lost" errors.
+     So, we cause the first three file descriptors to be open to
+     /dev/null if they aren't open to something else already.  This
+     must be done before any other files are opened (or the closing
+     of that other file will again free up one of the "magic" first
+     three FDs.)
+
+     We do this by opening /dev/null three times, and then closing
+     those fds, *unless* any of them got allocated as #0, #1, or #2,
+     in which case we leave them open.  Gag.
+
+     Really, this crap is technically required of *every* X program,
+     if you want it to be robust in the face of "2>&-".
+   */
+  int fd0 = open ("/dev/null", O_RDWR);
+  int fd1 = open ("/dev/null", O_RDWR);
+  int fd2 = open ("/dev/null", O_RDWR);
+  if (fd0 > 2) close (fd0);
+  if (fd1 > 2) close (fd1);
+  if (fd2 > 2) close (fd2);
+}
+
+
 int
 main (int argc, char **argv)
 {
@@ -353,6 +387,8 @@ main (int argc, char **argv)
   Boolean dont_clear /*, dont_map */;
   char version[255];
 
+  fix_fds();
+
 #ifdef XLOCKMORE
   pre_merge_options ();
 #endif
@@ -495,6 +531,7 @@ main (int argc, char **argv)
       XGetWindowAttributes (dpy, window, &xgwa);
       cmap = xgwa.colormap;
       visual = xgwa.visual;
+      screen = xgwa.screen;
       visual_warning (screen, window, visual, cmap, True);
 
       /* Select KeyPress events on the external window.
@@ -514,7 +551,7 @@ main (int argc, char **argv)
   else if (root_p)
     {
       XWindowAttributes xgwa;
-      window = RootWindowOfScreen (XtScreen (toplevel));
+      window = VirtualRootWindowOfScreen (XtScreen (toplevel));
       XtDestroyWidget (toplevel);
       XGetWindowAttributes (dpy, window, &xgwa);
       cmap = xgwa.colormap;
@@ -543,7 +580,7 @@ main (int argc, char **argv)
          unsigned int bg, bd;
          Widget new;
 
-         cmap = XCreateColormap (dpy, RootWindowOfScreen(screen),
+         cmap = XCreateColormap (dpy, VirtualRootWindowOfScreen(screen),
                                  visual, AllocNone);
          bg = get_pixel_resource ("background", "Background", dpy, cmap);
          bd = get_pixel_resource ("borderColor", "Foreground", dpy, cmap);
@@ -559,7 +596,7 @@ main (int argc, char **argv)
                                    XtNbackground, (Pixel) bg,
                                    XtNborderColor, (Pixel) bd,
                                    XtNinput, True,  /* for WM_HINTS */
-                                   0);
+                                   NULL);
          XtDestroyWidget (toplevel);
          toplevel = new;
          XtRealizeWidget (toplevel);
@@ -570,7 +607,7 @@ main (int argc, char **argv)
          XtVaSetValues (toplevel,
                          XtNmappedWhenManaged, False,
                          XtNinput, True,  /* for WM_HINTS */
-                         0);
+                         NULL);
          XtRealizeWidget (toplevel);
          window = XtWindow (toplevel);
 
@@ -590,7 +627,7 @@ main (int argc, char **argv)
 /*
       if (dont_map)
        {
-         XtVaSetValues (toplevel, XtNmappedWhenManaged, False, 0);
+         XtVaSetValues (toplevel, XtNmappedWhenManaged, False, NULL);
          XtRealizeWidget (toplevel);
        }
       else
@@ -599,7 +636,7 @@ main (int argc, char **argv)
          XtPopup (toplevel, XtGrabNone);
        }
 
-      XtVaSetValues(toplevel, XtNtitle, version, 0);
+      XtVaSetValues(toplevel, XtNtitle, version, NULL);
 
       /* For screenhack_handle_events(): select KeyPress, and
          announce that we accept WM_DELETE_WINDOW. */