aboutsummaryrefslogtreecommitdiff
path: root/hw/char
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2014-03-25 13:16:21 +0100
committerGerd Hoffmann <kraxel@redhat.com>2014-05-16 08:30:12 +0200
commit65e7545ea3c65a6468fb59418a6dbe66ef71d6d1 (patch)
tree4311c6751b7c475a070ae1d3a87006262919e5e0 /hw/char
parent2a766d294ae0d4d2e9b178ce0b9a966bc678e7e6 (diff)
input: switch sparc32 kbd to new input api
Nasty 0xe0 logic is gone. We map through QKeyCode now, giving us a nice, readable mapping table. Quick smoke test in OpenFirmware looks ok. Careful check from arch maintainers would be very nice, especially on the capslock and numlock logic. I'm not fully sure whenever I got it translated correctly and also what it is supposed to do in the first place ... Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw/char')
-rw-r--r--hw/char/escc.c229
1 files changed, 170 insertions, 59 deletions
diff --git a/hw/char/escc.c b/hw/char/escc.c
index 6397f6f282..823fe8dc68 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -27,6 +27,7 @@
#include "hw/char/escc.h"
#include "sysemu/char.h"
#include "ui/console.h"
+#include "ui/input.h"
#include "trace.h"
/*
@@ -94,6 +95,7 @@ typedef struct ChannelState {
ChnID chn; // this channel, A (base+4) or B (base+0)
ChnType type;
uint8_t rx, tx;
+ QemuInputHandlerState *hs;
} ChannelState;
#define ESCC(obj) OBJECT_CHECK(ESCCState, (obj), TYPE_ESCC)
@@ -714,71 +716,179 @@ MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB,
return &d->mmio;
}
-static const uint8_t keycodes[128] = {
- 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
- 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
- 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
- 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
- 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
- 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
- 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
- 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
+static const uint8_t qcode_to_keycode[Q_KEY_CODE_MAX] = {
+ [Q_KEY_CODE_SHIFT] = 99,
+ [Q_KEY_CODE_SHIFT_R] = 110,
+ [Q_KEY_CODE_ALT] = 19,
+ [Q_KEY_CODE_ALT_R] = 13,
+ [Q_KEY_CODE_ALTGR] = 13,
+ [Q_KEY_CODE_CTRL] = 76,
+ [Q_KEY_CODE_CTRL_R] = 76,
+ [Q_KEY_CODE_ESC] = 29,
+ [Q_KEY_CODE_1] = 30,
+ [Q_KEY_CODE_2] = 31,
+ [Q_KEY_CODE_3] = 32,
+ [Q_KEY_CODE_4] = 33,
+ [Q_KEY_CODE_5] = 34,
+ [Q_KEY_CODE_6] = 35,
+ [Q_KEY_CODE_7] = 36,
+ [Q_KEY_CODE_8] = 37,
+ [Q_KEY_CODE_9] = 38,
+ [Q_KEY_CODE_0] = 39,
+ [Q_KEY_CODE_MINUS] = 40,
+ [Q_KEY_CODE_EQUAL] = 41,
+ [Q_KEY_CODE_BACKSPACE] = 43,
+ [Q_KEY_CODE_TAB] = 53,
+ [Q_KEY_CODE_Q] = 54,
+ [Q_KEY_CODE_W] = 55,
+ [Q_KEY_CODE_E] = 56,
+ [Q_KEY_CODE_R] = 57,
+ [Q_KEY_CODE_T] = 58,
+ [Q_KEY_CODE_Y] = 59,
+ [Q_KEY_CODE_U] = 60,
+ [Q_KEY_CODE_I] = 61,
+ [Q_KEY_CODE_O] = 62,
+ [Q_KEY_CODE_P] = 63,
+ [Q_KEY_CODE_BRACKET_LEFT] = 64,
+ [Q_KEY_CODE_BRACKET_RIGHT] = 65,
+ [Q_KEY_CODE_RET] = 89,
+ [Q_KEY_CODE_A] = 77,
+ [Q_KEY_CODE_S] = 78,
+ [Q_KEY_CODE_D] = 79,
+ [Q_KEY_CODE_F] = 80,
+ [Q_KEY_CODE_G] = 81,
+ [Q_KEY_CODE_H] = 82,
+ [Q_KEY_CODE_J] = 83,
+ [Q_KEY_CODE_K] = 84,
+ [Q_KEY_CODE_L] = 85,
+ [Q_KEY_CODE_SEMICOLON] = 86,
+ [Q_KEY_CODE_APOSTROPHE] = 87,
+ [Q_KEY_CODE_GRAVE_ACCENT] = 42,
+ [Q_KEY_CODE_BACKSLASH] = 88,
+ [Q_KEY_CODE_Z] = 100,
+ [Q_KEY_CODE_X] = 101,
+ [Q_KEY_CODE_C] = 102,
+ [Q_KEY_CODE_V] = 103,
+ [Q_KEY_CODE_B] = 104,
+ [Q_KEY_CODE_N] = 105,
+ [Q_KEY_CODE_M] = 106,
+ [Q_KEY_CODE_COMMA] = 107,
+ [Q_KEY_CODE_DOT] = 108,
+ [Q_KEY_CODE_SLASH] = 109,
+ [Q_KEY_CODE_ASTERISK] = 47,
+ [Q_KEY_CODE_SPC] = 121,
+ [Q_KEY_CODE_CAPS_LOCK] = 119,
+ [Q_KEY_CODE_F1] = 5,
+ [Q_KEY_CODE_F2] = 6,
+ [Q_KEY_CODE_F3] = 8,
+ [Q_KEY_CODE_F4] = 10,
+ [Q_KEY_CODE_F5] = 12,
+ [Q_KEY_CODE_F6] = 14,
+ [Q_KEY_CODE_F7] = 16,
+ [Q_KEY_CODE_F8] = 17,
+ [Q_KEY_CODE_F9] = 18,
+ [Q_KEY_CODE_F10] = 7,
+ [Q_KEY_CODE_NUM_LOCK] = 98,
+ [Q_KEY_CODE_SCROLL_LOCK] = 23,
+ [Q_KEY_CODE_KP_DIVIDE] = 109,
+ [Q_KEY_CODE_KP_MULTIPLY] = 47,
+ [Q_KEY_CODE_KP_SUBTRACT] = 71,
+ [Q_KEY_CODE_KP_ADD] = 125,
+ [Q_KEY_CODE_KP_ENTER] = 90,
+ [Q_KEY_CODE_KP_DECIMAL] = 50,
+ [Q_KEY_CODE_KP_0] = 94,
+ [Q_KEY_CODE_KP_1] = 112,
+ [Q_KEY_CODE_KP_2] = 113,
+ [Q_KEY_CODE_KP_3] = 114,
+ [Q_KEY_CODE_KP_4] = 91,
+ [Q_KEY_CODE_KP_5] = 92,
+ [Q_KEY_CODE_KP_6] = 93,
+ [Q_KEY_CODE_KP_7] = 68,
+ [Q_KEY_CODE_KP_8] = 69,
+ [Q_KEY_CODE_KP_9] = 70,
+ [Q_KEY_CODE_LESS] = 124,
+ [Q_KEY_CODE_F11] = 9,
+ [Q_KEY_CODE_F12] = 11,
+ [Q_KEY_CODE_HOME] = 68,
+ [Q_KEY_CODE_PGUP] = 70,
+ [Q_KEY_CODE_PGDN] = 114,
+ [Q_KEY_CODE_END] = 112,
+ [Q_KEY_CODE_LEFT] = 91,
+ [Q_KEY_CODE_UP] = 69,
+ [Q_KEY_CODE_DOWN] = 113,
+ [Q_KEY_CODE_RIGHT] = 93,
+ [Q_KEY_CODE_INSERT] = 94,
+ [Q_KEY_CODE_DELETE] = 50,
+ [Q_KEY_CODE_STOP] = 1,
+ [Q_KEY_CODE_AGAIN] = 3,
+ [Q_KEY_CODE_PROPS] = 25,
+ [Q_KEY_CODE_UNDO] = 26,
+ [Q_KEY_CODE_FRONT] = 49,
+ [Q_KEY_CODE_COPY] = 52,
+ [Q_KEY_CODE_OPEN] = 72,
+ [Q_KEY_CODE_PASTE] = 73,
+ [Q_KEY_CODE_FIND] = 97,
+ [Q_KEY_CODE_CUT] = 99,
+ [Q_KEY_CODE_LF] = 111,
+ [Q_KEY_CODE_HELP] = 118,
+ [Q_KEY_CODE_META_L] = 120,
+ [Q_KEY_CODE_META_R] = 122,
+ [Q_KEY_CODE_COMPOSE] = 67,
};
-static const uint8_t e0_keycodes[128] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
- 113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0,
-};
-
-static void sunkbd_event(void *opaque, int ch)
+static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
+ InputEvent *evt)
{
- ChannelState *s = opaque;
- int release = ch & 0x80;
-
- trace_escc_sunkbd_event_in(ch);
- switch (ch) {
- case 58: // Caps lock press
- s->caps_lock_mode ^= 1;
- if (s->caps_lock_mode == 2)
- return; // Drop second press
- break;
- case 69: // Num lock press
- s->num_lock_mode ^= 1;
- if (s->num_lock_mode == 2)
- return; // Drop second press
- break;
- case 186: // Caps lock release
- s->caps_lock_mode ^= 2;
- if (s->caps_lock_mode == 3)
- return; // Drop first release
- break;
- case 197: // Num lock release
- s->num_lock_mode ^= 2;
- if (s->num_lock_mode == 3)
- return; // Drop first release
- break;
- case 0xe0:
- s->e0_mode = 1;
- return;
- default:
- break;
+ ChannelState *s = (ChannelState *)dev;
+ int qcode, keycode;
+
+ assert(evt->kind == INPUT_EVENT_KIND_KEY);
+ qcode = qemu_input_key_value_to_qcode(evt->key->key);
+ trace_escc_sunkbd_event_in(qcode, QKeyCode_lookup[qcode],
+ evt->key->down);
+
+ if (qcode == Q_KEY_CODE_CAPS_LOCK) {
+ if (evt->key->down) {
+ s->caps_lock_mode ^= 1;
+ if (s->caps_lock_mode == 2) {
+ return; /* Drop second press */
+ }
+ } else {
+ s->caps_lock_mode ^= 2;
+ if (s->caps_lock_mode == 3) {
+ return; /* Drop first release */
+ }
+ }
}
- if (s->e0_mode) {
- s->e0_mode = 0;
- ch = e0_keycodes[ch & 0x7f];
- } else {
- ch = keycodes[ch & 0x7f];
+
+ if (qcode == Q_KEY_CODE_NUM_LOCK) {
+ if (evt->key->down) {
+ s->num_lock_mode ^= 1;
+ if (s->num_lock_mode == 2) {
+ return; /* Drop second press */
+ }
+ } else {
+ s->num_lock_mode ^= 2;
+ if (s->num_lock_mode == 3) {
+ return; /* Drop first release */
+ }
+ }
+ }
+
+ keycode = qcode_to_keycode[qcode];
+ if (!evt->key->down) {
+ keycode |= 0x80;
}
- trace_escc_sunkbd_event_out(ch);
- put_queue(s, ch | release);
+ trace_escc_sunkbd_event_out(keycode);
+ put_queue(s, keycode);
}
+static QemuInputHandler sunkbd_handler = {
+ .name = "sun keyboard",
+ .mask = INPUT_EVENT_MASK_KEY,
+ .event = sunkbd_handle_event,
+};
+
static void handle_kbd_command(ChannelState *s, int val)
{
trace_escc_kbd_command(val);
@@ -898,7 +1008,8 @@ static int escc_init1(SysBusDevice *dev)
"QEMU Sun Mouse");
}
if (s->chn[1].type == kbd) {
- qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
+ s->chn[1].hs = qemu_input_handler_register((DeviceState *)(&s->chn[1]),
+ &sunkbd_handler);
}
return 0;