http://ftp.x.org/contrib/applications/xscreensaver-3.26.tar.gz
[xscreensaver] / driver / subprocs.c
index c693d5b68a6cb6b0180d15dbd848bd3c469569b3..fd4cef834fd13d4c56e88bca266d20a63ad1c7b3 100644 (file)
@@ -1,5 +1,5 @@
 /* subprocs.c --- choosing, spawning, and killing screenhacks.
- * xscreensaver, Copyright (c) 1991, 1992, 1993, 1995, 1997, 1998
+ * xscreensaver, Copyright (c) 1991, 1992, 1993, 1995, 1997, 1998, 1999, 2000
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -67,7 +67,7 @@ extern int kill (pid_t, int);         /* signal() is in sys/signal.h... */
 
 #include "xscreensaver.h"
 #include "yarandom.h"
-
+#include "visual.h"    /* for id_to_visual() */
 
 extern saver_info *global_si_kludge;   /* I hate C so much... */
 
@@ -395,12 +395,6 @@ make_job (pid_t pid, const char *cmd)
     }
 
   while (isspace(*in)) in++;           /* skip whitespace */
-  if (first && *in == ':')             /* token was a visual name; skip it. */
-    {
-      out = name;
-      first = 0;
-      goto AGAIN;
-    }
   *out = 0;
 
   job->name = strdup(name);
@@ -771,7 +765,7 @@ select_visual_of_hack (saver_screen_info *ssi, screenhack *hack)
   saver_preferences *p = &si->prefs;
   Bool selected;
 
-  if (hack->visual && *hack->visual == ':')
+  if (hack->visual && *hack->visual)
     selected = select_visual(ssi, hack->visual);
   else
     selected = select_visual(ssi, 0);
@@ -912,8 +906,8 @@ spawn_screenhack (saver_info *si, Bool first_time_p)
     }
   else if (si->prefs.verbose_p)
     fprintf (stderr,
-             "%s: server reports that monitor has powered down; "
-             "not launching a new hack.\n", blurb());
+             "%s: X says monitor has powered down; "
+             "not launching a hack.\n", blurb());
 
   store_saver_status (si);  /* store current hack numbers */
 }
@@ -971,15 +965,14 @@ emergency_kill_subproc (saver_info *si)
 Bool
 screenhack_running_p (saver_info *si)
 {
-  Bool result = True;
+  Bool any_running_p = False;
   int i;
   for (i = 0; i < si->nscreens; i++)
     {
       saver_screen_info *ssi = &si->screens[i];
-      if (!ssi->pid)
-       result = False;
+      if (ssi->pid) any_running_p = True;
     }
-  return result;
+  return any_running_p;
 }
 
 \f
@@ -1051,6 +1044,111 @@ hack_subproc_environment (saver_screen_info *ssi)
 #endif /* HAVE_PUTENV */
 }
 
+\f
+/* GL crap */
+
+Visual *
+get_best_gl_visual (saver_screen_info *ssi)
+{
+  saver_info *si = ssi->global;
+  pid_t forked;
+  int fds [2];
+  int in, out;
+  char buf[1024];
+
+  char *av[10];
+  int ac = 0;
+
+  av[ac++] = "xscreensaver-gl-helper";
+  av[ac] = 0;
+
+  if (pipe (fds))
+    {
+      perror ("error creating pipe:");
+      return 0;
+    }
+
+  in = fds [0];
+  out = fds [1];
+
+  switch ((int) (forked = fork ()))
+    {
+    case -1:
+      {
+        sprintf (buf, "%s: couldn't fork", blurb());
+        perror (buf);
+        saver_exit (si, 1, 0);
+      }
+    case 0:
+      {
+        int stdout_fd = 1;
+
+        close (in);  /* don't need this one */
+        close (ConnectionNumber (si->dpy));    /* close display fd */
+
+        if (dup2 (out, stdout_fd) < 0)         /* pipe stdout */
+          {
+            perror ("could not dup() a new stdout:");
+            return 0;
+          }
+        hack_subproc_environment (ssi);                /* set $DISPLAY */
+
+        execvp (av[0], av);                    /* shouldn't return. */
+
+        if (errno != ENOENT || si->prefs.verbose_p)
+          {
+            /* Ignore "no such file or directory" errors, unless verbose.
+               Issue all other exec errors, though. */
+            sprintf (buf, "%s: running %s", blurb(), av[0]);
+            perror (buf);
+          }
+        exit (1);                               /* exits fork */
+        break;
+      }
+    default:
+      {
+        int result = 0;
+        int wait_status = 0;
+
+        FILE *f = fdopen (in, "r");
+        unsigned long v = 0;
+        char c;
+
+        close (out);  /* don't need this one */
+
+        *buf = 0;
+        fgets (buf, sizeof(buf)-1, f);
+        fclose (f);
+
+        /* Wait for the child to die. */
+        waitpid (-1, &wait_status, 0);
+
+        if (1 == sscanf (buf, "0x%x %c", &v, &c))
+          result = (int) v;
+
+        if (result == 0)
+          {
+            if (si->prefs.verbose_p)
+              fprintf (stderr, "%s: %s did not report a GL visual!\n",
+                       blurb(), av[0]);
+            return 0;
+          }
+        else
+          {
+            Visual *v = id_to_visual (ssi->screen, result);
+            if (si->prefs.verbose_p)
+              fprintf (stderr, "%s: %s says the GL visual is 0x%X%s.\n",
+                       blurb(), av[0], result,
+                       (v == ssi->default_visual ? " (the default)" : ""));
+            return v;
+          }
+      }
+    }
+
+  abort();
+}
+
+
 \f
 /* Restarting the xscreensaver process from scratch. */