Skip to content

Commit

Permalink
Fix for 3.5
Browse files Browse the repository at this point in the history
  • Loading branch information
nickconway authored and allymparker committed May 30, 2024
1 parent 705547e commit a26e658
Showing 1 changed file with 31 additions and 34 deletions.
65 changes: 31 additions & 34 deletions app/src/behaviors/behavior_tri_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -259,43 +259,40 @@ 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), \
.ignored_layers = DT_INST_FOREACH_PROP_ELEM(n, ignored_layers, IF_BIT) 0, \
.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

0 comments on commit a26e658

Please sign in to comment.