X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=x.c;h=76fb910c05acb0c4b5604eb27e22be1f801ff422;hb=33201ac65f74e45b4fa60822ba9a538c3cfa9b25;hp=7bfa1b75891edd6bc2d88f3cc4de92640186b67c;hpb=d84f3f4bd15e7d65fc0334cf7d62913c901bad00;p=st.git diff --git a/x.c b/x.c index 7bfa1b7..76fb910 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 */ @@ -94,6 +93,9 @@ typedef struct { typedef struct { Atom xtarget; + char *primary, *clipboard; + struct timespec tclick1; + struct timespec tclick2; } XSelection; /* Font structure */ @@ -154,7 +156,7 @@ static void selnotify(XEvent *); static void selclear_(XEvent *); static void selrequest(XEvent *); static void setsel(char *, Time); -static void getbuttoninfo(XEvent *); +static void mousesel(XEvent *, int); static void mousereport(XEvent *); static char *kmap(KeySym, uint); static int match(uint, uint); @@ -234,11 +236,11 @@ clipcopy(const Arg *dummy) { Atom clipboard; - if (sel.clipboard != NULL) - free(sel.clipboard); + if (xsel.clipboard != NULL) + free(xsel.clipboard); - if (sel.primary != NULL) { - sel.clipboard = xstrdup(sel.primary); + if (xsel.primary != NULL) { + xsel.clipboard = xstrdup(xsel.primary); clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime); } @@ -310,24 +312,20 @@ y2row(int y) } void -getbuttoninfo(XEvent *e) +mousesel(XEvent *e, int done) { - int type; + int type, seltype = SEL_REGULAR; uint state = e->xbutton.state & ~(Button1Mask | forceselmod); - sel.alt = IS_SET(MODE_ALTSCREEN); - - sel.oe.x = x2col(e->xbutton.x); - sel.oe.y = y2row(e->xbutton.y); - selnormalize(); - - sel.type = SEL_REGULAR; for (type = 1; type < LEN(selmasks); ++type) { if (match(selmasks[type], state)) { - sel.type = type; + seltype = type; break; } } + selextend(x2col(e->xbutton.x), y2row(e->xbutton.y), seltype, done); + if (done) + setsel(getsel(), e->xbutton.time); } void @@ -391,7 +389,7 @@ mousereport(XEvent *e) return; } - ttywrite(buf, len); + ttywrite(buf, len, 0); } void @@ -399,6 +397,7 @@ bpress(XEvent *e) { struct timespec now; MouseShortcut *ms; + int snap; if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { mousereport(e); @@ -408,39 +407,28 @@ 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; } } if (e->xbutton.button == Button1) { - clock_gettime(CLOCK_MONOTONIC, &now); - - /* Clear previous selection, logically and visually. */ - selclear_(NULL); - sel.mode = SEL_EMPTY; - sel.type = SEL_REGULAR; - sel.oe.x = sel.ob.x = x2col(e->xbutton.x); - sel.oe.y = sel.ob.y = y2row(e->xbutton.y); - /* * If the user clicks below predefined timeouts specific * snapping behaviour is exposed. */ - if (TIMEDIFF(now, sel.tclick2) <= tripleclicktimeout) { - sel.snap = SNAP_LINE; - } else if (TIMEDIFF(now, sel.tclick1) <= doubleclicktimeout) { - sel.snap = SNAP_WORD; + clock_gettime(CLOCK_MONOTONIC, &now); + if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) { + snap = SNAP_LINE; + } else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) { + snap = SNAP_WORD; } else { - sel.snap = 0; + snap = 0; } - selnormalize(); + xsel.tclick2 = xsel.tclick1; + xsel.tclick1 = now; - if (sel.snap != 0) - sel.mode = SEL_READY; - tsetdirt(sel.nb.y, sel.ne.y); - sel.tclick2 = sel.tclick1; - sel.tclick1 = now; + selstart(x2col(e->xbutton.x), y2row(e->xbutton.y), snap); } } @@ -531,10 +519,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; @@ -594,9 +582,9 @@ selrequest(XEvent *e) */ clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); if (xsre->selection == XA_PRIMARY) { - seltext = sel.primary; + seltext = xsel.primary; } else if (xsre->selection == clipboard) { - seltext = sel.clipboard; + seltext = xsel.clipboard; } else { fprintf(stderr, "Unhandled clipboard selection 0x%lx\n", @@ -620,8 +608,8 @@ selrequest(XEvent *e) void setsel(char *str, Time t) { - free(sel.primary); - sel.primary = str; + free(xsel.primary); + xsel.primary = str; XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) @@ -642,41 +630,21 @@ brelease(XEvent *e) return; } - if (e->xbutton.button == Button2) { + if (e->xbutton.button == Button2) selpaste(NULL); - } else if (e->xbutton.button == Button1) { - if (sel.mode == SEL_READY) { - getbuttoninfo(e); - setsel(getsel(), e->xbutton.time); - } else - selclear_(NULL); - sel.mode = SEL_IDLE; - tsetdirt(sel.nb.y, sel.ne.y); - } + else if (e->xbutton.button == Button1) + mousesel(e, 1); } void bmotion(XEvent *e) { - int oldey, oldex, oldsby, oldsey; - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { mousereport(e); return; } - if (!sel.mode) - return; - - sel.mode = SEL_READY; - oldey = sel.oe.y; - oldex = sel.oe.x; - oldsby = sel.nb.y; - oldsey = sel.ne.y; - getbuttoninfo(e); - - if (oldey != sel.oe.y || oldex != sel.oe.x) - tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey)); + mousesel(e, 0); } void @@ -1127,6 +1095,10 @@ xinit(void) xhints(); XSync(xw.dpy, False); + clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1); + clock_gettime(CLOCK_MONOTONIC, &xsel.tclick2); + xsel.primary = NULL; + xsel.clipboard = NULL; xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0); if (xsel.xtarget == None) xsel.xtarget = XA_STRING; @@ -1418,7 +1390,6 @@ xdrawcursor(void) static int oldx = 0, oldy = 0; int curx; 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); @@ -1434,7 +1405,7 @@ xdrawcursor(void) /* remove the old cursor */ og = term.line[oldy][oldx]; - if (ena_sel && selected(oldx, oldy)) + if (selected(oldx, oldy)) og.mode ^= ATTR_REVERSE; xdrawglyph(og, oldx, oldy); @@ -1448,7 +1419,7 @@ xdrawcursor(void) if (IS_SET(MODE_REVERSE)) { g.mode |= ATTR_REVERSE; g.bg = defaultfg; - if (ena_sel && selected(term.c.x, term.c.y)) { + if (selected(term.c.x, term.c.y)) { drawcol = dc.col[defaultcs]; g.fg = defaultrcs; } else { @@ -1456,7 +1427,7 @@ xdrawcursor(void) g.fg = defaultcs; } } else { - if (ena_sel && selected(term.c.x, term.c.y)) { + if (selected(term.c.x, term.c.y)) { drawcol = dc.col[defaultrcs]; g.fg = defaultfg; g.bg = defaultrcs; @@ -1555,7 +1526,6 @@ drawregion(int x1, int y1, int x2, int y2) int i, x, y, ox, numspecs; Glyph base, new; XftGlyphFontSpec *specs; - int ena_sel = sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN); if (!(win.state & WIN_VISIBLE)) return; @@ -1574,7 +1544,7 @@ drawregion(int x1, int y1, int x2, int y2) new = term.line[y][x]; if (new.mode == ATTR_WDUMMY) continue; - if (ena_sel && selected(x, y)) + if (selected(x, y)) new.mode ^= ATTR_REVERSE; if (i > 0 && ATTRCMP(base, new)) { xdrawglyphfontspecs(specs, base, i, ox, y); @@ -1663,12 +1633,12 @@ focus(XEvent *ev) win.state |= WIN_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; if (IS_SET(MODE_FOCUS)) - ttywrite("\033[O", 3); + ttywrite("\033[O", 3, 0); } } @@ -1709,9 +1679,6 @@ kmap(KeySym k, uint state) 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; } @@ -1743,7 +1710,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; } @@ -1762,7 +1729,7 @@ kpress(XEvent *ev) len = 2; } } - ttysend(buf, len); + ttywrite(buf, len, 1); }