]> git.gir.st - tmk_keyboard.git/blob - common/action.c
New tapping logic.
[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(keyrecord_t *record);
14
15 void test_func(keyevent_t event, uint8_t opt)
16 {
17 if (event.pressed) {
18 debug("test_func:pressed: "); debug_hex(opt); debug("\n");
19 } else {
20 debug("test_func:released: "); debug_hex(opt); debug("\n");
21 }
22 }
23
24 /* layer */
25 uint8_t default_layer = 0;
26 uint8_t current_layer = 0;
27
28 /* tap term(ms) */
29 #define TAP_TERM 200
30
31 /* This counts up when tap occurs */
32 uint8_t tap_count = 0;
33 keyevent_t tapping_event = {};
34 keyrecord_t tapping_key = {};
35
36 /* TAPPING: This indicates that whether tap or not is not decided yet. */
37 // NOTE: keyevent_t.time 0 means no event.
38 #define IS_TAPPING() (tapping_key.event.time != 0)
39 #define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed)
40 #define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed)
41 #define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k)))
42 #define WITHIN_TAP_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAP_TERM)
43
44 /* waiting keys buffer */
45 #define WAITING_BUFFER_SIZE 8
46 static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {};
47 /* point to empty cell to enq */
48 static uint8_t waiting_buffer_head = 0;
49 /* point to the oldest data cell to deq */
50 static uint8_t waiting_buffer_tail = 0;
51
52 static bool waiting_buffer_enq(keyrecord_t record)
53 {
54 if (IS_NOEVENT(record.event)) {
55 return true;
56 }
57
58 if ((waiting_buffer_head + 1) % WAITING_BUFFER_SIZE == waiting_buffer_tail) {
59 debug("waiting_buffer_enq: Over flow.\n");
60 return false;
61 }
62
63 debug("waiting_buffer_enq["); debug_dec(waiting_buffer_head); debug("] = ");
64 debug_hex16(record.event.key.raw); debug("\n");
65
66 waiting_buffer[waiting_buffer_head] = record;
67 waiting_buffer_head = (waiting_buffer_head + 1) % WAITING_BUFFER_SIZE;
68 return true;
69 }
70 static keyrecord_t waiting_buffer_deq(void)
71 {
72 if (waiting_buffer_head == waiting_buffer_tail) {
73 return (keyrecord_t){};
74 }
75 uint8_t last_tail = waiting_buffer_tail;
76 waiting_buffer_tail = waiting_buffer_tail + 1 % WAITING_BUFFER_SIZE;
77 return waiting_buffer[last_tail];
78 }
79 static bool waiting_buffer_is_empty(void)
80 {
81 return (waiting_buffer_head == waiting_buffer_tail);
82 }
83 static void waiting_buffer_clear(void)
84 {
85 waiting_buffer_head = 0;
86 waiting_buffer_tail = 0;
87 }
88 static bool waiting_buffer_typed(keyevent_t event)
89 {
90 for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
91 if (KEYEQ(event.key, waiting_buffer[i].event.key) && event.pressed != waiting_buffer[i].event.pressed) {
92 return true;
93 }
94 }
95 return false;
96 }
97 static bool waiting_buffer_has_anykey_pressed(void)
98 {
99 for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
100 if (waiting_buffer[i].event.pressed) return true;
101 }
102 return false;
103 }
104 static void waiting_buffer_process(void)
105 {
106 }
107
108
109 /*
110 * Rule to judge tap:
111 * Tap key is typed(pressed and released) within TAP_TERM
112 * without interfaring by typing other key.
113 */
114 /* return true when key event is processed. */
115 static bool process_tap(keyrecord_t *keyp)
116 {
117 keyevent_t event = keyp->event;
118
119 // if tapping
120 if (IS_TAPPING_PRESSED()) {
121 if (WITHIN_TAP_TERM(event)) {
122 if (tapping_key.tap_count == 0) {
123 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
124 // first tap!
125 debug("Tapping: First tap.\n");
126 tapping_key.tap_count = 1;
127 process(&tapping_key);
128
129 // enqueue
130 keyp->tap_count = tapping_key.tap_count;
131 return false;
132 } else if (!event.pressed && waiting_buffer_typed(event)) {
133 // other key typed. not tap.
134 debug("Tapping: End(No tap. Interfered by typing key).\n");
135 process(&tapping_key);
136 tapping_key = (keyrecord_t){};
137
138 // enqueue
139 return false;
140 } else {
141 // other key events shall be stored till tapping state settles.
142 return false;
143 }
144 } else {
145 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
146 keyp->tap_count = tapping_key.tap_count;
147 debug("Tapping: tap release("); debug_dec(keyp->tap_count); debug(")\n");
148 tapping_key = *keyp;
149 return false;
150 }
151 else if (is_tap_key(keyp->event.key) && event.pressed) {
152 debug("Tapping: Start with forcing to release last tap.\n");
153 process(&(keyrecord_t){
154 .tap_count = tapping_key.tap_count,
155 .event.key = tapping_key.event.key,
156 .event.time = event.time,
157 .event.pressed = false
158 });
159 tapping_key = *keyp;
160 return false;
161 }
162 else {
163 if (!IS_NOEVENT(keyp->event)) debug("Tapping: key event while tap.\n");
164 process(keyp);
165 return true;
166 }
167 }
168 }
169 // not within TAP_TERM
170 else {
171 if (tapping_key.tap_count == 0) {
172 // timeout. not tap.
173 debug("Tapping: End. Not tap(time out).\n");
174 process(&tapping_key);
175 tapping_key = (keyrecord_t){};
176 return false;
177 } else {
178 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
179 debug("Tapping: End. tap release.");
180 keyp->tap_count = tapping_key.tap_count;
181 process(keyp);
182 tapping_key = (keyrecord_t){};
183 return true;
184 } else {
185 // other key after tap time out.
186 process(keyp);
187 return true;
188 }
189 }
190 }
191 } else if (IS_TAPPING_RELEASED()) {
192 if (WITHIN_TAP_TERM(event)) {
193 if (tapping_key.tap_count > 0 && IS_TAPPING_KEY(event.key) && event.pressed) {
194 // sequential tap.
195 keyp->tap_count = tapping_key.tap_count + 1;
196 debug("Tapping: tap press("); debug_dec(keyp->tap_count); debug(")\n");
197 process(keyp);
198 tapping_key = *keyp;
199 return true;
200 } else if (event.pressed && is_tap_key(event.key)) {
201 // Sequential tap can be interfered with other tap key.
202 debug("Tapping: Start with interfering other tap.\n");
203 tapping_key = *keyp;
204 return true;
205 } else {
206 if (!IS_NOEVENT(keyp->event)) debug("Tapping: other key just after tap.\n");
207 process(keyp);
208 return true;
209 }
210 } else {
211 // timeout. no sequential tap.
212 debug("Tapping: End(Time out after releasing last tap).\n");
213 tapping_key = (keyrecord_t){};
214 process(keyp);
215 return true;
216 }
217 } else {
218 if (event.pressed && is_tap_key(event.key)) {
219 debug("Tapping: Start(Press tap key).\n");
220 tapping_key = *keyp;
221 return true;
222 } else {
223 process(keyp);
224 return true;
225 }
226 }
227 }
228
229 void action_exec(keyevent_t event)
230 {
231 if (!IS_NOEVENT(event)) {
232 debug("event: ");
233 debug_hex16(event.time); debug(": ");
234 debug_hex16(event.key.raw);
235 debug("[");
236 if (event.pressed) debug("down"); else debug("up");
237 debug("]\n");
238 }
239
240 keyrecord_t record = { .event = event };
241
242 // pre-process on tapping
243 if (process_tap(&record)) {
244 if (!IS_NOEVENT(record.event)) debug("processed.\n");
245 } else {
246 if (!IS_NOEVENT(record.event)) debug("enqueued.\n");
247 if (!waiting_buffer_enq(record)) {
248 // clear all in case of overflow.
249 clear_keyboard();
250 waiting_buffer_clear();
251 tapping_key = (keyrecord_t){};
252 }
253 }
254
255 // TODO: need to process every time?
256 // process waiting_buffer
257 for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) {
258 if (process_tap(&waiting_buffer[waiting_buffer_tail])) {
259 debug("processed: waiting_buffer["); debug_dec(waiting_buffer_tail); debug("] = ");
260 debug_hex16(waiting_buffer[waiting_buffer_tail].event.key.raw); debug("\n");
261 } else {
262 break;
263 }
264 }
265 }
266
267 static void process(keyrecord_t *record)
268 {
269 // TODO: use record
270 keyevent_t event = record->event;
271 uint8_t tap_count = record->tap_count;
272
273 if (IS_NOEVENT(event)) { return; }
274
275 action_t action = keymap_get_action(current_layer, event.key.pos.row, event.key.pos.col);
276 debug("action: "); debug_hex16(action.code);
277 if (event.pressed) debug("[down]\n"); else debug("[up]\n");
278
279 switch (action.kind.id) {
280 /* Key and Mods */
281 case ACT_LMODS:
282 // |pressed |released
283 // --------------+---------------------------------+------------
284 // key |down(key) |up(key)
285 // mods |add(mods) |del(mods)
286 // key with mods |add(mods), down(key), unset(mods)|up(key)
287 if (event.pressed) {
288 uint8_t tmp_mods = host_get_mods();
289 if (action.key.mods) {
290 host_add_mods(action.key.mods);
291 host_send_keyboard_report();
292 }
293 register_code(action.key.code);
294 if (action.key.mods && action.key.code) {
295 host_set_mods(tmp_mods);
296 host_send_keyboard_report();
297 }
298 } else {
299 if (action.key.mods && !action.key.code) {
300 host_del_mods(action.key.mods);
301 host_send_keyboard_report();
302 }
303 unregister_code(action.key.code);
304 }
305 break;
306 case ACT_RMODS:
307 // |pressed |released
308 // --------------+---------------------------------+------------
309 // key |down(key) |up(key)
310 // mods |add(mods) |del(mods)
311 // key with mods |add(mods), down(key), unset(mods)|up(key)
312 if (event.pressed) {
313 uint8_t tmp_mods = host_get_mods();
314 if (action.key.mods) {
315 host_add_mods(action.key.mods<<4);
316 host_send_keyboard_report();
317 }
318 register_code(action.key.code);
319 if (action.key.mods && action.key.code) {
320 host_set_mods(tmp_mods);
321 host_send_keyboard_report();
322 }
323 } else {
324 if (action.key.mods && !action.key.code) {
325 host_del_mods(action.key.mods<<4);
326 host_send_keyboard_report();
327 }
328 unregister_code(action.key.code);
329 }
330 break;
331 case ACT_LMODS_TAP:
332 case ACT_RMODS_TAP:
333 {
334 uint8_t tmp_mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods :
335 action.key.mods<<4;
336 if (event.pressed) {
337 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
338 if (waiting_buffer_has_anykey_pressed()) {
339 debug("MODS_TAP: Tap: Cancel: add_mods\n");
340 // ad hoc: set 0 to cancel tap
341 record->tap_count = 0;
342 add_mods(tmp_mods);
343 } else {
344 debug("MODS_TAP: Tap: register_code\n");
345 register_code(action.key.code);
346 }
347 } else {
348 debug("MODS_TAP: No tap: add_mods\n");
349 add_mods(tmp_mods);
350 }
351 } else {
352 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
353 debug("MODS_TAP: Tap: unregister_code\n");
354 unregister_code(action.key.code);
355 } else {
356 debug("MODS_TAP: No tap: add_mods\n");
357 del_mods(tmp_mods);
358 }
359 }
360 }
361 break;
362
363 /* other HID usage */
364 case ACT_USAGE:
365 #ifdef EXTRAKEY_ENABLE
366 switch (action.usage.page) {
367 case ACTION_USAGE_PAGE_SYSTEM:
368 if (event.pressed) {
369 host_system_send(action.usage.code);
370 } else {
371 host_system_send(0);
372 }
373 break;
374 case ACTION_USAGE_PAGE_CONSUMER:
375 if (event.pressed) {
376 host_consumer_send(action.usage.code);
377 } else {
378 host_consumer_send(0);
379 }
380 break;
381 }
382 #endif
383 break;
384
385 /* Mouse key */
386 case ACT_MOUSEKEY:
387 #ifdef MOUSEKEY_ENABLE
388 if (event.pressed) {
389 mousekey_on(action.key.code);
390 mousekey_send();
391 } else {
392 mousekey_off(action.key.code);
393 mousekey_send();
394 }
395 #endif
396 break;
397
398 /* Layer key */
399 case ACT_LAYER_PRESSED:
400 // layer action when pressed
401 switch (action.layer.code) {
402 case 0x00:
403 if (event.pressed) {
404 layer_switch(action.layer.opt);
405 }
406 break;
407 case 0xF0:
408 // TODO: tap toggle
409 break;
410 case 0xFF:
411 if (event.pressed) {
412 default_layer = action.layer.opt;
413 layer_switch(default_layer);
414 }
415 break;
416 default:
417 // with tap key
418 if (event.pressed) {
419 if (IS_TAPPING_KEY(event.key)) {
420 if (tap_count > 0) {
421 debug("LAYER_PRESSED: Tap: register_code\n");
422 register_code(action.layer.code);
423 } else {
424 debug("LAYER_PRESSED: No tap: layer_switch\n");
425 layer_switch(action.layer.opt);
426 }
427 } else {
428 // TODO: while other key tapping
429 debug("LAYER_PRESSED: No tap: layer_switch\n");
430 layer_switch(action.layer.opt);
431 }
432 /*
433 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
434 debug("LAYER_PRESSED: Tap: register_code\n");
435 register_code(action.layer.code);
436 } else {
437 debug("LAYER_PRESSED: No tap: layer_switch\n");
438 layer_switch(action.layer.opt);
439 }
440 */
441 } else {
442 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
443 debug("LAYER_PRESSED: Tap: unregister_code\n");
444 unregister_code(action.layer.code);
445 } else {
446 debug("LAYER_PRESSED: No tap: NO ACTION\n");
447 }
448 }
449 break;
450 }
451 break;
452 case ACT_LAYER_RELEASED:
453 switch (action.layer.code) {
454 case 0x00:
455 if (!event.pressed) {
456 layer_switch(action.layer.opt);
457 }
458 break;
459 case 0xF0:
460 // Ignored. LAYER_RELEASED with tap toggle is invalid action.
461 break;
462 case 0xFF:
463 if (!event.pressed) {
464 default_layer = action.layer.opt;
465 layer_switch(default_layer);
466 }
467 break;
468 default:
469 // Ignored. LAYER_RELEASED with tap key is invalid action.
470 break;
471 }
472 break;
473 case ACT_LAYER_BIT:
474 switch (action.layer.code) {
475 case 0x00:
476 if (event.pressed) {
477 layer_switch(current_layer | action.layer.opt);
478 } else {
479 layer_switch(current_layer & ~action.layer.opt);
480 }
481 break;
482 case 0xF0:
483 // TODO: tap toggle
484 break;
485 case 0xFF:
486 // change default layer
487 if (event.pressed) {
488 default_layer = current_layer | action.layer.opt;
489 layer_switch(default_layer);
490 } else {
491 default_layer = current_layer & ~action.layer.opt;
492 layer_switch(default_layer);
493 }
494 break;
495 default:
496 // with tap key
497 if (event.pressed) {
498 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
499 debug("LAYER_BIT: Tap: register_code\n");
500 register_code(action.layer.code);
501 } else {
502 debug("LAYER_BIT: No tap: layer_switch(bit on)\n");
503 layer_switch(current_layer | action.layer.opt);
504 }
505 } else {
506 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
507 debug("LAYER_BIT: Tap: unregister_code\n");
508 unregister_code(action.layer.code);
509 } else {
510 debug("LAYER_BIT: No tap: layer_switch(bit off)\n");
511 layer_switch(current_layer & ~action.layer.opt);
512 }
513 }
514 break;
515 }
516 case ACT_LAYER_EXT:
517 switch (action.layer.opt) {
518 case 0x00:
519 // set default layer when pressed
520 switch (action.layer.code) {
521 case 0x00:
522 if (event.pressed) {
523 layer_switch(default_layer);
524 }
525 break;
526 case 0xF0:
527 // TODO: tap toggle
528 break;
529 case 0xFF:
530 if (event.pressed) {
531 default_layer = current_layer;
532 layer_switch(default_layer);
533 }
534 break;
535 default:
536 // TODO: tap key
537 break;
538 }
539 break;
540 case 0x01:
541 // set default layer when released
542 switch (action.layer.code) {
543 case 0x00:
544 if (!event.pressed) {
545 layer_switch(default_layer);
546 }
547 break;
548 case 0xFF:
549 if (!event.pressed) {
550 default_layer = current_layer;
551 layer_switch(default_layer);
552 }
553 break;
554 case 0xF0:
555 default:
556 // Ignore tap.
557 if (!event.pressed) {
558 layer_switch(default_layer);
559 }
560 break;
561 }
562 break;
563 }
564 break;
565
566 /* Extentions */
567 case ACT_MACRO:
568 break;
569 case ACT_COMMAND:
570 break;
571 case ACT_FUNCTION:
572 action_call_function(event, action.func.id);
573 //test_func(event, action.func.opt);
574 break;
575 default:
576 break;
577 }
578 }
579
580
581 /*
582 * Utilities for actions.
583 */
584 void register_code(uint8_t code)
585 {
586 if (code == KC_NO) {
587 return;
588 }
589 else if IS_KEY(code) {
590 // TODO: should push command_proc out of this block?
591 if (!command_proc(code)) {
592 host_add_key(code);
593 host_send_keyboard_report();
594 }
595 }
596 else if IS_MOD(code) {
597 host_add_mods(MOD_BIT(code));
598 host_send_keyboard_report();
599 }
600 }
601
602 void unregister_code(uint8_t code)
603 {
604 if IS_KEY(code) {
605 host_del_key(code);
606 host_send_keyboard_report();
607 }
608 else if IS_MOD(code) {
609 host_del_mods(MOD_BIT(code));
610 host_send_keyboard_report();
611 }
612 }
613
614 void add_mods(uint8_t mods)
615 {
616 if (mods) {
617 host_add_mods(mods);
618 host_send_keyboard_report();
619 }
620 }
621
622 void del_mods(uint8_t mods)
623 {
624 if (mods) {
625 host_del_mods(mods);
626 host_send_keyboard_report();
627 }
628 }
629
630 void set_mods(uint8_t mods)
631 {
632 host_set_mods(mods);
633 host_send_keyboard_report();
634 }
635
636 void clear_keyboard(void)
637 {
638 host_clear_mods();
639 clear_keyboard_but_mods();
640 }
641
642 void clear_keyboard_but_mods(void)
643 {
644 host_clear_keys();
645 host_send_keyboard_report();
646 #ifdef MOUSEKEY_ENABLE
647 mousekey_clear();
648 mousekey_send();
649 #endif
650 #ifdef EXTRAKEY_ENABLE
651 host_system_send(0);
652 host_consumer_send(0);
653 #endif
654 }
655
656 bool sending_anykey(void)
657 {
658 return (host_has_anykey() || host_mouse_in_use() ||
659 host_last_sysytem_report() || host_last_consumer_report());
660 }
661
662 void layer_switch(uint8_t new_layer)
663 {
664 if (current_layer != new_layer) {
665 debug("Layer Switch: "); debug_hex(current_layer);
666 debug(" -> "); debug_hex(new_layer); debug("\n");
667
668 current_layer = new_layer;
669 clear_keyboard_but_mods(); // To avoid stuck keys
670 // TODO: update mods with full scan of matrix? if modifier changes between layers
671 }
672 }
673
674 bool is_tap_key(key_t key)
675 {
676 action_t action = keymap_get_action(current_layer, key.pos.row, key.pos.col);
677 switch (action.kind.id) {
678 case ACT_LMODS_TAP:
679 case ACT_RMODS_TAP:
680 return true;
681 case ACT_LAYER_PRESSED:
682 case ACT_LAYER_BIT:
683 switch (action.layer.code) {
684 case 0x00:
685 case 0xF1 ... 0xFF:
686 return false;
687 case 0xF0:
688 default:
689 return true;
690 }
691 return false;
692 case ACT_FUNCTION:
693 if (action.func.opt & 0x1) {
694 return true;
695 }
696 return false;
697 }
698 return false;
699 }
Imprint / Impressum