refactor: Deduplicate key code decoding

Unified devicetree key code parameter decoding between key press and
caps word behaviors.

Reordered zmk_keycode_state_changed fields for better packing.
This commit is contained in:
Joel Spadin 2024-01-28 18:58:11 -06:00
parent 1bcd2f8122
commit 04763400a7
3 changed files with 39 additions and 35 deletions

View file

@ -11,35 +11,34 @@
#include <zmk/keys.h> #include <zmk/keys.h>
struct zmk_keycode_state_changed { struct zmk_keycode_state_changed {
uint16_t usage_page;
uint32_t keycode;
uint8_t implicit_modifiers;
uint8_t explicit_modifiers;
bool state;
int64_t timestamp; int64_t timestamp;
zmk_key_t keycode;
uint16_t usage_page;
zmk_mod_flags_t implicit_modifiers;
zmk_mod_flags_t explicit_modifiers;
bool state;
}; };
ZMK_EVENT_DECLARE(zmk_keycode_state_changed); ZMK_EVENT_DECLARE(zmk_keycode_state_changed);
static inline struct zmk_keycode_state_changed static inline struct zmk_keycode_state_changed
zmk_keycode_state_changed_from_encoded(uint32_t encoded, bool pressed, int64_t timestamp) { zmk_keycode_state_changed_from_encoded(uint32_t encoded, bool pressed, int64_t timestamp) {
uint16_t page = ZMK_HID_USAGE_PAGE(encoded); struct zmk_key_param key = ZMK_KEY_PARAM_DECODE(encoded);
uint16_t id = ZMK_HID_USAGE_ID(encoded); zmk_mod_flags_t implicit_modifiers = 0x00;
uint8_t implicit_modifiers = 0x00; zmk_mod_flags_t explicit_modifiers = 0x00;
uint8_t explicit_modifiers = 0x00;
if (!page) { if (!key.page) {
page = HID_USAGE_KEY; key.page = HID_USAGE_KEY;
} }
if (is_mod(page, id)) { if (is_mod(key.page, key.id)) {
explicit_modifiers = SELECT_MODS(encoded); explicit_modifiers = key.modifiers;
} else { } else {
implicit_modifiers = SELECT_MODS(encoded); implicit_modifiers = key.modifiers;
} }
return (struct zmk_keycode_state_changed){.usage_page = page, return (struct zmk_keycode_state_changed){.usage_page = key.page,
.keycode = id, .keycode = key.id,
.implicit_modifiers = implicit_modifiers, .implicit_modifiers = implicit_modifiers,
.explicit_modifiers = explicit_modifiers, .explicit_modifiers = explicit_modifiers,
.state = pressed, .state = pressed,

View file

@ -20,6 +20,24 @@ struct zmk_key_event {
bool pressed; bool pressed;
}; };
/**
* Key data from a devicetree key code parameter.
*/
struct zmk_key_param {
zmk_mod_flags_t modifiers;
uint8_t page;
uint16_t id;
};
/**
* Decode a uint32_t devicetree key code parameter to a struct zmk_key_param.
*/
#define ZMK_KEY_PARAM_DECODE(param) \
(struct zmk_key_param) { \
.modifiers = SELECT_MODS(param), .page = ZMK_HID_USAGE_PAGE(param), \
.id = ZMK_HID_USAGE_ID(param), \
}
static inline bool is_mod(uint8_t usage_page, uint32_t keycode) { static inline bool is_mod(uint8_t usage_page, uint32_t keycode) {
return (keycode >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL && return (keycode >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL &&
keycode <= HID_USAGE_KEY_KEYBOARD_RIGHT_GUI && usage_page == HID_USAGE_KEY); keycode <= HID_USAGE_KEY_KEYBOARD_RIGHT_GUI && usage_page == HID_USAGE_KEY);

View file

@ -22,16 +22,10 @@
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
struct caps_word_continue_item {
uint32_t id;
uint16_t page;
uint8_t implicit_modifiers;
};
struct behavior_caps_word_config { struct behavior_caps_word_config {
zmk_mod_flags_t mods; zmk_mod_flags_t mods;
uint16_t continuations_count; uint16_t continuations_count;
struct caps_word_continue_item continuations[]; struct zmk_key_param continuations[];
}; };
struct behavior_caps_word_data { struct behavior_caps_word_data {
@ -88,14 +82,13 @@ static bool caps_word_is_caps_includelist(const struct behavior_caps_word_config
uint16_t usage_page, uint8_t usage_id, uint16_t usage_page, uint8_t usage_id,
uint8_t implicit_modifiers) { uint8_t implicit_modifiers) {
for (int i = 0; i < config->continuations_count; i++) { for (int i = 0; i < config->continuations_count; i++) {
const struct caps_word_continue_item *continuation = &config->continuations[i]; const struct zmk_key_param *continuation = &config->continuations[i];
LOG_DBG("Comparing with 0x%02X - 0x%02X (with implicit mods: 0x%02X)", continuation->page, LOG_DBG("Comparing with 0x%02X - 0x%02X (with implicit mods: 0x%02X)", continuation->page,
continuation->id, continuation->implicit_modifiers); continuation->id, continuation->modifiers);
if (continuation->page == usage_page && continuation->id == usage_id && if (continuation->page == usage_page && continuation->id == usage_id &&
(continuation->implicit_modifiers & (continuation->modifiers & (implicit_modifiers | zmk_hid_get_explicit_mods())) ==
(implicit_modifiers | zmk_hid_get_explicit_mods())) == continuation->modifiers) {
continuation->implicit_modifiers) {
LOG_DBG("Continuing capsword, found included usage: 0x%02X - 0x%02X", usage_page, LOG_DBG("Continuing capsword, found included usage: 0x%02X - 0x%02X", usage_page,
usage_id); usage_id);
return true; return true;
@ -173,13 +166,7 @@ static int behavior_caps_word_init(const struct device *dev) { return 0; }
#define CAPS_WORD_LABEL(i, _n) DT_INST_LABEL(i) #define CAPS_WORD_LABEL(i, _n) DT_INST_LABEL(i)
#define PARSE_CONTINUATION(i) \ #define CONTINUATION_ITEM(i, n) ZMK_KEY_PARAM_DECODE(DT_INST_PROP_BY_IDX(n, continue_list, i))
{ \
.page = ZMK_HID_USAGE_PAGE(i), .id = ZMK_HID_USAGE_ID(i), \
.implicit_modifiers = SELECT_MODS(i) \
}
#define CONTINUATION_ITEM(i, n) PARSE_CONTINUATION(DT_INST_PROP_BY_IDX(n, continue_list, i))
#define KP_INST(n) \ #define KP_INST(n) \
static struct behavior_caps_word_data behavior_caps_word_data_##n = {.active = false}; \ static struct behavior_caps_word_data behavior_caps_word_data_##n = {.active = false}; \