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