X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fscreenhack.c;h=eb9d7185e0058dd0cd3e3e1c042d8a94f26d1fcb;hb=551b3de3f619c04c2dd1971ee9b3f02e270c28c9;hp=8462d4e792999b6431539f793ad4d5f4f8d399fb;hpb=f3e0240915ed9f9b3a61781f5c7002d587563fe0;p=xscreensaver diff --git a/hacks/screenhack.c b/hacks/screenhack.c index 8462d4e7..eb9d7185 100644 --- a/hacks/screenhack.c +++ b/hacks/screenhack.c @@ -1,5 +1,5 @@ -/* xscreensaver, Copyright (c) 1992, 1995, 1997 - * Jamie Zawinski +/* xscreensaver, Copyright (c) 1992, 1995, 1997, 1998 + * Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -37,6 +37,13 @@ #include #include #include +#include +#include + +#ifdef __sgi +# include /* for SgiUseSchemes() */ +#endif /* __sgi */ + #ifdef HAVE_XMU # ifndef VMS # include @@ -52,6 +59,7 @@ char *progname; XrmDatabase db; +XtAppContext app; Bool mono_p; static XrmOptionDescRec default_options [] = { @@ -61,15 +69,17 @@ static XrmOptionDescRec default_options [] = { { "-install", ".installColormap", XrmoptionNoArg, "True" }, { "-noinstall",".installColormap", XrmoptionNoArg, "False" }, { "-visual", ".visualID", XrmoptionSepArg, 0 }, + { "-window-id", ".windowID", XrmoptionSepArg, 0 }, { 0, 0, 0, 0 } }; static char *default_defaults[] = { - "*root: false", + ".root: false", "*geometry: 600x480", /* this should be .geometry, but nooooo... */ "*mono: false", "*installColormap: false", "*visualID: default", + "*windowID: ", 0 }; @@ -108,6 +118,23 @@ merge_options (void) def_defaults_size * sizeof(*defaults)); memcpy (merged_defaults + def_defaults_size, defaults, (defaults_size + 1) * sizeof(*defaults)); + + /* This totally sucks. Xt should behave like this by default. + If the string in `defaults' looks like ".foo", change that + to "Progclass.foo". + */ + { + char **s; + for (s = merged_defaults; *s; s++) + if (**s == '.') + { + const char *oldr = *s; + char *newr = (char *) malloc(strlen(oldr) + strlen(progclass) + 3); + strcpy (newr, progclass); + strcat (newr, oldr); + *s = newr; + } + } } @@ -143,17 +170,84 @@ extern void pre_merge_options (void); #endif +static Atom XA_WM_PROTOCOLS, XA_WM_DELETE_WINDOW; + +/* Dead-trivial event handling: exits if "q" or "ESC" are typed. + Exit if the WM_PROTOCOLS WM_DELETE_WINDOW ClientMessage is received. + */ +void +screenhack_handle_event (Display *dpy, XEvent *event) +{ + switch (event->xany.type) + { + case KeyPress: + { + KeySym keysym; + char c = 0; + XLookupString (&event->xkey, &c, 1, &keysym, 0); + if (c == 'q' || + c == 'Q' || + c == 3 || /* ^C */ + c == 27) /* ESC */ + exit (0); + else if (! (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)) + XBell (dpy, 0); /* beep for non-chord keys */ + } + break; + case ButtonPress: + XBell (dpy, 0); + break; + case ClientMessage: + { + if (event->xclient.message_type != XA_WM_PROTOCOLS) + { + char *s = XGetAtomName(dpy, event->xclient.message_type); + if (!s) s = "(null)"; + fprintf (stderr, "%s: unknown ClientMessage %s received!\n", + progname, s); + } + else if (event->xclient.data.l[0] != XA_WM_DELETE_WINDOW) + { + char *s1 = XGetAtomName(dpy, event->xclient.message_type); + char *s2 = XGetAtomName(dpy, event->xclient.data.l[0]); + if (!s1) s1 = "(null)"; + if (!s2) s2 = "(null)"; + fprintf (stderr, "%s: unknown ClientMessage %s[%s] received!\n", + progname, s1, s2); + } + else + { + exit (0); + } + } + break; + } +} + + +void +screenhack_handle_events (Display *dpy) +{ + while (XPending (dpy)) + { + XEvent event; + XNextEvent (dpy, &event); + screenhack_handle_event (dpy, &event); + } +} + + int main (int argc, char **argv) { - XtAppContext app; Widget toplevel; Display *dpy; Window window; Visual *visual; Colormap cmap; Bool root_p; + Window on_window = 0; XEvent event; Boolean dont_clear /*, dont_map */; char version[255]; @@ -162,6 +256,19 @@ main (int argc, char **argv) pre_merge_options (); #endif merge_options (); + +#ifdef __sgi + /* We have to do this on SGI to prevent the background color from being + overridden by the current desktop color scheme (we'd like our backgrounds + to be black, thanks.) This should be the same as setting the + "*useSchemes: none" resource, but it's not -- if that resource is + present in the `default_defaults' above, it doesn't work, though it + does work when passed as an -xrm arg on the command line. So screw it, + turn them off from C instead. + */ + SgiUseSchemes ("none"); +#endif /* __sgi */ + toplevel = XtAppInitialize (&app, progclass, merged_options, merged_options_size, &argc, argv, merged_defaults, 0, 0); @@ -170,12 +277,20 @@ main (int argc, char **argv) XtGetApplicationNameAndClass (dpy, &progname, &progclass); XSetErrorHandler (screenhack_ehandler); + XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False); + XA_WM_DELETE_WINDOW = XInternAtom (dpy, "WM_DELETE_WINDOW", False); + { char *v = (char *) strdup(strchr(screensaver_id, ' ')); - char *s = (char *) strchr(v, ','); - *s = 0; - sprintf (version, "%s: from the XScreenSaver%s distribution.", - progclass, v); + char *s1, *s2, *s3, *s4; + s1 = (char *) strchr(v, ' '); s1++; + s2 = (char *) strchr(s1, ' '); + s3 = (char *) strchr(v, '('); s3++; + s4 = (char *) strchr(s3, ')'); + *s2 = 0; + *s4 = 0; + sprintf (version, "%s: from the XScreenSaver %s distribution (%s.)", + progclass, s1, s3); free(v); } @@ -188,7 +303,7 @@ main (int argc, char **argv) Bool help_p = !strcmp(argv[1], "-help"); fprintf (stderr, "%s\n", version); for (s = progclass; *s; s++) fprintf(stderr, " "); - fprintf (stderr, " http://people.netscape.com/jwz/xscreensaver/\n\n"); + fprintf (stderr, " http://www.jwz.org/xscreensaver/\n\n"); if (!help_p) fprintf(stderr, "Unrecognised option: %s\n", argv[1]); @@ -219,7 +334,24 @@ main (int argc, char **argv) mono_p = True; root_p = get_boolean_resource ("root", "Boolean"); - if (root_p) + + { + char *s = get_string_resource ("windowID", "WindowID"); + if (s && *s) + on_window = get_integer_resource ("windowID", "WindowID"); + if (s) free (s); + } + + if (on_window) + { + XWindowAttributes xgwa; + window = (Window) on_window; + XtDestroyWidget (toplevel); + XGetWindowAttributes (dpy, window, &xgwa); + cmap = xgwa.colormap; + visual = xgwa.visual; + } + else if (root_p) { XWindowAttributes xgwa; window = RootWindowOfScreen (XtScreen (toplevel)); @@ -304,6 +436,18 @@ main (int argc, char **argv) } XtVaSetValues(toplevel, XtNtitle, version, 0); + + /* For screenhack_handle_events(): select KeyPress, and + announce that we accept WM_DELETE_WINDOW. */ + { + XWindowAttributes xgwa; + XGetWindowAttributes (dpy, window, &xgwa); + XSelectInput (dpy, window, + xgwa.your_event_mask | KeyPressMask | ButtonPressMask); + XChangeProperty (dpy, window, XA_WM_PROTOCOLS, XA_ATOM, 32, + PropModeReplace, + (unsigned char *) &XA_WM_DELETE_WINDOW, 1); + } } if (!dont_clear) @@ -314,7 +458,7 @@ main (int argc, char **argv) XClearWindow (dpy, window); } - if (!root_p) + if (!root_p && !on_window) /* wait for it to be mapped */ XIfEvent (dpy, &event, MapNotify_event_p, (XPointer) window);