Skip to content

Commit 9fe6967

Browse files
committed
refactor(behaviors): Convert state dependent params.
* Allow each behavior to map a relative binding, e.g. "toggle", to an absolute one, e.g. "on", before being invoked.
1 parent 994da3e commit 9fe6967

File tree

4 files changed

+79
-5
lines changed

4 files changed

+79
-5
lines changed

app/include/drivers/behavior.h

+25
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ typedef int (*behavior_sensor_keymap_binding_callback_t)(struct zmk_behavior_bin
2727
int64_t timestamp);
2828

2929
__subsystem struct behavior_driver_api {
30+
behavior_keymap_binding_callback_t binding_convert_central_state_dependent_params;
3031
behavior_keymap_binding_callback_t binding_pressed;
3132
behavior_keymap_binding_callback_t binding_released;
3233
behavior_sensor_keymap_binding_callback_t sensor_binding_triggered;
@@ -35,6 +36,30 @@ __subsystem struct behavior_driver_api {
3536
* @endcond
3637
*/
3738

39+
/**
40+
* @brief Handle the keymap binding which needs to be converted from relative "toggle" to absolute
41+
* "turn on"
42+
* @param binding Pointer to the details so of the binding
43+
* @param event The event that triggered use of the binding
44+
*
45+
* @retval 0 If successful.
46+
* @retval Negative errno code if failure.
47+
*/
48+
__syscall int behavior_keymap_binding_convert_central_state_dependent_params(
49+
struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event);
50+
51+
static inline int z_impl_behavior_keymap_binding_convert_central_state_dependent_params(
52+
struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) {
53+
const struct device *dev = device_get_binding(binding->behavior_dev);
54+
const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->api;
55+
56+
if (api->binding_convert_central_state_dependent_params == NULL) {
57+
return 0;
58+
}
59+
60+
return api->binding_convert_central_state_dependent_params(binding, event);
61+
}
62+
3863
/**
3964
* @brief Handle the keymap binding being pressed
4065
* @param dev Pointer to the device structure for the driver instance.

app/src/behaviors/behavior_ext_power.c

+18
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,22 @@
1616
#include <logging/log.h>
1717
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
1818

19+
static int
20+
on_keymap_binding_convert_central_state_dependent_params(struct zmk_behavior_binding *binding,
21+
struct zmk_behavior_binding_event event) {
22+
const struct device *ext_power = device_get_binding("EXT_POWER");
23+
if (ext_power == NULL) {
24+
LOG_ERR("Unable to retrieve ext_power device: %d", binding->param1);
25+
return -EIO;
26+
}
27+
28+
if (binding->param1 == EXT_POWER_TOGGLE_CMD) {
29+
binding->param1 = ext_power_get(ext_power) > 0 ? EXT_POWER_OFF_CMD : EXT_POWER_ON_CMD;
30+
}
31+
32+
return 0;
33+
}
34+
1935
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
2036
struct zmk_behavior_binding_event event) {
2137
const struct device *ext_power = device_get_binding("EXT_POWER");
@@ -49,6 +65,8 @@ static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
4965
static int behavior_ext_power_init(const struct device *dev) { return 0; };
5066

5167
static const struct behavior_driver_api behavior_ext_power_driver_api = {
68+
.binding_convert_central_state_dependent_params =
69+
on_keymap_binding_convert_central_state_dependent_params,
5270
.binding_pressed = on_keymap_binding_pressed,
5371
.binding_released = on_keymap_binding_released,
5472
};

app/src/behaviors/behavior_rgb_underglow.c

+23
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,27 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
1818

1919
static int behavior_rgb_underglow_init(const struct device *dev) { return 0; }
2020

21+
static int
22+
on_keymap_binding_convert_central_state_dependent_params(struct zmk_behavior_binding *binding,
23+
struct zmk_behavior_binding_event event) {
24+
switch (binding->param1) {
25+
case RGB_TOG_CMD: {
26+
bool state;
27+
int err = zmk_rgb_underglow_get_state(&state);
28+
if (err) {
29+
LOG_ERR("Failed to get RGB underglow state (err %d)", err);
30+
return err;
31+
}
32+
33+
binding->param1 = state ? RGB_OFF_CMD : RGB_ON_CMD;
34+
LOG_DBG("RGB relative toggle convert to absolute %s", state ? "OFF" : "ON");
35+
return 0;
36+
}
37+
default:
38+
return 0;
39+
}
40+
};
41+
2142
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
2243
struct zmk_behavior_binding_event event) {
2344
switch (binding->param1) {
@@ -61,6 +82,8 @@ static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
6182
}
6283

6384
static const struct behavior_driver_api behavior_rgb_underglow_driver_api = {
85+
.binding_convert_central_state_dependent_params =
86+
on_keymap_binding_convert_central_state_dependent_params,
6487
.binding_pressed = on_keymap_binding_pressed,
6588
.binding_released = on_keymap_binding_released,
6689
};

app/src/keymap.c

+13-5
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,9 @@ const char *zmk_keymap_layer_label(uint8_t layer) {
161161
}
162162

163163
int zmk_keymap_apply_position_state(int layer, uint32_t position, bool pressed, int64_t timestamp) {
164-
struct zmk_behavior_binding *binding = &zmk_keymap[layer][position];
164+
// We want to make a copy of this, since it may be converted from
165+
// relative to absolute before being invoked
166+
struct zmk_behavior_binding binding = zmk_keymap[layer][position];
165167
const struct device *behavior;
166168
struct zmk_behavior_binding_event event = {
167169
.layer = layer,
@@ -170,19 +172,25 @@ int zmk_keymap_apply_position_state(int layer, uint32_t position, bool pressed,
170172
};
171173

172174
LOG_DBG("layer: %d position: %d, binding name: %s", layer, position,
173-
log_strdup(binding->behavior_dev));
175+
log_strdup(binding.behavior_dev));
174176

175-
behavior = device_get_binding(binding->behavior_dev);
177+
behavior = device_get_binding(binding.behavior_dev);
176178

177179
if (!behavior) {
178180
LOG_DBG("No behavior assigned to %d on layer %d", position, layer);
179181
return 1;
180182
}
181183

184+
int err = behavior_keymap_binding_convert_central_state_dependent_params(&binding, event);
185+
if (err) {
186+
LOG_ERR("Failed to convert relative to absolute behavior binding (err %d)", err);
187+
return err;
188+
}
189+
182190
if (pressed) {
183-
return behavior_keymap_binding_pressed(binding, event);
191+
return behavior_keymap_binding_pressed(&binding, event);
184192
} else {
185-
return behavior_keymap_binding_released(binding, event);
193+
return behavior_keymap_binding_released(&binding, event);
186194
}
187195
}
188196

0 commit comments

Comments
 (0)