]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/common/action.c
Rename ONEHAND_ENABLE to SWAP_HANDS_ENABLE for consistency
[qmk_firmware.git] / tmk_core / 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 "keycode.h"
19 #include "keyboard.h"
20 #include "mousekey.h"
21 #include "command.h"
22 #include "led.h"
23 #include "backlight.h"
24 #include "action_layer.h"
25 #include "action_tapping.h"
26 #include "action_macro.h"
27 #include "action_util.h"
28 #include "action.h"
29 #include "wait.h"
30
31 #ifdef DEBUG_ACTION
32 #include "debug.h"
33 #else
34 #include "nodebug.h"
35 #endif
36
37 int tp_buttons;
38
39 #ifdef RETRO_TAPPING
40 int retro_tapping_counter = 0;
41 #endif
42
43 #ifdef FAUXCLICKY_ENABLE
44 #include <fauxclicky.h>
45 #endif
46
47 void action_exec(keyevent_t event)
48 {
49     if (!IS_NOEVENT(event)) {
50         dprint("\n---- action_exec: start -----\n");
51         dprint("EVENT: "); debug_event(event); dprintln();
52 #ifdef RETRO_TAPPING
53         retro_tapping_counter++;
54 #endif
55     }
56
57 #ifdef FAUXCLICKY_ENABLE
58     if (IS_PRESSED(event)) {
59         FAUXCLICKY_ACTION_PRESS;
60     }
61     if (IS_RELEASED(event)) {
62         FAUXCLICKY_ACTION_RELEASE;
63     }
64     fauxclicky_check();
65 #endif
66
67 #ifdef SWAP_HANDS_ENABLE
68     if (!IS_NOEVENT(event)) {
69         process_hand_swap(&event);
70     }
71 #endif
72
73     keyrecord_t record = { .event = event };
74
75 #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
76     if (has_oneshot_layer_timed_out()) {
77         clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
78     }
79     if (has_oneshot_mods_timed_out()) {
80         clear_oneshot_mods();
81     }
82 #endif
83
84 #ifndef NO_ACTION_TAPPING
85     action_tapping_process(record);
86 #else
87     process_record(&record);
88     if (!IS_NOEVENT(record.event)) {
89         dprint("processed: "); debug_record(record); dprintln();
90     }
91 #endif
92 }
93
94 #ifdef SWAP_HANDS_ENABLE
95 bool swap_hands = false;
96
97 void process_hand_swap(keyevent_t *event) {
98     static swap_state_row_t swap_state[MATRIX_ROWS];
99
100     keypos_t pos = event->key;
101     swap_state_row_t col_bit = (swap_state_row_t)1<<pos.col;
102     bool do_swap = event->pressed ? swap_hands :
103                                     swap_state[pos.row] & (col_bit);
104
105     if (do_swap) {
106         event->key = hand_swap_config[pos.row][pos.col];
107         swap_state[pos.row] |= col_bit;
108     } else {
109         swap_state[pos.row] &= ~(col_bit);
110     }
111 }
112 #endif
113
114 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
115 bool disable_action_cache = false;
116
117 void process_record_nocache(keyrecord_t *record)
118 {
119     disable_action_cache = true;
120     process_record(record);
121     disable_action_cache = false;
122 }
123 #else
124 void process_record_nocache(keyrecord_t *record)
125 {
126     process_record(record);
127 }
128 #endif
129
130 __attribute__ ((weak))
131 bool process_record_quantum(keyrecord_t *record) {
132     return true;
133 }
134
135 void process_record(keyrecord_t *record)
136 {
137     if (IS_NOEVENT(record->event)) { return; }
138
139     if(!process_record_quantum(record))
140         return;
141
142     action_t action = store_or_get_action(record->event.pressed, record->event.key);
143     dprint("ACTION: "); debug_action(action);
144 #ifndef NO_ACTION_LAYER
145     dprint(" layer_state: "); layer_debug();
146     dprint(" default_layer_state: "); default_layer_debug();
147 #endif
148     dprintln();
149
150     process_action(record, action);
151 }
152
153 void process_action(keyrecord_t *record, action_t action)
154 {
155     keyevent_t event = record->event;
156 #ifndef NO_ACTION_TAPPING
157     uint8_t tap_count = record->tap.count;
158 #endif
159
160     if (event.pressed) {
161         // clear the potential weak mods left by previously pressed keys
162         clear_weak_mods();
163     }
164
165 #ifndef NO_ACTION_ONESHOT
166     bool do_release_oneshot = false;
167     // notice we only clear the one shot layer if the pressed key is not a modifier.
168     if (is_oneshot_layer_active() && event.pressed && !IS_MOD(action.key.code)) {
169         clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
170         do_release_oneshot = !is_oneshot_layer_active();
171     }
172 #endif
173
174     switch (action.kind.id) {
175         /* Key and Mods */
176         case ACT_LMODS:
177         case ACT_RMODS:
178             {
179                 uint8_t mods = (action.kind.id == ACT_LMODS) ?  action.key.mods :
180                                                                 action.key.mods<<4;
181                 if (event.pressed) {
182                     if (mods) {
183                         if (IS_MOD(action.key.code) || action.key.code == KC_NO) {
184                             // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless.
185                             // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT).
186                             // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO).
187                             add_mods(mods);
188                         } else {
189                             add_weak_mods(mods);
190                         }
191                         send_keyboard_report();
192                     }
193                     register_code(action.key.code);
194                 } else {
195                     unregister_code(action.key.code);
196                     if (mods) {
197                         if (IS_MOD(action.key.code) || action.key.code == KC_NO) {
198                             del_mods(mods);
199                         } else {
200                             del_weak_mods(mods);
201                         }
202                         send_keyboard_report();
203                     }
204                 }
205             }
206             break;
207 #ifndef NO_ACTION_TAPPING
208         case ACT_LMODS_TAP:
209         case ACT_RMODS_TAP:
210             {
211                 uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ?  action.key.mods :
212                                                                     action.key.mods<<4;
213                 switch (action.layer_tap.code) {
214     #ifndef NO_ACTION_ONESHOT
215                     case MODS_ONESHOT:
216                         // Oneshot modifier
217                         if (event.pressed) {
218                             if (tap_count == 0) {
219                                 dprint("MODS_TAP: Oneshot: 0\n");
220                                 register_mods(mods);
221                             } else if (tap_count == 1) {
222                                 dprint("MODS_TAP: Oneshot: start\n");
223                                 set_oneshot_mods(mods);
224                     #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
225                             } else if (tap_count == ONESHOT_TAP_TOGGLE) {
226                                 dprint("MODS_TAP: Toggling oneshot");
227                                 clear_oneshot_mods();
228                                 set_oneshot_locked_mods(mods);
229                                 register_mods(mods);
230                     #endif
231                             } else {
232                                 register_mods(mods);
233                             }
234                         } else {
235                             if (tap_count == 0) {
236                                 clear_oneshot_mods();
237                                 unregister_mods(mods);
238                             } else if (tap_count == 1) {
239                                 // Retain Oneshot mods
240                     #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
241                                 if (mods & get_mods()) {
242                                     clear_oneshot_locked_mods();
243                                     clear_oneshot_mods();
244                                     unregister_mods(mods);
245                                 }
246                             } else if (tap_count == ONESHOT_TAP_TOGGLE) {
247                                 // Toggle Oneshot Layer
248                     #endif
249                             } else {
250                                 clear_oneshot_mods();
251                                 unregister_mods(mods);
252                             }
253                         }
254                         break;
255     #endif
256                     case MODS_TAP_TOGGLE:
257                         if (event.pressed) {
258                             if (tap_count <= TAPPING_TOGGLE) {
259                                 register_mods(mods);
260                             }
261                         } else {
262                             if (tap_count < TAPPING_TOGGLE) {
263                                 unregister_mods(mods);
264                             }
265                         }
266                         break;
267                     default:
268                         if (event.pressed) {
269                             if (tap_count > 0) {
270 #ifndef IGNORE_MOD_TAP_INTERRUPT
271                                 if (record->tap.interrupted) {
272                                     dprint("mods_tap: tap: cancel: add_mods\n");
273                                     // ad hoc: set 0 to cancel tap
274                                     record->tap.count = 0;
275                                     register_mods(mods);
276                                 } else
277 #endif
278                                 {
279                                     dprint("MODS_TAP: Tap: register_code\n");
280                                     register_code(action.key.code);
281                                 }
282                             } else {
283                                 dprint("MODS_TAP: No tap: add_mods\n");
284                                 register_mods(mods);
285                             }
286                         } else {
287                             if (tap_count > 0) {
288                                 dprint("MODS_TAP: Tap: unregister_code\n");
289                                 unregister_code(action.key.code);
290                             } else {
291                                 dprint("MODS_TAP: No tap: add_mods\n");
292                                 unregister_mods(mods);
293                             }
294                         }
295                         break;
296                 }
297             }
298             break;
299 #endif
300 #ifdef EXTRAKEY_ENABLE
301         /* other HID usage */
302         case ACT_USAGE:
303             switch (action.usage.page) {
304                 case PAGE_SYSTEM:
305                     if (event.pressed) {
306                         host_system_send(action.usage.code);
307                     } else {
308                         host_system_send(0);
309                     }
310                     break;
311                 case PAGE_CONSUMER:
312                     if (event.pressed) {
313                         host_consumer_send(action.usage.code);
314                     } else {
315                         host_consumer_send(0);
316                     }
317                     break;
318             }
319             break;
320 #endif
321 #ifdef MOUSEKEY_ENABLE
322         /* Mouse key */
323         case ACT_MOUSEKEY:
324             if (event.pressed) {
325                 switch (action.key.code) {
326                     case KC_MS_BTN1:
327                         tp_buttons |= (1<<0);
328                         break;
329                     case KC_MS_BTN2:
330                         tp_buttons |= (1<<1);
331                         break;
332                     case KC_MS_BTN3:
333                         tp_buttons |= (1<<2);
334                         break;
335                     default:
336                         break;
337                 }
338                 mousekey_on(action.key.code);
339                 mousekey_send();
340             } else {
341                 switch (action.key.code) {
342                     case KC_MS_BTN1:
343                         tp_buttons &= ~(1<<0);
344                         break;
345                     case KC_MS_BTN2:
346                         tp_buttons &= ~(1<<1);
347                         break;
348                     case KC_MS_BTN3:
349                         tp_buttons &= ~(1<<2);
350                         break;
351                     default:
352                         break;
353                 }
354                 mousekey_off(action.key.code);
355                 mousekey_send();
356             }
357             break;
358 #endif
359 #ifndef NO_ACTION_LAYER
360         case ACT_LAYER:
361             if (action.layer_bitop.on == 0) {
362                 /* Default Layer Bitwise Operation */
363                 if (!event.pressed) {
364                     uint8_t shift = action.layer_bitop.part*4;
365                     uint32_t bits = ((uint32_t)action.layer_bitop.bits)<<shift;
366                     uint32_t mask = (action.layer_bitop.xbit) ? ~(((uint32_t)0xf)<<shift) : 0;
367                     switch (action.layer_bitop.op) {
368                         case OP_BIT_AND: default_layer_and(bits | mask); break;
369                         case OP_BIT_OR:  default_layer_or(bits | mask);  break;
370                         case OP_BIT_XOR: default_layer_xor(bits | mask); break;
371                         case OP_BIT_SET: default_layer_and(mask); default_layer_or(bits); break;
372                     }
373                 }
374             } else {
375                 /* Layer Bitwise Operation */
376                 if (event.pressed ? (action.layer_bitop.on & ON_PRESS) :
377                                     (action.layer_bitop.on & ON_RELEASE)) {
378                     uint8_t shift = action.layer_bitop.part*4;
379                     uint32_t bits = ((uint32_t)action.layer_bitop.bits)<<shift;
380                     uint32_t mask = (action.layer_bitop.xbit) ? ~(((uint32_t)0xf)<<shift) : 0;
381                     switch (action.layer_bitop.op) {
382                         case OP_BIT_AND: layer_and(bits | mask); break;
383                         case OP_BIT_OR:  layer_or(bits | mask);  break;
384                         case OP_BIT_XOR: layer_xor(bits | mask); break;
385                         case OP_BIT_SET: layer_and(mask); layer_or(bits); break;
386                     }
387                 }
388             }
389             break;
390     #ifndef NO_ACTION_TAPPING
391         case ACT_LAYER_TAP:
392         case ACT_LAYER_TAP_EXT:
393             switch (action.layer_tap.code) {
394                 case 0xe0 ... 0xef:
395                     /* layer On/Off with modifiers(left only) */
396                     if (event.pressed) {
397                         layer_on(action.layer_tap.val);
398                         register_mods(action.layer_tap.code & 0x0f);
399                     } else {
400                         layer_off(action.layer_tap.val);
401                         unregister_mods(action.layer_tap.code & 0x0f);
402                     }
403                     break;
404                 case OP_TAP_TOGGLE:
405                     /* tap toggle */
406                     if (event.pressed) {
407                         if (tap_count < TAPPING_TOGGLE) {
408                             layer_invert(action.layer_tap.val);
409                         }
410                     } else {
411                         if (tap_count <= TAPPING_TOGGLE) {
412                             layer_invert(action.layer_tap.val);
413                         }
414                     }
415                     break;
416                 case OP_ON_OFF:
417                     event.pressed ? layer_on(action.layer_tap.val) :
418                                     layer_off(action.layer_tap.val);
419                     break;
420                 case OP_OFF_ON:
421                     event.pressed ? layer_off(action.layer_tap.val) :
422                                     layer_on(action.layer_tap.val);
423                     break;
424                 case OP_SET_CLEAR:
425                     event.pressed ? layer_move(action.layer_tap.val) :
426                                     layer_clear();
427                     break;
428             #ifndef NO_ACTION_ONESHOT
429                 case OP_ONESHOT:
430                     // Oneshot modifier
431                 #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
432                     do_release_oneshot = false;
433                     if (event.pressed) {
434                         del_mods(get_oneshot_locked_mods());
435                         if (get_oneshot_layer_state() == ONESHOT_TOGGLED) {
436                             reset_oneshot_layer();
437                             layer_off(action.layer_tap.val);
438                             break;
439                         } else if (tap_count < ONESHOT_TAP_TOGGLE) {
440                             layer_on(action.layer_tap.val);
441                             set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
442                         }
443                     } else {
444                         add_mods(get_oneshot_locked_mods());
445                         if (tap_count >= ONESHOT_TAP_TOGGLE) {
446                             reset_oneshot_layer();
447                             clear_oneshot_locked_mods();
448                             set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED);
449                         } else {
450                             clear_oneshot_layer_state(ONESHOT_PRESSED);
451                         }
452                     }
453                 #else
454                     if (event.pressed) {
455                         layer_on(action.layer_tap.val);
456                         set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
457                     } else {
458                         clear_oneshot_layer_state(ONESHOT_PRESSED);
459                         if (tap_count > 1) {
460                             clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
461                         }
462                     }
463                 #endif
464                     break;
465             #endif
466                 default:
467                     /* tap key */
468                     if (event.pressed) {
469                         if (tap_count > 0) {
470                             dprint("KEYMAP_TAP_KEY: Tap: register_code\n");
471                             register_code(action.layer_tap.code);
472                         } else {
473                             dprint("KEYMAP_TAP_KEY: No tap: On on press\n");
474                             layer_on(action.layer_tap.val);
475                         }
476                     } else {
477                         if (tap_count > 0) {
478                             dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n");
479                             if (action.layer_tap.code == KC_CAPS) {
480                                 wait_ms(80);
481                             }
482                             unregister_code(action.layer_tap.code);
483                         } else {
484                             dprint("KEYMAP_TAP_KEY: No tap: Off on release\n");
485                             layer_off(action.layer_tap.val);
486                         }
487                     }
488                     break;
489             }
490             break;
491     #endif
492 #endif
493         /* Extentions */
494 #ifndef NO_ACTION_MACRO
495         case ACT_MACRO:
496             action_macro_play(action_get_macro(record, action.func.id, action.func.opt));
497             break;
498 #endif
499 #ifdef BACKLIGHT_ENABLE
500         case ACT_BACKLIGHT:
501             if (!event.pressed) {
502                 switch (action.backlight.opt) {
503                     case BACKLIGHT_INCREASE:
504                         backlight_increase();
505                         break;
506                     case BACKLIGHT_DECREASE:
507                         backlight_decrease();
508                         break;
509                     case BACKLIGHT_TOGGLE:
510                         backlight_toggle();
511                         break;
512                     case BACKLIGHT_STEP:
513                         backlight_step();
514                         break;
515                     case BACKLIGHT_ON:
516                         backlight_level(BACKLIGHT_LEVELS);
517                         break;
518                     case BACKLIGHT_OFF:
519                         backlight_level(0);
520                         break;
521                 }
522             }
523             break;
524 #endif
525         case ACT_COMMAND:
526             break;
527 #ifdef SWAP_HANDS_ENABLE
528         case ACT_SWAP_HANDS:
529             switch (action.swap.code) {
530                 case OP_SH_TOGGLE:
531                     if (event.pressed) {
532                         swap_hands = !swap_hands;
533                     }
534                     break;
535                 case OP_SH_ON_OFF:
536                     swap_hands = event.pressed;
537                     break;
538                 case OP_SH_OFF_ON:
539                     swap_hands = !event.pressed;
540                     break;
541                 case OP_SH_ON:
542                     if (!event.pressed) {
543                         swap_hands = true;
544                     }
545                     break;
546                 case OP_SH_OFF:
547                     if (!event.pressed) {
548                         swap_hands = false;
549                     }
550                     break;
551     #ifndef NO_ACTION_TAPPING
552                 case OP_SH_TAP_TOGGLE:
553                     /* tap toggle */
554                     if (tap_count > 0) {
555                         if (!event.pressed) {
556                             swap_hands = !swap_hands;
557                         }
558                     } else {
559                         swap_hands = event.pressed;
560                     }
561                     break;
562                 default:
563                     if (tap_count > 0) {
564                         if (event.pressed) {
565                             register_code(action.swap.code);
566                         } else {
567                             unregister_code(action.swap.code);
568                         }
569                     } else {
570                         swap_hands = event.pressed;
571                     }
572     #endif
573             }
574 #endif
575 #ifndef NO_ACTION_FUNCTION
576         case ACT_FUNCTION:
577             action_function(record, action.func.id, action.func.opt);
578             break;
579 #endif
580         default:
581             break;
582     }
583
584 #ifndef NO_ACTION_LAYER
585     // if this event is a layer action, update the leds
586     switch (action.kind.id) {
587         case ACT_LAYER:
588         #ifndef NO_ACTION_TAPPING
589         case ACT_LAYER_TAP:
590         case ACT_LAYER_TAP_EXT:
591         #endif
592             led_set(host_keyboard_leds());
593             break;
594         default:
595             break;
596     }
597 #endif
598
599 #ifndef NO_ACTION_TAPPING
600   #ifdef RETRO_TAPPING
601   if (!is_tap_key(record->event.key)) {
602     retro_tapping_counter = 0;
603   } else {
604     if (event.pressed) {
605         if (tap_count > 0) {
606           retro_tapping_counter = 0;
607         } else {
608
609         }
610     } else {
611       if (tap_count > 0) {
612         retro_tapping_counter = 0;
613       } else {
614         if (retro_tapping_counter == 2) {
615           register_code(action.layer_tap.code);
616           unregister_code(action.layer_tap.code);
617         }
618         retro_tapping_counter = 0;
619       }
620     }
621   }
622   #endif
623 #endif
624
625 #ifndef NO_ACTION_ONESHOT
626     /* Because we switch layers after a oneshot event, we need to release the
627      * key before we leave the layer or no key up event will be generated.
628      */
629     if (do_release_oneshot && !(get_oneshot_layer_state() & ONESHOT_PRESSED )   ) {
630         record->event.pressed = false;
631         layer_on(get_oneshot_layer());
632         process_record(record);
633         layer_off(get_oneshot_layer());
634     }
635 #endif
636 }
637
638
639
640
641 /*
642  * Utilities for actions.
643  */
644 void register_code(uint8_t code)
645 {
646     if (code == KC_NO) {
647         return;
648     }
649
650 #ifdef LOCKING_SUPPORT_ENABLE
651     else if (KC_LOCKING_CAPS == code) {
652 #ifdef LOCKING_RESYNC_ENABLE
653         // Resync: ignore if caps lock already is on
654         if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) return;
655 #endif
656         add_key(KC_CAPSLOCK);
657         send_keyboard_report();
658         wait_ms(100);
659         del_key(KC_CAPSLOCK);
660         send_keyboard_report();
661     }
662
663     else if (KC_LOCKING_NUM == code) {
664 #ifdef LOCKING_RESYNC_ENABLE
665         if (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) return;
666 #endif
667         add_key(KC_NUMLOCK);
668         send_keyboard_report();
669         wait_ms(100);
670         del_key(KC_NUMLOCK);
671         send_keyboard_report();
672     }
673
674     else if (KC_LOCKING_SCROLL == code) {
675 #ifdef LOCKING_RESYNC_ENABLE
676         if (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) return;
677 #endif
678         add_key(KC_SCROLLLOCK);
679         send_keyboard_report();
680         wait_ms(100);
681         del_key(KC_SCROLLLOCK);
682         send_keyboard_report();
683     }
684 #endif
685
686     else if IS_KEY(code) {
687         // TODO: should push command_proc out of this block?
688         if (command_proc(code)) return;
689
690 #ifndef NO_ACTION_ONESHOT
691 /* TODO: remove
692         if (oneshot_state.mods && !oneshot_state.disabled) {
693             uint8_t tmp_mods = get_mods();
694             add_mods(oneshot_state.mods);
695
696             add_key(code);
697             send_keyboard_report();
698
699             set_mods(tmp_mods);
700             send_keyboard_report();
701             oneshot_cancel();
702         } else
703 */
704 #endif
705         {
706             add_key(code);
707             send_keyboard_report();
708         }
709     }
710     else if IS_MOD(code) {
711         add_mods(MOD_BIT(code));
712         send_keyboard_report();
713     }
714     else if IS_SYSTEM(code) {
715         host_system_send(KEYCODE2SYSTEM(code));
716     }
717     else if IS_CONSUMER(code) {
718         host_consumer_send(KEYCODE2CONSUMER(code));
719     }
720 }
721
722 void unregister_code(uint8_t code)
723 {
724     if (code == KC_NO) {
725         return;
726     }
727
728 #ifdef LOCKING_SUPPORT_ENABLE
729     else if (KC_LOCKING_CAPS == code) {
730 #ifdef LOCKING_RESYNC_ENABLE
731         // Resync: ignore if caps lock already is off
732         if (!(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK))) return;
733 #endif
734         add_key(KC_CAPSLOCK);
735         send_keyboard_report();
736         del_key(KC_CAPSLOCK);
737         send_keyboard_report();
738     }
739
740     else if (KC_LOCKING_NUM == code) {
741 #ifdef LOCKING_RESYNC_ENABLE
742         if (!(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK))) return;
743 #endif
744         add_key(KC_NUMLOCK);
745         send_keyboard_report();
746         del_key(KC_NUMLOCK);
747         send_keyboard_report();
748     }
749
750     else if (KC_LOCKING_SCROLL == code) {
751 #ifdef LOCKING_RESYNC_ENABLE
752         if (!(host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK))) return;
753 #endif
754         add_key(KC_SCROLLLOCK);
755         send_keyboard_report();
756         del_key(KC_SCROLLLOCK);
757         send_keyboard_report();
758     }
759 #endif
760
761     else if IS_KEY(code) {
762         del_key(code);
763         send_keyboard_report();
764     }
765     else if IS_MOD(code) {
766         del_mods(MOD_BIT(code));
767         send_keyboard_report();
768     }
769     else if IS_SYSTEM(code) {
770         host_system_send(0);
771     }
772     else if IS_CONSUMER(code) {
773         host_consumer_send(0);
774     }
775 }
776
777 void register_mods(uint8_t mods)
778 {
779     if (mods) {
780         add_mods(mods);
781         send_keyboard_report();
782     }
783 }
784
785 void unregister_mods(uint8_t mods)
786 {
787     if (mods) {
788         del_mods(mods);
789         send_keyboard_report();
790     }
791 }
792
793 void clear_keyboard(void)
794 {
795     clear_mods();
796     clear_keyboard_but_mods();
797 }
798
799 void clear_keyboard_but_mods(void)
800 {
801     clear_weak_mods();
802     clear_macro_mods();
803     clear_keys();
804     send_keyboard_report();
805 #ifdef MOUSEKEY_ENABLE
806     mousekey_clear();
807     mousekey_send();
808 #endif
809 #ifdef EXTRAKEY_ENABLE
810     host_system_send(0);
811     host_consumer_send(0);
812 #endif
813 }
814
815 bool is_tap_key(keypos_t key)
816 {
817     action_t action = layer_switch_get_action(key);
818
819     switch (action.kind.id) {
820         case ACT_LMODS_TAP:
821         case ACT_RMODS_TAP:
822         case ACT_LAYER_TAP:
823         case ACT_LAYER_TAP_EXT:
824             switch (action.layer_tap.code) {
825                 case 0x00 ... 0xdf:
826                 case OP_TAP_TOGGLE:
827                 case OP_ONESHOT:
828                     return true;
829             }
830             return false;
831         case ACT_SWAP_HANDS:
832             switch (action.swap.code) {
833                 case 0x00 ... 0xdf:
834                 case OP_SH_TAP_TOGGLE:
835                     return true;
836             }
837             return false;
838         case ACT_MACRO:
839         case ACT_FUNCTION:
840             if (action.func.opt & FUNC_TAP) { return true; }
841             return false;
842     }
843     return false;
844 }
845
846
847 /*
848  * debug print
849  */
850 void debug_event(keyevent_t event)
851 {
852     dprintf("%04X%c(%u)", (event.key.row<<8 | event.key.col), (event.pressed ? 'd' : 'u'), event.time);
853 }
854
855 void debug_record(keyrecord_t record)
856 {
857     debug_event(record.event);
858 #ifndef NO_ACTION_TAPPING
859     dprintf(":%u%c", record.tap.count, (record.tap.interrupted ? '-' : ' '));
860 #endif
861 }
862
863 void debug_action(action_t action)
864 {
865     switch (action.kind.id) {
866         case ACT_LMODS:             dprint("ACT_LMODS");             break;
867         case ACT_RMODS:             dprint("ACT_RMODS");             break;
868         case ACT_LMODS_TAP:         dprint("ACT_LMODS_TAP");         break;
869         case ACT_RMODS_TAP:         dprint("ACT_RMODS_TAP");         break;
870         case ACT_USAGE:             dprint("ACT_USAGE");             break;
871         case ACT_MOUSEKEY:          dprint("ACT_MOUSEKEY");          break;
872         case ACT_LAYER:             dprint("ACT_LAYER");             break;
873         case ACT_LAYER_TAP:         dprint("ACT_LAYER_TAP");         break;
874         case ACT_LAYER_TAP_EXT:     dprint("ACT_LAYER_TAP_EXT");     break;
875         case ACT_MACRO:             dprint("ACT_MACRO");             break;
876         case ACT_COMMAND:           dprint("ACT_COMMAND");           break;
877         case ACT_FUNCTION:          dprint("ACT_FUNCTION");          break;
878         case ACT_SWAP_HANDS:        dprint("ACT_SWAP_HANDS");        break;
879         default:                    dprint("UNKNOWN");               break;
880     }
881     dprintf("[%X:%02X]", action.kind.param>>8, action.kind.param&0xff);
882 }