aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2013-01-20 15:03:07 +0900
committertmk <nobody@nowhere>2013-01-21 15:44:49 +0900
commitf71a5217b762225eec294b02f9403f29a25ceb6a (patch)
tree9bc9332ec858853f66fbb686b4572a0b6021f98a
parentee7ce433357a1c1bbcaba54525fc5b5b5404aa82 (diff)
downloadqmk_firmware-f71a5217b762225eec294b02f9403f29a25ceb6a.tar.gz
qmk_firmware-f71a5217b762225eec294b02f9403f29a25ceb6a.zip
Fix mods with tapping.
-rw-r--r--common/action.c380
-rw-r--r--common/keyboard.h2
2 files changed, 190 insertions, 192 deletions
diff --git a/common/action.c b/common/action.c
index d01038301..3a504a45f 100644
--- a/common/action.c
+++ b/common/action.c
@@ -23,57 +23,83 @@ static void layer_switch(uint8_t new_layer);
23 23
24 24
25/* tap */ 25/* tap */
26#define TAP_TIME 200 26#define TAP_TIME 300
27static keyevent_t last_event = {}; 27/* This counts up when tap occurs */
28static uint8_t tap_count = 0; 28static uint8_t tap_count = 0;
29static 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}
29 50
30/* layer */ 51/* layer */
31uint8_t default_layer = 0; 52uint8_t default_layer = 0;
32uint8_t current_layer = 0; 53uint8_t current_layer = 0;
33static keyrecord_t tapping_key = {}; 54static keyevent_t tapping_event = {};
34// time 0 means no event. 55
35#define IS_TAPPING (tapping_key.event.time != 0) 56/* TAPPING: This indicates that whether tap or not is not decided yet. */
36/* TODO: 57// NOTE: keyevent_t.time 0 means no event.
37#define IS_TAPPING_KEY(key) (tapping_key.event.time != 0 && KEYEQ(tapping_key.event.key, key)) 58#define IS_TAPPING(k) (tapping_event.time != 0 && KEYEQ(tapping_event.key, (k)))
38 */
39 59
40/* waiting keys buffer */ 60/* waiting keys buffer */
41#define WAITING_KEYS_BUFFER 3 61#define WAITING_KEYS_BUFFER 8
42static keyrecord_t waiting_keys[WAITING_KEYS_BUFFER] = {}; 62static keyevent_t waiting_events[WAITING_KEYS_BUFFER] = {};
43// TODO: double buffer? 63static uint8_t waiting_events_head = 0;
44static keyrecord_t waiting_keys0[WAITING_KEYS_BUFFER] = {}; 64static bool waiting_events_enqueue(keyevent_t event)
45static keyrecord_t waiting_keys1[WAITING_KEYS_BUFFER] = {};
46static uint8_t waiting_keys_head = 0;
47static bool waiting_keys_enqueue(keyevent_t event)
48{ 65{
49 debug("waiting_keys["); debug_dec(waiting_keys_head); debug("] = "); 66 if (IS_NOEVENT(event)) { return true; }
50 debug_hex16(event.key.raw); debug("\n"); 67
51 if (waiting_keys_head < WAITING_KEYS_BUFFER) { 68 if (waiting_events_head < WAITING_KEYS_BUFFER) {
52 waiting_keys[waiting_keys_head++] = (keyrecord_t){ .event = event, 69 debug("waiting_events["); debug_dec(waiting_events_head); debug("] = ");
53 .mods = host_get_mods() }; 70 debug_hex16(event.key.raw); debug("\n");
54 } else { 71 waiting_events[waiting_events_head++] = event;
55 return true; 72 return true;
56 } 73 }
74 debug("waiting_events_enqueue: Over flow.\n");
75 return false;
57} 76}
58static void waiting_keys_clear(void) 77static void waiting_events_clear(void)
59{ 78{
60 waiting_keys_head = 0; 79 waiting_events_head = 0;
61} 80}
62static bool waiting_keys_has(key_t key) 81static bool waiting_events_has(key_t key)
63{ 82{
64 for (uint8_t i = 0; i < waiting_keys_head; i++) { 83 for (uint8_t i = 0; i < waiting_events_head; i++) {
65 if KEYEQ(key, waiting_keys[i].event.key) return true; 84 if KEYEQ(key, waiting_events[i].key) return true;
66 } 85 }
67 return false; 86 return false;
68} 87}
69static void waiting_keys_process_in_current_layer(void) 88static 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}
97static bool waiting_events_has_anykey_pressed(void)
70{ 98{
71 // TODO: in case of including layer key in waiting keys 99 for (uint8_t i = 0; i < waiting_events_head; i++) {
72 for (uint8_t i = 0; i < waiting_keys_head; i++) { 100 if (waiting_events[i].pressed) return true;
73 debug("waiting_keys_process_in_current_layer["); debug_dec(i); debug("]\n");
74 process(waiting_keys[i].event);
75 } 101 }
76 waiting_keys_clear(); 102 return false;
77} 103}
78 104
79 105
@@ -85,62 +111,106 @@ void action_exec(keyevent_t event)
85 if (event.pressed) debug("down"); else debug("up"); 111 if (event.pressed) debug("down"); else debug("up");
86 debug("]\n"); 112 debug("]\n");
87 } 113 }
88 if (IS_TAPPING) {
89 /* when tap time elapses or waiting key is released */
90 if ((timer_elapsed(tapping_key.event.time) > TAP_TIME) ||
91 (!event.pressed && waiting_keys_has(event.key))) {
92
93 // TODO process tapping_key: layer swich, modifier, ...
94 // action is needed?
95 debug("notap: process tapping_key.\n");
96 process(tapping_key.event);
97
98 /* Process waiting keys in new layer */
99 waiting_keys_process_in_current_layer();
100 }
101 /* when tapping key is released within tap time */
102 else if (!event.pressed && KEYEQ(event.key, tapping_key.event.key)) {
103 /* tap key down */
104 debug("tap("); debug_hex8(tap_count); debug(")[tapping_key](register): "); debug_hex8(tapping_key.action.layer.code); debug("\n");
105 register_code(tapping_key.action.layer.code);
106 tapping_key = (keyrecord_t){};
107
108 /* process waiting keys */
109 waiting_keys_process_in_current_layer();
110 }
111 }
112 114
113 // not real event. event just to handle time out of tapping key. 115 // In tapping term
114 if (IS_NOEVENT(event)) { 116 if (tapping_event.time && timer_elapsed(tapping_event.time) < TAP_TIME) {
115 return; 117 if (tapping_event.pressed) {
116 } 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++;
117 124
118 /* count up tap when key is up */ 125 process(tapping_event);
119 // key: d u d u d 126 waiting_events_process_in_current_layer();
120 // tap: 0 1 1 2 2 127 }
121 // key: u d u d u 128 tapping_event = event;
122 // tap: 0 0 1 1 2 129 process(event);
123 if (KEYEQ(event.key, last_event.key) && timer_elapsed(last_event.time) <= TAP_TIME) { 130 } else if (!event.pressed && waiting_events_has(event.key)) {
124 if (!event.pressed) tap_count++; 131 debug("Tapping: End(No tap by typing waiting key).\n");
125 } else {
126 tap_count = 0;
127 }
128 132
129 /* store key events while tapping */ 133 process(tapping_event);
130 if (IS_TAPPING) { 134 waiting_events_process_in_current_layer();
131 // TODO: action is needed? 135 process(event);
132 waiting_keys_enqueue(event); 136
133 } else { 137 tap_count = 0;
134 process(event); 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 }
135 } 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 }
136 205
137 /* last event */ 206 }
138 last_event = event;
139} 207}
140 208
141 209
142static void process(keyevent_t event) 210static void process(keyevent_t event)
143{ 211{
212 if (IS_NOEVENT(event)) { return; }
213
144 action_t action = keymap_get_action(current_layer, event.key.pos.row, event.key.pos.col); 214 action_t action = keymap_get_action(current_layer, event.key.pos.row, event.key.pos.col);
145 debug("action: "); debug_hex16(action.code); 215 debug("action: "); debug_hex16(action.code);
146 if (event.pressed) debug("[down]\n"); else debug("[up]\n"); 216 if (event.pressed) debug("[down]\n"); else debug("[up]\n");
@@ -198,82 +268,32 @@ static void process(keyevent_t event)
198 } 268 }
199 break; 269 break;
200 case ACT_LMODS_TAP: 270 case ACT_LMODS_TAP:
201 if (event.pressed) { 271 case ACT_RMODS_TAP:
202 if (tap_count == 0) { 272 {
203 if (host_has_anykey()) { 273 uint8_t tmp_mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods :
204 // This key is a modifier essentially. 274 action.key.mods<<4;
205 // Prioritize mods when key jam or rollover 275 if (event.pressed) {
206 add_mods(action.key.mods); 276 if (IS_TAPPING(event.key) && tap_count > 0) {
207 } else { 277 if (waiting_events_has_anykey_pressed()) {
208 if (IS_TAPPING && KEYEQ(tapping_key.event.key, event.key)) { 278 debug("MODS_TAP: Tap: Cancel: add_mods\n");
209 // no tapping 279 tap_count = 0;
210 add_mods(action.key.mods); 280 add_mods(tmp_mods);
211 tapping_key = (keyrecord_t){};
212 } else { 281 } else {
213 debug("tapping lmods("); debug_hex8(action.key.mods); debug(")\n"); 282 debug("MODS_TAP: Tap: register_code\n");
214 tapping_key = (keyrecord_t){ 283 register_code(action.key.code);
215 .event = event,
216 .action = action,
217 .mods = host_get_mods()
218 };
219 } 284 }
285 } else {
286 debug("MODS_TAP: No tap: add_mods\n");
287 add_mods(tmp_mods);
220 } 288 }
221 } else { 289 } else {
222 // pressed after tapping 290 if (IS_TAPPING(event.key) && tap_count > 0) {
223 debug("tap("); debug_hex(tap_count); debug(")[lmods](register): "); debug_hex8(action.key.code); debug("\n"); 291 debug("MODS_TAP: Tap: unregister_code\n");
224 register_code(action.key.code); 292 unregister_code(action.key.code);
225 }
226 } else {
227 if (tap_count == 0) {
228 debug("tap(00)[lmods](del_mods): "); debug_hex8(action.key.mods); debug("\n");
229 del_mods(action.key.mods);
230 } else if (tap_count == 1) {
231 debug("tap(01)[lmods](del_mods/unregister): "); debug_hex8(action.key.mods); debug(" "); debug_hex8(action.key.code); debug("\n");
232 del_mods(action.key.mods);
233 unregister_code(action.key.code);
234 } else {
235 debug("tap("); debug_hex(tap_count); debug(")[lmods](unregister): "); debug_hex8(action.key.code); debug("\n");
236 unregister_code(action.key.code);
237 }
238 }
239 break;
240 case ACT_RMODS_TAP:
241 if (event.pressed) {
242 if (tap_count == 0) {
243 if (host_has_anykey()) {
244 // This key is a modifier essentially.
245 // Prioritize mods when key jam or rollover
246 add_mods(action.key.mods<<4);
247 } else { 293 } else {
248 if (IS_TAPPING && KEYEQ(tapping_key.event.key, event.key)) { 294 debug("MODS_TAP: No tap: add_mods\n");
249 // no tapping 295 del_mods(tmp_mods);
250 add_mods(action.key.mods<<4);
251 tapping_key = (keyrecord_t){};
252 } else {
253 debug("tapping rmods("); debug_hex8(action.key.mods); debug(")\n");
254 tapping_key = (keyrecord_t){
255 .event = event,
256 .action = action,
257 .mods = host_get_mods()
258 };
259 }
260 } 296 }
261 } else {
262 // pressed after tapping
263 debug("tap("); debug_hex(tap_count); debug(")[rmods](register): "); debug_hex8(action.key.code); debug("\n");
264 register_code(action.key.code);
265 }
266 } else {
267 if (tap_count == 0) {
268 debug("tap(00)[rmods](del_mods): "); debug_hex8(action.key.mods); debug("\n");
269 del_mods(action.key.mods<<4);
270 } else if (tap_count == 1) {
271 debug("tap(01)[rmods](del_mods/unregister): "); debug_hex8(action.key.mods); debug(" "); debug_hex8(action.key.code); debug("\n");
272 del_mods(action.key.mods<<4);
273 unregister_code(action.key.code);
274 } else {
275 debug("tap("); debug_hex(tap_count); debug(")[rmods](unregister): "); debug_hex8(action.key.code); debug("\n");
276 unregister_code(action.key.code);
277 } 297 }
278 } 298 }
279 break; 299 break;
@@ -334,33 +354,20 @@ static void process(keyevent_t event)
334 default: 354 default:
335 // with tap key 355 // with tap key
336 if (event.pressed) { 356 if (event.pressed) {
337 if (tap_count == 0) { 357 if (IS_TAPPING(event.key) && tap_count > 0) {
338 if (host_has_anykey()) { 358 debug("LAYER_PRESSED: Tap: register_code\n");
339 // This key is a normal key than a leyar key essentially.
340 // Prioritize 'tap key' when key jam or rollover
341 register_code(action.layer.code);
342 } else {
343 if (IS_TAPPING && KEYEQ(tapping_key.event.key, event.key)) {
344 layer_switch(action.layer.opt);
345 tapping_key = (keyrecord_t){};
346 } else {
347 debug("tapping layer("); debug_hex8(action.layer.opt); debug(")\n");
348 tapping_key = (keyrecord_t){
349 .event = event,
350 .action = action,
351 .mods = host_get_mods()
352 };
353 }
354 }
355 } else if (tap_count > 0) {
356 // pressed after tapping
357 debug("tap[layer](register): "); debug_hex(tap_count); debug("\n");
358 register_code(action.layer.code); 359 register_code(action.layer.code);
360 } else {
361 debug("LAYER_PRESSED: No tap: layer_switch\n");
362 layer_switch(action.layer.opt);
359 } 363 }
360 } else { 364 } else {
361 // released after tapping 365 if (IS_TAPPING(event.key) && tap_count > 0) {
362 debug("tap[layer](unregister): "); debug_hex(tap_count); debug("\n"); 366 debug("LAYER_PRESSED: Tap: unregister_code\n");
363 unregister_code(action.layer.code); 367 unregister_code(action.layer.code);
368 } else {
369 debug("LAYER_PRESSED: No tap: NO ACTION\n");
370 }
364 } 371 }
365 break; 372 break;
366 } 373 }
@@ -409,32 +416,23 @@ static void process(keyevent_t event)
409 } 416 }
410 break; 417 break;
411 default: 418 default:
412 // TODO: see ACT_LAYER_PRESSED code
413 // with tap key 419 // with tap key
414 if (event.pressed) { 420 if (event.pressed) {
415 if (tap_count == 0) { 421 if (IS_TAPPING(event.key) && tap_count > 0) {
416 if (host_has_anykey()) { 422 debug("LAYER_BIT: Tap: register_code\n");
417 register_code(action.layer.code);
418 } else {
419 tapping_key = (keyrecord_t){
420 .event = event,
421 .action = action,
422 .mods = keyboard_report->mods
423 };
424 }
425 } else if (tap_count > 0) {
426 debug("tap[layer_bit](register): "); debug_hex(tap_count); debug("\n");
427 register_code(action.layer.code); 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);
428 } 427 }
429 } else { 428 } else {
430 if (tap_count == 0) { 429 if (IS_TAPPING(event.key) && tap_count > 0) {
431 // no tap 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");
432 layer_switch(current_layer & ~action.layer.opt); 434 layer_switch(current_layer & ~action.layer.opt);
433 } else if (tap_count == 1) {
434 // tap
435 register_code(action.layer.code);
436 } 435 }
437 unregister_code(action.layer.code);
438 } 436 }
439 break; 437 break;
440 } 438 }
diff --git a/common/keyboard.h b/common/keyboard.h
index 4518cdddc..4a3ee85a8 100644
--- a/common/keyboard.h
+++ b/common/keyboard.h
@@ -37,7 +37,7 @@ typedef union {
37} key_t; 37} key_t;
38 38
39typedef struct { 39typedef struct {
40 key_t key; 40 key_t key;
41 bool pressed; 41 bool pressed;
42 uint16_t time; 42 uint16_t time;
43} keyevent_t; 43} keyevent_t;