X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=st.c;h=4ead319dc0f07cc2dced9a2ba905ed37a22df70b;hb=a2a60f0a2ce33dbd4ef07aaa4a914391481fa1de;hp=0db3d58716d3b5203ee4f14b1559c63b3fa2585c;hpb=dc33d1d66e89ee974cc6d7cfa2efb693ce67aa86;p=st.git diff --git a/st.c b/st.c index 0db3d58..4ead319 100644 --- a/st.c +++ b/st.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -333,6 +334,7 @@ static void xzoomreset(const Arg *); static void printsel(const Arg *); static void printscreen(const Arg *) ; static void toggleprinter(const Arg *); +static void sendbreak(const Arg *); /* Config.h for applying patches and the configuration. */ #include "config.h" @@ -1002,7 +1004,10 @@ getsel(void) /* append every set & selected glyph to the selection */ for (y = sel.nb.y; y <= sel.ne.y; y++) { - linelen = tlinelen(y); + if ((linelen = tlinelen(y)) == 0) { + *ptr++ = '\n'; + continue; + } if (sel.type == SEL_RECTANGULAR) { gp = &term.line[y][sel.nb.x]; @@ -1130,10 +1135,10 @@ selnotify(XEvent *e) *repl++ = '\r'; } - if (IS_SET(MODE_BRCKTPASTE)) + if (IS_SET(MODE_BRCKTPASTE) && ofs == 0) ttywrite("\033[200~", 6); ttysend((char *)data, nitems * format / 8); - if (IS_SET(MODE_BRCKTPASTE)) + if (IS_SET(MODE_BRCKTPASTE) && rem == 0) ttywrite("\033[201~", 6); XFree(data); /* number of 32-bit chunks returned */ @@ -1425,8 +1430,7 @@ ttynew(void) if (opt_line) { if ((cmdfd = open(opt_line, O_RDWR)) < 0) die("open line failed: %s\n", strerror(errno)); - close(0); - dup(cmdfd); + dup2(cmdfd, 0); stty(); return; } @@ -1531,7 +1535,8 @@ ttywrite(const char *s, size_t n) * This means the buffer is getting full * again. Empty it. */ - ttyread(); + if (n < 256) + ttyread(); n -= r; s += r; } else { @@ -2428,15 +2433,15 @@ csihandle(void) break; case ' ': switch (csiescseq.mode[1]) { - case 'q': /* DECSCUSR -- Set Cursor Style */ - DEFAULT(csiescseq.arg[0], 1); - if (!BETWEEN(csiescseq.arg[0], 0, 6)) { - goto unknown; - } - xw.cursor = csiescseq.arg[0]; - break; - default: + case 'q': /* DECSCUSR -- Set Cursor Style */ + DEFAULT(csiescseq.arg[0], 1); + if (!BETWEEN(csiescseq.arg[0], 0, 6)) { goto unknown; + } + xw.cursor = csiescseq.arg[0]; + break; + default: + goto unknown; } break; } @@ -2577,6 +2582,13 @@ strreset(void) memset(&strescseq, 0, sizeof(strescseq)); } +void +sendbreak(const Arg *arg) +{ + if (tcsendbreak(cmdfd, 0)) + perror("Error sending break"); +} + void tprinter(char *s, size_t len) { @@ -2773,18 +2785,37 @@ tcontrolcode(uchar ascii) case '\023': /* XOFF (IGNORED) */ case 0177: /* DEL (IGNORED) */ return; + case 0x80: /* TODO: PAD */ + case 0x81: /* TODO: HOP */ + case 0x82: /* TODO: BPH */ + case 0x83: /* TODO: NBH */ case 0x84: /* TODO: IND */ break; case 0x85: /* NEL -- Next line */ tnewline(1); /* always go to first col */ break; + case 0x86: /* TODO: SSA */ + case 0x87: /* TODO: ESA */ + break; case 0x88: /* HTS -- Horizontal tab stop */ term.tabs[term.c.x] = 1; break; + case 0x89: /* TODO: HTJ */ + case 0x8a: /* TODO: VTS */ + case 0x8b: /* TODO: PLD */ + case 0x8c: /* TODO: PLU */ case 0x8d: /* TODO: RI */ case 0x8e: /* TODO: SS2 */ case 0x8f: /* TODO: SS3 */ + case 0x91: /* TODO: PU1 */ + case 0x92: /* TODO: PU2 */ + case 0x93: /* TODO: STS */ + case 0x94: /* TODO: CCH */ + case 0x95: /* TODO: MW */ + case 0x96: /* TODO: SPA */ + case 0x97: /* TODO: EPA */ case 0x98: /* TODO: SOS */ + case 0x99: /* TODO: SGCI */ break; case 0x9a: /* DECID -- Identify Terminal */ ttywrite(vtiden, sizeof(vtiden) - 1); @@ -2793,9 +2824,9 @@ tcontrolcode(uchar ascii) case 0x9c: /* TODO: ST */ break; case 0x90: /* DCS -- Device Control String */ - case 0x9f: /* APC -- Application Program Command */ - case 0x9e: /* PM -- Privacy Message */ case 0x9d: /* OSC -- Operating System Command */ + case 0x9e: /* PM -- Privacy Message */ + case 0x9f: /* APC -- Application Program Command */ tstrsequence(ascii); return; } @@ -2895,15 +2926,15 @@ tputc(Rune u) int width, len; Glyph *gp; + control = ISCONTROL(u); len = utf8encode(u, c); - if ((width = wcwidth(u)) == -1) { + if (!control && (width = wcwidth(u)) == -1) { memcpy(c, "\357\277\275", 4); /* UTF_INVALID */ width = 1; } if (IS_SET(MODE_PRINT)) tprinter(c, len); - control = ISCONTROL(u); /* * STR sequence must be checked before anything else @@ -3411,6 +3442,7 @@ xinit(void) Cursor cursor; Window parent; pid_t thispid = getpid(); + XColor xmousefg, xmousebg; if (!(xw.dpy = XOpenDisplay(NULL))) die("Can't open display\n"); @@ -3483,11 +3515,22 @@ xinit(void) die("XCreateIC failed. Could not obtain input method.\n"); /* white cursor, black outline */ - cursor = XCreateFontCursor(xw.dpy, XC_xterm); + cursor = XCreateFontCursor(xw.dpy, mouseshape); XDefineCursor(xw.dpy, xw.win, cursor); - XRecolorCursor(xw.dpy, cursor, - &(XColor){.red = 0xffff, .green = 0xffff, .blue = 0xffff}, - &(XColor){.red = 0x0000, .green = 0x0000, .blue = 0x0000}); + + if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) { + xmousefg.red = 0xffff; + xmousefg.green = 0xffff; + xmousefg.blue = 0xffff; + } + + if (XParseColor(xw.dpy, xw.cmap, colorname[mousebg], &xmousebg) == 0) { + xmousebg.red = 0x0000; + xmousebg.green = 0x0000; + xmousebg.blue = 0x0000; + } + + XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg); xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); @@ -3775,6 +3818,7 @@ xdrawglyph(Glyph g, int x, int y) { int numspecs; XftGlyphFontSpec spec; + numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); xdrawglyphfontspecs(&spec, g, numspecs, x, y); } @@ -3784,7 +3828,9 @@ xdrawcursor(void) { static int oldx = 0, oldy = 0; int curx; - Glyph g = {' ', ATTR_NULL, defaultbg, defaultcs}; + Glyph g = {' ', ATTR_NULL, defaultbg, defaultcs}, og; + int ena_sel = sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN); + Color drawcol; LIMIT(oldx, 0, term.col-1); LIMIT(oldy, 0, term.row-1); @@ -3797,10 +3843,19 @@ xdrawcursor(void) if (term.line[term.c.y][curx].mode & ATTR_WDUMMY) curx--; - g.u = term.line[term.c.y][term.c.x].u; - /* remove the old cursor */ - xdrawglyph(term.line[oldy][oldx], oldx, oldy); + og = term.line[oldy][oldx]; + if (ena_sel && selected(oldx, oldy)) + og.mode ^= ATTR_REVERSE; + xdrawglyph(og, oldx, oldy); + + g.u = term.line[term.c.y][term.c.x].u; + if (ena_sel && selected(term.c.x, term.c.y)) { + drawcol = dc.col[defaultrcs]; + g.mode ^= ATTR_REVERSE; + } else { + drawcol = dc.col[defaultcs]; + } if (IS_SET(MODE_HIDE)) return; @@ -3808,47 +3863,50 @@ xdrawcursor(void) /* draw the new one */ if (xw.state & WIN_FOCUSED) { switch (xw.cursor) { - case 0: /* Blinking Block */ - case 1: /* Blinking Block (Default) */ - case 2: /* Steady Block */ - if (IS_SET(MODE_REVERSE)) { - g.mode |= ATTR_REVERSE; - g.fg = defaultcs; - g.bg = defaultfg; - } + case 7: /* st extension: snowman */ + utf8decode("☃", &g.u, UTF_SIZ); + case 0: /* Blinking Block */ + case 1: /* Blinking Block (Default) */ + case 2: /* Steady Block */ + if (IS_SET(MODE_REVERSE)) { + g.mode |= ATTR_REVERSE; + g.fg = defaultcs; + g.bg = defaultfg; + } - g.mode |= term.line[term.c.y][curx].mode & ATTR_WIDE; - xdrawglyph(g, term.c.x, term.c.y); - break; - case 3: /* Blinking Underline */ - case 4: /* Steady Underline */ - XftDrawRect(xw.draw, &dc.col[defaultcs], - borderpx + curx * xw.cw, - borderpx + (term.c.y + 1) * xw.ch - cursorthickness, - xw.cw, cursorthickness); - break; - case 5: /* Blinking bar */ - case 6: /* Steady bar */ - XftDrawRect(xw.draw, &dc.col[defaultcs], - borderpx + curx * xw.cw, - borderpx + term.c.y * xw.ch, - cursorthickness, xw.ch); - break; + g.mode |= term.line[term.c.y][curx].mode & ATTR_WIDE; + xdrawglyph(g, term.c.x, term.c.y); + break; + case 3: /* Blinking Underline */ + case 4: /* Steady Underline */ + XftDrawRect(xw.draw, &drawcol, + borderpx + curx * xw.cw, + borderpx + (term.c.y + 1) * xw.ch - \ + cursorthickness, + xw.cw, cursorthickness); + break; + case 5: /* Blinking bar */ + case 6: /* Steady bar */ + XftDrawRect(xw.draw, &drawcol, + borderpx + curx * xw.cw, + borderpx + term.c.y * xw.ch, + cursorthickness, xw.ch); + break; } } else { - XftDrawRect(xw.draw, &dc.col[defaultcs], + XftDrawRect(xw.draw, &drawcol, borderpx + curx * xw.cw, borderpx + term.c.y * xw.ch, xw.cw - 1, 1); - XftDrawRect(xw.draw, &dc.col[defaultcs], + XftDrawRect(xw.draw, &drawcol, borderpx + curx * xw.cw, borderpx + term.c.y * xw.ch, 1, xw.ch - 1); - XftDrawRect(xw.draw, &dc.col[defaultcs], + XftDrawRect(xw.draw, &drawcol, borderpx + (curx + 1) * xw.cw - 1, borderpx + term.c.y * xw.ch, 1, xw.ch - 1); - XftDrawRect(xw.draw, &dc.col[defaultcs], + XftDrawRect(xw.draw, &drawcol, borderpx + curx * xw.cw, borderpx + (term.c.y + 1) * xw.ch - 1, xw.cw, 1); @@ -3898,7 +3956,7 @@ drawregion(int x1, int y1, int x2, int y2) { int i, x, y, ox, numspecs; Glyph base, new; - XftGlyphFontSpec* specs; + XftGlyphFontSpec *specs; int ena_sel = sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN); if (!(xw.state & WIN_VISIBLE)) @@ -4262,7 +4320,7 @@ usage(void) " [-i] [-t title] [-T title] [-w windowid] [-e command ...]" " [command ...]\n" " st [-a] [-v] [-c class] [-f font] [-g geometry] [-o file]\n" - " [-i] [-t title] [-T title] [-w windowid] [-l line]" + " [-i] [-t title] [-T title] [-w windowid] -l line" " [stty_args ...]\n", argv0); } @@ -4274,7 +4332,7 @@ main(int argc, char *argv[]) xw.l = xw.t = 0; xw.isfixed = False; - xw.cursor = 0; + xw.cursor = cursorshape; ARGBEGIN { case 'a':