diff options
| author | tmk <nobody@nowhere> | 2012-10-12 04:46:37 +0900 |
|---|---|---|
| committer | tmk <nobody@nowhere> | 2012-10-17 15:55:37 +0900 |
| commit | 1677b021d7bff6af7763532b038612363b61dada (patch) | |
| tree | 1f9d95373843f620cbd7be7d4bd7cbb84c9e8c22 /common/keyboard.c | |
| parent | 0a70be9a97215e2b514841f67e52b4c55a6adab1 (diff) | |
| download | qmk_firmware-1677b021d7bff6af7763532b038612363b61dada.tar.gz qmk_firmware-1677b021d7bff6af7763532b038612363b61dada.zip | |
Fix layer switching and host API.
Diffstat (limited to 'common/keyboard.c')
| -rw-r--r-- | common/keyboard.c | 136 |
1 files changed, 76 insertions, 60 deletions
diff --git a/common/keyboard.c b/common/keyboard.c index 43abf4236..7a17a9e38 100644 --- a/common/keyboard.c +++ b/common/keyboard.c | |||
| @@ -110,6 +110,12 @@ static void clear_keyboard_but_mods(void) | |||
| 110 | #endif | 110 | #endif |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | static bool anykey_sent_to_host(void) | ||
| 114 | { | ||
| 115 | return (host_has_anykey() || host_mouse_in_use() || | ||
| 116 | host_last_sysytem_report() || host_last_consumer_report()); | ||
| 117 | } | ||
| 118 | |||
| 113 | static void layer_switch_on(uint8_t code) | 119 | static void layer_switch_on(uint8_t code) |
| 114 | { | 120 | { |
| 115 | if (!IS_FN(code)) return; | 121 | if (!IS_FN(code)) return; |
| @@ -123,9 +129,9 @@ static void layer_switch_on(uint8_t code) | |||
| 123 | } | 129 | } |
| 124 | } | 130 | } |
| 125 | 131 | ||
| 126 | static void layer_switch_off(uint8_t code) | 132 | static bool layer_switch_off(uint8_t code) |
| 127 | { | 133 | { |
| 128 | if (!IS_FN(code)) return; | 134 | if (!IS_FN(code)) return false; |
| 129 | fn_state_bits &= ~FN_BIT(code); | 135 | fn_state_bits &= ~FN_BIT(code); |
| 130 | if (current_layer != keymap_fn_layer(biton(fn_state_bits))) { | 136 | if (current_layer != keymap_fn_layer(biton(fn_state_bits))) { |
| 131 | clear_keyboard_but_mods(); | 137 | clear_keyboard_but_mods(); |
| @@ -133,21 +139,7 @@ static void layer_switch_off(uint8_t code) | |||
| 133 | debug("Layer Switch(off): "); debug_hex(current_layer); | 139 | debug("Layer Switch(off): "); debug_hex(current_layer); |
| 134 | current_layer = keymap_fn_layer(biton(fn_state_bits)); | 140 | current_layer = keymap_fn_layer(biton(fn_state_bits)); |
| 135 | debug(" -> "); debug_hex(current_layer); debug("\n"); | 141 | debug(" -> "); debug_hex(current_layer); debug("\n"); |
| 136 | } | 142 | return true; |
| 137 | } | ||
| 138 | |||
| 139 | // whether any key except modifier is down or not | ||
| 140 | static inline bool is_anykey_down(void) | ||
| 141 | { | ||
| 142 | for (int r = 0; r < MATRIX_ROWS; r++) { | ||
| 143 | matrix_row_t matrix_row = matrix_get_row(r); | ||
| 144 | for (int c = 0; c < MATRIX_COLS; c++) { | ||
| 145 | if (matrix_row && (1<<c)) { | ||
| 146 | if (IS_KEY(keymap_get_keycode(current_layer, r, c))) { | ||
| 147 | return true; | ||
| 148 | } | ||
| 149 | } | ||
| 150 | } | ||
| 151 | } | 143 | } |
| 152 | return false; | 144 | return false; |
| 153 | } | 145 | } |
| @@ -162,6 +154,10 @@ static void register_code(uint8_t code) | |||
| 162 | host_add_mod_bit(MOD_BIT(code)); | 154 | host_add_mod_bit(MOD_BIT(code)); |
| 163 | host_send_keyboard_report(); | 155 | host_send_keyboard_report(); |
| 164 | } | 156 | } |
| 157 | else if IS_FN(code) { | ||
| 158 | host_add_key(keymap_fn_keycode(FN_INDEX(code))); | ||
| 159 | host_send_keyboard_report(); | ||
| 160 | } | ||
| 165 | else if IS_MOUSEKEY(code) { | 161 | else if IS_MOUSEKEY(code) { |
| 166 | #ifdef MOUSEKEY_ENABLE | 162 | #ifdef MOUSEKEY_ENABLE |
| 167 | mousekey_on(code); | 163 | mousekey_on(code); |
| @@ -256,6 +252,10 @@ static void unregister_code(uint8_t code) | |||
| 256 | host_del_mod_bit(MOD_BIT(code)); | 252 | host_del_mod_bit(MOD_BIT(code)); |
| 257 | host_send_keyboard_report(); | 253 | host_send_keyboard_report(); |
| 258 | } | 254 | } |
| 255 | else if IS_FN(code) { | ||
| 256 | host_del_key(keymap_fn_keycode(FN_INDEX(code))); | ||
| 257 | host_send_keyboard_report(); | ||
| 258 | } | ||
| 259 | else if IS_MOUSEKEY(code) { | 259 | else if IS_MOUSEKEY(code) { |
| 260 | #ifdef MOUSEKEY_ENABLE | 260 | #ifdef MOUSEKEY_ENABLE |
| 261 | mousekey_off(code); | 261 | mousekey_off(code); |
| @@ -272,24 +272,31 @@ static void unregister_code(uint8_t code) | |||
| 272 | 272 | ||
| 273 | /* | 273 | /* |
| 274 | * | 274 | * |
| 275 | * Event/State|IDLE DELAYING[f] WAITING[f,k] PRESSING | 275 | * Event/State|IDLE PRESSING DELAYING[f] WAITING[f,k] |
| 276 | * -----------+------------------------------------------------------------------ | 276 | * -----------+------------------------------------------------------------------ |
| 277 | * Fn Down |IDLE(L+) WAITING(Sk) WAITING(Sk) - | 277 | * Fn Down |(L+) -*1 WAITING(Sk) IDLE(Rf,Ps)*7 |
| 278 | * Up |IDLE(L-) IDLE(L-) IDLE(L-) IDLE(L-) | 278 | * Up |(L-) IDLE(L-)*8 IDLE(L-)*8 IDLE(L-)*8 |
| 279 | * Fnk Down |DELAYING(Sf) WAITING(Sk) WAINTING(Sk) PRESSING(Rf) | 279 | * Fnk Down |DELAYING(Sf)* (Rf) WAITING(Sk) IDLE(Rf,Ps,Rf) |
| 280 | * Up |IDLE(L-) IDLE(Rf,Uf) IDLE(Rf,Ps,Uf)*3 PRESSING(Uf) | 280 | * Up |(L-) IDLE(L-/Uf)*8 IDLE(Rf,Uf/L-)*3 IDLE(Rf,Ps,Uf/L-)*3 |
| 281 | * Key Down |PRESSING(Rk) WAITING(Sk) WAITING(Sk) PRESSING(Rk) | 281 | * Key Down |PRESSING(Rk) (Rk) WAITING(Sk) IDLE(Rf,Ps,Rk) |
| 282 | * Up |IDLE(Uk) DELAYING(Uk) IDLE(L+,Ps,Uk) IDLE(Uk)*4 | 282 | * Up |(Uk) IDLE(Uk)*4 (Uk) IDLE(L+,Ps,Pk)/(Uk)*a |
| 283 | * Delay |- IDLE(L+) IDLE(L+,Ps) - | ||
| 284 | * | | 283 | * | |
| 285 | * No key Down|IDLE(Ld) IDLE(Ld) IDLE(Ld) IDLE(Ld) | 284 | * Delay |- - IDLE(L+) IDLE(L+,Ps) |
| 285 | * Magic Key |COMMAND*5 | ||
| 286 | * | 286 | * |
| 287 | * *1: ignore Fn if other key is down. | ||
| 287 | * *2: register Fnk if any key is pressing | 288 | * *2: register Fnk if any key is pressing |
| 288 | * *3: when Fnk == Stored Fnk, if not ignore. | 289 | * *3: register/unregister delayed Fnk and move to IDLE if code == delayed Fnk, else *8 |
| 289 | * *4: when no registered key any more | 290 | * *4: if no keys registered to host |
| 291 | * *5: unregister all keys | ||
| 292 | * *6: only if no keys down | ||
| 293 | * *7: ignore Fn because Fnk key and stored key are down. | ||
| 294 | * *8: move to IDLE if layer switch(off) occurs, else stay at current state | ||
| 295 | * *9: repeat key if pressing Fnk twice quickly(move to PRESSING) | ||
| 296 | * *a: layer switch and process waiting key and code if code == wainting key, else unregister key | ||
| 290 | * | 297 | * |
| 291 | * States: | 298 | * States: |
| 292 | * IDLE: | 299 | * IDLE: No key is down except modifiers |
| 293 | * DELAYING: delay layer switch after pressing Fn with alt keycode | 300 | * DELAYING: delay layer switch after pressing Fn with alt keycode |
| 294 | * WAITING: key is pressed during DELAYING | 301 | * WAITING: key is pressed during DELAYING |
| 295 | * | 302 | * |
| @@ -297,17 +304,20 @@ static void unregister_code(uint8_t code) | |||
| 297 | * Fn: Fn key without alternative keycode | 304 | * Fn: Fn key without alternative keycode |
| 298 | * Fnk: Fn key with alternative keycode | 305 | * Fnk: Fn key with alternative keycode |
| 299 | * -: ignore | 306 | * -: ignore |
| 307 | * Delay: layer switch delay term is elapsed | ||
| 300 | * | 308 | * |
| 301 | * Actions: | 309 | * Actions: |
| 302 | * Rk: register key | 310 | * Rk: register key |
| 303 | * Uk: unregister key | 311 | * Uk: unregister key |
| 304 | * Rf: register stored Fn(alt keycode) | 312 | * Rf: register Fn(alt keycode) |
| 305 | * Uf: unregister stored Fn(alt keycode) | 313 | * Uf: unregister Fn(alt keycode) |
| 306 | * Rs: register stored key | 314 | * Rs: register stored key |
| 307 | * Us: unregister stored key | 315 | * Us: unregister stored key |
| 308 | * Sk: store key | 316 | * Sk: Store key(waiting Key) |
| 309 | * Sf: store Fn | 317 | * Sf: Store Fn(delayed Fn) |
| 310 | * Ps: play stored key(Interpret stored key and transit state) | 318 | * Ps: Process stored key |
| 319 | * Ps: Process key | ||
| 320 | * Is: Interpret stored keys in current layer | ||
| 311 | * L+: Switch to new layer(*unregister* all keys but modifiers) | 321 | * L+: Switch to new layer(*unregister* all keys but modifiers) |
| 312 | * L-: Switch back to last layer(*unregister* all keys but modifiers) | 322 | * L-: Switch back to last layer(*unregister* all keys but modifiers) |
| 313 | * Ld: Switch back to default layer(*unregister* all keys but modifiers) | 323 | * Ld: Switch back to default layer(*unregister* all keys but modifiers) |
| @@ -344,7 +354,7 @@ static inline void process_key(keyevent_t event) | |||
| 344 | // repeat Fn alt key when press Fn key down, up then down again quickly | 354 | // repeat Fn alt key when press Fn key down, up then down again quickly |
| 345 | if (KEYEQ(delayed_fn.event.key, event.key) && | 355 | if (KEYEQ(delayed_fn.event.key, event.key) && |
| 346 | timer_elapsed(delayed_fn.time) < LAYER_DELAY) { | 356 | timer_elapsed(delayed_fn.time) < LAYER_DELAY) { |
| 347 | register_code(keymap_fn_keycode(FN_INDEX(code))); | 357 | register_code(code); |
| 348 | NEXT(PRESSING); | 358 | NEXT(PRESSING); |
| 349 | } else { | 359 | } else { |
| 350 | delayed_fn = (keyrecord_t) { | 360 | delayed_fn = (keyrecord_t) { |
| @@ -380,16 +390,20 @@ static inline void process_key(keyevent_t event) | |||
| 380 | // ignored when any key is pressed | 390 | // ignored when any key is pressed |
| 381 | break; | 391 | break; |
| 382 | case FN_UP: | 392 | case FN_UP: |
| 383 | layer_switch_off(code); | 393 | if (layer_switch_off(code)) |
| 384 | NEXT(IDLE); | 394 | NEXT(IDLE); |
| 385 | break; | 395 | break; |
| 386 | case FNK_DOWN: | 396 | case FNK_DOWN: |
| 387 | register_code(keymap_fn_keycode(FN_INDEX(code))); | 397 | register_code(code); |
| 388 | break; | 398 | break; |
| 389 | case FNK_UP: | 399 | case FNK_UP: |
| 390 | // can't know whether layer switched or not | 400 | if (layer_switch_off(code)) { |
| 391 | layer_switch_off(code); | 401 | NEXT(IDLE); |
| 392 | unregister_code(keymap_fn_keycode(FN_INDEX(code))); | 402 | } else { |
| 403 | unregister_code(code); | ||
| 404 | if (!anykey_sent_to_host()) | ||
| 405 | NEXT(IDLE); | ||
| 406 | } | ||
| 393 | break; | 407 | break; |
| 394 | case KEY_DOWN: | 408 | case KEY_DOWN: |
| 395 | case MOD_DOWN: | 409 | case MOD_DOWN: |
| @@ -398,8 +412,7 @@ static inline void process_key(keyevent_t event) | |||
| 398 | case KEY_UP: | 412 | case KEY_UP: |
| 399 | case MOD_UP: | 413 | case MOD_UP: |
| 400 | unregister_code(code); | 414 | unregister_code(code); |
| 401 | // TODO: no key registered? mousekey, mediakey, systemkey | 415 | if (!anykey_sent_to_host()) |
| 402 | if (!host_has_anykey()) | ||
| 403 | NEXT(IDLE); | 416 | NEXT(IDLE); |
| 404 | break; | 417 | break; |
| 405 | default: | 418 | default: |
| @@ -423,8 +436,8 @@ static inline void process_key(keyevent_t event) | |||
| 423 | register_code(code); | 436 | register_code(code); |
| 424 | break; | 437 | break; |
| 425 | case FN_UP: | 438 | case FN_UP: |
| 426 | layer_switch_off(code); | 439 | if (layer_switch_off(code)) |
| 427 | NEXT(IDLE); | 440 | NEXT(IDLE); |
| 428 | break; | 441 | break; |
| 429 | case FNK_UP: | 442 | case FNK_UP: |
| 430 | if (code == delayed_fn.code) { | 443 | if (code == delayed_fn.code) { |
| @@ -432,19 +445,16 @@ static inline void process_key(keyevent_t event) | |||
| 432 | // restore the mod status at the time of pressing Fn key | 445 | // restore the mod status at the time of pressing Fn key |
| 433 | tmp_mods = keyboard_report->mods; | 446 | tmp_mods = keyboard_report->mods; |
| 434 | host_set_mods(delayed_fn.mods); | 447 | host_set_mods(delayed_fn.mods); |
| 435 | register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); | 448 | register_code(delayed_fn.code); |
| 436 | unregister_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); | 449 | unregister_code(delayed_fn.code); |
| 437 | host_set_mods(tmp_mods); | 450 | host_set_mods(tmp_mods); |
| 438 | NEXT(IDLE); | 451 | NEXT(IDLE); |
| 439 | } else { | 452 | } else { |
| 440 | layer_switch_off(code); | 453 | if (layer_switch_off(code)) |
| 441 | NEXT(IDLE); | 454 | NEXT(IDLE); |
| 442 | } | 455 | } |
| 443 | break; | 456 | break; |
| 444 | case KEY_UP: | 457 | case KEY_UP: |
| 445 | unregister_code(code); | ||
| 446 | NEXT(IDLE); | ||
| 447 | break; | ||
| 448 | case MOD_UP: | 458 | case MOD_UP: |
| 449 | unregister_code(code); | 459 | unregister_code(code); |
| 450 | break; | 460 | break; |
| @@ -459,34 +469,40 @@ static inline void process_key(keyevent_t event) | |||
| 459 | case KEY_DOWN: | 469 | case KEY_DOWN: |
| 460 | tmp_mods = keyboard_report->mods; | 470 | tmp_mods = keyboard_report->mods; |
| 461 | host_set_mods(delayed_fn.mods); | 471 | host_set_mods(delayed_fn.mods); |
| 462 | register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); | 472 | register_code(delayed_fn.code); |
| 463 | host_set_mods(waiting_key.mods); | 473 | host_set_mods(waiting_key.mods); |
| 464 | register_code(waiting_key.code); | 474 | register_code(waiting_key.code); |
| 465 | host_set_mods(tmp_mods); | 475 | host_set_mods(tmp_mods); |
| 466 | register_code(code); | 476 | if (kind == FN_DOWN) { |
| 477 | // ignore Fn | ||
| 478 | } else if (kind == FNK_DOWN) { | ||
| 479 | register_code(code); | ||
| 480 | } else if (kind == KEY_DOWN) { | ||
| 481 | register_code(code); | ||
| 482 | } | ||
| 467 | NEXT(IDLE); | 483 | NEXT(IDLE); |
| 468 | break; | 484 | break; |
| 469 | case MOD_DOWN: | 485 | case MOD_DOWN: |
| 470 | register_code(code); | 486 | register_code(code); |
| 471 | break; | 487 | break; |
| 472 | case FN_UP: | 488 | case FN_UP: |
| 473 | layer_switch_off(code); | 489 | if (layer_switch_off(code)) |
| 474 | NEXT(IDLE); | 490 | NEXT(IDLE); |
| 475 | break; | 491 | break; |
| 476 | case FNK_UP: | 492 | case FNK_UP: |
| 477 | if (code == delayed_fn.code) { | 493 | if (code == delayed_fn.code) { |
| 478 | // alt down, key down, alt up | 494 | // alt down, key down, alt up |
| 479 | tmp_mods = keyboard_report->mods; | 495 | tmp_mods = keyboard_report->mods; |
| 480 | host_set_mods(delayed_fn.mods); | 496 | host_set_mods(delayed_fn.mods); |
| 481 | register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); | 497 | register_code(delayed_fn.code); |
| 482 | host_set_mods(waiting_key.mods); | 498 | host_set_mods(waiting_key.mods); |
| 483 | register_code(waiting_key.code); | 499 | register_code(waiting_key.code); |
| 484 | unregister_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); | 500 | unregister_code(delayed_fn.code); |
| 485 | host_set_mods(tmp_mods); | 501 | host_set_mods(tmp_mods); |
| 486 | NEXT(IDLE); | 502 | NEXT(IDLE); |
| 487 | } else { | 503 | } else { |
| 488 | layer_switch_off(code); | 504 | if (layer_switch_off(code)) |
| 489 | NEXT(IDLE); | 505 | NEXT(IDLE); |
| 490 | } | 506 | } |
| 491 | break; | 507 | break; |
| 492 | case KEY_UP: | 508 | case KEY_UP: |
