1 #include "proto/virtual-keyboard-unstable-v1-client-protocol.h"
2 #include <linux/input-event-codes.h>
3 #include <stdio.h>
4 #include <sys/mman.h>
5 #include "keyboard.h"
6 #include "drw.h"
7 #include "os-compatibility.h"
8
9 #define MAX_LAYERS 25
10
11 /* lazy die macro */
12 #define die(...) \
13 fprintf(stderr, __VA_ARGS__); \
14 exit(1)
15
16 #ifndef KEYMAP
17 #error "make sure to define KEYMAP"
18 #endif
19 #include KEYMAP
20
21 void
kbd_switch_layout(struct kbd * kb,struct layout * l)22 kbd_switch_layout(struct kbd *kb, struct layout *l) {
23 kb->prevlayout = kb->layout;
24 kb->layout = l;
25 if (kb->debug)
26 fprintf(stderr, "Switching to layout %s)\n", kb->layout->name);
27 if ((!kb->prevlayout) ||
28 (strcmp(kb->prevlayout->keymap_name, kb->layout->keymap_name) != 0)) {
29 fprintf(stderr, "Switching to keymap %s\n", kb->layout->keymap_name);
30 create_and_upload_keymap(kb, kb->layout->keymap_name, 0, 0);
31 }
32 kbd_draw_layout(kb);
33 }
34
35 uint8_t
kbd_get_rows(struct layout * l)36 kbd_get_rows(struct layout *l) {
37 uint8_t rows = 0;
38 struct key *k = l->keys;
39 while (k->type != Last) {
40 if (k->type == EndRow) {
41 rows++;
42 }
43 k++;
44 }
45 return rows + 1;
46 }
47
48 void
kbd_init(struct kbd * kb,struct layout * layouts,char * layer_names_list)49 kbd_init(struct kbd *kb, struct layout *layouts, char *layer_names_list) {
50 char *s;
51 int i;
52 bool found;
53
54 fprintf(stderr, "Initializing keyboard\n");
55
56 kb->layouts = layouts;
57
58 for (i = 0; i < NumLayouts - 1; i++)
59 ;
60 fprintf(stderr, "Found %d layouts\n", i);
61
62 kb->layer_index = 0;
63
64 if (layer_names_list) {
65 uint8_t numlayers = 0;
66 kb->layers = malloc(MAX_LAYERS * sizeof(enum layout_id));
67 s = strtok(layer_names_list, ",");
68 while (s != NULL) {
69 if (numlayers + 1 == MAX_LAYERS) {
70 fprintf(stderr, "too many layers specified");
71 exit(3);
72 }
73 found = false;
74 for (i = 0; i < NumLayouts - 1; i++) {
75 if (kb->layouts[i].name && strcmp(kb->layouts[i].name, s) == 0) {
76 fprintf(stderr, "layer #%d = %s\n", numlayers + 1, s);
77 kb->layers[numlayers++] = i;
78 found = true;
79 break;
80 }
81 }
82 if (!found) {
83 fprintf(stderr, "No such layer: %s\n", s);
84 exit(3);
85 }
86 s = strtok(NULL, ",");
87 }
88 kb->layers[numlayers] = NumLayouts; // mark the end of the sequence
89 if (numlayers == 0) {
90 fprintf(stderr, "No layers defined\n");
91 exit(3);
92 }
93 }
94
95 i = 0;
96 enum layout_id lid = kb->layers[0];
97 while (lid != NumLayouts) {
98 lid = kb->layers[++i];
99 }
100 fprintf(stderr, "Found %d layers\n", i);
101
102 enum layout_id layer;
103 if (kb->landscape) {
104 layer = kb->landscape_layers[kb->layer_index];
105 } else {
106 layer = kb->layers[kb->layer_index];
107 }
108
109 kb->layout = &kb->layouts[layer];
110 kb->prevlayout = kb->layout;
111
112 /* upload keymap */
113 create_and_upload_keymap(kb, kb->layout->keymap_name, 0, 0);
114 }
115
116 void
kbd_init_layout(struct layout * l,uint32_t width,uint32_t height)117 kbd_init_layout(struct layout *l, uint32_t width, uint32_t height) {
118 uint32_t x = 0, y = 0;
119 uint8_t rows = kbd_get_rows(l);
120
121 l->keyheight = height / rows;
122
123 struct key *k = l->keys;
124 double rowlength = kbd_get_row_length(k);
125 while (k->type != Last) {
126 if (k->type == EndRow) {
127 y += l->keyheight;
128 x = 0;
129 rowlength = kbd_get_row_length(k + 1);
130 } else if (k->width > 0) {
131 k->x = x;
132 k->y = y;
133 k->w = ((double)width / rowlength) * k->width;
134 x += k->w;
135 }
136 k->h = l->keyheight;
137 k++;
138 }
139 }
140
141 double
kbd_get_row_length(struct key * k)142 kbd_get_row_length(struct key *k) {
143 double l = 0.0;
144 while ((k->type != Last) && (k->type != EndRow)) {
145 l += k->width;
146 k++;
147 }
148 return l;
149 }
150
151 struct key *
kbd_get_key(struct kbd * kb,uint32_t x,uint32_t y)152 kbd_get_key(struct kbd *kb, uint32_t x, uint32_t y) {
153 struct layout *l = kb->layout;
154 struct key *k = l->keys;
155 if (kb->debug)
156 fprintf(stderr, "get key: +%d+%d\n", x, y);
157 while (k->type != Last) {
158 if ((k->type != EndRow) && (k->type != Pad) && (k->type != Pad) &&
159 (x >= k->x) && (y >= k->y) && (x < k->x + k->w) && (y < k->y + k->h)) {
160 return k;
161 }
162 k++;
163 }
164 return NULL;
165 }
166
167 void
kbd_unpress_key(struct kbd * kb,uint32_t time)168 kbd_unpress_key(struct kbd *kb, uint32_t time) {
169 bool unlatch_shift = false;
170
171 if (kb->last_press) {
172 unlatch_shift = (kb->mods & Shift) == Shift;
173
174 if (unlatch_shift) {
175 kb->mods ^= Shift;
176 zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0);
177 }
178
179 if (kb->last_press->type == Copy) {
180 zwp_virtual_keyboard_v1_key(kb->vkbd, time, 127, // COMP key
181 WL_KEYBOARD_KEY_STATE_RELEASED);
182 } else {
183 zwp_virtual_keyboard_v1_key(kb->vkbd, time, kb->last_press->code,
184 WL_KEYBOARD_KEY_STATE_RELEASED);
185 }
186
187 if (kb->compose >= 2) {
188 kb->compose = 0;
189 kbd_switch_layout(kb, kb->prevlayout);
190 } else if (unlatch_shift) {
191 kbd_draw_layout(kb);
192 } else {
193 kbd_draw_key(kb, kb->last_press, Unpress);
194 }
195
196 kb->last_press = NULL;
197 }
198 }
199
kbd_release_key(struct kbd * kb,uint32_t time)200 void kbd_release_key(struct kbd *kb, uint32_t time) {
201 kbd_unpress_key(kb, time);
202 if (kb->print_intersect && kb->last_swipe) {
203 printf("\n");
204 // Important so autocompleted words get typed in time
205 fflush(stdout);
206 kbd_draw_layout(kb);
207 kb->last_swipe = NULL;
208 }
209 }
210
kbd_motion_key(struct kbd * kb,uint32_t time,uint32_t x,uint32_t y)211 void kbd_motion_key(struct kbd *kb, uint32_t time, uint32_t x, uint32_t y) {
212 // Output intersecting keys
213 // (for external 'swiping'-based accelerators).
214 if (kb->print_intersect) {
215 if (kb->last_press) {
216 kbd_unpress_key(kb, time);
217 // Redraw last press as a swipe.
218 kbd_draw_key(kb, kb->last_swipe, Swipe);
219 }
220 struct key *intersect_key;
221 intersect_key = kbd_get_key(kb, x, y);
222 if (intersect_key &&
223 (! kb->last_swipe || intersect_key->label != kb->last_swipe->label)) {
224 kbd_print_key_stdout(kb, intersect_key);
225 kb->last_swipe = intersect_key;
226 kbd_draw_key(kb, kb->last_swipe, Swipe);
227 }
228 } else {
229 kbd_unpress_key(kb, time);
230 }
231 }
232
233 void
kbd_press_key(struct kbd * kb,struct key * k,uint32_t time)234 kbd_press_key(struct kbd *kb, struct key *k, uint32_t time) {
235 if ((kb->compose == 1) && (k->type != Compose) && (k->type != Mod) &&
236 (k->layout)) {
237 kb->compose++;
238 if (kb->debug)
239 fprintf(stderr, "showing compose %d\n", kb->compose);
240 kbd_switch_layout(kb, k->layout);
241 return;
242 }
243
244 switch (k->type) {
245 case Code:
246 if (k->code_mod) {
247 if (k->reset_mod) {
248 zwp_virtual_keyboard_v1_modifiers(kb->vkbd, k->code_mod, 0, 0, 0);
249 } else {
250 zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods ^ k->code_mod, 0,
251 0, 0);
252 }
253 } else {
254 zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0);
255 }
256 kb->last_swipe = kb->last_press = k;
257 kbd_draw_key(kb, k, Press);
258 zwp_virtual_keyboard_v1_key(kb->vkbd, time, kb->last_press->code,
259 WL_KEYBOARD_KEY_STATE_PRESSED);
260 if (kb->print || kb->print_intersect)
261 kbd_print_key_stdout(kb, k);
262 if (kb->compose) {
263 if (kb->debug)
264 fprintf(stderr, "pressing composed key\n");
265 kb->compose++;
266 }
267 break;
268 case Mod:
269 kb->mods ^= k->code;
270 if (k->code == Shift) {
271 kbd_draw_layout(kb);
272 }
273 if (kb->mods & k->code) {
274 kbd_draw_key(kb, k, Press);
275 } else {
276 kbd_draw_key(kb, k, Unpress);
277 }
278 zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0);
279 break;
280 case Layout:
281 // switch to the layout determined by the key
282 kbd_switch_layout(kb, k->layout);
283 break;
284 case Compose:
285 // switch to the associated layout determined by the *next* keypress
286 if (kb->compose == 0) {
287 kb->compose = 1;
288 } else {
289 kb->compose = 0;
290 }
291 if ((bool)kb->compose) {
292 kbd_draw_key(kb, k, Press);
293 } else {
294 kbd_draw_key(kb, k, Unpress);
295 }
296 break;
297 case NextLayer:
298 // switch to the next layout in the layer sequence
299 kb->layer_index++;
300 enum layout_id layer;
301 if (kb->landscape) {
302 layer = kb->landscape_layers[kb->layer_index];
303 } else {
304 layer = kb->layers[kb->layer_index];
305 }
306 if (layer == NumLayouts) {
307 kb->layer_index = 0;
308 if (kb->landscape) {
309 layer = kb->landscape_layers[kb->layer_index];
310 } else {
311 layer = kb->layers[kb->layer_index];
312 }
313 }
314 kbd_switch_layout(kb, &kb->layouts[layer]);
315 break;
316 case BackLayer:
317 // switch to the previously active layout
318 if (kb->prevlayout)
319 kbd_switch_layout(kb, kb->prevlayout);
320 break;
321 case Copy:
322 // copy code as unicode chr by setting a temporary keymap
323 kb->last_swipe = kb->last_press = k;
324 kbd_draw_key(kb, k, Press);
325 if (kb->debug)
326 fprintf(stderr, "pressing copy key\n");
327 create_and_upload_keymap(kb, kb->layout->keymap_name, k->code, k->code_mod);
328 zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0);
329 zwp_virtual_keyboard_v1_key(kb->vkbd, time, 127, // COMP key
330 WL_KEYBOARD_KEY_STATE_PRESSED);
331 if (kb->print || kb->print_intersect)
332 kbd_print_key_stdout(kb, k);
333 break;
334 default:
335 break;
336 }
337 }
338
339 void
kbd_print_key_stdout(struct kbd * kb,struct key * k)340 kbd_print_key_stdout(struct kbd *kb, struct key *k) {
341 /* printed keys may slightly differ from the actual output
342 * we generally print what is on the key LABEL and only support the normal
343 * and shift layers. Other modifiers produce no output (Ctrl,Alt)
344 * */
345
346 bool handled = true;
347 if (k->type == Code) {
348 switch (k->code) {
349 case KEY_SPACE:
350 printf(" ");
351 break;
352 case KEY_ENTER:
353 printf("\n");
354 break;
355 case KEY_BACKSPACE:
356 printf("\b");
357 break;
358 case KEY_TAB:
359 printf("\t");
360 break;
361 default:
362 handled = false;
363 break;
364 }
365 } else if (k->type != Copy) {
366 return;
367 }
368
369 if (!handled) {
370 if ((kb->mods & Shift) || (kb->mods & CapsLock))
371 printf("%s", k->shift_label);
372 else if (!(kb->mods & Ctrl) && !(kb->mods & Alt) && !(kb->mods & Super))
373 printf("%s", k->label);
374 }
375 fflush(stdout);
376 }
377
378 void
kbd_draw_key(struct kbd * kb,struct key * k,enum key_draw_type type)379 kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type) {
380 struct drwsurf *d = kb->surf;
381 const char *label = (kb->mods & Shift) ? k->shift_label : k->label;
382 if (kb->debug)
383 fprintf(stderr, "Draw key +%d+%d %dx%d -> %s\n", k->x, k->y, k->w, k->h,
384 label);
385 struct clr_scheme *scheme = (k->scheme == 0) ? &(kb->scheme) : &(kb->scheme1);
386 switch (type) {
387 case Unpress:
388 draw_inset(d, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, scheme->fg);
389 break;
390 case Press:
391 draw_inset(d, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, scheme->high);
392 break;
393 case Swipe:
394 draw_over_inset(d, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, scheme->swipe);
395 break;
396 }
397 drw_draw_text(d, scheme->text, k->x, k->y, k->w, k->h, label);
398 }
399
400 void
kbd_draw_layout(struct kbd * kb)401 kbd_draw_layout(struct kbd *kb) {
402 struct drwsurf *d = kb->surf;
403 struct key *next_key = kb->layout->keys;
404 if (kb->debug)
405 fprintf(stderr, "Draw layout");
406
407 drw_fill_rectangle(d, kb->scheme.bg, 0, 0, kb->w, kb->h);
408
409 while (next_key->type != Last) {
410 if ((next_key->type == Pad) || (next_key->type == EndRow)) {
411 next_key++;
412 continue;
413 }
414 if (next_key->type == Mod && kb->mods & next_key->code) {
415 kbd_draw_key(kb, next_key, Press);
416 } else {
417 kbd_draw_key(kb, next_key, Unpress);
418 }
419 next_key++;
420 }
421 }
422
423 void
kbd_resize(struct kbd * kb,struct layout * layouts,uint8_t layoutcount)424 kbd_resize(struct kbd *kb, struct layout *layouts, uint8_t layoutcount) {
425 struct drwsurf *d = kb->surf;
426
427 fprintf(stderr, "Resize %dx%d %d, %d layouts\n", kb->w, kb->h, kb->s,
428 layoutcount);
429
430 drwsurf_resize(d, kb->w, kb->h, kb->s);
431 for (int i = 0; i < layoutcount; i++) {
432 kbd_init_layout(&layouts[i], kb->w, kb->h);
433 }
434 kbd_draw_layout(kb);
435 }
436
437 void
draw_inset(struct drwsurf * ds,uint32_t x,uint32_t y,uint32_t width,uint32_t height,uint32_t border,Color color)438 draw_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width,
439 uint32_t height, uint32_t border, Color color) {
440 drw_fill_rectangle(ds, color, x + border, y + border, width - border,
441 height - border);
442 }
443 void
draw_over_inset(struct drwsurf * ds,uint32_t x,uint32_t y,uint32_t width,uint32_t height,uint32_t border,Color color)444 draw_over_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width,
445 uint32_t height, uint32_t border, Color color) {
446 drw_over_rectangle(ds, color, x + border, y + border, width - border,
447 height - border);
448 }
449
450 void
create_and_upload_keymap(struct kbd * kb,const char * name,uint32_t comp_unichr,uint32_t comp_shift_unichr)451 create_and_upload_keymap(struct kbd *kb, const char *name, uint32_t comp_unichr,
452 uint32_t comp_shift_unichr) {
453 int keymap_index = -1;
454 for (int i = 0; i < NUMKEYMAPS; i++) {
455 if (!strcmp(keymap_names[i], name)) {
456 keymap_index = i;
457 }
458 }
459 if (keymap_index == -1) {
460 fprintf(stderr, "No such keymap defined: %s\n", name);
461 exit(9);
462 }
463 const char *keymap_template = keymaps[keymap_index];
464 const size_t keymap_size = strlen(keymap_template) + 64;
465 char *keymap_str = malloc(keymap_size);
466 sprintf(keymap_str, keymap_template, comp_unichr, comp_shift_unichr);
467 int keymap_fd = os_create_anonymous_file(keymap_size);
468 if (keymap_fd < 0) {
469 die("could not create keymap fd\n");
470 }
471 void *ptr =
472 mmap(NULL, keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, keymap_fd, 0);
473 if (ptr == (void *)-1) {
474 die("could not map keymap data\n");
475 }
476 if (kb->vkbd == NULL) {
477 die("kb.vkbd = NULL\n");
478 }
479 strcpy(ptr, keymap_str);
480 zwp_virtual_keyboard_v1_keymap(kb->vkbd, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
481 keymap_fd, keymap_size);
482 free((void *)keymap_str);
483 }
484