keys.c - ledit - Text editor (WIP)
HTML git clone git://lumidify.org/ledit.git (fast, but not encrypted)
HTML git clone https://lumidify.org/ledit.git (encrypted, but very slow)
HTML git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/ledit.git (over tor)
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
keys.c (3571B)
---
1 #include <limits.h>
2
3 #include <X11/Xlib.h>
4 #include <X11/Xutil.h>
5 #include <X11/keysym.h>
6 #include <X11/XF86keysym.h>
7 #include <pango/pangoxft.h>
8 #include <X11/extensions/Xdbe.h>
9
10 #include "memory.h"
11 #include "common.h"
12 #include "txtbuf.h"
13 #include "window.h"
14 #include "keys.h"
15
16 /* FIXME: Does this break anything? */
17 /* FIXME: ShiftMask is currently masked away when the key contains text - is this correct? */
18 /* FIXME: The Mod*Masks can be remapped, so it isn't really clear what is what */
19 /* LockMask and Mod2Mask in particular are disabled (caps lock and numlock usually) */
20 static unsigned int importantmod = ShiftMask | ControlMask | Mod1Mask | Mod3Mask | Mod4Mask | Mod5Mask;
21
22 #define KEY_TEXT_INITIAL_SIZE 32
23 static char *key_text = NULL;
24 static size_t key_text_alloc = 0;
25
26 void
27 key_processing_cleanup(void) {
28 free(key_text);
29 }
30
31 int
32 match_key(unsigned int mask, unsigned int state)
33 {
34 return mask == XK_ANY_MOD || mask == (state & importantmod);
35 }
36
37 #ifdef X_HAVE_UTF8_STRING
38 #define LOOKUP_STRING_FUNC Xutf8LookupString
39 #else
40 #define LOOKUP_STRING_FUNC XmbLookupString
41 #endif
42
43 void
44 preprocess_key(
45 ledit_window *window, XKeyEvent *event, KeySym *sym_ret,
46 char **buf_ret, int *buf_len_ret) {
47 /*
48 * FIXME: I don't understand how key handling works with different keymaps.
49 * If, for instance, you run "setxkbmap pk" and then type "Ctrl+c", the
50 * keysym will be "0x1000686, Arabic_tcheh" and the appropriate string will
51 * be returned by XmbLookupString (tested also using xev).
52 * If, however, you run "setxkbmap -layout "us,pk" -option grp:shifts_toggle"
53 * and type "Ctrl+c" after switching to the pk layout, the keysym will just
54 * be "0x63, c" and XmbLookupString will return the control code sent by
55 * Ctrl+c (ascii 03). This means the handling is different depending on how
56 * the keymap is switched to, and I have no clue what the proper way to
57 * handle this would be, since the shortcuts are explicitly supposed to work
58 * properly in all language maps. My current solution is to just ignore the
59 * control key in the state so the text found by Xutf8LookupString is correct
60 * and the modifier mask can be checked separately. Please tell me if you
61 * know the proper way to do this.
62 */
63 /*
64 * Note on the above: I guess XKB tries to be smart and map the keys back to
65 * the first language when control is pressed and multiple languages are
66 * configured. This is completely useless for ledit, though, because most
67 * keys don't use control in normal mode, and it just messes with all the
68 * keys that do use control because ledit does its own mapping.
69 */
70 if (key_text_alloc == 0) {
71 key_text = ledit_malloc(KEY_TEXT_INITIAL_SIZE);
72 key_text_alloc = KEY_TEXT_INITIAL_SIZE;
73 }
74 event->state &= ~ControlMask;
75
76 int len = 0;
77 Status status;
78 if (window->xic && event->type == KeyPress) {
79 len = LOOKUP_STRING_FUNC(window->xic, event, key_text, key_text_alloc - 1, sym_ret, &status);
80 if (status == XBufferOverflow) {
81 key_text_alloc = ideal_array_size(key_text_alloc, len + 1);
82 key_text = ledit_realloc(key_text, key_text_alloc);
83 len = LOOKUP_STRING_FUNC(window->xic, event, key_text, key_text_alloc - 1, sym_ret, &status);
84 }
85 } else {
86 /* FIXME: anything equivalent to XBufferOverflow here? */
87 len = XLookupString(event, key_text, key_text_alloc - 1, sym_ret, NULL);
88 status = XLookupBoth;
89 }
90 *buf_len_ret = len >= (int)key_text_alloc ? (int)key_text_alloc - 1 : len;
91 key_text[*buf_len_ret] = '\0';
92 if (status != XLookupBoth && status != XLookupKeySym)
93 *sym_ret = NoSymbol;
94 *buf_ret = key_text;
95 }