1 /* xscreensaver, Copyright (c) 1992, 1993, 1994, 1997, 1998, 2001
2 * Jamie Zawinski <jwz@jwz.org>
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation. No representations are made about the suitability of this
9 * software for any purpose. It is provided "as is" without express or
13 /* This file contains code for running an external program to grab an image
14 onto the given window. The external program in question must take a
15 window ID as its argument, e.g., the "xscreensaver-getimage" program
16 in the hacks/ directory.
18 That program links against utils/grabimage.c, which happens to export the
19 same API as this program (utils/grabclient.c).
23 #include "grabscreen.h"
24 #include "resources.h"
27 #include <X11/Xatom.h>
29 extern char *progname;
33 xscreensaver_window_p (Display *dpy, Window window)
37 unsigned long nitems, bytesafter;
39 if (XGetWindowProperty (dpy, window,
40 XInternAtom (dpy, "_SCREENSAVER_VERSION", False),
41 0, 1, False, XA_STRING,
42 &type, &format, &nitems, &bytesafter,
43 (unsigned char **) &version)
51 /* XCopyArea seems not to work right on SGI O2s if you draw in SubwindowMode
52 on a window whose depth is not the maximal depth of the screen? Or
53 something. Anyway, things don't work unless we: use SubwindowMode for
54 the real root window (or a legitimate virtual root window); but do not
55 use SubwindowMode for the xscreensaver window. I make no attempt to
59 use_subwindow_mode_p(Screen *screen, Window window)
61 if (window != VirtualRootWindowOfScreen(screen))
63 else if (xscreensaver_window_p(DisplayOfScreen(screen), window))
71 checkerboard (Screen *screen, Window window)
73 Display *dpy = DisplayOfScreen (screen);
78 GC gc = XCreateGC (dpy, window, 0, &gcv);
79 XWindowAttributes xgwa;
80 XGetWindowAttributes (dpy, window, &xgwa);
81 fg.flags = bg.flags = DoRed|DoGreen|DoBlue;
82 fg.red = fg.green = fg.blue = 0x0000;
83 bg.red = bg.green = bg.blue = 0x4444;
87 /* Allocate black and gray, but don't hold them locked. */
88 if (XAllocColor (dpy, xgwa.colormap, &fg))
89 XFreeColors (dpy, xgwa.colormap, &fg.pixel, 1, 0);
90 if (XAllocColor (dpy, xgwa.colormap, &bg))
91 XFreeColors (dpy, xgwa.colormap, &bg.pixel, 1, 0);
93 XSetForeground (dpy, gc, bg.pixel);
94 XFillRectangle (dpy, window, gc, 0, 0, xgwa.width, xgwa.height);
95 XSetForeground (dpy, gc, fg.pixel);
96 for (y = 0; y < xgwa.height; y += size+size)
97 for (x = 0; x < xgwa.width; x += size+size)
99 XFillRectangle (dpy, window, gc, x, y, size, size);
100 XFillRectangle (dpy, window, gc, x+size, y+size, size, size);
105 grab_screen_image (Screen *screen, Window window)
107 Display *dpy = DisplayOfScreen (screen);
108 char *grabber = get_string_resource ("desktopGrabber", "DesktopGrabber");
112 if (!grabber || !*grabber)
115 "%s: resources installed incorrectly: \"desktopGrabber\" is unset!\n",
120 sprintf (id, "0x%x", (unsigned long) window);
121 cmd = (char *) malloc (strlen(grabber) + strlen(id) + 1);
123 /* Needn't worry about buffer overflows here, because the buffer is
124 longer than the length of the format string, and the length of what
125 we're putting into it. So the only way to crash would be if the
126 format string itself was corrupted, but that comes from the
127 resource database, and if hostile forces have access to that,
128 then the game is already over.
130 sprintf (cmd, grabber, id);
132 /* In case "cmd" fails, leave some random image on the screen, not just
133 black or white, so that it's more obvious what went wrong. */
134 checkerboard (screen, window);