Le 21/12/2017 à 09:26, Mark Cave-Ayland a écrit : > On 20/12/17 12:14, Laurent Vivier 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 <laur...@vivier.eu> >> --- >> 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 >> @@ -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" >> +# 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" >> + >> # 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" >> > > Thanks Laurent - looks good to me. > > Reviewed-by: Mark Cave-Ayland <mark.cave-ayl...@ilande.co.uk>
Thank you. If nobody does before, I'll add this patch in my next pull request for m68k. Laurent