X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=st.c;h=7befdc0c05beb481eb2c0e48b312b2449563868f;hb=e5295629cdffb711001f3fdffbb9aa4ef772add0;hp=38cec50781ea53c47b4284df87845e16a577d94a;hpb=384fabdb5b2ac6c700a974a7fac539c8c14107f6;p=st.git diff --git a/st.c b/st.c index 38cec50..7befdc0 100644 --- a/st.c +++ b/st.c @@ -61,6 +61,7 @@ #define DRAW_BUF_SIZ 20*1024 #define XK_ANY_MOD UINT_MAX #define XK_NO_MOD 0 +#define XK_SWITCH_MOD (1<<13) #define REDRAW_TIMEOUT (80*1000) /* 80 ms */ @@ -807,7 +808,6 @@ void selclear(XEvent *e) { void selrequest(XEvent *e) { - fprintf(stderr, "selrequest\n"); XSelectionRequestEvent *xsre; XSelectionEvent xev; Atom xa_targets, string; @@ -843,7 +843,6 @@ selrequest(XEvent *e) { void xsetsel(char *str) { - fprintf(stderr, "xsetsel: %s\n", str); /* register the selection for both the clipboard and the primary */ Atom clipboard; @@ -1421,7 +1420,8 @@ tsetattr(int *attr, int l) { case 4: term.c.attr.mode |= ATTR_UNDERLINE; break; - case 5: + case 5: /* slow blink */ + case 6: /* rapid blink */ term.c.attr.mode |= ATTR_BLINK; break; case 7: @@ -1438,6 +1438,7 @@ tsetattr(int *attr, int l) { term.c.attr.mode &= ~ATTR_UNDERLINE; break; case 25: + case 26: term.c.attr.mode &= ~ATTR_BLINK; break; case 27: @@ -1557,9 +1558,11 @@ tsetmode(bool priv, bool set, int *args, int narg) { break; case 1000: /* 1000,1002: enable xterm mouse report */ MODBIT(term.mode, set, MODE_MOUSEBTN); + MODBIT(term.mode, 0, MODE_MOUSEMOTION); break; case 1002: MODBIT(term.mode, set, MODE_MOUSEMOTION); + MODBIT(term.mode, 0, MODE_MOUSEBTN); break; case 1006: MODBIT(term.mode, set, MODE_MOUSESGR); @@ -1659,7 +1662,7 @@ csihandle(void) { tmoveto(0, term.c.y-csiescseq.arg[0]); break; case 'g': /* TBC -- Tabulation clear */ - switch (csiescseq.arg[0]) { + switch(csiescseq.arg[0]) { case 0: /* clear current tab stop */ term.tabs[term.c.x] = 0; break; @@ -1743,8 +1746,8 @@ csihandle(void) { break; case 'X': /* ECH -- Erase char */ DEFAULT(csiescseq.arg[0], 1); - tclearregion(term.c.x, term.c.y, term.c.x + csiescseq.arg[0], - term.c.y, 0); + tclearregion(term.c.x, term.c.y, + term.c.x + csiescseq.arg[0] - 1, term.c.y, 1); break; case 'P': /* DCH -- Delete char */ DEFAULT(csiescseq.arg[0], 1); @@ -1924,7 +1927,7 @@ techo(char *buf, int len) { if(c == '\033') { /* escape */ tputc("^", 1); tputc("[", 1); - } else if (c < '\x20') { /* control code */ + } else if(c < '\x20') { /* control code */ if(c != '\n' && c != '\r' && c != '\t') { c |= '\x40'; tputc("^", 1); @@ -1934,7 +1937,7 @@ techo(char *buf, int len) { break; } } - if (len) + if(len) tputc(buf, len); } @@ -1944,7 +1947,7 @@ tputc(char *c, int len) { bool control = ascii < '\x20' || ascii == 0177; if(iofd != -1) { - if (xwrite(iofd, c, len) < 0) { + if(xwrite(iofd, c, len) < 0) { fprintf(stderr, "Error writing in %s:%s\n", opt_io, strerror(errno)); close(iofd); @@ -2206,9 +2209,11 @@ tresize(int col, int row) { /* free unneeded rows */ i = 0; if(slide > 0) { - /* slide screen to keep cursor where we expect it - + /* + * slide screen to keep cursor where we expect it - * tscrollup would work here, but we can optimize to - * memmove because we're freeing the earlier lines */ + * memmove because we're freeing the earlier lines + */ for(/* i = 0 */; i < slide; i++) { free(term.line[i]); free(term.alt[i]); @@ -2273,7 +2278,7 @@ xresize(int col, int row) { 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); + XSetForeground(xw.dpy, dc.gc, dc.col[IS_SET(MODE_REVERSE) ? defaultfg : defaultbg].pixel); XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, xw.w, xw.h); } @@ -2283,7 +2288,7 @@ xresize(int col, int row) { void xloadcols(void) { int i, r, g, b; - XRenderColor color = { .alpha = 0 }; + XRenderColor color = { .alpha = 0xffff }; /* load colors [0-15] colors and [256-LEN(colorname)[ (config.h) */ for(i = 0; i < LEN(colorname); i++) { @@ -2438,34 +2443,34 @@ xloadfonts(char *fontstr, int fontsize) { xw.cw = dc.font.width; xw.ch = dc.font.height; - FcPatternDel(pattern, FC_WEIGHT); - FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); - if(xloadfont(&dc.bfont, pattern)) - die("st: can't open font %s\n", fontstr); - FcPatternDel(pattern, FC_SLANT); FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); - if(xloadfont(&dc.ibfont, pattern)) + if(xloadfont(&dc.ifont, pattern)) die("st: can't open font %s\n", fontstr); FcPatternDel(pattern, FC_WEIGHT); - if(xloadfont(&dc.ifont, pattern)) + FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); + if(xloadfont(&dc.ibfont, pattern)) + die("st: can't open font %s\n", fontstr); + + FcPatternDel(pattern, FC_SLANT); + FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); + if(xloadfont(&dc.bfont, pattern)) die("st: can't open font %s\n", fontstr); FcPatternDestroy(pattern); } void -xunloadfonts(void) -{ +xunloadfonts(void) { int i, ip; /* * Free the loaded fonts in the font cache. This is done backwards * from the frccur. */ - for (i = 0, ip = frccur; i < frclen; i++, ip--) { - if (ip < 0) + for(i = 0, ip = frccur; i < frclen; i++, ip--) { + if(ip < 0) ip = LEN(frc) - 1; XftFontClose(xw.dpy, frc[ip].font); } @@ -2487,8 +2492,7 @@ xunloadfonts(void) } void -xzoom(const Arg *arg) -{ +xzoom(const Arg *arg) { xunloadfonts(); xloadfonts(usedfont, usedfontsize + arg->i); cresize(0, 0); @@ -2509,7 +2513,7 @@ xinit(void) { xw.vis = XDefaultVisual(xw.dpy, xw.scr); /* font */ - if (!FcInit()) + if(!FcInit()) die("Could not init fontconfig.\n"); usedfont = (opt_font == NULL)? font : opt_font; @@ -2570,7 +2574,7 @@ xinit(void) { &gcvalues); xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, DefaultDepth(xw.dpy, xw.scr)); - XSetForeground(xw.dpy, dc.gc, 0); + XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, xw.w, xw.h); //xw.buf = xw.win; /* @@ -2712,7 +2716,7 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { XftDrawRect(xw.draw, bg, winx, winy, width, xw.ch); fcsets[0] = font->set; - for (xp = winx; bytelen > 0;) { + for(xp = winx; bytelen > 0;) { /* * Search for the range in the to be printed string of glyphs * that are in the main font. Then print that range. If @@ -2722,22 +2726,22 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { u8fs = s; u8fblen = 0; u8fl = 0; - for (;;) { + for(;;) { u8c = s; u8cblen = utf8decode(s, &u8char); s += u8cblen; bytelen -= u8cblen; doesexist = XftCharIndex(xw.dpy, font->match, u8char); - if (!doesexist || bytelen <= 0) { - if (bytelen <= 0) { - if (doesexist) { + if(!doesexist || bytelen <= 0) { + if(bytelen <= 0) { + if(doesexist) { u8fl++; u8fblen += u8cblen; } } - if (u8fl > 0) { + if(u8fl > 0) { XftDrawStringUtf8(xw.draw, fg, font->match, xp, winy + font->ascent, @@ -2751,23 +2755,23 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { u8fl++; u8fblen += u8cblen; } - if (doesexist) + if(doesexist) break; frp = frccur; /* Search the font cache. */ - for (i = 0; i < frclen; i++, frp--) { - if (frp <= 0) + for(i = 0; i < frclen; i++, frp--) { + if(frp <= 0) frp = LEN(frc) - 1; - if (frc[frp].c == u8char + if(frc[frp].c == u8char && frc[frp].flags == frcflags) { break; } } /* Nothing was found. */ - if (i >= frclen) { + if(i >= frclen) { /* * Nothing was found in the cache. Now use * some dozen of Fontconfig calls to get the @@ -2795,9 +2799,9 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { */ frccur++; frclen++; - if (frccur >= LEN(frc)) + if(frccur >= LEN(frc)) frccur = 0; - if (frclen > LEN(frc)) { + if(frclen > LEN(frc)) { frclen = LEN(frc); XftFontClose(xw.dpy, frc[frccur].font); } @@ -2894,7 +2898,7 @@ draw(void) { } else { XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, xw.w, xw.h, 0, 0); - XSetForeground(xw.dpy, dc.gc, 0); + XSetForeground(xw.dpy, dc.gc, dc.col[IS_SET(MODE_REVERSE) ? defaultfg : defaultbg].pixel); } } @@ -2986,6 +2990,11 @@ xseturgency(int add) { void focus(XEvent *ev) { + XFocusChangeEvent *e = &ev->xfocus; + + if(e->mode == NotifyGrab) + return; + if(ev->type == FocusIn) { XSetICFocus(xw.xic); xw.state |= WIN_FOCUSED; @@ -2998,6 +3007,8 @@ focus(XEvent *ev) { inline bool match(uint mask, uint state) { + state &= ~(ignoremod); + if(mask == XK_NO_MOD && state) return false; if(mask != XK_ANY_MOD && mask != XK_NO_MOD && !state) @@ -3072,7 +3083,7 @@ kpress(XEvent *ev) { Status status; Shortcut *bp; - if (IS_SET(MODE_KBDLOCK)) + if(IS_SET(MODE_KBDLOCK)) return; len = XmbLookupString(xw.xic, e, xstr, sizeof(xstr), &ksym, &status); @@ -3094,7 +3105,7 @@ kpress(XEvent *ev) { if(len == 0) return; - if (len == 1 && e->state & Mod1Mask) + if(len == 1 && e->state & Mod1Mask) *cp++ = '\033'; memcpy(cp, xstr, len); @@ -3109,8 +3120,10 @@ kpress(XEvent *ev) { void cmessage(XEvent *e) { - /* See xembed specs - http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html */ + /* + * See xembed specs + * http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html + */ if(e->xclient.message_type == xw.xembed && e->xclient.format == 32) { if(e->xclient.data.l[1] == XEMBED_FOCUS_IN) { xw.state |= WIN_FOCUSED; @@ -3126,8 +3139,7 @@ cmessage(XEvent *e) { } void -cresize(int width, int height) -{ +cresize(int width, int height) { int col, row; if(width != 0) @@ -3155,10 +3167,12 @@ void run(void) { XEvent ev; fd_set rfd; - int xfd = XConnectionNumber(xw.dpy), i; - struct timeval drawtimeout, *tv = NULL; + int xfd = XConnectionNumber(xw.dpy), xev; + struct timeval drawtimeout, *tv = NULL, now, last; + + gettimeofday(&last, NULL); - for(i = 0;; i++) { + for(xev = actionfps;;) { FD_ZERO(&rfd); FD_SET(cmdfd, &rfd); FD_SET(xfd, &rfd); @@ -3168,35 +3182,36 @@ run(void) { die("select failed: %s\n", SERRNO); } - /* - * 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)) { + gettimeofday(&now, NULL); + drawtimeout.tv_sec = 0; + drawtimeout.tv_usec = (1000/xfps) * 1000; + tv = &drawtimeout; + + if(FD_ISSET(cmdfd, &rfd)) ttyread(); - /* - * 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; + if(FD_ISSET(xfd, &rfd)) + xev = actionfps; - while(XPending(xw.dpy)) { - XNextEvent(xw.dpy, &ev); - if(XFilterEvent(&ev, None)) - continue; - if(handler[ev.type]) - (handler[ev.type])(&ev); - } + if(TIMEDIFF(now, last) > \ + (xev ? (1000/xfps) : (1000/actionfps))) { + while(XPending(xw.dpy)) { + XNextEvent(xw.dpy, &ev); + if(XFilterEvent(&ev, None)) + continue; + if(handler[ev.type]) + (handler[ev.type])(&ev); + } + + draw(); + XFlush(xw.dpy); + last = now; - draw(); - XFlush(xw.dpy); + if(xev && !FD_ISSET(xfd, &rfd)) + xev--; + if(!FD_ISSET(cmdfd, &rfd) && !FD_ISSET(xfd, &rfd)) + tv = NULL; + } } }