From dc8fd64220336865fd24fd39315219460e1d9f35 Mon Sep 17 00:00:00 2001 From: keleki Date: Mon, 13 Sep 2021 01:16:02 -0300 Subject: [PATCH] added changes --- config.def.h | 15 +- config.def.h.orig | 476 ++++++++++ config.def.h.rej | 19 + config.h | 476 ++++++++++ config.mk | 2 +- config.mk.orig | 35 + config.mk.rej | 11 + st | Bin 0 -> 104296 bytes st-alpha-0.8.2.diff | 163 ++++ st.h | 1 + st.h.orig | 126 +++ st.h.rej | 7 + st.o | Bin 0 -> 74320 bytes x.c | 40 +- x.c.orig | 2085 +++++++++++++++++++++++++++++++++++++++++++ x.c.rej | 108 +++ x.o | Bin 0 -> 75728 bytes 17 files changed, 3549 insertions(+), 15 deletions(-) create mode 100644 config.def.h.orig create mode 100644 config.def.h.rej create mode 100644 config.h create mode 100644 config.mk.orig create mode 100644 config.mk.rej create mode 100755 st create mode 100644 st-alpha-0.8.2.diff create mode 100644 st.h.orig create mode 100644 st.h.rej create mode 100644 st.o create mode 100644 x.c.orig create mode 100644 x.c.rej create mode 100644 x.o diff --git a/config.def.h b/config.def.h index 6f05dce..9b18c04 100644 --- a/config.def.h +++ b/config.def.h @@ -5,7 +5,7 @@ * * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html */ -static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; +static char *font = "peep:style=Regular"; static int borderpx = 2; /* @@ -16,7 +16,7 @@ static int borderpx = 2; * 4: value of shell in /etc/passwd * 5: value of shell in config.h */ -static char *shell = "/bin/sh"; +static char *shell = "/usr/bin/zsh"; char *utmp = NULL; /* scroll program: to enable use a string like "scroll" */ char *scroll = NULL; @@ -93,6 +93,12 @@ char *termname = "st-256color"; */ unsigned int tabspaces = 8; +/* bg opacity */ +float alpha = 0.8; + +/* bg opacity */ +float alpha = 0.8; + /* Terminal colors (16 first used in escape sequence) */ static const char *colorname[] = { /* 8 normal colors */ @@ -120,6 +126,7 @@ static const char *colorname[] = { /* more colors can be added after 255 to use with DefaultXX */ "#cccccc", "#555555", + "black", }; @@ -128,7 +135,7 @@ static const char *colorname[] = { * foreground, background, cursor, reverse cursor */ unsigned int defaultfg = 7; -unsigned int defaultbg = 0; +unsigned int defaultbg = 258; static unsigned int defaultcs = 256; static unsigned int defaultrcs = 257; @@ -139,7 +146,7 @@ static unsigned int defaultrcs = 257; * 6: Bar ("|") * 7: Snowman ("☃") */ -static unsigned int cursorshape = 2; +static unsigned int cursorshape = 4; /* * Default columns and rows numbers diff --git a/config.def.h.orig b/config.def.h.orig new file mode 100644 index 0000000..e3c6f8a --- /dev/null +++ b/config.def.h.orig @@ -0,0 +1,476 @@ +/* See LICENSE file for copyright and license details. */ + +/* + * appearance + * + * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html + */ +static char *font = "peep:style=Regular"; +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 = "/usr/bin/zsh"; +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 = 8; +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; + +/* bg opacity */ +float alpha = 0.8; + +/* Terminal colors (16 first used in escape sequence) */ +static const char *colorname[] = { + /* 8 normal colors */ + "black", + "red3", + "green3", + "yellow3", + "blue2", + "magenta3", + "cyan3", + "gray90", + + /* 8 bright colors */ + "gray50", + "red", + "green", + "yellow", + "#5c5cff", + "magenta", + "cyan", + "white", + + [255] = 0, + + /* more colors can be added after 255 to use with DefaultXX */ + "#cccccc", + "#555555", + "black", +}; + + +/* + * Default colors (colorname index) + * foreground, background, cursor, reverse cursor + */ +unsigned int defaultfg = 7; +unsigned int defaultbg = 258; +static unsigned int defaultcs = 256; +static unsigned int defaultrcs = 257; + +/* + * Default shape of cursor + * 2: Block ("█") + * 4: Underline ("_") + * 6: Bar ("|") + * 7: Snowman ("☃") + */ +static unsigned int cursorshape = 4; + +/* + * 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, ttysend, {.s = "\033[5;2~"} }, + { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, + { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, + { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, +}; + +/* 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} }, + { TERMMOD, XK_Prior, zoom, {.f = +1} }, + { TERMMOD, XK_Next, 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{|}~"; diff --git a/config.def.h.rej b/config.def.h.rej new file mode 100644 index 0000000..a4fe123 --- /dev/null +++ b/config.def.h.rej @@ -0,0 +1,19 @@ +--- config.def.h ++++ config.def.h +@@ -112,6 +115,7 @@ static const char *colorname[] = { + /* more colors can be added after 255 to use with DefaultXX */ + "#cccccc", + "#555555", ++ "black", + }; + + +@@ -120,7 +124,7 @@ static const char *colorname[] = { + * foreground, background, cursor, reverse cursor + */ + unsigned int defaultfg = 7; +-unsigned int defaultbg = 0; ++unsigned int defaultbg = 258; + static unsigned int defaultcs = 256; + static unsigned int defaultrcs = 257; + diff --git a/config.h b/config.h new file mode 100644 index 0000000..14ba779 --- /dev/null +++ b/config.h @@ -0,0 +1,476 @@ +/* See LICENSE file for copyright and license details. */ + +/* + * appearance + * + * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html + */ +static char *font = "peep:style=Regular"; +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 = "/usr/bin/zsh"; +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 = 8; +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; + +/* bg opacity */ +float alpha = 0.8; + +/* Terminal colors (16 first used in escape sequence) */ +//static const char *colorname[] = { +// /* 8 normal colors */ +// "black", +// "red3", +// "green3", +// "yellow3", +// "blue2", +// "magenta3", +// "cyan3", +// "gray90", +// +// /* 8 bright colors */ +// "gray50", +// "red", +// "green", +// "yellow", +// "#5c5cff", +// "magenta", +// "cyan", +// "white", +// +// [255] = 0, +// +// /* more colors can be added after 255 to use with DefaultXX */ +// "#cccccc", +// "#555555", +// "black", +//}; +#include "/home/pavuz/.cache/wal/colors-wal-st.h" + +/* + * Default colors (colorname index) + * foreground, background, cursor, reverse cursor + */ +//unsigned int defaultfg = 7; +//unsigned int defaultbg = 258; +//static unsigned int defaultcs = 256; +//static unsigned int defaultrcs = 257; + +/* + * Default shape of cursor + * 2: Block ("█") + * 4: Underline ("_") + * 6: Bar ("|") + * 7: Snowman ("☃") + */ +static unsigned int cursorshape = 4; + +/* + * 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, ttysend, {.s = "\033[5;2~"} }, + { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, + { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, + { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, +}; + +/* 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} }, + { TERMMOD, XK_Prior, zoom, {.f = +1} }, + { TERMMOD, XK_Next, 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{|}~"; diff --git a/config.mk b/config.mk index c070a4a..aaa54ff 100644 --- a/config.mk +++ b/config.mk @@ -16,7 +16,7 @@ PKG_CONFIG = pkg-config INCS = -I$(X11INC) \ `$(PKG_CONFIG) --cflags fontconfig` \ `$(PKG_CONFIG) --cflags freetype2` -LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \ +LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender\ `$(PKG_CONFIG) --libs fontconfig` \ `$(PKG_CONFIG) --libs freetype2` diff --git a/config.mk.orig b/config.mk.orig new file mode 100644 index 0000000..aaa54ff --- /dev/null +++ b/config.mk.orig @@ -0,0 +1,35 @@ +# st version +VERSION = 0.8.4 + +# Customize below to fit your system + +# paths +PREFIX = /usr/local +MANPREFIX = $(PREFIX)/share/man + +X11INC = /usr/X11R6/include +X11LIB = /usr/X11R6/lib + +PKG_CONFIG = pkg-config + +# includes and libs +INCS = -I$(X11INC) \ + `$(PKG_CONFIG) --cflags fontconfig` \ + `$(PKG_CONFIG) --cflags freetype2` +LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender\ + `$(PKG_CONFIG) --libs fontconfig` \ + `$(PKG_CONFIG) --libs freetype2` + +# flags +STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 +STCFLAGS = $(INCS) $(STCPPFLAGS) $(CPPFLAGS) $(CFLAGS) +STLDFLAGS = $(LIBS) $(LDFLAGS) + +# OpenBSD: +#CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 -D_BSD_SOURCE +#LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \ +# `$(PKG_CONFIG) --libs fontconfig` \ +# `$(PKG_CONFIG) --libs freetype2` + +# compiler and linker +# CC = c99 diff --git a/config.mk.rej b/config.mk.rej new file mode 100644 index 0000000..ad62275 --- /dev/null +++ b/config.mk.rej @@ -0,0 +1,11 @@ +--- config.mk ++++ config.mk +@@ -16,7 +16,7 @@ PKG_CONFIG = pkg-config + INCS = -I$(X11INC) \ + `$(PKG_CONFIG) --cflags fontconfig` \ + `$(PKG_CONFIG) --cflags freetype2` +-LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \ ++LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender\ + `$(PKG_CONFIG) --libs fontconfig` \ + `$(PKG_CONFIG) --libs freetype2` + diff --git a/st b/st new file mode 100755 index 0000000000000000000000000000000000000000..a92a8e757a1b0ea3a9d1fe1b0fda10465fd0dcff GIT binary patch literal 104296 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 z zpOKOzxU|D5B#a-dz_GRY5`C0N2Nvc=xss*(EaW6^DxR3WrR~Mlo73{ERB=67`s-Vi zeES@)LImrYSVlh$n*JomO3-rU32M>hAZZSmv=ENUn&pRs-@)J;IJzH&6=l}&On&7H zzp;H@3?<#BQc8%e(HZhVM3h7K(0{|n9&E< zaM&Dj+J9WOxs_XroMd^Q#kcnObqyD1!Wp;4C0@j*Bc44-!s2V|vtT2B2E+4_Kc6;} z7Ji1?Yb3PwL8K@@h`6@iPp*k@g|zR4^AdC#Rx*CZK8^$FV9grJ%IZ z&S1zHxC<_GgXBmDFIRtr9vl~laIe1(Iqj$PVq?I{sh^-yhRWSGu+9<#Tk|BXH(HEN zRcwgOJRCwfWd4Y!GJg9VfiDp0eAF?{&_Jhc6O%s28y_Td$ThAq;fD>0iby5s>e$* zE4EWiT7Oa}Pewu#zGJlTl?PbZ6CRw|Gz-+FK^(U&1bdygMetYH%8BqlXJcvU{R7?> zDdF5Pn5pwle5jRETie!2x$*P$VPvaI;&!3SbK6;P@vwif*-4$KNq31$z}FvBQMfdR zqq(G%@Q;qM32P(q-I%!DJ5EY?BD#Q*6km}+)qN!joo@8rNZ{UoYn7HWQLD7==<0Im z=SdC={HSj+0~NoLov@J{TnEBQ<~4#{=6(M{ED$Q|pPP0r&wMVpgkrn)V`d4KNTi)3 zk(MA*`2{pnBpv!f{s5AZdwy})K+X|=!Cm z=_647F?7y5w)Um-j*Woocb})F(Joc!nT|qhbV9fwYol#g{3#c8e9QaBcrXJlgAm*P zEFx)%n@PC&Qs|^FbuyfnlzTlsoIiD2@$0Fd@TL4E`pX8urmDUj|4a9l=8|U@Au-01fIU9127CMUfT>rc4pj&7Vq%huw_Tr7%4gKs4 z{m+F%O?X@Jre;QR8*w<5l8b}oVfH!6-ZQRY^DW-vE@>E+tuCCWjfQQY&#>alT3iDN z%YR|mvs3UtW(`k>V?_|+*fbv%sqZT3jGp%CsR#NSDia0ghMWFCPlS_xu;fm;{%fjF z?k*5&2a`FHaw|DzQ_u;DL9#}M!D|+UlN@>EC4Z<`53UG?Ju{Wt&@e~zDv&sf9!b85 z(iM9jg&X^k2%d^?Y|aRYE)>UGh(jaVD9A`yw=j(R18#3;#Ww3?59ZpTGwj*{&M9QH zRzXBR>v&?O*6{Aaa7@x9gCpkCIbuN9wYhA#*sLy`3+YP(noPKCoe&1Y!fjBjf>e|; zPq3F`9%=GBDNpxD(Ca0#UqRw4GpW}@IoJ6|w>VCrC>L1i2ZQ`vFVrS>blXB7tq30l z&#!@!Cb5y`M@4(=tA8FU)VAMP+t!E1`)xu|&Aacs(+{VwDdO(h-}|IB`Qx+9JJ?o- z7)WdKTv1q5)3>j``Y(Thrs7~5efnIqM+tK*MQreeNanwMq*rez5whRUX@vL9N*TLj3&u|MAtv z6!NE9&+`3FpXIN_&r-Sg_qki)=k(Q(Px!2p@7D&eCAPtUCm?tds2HEWz*_Q=K@;d2 z&|C#{I?GRKgtyDqi+)ffjP)yBz>M>c53?-zT~>A@GX-H2DXj7(DL&1+6M?ZjLeV{^ zMTvw*$00(OZLkuhOX`~=ElhD?sUkTJBFD1$9vjmt=!_rJo^_C+o&ya_`&Bjmp&3B+Yo!(<@gb#4(n~?JLMA6>BL@Wtu&uAdbTA3sGGX<5~ zhvH`)B<%oDb;_&Wr!AYKasY2S+sx0!=SsP`;vp7Pk#UjPiuDrr?yp!8aBt(u`&U9c zd@u6~0Q+7hw)gYogf{3m;gV0XQ1oLriSDlpa+-{e_bf%lMzoOBhDuy zet;PDtR3xk|U1p8{CgTxCx9s zK1y3%eqme!l23d=^~PQN1v?LSLvi^rgu+aH7Be5Z+uaX?BpY|-uV@dq7(!Y@r`9wj zGFSF?2Ta7MF5^7JRoNu6shLeB3KAYcgf}86$$rHh^|3r{gL#dMvE% zq@)C>gdt@CdpXYkjFNvG1rzF_rG?Kd@MS)}DU0p>JA}^HQ(CyXMOzuPi4dE97&KP= zxJN`OT!$~&;yW+wN;mxYic=74dhLfc>MDQ2e@+q~99L&3=q`efIl<8Db+Xf`(A+b&82v{&`Goyf|&qXJy*1HV<8(S@Yx4IWYHVH>*c-OMZfjXA6^o74W1Ya?X@mG z&yfh=!VhU-XsE0a8=QQ0>*g2~qSCY7(uM|ssnjU{@V*lF;~^Fhcbb=EviSCcz}}cb zW3MYOp`I9BTvF2eU}#eN%Xu_J3^?f84w{K-jm`WkNpm8eq)!9y|A~C01Rt1eQAQdr zbX{24w=4Z7=`WA^KNJH@XDEgiyl$r`#v=e#+8ww)TWlLnDx!`cod9PghJr?wd?^Hy#$BvSawFua3@k*3t!{}X~zvoe1joJ>r*^a3$x zQRZ)hAA+IAP`F!;v(fIO%iH@DKuZMb(v59N$@jBQcj@Y{SaK9025MwfG7jM#b9GUg(`k6e%WC;f!{(E z@Wmf}VdE5=#NBLop)vJgC@t1H#h{b=H%#1V0YM)0qtG-i^o^JY{eyrK`Df9gW!a*oxpQ+DI|%rbvz*B)XjnP8^xS{IHh5o)Xq8N*eym=f^5D zoxi=QOr2pve=e|86~KqpbeP)hStZ;HuT#$Fr_ekiUaX~U9m#Pwr8|JqZ5-Jb5kj3g zm~Kr-kz(jKV8&R)yXXgClF|8$k1rG_^fWh#v19@Q#fFa;`K>e`@Vm^)d{Q`nS{!NF z$YO%E&|OGnz~?K`!_#uJuev`&H(P&x6<5-sr75(B;5UG@!RUqnS>Goc%G+xV%*INpB>Cf_)cHt|sS2|YeR_4I^WS&{o4_fse{vdRuT|1{zW zByxu_;)+jL#PlUIMZ9GLBED7^v5i8lr$)D$8r?yJj~En|?-vVm_+{HWm=qT9<#(p@ z6+T2MKgenw`wqASE`osgyj_L-EeYqaX~sXX1{C(bPUTW9Vv7Hh{3?nE^ZUbK2(AXC zFxyq{zp+wGJ-?5<>3s23Ocvy8E;6gBtfdsN?n46HHxS`hHmMA)1Q$RQGt?T9I}Sf> zefU6x-2)aT)s-p3cHOK!`Cp+B4b_ppimxmq zzsL?#9gB_i67p$g)^)*os7V@&{f?PPnc1`a@6S=i4>FHKEC?!L3VbP*d!f`B-fFSI zB$LkYS8|JfFq!B*8*g?Vj%^1mP+v8WO$o&PF`kYuJoway`yI|gfuC1{xc?ZV#Qi19 z0e4XI3caRi)&ze=v!0~cO^RlSWY<0f)U}t7ASi!=SeS;S)xN!ooqbct4@`O<5%W*} z4g=vU&*Dh}A3z}ZD}a*J)JRhAe}<%Pjg*cn;_(7`jE{Kqk9aI4k1}}3+gX2m9LIRN z?=NWdQFpVj_0*3>7EEx^t>aQW)iTI$k11sGfA{H6Lr?if)-^X`iL(cABMXIHym|Pn zlZE*I+WQjtrmF1!*Op*enpC9!728%OI|lMZg_5#2t~*U>yfHbX3g$d+t5AO&)zPzyJUL`Tds<4_?oG zXS?T~yWiY*AAI?25%`|E3wq$_lTnL*c>=ZgOt7lvp#n=H;XP=aStR8a=z`=8kQ6Pq z&>LPQ;xa9!h){}9jIx{vYk>jOJ5qT!hc;si8dtyfufoWyMwf4ESu~;0}RUU_h*3l&#+sVv#%kd zLLP*|=TefXFJ6KSfC~98W@ktFId~3r>SUM~KIV2zUEZSO5=&z8%SJ~Kn9kh^v&7rF zrk-mNZ0#`=*acnK{c8xz8QGswL^*0z0om68lcq44Dv+%Lq9q4QfAVwq7~%NM`1z$A z&!MDT#MNr+7s?n%fjXS2ok4+;5g}6=1#*XN%guvtwQafC1aRbXYv~}oEz+9Xza^^} zNu)FCwhIrr&d}C#1|2YEgO(7;vn}ouhv8kwG#t<3K(wJE&^MGa7=e~O zY3mb6@2|;$l=T>JAY={n!LNA(+FN%2($e0mHP|X19wDG#W>s$ILLK&0W|yGTPA#^HyeoDjBT{W2JbV*N5Gm^Cfr89J=P zL?Dyi`yTNE+=dPXFBI-O8~K3pJs;)f*+Ian@;wns!)Mc3>sdlc5 zVxK74hYNq`rlH@CEo%ZWdgHeVa*+-EsLlDB3i-0Cd#EU)2 z;I^#gdC++xQnarRnwuEXVj}(i1^FK&>D4#h7M45>5Ptg>kZ1=$_-fRNQjE@3S@Yxy zt{aJK5t^!&OEYnNB}T5pY!fyG60yxaE)b8Ok5PptA4JytDCQuU(4a59;Sn&6P7(Ml zTu31t6rNia$}I_vZTX|8WeHUboT>R1)@!!W+7!;}`okoLZaLTj+w$+8mg{I}i-)F` zKYCb}e2E9a@}rRatCY+}AG^ejLMF9Xmi#W+*4F~Qh!G^V@@&PaDO90L^4iXh%WKQ0 z4RBRRr`P}|dxc|ff`wa=IrymtFR*+i+!20u4`oO6e9W>`6lhUBHcuFN-43*N<3dRT z$(W7F&3JnAz{X^}Uz+vCGHUHMhLW}-(6Z6mI?@j2)|5H;yDtm5G9jfH!QiHjJ9Apv zC%61NKF2a+`@UmAX-)bIWLih234zl{pfAwdOpT-yNkUq)k+7xnfyHMS+H+_jYuQXZ zb=Vgl#3TtnE#={9@vkzRi7-q+y5NCR;ek`(f%>U292HCrqt+5PC0&rLqju|Sb1?C6Q@GVv$14@0E!w87_)`u*yzl$5?jj^ z*;){@d^E$5vq6k!k8K&Z=ZLcW(wivDYpK1*k42%}OuUL6n2qz6Yk{{cxsf75Q)*dq zm535AV}vg4Pm{T1*@KhO;T%*LnpyrPc%oNsElYcW10@G5x0pbiPJ~w3L5E6Vrc`$k ziX0S{sBX#%HP2A*8Ez8&P;NGflvDZJw-A}7YU8IeF1)I&I9-nMgC{f51LF6!NMg=?U&|9C3U>`92F3!{mb;VpeUzP+r1fCnzVw)XQ5(J*2y0-6 zZ1t#!qCtED-U|2p47Ff=4E`>{fBPx$tGbpX5>fD4f65D0m*gzoO9{u1=^LO2#}q>Y zI+k+?AsqD;5U64DExMeRPvBsbX&~_$83l6@#D1%N_)!Hi;XAR4g|i3cdDY@GH=Cts z$2MDNZf5v?{BVSylrWnMf3+J%y-!a1+4S~nn%2J^ElAG;g(YzTi<~&o4kF={@J$%P zcl=0g_0OgUV|fS2ynrdQUY(adPEFn=%Y0qKX=j(BB32&ijc>uIEMtfdo38jWt&8+%b zkHw&$O|)kz$^+@b1LWWSu7YihThk(3^#=4DcI6RRNwx3Yp9%S~JGTg+a3pe5zE zSI`n2o64f%HpTSA zHKW@Pm@b8`Y|B#WH)%sxD60?IjhdKY!zmM3xWZ3l)Zq1hCL1hR?g&?+f}%mf3K2fU zgzYQ$-bcg9`R0IS^>vznO3=>>RBoEudwG@Db=xE?pOH&C+baDkQn?9A1f)r z`RaEg1(+u8v9(>=KT?|9QI#L6MFV~?62uvR@4t+`9s}E!FL8p(ww%RZ(Vn1G4Kc!y zzOdnxW?_SMAZ)m>YVpCy?~O0hxRfTI)c-A^@fi*MaC!*710_0}@Gl=y_U8?)i7GF9 zh_7W!Q`BmE^QHZ@%ZDkeAF@q4BlvyjQv6c-ZTRbtgwbEn-oRbN*R+d1bkY;ScziYn zza(ja49mLQ0qx;qmb3?-LlwuQ5^GM>Ia3ZcPzj9c{9G_;Uk!-Omk!V@cei)EoO9qM z{Fa&n)B)3u?RZfla5|mLVV!)1Wyu+&g?w#!vAu6Ieu%zlm2|QgDG0W!^M;I04m@`{P7PTWi(?a3jGz zTQkNYgi*T{AY}Rz{-n#3ypBMIP#RjSrAX>sb@R+>xBjIw(^bgTd&e(xtx_2V= z*FOz&cVP>~58IHFrVsGfvS#ESdKkF_e=$VPq8LJ1rvQXoZ$LvFGWAAb2qmotJ(Tj8 zh`qC+tanLA+GC`{ zw4K;93g~avWWuNX9eDIY=*^=hXp6sDkCGTwwU!KB4aDg7&`2|+a5_jI0HmUvble9w z)6od`58aLI=;+<@ya*g0m_)02p{%jQ^lbbLqkfga=DUOuM1llrQ#nc|kPQz1p7mZG0?HvS>^ zM`BY1_C3AxRa@>9l+mKi*f)vl)vxsf8#Yd2JSEnL(#R?rO(6o97fO8+9Vi}Y`Y4Zn z!m;1QpW*`=ki}4Gq{9yb&!G)}c=sWcx)SWvo`^vW{*(>1Q4yYBgza7Q|7$VX`V>VF zC8d>qtqtd(>EKPFEAdRDrTMnDn}yr3G(nf#8M+AvayhmZ_gb`NKF!qdy*_H!dllm` zl=TsGg&R-|Xogjbnu7+{bQY`;YrklTx1(hru~9Yg+rP)&6S2hmy=C4;Jea;d3#~j@ zb_nx{^f4OylV1h8*fRAc@xDZODODnrzP7C3pVbIyKmC}3G?vI-XX;fn>)Kk}`fuA1 zm=;XrjeJSrAFz|I<2(6UJ}e$i7H>iILn}6gw$tvWl!~9M%tU&b>Zx3w{`P87M7G!* z^6=ZDP~J>Nxn0P&#k&P(IajrO1TXbtLit~;ZxJ!F&scA32!E+e1LG3W!NU^&Y=G?Ef(QzwLNIJ&L+`~& zGr&Q!_r)3c9Fj)%gOSoQI1NK;asxtXFnrf!6#Y9fEtzC8K_=KIloAIxVa{awQX`Jf zX`GBk`yPzK#3*hvjo(71t(z#hm!ByPZGHw1*tAR=4H8Ui=|SwwF+)xGwk0%DzE!Ya z@fM2Qur0u*lDf96G71ln;bsaa$?zi-jzgGy@Pp<21SH-D72y}Yd(r>!&FH!OysYFllUQsCh zW7?Sd0{yagF=RV1xy>qShk@wAkCQI>dMSNX^;px+2J~+x`T`>tv$v2&+JX1h1hE6p z^mj1e2P$lADKXm?Takg_zqX729_D|5`Ij>P#y$P%O@dy@+e}x28;R`P#IRY6^%s9b zgT_{T@Fl8bEg4Fy!=u~77qy7NOkbI&EAfObIYp!alkE#klr32%JcrYel2+5#M8df+ zWEfI;l9-Xmqz(oH_P(P*#132t;_NKRycNvhQ=uBvXRR8HN%tx0ktf?5@E*b zYWSv3S)rW#V+YMMZtZKk*JR8li=7}kh0UPSmJ9Q-&AB&?E#k}?norJRAk(mSbO z2wNAEcW6j=8fijLxC(JRLw$s(9_Zt6h6&o5Gzzs zjDCG2lyU`hpv`Co0b+I%dyT~8OK#z7?;%r6Zb42uTY!`&1;{8CAZsK*I8&Hxx>2GA z5^D5bihWBmO7fDs<5BZhkheow2VrkG^K#OQ^;gvPjNd2)p{%_`xEnnM&CJkZrF66j z+uoJrmx!DOGMbGP+De4>nZQ5^21z+9@V>leFN z*Hh#{Myu3TPf{;HYMbdK1Zk=o?z;vZ>CnAMMJS_EvYkV0w;)m!FX4!Zgm{UHNn1uw zgym?l-(><}>O>?EVw*{>Zb5LH>2=|pqhC<4(wY0|YPqw3)uy)7_7rg`^}NrFLIB8oh9TB%aoNtx??pO62HvnqSe^ zh5OoYnCqmIGvSPe6X>^JTI%U1w(19Ifz(PrKI{okcmw^xCMooG0Gr&gPYr!}LekG7 z*(tlQc#Dk45l>m0@Dx578G)8+Cs6o&FuweEY>)n;ZRuDMUJP2)bg$(bTTbim^pzaM zZ)@#46kB48F%xTsjm4qohh7aBlYmV8db{y!EAitPJbWUx!EE025a? zTbAa)KbEKQ9)H#1FWTa9EY*@$7}4^o6?4xYyy(@$_Y~j9auCMR6GNttfa8XIFH(tu7O4$SUqsoD@q1@wuq?e7 zF`!J@qLza2KJ_{S|G?~}wWtPpa2sCKdjhBZTCshvxYxIbI`QCb(?6Mp@D zjL@2Ko`Yp+BY8c_|0w>pq=eHDDT+(~j)&0QY=Q~cn7yxU8tuYPeVQJ-k|n;zj%3Y4 zio=bUqG}C=N}S^aHXIPOCaDDhyvNeI2|C_w*#vLQBX3X*!}$+rW@$_0DI`4s()d;y z32wBkc^yJ9*0LrgpEPWW&%-ZqIiiwDnXiEkn}p2ZC>gR1S&(88Quv82R_ZB|dh-&o zvhxjA>12L=N}-~-&McGm$#||Li8~>&?`+Hm!e1cksL{wiq|RX=hR=B&4^^}+9xH#S zAe8s`F#RquxRbv*g|gbg621c(>Fil-+dy-g5bwz)uWfSL_7C0-m;>0uJv`iN-(TAl=2i9i-AeAIkt)l+BWEz*6qXh zqXqj8`BRLee*gLkauc7ixvmt23d^<_t6XP85aWW$C}nb$h|Zf&+=nh14Hq_ALzUI` zB1)=g@oYnoOSWDZjuC`ktwcxLH^|ltKNVw%IS_}Zs5S>r?V^Fh>L~5*wnA+`)U-j^>+KwhjqQtuPR6hc zzIh4f{cfWZvvEK!-V(d~VthgGG7rwXcJ!#qS^PWJWj_lgKypMVHxU4z^I6ar?_A=W z*OBmrwD!G;-Z7vio{sLqQNhDu`XH$4hwpCD=eDet<(m?BSeDYk8C7|c5W8jR=LmN! z30}ExBs&l7ShkQq)O(M3QglyV`-wq;y16rgpRXh*}x1vwt^`X^?F;}FSmVr#Q;RSzMM@l+L#0LdI_S^95iu&gVITk^JL$v+Wp{&i&FL|bSUkW=H9K>WM}EO1cQ z(J{KYDP9YHK_~B11mgVaZKlhii7t|%^$W|o9s@~k0OVT2Ig`g(uIhmxjvp*?_`ev*n&3yvx|`^jHFskK_p627oee#iCUVC zGo2ddpvU6V#q5W|A=_c)#PMa=!6jF5Z&f!xsmZU!Lsgz71sh==~ zIK0%sjgXg^p(&Y#BTlyfU0OW+AT_e#EAV@WZR5d& zz~Ipzv3zms_vl4%7F|xH-)C~^@sr@!)DT9EhpVbaSq3km=tO**8In%XWD3gBKSw=q z)B{I7aMS}wJ#f?mM?G-V14lh@)B{I7aMT0Q9>DkM#iOgf-sN`;8=EPoA_=ke8pB{)L-?_`YD zUtQH?wFd(A)>Nl8=w0CTHF^)x$9QX9y}Q94a9RDXz?rbn6|mO&oGwVRgofBCiYK_xcWp{gA&WYAke{aoEfTxaM!GL?O|-%=L?xamUZ_fSHg%e`y*oK6XRE5EePn;WNLXXN^e58g3kK?f0c#bU zsUg0(+OT=v;rLTee_Z$jrA@=NTD!;Nb4YL3yP_WafqG}KE;<`rO>WA9MmJpR57+}i zzsLZ0XSs~c1vo3$7xXy2rw6PKD27a6p*E5&_0_q&lmn^$iR4y#w0hiL7n12eJ*Es0 zsSep2T`o{w7Q`UjK1aY~Ei0OlTbf%|c3upv+7+m447#~UHP-m7_Ij6fp)WY4w^nM) zFD}+{XB5wxHoa6UE}EWSs+Hx>oR*tYq7~05oSri+Uz=5$KU1^KK!_+^iK1fP==M5& zjVO;)xF{hqAN($_lTud+moCtTd4nF$@XoALg{#u;ca2N$%F@ovM;)XrOLfrSd51DM z{BEmu(%e+{q*V7z&7qu(xKJkQeYIA9jmzVa_V`^MYBHjoM}@>?MG;0#@OiDs70H^^ zTidhjM%*{y{tNCKv^}?6jr(?O&x#gp&#lW42L6Ut+}Gl6!+njmX|1;DafI&29n$vP zyaG2QZwANBH{*U@+k*`Td#-y9;buU3egWZ?xFK`%Q@9_&eWkXi70;~?Xm5h8b(Oa1 zK8=3S?e02&W%!NwJ&T~a-@)@ga1X@qaD+P-@EJh5=~;!Np^}ZpsqpwHd4>D0!tUao z4qL|I-hg{JL;7i!o{jG74nrfE2XNOQ?R#MJO@J@r{)(Uf4fp`?hr3DcaPv%A5Q-i3&7O;r3ZMuk

)0OPE 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%0D>P7 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 +#include + +/* 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 != (b).mode || (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 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 float alpha; diff --git a/st.h.rej b/st.h.rej new file mode 100644 index 0000000..575ff2e --- /dev/null +++ b/st.h.rej @@ -0,0 +1,7 @@ +--- st.h ++++ st.h +@@ -120,3 +120,4 @@ extern char *termname; + extern unsigned int tabspaces; + extern unsigned int defaultfg; + extern unsigned int defaultbg; ++extern float alpha; diff --git a/st.o b/st.o new file mode 100644 index 0000000000000000000000000000000000000000..c63ce657f557b7d856464430abc7d64b3f347461 GIT binary patch literal 74320 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

E1Ghrr;kt9U*>1(e-;KddCMMlwBxb%sK4IjTc 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⁣~ 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 literal 0 HcmV?d00001 diff --git a/x.c b/x.c index 7186040..6a6e5bf 100644 --- a/x.c +++ b/x.c @@ -105,6 +105,7 @@ typedef struct { XSetWindowAttributes attrs; int scr; int isfixed; /* is fixed geometry? */ + int depth; /* bit depth */ int l, t; /* left and top offset */ int gm; /* geometry mask */ } XWindow; @@ -243,6 +244,7 @@ static char *usedfont = NULL; static double usedfontsize = 0; static double defaultfontsize = 0; +static char *opt_alpha = NULL; static char *opt_class = NULL; static char **opt_cmd = NULL; static char *opt_embed = NULL; @@ -736,7 +738,7 @@ xresize(int col, int row) XFreePixmap(xw.dpy, xw.buf); xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, - DefaultDepth(xw.dpy, xw.scr)); + xw.depth); XftDrawChange(xw.draw, xw.buf); xclear(0, 0, win.w, win.h); @@ -796,6 +798,13 @@ xloadcols(void) else die("could not allocate color %d\n", i); } + + /* set alpha value of bg color */ + if (opt_alpha) + alpha = strtof(opt_alpha, NULL); + dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); + dc.col[defaultbg].pixel &= 0x00FFFFFF; + dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24; loaded = 1; } @@ -1105,11 +1114,23 @@ xinit(int cols, int rows) Window parent; pid_t thispid = getpid(); XColor xmousefg, xmousebg; + XWindowAttributes attr; + XVisualInfo vis; if (!(xw.dpy = XOpenDisplay(NULL))) die("can't open display\n"); xw.scr = XDefaultScreen(xw.dpy); - xw.vis = XDefaultVisual(xw.dpy, xw.scr); + + if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) { + parent = XRootWindow(xw.dpy, xw.scr); + xw.depth = 32; + } else { + XGetWindowAttributes(xw.dpy, parent, &attr); + xw.depth = attr.depth; + } + + XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis); + xw.vis = vis.visual; /* font */ if (!FcInit()) @@ -1119,7 +1140,7 @@ xinit(int cols, int rows) xloadfonts(usedfont, 0); /* colors */ - xw.cmap = XDefaultColormap(xw.dpy, xw.scr); + xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None); xloadcols(); /* adjust fixed window geometry */ @@ -1139,19 +1160,15 @@ xinit(int cols, int rows) | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; xw.attrs.colormap = xw.cmap; - if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) - parent = XRootWindow(xw.dpy, xw.scr); xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, - win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, + win.w, win.h, 0, xw.depth, InputOutput, xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask | CWColormap, &xw.attrs); memset(&gcvalues, 0, sizeof(gcvalues)); gcvalues.graphics_exposures = False; - dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, - &gcvalues); - xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, - DefaultDepth(xw.dpy, xw.scr)); + xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth); + dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues); XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); @@ -2004,6 +2021,9 @@ main(int argc, char *argv[]) case 'a': allowaltscreen = 0; break; + case 'A': + opt_alpha = EARGF(usage()); + break; case 'c': opt_class = EARGF(usage()); break; diff --git a/x.c.orig b/x.c.orig new file mode 100644 index 0000000..6a6e5bf --- /dev/null +++ b/x.c.orig @@ -0,0 +1,2085 @@ +/* See LICENSE for license details. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *argv0; +#include "arg.h" +#include "st.h" +#include "win.h" + +/* types used in config.h */ +typedef struct { + uint mod; + KeySym keysym; + void (*func)(const Arg *); + const Arg arg; +} Shortcut; + +typedef struct { + uint mod; + uint button; + void (*func)(const Arg *); + const Arg arg; + uint release; +} MouseShortcut; + +typedef struct { + KeySym k; + uint mask; + char *s; + /* three-valued logic variables: 0 indifferent, 1 on, -1 off */ + signed char appkey; /* application keypad */ + signed char appcursor; /* application cursor */ +} Key; + +/* X modifiers */ +#define XK_ANY_MOD UINT_MAX +#define XK_NO_MOD 0 +#define XK_SWITCH_MOD (1<<13) + +/* function definitions used in config.h */ +static void clipcopy(const Arg *); +static void clippaste(const Arg *); +static void numlock(const Arg *); +static void selpaste(const Arg *); +static void zoom(const Arg *); +static void zoomabs(const Arg *); +static void zoomreset(const Arg *); +static void ttysend(const Arg *); + +/* config.h for applying patches and the configuration. */ +#include "config.h" + +/* XEMBED messages */ +#define XEMBED_FOCUS_IN 4 +#define XEMBED_FOCUS_OUT 5 + +/* macros */ +#define IS_SET(flag) ((win.mode & (flag)) != 0) +#define TRUERED(x) (((x) & 0xff0000) >> 8) +#define TRUEGREEN(x) (((x) & 0xff00)) +#define TRUEBLUE(x) (((x) & 0xff) << 8) + +typedef XftDraw *Draw; +typedef XftColor Color; +typedef XftGlyphFontSpec GlyphFontSpec; + +/* Purely graphic info */ +typedef struct { + int tw, th; /* tty width and height */ + int w, h; /* window width and height */ + int ch; /* char height */ + int cw; /* char width */ + int mode; /* window state/mode flags */ + int cursor; /* cursor style */ +} TermWindow; + +typedef struct { + Display *dpy; + Colormap cmap; + Window win; + Drawable buf; + GlyphFontSpec *specbuf; /* font spec buffer used for rendering */ + Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid; + struct { + XIM xim; + XIC xic; + XPoint spot; + XVaNestedList spotlist; + } ime; + Draw draw; + Visual *vis; + XSetWindowAttributes attrs; + int scr; + int isfixed; /* is fixed geometry? */ + int depth; /* bit depth */ + int l, t; /* left and top offset */ + int gm; /* geometry mask */ +} XWindow; + +typedef struct { + Atom xtarget; + char *primary, *clipboard; + struct timespec tclick1; + struct timespec tclick2; +} XSelection; + +/* Font structure */ +#define Font Font_ +typedef struct { + int height; + int width; + int ascent; + int descent; + int badslant; + int badweight; + short lbearing; + short rbearing; + XftFont *match; + FcFontSet *set; + FcPattern *pattern; +} Font; + +/* Drawing Context */ +typedef struct { + Color *col; + size_t collen; + Font font, bfont, ifont, ibfont; + GC gc; +} DC; + +static inline ushort sixd_to_16bit(int); +static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int); +static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int); +static void xdrawglyph(Glyph, int, int); +static void xclear(int, int, int, int); +static int xgeommasktogravity(int); +static int ximopen(Display *); +static void ximinstantiate(Display *, XPointer, XPointer); +static void ximdestroy(XIM, XPointer, XPointer); +static int xicdestroy(XIC, XPointer, XPointer); +static void xinit(int, int); +static void cresize(int, int); +static void xresize(int, int); +static void xhints(void); +static int xloadcolor(int, const char *, Color *); +static int xloadfont(Font *, FcPattern *); +static void xloadfonts(const char *, double); +static void xunloadfont(Font *); +static void xunloadfonts(void); +static void xsetenv(void); +static void xseturgency(int); +static int evcol(XEvent *); +static int evrow(XEvent *); + +static void expose(XEvent *); +static void visibility(XEvent *); +static void unmap(XEvent *); +static void kpress(XEvent *); +static void cmessage(XEvent *); +static void resize(XEvent *); +static void focus(XEvent *); +static uint buttonmask(uint); +static int mouseaction(XEvent *, uint); +static void brelease(XEvent *); +static void bpress(XEvent *); +static void bmotion(XEvent *); +static void propnotify(XEvent *); +static void selnotify(XEvent *); +static void selclear_(XEvent *); +static void selrequest(XEvent *); +static void setsel(char *, Time); +static void mousesel(XEvent *, int); +static void mousereport(XEvent *); +static char *kmap(KeySym, uint); +static int match(uint, uint); + +static void run(void); +static void usage(void); + +static void (*handler[LASTEvent])(XEvent *) = { + [KeyPress] = kpress, + [ClientMessage] = cmessage, + [ConfigureNotify] = resize, + [VisibilityNotify] = visibility, + [UnmapNotify] = unmap, + [Expose] = expose, + [FocusIn] = focus, + [FocusOut] = focus, + [MotionNotify] = bmotion, + [ButtonPress] = bpress, + [ButtonRelease] = brelease, +/* + * Uncomment if you want the selection to disappear when you select something + * different in another window. + */ +/* [SelectionClear] = selclear_, */ + [SelectionNotify] = selnotify, +/* + * PropertyNotify is only turned on when there is some INCR transfer happening + * for the selection retrieval. + */ + [PropertyNotify] = propnotify, + [SelectionRequest] = selrequest, +}; + +/* Globals */ +static DC dc; +static XWindow xw; +static XSelection xsel; +static TermWindow win; + +/* Font Ring Cache */ +enum { + FRC_NORMAL, + FRC_ITALIC, + FRC_BOLD, + FRC_ITALICBOLD +}; + +typedef struct { + XftFont *font; + int flags; + Rune unicodep; +} Fontcache; + +/* Fontcache is an array now. A new font will be appended to the array. */ +static Fontcache *frc = NULL; +static int frclen = 0; +static int frccap = 0; +static char *usedfont = NULL; +static double usedfontsize = 0; +static double defaultfontsize = 0; + +static char *opt_alpha = NULL; +static char *opt_class = NULL; +static char **opt_cmd = NULL; +static char *opt_embed = NULL; +static char *opt_font = NULL; +static char *opt_io = NULL; +static char *opt_line = NULL; +static char *opt_name = NULL; +static char *opt_title = NULL; + +static int oldbutton = 3; /* button event on startup: 3 = release */ + +void +clipcopy(const Arg *dummy) +{ + Atom clipboard; + + free(xsel.clipboard); + xsel.clipboard = NULL; + + if (xsel.primary != NULL) { + xsel.clipboard = xstrdup(xsel.primary); + clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); + XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime); + } +} + +void +clippaste(const Arg *dummy) +{ + Atom clipboard; + + clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); + XConvertSelection(xw.dpy, clipboard, xsel.xtarget, clipboard, + xw.win, CurrentTime); +} + +void +selpaste(const Arg *dummy) +{ + XConvertSelection(xw.dpy, XA_PRIMARY, xsel.xtarget, XA_PRIMARY, + xw.win, CurrentTime); +} + +void +numlock(const Arg *dummy) +{ + win.mode ^= MODE_NUMLOCK; +} + +void +zoom(const Arg *arg) +{ + Arg larg; + + larg.f = usedfontsize + arg->f; + zoomabs(&larg); +} + +void +zoomabs(const Arg *arg) +{ + xunloadfonts(); + xloadfonts(usedfont, arg->f); + cresize(0, 0); + redraw(); + xhints(); +} + +void +zoomreset(const Arg *arg) +{ + Arg larg; + + if (defaultfontsize > 0) { + larg.f = defaultfontsize; + zoomabs(&larg); + } +} + +void +ttysend(const Arg *arg) +{ + ttywrite(arg->s, strlen(arg->s), 1); +} + +int +evcol(XEvent *e) +{ + int x = e->xbutton.x - borderpx; + LIMIT(x, 0, win.tw - 1); + return x / win.cw; +} + +int +evrow(XEvent *e) +{ + int y = e->xbutton.y - borderpx; + LIMIT(y, 0, win.th - 1); + return y / win.ch; +} + +void +mousesel(XEvent *e, int done) +{ + int type, seltype = SEL_REGULAR; + uint state = e->xbutton.state & ~(Button1Mask | forcemousemod); + + for (type = 1; type < LEN(selmasks); ++type) { + if (match(selmasks[type], state)) { + seltype = type; + break; + } + } + selextend(evcol(e), evrow(e), seltype, done); + if (done) + setsel(getsel(), e->xbutton.time); +} + +void +mousereport(XEvent *e) +{ + int len, x = evcol(e), y = evrow(e), + button = e->xbutton.button, state = e->xbutton.state; + char buf[40]; + static int ox, oy; + + /* from urxvt */ + if (e->xbutton.type == MotionNotify) { + if (x == ox && y == oy) + return; + if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY)) + return; + /* MOUSE_MOTION: no reporting if no button is pressed */ + if (IS_SET(MODE_MOUSEMOTION) && oldbutton == 3) + return; + + button = oldbutton + 32; + ox = x; + oy = y; + } else { + if (!IS_SET(MODE_MOUSESGR) && e->xbutton.type == ButtonRelease) { + button = 3; + } else { + button -= Button1; + if (button >= 7) + button += 128 - 7; + else if (button >= 3) + button += 64 - 3; + } + if (e->xbutton.type == ButtonPress) { + oldbutton = button; + ox = x; + oy = y; + } else if (e->xbutton.type == ButtonRelease) { + oldbutton = 3; + /* MODE_MOUSEX10: no button release reporting */ + if (IS_SET(MODE_MOUSEX10)) + return; + if (button == 64 || button == 65) + return; + } + } + + if (!IS_SET(MODE_MOUSEX10)) { + button += ((state & ShiftMask ) ? 4 : 0) + + ((state & Mod4Mask ) ? 8 : 0) + + ((state & ControlMask) ? 16 : 0); + } + + if (IS_SET(MODE_MOUSESGR)) { + len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c", + button, x+1, y+1, + e->xbutton.type == ButtonRelease ? 'm' : 'M'); + } else if (x < 223 && y < 223) { + len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", + 32+button, 32+x+1, 32+y+1); + } else { + return; + } + + ttywrite(buf, len, 0); +} + +uint +buttonmask(uint button) +{ + return button == Button1 ? Button1Mask + : button == Button2 ? Button2Mask + : button == Button3 ? Button3Mask + : button == Button4 ? Button4Mask + : button == Button5 ? Button5Mask + : 0; +} + +int +mouseaction(XEvent *e, uint release) +{ + MouseShortcut *ms; + + /* ignore Buttonmask for Button - it's set on release */ + uint state = e->xbutton.state & ~buttonmask(e->xbutton.button); + + for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { + if (ms->release == release && + ms->button == e->xbutton.button && + (match(ms->mod, state) || /* exact or forced */ + match(ms->mod, state & ~forcemousemod))) { + ms->func(&(ms->arg)); + return 1; + } + } + + return 0; +} + +void +bpress(XEvent *e) +{ + struct timespec now; + int snap; + + if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { + mousereport(e); + return; + } + + if (mouseaction(e, 0)) + return; + + if (e->xbutton.button == Button1) { + /* + * If the user clicks below predefined timeouts specific + * snapping behaviour is exposed. + */ + clock_gettime(CLOCK_MONOTONIC, &now); + if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) { + snap = SNAP_LINE; + } else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) { + snap = SNAP_WORD; + } else { + snap = 0; + } + xsel.tclick2 = xsel.tclick1; + xsel.tclick1 = now; + + selstart(evcol(e), evrow(e), snap); + } +} + +void +propnotify(XEvent *e) +{ + XPropertyEvent *xpev; + Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); + + xpev = &e->xproperty; + if (xpev->state == PropertyNewValue && + (xpev->atom == XA_PRIMARY || + xpev->atom == clipboard)) { + selnotify(e); + } +} + +void +selnotify(XEvent *e) +{ + ulong nitems, ofs, rem; + int format; + uchar *data, *last, *repl; + Atom type, incratom, property = None; + + incratom = XInternAtom(xw.dpy, "INCR", 0); + + ofs = 0; + if (e->type == SelectionNotify) + property = e->xselection.property; + else if (e->type == PropertyNotify) + property = e->xproperty.atom; + + if (property == None) + return; + + do { + if (XGetWindowProperty(xw.dpy, xw.win, property, ofs, + BUFSIZ/4, False, AnyPropertyType, + &type, &format, &nitems, &rem, + &data)) { + fprintf(stderr, "Clipboard allocation failed\n"); + return; + } + + if (e->type == PropertyNotify && nitems == 0 && rem == 0) { + /* + * If there is some PropertyNotify with no data, then + * this is the signal of the selection owner that all + * data has been transferred. We won't need to receive + * PropertyNotify events anymore. + */ + MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask); + XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, + &xw.attrs); + } + + if (type == incratom) { + /* + * Activate the PropertyNotify events so we receive + * when the selection owner does send us the next + * chunk of data. + */ + MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask); + XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, + &xw.attrs); + + /* + * Deleting the property is the transfer start signal. + */ + XDeleteProperty(xw.dpy, xw.win, (int)property); + continue; + } + + /* + * As seen in getsel: + * Line endings are inconsistent in the terminal and GUI world + * copy and pasting. When receiving some selection data, + * replace all '\n' with '\r'. + * FIXME: Fix the computer world. + */ + repl = data; + last = data + nitems * format / 8; + while ((repl = memchr(repl, '\n', last - repl))) { + *repl++ = '\r'; + } + + if (IS_SET(MODE_BRCKTPASTE) && ofs == 0) + ttywrite("\033[200~", 6, 0); + ttywrite((char *)data, nitems * format / 8, 1); + if (IS_SET(MODE_BRCKTPASTE) && rem == 0) + ttywrite("\033[201~", 6, 0); + XFree(data); + /* number of 32-bit chunks returned */ + ofs += nitems * format / 32; + } while (rem > 0); + + /* + * Deleting the property again tells the selection owner to send the + * next data chunk in the property. + */ + XDeleteProperty(xw.dpy, xw.win, (int)property); +} + +void +xclipcopy(void) +{ + clipcopy(NULL); +} + +void +selclear_(XEvent *e) +{ + selclear(); +} + +void +selrequest(XEvent *e) +{ + XSelectionRequestEvent *xsre; + XSelectionEvent xev; + Atom xa_targets, string, clipboard; + char *seltext; + + xsre = (XSelectionRequestEvent *) e; + xev.type = SelectionNotify; + xev.requestor = xsre->requestor; + xev.selection = xsre->selection; + xev.target = xsre->target; + xev.time = xsre->time; + if (xsre->property == None) + xsre->property = xsre->target; + + /* reject */ + xev.property = None; + + xa_targets = XInternAtom(xw.dpy, "TARGETS", 0); + if (xsre->target == xa_targets) { + /* respond with the supported type */ + string = xsel.xtarget; + XChangeProperty(xsre->display, xsre->requestor, xsre->property, + XA_ATOM, 32, PropModeReplace, + (uchar *) &string, 1); + xev.property = xsre->property; + } else if (xsre->target == xsel.xtarget || xsre->target == XA_STRING) { + /* + * xith XA_STRING non ascii characters may be incorrect in the + * requestor. It is not our problem, use utf8. + */ + clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); + if (xsre->selection == XA_PRIMARY) { + seltext = xsel.primary; + } else if (xsre->selection == clipboard) { + seltext = xsel.clipboard; + } else { + fprintf(stderr, + "Unhandled clipboard selection 0x%lx\n", + xsre->selection); + return; + } + if (seltext != NULL) { + XChangeProperty(xsre->display, xsre->requestor, + xsre->property, xsre->target, + 8, PropModeReplace, + (uchar *)seltext, strlen(seltext)); + xev.property = xsre->property; + } + } + + /* all done, send a notification to the listener */ + if (!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent *) &xev)) + fprintf(stderr, "Error sending SelectionNotify event\n"); +} + +void +setsel(char *str, Time t) +{ + if (!str) + return; + + free(xsel.primary); + xsel.primary = str; + + XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); + if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) + selclear(); +} + +void +xsetsel(char *str) +{ + setsel(str, CurrentTime); +} + +void +brelease(XEvent *e) +{ + if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { + mousereport(e); + return; + } + + if (mouseaction(e, 1)) + return; + if (e->xbutton.button == Button1) + mousesel(e, 1); +} + +void +bmotion(XEvent *e) +{ + if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { + mousereport(e); + return; + } + + mousesel(e, 0); +} + +void +cresize(int width, int height) +{ + int col, row; + + if (width != 0) + win.w = width; + if (height != 0) + win.h = height; + + col = (win.w - 2 * borderpx) / win.cw; + row = (win.h - 2 * borderpx) / win.ch; + col = MAX(1, col); + row = MAX(1, row); + + tresize(col, row); + xresize(col, row); + ttyresize(win.tw, win.th); +} + +void +xresize(int col, int row) +{ + win.tw = col * win.cw; + win.th = row * win.ch; + + XFreePixmap(xw.dpy, xw.buf); + xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, + xw.depth); + XftDrawChange(xw.draw, xw.buf); + xclear(0, 0, win.w, win.h); + + /* resize to new width */ + xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec)); +} + +ushort +sixd_to_16bit(int x) +{ + return x == 0 ? 0 : 0x3737 + 0x2828 * x; +} + +int +xloadcolor(int i, const char *name, Color *ncolor) +{ + XRenderColor color = { .alpha = 0xffff }; + + if (!name) { + if (BETWEEN(i, 16, 255)) { /* 256 color */ + if (i < 6*6*6+16) { /* same colors as xterm */ + color.red = sixd_to_16bit( ((i-16)/36)%6 ); + color.green = sixd_to_16bit( ((i-16)/6) %6 ); + color.blue = sixd_to_16bit( ((i-16)/1) %6 ); + } else { /* greyscale */ + color.red = 0x0808 + 0x0a0a * (i - (6*6*6+16)); + color.green = color.blue = color.red; + } + return XftColorAllocValue(xw.dpy, xw.vis, + xw.cmap, &color, ncolor); + } else + name = colorname[i]; + } + + return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor); +} + +void +xloadcols(void) +{ + int i; + static int loaded; + Color *cp; + + if (loaded) { + for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp) + XftColorFree(xw.dpy, xw.vis, xw.cmap, cp); + } else { + dc.collen = MAX(LEN(colorname), 256); + dc.col = xmalloc(dc.collen * sizeof(Color)); + } + + for (i = 0; i < dc.collen; i++) + if (!xloadcolor(i, NULL, &dc.col[i])) { + if (colorname[i]) + die("could not allocate color '%s'\n", colorname[i]); + else + die("could not allocate color %d\n", i); + } + + /* set alpha value of bg color */ + if (opt_alpha) + alpha = strtof(opt_alpha, NULL); + dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); + dc.col[defaultbg].pixel &= 0x00FFFFFF; + dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24; + loaded = 1; +} + +int +xsetcolorname(int x, const char *name) +{ + Color ncolor; + + if (!BETWEEN(x, 0, dc.collen)) + return 1; + + if (!xloadcolor(x, name, &ncolor)) + return 1; + + XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]); + dc.col[x] = ncolor; + + return 0; +} + +/* + * Absolute coordinates. + */ +void +xclear(int x1, int y1, int x2, int y2) +{ + XftDrawRect(xw.draw, + &dc.col[IS_SET(MODE_REVERSE)? defaultfg : defaultbg], + x1, y1, x2-x1, y2-y1); +} + +void +xhints(void) +{ + XClassHint class = {opt_name ? opt_name : termname, + opt_class ? opt_class : termname}; + XWMHints wm = {.flags = InputHint, .input = 1}; + XSizeHints *sizeh; + + sizeh = XAllocSizeHints(); + + sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; + sizeh->height = win.h; + sizeh->width = win.w; + sizeh->height_inc = win.ch; + sizeh->width_inc = win.cw; + sizeh->base_height = 2 * borderpx; + sizeh->base_width = 2 * borderpx; + sizeh->min_height = win.ch + 2 * borderpx; + sizeh->min_width = win.cw + 2 * borderpx; + if (xw.isfixed) { + sizeh->flags |= PMaxSize; + sizeh->min_width = sizeh->max_width = win.w; + sizeh->min_height = sizeh->max_height = win.h; + } + if (xw.gm & (XValue|YValue)) { + sizeh->flags |= USPosition | PWinGravity; + sizeh->x = xw.l; + sizeh->y = xw.t; + sizeh->win_gravity = xgeommasktogravity(xw.gm); + } + + XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm, + &class); + XFree(sizeh); +} + +int +xgeommasktogravity(int mask) +{ + switch (mask & (XNegative|YNegative)) { + case 0: + return NorthWestGravity; + case XNegative: + return NorthEastGravity; + case YNegative: + return SouthWestGravity; + } + + return SouthEastGravity; +} + +int +xloadfont(Font *f, FcPattern *pattern) +{ + FcPattern *configured; + FcPattern *match; + FcResult result; + XGlyphInfo extents; + int wantattr, haveattr; + + /* + * Manually configure instead of calling XftMatchFont + * so that we can use the configured pattern for + * "missing glyph" lookups. + */ + configured = FcPatternDuplicate(pattern); + if (!configured) + return 1; + + FcConfigSubstitute(NULL, configured, FcMatchPattern); + XftDefaultSubstitute(xw.dpy, xw.scr, configured); + + match = FcFontMatch(NULL, configured, &result); + if (!match) { + FcPatternDestroy(configured); + return 1; + } + + if (!(f->match = XftFontOpenPattern(xw.dpy, match))) { + FcPatternDestroy(configured); + FcPatternDestroy(match); + return 1; + } + + if ((XftPatternGetInteger(pattern, "slant", 0, &wantattr) == + XftResultMatch)) { + /* + * Check if xft was unable to find a font with the appropriate + * slant but gave us one anyway. Try to mitigate. + */ + if ((XftPatternGetInteger(f->match->pattern, "slant", 0, + &haveattr) != XftResultMatch) || haveattr < wantattr) { + f->badslant = 1; + fputs("font slant does not match\n", stderr); + } + } + + if ((XftPatternGetInteger(pattern, "weight", 0, &wantattr) == + XftResultMatch)) { + if ((XftPatternGetInteger(f->match->pattern, "weight", 0, + &haveattr) != XftResultMatch) || haveattr != wantattr) { + f->badweight = 1; + fputs("font weight does not match\n", stderr); + } + } + + XftTextExtentsUtf8(xw.dpy, f->match, + (const FcChar8 *) ascii_printable, + strlen(ascii_printable), &extents); + + f->set = NULL; + f->pattern = configured; + + f->ascent = f->match->ascent; + f->descent = f->match->descent; + f->lbearing = 0; + f->rbearing = f->match->max_advance_width; + + f->height = f->ascent + f->descent; + f->width = DIVCEIL(extents.xOff, strlen(ascii_printable)); + + return 0; +} + +void +xloadfonts(const char *fontstr, double fontsize) +{ + FcPattern *pattern; + double fontval; + + if (fontstr[0] == '-') + pattern = XftXlfdParse(fontstr, False, False); + else + pattern = FcNameParse((const FcChar8 *)fontstr); + + if (!pattern) + die("can't open font %s\n", fontstr); + + if (fontsize > 1) { + FcPatternDel(pattern, FC_PIXEL_SIZE); + FcPatternDel(pattern, FC_SIZE); + FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize); + usedfontsize = fontsize; + } else { + if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) == + FcResultMatch) { + usedfontsize = fontval; + } else if (FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval) == + FcResultMatch) { + usedfontsize = -1; + } else { + /* + * Default font size is 12, if none given. This is to + * have a known usedfontsize value. + */ + FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12); + usedfontsize = 12; + } + defaultfontsize = usedfontsize; + } + + if (xloadfont(&dc.font, pattern)) + die("can't open font %s\n", fontstr); + + if (usedfontsize < 0) { + FcPatternGetDouble(dc.font.match->pattern, + FC_PIXEL_SIZE, 0, &fontval); + usedfontsize = fontval; + if (fontsize == 0) + defaultfontsize = fontval; + } + + /* Setting character width and height. */ + win.cw = ceilf(dc.font.width * cwscale); + win.ch = ceilf(dc.font.height * chscale); + + FcPatternDel(pattern, FC_SLANT); + FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); + if (xloadfont(&dc.ifont, pattern)) + die("can't open font %s\n", fontstr); + + FcPatternDel(pattern, FC_WEIGHT); + FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); + if (xloadfont(&dc.ibfont, pattern)) + die("can't open font %s\n", fontstr); + + FcPatternDel(pattern, FC_SLANT); + FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); + if (xloadfont(&dc.bfont, pattern)) + die("can't open font %s\n", fontstr); + + FcPatternDestroy(pattern); +} + +void +xunloadfont(Font *f) +{ + XftFontClose(xw.dpy, f->match); + FcPatternDestroy(f->pattern); + if (f->set) + FcFontSetDestroy(f->set); +} + +void +xunloadfonts(void) +{ + /* Free the loaded fonts in the font cache. */ + while (frclen > 0) + XftFontClose(xw.dpy, frc[--frclen].font); + + xunloadfont(&dc.font); + xunloadfont(&dc.bfont); + xunloadfont(&dc.ifont); + xunloadfont(&dc.ibfont); +} + +int +ximopen(Display *dpy) +{ + XIMCallback imdestroy = { .client_data = NULL, .callback = ximdestroy }; + XICCallback icdestroy = { .client_data = NULL, .callback = xicdestroy }; + + xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL); + if (xw.ime.xim == NULL) + return 0; + + if (XSetIMValues(xw.ime.xim, XNDestroyCallback, &imdestroy, NULL)) + fprintf(stderr, "XSetIMValues: " + "Could not set XNDestroyCallback.\n"); + + xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot, + NULL); + + if (xw.ime.xic == NULL) { + xw.ime.xic = XCreateIC(xw.ime.xim, XNInputStyle, + XIMPreeditNothing | XIMStatusNothing, + XNClientWindow, xw.win, + XNDestroyCallback, &icdestroy, + NULL); + } + if (xw.ime.xic == NULL) + fprintf(stderr, "XCreateIC: Could not create input context.\n"); + + return 1; +} + +void +ximinstantiate(Display *dpy, XPointer client, XPointer call) +{ + if (ximopen(dpy)) + XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, + ximinstantiate, NULL); +} + +void +ximdestroy(XIM xim, XPointer client, XPointer call) +{ + xw.ime.xim = NULL; + XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, + ximinstantiate, NULL); + XFree(xw.ime.spotlist); +} + +int +xicdestroy(XIC xim, XPointer client, XPointer call) +{ + xw.ime.xic = NULL; + return 1; +} + +void +xinit(int cols, int rows) +{ + XGCValues gcvalues; + Cursor cursor; + Window parent; + pid_t thispid = getpid(); + XColor xmousefg, xmousebg; + XWindowAttributes attr; + XVisualInfo vis; + + if (!(xw.dpy = XOpenDisplay(NULL))) + die("can't open display\n"); + xw.scr = XDefaultScreen(xw.dpy); + + if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) { + parent = XRootWindow(xw.dpy, xw.scr); + xw.depth = 32; + } else { + XGetWindowAttributes(xw.dpy, parent, &attr); + xw.depth = attr.depth; + } + + XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis); + xw.vis = vis.visual; + + /* font */ + if (!FcInit()) + die("could not init fontconfig.\n"); + + usedfont = (opt_font == NULL)? font : opt_font; + xloadfonts(usedfont, 0); + + /* colors */ + xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None); + xloadcols(); + + /* adjust fixed window geometry */ + win.w = 2 * borderpx + cols * win.cw; + win.h = 2 * borderpx + rows * win.ch; + if (xw.gm & XNegative) + xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; + if (xw.gm & YNegative) + xw.t += DisplayHeight(xw.dpy, xw.scr) - win.h - 2; + + /* Events */ + xw.attrs.background_pixel = dc.col[defaultbg].pixel; + xw.attrs.border_pixel = dc.col[defaultbg].pixel; + xw.attrs.bit_gravity = NorthWestGravity; + xw.attrs.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask + | ExposureMask | VisibilityChangeMask | StructureNotifyMask + | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; + xw.attrs.colormap = xw.cmap; + + xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, + win.w, win.h, 0, xw.depth, InputOutput, + xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity + | CWEventMask | CWColormap, &xw.attrs); + + memset(&gcvalues, 0, sizeof(gcvalues)); + gcvalues.graphics_exposures = False; + xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth); + dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues); + XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); + XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); + + /* font spec buffer */ + xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec)); + + /* Xft rendering context */ + xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); + + /* input methods */ + if (!ximopen(xw.dpy)) { + XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, + ximinstantiate, NULL); + } + + /* white cursor, black outline */ + cursor = XCreateFontCursor(xw.dpy, mouseshape); + XDefineCursor(xw.dpy, xw.win, cursor); + + if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) { + xmousefg.red = 0xffff; + xmousefg.green = 0xffff; + xmousefg.blue = 0xffff; + } + + if (XParseColor(xw.dpy, xw.cmap, colorname[mousebg], &xmousebg) == 0) { + xmousebg.red = 0x0000; + xmousebg.green = 0x0000; + xmousebg.blue = 0x0000; + } + + XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg); + + xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); + xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); + xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False); + xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False); + XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1); + + xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False); + XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32, + PropModeReplace, (uchar *)&thispid, 1); + + win.mode = MODE_NUMLOCK; + resettitle(); + xhints(); + XMapWindow(xw.dpy, xw.win); + XSync(xw.dpy, False); + + clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1); + clock_gettime(CLOCK_MONOTONIC, &xsel.tclick2); + xsel.primary = NULL; + xsel.clipboard = NULL; + xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0); + if (xsel.xtarget == None) + xsel.xtarget = XA_STRING; +} + +int +xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) +{ + float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp; + ushort mode, prevmode = USHRT_MAX; + Font *font = &dc.font; + int frcflags = FRC_NORMAL; + float runewidth = win.cw; + Rune rune; + FT_UInt glyphidx; + FcResult fcres; + FcPattern *fcpattern, *fontpattern; + FcFontSet *fcsets[] = { NULL }; + FcCharSet *fccharset; + int i, f, numspecs = 0; + + for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) { + /* Fetch rune and mode for current glyph. */ + rune = glyphs[i].u; + mode = glyphs[i].mode; + + /* Skip dummy wide-character spacing. */ + if (mode == ATTR_WDUMMY) + continue; + + /* Determine font for glyph if different from previous glyph. */ + if (prevmode != mode) { + prevmode = mode; + font = &dc.font; + frcflags = FRC_NORMAL; + runewidth = win.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f); + 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; + } + 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, + 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; + xp += runewidth; + numspecs++; + } + + return numspecs; +} + +void +xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) +{ + int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); + int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, + width = charlen * win.cw; + Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; + XRenderColor colfg, colbg; + XRectangle r; + + /* Fallback on color display for attributes not supported by the font */ + if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) { + if (dc.ibfont.badslant || dc.ibfont.badweight) + base.fg = defaultattr; + } else if ((base.mode & ATTR_ITALIC && dc.ifont.badslant) || + (base.mode & ATTR_BOLD && dc.bfont.badweight)) { + base.fg = defaultattr; + } + + if (IS_TRUECOL(base.fg)) { + colfg.alpha = 0xffff; + colfg.red = TRUERED(base.fg); + colfg.green = TRUEGREEN(base.fg); + colfg.blue = TRUEBLUE(base.fg); + XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &truefg); + fg = &truefg; + } else { + fg = &dc.col[base.fg]; + } + + if (IS_TRUECOL(base.bg)) { + colbg.alpha = 0xffff; + colbg.green = TRUEGREEN(base.bg); + colbg.red = TRUERED(base.bg); + colbg.blue = TRUEBLUE(base.bg); + XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &truebg); + bg = &truebg; + } else { + bg = &dc.col[base.bg]; + } + + /* Change basic system colors [0-7] to bright system colors [8-15] */ + if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7)) + fg = &dc.col[base.fg + 8]; + + if (IS_SET(MODE_REVERSE)) { + if (fg == &dc.col[defaultfg]) { + fg = &dc.col[defaultbg]; + } else { + colfg.red = ~fg->color.red; + colfg.green = ~fg->color.green; + colfg.blue = ~fg->color.blue; + colfg.alpha = fg->color.alpha; + XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, + &revfg); + fg = &revfg; + } + + if (bg == &dc.col[defaultbg]) { + bg = &dc.col[defaultfg]; + } else { + colbg.red = ~bg->color.red; + colbg.green = ~bg->color.green; + colbg.blue = ~bg->color.blue; + colbg.alpha = bg->color.alpha; + XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, + &revbg); + bg = &revbg; + } + } + + if ((base.mode & ATTR_BOLD_FAINT) == ATTR_FAINT) { + colfg.red = fg->color.red / 2; + colfg.green = fg->color.green / 2; + colfg.blue = fg->color.blue / 2; + colfg.alpha = fg->color.alpha; + XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &revfg); + fg = &revfg; + } + + if (base.mode & ATTR_REVERSE) { + temp = fg; + fg = bg; + bg = temp; + } + + if (base.mode & ATTR_BLINK && win.mode & MODE_BLINK) + fg = bg; + + if (base.mode & ATTR_INVISIBLE) + fg = bg; + + /* Intelligent cleaning up of the borders. */ + if (x == 0) { + xclear(0, (y == 0)? 0 : winy, borderpx, + winy + win.ch + + ((winy + win.ch >= borderpx + win.th)? win.h : 0)); + } + if (winx + width >= borderpx + win.tw) { + xclear(winx + width, (y == 0)? 0 : winy, win.w, + ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); + } + if (y == 0) + xclear(winx, 0, winx + width, borderpx); + if (winy + win.ch >= borderpx + win.th) + xclear(winx, winy + win.ch, winx + width, win.h); + + /* Clean up the region we want to draw to. */ + XftDrawRect(xw.draw, bg, winx, winy, width, win.ch); + + /* Set the clip region because Xft is sometimes dirty. */ + r.x = 0; + r.y = 0; + r.height = win.ch; + r.width = width; + XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1); + + /* Render the glyphs. */ + XftDrawGlyphFontSpec(xw.draw, fg, specs, len); + + /* Render underline and strikethrough. */ + if (base.mode & ATTR_UNDERLINE) { + XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1, + width, 1); + } + + if (base.mode & ATTR_STRUCK) { + XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3, + width, 1); + } + + /* Reset clip to none. */ + XftDrawSetClip(xw.draw, 0); +} + +void +xdrawglyph(Glyph g, int x, int y) +{ + int numspecs; + XftGlyphFontSpec spec; + + numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); + xdrawglyphfontspecs(&spec, g, numspecs, x, y); +} + +void +xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) +{ + Color drawcol; + + /* remove the old cursor */ + if (selected(ox, oy)) + og.mode ^= ATTR_REVERSE; + xdrawglyph(og, ox, oy); + + if (IS_SET(MODE_HIDE)) + return; + + /* + * Select the right color for the right mode. + */ + g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE; + + if (IS_SET(MODE_REVERSE)) { + g.mode |= ATTR_REVERSE; + g.bg = defaultfg; + if (selected(cx, cy)) { + drawcol = dc.col[defaultcs]; + g.fg = defaultrcs; + } else { + drawcol = dc.col[defaultrcs]; + g.fg = defaultcs; + } + } else { + if (selected(cx, cy)) { + g.fg = defaultfg; + g.bg = defaultrcs; + } else { + g.fg = defaultbg; + g.bg = defaultcs; + } + drawcol = dc.col[g.bg]; + } + + /* draw the new one */ + if (IS_SET(MODE_FOCUSED)) { + switch (win.cursor) { + case 7: /* st extension */ + g.u = 0x2603; /* snowman (U+2603) */ + /* FALLTHROUGH */ + case 0: /* Blinking Block */ + case 1: /* Blinking Block (Default) */ + case 2: /* Steady Block */ + xdrawglyph(g, cx, cy); + break; + case 3: /* Blinking Underline */ + case 4: /* Steady Underline */ + XftDrawRect(xw.draw, &drawcol, + borderpx + cx * win.cw, + borderpx + (cy + 1) * win.ch - \ + cursorthickness, + win.cw, cursorthickness); + break; + case 5: /* Blinking bar */ + case 6: /* Steady bar */ + XftDrawRect(xw.draw, &drawcol, + borderpx + cx * win.cw, + borderpx + cy * win.ch, + cursorthickness, win.ch); + break; + } + } else { + XftDrawRect(xw.draw, &drawcol, + borderpx + cx * win.cw, + borderpx + cy * win.ch, + win.cw - 1, 1); + XftDrawRect(xw.draw, &drawcol, + borderpx + cx * win.cw, + borderpx + cy * win.ch, + 1, win.ch - 1); + XftDrawRect(xw.draw, &drawcol, + borderpx + (cx + 1) * win.cw - 1, + borderpx + cy * win.ch, + 1, win.ch - 1); + XftDrawRect(xw.draw, &drawcol, + borderpx + cx * win.cw, + borderpx + (cy + 1) * win.ch - 1, + win.cw, 1); + } +} + +void +xsetenv(void) +{ + char buf[sizeof(long) * 8 + 1]; + + snprintf(buf, sizeof(buf), "%lu", xw.win); + setenv("WINDOWID", buf, 1); +} + +void +xseticontitle(char *p) +{ + XTextProperty prop; + DEFAULT(p, opt_title); + + Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, + &prop); + XSetWMIconName(xw.dpy, xw.win, &prop); + XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname); + XFree(prop.value); +} + +void +xsettitle(char *p) +{ + XTextProperty prop; + DEFAULT(p, opt_title); + + Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, + &prop); + XSetWMName(xw.dpy, xw.win, &prop); + XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname); + XFree(prop.value); +} + +int +xstartdraw(void) +{ + return IS_SET(MODE_VISIBLE); +} + +void +xdrawline(Line line, int x1, int y1, int x2) +{ + int i, x, ox, numspecs; + Glyph base, new; + XftGlyphFontSpec *specs = xw.specbuf; + + numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1); + i = ox = 0; + for (x = x1; x < x2 && i < numspecs; x++) { + new = line[x]; + if (new.mode == ATTR_WDUMMY) + continue; + if (selected(x, y1)) + new.mode ^= ATTR_REVERSE; + if (i > 0 && ATTRCMP(base, new)) { + xdrawglyphfontspecs(specs, base, i, ox, y1); + specs += i; + numspecs -= i; + i = 0; + } + if (i == 0) { + ox = x; + base = new; + } + i++; + } + if (i > 0) + xdrawglyphfontspecs(specs, base, i, ox, y1); +} + +void +xfinishdraw(void) +{ + XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, + win.h, 0, 0); + XSetForeground(xw.dpy, dc.gc, + dc.col[IS_SET(MODE_REVERSE)? + defaultfg : defaultbg].pixel); +} + +void +xximspot(int x, int y) +{ + if (xw.ime.xic == NULL) + return; + + xw.ime.spot.x = borderpx + x * win.cw; + xw.ime.spot.y = borderpx + (y + 1) * win.ch; + + XSetICValues(xw.ime.xic, XNPreeditAttributes, xw.ime.spotlist, NULL); +} + +void +expose(XEvent *ev) +{ + redraw(); +} + +void +visibility(XEvent *ev) +{ + XVisibilityEvent *e = &ev->xvisibility; + + MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE); +} + +void +unmap(XEvent *ev) +{ + win.mode &= ~MODE_VISIBLE; +} + +void +xsetpointermotion(int set) +{ + MODBIT(xw.attrs.event_mask, set, PointerMotionMask); + 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 +xsetcursor(int cursor) +{ + if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */ + return 1; + win.cursor = cursor; + return 0; +} + +void +xseturgency(int add) +{ + XWMHints *h = XGetWMHints(xw.dpy, xw.win); + + MODBIT(h->flags, add, XUrgencyHint); + XSetWMHints(xw.dpy, xw.win, h); + XFree(h); +} + +void +xbell(void) +{ + if (!(IS_SET(MODE_FOCUSED))) + xseturgency(1); + if (bellvolume) + XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); +} + +void +focus(XEvent *ev) +{ + XFocusChangeEvent *e = &ev->xfocus; + + if (e->mode == NotifyGrab) + return; + + if (ev->type == FocusIn) { + if (xw.ime.xic) + XSetICFocus(xw.ime.xic); + win.mode |= MODE_FOCUSED; + xseturgency(0); + if (IS_SET(MODE_FOCUS)) + ttywrite("\033[I", 3, 0); + } else { + if (xw.ime.xic) + XUnsetICFocus(xw.ime.xic); + win.mode &= ~MODE_FOCUSED; + if (IS_SET(MODE_FOCUS)) + ttywrite("\033[O", 3, 0); + } +} + +int +match(uint mask, uint state) +{ + return mask == XK_ANY_MOD || mask == (state & ~ignoremod); +} + +char* +kmap(KeySym k, uint state) +{ + Key *kp; + int i; + + /* Check for mapped keys out of X11 function keys. */ + for (i = 0; i < LEN(mappedkeys); i++) { + if (mappedkeys[i] == k) + break; + } + if (i == LEN(mappedkeys)) { + if ((k & 0xFFFF) < 0xFD00) + return NULL; + } + + for (kp = key; kp < key + LEN(key); kp++) { + if (kp->k != k) + continue; + + if (!match(kp->mask, state)) + continue; + + if (IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0) + continue; + if (IS_SET(MODE_NUMLOCK) && kp->appkey == 2) + continue; + + if (IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0) + continue; + + return kp->s; + } + + return NULL; +} + +void +kpress(XEvent *ev) +{ + XKeyEvent *e = &ev->xkey; + KeySym ksym; + char buf[64], *customkey; + int len; + Rune c; + Status status; + Shortcut *bp; + + if (IS_SET(MODE_KBDLOCK)) + return; + + if (xw.ime.xic) + len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status); + else + len = XLookupString(e, buf, sizeof buf, &ksym, NULL); + /* 1. shortcuts */ + for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { + if (ksym == bp->keysym && match(bp->mod, e->state)) { + bp->func(&(bp->arg)); + return; + } + } + + /* 2. custom keys from config.h */ + if ((customkey = kmap(ksym, e->state))) { + ttywrite(customkey, strlen(customkey), 1); + return; + } + + /* 3. composed string from input method */ + if (len == 0) + return; + if (len == 1 && e->state & Mod1Mask) { + if (IS_SET(MODE_8BIT)) { + if (*buf < 0177) { + c = *buf | 0x80; + len = utf8encode(c, buf); + } + } else { + buf[1] = buf[0]; + buf[0] = '\033'; + len = 2; + } + } + ttywrite(buf, len, 1); +} + +void +cmessage(XEvent *e) +{ + /* + * See xembed specs + * http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html + */ + if (e->xclient.message_type == xw.xembed && e->xclient.format == 32) { + if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) { + win.mode |= MODE_FOCUSED; + xseturgency(0); + } else if (e->xclient.data.l[1] == XEMBED_FOCUS_OUT) { + win.mode &= ~MODE_FOCUSED; + } + } else if (e->xclient.data.l[0] == xw.wmdeletewin) { + ttyhangup(); + exit(0); + } +} + +void +resize(XEvent *e) +{ + if (e->xconfigure.width == win.w && e->xconfigure.height == win.h) + return; + + cresize(e->xconfigure.width, e->xconfigure.height); +} + +void +run(void) +{ + XEvent ev; + int w = win.w, h = win.h; + fd_set rfd; + int xfd = XConnectionNumber(xw.dpy), ttyfd, xev, drawing; + struct timespec seltv, *tv, now, lastblink, trigger; + double timeout; + + /* Waiting for window mapping */ + do { + XNextEvent(xw.dpy, &ev); + /* + * This XFilterEvent call is required because of XOpenIM. It + * does filter out the key event and some client message for + * the input method too. + */ + if (XFilterEvent(&ev, None)) + continue; + if (ev.type == ConfigureNotify) { + w = ev.xconfigure.width; + h = ev.xconfigure.height; + } + } while (ev.type != MapNotify); + + ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd); + cresize(w, h); + + for (timeout = -1, drawing = 0, lastblink = (struct timespec){0};;) { + FD_ZERO(&rfd); + FD_SET(ttyfd, &rfd); + FD_SET(xfd, &rfd); + + if (XPending(xw.dpy)) + timeout = 0; /* existing events might not set xfd */ + + seltv.tv_sec = timeout / 1E3; + seltv.tv_nsec = 1E6 * (timeout - 1E3 * seltv.tv_sec); + tv = timeout >= 0 ? &seltv : NULL; + + if (pselect(MAX(xfd, ttyfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) { + if (errno == EINTR) + continue; + die("select failed: %s\n", strerror(errno)); + } + clock_gettime(CLOCK_MONOTONIC, &now); + + if (FD_ISSET(ttyfd, &rfd)) + ttyread(); + + xev = 0; + while (XPending(xw.dpy)) { + xev = 1; + XNextEvent(xw.dpy, &ev); + if (XFilterEvent(&ev, None)) + continue; + if (handler[ev.type]) + (handler[ev.type])(&ev); + } + + /* + * To reduce flicker and tearing, when new content or event + * triggers drawing, we first wait a bit to ensure we got + * everything, and if nothing new arrives - we draw. + * We start with trying to wait minlatency ms. If more content + * arrives sooner, we retry with shorter and shorter periods, + * and eventually draw even without idle after maxlatency ms. + * Typically this results in low latency while interacting, + * maximum latency intervals during `cat huge.txt`, and perfect + * sync with periodic updates from animations/key-repeats/etc. + */ + if (FD_ISSET(ttyfd, &rfd) || xev) { + if (!drawing) { + trigger = now; + drawing = 1; + } + timeout = (maxlatency - TIMEDIFF(now, trigger)) \ + / maxlatency * minlatency; + if (timeout > 0) + continue; /* we have time, try to find idle */ + } + + /* idle detected or maxlatency exhausted -> draw */ + timeout = -1; + if (blinktimeout && tattrset(ATTR_BLINK)) { + timeout = blinktimeout - TIMEDIFF(now, lastblink); + if (timeout <= 0) { + if (-timeout > blinktimeout) /* start visible */ + win.mode |= MODE_BLINK; + win.mode ^= MODE_BLINK; + tsetdirtattr(ATTR_BLINK); + lastblink = now; + timeout = blinktimeout; + } + } + + draw(); + XFlush(xw.dpy); + drawing = 0; + } +} + +void +usage(void) +{ + die("usage: %s [-aiv] [-c class] [-f font] [-g geometry]" + " [-n name] [-o file]\n" + " [-T title] [-t title] [-w windowid]" + " [[-e] command [args ...]]\n" + " %s [-aiv] [-c class] [-f font] [-g geometry]" + " [-n name] [-o file]\n" + " [-T title] [-t title] [-w windowid] -l line" + " [stty_args ...]\n", argv0, argv0); +} + +int +main(int argc, char *argv[]) +{ + xw.l = xw.t = 0; + xw.isfixed = False; + xsetcursor(cursorshape); + + ARGBEGIN { + case 'a': + allowaltscreen = 0; + break; + case 'A': + opt_alpha = EARGF(usage()); + break; + case 'c': + opt_class = EARGF(usage()); + break; + case 'e': + if (argc > 0) + --argc, ++argv; + goto run; + case 'f': + opt_font = EARGF(usage()); + break; + case 'g': + xw.gm = XParseGeometry(EARGF(usage()), + &xw.l, &xw.t, &cols, &rows); + break; + case 'i': + xw.isfixed = 1; + break; + case 'o': + opt_io = EARGF(usage()); + break; + case 'l': + opt_line = EARGF(usage()); + break; + case 'n': + opt_name = EARGF(usage()); + break; + case 't': + case 'T': + opt_title = EARGF(usage()); + break; + case 'w': + opt_embed = EARGF(usage()); + break; + case 'v': + die("%s " VERSION "\n", argv0); + break; + default: + usage(); + } ARGEND; + +run: + if (argc > 0) /* eat all remaining arguments */ + opt_cmd = argv; + + if (!opt_title) + opt_title = (opt_line || !opt_cmd) ? "st" : opt_cmd[0]; + + setlocale(LC_CTYPE, ""); + XSetLocaleModifiers(""); + cols = MAX(cols, 1); + rows = MAX(rows, 1); + tnew(cols, rows); + xinit(cols, rows); + xsetenv(); + selinit(); + run(); + + return 0; +} diff --git a/x.c.rej b/x.c.rej new file mode 100644 index 0000000..e8688f4 --- /dev/null +++ b/x.c.rej @@ -0,0 +1,108 @@ +--- x.c ++++ x.c +@@ -98,6 +98,7 @@ typedef struct { + XSetWindowAttributes attrs; + int scr; + int isfixed; /* is fixed geometry? */ ++ int depth; /* bit depth */ + int l, t; /* left and top offset */ + int gm; /* geometry mask */ + } XWindow; +@@ -229,6 +230,7 @@ static char *usedfont = NULL; + static double usedfontsize = 0; + static double defaultfontsize = 0; + ++static char *opt_alpha = NULL; + static char *opt_class = NULL; + static char **opt_cmd = NULL; + static char *opt_embed = NULL; +@@ -688,7 +690,7 @@ xresize(int col, int row) + + XFreePixmap(xw.dpy, xw.buf); + xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, +- DefaultDepth(xw.dpy, xw.scr)); ++ xw.depth); + XftDrawChange(xw.draw, xw.buf); + xclear(0, 0, win.w, win.h); + +@@ -748,6 +750,13 @@ xloadcols(void) + else + die("could not allocate color %d\n", i); + } ++ ++ /* set alpha value of bg color */ ++ if (opt_alpha) ++ alpha = strtof(opt_alpha, NULL); ++ dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); ++ dc.col[defaultbg].pixel &= 0x00FFFFFF; ++ dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24; + loaded = 1; + } + +@@ -1004,11 +1013,23 @@ xinit(int cols, int rows) + Window parent; + pid_t thispid = getpid(); + XColor xmousefg, xmousebg; ++ XWindowAttributes attr; ++ XVisualInfo vis; + + if (!(xw.dpy = XOpenDisplay(NULL))) + die("can't open display\n"); + xw.scr = XDefaultScreen(xw.dpy); +- xw.vis = XDefaultVisual(xw.dpy, xw.scr); ++ ++ if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) { ++ parent = XRootWindow(xw.dpy, xw.scr); ++ xw.depth = 32; ++ } else { ++ XGetWindowAttributes(xw.dpy, parent, &attr); ++ xw.depth = attr.depth; ++ } ++ ++ XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis); ++ xw.vis = vis.visual; + + /* font */ + if (!FcInit()) +@@ -1018,7 +1039,7 @@ xinit(int cols, int rows) + xloadfonts(usedfont, 0); + + /* colors */ +- xw.cmap = XDefaultColormap(xw.dpy, xw.scr); ++ xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None); + xloadcols(); + + /* adjust fixed window geometry */ +@@ -1038,19 +1059,15 @@ xinit(int cols, int rows) + | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; + xw.attrs.colormap = xw.cmap; + +- if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) +- parent = XRootWindow(xw.dpy, xw.scr); + xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, +- win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, ++ win.w, win.h, 0, xw.depth, InputOutput, + xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity + | CWEventMask | CWColormap, &xw.attrs); + + memset(&gcvalues, 0, sizeof(gcvalues)); + gcvalues.graphics_exposures = False; +- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, +- &gcvalues); +- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, +- DefaultDepth(xw.dpy, xw.scr)); ++ xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth); ++ dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues); + XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); + XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); + +@@ -1894,6 +1911,9 @@ main(int argc, char *argv[]) + case 'a': + allowaltscreen = 0; + break; ++ case 'A': ++ opt_alpha = EARGF(usage()); ++ break; + case 'c': + opt_class = EARGF(usage()); + break; diff --git a/x.o b/x.o new file mode 100644 index 0000000000000000000000000000000000000000..7a1d8b2b6fd48dc902e0eb3f7e716b4687b180dd GIT binary patch literal 75728 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 I+UxlL2Xw;kG5`Po literal 0 HcmV?d00001