qemacs-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemacs-commit] qemacs TODO.org buffer.c configure extras.c qe....


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs TODO.org buffer.c configure extras.c qe....
Date: Wed, 12 Apr 2017 03:33:21 -0400 (EDT)

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        17/04/12 03:33:20

Modified files:
        .              : TODO.org buffer.c configure extras.c qe.c qe.h 
                         shell.c tty.c util.c 
        tests          : color-spaces.pl mandelbrot.sh 

Log message:
        colors: extend color system
        - add 8K color modes and 64-bit QETermStyle values
        - add 64-bit buffer style support
        - reduce colored character system used in syntax handlers to 8-bit 
style 
          and 24-bit code point
        - use QETermStyle type instead of int wherever a composite style is used
        - force color system used by the terminal with environment variables:
          USE_16_COLORS=1, USE_256_COLORS=1 or USE_TRUE_COLORS=1

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/TODO.org?cvsroot=qemacs&r1=1.33&r2=1.34
http://cvs.savannah.gnu.org/viewcvs/qemacs/buffer.c?cvsroot=qemacs&r1=1.109&r2=1.110
http://cvs.savannah.gnu.org/viewcvs/qemacs/configure?cvsroot=qemacs&r1=1.27&r2=1.28
http://cvs.savannah.gnu.org/viewcvs/qemacs/extras.c?cvsroot=qemacs&r1=1.66&r2=1.67
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.262&r2=1.263
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.246&r2=1.247
http://cvs.savannah.gnu.org/viewcvs/qemacs/shell.c?cvsroot=qemacs&r1=1.122&r2=1.123
http://cvs.savannah.gnu.org/viewcvs/qemacs/tty.c?cvsroot=qemacs&r1=1.77&r2=1.78
http://cvs.savannah.gnu.org/viewcvs/qemacs/util.c?cvsroot=qemacs&r1=1.79&r2=1.80
http://cvs.savannah.gnu.org/viewcvs/qemacs/tests/color-spaces.pl?cvsroot=qemacs&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/qemacs/tests/mandelbrot.sh?cvsroot=qemacs&r1=1.1&r2=1.2

Patches:
Index: TODO.org
===================================================================
RCS file: /sources/qemacs/qemacs/TODO.org,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -b -r1.33 -r1.34
--- TODO.org    3 Apr 2017 08:33:57 -0000       1.33
+++ TODO.org    12 Apr 2017 07:33:20 -0000      1.34
@@ -1,11 +1,27 @@
 ; TODO list for qemacs
 ;
 ; Author: Charles Gordon
-; Updated: 2017-04-02
+; Updated: 2017-04-11
 
-* Needed for release version 5
+* Recent bugs and ideas
 
 ** display: fix window split bug
+** basic: backspace delete hacking tabs
+** basic: prevent search inside minibuf
+** display: save display-width in binary and hex modes upon window change
+** display: default display-width of 0 is automatic, other values are shared 
between binary and hex modes
+** display: hex-mode should optionally display chunks of 2, 4 or 8 bytes in 
big or little endian order
+** display: hex-mode and binary-mode should have an initial skip value to 
align the display on any boundary
+** display: optimize display for very large display-width in binary and hex 
modes
+** display: add screen dump command and format
+** files: save all modified buffers on C-x s
+** xml: select on "<plist "
+** shell: support ':' as alternate escape sequence argument separator
+** shell: use target window for man and similar commands
+** charset: use unichar typedef
+** charset: limit number of combining marks to 20
+** clang: colorizing bug: static int (*qe__initcall_first)(void) qe__init_call 
= NULL;
+** clang: missed tag: static int (*qe__initcall_first)(void) qe__init_call = 
NULL;
 
 * Priority 0
 
@@ -572,9 +588,6 @@
 M-g M-p previous-error
 M-g M-n next-error
 
-colorizing bug: static int (*qe__initcall_first)(void) qe__init_call = NULL;
-missed tag: static int (*qe__initcall_first)(void) qe__init_call = NULL;
-
 create tags in other languages:
 ats.c:201:                        style = ATS_STYLE_FUNCTION;
 elm.c:233:                    style = ELM_STYLE_FUNCTION;

Index: buffer.c
===================================================================
RCS file: /sources/qemacs/qemacs/buffer.c,v
retrieving revision 1.109
retrieving revision 1.110
diff -u -b -r1.109 -r1.110
--- buffer.c    3 Apr 2017 08:33:57 -0000       1.109
+++ buffer.c    12 Apr 2017 07:33:20 -0000      1.110
@@ -1028,7 +1028,7 @@
         snprintf(name, sizeof(name), "*S<%s>", b->name);
         b->b_styles = eb_new(name, BF_SYSTEM | BF_IS_STYLE | BF_RAW);
         b->flags |= flags & BF_STYLES;
-        b->style_shift = ((flags & BF_STYLES) / BF_STYLE1) - 1;
+        b->style_shift = ((unsigned)(flags & BF_STYLES) / BF_STYLE1) - 1;
         b->style_bytes = 1 << b->style_shift;
         eb_set_style(b, 0, LOGOP_INSERT, 0, b->total_size);
         eb_add_callback(b, eb_style_callback, NULL, 0);
@@ -1044,10 +1044,13 @@
 }
 
 /* XXX: should compress styles buffer with run length encoding */
-void eb_set_style(EditBuffer *b, int style, enum LogOperation op,
+void eb_set_style(EditBuffer *b, QETermStyle style, enum LogOperation op,
                   int offset, int size)
 {
+    union {
     unsigned char buf[256];
+        QETermStyle align;
+    } s;
     int i, len;
 
     if (!b->b_styles || !size)
@@ -1059,29 +1062,31 @@
     switch (op) {
     case LOGOP_WRITE:
     case LOGOP_INSERT:
-        /* XXX: should make buf uint32_t[] */
         /* XXX: should use a single loop to initialize buf */
         /* XXX: should initialize buf just once */
         while (size > 0) {
-            len = min(size, ssizeof(buf));
+            len = min(size, ssizeof(s.buf));
+            if (b->style_shift == 3) {
+                for (i = 0; i < len; i += 8) {
+                    *(uint64_t*)(void *)(s.buf + i) = style;
+                }
+            } else
             if (b->style_shift == 2) {
                 for (i = 0; i < len; i += 4) {
-                    /* XXX: should enforce 32 bit alignment of buf */
-                    *(uint32_t*)(void *)(buf + i) = style;
+                    *(uint32_t*)(void *)(s.buf + i) = style;
                 }
             } else
             if (b->style_shift == 1) {
                 for (i = 0; i < len; i += 2) {
-                    /* XXX: should enforce 16 bit alignment of buf */
-                    *(uint16_t*)(void *)(buf + i) = style;
+                    *(uint16_t*)(void *)(s.buf + i) = style;
                 }
             } else {
-                memset(buf, style, len);
+                memset(s.buf, style, len);
             }
             if (op == LOGOP_WRITE)
-                eb_write(b->b_styles, offset, buf, len);
+                eb_write(b->b_styles, offset, s.buf, len);
             else
-                eb_insert(b->b_styles, offset, buf, len);
+                eb_insert(b->b_styles, offset, s.buf, len);
             size -= len;
             offset += len;
         }
@@ -1460,9 +1465,14 @@
     return ch;
 }
 
-int eb_get_style(EditBuffer *b, int offset)
+QETermStyle eb_get_style(EditBuffer *b, int offset)
 {
     if (b->b_styles) {
+        if (b->style_shift == 3) {
+            uint64_t style = 0;
+            eb_read(b->b_styles, (offset >> b->char_shift) << 3, &style, 8);
+            return style;
+        } else
         if (b->style_shift == 2) {
             uint32_t style = 0;
             eb_read(b->b_styles, (offset >> b->char_shift) << 2, &style, 4);
@@ -1474,7 +1484,7 @@
             return style;
         } else {
             uint8_t style = 0;
-            eb_read(b->b_styles, (offset >> b->char_shift), &style, 1);
+            eb_read(b->b_styles, (offset >> b->char_shift) << 0, &style, 1);
             return style;
         }
     }
@@ -2360,7 +2370,7 @@
         size = 0;
         for (offset = src_offset; offset < offset_max;) {
             char buf[MAX_CHAR_BYTES];
-            int style = eb_get_style(src, offset);
+            QETermStyle style = eb_get_style(src, offset);
             int c = eb_nextc(src, offset, &offset);
             int len = eb_encode_uchar(b, buf, c);
             b->cur_style = style;

Index: configure
===================================================================
RCS file: /sources/qemacs/qemacs/configure,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- configure   28 Dec 2016 07:39:45 -0000      1.27
+++ configure   12 Apr 2017 07:33:20 -0000      1.28
@@ -127,7 +127,7 @@
     darwin="yes"
     CFLAGS=""
     initcalls="no"
-    unlockio="no"
+    unlockio="yes"
     plugins="no"
     extralibs="-lm"
     strip_args="-x -S"
@@ -503,6 +503,7 @@
 echo "FFMPEG support      $ffmpeg"
 echo "Graphical HTML      $html"
 echo "Memory mapped files $mmap"
+echo "Unlocked I/O        $initcalls"
 echo "Initcall support    $initcalls"
 echo "Plugins support     $plugins"
 echo "Bidir support       $bidir"

Index: extras.c
===================================================================
RCS file: /sources/qemacs/qemacs/extras.c,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -b -r1.66 -r1.67
--- extras.c    3 Apr 2017 08:33:57 -0000       1.66
+++ extras.c    12 Apr 2017 07:33:20 -0000      1.67
@@ -1096,27 +1096,32 @@
     return len;
 }
 
-static int qe_term_get_style(const char *str)
+static int qe_term_get_style(const char *str, QETermStyle *style)
 {
     char buf[128];
     QEColor fg_color, bg_color;
-    int fg, bg, style, len;
+    unsigned int fg, bg, attr;
+    int len;
     const char *p = str;
 
-    style = 0;
+    attr = 0;
     for (;;) {
         len = str_get_word(buf, sizeof(buf), p, &p);
 
         if (strfind("bold|strong", buf)) {
-            style |= QE_TERM_BOLD;
+            attr |= QE_TERM_BOLD;
             continue;
         }
-        if (strfind("blinking|blink", buf)) {
-            style |= QE_TERM_BLINK;
+        if (strfind("italic|italics", buf)) {
+            attr |= QE_TERM_ITALIC;
             continue;
         }
         if (strfind("underlined|underline", buf)) {
-            style |= QE_TERM_UNDERLINE;
+            attr |= QE_TERM_UNDERLINE;
+            continue;
+        }
+        if (strfind("blinking|blink", buf)) {
+            attr |= QE_TERM_BLINK;
             continue;
         }
         break;
@@ -1125,29 +1130,30 @@
     bg_color = QERGB(0x00, 0x00, 0x00);
     if (len > 0) {
         if (css_get_color(&fg_color, buf))
-            return -1;
+            return 1;
         len = str_get_word(buf, sizeof(buf), p, &p);
         if (strfind("/|on", buf)) {
             str_get_word(buf, sizeof(buf), p, &p);
             if (css_get_color(&bg_color, buf))
-                return -1;
+                return 2;
         }
     }
     fg = qe_map_color(fg_color, xterm_colors, QE_TERM_FG_COLORS, NULL);
     bg = qe_map_color(bg_color, xterm_colors, QE_TERM_BG_COLORS, NULL);
 
-    return QE_TERM_COMPOSITE | style | QE_TERM_MAKE_COLOR(fg, bg);
+    *style = QE_TERM_COMPOSITE | attr | QE_TERM_MAKE_COLOR(fg, bg);
+    return 0;
 }
 
 static void do_set_region_color(EditState *s, const char *str)
 {
-    int offset, size, style;
+    int offset, size;
+    QETermStyle style;
 
     /* deactivate region hilite */
     s->region_style = 0;
 
-    style = qe_term_get_style(str);
-    if (style < 0) {
+    if (qe_term_get_style(str, &style)) {
         put_status(s, "Invalid color '%s'", str);
         return;
     }
@@ -1159,14 +1165,16 @@
         size = -size;
     }
     if (size > 0) {
-        eb_create_style_buffer(s->b, QE_TERM_STYLE_BITS <= 16 ? BF_STYLE2 : 
BF_STYLE4);
+        eb_create_style_buffer(s->b, QE_TERM_STYLE_BITS <= 16 ? BF_STYLE2 :
+                               QE_TERM_STYLE_BITS <= 32 ? BF_STYLE4 : 
BF_STYLE8);
         eb_set_style(s->b, style, LOGOP_WRITE, offset, size);
     }
 }
 
 static void do_set_region_style(EditState *s, const char *str)
 {
-    int offset, size, style;
+    int offset, size;
+    QETermStyle style;
     QEStyleDef *st;
 
     /* deactivate region hilite */
@@ -1186,7 +1194,8 @@
         size = -size;
     }
     if (size > 0) {
-        eb_create_style_buffer(s->b, QE_TERM_STYLE_BITS <= 16 ? BF_STYLE2 : 
BF_STYLE4);
+        eb_create_style_buffer(s->b, QE_TERM_STYLE_BITS <= 16 ? BF_STYLE2 :
+                               QE_TERM_STYLE_BITS <= 32 ? BF_STYLE4 : 
BF_STYLE8);
         eb_set_style(s->b, style, LOGOP_WRITE, offset, size);
     }
 }
@@ -1288,8 +1297,9 @@
 
     eb_printf(b1, "    save_log: %d  (new_index=%d, current=%d, nb_logs=%d)\n",
               b->save_log, b->log_new_index, b->log_current, b->nb_logs);
-    eb_printf(b1, "      styles: %d  (cur_style=%d, bytes=%d, shift=%d)\n",
-              !!b->b_styles, b->cur_style, b->style_bytes, b->style_shift);
+    eb_printf(b1, "      styles: %d  (cur_style=%lld, bytes=%d, shift=%d)\n",
+              !!b->b_styles, (long long)b->cur_style,
+              b->style_bytes, b->style_shift);
 
     if (b->total_size > 0) {
         u8 buf[4096];
@@ -1449,7 +1459,7 @@
     eb_printf(b1, "%*s: %d\n", w, "mouse_force_highlight", 
s->mouse_force_highlight);
     eb_printf(b1, "%*s: %p\n", w, "get_colorized_line", 
(void*)s->get_colorized_line);
     eb_printf(b1, "%*s: %p\n", w, "colorize_func", (void*)s->colorize_func);
-    eb_printf(b1, "%*s: %d\n", w, "default_style", s->default_style);
+    eb_printf(b1, "%*s: %lld\n", w, "default_style", (long 
long)s->default_style);
     eb_printf(b1, "%*s: %s\n", w, "buffer", s->b->name);
     if (s->last_buffer)
         eb_printf(b1, "%*s: %s\n", w, "last_buffer", s->last_buffer->name);
@@ -1489,6 +1499,10 @@
     eb_printf(b1, "%*s: %d\n", w, "bitmap_format", s->bitmap_format);
     eb_printf(b1, "%*s: %d\n\n", w, "video_format", s->video_format);
 
+    eb_printf(b1, "%*s: %d\n", w, "QE_TERM_STYLE_BITS", QE_TERM_STYLE_BITS);
+    eb_printf(b1, "%*s: %x << %d\n", w, "QE_TERM_FG_COLORS", 
QE_TERM_FG_COLORS, QE_TERM_FG_SHIFT);
+    eb_printf(b1, "%*s: %x << %d\n\n", w, "QE_TERM_BG_COLORS", 
QE_TERM_BG_COLORS, QE_TERM_BG_SHIFT);
+
     if (s->dpy.dpy_describe) {
         s->dpy.dpy_describe(s, b1);
     }

Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.262
retrieving revision 1.263
diff -u -b -r1.262 -r1.263
--- qe.c        11 Apr 2017 06:46:13 -0000      1.262
+++ qe.c        12 Apr 2017 07:33:20 -0000      1.263
@@ -51,7 +51,7 @@
 
 void print_at_byte(QEditScreen *screen,
                    int x, int y, int width, int height,
-                   const char *str, int style);
+                   const char *str, QETermStyle style);
 static EditBuffer *predict_switch_to_buffer(EditState *s);
 static StringArray *get_history(const char *name);
 static void qe_key_process(int key);
@@ -2340,7 +2340,7 @@
 
     /* slow, but simple iterative method */
     for (offset = 0; offset < b->total_size;) {
-        int style = eb_get_style(b, offset);
+        QETermStyle style = eb_get_style(b, offset);
         int c = eb_nextc(b, offset, &offset);
         b1->cur_style = style;
         len = eb_encode_uchar(b1, buf, c);
@@ -2589,8 +2589,8 @@
             buf_put_byte(out, ']');
         }
         if (s->b->style_bytes) {
-            buf_printf(out, " {%0*X}", s->b->style_bytes * 2,
-                       eb_get_style(s->b, s->offset));
+            buf_printf(out, " {%0*llX}", s->b->style_bytes * 2,
+                       (unsigned long long)eb_get_style(s->b, s->offset));
         }
     }
     eb_get_pos(s->b, &line_num, &col_num, s->offset);
@@ -2754,13 +2754,13 @@
 /* Should move all this to display.c */
 
 /* compute style */
-static void apply_style(QEStyleDef *stp, int style)
+static void apply_style(QEStyleDef *stp, QETermStyle style)
 {
     QEStyleDef *s;
 
     if (style & QE_TERM_COMPOSITE) {
-        stp->fg_color = xterm_colors[QE_TERM_GET_FG(style)];
-        stp->bg_color = xterm_colors[QE_TERM_GET_BG(style)];
+        stp->fg_color = qe_unmap_color(QE_TERM_GET_FG(style), 
QE_TERM_FG_COLORS);
+        stp->bg_color = qe_unmap_color(QE_TERM_GET_BG(style), 
QE_TERM_BG_COLORS);
         if (style & QE_TERM_UNDERLINE)
             stp->font_style |= QE_FONT_STYLE_UNDERLINE;
         if (style & QE_TERM_BOLD)
@@ -2789,7 +2789,7 @@
     }
 }
 
-void get_style(EditState *e, QEStyleDef *stp, int style)
+void get_style(EditState *e, QEStyleDef *stp, QETermStyle style)
 {
     /* get root default style */
     *stp = qe_styles[0];
@@ -2996,13 +2996,13 @@
 
 void do_set_window_style(EditState *s, const char *stylestr)
 {
-    int style = find_style_index(stylestr);
+    int style_index = find_style_index(stylestr);
 
-    if (style < 0) {
+    if (style_index < 0) {
         put_status(s, "Unknown style '%s'", stylestr);
         return;
     }
-    s->default_style = style;
+    s->default_style = style_index;
 }
 
 void do_set_system_font(EditState *s, const char *qe_font_name,
@@ -3380,7 +3380,8 @@
 /* layout of a word fragment */
 static void flush_fragment(DisplayState *ds)
 {
-    int w, len, style, i, j;
+    int w, len, i, j;
+    QETermStyle style;
     QEditScreen *screen = ds->edit_state->screen;
     TextFragment *frag;
     QEStyleDef styledef;
@@ -3572,7 +3573,8 @@
 int display_char_bidir(DisplayState *ds, int offset1, int offset2,
                        int embedding_level, int ch)
 {
-    int space, style, istab, isaccent;
+    int space, istab, isaccent;
+    QETermStyle style;
     EditState *e;
 
     style = ds->style;
@@ -3819,7 +3821,7 @@
     buf_ptr = buf;
     buf_end = buf + buf_size - 1;
     for (;;) {
-        int style = eb_get_style(b, offset);
+        QETermStyle style = eb_get_style(b, offset);
         int c = eb_nextc(b, offset, &offset);
         if (c == '\n') {
             /* XXX: set style for end of line? */
@@ -5307,7 +5309,7 @@
 /* Print a utf-8 encoded buffer as unicode */
 void print_at_byte(QEditScreen *screen,
                    int x, int y, int width, int height,
-                   const char *str, int style)
+                   const char *str, QETermStyle style)
 {
     unsigned int ubuf[MAX_SCREEN_WIDTH];
     int len;
@@ -7148,7 +7150,7 @@
     put_status(s, "Hello, how are you?");
 }
 
-int get_glyph_width(QEditScreen *screen, EditState *s, int style, int c)
+int get_glyph_width(QEditScreen *screen, EditState *s, QETermStyle style, int 
c)
 {
     QEStyleDef styledef;
     QEFont *font;
@@ -7161,7 +7163,7 @@
     return width;
 }
 
-int get_line_height(QEditScreen *screen, EditState *s, int style)
+int get_line_height(QEditScreen *screen, EditState *s, QETermStyle style)
 {
     QEStyleDef styledef;
     QEFont *font;

Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.246
retrieving revision 1.247
diff -u -b -r1.246 -r1.247
--- qe.h        3 Apr 2017 08:33:57 -0000       1.246
+++ qe.h        12 Apr 2017 07:33:20 -0000      1.247
@@ -205,11 +205,10 @@
 typedef unsigned int QEColor;
 #define QEARGB(a,r,g,b)    (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
 #define QERGB(r,g,b)       QEARGB(0xff, r, g, b)
+#define QERGB25(r,g,b)     QEARGB(1, r, g, b)
 #define COLOR_TRANSPARENT  0
 #define QECOLOR_XOR        1
 
-#if 1  /* new composite style scheme */
-
 /* A qemacs style is a named set of attributes including:
  * - colors for foreground and background
  * - font style bits
@@ -238,6 +237,42 @@
  * - text and background colors as either palette numbers or 4096 rgb values
  */
 
+#if 0   /* 25-bit color for FG and BG */
+
+#define QE_TERM_STYLE_BITS  64
+typedef uint64_t QETermStyle;
+#define QE_STYLE_NUM        0x00FF
+#define QE_STYLE_SEL        0x02000000  /* special selection style (cumulative 
with another style) */
+#define QE_TERM_COMPOSITE   0x04000000  /* special bit to indicate qe-term 
composite style */
+/* XXX: reversed as attribute? */
+/* XXX: faint? */
+#define QE_TERM_UNDERLINE   0x08000000
+#define QE_TERM_BOLD        0x10000000
+#define QE_TERM_ITALIC      0x20000000
+#define QE_TERM_BLINK       0x40000000
+#define QE_TERM_BG_BITS     25
+#define QE_TERM_BG_SHIFT    32
+#define QE_TERM_FG_BITS     25
+#define QE_TERM_FG_SHIFT    0
+
+#elif 1   /* 8K colors for FG and BG */
+
+#define QE_TERM_STYLE_BITS  32
+typedef uint32_t QETermStyle;
+#define QE_STYLE_NUM        0x00FF
+#define QE_STYLE_SEL        0x02000  /* special selection style (cumulative 
with another style) */
+#define QE_TERM_COMPOSITE   0x04000  /* special bit to indicate qe-term 
composite style */
+#define QE_TERM_UNDERLINE   0x08000
+#define QE_TERM_BOLD        0x10000
+#define QE_TERM_ITALIC      0x20000
+#define QE_TERM_BLINK       0x40000
+#define QE_TERM_BG_BITS     13
+#define QE_TERM_BG_SHIFT    19
+#define QE_TERM_FG_BITS     13
+#define QE_TERM_FG_SHIFT    0
+
+#elif 1   /* 256 colors for FG and BG */
+
 #define QE_TERM_STYLE_BITS  32
 typedef uint32_t QETermStyle;
 #define QE_STYLE_NUM        0x00FF
@@ -248,11 +283,11 @@
 #define QE_TERM_ITALIC      0x1000
 #define QE_TERM_BLINK       0x2000
 #define QE_TERM_BG_BITS     8
-#define QE_TERM_BG_SHIFT    0
+#define QE_TERM_BG_SHIFT    16
 #define QE_TERM_FG_BITS     8
-#define QE_TERM_FG_SHIFT    16
+#define QE_TERM_FG_SHIFT    0
 
-#else
+#else   /* 16 colors for FG and 16 color BG */
 
 #define QE_TERM_STYLE_BITS  16
 typedef uint16_t QETermStyle;
@@ -274,11 +309,11 @@
 #define QE_TERM_DEF_BG      0
 #define QE_TERM_BG_COLORS   (1 << QE_TERM_BG_BITS)
 #define QE_TERM_FG_COLORS   (1 << QE_TERM_FG_BITS)
-#define QE_TERM_BG_MASK     ((QE_TERM_BG_COLORS - 1) << QE_TERM_BG_SHIFT)
-#define QE_TERM_FG_MASK     ((QE_TERM_FG_COLORS - 1) << QE_TERM_FG_SHIFT)
-#define QE_TERM_MAKE_COLOR(fg, bg)  (((fg) << QE_TERM_FG_SHIFT) | ((bg) << 
QE_TERM_BG_SHIFT))
-#define QE_TERM_SET_FG(col, fg)  ((col) = ((col) & ~QE_TERM_FG_MASK) | ((fg) 
<< QE_TERM_FG_SHIFT))
-#define QE_TERM_SET_BG(col, bg)  ((col) = ((col) & ~QE_TERM_BG_MASK) | ((bg) 
<< QE_TERM_BG_SHIFT))
+#define QE_TERM_BG_MASK     ((QETermStyle)(QE_TERM_BG_COLORS - 1) << 
QE_TERM_BG_SHIFT)
+#define QE_TERM_FG_MASK     ((QETermStyle)(QE_TERM_FG_COLORS - 1) << 
QE_TERM_FG_SHIFT)
+#define QE_TERM_MAKE_COLOR(fg, bg)  (((QETermStyle)(fg) << QE_TERM_FG_SHIFT) | 
((QETermStyle)(bg) << QE_TERM_BG_SHIFT))
+#define QE_TERM_SET_FG(col, fg)  ((col) = ((col) & ~QE_TERM_FG_MASK) | 
((QETermStyle)(fg) << QE_TERM_FG_SHIFT))
+#define QE_TERM_SET_BG(col, bg)  ((col) = ((col) & ~QE_TERM_BG_MASK) | 
((QETermStyle)(bg) << QE_TERM_BG_SHIFT))
 #define QE_TERM_GET_FG(color)  (((color) & QE_TERM_FG_MASK) >> 
QE_TERM_FG_SHIFT)
 #define QE_TERM_GET_BG(color)  (((color) & QE_TERM_BG_MASK) >> 
QE_TERM_BG_SHIFT)
 
@@ -443,7 +478,10 @@
 
 extern QEColor const xterm_colors[];
 /* XXX: should have a more generic API with precomputed mapping scales */
-int qe_map_color(QEColor color, QEColor const *colors, int count, int *dist);
+/* Convert RGB triplet to a composite color */
+unsigned int qe_map_color(QEColor color, QEColor const *colors, int count, int 
*dist);
+/* Convert a composite color to an RGB triplet */
+QEColor qe_unmap_color(int color, int count);
 
 void color_completion(CompleteState *cp);
 int css_define_color(const char *name, const char *value);
@@ -954,12 +992,13 @@
 #define BF_UTF8      0x0200  /* buffer charset is utf-8 */
 #define BF_RAW       0x0400  /* buffer charset is raw (no charset translation) 
*/
 #define BF_TRANSIENT 0x0800  /* buffer is deleted upon window close */
-#define BF_STYLES    0x3000  /* buffer has styles */
+#define BF_STYLES    0x7000  /* buffer has styles */
 #define BF_STYLE1    0x1000  /* buffer has 1 byte styles */
 #define BF_STYLE2    0x2000  /* buffer has 2 byte styles */
 #define BF_STYLE4    0x3000  /* buffer has 4 byte styles */
-#define BF_IS_STYLE  0x4000  /* buffer is a styles buffer */
-#define BF_IS_LOG    0x8000  /* buffer is a log buffer */
+#define BF_STYLE8    0x4000  /* buffer has 8 byte styles */
+#define BF_IS_STYLE  0x8000  /* buffer is a styles buffer */
+#define BF_IS_LOG    0x10000  /* buffer is a log buffer */
 
 struct EditBuffer {
     OWNED Page *page_table;
@@ -1009,9 +1048,9 @@
 
     /* style system */
     EditBuffer *b_styles;
-    int cur_style;  /* current style for buffer writing APIs */
-    int style_bytes;
-    int style_shift;
+    QETermStyle cur_style;  /* current style for buffer writing APIs */
+    int style_bytes;  /* 0, 1, 2, 4 or 8 bytes per char */
+    int style_shift;  /* 0, 0, 1, 2 or 3 */
 
     /* modification callbacks */
     OWNED EditBufferCallbackList *first_callback;
@@ -1130,8 +1169,8 @@
                         enum LogOperation op, int offset, int size);
 int eb_create_style_buffer(EditBuffer *b, int flags);
 void eb_free_style_buffer(EditBuffer *b);
-int eb_get_style(EditBuffer *b, int offset);
-void eb_set_style(EditBuffer *b, int style, enum LogOperation op,
+QETermStyle eb_get_style(EditBuffer *b, int offset);
+void eb_set_style(EditBuffer *b, QETermStyle style, enum LogOperation op,
                   int offset, int size);
 void eb_style_callback(EditBuffer *b, void *opaque, int arg,
                        enum LogOperation op, int offset, int size);
@@ -1294,7 +1333,7 @@
     GetColorizedLineFunc get_colorized_line;
     ColorizeFunc colorize_func; /* colorization function */
 
-    int default_style;  /* default text style */
+    QETermStyle default_style;  /* default text style */
 
     /* after this limit, the fields are not saved into the buffer */
     int end_of_saved_data;
@@ -1712,7 +1751,7 @@
 #define MAX_WORD_SIZE  128
 #define NO_CURSOR      0x7fffffff
 
-#define STYLE_BITS     12
+#define STYLE_BITS     8
 #define STYLE_SHIFT    (32 - STYLE_BITS)
 #define CHAR_MASK      ((1 << STYLE_SHIFT) - 1)
 
@@ -1745,7 +1784,7 @@
     int wrap;
     int eol_reached;
     EditState *edit_state;
-    int style;          /* current style for display_printf... */
+    QETermStyle style;   /* current style for display_printf... */
 
     /* fragment buffers */
     TextFragment fragments[MAX_SCREEN_WIDTH];
@@ -1766,8 +1805,8 @@
     unsigned char fragment_hex_mode[MAX_WORD_SIZE];
     int fragment_index;
     int last_space;
-    int last_style;
     int last_embedding_level;
+    QETermStyle last_style;
 };
 
 enum DisplayType {
@@ -1803,15 +1842,15 @@
 #define SET_COLOR(str,a,b,style)  set_color((str) + (a), (str) + (b), style)
 
 static inline void set_color(unsigned int *p, unsigned int *to, int style) {
-    style <<= STYLE_SHIFT;
+    unsigned int bits = (unsigned int)style << STYLE_SHIFT;
     while (p < to)
-        *p++ |= style;
+        *p++ |= bits;
 }
 
 #define SET_COLOR1(str,a,style)  set_color1((str) + (a), style)
 
 static inline void set_color1(unsigned int *p, int style) {
-    *p |= style << STYLE_SHIFT;
+    *p |= (unsigned int)style << STYLE_SHIFT;
 }
 
 /* input.c */
@@ -1925,8 +1964,8 @@
 void edit_detach(EditState *s);
 EditBuffer *check_buffer(EditBuffer **sp);
 EditState *check_window(EditState **sp);
-int get_glyph_width(QEditScreen *screen, EditState *s, int style, int c);
-int get_line_height(QEditScreen *screen, EditState *s, int style);
+int get_glyph_width(QEditScreen *screen, EditState *s, QETermStyle style, int 
c);
+int get_line_height(QEditScreen *screen, EditState *s, QETermStyle style);
 void do_refresh(EditState *s);
 // should take direction argument
 void do_other_window(EditState *s);
@@ -2082,7 +2121,7 @@
 int find_style_index(const char *name);
 QEStyleDef *find_style(const char *name);
 void style_completion(CompleteState *cp);
-void get_style(EditState *e, QEStyleDef *stp, int style);
+void get_style(EditState *e, QEStyleDef *stp, QETermStyle style);
 void style_property_completion(CompleteState *cp);
 int find_style_property(const char *name);
 void do_define_color(EditState *e, const char *name, const char *value);

Index: shell.c
===================================================================
RCS file: /sources/qemacs/qemacs/shell.c,v
retrieving revision 1.122
retrieving revision 1.123
diff -u -b -r1.122 -r1.123
--- shell.c     3 Apr 2017 08:33:57 -0000       1.122
+++ shell.c     12 Apr 2017 07:33:20 -0000      1.123
@@ -36,7 +36,6 @@
 
 /* XXX: status line */
 /* XXX: better tab handling */
-/* XXX: bold & italic ? */
 /* XXX: send real cursor position (CSI n) */
 
 static ModeDef shell_mode, pager_mode;
@@ -57,12 +56,12 @@
     /* buffer state */
     int pty_fd;
     int pid; /* -1 if not launched */
-    int attr, fgcolor, bgcolor, reverse;
+    unsigned int attr, fgcolor, bgcolor, reverse;
     int cur_offset; /* current offset at position x, y */
     int cur_prompt; /* offset of end of prompt on current line */
+    int nb_esc_params;
     int esc_params[MAX_ESC_PARAMS];
     int has_params[MAX_ESC_PARAMS];
-    int nb_esc_params;
     int state;
     int esc1, esc2;
     int shifted;
@@ -270,9 +269,9 @@
     /* Should compute def_color from shell default style at display
      * time and force full redisplay upon style change.
      */
-    s->attr = 0;
     s->fgcolor = QE_TERM_DEF_FG;
     s->bgcolor = QE_TERM_DEF_BG;
+    s->attr = 0;
     s->reverse = 0;
 
     term = getenv("TERM");
@@ -440,7 +439,7 @@
 }
 
 static inline void qe_term_set_setyle(ShellState *s) {
-    int composite_color;
+    QETermStyle composite_color;
 
     if (s->reverse) {
         composite_color = QE_TERM_MAKE_COLOR(s->bgcolor, s->fgcolor);
@@ -549,7 +548,7 @@
      *
      * case 2:
      *  This is sometimes DIM, eg on the
-     *  GIGI and Linux
+     *  GIGI and Linux (aka FAINT in iTerm2)
      * case 8:
      *  This is sometimes INVIS various ANSI.
      * case 21:
@@ -607,7 +606,7 @@
     case 27:    /* exit_reverse_mode, exit_standout_mode */
         s->reverse = 0;
         break;
-    case 2:     /* Xenix combined fg/bg: \027[2;FG;BGm */
+    case 2:     /* DIM or FAINT */
     case 6:     /* SCO light background */
     case 8:     /* enter_secure_mode */
     case 9:     /* cygwin dim mode */
@@ -624,68 +623,116 @@
         s->bgcolor = QE_TERM_DEF_BG;
         break;
     case 38:    /* set extended foreground color */
+        // First subparam means:   # additional subparams:  Accepts optional 
params:
+        // 1: transparent          0                        NO
+        // 2: RGB                  3                        YES
+        // 3: CMY                  3                        YES
+        // 4: CMYK                 4                        YES
+        // 5: Indexed color        1                        NO
+        //
+        // Optional paramters go at position 7 and 8, and indicate toleranace 
as an
+        // integer; and color space (0=CIELUV, 1=CIELAB). Example:
+        //
+        // CSI 38:2:255:128:64:0:5:1 m
+        //
+        // Also accepted for xterm compatibility, but never with optional 
parameters:
+        // CSI 38;2;255;128;64 m
+        //
+        // Set the foreground color to red=255, green=128, blue=64 with a 
tolerance of
+        // 5 in the CIELAB color space. The 0 at the 6th position has no 
meaning and
+        // is just a filler.
+        // 
+        // For 256-color mode (indexed) use this for the foreground:
+        // CSI 38;5;N m
+        // where N is a value between 0 and 255. See the colors described in 
screen_char_t
+        // in the comments for fgColorCode.
+
         if (s->esc_params[1] == 5) {
             /* set foreground color to third esc_param */
             /* complete syntax is \033[38;5;Nm where N is in range 0..255 */
-            int color = s->esc_params[2];
-            QEColor rgb = xterm_colors[color & 255];
+            int color = s->esc_params[2] & 255;
+            QEColor rgb = xterm_colors[color];
 
             /* map color to qe-term palette */
+            s->fgcolor = color;
+            if (QE_TERM_FG_COLORS < 256)
             s->fgcolor = qe_map_color(rgb, xterm_colors, QE_TERM_FG_COLORS, 
NULL);
-            s->nb_esc_params = 1;
+            s->nb_esc_params = 1;  /* XXX: should instead consume 2 arguments 
*/
         } else
         if (s->esc_params[1] == 2) {
             /* set foreground color to 24-bit color */
             /* complete syntax is \033[38;2;r;g;bm where r,g,b are in 0..255 */
-            QEColor rgb = QERGB(s->esc_params[2] & 255,
+            QEColor rgb = QERGB25(s->esc_params[2] & 255,
                                 s->esc_params[3] & 255,
                                 s->esc_params[4] & 255);
 
             /* map 24-bit colors to qe-term palette */
             s->fgcolor = qe_map_color(rgb, xterm_colors, QE_TERM_FG_COLORS, 
NULL);
-            s->nb_esc_params = 1;
+            s->nb_esc_params = 1;  /* XXX: should instead consume 4 arguments 
*/
         }
         break;
     case 48:    /* set extended background color */
         if (s->esc_params[1] == 5) {
             /* set background color to third esc_param */
             /* complete syntax is \033[48;5;Nm where N is in range 0..255 */
-            int color = s->esc_params[2];
-            QEColor rgb = xterm_colors[color & 255];
+            int color = s->esc_params[2] & 255;
+            QEColor rgb = xterm_colors[color];
 
             /* map color to qe-term palette */
+            s->bgcolor = color;
+            if (QE_TERM_BG_COLORS < 256)
             s->bgcolor = qe_map_color(rgb, xterm_colors, QE_TERM_BG_COLORS, 
NULL);
-            s->nb_esc_params = 1;
+            s->nb_esc_params = 1;  /* XXX: should instead consume 2 arguments 
*/
         } else
         if (s->esc_params[1] == 2) {
             /* set background color to 24-bit color */
             /* complete syntax is \033[48;2;r;g;bm where r,g,b are in 0..255 */
-            QEColor rgb = QERGB(s->esc_params[2] & 255,
+            QEColor rgb = QERGB25(s->esc_params[2] & 255,
                                 s->esc_params[3] & 255,
                                 s->esc_params[4] & 255);
 
             /* map 24-bit colors to qe-term palette */
             s->bgcolor = qe_map_color(rgb, xterm_colors, QE_TERM_BG_COLORS, 
NULL);
-            s->nb_esc_params = 1;
+            s->nb_esc_params = 1;  /* XXX: should instead consume 4 arguments 
*/
         }
         break;
     default:
         /* 0:black 1:red 2:green 3:yellow 4:blue 5:magenta 6:cyan 7:white */
         if (c >= 30 && c <= 37) {
             /* set foreground color */
+            /* XXX: should distinguish system colors and palette colors */
             s->fgcolor = c - 30;
+            if (QE_TERM_FG_COLORS < 256) {
+                s->fgcolor = qe_map_color(xterm_colors[c - 30], xterm_colors,
+                                          QE_TERM_FG_COLORS, NULL);
+            }
         } else
         if (c >= 40 && c <= 47) {
             /* set background color */
+            /* XXX: should distinguish system colors and palette colors */
             s->bgcolor = c - 40;
+            if (QE_TERM_BG_COLORS < 256) {
+                s->bgcolor = qe_map_color(xterm_colors[c - 40], xterm_colors,
+                                          QE_TERM_BG_COLORS, NULL);
+            }
         } else
         if (c >= 90 && c <= 97) {
             /* set bright foreground color */
+            /* XXX: should distinguish system colors and palette colors */
             s->fgcolor = c - 90 + 8;
+            if (QE_TERM_FG_COLORS < 256) {
+                s->fgcolor = qe_map_color(xterm_colors[c - 90 + 8], 
xterm_colors,
+                                          QE_TERM_FG_COLORS, NULL);
+            }
         } else
         if (c >= 100 && c <= 107) {
             /* set bright background color */
+            /* XXX: should distinguish system colors and palette colors */
             s->bgcolor = c - 100 + 8;
+            if (QE_TERM_BG_COLORS < 256) {
+                s->bgcolor = qe_map_color(xterm_colors[c - 100 + 8], 
xterm_colors,
+                                          QE_TERM_BG_COLORS, NULL);
+            }
         } else {
             TRACE_MSG("unhandled");
         }
@@ -1077,7 +1124,38 @@
         case ESC2(']','0'):     /* xterm's set-window-title and icon */
         case ESC2(']','1'):     /* xterm's set-window-title */
         case ESC2(']','2'):     /* xterm's set-window-title */
-        case ESC2(']','4'):     /* xterm's define-extended color */
+        case ESC2(']','3'):     /* Set X property on top-level window */
+            /* Pt should be in the form "prop=value", or just "prop" to delete 
the property */
+        case ESC2(']','4'):     /* xterm's define-extended color 
"\033]4;c;name\007" */
+            /* Change Color #c to cname. Any number of c name pairs may be 
given. */
+            /* iTerm2 has a specific behavior for colors 16 to 22:
+                16: terminalSetForegroundColor
+                17: terminalSetBackgroundColor
+                18: terminalSetBoldColor
+                19: terminalSetSelectionColor
+                20: terminalSetSelectedTextColor
+                21: terminalSetCursorColor
+                22: terminalSetCursorTextColor
+            */
+            /* xterm has the following set extended attribute: */
+            /* 10    Change color names starting with text foreground to Pt
+                     (a list of one or more color names or RGB specifications,
+                     separated by semicolon, up to eight, as per XParseColor).
+            */
+            /* 11    Change colors starting with text background to Pt */
+            /* 12    Change colors starting with text cursor to Pt */
+            /* 13    Change colors starting with mouse foreground to Pt */
+            /* 14    Change colors starting with mouse background to Pt */
+            /* 15    Change colors starting with Tek foreground to Pt */
+            /* 16    Change colors starting with Tek background to Pt */
+            /* 17    Change colors starting with highlight to Pt */
+            /* 46    Change Log File to Pt (normally disabled by a 
compile-time option) */
+            /* 50    Set Font to Pt If Pt begins with a "#", index in the font 
+                     menu, relative (if the next character is a plus or minus
+                     sign) or absolute. A number is expected but not required
+                     after the sign (the default is the current entry for 
+                     relative, zero for absolute indexing).
+            */
         case ESC2(']','W'):     /* word-set (define char wordness) */
             s->state = QE_TERM_STATE_STRING;
             break;
@@ -1085,6 +1163,11 @@
         case ESC2(']','R'):     /* linux reset palette */
             /* XXX: Todo */
             TRACE_MSG("linux palette");
+            /* followed by 7 digit palette entry nrrggbb with
+               n: letter 0-f for standard palette entries
+                         g-m for extended attributes:
+               rr, gg, bb 2 hex digit values
+            */
             break;
        default:
             TRACE_MSG("unhandled");
@@ -1104,6 +1187,8 @@
             /* CG: ESC2(']','0') should set shell caption */
             /* CG: ESC2(']','4') should parse color definition string */
             /* (example: "\033]4;16;rgb:00/00/00\033\134" ) */
+            // executeXtermSetRgb
+            // iTerm2 reports the current rgb value with "<index>;?", e.g. 
"105;?" -> report as \033]4;P;rgb:00/cc/ff\007",
             s->state = QE_TERM_STATE_NORM;
         }
         break;
@@ -1511,9 +1596,10 @@
     }
 
     eb_set_buffer_name(b, bufname); /* ensure that the name is unique */
-    if (shell_flags & SF_COLOR)
-        eb_create_style_buffer(b, QE_TERM_STYLE_BITS <= 16 ? BF_STYLE2 : 
BF_STYLE4);
-
+    if (shell_flags & SF_COLOR) {
+        eb_create_style_buffer(b, QE_TERM_STYLE_BITS <= 16 ? BF_STYLE2 :
+                               QE_TERM_STYLE_BITS <= 32 ? BF_STYLE4 : 
BF_STYLE8);
+    }
     /* Select shell output buffer encoding from LANG setting */
     if (((lang = getenv("LANG")) != NULL && strstr(lang, "UTF-8")) ||
           qs->screen->charset == &charset_utf8) {

Index: tty.c
===================================================================
RCS file: /sources/qemacs/qemacs/tty.c,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -b -r1.77 -r1.78
--- tty.c       11 Apr 2017 06:46:13 -0000      1.77
+++ tty.c       12 Apr 2017 07:33:20 -0000      1.78
@@ -35,46 +35,56 @@
 
 #if MAX_UNICODE_DISPLAY > 0xFFFF
 typedef uint64_t TTYChar;
-/* TTY composite style has 8 bit color number for FG and BG plus attribute 
bits */
+/* TTY composite style has 13-bit BG color, 4 attribute bits and 13-bit FG 
color */
 #define TTY_STYLE_BITS        32
-#define TTY_CHAR(ch,fg,bg)    ((uint32_t)(ch) | ((uint64_t)((fg) | ((bg) << 
16)) << 32))
+#define TTY_FG_COLORS         7936
+#define TTY_BG_COLORS         7936
+#define TTY_CHAR(ch,fg,bg)    ((uint32_t)(ch) | ((uint64_t)((fg) | ((bg) << 
17)) << 32))
 #define TTY_CHAR2(ch,col)     ((uint32_t)(ch) | ((uint64_t)(col) << 32))
 #define TTY_CHAR_GET_CH(cc)   ((uint32_t)(cc))
 #define TTY_CHAR_GET_COL(cc)  ((uint32_t)((cc) >> 32))
-#define TTY_CHAR_GET_FG(cc)   ((uint32_t)((cc) >> 32) & 0xFF)
-#define TTY_CHAR_GET_BG(cc)   ((uint32_t)((cc) >> (32 + 16)) & 0xFF)
+#define TTY_CHAR_GET_ATTR(cc) ((uint32_t)((cc) >> 32) & 0x1E000)
+#define TTY_CHAR_GET_FG(cc)   ((uint32_t)((cc) >> 32) & 0x1FFF)
+#define TTY_CHAR_GET_BG(cc)   ((uint32_t)((cc) >> (32 + 17)) & 0x1FFF)
 #define TTY_CHAR_DEFAULT      TTY_CHAR(' ', 7, 0)
 #define TTY_CHAR_COMB         0x200000
 #define TTY_CHAR_BAD          0xFFFD
 #define TTY_CHAR_NONE         0xFFFFFFFF
-#define TTY_BOLD              0x0100
-#define TTY_UNDERLINE         0x0200
-#define TTY_BLINK             0x0400
-#define TTY_ITALIC            0x0800
+#define TTY_BOLD              0x02000
+#define TTY_UNDERLINE         0x04000
+#define TTY_ITALIC            0x08000
+#define TTY_BLINK             0x10000
 #define COMB_CACHE_SIZE       2048
 #else
 typedef uint32_t TTYChar;
-/* TTY composite style has 4 bit color number for FG and BG plus attribute 
bits */
+/* TTY composite style has 4-bit BG color, 4 attribute bits and 8-bit FG color 
*/
 #define TTY_STYLE_BITS        16
+#define TTY_FG_COLORS         256
+#define TTY_BG_COLORS         16
 #define TTY_CHAR(ch,fg,bg)    ((uint32_t)(ch) | ((uint32_t)((fg) | ((bg) << 
12)) << 16))
 #define TTY_CHAR2(ch,col)     ((uint32_t)(ch) | ((uint32_t)(col) << 16))
 #define TTY_CHAR_GET_CH(cc)   ((cc) & 0xFFFF)
 #define TTY_CHAR_GET_COL(cc)  (((cc) >> 16) & 0xFFFF)
+#define TTY_CHAR_GET_ATTR(cc) ((uint32_t)((cc) >> 16) & 0x0F000)
 #define TTY_CHAR_GET_FG(cc)   (((cc) >> 16) & 0xFF)
-#define TTY_CHAR_GET_BG(cc)   (((cc) >> (16 + 8)) & 0xFF)
+#define TTY_CHAR_GET_BG(cc)   (((cc) >> (16 + 12)) & 0x0F)
 #define TTY_CHAR_DEFAULT      TTY_CHAR(' ', 7, 0)
 #define TTY_CHAR_BAD          0xFFFD
 #define TTY_CHAR_NONE         0xFFFF
 #define TTY_BOLD              0x0100
 #define TTY_UNDERLINE         0x0200
-#define TTY_BLINK             0x0400
-#define TTY_ITALIC            0x0800
+#define TTY_ITALIC            0x0400
+#define TTY_BLINK             0x0800
 #define COMB_CACHE_SIZE       1
 #endif
 
 #if defined(CONFIG_UNLOCKIO)
 #  define TTY_PUTC(c,f)         putc_unlocked(c, f)
+#ifdef CONFIG_DARWIN
+#  define TTY_FWRITE(b,s,n,f)   fwrite(b, s, n, f)
+#else
 #  define TTY_FWRITE(b,s,n,f)   fwrite_unlocked(b, s, n, f)
+#endif
 #  define TTY_FPRINTF           fprintf
 static inline void TTY_FPUTS(const char *s, FILE *fp) {
     TTY_FWRITE(s, 1, strlen(s), fp);
@@ -122,10 +132,15 @@
 #define USE_BOLD_AS_BRIGHT_FG   0x04
 #define USE_BLINK_AS_BRIGHT_BG  0x08
 #define USE_256_COLORS          0x10
-#define USE_24_BIT_COLORS       0x20
+#define USE_TRUE_COLORS         0x20
+    /* number of colors supported by the actual terminal */
     const QEColor *term_colors;
     int term_fg_colors_count;
     int term_bg_colors_count;
+    /* number of colors supported by the virtual terminal */
+    const QEColor *tty_colors;
+    int tty_fg_colors_count;
+    int tty_bg_colors_count;
     unsigned int comb_cache[COMB_CACHE_SIZE];
 } TTYState;
 
@@ -189,28 +204,52 @@
             ts->term_flags |= KBS_CONTROL_H |
                               USE_BOLD_AS_BRIGHT_FG | USE_BLINK_AS_BRIGHT_BG;
         }
-#if defined(CONFIG_TINY)
-        ts->term_flags &= ~(USE_256_COLORS | USE_24_BIT_COLORS);
-#else
+    }
+#if TTY_STYLE_BITS == 32
+    if (strstr(ts->term_name, "true") || strstr(ts->term_name, "24")) {
+        ts->term_flags |= USE_TRUE_COLORS;
+    }
+#endif
         if (strstr(ts->term_name, "256")) {
-            ts->term_flags &= ~(USE_BOLD_AS_BRIGHT_FG | USE_BLINK_AS_BRIGHT_BG 
|
-                                USE_256_COLORS | USE_24_BIT_COLORS);
             ts->term_flags |= USE_256_COLORS;
         }
-        if (strstr(ts->term_name, "true") || strstr(ts->term_name, "24")) {
+    /* actual color mode can be forced via environment variables */
+    /* XXX: should have qemacs variables too */
+#if TTY_STYLE_BITS == 32
+    if (getenv("USE_24_BIT_COLORS") || getenv("USE_TRUE_COLORS")) {
             ts->term_flags &= ~(USE_BOLD_AS_BRIGHT_FG | USE_BLINK_AS_BRIGHT_BG 
|
-                                USE_256_COLORS | USE_24_BIT_COLORS);
-            ts->term_flags |= USE_24_BIT_COLORS;
-        }
+                            USE_256_COLORS | USE_TRUE_COLORS);
+        ts->term_flags |= USE_TRUE_COLORS;
+    } else
 #endif
+    if (getenv("USE_256_COLORS")) {
+        ts->term_flags &= ~(USE_BOLD_AS_BRIGHT_FG | USE_BLINK_AS_BRIGHT_BG |
+                            USE_256_COLORS | USE_TRUE_COLORS);
+        ts->term_flags |= USE_256_COLORS;
+    } else
+    if (getenv("USE_16_COLORS")) {
+        ts->term_flags &= ~(USE_BOLD_AS_BRIGHT_FG | USE_BLINK_AS_BRIGHT_BG |
+                            USE_256_COLORS | USE_TRUE_COLORS);
     }
-
-    if (ts->term_flags & (USE_256_COLORS | USE_24_BIT_COLORS)) {
-        ts->term_fg_colors_count = 256;
 #if TTY_STYLE_BITS == 32
+    if (ts->term_flags & USE_TRUE_COLORS) {
+        ts->term_fg_colors_count = 0x1000000;
+        ts->term_bg_colors_count = 0x1000000;
+    } else
+    if (ts->term_flags & USE_256_COLORS) {
+        ts->term_fg_colors_count = 256;
         ts->term_bg_colors_count = 256;
-#endif
     }
+#else
+    ts->term_flags &= ~USE_TRUE_COLORS;
+    if (ts->term_flags & USE_256_COLORS) {
+        ts->term_fg_colors_count = 256;
+    }
+#endif
+
+    ts->tty_bg_colors_count = min(ts->term_bg_colors_count, TTY_BG_COLORS);
+    ts->tty_fg_colors_count = min(ts->term_fg_colors_count, TTY_FG_COLORS);
+    ts->tty_colors = xterm_colors;
 
     tcgetattr(fileno(s->STDIN), &tty);
     ts->oldtty = tty;
@@ -269,6 +308,7 @@
         TTY_FPRINTF(s->STDOUT, "%s",
                     "\030\032" "\r\xC3\xA9" "\033[6n\033D");
         fflush(s->STDOUT);
+        /* XXX: should have a timeout to avoid locking on unsupported 
terminals */
         n = fscanf(s->STDIN, "\033[%d;%d", &y, &x);  /* get cursor position */
         TTY_FPRINTF(s->STDOUT, "\r   \r");        /* go back, erase 3 chars */
         if (n == 2 && x == 2) {
@@ -643,20 +683,21 @@
     int x, y;
     TTYChar *ptr;
     int wrap = s->width - w;
-    int bgcolor;
+    unsigned int bgcolor;
 
     ptr = ts->screen + y1 * s->width + x1;
     if (color == QECOLOR_XOR) {
         for (y = y1; y < y2; y++) {
             ts->line_updated[y] = 1;
             for (x = x1; x < x2; x++) {
+                /* XXX: should reverse fg and bg */
                 *ptr ^= TTY_CHAR(0, 7, 7);
                 ptr++;
             }
             ptr += wrap;
         }
     } else {
-        bgcolor = qe_map_color(color, ts->term_colors, 
ts->term_bg_colors_count, NULL);
+        bgcolor = qe_map_color(color, ts->tty_colors, ts->tty_bg_colors_count, 
NULL);
         for (y = y1; y < y2; y++) {
             ts->line_updated[y] = 1;
             for (x = x1; x < x2; x++) {
@@ -798,9 +839,11 @@
               ts->term_flags & USE_BOLD_AS_BRIGHT_FG ? " 
USE_BOLD_AS_BRIGHT_FG" : "",
               ts->term_flags & USE_BLINK_AS_BRIGHT_BG ? " 
USE_BLINK_AS_BRIGHT_BG" : "",
               ts->term_flags & USE_256_COLORS ? " USE_256_COLORS" : "",
-              ts->term_flags & USE_24_BIT_COLORS ? " USE_24_BIT_COLORS" : "");
-    eb_printf(b, "%*s: fg:%d, bg:%d\n", w, "colors",
+              ts->term_flags & USE_TRUE_COLORS ? " USE_TRUE_COLORS" : "");
+    eb_printf(b, "%*s: fg:%d, bg:%d\n", w, "terminal colors",
               ts->term_fg_colors_count, ts->term_bg_colors_count);
+    eb_printf(b, "%*s: fg:%d, bg:%d\n", w, "virtual tty colors",
+              ts->tty_fg_colors_count, ts->tty_bg_colors_count);
     
     eb_printf(b, "\n");
     eb_printf(b, "Unicode combination cache:\n\n");
@@ -839,7 +882,7 @@
         return;
 
     ts->line_updated[y] = 1;
-    fgcolor = qe_map_color(color, ts->term_colors, ts->term_fg_colors_count, 
NULL);
+    fgcolor = qe_map_color(color, ts->tty_colors, ts->tty_fg_colors_count, 
NULL);
     if (font->style & QE_FONT_STYLE_UNDERLINE)
         fgcolor |= TTY_UNDERLINE;
     if (font->style & QE_FONT_STYLE_BOLD)
@@ -1030,7 +1073,15 @@
                     if (bgcolor != (int)TTY_CHAR_GET_BG(cc)) {
                         int lastbg = bgcolor;
                         bgcolor = TTY_CHAR_GET_BG(cc);
-                        if (ts->term_flags & (USE_256_COLORS | 
USE_24_BIT_COLORS)) {
+#if TTY_STYLE_BITS == 32
+                        if (ts->term_bg_colors_count > 256 && bgcolor >= 256) {
+                            /* XXX: should special case dynamic palette */
+                            QEColor rgb = qe_unmap_color(bgcolor, 
ts->tty_bg_colors_count);
+                            TTY_FPRINTF(s->STDOUT, "\033[48;2;%d;%d;%dm",
+                                        (rgb >> 16) & 255, (rgb >> 8) & 255, 
(rgb >> 0) & 255);
+                        } else
+#endif
+                        if (ts->term_bg_colors_count > 16) {
                             TTY_FPRINTF(s->STDOUT, "\033[48;5;%dm", bgcolor);
                         } else
                         if (ts->term_flags & USE_BLINK_AS_BRIGHT_BG) {
@@ -1055,7 +1106,14 @@
                     if (fgcolor != (int)TTY_CHAR_GET_FG(cc)) {
                         int lastfg = fgcolor;
                         fgcolor = TTY_CHAR_GET_FG(cc);
-                        if (ts->term_flags & (USE_256_COLORS | 
USE_24_BIT_COLORS)) {
+#if TTY_STYLE_BITS == 32
+                        if (ts->term_fg_colors_count > 256 && fgcolor >= 256) {
+                            QEColor rgb = qe_unmap_color(fgcolor, 
ts->tty_fg_colors_count);
+                            TTY_FPRINTF(s->STDOUT, "\033[38;2;%d;%d;%dm",
+                                        (rgb >> 16) & 255, (rgb >> 8) & 255, 
(rgb >> 0) & 255);
+                        } else
+#endif
+                        if (ts->term_fg_colors_count > 16) {
                             TTY_FPRINTF(s->STDOUT, "\033[38;5;%dm", fgcolor);
                         } else
                         if (ts->term_flags & USE_BOLD_AS_BRIGHT_FG) {

Index: util.c
===================================================================
RCS file: /sources/qemacs/qemacs/util.c,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -b -r1.79 -r1.80
--- util.c      11 Apr 2017 06:46:13 -0000      1.79
+++ util.c      12 Apr 2017 07:33:20 -0000      1.80
@@ -1146,7 +1146,41 @@
 }
 
 #if 1
-/* Should move all this to display.c */
+/* Should move all this to a separate source file color.c */
+
+/* For 8K colors, We use a color system with 7936 colors:
+ *   - 16 standard colors
+ *   - 240 standard palette colors
+ *   - 4096 colors in a 16x16x16 cube
+ *   - a 256 level gray ramp
+ *   - 6 256-level fade to black ramps
+ *   - 6 256-level fade to white ramps
+ *   - a 256 color palette with default xterm values
+ *   - 256 unused slots
+ */
+
+/* Alternately we could use a system with 8157 colors:
+ *   - 2 default color
+ *   - 16 standard colors
+ *   - 256 standard palette colors
+ *   - 6859 colors in a 19x19x19 cube
+ *     with ramp 0,15,31,47,63,79,95,108,121,135,
+ *               148,161,175,188,201,215,228,241,255 values
+ *   - 256 level gray ramp
+ *   - extra space for 3 256 level ramps or 12 64 level ramps
+ *   - 15 unused slots
+ */
+
+/* Another possible system for 8K colors has 8042+ colors:
+ *   - 2 default color
+ *   - 16 standard colors
+ *   - 24 standard grey scale colors
+ *   - 8000 colors in a 20x20x20 cube
+ *     with ramp 0,13,27,40,54,67,81,95,108,121,135,
+ *               148,161,175,188,201,215,228,241,255 values
+ *   - extra grey scale colors
+ *   - some unused slots
+ */
 
 typedef struct ColorDef {
     const char *name;
@@ -1469,6 +1503,7 @@
 #endif
 };
 
+#if 0
 static unsigned char const scale_cube[256] = {
     /* This array is used for mapping rgb colors to the standard palette */
     /* 216 entry RGB cube with axes 0,95,135,175,215,255 */
@@ -1494,10 +1529,11 @@
     255, 255, 255,
     231, 231, 231, 231, 231, 231, 231, 231, 231
 };
+#endif
 
 static inline int color_dist(QEColor c1, QEColor c2) {
     /* using casts because c1 and c2 are unsigned */
-#if 1
+#if 0
     /* using a quick approximation to give green extra weight */
     return      abs((int)((c1 >>  0) & 0xff) - (int)((c2 >>  0) & 0xff)) +
             2 * abs((int)((c1 >>  8) & 0xff) - (int)((c2 >>  8) & 0xff)) +
@@ -1511,12 +1547,20 @@
 }
 
 /* XXX: should have a more generic API with precomputed mapping scales */
-int qe_map_color(QEColor color, QEColor const *colors, int count, int *dist)
+/* Convert RGB triplet to a composite color */
+unsigned int qe_map_color(QEColor color, QEColor const *colors, int count, int 
*dist)
 {
     int i, cmin, dmin, d;
 
+    color &= 0xFFFFFF;  /* mask off the alpha channel */
+
+    if (count >= 0x1000000) {
+        cmin = color | 0x1000000;  /* force explicit RGB triplet */
+        dmin = 0;
+    } else {
     dmin = INT_MAX;
     cmin = 0;
+        if (count <= 16) {
     for (i = 0; i < count; i++) {
         d = color_dist(color, colors[i]);
         if (d < dmin) {
@@ -1524,11 +1568,11 @@
             dmin = d;
         }
     }
-#if 1
-    if (dmin > 0 && count > 16) {
+        } else { /* if (dmin > 0 && count > 16) */
         unsigned int r = (color >> 16) & 0xff;
         unsigned int g = (color >>  8) & 0xff;
         unsigned int b = (color >>  0) & 0xff;
+#if 0
         if (r == g && g == b) {
             i = scale_grey[r];
             d = color_dist(color, colors[i]);
@@ -1538,7 +1582,43 @@
             }
         } else {
             /* XXX: should use more precise projection */
-            i = scale_cube[r] * 36 + scale_cube[g] * 6 + scale_cube[b];
+                i = 16 + scale_cube[r] * 36 +
+                    scale_cube[g] * 6 +
+                    scale_cube[b];
+                d = color_dist(color, colors[i]);
+                if (d < dmin) {
+                    cmin = i;
+                    dmin = d;
+                }
+            }
+#else
+            if (r == g && g == b) {
+                /* color is a gray tone:
+                 * map to the closest palette entry
+                 */
+                d = color_dist(color, colors[16]);
+                if (d < dmin) {
+                    cmin = 16;
+                    dmin = d;
+                }
+                for (i = 231; i < 256; i++) {
+                    d = color_dist(color, colors[i]);
+                    if (d < dmin) {
+                        cmin = i;
+                        dmin = d;
+                    }
+                }
+            } else {
+                /* general case: try and match a palette entry
+                 * from the 6x6x6 color cube .
+                 */
+                /* XXX: this causes gliches on true color terminals
+                 * with a non standard xterm palette, such as iTerm2.
+                 * On true color terminals, we should treat palette
+                 * colors and rgb colors differently in the shell buffer
+                 * terminal emulator.
+                 */
+                for (i = 16; i < 232; i++) {
             d = color_dist(color, colors[i]);
             if (d < dmin) {
                 cmin = i;
@@ -1547,12 +1627,118 @@
         }
     }
 #endif
+            if (dmin > 0 && count >= 4096) {
+                /* 13-bit 7936 color system */
+                d = 0;
+                for (;;) {
+                    if (r == g) {
+                        if (g == b) {  /* #xxxxxx */
+                            i = 0x700 + r;
+                            break;
+                        }
+                        if (r == 0) {  /* #0000xx */
+                            i = 0x100 + b;
+                            break;
+                        }
+                        if (r == 255) {  /* #FFFFxx */
+                            i = 0x800 + 0x100 + b;
+                            break;
+                        }
+                        if (b == 0) {  /* #xxxx00 */
+                            i = 0x600 + r;
+                            break;
+                        }
+                        if (b == 255) {  /* #xxxxFF */
+                            i = 0x800 + 0x600 + r;
+                            break;
+                        }
+                    } else
+                    if (r == b) {
+                        if (r == 0) {  /* #00xx00 */
+                            i = 0x200 + g;
+                            break;
+                        }
+                        if (r == 255) {  /* #FFxxFF */
+                            i = 0x800 + 0x200 + g;
+                            break;
+                        }
+                        if (g == 0) {  /* #xx00xx */
+                            i = 0x500 + r;
+                            break;
+                        }
+                        if (g == 255) {  /* #xxFFxx */
+                            i = 0x800 + 0x500 + r;
+                            break;
+                        }
+                    } else
+                    if (g == b) {
+                        if (g == 0) {  /* #xx0000 */
+                            i = 0x400 + r;
+                            break;
+                        }
+                        if (g == 255) {  /* #xxFFFF */
+                            i = 0x800 + 0x400 + r;
+                            break;
+                        }
+                        if (r == 0) {  /* #00xxxx */
+                            i = 0x300 + g;
+                            break;
+                        }
+                        if (r == 255) {  /* #FFxxxx */
+                            i = 0x800 + 0x300 + g;
+                            break;
+                        }
+                    }
+                    i = 0x1000 | ((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4);
+                    d = color_dist(color, (color & 0xF0F0F0) | ((color & 
0xF0F0F0) >> 4));
+                    break;
+                }
+                if (d < dmin) {
+                    cmin = i;
+                    dmin = d;
+                }
+            }
+        }
+    }
     if (dist) {
         *dist = dmin;
     }
     return cmin;
 }
 
+/* Convert a composite color to an RGB triplet */
+QEColor qe_unmap_color(int color, int count) {
+    /* XXX: Should use an 8K array for all colors <= 8192 */
+    if (color < 256) {
+        return xterm_colors[color];
+    }
+    if (color < 8192) {
+        /* 13-bit 7936 color system */
+        if (color & 0x1000) {
+            /* explicit 12-bit color */
+            QEColor rgb = (((color & 0xF00) << 12) |
+                           ((color & 0x0F0) <<  4) |
+                           ((color & 0x00F) <<  0));
+            return rgb | (rgb << 4);
+        }
+        if ((color & 0xf00) < 0xf00) {
+            /* 256 level color ramps */
+            /* 0x800 is unused and converts to white */
+            int r, g, b;
+            r = g = b = color & 0xFF;
+            if (!(color & 0x400)) r = -(color >> 11) & 0xFF;
+            if (!(color & 0x200)) g = -(color >> 11) & 0xFF;
+            if (!(color & 0x100)) b = -(color >> 11) & 0xFF;
+            return QERGB(r, g, b);
+        } else {
+            /* 0xf00 indicates the standard xterm color palette */
+            return xterm_colors[color & 255];
+        }
+    }
+    /* explicit RGB color */
+    return color & 0xFFFFFF;
+}
+
 void color_completion(CompleteState *cp)
 {
     ColorDef const *def;

Index: tests/color-spaces.pl
===================================================================
RCS file: /sources/qemacs/qemacs/tests/color-spaces.pl,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- tests/color-spaces.pl       11 Apr 2017 06:46:13 -0000      1.2
+++ tests/color-spaces.pl       12 Apr 2017 07:33:20 -0000      1.3
@@ -4,7 +4,7 @@
 
 print "256 color mode\n\n";
 
-# display back ground colors
+# display foreground and background colors
 
 for ($fgbg = 38; $fgbg <= 48; $fgbg +=10) {
 
@@ -73,7 +73,7 @@
 
 $s = "::";
 
-for ($fgbg = 38; $fgbg <= 48; $fgbg +=10) {
+for ($fgbg = 48; $fgbg <= 48; $fgbg +=10) {
     # the color cube
     print "RGB color cube\n";
     for ($green = 0; $green < 6; $green += 1) {

Index: tests/mandelbrot.sh
===================================================================
RCS file: /sources/qemacs/qemacs/tests/mandelbrot.sh,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- tests/mandelbrot.sh 11 Apr 2017 06:46:13 -0000      1.1
+++ tests/mandelbrot.sh 12 Apr 2017 07:33:20 -0000      1.2
@@ -5,28 +5,30 @@
 # Combined Bash/ksh93 flavors by Dan Douglas (ormaaj)
 
 function doBash {
-    typeset P Q X Y a b c i j v x y 
-    for 
((P=10**8,Q=P/100,X=320*Q/cols,Y=210*Q/lines,y=-105*Q,y1=y+Y/2,v=-220*Q,x=v; 
y<105*Q; x=v,y+=Y,y1+=Y)); do
+    typeset P Q X Y a b c i j v x y cb m
+    for 
((cb=0,m=16,P=10**8,Q=P/100,X=320*Q/cols,Y=210*Q/lines,y=-105*Q,y1=y+Y/2,v=-220*Q,x=v;
 y<105*Q; x=v,y+=Y,y1+=Y)); do
         for ((;x<P;a=b=i=j=c=0,x+=X)); do
             for ((; a**2+b**2<4*P**2&&i++<99; 
a=((c=a)**2-b**2)/P+x,b=2*c*b/P+y)); do :
             done
             for ((; a**2+b**2<4*P**2&&j++<99; 
a=((c=a)**2-b**2)/P+x,b=2*c*b/P+y1)); do :
             done
-            colorBox $((i<99?i%16:0)) $((j<99?j%16:0))
+            #colorBox $((i<99?i%m+cb:cb)) $((j<99?j%m+cb:cb))
+          . colorBox $((i<99?i%m:0)) $((j<99?j%m:0))
         done
         echo
     done
 }
 
 function doKsh {
-    integer i j
+    integer i j cb=0 m=16
     float a b c x=2.2 y=-1.05 y2=y+Y/2 X=3.2/cols Y=2.1/lines 
     while
         for ((a=b=i=0;(c=a)**2+b**2<=2&&i++<99&&(a=a**2-b**2+x,b=2*c*b+y);)); 
do :
         done
         for ((a=b=j=0;(c=a)**2+b**2<=2&&j++<99&&(a=a**2-b**2+x,b=2*c*b+y2);)); 
do :
         done
-        . colorBox $((i<99?i%16:0)) $((j<99?j%16:0))
+          #colorBox $((i<99?i%m+cb:cb)) $((j<99?j%m+cb:cb))
+        . colorBox $((i<99?i%m:0)) $((j<99?j%m:0))
         if ((x<1?!(x+=X):(y+=Y,y2+=Y,x=-2.2))); then
             print
             ((y<1.05)) 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]