X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=st.c;h=9e66d09bf3e94ffd4dc783a6dd7f4ad5187301db;hb=ebc287271cd1c31a0a44826915257093867733ac;hp=0c876f5658ea9415d5f20d11e8ff5e1c269b1f81;hpb=df5c5ed04547986ad2fd22226aaa3da430310374;p=st.git diff --git a/st.c b/st.c index 0c876f5..9e66d09 100644 --- a/st.c +++ b/st.c @@ -28,6 +28,10 @@ #include #endif +#define USAGE \ + "st-" VERSION ", (c) 2010 st engineers\n" \ + "usage: st [-t title] [-e cmd] [-v]\n" + /* Arbitrary sizes */ #define ESC_TITLE_SIZ 256 #define ESC_BUF_SIZ 256 @@ -161,8 +165,8 @@ static void tputc(char); static void tputs(char*, int); static void treset(void); static void tresize(int, int); -static void tscrollup(int); -static void tscrolldown(int); +static void tscrollup(int, int); +static void tscrolldown(int, int); static void tsetattr(int*, int); static void tsetchar(char); static void tsetscroll(int, int); @@ -210,6 +214,8 @@ static CSIEscape escseq; static int cmdfd; static pid_t pid; static Selection sel; +static char *opt_cmd = NULL; +static char *opt_title = NULL; void selinit(void) { @@ -329,9 +335,12 @@ die(const char *errstr, ...) { void execsh(void) { - char *args[3] = {getenv("SHELL"), "-i", NULL}; - DEFAULT(args[0], SHELL); /* if getenv() failed */ - putenv("TERM=" TNAME); + char *args[] = {getenv("SHELL"), "-i", NULL}; + if(opt_cmd) + args[0] = opt_cmd, args[1] = NULL; + else + DEFAULT(args[0], SHELL); + putenv("TERM="TNAME); execvp(args[0], args); } @@ -459,15 +468,15 @@ tswapscreen(void) { } void -tscrolldown (int n) { +tscrolldown(int orig, int n) { int i; Line temp; - LIMIT(n, 0, term.bot-term.top+1); + LIMIT(n, 0, term.bot-orig+1); tclearregion(0, term.bot-n+1, term.col-1, term.bot); - for(i = term.bot; i >= term.top+n; i--) { + for(i = term.bot; i >= orig+n; i--) { temp = term.line[i]; term.line[i] = term.line[i-n]; term.line[i-n] = temp; @@ -475,14 +484,14 @@ tscrolldown (int n) { } void -tscrollup (int n) { +tscrollup(int orig, int n) { int i; Line temp; - LIMIT(n, 0, term.bot-term.top+1); + LIMIT(n, 0, term.bot-orig+1); - tclearregion(0, term.top, term.col-1, term.top+n-1); + tclearregion(0, orig, term.col-1, orig+n-1); - for(i = term.top; i <= term.bot-n; i++) { + for(i = orig; i <= term.bot-n; i++) { temp = term.line[i]; term.line[i] = term.line[i+n]; term.line[i+n] = temp; @@ -491,9 +500,11 @@ tscrollup (int n) { void tnewline(void) { - int y = term.c.y + 1; - if(y > term.bot) - tscrollup(1), y = term.bot; + int y = term.c.y; + if(term.c.y == term.bot) + tscrollup(term.top, 1); + else + y++; tmoveto(0, y); } @@ -585,40 +596,18 @@ tinsertblank(int n) { void tinsertblankline(int n) { - int i; - Line blank; - int bot = term.bot; - if(term.c.y < term.top || term.c.y > term.bot) return; - LIMIT(n, 0, bot-term.c.y+1); - tclearregion(0, bot-n+1, term.col-1, bot); - for(i = bot; i >= term.c.y+n; i--) { - /* swap deleted line <-> blanked line */ - blank = term.line[i]; - term.line[i] = term.line[i-n]; - term.line[i-n] = blank; - } + tscrolldown(term.c.y, n); } void tdeleteline(int n) { - int i; - Line blank; - int bot = term.bot; - if(term.c.y < term.top || term.c.y > term.bot) return; - LIMIT(n, 0, bot-term.c.y+1); - tclearregion(0, term.c.y, term.col-1, term.c.y+n-1); - for(i = term.c.y; i <= bot-n; i++) { - /* swap deleted line <-> blanked line */ - blank = term.line[i]; - term.line[i] = term.line[i+n]; - term.line[i+n] = blank; - } + tscrollup(term.c.y, n); } void @@ -688,7 +677,8 @@ tsetattr(int *attr, int l) { else if(BETWEEN(attr[i], 100, 107)) term.c.attr.fg = attr[i] - 100 + 8; else - fprintf(stderr, "erresc: gfx attr %d unknown\n", attr[i]); + fprintf(stderr, "erresc: gfx attr %d unknown\n", attr[i]), csidump(); + break; } } @@ -790,11 +780,11 @@ csihandle(void) { break; case 'S': /* SU -- Scroll line up */ DEFAULT(escseq.arg[0], 1); - tscrollup(escseq.arg[0]); + tscrollup(term.top, escseq.arg[0]); break; case 'T': /* SD -- Scroll line down */ DEFAULT(escseq.arg[0], 1); - tscrolldown(escseq.arg[0]); + tscrolldown(term.top, escseq.arg[0]); break; case 'L': /* IL -- Insert blank lines */ DEFAULT(escseq.arg[0], 1); @@ -984,7 +974,7 @@ tputc(char c) { break; case 'D': /* IND -- Linefeed */ if(term.c.y == term.bot) - tscrollup(1); + tscrollup(term.top, 1); else tmoveto(term.c.x, term.c.y+1); term.esc = 0; @@ -995,7 +985,7 @@ tputc(char c) { break; case 'M': /* RI -- Reverse index */ if(term.c.y == term.top) - tscrolldown(1); + tscrolldown(term.top, 1); else tmoveto(term.c.x, term.c.y-1); term.esc = 0; @@ -1071,12 +1061,25 @@ tresize(int col, int row) { int i; int minrow = MIN(row, term.row); int mincol = MIN(col, term.col); + int slide = term.c.y - row + 1; if(col < 1 || row < 1) return; - /* free uneeded rows */ - for(i = row; i < term.row; i++) { + /* free unneeded rows */ + i = 0; + if(slide > 0) { + /* slide screen to keep cursor where we expect it - + * tscrollup would work here, but we can optimize to + * memmove because we're freeing the earlier lines */ + for(/* i = 0 */; i < slide; i++) { + free(term.line[i]); + free(term.alt[i]); + } + memmove(term.line, term.line + slide, row * sizeof(Line)); + memmove(term.alt, term.alt + slide, row * sizeof(Line)); + } + for(i += row; i < term.row; i++) { free(term.line[i]); free(term.alt[i]); } @@ -1209,7 +1212,7 @@ xinit(void) { XMapWindow(xw.dis, xw.win); xhints(); - XStoreName(xw.dis, xw.win, "st"); + XStoreName(xw.dis, xw.win, opt_title ? opt_title : "st"); XSync(xw.dis, 0); } @@ -1228,8 +1231,13 @@ xdraws(char *s, Glyph base, int x, int y, int len) { XSetForeground(xw.dis, dc.gc, xfg); if(base.mode & ATTR_GFX) - for(i = 0; i < len; i++) - s[i] = gfx[(int)s[i]]; + for(i = 0; i < len; i++) { + char c = gfx[(unsigned int)s[i] % 256]; + if(c) + s[i] = c; + else if(s[i] > 0x5f) + s[i] -= 0x5f; + } XSetFont(xw.dis, dc.gc, base.mode & ATTR_BOLD ? dc.bfont->fid : dc.font->fid); XDrawImageString(xw.dis, xw.buf, dc.gc, winx, winy, s, len); @@ -1449,10 +1457,21 @@ run(void) { int main(int argc, char *argv[]) { - if(argc == 2 && !strncmp("-v", argv[1], 3)) - die("st-" VERSION ", (c) 2010 st engineers\n"); - else if(argc != 1) - die("usage: st [-v]\n"); + int i; + + for(i = 1; i < argc; i++) { + switch(argv[i][0] != '-' || argv[i][2] ? -1 : argv[i][1]) { + case 't': + if(++i < argc) opt_title = argv[i]; + break; + case 'e': + if(++i < argc) opt_cmd = argv[i]; + break; + case 'v': + default: + die(USAGE); + } + } setlocale(LC_CTYPE, ""); tnew(80, 24); ttynew();