X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=x.c;h=5989947e47833ee89400313febb139401df56045;hb=2c55edb305e15194a11796a865015e84bfefecfe;hp=76f167f06c6282761ab8f41d6a864c5b7d7141e0;hpb=f345ce16ce1606bf5017022f79be1c392502020b;p=st.git diff --git a/x.c b/x.c index 76f167f..5989947 100644 --- a/x.c +++ b/x.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -20,6 +21,7 @@ char *argv0; #include "arg.h" #include "st.h" #include "win.h" +#include "normalMode.h" /* types used in config.h */ typedef struct { @@ -73,6 +75,7 @@ static void zoom(const Arg *); static void zoomabs(const Arg *); static void zoomreset(const Arg *); static void ttysend(const Arg *); +static void plumber(const Arg *); /* config.h for applying patches and the configuration. */ #include "config.h" @@ -195,11 +198,13 @@ static void selnotify(XEvent *); static void selclear_(XEvent *); static void selrequest(XEvent *); static void setsel(char *, Time); +static void plumb(char *sel); static void mousesel(XEvent *, int); static void mousereport(XEvent *); static char *kmap(KeySym, uint); static int match(uint, uint); + static void run(void); static void usage(void); @@ -230,6 +235,7 @@ static void (*handler[LASTEvent])(XEvent *) = { }; /* Globals */ +static int plumbsel; static DC dc; static XWindow xw; static XSelection xsel; @@ -267,6 +273,7 @@ static char *opt_name = NULL; static char *opt_title = NULL; static int oldbutton = 3; /* button event on startup: 3 = release */ +static int cursorblinks = 0; void clipcopy(const Arg *dummy) @@ -275,6 +282,7 @@ clipcopy(const Arg *dummy) free(xsel.clipboard); xsel.clipboard = NULL; + xsetsel(getsel()); if (xsel.primary != NULL) { xsel.clipboard = xstrdup(xsel.primary); @@ -342,6 +350,12 @@ ttysend(const Arg *arg) ttywrite(arg->s, strlen(arg->s), 1); } +void +plumber(const Arg *arg) +{ + plumb(xsel.primary); +} + int evcol(XEvent *e) { @@ -695,6 +709,37 @@ xsetsel(char *str) setsel(str, CurrentTime); } +void +plumbinit() +{ + for(plumbsel = 0; plumb_cmd[plumbsel]; plumbsel++); +} + +void +plumb(char *sel) { + if (sel == NULL) + return; + char cwd[PATH_MAX]; + pid_t child; + if (subprocwd(cwd) != 0) + return; + + plumb_cmd[plumbsel] = sel; + + switch(child = fork()) { + case -1: + return; + case 0: + if (chdir(cwd) != 0) + exit(1); + if (execvp(plumb_cmd[0], plumb_cmd) == -1) + exit(1); + exit(0); + default: + waitpid(child, NULL, 0); + } +} + void brelease(XEvent *e) { @@ -786,6 +831,8 @@ xloadcolor(int i, const char *name, Color *ncolor) return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor); } +void normalMode() { historyModeToggle((win.mode ^=MODE_NORMAL) & MODE_NORMAL); } + void xloadcols(void) { @@ -1237,8 +1284,10 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) { /* Fetch rune and mode for current glyph. */ - rune = glyphs[i].u; - mode = glyphs[i].mode; + Glyph g = glyphs[i]; + historyOverlay(x+i, y, &g); + rune = g.u; + mode = g.mode; /* Skip dummy wide-character spacing. */ if (mode == ATTR_WDUMMY) @@ -1538,16 +1587,19 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) /* draw the new one */ if (IS_SET(MODE_FOCUSED)) { switch (win.cursor) { - case 7: /* st extension */ - g.u = 0x2603; /* snowman (U+2603) */ + case 0: /* Blinking block */ + case 1: /* Blinking block (default) */ + if (IS_SET(MODE_BLINK)) + break; /* FALLTHROUGH */ - case 0: /* Blinking Block */ - case 1: /* Blinking Block (Default) */ - case 2: /* Steady Block */ + case 2: /* Steady block */ xdrawglyph(g, cx, cy); break; - case 3: /* Blinking Underline */ - case 4: /* Steady Underline */ + case 3: /* Blinking underline */ + if (IS_SET(MODE_BLINK)) + break; + /* FALLTHROUGH */ + case 4: /* Steady underline */ XftDrawRect(xw.draw, &drawcol, borderpx + cx * win.cw, borderpx + (cy + 1) * win.ch - \ @@ -1555,12 +1607,23 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) win.cw, cursorthickness); break; case 5: /* Blinking bar */ + if (IS_SET(MODE_BLINK)) + break; + /* FALLTHROUGH */ case 6: /* Steady bar */ XftDrawRect(xw.draw, &drawcol, borderpx + cx * win.cw, borderpx + cy * win.ch, cursorthickness, win.ch); break; + case 7: /* Blinking st cursor */ + if (IS_SET(MODE_BLINK)) + break; + /* FALLTHROUGH */ + case 8: /* Steady st cursor */ + g.u = stcursor; + xdrawglyph(g, cx, cy); + break; } } else { XftDrawRect(xw.draw, &drawcol, @@ -1607,6 +1670,8 @@ xsettitle(char *p) int xstartdraw(void) { + if (IS_SET(MODE_VISIBLE)) + XCopyArea(xw.dpy, xw.win, xw.buf, dc.gc, 0, 0, win.w, win.h, 0, 0); return IS_SET(MODE_VISIBLE); } @@ -1621,6 +1686,7 @@ xdrawline(Line line, int x1, int y1, int x2) i = ox = 0; for (x = x1; x < x2 && i < numspecs; x++) { new = line[x]; + historyOverlay(x, y1, &new); if (new.mode == ATTR_WDUMMY) continue; if (selected(x, y1)) @@ -1702,9 +1768,12 @@ xsetmode(int set, unsigned int flags) int xsetcursor(int cursor) { - if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */ + if (!BETWEEN(cursor, 0, 8)) /* 7-8: st extensions */ return 1; win.cursor = cursor; + cursorblinks = win.cursor == 0 || win.cursor == 1 || + win.cursor == 3 || win.cursor == 5 || + win.cursor == 7; return 0; } @@ -1812,6 +1881,11 @@ kpress(XEvent *ev) len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status); else len = XLookupString(e, buf, sizeof buf, &ksym, NULL); + if (IS_SET(MODE_NORMAL)) { + if (kpressHist(buf, len, match(ControlMask, e->state), &ksym) + == finished) normalMode(); + return; + } /* 1. shortcuts */ for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { if (ksym == bp->keysym && match(bp->mod, e->state)) { @@ -1948,6 +2022,10 @@ run(void) if (FD_ISSET(ttyfd, &rfd) || xev) { if (!drawing) { trigger = now; + if (IS_SET(MODE_BLINK)) { + win.mode ^= MODE_BLINK; + } + lastblink = now; drawing = 1; } timeout = (maxlatency - TIMEDIFF(now, trigger)) \ @@ -1958,7 +2036,7 @@ run(void) /* idle detected or maxlatency exhausted -> draw */ timeout = -1; - if (blinktimeout && tattrset(ATTR_BLINK)) { + if (blinktimeout && (cursorblinks || tattrset(ATTR_BLINK))) { timeout = blinktimeout - TIMEDIFF(now, lastblink); if (timeout <= 0) { if (-timeout > blinktimeout) /* start visible */ @@ -2047,7 +2125,7 @@ main(int argc, char *argv[]) { xw.l = xw.t = 0; xw.isfixed = False; - xsetcursor(cursorshape); + xsetcursor(cursorstyle); ARGBEGIN { case 'a': @@ -2094,6 +2172,7 @@ main(int argc, char *argv[]) } ARGEND; run: + plumbinit(); if (argc > 0) /* eat all remaining arguments */ opt_cmd = argv;