X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=utils%2Fgrabscreen.c;h=77fe3c96bd4c5d5130bc8e337aa6a88e31136b12;hb=d6b0217f2417bd19187f0ebc389d6c5c2233b11c;hp=9bcb4264ac90d86d283b0865347be6d1570cdec0;hpb=40eacb5812ef7c0e3374fb139afbb4f5bc8bbfb5;p=xscreensaver diff --git a/utils/grabscreen.c b/utils/grabscreen.c index 9bcb4264..77fe3c96 100644 --- a/utils/grabscreen.c +++ b/utils/grabscreen.c @@ -1,5 +1,4 @@ -/* xscreensaver, Copyright (c) 1992, 1993, 1994, 1997, 1998, 2003 - * Jamie Zawinski +/* xscreensaver, Copyright (c) 1992-2016 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -15,6 +14,32 @@ 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" @@ -117,12 +142,12 @@ xscreensaver_window_p (Display *dpy, Window window) 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; @@ -133,7 +158,6 @@ xscreensaver_window_p (Display *dpy, Window window) /* 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. */ @@ -142,20 +166,16 @@ top_level_window_p (Screen *screen, Window window) { 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 { @@ -183,7 +203,6 @@ top_level_window_p (Screen *screen, Window window) } - static Bool error_handler_hit_p = False; static XErrorHandler old_ehandler = 0; static int @@ -229,9 +248,9 @@ use_subwindow_mode_p(Screen *screen, Window window) 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; @@ -239,8 +258,8 @@ install_screen_colormaps (Screen *screen) 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; @@ -266,7 +285,7 @@ install_screen_colormaps (Screen *screen) void -grab_screen_image (Screen *screen, Window window) +grab_screen_image_internal (Screen *screen, Window window) { Display *dpy = DisplayOfScreen (screen); XWindowAttributes xgwa; @@ -297,12 +316,12 @@ grab_screen_image (Screen *screen, Window window) 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; @@ -470,7 +489,7 @@ copy_default_colormap_contents (Screen *screen, 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, @@ -723,6 +742,8 @@ read_display (Screen *screen, Window window, Pixmap into_pixmap, /* 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) @@ -738,7 +759,7 @@ 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) { @@ -790,6 +811,11 @@ allocate_cubic_colormap (Screen *screen, Window window, Visual *visual) } } +/* 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) @@ -825,6 +851,13 @@ find_closest_pixel (XColor *colors, int ncolors, } +/* 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) {