bold attribute is back. - st - Personal fork of st
 (HTM) git clone git://git.drkhsh.at/st.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 0f4dd5035ed920c67133f1a4b8aef5cbd957c7be
 (DIR) parent 7cdaf130b17e4991da9bb3d8d1341e0092474a73
 (HTM) Author: Aurélien Aptel <aurelien.aptel@gmail.com>
       Date:   Thu, 11 Mar 2010 23:50:50 +0100
       
       bold attribute is back.
       
       visibility of the cursor is not saved/loaded anymore.
       scrolling up/down is fixed.
       added RI and RIS sequences.
       fixed cursor drawing bug.
       Diffstat:
         M config.h                            |       3 ++-
         M st.c                                |     173 ++++++++++++++++++++++---------
       
       2 files changed, 126 insertions(+), 50 deletions(-)
       ---
 (DIR) diff --git a/config.h b/config.h
       @@ -1,7 +1,8 @@
        #define SHELL "/bin/bash"
        #define TAB    8
        
       -#define FONT "fixed"
       +#define FONT "6x13"
       +#define BOLDFONT FONT"bold"
        #define BORDER 3
        #define LINESPACE 0 /* additional pixel between each line */
        
 (DIR) diff --git a/st.c b/st.c
       @@ -57,7 +57,6 @@ typedef Glyph* Line;
        
        typedef struct {
                Glyph attr;  /* current char attributes */
       -        char hidden;
                int x;
                int y;
        } TCursor;
       @@ -79,6 +78,7 @@ typedef struct {
                int col;    /* nb col */
                Line* line; /* screen */
                TCursor c;  /* cursor */
       +        char hidec;
                int top;    /* top    scroll limit */
                int bot;    /* bottom scroll limit */
                int mode;   /* terminal mode flags */
       @@ -109,6 +109,7 @@ typedef struct {
        typedef struct {
                unsigned long col[LEN(colorname)];
                XFontStruct* font;
       +        XFontStruct* bfont;
                GC gc;
        } DC;
        
       @@ -135,8 +136,11 @@ static void tnew(int, int);
        static void tnewline(void);
        static void tputc(char);
        static void tputs(char*, int);
       +static void treset(void);
        static void tresize(int, int);
        static void tscroll(void);
       +static void tscrollup(int);
       +static void tscrolldown(int);
        static void tsetattr(int*, int);
        static void tsetchar(char);
        static void tsetscroll(int, int);
       @@ -149,12 +153,11 @@ static void ttywrite(const char *, size_t);
        static unsigned long xgetcol(const char *);
        static void xclear(int, int, int, int);
        static void xcursor(int);
       -static void xdrawc(int, int, Glyph);
        static void xinit(void);
        static void xscroll(void);
        
        static void expose(XEvent *);
       -static char * kmap(KeySym);
       +static char* kmap(KeySym);
        static void kpress(XEvent *);
        static void resize(XEvent *);
        
       @@ -313,6 +316,18 @@ tcursor(int mode) {
        }
        
        void
       +treset(void) {
       +        term.c.attr.mode = ATTR_NULL;
       +        term.c.attr.fg = DefaultFG;
       +        term.c.attr.bg = DefaultBG;
       +        term.c.x = term.c.y = 0;
       +        term.hidec = 0;
       +        term.top = 0, term.bot = term.row - 1;
       +        term.mode = MODE_WRAP;
       +        tclearregion(0, 0, term.col-1, term.row-1);
       +}
       +
       +void
        tnew(int col, int row) {   /* screen size */
                term.row = row, term.col = col;
                term.top = 0, term.bot = term.row - 1;
       @@ -323,17 +338,19 @@ tnew(int col, int row) {   /* screen size */
                term.c.attr.fg = DefaultFG;
                term.c.attr.bg = DefaultBG;
                term.c.x = term.c.y = 0;
       -        term.c.hidden = 0;
       +        term.hidec = 0;
                /* allocate screen */
                term.line = calloc(term.row, sizeof(Line));
                for(row = 0 ; row < term.row; row++)
                        term.line[row] = calloc(term.col, sizeof(Glyph));
        }
        
       +/* TODO: Replace with scrollup/scolldown */
        void
        tscroll(void) {
                Line temp = term.line[term.top];
                int i;
       +        /* No dirty flag to set because of xscroll */
                /* X stuff _before_ the line swapping (results in wrong line index) */
                xscroll();
                for(i = term.top; i < term.bot; i++)
       @@ -343,6 +360,41 @@ tscroll(void) {
        }
        
        void
       +tscrolldown (int n) {
       +        int i;
       +        Line temp;
       +        
       +        /* TODO: set dirty flag or scroll with some X func */
       +        LIMIT(n, 0, term.bot-term.top+1);
       +
       +        for(i = 0; i < n; i++)
       +                memset(term.line[term.bot-i], 0, term.col*sizeof(Glyph));
       +           
       +        for(i = term.bot; i >= term.top+n; i--) {
       +                temp = term.line[i];
       +                term.line[i] = term.line[i-n];
       +                term.line[i-n] = temp;
       +        }
       +}
       +
       +void
       +tscrollup (int n) {
       +        int i;
       +        Line temp;
       +        LIMIT(n, 0, term.bot-term.top+1);
       +        
       +        /* TODO: set dirty flag or scroll with some X func */
       +        for(i = 0; i < n; i++)
       +                memset(term.line[term.top+i], 0, term.col*sizeof(Glyph));
       +        
       +         for(i = term.top; i <= term.bot-n; i++) { 
       +                 temp = term.line[i];
       +                 term.line[i] = term.line[i+n]; 
       +                 term.line[i+n] = temp;
       +         }
       +}
       +
       +void
        tnewline(void) {
                int y = term.c.y + 1;
                if(y > term.bot)
       @@ -420,17 +472,20 @@ tsetchar(char c) {
        
        void
        tclearregion(int x1, int y1, int x2, int y2) {
       -        int x, y;
       +        int y, temp;
       +
       +        if(x1 > x2)
       +                temp = x1, x1 = x2, x2 = temp;
       +        if(y1 > y2)
       +                temp = y1, y1 = y2, y2 = temp;
        
                LIMIT(x1, 0, term.col-1);
                LIMIT(x2, 0, term.col-1);
                LIMIT(y1, 0, term.row-1);
                LIMIT(y2, 0, term.row-1);
        
       -        /* XXX: could be optimized */
       -        for(x = x1; x <= x2; x++)
       -                for(y = y1; y <= y2; y++)
       -                        memset(&term.line[y][x], 0, sizeof(Glyph));
       +        for(y = y1; y <= y2; y++)
       +                memset(&term.line[y][x1], 0, sizeof(Glyph)*(x2-x1+1));
        
                xclear(x1, y1, x2, y2);
        }
       @@ -542,9 +597,6 @@ tsetattr(int *attr, int l) {
                        case 7: 
                                term.c.attr.mode |= ATTR_REVERSE;        
                                break;
       -                case 8:
       -                        term.c.hidden = CURSOR_HIDE;
       -                        break;
                        case 22: 
                                term.c.attr.mode &= ~ATTR_BOLD;  
                                break;
       @@ -565,6 +617,8 @@ tsetattr(int *attr, int l) {
                                        term.c.attr.fg = attr[i] - 30;
                                else if(BETWEEN(attr[i], 40, 47))
                                        term.c.attr.bg = attr[i] - 40;
       +                        else 
       +                                fprintf(stderr, "erresc: gfx attr %d unkown\n", attr[i]); 
                                break;
                        }
                }
       @@ -590,7 +644,7 @@ csihandle(void) {
                switch(escseq.mode) {
                default:
                unknown:
       -                printf("erresc: unknown sequence -- ");
       +                printf("erresc: unknown csi ");
                        csidump();
                        /* die(""); */
                        break;
       @@ -665,7 +719,14 @@ csihandle(void) {
                                break;
                        }
                        break;
       -        case 'S': /* XXX: SU -- Scroll <n> line up (faked) */ 
       +        case 'S': /* SU -- Scroll <n> line up */
       +                DEFAULT(escseq.arg[0], 1);
       +                tscrollup(escseq.arg[0]);
       +                break;
       +        case 'T': /* SD -- Scroll <n> line down */
       +                DEFAULT(escseq.arg[0], 1);
       +                tscrolldown(escseq.arg[0]);
       +                break;
                case 'L': /* IL -- Insert <n> blank lines */
                        DEFAULT(escseq.arg[0], 1);
                        tinsertblankline(escseq.arg[0]);
       @@ -682,7 +743,7 @@ csihandle(void) {
                                case 12: /* att610 -- Stop blinking cursor (IGNORED) */
                                        break;
                                case 25:
       -                                term.c.hidden = 1;
       +                                term.hidec = 1;
                                        break;
                                case 1048: /* XXX: no alt. screen to erase/save */
                                case 1049:
       @@ -731,7 +792,7 @@ csihandle(void) {
                                case 12: /* att610 -- Start blinking cursor (IGNORED) */
                                        break;
                                case 25:
       -                                term.c.hidden = 0;
       +                                term.hidec = 0;
                                        break;
                                case 1048: 
                                case 1049: /* XXX: no alt. screen to erase/save */
       @@ -866,11 +927,15 @@ tputc(char c) {
                                        break;
                                case 'M': /* RI -- Reverse index */
                                        if(term.c.y == term.top)
       -                                        tinsertblankline(1);
       +                                        tscrolldown(1);
                                        else
                                                tmoveto(term.c.x, term.c.y-1);
                                        term.esc = 0;
                                        break;
       +                        case 'c': /* RIS -- Reset to inital state */
       +                                treset();
       +                                term.esc = 0;
       +                                break;
                                case '=': /* DECPAM */
                                        term.mode |= MODE_APPKEYPAD;
                                        term.esc = 0;
       @@ -888,7 +953,7 @@ tputc(char c) {
                                        term.esc = 0;
                                        break;
                                default:
       -                                fprintf(stderr, "erresc: unknown sequence ESC %02X '%c'\n", c, isprint(c)?c:'.');
       +                                fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n", c, isprint(c)?c:'.');
                                        term.esc = 0;
                                }
                        }
       @@ -991,8 +1056,6 @@ xscroll(void) {
        
        void
        xinit(void) {
       -        XGCValues values;
       -        unsigned long valuemask;
                XClassHint chint;
                XWMHints wmhint;
                XSizeHints shint;
       @@ -1005,9 +1068,10 @@ xinit(void) {
                        die("Can't open display\n");
                
                /* font */
       -        if(!(dc.font = XLoadQueryFont(xw.dis, FONT)))
       -                die("Can't load font %s\n", FONT);
       +        if(!(dc.font = XLoadQueryFont(xw.dis, FONT)) || !(dc.bfont = XLoadQueryFont(xw.dis, BOLDFONT)))
       +                die("Can't load font %s\n", dc.font ? BOLDFONT : FONT);
        
       +        /* XXX: Assuming same size for bold font */
                xw.cw = dc.font->max_bounds.rbearing - dc.font->min_bounds.lbearing;
                xw.ch = dc.font->ascent + dc.font->descent + LINESPACE;
        
       @@ -1027,10 +1091,7 @@ xinit(void) {
                                dc.col[DefaultBG],
                                dc.col[DefaultBG]);
                /* gc */
       -        values.foreground = XWhitePixel(xw.dis, xw.scr);
       -        values.font = dc.font->fid;
       -        valuemask = GCForeground | GCFont;
       -        dc.gc = XCreateGC(xw.dis, xw.win, valuemask, &values);
       +        dc.gc = XCreateGC(xw.dis, xw.win, 0, NULL);
                XMapWindow(xw.dis, xw.win);
                /* wm stuff */
                chint.res_name = TNAME, chint.res_class = TNAME;
       @@ -1060,7 +1121,8 @@ xdraws(char *s, Glyph base, int x, int y, int len) {
                if(base.mode & ATTR_GFX)
                        for(i = 0; i < len; i++)
                                s[i] = gfx[s[i]];
       -        
       +
       +        XSetFont(xw.dis, dc.gc, base.mode & ATTR_BOLD ? dc.bfont->fid : dc.font->fid);        
                XDrawImageString(xw.dis, xw.win, dc.gc, winx, winy, s, len);
                
                if(base.mode & ATTR_UNDERLINE)
       @@ -1068,22 +1130,6 @@ xdraws(char *s, Glyph base, int x, int y, int len) {
        }
        
        void
       -xdrawc(int x, int y, Glyph g) {
       -        XRectangle r = { x * xw.cw, y * xw.ch, xw.cw, xw.ch };
       -        unsigned long xfg, xbg;
       -
       -        /* reverse video */
       -        if(g.mode & ATTR_REVERSE)
       -                xfg = dc.col[g.bg], xbg = dc.col[g.fg];
       -        else
       -                xfg = dc.col[g.fg], xbg = dc.col[g.bg];
       -        /* background */
       -        XSetBackground(xw.dis, dc.gc, xbg);
       -        XSetForeground(xw.dis, dc.gc, xfg);
       -        XDrawImageString(xw.dis, xw.win, dc.gc, r.x, r.y+dc.font->ascent, &g.c, 1);
       -}
       -
       -void
        xcursor(int mode) {
                static int oldx = 0;
                static int oldy = 0;
       @@ -1094,24 +1140,54 @@ xcursor(int mode) {
                
                if(term.line[term.c.y][term.c.x].state & GLYPH_SET)
                        g.c = term.line[term.c.y][term.c.x].c;
       +
                /* remove the old cursor */
                if(term.line[oldy][oldx].state & GLYPH_SET)
       -                xdrawc(oldx, oldy, term.line[oldy][oldx]);
       -        else 
       +                xdraws(&term.line[oldy][oldx].c, term.line[oldy][oldx], oldx, oldy, 1);
       +        else
                        xclear(oldx, oldy, oldx, oldy);
       +        
                /* draw the new one */
                if(mode == CURSOR_DRAW) {
       -                xdrawc(term.c.x, term.c.y, g);
       +                xdraws(&g.c, g, term.c.x, term.c.y, 1);
                        oldx = term.c.x, oldy = term.c.y;
                }
        }
        
       +
       +#ifdef DEBUG
       +/* basic drawing routines */
       +void
       +xdrawc(int x, int y, Glyph g) {
       +        XRectangle r = { x * xw.cw, y * xw.ch, xw.cw, xw.ch };
       +        XSetBackground(xw.dis, dc.gc, dc.col[g.bg]);
       +        XSetForeground(xw.dis, dc.gc, dc.col[g.fg]);
       +        XSetFont(xw.dis, dc.gc, g.mode & ATTR_BOLD ? dc.bfont->fid : dc.font->fid);
       +        XDrawImageString(xw.dis, xw.win, dc.gc, r.x, r.y+dc.font->ascent, &g.c, 1);
       +}
       +
       +void
       +draw_(int dummy) {
       +        int x, y;
       +
       +        xclear(0, 0, term.col-1, term.row-1);
       +        for(y = 0; y < term.row; y++)
       +                for(x = 0; x < term.col; x++)
       +                        if(term.line[y][x].state & GLYPH_SET)
       +                                xdrawc(x, y, term.line[y][x]);
       +
       +        if(!term.hidec)
       +                xcursor(CURSOR_DRAW);
       +}
       +#endif
       +
        void
        draw(int redraw_all) {
                int i, x, y, ox;
                Glyph base, new;
                char buf[DRAW_BUF_SIZ];
                
       +        /* XXX: optimize with GLYPH_DIRTY hint */
                for(y = 0; y < term.row; y++) {
                        base = term.line[y][0];
                        i = ox = 0;
       @@ -1129,8 +1205,7 @@ draw(int redraw_all) {
                        }
                        xdraws(buf, base, ox, y, i);
                }
       -        if(!term.c.hidden)
       -                xcursor(CURSOR_DRAW);
       +        xcursor(term.hidec ? CURSOR_HIDE : CURSOR_DRAW);
        }
        
        void
       @@ -1179,7 +1254,7 @@ kpress(XEvent *ev) {
                                break;
                        case XK_Insert:
                                if(shift)
       -                                /* XXX: paste X clipboard */;
       +                                draw(1), puts("draw!")/* XXX: paste X clipboard */;
                                break;
                        default:
                                fprintf(stderr, "errkey: %d\n", (int)ksym);