aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/action.c168
-rw-r--r--common/keyboard.h1
2 files changed, 102 insertions, 67 deletions
diff --git a/common/action.c b/common/action.c
index 7299a874a..d5040479e 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, action_t action); 13static void process(keyevent_t event);
14static void register_code(uint8_t code); 14static void register_code(uint8_t code);
15static void unregister_code(uint8_t code); 15static void unregister_code(uint8_t code);
16static void add_mods(uint8_t mods); 16static void add_mods(uint8_t mods);
@@ -30,19 +30,26 @@ static uint8_t tap_count = 0;
30/* layer */ 30/* layer */
31uint8_t default_layer = 0; 31uint8_t default_layer = 0;
32uint8_t current_layer = 0; 32uint8_t current_layer = 0;
33keyrecord_t delaying_layer = {}; 33static keyrecord_t tapping_key = {};
34// time 0 means no event.
35#define IS_TAPPING (tapping_key.event.time != 0)
36/* TODO:
37#define IS_TAPPING_KEY(key) (tapping_key.event.time != 0 && KEYEQ(tapping_key.event.key, key))
38 */
34 39
35/* waiting keys buffer */ 40/* waiting keys buffer */
36#define WAITING_KEYS_BUFFER 3 41#define WAITING_KEYS_BUFFER 3
37static keyrecord_t waiting_keys[WAITING_KEYS_BUFFER] = {}; 42static keyrecord_t waiting_keys[WAITING_KEYS_BUFFER] = {};
43// TODO: double buffer?
44static keyrecord_t waiting_keys0[WAITING_KEYS_BUFFER] = {};
45static keyrecord_t waiting_keys1[WAITING_KEYS_BUFFER] = {};
38static uint8_t waiting_keys_head = 0; 46static uint8_t waiting_keys_head = 0;
39static bool waiting_keys_enqueue(keyevent_t event, action_t action) 47static bool waiting_keys_enqueue(keyevent_t event)
40{ 48{
41 debug("waiting_keys["); debug_dec(waiting_keys_head); debug("] = "); 49 debug("waiting_keys["); debug_dec(waiting_keys_head); debug("] = ");
42 debug_hex16(action.code); debug("\n"); 50 debug_hex8(event.key.row); debug_hex8(event.key.col); debug("\n"); // TODO event.key.raw
43 if (waiting_keys_head < WAITING_KEYS_BUFFER) { 51 if (waiting_keys_head < WAITING_KEYS_BUFFER) {
44 waiting_keys[waiting_keys_head++] = (keyrecord_t){ .event = event, 52 waiting_keys[waiting_keys_head++] = (keyrecord_t){ .event = event,
45 .action = action,
46 .mods = host_get_mods() }; 53 .mods = host_get_mods() };
47 } else { 54 } else {
48 return true; 55 return true;
@@ -62,80 +69,64 @@ static bool waiting_keys_has(keypos_t key)
62static void waiting_keys_process_in_current_layer(void) 69static void waiting_keys_process_in_current_layer(void)
63{ 70{
64 // TODO: in case of including layer key in waiting keys 71 // TODO: in case of including layer key in waiting keys
65 uint8_t tmp_mods = host_get_mods();
66 for (uint8_t i = 0; i < waiting_keys_head; i++) { 72 for (uint8_t i = 0; i < waiting_keys_head; i++) {
67 /* revive status of mods */
68 host_set_mods(waiting_keys[i].mods);
69 process(waiting_keys[i].event, keymap_get_action(current_layer,
70 waiting_keys[i].event.key.row,
71 waiting_keys[i].event.key.col));
72 debug("waiting_keys_process_in_current_layer["); debug_dec(i); debug("]\n"); 73 debug("waiting_keys_process_in_current_layer["); debug_dec(i); debug("]\n");
74 // TODO: no need action in waiting_keys? should get_action() in process()?
75 process(waiting_keys[i].event);
73 } 76 }
74 host_set_mods(tmp_mods);
75 waiting_keys_clear(); 77 waiting_keys_clear();
76} 78}
77 79
78 80
79void action_exec(keyevent_t event) 81void action_exec(keyevent_t event)
80{ 82{
81 /* When delaying layer switch */ 83 if (IS_TAPPING) {
82 if (delaying_layer.action.code) { 84 /* when tap time elapses or waiting key is released */
83 /* Layer switch when tap time elapses or waiting key is released */ 85 if ((timer_elapsed(tapping_key.event.time) > TAP_TIME) ||
84 if ((timer_elapsed(delaying_layer.event.time) > TAP_TIME) ||
85 (!event.pressed && waiting_keys_has(event.key))) { 86 (!event.pressed && waiting_keys_has(event.key))) {
86 /* layer switch */ 87
87 switch (delaying_layer.action.kind.id) { 88 // TODO process tapping_key: layer swich, modifier, ...
88 case ACT_LAYER_PRESSED: 89 // action is needed?
89 layer_switch(delaying_layer.action.layer.opt); 90 debug("notap: process tapping_key.\n");
90 break; 91 process(tapping_key.event);
91 case ACT_LAYER_BIT:
92 layer_switch(current_layer | delaying_layer.action.layer.opt);
93 break;
94 }
95 delaying_layer = (keyrecord_t){};
96 92
97 /* Process waiting keys in new layer */ 93 /* Process waiting keys in new layer */
98 waiting_keys_process_in_current_layer(); 94 waiting_keys_process_in_current_layer();
99 } 95 }
100 /* when delaying layer key is released within delay term */ 96 /* when tapping key is released within tap time */
101 else if (!event.pressed && KEYEQ(event.key, delaying_layer.event.key)) { 97 else if (!event.pressed && KEYEQ(event.key, tapping_key.event.key)) {
102 /* tap key down */ 98 /* tap key down */
103 debug("tap[delaying_layer](register): fist\n"); 99 debug("tap("); debug_hex8(tap_count); debug(")[tapping_key](register): "); debug_hex8(tapping_key.action.layer.code); debug("\n");
104 uint8_t tmp_mods = host_get_mods(); 100 register_code(tapping_key.action.layer.code);
105 host_set_mods(delaying_layer.mods); 101 tapping_key = (keyrecord_t){};
106 register_code(delaying_layer.action.layer.code);
107 delaying_layer = (keyrecord_t){};
108 host_set_mods(tmp_mods);
109 102
110 /* process waiting keys */ 103 /* process waiting keys */
111 waiting_keys_process_in_current_layer(); 104 waiting_keys_process_in_current_layer();
112 } 105 }
113 } 106 }
114 107
115 // not real event. event just to update delaying layer. 108 // not real event. event just to handle time out of tapping key.
116 if (IS_NOEVENT(event)) { 109 if (IS_NOEVENT(event)) {
117 return; 110 return;
118 } 111 }
119 112
120 /* count tap when key is up */ 113 /* count up tap when key is up */
114 // key: d u d u d
115 // tap: 0 1 1 2 2
116 // key: u d u d u
117 // tap: 0 0 1 1 2
121 if (KEYEQ(event.key, last_event.key) && timer_elapsed(last_event.time) <= TAP_TIME) { 118 if (KEYEQ(event.key, last_event.key) && timer_elapsed(last_event.time) <= TAP_TIME) {
122 if (!event.pressed) tap_count++; 119 if (!event.pressed) tap_count++;
123 } else { 120 } else {
124 tap_count = 0; 121 tap_count = 0;
125 } 122 }
126 123
127 action_t action = keymap_get_action(current_layer, event.key.row, event.key.col); 124 /* store key events while tapping */
128 125 if (IS_TAPPING) {
129 // TODO: all key events(pressed, released) should be recorded? 126 // TODO: action is needed?
130 /* postpone key-down events while delaying layer */ 127 waiting_keys_enqueue(event);
131 if (delaying_layer.action.code) {
132 if (event.pressed) {
133 waiting_keys_enqueue(event, action);
134 } else {
135 process(event, action);
136 }
137 } else { 128 } else {
138 process(event, action); 129 process(event);
139 } 130 }
140 131
141 /* last event */ 132 /* last event */
@@ -143,9 +134,9 @@ void action_exec(keyevent_t event)
143} 134}
144 135
145 136
146static void process(keyevent_t event, action_t action) 137static void process(keyevent_t event)
147{ 138{
148 //action_t action = keymap_get_action(current_layer, event.key.row, event.key.col); 139 action_t action = keymap_get_action(current_layer, event.key.row, event.key.col);
149 debug("action: "); debug_hex16(action.code); 140 debug("action: "); debug_hex16(action.code);
150 if (event.pressed) debug("[down]\n"); else debug("[up]\n"); 141 if (event.pressed) debug("[down]\n"); else debug("[up]\n");
151 142
@@ -204,21 +195,39 @@ static void process(keyevent_t event, action_t action)
204 case ACT_LMODS_TAP: 195 case ACT_LMODS_TAP:
205 if (event.pressed) { 196 if (event.pressed) {
206 if (tap_count == 0) { 197 if (tap_count == 0) {
207 add_mods(action.key.mods); 198 if (host_has_anykey()) {
199 // This key is a modifier essentially.
200 // Prioritize mods when key jam or rollover
201 add_mods(action.key.mods);
202 } else {
203 if (IS_TAPPING && KEYEQ(tapping_key.event.key, event.key)) {
204 // no tapping
205 add_mods(action.key.mods);
206 tapping_key = (keyrecord_t){};
207 } else {
208 debug("tapping lmods("); debug_hex8(action.key.mods); debug(")\n");
209 tapping_key = (keyrecord_t){
210 .event = event,
211 .action = action,
212 .mods = host_get_mods()
213 };
214 }
215 }
208 } else { 216 } else {
209 debug("tap[lmods](register): "); debug_hex(tap_count); debug("\n"); 217 // pressed after tapping
218 debug("tap("); debug_hex(tap_count); debug(")[lmods](register): "); debug_hex8(action.key.code); debug("\n");
210 register_code(action.key.code); 219 register_code(action.key.code);
211 } 220 }
212 } else { 221 } else {
213 if (tap_count == 0) { 222 if (tap_count == 0) {
223 debug("tap(00)[lmods](del_mods): "); debug_hex8(action.key.mods); debug("\n");
214 del_mods(action.key.mods); 224 del_mods(action.key.mods);
215 } else if (tap_count == 1) { 225 } else if (tap_count == 1) {
216 debug("tap[lmods](register/unregister): "); debug_hex(tap_count); debug("\n"); 226 debug("tap(01)[lmods](del_mods/unregister): "); debug_hex8(action.key.mods); debug(" "); debug_hex8(action.key.code); debug("\n");
217 del_mods(action.key.mods); 227 del_mods(action.key.mods);
218 register_code(action.key.code);
219 unregister_code(action.key.code); 228 unregister_code(action.key.code);
220 } else { 229 } else {
221 debug("tap[lmods](unregister): "); debug_hex(tap_count); debug("\n"); 230 debug("tap("); debug_hex(tap_count); debug(")[lmods](unregister): "); debug_hex8(action.key.code); debug("\n");
222 unregister_code(action.key.code); 231 unregister_code(action.key.code);
223 } 232 }
224 } 233 }
@@ -226,21 +235,39 @@ static void process(keyevent_t event, action_t action)
226 case ACT_RMODS_TAP: 235 case ACT_RMODS_TAP:
227 if (event.pressed) { 236 if (event.pressed) {
228 if (tap_count == 0) { 237 if (tap_count == 0) {
229 add_mods(action.key.mods<<4); 238 if (host_has_anykey()) {
239 // This key is a modifier essentially.
240 // Prioritize mods when key jam or rollover
241 add_mods(action.key.mods<<4);
242 } else {
243 if (IS_TAPPING && KEYEQ(tapping_key.event.key, event.key)) {
244 // no tapping
245 add_mods(action.key.mods<<4);
246 tapping_key = (keyrecord_t){};
247 } else {
248 debug("tapping rmods("); debug_hex8(action.key.mods); debug(")\n");
249 tapping_key = (keyrecord_t){
250 .event = event,
251 .action = action,
252 .mods = host_get_mods()
253 };
254 }
255 }
230 } else { 256 } else {
231 debug("tap[rmods](register): "); debug_hex(tap_count); debug("\n"); 257 // pressed after tapping
258 debug("tap("); debug_hex(tap_count); debug(")[rmods](register): "); debug_hex8(action.key.code); debug("\n");
232 register_code(action.key.code); 259 register_code(action.key.code);
233 } 260 }
234 } else { 261 } else {
235 if (tap_count == 0) { 262 if (tap_count == 0) {
263 debug("tap(00)[rmods](del_mods): "); debug_hex8(action.key.mods); debug("\n");
236 del_mods(action.key.mods<<4); 264 del_mods(action.key.mods<<4);
237 } else if (tap_count == 1) { 265 } else if (tap_count == 1) {
238 debug("tap[rmods](register/unregister): "); debug_hex(tap_count); debug("\n"); 266 debug("tap(01)[rmods](del_mods/unregister): "); debug_hex8(action.key.mods); debug(" "); debug_hex8(action.key.code); debug("\n");
239 del_mods(action.key.mods<<4); 267 del_mods(action.key.mods<<4);
240 register_code(action.key.code);
241 unregister_code(action.key.code); 268 unregister_code(action.key.code);
242 } else { 269 } else {
243 debug("tap[rmods](unregister): "); debug_hex(tap_count); debug("\n"); 270 debug("tap("); debug_hex(tap_count); debug(")[rmods](unregister): "); debug_hex8(action.key.code); debug("\n");
244 unregister_code(action.key.code); 271 unregister_code(action.key.code);
245 } 272 }
246 } 273 }
@@ -303,16 +330,22 @@ static void process(keyevent_t event, action_t action)
303 // with tap key 330 // with tap key
304 if (event.pressed) { 331 if (event.pressed) {
305 if (tap_count == 0) { 332 if (tap_count == 0) {
306 // not tapping yet
307 if (host_has_anykey()) { 333 if (host_has_anykey()) {
334 // This key is a normal key than a leyar key essentially.
335 // Prioritize 'tap key' when key jam or rollover
308 register_code(action.layer.code); 336 register_code(action.layer.code);
309 } else { 337 } else {
310 debug("Delay switching layer("); debug_hex8(action.layer.opt); debug(")\n"); 338 if (IS_TAPPING && KEYEQ(tapping_key.event.key, event.key)) {
311 delaying_layer = (keyrecord_t){ 339 layer_switch(action.layer.opt);
312 .event = event, 340 tapping_key = (keyrecord_t){};
313 .action = action, 341 } else {
314 .mods = host_get_mods() 342 debug("tapping layer("); debug_hex8(action.layer.opt); debug(")\n");
315 }; 343 tapping_key = (keyrecord_t){
344 .event = event,
345 .action = action,
346 .mods = host_get_mods()
347 };
348 }
316 } 349 }
317 } else if (tap_count > 0) { 350 } else if (tap_count > 0) {
318 // pressed after tapping 351 // pressed after tapping
@@ -371,13 +404,14 @@ static void process(keyevent_t event, action_t action)
371 } 404 }
372 break; 405 break;
373 default: 406 default:
407 // TODO: see ACT_LAYER_PRESSED code
374 // with tap key 408 // with tap key
375 if (event.pressed) { 409 if (event.pressed) {
376 if (tap_count == 0) { 410 if (tap_count == 0) {
377 if (host_has_anykey()) { 411 if (host_has_anykey()) {
378 register_code(action.layer.code); 412 register_code(action.layer.code);
379 } else { 413 } else {
380 delaying_layer = (keyrecord_t){ 414 tapping_key = (keyrecord_t){
381 .event = event, 415 .event = event,
382 .action = action, 416 .action = action,
383 .mods = keyboard_report->mods 417 .mods = keyboard_report->mods
diff --git a/common/keyboard.h b/common/keyboard.h
index cf85b1233..907ee1f97 100644
--- a/common/keyboard.h
+++ b/common/keyboard.h
@@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
26extern "C" { 26extern "C" {
27#endif 27#endif
28 28
29// TODO: union {raw = row:col}
29typedef struct { 30typedef struct {
30 uint8_t row; 31 uint8_t row;
31 uint8_t col; 32 uint8_t col;