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.
This commit is contained in:
parent
bb2c478af9
commit
e6f168d6df
4 changed files with 79 additions and 5 deletions
|
@ -27,6 +27,7 @@ typedef int (*behavior_sensor_keymap_binding_callback_t)(struct zmk_behavior_bin
|
||||||
int64_t timestamp);
|
int64_t timestamp);
|
||||||
|
|
||||||
__subsystem struct behavior_driver_api {
|
__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_pressed;
|
||||||
behavior_keymap_binding_callback_t binding_released;
|
behavior_keymap_binding_callback_t binding_released;
|
||||||
behavior_sensor_keymap_binding_callback_t sensor_binding_triggered;
|
behavior_sensor_keymap_binding_callback_t sensor_binding_triggered;
|
||||||
|
@ -35,6 +36,30 @@ __subsystem struct behavior_driver_api {
|
||||||
* @endcond
|
* @endcond
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
* @brief Handle the keymap binding being pressed
|
||||||
* @param dev Pointer to the device structure for the driver instance.
|
* @param dev Pointer to the device structure for the driver instance.
|
||||||
|
|
|
@ -18,6 +18,22 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
#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,
|
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||||
struct zmk_behavior_binding_event event) {
|
struct zmk_behavior_binding_event event) {
|
||||||
const struct device *ext_power = device_get_binding("EXT_POWER");
|
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 int behavior_ext_power_init(const struct device *dev) { return 0; };
|
||||||
|
|
||||||
static const struct behavior_driver_api behavior_ext_power_driver_api = {
|
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_pressed = on_keymap_binding_pressed,
|
||||||
.binding_released = on_keymap_binding_released,
|
.binding_released = on_keymap_binding_released,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 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,
|
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||||
struct zmk_behavior_binding_event event) {
|
struct zmk_behavior_binding_event event) {
|
||||||
switch (binding->param1) {
|
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 = {
|
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_pressed = on_keymap_binding_pressed,
|
||||||
.binding_released = on_keymap_binding_released,
|
.binding_released = on_keymap_binding_released,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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) {
|
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;
|
const struct device *behavior;
|
||||||
struct zmk_behavior_binding_event event = {
|
struct zmk_behavior_binding_event event = {
|
||||||
.layer = layer,
|
.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_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) {
|
if (!behavior) {
|
||||||
LOG_DBG("No behavior assigned to %d on layer %d", position, layer);
|
LOG_DBG("No behavior assigned to %d on layer %d", position, layer);
|
||||||
return 1;
|
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) {
|
if (pressed) {
|
||||||
return behavior_keymap_binding_pressed(binding, event);
|
return behavior_keymap_binding_pressed(&binding, event);
|
||||||
} else {
|
} else {
|
||||||
return behavior_keymap_binding_released(binding, event);
|
return behavior_keymap_binding_released(&binding, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue