Split mode bits between Term and TermWindow

Moves the mode bits used by x.c from Term to TermWindow, absorbing
UI/input-related mode bits (visible/focused/numlock) along the way.

This is gradually reducing external references to Term.  Since
TermWindow is already internal to x.c, we add xsetmode() to allow st to
modify window bits in accordance with escape sequences.

IS_SET() is redefined accordingly (term.mode in st.c, win.mode in x.c).

Signed-off-by: Devin J. Pohly <djpohly@gmail.com>
This commit is contained in:
Devin J. Pohly 2018-02-23 14:16:52 -06:00
parent 33201ac65f
commit 05c66cb37d
4 changed files with 88 additions and 83 deletions

64
st.c
View File

@ -42,6 +42,7 @@
#define STR_ARG_SIZ ESC_ARG_SIZ #define STR_ARG_SIZ ESC_ARG_SIZ
/* macros */ /* macros */
#define IS_SET(flag) ((term.mode & (flag)) != 0)
#define NUMMAXLEN(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1) #define NUMMAXLEN(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1)
#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177') #define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177')
#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) #define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
@ -51,6 +52,17 @@
/* constants */ /* constants */
#define ISO14755CMD "dmenu -w \"$WINDOWID\" -p codepoint: </dev/null" #define ISO14755CMD "dmenu -w \"$WINDOWID\" -p codepoint: </dev/null"
enum term_mode {
MODE_WRAP = 1 << 0,
MODE_INSERT = 1 << 1,
MODE_ALTSCREEN = 1 << 2,
MODE_CRLF = 1 << 3,
MODE_ECHO = 1 << 4,
MODE_PRINT = 1 << 5,
MODE_UTF8 = 1 << 6,
MODE_SIXEL = 1 << 7,
};
enum cursor_movement { enum cursor_movement {
CURSOR_SAVE, CURSOR_SAVE,
CURSOR_LOAD CURSOR_LOAD
@ -977,8 +989,6 @@ tnew(int col, int row)
{ {
term = (Term){ .c = { .attr = { .fg = defaultfg, .bg = defaultbg } } }; term = (Term){ .c = { .attr = { .fg = defaultfg, .bg = defaultbg } } };
tresize(col, row); tresize(col, row);
term.numlock = 1;
treset(); treset();
} }
@ -1414,20 +1424,16 @@ tsetscroll(int t, int b)
void void
tsetmode(int priv, int set, int *args, int narg) tsetmode(int priv, int set, int *args, int narg)
{ {
int *lim, mode; int alt, *lim;
int alt;
for (lim = args + narg; args < lim; ++args) { for (lim = args + narg; args < lim; ++args) {
if (priv) { if (priv) {
switch (*args) { switch (*args) {
case 1: /* DECCKM -- Cursor key */ case 1: /* DECCKM -- Cursor key */
MODBIT(term.mode, set, MODE_APPCURSOR); xsetmode(set, MODE_APPCURSOR);
break; break;
case 5: /* DECSCNM -- Reverse video */ case 5: /* DECSCNM -- Reverse video */
mode = term.mode; xsetmode(set, MODE_REVERSE);
MODBIT(term.mode, set, MODE_REVERSE);
if (mode != term.mode)
redraw();
break; break;
case 6: /* DECOM -- Origin */ case 6: /* DECOM -- Origin */
MODBIT(term.c.state, set, CURSOR_ORIGIN); MODBIT(term.c.state, set, CURSOR_ORIGIN);
@ -1447,36 +1453,36 @@ tsetmode(int priv, int set, int *args, int narg)
case 12: /* att610 -- Start blinking cursor (IGNORED) */ case 12: /* att610 -- Start blinking cursor (IGNORED) */
break; break;
case 25: /* DECTCEM -- Text Cursor Enable Mode */ case 25: /* DECTCEM -- Text Cursor Enable Mode */
MODBIT(term.mode, !set, MODE_HIDE); xsetmode(!set, MODE_HIDE);
break; break;
case 9: /* X10 mouse compatibility mode */ case 9: /* X10 mouse compatibility mode */
xsetpointermotion(0); xsetpointermotion(0);
MODBIT(term.mode, 0, MODE_MOUSE); xsetmode(0, MODE_MOUSE);
MODBIT(term.mode, set, MODE_MOUSEX10); xsetmode(set, MODE_MOUSEX10);
break; break;
case 1000: /* 1000: report button press */ case 1000: /* 1000: report button press */
xsetpointermotion(0); xsetpointermotion(0);
MODBIT(term.mode, 0, MODE_MOUSE); xsetmode(0, MODE_MOUSE);
MODBIT(term.mode, set, MODE_MOUSEBTN); xsetmode(set, MODE_MOUSEBTN);
break; break;
case 1002: /* 1002: report motion on button press */ case 1002: /* 1002: report motion on button press */
xsetpointermotion(0); xsetpointermotion(0);
MODBIT(term.mode, 0, MODE_MOUSE); xsetmode(0, MODE_MOUSE);
MODBIT(term.mode, set, MODE_MOUSEMOTION); xsetmode(set, MODE_MOUSEMOTION);
break; break;
case 1003: /* 1003: enable all mouse motions */ case 1003: /* 1003: enable all mouse motions */
xsetpointermotion(set); xsetpointermotion(set);
MODBIT(term.mode, 0, MODE_MOUSE); xsetmode(0, MODE_MOUSE);
MODBIT(term.mode, set, MODE_MOUSEMANY); xsetmode(set, MODE_MOUSEMANY);
break; break;
case 1004: /* 1004: send focus events to tty */ case 1004: /* 1004: send focus events to tty */
MODBIT(term.mode, set, MODE_FOCUS); xsetmode(set, MODE_FOCUS);
break; break;
case 1006: /* 1006: extended reporting mode */ case 1006: /* 1006: extended reporting mode */
MODBIT(term.mode, set, MODE_MOUSESGR); xsetmode(set, MODE_MOUSESGR);
break; break;
case 1034: case 1034:
MODBIT(term.mode, set, MODE_8BIT); xsetmode(set, MODE_8BIT);
break; break;
case 1049: /* swap screen & set/restore cursor as xterm */ case 1049: /* swap screen & set/restore cursor as xterm */
if (!allowaltscreen) if (!allowaltscreen)
@ -1501,7 +1507,7 @@ tsetmode(int priv, int set, int *args, int narg)
tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD);
break; break;
case 2004: /* 2004: bracketed paste mode */ case 2004: /* 2004: bracketed paste mode */
MODBIT(term.mode, set, MODE_BRCKTPASTE); xsetmode(set, MODE_BRCKTPASTE);
break; break;
/* Not implemented mouse modes. See comments there. */ /* Not implemented mouse modes. See comments there. */
case 1001: /* mouse highlight mode; can hang the case 1001: /* mouse highlight mode; can hang the
@ -1522,8 +1528,8 @@ tsetmode(int priv, int set, int *args, int narg)
switch (*args) { switch (*args) {
case 0: /* Error (IGNORED) */ case 0: /* Error (IGNORED) */
break; break;
case 2: /* KAM -- keyboard action */ case 2:
MODBIT(term.mode, set, MODE_KBDLOCK); xsetmode(set, MODE_KBDLOCK);
break; break;
case 4: /* IRM -- Insertion-replacement */ case 4: /* IRM -- Insertion-replacement */
MODBIT(term.mode, set, MODE_INSERT); MODBIT(term.mode, set, MODE_INSERT);
@ -2230,10 +2236,10 @@ eschandle(uchar ascii)
xloadcols(); xloadcols();
break; break;
case '=': /* DECPAM -- Application keypad */ case '=': /* DECPAM -- Application keypad */
term.mode |= MODE_APPKEYPAD; xsetmode(1, MODE_APPKEYPAD);
break; break;
case '>': /* DECPNM -- Normal keypad */ case '>': /* DECPNM -- Normal keypad */
term.mode &= ~MODE_APPKEYPAD; xsetmode(0, MODE_APPKEYPAD);
break; break;
case '7': /* DECSC -- Save Cursor */ case '7': /* DECSC -- Save Cursor */
tcursor(CURSOR_SAVE); tcursor(CURSOR_SAVE);
@ -2526,9 +2532,3 @@ redraw(void)
tfulldirt(); tfulldirt();
draw(); draw();
} }
void
numlock(const Arg *dummy)
{
term.numlock ^= 1;
}

33
st.h
View File

@ -13,7 +13,6 @@
#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) #define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \ #define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \
(a).bg != (b).bg) (a).bg != (b).bg)
#define IS_SET(flag) ((term.mode & (flag)) != 0)
#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \ #define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \
(t1.tv_nsec-t2.tv_nsec)/1E6) (t1.tv_nsec-t2.tv_nsec)/1E6)
#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit))) #define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit)))
@ -37,34 +36,6 @@ enum glyph_attribute {
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT, ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
}; };
enum term_mode {
MODE_WRAP = 1 << 0,
MODE_INSERT = 1 << 1,
MODE_APPKEYPAD = 1 << 2,
MODE_ALTSCREEN = 1 << 3,
MODE_CRLF = 1 << 4,
MODE_MOUSEBTN = 1 << 5,
MODE_MOUSEMOTION = 1 << 6,
MODE_REVERSE = 1 << 7,
MODE_KBDLOCK = 1 << 8,
MODE_HIDE = 1 << 9,
MODE_ECHO = 1 << 10,
MODE_APPCURSOR = 1 << 11,
MODE_MOUSESGR = 1 << 12,
MODE_8BIT = 1 << 13,
MODE_BLINK = 1 << 14,
MODE_FBLINK = 1 << 15,
MODE_FOCUS = 1 << 16,
MODE_MOUSEX10 = 1 << 17,
MODE_MOUSEMANY = 1 << 18,
MODE_BRCKTPASTE = 1 << 19,
MODE_PRINT = 1 << 20,
MODE_UTF8 = 1 << 21,
MODE_SIXEL = 1 << 22,
MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\
|MODE_MOUSEMANY,
};
enum selection_mode { enum selection_mode {
SEL_IDLE = 0, SEL_IDLE = 0,
SEL_EMPTY = 1, SEL_EMPTY = 1,
@ -120,7 +91,6 @@ typedef struct {
char trantbl[4]; /* charset table translation */ char trantbl[4]; /* charset table translation */
int charset; /* current charset */ int charset; /* current charset */
int icharset; /* selected charset for sequence */ int icharset; /* selected charset for sequence */
int numlock; /* lock numbers in keyboard */
int *tabs; int *tabs;
} Term; } Term;
@ -130,7 +100,7 @@ typedef struct {
int w, h; /* window width and height */ int w, h; /* window width and height */
int ch; /* char height */ int ch; /* char height */
int cw; /* char width */ int cw; /* char width */
char state; /* focus, redraw, visible */ int mode; /* window state/mode flags */
int cursor; /* cursor style */ int cursor; /* cursor style */
} TermWindow; } TermWindow;
@ -163,7 +133,6 @@ void die(const char *, ...);
void redraw(void); void redraw(void);
void iso14755(const Arg *); void iso14755(const Arg *);
void numlock(const Arg *);
void printscreen(const Arg *); void printscreen(const Arg *);
void printsel(const Arg *); void printsel(const Arg *);
void sendbreak(const Arg *); void sendbreak(const Arg *);

24
win.h
View File

@ -1,5 +1,28 @@
/* See LICENSE for license details. */ /* See LICENSE for license details. */
enum win_mode {
MODE_VISIBLE = 1 << 0,
MODE_FOCUSED = 1 << 1,
MODE_APPKEYPAD = 1 << 2,
MODE_MOUSEBTN = 1 << 3,
MODE_MOUSEMOTION = 1 << 4,
MODE_REVERSE = 1 << 5,
MODE_KBDLOCK = 1 << 6,
MODE_HIDE = 1 << 7,
MODE_APPCURSOR = 1 << 8,
MODE_MOUSESGR = 1 << 9,
MODE_8BIT = 1 << 10,
MODE_BLINK = 1 << 11,
MODE_FBLINK = 1 << 12,
MODE_FOCUS = 1 << 13,
MODE_MOUSEX10 = 1 << 14,
MODE_MOUSEMANY = 1 << 15,
MODE_BRCKTPASTE = 1 << 16,
MODE_NUMLOCK = 1 << 17,
MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\
|MODE_MOUSEMANY,
};
void draw(void); void draw(void);
void drawregion(int, int, int, int); void drawregion(int, int, int, int);
@ -10,5 +33,6 @@ void xloadcols(void);
int xsetcolorname(int, const char *); int xsetcolorname(int, const char *);
void xsettitle(char *); void xsettitle(char *);
int xsetcursor(int); int xsetcursor(int);
void xsetmode(int, unsigned int);
void xsetpointermotion(int); void xsetpointermotion(int);
void xsetsel(char *); void xsetsel(char *);

50
x.c
View File

@ -51,6 +51,7 @@ typedef struct {
/* function definitions used in config.h */ /* function definitions used in config.h */
static void clipcopy(const Arg *); static void clipcopy(const Arg *);
static void clippaste(const Arg *); static void clippaste(const Arg *);
static void numlock(const Arg *);
static void selpaste(const Arg *); static void selpaste(const Arg *);
static void zoom(const Arg *); static void zoom(const Arg *);
static void zoomabs(const Arg *); static void zoomabs(const Arg *);
@ -64,6 +65,7 @@ static void zoomreset(const Arg *);
#define XEMBED_FOCUS_OUT 5 #define XEMBED_FOCUS_OUT 5
/* macros */ /* macros */
#define IS_SET(flag) ((win.mode & (flag)) != 0)
#define TRUERED(x) (((x) & 0xff0000) >> 8) #define TRUERED(x) (((x) & 0xff0000) >> 8)
#define TRUEGREEN(x) (((x) & 0xff00)) #define TRUEGREEN(x) (((x) & 0xff00))
#define TRUEBLUE(x) (((x) & 0xff) << 8) #define TRUEBLUE(x) (((x) & 0xff) << 8)
@ -196,11 +198,6 @@ static XWindow xw;
static XSelection xsel; static XSelection xsel;
static TermWindow win; static TermWindow win;
enum window_state {
WIN_VISIBLE = 1,
WIN_FOCUSED = 2
};
/* Font Ring Cache */ /* Font Ring Cache */
enum { enum {
FRC_NORMAL, FRC_NORMAL,
@ -263,6 +260,12 @@ selpaste(const Arg *dummy)
xw.win, CurrentTime); xw.win, CurrentTime);
} }
void
numlock(const Arg *dummy)
{
win.mode ^= MODE_NUMLOCK;
}
void void
zoom(const Arg *arg) zoom(const Arg *arg)
{ {
@ -1090,6 +1093,7 @@ xinit(void)
XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32, XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32,
PropModeReplace, (uchar *)&thispid, 1); PropModeReplace, (uchar *)&thispid, 1);
win.mode = MODE_NUMLOCK;
resettitle(); resettitle();
XMapWindow(xw.dpy, xw.win); XMapWindow(xw.dpy, xw.win);
xhints(); xhints();
@ -1319,14 +1323,13 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
fg = &revfg; fg = &revfg;
} }
if (base.mode & ATTR_REVERSE) { if (base.mode & ATTR_REVERSE) {
temp = fg; temp = fg;
fg = bg; fg = bg;
bg = temp; bg = temp;
} }
if (base.mode & ATTR_BLINK && term.mode & MODE_BLINK) if (base.mode & ATTR_BLINK && win.mode & MODE_BLINK)
fg = bg; fg = bg;
if (base.mode & ATTR_INVISIBLE) if (base.mode & ATTR_INVISIBLE)
@ -1440,7 +1443,7 @@ xdrawcursor(void)
return; return;
/* draw the new one */ /* draw the new one */
if (win.state & WIN_FOCUSED) { if (IS_SET(MODE_FOCUSED)) {
switch (win.cursor) { switch (win.cursor) {
case 7: /* st extension: snowman */ case 7: /* st extension: snowman */
utf8decode("", &g.u, UTF_SIZ); utf8decode("", &g.u, UTF_SIZ);
@ -1527,7 +1530,7 @@ drawregion(int x1, int y1, int x2, int y2)
Glyph base, new; Glyph base, new;
XftGlyphFontSpec *specs; XftGlyphFontSpec *specs;
if (!(win.state & WIN_VISIBLE)) if (!(IS_SET(MODE_VISIBLE)))
return; return;
for (y = y1; y < y2; y++) { for (y = y1; y < y2; y++) {
@ -1575,13 +1578,13 @@ visibility(XEvent *ev)
{ {
XVisibilityEvent *e = &ev->xvisibility; XVisibilityEvent *e = &ev->xvisibility;
MODBIT(win.state, e->state != VisibilityFullyObscured, WIN_VISIBLE); MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE);
} }
void void
unmap(XEvent *ev) unmap(XEvent *ev)
{ {
win.state &= ~WIN_VISIBLE; win.mode &= ~MODE_VISIBLE;
} }
void void
@ -1591,6 +1594,15 @@ xsetpointermotion(int set)
XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); 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 int
xsetcursor(int cursor) xsetcursor(int cursor)
{ {
@ -1614,7 +1626,7 @@ xseturgency(int add)
void void
xbell(void) xbell(void)
{ {
if (!(win.state & WIN_FOCUSED)) if (!(IS_SET(MODE_FOCUSED)))
xseturgency(1); xseturgency(1);
if (bellvolume) if (bellvolume)
XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL);
@ -1630,13 +1642,13 @@ focus(XEvent *ev)
if (ev->type == FocusIn) { if (ev->type == FocusIn) {
XSetICFocus(xw.xic); XSetICFocus(xw.xic);
win.state |= WIN_FOCUSED; win.mode |= MODE_FOCUSED;
xseturgency(0); xseturgency(0);
if (IS_SET(MODE_FOCUS)) if (IS_SET(MODE_FOCUS))
ttywrite("\033[I", 3, 0); ttywrite("\033[I", 3, 0);
} else { } else {
XUnsetICFocus(xw.xic); XUnsetICFocus(xw.xic);
win.state &= ~WIN_FOCUSED; win.mode &= ~MODE_FOCUSED;
if (IS_SET(MODE_FOCUS)) if (IS_SET(MODE_FOCUS))
ttywrite("\033[O", 3, 0); ttywrite("\033[O", 3, 0);
} }
@ -1673,7 +1685,7 @@ kmap(KeySym k, uint state)
if (IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0) if (IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0)
continue; continue;
if (term.numlock && kp->appkey == 2) if (IS_SET(MODE_NUMLOCK) && kp->appkey == 2)
continue; continue;
if (IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0) if (IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0)
@ -1742,10 +1754,10 @@ cmessage(XEvent *e)
*/ */
if (e->xclient.message_type == xw.xembed && e->xclient.format == 32) { if (e->xclient.message_type == xw.xembed && e->xclient.format == 32) {
if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) { if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) {
win.state |= WIN_FOCUSED; win.mode |= MODE_FOCUSED;
xseturgency(0); xseturgency(0);
} else if (e->xclient.data.l[1] == XEMBED_FOCUS_OUT) { } 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) { } else if (e->xclient.data.l[0] == xw.wmdeletewin) {
/* Send SIGHUP to shell */ /* Send SIGHUP to shell */
@ -1810,7 +1822,7 @@ run(void)
if (blinktimeout) { if (blinktimeout) {
blinkset = tattrset(ATTR_BLINK); blinkset = tattrset(ATTR_BLINK);
if (!blinkset) if (!blinkset)
MODBIT(term.mode, 0, MODE_BLINK); MODBIT(win.mode, 0, MODE_BLINK);
} }
} }
@ -1825,7 +1837,7 @@ run(void)
dodraw = 0; dodraw = 0;
if (blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) { if (blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) {
tsetdirtattr(ATTR_BLINK); tsetdirtattr(ATTR_BLINK);
term.mode ^= MODE_BLINK; win.mode ^= MODE_BLINK;
lastblink = now; lastblink = now;
dodraw = 1; dodraw = 1;
} }