1 /* xscreensaver, Copyright (c) 2001 by Jamie Zawinski <jwz@jwz.org>
3 * Permission to use, copy, modify, distribute, and sell this software and its
4 * documentation for any purpose is hereby granted without fee, provided that
5 * the above copyright notice appear in all copies and that both that
6 * copyright notice and this permission notice appear in supporting
7 * documentation. No representations are made about the suitability of this
8 * software for any purpose. It is provided "as is" without express or
12 /* xscreensaver-getimage -- helper program that puts an image
13 (e.g., a snapshot of the desktop) onto the given window.
18 #include <X11/Intrinsic.h>
22 #include "grabscreen.h"
23 #include "resources.h"
24 #include "colorbars.h"
29 static char *defaults[] = {
30 #include "../driver/XScreenSaver_ad.h"
37 char *progclass = "XScreenSaver";
41 extern void grabscreen_verbose (void);
44 #define GETIMAGE_VIDEO_PROGRAM "xscreensaver-getimage-video"
45 #define GETIMAGE_FILE_PROGRAM "xscreensaver-getimage-file"
56 exec_error (char **av)
61 sprintf (buf, "%s: could not execute \"%s\"", progname, av[0]);
64 if (errno == ENOENT &&
65 (token = getenv("PATH")))
69 # define PATH_MAX MAXPATHLEN
71 # define PATH_MAX 2048
75 fprintf (stderr, "\n");
77 # if defined(HAVE_GETCWD)
78 getcwd (path, sizeof(path));
79 # elif defined(HAVE_GETWD)
83 fprintf (stderr, " Current directory is: %s\n", path);
84 fprintf (stderr, " PATH is:\n");
85 token = strtok (strdup(token), ":");
88 fprintf (stderr, " %s\n", token);
89 token = strtok(0, ":");
91 fprintf (stderr, "\n");
99 get_image (Screen *screen, Window window, Bool verbose_p)
101 Display *dpy = DisplayOfScreen (screen);
102 Bool desk_p = get_boolean_resource ("grabDesktopImages", "Boolean");
103 Bool video_p = get_boolean_resource ("grabVideoFrames", "Boolean");
104 Bool image_p = get_boolean_resource ("chooseRandomImages", "Boolean");
105 char *dir = get_string_resource ("imageDirectory", "ImageDirectory");
107 enum { do_desk, do_video, do_image, do_bars } which = do_bars;
110 if (video_p) count++;
111 if (image_p) count++;
115 fprintf (stderr, "%s: grabDesktopImages: %s\n",
116 progname, desk_p ? "True" : "False");
117 fprintf (stderr, "%s: grabVideoFrames: %s\n",
118 progname, video_p ? "True" : "False");
119 fprintf (stderr, "%s: chooseRandomImages: %s\n",
120 progname, image_p ? "True" : "False");
121 fprintf (stderr, "%s: imageDirectory: %s\n",
122 progname, (dir ? dir : ""));
127 if (verbose_p && image_p)
129 "%s: no imageDirectory: turning off chooseRandomImages.\n",
135 # error Error! This file definitely needs vroot.h!
138 /* If the window is not the root window (real or virtual!) then the hack
139 that called this program is running in "-window" mode instead of in
142 If the window is not the root window, then it's not possible to grab
143 video or images onto it (the contract with those programs is to draw on
144 the root.) So turn off those options in that case, and turn on desktop
145 grabbing. (Since we're running in a window on the desktop already, we
146 know it's not a security problem to expose desktop bits.)
149 if (window != VirtualRootWindowOfScreen (screen))
151 Bool changed_p = False;
152 if (!desk_p) desk_p = True, changed_p = True;
153 if (video_p) video_p = False, changed_p = True;
154 if (image_p) image_p = False, changed_p = True;
155 if (changed_p && verbose_p)
157 "%s: not running on root window: grabbing desktop.\n",
164 while (1) /* loop until we get one that's permitted */
166 which = (random() % 3);
167 if (which == do_desk && desk_p) break;
168 if (which == do_video && video_p) break;
169 if (which == do_image && image_p) break;
172 if (which == do_desk)
176 fprintf (stderr, "%s: grabbing desktop image\n", progname);
177 grabscreen_verbose();
179 grab_screen_image (screen, window);
182 else if (which == do_bars)
184 XWindowAttributes xgwa;
185 XGetWindowAttributes (dpy, window, &xgwa);
187 fprintf (stderr, "%s: drawing colorbars\n", progname);
188 draw_colorbars (dpy, window, 0, 0, xgwa.width, xgwa.height);
194 memset (av, 0, sizeof(av));
199 fprintf (stderr, "%s: grabbing video\n", progname);
200 av[0] = GETIMAGE_VIDEO_PROGRAM;
204 fprintf (stderr, "%s: loading random image file\n", progname);
205 av[0] = GETIMAGE_FILE_PROGRAM;
216 for (i = (sizeof(av)/sizeof(*av))-1; i > 1; i--)
218 av[1] = strdup ("--verbose");
224 fprintf (stderr, "%s: executing \"", progname);
227 fprintf (stderr, "%s", av[i]);
228 if (av[++i]) fprintf (stderr, " ");
230 fprintf (stderr, "\"\n");
234 /* Store our "-display" argument into the $DISPLAY variable,
235 so that the subprocess gets the right display if the
236 prevailing $DISPLAY is different. */
238 const char *odpy = DisplayString (dpy);
239 char *ndpy = (char *) malloc(strlen(odpy) + 20);
240 strcpy (ndpy, "DISPLAY=");
245 # endif /* HAVE_PUTENV */
247 close (ConnectionNumber (dpy)); /* close display fd */
249 execvp (av[0], av); /* shouldn't return */
257 mapper (XrmDatabase *db, XrmBindingList bindings, XrmQuarkList quarks,
258 XrmRepresentation *type, XrmValue *value, XPointer closure)
261 for (i = 0; quarks[i]; i++)
263 if (bindings[i] == XrmBindTightly)
264 fprintf (stderr, (i == 0 ? "" : "."));
265 else if (bindings[i] == XrmBindLoosely)
266 fprintf (stderr, "*");
268 fprintf (stderr, " ??? ");
269 fprintf(stderr, "%s", XrmQuarkToString (quarks[i]));
272 fprintf (stderr, ": %s\n", (char *) value->addr);
280 main (int argc, char **argv)
286 Window window = (Window) 0;
287 Bool verbose_p = False;
292 s = strrchr (progname, '/');
293 if (s) progname = s+1;
295 /* We must read exactly the same resources as xscreensaver.
296 That means we must have both the same progclass *and* progname,
297 at least as far as the resource database is concerned. So,
298 put "xscreensaver" in argv[0] while initializing Xt.
300 argv[0] = "xscreensaver";
301 toplevel = XtAppInitialize (&app, progclass, 0, 0, &argc, argv,
304 dpy = XtDisplay (toplevel);
305 screen = XtScreen (toplevel);
306 db = XtDatabase (dpy);
308 XtGetApplicationNameAndClass (dpy, &s, &progclass);
310 /* half-assed way of avoiding buffer-overrun attacks. */
311 if (strlen (progname) >= 100) progname[100] = 0;
313 for (i = 1; i < argc; i++)
315 if (argv[i][0] == '-' && argv[i][1] == '-') argv[i]++;
316 if (!strcmp (argv[i], "-v") ||
317 !strcmp (argv[i], "-verbose"))
319 else if (window == 0)
324 if (!strcmp (argv[i], "root") ||
325 !strcmp (argv[i], "-root") ||
326 !strcmp (argv[i], "--root"))
327 window = RootWindowOfScreen (screen);
329 else if ((1 == sscanf (argv[i], " 0x%x %c", &w, &dummy) ||
330 1 == sscanf (argv[i], " %d %c", &w, &dummy)) &&
340 "usage: %s [ -display host:dpy.screen ] [ -v ] window-id\n",
342 fprintf (stderr, "\n"
343 "\tThis program puts an image of the desktop on the given window.\n"
344 "\tIt is used by those xscreensaver demos that operate on images.\n"
350 if (window == 0) goto LOSE;
352 /* Randomize -- only need to do this here because this program
353 doesn't use the `screenhack.h' or `lockmore.h' APIs. */
357 memset (&P, 0, sizeof(P));
365 /* Print out all the resources we read. */
367 XrmName name = { 0 };
368 XrmClass class = { 0 };
370 XrmEnumerateDatabase (db, &name, &class, XrmEnumAllLevels, mapper,
375 get_image (screen, window, verbose_p);