st

st fork
git clone git://git.rr3.xyz/st
Log | Files | Refs | README | LICENSE

commit 2243c8b2f366f8b67c3ebc724f51b25d854e6830
parent 551494f58cedcee804921822e6cec10498119410
Author: robert <robertrussell.72001@gmail.com>
Date:   Mon,  7 Jun 2021 14:55:18 -0700

Fix bugs from reorganization

Diffstat:
Mconfig.def.c | 46+++++++++++++++++++++++++---------------------
Mconfig.def.h | 12+++++++++---
Mst.c | 1+
Mutil.c | 2++
Mutil.h | 21+++++++++++----------
Mwin.h | 7+++++--
Mx.c | 151+++++++++++++++++++++++++++++--------------------------------------------------
7 files changed, 108 insertions(+), 132 deletions(-)

diff --git a/config.def.c b/config.def.c @@ -54,7 +54,7 @@ uint tripleclicktimeout = 600; int allowaltscreen = 1; -/* allow certain non-interactive (insecure) window operations such as: +/* allow certain non-interactive (insecure) window operations, such as setting the clipboard text */ int allowwindowops = 0; @@ -73,7 +73,7 @@ uint blinktimeout = 800; uint cursorthickness = 2; /* bell volume. It must be a value between -100 and 100. - * Use 0 to disabling it. */ + * Use 0 to disable it. */ int bellvolume = 0; char *termname = "st-256color"; @@ -114,12 +114,11 @@ const char *colorname[] = { /* more colors can be added after 255 to use with DefaultXX */ "#cccccc", "#555555", + 0, }; -/* - * Default colors (colorname index) - * foreground, background, cursor, reverse cursor - */ +/* Default colors (colorname index) + * foreground, background, cursor, reverse cursor */ uint defaultfg = 7; uint defaultbg = 0; uint defaultcs = 256; @@ -144,11 +143,6 @@ uint mousebg = 0; * doesn't match the ones requested. */ uint defaultattr = 11; -/* Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set). - * Note that if you want to use ShiftMask with selmasks, set this to an other - * modifier, set to 0 to not use it. */ -uint forcemousemod = ShiftMask; // TODO - #define R RELS #define S SHFT #define C CTRL @@ -167,6 +161,7 @@ Btn btns[] = { { Button4, 0, R, SENDSTR("\031") }, { Button5, S, KEXCL(S)|R, SENDSTR("\033[6;2~") }, { Button5, 0, R, SENDSTR("\005") }, + { 0 }, }; /* TODO: add RELS to clr */ @@ -299,20 +294,29 @@ Key keys[] = { { XK_F19, 0, 0, SENDTILDE(33) }, { XK_F20, 0, 0, SENDTILDE(34) }, /* libtermkey only recognizes up to F20. */ + + { 0 }, }; -/* - * Selection types' masks. - * Use the same masks as usual. - * Button1Mask is always unset, to make masks match between ButtonPress. - * ButtonRelease and MotionNotify. - * If no match is found, regular selection is used. - */ -// TODO: fix -uint selmasks[] = { - [SEL_RECTANGULAR] = Mod1Mask, +SelType seltypes[] = { + { SEL_RECTANGULAR, A, KEXCL(A) }, + /* If no match is found, regular selection is used. */ + { 0 }, }; +uint +confstate(uint xstate, int rels) +{ + uint winmode; + + winmode = xgetmode(); + return (winmode&MODE_APPCURSOR ? CURS : 0) + | (winmode&MODE_APPKEYPAD ? KPAD : 0) + | (winmode&MODE_NUMLOCK ? NMLK : 0) + | (rels ? RELS : 0) + | (xstate << MODOFFS); +} + void clipcopy(uint state, Arg arg) { xclipcopy(); } diff --git a/config.def.h b/config.def.h @@ -6,7 +6,7 @@ #define NMLK (1<<2) /* Num lock */ #define RELS (1<<3) /* Key/buttom release */ /* To allow checking more boolean properties when matching key/button events, - * define them here and modify MODOFFS and TODO. */ + * define them here and modify MODOFFS and confstate. */ #define MODOFFS 4 #define SHFT (ShiftMask<<MODOFFS) #define CTRL (ControlMask<<MODOFFS) @@ -60,6 +60,11 @@ typedef struct { Arg arg; } Key; +typedef struct { + int type; + uint set, clr; +} SelType; + extern char *font; extern int borderpx; extern float cwscale; @@ -93,8 +98,9 @@ extern uint mouseshape; extern uint mousefg; extern uint mousebg; extern uint defaultattr; -extern uint forcemousemod; extern uint ignoremod; extern Btn btns[]; extern Key keys[]; -extern uint selmasks[]; +extern SelType seltypes[]; + +uint confstate(uint, int); diff --git a/st.c b/st.c @@ -17,6 +17,7 @@ #include <termios.h> #include <unistd.h> #include <wchar.h> +#include <X11/Xlib.h> /* TODO gross? */ #include "util.h" #include "config.h" diff --git a/util.c b/util.c @@ -6,6 +6,8 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <wchar.h> +#include <X11/Xlib.h> #include "util.h" #include "config.h" diff --git a/util.h b/util.h @@ -4,16 +4,17 @@ #define UTF_INVALID 0xFFFD #define UTF_SIZ 4 -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a) / sizeof(a)[0]) -#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) -#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d)) -#define DEFAULT(a, b) (a) = (a) ? (a) : (b) -#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) -#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \ - (t1.tv_nsec-t2.tv_nsec)/1E6) -#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit))) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) < (b) ? (b) : (a)) +#define LEN(a) (sizeof(a) / sizeof(a)[0]) +#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) +#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d)) +#define DEFAULT(a, b) (a) = (a) ? (a) : (b) +#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) +#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \ + (t1.tv_nsec-t2.tv_nsec)/1E6) +#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit))) +#define MATCH(state, set, clr) (((set & ~state) | (clr & state)) == 0) typedef unsigned char uchar; typedef unsigned short ushort; diff --git a/win.h b/win.h @@ -1,6 +1,10 @@ /* See LICENSE for license details. */ /* Requires: util.h, st.h */ +#define xgetmode() xmode(0,0) +#define xsetmode(set,flags) ((set) ? xmode((flags),0) : xmode(0,(flags))) +#define xtogmode(flags) xmode((flags),(flags)) + enum win_mode { MODE_VISIBLE = 1 << 0, MODE_FOCUSED = 1 << 1, @@ -40,8 +44,7 @@ int xsetcolorname(int, const char *); void xseticontitle(char *); void xsettitle(char *); int xsetcursor(int); -void xsetmode(int, uint); -void xtogmode(uint); +uint xmode(uint, uint); void xsetpointermotion(int); void xsetsel(char *); int xstartdraw(void); diff --git a/x.c b/x.c @@ -44,7 +44,7 @@ typedef struct { int w, h; /* window width and height */ int ch; /* char height */ int cw; /* char width */ - int mode; /* window state/mode flags */ + uint mode; /* window state/mode flags */ int cursor; /* cursor style */ } TermWindow; @@ -132,7 +132,6 @@ static void kpress(XEvent *); static void cmessage(XEvent *); static void resize(XEvent *); static void focus(XEvent *); -static uint buttonmask(uint); static int mouseaction(XEvent *, uint); static void brelease(XEvent *); static void bpress(XEvent *); @@ -294,16 +293,20 @@ evrow(XEvent *e) void mousesel(XEvent *e, int done) { - int type, seltype = SEL_REGULAR; - uint state = e->xbutton.state & ~(Button1Mask | forcemousemod); + int type; + uint state; + SelType *st; - for (type = 1; type < LEN(selmasks); ++type) { - if (match(selmasks[type], state)) { - seltype = type; + type = SEL_REGULAR; + state = confstate(e->xbutton.state, 0); + for (st = seltypes; st->type; st++) { + if (MATCH(state, st->set, st->clr)) { + type = st->type; break; } } - selextend(evcol(e), evrow(e), seltype, done); + + selextend(evcol(e), evrow(e), type, done); if (done) setsel(getsel(), e->xbutton.time); } @@ -373,31 +376,16 @@ mousereport(XEvent *e) ttywrite(buf, len, 0); } -uint -buttonmask(uint button) -{ - return button == Button1 ? Button1Mask - : button == Button2 ? Button2Mask - : button == Button3 ? Button3Mask - : button == Button4 ? Button4Mask - : button == Button5 ? Button5Mask - : 0; -} - int mouseaction(XEvent *e, uint release) { - MouseShortcut *ms; - - /* ignore Button<N>mask for Button<N> - it's set on release */ - uint state = e->xbutton.state & ~buttonmask(e->xbutton.button); + uint state; + Btn *b; - for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { - if (ms->release == release && - ms->button == e->xbutton.button && - (match(ms->mod, state) || /* exact or forced */ - match(ms->mod, state & ~forcemousemod))) { - ms->func(&(ms->arg)); + state = confstate(e->xbutton.state, release); + for (b = btns; b->btn; b++) { + if (b->btn == e->xbutton.button && MATCH(state, b->set, b->clr)) { + b->fn(state, b->arg); return 1; } } @@ -411,7 +399,7 @@ bpress(XEvent *e) struct timespec now; int snap; - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { + if (IS_SET(MODE_MOUSE)) { mousereport(e); return; } @@ -627,7 +615,7 @@ xsetsel(char *str) void brelease(XEvent *e) { - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { + if (IS_SET(MODE_MOUSE)) { mousereport(e); return; } @@ -641,7 +629,7 @@ brelease(XEvent *e) void bmotion(XEvent *e) { - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { + if (IS_SET(MODE_MOUSE)) { mousereport(e); return; } @@ -721,12 +709,15 @@ xloadcols(void) int i; static int loaded; Color *cp; + const char **c; if (loaded) { for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp) XftColorFree(xw.dpy, xw.vis, xw.cmap, cp); } else { - dc.collen = MAX(LEN(colorname), 256); + dc.collen = 256; + for (c = &colorname[256]; *c; c++) + dc.collen++; dc.col = xmalloc(dc.collen * sizeof(Color)); } @@ -1635,23 +1626,20 @@ xsetpointermotion(int set) XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); } -/* TODO combine xsetmode and xtogmode into one general function? */ -void -xsetmode(int set, uint flags) -{ - int mode = win.mode; - MODBIT(win.mode, set, flags); - if ((win.mode & MODE_REVERSE) != (mode & MODE_REVERSE)) - redraw(); -} - -void -xtogmode(uint flags) +/* Modify the window mode and return the new mode. + * set clr + * 0 0 unchanged + * 0 1 clear + * 1 0 set + * 1 1 toggle */ +uint +xmode(uint set, uint clr) { - int mode = win.mode; - win.mode ^= flags; - if ((win.mode & MODE_REVERSE) != (mode & MODE_REVERSE)) + int orig = win.mode; + win.mode = (~win.mode & set) | (win.mode & ~clr); + if ((win.mode & MODE_REVERSE) != (orig & MODE_REVERSE)) redraw(); + return win.mode; } int @@ -1706,19 +1694,6 @@ focus(XEvent *ev) } } -int -match(uint mask, uint state) -{ - uint ignoremod = Mod2Mask|XK_SWITCH_MOD; - return mask == XK_ANY_MOD || mask == (state & ~ignoremod); -} - -int -scmatch(uint state, uint set, uint clr) -{ - return ((set & ~state) | (clr & state)) == 0; -} - void kpress(XEvent *ev) { @@ -1728,7 +1703,6 @@ kpress(XEvent *ev) int len; Rune c; Status status; - Shortcut *bp; Key *k; uint state; @@ -1740,63 +1714,48 @@ kpress(XEvent *ev) else len = XLookupString(e, buf, sizeof buf, &ksym, NULL); - /* 1. shortcuts */ - for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { - if (ksym == bp->keysym && match(bp->mod, e->state)) { - bp->func(&(bp->arg)); - return; - } - } + /* TODO: pull all this out into keyaction for symmetry with mouseaction */ - /* 2. custom keys from config.h */ - state = (IS_SET(MODE_APPCURSOR) ? CURS : 0) - | (IS_SET(MODE_APPKEYPAD) ? KPAD : 0) - | (IS_SET(MODE_NUMLOCK) ? NMLK : 0) - | (e->state&ShiftMask ? S : 0) - | (e->state&Mod1Mask ? A : 0) - | (e->state&ControlMask ? C : 0); - for (k = keys; k < keys + LEN(keys); k++) { - if (k->sym == ksym && scmatch(state, k->set, k->clr)) { - len = k->enc(buf, sizeof buf, ksym, state, k->arg); - ttywrite(buf, len, 1); + state = confstate(e->state, 0); + + /* 1. custom handling from config */ + for (k = keys; k->sym; k++) { + if (k->sym == ksym && MATCH(state, k->set, k->clr)) { + k->fn(state, k->arg); return; } } - /* 3. latin 1 */ + /* 2. latin 1 */ if (0x20 <= ksym && ksym < 0x7f) { buf[0] = ksym; len = 1; - if ((state&C) > 0) { + if ((state&CTRL) > 0) { if ('a' <= ksym && ksym <= 'z') { buf[0] -= 0x60; } else { - len = kcsi(buf, sizeof buf, state, ksym, S, 'u'); - ttywrite(buf, len, 1); - return; + len = csienc(buf, sizeof buf, state, ksym, SHFT, 'u'); + goto write; } } - if ((state&A) > 0) { + if ((state&ALT) > 0) { buf[1] = buf[0]; buf[0] = '\033'; len = 2; } - ttywrite(buf, len, 1); - return; + goto write; } if (len == 0) return; - /* 4. modified UTF8-encoded unicode */ - if ((state&ALLM) > 0 && utf8decode(buf, &c, len) == len - && c != UTF_INVALID) { - len = kcsi(buf, sizeof buf, state, c, S, 'u'); - ttywrite(buf, len, 1); - return; - } + /* 3. modified UTF8-encoded unicode */ + if ((state&KMOD) > 0 && utf8decode(buf, &c, len) == len + && c != UTF_INVALID) + len = csienc(buf, sizeof buf, state, c, SHFT, 'u'); - /* 5. composed string from input method */ + /* 4. directly send composed string from input method */ +write: ttywrite(buf, len, 1); }