X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=x.c;h=96944ee9963dda568dc9d391c1bb848648525578;hb=88d8293fb4ba150a5f19d58d133b5db93d9dcfa5;hp=76fb910c05acb0c4b5604eb27e22be1f801ff422;hpb=33201ac65f74e45b4fa60822ba9a538c3cfa9b25;p=st.git diff --git a/x.c b/x.c index 76fb910..96944ee 100644 --- a/x.c +++ b/x.c @@ -51,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 *); @@ -64,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) @@ -127,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); @@ -196,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, @@ -263,6 +259,12 @@ selpaste(const Arg *dummy) xw.win, CurrentTime); } +void +numlock(const Arg *dummy) +{ + win.mode ^= MODE_NUMLOCK; +} + void zoom(const Arg *arg) { @@ -1090,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(); @@ -1319,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) @@ -1440,7 +1442,7 @@ 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); @@ -1509,59 +1511,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) { + ox = x; + base = new; } - if (i > 0) - xdrawglyphfontspecs(specs, base, i, ox, y); + 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 @@ -1575,13 +1569,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 @@ -1591,6 +1585,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) { @@ -1614,7 +1617,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); @@ -1630,13 +1633,13 @@ 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, 0); } else { XUnsetICFocus(xw.xic); - win.state &= ~WIN_FOCUSED; + win.mode &= ~MODE_FOCUSED; if (IS_SET(MODE_FOCUS)) ttywrite("\033[O", 3, 0); } @@ -1673,7 +1676,7 @@ 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) @@ -1742,10 +1745,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 */ @@ -1810,7 +1813,7 @@ run(void) if (blinktimeout) { blinkset = tattrset(ATTR_BLINK); if (!blinkset) - MODBIT(term.mode, 0, MODE_BLINK); + MODBIT(win.mode, 0, MODE_BLINK); } } @@ -1825,7 +1828,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; }