-/* xscreensaver, Copyright (c) 1992 Jamie Zawinski <jwz@netscape.com>
+/* xscreensaver, Copyright (c) 1992, 1996, 1997, 1998, 2005
+ * 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-*-*-*-*-*-*-*"
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;
#define FROM_PROGRAM 2
#define FROM_FILE 3
#define FROM_RESRC 4
-static int getwordsfrom;
#define IS_MOVING 1
#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
#define Y_INCR 2
static void
-move()
+move (void)
{
static int length,
dir;
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;
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)
{
* 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! */
}
/* 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)
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);
- return 1;
+ words = get_words();
+ return 1;
}
return 0;
}
-#define MAXLINES 40
+#define MAXLINES 25
+
+#undef BUFSIZ
+#define BUFSIZ ((MAXLINES + 1) * 100)
+
static void
-talk(force_erase)
- int force_erase;
+talk(int force_erase)
{
int width = 0,
height,
walk(FRONT);
p = strcpy(buf, words);
- if (!(p2 = index(p, '\n')) || !p2[1])
+ for (p2 = p; *p2; p2++)
+ if (*p2 == '\t') *p2 = ' ';
+
+ if (!(p2 = strchr(p, '\n')) || !p2[1])
{
total = strlen (words);
strcpy (args[0], words);
(void) strcpy(args[height], p);
if (height == MAXLINES - 1)
{
- puts("Message too long!");
+ /* puts("Message too long!"); */
break;
}
p = p2 + 1;
- if (!(p2 = index(p, '\n')))
+ if (!(p2 = strchr(p, '\n')))
break;
}
height++;
}
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");
-
program = get_string_resource ("program", "Program");
filename = get_string_resource ("filename", "Filename");
text = get_string_resource ("text", "Text");
strcat (program, " ) 2>&1");
}
- if (!mode || !strcmp (mode, "program"))
- getwordsfrom = FROM_PROGRAM;
- else if (!strcmp (mode, "file"))
- getwordsfrom = FROM_FILE;
- else if (!strcmp (mode, "string"))
- getwordsfrom = FROM_RESRC;
- else
- {
- fprintf (stderr,
- "%s: mode must be program, file, or string, not %s\n",
- progname, mode);
- exit (1);
- }
-
- if (getwordsfrom == FROM_PROGRAM && !program)
- {
- fprintf (stderr, "%s: no program specified.\n", progname);
- exit (1);
- }
- if (getwordsfrom == FROM_FILE && !filename)
- {
- fprintf (stderr, "%s: no file specified.\n", progname);
- exit (1);
- }
-
words = get_words();
}
static int first_time = 1;
static char *
-get_words()
+get_words (void)
{
FILE *pp;
static char buf[BUFSIZ];
buf[0] = '\0';
- switch (getwordsfrom)
- {
- case FROM_PROGRAM:
if ((pp = popen(program, "r")))
{
while (fgets(p, sizeof(buf) - strlen(buf), pp))
sprintf (buf, "\"%s\" produced no output!", orig_program);
else if (!first_time &&
(strstr (buf, ": not found") ||
- 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");
else
{
perror(program);
- p = def_words;
- }
- break;
- case FROM_FILE:
- if ((pp = fopen(filename, "r")))
- {
- while (fgets(p, sizeof(buf) - strlen(buf), pp))
- {
- if (strlen(buf) + 1 < sizeof(buf))
- p = buf + strlen(buf);
- else
- break;
- }
- (void) fclose(pp);
- if (! buf[0])
- sprintf (buf, "file \"%s\" is empty!", filename);
- p = buf;
- }
- else
- {
- sprintf (buf, "couldn't read file \"%s\"!", filename);
- p = buf;
}
- break;
- case FROM_RESRC:
- p = text;
- break;
- default:
- p = def_words;
- break;
- }
- if (!p || *p == '\0')
- p = def_words;
return p;
}
char *progclass = "Noseguy";
char *defaults [] = {
- "Noseguy.background: black", /* to placate SGI */
- "Noseguy.foreground: white",
- "*mode: program",
- "*program: fortune -s",
- "noseguy.font: -*-new century schoolbook-*-r-*-*-*-180-*-*-*-*-*-*",
+ ".background: black",
+ ".foreground: gray80",
+ "*program: xscreensaver-text --cols 40 | head -15",
+ "noseguy.font: -*-new century schoolbook-*-r-*-*-*-180-*-*-*-*-*-*",
0
};
{ "-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");
}
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);
}
}