-/* xscreensaver, Copyright (c) 1992, 1993, 1994, 1997, 1998
- * Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
the difference between drawing on the actual root window, and on the fake
root window used by the screensaver, since at this level the illusion
breaks down...
+
+ The hacks themselves use utils/grabclient.c to invoke the
+ "xscreensaver-getimage" program as a sub-process.
+
+ On "real" X11 systems:
+
+ "driver/xscreensaver-getimage" runs the code in this file to grab
+ the X11 root window image as a Pixmap.
+
+ On MacOS systems running X11, which nobody does any more:
+
+ "driver/xscreensaver-getimage" runs the Perl script
+ "driver/xscreensaver-getimage-desktop", which in turn runs the MacOS
+ program "/usr/sbin/screencapture" to get the Mac desktop image as a
+ PNG file.
+
+ On MacOS systems running the native Cocoa build, or on iOS or Android
+ systems:
+
+ "driver/xscreensaver-getimage" is not used. Instead, each saver's
+ "utils/grabclient.c" links against "OSX/grabclient-osx.m",
+ "OSX/grabclient-ios.m" or "jwxyz/jwxyz-android.c" to grab
+ screenshots directly without invoking a sub-process to do it.
+
+ See the comment at the top of utils/grabclient.c for a more detailed
+ explanation.
*/
#include "utils.h"
Atom type;
int format;
unsigned long nitems, bytesafter;
- char *version;
+ unsigned char *version;
if (XGetWindowProperty (dpy, window,
XInternAtom (dpy, "_SCREENSAVER_VERSION", False),
0, 1, False, XA_STRING,
&type, &format, &nitems, &bytesafter,
- (unsigned char **) &version)
+ &version)
== Success
&& type != None)
return True;
/* Whether the given window is:
- the real root window;
- - the virtual root window;
- a direct child of the root window;
- a direct child of the window manager's decorations.
*/
{
Display *dpy = DisplayOfScreen (screen);
Window root, parent, *kids;
- Window vroot = VirtualRootWindowOfScreen(screen);
unsigned int nkids;
- if (window == vroot)
- return True;
-
if (!XQueryTree (dpy, window, &root, &parent, &kids, &nkids))
return False;
if (window == root)
return True;
- /* If our direct parent is the root (or *a* root), then yes. */
- if (parent == root || parent == vroot)
+ /* If our direct parent is the real root window, then yes. */
+ if (parent == root)
return True;
else
{
}
-
+static Bool error_handler_hit_p = False;
static XErrorHandler old_ehandler = 0;
static int
BadWindow_ehandler (Display *dpy, XErrorEvent *error)
{
+ error_handler_hit_p = True;
if (error->error_code == BadWindow || error->error_code == BadDrawable)
return 0;
else if (!old_ehandler)
static void
install_screen_colormaps (Screen *screen)
{
- int i;
+ unsigned int i;
Display *dpy = DisplayOfScreen (screen);
- Window vroot, real_root;
+ Window real_root;
Window parent, *kids = 0;
unsigned int nkids = 0;
XSync (dpy, False);
old_ehandler = XSetErrorHandler (BadWindow_ehandler);
+ error_handler_hit_p = False;
- vroot = VirtualRootWindowOfScreen (screen);
- if (XQueryTree (dpy, vroot, &real_root, &parent, &kids, &nkids))
+ real_root = XRootWindowOfScreen (screen); /* not vroot */
+ if (XQueryTree (dpy, real_root, &real_root, &parent, &kids, &nkids))
for (i = 0; i < nkids; i++)
{
XWindowAttributes xgwa;
void
-grab_screen_image (Screen *screen, Window window)
+grab_screen_image_internal (Screen *screen, Window window)
{
Display *dpy = DisplayOfScreen (screen);
XWindowAttributes xgwa;
- Window real_root = XRootWindowOfScreen (screen); /* not vroot */
- Bool root_p = (window == real_root);
- Bool saver_p = xscreensaver_window_p (dpy, window);
+ Window real_root;
+ Bool root_p;
+ Bool saver_p;
Bool grab_mouse_p = False;
int unmap_time = 0;
+ real_root = XRootWindowOfScreen (screen); /* not vroot */
+ root_p = (window == real_root);
+ saver_p = xscreensaver_window_p (dpy, window);
+
+ XGetWindowAttributes (dpy, window, &xgwa);
+ screen = xgwa.screen;
+
if (saver_p)
/* I think this is redundant, but just to be safe... */
root_p = False;
double unmap = 0;
if (saver_p)
{
- unmap = get_float_resource("grabRootDelay", "Seconds");
+ unmap = get_float_resource(dpy, "grabRootDelay", "Seconds");
if (unmap <= 0.00001 || unmap > 20) unmap = 2.5;
}
else
{
- unmap = get_float_resource("grabWindowDelay", "Seconds");
+ unmap = get_float_resource(dpy, "grabWindowDelay", "Seconds");
if (unmap <= 0.00001 || unmap > 20) unmap = 0.66;
}
unmap_time = unmap * 100000;
if (grab_verbose_p)
{
- XWindowAttributes xgwa2;
fprintf(stderr,
"\n%s: window 0x%08lX root: %d saver: %d grab: %d wait: %.1f\n",
progname, (unsigned long) window,
root_p, saver_p, grab_mouse_p, ((double)unmap_time)/1000000.0);
- XGetWindowAttributes (dpy, window, &xgwa2);
fprintf(stderr, "%s: ", progname);
- describe_visual(stderr, screen, xgwa2.visual, False);
+ describe_visual(stderr, screen, xgwa.visual, False);
fprintf (stderr, "\n");
}
usleep(unmap_time); /* wait for everyone to swap in and handle exposes */
}
- XGetWindowAttributes (dpy, window, &xgwa);
-
if (!root_p)
{
#ifdef HAVE_READ_DISPLAY_EXTENSION
else /* root_p */
{
Pixmap pixmap;
- XWindowAttributes xgwa;
- XGetWindowAttributes(dpy, window, &xgwa);
pixmap = XCreatePixmap(dpy, window, xgwa.width, xgwa.height, xgwa.depth);
#ifdef HAVE_READ_DISPLAY_EXTENSION
if (! read_display(screen, window, pixmap, True))
#endif
{
- Window real_root = XRootWindowOfScreen (xgwa.screen); /* not vroot */
+ Window real_root = XRootWindowOfScreen (screen); /* not vroot */
XGCValues gcv;
GC gc;
XQueryColors (dpy, from_cmap, old_colors, max_cells);
got_cells = max_cells;
- allocate_writable_colors (dpy, to_cmap, pixels, &got_cells);
+ allocate_writable_colors (screen, to_cmap, pixels, &got_cells);
if (grab_verbose_p && got_cells != max_cells)
fprintf(stderr, "%s: got only %d of %d cells\n", progname,
/* Makes and installs a colormap that makes a PseudoColor or DirectColor
visual behave like a TrueColor visual of the same depth.
+
+ #### Duplicated in driver/xscreensaver-getimage.c
*/
static void
allocate_cubic_colormap (Screen *screen, Window window, Visual *visual)
XGetWindowAttributes (dpy, window, &xgwa);
cmap = xgwa.colormap;
- depth = visual_depth(screen, visual);
+ depth = visual_depth (screen, visual);
switch (depth)
{
}
}
+/* Find the pixel index that is closest to the given color
+ (using linear distance in RGB space -- which is far from the best way.)
+
+ #### Duplicated in driver/xscreensaver-getimage.c
+ */
static unsigned long
find_closest_pixel (XColor *colors, int ncolors,
unsigned long r, unsigned long g, unsigned long b)
}
+/* Given an XImage with 8-bit or 12-bit RGB data, convert it to be
+ displayable with the given X colormap. The farther from a perfect
+ color cube the contents of the colormap are, the lossier the
+ transformation will be. No dithering is done.
+
+ #### Duplicated in driver/xscreensaver-getimage.c
+ */
void
remap_image (Screen *screen, Window window, Colormap cmap, XImage *image)
{