+/* Called when the RANDR (Resize and Rotate) extension tells us that the
+ size of the screen has changed while the screen was blanked. If we
+ don't do this, then the screen saver will no longer fully fill the
+ screen, and some of the underlying desktop may be visible.
+ */
+void
+resize_screensaver_window (saver_info *si)
+{
+ saver_preferences *p = &si->prefs;
+ int i;
+
+ /* First update the size info in the saver_screen_info structs.
+ */
+
+# ifdef HAVE_XINERAMA
+ if (si->xinerama_p)
+ {
+ /* As of XFree86 4.3.0, the RANDR and XINERAMA extensions cannot coexist.
+ However, maybe they will someday, so I'm guessing that the right thing
+ to do in that case will be to re-query the Xinerama rectangles after
+ a RANDR size change is received: presumably, if the resolution of one
+ or more of the monitors has changed, then the Xinerama rectangle
+ corresponding to that monitor will also have been updated.
+ */
+ int nscreens;
+ XineramaScreenInfo *xsi = XineramaQueryScreens (si->dpy, &nscreens);
+ if (nscreens != si->nscreens) abort();
+ if (!xsi) abort();
+ for (i = 0; i < si->nscreens; i++)
+ {
+ saver_screen_info *ssi = &si->screens[i];
+ if (p->verbose_p &&
+ (ssi->x != xsi[i].x_org ||
+ ssi->y != xsi[i].y_org ||
+ ssi->width != xsi[i].width ||
+ ssi->height != xsi[i].height))
+ fprintf (stderr,
+ "%s: %d: resize xinerama from %dx%d+%d+%d to %dx%d+%d+%d\n",
+ blurb(), i,
+ ssi->width, ssi->height, ssi->x, ssi->y,
+ xsi[i].width, xsi[i].height, xsi[i].x_org, xsi[i].y_org);
+
+ ssi->x = xsi[i].x_org;
+ ssi->y = xsi[i].y_org;
+ ssi->width = xsi[i].width;
+ ssi->height = xsi[i].height;
+ }
+ XFree (xsi);
+ }
+ else
+# endif /* HAVE_XINERAMA */
+ {
+ /* Not Xinerama -- get the real sizes of the root windows. */
+ for (i = 0; i < si->nscreens; i++)
+ {
+ saver_screen_info *ssi = &si->screens[i];
+ XWindowAttributes xgwa;
+ XGetWindowAttributes (si->dpy, RootWindowOfScreen (ssi->screen),
+ &xgwa);
+
+ if (p->verbose_p &&
+ (ssi->x != xgwa.x ||
+ ssi->y != xgwa.y ||
+ ssi->width != xgwa.width ||
+ ssi->height != xgwa.height))
+ fprintf (stderr,
+ "%s: %d: resize screen from %dx%d+%d+%d to %dx%d+%d+%d\n",
+ blurb(), i,
+ ssi->width, ssi->height, ssi->x, ssi->y,
+ xgwa.width, xgwa.height, xgwa.x, xgwa.y);
+
+ ssi->x = xgwa.x;
+ ssi->y = xgwa.y;
+ ssi->width = xgwa.width;
+ ssi->height = xgwa.height;
+ }
+ }
+
+ /* Next, ensure that the screensaver windows are the right size, taking
+ into account both the new size of the screen in question's root window,
+ and any viewport within that.
+ */
+
+ for (i = 0; i < si->nscreens; i++)
+ {
+ saver_screen_info *ssi = &si->screens[i];
+ XWindowAttributes xgwa;
+ XWindowChanges changes;
+ int x, y, width, height;
+ unsigned int changesmask = CWX|CWY|CWWidth|CWHeight|CWBorderWidth;
+
+ XGetWindowAttributes (si->dpy, ssi->screensaver_window, &xgwa);
+ get_screen_viewport (ssi, &x, &y, &width, &height, -1, -1,
+ (p->verbose_p && !si->screen_blanked_p));
+ if (xgwa.x == x &&
+ xgwa.y == y &&
+ xgwa.width == width &&
+ xgwa.height == height)
+ continue; /* no change! */
+
+ changes.x = x;
+ changes.y = y;
+ changes.width = width;
+ changes.height = height;
+ changes.border_width = 0;
+
+ if (p->debug_p && !p->quad_p) changes.width = changes.width / 2;
+
+ if (p->verbose_p)
+ fprintf (stderr,
+ "%s: %d: resize 0x%lx from %dx%d+%d+%d to %dx%d+%d+%d\n",
+ blurb(), i, (unsigned long) ssi->screensaver_window,
+ xgwa.width, xgwa.height, xgwa.x, xgwa.y,
+ width, height, x, y);
+ if (! safe_XConfigureWindow (si->dpy, ssi->screensaver_window,
+ changesmask, &changes))
+ {
+ fprintf (stderr,
+ "%s: %d: someone horked our saver window (0x%lx)! Unable to resize it!\n",
+ blurb(), i, (unsigned long) ssi->screensaver_window);
+ }
+ }
+}
+
+