Parent directory

action.c

42121 bytes
   1/*
   2Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
   3
   4This program is free software: you can redistribute it and/or modify
   5it under the terms of the GNU General Public License as published by
   6the Free Software Foundation, either version 2 of the License, or
   7(at your option) any later version.
   8
   9This program is distributed in the hope that it will be useful,
  10but WITHOUT ANY WARRANTY; without even the implied warranty of
  11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12GNU General Public License for more details.
  13
  14You should have received a copy of the GNU General Public License
  15along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16*/
  17#include <limits.h>
  18
  19#include "host.h"
  20#include "keycode.h"
  21#include "keyboard.h"
  22#include "mousekey.h"
  23#include "programmable_button.h"
  24#include "command.h"
  25#include "led.h"
  26#include "action_layer.h"
  27#include "action_tapping.h"
  28#include "action_util.h"
  29#include "action.h"
  30#include "wait.h"
  31#include "keycode_config.h"
  32#include "debug.h"
  33#include "quantum.h"
  34
  35#ifdef BACKLIGHT_ENABLE
  36#    include "backlight.h"
  37#endif
  38
  39#ifdef POINTING_DEVICE_ENABLE
  40#    include "pointing_device.h"
  41#endif
  42
  43#if defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE) && defined(SWAP_HANDS_ENABLE)
  44#    include "encoder.h"
  45#endif
  46
  47int tp_buttons;
  48
  49#if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
  50int retro_tapping_counter = 0;
  51#endif
  52
  53#if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING)
  54#    include "process_auto_shift.h"
  55#endif
  56
  57#ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
  58__attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
  59    return false;
  60}
  61#endif
  62
  63#ifdef RETRO_TAPPING_PER_KEY
  64__attribute__((weak)) bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) {
  65    return false;
  66}
  67#endif
  68
  69/** \brief Called to execute an action.
  70 *
  71 * FIXME: Needs documentation.
  72 */
  73void action_exec(keyevent_t event) {
  74    if (IS_EVENT(event)) {
  75        ac_dprintf("\n---- action_exec: start -----\n");
  76        ac_dprintf("EVENT: ");
  77        debug_event(event);
  78        ac_dprintf("\n");
  79#if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
  80        retro_tapping_counter++;
  81#endif
  82    }
  83
  84    if (event.pressed) {
  85        // clear the potential weak mods left by previously pressed keys
  86        clear_weak_mods();
  87    }
  88
  89#ifdef SWAP_HANDS_ENABLE
  90    // Swap hands handles both keys and encoders, if ENCODER_MAP_ENABLE is defined.
  91    if (IS_EVENT(event)) {
  92        process_hand_swap(&event);
  93    }
  94#endif
  95
  96    keyrecord_t record = {.event = event};
  97
  98#ifndef NO_ACTION_ONESHOT
  99    if (keymap_config.oneshot_enable) {
 100#    if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
 101        if (has_oneshot_layer_timed_out()) {
 102            clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
 103        }
 104        if (has_oneshot_mods_timed_out()) {
 105            clear_oneshot_mods();
 106        }
 107#        ifdef SWAP_HANDS_ENABLE
 108        if (has_oneshot_swaphands_timed_out()) {
 109            clear_oneshot_swaphands();
 110        }
 111#        endif
 112#    endif
 113    }
 114#endif
 115
 116#ifndef NO_ACTION_TAPPING
 117#    if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
 118    if (event.pressed) {
 119        retroshift_poll_time(&event);
 120    }
 121#    endif
 122    if (IS_NOEVENT(record.event) || pre_process_record_quantum(&record)) {
 123        action_tapping_process(record);
 124    }
 125#else
 126    if (IS_NOEVENT(record.event) || pre_process_record_quantum(&record)) {
 127        process_record(&record);
 128    }
 129    if (IS_EVENT(record.event)) {
 130        ac_dprintf("processed: ");
 131        debug_record(record);
 132        dprintln();
 133    }
 134#endif
 135}
 136
 137#ifdef SWAP_HANDS_ENABLE
 138extern const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS];
 139#    ifdef ENCODER_MAP_ENABLE
 140extern const uint8_t PROGMEM encoder_hand_swap_config[NUM_ENCODERS];
 141#    endif // ENCODER_MAP_ENABLE
 142
 143bool swap_hands = false;
 144bool swap_held  = false;
 145
 146bool should_swap_hands(size_t index, uint8_t *swap_state, bool pressed) {
 147    size_t  array_index = index / (CHAR_BIT);
 148    size_t  bit_index   = index % (CHAR_BIT);
 149    uint8_t bit_val     = 1 << bit_index;
 150    bool    do_swap     = pressed ? swap_hands : swap_state[array_index] & bit_val;
 151    return do_swap;
 152}
 153
 154void set_swap_hands_state(size_t index, uint8_t *swap_state, bool on) {
 155    size_t  array_index = index / (CHAR_BIT);
 156    size_t  bit_index   = index % (CHAR_BIT);
 157    uint8_t bit_val     = 1 << bit_index;
 158    if (on) {
 159        swap_state[array_index] |= bit_val;
 160    } else {
 161        swap_state[array_index] &= ~bit_val;
 162    }
 163}
 164
 165void swap_hands_on(void) {
 166    swap_hands = true;
 167}
 168
 169void swap_hands_off(void) {
 170    swap_hands = false;
 171}
 172
 173void swap_hands_toggle(void) {
 174    swap_hands = !swap_hands;
 175}
 176
 177bool is_swap_hands_on(void) {
 178    return swap_hands;
 179}
 180
 181/** \brief Process Hand Swap
 182 *
 183 * FIXME: Needs documentation.
 184 */
 185void process_hand_swap(keyevent_t *event) {
 186    keypos_t pos = event->key;
 187    if (IS_KEYEVENT(*event) && pos.row < MATRIX_ROWS && pos.col < MATRIX_COLS) {
 188        static uint8_t matrix_swap_state[((MATRIX_ROWS * MATRIX_COLS) + (CHAR_BIT)-1) / (CHAR_BIT)];
 189        size_t         index   = (size_t)(pos.row * MATRIX_COLS) + pos.col;
 190        bool           do_swap = should_swap_hands(index, matrix_swap_state, event->pressed);
 191        if (do_swap) {
 192            event->key.row = pgm_read_byte(&hand_swap_config[pos.row][pos.col].row);
 193            event->key.col = pgm_read_byte(&hand_swap_config[pos.row][pos.col].col);
 194            set_swap_hands_state(index, matrix_swap_state, true);
 195        } else {
 196            set_swap_hands_state(index, matrix_swap_state, false);
 197        }
 198    }
 199#    ifdef ENCODER_MAP_ENABLE
 200    else if (IS_ENCODEREVENT(*event) && (pos.row == KEYLOC_ENCODER_CW || pos.row == KEYLOC_ENCODER_CCW)) {
 201        static uint8_t encoder_swap_state[((NUM_ENCODERS) + (CHAR_BIT)-1) / (CHAR_BIT)];
 202        size_t         index   = pos.col;
 203        bool           do_swap = should_swap_hands(index, encoder_swap_state, event->pressed);
 204        if (do_swap) {
 205            event->key.row = pos.row;
 206            event->key.col = pgm_read_byte(&encoder_hand_swap_config[pos.col]);
 207            set_swap_hands_state(index, encoder_swap_state, true);
 208        } else {
 209            set_swap_hands_state(index, encoder_swap_state, false);
 210        }
 211    }
 212#    endif // ENCODER_MAP_ENABLE
 213}
 214#endif
 215
 216#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
 217bool disable_action_cache = false;
 218
 219void process_record_nocache(keyrecord_t *record) {
 220    disable_action_cache = true;
 221    process_record(record);
 222    disable_action_cache = false;
 223}
 224#else
 225void process_record_nocache(keyrecord_t *record) {
 226    process_record(record);
 227}
 228#endif
 229
 230__attribute__((weak)) bool process_record_quantum(keyrecord_t *record) {
 231    return true;
 232}
 233
 234__attribute__((weak)) void post_process_record_quantum(keyrecord_t *record) {}
 235
 236#ifndef NO_ACTION_TAPPING
 237/** \brief Allows for handling tap-hold actions immediately instead of waiting for TAPPING_TERM or another keypress.
 238 *
 239 * FIXME: Needs documentation.
 240 */
 241void process_record_tap_hint(keyrecord_t *record) {
 242    if (!IS_KEYEVENT(record->event)) {
 243        return;
 244    }
 245
 246    action_t action = layer_switch_get_action(record->event.key);
 247
 248    switch (action.kind.id) {
 249#    ifdef SWAP_HANDS_ENABLE
 250        case ACT_SWAP_HANDS:
 251            switch (action.swap.code) {
 252                case OP_SH_ONESHOT:
 253                    break;
 254                case OP_SH_TAP_TOGGLE:
 255                default:
 256                    swap_hands = !swap_hands;
 257                    swap_held  = true;
 258            }
 259            break;
 260#    endif
 261    }
 262}
 263#endif
 264
 265/** \brief Take a key event (key press or key release) and processes it.
 266 *
 267 * FIXME: Needs documentation.
 268 */
 269void process_record(keyrecord_t *record) {
 270    if (IS_NOEVENT(record->event)) {
 271        return;
 272    }
 273
 274    if (!process_record_quantum(record)) {
 275#ifndef NO_ACTION_ONESHOT
 276        if (is_oneshot_layer_active() && record->event.pressed && keymap_config.oneshot_enable) {
 277            clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
 278        }
 279#endif
 280        return;
 281    }
 282
 283    process_record_handler(record);
 284    post_process_record_quantum(record);
 285}
 286
 287void process_record_handler(keyrecord_t *record) {
 288#if defined(COMBO_ENABLE) || defined(REPEAT_KEY_ENABLE)
 289    action_t action;
 290    if (record->keycode) {
 291        action = action_for_keycode(record->keycode);
 292    } else {
 293        action = store_or_get_action(record->event.pressed, record->event.key);
 294    }
 295#else
 296    action_t action = store_or_get_action(record->event.pressed, record->event.key);
 297#endif
 298    ac_dprintf("ACTION: ");
 299    debug_action(action);
 300#ifndef NO_ACTION_LAYER
 301    ac_dprintf(" layer_state: ");
 302    layer_debug();
 303    ac_dprintf(" default_layer_state: ");
 304    default_layer_debug();
 305#endif
 306    ac_dprintf("\n");
 307
 308    process_action(record, action);
 309}
 310
 311/**
 312 * @brief handles all the messy mouse stuff
 313 *
 314 * Handles all the edgecases and special stuff that is needed for coexistense
 315 * of the multiple mouse subsystems.
 316 *
 317 * @param mouse_keycode[in] uint8_t mouse keycode
 318 * @param pressed[in] bool
 319 */
 320
 321void register_mouse(uint8_t mouse_keycode, bool pressed) {
 322#ifdef MOUSEKEY_ENABLE
 323    // if mousekeys is enabled, let it do the brunt of the work
 324    if (pressed) {
 325        mousekey_on(mouse_keycode);
 326    } else {
 327        mousekey_off(mouse_keycode);
 328    }
 329    // should mousekeys send report, or does something else handle this?
 330    switch (mouse_keycode) {
 331#    if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE)
 332        case QK_MOUSE_BUTTON_1 ... QK_MOUSE_BUTTON_8:
 333            // let pointing device handle the buttons
 334            // expand if/when it handles more of the code
 335#        if defined(POINTING_DEVICE_ENABLE)
 336            pointing_device_keycode_handler(mouse_keycode, pressed);
 337#        endif
 338            break;
 339#    endif
 340        default:
 341            mousekey_send();
 342            break;
 343    }
 344#elif defined(POINTING_DEVICE_ENABLE)
 345    // if mousekeys isn't enabled, and pointing device is enabled, then
 346    // let pointing device do all the heavy lifting, then
 347    if (IS_MOUSE_KEYCODE(mouse_keycode)) {
 348        pointing_device_keycode_handler(mouse_keycode, pressed);
 349    }
 350#endif
 351
 352#ifdef PS2_MOUSE_ENABLE
 353    // make sure that ps2 mouse has button report synced
 354    if (QK_MOUSE_BUTTON_1 <= mouse_keycode && mouse_keycode <= QK_MOUSE_BUTTON_3) {
 355        uint8_t tmp_button_msk = MOUSE_BTN_MASK(mouse_keycode - QK_MOUSE_BUTTON_1);
 356        tp_buttons             = pressed ? tp_buttons | tmp_button_msk : tp_buttons & ~tmp_button_msk;
 357    }
 358#endif
 359}
 360
 361/** \brief Take an action and processes it.
 362 *
 363 * FIXME: Needs documentation.
 364 */
 365void process_action(keyrecord_t *record, action_t action) {
 366    keyevent_t event = record->event;
 367#ifndef NO_ACTION_TAPPING
 368    uint8_t tap_count = record->tap.count;
 369#endif
 370
 371#ifndef NO_ACTION_ONESHOT
 372    bool do_release_oneshot = false;
 373    // notice we only clear the one shot layer if the pressed key is not a modifier.
 374    if (is_oneshot_layer_active() && event.pressed &&
 375        (action.kind.id == ACT_USAGE || !(IS_MODIFIER_KEYCODE(action.key.code)
 376#    ifndef NO_ACTION_TAPPING
 377                                          || ((action.kind.id == ACT_LMODS_TAP || action.kind.id == ACT_RMODS_TAP) && (action.layer_tap.code <= MODS_TAP_TOGGLE || tap_count == 0))
 378#    endif
 379                                              ))
 380#    ifdef SWAP_HANDS_ENABLE
 381        && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)
 382#    endif
 383        && keymap_config.oneshot_enable) {
 384        clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
 385        do_release_oneshot = !is_oneshot_layer_active();
 386    }
 387#endif
 388
 389    switch (action.kind.id) {
 390        /* Key and Mods */
 391        case ACT_LMODS:
 392        case ACT_RMODS: {
 393            uint8_t mods = (action.kind.id == ACT_LMODS) ? action.key.mods : action.key.mods << 4;
 394            if (event.pressed) {
 395                if (mods) {
 396                    if (IS_MODIFIER_KEYCODE(action.key.code) || action.key.code == KC_NO) {
 397                        // e.g. LSFT(KC_LEFT_GUI): we don't want the LSFT to be weak as it would make it useless.
 398                        // This also makes LSFT(KC_LEFT_GUI) behave exactly the same as LGUI(KC_LEFT_SHIFT).
 399                        // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO).
 400                        add_mods(mods);
 401                    } else {
 402                        add_weak_mods(mods);
 403                    }
 404                    send_keyboard_report();
 405                }
 406                register_code(action.key.code);
 407            } else {
 408                unregister_code(action.key.code);
 409                if (mods) {
 410                    if (IS_MODIFIER_KEYCODE(action.key.code) || action.key.code == KC_NO) {
 411                        del_mods(mods);
 412                    } else {
 413                        del_weak_mods(mods);
 414                    }
 415                    send_keyboard_report();
 416                }
 417            }
 418        } break;
 419        case ACT_LMODS_TAP:
 420        case ACT_RMODS_TAP: {
 421#ifndef NO_ACTION_TAPPING
 422            uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods : action.key.mods << 4;
 423            switch (action.layer_tap.code) {
 424#    ifndef NO_ACTION_ONESHOT
 425                case MODS_ONESHOT:
 426                    // Oneshot modifier
 427                    if (!keymap_config.oneshot_enable) {
 428                        if (event.pressed) {
 429                            if (mods) {
 430                                if (IS_MODIFIER_KEYCODE(action.key.code) || action.key.code == KC_NO) {
 431                                    // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless.
 432                                    // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT).
 433                                    // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO).
 434                                    add_mods(mods);
 435                                } else {
 436                                    add_weak_mods(mods);
 437                                }
 438                                send_keyboard_report();
 439                            }
 440                            register_code(action.key.code);
 441                        } else {
 442                            unregister_code(action.key.code);
 443                            if (mods) {
 444                                if (IS_MODIFIER_KEYCODE(action.key.code) || action.key.code == KC_NO) {
 445                                    del_mods(mods);
 446                                } else {
 447                                    del_weak_mods(mods);
 448                                }
 449                                send_keyboard_report();
 450                            }
 451                        }
 452                    } else {
 453                        if (event.pressed) {
 454                            if (tap_count == 0) {
 455                                // Not a tap, but a hold: register the held mod
 456                                ac_dprintf("MODS_TAP: Oneshot: 0\n");
 457                                register_mods(mods);
 458                            } else if (tap_count == 1) {
 459                                ac_dprintf("MODS_TAP: Oneshot: start\n");
 460                                add_oneshot_mods(mods);
 461#        if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
 462                            } else if (tap_count == ONESHOT_TAP_TOGGLE) {
 463                                ac_dprintf("MODS_TAP: Toggling oneshot");
 464                                register_mods(mods);
 465                                del_oneshot_mods(mods);
 466                                add_oneshot_locked_mods(mods);
 467#        endif
 468                            }
 469                        } else {
 470                            if (tap_count == 0) {
 471                                // Release hold: unregister the held mod and its variants
 472                                unregister_mods(mods);
 473                                del_oneshot_mods(mods);
 474                                del_oneshot_locked_mods(mods);
 475#        if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
 476                            } else if (tap_count == 1 && (mods & get_mods())) {
 477                                unregister_mods(mods);
 478                                del_oneshot_mods(mods);
 479                                del_oneshot_locked_mods(mods);
 480#        endif
 481                            }
 482                        }
 483                    }
 484                    break;
 485#    endif
 486                case MODS_TAP_TOGGLE:
 487                    if (event.pressed) {
 488                        if (tap_count <= TAPPING_TOGGLE) {
 489                            register_mods(mods);
 490                        }
 491                    } else {
 492                        if (tap_count < TAPPING_TOGGLE) {
 493                            unregister_mods(mods);
 494                        }
 495                    }
 496                    break;
 497                default:
 498                    if (event.pressed) {
 499                        if (tap_count > 0) {
 500#    ifdef HOLD_ON_OTHER_KEY_PRESS
 501                            if (
 502#        ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
 503                                get_hold_on_other_key_press(get_event_keycode(record->event, false), record) &&
 504#        endif
 505                                record->tap.interrupted) {
 506                                ac_dprintf("mods_tap: tap: cancel: add_mods\n");
 507                                // ad hoc: set 0 to cancel tap
 508                                record->tap.count = 0;
 509                                register_mods(mods);
 510                            } else
 511#    endif
 512                            {
 513                                ac_dprintf("MODS_TAP: Tap: register_code\n");
 514                                register_code(action.key.code);
 515                            }
 516                        } else {
 517                            ac_dprintf("MODS_TAP: No tap: add_mods\n");
 518                            register_mods(mods);
 519                        }
 520                    } else {
 521                        if (tap_count > 0) {
 522                            ac_dprintf("MODS_TAP: Tap: unregister_code\n");
 523                            if (action.layer_tap.code == KC_CAPS_LOCK) {
 524                                wait_ms(TAP_HOLD_CAPS_DELAY);
 525                            } else {
 526                                wait_ms(TAP_CODE_DELAY);
 527                            }
 528                            unregister_code(action.key.code);
 529                        } else {
 530                            ac_dprintf("MODS_TAP: No tap: add_mods\n");
 531#    if defined(RETRO_TAPPING) && defined(DUMMY_MOD_NEUTRALIZER_KEYCODE)
 532                            // Send a dummy keycode to neutralize flashing modifiers
 533                            // if the key was held and then released with no interruptions.
 534                            if (retro_tapping_counter == 2) {
 535                                neutralize_flashing_modifiers(get_mods());
 536                            }
 537#    endif
 538                            unregister_mods(mods);
 539                        }
 540                    }
 541                    break;
 542            }
 543#endif // NO_ACTION_TAPPING
 544        } break;
 545#ifdef EXTRAKEY_ENABLE
 546        /* other HID usage */
 547        case ACT_USAGE:
 548            switch (action.usage.page) {
 549                case PAGE_SYSTEM:
 550                    host_system_send(event.pressed ? action.usage.code : 0);
 551                    break;
 552                case PAGE_CONSUMER:
 553                    host_consumer_send(event.pressed ? action.usage.code : 0);
 554                    break;
 555            }
 556            break;
 557#endif // EXTRAKEY_ENABLE
 558        /* Mouse key */
 559        case ACT_MOUSEKEY:
 560            register_mouse(action.key.code, event.pressed);
 561            break;
 562#ifndef NO_ACTION_LAYER
 563        case ACT_LAYER:
 564            if (action.layer_bitop.on == 0) {
 565                /* Default Layer Bitwise Operation */
 566                if (!event.pressed) {
 567                    uint8_t       shift = action.layer_bitop.part * 4;
 568                    layer_state_t bits  = ((layer_state_t)action.layer_bitop.bits) << shift;
 569                    layer_state_t mask  = (action.layer_bitop.xbit) ? ~(((layer_state_t)0xf) << shift) : 0;
 570                    switch (action.layer_bitop.op) {
 571                        case OP_BIT_AND:
 572                            default_layer_and(bits | mask);
 573                            break;
 574                        case OP_BIT_OR:
 575                            default_layer_or(bits | mask);
 576                            break;
 577                        case OP_BIT_XOR:
 578                            default_layer_xor(bits | mask);
 579                            break;
 580                        case OP_BIT_SET:
 581                            default_layer_set(bits | mask);
 582                            break;
 583                    }
 584                }
 585            } else {
 586                /* Layer Bitwise Operation */
 587                if (event.pressed ? (action.layer_bitop.on & ON_PRESS) : (action.layer_bitop.on & ON_RELEASE)) {
 588                    uint8_t       shift = action.layer_bitop.part * 4;
 589                    layer_state_t bits  = ((layer_state_t)action.layer_bitop.bits) << shift;
 590                    layer_state_t mask  = (action.layer_bitop.xbit) ? ~(((layer_state_t)0xf) << shift) : 0;
 591                    switch (action.layer_bitop.op) {
 592                        case OP_BIT_AND:
 593                            layer_and(bits | mask);
 594                            break;
 595                        case OP_BIT_OR:
 596                            layer_or(bits | mask);
 597                            break;
 598                        case OP_BIT_XOR:
 599                            layer_xor(bits | mask);
 600                            break;
 601                        case OP_BIT_SET:
 602                            layer_state_set(bits | mask);
 603                            break;
 604                    }
 605                }
 606            }
 607            break;
 608        case ACT_LAYER_MODS:
 609            if (event.pressed) {
 610                layer_on(action.layer_mods.layer);
 611                register_mods(action.layer_mods.mods);
 612            } else {
 613                unregister_mods(action.layer_mods.mods);
 614                layer_off(action.layer_mods.layer);
 615            }
 616            break;
 617        case ACT_LAYER_TAP:
 618        case ACT_LAYER_TAP_EXT:
 619            switch (action.layer_tap.code) {
 620#    ifndef NO_ACTION_TAPPING
 621                case OP_TAP_TOGGLE:
 622                    /* tap toggle */
 623                    if (event.pressed) {
 624                        if (tap_count < TAPPING_TOGGLE) {
 625                            layer_invert(action.layer_tap.val);
 626                        }
 627                    } else {
 628                        if (tap_count <= TAPPING_TOGGLE) {
 629                            layer_invert(action.layer_tap.val);
 630                        }
 631                    }
 632                    break;
 633#    endif
 634                case OP_ON_OFF:
 635                    event.pressed ? layer_on(action.layer_tap.val) : layer_off(action.layer_tap.val);
 636                    break;
 637                case OP_OFF_ON:
 638                    event.pressed ? layer_off(action.layer_tap.val) : layer_on(action.layer_tap.val);
 639                    break;
 640                case OP_SET_CLEAR:
 641                    event.pressed ? layer_move(action.layer_tap.val) : layer_clear();
 642                    break;
 643#    if !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING)
 644                case OP_ONESHOT:
 645                    // Oneshot modifier
 646                    if (!keymap_config.oneshot_enable) {
 647                        if (event.pressed) {
 648                            layer_on(action.layer_tap.val);
 649                        } else {
 650                            layer_off(action.layer_tap.val);
 651                        }
 652                    } else {
 653#        if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
 654                        do_release_oneshot = false;
 655                        if (event.pressed) {
 656                            if (get_oneshot_layer_state() == ONESHOT_TOGGLED) {
 657                                reset_oneshot_layer();
 658                                layer_off(action.layer_tap.val);
 659                                break;
 660                            } else if (tap_count < ONESHOT_TAP_TOGGLE) {
 661                                set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
 662                            }
 663                        } else {
 664                            if (tap_count >= ONESHOT_TAP_TOGGLE) {
 665                                reset_oneshot_layer();
 666                                set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED);
 667                            } else {
 668                                clear_oneshot_layer_state(ONESHOT_PRESSED);
 669                            }
 670                        }
 671#        else
 672                        if (event.pressed) {
 673                            set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
 674                        } else {
 675                            clear_oneshot_layer_state(ONESHOT_PRESSED);
 676                            if (tap_count > 1) {
 677                                clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
 678                            }
 679                        }
 680#        endif
 681                    }
 682#    else  // NO_ACTION_ONESHOT && NO_ACTION_TAPPING
 683                    if (event.pressed) {
 684                        layer_on(action.layer_tap.val);
 685                    } else {
 686                        layer_off(action.layer_tap.val);
 687                    }
 688#    endif // !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING)
 689                    break;
 690                default:
 691#    ifndef NO_ACTION_TAPPING /* tap key */
 692                    if (event.pressed) {
 693                        if (tap_count > 0) {
 694                            ac_dprintf("KEYMAP_TAP_KEY: Tap: register_code\n");
 695                            register_code(action.layer_tap.code);
 696                        } else {
 697                            ac_dprintf("KEYMAP_TAP_KEY: No tap: On on press\n");
 698                            layer_on(action.layer_tap.val);
 699                        }
 700                    } else {
 701                        if (tap_count > 0) {
 702                            ac_dprintf("KEYMAP_TAP_KEY: Tap: unregister_code\n");
 703                            if (action.layer_tap.code == KC_CAPS_LOCK) {
 704                                wait_ms(TAP_HOLD_CAPS_DELAY);
 705                            } else {
 706                                wait_ms(TAP_CODE_DELAY);
 707                            }
 708                            unregister_code(action.layer_tap.code);
 709                        } else {
 710                            ac_dprintf("KEYMAP_TAP_KEY: No tap: Off on release\n");
 711                            layer_off(action.layer_tap.val);
 712                        }
 713                    }
 714#    else
 715                    if (event.pressed) {
 716                        ac_dprintf("KEYMAP_TAP_KEY: Tap: register_code\n");
 717                        register_code(action.layer_tap.code);
 718                    } else {
 719                        ac_dprintf("KEYMAP_TAP_KEY: Tap: unregister_code\n");
 720                        if (action.layer_tap.code == KC_CAPS) {
 721                            wait_ms(TAP_HOLD_CAPS_DELAY);
 722                        } else {
 723                            wait_ms(TAP_CODE_DELAY);
 724                        }
 725                        unregister_code(action.layer_tap.code);
 726                    }
 727#    endif
 728                    break;
 729            }
 730            break;
 731#endif // NO_ACTION_LAYER
 732
 733#ifdef SWAP_HANDS_ENABLE
 734        case ACT_SWAP_HANDS:
 735            switch (action.swap.code) {
 736                case OP_SH_TOGGLE:
 737                    if (event.pressed) {
 738                        swap_hands = !swap_hands;
 739                    }
 740                    break;
 741                case OP_SH_ON_OFF:
 742                    swap_hands = event.pressed;
 743                    break;
 744                case OP_SH_OFF_ON:
 745                    swap_hands = !event.pressed;
 746                    break;
 747                case OP_SH_ON:
 748                    if (!event.pressed) {
 749                        swap_hands = true;
 750                    }
 751                    break;
 752                case OP_SH_OFF:
 753                    if (!event.pressed) {
 754                        swap_hands = false;
 755                    }
 756                    break;
 757#    ifndef NO_ACTION_ONESHOT
 758                case OP_SH_ONESHOT:
 759                    if (event.pressed) {
 760                        set_oneshot_swaphands();
 761                    } else {
 762                        release_oneshot_swaphands();
 763                    }
 764                    break;
 765#    endif
 766
 767#    ifndef NO_ACTION_TAPPING
 768                case OP_SH_TAP_TOGGLE:
 769                    /* tap toggle */
 770
 771                    if (event.pressed) {
 772                        if (swap_held) {
 773                            swap_held = false;
 774                        } else {
 775                            swap_hands = !swap_hands;
 776                        }
 777                    } else {
 778                        if (tap_count < TAPPING_TOGGLE) {
 779                            swap_hands = !swap_hands;
 780                        }
 781                    }
 782                    break;
 783                default:
 784                    /* tap key */
 785                    if (tap_count > 0) {
 786                        if (swap_held) {
 787                            swap_hands = !swap_hands; // undo hold set up in _tap_hint
 788                            swap_held  = false;
 789                        }
 790                        if (event.pressed) {
 791                            register_code(action.swap.code);
 792                        } else {
 793                            wait_ms(TAP_CODE_DELAY);
 794                            unregister_code(action.swap.code);
 795                            *record = (keyrecord_t){}; // hack: reset tap mode
 796                        }
 797                    } else {
 798                        if (swap_held && !event.pressed) {
 799                            swap_hands = !swap_hands; // undo hold set up in _tap_hint
 800                            swap_held  = false;
 801                        }
 802                    }
 803#    endif
 804            }
 805#endif
 806        default:
 807            break;
 808    }
 809
 810#ifndef NO_ACTION_LAYER
 811    // if this event is a layer action, update the leds
 812    switch (action.kind.id) {
 813        case ACT_LAYER:
 814        case ACT_LAYER_MODS:
 815#    ifndef NO_ACTION_TAPPING
 816        case ACT_LAYER_TAP:
 817        case ACT_LAYER_TAP_EXT:
 818#    endif
 819            led_set(host_keyboard_leds());
 820            break;
 821        default:
 822            break;
 823    }
 824#endif
 825
 826#ifndef NO_ACTION_TAPPING
 827#    if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
 828    if (!is_tap_action(action)) {
 829        retro_tapping_counter = 0;
 830    } else {
 831        if (event.pressed) {
 832            if (tap_count > 0) {
 833                retro_tapping_counter = 0;
 834            }
 835        } else {
 836            if (tap_count > 0) {
 837                retro_tapping_counter = 0;
 838            } else {
 839                if (
 840#        ifdef RETRO_TAPPING_PER_KEY
 841                    get_retro_tapping(get_event_keycode(record->event, false), record) &&
 842#        endif
 843                    retro_tapping_counter == 2) {
 844#        if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
 845                    process_auto_shift(action.layer_tap.code, record);
 846#        else
 847                    tap_code(action.layer_tap.code);
 848#        endif
 849                }
 850                retro_tapping_counter = 0;
 851            }
 852        }
 853    }
 854#    endif
 855#endif
 856
 857#ifdef SWAP_HANDS_ENABLE
 858#    ifndef NO_ACTION_ONESHOT
 859    if (event.pressed && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)) {
 860        use_oneshot_swaphands();
 861    }
 862#    endif
 863#endif
 864
 865#ifndef NO_ACTION_ONESHOT
 866    /* Because we switch layers after a oneshot event, we need to release the
 867     * key before we leave the layer or no key up event will be generated.
 868     */
 869    if (do_release_oneshot && !(get_oneshot_layer_state() & ONESHOT_PRESSED)) {
 870        record->event.pressed = false;
 871        layer_on(get_oneshot_layer());
 872        process_record(record);
 873        layer_off(get_oneshot_layer());
 874    }
 875#endif
 876}
 877
 878/** \brief Utilities for actions. (FIXME: Needs better description)
 879 *
 880 * FIXME: Needs documentation.
 881 */
 882__attribute__((weak)) void register_code(uint8_t code) {
 883    if (code == KC_NO) {
 884        return;
 885
 886#ifdef LOCKING_SUPPORT_ENABLE
 887    } else if (KC_LOCKING_CAPS_LOCK == code) {
 888#    ifdef LOCKING_RESYNC_ENABLE
 889        // Resync: ignore if caps lock already is on
 890        if (host_keyboard_led_state().caps_lock) return;
 891#    endif
 892        add_key(KC_CAPS_LOCK);
 893        send_keyboard_report();
 894        wait_ms(TAP_HOLD_CAPS_DELAY);
 895        del_key(KC_CAPS_LOCK);
 896        send_keyboard_report();
 897
 898    } else if (KC_LOCKING_NUM_LOCK == code) {
 899#    ifdef LOCKING_RESYNC_ENABLE
 900        if (host_keyboard_led_state().num_lock) return;
 901#    endif
 902        add_key(KC_NUM_LOCK);
 903        send_keyboard_report();
 904        wait_ms(100);
 905        del_key(KC_NUM_LOCK);
 906        send_keyboard_report();
 907
 908    } else if (KC_LOCKING_SCROLL_LOCK == code) {
 909#    ifdef LOCKING_RESYNC_ENABLE
 910        if (host_keyboard_led_state().scroll_lock) return;
 911#    endif
 912        add_key(KC_SCROLL_LOCK);
 913        send_keyboard_report();
 914        wait_ms(100);
 915        del_key(KC_SCROLL_LOCK);
 916        send_keyboard_report();
 917#endif
 918
 919    } else if (IS_BASIC_KEYCODE(code)) {
 920        // TODO: should push command_proc out of this block?
 921        if (command_proc(code)) return;
 922
 923        // Force a new key press if the key is already pressed
 924        // without this, keys with the same keycode, but different
 925        // modifiers will be reported incorrectly, see issue #1708
 926        if (is_key_pressed(code)) {
 927            del_key(code);
 928            send_keyboard_report();
 929        }
 930        add_key(code);
 931        send_keyboard_report();
 932    } else if (IS_MODIFIER_KEYCODE(code)) {
 933        add_mods(MOD_BIT(code));
 934        send_keyboard_report();
 935
 936#ifdef EXTRAKEY_ENABLE
 937    } else if (IS_SYSTEM_KEYCODE(code)) {
 938        host_system_send(KEYCODE2SYSTEM(code));
 939    } else if (IS_CONSUMER_KEYCODE(code)) {
 940        host_consumer_send(KEYCODE2CONSUMER(code));
 941#endif
 942
 943    } else if (IS_MOUSE_KEYCODE(code)) {
 944        register_mouse(code, true);
 945    }
 946}
 947
 948/** \brief Utilities for actions. (FIXME: Needs better description)
 949 *
 950 * FIXME: Needs documentation.
 951 */
 952__attribute__((weak)) void unregister_code(uint8_t code) {
 953    if (code == KC_NO) {
 954        return;
 955
 956#ifdef LOCKING_SUPPORT_ENABLE
 957    } else if (KC_LOCKING_CAPS_LOCK == code) {
 958#    ifdef LOCKING_RESYNC_ENABLE
 959        // Resync: ignore if caps lock already is off
 960        if (!host_keyboard_led_state().caps_lock) return;
 961#    endif
 962        add_key(KC_CAPS_LOCK);
 963        send_keyboard_report();
 964        del_key(KC_CAPS_LOCK);
 965        send_keyboard_report();
 966
 967    } else if (KC_LOCKING_NUM_LOCK == code) {
 968#    ifdef LOCKING_RESYNC_ENABLE
 969        if (!host_keyboard_led_state().num_lock) return;
 970#    endif
 971        add_key(KC_NUM_LOCK);
 972        send_keyboard_report();
 973        del_key(KC_NUM_LOCK);
 974        send_keyboard_report();
 975
 976    } else if (KC_LOCKING_SCROLL_LOCK == code) {
 977#    ifdef LOCKING_RESYNC_ENABLE
 978        if (!host_keyboard_led_state().scroll_lock) return;
 979#    endif
 980        add_key(KC_SCROLL_LOCK);
 981        send_keyboard_report();
 982        del_key(KC_SCROLL_LOCK);
 983        send_keyboard_report();
 984#endif
 985
 986    } else if (IS_BASIC_KEYCODE(code)) {
 987        del_key(code);
 988        send_keyboard_report();
 989    } else if (IS_MODIFIER_KEYCODE(code)) {
 990        del_mods(MOD_BIT(code));
 991        send_keyboard_report();
 992
 993#ifdef EXTRAKEY_ENABLE
 994    } else if (IS_SYSTEM_KEYCODE(code)) {
 995        host_system_send(0);
 996    } else if (IS_CONSUMER_KEYCODE(code)) {
 997        host_consumer_send(0);
 998#endif
 999
1000    } else if (IS_MOUSE_KEYCODE(code)) {
1001        register_mouse(code, false);
1002    }
1003}
1004
1005/** \brief Tap a keycode with a delay.
1006 *
1007 * \param code The basic keycode to tap.
1008 * \param delay The amount of time in milliseconds to leave the keycode registered, before unregistering it.
1009 */
1010__attribute__((weak)) void tap_code_delay(uint8_t code, uint16_t delay) {
1011    register_code(code);
1012    wait_ms(delay);
1013    unregister_code(code);
1014}
1015
1016/** \brief Tap a keycode with the default delay.
1017 *
1018 * \param code The basic keycode to tap. If `code` is `KC_CAPS_LOCK`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined.
1019 */
1020__attribute__((weak)) void tap_code(uint8_t code) {
1021    tap_code_delay(code, code == KC_CAPS_LOCK ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY);
1022}
1023
1024/** \brief Adds the given physically pressed modifiers and sends a keyboard report immediately.
1025 *
1026 * \param mods A bitfield of modifiers to register.
1027 */
1028__attribute__((weak)) void register_mods(uint8_t mods) {
1029    if (mods) {
1030        add_mods(mods);
1031        send_keyboard_report();
1032    }
1033}
1034
1035/** \brief Removes the given physically pressed modifiers and sends a keyboard report immediately.
1036 *
1037 * \param mods A bitfield of modifiers to unregister.
1038 */
1039__attribute__((weak)) void unregister_mods(uint8_t mods) {
1040    if (mods) {
1041        del_mods(mods);
1042        send_keyboard_report();
1043    }
1044}
1045
1046/** \brief Adds the given weak modifiers and sends a keyboard report immediately.
1047 *
1048 * \param mods A bitfield of modifiers to register.
1049 */
1050__attribute__((weak)) void register_weak_mods(uint8_t mods) {
1051    if (mods) {
1052        add_weak_mods(mods);
1053        send_keyboard_report();
1054    }
1055}
1056
1057/** \brief Removes the given weak modifiers and sends a keyboard report immediately.
1058 *
1059 * \param mods A bitfield of modifiers to unregister.
1060 */
1061__attribute__((weak)) void unregister_weak_mods(uint8_t mods) {
1062    if (mods) {
1063        del_weak_mods(mods);
1064        send_keyboard_report();
1065    }
1066}
1067
1068/** \brief Utilities for actions. (FIXME: Needs better description)
1069 *
1070 * FIXME: Needs documentation.
1071 */
1072void clear_keyboard(void) {
1073    clear_mods();
1074    clear_keyboard_but_mods();
1075}
1076
1077/** \brief Utilities for actions. (FIXME: Needs better description)
1078 *
1079 * FIXME: Needs documentation.
1080 */
1081void clear_keyboard_but_mods(void) {
1082    clear_keys();
1083    clear_keyboard_but_mods_and_keys();
1084}
1085
1086/** \brief Utilities for actions. (FIXME: Needs better description)
1087 *
1088 * FIXME: Needs documentation.
1089 */
1090void clear_keyboard_but_mods_and_keys(void) {
1091#ifdef EXTRAKEY_ENABLE
1092    host_system_send(0);
1093    host_consumer_send(0);
1094#endif
1095    clear_weak_mods();
1096    send_keyboard_report();
1097#ifdef MOUSEKEY_ENABLE
1098    mousekey_clear();
1099    mousekey_send();
1100#endif
1101#ifdef PROGRAMMABLE_BUTTON_ENABLE
1102    programmable_button_clear();
1103#endif
1104}
1105
1106/** \brief Utilities for actions. (FIXME: Needs better description)
1107 *
1108 * FIXME: Needs documentation.
1109 */
1110bool is_tap_record(keyrecord_t *record) {
1111    if (IS_NOEVENT(record->event)) {
1112        return false;
1113    }
1114
1115#if defined(COMBO_ENABLE) || defined(REPEAT_KEY_ENABLE)
1116    action_t action;
1117    if (record->keycode) {
1118        action = action_for_keycode(record->keycode);
1119    } else {
1120        action = layer_switch_get_action(record->event.key);
1121    }
1122#else
1123    action_t action = layer_switch_get_action(record->event.key);
1124#endif
1125    return is_tap_action(action);
1126}
1127
1128/** \brief Utilities for actions. (FIXME: Needs better description)
1129 *
1130 * FIXME: Needs documentation.
1131 */
1132bool is_tap_action(action_t action) {
1133    switch (action.kind.id) {
1134        case ACT_LMODS_TAP:
1135        case ACT_RMODS_TAP:
1136        case ACT_LAYER_TAP:
1137        case ACT_LAYER_TAP_EXT:
1138            switch (action.layer_tap.code) {
1139                case KC_NO ... KC_RIGHT_GUI:
1140                case OP_TAP_TOGGLE:
1141                case OP_ONESHOT:
1142                    return true;
1143            }
1144            return false;
1145        case ACT_SWAP_HANDS:
1146            switch (action.swap.code) {
1147                case KC_NO ... KC_RIGHT_GUI:
1148                case OP_SH_TAP_TOGGLE:
1149                    return true;
1150            }
1151            return false;
1152    }
1153    return false;
1154}
1155
1156/** \brief Debug print (FIXME: Needs better description)
1157 *
1158 * FIXME: Needs documentation.
1159 */
1160void debug_event(keyevent_t event) {
1161    ac_dprintf("%04X%c(%u)", (event.key.row << 8 | event.key.col), (event.pressed ? 'd' : 'u'), event.time);
1162}
1163/** \brief Debug print (FIXME: Needs better description)
1164 *
1165 * FIXME: Needs documentation.
1166 */
1167void debug_record(keyrecord_t record) {
1168    debug_event(record.event);
1169#ifndef NO_ACTION_TAPPING
1170    ac_dprintf(":%u%c", record.tap.count, (record.tap.interrupted ? '-' : ' '));
1171#endif
1172}
1173
1174/** \brief Debug print (FIXME: Needs better description)
1175 *
1176 * FIXME: Needs documentation.
1177 */
1178void debug_action(action_t action) {
1179    switch (action.kind.id) {
1180        case ACT_LMODS:
1181            ac_dprintf("ACT_LMODS");
1182            break;
1183        case ACT_RMODS:
1184            ac_dprintf("ACT_RMODS");
1185            break;
1186        case ACT_LMODS_TAP:
1187            ac_dprintf("ACT_LMODS_TAP");
1188            break;
1189        case ACT_RMODS_TAP:
1190            ac_dprintf("ACT_RMODS_TAP");
1191            break;
1192        case ACT_USAGE:
1193            ac_dprintf("ACT_USAGE");
1194            break;
1195        case ACT_MOUSEKEY:
1196            ac_dprintf("ACT_MOUSEKEY");
1197            break;
1198        case ACT_LAYER:
1199            ac_dprintf("ACT_LAYER");
1200            break;
1201        case ACT_LAYER_MODS:
1202            ac_dprintf("ACT_LAYER_MODS");
1203            break;
1204        case ACT_LAYER_TAP:
1205            ac_dprintf("ACT_LAYER_TAP");
1206            break;
1207        case ACT_LAYER_TAP_EXT:
1208            ac_dprintf("ACT_LAYER_TAP_EXT");
1209            break;
1210        case ACT_SWAP_HANDS:
1211            ac_dprintf("ACT_SWAP_HANDS");
1212            break;
1213        default:
1214            ac_dprintf("UNKNOWN");
1215            break;
1216    }
1217    ac_dprintf("[%X:%02X]", action.kind.param >> 8, action.kind.param & 0xff);
1218}