[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2] Split adb.c into adb.c, adb-mouse.c and adb-
From: |
Philippe Mathieu-Daudé |
Subject: |
Re: [Qemu-devel] [PATCH v2] Split adb.c into adb.c, adb-mouse.c and adb-kbd.c |
Date: |
Wed, 20 Dec 2017 10:16:50 -0300 |
On Wed, Dec 20, 2017 at 9:14 AM, Laurent Vivier <address@hidden> wrote:
> It makes the code clearer to separate the bus implementation
> from the devices one.
>
> Replace ADB_DPRINTF() with trace events (and adding new ones in adb-kbd.c).
> Some minor changes to make checkpatch.pl happy.
>
> Signed-off-by: Laurent Vivier <address@hidden>
> ---
> v2: move internal declarations to adb-internal.h
> replace ADB_DPRINTF() with trace event.
>
> hw/input/Makefile.objs | 2 +-
> hw/input/adb-internal.h | 49 ++++
> hw/input/adb-kbd.c | 400 +++++++++++++++++++++++++++++++
> hw/input/adb-mouse.c | 254 ++++++++++++++++++++
> hw/input/adb.c | 622
> +-----------------------------------------------
> hw/input/trace-events | 8 +
> 6 files changed, 714 insertions(+), 621 deletions(-)
> create mode 100644 hw/input/adb-internal.h
> create mode 100644 hw/input/adb-kbd.c
> create mode 100644 hw/input/adb-mouse.c
>
> diff --git a/hw/input/Makefile.objs b/hw/input/Makefile.objs
> index 636f794b6b..77e53e6883 100644
> --- a/hw/input/Makefile.objs
> +++ b/hw/input/Makefile.objs
> @@ -1,4 +1,4 @@
> -common-obj-$(CONFIG_ADB) += adb.o
> +common-obj-$(CONFIG_ADB) += adb.o adb-mouse.o adb-kbd.o
> common-obj-y += hid.o
> common-obj-$(CONFIG_LM832X) += lm832x.o
> common-obj-$(CONFIG_PCKBD) += pckbd.o
> diff --git a/hw/input/adb-internal.h b/hw/input/adb-internal.h
> new file mode 100644
> index 0000000000..2a779b8a0a
> --- /dev/null
> +++ b/hw/input/adb-internal.h
thanks :)
> @@ -0,0 +1,49 @@
> +/*
> + * QEMU ADB support
> + *
> + * Copyright (c) 2004 Fabrice Bellard
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> deal
> + * in the Software without restriction, including without limitation the
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +/* ADB commands */
> +
> +#define ADB_BUSRESET 0x00
> +#define ADB_FLUSH 0x01
> +#define ADB_WRITEREG 0x08
> +#define ADB_READREG 0x0c
> +
> +/* ADB device commands */
> +
> +#define ADB_CMD_SELF_TEST 0xff
> +#define ADB_CMD_CHANGE_ID 0xfe
> +#define ADB_CMD_CHANGE_ID_AND_ACT 0xfd
> +#define ADB_CMD_CHANGE_ID_AND_ENABLE 0x00
> +
> +/* ADB default device IDs (upper 4 bits of ADB command byte) */
> +
> +#define ADB_DEVID_DONGLE 1
> +#define ADB_DEVID_KEYBOARD 2
> +#define ADB_DEVID_MOUSE 3
> +#define ADB_DEVID_TABLET 4
> +#define ADB_DEVID_MODEM 5
> +#define ADB_DEVID_MISC 7
> +
> +extern const VMStateDescription vmstate_adb_device;
> +
> diff --git a/hw/input/adb-kbd.c b/hw/input/adb-kbd.c
> new file mode 100644
> index 0000000000..354f56e41e
> --- /dev/null
> +++ b/hw/input/adb-kbd.c
> @@ -0,0 +1,400 @@
> +/*
> + * QEMU ADB keyboard support
> + *
> + * Copyright (c) 2004 Fabrice Bellard
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> deal
> + * in the Software without restriction, including without limitation the
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +#include "qemu/osdep.h"
> +#include "hw/input/adb.h"
> +#include "ui/input.h"
> +#include "hw/input/adb-keys.h"
> +#include "sysemu/sysemu.h"
> +#include "adb-internal.h"
> +#include "trace.h"
> +
> +#define ADB_KEYBOARD(obj) OBJECT_CHECK(KBDState, (obj), TYPE_ADB_KEYBOARD)
> +
> +typedef struct KBDState {
> + /*< private >*/
> + ADBDevice parent_obj;
> + /*< public >*/
> +
> + uint8_t data[128];
> + int rptr, wptr, count;
> +} KBDState;
> +
> +#define ADB_KEYBOARD_CLASS(class) \
> + OBJECT_CLASS_CHECK(ADBKeyboardClass, (class), TYPE_ADB_KEYBOARD)
> +#define ADB_KEYBOARD_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(ADBKeyboardClass, (obj), TYPE_ADB_KEYBOARD)
> +
> +typedef struct ADBKeyboardClass {
> + /*< private >*/
> + ADBDeviceClass parent_class;
> + /*< public >*/
> +
> + DeviceRealize parent_realize;
> +} ADBKeyboardClass;
> +
> +/* The adb keyboard doesn't have every key imaginable */
> +#define NO_KEY 0xff
> +
> +int qcode_to_adb_keycode[] = {
> + /* Make sure future additions are automatically set to NO_KEY */
> + [0 ... 0xff] = NO_KEY,
> +
> + [Q_KEY_CODE_SHIFT] = ADB_KEY_LEFT_SHIFT,
> + [Q_KEY_CODE_SHIFT_R] = ADB_KEY_RIGHT_SHIFT,
> + [Q_KEY_CODE_ALT] = ADB_KEY_LEFT_OPTION,
> + [Q_KEY_CODE_ALT_R] = ADB_KEY_RIGHT_OPTION,
> + [Q_KEY_CODE_CTRL] = ADB_KEY_LEFT_CONTROL,
> + [Q_KEY_CODE_CTRL_R] = ADB_KEY_RIGHT_CONTROL,
> + [Q_KEY_CODE_META_L] = ADB_KEY_COMMAND,
> + [Q_KEY_CODE_META_R] = ADB_KEY_COMMAND,
> + [Q_KEY_CODE_SPC] = ADB_KEY_SPACEBAR,
> +
> + [Q_KEY_CODE_ESC] = ADB_KEY_ESC,
> + [Q_KEY_CODE_1] = ADB_KEY_1,
> + [Q_KEY_CODE_2] = ADB_KEY_2,
> + [Q_KEY_CODE_3] = ADB_KEY_3,
> + [Q_KEY_CODE_4] = ADB_KEY_4,
> + [Q_KEY_CODE_5] = ADB_KEY_5,
> + [Q_KEY_CODE_6] = ADB_KEY_6,
> + [Q_KEY_CODE_7] = ADB_KEY_7,
> + [Q_KEY_CODE_8] = ADB_KEY_8,
> + [Q_KEY_CODE_9] = ADB_KEY_9,
> + [Q_KEY_CODE_0] = ADB_KEY_0,
> + [Q_KEY_CODE_MINUS] = ADB_KEY_MINUS,
> + [Q_KEY_CODE_EQUAL] = ADB_KEY_EQUAL,
> + [Q_KEY_CODE_BACKSPACE] = ADB_KEY_DELETE,
> + [Q_KEY_CODE_TAB] = ADB_KEY_TAB,
> + [Q_KEY_CODE_Q] = ADB_KEY_Q,
> + [Q_KEY_CODE_W] = ADB_KEY_W,
> + [Q_KEY_CODE_E] = ADB_KEY_E,
> + [Q_KEY_CODE_R] = ADB_KEY_R,
> + [Q_KEY_CODE_T] = ADB_KEY_T,
> + [Q_KEY_CODE_Y] = ADB_KEY_Y,
> + [Q_KEY_CODE_U] = ADB_KEY_U,
> + [Q_KEY_CODE_I] = ADB_KEY_I,
> + [Q_KEY_CODE_O] = ADB_KEY_O,
> + [Q_KEY_CODE_P] = ADB_KEY_P,
> + [Q_KEY_CODE_BRACKET_LEFT] = ADB_KEY_LEFT_BRACKET,
> + [Q_KEY_CODE_BRACKET_RIGHT] = ADB_KEY_RIGHT_BRACKET,
> + [Q_KEY_CODE_RET] = ADB_KEY_RETURN,
> + [Q_KEY_CODE_A] = ADB_KEY_A,
> + [Q_KEY_CODE_S] = ADB_KEY_S,
> + [Q_KEY_CODE_D] = ADB_KEY_D,
> + [Q_KEY_CODE_F] = ADB_KEY_F,
> + [Q_KEY_CODE_G] = ADB_KEY_G,
> + [Q_KEY_CODE_H] = ADB_KEY_H,
> + [Q_KEY_CODE_J] = ADB_KEY_J,
> + [Q_KEY_CODE_K] = ADB_KEY_K,
> + [Q_KEY_CODE_L] = ADB_KEY_L,
> + [Q_KEY_CODE_SEMICOLON] = ADB_KEY_SEMICOLON,
> + [Q_KEY_CODE_APOSTROPHE] = ADB_KEY_APOSTROPHE,
> + [Q_KEY_CODE_GRAVE_ACCENT] = ADB_KEY_GRAVE_ACCENT,
> + [Q_KEY_CODE_BACKSLASH] = ADB_KEY_BACKSLASH,
> + [Q_KEY_CODE_Z] = ADB_KEY_Z,
> + [Q_KEY_CODE_X] = ADB_KEY_X,
> + [Q_KEY_CODE_C] = ADB_KEY_C,
> + [Q_KEY_CODE_V] = ADB_KEY_V,
> + [Q_KEY_CODE_B] = ADB_KEY_B,
> + [Q_KEY_CODE_N] = ADB_KEY_N,
> + [Q_KEY_CODE_M] = ADB_KEY_M,
> + [Q_KEY_CODE_COMMA] = ADB_KEY_COMMA,
> + [Q_KEY_CODE_DOT] = ADB_KEY_PERIOD,
> + [Q_KEY_CODE_SLASH] = ADB_KEY_FORWARD_SLASH,
> + [Q_KEY_CODE_ASTERISK] = ADB_KEY_KP_MULTIPLY,
> + [Q_KEY_CODE_CAPS_LOCK] = ADB_KEY_CAPS_LOCK,
> +
> + [Q_KEY_CODE_F1] = ADB_KEY_F1,
> + [Q_KEY_CODE_F2] = ADB_KEY_F2,
> + [Q_KEY_CODE_F3] = ADB_KEY_F3,
> + [Q_KEY_CODE_F4] = ADB_KEY_F4,
> + [Q_KEY_CODE_F5] = ADB_KEY_F5,
> + [Q_KEY_CODE_F6] = ADB_KEY_F6,
> + [Q_KEY_CODE_F7] = ADB_KEY_F7,
> + [Q_KEY_CODE_F8] = ADB_KEY_F8,
> + [Q_KEY_CODE_F9] = ADB_KEY_F9,
> + [Q_KEY_CODE_F10] = ADB_KEY_F10,
> + [Q_KEY_CODE_F11] = ADB_KEY_F11,
> + [Q_KEY_CODE_F12] = ADB_KEY_F12,
> + [Q_KEY_CODE_PRINT] = ADB_KEY_F13,
> + [Q_KEY_CODE_SYSRQ] = ADB_KEY_F13,
> + [Q_KEY_CODE_SCROLL_LOCK] = ADB_KEY_F14,
> + [Q_KEY_CODE_PAUSE] = ADB_KEY_F15,
> +
> + [Q_KEY_CODE_NUM_LOCK] = ADB_KEY_KP_CLEAR,
> + [Q_KEY_CODE_KP_EQUALS] = ADB_KEY_KP_EQUAL,
> + [Q_KEY_CODE_KP_DIVIDE] = ADB_KEY_KP_DIVIDE,
> + [Q_KEY_CODE_KP_MULTIPLY] = ADB_KEY_KP_MULTIPLY,
> + [Q_KEY_CODE_KP_SUBTRACT] = ADB_KEY_KP_SUBTRACT,
> + [Q_KEY_CODE_KP_ADD] = ADB_KEY_KP_PLUS,
> + [Q_KEY_CODE_KP_ENTER] = ADB_KEY_KP_ENTER,
> + [Q_KEY_CODE_KP_DECIMAL] = ADB_KEY_KP_PERIOD,
> + [Q_KEY_CODE_KP_0] = ADB_KEY_KP_0,
> + [Q_KEY_CODE_KP_1] = ADB_KEY_KP_1,
> + [Q_KEY_CODE_KP_2] = ADB_KEY_KP_2,
> + [Q_KEY_CODE_KP_3] = ADB_KEY_KP_3,
> + [Q_KEY_CODE_KP_4] = ADB_KEY_KP_4,
> + [Q_KEY_CODE_KP_5] = ADB_KEY_KP_5,
> + [Q_KEY_CODE_KP_6] = ADB_KEY_KP_6,
> + [Q_KEY_CODE_KP_7] = ADB_KEY_KP_7,
> + [Q_KEY_CODE_KP_8] = ADB_KEY_KP_8,
> + [Q_KEY_CODE_KP_9] = ADB_KEY_KP_9,
> +
> + [Q_KEY_CODE_UP] = ADB_KEY_UP,
> + [Q_KEY_CODE_DOWN] = ADB_KEY_DOWN,
> + [Q_KEY_CODE_LEFT] = ADB_KEY_LEFT,
> + [Q_KEY_CODE_RIGHT] = ADB_KEY_RIGHT,
> +
> + [Q_KEY_CODE_HELP] = ADB_KEY_HELP,
> + [Q_KEY_CODE_INSERT] = ADB_KEY_HELP,
> + [Q_KEY_CODE_DELETE] = ADB_KEY_FORWARD_DELETE,
> + [Q_KEY_CODE_HOME] = ADB_KEY_HOME,
> + [Q_KEY_CODE_END] = ADB_KEY_END,
> + [Q_KEY_CODE_PGUP] = ADB_KEY_PAGE_UP,
> + [Q_KEY_CODE_PGDN] = ADB_KEY_PAGE_DOWN,
> +
> + [Q_KEY_CODE_POWER] = ADB_KEY_POWER
> +};
> +
> +static void adb_kbd_put_keycode(void *opaque, int keycode)
> +{
> + KBDState *s = opaque;
> +
> + if (s->count < sizeof(s->data)) {
> + s->data[s->wptr] = keycode;
> + if (++s->wptr == sizeof(s->data)) {
> + s->wptr = 0;
> + }
> + s->count++;
> + }
> +}
> +
> +static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
> +{
> + KBDState *s = ADB_KEYBOARD(d);
> + int keycode;
> + int olen;
> +
> + olen = 0;
> + if (s->count == 0) {
> + return 0;
> + }
> + keycode = s->data[s->rptr];
> + s->rptr++;
> + if (s->rptr == sizeof(s->data)) {
> + s->rptr = 0;
> + }
> + s->count--;
> + /*
> + * The power key is the only two byte value key, so it is a special case.
> + * Since 0x7f is not a used keycode for ADB we overload it to indicate
> the
> + * power button when we're storing keycodes in our internal buffer, and
> + * expand it out to two bytes when we send to the guest.
> + */
> + if (keycode == 0x7f) {
> + obuf[0] = 0x7f;
> + obuf[1] = 0x7f;
> + olen = 2;
> + } else {
> + obuf[0] = keycode;
> + /* NOTE: the power key key-up is the two byte sequence 0xff 0xff;
> + * otherwise we could in theory send a second keycode in the second
> + * byte, but choose not to bother.
> + */
> + obuf[1] = 0xff;
> + olen = 2;
> + }
> +
> + return olen;
> +}
> +
> +static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
> + const uint8_t *buf, int len)
> +{
> + KBDState *s = ADB_KEYBOARD(d);
> + int cmd, reg, olen;
> +
> + if ((buf[0] & 0x0f) == ADB_FLUSH) {
> + /* flush keyboard fifo */
> + s->wptr = s->rptr = s->count = 0;
> + return 0;
> + }
> +
> + cmd = buf[0] & 0xc;
> + reg = buf[0] & 0x3;
> + olen = 0;
> + switch (cmd) {
> + case ADB_WRITEREG:
> + trace_adb_kbd_writereg(reg, buf[1]);
> + switch (reg) {
> + case 2:
> + /* LED status */
> + break;
> + case 3:
> + switch (buf[2]) {
> + case ADB_CMD_SELF_TEST:
> + break;
> + case ADB_CMD_CHANGE_ID:
> + case ADB_CMD_CHANGE_ID_AND_ACT:
> + case ADB_CMD_CHANGE_ID_AND_ENABLE:
> + d->devaddr = buf[1] & 0xf;
> + break;
> + default:
> + d->devaddr = buf[1] & 0xf;
> + /* we support handlers:
> + * 1: Apple Standard Keyboard
> + * 2: Apple Extended Keyboard (LShift = RShift)
> + * 3: Apple Extended Keyboard (LShift != RShift)
> + */
> + if (buf[2] == 1 || buf[2] == 2 || buf[2] == 3) {
> + d->handler = buf[2];
> + }
> + break;
> + }
> + }
> + break;
> + case ADB_READREG:
> + switch (reg) {
> + case 0:
> + olen = adb_kbd_poll(d, obuf);
> + break;
> + case 1:
> + break;
> + case 2:
> + obuf[0] = 0x00; /* XXX: check this */
> + obuf[1] = 0x07; /* led status */
> + olen = 2;
> + break;
> + case 3:
> + obuf[0] = d->handler;
> + obuf[1] = d->devaddr;
> + olen = 2;
> + break;
> + }
> + trace_adb_kbd_readreg(reg, obuf[0], obuf[1]);
> + break;
> + }
> + return olen;
> +}
> +
> +/* This is where keyboard events enter this file */
> +static void adb_keyboard_event(DeviceState *dev, QemuConsole *src,
> + InputEvent *evt)
> +{
> + KBDState *s = (KBDState *)dev;
> + int qcode, keycode;
> +
> + qcode = qemu_input_key_value_to_qcode(evt->u.key.data->key);
> + if (qcode >= ARRAY_SIZE(qcode_to_adb_keycode)) {
> + return;
> + }
> + /* FIXME: take handler into account when translating qcode */
> + keycode = qcode_to_adb_keycode[qcode];
> + if (keycode == NO_KEY) { /* We don't want to send this to the guest */
> + trace_adb_kbd_no_key();
> + return;
> + }
> + if (evt->u.key.data->down == false) { /* if key release event */
> + keycode = keycode | 0x80; /* create keyboard break code */
> + }
> +
> + adb_kbd_put_keycode(s, keycode);
> +}
> +
> +static const VMStateDescription vmstate_adb_kbd = {
> + .name = "adb_kbd",
> + .version_id = 2,
> + .minimum_version_id = 2,
> + .fields = (VMStateField[]) {
> + VMSTATE_STRUCT(parent_obj, KBDState, 0, vmstate_adb_device,
> ADBDevice),
> + VMSTATE_BUFFER(data, KBDState),
> + VMSTATE_INT32(rptr, KBDState),
> + VMSTATE_INT32(wptr, KBDState),
> + VMSTATE_INT32(count, KBDState),
> + VMSTATE_END_OF_LIST()
> + }
> +};
> +
> +static void adb_kbd_reset(DeviceState *dev)
> +{
> + ADBDevice *d = ADB_DEVICE(dev);
> + KBDState *s = ADB_KEYBOARD(dev);
> +
> + d->handler = 1;
> + d->devaddr = ADB_DEVID_KEYBOARD;
> + memset(s->data, 0, sizeof(s->data));
> + s->rptr = 0;
> + s->wptr = 0;
> + s->count = 0;
> +}
> +
> +static QemuInputHandler adb_keyboard_handler = {
> + .name = "QEMU ADB Keyboard",
> + .mask = INPUT_EVENT_MASK_KEY,
> + .event = adb_keyboard_event,
> +};
> +
> +static void adb_kbd_realizefn(DeviceState *dev, Error **errp)
> +{
> + ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev);
> + akc->parent_realize(dev, errp);
> + qemu_input_handler_register(dev, &adb_keyboard_handler);
> +}
> +
> +static void adb_kbd_initfn(Object *obj)
> +{
> + ADBDevice *d = ADB_DEVICE(obj);
> +
> + d->devaddr = ADB_DEVID_KEYBOARD;
> +}
> +
> +static void adb_kbd_class_init(ObjectClass *oc, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(oc);
> + ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
> + ADBKeyboardClass *akc = ADB_KEYBOARD_CLASS(oc);
> +
> + 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;
> + dc->vmsd = &vmstate_adb_kbd;
> +}
> +
> +static const TypeInfo adb_kbd_type_info = {
> + .name = TYPE_ADB_KEYBOARD,
> + .parent = TYPE_ADB_DEVICE,
> + .instance_size = sizeof(KBDState),
> + .instance_init = adb_kbd_initfn,
> + .class_init = adb_kbd_class_init,
> + .class_size = sizeof(ADBKeyboardClass),
> +};
> +
> +static void adb_kbd_register_types(void)
> +{
> + type_register_static(&adb_kbd_type_info);
> +}
> +
> +type_init(adb_kbd_register_types)
> diff --git a/hw/input/adb-mouse.c b/hw/input/adb-mouse.c
> new file mode 100644
> index 0000000000..c9004233b8
> --- /dev/null
> +++ b/hw/input/adb-mouse.c
> @@ -0,0 +1,254 @@
> +/*
> + * QEMU ADB mouse support
> + *
> + * Copyright (c) 2004 Fabrice Bellard
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> deal
> + * in the Software without restriction, including without limitation the
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +#include "qemu/osdep.h"
> +#include "ui/console.h"
> +#include "hw/input/adb.h"
> +#include "adb-internal.h"
> +#include "trace.h"
> +
> +#define ADB_MOUSE(obj) OBJECT_CHECK(MouseState, (obj), TYPE_ADB_MOUSE)
> +
> +typedef struct MouseState {
> + /*< public >*/
> + ADBDevice parent_obj;
> + /*< private >*/
> +
> + int buttons_state, last_buttons_state;
> + int dx, dy, dz;
> +} MouseState;
> +
> +#define ADB_MOUSE_CLASS(class) \
> + OBJECT_CLASS_CHECK(ADBMouseClass, (class), TYPE_ADB_MOUSE)
> +#define ADB_MOUSE_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(ADBMouseClass, (obj), TYPE_ADB_MOUSE)
> +
> +typedef struct ADBMouseClass {
> + /*< public >*/
> + ADBDeviceClass parent_class;
> + /*< private >*/
> +
> + DeviceRealize parent_realize;
> +} ADBMouseClass;
> +
> +static void adb_mouse_event(void *opaque,
> + int dx1, int dy1, int dz1, int buttons_state)
> +{
> + MouseState *s = opaque;
> +
> + s->dx += dx1;
> + s->dy += dy1;
> + s->dz += dz1;
> + s->buttons_state = buttons_state;
> +}
> +
> +
> +static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
> +{
> + MouseState *s = ADB_MOUSE(d);
> + int dx, dy;
> +
> + if (s->last_buttons_state == s->buttons_state &&
> + s->dx == 0 && s->dy == 0) {
> + return 0;
> + }
> +
> + dx = s->dx;
> + if (dx < -63) {
> + dx = -63;
> + } else if (dx > 63) {
> + dx = 63;
> + }
> +
> + dy = s->dy;
> + if (dy < -63) {
> + dy = -63;
> + } else if (dy > 63) {
> + dy = 63;
> + }
> +
> + s->dx -= dx;
> + s->dy -= dy;
> + s->last_buttons_state = s->buttons_state;
> +
> + dx &= 0x7f;
> + dy &= 0x7f;
> +
> + if (!(s->buttons_state & MOUSE_EVENT_LBUTTON)) {
> + dy |= 0x80;
> + }
> + if (!(s->buttons_state & MOUSE_EVENT_RBUTTON)) {
> + dx |= 0x80;
> + }
> +
> + obuf[0] = dy;
> + obuf[1] = dx;
> + return 2;
> +}
> +
> +static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
> + const uint8_t *buf, int len)
> +{
> + MouseState *s = ADB_MOUSE(d);
> + int cmd, reg, olen;
> +
> + if ((buf[0] & 0x0f) == ADB_FLUSH) {
> + /* flush mouse fifo */
> + s->buttons_state = s->last_buttons_state;
> + s->dx = 0;
> + s->dy = 0;
> + s->dz = 0;
> + return 0;
> + }
> +
> + cmd = buf[0] & 0xc;
> + reg = buf[0] & 0x3;
> + olen = 0;
> + switch (cmd) {
> + case ADB_WRITEREG:
> + trace_adb_mouse_writereg(reg, buf[1]);
> + switch (reg) {
> + case 2:
> + break;
> + case 3:
> + switch (buf[2]) {
> + case ADB_CMD_SELF_TEST:
> + break;
> + case ADB_CMD_CHANGE_ID:
> + case ADB_CMD_CHANGE_ID_AND_ACT:
> + case ADB_CMD_CHANGE_ID_AND_ENABLE:
> + d->devaddr = buf[1] & 0xf;
> + break;
> + default:
> + d->devaddr = buf[1] & 0xf;
> + /* we support handlers:
> + * 0x01: Classic Apple Mouse Protocol / 100 cpi operations
> + * 0x02: Classic Apple Mouse Protocol / 200 cpi operations
> + * we don't support handlers (at least):
> + * 0x03: Mouse systems A3 trackball
> + * 0x04: Extended Apple Mouse Protocol
> + * 0x2f: Microspeed mouse
> + * 0x42: Macally
> + * 0x5f: Microspeed mouse
> + * 0x66: Microspeed mouse
> + */
> + if (buf[2] == 1 || buf[2] == 2) {
> + d->handler = buf[2];
> + }
> + break;
> + }
> + }
> + break;
> + case ADB_READREG:
> + switch (reg) {
> + case 0:
> + olen = adb_mouse_poll(d, obuf);
> + break;
> + case 1:
> + break;
> + case 3:
> + obuf[0] = d->handler;
> + obuf[1] = d->devaddr;
> + olen = 2;
> + break;
> + }
> + trace_adb_mouse_readreg(reg, obuf[0], obuf[1]);
> + break;
> + }
> + return olen;
> +}
> +
> +static void adb_mouse_reset(DeviceState *dev)
> +{
> + ADBDevice *d = ADB_DEVICE(dev);
> + MouseState *s = ADB_MOUSE(dev);
> +
> + d->handler = 2;
> + d->devaddr = ADB_DEVID_MOUSE;
> + s->last_buttons_state = s->buttons_state = 0;
> + s->dx = s->dy = s->dz = 0;
> +}
> +
> +static const VMStateDescription vmstate_adb_mouse = {
> + .name = "adb_mouse",
> + .version_id = 2,
> + .minimum_version_id = 2,
> + .fields = (VMStateField[]) {
> + VMSTATE_STRUCT(parent_obj, MouseState, 0, vmstate_adb_device,
> + ADBDevice),
> + VMSTATE_INT32(buttons_state, MouseState),
> + VMSTATE_INT32(last_buttons_state, MouseState),
> + VMSTATE_INT32(dx, MouseState),
> + VMSTATE_INT32(dy, MouseState),
> + VMSTATE_INT32(dz, MouseState),
> + VMSTATE_END_OF_LIST()
> + }
> +};
> +
> +static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
> +{
> + MouseState *s = ADB_MOUSE(dev);
> + ADBMouseClass *amc = ADB_MOUSE_GET_CLASS(dev);
> +
> + amc->parent_realize(dev, errp);
> +
> + qemu_add_mouse_event_handler(adb_mouse_event, s, 0, "QEMU ADB Mouse");
> +}
> +
> +static void adb_mouse_initfn(Object *obj)
> +{
> + ADBDevice *d = ADB_DEVICE(obj);
> +
> + d->devaddr = ADB_DEVID_MOUSE;
> +}
> +
> +static void adb_mouse_class_init(ObjectClass *oc, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(oc);
> + ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
> + ADBMouseClass *amc = ADB_MOUSE_CLASS(oc);
> +
> + 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;
> + dc->vmsd = &vmstate_adb_mouse;
> +}
> +
> +static const TypeInfo adb_mouse_type_info = {
> + .name = TYPE_ADB_MOUSE,
> + .parent = TYPE_ADB_DEVICE,
> + .instance_size = sizeof(MouseState),
> + .instance_init = adb_mouse_initfn,
> + .class_init = adb_mouse_class_init,
> + .class_size = sizeof(ADBMouseClass),
> +};
> +
> +static void adb_mouse_register_types(void)
> +{
> + type_register_static(&adb_mouse_type_info);
> +}
> +
> +type_init(adb_mouse_register_types)
> diff --git a/hw/input/adb.c b/hw/input/adb.c
> index 924a3f9fd5..23ae6f0d75 100644
> --- a/hw/input/adb.c
> +++ b/hw/input/adb.c
> @@ -22,49 +22,12 @@
> * THE SOFTWARE.
> */
> #include "qemu/osdep.h"
> -#include "hw/hw.h"
> #include "hw/input/adb.h"
> -#include "hw/input/adb-keys.h"
> -#include "ui/console.h"
> -#include "ui/input.h"
> -#include "sysemu/sysemu.h"
> -
> -/* debug ADB */
> -//#define DEBUG_ADB
> -
> -#ifdef DEBUG_ADB
> -#define ADB_DPRINTF(fmt, ...) \
> -do { printf("ADB: " fmt , ## __VA_ARGS__); } while (0)
> -#else
> -#define ADB_DPRINTF(fmt, ...)
> -#endif
> -
> -/* ADB commands */
> -#define ADB_BUSRESET 0x00
> -#define ADB_FLUSH 0x01
> -#define ADB_WRITEREG 0x08
> -#define ADB_READREG 0x0c
> -
> -/* ADB device commands */
> -#define ADB_CMD_SELF_TEST 0xff
> -#define ADB_CMD_CHANGE_ID 0xfe
> -#define ADB_CMD_CHANGE_ID_AND_ACT 0xfd
> -#define ADB_CMD_CHANGE_ID_AND_ENABLE 0x00
> -
> -/* ADB default device IDs (upper 4 bits of ADB command byte) */
> -#define ADB_DEVID_DONGLE 1
> -#define ADB_DEVID_KEYBOARD 2
> -#define ADB_DEVID_MOUSE 3
> -#define ADB_DEVID_TABLET 4
> -#define ADB_DEVID_MODEM 5
> -#define ADB_DEVID_MISC 7
> +#include "adb-internal.h"
>
> /* error codes */
> #define ADB_RET_NOTPRESENT (-2)
>
> -/* The adb keyboard doesn't have every key imaginable */
> -#define NO_KEY 0xff
> -
> static void adb_device_reset(ADBDevice *d)
> {
> qdev_reset_all(DEVICE(d));
> @@ -127,7 +90,7 @@ static const TypeInfo adb_bus_type_info = {
> .instance_size = sizeof(ADBBusState),
> };
>
> -static const VMStateDescription vmstate_adb_device = {
> +const VMStateDescription vmstate_adb_device = {
> .name = "adb_device",
> .version_id = 0,
> .minimum_version_id = 0,
> @@ -166,591 +129,10 @@ static const TypeInfo adb_device_type_info = {
> .class_init = adb_device_class_init,
> };
>
> -/***************************************************************/
> -/* Keyboard ADB device */
> -
> -#define ADB_KEYBOARD(obj) OBJECT_CHECK(KBDState, (obj), TYPE_ADB_KEYBOARD)
> -
> -typedef struct KBDState {
> - /*< private >*/
> - ADBDevice parent_obj;
> - /*< public >*/
> -
> - uint8_t data[128];
> - int rptr, wptr, count;
> -} KBDState;
> -
> -#define ADB_KEYBOARD_CLASS(class) \
> - OBJECT_CLASS_CHECK(ADBKeyboardClass, (class), TYPE_ADB_KEYBOARD)
> -#define ADB_KEYBOARD_GET_CLASS(obj) \
> - OBJECT_GET_CLASS(ADBKeyboardClass, (obj), TYPE_ADB_KEYBOARD)
> -
> -typedef struct ADBKeyboardClass {
> - /*< private >*/
> - ADBDeviceClass parent_class;
> - /*< public >*/
> -
> - DeviceRealize parent_realize;
> -} ADBKeyboardClass;
> -
> -int qcode_to_adb_keycode[] = {
> - /* Make sure future additions are automatically set to NO_KEY */
> - [0 ... 0xff] = NO_KEY,
> -
> - [Q_KEY_CODE_SHIFT] = ADB_KEY_LEFT_SHIFT,
> - [Q_KEY_CODE_SHIFT_R] = ADB_KEY_RIGHT_SHIFT,
> - [Q_KEY_CODE_ALT] = ADB_KEY_LEFT_OPTION,
> - [Q_KEY_CODE_ALT_R] = ADB_KEY_RIGHT_OPTION,
> - [Q_KEY_CODE_CTRL] = ADB_KEY_LEFT_CONTROL,
> - [Q_KEY_CODE_CTRL_R] = ADB_KEY_RIGHT_CONTROL,
> - [Q_KEY_CODE_META_L] = ADB_KEY_COMMAND,
> - [Q_KEY_CODE_META_R] = ADB_KEY_COMMAND,
> - [Q_KEY_CODE_SPC] = ADB_KEY_SPACEBAR,
> -
> - [Q_KEY_CODE_ESC] = ADB_KEY_ESC,
> - [Q_KEY_CODE_1] = ADB_KEY_1,
> - [Q_KEY_CODE_2] = ADB_KEY_2,
> - [Q_KEY_CODE_3] = ADB_KEY_3,
> - [Q_KEY_CODE_4] = ADB_KEY_4,
> - [Q_KEY_CODE_5] = ADB_KEY_5,
> - [Q_KEY_CODE_6] = ADB_KEY_6,
> - [Q_KEY_CODE_7] = ADB_KEY_7,
> - [Q_KEY_CODE_8] = ADB_KEY_8,
> - [Q_KEY_CODE_9] = ADB_KEY_9,
> - [Q_KEY_CODE_0] = ADB_KEY_0,
> - [Q_KEY_CODE_MINUS] = ADB_KEY_MINUS,
> - [Q_KEY_CODE_EQUAL] = ADB_KEY_EQUAL,
> - [Q_KEY_CODE_BACKSPACE] = ADB_KEY_DELETE,
> - [Q_KEY_CODE_TAB] = ADB_KEY_TAB,
> - [Q_KEY_CODE_Q] = ADB_KEY_Q,
> - [Q_KEY_CODE_W] = ADB_KEY_W,
> - [Q_KEY_CODE_E] = ADB_KEY_E,
> - [Q_KEY_CODE_R] = ADB_KEY_R,
> - [Q_KEY_CODE_T] = ADB_KEY_T,
> - [Q_KEY_CODE_Y] = ADB_KEY_Y,
> - [Q_KEY_CODE_U] = ADB_KEY_U,
> - [Q_KEY_CODE_I] = ADB_KEY_I,
> - [Q_KEY_CODE_O] = ADB_KEY_O,
> - [Q_KEY_CODE_P] = ADB_KEY_P,
> - [Q_KEY_CODE_BRACKET_LEFT] = ADB_KEY_LEFT_BRACKET,
> - [Q_KEY_CODE_BRACKET_RIGHT] = ADB_KEY_RIGHT_BRACKET,
> - [Q_KEY_CODE_RET] = ADB_KEY_RETURN,
> - [Q_KEY_CODE_A] = ADB_KEY_A,
> - [Q_KEY_CODE_S] = ADB_KEY_S,
> - [Q_KEY_CODE_D] = ADB_KEY_D,
> - [Q_KEY_CODE_F] = ADB_KEY_F,
> - [Q_KEY_CODE_G] = ADB_KEY_G,
> - [Q_KEY_CODE_H] = ADB_KEY_H,
> - [Q_KEY_CODE_J] = ADB_KEY_J,
> - [Q_KEY_CODE_K] = ADB_KEY_K,
> - [Q_KEY_CODE_L] = ADB_KEY_L,
> - [Q_KEY_CODE_SEMICOLON] = ADB_KEY_SEMICOLON,
> - [Q_KEY_CODE_APOSTROPHE] = ADB_KEY_APOSTROPHE,
> - [Q_KEY_CODE_GRAVE_ACCENT] = ADB_KEY_GRAVE_ACCENT,
> - [Q_KEY_CODE_BACKSLASH] = ADB_KEY_BACKSLASH,
> - [Q_KEY_CODE_Z] = ADB_KEY_Z,
> - [Q_KEY_CODE_X] = ADB_KEY_X,
> - [Q_KEY_CODE_C] = ADB_KEY_C,
> - [Q_KEY_CODE_V] = ADB_KEY_V,
> - [Q_KEY_CODE_B] = ADB_KEY_B,
> - [Q_KEY_CODE_N] = ADB_KEY_N,
> - [Q_KEY_CODE_M] = ADB_KEY_M,
> - [Q_KEY_CODE_COMMA] = ADB_KEY_COMMA,
> - [Q_KEY_CODE_DOT] = ADB_KEY_PERIOD,
> - [Q_KEY_CODE_SLASH] = ADB_KEY_FORWARD_SLASH,
> - [Q_KEY_CODE_ASTERISK] = ADB_KEY_KP_MULTIPLY,
> - [Q_KEY_CODE_CAPS_LOCK] = ADB_KEY_CAPS_LOCK,
> -
> - [Q_KEY_CODE_F1] = ADB_KEY_F1,
> - [Q_KEY_CODE_F2] = ADB_KEY_F2,
> - [Q_KEY_CODE_F3] = ADB_KEY_F3,
> - [Q_KEY_CODE_F4] = ADB_KEY_F4,
> - [Q_KEY_CODE_F5] = ADB_KEY_F5,
> - [Q_KEY_CODE_F6] = ADB_KEY_F6,
> - [Q_KEY_CODE_F7] = ADB_KEY_F7,
> - [Q_KEY_CODE_F8] = ADB_KEY_F8,
> - [Q_KEY_CODE_F9] = ADB_KEY_F9,
> - [Q_KEY_CODE_F10] = ADB_KEY_F10,
> - [Q_KEY_CODE_F11] = ADB_KEY_F11,
> - [Q_KEY_CODE_F12] = ADB_KEY_F12,
> - [Q_KEY_CODE_PRINT] = ADB_KEY_F13,
> - [Q_KEY_CODE_SYSRQ] = ADB_KEY_F13,
> - [Q_KEY_CODE_SCROLL_LOCK] = ADB_KEY_F14,
> - [Q_KEY_CODE_PAUSE] = ADB_KEY_F15,
> -
> - [Q_KEY_CODE_NUM_LOCK] = ADB_KEY_KP_CLEAR,
> - [Q_KEY_CODE_KP_EQUALS] = ADB_KEY_KP_EQUAL,
> - [Q_KEY_CODE_KP_DIVIDE] = ADB_KEY_KP_DIVIDE,
> - [Q_KEY_CODE_KP_MULTIPLY] = ADB_KEY_KP_MULTIPLY,
> - [Q_KEY_CODE_KP_SUBTRACT] = ADB_KEY_KP_SUBTRACT,
> - [Q_KEY_CODE_KP_ADD] = ADB_KEY_KP_PLUS,
> - [Q_KEY_CODE_KP_ENTER] = ADB_KEY_KP_ENTER,
> - [Q_KEY_CODE_KP_DECIMAL] = ADB_KEY_KP_PERIOD,
> - [Q_KEY_CODE_KP_0] = ADB_KEY_KP_0,
> - [Q_KEY_CODE_KP_1] = ADB_KEY_KP_1,
> - [Q_KEY_CODE_KP_2] = ADB_KEY_KP_2,
> - [Q_KEY_CODE_KP_3] = ADB_KEY_KP_3,
> - [Q_KEY_CODE_KP_4] = ADB_KEY_KP_4,
> - [Q_KEY_CODE_KP_5] = ADB_KEY_KP_5,
> - [Q_KEY_CODE_KP_6] = ADB_KEY_KP_6,
> - [Q_KEY_CODE_KP_7] = ADB_KEY_KP_7,
> - [Q_KEY_CODE_KP_8] = ADB_KEY_KP_8,
> - [Q_KEY_CODE_KP_9] = ADB_KEY_KP_9,
> -
> - [Q_KEY_CODE_UP] = ADB_KEY_UP,
> - [Q_KEY_CODE_DOWN] = ADB_KEY_DOWN,
> - [Q_KEY_CODE_LEFT] = ADB_KEY_LEFT,
> - [Q_KEY_CODE_RIGHT] = ADB_KEY_RIGHT,
> -
> - [Q_KEY_CODE_HELP] = ADB_KEY_HELP,
> - [Q_KEY_CODE_INSERT] = ADB_KEY_HELP,
> - [Q_KEY_CODE_DELETE] = ADB_KEY_FORWARD_DELETE,
> - [Q_KEY_CODE_HOME] = ADB_KEY_HOME,
> - [Q_KEY_CODE_END] = ADB_KEY_END,
> - [Q_KEY_CODE_PGUP] = ADB_KEY_PAGE_UP,
> - [Q_KEY_CODE_PGDN] = ADB_KEY_PAGE_DOWN,
> -
> - [Q_KEY_CODE_POWER] = ADB_KEY_POWER
> -};
> -
> -static void adb_kbd_put_keycode(void *opaque, int keycode)
> -{
> - KBDState *s = opaque;
> -
> - if (s->count < sizeof(s->data)) {
> - s->data[s->wptr] = keycode;
> - if (++s->wptr == sizeof(s->data))
> - s->wptr = 0;
> - s->count++;
> - }
> -}
> -
> -static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
> -{
> - KBDState *s = ADB_KEYBOARD(d);
> - int keycode;
> - int olen;
> -
> - olen = 0;
> - if (s->count == 0) {
> - return 0;
> - }
> - keycode = s->data[s->rptr];
> - s->rptr++;
> - if (s->rptr == sizeof(s->data)) {
> - s->rptr = 0;
> - }
> - s->count--;
> - /*
> - * The power key is the only two byte value key, so it is a special case.
> - * Since 0x7f is not a used keycode for ADB we overload it to indicate
> the
> - * power button when we're storing keycodes in our internal buffer, and
> - * expand it out to two bytes when we send to the guest.
> - */
> - if (keycode == 0x7f) {
> - obuf[0] = 0x7f;
> - obuf[1] = 0x7f;
> - olen = 2;
> - } else {
> - obuf[0] = keycode;
> - /* NOTE: the power key key-up is the two byte sequence 0xff 0xff;
> - * otherwise we could in theory send a second keycode in the second
> - * byte, but choose not to bother.
> - */
> - obuf[1] = 0xff;
> - olen = 2;
> - }
> -
> - return olen;
> -}
> -
> -static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
> - const uint8_t *buf, int len)
> -{
> - KBDState *s = ADB_KEYBOARD(d);
> - int cmd, reg, olen;
> -
> - if ((buf[0] & 0x0f) == ADB_FLUSH) {
> - /* flush keyboard fifo */
> - s->wptr = s->rptr = s->count = 0;
> - return 0;
> - }
> -
> - cmd = buf[0] & 0xc;
> - reg = buf[0] & 0x3;
> - olen = 0;
> - switch(cmd) {
> - case ADB_WRITEREG:
> - switch(reg) {
> - case 2:
> - /* LED status */
> - break;
> - case 3:
> - switch(buf[2]) {
> - case ADB_CMD_SELF_TEST:
> - break;
> - case ADB_CMD_CHANGE_ID:
> - case ADB_CMD_CHANGE_ID_AND_ACT:
> - case ADB_CMD_CHANGE_ID_AND_ENABLE:
> - d->devaddr = buf[1] & 0xf;
> - break;
> - default:
> - d->devaddr = buf[1] & 0xf;
> - /* we support handlers:
> - * 1: Apple Standard Keyboard
> - * 2: Apple Extended Keyboard (LShift = RShift)
> - * 3: Apple Extended Keyboard (LShift != RShift)
> - */
> - if (buf[2] == 1 || buf[2] == 2 || buf[2] == 3) {
> - d->handler = buf[2];
> - }
> - break;
> - }
> - }
> - break;
> - case ADB_READREG:
> - switch(reg) {
> - case 0:
> - olen = adb_kbd_poll(d, obuf);
> - break;
> - case 1:
> - break;
> - case 2:
> - obuf[0] = 0x00; /* XXX: check this */
> - obuf[1] = 0x07; /* led status */
> - olen = 2;
> - break;
> - case 3:
> - obuf[0] = d->handler;
> - obuf[1] = d->devaddr;
> - olen = 2;
> - break;
> - }
> - break;
> - }
> - return olen;
> -}
> -
> -/* This is where keyboard events enter this file */
> -static void adb_keyboard_event(DeviceState *dev, QemuConsole *src,
> - InputEvent *evt)
> -{
> - KBDState *s = (KBDState *)dev;
> - int qcode, keycode;
> -
> - qcode = qemu_input_key_value_to_qcode(evt->u.key.data->key);
> - if (qcode >= ARRAY_SIZE(qcode_to_adb_keycode)) {
> - return;
> - }
> - /* FIXME: take handler into account when translating qcode */
> - keycode = qcode_to_adb_keycode[qcode];
> - if (keycode == NO_KEY) { /* We don't want to send this to the guest */
> - ADB_DPRINTF("Ignoring NO_KEY\n");
> - return;
> - }
> - if (evt->u.key.data->down == false) { /* if key release event */
> - keycode = keycode | 0x80; /* create keyboard break code */
> - }
> -
> - adb_kbd_put_keycode(s, keycode);
> -}
> -
> -static const VMStateDescription vmstate_adb_kbd = {
> - .name = "adb_kbd",
> - .version_id = 2,
> - .minimum_version_id = 2,
> - .fields = (VMStateField[]) {
> - VMSTATE_STRUCT(parent_obj, KBDState, 0, vmstate_adb_device,
> ADBDevice),
> - VMSTATE_BUFFER(data, KBDState),
> - VMSTATE_INT32(rptr, KBDState),
> - VMSTATE_INT32(wptr, KBDState),
> - VMSTATE_INT32(count, KBDState),
> - VMSTATE_END_OF_LIST()
> - }
> -};
> -
> -static void adb_kbd_reset(DeviceState *dev)
> -{
> - ADBDevice *d = ADB_DEVICE(dev);
> - KBDState *s = ADB_KEYBOARD(dev);
> -
> - d->handler = 1;
> - d->devaddr = ADB_DEVID_KEYBOARD;
> - memset(s->data, 0, sizeof(s->data));
> - s->rptr = 0;
> - s->wptr = 0;
> - s->count = 0;
> -}
> -
> -static QemuInputHandler adb_keyboard_handler = {
> - .name = "QEMU ADB Keyboard",
> - .mask = INPUT_EVENT_MASK_KEY,
> - .event = adb_keyboard_event,
> -};
> -
> -static void adb_kbd_realizefn(DeviceState *dev, Error **errp)
> -{
> - ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev);
> - akc->parent_realize(dev, errp);
> - qemu_input_handler_register(dev, &adb_keyboard_handler);
> -}
> -
> -static void adb_kbd_initfn(Object *obj)
> -{
> - ADBDevice *d = ADB_DEVICE(obj);
> -
> - d->devaddr = ADB_DEVID_KEYBOARD;
> -}
> -
> -static void adb_kbd_class_init(ObjectClass *oc, void *data)
> -{
> - DeviceClass *dc = DEVICE_CLASS(oc);
> - ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
> - ADBKeyboardClass *akc = ADB_KEYBOARD_CLASS(oc);
> -
> - 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;
> - dc->vmsd = &vmstate_adb_kbd;
> -}
> -
> -static const TypeInfo adb_kbd_type_info = {
> - .name = TYPE_ADB_KEYBOARD,
> - .parent = TYPE_ADB_DEVICE,
> - .instance_size = sizeof(KBDState),
> - .instance_init = adb_kbd_initfn,
> - .class_init = adb_kbd_class_init,
> - .class_size = sizeof(ADBKeyboardClass),
> -};
> -
> -/***************************************************************/
> -/* Mouse ADB device */
> -
> -#define ADB_MOUSE(obj) OBJECT_CHECK(MouseState, (obj), TYPE_ADB_MOUSE)
> -
> -typedef struct MouseState {
> - /*< public >*/
> - ADBDevice parent_obj;
> - /*< private >*/
> -
> - int buttons_state, last_buttons_state;
> - int dx, dy, dz;
> -} MouseState;
> -
> -#define ADB_MOUSE_CLASS(class) \
> - OBJECT_CLASS_CHECK(ADBMouseClass, (class), TYPE_ADB_MOUSE)
> -#define ADB_MOUSE_GET_CLASS(obj) \
> - OBJECT_GET_CLASS(ADBMouseClass, (obj), TYPE_ADB_MOUSE)
> -
> -typedef struct ADBMouseClass {
> - /*< public >*/
> - ADBDeviceClass parent_class;
> - /*< private >*/
> -
> - DeviceRealize parent_realize;
> -} ADBMouseClass;
> -
> -static void adb_mouse_event(void *opaque,
> - int dx1, int dy1, int dz1, int buttons_state)
> -{
> - MouseState *s = opaque;
> -
> - s->dx += dx1;
> - s->dy += dy1;
> - s->dz += dz1;
> - s->buttons_state = buttons_state;
> -}
> -
> -
> -static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
> -{
> - MouseState *s = ADB_MOUSE(d);
> - int dx, dy;
> -
> - if (s->last_buttons_state == s->buttons_state &&
> - s->dx == 0 && s->dy == 0)
> - return 0;
> -
> - dx = s->dx;
> - if (dx < -63)
> - dx = -63;
> - else if (dx > 63)
> - dx = 63;
> -
> - dy = s->dy;
> - if (dy < -63)
> - dy = -63;
> - else if (dy > 63)
> - dy = 63;
> -
> - s->dx -= dx;
> - s->dy -= dy;
> - s->last_buttons_state = s->buttons_state;
> -
> - dx &= 0x7f;
> - dy &= 0x7f;
> -
> - if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
> - dy |= 0x80;
> - if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
> - dx |= 0x80;
> -
> - obuf[0] = dy;
> - obuf[1] = dx;
> - return 2;
> -}
> -
> -static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
> - const uint8_t *buf, int len)
> -{
> - MouseState *s = ADB_MOUSE(d);
> - int cmd, reg, olen;
> -
> - if ((buf[0] & 0x0f) == ADB_FLUSH) {
> - /* flush mouse fifo */
> - s->buttons_state = s->last_buttons_state;
> - s->dx = 0;
> - s->dy = 0;
> - s->dz = 0;
> - return 0;
> - }
> -
> - cmd = buf[0] & 0xc;
> - reg = buf[0] & 0x3;
> - olen = 0;
> - switch(cmd) {
> - case ADB_WRITEREG:
> - ADB_DPRINTF("write reg %d val 0x%2.2x\n", reg, buf[1]);
> - switch(reg) {
> - case 2:
> - break;
> - case 3:
> - switch(buf[2]) {
> - case ADB_CMD_SELF_TEST:
> - break;
> - case ADB_CMD_CHANGE_ID:
> - case ADB_CMD_CHANGE_ID_AND_ACT:
> - case ADB_CMD_CHANGE_ID_AND_ENABLE:
> - d->devaddr = buf[1] & 0xf;
> - break;
> - default:
> - d->devaddr = buf[1] & 0xf;
> - /* we support handlers:
> - * 0x01: Classic Apple Mouse Protocol / 100 cpi operations
> - * 0x02: Classic Apple Mouse Protocol / 200 cpi operations
> - * we don't support handlers (at least):
> - * 0x03: Mouse systems A3 trackball
> - * 0x04: Extended Apple Mouse Protocol
> - * 0x2f: Microspeed mouse
> - * 0x42: Macally
> - * 0x5f: Microspeed mouse
> - * 0x66: Microspeed mouse
> - */
> - if (buf[2] == 1 || buf[2] == 2) {
> - d->handler = buf[2];
> - }
> - break;
> - }
> - }
> - break;
> - case ADB_READREG:
> - switch(reg) {
> - case 0:
> - olen = adb_mouse_poll(d, obuf);
> - break;
> - case 1:
> - break;
> - case 3:
> - obuf[0] = d->handler;
> - obuf[1] = d->devaddr;
> - olen = 2;
> - break;
> - }
> - ADB_DPRINTF("read reg %d obuf[0] 0x%2.2x obuf[1] 0x%2.2x\n", reg,
> - obuf[0], obuf[1]);
> - break;
> - }
> - return olen;
> -}
> -
> -static void adb_mouse_reset(DeviceState *dev)
> -{
> - ADBDevice *d = ADB_DEVICE(dev);
> - MouseState *s = ADB_MOUSE(dev);
> -
> - d->handler = 2;
> - d->devaddr = ADB_DEVID_MOUSE;
> - s->last_buttons_state = s->buttons_state = 0;
> - s->dx = s->dy = s->dz = 0;
> -}
> -
> -static const VMStateDescription vmstate_adb_mouse = {
> - .name = "adb_mouse",
> - .version_id = 2,
> - .minimum_version_id = 2,
> - .fields = (VMStateField[]) {
> - VMSTATE_STRUCT(parent_obj, MouseState, 0, vmstate_adb_device,
> - ADBDevice),
> - VMSTATE_INT32(buttons_state, MouseState),
> - VMSTATE_INT32(last_buttons_state, MouseState),
> - VMSTATE_INT32(dx, MouseState),
> - VMSTATE_INT32(dy, MouseState),
> - VMSTATE_INT32(dz, MouseState),
> - VMSTATE_END_OF_LIST()
> - }
> -};
> -
> -static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
> -{
> - MouseState *s = ADB_MOUSE(dev);
> - ADBMouseClass *amc = ADB_MOUSE_GET_CLASS(dev);
> -
> - amc->parent_realize(dev, errp);
> -
> - qemu_add_mouse_event_handler(adb_mouse_event, s, 0, "QEMU ADB Mouse");
> -}
> -
> -static void adb_mouse_initfn(Object *obj)
> -{
> - ADBDevice *d = ADB_DEVICE(obj);
> -
> - d->devaddr = ADB_DEVID_MOUSE;
> -}
> -
> -static void adb_mouse_class_init(ObjectClass *oc, void *data)
> -{
> - DeviceClass *dc = DEVICE_CLASS(oc);
> - ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
> - ADBMouseClass *amc = ADB_MOUSE_CLASS(oc);
> -
> - 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;
> - dc->vmsd = &vmstate_adb_mouse;
> -}
> -
> -static const TypeInfo adb_mouse_type_info = {
> - .name = TYPE_ADB_MOUSE,
> - .parent = TYPE_ADB_DEVICE,
> - .instance_size = sizeof(MouseState),
> - .instance_init = adb_mouse_initfn,
> - .class_init = adb_mouse_class_init,
> - .class_size = sizeof(ADBMouseClass),
> -};
> -
> -
> static void adb_register_types(void)
> {
> type_register_static(&adb_bus_type_info);
> type_register_static(&adb_device_type_info);
> - type_register_static(&adb_kbd_type_info);
> - type_register_static(&adb_mouse_type_info);
> }
>
> type_init(adb_register_types)
> diff --git a/hw/input/trace-events b/hw/input/trace-events
> index 88150ef7a6..a8d46cb766 100644
> --- a/hw/input/trace-events
> +++ b/hw/input/trace-events
> @@ -1,5 +1,13 @@
> # See docs/devel/tracing.txt for syntax documentation.
>
> +# hw/input/adb-kbd.c
> +adb_kbd_no_key(void) "Ignoring NO_KEY"
> +adb_kbd_writereg(int reg, uint8_t val) "reg %d val 0x%2.2x"
> +adb_kbd_readreg(int reg, uint8_t val0, uint8_t val1) "reg %d obuf[0] 0x%2.2x
> obuf[1] 0x%2.2x"
Minor aesthetical change:
adb_kbd_readreg(int reg, uint8_t val0, uint8_t val1) "reg %d obuf
[0x%2.2x, 0x%2.2x]"
Anyway, regardless this:
Reviewed-by: Philippe Mathieu-Daudé <address@hidden>
> +# hw/input/adb-mouse.c
> +adb_mouse_writereg(int reg, uint8_t val) "reg %d val 0x%2.2x"
> +adb_mouse_readreg(int reg, uint8_t val0, uint8_t val1) "reg %d obuf[0]
> 0x%2.2x obuf[1] 0x%2.2x"
Ditto:
adb_mouse_readreg(int reg, uint8_t val0, uint8_t val1) "reg %d obuf
[0x%2.2x, 0x%2.2x]"
> +
> # hw/input/ps2.c
> ps2_put_keycode(void *opaque, int keycode) "%p keycode 0x%02x"
> ps2_keyboard_event(void *opaque, int qcode, int down, unsigned int modifier,
> unsigned int modifiers) "%p qcode %d down %d modifier 0x%x modifiers 0x%x"
> --
> 2.14.3
>