X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fnoseguy.c;h=f6502bef5621059f5214e5291c52bf0debcfd939;hp=594d7462e3d3b961e5a1713a6fcceafe9fef4b89;hb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;hpb=ccb7f4903325f92555a9722bba74b58346654ba0 diff --git a/hacks/noseguy.c b/hacks/noseguy.c index 594d7462..f6502bef 100644 --- a/hacks/noseguy.c +++ b/hacks/noseguy.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1992, 1996, 1997, 1998, 2005 +/* xscreensaver, Copyright (c) 1992, 1996, 1997, 1998, 2005, 2006 * Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its @@ -19,30 +19,57 @@ #include "xpm-pixmap.h" #include +#ifdef HAVE_COCOA +# define HAVE_XPM +#endif + extern FILE *popen (const char *, const char *); extern int pclose (FILE *); #define font_height(font) (font->ascent + font->descent) -#define FONT_NAME "-*-times-*-*-*-*-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; -static char *get_words (void); -static int x, y; -static XFontStruct *font; -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; + + +struct state { + Display *dpy; + Window window; + int Width, Height; + GC fg_gc, bg_gc, text_fg_gc, text_bg_gc; + char *words; + int x, y; + XFontStruct *font; + + unsigned long interval; + Pixmap left1, left2, right1, right2; + Pixmap left_front, right_front, front, down; + + char *program, *orig_program; + + int state; /* indicates states: walking or getting passwd */ + int first_time; + + void (*next_fn) (struct state *); + + int move_length, move_dir; + + int walk_lastdir; + int walk_up; + Pixmap walk_frame; + + int X, Y, talking; + + struct { + int x, y, width, height; + } s_rect; + + char word_buf[BUFSIZ]; +}; + +static char *get_words (struct state *); +static void walk (struct state *, int dir); +static void talk (struct state *, int erase); +static void talk_1 (struct state *); +static int think (struct state *); +static unsigned long look (struct state *); #define FROM_ARGV 1 #define FROM_PROGRAM 2 @@ -51,9 +78,6 @@ static char *program, *orig_program, *filename, *text; #define IS_MOVING 1 #define GET_PASSWD 2 -static int state; /* indicates states: walking or getting passwd */ - -static void (*next_fn) (void); #if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) # include "images/noseguy/nose-f1.xpm" @@ -76,24 +100,40 @@ static void (*next_fn) (void); #endif static void -init_images (void) +init_images (struct state *st) { - static Pixmap *images[] = { - &left1, &left2, &right1, &right2, - &left_front, &right_front, &front, &down - }; - int i; + Pixmap *images[8]; #if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) + char **bits[8]; +#else + unsigned char *bits[8]; +#endif + + int i = 0; + images[i++] = &st->left1; + images[i++] = &st->left2; + images[i++] = &st->right1; + images[i++] = &st->right2; + images[i++] = &st->left_front; + images[i++] = &st->right_front; + images[i++] = &st->front; + images[i++] = &st->down; - 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 - }; +#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) + i = 0; + bits[i++] = nose_l1_xpm; + bits[i++] = nose_l2_xpm; + bits[i++] = nose_r1_xpm; + bits[i++] = nose_r2_xpm; + bits[i++] = nose_f2_xpm; + bits[i++] = nose_f3_xpm; + bits[i++] = nose_f1_xpm; + bits[i++] = nose_f4_xpm; for (i = 0; i < sizeof (images) / sizeof(*images); i++) { - Pixmap pixmap = xpm_data_to_pixmap (dpy, window, bits[i], + Pixmap pixmap = xpm_data_to_pixmap (st->dpy, st->window, bits[i], 0, 0, 0); if (!pixmap) { @@ -103,14 +143,19 @@ init_images (void) *images[i] = pixmap; } #else - static unsigned char *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 - }; + i = 0; + bits[i++] = nose_l1_bits; + bits[i++] = nose_l2_bits; + bits[i++] = nose_r1_bits; + bits[i++] = nose_r2_bits; + bits[i++] = nose_f2_bits; + bits[i++] = nose_f3_bits; + bits[i++] = nose_f1_bits; + bits[i++] = nose_f4_bits; for (i = 0; i < sizeof (images) / sizeof(*images); i++) if (!(*images[i] = - XCreatePixmapFromBitmapData(dpy, window, + XCreatePixmapFromBitmapData(st->dpy, st->window, (char *) bits[i], 64, 64, 1, 0, 1))) { fprintf (stderr, "%s: Can't load nose images\n", progname); @@ -128,78 +173,75 @@ init_images (void) #define Y_INCR 2 static void -move (void) +move (struct state *st) { - static int length, - dir; - - if (!length) + if (!st->move_length) { register int tries = 0; - dir = 0; - if ((random() & 1) && think()) + st->move_dir = 0; + if ((random() & 1) && think(st)) { - talk(0); /* sets timeout to itself */ + talk(st, 0); /* sets timeout to itself */ return; } - if (!(random() % 3) && (interval = look())) + if (!(random() % 3) && (st->interval = look(st))) { - next_fn = move; + st->next_fn = move; return; } - interval = 20 + random() % 100; + st->interval = 20 + random() % 100; do { if (!tries) - length = Width / 100 + random() % 90, tries = 8; + st->move_length = st->Width / 100 + random() % 90, tries = 8; else tries--; switch (random() % 8) { case 0: - if (x - X_INCR * length >= 5) - dir = LEFT; + if (st->x - X_INCR * st->move_length >= 5) + st->move_dir = LEFT; break; case 1: - if (x + X_INCR * length <= Width - 70) - dir = RIGHT; + if (st->x + X_INCR * st->move_length <= st->Width - 70) + st->move_dir = RIGHT; break; case 2: - if (y - (Y_INCR * length) >= 5) - dir = UP, interval = 40; + if (st->y - (Y_INCR * st->move_length) >= 5) + st->move_dir = UP, st->interval = 40; break; case 3: - if (y + Y_INCR * length <= Height - 70) - dir = DOWN, interval = 20; + if (st->y + Y_INCR * st->move_length <= st->Height - 70) + st->move_dir = DOWN, st->interval = 20; break; case 4: - if (x - X_INCR * length >= 5 && y - (Y_INCR * length) >= 5) - dir = (LEFT | UP); + if (st->x - X_INCR * st->move_length >= 5 && st->y - (Y_INCR * st->move_length) >= 5) + st->move_dir = (LEFT | UP); break; case 5: - if (x + X_INCR * length <= Width - 70 && - y - Y_INCR * length >= 5) - dir = (RIGHT | UP); + if (st->x + X_INCR * st->move_length <= st->Width - 70 && + st->y - Y_INCR * st->move_length >= 5) + st->move_dir = (RIGHT | UP); break; case 6: - if (x - X_INCR * length >= 5 && - y + Y_INCR * length <= Height - 70) - dir = (LEFT | DOWN); + if (st->x - X_INCR * st->move_length >= 5 && + st->y + Y_INCR * st->move_length <= st->Height - 70) + st->move_dir = (LEFT | DOWN); break; case 7: - if (x + X_INCR * length <= Width - 70 && - y + Y_INCR * length <= Height - 70) - dir = (RIGHT | DOWN); + if (st->x + X_INCR * st->move_length <= st->Width - 70 && + st->y + Y_INCR * st->move_length <= st->Height - 70) + st->move_dir = (RIGHT | DOWN); break; default: /* No Defaults */ break; } - } while (!dir); + } while (!st->move_dir); } - walk(dir); - --length; - next_fn = move; + walk(st, st->move_dir); + --st->move_length; + st->next_fn = move; } #ifdef HAVE_XPM @@ -211,82 +253,76 @@ move (void) #endif static void -walk(int dir) +walk (struct state *st, int dir) { register int incr = 0; - static int lastdir; - static int up = 1; - static Pixmap frame; if (dir & (LEFT | RIGHT)) - { /* left/right movement (mabye up/down too) */ - up = -up; /* bouncing effect (even if hit a wall) */ + { /* left/right movement (mabye up/st->down too) */ + st->walk_up = -st->walk_up; /* bouncing effect (even if hit a wall) */ if (dir & LEFT) { incr = X_INCR; - frame = (up < 0) ? left1 : left2; + st->walk_frame = (st->walk_up < 0) ? st->left1 : st->left2; } else { incr = -X_INCR; - frame = (up < 0) ? right1 : right2; + st->walk_frame = (st->walk_up < 0) ? st->right1 : st->right2; } - if ((lastdir == FRONT || lastdir == DOWN) && dir & UP) + if ((st->walk_lastdir == FRONT || st->walk_lastdir == DOWN) && dir & UP) { /* * workaround silly bug that leaves screen dust when guy is - * facing forward or down and moves up-left/right. + * facing forward or st->down and moves up-left/right. */ - COPY(dpy, frame, window, fg_gc, 0, 0, 64, 64, x, y); - XFlush(dpy); + COPY(st->dpy, st->walk_frame, st->window, st->fg_gc, 0, 0, 64, 64, st->x, st->y); } /* note that maybe neither UP nor DOWN is set! */ - if (dir & UP && y > Y_INCR) - y -= Y_INCR; - else if (dir & DOWN && y < Height - 64) - y += Y_INCR; + if (dir & UP && st->y > Y_INCR) + st->y -= Y_INCR; + else if (dir & DOWN && st->y < st->Height - 64) + st->y += Y_INCR; } - /* Explicit up/down movement only (no left/right) */ + /* Explicit up/st->down movement only (no left/right) */ else if (dir == UP) - COPY(dpy, front, window, fg_gc, 0, 0, 64, 64, x, y -= Y_INCR); + COPY(st->dpy, st->front, st->window, st->fg_gc, 0, 0, 64, 64, st->x, st->y -= Y_INCR); else if (dir == DOWN) - COPY(dpy, down, window, fg_gc, 0, 0, 64, 64, x, y += Y_INCR); - else if (dir == FRONT && frame != front) + COPY(st->dpy, st->down, st->window, st->fg_gc, 0, 0, 64, 64, st->x, st->y += Y_INCR); + else if (dir == FRONT && st->walk_frame != st->front) { - if (up > 0) - up = -up; - if (lastdir & LEFT) - frame = left_front; - else if (lastdir & RIGHT) - frame = right_front; + if (st->walk_up > 0) + st->walk_up = -st->walk_up; + if (st->walk_lastdir & LEFT) + st->walk_frame = st->left_front; + else if (st->walk_lastdir & RIGHT) + st->walk_frame = st->right_front; else - frame = front; - COPY(dpy, frame, window, fg_gc, 0, 0, 64, 64, x, y); + st->walk_frame = st->front; + COPY(st->dpy, st->walk_frame, st->window, st->fg_gc, 0, 0, 64, 64, st->x, st->y); } if (dir & LEFT) while (--incr >= 0) { - COPY(dpy, frame, window, fg_gc, 0, 0, 64, 64, --x, y + up); - XFlush(dpy); + COPY(st->dpy, st->walk_frame, st->window, st->fg_gc, 0, 0, 64, 64, --st->x, st->y + st->walk_up); } else if (dir & RIGHT) while (++incr <= 0) { - COPY(dpy, frame, window, fg_gc, 0, 0, 64, 64, ++x, y + up); - XFlush(dpy); + COPY(st->dpy, st->walk_frame, st->window, st->fg_gc, 0, 0, 64, 64, ++st->x, st->y + st->walk_up); } - lastdir = dir; + st->walk_lastdir = dir; } static int -think (void) +think (struct state *st) { if (random() & 1) - walk(FRONT); + walk(st, FRONT); if (random() & 1) { - words = get_words(); + st->words = get_words(st); return 1; } return 0; @@ -299,59 +335,49 @@ think (void) static void -talk(int force_erase) +talk (struct state *st, int force_erase) { int width = 0, height, Z, total = 0; - static int X, - Y, - talking; - static struct - { - int x, - y, - width, - height; - } s_rect; register char *p, *p2; char buf[BUFSIZ], args[MAXLINES][256]; /* clear what we've written */ - if (talking || force_erase) + if (st->talking || force_erase) { - if (!talking) + if (!st->talking) return; - XFillRectangle(dpy, window, bg_gc, s_rect.x - 5, s_rect.y - 5, - s_rect.width + 10, s_rect.height + 10); - talking = 0; + XFillRectangle(st->dpy, st->window, st->bg_gc, st->s_rect.x - 5, st->s_rect.y - 5, + st->s_rect.width + 10, st->s_rect.height + 10); + st->talking = 0; if (!force_erase) - next_fn = move; - interval = 0; + st->next_fn = move; + st->interval = 0; { - /* might as well check the window for size changes now... */ + /* might as well check the st->window for size changes now... */ XWindowAttributes xgwa; - XGetWindowAttributes (dpy, window, &xgwa); - Width = xgwa.width + 2; - Height = xgwa.height + 2; + XGetWindowAttributes (st->dpy, st->window, &xgwa); + st->Width = xgwa.width + 2; + st->Height = xgwa.height + 2; } return; } - talking = 1; - walk(FRONT); - p = strcpy(buf, words); + st->talking = 1; + walk(st, FRONT); + p = strcpy(buf, st->words); for (p2 = p; *p2; p2++) if (*p2 == '\t') *p2 = ' '; if (!(p2 = strchr(p, '\n')) || !p2[1]) { - total = strlen (words); - strcpy (args[0], words); - width = XTextWidth(font, words, total); + total = strlen (st->words); + strcpy (args[0], st->words); + width = XTextWidth(st->font, st->words, total); height = 0; } else @@ -360,7 +386,7 @@ talk(int force_erase) { int w; *p2 = 0; - if ((w = XTextWidth(font, p, p2 - p)) > width) + if ((w = XTextWidth(st->font, p, p2 - p)) > width) width = w; total += p2 - p; /* total chars; count to determine reading * time */ @@ -380,146 +406,145 @@ talk(int force_erase) * Figure out the height and width in pixels (height, width) extend the * new box by 15 pixels on the sides (30 total) top and bottom. */ - s_rect.width = width + 30; - s_rect.height = height * font_height(font) + 30; - if (x - s_rect.width - 10 < 5) - s_rect.x = 5; - else if ((s_rect.x = x + 32 - (s_rect.width + 15) / 2) - + s_rect.width + 15 > Width - 5) - s_rect.x = Width - 15 - s_rect.width; - if (y - s_rect.height - 10 < 5) - s_rect.y = y + 64 + 5; + st->s_rect.width = width + 30; + st->s_rect.height = height * font_height(st->font) + 30; + if (st->x - st->s_rect.width - 10 < 5) + st->s_rect.x = 5; + else if ((st->s_rect.x = st->x + 32 - (st->s_rect.width + 15) / 2) + + st->s_rect.width + 15 > st->Width - 5) + st->s_rect.x = st->Width - 15 - st->s_rect.width; + if (st->y - st->s_rect.height - 10 < 5) + st->s_rect.y = st->y + 64 + 5; else - s_rect.y = y - 5 - s_rect.height; + st->s_rect.y = st->y - 5 - st->s_rect.height; - XFillRectangle(dpy, window, text_bg_gc, - s_rect.x, s_rect.y, s_rect.width, s_rect.height); + XFillRectangle(st->dpy, st->window, st->text_bg_gc, + st->s_rect.x, st->s_rect.y, st->s_rect.width, st->s_rect.height); /* make a box that's 5 pixels thick. Then add a thin box inside it */ - XSetLineAttributes(dpy, text_fg_gc, 5, 0, 0, 0); - XDrawRectangle(dpy, window, text_fg_gc, - s_rect.x, s_rect.y, s_rect.width - 1, s_rect.height - 1); - XSetLineAttributes(dpy, text_fg_gc, 0, 0, 0, 0); - XDrawRectangle(dpy, window, text_fg_gc, - s_rect.x + 7, s_rect.y + 7, s_rect.width - 15, s_rect.height - 15); + XSetLineAttributes(st->dpy, st->text_fg_gc, 5, 0, 0, 0); + XDrawRectangle(st->dpy, st->window, st->text_fg_gc, + st->s_rect.x, st->s_rect.y, st->s_rect.width - 1, st->s_rect.height - 1); + XSetLineAttributes(st->dpy, st->text_fg_gc, 0, 0, 0, 0); + XDrawRectangle(st->dpy, st->window, st->text_fg_gc, + st->s_rect.x + 7, st->s_rect.y + 7, st->s_rect.width - 15, st->s_rect.height - 15); - X = 15; - Y = 15 + font_height(font); + st->X = 15; + st->Y = 15 + font_height(st->font); /* now print each string in reverse order (start at bottom of box) */ for (Z = 0; Z < height; Z++) { - XDrawString(dpy, window, text_fg_gc, s_rect.x + X, s_rect.y + Y, - args[Z], strlen(args[Z])); - Y += font_height(font); + int L = strlen(args[Z]); + if (args[Z][L-1] == '\r' || args[Z][L-1] == '\n') + args[Z][--L] = 0; + XDrawString(st->dpy, st->window, st->text_fg_gc, st->s_rect.x + st->X, st->s_rect.y + st->Y, + args[Z], L); + st->Y += font_height(st->font); } - interval = (total / 15) * 1000; - if (interval < 2000) interval = 2000; - next_fn = talk_1; + st->interval = (total / 15) * 1000; + if (st->interval < 2000) st->interval = 2000; + st->next_fn = talk_1; } -static void talk_1 (void) +static void +talk_1 (struct state *st) { - talk(0); + talk(st, 0); } static unsigned long -look (void) +look (struct state *st) { if (random() % 3) { - COPY(dpy, (random() & 1) ? down : front, window, fg_gc, - 0, 0, 64, 64, x, y); + COPY(st->dpy, (random() & 1) ? st->down : st->front, st->window, st->fg_gc, + 0, 0, 64, 64, st->x, st->y); return 1000L; } if (!(random() % 5)) return 0; if (random() % 3) { - COPY(dpy, (random() & 1) ? left_front : right_front, - window, fg_gc, 0, 0, 64, 64, x, y); + COPY(st->dpy, (random() & 1) ? st->left_front : st->right_front, + st->window, st->fg_gc, 0, 0, 64, 64, st->x, st->y); return 1000L; } if (!(random() % 5)) return 0; - COPY(dpy, (random() & 1) ? left1 : right1, window, fg_gc, - 0, 0, 64, 64, x, y); + COPY(st->dpy, (random() & 1) ? st->left1 : st->right1, st->window, st->fg_gc, + 0, 0, 64, 64, st->x, st->y); return 1000L; } static void -init_words (void) +init_words (struct state *st) { - program = get_string_resource ("program", "Program"); - filename = get_string_resource ("filename", "Filename"); - text = get_string_resource ("text", "Text"); + st->program = get_string_resource (st->dpy, "program", "Program"); - if (program) /* get stderr on stdout, so it shows up on the window */ + if (st->program) /* get stderr on stdout, so it shows up on the window */ { - orig_program = program; - program = (char *) malloc (strlen (program) + 10); - strcpy (program, "( "); - strcat (program, orig_program); - strcat (program, " ) 2>&1"); + st->orig_program = st->program; + st->program = (char *) malloc (strlen (st->program) + 10); + strcpy (st->program, "( "); + strcat (st->program, st->orig_program); + strcat (st->program, " ) 2>&1"); } - words = get_words(); + st->words = get_words(st); } -static int first_time = 1; - static char * -get_words (void) +get_words (struct state *st) { FILE *pp; - static char buf[BUFSIZ]; - register char *p = buf; + register char *p = st->word_buf; - buf[0] = '\0'; + st->word_buf[0] = '\0'; - if ((pp = popen(program, "r"))) + if ((pp = popen(st->program, "r"))) { - while (fgets(p, sizeof(buf) - strlen(buf), pp)) + while (fgets(p, sizeof(st->word_buf) - strlen(st->word_buf), pp)) { - if (strlen(buf) + 1 < sizeof(buf)) - p = buf + strlen(buf); + if (strlen(st->word_buf) + 1 < sizeof(st->word_buf)) + p = st->word_buf + strlen(st->word_buf); else break; } (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"))) + if (! st->word_buf[0]) + sprintf (st->word_buf, "\"%s\" produced no output!", st->orig_program); + else if (!st->first_time && + (strstr (st->word_buf, ": not found") || + strstr (st->word_buf, ": Not found") || + strstr (st->word_buf, ": command not found") || + strstr (st->word_buf, ": Command not found"))) switch (random () % 20) { - case 1: strcat (buf, "( Get with the program, bub. )\n"); + case 1: strcat (st->word_buf, "( Get with the st->program, bub. )\n"); break; - case 2: strcat (buf, + case 2: strcat (st->word_buf, "( I blow my nose at you, you silly person! ) \n"); break; - case 3: strcat (buf, + case 3: strcat (st->word_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; + strcat(st->word_buf,"\nHelp!! Help!!\nAAAAAAGGGGHHH!! \n\n"); break; + case 5: strcpy (st->word_buf, "You have new mail.\n"); break; case 6: - strcat(buf,"( Hello? Are you paying attention? )\n");break; + strcat(st->word_buf,"( Hello? Are you paying attention? )\n");break; case 7: - strcat (buf, "sh: what kind of fool do you take me for? \n"); + strcat (st->word_buf, "sh: what kind of fool do you take me for? \n"); break; } - first_time = 0; - p = buf; + st->first_time = 0; + p = st->word_buf; } else { - perror(program); + perror(st->program); } return p; @@ -527,21 +552,18 @@ get_words (void) -char *progclass = "Noseguy"; - -char *defaults [] = { - ".background: black", - ".foreground: gray80", +static const char *noseguy_defaults [] = { + ".background: black", + ".foreground: #CCCCCC", + "*textForeground: black", + "*textBackground: #CCCCCC", "*program: xscreensaver-text --cols 40 | head -n15", - "noseguy.font: -*-new century schoolbook-*-r-*-*-*-180-*-*-*-*-*-*", + ".font: -*-new century schoolbook-*-r-*-*-*-180-*-*-*-*-*-*", 0 }; -XrmOptionDescRec options [] = { - { "-mode", ".mode", XrmoptionSepArg, 0 }, +static XrmOptionDescRec noseguy_options [] = { { "-program", ".program", XrmoptionSepArg, 0 }, - { "-text", ".text", XrmoptionSepArg, 0 }, - { "-filename", ".filename", XrmoptionSepArg, 0 }, { "-font", ".font", XrmoptionSepArg, 0 }, { "-text-foreground", ".textForeground", XrmoptionSepArg, 0 }, { "-text-background", ".textBackground", XrmoptionSepArg, 0 }, @@ -549,88 +571,96 @@ XrmOptionDescRec options [] = { }; -static void +static void * noseguy_init (Display *d, Window w) { + struct state *st = (struct state *) calloc (1, sizeof(*st)); unsigned long fg, bg, text_fg, text_bg; XWindowAttributes xgwa; Colormap cmap; - char *fontname = get_string_resource ("font", "Font"); - char **list; - int foo, i; + char *fontname; XGCValues gcvalues; - dpy = d; - window = w; - XGetWindowAttributes (dpy, window, &xgwa); - Width = xgwa.width + 2; - Height = xgwa.height + 2; + st->dpy = d; + st->window = w; + st->first_time = 1; + + fontname = get_string_resource (st->dpy, "font", "Font"); + XGetWindowAttributes (st->dpy, st->window, &xgwa); + st->Width = xgwa.width + 2; + st->Height = xgwa.height + 2; cmap = xgwa.colormap; - init_words(); - init_images(); + init_words(st); + init_images(st); - if (!fontname || !(font = XLoadQueryFont(dpy, fontname))) - { - list = XListFonts(dpy, FONT_NAME, 32767, &foo); - for (i = 0; i < foo; i++) - if ((font = XLoadQueryFont(dpy, list[i]))) - break; - if (!font) - { - fprintf (stderr, "%s: Can't find a large font.", progname); - exit (1); - } - XFreeFontNames(list); - } + if (!fontname || !*fontname) + fprintf (stderr, "%s: no font specified.\n", progname); + st->font = XLoadQueryFont(st->dpy, fontname); + if (!st->font) + fprintf (stderr, "%s: could not load font %s.\n", progname, fontname); - fg = get_pixel_resource ("foreground", "Foreground", dpy, cmap); - bg = get_pixel_resource ("background", "Background", dpy, cmap); - text_fg = get_pixel_resource ("textForeground", "Foreground", dpy, cmap); - text_bg = get_pixel_resource ("textBackground", "Background", dpy, cmap); + fg = get_pixel_resource (st->dpy, cmap, "foreground", "Foreground"); + bg = get_pixel_resource (st->dpy, cmap, "background", "Background"); + text_fg = get_pixel_resource (st->dpy, cmap, "textForeground", "Foreground"); + text_bg = get_pixel_resource (st->dpy, cmap, "textBackground", "Background"); /* notice when unspecified */ - if (! get_string_resource ("textForeground", "Foreground")) + if (! get_string_resource (st->dpy, "textForeground", "Foreground")) text_fg = bg; - if (! get_string_resource ("textBackground", "Background")) + if (! get_string_resource (st->dpy, "textBackground", "Background")) text_bg = fg; - gcvalues.font = font->fid; - gcvalues.graphics_exposures = False; + gcvalues.font = st->font->fid; gcvalues.foreground = fg; gcvalues.background = bg; - fg_gc = XCreateGC (dpy, window, - GCForeground|GCBackground|GCGraphicsExposures|GCFont, + st->fg_gc = XCreateGC (st->dpy, st->window, + GCForeground|GCBackground|GCFont, &gcvalues); gcvalues.foreground = bg; gcvalues.background = fg; - bg_gc = XCreateGC (dpy, window, - GCForeground|GCBackground|GCGraphicsExposures|GCFont, + st->bg_gc = XCreateGC (st->dpy, st->window, + GCForeground|GCBackground|GCFont, &gcvalues); gcvalues.foreground = text_fg; gcvalues.background = text_bg; - text_fg_gc = XCreateGC (dpy, window, - GCForeground|GCBackground|GCGraphicsExposures|GCFont, + st->text_fg_gc = XCreateGC (st->dpy, st->window, + GCForeground|GCBackground|GCFont, &gcvalues); gcvalues.foreground = text_bg; gcvalues.background = text_fg; - text_bg_gc = XCreateGC (dpy, window, - GCForeground|GCBackground|GCGraphicsExposures|GCFont, + st->text_bg_gc = XCreateGC (st->dpy, st->window, + GCForeground|GCBackground|GCFont, &gcvalues); - x = Width / 2; - y = Height / 2; - state = IS_MOVING; + st->x = st->Width / 2; + st->y = st->Height / 2; + st->state = IS_MOVING; + st->next_fn = move; + st->walk_up = 1; + return st; } -void -screenhack (Display *d, Window w) +static unsigned long +noseguy_draw (Display *dpy, Window window, void *closure) +{ + struct state *st = (struct state *) closure; + st->next_fn(st); + return (st->interval * 1000); +} + +static void +noseguy_reshape (Display *dpy, Window window, void *closure, + unsigned int w, unsigned int h) +{ +} + +static Bool +noseguy_event (Display *dpy, Window window, void *closure, XEvent *event) +{ + return False; +} + +static void +noseguy_free (Display *dpy, Window window, void *closure) { - noseguy_init (d, w); - next_fn = move; - while (1) - { - next_fn(); - XSync (dpy, False); - screenhack_handle_events (dpy); - usleep (interval * 1000); - } } +XSCREENSAVER_MODULE ("NoseGuy", noseguy)