1/* See LICENSE file for copyright and license details. */
2
3/*
4 * appearance
5 *
6 * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
7 */
8static char font[] = "Terminus:pixelsize=12";
9static int borderpx = 5;
10
11/*
12 * What program is execed by st depends of these precedence rules:
13 * 1: program passed with -e
14 * 2: utmp option
15 * 3: SHELL environment variable
16 * 4: value of shell in /etc/passwd
17 * 5: value of shell in config.h
18 */
19static char shell[] = "/bin/sh";
20static char *utmp = NULL;
21static char stty_args[] = "stty raw pass8 nl -echo -iexten -cstopb 38400";
22
23/* identification sequence returned in DA and DECID */
24static char vtiden[] = "\033[?6c";
25
26/* Kerning / character bounding-box multipliers */
27static float cwscale = 1.0;
28static float chscale = 1.0;
29
30/*
31 * word delimiter string
32 *
33 * More advanced example: " `'\"()[]{}"
34 */
35static char worddelimiters[] = " ";
36
37/* selection timeouts (in milliseconds) */
38static unsigned int doubleclicktimeout = 300;
39static unsigned int tripleclicktimeout = 600;
40
41/* key repeat timeouts (in milliseconds) */
42static unsigned int keyrepeatdelay = 500;
43static unsigned int keyrepeatinterval = 25;
44
45/* alt screens */
46static int allowaltscreen = 1;
47
48/*
49 * blinking timeout (set to 0 to disable blinking) for the terminal blinking
50 * attribute.
51 */
52static unsigned int blinktimeout = 800;
53
54/*
55 * thickness of underline and bar cursors
56 */
57static unsigned int cursorthickness = 2;
58
59/*
60 * bell volume. It must be a value between -100 and 100. Use 0 for disabling
61 * it
62 */
63/* XXX: Wayland does not have a bell.
64 * static int bellvolume = 0;
65 */
66
67/* default TERM value */
68static char termname[] = "st-256color";
69
70/*
71 * spaces per tab
72 *
73 * When you are changing this value, don't forget to adapt the »it« value in
74 * the st.info and appropriately install the st.info in the environment where
75 * you use this st version.
76 *
77 * it#$tabspaces,
78 *
79 * Secondly make sure your kernel is not expanding tabs. When running `stty
80 * -a` »tab0« should appear. You can tell the terminal to not expand tabs by
81 * running following command:
82 *
83 * stty tabs
84 */
85static unsigned int tabspaces = 8;
86
87/* Terminal colors (16 first used in escape sequence) */
88static const char *colorname[] = {
89 /* 8 normal colors */
90 "#1d1d1d",
91 "#755a5b",
92 "#68755a",
93 "#756e5a",
94 "#5b6976",
95 "#755b76",
96 "#465457",
97 "#ccccc6",
98
99 /* 8 bright colors */
100 "#5a5b5c",
101 "#a37679",
102 "#87a376",
103 "#a39b76",
104 "#758ba3",
105 "#9f76a3",
106 "#899ca1",
107 "#f8f8f2",
108
109 [255] = 0,
110
111 /* more colors can be added after 255 to use with DefaultXX */
112 "#cccccc",
113 "#555555",
114
115 /* background */
116 "#000000",
117
118 /* foreground */
119 "#babdb6"
120};
121
122
123/*
124 * Default colors (colorname index)
125 * foreground, background, cursor, reverse cursor
126 */
127static unsigned int defaultfg = 15;
128static unsigned int defaultbg = 0;
129static unsigned int defaultcs = 15;
130static unsigned int defaultrcs = 257;
131
132/*
133 * Default shape of cursor
134 * 2: Block ("█")
135 * 4: Underline ("_")
136 * 6: Bar ("|")
137 * 7: Snowman ("☃")
138 */
139static unsigned int cursorshape = 4;
140
141/*
142 * Default columns and rows numbers
143 */
144
145static unsigned int cols = 80;
146static unsigned int rows = 24;
147
148/*
149 * Default shape of the mouse cursor
150 */
151static char mouseshape[] = "xterm";
152
153/*
154 * Color used to display font attributes when fontconfig selected a font which
155 * doesn't match the ones requested.
156 */
157static unsigned int defaultattr = 11;
158
159/*
160 * Internal mouse shortcuts.
161 * Beware that overloading Button1 will disable the selection.
162 */
163static MouseShortcut mshortcuts[] = {
164 /* button mask string */
165 { -1, MOD_MASK_NONE, "" }
166};
167
168static Axiskey ashortcuts[] = {
169 /* axis direction mask string */
170 { AXIS_VERTICAL, +1, MOD_MASK_ANY, "\031"},
171 { AXIS_VERTICAL, -1, MOD_MASK_ANY, "\005"},
172};
173
174/* Internal keyboard shortcuts. */
175#define MODKEY MOD_MASK_ALT
176
177static Shortcut shortcuts[] = {
178 /* modifier key function argument */
179 { MOD_MASK_ANY, XKB_KEY_Break, sendbreak, {.i = 0} },
180 { MOD_MASK_CTRL, XKB_KEY_Print, toggleprinter, {.i = 0} },
181 { MOD_MASK_SHIFT, XKB_KEY_Print, printscreen, {.i = 0} },
182 { MOD_MASK_ANY, XKB_KEY_Print, printsel, {.i = 0} },
183 { MODKEY|MOD_MASK_SHIFT, XKB_KEY_Prior, wlzoom, {.f = +1} },
184 { MODKEY|MOD_MASK_SHIFT, XKB_KEY_Next, wlzoom, {.f = -1} },
185 { MODKEY|MOD_MASK_SHIFT, XKB_KEY_Home, wlzoomreset, {.f = 0} },
186 { MODKEY|MOD_MASK_SHIFT, XKB_KEY_V, selpaste, {.i = 0} },
187 { MODKEY|MOD_MASK_SHIFT, XKB_KEY_C, printsel, {.i = 0} },
188 { MODKEY, XKB_KEY_Num_Lock, numlock, {.i = 0} },
189 { MODKEY, XKB_KEY_Control_R, iso14755, {.i = 0} },
190};
191
192/*
193 * Special keys (change & recompile st.info accordingly)
194 *
195 * Mask value:
196 * * Use MOD_MASK_ANY to match the key no matter modifiers state
197 * * Use MOD_MASK_NONE to match the key alone (no modifiers)
198 * appkey value:
199 * * 0: no value
200 * * > 0: keypad application mode enabled
201 * * = 2: term.numlock = 1
202 * * < 0: keypad application mode disabled
203 * appcursor value:
204 * * 0: no value
205 * * > 0: cursor application mode enabled
206 * * < 0: cursor application mode disabled
207 * crlf value
208 * * 0: no value
209 * * > 0: crlf mode is enabled
210 * * < 0: crlf mode is disabled
211 *
212 * Be careful with the order of the definitions because st searches in
213 * this table sequentially, so any MOD_MASK_ANY must be in the last
214 * position for a key.
215 */
216
217/*
218 * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
219 * to be mapped below, add them to this array.
220 */
221static xkb_keysym_t mappedkeys[] = { -1 };
222
223/* State bits to ignore when matching key or button events. */
224static uint ignoremod = 0;
225
226/*
227 * Override mouse-select while mask is active (when MODE_MOUSE is set).
228 * Note that if you want to use MOD_MASK_SHIFT with selmasks, set this to an
229 * other modifier, set to 0 to not use it.
230 */
231static uint forceselmod = MOD_MASK_SHIFT;
232
233/*
234 * This is the huge key array which defines all compatibility to the Linux
235 * world. Please decide about changes wisely.
236 */
237static Key key[] = {
238 /* keysym mask string appkey appcursor crlf */
239 { XKB_KEY_KP_Home, MOD_MASK_SHIFT, "\033[2J", 0, -1, 0},
240 { XKB_KEY_KP_Home, MOD_MASK_SHIFT, "\033[1;2H", 0, +1, 0},
241 { XKB_KEY_KP_Home, MOD_MASK_ANY, "\033[H", 0, -1, 0},
242 { XKB_KEY_KP_Home, MOD_MASK_ANY, "\033[1~", 0, +1, 0},
243 { XKB_KEY_KP_Up, MOD_MASK_ANY, "\033Ox", +1, 0, 0},
244 { XKB_KEY_KP_Up, MOD_MASK_ANY, "\033[A", 0, -1, 0},
245 { XKB_KEY_KP_Up, MOD_MASK_ANY, "\033OA", 0, +1, 0},
246 { XKB_KEY_KP_Down, MOD_MASK_ANY, "\033Or", +1, 0, 0},
247 { XKB_KEY_KP_Down, MOD_MASK_ANY, "\033[B", 0, -1, 0},
248 { XKB_KEY_KP_Down, MOD_MASK_ANY, "\033OB", 0, +1, 0},
249 { XKB_KEY_KP_Left, MOD_MASK_ANY, "\033Ot", +1, 0, 0},
250 { XKB_KEY_KP_Left, MOD_MASK_ANY, "\033[D", 0, -1, 0},
251 { XKB_KEY_KP_Left, MOD_MASK_ANY, "\033OD", 0, +1, 0},
252 { XKB_KEY_KP_Right, MOD_MASK_ANY, "\033Ov", +1, 0, 0},
253 { XKB_KEY_KP_Right, MOD_MASK_ANY, "\033[C", 0, -1, 0},
254 { XKB_KEY_KP_Right, MOD_MASK_ANY, "\033OC", 0, +1, 0},
255 { XKB_KEY_KP_Prior, MOD_MASK_SHIFT, "\033[5;2~", 0, 0, 0},
256 { XKB_KEY_KP_Prior, MOD_MASK_ANY, "\033[5~", 0, 0, 0},
257 { XKB_KEY_KP_Begin, MOD_MASK_ANY, "\033[E", 0, 0, 0},
258 { XKB_KEY_KP_End, MOD_MASK_CTRL, "\033[J", -1, 0, 0},
259 { XKB_KEY_KP_End, MOD_MASK_CTRL, "\033[1;5F", +1, 0, 0},
260 { XKB_KEY_KP_End, MOD_MASK_SHIFT, "\033[K", -1, 0, 0},
261 { XKB_KEY_KP_End, MOD_MASK_SHIFT, "\033[1;2F", +1, 0, 0},
262 { XKB_KEY_KP_End, MOD_MASK_ANY, "\033[4~", 0, 0, 0},
263 { XKB_KEY_KP_Next, MOD_MASK_SHIFT, "\033[6;2~", 0, 0, 0},
264 { XKB_KEY_KP_Next, MOD_MASK_ANY, "\033[6~", 0, 0, 0},
265 { XKB_KEY_KP_Insert, MOD_MASK_SHIFT, "\033[2;2~", +1, 0, 0},
266 { XKB_KEY_KP_Insert, MOD_MASK_SHIFT, "\033[4l", -1, 0, 0},
267 { XKB_KEY_KP_Insert, MOD_MASK_CTRL, "\033[L", -1, 0, 0},
268 { XKB_KEY_KP_Insert, MOD_MASK_CTRL, "\033[2;5~", +1, 0, 0},
269 { XKB_KEY_KP_Insert, MOD_MASK_ANY, "\033[4h", -1, 0, 0},
270 { XKB_KEY_KP_Insert, MOD_MASK_ANY, "\033[2~", +1, 0, 0},
271 { XKB_KEY_KP_Delete, MOD_MASK_CTRL, "\033[M", -1, 0, 0},
272 { XKB_KEY_KP_Delete, MOD_MASK_CTRL, "\033[3;5~", +1, 0, 0},
273 { XKB_KEY_KP_Delete, MOD_MASK_SHIFT, "\033[2K", -1, 0, 0},
274 { XKB_KEY_KP_Delete, MOD_MASK_SHIFT, "\033[3;2~", +1, 0, 0},
275 { XKB_KEY_KP_Delete, MOD_MASK_ANY, "\033[P", -1, 0, 0},
276 { XKB_KEY_KP_Delete, MOD_MASK_ANY, "\033[3~", +1, 0, 0},
277 { XKB_KEY_KP_Multiply, MOD_MASK_ANY, "\033Oj", +2, 0, 0},
278 { XKB_KEY_KP_Add, MOD_MASK_ANY, "\033Ok", +2, 0, 0},
279 { XKB_KEY_KP_Enter, MOD_MASK_ANY, "\033OM", +2, 0, 0},
280 { XKB_KEY_KP_Enter, MOD_MASK_ANY, "\r", -1, 0, -1},
281 { XKB_KEY_KP_Enter, MOD_MASK_ANY, "\r\n", -1, 0, +1},
282 { XKB_KEY_KP_Subtract, MOD_MASK_ANY, "\033Om", +2, 0, 0},
283 { XKB_KEY_KP_Decimal, MOD_MASK_ANY, "\033On", +2, 0, 0},
284 { XKB_KEY_KP_Divide, MOD_MASK_ANY, "\033Oo", +2, 0, 0},
285 { XKB_KEY_KP_0, MOD_MASK_ANY, "\033Op", +2, 0, 0},
286 { XKB_KEY_KP_1, MOD_MASK_ANY, "\033Oq", +2, 0, 0},
287 { XKB_KEY_KP_2, MOD_MASK_ANY, "\033Or", +2, 0, 0},
288 { XKB_KEY_KP_3, MOD_MASK_ANY, "\033Os", +2, 0, 0},
289 { XKB_KEY_KP_4, MOD_MASK_ANY, "\033Ot", +2, 0, 0},
290 { XKB_KEY_KP_5, MOD_MASK_ANY, "\033Ou", +2, 0, 0},
291 { XKB_KEY_KP_6, MOD_MASK_ANY, "\033Ov", +2, 0, 0},
292 { XKB_KEY_KP_7, MOD_MASK_ANY, "\033Ow", +2, 0, 0},
293 { XKB_KEY_KP_8, MOD_MASK_ANY, "\033Ox", +2, 0, 0},
294 { XKB_KEY_KP_9, MOD_MASK_ANY, "\033Oy", +2, 0, 0},
295 { XKB_KEY_Up, MOD_MASK_SHIFT, "\033[1;2A", 0, 0, 0},
296 { XKB_KEY_Up, MOD_MASK_ALT, "\033[1;3A", 0, 0, 0},
297 { XKB_KEY_Up, MOD_MASK_SHIFT|MOD_MASK_ALT,"\033[1;4A", 0, 0, 0},
298 { XKB_KEY_Up, MOD_MASK_CTRL, "\033[1;5A", 0, 0, 0},
299 { XKB_KEY_Up,MOD_MASK_SHIFT|MOD_MASK_CTRL,"\033[1;6A", 0, 0, 0},
300 { XKB_KEY_Up, MOD_MASK_CTRL|MOD_MASK_ALT,"\033[1;7A", 0, 0, 0},
301 { XKB_KEY_Up,MOD_MASK_SHIFT|MOD_MASK_CTRL|MOD_MASK_ALT,"\033[1;8A",0,0,0},
302 { XKB_KEY_Up, MOD_MASK_ANY, "\033[A", 0, -1, 0},
303 { XKB_KEY_Up, MOD_MASK_ANY, "\033OA", 0, +1, 0},
304 { XKB_KEY_Down, MOD_MASK_SHIFT, "\033[1;2B", 0, 0, 0},
305 { XKB_KEY_Down, MOD_MASK_ALT, "\033[1;3B", 0, 0, 0},
306 { XKB_KEY_Down,MOD_MASK_SHIFT|MOD_MASK_ALT,"\033[1;4B", 0, 0, 0},
307 { XKB_KEY_Down, MOD_MASK_CTRL, "\033[1;5B", 0, 0, 0},
308 { XKB_KEY_Down,MOD_MASK_SHIFT|MOD_MASK_CTRL,"\033[1;6B", 0, 0, 0},
309 { XKB_KEY_Down,MOD_MASK_CTRL|MOD_MASK_ALT,"\033[1;7B", 0, 0, 0},
310 { XKB_KEY_Down,MOD_MASK_SHIFT|MOD_MASK_CTRL|MOD_MASK_ALT,"\033[1;8B",0,0,0},
311 { XKB_KEY_Down, MOD_MASK_ANY, "\033[B", 0, -1, 0},
312 { XKB_KEY_Down, MOD_MASK_ANY, "\033OB", 0, +1, 0},
313 { XKB_KEY_Left, MOD_MASK_SHIFT, "\033[1;2D", 0, 0, 0},
314 { XKB_KEY_Left, MOD_MASK_ALT, "\033[1;3D", 0, 0, 0},
315 { XKB_KEY_Left,MOD_MASK_SHIFT|MOD_MASK_ALT,"\033[1;4D", 0, 0, 0},
316 { XKB_KEY_Left, MOD_MASK_CTRL, "\033[1;5D", 0, 0, 0},
317 { XKB_KEY_Left,MOD_MASK_SHIFT|MOD_MASK_CTRL,"\033[1;6D", 0, 0, 0},
318 { XKB_KEY_Left,MOD_MASK_CTRL|MOD_MASK_ALT,"\033[1;7D", 0, 0, 0},
319 { XKB_KEY_Left,MOD_MASK_SHIFT|MOD_MASK_CTRL|MOD_MASK_ALT,"\033[1;8D",0,0,0},
320 { XKB_KEY_Left, MOD_MASK_ANY, "\033[D", 0, -1, 0},
321 { XKB_KEY_Left, MOD_MASK_ANY, "\033OD", 0, +1, 0},
322 { XKB_KEY_Right, MOD_MASK_SHIFT, "\033[1;2C", 0, 0, 0},
323 { XKB_KEY_Right, MOD_MASK_ALT, "\033[1;3C", 0, 0, 0},
324 { XKB_KEY_Right,MOD_MASK_SHIFT|MOD_MASK_ALT,"\033[1;4C", 0, 0, 0},
325 { XKB_KEY_Right, MOD_MASK_CTRL, "\033[1;5C", 0, 0, 0},
326 { XKB_KEY_Right,MOD_MASK_SHIFT|MOD_MASK_CTRL,"\033[1;6C", 0, 0, 0},
327 { XKB_KEY_Right,MOD_MASK_CTRL|MOD_MASK_ALT,"\033[1;7C", 0, 0, 0},
328 { XKB_KEY_Right,MOD_MASK_SHIFT|MOD_MASK_CTRL|MOD_MASK_ALT,"\033[1;8C",0,0,0},
329 { XKB_KEY_Right, MOD_MASK_ANY, "\033[C", 0, -1, 0},
330 { XKB_KEY_Right, MOD_MASK_ANY, "\033OC", 0, +1, 0},
331 { XKB_KEY_ISO_Left_Tab, MOD_MASK_SHIFT, "\033[Z", 0, 0, 0},
332 { XKB_KEY_Return, MOD_MASK_ALT, "\033\r", 0, 0, -1},
333 { XKB_KEY_Return, MOD_MASK_ALT, "\033\r\n", 0, 0, +1},
334 { XKB_KEY_Return, MOD_MASK_ANY, "\r", 0, 0, -1},
335 { XKB_KEY_Return, MOD_MASK_ANY, "\r\n", 0, 0, +1},
336 { XKB_KEY_Insert, MOD_MASK_SHIFT, "\033[4l", -1, 0, 0},
337 { XKB_KEY_Insert, MOD_MASK_SHIFT, "\033[2;2~", +1, 0, 0},
338 { XKB_KEY_Insert, MOD_MASK_CTRL, "\033[L", -1, 0, 0},
339 { XKB_KEY_Insert, MOD_MASK_CTRL, "\033[2;5~", +1, 0, 0},
340 { XKB_KEY_Insert, MOD_MASK_ANY, "\033[4h", -1, 0, 0},
341 { XKB_KEY_Insert, MOD_MASK_ANY, "\033[2~", +1, 0, 0},
342 { XKB_KEY_Delete, MOD_MASK_CTRL, "\033[M", -1, 0, 0},
343 { XKB_KEY_Delete, MOD_MASK_CTRL, "\033[3;5~", +1, 0, 0},
344 { XKB_KEY_Delete, MOD_MASK_SHIFT, "\033[2K", -1, 0, 0},
345 { XKB_KEY_Delete, MOD_MASK_SHIFT, "\033[3;2~", +1, 0, 0},
346 { XKB_KEY_Delete, MOD_MASK_ANY, "\033[P", -1, 0, 0},
347 { XKB_KEY_Delete, MOD_MASK_ANY, "\033[3~", +1, 0, 0},
348 { XKB_KEY_BackSpace, MOD_MASK_NONE, "\177", 0, 0, 0},
349 { XKB_KEY_BackSpace, MOD_MASK_CTRL, "\033\177", 0, 0, 0},
350 { XKB_KEY_Home, MOD_MASK_SHIFT, "\033[2J", 0, -1, 0},
351 { XKB_KEY_Home, MOD_MASK_SHIFT, "\033[1;2H", 0, +1, 0},
352 { XKB_KEY_Home, MOD_MASK_ANY, "\033[H", 0, -1, 0},
353 { XKB_KEY_Home, MOD_MASK_ANY, "\033[1~", 0, +1, 0},
354 { XKB_KEY_End, MOD_MASK_CTRL, "\033[J", -1, 0, 0},
355 { XKB_KEY_End, MOD_MASK_CTRL, "\033[1;5F", +1, 0, 0},
356 { XKB_KEY_End, MOD_MASK_SHIFT, "\033[K", -1, 0, 0},
357 { XKB_KEY_End, MOD_MASK_SHIFT, "\033[1;2F", +1, 0, 0},
358 { XKB_KEY_End, MOD_MASK_ANY, "\033[4~", 0, 0, 0},
359 { XKB_KEY_Prior, MOD_MASK_CTRL, "\033[5;5~", 0, 0, 0},
360 { XKB_KEY_Prior, MOD_MASK_SHIFT, "\033[5;2~", 0, 0, 0},
361 { XKB_KEY_Prior, MOD_MASK_ANY, "\033[5~", 0, 0, 0},
362 { XKB_KEY_Next, MOD_MASK_CTRL, "\033[6;5~", 0, 0, 0},
363 { XKB_KEY_Next, MOD_MASK_SHIFT, "\033[6;2~", 0, 0, 0},
364 { XKB_KEY_Next, MOD_MASK_ANY, "\033[6~", 0, 0, 0},
365 { XKB_KEY_F1, MOD_MASK_NONE, "\033OP" , 0, 0, 0},
366 { XKB_KEY_F1, /* F13 */ MOD_MASK_SHIFT, "\033[1;2P", 0, 0, 0},
367 { XKB_KEY_F1, /* F25 */ MOD_MASK_CTRL, "\033[1;5P", 0, 0, 0},
368 { XKB_KEY_F1, /* F37 */ MOD_MASK_LOGO, "\033[1;6P", 0, 0, 0},
369 { XKB_KEY_F1, /* F49 */ MOD_MASK_ALT, "\033[1;3P", 0, 0, 0},
370 { XKB_KEY_F2, MOD_MASK_NONE, "\033OQ" , 0, 0, 0},
371 { XKB_KEY_F2, /* F14 */ MOD_MASK_SHIFT, "\033[1;2Q", 0, 0, 0},
372 { XKB_KEY_F2, /* F26 */ MOD_MASK_CTRL, "\033[1;5Q", 0, 0, 0},
373 { XKB_KEY_F2, /* F38 */ MOD_MASK_LOGO, "\033[1;6Q", 0, 0, 0},
374 { XKB_KEY_F2, /* F50 */ MOD_MASK_ALT, "\033[1;3Q", 0, 0, 0},
375 { XKB_KEY_F3, MOD_MASK_NONE, "\033OR" , 0, 0, 0},
376 { XKB_KEY_F3, /* F15 */ MOD_MASK_SHIFT, "\033[1;2R", 0, 0, 0},
377 { XKB_KEY_F3, /* F27 */ MOD_MASK_CTRL, "\033[1;5R", 0, 0, 0},
378 { XKB_KEY_F3, /* F39 */ MOD_MASK_LOGO, "\033[1;6R", 0, 0, 0},
379 { XKB_KEY_F3, /* F51 */ MOD_MASK_ALT, "\033[1;3R", 0, 0, 0},
380 { XKB_KEY_F4, MOD_MASK_NONE, "\033OS" , 0, 0, 0},
381 { XKB_KEY_F4, /* F16 */ MOD_MASK_SHIFT, "\033[1;2S", 0, 0, 0},
382 { XKB_KEY_F4, /* F28 */ MOD_MASK_CTRL, "\033[1;5S", 0, 0, 0},
383 { XKB_KEY_F4, /* F40 */ MOD_MASK_LOGO, "\033[1;6S", 0, 0, 0},
384 { XKB_KEY_F4, /* F52 */ MOD_MASK_ALT, "\033[1;3S", 0, 0, 0},
385 { XKB_KEY_F5, MOD_MASK_NONE, "\033[15~", 0, 0, 0},
386 { XKB_KEY_F5, /* F17 */ MOD_MASK_SHIFT, "\033[15;2~", 0, 0, 0},
387 { XKB_KEY_F5, /* F29 */ MOD_MASK_CTRL, "\033[15;5~", 0, 0, 0},
388 { XKB_KEY_F5, /* F41 */ MOD_MASK_LOGO, "\033[15;6~", 0, 0, 0},
389 { XKB_KEY_F5, /* F53 */ MOD_MASK_ALT, "\033[15;3~", 0, 0, 0},
390 { XKB_KEY_F6, MOD_MASK_NONE, "\033[17~", 0, 0, 0},
391 { XKB_KEY_F6, /* F18 */ MOD_MASK_SHIFT, "\033[17;2~", 0, 0, 0},
392 { XKB_KEY_F6, /* F30 */ MOD_MASK_CTRL, "\033[17;5~", 0, 0, 0},
393 { XKB_KEY_F6, /* F42 */ MOD_MASK_LOGO, "\033[17;6~", 0, 0, 0},
394 { XKB_KEY_F6, /* F54 */ MOD_MASK_ALT, "\033[17;3~", 0, 0, 0},
395 { XKB_KEY_F7, MOD_MASK_NONE, "\033[18~", 0, 0, 0},
396 { XKB_KEY_F7, /* F19 */ MOD_MASK_SHIFT, "\033[18;2~", 0, 0, 0},
397 { XKB_KEY_F7, /* F31 */ MOD_MASK_CTRL, "\033[18;5~", 0, 0, 0},
398 { XKB_KEY_F7, /* F43 */ MOD_MASK_LOGO, "\033[18;6~", 0, 0, 0},
399 { XKB_KEY_F7, /* F55 */ MOD_MASK_ALT, "\033[18;3~", 0, 0, 0},
400 { XKB_KEY_F8, MOD_MASK_NONE, "\033[19~", 0, 0, 0},
401 { XKB_KEY_F8, /* F20 */ MOD_MASK_SHIFT, "\033[19;2~", 0, 0, 0},
402 { XKB_KEY_F8, /* F32 */ MOD_MASK_CTRL, "\033[19;5~", 0, 0, 0},
403 { XKB_KEY_F8, /* F44 */ MOD_MASK_LOGO, "\033[19;6~", 0, 0, 0},
404 { XKB_KEY_F8, /* F56 */ MOD_MASK_ALT, "\033[19;3~", 0, 0, 0},
405 { XKB_KEY_F9, MOD_MASK_NONE, "\033[20~", 0, 0, 0},
406 { XKB_KEY_F9, /* F21 */ MOD_MASK_SHIFT, "\033[20;2~", 0, 0, 0},
407 { XKB_KEY_F9, /* F33 */ MOD_MASK_CTRL, "\033[20;5~", 0, 0, 0},
408 { XKB_KEY_F9, /* F45 */ MOD_MASK_LOGO, "\033[20;6~", 0, 0, 0},
409 { XKB_KEY_F9, /* F57 */ MOD_MASK_ALT, "\033[20;3~", 0, 0, 0},
410 { XKB_KEY_F10, MOD_MASK_NONE, "\033[21~", 0, 0, 0},
411 { XKB_KEY_F10, /* F22 */ MOD_MASK_SHIFT, "\033[21;2~", 0, 0, 0},
412 { XKB_KEY_F10, /* F34 */ MOD_MASK_CTRL, "\033[21;5~", 0, 0, 0},
413 { XKB_KEY_F10, /* F46 */ MOD_MASK_LOGO, "\033[21;6~", 0, 0, 0},
414 { XKB_KEY_F10, /* F58 */ MOD_MASK_ALT, "\033[21;3~", 0, 0, 0},
415 { XKB_KEY_F11, MOD_MASK_NONE, "\033[23~", 0, 0, 0},
416 { XKB_KEY_F11, /* F23 */ MOD_MASK_SHIFT, "\033[23;2~", 0, 0, 0},
417 { XKB_KEY_F11, /* F35 */ MOD_MASK_CTRL, "\033[23;5~", 0, 0, 0},
418 { XKB_KEY_F11, /* F47 */ MOD_MASK_LOGO, "\033[23;6~", 0, 0, 0},
419 { XKB_KEY_F11, /* F59 */ MOD_MASK_ALT, "\033[23;3~", 0, 0, 0},
420 { XKB_KEY_F12, MOD_MASK_NONE, "\033[24~", 0, 0, 0},
421 { XKB_KEY_F12, /* F24 */ MOD_MASK_SHIFT, "\033[24;2~", 0, 0, 0},
422 { XKB_KEY_F12, /* F36 */ MOD_MASK_CTRL, "\033[24;5~", 0, 0, 0},
423 { XKB_KEY_F12, /* F48 */ MOD_MASK_LOGO, "\033[24;6~", 0, 0, 0},
424 { XKB_KEY_F12, /* F60 */ MOD_MASK_ALT, "\033[24;3~", 0, 0, 0},
425 { XKB_KEY_F13, MOD_MASK_NONE, "\033[1;2P", 0, 0, 0},
426 { XKB_KEY_F14, MOD_MASK_NONE, "\033[1;2Q", 0, 0, 0},
427 { XKB_KEY_F15, MOD_MASK_NONE, "\033[1;2R", 0, 0, 0},
428 { XKB_KEY_F16, MOD_MASK_NONE, "\033[1;2S", 0, 0, 0},
429 { XKB_KEY_F17, MOD_MASK_NONE, "\033[15;2~", 0, 0, 0},
430 { XKB_KEY_F18, MOD_MASK_NONE, "\033[17;2~", 0, 0, 0},
431 { XKB_KEY_F19, MOD_MASK_NONE, "\033[18;2~", 0, 0, 0},
432 { XKB_KEY_F20, MOD_MASK_NONE, "\033[19;2~", 0, 0, 0},
433 { XKB_KEY_F21, MOD_MASK_NONE, "\033[20;2~", 0, 0, 0},
434 { XKB_KEY_F22, MOD_MASK_NONE, "\033[21;2~", 0, 0, 0},
435 { XKB_KEY_F23, MOD_MASK_NONE, "\033[23;2~", 0, 0, 0},
436 { XKB_KEY_F24, MOD_MASK_NONE, "\033[24;2~", 0, 0, 0},
437 { XKB_KEY_F25, MOD_MASK_NONE, "\033[1;5P", 0, 0, 0},
438 { XKB_KEY_F26, MOD_MASK_NONE, "\033[1;5Q", 0, 0, 0},
439 { XKB_KEY_F27, MOD_MASK_NONE, "\033[1;5R", 0, 0, 0},
440 { XKB_KEY_F28, MOD_MASK_NONE, "\033[1;5S", 0, 0, 0},
441 { XKB_KEY_F29, MOD_MASK_NONE, "\033[15;5~", 0, 0, 0},
442 { XKB_KEY_F30, MOD_MASK_NONE, "\033[17;5~", 0, 0, 0},
443 { XKB_KEY_F31, MOD_MASK_NONE, "\033[18;5~", 0, 0, 0},
444 { XKB_KEY_F32, MOD_MASK_NONE, "\033[19;5~", 0, 0, 0},
445 { XKB_KEY_F33, MOD_MASK_NONE, "\033[20;5~", 0, 0, 0},
446 { XKB_KEY_F34, MOD_MASK_NONE, "\033[21;5~", 0, 0, 0},
447 { XKB_KEY_F35, MOD_MASK_NONE, "\033[23;5~", 0, 0, 0},
448};
449
450/*
451 * Selection types' masks.
452 * Use the same masks as usual.
453 * Button1Mask is always unset, to make masks match between ButtonPress.
454 * ButtonRelease and MotionNotify.
455 * If no match is found, regular selection is used.
456 */
457static uint selmasks[] = {
458 [SEL_RECTANGULAR] = MOD_MASK_ALT,
459};
460
461/*
462 * Printable characters in ASCII, used to estimate the advance width
463 * of single wide characters.
464 */
465static char ascii_printable[] =
466 " !\"#$%&'()*+,-./0123456789:;<=>?"
467 "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
468 "`abcdefghijklmnopqrstuvwxyz{|}~";
469
470/*
471 * plumb_cmd is run on mouse button 3 click, with first NULL set to
472 * current selection and with cwd set to the cwd of the active shell
473 */
474static char *plumb_cmd[] = {"plumb", NULL, NULL};