X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fscreenhack.c;h=728d18edabbb7b6b4ed25f0899faa8055b2a4a56;hp=7c11b35b04be6f5b9209b3ff63e806582a007498;hb=ffd8c0873576a9e3065696a624dce6b766b77062;hpb=8eb2873d7054e705c4e83f22d18c40946a9e2529 diff --git a/hacks/screenhack.c b/hacks/screenhack.c index 7c11b35b..728d18ed 100644 --- a/hacks/screenhack.c +++ b/hacks/screenhack.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1992, 1995, 1997, 1998, 2001 +/* xscreensaver, Copyright (c) 1992, 1995, 1997, 1998, 2001, 2002, 2003, 2004 * Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its @@ -57,6 +57,10 @@ #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 @@ -183,6 +187,9 @@ static Atom XA_WM_PROTOCOLS, XA_WM_DELETE_WINDOW; void screenhack_handle_event (Display *dpy, XEvent *event) { + if (XtAppPending (app) & (XtIMTimer|XtIMAlternateInput)) + XtAppProcessEvent (app, XtIMTimer|XtIMAlternateInput); + switch (event->xany.type) { case KeyPress: @@ -293,10 +300,10 @@ visual_warning (Screen *screen, Window window, Visual *visual, Colormap cmap, if (window == RootWindowOfScreen (screen)) strcpy (win, "root window"); else - sprintf (win, "window 0x%x", (unsigned long) window); + sprintf (win, "window 0x%lx", (unsigned long) window); if (window_p) - sprintf (why, "-window-id 0x%x", (unsigned long) window); + sprintf (why, "-window-id 0x%lx", (unsigned long) window); else strcpy (why, "-root"); @@ -315,7 +322,7 @@ visual_warning (Screen *screen, Window window, Visual *visual, Colormap cmap, { fprintf (stderr, "%s: ignoring `-visual %s' because of `%s'.\n", progname, visual_string, why); - fprintf (stderr, "%s: using %s's visual 0x%x.\n", + fprintf (stderr, "%s: using %s's visual 0x%lx.\n", progname, win, XVisualIDFromVisual (visual)); } free (visual_string); @@ -327,7 +334,7 @@ visual_warning (Screen *screen, Window window, Visual *visual, Colormap cmap, { fprintf (stderr, "%s: ignoring `-install' because of `%s'.\n", progname, why); - fprintf (stderr, "%s: using %s's colormap 0x%x.\n", + fprintf (stderr, "%s: using %s's colormap 0x%lx.\n", progname, win, (unsigned long) cmap); } @@ -338,6 +345,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 +390,8 @@ main (int argc, char **argv) Boolean dont_clear /*, dont_map */; char version[255]; + fix_fds(); + #ifdef XLOCKMORE pre_merge_options (); #endif @@ -495,12 +534,27 @@ 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 and resize events on the external window. + */ + xgwa.your_event_mask |= KeyPressMask | StructureNotifyMask; + XSelectInput (dpy, window, xgwa.your_event_mask); + + /* Select ButtonPress and ButtonRelease events on the external window, + if no other app has already selected them (only one app can select + ButtonPress at a time: BadAccess results.) + */ + if (! (xgwa.all_event_masks & (ButtonPressMask | ButtonReleaseMask))) + XSelectInput (dpy, window, + (xgwa.your_event_mask | + ButtonPressMask | ButtonReleaseMask)); } else if (root_p) { XWindowAttributes xgwa; - window = RootWindowOfScreen (XtScreen (toplevel)); + window = VirtualRootWindowOfScreen (XtScreen (toplevel)); XtDestroyWidget (toplevel); XGetWindowAttributes (dpy, window, &xgwa); cmap = xgwa.colormap; @@ -529,7 +583,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); @@ -545,7 +599,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); @@ -556,7 +610,7 @@ main (int argc, char **argv) XtVaSetValues (toplevel, XtNmappedWhenManaged, False, XtNinput, True, /* for WM_HINTS */ - 0); + NULL); XtRealizeWidget (toplevel); window = XtWindow (toplevel); @@ -576,7 +630,7 @@ main (int argc, char **argv) /* if (dont_map) { - XtVaSetValues (toplevel, XtNmappedWhenManaged, False, 0); + XtVaSetValues (toplevel, XtNmappedWhenManaged, False, NULL); XtRealizeWidget (toplevel); } else @@ -585,7 +639,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. */ @@ -593,7 +647,8 @@ main (int argc, char **argv) XWindowAttributes xgwa; XGetWindowAttributes (dpy, window, &xgwa); XSelectInput (dpy, window, - xgwa.your_event_mask | KeyPressMask | ButtonPressMask); + (xgwa.your_event_mask | KeyPressMask | + ButtonPressMask | ButtonReleaseMask)); XChangeProperty (dpy, window, XA_WM_PROTOCOLS, XA_ATOM, 32, PropModeReplace, (unsigned char *) &XA_WM_DELETE_WINDOW, 1);