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,6 +95,7 @@ typedef struct ChannelState {
95 uint8_t rx, tx, wregs[16], rregs[16]; 95 uint8_t rx, tx, wregs[16], rregs[16];
96 SERIOQueue queue; 96 SERIOQueue queue;
97 CharDriverState *chr; 97 CharDriverState *chr;
  98 + int e0_mode, led_mode;
98 } ChannelState; 99 } ChannelState;
99 100
100 struct SerialState { 101 struct SerialState {
@@ -194,6 +195,7 @@ static void slavio_serial_reset_chn(ChannelState *s) @@ -194,6 +195,7 @@ static void slavio_serial_reset_chn(ChannelState *s)
194 s->rx = s->tx = 0; 195 s->rx = s->tx = 0;
195 s->rxint = s->txint = 0; 196 s->rxint = s->txint = 0;
196 s->rxint_under_svc = s->txint_under_svc = 0; 197 s->rxint_under_svc = s->txint_under_svc = 0;
  198 + s->e0_mode = s->led_mode = 0;
197 clear_queue(s); 199 clear_queue(s);
198 } 200 }
199 201
@@ -632,30 +634,59 @@ static const uint8_t keycodes[128] = { @@ -632,30 +634,59 @@ static const uint8_t keycodes[128] = {
632 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67, 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 static void sunkbd_event(void *opaque, int ch) 648 static void sunkbd_event(void *opaque, int ch)
636 { 649 {
637 ChannelState *s = opaque; 650 ChannelState *s = opaque;
638 int release = ch & 0x80; 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 put_queue(s, ch | release); 665 put_queue(s, ch | release);
643 } 666 }
644 667
645 static void handle_kbd_command(ChannelState *s, int val) 668 static void handle_kbd_command(ChannelState *s, int val)
646 { 669 {
647 KBD_DPRINTF("Command %d\n", val); 670 KBD_DPRINTF("Command %d\n", val);
  671 + if (s->led_mode) { // Ignore led byte
  672 + s->led_mode = 0;
  673 + return;
  674 + }
648 switch (val) { 675 switch (val) {
649 case 1: // Reset, return type code 676 case 1: // Reset, return type code
650 clear_queue(s); 677 clear_queue(s);
651 put_queue(s, 0xff); 678 put_queue(s, 0xff);
652 put_queue(s, 4); // Type 4 679 put_queue(s, 4); // Type 4
  680 + put_queue(s, 0x7f);
653 break; 681 break;
  682 + case 0xe: // Set leds
  683 + s->led_mode = 1;
  684 + break;
654 case 7: // Query layout 685 case 7: // Query layout
655 case 0xf: 686 case 0xf:
656 clear_queue(s); 687 clear_queue(s);
657 put_queue(s, 0xfe); 688 put_queue(s, 0xfe);
658 - put_queue(s, 19); // XXX, layout? 689 + put_queue(s, 0); // XXX, layout?
659 break; 690 break;
660 default: 691 default:
661 break; 692 break;