X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=st.c;h=df7f8d8675864d375e122663138fd760c4d5e7f1;hb=e3671006dba1c21316c570e11d6688f5513fb44e;hp=f4ad23d21497d7d3e2ccadef170af3d9e8141aaa;hpb=15cc8754c2e272ebac6e86845859816e881da000;p=st.git diff --git a/st.c b/st.c index f4ad23d..df7f8d8 100644 --- a/st.c +++ b/st.c @@ -48,13 +48,11 @@ #define ESC_ARG_SIZ 16 #define STR_BUF_SIZ 256 #define STR_ARG_SIZ 16 -#define DRAW_BUF_SIZ 1024 +#define DRAW_BUF_SIZ 20*1024 #define UTF_SIZ 4 #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 { @@ -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,7 +288,6 @@ 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); @@ -329,6 +324,7 @@ static int isfullutf8(char *, int); static void *xmalloc(size_t); static void *xrealloc(void *, size_t); +static void *xcalloc(size_t nmemb, size_t size); static void (*handler[LASTEvent])(XEvent *) = { [KeyPress] = kpress, @@ -378,6 +374,14 @@ xrealloc(void *p, size_t len) { return p; } +void * +xcalloc(size_t nmemb, size_t size) { + void *p = calloc(nmemb, size); + if(!p) + die("Out of memory\n"); + return p; +} + int utf8decode(char *s, long *u) { uchar c; @@ -566,8 +570,11 @@ bpress(XEvent *e) { if(IS_SET(MODE_MOUSE)) mousereport(e); else if(e->xbutton.button == Button1) { - if(sel.bx != -1) + if(sel.bx != -1) { + sel.bx = -1; tsetdirt(sel.b.y, sel.e.y); + draw(); + } sel.mode = 1; sel.ex = sel.bx = X2COL(e->xbutton.x); sel.ey = sel.by = Y2ROW(e->xbutton.y); @@ -639,7 +646,6 @@ void selclear(XEvent *e) { return; sel.bx = -1; tsetdirt(sel.b.y, sel.e.y); - draw(); } void @@ -689,8 +695,6 @@ xsetsel(char *str) { clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime); - - XFlush(xw.dpy); } void @@ -733,7 +737,6 @@ brelease(XEvent *e) { } memcpy(&sel.tclick2, &sel.tclick1, sizeof(struct timeval)); gettimeofday(&sel.tclick1, NULL); - draw(); } void @@ -750,7 +753,6 @@ bmotion(XEvent *e) { int starty = MIN(oldey, sel.ey); int endy = MAX(oldey, sel.ey); tsetdirt(starty, endy); - draw(); } } } @@ -1808,8 +1810,8 @@ tresize(int col, int row) { /* allocate any new rows */ for(/* i == minrow */; i < row; i++) { term.dirty[i] = 1; - term.line[i] = calloc(col, sizeof(Glyph)); - term.alt [i] = calloc(col, sizeof(Glyph)); + term.line[i] = xcalloc(col, sizeof(Glyph)); + term.alt [i] = xcalloc(col, sizeof(Glyph)); } if(col > term.col) { bool *bp = term.tabs + term.col; @@ -2095,13 +2097,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; @@ -2122,8 +2117,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)) @@ -2136,8 +2129,6 @@ xdrawcursor(void) { xdraws(g.c, g, term.c.x, term.c.y, 1, sl); oldx = term.c.x, oldy = term.c.y; } - - xcopy(); } void @@ -2156,9 +2147,10 @@ redraw(void) { 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 @@ -2213,7 +2205,6 @@ expose(XEvent *ev) { if(!e->count) xw.state &= ~WIN_REDRAW; } - xcopy(); } void @@ -2246,7 +2237,6 @@ focus(XEvent *ev) { xseturgency(0); } else xw.state &= ~WIN_FOCUSED; - draw(); } char* @@ -2322,7 +2312,6 @@ cmessage(XEvent *e) { } else if(e->xclient.data.l[1] == XEMBED_FOCUS_OUT) { xw.state &= ~WIN_FOCUSED; } - draw(); } } @@ -2339,47 +2328,46 @@ resize(XEvent *e) { row = (xw.h - 2*BORDER) / xw.ch; if(col == term.col && row == term.row) return; - if(tresize(col, row)) - draw(); + tresize(col, row); xresize(col, row); 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; + int xfd = XConnectionNumber(xw.dpy), i; + struct timeval drawtimeout, *tv = NULL; - for(;;) { + for(i = 0;; i++) { 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, tv) < 0) { if(errno == EINTR) continue; die("select failed: %s\n", SERRNO); } - if(FD_ISSET(cmdfd, &rfd)) { + + /* + * Stop after a certain number of reads so the user does not + * feel like the system is stuttering. + */ + if(i < 1000 && FD_ISSET(cmdfd, &rfd)) { ttyread(); - stuff_to_print = 1; - } - if(stuff_to_print && last_draw_too_old()) { - stuff_to_print = 0; - draw(); + /* + * Just wait a bit so it isn't disturbing the + * user and the system is able to write something. + */ + drawtimeout.tv_sec = 0; + drawtimeout.tv_usec = 5; + tv = &drawtimeout; + continue; } + i = 0; + tv = NULL; while(XPending(xw.dpy)) { XNextEvent(xw.dpy, &ev); @@ -2388,6 +2376,9 @@ run(void) { if(handler[ev.type]) (handler[ev.type])(&ev); } + + draw(); + XFlush(xw.dpy); } }