Add per-handler LED state and a NotifierList for UI backends to subscribe to LED changes.
Devices call qemu_input_handler_set_led() to store their LED state and notify backends. Notify also on focus change, or list update. Note: I considered conflating mouse-mode & led-state changes, but those are quite different events (from different source kinds etc) and we may want to improve the internal implementation. Signed-off-by: Marc-André Lureau <[email protected]> --- include/ui/input.h | 5 +++++ ui/input.c | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/include/ui/input.h b/include/ui/input.h index 6df8ae3a8a3..66e5c1f4b06 100644 --- a/include/ui/input.h +++ b/include/ui/input.h @@ -151,4 +151,9 @@ extern const guint16 qemu_input_map_xorgxwin_to_linux[]; extern const guint qemu_input_map_osx_to_linux_len; extern const guint16 qemu_input_map_osx_to_linux[]; +void qemu_input_handler_set_led(QemuInputHandlerState *s, int ledstate); +void qemu_input_led_notifier_add(Notifier *n); +void qemu_input_led_notifier_remove(Notifier *n); +int qemu_input_get_led(QemuConsole *con); + #endif /* INPUT_H */ diff --git a/ui/input.c b/ui/input.c index 15affeabf44..99a1090f8c3 100644 --- a/ui/input.c +++ b/ui/input.c @@ -14,6 +14,7 @@ struct QemuInputHandlerState { int id; int events; QemuConsole *con; + int ledstate; QTAILQ_ENTRY(QemuInputHandlerState) node; }; @@ -38,6 +39,8 @@ static QTAILQ_HEAD(, QemuInputHandlerState) handlers = QTAILQ_HEAD_INITIALIZER(handlers); static NotifierList mouse_mode_notifiers = NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers); +static NotifierList led_notifiers = + NOTIFIER_LIST_INITIALIZER(led_notifiers); static QemuInputEventQueueHead kbd_queue = QTAILQ_HEAD_INITIALIZER(kbd_queue); static QEMUTimer *kbd_timer; @@ -45,6 +48,14 @@ static uint32_t kbd_default_delay_ms = 10; static uint32_t queue_count; static uint32_t queue_limit = 1024; +static void notify_input_changed(uint32_t mask) +{ + notifier_list_notify(&mouse_mode_notifiers, NULL); + if (mask & INPUT_EVENT_MASK_KEY) { + notifier_list_notify(&led_notifiers, NULL); + } +} + QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev, const QemuInputHandler *handler) { @@ -55,8 +66,8 @@ QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev, s->handler = handler; s->id = id++; QTAILQ_INSERT_TAIL(&handlers, s, node); + notify_input_changed(handler->mask); - notifier_list_notify(&mouse_mode_notifiers, NULL); return s; } @@ -64,21 +75,23 @@ void qemu_input_handler_activate(QemuInputHandlerState *s) { QTAILQ_REMOVE(&handlers, s, node); QTAILQ_INSERT_HEAD(&handlers, s, node); - notifier_list_notify(&mouse_mode_notifiers, NULL); + notify_input_changed(s->handler->mask); } void qemu_input_handler_deactivate(QemuInputHandlerState *s) { QTAILQ_REMOVE(&handlers, s, node); QTAILQ_INSERT_TAIL(&handlers, s, node); - notifier_list_notify(&mouse_mode_notifiers, NULL); + notify_input_changed(s->handler->mask); } void qemu_input_handler_unregister(QemuInputHandlerState *s) { + uint32_t mask = s->handler->mask; + QTAILQ_REMOVE(&handlers, s, node); g_free(s); - notifier_list_notify(&mouse_mode_notifiers, NULL); + notify_input_changed(mask); } void qemu_input_handler_bind(QemuInputHandlerState *s, @@ -122,6 +135,23 @@ qemu_input_find_handler(uint32_t mask, QemuConsole *con) return NULL; } +void qemu_input_handler_set_led(QemuInputHandlerState *s, int ledstate) +{ + assert(s->handler->mask & INPUT_EVENT_MASK_KEY); + s->ledstate = ledstate; + notifier_list_notify(&led_notifiers, NULL); +} + +void qemu_input_led_notifier_add(Notifier *n) +{ + notifier_list_add(&led_notifiers, n); +} + +void qemu_input_led_notifier_remove(Notifier *n) +{ + notifier_remove(n); +} + void qmp_input_send_event(const char *device, bool has_head, int64_t head, InputEventList *events, Error **errp) @@ -445,6 +475,17 @@ bool qemu_input_is_absolute(QemuConsole *con) return (s != NULL) && (s->handler->mask & INPUT_EVENT_MASK_ABS); } +int qemu_input_get_led(QemuConsole *con) +{ + QemuInputHandlerState *s; + + s = qemu_input_find_handler(INPUT_EVENT_MASK_KEY, con); + if (s) { + return s->ledstate; + } + return 0; +} + int qemu_input_scale_axis(int value, int min_in, int max_in, int min_out, int max_out) -- 2.54.0
