aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2013-01-15 00:06:52 +0900
committertmk <nobody@nowhere>2013-01-15 00:55:16 +0900
commitf609712da3b94ea36612a6f210bd6ce902b74631 (patch)
tree8fe37ac58b1fabf1d960cfe091c118b06ff2f00e
parent32633a42c74c65462370ef4a39a44a5784a98a06 (diff)
downloadqmk_firmware-f609712da3b94ea36612a6f210bd6ce902b74631.tar.gz
qmk_firmware-f609712da3b94ea36612a6f210bd6ce902b74631.zip
Fix waiting_keys and periodical update for delaying layer.
-rw-r--r--common/action.c222
-rw-r--r--common/keyboard.c9
-rw-r--r--common/keyboard.h9
-rw-r--r--keyboard/hhkb/keymap.c1
4 files changed, 90 insertions, 151 deletions
diff --git a/common/action.c b/common/action.c
index 1a86f16d3..389fc5df1 100644
--- a/common/action.c
+++ b/common/action.c
@@ -9,103 +9,20 @@
9#include "debug.h" 9#include "debug.h"
10#include "action.h" 10#include "action.h"
11 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 12
16 13
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
71typedef 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
79static kbdstate_t kbdstate = IDLE;
80static uint8_t fn_state_bits = 0;
81
82static 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}
90static 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 14
15static void process(keyevent_t event, action_t action);
97static void register_code(uint8_t code); 16static void register_code(uint8_t code);
98static void unregister_code(uint8_t code); 17static void unregister_code(uint8_t code);
99static void register_mods(uint8_t mods);
100static void unregister_mods(uint8_t mods);
101static void clear_keyboard(void); 18static void clear_keyboard(void);
102static void clear_keyboard_but_mods(void); 19static void clear_keyboard_but_mods(void);
20static bool sending_anykey(void);
103static void layer_switch(uint8_t new_layer); 21static void layer_switch(uint8_t new_layer);
104 22
105 23
106/* tap */ 24/* tap */
107#define TAP_TIME 200 25#define TAP_TIME 200
108#define LAYER_DELAY 200
109static keyevent_t last_event = {}; 26static keyevent_t last_event = {};
110static uint16_t last_event_time = 0; 27static uint16_t last_event_time = 0;
111static uint8_t tap_count = 0; 28static uint8_t tap_count = 0;
@@ -115,31 +32,54 @@ uint8_t default_layer = 0;
115uint8_t current_layer = 0; 32uint8_t current_layer = 0;
116keyrecord_t delaying_layer = {}; 33keyrecord_t delaying_layer = {};
117 34
118keyrecord_t waiting_key = {};
119
120// TODO: ring buffer: waiting_keys[]
121/*
122#define WAITING_KEYS_BUFFER 3 35#define WAITING_KEYS_BUFFER 3
123static keyrecord_t waiting_keys[WAITING_KEYS_BUFFER] = {}; 36static keyrecord_t waiting_keys[WAITING_KEYS_BUFFER] = {};
124static uint8_t waiting_keys_head = 0; 37static uint8_t waiting_keys_head = 0;
125static uint8_t waiting_keys_tail = 0; 38static bool waiting_keys_enqueue(keyevent_t event, action_t action)
126static void waiting_key_queue(keyevent_t event)
127{ 39{
40 debug("waiting_keys["); debug_dec(waiting_keys_head); debug("] = ");
41 debug_hex16(action.code); debug("\n");
42 if (waiting_keys_head < WAITING_KEYS_BUFFER) {
43 waiting_keys[waiting_keys_head++] = (keyrecord_t){ .event = event,
44 .action = action,
45 .mods = host_get_mods() };
46 } else {
47 return true;
48 }
128} 49}
129static void waiting_key_dequeue(keyevent_t event) 50static void waiting_keys_clear(void)
130{ 51{
52 waiting_keys_head = 0;
131} 53}
132*/ 54static bool waiting_keys_has(keypos_t key)
55{
56 for (uint8_t i = 0; i < waiting_keys_head; i++) {
57 if KEYEQ(key, waiting_keys[i].event.key) return true;
58 }
59 return false;
60}
61static void waiting_keys_process_in_current_layer(void)
62{
63 // TODO: in case of including layer key in waiting keys
64 uint8_t tmp_mods = host_get_mods();
65 for (uint8_t i = 0; i < waiting_keys_head; i++) {
66 /* revive status of mods */
67 host_set_mods(waiting_keys[i].mods);
68 process(waiting_keys[i].event, keymap_get_action(current_layer,
69 waiting_keys[i].event.key.row,
70 waiting_keys[i].event.key.col));
71 debug("waiting_keys_process_in_current_layer["); debug_dec(i); debug("]\n");
72 }
73 host_set_mods(tmp_mods);
74 waiting_keys_clear();
75}
76
133 77
134static void process(keyevent_t event, action_t action) 78static void process(keyevent_t event, action_t action)
135{ 79{
136 //action_t action = keymap_get_action(current_layer, event.key.row, event.key.col); 80 //action_t action = keymap_get_action(current_layer, event.key.row, event.key.col);
137
138 debug("action: "); debug_hex16(action.code); debug("\n"); 81 debug("action: "); debug_hex16(action.code); debug("\n");
139 debug("kind.id: "); debug_hex(action.kind.id); debug("\n"); 82
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 83
144 switch (action.kind.id) { 84 switch (action.kind.id) {
145 /* Key and Mods */ 85 /* Key and Mods */
@@ -244,12 +184,12 @@ static void process(keyevent_t event, action_t action)
244 break; 184 break;
245 default: 185 default:
246 // with tap key 186 // with tap key
247 debug("tap: "); debug_hex(tap_count); debug("\n");
248 if (event.pressed) { 187 if (event.pressed) {
249 if (tap_count == 0) { 188 if (tap_count == 0) {
250 if (host_has_anykey()) { 189 if (host_has_anykey()) {
251 register_code(action.layer.code); 190 register_code(action.layer.code);
252 } else { 191 } else {
192 debug("Delay switching layer("); debug_hex8(action.layer.opt); debug(")\n");
253 delaying_layer = (keyrecord_t){ 193 delaying_layer = (keyrecord_t){
254 .event = event, 194 .event = event,
255 .action = action, 195 .action = action,
@@ -257,12 +197,13 @@ static void process(keyevent_t event, action_t action)
257 }; 197 };
258 } 198 }
259 } else if (tap_count > 0) { 199 } else if (tap_count > 0) {
200 debug("tap: "); debug_hex(tap_count); debug("\n");
260 register_code(action.layer.code); 201 register_code(action.layer.code);
261 } 202 }
262 } else { 203 } else {
263 // tap key 204 // tap key
264 if (KEYEQ(event.key, delaying_layer.event.key) && 205 if (KEYEQ(event.key, delaying_layer.event.key) &&
265 timer_elapsed(delaying_layer.event.time) < TAP_TIME) { 206 timer_elapsed(delaying_layer.event.time) <= TAP_TIME) {
266 uint8_t tmp_mods = host_get_mods(); 207 uint8_t tmp_mods = host_get_mods();
267 host_set_mods(delaying_layer.mods); 208 host_set_mods(delaying_layer.mods);
268 register_code(delaying_layer.action.layer.code); 209 register_code(delaying_layer.action.layer.code);
@@ -321,7 +262,6 @@ static void process(keyevent_t event, action_t action)
321 break; 262 break;
322 default: 263 default:
323 // with tap key 264 // with tap key
324 debug("tap: "); debug_hex(tap_count); debug("\n");
325 if (event.pressed) { 265 if (event.pressed) {
326 if (tap_count == 0) { 266 if (tap_count == 0) {
327 if (host_has_anykey()) { 267 if (host_has_anykey()) {
@@ -334,6 +274,7 @@ static void process(keyevent_t event, action_t action)
334 }; 274 };
335 } 275 }
336 } else if (tap_count > 0) { 276 } else if (tap_count > 0) {
277 debug("tap: "); debug_hex(tap_count); debug("\n");
337 register_code(action.layer.code); 278 register_code(action.layer.code);
338 } 279 }
339 } else { 280 } else {
@@ -409,18 +350,16 @@ static void process(keyevent_t event, action_t action)
409 350
410void action_exec(keyevent_t event) 351void action_exec(keyevent_t event)
411{ 352{
412 /* count tap when key is up */ 353/*
413 if (KEYEQ(event.key, last_event.key) && timer_elapsed(last_event_time) < TAP_TIME) { 354 debug("key["); debug_hex8(event.key.row); debug(":"); debug_hex8(event.key.col);
414 if (!event.pressed) tap_count++; 355 if (event.pressed) debug("]down\n"); else debug("]up\n");
415 } else { 356*/
416 tap_count = 0;
417 }
418 357
419 /* When delaying layer switch */ 358 /* When delaying layer switch */
420 if (delaying_layer.action.code) { 359 if (delaying_layer.action.code) {
421 /* Layer switch when delay time elapses or waiting key is released */ 360 /* Layer switch when tap time elapses or waiting key is released */
422 if ((timer_elapsed(delaying_layer.event.time) > LAYER_DELAY) || 361 if ((timer_elapsed(delaying_layer.event.time) > TAP_TIME) ||
423 (!event.pressed && KEYEQ(event.key, waiting_key.event.key))) { 362 (!event.pressed && waiting_keys_has(event.key))) {
424 /* layer switch */ 363 /* layer switch */
425 switch (delaying_layer.action.kind.id) { 364 switch (delaying_layer.action.kind.id) {
426 case ACT_LAYER_PRESSED: 365 case ACT_LAYER_PRESSED:
@@ -433,15 +372,7 @@ void action_exec(keyevent_t event)
433 delaying_layer = (keyrecord_t){}; 372 delaying_layer = (keyrecord_t){};
434 373
435 /* Process waiting keys in new layer */ 374 /* Process waiting keys in new layer */
436 if (waiting_key.event.time) { 375 waiting_keys_process_in_current_layer();
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 } 376 }
446 /* when delaying layer key is released within delay term */ 377 /* when delaying layer key is released within delay term */
447 else if (!event.pressed && KEYEQ(event.key, delaying_layer.event.key)) { 378 else if (!event.pressed && KEYEQ(event.key, delaying_layer.event.key)) {
@@ -450,28 +381,32 @@ void action_exec(keyevent_t event)
450 host_set_mods(delaying_layer.mods); 381 host_set_mods(delaying_layer.mods);
451 register_code(delaying_layer.action.layer.code); 382 register_code(delaying_layer.action.layer.code);
452 delaying_layer = (keyrecord_t){}; 383 delaying_layer = (keyrecord_t){};
384 host_set_mods(tmp_mods);
453 385
454 /* process waiting keys */ 386 /* process waiting keys */
455 if (waiting_key.event.time) { 387 waiting_keys_process_in_current_layer();
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 } 388 }
462 } 389 }
463 390
391 // not real event. event just to update delaying layer.
392 if (IS_NOEVENT(event)) {
393 return;
394 }
395
396 /* count tap when key is up */
397 if (KEYEQ(event.key, last_event.key) && timer_elapsed(last_event.time) <= TAP_TIME) {
398 if (!event.pressed) tap_count++;
399 } else {
400 tap_count = 0;
401 }
402
464 action_t action = keymap_get_action(current_layer, event.key.row, event.key.col); 403 action_t action = keymap_get_action(current_layer, event.key.row, event.key.col);
465 404
405 // TODO: all key events(pressed, released) should be recorded?
466 /* postpone key-down events while delaying layer */ 406 /* postpone key-down events while delaying layer */
467 if (delaying_layer.action.code) { 407 if (delaying_layer.action.code) {
468 if (event.pressed) { 408 if (event.pressed) {
469 // TODO: waiting_keys[] 409 waiting_keys_enqueue(event, action);
470 waiting_key = (keyrecord_t){
471 .event = event,
472 .action = action,
473 .mods = host_get_mods()
474 };
475 } else { 410 } else {
476 process(event, action); 411 process(event, action);
477 } 412 }
@@ -481,7 +416,6 @@ void action_exec(keyevent_t event)
481 416
482 /* last event */ 417 /* last event */
483 last_event = event; 418 last_event = event;
484 last_event_time = timer_read();
485} 419}
486 420
487 421
@@ -515,20 +449,6 @@ static void unregister_code(uint8_t code)
515 } 449 }
516} 450}
517 451
518static void register_mods(uint8_t mods)
519{
520 if (!mods) return;
521 host_add_mods(mods);
522 host_send_keyboard_report();
523}
524
525static void unregister_mods(uint8_t mods)
526{
527 if (!mods) return;
528 host_del_mods(mods);
529 host_send_keyboard_report();
530}
531
532static void clear_keyboard(void) 452static void clear_keyboard(void)
533{ 453{
534 host_clear_mods(); 454 host_clear_mods();
@@ -549,11 +469,17 @@ static void clear_keyboard_but_mods(void)
549#endif 469#endif
550} 470}
551 471
472static bool sending_anykey(void)
473{
474 return (host_has_anykey() || host_mouse_in_use() ||
475 host_last_sysytem_report() || host_last_consumer_report());
476}
477
552static void layer_switch(uint8_t new_layer) 478static void layer_switch(uint8_t new_layer)
553{ 479{
554 if (current_layer != new_layer) { 480 if (current_layer != new_layer) {
555 Kdebug("Layer Switch: "); Kdebug_hex(current_layer); 481 debug("Layer Switch: "); debug_hex(current_layer);
556 Kdebug(" -> "); Kdebug_hex(new_layer); Kdebug("\n"); 482 debug(" -> "); debug_hex(new_layer); debug("\n");
557 483
558 current_layer = new_layer; 484 current_layer = new_layer;
559 clear_keyboard_but_mods(); // To avoid stuck keys 485 clear_keyboard_but_mods(); // To avoid stuck keys
diff --git a/common/keyboard.c b/common/keyboard.c
index 4e955e129..2e32e91e0 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -78,7 +78,14 @@ void keyboard_task(void)
78 } 78 }
79 } 79 }
80 } 80 }
81 MATRIX_LOOP_END: 81 // call to update delaying layer when no real event
82 action_exec((keyevent_t) {
83 .key = (keypos_t){ .row = 255, .col = 255 }, // assume this key doesn't exist
84 .pressed = false,
85 .time = 0,
86 });
87
88MATRIX_LOOP_END:
82 89
83#ifdef MOUSEKEY_ENABLE 90#ifdef MOUSEKEY_ENABLE
84 // mousekey repeat & acceleration 91 // mousekey repeat & acceleration
diff --git a/common/keyboard.h b/common/keyboard.h
index 116653661..cf85b1233 100644
--- a/common/keyboard.h
+++ b/common/keyboard.h
@@ -37,7 +37,14 @@ typedef struct {
37 uint16_t time; 37 uint16_t time;
38} keyevent_t; 38} keyevent_t;
39 39
40#define KEYEQ(keya, keyb) (keya.row == keyb.row && keya.col == keyb.col) 40#define KEYEQ(keya, keyb) (keya.row == keyb.row && keya.col == keyb.col)
41#define IS_NOEVENT(event) (event.time == 0)
42#define NOEVENT (keyevent_t) { \
43 .key = (keypos_t){ .row = 255, .col = 255 }, \
44 .pressed = false, \
45 .time = 0, \
46}
47
41 48
42extern uint8_t current_layer; 49extern uint8_t current_layer;
43extern uint8_t default_layer; 50extern uint8_t default_layer;
diff --git a/keyboard/hhkb/keymap.c b/keyboard/hhkb/keymap.c
index 9fe1237aa..38461290b 100644
--- a/keyboard/hhkb/keymap.c
+++ b/keyboard/hhkb/keymap.c
@@ -224,6 +224,5 @@ action_t keymap_get_action(uint8_t layer, uint8_t row, uint8_t col) {
224 action.code = ACTION_NO; 224 action.code = ACTION_NO;
225 break; 225 break;
226 } 226 }
227 debug("action: "); debug_hex16(action.code); debug("\n");
228 return action; 227 return action;
229} 228}