X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=st.c;h=397f6a6294ca9c7c9f2062e4eb8638932dbbb197;hb=c5a9b799d44be9c0fa4264dc34d9dd61321be795;hp=19d0a86887f6dc647bbf120a05466f04d2c988ec;hpb=720cb816dcff55f8b75bdc2a8ffa265f460f5d55;p=st.git diff --git a/st.c b/st.c index 19d0a86..397f6a6 100644 --- a/st.c +++ b/st.c @@ -53,8 +53,6 @@ #define XK_NO_MOD UINT_MAX #define XK_ANY_MOD 0 -#define SELECT_TIMEOUT (20*1000) /* 20 ms */ -#define DRAW_TIMEOUT (20*1000) /* 20 ms */ #define REDRAW_TIMEOUT (80*1000) /* 80 ms */ #define SERRNO strerror(errno) @@ -205,7 +203,6 @@ typedef struct { int ch; /* char height */ int cw; /* char width */ char state; /* focus, redraw, visible */ - struct timeval lastdraw; } XWindow; typedef struct { @@ -240,7 +237,7 @@ typedef struct { short lbearing; short rbearing; XFontSet set; - } font, bfont, ifont; + } font, bfont, ifont, ibfont; } DC; static void die(const char*, ...); @@ -250,7 +247,6 @@ static void drawregion(int, int, int, int); static void execsh(void); static void sigchld(int); static void run(void); -static bool last_draw_too_old(void); static void csidump(void); static void csihandle(void); @@ -292,10 +288,10 @@ static void ttywrite(const char *, size_t); static void xdraws(char *, Glyph, int, int, int, int); static void xhints(void); static void xclear(int, int, int, int); -static void xcopy(void); static void xdrawcursor(void); static void xinit(void); static void xloadcols(void); +static void xresettitle(void); static void xseturgency(int); static void xsetsel(char*); static void xresize(int, int); @@ -638,7 +634,6 @@ void selclear(XEvent *e) { return; sel.bx = -1; tsetdirt(sel.b.y, sel.e.y); - draw(); } void @@ -688,8 +683,6 @@ xsetsel(char *str) { clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime); - - XFlush(xw.dpy); } void @@ -732,7 +725,6 @@ brelease(XEvent *e) { } memcpy(&sel.tclick2, &sel.tclick1, sizeof(struct timeval)); gettimeofday(&sel.tclick1, NULL); - draw(); } void @@ -749,7 +741,6 @@ bmotion(XEvent *e) { int starty = MIN(oldey, sel.ey); int endy = MAX(oldey, sel.ey); tsetdirt(starty, endy); - draw(); } } } @@ -773,6 +764,13 @@ execsh(void) { unsetenv("LINES"); unsetenv("TERMCAP"); + signal(SIGCHLD, SIG_DFL); + signal(SIGHUP, SIG_DFL); + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGALRM, SIG_DFL); + DEFAULT(envshell, SHELL); putenv("TERM="TNAME); args = opt_cmd ? opt_cmd : (char*[]){envshell, "-i", NULL}; @@ -1171,6 +1169,7 @@ tsetattr(int *attr, int l) { case 7: term.c.attr.mode |= ATTR_REVERSE; break; + case 21: case 22: term.c.attr.mode &= ~ATTR_BOLD; break; @@ -1683,6 +1682,7 @@ tputc(char *c) { case 'c': /* RIS -- Reset to inital state */ treset(); term.esc = 0; + xresettitle(); break; case '=': /* DECPAM -- Application keypad */ term.mode |= MODE_APPKEYPAD; @@ -1713,6 +1713,8 @@ tputc(char *c) { if(sel.bx != -1 && BETWEEN(term.c.y, sel.by, sel.ey)) sel.bx = -1; switch(ascii) { + case '\0': /* padding character, do nothing */ + break; case '\t': tputtab(1); break; @@ -1933,13 +1935,15 @@ xgetfontinfo(XFontSet set, int *ascent, int *descent, short *lbearing, short *rb } void -initfonts(char *fontstr, char *bfontstr, char *ifontstr) { +initfonts(char *fontstr, char *bfontstr, char *ifontstr, char *ibfontstr) { if((dc.font.set = xinitfont(fontstr)) == NULL) die("Can't load font %s\n", fontstr); if((dc.bfont.set = xinitfont(bfontstr)) == NULL) die("Can't load bfont %s\n", bfontstr); if((dc.ifont.set = xinitfont(ifontstr)) == NULL) die("Can't load ifont %s\n", ifontstr); + if((dc.ibfont.set = xinitfont(ibfontstr)) == NULL) + die("Can't load ibfont %s\n", ibfontstr); xgetfontinfo(dc.font.set, &dc.font.ascent, &dc.font.descent, &dc.font.lbearing, &dc.font.rbearing); @@ -1947,6 +1951,8 @@ initfonts(char *fontstr, char *bfontstr, char *ifontstr) { &dc.bfont.lbearing, &dc.bfont.rbearing); xgetfontinfo(dc.ifont.set, &dc.ifont.ascent, &dc.ifont.descent, &dc.ifont.lbearing, &dc.ifont.rbearing); + xgetfontinfo(dc.ibfont.set, &dc.ibfont.ascent, &dc.ibfont.descent, + &dc.ibfont.lbearing, &dc.ibfont.rbearing); } void @@ -1954,14 +1960,14 @@ xinit(void) { XSetWindowAttributes attrs; Cursor cursor; Window parent; - int sw, sh; + int sw, sh, major, minor; if(!(xw.dpy = XOpenDisplay(NULL))) die("Can't open display\n"); xw.scr = XDefaultScreen(xw.dpy); /* font */ - initfonts(FONT, BOLDFONT, ITALICFONT); + initfonts(FONT, BOLDFONT, ITALICFONT, ITALICBOLDFONT); /* XXX: Assuming same size for bold font */ xw.cw = dc.font.rbearing - dc.font.lbearing; @@ -2005,9 +2011,10 @@ xinit(void) { CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask | CWColormap, &attrs); + if(!XdbeQueryExtension(xw.dpy, &major, &minor)) + die("Xdbe extension is not present\n"); xw.buf = XdbeAllocateBackBufferName(xw.dpy, xw.win, XdbeCopied); - /* input methods */ xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL); xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing @@ -2025,7 +2032,7 @@ xinit(void) { xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); - XStoreName(xw.dpy, xw.win, opt_title ? opt_title : "st"); + xresettitle(); XMapWindow(xw.dpy, xw.win); xhints(); XSync(xw.dpy, 0); @@ -2056,6 +2063,8 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { if(base.mode & ATTR_ITALIC) fontset = dc.ifont.set; + if(base.mode & (ATTR_ITALIC|ATTR_ITALIC)) + fontset = dc.ibfont.set; XSetBackground(xw.dpy, dc.gc, dc.col[bg]); XSetForeground(xw.dpy, dc.gc, dc.col[fg]); @@ -2076,13 +2085,6 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { XDrawLine(xw.dpy, xw.buf, dc.gc, winx, winy+1, winx+width-1, winy+1); } -/* copy buffer pixmap to screen pixmap */ -void -xcopy() { - XdbeSwapInfo swpinfo[1] = {{xw.win, XdbeCopied}}; - XdbeSwapBuffers(xw.dpy, swpinfo, 1); -} - void xdrawcursor(void) { static int oldx = 0; @@ -2103,8 +2105,6 @@ xdrawcursor(void) { } else xclear(oldx, oldy, oldx, oldy); - xcopy(); - /* draw the new one */ if(!(term.c.state & CURSOR_HIDE)) { if(!(xw.state & WIN_FOCUSED)) @@ -2117,8 +2117,11 @@ xdrawcursor(void) { xdraws(g.c, g, term.c.x, term.c.y, 1, sl); oldx = term.c.x, oldy = term.c.y; } +} - xcopy(); +void +xresettitle(void) { + XStoreName(xw.dpy, xw.win, opt_title ? opt_title : "st"); } void @@ -2126,14 +2129,16 @@ redraw(void) { struct timespec tv = {0, REDRAW_TIMEOUT * 1000}; tfulldirt(); draw(); + XSync(xw.dpy, False); /* necessary for a good tput flash */ nanosleep(&tv, NULL); } void draw() { + XdbeSwapInfo swpinfo[1] = {{xw.win, XdbeCopied}}; + drawregion(0, 0, term.col, term.row); - xcopy(); - gettimeofday(&xw.lastdraw, NULL); + XdbeSwapBuffers(xw.dpy, swpinfo, 1); } void @@ -2188,7 +2193,6 @@ expose(XEvent *ev) { if(!e->count) xw.state &= ~WIN_REDRAW; } - xcopy(); } void @@ -2221,7 +2225,6 @@ focus(XEvent *ev) { xseturgency(0); } else xw.state &= ~WIN_FOCUSED; - draw(); } char* @@ -2297,7 +2300,6 @@ cmessage(XEvent *e) { } else if(e->xclient.data.l[1] == XEMBED_FOCUS_OUT) { xw.state &= ~WIN_FOCUSED; } - draw(); } } @@ -2320,41 +2322,23 @@ resize(XEvent *e) { ttyresize(col, row); } -bool -last_draw_too_old(void) { - struct timeval now; - gettimeofday(&now, NULL); - return TIMEDIFF(now, xw.lastdraw) >= DRAW_TIMEOUT/1000; -} - void run(void) { XEvent ev; fd_set rfd; int xfd = XConnectionNumber(xw.dpy); - struct timeval timeout = {0}; - bool stuff_to_print = 0; for(;;) { FD_ZERO(&rfd); FD_SET(cmdfd, &rfd); FD_SET(xfd, &rfd); - timeout.tv_sec = 0; - timeout.tv_usec = SELECT_TIMEOUT; - if(select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, &timeout) < 0) { + if(select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, NULL) < 0) { if(errno == EINTR) continue; die("select failed: %s\n", SERRNO); } - if(FD_ISSET(cmdfd, &rfd)) { + if(FD_ISSET(cmdfd, &rfd)) ttyread(); - stuff_to_print = 1; - } - - if(stuff_to_print && last_draw_too_old()) { - stuff_to_print = 0; - draw(); - } while(XPending(xw.dpy)) { XNextEvent(xw.dpy, &ev); @@ -2363,6 +2347,9 @@ run(void) { if(handler[ev.type]) (handler[ev.type])(&ev); } + + draw(); + XFlush(xw.dpy); } }