/* windows.c --- turning the screen black; dealing with visuals, virtual roots.
- * xscreensaver, Copyright (c) 1991-1997 Jamie Zawinski <jwz@netscape.com>
+ * xscreensaver, Copyright (c) 1991-1998 Jamie Zawinski <jwz@netscape.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
extern int kill (pid_t, int); /* signal() is in sys/signal.h... */
Atom XA_VROOT, XA_XSETROOT_ID;
-Atom XA_SCREENSAVER_VERSION, XA_SCREENSAVER_ID;
+Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_ID;
Atom XA_SCREENSAVER_TIME;
Button1MotionMask | Button2MotionMask | Button3MotionMask | \
Button4MotionMask | Button5MotionMask | ButtonMotionMask)
-/* I don't really understand Sync vs Async, but these seem to work... */
-#define grab_kbd(dpy,win) \
- XGrabKeyboard ((dpy), (win), True, GrabModeSync, GrabModeAsync, CurrentTime)
-#define grab_mouse(dpy,win,cursor) \
- XGrabPointer ((dpy), (win), True, ALL_POINTER_EVENTS, \
- GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime)
+
+static int
+grab_kbd(saver_info *si, Window w)
+{
+ saver_preferences *p = &si->prefs;
+ int status = XGrabKeyboard (si->dpy, w, True,
+ /* I don't really understand Sync vs Async,
+ but these seem to work... */
+ GrabModeSync, GrabModeAsync,
+ CurrentTime);
+ if (status == GrabSuccess)
+ si->keyboard_grab_window = w;
+
+ if (p->debug_p)
+ fprintf(stderr, "%s: XGrabKeyboard(... 0x%x ...) ==> %s\n",
+ blurb(), (unsigned long) w,
+ (status == GrabSuccess ? "GrabSuccess" :
+ status == AlreadyGrabbed ? "AlreadyGrabbed" :
+ status == GrabInvalidTime ? "GrabInvalidTime" :
+ status == GrabNotViewable ? "GrabNotViewable" :
+ status == GrabFrozen ? "GrabFrozen" :
+ "???"));
+
+ return status;
+}
+
+static const char *
+grab_string(int status)
+{
+ switch (status)
+ {
+ case GrabSuccess: return "GrabSuccess"; break;
+ case AlreadyGrabbed: return "AlreadyGrabbed"; break;
+ case GrabInvalidTime: return "GrabInvalidTime"; break;
+ case GrabNotViewable: return "GrabNotViewable"; break;
+ case GrabFrozen: return "GrabFrozen"; break;
+ default:
+ {
+ static char foo[255];
+ sprintf(foo, "unknown status: %d", status);
+ return foo;
+ }
+ }
+}
+
+
+static int
+grab_mouse (saver_info *si, Window w, Cursor cursor)
+{
+ saver_preferences *p = &si->prefs;
+ int status = XGrabPointer (si->dpy, w, True, ALL_POINTER_EVENTS,
+ GrabModeAsync, GrabModeAsync, None,
+ cursor, CurrentTime);
+ if (status == GrabSuccess)
+ si->mouse_grab_window = w;
+
+ if (p->debug_p)
+ fprintf(stderr, "%s: XGrabPointer(... 0x%x, 0x%x ...) ==> %s\n",
+ blurb(), (unsigned long) w, (unsigned long) cursor,
+ grab_string(status));
+ return status;
+}
+
+
+static void
+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", blurb(),
+ (unsigned long) si->keyboard_grab_window);
+ si->keyboard_grab_window = 0;
+}
+
+
+static void
+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", blurb(),
+ (unsigned long) si->mouse_grab_window);
+ si->mouse_grab_window = 0;
+}
+
void
-grab_keyboard_and_mouse (Display *dpy, Window window, Cursor cursor)
+grab_keyboard_and_mouse (saver_info *si, Window window, Cursor cursor)
{
Status status;
- XSync (dpy, False);
+ XSync (si->dpy, False);
- status = grab_kbd (dpy, window);
+ status = grab_kbd (si, window);
if (status != GrabSuccess)
{ /* try again in a second */
sleep (1);
- status = grab_kbd (dpy, window);
+ status = grab_kbd (si, window);
if (status != GrabSuccess)
- fprintf (stderr, "%s: couldn't grab keyboard! (%d)\n",
- progname, status);
+ fprintf (stderr, "%s: couldn't grab keyboard! (%s)\n",
+ blurb(), grab_string(status));
}
- status = grab_mouse (dpy, window, cursor);
+
+ status = grab_mouse (si, window, cursor);
if (status != GrabSuccess)
{ /* try again in a second */
sleep (1);
- status = grab_mouse (dpy, window, cursor);
+ status = grab_mouse (si, window, cursor);
if (status != GrabSuccess)
- fprintf (stderr, "%s: couldn't grab pointer! (%d)\n",
- progname, status);
+ fprintf (stderr, "%s: couldn't grab pointer! (%s)\n",
+ blurb(), grab_string(status));
}
}
void
-ungrab_keyboard_and_mouse (Display *dpy)
+ungrab_keyboard_and_mouse (saver_info *si)
{
- XUngrabPointer (dpy, CurrentTime);
- XUngrabKeyboard (dpy, CurrentTime);
+ ungrab_mouse (si);
+ ungrab_kbd (si);
}
-void
+/* Prints an error message to stderr and returns True if there is another
+ xscreensaver running already. Silently returns False otherwise. */
+Bool
ensure_no_screensaver_running (Display *dpy, Screen *screen)
{
+ Bool status = 0;
int i;
Window root = RootWindowOfScreen (screen);
Window root2, parent, *kids;
fprintf (stderr,
"%s: already running on display %s (window 0x%x)\n from process %s.\n",
- progname, DisplayString (dpy), (int) kids [i], id);
- exit (1);
+ blurb(), DisplayString (dpy), (int) kids [i], id);
+ status = True;
}
}
if (kids) XFree ((char *) kids);
XSync (dpy, False);
XSetErrorHandler (old_handler);
+ return status;
}
#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" :
{
#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" : "???"))));
{
if (verbose_p)
printf ("%s: destroying xsetroot data (0x%lX).\n",
- progname, *dataP);
+ 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);
}
}
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];
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);
+ blurb(), (unsigned long) ssi->real_vroot);
remove_vroot_property (si->dpy, ssi->screensaver_window);
if (ssi->real_vroot)
{
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);
}
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);
}
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);
else if (status == 1) status = -1;
#endif
-#ifdef DEBUG
if (si->prefs.debug_p)
- /* Do this to drop a core file, so that we can get a stack trace. */
- abort();
-#endif
+ {
+ fprintf(real_stderr, "%s: dumping core (because of -debug)\n", blurb());
+ /* Do this to drop a core file, so that we can get a stack trace. */
+ abort();
+ }
exit (status);
}
{
saver_info *si = ssi->global;
saver_preferences *p = &si->prefs;
+ 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
if (ssi->cmap == DefaultColormapOfScreen (ssi->screen))
ssi->cmap = 0;
- if (p->install_cmap_p ||
- ssi->current_visual != DefaultVisualOfScreen (ssi->screen))
+ if (ssi->current_visual != DefaultVisualOfScreen (ssi->screen))
+ install_cmap_p = True;
+
+ if (install_cmap_p)
{
if (! ssi->cmap)
{
}
else
{
+ Colormap def_cmap = DefaultColormapOfScreen (ssi->screen);
if (ssi->cmap)
{
XFreeColors (si->dpy, ssi->cmap, &ssi->black_pixel, 1, 0);
- if (ssi->cmap != ssi->demo_cmap)
+ if (ssi->cmap != ssi->demo_cmap &&
+ ssi->cmap != def_cmap)
XFreeColormap (si->dpy, ssi->cmap);
}
- ssi->cmap = DefaultColormapOfScreen (ssi->screen);
+ ssi->cmap = def_cmap;
ssi->black_pixel = BlackPixelOfScreen (ssi->screen);
}
-#if 0
- if (cmap2)
- {
- XFreeColormap (si->dpy, cmap2);
- cmap2 = 0;
- }
-
- if (p->fade_p)
- {
- cmap2 = copy_colormap (si->screen, ssi->current_visual, ssi->cmap, 0);
- if (! cmap2)
- p->fade_p = p->unfade_p = 0;
- }
-#endif
-
attrmask = (CWOverrideRedirect | CWEventMask | CWBackingStore | CWColormap |
CWBackPixel | CWBackingPixel | CWBorderPixel);
attrs.override_redirect = True;
attrs.backing_pixel = ssi->black_pixel;
attrs.border_pixel = ssi->black_pixel;
-#ifdef DEBUG
if (p->debug_p) width = width / 2;
-#endif /* DEBUG */
if (!p->verbose_p || printed_visual_info)
;
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;
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
if (p->fade_p && !inhibit_fade && !si->demo_mode_p)
{
int grabbed = -1;
+ Window *current_windows = (Window *)
+ calloc(sizeof(Window), si->nscreens);
Colormap *current_maps = (Colormap *)
calloc(sizeof(Colormap), si->nscreens);
for (i = 0; i < si->nscreens; i++)
{
saver_screen_info *ssi = &si->screens[i];
+ current_windows[i] = ssi->screensaver_window;
current_maps[i] = (between_hacks_p
? ssi->cmap
: DefaultColormapOfScreen (ssi->screen));
+ /* Ensure that the default background of the window is really black,
+ not a pixmap or something. (This does not clear the window.) */
+ XSetWindowBackground (si->dpy, ssi->screensaver_window,
+ ssi->black_pixel);
}
- if (p->verbose_p) fprintf (stderr, "%s: fading... ", progname);
+ if (p->verbose_p) fprintf (stderr, "%s: fading... ", blurb());
- XGrabServer (si->dpy);
+ 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)
- grabbed = grab_mouse (si->dpy, ssi->screensaver_window,
- (si->demo_mode_p ? 0 : ssi->cursor));
+ {
+ 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
clear_stderr (ssi);
}
- fade_screens (si->dpy, current_maps, p->fade_seconds, p->fade_ticks,
- True);
+ /* 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);
+
+ free(current_maps);
+ free(current_windows);
+ current_maps = 0;
+ current_windows = 0;
if (p->verbose_p) fprintf (stderr, "fading done.\n");
+#ifdef HAVE_MIT_SAVER_EXTENSION
for (i = 0; i < si->nscreens; i++)
{
saver_screen_info *ssi = &si->screens[i];
- if (!dont_clear)
- XClearWindow (si->dpy, ssi->screensaver_window);
- XMapRaised (si->dpy, ssi->screensaver_window);
-
-#ifdef HAVE_MIT_SAVER_EXTENSION
if (ssi->server_mit_saver_window &&
window_exists_p (si->dpy, ssi->server_mit_saver_window))
XUnmapWindow (si->dpy, ssi->server_mit_saver_window);
-#endif /* HAVE_MIT_SAVER_EXTENSION */
-
- /* Once the saver window is up, restore the colormap.
- (The "black" pixels of the two colormaps are compatible.) */
- if (ssi->cmap)
- XInstallColormap (si->dpy, ssi->cmap);
}
+#endif /* HAVE_MIT_SAVER_EXTENSION */
+ /* If we had successfully grabbed the mouse, let it go now. */
if (grabbed == GrabSuccess)
- XUngrabPointer (si->dpy, CurrentTime);
+ ungrab_mouse (si);
+
XUngrabServer (si->dpy);
+ XSync (si->dpy, False); /* ###### (danger over) */
}
else
{
ssi->screensaver_window,
ssi->screensaver_window);
}
- store_activate_time (si, True);
+ store_activate_time (si, si->screen_blanked_p);
raise_window (si, False, False, False);
- /* #### */
- grab_keyboard_and_mouse (si->dpy, si->screens[0].screensaver_window,
+
+ /* 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)
{
unblank_screen (saver_info *si)
{
saver_preferences *p = &si->prefs;
- int i, j;
+ int i;
+
+ monitor_power_on (si);
store_activate_time (si, True);
reset_watchdog_timer (si, False);
if (p->unfade_p && !si->demo_mode_p)
{
int grabbed = -1;
- int extra_cmaps = 4;
- int ncmaps = si->nscreens * (extra_cmaps + 1);
- Colormap *cmaps = (Colormap *) calloc(sizeof(Colormap), ncmaps);
-
- if (p->verbose_p) fprintf (stderr, "%s: unfading... ", progname);
-
- /* Fake out SGI's multi-colormap hardware; see utils/fade.c
- for an explanation. */
- for (i = 0; i < ncmaps; i += (extra_cmaps + 1))
- for (j = 0; j < (extra_cmaps + 1); j++)
- {
- cmaps[i+j] = XCreateColormap (si->dpy,
- RootWindow (si->dpy, i),
- DefaultVisual(si->dpy, i),
- AllocAll);
- if (cmaps[i+j])
- {
- blacken_colormap (ScreenOfDisplay(si->dpy, i), cmaps[i+j]);
- XInstallColormap (si->dpy, cmaps[i+j]);
- }
- }
-
- XGrabServer (si->dpy);
+ Window *current_windows = (Window *)
+ calloc(sizeof(Window), si->nscreens);
+
+ for (i = 0; i < si->nscreens; i++)
+ {
+ saver_screen_info *ssi = &si->screens[i];
+ current_windows[i] = ssi->screensaver_window;
+ /* Ensure that the default background of the window is really black,
+ not a pixmap or something. (This does not clear the window.) */
+ XSetWindowBackground (si->dpy, ssi->screensaver_window,
+ ssi->black_pixel);
+ }
+
+ if (p->verbose_p) fprintf (stderr, "%s: unfading... ", blurb());
+
+
+ XSync (si->dpy, False);
+ XGrabServer (si->dpy); /* ############ DANGER! */
+ 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->dpy, RootWindowOfScreen (ssi->screen),
+ grabbed = grab_mouse (si, RootWindowOfScreen (ssi->screen),
0);
- XUnmapWindow (si->dpy, ssi->screensaver_window);
clear_stderr (ssi);
}
+
XUngrabServer (si->dpy);
+ XSync (si->dpy, False); /* ###### (danger over) */
+
- fade_screens (si->dpy, 0, p->fade_seconds, p->fade_ticks, False);
+ fade_screens (si->dpy, 0, current_windows,
+ p->fade_seconds, p->fade_ticks,
+ False, False);
- for (i = 0; i < ncmaps; i++)
- if (cmaps[i]) XFreeColormap (si->dpy, cmaps[i]);
- free (cmaps);
+ 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)
- XUngrabPointer (si->dpy, CurrentTime);
+ ungrab_mouse (si);
}
else
{
kill_xsetroot_data (si->dpy, ssi->screensaver_window, p->verbose_p);
}
- ungrab_keyboard_and_mouse (si->dpy);
+ store_activate_time(si, False); /* store unblank time */
+
+ ungrab_keyboard_and_mouse (si);
restore_real_vroot (si);
#ifdef HAVE_XHPDISABLERESET
}
#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.)
+ */
+ for (i = 0; i < si->nscreens; i++)
+ XUnmapWindow (si->dpy, si->screens[i].screensaver_window);
+
si->screen_blanked_p = False;
}
{
saver_info *si = ssi->global;
saver_preferences *p = &si->prefs;
+ Bool install_cmap_p = p->install_cmap_p;
+ Bool was_installed_p = (ssi->cmap != DefaultColormapOfScreen(ssi->screen));
Visual *new_v;
Bool got_it;
if (visual_name && *visual_name)
- new_v = get_visual (ssi->screen, visual_name, True, False);
+ {
+ if (!strcmp(visual_name, "default-i"))
+ {
+ visual_name = "default";
+ install_cmap_p = True;
+ }
+ else if (!strcmp(visual_name, "default-n"))
+ {
+ visual_name = "default";
+ install_cmap_p = False;
+ }
+ new_v = get_visual (ssi->screen, visual_name, True, False);
+ }
else
- new_v = ssi->default_visual;
+ {
+ new_v = ssi->default_visual;
+ }
got_it = !!new_v;
- if (new_v && ssi->current_visual != new_v)
+ if (new_v && new_v != DefaultVisualOfScreen(ssi->screen))
+ install_cmap_p = True;
+
+ ssi->install_cmap_p = install_cmap_p;
+
+ if (new_v &&
+ ((ssi->current_visual != new_v) ||
+ (install_cmap_p != was_installed_p)))
{
Colormap old_c = ssi->cmap;
Window old_w = ssi->screensaver_window;
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);
-#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
}
raise_window (si, True, True, False);
store_vroot_property (si->dpy,
ssi->screensaver_window, ssi->screensaver_window);
- store_activate_time (si, False);
+ store_activate_time (si, True);
+
+
+
+ /* Transfer the grabs from the old window to the new.
+ Actually I think none of this is necessary, since we always
+ hold our grabs on the root window, but I wrote this before
+ re-discovering that...
+ */
+
+
+ /* If we're destroying the window that holds our mouse grab,
+ transfer the grab to the new window. (Grab the server while
+ so doing, to avoid a race condition.)
+ */
+ if (old_w == si->mouse_grab_window)
+ {
+ XGrabServer (si->dpy); /* ############ DANGER! */
+ ungrab_mouse(si);
+ grab_mouse(si, ssi->screensaver_window,
+ (si->demo_mode_p ? 0 : ssi->cursor));
+ XUngrabServer (si->dpy);
+ XSync (si->dpy, False); /* ###### (danger over) */
+ }
+
+ /* If we're destroying the window that holds our keyboard grab,
+ transfer the grab to the new window. (Grab the server while
+ so doing, to avoid a race condition.)
+ */
+ if (old_w == si->keyboard_grab_window)
+ {
+ XGrabServer (si->dpy); /* ############ DANGER! */
+ ungrab_kbd(si);
+ grab_kbd(si, ssi->screensaver_window);
+ XUngrabServer (si->dpy);
+ XSync (si->dpy, False); /* ###### (danger over) */
+ }
+
+ /* Now we can destroy this window without horking our grabs. */
XDestroyWindow (si->dpy, old_w);
+
+ if (p->verbose_p)
+ fprintf (stderr, "%s: destroyed old saver window 0x%lx.\n",
+ blurb(), (unsigned long) old_w);
+
if (old_c &&
old_c != DefaultColormapOfScreen (ssi->screen) &&
old_c != ssi->demo_cmap)