summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/include/drivers/behavior.h25
-rw-r--r--app/src/behaviors/behavior_ext_power.c18
-rw-r--r--app/src/behaviors/behavior_rgb_underglow.c23
-rw-r--r--app/src/keymap.c18
4 files changed, 79 insertions, 5 deletions
diff --git a/app/include/drivers/behavior.h b/app/include/drivers/behavior.h
index bc135fd..2bdffea 100644
--- a/app/include/drivers/behavior.h
+++ b/app/include/drivers/behavior.h
@@ -27,6 +27,7 @@ typedef int (*behavior_sensor_keymap_binding_callback_t)(struct zmk_behavior_bin
int64_t timestamp);
__subsystem struct behavior_driver_api {
+ behavior_keymap_binding_callback_t binding_convert_central_state_dependent_params;
behavior_keymap_binding_callback_t binding_pressed;
behavior_keymap_binding_callback_t binding_released;
behavior_sensor_keymap_binding_callback_t sensor_binding_triggered;
@@ -36,6 +37,30 @@ __subsystem struct behavior_driver_api {
*/
/**
+ * @brief Handle the keymap binding which needs to be converted from relative "toggle" to absolute
+ * "turn on"
+ * @param binding Pointer to the details so of the binding
+ * @param event The event that triggered use of the binding
+ *
+ * @retval 0 If successful.
+ * @retval Negative errno code if failure.
+ */
+__syscall int behavior_keymap_binding_convert_central_state_dependent_params(
+ struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event);
+
+static inline int z_impl_behavior_keymap_binding_convert_central_state_dependent_params(
+ struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) {
+ const struct device *dev = device_get_binding(binding->behavior_dev);
+ const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->api;
+
+ if (api->binding_convert_central_state_dependent_params == NULL) {
+ return 0;
+ }
+
+ return api->binding_convert_central_state_dependent_params(binding, event);
+}
+
+/**
* @brief Handle the keymap binding being pressed
* @param dev Pointer to the device structure for the driver instance.
* @param param1 User parameter specified at time of behavior binding.
diff --git a/app/src/behaviors/behavior_ext_power.c b/app/src/behaviors/behavior_ext_power.c
index 659cde5..3ce1e74 100644
--- a/app/src/behaviors/behavior_ext_power.c
+++ b/app/src/behaviors/behavior_ext_power.c
@@ -18,6 +18,22 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
+static int
+on_keymap_binding_convert_central_state_dependent_params(struct zmk_behavior_binding *binding,
+ struct zmk_behavior_binding_event event) {
+ const struct device *ext_power = device_get_binding("EXT_POWER");
+ if (ext_power == NULL) {
+ LOG_ERR("Unable to retrieve ext_power device: %d", binding->param1);
+ return -EIO;
+ }
+
+ if (binding->param1 == EXT_POWER_TOGGLE_CMD) {
+ binding->param1 = ext_power_get(ext_power) > 0 ? EXT_POWER_OFF_CMD : EXT_POWER_ON_CMD;
+ }
+
+ return 0;
+}
+
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) {
const struct device *ext_power = device_get_binding("EXT_POWER");
@@ -51,6 +67,8 @@ static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
static int behavior_ext_power_init(const struct device *dev) { return 0; };
static const struct behavior_driver_api behavior_ext_power_driver_api = {
+ .binding_convert_central_state_dependent_params =
+ on_keymap_binding_convert_central_state_dependent_params,
.binding_pressed = on_keymap_binding_pressed,
.binding_released = on_keymap_binding_released,
};
diff --git a/app/src/behaviors/behavior_rgb_underglow.c b/app/src/behaviors/behavior_rgb_underglow.c
index f9eaa13..fe33e04 100644
--- a/app/src/behaviors/behavior_rgb_underglow.c
+++ b/app/src/behaviors/behavior_rgb_underglow.c
@@ -20,6 +20,27 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
static int behavior_rgb_underglow_init(const struct device *dev) { return 0; }
+static int
+on_keymap_binding_convert_central_state_dependent_params(struct zmk_behavior_binding *binding,
+ struct zmk_behavior_binding_event event) {
+ switch (binding->param1) {
+ case RGB_TOG_CMD: {
+ bool state;
+ int err = zmk_rgb_underglow_get_state(&state);
+ if (err) {
+ LOG_ERR("Failed to get RGB underglow state (err %d)", err);
+ return err;
+ }
+
+ binding->param1 = state ? RGB_OFF_CMD : RGB_ON_CMD;
+ LOG_DBG("RGB relative toggle convert to absolute %s", state ? "OFF" : "ON");
+ return 0;
+ }
+ default:
+ return 0;
+ }
+};
+
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) {
switch (binding->param1) {
@@ -63,6 +84,8 @@ static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
}
static const struct behavior_driver_api behavior_rgb_underglow_driver_api = {
+ .binding_convert_central_state_dependent_params =
+ on_keymap_binding_convert_central_state_dependent_params,
.binding_pressed = on_keymap_binding_pressed,
.binding_released = on_keymap_binding_released,
};
diff --git a/app/src/keymap.c b/app/src/keymap.c
index 75ec6bf..1643f64 100644
--- a/app/src/keymap.c
+++ b/app/src/keymap.c
@@ -153,7 +153,9 @@ const char *zmk_keymap_layer_label(uint8_t layer) {
}
int zmk_keymap_apply_position_state(int layer, uint32_t position, bool pressed, int64_t timestamp) {
- struct zmk_behavior_binding *binding = &zmk_keymap[layer][position];
+ // We want to make a copy of this, since it may be converted from
+ // relative to absolute before being invoked
+ struct zmk_behavior_binding binding = zmk_keymap[layer][position];
const struct device *behavior;
struct zmk_behavior_binding_event event = {
.layer = layer,
@@ -162,19 +164,25 @@ int zmk_keymap_apply_position_state(int layer, uint32_t position, bool pressed,
};
LOG_DBG("layer: %d position: %d, binding name: %s", layer, position,
- log_strdup(binding->behavior_dev));
+ log_strdup(binding.behavior_dev));
- behavior = device_get_binding(binding->behavior_dev);
+ behavior = device_get_binding(binding.behavior_dev);
if (!behavior) {
LOG_DBG("No behavior assigned to %d on layer %d", position, layer);
return 1;
}
+ int err = behavior_keymap_binding_convert_central_state_dependent_params(&binding, event);
+ if (err) {
+ LOG_ERR("Failed to convert relative to absolute behavior binding (err %d)", err);
+ return err;
+ }
+
if (pressed) {
- return behavior_keymap_binding_pressed(binding, event);
+ return behavior_keymap_binding_pressed(&binding, event);
} else {
- return behavior_keymap_binding_released(binding, event);
+ return behavior_keymap_binding_released(&binding, event);
}
}