diff --git a/app/include/zmk/event_manager.h b/app/include/zmk/event_manager.h index 489147443a5..6213db16a8b 100644 --- a/app/include/zmk/event_manager.h +++ b/app/include/zmk/event_manager.h @@ -52,8 +52,8 @@ struct zmk_event_subscription { return *outer; \ }; \ int raise_##event_type(struct event_type data) { \ - struct event_type##_event ev = {.data = data}; \ - ev.header.event = &zmk_event_##event_type; \ + struct event_type##_event ev = {.data = data, \ + .header = {.event = &zmk_event_##event_type}}; \ return ZMK_EVENT_RAISE(ev); \ }; \ struct event_type *as_##event_type(const zmk_event_t *eh) { \ @@ -71,15 +71,19 @@ struct zmk_event_subscription { .listener = &zmk_listener_##mod, \ }; -#define ZMK_EVENT_RAISE(ev) zmk_event_manager_raise((zmk_event_t *)&ev); +#define ZMK_ASSERT_EVENT_LIKE(ev) \ + (__ASSERT((uint8_t *)&(ev).header - (uint8_t *)&ev == 0, \ + "header must be first element of event")) + +#define ZMK_EVENT_RAISE(ev) (ZMK_ASSERT_EVENT_LIKE(ev), zmk_event_manager_raise(&(ev).header)) #define ZMK_EVENT_RAISE_AFTER(ev, mod) \ - zmk_event_manager_raise_after((zmk_event_t *)&ev, &zmk_listener_##mod); + (ZMK_ASSERT_EVENT_LIKE(ev), zmk_event_manager_raise_after(&(ev).header, &zmk_listener_##mod)) #define ZMK_EVENT_RAISE_AT(ev, mod) \ - zmk_event_manager_raise_at((zmk_event_t *)&ev, &zmk_listener_##mod); + (ZMK_ASSERT_EVENT_LIKE(ev), zmk_event_manager_raise_at(&(ev).header, &zmk_listener_##mod)) -#define ZMK_EVENT_RELEASE(ev) zmk_event_manager_release((zmk_event_t *)&ev); +#define ZMK_EVENT_RELEASE(ev) (ZMK_ASSERT_EVENT_LIKE(ev), zmk_event_manager_release(&(ev).header)) int zmk_event_manager_raise(zmk_event_t *event); int zmk_event_manager_raise_after(zmk_event_t *event, const struct zmk_listener *listener); diff --git a/app/include/zmk/events/keycode_state_changed.h b/app/include/zmk/events/keycode_state_changed.h index 20a46351552..60ffcfc89e2 100644 --- a/app/include/zmk/events/keycode_state_changed.h +++ b/app/include/zmk/events/keycode_state_changed.h @@ -45,3 +45,9 @@ zmk_keycode_state_changed_from_encoded(uint32_t encoded, bool pressed, int64_t t .state = pressed, .timestamp = timestamp}; } + +static inline int raise_zmk_keycode_state_changed_from_encoded(uint32_t encoded, bool pressed, + int64_t timestamp) { + return raise_zmk_keycode_state_changed( + zmk_keycode_state_changed_from_encoded(encoded, pressed, timestamp)); +} diff --git a/app/src/behaviors/behavior_key_press.c b/app/src/behaviors/behavior_key_press.c index f516122ed96..5374e6dd158 100644 --- a/app/src/behaviors/behavior_key_press.c +++ b/app/src/behaviors/behavior_key_press.c @@ -21,15 +21,13 @@ static int behavior_key_press_init(const struct device *dev) { return 0; }; static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) { LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1); - return raise_zmk_keycode_state_changed( - zmk_keycode_state_changed_from_encoded(binding->param1, true, event.timestamp)); + return raise_zmk_keycode_state_changed_from_encoded(binding->param1, true, event.timestamp); } static int on_keymap_binding_released(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) { LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1); - return raise_zmk_keycode_state_changed( - zmk_keycode_state_changed_from_encoded(binding->param1, false, event.timestamp)); + return raise_zmk_keycode_state_changed_from_encoded(binding->param1, false, event.timestamp); } static const struct behavior_driver_api behavior_key_press_driver_api = { diff --git a/app/src/behaviors/behavior_key_toggle.c b/app/src/behaviors/behavior_key_toggle.c index a4bfafb4047..db77f81412a 100644 --- a/app/src/behaviors/behavior_key_toggle.c +++ b/app/src/behaviors/behavior_key_toggle.c @@ -23,8 +23,7 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) { LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1); bool pressed = zmk_hid_is_pressed(binding->param1); - return raise_zmk_keycode_state_changed( - zmk_keycode_state_changed_from_encoded(binding->param1, !pressed, event.timestamp)); + return raise_zmk_keycode_state_changed_from_encoded(binding->param1, !pressed, event.timestamp); } static int on_keymap_binding_released(struct zmk_behavior_binding *binding, diff --git a/app/src/behaviors/behavior_sticky_key.c b/app/src/behaviors/behavior_sticky_key.c index 86a0783ef7a..aabb017eaa1 100644 --- a/app/src/behaviors/behavior_sticky_key.c +++ b/app/src/behaviors/behavior_sticky_key.c @@ -236,8 +236,8 @@ static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) { if (sticky_key->config->quick_release) { // immediately release the sticky key after the key press is handled. if (!event_reraised) { - struct zmk_keycode_state_changed_event dupe_ev; - memcpy(&dupe_ev, eh, sizeof(struct zmk_keycode_state_changed_event)); + struct zmk_keycode_state_changed_event dupe_ev = + copy_raised_zmk_keycode_state_changed(ev); ZMK_EVENT_RAISE_AFTER(dupe_ev, behavior_sticky_key); event_reraised = true; } diff --git a/app/src/combo.c b/app/src/combo.c index 2ccc1051f00..5003d7f957a 100644 --- a/app/src/combo.c +++ b/app/src/combo.c @@ -274,14 +274,14 @@ static int release_pressed_keys() { uint32_t count = pressed_keys_count; pressed_keys_count = 0; for (int i = 0; i < count; i++) { - struct zmk_position_state_changed_event ev = pressed_keys[i]; + struct zmk_position_state_changed_event *ev = &pressed_keys[i]; if (i == 0) { - LOG_DBG("combo: releasing position event %d", ev.data.position); - ZMK_EVENT_RELEASE(ev) + LOG_DBG("combo: releasing position event %d", ev->data.position); + ZMK_EVENT_RELEASE(*ev); } else { // reprocess events (see tests/combo/fully-overlapping-combos-3 for why this is needed) - LOG_DBG("combo: reraising position event %d", ev.data.position); - ZMK_EVENT_RAISE(ev); + LOG_DBG("combo: reraising position event %d", ev->data.position); + ZMK_EVENT_RAISE(*ev); } }