* [Qemu-devel] [PATCH] Split adb.c into adb.c, adb-mouse.c and adb-kbd.c
@ 2017-12-19 11:54 Laurent Vivier
2017-12-19 15:26 ` Philippe Mathieu-Daudé
2017-12-19 19:33 ` Mark Cave-Ayland
0 siblings, 2 replies; 5+ messages in thread
From: Laurent Vivier @ 2017-12-19 11:54 UTC (permalink / raw)
To: qemu-devel
Cc: Gerd Hoffmann, Hervé Poussineau, Mark Cave-Ayland,
Philippe Mathieu-Daudé,
Laurent Vivier
It makes the code clearer to separate the bus implementation
from the devices one.
Remove ADB_DPRINTF() from adb.c instead of adding it to new files.
Some minor changes to make checkpatch.pl happy.
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
hw/input/Makefile.objs | 2 +-
hw/input/adb-kbd.c | 395 +++++++++++++++++++++++++++++++
hw/input/adb-mouse.c | 250 ++++++++++++++++++++
hw/input/adb.c | 621 +------------------------------------------------
include/hw/input/adb.h | 26 +++
5 files changed, 673 insertions(+), 621 deletions(-)
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-kbd.c b/hw/input/adb-kbd.c
new file mode 100644
index 0000000000..c405ac814e
--- /dev/null
+++ b/hw/input/adb-kbd.c
@@ -0,0 +1,395 @@
+/*
+ * 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"
+
+#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:
+ 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 */
+ 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..8d96da6640
--- /dev/null
+++ b/hw/input/adb-mouse.c
@@ -0,0 +1,250 @@
+/*
+ * 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"
+
+#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:
+ 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;
+ }
+ 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..a9ad07fa55 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -22,49 +22,11 @@
* 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
/* 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 +89,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 +128,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/include/hw/input/adb.h b/include/hw/input/adb.h
index 3ae8445e95..df21b51117 100644
--- a/include/hw/input/adb.h
+++ b/include/hw/input/adb.h
@@ -33,6 +33,30 @@
#define ADB_MAX_OUT_LEN 16
typedef struct ADBBusState ADBBusState;
+
+/* 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
+
typedef struct ADBDevice ADBDevice;
/* buf = NULL means polling */
@@ -77,6 +101,8 @@ struct ADBBusState {
int poll_index;
};
+extern const VMStateDescription vmstate_adb_device;
+
int adb_request(ADBBusState *s, uint8_t *buf_out,
const uint8_t *buf, int len);
int adb_poll(ADBBusState *s, uint8_t *buf_out, uint16_t poll_mask);
--
2.14.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH] Split adb.c into adb.c, adb-mouse.c and adb-kbd.c
2017-12-19 11:54 [Qemu-devel] [PATCH] Split adb.c into adb.c, adb-mouse.c and adb-kbd.c Laurent Vivier
@ 2017-12-19 15:26 ` Philippe Mathieu-Daudé
2017-12-19 16:28 ` Laurent Vivier
2017-12-19 19:33 ` Mark Cave-Ayland
1 sibling, 1 reply; 5+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-12-19 15:26 UTC (permalink / raw)
To: Laurent Vivier
Cc: qemu-devel@nongnu.org Developers, Gerd Hoffmann,
Hervé Poussineau, Mark Cave-Ayland
Hi Laurent,
On Tue, Dec 19, 2017 at 8:54 AM, Laurent Vivier <laurent@vivier.eu> wrote:
> It makes the code clearer to separate the bus implementation
> from the devices one.
>
> Remove ADB_DPRINTF() from adb.c instead of adding it to new files.
> Some minor changes to make checkpatch.pl happy.
>
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
> hw/input/Makefile.objs | 2 +-
> hw/input/adb-kbd.c | 395 +++++++++++++++++++++++++++++++
> hw/input/adb-mouse.c | 250 ++++++++++++++++++++
> hw/input/adb.c | 621 +------------------------------------------------
> include/hw/input/adb.h | 26 +++
> 5 files changed, 673 insertions(+), 621 deletions(-)
> 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-kbd.c b/hw/input/adb-kbd.c
> new file mode 100644
> index 0000000000..c405ac814e
> --- /dev/null
> +++ b/hw/input/adb-kbd.c
> @@ -0,0 +1,395 @@
> +/*
> + * 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"
> +
> +#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:
> + 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 */
> + 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..8d96da6640
> --- /dev/null
> +++ b/hw/input/adb-mouse.c
> @@ -0,0 +1,250 @@
> +/*
> + * 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"
> +
> +#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:
> + 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;
> + }
> + 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..a9ad07fa55 100644
> --- a/hw/input/adb.c
> +++ b/hw/input/adb.c
> @@ -22,49 +22,11 @@
> * 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
>
> /* 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 +89,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 +128,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/include/hw/input/adb.h b/include/hw/input/adb.h
> index 3ae8445e95..df21b51117 100644
> --- a/include/hw/input/adb.h
> +++ b/include/hw/input/adb.h
> @@ -33,6 +33,30 @@
> #define ADB_MAX_OUT_LEN 16
>
> typedef struct ADBBusState ADBBusState;
ok
> +
> +/* 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
Is ADB the protocol used out of adb*.c?
Personally I prefer not expose those protocol defines if not needed,
so I'd add them to hw/input/adb-protocol.h (or to match the other
includes, hw/input/adb-internal.h).
regardless this comment:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> +
> typedef struct ADBDevice ADBDevice;
>
> /* buf = NULL means polling */
> @@ -77,6 +101,8 @@ struct ADBBusState {
> int poll_index;
> };
>
> +extern const VMStateDescription vmstate_adb_device;
If you choose to add hw/input/adb-internal.h, this extern can go there.
> +
> int adb_request(ADBBusState *s, uint8_t *buf_out,
> const uint8_t *buf, int len);
> int adb_poll(ADBBusState *s, uint8_t *buf_out, uint16_t poll_mask);
> --
> 2.14.3
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH] Split adb.c into adb.c, adb-mouse.c and adb-kbd.c
2017-12-19 15:26 ` Philippe Mathieu-Daudé
@ 2017-12-19 16:28 ` Laurent Vivier
0 siblings, 0 replies; 5+ messages in thread
From: Laurent Vivier @ 2017-12-19 16:28 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: qemu-devel@nongnu.org Developers, Gerd Hoffmann,
Hervé Poussineau, Mark Cave-Ayland
Le 19/12/2017 à 16:26, Philippe Mathieu-Daudé a écrit :
> Hi Laurent,
>
> On Tue, Dec 19, 2017 at 8:54 AM, Laurent Vivier <laurent@vivier.eu> wrote:
>> It makes the code clearer to separate the bus implementation
>> from the devices one.
>>
>> Remove ADB_DPRINTF() from adb.c instead of adding it to new files.
>> Some minor changes to make checkpatch.pl happy.
>>
>> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
>> ---
>> hw/input/Makefile.objs | 2 +-
>> hw/input/adb-kbd.c | 395 +++++++++++++++++++++++++++++++
>> hw/input/adb-mouse.c | 250 ++++++++++++++++++++
>> hw/input/adb.c | 621 +------------------------------------------------
>> include/hw/input/adb.h | 26 +++
>> 5 files changed, 673 insertions(+), 621 deletions(-)
>> create mode 100644 hw/input/adb-kbd.c
>> create mode 100644 hw/input/adb-mouse.c
>>
...
>> +
>> +/* 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
>
> Is ADB the protocol used out of adb*.c?
> Personally I prefer not expose those protocol defines if not needed,
> so I'd add them to hw/input/adb-protocol.h (or to match the other
> includes, hw/input/adb-internal.h).
>
> regardless this comment:
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
>
>> +
>> typedef struct ADBDevice ADBDevice;
>>
>> /* buf = NULL means polling */
>> @@ -77,6 +101,8 @@ struct ADBBusState {
>> int poll_index;
>> };
>>
>> +extern const VMStateDescription vmstate_adb_device;
>
> If you choose to add hw/input/adb-internal.h, this extern can go there.
>
>> +
>> int adb_request(ADBBusState *s, uint8_t *buf_out,
>> const uint8_t *buf, int len);
>> int adb_poll(ADBBusState *s, uint8_t *buf_out, uint16_t poll_mask);
>> --
>> 2.14.3
>>
I agree with you, I'm going to add an new include, hw/input/adb-internal.h
Thanks,
Laurent
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH] Split adb.c into adb.c, adb-mouse.c and adb-kbd.c
2017-12-19 11:54 [Qemu-devel] [PATCH] Split adb.c into adb.c, adb-mouse.c and adb-kbd.c Laurent Vivier
2017-12-19 15:26 ` Philippe Mathieu-Daudé
@ 2017-12-19 19:33 ` Mark Cave-Ayland
2017-12-20 8:14 ` Laurent Vivier
1 sibling, 1 reply; 5+ messages in thread
From: Mark Cave-Ayland @ 2017-12-19 19:33 UTC (permalink / raw)
To: Laurent Vivier, qemu-devel
Cc: Hervé Poussineau, Gerd Hoffmann, Philippe Mathieu-Daudé
On 19/12/17 11:54, Laurent Vivier wrote:
> It makes the code clearer to separate the bus implementation
> from the devices one.
>
> Remove ADB_DPRINTF() from adb.c instead of adding it to new files.
> Some minor changes to make checkpatch.pl happy.
>
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
> hw/input/Makefile.objs | 2 +-
> hw/input/adb-kbd.c | 395 +++++++++++++++++++++++++++++++
> hw/input/adb-mouse.c | 250 ++++++++++++++++++++
> hw/input/adb.c | 621 +------------------------------------------------
> include/hw/input/adb.h | 26 +++
> 5 files changed, 673 insertions(+), 621 deletions(-)
> 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-kbd.c b/hw/input/adb-kbd.c
> new file mode 100644
> index 0000000000..c405ac814e
> --- /dev/null
> +++ b/hw/input/adb-kbd.c
> @@ -0,0 +1,395 @@
> +/*
> + * 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"
> +
> +#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:
> + 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 */
> + 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..8d96da6640
> --- /dev/null
> +++ b/hw/input/adb-mouse.c
> @@ -0,0 +1,250 @@
> +/*
> + * 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"
> +
> +#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:
> + 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;
> + }
> + 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..a9ad07fa55 100644
> --- a/hw/input/adb.c
> +++ b/hw/input/adb.c
> @@ -22,49 +22,11 @@
> * 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
>
> /* 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 +89,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 +128,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/include/hw/input/adb.h b/include/hw/input/adb.h
> index 3ae8445e95..df21b51117 100644
> --- a/include/hw/input/adb.h
> +++ b/include/hw/input/adb.h
> @@ -33,6 +33,30 @@
> #define ADB_MAX_OUT_LEN 16
>
> typedef struct ADBBusState ADBBusState;
> +
> +/* 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
> +
> typedef struct ADBDevice ADBDevice;
>
> /* buf = NULL means polling */
> @@ -77,6 +101,8 @@ struct ADBBusState {
> int poll_index;
> };
>
> +extern const VMStateDescription vmstate_adb_device;
> +
> int adb_request(ADBBusState *s, uint8_t *buf_out,
> const uint8_t *buf, int len);
> int adb_poll(ADBBusState *s, uint8_t *buf_out, uint16_t poll_mask);
>
This is definitely a welcome refactoring! My only comment is that I'd
like to keep the ADB_DPRINTF() (or convert to tracepoints) because some
versions of MacOS 9 do strange things to the ADB bus which means that
these are sadly still required :/
ATB,
Mark.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH] Split adb.c into adb.c, adb-mouse.c and adb-kbd.c
2017-12-19 19:33 ` Mark Cave-Ayland
@ 2017-12-20 8:14 ` Laurent Vivier
0 siblings, 0 replies; 5+ messages in thread
From: Laurent Vivier @ 2017-12-20 8:14 UTC (permalink / raw)
To: Mark Cave-Ayland, qemu-devel
Cc: Hervé Poussineau, Gerd Hoffmann, Philippe Mathieu-Daudé
Le 19/12/2017 à 20:33, Mark Cave-Ayland a écrit :
> On 19/12/17 11:54, Laurent Vivier wrote:
>
>> It makes the code clearer to separate the bus implementation
>> from the devices one.
>>
>> Remove ADB_DPRINTF() from adb.c instead of adding it to new files.
>> Some minor changes to make checkpatch.pl happy.
>>
>> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
>> ---
>> hw/input/Makefile.objs | 2 +-
>> hw/input/adb-kbd.c | 395 +++++++++++++++++++++++++++++++
>> hw/input/adb-mouse.c | 250 ++++++++++++++++++++
>> hw/input/adb.c | 621
>> +------------------------------------------------
>> include/hw/input/adb.h | 26 +++
>> 5 files changed, 673 insertions(+), 621 deletions(-)
>> 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-kbd.c b/hw/input/adb-kbd.c
>> new file mode 100644
>> index 0000000000..c405ac814e
>> --- /dev/null
>> +++ b/hw/input/adb-kbd.c
>> @@ -0,0 +1,395 @@
>> +/*
>> + * 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"
>> +
>> +#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:
>> + 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 */
>> + 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..8d96da6640
>> --- /dev/null
>> +++ b/hw/input/adb-mouse.c
>> @@ -0,0 +1,250 @@
>> +/*
>> + * 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"
>> +
>> +#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:
>> + 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;
>> + }
>> + 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..a9ad07fa55 100644
>> --- a/hw/input/adb.c
>> +++ b/hw/input/adb.c
>> @@ -22,49 +22,11 @@
>> * 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
>> /* 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 +89,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 +128,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/include/hw/input/adb.h b/include/hw/input/adb.h
>> index 3ae8445e95..df21b51117 100644
>> --- a/include/hw/input/adb.h
>> +++ b/include/hw/input/adb.h
>> @@ -33,6 +33,30 @@
>> #define ADB_MAX_OUT_LEN 16
>> typedef struct ADBBusState ADBBusState;
>> +
>> +/* 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
>> +
>> typedef struct ADBDevice ADBDevice;
>> /* buf = NULL means polling */
>> @@ -77,6 +101,8 @@ struct ADBBusState {
>> int poll_index;
>> };
>> +extern const VMStateDescription vmstate_adb_device;
>> +
>> int adb_request(ADBBusState *s, uint8_t *buf_out,
>> const uint8_t *buf, int len);
>> int adb_poll(ADBBusState *s, uint8_t *buf_out, uint16_t poll_mask);
>>
>
> This is definitely a welcome refactoring! My only comment is that I'd
> like to keep the ADB_DPRINTF() (or convert to tracepoints) because some
> versions of MacOS 9 do strange things to the ADB bus which means that
> these are sadly still required :/
OK, I'll add tracepoints.
Thanks,
Laurent
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-12-20 8:14 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-19 11:54 [Qemu-devel] [PATCH] Split adb.c into adb.c, adb-mouse.c and adb-kbd.c Laurent Vivier
2017-12-19 15:26 ` Philippe Mathieu-Daudé
2017-12-19 16:28 ` Laurent Vivier
2017-12-19 19:33 ` Mark Cave-Ayland
2017-12-20 8:14 ` Laurent Vivier
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.