
Correct support for arrow keys: use the standard xterm escape sequences.
Provide support for F1-F12, Insert, Delete, Home, End, Page Up, Page Down.
Signed-off-by: Heinrich Schuchardt xypron.glpk@gmx.de --- common/usb_kbd.c | 121 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 90 insertions(+), 31 deletions(-)
diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 706cc350a6..e8adccf219 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -75,12 +75,13 @@ static const unsigned char usb_kbd_num_keypad[] = { };
/* - * map arrow keys to ^F/^B ^N/^P, can't really use the proper - * ANSI sequence for arrow keys because the queuing code breaks - * when a single keypress expands to 3 queue elements + * map arrow keys to CSI A..D */ static const unsigned char usb_kbd_arrow[] = { - 0x6, 0x2, 0xe, 0x10 + 'C', /* 0x4f, right */ + 'D', /* 0x50, left */ + 'B', /* 0x51, down */ + 'A', /* 0x52, up */ };
/* @@ -175,7 +176,9 @@ static void usb_kbd_setled(struct usb_device *dev) static int usb_kbd_translate(struct usb_kbd_pdata *data, unsigned char scancode, unsigned char modifier, int pressed) { - uint8_t keycode = 0; + uint8_t keycode[8] = {0}; + int i; + int len = 1;
/* Key released */ if (pressed == 0) { @@ -191,41 +194,96 @@ static int usb_kbd_translate(struct usb_kbd_pdata *data, unsigned char scancode, data->repeat_delay = REPEAT_DELAY; }
- /* Alphanumeric values */ - if ((scancode > 3) && (scancode <= 0x1d)) { - keycode = scancode - 4 + 'a'; + if (data->flags & USB_KBD_CTRL) { + keycode[0] = scancode - 0x3; + } else if ((scancode > 3) && (scancode <= 0x1d)) { + /* Alphanumeric values */ + keycode[0] = scancode - 4 + 'a';
if (data->flags & USB_KBD_CAPSLOCK) - keycode &= ~CAPITAL_MASK; + keycode[0] &= ~CAPITAL_MASK;
if (modifier & (LEFT_SHIFT | RIGHT_SHIFT)) { /* Handle CAPSLock + Shift pressed simultaneously */ - if (keycode & CAPITAL_MASK) - keycode &= ~CAPITAL_MASK; + if (keycode[0] & CAPITAL_MASK) + keycode[0] &= ~CAPITAL_MASK; else - keycode |= CAPITAL_MASK; + keycode[0] |= CAPITAL_MASK; } - } - - if ((scancode > 0x1d) && (scancode < 0x39)) { + } else if ((scancode >= 0x1e) && (scancode <= 0x38)) { /* Shift pressed */ if (modifier & (LEFT_SHIFT | RIGHT_SHIFT)) - keycode = usb_kbd_numkey_shifted[scancode - 0x1e]; + keycode[0] = usb_kbd_numkey_shifted[scancode - 0x1e]; else - keycode = usb_kbd_numkey[scancode - 0x1e]; + keycode[0] = usb_kbd_numkey[scancode - 0x1e]; + } else if ((scancode >= 0x3a) && (scancode <= 0x3d)) { + /* F1 - F4 */ + keycode[0] = 0x1b; + keycode[1] = 'O'; + keycode[2] = scancode - 0x3a + 'P'; + len = 3; + } else if ((scancode >= 0x3e) && (scancode <= 0x45)) { + /* F5 - F12 */ + keycode[0] = 0x1b; + keycode[1] = '['; + if (scancode <= 0x41) { + keycode[2] = '1'; + if (scancode == 0x3e) + /* F5 */ + keycode[3] = '5'; + else + /* F6 - F7 */ + keycode[3] = scancode - 0x3f + '7'; + } else { + keycode[2] = '2'; + if (scancode <= 0x43) + /* F9, F10 */ + keycode[3] = scancode - 0x42 + '0'; + else + /* F11, F12 */ + keycode[3] = scancode - 0x44 + '3'; + } + keycode[4] = '~'; + len = 5; + } else if ((scancode >= 0x49) && (scancode <= 0x4e)) { + /* Insert, Home, Page Up, Delete, End, Page Down */ + len = 4; + keycode[0] = 0x1b; + keycode[1] = '['; + keycode[3] = '~'; + switch (scancode) { + case 0x49: /* Insert */ + keycode[2] = '2'; + break; + case 0x4a: /* Home */ + keycode[2] = 'H'; + len = 3; + break; + case 0x4b: /* Page Up */ + keycode[2] = '5'; + break; + case 0x4c: /* Delete */ + keycode[2] = '3'; + break; + case 0x4d: /* End */ + keycode[2] = 'F'; + len = 3; + break; + case 0x4e: /* Page Down */ + keycode[2] = '6'; + break; + } + } else if ((scancode >= 0x4f) && (scancode <= 0x52)) { + /* Arrow keys */ + keycode[0] = 0x1b; + keycode[1] = '['; + keycode[2] = usb_kbd_arrow[scancode - 0x4f]; + len = 3; + } else if ((scancode >= 0x54) && (scancode <= 0x67)) { + /* Numeric keypad */ + keycode[0] = usb_kbd_num_keypad[scancode - 0x54]; }
- /* Arrow keys */ - if ((scancode >= 0x4f) && (scancode <= 0x52)) - keycode = usb_kbd_arrow[scancode - 0x4f]; - - /* Numeric keypad */ - if ((scancode >= 0x54) && (scancode <= 0x67)) - keycode = usb_kbd_num_keypad[scancode - 0x54]; - - if (data->flags & USB_KBD_CTRL) - keycode = scancode - 0x3; - if (pressed == 1) { if (scancode == NUM_LOCK) { data->flags ^= USB_KBD_NUMLOCK; @@ -243,9 +301,10 @@ static int usb_kbd_translate(struct usb_kbd_pdata *data, unsigned char scancode, }
/* Report keycode if any */ - if (keycode) { - debug("%c", keycode); - usb_kbd_put_queue(data, &keycode, 1); + if (keycode[0]) { + for (i = 0; i < len; ++i) + debug("%02x ", (unsigned int)keycode); + usb_kbd_put_queue(data, keycode, len); }
return 0;