#include "vroot.h"
#include <X11/Xatom.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h> /* for waitpid() and associated macros */
+#endif
+
+
extern char *progname;
checkerboard (Screen *screen, Drawable drawable)
{
Display *dpy = DisplayOfScreen (screen);
- int x, y;
+ unsigned int x, y;
int size = 24;
XColor fg, bg;
XGCValues gcv;
}
+/* Spawn a program, and wait for it to finish.
+ If we just use system() for this, then sometimes the subprocess
+ doesn't die when *this* process is sent a TERM signal. Perhaps
+ this is due to the intermediate /bin/sh that system() uses to
+ parse arguments? I'm not sure. But using fork() and execvp()
+ here seems to close the race.
+ */
+
+static void
+exec_simple_command (const char *command)
+{
+ char *av[1024];
+ int ac = 0;
+ char *token = strtok (strdup(command), " \t");
+ while (token)
+ {
+ av[ac++] = token;
+ token = strtok(0, " \t");
+ }
+ av[ac] = 0;
+
+ execvp (av[0], av); /* shouldn't return. */
+}
+
+static void
+fork_exec_wait (const char *command)
+{
+ char buf [255];
+ pid_t forked;
+ int status;
+
+ switch ((int) (forked = fork ()))
+ {
+ case -1:
+ sprintf (buf, "%s: couldn't fork", progname);
+ perror (buf);
+ return;
+
+ case 0:
+ exec_simple_command (command);
+ exit (1); /* exits child fork */
+ break;
+
+ default:
+ waitpid (forked, &status, 0);
+ break;
+ }
+}
+
+
/* Loads an image into the Drawable.
When grabbing desktop images, the Window will be unmapped first.
*/
void
-load_random_image (Screen *screen, Window window, Drawable drawable)
+load_random_image (Screen *screen, Window window, Drawable drawable,
+ char **name_ret)
{
Display *dpy = DisplayOfScreen (screen);
char *grabber = get_string_resource ("desktopGrabber", "DesktopGrabber");
XSync (dpy, True);
hack_subproc_environment (dpy);
- system (cmd);
+ fork_exec_wait (cmd);
free (cmd);
XSync (dpy, True);
+
+ if (name_ret)
+ {
+ Atom type;
+ int format;
+ unsigned long nitems, bytesafter;
+ char *name=NULL;
+
+ *name_ret = NULL;
+
+ if (XGetWindowProperty (dpy, window,
+ XInternAtom (dpy, XA_XSCREENSAVER_IMAGE_FILENAME,
+ False),
+ 0, 1024, False, XA_STRING,
+ &type, &format, &nitems, &bytesafter,
+ (unsigned char **) &name)
+ == Success
+ && type != None)
+ *name_ret = strdup(name);
+ }
}