]> git.gir.st - tmk_keyboard.git/blob - common/action.c
Fix mods with tapping.
[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(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 }
Imprint / Impressum