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>
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;
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);
static inline struct zmk_keycode_state_changed
zmk_keycode_state_changed_from_encoded(uint32_t encoded, bool pressed, int64_t timestamp) {
uint16_t page = ZMK_HID_USAGE_PAGE(encoded);
uint16_t id = ZMK_HID_USAGE_ID(encoded);
uint8_t implicit_modifiers = 0x00;
uint8_t explicit_modifiers = 0x00;
struct zmk_key_param key = ZMK_KEY_PARAM_DECODE(encoded);
zmk_mod_flags_t implicit_modifiers = 0x00;
zmk_mod_flags_t explicit_modifiers = 0x00;
if (!page) {
page = HID_USAGE_KEY;
if (!key.page) {
key.page = HID_USAGE_KEY;
}
if (is_mod(page, id)) {
explicit_modifiers = SELECT_MODS(encoded);
if (is_mod(key.page, key.id)) {
explicit_modifiers = key.modifiers;
} else {
implicit_modifiers = SELECT_MODS(encoded);
implicit_modifiers = key.modifiers;
}
return (struct zmk_keycode_state_changed){.usage_page = page,
.keycode = id,
return (struct zmk_keycode_state_changed){.usage_page = key.page,
.keycode = key.id,
.implicit_modifiers = implicit_modifiers,
.explicit_modifiers = explicit_modifiers,
.state = pressed,

View file

@ -20,6 +20,24 @@ struct zmk_key_event {
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) {
return (keycode >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL &&
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);
struct caps_word_continue_item {
uint32_t id;
uint16_t page;
uint8_t implicit_modifiers;
};
struct behavior_caps_word_config {
zmk_mod_flags_t mods;
uint16_t continuations_count;
struct caps_word_continue_item continuations[];
struct zmk_key_param continuations[];
};
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,
uint8_t implicit_modifiers) {
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,
continuation->id, continuation->implicit_modifiers);
continuation->id, continuation->modifiers);
if (continuation->page == usage_page && continuation->id == usage_id &&
(continuation->implicit_modifiers &
(implicit_modifiers | zmk_hid_get_explicit_mods())) ==
continuation->implicit_modifiers) {
(continuation->modifiers & (implicit_modifiers | zmk_hid_get_explicit_mods())) ==
continuation->modifiers) {
LOG_DBG("Continuing capsword, found included usage: 0x%02X - 0x%02X", usage_page,
usage_id);
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 PARSE_CONTINUATION(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 CONTINUATION_ITEM(i, n) ZMK_KEY_PARAM_DECODE(DT_INST_PROP_BY_IDX(n, continue_list, i))
#define KP_INST(n) \
static struct behavior_caps_word_data behavior_caps_word_data_##n = {.active = false}; \