experimental hackfix for non-existing problem ;-)
[k8sterm.git] / src / x11evtkbd.c
blobc32b564426fcd6c96277b981a1d4f2dc92729f46
1 ////////////////////////////////////////////////////////////////////////////////
2 // keyboard mapping
3 static const char *kmap (KeySym k, uint32_t state) {
4 const char *res = NULL;
5 //
6 state &= ~Mod2Mask; // numlock
7 for (int f = 0; f < keymap_used; ++f) {
8 uint32_t mask = keymap[f].mask;
9 //
10 if (keymap[f].key == k && ((mask == XK_NO_MOD && !state) || state == mask)) {
11 //fprintf(stderr, "kp: %d\n", K8T_ISSET(curterm, term, K8T_MODE_APPKEYPAD));
12 if (!K8T_ISSET(curterm, K8T_MODE_APPKEYPAD)) {
13 if (!keymap[f].kp) {
14 //fprintf(stderr, "nokp! %d %s\n", keymap[f].kp, keymap[f].str+1);
15 return keymap[f].str; // non-keypad hit
17 continue;
19 //fprintf(stderr, "kp! %d %s\n", keymap[f].kp, keymap[f].str+1);
20 if (keymap[f].kp) return keymap[f].str; // keypad hit
21 res = keymap[f].str; // kp mode, but non-kp mapping found
24 return res;
28 static const char *kbind (KeySym k, uint32_t state) {
29 state &= ~Mod2Mask; // numlock
30 for (int f = 0; f < keybinds_used; ++f) {
31 uint32_t mask = keybinds[f].mask;
33 if (keybinds[f].key == k && ((mask == XK_NO_MOD && !state) || state == mask)) return keybinds[f].str;
35 return NULL;
39 static KeySym do_keytrans (KeySym ks) {
40 for (int f = 0; f < keytrans_used; ++f) if (keytrans[f].src == ks) return keytrans[f].dst;
41 return ks;
45 static void cmdline_closequeryexec (K8Term *term, K8TCmdLine *cmdline, int cancelled) {
46 if (!cancelled) {
47 char *rep = cmdline->cmdline+cmdline->cmdreslen;
49 trimstr(rep);
50 if (!rep[0] || strchr("yt", tolower(rep[0])) != NULL) {
51 closeRequestComes = 2;
52 return;
55 closeRequestComes = 0;
59 static void eskdump (const char *kstr) {
60 if (kstr != NULL && kstr[0]) {
61 if (K8T_ISSET(curterm, K8T_MODE_APPKEYPAD)) fprintf(stderr, "<KP>");
62 while (*kstr) {
63 uint32_t c = (uint32_t)(*kstr++);
65 if (c != 32 && isprint(c)) fputc(c, stderr);
66 else if (c == '\n') fprintf(stderr, "(\\n)");
67 else if (c == '\r') fprintf(stderr, "(\\r)");
68 else if (c == 0x1b) fprintf(stderr, "(^[)");
69 else fprintf(stderr, "(%u)", c);
72 fputc('\n', stderr);
76 static void xevtcbkpress (XEvent *ev) {
77 XKeyEvent *e = &ev->xkey;
78 KeySym ksym = NoSymbol;
79 const char *kstr;
80 int len;
81 Status status;
82 char buf[32];
84 if (curterm == NULL) return;
86 if (!ptrBlanked && opt_ptrblank > 0) xblankPointer();
88 //if (len < 1) len = XmbLookupString(xw.xic, e, buf, sizeof(buf), &ksym, &status);
89 if ((len = Xutf8LookupString(xw.xic, e, buf, sizeof(buf), &ksym, &status)) > 0) buf[len] = 0;
90 // leave only known mods
91 e->state &= (Mod1Mask|Mod4Mask|ControlMask|ShiftMask);
92 #ifdef DUMP_KEYSYMS
94 const char *ksname = XKeysymToString(ksym);
96 fprintf(stderr, "utf(%d):[%s] (%s) 0x%08x\n", len, len>=0?buf:"<shit>", ksname, (unsigned int)e->state);
98 #endif
99 if ((kstr = kbind(ksym, e->state)) != NULL) {
100 // keybind found
101 executeCommands(kstr);
102 return;
105 if (K8T_DATA(curterm)->cmdline.cmdMode != K8T_CMDMODE_NONE) {
106 if (tcmdlProcessKeys(curterm, &K8T_DATA(curterm)->cmdline, do_keytrans(ksym), buf, len, e)) return;
109 if ((kstr = kmap(do_keytrans(ksym), e->state)) != NULL) {
110 if (kstr[0]) {
111 k8t_tmUnshowHistory(curterm);
112 if (curterm->dumpeskeys) {
113 if (!isprint(kstr[0]) || kstr[1]) {
114 fprintf(stderr, "KEY: ");
115 eskdump(kstr);
118 k8t_ttyWriteStr(curterm, kstr);
120 } else {
121 int meta = (e->state&Mod1Mask);
123 int shift = (e->state&ShiftMask);
124 int ctrl = (e->state&ControlMask);
127 if (K8T_DATA(curterm)->waitkeypress) {
128 switch (ksym) {
129 case XK_Return:
130 case XK_KP_Enter:
131 case XK_space:
132 case XK_Escape:
133 K8T_DATA(curterm)->waitkeypress = 0;
134 curterm->dead = 1;
135 break;
137 } else {
138 switch (ksym) {
139 case XK_Return:
140 k8t_tmUnshowHistory(curterm);
141 if (meta) {
142 k8t_ttyWriteStr(curterm, "\x1b\x0a");
143 } else {
144 if (K8T_ISSET(curterm, K8T_MODE_CRLF)) k8t_ttyWriteStr(curterm, "\r\n"); else k8t_ttyWriteStr(curterm, "\r");
146 break;
147 default:
148 if (!curterm->dead && len > 0) {
149 k8t_tmUnshowHistory(curterm);
150 if (meta && len == 1) k8t_ttyWriteStr(curterm, "\x1b");
151 k8t_ttyWrite(curterm, buf, len);
153 break;