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 hack_subproc_environment (Display *dpy)
107 /* Store $DISPLAY into the environment, so that the $DISPLAY variable that
108 the spawned processes inherit is what we are actually using.
110 const char *odpy = DisplayString (dpy);
111 char *ndpy = (char *) malloc(strlen(odpy) + 20);
112 strcpy (ndpy, "DISPLAY=");
115 /* Allegedly, BSD 4.3 didn't have putenv(), but nobody runs such systems
116 any more, right? It's not Posix, but everyone seems to have it. */
120 #endif /* HAVE_PUTENV */
125 grab_screen_image (Screen *screen, Window window)
127 Display *dpy = DisplayOfScreen (screen);
128 char *grabber = get_string_resource ("desktopGrabber", "DesktopGrabber");
132 if (!grabber || !*grabber)
135 "%s: resources installed incorrectly: \"desktopGrabber\" is unset!\n",
140 sprintf (id, "0x%x", (unsigned long) window);
141 cmd = (char *) malloc (strlen(grabber) + strlen(id) + 1);
143 /* Needn't worry about buffer overflows here, because the buffer is
144 longer than the length of the format string, and the length of what
145 we're putting into it. So the only way to crash would be if the
146 format string itself was corrupted, but that comes from the
147 resource database, and if hostile forces have access to that,
148 then the game is already over.
150 sprintf (cmd, grabber, id);
152 /* In case "cmd" fails, leave some random image on the screen, not just
153 black or white, so that it's more obvious what went wrong. */
154 checkerboard (screen, window);
157 hack_subproc_environment (dpy);