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);
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
#define ZMK_BHV_MAX_ACTIVE_TRI_STATES 10
struct behavior_tri_state_config {
int32_t ignored_key_positions_len;
int32_t ignored_layers_len;
struct zmk_behavior_binding start_behavior;
struct zmk_behavior_binding continue_behavior;
struct zmk_behavior_binding end_behavior;
struct zmk_behavior_binding *behaviors;
size_t behavior_count;
int32_t ignored_layers;
int32_t timeout_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) {
zmk_behavior_queue_add(si->position, si->config->end_behavior, 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], true, si->config->tap_ms);
zmk_behavior_queue_add(si->position, si->config->behaviors[2], false, 0);
}
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) {
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);
tri_state->is_pressed = true;
if (tri_state->first_press) {
behavior_keymap_binding_pressed((struct zmk_behavior_binding *)&cfg->start_behavior, event);
behavior_keymap_binding_released((struct zmk_behavior_binding *)&cfg->start_behavior,
event);
behavior_keymap_binding_pressed(&cfg->behaviors[0], event);
behavior_keymap_binding_released(&cfg->behaviors[0], event);
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;
}
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);
if (tri_state == NULL) {
return;
}
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);
}
@ -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 behavior_tri_state_config *cfg = dev->config;
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;
}
@ -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,
.timestamp = k_uptime_get()};
if (tri_state->is_pressed) {
behavior_keymap_binding_released(
(struct zmk_behavior_binding *)&tri_state->config->continue_behavior, event);
behavior_keymap_binding_released(&tri_state->config->behaviors[1], event);
}
trigger_end_behavior(tri_state);
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,
.timestamp = k_uptime_get()};
if (tri_state->is_pressed) {
behavior_keymap_binding_released(
(struct zmk_behavior_binding *)&tri_state->config->continue_behavior, event);
behavior_keymap_binding_released(&tri_state->config->behaviors[1], event);
}
behavior_keymap_binding_pressed(
(struct zmk_behavior_binding *)&tri_state->config->end_behavior, event);
behavior_keymap_binding_released(
(struct zmk_behavior_binding *)&tri_state->config->end_behavior, event);
behavior_keymap_binding_pressed(&tri_state->config->behaviors[2], event);
behavior_keymap_binding_released(&tri_state->config->behaviors[2], event);
return ZMK_EV_EVENT_BUBBLE;
}
}
return ZMK_EV_EVENT_BUBBLE;
}
#define _TRANSFORM_ENTRY(idx, node) \
{ \
.behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(node, bindings, idx)), \
.param1 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param1), (0), \
(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 _TRANSFORM_ENTRY(idx, node) ZMK_KEYMAP_EXTRACT_BINDING(idx, node)
#define TRANSFORMED_BINDINGS(node) \
{ LISTIFY(DT_INST_PROP_LEN(node, bindings), _TRANSFORM_ENTRY, (, ), DT_DRV_INST(node)) }
#define IF_BIT(n, prop, i) BIT(DT_PROP_BY_IDX(n, prop, i)) |
#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 = { \
.ignored_key_positions = DT_INST_PROP(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), \
.timeout_ms = DT_INST_PROP(n, timeout_ms), \
.tap_ms = DT_INST_PROP(n, tap_ms), \
.start_behavior = _TRANSFORM_ENTRY(0, n), \
.continue_behavior = _TRANSFORM_ENTRY(1, n), \
.end_behavior = _TRANSFORM_ENTRY(2, n)}; \
DEVICE_DT_INST_DEFINE(n, behavior_tri_state_init, NULL, NULL, &behavior_tri_state_config_##n, \
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
.behaviors = behavior_tri_state_config_##n##_bindings, \
.behavior_count = DT_INST_PROP_LEN(n, bindings)}; \
BEHAVIOR_DT_INST_DEFINE(n, behavior_tri_state_init, NULL, NULL, &behavior_tri_state_config_##n,\
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
&behavior_tri_state_driver_api);
DT_INST_FOREACH_STATUS_OKAY(TRI_STATE_INST)
#endif