X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=st.c;h=8b0e5104eff84880e2356874e191dc282185e91f;hb=5d611cd5476b56884077120bc2a6ba9727fcdd2c;hp=deddb0d2c2e76faa9c4538a1f98b941fa0b1dd3d;hpb=d2f157c7418e2762316e5471f819ec1e5c49e93c;p=st.git diff --git a/st.c b/st.c index deddb0d..8b0e510 100644 --- a/st.c +++ b/st.c @@ -20,8 +20,6 @@ #include #include -#define TNAME "st-256color" - /* Arbitrary sizes */ #define ESC_TITLE_SIZ 256 #define ESC_BUF_SIZ 256 @@ -36,6 +34,7 @@ #define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) #define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) #define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg) +#define IS_SET(flag) (term.mode & flag) /* Attribute, Cursor, Character state, Terminal mode, Screen draw mode */ enum { ATTR_NULL=0 , ATTR_REVERSE=1 , ATTR_UNDERLINE=2, ATTR_BOLD=4, ATTR_GFX=8 }; @@ -107,8 +106,6 @@ typedef struct { char s[ESC_BUF_SIZ]; } Key; -#include "config.h" - /* Drawing Context */ typedef struct { unsigned long col[256]; @@ -117,6 +114,8 @@ typedef struct { GC gc; } DC; +#include "config.h" + static void die(const char *errstr, ...); static void draw(int); static void execsh(void); @@ -130,7 +129,7 @@ static void csireset(void); static void tclearregion(int, int, int, int); static void tcursor(int); -static void tmovecursor(int); +static void twrapcursor(void); static void tdeletechar(int); static void tdeleteline(int); static void tinsertblank(int); @@ -138,6 +137,7 @@ static void tinsertblankline(int); static void tmoveto(int, int); static void tnew(int, int); static void tnewline(void); +static void tputtab(void); static void tputc(char); static void tputs(char*, int); static void treset(void); @@ -154,6 +154,9 @@ static void ttyread(void); static void ttyresize(int, int); static void ttywrite(const char *, size_t); +static void xbell(void); +static void xdraws(char *, Glyph, int, int, int); +static void xhints(void); static void xclear(int, int, int, int); static void xcursor(int); static void xinit(void); @@ -245,7 +248,7 @@ ttynew(void) { if((m = posix_openpt(O_RDWR | O_NOCTTY)) < 0) die("openpt failed: %s\n", SERRNO); if(grantpt(m) < 0) - die("grandpt failed: %s\n", SERRNO); + die("grantpt failed: %s\n", SERRNO); if(unlockpt(m) < 0) die("unlockpt failed: %s\n", SERRNO); if(!(pts = ptsname(m))) @@ -263,7 +266,9 @@ ttynew(void) { dup2(s, STDOUT_FILENO); dup2(s, STDERR_FILENO); if(ioctl(s, TIOCSCTTY, NULL) < 0) - die("ioctl TTIOCSTTY failed: %s\n", SERRNO); + die("ioctl TIOCSCTTY failed: %s\n", SERRNO); + close(s); + close(m); execsh(); break; default: @@ -433,34 +438,13 @@ tmoveto(int x, int y) { } void -tmovecursor(int dir) { - int xf = term.c.x, yf = term.c.y; - - switch(dir) { - case CURSOR_UP: - yf--; - break; - case CURSOR_DOWN: - yf++; - break; - case CURSOR_LEFT: - xf--; - if(term.mode & MODE_WRAP && xf < 0) { - xf = term.col-1, yf--; - if(yf < term.top) - yf = term.top, xf = 0; - } - break; - case CURSOR_RIGHT: - xf++; - if(term.mode & MODE_WRAP && xf >= term.col) { - xf = 0, yf++; - if(yf > term.bot) - yf = term.bot, tscroll(); - } - break; - } - tmoveto(xf, yf); +twrapcursor(void) { + int y = term.c.y+1; + if(y > term.bot) { + tmoveto(0, term.bot); + tscroll(); + } else + tmoveto(0, y); } void @@ -499,21 +483,21 @@ tdeletechar(int n) { return; } memmove(&term.line[term.c.y][dst], &term.line[term.c.y][src], size * sizeof(Glyph)); - tclearregion(term.col-size, term.c.y, term.col-1, term.c.y); + tclearregion(term.col-n, term.c.y, term.col-1, term.c.y); } void tinsertblank(int n) { int src = term.c.x; int dst = src + n; - int size = term.col - n - src; + int size = term.col - dst; if(dst >= term.col) { tclearregion(term.c.x, term.c.y, term.col-1, term.c.y); return; } memmove(&term.line[term.c.y][dst], &term.line[term.c.y][src], size * sizeof(Glyph)); - tclearregion(src, term.c.y, dst, term.c.y); + tclearregion(src, term.c.y, dst - 1, term.c.y); } void @@ -864,12 +848,7 @@ csireset(void) { void tputtab(void) { int space = TAB - term.c.x % TAB; - - if(term.c.x + space >= term.col) - space--; - - for(; space > 0; space--) - tmovecursor(CURSOR_RIGHT); + tmoveto(term.c.x + space, term.c.y); } void @@ -975,7 +954,7 @@ tputc(char c) { tputtab(); break; case '\b': - tmovecursor(CURSOR_LEFT); + tmoveto(term.c.x-1, term.c.y); break; case '\r': tmoveto(0, term.c.y); @@ -992,7 +971,10 @@ tputc(char c) { break; default: tsetchar(c); - tmovecursor(CURSOR_RIGHT); + if(term.c.x+1 < term.col) { + tmoveto(term.c.x+1, term.c.y); + } else if(IS_SET(MODE_WRAP)) + twrapcursor(); break; } } @@ -1007,23 +989,21 @@ tputs(char *s, int len) { void tresize(int col, int row) { int i; - Line *line; int minrow = MIN(row, term.row); int mincol = MIN(col, term.col); if(col < 1 || row < 1) return; - /* alloc */ - line = calloc(row, sizeof(Line)); - for(i = 0 ; i < row; i++) - line[i] = calloc(col, sizeof(Glyph)); - /* copy */ - for(i = 0 ; i < minrow; i++) - memcpy(line[i], term.line[i], mincol * sizeof(Glyph)); - /* free */ - for(i = 0; i < term.row; i++) + + for(i = row; i < term.row; i++) free(term.line[i]); - free(term.line); + term.line = realloc(term.line, row * sizeof(Line)); + for(i = 0; i < minrow; i++) { + term.line[i] = realloc(term.line[i], col * sizeof(Glyph)); + memset(term.line[i] + mincol, 0, (col - mincol) * sizeof(Glyph)); + } + for(/* i == minrow */; i < row; i++) + term.line[i] = calloc(col, sizeof(Glyph)); LIMIT(term.c.x, 0, col-1); LIMIT(term.c.y, 0, row-1); @@ -1031,7 +1011,6 @@ tresize(int col, int row) { LIMIT(term.bot, 0, row-1); term.bot = row-1; - term.line = line; term.col = col, term.row = row; } @@ -1175,7 +1154,7 @@ 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) xdraws(&term.line[oldy][oldx].c, term.line[oldy][oldx], oldx, oldy, 1); @@ -1291,7 +1270,7 @@ kpress(XEvent *ev) { case XK_Down: case XK_Left: case XK_Right: - sprintf(buf, "\033%c%c", term.mode & MODE_APPKEYPAD ? 'O' : '[', "DACB"[ksym - XK_Left]); + sprintf(buf, "\033%c%c", IS_SET(MODE_APPKEYPAD) ? 'O' : '[', "DACB"[ksym - XK_Left]); ttywrite(buf, 3); break; case XK_Insert: