]> git.gir.st - tmk_keyboard.git/blob - common/action.c
Refactor struct keyevent_t.
[tmk_keyboard.git] / common / action.c
1 #include "host.h"
2 #include "timer.h"
3 #include "keymap.h"
4 #include "keycode.h"
5 #include "keyboard.h"
6 #include "mousekey.h"
7 #include "command.h"
8 #include "util.h"
9 #include "debug.h"
10 #include "action.h"
11
12
13 static void process(keyevent_t event);
14 static void register_code(uint8_t code);
15 static void unregister_code(uint8_t code);
16 static void add_mods(uint8_t mods);
17 static void del_mods(uint8_t mods);
18 static void set_mods(uint8_t mods);
19 static void clear_keyboard(void);
20 static void clear_keyboard_but_mods(void);
21 static bool sending_anykey(void);
22 static void layer_switch(uint8_t new_layer);
23
24
25 /* tap */
26 #define TAP_TIME 200
27 static keyevent_t last_event = {};
28 static uint8_t tap_count = 0;
29
30 /* layer */
31 uint8_t default_layer = 0;
32 uint8_t current_layer = 0;
33 static keyrecord_t tapping_key = {};
34 // time 0 means no event.
35 #define IS_TAPPING (tapping_key.event.time != 0)
36 /* TODO:
37 #define IS_TAPPING_KEY(key) (tapping_key.event.time != 0 && KEYEQ(tapping_key.event.key, key))
38 */
39
40 /* waiting keys buffer */
41 #define WAITING_KEYS_BUFFER 3
42 static keyrecord_t waiting_keys[WAITING_KEYS_BUFFER] = {};
43 // TODO: double buffer?
44 static keyrecord_t waiting_keys0[WAITING_KEYS_BUFFER] = {};
45 static keyrecord_t waiting_keys1[WAITING_KEYS_BUFFER] = {};
46 static uint8_t waiting_keys_head = 0;
47 static bool waiting_keys_enqueue(keyevent_t event)
48 {
49 debug("waiting_keys["); debug_dec(waiting_keys_head); debug("] = ");
50 debug_hex16(event.key.raw); debug("\n");
51 if (waiting_keys_head < WAITING_KEYS_BUFFER) {
52 waiting_keys[waiting_keys_head++] = (keyrecord_t){ .event = event,
53 .mods = host_get_mods() };
54 } else {
55 return true;
56 }
57 }
58 static void waiting_keys_clear(void)
59 {
60 waiting_keys_head = 0;
61 }
62 static bool waiting_keys_has(key_t key)
63 {
64 for (uint8_t i = 0; i < waiting_keys_head; i++) {
65 if KEYEQ(key, waiting_keys[i].event.key) return true;
66 }
67 return false;
68 }
69 static void waiting_keys_process_in_current_layer(void)
70 {
71 // TODO: in case of including layer key in waiting keys
72 for (uint8_t i = 0; i < waiting_keys_head; i++) {
73 debug("waiting_keys_process_in_current_layer["); debug_dec(i); debug("]\n");
74 process(waiting_keys[i].event);
75 }
76 waiting_keys_clear();
77 }
78
79
80 void action_exec(keyevent_t event)
81 {
82 if (!IS_NOEVENT(event)) {
83 debug("event: "); debug_hex16(event.key.raw);
84 debug("[");
85 if (event.pressed) debug("down"); else debug("up");
86 debug("]\n");
87 }
88 if (IS_TAPPING) {
89 /* when tap time elapses or waiting key is released */
90 if ((timer_elapsed(tapping_key.event.time) > TAP_TIME) ||
91 (!event.pressed && waiting_keys_has(event.key))) {
92
93 // TODO process tapping_key: layer swich, modifier, ...
94 // action is needed?
95 debug("notap: process tapping_key.\n");
96 process(tapping_key.event);
97
98 /* Process waiting keys in new layer */
99 waiting_keys_process_in_current_layer();
100 }
101 /* when tapping key is released within tap time */
102 else if (!event.pressed && KEYEQ(event.key, tapping_key.event.key)) {
103 /* tap key down */
104 debug("tap("); debug_hex8(tap_count); debug(")[tapping_key](register): "); debug_hex8(tapping_key.action.layer.code); debug("\n");
105 register_code(tapping_key.action.layer.code);
106 tapping_key = (keyrecord_t){};
107
108 /* process waiting keys */
109 waiting_keys_process_in_current_layer();
110 }
111 }
112
113 // not real event. event just to handle time out of tapping key.
114 if (IS_NOEVENT(event)) {
115 return;
116 }
117
118 /* count up tap when key is up */
119 // key: d u d u d
120 // tap: 0 1 1 2 2
121 // key: u d u d u
122 // tap: 0 0 1 1 2
123 if (KEYEQ(event.key, last_event.key) && timer_elapsed(last_event.time) <= TAP_TIME) {
124 if (!event.pressed) tap_count++;
125 } else {
126 tap_count = 0;
127 }
128
129 /* store key events while tapping */
130 if (IS_TAPPING) {
131 // TODO: action is needed?
132 waiting_keys_enqueue(event);
133 } else {
134 process(event);
135 }
136
137 /* last event */
138 last_event = event;
139 }
140
141
142 static void process(keyevent_t event)
143 {
144 action_t action = keymap_get_action(current_layer, event.key.pos.row, event.key.pos.col);
145 debug("action: "); debug_hex16(action.code);
146 if (event.pressed) debug("[down]\n"); else debug("[up]\n");
147
148 switch (action.kind.id) {
149 /* Key and Mods */
150 case ACT_LMODS:
151 // |pressed |released
152 // --------------+---------------------------------+------------
153 // key |down(key) |up(key)
154 // mods |add(mods) |del(mods)
155 // key with mods |add(mods), down(key), unset(mods)|up(key)
156 if (event.pressed) {
157 uint8_t tmp_mods = host_get_mods();
158 if (action.key.mods) {
159 host_add_mods(action.key.mods);
160 host_send_keyboard_report();
161 }
162 register_code(action.key.code);
163 if (action.key.mods && action.key.code) {
164 host_set_mods(tmp_mods);
165 host_send_keyboard_report();
166 }
167 } else {
168 if (action.key.mods && !action.key.code) {
169 host_del_mods(action.key.mods);
170 host_send_keyboard_report();
171 }
172 unregister_code(action.key.code);
173 }
174 break;
175 case ACT_RMODS:
176 // |pressed |released
177 // --------------+---------------------------------+------------
178 // key |down(key) |up(key)
179 // mods |add(mods) |del(mods)
180 // key with mods |add(mods), down(key), unset(mods)|up(key)
181 if (event.pressed) {
182 uint8_t tmp_mods = host_get_mods();
183 if (action.key.mods) {
184 host_add_mods(action.key.mods<<4);
185 host_send_keyboard_report();
186 }
187 register_code(action.key.code);
188 if (action.key.mods && action.key.code) {
189 host_set_mods(tmp_mods);
190 host_send_keyboard_report();
191 }
192 } else {
193 if (action.key.mods && !action.key.code) {
194 host_del_mods(action.key.mods<<4);
195 host_send_keyboard_report();
196 }
197 unregister_code(action.key.code);
198 }
199 break;
200 case ACT_LMODS_TAP:
201 if (event.pressed) {
202 if (tap_count == 0) {
203 if (host_has_anykey()) {
204 // This key is a modifier essentially.
205 // Prioritize mods when key jam or rollover
206 add_mods(action.key.mods);
207 } else {
208 if (IS_TAPPING && KEYEQ(tapping_key.event.key, event.key)) {
209 // no tapping
210 add_mods(action.key.mods);
211 tapping_key = (keyrecord_t){};
212 } else {
213 debug("tapping lmods("); debug_hex8(action.key.mods); debug(")\n");
214 tapping_key = (keyrecord_t){
215 .event = event,
216 .action = action,
217 .mods = host_get_mods()
218 };
219 }
220 }
221 } else {
222 // pressed after tapping
223 debug("tap("); debug_hex(tap_count); debug(")[lmods](register): "); debug_hex8(action.key.code); debug("\n");
224 register_code(action.key.code);
225 }
226 } else {
227 if (tap_count == 0) {
228 debug("tap(00)[lmods](del_mods): "); debug_hex8(action.key.mods); debug("\n");
229 del_mods(action.key.mods);
230 } else if (tap_count == 1) {
231 debug("tap(01)[lmods](del_mods/unregister): "); debug_hex8(action.key.mods); debug(" "); debug_hex8(action.key.code); debug("\n");
232 del_mods(action.key.mods);
233 unregister_code(action.key.code);
234 } else {
235 debug("tap("); debug_hex(tap_count); debug(")[lmods](unregister): "); debug_hex8(action.key.code); debug("\n");
236 unregister_code(action.key.code);
237 }
238 }
239 break;
240 case ACT_RMODS_TAP:
241 if (event.pressed) {
242 if (tap_count == 0) {
243 if (host_has_anykey()) {
244 // This key is a modifier essentially.
245 // Prioritize mods when key jam or rollover
246 add_mods(action.key.mods<<4);
247 } else {
248 if (IS_TAPPING && KEYEQ(tapping_key.event.key, event.key)) {
249 // no tapping
250 add_mods(action.key.mods<<4);
251 tapping_key = (keyrecord_t){};
252 } else {
253 debug("tapping rmods("); debug_hex8(action.key.mods); debug(")\n");
254 tapping_key = (keyrecord_t){
255 .event = event,
256 .action = action,
257 .mods = host_get_mods()
258 };
259 }
260 }
261 } else {
262 // pressed after tapping
263 debug("tap("); debug_hex(tap_count); debug(")[rmods](register): "); debug_hex8(action.key.code); debug("\n");
264 register_code(action.key.code);
265 }
266 } else {
267 if (tap_count == 0) {
268 debug("tap(00)[rmods](del_mods): "); debug_hex8(action.key.mods); debug("\n");
269 del_mods(action.key.mods<<4);
270 } else if (tap_count == 1) {
271 debug("tap(01)[rmods](del_mods/unregister): "); debug_hex8(action.key.mods); debug(" "); debug_hex8(action.key.code); debug("\n");
272 del_mods(action.key.mods<<4);
273 unregister_code(action.key.code);
274 } else {
275 debug("tap("); debug_hex(tap_count); debug(")[rmods](unregister): "); debug_hex8(action.key.code); debug("\n");
276 unregister_code(action.key.code);
277 }
278 }
279 break;
280
281 /* other HID usage */
282 case ACT_USAGE:
283 #ifdef EXTRAKEY_ENABLE
284 switch (action.usage.page) {
285 case ACTION_USAGE_PAGE_SYSTEM:
286 if (event.pressed) {
287 host_system_send(action.usage.code);
288 } else {
289 host_system_send(0);
290 }
291 break;
292 case ACTION_USAGE_PAGE_CONSUMER:
293 if (event.pressed) {
294 host_consumer_send(action.usage.code);
295 } else {
296 host_consumer_send(0);
297 }
298 break;
299 }
300 #endif
301 break;
302
303 /* Mouse key */
304 case ACT_MOUSEKEY:
305 #ifdef MOUSEKEY_ENABLE
306 if (event.pressed) {
307 mousekey_on(action.key.code);
308 mousekey_send();
309 } else {
310 mousekey_off(action.key.code);
311 mousekey_send();
312 }
313 #endif
314 break;
315
316 /* Layer key */
317 case ACT_LAYER_PRESSED:
318 // layer action when pressed
319 switch (action.layer.code) {
320 case 0x00:
321 if (event.pressed) {
322 layer_switch(action.layer.opt);
323 }
324 break;
325 case 0xF0:
326 // TODO: tap toggle
327 break;
328 case 0xFF:
329 if (event.pressed) {
330 default_layer = action.layer.opt;
331 layer_switch(default_layer);
332 }
333 break;
334 default:
335 // with tap key
336 if (event.pressed) {
337 if (tap_count == 0) {
338 if (host_has_anykey()) {
339 // This key is a normal key than a leyar key essentially.
340 // Prioritize 'tap key' when key jam or rollover
341 register_code(action.layer.code);
342 } else {
343 if (IS_TAPPING && KEYEQ(tapping_key.event.key, event.key)) {
344 layer_switch(action.layer.opt);
345 tapping_key = (keyrecord_t){};
346 } else {
347 debug("tapping layer("); debug_hex8(action.layer.opt); debug(")\n");
348 tapping_key = (keyrecord_t){
349 .event = event,
350 .action = action,
351 .mods = host_get_mods()
352 };
353 }
354 }
355 } else if (tap_count > 0) {
356 // pressed after tapping
357 debug("tap[layer](register): "); debug_hex(tap_count); debug("\n");
358 register_code(action.layer.code);
359 }
360 } else {
361 // released after tapping
362 debug("tap[layer](unregister): "); debug_hex(tap_count); debug("\n");
363 unregister_code(action.layer.code);
364 }
365 break;
366 }
367 break;
368 case ACT_LAYER_RELEASED:
369 switch (action.layer.code) {
370 case 0x00:
371 if (!event.pressed) {
372 layer_switch(action.layer.opt);
373 }
374 break;
375 case 0xF0:
376 // Ignored. LAYER_RELEASED with tap toggle is invalid action.
377 break;
378 case 0xFF:
379 if (!event.pressed) {
380 default_layer = action.layer.opt;
381 layer_switch(default_layer);
382 }
383 break;
384 default:
385 // Ignored. LAYER_RELEASED with tap key is invalid action.
386 break;
387 }
388 break;
389 case ACT_LAYER_BIT:
390 switch (action.layer.code) {
391 case 0x00:
392 if (event.pressed) {
393 layer_switch(current_layer | action.layer.opt);
394 } else {
395 layer_switch(current_layer & ~action.layer.opt);
396 }
397 break;
398 case 0xF0:
399 // TODO: tap toggle
400 break;
401 case 0xFF:
402 // change default layer
403 if (event.pressed) {
404 default_layer = current_layer | action.layer.opt;
405 layer_switch(default_layer);
406 } else {
407 default_layer = current_layer & ~action.layer.opt;
408 layer_switch(default_layer);
409 }
410 break;
411 default:
412 // TODO: see ACT_LAYER_PRESSED code
413 // with tap key
414 if (event.pressed) {
415 if (tap_count == 0) {
416 if (host_has_anykey()) {
417 register_code(action.layer.code);
418 } else {
419 tapping_key = (keyrecord_t){
420 .event = event,
421 .action = action,
422 .mods = keyboard_report->mods
423 };
424 }
425 } else if (tap_count > 0) {
426 debug("tap[layer_bit](register): "); debug_hex(tap_count); debug("\n");
427 register_code(action.layer.code);
428 }
429 } else {
430 if (tap_count == 0) {
431 // no tap
432 layer_switch(current_layer & ~action.layer.opt);
433 } else if (tap_count == 1) {
434 // tap
435 register_code(action.layer.code);
436 }
437 unregister_code(action.layer.code);
438 }
439 break;
440 }
441 case ACT_LAYER_EXT:
442 switch (action.layer.opt) {
443 case 0x00:
444 // set default layer when pressed
445 switch (action.layer.code) {
446 case 0x00:
447 if (event.pressed) {
448 layer_switch(default_layer);
449 }
450 break;
451 case 0xF0:
452 // TODO: tap toggle
453 break;
454 case 0xFF:
455 if (event.pressed) {
456 default_layer = current_layer;
457 layer_switch(default_layer);
458 }
459 break;
460 default:
461 // TODO: tap key
462 break;
463 }
464 break;
465 case 0x01:
466 // set default layer when released
467 switch (action.layer.code) {
468 case 0x00:
469 if (!event.pressed) {
470 layer_switch(default_layer);
471 }
472 break;
473 case 0xFF:
474 if (!event.pressed) {
475 default_layer = current_layer;
476 layer_switch(default_layer);
477 }
478 break;
479 case 0xF0:
480 default:
481 // Ignore tap.
482 if (!event.pressed) {
483 layer_switch(default_layer);
484 }
485 break;
486 }
487 break;
488 }
489 break;
490
491 /* Extentions */
492 case ACT_MACRO:
493 case ACT_COMMAND:
494 case ACT_FUNCTION:
495 default:
496 break;
497 }
498 }
499
500 static void register_code(uint8_t code)
501 {
502 if (code == KC_NO) {
503 return;
504 }
505 else if IS_KEY(code) {
506 // TODO: should push command_proc out of this block?
507 if (!command_proc(code)) {
508 host_add_key(code);
509 host_send_keyboard_report();
510 }
511 }
512 else if IS_MOD(code) {
513 host_add_mods(MOD_BIT(code));
514 host_send_keyboard_report();
515 }
516 }
517
518 static void unregister_code(uint8_t code)
519 {
520 if IS_KEY(code) {
521 host_del_key(code);
522 host_send_keyboard_report();
523 }
524 else if IS_MOD(code) {
525 host_del_mods(MOD_BIT(code));
526 host_send_keyboard_report();
527 }
528 }
529
530 static void add_mods(uint8_t mods)
531 {
532 if (mods) {
533 host_add_mods(mods);
534 host_send_keyboard_report();
535 }
536 }
537
538 static void del_mods(uint8_t mods)
539 {
540 if (mods) {
541 host_del_mods(mods);
542 host_send_keyboard_report();
543 }
544 }
545
546 static void set_mods(uint8_t mods)
547 {
548 host_set_mods(mods);
549 host_send_keyboard_report();
550 }
551
552 static void clear_keyboard(void)
553 {
554 host_clear_mods();
555 clear_keyboard_but_mods();
556 }
557
558 static void clear_keyboard_but_mods(void)
559 {
560 host_clear_keys();
561 host_send_keyboard_report();
562 #ifdef MOUSEKEY_ENABLE
563 mousekey_clear();
564 mousekey_send();
565 #endif
566 #ifdef EXTRAKEY_ENABLE
567 host_system_send(0);
568 host_consumer_send(0);
569 #endif
570 }
571
572 static bool sending_anykey(void)
573 {
574 return (host_has_anykey() || host_mouse_in_use() ||
575 host_last_sysytem_report() || host_last_consumer_report());
576 }
577
578 static void layer_switch(uint8_t new_layer)
579 {
580 if (current_layer != new_layer) {
581 debug("Layer Switch: "); debug_hex(current_layer);
582 debug(" -> "); debug_hex(new_layer); debug("\n");
583
584 current_layer = new_layer;
585 clear_keyboard_but_mods(); // To avoid stuck keys
586 // TODO: update mods with full scan of matrix? if modifier changes between layers
587 }
588 }
Imprint / Impressum