[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