| #include "sysemu/sysemu.h" |
| #include "qapi-types.h" |
| #include "ui/input.h" |
| |
| struct QemuInputHandlerState { |
| DeviceState *dev; |
| QemuInputHandler *handler; |
| int id; |
| int events; |
| QTAILQ_ENTRY(QemuInputHandlerState) node; |
| }; |
| static QTAILQ_HEAD(, QemuInputHandlerState) handlers = |
| QTAILQ_HEAD_INITIALIZER(handlers); |
| |
| QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev, |
| QemuInputHandler *handler) |
| { |
| QemuInputHandlerState *s = g_new0(QemuInputHandlerState, 1); |
| static int id = 1; |
| |
| s->dev = dev; |
| s->handler = handler; |
| s->id = id++; |
| QTAILQ_INSERT_TAIL(&handlers, s, node); |
| return s; |
| } |
| |
| void qemu_input_handler_activate(QemuInputHandlerState *s) |
| { |
| QTAILQ_REMOVE(&handlers, s, node); |
| QTAILQ_INSERT_HEAD(&handlers, s, node); |
| } |
| |
| void qemu_input_handler_unregister(QemuInputHandlerState *s) |
| { |
| QTAILQ_REMOVE(&handlers, s, node); |
| g_free(s); |
| } |
| |
| static QemuInputHandlerState* |
| qemu_input_find_handler(uint32_t mask) |
| { |
| QemuInputHandlerState *s; |
| |
| QTAILQ_FOREACH(s, &handlers, node) { |
| if (mask & s->handler->mask) { |
| return s; |
| } |
| } |
| return NULL; |
| } |
| |
| void qemu_input_event_send(QemuConsole *src, InputEvent *evt) |
| { |
| QemuInputHandlerState *s; |
| |
| if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { |
| return; |
| } |
| |
| s = qemu_input_find_handler(1 << evt->kind); |
| s->handler->event(s->dev, src, evt); |
| s->events++; |
| } |
| |
| void qemu_input_event_sync(void) |
| { |
| QemuInputHandlerState *s; |
| |
| if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { |
| return; |
| } |
| |
| QTAILQ_FOREACH(s, &handlers, node) { |
| if (!s->events) { |
| continue; |
| } |
| if (s->handler->sync) { |
| s->handler->sync(s->dev); |
| } |
| s->events = 0; |
| } |
| } |
| |
| InputEvent *qemu_input_event_new_key(KeyValue *key, bool down) |
| { |
| InputEvent *evt = g_new0(InputEvent, 1); |
| evt->key = g_new0(InputKeyEvent, 1); |
| evt->kind = INPUT_EVENT_KIND_KEY; |
| evt->key->key = key; |
| evt->key->down = down; |
| return evt; |
| } |
| |
| void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down) |
| { |
| InputEvent *evt; |
| evt = qemu_input_event_new_key(key, down); |
| qemu_input_event_send(src, evt); |
| qemu_input_event_sync(); |
| qapi_free_InputEvent(evt); |
| } |
| |
| void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down) |
| { |
| KeyValue *key = g_new0(KeyValue, 1); |
| key->kind = KEY_VALUE_KIND_NUMBER; |
| key->number = num; |
| qemu_input_event_send_key(src, key, down); |
| } |
| |
| void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down) |
| { |
| KeyValue *key = g_new0(KeyValue, 1); |
| key->kind = KEY_VALUE_KIND_QCODE; |
| key->qcode = q; |
| qemu_input_event_send_key(src, key, down); |
| } |