Skip to content

Commit

Permalink
input: switch sparc32 kbd to new input api
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
kraxel committed May 16, 2014
1 parent 2a766d2 commit 65e7545
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 61 deletions.
229 changes: 170 additions & 59 deletions hw/char/escc.c
Expand Up @@ -27,6 +27,7 @@
#include "hw/char/escc.h"
#include "sysemu/char.h"
#include "ui/console.h"
#include "ui/input.h"
#include "trace.h"

/*
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions trace-events
Expand Up @@ -862,8 +862,8 @@ escc_mem_writeb_data(char channel, uint32_t val) "Write channel %c, ch %d"
escc_mem_readb_ctrl(char channel, uint32_t reg, uint8_t val) "Read channel %c, reg[%d] = %2.2x"
escc_mem_readb_data(char channel, uint32_t ret) "Read channel %c, ch %d"
escc_serial_receive_byte(char channel, int ch) "channel %c put ch %d"
escc_sunkbd_event_in(int ch) "Untranslated keycode %2.2x"
escc_sunkbd_event_out(int ch) "Translated keycode %2.2x"
escc_sunkbd_event_in(int ch, const char *name, int down) "QKeyCode 0x%2.2x [%s], down %d"
escc_sunkbd_event_out(int ch) "Translated keycode 0x%2.2x"
escc_kbd_command(int val) "Command %d"
escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=%01x"

Expand Down

0 comments on commit 65e7545

Please sign in to comment.