term: 256-color support
authorAli Gholami Rudi <ali@rudi.ir>
Sat, 12 Nov 2011 17:43:33 +0000 (12 21:13 +0330)
committerAli Gholami Rudi <ali@rudi.ir>
Mon, 16 Sep 2013 14:23:00 +0000 (16 18:53 +0430)
Most of the credit goes to Sara Fauzia <sfauzia@fas.harvard.edu>.

README
config.h
fbpad.h
pad.c
term.c

diff --git a/README b/README
index 9e3e9ef..63d8633 100644 (file)
--- a/README
+++ b/README
@@ -58,3 +58,35 @@ If you are want to use fbpad's scrsnap feature, you can edit TAGS_SAVED
 to change the list of saved terminals.  Framebuffer memory is saved and
 reloaded for these tags, which is very convenient when you are using
 programs that change the framebuffer simultaneously, like fbpdf.
+
+256-COLOR MODE
+==============
+
+Fbpad supports xterm's 256-color extension, but most programs will not
+use this extension, unless the $TERM terminfo entry declares this
+feature.  For this purpose, you need to create fbpad-256 terminfo file
+containing (ignore the two-space identation):
+
+  fbpad-256,
+       use=linux, U8#0,
+       colors#256,
+       pairs#32767,
+       setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
+       setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
+
+And install it with:
+
+  $ tic -x ./fbpad-256
+
+Now you can add this line to your shell startup script:
+
+  export TERM=fbpad-256
+
+Note that in order to use this feature and italic fonts in Vim, adding
+fbpad-256 terminfo is not necessary.  Including the following lines in
+your vimrc should enable them:
+
+  set t_ve=\e[?25h
+  set t_vi=
+  set t_ZH=\e[3m
+  set t_Co=256
index 62bed1c..257ff94 100644 (file)
--- a/config.h
+++ b/config.h
@@ -17,7 +17,7 @@ typedef unsigned int fbval_t;
 
 /* foreground and background colors */
 #define FGCOLOR                0
-#define BGCOLOR                7
+#define BGCOLOR                15
 
 /* where to write the screen shot */
 #define SCRSHOT                "/tmp/scr"
@@ -30,25 +30,25 @@ typedef unsigned int fbval_t;
 
 /* black */
 #define COLOR0         0x000000
-#define COLOR8         0x407080
+#define COLOR8         0x555555
 /* red */
-#define COLOR1         0xa02020
-#define COLOR9         0xb05050
+#define COLOR1         0xaa0000
+#define COLOR9         0xff5555
 /* green */
-#define COLOR2         0x156015
-#define COLOR10                0x307030
+#define COLOR2         0x00aa00
+#define COLOR10                0x55ff55
 /* yellow */
-#define COLOR3         0x707030
-#define COLOR11                0x909060
+#define COLOR3         0xaa5500
+#define COLOR11                0xffff55
 /* blue */
-#define COLOR4         0x202070
-#define COLOR12                0x303080
+#define COLOR4         0x0000aa
+#define COLOR12                0x5555ff
 /* magenta */
-#define COLOR5         0x903070
-#define COLOR13                0xa05080
+#define COLOR5         0xaa00aa
+#define COLOR13                0xff55ff
 /* cyan */
-#define COLOR6         0x602080
-#define COLOR14                0x704090
+#define COLOR6         0xaa00aa
+#define COLOR14                0x55ffff
 /* white */
-#define COLOR7         0xf0f0f0
-#define COLOR15                0xdedede
+#define COLOR7         0xaaaaaa
+#define COLOR15                0xffffff
diff --git a/fbpad.h b/fbpad.h
index a92219c..b479d1b 100644 (file)
--- a/fbpad.h
+++ b/fbpad.h
@@ -26,8 +26,8 @@ struct term_state {
 struct term {
        int screen[NROWS * NCOLS];
        int hist[NHIST * NCOLS];
-       char fgs[NROWS * NCOLS];
-       char bgs[NROWS * NCOLS];
+       short fgs[NROWS * NCOLS];
+       short bgs[NROWS * NCOLS];
        struct term_state cur, sav;
        int histtail;                   /* the next history row */
        int fd;
@@ -47,11 +47,12 @@ void term_hist(int pos);
 void term_redraw(void);
 
 /* pad.c */
-#define FN_I           0x10
-#define FN_B           0x20
+#define FN_I           0x100
+#define FN_B           0x200
 
 int pad_init(void);
 void pad_free(void);
+int pad_font(char *fr, char *fi, char *fb);
 void pad_put(int ch, int r, int c, int fg, int bg);
 int pad_rows(void);
 int pad_cols(void);
diff --git a/pad.c b/pad.c
index 89d952d..c1f139c 100644 (file)
--- a/pad.c
+++ b/pad.c
@@ -6,11 +6,11 @@
 #include "draw.h"
 #include "fbpad.h"
 
-#define FN_C(fg)       (((fg) & FN_B ? (fg) + 8 : (fg)) & 0x0f)
+#define FN_C(fg)       ((fg) & ~(FN_I | FN_B))
 #define NCACHE         (1 << 11)
 #define MAXFBWIDTH     (1 << 12)
 
-static unsigned int cd[] = {
+static unsigned int cd[256] = {
        COLOR0, COLOR1, COLOR2, COLOR3,
        COLOR4, COLOR5, COLOR6, COLOR7,
        COLOR8, COLOR9, COLOR10, COLOR11,
@@ -21,24 +21,32 @@ static struct font *fonts[3];
 
 int pad_init(void)
 {
-       int i;
-       char *paths[] = {FR, FI, FB};
+       int r, g, b;
        if (fb_init())
                return 1;
        if (sizeof(fbval_t) != FBM_BPP(fb_mode())) {
                fprintf(stderr, "pad_init: fbval_t doesn't match fb depth\n");
                return 1;
        }
-       for (i = 0; i < 3; i++)
-               fonts[i] = paths[i] ? font_open(paths[i]) : NULL;
-       if (!fonts[0]) {
-               fprintf(stderr, "pad: bad font <%s>\n", paths[0]);
+       if (pad_font(FR, FI, FB) < 0)
                return -1;
-       }
        fnrows = font_rows(fonts[0]);
        fncols = font_cols(fonts[0]);
        rows = fb_rows() / fnrows;
        cols = fb_cols() / fncols;
+       for (r = 0; r < 6; r++) {
+               for (g = 0; g < 6; g++) {
+                       for (b = 0; b < 6; b++) {
+                               int idx = 16 + r * 36 + g * 6 + b;
+                               cd[idx] = ((r * 40 + 55) << 16) |
+                                               ((g * 40 + 55) << 8) |
+                                               (b * 40 + 55);
+                       }
+               }
+       }
+       for (r = 0; r < 24; r++)
+               cd[232 + r] = ((r * 10 + 8) << 16) |
+                               ((r * 10 + 8) << 8) | (r * 10 + 8);
        return 0;
 }
 
@@ -182,3 +190,18 @@ int pad_cols(void)
 {
        return cols;
 }
+
+int pad_font(char *fr, char *fi, char *fb)
+{
+       char *fns[] = {fr, fi, fb};
+       int i;
+       for (i = 0; i < 3; i++) {
+               if (fonts[i])
+                       font_free(fonts[i]);
+               fonts[i] = fns[i] ? font_open(fns[i]) : NULL;
+       }
+       memset(glyphs, 0, sizeof(glyphs));
+       if (!fonts[0])
+               fprintf(stderr, "pad: bad font <%s>\n", fr);
+       return fonts[0] ? 0 : -1;
+}
diff --git a/term.c b/term.c
index da41fae..4124c99 100644 (file)
--- a/term.c
+++ b/term.c
@@ -30,9 +30,9 @@
 
 static struct term *term;
 static int *screen;
-static char *fgs, *bgs;
+static short *fgs, *bgs;
 static int row, col;
-static char fg, bg;
+static int fg, bg;
 static int top, bot;
 static int mode;
 static int visible;
@@ -42,7 +42,7 @@ static int visible;
 static int dirty[NROWS];
 static int lazy;
 
-static char fgcolor(void)
+static int fgcolor(void)
 {
        int c = mode & ATTR_REV ? bg : fg;
        if (mode & ATTR_BOLD)
@@ -52,7 +52,7 @@ static char fgcolor(void)
        return c;
 }
 
-static char bgcolor(void)
+static int bgcolor(void)
 {
        return mode & ATTR_REV ? fg : bg;
 }
@@ -62,8 +62,8 @@ static void _draw_pos(int r, int c, int cursor)
 {
        int rev = cursor && mode & MODE_CURSOR;
        int i = OFFSET(r, c);
-       char fg = rev ? bgs[i] : fgs[i];
-       char bg = rev ? fgs[i] : bgs[i];
+       int fg = rev ? bgs[i] : fgs[i];
+       int bg = rev ? fgs[i] : bgs[i];
        pad_put(screen[i], r, c, fg, bg);
 }
 
@@ -143,16 +143,19 @@ static void lazy_flush(void)
 
 static void screen_reset(int i, int n)
 {
+       int c;
        memset(screen + i, 0, n * sizeof(*screen));
-       memset(fgs + i, fg, n);
-       memset(bgs + i, bg, n);
+       for (c = 0; c < n; c++)
+               fgs[i + c] = fg;
+       for (c = 0; c < n; c++)
+               bgs[i + c] = bg;
 }
 
 static void screen_move(int dst, int src, int n)
 {
        memmove(screen + dst, screen + src, n * sizeof(*screen));
-       memmove(fgs + dst, fgs + src, n);
-       memmove(bgs + dst, bgs + src, n);
+       memmove(fgs + dst, fgs + src, n * sizeof(*fgs));
+       memmove(bgs + dst, bgs + src, n * sizeof(*bgs));
 }
 
 /* terminal input buffering */
@@ -451,8 +454,8 @@ void term_hist(int scrl)
        for (i = 0; i < pad_rows(); i++) {
                int off = (i - scrl) * pad_cols();
                int *_scr = i < scrl ? HISTROW(scrl - i) : term->screen + off;
-               char *_fgs = i < scrl ? NULL : term->fgs + off;
-               char *_bgs = i < scrl ? NULL : term->bgs + off;
+               short *_fgs = i < scrl ? NULL : term->fgs + off;
+               short *_bgs = i < scrl ? NULL : term->bgs + off;
                for (j = 0; j < pad_cols(); j++)
                        pad_put(_scr[j], i, j, _fgs ? _fgs[j] : BGCOLOR,
                                                _bgs ? _bgs[j] : FGCOLOR);
@@ -546,6 +549,10 @@ static void setattr(int m)
                        fg = m > 37 ? FGCOLOR : m - 30;
                if ((m / 10) == 4)
                        bg = m > 47 ? BGCOLOR : m - 40;
+               if ((m / 10) == 9)
+                       fg = 8 + m - 90;
+               if ((m / 10) == 10)
+                       bg = 8 + m - 100;
        }
 }
 
@@ -933,8 +940,19 @@ static void csiseq(void)
        case 'm':       /* SGR          set graphic rendition */
                if (!n)
                        setattr(0);
-               for (i = 0; i < n; i++)
+               for (i = 0; i < n; i++) {
+                       if (args[i] == 38) {
+                               fg = args[i + 2];
+                               i += 2;
+                               continue;
+                       }
+                       if (args[i] == 48) {
+                               bg = args[i + 2];
+                               i += 2;
+                               continue;
+                       }
                        setattr(args[i]);
+               }
                break;
        case 'r':       /* DECSTBM      set scrolling region to (top, bottom) rows */
                set_region(args[0], args[1]);