From http://www.jwz.org/xscreensaver/xscreensaver-5.30.tar.gz
[xscreensaver] / hacks / noseguy.c
index 32b09e251ef91996baca957a49bb03989680f5f8..2e0782714791f302c92ad72e3963c63b8c3e3f09 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992-2012 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992-2014 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
@@ -37,7 +37,6 @@ struct state {
   Pixmap left1, left2, right1, right2;
   Pixmap left_front, right_front, front, down;
 
-  char *program;
   text_data *tc;
 
   int state;   /* indicates states: walking or getting passwd */
@@ -329,6 +328,7 @@ think (struct state *st)
 }
 
 #define MAXLINES 10
+#define LINELEN 256
 
 static void
 talk (struct state *st, int force_erase)
@@ -339,7 +339,7 @@ talk (struct state *st, int force_erase)
                     total = 0;
     register char  *p,
                    *p2;
-    char            args[MAXLINES][256];
+    char            args[MAXLINES][LINELEN];
 
     /* clear what we've written */
     if (st->talking || force_erase)
@@ -361,9 +361,15 @@ talk (struct state *st, int force_erase)
        }
        return;
     }
+    p = st->words;
+    /* If there is actually no words, just return */
+    if (!*p)
+    {
+      st->talking = 0;
+      return;
+    }
     st->talking = 1;
     walk(st, FRONT);
-    p = st->words;
 
     for (p2 = p; *p2; p2++)
       if (*p2 == '\t') *p2 = ' ';
@@ -371,7 +377,8 @@ talk (struct state *st, int force_erase)
     if (!(p2 = strchr(p, '\n')) || !p2[1])
       {
        total = strlen (st->words);
-       strcpy (args[0], st->words);
+       strncpy (args[0], st->words, LINELEN);
+       args[0][LINELEN - 1] = 0;
        width = XTextWidth(st->font, st->words, total);
        height = 0;
       }
@@ -385,7 +392,8 @@ talk (struct state *st, int force_erase)
            width = w;
          total += p2 - p;      /* total chars; count to determine reading
                                 * time */
-         (void) strcpy(args[height], p);
+         (void) strncpy(args[height], p, LINELEN);
+         args[height][LINELEN - 1] = 0;
          if (height == MAXLINES - 1)
            {
              /* puts("Message too long!"); */
@@ -431,7 +439,8 @@ talk (struct state *st, int force_erase)
     for (Z = 0; Z < height; Z++)
     {
         int L = strlen(args[Z]);
-        if (args[Z][L-1] == '\r' || args[Z][L-1] == '\n')
+        /* If there are continuous new lines, L can be 0 */
+        if (L && (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);
@@ -480,18 +489,28 @@ static void
 fill_words (struct state *st)
 {
   char *p = st->words + strlen(st->words);
+  char *c;
+  int lines = 0;
+  int max = MAXLINES;
+
+  for (c = st->words; c < p; c++)
+    if (*c == '\n')
+      lines++;
+
   while (p < st->words + sizeof(st->words) - 1 &&
-         st->lines < MAXLINES)
+         lines < max)
     {
-      char c = textclient_getc (st->tc);
+      int c = textclient_getc (st->tc);
       if (c == '\n')
-        st->lines++;
+        lines++;
       if (c > 0)
-        *p++ = c;
+        *p++ = (char) c;
       else
         break;
     }
   *p = 0;
+
+  st->lines = lines;
 }
 
 
@@ -502,7 +521,7 @@ static const char *noseguy_defaults [] = {
   "*textForeground: black",
   "*textBackground: #CCCCCC",
   "*fpsSolid:   true",
-  "*program:    xscreensaver-text --cols 40 | head -n15",
+  "*program:    xscreensaver-text",
   "*usePty:      False",
   ".font:       -*-new century schoolbook-*-r-*-*-*-180-*-*-*-*-*-*",
   0
@@ -536,8 +555,15 @@ noseguy_init (Display *d, Window w)
   st->Height = xgwa.height + 2;
   cmap = xgwa.colormap;
 
-  st->program = get_string_resource (st->dpy, "program", "Program");
   st->tc = textclient_open (st->dpy);
+  {
+    int w = 40;
+    int h = 15;
+    textclient_reshape (st->tc, w, h, w, h,
+                        /* Passing MAXLINES isn't actually necessary */
+                        0);
+  }
+
   init_images(st);
 
   if (!fontname || !*fontname)