[U-Boot] [PATCH 2/2] usb: kbd: implement special keys
Heinrich Schuchardt
xypron.glpk at gmx.de
Thu Feb 22 12:04:18 UTC 2018
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 at 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
More information about the U-Boot
mailing list