commit 2243c8b2f366f8b67c3ebc724f51b25d854e6830
parent 551494f58cedcee804921822e6cec10498119410
Author: robert <robertrussell.72001@gmail.com>
Date: Mon, 7 Jun 2021 14:55:18 -0700
Fix bugs from reorganization
Diffstat:
| M | config.def.c | | | 46 | +++++++++++++++++++++++++--------------------- |
| M | config.def.h | | | 12 | +++++++++--- |
| M | st.c | | | 1 | + |
| M | util.c | | | 2 | ++ |
| M | util.h | | | 21 | +++++++++++---------- |
| M | win.h | | | 7 | +++++-- |
| M | x.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);
}