Commit 43febf49523552ca678eacc2677d3bac58cda4c0

Authored by blueswir1
1 parent 9706285b

Improve keyboard handling


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3204 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 34 additions and 3 deletions
hw/slavio_serial.c
... ... @@ -95,6 +95,7 @@ typedef struct ChannelState {
95 95 uint8_t rx, tx, wregs[16], rregs[16];
96 96 SERIOQueue queue;
97 97 CharDriverState *chr;
  98 + int e0_mode, led_mode;
98 99 } ChannelState;
99 100  
100 101 struct SerialState {
... ... @@ -194,6 +195,7 @@ static void slavio_serial_reset_chn(ChannelState *s)
194 195 s->rx = s->tx = 0;
195 196 s->rxint = s->txint = 0;
196 197 s->rxint_under_svc = s->txint_under_svc = 0;
  198 + s->e0_mode = s->led_mode = 0;
197 199 clear_queue(s);
198 200 }
199 201  
... ... @@ -632,30 +634,59 @@ static const uint8_t keycodes[128] = {
632 634 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
633 635 };
634 636  
  637 +static const uint8_t e0_keycodes[128] = {
  638 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  639 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
  640 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  641 + 0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
  642 + 0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
  643 + 113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  644 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  645 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  646 +};
  647 +
635 648 static void sunkbd_event(void *opaque, int ch)
636 649 {
637 650 ChannelState *s = opaque;
638 651 int release = ch & 0x80;
639 652  
640   - ch = keycodes[ch & 0x7f];
641   - KBD_DPRINTF("Keycode %d (%s)\n", ch, release? "release" : "press");
  653 + KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" : "press");
  654 + if (ch == 0xe0) {
  655 + s->e0_mode = 1;
  656 + return;
  657 + }
  658 + if (s->e0_mode) {
  659 + s->e0_mode = 0;
  660 + ch = e0_keycodes[ch & 0x7f];
  661 + } else {
  662 + ch = keycodes[ch & 0x7f];
  663 + }
  664 + KBD_DPRINTF("Translated keycode %2.2x\n", ch);
642 665 put_queue(s, ch | release);
643 666 }
644 667  
645 668 static void handle_kbd_command(ChannelState *s, int val)
646 669 {
647 670 KBD_DPRINTF("Command %d\n", val);
  671 + if (s->led_mode) { // Ignore led byte
  672 + s->led_mode = 0;
  673 + return;
  674 + }
648 675 switch (val) {
649 676 case 1: // Reset, return type code
650 677 clear_queue(s);
651 678 put_queue(s, 0xff);
652 679 put_queue(s, 4); // Type 4
  680 + put_queue(s, 0x7f);
653 681 break;
  682 + case 0xe: // Set leds
  683 + s->led_mode = 1;
  684 + break;
654 685 case 7: // Query layout
655 686 case 0xf:
656 687 clear_queue(s);
657 688 put_queue(s, 0xfe);
658   - put_queue(s, 19); // XXX, layout?
  689 + put_queue(s, 0); // XXX, layout?
659 690 break;
660 691 default:
661 692 break;
... ...