From d9fa845fc4fb169c34b880aa11d2bee91f9d294b Mon Sep 17 00:00:00 2001 From: Sam Hoffman Date: Thu, 1 Jan 2026 13:10:24 -0500 Subject: [PATCH] patch: bold-is-not-bright --- config.h | 476 ++++++++++++ st | Bin 0 -> 108600 bytes st.o | Bin 0 -> 83304 bytes x.c | 4 - x.c.orig | 2108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ x.o | Bin 0 -> 75920 bytes 6 files changed, 2584 insertions(+), 4 deletions(-) create mode 100644 config.h create mode 100755 st create mode 100644 st.o create mode 100644 x.c.orig create mode 100644 x.o diff --git a/config.h b/config.h new file mode 100644 index 0000000..8b25d40 --- /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 = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; +static int borderpx = 2; + +/* + * What program is execed by st depends of these precedence rules: + * 1: program passed with -e + * 2: scroll and/or utmp + * 3: SHELL environment variable + * 4: value of shell in /etc/passwd + * 5: value of shell in config.h + */ +static char *shell = "/bin/sh"; +char *utmp = NULL; +/* scroll program: to enable use a string like "scroll" */ +char *scroll = NULL; +char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400"; + +/* identification sequence returned in DA and DECID */ +char *vtiden = "\033[?6c"; + +/* Kerning / character bounding-box multipliers */ +static float cwscale = 1.0; +static float chscale = 1.0; + +/* + * word delimiter string + * + * More advanced example: L" `'\"()[]{}" + */ +wchar_t *worddelimiters = L" "; + +/* selection timeouts (in milliseconds) */ +static unsigned int doubleclicktimeout = 300; +static unsigned int tripleclicktimeout = 600; + +/* alt screens */ +int allowaltscreen = 1; + +/* allow certain non-interactive (insecure) window operations such as: + setting the clipboard text */ +int allowwindowops = 0; + +/* + * draw latency range in ms - from new content/keypress/etc until drawing. + * within this range, st draws when content stops arriving (idle). mostly it's + * near minlatency, but it waits longer for slow updates to avoid partial draw. + * low minlatency will tear/flicker more, as it can "detect" idle too early. + */ +static double minlatency = 2; +static double maxlatency = 33; + +/* + * blinking timeout (set to 0 to disable blinking) for the terminal blinking + * attribute. + */ +static unsigned int blinktimeout = 800; + +/* + * thickness of underline and bar cursors + */ +static unsigned int cursorthickness = 2; + +/* + * bell volume. It must be a value between -100 and 100. Use 0 for disabling + * it + */ +static int bellvolume = 0; + +/* default TERM value */ +char *termname = "st-256color"; + +/* + * spaces per tab + * + * When you are changing this value, don't forget to adapt the »it« value in + * the st.info and appropriately install the st.info in the environment where + * you use this st version. + * + * it#$tabspaces, + * + * Secondly make sure your kernel is not expanding tabs. When running `stty + * -a` »tab0« should appear. You can tell the terminal to not expand tabs by + * running following command: + * + * stty tabs + */ +unsigned int tabspaces = 8; + +/* Terminal colors (16 first used in escape sequence) */ +static const char *colorname[] = { + /* 8 normal colors */ + "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", + "gray90", /* default foreground colour */ + "black", /* default background colour */ +}; + + +/* + * Default colors (colorname index) + * foreground, background, cursor, reverse cursor + */ +unsigned int defaultfg = 258; +unsigned int defaultbg = 259; +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 = 2; + +/* + * 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} }, + { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} }, + { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} }, +}; + +/* + * 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/st b/st new file mode 100755 index 0000000000000000000000000000000000000000..cda195825ba929bab65b29d40654386561579141 GIT binary patch literal 108600 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 literal 0 HcmV?d00001 diff --git a/x.c b/x.c index 1e4bdf5..82c9002 100644 --- a/x.c +++ b/x.c @@ -1417,10 +1417,6 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i 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]; diff --git a/x.c.orig b/x.c.orig new file mode 100644 index 0000000..d73152b --- /dev/null +++ b/x.c.orig @@ -0,0 +1,2108 @@ +/* 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|1<<14) + +/* 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 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_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 uint buttons; /* bit field of pressed buttons */ + +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, btn, code; + int x = evcol(e), y = evrow(e); + int state = e->xbutton.state; + char buf[40]; + static int ox, oy; + + if (e->type == MotionNotify) { + if (x == ox && y == oy) + return; + if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY)) + return; + /* MODE_MOUSEMOTION: no reporting if no button is pressed */ + if (IS_SET(MODE_MOUSEMOTION) && buttons == 0) + return; + /* Set btn to lowest-numbered pressed button, or 12 if no + * buttons are pressed. */ + for (btn = 1; btn <= 11 && !(buttons & (1<<(btn-1))); btn++) + ; + code = 32; + } else { + btn = e->xbutton.button; + /* Only buttons 1 through 11 can be encoded */ + if (btn < 1 || btn > 11) + return; + if (e->type == ButtonRelease) { + /* MODE_MOUSEX10: no button release reporting */ + if (IS_SET(MODE_MOUSEX10)) + return; + /* Don't send release events for the scroll wheel */ + if (btn == 4 || btn == 5) + return; + } + code = 0; + } + + ox = x; + oy = y; + + /* Encode btn into code. If no button is pressed for a motion event in + * MODE_MOUSEMANY, then encode it as a release. */ + if ((!IS_SET(MODE_MOUSESGR) && e->type == ButtonRelease) || btn == 12) + code += 3; + else if (btn >= 8) + code += 128 + btn - 8; + else if (btn >= 4) + code += 64 + btn - 4; + else + code += btn - 1; + + if (!IS_SET(MODE_MOUSEX10)) { + code += ((state & ShiftMask ) ? 4 : 0) + + ((state & Mod1Mask ) ? 8 : 0) /* meta key: alt */ + + ((state & ControlMask) ? 16 : 0); + } + + if (IS_SET(MODE_MOUSESGR)) { + len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c", + code, x+1, y+1, + e->type == ButtonRelease ? 'm' : 'M'); + } else if (x < 223 && y < 223) { + len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", + 32+code, 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) +{ + int btn = e->xbutton.button; + struct timespec now; + int snap; + + if (1 <= btn && btn <= 11) + buttons |= 1 << (btn-1); + + if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { + mousereport(e); + return; + } + + if (mouseaction(e, 0)) + return; + + if (btn == 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) +{ + int btn = e->xbutton.button; + + if (1 <= btn && btn <= 11) + buttons &= ~(1 << (btn-1)); + + if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { + mousereport(e); + return; + } + + if (mouseaction(e, 1)) + return; + if (btn == 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, + DefaultDepth(xw.dpy, xw.scr)); + 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); + } + loaded = 1; +} + +int +xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b) +{ + if (!BETWEEN(x, 0, dc.collen - 1)) + return 1; + + *r = dc.col[x].color.red >> 8; + *g = dc.col[x].color.green >> 8; + *b = dc.col[x].color.blue >> 8; + + return 0; +} + +int +xsetcolorname(int x, const char *name) +{ + Color ncolor; + + if (!BETWEEN(x, 0, dc.collen - 1)) + 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, root; + pid_t thispid = getpid(); + XColor xmousefg, xmousebg; + + if (!(xw.dpy = XOpenDisplay(NULL))) + die("can't open display\n"); + xw.scr = XDefaultScreen(xw.dpy); + xw.vis = XDefaultVisual(xw.dpy, xw.scr); + + /* font */ + if (!FcInit()) + die("could not init fontconfig.\n"); + + usedfont = (opt_font == NULL)? font : opt_font; + xloadfonts(usedfont, 0); + + /* colors */ + xw.cmap = XDefaultColormap(xw.dpy, xw.scr); + 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; + + root = XRootWindow(xw.dpy, xw.scr); + if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) + parent = root; + xw.win = XCreateWindow(xw.dpy, root, xw.l, xw.t, + win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, + xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity + | CWEventMask | CWColormap, &xw.attrs); + if (parent != root) + XReparentWindow(xw.dpy, xw.win, parent, xw.l, xw.t); + + memset(&gcvalues, 0, sizeof(gcvalues)); + gcvalues.graphics_exposures = False; + dc.gc = XCreateGC(xw.dpy, xw.win, GCGraphicsExposures, + &gcvalues); + xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, + DefaultDepth(xw.dpy, xw.scr)); + 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 * chscale + 1, + width, 1); + } + + if (base.mode & ATTR_STRUCK) { + XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 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); + + if (p[0] == '\0') + p = opt_title; + + if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, + &prop) != Success) + return; + 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); + + if (p[0] == '\0') + p = opt_title; + + if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, + &prop) != Success) + return; + 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 = NoSymbol; + 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); + if (status == XBufferOverflow) + return; + } 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 '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.o b/x.o new file mode 100644 index 0000000000000000000000000000000000000000..f38864117201f59e42087d8b3977474df6a0ed82 GIT binary patch literal 75920 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