feature(events): add behavior-state-changed event

This commit is contained in:
Okke Formsma 2020-12-19 14:28:32 +01:00
parent a7c6e080a7
commit 5c93f0b50b
6 changed files with 110 additions and 20 deletions

View file

@ -32,6 +32,7 @@ target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/wpm.c)
target_sources(app PRIVATE src/event_manager.c)
target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/ext_power_generic.c)
target_sources(app PRIVATE src/events/activity_state_changed.c)
target_sources(app PRIVATE src/events/behavior_state_changed.c)
target_sources(app PRIVATE src/events/position_state_changed.c)
target_sources(app PRIVATE src/events/layer_state_changed.c)
target_sources(app PRIVATE src/events/keycode_state_changed.c)
@ -74,6 +75,7 @@ target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/hog.c)
target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/rgb_underglow.c)
target_sources(app PRIVATE src/endpoints.c)
target_sources(app PRIVATE src/hid_listener.c)
target_sources(app PRIVATE src/behavior.c)
target_sources(app PRIVATE src/main.c)
add_subdirectory(src/display/)

View file

@ -0,0 +1,21 @@
/*
* Copyright (c) 2020 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/
#pragma once
#include <zephyr.h>
#include <zmk/event_manager.h>
#include <zmk/behavior.h>
struct zmk_behavior_state_changed {
struct zmk_behavior_binding binding;
bool pressed;
int layer;
uint32_t position;
int64_t timestamp;
};
ZMK_EVENT_DECLARE(zmk_behavior_state_changed);

59
app/src/behavior.c Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2020 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/
#include <sys/util.h>
#include <logging/log.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/matrix.h>
#include <zmk/sensors.h>
#include <zmk/keymap.h>
#include <drivers/behavior.h>
#include <zmk/behavior.h>
#include <zmk/event_manager.h>
#include <zmk/events/position_state_changed.h>
#include <zmk/events/behavior_state_changed.h>
#include <zmk/events/sensor_event.h>
int zmk_behavior_state_changed_listener(const zmk_event_t *zmk_ev) {
struct zmk_behavior_state_changed *ev = as_zmk_behavior_state_changed(zmk_ev);
if (ev == NULL) {
return 0;
}
const struct zmk_behavior_binding_event event = {
.layer = ev->layer,
.position = ev->position,
.timestamp = ev->timestamp,
};
int err = behavior_keymap_binding_convert_central_state_dependent_params(&ev->binding, event);
if (err) {
LOG_ERR("Failed to convert relative to absolute behavior binding (err %d)", err);
return err;
}
int ret;
if (ev->pressed) {
ret = behavior_keymap_binding_pressed(&ev->binding, event);
} else {
ret = behavior_keymap_binding_released(&ev->binding, event);
}
if (ret < 0) {
return ret;
}
switch (ret) {
case ZMK_BEHAVIOR_TRANSPARENT:
return ZMK_EV_EVENT_BUBBLE;
case ZMK_BEHAVIOR_OPAQUE:
return ZMK_EV_EVENT_HANDLED;
default:
return -ENOTSUP;
}
}
ZMK_LISTENER(behavior, zmk_behavior_state_changed_listener);
ZMK_SUBSCRIPTION(behavior, zmk_behavior_state_changed);

View file

@ -17,6 +17,12 @@ extern struct zmk_event_type *__event_type_end[];
extern struct zmk_event_subscription __event_subscriptions_start[];
extern struct zmk_event_subscription __event_subscriptions_end[];
/*
* Returns negative values for errors.
* Returns ZMK_EV_EVENT_HANDLED if the event was handled
* Returns ZMK_EV_EVENT_CAPTURED if the event was captured
* Returns ZMK_EV_EVENT_BUBBLE if no handler handled the event
*/
int zmk_event_manager_handle_from(zmk_event_t *event, uint8_t start_index) {
int ret = 0;
uint8_t len = __event_subscriptions_end - __event_subscriptions_start;
@ -31,13 +37,12 @@ int zmk_event_manager_handle_from(zmk_event_t *event, uint8_t start_index) {
switch (ret) {
case ZMK_EV_EVENT_HANDLED:
LOG_DBG("Listener handled the event");
ret = 0;
goto release;
case ZMK_EV_EVENT_CAPTURED:
LOG_DBG("Listener captured the event");
event->last_listener_index = i;
// Listeners are expected to free events they capture
return 0;
return ret;
}
}
}

View file

@ -0,0 +1,10 @@
/*
* Copyright (c) 2020 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/
#include <kernel.h>
#include <zmk/events/behavior_state_changed.h>
ZMK_EVENT_IMPL(zmk_behavior_state_changed);

View file

@ -16,6 +16,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/event_manager.h>
#include <zmk/events/position_state_changed.h>
#include <zmk/events/behavior_state_changed.h>
#include <zmk/events/layer_state_changed.h>
#include <zmk/events/sensor_event.h>
@ -157,11 +158,6 @@ int zmk_keymap_apply_position_state(int layer, uint32_t position, bool pressed,
// 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,
.position = position,
.timestamp = timestamp,
};
LOG_DBG("layer: %d position: %d, binding name: %s", layer, position,
log_strdup(binding.behavior_dev));
@ -170,20 +166,17 @@ int zmk_keymap_apply_position_state(int layer, uint32_t position, bool pressed,
if (!behavior) {
LOG_DBG("No behavior assigned to %d on layer %d", position, layer);
return 1;
return ZMK_EV_EVENT_HANDLED;
}
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);
} else {
return behavior_keymap_binding_released(&binding, event);
}
return ZMK_EVENT_RAISE(new_zmk_behavior_state_changed((struct zmk_behavior_state_changed){
.binding = binding,
.pressed = pressed,
.layer = layer,
.position = position,
.timestamp = timestamp,
}));
;
}
int zmk_keymap_position_state_changed(uint32_t position, bool pressed, int64_t timestamp) {
@ -193,7 +186,7 @@ int zmk_keymap_position_state_changed(uint32_t position, bool pressed, int64_t t
for (int layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer >= _zmk_keymap_layer_default; layer--) {
if (zmk_keymap_layer_active_with_state(layer, zmk_keymap_active_behavior_layer[position])) {
int ret = zmk_keymap_apply_position_state(layer, position, pressed, timestamp);
if (ret > 0) {
if (ret == ZMK_EV_EVENT_BUBBLE) {
LOG_DBG("behavior processing to continue to next layer");
continue;
} else if (ret < 0) {