X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=st.c;h=efe309fb9b5d5e67deda1f2b3d122a43cf5267bb;hb=980c5956ed4eb0c1e748f1e5c550fabdaaf4ef14;hp=da895c6a64bc3d3a46212c61ed2c3abdd22584de;hpb=b1563526561a913dc2a69ee78eb5aaa09cc98978;p=st.git diff --git a/st.c b/st.c index da895c6..efe309f 100644 --- a/st.c +++ b/st.c @@ -25,6 +25,9 @@ #include #include #include +#include +#define Glyph Glyph_ +#define Font Font_ #if defined(__linux) #include @@ -48,13 +51,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) @@ -109,7 +110,8 @@ enum term_mode { MODE_MOUSEBTN = 32, MODE_MOUSEMOTION = 64, MODE_MOUSE = 32|64, - MODE_REVERSE = 128 + MODE_REVERSE = 128, + MODE_KBDLOCK = 256 }; enum escape_state { @@ -197,15 +199,17 @@ typedef struct { Atom xembed; XIM xim; XIC xic; + XftDraw *xft_draw; + Visual *vis; int scr; - Bool isfixed; /* is fixed geometry? */ + bool isfixed; /* is fixed geometry? */ int fx, fy, fw, fh; /* fixed geometry */ + int tw, th; /* tty width and height */ int w; /* window width */ int h; /* window height */ int ch; /* char height */ int cw; /* char width */ char state; /* focus, redraw, visible */ - struct timeval lastdraw; } XWindow; typedef struct { @@ -214,7 +218,6 @@ typedef struct { char s[ESC_BUF_SIZ]; } Key; - /* TODO: use better name for vars... */ typedef struct { int mode; @@ -230,17 +233,22 @@ typedef struct { #include "config.h" +/* Font structure */ +typedef struct { + int ascent; + int descent; + short lbearing; + short rbearing; + XFontSet set; + XftFont* xft_set; +} Font; + /* Drawing Context */ typedef struct { ulong col[LEN(colorname) < 256 ? 256 : LEN(colorname)]; + XftColor xft_col[LEN(colorname) < 256 ? 256 : LEN(colorname)]; GC gc; - struct { - int ascent; - int descent; - short lbearing; - short rbearing; - XFontSet set; - } font, bfont, ifont; + Font font, bfont, ifont, ibfont; } DC; static void die(const char*, ...); @@ -250,7 +258,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); @@ -271,7 +278,7 @@ static void tmoveto(int, int); static void tnew(int, int); static void tnewline(int); static void tputtab(bool); -static void tputc(char*); +static void tputc(char*, int); static void treset(void); static int tresize(int, int); static void tscrollup(int, int); @@ -286,13 +293,12 @@ static void tfulldirt(void); static void ttynew(void); static void ttyread(void); -static void ttyresize(int, int); +static void ttyresize(void); 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 +335,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, @@ -367,14 +374,22 @@ void * xmalloc(size_t len) { void *p = malloc(len); if(!p) - die("Out of memory"); + die("Out of memory\n"); return p; } void * xrealloc(void *p, size_t len) { if((p = realloc(p, len)) == NULL) - die("Out of memory"); + die("Out of memory\n"); + return p; +} + +void * +xcalloc(size_t nmemb, size_t size) { + void *p = calloc(nmemb, size); + if(!p) + die("Out of memory\n"); return p; } @@ -566,8 +581,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); @@ -589,14 +607,17 @@ selcopy(void) { /* append every set & selected glyph to the selection */ for(y = 0; y < term.row; y++) { for(x = 0; x < term.col; x++) { - is_selected = selected(x, y); - if((term.line[y][x].state & GLYPH_SET) && is_selected) { - int size = utf8size(term.line[y][x].c); - memcpy(ptr, term.line[y][x].c, size); - ptr += size; - } + int size; + char *p; + Glyph *gp = &term.line[y][x]; + + if(!(is_selected = selected(x, y))) + continue; + p = (gp->state & GLYPH_SET) ? gp->c : " "; + size = utf8size(p); + memcpy(ptr, p, size); + ptr += size; } - /* \n at the end of every selected line except for the last one */ if(is_selected && y < sel.e.y) *ptr++ = '\n'; @@ -639,7 +660,6 @@ void selclear(XEvent *e) { return; sel.bx = -1; tsetdirt(sel.b.y, sel.e.y); - draw(); } void @@ -689,8 +709,6 @@ xsetsel(char *str) { clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime); - - XFlush(xw.dpy); } void @@ -733,7 +751,6 @@ brelease(XEvent *e) { } memcpy(&sel.tclick2, &sel.tclick1, sizeof(struct timeval)); gettimeofday(&sel.tclick1, NULL); - draw(); } void @@ -750,7 +767,6 @@ bmotion(XEvent *e) { int starty = MIN(oldey, sel.ey); int endy = MAX(oldey, sel.ey); tsetdirt(starty, endy); - draw(); } } } @@ -868,7 +884,7 @@ ttyread(void) { while(buflen >= UTF_SIZ || isfullutf8(ptr,buflen)) { charsize = utf8decode(ptr, &utf8c); utf8encode(&utf8c, s); - tputc(s); + tputc(s, charsize); ptr += charsize; buflen -= charsize; } @@ -884,13 +900,13 @@ ttywrite(const char *s, size_t n) { } void -ttyresize(int x, int y) { +ttyresize(void) { struct winsize w; w.ws_row = term.row; w.ws_col = term.col; - w.ws_xpixel = xw.w; - w.ws_ypixel = xw.h; + w.ws_xpixel = xw.tw; + w.ws_ypixel = xw.th; if(ioctl(cmdfd, TIOCSWINSZ, &w) < 0) fprintf(stderr, "Couldn't set window size: %s\n", SERRNO); } @@ -925,7 +941,7 @@ tcursor(int mode) { void treset(void) { - unsigned i; + uint i; term.c = (TCursor){{ .mode = ATTR_NULL, .fg = DefaultFG, @@ -937,6 +953,7 @@ treset(void) { term.tabs[i] = 1; term.top = 0, term.bot = term.row - 1; term.mode = MODE_WRAP; + tclearregion(0, 0, term.col-1, term.row-1); } @@ -1263,7 +1280,8 @@ tsetmode(bool priv, bool set, int *args, int narg) { for(lim = args + narg; args < lim; ++args) { if(priv) { switch(*args) { - case 1: + break; + case 1: /* DECCKM -- Cursor key */ MODBIT(term.mode, set, MODE_APPKEYPAD); break; case 5: /* DECSCNM -- Reverve video */ @@ -1272,12 +1290,14 @@ tsetmode(bool priv, bool set, int *args, int narg) { if(mode != term.mode) redraw(); break; - case 7: + case 6: /* XXX: DECOM -- Origin */ + break; + case 7: /* DECAWM -- Auto wrap */ MODBIT(term.mode, set, MODE_WRAP); break; - case 20: - MODBIT(term.mode, set, MODE_CRLF); + case 8: /* XXX: DECARM -- Auto repeat */ break; + case 0: /* Error (IGNORED) */ case 12: /* att610 -- Start blinking cursor (IGNORED) */ break; case 25: @@ -1305,6 +1325,12 @@ tsetmode(bool priv, bool set, int *args, int narg) { tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); break; default: + /* case 2: DECANM -- ANSI/VT52 (NOT SUPPOURTED) */ + /* case 3: DECCOLM -- Column (NOT SUPPORTED) */ + /* case 4: DECSCLM -- Scroll (NOT SUPPORTED) */ + /* case 18: DECPFF -- Printer feed (NOT SUPPORTED) */ + /* case 19: DECPEX -- Printer extent (NOT SUPPORTED) */ + /* case 42: DECNRCM -- National characters (NOT SUPPORTED) */ fprintf(stderr, "erresc: unknown private set/reset mode %d\n", *args); @@ -1312,9 +1338,19 @@ tsetmode(bool priv, bool set, int *args, int narg) { } } else { switch(*args) { - case 4: + case 0: /* Error (IGNORED) */ + break; + case 2: /* KAM -- keyboard action */ + MODBIT(term.mode, set, MODE_KBDLOCK); + break; + case 4: /* IRM -- Insertion-replacement */ MODBIT(term.mode, set, MODE_INSERT); break; + case 12: /* XXX: SRM -- Send/Receive */ + break; + case 20: /* LNM -- Linefeed/new line */ + MODBIT(term.mode, set, MODE_CRLF); + break; default: fprintf(stderr, "erresc: unknown set/reset mode %d\n", @@ -1588,7 +1624,7 @@ strreset(void) { void tputtab(bool forward) { - unsigned x = term.c.x; + uint x = term.c.x; if(forward) { if(x == term.col) @@ -1605,11 +1641,11 @@ tputtab(bool forward) { } void -tputc(char *c) { +tputc(char *c, int len) { char ascii = *c; if(iofd != -1) - write(iofd, c, 1); + write(iofd, c, len); if(term.esc & ESC_START) { if(term.esc & ESC_CSI) { @@ -1664,6 +1700,7 @@ tputc(char *c) { strescseq.type = ascii; term.esc |= ESC_STR; break; + case ')': case '(': term.esc |= ESC_ALTCHARSET; break; @@ -1692,6 +1729,7 @@ tputc(char *c) { case 'c': /* RIS -- Reset to inital state */ treset(); term.esc = 0; + xclear(0, 0, xw.w, xw.h); xresettitle(); break; case '=': /* DECPAM -- Application keypad */ @@ -1808,8 +1846,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; @@ -1832,49 +1870,51 @@ tresize(int col, int row) { void xresize(int col, int row) { - xw.w = MAX(1, 2*BORDER + col * xw.cw); - xw.h = MAX(1, 2*BORDER + row * xw.ch); + xw.tw = MAX(1, 2*BORDER + col * xw.cw); + xw.th = MAX(1, 2*BORDER + row * xw.ch); + + XftDrawChange(xw.xft_draw, xw.buf); } void xloadcols(void) { int i, r, g, b; - XColor color; + XRenderColor xft_color = { .alpha = 0 }; ulong white = WhitePixel(xw.dpy, xw.scr); /* load colors [0-15] colors and [256-LEN(colorname)[ (config.h) */ for(i = 0; i < LEN(colorname); i++) { if(!colorname[i]) continue; - if(!XAllocNamedColor(xw.dpy, xw.cmap, colorname[i], &color, &color)) { + if(!XftColorAllocName(xw.dpy, xw.vis, xw.cmap, colorname[i], &dc.xft_col[i])) { dc.col[i] = white; fprintf(stderr, "Could not allocate color '%s'\n", colorname[i]); } else - dc.col[i] = color.pixel; + dc.col[i] = dc.xft_col[i].pixel; } /* load colors [16-255] ; same colors as xterm */ for(i = 16, r = 0; r < 6; r++) for(g = 0; g < 6; g++) for(b = 0; b < 6; b++) { - color.red = r == 0 ? 0 : 0x3737 + 0x2828 * r; - color.green = g == 0 ? 0 : 0x3737 + 0x2828 * g; - color.blue = b == 0 ? 0 : 0x3737 + 0x2828 * b; - if(!XAllocColor(xw.dpy, xw.cmap, &color)) { + xft_color.red = r == 0 ? 0 : 0x3737 + 0x2828 * r; + xft_color.green = g == 0 ? 0 : 0x3737 + 0x2828 * g; + xft_color.blue = b == 0 ? 0 : 0x3737 + 0x2828 * b; + if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &xft_color, &dc.xft_col[i])) { dc.col[i] = white; fprintf(stderr, "Could not allocate color %d\n", i); } else - dc.col[i] = color.pixel; + dc.col[i] = dc.xft_col[i].pixel; i++; } for(r = 0; r < 24; r++, i++) { - color.red = color.green = color.blue = 0x0808 + 0x0a0a * r; - if(!XAllocColor(xw.dpy, xw.cmap, &color)) { + xft_color.red = xft_color.green = xft_color.blue = 0x0808 + 0x0a0a * r; + if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &xft_color, &dc.xft_col[i])) { dc.col[i] = white; fprintf(stderr, "Could not allocate color %d\n", i); } else - dc.col[i] = color.pixel; + dc.col[i] = dc.xft_col[i].pixel; } } @@ -1911,54 +1951,25 @@ xhints(void) { XFree(sizeh); } -XFontSet -xinitfont(char *fontstr) { - XFontSet set; - char *def, **missing; - int n; - - missing = NULL; - set = XCreateFontSet(xw.dpy, fontstr, &missing, &n, &def); - if(missing) { - while(n--) - fprintf(stderr, "st: missing fontset: %s\n", missing[n]); - XFreeStringList(missing); - } - return set; -} - void -xgetfontinfo(XFontSet set, int *ascent, int *descent, short *lbearing, short *rbearing) { - XFontStruct **xfonts; - char **font_names; - int i, n; +xinitfont(Font *f, char *fontstr) { + f->xft_set = XftFontOpenName(xw.dpy, xw.scr, fontstr); - *ascent = *descent = *lbearing = *rbearing = 0; - n = XFontsOfFontSet(set, &xfonts, &font_names); - for(i = 0; i < n; i++) { - *ascent = MAX(*ascent, (*xfonts)->ascent); - *descent = MAX(*descent, (*xfonts)->descent); - *lbearing = MAX(*lbearing, (*xfonts)->min_bounds.lbearing); - *rbearing = MAX(*rbearing, (*xfonts)->max_bounds.rbearing); - xfonts++; - } + if(!f->xft_set) + die("st: can't open font %s.\n", fontstr); + + f->ascent = f->xft_set->ascent; + f->descent = f->xft_set->descent; + f->lbearing = 0; + f->rbearing = f->xft_set->max_advance_width; } void -initfonts(char *fontstr, char *bfontstr, char *ifontstr) { - 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); - - xgetfontinfo(dc.font.set, &dc.font.ascent, &dc.font.descent, - &dc.font.lbearing, &dc.font.rbearing); - xgetfontinfo(dc.bfont.set, &dc.bfont.ascent, &dc.bfont.descent, - &dc.bfont.lbearing, &dc.bfont.rbearing); - xgetfontinfo(dc.ifont.set, &dc.ifont.ascent, &dc.ifont.descent, - &dc.ifont.lbearing, &dc.ifont.rbearing); +initfonts(char *fontstr, char *bfontstr, char *ifontstr, char *ibfontstr) { + xinitfont(&dc.font, fontstr); + xinitfont(&dc.bfont, bfontstr); + xinitfont(&dc.ifont, ifontstr); + xinitfont(&dc.ibfont, ibfontstr); } void @@ -1966,14 +1977,15 @@ 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); + xw.vis = XDefaultVisual(xw.dpy, xw.scr); /* 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; @@ -2013,12 +2025,18 @@ xinit(void) { parent = opt_embed ? strtol(opt_embed, NULL, 0) : XRootWindow(xw.dpy, xw.scr); xw.win = XCreateWindow(xw.dpy, parent, xw.fx, xw.fy, xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, - XDefaultVisual(xw.dpy, xw.scr), + xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask | CWColormap, &attrs); + + /* double buffering */ + if(!XdbeQueryExtension(xw.dpy, &major, &minor)) + die("Xdbe extension is not present\n"); xw.buf = XdbeAllocateBackBufferName(xw.dpy, xw.win, XdbeCopied); + /* Xft rendering context */ + xw.xft_draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); /* input methods */ xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL); @@ -2047,7 +2065,8 @@ void xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { int fg = base.fg, bg = base.bg, temp; int winx = BORDER+x*xw.cw, winy = BORDER+y*xw.ch + dc.font.ascent, width = charlen*xw.cw; - XFontSet fontset = dc.font.set; + Font *font = &dc.font; + XGlyphInfo extents; int i; /* only switch default fg/bg if term is in RV mode */ @@ -2063,11 +2082,13 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { if(base.mode & ATTR_BOLD) { fg += 8; - fontset = dc.bfont.set; + font = &dc.bfont; } if(base.mode & ATTR_ITALIC) - fontset = dc.ifont.set; + font = &dc.ifont; + if(base.mode & (ATTR_ITALIC|ATTR_ITALIC)) + font = &dc.ibfont; XSetBackground(xw.dpy, dc.gc, dc.col[bg]); XSetForeground(xw.dpy, dc.gc, dc.col[fg]); @@ -2082,19 +2103,15 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { } } - XmbDrawImageString(xw.dpy, xw.buf, fontset, dc.gc, winx, winy, s, bytelen); + XftTextExtentsUtf8(xw.dpy, font->xft_set, (FcChar8 *)s, bytelen, &extents); + width = extents.xOff; + XftDrawRect(xw.xft_draw, &dc.xft_col[bg], winx, winy - font->ascent, width, xw.ch); + XftDrawStringUtf8(xw.xft_draw, &dc.xft_col[fg], font->xft_set, winx, winy, (FcChar8 *)s, bytelen); if(base.mode & ATTR_UNDERLINE) 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; @@ -2115,8 +2132,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)) @@ -2129,8 +2144,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 @@ -2141,16 +2154,20 @@ xresettitle(void) { void redraw(void) { struct timespec tv = {0, REDRAW_TIMEOUT * 1000}; + + xclear(0, 0, xw.w, xw.h); 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 @@ -2205,7 +2222,6 @@ expose(XEvent *ev) { if(!e->count) xw.state &= ~WIN_REDRAW; } - xcopy(); } void @@ -2238,7 +2254,6 @@ focus(XEvent *ev) { xseturgency(0); } else xw.state &= ~WIN_FOCUSED; - draw(); } char* @@ -2264,6 +2279,8 @@ kpress(XEvent *ev) { int shift; Status status; + if (IS_SET(MODE_KBDLOCK)) + return; meta = e->state & Mod1Mask; shift = e->state & ShiftMask; len = XmbLookupString(xw.xic, e, buf, sizeof(buf), &ksym, &status); @@ -2314,7 +2331,6 @@ cmessage(XEvent *e) { } else if(e->xclient.data.l[1] == XEMBED_FOCUS_OUT) { xw.state &= ~WIN_FOCUSED; } - draw(); } } @@ -2331,47 +2347,48 @@ resize(XEvent *e) { row = (xw.h - 2*BORDER) / xw.ch; if(col == term.col && row == term.row) return; - if(tresize(col, row)) - draw(); - 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; + xclear(0, 0, xw.w, xw.h); + tresize(col, row); + xresize(col, row); + ttyresize(); } 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); @@ -2380,13 +2397,16 @@ run(void) { if(handler[ev.type]) (handler[ev.type])(&ev); } + + draw(); + XFlush(xw.dpy); } } int main(int argc, char *argv[]) { int i, bitm, xr, yr; - unsigned int wr, hr; + uint wr, hr; xw.fw = xw.fh = xw.fx = xw.fy = 0; xw.isfixed = False;