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