diff options
| author | tmk <nobody@nowhere> | 2013-02-14 15:22:59 +0900 |
|---|---|---|
| committer | tmk <nobody@nowhere> | 2013-02-14 15:22:59 +0900 |
| commit | 0018e19f07661cbae722d64d94cdf6ee388252ff (patch) | |
| tree | 8e9673dff46070d4c77444fd7172df2a38be2242 /common/action.c | |
| parent | 7a31451a077a55e1ad97cf8b31a111c7cd311a4d (diff) | |
| download | qmk_firmware-0018e19f07661cbae722d64d94cdf6ee388252ff.tar.gz qmk_firmware-0018e19f07661cbae722d64d94cdf6ee388252ff.zip | |
Add layer stack
Diffstat (limited to 'common/action.c')
| -rw-r--r-- | common/action.c | 255 |
1 files changed, 211 insertions, 44 deletions
diff --git a/common/action.c b/common/action.c index 6528cd46c..d0c9ddb0a 100644 --- a/common/action.c +++ b/common/action.c | |||
| @@ -163,6 +163,85 @@ static void oneshot_toggle(void) | |||
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | 165 | ||
| 166 | /* | ||
| 167 | * Layer stack | ||
| 168 | */ | ||
| 169 | #define LAYER_STACK_SIZE 8 | ||
| 170 | typedef struct { | ||
| 171 | uint8_t layer:4; | ||
| 172 | uint8_t next:3; | ||
| 173 | bool used; | ||
| 174 | } layer_item_t; | ||
| 175 | |||
| 176 | static uint8_t top_layer = 0; | ||
| 177 | // [0] is sentinel and not used. [0] is null item. | ||
| 178 | static layer_item_t layer_stack[LAYER_STACK_SIZE] = {}; | ||
| 179 | |||
| 180 | static bool layer_push(uint8_t layer) | ||
| 181 | { | ||
| 182 | for (uint8_t i = 1; i < LAYER_STACK_SIZE; i++) { | ||
| 183 | if (!layer_stack[i].used) { | ||
| 184 | layer_stack[i] = (layer_item_t){ .layer = layer, | ||
| 185 | .next = top_layer, | ||
| 186 | .used = true }; | ||
| 187 | top_layer = i; | ||
| 188 | return true; | ||
| 189 | } | ||
| 190 | } | ||
| 191 | return false; | ||
| 192 | } | ||
| 193 | static bool layer_pop(void) | ||
| 194 | { | ||
| 195 | if (layer_stack[top_layer].used) { | ||
| 196 | uint8_t popped = top_layer; | ||
| 197 | top_layer = layer_stack[popped].next; | ||
| 198 | layer_stack[popped] = (layer_item_t){}; | ||
| 199 | return true; | ||
| 200 | } | ||
| 201 | return false; | ||
| 202 | } | ||
| 203 | static bool layer_remove(uint8_t layer) | ||
| 204 | { | ||
| 205 | if (layer_stack[top_layer].used && layer_stack[top_layer].layer == layer) { | ||
| 206 | layer_pop(); | ||
| 207 | debug("layer_remove: top_layer\n"); | ||
| 208 | return true; | ||
| 209 | } | ||
| 210 | |||
| 211 | for (uint8_t i = top_layer; layer_stack[i].used; i = layer_stack[i].next) { | ||
| 212 | debug("layer_remove: ["); debug_dec(i); debug("]"); | ||
| 213 | debug_dec(layer_stack[i].layer); debug("\n"); | ||
| 214 | uint8_t removed = layer_stack[i].next; | ||
| 215 | if (layer_stack[removed].used && layer_stack[removed].layer == layer) { | ||
| 216 | layer_stack[i].next = layer_stack[removed].next; | ||
| 217 | layer_stack[removed] = (layer_item_t){}; | ||
| 218 | debug("layer_remove: removed.\n"); | ||
| 219 | return true; | ||
| 220 | } | ||
| 221 | } | ||
| 222 | return false; | ||
| 223 | } | ||
| 224 | static bool layer_remove_then_push(uint8_t layer) | ||
| 225 | { | ||
| 226 | layer_remove(layer); | ||
| 227 | return layer_push(layer); | ||
| 228 | } | ||
| 229 | static bool layer_remove_or_push(uint8_t layer) | ||
| 230 | { | ||
| 231 | return (layer_remove(layer)) || layer_push(layer); | ||
| 232 | } | ||
| 233 | static void debug_layer_stack(void) | ||
| 234 | { | ||
| 235 | debug("layer_stack: "); | ||
| 236 | layer_item_t item = layer_stack[top_layer]; | ||
| 237 | while (item.used) { | ||
| 238 | debug_dec(item.layer); | ||
| 239 | debug("["); debug_dec(item.next); debug("]"); | ||
| 240 | item = layer_stack[item.next]; | ||
| 241 | } | ||
| 242 | debug("\n"); | ||
| 243 | } | ||
| 244 | |||
| 166 | 245 | ||
| 167 | void action_exec(keyevent_t event) | 246 | void action_exec(keyevent_t event) |
| 168 | { | 247 | { |
| @@ -209,13 +288,26 @@ void action_exec(keyevent_t event) | |||
| 209 | 288 | ||
| 210 | static action_t get_action(key_t key) | 289 | static action_t get_action(key_t key) |
| 211 | { | 290 | { |
| 212 | action_t action = action_for_key(current_layer, key); | 291 | action_t action; |
| 292 | |||
| 293 | /* layer stack */ | ||
| 294 | for (layer_item_t i = layer_stack[top_layer]; i.used; i = layer_stack[i.next]) { | ||
| 295 | action = action_for_key(i.layer, key); | ||
| 296 | if (action.code != ACTION_TRANSPARENT) { | ||
| 297 | debug_layer_stack(); | ||
| 298 | debug("layer_stack: used. "); debug_dec(i.layer); debug("\n"); | ||
| 299 | return action; | ||
| 300 | } | ||
| 301 | debug("layer_stack: through. "); debug_dec(i.layer); debug("\n"); | ||
| 302 | } | ||
| 213 | 303 | ||
| 214 | /* Transparently use default layer */ | 304 | /* current layer */ |
| 305 | action = action_for_key(current_layer, key); | ||
| 306 | |||
| 307 | /* default layer */ | ||
| 215 | if (action.code == ACTION_TRANSPARENT) { | 308 | if (action.code == ACTION_TRANSPARENT) { |
| 216 | // TODO: layer stacking | ||
| 217 | action = action_for_key(default_layer, key); | ||
| 218 | debug("TRNASPARENT: "); debug_hex16(action.code); debug("\n"); | 309 | debug("TRNASPARENT: "); debug_hex16(action.code); debug("\n"); |
| 310 | action = action_for_key(default_layer, key); | ||
| 219 | } | 311 | } |
| 220 | return action; | 312 | return action; |
| 221 | } | 313 | } |
| @@ -287,7 +379,7 @@ static void process_action(keyrecord_t *record) | |||
| 287 | } else { | 379 | } else { |
| 288 | if (tap_count == 0) { | 380 | if (tap_count == 0) { |
| 289 | debug("MODS_TAP: Oneshot: cancel/del_mods\n"); | 381 | debug("MODS_TAP: Oneshot: cancel/del_mods\n"); |
| 290 | // cancel oneshot by holding. | 382 | // cancel oneshot on hold |
| 291 | oneshot_cancel(); | 383 | oneshot_cancel(); |
| 292 | del_mods(mods); | 384 | del_mods(mods); |
| 293 | } | 385 | } |
| @@ -390,22 +482,8 @@ static void process_action(keyrecord_t *record) | |||
| 390 | layer_switch(action.layer.val); | 482 | layer_switch(action.layer.val); |
| 391 | } | 483 | } |
| 392 | break; | 484 | break; |
| 393 | case LAYER_DEFAULT: /* default layer */ | 485 | case LAYER_ON_BOTH: |
| 394 | switch (action.layer.val) { | 486 | layer_switch(action.layer.val); |
| 395 | case DEFAULT_ON_BOTH: | ||
| 396 | layer_switch(default_layer); | ||
| 397 | break; | ||
| 398 | case DEFAULT_ON_PRESS: | ||
| 399 | if (event.pressed) { | ||
| 400 | layer_switch(default_layer); | ||
| 401 | } | ||
| 402 | break; | ||
| 403 | case DEFAULT_ON_RELEASE: | ||
| 404 | if (!event.pressed) { | ||
| 405 | layer_switch(default_layer); | ||
| 406 | } | ||
| 407 | break; | ||
| 408 | } | ||
| 409 | break; | 487 | break; |
| 410 | case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ | 488 | case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ |
| 411 | if (event.pressed) { | 489 | if (event.pressed) { |
| @@ -419,29 +497,39 @@ static void process_action(keyrecord_t *record) | |||
| 419 | } | 497 | } |
| 420 | } | 498 | } |
| 421 | break; | 499 | break; |
| 422 | case LAYER_CHANGE_DEFAULT: /* change default layer */ | 500 | case LAYER_SET_DEFAULT_ON_PRESS: |
| 423 | if (event.pressed) { | 501 | if (event.pressed) { |
| 424 | default_layer = action.layer.val; | 502 | default_layer = action.layer.val; |
| 425 | layer_switch(default_layer); | 503 | layer_switch(default_layer); |
| 426 | } | 504 | } |
| 427 | break; | 505 | break; |
| 428 | default: /* switch layer on hold and key on tap*/ | 506 | case LAYER_SET_DEFAULT_ON_RELEASE: |
| 507 | if (!event.pressed) { | ||
| 508 | default_layer = action.layer.val; | ||
| 509 | layer_switch(default_layer); | ||
| 510 | } | ||
| 511 | break; | ||
| 512 | case LAYER_SET_DEFAULT_ON_BOTH: | ||
| 513 | default_layer = action.layer.val; | ||
| 514 | layer_switch(default_layer); | ||
| 515 | break; | ||
| 516 | default: | ||
| 517 | /* tap key */ | ||
| 429 | if (event.pressed) { | 518 | if (event.pressed) { |
| 430 | if (tap_count > 0) { | 519 | if (IS_TAPPING_KEY(event.key) && tap_count > 0) { |
| 431 | debug("LAYER_PRESSED: Tap: register_code\n"); | 520 | debug("LAYER_SET: Tap: register_code\n"); |
| 432 | register_code(action.layer.code); | 521 | register_code(action.layer.code); |
| 433 | } else { | 522 | } else { |
| 434 | debug("LAYER_PRESSED: No tap: layer_switch\n"); | 523 | debug("LAYER_SET: No tap: layer_set(on press)\n"); |
| 435 | layer_switch(action.layer.val); | 524 | layer_switch(action.layer.val); |
| 436 | } | 525 | } |
| 437 | } else { | 526 | } else { |
| 438 | if (tap_count > 0) { | 527 | if (IS_TAPPING_KEY(event.key) && tap_count > 0) { |
| 439 | debug("LAYER_PRESSED: Tap: unregister_code\n"); | 528 | debug("LAYER_SET: Tap: unregister_code\n"); |
| 440 | unregister_code(action.layer.code); | 529 | unregister_code(action.layer.code); |
| 441 | } else { | 530 | } else { |
| 442 | //debug("LAYER_PRESSED: No tap: NO ACTION\n"); | ||
| 443 | // NOTE: This is needed by legacy keymap support | 531 | // NOTE: This is needed by legacy keymap support |
| 444 | debug("LAYER_PRESSED: No tap: return to default layer\n"); | 532 | debug("LAYER_SET: No tap: return to default layer(on release)\n"); |
| 445 | layer_switch(default_layer); | 533 | layer_switch(default_layer); |
| 446 | } | 534 | } |
| 447 | } | 535 | } |
| @@ -452,9 +540,9 @@ static void process_action(keyrecord_t *record) | |||
| 452 | switch (action.layer.code) { | 540 | switch (action.layer.code) { |
| 453 | case LAYER_MOMENTARY: /* momentary */ | 541 | case LAYER_MOMENTARY: /* momentary */ |
| 454 | if (event.pressed) { | 542 | if (event.pressed) { |
| 455 | layer_switch(current_layer ^ action.layer.val); | 543 | layer_switch(current_layer | action.layer.val); |
| 456 | } else { | 544 | } else { |
| 457 | layer_switch(current_layer ^ action.layer.val); | 545 | layer_switch(current_layer & ~action.layer.val); |
| 458 | } | 546 | } |
| 459 | break; | 547 | break; |
| 460 | case LAYER_ON_PRESS: | 548 | case LAYER_ON_PRESS: |
| @@ -467,6 +555,9 @@ static void process_action(keyrecord_t *record) | |||
| 467 | layer_switch(current_layer ^ action.layer.val); | 555 | layer_switch(current_layer ^ action.layer.val); |
| 468 | } | 556 | } |
| 469 | break; | 557 | break; |
| 558 | case LAYER_ON_BOTH: | ||
| 559 | layer_switch(current_layer ^ action.layer.val); | ||
| 560 | break; | ||
| 470 | case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ | 561 | case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ |
| 471 | if (event.pressed) { | 562 | if (event.pressed) { |
| 472 | if (tap_count < TAPPING_TOGGLE) { | 563 | if (tap_count < TAPPING_TOGGLE) { |
| @@ -480,24 +571,30 @@ static void process_action(keyrecord_t *record) | |||
| 480 | } | 571 | } |
| 481 | } | 572 | } |
| 482 | break; | 573 | break; |
| 483 | case 0xFF: | 574 | case LAYER_SET_DEFAULT_ON_PRESS: |
| 484 | // change default layer | ||
| 485 | if (event.pressed) { | 575 | if (event.pressed) { |
| 486 | default_layer = current_layer ^ action.layer.val; | 576 | default_layer = current_layer ^ action.layer.val; |
| 487 | layer_switch(default_layer); | 577 | layer_switch(default_layer); |
| 488 | } else { | 578 | } |
| 579 | break; | ||
| 580 | case LAYER_SET_DEFAULT_ON_RELEASE: | ||
| 581 | if (!event.pressed) { | ||
| 489 | default_layer = current_layer ^ action.layer.val; | 582 | default_layer = current_layer ^ action.layer.val; |
| 490 | layer_switch(default_layer); | 583 | layer_switch(default_layer); |
| 491 | } | 584 | } |
| 492 | break; | 585 | break; |
| 586 | case LAYER_SET_DEFAULT_ON_BOTH: | ||
| 587 | default_layer = current_layer ^ action.layer.val; | ||
| 588 | layer_switch(default_layer); | ||
| 589 | break; | ||
| 493 | default: | 590 | default: |
| 494 | // with tap key | 591 | // tap key |
| 495 | if (event.pressed) { | 592 | if (event.pressed) { |
| 496 | if (IS_TAPPING_KEY(event.key) && tap_count > 0) { | 593 | if (IS_TAPPING_KEY(event.key) && tap_count > 0) { |
| 497 | debug("LAYER_BIT: Tap: register_code\n"); | 594 | debug("LAYER_BIT: Tap: register_code\n"); |
| 498 | register_code(action.layer.code); | 595 | register_code(action.layer.code); |
| 499 | } else { | 596 | } else { |
| 500 | debug("LAYER_BIT: No tap: layer_switch(bit on)\n"); | 597 | debug("LAYER_BIT: No tap: layer_bit(on press)\n"); |
| 501 | layer_switch(current_layer ^ action.layer.val); | 598 | layer_switch(current_layer ^ action.layer.val); |
| 502 | } | 599 | } |
| 503 | } else { | 600 | } else { |
| @@ -505,13 +602,79 @@ static void process_action(keyrecord_t *record) | |||
| 505 | debug("LAYER_BIT: Tap: unregister_code\n"); | 602 | debug("LAYER_BIT: Tap: unregister_code\n"); |
| 506 | unregister_code(action.layer.code); | 603 | unregister_code(action.layer.code); |
| 507 | } else { | 604 | } else { |
| 508 | debug("LAYER_BIT: No tap: layer_switch(bit off)\n"); | 605 | debug("LAYER_BIT: No tap: layer_bit(on release)\n"); |
| 509 | layer_switch(current_layer ^ action.layer.val); | 606 | layer_switch(current_layer ^ action.layer.val); |
| 510 | } | 607 | } |
| 511 | } | 608 | } |
| 512 | break; | 609 | break; |
| 513 | } | 610 | } |
| 514 | break; | 611 | break; |
| 612 | case ACT_LAYER_STACK: | ||
| 613 | switch (action.layer.code) { | ||
| 614 | case LAYER_MOMENTARY: /* momentary */ | ||
| 615 | if (event.pressed) { | ||
| 616 | layer_remove_then_push(action.layer.val); | ||
| 617 | debug_layer_stack(); | ||
| 618 | } else { | ||
| 619 | layer_remove(action.layer.val); | ||
| 620 | debug_layer_stack(); | ||
| 621 | } | ||
| 622 | break; | ||
| 623 | case LAYER_ON_PRESS: | ||
| 624 | if (event.pressed) { | ||
| 625 | layer_remove_or_push(action.layer.val); | ||
| 626 | debug_layer_stack(); | ||
| 627 | } | ||
| 628 | break; | ||
| 629 | case LAYER_ON_RELEASE: | ||
| 630 | if (!event.pressed) { | ||
| 631 | layer_remove_or_push(action.layer.val); | ||
| 632 | debug_layer_stack(); | ||
| 633 | } | ||
| 634 | break; | ||
| 635 | case LAYER_ON_BOTH: | ||
| 636 | layer_remove_or_push(action.layer.val); | ||
| 637 | debug_layer_stack(); | ||
| 638 | break; | ||
| 639 | case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ | ||
| 640 | if (event.pressed) { | ||
| 641 | if (tap_count < TAPPING_TOGGLE) { | ||
| 642 | debug("LAYER_STACK: tap toggle(press).\n"); | ||
| 643 | layer_remove_or_push(action.layer.val); | ||
| 644 | debug_layer_stack(); | ||
| 645 | } | ||
| 646 | } else { | ||
| 647 | if (tap_count <= TAPPING_TOGGLE) { | ||
| 648 | debug("LAYER_STACK: tap toggle(release).\n"); | ||
| 649 | layer_remove_or_push(action.layer.val); | ||
| 650 | debug_layer_stack(); | ||
| 651 | } | ||
| 652 | } | ||
| 653 | break; | ||
| 654 | default: | ||
| 655 | // tap key | ||
| 656 | if (event.pressed) { | ||
| 657 | if (IS_TAPPING_KEY(event.key) && tap_count > 0) { | ||
| 658 | debug("LAYER_STACK: Tap: register_code\n"); | ||
| 659 | register_code(action.layer.code); | ||
| 660 | } else { | ||
| 661 | debug("LAYER_STACK: No tap: layer_stack(on press)\n"); | ||
| 662 | layer_remove_or_push(action.layer.val); | ||
| 663 | debug_layer_stack(); | ||
| 664 | } | ||
| 665 | } else { | ||
| 666 | if (IS_TAPPING_KEY(event.key) && tap_count > 0) { | ||
| 667 | debug("LAYER_STACK: Tap: unregister_code\n"); | ||
| 668 | unregister_code(action.layer.code); | ||
| 669 | } else { | ||
| 670 | debug("LAYER_STACK: No tap: layer_stack(on release)\n"); | ||
| 671 | layer_remove_or_push(action.layer.val); | ||
| 672 | debug_layer_stack(); | ||
| 673 | } | ||
| 674 | } | ||
| 675 | break; | ||
| 676 | } | ||
| 677 | break; | ||
| 515 | 678 | ||
| 516 | /* Extentions */ | 679 | /* Extentions */ |
| 517 | case ACT_MACRO: | 680 | case ACT_MACRO: |
| @@ -839,7 +1002,10 @@ bool is_tap_key(key_t key) | |||
| 839 | case LAYER_MOMENTARY: | 1002 | case LAYER_MOMENTARY: |
| 840 | case LAYER_ON_PRESS: | 1003 | case LAYER_ON_PRESS: |
| 841 | case LAYER_ON_RELEASE: | 1004 | case LAYER_ON_RELEASE: |
| 842 | case LAYER_DEFAULT: | 1005 | case LAYER_ON_BOTH: |
| 1006 | case LAYER_SET_DEFAULT_ON_PRESS: | ||
| 1007 | case LAYER_SET_DEFAULT_ON_RELEASE: | ||
| 1008 | case LAYER_SET_DEFAULT_ON_BOTH: | ||
| 843 | return false; | 1009 | return false; |
| 844 | case LAYER_TAP_TOGGLE: | 1010 | case LAYER_TAP_TOGGLE: |
| 845 | default: /* tap key */ | 1011 | default: /* tap key */ |
| @@ -876,8 +1042,9 @@ static void debug_action(action_t action) | |||
| 876 | case ACT_RMODS_TAP: debug("ACT_RMODS_TAP"); break; | 1042 | case ACT_RMODS_TAP: debug("ACT_RMODS_TAP"); break; |
| 877 | case ACT_USAGE: debug("ACT_USAGE"); break; | 1043 | case ACT_USAGE: debug("ACT_USAGE"); break; |
| 878 | case ACT_MOUSEKEY: debug("ACT_MOUSEKEY"); break; | 1044 | case ACT_MOUSEKEY: debug("ACT_MOUSEKEY"); break; |
| 879 | case ACT_LAYER: debug("ACT_LAYER"); break; | 1045 | case ACT_LAYER: debug("ACT_LAYER"); break; |
| 880 | case ACT_LAYER_BIT: debug("ACT_LAYER_BIT"); break; | 1046 | case ACT_LAYER_BIT: debug("ACT_LAYER_BIT"); break; |
| 1047 | case ACT_LAYER_STACK: debug("ACT_LAYER_STACK"); break; | ||
| 881 | case ACT_MACRO: debug("ACT_MACRO"); break; | 1048 | case ACT_MACRO: debug("ACT_MACRO"); break; |
| 882 | case ACT_COMMAND: debug("ACT_COMMAND"); break; | 1049 | case ACT_COMMAND: debug("ACT_COMMAND"); break; |
| 883 | case ACT_FUNCTION: debug("ACT_FUNCTION"); break; | 1050 | case ACT_FUNCTION: debug("ACT_FUNCTION"); break; |
