]> git.donarmstrong.com Git - tmk_firmware.git/blob - common/action.c
New tapping logic.
[tmk_firmware.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 }