143 lines
4.6 KiB
C++
143 lines
4.6 KiB
C++
#include "keyboard_input.h"
|
|
#include <stdio.h>
|
|
|
|
static const uint8_t keycode2ascii[128][2] = {
|
|
{0, 0}, /* 0x00 */
|
|
{0, 0}, /* 0x01 */
|
|
{0, 0}, /* 0x02 */
|
|
{0, 0}, /* 0x03 */
|
|
{'a', 'A'}, /* 0x04 */
|
|
{'b', 'B'}, /* 0x05 */
|
|
{'c', 'C'}, /* 0x06 */
|
|
{'d', 'D'}, /* 0x07 */
|
|
{'e', 'E'}, /* 0x08 */
|
|
{'f', 'F'}, /* 0x09 */
|
|
{'g', 'G'}, /* 0x0a */
|
|
{'h', 'H'}, /* 0x0b */
|
|
{'i', 'I'}, /* 0x0c */
|
|
{'j', 'J'}, /* 0x0d */
|
|
{'k', 'K'}, /* 0x0e */
|
|
{'l', 'L'}, /* 0x0f */
|
|
{'m', 'M'}, /* 0x10 */
|
|
{'n', 'N'}, /* 0x11 */
|
|
{'o', 'O'}, /* 0x12 */
|
|
{'p', 'P'}, /* 0x13 */
|
|
{'q', 'Q'}, /* 0x14 */
|
|
{'r', 'R'}, /* 0x15 */
|
|
{'s', 'S'}, /* 0x16 */
|
|
{'t', 'T'}, /* 0x17 */
|
|
{'u', 'U'}, /* 0x18 */
|
|
{'v', 'V'}, /* 0x19 */
|
|
{'w', 'W'}, /* 0x1a */
|
|
{'x', 'X'}, /* 0x1b */
|
|
{'y', 'Y'}, /* 0x1c */
|
|
{'z', 'Z'}, /* 0x1d */
|
|
{'1', '!'}, /* 0x1e */
|
|
{'2', '@'}, /* 0x1f */
|
|
{'3', '#'}, /* 0x20 */
|
|
{'4', '$'}, /* 0x21 */
|
|
{'5', '%'}, /* 0x22 */
|
|
{'6', '^'}, /* 0x23 */
|
|
{'7', '&'}, /* 0x24 */
|
|
{'8', '*'}, /* 0x25 */
|
|
{'9', '('}, /* 0x26 */
|
|
{'0', ')'}, /* 0x27 */
|
|
{'\r', '\r'}, /* 0x28 ENTER */
|
|
{'\x1b', '\x1b'}, /* 0x29 ESCAPE */
|
|
{'\b', '\b'}, /* 0x2a BACKSPACE */
|
|
{'\t', '\t'}, /* 0x2b TAB */
|
|
{' ', ' '}, /* 0x2c SPACE */
|
|
{'-', '_'}, /* 0x2d MINUS */
|
|
{'=', '+'}, /* 0x2e EQUAL */
|
|
{'[', '{'}, /* 0x2f BRACKET_LEFT */
|
|
{']', '}'}, /* 0x30 BRACKET_RIGHT */
|
|
{'\\', '|'}, /* 0x31 BACKSLASH */
|
|
{'#', '~'}, /* 0x32 EUROPE_1 */
|
|
{';', ':'}, /* 0x33 SEMICOLON */
|
|
{'\'', '\"'}, /* 0x34 APOSTROPHE */
|
|
{'`', '~'}, /* 0x35 GRAVE */
|
|
{',', '<'}, /* 0x36 COMMA */
|
|
{'.', '>'}, /* 0x37 PERIOD */
|
|
{'/', '?'}, /* 0x38 SLASH */
|
|
{0, 0}, /* 0x39 CAPS_LOCK */
|
|
{0, 0}, /* 0x3a F1 */
|
|
{0, 0}, /* 0x3b F2 */
|
|
{0, 0}, /* 0x3c F3 */
|
|
{0, 0}, /* 0x3d F4 */
|
|
{0, 0}, /* 0x3e F5 */
|
|
{0, 0}, /* 0x3f F6 */
|
|
{0, 0}, /* 0x40 F7 */
|
|
{0, 0}, /* 0x41 F8 */
|
|
{0, 0}, /* 0x42 F9 */
|
|
{0, 0}, /* 0x43 F10 */
|
|
{0, 0}, /* 0x44 F11 */
|
|
{0, 0}, /* 0x45 F12 */
|
|
{0, 0}, /* 0x46 PRINT_SCREEN */
|
|
{0, 0}, /* 0x47 SCROLL_LOCK */
|
|
{0, 0}, /* 0x48 PAUSE */
|
|
{0, 0}, /* 0x49 INSERT */
|
|
{0, 0}, /* 0x4a HOME */
|
|
{0, 0}, /* 0x4b PAGE_UP */
|
|
{0, 0}, /* 0x4c DELETE */
|
|
{0, 0}, /* 0x4d END */
|
|
{0, 0}, /* 0x4e PAGE_DOWN */
|
|
{0, 0}, /* 0x4f RIGHT_ARROW */
|
|
{0, 0}, /* 0x50 LEFT_ARROW */
|
|
{0, 0}, /* 0x51 DOWN_ARROW */
|
|
{0, 0}, /* 0x52 UP_ARROW */
|
|
{0, 0}, /* 0x53 NUM_LOCK */
|
|
{'/', '/'}, /* 0x54 KP_DIVIDE */
|
|
{'*', '*'}, /* 0x55 KP_MULTIPLY */
|
|
{'-', '-'}, /* 0x56 KP_MINUS */
|
|
{'+', '+'}, /* 0x57 KP_PLUS */
|
|
{'\r', '\r'}, /* 0x58 KP_ENTER */
|
|
{'1', '1'}, /* 0x59 KP_1 */
|
|
{'2', '2'}, /* 0x5a KP_2 */
|
|
{'3', '3'}, /* 0x5b KP_3 */
|
|
{'4', '4'}, /* 0x5c KP_4 */
|
|
{'5', '5'}, /* 0x5d KP_5 */
|
|
{'6', '6'}, /* 0x5e KP_6 */
|
|
{'7', '7'}, /* 0x5f KP_7 */
|
|
{'8', '8'}, /* 0x60 KP_8 */
|
|
{'9', '9'}, /* 0x61 KP_9 */
|
|
{'0', '0'}, /* 0x62 KP_0 */
|
|
{'.', '.'}, /* 0x63 KP_DECIMAL */
|
|
};
|
|
|
|
static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8_t keycode) {
|
|
for(uint8_t i=0; i<6; i++) {
|
|
if (report->keycode[i] == keycode) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool parse_keyboard_report(hid_keyboard_report_t const *report, KeyEvent* result) {
|
|
static hid_keyboard_report_t prev_report = { 0, 0, {0} };
|
|
bool event_found = false;
|
|
|
|
for(uint8_t i=0; i<6; i++) {
|
|
if (report->keycode[i]) {
|
|
if (find_key_in_report(&prev_report, report->keycode[i])) {
|
|
// exist in previous report means the current key is holding
|
|
} else {
|
|
// not existed in previous report means the current key is pressed
|
|
bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT);
|
|
uint8_t ch = keycode2ascii[report->keycode[i]][is_shift ? 1 : 0];
|
|
|
|
if (ch) {
|
|
result->ascii = ch;
|
|
result->is_enter = (ch == '\r' || ch == '\n');
|
|
result->is_backspace = (ch == '\b' || ch == 127);
|
|
result->is_printable = !result->is_enter && !result->is_backspace;
|
|
event_found = true;
|
|
// We only process one key event per report for simplicity in this refactor
|
|
// Ideally we might want to queue them if multiple keys are pressed at once
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
prev_report = *report;
|
|
return event_found;
|
|
}
|