diff --git a/README.md b/README.md index b36715f..b5e5fef 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,18 @@ -Similar to [dwm-flexipatch]() this project has a different take on st patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more. +Similar to [dwm-flexipatch](https://github.com/bakkeby/dwm-flexipatch) this st 0.8.2 project has a different take on st patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more. -For example to include the `alpha` patch then you would only need to flip this setting from 0 to 1 in [patches.h](https://github.com/bakkeby/dwm-flexipatch/blob/master/patches.h): +For example to include the `alpha` patch then you would only need to flip this setting from 0 to 1 in [patches.h](https://github.com/bakkeby/st-flexipatch/blob/master/patches.h): ```c #define ALPHA_PATCH 1 ``` -Refer to [https://dwm.suckless.org/](https://st.suckless.org/) for details on the st terminal, how to install it and how it works. +Refer to [https://st.suckless.org/](https://st.suckless.org/) for details on the st terminal, how to install it and how it works. --- ### Changelog: +2019-09-17 - Added relativeborder, fix-keyboard-input, iso14755, visualbell, right-click-to-plumb, boxdraw and keyboard-select patches + 2019-09-16 - Added alpha, anysize, bold-is-not-bright, clipboard, copyurl, disable-fonts, externalpipe, fixime, hidecursor, newterm, open-copied-url, vertcenter, scrollback, spoiler, themed cursor and xresources patches ### Patches included: @@ -25,6 +27,9 @@ Refer to [https://dwm.suckless.org/](https://st.suckless.org/) for details on th - by default bold text is rendered with a bold font in the bright variant of the current color - this patch makes bold text rendered simply as bold, leaving the color unaffected + - [boxdraw](https://st.suckless.org/patches/boxdraw/) + - adds dustom rendering of lines/blocks/braille characters for gapless alignment + - [clipboard](https://st.suckless.org/patches/clipboard/) - by default st only sets PRIMARY on selection - this patch makes st set CLIPBOARD on selection @@ -42,9 +47,18 @@ Refer to [https://dwm.suckless.org/](https://st.suckless.org/) for details on th - [fixime](https://st.suckless.org/patches/fix_ime/) - adds better Input Method Editor (IME) support + - [fix-keyboard-input](https://st.suckless.org/patches/fix_keyboard_input/) + - allows cli applications to use all the fancy key combinations that are available to GUI applications + - [hidecursor](https://st.suckless.org/patches/hidecursor/) - hides the X cursor whenever a key is pressed and show it back when the mouse is moved in the terminal window + - [iso14755](https://st.suckless.org/patches/iso14755/) + - pressing the default binding Ctrl+Shift-i will popup dmenu, asking you to enter a unicode codepoint that will be converted to a glyph and then pushed to st + + - [keyboard-select](https://st.suckless.org/patches/keyboard_select/) + - allows you to select text on the terminal using keyboard shortcuts + - [newterm](https://st.suckless.org/patches/newterm/) - allows you to spawn a new st terminal using Ctrl-Shift-Return - it will have the same CWD (current working directory) as the original st instance @@ -52,6 +66,12 @@ Refer to [https://dwm.suckless.org/](https://st.suckless.org/) for details on th - [open-copied-url](https://st.suckless.org/patches/open_copied_url/) - open contents of the clipboard in a user-defined browser + - [relativeborder](https://st.suckless.org/patches/relativeborder/) + - allows you to specify a border that is relative in size to the width of a cell in the terminal + + - [right-click-to-plumb](https://st.suckless.org/patches/right_click_to_plumb/) + - allows you to right-click on some selected text to send it to the plumbing program of choice + - [scrollback](https://st.suckless.org/patches/scrollback/) - allows you scroll back through terminal output using keyboard shortcuts or mousewheel @@ -64,6 +84,9 @@ Refer to [https://dwm.suckless.org/](https://st.suckless.org/) for details on th - [vertcenter](https://st.suckless.org/patches/vertcenter/) - vertically center lines in the space available if you have set a larger chscale in config.h + - [visualbell](https://st.suckless.org/patches/visualbell/) + - adds visual indicators for the terminal bell event + - [xresources](https://st.suckless.org/patches/xresources/) - adds the ability to configure st via Xresources - during startup, st will read and apply the resources named in the resources[] array in config.h diff --git a/config.def.h b/config.def.h index 82c5adc..ad5f055 100644 --- a/config.def.h +++ b/config.def.h @@ -6,7 +6,13 @@ * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html */ static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; +#if RELATIVEBORDER_PATCH +/* borderperc: percentage of cell width to use as a border + * 0 = no border, 100 = border width is same as cell width */ +int borderperc = 20; +#else static int borderpx = 2; +#endif // RELATIVEBORDER_PATCH /* * What program is execed by st depends of these precedence rules: @@ -56,12 +62,53 @@ static unsigned int blinktimeout = 800; */ static unsigned int cursorthickness = 2; +#if BOXDRAW_PATCH +/* + * 1: render most of the lines/blocks characters without using the font for + * perfect alignment between cells (U2500 - U259F except dashes/diagonals). + * Bold affects lines thickness if boxdraw_bold is not 0. Italic is ignored. + * 0: disable (render all U25XX glyphs normally from the font). + */ +const int boxdraw = 0; +const int boxdraw_bold = 0; + +/* braille (U28XX): 1: render as adjacent "pixels", 0: use font */ +const int boxdraw_braille = 0; +#endif // BOXDRAW_PATCH + /* * bell volume. It must be a value between -100 and 100. Use 0 for disabling * it */ static int bellvolume = 0; +#if VISUALBELL_2_PATCH || VISUALBELL_3_PATCH +/* + * visual-bell timeout (set to 0 to disable visual-bell). + */ +static int vbelltimeout = 0; +/* + * visual bell mode when enabled: + * 1: Inverse whole screen + * 2: Inverse outer (border) cells + * 3: Draw a filled circle (VISUALBELL_3_PATCH only) + */ +static int vbellmode = 1; +#if VISUALBELL_3_PATCH +/* + * for vbellmode == 3 (circle) the following parameters apply: + * - base and outline colors (colorname index - see below). + * - radius: relative to window width, or if negative: relative to cell-width. + * - position: relative to window width/height (0 and 1 are at the edges). + */ +static int vbellcolor = 3; +static int vbellcolor_outline = 1; +static float vbellradius = 0.03; +static float vbellx = 0.5; +static float vbelly = 0.5; +#endif // VISUALBELL_3_PATCH +#endif // VISUALBELL_2_PATCH + /* default TERM value */ char *termname = "st-256color"; @@ -246,40 +293,46 @@ static char *openurlcmd[] = { "/bin/sh", "-c", #endif // EXTERNALPIPE_PATCH 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} }, + /* 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} }, #if SCROLLBACK_PATCH - { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} }, - { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} }, + { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} }, + { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} }, #endif // SCROLLBACK_PATCH #if CLIPBOARD_PATCH - { TERMMOD, XK_Y, clippaste, {.i = 0} }, - { ShiftMask, XK_Insert, clippaste, {.i = 0} }, + { TERMMOD, XK_Y, clippaste, {.i = 0} }, + { ShiftMask, XK_Insert, clippaste, {.i = 0} }, #else - { TERMMOD, XK_Y, selpaste, {.i = 0} }, - { ShiftMask, XK_Insert, selpaste, {.i = 0} }, + { TERMMOD, XK_Y, selpaste, {.i = 0} }, + { ShiftMask, XK_Insert, selpaste, {.i = 0} }, #endif // CLIPBOARD_PATCH - { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, + { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, #if COPYURL_PATCH || COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH - { MODKEY, XK_l, copyurl, {.i = 0} }, + { MODKEY, XK_l, copyurl, {.i = 0} }, #endif // COPYURL_PATCH #if OPENCOPIED_PATCH - { MODKEY, XK_o, opencopied, {.v = "xdg-open"} }, + { MODKEY, XK_o, opencopied, {.v = "xdg-open"} }, #endif // OPENCOPIED_PATCH #if NEWTERM_PATCH - { TERMMOD, XK_Return, newterm, {.i = 0} }, + { TERMMOD, XK_Return, newterm, {.i = 0} }, #endif // NEWTERM_PATCH #if EXTERNALPIPE_PATCH - { TERMMOD, XK_U, externalpipe, { .v = openurlcmd } }, + { TERMMOD, XK_U, externalpipe, { .v = openurlcmd } }, #endif // EXTERNALPIPE_PATCH + #if KEYBOARDSELECT_PATCH + { TERMMOD, XK_Escape, keyboard_select, { 0 } }, + #endif // KEYBOARDSELECT_PATCH + #if ISO14755_PATCH + { TERMMOD, XK_I, iso14755, {.i = 0} }, + #endif // ISO14755_PATCH }; /* @@ -307,11 +360,13 @@ static Shortcut shortcuts[] = { * position for a key. */ +#if !FIXKEYBOARDINPUT_PATCH /* * 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 }; +#endif // FIXKEYBOARDINPUT_PATCH /* * State bits to ignore when matching key or button events. By default, @@ -326,6 +381,7 @@ static uint ignoremod = Mod2Mask|XK_SWITCH_MOD; */ static uint forceselmod = ShiftMask; +#if !FIXKEYBOARDINPUT_PATCH /* * This is the huge key array which defines all compatibility to the Linux * world. Please decide about changes wisely. @@ -542,6 +598,7 @@ static Key key[] = { { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0}, { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0}, }; +#endif // FIXKEYBOARDINPUT_PATCH /* * Selection types' masks. @@ -562,3 +619,11 @@ static char ascii_printable[] = " !\"#$%&'()*+,-./0123456789:;<=>?" "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" "`abcdefghijklmnopqrstuvwxyz{|}~"; + +#if RIGHTCLICKTOPLUMB_PATCH +/* + * plumb_cmd is run on mouse button 3 click, with argument set to + * current selection and with cwd set to the cwd of the active shell + */ +static char *plumb_cmd = "plumb"; +#endif // RIGHTCLICKTOPLUMB_PATCH \ No newline at end of file diff --git a/patch/boxdraw.c b/patch/boxdraw.c new file mode 100644 index 0000000..3cc5b51 --- /dev/null +++ b/patch/boxdraw.c @@ -0,0 +1,192 @@ +/* + * Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih + * MIT/X Consortium License + */ + +#include + +/* Rounded non-negative integers division of n / d */ +#define DIV(n, d) (((n) + (d) / 2) / (d)) + +static Display *xdpy; +static Colormap xcmap; +static XftDraw *xd; +static Visual *xvis; + +static void drawbox(int, int, int, int, XftColor *, XftColor *, ushort); +static void drawboxlines(int, int, int, int, XftColor *, ushort); + +/* public API */ + +void +boxdraw_xinit(Display *dpy, Colormap cmap, XftDraw *draw, Visual *vis) +{ + xdpy = dpy; xcmap = cmap; xd = draw, xvis = vis; +} + +int +isboxdraw(Rune u) +{ + Rune block = u & ~0xff; + return (boxdraw && block == 0x2500 && boxdata[(uint8_t)u]) || + (boxdraw_braille && block == 0x2800); +} + +/* the "index" is actually the entire shape data encoded as ushort */ +ushort +boxdrawindex(const Glyph *g) +{ + if (boxdraw_braille && (g->u & ~0xff) == 0x2800) + return BRL | (uint8_t)g->u; + if (boxdraw_bold && (g->mode & ATTR_BOLD)) + return BDB | boxdata[(uint8_t)g->u]; + return boxdata[(uint8_t)g->u]; +} + +void +drawboxes(int x, int y, int cw, int ch, XftColor *fg, XftColor *bg, + const XftGlyphFontSpec *specs, int len) +{ + for ( ; len-- > 0; x += cw, specs++) + drawbox(x, y, cw, ch, fg, bg, (ushort)specs->glyph); +} + +/* implementation */ + +void +drawbox(int x, int y, int w, int h, XftColor *fg, XftColor *bg, ushort bd) +{ + ushort cat = bd & ~(BDB | 0xff); /* mask out bold and data */ + if (bd & (BDL | BDA)) { + /* lines (light/double/heavy/arcs) */ + drawboxlines(x, y, w, h, fg, bd); + + } else if (cat == BBD) { + /* lower (8-X)/8 block */ + int d = DIV((uint8_t)bd * h, 8); + XftDrawRect(xd, fg, x, y + d, w, h - d); + + } else if (cat == BBU) { + /* upper X/8 block */ + XftDrawRect(xd, fg, x, y, w, DIV((uint8_t)bd * h, 8)); + + } else if (cat == BBL) { + /* left X/8 block */ + XftDrawRect(xd, fg, x, y, DIV((uint8_t)bd * w, 8), h); + + } else if (cat == BBR) { + /* right (8-X)/8 block */ + int d = DIV((uint8_t)bd * w, 8); + XftDrawRect(xd, fg, x + d, y, w - d, h); + + } else if (cat == BBQ) { + /* Quadrants */ + int w2 = DIV(w, 2), h2 = DIV(h, 2); + if (bd & TL) + XftDrawRect(xd, fg, x, y, w2, h2); + if (bd & TR) + XftDrawRect(xd, fg, x + w2, y, w - w2, h2); + if (bd & BL) + XftDrawRect(xd, fg, x, y + h2, w2, h - h2); + if (bd & BR) + XftDrawRect(xd, fg, x + w2, y + h2, w - w2, h - h2); + + } else if (bd & BBS) { + /* Shades - data is 1/2/3 for 25%/50%/75% alpha, respectively */ + int d = (uint8_t)bd; + XftColor xfc; + XRenderColor xrc = { .alpha = 0xffff }; + + xrc.red = DIV(fg->color.red * d + bg->color.red * (4 - d), 4); + xrc.green = DIV(fg->color.green * d + bg->color.green * (4 - d), 4); + xrc.blue = DIV(fg->color.blue * d + bg->color.blue * (4 - d), 4); + + XftColorAllocValue(xdpy, xvis, xcmap, &xrc, &xfc); + XftDrawRect(xd, &xfc, x, y, w, h); + XftColorFree(xdpy, xvis, xcmap, &xfc); + + } else if (cat == BRL) { + /* braille, each data bit corresponds to one dot at 2x4 grid */ + int w1 = DIV(w, 2); + int h1 = DIV(h, 4), h2 = DIV(h, 2), h3 = DIV(3 * h, 4); + + if (bd & 1) XftDrawRect(xd, fg, x, y, w1, h1); + if (bd & 2) XftDrawRect(xd, fg, x, y + h1, w1, h2 - h1); + if (bd & 4) XftDrawRect(xd, fg, x, y + h2, w1, h3 - h2); + if (bd & 8) XftDrawRect(xd, fg, x + w1, y, w - w1, h1); + if (bd & 16) XftDrawRect(xd, fg, x + w1, y + h1, w - w1, h2 - h1); + if (bd & 32) XftDrawRect(xd, fg, x + w1, y + h2, w - w1, h3 - h2); + if (bd & 64) XftDrawRect(xd, fg, x, y + h3, w1, h - h3); + if (bd & 128) XftDrawRect(xd, fg, x + w1, y + h3, w - w1, h - h3); + + } +} + +void +drawboxlines(int x, int y, int w, int h, XftColor *fg, ushort bd) +{ + /* s: stem thickness. width/8 roughly matches underscore thickness. */ + /* We draw bold as 1.5 * normal-stem and at least 1px thicker. */ + /* doubles draw at least 3px, even when w or h < 3. bold needs 6px. */ + int mwh = MIN(w, h); + int base_s = MAX(1, DIV(mwh, 8)); + int bold = (bd & BDB) && mwh >= 6; /* possibly ignore boldness */ + int s = bold ? MAX(base_s + 1, DIV(3 * base_s, 2)) : base_s; + int w2 = DIV(w - s, 2), h2 = DIV(h - s, 2); + /* the s-by-s square (x + w2, y + h2, s, s) is the center texel. */ + /* The base length (per direction till edge) includes this square. */ + + int light = bd & (LL | LU | LR | LD); + int double_ = bd & (DL | DU | DR | DD); + + if (light) { + /* d: additional (negative) length to not-draw the center */ + /* texel - at arcs and avoid drawing inside (some) doubles */ + int arc = bd & BDA; + int multi_light = light & (light - 1); + int multi_double = double_ & (double_ - 1); + /* light crosses double only at DH+LV, DV+LH (ref. shapes) */ + int d = arc || (multi_double && !multi_light) ? -s : 0; + + if (bd & LL) + XftDrawRect(xd, fg, x, y + h2, w2 + s + d, s); + if (bd & LU) + XftDrawRect(xd, fg, x + w2, y, s, h2 + s + d); + if (bd & LR) + XftDrawRect(xd, fg, x + w2 - d, y + h2, w - w2 + d, s); + if (bd & LD) + XftDrawRect(xd, fg, x + w2, y + h2 - d, s, h - h2 + d); + } + + /* double lines - also align with light to form heavy when combined */ + if (double_) { + /* + * going clockwise, for each double-ray: p is additional length + * to the single-ray nearer to the previous direction, and n to + * the next. p and n adjust from the base length to lengths + * which consider other doubles - shorter to avoid intersections + * (p, n), or longer to draw the far-corner texel (n). + */ + int dl = bd & DL, du = bd & DU, dr = bd & DR, dd = bd & DD; + if (dl) { + int p = dd ? -s : 0, n = du ? -s : dd ? s : 0; + XftDrawRect(xd, fg, x, y + h2 + s, w2 + s + p, s); + XftDrawRect(xd, fg, x, y + h2 - s, w2 + s + n, s); + } + if (du) { + int p = dl ? -s : 0, n = dr ? -s : dl ? s : 0; + XftDrawRect(xd, fg, x + w2 - s, y, s, h2 + s + p); + XftDrawRect(xd, fg, x + w2 + s, y, s, h2 + s + n); + } + if (dr) { + int p = du ? -s : 0, n = dd ? -s : du ? s : 0; + XftDrawRect(xd, fg, x + w2 - p, y + h2 - s, w - w2 + p, s); + XftDrawRect(xd, fg, x + w2 - n, y + h2 + s, w - w2 + n, s); + } + if (dd) { + int p = dr ? -s : 0, n = dl ? -s : dr ? s : 0; + XftDrawRect(xd, fg, x + w2 + s, y + h2 - p, s, h - h2 + p); + XftDrawRect(xd, fg, x + w2 - s, y + h2 - n, s, h - h2 + n); + } + } +} \ No newline at end of file diff --git a/patch/boxdraw.h b/patch/boxdraw.h new file mode 100644 index 0000000..12df637 --- /dev/null +++ b/patch/boxdraw.h @@ -0,0 +1,214 @@ +/* + * Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih + * MIT/X Consortium License + */ + +/* + * U+25XX codepoints data + * + * References: + * http://www.unicode.org/charts/PDF/U2500.pdf + * http://www.unicode.org/charts/PDF/U2580.pdf + * + * Test page: + * https://github.com/GNOME/vte/blob/master/doc/boxes.txt + */ + +/* Each shape is encoded as 16-bits. Higher bits are category, lower are data */ +/* Categories (mutually exclusive except BDB): */ +/* For convenience, BDL/BDA/BBS/BDB are 1 bit each, the rest are enums */ +#define BDL (1<<8) /* Box Draw Lines (light/double/heavy) */ +#define BDA (1<<9) /* Box Draw Arc (light) */ + +#define BBD (1<<10) /* Box Block Down (lower) X/8 */ +#define BBL (2<<10) /* Box Block Left X/8 */ +#define BBU (3<<10) /* Box Block Upper X/8 */ +#define BBR (4<<10) /* Box Block Right X/8 */ +#define BBQ (5<<10) /* Box Block Quadrants */ +#define BRL (6<<10) /* Box Braille (data is lower byte of U28XX) */ + +#define BBS (1<<14) /* Box Block Shades */ +#define BDB (1<<15) /* Box Draw is Bold */ + +/* (BDL/BDA) Light/Double/Heavy x Left/Up/Right/Down/Horizontal/Vertical */ +/* Heavy is light+double (literally drawing light+double align to form heavy) */ +#define LL (1<<0) +#define LU (1<<1) +#define LR (1<<2) +#define LD (1<<3) +#define LH (LL+LR) +#define LV (LU+LD) + +#define DL (1<<4) +#define DU (1<<5) +#define DR (1<<6) +#define DD (1<<7) +#define DH (DL+DR) +#define DV (DU+DD) + +#define HL (LL+DL) +#define HU (LU+DU) +#define HR (LR+DR) +#define HD (LD+DD) +#define HH (HL+HR) +#define HV (HU+HD) + +/* (BBQ) Quadrants Top/Bottom x Left/Right */ +#define TL (1<<0) +#define TR (1<<1) +#define BL (1<<2) +#define BR (1<<3) + +/* Data for U+2500 - U+259F except dashes/diagonals */ +static const unsigned short boxdata[256] = { + /* light lines */ + [0x00] = BDL + LH, /* light horizontal */ + [0x02] = BDL + LV, /* light vertical */ + [0x0c] = BDL + LD + LR, /* light down and right */ + [0x10] = BDL + LD + LL, /* light down and left */ + [0x14] = BDL + LU + LR, /* light up and right */ + [0x18] = BDL + LU + LL, /* light up and left */ + [0x1c] = BDL + LV + LR, /* light vertical and right */ + [0x24] = BDL + LV + LL, /* light vertical and left */ + [0x2c] = BDL + LH + LD, /* light horizontal and down */ + [0x34] = BDL + LH + LU, /* light horizontal and up */ + [0x3c] = BDL + LV + LH, /* light vertical and horizontal */ + [0x74] = BDL + LL, /* light left */ + [0x75] = BDL + LU, /* light up */ + [0x76] = BDL + LR, /* light right */ + [0x77] = BDL + LD, /* light down */ + + /* heavy [+light] lines */ + [0x01] = BDL + HH, + [0x03] = BDL + HV, + [0x0d] = BDL + HR + LD, + [0x0e] = BDL + HD + LR, + [0x0f] = BDL + HD + HR, + [0x11] = BDL + HL + LD, + [0x12] = BDL + HD + LL, + [0x13] = BDL + HD + HL, + [0x15] = BDL + HR + LU, + [0x16] = BDL + HU + LR, + [0x17] = BDL + HU + HR, + [0x19] = BDL + HL + LU, + [0x1a] = BDL + HU + LL, + [0x1b] = BDL + HU + HL, + [0x1d] = BDL + HR + LV, + [0x1e] = BDL + HU + LD + LR, + [0x1f] = BDL + HD + LR + LU, + [0x20] = BDL + HV + LR, + [0x21] = BDL + HU + HR + LD, + [0x22] = BDL + HD + HR + LU, + [0x23] = BDL + HV + HR, + [0x25] = BDL + HL + LV, + [0x26] = BDL + HU + LD + LL, + [0x27] = BDL + HD + LU + LL, + [0x28] = BDL + HV + LL, + [0x29] = BDL + HU + HL + LD, + [0x2a] = BDL + HD + HL + LU, + [0x2b] = BDL + HV + HL, + [0x2d] = BDL + HL + LD + LR, + [0x2e] = BDL + HR + LL + LD, + [0x2f] = BDL + HH + LD, + [0x30] = BDL + HD + LH, + [0x31] = BDL + HD + HL + LR, + [0x32] = BDL + HR + HD + LL, + [0x33] = BDL + HH + HD, + [0x35] = BDL + HL + LU + LR, + [0x36] = BDL + HR + LU + LL, + [0x37] = BDL + HH + LU, + [0x38] = BDL + HU + LH, + [0x39] = BDL + HU + HL + LR, + [0x3a] = BDL + HU + HR + LL, + [0x3b] = BDL + HH + HU, + [0x3d] = BDL + HL + LV + LR, + [0x3e] = BDL + HR + LV + LL, + [0x3f] = BDL + HH + LV, + [0x40] = BDL + HU + LH + LD, + [0x41] = BDL + HD + LH + LU, + [0x42] = BDL + HV + LH, + [0x43] = BDL + HU + HL + LD + LR, + [0x44] = BDL + HU + HR + LD + LL, + [0x45] = BDL + HD + HL + LU + LR, + [0x46] = BDL + HD + HR + LU + LL, + [0x47] = BDL + HH + HU + LD, + [0x48] = BDL + HH + HD + LU, + [0x49] = BDL + HV + HL + LR, + [0x4a] = BDL + HV + HR + LL, + [0x4b] = BDL + HV + HH, + [0x78] = BDL + HL, + [0x79] = BDL + HU, + [0x7a] = BDL + HR, + [0x7b] = BDL + HD, + [0x7c] = BDL + HR + LL, + [0x7d] = BDL + HD + LU, + [0x7e] = BDL + HL + LR, + [0x7f] = BDL + HU + LD, + + /* double [+light] lines */ + [0x50] = BDL + DH, + [0x51] = BDL + DV, + [0x52] = BDL + DR + LD, + [0x53] = BDL + DD + LR, + [0x54] = BDL + DR + DD, + [0x55] = BDL + DL + LD, + [0x56] = BDL + DD + LL, + [0x57] = BDL + DL + DD, + [0x58] = BDL + DR + LU, + [0x59] = BDL + DU + LR, + [0x5a] = BDL + DU + DR, + [0x5b] = BDL + DL + LU, + [0x5c] = BDL + DU + LL, + [0x5d] = BDL + DL + DU, + [0x5e] = BDL + DR + LV, + [0x5f] = BDL + DV + LR, + [0x60] = BDL + DV + DR, + [0x61] = BDL + DL + LV, + [0x62] = BDL + DV + LL, + [0x63] = BDL + DV + DL, + [0x64] = BDL + DH + LD, + [0x65] = BDL + DD + LH, + [0x66] = BDL + DD + DH, + [0x67] = BDL + DH + LU, + [0x68] = BDL + DU + LH, + [0x69] = BDL + DH + DU, + [0x6a] = BDL + DH + LV, + [0x6b] = BDL + DV + LH, + [0x6c] = BDL + DH + DV, + + /* (light) arcs */ + [0x6d] = BDA + LD + LR, + [0x6e] = BDA + LD + LL, + [0x6f] = BDA + LU + LL, + [0x70] = BDA + LU + LR, + + /* Lower (Down) X/8 block (data is 8 - X) */ + [0x81] = BBD + 7, [0x82] = BBD + 6, [0x83] = BBD + 5, [0x84] = BBD + 4, + [0x85] = BBD + 3, [0x86] = BBD + 2, [0x87] = BBD + 1, [0x88] = BBD + 0, + + /* Left X/8 block (data is X) */ + [0x89] = BBL + 7, [0x8a] = BBL + 6, [0x8b] = BBL + 5, [0x8c] = BBL + 4, + [0x8d] = BBL + 3, [0x8e] = BBL + 2, [0x8f] = BBL + 1, + + /* upper 1/2 (4/8), 1/8 block (X), right 1/2, 1/8 block (8-X) */ + [0x80] = BBU + 4, [0x94] = BBU + 1, + [0x90] = BBR + 4, [0x95] = BBR + 7, + + /* Quadrants */ + [0x96] = BBQ + BL, + [0x97] = BBQ + BR, + [0x98] = BBQ + TL, + [0x99] = BBQ + TL + BL + BR, + [0x9a] = BBQ + TL + BR, + [0x9b] = BBQ + TL + TR + BL, + [0x9c] = BBQ + TL + TR + BR, + [0x9d] = BBQ + TR, + [0x9e] = BBQ + BL + TR, + [0x9f] = BBQ + BL + TR + BR, + + /* Shades, data is an alpha value in 25% units (1/4, 1/2, 3/4) */ + [0x91] = BBS + 1, [0x92] = BBS + 2, [0x93] = BBS + 3, + + /* U+2504 - U+250B, U+254C - U+254F: unsupported (dashes) */ + /* U+2571 - U+2573: unsupported (diagonals) */ +}; \ No newline at end of file diff --git a/patch/fixkeyboardinput.c b/patch/fixkeyboardinput.c new file mode 100644 index 0000000..6d485c3 --- /dev/null +++ b/patch/fixkeyboardinput.c @@ -0,0 +1,813 @@ +/* + * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF) + * to be mapped below, add them to this array. + */ +static KeySym mappedkeys[] = { + XK_space, + XK_m, + XK_i, + XK_A, + XK_B, + XK_C, + XK_D, + XK_E, + XK_F, + XK_G, + XK_H, + XK_I, + XK_K, + XK_J, + XK_L, + XK_M, + XK_N, + XK_O, + XK_P, + XK_Q, + XK_R, + XK_S, + XK_T, + XK_U, + XK_V, + XK_W, + XK_X, + XK_Y, + XK_Z, + XK_Z, + XK_0, + XK_1, + XK_2, + XK_3, + XK_4, + XK_5, + XK_6, + XK_7, + XK_8, + XK_9, + XK_exclam, + XK_quotedbl, + XK_numbersign, + XK_dollar, + XK_percent, + XK_ampersand, + XK_apostrophe, + XK_parenleft, + XK_parenright, + XK_asterisk, + XK_plus, + XK_comma, + XK_minus, + XK_period, + XK_slash, + XK_colon, + XK_semicolon, + XK_less, + XK_equal, + XK_greater, + XK_question, + XK_at, + XK_bracketleft, + XK_backslash, + XK_bracketright, + XK_asciicircum, + XK_underscore, + XK_grave, + XK_braceleft, + XK_bar, + XK_braceright, + XK_asciitilde, +}; + +/* + * 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_Prior, ShiftMask, "\033[5;2~", 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_Next, ShiftMask, "\033[6;2~", 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_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_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_NO_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_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_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_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_Prior, ControlMask, "\033[5;5~", 0, 0}, + { XK_Prior, ShiftMask, "\033[5;2~", 0, 0}, + { XK_Next, ControlMask, "\033[6;5~", 0, 0}, + { XK_Next, ShiftMask, "\033[6;2~", 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}, + + // libtermkey compatible keyboard input + { XK_KP_Home, XK_NO_MOD, "\033[H", 0, -1}, + { XK_KP_Home, XK_NO_MOD, "\033[1~", 0, +1}, + { XK_KP_Home, ControlMask, "\033[149;5u", 0, 0}, + { XK_KP_Home, ControlMask|ShiftMask, "\033[149;6u", 0, 0}, + { XK_KP_Home, Mod1Mask, "\033[149;3u", 0, 0}, + { XK_KP_Home, Mod1Mask|ControlMask, "\033[149;7u", 0, 0}, + { XK_KP_Home, Mod1Mask|ControlMask|ShiftMask, "\033[149;8u", 0, 0}, + { XK_KP_Home, Mod1Mask|ShiftMask, "\033[149;4u", 0, 0}, + { XK_KP_Home, ShiftMask, "\033[149;2u", 0, 0}, + { XK_KP_Up, XK_NO_MOD, "\033Ox", +1, 0}, + { XK_KP_Up, XK_NO_MOD, "\033[A", 0, -1}, + { XK_KP_Up, XK_NO_MOD, "\033OA", 0, +1}, + { XK_KP_Up, ControlMask, "\033[151;5u", 0, 0}, + { XK_KP_Up, ControlMask|ShiftMask, "\033[151;6u", 0, 0}, + { XK_KP_Up, Mod1Mask, "\033[151;3u", 0, 0}, + { XK_KP_Up, Mod1Mask|ControlMask, "\033[151;7u", 0, 0}, + { XK_KP_Up, Mod1Mask|ControlMask|ShiftMask, "\033[151;8u", 0, 0}, + { XK_KP_Up, Mod1Mask|ShiftMask, "\033[151;4u", 0, 0}, + { XK_KP_Up, ShiftMask, "\033[151;2u", 0, 0}, + { XK_KP_Down, XK_NO_MOD, "\033Or", +1, 0}, + { XK_KP_Down, XK_NO_MOD, "\033[B", 0, -1}, + { XK_KP_Down, XK_NO_MOD, "\033OB", 0, +1}, + { XK_KP_Down, ControlMask, "\033[153;5u", 0, 0}, + { XK_KP_Down, ControlMask|ShiftMask, "\033[153;6u", 0, 0}, + { XK_KP_Down, Mod1Mask, "\033[153;3u", 0, 0}, + { XK_KP_Down, Mod1Mask|ControlMask, "\033[153;7u", 0, 0}, + { XK_KP_Down, Mod1Mask|ControlMask|ShiftMask, "\033[153;8u", 0, 0}, + { XK_KP_Down, Mod1Mask|ShiftMask, "\033[153;4u", 0, 0}, + { XK_KP_Down, ShiftMask, "\033[153;2u", 0, 0}, + { XK_KP_Left, XK_NO_MOD, "\033Ot", +1, 0}, + { XK_KP_Left, XK_NO_MOD, "\033[D", 0, -1}, + { XK_KP_Left, XK_NO_MOD, "\033OD", 0, +1}, + { XK_KP_Left, ControlMask, "\033[150;5u", 0, 0}, + { XK_KP_Left, ControlMask|ShiftMask, "\033[150;6u", 0, 0}, + { XK_KP_Left, Mod1Mask, "\033[150;3u", 0, 0}, + { XK_KP_Left, Mod1Mask|ControlMask, "\033[150;7u", 0, 0}, + { XK_KP_Left, Mod1Mask|ControlMask|ShiftMask, "\033[150;8u", 0, 0}, + { XK_KP_Left, Mod1Mask|ShiftMask, "\033[150;4u", 0, 0}, + { XK_KP_Left, ShiftMask, "\033[150;2u", 0, 0}, + { XK_KP_Right, XK_NO_MOD, "\033Ov", +1, 0}, + { XK_KP_Right, XK_NO_MOD, "\033[C", 0, -1}, + { XK_KP_Right, XK_NO_MOD, "\033OC", 0, +1}, + { XK_KP_Right, ControlMask, "\033[152;5u", 0, 0}, + { XK_KP_Right, ControlMask|ShiftMask, "\033[152;6u", 0, 0}, + { XK_KP_Right, Mod1Mask, "\033[152;3u", 0, 0}, + { XK_KP_Right, Mod1Mask|ControlMask, "\033[152;7u", 0, 0}, + { XK_KP_Right, Mod1Mask|ControlMask|ShiftMask, "\033[152;8u", 0, 0}, + { XK_KP_Right, Mod1Mask|ShiftMask, "\033[152;4u", 0, 0}, + { XK_KP_Right, ShiftMask, "\033[152;2u", 0, 0}, + { XK_KP_Prior, XK_NO_MOD, "\033[5~", 0, 0}, + { XK_KP_Prior, ControlMask, "\033[154;5u", 0, 0}, + { XK_KP_Prior, ControlMask|ShiftMask, "\033[154;6u", 0, 0}, + { XK_KP_Prior, Mod1Mask, "\033[154;3u", 0, 0}, + { XK_KP_Prior, Mod1Mask|ControlMask, "\033[154;7u", 0, 0}, + { XK_KP_Prior, Mod1Mask|ControlMask|ShiftMask, "\033[154;8u", 0, 0}, + { XK_KP_Prior, Mod1Mask|ShiftMask, "\033[154;4u", 0, 0}, + { XK_KP_Begin, XK_NO_MOD, "\033[E", 0, 0}, + { XK_KP_Begin, ControlMask, "\033[157;5u", 0, 0}, + { XK_KP_Begin, ControlMask|ShiftMask, "\033[157;6u", 0, 0}, + { XK_KP_Begin, Mod1Mask, "\033[157;3u", 0, 0}, + { XK_KP_Begin, Mod1Mask|ControlMask, "\033[157;7u", 0, 0}, + { XK_KP_Begin, Mod1Mask|ControlMask|ShiftMask, "\033[157;8u", 0, 0}, + { XK_KP_Begin, Mod1Mask|ShiftMask, "\033[157;4u", 0, 0}, + { XK_KP_Begin, ShiftMask, "\033[157;2u", 0, 0}, + { XK_KP_End, XK_NO_MOD, "\033[4~", 0, 0}, + { XK_KP_End, ControlMask|ShiftMask, "\033[156;6u", 0, 0}, + { XK_KP_End, Mod1Mask, "\033[156;3u", 0, 0}, + { XK_KP_End, Mod1Mask|ControlMask, "\033[156;7u", 0, 0}, + { XK_KP_End, Mod1Mask|ControlMask|ShiftMask, "\033[156;8u", 0, 0}, + { XK_KP_End, Mod1Mask|ShiftMask, "\033[156;4u", 0, 0}, + { XK_KP_Next, XK_NO_MOD, "\033[6~", 0, 0}, + { XK_KP_Next, ControlMask, "\033[155;5u", 0, 0}, + { XK_KP_Next, ControlMask|ShiftMask, "\033[155;6u", 0, 0}, + { XK_KP_Next, Mod1Mask, "\033[155;3u", 0, 0}, + { XK_KP_Next, Mod1Mask|ControlMask, "\033[155;7u", 0, 0}, + { XK_KP_Next, Mod1Mask|ControlMask|ShiftMask, "\033[155;8u", 0, 0}, + { XK_KP_Next, Mod1Mask|ShiftMask, "\033[155;4u", 0, 0}, + { XK_KP_Insert, XK_NO_MOD, "\033[4h", -1, 0}, + { XK_KP_Insert, XK_NO_MOD, "\033[2~", +1, 0}, + { XK_KP_Insert, ControlMask|ShiftMask, "\033[158;6u", 0, 0}, + { XK_KP_Insert, Mod1Mask, "\033[158;3u", 0, 0}, + { XK_KP_Insert, Mod1Mask|ControlMask, "\033[158;7u", 0, 0}, + { XK_KP_Insert, Mod1Mask|ControlMask|ShiftMask, "\033[158;8u", 0, 0}, + { XK_KP_Insert, Mod1Mask|ShiftMask, "\033[158;4u", 0, 0}, + { XK_KP_Delete, XK_NO_MOD, "\033[P", -1, 0}, + { XK_KP_Delete, XK_NO_MOD, "\033[3~", +1, 0}, + { XK_KP_Delete, ControlMask|ShiftMask, "\033[159;6u", 0, 0}, + { XK_KP_Delete, Mod1Mask, "\033[159;3u", 0, 0}, + { XK_KP_Delete, Mod1Mask|ControlMask, "\033[159;7u", 0, 0}, + { XK_KP_Delete, Mod1Mask|ControlMask|ShiftMask, "\033[159;8u", 0, 0}, + { XK_KP_Delete, Mod1Mask|ShiftMask, "\033[159;4u", 0, 0}, + { XK_KP_Multiply, XK_NO_MOD, "\033Oj", +2, 0}, + { XK_KP_Multiply, ControlMask, "\033[170;5u", 0, 0}, + { XK_KP_Multiply, ControlMask|ShiftMask, "\033[170;6u", 0, 0}, + { XK_KP_Multiply, Mod1Mask, "\033[170;3u", 0, 0}, + { XK_KP_Multiply, Mod1Mask|ControlMask, "\033[170;7u", 0, 0}, + { XK_KP_Multiply, Mod1Mask|ControlMask|ShiftMask, "\033[170;8u", 0, 0}, + { XK_KP_Multiply, Mod1Mask|ShiftMask, "\033[170;4u", 0, 0}, + { XK_KP_Multiply, ShiftMask, "\033[170;2u", 0, 0}, + { XK_KP_Add, XK_NO_MOD, "\033Ok", +2, 0}, + { XK_KP_Add, ControlMask, "\033[171;5u", 0, 0}, + { XK_KP_Add, ControlMask|ShiftMask, "\033[171;6u", 0, 0}, + { XK_KP_Add, Mod1Mask, "\033[171;3u", 0, 0}, + { XK_KP_Add, Mod1Mask|ControlMask, "\033[171;7u", 0, 0}, + { XK_KP_Add, Mod1Mask|ControlMask|ShiftMask, "\033[171;8u", 0, 0}, + { XK_KP_Add, Mod1Mask|ShiftMask, "\033[171;4u", 0, 0}, + { XK_KP_Add, ShiftMask, "\033[171;2u", 0, 0}, + { XK_KP_Enter, XK_NO_MOD, "\033OM", +2, 0}, + { XK_KP_Enter, XK_NO_MOD, "\r", -1, 0}, + { XK_KP_Enter, XK_NO_MOD, "\r\n", -1, 0}, + { XK_KP_Enter, ControlMask, "\033[141;5u", 0, 0}, + { XK_KP_Enter, ControlMask|ShiftMask, "\033[141;6u", 0, 0}, + { XK_KP_Enter, Mod1Mask, "\033[141;3u", 0, 0}, + { XK_KP_Enter, Mod1Mask|ControlMask, "\033[141;7u", 0, 0}, + { XK_KP_Enter, Mod1Mask|ControlMask|ShiftMask, "\033[141;8u", 0, 0}, + { XK_KP_Enter, Mod1Mask|ShiftMask, "\033[141;4u", 0, 0}, + { XK_KP_Enter, ShiftMask, "\033[141;2u", 0, 0}, + { XK_KP_Subtract, XK_NO_MOD, "\033Om", +2, 0}, + { XK_KP_Subtract, ControlMask, "\033[173;5u", 0, 0}, + { XK_KP_Subtract, ControlMask|ShiftMask, "\033[173;6u", 0, 0}, + { XK_KP_Subtract, Mod1Mask, "\033[173;3u", 0, 0}, + { XK_KP_Subtract, Mod1Mask|ControlMask, "\033[173;7u", 0, 0}, + { XK_KP_Subtract, Mod1Mask|ControlMask|ShiftMask, "\033[173;8u", 0, 0}, + { XK_KP_Subtract, Mod1Mask|ShiftMask, "\033[173;4u", 0, 0}, + { XK_KP_Subtract, ShiftMask, "\033[173;2u", 0, 0}, + { XK_KP_Decimal, XK_NO_MOD, "\033On", +2, 0}, + { XK_KP_Decimal, ControlMask, "\033[174;5u", 0, 0}, + { XK_KP_Decimal, ControlMask|ShiftMask, "\033[174;6u", 0, 0}, + { XK_KP_Decimal, Mod1Mask, "\033[174;3u", 0, 0}, + { XK_KP_Decimal, Mod1Mask|ControlMask, "\033[174;7u", 0, 0}, + { XK_KP_Decimal, Mod1Mask|ControlMask|ShiftMask, "\033[174;8u", 0, 0}, + { XK_KP_Decimal, Mod1Mask|ShiftMask, "\033[174;4u", 0, 0}, + { XK_KP_Decimal, ShiftMask, "\033[174;2u", 0, 0}, + { XK_KP_Divide, XK_NO_MOD, "\033Oo", +2, 0}, + { XK_KP_Divide, ControlMask, "\033[175;5u", 0, 0}, + { XK_KP_Divide, ControlMask|ShiftMask, "\033[175;6u", 0, 0}, + { XK_KP_Divide, Mod1Mask, "\033[175;3u", 0, 0}, + { XK_KP_Divide, Mod1Mask|ControlMask, "\033[175;7u", 0, 0}, + { XK_KP_Divide, Mod1Mask|ControlMask|ShiftMask, "\033[175;8u", 0, 0}, + { XK_KP_Divide, Mod1Mask|ShiftMask, "\033[175;4u", 0, 0}, + { XK_KP_Divide, ShiftMask, "\033[175;2u", 0, 0}, + { XK_KP_0, XK_NO_MOD, "\033Op", +2, 0}, + { XK_KP_0, ControlMask, "\033[176;5u", 0, 0}, + { XK_KP_0, ControlMask|ShiftMask, "\033[176;6u", 0, 0}, + { XK_KP_0, Mod1Mask, "\033[176;3u", 0, 0}, + { XK_KP_0, Mod1Mask|ControlMask, "\033[176;7u", 0, 0}, + { XK_KP_0, Mod1Mask|ControlMask|ShiftMask, "\033[176;8u", 0, 0}, + { XK_KP_0, Mod1Mask|ShiftMask, "\033[176;4u", 0, 0}, + { XK_KP_0, ShiftMask, "\033[176;2u", 0, 0}, + { XK_KP_1, XK_NO_MOD, "\033Oq", +2, 0}, + { XK_KP_0, ControlMask, "\033[177;5u", 0, 0}, + { XK_KP_0, ControlMask|ShiftMask, "\033[177;6u", 0, 0}, + { XK_KP_0, Mod1Mask, "\033[177;3u", 0, 0}, + { XK_KP_0, Mod1Mask|ControlMask, "\033[177;7u", 0, 0}, + { XK_KP_0, Mod1Mask|ControlMask|ShiftMask, "\033[177;8u", 0, 0}, + { XK_KP_0, Mod1Mask|ShiftMask, "\033[177;4u", 0, 0}, + { XK_KP_0, ShiftMask, "\033[177;2u", 0, 0}, + { XK_KP_2, XK_NO_MOD, "\033Or", +2, 0}, + { XK_KP_2, ControlMask, "\033[178;5u", 0, 0}, + { XK_KP_2, ControlMask|ShiftMask, "\033[178;6u", 0, 0}, + { XK_KP_2, Mod1Mask, "\033[178;3u", 0, 0}, + { XK_KP_2, Mod1Mask|ControlMask, "\033[178;7u", 0, 0}, + { XK_KP_2, Mod1Mask|ControlMask|ShiftMask, "\033[178;8u", 0, 0}, + { XK_KP_2, Mod1Mask|ShiftMask, "\033[178;4u", 0, 0}, + { XK_KP_2, ShiftMask, "\033[178;2u", 0, 0}, + { XK_KP_3, XK_NO_MOD, "\033Os", +2, 0}, + { XK_KP_3, ControlMask, "\033[179;5u", 0, 0}, + { XK_KP_3, ControlMask|ShiftMask, "\033[179;6u", 0, 0}, + { XK_KP_3, Mod1Mask, "\033[179;3u", 0, 0}, + { XK_KP_3, Mod1Mask|ControlMask, "\033[179;7u", 0, 0}, + { XK_KP_3, Mod1Mask|ControlMask|ShiftMask, "\033[179;8u", 0, 0}, + { XK_KP_3, Mod1Mask|ShiftMask, "\033[179;4u", 0, 0}, + { XK_KP_3, ShiftMask, "\033[179;2u", 0, 0}, + { XK_KP_4, XK_NO_MOD, "\033Ot", +2, 0}, + { XK_KP_4, ControlMask, "\033[180;5u", 0, 0}, + { XK_KP_4, ControlMask|ShiftMask, "\033[180;6u", 0, 0}, + { XK_KP_4, Mod1Mask, "\033[180;3u", 0, 0}, + { XK_KP_4, Mod1Mask|ControlMask, "\033[180;7u", 0, 0}, + { XK_KP_4, Mod1Mask|ControlMask|ShiftMask, "\033[180;8u", 0, 0}, + { XK_KP_4, Mod1Mask|ShiftMask, "\033[180;4u", 0, 0}, + { XK_KP_4, ShiftMask, "\033[180;2u", 0, 0}, + { XK_KP_5, XK_NO_MOD, "\033Ou", +2, 0}, + { XK_KP_5, ControlMask, "\033[181;5u", 0, 0}, + { XK_KP_5, ControlMask|ShiftMask, "\033[181;6u", 0, 0}, + { XK_KP_5, Mod1Mask, "\033[181;3u", 0, 0}, + { XK_KP_5, Mod1Mask|ControlMask, "\033[181;7u", 0, 0}, + { XK_KP_5, Mod1Mask|ControlMask|ShiftMask, "\033[181;8u", 0, 0}, + { XK_KP_5, Mod1Mask|ShiftMask, "\033[181;4u", 0, 0}, + { XK_KP_5, ShiftMask, "\033[181;2u", 0, 0}, + { XK_KP_6, XK_NO_MOD, "\033Ov", +2, 0}, + { XK_KP_6, ControlMask, "\033[182;5u", 0, 0}, + { XK_KP_6, ControlMask|ShiftMask, "\033[182;6u", 0, 0}, + { XK_KP_6, Mod1Mask, "\033[182;3u", 0, 0}, + { XK_KP_6, Mod1Mask|ControlMask, "\033[182;7u", 0, 0}, + { XK_KP_6, Mod1Mask|ControlMask|ShiftMask, "\033[182;8u", 0, 0}, + { XK_KP_6, Mod1Mask|ShiftMask, "\033[182;4u", 0, 0}, + { XK_KP_6, ShiftMask, "\033[182;2u", 0, 0}, + { XK_KP_7, XK_NO_MOD, "\033Ow", +2, 0}, + { XK_KP_7, ControlMask, "\033[183;5u", 0, 0}, + { XK_KP_7, ControlMask|ShiftMask, "\033[183;6u", 0, 0}, + { XK_KP_7, Mod1Mask, "\033[183;3u", 0, 0}, + { XK_KP_7, Mod1Mask|ControlMask, "\033[183;7u", 0, 0}, + { XK_KP_7, Mod1Mask|ControlMask|ShiftMask, "\033[183;8u", 0, 0}, + { XK_KP_7, Mod1Mask|ShiftMask, "\033[183;4u", 0, 0}, + { XK_KP_7, ShiftMask, "\033[183;2u", 0, 0}, + { XK_KP_8, XK_NO_MOD, "\033Ox", +2, 0}, + { XK_KP_8, ControlMask, "\033[184;5u", 0, 0}, + { XK_KP_8, ControlMask|ShiftMask, "\033[184;6u", 0, 0}, + { XK_KP_8, Mod1Mask, "\033[184;3u", 0, 0}, + { XK_KP_8, Mod1Mask|ControlMask, "\033[184;7u", 0, 0}, + { XK_KP_8, Mod1Mask|ControlMask|ShiftMask, "\033[184;8u", 0, 0}, + { XK_KP_8, Mod1Mask|ShiftMask, "\033[184;4u", 0, 0}, + { XK_KP_8, ShiftMask, "\033[184;2u", 0, 0}, + { XK_KP_9, XK_NO_MOD, "\033Oy", +2, 0}, + { XK_KP_9, ControlMask, "\033[185;5u", 0, 0}, + { XK_KP_9, ControlMask|ShiftMask, "\033[185;6u", 0, 0}, + { XK_KP_9, Mod1Mask, "\033[185;3u", 0, 0}, + { XK_KP_9, Mod1Mask|ControlMask, "\033[185;7u", 0, 0}, + { XK_KP_9, Mod1Mask|ControlMask|ShiftMask, "\033[185;8u", 0, 0}, + { XK_KP_9, Mod1Mask|ShiftMask, "\033[185;4u", 0, 0}, + { XK_KP_9, ShiftMask, "\033[185;2u", 0, 0}, + { XK_BackSpace, ControlMask, "\033[127;5u", 0, 0}, + { XK_BackSpace, ControlMask|ShiftMask, "\033[127;6u", 0, 0}, + { XK_BackSpace, Mod1Mask, "\033[127;3u", 0, 0}, + { XK_BackSpace, Mod1Mask|ControlMask, "\033[127;7u", 0, 0}, + { XK_BackSpace, Mod1Mask|ControlMask|ShiftMask, "\033[127;8u", 0, 0}, + { XK_BackSpace, Mod1Mask|ShiftMask, "\033[127;4u", 0, 0}, + { XK_BackSpace, ShiftMask, "\033[127;2u", 0, 0}, + { XK_Tab, ControlMask, "\033[9;5u", 0, 0}, + { XK_Tab, ControlMask|ShiftMask, "\033[1;5Z", 0, 0}, + { XK_Tab, Mod1Mask, "\033[1;3Z", 0, 0}, + { XK_Tab, Mod1Mask|ControlMask, "\033[1;7Z", 0, 0}, + { XK_Tab, Mod1Mask|ControlMask|ShiftMask, "\033[1;8Z", 0, 0}, + { XK_Tab, Mod1Mask|ShiftMask, "\033[1;4Z", 0, 0}, + { XK_Return, ControlMask, "\033[13;5u", 0, 0}, + { XK_Return, ControlMask|ShiftMask, "\033[13;6u", 0, 0}, + { XK_Return, Mod1Mask, "\033[13;3u", 0, 0}, + { XK_Return, Mod1Mask|ControlMask, "\033[13;7u", 0, 0}, + { XK_Return, Mod1Mask|ControlMask|ShiftMask, "\033[13;8u", 0, 0}, + { XK_Return, Mod1Mask|ShiftMask, "\033[13;4u", 0, 0}, + { XK_Return, ShiftMask, "\033[13;2u", 0, 0}, + { XK_Pause, ControlMask, "\033[18;5u", 0, 0}, + { XK_Pause, ControlMask|ShiftMask, "\033[18;6u", 0, 0}, + { XK_Pause, Mod1Mask, "\033[18;3u", 0, 0}, + { XK_Pause, Mod1Mask|ControlMask, "\033[18;7u", 0, 0}, + { XK_Pause, Mod1Mask|ControlMask|ShiftMask, "\033[18;8u", 0, 0}, + { XK_Pause, Mod1Mask|ShiftMask, "\033[18;4u", 0, 0}, + { XK_Pause, ShiftMask, "\033[18;2u", 0, 0}, + { XK_Scroll_Lock, ControlMask, "\033[20;5u", 0, 0}, + { XK_Scroll_Lock, ControlMask|ShiftMask, "\033[20;6u", 0, 0}, + { XK_Scroll_Lock, Mod1Mask, "\033[20;3u", 0, 0}, + { XK_Scroll_Lock, Mod1Mask|ControlMask, "\033[20;7u", 0, 0}, + { XK_Scroll_Lock, Mod1Mask|ControlMask|ShiftMask, "\033[20;8u", 0, 0}, + { XK_Scroll_Lock, Mod1Mask|ShiftMask, "\033[20;4u", 0, 0}, + { XK_Scroll_Lock, ShiftMask, "\033[20;2u", 0, 0}, + { XK_Escape, ControlMask, "\033[27;5u", 0, 0}, + { XK_Escape, ControlMask|ShiftMask, "\033[27;6u", 0, 0}, + { XK_Escape, Mod1Mask, "\033[27;3u", 0, 0}, + { XK_Escape, Mod1Mask|ControlMask, "\033[27;7u", 0, 0}, + { XK_Escape, Mod1Mask|ControlMask|ShiftMask, "\033[27;8u", 0, 0}, + { XK_Escape, Mod1Mask|ShiftMask, "\033[27;4u", 0, 0}, + { XK_Escape, ShiftMask, "\033[27;2u", 0, 0}, + { XK_Home, XK_NO_MOD, "\033[H", 0, -1}, + { XK_Home, XK_NO_MOD, "\033[1~", 0, +1}, + { XK_Home, ControlMask|ShiftMask, "\033[80;6u", 0, 0}, + { XK_Home, Mod1Mask, "\033[80;3u", 0, 0}, + { XK_Home, Mod1Mask|ControlMask, "\033[80;7u", 0, 0}, + { XK_Home, Mod1Mask|ControlMask|ShiftMask, "\033[80;8u", 0, 0}, + { XK_Home, Mod1Mask|ShiftMask, "\033[80;4u", 0, 0}, + { XK_End, XK_NO_MOD, "\033[4~", 0, 0}, + { XK_End, ControlMask|ShiftMask, "\033[87;6u", 0, 0}, + { XK_End, Mod1Mask, "\033[87;3u", 0, 0}, + { XK_End, Mod1Mask|ControlMask, "\033[87;7u", 0, 0}, + { XK_End, Mod1Mask|ControlMask|ShiftMask, "\033[87;8u", 0, 0}, + { XK_End, Mod1Mask|ShiftMask, "\033[87;4u", 0, 0}, + { XK_Prior, XK_NO_MOD, "\033[5~", 0, 0}, + { XK_Prior, ControlMask|ShiftMask, "\033[85;6u", 0, 0}, + { XK_Prior, Mod1Mask, "\033[85;3u", 0, 0}, + { XK_Prior, Mod1Mask|ControlMask, "\033[85;7u", 0, 0}, + { XK_Prior, Mod1Mask|ControlMask|ShiftMask, "\033[85;8u", 0, 0}, + { XK_Prior, Mod1Mask|ShiftMask, "\033[85;4u", 0, 0}, + { XK_Next, XK_NO_MOD, "\033[6~", 0, 0}, + { XK_Next, ControlMask|ShiftMask, "\033[86;6u", 0, 0}, + { XK_Next, Mod1Mask, "\033[86;3u", 0, 0}, + { XK_Next, Mod1Mask|ControlMask, "\033[86;7u", 0, 0}, + { XK_Next, Mod1Mask|ControlMask|ShiftMask, "\033[86;8u", 0, 0}, + { XK_Next, Mod1Mask|ShiftMask, "\033[86;4u", 0, 0}, + { XK_Print, ControlMask, "\033[97;5u", 0, 0}, + { XK_Print, ControlMask|ShiftMask, "\033[97;6u", 0, 0}, + { XK_Print, Mod1Mask, "\033[97;3u", 0, 0}, + { XK_Print, Mod1Mask|ControlMask, "\033[97;7u", 0, 0}, + { XK_Print, Mod1Mask|ControlMask|ShiftMask, "\033[97;8u", 0, 0}, + { XK_Print, Mod1Mask|ShiftMask, "\033[97;4u", 0, 0}, + { XK_Print, ShiftMask, "\033[97;2u", 0, 0}, + { XK_Insert, XK_NO_MOD, "\033[4h", -1, 0}, + { XK_Insert, XK_NO_MOD, "\033[2~", +1, 0}, + { XK_Insert, ControlMask|ShiftMask, "\033[99;6u", 0, 0}, + { XK_Insert, Mod1Mask, "\033[99;3u", 0, 0}, + { XK_Insert, Mod1Mask|ControlMask, "\033[99;7u", 0, 0}, + { XK_Insert, Mod1Mask|ControlMask|ShiftMask, "\033[99;8u", 0, 0}, + { XK_Insert, Mod1Mask|ShiftMask, "\033[99;4u", 0, 0}, + { XK_Menu, ControlMask, "\033[103;5u", 0, 0}, + { XK_Menu, ControlMask|ShiftMask, "\033[103;6u", 0, 0}, + { XK_Menu, Mod1Mask, "\033[103;3u", 0, 0}, + { XK_Menu, Mod1Mask|ControlMask, "\033[103;7u", 0, 0}, + { XK_Menu, Mod1Mask|ControlMask|ShiftMask, "\033[103;8u", 0, 0}, + { XK_Menu, Mod1Mask|ShiftMask, "\033[103;4u", 0, 0}, + { XK_Menu, ShiftMask, "\033[103;2u", 0, 0}, + { XK_Delete, XK_NO_MOD, "\033[P", -1, 0}, + { XK_Delete, XK_NO_MOD, "\033[3~", +1, 0}, + { XK_Delete, ControlMask|ShiftMask, "\033[255;6u", 0, 0}, + { XK_Delete, Mod1Mask, "\033[255;3u", 0, 0}, + { XK_Delete, Mod1Mask|ControlMask, "\033[255;7u", 0, 0}, + { XK_Delete, Mod1Mask|ControlMask|ShiftMask, "\033[255;8u", 0, 0}, + { XK_Delete, Mod1Mask|ShiftMask, "\033[255;4u", 0, 0}, + { XK_i, ControlMask, "\033[105;5u", 0, 0}, + { XK_i, Mod1Mask|ControlMask, "\033[105;7u", 0, 0}, + { XK_m, ControlMask, "\033[109;5u", 0, 0}, + { XK_m, Mod1Mask|ControlMask, "\033[109;7u", 0, 0}, + { XK_space, ControlMask|ShiftMask, "\033[32;6u", 0, 0}, + { XK_space, Mod1Mask, "\033[32;3u", 0, 0}, + { XK_space, Mod1Mask|ControlMask, "\033[32;7u", 0, 0}, + { XK_space, Mod1Mask|ControlMask|ShiftMask, "\033[32;8u", 0, 0}, + { XK_space, Mod1Mask|ShiftMask, "\033[32;4u", 0, 0}, + { XK_space, ShiftMask, "\033[32;2u", 0, 0}, + { XK_0, ControlMask, "\033[48;5u", 0, 0}, + { XK_A, ControlMask|ShiftMask, "\033[65;6u", 0, 0}, + { XK_B, ControlMask|ShiftMask, "\033[66;6u", 0, 0}, + { XK_C, ControlMask|ShiftMask, "\033[67;6u", 0, 0}, + { XK_D, ControlMask|ShiftMask, "\033[68;6u", 0, 0}, + { XK_E, ControlMask|ShiftMask, "\033[69;6u", 0, 0}, + { XK_F, ControlMask|ShiftMask, "\033[70;6u", 0, 0}, + { XK_G, ControlMask|ShiftMask, "\033[71;6u", 0, 0}, + { XK_H, ControlMask|ShiftMask, "\033[72;6u", 0, 0}, + { XK_I, ControlMask|ShiftMask, "\033[73;6u", 0, 0}, + { XK_I, Mod1Mask|ControlMask|ShiftMask, "\033[73;8u", 0, 0}, + { XK_J, ControlMask|ShiftMask, "\033[75;6u", 0, 0}, + { XK_K, ControlMask|ShiftMask, "\033[74;6u", 0, 0}, + { XK_L, ControlMask|ShiftMask, "\033[76;6u", 0, 0}, + { XK_M, ControlMask|ShiftMask, "\033[77;6u", 0, 0}, + { XK_M, Mod1Mask|ControlMask|ShiftMask, "\033[77;8u", 0, 0}, + { XK_N, ControlMask|ShiftMask, "\033[78;6u", 0, 0}, + { XK_O, ControlMask|ShiftMask, "\033[79;6u", 0, 0}, + { XK_P, ControlMask|ShiftMask, "\033[80;6u", 0, 0}, + { XK_Q, ControlMask|ShiftMask, "\033[81;6u", 0, 0}, + { XK_R, ControlMask|ShiftMask, "\033[82;6u", 0, 0}, + { XK_S, ControlMask|ShiftMask, "\033[83;6u", 0, 0}, + { XK_T, ControlMask|ShiftMask, "\033[84;6u", 0, 0}, + { XK_U, ControlMask|ShiftMask, "\033[85;6u", 0, 0}, + { XK_V, ControlMask|ShiftMask, "\033[86;6u", 0, 0}, + { XK_W, ControlMask|ShiftMask, "\033[87;6u", 0, 0}, + { XK_X, ControlMask|ShiftMask, "\033[88;6u", 0, 0}, + { XK_Y, ControlMask|ShiftMask, "\033[89;6u", 0, 0}, + { XK_Z, ControlMask|ShiftMask, "\033[90;6u", 0, 0}, + { XK_Z, ControlMask|ShiftMask, "\033[90;6u", 0, 0}, + { XK_0, Mod1Mask|ControlMask, "\033[48;7u", 0, 0}, + { XK_1, ControlMask, "\033[49;5u", 0, 0}, + { XK_1, Mod1Mask|ControlMask, "\033[49;7u", 0, 0}, + { XK_2, ControlMask, "\033[50;5u", 0, 0}, + { XK_2, Mod1Mask|ControlMask, "\033[50;7u", 0, 0}, + { XK_3, ControlMask, "\033[51;5u", 0, 0}, + { XK_3, Mod1Mask|ControlMask, "\033[51;7u", 0, 0}, + { XK_4, ControlMask, "\033[52;5u", 0, 0}, + { XK_4, Mod1Mask|ControlMask, "\033[52;7u", 0, 0}, + { XK_5, ControlMask, "\033[53;5u", 0, 0}, + { XK_5, Mod1Mask|ControlMask, "\033[53;7u", 0, 0}, + { XK_6, ControlMask, "\033[54;5u", 0, 0}, + { XK_6, Mod1Mask|ControlMask, "\033[54;7u", 0, 0}, + { XK_7, ControlMask, "\033[55;5u", 0, 0}, + { XK_7, Mod1Mask|ControlMask, "\033[55;7u", 0, 0}, + { XK_8, ControlMask, "\033[56;5u", 0, 0}, + { XK_8, Mod1Mask|ControlMask, "\033[56;7u", 0, 0}, + { XK_9, ControlMask, "\033[57;5u", 0, 0}, + { XK_9, Mod1Mask|ControlMask, "\033[57;7u", 0, 0}, + { XK_ampersand, ControlMask, "\033[38;5u", 0, 0}, + { XK_ampersand, ControlMask|ShiftMask, "\033[38;6u", 0, 0}, + { XK_ampersand, Mod1Mask, "\033[38;3u", 0, 0}, + { XK_ampersand, Mod1Mask|ControlMask, "\033[38;7u", 0, 0}, + { XK_ampersand, Mod1Mask|ControlMask|ShiftMask, "\033[38;8u", 0, 0}, + { XK_ampersand, Mod1Mask|ShiftMask, "\033[38;4u", 0, 0}, + { XK_apostrophe, ControlMask, "\033[39;5u", 0, 0}, + { XK_apostrophe, ControlMask|ShiftMask, "\033[39;6u", 0, 0}, + { XK_apostrophe, Mod1Mask, "\033[39;3u", 0, 0}, + { XK_apostrophe, Mod1Mask|ControlMask, "\033[39;7u", 0, 0}, + { XK_apostrophe, Mod1Mask|ControlMask|ShiftMask, "\033[39;8u", 0, 0}, + { XK_apostrophe, Mod1Mask|ShiftMask, "\033[39;4u", 0, 0}, + { XK_asciicircum, ControlMask, "\033[94;5u", 0, 0}, + { XK_asciicircum, ControlMask|ShiftMask, "\033[94;6u", 0, 0}, + { XK_asciicircum, Mod1Mask, "\033[94;3u", 0, 0}, + { XK_asciicircum, Mod1Mask|ControlMask, "\033[94;7u", 0, 0}, + { XK_asciicircum, Mod1Mask|ControlMask|ShiftMask, "\033[94;8u", 0, 0}, + { XK_asciicircum, Mod1Mask|ShiftMask, "\033[94;4u", 0, 0}, + { XK_asciitilde, ControlMask, "\033[126;5u", 0, 0}, + { XK_asciitilde, ControlMask|ShiftMask, "\033[126;6u", 0, 0}, + { XK_asciitilde, Mod1Mask, "\033[126;3u", 0, 0}, + { XK_asciitilde, Mod1Mask|ControlMask, "\033[126;7u", 0, 0}, + { XK_asciitilde, Mod1Mask|ControlMask|ShiftMask, "\033[126;8u", 0, 0}, + { XK_asciitilde, Mod1Mask|ShiftMask, "\033[126;4u", 0, 0}, + { XK_asterisk, ControlMask, "\033[42;5u", 0, 0}, + { XK_asterisk, ControlMask|ShiftMask, "\033[42;6u", 0, 0}, + { XK_asterisk, Mod1Mask, "\033[42;3u", 0, 0}, + { XK_asterisk, Mod1Mask|ControlMask, "\033[42;7u", 0, 0}, + { XK_asterisk, Mod1Mask|ControlMask|ShiftMask, "\033[42;8u", 0, 0}, + { XK_asterisk, Mod1Mask|ShiftMask, "\033[42;4u", 0, 0}, + { XK_at, ControlMask, "\033[64;5u", 0, 0}, + { XK_at, ControlMask|ShiftMask, "\033[64;6u", 0, 0}, + { XK_at, Mod1Mask, "\033[64;3u", 0, 0}, + { XK_at, Mod1Mask|ControlMask, "\033[64;7u", 0, 0}, + { XK_at, Mod1Mask|ControlMask|ShiftMask, "\033[64;8u", 0, 0}, + { XK_at, Mod1Mask|ShiftMask, "\033[64;4u", 0, 0}, + { XK_backslash, ControlMask, "\033[92;5u", 0, 0}, + { XK_backslash, ControlMask|ShiftMask, "\033[92;6u", 0, 0}, + { XK_backslash, Mod1Mask, "\033[92;3u", 0, 0}, + { XK_backslash, Mod1Mask|ControlMask, "\033[92;7u", 0, 0}, + { XK_backslash, Mod1Mask|ControlMask|ShiftMask, "\033[92;8u", 0, 0}, + { XK_backslash, Mod1Mask|ShiftMask, "\033[92;4u", 0, 0}, + { XK_bar, ControlMask, "\033[124;5u", 0, 0}, + { XK_bar, ControlMask|ShiftMask, "\033[124;6u", 0, 0}, + { XK_bar, Mod1Mask, "\033[124;3u", 0, 0}, + { XK_bar, Mod1Mask|ControlMask, "\033[124;7u", 0, 0}, + { XK_bar, Mod1Mask|ControlMask|ShiftMask, "\033[124;8u", 0, 0}, + { XK_bar, Mod1Mask|ShiftMask, "\033[124;4u", 0, 0}, + { XK_braceleft, ControlMask, "\033[123;5u", 0, 0}, + { XK_braceleft, ControlMask|ShiftMask, "\033[123;6u", 0, 0}, + { XK_braceleft, Mod1Mask, "\033[123;3u", 0, 0}, + { XK_braceleft, Mod1Mask|ControlMask, "\033[123;7u", 0, 0}, + { XK_braceleft, Mod1Mask|ControlMask|ShiftMask, "\033[123;8u", 0, 0}, + { XK_braceleft, Mod1Mask|ShiftMask, "\033[123;4u", 0, 0}, + { XK_braceright, ControlMask, "\033[125;5u", 0, 0}, + { XK_braceright, ControlMask|ShiftMask, "\033[125;6u", 0, 0}, + { XK_braceright, Mod1Mask, "\033[125;3u", 0, 0}, + { XK_braceright, Mod1Mask|ControlMask, "\033[125;7u", 0, 0}, + { XK_braceright, Mod1Mask|ControlMask|ShiftMask, "\033[125;8u", 0, 0}, + { XK_braceright, Mod1Mask|ShiftMask, "\033[125;4u", 0, 0}, + { XK_bracketleft, ControlMask, "\033[91;5u", 0, 0}, + { XK_bracketleft, ControlMask|ShiftMask, "\033[91;6u", 0, 0}, + { XK_bracketleft, Mod1Mask, "\033[91;3u", 0, 0}, + { XK_bracketleft, Mod1Mask|ControlMask, "\033[91;7u", 0, 0}, + { XK_bracketleft, Mod1Mask|ControlMask|ShiftMask, "\033[91;8u", 0, 0}, + { XK_bracketleft, Mod1Mask|ShiftMask, "\033[91;4u", 0, 0}, + { XK_bracketright, ControlMask, "\033[93;5u", 0, 0}, + { XK_bracketright, ControlMask|ShiftMask, "\033[93;6u", 0, 0}, + { XK_bracketright, Mod1Mask, "\033[93;3u", 0, 0}, + { XK_bracketright, Mod1Mask|ControlMask, "\033[93;7u", 0, 0}, + { XK_bracketright, Mod1Mask|ControlMask|ShiftMask, "\033[93;8u", 0, 0}, + { XK_bracketright, Mod1Mask|ShiftMask, "\033[93;4u", 0, 0}, + { XK_colon, ControlMask, "\033[58;5u", 0, 0}, + { XK_colon, ControlMask|ShiftMask, "\033[58;6u", 0, 0}, + { XK_colon, Mod1Mask, "\033[58;3u", 0, 0}, + { XK_colon, Mod1Mask|ControlMask, "\033[58;7u", 0, 0}, + { XK_colon, Mod1Mask|ControlMask|ShiftMask, "\033[58;8u", 0, 0}, + { XK_colon, Mod1Mask|ShiftMask, "\033[58;4u", 0, 0}, + { XK_comma, ControlMask, "\033[44;5u", 0, 0}, + { XK_comma, ControlMask|ShiftMask, "\033[44;6u", 0, 0}, + { XK_comma, Mod1Mask, "\033[44;3u", 0, 0}, + { XK_comma, Mod1Mask|ControlMask, "\033[44;7u", 0, 0}, + { XK_comma, Mod1Mask|ControlMask|ShiftMask, "\033[44;8u", 0, 0}, + { XK_comma, Mod1Mask|ShiftMask, "\033[44;4u", 0, 0}, + { XK_dollar, ControlMask, "\033[36;5u", 0, 0}, + { XK_dollar, ControlMask|ShiftMask, "\033[36;6u", 0, 0}, + { XK_dollar, Mod1Mask, "\033[36;3u", 0, 0}, + { XK_dollar, Mod1Mask|ControlMask, "\033[36;7u", 0, 0}, + { XK_dollar, Mod1Mask|ControlMask|ShiftMask, "\033[36;8u", 0, 0}, + { XK_dollar, Mod1Mask|ShiftMask, "\033[36;4u", 0, 0}, + { XK_equal, ControlMask, "\033[61;5u", 0, 0}, + { XK_equal, ControlMask|ShiftMask, "\033[61;6u", 0, 0}, + { XK_equal, Mod1Mask, "\033[61;3u", 0, 0}, + { XK_equal, Mod1Mask|ControlMask, "\033[61;7u", 0, 0}, + { XK_equal, Mod1Mask|ControlMask|ShiftMask, "\033[61;8u", 0, 0}, + { XK_equal, Mod1Mask|ShiftMask, "\033[61;4u", 0, 0}, + { XK_exclam, ControlMask, "\033[33;5u", 0, 0}, + { XK_exclam, ControlMask|ShiftMask, "\033[33;6u", 0, 0}, + { XK_exclam, Mod1Mask, "\033[33;3u", 0, 0}, + { XK_exclam, Mod1Mask|ControlMask, "\033[33;7u", 0, 0}, + { XK_exclam, Mod1Mask|ControlMask|ShiftMask, "\033[33;8u", 0, 0}, + { XK_exclam, Mod1Mask|ShiftMask, "\033[33;4u", 0, 0}, + { XK_grave, ControlMask, "\033[96;5u", 0, 0}, + { XK_grave, ControlMask|ShiftMask, "\033[96;6u", 0, 0}, + { XK_grave, Mod1Mask, "\033[96;3u", 0, 0}, + { XK_grave, Mod1Mask|ControlMask, "\033[96;7u", 0, 0}, + { XK_grave, Mod1Mask|ControlMask|ShiftMask, "\033[96;8u", 0, 0}, + { XK_grave, Mod1Mask|ShiftMask, "\033[96;4u", 0, 0}, + { XK_greater, ControlMask, "\033[62;5u", 0, 0}, + { XK_greater, ControlMask|ShiftMask, "\033[62;6u", 0, 0}, + { XK_greater, Mod1Mask, "\033[62;3u", 0, 0}, + { XK_greater, Mod1Mask|ControlMask, "\033[62;7u", 0, 0}, + { XK_greater, Mod1Mask|ControlMask|ShiftMask, "\033[62;8u", 0, 0}, + { XK_greater, Mod1Mask|ShiftMask, "\033[62;4u", 0, 0}, + { XK_less, ControlMask, "\033[60;5u", 0, 0}, + { XK_less, ControlMask|ShiftMask, "\033[60;6u", 0, 0}, + { XK_less, Mod1Mask, "\033[60;3u", 0, 0}, + { XK_less, Mod1Mask|ControlMask, "\033[60;7u", 0, 0}, + { XK_less, Mod1Mask|ControlMask|ShiftMask, "\033[60;8u", 0, 0}, + { XK_less, Mod1Mask|ShiftMask, "\033[60;4u", 0, 0}, + { XK_minus, ControlMask, "\033[45;5u", 0, 0}, + { XK_minus, ControlMask|ShiftMask, "\033[45;6u", 0, 0}, + { XK_minus, Mod1Mask, "\033[45;3u", 0, 0}, + { XK_minus, Mod1Mask|ControlMask, "\033[45;7u", 0, 0}, + { XK_minus, Mod1Mask|ControlMask|ShiftMask, "\033[45;8u", 0, 0}, + { XK_minus, Mod1Mask|ShiftMask, "\033[45;4u", 0, 0}, + { XK_numbersign, ControlMask, "\033[35;5u", 0, 0}, + { XK_numbersign, ControlMask|ShiftMask, "\033[35;6u", 0, 0}, + { XK_numbersign, Mod1Mask, "\033[35;3u", 0, 0}, + { XK_numbersign, Mod1Mask|ControlMask, "\033[35;7u", 0, 0}, + { XK_numbersign, Mod1Mask|ControlMask|ShiftMask, "\033[35;8u", 0, 0}, + { XK_numbersign, Mod1Mask|ShiftMask, "\033[35;4u", 0, 0}, + { XK_parenleft, ControlMask, "\033[40;5u", 0, 0}, + { XK_parenleft, ControlMask|ShiftMask, "\033[40;6u", 0, 0}, + { XK_parenleft, Mod1Mask, "\033[40;3u", 0, 0}, + { XK_parenleft, Mod1Mask|ControlMask, "\033[40;7u", 0, 0}, + { XK_parenleft, Mod1Mask|ControlMask|ShiftMask, "\033[40;8u", 0, 0}, + { XK_parenleft, Mod1Mask|ShiftMask, "\033[40;4u", 0, 0}, + { XK_parenright, ControlMask, "\033[41;5u", 0, 0}, + { XK_parenright, ControlMask|ShiftMask, "\033[41;6u", 0, 0}, + { XK_parenright, Mod1Mask, "\033[41;3u", 0, 0}, + { XK_parenright, Mod1Mask|ControlMask, "\033[41;7u", 0, 0}, + { XK_parenright, Mod1Mask|ControlMask|ShiftMask, "\033[41;8u", 0, 0}, + { XK_parenright, Mod1Mask|ShiftMask, "\033[41;4u", 0, 0}, + { XK_percent, ControlMask, "\033[37;5u", 0, 0}, + { XK_percent, ControlMask|ShiftMask, "\033[37;6u", 0, 0}, + { XK_percent, Mod1Mask, "\033[37;3u", 0, 0}, + { XK_percent, Mod1Mask|ControlMask, "\033[37;7u", 0, 0}, + { XK_percent, Mod1Mask|ControlMask|ShiftMask, "\033[37;8u", 0, 0}, + { XK_percent, Mod1Mask|ShiftMask, "\033[37;4u", 0, 0}, + { XK_period, ControlMask, "\033[46;5u", 0, 0}, + { XK_period, ControlMask|ShiftMask, "\033[46;6u", 0, 0}, + { XK_period, Mod1Mask|ControlMask, "\033[46;7u", 0, 0}, + { XK_period, Mod1Mask|ControlMask|ShiftMask, "\033[46;8u", 0, 0}, + { XK_period, Mod1Mask|ShiftMask, "\033[46;4u", 0, 0}, + { XK_plus, ControlMask, "\033[43;5u", 0, 0}, + { XK_plus, ControlMask|ShiftMask, "\033[43;6u", 0, 0}, + { XK_plus, Mod1Mask, "\033[43;3u", 0, 0}, + { XK_plus, Mod1Mask|ControlMask, "\033[43;7u", 0, 0}, + { XK_plus, Mod1Mask|ControlMask|ShiftMask, "\033[43;8u", 0, 0}, + { XK_plus, Mod1Mask|ShiftMask, "\033[43;4u", 0, 0}, + { XK_question, ControlMask, "\033[63;5u", 0, 0}, + { XK_question, ControlMask|ShiftMask, "\033[63;6u", 0, 0}, + { XK_question, Mod1Mask, "\033[63;3u", 0, 0}, + { XK_question, Mod1Mask|ControlMask, "\033[63;7u", 0, 0}, + { XK_question, Mod1Mask|ControlMask|ShiftMask, "\033[63;8u", 0, 0}, + { XK_question, Mod1Mask|ShiftMask, "\033[63;4u", 0, 0}, + { XK_quotedbl, ControlMask, "\033[34;5u", 0, 0}, + { XK_quotedbl, ControlMask|ShiftMask, "\033[34;6u", 0, 0}, + { XK_quotedbl, Mod1Mask, "\033[34;3u", 0, 0}, + { XK_quotedbl, Mod1Mask|ControlMask, "\033[34;7u", 0, 0}, + { XK_quotedbl, Mod1Mask|ControlMask|ShiftMask, "\033[34;8u", 0, 0}, + { XK_quotedbl, Mod1Mask|ShiftMask, "\033[34;4u", 0, 0}, + { XK_semicolon, ControlMask, "\033[59;5u", 0, 0}, + { XK_semicolon, ControlMask|ShiftMask, "\033[59;6u", 0, 0}, + { XK_semicolon, Mod1Mask, "\033[59;3u", 0, 0}, + { XK_semicolon, Mod1Mask|ControlMask, "\033[59;7u", 0, 0}, + { XK_semicolon, Mod1Mask|ControlMask|ShiftMask, "\033[59;8u", 0, 0}, + { XK_semicolon, Mod1Mask|ShiftMask, "\033[59;4u", 0, 0}, + { XK_slash, ControlMask|ShiftMask, "\033[47;6u", 0, 0}, + { XK_slash, Mod1Mask, "\033[47;3u", 0, 0}, + { XK_slash, Mod1Mask|ControlMask, "\033[47;7u", 0, 0}, + { XK_slash, Mod1Mask|ControlMask|ShiftMask, "\033[47;8u", 0, 0}, + { XK_slash, Mod1Mask|ShiftMask, "\033[47;4u", 0, 0}, + { XK_underscore, ControlMask, "\033[95;5u", 0, 0}, + { XK_underscore, ControlMask|ShiftMask, "\033[95;6u", 0, 0}, + { XK_underscore, Mod1Mask, "\033[95;3u", 0, 0}, + { XK_underscore, Mod1Mask|ControlMask, "\033[95;7u", 0, 0}, + { XK_underscore, Mod1Mask|ControlMask|ShiftMask, "\033[95;8u", 0, 0}, + { XK_underscore, Mod1Mask|ShiftMask, "\033[95;4u", 0, 0}, +}; \ No newline at end of file diff --git a/patch/iso14755.c b/patch/iso14755.c new file mode 100644 index 0000000..a2fbd79 --- /dev/null +++ b/patch/iso14755.c @@ -0,0 +1,21 @@ +void +iso14755(const Arg *arg) +{ + FILE *p; + char *us, *e, codepoint[9], uc[UTF_SIZ]; + unsigned long utf32; + + if (!(p = popen(ISO14755CMD, "r"))) + return; + + us = fgets(codepoint, sizeof(codepoint), p); + pclose(p); + + if (!us || *us == '\0' || *us == '-' || strlen(us) > 7) + return; + if ((utf32 = strtoul(us, &e, 16)) == ULONG_MAX || + (*e != '\n' && *e != '\0')) + return; + + ttywrite(uc, utf8encode(utf32, uc), 1); +} \ No newline at end of file diff --git a/patch/iso14755.h b/patch/iso14755.h new file mode 100644 index 0000000..45a3d7a --- /dev/null +++ b/patch/iso14755.h @@ -0,0 +1,6 @@ +#define NUMMAXLEN(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1) + +/* constants */ +#define ISO14755CMD "dmenu -w \"$WINDOWID\" -p codepoint: mode = ATTR_REVERSE, + deb->u = *z, + deb->fg = defaultfg, deb->bg = defaultbg; + } + else if ( type < 5 ) + memcpy(term.line[bot], g, col * sizeof(Glyph)); + else { + for (deb = &term.line[bot][0], fin = &term.line[bot][col]; deb < fin; deb++) + deb->mode = ATTR_REVERSE, + deb->u = ' ', + deb->fg = defaultfg, deb->bg = defaultbg; + term.line[bot][0].u = ksym; + } + + term.dirty[bot] = 1; + drawregion(0, bot, col, bot + 1); +} + +void select_or_drawcursor(int selectsearch_mode, int type) { + int done = 0; + + if ( selectsearch_mode & 1 ) { + selextend(term.c.x, term.c.y, type, done); + xsetsel(getsel()); + } + else + xdrawcursor(term.c.x, term.c.y, term.line[term.c.y][term.c.x], + term.ocx, term.ocy, term.line[term.ocy][term.ocx]); +} + +void search(int selectsearch_mode, Rune *target, int ptarget, int incr, int type, TCursor *cu) { + Rune *r; + int i, bound = (term.col * cu->y + cu->x) * (incr > 0) + incr; + + for (i = term.col * term.c.y + term.c.x + incr; i != bound; i += incr) { + for (r = target; r - target < ptarget; r++) { + if ( *r == term.line[(i + r - target) / term.col][(i + r - target) % term.col].u ) { + if ( r - target == ptarget - 1 ) break; + } else { + r = NULL; + break; + } + } + if ( r != NULL ) break; + } + + if ( i != bound ) { + term.c.y = i / term.col, term.c.x = i % term.col; + select_or_drawcursor(selectsearch_mode, type); + } +} + +int trt_kbdselect(KeySym ksym, char *buf, int len) { + static TCursor cu; + static Rune target[64]; + static int type = 1, ptarget, in_use; + static int sens, quant; + static char selectsearch_mode; + int i, bound, *xy; + + + if ( selectsearch_mode & 2 ) { + if ( ksym == XK_Return ) { + selectsearch_mode ^= 2; + set_notifmode(selectsearch_mode, -2); + if ( ksym == XK_Escape ) ptarget = 0; + return 0; + } + else if ( ksym == XK_BackSpace ) { + if ( !ptarget ) return 0; + term.line[term.bot][ptarget--].u = ' '; + } + else if ( len < 1 ) { + return 0; + } + else if ( ptarget == term.col || ksym == XK_Escape ) { + return 0; + } + else { + utf8decode(buf, &target[ptarget++], len); + term.line[term.bot][ptarget].u = target[ptarget - 1]; + } + + if ( ksym != XK_BackSpace ) + search(selectsearch_mode, &target[0], ptarget, sens, type, &cu); + + term.dirty[term.bot] = 1; + drawregion(0, term.bot, term.col, term.bot + 1); + return 0; + } + + switch ( ksym ) { + case -1 : + in_use = 1; + cu.x = term.c.x, cu.y = term.c.y; + set_notifmode(0, ksym); + return MODE_KBDSELECT; + case XK_s : + if ( selectsearch_mode & 1 ) + selclear(); + else + selstart(term.c.x, term.c.y, 0); + set_notifmode(selectsearch_mode ^= 1, ksym); + break; + case XK_t : + selextend(term.c.x, term.c.y, type ^= 3, i = 0); /* 2 fois */ + selextend(term.c.x, term.c.y, type, i = 0); + break; + case XK_slash : + case XK_KP_Divide : + case XK_question : + ksym &= XK_question; /* Divide to slash */ + sens = (ksym == XK_slash) ? -1 : 1; + ptarget = 0; + set_notifmode(15, ksym); + selectsearch_mode ^= 2; + break; + case XK_Escape : + if ( !in_use ) break; + selclear(); + case XK_Return : + set_notifmode(4, ksym); + term.c.x = cu.x, term.c.y = cu.y; + select_or_drawcursor(selectsearch_mode = 0, type); + in_use = quant = 0; + return MODE_KBDSELECT; + case XK_n : + case XK_N : + if ( ptarget ) + search(selectsearch_mode, &target[0], ptarget, (ksym == XK_n) ? -1 : 1, type, &cu); + break; + case XK_BackSpace : + term.c.x = 0; + select_or_drawcursor(selectsearch_mode, type); + break; + case XK_dollar : + term.c.x = term.col - 1; + select_or_drawcursor(selectsearch_mode, type); + break; + case XK_Home : + term.c.x = 0, term.c.y = 0; + select_or_drawcursor(selectsearch_mode, type); + break; + case XK_End : + term.c.x = cu.x, term.c.y = cu.y; + select_or_drawcursor(selectsearch_mode, type); + break; + case XK_Page_Up : + case XK_Page_Down : + term.c.y = (ksym == XK_Prior ) ? 0 : cu.y; + select_or_drawcursor(selectsearch_mode, type); + break; + case XK_exclam : + term.c.x = term.col >> 1; + select_or_drawcursor(selectsearch_mode, type); + break; + case XK_asterisk : + case XK_KP_Multiply : + term.c.x = term.col >> 1; + case XK_underscore : + term.c.y = cu.y >> 1; + select_or_drawcursor(selectsearch_mode, type); + break; + default : + if ( ksym >= XK_0 && ksym <= XK_9 ) { /* 0-9 keyboard */ + quant = (quant * 10) + (ksym ^ XK_0); + return 0; + } + else if ( ksym >= XK_KP_0 && ksym <= XK_KP_9 ) { /* 0-9 numpad */ + quant = (quant * 10) + (ksym ^ XK_KP_0); + return 0; + } + else if ( ksym == XK_k || ksym == XK_h ) + i = ksym & 1; + else if ( ksym == XK_l || ksym == XK_j ) + i = ((ksym & 6) | 4) >> 1; + else if ( (XK_Home & ksym) != XK_Home || (i = (ksym ^ XK_Home) - 1) > 3 ) + break; + + xy = (i & 1) ? &term.c.y : &term.c.x; + sens = (i & 2) ? 1 : -1; + bound = (i >> 1 ^ 1) ? 0 : (i ^ 3) ? term.col - 1 : term.bot; + + if ( quant == 0 ) + quant++; + + if ( *xy == bound && ((sens < 0 && bound == 0) || (sens > 0 && bound > 0)) ) + break; + + *xy += quant * sens; + if ( *xy < 0 || ( bound > 0 && *xy > bound) ) + *xy = bound; + + select_or_drawcursor(selectsearch_mode, type); + } + quant = 0; + return 0; +} \ No newline at end of file diff --git a/patch/keyboardselect.h b/patch/keyboardselect.h new file mode 100644 index 0000000..fa2b490 --- /dev/null +++ b/patch/keyboardselect.h @@ -0,0 +1,3 @@ +void toggle_winmode(int); +void keyboard_select(const Arg *); +int trt_kbdselect(KeySym, char *, int); \ No newline at end of file diff --git a/patch/rightclicktoplumb_st.c b/patch/rightclicktoplumb_st.c new file mode 100644 index 0000000..c60b946 --- /dev/null +++ b/patch/rightclicktoplumb_st.c @@ -0,0 +1,19 @@ +#if defined(__OpenBSD__) + #include +#endif + +int +subprocwd(char *path) +{ +#if defined(__linux) + if (snprintf(path, PATH_MAX, "/proc/%d/cwd", pid) < 0) + return -1; + return 0; +#elif defined(__OpenBSD__) + size_t sz = PATH_MAX; + int name[3] = {CTL_KERN, KERN_PROC_CWD, pid}; + if (sysctl(name, 3, path, &sz, 0, 0) == -1) + return -1; + return 0; +#endif +} \ No newline at end of file diff --git a/patch/rightclicktoplumb_st.h b/patch/rightclicktoplumb_st.h new file mode 100644 index 0000000..98e42ab --- /dev/null +++ b/patch/rightclicktoplumb_st.h @@ -0,0 +1 @@ +int subprocwd(char *); \ No newline at end of file diff --git a/patch/rightclicktoplumb_x.c b/patch/rightclicktoplumb_x.c new file mode 100644 index 0000000..1b9b2bc --- /dev/null +++ b/patch/rightclicktoplumb_x.c @@ -0,0 +1,24 @@ +#include + +void +plumb(char *sel) { + if (sel == NULL) + return; + char cwd[PATH_MAX]; + pid_t child; + if (subprocwd(cwd) != 0) + return; + + switch(child = fork()) { + case -1: + return; + case 0: + if (chdir(cwd) != 0) + exit(1); + if (execvp(plumb_cmd, (char *const []){plumb_cmd, sel, 0}) == -1) + exit(1); + exit(0); + default: + waitpid(child, NULL, 0); + } +} \ No newline at end of file diff --git a/patch/rightclicktoplumb_x.h b/patch/rightclicktoplumb_x.h new file mode 100644 index 0000000..d0c8b88 --- /dev/null +++ b/patch/rightclicktoplumb_x.h @@ -0,0 +1 @@ +void plumb(char *); \ No newline at end of file diff --git a/patch/st_include.c b/patch/st_include.c index 09b2a92..736b566 100644 --- a/patch/st_include.c +++ b/patch/st_include.c @@ -8,6 +8,18 @@ #include "externalpipe.c" #endif +#if ISO14755_PATCH +#include "iso14755.c" +#endif + +#if KEYBOARDSELECT_PATCH +#include "keyboardselect.c" +#endif + +#if RIGHTCLICKTOPLUMB_PATCH +#include "rightclicktoplumb_st.c" +#endif + #if NEWTERM_PATCH #include "newterm.c" #endif diff --git a/patch/st_include.h b/patch/st_include.h index e5423ec..8c6a342 100644 --- a/patch/st_include.h +++ b/patch/st_include.h @@ -12,6 +12,18 @@ void xximspot(int, int); #endif +#if ISO14755_PATCH +#include "iso14755.h" +#endif + +#if KEYBOARDSELECT_PATCH +#include "keyboardselect.h" +#endif + +#if RIGHTCLICKTOPLUMB_PATCH +#include "rightclicktoplumb_st.h" +#endif + #if NEWTERM_PATCH #include "newterm.h" #endif diff --git a/patch/visualbell.c b/patch/visualbell.c new file mode 100644 index 0000000..903f13a --- /dev/null +++ b/patch/visualbell.c @@ -0,0 +1,45 @@ +int +isvbellcell(int x, int y) +{ + if (vbellmode == 1) + return 1; + if (vbellmode == 2) + return y == 0 || y == win.th / win.ch - 1 || + x == 0 || x == win.tw / win.cw - 1; + return 0; +} + +void +vbellbegin() +{ + clock_gettime(CLOCK_MONOTONIC, &win.lastvbell); + if (win.vbellset) /* already visible, just extend win.lastvbell */ + return; + win.vbellset = 1; + #if VISUALBELL_3_PATCH + if (vbellmode != 3) /* 3 is an overlay, no need to re-render cells */ + tfulldirt(); + #else + tfulldirt(); + #endif // VISUALBELL_3_PATCH + draw(); + XFlush(xw.dpy); +} + +#if VISUALBELL_3_PATCH +void +xfillcircle(int x, int y, int r, uint color_ix) +{ + XSetForeground(xw.dpy, dc.gc, dc.col[color_ix].pixel); + XFillArc(xw.dpy, xw.buf, dc.gc, x - r, y - r, r * 2, r * 2, 0, 360*64); +} + +void +xdrawvbell() { + int r = round(vbellradius * (vbellradius > 0 ? win.w : -win.cw)); + int x = borderpx + r + vbellx * (win.tw - 2 * r); + int y = borderpx + r + vbelly * (win.th - 2 * r); + xfillcircle(x, y, r, vbellcolor_outline); + xfillcircle(x, y, r / 1.2, vbellcolor); /* 1.2 - an artistic choice */ +} +#endif // VISUALBELL_3_PATCH \ No newline at end of file diff --git a/patch/visualbell.h b/patch/visualbell.h new file mode 100644 index 0000000..9ef8ec9 --- /dev/null +++ b/patch/visualbell.h @@ -0,0 +1,7 @@ +static void vbellbegin(); +static int isvbellcell(int x, int y); + +#if VISUALBELL_3_PATCH +static void xdrawvbell(); +static void xfillcircle(int x, int y, int r, uint color_ix); +#endif // VISUALBELL_3_PATCH \ No newline at end of file diff --git a/patch/x_include.c b/patch/x_include.c index 1f09c89..05e6f66 100644 --- a/patch/x_include.c +++ b/patch/x_include.c @@ -1,5 +1,9 @@ /* Patches */ +#if BOXDRAW_PATCH +#include "boxdraw.c" +#endif + #if OPENCOPIED_PATCH #include "opencopied.c" #endif @@ -8,6 +12,28 @@ #include "fixime.c" #endif +#if FIXKEYBOARDINPUT_PATCH +#include "fixkeyboardinput.c" +#endif + +#if KEYBOARDSELECT_PATCH +void toggle_winmode(int flag) { + win.mode ^= flag; +} + +void keyboard_select(const Arg *dummy) { + win.mode ^= trt_kbdselect(-1, NULL, 0); +} +#endif // KEYBOARDSELECT_PATCH + +#if RIGHTCLICKTOPLUMB_PATCH +#include "rightclicktoplumb_x.c" +#endif + +#if VISUALBELL_2_PATCH || VISUALBELL_3_PATCH +#include "visualbell.c" +#endif + #if XRESOURCES_PATCH #include "xresources.c" #endif \ No newline at end of file diff --git a/patch/x_include.h b/patch/x_include.h index fa163b2..a085995 100644 --- a/patch/x_include.h +++ b/patch/x_include.h @@ -1,5 +1,9 @@ /* Patches */ +#if BOXDRAW_PATCH +#include "boxdraw.h" +#endif + #if OPENCOPIED_PATCH #include "opencopied.h" #endif @@ -8,6 +12,14 @@ #include "fixime.h" #endif +#if RIGHTCLICKTOPLUMB_PATCH +#include "rightclicktoplumb_x.h" +#endif + +#if VISUALBELL_2_PATCH || VISUALBELL_3_PATCH +#include "visualbell.h" +#endif + #if XRESOURCES_PATCH #include "xresources.h" #endif \ No newline at end of file diff --git a/patches.h b/patches.h index e4cfc76..b030efb 100644 --- a/patches.h +++ b/patches.h @@ -12,83 +12,116 @@ /* The alpha patch adds transparency for the terminal. * https://st.suckless.org/patches/alpha/ */ -#define ALPHA_PATCH 1 +#define ALPHA_PATCH 0 /* This patch allows st to reize to any pixel size rather than snapping to character width/height. * https://st.suckless.org/patches/anysize/ */ -#define ANYSIZE_PATCH 1 +#define ANYSIZE_PATCH 0 /* By default bold text is rendered with a bold font in the bright variant of the current color. * This patch makes bold text rendered simply as bold, leaving the color unaffected. * https://st.suckless.org/patches/bold-is-not-bright/ */ -#define BOLD_IS_NOT_BRIGHT_PATCH 1 +#define BOLD_IS_NOT_BRIGHT_PATCH 0 + +/* This patch adds dustom rendering of lines/blocks/braille characters for gapless alignment. + * https://st.suckless.org/patches/boxdraw/ + */ +#define BOXDRAW_PATCH 0 /* By default st only sets PRIMARY on selection. * This patch makes st set CLIPBOARD on selection. * https://st.suckless.org/patches/clipboard/ */ -#define CLIPBOARD_PATCH 1 +#define CLIPBOARD_PATCH 0 /* Select and copy the last URL displayed with Mod+l. Multiple invocations cycle through the * available URLs. * https://st.suckless.org/patches/copyurl/ */ -#define COPYURL_PATCH 1 +#define COPYURL_PATCH 0 /* Select and copy the last URL displayed with Mod+l. Multiple invocations cycle through the * available URLs. This variant also highlights the selected URLs. * https://st.suckless.org/patches/copyurl/ */ -#define COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH 1 +#define COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH 0 /* This patch adds the option of disabling bold fonts globally. * https://st.suckless.org/patches/disable_bold_italic_fonts/ */ -#define DISABLE_BOLD_FONTS_PATCH 1 +#define DISABLE_BOLD_FONTS_PATCH 0 /* This patch adds the option of disabling italic fonts globally. * https://st.suckless.org/patches/disable_bold_italic_fonts/ */ -#define DISABLE_ITALIC_FONTS_PATCH 1 +#define DISABLE_ITALIC_FONTS_PATCH 0 /* This patch adds the option of disabling roman fonts globally. * https://st.suckless.org/patches/disable_bold_italic_fonts/ */ -#define DISABLE_ROMAN_FONTS_PATCH 1 +#define DISABLE_ROMAN_FONTS_PATCH 0 /* Reading and writing st's screen through a pipe, e.g. pass info to dmenu. * https://st.suckless.org/patches/externalpipe/ */ -#define EXTERNALPIPE_PATCH 1 +#define EXTERNALPIPE_PATCH 0 /* This patch adds better Input Method Editor (IME) support. * https://st.suckless.org/patches/fix_ime/ */ -#define FIXIME_PATCH 1 +#define FIXIME_PATCH 0 + +/* + * https://st.suckless.org/patches/fix_keyboard_input/ + */ +#define FIXKEYBOARDINPUT_PATCH 0 /* Hide the X cursor whenever a key is pressed and show it back when the mouse is moved in * the terminal window. * https://st.suckless.org/patches/hidecursor/ */ -#define HIDECURSOR_PATCH 1 +#define HIDECURSOR_PATCH 0 + +/* Pressing the default binding Ctrl+Shift-i will popup dmenu, asking you to enter a unicode + * codepoint that will be converted to a glyph and then pushed to st. + * https://st.suckless.org/patches/iso14755/ + */ +#define ISO14755_PATCH 0 + +/* This patch allows you to select text on the terminal using keyboard shortcuts. + * https://st.suckless.org/patches/keyboard_select/ + */ +#define KEYBOARDSELECT_PATCH 0 /* This patch allows you to spawn a new st terminal using Ctrl-Shift-Return. It will have the * same CWD (current working directory) as the original st instance. * https://st.suckless.org/patches/newterm/ */ -#define NEWTERM_PATCH 1 +#define NEWTERM_PATCH 0 /* Open contents of the clipboard in a user-defined browser. * https://st.suckless.org/patches/open_copied_url/ */ -#define OPENCOPIED_PATCH 1 +#define OPENCOPIED_PATCH 0 + +/* This patch allows you to specify a border that is relative in size to the width of a cell + * in the terminal. + * https://st.suckless.org/patches/relativeborder/ + */ +#define RELATIVEBORDER_PATCH 0 + +/* This patch allows you to right-click on some selected text to send it to the plumbing + * program of choice, e.g. open a file, view an image, open a URL. + * https://st.suckless.org/patches/right_click_to_plumb/ + */ +#define RIGHTCLICKTOPLUMB_PATCH 0 /* Scroll back through terminal output using Shift+{PageUp, PageDown}. * https://st.suckless.org/patches/scrollback/ */ -#define SCROLLBACK_PATCH 1 +#define SCROLLBACK_PATCH 0 /* Scroll back through terminal output using Shift+MouseWheel. * This variant depends on SCROLLBACK_PATCH being enabled. @@ -100,26 +133,50 @@ * This variant depends on SCROLLBACK_PATCH being enabled. * https://st.suckless.org/patches/scrollback/ */ -#define SCROLLBACK_MOUSE_ALTSCREEN_PATCH 1 +#define SCROLLBACK_MOUSE_ALTSCREEN_PATCH 0 /* Use inverted defaultbg/fg for selection when bg/fg are the same. * https://st.suckless.org/patches/spoiler/ */ -#define SPOILER_PATCH 1 +#define SPOILER_PATCH 0 /* Instead of a default X cursor, use the xterm cursor from your cursor theme. * https://st.suckless.org/patches/themed_cursor/ */ -#define THEMED_CURSOR_PATCH 1 +#define THEMED_CURSOR_PATCH 0 /* * Vertically center lines in the space available if you have set a larger chscale in config.h * https://st.suckless.org/patches/vertcenter/ */ -#define VERTCENTER_PATCH 1 +#define VERTCENTER_PATCH 0 + +/* On receiving a terminal bell event this patch briefly inverts the window content colors. + * You may need to reduce the xfps value in config.h to less or equal to that of the refresh + * rate of your monitor for this to be noticeble. + * The visualbell 2 and 3 patches takes precedence over this patch. + * https://st.suckless.org/patches/visualbell/ + */ +#define VISUALBELL_1_PATCH 0 + +/* On receiving a terminal bell event this patch either: + * - briefly inverts the window content colors across the whole terminal or + * - briefly inverts the window content colors across the window border + * The visualbell 3 patch takes precedence over this patch. + * https://st.suckless.org/patches/visualbell/ + */ +#define VISUALBELL_2_PATCH 0 + +/* On receiving a terminal bell event this patch either: + * - briefly inverts the window content colors across the whole terminal or + * - briefly inverts the window content colors across the window border or + * - draws a (configurable) circle as a visual bell indicator + * https://st.suckless.org/patches/visualbell/ + */ +#define VISUALBELL_3_PATCH 0 /* This patch adds the ability to configure st via Xresources. At startup, st will read and * apply the resources named in the resources[] array in config.h. * https://st.suckless.org/patches/xresources/ */ -#define XRESOURCES_PATCH 1 +#define XRESOURCES_PATCH 0 diff --git a/st.c b/st.c index e01d36c..3557ace 100644 --- a/st.c +++ b/st.c @@ -20,6 +20,11 @@ #include "st.h" #include "win.h" +#if KEYBOARDSELECT_PATCH +#include +#include +#endif // KEYBOARDSELECT_PATCH + #if defined(__linux) #include #elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) @@ -206,7 +211,9 @@ static void tsetscroll(int, int); static void tswapscreen(void); static void tsetmode(int, int, int *, int); static int twrite(const char *, int, int); +#if !VISUALBELL_2_PATCH && !VISUALBELL_3_PATCH static void tfulldirt(void); +#endif // VISUALBELL_2_PATCH static void tcontrolcode(uchar ); static void tdectest(char ); static void tdefutf8(char); @@ -867,7 +874,11 @@ ttynew(char *line, char *cmd, char *out, char **args) break; default: #ifdef __OpenBSD__ + #if RIGHTCLICKTOPLUMB_PATCH + if (pledge("stdio rpath tty proc ps exec", NULL) == -1) + #else if (pledge("stdio rpath tty proc", NULL) == -1) + #endif // RIGHTCLICKTOPLUMB_PATCH die("pledge\n"); #endif close(s); @@ -1323,6 +1334,11 @@ tsetchar(Rune u, Glyph *attr, int x, int y) term.dirty[y] = 1; term.line[y][x] = *attr; term.line[y][x].u = u; + + #if BOXDRAW_PATCH + if (isboxdraw(u)) + term.line[y][x].mode |= ATTR_BOXDRAW; + #endif // BOXDRAW_PATCH } void @@ -2601,6 +2617,11 @@ tresize(int col, int row) int *bp; TCursor c; + #if KEYBOARDSELECT_PATCH + if ( row < term.row || col < term.col ) + toggle_winmode(trt_kbdselect(XK_Escape, NULL, 0)); + #endif // KEYBOARDSELECT_PATCH + if (col < 1 || row < 1) { fprintf(stderr, "tresize: error resizing to %dx%d\n", col, row); diff --git a/st.h b/st.h index dd23c4f..f87a2b8 100644 --- a/st.h +++ b/st.h @@ -34,6 +34,9 @@ enum glyph_attribute { ATTR_WRAP = 1 << 8, ATTR_WIDE = 1 << 9, ATTR_WDUMMY = 1 << 10, + #if BOXDRAW_PATCH + ATTR_BOXDRAW = 1 << 11, + #endif // BOXDRAW_PATCH ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT, }; @@ -90,6 +93,9 @@ int tattrset(int); void tnew(int, int); void tresize(int, int); void tsetdirtattr(int); +#if VISUALBELL_2_PATCH || VISUALBELL_3_PATCH +void tfulldirt(); +#endif // VISUALBELL_2_PATCH void ttyhangup(void); int ttynew(char *, char *, char *, char **); size_t ttyread(void); @@ -110,6 +116,18 @@ size_t utf8encode(Rune, char *); void *xmalloc(size_t); void *xrealloc(void *, size_t); char *xstrdup(char *); +#if BOXDRAW_PATCH +int isboxdraw(Rune); +ushort boxdrawindex(const Glyph *); +#ifdef XFT_VERSION +/* only exposed to x.c, otherwise we'll need Xft.h for the types */ +void boxdraw_xinit(Display *, Colormap, XftDraw *, Visual *); +void drawboxes(int, int, int, int, XftColor *, XftColor *, const XftGlyphFontSpec *, int); +#endif // XFT_VERSION +#endif // BOXDRAW_PATCH +#if RELATIVEBORDER_PATCH +int borderpx; +#endif // RELATIVEBORDER_PATCH /* config.h globals */ extern char *utmp; @@ -121,6 +139,9 @@ extern char *termname; extern unsigned int tabspaces; extern unsigned int defaultfg; extern unsigned int defaultbg; +#if BOXDRAW_PATCH +extern const int boxdraw, boxdraw_bold, boxdraw_braille; +#endif // BOXDRAW_PATCH #if ALPHA_PATCH extern float alpha; #endif // ALPHA_PATCH \ No newline at end of file diff --git a/st.info b/st.info index 52fc617..39362a8 100644 --- a/st.info +++ b/st.info @@ -54,7 +54,7 @@ st| simpleterm, ka3=\E[5~, kc1=\E[4~, kc3=\E[6~, - kbs=\177, + kbs=\010, kcbt=\E[Z, kb2=\EOu, kcub1=\EOD, @@ -74,7 +74,7 @@ st| simpleterm, kri=\E[1;2A, kclr=\E[3;5~, kdl1=\E[3;2~, - kdch1=\E[3~, + kdch1=\177~, kich1=\E[2~, kend=\E[4~, kf1=\EOP, diff --git a/win.h b/win.h index 31f327d..820a4a3 100644 --- a/win.h +++ b/win.h @@ -21,6 +21,9 @@ enum win_mode { MODE_NUMLOCK = 1 << 17, MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\ |MODE_MOUSEMANY, + #if KEYBOARDSELECT_PATCH + MODE_KBDSELECT = 1 << 18, + #endif // KEYBOARDSELECT_PATCH }; void xbell(void); diff --git a/x.c b/x.c index 2d19b12..c2c80fb 100644 --- a/x.c +++ b/x.c @@ -95,6 +95,10 @@ typedef struct { #endif // VERTCENTER_PATCH int mode; /* window state/mode flags */ int cursor; /* cursor style */ + #if VISUALBELL_2_PATCH || VISUALBELL_3_PATCH + int vbellset; /* 1 during visual bell, 0 otherwise */ + struct timespec lastvbell; + #endif // VISUALBELL_2_PATCH } TermWindow; typedef struct { @@ -265,6 +269,9 @@ static char *opt_name = NULL; static char *opt_title = NULL; static int oldbutton = 3; /* button event on startup: 3 = release */ +#if VISUALBELL_1_PATCH && !VISUALBELL_2_PATCH && !VISUALBELL_3_PATCH +static int bellon = 0; /* visual bell status */ +#endif // VISUALBELL_1_PATCH #include "patch/x_include.c" @@ -707,6 +714,10 @@ brelease(XEvent *e) #endif // CLIPBOARD_PATCH else if (e->xbutton.button == Button1) mousesel(e, 1); + #if RIGHTCLICKTOPLUMB_PATCH + else if (e->xbutton.button == Button3) + plumb(xsel.primary); + #endif // RIGHTCLICKTOPLUMB_PATCH } void @@ -1056,6 +1067,9 @@ xloadfonts(char *fontstr, double fontsize) win.cyo = ceilf(dc.font.height * (chscale - 1) / 2); #endif // VERTCENTER_PATCH + #if RELATIVEBORDER_PATCH + borderpx = (int) ceilf(((float)borderperc / 100) * win.cw); + #endif // RELATIVEBORDER_PATCH FcPatternDel(pattern, FC_SLANT); #if !DISABLE_ITALIC_FONTS_PATCH FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); @@ -1298,6 +1312,10 @@ xinit(int cols, int rows) xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0); if (xsel.xtarget == None) xsel.xtarget = XA_STRING; + + #if BOXDRAW_PATCH + boxdraw_xinit(xw.dpy, xw.cmap, xw.draw, xw.vis); + #endif // BOXDRAW_PATCH } int @@ -1357,8 +1375,18 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x #endif // VERTCENTER_PATCH } + #if BOXDRAW_PATCH + if (mode & ATTR_BOXDRAW) { + /* minor shoehorning: boxdraw uses only this ushort */ + glyphidx = boxdrawindex(&glyphs[i]); + } else { + /* Lookup character index with default font. */ + glyphidx = XftCharIndex(xw.dpy, font->match, rune); + } + #else /* Lookup character index with default font. */ glyphidx = XftCharIndex(xw.dpy, font->match, rune); + #endif // BOXDRAW_PATCH if (glyphidx) { specs[numspecs].font = font->match; specs[numspecs].glyph = glyphidx; @@ -1598,8 +1626,17 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i r.width = width; XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1); + #if BOXDRAW_PATCH + if (base.mode & ATTR_BOXDRAW) { + drawboxes(winx, winy, width / len, win.ch, fg, bg, specs, len); + } else { + /* Render the glyphs. */ + XftDrawGlyphFontSpec(xw.draw, fg, specs, len); + } + #else /* Render the glyphs. */ XftDrawGlyphFontSpec(xw.draw, fg, specs, len); + #endif // BOXDRAW_PATCH /* Render underline and strikethrough. */ if (base.mode & ATTR_UNDERLINE) { @@ -1652,7 +1689,11 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) /* * Select the right color for the right mode. */ + #if BOXDRAW_PATCH + g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE|ATTR_BOXDRAW; + #else g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE; + #endif // BOXDRAW_PATCH if (IS_SET(MODE_REVERSE)) { g.mode |= ATTR_REVERSE; @@ -1797,6 +1838,10 @@ xdrawline(Line line, int x1, int y1, int x2) continue; if (selected(x, y1)) new.mode ^= ATTR_REVERSE; + #if VISUALBELL_2_PATCH || VISUALBELL_3_PATCH + if (win.vbellset && isvbellcell(x, y1)) + new.mode ^= ATTR_REVERSE; + #endif // VISUALBELL_2_PATCH if (i > 0 && ATTRCMP(base, new)) { xdrawglyphfontspecs(specs, base, i, ox, y1); specs += i; @@ -1816,6 +1861,10 @@ xdrawline(Line line, int x1, int y1, int x2) void xfinishdraw(void) { + #if VISUALBELL_3_PATCH + if (vbellmode == 3 && win.vbellset) + xdrawvbell(); + #endif // VISUALBELL_3_PATCH XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, win.h, 0, 0); XSetForeground(xw.dpy, dc.gc, @@ -1890,6 +1939,20 @@ xbell(void) xseturgency(1); if (bellvolume) XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); + + #if VISUALBELL_2_PATCH || VISUALBELL_3_PATCH + if (vbelltimeout) + vbellbegin(); + #elif VISUALBELL_1_PATCH + /* visual bell*/ + if (!bellon) { + bellon = 1; + MODBIT(win.mode, !IS_SET(MODE_REVERSE), MODE_REVERSE); + redraw(); + XFlush(xw.dpy); + MODBIT(win.mode, !IS_SET(MODE_REVERSE), MODE_REVERSE); + } + #endif // VISUALBELL_1_PATCH / VISUALBELL_2_PATCH } void @@ -1980,6 +2043,15 @@ kpress(XEvent *ev) return; len = XmbLookupString(xw.xic, e, buf, sizeof buf, &ksym, &status); + #if KEYBOARDSELECT_PATCH + if ( IS_SET(MODE_KBDSELECT) ) { + if ( match(XK_NO_MOD, e->state) || + (XK_Shift_L | XK_Shift_R) & e->state ) + win.mode ^= trt_kbdselect(ksym, buf, len); + return; + } + #endif // KEYBOARDSELECT_PATCH + /* 1. shortcuts */ for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { if (ksym == bp->keysym && match(bp->mod, e->state)) { @@ -2052,6 +2124,9 @@ run(void) int ttyfd; struct timespec drawtimeout, *tv = NULL, now, last, lastblink; long deltatime; + #if VISUALBELL_2_PATCH || VISUALBELL_3_PATCH + long to_ms, remain; + #endif // VISUALBELL_2_PATCH /* Waiting for window mapping */ do { @@ -2103,12 +2178,39 @@ run(void) tv = &drawtimeout; dodraw = 0; + #if VISUALBELL_2_PATCH || VISUALBELL_3_PATCH + to_ms = -1; /* timeout in ms, indefinite if negative */ + if (blinkset) { + remain = blinktimeout - TIMEDIFF(now, lastblink); + if (remain <= 0) { + dodraw = 1; + remain = 1; /* draw, wait 1ms, and re-calc */ + tsetdirtattr(ATTR_BLINK); + win.mode ^= MODE_BLINK; + lastblink = now; + } + to_ms = remain; + } + if (win.vbellset) { + remain = vbelltimeout - TIMEDIFF(now, win.lastvbell); + if (remain <= 0) { + dodraw = 1; + remain = -1; /* draw (clear), and that's it */ + tfulldirt(); + win.vbellset = 0; + } + if (remain >= 0 && (to_ms < 0 || remain < to_ms)) + to_ms = remain; + } + + #else if (blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) { tsetdirtattr(ATTR_BLINK); win.mode ^= MODE_BLINK; lastblink = now; dodraw = 1; } + #endif // VISUALBELL_2_PATCH deltatime = TIMEDIFF(now, last); if (deltatime > 1000 / (xev ? xfps : actionfps)) { dodraw = 1; @@ -2124,12 +2226,30 @@ run(void) (handler[ev.type])(&ev); } + #if VISUALBELL_1_PATCH && !VISUALBELL_2_PATCH && !VISUALBELL_3_PATCH + if (bellon) { + bellon = 0; + redraw(); + } + else draw(); + XFlush(xw.dpy); + #else draw(); + #endif // VISUALBELL_1_PATCH XFlush(xw.dpy); if (xev && !FD_ISSET(xfd, &rfd)) xev--; if (!FD_ISSET(ttyfd, &rfd) && !FD_ISSET(xfd, &rfd)) { + #if VISUALBELL_2_PATCH || VISUALBELL_3_PATCH + if (to_ms >= 0) { + static const long k = 1E3, m = 1E6; + drawtimeout.tv_sec = to_ms / k; + drawtimeout.tv_nsec = (to_ms % k) * m; + } else { + tv = NULL; + } + #else if (blinkset) { if (TIMEDIFF(now, lastblink) \ > blinktimeout) { @@ -2146,6 +2266,7 @@ run(void) } else { tv = NULL; } + #endif // VISUALBELL_2_PATCH } } }