X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fnoseguy.c;h=594d7462e3d3b961e5a1713a6fcceafe9fef4b89;hb=0d6b320def9180cf907ceaed56b23a972a11b757;hp=207311fc3f24207b98c055ab1226cb7afc32485d;hpb=0cac953ce8d5139c1a264b417951ee15a3176b51;p=xscreensaver diff --git a/hacks/noseguy.c b/hacks/noseguy.c index 207311fc..594d7462 100644 --- a/hacks/noseguy.c +++ b/hacks/noseguy.c @@ -1,4 +1,5 @@ -/* xscreensaver, Copyright (c) 1992 Jamie Zawinski +/* xscreensaver, Copyright (c) 1992, 1996, 1997, 1998, 2005 + * Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -10,18 +11,16 @@ */ /* Make a little guy with a big nose and a hat wanter around the screen, - spewing out messages. Derived from xnlock by Dan Heller . + spewing out messages. Derived from xnlock by + Dan Heller . */ #include "screenhack.h" +#include "xpm-pixmap.h" #include -#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,17 @@ 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; @@ -46,45 +48,75 @@ 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 @@ -96,7 +128,7 @@ init_images () #define Y_INCR 2 static void -move() +move (void) { static int length, dir; @@ -170,9 +202,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 +224,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 +238,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 +249,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,44 +262,44 @@ 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); - 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, @@ -307,7 +344,10 @@ talk(force_erase) 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); @@ -327,11 +367,11 @@ talk(force_erase) (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++; @@ -375,39 +415,43 @@ 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"); - program = get_string_resource ("program", "Program"); filename = get_string_resource ("filename", "Filename"); text = get_string_resource ("text", "Text"); @@ -421,38 +465,13 @@ init_words() 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]; @@ -460,10 +479,7 @@ get_words() buf[0] = '\0'; - switch (getwordsfrom) - { - case FROM_PROGRAM: - if (pp = popen(program, "r")) + if ((pp = popen(program, "r"))) { while (fgets(p, sizeof(buf) - strlen(buf), pp)) { @@ -476,7 +492,10 @@ get_words() if (! buf[0]) sprintf (buf, "\"%s\" produced no output!", orig_program); else if (!first_time && - !strcmp (buf, "sh: fortune: not found\n")) + (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"); @@ -501,40 +520,8 @@ get_words() 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; } @@ -543,11 +530,10 @@ get_words() char *progclass = "Noseguy"; char *defaults [] = { - "*background: black", - "*foreground: white", - "*mode: program", - "*program: fortune -s", - "noseguy.font: -*-new century schoolbook-*-r-*-*-*-180-*-*-*-*-*-*", + ".background: black", + ".foreground: gray80", + "*program: xscreensaver-text --cols 40 | head -n15", + "noseguy.font: -*-new century schoolbook-*-r-*-*-*-180-*-*-*-*-*-*", 0 }; @@ -558,17 +544,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"); @@ -589,7 +573,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) { @@ -637,16 +621,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); } }