]> git.gir.st - tmk_keyboard.git/blob - common/action.c
Remove test_func.
[tmk_keyboard.git] / common / action.c
1 #include "host.h"
2 #include "timer.h"
3 #include "keymap.h"
4 #include "keycode.h"
5 #include "keyboard.h"
6 #include "mousekey.h"
7 #include "command.h"
8 #include "util.h"
9 #include "debug.h"
10 #include "action.h"
11
12
13 static void process(keyrecord_t *record);
14
15 // TODO
16 /* layer */
17 uint8_t default_layer = 0;
18 uint8_t current_layer = 0;
19
20 /* tap term(ms) */
21 #define TAP_TERM 200
22
23 /* This counts up when tap occurs */
24 uint8_t tap_count = 0;
25 keyevent_t tapping_event = {};
26 keyrecord_t tapping_key = {};
27
28 /* TAPPING: This indicates that whether tap or not is not decided yet. */
29 // NOTE: keyevent_t.time 0 means no event.
30 #define IS_TAPPING() (tapping_key.event.time != 0)
31 #define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed)
32 #define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed)
33 #define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k)))
34 #define WITHIN_TAP_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAP_TERM)
35
36 /* waiting keys buffer */
37 #define WAITING_BUFFER_SIZE 8
38 static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {};
39 /* point to empty cell to enq */
40 static uint8_t waiting_buffer_head = 0;
41 /* point to the oldest data cell to deq */
42 static uint8_t waiting_buffer_tail = 0;
43
44 static bool waiting_buffer_enq(keyrecord_t record)
45 {
46 if (IS_NOEVENT(record.event)) {
47 return true;
48 }
49
50 if ((waiting_buffer_head + 1) % WAITING_BUFFER_SIZE == waiting_buffer_tail) {
51 debug("waiting_buffer_enq: Over flow.\n");
52 return false;
53 }
54
55 debug("waiting_buffer_enq["); debug_dec(waiting_buffer_head); debug("] = ");
56 debug_hex16(record.event.key.raw); debug("\n");
57
58 waiting_buffer[waiting_buffer_head] = record;
59 waiting_buffer_head = (waiting_buffer_head + 1) % WAITING_BUFFER_SIZE;
60 return true;
61 }
62 static keyrecord_t waiting_buffer_deq(void)
63 {
64 if (waiting_buffer_head == waiting_buffer_tail) {
65 return (keyrecord_t){};
66 }
67 uint8_t last_tail = waiting_buffer_tail;
68 waiting_buffer_tail = waiting_buffer_tail + 1 % WAITING_BUFFER_SIZE;
69 return waiting_buffer[last_tail];
70 }
71 static bool waiting_buffer_is_empty(void)
72 {
73 return (waiting_buffer_head == waiting_buffer_tail);
74 }
75 static void waiting_buffer_clear(void)
76 {
77 waiting_buffer_head = 0;
78 waiting_buffer_tail = 0;
79 }
80 static bool waiting_buffer_typed(keyevent_t event)
81 {
82 for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
83 if (KEYEQ(event.key, waiting_buffer[i].event.key) && event.pressed != waiting_buffer[i].event.pressed) {
84 return true;
85 }
86 }
87 return false;
88 }
89 static bool waiting_buffer_has_anykey_pressed(void)
90 {
91 for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
92 if (waiting_buffer[i].event.pressed) return true;
93 }
94 return false;
95 }
96 static void waiting_buffer_process(void)
97 {
98 }
99
100
101 /*
102 * Rule to judge tap:
103 * Tap key is typed(pressed and released) within TAP_TERM
104 * without interfaring by typing other key.
105 */
106 /* return true when key event is processed. */
107 static bool process_tap(keyrecord_t *keyp)
108 {
109 keyevent_t event = keyp->event;
110
111 // if tapping
112 if (IS_TAPPING_PRESSED()) {
113 if (WITHIN_TAP_TERM(event)) {
114 if (tapping_key.tap_count == 0) {
115 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
116 // first tap!
117 debug("Tapping: First tap.\n");
118 tapping_key.tap_count = 1;
119 process(&tapping_key);
120
121 // enqueue
122 keyp->tap_count = tapping_key.tap_count;
123 return false;
124 } else if (!event.pressed && waiting_buffer_typed(event)) {
125 // other key typed. not tap.
126 debug("Tapping: End(No tap. Interfered by typing key).\n");
127 process(&tapping_key);
128 tapping_key = (keyrecord_t){};
129
130 // enqueue
131 return false;
132 } else {
133 // other key events shall be stored till tapping state settles.
134 return false;
135 }
136 } else {
137 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
138 keyp->tap_count = tapping_key.tap_count;
139 debug("Tapping: tap release("); debug_dec(keyp->tap_count); debug(")\n");
140 tapping_key = *keyp;
141 return false;
142 }
143 else if (is_tap_key(keyp->event.key) && event.pressed) {
144 debug("Tapping: Start with forcing to release last tap.\n");
145 process(&(keyrecord_t){
146 .tap_count = tapping_key.tap_count,
147 .event.key = tapping_key.event.key,
148 .event.time = event.time,
149 .event.pressed = false
150 });
151 tapping_key = *keyp;
152 return false;
153 }
154 else {
155 if (!IS_NOEVENT(keyp->event)) debug("Tapping: key event while tap.\n");
156 process(keyp);
157 return true;
158 }
159 }
160 }
161 // not within TAP_TERM
162 else {
163 if (tapping_key.tap_count == 0) {
164 // timeout. not tap.
165 debug("Tapping: End. Not tap(time out).\n");
166 process(&tapping_key);
167 tapping_key = (keyrecord_t){};
168 return false;
169 } else {
170 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
171 debug("Tapping: End. tap release.");
172 keyp->tap_count = tapping_key.tap_count;
173 process(keyp);
174 tapping_key = (keyrecord_t){};
175 return true;
176 } else {
177 // other key after tap time out.
178 process(keyp);
179 return true;
180 }
181 }
182 }
183 } else if (IS_TAPPING_RELEASED()) {
184 if (WITHIN_TAP_TERM(event)) {
185 if (tapping_key.tap_count > 0 && IS_TAPPING_KEY(event.key) && event.pressed) {
186 // sequential tap.
187 keyp->tap_count = tapping_key.tap_count + 1;
188 debug("Tapping: tap press("); debug_dec(keyp->tap_count); debug(")\n");
189 process(keyp);
190 tapping_key = *keyp;
191 return true;
192 } else if (event.pressed && is_tap_key(event.key)) {
193 // Sequential tap can be interfered with other tap key.
194 debug("Tapping: Start with interfering other tap.\n");
195 tapping_key = *keyp;
196 return true;
197 } else {
198 if (!IS_NOEVENT(keyp->event)) debug("Tapping: other key just after tap.\n");
199 process(keyp);
200 return true;
201 }
202 } else {
203 // timeout. no sequential tap.
204 debug("Tapping: End(Time out after releasing last tap).\n");
205 tapping_key = (keyrecord_t){};
206 process(keyp);
207 return true;
208 }
209 } else {
210 if (event.pressed && is_tap_key(event.key)) {
211 debug("Tapping: Start(Press tap key).\n");
212 tapping_key = *keyp;
213 return true;
214 } else {
215 process(keyp);
216 return true;
217 }
218 }
219 }
220
221 void action_exec(keyevent_t event)
222 {
223 if (!IS_NOEVENT(event)) {
224 debug("event: ");
225 debug_hex16(event.time); debug(": ");
226 debug_hex16(event.key.raw);
227 debug("[");
228 if (event.pressed) debug("down"); else debug("up");
229 debug("]\n");
230 }
231
232 keyrecord_t record = { .event = event };
233
234 // pre-process on tapping
235 if (process_tap(&record)) {
236 if (!IS_NOEVENT(record.event)) debug("processed.\n");
237 } else {
238 if (!IS_NOEVENT(record.event)) debug("enqueued.\n");
239 if (!waiting_buffer_enq(record)) {
240 // clear all in case of overflow.
241 clear_keyboard();
242 waiting_buffer_clear();
243 tapping_key = (keyrecord_t){};
244 }
245 }
246
247 // TODO: need to process every time?
248 // process waiting_buffer
249 for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) {
250 if (process_tap(&waiting_buffer[waiting_buffer_tail])) {
251 debug("processed: waiting_buffer["); debug_dec(waiting_buffer_tail); debug("] = ");
252 debug_hex16(waiting_buffer[waiting_buffer_tail].event.key.raw); debug("\n");
253 } else {
254 break;
255 }
256 }
257 }
258
259 static void process(keyrecord_t *record)
260 {
261 // TODO: use record
262 keyevent_t event = record->event;
263 uint8_t tap_count = record->tap_count;
264
265 if (IS_NOEVENT(event)) { return; }
266
267 action_t action = keymap_get_action(current_layer, event.key.pos.row, event.key.pos.col);
268 debug("action: "); debug_hex16(action.code);
269 if (event.pressed) debug("[down]\n"); else debug("[up]\n");
270
271 switch (action.kind.id) {
272 /* Key and Mods */
273 case ACT_LMODS:
274 // |pressed |released
275 // --------------+---------------------------------+------------
276 // key |down(key) |up(key)
277 // mods |add(mods) |del(mods)
278 // key with mods |add(mods), down(key), unset(mods)|up(key)
279 if (event.pressed) {
280 uint8_t tmp_mods = host_get_mods();
281 if (action.key.mods) {
282 host_add_mods(action.key.mods);
283 host_send_keyboard_report();
284 }
285 register_code(action.key.code);
286 if (action.key.mods && action.key.code) {
287 host_set_mods(tmp_mods);
288 host_send_keyboard_report();
289 }
290 } else {
291 if (action.key.mods && !action.key.code) {
292 host_del_mods(action.key.mods);
293 host_send_keyboard_report();
294 }
295 unregister_code(action.key.code);
296 }
297 break;
298 case ACT_RMODS:
299 // |pressed |released
300 // --------------+---------------------------------+------------
301 // key |down(key) |up(key)
302 // mods |add(mods) |del(mods)
303 // key with mods |add(mods), down(key), unset(mods)|up(key)
304 if (event.pressed) {
305 uint8_t tmp_mods = host_get_mods();
306 if (action.key.mods) {
307 host_add_mods(action.key.mods<<4);
308 host_send_keyboard_report();
309 }
310 register_code(action.key.code);
311 if (action.key.mods && action.key.code) {
312 host_set_mods(tmp_mods);
313 host_send_keyboard_report();
314 }
315 } else {
316 if (action.key.mods && !action.key.code) {
317 host_del_mods(action.key.mods<<4);
318 host_send_keyboard_report();
319 }
320 unregister_code(action.key.code);
321 }
322 break;
323 case ACT_LMODS_TAP:
324 case ACT_RMODS_TAP:
325 {
326 uint8_t tmp_mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods :
327 action.key.mods<<4;
328 if (event.pressed) {
329 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
330 if (waiting_buffer_has_anykey_pressed()) {
331 debug("MODS_TAP: Tap: Cancel: add_mods\n");
332 // ad hoc: set 0 to cancel tap
333 record->tap_count = 0;
334 add_mods(tmp_mods);
335 } else {
336 debug("MODS_TAP: Tap: register_code\n");
337 register_code(action.key.code);
338 }
339 } else {
340 debug("MODS_TAP: No tap: add_mods\n");
341 add_mods(tmp_mods);
342 }
343 } else {
344 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
345 debug("MODS_TAP: Tap: unregister_code\n");
346 unregister_code(action.key.code);
347 } else {
348 debug("MODS_TAP: No tap: add_mods\n");
349 del_mods(tmp_mods);
350 }
351 }
352 }
353 break;
354
355 /* other HID usage */
356 case ACT_USAGE:
357 #ifdef EXTRAKEY_ENABLE
358 switch (action.usage.page) {
359 case ACTION_USAGE_PAGE_SYSTEM:
360 if (event.pressed) {
361 host_system_send(action.usage.code);
362 } else {
363 host_system_send(0);
364 }
365 break;
366 case ACTION_USAGE_PAGE_CONSUMER:
367 if (event.pressed) {
368 host_consumer_send(action.usage.code);
369 } else {
370 host_consumer_send(0);
371 }
372 break;
373 }
374 #endif
375 break;
376
377 /* Mouse key */
378 case ACT_MOUSEKEY:
379 #ifdef MOUSEKEY_ENABLE
380 if (event.pressed) {
381 mousekey_on(action.key.code);
382 mousekey_send();
383 } else {
384 mousekey_off(action.key.code);
385 mousekey_send();
386 }
387 #endif
388 break;
389
390 /* Layer key */
391 case ACT_LAYER_PRESSED:
392 // layer action when pressed
393 switch (action.layer.code) {
394 case 0x00:
395 if (event.pressed) {
396 layer_switch(action.layer.opt);
397 }
398 break;
399 case 0xF0:
400 // TODO: tap toggle
401 break;
402 case 0xFF:
403 if (event.pressed) {
404 default_layer = action.layer.opt;
405 layer_switch(default_layer);
406 }
407 break;
408 default:
409 // with tap key
410 if (event.pressed) {
411 if (IS_TAPPING_KEY(event.key)) {
412 if (tap_count > 0) {
413 debug("LAYER_PRESSED: Tap: register_code\n");
414 register_code(action.layer.code);
415 } else {
416 debug("LAYER_PRESSED: No tap: layer_switch\n");
417 layer_switch(action.layer.opt);
418 }
419 } else {
420 // TODO: while other key tapping
421 debug("LAYER_PRESSED: No tap: layer_switch\n");
422 layer_switch(action.layer.opt);
423 }
424 /*
425 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
426 debug("LAYER_PRESSED: Tap: register_code\n");
427 register_code(action.layer.code);
428 } else {
429 debug("LAYER_PRESSED: No tap: layer_switch\n");
430 layer_switch(action.layer.opt);
431 }
432 */
433 } else {
434 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
435 debug("LAYER_PRESSED: Tap: unregister_code\n");
436 unregister_code(action.layer.code);
437 } else {
438 debug("LAYER_PRESSED: No tap: NO ACTION\n");
439 }
440 }
441 break;
442 }
443 break;
444 case ACT_LAYER_RELEASED:
445 switch (action.layer.code) {
446 case 0x00:
447 if (!event.pressed) {
448 layer_switch(action.layer.opt);
449 }
450 break;
451 case 0xF0:
452 // Ignored. LAYER_RELEASED with tap toggle is invalid action.
453 break;
454 case 0xFF:
455 if (!event.pressed) {
456 default_layer = action.layer.opt;
457 layer_switch(default_layer);
458 }
459 break;
460 default:
461 // Ignored. LAYER_RELEASED with tap key is invalid action.
462 break;
463 }
464 break;
465 case ACT_LAYER_BIT:
466 switch (action.layer.code) {
467 case 0x00:
468 if (event.pressed) {
469 layer_switch(current_layer | action.layer.opt);
470 } else {
471 layer_switch(current_layer & ~action.layer.opt);
472 }
473 break;
474 case 0xF0:
475 // TODO: tap toggle
476 break;
477 case 0xFF:
478 // change default layer
479 if (event.pressed) {
480 default_layer = current_layer | action.layer.opt;
481 layer_switch(default_layer);
482 } else {
483 default_layer = current_layer & ~action.layer.opt;
484 layer_switch(default_layer);
485 }
486 break;
487 default:
488 // with tap key
489 if (event.pressed) {
490 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
491 debug("LAYER_BIT: Tap: register_code\n");
492 register_code(action.layer.code);
493 } else {
494 debug("LAYER_BIT: No tap: layer_switch(bit on)\n");
495 layer_switch(current_layer | action.layer.opt);
496 }
497 } else {
498 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
499 debug("LAYER_BIT: Tap: unregister_code\n");
500 unregister_code(action.layer.code);
501 } else {
502 debug("LAYER_BIT: No tap: layer_switch(bit off)\n");
503 layer_switch(current_layer & ~action.layer.opt);
504 }
505 }
506 break;
507 }
508 case ACT_LAYER_EXT:
509 switch (action.layer.opt) {
510 case 0x00:
511 // set default layer when pressed
512 switch (action.layer.code) {
513 case 0x00:
514 if (event.pressed) {
515 layer_switch(default_layer);
516 }
517 break;
518 case 0xF0:
519 // TODO: tap toggle
520 break;
521 case 0xFF:
522 if (event.pressed) {
523 default_layer = current_layer;
524 layer_switch(default_layer);
525 }
526 break;
527 default:
528 // TODO: tap key
529 break;
530 }
531 break;
532 case 0x01:
533 // set default layer when released
534 switch (action.layer.code) {
535 case 0x00:
536 if (!event.pressed) {
537 layer_switch(default_layer);
538 }
539 break;
540 case 0xFF:
541 if (!event.pressed) {
542 default_layer = current_layer;
543 layer_switch(default_layer);
544 }
545 break;
546 case 0xF0:
547 default:
548 // Ignore tap.
549 if (!event.pressed) {
550 layer_switch(default_layer);
551 }
552 break;
553 }
554 break;
555 }
556 break;
557
558 /* Extentions */
559 case ACT_MACRO:
560 break;
561 case ACT_COMMAND:
562 break;
563 case ACT_FUNCTION:
564 action_call_function(event, action.func.id);
565 break;
566 default:
567 break;
568 }
569 }
570
571
572 /*
573 * Utilities for actions.
574 */
575 void register_code(uint8_t code)
576 {
577 if (code == KC_NO) {
578 return;
579 }
580 else if IS_KEY(code) {
581 // TODO: should push command_proc out of this block?
582 if (!command_proc(code)) {
583 host_add_key(code);
584 host_send_keyboard_report();
585 }
586 }
587 else if IS_MOD(code) {
588 host_add_mods(MOD_BIT(code));
589 host_send_keyboard_report();
590 }
591 }
592
593 void unregister_code(uint8_t code)
594 {
595 if IS_KEY(code) {
596 host_del_key(code);
597 host_send_keyboard_report();
598 }
599 else if IS_MOD(code) {
600 host_del_mods(MOD_BIT(code));
601 host_send_keyboard_report();
602 }
603 }
604
605 void add_mods(uint8_t mods)
606 {
607 if (mods) {
608 host_add_mods(mods);
609 host_send_keyboard_report();
610 }
611 }
612
613 void del_mods(uint8_t mods)
614 {
615 if (mods) {
616 host_del_mods(mods);
617 host_send_keyboard_report();
618 }
619 }
620
621 void set_mods(uint8_t mods)
622 {
623 host_set_mods(mods);
624 host_send_keyboard_report();
625 }
626
627 void clear_keyboard(void)
628 {
629 host_clear_mods();
630 clear_keyboard_but_mods();
631 }
632
633 void clear_keyboard_but_mods(void)
634 {
635 host_clear_keys();
636 host_send_keyboard_report();
637 #ifdef MOUSEKEY_ENABLE
638 mousekey_clear();
639 mousekey_send();
640 #endif
641 #ifdef EXTRAKEY_ENABLE
642 host_system_send(0);
643 host_consumer_send(0);
644 #endif
645 }
646
647 bool sending_anykey(void)
648 {
649 return (host_has_anykey() || host_mouse_in_use() ||
650 host_last_sysytem_report() || host_last_consumer_report());
651 }
652
653 void layer_switch(uint8_t new_layer)
654 {
655 if (current_layer != new_layer) {
656 debug("Layer Switch: "); debug_hex(current_layer);
657 debug(" -> "); debug_hex(new_layer); debug("\n");
658
659 current_layer = new_layer;
660 clear_keyboard_but_mods(); // To avoid stuck keys
661 // TODO: update mods with full scan of matrix? if modifier changes between layers
662 }
663 }
664
665 bool is_tap_key(key_t key)
666 {
667 action_t action = keymap_get_action(current_layer, key.pos.row, key.pos.col);
668 switch (action.kind.id) {
669 case ACT_LMODS_TAP:
670 case ACT_RMODS_TAP:
671 return true;
672 case ACT_LAYER_PRESSED:
673 case ACT_LAYER_BIT:
674 switch (action.layer.code) {
675 case 0x00:
676 case 0xF1 ... 0xFF:
677 return false;
678 case 0xF0:
679 default:
680 return true;
681 }
682 return false;
683 case ACT_FUNCTION:
684 if (action.func.opt & 0x1) {
685 return true;
686 }
687 return false;
688 }
689 return false;
690 }
Imprint / Impressum