]> git.gir.st - tmk_keyboard.git/blob - common/action.c
Remove ACT_KEYMAP and ACT_OVERLAY
[tmk_keyboard.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 }
Imprint / Impressum