qemacs-commit
[Top][All Lists]
Advanced

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

[Qemacs-commit] qemacs TODO.org clang.c extras.c qe.h tty.c VER...


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs TODO.org clang.c extras.c qe.h tty.c VER...
Date: Sat, 1 Apr 2017 21:12:01 -0400 (EDT)

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        17/04/01 21:12:01

Modified files:
        .              : TODO.org clang.c extras.c qe.h tty.c VERSION 
                         display.h qe.c shell.c 

Log message:
        display: improve color and style handling
        - add support for 256 and true color terminals
        - fix color handling for defined styles
        - fix bold, italic and underline handling for terminals
        - use more explicit symbols for qe-term emulator in shell.c
        - shell buffer terminal emulator still uses 16 colors
        - display buffer style in C-X =
        - bumped version to 0.5.0dev

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/TODO.org?cvsroot=qemacs&r1=1.31&r2=1.32
http://cvs.savannah.gnu.org/viewcvs/qemacs/clang.c?cvsroot=qemacs&r1=1.120&r2=1.121
http://cvs.savannah.gnu.org/viewcvs/qemacs/extras.c?cvsroot=qemacs&r1=1.64&r2=1.65
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.244&r2=1.245
http://cvs.savannah.gnu.org/viewcvs/qemacs/tty.c?cvsroot=qemacs&r1=1.74&r2=1.75
http://cvs.savannah.gnu.org/viewcvs/qemacs/VERSION?cvsroot=qemacs&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/qemacs/display.h?cvsroot=qemacs&r1=1.18&r2=1.19
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.259&r2=1.260
http://cvs.savannah.gnu.org/viewcvs/qemacs/shell.c?cvsroot=qemacs&r1=1.120&r2=1.121

Patches:
Index: TODO.org
===================================================================
RCS file: /sources/qemacs/qemacs/TODO.org,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -b -r1.31 -r1.32
--- TODO.org    31 Mar 2017 15:33:02 -0000      1.31
+++ TODO.org    2 Apr 2017 01:12:01 -0000       1.32
@@ -1,7 +1,7 @@
 ; TODO list for qemacs
 ;
 ; Author: Charles Gordon
-; Updated: 2017-03-31
+; Updated: 2017-04-02
 
 * Needed for release version 5
 
@@ -15,6 +15,7 @@
 ** basic: share mmapped pages correctly
 ** completion: fix electric behavior
 ** completion: add completion function to get the default value
+** display: remove QECOLOR_XOR mess, use dpy_cursor_at for all devices
 ** files: check file date to detect asynchronous modifications on disk
 ** files: reload modified file upon change if untouched since load
 ** layout: kill buffer should delete popup and popleft window
@@ -26,6 +27,7 @@
 ** shell: give commands a chance to execute for macros to behave correctly
 ** shell: A-y at process prompt
 ** shell: fix very long lines in shell buffer
+** shell: C-x RET should switch to last process buffer and move to the end of 
buffer
 ** undo: saving the file kills the redo stack!
 ** undo: when undo resets the modified buffer flag, this prevents file save
 ** xml/htmlsrc: scan for `</script>` beyond end of very long line
@@ -238,8 +240,6 @@
    Terminal glyph width of 0 should be supported.
 ** deal with accents in filenames (OS/X uses separate utf8 accents)
 ** support 256 and true color escapes in tty emulator
-** support st-256-color terminal
-** support 256 and true color terminals
 ** auto-fill-mode
 ** auto-revert-mode, global-auto-revert-mode, auto-revert-tail-mode
 ** rectangular regions, cut/paste

Index: clang.c
===================================================================
RCS file: /sources/qemacs/qemacs/clang.c,v
retrieving revision 1.120
retrieving revision 1.121
diff -u -b -r1.120 -r1.121
--- clang.c     31 Mar 2017 19:12:07 -0000      1.120
+++ clang.c     2 Apr 2017 01:12:01 -0000       1.121
@@ -793,7 +793,7 @@
             p--;
             c = *p;
             /* skip strings or comments */
-            style = c >> STYLE_SHIFT;
+            style = (unsigned int)c >> STYLE_SHIFT;
             if (style == C_STYLE_COMMENT
             ||  style == C_STYLE_STRING
             ||  style == C_STYLE_PREPROCESS) {
@@ -929,7 +929,7 @@
 
     for (i = 0; i < len; i++) {
         c = buf[i];
-        style = c >> STYLE_SHIFT;
+        style = (unsigned int)c >> STYLE_SHIFT;
         if (qe_isblank(c & CHAR_MASK))
             continue;
         /* if preprocess, no indent */

Index: extras.c
===================================================================
RCS file: /sources/qemacs/qemacs/extras.c,v
retrieving revision 1.64
retrieving revision 1.65
diff -u -b -r1.64 -r1.65
--- extras.c    1 Apr 2017 14:38:28 -0000       1.64
+++ extras.c    2 Apr 2017 01:12:01 -0000       1.65
@@ -1048,6 +1048,87 @@
     show_popup(s, b);
 }
 
+/* extract the next word from the string. ignore spaces, stop on '/' */
+static int str_get_word(char *buf, int size, const char *p, const char **pp)
+{
+    int len = 0;
+
+    while (*p == ' ')
+        p++;
+
+    if (*p == '/') {
+        /* special case meta character '/' */
+        if (len + 1 < size) {
+            buf[len] = *p;
+        }
+        p++;
+        len++;
+    } else {
+        for (; *p != '\0' && *p != ' ' && *p != '/'; p++, len++) {
+            if (len + 1 < size) {
+                buf[len] = qe_tolower((unsigned char)*p);
+            }
+        }
+    }
+    if (size > 0) {
+        if (len < size)
+            buf[len] = '\0';
+        else
+            buf[size - 1] = '\0';
+    }
+
+    while (*p == ' ')
+        p++;
+
+    if (pp)
+        *pp = p;
+
+    return len;
+}
+
+int get_tty_style(const char *str)
+{
+    char buf[128];
+    QEColor fg_color, bg_color;
+    int fg, bg, style, len;
+    const char *p = str;
+
+    style = 0;
+    for (;;) {
+        len = str_get_word(buf, sizeof(buf), p, &p);
+
+        if (strfind("bold|strong", buf)) {
+            style |= QE_TERM_BOLD;
+            continue;
+        }
+        if (strfind("blinking|blink", buf)) {
+            style |= QE_TERM_BLINK;
+            continue;
+        }
+        if (strfind("underlined|underline", buf)) {
+            style |= QE_TERM_UNDERLINE;
+            continue;
+        }
+        break;
+    }
+    fg_color = QERGB(0xbb, 0xbb, 0xbb);
+    bg_color = QERGB(0x00, 0x00, 0x00);
+    if (len > 0) {
+        if (css_get_color(&fg_color, buf))
+            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;
+        }
+    }
+    fg = get_tty_color(fg_color, xterm_colors, QE_TERM_FG_COLORS);
+    bg = get_tty_color(bg_color, xterm_colors, QE_TERM_BG_COLORS);
+
+    return QE_TERM_COMPOSITE | style | QE_TERM_MAKE_COLOR(fg, bg);
+}
+
 static void do_set_region_color(EditState *s, const char *str)
 {
     int offset, size, style;
@@ -1068,7 +1149,7 @@
         size = -size;
     }
     if (size > 0) {
-        eb_create_style_buffer(s->b, BF_STYLE2);
+        eb_create_style_buffer(s->b, QE_TERM_STYLE_BITS <= 16 ? BF_STYLE2 : 
BF_STYLE4);
         eb_set_style(s->b, style, LOGOP_WRITE, offset, size);
     }
 }
@@ -1095,7 +1176,7 @@
         size = -size;
     }
     if (size > 0) {
-        eb_create_style_buffer(s->b, BF_STYLE2);
+        eb_create_style_buffer(s->b, QE_TERM_STYLE_BITS <= 16 ? BF_STYLE2 : 
BF_STYLE4);
         eb_set_style(s->b, style, LOGOP_WRITE, offset, size);
     }
 }
@@ -1326,7 +1407,7 @@
     eb_printf(b1, "%*s: %d, %d\n", w, "xleft, ytop", s->xleft, s->ytop);
     eb_printf(b1, "%*s: %d, %d\n", w, "width, height", s->width, s->height);
     eb_printf(b1, "%*s: %d, %d, %d, %d\n", w, "x1, y1, x2, y2", s->x1, s->y1, 
s->x2, s->y2);
-    eb_printf(b1, "%*s: %#x %s%s%s%s%s%s\n", w, "flags", s->flags,
+    eb_printf(b1, "%*s: %#x%s%s%s%s%s%s\n", w, "flags", s->flags,
               (s->flags & WF_POPUP) ? " POPUP" : "",
               (s->flags & WF_MODELINE) ? " MODELINE" : "",
               (s->flags & WF_RSEPARATOR) ? " RSEPARATOR" : "",

Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.244
retrieving revision 1.245
diff -u -b -r1.244 -r1.245
--- qe.h        31 Mar 2017 15:33:02 -0000      1.244
+++ qe.h        2 Apr 2017 01:12:01 -0000       1.245
@@ -1375,18 +1375,77 @@
     ModeDef *next;
 };
 
-/* special bit to indicate tty styles (for shell mode) */
-#define QE_STYLE_TTY       0x800
-#define TTY_UNDERLINE      0
-#define TTY_BOLD           (1 << 7)
-#define TTY_BLINK          (1 << 3)
-#define TTY_DEFFG          7
-#define TTY_DEFBG          0
-#define TTY_MAKE_COLOR(fg, bg)  (((fg) << 4) | (bg))
-#define TTY_SET_FG_COLOR(color, fg)   ((color) = ((color) & ~(15 << 4)) | 
((fg) << 4))
-#define TTY_SET_BG_COLOR(color, bg)   ((color) = ((color) & ~(15)) | ((bg)))
-#define TTY_GET_FG(color)  (((color) >> 4) & 15)
-#define TTY_GET_BG(color)  (((color) >> 0) & 15)
+#if 0  /* new composite style scheme */
+
+/* A qemacs style is a named set of attributes including:
+ * - colors for foreground and background
+ * - font style bits
+ * - font style size
+ *
+ * Styles are applied to text in successive phases:
+ * - the current syntax mode computes style numbers for each character
+ *   on the line. These nubers are stored into the high bits of the
+ *   32-bit code point.
+ * - these style numbers are then extracted into an array of 32-bit composite
+ *   style values.
+ * - the styles from the optional style buffer are combined into these style
+ *   values.
+ * - search matches and selection styles are applied if relevant.
+ * - the bidirectional algorithm is applied to compute the display order
+ * - sequences of code-point with the same compsite style are formed into
+ *   display units, ligatures are applied.
+ * - the composite style is expanded and converted into display attributes
+ *   to trace the display unit on the device surface
+ */
+
+/* Style numbers are limited to 8 bits, the default set has 27 entries */
+/* Composite styles are 32-bit values that specify
+ * - a style number
+ * - display attributes for underline, bold, blink
+ * - text and background colors as either palette numbers or 4096 rgb values
+ */
+
+#define QE_TERM_STYLE_BITS  32
+#define QE_STYLE_NUM        0x00FF
+#define QE_STYLE_SEL        0x0100  /* special selection style (cumulative 
with another style) */
+#define QE_TERM_COMPOSITE   0x0200  /* special bit to indicate qe-term 
composite style */
+#define QE_TERM_UNDERLINE   0x0400
+#define QE_TERM_BOLD        0x0800
+#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_FG_BITS     8
+#define QE_TERM_FG_SHIFT    16
+
+#else
+
+#define QE_TERM_STYLE_BITS  16
+#define QE_STYLE_NUM        0x00FF
+#define QE_STYLE_SEL        0x0100  /* special selection style (cumulative 
with another style) */
+#define QE_TERM_COMPOSITE   0x0200  /* special bit to indicate qe-term 
composite style */
+#define QE_TERM_UNDERLINE   0x0400
+#define QE_TERM_BOLD        0x0800
+#define QE_TERM_ITALIC      0x1000
+#define QE_TERM_BLINK       0x2000
+#define QE_TERM_BG_BITS     4
+#define QE_TERM_BG_SHIFT    0
+#define QE_TERM_FG_BITS     4
+#define QE_TERM_FG_SHIFT    4
+
+#endif
+
+#define QE_TERM_DEF_FG      7
+#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_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)
 
 QEModeData *qe_create_buffer_mode_data(EditBuffer *b, ModeDef *m);
 void *qe_get_buffer_mode_data(EditBuffer *b, ModeDef *m, EditState *e);
@@ -1397,16 +1456,11 @@
 /* from tty.c */
 /* set from command line option to prevent GUI such as X11 */
 extern int force_tty;
-extern unsigned int const *tty_bg_colors;
-extern int tty_bg_colors_count;
-extern unsigned int const *tty_fg_colors;
-extern int tty_fg_colors_count;
-int get_tty_color(QEColor color, unsigned int const *colors, int count);
+extern QEColor const xterm_colors[];
+/* XXX: should have a more generic API with precomputed mapping scales */
+int get_tty_color(QEColor color, QEColor const *colors, int count);
 int get_tty_style(const char *style);
 
-/* special selection style (cumulative with another style) */
-#define QE_STYLE_SEL     0x400
-
 enum QEStyle {
 #define STYLE_DEF(constant, name, fg_color, bg_color, \
                   font_style, font_size) \

Index: tty.c
===================================================================
RCS file: /sources/qemacs/qemacs/tty.c,v
retrieving revision 1.74
retrieving revision 1.75
diff -u -b -r1.74 -r1.75
--- tty.c       16 Mar 2017 17:18:29 -0000      1.74
+++ tty.c       2 Apr 2017 01:12:01 -0000       1.75
@@ -1,5 +1,5 @@
 /*
- * TTY handling for QEmacs
+ * TTY Terminal handling for QEmacs
  *
  * Copyright (c) 2000-2001 Fabrice Bellard.
  * Copyright (c) 2002-2017 Charlie Gordon.
@@ -35,28 +35,40 @@
 
 #if MAX_UNICODE_DISPLAY > 0xFFFF
 typedef uint64_t TTYChar;
-#define TTYCHAR(ch,fg,bg)   ((uint32_t)(ch) | ((uint64_t)((fg) | ((bg) << 8)) 
<< 32))
+/* TTY composite style has 8 bit color number for FG and BG plus attribute 
bits */
+#define TTY_STYLE_BITS      32
+#define TTYCHAR(ch,fg,bg)   ((uint32_t)(ch) | ((uint64_t)((fg) | ((bg) << 16)) 
<< 32))
 #define TTYCHAR2(ch,col)    ((uint32_t)(ch) | ((uint64_t)(col) << 32))
 #define TTYCHAR_GETCH(cc)   ((uint32_t)(cc))
-#define TTYCHAR_GETCOL(cc)  ((uint32_t)((cc) >> 32) & 0xFFFF)
+#define TTYCHAR_GETCOL(cc)  ((uint32_t)((cc) >> 32))
 #define TTYCHAR_GETFG(cc)   ((uint32_t)((cc) >> 32) & 0xFF)
-#define TTYCHAR_GETBG(cc)   ((uint32_t)((cc) >> (32 + 8)) & 0xFF)
+#define TTYCHAR_GETBG(cc)   ((uint32_t)((cc) >> (32 + 16)) & 0xFF)
 #define TTYCHAR_DEFAULT     TTYCHAR(' ', 7, 0)
 #define TTYCHAR_COMB        0x200000
 #define TTYCHAR_BAD         0xFFFD
 #define TTYCHAR_NONE        0xFFFFFFFF
+#define TTY_BOLD            0x0100
+#define TTY_UNDERLINE       0x0200
+#define TTY_BLINK           0x0400
+#define TTY_ITALIC          0x0800
 #define COMB_CACHE_SIZE     2048
 #else
-typedef unsigned int TTYChar;
-#define TTYCHAR(ch,fg,bg)   ((ch) | ((fg) << 16) | ((bg) << 24))
-#define TTYCHAR2(ch,col)    ((ch) | ((col) << 16))
+typedef uint32_t TTYChar;
+/* TTY composite style has 4 bit color number for FG and BG plus attribute 
bits */
+#define TTY_STYLE_BITS      16
+#define TTYCHAR(ch,fg,bg)   ((uint32_t)(ch) | ((uint32_t)((fg) | ((bg) << 12)) 
<< 16))
+#define TTYCHAR2(ch,col)    ((uint32_t)(ch) | ((uint32_t)(col) << 16))
 #define TTYCHAR_GETCH(cc)   ((cc) & 0xFFFF)
 #define TTYCHAR_GETCOL(cc)  (((cc) >> 16) & 0xFFFF)
 #define TTYCHAR_GETFG(cc)   (((cc) >> 16) & 0xFF)
-#define TTYCHAR_GETBG(cc)   (((cc) >> 24) & 0xFF)
+#define TTYCHAR_GETBG(cc)   (((cc) >> (16 + 8)) & 0xFF)
 #define TTYCHAR_DEFAULT     TTYCHAR(' ', 7, 0)
 #define TTYCHAR_BAD         0xFFFD
 #define TTYCHAR_NONE        0xFFFF
+#define TTY_BOLD            0x0100
+#define TTY_UNDERLINE       0x0200
+#define TTY_BLINK           0x0400
+#define TTY_ITALIC          0x0800
 #define COMB_CACHE_SIZE     1
 #endif
 
@@ -105,10 +117,15 @@
     char *term_name;
     enum TermCode term_code;
     int term_flags;
-#define KBS_CONTROL_H          1
-#define USE_BOLD_AS_BRIGHT     2
-#define USE_BLINK_AS_BRIGHT    4
-#define USE_ERASE_END_OF_LINE  8
+#define KBS_CONTROL_H           0x01
+#define USE_ERASE_END_OF_LINE   0x02
+#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
+    const QEColor *term_colors;
+    int term_fg_colors_count;
+    int term_bg_colors_count;
     unsigned int comb_cache[COMB_CACHE_SIZE];
 } TTYState;
 
@@ -144,6 +161,10 @@
     /* Derive some settings from the TERM environment variable */
     ts->term_code = TERM_UNKNOWN;
     ts->term_flags = USE_ERASE_END_OF_LINE;
+    ts->term_colors = xterm_colors;
+    ts->term_fg_colors_count = 16;
+    ts->term_bg_colors_count = 16;
+
     ts->term_name = getenv("TERM");
     if (ts->term_name) {
         /* linux and xterm -> kbs=\177
@@ -166,8 +187,29 @@
         if (strstart(ts->term_name, "cygwin", NULL)) {
             ts->term_code = TERM_CYGWIN;
             ts->term_flags |= KBS_CONTROL_H |
-                                    USE_BOLD_AS_BRIGHT | USE_BLINK_AS_BRIGHT;
+                              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 (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")) {
+            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;
         }
+#endif
+    }
+
+    if (ts->term_flags & (USE_256_COLORS | USE_24_BIT_COLORS)) {
+        ts->term_fg_colors_count = 256;
+#if TTY_STYLE_BITS == 32
+        ts->term_bg_colors_count = 256;
+#endif
     }
 
     tcgetattr(fileno(s->STDIN), &tty);
@@ -593,7 +635,7 @@
 }
 
 #if 0
-unsigned int const tty_full_colors[8] = {
+static QEColor const tty_full_colors[8] = {
     QERGB(0x00, 0x00, 0x00),
     QERGB(0xff, 0x00, 0x00),
     QERGB(0x00, 0xff, 0x00),
@@ -605,7 +647,7 @@
 };
 #endif
 
-static unsigned int const tty_putty_colors[256] = {
+QEColor const xterm_colors[256] = {
     QERGB(0x00, 0x00, 0x00),
     QERGB(0xbb, 0x00, 0x00),
     QERGB(0x00, 0xbb, 0x00),
@@ -875,19 +917,49 @@
 #endif
 };
 
-unsigned int const *tty_bg_colors = tty_putty_colors;
-int tty_bg_colors_count = 16;
-unsigned int const *tty_fg_colors = tty_putty_colors;
-int tty_fg_colors_count = 16;
+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 */
+#define REP5(x)   (x), (x), (x), (x), (x)
+#define REP10(x)  REP5(x), REP5(x)
+#define REP20(x)  REP10(x), REP10(x)
+#define REP40(x)  REP20(x), REP20(x)
+#define REP25(x)  REP5(x), REP5(x), REP5(x), REP5(x), REP5(x)
+#define REP47(x)  REP10(x), REP10(x), REP10(x), REP10(x), REP5(x), (x), (x)
+    REP47(0), REP47(1), REP20(1), REP40(2), REP40(3), REP40(4), REP20(5), 5
+};
+
+static unsigned char const scale_grey[256] = {
+    /* This array is used for mapping gray levels to the standard palette */
+    /* 232..255: 24 entry grey scale 8,18..238 */
+    16, 16, 16, 16,
+    REP10(232), REP10(233), REP10(234), REP10(235),
+    REP10(236), REP10(237), REP10(238), REP10(239), 
+    REP10(240), REP10(241), REP10(242), REP10(243), 
+    REP10(244), REP10(245), REP10(246), REP10(247),
+    REP10(248), REP10(249), REP10(250), REP10(251),
+    REP10(252), REP10(253), REP10(254), REP10(255),
+    255, 255, 255,
+    231, 231, 231, 231, 231, 231, 231, 231, 231
+};
 
-static inline int color_dist(unsigned int c1, unsigned int c2) {
+static inline int color_dist(QEColor c1, QEColor c2) {
     /* using casts because c1 and c2 are unsigned */
+#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)) +
                 abs((int)((c1 >> 16) & 0xff) - (int)((c2 >> 16) & 0xff));
+#else
+    /* using different weights to R, G, B according to luminance levels */
+    return  11 * abs((int)((c1 >>  0) & 0xff) - (int)((c2 >>  0) & 0xff)) +
+            59 * abs((int)((c1 >>  8) & 0xff) - (int)((c2 >>  8) & 0xff)) +
+            30 * abs((int)((c1 >> 16) & 0xff) - (int)((c2 >> 16) & 0xff));
+#endif
 }
 
-int get_tty_color(QEColor color, unsigned int const *colors, int count)
+/* XXX: should have a more generic API with precomputed mapping scales */
+int get_tty_color(QEColor color, QEColor const *colors, int count)
 {
     int i, cmin, dmin, d;
 
@@ -900,6 +972,29 @@
             dmin = d;
         }
     }
+#if 1
+    if (dmin > 0 && count > 16) {
+        unsigned int r = (color >> 16) & 0xff;
+        unsigned int g = (color >>  8) & 0xff;
+        unsigned int b = (color >>  0) & 0xff;
+        if (r == g && g == b) {
+            i = scale_grey[r];
+            d = color_dist(color, colors[i]);
+            if (d < dmin) {
+                cmin = i;
+                dmin = d;
+            }
+        } else {
+            /* XXX: should use more precise projection */
+            i = scale_cube[r] * 36 + scale_cube[g] * 6 + scale_cube[b];
+            d = color_dist(color, colors[i]);
+            if (d < dmin) {
+                cmin = i;
+                dmin = d;
+            }
+        }
+    }
+#endif
     return cmin;
 }
 
@@ -925,7 +1020,7 @@
             ptr += wrap;
         }
     } else {
-        bgcolor = get_tty_color(color, tty_bg_colors, tty_bg_colors_count);
+        bgcolor = get_tty_color(color, ts->term_colors, 
ts->term_bg_colors_count);
         for (y = y1; y < y2; y++) {
             ts->line_updated[y] = 1;
             for (x = x1; x < x2; x++) {
@@ -937,79 +1032,6 @@
     }
 }
 
-static int str_get_word(char *buf, int size, const char *p, const char **pp)
-{
-    int len;
-
-    while (*p == ' ')
-        p++;
-
-    for (len = 0; *p != '\0' && *p != ' ' && *p != '/'; p++, len++) {
-        if (len < size - 1)
-            buf[len] = *p;
-    }
-    if (len < size - 1)
-        buf[len] = '\0';
-
-    while (*p == ' ')
-        p++;
-
-    if (pp)
-        *pp = p;
-
-    return len;
-}
-
-/* match a keyword, ignore case, check word boundary */
-static int str_match_word(const char *str, const char *val, const char **pp)
-{
-    if (stristart(str, val, &str) && (*str == '\0' || *str == ' ')) {
-        while (*str == ' ')
-            str++;
-        if (pp)
-            *pp = str;
-        return 1;
-    }
-    return 0;
-}
-
-int get_tty_style(const char *str)
-{
-    char buf[128];
-    QEColor fg_color, bg_color;
-    int fg, bg, style;
-    const char *p = str;
-
-    style = 0;
-    for (;;) {
-        if (str_match_word(p, "bold", &p)) {
-            style |= TTY_BOLD;
-            continue;
-        }
-        if (str_match_word(p, "blinking", &p)
-        ||  str_match_word(p, "blink", &p)) {
-            style |= TTY_BLINK;
-            continue;
-        }
-        break;
-    }
-    fg_color = QERGB(0xbb, 0xbb, 0xbb);
-    bg_color = QERGB(0x00, 0x00, 0x00);
-    if (str_get_word(buf, sizeof(buf), p, &p)) {
-        if (css_get_color(&fg_color, buf))
-            return -1;
-        if (str_match_word(p, "on", &p) || (*p == '/' && p++)) {
-            str_get_word(buf, sizeof(buf), p, &p);
-            if (css_get_color(&bg_color, buf))
-                return -1;
-        }
-    }
-    fg = get_tty_color(fg_color, tty_fg_colors, tty_fg_colors_count);
-    bg = get_tty_color(bg_color, tty_fg_colors, tty_fg_colors_count);
-
-    return QE_STYLE_TTY | style | TTY_MAKE_COLOR(fg, bg);
-}
-
 /* XXX: could alloc font in wrapper */
 static QEFont *tty_term_open_font(qe__unused__ QEditScreen *s,
                                   qe__unused__ int style, qe__unused__ int 
size)
@@ -1121,7 +1143,30 @@
     TTYState *ts = s->priv_data;
     unsigned int *ip;
     unsigned int i;
+    int w = 16;
+
+    eb_printf(b, "Device Description\n\n");
+
+    eb_printf(b, "%*s: %s\n", w, "term_name", ts->term_name);
+    eb_printf(b, "%*s: %d  %s\n", w, "term_code", ts->term_code,
+              ts->term_code == TERM_UNKNOWN ? "UNKNOWN" :
+              ts->term_code == TERM_ANSI ? "ANSI" :
+              ts->term_code == TERM_VT100 ? "VT100" :
+              ts->term_code == TERM_XTERM ? "XTERM" :
+              ts->term_code == TERM_LINUX ? "LINUX" :
+              ts->term_code == TERM_CYGWIN ? "CYGWIN" :
+              "");
+    eb_printf(b, "%*s: %#x %s%s%s%s%s%s\n", w, "term_flags", ts->term_flags,
+              ts->term_flags & KBS_CONTROL_H ? " KBS_CONTROL_H" : "",
+              ts->term_flags & USE_ERASE_END_OF_LINE ? " 
USE_ERASE_END_OF_LINE" : "",
+              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_fg_colors_count, ts->term_bg_colors_count);
 
+    eb_printf(b, "\n");
     eb_printf(b, "Unicode combination cache:\n\n");
     
     for (ip = ts->comb_cache; *ip != 0; ip += *ip & 0xFFFF) {
@@ -1158,7 +1203,15 @@
         return;
 
     ts->line_updated[y] = 1;
-    fgcolor = get_tty_color(color, tty_fg_colors, tty_fg_colors_count);
+    fgcolor = get_tty_color(color, ts->term_colors, ts->term_fg_colors_count);
+    if (font->style & QE_STYLE_UNDERLINE)
+        fgcolor |= TTY_UNDERLINE;
+    if (font->style & QE_STYLE_BOLD)
+        fgcolor |= TTY_BOLD;
+    if (font->style & QE_STYLE_BLINK)
+        fgcolor |= TTY_BLINK;
+    if (font->style & QE_STYLE_ITALIC)
+        fgcolor |= TTY_ITALIC;
     ptr = ts->screen + y * s->width;
 
     if (x < s->clip_x1) {
@@ -1237,7 +1290,7 @@
 {
     TTYState *ts = s->priv_data;
     TTYChar *ptr, *ptr1, *ptr2, *ptr3, *ptr4, cc, blankcc;
-    int y, shadow, ch, bgcolor, fgcolor, shifted;
+    int y, shadow, ch, bgcolor, fgcolor, shifted, attr;
 
     TTY_FPUTS("\033[H\033[0m", s->STDOUT);
 
@@ -1247,6 +1300,7 @@
 
     bgcolor = -1;
     fgcolor = -1;
+    attr = 0;
     shifted = 0;
 
     /* CG: Should optimize output by computing it in a temporary buffer
@@ -1298,7 +1352,7 @@
              */
             if ((ts->term_flags & USE_ERASE_END_OF_LINE)
             &&  TTYCHAR_GETCH(ptr4[-1]) == ' '
-            &&  (/*!(ts->term_flags & USE_BLINK_AS_BRIGHT) ||*/
+            &&  (/*!(ts->term_flags & USE_BLINK_AS_BRIGHT_BG) ||*/
                  TTYCHAR_GETBG(ptr4[-1]) < 8))
             {
                 /* find the last non blank char on row */
@@ -1341,15 +1395,18 @@
                     if (bgcolor != (int)TTYCHAR_GETBG(cc)) {
                         int lastbg = bgcolor;
                         bgcolor = TTYCHAR_GETBG(cc);
-                        if (ts->term_flags & USE_BLINK_AS_BRIGHT) {
+                        if (ts->term_flags & (USE_256_COLORS | 
USE_24_BIT_COLORS)) {
+                            TTY_FPRINTF(s->STDOUT, "\033[48;5;%dm", bgcolor);
+                        } else
+                        if (ts->term_flags & USE_BLINK_AS_BRIGHT_BG) {
                             if (bgcolor > 7) {
                                 if (lastbg <= 7) {
                                     TTY_FPUTS("\033[5m", s->STDOUT);
                                 }
                             } else {
                                 if (lastbg > 7) {
-                                    TTY_FPUTS("\033[0m", s->STDOUT);
-                                    fgcolor = -1;
+                                    TTY_FPUTS("\033[25m", s->STDOUT);
+                                    //fgcolor = -1;
                                 }
                             }
                             TTY_FPRINTF(s->STDOUT, "\033[%dm",
@@ -1365,16 +1422,19 @@
                     if (fgcolor != (int)TTYCHAR_GETFG(cc)) {
                         int lastfg = fgcolor;
                         fgcolor = TTYCHAR_GETFG(cc);
-                        if (ts->term_flags & USE_BOLD_AS_BRIGHT) {
+                        if (ts->term_flags & (USE_256_COLORS | 
USE_24_BIT_COLORS)) {
+                            TTY_FPRINTF(s->STDOUT, "\033[38;5;%dm", fgcolor);
+                        } else
+                        if (ts->term_flags & USE_BOLD_AS_BRIGHT_FG) {
                             if (fgcolor > 7) {
                                 if (lastfg <= 7) {
                                     TTY_FPUTS("\033[1m", s->STDOUT);
                                 }
                             } else {
                                 if (lastfg > 7) {
-                                    TTY_FPUTS("\033[0m", s->STDOUT);
-                                    fgcolor = -1;
-                                    bgcolor = -1;
+                                    TTY_FPUTS("\033[22m", s->STDOUT);
+                                    //fgcolor = -1;
+                                    //bgcolor = -1;
                                     goto again;
                                 }
                             }
@@ -1386,6 +1446,41 @@
                                         30 + fgcolor);
                         }
                     }
+#if 1
+                    if (attr != (int)TTYCHAR_GETCOL(cc)) {
+                        int lastattr = attr;
+                        attr = TTYCHAR_GETCOL(cc);
+
+                        if ((attr ^ lastattr) & TTY_BOLD) {
+                            if (attr & TTY_BOLD) {
+                                TTY_FPUTS("\033[1m", s->STDOUT);
+                            } else {
+                                TTY_FPUTS("\033[22m", s->STDOUT);
+                            }
+                        }
+                        if ((attr ^ lastattr) & TTY_UNDERLINE) {
+                            if (attr & TTY_UNDERLINE) {
+                                TTY_FPUTS("\033[4m", s->STDOUT);
+                            } else {
+                                TTY_FPUTS("\033[24m", s->STDOUT);
+                            }
+                        }
+                        if ((attr ^ lastattr) & TTY_BLINK) {
+                            if (attr & TTY_BLINK) {
+                                TTY_FPUTS("\033[5m", s->STDOUT);
+                            } else {
+                                TTY_FPUTS("\033[25m", s->STDOUT);
+                            }
+                        }
+                        if ((attr ^ lastattr) & TTY_ITALIC) {
+                            if (attr & TTY_ITALIC) {
+                                TTY_FPUTS("\033[3m", s->STDOUT);
+                            } else {
+                                TTY_FPUTS("\033[23m", s->STDOUT);
+                            }
+                        }
+#endif
+                    }
                     if (shifted) {
                         /* Kludge for linedrawing chars */
                         if (ch < 128 || ch >= 128 + 32) {
@@ -1477,11 +1572,12 @@
                     ptr1++;
                 }
             }
-//            if (ts->term_flags & USE_BLINK_AS_BRIGHT)
+//            if (ts->term_flags & USE_BLINK_AS_BRIGHT_BG)
             {
                 if (bgcolor > 7) {
                     TTY_FPUTS("\033[0m", s->STDOUT);
                     fgcolor = bgcolor = -1;
+                    attr = 0;
                 }
             }
         }

Index: VERSION
===================================================================
RCS file: /sources/qemacs/qemacs/VERSION,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- VERSION     28 Jul 2015 19:03:52 -0000      1.4
+++ VERSION     2 Apr 2017 01:12:01 -0000       1.5
@@ -1 +1 @@
-0.4.1dev
+0.5.0dev

Index: display.h
===================================================================
RCS file: /sources/qemacs/qemacs/display.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- display.h   15 Mar 2017 07:24:31 -0000      1.18
+++ display.h   2 Apr 2017 01:12:01 -0000       1.19
@@ -31,6 +31,7 @@
 #define QE_STYLE_ITALIC       0x0004
 #define QE_STYLE_UNDERLINE    0x0008
 #define QE_STYLE_LINE_THROUGH 0x0010
+#define QE_STYLE_BLINK        0x0020
 #define QE_STYLE_MASK         0x00ff
 
 #define NB_FONT_FAMILIES      3

Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.259
retrieving revision 1.260
diff -u -b -r1.259 -r1.260
--- qe.c        31 Mar 2017 15:33:02 -0000      1.259
+++ qe.c        2 Apr 2017 01:12:01 -0000       1.260
@@ -2588,6 +2588,10 @@
             }
             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));
+        }
     }
     eb_get_pos(s->b, &line_num, &col_num, s->offset);
     put_status(s, "%s  point=%d mark=%d size=%d region=%d col=%d",
@@ -2754,14 +2758,17 @@
 {
     QEStyleDef *s;
 
-#ifndef CONFIG_WIN32
-    if (style_index & QE_STYLE_TTY) {
-        style->fg_color = tty_fg_colors[TTY_GET_FG(style_index)];
-        style->bg_color = tty_bg_colors[TTY_GET_BG(style_index)];
-    } else
-#endif
-    {
-        s = &qe_styles[style_index & ~QE_STYLE_SEL];
+    if (style_index & QE_TERM_COMPOSITE) {
+        style->fg_color = xterm_colors[QE_TERM_GET_FG(style_index)];
+        style->bg_color = xterm_colors[QE_TERM_GET_BG(style_index)];
+        if (style_index & QE_TERM_UNDERLINE)
+            style->font_style |= QE_STYLE_UNDERLINE;
+        if (style_index & QE_TERM_BOLD)
+            style->font_style |= QE_STYLE_BOLD;
+        if (style_index & QE_TERM_BLINK)
+            style->font_style |= QE_STYLE_BLINK;
+    } else {
+        s = &qe_styles[style_index & QE_STYLE_NUM];
         if (s->fg_color != COLOR_TRANSPARENT)
             style->fg_color = s->fg_color;
         if (s->bg_color != COLOR_TRANSPARENT)
@@ -4135,7 +4142,7 @@
             if (char_index < colored_nb_chars) {
                 /* colored_chars should just be a style array */
                 c = colored_chars[char_index];
-                ds->style = c >> STYLE_SHIFT;
+                ds->style = (unsigned int)c >> STYLE_SHIFT;
             }
             c = eb_nextc(s->b, offset, &offset);
             if (c == '\n' && !s->minibuf) {

Index: shell.c
===================================================================
RCS file: /sources/qemacs/qemacs/shell.c,v
retrieving revision 1.120
retrieving revision 1.121
diff -u -b -r1.120 -r1.121
--- shell.c     31 Mar 2017 07:42:44 -0000      1.120
+++ shell.c     2 Apr 2017 01:12:01 -0000       1.121
@@ -43,13 +43,13 @@
 
 #define MAX_ESC_PARAMS 6
 
-enum TTYState {
-    TTY_STATE_NORM,
-    TTY_STATE_UTF8,
-    TTY_STATE_ESC,
-    TTY_STATE_ESC2,
-    TTY_STATE_CSI,
-    TTY_STATE_STRING,
+enum QETermState {
+    QE_TERM_STATE_NORM,
+    QE_TERM_STATE_UTF8,
+    QE_TERM_STATE_ESC,
+    QE_TERM_STATE_ESC2,
+    QE_TERM_STATE_CSI,
+    QE_TERM_STATE_STRING,
 };
 
 typedef struct ShellState {
@@ -57,7 +57,7 @@
     /* buffer state */
     int pty_fd;
     int pid; /* -1 if not launched */
-    int color, attr, def_color;
+    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 esc_params[MAX_ESC_PARAMS];
@@ -173,9 +173,9 @@
     return shell_path;
 }
 
-#define TTY_XSIZE  80
-#define TTY_YSIZE  25
-#define TTY_YSIZE_INFINITE  10000
+#define QE_TERM_XSIZE  80
+#define QE_TERM_YSIZE  25
+#define QE_TERM_YSIZE_INFINITE  10000
 
 static int run_process(const char *cmd, int *fd_ptr, int *pid_ptr,
                        int cols, int rows, int shell_flags)
@@ -262,16 +262,18 @@
                                eb_trace_bytes(" <-- "m" ", -1, \
                                EB_TRACE_SHELL); } while (0) */
 
-static void tty_init(ShellState *s)
+static void qe_term_init(ShellState *s)
 {
     char *term;
 
-    s->state = TTY_STATE_NORM;
+    s->state = QE_TERM_STATE_NORM;
     /* Should compute def_color from shell default style at display
      * time and force full redisplay upon style change.
      */
-    s->color = s->def_color = TTY_MAKE_COLOR(TTY_DEFFG, TTY_DEFBG);
     s->attr = 0;
+    s->fgcolor = QE_TERM_DEF_FG;
+    s->bgcolor = QE_TERM_DEF_BG;
+    s->reverse = 0;
 
     term = getenv("TERM");
     /* vt100 terminfo definitions */
@@ -415,7 +417,7 @@
 }
 
 // XXX: should use an auxiliary buffer to make this asynchous
-static void tty_write(ShellState *s, const char *buf, int len)
+static void qe_term_write(ShellState *s, const char *buf, int len)
 {
     int ret;
 
@@ -437,12 +439,23 @@
     }
 }
 
+static inline void qe_term_set_setyle(ShellState *s) {
+    int composite_color;
+
+    if (s->reverse) {
+        composite_color = QE_TERM_MAKE_COLOR(s->bgcolor, s->fgcolor);
+    } else {
+        composite_color = QE_TERM_MAKE_COLOR(s->fgcolor, s->bgcolor);
+    }
+    s->b->cur_style = QE_TERM_COMPOSITE | s->attr | composite_color;
+}
+
 /* Compute offset of the char at column x and row y (0 based).
  * Can insert spaces or rows if needed.
  * x and y may each be relative to the current position.
  */
 /* XXX: optimize !!!!! */
-static void tty_goto_xy(ShellState *s, int x, int y, int relative)
+static void qe_term_goto_xy(ShellState *s, int x, int y, int relative)
 {
     int total_lines, cur_line, line_num, col_num, offset, offset1, c;
 
@@ -452,7 +465,7 @@
     ||  eb_prevc(s->b, s->b->total_size, &offset1) != '\n')
         total_lines++;
 
-    line_num = total_lines - TTY_YSIZE;
+    line_num = total_lines - QE_TERM_YSIZE;
     if (line_num < 0)
         line_num = 0;
 
@@ -466,11 +479,11 @@
         if (relative & 2)
             y += cur_line;
     }
-    if (y < 0 || y >= TTY_YSIZE_INFINITE - 1)
+    if (y < 0 || y >= QE_TERM_YSIZE_INFINITE - 1)
         y = 0;
     else
-    if (y >= TTY_YSIZE)
-        y = TTY_YSIZE - 1;
+    if (y >= QE_TERM_YSIZE)
+        y = QE_TERM_YSIZE - 1;
     if (x < 0)
         x = 0;
 
@@ -478,7 +491,7 @@
     /* add lines if necessary */
     while (line_num >= total_lines) {
         /* XXX: color may be wrong */
-        s->b->cur_style = QE_STYLE_TTY | s->color | s->attr;
+        qe_term_set_setyle(s);
         eb_insert_uchar(s->b, s->b->total_size, '\n');
         total_lines++;
     }
@@ -497,7 +510,7 @@
 }
 
 /* CG: XXX: tty_put_char purposely ignores charset when inserting chars */
-static int tty_put_char(ShellState *s, int c)
+static int qe_term_put_char(ShellState *s, int c)
 {
     char buf[1];
     int c1, cur_len, offset, offset1;
@@ -505,7 +518,7 @@
     offset = s->cur_offset;
     buf[0] = c;
     c1 = eb_nextc(s->b, offset, &offset1);
-    s->b->cur_style = QE_STYLE_TTY | s->color | s->attr;
+    qe_term_set_setyle(s);
     if (c1 == '\n') {
         /* insert */
         eb_insert(s->b, offset, buf, 1);
@@ -524,7 +537,7 @@
     return s->cur_offset = offset + 1;
 }
 
-static void tty_csi_m(ShellState *s, int c, int has_param)
+static void qe_term_csi_m(ShellState *s, int c, int has_param)
 {
     /* Comment from putty/terminal.c:
      *
@@ -558,32 +571,43 @@
 
     switch (has_param ? c : 0) {
     case 0:     /* exit_attribute_mode */
-        s->color = s->def_color;
+        s->fgcolor = QE_TERM_DEF_FG;
+        s->bgcolor = QE_TERM_DEF_BG;
+        s->reverse = 0;
         s->attr = 0;
         break;
     case 1:     /* enter_bold_mode */
-        s->attr |= TTY_BOLD;
+        s->attr |= QE_TERM_BOLD;
         break;
-    case 22:    /* exit_bold_mode */
-        s->attr &= ~TTY_BOLD;
+    case 3:     /* enter_italic_mode */
+        s->attr |= QE_TERM_ITALIC;
         break;
     case 4:     /* enter_underline_mode */
-        s->attr |= TTY_UNDERLINE;
-        break;
-    case 24:    /* exit_underline_mode */
-        s->attr &= ~TTY_UNDERLINE;
+        s->attr |= QE_TERM_UNDERLINE;
         break;
     case 5:     /* enter_blink_mode */
-        s->attr |= TTY_BLINK;
+        s->attr |= QE_TERM_BLINK;
+        break;
+    case 7:     /* enter_reverse_mode, enter_standout_mode */
+                /* also Xenix combined reverse fg/bg: \027[7;FG;BGm */
+        s->reverse = 1;
+        break;
+    case 22:    /* exit_bold_mode */
+        s->attr &= ~QE_TERM_BOLD;
+        break;
+    case 23:    /* exit_italic_mode */
+        s->attr &= ~QE_TERM_ITALIC;
+        break;
+    case 24:    /* exit_underline_mode */
+        s->attr &= ~QE_TERM_UNDERLINE;
         break;
     case 25:    /* exit_blink_mode */
-        s->attr &= ~TTY_BLINK;
+        s->attr &= ~QE_TERM_BLINK;
         break;
-    case 7:     /* enter_reverse_mode, enter_standout_mode */
     case 27:    /* exit_reverse_mode, exit_standout_mode */
-        /* TODO */
-        TRACE_MSG("unhandled");
+        s->reverse = 0;
         break;
+    case 2:     /* Xenix combined fg/bg: \027[2;FG;BGm */
     case 6:     /* SCO light background */
     case 8:     /* enter_secure_mode */
     case 9:     /* cygwin dim mode */
@@ -594,35 +618,54 @@
         TRACE_MSG("unhandled");
         break;
     case 39:    /* orig_pair(1) default-foreground */
-        TTY_SET_FG_COLOR(s->color, TTY_DEFFG);
+        s->fgcolor = QE_TERM_DEF_FG;
         break;
     case 49:    /* orig_pair(2) default-background */
-        TTY_SET_BG_COLOR(s->color, TTY_DEFBG);
+        s->bgcolor = QE_TERM_DEF_BG;
         break;
     case 38:    /* set extended foreground color */
-        /* complete syntax is \033[38;5;Nm where N is in range 1..255 */
         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];
 
-            /* simulate 256 colors */
-            color = get_tty_color(tty_fg_colors[color & 255],
-                                  tty_fg_colors, 16);
+            /* map color to qe-term palette */
+            s->fgcolor = get_tty_color(rgb, xterm_colors, QE_TERM_FG_COLORS);
+            s->nb_esc_params = 1;
+        } 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,
+                                s->esc_params[3] & 255,
+                                s->esc_params[4] & 255);
 
-            TTY_SET_FG_COLOR(s->color, color);
+            /* map 24-bit colors to qe-term palette */
+            s->fgcolor = get_tty_color(rgb, xterm_colors, QE_TERM_FG_COLORS);
             s->nb_esc_params = 1;
         }
         break;
     case 48:    /* set extended background color */
-        /* complete syntax is \033[48;5;Nm where N is in range 1..255 */
         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];
+
+            /* map color to qe-term palette */
+            s->bgcolor = get_tty_color(rgb, xterm_colors, QE_TERM_BG_COLORS);
+            s->nb_esc_params = 1;
+        } 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,
+                                s->esc_params[3] & 255,
+                                s->esc_params[4] & 255);
 
-            /* simulate 256 colors */
-            color = get_tty_color(tty_fg_colors[color & 255],
-                                  tty_fg_colors, 16);
-            TTY_SET_BG_COLOR(s->color, color);
+            /* map 24-bit colors to qe-term palette */
+            s->bgcolor = get_tty_color(rgb, xterm_colors, QE_TERM_BG_COLORS);
             s->nb_esc_params = 1;
         }
         break;
@@ -630,19 +673,19 @@
         /* 0:black 1:red 2:green 3:yellow 4:blue 5:magenta 6:cyan 7:white */
         if (c >= 30 && c <= 37) {
             /* set foreground color */
-            TTY_SET_FG_COLOR(s->color, c - 30);
+            s->fgcolor = c - 30;
         } else
         if (c >= 40 && c <= 47) {
             /* set background color */
-            TTY_SET_BG_COLOR(s->color, c - 40);
+            s->bgcolor = c - 40;
         } else
         if (c >= 90 && c <= 97) {
             /* set bright foreground color */
-            TTY_SET_FG_COLOR(s->color, c - 90 + 8);
+            s->fgcolor = c - 90 + 8;
         } else
         if (c >= 100 && c <= 107) {
             /* set bright background color */
-            TTY_SET_BG_COLOR(s->color, c - 100 + 8);
+            s->bgcolor = c - 100 + 8;
         } else {
             TRACE_MSG("unhandled");
         }
@@ -652,7 +695,7 @@
 
 
 /* Well, almost a hack to update cursor */
-static void tty_update_cursor(qe__unused__ ShellState *s)
+static void qe_term_update_cursor(qe__unused__ ShellState *s)
 {
 #if 0
     QEmacsState *qs = s->qe_state;
@@ -758,7 +801,7 @@
         break;
     }
     if (p) {
-        tty_write(s, p, len);
+        qe_term_write(s, p, len);
     }
 }
 
@@ -766,7 +809,7 @@
     0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15,
 };
 
-static void tty_emulate(ShellState *s, int c)
+static void qe_term_emulate(ShellState *s, int c)
 {
     int i, offset, offset1, offset2, n;
     char buf1[10];
@@ -778,10 +821,10 @@
     switch (c) {
     case 0x18:
     case 0x1A:
-        s->state = TTY_STATE_NORM;
+        s->state = QE_TERM_STATE_NORM;
         return;
     case 0x1B:
-        s->state = TTY_STATE_ESC;
+        s->state = QE_TERM_STATE_ESC;
         return;
 #if 0
     case 0x9B:
@@ -790,7 +833,7 @@
     }
 
     switch (s->state) {
-    case TTY_STATE_NORM:
+    case QE_TERM_STATE_NORM:
         switch (c) {
             /* BEL            Bell (Ctrl-G) */
             /* FF             Form Feed or New Page (NP) (Ctrl-L) same as LF */
@@ -803,7 +846,7 @@
                 if (c1 != '\n') {
                     s->cur_offset = offset1;
                     /* back_color_erase */
-                    //tty_put_char(s, ' ');
+                    //qe_term_put_char(s, ' ');
                 }
             }
             break;
@@ -811,7 +854,7 @@
             {
                 int col_num, cur_line;
                 eb_get_pos(s->b, &cur_line, &col_num, offset);
-                tty_goto_xy(s, (col_num + 8) & ~7, 0, 2);
+                qe_term_goto_xy(s, (col_num + 8) & ~7, 0, 2);
                 break;
             }
         case 10:        /* ^J  NL = line feed */
@@ -821,7 +864,7 @@
                 if (offset == s->b->total_size) {
                     /* add a new line */
                     /* CG: XXX: ignoring charset */
-                    s->b->cur_style = QE_STYLE_TTY | s->color | s->attr;
+                    qe_term_set_setyle(s);
                     buf1[0] = '\n';
                     eb_insert(s->b, offset, buf1, 1);
                     offset = s->b->total_size;
@@ -894,7 +937,7 @@
                         if (s->utf8_len > 1) {
                             s->utf8_buf[0] = c;
                             s->utf8_pos = 1;
-                            s->state = TTY_STATE_UTF8;
+                            s->state = QE_TERM_STATE_UTF8;
                             break;
                         }
                     }
@@ -903,8 +946,8 @@
                     len = 1;
                 }
                 c1 = eb_nextc(s->b, offset, &offset1);
-                s->b->cur_style = QE_STYLE_TTY | s->color | s->attr;
-                /* Should simplify with tty_put_char */
+                qe_term_set_setyle(s);
+                /* Should simplify with qe_term_put_char */
                 if (c1 == '\n') {
                     /* insert */
                     eb_insert(s->b, offset, buf1, len);
@@ -924,14 +967,14 @@
             break;
         }
         break;
-    case TTY_STATE_UTF8:
+    case QE_TERM_STATE_UTF8:
         s->utf8_buf[s->utf8_pos++] = c;
         if (s->utf8_pos >= s->utf8_len) {
             int c1, cur_len, len;
 
             len = s->utf8_len;
             c1 = eb_nextc(s->b, offset, &offset1);
-            s->b->cur_style = QE_STYLE_TTY | s->color | s->attr;
+            qe_term_set_setyle(s);
             if (c1 == '\n') {
                 /* insert */
                 eb_insert(s->b, offset, s->utf8_buf, len);
@@ -945,10 +988,10 @@
                 }
             }
             s->cur_offset = offset + len;
-            s->state = TTY_STATE_NORM;
+            s->state = QE_TERM_STATE_NORM;
         }
         break;
-    case TTY_STATE_ESC:
+    case QE_TERM_STATE_ESC:
         if (c == '[') {
             for (i = 0; i < MAX_ESC_PARAMS; i++) {
                 s->esc_params[i] = 1;
@@ -956,7 +999,7 @@
             }
             s->nb_esc_params = 0;
             s->esc1 = 0;
-            s->state = TTY_STATE_CSI;
+            s->state = QE_TERM_STATE_CSI;
         } else {
             /* CG: should deal with other sequences:
              * ansi: hts=\EH, s0ds=\E(B, s1ds=\E)B, s2ds=\E*B, s3ds=\E+B,
@@ -969,6 +1012,8 @@
              *        rc=\E8, ri=\EM, rmkx=\E[?1l\E>, rs1=\Ec,
              *        rs2=\E[!p\E[?3;4l\E[4l\E>, sc=\E7, smkx=\E[?1h\E=,
              *        set-window-title=\E]0;title text\007,
+             * tests: \E#8  fill screen with 'E's
+             * tests: \Ec   reset
              */
             switch (c) {
             case '%':
@@ -978,7 +1023,7 @@
             case '+':
             case ']':
                 s->esc1 = c;
-                s->state = TTY_STATE_ESC2;
+                s->state = QE_TERM_STATE_ESC2;
                 break;
             case '7':   // sc   (save_cursor)
             case '8':   // rc   (restore_cursor)
@@ -994,13 +1039,13 @@
                 // XXX: do these
             default:
                 TRACE_MSG("unhandled");
-                s->state = TTY_STATE_NORM;
+                s->state = QE_TERM_STATE_NORM;
                 break;
             }
         }
         break;
-    case TTY_STATE_ESC2:
-        s->state = TTY_STATE_NORM;
+    case QE_TERM_STATE_ESC2:
+        s->state = QE_TERM_STATE_NORM;
         s->esc2 = c;
         switch (ESC2(s->esc1, c)) {
         case ESC2('%','G'):     /* set utf mode */
@@ -1034,7 +1079,7 @@
         case ESC2(']','2'):     /* xterm's set-window-title */
         case ESC2(']','4'):     /* xterm's define-extended color */
         case ESC2(']','W'):     /* word-set (define char wordness) */
-            s->state = TTY_STATE_STRING;
+            s->state = QE_TERM_STATE_STRING;
             break;
         case ESC2(']','P'):     /* linux set palette */
         case ESC2(']','R'):     /* linux reset palette */
@@ -1047,11 +1092,11 @@
         }
         s->shifted = s->charset[s->cset];
         break;
-    case TTY_STATE_STRING:
+    case QE_TERM_STATE_STRING:
         /* CG: should store the string */
         /* Stop string on CR or LF, for protection */
         if (c == '\012' || c == '\015') {
-            s->state = TTY_STATE_NORM;
+            s->state = QE_TERM_STATE_NORM;
             break;
         }
         /* Stop string on \a (^G) or M-\ -- need better test for ESC \ */
@@ -1059,10 +1104,10 @@
             /* 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" ) */
-            s->state = TTY_STATE_NORM;
+            s->state = QE_TERM_STATE_NORM;
         }
         break;
-    case TTY_STATE_CSI:
+    case QE_TERM_STATE_CSI:
         if (c == '?' || c == '=') {
             s->esc1 = c;
             break;
@@ -1081,7 +1126,7 @@
             s->nb_esc_params++;
             if (c == ';')
                 break;
-            s->state = TTY_STATE_NORM;
+            s->state = QE_TERM_STATE_NORM;
             switch (ESC2(s->esc1,c)) {
                /* unhandled:
                 * \^[[4l
@@ -1102,7 +1147,7 @@
                     s->esc_params[0] == 1048 ||
                     s->esc_params[0] == 1049) {
                     if (s->shell_flags & SF_INTERACTIVE) {
-                        /* only grab keys in interactive tty buffers */
+                        /* only grab keys in interactive qe_term buffers */
                         s->grab_keys = 1;
                         qe_grab_keys(shell_key, s);
                         /* Should also clear screen */
@@ -1128,33 +1173,33 @@
                }
                 break;
             case 'A':  /* CUU: move up N lines */
-                tty_goto_xy(s, 0, -s->esc_params[0], 3);
+                qe_term_goto_xy(s, 0, -s->esc_params[0], 3);
                 break;
             case 'e':  /* VPR: move down N lines */
             case 'B':  /* CUD: Cursor down */
-                tty_goto_xy(s, 0, s->esc_params[0], 3);
+                qe_term_goto_xy(s, 0, s->esc_params[0], 3);
                 break;
             case 'a':  /* HPR: move right N cols */
             case 'C':  /* CUF: Cursor right */
-                tty_goto_xy(s, s->esc_params[0], 0, 3);
+                qe_term_goto_xy(s, s->esc_params[0], 0, 3);
                 break;
             case 'D':  /* CUB: move left N cols */
-                tty_goto_xy(s, -s->esc_params[0], 0, 3);
+                qe_term_goto_xy(s, -s->esc_params[0], 0, 3);
                 break;
             case 'F':  /* CPL: move up N lines and CR */
-                tty_goto_xy(s, 0, -s->esc_params[0], 2);
+                qe_term_goto_xy(s, 0, -s->esc_params[0], 2);
                 break;
             case 'G':  /* CHA: goto column_address */
             case '`':  /* HPA: set horizontal posn */
-                tty_goto_xy(s, s->esc_params[0] - 1, 0, 2);
+                qe_term_goto_xy(s, s->esc_params[0] - 1, 0, 2);
                 break;
             case 'H':  /* CUP: goto xy */
             case 'f':  /* HVP: set horz and vert posns at once */
-                tty_goto_xy(s, s->esc_params[1] - 1, s->esc_params[0] - 1, 0);
+                qe_term_goto_xy(s, s->esc_params[1] - 1, s->esc_params[0] - 1, 
0);
                 break;
             case 'd':
                 /* goto y */
-                tty_goto_xy(s, 0, s->esc_params[0] - 1, 1);
+                qe_term_goto_xy(s, 0, s->esc_params[0] - 1, 1);
                 break;
             case 'J':  /* ED: erase screen or parts of it */
                        /*     0: to end, 1: from begin, 2: all */
@@ -1179,7 +1224,7 @@
             case '@':  /* ICH: insert chars (no cursor update) */
                 buf1[0] = ' ';
                 offset1 = offset;
-                s->b->cur_style = QE_STYLE_TTY | s->color | s->attr;
+                qe_term_set_setyle(s);
                 for (n = s->esc_params[0]; n > 0; n--) {
                     /* XXX: incorrect for non 8 bit charsets */
                     eb_insert(s->b, offset1, buf1, 1);
@@ -1198,9 +1243,16 @@
                 eb_delete(s->b, offset, offset1 - offset);
                 break;
             case 'c':  /* DA: terminal type query */
-                TRACE_MSG("term type query");
+                if (s->esc_params[0] == 0) {
+                    /* Report Advanced Video option (AVO) */
+                    qe_term_write(s, "\033[?1;2c", -1);
+                }
                 break;
             case 'n':  /* DSR: cursor position query */
+                if (s->esc_params[0] == 5) {
+                    /* Status report: terminal is OK */
+                    qe_term_write(s, "\033[0n", -1);
+                } else
                 if (s->esc_params[0] == 6) {
                     /* XXX: send cursor position, just to be able to
                        launch qemacs in qemacs (in 8859-1) ! */
@@ -1210,7 +1262,7 @@
                     /* XXX: actually send position of point in window */
                     snprintf(buf2, sizeof(buf2), "\033[%d;%dR",
                              1, col_num + 1);
-                    tty_write(s, buf2, -1);
+                    qe_term_write(s, buf2, -1);
                 }
                 break;
             case 'g':  /* TBC: clear tabs */
@@ -1223,7 +1275,7 @@
                 break;
             case 'm':  /* SGR: set graphics rendition (style and colors) */
                 for (i = 0;;) {
-                    tty_csi_m(s, s->esc_params[i], s->has_params[i]);
+                    qe_term_csi_m(s, s->esc_params[i], s->has_params[i]);
                     if (++i >= s->nb_esc_params)
                         break;
                 }
@@ -1248,7 +1300,7 @@
                 break;
             case 'X':  /* ECH: erase n characters w/o moving cursor */
                 for (n = s->esc_params[0]; n > 0; n--) {
-                    tty_put_char(s, ' ');
+                    qe_term_put_char(s, ' ');
                 }
                 /* restore cursor */
                 s->cur_offset = offset;
@@ -1263,10 +1315,10 @@
                TRACE_MSG("unhandled");
                 break;
             case ESC2('=','F'): /* select SCO foreground color */
-                TTY_SET_FG_COLOR(s->color, sco_color[s->esc_params[0] & 15]);
+                s->fgcolor = sco_color[s->esc_params[0] & 15];
                 break;
             case ESC2('=','G'): /* select SCO background color */
-                TTY_SET_BG_COLOR(s->color, sco_color[s->esc_params[0] & 15]);
+                s->bgcolor = sco_color[s->esc_params[0] & 15];
                 break;
             default:
                TRACE_MSG("unhandled");
@@ -1276,12 +1328,12 @@
         break;
     }
 #undef ESC2
-    tty_update_cursor(s);
+    qe_term_update_cursor(s);
 }
 
 /* buffer related functions */
 
-/* called when characters are available on the tty */
+/* called when characters are available from the process */
 static void shell_read_cb(void *opaque)
 {
     ShellState *s = opaque;
@@ -1313,7 +1365,7 @@
         } else
 #endif
         for (i = 0; i < len; i++)
-            tty_emulate(s, buf[i]);
+            qe_term_emulate(s, buf[i]);
 
         if (save_readonly) {
             s->b->modified = 0;
@@ -1460,7 +1512,7 @@
 
     eb_set_buffer_name(b, bufname); /* ensure that the name is unique */
     if (shell_flags & SF_COLOR)
-        eb_create_style_buffer(b, BF_STYLE2);
+        eb_create_style_buffer(b, QE_TERM_STYLE_BITS <= 16 ? BF_STYLE2 : 
BF_STYLE4);
 
     /* Select shell output buffer encoding from LANG setting */
     if (((lang = getenv("LANG")) != NULL && strstr(lang, "UTF-8")) ||
@@ -1489,13 +1541,13 @@
     s->caption = caption;
     s->shell_flags = shell_flags;
     s->cur_prompt = s->cur_offset = b->total_size;
-    tty_init(s);
+    qe_term_init(s);
 
     /* launch shell */
-    cols = TTY_XSIZE;
-    rows = TTY_YSIZE;
+    cols = QE_TERM_XSIZE;
+    rows = QE_TERM_YSIZE;
     if (shell_flags & SF_INFINITE)
-        rows = TTY_YSIZE_INFINITE;
+        rows = QE_TERM_YSIZE_INFINITE;
 
     if (run_process(cmd, &s->pty_fd, &s->pid, cols, rows, shell_flags) < 0) {
         if (!b0)
@@ -1634,7 +1686,7 @@
     ShellState *s = shell_get_state(e, 1);
 
     if (s && e->interactive) {
-        tty_write(s, dir > 0 ? s->kcuf1 : s->kcub1, -1);
+        qe_term_write(s, dir > 0 ? s->kcuf1 : s->kcub1, -1);
     } else {
         text_move_left_right_visual(e, dir);
     }
@@ -1645,7 +1697,7 @@
     ShellState *s = shell_get_state(e, 1);
 
     if (s && e->interactive) {
-        tty_write(s, dir > 0 ? "\033f" : "\033b", -1);
+        qe_term_write(s, dir > 0 ? "\033f" : "\033b", -1);
     } else {
         text_move_word_left_right(e, dir);
     }
@@ -1656,7 +1708,7 @@
     ShellState *s = shell_get_state(e, 1);
 
     if (s && e->interactive) {
-        tty_write(s, dir > 0 ? s->kcud1 : s->kcuu1, -1);
+        qe_term_write(s, dir > 0 ? s->kcud1 : s->kcuu1, -1);
     } else {
         text_move_up_down(e, dir);
         // XXX: what if beyond?
@@ -1671,7 +1723,7 @@
 
     if (s && e->interactive) {
         /* hack: M-p silently converted to C-p */
-        tty_write(s, dir > 0 ? s->kcud1 : s->kcuu1, -1);
+        qe_term_write(s, dir > 0 ? s->kcud1 : s->kcuu1, -1);
     } else {
         /* hack: M-p silently converted to C-u C-p */
         text_move_up_down(e, dir * 4);
@@ -1686,7 +1738,7 @@
     ShellState *s = shell_get_state(e, 1);
 
     if (s && e->interactive) {
-        tty_write(s, "\030\030", 2);  /* C-x C-x */
+        qe_term_write(s, "\030\030", 2);  /* C-x C-x */
     } else {
         do_exchange_point_and_mark(e);
         // XXX: what if beyond?
@@ -1715,7 +1767,7 @@
         e->interactive = 0;
 
     if (s && e->interactive) {
-        tty_write(s, "\001", 1); /* Control-A */
+        qe_term_write(s, "\001", 1); /* Control-A */
     } else {
         text_move_bol(e);
     }
@@ -1726,7 +1778,7 @@
     ShellState *s = shell_get_state(e, 1);
 
     if (s && e->interactive) {
-        tty_write(s, "\005", 1); /* Control-E */
+        qe_term_write(s, "\005", 1); /* Control-E */
     } else {
         text_move_eol(e);
         /* XXX: restore shell interactive mode on end / ^E */
@@ -1734,7 +1786,7 @@
         &&  e->offset >= s->cur_offset) {
             e->interactive = 1;
             if (e->offset > s->cur_offset)
-                tty_write(s, "\005", 1); /* Control-E */
+                qe_term_write(s, "\005", 1); /* Control-E */
         }
     }
 }
@@ -1751,7 +1803,7 @@
     ShellState *s = shell_get_state(e, 1);
 
     if (s && e->interactive) {
-        tty_write(s, "\005", 1); /* Control-E */
+        qe_term_write(s, "\005", 1); /* Control-E */
     } else {
         text_move_eof(e);
         /* Restore shell interactive mode on end-buffer / M-> */
@@ -1759,7 +1811,7 @@
         &&  e->offset >= s->cur_offset) {
             e->interactive = 1;
             if (e->offset != s->cur_offset)
-                tty_write(s, "\005", 1); /* Control-E */
+                qe_term_write(s, "\005", 1); /* Control-E */
         }
     }
 }
@@ -1779,7 +1831,7 @@
         } else {
             len = eb_encode_uchar(e->b, buf, c);
         }
-        tty_write(s, buf, len);
+        qe_term_write(s, buf, len);
     } else {
         text_write_char(e, c);
     }
@@ -1805,23 +1857,23 @@
         cur_char = eb_get_char_offset(e->b, s->cur_offset);
         end_char = eb_get_char_offset(e->b, end);
         while (cur_char > end_char) {
-            tty_write(s, "\002", 1);  /* C-b */
+            qe_term_write(s, "\002", 1);  /* C-b */
             cur_char--;
         }
         while (cur_char < start_char) {
-            tty_write(s, "\006", 1);  /* C-f */
+            qe_term_write(s, "\006", 1);  /* C-f */
             cur_char++;
         }
         if (start_char == cur_char && end == e->b->total_size) {
             /* kill to end of line with control-k */
-            tty_write(s, "\013", 1);
+            qe_term_write(s, "\013", 1);
         } else {
             while (cur_char < end_char) {
-                tty_write(s, "\004", 1);  /* C-d */
+                qe_term_write(s, "\004", 1);  /* C-d */
                 end_char--;
             }
             while (start_char < cur_char) {
-                tty_write(s, "\010", 1);  /* backspace */
+                qe_term_write(s, "\010", 1);  /* backspace */
                 cur_char--;
                 end_char--;
             }
@@ -2047,7 +2099,7 @@
     }
 #if 0
     if (e->interactive) {
-        tty_update_cursor(s);
+        qe_term_update_cursor(s);
     }
 #endif
 }



reply via email to

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