http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.01.tar.gz
[xscreensaver] / hacks / noseguy.c
index 4707d422b029b2a9d326c0e0fd62cccc8944166c..f7c8013dee02e3c7bf07ae26e624c33021269500 100644 (file)
@@ -1,4 +1,5 @@
-/* xscreensaver, Copyright (c) 1992 Jamie Zawinski <jwz@lucid.com>
+/* xscreensaver, Copyright (c) 1992, 1996, 1997, 1998
+ *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
  */
 
 /* Make a little guy with a big nose and a hat wanter around the screen,
-   spewing out messages.  Derived from xnlock by Dan Heller <argv@sun.com>.
+   spewing out messages.  Derived from xnlock by 
+   Dan Heller <argv@danheller.com>.
  */
 
 #include "screenhack.h"
+#include "xpm-pixmap.h"
 #include <stdio.h>
 
-#if __STDC__
 extern FILE *popen (const char *, const char *);
 extern int pclose (FILE *);
-#endif
-
-#define Pixel unsigned long
 
 #define font_height(font)              (font->ascent + font->descent)
 #define FONT_NAME                      "-*-times-*-*-*-*-18-*-*-*-*-*-*-*"
@@ -30,14 +29,18 @@ static Display *dpy;
 static Window window;
 static int Width, Height;
 static GC fg_gc, bg_gc, text_fg_gc, text_bg_gc;
-static char *words, *get_words();
+static char *words;
+static char *get_words (void);
 static int x, y;
 static XFontStruct *font;
 static char *def_words = "I'm out running around.";
-static void init_images(), walk(), talk();
-static int think();
-static unsigned long interval, look(); 
-static Pixmap left0, left1, right0, right1;
+static void walk (int dir);
+static void talk (int erase);
+static void talk_1 (void);
+static int think (void);
+static unsigned long interval;
+static unsigned long look (void); 
+static Pixmap left1, left2, right1, right2;
 static Pixmap left_front, right_front, front, down;
 
 static char *program, *orig_program, *filename, *text;
@@ -52,39 +55,70 @@ static int getwordsfrom;
 #define GET_PASSWD 2
 static int state;      /* indicates states: walking or getting passwd */
 
-static void (*next_fn) ();
-
-#include "noses/nose.0.left"
-#include "noses/nose.1.left"
-#include "noses/nose.0.right"
-#include "noses/nose.1.right"
-#include "noses/nose.left.front"
-#include "noses/nose.right.front"
-#include "noses/nose.front"
-#include "noses/nose.down"
+static void (*next_fn) (void);
+
+#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM)
+# include "images/noseguy/nose-f1.xpm"
+# include "images/noseguy/nose-f2.xpm"
+# include "images/noseguy/nose-f3.xpm"
+# include "images/noseguy/nose-f4.xpm"
+# include "images/noseguy/nose-l1.xpm"
+# include "images/noseguy/nose-l2.xpm"
+# include "images/noseguy/nose-r1.xpm"
+# include "images/noseguy/nose-r2.xpm"
+#else
+# include "images/noseguy/nose-f1.xbm"
+# include "images/noseguy/nose-f2.xbm"
+# include "images/noseguy/nose-f3.xbm"
+# include "images/noseguy/nose-f4.xbm"
+# include "images/noseguy/nose-l1.xbm"
+# include "images/noseguy/nose-l2.xbm"
+# include "images/noseguy/nose-r1.xbm"
+# include "images/noseguy/nose-r2.xbm"
+#endif
 
 static void
-init_images ()
+init_images (void)
 {
   static Pixmap *images[] = {
-    &left0, &left1, &right0, &right1,
+    &left1, &left2, &right1, &right2,
     &left_front, &right_front, &front, &down
   };
+  int i;
+#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM)
+
+  static char **bits[] = {
+    nose_l1_xpm, nose_l2_xpm, nose_r1_xpm, nose_r2_xpm,
+    nose_f2_xpm, nose_f3_xpm, nose_f1_xpm, nose_f4_xpm
+  };
+
+
+  for (i = 0; i < sizeof (images) / sizeof(*images); i++)
+    {
+      Pixmap pixmap = xpm_data_to_pixmap (dpy, window, bits[i],
+                                          0, 0, 0);
+      if (!pixmap)
+       {
+         fprintf (stderr, "%s: Can't load nose images\n", progname);
+         exit (1);
+       }
+      *images[i] = pixmap;
+    }
+#else
   static unsigned char *bits[] = {
-    nose_0_left_bits, nose_1_left_bits, nose_0_right_bits,
-    nose_1_right_bits, nose_left_front_bits, nose_right_front_bits,
-    nose_front_bits, nose_down_bits
+    nose_l1_bits, nose_l2_bits, nose_r1_bits, nose_r2_bits,
+    nose_f2_bits, nose_f3_bits, nose_f1_bits, nose_f4_bits
   };
-  int i;
 
-  for (i = 0; i < sizeof (images) / sizeof (images[0]); i++)
+  for (i = 0; i < sizeof (images) / sizeof(*images); i++)
     if (!(*images[i] =
          XCreatePixmapFromBitmapData(dpy, window,
                                      (char *) bits[i], 64, 64, 1, 0, 1)))
       {
-       fprintf (stderr, "%s: Can't load nose images", progname);
+       fprintf (stderr, "%s: Can't load nose images\n", progname);
        exit (1);
       }
+#endif
 }
 
 #define LEFT   001
@@ -96,7 +130,7 @@ init_images ()
 #define Y_INCR 2
 
 static void
-move()
+move (void)
 {
     static int      length,
                     dir;
@@ -170,9 +204,16 @@ move()
     next_fn = move;
 }
 
+#ifdef HAVE_XPM
+# define COPY(dpy,frame,window,gc,x,y,w,h,x2,y2) \
+  XCopyArea (dpy,frame,window,gc,x,y,w,h,x2,y2)
+#else
+# define COPY(dpy,frame,window,gc,x,y,w,h,x2,y2) \
+  XCopyPlane(dpy,frame,window,gc,x,y,w,h,x2,y2,1L)
+#endif
+
 static void
-walk(dir)
-    register int    dir;
+walk(int dir)
 {
     register int    incr = 0;
     static int      lastdir;
@@ -185,12 +226,12 @@ walk(dir)
        if (dir & LEFT)
        {
            incr = X_INCR;
-           frame = (up < 0) ? left0 : left1;
+           frame = (up < 0) ? left1 : left2;
        }
        else
        {
            incr = -X_INCR;
-           frame = (up < 0) ? right0 : right1;
+           frame = (up < 0) ? right1 : right2;
        }
        if ((lastdir == FRONT || lastdir == DOWN) && dir & UP)
        {
@@ -199,7 +240,7 @@ walk(dir)
             * workaround silly bug that leaves screen dust when guy is
             * facing forward or down and moves up-left/right.
             */
-           XCopyPlane(dpy, frame, window, fg_gc, 0, 0, 64, 64, x, y, 1L);
+           COPY(dpy, frame, window, fg_gc, 0, 0, 64, 64, x, y);
            XFlush(dpy);
        }
        /* note that maybe neither UP nor DOWN is set! */
@@ -210,11 +251,9 @@ walk(dir)
     }
     /* Explicit up/down movement only (no left/right) */
     else if (dir == UP)
-       XCopyPlane(dpy, front, window, fg_gc,
-                  0, 0, 64, 64, x, y -= Y_INCR, 1L);
+       COPY(dpy, front, window, fg_gc, 0, 0, 64, 64, x, y -= Y_INCR);
     else if (dir == DOWN)
-       XCopyPlane(dpy, down, window, fg_gc,
-                  0, 0, 64, 64, x, y += Y_INCR, 1L);
+       COPY(dpy, down, window, fg_gc, 0, 0, 64, 64, x, y += Y_INCR);
     else if (dir == FRONT && frame != front)
     {
        if (up > 0)
@@ -225,34 +264,32 @@ walk(dir)
            frame = right_front;
        else
            frame = front;
-       XCopyPlane(dpy, frame, window, fg_gc, 0, 0, 64, 64, x, y, 1L);
+       COPY(dpy, frame, window, fg_gc, 0, 0, 64, 64, x, y);
     }
     if (dir & LEFT)
        while (--incr >= 0)
        {
-           XCopyPlane(dpy, frame, window, fg_gc,
-                      0, 0, 64, 64, --x, y + up, 1L);
+           COPY(dpy, frame, window, fg_gc, 0, 0, 64, 64, --x, y + up);
            XFlush(dpy);
        }
     else if (dir & RIGHT)
        while (++incr <= 0)
        {
-           XCopyPlane(dpy, frame, window, fg_gc,
-                      0, 0, 64, 64, ++x, y + up, 1L);
+           COPY(dpy, frame, window, fg_gc, 0, 0, 64, 64, ++x, y + up);
            XFlush(dpy);
        }
     lastdir = dir;
 }
 
 static int
-think()
+think (void)
 {
     if (random() & 1)
        walk(FRONT);
     if (random() & 1)
     {
        if (getwordsfrom == FROM_PROGRAM)
-           words = get_words(0, (char **) 0);
+           words = get_words();
        return 1;
     }
     return 0;
@@ -261,8 +298,7 @@ think()
 #define MAXLINES 40
 
 static void
-talk(force_erase)
-    int             force_erase;
+talk(int force_erase)
 {
     int             width = 0,
                     height,
@@ -307,7 +343,7 @@ talk(force_erase)
     walk(FRONT);
     p = strcpy(buf, words);
 
-    if (!(p2 = index(p, '\n')) || !p2[1])
+    if (!(p2 = strchr(p, '\n')) || !p2[1])
       {
        total = strlen (words);
        strcpy (args[0], words);
@@ -331,7 +367,7 @@ talk(force_erase)
              break;
            }
          p = p2 + 1;
-         if (!(p2 = index(p, '\n')))
+         if (!(p2 = strchr(p, '\n')))
            break;
        }
     height++;
@@ -375,36 +411,42 @@ talk(force_erase)
     }
     interval = (total / 15) * 1000;
     if (interval < 2000) interval = 2000;
-    next_fn = talk;
+    next_fn = talk_1;
 }
 
+static void talk_1 (void) 
+{
+  talk(0);
+}
+
+
 static unsigned long
-look()
+look (void)
 {
     if (random() % 3)
     {
-       XCopyPlane(dpy, (random() & 1) ? down : front, window, fg_gc,
-                  0, 0, 64, 64, x, y, 1L);
+       COPY(dpy, (random() & 1) ? down : front, window, fg_gc,
+            0, 0, 64, 64, x, y);
        return 1000L;
     }
     if (!(random() % 5))
        return 0;
     if (random() % 3)
     {
-       XCopyPlane(dpy, (random() & 1) ? left_front : right_front,
-                  window, fg_gc, 0, 0, 64, 64, x, y, 1L);
+       COPY(dpy, (random() & 1) ? left_front : right_front,
+            window, fg_gc, 0, 0, 64, 64, x, y);
        return 1000L;
     }
     if (!(random() % 5))
        return 0;
-    XCopyPlane(dpy, (random() & 1) ? left0 : right0, window, fg_gc,
-              0, 0, 64, 64, x, y, 1L);
+    COPY(dpy, (random() & 1) ? left1 : right1, window, fg_gc,
+        0, 0, 64, 64, x, y);
     return 1000L;
 }
 
 
 static void
-init_words()
+init_words (void)
 {
   char *mode = get_string_resource ("mode", "Mode");
 
@@ -449,8 +491,10 @@ init_words()
   words = get_words(); 
 }
 
+static int first_time = 1;
+
 static char *
-get_words()
+get_words (void)
 {
     FILE           *pp;
     static char     buf[BUFSIZ];
@@ -461,7 +505,8 @@ get_words()
     switch (getwordsfrom)
     {
     case FROM_PROGRAM:
-       if (pp = popen(program, "r"))
+#ifndef VMS
+       if ((pp = popen(program, "r")))
        {
            while (fgets(p, sizeof(buf) - strlen(buf), pp))
            {
@@ -473,6 +518,30 @@ get_words()
            (void) pclose(pp);
            if (! buf[0])
              sprintf (buf, "\"%s\" produced no output!", orig_program);
+           else if (!first_time &&
+                    (strstr (buf, ": not found") ||
+                     strstr (buf, ": Not found") ||
+                      strstr (buf, ": command not found") ||
+                      strstr (buf, ": Command not found")))
+             switch (random () % 20)
+               {
+               case 1: strcat (buf, "( Get with the program, bub. )\n");
+                 break;
+               case 2: strcat (buf,
+                 "( I blow my nose at you, you silly person! ) \n"); break;
+               case 3: strcat (buf,
+                 "\nThe resource you want to\nset is `noseguy.program'\n");
+                 break;
+               case 4:
+                 strcat(buf,"\nHelp!!  Help!!\nAAAAAAGGGGHHH!!  \n\n"); break;
+               case 5: strcpy (buf, "You have new mail.\n"); break;
+               case 6:
+                 strcat(buf,"( Hello?  Are you paying attention? )\n");break;
+               case 7:
+                 strcat (buf, "sh: what kind of fool do you take me for? \n");
+                 break;
+               }
+           first_time = 0;
            p = buf;
        }
        else
@@ -481,8 +550,9 @@ get_words()
            p = def_words;
        }
        break;
+#endif /* VMS */
     case FROM_FILE:
-       if (pp = fopen(filename, "r"))
+       if ((pp = fopen(filename, "r")))
        {
            while (fgets(p, sizeof(buf) - strlen(buf), pp))
            {
@@ -520,10 +590,14 @@ get_words()
 char *progclass = "Noseguy";
 
 char *defaults [] = {
-  "*background:                black",
-  "*foreground:                white",
+  ".background:                black",
+  ".foreground:                gray80",
+#ifndef VMS
   "*mode:              program",
-  "*program:           fortune -s",
+#else
+  "*mode:              string",
+#endif
+  "*program:           " FORTUNE_PROGRAM,
   "noseguy.font:       -*-new century schoolbook-*-r-*-*-*-180-*-*-*-*-*-*",
   0
 };
@@ -535,17 +609,15 @@ XrmOptionDescRec options [] = {
   { "-filename",       ".filename",            XrmoptionSepArg, 0 },
   { "-font",           ".font",                XrmoptionSepArg, 0 },
   { "-text-foreground",        ".textForeground",      XrmoptionSepArg, 0 },
-  { "-text-background",        ".textBackground",      XrmoptionSepArg, 0 }
+  { "-text-background",        ".textBackground",      XrmoptionSepArg, 0 },
+  { 0, 0, 0, 0 }
 };
-int options_size = (sizeof (options) / sizeof (options[0]));
 
 
 static void
-noseguy_init (d, w)
-     Display *d;
-     Window w;
+noseguy_init (Display *d, Window w)
 {
-  Pixel fg, bg, text_fg, text_bg;
+  unsigned long fg, bg, text_fg, text_bg;
   XWindowAttributes xgwa;
   Colormap cmap;
   char *fontname = get_string_resource ("font", "Font");
@@ -566,7 +638,7 @@ noseguy_init (d, w)
     {
        list = XListFonts(dpy, FONT_NAME, 32767, &foo);
        for (i = 0; i < foo; i++)
-           if (font = XLoadQueryFont(dpy, list[i]))
+           if ((font = XLoadQueryFont(dpy, list[i])))
                break;
        if (!font)
          {
@@ -614,16 +686,15 @@ noseguy_init (d, w)
 }
      
 void
-screenhack (d, w)
-     Display *d;
-     Window w;
+screenhack (Display *d, Window w)
 {
   noseguy_init (d, w);
   next_fn = move;
   while (1)
     {
-      next_fn (0);
-      XSync (dpy, True);
+      next_fn();
+      XSync (dpy, False);
+      screenhack_handle_events (dpy);
       usleep (interval * 1000);
     }
 }