qmk_firmware

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

process_tap_dance.h (5104B)


      1 /* Copyright 2016 Jack Humbert
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 2 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15  */
     16 
     17 #pragma once
     18 
     19 #include <stdint.h>
     20 #include <stdbool.h>
     21 #include "action.h"
     22 #include "quantum_keycodes.h"
     23 
     24 typedef struct {
     25     uint16_t interrupting_keycode;
     26     uint8_t  count;
     27     uint8_t  weak_mods;
     28 #ifndef NO_ACTION_ONESHOT
     29     uint8_t oneshot_mods;
     30 #endif
     31     bool    pressed : 1;
     32     bool    finished : 1;
     33     bool    interrupted : 1;
     34     bool    in_use : 1;
     35     uint8_t index;
     36 } tap_dance_state_t;
     37 
     38 typedef void (*tap_dance_user_fn_t)(tap_dance_state_t *state, void *user_data);
     39 
     40 typedef struct tap_dance_action_t {
     41     struct {
     42         tap_dance_user_fn_t on_each_tap;
     43         tap_dance_user_fn_t on_dance_finished;
     44         tap_dance_user_fn_t on_reset;
     45         tap_dance_user_fn_t on_each_release;
     46     } fn;
     47     void *user_data;
     48 } tap_dance_action_t;
     49 
     50 typedef struct {
     51     uint16_t kc1;
     52     uint16_t kc2;
     53 } tap_dance_pair_t;
     54 
     55 typedef struct {
     56     uint16_t kc;
     57     uint8_t  layer;
     58     void (*layer_function)(uint8_t);
     59 } tap_dance_dual_role_t;
     60 
     61 #define ACTION_TAP_DANCE_DOUBLE(kc1, kc2)                                                               \
     62     {                                                                                                   \
     63         .fn        = {tap_dance_pair_on_each_tap, tap_dance_pair_finished, tap_dance_pair_reset, NULL}, \
     64         .user_data = (void *)&((tap_dance_pair_t){kc1, kc2}),                                           \
     65     }
     66 
     67 #define ACTION_TAP_DANCE_LAYER_MOVE(kc, layer)                                                                         \
     68     {                                                                                                                  \
     69         .fn        = {tap_dance_dual_role_on_each_tap, tap_dance_dual_role_finished, tap_dance_dual_role_reset, NULL}, \
     70         .user_data = (void *)&((tap_dance_dual_role_t){kc, layer, layer_move}),                                        \
     71     }
     72 
     73 #define ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer)                                            \
     74     {                                                                                       \
     75         .fn        = {NULL, tap_dance_dual_role_finished, tap_dance_dual_role_reset, NULL}, \
     76         .user_data = (void *)&((tap_dance_dual_role_t){kc, layer, layer_invert}),           \
     77     }
     78 
     79 #define ACTION_TAP_DANCE_FN(user_fn)              \
     80     {                                             \
     81         .fn        = {NULL, user_fn, NULL, NULL}, \
     82         .user_data = NULL,                        \
     83     }
     84 
     85 #define ACTION_TAP_DANCE_FN_ADVANCED(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset) \
     86     {                                                                                                        \
     87         .fn        = {user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset, NULL},         \
     88         .user_data = NULL,                                                                                   \
     89     }
     90 
     91 #define ACTION_TAP_DANCE_FN_ADVANCED_WITH_RELEASE(user_fn_on_each_tap, user_fn_on_each_release, user_fn_on_dance_finished, user_fn_on_dance_reset) \
     92     {                                                                                                                                              \
     93         .fn        = {user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset, user_fn_on_each_release},                            \
     94         .user_data = NULL,                                                                                                                         \
     95     }
     96 
     97 #define TD_INDEX(code) QK_TAP_DANCE_GET_INDEX(code)
     98 #define TAP_DANCE_KEYCODE(state) TD(((tap_dance_action_t *)state) - tap_dance_actions)
     99 
    100 void reset_tap_dance(tap_dance_state_t *state);
    101 
    102 tap_dance_state_t *tap_dance_get_state(uint8_t tap_dance_idx);
    103 
    104 /* To be used internally */
    105 
    106 bool preprocess_tap_dance(uint16_t keycode, keyrecord_t *record);
    107 bool process_tap_dance(uint16_t keycode, keyrecord_t *record);
    108 void tap_dance_task(void);
    109 
    110 void tap_dance_pair_on_each_tap(tap_dance_state_t *state, void *user_data);
    111 void tap_dance_pair_finished(tap_dance_state_t *state, void *user_data);
    112 void tap_dance_pair_reset(tap_dance_state_t *state, void *user_data);
    113 
    114 void tap_dance_dual_role_on_each_tap(tap_dance_state_t *state, void *user_data);
    115 void tap_dance_dual_role_finished(tap_dance_state_t *state, void *user_data);
    116 void tap_dance_dual_role_reset(tap_dance_state_t *state, void *user_data);