X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=st.c;h=7b0fb21e076e41730117dc52ebd736ac7dbfd50b;hb=15c2bff9faa87644abf96c19b17133d03d40b974;hp=213541f50a0ebb2bbe5873769a4d887b2b6247dc;hpb=1827e0643fc95b44d12eaf951be5994637d1b30d;p=st.git diff --git a/st.c b/st.c index 213541f..7b0fb21 100644 --- a/st.c +++ b/st.c @@ -53,12 +53,12 @@ #define XEMBED_FOCUS_OUT 5 /* Arbitrary sizes */ -#define ESC_BUF_SIZ 256 +#define UTF_SIZ 4 +#define ESC_BUF_SIZ (128*UTF_SIZ) #define ESC_ARG_SIZ 16 -#define STR_BUF_SIZ 256 -#define STR_ARG_SIZ 16 +#define STR_BUF_SIZ ESC_BUF_SIZ +#define STR_ARG_SIZ ESC_ARG_SIZ #define DRAW_BUF_SIZ 20*1024 -#define UTF_SIZ 4 #define XK_ANY_MOD UINT_MAX #define XK_NO_MOD 0 @@ -168,7 +168,7 @@ typedef struct { 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; @@ -203,7 +203,7 @@ typedef struct { Display *dpy; Colourmap cmap; Window win; - XdbeBackBuffer buf; + Drawable buf; Atom xembed, wmdeletewin; XIM xim; XIC xic; @@ -213,8 +213,7 @@ typedef struct { 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 w, h; /* window width and height */ int ch; /* char height */ int cw; /* char width */ char state; /* focus, redraw, visible */ @@ -284,11 +283,12 @@ typedef struct { typedef struct { Colour col[LEN(colorname) < 256 ? 256 : LEN(colorname)]; Font font, bfont, ifont, ibfont; + GC gc; } DC; static void die(const char *, ...); static void draw(void); -static void redraw(void); +static void redraw(int); static void drawregion(int, int, int, int); static void execsh(void); static void sigchld(int); @@ -414,6 +414,8 @@ static char *opt_embed = NULL; static char *opt_class = NULL; static char *opt_font = NULL; +bool usedbe = False; + static char *usedfont = NULL; static int usedfontsize = 0; @@ -1508,7 +1510,7 @@ tsetmode(bool priv, bool set, int *args, int narg) { mode = term.mode; MODBIT(term.mode, set, MODE_REVERSE); if(mode != term.mode) - redraw(); + redraw(REDRAW_TIMEOUT); break; case 6: /* DECOM -- Origin */ MODBIT(term.c.state, set, CURSOR_ORIGIN); @@ -1911,12 +1913,13 @@ tputc(char *c, int len) { if(iofd != -1) { if (xwrite(iofd, c, len) < 0) { - fprintf(stderr, "Error writting in %s:%s\n", + fprintf(stderr, "Error writing in %s:%s\n", opt_io, strerror(errno)); close(iofd); iofd = -1; } } + /* * STR sequences must be checked before anything else * because it can use some control codes as part of the sequence. @@ -1931,10 +1934,23 @@ tputc(char *c, int len) { strhandle(); break; default: - strescseq.buf[strescseq.len++] = ascii; - if(strescseq.len+1 >= STR_BUF_SIZ) { - term.esc = 0; - strhandle(); + if(strescseq.len + len < sizeof(strescseq.buf)) { + memmove(&strescseq.buf[strescseq.len], c, len); + strescseq.len += len; + } else { + /* + * Here is a bug in terminals. If the user never sends + * some code to stop the str or esc command, then st + * will stop responding. But this is better than + * silently failing with unknown characters. At least + * then users will report back. + * + * In the case users ever get fixed, here is the code: + */ + /* + * term.esc = 0; + * strhandle(); + */ } } return; @@ -2218,6 +2234,14 @@ xresize(int col, int row) { xw.tw = MAX(1, col * xw.cw); xw.th = MAX(1, row * xw.ch); + if(!usedbe) { + XFreePixmap(xw.dpy, xw.buf); + xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, + DefaultDepth(xw.dpy, xw.scr)); + XSetForeground(xw.dpy, dc.gc, 0); + XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, xw.w, xw.h); + } + XftDrawChange(xw.draw, xw.buf); } @@ -2433,7 +2457,7 @@ xzoom(const Arg *arg) xunloadfonts(); xloadfonts(usedfont, usedfontsize + arg->i); cresize(0, 0); - draw(); + redraw(0); } void @@ -2486,7 +2510,8 @@ xinit(void) { | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; attrs.colormap = xw.cmap; - parent = opt_embed ? strtol(opt_embed, NULL, 0) : XRootWindow(xw.dpy, xw.scr); + 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, xw.vis, @@ -2495,9 +2520,22 @@ xinit(void) { &attrs); /* double buffering */ - if(!XdbeQueryExtension(xw.dpy, &major, &minor)) - die("Xdbe extension is not present\n"); - xw.buf = XdbeAllocateBackBufferName(xw.dpy, xw.win, XdbeBackground); + /* + if(XdbeQueryExtension(xw.dpy, &major, &minor)) { + xw.buf = XdbeAllocateBackBufferName(xw.dpy, xw.win, + XdbeBackground); + usedbe = True; + } else { + */ + dc.gc = XCreateGC(xw.dpy, parent, 0, 0); + xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, + DefaultDepth(xw.dpy, xw.scr)); + XSetForeground(xw.dpy, dc.gc, 0); + XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, xw.w, xw.h); + //xw.buf = xw.win; + /* + } + */ /* Xft rendering context */ xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); @@ -2794,13 +2832,16 @@ xresettitle(void) { } void -redraw(void) { - struct timespec tv = {0, REDRAW_TIMEOUT * 1000}; +redraw(int timeout) { + struct timespec tv = {0, timeout * 1000}; tfulldirt(); draw(); - XSync(xw.dpy, False); /* necessary for a good tput flash */ - nanosleep(&tv, NULL); + + if(timeout > 0) { + nanosleep(&tv, NULL); + XSync(xw.dpy, False); /* necessary for a good tput flash */ + } } void @@ -2808,7 +2849,14 @@ draw(void) { XdbeSwapInfo swpinfo[1] = {{xw.win, XdbeCopied}}; drawregion(0, 0, term.col, term.row); - XdbeSwapBuffers(xw.dpy, swpinfo, 1); + if(usedbe) { + XdbeSwapBuffers(xw.dpy, swpinfo, 1); + } else { + XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, xw.w, + xw.h, 0, 0); + XSetForeground(xw.dpy, dc.gc, 0); + XSync(xw.dpy, False); + } } void @@ -2867,6 +2915,7 @@ expose(XEvent *ev) { if(!e->count) xw.state &= ~WIN_REDRAW; } + redraw(0); } void