Compare commits
9 Commits
3285ec77ca
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 31164e4c6d | |||
| 6be2a4fcb5 | |||
| c0a453cfa3 | |||
| 516c261aa6 | |||
| a2fae17ed4 | |||
| 8c496910d4 | |||
| e82186f9b5 | |||
| f4100cdc22 | |||
| f7b397d0cb |
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
*.o
|
||||||
|
|
||||||
|
*.diff
|
||||||
5
Makefile
5
Makefile
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
include config.mk
|
include config.mk
|
||||||
|
|
||||||
SRC = st.c x.c
|
SRC = st.c x.c hb.c
|
||||||
OBJ = $(SRC:.c=.o)
|
OBJ = $(SRC:.c=.o)
|
||||||
|
|
||||||
all: st
|
all: st
|
||||||
@@ -16,7 +16,8 @@ config.h:
|
|||||||
$(CC) $(STCFLAGS) -c $<
|
$(CC) $(STCFLAGS) -c $<
|
||||||
|
|
||||||
st.o: config.h st.h win.h
|
st.o: config.h st.h win.h
|
||||||
x.o: arg.h config.h st.h win.h
|
x.o: arg.h config.h st.h win.h hb.h
|
||||||
|
hb.o: st.h
|
||||||
|
|
||||||
$(OBJ): config.h config.mk
|
$(OBJ): config.h config.mk
|
||||||
|
|
||||||
|
|||||||
551
config.def.h
551
config.def.h
@@ -5,7 +5,11 @@
|
|||||||
*
|
*
|
||||||
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
||||||
*/
|
*/
|
||||||
static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
|
static char *font =
|
||||||
|
"JetBrainsMono NFP:pixelsize=15:antialias=true:autohint=true";
|
||||||
|
static char *font2[] = {
|
||||||
|
"Noto Color Emoji:pixelsize=15:antialias=true:autohint=true",
|
||||||
|
};
|
||||||
static int borderpx = 2;
|
static int borderpx = 2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -16,7 +20,7 @@ static int borderpx = 2;
|
|||||||
* 4: value of shell in /etc/passwd
|
* 4: value of shell in /etc/passwd
|
||||||
* 5: value of shell in config.h
|
* 5: value of shell in config.h
|
||||||
*/
|
*/
|
||||||
static char *shell = "/bin/sh";
|
static char *shell = "/bin/bash";
|
||||||
char *utmp = NULL;
|
char *utmp = NULL;
|
||||||
/* scroll program: to enable use a string like "scroll" */
|
/* scroll program: to enable use a string like "scroll" */
|
||||||
char *scroll = NULL;
|
char *scroll = NULL;
|
||||||
@@ -95,53 +99,47 @@ unsigned int tabspaces = 8;
|
|||||||
|
|
||||||
/* Terminal colors (16 first used in escape sequence) */
|
/* Terminal colors (16 first used in escape sequence) */
|
||||||
static const char *colorname[] = {
|
static const char *colorname[] = {
|
||||||
/* 8 normal colors */
|
/* 8 normal colors */
|
||||||
"black",
|
[0] = "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */
|
||||||
"red3",
|
[1] = "#cc241d", /* red */
|
||||||
"green3",
|
[2] = "#98971a", /* green */
|
||||||
"yellow3",
|
[3] = "#d79921", /* yellow */
|
||||||
"blue2",
|
[4] = "#458588", /* blue */
|
||||||
"magenta3",
|
[5] = "#b16286", /* magenta */
|
||||||
"cyan3",
|
[6] = "#689d6a", /* cyan */
|
||||||
"gray90",
|
[7] = "#a89984", /* white */
|
||||||
|
[8] = "#928374", /* black */
|
||||||
/* 8 bright colors */
|
[9] = "#fb4934", /* red */
|
||||||
"gray50",
|
[10] = "#b8bb26", /* green */
|
||||||
"red",
|
[11] = "#fabd2f", /* yellow */
|
||||||
"green",
|
[12] = "#83a598", /* blue */
|
||||||
"yellow",
|
[13] = "#d3869b", /* magenta */
|
||||||
"#5c5cff",
|
[14] = "#8ec07c", /* cyan */
|
||||||
"magenta",
|
[15] = "#ebdbb2", /* white */
|
||||||
"cyan",
|
[255] = 0,
|
||||||
"white",
|
|
||||||
|
|
||||||
[255] = 0,
|
|
||||||
|
|
||||||
/* more colors can be added after 255 to use with DefaultXX */
|
|
||||||
"#cccccc",
|
|
||||||
"#555555",
|
|
||||||
"gray90", /* default foreground colour */
|
|
||||||
"black", /* default background colour */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default colors (colorname index)
|
* Default colors (colorname index)
|
||||||
* foreground, background, cursor, reverse cursor
|
* foreground, background, cursor, reverse cursor
|
||||||
*/
|
*/
|
||||||
unsigned int defaultfg = 258;
|
unsigned int defaultfg = 15;
|
||||||
unsigned int defaultbg = 259;
|
unsigned int defaultbg = 0;
|
||||||
unsigned int defaultcs = 256;
|
unsigned int defaultcs = 15;
|
||||||
static unsigned int defaultrcs = 257;
|
static unsigned int defaultrcs = 257;
|
||||||
|
|
||||||
/*
|
/* https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-SP-q.1D81
|
||||||
* Default shape of cursor
|
* Default style of cursor
|
||||||
* 2: Block ("█")
|
* 0: blinking block
|
||||||
* 4: Underline ("_")
|
* 1: blinking block (default)
|
||||||
* 6: Bar ("|")
|
* 2: steady block ("█")
|
||||||
* 7: Snowman ("☃")
|
* 3: blinking underline
|
||||||
|
* 4: steady underline ("_")
|
||||||
|
* 5: blinking bar
|
||||||
|
* 6: steady bar ("|")
|
||||||
|
* 7: blinking st cursor
|
||||||
|
* 8: steady st cursor
|
||||||
*/
|
*/
|
||||||
static unsigned int cursorshape = 2;
|
static unsigned int cursorshape = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default columns and rows numbers
|
* Default columns and rows numbers
|
||||||
@@ -175,32 +173,30 @@ static uint forcemousemod = ShiftMask;
|
|||||||
* Beware that overloading Button1 will disable the selection.
|
* Beware that overloading Button1 will disable the selection.
|
||||||
*/
|
*/
|
||||||
static MouseShortcut mshortcuts[] = {
|
static MouseShortcut mshortcuts[] = {
|
||||||
/* mask button function argument release */
|
/* mask button function argument release */
|
||||||
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
|
{XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1},
|
||||||
{ ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
|
{ShiftMask, Button4, kscrollup, {.i = 1}},
|
||||||
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
|
{ShiftMask, Button5, kscrolldown, {.i = 1}},
|
||||||
{ ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
|
|
||||||
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Internal keyboard shortcuts. */
|
/* Internal keyboard shortcuts. */
|
||||||
#define MODKEY Mod1Mask
|
#define MODKEY Mod1Mask
|
||||||
#define TERMMOD (ControlMask|ShiftMask)
|
#define TERMMOD (ControlMask | ShiftMask)
|
||||||
|
|
||||||
static Shortcut shortcuts[] = {
|
static Shortcut shortcuts[] = {
|
||||||
/* mask keysym function argument */
|
/* mask keysym function argument */
|
||||||
{ XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
|
{XK_ANY_MOD, XK_Break, sendbreak, {.i = 0}},
|
||||||
{ ControlMask, XK_Print, toggleprinter, {.i = 0} },
|
{ControlMask, XK_Print, toggleprinter, {.i = 0}},
|
||||||
{ ShiftMask, XK_Print, printscreen, {.i = 0} },
|
{ShiftMask, XK_Print, printscreen, {.i = 0}},
|
||||||
{ XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
|
{XK_ANY_MOD, XK_Print, printsel, {.i = 0}},
|
||||||
{ TERMMOD, XK_Prior, zoom, {.f = +1} },
|
{ControlMask, XK_KP_Add, zoom, {.f = +1}},
|
||||||
{ TERMMOD, XK_Next, zoom, {.f = -1} },
|
{ControlMask, XK_minus, zoom, {.f = -1}},
|
||||||
{ TERMMOD, XK_Home, zoomreset, {.f = 0} },
|
{TERMMOD, XK_Home, zoomreset, {.f = 0}},
|
||||||
{ TERMMOD, XK_C, clipcopy, {.i = 0} },
|
{TERMMOD, XK_C, clipcopy, {.i = 0}},
|
||||||
{ TERMMOD, XK_V, clippaste, {.i = 0} },
|
{TERMMOD, XK_V, clippaste, {.i = 0}},
|
||||||
{ TERMMOD, XK_Y, selpaste, {.i = 0} },
|
{TERMMOD, XK_Y, selpaste, {.i = 0}},
|
||||||
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
|
{ShiftMask, XK_Insert, selpaste, {.i = 0}},
|
||||||
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
|
{TERMMOD, XK_Num_Lock, numlock, {.i = 0}},
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -228,229 +224,229 @@ static Shortcut shortcuts[] = {
|
|||||||
* If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
|
* If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
|
||||||
* to be mapped below, add them to this array.
|
* to be mapped below, add them to this array.
|
||||||
*/
|
*/
|
||||||
static KeySym mappedkeys[] = { -1 };
|
static KeySym mappedkeys[] = {-1};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* State bits to ignore when matching key or button events. By default,
|
* State bits to ignore when matching key or button events. By default,
|
||||||
* numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
|
* numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
|
||||||
*/
|
*/
|
||||||
static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
|
static uint ignoremod = Mod2Mask | XK_SWITCH_MOD;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the huge key array which defines all compatibility to the Linux
|
* This is the huge key array which defines all compatibility to the Linux
|
||||||
* world. Please decide about changes wisely.
|
* world. Please decide about changes wisely.
|
||||||
*/
|
*/
|
||||||
static Key key[] = {
|
static Key key[] = {
|
||||||
/* keysym mask string appkey appcursor */
|
/* keysym mask string appkey appcursor */
|
||||||
{ XK_KP_Home, ShiftMask, "\033[2J", 0, -1},
|
{XK_KP_Home, ShiftMask, "\033[2J", 0, -1},
|
||||||
{ XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1},
|
{XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1},
|
||||||
{ XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1},
|
{XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1},
|
||||||
{ XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1},
|
{XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1},
|
||||||
{ XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0},
|
{XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0},
|
||||||
{ XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
{XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||||
{ XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
{XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||||
{ XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0},
|
{XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0},
|
||||||
{ XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
{XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||||
{ XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
{XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||||
{ XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0},
|
{XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0},
|
||||||
{ XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
{XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||||
{ XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
{XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||||
{ XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0},
|
{XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0},
|
||||||
{ XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
{XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||||
{ XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
{XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||||
{ XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
{XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||||
{ XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
{XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||||
{ XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0},
|
{XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0},
|
||||||
{ XK_KP_End, ControlMask, "\033[J", -1, 0},
|
{XK_KP_End, ControlMask, "\033[J", -1, 0},
|
||||||
{ XK_KP_End, ControlMask, "\033[1;5F", +1, 0},
|
{XK_KP_End, ControlMask, "\033[1;5F", +1, 0},
|
||||||
{ XK_KP_End, ShiftMask, "\033[K", -1, 0},
|
{XK_KP_End, ShiftMask, "\033[K", -1, 0},
|
||||||
{ XK_KP_End, ShiftMask, "\033[1;2F", +1, 0},
|
{XK_KP_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||||
{ XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
{XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||||
{ XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0},
|
{XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||||
{ XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
{XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||||
{ XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
{XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||||
{ XK_KP_Insert, ShiftMask, "\033[4l", -1, 0},
|
{XK_KP_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||||
{ XK_KP_Insert, ControlMask, "\033[L", -1, 0},
|
{XK_KP_Insert, ControlMask, "\033[L", -1, 0},
|
||||||
{ XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0},
|
{XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||||
{ XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
{XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||||
{ XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
{XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||||
{ XK_KP_Delete, ControlMask, "\033[M", -1, 0},
|
{XK_KP_Delete, ControlMask, "\033[M", -1, 0},
|
||||||
{ XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
|
{XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||||
{ XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
|
{XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||||
{ XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
{XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||||
{ XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
{XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||||
{ XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
{XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||||
{ XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
|
{XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
|
||||||
{ XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
|
{XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
|
||||||
{ XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0},
|
{XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0},
|
||||||
{ XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0},
|
{XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0},
|
||||||
{ XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0},
|
{XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0},
|
||||||
{ XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0},
|
{XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0},
|
||||||
{ XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0},
|
{XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0},
|
||||||
{ XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0},
|
{XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0},
|
||||||
{ XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0},
|
{XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0},
|
||||||
{ XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0},
|
{XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0},
|
||||||
{ XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0},
|
{XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0},
|
||||||
{ XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0},
|
{XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0},
|
||||||
{ XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0},
|
{XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0},
|
||||||
{ XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0},
|
{XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0},
|
||||||
{ XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0},
|
{XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0},
|
||||||
{ XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0},
|
{XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0},
|
||||||
{ XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0},
|
{XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0},
|
||||||
{ XK_Up, ShiftMask, "\033[1;2A", 0, 0},
|
{XK_Up, ShiftMask, "\033[1;2A", 0, 0},
|
||||||
{ XK_Up, Mod1Mask, "\033[1;3A", 0, 0},
|
{XK_Up, Mod1Mask, "\033[1;3A", 0, 0},
|
||||||
{ XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0},
|
{XK_Up, ShiftMask | Mod1Mask, "\033[1;4A", 0, 0},
|
||||||
{ XK_Up, ControlMask, "\033[1;5A", 0, 0},
|
{XK_Up, ControlMask, "\033[1;5A", 0, 0},
|
||||||
{ XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0},
|
{XK_Up, ShiftMask | ControlMask, "\033[1;6A", 0, 0},
|
||||||
{ XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0},
|
{XK_Up, ControlMask | Mod1Mask, "\033[1;7A", 0, 0},
|
||||||
{ XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0},
|
{XK_Up, ShiftMask | ControlMask | Mod1Mask, "\033[1;8A", 0, 0},
|
||||||
{ XK_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
{XK_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||||
{ XK_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
{XK_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||||
{ XK_Down, ShiftMask, "\033[1;2B", 0, 0},
|
{XK_Down, ShiftMask, "\033[1;2B", 0, 0},
|
||||||
{ XK_Down, Mod1Mask, "\033[1;3B", 0, 0},
|
{XK_Down, Mod1Mask, "\033[1;3B", 0, 0},
|
||||||
{ XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0},
|
{XK_Down, ShiftMask | Mod1Mask, "\033[1;4B", 0, 0},
|
||||||
{ XK_Down, ControlMask, "\033[1;5B", 0, 0},
|
{XK_Down, ControlMask, "\033[1;5B", 0, 0},
|
||||||
{ XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0},
|
{XK_Down, ShiftMask | ControlMask, "\033[1;6B", 0, 0},
|
||||||
{ XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0},
|
{XK_Down, ControlMask | Mod1Mask, "\033[1;7B", 0, 0},
|
||||||
{ XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0},
|
{XK_Down, ShiftMask | ControlMask | Mod1Mask, "\033[1;8B", 0, 0},
|
||||||
{ XK_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
{XK_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||||
{ XK_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
{XK_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||||
{ XK_Left, ShiftMask, "\033[1;2D", 0, 0},
|
{XK_Left, ShiftMask, "\033[1;2D", 0, 0},
|
||||||
{ XK_Left, Mod1Mask, "\033[1;3D", 0, 0},
|
{XK_Left, Mod1Mask, "\033[1;3D", 0, 0},
|
||||||
{ XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0},
|
{XK_Left, ShiftMask | Mod1Mask, "\033[1;4D", 0, 0},
|
||||||
{ XK_Left, ControlMask, "\033[1;5D", 0, 0},
|
{XK_Left, ControlMask, "\033[1;5D", 0, 0},
|
||||||
{ XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0},
|
{XK_Left, ShiftMask | ControlMask, "\033[1;6D", 0, 0},
|
||||||
{ XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0},
|
{XK_Left, ControlMask | Mod1Mask, "\033[1;7D", 0, 0},
|
||||||
{ XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0},
|
{XK_Left, ShiftMask | ControlMask | Mod1Mask, "\033[1;8D", 0, 0},
|
||||||
{ XK_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
{XK_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||||
{ XK_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
{XK_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||||
{ XK_Right, ShiftMask, "\033[1;2C", 0, 0},
|
{XK_Right, ShiftMask, "\033[1;2C", 0, 0},
|
||||||
{ XK_Right, Mod1Mask, "\033[1;3C", 0, 0},
|
{XK_Right, Mod1Mask, "\033[1;3C", 0, 0},
|
||||||
{ XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0},
|
{XK_Right, ShiftMask | Mod1Mask, "\033[1;4C", 0, 0},
|
||||||
{ XK_Right, ControlMask, "\033[1;5C", 0, 0},
|
{XK_Right, ControlMask, "\033[1;5C", 0, 0},
|
||||||
{ XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0},
|
{XK_Right, ShiftMask | ControlMask, "\033[1;6C", 0, 0},
|
||||||
{ XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0},
|
{XK_Right, ControlMask | Mod1Mask, "\033[1;7C", 0, 0},
|
||||||
{ XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0},
|
{XK_Right, ShiftMask | ControlMask | Mod1Mask, "\033[1;8C", 0, 0},
|
||||||
{ XK_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
{XK_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||||
{ XK_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
{XK_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||||
{ XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0},
|
{XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0},
|
||||||
{ XK_Return, Mod1Mask, "\033\r", 0, 0},
|
{XK_Return, Mod1Mask, "\033\r", 0, 0},
|
||||||
{ XK_Return, XK_ANY_MOD, "\r", 0, 0},
|
{XK_Return, XK_ANY_MOD, "\r", 0, 0},
|
||||||
{ XK_Insert, ShiftMask, "\033[4l", -1, 0},
|
{XK_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||||
{ XK_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
{XK_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||||
{ XK_Insert, ControlMask, "\033[L", -1, 0},
|
{XK_Insert, ControlMask, "\033[L", -1, 0},
|
||||||
{ XK_Insert, ControlMask, "\033[2;5~", +1, 0},
|
{XK_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||||
{ XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
{XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||||
{ XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
{XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||||
{ XK_Delete, ControlMask, "\033[M", -1, 0},
|
{XK_Delete, ControlMask, "\033[M", -1, 0},
|
||||||
{ XK_Delete, ControlMask, "\033[3;5~", +1, 0},
|
{XK_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||||
{ XK_Delete, ShiftMask, "\033[2K", -1, 0},
|
{XK_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||||
{ XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
{XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||||
{ XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
{XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||||
{ XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
{XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||||
{ XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
|
{XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
|
||||||
{ XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
|
{XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
|
||||||
{ XK_Home, ShiftMask, "\033[2J", 0, -1},
|
{XK_Home, ShiftMask, "\033[2J", 0, -1},
|
||||||
{ XK_Home, ShiftMask, "\033[1;2H", 0, +1},
|
{XK_Home, ShiftMask, "\033[1;2H", 0, +1},
|
||||||
{ XK_Home, XK_ANY_MOD, "\033[H", 0, -1},
|
{XK_Home, XK_ANY_MOD, "\033[H", 0, -1},
|
||||||
{ XK_Home, XK_ANY_MOD, "\033[1~", 0, +1},
|
{XK_Home, XK_ANY_MOD, "\033[1~", 0, +1},
|
||||||
{ XK_End, ControlMask, "\033[J", -1, 0},
|
{XK_End, ControlMask, "\033[J", -1, 0},
|
||||||
{ XK_End, ControlMask, "\033[1;5F", +1, 0},
|
{XK_End, ControlMask, "\033[1;5F", +1, 0},
|
||||||
{ XK_End, ShiftMask, "\033[K", -1, 0},
|
{XK_End, ShiftMask, "\033[K", -1, 0},
|
||||||
{ XK_End, ShiftMask, "\033[1;2F", +1, 0},
|
{XK_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||||
{ XK_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
{XK_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||||
{ XK_Prior, ControlMask, "\033[5;5~", 0, 0},
|
{XK_Prior, ControlMask, "\033[5;5~", 0, 0},
|
||||||
{ XK_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
{XK_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||||
{ XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
{XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||||
{ XK_Next, ControlMask, "\033[6;5~", 0, 0},
|
{XK_Next, ControlMask, "\033[6;5~", 0, 0},
|
||||||
{ XK_Next, ShiftMask, "\033[6;2~", 0, 0},
|
{XK_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||||
{ XK_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
{XK_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||||
{ XK_F1, XK_NO_MOD, "\033OP" , 0, 0},
|
{XK_F1, XK_NO_MOD, "\033OP", 0, 0},
|
||||||
{ XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0},
|
{XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0},
|
||||||
{ XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0},
|
{XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0},
|
||||||
{ XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0},
|
{XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0},
|
||||||
{ XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0},
|
{XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0},
|
||||||
{ XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0},
|
{XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0},
|
||||||
{ XK_F2, XK_NO_MOD, "\033OQ" , 0, 0},
|
{XK_F2, XK_NO_MOD, "\033OQ", 0, 0},
|
||||||
{ XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0},
|
{XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0},
|
||||||
{ XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0},
|
{XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0},
|
||||||
{ XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0},
|
{XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0},
|
||||||
{ XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0},
|
{XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0},
|
||||||
{ XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0},
|
{XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0},
|
||||||
{ XK_F3, XK_NO_MOD, "\033OR" , 0, 0},
|
{XK_F3, XK_NO_MOD, "\033OR", 0, 0},
|
||||||
{ XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0},
|
{XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0},
|
||||||
{ XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0},
|
{XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0},
|
||||||
{ XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0},
|
{XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0},
|
||||||
{ XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0},
|
{XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0},
|
||||||
{ XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0},
|
{XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0},
|
||||||
{ XK_F4, XK_NO_MOD, "\033OS" , 0, 0},
|
{XK_F4, XK_NO_MOD, "\033OS", 0, 0},
|
||||||
{ XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0},
|
{XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0},
|
||||||
{ XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0},
|
{XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0},
|
||||||
{ XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0},
|
{XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0},
|
||||||
{ XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0},
|
{XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0},
|
||||||
{ XK_F5, XK_NO_MOD, "\033[15~", 0, 0},
|
{XK_F5, XK_NO_MOD, "\033[15~", 0, 0},
|
||||||
{ XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0},
|
{XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0},
|
||||||
{ XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0},
|
{XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0},
|
||||||
{ XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0},
|
{XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0},
|
||||||
{ XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0},
|
{XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0},
|
||||||
{ XK_F6, XK_NO_MOD, "\033[17~", 0, 0},
|
{XK_F6, XK_NO_MOD, "\033[17~", 0, 0},
|
||||||
{ XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0},
|
{XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0},
|
||||||
{ XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0},
|
{XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0},
|
||||||
{ XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0},
|
{XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0},
|
||||||
{ XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0},
|
{XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0},
|
||||||
{ XK_F7, XK_NO_MOD, "\033[18~", 0, 0},
|
{XK_F7, XK_NO_MOD, "\033[18~", 0, 0},
|
||||||
{ XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0},
|
{XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0},
|
||||||
{ XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0},
|
{XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0},
|
||||||
{ XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0},
|
{XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0},
|
||||||
{ XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0},
|
{XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0},
|
||||||
{ XK_F8, XK_NO_MOD, "\033[19~", 0, 0},
|
{XK_F8, XK_NO_MOD, "\033[19~", 0, 0},
|
||||||
{ XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0},
|
{XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0},
|
||||||
{ XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0},
|
{XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0},
|
||||||
{ XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0},
|
{XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0},
|
||||||
{ XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0},
|
{XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0},
|
||||||
{ XK_F9, XK_NO_MOD, "\033[20~", 0, 0},
|
{XK_F9, XK_NO_MOD, "\033[20~", 0, 0},
|
||||||
{ XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0},
|
{XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0},
|
||||||
{ XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0},
|
{XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0},
|
||||||
{ XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0},
|
{XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0},
|
||||||
{ XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0},
|
{XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0},
|
||||||
{ XK_F10, XK_NO_MOD, "\033[21~", 0, 0},
|
{XK_F10, XK_NO_MOD, "\033[21~", 0, 0},
|
||||||
{ XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0},
|
{XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0},
|
||||||
{ XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0},
|
{XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0},
|
||||||
{ XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0},
|
{XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0},
|
||||||
{ XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0},
|
{XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0},
|
||||||
{ XK_F11, XK_NO_MOD, "\033[23~", 0, 0},
|
{XK_F11, XK_NO_MOD, "\033[23~", 0, 0},
|
||||||
{ XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0},
|
{XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0},
|
||||||
{ XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0},
|
{XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0},
|
||||||
{ XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0},
|
{XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0},
|
||||||
{ XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0},
|
{XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0},
|
||||||
{ XK_F12, XK_NO_MOD, "\033[24~", 0, 0},
|
{XK_F12, XK_NO_MOD, "\033[24~", 0, 0},
|
||||||
{ XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0},
|
{XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0},
|
||||||
{ XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0},
|
{XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0},
|
||||||
{ XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0},
|
{XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0},
|
||||||
{ XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0},
|
{XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0},
|
||||||
{ XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0},
|
{XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0},
|
||||||
{ XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0},
|
{XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0},
|
||||||
{ XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0},
|
{XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0},
|
||||||
{ XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0},
|
{XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0},
|
||||||
{ XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0},
|
{XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0},
|
||||||
{ XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0},
|
{XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0},
|
||||||
{ XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0},
|
{XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0},
|
||||||
{ XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0},
|
{XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0},
|
||||||
{ XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0},
|
{XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0},
|
||||||
{ XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0},
|
{XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0},
|
||||||
{ XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0},
|
{XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0},
|
||||||
{ XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0},
|
{XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0},
|
||||||
{ XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0},
|
{XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0},
|
||||||
{ XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0},
|
{XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0},
|
||||||
{ XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0},
|
{XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0},
|
||||||
{ XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0},
|
{XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0},
|
||||||
{ XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0},
|
{XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0},
|
||||||
{ XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0},
|
{XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0},
|
||||||
{ XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0},
|
{XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0},
|
||||||
{ XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0},
|
{XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0},
|
||||||
{ XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0},
|
{XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0},
|
||||||
{ XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0},
|
{XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0},
|
||||||
{ XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0},
|
{XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -461,14 +457,13 @@ static Key key[] = {
|
|||||||
* If no match is found, regular selection is used.
|
* If no match is found, regular selection is used.
|
||||||
*/
|
*/
|
||||||
static uint selmasks[] = {
|
static uint selmasks[] = {
|
||||||
[SEL_RECTANGULAR] = Mod1Mask,
|
[SEL_RECTANGULAR] = Mod1Mask,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Printable characters in ASCII, used to estimate the advance width
|
* Printable characters in ASCII, used to estimate the advance width
|
||||||
* of single wide characters.
|
* of single wide characters.
|
||||||
*/
|
*/
|
||||||
static char ascii_printable[] =
|
static char ascii_printable[] = " !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||||
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||||
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
"`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||||
"`abcdefghijklmnopqrstuvwxyz{|}~";
|
|
||||||
|
|||||||
469
config.h
Normal file
469
config.h
Normal file
@@ -0,0 +1,469 @@
|
|||||||
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* appearance
|
||||||
|
*
|
||||||
|
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
||||||
|
*/
|
||||||
|
static char *font =
|
||||||
|
"JetBrainsMono NFP:pixelsize=15:antialias=true:autohint=true";
|
||||||
|
static char *font2[] = {
|
||||||
|
"Noto Color Emoji:pixelsize=15:antialias=true:autohint=true",
|
||||||
|
};
|
||||||
|
static int borderpx = 2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* What program is execed by st depends of these precedence rules:
|
||||||
|
* 1: program passed with -e
|
||||||
|
* 2: scroll and/or utmp
|
||||||
|
* 3: SHELL environment variable
|
||||||
|
* 4: value of shell in /etc/passwd
|
||||||
|
* 5: value of shell in config.h
|
||||||
|
*/
|
||||||
|
static char *shell = "/bin/bash";
|
||||||
|
char *utmp = NULL;
|
||||||
|
/* scroll program: to enable use a string like "scroll" */
|
||||||
|
char *scroll = NULL;
|
||||||
|
char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
|
||||||
|
|
||||||
|
/* identification sequence returned in DA and DECID */
|
||||||
|
char *vtiden = "\033[?6c";
|
||||||
|
|
||||||
|
/* Kerning / character bounding-box multipliers */
|
||||||
|
static float cwscale = 1.0;
|
||||||
|
static float chscale = 1.0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* word delimiter string
|
||||||
|
*
|
||||||
|
* More advanced example: L" `'\"()[]{}"
|
||||||
|
*/
|
||||||
|
wchar_t *worddelimiters = L" ";
|
||||||
|
|
||||||
|
/* selection timeouts (in milliseconds) */
|
||||||
|
static unsigned int doubleclicktimeout = 300;
|
||||||
|
static unsigned int tripleclicktimeout = 600;
|
||||||
|
|
||||||
|
/* alt screens */
|
||||||
|
int allowaltscreen = 1;
|
||||||
|
|
||||||
|
/* allow certain non-interactive (insecure) window operations such as:
|
||||||
|
setting the clipboard text */
|
||||||
|
int allowwindowops = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* draw latency range in ms - from new content/keypress/etc until drawing.
|
||||||
|
* within this range, st draws when content stops arriving (idle). mostly it's
|
||||||
|
* near minlatency, but it waits longer for slow updates to avoid partial draw.
|
||||||
|
* low minlatency will tear/flicker more, as it can "detect" idle too early.
|
||||||
|
*/
|
||||||
|
static double minlatency = 2;
|
||||||
|
static double maxlatency = 33;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* blinking timeout (set to 0 to disable blinking) for the terminal blinking
|
||||||
|
* attribute.
|
||||||
|
*/
|
||||||
|
static unsigned int blinktimeout = 800;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* thickness of underline and bar cursors
|
||||||
|
*/
|
||||||
|
static unsigned int cursorthickness = 2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bell volume. It must be a value between -100 and 100. Use 0 for disabling
|
||||||
|
* it
|
||||||
|
*/
|
||||||
|
static int bellvolume = 0;
|
||||||
|
|
||||||
|
/* default TERM value */
|
||||||
|
char *termname = "st-256color";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* spaces per tab
|
||||||
|
*
|
||||||
|
* When you are changing this value, don't forget to adapt the »it« value in
|
||||||
|
* the st.info and appropriately install the st.info in the environment where
|
||||||
|
* you use this st version.
|
||||||
|
*
|
||||||
|
* it#$tabspaces,
|
||||||
|
*
|
||||||
|
* Secondly make sure your kernel is not expanding tabs. When running `stty
|
||||||
|
* -a` »tab0« should appear. You can tell the terminal to not expand tabs by
|
||||||
|
* running following command:
|
||||||
|
*
|
||||||
|
* stty tabs
|
||||||
|
*/
|
||||||
|
unsigned int tabspaces = 8;
|
||||||
|
|
||||||
|
/* Terminal colors (16 first used in escape sequence) */
|
||||||
|
static const char *colorname[] = {
|
||||||
|
/* 8 normal colors */
|
||||||
|
[0] = "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */
|
||||||
|
[1] = "#cc241d", /* red */
|
||||||
|
[2] = "#98971a", /* green */
|
||||||
|
[3] = "#d79921", /* yellow */
|
||||||
|
[4] = "#458588", /* blue */
|
||||||
|
[5] = "#b16286", /* magenta */
|
||||||
|
[6] = "#689d6a", /* cyan */
|
||||||
|
[7] = "#a89984", /* white */
|
||||||
|
[8] = "#928374", /* black */
|
||||||
|
[9] = "#fb4934", /* red */
|
||||||
|
[10] = "#b8bb26", /* green */
|
||||||
|
[11] = "#fabd2f", /* yellow */
|
||||||
|
[12] = "#83a598", /* blue */
|
||||||
|
[13] = "#d3869b", /* magenta */
|
||||||
|
[14] = "#8ec07c", /* cyan */
|
||||||
|
[15] = "#ebdbb2", /* white */
|
||||||
|
[255] = 0,
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
* Default colors (colorname index)
|
||||||
|
* foreground, background, cursor, reverse cursor
|
||||||
|
*/
|
||||||
|
unsigned int defaultfg = 15;
|
||||||
|
unsigned int defaultbg = 0;
|
||||||
|
unsigned int defaultcs = 15;
|
||||||
|
static unsigned int defaultrcs = 257;
|
||||||
|
|
||||||
|
/* https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-SP-q.1D81
|
||||||
|
* Default style of cursor
|
||||||
|
* 0: blinking block
|
||||||
|
* 1: blinking block (default)
|
||||||
|
* 2: steady block ("█")
|
||||||
|
* 3: blinking underline
|
||||||
|
* 4: steady underline ("_")
|
||||||
|
* 5: blinking bar
|
||||||
|
* 6: steady bar ("|")
|
||||||
|
* 7: blinking st cursor
|
||||||
|
* 8: steady st cursor
|
||||||
|
*/
|
||||||
|
static unsigned int cursorshape = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default columns and rows numbers
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unsigned int cols = 80;
|
||||||
|
static unsigned int rows = 24;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default colour and shape of the mouse cursor
|
||||||
|
*/
|
||||||
|
static unsigned int mouseshape = XC_xterm;
|
||||||
|
static unsigned int mousefg = 7;
|
||||||
|
static unsigned int mousebg = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Color used to display font attributes when fontconfig selected a font which
|
||||||
|
* doesn't match the ones requested.
|
||||||
|
*/
|
||||||
|
static unsigned int 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.
|
||||||
|
*/
|
||||||
|
static uint forcemousemod = ShiftMask;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal mouse shortcuts.
|
||||||
|
* Beware that overloading Button1 will disable the selection.
|
||||||
|
*/
|
||||||
|
static MouseShortcut mshortcuts[] = {
|
||||||
|
/* mask button function argument release */
|
||||||
|
{XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1},
|
||||||
|
{ShiftMask, Button4, kscrollup, {.i = 1}},
|
||||||
|
{ShiftMask, Button5, kscrolldown, {.i = 1}},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Internal keyboard shortcuts. */
|
||||||
|
#define MODKEY Mod1Mask
|
||||||
|
#define TERMMOD (ControlMask | ShiftMask)
|
||||||
|
|
||||||
|
static Shortcut shortcuts[] = {
|
||||||
|
/* mask keysym function argument */
|
||||||
|
{XK_ANY_MOD, XK_Break, sendbreak, {.i = 0}},
|
||||||
|
{ControlMask, XK_Print, toggleprinter, {.i = 0}},
|
||||||
|
{ShiftMask, XK_Print, printscreen, {.i = 0}},
|
||||||
|
{XK_ANY_MOD, XK_Print, printsel, {.i = 0}},
|
||||||
|
{ControlMask, XK_KP_Add, zoom, {.f = +1}},
|
||||||
|
{ControlMask, XK_minus, zoom, {.f = -1}},
|
||||||
|
{TERMMOD, XK_Home, zoomreset, {.f = 0}},
|
||||||
|
{TERMMOD, XK_C, clipcopy, {.i = 0}},
|
||||||
|
{TERMMOD, XK_V, clippaste, {.i = 0}},
|
||||||
|
{TERMMOD, XK_Y, selpaste, {.i = 0}},
|
||||||
|
{ShiftMask, XK_Insert, selpaste, {.i = 0}},
|
||||||
|
{TERMMOD, XK_Num_Lock, numlock, {.i = 0}},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special keys (change & recompile st.info accordingly)
|
||||||
|
*
|
||||||
|
* Mask value:
|
||||||
|
* * Use XK_ANY_MOD to match the key no matter modifiers state
|
||||||
|
* * Use XK_NO_MOD to match the key alone (no modifiers)
|
||||||
|
* appkey value:
|
||||||
|
* * 0: no value
|
||||||
|
* * > 0: keypad application mode enabled
|
||||||
|
* * = 2: term.numlock = 1
|
||||||
|
* * < 0: keypad application mode disabled
|
||||||
|
* appcursor value:
|
||||||
|
* * 0: no value
|
||||||
|
* * > 0: cursor application mode enabled
|
||||||
|
* * < 0: cursor application mode disabled
|
||||||
|
*
|
||||||
|
* Be careful with the order of the definitions because st searches in
|
||||||
|
* this table sequentially, so any XK_ANY_MOD must be in the last
|
||||||
|
* position for a key.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
|
||||||
|
* to be mapped below, add them to this array.
|
||||||
|
*/
|
||||||
|
static KeySym mappedkeys[] = {-1};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* State bits to ignore when matching key or button events. By default,
|
||||||
|
* numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
|
||||||
|
*/
|
||||||
|
static uint ignoremod = Mod2Mask | XK_SWITCH_MOD;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the huge key array which defines all compatibility to the Linux
|
||||||
|
* world. Please decide about changes wisely.
|
||||||
|
*/
|
||||||
|
static Key key[] = {
|
||||||
|
/* keysym mask string appkey appcursor */
|
||||||
|
{XK_KP_Home, ShiftMask, "\033[2J", 0, -1},
|
||||||
|
{XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1},
|
||||||
|
{XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1},
|
||||||
|
{XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1},
|
||||||
|
{XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0},
|
||||||
|
{XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||||
|
{XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||||
|
{XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0},
|
||||||
|
{XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||||
|
{XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||||
|
{XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0},
|
||||||
|
{XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||||
|
{XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||||
|
{XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0},
|
||||||
|
{XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||||
|
{XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||||
|
{XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||||
|
{XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||||
|
{XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0},
|
||||||
|
{XK_KP_End, ControlMask, "\033[J", -1, 0},
|
||||||
|
{XK_KP_End, ControlMask, "\033[1;5F", +1, 0},
|
||||||
|
{XK_KP_End, ShiftMask, "\033[K", -1, 0},
|
||||||
|
{XK_KP_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||||
|
{XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||||
|
{XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||||
|
{XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||||
|
{XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||||
|
{XK_KP_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||||
|
{XK_KP_Insert, ControlMask, "\033[L", -1, 0},
|
||||||
|
{XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||||
|
{XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||||
|
{XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||||
|
{XK_KP_Delete, ControlMask, "\033[M", -1, 0},
|
||||||
|
{XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||||
|
{XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||||
|
{XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||||
|
{XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||||
|
{XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||||
|
{XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
|
||||||
|
{XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
|
||||||
|
{XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0},
|
||||||
|
{XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0},
|
||||||
|
{XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0},
|
||||||
|
{XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0},
|
||||||
|
{XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0},
|
||||||
|
{XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0},
|
||||||
|
{XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0},
|
||||||
|
{XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0},
|
||||||
|
{XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0},
|
||||||
|
{XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0},
|
||||||
|
{XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0},
|
||||||
|
{XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0},
|
||||||
|
{XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0},
|
||||||
|
{XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0},
|
||||||
|
{XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0},
|
||||||
|
{XK_Up, ShiftMask, "\033[1;2A", 0, 0},
|
||||||
|
{XK_Up, Mod1Mask, "\033[1;3A", 0, 0},
|
||||||
|
{XK_Up, ShiftMask | Mod1Mask, "\033[1;4A", 0, 0},
|
||||||
|
{XK_Up, ControlMask, "\033[1;5A", 0, 0},
|
||||||
|
{XK_Up, ShiftMask | ControlMask, "\033[1;6A", 0, 0},
|
||||||
|
{XK_Up, ControlMask | Mod1Mask, "\033[1;7A", 0, 0},
|
||||||
|
{XK_Up, ShiftMask | ControlMask | Mod1Mask, "\033[1;8A", 0, 0},
|
||||||
|
{XK_Up, XK_ANY_MOD, "\033[A", 0, -1},
|
||||||
|
{XK_Up, XK_ANY_MOD, "\033OA", 0, +1},
|
||||||
|
{XK_Down, ShiftMask, "\033[1;2B", 0, 0},
|
||||||
|
{XK_Down, Mod1Mask, "\033[1;3B", 0, 0},
|
||||||
|
{XK_Down, ShiftMask | Mod1Mask, "\033[1;4B", 0, 0},
|
||||||
|
{XK_Down, ControlMask, "\033[1;5B", 0, 0},
|
||||||
|
{XK_Down, ShiftMask | ControlMask, "\033[1;6B", 0, 0},
|
||||||
|
{XK_Down, ControlMask | Mod1Mask, "\033[1;7B", 0, 0},
|
||||||
|
{XK_Down, ShiftMask | ControlMask | Mod1Mask, "\033[1;8B", 0, 0},
|
||||||
|
{XK_Down, XK_ANY_MOD, "\033[B", 0, -1},
|
||||||
|
{XK_Down, XK_ANY_MOD, "\033OB", 0, +1},
|
||||||
|
{XK_Left, ShiftMask, "\033[1;2D", 0, 0},
|
||||||
|
{XK_Left, Mod1Mask, "\033[1;3D", 0, 0},
|
||||||
|
{XK_Left, ShiftMask | Mod1Mask, "\033[1;4D", 0, 0},
|
||||||
|
{XK_Left, ControlMask, "\033[1;5D", 0, 0},
|
||||||
|
{XK_Left, ShiftMask | ControlMask, "\033[1;6D", 0, 0},
|
||||||
|
{XK_Left, ControlMask | Mod1Mask, "\033[1;7D", 0, 0},
|
||||||
|
{XK_Left, ShiftMask | ControlMask | Mod1Mask, "\033[1;8D", 0, 0},
|
||||||
|
{XK_Left, XK_ANY_MOD, "\033[D", 0, -1},
|
||||||
|
{XK_Left, XK_ANY_MOD, "\033OD", 0, +1},
|
||||||
|
{XK_Right, ShiftMask, "\033[1;2C", 0, 0},
|
||||||
|
{XK_Right, Mod1Mask, "\033[1;3C", 0, 0},
|
||||||
|
{XK_Right, ShiftMask | Mod1Mask, "\033[1;4C", 0, 0},
|
||||||
|
{XK_Right, ControlMask, "\033[1;5C", 0, 0},
|
||||||
|
{XK_Right, ShiftMask | ControlMask, "\033[1;6C", 0, 0},
|
||||||
|
{XK_Right, ControlMask | Mod1Mask, "\033[1;7C", 0, 0},
|
||||||
|
{XK_Right, ShiftMask | ControlMask | Mod1Mask, "\033[1;8C", 0, 0},
|
||||||
|
{XK_Right, XK_ANY_MOD, "\033[C", 0, -1},
|
||||||
|
{XK_Right, XK_ANY_MOD, "\033OC", 0, +1},
|
||||||
|
{XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0},
|
||||||
|
{XK_Return, Mod1Mask, "\033\r", 0, 0},
|
||||||
|
{XK_Return, XK_ANY_MOD, "\r", 0, 0},
|
||||||
|
{XK_Insert, ShiftMask, "\033[4l", -1, 0},
|
||||||
|
{XK_Insert, ShiftMask, "\033[2;2~", +1, 0},
|
||||||
|
{XK_Insert, ControlMask, "\033[L", -1, 0},
|
||||||
|
{XK_Insert, ControlMask, "\033[2;5~", +1, 0},
|
||||||
|
{XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
|
||||||
|
{XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
|
||||||
|
{XK_Delete, ControlMask, "\033[M", -1, 0},
|
||||||
|
{XK_Delete, ControlMask, "\033[3;5~", +1, 0},
|
||||||
|
{XK_Delete, ShiftMask, "\033[2K", -1, 0},
|
||||||
|
{XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
|
||||||
|
{XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
|
||||||
|
{XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
|
||||||
|
{XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
|
||||||
|
{XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
|
||||||
|
{XK_Home, ShiftMask, "\033[2J", 0, -1},
|
||||||
|
{XK_Home, ShiftMask, "\033[1;2H", 0, +1},
|
||||||
|
{XK_Home, XK_ANY_MOD, "\033[H", 0, -1},
|
||||||
|
{XK_Home, XK_ANY_MOD, "\033[1~", 0, +1},
|
||||||
|
{XK_End, ControlMask, "\033[J", -1, 0},
|
||||||
|
{XK_End, ControlMask, "\033[1;5F", +1, 0},
|
||||||
|
{XK_End, ShiftMask, "\033[K", -1, 0},
|
||||||
|
{XK_End, ShiftMask, "\033[1;2F", +1, 0},
|
||||||
|
{XK_End, XK_ANY_MOD, "\033[4~", 0, 0},
|
||||||
|
{XK_Prior, ControlMask, "\033[5;5~", 0, 0},
|
||||||
|
{XK_Prior, ShiftMask, "\033[5;2~", 0, 0},
|
||||||
|
{XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
|
||||||
|
{XK_Next, ControlMask, "\033[6;5~", 0, 0},
|
||||||
|
{XK_Next, ShiftMask, "\033[6;2~", 0, 0},
|
||||||
|
{XK_Next, XK_ANY_MOD, "\033[6~", 0, 0},
|
||||||
|
{XK_F1, XK_NO_MOD, "\033OP", 0, 0},
|
||||||
|
{XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0},
|
||||||
|
{XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0},
|
||||||
|
{XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0},
|
||||||
|
{XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0},
|
||||||
|
{XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0},
|
||||||
|
{XK_F2, XK_NO_MOD, "\033OQ", 0, 0},
|
||||||
|
{XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0},
|
||||||
|
{XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0},
|
||||||
|
{XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0},
|
||||||
|
{XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0},
|
||||||
|
{XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0},
|
||||||
|
{XK_F3, XK_NO_MOD, "\033OR", 0, 0},
|
||||||
|
{XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0},
|
||||||
|
{XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0},
|
||||||
|
{XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0},
|
||||||
|
{XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0},
|
||||||
|
{XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0},
|
||||||
|
{XK_F4, XK_NO_MOD, "\033OS", 0, 0},
|
||||||
|
{XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0},
|
||||||
|
{XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0},
|
||||||
|
{XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0},
|
||||||
|
{XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0},
|
||||||
|
{XK_F5, XK_NO_MOD, "\033[15~", 0, 0},
|
||||||
|
{XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0},
|
||||||
|
{XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0},
|
||||||
|
{XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0},
|
||||||
|
{XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0},
|
||||||
|
{XK_F6, XK_NO_MOD, "\033[17~", 0, 0},
|
||||||
|
{XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0},
|
||||||
|
{XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0},
|
||||||
|
{XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0},
|
||||||
|
{XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0},
|
||||||
|
{XK_F7, XK_NO_MOD, "\033[18~", 0, 0},
|
||||||
|
{XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0},
|
||||||
|
{XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0},
|
||||||
|
{XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0},
|
||||||
|
{XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0},
|
||||||
|
{XK_F8, XK_NO_MOD, "\033[19~", 0, 0},
|
||||||
|
{XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0},
|
||||||
|
{XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0},
|
||||||
|
{XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0},
|
||||||
|
{XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0},
|
||||||
|
{XK_F9, XK_NO_MOD, "\033[20~", 0, 0},
|
||||||
|
{XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0},
|
||||||
|
{XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0},
|
||||||
|
{XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0},
|
||||||
|
{XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0},
|
||||||
|
{XK_F10, XK_NO_MOD, "\033[21~", 0, 0},
|
||||||
|
{XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0},
|
||||||
|
{XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0},
|
||||||
|
{XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0},
|
||||||
|
{XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0},
|
||||||
|
{XK_F11, XK_NO_MOD, "\033[23~", 0, 0},
|
||||||
|
{XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0},
|
||||||
|
{XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0},
|
||||||
|
{XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0},
|
||||||
|
{XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0},
|
||||||
|
{XK_F12, XK_NO_MOD, "\033[24~", 0, 0},
|
||||||
|
{XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0},
|
||||||
|
{XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0},
|
||||||
|
{XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0},
|
||||||
|
{XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0},
|
||||||
|
{XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0},
|
||||||
|
{XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0},
|
||||||
|
{XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0},
|
||||||
|
{XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0},
|
||||||
|
{XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0},
|
||||||
|
{XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0},
|
||||||
|
{XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0},
|
||||||
|
{XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0},
|
||||||
|
{XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0},
|
||||||
|
{XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0},
|
||||||
|
{XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0},
|
||||||
|
{XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0},
|
||||||
|
{XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0},
|
||||||
|
{XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0},
|
||||||
|
{XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0},
|
||||||
|
{XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0},
|
||||||
|
{XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0},
|
||||||
|
{XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0},
|
||||||
|
{XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0},
|
||||||
|
{XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0},
|
||||||
|
{XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0},
|
||||||
|
{XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0},
|
||||||
|
{XK_F35, XK_NO_MOD, "\033[23;5~", 0, 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.
|
||||||
|
*/
|
||||||
|
static uint selmasks[] = {
|
||||||
|
[SEL_RECTANGULAR] = Mod1Mask,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Printable characters in ASCII, used to estimate the advance width
|
||||||
|
* of single wide characters.
|
||||||
|
*/
|
||||||
|
static char ascii_printable[] = " !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||||
|
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||||
|
"`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# st version
|
# st version
|
||||||
VERSION = 0.9.2
|
VERSION = 0.9
|
||||||
|
|
||||||
# Customize below to fit your system
|
# Customize below to fit your system
|
||||||
|
|
||||||
@@ -15,10 +15,12 @@ PKG_CONFIG = pkg-config
|
|||||||
# includes and libs
|
# includes and libs
|
||||||
INCS = -I$(X11INC) \
|
INCS = -I$(X11INC) \
|
||||||
`$(PKG_CONFIG) --cflags fontconfig` \
|
`$(PKG_CONFIG) --cflags fontconfig` \
|
||||||
`$(PKG_CONFIG) --cflags freetype2`
|
`$(PKG_CONFIG) --cflags freetype2` \
|
||||||
|
`$(PKG_CONFIG) --cflags harfbuzz`
|
||||||
LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \
|
LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \
|
||||||
`$(PKG_CONFIG) --libs fontconfig` \
|
`$(PKG_CONFIG) --libs fontconfig` \
|
||||||
`$(PKG_CONFIG) --libs freetype2`
|
`$(PKG_CONFIG) --libs freetype2` \
|
||||||
|
`$(PKG_CONFIG) --libs harfbuzz`
|
||||||
|
|
||||||
# flags
|
# flags
|
||||||
STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600
|
STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600
|
||||||
@@ -34,3 +36,4 @@ STLDFLAGS = $(LIBS) $(LDFLAGS)
|
|||||||
|
|
||||||
# compiler and linker
|
# compiler and linker
|
||||||
# CC = c99
|
# CC = c99
|
||||||
|
|
||||||
|
|||||||
125
hb.c
Normal file
125
hb.c
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <X11/Xft/Xft.h>
|
||||||
|
#include <X11/cursorfont.h>
|
||||||
|
#include <hb.h>
|
||||||
|
#include <hb-ft.h>
|
||||||
|
|
||||||
|
#include "st.h"
|
||||||
|
#include "hb.h"
|
||||||
|
|
||||||
|
#define FEATURE(c1,c2,c3,c4) { .tag = HB_TAG(c1,c2,c3,c4), .value = 1, .start = HB_FEATURE_GLOBAL_START, .end = HB_FEATURE_GLOBAL_END }
|
||||||
|
#define BUFFER_STEP 256
|
||||||
|
|
||||||
|
hb_font_t *hbfindfont(XftFont *match);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
XftFont *match;
|
||||||
|
hb_font_t *font;
|
||||||
|
} HbFontMatch;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t capacity;
|
||||||
|
HbFontMatch *fonts;
|
||||||
|
} HbFontCache;
|
||||||
|
|
||||||
|
static HbFontCache hbfontcache = { 0, NULL };
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t capacity;
|
||||||
|
Rune *runes;
|
||||||
|
} RuneBuffer;
|
||||||
|
|
||||||
|
static RuneBuffer hbrunebuffer = { 0, NULL };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Poplulate the array with a list of font features, wrapped in FEATURE macro,
|
||||||
|
* e. g.
|
||||||
|
* FEATURE('c', 'a', 'l', 't'), FEATURE('d', 'l', 'i', 'g')
|
||||||
|
*/
|
||||||
|
hb_feature_t features[] = { };
|
||||||
|
|
||||||
|
void
|
||||||
|
hbunloadfonts()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < hbfontcache.capacity; i++) {
|
||||||
|
hb_font_destroy(hbfontcache.fonts[i].font);
|
||||||
|
XftUnlockFace(hbfontcache.fonts[i].match);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hbfontcache.fonts != NULL) {
|
||||||
|
free(hbfontcache.fonts);
|
||||||
|
hbfontcache.fonts = NULL;
|
||||||
|
}
|
||||||
|
hbfontcache.capacity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hb_font_t *
|
||||||
|
hbfindfont(XftFont *match)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < hbfontcache.capacity; i++) {
|
||||||
|
if (hbfontcache.fonts[i].match == match)
|
||||||
|
return hbfontcache.fonts[i].font;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Font not found in cache, caching it now. */
|
||||||
|
hbfontcache.fonts = realloc(hbfontcache.fonts, sizeof(HbFontMatch) * (hbfontcache.capacity + 1));
|
||||||
|
FT_Face face = XftLockFace(match);
|
||||||
|
hb_font_t *font = hb_ft_font_create(face, NULL);
|
||||||
|
if (font == NULL)
|
||||||
|
die("Failed to load Harfbuzz font.");
|
||||||
|
|
||||||
|
hbfontcache.fonts[hbfontcache.capacity].match = match;
|
||||||
|
hbfontcache.fonts[hbfontcache.capacity].font = font;
|
||||||
|
hbfontcache.capacity += 1;
|
||||||
|
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hbtransform(HbTransformData *data, XftFont *xfont, const Glyph *glyphs, int start, int length) {
|
||||||
|
ushort mode = USHRT_MAX;
|
||||||
|
unsigned int glyph_count;
|
||||||
|
int rune_idx, glyph_idx, end = start + length;
|
||||||
|
|
||||||
|
hb_font_t *font = hbfindfont(xfont);
|
||||||
|
if (font == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hb_buffer_t *buffer = hb_buffer_create();
|
||||||
|
hb_buffer_set_direction(buffer, HB_DIRECTION_LTR);
|
||||||
|
hb_buffer_set_cluster_level(buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
|
||||||
|
|
||||||
|
/* Resize the buffer if required length is larger. */
|
||||||
|
if (hbrunebuffer.capacity < length) {
|
||||||
|
hbrunebuffer.capacity = (length / BUFFER_STEP + 1) * BUFFER_STEP;
|
||||||
|
hbrunebuffer.runes = realloc(hbrunebuffer.runes, hbrunebuffer.capacity * sizeof(Rune));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill buffer with codepoints. */
|
||||||
|
for (rune_idx = 0, glyph_idx = start; glyph_idx < end; glyph_idx++, rune_idx++) {
|
||||||
|
hbrunebuffer.runes[rune_idx] = glyphs[glyph_idx].u;
|
||||||
|
mode = glyphs[glyph_idx].mode;
|
||||||
|
if (mode & ATTR_WDUMMY)
|
||||||
|
hbrunebuffer.runes[rune_idx] = 0x0020;
|
||||||
|
}
|
||||||
|
hb_buffer_add_codepoints(buffer, hbrunebuffer.runes, length, 0, length);
|
||||||
|
|
||||||
|
/* Shape the segment. */
|
||||||
|
hb_shape(font, buffer, features, sizeof(features)/sizeof(hb_feature_t));
|
||||||
|
|
||||||
|
/* Get new glyph info. */
|
||||||
|
hb_glyph_info_t *info = hb_buffer_get_glyph_infos(buffer, &glyph_count);
|
||||||
|
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions(buffer, &glyph_count);
|
||||||
|
|
||||||
|
/* Fill the output. */
|
||||||
|
data->buffer = buffer;
|
||||||
|
data->glyphs = info;
|
||||||
|
data->positions = pos;
|
||||||
|
data->count = glyph_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hbcleanup(HbTransformData *data) {
|
||||||
|
hb_buffer_destroy(data->buffer);
|
||||||
|
memset(data, 0, sizeof(HbTransformData));
|
||||||
|
}
|
||||||
14
hb.h
Normal file
14
hb.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#include <X11/Xft/Xft.h>
|
||||||
|
#include <hb.h>
|
||||||
|
#include <hb-ft.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
hb_buffer_t *buffer;
|
||||||
|
hb_glyph_info_t *glyphs;
|
||||||
|
hb_glyph_position_t *positions;
|
||||||
|
unsigned int count;
|
||||||
|
} HbTransformData;
|
||||||
|
|
||||||
|
void hbunloadfonts();
|
||||||
|
void hbtransform(HbTransformData *, XftFont *, const Glyph *, int, int);
|
||||||
|
void hbcleanup(HbTransformData *);
|
||||||
5
st.h
5
st.h
@@ -11,7 +11,8 @@
|
|||||||
#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d))
|
#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d))
|
||||||
#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
|
#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
|
||||||
#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 & (~ATTR_WRAP)) != ((b).mode & (~ATTR_WRAP)) || \
|
||||||
|
(a).fg != (b).fg || \
|
||||||
(a).bg != (b).bg)
|
(a).bg != (b).bg)
|
||||||
#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)
|
||||||
@@ -81,6 +82,8 @@ void die(const char *, ...);
|
|||||||
void redraw(void);
|
void redraw(void);
|
||||||
void draw(void);
|
void draw(void);
|
||||||
|
|
||||||
|
void kscrolldown(const Arg *);
|
||||||
|
void kscrollup(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 *);
|
||||||
|
|||||||
129
st.h.orig
Normal file
129
st.h.orig
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
/* See LICENSE for license details. */
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
/* macros */
|
||||||
|
#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 ATTRCMP(a, b) (((a).mode & (~ATTR_WRAP)) != ((b).mode & (~ATTR_WRAP)) || \
|
||||||
|
(a).fg != (b).fg || \
|
||||||
|
(a).bg != (b).bg)
|
||||||
|
#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 TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b))
|
||||||
|
#define IS_TRUECOL(x) (1 << 24 & (x))
|
||||||
|
|
||||||
|
enum glyph_attribute {
|
||||||
|
ATTR_NULL = 0,
|
||||||
|
ATTR_BOLD = 1 << 0,
|
||||||
|
ATTR_FAINT = 1 << 1,
|
||||||
|
ATTR_ITALIC = 1 << 2,
|
||||||
|
ATTR_UNDERLINE = 1 << 3,
|
||||||
|
ATTR_BLINK = 1 << 4,
|
||||||
|
ATTR_REVERSE = 1 << 5,
|
||||||
|
ATTR_INVISIBLE = 1 << 6,
|
||||||
|
ATTR_STRUCK = 1 << 7,
|
||||||
|
ATTR_WRAP = 1 << 8,
|
||||||
|
ATTR_WIDE = 1 << 9,
|
||||||
|
ATTR_WDUMMY = 1 << 10,
|
||||||
|
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum selection_mode {
|
||||||
|
SEL_IDLE = 0,
|
||||||
|
SEL_EMPTY = 1,
|
||||||
|
SEL_READY = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum selection_type {
|
||||||
|
SEL_REGULAR = 1,
|
||||||
|
SEL_RECTANGULAR = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum selection_snap {
|
||||||
|
SNAP_WORD = 1,
|
||||||
|
SNAP_LINE = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef unsigned char uchar;
|
||||||
|
typedef unsigned int uint;
|
||||||
|
typedef unsigned long ulong;
|
||||||
|
typedef unsigned short ushort;
|
||||||
|
|
||||||
|
typedef uint_least32_t Rune;
|
||||||
|
|
||||||
|
#define Glyph Glyph_
|
||||||
|
typedef struct {
|
||||||
|
Rune u; /* character code */
|
||||||
|
ushort mode; /* attribute flags */
|
||||||
|
uint32_t fg; /* foreground */
|
||||||
|
uint32_t bg; /* background */
|
||||||
|
} Glyph;
|
||||||
|
|
||||||
|
typedef Glyph *Line;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
int i;
|
||||||
|
uint ui;
|
||||||
|
float f;
|
||||||
|
const void *v;
|
||||||
|
const char *s;
|
||||||
|
} Arg;
|
||||||
|
|
||||||
|
void die(const char *, ...);
|
||||||
|
void redraw(void);
|
||||||
|
void draw(void);
|
||||||
|
|
||||||
|
void kscrolldown(const Arg *);
|
||||||
|
void kscrollup(const Arg *);
|
||||||
|
void printscreen(const Arg *);
|
||||||
|
void printsel(const Arg *);
|
||||||
|
void sendbreak(const Arg *);
|
||||||
|
void toggleprinter(const Arg *);
|
||||||
|
|
||||||
|
int tattrset(int);
|
||||||
|
void tnew(int, int);
|
||||||
|
void tresize(int, int);
|
||||||
|
void tsetdirtattr(int);
|
||||||
|
void ttyhangup(void);
|
||||||
|
int ttynew(const char *, char *, const char *, char **);
|
||||||
|
size_t ttyread(void);
|
||||||
|
void ttyresize(int, int);
|
||||||
|
void ttywrite(const char *, size_t, int);
|
||||||
|
|
||||||
|
void resettitle(void);
|
||||||
|
|
||||||
|
void selclear(void);
|
||||||
|
void selinit(void);
|
||||||
|
void selstart(int, int, int);
|
||||||
|
void selextend(int, int, int, int);
|
||||||
|
int selected(int, int);
|
||||||
|
char *getsel(void);
|
||||||
|
|
||||||
|
size_t utf8encode(Rune, char *);
|
||||||
|
|
||||||
|
void *xmalloc(size_t);
|
||||||
|
void *xrealloc(void *, size_t);
|
||||||
|
char *xstrdup(const char *);
|
||||||
|
|
||||||
|
/* config.h globals */
|
||||||
|
extern char *utmp;
|
||||||
|
extern char *scroll;
|
||||||
|
extern char *stty_args;
|
||||||
|
extern char *vtiden;
|
||||||
|
extern wchar_t *worddelimiters;
|
||||||
|
extern int allowaltscreen;
|
||||||
|
extern int allowwindowops;
|
||||||
|
extern char *termname;
|
||||||
|
extern unsigned int tabspaces;
|
||||||
|
extern unsigned int defaultfg;
|
||||||
|
extern unsigned int defaultbg;
|
||||||
|
extern unsigned int defaultcs;
|
||||||
2
win.h
2
win.h
@@ -25,7 +25,7 @@ enum win_mode {
|
|||||||
|
|
||||||
void xbell(void);
|
void xbell(void);
|
||||||
void xclipcopy(void);
|
void xclipcopy(void);
|
||||||
void xdrawcursor(int, int, Glyph, int, int, Glyph);
|
void xdrawcursor(int, int, Glyph, int, int, Glyph, Line, int);
|
||||||
void xdrawline(Line, int, int, int);
|
void xdrawline(Line, int, int, int);
|
||||||
void xfinishdraw(void);
|
void xfinishdraw(void);
|
||||||
void xloadcols(void);
|
void xloadcols(void);
|
||||||
|
|||||||
445
x.c
445
x.c
@@ -4,6 +4,7 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -19,6 +20,7 @@ char *argv0;
|
|||||||
#include "arg.h"
|
#include "arg.h"
|
||||||
#include "st.h"
|
#include "st.h"
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
|
#include "hb.h"
|
||||||
|
|
||||||
/* types used in config.h */
|
/* types used in config.h */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -141,8 +143,9 @@ typedef struct {
|
|||||||
} DC;
|
} DC;
|
||||||
|
|
||||||
static inline ushort sixd_to_16bit(int);
|
static inline ushort sixd_to_16bit(int);
|
||||||
|
static void xresetfontsettings(ushort mode, Font **font, int *frcflags);
|
||||||
static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int);
|
static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int);
|
||||||
static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
|
static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int, int);
|
||||||
static void xdrawglyph(Glyph, int, int);
|
static void xdrawglyph(Glyph, int, int);
|
||||||
static void xclear(int, int, int, int);
|
static void xclear(int, int, int, int);
|
||||||
static int xgeommasktogravity(int);
|
static int xgeommasktogravity(int);
|
||||||
@@ -157,6 +160,8 @@ static void xhints(void);
|
|||||||
static int xloadcolor(int, const char *, Color *);
|
static int xloadcolor(int, const char *, Color *);
|
||||||
static int xloadfont(Font *, FcPattern *);
|
static int xloadfont(Font *, FcPattern *);
|
||||||
static void xloadfonts(const char *, double);
|
static void xloadfonts(const char *, double);
|
||||||
|
static int xloadsparefont(FcPattern *, int);
|
||||||
|
static void xloadsparefonts(void);
|
||||||
static void xunloadfont(Font *);
|
static void xunloadfont(Font *);
|
||||||
static void xunloadfonts(void);
|
static void xunloadfonts(void);
|
||||||
static void xsetenv(void);
|
static void xsetenv(void);
|
||||||
@@ -253,6 +258,7 @@ static char *opt_name = NULL;
|
|||||||
static char *opt_title = NULL;
|
static char *opt_title = NULL;
|
||||||
|
|
||||||
static uint buttons; /* bit field of pressed buttons */
|
static uint buttons; /* bit field of pressed buttons */
|
||||||
|
static int cursorblinks = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
clipcopy(const Arg *dummy)
|
clipcopy(const Arg *dummy)
|
||||||
@@ -306,6 +312,7 @@ zoomabs(const Arg *arg)
|
|||||||
{
|
{
|
||||||
xunloadfonts();
|
xunloadfonts();
|
||||||
xloadfonts(usedfont, arg->f);
|
xloadfonts(usedfont, arg->f);
|
||||||
|
xloadsparefonts();
|
||||||
cresize(0, 0);
|
cresize(0, 0);
|
||||||
redraw();
|
redraw();
|
||||||
xhints();
|
xhints();
|
||||||
@@ -757,7 +764,7 @@ xresize(int col, int row)
|
|||||||
xclear(0, 0, win.w, win.h);
|
xclear(0, 0, win.w, win.h);
|
||||||
|
|
||||||
/* resize to new width */
|
/* resize to new width */
|
||||||
xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec));
|
xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec) * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
ushort
|
ushort
|
||||||
@@ -1050,6 +1057,101 @@ xloadfonts(const char *fontstr, double fontsize)
|
|||||||
FcPatternDestroy(pattern);
|
FcPatternDestroy(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xloadsparefont(FcPattern *pattern, int flags)
|
||||||
|
{
|
||||||
|
FcPattern *match;
|
||||||
|
FcResult result;
|
||||||
|
|
||||||
|
match = FcFontMatch(NULL, pattern, &result);
|
||||||
|
if (!match) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(frc[frclen].font = XftFontOpenPattern(xw.dpy, match))) {
|
||||||
|
FcPatternDestroy(match);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
frc[frclen].flags = flags;
|
||||||
|
/* Believe U+0000 glyph will present in each default font */
|
||||||
|
frc[frclen].unicodep = 0;
|
||||||
|
frclen++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xloadsparefonts(void)
|
||||||
|
{
|
||||||
|
FcPattern *pattern;
|
||||||
|
double sizeshift, fontval;
|
||||||
|
int fc;
|
||||||
|
char **fp;
|
||||||
|
|
||||||
|
if (frclen != 0)
|
||||||
|
die("can't embed spare fonts. cache isn't empty");
|
||||||
|
|
||||||
|
/* Calculate count of spare fonts */
|
||||||
|
fc = sizeof(font2) / sizeof(*font2);
|
||||||
|
if (fc == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Allocate memory for cache entries. */
|
||||||
|
if (frccap < 4 * fc) {
|
||||||
|
frccap += 4 * fc - frccap;
|
||||||
|
frc = xrealloc(frc, frccap * sizeof(Fontcache));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (fp = font2; fp - font2 < fc; ++fp) {
|
||||||
|
|
||||||
|
if (**fp == '-')
|
||||||
|
pattern = XftXlfdParse(*fp, False, False);
|
||||||
|
else
|
||||||
|
pattern = FcNameParse((FcChar8 *)*fp);
|
||||||
|
|
||||||
|
if (!pattern)
|
||||||
|
die("can't open spare font %s\n", *fp);
|
||||||
|
|
||||||
|
if (defaultfontsize > 0) {
|
||||||
|
sizeshift = usedfontsize - defaultfontsize;
|
||||||
|
if (sizeshift != 0 &&
|
||||||
|
FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) ==
|
||||||
|
FcResultMatch) {
|
||||||
|
fontval += sizeshift;
|
||||||
|
FcPatternDel(pattern, FC_PIXEL_SIZE);
|
||||||
|
FcPatternDel(pattern, FC_SIZE);
|
||||||
|
FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FcPatternAddBool(pattern, FC_SCALABLE, 1);
|
||||||
|
|
||||||
|
FcConfigSubstitute(NULL, pattern, FcMatchPattern);
|
||||||
|
XftDefaultSubstitute(xw.dpy, xw.scr, pattern);
|
||||||
|
|
||||||
|
if (xloadsparefont(pattern, FRC_NORMAL))
|
||||||
|
die("can't open spare font %s\n", *fp);
|
||||||
|
|
||||||
|
FcPatternDel(pattern, FC_SLANT);
|
||||||
|
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
|
||||||
|
if (xloadsparefont(pattern, FRC_ITALIC))
|
||||||
|
die("can't open spare font %s\n", *fp);
|
||||||
|
|
||||||
|
FcPatternDel(pattern, FC_WEIGHT);
|
||||||
|
FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
|
||||||
|
if (xloadsparefont(pattern, FRC_ITALICBOLD))
|
||||||
|
die("can't open spare font %s\n", *fp);
|
||||||
|
|
||||||
|
FcPatternDel(pattern, FC_SLANT);
|
||||||
|
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
|
||||||
|
if (xloadsparefont(pattern, FRC_BOLD))
|
||||||
|
die("can't open spare font %s\n", *fp);
|
||||||
|
|
||||||
|
FcPatternDestroy(pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xunloadfont(Font *f)
|
xunloadfont(Font *f)
|
||||||
{
|
{
|
||||||
@@ -1062,6 +1164,9 @@ xunloadfont(Font *f)
|
|||||||
void
|
void
|
||||||
xunloadfonts(void)
|
xunloadfonts(void)
|
||||||
{
|
{
|
||||||
|
/* Clear Harfbuzz font cache. */
|
||||||
|
hbunloadfonts();
|
||||||
|
|
||||||
/* Free the loaded fonts in the font cache. */
|
/* Free the loaded fonts in the font cache. */
|
||||||
while (frclen > 0)
|
while (frclen > 0)
|
||||||
XftFontClose(xw.dpy, frc[--frclen].font);
|
XftFontClose(xw.dpy, frc[--frclen].font);
|
||||||
@@ -1145,7 +1250,11 @@ xinit(int cols, int rows)
|
|||||||
die("could not init fontconfig.\n");
|
die("could not init fontconfig.\n");
|
||||||
|
|
||||||
usedfont = (opt_font == NULL)? font : opt_font;
|
usedfont = (opt_font == NULL)? font : opt_font;
|
||||||
xloadfonts(usedfont, 0);
|
|
||||||
|
xloadfonts(usedfont, defaultfontsize);
|
||||||
|
|
||||||
|
/* spare fonts */
|
||||||
|
xloadsparefonts();
|
||||||
|
|
||||||
/* colors */
|
/* colors */
|
||||||
xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
|
xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
|
||||||
@@ -1188,7 +1297,7 @@ xinit(int cols, int rows)
|
|||||||
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
|
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
|
||||||
|
|
||||||
/* font spec buffer */
|
/* font spec buffer */
|
||||||
xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec));
|
xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec) * 4);
|
||||||
|
|
||||||
/* Xft rendering context */
|
/* Xft rendering context */
|
||||||
xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
|
xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
|
||||||
@@ -1242,6 +1351,22 @@ xinit(int cols, int rows)
|
|||||||
xsel.xtarget = XA_STRING;
|
xsel.xtarget = XA_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xresetfontsettings(ushort mode, Font **font, int *frcflags)
|
||||||
|
{
|
||||||
|
*font = &dc.font;
|
||||||
|
if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) {
|
||||||
|
*font = &dc.ibfont;
|
||||||
|
*frcflags = FRC_ITALICBOLD;
|
||||||
|
} else if (mode & ATTR_ITALIC) {
|
||||||
|
*font = &dc.ifont;
|
||||||
|
*frcflags = FRC_ITALIC;
|
||||||
|
} else if (mode & ATTR_BOLD) {
|
||||||
|
*font = &dc.bfont;
|
||||||
|
*frcflags = FRC_BOLD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
|
xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
|
||||||
{
|
{
|
||||||
@@ -1256,128 +1381,156 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
|
|||||||
FcPattern *fcpattern, *fontpattern;
|
FcPattern *fcpattern, *fontpattern;
|
||||||
FcFontSet *fcsets[] = { NULL };
|
FcFontSet *fcsets[] = { NULL };
|
||||||
FcCharSet *fccharset;
|
FcCharSet *fccharset;
|
||||||
int i, f, numspecs = 0;
|
int i, f, length = 0, start = 0, numspecs = 0;
|
||||||
|
float cluster_xp = xp, cluster_yp = yp;
|
||||||
|
HbTransformData shaped = { 0 };
|
||||||
|
|
||||||
|
/* Initial values. */
|
||||||
|
mode = prevmode = glyphs[0].mode & ~ATTR_WRAP;
|
||||||
|
xresetfontsettings(mode, &font, &frcflags);
|
||||||
|
|
||||||
for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) {
|
for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) {
|
||||||
/* Fetch rune and mode for current glyph. */
|
mode = glyphs[i].mode & ~ATTR_WRAP;
|
||||||
rune = glyphs[i].u;
|
|
||||||
mode = glyphs[i].mode;
|
|
||||||
|
|
||||||
/* Skip dummy wide-character spacing. */
|
/* Skip dummy wide-character spacing. */
|
||||||
if (mode == ATTR_WDUMMY)
|
if (mode & ATTR_WDUMMY && i < (len - 1))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Determine font for glyph if different from previous glyph. */
|
if (
|
||||||
if (prevmode != mode) {
|
prevmode != mode
|
||||||
prevmode = mode;
|
|| ATTRCMP(glyphs[start], glyphs[i])
|
||||||
font = &dc.font;
|
|| selected(x + i, y) != selected(x + start, y)
|
||||||
frcflags = FRC_NORMAL;
|
|| i == (len - 1)
|
||||||
runewidth = win.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f);
|
) {
|
||||||
if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) {
|
/* Handle 1-character wide segments and end of line */
|
||||||
font = &dc.ibfont;
|
length = i - start;
|
||||||
frcflags = FRC_ITALICBOLD;
|
if (i == start) {
|
||||||
} else if (mode & ATTR_ITALIC) {
|
length = 1;
|
||||||
font = &dc.ifont;
|
} else if (i == (len - 1)) {
|
||||||
frcflags = FRC_ITALIC;
|
length = (i - start + 1);
|
||||||
} else if (mode & ATTR_BOLD) {
|
|
||||||
font = &dc.bfont;
|
|
||||||
frcflags = FRC_BOLD;
|
|
||||||
}
|
|
||||||
yp = winy + font->ascent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lookup character index with default font. */
|
|
||||||
glyphidx = XftCharIndex(xw.dpy, font->match, rune);
|
|
||||||
if (glyphidx) {
|
|
||||||
specs[numspecs].font = font->match;
|
|
||||||
specs[numspecs].glyph = glyphidx;
|
|
||||||
specs[numspecs].x = (short)xp;
|
|
||||||
specs[numspecs].y = (short)yp;
|
|
||||||
xp += runewidth;
|
|
||||||
numspecs++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fallback on font cache, search the font cache for match. */
|
|
||||||
for (f = 0; f < frclen; f++) {
|
|
||||||
glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune);
|
|
||||||
/* Everything correct. */
|
|
||||||
if (glyphidx && frc[f].flags == frcflags)
|
|
||||||
break;
|
|
||||||
/* We got a default font for a not found glyph. */
|
|
||||||
if (!glyphidx && frc[f].flags == frcflags
|
|
||||||
&& frc[f].unicodep == rune) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nothing was found. Use fontconfig to find matching font. */
|
|
||||||
if (f >= frclen) {
|
|
||||||
if (!font->set)
|
|
||||||
font->set = FcFontSort(0, font->pattern,
|
|
||||||
1, 0, &fcres);
|
|
||||||
fcsets[0] = font->set;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Nothing was found in the cache. Now use
|
|
||||||
* some dozen of Fontconfig calls to get the
|
|
||||||
* font for one single character.
|
|
||||||
*
|
|
||||||
* Xft and fontconfig are design failures.
|
|
||||||
*/
|
|
||||||
fcpattern = FcPatternDuplicate(font->pattern);
|
|
||||||
fccharset = FcCharSetCreate();
|
|
||||||
|
|
||||||
FcCharSetAddChar(fccharset, rune);
|
|
||||||
FcPatternAddCharSet(fcpattern, FC_CHARSET,
|
|
||||||
fccharset);
|
|
||||||
FcPatternAddBool(fcpattern, FC_SCALABLE, 1);
|
|
||||||
|
|
||||||
FcConfigSubstitute(0, fcpattern,
|
|
||||||
FcMatchPattern);
|
|
||||||
FcDefaultSubstitute(fcpattern);
|
|
||||||
|
|
||||||
fontpattern = FcFontSetMatch(0, fcsets, 1,
|
|
||||||
fcpattern, &fcres);
|
|
||||||
|
|
||||||
/* Allocate memory for the new cache entry. */
|
|
||||||
if (frclen >= frccap) {
|
|
||||||
frccap += 16;
|
|
||||||
frc = xrealloc(frc, frccap * sizeof(Fontcache));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
frc[frclen].font = XftFontOpenPattern(xw.dpy,
|
/* Shape the segment. */
|
||||||
fontpattern);
|
hbtransform(&shaped, font->match, glyphs, start, length);
|
||||||
if (!frc[frclen].font)
|
runewidth = win.cw * ((glyphs[start].mode & ATTR_WIDE) ? 2.0f : 1.0f);
|
||||||
die("XftFontOpenPattern failed seeking fallback font: %s\n",
|
cluster_xp = xp; cluster_yp = yp;
|
||||||
strerror(errno));
|
for (int code_idx = 0; code_idx < shaped.count; code_idx++) {
|
||||||
frc[frclen].flags = frcflags;
|
int idx = shaped.glyphs[code_idx].cluster;
|
||||||
frc[frclen].unicodep = rune;
|
|
||||||
|
|
||||||
glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune);
|
if (glyphs[start + idx].mode & ATTR_WDUMMY)
|
||||||
|
continue;
|
||||||
|
|
||||||
f = frclen;
|
/* Advance the drawing cursor if we've moved to a new cluster */
|
||||||
frclen++;
|
if (code_idx > 0 && idx != shaped.glyphs[code_idx - 1].cluster) {
|
||||||
|
xp += runewidth;
|
||||||
|
cluster_xp = xp;
|
||||||
|
cluster_yp = yp;
|
||||||
|
runewidth = win.cw * ((glyphs[start + idx].mode & ATTR_WIDE) ? 2.0f : 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
FcPatternDestroy(fcpattern);
|
if (shaped.glyphs[code_idx].codepoint != 0) {
|
||||||
FcCharSetDestroy(fccharset);
|
/* If symbol is found, put it into the specs. */
|
||||||
|
specs[numspecs].font = font->match;
|
||||||
|
specs[numspecs].glyph = shaped.glyphs[code_idx].codepoint;
|
||||||
|
specs[numspecs].x = cluster_xp + (short)(shaped.positions[code_idx].x_offset / 64.);
|
||||||
|
specs[numspecs].y = cluster_yp - (short)(shaped.positions[code_idx].y_offset / 64.);
|
||||||
|
cluster_xp += shaped.positions[code_idx].x_advance / 64.;
|
||||||
|
cluster_yp += shaped.positions[code_idx].y_advance / 64.;
|
||||||
|
numspecs++;
|
||||||
|
} else {
|
||||||
|
/* If it's not found, try to fetch it through the font cache. */
|
||||||
|
rune = glyphs[start + idx].u;
|
||||||
|
for (f = 0; f < frclen; f++) {
|
||||||
|
glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune);
|
||||||
|
/* Everything correct. */
|
||||||
|
if (glyphidx && frc[f].flags == frcflags)
|
||||||
|
break;
|
||||||
|
/* We got a default font for a not found glyph. */
|
||||||
|
if (!glyphidx && frc[f].flags == frcflags
|
||||||
|
&& frc[f].unicodep == rune) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nothing was found. Use fontconfig to find matching font. */
|
||||||
|
if (f >= frclen) {
|
||||||
|
if (!font->set)
|
||||||
|
font->set = FcFontSort(0, font->pattern,
|
||||||
|
1, 0, &fcres);
|
||||||
|
fcsets[0] = font->set;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Nothing was found in the cache. Now use
|
||||||
|
* some dozen of Fontconfig calls to get the
|
||||||
|
* font for one single character.
|
||||||
|
*
|
||||||
|
* Xft and fontconfig are design failures.
|
||||||
|
*/
|
||||||
|
fcpattern = FcPatternDuplicate(font->pattern);
|
||||||
|
fccharset = FcCharSetCreate();
|
||||||
|
|
||||||
|
FcCharSetAddChar(fccharset, rune);
|
||||||
|
FcPatternAddCharSet(fcpattern, FC_CHARSET,
|
||||||
|
fccharset);
|
||||||
|
FcPatternAddBool(fcpattern, FC_SCALABLE, 1);
|
||||||
|
|
||||||
|
FcConfigSubstitute(0, fcpattern,
|
||||||
|
FcMatchPattern);
|
||||||
|
FcDefaultSubstitute(fcpattern);
|
||||||
|
|
||||||
|
fontpattern = FcFontSetMatch(0, fcsets, 1,
|
||||||
|
fcpattern, &fcres);
|
||||||
|
|
||||||
|
/* Allocate memory for the new cache entry. */
|
||||||
|
if (frclen >= frccap) {
|
||||||
|
frccap += 16;
|
||||||
|
frc = xrealloc(frc, frccap * sizeof(Fontcache));
|
||||||
|
}
|
||||||
|
|
||||||
|
frc[frclen].font = XftFontOpenPattern(xw.dpy,
|
||||||
|
fontpattern);
|
||||||
|
if (!frc[frclen].font)
|
||||||
|
die("XftFontOpenPattern failed seeking fallback font: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
frc[frclen].flags = frcflags;
|
||||||
|
frc[frclen].unicodep = rune;
|
||||||
|
|
||||||
|
glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune);
|
||||||
|
|
||||||
|
f = frclen;
|
||||||
|
frclen++;
|
||||||
|
|
||||||
|
FcPatternDestroy(fcpattern);
|
||||||
|
FcCharSetDestroy(fccharset);
|
||||||
|
}
|
||||||
|
|
||||||
|
specs[numspecs].font = frc[f].font;
|
||||||
|
specs[numspecs].glyph = glyphidx;
|
||||||
|
specs[numspecs].x = (short)xp;
|
||||||
|
specs[numspecs].y = (short)yp;
|
||||||
|
numspecs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cleanup and get ready for next segment. */
|
||||||
|
hbcleanup(&shaped);
|
||||||
|
start = i;
|
||||||
|
|
||||||
|
/* Determine font for glyph if different from previous glyph. */
|
||||||
|
if (prevmode != mode) {
|
||||||
|
prevmode = mode;
|
||||||
|
xresetfontsettings(mode, &font, &frcflags);
|
||||||
|
yp = winy + font->ascent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
specs[numspecs].font = frc[f].font;
|
|
||||||
specs[numspecs].glyph = glyphidx;
|
|
||||||
specs[numspecs].x = (short)xp;
|
|
||||||
specs[numspecs].y = (short)yp;
|
|
||||||
xp += runewidth;
|
|
||||||
numspecs++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return numspecs;
|
return numspecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)
|
xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y, int charlen)
|
||||||
{
|
{
|
||||||
int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
|
|
||||||
int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch,
|
int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch,
|
||||||
width = charlen * win.cw;
|
width = charlen * win.cw;
|
||||||
Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
|
Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
|
||||||
@@ -1513,21 +1666,24 @@ void
|
|||||||
xdrawglyph(Glyph g, int x, int y)
|
xdrawglyph(Glyph g, int x, int y)
|
||||||
{
|
{
|
||||||
int numspecs;
|
int numspecs;
|
||||||
XftGlyphFontSpec spec;
|
XftGlyphFontSpec *specs = xw.specbuf;
|
||||||
|
|
||||||
numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y);
|
numspecs = xmakeglyphfontspecs(specs, &g, 1, x, y);
|
||||||
xdrawglyphfontspecs(&spec, g, numspecs, x, y);
|
xdrawglyphfontspecs(specs, g, numspecs, x, y, (g.mode & ATTR_WIDE) ? 2 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
|
xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int len)
|
||||||
{
|
{
|
||||||
Color drawcol;
|
Color drawcol;
|
||||||
|
|
||||||
/* remove the old cursor */
|
/* remove the old cursor */
|
||||||
if (selected(ox, oy))
|
if (selected(ox, oy))
|
||||||
og.mode ^= ATTR_REVERSE;
|
og.mode ^= ATTR_REVERSE;
|
||||||
xdrawglyph(og, ox, oy);
|
|
||||||
|
/* Redraw the line where cursor was previously.
|
||||||
|
* It will restore the ligatures broken by the cursor. */
|
||||||
|
xdrawline(line, 0, oy, len);
|
||||||
|
|
||||||
if (IS_SET(MODE_HIDE))
|
if (IS_SET(MODE_HIDE))
|
||||||
return;
|
return;
|
||||||
@@ -1561,29 +1717,44 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
|
|||||||
/* draw the new one */
|
/* draw the new one */
|
||||||
if (IS_SET(MODE_FOCUSED)) {
|
if (IS_SET(MODE_FOCUSED)) {
|
||||||
switch (win.cursor) {
|
switch (win.cursor) {
|
||||||
case 7: /* st extension */
|
default:
|
||||||
g.u = 0x2603; /* snowman (U+2603) */
|
case 0: /* blinking block */
|
||||||
|
case 1: /* blinking block (default) */
|
||||||
|
if (IS_SET(MODE_BLINK))
|
||||||
|
break;
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case 0: /* Blinking Block */
|
case 2: /* steady block */
|
||||||
case 1: /* Blinking Block (Default) */
|
|
||||||
case 2: /* Steady Block */
|
|
||||||
xdrawglyph(g, cx, cy);
|
xdrawglyph(g, cx, cy);
|
||||||
break;
|
break;
|
||||||
case 3: /* Blinking Underline */
|
case 3: /* blinking underline */
|
||||||
case 4: /* Steady Underline */
|
if (IS_SET(MODE_BLINK))
|
||||||
|
break;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 4: /* steady underline */
|
||||||
XftDrawRect(xw.draw, &drawcol,
|
XftDrawRect(xw.draw, &drawcol,
|
||||||
borderpx + cx * win.cw,
|
borderpx + cx * win.cw,
|
||||||
borderpx + (cy + 1) * win.ch - \
|
borderpx + (cy + 1) * win.ch - \
|
||||||
cursorthickness,
|
cursorthickness,
|
||||||
win.cw, cursorthickness);
|
win.cw, cursorthickness);
|
||||||
break;
|
break;
|
||||||
case 5: /* Blinking bar */
|
case 5: /* blinking bar */
|
||||||
case 6: /* Steady bar */
|
if (IS_SET(MODE_BLINK))
|
||||||
|
break;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 6: /* steady bar */
|
||||||
XftDrawRect(xw.draw, &drawcol,
|
XftDrawRect(xw.draw, &drawcol,
|
||||||
borderpx + cx * win.cw,
|
borderpx + cx * win.cw,
|
||||||
borderpx + cy * win.ch,
|
borderpx + cy * win.ch,
|
||||||
cursorthickness, win.ch);
|
cursorthickness, win.ch);
|
||||||
break;
|
break;
|
||||||
|
case 7: /* blinking st cursor */
|
||||||
|
if (IS_SET(MODE_BLINK))
|
||||||
|
break;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 8: /* steady st cursor */
|
||||||
|
g.u = (unsigned int) xsetcursor;
|
||||||
|
xdrawglyph(g, cx, cy);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XftDrawRect(xw.draw, &drawcol,
|
XftDrawRect(xw.draw, &drawcol,
|
||||||
@@ -1661,18 +1832,16 @@ xdrawline(Line line, int x1, int y1, int x2)
|
|||||||
Glyph base, new;
|
Glyph base, new;
|
||||||
XftGlyphFontSpec *specs = xw.specbuf;
|
XftGlyphFontSpec *specs = xw.specbuf;
|
||||||
|
|
||||||
numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
|
|
||||||
i = ox = 0;
|
i = ox = 0;
|
||||||
for (x = x1; x < x2 && i < numspecs; x++) {
|
for (x = x1; x < x2; x++) {
|
||||||
new = line[x];
|
new = line[x];
|
||||||
if (new.mode == ATTR_WDUMMY)
|
if (new.mode == ATTR_WDUMMY)
|
||||||
continue;
|
continue;
|
||||||
if (selected(x, y1))
|
if (selected(x, y1))
|
||||||
new.mode ^= ATTR_REVERSE;
|
new.mode ^= ATTR_REVERSE;
|
||||||
if (i > 0 && ATTRCMP(base, new)) {
|
if ((i > 0) && ATTRCMP(base, new)) {
|
||||||
xdrawglyphfontspecs(specs, base, i, ox, y1);
|
numspecs = xmakeglyphfontspecs(specs, &line[ox], x - ox, ox, y1);
|
||||||
specs += i;
|
xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x - ox);
|
||||||
numspecs -= i;
|
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
@@ -1681,8 +1850,10 @@ xdrawline(Line line, int x1, int y1, int x2)
|
|||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (i > 0)
|
if (i > 0) {
|
||||||
xdrawglyphfontspecs(specs, base, i, ox, y1);
|
numspecs = xmakeglyphfontspecs(specs, &line[ox], x2 - ox, ox, y1);
|
||||||
|
xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x2 - ox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1746,9 +1917,12 @@ xsetmode(int set, unsigned int flags)
|
|||||||
int
|
int
|
||||||
xsetcursor(int cursor)
|
xsetcursor(int cursor)
|
||||||
{
|
{
|
||||||
if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */
|
if (!BETWEEN(cursor, 0, 8)) /* 7-8: st extensions */
|
||||||
return 1;
|
return 1;
|
||||||
win.cursor = cursor;
|
win.cursor = cursor;
|
||||||
|
cursorblinks = win.cursor == 0 || win.cursor == 1 ||
|
||||||
|
win.cursor == 3 || win.cursor == 5 ||
|
||||||
|
win.cursor == 7;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1995,6 +2169,10 @@ run(void)
|
|||||||
if (FD_ISSET(ttyfd, &rfd) || xev) {
|
if (FD_ISSET(ttyfd, &rfd) || xev) {
|
||||||
if (!drawing) {
|
if (!drawing) {
|
||||||
trigger = now;
|
trigger = now;
|
||||||
|
if (IS_SET(MODE_BLINK)) {
|
||||||
|
win.mode ^= MODE_BLINK;
|
||||||
|
}
|
||||||
|
lastblink = now;
|
||||||
drawing = 1;
|
drawing = 1;
|
||||||
}
|
}
|
||||||
timeout = (maxlatency - TIMEDIFF(now, trigger)) \
|
timeout = (maxlatency - TIMEDIFF(now, trigger)) \
|
||||||
@@ -2005,7 +2183,7 @@ run(void)
|
|||||||
|
|
||||||
/* idle detected or maxlatency exhausted -> draw */
|
/* idle detected or maxlatency exhausted -> draw */
|
||||||
timeout = -1;
|
timeout = -1;
|
||||||
if (blinktimeout && tattrset(ATTR_BLINK)) {
|
if (blinktimeout && (cursorblinks || tattrset(ATTR_BLINK))) {
|
||||||
timeout = blinktimeout - TIMEDIFF(now, lastblink);
|
timeout = blinktimeout - TIMEDIFF(now, lastblink);
|
||||||
if (timeout <= 0) {
|
if (timeout <= 0) {
|
||||||
if (-timeout > blinktimeout) /* start visible */
|
if (-timeout > blinktimeout) /* start visible */
|
||||||
@@ -2083,6 +2261,11 @@ main(int argc, char *argv[])
|
|||||||
case 'v':
|
case 'v':
|
||||||
die("%s " VERSION "\n", argv0);
|
die("%s " VERSION "\n", argv0);
|
||||||
break;
|
break;
|
||||||
|
case 'z':
|
||||||
|
defaultfontsize = strtod(EARGF(usage()), NULL);
|
||||||
|
if (!(defaultfontsize > 0))
|
||||||
|
usage();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
} ARGEND;
|
} ARGEND;
|
||||||
|
|||||||
Reference in New Issue
Block a user