]> git.donarmstrong.com Git - tmk_firmware.git/blob - common/action.c
Fix tap key using delaying_layer and waiting_key.
[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 #define Kdebug(s)       do { if (debug_keyboard) debug(s); } while(0)
13 #define Kdebug_P(s)     do { if (debug_keyboard) debug_P(s); } while(0)
14 #define Kdebug_hex(s)   do { if (debug_keyboard) debug_hex(s); } while(0)
15
16
17 /*
18  *
19  * Event/State|IDLE          PRESSING      DELAYING[f]      WAITING[f,k]         
20  * -----------+------------------------------------------------------------------
21  * Fn  Down   |(L+)          -*1           WAITING(Sk)      IDLE(Rf,Ps)*7        
22  *     Up     |(L-)          IDLE(L-)*8    IDLE(L-)*8       IDLE(L-)*8           
23  * Fnk Down   |DELAYING(Sf)* (Rf)          WAITING(Sk)      IDLE(Rf,Ps,Rf)       
24  *     Up     |(L-)          IDLE(L-/Uf)*8 IDLE(Rf,Uf/L-)*3 IDLE(Rf,Ps,Uf/L-)*3  
25  * Key Down   |PRESSING(Rk)  (Rk)          WAITING(Sk)      IDLE(Rf,Ps,Rk)       
26  *     Up     |(Uk)          IDLE(Uk)*4    (Uk)             IDLE(L+,Ps,Pk)/(Uk)*a
27  *            |
28  * Delay      |-             -             IDLE(L+)         IDLE(L+,Ps)          
29  * Magic Key  |COMMAND*5
30  *
31  * *1: ignore Fn if other key is down.
32  * *2: register Fnk if any key is pressing
33  * *3: register/unregister delayed Fnk and move to IDLE if code == delayed Fnk, else *8
34  * *4: if no keys registered to host
35  * *5: unregister all keys
36  * *6: only if no keys down
37  * *7: ignore Fn because Fnk key and stored key are down.
38  * *8: move to IDLE if layer switch(off) occurs, else stay at current state
39  * *9: repeat key if pressing Fnk twice quickly(move to PRESSING)
40  * *a: layer switch and process waiting key and code if code == wainting key, else unregister key
41  *
42  * States:
43  *      IDLE: No key is down except modifiers
44  *      DELAYING: delay layer switch after pressing Fn with alt keycode
45  *      WAITING: key is pressed during DELAYING
46  *
47  * Events:
48  *      Fn: Fn key without alternative keycode
49  *      Fnk: Fn key with alternative keycode
50  *      -: ignore
51  *      Delay: layer switch delay term is elapsed
52  *
53  * Actions:
54  *      Rk: register key
55  *      Uk: unregister key
56  *      Rf: register Fn(alt keycode)
57  *      Uf: unregister Fn(alt keycode)
58  *      Rs: register stored key
59  *      Us: unregister stored key
60  *      Sk: Store key(waiting Key)
61  *      Sf: Store Fn(delayed Fn)
62  *      Ps: Process stored key
63  *      Ps: Process key
64  *      Is: Interpret stored keys in current layer
65  *      L+: Switch to new layer(*unregister* all keys but modifiers)
66  *      L-: Switch back to last layer(*unregister* all keys but modifiers)
67  *      Ld: Switch back to default layer(*unregister* all keys but modifiers)
68  */
69
70
71 typedef enum { IDLE, DELAYING, WAITING, PRESSING } kbdstate_t;
72 #define NEXT(state)     do { \
73     Kdebug("NEXT: "); Kdebug_P(state_str(kbdstate)); \
74     kbdstate = state; \
75     Kdebug(" -> "); Kdebug_P(state_str(kbdstate)); Kdebug("\n"); \
76 } while (0)
77
78
79 static kbdstate_t kbdstate = IDLE;
80 static uint8_t fn_state_bits = 0;
81
82 static const char *state_str(kbdstate_t state)
83 {
84     if (state == IDLE)      return PSTR("IDLE");
85     if (state == DELAYING)  return PSTR("DELAYING");
86     if (state == WAITING)   return PSTR("WAITING");
87     if (state == PRESSING)  return PSTR("PRESSING");
88     return PSTR("UNKNOWN");
89 }
90 static bool anykey_sent_to_host(void)
91 {
92     return (host_has_anykey() || host_mouse_in_use() ||
93             host_last_sysytem_report() || host_last_consumer_report());
94 }
95
96
97 static void register_code(uint8_t code);
98 static void unregister_code(uint8_t code);
99 static void register_mods(uint8_t mods);
100 static void unregister_mods(uint8_t mods);
101 static void clear_keyboard(void);
102 static void clear_keyboard_but_mods(void);
103 static void layer_switch(uint8_t new_layer);
104
105
106 /* tap */
107 #define TAP_TIME    200
108 #define LAYER_DELAY 200
109 static keyevent_t last_event = {};
110 static uint16_t last_event_time = 0;
111 static uint8_t tap_count = 0;
112
113 /* layer */
114 uint8_t default_layer = 0;
115 uint8_t current_layer = 0;
116 keyrecord_t delaying_layer = {};
117
118 keyrecord_t waiting_key = {};
119
120 // TODO: ring buffer: waiting_keys[]
121 /*
122 #define WAITING_KEYS_BUFFER 3
123 static keyrecord_t waiting_keys[WAITING_KEYS_BUFFER] = {};
124 static uint8_t waiting_keys_head = 0;
125 static uint8_t waiting_keys_tail = 0;
126 static void waiting_key_queue(keyevent_t event)
127 {
128 }
129 static void waiting_key_dequeue(keyevent_t event)
130 {
131 }
132 */
133
134 static void process(keyevent_t event, action_t action)
135 {
136     //action_t action = keymap_get_action(current_layer, event.key.row, event.key.col);
137
138     debug("action: "); debug_hex16(action.code); debug("\n");
139     debug("kind.id: "); debug_hex(action.kind.id); debug("\n");
140     debug("kind.param: "); debug_hex16(action.kind.param); debug("\n");
141     debug("key.code: "); debug_hex(action.key.code); debug("\n");
142     debug("key.mods: "); debug_hex(action.key.mods); debug("\n");
143
144     switch (action.kind.id) {
145         /* Key and Mods */
146         case ACT_LMODS:
147             // normal key or key plus mods
148             if (event.pressed) {
149                 uint8_t tmp_mods = host_get_mods();
150                 if (action.key.mods) {
151                     host_add_mods(action.key.mods);
152                     host_send_keyboard_report();
153                 }
154                 register_code(action.key.code);
155                 if (action.key.mods && action.key.code) {
156                     host_set_mods(tmp_mods);
157                     host_send_keyboard_report();
158                 }
159             } else {
160                 if (action.key.mods && !action.key.code) {
161                     host_del_mods(action.key.mods);
162                     host_send_keyboard_report();
163                 }
164                 unregister_code(action.key.code);
165             }
166             break;
167         case ACT_RMODS:
168             if (event.pressed) {
169                 uint8_t tmp_mods = host_get_mods();
170                 if (action.key.mods) {
171                     host_add_mods(action.key.mods<<4);
172                     host_send_keyboard_report();
173                 }
174                 register_code(action.key.code);
175                 if (action.key.mods && action.key.code) {
176                     host_set_mods(tmp_mods);
177                     host_send_keyboard_report();
178                 }
179             } else {
180                 if (action.key.mods && !action.key.code) {
181                     host_del_mods(action.key.mods<<4);
182                     host_send_keyboard_report();
183                 }
184                 unregister_code(action.key.code);
185             }
186             break;
187         case ACT_LMOD_TAP:
188             break;
189         case ACT_RMOD_TAP:
190             break;
191
192         /* other HID usage */
193         case ACT_USAGE:
194 #ifdef EXTRAKEY_ENABLE
195             switch (action.usage.page) {
196                 case ACTION_USAGE_PAGE_SYSTEM:
197                     if (event.pressed) {
198                         host_system_send(action.usage.code);
199                     } else {
200                         host_system_send(0);
201                     }
202                     break;
203                 case ACTION_USAGE_PAGE_CONSUMER:
204                     if (event.pressed) {
205                         host_consumer_send(action.usage.code);
206                     } else {
207                         host_consumer_send(0);
208                     }
209                     break;
210             }
211 #endif
212             break;
213
214         /* Mouse key */
215         case ACT_MOUSEKEY:
216 #ifdef MOUSEKEY_ENABLE
217             if (event.pressed) {
218                 mousekey_on(action.key.code);
219                 mousekey_send();
220             } else {
221                 mousekey_off(action.key.code);
222                 mousekey_send();
223             }
224 #endif
225             break;
226
227         /* Layer key */
228         case ACT_LAYER_PRESSED:
229             // layer action when pressed
230             switch (action.layer.code) {
231                 case 0x00:
232                     if (event.pressed) {
233                         layer_switch(action.layer.opt);
234                     }
235                     break;
236                 case 0xF0:
237                     // TODO: tap toggle
238                     break;
239                 case 0xFF:
240                     if (event.pressed) {
241                         default_layer = action.layer.opt;
242                         layer_switch(default_layer);
243                     }
244                     break;
245                 default:
246                     // with tap key
247                     debug("tap: "); debug_hex(tap_count); debug("\n");
248                     if (event.pressed) {
249                         if (tap_count == 0) {
250                             if (host_has_anykey()) {
251                                 register_code(action.layer.code);
252                             } else {
253                                 delaying_layer = (keyrecord_t){
254                                     .event = event,
255                                     .action = action,
256                                     .mods = host_get_mods()
257                                 };
258                             }
259                         } else if (tap_count > 0) {
260                             register_code(action.layer.code);
261                         }
262                     } else {
263                         // tap key
264                         if (KEYEQ(event.key, delaying_layer.event.key) &&
265                                 timer_elapsed(delaying_layer.event.time) < TAP_TIME) {
266                             uint8_t tmp_mods = host_get_mods();
267                             host_set_mods(delaying_layer.mods);
268                             register_code(delaying_layer.action.layer.code);
269                             host_set_mods(tmp_mods);
270                             unregister_code(delaying_layer.action.layer.code);
271                         } else {
272                             unregister_code(action.layer.code);
273                         }
274                         delaying_layer = (keyrecord_t){};
275                     }
276                     break;
277             }
278             break;
279         case ACT_LAYER_RELEASED:
280             switch (action.layer.code) {
281                 case 0x00:
282                     if (event.pressed) {
283                         layer_switch(action.layer.opt);
284                     }
285                     break;
286                 case 0xF0:
287                     // Ignored. LAYER_RELEASED with tap toggle is invalid action.
288                     break;
289                 case 0xFF:
290                     if (!event.pressed) {
291                         default_layer = action.layer.opt;
292                         layer_switch(default_layer);
293                     }
294                     break;
295                 default:
296                     // Ignored. LAYER_RELEASED with tap key is invalid action.
297                     break;
298             }
299             break;
300         case ACT_LAYER_BIT:
301             switch (action.layer.code) {
302                 case 0x00:
303                     if (event.pressed) {
304                         layer_switch(current_layer | action.layer.opt);
305                     } else {
306                         layer_switch(current_layer & ~action.layer.opt);
307                     }
308                     break;
309                 case 0xF0:
310                     // TODO: tap toggle
311                     break;
312                 case 0xFF:
313                     // change default layer
314                     if (event.pressed) {
315                         default_layer = current_layer | action.layer.opt;
316                         layer_switch(default_layer);
317                     } else {
318                         default_layer = current_layer & ~action.layer.opt;
319                         layer_switch(default_layer);
320                     }
321                     break;
322                 default:
323                     // with tap key
324                     debug("tap: "); debug_hex(tap_count); debug("\n");
325                     if (event.pressed) {
326                         if (tap_count == 0) {
327                             if (host_has_anykey()) {
328                                 register_code(action.layer.code);
329                             } else {
330                                 delaying_layer = (keyrecord_t){
331                                     .event = event,
332                                     .action = action,
333                                     .mods = keyboard_report->mods
334                                 };
335                             }
336                         } else if (tap_count > 0) {
337                             register_code(action.layer.code);
338                         }
339                     } else {
340                         if (tap_count == 0) {
341                             // no tap
342                             layer_switch(current_layer & ~action.layer.opt);
343                         } else if (tap_count == 1) {
344                             // tap
345                             register_code(action.layer.code);
346                         }
347                         unregister_code(action.layer.code);
348                     }
349                     break;
350             }
351         case ACT_LAYER_EXT:
352             switch (action.layer.opt) {
353                 case 0x00:
354                     // set default layer when pressed
355                     switch (action.layer.code) {
356                         case 0x00:
357                             if (event.pressed) {
358                                 layer_switch(default_layer);
359                             }
360                             break;
361                         case 0xF0:
362                             // TODO: tap toggle
363                             break;
364                         case 0xFF:
365                             if (event.pressed) {
366                                 default_layer = current_layer;
367                                 layer_switch(default_layer);
368                             }
369                             break;
370                         default:
371                             // TODO: tap key
372                             break;
373                     }
374                     break;
375                 case 0x01:
376                     // set default layer when released
377                     switch (action.layer.code) {
378                         case 0x00:
379                             if (!event.pressed) {
380                                 layer_switch(default_layer);
381                             }
382                             break;
383                         case 0xFF:
384                             if (!event.pressed) {
385                                 default_layer = current_layer;
386                                 layer_switch(default_layer);
387                             }
388                             break;
389                         case 0xF0:
390                         default:
391                             // Ignore tap.
392                             if (!event.pressed) {
393                                 layer_switch(default_layer);
394                             }
395                             break;
396                     }
397                     break;
398             }
399             break;
400
401         /* Extentions */
402         case ACT_MACRO:
403         case ACT_COMMAND:
404         case ACT_FUNCTION:
405         default:
406             break;
407     }
408 }
409
410 void action_exec(keyevent_t event)
411 {
412     /* count tap when key is up */
413     if (KEYEQ(event.key, last_event.key) && timer_elapsed(last_event_time) < TAP_TIME) {
414         if (!event.pressed) tap_count++;
415     } else {
416         tap_count = 0;
417     }
418
419     /* When delaying layer switch */
420     if (delaying_layer.action.code) {
421         /* Layer switch when delay time elapses or waiting key is released */
422         if ((timer_elapsed(delaying_layer.event.time) > LAYER_DELAY) ||
423             (!event.pressed && KEYEQ(event.key, waiting_key.event.key))) {
424             /* layer switch */
425             switch (delaying_layer.action.kind.id) {
426                 case ACT_LAYER_PRESSED:
427                     layer_switch(delaying_layer.action.layer.opt);
428                     break;
429                 case ACT_LAYER_BIT:
430                     layer_switch(current_layer | delaying_layer.action.layer.opt);
431                     break;
432             }
433             delaying_layer = (keyrecord_t){};
434
435             /* Process waiting keys in new layer */
436             if (waiting_key.event.time) {
437                 uint8_t tmp_mods = host_get_mods();
438                 host_set_mods(waiting_key.mods);
439                 process(waiting_key.event, keymap_get_action(current_layer,
440                                                              waiting_key.event.key.row,
441                                                              waiting_key.event.key.col));
442                 host_set_mods(tmp_mods);
443                 waiting_key = (keyrecord_t){};
444             }
445         }
446         /* when delaying layer key is released within delay term */
447         else if (!event.pressed && KEYEQ(event.key, delaying_layer.event.key)) {
448             /* tap key down */
449             uint8_t tmp_mods = host_get_mods();
450             host_set_mods(delaying_layer.mods);
451             register_code(delaying_layer.action.layer.code);
452             delaying_layer = (keyrecord_t){};
453
454             /* process waiting keys */
455             if (waiting_key.event.time) {
456                 host_set_mods(waiting_key.mods);
457                 process(waiting_key.event, waiting_key.action);
458                 waiting_key = (keyrecord_t){};
459             }
460             host_set_mods(tmp_mods);
461         }
462     }
463
464     action_t action = keymap_get_action(current_layer, event.key.row, event.key.col);
465
466     /* postpone key-down events while delaying layer */
467     if (delaying_layer.action.code) {
468         if (event.pressed) {
469             // TODO: waiting_keys[]
470             waiting_key = (keyrecord_t){
471                 .event = event,
472                 .action = action,
473                 .mods = host_get_mods()
474             };
475         } else {
476             process(event, action);
477         }
478     } else {
479         process(event, action);
480     }
481
482     /* last event */
483     last_event = event;
484     last_event_time = timer_read();
485 }
486
487
488 static void register_code(uint8_t code)
489 {
490     if (code == KC_NO) {
491         return;
492     }
493     else if IS_KEY(code) {
494         // TODO: should push command_proc out of this block?
495         if (!command_proc(code)) {
496             host_add_key(code);
497             host_send_keyboard_report();
498         }
499     }
500     else if IS_MOD(code) {
501         host_add_mods(MOD_BIT(code));
502         host_send_keyboard_report();
503     }
504 }
505
506 static void unregister_code(uint8_t code)
507 {
508     if IS_KEY(code) {
509         host_del_key(code);
510         host_send_keyboard_report();
511     }
512     else if IS_MOD(code) {
513         host_del_mods(MOD_BIT(code));
514         host_send_keyboard_report();
515     }
516 }
517
518 static void register_mods(uint8_t mods)
519 {
520     if (!mods) return;
521     host_add_mods(mods);
522     host_send_keyboard_report();
523 }
524
525 static void unregister_mods(uint8_t mods)
526 {
527     if (!mods) return;
528     host_del_mods(mods);
529     host_send_keyboard_report();
530 }
531
532 static void clear_keyboard(void)
533 {
534     host_clear_mods();
535     clear_keyboard_but_mods();
536 }
537
538 static void clear_keyboard_but_mods(void)
539 {
540     host_clear_keys();
541     host_send_keyboard_report();
542 #ifdef MOUSEKEY_ENABLE
543     mousekey_clear();
544     mousekey_send();
545 #endif
546 #ifdef EXTRAKEY_ENABLE
547     host_system_send(0);
548     host_consumer_send(0);
549 #endif
550 }
551
552 static void layer_switch(uint8_t new_layer)
553 {
554     if (current_layer != new_layer) {
555         Kdebug("Layer Switch: "); Kdebug_hex(current_layer);
556         Kdebug(" -> "); Kdebug_hex(new_layer); Kdebug("\n");
557
558         current_layer = new_layer;
559         clear_keyboard_but_mods(); // To avoid stuck keys
560         // TODO: update mods with full scan of matrix? if modifier changes between layers
561     }
562 }