]> git.donarmstrong.com Git - tmk_firmware.git/blob - common/action.c
Remove ACT_KEYMAP and ACT_OVERLAY
[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(" keymaps: "); keymap_debug();
60     debug(" default_layer: "); debug_dec(default_layer); debug("\n");
61
62     switch (action.kind.id) {
63         /* Key and Mods */
64         case ACT_LMODS:
65         case ACT_RMODS:
66             {
67                 uint8_t mods = (action.kind.id == ACT_LMODS) ?  action.key.mods :
68                                                                 action.key.mods<<4;
69                 if (event.pressed) {
70                     uint8_t tmp_mods = host_get_mods();
71                     if (mods) {
72                         host_add_mods(mods);
73                         host_send_keyboard_report();
74                     }
75                     register_code(action.key.code);
76                     if (mods && action.key.code) {
77                         host_set_mods(tmp_mods);
78                         host_send_keyboard_report();
79                     }
80                 } else {
81                     if (mods && !action.key.code) {
82                         host_del_mods(mods);
83                         host_send_keyboard_report();
84                     }
85                     unregister_code(action.key.code);
86                 }
87             }
88             break;
89 #ifndef NO_ACTION_TAPPING
90         case ACT_LMODS_TAP:
91         case ACT_RMODS_TAP:
92             {
93                 uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ?  action.key.mods :
94                                                                     action.key.mods<<4;
95                 switch (action.layer.code) {
96     #ifndef NO_ACTION_ONESHOT
97                     case 0x00:
98                         // Oneshot modifier
99                         if (event.pressed) {
100                             if (tap_count == 0) {
101                                 debug("MODS_TAP: Oneshot: add_mods\n");
102                                 add_mods(mods);
103                             }
104                             else if (tap_count == 1) {
105                                 debug("MODS_TAP: Oneshot: start\n");
106                                 oneshot_start(mods);
107                             }
108                             else if (tap_count == TAPPING_TOGGLE) {
109                                 debug("MODS_TAP: Oneshot: toggle\n");
110                                 oneshot_toggle();
111                             }
112                             else {
113                                 debug("MODS_TAP: Oneshot: cancel&add_mods\n");
114                                 // double tap cancels oneshot and works as normal modifier.
115                                 oneshot_cancel();
116                                 add_mods(mods);
117                             }
118                         } else {
119                             if (tap_count == 0) {
120                                 debug("MODS_TAP: Oneshot: cancel/del_mods\n");
121                                 // cancel oneshot on hold
122                                 oneshot_cancel();
123                                 del_mods(mods);
124                             }
125                             else if (tap_count == 1) {
126                                 debug("MODS_TAP: Oneshot: del_mods\n");
127                                 // retain Oneshot
128                                 del_mods(mods);
129                             }
130                             else {
131                                 debug("MODS_TAP: Oneshot: del_mods\n");
132                                 // cancel Mods
133                                 del_mods(mods);
134                             }
135                         }
136                         break;
137     #endif
138                     default:
139                         if (event.pressed) {
140                             if (tap_count > 0) {
141                                 if (record->tap.interrupted) {
142                                     debug("MODS_TAP: Tap: Cancel: add_mods\n");
143                                     // ad hoc: set 0 to cancel tap
144                                     record->tap.count = 0;
145                                     add_mods(mods);
146                                 } else {
147                                     debug("MODS_TAP: Tap: register_code\n");
148                                     register_code(action.key.code);
149                                 }
150                             } else {
151                                 debug("MODS_TAP: No tap: add_mods\n");
152                                 add_mods(mods);
153                             }
154                         } else {
155                             if (tap_count > 0) {
156                                 debug("MODS_TAP: Tap: unregister_code\n");
157                                 unregister_code(action.key.code);
158                             } else {
159                                 debug("MODS_TAP: No tap: add_mods\n");
160                                 del_mods(mods);
161                             }
162                         }
163                         break;
164                 }
165             }
166             break;
167 #endif
168 #ifdef EXTRAKEY_ENABLE
169         /* other HID usage */
170         case ACT_USAGE:
171             switch (action.usage.page) {
172                 case PAGE_SYSTEM:
173                     if (event.pressed) {
174                         host_system_send(action.usage.code);
175                     } else {
176                         host_system_send(0);
177                     }
178                     break;
179                 case PAGE_CONSUMER:
180                     if (event.pressed) {
181                         host_consumer_send(action.usage.code);
182                     } else {
183                         host_consumer_send(0);
184                     }
185                     break;
186             }
187             break;
188 #endif
189 #ifdef MOUSEKEY_ENABLE
190         /* Mouse key */
191         case ACT_MOUSEKEY:
192             if (event.pressed) {
193                 mousekey_on(action.key.code);
194                 mousekey_send();
195             } else {
196                 mousekey_off(action.key.code);
197                 mousekey_send();
198             }
199             break;
200 #endif
201 #ifndef NO_ACTION_LAYER
202         case ACT_LAYER:
203         case ACT_LAYER1:
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                             keymap_clear();
211                             break;
212                         case ON_PRESS:
213                             if (event.pressed) {
214                                 keymap_clear();
215                             }
216                             break;
217                         case ON_RELEASE:
218                             if (!event.pressed) {
219                                 keymap_clear();
220                             }
221                             break;
222                         case ON_BOTH:
223                             keymap_clear();
224                             break;
225                         /* NOTE: 4-7 rserved */
226                     }
227                     break;
228                 /* Keymap Reset default layer */
229                 case (OP_RESET | ON_PRESS):
230                     if (event.pressed) {
231                         default_layer_set(action.layer.val);
232                     }
233                     break;
234                 case (OP_RESET | ON_RELEASE):
235                     if (!event.pressed) {
236                         default_layer_set(action.layer.val);
237                     }
238                     break;
239                 case (OP_RESET | ON_BOTH):
240                     default_layer_set(action.layer.val);
241                     break;
242
243                 /* Keymap Bit invert */
244                 case OP_INV:
245                     /* with tap toggle */
246                     if (event.pressed) {
247                         if (tap_count < TAPPING_TOGGLE) {
248                             debug("KEYMAP_INV: tap toggle(press).\n");
249                             keymap_invert(action.layer.val);
250                         }
251                     } else {
252                         if (tap_count <= TAPPING_TOGGLE) {
253                             debug("KEYMAP_INV: tap toggle(release).\n");
254                             keymap_invert(action.layer.val);
255                         }
256                     }
257                     break;
258                 case (OP_INV | ON_PRESS):
259                     if (event.pressed) {
260                         keymap_invert(action.layer.val);
261                     }
262                     break;
263                 case (OP_INV | ON_RELEASE):
264                     if (!event.pressed) {
265                         keymap_invert(action.layer.val);
266                     }
267                     break;
268                 case (OP_INV | ON_BOTH):
269                     keymap_invert(action.layer.val);
270                     break;
271
272                 /* Keymap Bit on */
273                 case OP_ON:
274                     if (event.pressed) {
275                         keymap_on(action.layer.val);
276                     } else {
277                         keymap_off(action.layer.val);
278                     }
279                     break;
280                 case (OP_ON | ON_PRESS):
281                     if (event.pressed) {
282                         keymap_on(action.layer.val);
283                     }
284                     break;
285                 case (OP_ON | ON_RELEASE):
286                     if (!event.pressed) {
287                         keymap_on(action.layer.val);
288                     }
289                     break;
290                 case (OP_ON | ON_BOTH):
291                     keymap_on(action.layer.val);
292                     break;
293
294                 /* Keymap Bit off */
295                 case OP_OFF:
296                     if (event.pressed) {
297                         keymap_off(action.layer.val);
298                     } else {
299                         keymap_on(action.layer.val);
300                     }
301                     break;
302                 case (OP_OFF | ON_PRESS):
303                     if (event.pressed) {
304                         keymap_off(action.layer.val);
305                     }
306                     break;
307                 case (OP_OFF | ON_RELEASE):
308                     if (!event.pressed) {
309                         keymap_off(action.layer.val);
310                     }
311                     break;
312                 case (OP_OFF | ON_BOTH):
313                     keymap_off(action.layer.val);
314                     break;
315
316                 /* Keymap Bit set */
317                 case OP_SET:
318                     if (event.pressed) {
319                         keymap_set(action.layer.val);
320                     } else {
321                         keymap_clear();
322                     }
323                     break;
324                 case (OP_SET | ON_PRESS):
325                     if (event.pressed) {
326                         keymap_set(action.layer.val);
327                     }
328                     break;
329                 case (OP_SET | ON_RELEASE):
330                     if (!event.pressed) {
331                         keymap_set(action.layer.val);
332                     }
333                     break;
334                 case (OP_SET | ON_BOTH):
335                     keymap_set(action.layer.val);
336                     break;
337
338                 /* Keymap Bit invert with tap key */
339                 default:
340                     if (event.pressed) {
341                         if (tap_count > 0) {
342                             debug("KEYMAP_TAP_KEY: Tap: register_code\n");
343                             register_code(action.layer.code);
344                         } else {
345                             debug("KEYMAP_TAP_KEY: No tap: On on press\n");
346                             keymap_on(action.layer.val);
347                         }
348                     } else {
349                         if (tap_count > 0) {
350                             debug("KEYMAP_TAP_KEY: Tap: unregister_code\n");
351                             unregister_code(action.layer.code);
352                         } else {
353                             debug("KEYMAP_TAP_KEY: No tap: Off on release\n");
354                             keymap_off(action.layer.val);
355                         }
356                     }
357                     break;
358             }
359             break;
360 #endif
361         /* Extentions */
362 #ifndef NO_ACTION_MACRO
363         case ACT_MACRO:
364             action_macro_play(action_get_macro(record, action.func.id, action.func.opt));
365             break;
366 #endif
367         case ACT_COMMAND:
368             break;
369 #ifndef NO_ACTION_FUNCTION
370         case ACT_FUNCTION:
371             action_function(record, action.func.id, action.func.opt);
372             break;
373 #endif
374         default:
375             break;
376     }
377 }
378
379
380
381
382 /*
383  * Utilities for actions.
384  */
385 void register_code(uint8_t code)
386 {
387     if (code == KC_NO) {
388         return;
389     }
390 #ifdef CAPSLOCK_LOCKING_ENABLE
391     else if (KC_LOCKING_CAPS == code) {
392 #ifdef CAPSLOCK_LOCKING_RESYNC_ENABLE
393         // Resync: ignore if caps lock already is on
394         if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) return;
395 #endif
396         host_add_key(KC_CAPSLOCK);
397         host_send_keyboard_report();
398         host_del_key(KC_CAPSLOCK);
399         host_send_keyboard_report();
400     }
401 #endif
402     else if IS_KEY(code) {
403         // TODO: should push command_proc out of this block?
404         if (command_proc(code)) return;
405
406 #ifndef NO_ACTION_ONESHOT
407         if (oneshot_state.mods && !oneshot_state.disabled) {
408             uint8_t tmp_mods = host_get_mods();
409             host_add_mods(oneshot_state.mods);
410
411             host_add_key(code);
412             host_send_keyboard_report();
413
414             host_set_mods(tmp_mods);
415             oneshot_cancel();
416         } else 
417 #endif
418         {
419             host_add_key(code);
420             host_send_keyboard_report();
421         }
422     }
423     else if IS_MOD(code) {
424         host_add_mods(MOD_BIT(code));
425         host_send_keyboard_report();
426     }
427 }
428
429 void unregister_code(uint8_t code)
430 {
431     if (code == KC_NO) {
432         return;
433     }
434 #ifdef CAPSLOCK_LOCKING_ENABLE
435     else if (KC_LOCKING_CAPS == code) {
436 #ifdef CAPSLOCK_LOCKING_RESYNC_ENABLE
437         // Resync: ignore if caps lock already is off
438         if (!(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK))) return;
439 #endif
440         host_add_key(KC_CAPSLOCK);
441         host_send_keyboard_report();
442         host_del_key(KC_CAPSLOCK);
443         host_send_keyboard_report();
444     }
445 #endif
446     else if IS_KEY(code) {
447         host_del_key(code);
448         host_send_keyboard_report();
449     }
450     else if IS_MOD(code) {
451         host_del_mods(MOD_BIT(code));
452         host_send_keyboard_report();
453     }
454 }
455
456 void add_mods(uint8_t mods)
457 {
458     if (mods) {
459         host_add_mods(mods);
460         host_send_keyboard_report();
461     }
462 }
463
464 void del_mods(uint8_t mods)
465 {
466     if (mods) {
467         host_del_mods(mods);
468         host_send_keyboard_report();
469     }
470 }
471
472 void set_mods(uint8_t mods)
473 {
474     host_set_mods(mods);
475     host_send_keyboard_report();
476 }
477
478 void clear_keyboard(void)
479 {
480     host_clear_mods();
481     clear_keyboard_but_mods();
482 }
483
484 void clear_keyboard_but_mods(void)
485 {
486     host_clear_keys();
487     host_send_keyboard_report();
488 #ifdef MOUSEKEY_ENABLE
489     mousekey_clear();
490     mousekey_send();
491 #endif
492 #ifdef EXTRAKEY_ENABLE
493     host_system_send(0);
494     host_consumer_send(0);
495 #endif
496 }
497
498 bool sending_anykey(void)
499 {
500     return (host_has_anykey() || host_mouse_in_use() ||
501             host_last_sysytem_report() || host_last_consumer_report());
502 }
503
504 bool is_tap_key(key_t key)
505 {
506     action_t action = layer_switch_get_action(key);
507
508     switch (action.kind.id) {
509         case ACT_LMODS_TAP:
510         case ACT_RMODS_TAP:
511             return true;
512         case ACT_LAYER:
513             switch (action.layer.code) {
514                 case 0x04 ... 0xEF:    /* tap key */
515                 case OP_INV:
516                     return true;
517                 default:
518                     return false;
519             }
520         case ACT_MACRO:
521         case ACT_FUNCTION:
522             if (action.func.opt & FUNC_TAP) { return true; }
523             return false;
524     }
525     return false;
526 }
527
528
529 /*
530  * debug print
531  */
532 void debug_event(keyevent_t event)
533 {
534     debug_hex16((event.key.row<<8) | event.key.col);
535     if (event.pressed) debug("d("); else debug("u(");
536     debug_dec(event.time); debug(")");
537 }
538
539 void debug_record(keyrecord_t record)
540 {
541     debug_event(record.event);
542 #ifndef NO_ACTION_TAPPING
543     debug(":"); debug_dec(record.tap.count);
544     if (record.tap.interrupted) debug("-");
545 #endif
546 }
547
548 void debug_action(action_t action)
549 {
550     switch (action.kind.id) {
551         case ACT_LMODS:             debug("ACT_LMODS");             break;
552         case ACT_RMODS:             debug("ACT_RMODS");             break;
553         case ACT_LMODS_TAP:         debug("ACT_LMODS_TAP");         break;
554         case ACT_RMODS_TAP:         debug("ACT_RMODS_TAP");         break;
555         case ACT_USAGE:             debug("ACT_USAGE");             break;
556         case ACT_MOUSEKEY:          debug("ACT_MOUSEKEY");          break;
557         case ACT_LAYER:             debug("ACT_LAYER");             break;
558         case ACT_LAYER_BITOP:       debug("ACT_LAYER_BITOP");       break;
559         case ACT_MACRO:             debug("ACT_MACRO");             break;
560         case ACT_COMMAND:           debug("ACT_COMMAND");           break;
561         case ACT_FUNCTION:          debug("ACT_FUNCTION");          break;
562         default:                    debug("UNKNOWN");               break;
563     }
564     debug("[");
565     debug_hex4(action.kind.param>>8);
566     debug(":");
567     debug_hex8(action.kind.param & 0xff);
568     debug("]");
569 }