2013-11-27 17:35:26 +08:00
|
|
|
#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;
|
|
|
|
}
|
|
|
|
}
|
2013-11-27 18:38:47 +08:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|