qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

action_util.c (15633B)


      1 /*
      2 Copyright 2013 Jun Wako <wakojun@gmail.com>
      3 
      4 This program is free software: you can redistribute it and/or modify
      5 it under the terms of the GNU General Public License as published by
      6 the Free Software Foundation, either version 2 of the License, or
      7 (at your option) any later version.
      8 
      9 This program is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 GNU General Public License for more details.
     13 
     14 You should have received a copy of the GNU General Public License
     15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17 #include "host.h"
     18 #include "report.h"
     19 #include "debug.h"
     20 #include "action_util.h"
     21 #include "action_layer.h"
     22 #include "action_tapping.h"
     23 #include "timer.h"
     24 #include "keycode_config.h"
     25 #include <string.h>
     26 
     27 extern keymap_config_t keymap_config;
     28 
     29 static uint8_t real_mods = 0;
     30 static uint8_t weak_mods = 0;
     31 #ifdef KEY_OVERRIDE_ENABLE
     32 static uint8_t weak_override_mods = 0;
     33 static uint8_t suppressed_mods    = 0;
     34 #endif
     35 
     36 // TODO: pointer variable is not needed
     37 // report_keyboard_t keyboard_report = {};
     38 report_keyboard_t *keyboard_report = &(report_keyboard_t){};
     39 #ifdef NKRO_ENABLE
     40 report_nkro_t *nkro_report = &(report_nkro_t){};
     41 #endif
     42 
     43 extern inline void add_key(uint8_t key);
     44 extern inline void del_key(uint8_t key);
     45 extern inline void clear_keys(void);
     46 
     47 #ifndef NO_ACTION_ONESHOT
     48 static uint8_t oneshot_mods        = 0;
     49 static uint8_t oneshot_locked_mods = 0;
     50 /**
     51  * @brief Retrieve current state of locked oneshot modifiers.
     52  *
     53  * @return Current state of the locked oneshot modifier keys as a bitmask.
     54  */
     55 uint8_t get_oneshot_locked_mods(void) {
     56     return oneshot_locked_mods;
     57 }
     58 /**
     59  * Same as \ref get_oneshot_locked_mods but returns \ref mod_t for convenience.
     60  */
     61 mod_t get_oneshot_locked_mod_state(void) {
     62     return (mod_t)get_oneshot_locked_mods();
     63 }
     64 void add_oneshot_locked_mods(uint8_t mods) {
     65     if ((oneshot_locked_mods & mods) != mods) {
     66         oneshot_locked_mods |= mods;
     67         oneshot_locked_mods_changed_kb(oneshot_locked_mods);
     68     }
     69 }
     70 void set_oneshot_locked_mods(uint8_t mods) {
     71     if (mods != oneshot_locked_mods) {
     72         oneshot_locked_mods = mods;
     73         oneshot_locked_mods_changed_kb(oneshot_locked_mods);
     74     }
     75 }
     76 void clear_oneshot_locked_mods(void) {
     77     if (oneshot_locked_mods) {
     78         oneshot_locked_mods = 0;
     79         oneshot_locked_mods_changed_kb(oneshot_locked_mods);
     80     }
     81 }
     82 void del_oneshot_locked_mods(uint8_t mods) {
     83     if (oneshot_locked_mods & mods) {
     84         oneshot_locked_mods &= ~mods;
     85         oneshot_locked_mods_changed_kb(oneshot_locked_mods);
     86     }
     87 }
     88 #    if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
     89 static uint16_t oneshot_time = 0;
     90 bool            has_oneshot_mods_timed_out(void) {
     91     return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT;
     92 }
     93 #    else
     94 bool has_oneshot_mods_timed_out(void) {
     95     return false;
     96 }
     97 #    endif
     98 #endif
     99 
    100 /* oneshot layer */
    101 #ifndef NO_ACTION_ONESHOT
    102 /** \brief oneshot_layer_data bits
    103  * LLLL LSSS
    104  * where:
    105  *   L => are layer bits
    106  *   S => oneshot state bits
    107  */
    108 static uint8_t oneshot_layer_data = 0;
    109 
    110 inline uint8_t get_oneshot_layer(void) {
    111     return oneshot_layer_data >> 3;
    112 }
    113 inline uint8_t get_oneshot_layer_state(void) {
    114     return oneshot_layer_data & 0b111;
    115 }
    116 
    117 #    ifdef SWAP_HANDS_ENABLE
    118 enum {
    119     SHO_OFF,
    120     SHO_ACTIVE,  // Swap hands button was pressed, and we didn't send any swapped keys yet
    121     SHO_PRESSED, // Swap hands button is currently pressed
    122     SHO_USED,    // Swap hands button is still pressed, and we already sent swapped keys
    123 } swap_hands_oneshot = SHO_OFF;
    124 #    endif
    125 
    126 #    if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
    127 static uint16_t oneshot_layer_time = 0;
    128 inline bool     has_oneshot_layer_timed_out(void) {
    129     return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && !(get_oneshot_layer_state() & ONESHOT_TOGGLED);
    130 }
    131 #        ifdef SWAP_HANDS_ENABLE
    132 static uint16_t oneshot_swaphands_time = 0;
    133 inline bool     has_oneshot_swaphands_timed_out(void) {
    134     return TIMER_DIFF_16(timer_read(), oneshot_swaphands_time) >= ONESHOT_TIMEOUT && (swap_hands_oneshot == SHO_ACTIVE);
    135 }
    136 #        endif
    137 #    endif
    138 
    139 #    ifdef SWAP_HANDS_ENABLE
    140 
    141 void set_oneshot_swaphands(void) {
    142     swap_hands_oneshot = SHO_PRESSED;
    143     swap_hands         = true;
    144 #        if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
    145     oneshot_swaphands_time = timer_read();
    146     if (oneshot_layer_time != 0) {
    147         oneshot_layer_time = oneshot_swaphands_time;
    148     }
    149 #        endif
    150 }
    151 
    152 void release_oneshot_swaphands(void) {
    153     if (swap_hands_oneshot == SHO_PRESSED) {
    154         swap_hands_oneshot = SHO_ACTIVE;
    155     }
    156     if (swap_hands_oneshot == SHO_USED) {
    157         clear_oneshot_swaphands();
    158     }
    159 }
    160 
    161 void use_oneshot_swaphands(void) {
    162     if (swap_hands_oneshot == SHO_PRESSED) {
    163         swap_hands_oneshot = SHO_USED;
    164     }
    165     if (swap_hands_oneshot == SHO_ACTIVE) {
    166         clear_oneshot_swaphands();
    167     }
    168 }
    169 
    170 void clear_oneshot_swaphands(void) {
    171     swap_hands_oneshot = SHO_OFF;
    172     swap_hands         = false;
    173 #        if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
    174     oneshot_swaphands_time = 0;
    175 #        endif
    176 }
    177 
    178 #    endif
    179 
    180 /** \brief Set oneshot layer
    181  *
    182  * FIXME: needs doc
    183  */
    184 void set_oneshot_layer(uint8_t layer, uint8_t state) {
    185     if (keymap_config.oneshot_enable) {
    186         oneshot_layer_data = layer << 3 | state;
    187         layer_on(layer);
    188 #    if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
    189         oneshot_layer_time = timer_read();
    190 #    endif
    191         oneshot_layer_changed_kb(get_oneshot_layer());
    192     } else {
    193         layer_on(layer);
    194     }
    195 }
    196 /** \brief Reset oneshot layer
    197  *
    198  * FIXME: needs doc
    199  */
    200 void reset_oneshot_layer(void) {
    201     oneshot_layer_data = 0;
    202 #    if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
    203     oneshot_layer_time = 0;
    204 #    endif
    205     oneshot_layer_changed_kb(get_oneshot_layer());
    206 }
    207 /** \brief Clear oneshot layer
    208  *
    209  * FIXME: needs doc
    210  */
    211 void clear_oneshot_layer_state(oneshot_fullfillment_t state) {
    212     uint8_t start_state = oneshot_layer_data;
    213     oneshot_layer_data &= ~state;
    214     if ((!get_oneshot_layer_state() && start_state != oneshot_layer_data) && keymap_config.oneshot_enable) {
    215         layer_off(get_oneshot_layer());
    216         reset_oneshot_layer();
    217     }
    218 }
    219 /** \brief Is oneshot layer active
    220  *
    221  * FIXME: needs doc
    222  */
    223 bool is_oneshot_layer_active(void) {
    224     return get_oneshot_layer_state();
    225 }
    226 
    227 /** \brief set oneshot
    228  *
    229  * FIXME: needs doc
    230  */
    231 void oneshot_set(bool active) {
    232     if (keymap_config.oneshot_enable != active) {
    233         keymap_config.oneshot_enable = active;
    234         eeconfig_update_keymap(&keymap_config);
    235         clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
    236         dprintf("Oneshot: active: %d\n", active);
    237     }
    238 }
    239 
    240 /** \brief toggle oneshot
    241  *
    242  * FIXME: needs doc
    243  */
    244 void oneshot_toggle(void) {
    245     oneshot_set(!keymap_config.oneshot_enable);
    246 }
    247 
    248 /** \brief enable oneshot
    249  *
    250  * FIXME: needs doc
    251  */
    252 void oneshot_enable(void) {
    253     oneshot_set(true);
    254 }
    255 
    256 /** \brief disable oneshot
    257  *
    258  * FIXME: needs doc
    259  */
    260 void oneshot_disable(void) {
    261     oneshot_set(false);
    262 }
    263 
    264 bool is_oneshot_enabled(void) {
    265     return keymap_config.oneshot_enable;
    266 }
    267 
    268 #endif
    269 
    270 static uint8_t get_mods_for_report(void) {
    271     uint8_t mods = real_mods | weak_mods;
    272 
    273 #ifndef NO_ACTION_ONESHOT
    274     if (oneshot_mods) {
    275 #    if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
    276         if (has_oneshot_mods_timed_out()) {
    277             dprintf("Oneshot: timeout\n");
    278             clear_oneshot_mods();
    279         }
    280 #    endif
    281         mods |= oneshot_mods;
    282         if (has_anykey()) {
    283             clear_oneshot_mods();
    284         }
    285     }
    286 #endif
    287 
    288 #ifdef SPECULATIVE_HOLD
    289     mods |= get_speculative_mods();
    290 #endif
    291 
    292 #ifdef KEY_OVERRIDE_ENABLE
    293     // These need to be last to be able to properly control key overrides
    294     mods &= ~suppressed_mods;
    295     mods |= weak_override_mods;
    296 #endif
    297 
    298     return mods;
    299 }
    300 
    301 void send_6kro_report(void) {
    302     keyboard_report->mods = get_mods_for_report();
    303 
    304 #ifdef PROTOCOL_VUSB
    305     host_keyboard_send(keyboard_report);
    306 #else
    307     static report_keyboard_t last_report;
    308 
    309     /* Only send the report if there are changes to propagate to the host. */
    310     if (memcmp(keyboard_report, &last_report, sizeof(report_keyboard_t)) != 0) {
    311         memcpy(&last_report, keyboard_report, sizeof(report_keyboard_t));
    312         host_keyboard_send(keyboard_report);
    313     }
    314 #endif
    315 }
    316 
    317 #ifdef NKRO_ENABLE
    318 void send_nkro_report(void) {
    319     nkro_report->mods = get_mods_for_report();
    320 
    321     static report_nkro_t last_report;
    322 
    323     /* Only send the report if there are changes to propagate to the host. */
    324     if (memcmp(nkro_report, &last_report, sizeof(report_nkro_t)) != 0) {
    325         memcpy(&last_report, nkro_report, sizeof(report_nkro_t));
    326         host_nkro_send(nkro_report);
    327     }
    328 }
    329 #endif
    330 
    331 /** \brief Send keyboard report
    332  *
    333  * FIXME: needs doc
    334  */
    335 void send_keyboard_report(void) {
    336 #ifdef NKRO_ENABLE
    337     if (host_can_send_nkro() && keymap_config.nkro) {
    338         send_nkro_report();
    339         return;
    340     }
    341 #endif
    342     send_6kro_report();
    343 }
    344 
    345 /**
    346  * @brief Retrieve current state of modifiers.
    347  *
    348  * @return Current state of the modifier keys as a bitmask.
    349  */
    350 uint8_t get_mods(void) {
    351     return real_mods;
    352 }
    353 /**
    354  * Same as \ref get_mods but returns \ref mod_t for convenience.
    355  */
    356 mod_t get_mod_state(void) {
    357     return (mod_t)get_mods();
    358 }
    359 /** \brief add mods
    360  *
    361  * FIXME: needs doc
    362  */
    363 void add_mods(uint8_t mods) {
    364     real_mods |= mods;
    365 }
    366 /** \brief del mods
    367  *
    368  * FIXME: needs doc
    369  */
    370 void del_mods(uint8_t mods) {
    371     real_mods &= ~mods;
    372 }
    373 /** \brief set mods
    374  *
    375  * FIXME: needs doc
    376  */
    377 void set_mods(uint8_t mods) {
    378     real_mods = mods;
    379 }
    380 /** \brief clear mods
    381  *
    382  * FIXME: needs doc
    383  */
    384 void clear_mods(void) {
    385     real_mods = 0;
    386 }
    387 
    388 /**
    389  * @brief Retrieve current state of weak modifiers.
    390  *
    391  * @return Current state of the weak modifier keys as a bitmask.
    392  */
    393 uint8_t get_weak_mods(void) {
    394     return weak_mods;
    395 }
    396 /**
    397  * Same as \ref get_weak_mods but returns \ref mod_t for convenience.
    398  */
    399 mod_t get_weak_mod_state(void) {
    400     return (mod_t)get_weak_mods();
    401 }
    402 /** \brief add weak mods
    403  *
    404  * FIXME: needs doc
    405  */
    406 void add_weak_mods(uint8_t mods) {
    407     weak_mods |= mods;
    408 }
    409 /** \brief del weak mods
    410  *
    411  * FIXME: needs doc
    412  */
    413 void del_weak_mods(uint8_t mods) {
    414     weak_mods &= ~mods;
    415 }
    416 /** \brief set weak mods
    417  *
    418  * FIXME: needs doc
    419  */
    420 void set_weak_mods(uint8_t mods) {
    421     weak_mods = mods;
    422 }
    423 /** \brief clear weak mods
    424  *
    425  * FIXME: needs doc
    426  */
    427 void clear_weak_mods(void) {
    428     weak_mods = 0;
    429 }
    430 
    431 #ifdef KEY_OVERRIDE_ENABLE
    432 /** \brief set weak mods used by key overrides. DO not call this manually
    433  */
    434 void set_weak_override_mods(uint8_t mods) {
    435     weak_override_mods = mods;
    436 }
    437 /** \brief clear weak mods used by key overrides. DO not call this manually
    438  */
    439 void clear_weak_override_mods(void) {
    440     weak_override_mods = 0;
    441 }
    442 
    443 /** \brief set suppressed mods used by key overrides. DO not call this manually
    444  */
    445 void set_suppressed_override_mods(uint8_t mods) {
    446     suppressed_mods = mods;
    447 }
    448 /** \brief clear suppressed mods used by key overrides. DO not call this manually
    449  */
    450 void clear_suppressed_override_mods(void) {
    451     suppressed_mods = 0;
    452 }
    453 #endif
    454 
    455 #ifndef NO_ACTION_ONESHOT
    456 /**
    457  * @brief Retrieve current state of oneshot modifiers.
    458  *
    459  * @return Current state of the oneshot modifier keys as a bitmask.
    460  */
    461 uint8_t get_oneshot_mods(void) {
    462     return oneshot_mods;
    463 }
    464 
    465 /**
    466  * Same as \ref get_oneshot_mods but returns \ref mod_t for convenience.
    467  */
    468 mod_t get_oneshot_mod_state(void) {
    469     return (mod_t)get_oneshot_mods();
    470 }
    471 
    472 void add_oneshot_mods(uint8_t mods) {
    473     if ((oneshot_mods & mods) != mods) {
    474 #    if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
    475         oneshot_time = timer_read();
    476 #    endif
    477         oneshot_mods |= mods;
    478         oneshot_mods_changed_kb(mods);
    479     }
    480 }
    481 
    482 void del_oneshot_mods(uint8_t mods) {
    483     if (oneshot_mods & mods) {
    484         oneshot_mods &= ~mods;
    485 #    if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
    486         oneshot_time = oneshot_mods ? timer_read() : 0;
    487 #    endif
    488         oneshot_mods_changed_kb(oneshot_mods);
    489     }
    490 }
    491 
    492 /** \brief set oneshot mods
    493  *
    494  * FIXME: needs doc
    495  */
    496 void set_oneshot_mods(uint8_t mods) {
    497     if (keymap_config.oneshot_enable) {
    498         if (oneshot_mods != mods) {
    499 #    if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
    500             oneshot_time = timer_read();
    501 #    endif
    502             oneshot_mods = mods;
    503             oneshot_mods_changed_kb(mods);
    504         }
    505     }
    506 }
    507 
    508 /** \brief clear oneshot mods
    509  *
    510  * FIXME: needs doc
    511  */
    512 void clear_oneshot_mods(void) {
    513     if (oneshot_mods) {
    514         oneshot_mods = 0;
    515 #    if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
    516         oneshot_time = 0;
    517 #    endif
    518         oneshot_mods_changed_kb(oneshot_mods);
    519     }
    520 }
    521 #endif
    522 
    523 /** \brief Called when the one shot modifiers have been changed.
    524  *
    525  * \param mods Contains the active modifiers active after the change.
    526  */
    527 __attribute__((weak)) void oneshot_locked_mods_changed_user(uint8_t mods) {}
    528 
    529 /** \brief Called when the locked one shot modifiers have been changed.
    530  *
    531  * \param mods Contains the active modifiers active after the change.
    532  */
    533 __attribute__((weak)) void oneshot_locked_mods_changed_kb(uint8_t mods) {
    534     oneshot_locked_mods_changed_user(mods);
    535 }
    536 
    537 /** \brief Called when the one shot modifiers have been changed.
    538  *
    539  * \param mods Contains the active modifiers active after the change.
    540  */
    541 __attribute__((weak)) void oneshot_mods_changed_user(uint8_t mods) {}
    542 
    543 /** \brief Called when the one shot modifiers have been changed.
    544  *
    545  * \param mods Contains the active modifiers active after the change.
    546  */
    547 __attribute__((weak)) void oneshot_mods_changed_kb(uint8_t mods) {
    548     oneshot_mods_changed_user(mods);
    549 }
    550 
    551 /** \brief Called when the one shot layers have been changed.
    552  *
    553  * \param layer Contains the layer that is toggled on, or zero when toggled off.
    554  */
    555 __attribute__((weak)) void oneshot_layer_changed_user(uint8_t layer) {}
    556 
    557 /** \brief Called when the one shot layers have been changed.
    558  *
    559  * \param layer Contains the layer that is toggled on, or zero when toggled off.
    560  */
    561 __attribute__((weak)) void oneshot_layer_changed_kb(uint8_t layer) {
    562     oneshot_layer_changed_user(layer);
    563 }
    564 
    565 /** \brief inspect keyboard state
    566  *
    567  * FIXME: needs doc
    568  */
    569 uint8_t has_anymod(void) {
    570     return bitpop(real_mods);
    571 }
    572 
    573 #ifdef DUMMY_MOD_NEUTRALIZER_KEYCODE
    574 /** \brief Send a dummy keycode in between the register and unregister event of a modifier key, to neutralize the "flashing modifiers" phenomenon.
    575  *
    576  * \param active_mods 8-bit packed bit-array describing the currently active modifiers (in the format GASCGASC).
    577  *
    578  * Certain QMK features like  key overrides or retro tap must unregister a previously
    579  * registered modifier before sending another keycode but this can trigger undesired
    580  * keyboard shortcuts if the clean tap of a single modifier key is bound to an action
    581  * on the host OS, as is for example the case for the left GUI key on Windows, which
    582  * opens the Start Menu when tapped.
    583  */
    584 void neutralize_flashing_modifiers(uint8_t active_mods) {
    585     // In most scenarios, the flashing modifiers phenomenon is a problem
    586     // only for a subset of modifier masks.
    587     const static uint8_t mods_to_neutralize[] = MODS_TO_NEUTRALIZE;
    588     const static uint8_t n_mods               = ARRAY_SIZE(mods_to_neutralize);
    589     for (uint8_t i = 0; i < n_mods; ++i) {
    590         if (active_mods == mods_to_neutralize[i]) {
    591             tap_code(DUMMY_MOD_NEUTRALIZER_KEYCODE);
    592             break;
    593         }
    594     }
    595 }
    596 #endif