Fix for 3.5

This commit is contained in:
Nick Conway 2024-04-15 17:15:05 -04:00
parent ed0151a8c6
commit 69d70c8e07
No known key found for this signature in database
GPG key ID: AA850592E4C1D453

View file

@ -20,14 +20,15 @@
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
#define ZMK_BHV_MAX_ACTIVE_TRI_STATES 10 #define ZMK_BHV_MAX_ACTIVE_TRI_STATES 10
struct behavior_tri_state_config { struct behavior_tri_state_config {
int32_t ignored_key_positions_len; int32_t ignored_key_positions_len;
int32_t ignored_layers_len; int32_t ignored_layers_len;
struct zmk_behavior_binding start_behavior; struct zmk_behavior_binding *behaviors;
struct zmk_behavior_binding continue_behavior; size_t behavior_count;
struct zmk_behavior_binding end_behavior;
int32_t ignored_layers; int32_t ignored_layers;
int32_t timeout_ms; int32_t timeout_ms;
int tap_ms; int tap_ms;
@ -65,12 +66,13 @@ static void reset_timer(int32_t timestamp, struct active_tri_state *tri_state) {
} }
void trigger_end_behavior(struct active_tri_state *si) { void trigger_end_behavior(struct active_tri_state *si) {
zmk_behavior_queue_add(si->position, si->config->end_behavior, true, si->config->tap_ms); zmk_behavior_queue_add(si->position, si->config->behaviors[2], true, si->config->tap_ms);
zmk_behavior_queue_add(si->position, si->config->end_behavior, false, 0); zmk_behavior_queue_add(si->position, si->config->behaviors[2], false, 0);
} }
void behavior_tri_state_timer_handler(struct k_work *item) { void behavior_tri_state_timer_handler(struct k_work *item) {
struct active_tri_state *tri_state = CONTAINER_OF(item, struct active_tri_state, release_timer); struct k_work_delayable *d_work = k_work_delayable_from_work(item);
struct active_tri_state *tri_state = CONTAINER_OF(d_work, struct active_tri_state, release_timer);
if (!tri_state->is_active || tri_state->timer_cancelled || tri_state->is_pressed) { if (!tri_state->is_active || tri_state->timer_cancelled || tri_state->is_pressed) {
return; return;
} }
@ -142,23 +144,22 @@ static int on_tri_state_binding_pressed(struct zmk_behavior_binding *binding,
LOG_DBG("%d tri_state pressed", event.position); LOG_DBG("%d tri_state pressed", event.position);
tri_state->is_pressed = true; tri_state->is_pressed = true;
if (tri_state->first_press) { if (tri_state->first_press) {
behavior_keymap_binding_pressed((struct zmk_behavior_binding *)&cfg->start_behavior, event); behavior_keymap_binding_pressed(&cfg->behaviors[0], event);
behavior_keymap_binding_released((struct zmk_behavior_binding *)&cfg->start_behavior, behavior_keymap_binding_released(&cfg->behaviors[0], event);
event);
tri_state->first_press = false; tri_state->first_press = false;
} }
behavior_keymap_binding_pressed((struct zmk_behavior_binding *)&cfg->continue_behavior, event); behavior_keymap_binding_pressed(&cfg->behaviors[1], event);
return ZMK_BEHAVIOR_OPAQUE; return ZMK_BEHAVIOR_OPAQUE;
} }
static void release_tri_state(struct zmk_behavior_binding_event event, static void release_tri_state(struct zmk_behavior_binding_event event,
struct zmk_behavior_binding *continue_behavior) { struct zmk_behavior_binding *behavior) {
struct active_tri_state *tri_state = find_tri_state(event.position); struct active_tri_state *tri_state = find_tri_state(event.position);
if (tri_state == NULL) { if (tri_state == NULL) {
return; return;
} }
tri_state->is_pressed = false; tri_state->is_pressed = false;
behavior_keymap_binding_released(continue_behavior, event); behavior_keymap_binding_released(behavior, event);
reset_timer(k_uptime_get(), tri_state); reset_timer(k_uptime_get(), tri_state);
} }
@ -167,7 +168,7 @@ static int on_tri_state_binding_released(struct zmk_behavior_binding *binding,
const struct device *dev = device_get_binding(binding->behavior_dev); const struct device *dev = device_get_binding(binding->behavior_dev);
const struct behavior_tri_state_config *cfg = dev->config; const struct behavior_tri_state_config *cfg = dev->config;
LOG_DBG("%d tri_state keybind released", event.position); LOG_DBG("%d tri_state keybind released", event.position);
release_tri_state(event, (struct zmk_behavior_binding *)&cfg->continue_behavior); release_tri_state(event, &cfg->behaviors[1]);
return ZMK_BEHAVIOR_OPAQUE; return ZMK_BEHAVIOR_OPAQUE;
} }
@ -225,8 +226,7 @@ static int tri_state_position_state_changed_listener(const zmk_event_t *eh) {
struct zmk_behavior_binding_event event = {.position = tri_state->position, struct zmk_behavior_binding_event event = {.position = tri_state->position,
.timestamp = k_uptime_get()}; .timestamp = k_uptime_get()};
if (tri_state->is_pressed) { if (tri_state->is_pressed) {
behavior_keymap_binding_released( behavior_keymap_binding_released(&tri_state->config->behaviors[1], event);
(struct zmk_behavior_binding *)&tri_state->config->continue_behavior, event);
} }
trigger_end_behavior(tri_state); trigger_end_behavior(tri_state);
return ZMK_EV_EVENT_BUBBLE; return ZMK_EV_EVENT_BUBBLE;
@ -259,31 +259,27 @@ static int tri_state_layer_state_changed_listener(const zmk_event_t *eh) {
struct zmk_behavior_binding_event event = {.position = tri_state->position, struct zmk_behavior_binding_event event = {.position = tri_state->position,
.timestamp = k_uptime_get()}; .timestamp = k_uptime_get()};
if (tri_state->is_pressed) { if (tri_state->is_pressed) {
behavior_keymap_binding_released( behavior_keymap_binding_released(&tri_state->config->behaviors[1], event);
(struct zmk_behavior_binding *)&tri_state->config->continue_behavior, event);
} }
behavior_keymap_binding_pressed( behavior_keymap_binding_pressed(&tri_state->config->behaviors[2], event);
(struct zmk_behavior_binding *)&tri_state->config->end_behavior, event); behavior_keymap_binding_released(&tri_state->config->behaviors[2], event);
behavior_keymap_binding_released(
(struct zmk_behavior_binding *)&tri_state->config->end_behavior, event);
return ZMK_EV_EVENT_BUBBLE; return ZMK_EV_EVENT_BUBBLE;
} }
} }
return ZMK_EV_EVENT_BUBBLE; return ZMK_EV_EVENT_BUBBLE;
} }
#define _TRANSFORM_ENTRY(idx, node) \ #define _TRANSFORM_ENTRY(idx, node) ZMK_KEYMAP_EXTRACT_BINDING(idx, node)
{ \
.behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(node, bindings, idx)), \ #define TRANSFORMED_BINDINGS(node) \
.param1 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param1), (0), \ { LISTIFY(DT_INST_PROP_LEN(node, bindings), _TRANSFORM_ENTRY, (, ), DT_DRV_INST(node)) }
(DT_INST_PHA_BY_IDX(node, bindings, idx, param1))), \
.param2 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param2), (0), \
(DT_INST_PHA_BY_IDX(node, bindings, idx, param2))), \
}
#define IF_BIT(n, prop, i) BIT(DT_PROP_BY_IDX(n, prop, i)) | #define IF_BIT(n, prop, i) BIT(DT_PROP_BY_IDX(n, prop, i)) |
#define TRI_STATE_INST(n) \ #define TRI_STATE_INST(n) \
static struct zmk_behavior_binding \
behavior_tri_state_config_##n##_bindings[DT_INST_PROP_LEN(n, bindings)] = \
TRANSFORMED_BINDINGS(n); \
static struct behavior_tri_state_config behavior_tri_state_config_##n = { \ static struct behavior_tri_state_config behavior_tri_state_config_##n = { \
.ignored_key_positions = DT_INST_PROP(n, ignored_key_positions), \ .ignored_key_positions = DT_INST_PROP(n, ignored_key_positions), \
.ignored_key_positions_len = DT_INST_PROP_LEN(n, ignored_key_positions), \ .ignored_key_positions_len = DT_INST_PROP_LEN(n, ignored_key_positions), \
@ -291,11 +287,12 @@ static int tri_state_layer_state_changed_listener(const zmk_event_t *eh) {
.ignored_layers_len = DT_INST_PROP_LEN(n, ignored_layers), \ .ignored_layers_len = DT_INST_PROP_LEN(n, ignored_layers), \
.timeout_ms = DT_INST_PROP(n, timeout_ms), \ .timeout_ms = DT_INST_PROP(n, timeout_ms), \
.tap_ms = DT_INST_PROP(n, tap_ms), \ .tap_ms = DT_INST_PROP(n, tap_ms), \
.start_behavior = _TRANSFORM_ENTRY(0, n), \ .behaviors = behavior_tri_state_config_##n##_bindings, \
.continue_behavior = _TRANSFORM_ENTRY(1, n), \ .behavior_count = DT_INST_PROP_LEN(n, bindings)}; \
.end_behavior = _TRANSFORM_ENTRY(2, n)}; \ BEHAVIOR_DT_INST_DEFINE(n, behavior_tri_state_init, NULL, NULL, &behavior_tri_state_config_##n,\
DEVICE_DT_INST_DEFINE(n, behavior_tri_state_init, NULL, NULL, &behavior_tri_state_config_##n, \ POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
&behavior_tri_state_driver_api); &behavior_tri_state_driver_api);
DT_INST_FOREACH_STATUS_OKAY(TRI_STATE_INST) DT_INST_FOREACH_STATUS_OKAY(TRI_STATE_INST)
#endif