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