X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=x.c;h=d205ca73022a393670d32668c00917447d080bb5;hb=a5dc1b46976b2252f9d7bb68f126c4b0f351dd1a;hp=a7f619eee3ee0fce1d7723c8f0b401d40f256601;hpb=cfc7acdfd923924ae150a32061fb95987697b159;p=st.git diff --git a/x.c b/x.c index a7f619e..d205ca7 100644 --- a/x.c +++ b/x.c @@ -38,10 +38,9 @@ typedef struct { KeySym k; uint mask; char *s; - /* three valued logic variables: 0 indifferent, 1 on, -1 off */ + /* three-valued logic variables: 0 indifferent, 1 on, -1 off */ signed char appkey; /* application keypad */ signed char appcursor; /* application cursor */ - signed char crlf; /* crlf mode */ } Key; /* X modifiers */ @@ -52,6 +51,7 @@ typedef struct { /* function definitions used in config.h */ static void clipcopy(const Arg *); static void clippaste(const Arg *); +static void numlock(const Arg *); static void selpaste(const Arg *); static void zoom(const Arg *); static void zoomabs(const Arg *); @@ -65,6 +65,7 @@ static void zoomreset(const Arg *); #define XEMBED_FOCUS_OUT 5 /* macros */ +#define IS_SET(flag) ((win.mode & (flag)) != 0) #define TRUERED(x) (((x) & 0xff0000) >> 8) #define TRUEGREEN(x) (((x) & 0xff00)) #define TRUEBLUE(x) (((x) & 0xff) << 8) @@ -128,7 +129,6 @@ static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int) static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int); static void xdrawglyph(Glyph, int, int); static void xclear(int, int, int, int); -static void xdrawcursor(void); static int xgeommasktogravity(int); static void xinit(void); static void cresize(int, int); @@ -197,11 +197,6 @@ static XWindow xw; static XSelection xsel; static TermWindow win; -enum window_state { - WIN_VISIBLE = 1, - WIN_FOCUSED = 2 -}; - /* Font Ring Cache */ enum { FRC_NORMAL, @@ -264,6 +259,12 @@ selpaste(const Arg *dummy) xw.win, CurrentTime); } +void +numlock(const Arg *dummy) +{ + win.mode ^= MODE_NUMLOCK; +} + void zoom(const Arg *arg) { @@ -390,7 +391,7 @@ mousereport(XEvent *e) return; } - ttywrite(buf, len); + ttywrite(buf, len, 0); } void @@ -408,7 +409,7 @@ bpress(XEvent *e) for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { if (e->xbutton.button == ms->b && match(ms->mask, e->xbutton.state)) { - ttysend(ms->s, strlen(ms->s)); + ttywrite(ms->s, strlen(ms->s), 1); return; } } @@ -520,10 +521,10 @@ selnotify(XEvent *e) } if (IS_SET(MODE_BRCKTPASTE) && ofs == 0) - ttywrite("\033[200~", 6); - ttysend((char *)data, nitems * format / 8); + ttywrite("\033[200~", 6, 0); + ttywrite((char *)data, nitems * format / 8, 1); if (IS_SET(MODE_BRCKTPASTE) && rem == 0) - ttywrite("\033[201~", 6); + ttywrite("\033[201~", 6, 0); XFree(data); /* number of 32-bit chunks returned */ ofs += nitems * format / 32; @@ -1091,6 +1092,7 @@ xinit(void) XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32, PropModeReplace, (uchar *)&thispid, 1); + win.mode = MODE_NUMLOCK; resettitle(); XMapWindow(xw.dpy, xw.win); xhints(); @@ -1320,14 +1322,13 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i fg = &revfg; } - if (base.mode & ATTR_REVERSE) { temp = fg; fg = bg; bg = temp; } - if (base.mode & ATTR_BLINK && term.mode & MODE_BLINK) + if (base.mode & ATTR_BLINK && win.mode & MODE_BLINK) fg = bg; if (base.mode & ATTR_INVISIBLE) @@ -1386,41 +1387,26 @@ xdrawglyph(Glyph g, int x, int y) } void -xdrawcursor(void) +xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) { - static int oldx = 0, oldy = 0; - int curx; - Glyph g = {' ', ATTR_NULL, defaultbg, defaultcs}, og; Color drawcol; - LIMIT(oldx, 0, term.col-1); - LIMIT(oldy, 0, term.row-1); - - curx = term.c.x; - - /* adjust position if in dummy */ - if (term.line[oldy][oldx].mode & ATTR_WDUMMY) - oldx--; - if (term.line[term.c.y][curx].mode & ATTR_WDUMMY) - curx--; - /* remove the old cursor */ - og = term.line[oldy][oldx]; - if (selected(oldx, oldy)) + if (selected(ox, oy)) og.mode ^= ATTR_REVERSE; - xdrawglyph(og, oldx, oldy); - - g.u = term.line[term.c.y][term.c.x].u; - g.mode |= term.line[term.c.y][term.c.x].mode & - (ATTR_BOLD | ATTR_ITALIC | ATTR_UNDERLINE | ATTR_STRUCK); + xdrawglyph(og, ox, oy); /* * Select the right color for the right mode. */ + g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE; + g.fg = defaultbg; + g.bg = defaultcs; + if (IS_SET(MODE_REVERSE)) { g.mode |= ATTR_REVERSE; g.bg = defaultfg; - if (selected(term.c.x, term.c.y)) { + if (selected(cx, cy)) { drawcol = dc.col[defaultcs]; g.fg = defaultrcs; } else { @@ -1428,7 +1414,7 @@ xdrawcursor(void) g.fg = defaultcs; } } else { - if (selected(term.c.x, term.c.y)) { + if (selected(cx, cy)) { drawcol = dc.col[defaultrcs]; g.fg = defaultfg; g.bg = defaultrcs; @@ -1441,51 +1427,49 @@ xdrawcursor(void) return; /* draw the new one */ - if (win.state & WIN_FOCUSED) { + if (IS_SET(MODE_FOCUSED)) { switch (win.cursor) { case 7: /* st extension: snowman */ utf8decode("☃", &g.u, UTF_SIZ); case 0: /* Blinking Block */ case 1: /* Blinking Block (Default) */ case 2: /* Steady Block */ - g.mode |= term.line[term.c.y][curx].mode & ATTR_WIDE; - xdrawglyph(g, term.c.x, term.c.y); + xdrawglyph(g, cx, cy); break; case 3: /* Blinking Underline */ case 4: /* Steady Underline */ XftDrawRect(xw.draw, &drawcol, - borderpx + curx * win.cw, - borderpx + (term.c.y + 1) * win.ch - \ + borderpx + cx * win.cw, + borderpx + (cy + 1) * win.ch - \ cursorthickness, win.cw, cursorthickness); break; case 5: /* Blinking bar */ case 6: /* Steady bar */ XftDrawRect(xw.draw, &drawcol, - borderpx + curx * win.cw, - borderpx + term.c.y * win.ch, + borderpx + cx * win.cw, + borderpx + cy * win.ch, cursorthickness, win.ch); break; } } else { XftDrawRect(xw.draw, &drawcol, - borderpx + curx * win.cw, - borderpx + term.c.y * win.ch, + borderpx + cx * win.cw, + borderpx + cy * win.ch, win.cw - 1, 1); XftDrawRect(xw.draw, &drawcol, - borderpx + curx * win.cw, - borderpx + term.c.y * win.ch, + borderpx + cx * win.cw, + borderpx + cy * win.ch, 1, win.ch - 1); XftDrawRect(xw.draw, &drawcol, - borderpx + (curx + 1) * win.cw - 1, - borderpx + term.c.y * win.ch, + borderpx + (cx + 1) * win.cw - 1, + borderpx + cy * win.ch, 1, win.ch - 1); XftDrawRect(xw.draw, &drawcol, - borderpx + curx * win.cw, - borderpx + (term.c.y + 1) * win.ch - 1, + borderpx + cx * win.cw, + borderpx + (cy + 1) * win.ch - 1, win.cw, 1); } - oldx = curx, oldy = term.c.y; } void @@ -1510,59 +1494,51 @@ xsettitle(char *p) XFree(prop.value); } -void -draw(void) +int +xstartdraw(void) { - drawregion(0, 0, term.col, term.row); - XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, - win.h, 0, 0); - XSetForeground(xw.dpy, dc.gc, - dc.col[IS_SET(MODE_REVERSE)? - defaultfg : defaultbg].pixel); + return IS_SET(MODE_VISIBLE); } void -drawregion(int x1, int y1, int x2, int y2) +xdrawline(Line line, int x1, int y1, int x2) { - int i, x, y, ox, numspecs; + int i, x, ox, numspecs; Glyph base, new; - XftGlyphFontSpec *specs; + XftGlyphFontSpec *specs = xw.specbuf; - if (!(win.state & WIN_VISIBLE)) - return; - - for (y = y1; y < y2; y++) { - if (!term.dirty[y]) + numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1); + i = ox = 0; + for (x = x1; x < x2 && i < numspecs; x++) { + new = line[x]; + if (new.mode == ATTR_WDUMMY) continue; - - term.dirty[y] = 0; - - specs = xw.specbuf; - numspecs = xmakeglyphfontspecs(specs, &term.line[y][x1], x2 - x1, x1, y); - - i = ox = 0; - for (x = x1; x < x2 && i < numspecs; x++) { - new = term.line[y][x]; - if (new.mode == ATTR_WDUMMY) - continue; - if (selected(x, y)) - new.mode ^= ATTR_REVERSE; - if (i > 0 && ATTRCMP(base, new)) { - xdrawglyphfontspecs(specs, base, i, ox, y); - specs += i; - numspecs -= i; - i = 0; - } - if (i == 0) { - ox = x; - base = new; - } - i++; + if (selected(x, y1)) + new.mode ^= ATTR_REVERSE; + if (i > 0 && ATTRCMP(base, new)) { + xdrawglyphfontspecs(specs, base, i, ox, y1); + specs += i; + numspecs -= i; + i = 0; } - if (i > 0) - xdrawglyphfontspecs(specs, base, i, ox, y); + if (i == 0) { + ox = x; + base = new; + } + i++; } - xdrawcursor(); + if (i > 0) + xdrawglyphfontspecs(specs, base, i, ox, y1); +} + +void +xfinishdraw(void) +{ + XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, + win.h, 0, 0); + XSetForeground(xw.dpy, dc.gc, + dc.col[IS_SET(MODE_REVERSE)? + defaultfg : defaultbg].pixel); } void @@ -1576,13 +1552,13 @@ visibility(XEvent *ev) { XVisibilityEvent *e = &ev->xvisibility; - MODBIT(win.state, e->state != VisibilityFullyObscured, WIN_VISIBLE); + MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE); } void unmap(XEvent *ev) { - win.state &= ~WIN_VISIBLE; + win.mode &= ~MODE_VISIBLE; } void @@ -1592,6 +1568,15 @@ xsetpointermotion(int set) XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); } +void +xsetmode(int set, unsigned int flags) +{ + int mode = win.mode; + MODBIT(win.mode, set, flags); + if ((win.mode & MODE_REVERSE) != (mode & MODE_REVERSE)) + redraw(); +} + int xsetcursor(int cursor) { @@ -1615,7 +1600,7 @@ xseturgency(int add) void xbell(void) { - if (!(win.state & WIN_FOCUSED)) + if (!(IS_SET(MODE_FOCUSED))) xseturgency(1); if (bellvolume) XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); @@ -1631,15 +1616,15 @@ focus(XEvent *ev) if (ev->type == FocusIn) { XSetICFocus(xw.xic); - win.state |= WIN_FOCUSED; + win.mode |= MODE_FOCUSED; xseturgency(0); if (IS_SET(MODE_FOCUS)) - ttywrite("\033[I", 3); + ttywrite("\033[I", 3, 0); } else { XUnsetICFocus(xw.xic); - win.state &= ~WIN_FOCUSED; + win.mode &= ~MODE_FOCUSED; if (IS_SET(MODE_FOCUS)) - ttywrite("\033[O", 3); + ttywrite("\033[O", 3, 0); } } @@ -1674,15 +1659,12 @@ kmap(KeySym k, uint state) if (IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0) continue; - if (term.numlock && kp->appkey == 2) + if (IS_SET(MODE_NUMLOCK) && kp->appkey == 2) continue; if (IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0) continue; - if (IS_SET(MODE_CRLF) ? kp->crlf < 0 : kp->crlf > 0) - continue; - return kp->s; } @@ -1714,7 +1696,7 @@ kpress(XEvent *ev) /* 2. custom keys from config.h */ if ((customkey = kmap(ksym, e->state))) { - ttysend(customkey, strlen(customkey)); + ttywrite(customkey, strlen(customkey), 1); return; } @@ -1733,7 +1715,7 @@ kpress(XEvent *ev) len = 2; } } - ttysend(buf, len); + ttywrite(buf, len, 1); } @@ -1746,10 +1728,10 @@ cmessage(XEvent *e) */ if (e->xclient.message_type == xw.xembed && e->xclient.format == 32) { if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) { - win.state |= WIN_FOCUSED; + win.mode |= MODE_FOCUSED; xseturgency(0); } else if (e->xclient.data.l[1] == XEMBED_FOCUS_OUT) { - win.state &= ~WIN_FOCUSED; + win.mode &= ~MODE_FOCUSED; } } else if (e->xclient.data.l[0] == xw.wmdeletewin) { /* Send SIGHUP to shell */ @@ -1814,7 +1796,7 @@ run(void) if (blinktimeout) { blinkset = tattrset(ATTR_BLINK); if (!blinkset) - MODBIT(term.mode, 0, MODE_BLINK); + MODBIT(win.mode, 0, MODE_BLINK); } } @@ -1829,7 +1811,7 @@ run(void) dodraw = 0; if (blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) { tsetdirtattr(ATTR_BLINK); - term.mode ^= MODE_BLINK; + win.mode ^= MODE_BLINK; lastblink = now; dodraw = 1; }