aboutsummaryrefslogtreecommitdiff
path: root/common/action.c
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2013-01-27 02:42:48 +0900
committertmk <nobody@nowhere>2013-01-27 02:42:48 +0900
commitef873791bdbff5cc6971705544e120c69ca94212 (patch)
tree653a1959260642ea6cb31bf9c92aaa75392b6c39 /common/action.c
parentd8dddf9f25181e29e3fb82250833a00a11921452 (diff)
downloadqmk_firmware-ef873791bdbff5cc6971705544e120c69ca94212.tar.gz
qmk_firmware-ef873791bdbff5cc6971705544e120c69ca94212.zip
New tapping logic.
Diffstat (limited to 'common/action.c')
-rw-r--r--common/action.c359
1 files changed, 204 insertions, 155 deletions
diff --git a/common/action.c b/common/action.c
index 88f8186c3..815931548 100644
--- a/common/action.c
+++ b/common/action.c
@@ -10,7 +10,7 @@
10#include "action.h" 10#include "action.h"
11 11
12 12
13static void process(keyevent_t event); 13static void process(keyrecord_t *record);
14 14
15void test_func(keyevent_t event, uint8_t opt) 15void test_func(keyevent_t event, uint8_t opt)
16{ 16{
@@ -26,202 +26,250 @@ uint8_t default_layer = 0;
26uint8_t current_layer = 0; 26uint8_t current_layer = 0;
27 27
28/* tap term(ms) */ 28/* tap term(ms) */
29#define TAP_TIME 200 29#define TAP_TERM 200
30 30
31/* This counts up when tap occurs */ 31/* This counts up when tap occurs */
32uint8_t tap_count = 0; 32uint8_t tap_count = 0;
33keyevent_t tapping_event = {}; 33keyevent_t tapping_event = {};
34keyrecord_t tapping_key = {};
34 35
35/* TAPPING: This indicates that whether tap or not is not decided yet. */ 36/* TAPPING: This indicates that whether tap or not is not decided yet. */
36// NOTE: keyevent_t.time 0 means no event. 37// NOTE: keyevent_t.time 0 means no event.
37#define IS_TAPPING(k) (tapping_event.time != 0 && KEYEQ(tapping_event.key, (k))) 38#define IS_TAPPING() (tapping_key.event.time != 0)
39#define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed)
40#define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed)
41#define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k)))
42#define WITHIN_TAP_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAP_TERM)
38 43
39/* waiting keys buffer */ 44/* waiting keys buffer */
40#define WAITING_KEYS_BUFFER 8 45#define WAITING_BUFFER_SIZE 8
41static keyevent_t waiting_events[WAITING_KEYS_BUFFER] = {}; 46static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {};
42static uint8_t waiting_events_head = 0; 47/* point to empty cell to enq */
43static uint8_t waiting_events_tail = 0; 48static uint8_t waiting_buffer_head = 0;
44 49/* point to the oldest data cell to deq */
45static bool waiting_events_enqueue(keyevent_t event) 50static uint8_t waiting_buffer_tail = 0;
51
52static bool waiting_buffer_enq(keyrecord_t record)
46{ 53{
47 if (IS_NOEVENT(event)) { return true; } 54 if (IS_NOEVENT(record.event)) {
55 return true;
56 }
48 57
49 if ((waiting_events_head + 1) % WAITING_KEYS_BUFFER == waiting_events_tail) { 58 if ((waiting_buffer_head + 1) % WAITING_BUFFER_SIZE == waiting_buffer_tail) {
50 debug("waiting_events_enqueue: Over flow.\n"); 59 debug("waiting_buffer_enq: Over flow.\n");
51 return false; 60 return false;
52 } 61 }
53 62
54 debug("waiting_events["); debug_dec(waiting_events_head); debug("] = "); 63 debug("waiting_buffer_enq["); debug_dec(waiting_buffer_head); debug("] = ");
55 debug_hex16(event.key.raw); debug("\n"); 64 debug_hex16(record.event.key.raw); debug("\n");
56 65
57 waiting_events[waiting_events_head] = event; 66 waiting_buffer[waiting_buffer_head] = record;
58 waiting_events_head = (waiting_events_head + 1)% WAITING_KEYS_BUFFER; 67 waiting_buffer_head = (waiting_buffer_head + 1) % WAITING_BUFFER_SIZE;
59 return true; 68 return true;
60} 69}
61static keyevent_t waiting_events_dequeue(void) 70static keyrecord_t waiting_buffer_deq(void)
62{ 71{
63 if (waiting_events_head == waiting_events_tail) { 72 if (waiting_buffer_head == waiting_buffer_tail) {
64 return (keyevent_t){}; 73 return (keyrecord_t){};
65 } 74 }
66 uint8_t tail = waiting_events_tail; 75 uint8_t last_tail = waiting_buffer_tail;
67 waiting_events_tail = waiting_events_tail + 1 % WAITING_KEYS_BUFFER; 76 waiting_buffer_tail = waiting_buffer_tail + 1 % WAITING_BUFFER_SIZE;
68 return waiting_events[tail]; 77 return waiting_buffer[last_tail];
69} 78}
70static void waiting_events_clear(void) 79static bool waiting_buffer_is_empty(void)
71{ 80{
72 waiting_events_head = 0; 81 return (waiting_buffer_head == waiting_buffer_tail);
73 waiting_events_tail = 0;
74} 82}
75static bool waiting_events_has(key_t key) 83static void waiting_buffer_clear(void)
76{ 84{
77 for (uint8_t i = waiting_events_tail; i != waiting_events_head; i = (i + 1) % WAITING_KEYS_BUFFER) { 85 waiting_buffer_head = 0;
78 if KEYEQ(key, waiting_events[i].key) return true; 86 waiting_buffer_tail = 0;
79 }
80 return false;
81} 87}
82static void waiting_events_process_in_current_layer(void) 88static bool waiting_buffer_typed(keyevent_t event)
83{ 89{
84 // TODO: in case of including tap key in waiting keys 90 for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
85 for (uint8_t i = waiting_events_tail; i != waiting_events_head; i = (i + 1) % WAITING_KEYS_BUFFER) { 91 if (KEYEQ(event.key, waiting_buffer[i].event.key) && event.pressed != waiting_buffer[i].event.pressed) {
86 debug("waiting_events_process_in_current_layer["); debug_dec(i); debug("]\n"); 92 return true;
87 process(waiting_events[i]); 93 }
88 } 94 }
89 waiting_events_clear(); 95 return false;
90} 96}
91static bool waiting_events_has_anykey_pressed(void) 97static bool waiting_buffer_has_anykey_pressed(void)
92{ 98{
93 for (uint8_t i = waiting_events_tail; i != waiting_events_head; i = (i + 1) % WAITING_KEYS_BUFFER) { 99 for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
94 if (waiting_events[i].pressed) return true; 100 if (waiting_buffer[i].event.pressed) return true;
95 } 101 }
96 return false; 102 return false;
97} 103}
104static void waiting_buffer_process(void)
105{
106}
98 107
99 108
100void action_exec(keyevent_t event) 109/*
110 * Rule to judge tap:
111 * Tap key is typed(pressed and released) within TAP_TERM
112 * without interfaring by typing other key.
113 */
114/* return true when key event is processed. */
115static bool process_tap(keyrecord_t *keyp)
101{ 116{
102 if (!IS_NOEVENT(event)) { 117 keyevent_t event = keyp->event;
103 debug("event: "); debug_hex16(event.key.raw); 118
104 debug("["); 119 // if tapping
105 if (event.pressed) debug("down"); else debug("up"); 120 if (IS_TAPPING_PRESSED()) {
106 debug("]\n"); 121 if (WITHIN_TAP_TERM(event)) {
107 } 122 if (tapping_key.tap_count == 0) {
108 123 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
109 // In tapping term 124 // first tap!
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"); 125 debug("Tapping: First tap.\n");
116 // count up on release 126 tapping_key.tap_count = 1;
117 tap_count++; 127 process(&tapping_key);
118 128
119 process(tapping_event); 129 // enqueue
120 waiting_events_process_in_current_layer(); 130 keyp->tap_count = tapping_key.tap_count;
121 } 131 return false;
122 tapping_event = event; 132 } else if (!event.pressed && waiting_buffer_typed(event)) {
123 process(event); 133 // other key typed. not tap.
124 } else if (!event.pressed && waiting_events_has(event.key)) { 134 debug("Tapping: End(No tap. Interfered by typing key).\n");
125 debug("Tapping: End(No tap by typing waiting key).\n"); 135 process(&tapping_key);
126 136 tapping_key = (keyrecord_t){};
127 process(tapping_event);
128 waiting_events_process_in_current_layer();
129 process(event);
130 137
131 tap_count = 0; 138 // enqueue
132 tapping_event = (keyevent_t){}; 139 return false;
140 } else {
141 // other key events shall be stored till tapping state settles.
142 return false;
143 }
133 } else { 144 } else {
134 if (!IS_NOEVENT(event)) debug("Tapping: other key while tapping.\n"); 145 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
135 if (tap_count == 0) { 146 keyp->tap_count = tapping_key.tap_count;
136 // store event 147 debug("Tapping: tap release("); debug_dec(keyp->tap_count); debug(")\n");
137 waiting_events_enqueue(event); 148 tapping_key = *keyp;
138 return; 149 return false;
150 }
151 else if (is_tap_key(keyp->event.key) && event.pressed) {
152 debug("Tapping: Start with forcing to release last tap.\n");
153 process(&(keyrecord_t){
154 .tap_count = tapping_key.tap_count,
155 .event.key = tapping_key.event.key,
156 .event.time = event.time,
157 .event.pressed = false
158 });
159 tapping_key = *keyp;
160 return false;
161 }
162 else {
163 if (!IS_NOEVENT(keyp->event)) debug("Tapping: key event while tap.\n");
164 process(keyp);
165 return true;
139 } 166 }
140 process(event);
141 } 167 }
142 } else { 168 }
143 // Waiting for sequential tap 169 // not within TAP_TERM
144 if (tap_count && event.pressed && KEYEQ(tapping_event.key, event.key)) { 170 else {
145 tap_count++; 171 if (tapping_key.tap_count == 0) {
146 tapping_event = event; 172 // timeout. not tap.
147 debug("Tapping: Sequential tap("); debug_hex(tap_count); debug(")\n"); 173 debug("Tapping: End. Not tap(time out).\n");
148 process(event); 174 process(&tapping_key);
149 } else if (event.pressed && is_tap_key(event)) { 175 tapping_key = (keyrecord_t){};
176 return false;
177 } else {
178 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
179 debug("Tapping: End. tap release.");
180 keyp->tap_count = tapping_key.tap_count;
181 process(keyp);
182 tapping_key = (keyrecord_t){};
183 return true;
184 } else {
185 // other key after tap time out.
186 process(keyp);
187 return true;
188 }
189 }
190 }
191 } else if (IS_TAPPING_RELEASED()) {
192 if (WITHIN_TAP_TERM(event)) {
193 if (tapping_key.tap_count > 0 && IS_TAPPING_KEY(event.key) && event.pressed) {
194 // sequential tap.
195 keyp->tap_count = tapping_key.tap_count + 1;
196 debug("Tapping: tap press("); debug_dec(keyp->tap_count); debug(")\n");
197 process(keyp);
198 tapping_key = *keyp;
199 return true;
200 } else if (event.pressed && is_tap_key(event.key)) {
150 // Sequential tap can be interfered with other tap key. 201 // Sequential tap can be interfered with other tap key.
151 debug("Tapping: Start with interfering other tap.\n"); 202 debug("Tapping: Start with interfering other tap.\n");
152 tapping_event = event; 203 tapping_key = *keyp;
153 tap_count = 0; 204 return true;
154 waiting_events_clear();
155 } else { 205 } else {
156 if (!IS_NOEVENT(event)) debug("Tapping: other key just after tap.\n"); 206 if (!IS_NOEVENT(keyp->event)) debug("Tapping: other key just after tap.\n");
157 process(event); 207 process(keyp);
208 return true;
158 } 209 }
210 } else {
211 // timeout. no sequential tap.
212 debug("Tapping: End(Time out after releasing last tap).\n");
213 tapping_key = (keyrecord_t){};
214 process(keyp);
215 return true;
216 }
217 } else {
218 if (event.pressed && is_tap_key(event.key)) {
219 debug("Tapping: Start(Press tap key).\n");
220 tapping_key = *keyp;
221 return true;
222 } else {
223 process(keyp);
224 return true;
159 } 225 }
160 } 226 }
161 // Not in tapping term 227}
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 228
205 process(event); 229void action_exec(keyevent_t event)
206 } 230{
207 } else { 231 if (!IS_NOEVENT(event)) {
208 // Normal state without tapping 232 debug("event: ");
209 if (event.pressed && is_tap_key(event)) { 233 debug_hex16(event.time); debug(": ");
210 debug("Tapping: Start(Press tap key).\n"); 234 debug_hex16(event.key.raw);
211 tapping_event = event; 235 debug("[");
212 tap_count = 0; 236 if (event.pressed) debug("down"); else debug("up");
213 waiting_events_clear(); 237 debug("]\n");
214 } else { 238 }
215 //debug("Normal event(No tapping)\n"); 239
216 process(event); 240 keyrecord_t record = { .event = event };
217 } 241
242 // pre-process on tapping
243 if (process_tap(&record)) {
244 if (!IS_NOEVENT(record.event)) debug("processed.\n");
245 } else {
246 if (!IS_NOEVENT(record.event)) debug("enqueued.\n");
247 if (!waiting_buffer_enq(record)) {
248 // clear all in case of overflow.
249 clear_keyboard();
250 waiting_buffer_clear();
251 tapping_key = (keyrecord_t){};
218 } 252 }
253 }
219 254
255 // TODO: need to process every time?
256 // process waiting_buffer
257 for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) {
258 if (process_tap(&waiting_buffer[waiting_buffer_tail])) {
259 debug("processed: waiting_buffer["); debug_dec(waiting_buffer_tail); debug("] = ");
260 debug_hex16(waiting_buffer[waiting_buffer_tail].event.key.raw); debug("\n");
261 } else {
262 break;
263 }
220 } 264 }
221} 265}
222 266
223static void process(keyevent_t event) 267static void process(keyrecord_t *record)
224{ 268{
269 // TODO: use record
270 keyevent_t event = record->event;
271 uint8_t tap_count = record->tap_count;
272
225 if (IS_NOEVENT(event)) { return; } 273 if (IS_NOEVENT(event)) { return; }
226 274
227 action_t action = keymap_get_action(current_layer, event.key.pos.row, event.key.pos.col); 275 action_t action = keymap_get_action(current_layer, event.key.pos.row, event.key.pos.col);
@@ -286,10 +334,11 @@ static void process(keyevent_t event)
286 uint8_t tmp_mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods : 334 uint8_t tmp_mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods :
287 action.key.mods<<4; 335 action.key.mods<<4;
288 if (event.pressed) { 336 if (event.pressed) {
289 if (IS_TAPPING(event.key) && tap_count > 0) { 337 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
290 if (waiting_events_has_anykey_pressed()) { 338 if (waiting_buffer_has_anykey_pressed()) {
291 debug("MODS_TAP: Tap: Cancel: add_mods\n"); 339 debug("MODS_TAP: Tap: Cancel: add_mods\n");
292 tap_count = 0; 340 // ad hoc: set 0 to cancel tap
341 record->tap_count = 0;
293 add_mods(tmp_mods); 342 add_mods(tmp_mods);
294 } else { 343 } else {
295 debug("MODS_TAP: Tap: register_code\n"); 344 debug("MODS_TAP: Tap: register_code\n");
@@ -300,7 +349,7 @@ static void process(keyevent_t event)
300 add_mods(tmp_mods); 349 add_mods(tmp_mods);
301 } 350 }
302 } else { 351 } else {
303 if (IS_TAPPING(event.key) && tap_count > 0) { 352 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
304 debug("MODS_TAP: Tap: unregister_code\n"); 353 debug("MODS_TAP: Tap: unregister_code\n");
305 unregister_code(action.key.code); 354 unregister_code(action.key.code);
306 } else { 355 } else {
@@ -367,7 +416,7 @@ static void process(keyevent_t event)
367 default: 416 default:
368 // with tap key 417 // with tap key
369 if (event.pressed) { 418 if (event.pressed) {
370 if (IS_TAPPING(event.key)) { 419 if (IS_TAPPING_KEY(event.key)) {
371 if (tap_count > 0) { 420 if (tap_count > 0) {
372 debug("LAYER_PRESSED: Tap: register_code\n"); 421 debug("LAYER_PRESSED: Tap: register_code\n");
373 register_code(action.layer.code); 422 register_code(action.layer.code);
@@ -381,7 +430,7 @@ static void process(keyevent_t event)
381 layer_switch(action.layer.opt); 430 layer_switch(action.layer.opt);
382 } 431 }
383/* 432/*
384 if (IS_TAPPING(event.key) && tap_count > 0) { 433 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
385 debug("LAYER_PRESSED: Tap: register_code\n"); 434 debug("LAYER_PRESSED: Tap: register_code\n");
386 register_code(action.layer.code); 435 register_code(action.layer.code);
387 } else { 436 } else {
@@ -390,7 +439,7 @@ static void process(keyevent_t event)
390 } 439 }
391*/ 440*/
392 } else { 441 } else {
393 if (IS_TAPPING(event.key) && tap_count > 0) { 442 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
394 debug("LAYER_PRESSED: Tap: unregister_code\n"); 443 debug("LAYER_PRESSED: Tap: unregister_code\n");
395 unregister_code(action.layer.code); 444 unregister_code(action.layer.code);
396 } else { 445 } else {
@@ -446,7 +495,7 @@ static void process(keyevent_t event)
446 default: 495 default:
447 // with tap key 496 // with tap key
448 if (event.pressed) { 497 if (event.pressed) {
449 if (IS_TAPPING(event.key) && tap_count > 0) { 498 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
450 debug("LAYER_BIT: Tap: register_code\n"); 499 debug("LAYER_BIT: Tap: register_code\n");
451 register_code(action.layer.code); 500 register_code(action.layer.code);
452 } else { 501 } else {
@@ -454,7 +503,7 @@ static void process(keyevent_t event)
454 layer_switch(current_layer | action.layer.opt); 503 layer_switch(current_layer | action.layer.opt);
455 } 504 }
456 } else { 505 } else {
457 if (IS_TAPPING(event.key) && tap_count > 0) { 506 if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
458 debug("LAYER_BIT: Tap: unregister_code\n"); 507 debug("LAYER_BIT: Tap: unregister_code\n");
459 unregister_code(action.layer.code); 508 unregister_code(action.layer.code);
460 } else { 509 } else {
@@ -622,9 +671,9 @@ void layer_switch(uint8_t new_layer)
622 } 671 }
623} 672}
624 673
625bool is_tap_key(keyevent_t event) 674bool is_tap_key(key_t key)
626{ 675{
627 action_t action = keymap_get_action(current_layer, event.key.pos.row, event.key.pos.col); 676 action_t action = keymap_get_action(current_layer, key.pos.row, key.pos.col);
628 switch (action.kind.id) { 677 switch (action.kind.id) {
629 case ACT_LMODS_TAP: 678 case ACT_LMODS_TAP:
630 case ACT_RMODS_TAP: 679 case ACT_RMODS_TAP: