]> git.donarmstrong.com Git - tmk_firmware.git/blob - common/action.c
Merge branch 'action_tapping'
[tmk_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 "keycode.h"
19 #include "keyboard.h"
20 #include "mousekey.h"
21 #include "command.h"
22 #include "debug.h"
23 #include "led.h"
24 #include "layer_switch.h"
25 #include "action_tapping.h"
26 #include "action_oneshot.h"
27 #include "action_macro.h"
28 #include "action.h"
29
30
31 void action_exec(keyevent_t event)
32 {
33     if (!IS_NOEVENT(event)) {
34         debug("\n---- action_exec: start -----\n");
35         debug("EVENT: "); debug_event(event); debug("\n");
36     }
37
38     keyrecord_t record = { .event = event };
39
40 #ifndef NO_ACTION_TAPPING
41     action_tapping_process(record);
42 #else
43     process_action(&record);
44     if (!IS_NOEVENT(record.event)) {
45         debug("processed: "); debug_record(record); debug("\n");
46     }
47 #endif
48 }
49
50 void process_action(keyrecord_t *record)
51 {
52     keyevent_t event = record->event;
53     uint8_t tap_count = record->tap.count;
54
55     if (IS_NOEVENT(event)) { return; }
56
57     action_t action = layer_switch_get_action(event.key);
58     debug("ACTION: "); debug_action(action);
59     debug(" overlays: "); overlay_debug();
60     debug(" keymaps: "); keymap_debug();
61     debug(" default_layer: "); debug_dec(default_layer); debug("\n");
62
63     switch (action.kind.id) {
64         /* Key and Mods */
65         case ACT_LMODS:
66         case ACT_RMODS:
67             {
68                 uint8_t mods = (action.kind.id == ACT_LMODS) ?  action.key.mods :
69                                                                 action.key.mods<<4;
70                 if (event.pressed) {
71                     uint8_t tmp_mods = host_get_mods();
72                     if (mods) {
73                         host_add_mods(mods);
74                         host_send_keyboard_report();
75                     }
76                     register_code(action.key.code);
77                     if (mods && action.key.code) {
78                         host_set_mods(tmp_mods);
79                         host_send_keyboard_report();
80                     }
81                 } else {
82                     if (mods && !action.key.code) {
83                         host_del_mods(mods);
84                         host_send_keyboard_report();
85                     }
86                     unregister_code(action.key.code);
87                 }
88             }
89             break;
90 #ifndef NO_ACTION_TAPPING
91         case ACT_LMODS_TAP:
92         case ACT_RMODS_TAP:
93             {
94                 uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ?  action.key.mods :
95                                                                     action.key.mods<<4;
96                 switch (action.layer.code) {
97     #ifndef NO_ACTION_ONESHOT
98                     case 0x00:
99                         // Oneshot modifier
100                         if (event.pressed) {
101                             if (tap_count == 0) {
102                                 debug("MODS_TAP: Oneshot: add_mods\n");
103                                 add_mods(mods);
104                             }
105                             else if (tap_count == 1) {
106                                 debug("MODS_TAP: Oneshot: start\n");
107                                 oneshot_start(mods);
108                             }
109                             else if (tap_count == TAPPING_TOGGLE) {
110                                 debug("MODS_TAP: Oneshot: toggle\n");
111                                 oneshot_toggle();
112                             }
113                             else {
114                                 debug("MODS_TAP: Oneshot: cancel&add_mods\n");
115                                 // double tap cancels oneshot and works as normal modifier.
116                                 oneshot_cancel();
117                                 add_mods(mods);
118                             }
119                         } else {
120                             if (tap_count == 0) {
121                                 debug("MODS_TAP: Oneshot: cancel/del_mods\n");
122                                 // cancel oneshot on hold
123                                 oneshot_cancel();
124                                 del_mods(mods);
125                             }
126                             else if (tap_count == 1) {
127                                 debug("MODS_TAP: Oneshot: del_mods\n");
128                                 // retain Oneshot
129                                 del_mods(mods);
130                             }
131                             else {
132                                 debug("MODS_TAP: Oneshot: del_mods\n");
133                                 // cancel Mods
134                                 del_mods(mods);
135                             }
136                         }
137                         break;
138     #endif
139                     default:
140                         if (event.pressed) {
141                             if (tap_count > 0) {
142                                 if (record->tap.interrupted) {
143                                     debug("MODS_TAP: Tap: Cancel: add_mods\n");
144                                     // ad hoc: set 0 to cancel tap
145                                     record->tap.count = 0;
146                                     add_mods(mods);
147                                 } else {
148                                     debug("MODS_TAP: Tap: register_code\n");
149                                     register_code(action.key.code);
150                                 }
151                             } else {
152                                 debug("MODS_TAP: No tap: add_mods\n");
153                                 add_mods(mods);
154                             }
155                         } else {
156                             if (tap_count > 0) {
157                                 debug("MODS_TAP: Tap: unregister_code\n");
158                                 unregister_code(action.key.code);
159                             } else {
160                                 debug("MODS_TAP: No tap: add_mods\n");
161                                 del_mods(mods);
162                             }
163                         }
164                         break;
165                 }
166             }
167             break;
168 #endif
169 #ifdef EXTRAKEY_ENABLE
170         /* other HID usage */
171         case ACT_USAGE:
172             switch (action.usage.page) {
173                 case PAGE_SYSTEM:
174                     if (event.pressed) {
175                         host_system_send(action.usage.code);
176                     } else {
177                         host_system_send(0);
178                     }
179                     break;
180                 case PAGE_CONSUMER:
181                     if (event.pressed) {
182                         host_consumer_send(action.usage.code);
183                     } else {
184                         host_consumer_send(0);
185                     }
186                     break;
187             }
188             break;
189 #endif
190 #ifdef MOUSEKEY_ENABLE
191         /* Mouse key */
192         case ACT_MOUSEKEY:
193             if (event.pressed) {
194                 mousekey_on(action.key.code);
195                 mousekey_send();
196             } else {
197                 mousekey_off(action.key.code);
198                 mousekey_send();
199             }
200             break;
201 #endif
202 #ifndef NO_ACTION_KEYMAP
203         case ACT_KEYMAP:
204             switch (action.layer.code) {
205                 /* Keymap clear */
206                 case OP_RESET:
207                     switch (action.layer.val & 0x03) {
208                         case 0:
209                             // NOTE: reserved
210                             overlay_clear();
211                             keymap_clear();
212                             break;
213                         case ON_PRESS:
214                             if (event.pressed) {
215                                 overlay_clear();
216                                 keymap_clear();
217                             }
218                             break;
219                         case ON_RELEASE:
220                             if (!event.pressed) {
221                                 overlay_clear();
222                                 keymap_clear();
223                             }
224                             break;
225                         case ON_BOTH:
226                             overlay_clear();
227                             keymap_clear();
228                             break;
229                         /* NOTE: 4-7 rserved */
230                     }
231                     break;
232                 /* Keymap Reset default layer */
233                 case (OP_RESET | ON_PRESS):
234                     if (event.pressed) {
235                         default_layer_set(action.layer.val);
236                     }
237                     break;
238                 case (OP_RESET | ON_RELEASE):
239                     if (!event.pressed) {
240                         default_layer_set(action.layer.val);
241                     }
242                     break;
243                 case (OP_RESET | ON_BOTH):
244                     default_layer_set(action.layer.val);
245                     break;
246
247                 /* Keymap Bit invert */
248                 case OP_INV:
249                     /* with tap toggle */
250                     if (event.pressed) {
251                         if (tap_count < TAPPING_TOGGLE) {
252                             debug("KEYMAP_INV: tap toggle(press).\n");
253                             keymap_invert(action.layer.val);
254                         }
255                     } else {
256                         if (tap_count <= TAPPING_TOGGLE) {
257                             debug("KEYMAP_INV: tap toggle(release).\n");
258                             keymap_invert(action.layer.val);
259                         }
260                     }
261                     break;
262                 case (OP_INV | ON_PRESS):
263                     if (event.pressed) {
264                         keymap_invert(action.layer.val);
265                     }
266                     break;
267                 case (OP_INV | ON_RELEASE):
268                     if (!event.pressed) {
269                         keymap_invert(action.layer.val);
270                     }
271                     break;
272                 case (OP_INV | ON_BOTH):
273                     keymap_invert(action.layer.val);
274                     break;
275
276                 /* Keymap Bit on */
277                 case OP_ON:
278                     if (event.pressed) {
279                         keymap_on(action.layer.val);
280                     } else {
281                         keymap_off(action.layer.val);
282                     }
283                     break;
284                 case (OP_ON | ON_PRESS):
285                     if (event.pressed) {
286                         keymap_on(action.layer.val);
287                     }
288                     break;
289                 case (OP_ON | ON_RELEASE):
290                     if (!event.pressed) {
291                         keymap_on(action.layer.val);
292                     }
293                     break;
294                 case (OP_ON | ON_BOTH):
295                     keymap_on(action.layer.val);
296                     break;
297
298                 /* Keymap Bit off */
299                 case OP_OFF:
300                     if (event.pressed) {
301                         keymap_off(action.layer.val);
302                     } else {
303                         keymap_on(action.layer.val);
304                     }
305                     break;
306                 case (OP_OFF | ON_PRESS):
307                     if (event.pressed) {
308                         keymap_off(action.layer.val);
309                     }
310                     break;
311                 case (OP_OFF | ON_RELEASE):
312                     if (!event.pressed) {
313                         keymap_off(action.layer.val);
314                     }
315                     break;
316                 case (OP_OFF | ON_BOTH):
317                     keymap_off(action.layer.val);
318                     break;
319
320                 /* Keymap Bit set */
321                 case OP_SET:
322                     if (event.pressed) {
323                         keymap_set(action.layer.val);
324                     } else {
325                         keymap_clear();
326                     }
327                     break;
328                 case (OP_SET | ON_PRESS):
329                     if (event.pressed) {
330                         keymap_set(action.layer.val);
331                     }
332                     break;
333                 case (OP_SET | ON_RELEASE):
334                     if (!event.pressed) {
335                         keymap_set(action.layer.val);
336                     }
337                     break;
338                 case (OP_SET | ON_BOTH):
339                     keymap_set(action.layer.val);
340                     break;
341
342                 /* Keymap Bit invert with tap key */
343                 default:
344                     if (event.pressed) {
345                         if (tap_count > 0) {
346                             debug("KEYMAP_TAP_KEY: Tap: register_code\n");
347                             register_code(action.layer.code);
348                         } else {
349                             debug("KEYMAP_TAP_KEY: No tap: On on press\n");
350                             keymap_on(action.layer.val);
351                         }
352                     } else {
353                         if (tap_count > 0) {
354                             debug("KEYMAP_TAP_KEY: Tap: unregister_code\n");
355                             unregister_code(action.layer.code);
356                         } else {
357                             debug("KEYMAP_TAP_KEY: No tap: Off on release\n");
358                             keymap_off(action.layer.val);
359                         }
360                     }
361                     break;
362             }
363             break;
364 #endif
365 #ifndef NO_ACTION_OVERLAY
366         case ACT_OVERLAY:
367             switch (action.layer.code) {
368                 // Overlay Invert bit4
369                 case OP_INV4 | 0:
370                     if (action.layer.val == 0) {
371                         // NOTE: reserved for future use
372                         overlay_clear();
373                     } else {
374                         overlay_set(overlay_stat ^ action.layer.val);
375                     }
376                     break;
377                 case OP_INV4 | 1:
378                     if (action.layer.val == 0) {
379                         // on pressed
380                         if (event.pressed) overlay_clear();
381                     } else {
382                         overlay_set(overlay_stat ^ action.layer.val<<4);
383                     }
384                     break;
385                 case OP_INV4 | 2:
386                     if (action.layer.val == 0) {
387                         // on released
388                         if (!event.pressed) overlay_clear();
389                     } else {
390                         overlay_set(overlay_stat ^ action.layer.val<<8);
391                     }
392                     break;
393                 case OP_INV4 | 3:
394                     if (action.layer.val == 0) {
395                         // on both
396                         overlay_clear();
397                     } else {
398                         overlay_set(overlay_stat ^ action.layer.val<<12);
399                     }
400                     break;
401
402                 /* Overlay Bit invert */
403                 case OP_INV:
404                     /* with tap toggle */
405                     if (event.pressed) {
406                         if (tap_count < TAPPING_TOGGLE) {
407                             debug("OVERLAY_INV: tap toggle(press).\n");
408                             overlay_invert(action.layer.val);
409                         }
410                     } else {
411                         if (tap_count <= TAPPING_TOGGLE) {
412                             debug("OVERLAY_INV: tap toggle(release).\n");
413                             overlay_invert(action.layer.val);
414                         }
415                     }
416                     break;
417                 case (OP_INV | ON_PRESS):
418                     if (event.pressed) {
419                         overlay_invert(action.layer.val);
420                     }
421                     break;
422                 case (OP_INV | ON_RELEASE):
423                     if (!event.pressed) {
424                         overlay_invert(action.layer.val);
425                     }
426                     break;
427                 case (OP_INV | ON_BOTH):
428                     overlay_invert(action.layer.val);
429                     break;
430
431                 /* Overlay Bit on */
432                 case OP_ON:
433                     if (event.pressed) {
434                         overlay_on(action.layer.val);
435                     } else {
436                         overlay_off(action.layer.val);
437                     }
438                     break;
439                 case (OP_ON | ON_PRESS):
440                     if (event.pressed) {
441                         overlay_on(action.layer.val);
442                     }
443                     break;
444                 case (OP_ON | ON_RELEASE):
445                     if (!event.pressed) {
446                         overlay_on(action.layer.val);
447                     }
448                     break;
449                 case (OP_ON | ON_BOTH):
450                     overlay_on(action.layer.val);
451                     break;
452
453                 /* Overlay Bit off */
454                 case OP_OFF:
455                     if (event.pressed) {
456                         overlay_off(action.layer.val);
457                     } else {
458                         overlay_on(action.layer.val);
459                     }
460                     break;
461                 case (OP_OFF | ON_PRESS):
462                     if (event.pressed) {
463                         overlay_off(action.layer.val);
464                     }
465                     break;
466                 case (OP_OFF | ON_RELEASE):
467                     if (!event.pressed) {
468                         overlay_off(action.layer.val);
469                     }
470                     break;
471                 case (OP_OFF | ON_BOTH):
472                     overlay_off(action.layer.val);
473                     break;
474
475                 /* Overlay Bit set */
476                 case OP_SET:
477                     if (event.pressed) {
478                         overlay_move(action.layer.val);
479                     } else {
480                         overlay_clear();
481                     }
482                     break;
483                 case (OP_SET | ON_PRESS):
484                     if (event.pressed) {
485                         overlay_move(action.layer.val);
486                     }
487                     break;
488                 case (OP_SET | ON_RELEASE):
489                     if (!event.pressed) {
490                         overlay_move(action.layer.val);
491                     }
492                     break;
493                 case (OP_SET | ON_BOTH):
494                     overlay_move(action.layer.val);
495                     break;
496
497                 /* Overlay Bit invert with tap key */
498                 default:
499                     if (event.pressed) {
500                         if (tap_count > 0) {
501                             debug("OVERLAY_TAP_KEY: Tap: register_code\n");
502                             register_code(action.layer.code);
503                         } else {
504                             debug("OVERLAY_TAP_KEY: No tap: On on press\n");
505                             overlay_on(action.layer.val);
506                         }
507                     } else {
508                         if (tap_count > 0) {
509                             debug("OVERLAY_TAP_KEY: Tap: unregister_code\n");
510                             unregister_code(action.layer.code);
511                         } else {
512                             debug("OVERLAY_TAP_KEY: No tap: Off on release\n");
513                             overlay_off(action.layer.val);
514                         }
515                     }
516                     break;
517             }
518             break;
519 #endif
520         /* Extentions */
521 #ifndef NO_ACTION_MACRO
522         case ACT_MACRO:
523             action_macro_play(action_get_macro(record, action.func.id, action.func.opt));
524             break;
525 #endif
526         case ACT_COMMAND:
527             break;
528 #ifndef NO_ACTION_FUNCTION
529         case ACT_FUNCTION:
530             action_function(record, action.func.id, action.func.opt);
531             break;
532 #endif
533         default:
534             break;
535     }
536 }
537
538
539
540
541 /*
542  * Utilities for actions.
543  */
544 void register_code(uint8_t code)
545 {
546     if (code == KC_NO) {
547         return;
548     }
549 #ifdef CAPSLOCK_LOCKING_ENABLE
550     else if (KC_LOCKING_CAPS == code) {
551 #ifdef CAPSLOCK_LOCKING_RESYNC_ENABLE
552         // Resync: ignore if caps lock already is on
553         if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) return;
554 #endif
555         host_add_key(KC_CAPSLOCK);
556         host_send_keyboard_report();
557         host_del_key(KC_CAPSLOCK);
558         host_send_keyboard_report();
559     }
560 #endif
561     else if IS_KEY(code) {
562         // TODO: should push command_proc out of this block?
563         if (command_proc(code)) return;
564
565 #ifndef NO_ACTION_ONESHOT
566         if (oneshot_state.mods && !oneshot_state.disabled) {
567             uint8_t tmp_mods = host_get_mods();
568             host_add_mods(oneshot_state.mods);
569
570             host_add_key(code);
571             host_send_keyboard_report();
572
573             host_set_mods(tmp_mods);
574             oneshot_cancel();
575         } else 
576 #endif
577         {
578             host_add_key(code);
579             host_send_keyboard_report();
580         }
581     }
582     else if IS_MOD(code) {
583         host_add_mods(MOD_BIT(code));
584         host_send_keyboard_report();
585     }
586 }
587
588 void unregister_code(uint8_t code)
589 {
590     if (code == KC_NO) {
591         return;
592     }
593 #ifdef CAPSLOCK_LOCKING_ENABLE
594     else if (KC_LOCKING_CAPS == code) {
595 #ifdef CAPSLOCK_LOCKING_RESYNC_ENABLE
596         // Resync: ignore if caps lock already is off
597         if (!(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK))) return;
598 #endif
599         host_add_key(KC_CAPSLOCK);
600         host_send_keyboard_report();
601         host_del_key(KC_CAPSLOCK);
602         host_send_keyboard_report();
603     }
604 #endif
605     else if IS_KEY(code) {
606         host_del_key(code);
607         host_send_keyboard_report();
608     }
609     else if IS_MOD(code) {
610         host_del_mods(MOD_BIT(code));
611         host_send_keyboard_report();
612     }
613 }
614
615 void add_mods(uint8_t mods)
616 {
617     if (mods) {
618         host_add_mods(mods);
619         host_send_keyboard_report();
620     }
621 }
622
623 void del_mods(uint8_t mods)
624 {
625     if (mods) {
626         host_del_mods(mods);
627         host_send_keyboard_report();
628     }
629 }
630
631 void set_mods(uint8_t mods)
632 {
633     host_set_mods(mods);
634     host_send_keyboard_report();
635 }
636
637 void clear_keyboard(void)
638 {
639     host_clear_mods();
640     clear_keyboard_but_mods();
641 }
642
643 void clear_keyboard_but_mods(void)
644 {
645     host_clear_keys();
646     host_send_keyboard_report();
647 #ifdef MOUSEKEY_ENABLE
648     mousekey_clear();
649     mousekey_send();
650 #endif
651 #ifdef EXTRAKEY_ENABLE
652     host_system_send(0);
653     host_consumer_send(0);
654 #endif
655 }
656
657 bool sending_anykey(void)
658 {
659     return (host_has_anykey() || host_mouse_in_use() ||
660             host_last_sysytem_report() || host_last_consumer_report());
661 }
662
663 bool is_tap_key(key_t key)
664 {
665     action_t action = layer_switch_get_action(key);
666
667     switch (action.kind.id) {
668         case ACT_LMODS_TAP:
669         case ACT_RMODS_TAP:
670             return true;
671         case ACT_KEYMAP:
672         case ACT_OVERLAY:
673             switch (action.layer.code) {
674                 case 0x04 ... 0xEF:    /* tap key */
675                 case OP_INV:
676                     return true;
677                 default:
678                     return false;
679             }
680         case ACT_MACRO:
681         case ACT_FUNCTION:
682             if (action.func.opt & FUNC_TAP) { return true; }
683             return false;
684     }
685     return false;
686 }
687
688
689 /*
690  * debug print
691  */
692 void debug_event(keyevent_t event)
693 {
694     debug_hex16((event.key.row<<8) | event.key.col);
695     if (event.pressed) debug("d("); else debug("u(");
696     debug_dec(event.time); debug(")");
697 }
698
699 void debug_record(keyrecord_t record)
700 {
701     debug_event(record.event);
702 #ifndef NO_ACTION_TAPPING
703     debug(":"); debug_dec(record.tap.count);
704     if (record.tap.interrupted) debug("-");
705 #endif
706 }
707
708 void debug_action(action_t action)
709 {
710     switch (action.kind.id) {
711         case ACT_LMODS:             debug("ACT_LMODS");             break;
712         case ACT_RMODS:             debug("ACT_RMODS");             break;
713         case ACT_LMODS_TAP:         debug("ACT_LMODS_TAP");         break;
714         case ACT_RMODS_TAP:         debug("ACT_RMODS_TAP");         break;
715         case ACT_USAGE:             debug("ACT_USAGE");             break;
716         case ACT_MOUSEKEY:          debug("ACT_MOUSEKEY");          break;
717         case ACT_KEYMAP:            debug("ACT_KEYMAP");            break;
718         case ACT_OVERLAY:           debug("ACT_OVERLAY");           break;
719         case ACT_MACRO:             debug("ACT_MACRO");             break;
720         case ACT_COMMAND:           debug("ACT_COMMAND");           break;
721         case ACT_FUNCTION:          debug("ACT_FUNCTION");          break;
722         default:                    debug("UNKNOWN");               break;
723     }
724     debug("[");
725     debug_hex4(action.kind.param>>8);
726     debug(":");
727     debug_hex8(action.kind.param & 0xff);
728     debug("]");
729 }