diff options
Diffstat (limited to 'qemu/hw/input')
-rw-r--r-- | qemu/hw/input/Makefile.objs | 2 | ||||
-rw-r--r-- | qemu/hw/input/adb.c | 21 | ||||
-rw-r--r-- | qemu/hw/input/hid.c | 45 | ||||
-rw-r--r-- | qemu/hw/input/lm832x.c | 1 | ||||
-rw-r--r-- | qemu/hw/input/milkymist-softusb.c | 6 | ||||
-rw-r--r-- | qemu/hw/input/pckbd.c | 1 | ||||
-rw-r--r-- | qemu/hw/input/pl050.c | 1 | ||||
-rw-r--r-- | qemu/hw/input/ps2.c | 34 | ||||
-rw-r--r-- | qemu/hw/input/pxa2xx_keypad.c | 1 | ||||
-rw-r--r-- | qemu/hw/input/stellaris_input.c | 7 | ||||
-rw-r--r-- | qemu/hw/input/tsc2005.c | 4 | ||||
-rw-r--r-- | qemu/hw/input/tsc210x.c | 12 | ||||
-rw-r--r-- | qemu/hw/input/virtio-input-hid.c | 49 | ||||
-rw-r--r-- | qemu/hw/input/virtio-input-host.c | 72 | ||||
-rw-r--r-- | qemu/hw/input/virtio-input.c | 76 | ||||
-rw-r--r-- | qemu/hw/input/vmmouse.c | 1 |
16 files changed, 246 insertions, 87 deletions
diff --git a/qemu/hw/input/Makefile.objs b/qemu/hw/input/Makefile.objs index 624ba7ea4..7715d7230 100644 --- a/qemu/hw/input/Makefile.objs +++ b/qemu/hw/input/Makefile.objs @@ -8,9 +8,9 @@ common-obj-$(CONFIG_STELLARIS_INPUT) += stellaris_input.o common-obj-$(CONFIG_TSC2005) += tsc2005.o common-obj-$(CONFIG_VMMOUSE) += vmmouse.o -ifeq ($(CONFIG_LINUX),y) common-obj-$(CONFIG_VIRTIO) += virtio-input.o common-obj-$(CONFIG_VIRTIO) += virtio-input-hid.o +ifeq ($(CONFIG_LINUX),y) common-obj-$(CONFIG_VIRTIO) += virtio-input-host.o endif diff --git a/qemu/hw/input/adb.c b/qemu/hw/input/adb.c index a18eea265..f0ad0d447 100644 --- a/qemu/hw/input/adb.c +++ b/qemu/hw/input/adb.c @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/input/adb.h" #include "ui/console.h" @@ -88,7 +89,7 @@ int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len) } /* XXX: move that to cuda ? */ -int adb_poll(ADBBusState *s, uint8_t *obuf) +int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask) { ADBDevice *d; int olen, i; @@ -99,13 +100,15 @@ int adb_poll(ADBBusState *s, uint8_t *obuf) if (s->poll_index >= s->nb_devices) s->poll_index = 0; d = s->devices[s->poll_index]; - buf[0] = ADB_READREG | (d->devaddr << 4); - olen = adb_request(s, obuf + 1, buf, 1); - /* if there is data, we poll again the same device */ - if (olen > 0) { - obuf[0] = buf[0]; - olen++; - break; + if ((1 << d->devaddr) & poll_mask) { + buf[0] = ADB_READREG | (d->devaddr << 4); + olen = adb_request(s, obuf + 1, buf, 1); + /* if there is data, we poll again the same device */ + if (olen > 0) { + obuf[0] = buf[0]; + olen++; + break; + } } s->poll_index++; } @@ -362,6 +365,7 @@ static void adb_kbd_class_init(ObjectClass *oc, void *data) akc->parent_realize = dc->realize; dc->realize = adb_kbd_realizefn; + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); adc->devreq = adb_kbd_request; dc->reset = adb_kbd_reset; @@ -566,6 +570,7 @@ static void adb_mouse_class_init(ObjectClass *oc, void *data) amc->parent_realize = dc->realize; dc->realize = adb_mouse_realizefn; + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); adc->devreq = adb_mouse_request; dc->reset = adb_mouse_reset; diff --git a/qemu/hw/input/hid.c b/qemu/hw/input/hid.c index 21ebd9e71..d92c7463b 100644 --- a/qemu/hw/input/hid.c +++ b/qemu/hw/input/hid.c @@ -22,6 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "ui/console.h" #include "qemu/timer.h" @@ -44,7 +45,7 @@ static const uint8_t hid_usage_keys[0x100] = { 0xe2, 0x2c, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f, 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59, - 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44, + 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x64, 0x44, 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, @@ -95,7 +96,7 @@ void hid_set_next_idle(HIDState *hs) { if (hs->idle) { uint64_t expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - get_ticks_per_sec() * hs->idle * 4 / 1000; + NANOSECONDS_PER_SECOND * hs->idle * 4 / 1000; if (!hs->idle_timer) { hs->idle_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, hid_idle_timer, hs); } @@ -108,44 +109,49 @@ void hid_set_next_idle(HIDState *hs) static void hid_pointer_event(DeviceState *dev, QemuConsole *src, InputEvent *evt) { - static const int bmap[INPUT_BUTTON_MAX] = { + static const int bmap[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = 0x01, [INPUT_BUTTON_RIGHT] = 0x02, [INPUT_BUTTON_MIDDLE] = 0x04, }; HIDState *hs = (HIDState *)dev; HIDPointerEvent *e; + InputMoveEvent *move; + InputBtnEvent *btn; assert(hs->n < QUEUE_LENGTH); e = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK]; - switch (evt->kind) { + switch (evt->type) { case INPUT_EVENT_KIND_REL: - if (evt->rel->axis == INPUT_AXIS_X) { - e->xdx += evt->rel->value; - } else if (evt->rel->axis == INPUT_AXIS_Y) { - e->ydy += evt->rel->value; + move = evt->u.rel.data; + if (move->axis == INPUT_AXIS_X) { + e->xdx += move->value; + } else if (move->axis == INPUT_AXIS_Y) { + e->ydy += move->value; } break; case INPUT_EVENT_KIND_ABS: - if (evt->rel->axis == INPUT_AXIS_X) { - e->xdx = evt->rel->value; - } else if (evt->rel->axis == INPUT_AXIS_Y) { - e->ydy = evt->rel->value; + move = evt->u.abs.data; + if (move->axis == INPUT_AXIS_X) { + e->xdx = move->value; + } else if (move->axis == INPUT_AXIS_Y) { + e->ydy = move->value; } break; case INPUT_EVENT_KIND_BTN: - if (evt->btn->down) { - e->buttons_state |= bmap[evt->btn->button]; - if (evt->btn->button == INPUT_BUTTON_WHEEL_UP) { + btn = evt->u.btn.data; + if (btn->down) { + e->buttons_state |= bmap[btn->button]; + if (btn->button == INPUT_BUTTON_WHEEL_UP) { e->dz--; - } else if (evt->btn->button == INPUT_BUTTON_WHEEL_DOWN) { + } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) { e->dz++; } } else { - e->buttons_state &= ~bmap[evt->btn->button]; + e->buttons_state &= ~bmap[btn->button]; } break; @@ -222,9 +228,10 @@ static void hid_keyboard_event(DeviceState *dev, QemuConsole *src, HIDState *hs = (HIDState *)dev; int scancodes[3], i, count; int slot; + InputKeyEvent *key = evt->u.key.data; - count = qemu_input_key_value_to_scancode(evt->key->key, - evt->key->down, + count = qemu_input_key_value_to_scancode(key->key, + key->down, scancodes); if (hs->n + count > QUEUE_LENGTH) { fprintf(stderr, "usb-kbd: warning: key event queue full\n"); diff --git a/qemu/hw/input/lm832x.c b/qemu/hw/input/lm832x.c index 530a6e01f..539682cac 100644 --- a/qemu/hw/input/lm832x.c +++ b/qemu/hw/input/lm832x.c @@ -18,6 +18,7 @@ * with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/i2c/i2c.h" #include "qemu/timer.h" diff --git a/qemu/hw/input/milkymist-softusb.c b/qemu/hw/input/milkymist-softusb.c index 7b0f4db88..40dfca157 100644 --- a/qemu/hw/input/milkymist-softusb.c +++ b/qemu/hw/input/milkymist-softusb.c @@ -21,6 +21,8 @@ * not available yet */ +#include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/sysbus.h" #include "trace.h" @@ -255,12 +257,12 @@ static int milkymist_softusb_init(SysBusDevice *dev) /* register pmem and dmem */ memory_region_init_ram(&s->pmem, OBJECT(s), "milkymist-softusb.pmem", - s->pmem_size, &error_abort); + s->pmem_size, &error_fatal); vmstate_register_ram_global(&s->pmem); s->pmem_ptr = memory_region_get_ram_ptr(&s->pmem); sysbus_init_mmio(dev, &s->pmem); memory_region_init_ram(&s->dmem, OBJECT(s), "milkymist-softusb.dmem", - s->dmem_size, &error_abort); + s->dmem_size, &error_fatal); vmstate_register_ram_global(&s->dmem); s->dmem_ptr = memory_region_get_ram_ptr(&s->dmem); sysbus_init_mmio(dev, &s->dmem); diff --git a/qemu/hw/input/pckbd.c b/qemu/hw/input/pckbd.c index ddac69df6..1d932ec19 100644 --- a/qemu/hw/input/pckbd.c +++ b/qemu/hw/input/pckbd.c @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/isa/isa.h" #include "hw/i386/pc.h" diff --git a/qemu/hw/input/pl050.c b/qemu/hw/input/pl050.c index c1b08d5a4..3092b0fe3 100644 --- a/qemu/hw/input/pl050.c +++ b/qemu/hw/input/pl050.c @@ -7,6 +7,7 @@ * This code is licensed under the GPL. */ +#include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/input/ps2.h" diff --git a/qemu/hw/input/ps2.c b/qemu/hw/input/ps2.c index fdbe565e6..a8aa36f5c 100644 --- a/qemu/hw/input/ps2.c +++ b/qemu/hw/input/ps2.c @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/input/ps2.h" #include "ui/console.h" @@ -181,10 +182,11 @@ static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src, { PS2KbdState *s = (PS2KbdState *)dev; int scancodes[3], i, count; + InputKeyEvent *key = evt->u.key.data; qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); - count = qemu_input_key_value_to_scancode(evt->key->key, - evt->key->down, + count = qemu_input_key_value_to_scancode(key->key, + key->down, scancodes); for (i = 0; i < count; i++) { ps2_put_keycode(s, scancodes[i]); @@ -382,36 +384,40 @@ static void ps2_mouse_send_packet(PS2MouseState *s) static void ps2_mouse_event(DeviceState *dev, QemuConsole *src, InputEvent *evt) { - static const int bmap[INPUT_BUTTON_MAX] = { + static const int bmap[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, }; PS2MouseState *s = (PS2MouseState *)dev; + InputMoveEvent *move; + InputBtnEvent *btn; /* check if deltas are recorded when disabled */ if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) return; - switch (evt->kind) { + switch (evt->type) { case INPUT_EVENT_KIND_REL: - if (evt->rel->axis == INPUT_AXIS_X) { - s->mouse_dx += evt->rel->value; - } else if (evt->rel->axis == INPUT_AXIS_Y) { - s->mouse_dy -= evt->rel->value; + move = evt->u.rel.data; + if (move->axis == INPUT_AXIS_X) { + s->mouse_dx += move->value; + } else if (move->axis == INPUT_AXIS_Y) { + s->mouse_dy -= move->value; } break; case INPUT_EVENT_KIND_BTN: - if (evt->btn->down) { - s->mouse_buttons |= bmap[evt->btn->button]; - if (evt->btn->button == INPUT_BUTTON_WHEEL_UP) { + btn = evt->u.btn.data; + if (btn->down) { + s->mouse_buttons |= bmap[btn->button]; + if (btn->button == INPUT_BUTTON_WHEEL_UP) { s->mouse_dz--; - } else if (evt->btn->button == INPUT_BUTTON_WHEEL_DOWN) { + } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) { s->mouse_dz++; } } else { - s->mouse_buttons &= ~bmap[evt->btn->button]; + s->mouse_buttons &= ~bmap[btn->button]; } break; @@ -622,7 +628,7 @@ static void ps2_kbd_reset(void *opaque) ps2_common_reset(&s->common); s->scan_enabled = 0; s->translate = 0; - s->scancode_set = 0; + s->scancode_set = 2; } static void ps2_mouse_reset(void *opaque) diff --git a/qemu/hw/input/pxa2xx_keypad.c b/qemu/hw/input/pxa2xx_keypad.c index 85011145e..2b70bbb95 100644 --- a/qemu/hw/input/pxa2xx_keypad.c +++ b/qemu/hw/input/pxa2xx_keypad.c @@ -11,6 +11,7 @@ * GNU GPL, version 2 or (at your option) any later version. */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/arm/pxa.h" #include "ui/console.h" diff --git a/qemu/hw/input/stellaris_input.c b/qemu/hw/input/stellaris_input.c index 0609e8086..99168bfee 100644 --- a/qemu/hw/input/stellaris_input.c +++ b/qemu/hw/input/stellaris_input.c @@ -6,6 +6,7 @@ * * This code is licensed under the GPL. */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/devices.h" #include "ui/console.h" @@ -69,14 +70,14 @@ static const VMStateDescription vmstate_stellaris_gamepad = { } }; -/* Returns an array 5 ouput slots. */ +/* Returns an array of 5 output slots. */ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode) { gamepad_state *s; int i; - s = (gamepad_state *)g_malloc0(sizeof (gamepad_state)); - s->buttons = (gamepad_button *)g_malloc0(n * sizeof (gamepad_button)); + s = g_new0(gamepad_state, 1); + s->buttons = g_new0(gamepad_button, n); for (i = 0; i < n; i++) { s->buttons[i].irq = irq[i]; s->buttons[i].keycode = keycode[i]; diff --git a/qemu/hw/input/tsc2005.c b/qemu/hw/input/tsc2005.c index 21d4f4dbb..9b359aaec 100644 --- a/qemu/hw/input/tsc2005.c +++ b/qemu/hw/input/tsc2005.c @@ -18,6 +18,7 @@ * with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "qemu/timer.h" #include "ui/console.h" @@ -290,7 +291,8 @@ static void tsc2005_pin_update(TSC2005State *s) s->precision = s->nextprecision; s->function = s->nextfunction; s->pdst = !s->pnd0; /* Synchronised on internal clock */ - expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() >> 7); + expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + (NANOSECONDS_PER_SECOND >> 7); timer_mod(s->timer, expires); } diff --git a/qemu/hw/input/tsc210x.c b/qemu/hw/input/tsc210x.c index fae338563..93ca374fc 100644 --- a/qemu/hw/input/tsc210x.c +++ b/qemu/hw/input/tsc210x.c @@ -19,6 +19,7 @@ * with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "audio/audio.h" #include "qemu/timer.h" @@ -834,7 +835,8 @@ static void tsc210x_pin_update(TSC210xState *s) s->busy = 1; s->precision = s->nextprecision; s->function = s->nextfunction; - expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() >> 10); + expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + (NANOSECONDS_PER_SECOND >> 10); timer_mod(s->timer, expires); } @@ -1086,9 +1088,7 @@ uWireSlave *tsc2102_init(qemu_irq pint) { TSC210xState *s; - s = (TSC210xState *) - g_malloc0(sizeof(TSC210xState)); - memset(s, 0, sizeof(TSC210xState)); + s = g_new0(TSC210xState, 1); s->x = 160; s->y = 160; s->pressure = 0; @@ -1135,9 +1135,7 @@ uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav) { TSC210xState *s; - s = (TSC210xState *) - g_malloc0(sizeof(TSC210xState)); - memset(s, 0, sizeof(TSC210xState)); + s = g_new0(TSC210xState, 1); s->x = 400; s->y = 240; s->pressure = 0; diff --git a/qemu/hw/input/virtio-input-hid.c b/qemu/hw/input/virtio-input-hid.c index 4d85dad4d..3ee0c1814 100644 --- a/qemu/hw/input/virtio-input-hid.c +++ b/qemu/hw/input/virtio-input-hid.c @@ -4,6 +4,7 @@ * top-level directory. */ +#include "qemu/osdep.h" #include "qemu/iov.h" #include "hw/qdev.h" @@ -21,7 +22,7 @@ /* ----------------------------------------------------------------- */ -static const unsigned int keymap_qcode[Q_KEY_CODE_MAX] = { +static const unsigned int keymap_qcode[Q_KEY_CODE__MAX] = { [Q_KEY_CODE_ESC] = KEY_ESC, [Q_KEY_CODE_1] = KEY_1, [Q_KEY_CODE_2] = KEY_2, @@ -120,6 +121,8 @@ static const unsigned int keymap_qcode[Q_KEY_CODE_MAX] = { [Q_KEY_CODE_CTRL_R] = KEY_RIGHTCTRL, [Q_KEY_CODE_SYSRQ] = KEY_SYSRQ, + [Q_KEY_CODE_PRINT] = KEY_SYSRQ, + [Q_KEY_CODE_PAUSE] = KEY_PAUSE, [Q_KEY_CODE_ALT_R] = KEY_RIGHTALT, [Q_KEY_CODE_HOME] = KEY_HOME, @@ -138,7 +141,7 @@ static const unsigned int keymap_qcode[Q_KEY_CODE_MAX] = { [Q_KEY_CODE_MENU] = KEY_MENU, }; -static const unsigned int keymap_button[INPUT_BUTTON_MAX] = { +static const unsigned int keymap_button[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = BTN_LEFT, [INPUT_BUTTON_RIGHT] = BTN_RIGHT, [INPUT_BUTTON_MIDDLE] = BTN_MIDDLE, @@ -146,12 +149,12 @@ static const unsigned int keymap_button[INPUT_BUTTON_MAX] = { [INPUT_BUTTON_WHEEL_DOWN] = BTN_GEAR_DOWN, }; -static const unsigned int axismap_rel[INPUT_AXIS_MAX] = { +static const unsigned int axismap_rel[INPUT_AXIS__MAX] = { [INPUT_AXIS_X] = REL_X, [INPUT_AXIS_Y] = REL_Y, }; -static const unsigned int axismap_abs[INPUT_AXIS_MAX] = { +static const unsigned int axismap_abs[INPUT_AXIS__MAX] = { [INPUT_AXIS_X] = ABS_X, [INPUT_AXIS_Y] = ABS_Y, }; @@ -190,45 +193,53 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src, VirtIOInput *vinput = VIRTIO_INPUT(dev); virtio_input_event event; int qcode; + InputKeyEvent *key; + InputMoveEvent *move; + InputBtnEvent *btn; - switch (evt->kind) { + switch (evt->type) { case INPUT_EVENT_KIND_KEY: - qcode = qemu_input_key_value_to_qcode(evt->key->key); + key = evt->u.key.data; + qcode = qemu_input_key_value_to_qcode(key->key); if (qcode && keymap_qcode[qcode]) { event.type = cpu_to_le16(EV_KEY); event.code = cpu_to_le16(keymap_qcode[qcode]); - event.value = cpu_to_le32(evt->key->down ? 1 : 0); + event.value = cpu_to_le32(key->down ? 1 : 0); virtio_input_send(vinput, &event); } else { - if (evt->key->down) { + if (key->down) { fprintf(stderr, "%s: unmapped key: %d [%s]\n", __func__, qcode, QKeyCode_lookup[qcode]); } } break; case INPUT_EVENT_KIND_BTN: - if (keymap_button[evt->btn->button]) { + btn = evt->u.btn.data; + if (keymap_button[btn->button]) { event.type = cpu_to_le16(EV_KEY); - event.code = cpu_to_le16(keymap_button[evt->btn->button]); - event.value = cpu_to_le32(evt->btn->down ? 1 : 0); + event.code = cpu_to_le16(keymap_button[btn->button]); + event.value = cpu_to_le32(btn->down ? 1 : 0); virtio_input_send(vinput, &event); } else { - if (evt->btn->down) { + if (btn->down) { fprintf(stderr, "%s: unmapped button: %d [%s]\n", __func__, - evt->btn->button, InputButton_lookup[evt->btn->button]); + btn->button, + InputButton_lookup[btn->button]); } } break; case INPUT_EVENT_KIND_REL: + move = evt->u.rel.data; event.type = cpu_to_le16(EV_REL); - event.code = cpu_to_le16(axismap_rel[evt->rel->axis]); - event.value = cpu_to_le32(evt->rel->value); + event.code = cpu_to_le16(axismap_rel[move->axis]); + event.value = cpu_to_le32(move->value); virtio_input_send(vinput, &event); break; case INPUT_EVENT_KIND_ABS: + move = evt->u.abs.data; event.type = cpu_to_le16(EV_ABS); - event.code = cpu_to_le16(axismap_abs[evt->abs->axis]); - event.value = cpu_to_le32(evt->abs->value); + event.code = cpu_to_le16(axismap_abs[move->axis]); + event.value = cpu_to_le32(move->value); virtio_input_send(vinput, &event); break; default: @@ -473,12 +484,12 @@ static struct virtio_input_config virtio_tablet_config[] = { .select = VIRTIO_INPUT_CFG_ABS_INFO, .subsel = ABS_X, .size = sizeof(virtio_input_absinfo), - .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE), + .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1), },{ .select = VIRTIO_INPUT_CFG_ABS_INFO, .subsel = ABS_Y, .size = sizeof(virtio_input_absinfo), - .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE), + .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1), }, { /* end of list */ }, }; diff --git a/qemu/hw/input/virtio-input-host.c b/qemu/hw/input/virtio-input-host.c index 8978f16ba..cb79e8002 100644 --- a/qemu/hw/input/virtio-input-host.c +++ b/qemu/hw/input/virtio-input-host.c @@ -4,6 +4,8 @@ * top-level directory. */ +#include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/sockets.h" @@ -68,13 +70,39 @@ static void virtio_input_bits_config(VirtIOInputHost *vih, virtio_input_add_config(VIRTIO_INPUT(vih), &bits); } +static void virtio_input_abs_config(VirtIOInputHost *vih, int axis) +{ + virtio_input_config config; + struct input_absinfo absinfo; + int rc; + + rc = ioctl(vih->fd, EVIOCGABS(axis), &absinfo); + if (rc < 0) { + return; + } + + memset(&config, 0, sizeof(config)); + config.select = VIRTIO_INPUT_CFG_ABS_INFO; + config.subsel = axis; + config.size = sizeof(virtio_input_absinfo); + + config.u.abs.min = cpu_to_le32(absinfo.minimum); + config.u.abs.max = cpu_to_le32(absinfo.maximum); + config.u.abs.fuzz = cpu_to_le32(absinfo.fuzz); + config.u.abs.flat = cpu_to_le32(absinfo.flat); + config.u.abs.res = cpu_to_le32(absinfo.resolution); + + virtio_input_add_config(VIRTIO_INPUT(vih), &config); +} + static void virtio_input_host_realize(DeviceState *dev, Error **errp) { VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev); VirtIOInput *vinput = VIRTIO_INPUT(dev); - virtio_input_config id; + virtio_input_config id, *abs; struct input_id ids; - int rc, ver; + int rc, ver, i, axis; + uint8_t byte; if (!vih->evdev) { error_setg(errp, "evdev property is required"); @@ -123,6 +151,23 @@ static void virtio_input_host_realize(DeviceState *dev, Error **errp) virtio_input_bits_config(vih, EV_ABS, ABS_CNT); virtio_input_bits_config(vih, EV_MSC, MSC_CNT); virtio_input_bits_config(vih, EV_SW, SW_CNT); + virtio_input_bits_config(vih, EV_LED, LED_CNT); + + abs = virtio_input_find_config(VIRTIO_INPUT(vih), + VIRTIO_INPUT_CFG_EV_BITS, EV_ABS); + if (abs) { + for (i = 0; i < abs->size; i++) { + byte = abs->u.bitmap[i]; + axis = 8 * i; + while (byte) { + if (byte & 1) { + virtio_input_abs_config(vih, axis); + } + axis++; + byte >>= 1; + } + } + } qemu_set_fd_handler(vih->fd, virtio_input_host_event, NULL, vih); return; @@ -143,6 +188,28 @@ static void virtio_input_host_unrealize(DeviceState *dev, Error **errp) } } +static void virtio_input_host_handle_status(VirtIOInput *vinput, + virtio_input_event *event) +{ + VirtIOInputHost *vih = VIRTIO_INPUT_HOST(vinput); + struct input_event evdev; + int rc; + + if (gettimeofday(&evdev.time, NULL)) { + perror("virtio_input_host_handle_status: gettimeofday"); + return; + } + + evdev.type = le16_to_cpu(event->type); + evdev.code = le16_to_cpu(event->code); + evdev.value = le32_to_cpu(event->value); + + rc = write(vih->fd, &evdev, sizeof(evdev)); + if (rc == -1) { + perror("virtio_input_host_handle_status: write"); + } +} + static const VMStateDescription vmstate_virtio_input_host = { .name = "virtio-input-host", .unmigratable = 1, @@ -162,6 +229,7 @@ static void virtio_input_host_class_init(ObjectClass *klass, void *data) dc->props = virtio_input_host_properties; vic->realize = virtio_input_host_realize; vic->unrealize = virtio_input_host_unrealize; + vic->handle_status = virtio_input_host_handle_status; } static void virtio_input_host_init(Object *obj) diff --git a/qemu/hw/input/virtio-input.c b/qemu/hw/input/virtio-input.c index 7b25d2769..f59749a94 100644 --- a/qemu/hw/input/virtio-input.c +++ b/qemu/hw/input/virtio-input.c @@ -4,6 +4,8 @@ * top-level directory. */ +#include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu/iov.h" #include "hw/qdev.h" @@ -12,14 +14,20 @@ #include "standard-headers/linux/input.h" +#define VIRTIO_INPUT_VM_VERSION 1 + /* ----------------------------------------------------------------- */ void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event) { - VirtQueueElement elem; + VirtQueueElement *elem; unsigned have, need; int i, len; + if (!vinput->active) { + return; + } + /* queue up events ... */ if (vinput->qindex == vinput->qsize) { vinput->qsize++; @@ -45,14 +53,16 @@ void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event) /* ... and finally pass them to the guest */ for (i = 0; i < vinput->qindex; i++) { - if (!virtqueue_pop(vinput->evt, &elem)) { + elem = virtqueue_pop(vinput->evt, sizeof(VirtQueueElement)); + if (!elem) { /* should not happen, we've checked for space beforehand */ fprintf(stderr, "%s: Huh? No vq elem available ...\n", __func__); return; } - len = iov_from_buf(elem.in_sg, elem.in_num, + len = iov_from_buf(elem->in_sg, elem->in_num, 0, vinput->queue+i, sizeof(virtio_input_event)); - virtqueue_push(vinput->evt, &elem, len); + virtqueue_push(vinput->evt, elem, len); + g_free(elem); } virtio_notify(VIRTIO_DEVICE(vinput), vinput->evt); vinput->qindex = 0; @@ -68,24 +78,30 @@ static void virtio_input_handle_sts(VirtIODevice *vdev, VirtQueue *vq) VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vdev); VirtIOInput *vinput = VIRTIO_INPUT(vdev); virtio_input_event event; - VirtQueueElement elem; + VirtQueueElement *elem; int len; - while (virtqueue_pop(vinput->sts, &elem)) { + for (;;) { + elem = virtqueue_pop(vinput->sts, sizeof(VirtQueueElement)); + if (!elem) { + break; + } + memset(&event, 0, sizeof(event)); - len = iov_to_buf(elem.out_sg, elem.out_num, + len = iov_to_buf(elem->out_sg, elem->out_num, 0, &event, sizeof(event)); if (vic->handle_status) { vic->handle_status(vinput, &event); } - virtqueue_push(vinput->sts, &elem, len); + virtqueue_push(vinput->sts, elem, len); + g_free(elem); } virtio_notify(vdev, vinput->sts); } -static virtio_input_config *virtio_input_find_config(VirtIOInput *vinput, - uint8_t select, - uint8_t subsel) +virtio_input_config *virtio_input_find_config(VirtIOInput *vinput, + uint8_t select, + uint8_t subsel) { VirtIOInputConfig *cfg; @@ -200,6 +216,38 @@ static void virtio_input_reset(VirtIODevice *vdev) } } +static void virtio_input_save(QEMUFile *f, void *opaque) +{ + VirtIOInput *vinput = opaque; + VirtIODevice *vdev = VIRTIO_DEVICE(vinput); + + virtio_save(vdev, f); +} + +static int virtio_input_load(QEMUFile *f, void *opaque, int version_id) +{ + VirtIOInput *vinput = opaque; + VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vinput); + VirtIODevice *vdev = VIRTIO_DEVICE(vinput); + int ret; + + if (version_id != VIRTIO_INPUT_VM_VERSION) { + return -EINVAL; + } + + ret = virtio_load(vdev, f, version_id); + if (ret) { + return ret; + } + + /* post_load() */ + vinput->active = vdev->status & VIRTIO_CONFIG_S_DRIVER_OK; + if (vic->change_active) { + vic->change_active(vinput); + } + return 0; +} + static void virtio_input_device_realize(DeviceState *dev, Error **errp) { VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev); @@ -231,14 +279,20 @@ static void virtio_input_device_realize(DeviceState *dev, Error **errp) vinput->cfg_size); vinput->evt = virtio_add_queue(vdev, 64, virtio_input_handle_evt); vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts); + + register_savevm(dev, "virtio-input", -1, VIRTIO_INPUT_VM_VERSION, + virtio_input_save, virtio_input_load, vinput); } static void virtio_input_device_unrealize(DeviceState *dev, Error **errp) { VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev); VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOInput *vinput = VIRTIO_INPUT(dev); Error *local_err = NULL; + unregister_savevm(dev, "virtio-input", vinput); + if (vic->unrealize) { vic->unrealize(dev, &local_err); if (local_err) { diff --git a/qemu/hw/input/vmmouse.c b/qemu/hw/input/vmmouse.c index d7b1c76f5..6d15a887c 100644 --- a/qemu/hw/input/vmmouse.c +++ b/qemu/hw/input/vmmouse.c @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "ui/console.h" #include "hw/input/ps2.h" |