X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=driver%2Fwindows.c;h=2d975475f0ece5a0a7cde66fd4e1943f9c80b256;hb=2a991a811de4c7b22f812682b267b616a809fd9a;hp=b91ee2a0b0c7f0366bdc52a9bbb4a63f5d6614c4;hpb=c6b273ef7292ba10943694df1656b05203d7b62f;p=xscreensaver diff --git a/driver/windows.c b/driver/windows.c index b91ee2a0..2d975475 100644 --- a/driver/windows.c +++ b/driver/windows.c @@ -1,5 +1,5 @@ /* windows.c --- turning the screen black; dealing with visuals, virtual roots. - * xscreensaver, Copyright (c) 1991-1998 Jamie Zawinski + * xscreensaver, Copyright (c) 1991-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 @@ -17,9 +17,6 @@ #ifdef VMS # include /* for getpid() */ # include "vms-gtod.h" /* for gettimeofday() */ -# if !defined(HAVE_UNAME) && (__VMS_VER >= 70000000) -# define HAVE_UNAME 1 -# endif /* !HAVE_UNAME */ #endif /* VMS */ # ifdef HAVE_UNAME @@ -62,6 +59,15 @@ #include "visual.h" #include "fade.h" + +#ifdef HAVE_VT_LOCKSWITCH +# include +# include +# include + static void lock_vt (saver_info *si, Bool lock_p); +#endif /* HAVE_VT_LOCKSWITCH */ + + extern int kill (pid_t, int); /* signal() is in sys/signal.h... */ Atom XA_VROOT, XA_XSETROOT_ID; @@ -93,9 +99,9 @@ grab_kbd(saver_info *si, Window w) if (status == GrabSuccess) si->keyboard_grab_window = w; - if (p->debug_p) - fprintf(stderr, "%s: XGrabKeyboard(... 0x%x ...) ==> %s\n", - progname, (unsigned long) w, + if (p->verbose_p) + fprintf(stderr, "%s: grabbing keyboard on 0x%x... %s.\n", + blurb(), (unsigned long) w, (status == GrabSuccess ? "GrabSuccess" : status == AlreadyGrabbed ? "AlreadyGrabbed" : status == GrabInvalidTime ? "GrabInvalidTime" : @@ -136,10 +142,9 @@ grab_mouse (saver_info *si, Window w, Cursor cursor) if (status == GrabSuccess) si->mouse_grab_window = w; - if (p->debug_p) - fprintf(stderr, "%s: XGrabPointer(... 0x%x, 0x%x ...) ==> %s\n", - progname, (unsigned long) w, (unsigned long) cursor, - grab_string(status)); + if (p->verbose_p) + fprintf(stderr, "%s: grabbing mouse on 0x%x... %s.\n", + blurb(), (unsigned long) w, grab_string(status)); return status; } @@ -149,8 +154,8 @@ ungrab_kbd(saver_info *si) { saver_preferences *p = &si->prefs; XUngrabKeyboard(si->dpy, CurrentTime); - if (p->debug_p) - fprintf(stderr, "%s: XUngrabKeyboard (was 0x%x)\n", progname, + if (p->verbose_p) + fprintf(stderr, "%s: ungrabbing keyboard (was 0x%x).\n", blurb(), (unsigned long) si->keyboard_grab_window); si->keyboard_grab_window = 0; } @@ -161,8 +166,8 @@ ungrab_mouse(saver_info *si) { saver_preferences *p = &si->prefs; XUngrabPointer(si->dpy, CurrentTime); - if (p->debug_p) - fprintf(stderr, "%s: XUngrabPointer (was 0x%x)\n", progname, + if (p->verbose_p) + fprintf(stderr, "%s: ungrabbing mouse (was 0x%x).\n", blurb(), (unsigned long) si->mouse_grab_window); si->mouse_grab_window = 0; } @@ -181,7 +186,7 @@ grab_keyboard_and_mouse (saver_info *si, Window window, Cursor cursor) status = grab_kbd (si, window); if (status != GrabSuccess) fprintf (stderr, "%s: couldn't grab keyboard! (%s)\n", - progname, grab_string(status)); + blurb(), grab_string(status)); } status = grab_mouse (si, window, cursor); @@ -191,7 +196,7 @@ grab_keyboard_and_mouse (saver_info *si, Window window, Cursor cursor) status = grab_mouse (si, window, cursor); if (status != GrabSuccess) fprintf (stderr, "%s: couldn't grab pointer! (%s)\n", - progname, grab_string(status)); + blurb(), grab_string(status)); } } @@ -244,7 +249,7 @@ ensure_no_screensaver_running (Display *dpy, Screen *screen) fprintf (stderr, "%s: already running on display %s (window 0x%x)\n from process %s.\n", - progname, DisplayString (dpy), (int) kids [i], id); + blurb(), DisplayString (dpy), (int) kids [i], id); status = True; } } @@ -269,7 +274,7 @@ store_vroot_property (Display *dpy, Window win, Window value) #if 0 if (p->verbose_p) fprintf (stderr, - "%s: storing XA_VROOT = 0x%x (%s) = 0x%x (%s)\n", progname, + "%s: storing XA_VROOT = 0x%x (%s) = 0x%x (%s)\n", blurb(), win, (win == screensaver_window ? "ScreenSaver" : (win == real_vroot ? "VRoot" : @@ -288,7 +293,7 @@ remove_vroot_property (Display *dpy, Window win) { #if 0 if (p->verbose_p) - fprintf (stderr, "%s: removing XA_VROOT from 0x%x (%s)\n", progname, win, + fprintf (stderr, "%s: removing XA_VROOT from 0x%x (%s)\n", blurb(), win, (win == screensaver_window ? "ScreenSaver" : (win == real_vroot ? "VRoot" : (win == real_vroot_value ? "Vroot_value" : "???")))); @@ -327,14 +332,14 @@ kill_xsetroot_data (Display *dpy, Window window, Bool verbose_p) nitems == 1 && bytesafter == 0) { if (verbose_p) - printf ("%s: destroying xsetroot data (0x%lX).\n", - progname, *dataP); + fprintf (stderr, "%s: destroying xsetroot data (0x%lX).\n", + blurb(), *dataP); XKillClient (dpy, *dataP); } else fprintf (stderr, "%s: deleted unrecognised _XSETROOT_ID property: \n\ %lu, %lu; type: %lu, format: %d, nitems: %lu, bytesafter %ld\n", - progname, (unsigned long) dataP, (dataP ? *dataP : 0), type, + blurb(), (unsigned long) dataP, (dataP ? *dataP : 0), type, format, nitems, bytesafter); } } @@ -380,7 +385,7 @@ save_real_vroot (saver_screen_info *ssi) if (*vrootP == ssi->screensaver_window) abort (); fprintf (stderr, "%s: more than one virtual root window found (0x%x and 0x%x).\n", - progname, (int) ssi->real_vroot, (int) kids [i]); + blurb(), (int) ssi->real_vroot, (int) kids [i]); exit (1); } ssi->real_vroot = kids [i]; @@ -404,8 +409,9 @@ restore_real_vroot_2 (saver_screen_info *ssi) saver_info *si = ssi->global; saver_preferences *p = &si->prefs; if (p->verbose_p && ssi->real_vroot) - printf ("%s: restoring __SWM_VROOT property on the real vroot (0x%lx).\n", - progname, (unsigned long) ssi->real_vroot); + fprintf (stderr, + "%s: restoring __SWM_VROOT property on the real vroot (0x%lx).\n", + blurb(), (unsigned long) ssi->real_vroot); remove_vroot_property (si->dpy, ssi->screensaver_window); if (ssi->real_vroot) { @@ -530,7 +536,7 @@ restore_real_vroot_handler (int sig) signal (sig, SIG_DFL); if (restore_real_vroot_1 (si)) fprintf (real_stderr, "\n%s: %s intercepted, vroot restored.\n", - progname, signal_name(sig)); + blurb(), signal_name(sig)); kill (getpid (), sig); } @@ -544,9 +550,9 @@ catch_signal (saver_info *si, int sig, Bool on_p) if (((long) signal (sig, restore_real_vroot_handler)) == -1L) { char buf [255]; - sprintf (buf, "%s: couldn't catch %s", progname, signal_name(sig)); + sprintf (buf, "%s: couldn't catch %s", blurb(), signal_name(sig)); perror (buf); - saver_exit (si, 1); + saver_exit (si, 1, 0); } } } @@ -555,8 +561,8 @@ static void handle_signals (saver_info *si, Bool on_p) { #if 0 - if (on_p) printf ("handling signals\n"); - else printf ("unhandling signals\n"); + if (on_p) fprintf (stderr, "handling signals\n"); + else fprintf (stderr, "unhandling signals\n"); #endif catch_signal (si, SIGHUP, on_p); @@ -588,10 +594,11 @@ handle_signals (saver_info *si, Bool on_p) } void -saver_exit (saver_info *si, int status) +saver_exit (saver_info *si, int status, const char *dump_core_reason) { saver_preferences *p = &si->prefs; static Bool exiting = False; + Bool bugp; Bool vrs; if (exiting) @@ -603,9 +610,9 @@ saver_exit (saver_info *si, int status) emergency_kill_subproc (si); if (vrs && (p->verbose_p || status != 0)) - fprintf (real_stderr, "%s: vroot restored, exiting.\n", progname); + fprintf (real_stderr, "%s: vroot restored, exiting.\n", blurb()); else if (p->verbose_p) - fprintf (real_stderr, "%s: no vroot to restore; exiting.\n", progname); + fprintf (real_stderr, "%s: no vroot to restore; exiting.\n", blurb()); fflush(real_stdout); @@ -614,9 +621,38 @@ saver_exit (saver_info *si, int status) else if (status == 1) status = -1; #endif - if (si->prefs.debug_p) + bugp = !!dump_core_reason; + + if (si->prefs.debug_p && !dump_core_reason) + dump_core_reason = "because of -debug"; + + if (dump_core_reason) { - fprintf(real_stderr, "%s: dumping core (because of -debug)\n", progname); + /* Note that the Linux man page for setuid() says If uid is + different from the old effective uid, the process will be + forbidden from leaving core dumps. + */ + char cwd[4096]; /* should really be PATH_MAX, but who cares. */ + cwd[0] = 0; + fprintf(real_stderr, "%s: dumping core (%s)\n", blurb(), + dump_core_reason); + + if (bugp) + fprintf(real_stderr, + "%s: see http://www.jwz.org/xscreensaver/bugs.html\n" + "\t\tfor bug reporting information.\n\n", + blurb()); + +# if defined(HAVE_GETCWD) + if (!getcwd (cwd, sizeof(cwd))) +# elif defined(HAVE_GETWD) + if (!getwd (cwd)) +# endif + strcpy(cwd, "unknown."); + + fprintf (real_stderr, "%s: current directory is %s\n", blurb(), cwd); + describe_uids (si, real_stderr); + /* Do this to drop a core file, so that we can get a stack trace. */ abort(); } @@ -645,7 +681,7 @@ initialize_screensaver_window_1 (saver_screen_info *ssi) { saver_info *si = ssi->global; saver_preferences *p = &si->prefs; - Bool install_cmap_p = ssi->install_cmap_p; + Bool install_cmap_p = (ssi->install_cmap_p || p->install_cmap_p); /* This resets the screensaver window as fully as possible, since there's no way of knowing what some random client may have done to us in the @@ -717,16 +753,19 @@ initialize_screensaver_window_1 (saver_screen_info *ssi) ; else if (ssi->current_visual == DefaultVisualOfScreen (ssi->screen)) { - fprintf (stderr, "%s: using default visual ", progname); - describe_visual (stderr, ssi->screen, ssi->current_visual); + fprintf (stderr, "%s: using default visual ", blurb()); + describe_visual (stderr, ssi->screen, ssi->current_visual, + install_cmap_p); } else { - fprintf (stderr, "%s: using visual: ", progname); - describe_visual (stderr, ssi->screen, ssi->current_visual); - fprintf (stderr, "%s: default visual: ", progname); + fprintf (stderr, "%s: using visual: ", blurb()); + describe_visual (stderr, ssi->screen, ssi->current_visual, + install_cmap_p); + fprintf (stderr, "%s: default visual: ", blurb()); describe_visual (stderr, ssi->screen, - DefaultVisualOfScreen (ssi->screen)); + DefaultVisualOfScreen (ssi->screen), + ssi->install_cmap_p); } printed_visual_info = True; @@ -806,7 +845,7 @@ initialize_screensaver_window_1 (saver_screen_info *ssi) store_activate_time(si, True); if (p->verbose_p) fprintf (stderr, "%s: saver window is 0x%lx.\n", - progname, (unsigned long) ssi->screensaver_window); + blurb(), (unsigned long) ssi->screensaver_window); } #ifdef HAVE_MIT_SAVER_EXTENSION @@ -892,9 +931,8 @@ raise_window (saver_info *si, initialize_screensaver_window (si); reset_watchdog_timer (si, True); - if (p->fade_p && !inhibit_fade && !si->demo_mode_p) + if (p->fade_p && si->fading_possible_p && !inhibit_fade && !si->demo_mode_p) { - int grabbed = -1; Window *current_windows = (Window *) calloc(sizeof(Window), si->nscreens); Colormap *current_maps = (Colormap *) @@ -913,49 +951,33 @@ raise_window (saver_info *si, ssi->black_pixel); } - if (p->verbose_p) fprintf (stderr, "%s: fading... ", progname); + if (p->verbose_p) fprintf (stderr, "%s: fading...\n", blurb()); XGrabServer (si->dpy); /* ############ DANGER! */ /* Clear the stderr layer on each screen. - Grab the mouse on the first screen on which the mouse is grabbable - (if there are multiple heads, I think you might only be able to - grab the mouse on the screen that currently has the mouse? Anyway, - we only grab the mouse once, and don't try again after the grab - has succeeded.) We grab the mouse on the root window of the screen, - not on the screensaver window, since the screensaver window is not - yet mapped. */ - for (i = 0; i < si->nscreens; i++) - { - saver_screen_info *ssi = &si->screens[i]; - - /* grab and blacken mouse on the root window (saver not mapped yet) - */ - if (grabbed != GrabSuccess) - { - Window root = RootWindowOfScreen(ssi->screen); - grabbed = grab_mouse (si, root, - (si->demo_mode_p ? 0 : ssi->cursor)); - } - - if (!dont_clear || ssi->stderr_overlay_window) - /* Do this before the fade, since the stderr cmap won't fade - even if we uninstall it (beats me...) */ - clear_stderr (ssi); - } + if (!dont_clear) + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->stderr_overlay_window) + /* Do this before the fade, since the stderr cmap won't fade + even if we uninstall it (beats me...) */ + clear_stderr (ssi); + } /* Note! The server is grabbed, and this will take several seconds to complete! */ fade_screens (si->dpy, current_maps, current_windows, - p->fade_seconds, p->fade_ticks, True, !dont_clear); + p->fade_seconds/1000, p->fade_ticks, True, !dont_clear); free(current_maps); free(current_windows); current_maps = 0; current_windows = 0; - if (p->verbose_p) fprintf (stderr, "fading done.\n"); + if (p->verbose_p) fprintf (stderr, "%s: fading done.\n", blurb()); #ifdef HAVE_MIT_SAVER_EXTENSION for (i = 0; i < si->nscreens; i++) @@ -967,10 +989,6 @@ raise_window (saver_info *si, } #endif /* HAVE_MIT_SAVER_EXTENSION */ - /* If we had successfully grabbed the mouse, let it go now. */ - if (grabbed == GrabSuccess) - ungrab_mouse (si); - XUngrabServer (si->dpy); XSync (si->dpy, False); /* ###### (danger over) */ } @@ -1004,6 +1022,16 @@ void blank_screen (saver_info *si) { int i; + + /* Note: we do our grabs on the root window, not on the screensaver window. + If we grabbed on the saver window, then the demo mode and lock dialog + boxes wouldn't get any events. + */ + grab_keyboard_and_mouse (si, + /*si->screens[0].screensaver_window,*/ + RootWindowOfScreen(si->screens[0].screen), + (si->demo_mode_p ? 0 : si->screens[0].cursor)); + for (i = 0; i < si->nscreens; i++) { saver_screen_info *ssi = &si->screens[i]; @@ -1016,15 +1044,6 @@ blank_screen (saver_info *si) store_activate_time (si, si->screen_blanked_p); raise_window (si, False, False, False); - /* Note: we do our grabs on the root window, not on the screensaver window. - If we grabbed on the saver window, then the demo mode and lock dialog - boxes wouldn't get any events. - */ - grab_keyboard_and_mouse (si, - /*si->screens[0].screensaver_window,*/ - RootWindowOfScreen(si->screens[0].screen), - (si->demo_mode_p ? 0 : si->screens[0].cursor)); - #ifdef HAVE_XHPDISABLERESET if (si->locked_p && !hp_locked_p) { @@ -1033,6 +1052,11 @@ blank_screen (saver_info *si) } #endif +#ifdef HAVE_VT_LOCKSWITCH + if (si->locked_p) + lock_vt (si, True); /* turn off C-Alt-Fn */ +#endif + si->screen_blanked_p = True; } @@ -1042,12 +1066,13 @@ unblank_screen (saver_info *si) saver_preferences *p = &si->prefs; int i; + monitor_power_on (si); + store_activate_time (si, True); reset_watchdog_timer (si, False); - if (p->unfade_p && !si->demo_mode_p) + if (p->unfade_p && si->fading_possible_p && !si->demo_mode_p) { - int grabbed = -1; Window *current_windows = (Window *) calloc(sizeof(Window), si->nscreens); @@ -1061,7 +1086,7 @@ unblank_screen (saver_info *si) ssi->black_pixel); } - if (p->verbose_p) fprintf (stderr, "%s: unfading... ", progname); + if (p->verbose_p) fprintf (stderr, "%s: unfading...\n", blurb()); XSync (si->dpy, False); @@ -1069,18 +1094,10 @@ unblank_screen (saver_info *si) XSync (si->dpy, False); /* Clear the stderr layer on each screen. - Grab the mouse on the first screen on which the mouse is grabbable - (if there are multiple heads, I think you might only be able to - grab the mouse on the screen that currently has the mouse? Anyway, - we only grab the mouse once, and don't try again after the grab - has succeeded.) */ for (i = 0; i < si->nscreens; i++) { saver_screen_info *ssi = &si->screens[i]; - if (grabbed != GrabSuccess) - grabbed = grab_mouse (si, RootWindowOfScreen (ssi->screen), - 0); clear_stderr (ssi); } @@ -1089,17 +1106,13 @@ unblank_screen (saver_info *si) fade_screens (si->dpy, 0, current_windows, - p->fade_seconds, p->fade_ticks, + p->fade_seconds/1000, p->fade_ticks, False, False); free(current_windows); current_windows = 0; - if (p->verbose_p) fprintf (stderr, "unfading done.\n"); - - /* If we had successfully grabbed the mouse, let it go now. */ - if (grabbed == GrabSuccess) - ungrab_mouse (si); + if (p->verbose_p) fprintf (stderr, "%s: unfading done.\n", blurb()); } else { @@ -1159,6 +1172,10 @@ unblank_screen (saver_info *si) } #endif +#ifdef HAVE_VT_LOCKSWITCH + lock_vt (si, False); /* turn C-Alt-Fn back on */ +#endif + /* Unmap the windows a second time, dammit -- just to avoid a race with the screen-grabbing hacks. (I'm not sure if this is really necessary; I'm stabbing in the dark now.) @@ -1235,16 +1252,12 @@ select_visual (saver_screen_info *ssi, const char *visual_name) if (p->verbose_p) { + fprintf (stderr, "%s: switching to visual ", blurb()); + describe_visual (stderr, ssi->screen, new_v, install_cmap_p); #if 0 - fprintf (stderr, "%s: switching visuals\tfrom: ", progname); - describe_visual (stderr, ssi->screen, ssi->current_visual); - fprintf (stderr, "\t\t\t\tto: "); - describe_visual (stderr, ssi->screen, new_v); - fprintf (stderr, "\t\t\t\t install cmap: %s\n", - (install_cmap_p ? "yes" : "no")); -#else - fprintf (stderr, "%s: switching to visual ", progname); - describe_visual (stderr, ssi->screen, new_v); + fprintf (stderr, "%s: from ", blurb()); + describe_visual (stderr, ssi->screen, ssi->current_visual, + was_installed_p); #endif } @@ -1255,6 +1268,13 @@ select_visual (saver_screen_info *ssi, const char *visual_name) ssi->screensaver_window = 0; initialize_screensaver_window_1 (ssi); + + /* stderr_overlay_window is a child of screensaver_window, so we need + to destroy that as well (actually, we just need to invalidate and + drop our pointers to it, but this will destroy it, which is ok so + long as it happens before old_w itself is destroyed.) */ + reset_stderr (ssi); + raise_window (si, True, True, False); store_vroot_property (si->dpy, ssi->screensaver_window, ssi->screensaver_window); @@ -1302,7 +1322,7 @@ select_visual (saver_screen_info *ssi, const char *visual_name) if (p->verbose_p) fprintf (stderr, "%s: destroyed old saver window 0x%lx.\n", - progname, (unsigned long) old_w); + blurb(), (unsigned long) old_w); if (old_c && old_c != DefaultColormapOfScreen (ssi->screen) && @@ -1312,3 +1332,56 @@ select_visual (saver_screen_info *ssi, const char *visual_name) return got_it; } + + +/* VT locking */ + +#ifdef HAVE_VT_LOCKSWITCH +static void +lock_vt (saver_info *si, Bool lock_p) +{ + saver_preferences *p = &si->prefs; + static Bool locked_p = False; + const char *dev_console = "/dev/console"; + int fd; + + if (lock_p == locked_p) + return; + + if (lock_p && !p->lock_vt_p) + return; + + fd = open (dev_console, O_RDWR); + if (fd < 0) + { + char buf [255]; + sprintf (buf, "%s: couldn't %s VTs: %s", blurb(), + (lock_p ? "lock" : "unlock"), + dev_console); +#if 0 /* #### doesn't work yet, so don't bother complaining */ + perror (buf); +#endif + return; + } + + if (ioctl (fd, (lock_p ? VT_LOCKSWITCH : VT_UNLOCKSWITCH)) == 0) + { + locked_p = lock_p; + + if (p->verbose_p) + fprintf (stderr, "%s: %s VTs\n", blurb(), + (lock_p ? "locked" : "unlocked")); + } + else + { + char buf [255]; + sprintf (buf, "%s: couldn't %s VTs: ioctl", blurb(), + (lock_p ? "lock" : "unlock")); +#if 0 /* #### doesn't work yet, so don't bother complaining */ + perror (buf); +#endif + } + + close (fd); +} +#endif /* HAVE_VT_LOCKSWITCH */