From nobody Sat May 4 06:00:24 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1513684623230922.2590805748877; Tue, 19 Dec 2017 03:57:03 -0800 (PST) Received: from localhost ([::1]:40134 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eRGVz-0001mu-5T for importer@patchew.org; Tue, 19 Dec 2017 06:56:55 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43509) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eRGUT-0000wC-Co for qemu-devel@nongnu.org; Tue, 19 Dec 2017 06:55:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eRGUO-0000k5-9W for qemu-devel@nongnu.org; Tue, 19 Dec 2017 06:55:21 -0500 Received: from mout.kundenserver.de ([217.72.192.74]:62642) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eRGUN-0000gk-Ja for qemu-devel@nongnu.org; Tue, 19 Dec 2017 06:55:16 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue103 [212.227.15.183]) with ESMTPSA (Nemesis) id 0MOU8z-1eODg31lYb-005nGz; Tue, 19 Dec 2017 12:55:04 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 19 Dec 2017 12:54:47 +0100 Message-Id: <20171219115447.17948-1-laurent@vivier.eu> X-Mailer: git-send-email 2.14.3 X-Provags-ID: V03:K0:8CXIsoJ8Zyk0ek4RQ8TFBcbp22HFB3N2+QeXRbZ9bzdlt4aHu2L P2u7RHAqpVRHNaN+k4nAVW3GenlcdFeb+zFXSVYfcNwXBacqzRD/t+gMf2mHl+EFYhzjsoz V35CB03XWSgq8a2g0KLCBeIBEj0usOWsvI/c5R7zue1RRb2W3xjN3UArxtRENzn/IsFaCWC fK5S8OwG+T87TNATNWP8w== X-UI-Out-Filterresults: notjunk:1;V01:K0:1a+obYsEyv8=:puhofQabuYN7ijuvVjiTIu dt4ukQKsVswYHoymKdrv0xQYVrK2hAkvgXIhFGizyrzlR/mReas0GdvoaqzLM1yvsQ8xABZZb XRs8o927aJpXA9j9g+6ww3Tkj4T7UVonN3qEu/TT0E9rLFHIljS5PxWSOB8w9VFFCxvsvE8PL XBkWXox25oR6Nlw8+PJZMjaD8Ane1nrkdAC/Iif1LjH5nbhrrtbxAv/IOL3xEqxcRxQivNBS0 qlOsfB8G4I7MDHqh0j3i6bn574rjNG7MncajUJdI9aJG88uvuN/tvrxQh2A98Zha0lnattx3R /b6e9l5NSL+GUxunvJ4+cMKhsg/AkYAwuZy+W4ox9XUtKDv40uWZKVRgcEPPB6uCOSTxgc7la BcjESm1Ud5jU8xV8V20rsG52oKjEP5fb33iSx+wPsnrXoQWI8Jbba5c0vIMUzMbuHEFXDn2HS 0fXm1CuSkR/ge3pGtQ5WTwHplETUMPrQBbCMgJT+D5ULphKTH9qZ5hzdOGCIVGq8CMeCcN/Mu UC4vhp5LN0VElT4rLGL897anx+zEw4PyHfhZegizeH2wpjyhbktG9c5mpNCnu2W+AEMVRNbmF TD3B3SsOOiKPeidjV2Van13AYol29HkHTsvonDwhGQK0EspB3c6bMENspITyjkR0aC817U7mb wClS04zwvdk/E77ELk7huc1mhZpvRV9JguRc68KmD8CLGnm2wW8fouoVz2H4WmeqXLsnez1ZP Q6mqS2fSp9ErTidKfTjIlLSsi/Jp+5seCDjfgA== X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 217.72.192.74 Subject: [Qemu-devel] [PATCH] Split adb.c into adb.c, adb-mouse.c and adb-kbd.c X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Cave-Ayland , Laurent Vivier , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , Gerd Hoffmann , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- 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) +=3D adb.o +common-obj-$(CONFIG_ADB) +=3D adb.o adb-mouse.o adb-kbd.o common-obj-y +=3D hid.o common-obj-$(CONFIG_LM832X) +=3D lm832x.o common-obj-$(CONFIG_PCKBD) +=3D 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"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * 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 OT= HER + * 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[] =3D { + /* Make sure future additions are automatically set to NO_KEY */ + [0 ... 0xff] =3D NO_KEY, + + [Q_KEY_CODE_SHIFT] =3D ADB_KEY_LEFT_SHIFT, + [Q_KEY_CODE_SHIFT_R] =3D ADB_KEY_RIGHT_SHIFT, + [Q_KEY_CODE_ALT] =3D ADB_KEY_LEFT_OPTION, + [Q_KEY_CODE_ALT_R] =3D ADB_KEY_RIGHT_OPTION, + [Q_KEY_CODE_CTRL] =3D ADB_KEY_LEFT_CONTROL, + [Q_KEY_CODE_CTRL_R] =3D ADB_KEY_RIGHT_CONTROL, + [Q_KEY_CODE_META_L] =3D ADB_KEY_COMMAND, + [Q_KEY_CODE_META_R] =3D ADB_KEY_COMMAND, + [Q_KEY_CODE_SPC] =3D ADB_KEY_SPACEBAR, + + [Q_KEY_CODE_ESC] =3D ADB_KEY_ESC, + [Q_KEY_CODE_1] =3D ADB_KEY_1, + [Q_KEY_CODE_2] =3D ADB_KEY_2, + [Q_KEY_CODE_3] =3D ADB_KEY_3, + [Q_KEY_CODE_4] =3D ADB_KEY_4, + [Q_KEY_CODE_5] =3D ADB_KEY_5, + [Q_KEY_CODE_6] =3D ADB_KEY_6, + [Q_KEY_CODE_7] =3D ADB_KEY_7, + [Q_KEY_CODE_8] =3D ADB_KEY_8, + [Q_KEY_CODE_9] =3D ADB_KEY_9, + [Q_KEY_CODE_0] =3D ADB_KEY_0, + [Q_KEY_CODE_MINUS] =3D ADB_KEY_MINUS, + [Q_KEY_CODE_EQUAL] =3D ADB_KEY_EQUAL, + [Q_KEY_CODE_BACKSPACE] =3D ADB_KEY_DELETE, + [Q_KEY_CODE_TAB] =3D ADB_KEY_TAB, + [Q_KEY_CODE_Q] =3D ADB_KEY_Q, + [Q_KEY_CODE_W] =3D ADB_KEY_W, + [Q_KEY_CODE_E] =3D ADB_KEY_E, + [Q_KEY_CODE_R] =3D ADB_KEY_R, + [Q_KEY_CODE_T] =3D ADB_KEY_T, + [Q_KEY_CODE_Y] =3D ADB_KEY_Y, + [Q_KEY_CODE_U] =3D ADB_KEY_U, + [Q_KEY_CODE_I] =3D ADB_KEY_I, + [Q_KEY_CODE_O] =3D ADB_KEY_O, + [Q_KEY_CODE_P] =3D ADB_KEY_P, + [Q_KEY_CODE_BRACKET_LEFT] =3D ADB_KEY_LEFT_BRACKET, + [Q_KEY_CODE_BRACKET_RIGHT] =3D ADB_KEY_RIGHT_BRACKET, + [Q_KEY_CODE_RET] =3D ADB_KEY_RETURN, + [Q_KEY_CODE_A] =3D ADB_KEY_A, + [Q_KEY_CODE_S] =3D ADB_KEY_S, + [Q_KEY_CODE_D] =3D ADB_KEY_D, + [Q_KEY_CODE_F] =3D ADB_KEY_F, + [Q_KEY_CODE_G] =3D ADB_KEY_G, + [Q_KEY_CODE_H] =3D ADB_KEY_H, + [Q_KEY_CODE_J] =3D ADB_KEY_J, + [Q_KEY_CODE_K] =3D ADB_KEY_K, + [Q_KEY_CODE_L] =3D ADB_KEY_L, + [Q_KEY_CODE_SEMICOLON] =3D ADB_KEY_SEMICOLON, + [Q_KEY_CODE_APOSTROPHE] =3D ADB_KEY_APOSTROPHE, + [Q_KEY_CODE_GRAVE_ACCENT] =3D ADB_KEY_GRAVE_ACCENT, + [Q_KEY_CODE_BACKSLASH] =3D ADB_KEY_BACKSLASH, + [Q_KEY_CODE_Z] =3D ADB_KEY_Z, + [Q_KEY_CODE_X] =3D ADB_KEY_X, + [Q_KEY_CODE_C] =3D ADB_KEY_C, + [Q_KEY_CODE_V] =3D ADB_KEY_V, + [Q_KEY_CODE_B] =3D ADB_KEY_B, + [Q_KEY_CODE_N] =3D ADB_KEY_N, + [Q_KEY_CODE_M] =3D ADB_KEY_M, + [Q_KEY_CODE_COMMA] =3D ADB_KEY_COMMA, + [Q_KEY_CODE_DOT] =3D ADB_KEY_PERIOD, + [Q_KEY_CODE_SLASH] =3D ADB_KEY_FORWARD_SLASH, + [Q_KEY_CODE_ASTERISK] =3D ADB_KEY_KP_MULTIPLY, + [Q_KEY_CODE_CAPS_LOCK] =3D ADB_KEY_CAPS_LOCK, + + [Q_KEY_CODE_F1] =3D ADB_KEY_F1, + [Q_KEY_CODE_F2] =3D ADB_KEY_F2, + [Q_KEY_CODE_F3] =3D ADB_KEY_F3, + [Q_KEY_CODE_F4] =3D ADB_KEY_F4, + [Q_KEY_CODE_F5] =3D ADB_KEY_F5, + [Q_KEY_CODE_F6] =3D ADB_KEY_F6, + [Q_KEY_CODE_F7] =3D ADB_KEY_F7, + [Q_KEY_CODE_F8] =3D ADB_KEY_F8, + [Q_KEY_CODE_F9] =3D ADB_KEY_F9, + [Q_KEY_CODE_F10] =3D ADB_KEY_F10, + [Q_KEY_CODE_F11] =3D ADB_KEY_F11, + [Q_KEY_CODE_F12] =3D ADB_KEY_F12, + [Q_KEY_CODE_PRINT] =3D ADB_KEY_F13, + [Q_KEY_CODE_SYSRQ] =3D ADB_KEY_F13, + [Q_KEY_CODE_SCROLL_LOCK] =3D ADB_KEY_F14, + [Q_KEY_CODE_PAUSE] =3D ADB_KEY_F15, + + [Q_KEY_CODE_NUM_LOCK] =3D ADB_KEY_KP_CLEAR, + [Q_KEY_CODE_KP_EQUALS] =3D ADB_KEY_KP_EQUAL, + [Q_KEY_CODE_KP_DIVIDE] =3D ADB_KEY_KP_DIVIDE, + [Q_KEY_CODE_KP_MULTIPLY] =3D ADB_KEY_KP_MULTIPLY, + [Q_KEY_CODE_KP_SUBTRACT] =3D ADB_KEY_KP_SUBTRACT, + [Q_KEY_CODE_KP_ADD] =3D ADB_KEY_KP_PLUS, + [Q_KEY_CODE_KP_ENTER] =3D ADB_KEY_KP_ENTER, + [Q_KEY_CODE_KP_DECIMAL] =3D ADB_KEY_KP_PERIOD, + [Q_KEY_CODE_KP_0] =3D ADB_KEY_KP_0, + [Q_KEY_CODE_KP_1] =3D ADB_KEY_KP_1, + [Q_KEY_CODE_KP_2] =3D ADB_KEY_KP_2, + [Q_KEY_CODE_KP_3] =3D ADB_KEY_KP_3, + [Q_KEY_CODE_KP_4] =3D ADB_KEY_KP_4, + [Q_KEY_CODE_KP_5] =3D ADB_KEY_KP_5, + [Q_KEY_CODE_KP_6] =3D ADB_KEY_KP_6, + [Q_KEY_CODE_KP_7] =3D ADB_KEY_KP_7, + [Q_KEY_CODE_KP_8] =3D ADB_KEY_KP_8, + [Q_KEY_CODE_KP_9] =3D ADB_KEY_KP_9, + + [Q_KEY_CODE_UP] =3D ADB_KEY_UP, + [Q_KEY_CODE_DOWN] =3D ADB_KEY_DOWN, + [Q_KEY_CODE_LEFT] =3D ADB_KEY_LEFT, + [Q_KEY_CODE_RIGHT] =3D ADB_KEY_RIGHT, + + [Q_KEY_CODE_HELP] =3D ADB_KEY_HELP, + [Q_KEY_CODE_INSERT] =3D ADB_KEY_HELP, + [Q_KEY_CODE_DELETE] =3D ADB_KEY_FORWARD_DELETE, + [Q_KEY_CODE_HOME] =3D ADB_KEY_HOME, + [Q_KEY_CODE_END] =3D ADB_KEY_END, + [Q_KEY_CODE_PGUP] =3D ADB_KEY_PAGE_UP, + [Q_KEY_CODE_PGDN] =3D ADB_KEY_PAGE_DOWN, + + [Q_KEY_CODE_POWER] =3D ADB_KEY_POWER +}; + +static void adb_kbd_put_keycode(void *opaque, int keycode) +{ + KBDState *s =3D opaque; + + if (s->count < sizeof(s->data)) { + s->data[s->wptr] =3D keycode; + if (++s->wptr =3D=3D sizeof(s->data)) { + s->wptr =3D 0; + } + s->count++; + } +} + +static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf) +{ + KBDState *s =3D ADB_KEYBOARD(d); + int keycode; + int olen; + + olen =3D 0; + if (s->count =3D=3D 0) { + return 0; + } + keycode =3D s->data[s->rptr]; + s->rptr++; + if (s->rptr =3D=3D sizeof(s->data)) { + s->rptr =3D 0; + } + s->count--; + /* + * The power key is the only two byte value key, so it is a special ca= se. + * 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 =3D=3D 0x7f) { + obuf[0] =3D 0x7f; + obuf[1] =3D 0x7f; + olen =3D 2; + } else { + obuf[0] =3D 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] =3D 0xff; + olen =3D 2; + } + + return olen; +} + +static int adb_kbd_request(ADBDevice *d, uint8_t *obuf, + const uint8_t *buf, int len) +{ + KBDState *s =3D ADB_KEYBOARD(d); + int cmd, reg, olen; + + if ((buf[0] & 0x0f) =3D=3D ADB_FLUSH) { + /* flush keyboard fifo */ + s->wptr =3D s->rptr =3D s->count =3D 0; + return 0; + } + + cmd =3D buf[0] & 0xc; + reg =3D buf[0] & 0x3; + olen =3D 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 =3D buf[1] & 0xf; + break; + default: + d->devaddr =3D buf[1] & 0xf; + /* we support handlers: + * 1: Apple Standard Keyboard + * 2: Apple Extended Keyboard (LShift =3D RShift) + * 3: Apple Extended Keyboard (LShift !=3D RShift) + */ + if (buf[2] =3D=3D 1 || buf[2] =3D=3D 2 || buf[2] =3D=3D 3)= { + d->handler =3D buf[2]; + } + break; + } + } + break; + case ADB_READREG: + switch (reg) { + case 0: + olen =3D adb_kbd_poll(d, obuf); + break; + case 1: + break; + case 2: + obuf[0] =3D 0x00; /* XXX: check this */ + obuf[1] =3D 0x07; /* led status */ + olen =3D 2; + break; + case 3: + obuf[0] =3D d->handler; + obuf[1] =3D d->devaddr; + olen =3D 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 =3D (KBDState *)dev; + int qcode, keycode; + + qcode =3D qemu_input_key_value_to_qcode(evt->u.key.data->key); + if (qcode >=3D ARRAY_SIZE(qcode_to_adb_keycode)) { + return; + } + /* FIXME: take handler into account when translating qcode */ + keycode =3D qcode_to_adb_keycode[qcode]; + if (keycode =3D=3D NO_KEY) { /* We don't want to send this to the gue= st */ + return; + } + if (evt->u.key.data->down =3D=3D false) { /* if key release event */ + keycode =3D keycode | 0x80; /* create keyboard break code */ + } + + adb_kbd_put_keycode(s, keycode); +} + +static const VMStateDescription vmstate_adb_kbd =3D { + .name =3D "adb_kbd", + .version_id =3D 2, + .minimum_version_id =3D 2, + .fields =3D (VMStateField[]) { + VMSTATE_STRUCT(parent_obj, KBDState, 0, vmstate_adb_device, ADBDev= ice), + 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 =3D ADB_DEVICE(dev); + KBDState *s =3D ADB_KEYBOARD(dev); + + d->handler =3D 1; + d->devaddr =3D ADB_DEVID_KEYBOARD; + memset(s->data, 0, sizeof(s->data)); + s->rptr =3D 0; + s->wptr =3D 0; + s->count =3D 0; +} + +static QemuInputHandler adb_keyboard_handler =3D { + .name =3D "QEMU ADB Keyboard", + .mask =3D INPUT_EVENT_MASK_KEY, + .event =3D adb_keyboard_event, +}; + +static void adb_kbd_realizefn(DeviceState *dev, Error **errp) +{ + ADBKeyboardClass *akc =3D 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 =3D ADB_DEVICE(obj); + + d->devaddr =3D ADB_DEVID_KEYBOARD; +} + +static void adb_kbd_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(oc); + ADBDeviceClass *adc =3D ADB_DEVICE_CLASS(oc); + ADBKeyboardClass *akc =3D ADB_KEYBOARD_CLASS(oc); + + akc->parent_realize =3D dc->realize; + dc->realize =3D adb_kbd_realizefn; + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); + + adc->devreq =3D adb_kbd_request; + dc->reset =3D adb_kbd_reset; + dc->vmsd =3D &vmstate_adb_kbd; +} + +static const TypeInfo adb_kbd_type_info =3D { + .name =3D TYPE_ADB_KEYBOARD, + .parent =3D TYPE_ADB_DEVICE, + .instance_size =3D sizeof(KBDState), + .instance_init =3D adb_kbd_initfn, + .class_init =3D adb_kbd_class_init, + .class_size =3D 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"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * 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 OT= HER + * 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 =3D opaque; + + s->dx +=3D dx1; + s->dy +=3D dy1; + s->dz +=3D dz1; + s->buttons_state =3D buttons_state; +} + + +static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf) +{ + MouseState *s =3D ADB_MOUSE(d); + int dx, dy; + + if (s->last_buttons_state =3D=3D s->buttons_state && + s->dx =3D=3D 0 && s->dy =3D=3D 0) { + return 0; + } + + dx =3D s->dx; + if (dx < -63) { + dx =3D -63; + } else if (dx > 63) { + dx =3D 63; + } + + dy =3D s->dy; + if (dy < -63) { + dy =3D -63; + } else if (dy > 63) { + dy =3D 63; + } + + s->dx -=3D dx; + s->dy -=3D dy; + s->last_buttons_state =3D s->buttons_state; + + dx &=3D 0x7f; + dy &=3D 0x7f; + + if (!(s->buttons_state & MOUSE_EVENT_LBUTTON)) { + dy |=3D 0x80; + } + if (!(s->buttons_state & MOUSE_EVENT_RBUTTON)) { + dx |=3D 0x80; + } + + obuf[0] =3D dy; + obuf[1] =3D dx; + return 2; +} + +static int adb_mouse_request(ADBDevice *d, uint8_t *obuf, + const uint8_t *buf, int len) +{ + MouseState *s =3D ADB_MOUSE(d); + int cmd, reg, olen; + + if ((buf[0] & 0x0f) =3D=3D ADB_FLUSH) { + /* flush mouse fifo */ + s->buttons_state =3D s->last_buttons_state; + s->dx =3D 0; + s->dy =3D 0; + s->dz =3D 0; + return 0; + } + + cmd =3D buf[0] & 0xc; + reg =3D buf[0] & 0x3; + olen =3D 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 =3D buf[1] & 0xf; + break; + default: + d->devaddr =3D 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] =3D=3D 1 || buf[2] =3D=3D 2) { + d->handler =3D buf[2]; + } + break; + } + } + break; + case ADB_READREG: + switch (reg) { + case 0: + olen =3D adb_mouse_poll(d, obuf); + break; + case 1: + break; + case 3: + obuf[0] =3D d->handler; + obuf[1] =3D d->devaddr; + olen =3D 2; + break; + } + break; + } + return olen; +} + +static void adb_mouse_reset(DeviceState *dev) +{ + ADBDevice *d =3D ADB_DEVICE(dev); + MouseState *s =3D ADB_MOUSE(dev); + + d->handler =3D 2; + d->devaddr =3D ADB_DEVID_MOUSE; + s->last_buttons_state =3D s->buttons_state =3D 0; + s->dx =3D s->dy =3D s->dz =3D 0; +} + +static const VMStateDescription vmstate_adb_mouse =3D { + .name =3D "adb_mouse", + .version_id =3D 2, + .minimum_version_id =3D 2, + .fields =3D (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 =3D ADB_MOUSE(dev); + ADBMouseClass *amc =3D 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 =3D ADB_DEVICE(obj); + + d->devaddr =3D ADB_DEVID_MOUSE; +} + +static void adb_mouse_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(oc); + ADBDeviceClass *adc =3D ADB_DEVICE_CLASS(oc); + ADBMouseClass *amc =3D ADB_MOUSE_CLASS(oc); + + amc->parent_realize =3D dc->realize; + dc->realize =3D adb_mouse_realizefn; + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); + + adc->devreq =3D adb_mouse_request; + dc->reset =3D adb_mouse_reset; + dc->vmsd =3D &vmstate_adb_mouse; +} + +static const TypeInfo adb_mouse_type_info =3D { + .name =3D TYPE_ADB_MOUSE, + .parent =3D TYPE_ADB_DEVICE, + .instance_size =3D sizeof(MouseState), + .instance_init =3D adb_mouse_initfn, + .class_init =3D adb_mouse_class_init, + .class_size =3D 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 =20 /* error codes */ #define ADB_RET_NOTPRESENT (-2) =20 -/* 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 =3D { .instance_size =3D sizeof(ADBBusState), }; =20 -static const VMStateDescription vmstate_adb_device =3D { +const VMStateDescription vmstate_adb_device =3D { .name =3D "adb_device", .version_id =3D 0, .minimum_version_id =3D 0, @@ -166,591 +128,10 @@ static const TypeInfo adb_device_type_info =3D { .class_init =3D adb_device_class_init, }; =20 -/***************************************************************/ -/* 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[] =3D { - /* Make sure future additions are automatically set to NO_KEY */ - [0 ... 0xff] =3D NO_KEY, - - [Q_KEY_CODE_SHIFT] =3D ADB_KEY_LEFT_SHIFT, - [Q_KEY_CODE_SHIFT_R] =3D ADB_KEY_RIGHT_SHIFT, - [Q_KEY_CODE_ALT] =3D ADB_KEY_LEFT_OPTION, - [Q_KEY_CODE_ALT_R] =3D ADB_KEY_RIGHT_OPTION, - [Q_KEY_CODE_CTRL] =3D ADB_KEY_LEFT_CONTROL, - [Q_KEY_CODE_CTRL_R] =3D ADB_KEY_RIGHT_CONTROL, - [Q_KEY_CODE_META_L] =3D ADB_KEY_COMMAND, - [Q_KEY_CODE_META_R] =3D ADB_KEY_COMMAND, - [Q_KEY_CODE_SPC] =3D ADB_KEY_SPACEBAR, - - [Q_KEY_CODE_ESC] =3D ADB_KEY_ESC, - [Q_KEY_CODE_1] =3D ADB_KEY_1, - [Q_KEY_CODE_2] =3D ADB_KEY_2, - [Q_KEY_CODE_3] =3D ADB_KEY_3, - [Q_KEY_CODE_4] =3D ADB_KEY_4, - [Q_KEY_CODE_5] =3D ADB_KEY_5, - [Q_KEY_CODE_6] =3D ADB_KEY_6, - [Q_KEY_CODE_7] =3D ADB_KEY_7, - [Q_KEY_CODE_8] =3D ADB_KEY_8, - [Q_KEY_CODE_9] =3D ADB_KEY_9, - [Q_KEY_CODE_0] =3D ADB_KEY_0, - [Q_KEY_CODE_MINUS] =3D ADB_KEY_MINUS, - [Q_KEY_CODE_EQUAL] =3D ADB_KEY_EQUAL, - [Q_KEY_CODE_BACKSPACE] =3D ADB_KEY_DELETE, - [Q_KEY_CODE_TAB] =3D ADB_KEY_TAB, - [Q_KEY_CODE_Q] =3D ADB_KEY_Q, - [Q_KEY_CODE_W] =3D ADB_KEY_W, - [Q_KEY_CODE_E] =3D ADB_KEY_E, - [Q_KEY_CODE_R] =3D ADB_KEY_R, - [Q_KEY_CODE_T] =3D ADB_KEY_T, - [Q_KEY_CODE_Y] =3D ADB_KEY_Y, - [Q_KEY_CODE_U] =3D ADB_KEY_U, - [Q_KEY_CODE_I] =3D ADB_KEY_I, - [Q_KEY_CODE_O] =3D ADB_KEY_O, - [Q_KEY_CODE_P] =3D ADB_KEY_P, - [Q_KEY_CODE_BRACKET_LEFT] =3D ADB_KEY_LEFT_BRACKET, - [Q_KEY_CODE_BRACKET_RIGHT] =3D ADB_KEY_RIGHT_BRACKET, - [Q_KEY_CODE_RET] =3D ADB_KEY_RETURN, - [Q_KEY_CODE_A] =3D ADB_KEY_A, - [Q_KEY_CODE_S] =3D ADB_KEY_S, - [Q_KEY_CODE_D] =3D ADB_KEY_D, - [Q_KEY_CODE_F] =3D ADB_KEY_F, - [Q_KEY_CODE_G] =3D ADB_KEY_G, - [Q_KEY_CODE_H] =3D ADB_KEY_H, - [Q_KEY_CODE_J] =3D ADB_KEY_J, - [Q_KEY_CODE_K] =3D ADB_KEY_K, - [Q_KEY_CODE_L] =3D ADB_KEY_L, - [Q_KEY_CODE_SEMICOLON] =3D ADB_KEY_SEMICOLON, - [Q_KEY_CODE_APOSTROPHE] =3D ADB_KEY_APOSTROPHE, - [Q_KEY_CODE_GRAVE_ACCENT] =3D ADB_KEY_GRAVE_ACCENT, - [Q_KEY_CODE_BACKSLASH] =3D ADB_KEY_BACKSLASH, - [Q_KEY_CODE_Z] =3D ADB_KEY_Z, - [Q_KEY_CODE_X] =3D ADB_KEY_X, - [Q_KEY_CODE_C] =3D ADB_KEY_C, - [Q_KEY_CODE_V] =3D ADB_KEY_V, - [Q_KEY_CODE_B] =3D ADB_KEY_B, - [Q_KEY_CODE_N] =3D ADB_KEY_N, - [Q_KEY_CODE_M] =3D ADB_KEY_M, - [Q_KEY_CODE_COMMA] =3D ADB_KEY_COMMA, - [Q_KEY_CODE_DOT] =3D ADB_KEY_PERIOD, - [Q_KEY_CODE_SLASH] =3D ADB_KEY_FORWARD_SLASH, - [Q_KEY_CODE_ASTERISK] =3D ADB_KEY_KP_MULTIPLY, - [Q_KEY_CODE_CAPS_LOCK] =3D ADB_KEY_CAPS_LOCK, - - [Q_KEY_CODE_F1] =3D ADB_KEY_F1, - [Q_KEY_CODE_F2] =3D ADB_KEY_F2, - [Q_KEY_CODE_F3] =3D ADB_KEY_F3, - [Q_KEY_CODE_F4] =3D ADB_KEY_F4, - [Q_KEY_CODE_F5] =3D ADB_KEY_F5, - [Q_KEY_CODE_F6] =3D ADB_KEY_F6, - [Q_KEY_CODE_F7] =3D ADB_KEY_F7, - [Q_KEY_CODE_F8] =3D ADB_KEY_F8, - [Q_KEY_CODE_F9] =3D ADB_KEY_F9, - [Q_KEY_CODE_F10] =3D ADB_KEY_F10, - [Q_KEY_CODE_F11] =3D ADB_KEY_F11, - [Q_KEY_CODE_F12] =3D ADB_KEY_F12, - [Q_KEY_CODE_PRINT] =3D ADB_KEY_F13, - [Q_KEY_CODE_SYSRQ] =3D ADB_KEY_F13, - [Q_KEY_CODE_SCROLL_LOCK] =3D ADB_KEY_F14, - [Q_KEY_CODE_PAUSE] =3D ADB_KEY_F15, - - [Q_KEY_CODE_NUM_LOCK] =3D ADB_KEY_KP_CLEAR, - [Q_KEY_CODE_KP_EQUALS] =3D ADB_KEY_KP_EQUAL, - [Q_KEY_CODE_KP_DIVIDE] =3D ADB_KEY_KP_DIVIDE, - [Q_KEY_CODE_KP_MULTIPLY] =3D ADB_KEY_KP_MULTIPLY, - [Q_KEY_CODE_KP_SUBTRACT] =3D ADB_KEY_KP_SUBTRACT, - [Q_KEY_CODE_KP_ADD] =3D ADB_KEY_KP_PLUS, - [Q_KEY_CODE_KP_ENTER] =3D ADB_KEY_KP_ENTER, - [Q_KEY_CODE_KP_DECIMAL] =3D ADB_KEY_KP_PERIOD, - [Q_KEY_CODE_KP_0] =3D ADB_KEY_KP_0, - [Q_KEY_CODE_KP_1] =3D ADB_KEY_KP_1, - [Q_KEY_CODE_KP_2] =3D ADB_KEY_KP_2, - [Q_KEY_CODE_KP_3] =3D ADB_KEY_KP_3, - [Q_KEY_CODE_KP_4] =3D ADB_KEY_KP_4, - [Q_KEY_CODE_KP_5] =3D ADB_KEY_KP_5, - [Q_KEY_CODE_KP_6] =3D ADB_KEY_KP_6, - [Q_KEY_CODE_KP_7] =3D ADB_KEY_KP_7, - [Q_KEY_CODE_KP_8] =3D ADB_KEY_KP_8, - [Q_KEY_CODE_KP_9] =3D ADB_KEY_KP_9, - - [Q_KEY_CODE_UP] =3D ADB_KEY_UP, - [Q_KEY_CODE_DOWN] =3D ADB_KEY_DOWN, - [Q_KEY_CODE_LEFT] =3D ADB_KEY_LEFT, - [Q_KEY_CODE_RIGHT] =3D ADB_KEY_RIGHT, - - [Q_KEY_CODE_HELP] =3D ADB_KEY_HELP, - [Q_KEY_CODE_INSERT] =3D ADB_KEY_HELP, - [Q_KEY_CODE_DELETE] =3D ADB_KEY_FORWARD_DELETE, - [Q_KEY_CODE_HOME] =3D ADB_KEY_HOME, - [Q_KEY_CODE_END] =3D ADB_KEY_END, - [Q_KEY_CODE_PGUP] =3D ADB_KEY_PAGE_UP, - [Q_KEY_CODE_PGDN] =3D ADB_KEY_PAGE_DOWN, - - [Q_KEY_CODE_POWER] =3D ADB_KEY_POWER -}; - -static void adb_kbd_put_keycode(void *opaque, int keycode) -{ - KBDState *s =3D opaque; - - if (s->count < sizeof(s->data)) { - s->data[s->wptr] =3D keycode; - if (++s->wptr =3D=3D sizeof(s->data)) - s->wptr =3D 0; - s->count++; - } -} - -static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf) -{ - KBDState *s =3D ADB_KEYBOARD(d); - int keycode; - int olen; - - olen =3D 0; - if (s->count =3D=3D 0) { - return 0; - } - keycode =3D s->data[s->rptr]; - s->rptr++; - if (s->rptr =3D=3D sizeof(s->data)) { - s->rptr =3D 0; - } - s->count--; - /* - * The power key is the only two byte value key, so it is a special ca= se. - * 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 =3D=3D 0x7f) { - obuf[0] =3D 0x7f; - obuf[1] =3D 0x7f; - olen =3D 2; - } else { - obuf[0] =3D 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] =3D 0xff; - olen =3D 2; - } - - return olen; -} - -static int adb_kbd_request(ADBDevice *d, uint8_t *obuf, - const uint8_t *buf, int len) -{ - KBDState *s =3D ADB_KEYBOARD(d); - int cmd, reg, olen; - - if ((buf[0] & 0x0f) =3D=3D ADB_FLUSH) { - /* flush keyboard fifo */ - s->wptr =3D s->rptr =3D s->count =3D 0; - return 0; - } - - cmd =3D buf[0] & 0xc; - reg =3D buf[0] & 0x3; - olen =3D 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 =3D buf[1] & 0xf; - break; - default: - d->devaddr =3D buf[1] & 0xf; - /* we support handlers: - * 1: Apple Standard Keyboard - * 2: Apple Extended Keyboard (LShift =3D RShift) - * 3: Apple Extended Keyboard (LShift !=3D RShift) - */ - if (buf[2] =3D=3D 1 || buf[2] =3D=3D 2 || buf[2] =3D=3D 3)= { - d->handler =3D buf[2]; - } - break; - } - } - break; - case ADB_READREG: - switch(reg) { - case 0: - olen =3D adb_kbd_poll(d, obuf); - break; - case 1: - break; - case 2: - obuf[0] =3D 0x00; /* XXX: check this */ - obuf[1] =3D 0x07; /* led status */ - olen =3D 2; - break; - case 3: - obuf[0] =3D d->handler; - obuf[1] =3D d->devaddr; - olen =3D 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 =3D (KBDState *)dev; - int qcode, keycode; - - qcode =3D qemu_input_key_value_to_qcode(evt->u.key.data->key); - if (qcode >=3D ARRAY_SIZE(qcode_to_adb_keycode)) { - return; - } - /* FIXME: take handler into account when translating qcode */ - keycode =3D qcode_to_adb_keycode[qcode]; - if (keycode =3D=3D NO_KEY) { /* We don't want to send this to the gue= st */ - ADB_DPRINTF("Ignoring NO_KEY\n"); - return; - } - if (evt->u.key.data->down =3D=3D false) { /* if key release event */ - keycode =3D keycode | 0x80; /* create keyboard break code */ - } - - adb_kbd_put_keycode(s, keycode); -} - -static const VMStateDescription vmstate_adb_kbd =3D { - .name =3D "adb_kbd", - .version_id =3D 2, - .minimum_version_id =3D 2, - .fields =3D (VMStateField[]) { - VMSTATE_STRUCT(parent_obj, KBDState, 0, vmstate_adb_device, ADBDev= ice), - 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 =3D ADB_DEVICE(dev); - KBDState *s =3D ADB_KEYBOARD(dev); - - d->handler =3D 1; - d->devaddr =3D ADB_DEVID_KEYBOARD; - memset(s->data, 0, sizeof(s->data)); - s->rptr =3D 0; - s->wptr =3D 0; - s->count =3D 0; -} - -static QemuInputHandler adb_keyboard_handler =3D { - .name =3D "QEMU ADB Keyboard", - .mask =3D INPUT_EVENT_MASK_KEY, - .event =3D adb_keyboard_event, -}; - -static void adb_kbd_realizefn(DeviceState *dev, Error **errp) -{ - ADBKeyboardClass *akc =3D 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 =3D ADB_DEVICE(obj); - - d->devaddr =3D ADB_DEVID_KEYBOARD; -} - -static void adb_kbd_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc =3D DEVICE_CLASS(oc); - ADBDeviceClass *adc =3D ADB_DEVICE_CLASS(oc); - ADBKeyboardClass *akc =3D ADB_KEYBOARD_CLASS(oc); - - akc->parent_realize =3D dc->realize; - dc->realize =3D adb_kbd_realizefn; - set_bit(DEVICE_CATEGORY_INPUT, dc->categories); - - adc->devreq =3D adb_kbd_request; - dc->reset =3D adb_kbd_reset; - dc->vmsd =3D &vmstate_adb_kbd; -} - -static const TypeInfo adb_kbd_type_info =3D { - .name =3D TYPE_ADB_KEYBOARD, - .parent =3D TYPE_ADB_DEVICE, - .instance_size =3D sizeof(KBDState), - .instance_init =3D adb_kbd_initfn, - .class_init =3D adb_kbd_class_init, - .class_size =3D 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 =3D opaque; - - s->dx +=3D dx1; - s->dy +=3D dy1; - s->dz +=3D dz1; - s->buttons_state =3D buttons_state; -} - - -static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf) -{ - MouseState *s =3D ADB_MOUSE(d); - int dx, dy; - - if (s->last_buttons_state =3D=3D s->buttons_state && - s->dx =3D=3D 0 && s->dy =3D=3D 0) - return 0; - - dx =3D s->dx; - if (dx < -63) - dx =3D -63; - else if (dx > 63) - dx =3D 63; - - dy =3D s->dy; - if (dy < -63) - dy =3D -63; - else if (dy > 63) - dy =3D 63; - - s->dx -=3D dx; - s->dy -=3D dy; - s->last_buttons_state =3D s->buttons_state; - - dx &=3D 0x7f; - dy &=3D 0x7f; - - if (!(s->buttons_state & MOUSE_EVENT_LBUTTON)) - dy |=3D 0x80; - if (!(s->buttons_state & MOUSE_EVENT_RBUTTON)) - dx |=3D 0x80; - - obuf[0] =3D dy; - obuf[1] =3D dx; - return 2; -} - -static int adb_mouse_request(ADBDevice *d, uint8_t *obuf, - const uint8_t *buf, int len) -{ - MouseState *s =3D ADB_MOUSE(d); - int cmd, reg, olen; - - if ((buf[0] & 0x0f) =3D=3D ADB_FLUSH) { - /* flush mouse fifo */ - s->buttons_state =3D s->last_buttons_state; - s->dx =3D 0; - s->dy =3D 0; - s->dz =3D 0; - return 0; - } - - cmd =3D buf[0] & 0xc; - reg =3D buf[0] & 0x3; - olen =3D 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 =3D buf[1] & 0xf; - break; - default: - d->devaddr =3D 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] =3D=3D 1 || buf[2] =3D=3D 2) { - d->handler =3D buf[2]; - } - break; - } - } - break; - case ADB_READREG: - switch(reg) { - case 0: - olen =3D adb_mouse_poll(d, obuf); - break; - case 1: - break; - case 3: - obuf[0] =3D d->handler; - obuf[1] =3D d->devaddr; - olen =3D 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 =3D ADB_DEVICE(dev); - MouseState *s =3D ADB_MOUSE(dev); - - d->handler =3D 2; - d->devaddr =3D ADB_DEVID_MOUSE; - s->last_buttons_state =3D s->buttons_state =3D 0; - s->dx =3D s->dy =3D s->dz =3D 0; -} - -static const VMStateDescription vmstate_adb_mouse =3D { - .name =3D "adb_mouse", - .version_id =3D 2, - .minimum_version_id =3D 2, - .fields =3D (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 =3D ADB_MOUSE(dev); - ADBMouseClass *amc =3D 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 =3D ADB_DEVICE(obj); - - d->devaddr =3D ADB_DEVID_MOUSE; -} - -static void adb_mouse_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc =3D DEVICE_CLASS(oc); - ADBDeviceClass *adc =3D ADB_DEVICE_CLASS(oc); - ADBMouseClass *amc =3D ADB_MOUSE_CLASS(oc); - - amc->parent_realize =3D dc->realize; - dc->realize =3D adb_mouse_realizefn; - set_bit(DEVICE_CATEGORY_INPUT, dc->categories); - - adc->devreq =3D adb_mouse_request; - dc->reset =3D adb_mouse_reset; - dc->vmsd =3D &vmstate_adb_mouse; -} - -static const TypeInfo adb_mouse_type_info =3D { - .name =3D TYPE_ADB_MOUSE, - .parent =3D TYPE_ADB_DEVICE, - .instance_size =3D sizeof(MouseState), - .instance_init =3D adb_mouse_initfn, - .class_init =3D adb_mouse_class_init, - .class_size =3D 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); } =20 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 =20 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; =20 /* buf =3D NULL means polling */ @@ -77,6 +101,8 @@ struct ADBBusState { int poll_index; }; =20 +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); --=20 2.14.3