ftp://ftp.linux.ncsu.edu/mirror/ftp.redhat.com/pub/redhat/linux/enterprise/4/en/os...
[xscreensaver] / hacks / glx / starwars.c
index 96c77753bac124bf705f30c92287e06a24ae2c79..60f766a72514e576e63a11aa105901f098e0dc79 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * starwars, Copyright (c) 1998-2001 Jamie Zawinski <jwz@jwz.org> and
+ * starwars, Copyright (c) 1998-2001, 2004 Jamie Zawinski <jwz@jwz.org> and
  * Claudio Matsuoka <claudio@helllabs.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -87,12 +87,17 @@ extern XtAppContext app;
 
 #ifdef USE_GL /* whole file */
 
+#include <ctype.h>
 #include <GL/glu.h>
 #include <sys/stat.h>
 #include "glutstroke.h"
 #include "glut_roman.h"
 #define GLUT_FONT (&glutStrokeRoman)
 
+#ifdef HAVE_UNAME
+# include <sys/utsname.h>
+#endif /* HAVE_UNAME */
+
 
 typedef struct {
   GLXContext *glx_context;
@@ -136,38 +141,38 @@ static char *alignment_str;
 static int alignment;
 
 static XrmOptionDescRec opts[] = {
-  {"-program",   ".starwars.program",  XrmoptionSepArg, (caddr_t) 0 },
-  {"-lines",     ".starwars.lines",    XrmoptionSepArg, (caddr_t) 0 },
-  {"-steps",     ".starwars.steps",    XrmoptionSepArg, (caddr_t) 0 },
-  {"-spin",      ".starwars.spin",     XrmoptionSepArg, (caddr_t) 0 },
-  {"-size",     ".starwars.fontSize", XrmoptionSepArg, (caddr_t) 0 },
-  {"-columns",  ".starwars.columns",  XrmoptionSepArg, (caddr_t) 0 },
-  {"-smooth",    ".starwars.smooth",   XrmoptionNoArg,  (caddr_t) "True" },
-  {"-no-smooth", ".starwars.smooth",   XrmoptionNoArg,  (caddr_t) "False" },
-  {"-thick",     ".starwars.thick",    XrmoptionNoArg,  (caddr_t) "True" },
-  {"-no-thick",  ".starwars.thick",    XrmoptionNoArg,  (caddr_t) "False" },
-  {"-fade",      ".starwars.fade",     XrmoptionNoArg,  (caddr_t) "True" },
-  {"-no-fade",   ".starwars.fade",     XrmoptionNoArg,  (caddr_t) "False" },
-  {"-wrap",     ".starwars.lineWrap", XrmoptionNoArg,  (caddr_t) "True" },
-  {"-no-wrap",  ".starwars.lineWrap", XrmoptionNoArg,  (caddr_t) "False" },
-  {"-nowrap",   ".starwars.lineWrap", XrmoptionNoArg,  (caddr_t) "False" },
-  {"-left",      ".starwars.alignment",XrmoptionNoArg,  (caddr_t) "Left" },
-  {"-right",     ".starwars.alignment",XrmoptionNoArg,  (caddr_t) "Right" },
-  {"-center",    ".starwars.alignment",XrmoptionNoArg,  (caddr_t) "Center" },
+  {"-program",   ".starwars.program",  XrmoptionSepArg, 0 },
+  {"-lines",     ".starwars.lines",    XrmoptionSepArg, 0 },
+  {"-steps",     ".starwars.steps",    XrmoptionSepArg, 0 },
+  {"-spin",      ".starwars.spin",     XrmoptionSepArg, 0 },
+  {"-size",     ".starwars.fontSize", XrmoptionSepArg, 0 },
+  {"-columns",  ".starwars.columns",  XrmoptionSepArg, 0 },
+  {"-smooth",    ".starwars.smooth",   XrmoptionNoArg,  "True" },
+  {"-no-smooth", ".starwars.smooth",   XrmoptionNoArg,  "False" },
+  {"-thick",     ".starwars.thick",    XrmoptionNoArg,  "True" },
+  {"-no-thick",  ".starwars.thick",    XrmoptionNoArg,  "False" },
+  {"-fade",      ".starwars.fade",     XrmoptionNoArg,  "True" },
+  {"-no-fade",   ".starwars.fade",     XrmoptionNoArg,  "False" },
+  {"-wrap",     ".starwars.lineWrap", XrmoptionNoArg,  "True" },
+  {"-no-wrap",  ".starwars.lineWrap", XrmoptionNoArg,  "False" },
+  {"-nowrap",   ".starwars.lineWrap", XrmoptionNoArg,  "False" },
+  {"-left",      ".starwars.alignment",XrmoptionNoArg,  "Left" },
+  {"-right",     ".starwars.alignment",XrmoptionNoArg,  "Right" },
+  {"-center",    ".starwars.alignment",XrmoptionNoArg,  "Center" },
 };
 
 static argtype vars[] = {
-  {(caddr_t *) &program,        "program", "Program", DEF_PROGRAM, t_String},
-  {(caddr_t *) &max_lines,      "lines",   "Integer", DEF_LINES,   t_Int},
-  {(caddr_t *) &scroll_steps,   "steps",   "Integer", DEF_STEPS,   t_Int},
-  {(caddr_t *) &star_spin,      "spin",    "Float",   DEF_SPIN,    t_Float},
-  {(caddr_t *) &font_size,      "fontSize","Float",   DEF_STEPS,   t_Float},
-  {(caddr_t *) &target_columns, "columns", "Integer", DEF_COLUMNS, t_Int},
-  {(caddr_t *) &wrap_p,         "lineWrap","Boolean", DEF_COLUMNS, t_Bool},
-  {(caddr_t *) &alignment_str,  "alignment","Alignment",DEF_ALIGN, t_String},
-  {(caddr_t *) &smooth_p,       "smooth",  "Boolean", DEF_SMOOTH,  t_Bool},
-  {(caddr_t *) &thick_p,        "thick",   "Boolean", DEF_THICK,   t_Bool},
-  {(caddr_t *) &fade_p,         "fade",    "Boolean", DEF_FADE,    t_Bool},
+  {&program,        "program",   "Program",    DEF_PROGRAM, t_String},
+  {&max_lines,      "lines",     "Integer",    DEF_LINES,   t_Int},
+  {&scroll_steps,   "steps",     "Integer",    DEF_STEPS,   t_Int},
+  {&star_spin,      "spin",      "Float",      DEF_SPIN,    t_Float},
+  {&font_size,      "fontSize",  "Float",      DEF_STEPS,   t_Float},
+  {&target_columns, "columns",   "Integer",    DEF_COLUMNS, t_Int},
+  {&wrap_p,         "lineWrap",  "Boolean",    DEF_COLUMNS, t_Bool},
+  {&alignment_str,  "alignment", "Alignment", DEF_ALIGN,    t_String},
+  {&smooth_p,       "smooth",    "Boolean",   DEF_SMOOTH,   t_Bool},
+  {&thick_p,        "thick",     "Boolean",   DEF_THICK,    t_Bool},
+  {&fade_p,         "fade",      "Boolean",   DEF_FADE,     t_Bool},
 };
 
 ModeSpecOpt sws_opts = {countof(opts), opts, countof(vars), vars, NULL};
@@ -235,6 +240,31 @@ strip (char *s, Bool leading, Bool trailing)
 }
 
 
+/* The GLUT font only has ASCII characters in them, so do what we can to
+   convert Latin1 characters to the nearest ASCII equivalent... 
+ */
+static void
+latin1_to_ascii (char *s)
+{
+  unsigned char *us = (unsigned char *) s;
+  const unsigned char ascii[95] = {
+    '!', 'C', '#', '#', 'Y', '|', 'S', '_', 'C', '?', '<', '=', '-', 'R', '_',
+    '?', '?', '2', '3', '\'','u', 'P', '.', ',', '1', 'o', '>', '?', '?', '?',
+    '?', 'A', 'A', 'A', 'A', 'A', 'A', 'E', 'C', 'E', 'E', 'E', 'E', 'I', 'I',
+    'I', 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'x', '0', 'U', 'U', 'U', 'U',
+    'Y', 'p', 'S', 'a', 'a', 'a', 'a', 'a', 'a', 'e', 'c', 'e', 'e', 'e', 'e',
+    'i', 'i', 'i', 'i', 'o', 'n', 'o', 'o', 'o', 'o', 'o', '/', 'o', 'u', 'u',
+    'u', 'u', 'y', 'p', 'y' };
+  while (*us)
+    {
+      if (*us >= 161)
+        *us = ascii[*us - 161];
+      else if (*us > 127)
+        *us = '?';
+      us++;
+    }
+}
+
 \f
 /* Subprocess.
    (This bit mostly cribbed from phosphor.c)
@@ -258,18 +288,55 @@ launch_text_generator (sws_configuration *sc)
 
   if (!strcasecmp(oprogram, "(default)"))
     {
-#ifdef __linux__
-      static int done_once = 0;
-      struct stat st;
-      char *cmd = "cat /usr/src/linux/README";
-      if (!(done_once++) && !stat (cmd+4, &st))
-        oprogram = cmd;
-      else
-#endif
-        oprogram = FORTUNE_PROGRAM;
+      oprogram = FORTUNE_PROGRAM;
+
+#if defined(__linux__) && defined(HAVE_UNAME)
+      {
+        static int done_once = 0;
+        if (!done_once)
+          {
+            struct utsname uts;
+            struct stat st;
+            done_once = 1;
+            if (uname (&uts) == 0)
+              {
+                static char cmd[200];
+                char *s;
+                /* strip version at the first non-digit-dash-dot, to
+                   lose any "SMP" crap at the end. */
+                for (s = uts.release; *s; s++)
+                  if (!isdigit(*s) && *s != '.' && *s != '-')
+                    *s = 0;
+                sprintf (cmd, "cat /usr/src/linux-%s/README", uts.release);
+                if (!stat (cmd+4, &st))
+                  oprogram = cmd;
+                else
+                  {
+                    /* kernel source not installed?  try X... */
+                    strcpy (cmd, "cat /usr/X11R6/lib/X11/doc/README");
+                    if (!stat (cmd+4, &st))
+                      oprogram = cmd;
+                  }
+              }
+          }
+      }
+#endif /* __linux__ && HAVE_UNAME */
+
+#ifdef __APPLE__   /* MacOS X + XDarwin */
+      {
+        static int done_once = 0;
+        if (!done_once)
+          {
+            struct stat st;
+            static char *cmd = "cat /usr/X11R6/README";
+            if (!stat (cmd+4, &st))
+              oprogram = cmd;
+          }
+      }
+#endif /* __APPLE__ */
     }
 
- program = (char *) malloc (strlen (oprogram) + 10);
 program = (char *) malloc (strlen (oprogram) + 10);
   strcpy (program, "( ");
   strcat (program, oprogram);
   strcat (program, " ) 2>&1");
@@ -386,6 +453,7 @@ get_more_lines (sws_configuration *sc)
           sc->lines[sc->total_lines] = (char *) malloc (L+1);
           memcpy (sc->lines[sc->total_lines], sc->buf, L);
           sc->lines[sc->total_lines][L] = 0;
+          latin1_to_ascii (sc->lines[sc->total_lines]);
 
           {
             char *t = sc->lines[sc->total_lines];
@@ -401,7 +469,7 @@ get_more_lines (sws_configuration *sc)
           if (sc->buf_tail > (s - sc->buf))
             {
               int i = sc->buf_tail - (s - sc->buf);
-              memcpy (sc->buf, s, i);
+              memmove (sc->buf, s, i);
               sc->buf_tail = i;
               sc->buf[sc->buf_tail] = 0;
             }
@@ -863,7 +931,9 @@ draw_sws (ModeInfo *mi)
             }
 
           if (alignment >= 0)
-            xoff = 1.0 - (glutStrokeLength(GLUT_FONT, line) * sc->font_scale);
+            xoff = 1.0 - (glutStrokeLength(GLUT_FONT,
+                                           (unsigned char *) line)
+                          * sc->font_scale);
           if (alignment == 0)
             xoff /= 2;