diff options
| author | Stefan Kerkmann <karlk90@pm.me> | 2023-04-03 10:33:45 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-03 18:33:45 +1000 |
| commit | fcf8b804ed95a98561bd4c1d6c85604be0f7cc7b (patch) | |
| tree | 6b6917d99ced027d614e7b461e1cd1939833a9cd /quantum/keyboard.h | |
| parent | 2d9140af53e4e5bbc5cd50a2b6f3eda20ed8f71e (diff) | |
[Core] Refactor `keyevent_t` for 1ms timing resolution (#15847)
Diffstat (limited to 'quantum/keyboard.h')
| -rw-r--r-- | quantum/keyboard.h | 59 |
1 files changed, 29 insertions, 30 deletions
diff --git a/quantum/keyboard.h b/quantum/keyboard.h index f82f2fa58a..bf1890d10b 100644 --- a/quantum/keyboard.h +++ b/quantum/keyboard.h | |||
| @@ -30,65 +30,64 @@ typedef struct { | |||
| 30 | uint8_t row; | 30 | uint8_t row; |
| 31 | } keypos_t; | 31 | } keypos_t; |
| 32 | 32 | ||
| 33 | typedef enum keyevent_type_t { TICK_EVENT = 0, KEY_EVENT = 1, ENCODER_CW_EVENT = 2, ENCODER_CCW_EVENT = 3, COMBO_EVENT = 4 } keyevent_type_t; | ||
| 34 | |||
| 33 | /* key event */ | 35 | /* key event */ |
| 34 | typedef struct { | 36 | typedef struct { |
| 35 | keypos_t key; | 37 | keypos_t key; |
| 36 | bool pressed; | 38 | uint16_t time; |
| 37 | uint16_t time; | 39 | keyevent_type_t type; |
| 40 | bool pressed; | ||
| 38 | } keyevent_t; | 41 | } keyevent_t; |
| 39 | 42 | ||
| 40 | /* equivalent test of keypos_t */ | 43 | /* equivalent test of keypos_t */ |
| 41 | #define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col) | 44 | #define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col) |
| 42 | 45 | ||
| 43 | /* special keypos_t entries */ | 46 | /* special keypos_t entries */ |
| 44 | #define KEYLOC_TICK 255 | ||
| 45 | #define KEYLOC_COMBO 254 | ||
| 46 | #define KEYLOC_ENCODER_CW 253 | 47 | #define KEYLOC_ENCODER_CW 253 |
| 47 | #define KEYLOC_ENCODER_CCW 252 | 48 | #define KEYLOC_ENCODER_CCW 252 |
| 48 | 49 | ||
| 49 | /* Rules for No Event: | 50 | static inline bool IS_NOEVENT(const keyevent_t event) { |
| 50 | * 1) (time == 0) to handle (keyevent_t){} as empty event | 51 | return event.type == TICK_EVENT; |
| 51 | * 2) Matrix(255, 255) to make TICK event available | ||
| 52 | */ | ||
| 53 | static inline bool IS_NOEVENT(keyevent_t event) { | ||
| 54 | return event.time == 0 || (event.key.row == KEYLOC_TICK && event.key.col == KEYLOC_TICK); | ||
| 55 | } | ||
| 56 | static inline bool IS_EVENT(keyevent_t event) { | ||
| 57 | return !IS_NOEVENT(event); | ||
| 58 | } | ||
| 59 | static inline bool IS_KEYEVENT(keyevent_t event) { | ||
| 60 | return event.key.row < MATRIX_ROWS && event.key.col < MATRIX_COLS; | ||
| 61 | } | 52 | } |
| 62 | static inline bool IS_COMBOEVENT(keyevent_t event) { | 53 | static inline bool IS_EVENT(const keyevent_t event) { |
| 63 | return event.key.row == KEYLOC_COMBO; | 54 | return event.type != TICK_EVENT; |
| 64 | } | 55 | } |
| 65 | static inline bool IS_ENCODEREVENT(keyevent_t event) { | 56 | static inline bool IS_KEYEVENT(const keyevent_t event) { |
| 66 | return event.key.row == KEYLOC_ENCODER_CW || event.key.row == KEYLOC_ENCODER_CCW; | 57 | return event.type == KEY_EVENT; |
| 67 | } | 58 | } |
| 68 | static inline bool IS_PRESSED(keyevent_t event) { | 59 | static inline bool IS_COMBOEVENT(const keyevent_t event) { |
| 69 | return IS_EVENT(event) && event.pressed; | 60 | return event.type == COMBO_EVENT; |
| 70 | } | 61 | } |
| 71 | static inline bool IS_RELEASED(keyevent_t event) { | 62 | static inline bool IS_ENCODEREVENT(const keyevent_t event) { |
| 72 | return IS_EVENT(event) && !event.pressed; | 63 | return event.type == ENCODER_CW_EVENT || event.type == ENCODER_CCW_EVENT; |
| 73 | } | 64 | } |
| 74 | 65 | ||
| 75 | /* Common keyevent object factory */ | 66 | /* Common keypos_t object factory */ |
| 76 | #define MAKE_KEYPOS(row_num, col_num) ((keypos_t){.row = (row_num), .col = (col_num)}) | 67 | #define MAKE_KEYPOS(row_num, col_num) ((keypos_t){.row = (row_num), .col = (col_num)}) |
| 77 | 68 | ||
| 69 | /* Common keyevent_t object factory */ | ||
| 70 | #define MAKE_EVENT(row_num, col_num, press, event_type) ((keyevent_t){.key = MAKE_KEYPOS((row_num), (col_num)), .pressed = (press), .time = timer_read(), .type = (event_type)}) | ||
| 71 | |||
| 78 | /** | 72 | /** |
| 79 | * @brief Constructs a key event for a pressed or released key. | 73 | * @brief Constructs a key event for a pressed or released key. |
| 80 | */ | 74 | */ |
| 81 | #define MAKE_KEYEVENT(row_num, col_num, press) ((keyevent_t){.key = MAKE_KEYPOS((row_num), (col_num)), .pressed = (press), .time = (timer_read() | 1)}) | 75 | #define MAKE_KEYEVENT(row_num, col_num, press) MAKE_EVENT((row_num), (col_num), (press), KEY_EVENT) |
| 76 | |||
| 77 | /** | ||
| 78 | * @brief Constructs a combo event. | ||
| 79 | */ | ||
| 80 | #define MAKE_COMBOEVENT(press) MAKE_EVENT(0, 0, (press), COMBO_EVENT) | ||
| 82 | 81 | ||
| 83 | /** | 82 | /** |
| 84 | * @brief Constructs a internal tick event that is used to drive the internal QMK state machine. | 83 | * @brief Constructs a internal tick event that is used to drive the internal QMK state machine. |
| 85 | */ | 84 | */ |
| 86 | #define TICK_EVENT MAKE_KEYEVENT(KEYLOC_TICK, KEYLOC_TICK, false) | 85 | #define MAKE_TICK_EVENT MAKE_EVENT(0, 0, false, TICK_EVENT) |
| 87 | 86 | ||
| 88 | #ifdef ENCODER_MAP_ENABLE | 87 | #ifdef ENCODER_MAP_ENABLE |
| 89 | /* Encoder events */ | 88 | /* Encoder events */ |
| 90 | # define ENCODER_CW_EVENT(enc_id, press) MAKE_KEYEVENT(KEYLOC_ENCODER_CW, (enc_id), (press)) | 89 | # define MAKE_ENCODER_CW_EVENT(enc_id, press) MAKE_EVENT(KEYLOC_ENCODER_CW, (enc_id), (press), ENCODER_CW_EVENT) |
| 91 | # define ENCODER_CCW_EVENT(enc_id, press) MAKE_KEYEVENT(KEYLOC_ENCODER_CCW, (enc_id), (press)) | 90 | # define MAKE_ENCODER_CCW_EVENT(enc_id, press) MAKE_EVENT(KEYLOC_ENCODER_CCW, (enc_id), (press), ENCODER_CCW_EVENT) |
| 92 | #endif // ENCODER_MAP_ENABLE | 91 | #endif // ENCODER_MAP_ENABLE |
| 93 | 92 | ||
| 94 | /* it runs once at early stage of startup before keyboard_init. */ | 93 | /* it runs once at early stage of startup before keyboard_init. */ |
