+
+ /* 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;
+}
+
+
+static void
+store_activate_time (saver_info *si, Bool use_last_p)
+{
+ static time_t last_time = 0;
+ time_t now = ((use_last_p && last_time) ? last_time : time ((time_t) 0));
+ CARD32 now32 = (CARD32) now;
+ int i;
+ last_time = now;
+
+ for (i = 0; i < si->nscreens; i++)
+ {
+ saver_screen_info *ssi = &si->screens[i];
+ if (!ssi->screensaver_window) continue;
+ XChangeProperty (si->dpy, ssi->screensaver_window, XA_SCREENSAVER_TIME,
+ XA_INTEGER, 32, PropModeReplace,
+ (unsigned char *) &now32, 1);
+ }
+}
+
+
+Bool
+select_visual (saver_screen_info *ssi, const char *visual_name)
+{
+ 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)
+ {
+ 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;
+ }
+
+ got_it = !!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: from ", blurb());
+ describe_visual (stderr, ssi->screen, ssi->current_visual,
+ was_installed_p);
+#endif
+ }
+
+ reset_stderr (ssi);
+ ssi->current_visual = new_v;
+ ssi->current_depth = visual_depth(ssi->screen, new_v);
+ ssi->cmap = 0;
+ ssi->screensaver_window = 0;
+
+ initialize_screensaver_window_1 (ssi);
+ raise_window (si, True, True, False);
+ store_vroot_property (si->dpy,
+ ssi->screensaver_window, ssi->screensaver_window);
+ 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)
+ XFreeColormap (si->dpy, old_c);
+ }
+
+ return got_it;