Improve keyboard handling

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3204 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
blueswir1 2007-09-21 19:09:35 +00:00
parent 9706285b78
commit 43febf4952
1 changed files with 34 additions and 3 deletions

View File

@ -95,6 +95,7 @@ typedef struct ChannelState {
uint8_t rx, tx, wregs[16], rregs[16]; uint8_t rx, tx, wregs[16], rregs[16];
SERIOQueue queue; SERIOQueue queue;
CharDriverState *chr; CharDriverState *chr;
int e0_mode, led_mode;
} ChannelState; } ChannelState;
struct SerialState { struct SerialState {
@ -194,6 +195,7 @@ static void slavio_serial_reset_chn(ChannelState *s)
s->rx = s->tx = 0; s->rx = s->tx = 0;
s->rxint = s->txint = 0; s->rxint = s->txint = 0;
s->rxint_under_svc = s->txint_under_svc = 0; s->rxint_under_svc = s->txint_under_svc = 0;
s->e0_mode = s->led_mode = 0;
clear_queue(s); clear_queue(s);
} }
@ -632,30 +634,59 @@ static const uint8_t keycodes[128] = {
0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67, 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 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,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
static void sunkbd_event(void *opaque, int ch) static void sunkbd_event(void *opaque, int ch)
{ {
ChannelState *s = opaque; ChannelState *s = opaque;
int release = ch & 0x80; int release = ch & 0x80;
ch = keycodes[ch & 0x7f]; KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" : "press");
KBD_DPRINTF("Keycode %d (%s)\n", ch, release? "release" : "press"); if (ch == 0xe0) {
s->e0_mode = 1;
return;
}
if (s->e0_mode) {
s->e0_mode = 0;
ch = e0_keycodes[ch & 0x7f];
} else {
ch = keycodes[ch & 0x7f];
}
KBD_DPRINTF("Translated keycode %2.2x\n", ch);
put_queue(s, ch | release); put_queue(s, ch | release);
} }
static void handle_kbd_command(ChannelState *s, int val) static void handle_kbd_command(ChannelState *s, int val)
{ {
KBD_DPRINTF("Command %d\n", val); KBD_DPRINTF("Command %d\n", val);
if (s->led_mode) { // Ignore led byte
s->led_mode = 0;
return;
}
switch (val) { switch (val) {
case 1: // Reset, return type code case 1: // Reset, return type code
clear_queue(s); clear_queue(s);
put_queue(s, 0xff); put_queue(s, 0xff);
put_queue(s, 4); // Type 4 put_queue(s, 4); // Type 4
put_queue(s, 0x7f);
break; break;
case 0xe: // Set leds
s->led_mode = 1;
break;
case 7: // Query layout case 7: // Query layout
case 0xf: case 0xf:
clear_queue(s); clear_queue(s);
put_queue(s, 0xfe); put_queue(s, 0xfe);
put_queue(s, 19); // XXX, layout? put_queue(s, 0); // XXX, layout?
break; break;
default: default:
break; break;