From a0883a7f4ab866b7225fe7c2528958166acb3c4c Mon Sep 17 00:00:00 2001 From: vx-clutch Date: Mon, 9 Feb 2026 19:41:04 -0500 Subject: [PATCH] font2 --- config.def.h | 6 + config.h | 480 ++++++++ patches/st-font2-0.8.5.diff | 163 +++ st | Bin 0 -> 94384 bytes st.o | Bin 0 -> 78768 bytes x.c | 101 ++ x.c.orig | 2108 +++++++++++++++++++++++++++++++++++ x.o | Bin 0 -> 73000 bytes 8 files changed, 2858 insertions(+) create mode 100644 config.h create mode 100644 patches/st-font2-0.8.5.diff create mode 100755 st create mode 100644 st.o create mode 100644 x.c.orig create mode 100644 x.o diff --git a/config.def.h b/config.def.h index 0d4fac3..2bb40e4 100644 --- a/config.def.h +++ b/config.def.h @@ -6,6 +6,12 @@ * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html */ static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; +/* Spare fonts */ +static char *font2[] = { +/* "Inconsolata for Powerline:pixelsize=12:antialias=true:autohint=true", */ +/* "Hack Nerd Font Mono:pixelsize=11:antialias=true:autohint=true", */ +}; + static int borderpx = 2; /* diff --git a/config.h b/config.h new file mode 100644 index 0000000..2bb40e4 --- /dev/null +++ b/config.h @@ -0,0 +1,480 @@ +/* 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"; +/* Spare fonts */ +static char *font2[] = { +/* "Inconsolata for Powerline:pixelsize=12:antialias=true:autohint=true", */ +/* "Hack Nerd Font Mono:pixelsize=11: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 */ + "#2e3436", + "#a40000", + "#4e9a06", + "#c4a000", + "#3465a4", + "#75507b", + "#34a0a4", + "#babdb9", + + /* 8 bright colors */ + "#555753", + "#ef2929", + "#8ae234", + "#fce94f", + "#729fcf", + "#ad7fa8", + "#72d9cf", + "#eeeeec", + + [255] = 0, + + /* more colors can be added after 255 to use with DefaultXX */ + "#cccccc", + "#555555", + "#e4e4ef", /* default foreground colour */ + "#181818", /* 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} }, +}; + +/* + * 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/patches/st-font2-0.8.5.diff b/patches/st-font2-0.8.5.diff new file mode 100644 index 0000000..9b22b8a --- /dev/null +++ b/patches/st-font2-0.8.5.diff @@ -0,0 +1,163 @@ +From 1635e04d3643dd4caa0c7c2043b585c6d7e4705f Mon Sep 17 00:00:00 2001 +From: Rizqi Nur Assyaufi +Date: Mon, 18 Jul 2022 01:15:45 +0800 +Subject: [PATCH] [st][patch][font2] Add patch for st-0.8.5 + +--- + config.def.h | 6 +++ + x.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 107 insertions(+) + +diff --git a/config.def.h b/config.def.h +index 91ab8ca..717b2f0 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -6,6 +6,12 @@ + * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html + */ + static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; ++/* Spare fonts */ ++static char *font2[] = { ++/* "Inconsolata for Powerline:pixelsize=12:antialias=true:autohint=true", */ ++/* "Hack Nerd Font Mono:pixelsize=11:antialias=true:autohint=true", */ ++}; ++ + static int borderpx = 2; + + /* +diff --git a/x.c b/x.c +index 8a16faa..220fc4f 100644 +--- a/x.c ++++ b/x.c +@@ -157,6 +157,8 @@ static void xhints(void); + static int xloadcolor(int, const char *, Color *); + static int xloadfont(Font *, FcPattern *); + static void xloadfonts(const char *, double); ++static int xloadsparefont(FcPattern *, int); ++static void xloadsparefonts(void); + static void xunloadfont(Font *); + static void xunloadfonts(void); + static void xsetenv(void); +@@ -306,6 +308,7 @@ zoomabs(const Arg *arg) + { + xunloadfonts(); + xloadfonts(usedfont, arg->f); ++ xloadsparefonts(); + cresize(0, 0); + redraw(); + xhints(); +@@ -1034,6 +1037,101 @@ xloadfonts(const char *fontstr, double fontsize) + FcPatternDestroy(pattern); + } + ++int ++xloadsparefont(FcPattern *pattern, int flags) ++{ ++ FcPattern *match; ++ FcResult result; ++ ++ match = FcFontMatch(NULL, pattern, &result); ++ if (!match) { ++ return 1; ++ } ++ ++ if (!(frc[frclen].font = XftFontOpenPattern(xw.dpy, match))) { ++ FcPatternDestroy(match); ++ return 1; ++ } ++ ++ frc[frclen].flags = flags; ++ /* Believe U+0000 glyph will present in each default font */ ++ frc[frclen].unicodep = 0; ++ frclen++; ++ ++ return 0; ++} ++ ++void ++xloadsparefonts(void) ++{ ++ FcPattern *pattern; ++ double sizeshift, fontval; ++ int fc; ++ char **fp; ++ ++ if (frclen != 0) ++ die("can't embed spare fonts. cache isn't empty"); ++ ++ /* Calculate count of spare fonts */ ++ fc = sizeof(font2) / sizeof(*font2); ++ if (fc == 0) ++ return; ++ ++ /* Allocate memory for cache entries. */ ++ if (frccap < 4 * fc) { ++ frccap += 4 * fc - frccap; ++ frc = xrealloc(frc, frccap * sizeof(Fontcache)); ++ } ++ ++ for (fp = font2; fp - font2 < fc; ++fp) { ++ ++ if (**fp == '-') ++ pattern = XftXlfdParse(*fp, False, False); ++ else ++ pattern = FcNameParse((FcChar8 *)*fp); ++ ++ if (!pattern) ++ die("can't open spare font %s\n", *fp); ++ ++ if (defaultfontsize > 0) { ++ sizeshift = usedfontsize - defaultfontsize; ++ if (sizeshift != 0 && ++ FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) == ++ FcResultMatch) { ++ fontval += sizeshift; ++ FcPatternDel(pattern, FC_PIXEL_SIZE); ++ FcPatternDel(pattern, FC_SIZE); ++ FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontval); ++ } ++ } ++ ++ FcPatternAddBool(pattern, FC_SCALABLE, 1); ++ ++ FcConfigSubstitute(NULL, pattern, FcMatchPattern); ++ XftDefaultSubstitute(xw.dpy, xw.scr, pattern); ++ ++ if (xloadsparefont(pattern, FRC_NORMAL)) ++ die("can't open spare font %s\n", *fp); ++ ++ FcPatternDel(pattern, FC_SLANT); ++ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); ++ if (xloadsparefont(pattern, FRC_ITALIC)) ++ die("can't open spare font %s\n", *fp); ++ ++ FcPatternDel(pattern, FC_WEIGHT); ++ FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); ++ if (xloadsparefont(pattern, FRC_ITALICBOLD)) ++ die("can't open spare font %s\n", *fp); ++ ++ FcPatternDel(pattern, FC_SLANT); ++ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); ++ if (xloadsparefont(pattern, FRC_BOLD)) ++ die("can't open spare font %s\n", *fp); ++ ++ FcPatternDestroy(pattern); ++ } ++} ++ + void + xunloadfont(Font *f) + { +@@ -1131,6 +1229,9 @@ xinit(int cols, int rows) + usedfont = (opt_font == NULL)? font : opt_font; + xloadfonts(usedfont, 0); + ++ /* spare fonts */ ++ xloadsparefonts(); ++ + /* colors */ + xw.cmap = XDefaultColormap(xw.dpy, xw.scr); + xloadcols(); +-- +2.37.1 + diff --git a/st b/st new file mode 100755 index 0000000000000000000000000000000000000000..dccf9ccdb3aada807ab4e01f6043b54e9a34a1fd GIT binary patch literal 94384 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⪚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 Cj_8X3 literal 0 HcmV?d00001 diff --git a/x.c b/x.c index d73152b..2f2180c 100644 --- a/x.c +++ b/x.c @@ -157,6 +157,8 @@ static void xhints(void); static int xloadcolor(int, const char *, Color *); static int xloadfont(Font *, FcPattern *); static void xloadfonts(const char *, double); +static int xloadsparefont(FcPattern *, int); +static void xloadsparefonts(void); static void xunloadfont(Font *); static void xunloadfonts(void); static void xsetenv(void); @@ -306,6 +308,7 @@ zoomabs(const Arg *arg) { xunloadfonts(); xloadfonts(usedfont, arg->f); + xloadsparefonts(); cresize(0, 0); redraw(); xhints(); @@ -1050,6 +1053,101 @@ xloadfonts(const char *fontstr, double fontsize) FcPatternDestroy(pattern); } +int +xloadsparefont(FcPattern *pattern, int flags) +{ + FcPattern *match; + FcResult result; + + match = FcFontMatch(NULL, pattern, &result); + if (!match) { + return 1; + } + + if (!(frc[frclen].font = XftFontOpenPattern(xw.dpy, match))) { + FcPatternDestroy(match); + return 1; + } + + frc[frclen].flags = flags; + /* Believe U+0000 glyph will present in each default font */ + frc[frclen].unicodep = 0; + frclen++; + + return 0; +} + +void +xloadsparefonts(void) +{ + FcPattern *pattern; + double sizeshift, fontval; + int fc; + char **fp; + + if (frclen != 0) + die("can't embed spare fonts. cache isn't empty"); + + /* Calculate count of spare fonts */ + fc = sizeof(font2) / sizeof(*font2); + if (fc == 0) + return; + + /* Allocate memory for cache entries. */ + if (frccap < 4 * fc) { + frccap += 4 * fc - frccap; + frc = xrealloc(frc, frccap * sizeof(Fontcache)); + } + + for (fp = font2; fp - font2 < fc; ++fp) { + + if (**fp == '-') + pattern = XftXlfdParse(*fp, False, False); + else + pattern = FcNameParse((FcChar8 *)*fp); + + if (!pattern) + die("can't open spare font %s\n", *fp); + + if (defaultfontsize > 0) { + sizeshift = usedfontsize - defaultfontsize; + if (sizeshift != 0 && + FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) == + FcResultMatch) { + fontval += sizeshift; + FcPatternDel(pattern, FC_PIXEL_SIZE); + FcPatternDel(pattern, FC_SIZE); + FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontval); + } + } + + FcPatternAddBool(pattern, FC_SCALABLE, 1); + + FcConfigSubstitute(NULL, pattern, FcMatchPattern); + XftDefaultSubstitute(xw.dpy, xw.scr, pattern); + + if (xloadsparefont(pattern, FRC_NORMAL)) + die("can't open spare font %s\n", *fp); + + FcPatternDel(pattern, FC_SLANT); + FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); + if (xloadsparefont(pattern, FRC_ITALIC)) + die("can't open spare font %s\n", *fp); + + FcPatternDel(pattern, FC_WEIGHT); + FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); + if (xloadsparefont(pattern, FRC_ITALICBOLD)) + die("can't open spare font %s\n", *fp); + + FcPatternDel(pattern, FC_SLANT); + FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); + if (xloadsparefont(pattern, FRC_BOLD)) + die("can't open spare font %s\n", *fp); + + FcPatternDestroy(pattern); + } +} + void xunloadfont(Font *f) { @@ -1147,6 +1245,9 @@ xinit(int cols, int rows) usedfont = (opt_font == NULL)? font : opt_font; xloadfonts(usedfont, 0); + /* spare fonts */ + xloadsparefonts(); + /* colors */ xw.cmap = XDefaultColormap(xw.dpy, xw.scr); xloadcols(); 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..ea8664c7c50ea2071d3551883e317812efd897df GIT binary patch literal 73000 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 Cs$ru5 literal 0 HcmV?d00001