From http://www.jwz.org/xscreensaver/xscreensaver-5.36.tar.gz
[xscreensaver] / hacks / phosphor.c
index 1238048976d0e3dd6c8eebb1fa36e52f464acdf9..a8469b0a58ac830d1ce1043233005a9c7bcaaf1e 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1999-2014 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1999-2016 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
@@ -78,7 +78,7 @@ typedef struct {
   int escstate;
   int csiparam[NPAR];
   int curparam;
-  int unicruds; char unicrud[7];
+  int unicruds; unsigned char unicrud[7];
 
   p_char **chars;
   p_cell *cells;
@@ -729,6 +729,56 @@ scroll (p_state *state)
 }
 
 
+static int
+process_unicrud (p_state *state, int c)
+{
+  if ((c & 0xE0) == 0xC0) {        /* 110xxxxx: 11 bits, 2 bytes */
+    state->unicruds = 1;
+    state->unicrud[0] = c;
+    state->escstate = 102;
+  } else if ((c & 0xF0) == 0xE0) { /* 1110xxxx: 16 bits, 3 bytes */
+    state->unicruds = 1;
+    state->unicrud[0] = c;
+    state->escstate = 103;
+  } else if ((c & 0xF8) == 0xF0) { /* 11110xxx: 21 bits, 4 bytes */
+    state->unicruds = 1;
+    state->unicrud[0] = c;
+    state->escstate = 104;
+  } else if ((c & 0xFC) == 0xF8) { /* 111110xx: 26 bits, 5 bytes */
+    state->unicruds = 1;
+    state->unicrud[0] = c;
+    state->escstate = 105;
+  } else if ((c & 0xFE) == 0xFC) { /* 1111110x: 31 bits, 6 bytes */
+    state->unicruds = 1;
+    state->unicrud[0] = c;
+    state->escstate = 106;
+  } else if (state->unicruds == 0) {
+    return c;
+  } else {
+    int total = state->escstate - 100;  /* see what I did there */
+    if (state->unicruds < total) {
+      /* Buffer more bytes of the UTF-8 sequence */
+      state->unicrud[state->unicruds++] = c;
+    }
+
+    if (state->unicruds >= total) {
+      /* Done! Convert it to Latin1 and print that. */
+      char *s;
+      state->unicrud[state->unicruds] = 0;
+      s = utf8_to_latin1 ((const char *) state->unicrud, False);
+      state->unicruds = 0;
+      state->escstate = 0;
+      if (s) {
+        c = (unsigned char) s[0];
+        free (s);
+        return c;
+      }
+    }
+  }
+  return 0;
+}
+
+
 static void
 print_char (p_state *state, int c)
 {
@@ -831,36 +881,10 @@ print_char (p_state *state, int c)
              break;
            default:
 
-              /* states 102-106 are for UTF-8 decoding */
-
-              if ((c & 0xE0) == 0xC0) {        /* 110xxxxx: 11 bits, 2 bytes */
-                state->unicruds = 1;
-                state->unicrud[0] = c;
-                state->escstate = 102;
-                break;
-              } else if ((c & 0xF0) == 0xE0) { /* 1110xxxx: 16 bits, 3 bytes */
-                state->unicruds = 1;
-                state->unicrud[0] = c;
-                state->escstate = 103;
-                break;
-              } else if ((c & 0xF8) == 0xF0) { /* 11110xxx: 21 bits, 4 bytes */
-                state->unicruds = 1;
-                state->unicrud[0] = c;
-                state->escstate = 104;
+            PRINT: /* Come from states 102-106 */
+              c = process_unicrud (state, c);
+              if (! c)
                 break;
-              } else if ((c & 0xFC) == 0xF8) { /* 111110xx: 26 bits, 5 bytes */
-                state->unicruds = 1;
-                state->unicrud[0] = c;
-                state->escstate = 105;
-                break;
-              } else if ((c & 0xFE) == 0xFC) { /* 1111110x: 31 bits, 6 bytes */
-                state->unicruds = 1;
-                state->unicrud[0] = c;
-                state->escstate = 106;
-                break;
-              }
-
-            PRINT:
 
               /* If the cursor is in column 39 and we print a character, then
                  that character shows up in column 39, and the cursor is no
@@ -1137,35 +1161,12 @@ print_char (p_state *state, int c)
          state->escstate = 0;
          break;
 
-        case 102:
+        case 102:      /* states 102-106 are for UTF-8 decoding */
         case 103:
         case 104:
         case 105:
         case 106:
-          {
-            int total = state->escstate - 100;  /* see what I did there */
-            if (state->unicruds < total) {
-              /* Buffer more bytes of the UTF-8 sequence */
-              state->unicrud[state->unicruds++] = c;
-            }
-
-            if (state->unicruds >= total) {
-              /* Done! Convert it to Latin1 and print that. */
-              char *s;
-              state->unicrud[state->unicruds] = 0;
-              s = utf8_to_latin1 ((const char *) state->unicrud, False);
-              state->unicruds = 0;
-              state->escstate = 0;
-              if (s) {
-                c = (unsigned char) s[0];
-                free (s);
-                goto PRINT;
-              } else {
-                c = 0;
-              }
-            }
-          }
-          break;
+          goto PRINT;
 
         default:
           abort();
@@ -1196,7 +1197,8 @@ print_char (p_state *state, int c)
        }
       else
        {
-          /* #### This should do UTF-8 decoding */
+          c = process_unicrud (state, c);
+          if (!c) return;
 
          cell->state = FLARE;
          cell->p_char = state->chars[c];