aboutsummaryrefslogtreecommitdiff
path: root/common/action.c
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2013-01-09 22:33:33 +0900
committertmk <nobody@nowhere>2013-01-09 22:33:33 +0900
commit411de9cc22e927313a5a768f3bf41f2f99bca126 (patch)
treecff699c11ec293df8375566e7a3d186712e72e74 /common/action.c
parent4324e163360db4c6ebd25cab74d09d42b3021278 (diff)
downloadqmk_firmware-411de9cc22e927313a5a768f3bf41f2f99bca126.tar.gz
qmk_firmware-411de9cc22e927313a5a768f3bf41f2f99bca126.zip
Add new layer actions.
Diffstat (limited to 'common/action.c')
-rw-r--r--common/action.c394
1 files changed, 187 insertions, 207 deletions
diff --git a/common/action.c b/common/action.c
index 45e2276e7..425a2b00f 100644
--- a/common/action.c
+++ b/common/action.c
@@ -1,6 +1,6 @@
1#include "host.h" 1#include "host.h"
2#include "timer.h" 2#include "timer.h"
3//#include "keymap.h" 3#include "keymap.h"
4#include "keycode.h" 4#include "keycode.h"
5#include "keyboard.h" 5#include "keyboard.h"
6#include "mousekey.h" 6#include "mousekey.h"
@@ -78,8 +78,6 @@ typedef enum { IDLE, DELAYING, WAITING, PRESSING } kbdstate_t;
78 78
79static kbdstate_t kbdstate = IDLE; 79static kbdstate_t kbdstate = IDLE;
80static uint8_t fn_state_bits = 0; 80static uint8_t fn_state_bits = 0;
81static keyrecord_t delayed_fn = {};
82static keyrecord_t waiting_key = {};
83 81
84static const char *state_str(kbdstate_t state) 82static const char *state_str(kbdstate_t state)
85{ 83{
@@ -96,17 +94,6 @@ static bool anykey_sent_to_host(void)
96} 94}
97 95
98 96
99
100/*
101static void layer_switch_on(uint8_t code);
102static void layer_switch_off(uint8_t code);
103static void key_action(uint8_t code, keyevent_t event);
104static void key_pressed(uint8_t code, keyevent_t event);
105static void key_released(uint8_t code, keyevent_t event);
106static void mod_pressed(uint8_t code, keyevent_t event);
107static void mod_released(uint8_t code, keyevent_t event);
108*/
109
110static void register_code(uint8_t code); 97static void register_code(uint8_t code);
111static void unregister_code(uint8_t code); 98static void unregister_code(uint8_t code);
112static void register_mods(uint8_t mods); 99static void register_mods(uint8_t mods);
@@ -118,6 +105,7 @@ static void layer_switch(uint8_t new_layer);
118 105
119/* tap */ 106/* tap */
120#define TAP_TIME 200 107#define TAP_TIME 200
108#define LAYER_DELAY 200
121static keyevent_t last_event = {}; 109static keyevent_t last_event = {};
122static uint16_t last_event_time = 0; 110static uint16_t last_event_time = 0;
123static uint8_t tap_count = 0; 111static uint8_t tap_count = 0;
@@ -125,10 +113,10 @@ static uint8_t tap_count = 0;
125/* layer */ 113/* layer */
126uint8_t default_layer = 0; 114uint8_t default_layer = 0;
127uint8_t current_layer = 0; 115uint8_t current_layer = 0;
128uint8_t waiting_layer = 0; 116keyrecord_t delaying_layer = {};
129 117
130 118
131void action_exec(action_t action, keyevent_t event) 119void action_exec(keyevent_t event)
132{ 120{
133 /* count tap when key is up */ 121 /* count tap when key is up */
134 if (KEYEQ(event.key, last_event.key) && timer_elapsed(last_event_time) < TAP_TIME) { 122 if (KEYEQ(event.key, last_event.key) && timer_elapsed(last_event_time) < TAP_TIME) {
@@ -137,6 +125,20 @@ void action_exec(action_t action, keyevent_t event)
137 tap_count = 0; 125 tap_count = 0;
138 } 126 }
139 127
128 /* layer switch after LAYER_DELAY */
129 if (delaying_layer.action.code && timer_elapsed(delaying_layer.event.time) > LAYER_DELAY) {
130 switch (delaying_layer.action.kind.id) {
131 case ACT_LAYER_PRESSED:
132 layer_switch(delaying_layer.action.layer.opt);
133 break;
134 case ACT_LAYER_BIT:
135 layer_switch(current_layer | delaying_layer.action.layer.opt);
136 break;
137 }
138 delaying_layer = (keyrecord_t){};
139 }
140 action_t action = keymap_get_action(current_layer, event.key.row, event.key.col);
141
140 debug("action: "); debug_hex16(action.code); debug("\n"); 142 debug("action: "); debug_hex16(action.code); debug("\n");
141 debug("kind.id: "); debug_hex(action.kind.id); debug("\n"); 143 debug("kind.id: "); debug_hex(action.kind.id); debug("\n");
142 debug("kind.param: "); debug_hex16(action.kind.param); debug("\n"); 144 debug("kind.param: "); debug_hex16(action.kind.param); debug("\n");
@@ -145,6 +147,7 @@ void action_exec(action_t action, keyevent_t event)
145 147
146 switch (action.kind.id) { 148 switch (action.kind.id) {
147 case ACT_LMODS: 149 case ACT_LMODS:
150 // normal key or key plus mods
148 if (event.pressed) { 151 if (event.pressed) {
149 register_mods(action.key.mods); 152 register_mods(action.key.mods);
150 register_code(action.key.code); 153 register_code(action.key.code);
@@ -162,94 +165,207 @@ void action_exec(action_t action, keyevent_t event)
162 unregister_mods(action.key.mods<<4); 165 unregister_mods(action.key.mods<<4);
163 } 166 }
164 break; 167 break;
165 case ACT_LAYER: 168 case ACT_LMOD_TAP:
166 switch (action.layer_key.code) { 169 break;
167 case 0x00: // Momentary switch 170 case ACT_RMOD_TAP:
168 // TODO: history of layer switch 171 break;
172 case ACT_USAGE:
173#ifdef EXTRAKEY_ENABLE
174 switch (action.usage.page) {
175 case ACTION_USAGE_PAGE_SYSTEM:
169 if (event.pressed) { 176 if (event.pressed) {
170 layer_switch(action.layer_key.layer); 177 host_system_send(action.usage.code);
171 } else { 178 } else {
172 layer_switch(default_layer); 179 host_system_send(0);
173 } 180 }
174 break; 181 break;
175 case 0x01: // Oneshot switch 182 case ACTION_USAGE_PAGE_CONSUMER:
176 // TODO: 183 if (event.pressed) {
184 host_consumer_send(action.usage.code);
185 } else {
186 host_consumer_send(0);
187 }
177 break; 188 break;
178 case 0x02: // reserved 189 }
179 case 0x03: // reserved 190#endif
191 break;
192 case ACT_MOUSEKEY:
193#ifdef MOUSEKEY_ENABLE
194 if (event.pressed) {
195 mousekey_on(action.key.code);
196 mousekey_send();
197 } else {
198 mousekey_off(action.key.code);
199 mousekey_send();
200 }
201#endif
202 break;
203 case ACT_LAYER_PRESSED:
204 // layer action when pressed
205 switch (action.layer.code) {
206 case 0x00:
207 if (event.pressed) {
208 layer_switch(action.layer.opt);
209 }
180 break; 210 break;
181 case 0xF0 ... 0xF7: // Tap to enable/disable 211 case 0xF0:
182 case 0xF8 ... 0xFF: // Tap to toggle layer 212 // TODO: tap toggle
183 // TODO:
184 break; 213 break;
185 default: // with keycode for tap 214 case 0xFF:
215 if (event.pressed) {
216 default_layer = action.layer.opt;
217 layer_switch(default_layer);
218 }
219 break;
220 default:
221 // with tap key
186 debug("tap: "); debug_hex(tap_count); debug("\n"); 222 debug("tap: "); debug_hex(tap_count); debug("\n");
187 // TODO: layer switch
188 // TODO: in case tap is interrupted by other key
189
190
191 if (event.pressed) { 223 if (event.pressed) {
192 // when any key down
193 if (host_has_anykey()) {
194 if (tap_count == 0)
195 register_code(action.layer_key.code);
196 } else {
197 }
198
199 if (tap_count == 0) { 224 if (tap_count == 0) {
200 if (host_has_anykey()) { 225 if (host_has_anykey()) {
201 register_code(action.layer_key.code); 226 register_code(action.layer.code);
202 } else { 227 } else {
203 waiting_layer = action.layer_key.layer; 228 delaying_layer = (keyrecord_t){
229 .event = event,
230 .action = action,
231 .mods = keyboard_report->mods
232 };
204 } 233 }
205 } 234 } else if (tap_count > 0) {
206 // register key when press after a tap 235 register_code(action.layer.code);
207 if (tap_count > 0) {
208 register_code(action.layer_key.code);
209 } 236 }
210 } else { 237 } else {
211 // type key after tap 238 // type key after tap
212 if (tap_count == 1) { 239 if (tap_count == 1) {
213 register_code(action.layer_key.code); 240 delaying_layer = (keyrecord_t){};
241 register_code(action.layer.code);
214 } 242 }
215 unregister_code(action.layer_key.code); 243 unregister_code(action.layer.code);
216 } 244 }
217 break; 245 break;
218 } 246 }
219 break; 247 break;
220 case ACT_USAGE: 248 case ACT_LAYER_RELEASED:
221#ifdef EXTRAKEY_ENABLE 249 switch (action.layer.code) {
222 switch (action.usage.page) { 250 case 0x00:
223 case ACTION_USAGE_PAGE_SYSTEM:
224 if (event.pressed) { 251 if (event.pressed) {
225 host_system_send(action.usage.code); 252 layer_switch(action.layer.opt);
253 }
254 break;
255 case 0xF0:
256 // Ignored. LAYER_RELEASED with tap toggle is invalid action.
257 break;
258 case 0xFF:
259 if (!event.pressed) {
260 default_layer = action.layer.opt;
261 layer_switch(default_layer);
262 }
263 break;
264 default:
265 // Ignored. LAYER_RELEASED with tap key is invalid action.
266 break;
267 }
268 break;
269 case ACT_LAYER_BIT:
270 switch (action.layer.code) {
271 case 0x00:
272 if (event.pressed) {
273 layer_switch(current_layer | action.layer.opt);
226 } else { 274 } else {
227 host_system_send(0); 275 layer_switch(current_layer & ~action.layer.opt);
228 } 276 }
229 break; 277 break;
230 case ACTION_USAGE_PAGE_CONSUMER: 278 case 0xF0:
279 // TODO: tap toggle
280 break;
281 case 0xFF:
282 // change default layer
231 if (event.pressed) { 283 if (event.pressed) {
232 host_consumer_send(action.usage.code); 284 default_layer = current_layer | action.layer.opt;
285 layer_switch(default_layer);
233 } else { 286 } else {
234 host_consumer_send(0); 287 default_layer = current_layer & ~action.layer.opt;
288 layer_switch(default_layer);
289 }
290 break;
291 default:
292 // with tap key
293 debug("tap: "); debug_hex(tap_count); debug("\n");
294 if (event.pressed) {
295 if (tap_count == 0) {
296 if (host_has_anykey()) {
297 register_code(action.layer.code);
298 } else {
299 delaying_layer = (keyrecord_t){
300 .event = event,
301 .action = action,
302 .mods = keyboard_report->mods
303 };
304 }
305 } else if (tap_count > 0) {
306 register_code(action.layer.code);
307 }
308 } else {
309 if (tap_count == 0) {
310 // no tap
311 layer_switch(current_layer & ~action.layer.opt);
312 } else if (tap_count == 1) {
313 // tap
314 register_code(action.layer.code);
315 }
316 unregister_code(action.layer.code);
235 } 317 }
236 break; 318 break;
237 } 319 }
238#endif 320 case ACT_LAYER_EXT:
239 break; 321 switch (action.layer.opt) {
240 case ACT_MOUSEKEY: 322 case 0x00:
241#ifdef MOUSEKEY_ENABLE 323 // set default layer when pressed
242 if (event.pressed) { 324 switch (action.layer.code) {
243 mousekey_on(action.key.code); 325 case 0x00:
244 mousekey_send(); 326 if (event.pressed) {
245 } else { 327 layer_switch(default_layer);
246 mousekey_off(action.key.code); 328 }
247 mousekey_send(); 329 break;
330 case 0xF0:
331 // TODO: tap toggle
332 break;
333 case 0xFF:
334 if (event.pressed) {
335 default_layer = current_layer;
336 layer_switch(default_layer);
337 }
338 break;
339 default:
340 // TODO: tap key
341 break;
342 }
343 break;
344 case 0x01:
345 // set default layer when released
346 switch (action.layer.code) {
347 case 0x00:
348 if (!event.pressed) {
349 layer_switch(default_layer);
350 }
351 break;
352 case 0xFF:
353 if (!event.pressed) {
354 default_layer = current_layer;
355 layer_switch(default_layer);
356 }
357 break;
358 case 0xF0:
359 default:
360 // Ignore tap.
361 if (!event.pressed) {
362 layer_switch(default_layer);
363 }
364 break;
365 }
366 break;
248 } 367 }
249#endif
250 break; 368 break;
251 case ACT_LMOD_TAP:
252 case ACT_RMOD_TAP:
253 case ACT_MACRO: 369 case ACT_MACRO:
254 case ACT_COMMAND: 370 case ACT_COMMAND:
255 case ACT_FUNCTION: 371 case ACT_FUNCTION:
@@ -263,142 +379,6 @@ void action_exec(action_t action, keyevent_t event)
263} 379}
264 380
265 381
266#if 0
267/* Key Action */
268inline
269static void key_action(uint8_t code, keyevent_t event)
270{
271 if (event.pressed)
272 key_pressed(code, event);
273 else
274 key_released(code, event);
275}
276
277void fn_action(uint8_t code, keyevent_t event)
278{
279}
280
281/* Key */
282inline static void key_pressed(uint8_t code, keyevent_t event)
283{
284 uint8_t tmp_mods;
285 switch (kbdstate) {
286 case IDLE:
287 register_code(code);
288 NEXT(PRESSING);
289 break;
290 case PRESSING:
291 register_code(code);
292 break;
293 case DELAYING:
294 waiting_key = (keyrecord_t) {
295 .event = event,
296 .code = code,
297 .mods = keyboard_report->mods,
298 .time = timer_read()
299 };
300 NEXT(WAITING);
301 break;
302 case WAITING:
303 // play back key stroke
304 tmp_mods = keyboard_report->mods;
305 host_set_mods(delayed_fn.mods);
306 register_code(delayed_fn.code);
307 host_set_mods(waiting_key.mods);
308 register_code(waiting_key.code);
309 host_set_mods(tmp_mods);
310 register_code(code);
311 NEXT(IDLE);
312 break;
313 }
314}
315inline static void key_released(uint8_t code, keyevent_t event)
316{
317 uint8_t tmp_mods;
318 switch (kbdstate) {
319 case IDLE:
320 unregister_code(code);
321 break;
322 case PRESSING:
323 unregister_code(code);
324 if (!anykey_sent_to_host())
325 NEXT(IDLE);
326 break;
327 case DELAYING:
328 unregister_code(code);
329 break;
330 case WAITING:
331 if (code == waiting_key.code) {
332 layer_switch_on(delayed_fn.code);
333 NEXT(IDLE);
334 // process waiting_key
335 tmp_mods = keyboard_report->mods;
336 host_set_mods(waiting_key.mods);
337 keymap_process_event(waiting_key.event);
338 host_set_mods(tmp_mods);
339 keymap_process_event(event);
340 } else {
341 unregister_code(code);
342 }
343 break;
344 }
345}
346
347/* layer switch momentary */
348inline static void layerkey_pressed(uint8_t code, keyevent_t event)
349{
350 uint8_t tmp_mods;
351 switch (kbdstate) {
352 case IDLE:
353 layer_switch_on(code);
354 break;
355 case PRESSING:
356 // ignore
357 break;
358 case DELAYING:
359 waiting_key = (keyrecord_t) {
360 .event = event,
361 .code = code,
362 .mods = keyboard_report->mods,
363 .time = timer_read()
364 };
365 NEXT(WAITING);
366 break;
367 case WAITING:
368 tmp_mods = keyboard_report->mods;
369 host_set_mods(delayed_fn.mods);
370 register_code(delayed_fn.code);
371 host_set_mods(waiting_key.mods);
372 register_code(waiting_key.code);
373 host_set_mods(tmp_mods);
374 if (kind == FN_DOWN) {
375 // ignore Fn
376 } else if (kind == FNK_DOWN) {
377 register_code(code);
378 } else if (kind == KEY_DOWN) {
379 register_code(code);
380 }
381 NEXT(IDLE);
382 break;
383 }
384}
385inline static void layerkey_released(uint8_t code, keyevent_t event)
386{
387 switch (kbdstate) {
388 case IDLE:
389 layer_switch_off(code);
390 break;
391 case PRESSING:
392 case DELAYING:
393 case WAITING:
394 if (layer_switch_off(code))
395 NEXT(IDLE);
396 break;
397 }
398}
399#endif
400
401
402static void register_code(uint8_t code) 382static void register_code(uint8_t code)
403{ 383{
404 if (code == KC_NO) { 384 if (code == KC_NO) {