From e5ccdebc696a67c834a31a336346f7cb3b4a66f2 Mon Sep 17 00:00:00 2001 From: Ali Gholami Rudi Date: Sat, 12 Nov 2011 21:13:33 +0330 Subject: [PATCH] term: 256-color support Most of the credit goes to Sara Fauzia . --- README | 32 ++++++++++++++++++++++++++++++++ config.h | 32 ++++++++++++++++---------------- fbpad.h | 9 +++++---- pad.c | 41 ++++++++++++++++++++++++++++++++--------- term.c | 44 +++++++++++++++++++++++++++++++------------- 5 files changed, 116 insertions(+), 42 deletions(-) diff --git a/README b/README index 9e3e9ef..63d8633 100644 --- 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=[?25h + set t_vi= + set t_ZH= + set t_Co=256 diff --git a/config.h b/config.h index 62bed1c..257ff94 100644 --- 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 --- 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 --- 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 --- 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]); -- 2.11.4.GIT