Fix color initialization, we can recurse into ourselves now \o/
[apps/madtty.git] / madtty / madtty.c
index ce9f256..7b85f27 100644 (file)
@@ -19,6 +19,7 @@
     Copyright © 2006 Pierre Habouzit
  */
 
+#define _GNU_SOURCE
 #include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
+#include <wchar.h>
 
 #include "madtty.h"
 
 #define IS_CONTROL(ch) !((ch) & 0xffffff60UL)
 
+static int has_default = 0;
+
 enum {
     C0_NUL = 0x00,
             C0_SOH, C0_STX, C0_ETX, C0_EOT, C0_ENQ, C0_ACK, C0_BEL,
@@ -207,22 +211,32 @@ static void interpret_csi_SGR(madtty_t *rt, int param[], int pcount)
             CASE(27, rt->curattrs &= ~A_REVERSE);
             CASE(28, rt->curattrs &= ~A_INVIS);
 
-          case 30 ... 37:
-            rt->curattrs &= ~0xf0;
-            rt->curattrs |= (param[i] - 29) << 4;
+          case 30 ... 37: /* fg */
+            if (has_default) {
+                rt->curattrs &= ~0xf0;
+                rt->curattrs |= (param[i] + 1 - 30) << 4;
+            } else {
+                rt->curattrs &= ~070;
+                rt->curattrs |= (7 - (param[i] - 30)) << 3;
+            }
             break;
 
           case 39:
-            rt->curattrs &= ~0xf0;
+            rt->curattrs &= has_default ? ~0xf0 : ~070;
             break;
 
-          case 40 ... 47:
-            rt->curattrs &= ~0x0f;
-            rt->curattrs |= (param[i] - 39);
+          case 40 ... 47: /* bg */
+            if (has_default) {
+                rt->curattrs &= ~0x0f;
+                rt->curattrs |= (param[i] + 1 - 40);
+            } else {
+                rt->curattrs &= ~007;
+                rt->curattrs |= (param[i] - 40);
+            }
             break;
 
           case 49:
-            rt->curattrs &= ~0x0f;
+            rt->curattrs &= has_default ? ~0x0f : ~007;
             break;
 
           default:
@@ -564,9 +578,9 @@ static void try_interpret_escape_seq(madtty_t *rt)
     }
 
     if (rt->elen + 1 >= (int)sizeof(rt->ebuf)) {
-        int i;
 cancel:
 #if 0
+        int i;
         fprintf(stderr, "cancelled: \\033");
         for (i = 0; i < rt->elen; i++) {
             int c = rt->ebuf[i];
@@ -625,6 +639,8 @@ static void madtty_process_nonprinting(madtty_t *rt, wchar_t wc)
 
 void madtty_putc(madtty_t *rt, wchar_t wc)
 {
+    int width = 0;
+
     if (!rt->seen_input) {
         rt->seen_input = 1;
         kill(-rt->childpid, SIGWINCH);
@@ -665,8 +681,18 @@ void madtty_putc(madtty_t *rt, wchar_t wc)
 
             if (wc >= 0x41 && wc <= 0x7e && vt100_0[wc - 0x41]) {
                 wc = vt100_0[wc - 0x41];
-                // width = 1; // vt100 line drawing characters are always single-width
             }
+            width = 1;
+        } else {
+            width = wcwidth(wc) ?: 1;
+        }
+
+        if (width == 2 && rt->curs_col == rt->cols - 1) {
+            tmp = rt->curs_row;
+            tmp->dirty = true;
+            tmp->text[rt->curs_col] = 0;
+            tmp->attr[rt->curs_col] = build_attrs(rt->curattrs);
+            rt->curs_col++;
         }
 
         if (rt->curs_col >= rt->cols) {
@@ -675,18 +701,23 @@ void madtty_putc(madtty_t *rt, wchar_t wc)
         }
 
         tmp = rt->curs_row;
+        tmp->dirty = true;
 
         if (rt->insert) {
-            wmemmove(tmp->text + rt->curs_col + 1, tmp->text + rt->curs_col,
-                     (rt->cols - rt->curs_col - 1));
-            memmove(tmp->attr + rt->curs_col + 1, tmp->attr + rt->curs_col,
-                    (rt->cols - rt->curs_col - 1) * sizeof(tmp->attr[0]));
+            wmemmove(tmp->text + rt->curs_col + width, tmp->text + rt->curs_col,
+                     (rt->cols - rt->curs_col - width));
+            memmove(tmp->attr + rt->curs_col + width, tmp->attr + rt->curs_col,
+                    (rt->cols - rt->curs_col - width) * sizeof(tmp->attr[0]));
         }
 
         tmp->text[rt->curs_col] = wc;
         tmp->attr[rt->curs_col] = build_attrs(rt->curattrs);
-        tmp->dirty = true;
         rt->curs_col++;
+        if (width == 2) {
+            tmp->text[rt->curs_col] = 0;
+            tmp->attr[rt->curs_col] = build_attrs(rt->curattrs);
+            rt->curs_col++;
+        }
     }
 }
 
@@ -746,7 +777,7 @@ madtty_t *madtty_create(int rows, int cols)
     rt->cols = cols;
 
     /* default mode is replace */
-    rt->insert = false; 
+    rt->insert = false;
 
     /* create the cell matrix */
     rt->lines = (mtty_row_t*)calloc(sizeof(mtty_row_t), rt->rows);
@@ -803,6 +834,8 @@ void madtty_draw(madtty_t *rt, WINDOW *win, int srow, int scol)
 
                 len = wcrtomb(buf, row->text[j], NULL);
                 waddnstr(win, buf, len);
+                if (wcwidth(row->text[j]) > 1)
+                    j++;
             } else {
                 waddch(win, row->text[j] > ' ' ? row->text[j] : ' ');
             }
@@ -879,15 +912,28 @@ void madtty_initialize(void)
     setlocale(LC_ALL, "");
     initscr();
     start_color();
-    use_default_colors();
     noecho();
     raw();
     nodelay(stdscr, TRUE);
     keypad(stdscr, TRUE);
+    curs_set(0);
+    ESCDELAY=50;
 
-    for (int i = -1; i < 8; i++) {
-        for (int j = -1; j < 8; j++) {
-            init_pair((i + 1) * 16 + j + 1, i, j);
+    if (COLORS > 8) {
+        use_default_colors();
+        assume_default_colors(-1, -1);
+        has_default = 1;
+
+        for (int bg = -1; bg < 8; bg++) {
+            for (int fg = -1; fg < 8; fg++) {
+                init_pair((fg + 1) * 16 + bg + 1, fg, bg);
+            }
+        }
+    } else {
+        for (int bg = 0; bg < 8; bg++) {
+            for (int fg = 0; fg < 8; fg++) {
+                init_pair((7 - fg) * 8 + bg, fg, bg);
+            }
         }
     }
 }