From a26e65826dcd2614dd521c0ed2d003298992f21e Mon Sep 17 00:00:00 2001 From: Nick Conway Date: Mon, 15 Apr 2024 17:15:05 -0400 Subject: [PATCH] Fix for 3.5 --- app/src/behaviors/behavior_tri_state.c | 65 ++++++++++++-------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/app/src/behaviors/behavior_tri_state.c b/app/src/behaviors/behavior_tri_state.c index 463694e48e4e..af517dfd0096 100644 --- a/app/src/behaviors/behavior_tri_state.c +++ b/app/src/behaviors/behavior_tri_state.c @@ -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