-}
-
-
-
-/* Returns the area of the screen which the xscreensaver window should cover.
- Normally this is the whole screen, but if the X server's root window is
- actually larger than the monitor's displayable area, then we want to
- operate in the currently-visible portion of the desktop instead.
- */
-void
-get_screen_viewport (saver_screen_info *ssi,
- int *x_ret, int *y_ret,
- int *w_ret, int *h_ret,
- Bool verbose_p)
-{
- int w = WidthOfScreen (ssi->screen);
- int h = HeightOfScreen (ssi->screen);
-
-#ifdef HAVE_XF86VMODE
- saver_info *si = ssi->global;
- int screen_no = screen_number (ssi->screen);
- int op, event, error;
- int dot;
- XF86VidModeModeLine ml;
- int x, y;
-
- /* Check for Xinerama first, because the VidModeExtension is broken
- when Xinerama is present. Wheee!
- */
-
- if (!XQueryExtension (si->dpy, "XINERAMA", &op, &event, &error) &&
- XF86VidModeQueryExtension (si->dpy, &event, &error) &&
- XF86VidModeGetModeLine (si->dpy, screen_no, &dot, &ml) &&
- XF86VidModeGetViewPort (si->dpy, screen_no, &x, &y))
- {
- char msg[512];
- *x_ret = x;
- *y_ret = y;
- *w_ret = ml.hdisplay;
- *h_ret = ml.vdisplay;
-
- if (*x_ret == 0 && *y_ret == 0 && *w_ret == w && *h_ret == h)
- /* There is no viewport -- the screen does not scroll. */
- return;
-
-
- /* Apparently some versions of XFree86 return nonsense here!
- I've had reports of 1024x768 viewports at -1936862040, -1953705044.
- So, sanity-check the values and give up if they are out of range.
- */
- if (*x_ret < 0 || *x_ret >= w ||
- *y_ret < 0 || *y_ret >= h ||
- *w_ret <= 0 || *w_ret > w ||
- *h_ret <= 0 || *h_ret > h)
- {
- static int warned_once = 0;
- if (!warned_once)
- {
- fprintf (stderr, "\n"
- "%s: X SERVER BUG: %dx%d viewport at %d,%d is impossible.\n"
- "%s: The XVidMode server extension is returning nonsense.\n"
- "%s: Please report this bug to your X server vendor.\n\n",
- blurb(), *w_ret, *h_ret, *x_ret, *y_ret,
- blurb(), blurb());
- warned_once = 1;
- }
- *x_ret = 0;
- *y_ret = 0;
- *w_ret = w;
- *h_ret = h;
- return;
- }
-
-
- sprintf (msg, "%s: vp is %dx%d+%d+%d",
- blurb(), *w_ret, *h_ret, *x_ret, *y_ret);
-
-
- /* Apparently, though the server stores the X position in increments of
- 1 pixel, it will only make changes to the *display* in some other
- increment. With XF86_SVGA on a Thinkpad, the display only updates
- in multiples of 8 pixels when in 8-bit mode, and in multiples of 4
- pixels in 16-bit mode. I don't know what it does in 24- and 32-bit
- mode, because I don't have enough video memory to find out.
-
- I consider it a bug that XF86VidModeGetViewPort() is telling me the
- server's *target* scroll position rather than the server's *actual*
- scroll position. David Dawes agrees, and says they may fix this in
- XFree86 4.0, but it's notrivial.
-
- He also confirms that this behavior is server-dependent, so the
- actual scroll position cannot be reliably determined by the client.
- So... that means the only solution is to provide a ``sandbox''
- around the blackout window -- we make the window be up to N pixels
- larger than the viewport on both the left and right sides. That
- means some part of the outer edges of each hack might not be
- visible, but screw it.
-
- I'm going to guess that 16 pixels is enough, and that the Y dimension
- doesn't have this problem.
-
- The drawback of doing this, of course, is that some of the screenhacks
- will still look pretty stupid -- for example, "slidescreen" will cut
- off the left and right edges of the grid, etc.
- */
-# define FUDGE 16
- if (x > 0 && x < w - ml.hdisplay) /* not at left edge or right edge */
- {
- /* Round X position down to next lower multiple of FUDGE.
- Increase width by 2*FUDGE in case some server rounds up.
- */
- *x_ret = ((x - 1) / FUDGE) * FUDGE;
- *w_ret += (FUDGE * 2);
- }
-# undef FUDGE
-
- if (*x_ret != x ||
- *y_ret != y ||
- *w_ret != ml.hdisplay ||
- *h_ret != ml.vdisplay)
- sprintf (msg + strlen(msg), "; fudged to %dx%d+%d+%d",
- *w_ret, *h_ret, *x_ret, *y_ret);
-
- if (verbose_p)
- fprintf (stderr, "%s.\n", msg);
-
- return;
- }
-
-#endif /* HAVE_XF86VMODE */
-
- *x_ret = 0;
- *y_ret = 0;
- *w_ret = w;
- *h_ret = h;