X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=st.c;h=db5e04f401c8f24953d0cd4bbadc4b40d915db08;hb=2f5ebe0a4d71aea0bb3aa0e500765a402e4a96f4;hp=f288f2a1695c71d68c214360b79afb9fe968e611;hpb=0f4dd5035ed920c67133f1a4b8aef5cbd957c7be;p=st.git diff --git a/st.c b/st.c old mode 100644 new mode 100755 index f288f2a..db5e04f --- a/st.c +++ b/st.c @@ -56,7 +56,7 @@ typedef struct { typedef Glyph* Line; typedef struct { - Glyph attr; /* current char attributes */ + Glyph attr; /* current char attributes */ int x; int y; } TCursor; @@ -65,24 +65,24 @@ typedef struct { /* ESC '[' [[ [] [;]] ] */ typedef struct { char buf[ESC_BUF_SIZ]; /* raw string */ - int len; /* raw string length */ + int len; /* raw string length */ char priv; int arg[ESC_ARG_SIZ]; - int narg; /* nb of args */ + int narg; /* nb of args */ char mode; } CSIEscape; /* Internal representation of the screen */ typedef struct { - int row; /* nb row */ - int col; /* nb col */ + int row; /* nb row */ + int col; /* nb col */ Line* line; /* screen */ - TCursor c; /* cursor */ + TCursor c; /* cursor */ char hidec; - int top; /* top scroll limit */ - int bot; /* bottom scroll limit */ - int mode; /* terminal mode flags */ - int esc; /* escape state flags */ + int top; /* top scroll limit */ + int bot; /* bottom scroll limit */ + int mode; /* terminal mode flags */ + int esc; /* escape state flags */ char title[ESC_TITLE_SIZ]; int titlelen; } Term; @@ -91,9 +91,12 @@ typedef struct { typedef struct { Display* dis; Window win; + Pixmap buf; int scr; - int w; /* window width */ - int h; /* window height */ + int w; /* window width */ + int h; /* window height */ + int bufw; /* pixmap width */ + int bufh; /* pixmap height */ int ch; /* char height */ int cw; /* char width */ } XWindow; @@ -154,7 +157,6 @@ static unsigned long xgetcol(const char *); static void xclear(int, int, int, int); static void xcursor(int); static void xinit(void); -static void xscroll(void); static void expose(XEvent *); static char* kmap(KeySym); @@ -208,14 +210,15 @@ die(const char *errstr, ...) { void execsh(void) { - char *args[3] = {SHELL, "-i", NULL}; + char *args[3] = {getenv("SHELL"), "-i", NULL}; + DEFAULT(args[0], "/bin/sh"); /* default shell if getenv() failed */ putenv("TERM=" TNAME); - execvp(SHELL, args); + execvp(args[0], args); } void xbell(void) { /* visual bell */ - XRectangle r = { 0, 0, xw.w, xw.h }; + XRectangle r = { BORDER, BORDER, xw.bufw, xw.bufh }; XSetForeground(xw.dis, dc.gc, dc.col[BellCol]); XFillRectangles(xw.dis, xw.win, dc.gc, &r, 1); /* usleep(30000); */ @@ -350,9 +353,7 @@ 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++) term.line[i] = term.line[i+1]; memset(temp, 0, sizeof(Glyph) * term.col); @@ -364,12 +365,11 @@ 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]; @@ -383,7 +383,6 @@ tscrollup (int n) { 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)); @@ -467,7 +466,7 @@ void tsetchar(char c) { term.line[term.c.y][term.c.x] = term.c.attr; term.line[term.c.y][term.c.x].c = c; - term.line[term.c.y][term.c.x].state |= GLYPH_SET | GLYPH_DIRTY; + term.line[term.c.y][term.c.x].state |= GLYPH_SET; } void @@ -486,8 +485,6 @@ tclearregion(int x1, int y1, int x2, int y2) { for(y = y1; y <= y2; y++) memset(&term.line[y][x1], 0, sizeof(Glyph)*(x2-x1+1)); - - xclear(x1, y1, x2, y2); } void @@ -519,13 +516,6 @@ tinsertblank(int n) { } void -tsetlinestate(int n, int state) { - int i; - for(i = 0; i < term.col; i++) - term.line[n][i].state |= state; -} - -void tinsertblankline(int n) { int i; Line blank; @@ -546,8 +536,6 @@ tinsertblankline(int n) { term.line[i-n] = blank; /* blank it */ memset(blank, 0, term.col * sizeof(Glyph)); - tsetlinestate(i, GLYPH_DIRTY); - tsetlinestate(i-n, GLYPH_DIRTY); } } @@ -572,8 +560,6 @@ tdeleteline(int n) { term.line[i+n] = blank; /* blank it */ memset(blank, 0, term.col * sizeof(Glyph)); - tsetlinestate(i, GLYPH_DIRTY); - tsetlinestate(i-n, GLYPH_DIRTY); } } @@ -598,7 +584,7 @@ tsetattr(int *attr, int l) { term.c.attr.mode |= ATTR_REVERSE; break; case 22: - term.c.attr.mode &= ~ATTR_BOLD; + term.c.attr.mode &= ~ATTR_BOLD; break; case 24: term.c.attr.mode &= ~ATTR_UNDERLINE; @@ -681,7 +667,7 @@ csihandle(void) { case 'G': /* CHA -- Move to */ case '`': /* XXX: HPA -- same? */ DEFAULT(escseq.arg[0], 1); - tmoveto(escseq.arg[0]-1, term.c.y); + tmoveto(escseq.arg[0]-1, term.c.y); break; case 'H': /* CUP -- Move to */ case 'f': /* XXX: HVP -- same? */ @@ -861,7 +847,6 @@ tputtab(void) { void tputc(char c) { - /* dump(c); */ if(term.esc & ESC_START) { if(term.esc & ESC_CSI) { escseq.buf[escseq.len++] = c; @@ -1037,29 +1022,29 @@ xgetcol(const char *s) { void xclear(int x1, int y1, int x2, int y2) { - XClearArea(xw.dis, xw.win, - x1 * xw.cw, y1 * xw.ch, - (x2-x1+1) * xw.cw, (y2-y1+1) * xw.ch, - False); + XSetForeground(xw.dis, dc.gc, dc.col[DefaultBG]); + XFillRectangle(xw.dis, xw.buf, dc.gc, + x1 * xw.cw, y1 * xw.ch, + (x2-x1+1) * xw.cw, (y2-y1+1) * xw.ch); } void -xscroll(void) { - int srcy = (term.top+1) * xw.ch; - int dsty = term.top * xw.ch; - int height = (term.bot-term.top) * xw.ch; - - xcursor(CURSOR_HIDE); - XCopyArea(xw.dis, xw.win, xw.win, dc.gc, 0, srcy, xw.w, height, 0, dsty); - xclear(0, term.bot, term.col-1, term.bot); +xhints(void) +{ + XClassHint chint = {TNAME, TNAME}; + XWMHints wmhint = {.flags = InputHint, .input = 1}; + XSizeHints shint = { + .flags = PSize | PResizeInc, + .height = xw.h, /* XXX: doesn't seem to work, see run() */ + .width = xw.w, + .height_inc = xw.ch, + .width_inc = xw.cw, + }; + XSetWMProperties(xw.dis, xw.win, NULL, NULL, NULL, 0, &shint, &wmhint, &chint); } void xinit(void) { - XClassHint chint; - XWMHints wmhint; - XSizeHints shint; - char *args[] = {NULL}; int i; xw.dis = XOpenDisplay(NULL); @@ -1073,7 +1058,7 @@ xinit(void) { /* 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; + xw.ch = dc.font->ascent + dc.font->descent; /* colors */ for(i = 0; i < LEN(colorname); i++) @@ -1083,23 +1068,19 @@ xinit(void) { term.c.attr.bg = DefaultBG; term.c.attr.mode = ATTR_NULL; /* windows */ - xw.h = term.row * xw.ch; - xw.w = term.col * xw.cw; - /* XXX: this BORDER is useless after the first resize, handle it in xdraws() */ + xw.h = term.row * xw.ch + 2*BORDER; + xw.w = term.col * xw.cw + 2*BORDER; xw.win = XCreateSimpleWindow(xw.dis, XRootWindow(xw.dis, xw.scr), 0, 0, - xw.w, xw.h, BORDER, + xw.w, xw.h, 0, dc.col[DefaultBG], dc.col[DefaultBG]); + xw.bufw = xw.w - 2*BORDER; + xw.bufh = xw.h - 2*BORDER; + xw.buf = XCreatePixmap(xw.dis, xw.win, xw.bufw, xw.bufh, XDefaultDepth(xw.dis, xw.scr)); /* gc */ dc.gc = XCreateGC(xw.dis, xw.win, 0, NULL); XMapWindow(xw.dis, xw.win); - /* wm stuff */ - chint.res_name = TNAME, chint.res_class = TNAME; - wmhint.input = 1, wmhint.flags = InputHint; - shint.height_inc = xw.ch, shint.width_inc = xw.cw; - shint.height = xw.h, shint.width = xw.w; - shint.flags = PSize | PResizeInc; - XSetWMProperties(xw.dis, xw.win, NULL, NULL, &args[0], 0, &shint, &wmhint, &chint); + xhints(); XStoreName(xw.dis, xw.win, TNAME); XSync(xw.dis, 0); } @@ -1123,10 +1104,10 @@ xdraws(char *s, Glyph base, int x, int y, int len) { 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); + XDrawImageString(xw.dis, xw.buf, dc.gc, winx, winy, s, len); if(base.mode & ATTR_UNDERLINE) - XDrawLine(xw.dis, xw.win, dc.gc, winx, winy+1, winx+width-1, winy+1); + XDrawLine(xw.dis, xw.buf, dc.gc, winx, winy+1, winx+width-1, winy+1); } void @@ -1163,7 +1144,7 @@ xdrawc(int x, int y, Glyph g) { 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); + XDrawImageString(xw.dis, xw.buf, dc.gc, r.x, r.y+dc.font->ascent, &g.c, 1); } void @@ -1178,6 +1159,8 @@ draw_(int dummy) { if(!term.hidec) xcursor(CURSOR_DRAW); + XCopyArea(xw.dis, xw.buf, xw.win, dc.gc, 0, 0, xw.bufw, xw.bufh, BORDER, BORDER); + XFlush(xw.dis); } #endif @@ -1187,7 +1170,6 @@ draw(int redraw_all) { 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; @@ -1206,6 +1188,8 @@ draw(int redraw_all) { xdraws(buf, base, ox, y, i); } xcursor(term.hidec ? CURSOR_HIDE : CURSOR_DRAW); + XCopyArea(xw.dis, xw.buf, xw.win, dc.gc, 0, 0, xw.bufw, xw.bufh, BORDER, BORDER); + XFlush(xw.dis); } void @@ -1232,7 +1216,7 @@ kpress(XEvent *ev) { int meta; int shift; - meta = e->state & Mod1Mask; + meta = e->state & Mod1Mask; shift = e->state & ShiftMask; len = XLookupString(e, buf, sizeof(buf), &ksym, NULL); @@ -1265,16 +1249,21 @@ kpress(XEvent *ev) { void resize(XEvent *e) { int col, row; - col = e->xconfigure.width / xw.cw; - row = e->xconfigure.height / xw.ch; - if(term.col != col || term.row != row) { - tresize(col, row); - ttyresize(col, row); - xw.w = e->xconfigure.width; - xw.h = e->xconfigure.height; - draw(SCREEN_REDRAW); - } + if(e->xconfigure.width == xw.w && e->xconfigure.height == xw.h) + return; + + xw.w = e->xconfigure.width; + xw.h = e->xconfigure.height; + xw.bufw = xw.w - 2*BORDER; + xw.bufh = xw.h - 2*BORDER; + col = xw.bufw / xw.cw; + row = xw.bufh / xw.ch; + tresize(col, row); + ttyresize(col, row); + XFreePixmap(xw.dis, xw.buf); + xw.buf = XCreatePixmap(xw.dis, xw.win, xw.bufw, xw.bufh, XDefaultDepth(xw.dis, xw.scr)); + draw(SCREEN_REDRAW); } void @@ -1285,7 +1274,7 @@ run(void) { running = 1; XSelectInput(xw.dis, xw.win, ExposureMask | KeyPressMask | StructureNotifyMask); - XResizeWindow(xw.dis, xw.win, xw.w , xw.h); /* fix resize bug in wmii (?) */ + XResizeWindow(xw.dis, xw.win, xw.w, xw.h); /* XXX: fix resize bug in wmii (?) */ while(running) { FD_ZERO(&rfd); @@ -1298,7 +1287,7 @@ run(void) { } if(FD_ISSET(cmdfd, &rfd)) { ttyread(); - draw(SCREEN_UPDATE); + draw(SCREEN_UPDATE); } while(XPending(xw.dis)) { XNextEvent(xw.dis, &ev);