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