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.g...@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;
-- 
2.14.2

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to