blob: cccbe93db1d7dc2354565a708857764683f6ee0b [file] [log] [blame]
/*
* Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#define VK_MAX_ENUM 0xFF
#define PS2_MAX_KEYCODES_BASIC 0xFF
#define KEYBOARD_KEY_DEBUG false
typedef struct keycode_info {
int16_t ch;
int16_t uppercase;
int16_t ctrlchar;
} keycode_info_t;
typedef struct keycode_state {
bool keystate[VK_MAX_ENUM];
bool scroll_lock;
bool num_lock;
bool caps_lock;
bool led_state_changed;
/* Optional callback, called when a vkey has been pressed or released. */
void (*handle_keyevent_callback)(int16_t vkey, bool pressed, void *cookie);
/* Optional callback, called when a character has been typed. */
void (*handle_chartyped_callback)(int c, void *cookie);
/* Optional callback, called when num/scroll/caps lock LED state has changed. */
void (*handle_led_state_changed_callback)(void *cookie);
} keycode_state_t;
/* ref:
http://nehe.gamedev.net/article/msdn_virtualkey_codes/15009/
http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx
*/
enum virtual_keycode_enum {
VK_LBUTTON = 0x1 , /* Left mouse button */
VK_RBUTTON = 0x2 , /* Right mouse button */
VK_CANCEL = 0x3 , /* Control-break processing */
VK_MBUTTON = 0x4 , /* Middle mouse button (three-button mouse) */
VK_XBUTTON1 = 0x5 , /* X1 mouse button */
VK_XBUTTON2 = 0x6 , /* X2 mouse button */
VK_BACK = 0x8 , /* BACKSPACE key */
VK_TAB = 0x9 , /* TAB key */
VK_CLEAR = 0x0C, /* CLEAR key */
VK_RETURN = 0x0D, /* ENTER key */
VK_CONTROL = 0x11, /* CTRL key */
VK_SHIFT = 0x10, /* SHIFT key */
VK_MENU = 0x12, /* ALT key */
VK_PAUSE = 0x13, /* PAUSE key */
VK_CAPITAL = 0x14, /* CAPS LOCK key */
VK_KANA = 0x15, /* IME Kana mode */
VK_HANGUEL = 0x15, /* IME Hanguel mode (maintained for compatibility; use VK_HANGUL) */
VK_HANGUL = 0x15, /* IME Hangul mode */
VK_JUNJA = 0x17, /* IME Junja mode */
VK_FINAL = 0x18, /* IME final mode */
VK_HANJA = 0x19, /* IME Hanja mode */
VK_KANJI = 0x19, /* IME Kanji mode */
VK_ESCAPE = 0x1B, /* ESC key */
VK_CONVERT = 0x1C, /* IME convert */
VK_NONCONVERT = 0x1D, /* IME nonconvert */
VK_ACCEPT = 0x1E, /* IME accept */
VK_MODECHANGE = 0x1F, /* IME mode change request */
VK_SPACE = 0x20, /* SPACEBAR */
VK_PRIOR = 0x21, /* PAGE UP key */
VK_NEXT = 0x22, /* PAGE DOWN key */
VK_END = 0x23, /* END key */
VK_HOME = 0x24, /* HOME key */
VK_LEFT = 0x25, /* LEFT ARROW key */
VK_UP = 0x26, /* UP ARROW key */
VK_RIGHT = 0x27, /* RIGHT ARROW key */
VK_DOWN = 0x28, /* DOWN ARROW key */
VK_SELECT = 0x29, /* SELECT key */
VK_PRINT = 0x2A, /* PRINT key */
VK_EXECUTE = 0x2B, /* EXECUTE key */
VK_SNAPSHOT = 0x2C, /* PRINT SCREEN key */
VK_INSERT = 0x2D, /* INS key */
VK_DELETE = 0x2E, /* DEL key */
VK_HELP = 0x2F, /* HELP key */
VK_0 = 0x30, /* 0 key */
VK_1 = 0x31, /* 1 key */
VK_2 = 0x32, /* 2 key */
VK_3 = 0x33, /* 3 key */
VK_4 = 0x34, /* 4 key */
VK_5 = 0x35, /* 5 key */
VK_6 = 0x36, /* 6 key */
VK_7 = 0x37, /* 7 key */
VK_8 = 0x38, /* 8 key */
VK_9 = 0x39, /* 9 key */
VK_A = 0x41, /* A key */
VK_B = 0x42, /* B key */
VK_C = 0x43, /* C key */
VK_D = 0x44, /* D key */
VK_E = 0x45, /* E key */
VK_F = 0x46, /* F key */
VK_G = 0x47, /* G key */
VK_H = 0x48, /* H key */
VK_I = 0x49, /* I key */
VK_J = 0x4A, /* J key */
VK_K = 0x4B, /* K key */
VK_L = 0x4C, /* L key */
VK_M = 0x4D, /* M key */
VK_N = 0x4E, /* N key */
VK_O = 0x4F, /* O key */
VK_P = 0x50, /* P key */
VK_Q = 0x51, /* Q key */
VK_R = 0x52, /* R key */
VK_S = 0x53, /* S key */
VK_T = 0x54, /* T key */
VK_U = 0x55, /* U key */
VK_V = 0x56, /* V key */
VK_W = 0x57, /* W key */
VK_X = 0x58, /* X key */
VK_Y = 0x59, /* Y key */
VK_Z = 0x5A, /* Z key */
VK_LWIN = 0x5B, /* Left Windows key (Microsoft Natural Keyboard) */
VK_RWIN = 0x5C, /* Right Windows key (Microsoft Natural Keyboard) */
VK_APPS = 0x5D, /* Applications key (Microsoft Natural Keyboard) */
VK_SLEEP = 0x5F, /* Computer Sleep key */
VK_NUMPAD0 = 0x60, /* Numeric keypad 0 key */
VK_NUMPAD1 = 0x61, /* Numeric keypad 1 key */
VK_NUMPAD2 = 0x62, /* Numeric keypad 2 key */
VK_NUMPAD3 = 0x63, /* Numeric keypad 3 key */
VK_NUMPAD4 = 0x64, /* Numeric keypad 4 key */
VK_NUMPAD5 = 0x65, /* Numeric keypad 5 key */
VK_NUMPAD6 = 0x66, /* Numeric keypad 6 key */
VK_NUMPAD7 = 0x67, /* Numeric keypad 7 key */
VK_NUMPAD8 = 0x68, /* Numeric keypad 8 key */
VK_NUMPAD9 = 0x69, /* Numeric keypad 9 key */
VK_MULTIPLY = 0x6A, /* Multiply key */
VK_ADD = 0x6B, /* Add key */
VK_SEPARATOR = 0x6C, /* Separator key */
VK_SUBTRACT = 0x6D, /* Subtract key */
VK_DECIMAL = 0x6E, /* Decimal key */
VK_DIVIDE = 0x6F, /* Divide key */
VK_F1 = 0x70, /* F1 key */
VK_F2 = 0x71, /* F2 key */
VK_F3 = 0x72, /* F3 key */
VK_F4 = 0x73, /* F4 key */
VK_F5 = 0x74, /* F5 key */
VK_F6 = 0x75, /* F6 key */
VK_F7 = 0x76, /* F7 key */
VK_F8 = 0x77, /* F8 key */
VK_F9 = 0x78, /* F9 key */
VK_F10 = 0x79, /* F10 key */
VK_F11 = 0x7A, /* F11 key */
VK_F12 = 0x7B, /* F12 key */
VK_F13 = 0x7C, /* F13 key */
VK_F14 = 0x7D, /* F14 key */
VK_F15 = 0x7E, /* F15 key */
VK_F16 = 0x7F, /* F16 key */
VK_F17 = 0x80, /* F17 key */
VK_F18 = 0x81, /* F18 key */
VK_F19 = 0x82, /* F19 key */
VK_F20 = 0x83, /* F20 key */
VK_F21 = 0x84, /* F21 key */
VK_F22 = 0x85, /* F22 key */
VK_F23 = 0x86, /* F23 key */
VK_F24 = 0x87, /* F24 key */
VK_NUMLOCK = 0x90, /* NUM LOCK key */
VK_SCROLL = 0x91, /* SCROLL LOCK key */
VK_LSHIFT = 0xA0, /* Left SHIFT key */
VK_RSHIFT = 0xA1, /* Right SHIFT key */
VK_LCONTROL = 0xA2, /* Left CONTROL key */
VK_RCONTROL = 0xA3, /* Right CONTROL key */
VK_LMENU = 0xA4, /* Left MENU key */
VK_RMENU = 0xA5, /* Right MENU key */
VK_BROWSER_BACK = 0xA6, /* Browser Back key */
VK_BROWSER_FORWARD = 0xA7, /* Browser Forward key */
VK_BROWSER_REFRESH = 0xA8, /* Browser Refresh key */
VK_BROWSER_STOP = 0xA9, /* Browser Stop key */
VK_BROWSER_SEARCH = 0xAA, /* Browser Search key */
VK_BROWSER_FAVORITES = 0xAB, /* Browser Favorites key */
VK_BROWSER_HOME = 0xAC, /* Browser Launch and Home key */
VK_VOLUME_MUTE = 0xAD, /* Volume Mute key */
VK_VOLUME_DOWN = 0xAE, /* Volume Down key */
VK_VOLUME_UP = 0xAF, /* Volume Up key */
VK_MEDIA_NEXT_TRACK = 0xB0, /* Next Track key */
VK_MEDIA_PREV_TRACK = 0xB1, /* Previous Track key */
VK_MEDIA_STOP = 0xB2, /* Stop Media key */
VK_MEDIA_PLAY_PAUSE = 0xB3, /* Play/Pause Media key */
VK_LAUNCH_MAIL = 0xB4, /* Launch Mail key */
VK_LAUNCH_MEDIA_SELECT = 0xB5, /* Select Media key */
VK_LAUNCH_APP1 = 0xB6, /* Launch Application 1 key */
VK_LAUNCH_APP2 = 0xB7, /* Launch Application 2 key */
VK_OEM_1 = 0xBA, /* For the US standard keyboard, the ';:' key */
VK_OEM_PLUS = 0xBB, /* For any country/region, the '+' key */
VK_OEM_COMMA = 0xBC, /* For any country/region, the ',' key */
VK_OEM_MINUS = 0xBD, /* For any country/region, the '-' key */
VK_OEM_PERIOD = 0xBE, /* For any country/region, the '.' key */
VK_OEM_2 = 0xBF, /* For the US standard keyboard, the '/?' key */
VK_OEM_3 = 0xC0, /* For the US standard keyboard, the '`~' key */
VK_OEM_4 = 0xDB, /* For the US standard keyboard, the '[{' key */
VK_OEM_5 = 0xDC, /* For the US standard keyboard, the '\|' key */
VK_OEM_6 = 0xDD, /* For the US standard keyboard, the ']}' key */
VK_OEM_7 = 0xDE, /* For the US standard keyboard, the 'single-quote/double-quote' key */
VK_OEM_8 = 0xDF, /*   */
VK_OEM_102 = 0xE2, /* either the '<>' key or the '\|' key on the RT 102-key keyboard */
VK_PROCESSKEY = 0xE5, /* Windows 95, Windows NT 4.0, and IME PROCESS key */
VK_PACKET = 0xE7, /* Used to pass Unicode characters as if they were keystrokes. */
VK_ATTN = 0xF6, /* Attn key */
VK_CRSEL = 0xF7, /* CrSel key */
VK_EXSEL = 0xF8, /* ExSel key */
VK_EREOF = 0xF9, /* Erase EOF key */
VK_PLAY = 0xFA, /* Play key */
VK_ZOOM = 0xFB, /* Zoom key */
VK_NONAME = 0xFC, /* Reserved for future use */
VK_PA1 = 0xFD, /* PA1 key */
VK_OEM_CLEAR = 0xFE /* Clear key */
};
/* ref: http://techdocs.altium.com/display/FPGA/PS2+Keyboard+Scan+Codes */
enum ps2_keycode_scanmode2_enum {
PS2_KEY_ESC = 0x76,
PS2_KEY_F1 = 0x05,
PS2_KEY_F2 = 0x06,
PS2_KEY_F3 = 0x04,
PS2_KEY_F4 = 0x0C,
PS2_KEY_F5 = 0x03,
PS2_KEY_F6 = 0x0B,
PS2_KEY_F7 = 0x83,
PS2_KEY_F8 = 0x0A,
PS2_KEY_F9 = 0x01,
PS2_KEY_F10 = 0x09,
PS2_KEY_F11 = 0x78,
PS2_KEY_F12 = 0x07,
PS2_KEY_SCROLL_LOCK = 0x7E,
PS2_KEY_TILDE = 0x0E,
PS2_KEY_1 = 0x16,
PS2_KEY_2 = 0x1E,
PS2_KEY_3 = 0x26,
PS2_KEY_4 = 0x25,
PS2_KEY_5 = 0x2E,
PS2_KEY_6 = 0x36,
PS2_KEY_7 = 0x3D,
PS2_KEY_8 = 0x3E,
PS2_KEY_9 = 0x46,
PS2_KEY_0 = 0x45,
PS2_KEY_SUBTRACT = 0x4E,
PS2_KEY_EQUALS = 0x55,
PS2_KEY_BACKSPACE = 0x66,
PS2_KEY_TAB = 0x0D,
PS2_KEY_Q = 0x15,
PS2_KEY_W = 0x1D,
PS2_KEY_E = 0x24,
PS2_KEY_R = 0x2D,
PS2_KEY_T = 0x2C,
PS2_KEY_Y = 0x35,
PS2_KEY_U = 0x3C,
PS2_KEY_I = 0x43,
PS2_KEY_O = 0x44,
PS2_KEY_P = 0x4D,
PS2_KEY_LBRACKET = 0x54,
PS2_KEY_RBRACKET = 0x5B,
PS2_KEY_BACKSLASH = 0x5D,
PS2_KEY_CAPS_LOCK = 0x58,
PS2_KEY_A = 0x1C,
PS2_KEY_S = 0x1B,
PS2_KEY_D = 0x23,
PS2_KEY_F = 0x2B,
PS2_KEY_G = 0x34,
PS2_KEY_H = 0x33,
PS2_KEY_J = 0x3B,
PS2_KEY_K = 0x42,
PS2_KEY_L = 0x4B,
PS2_KEY_COLON = 0x4C,
PS2_KEY_TICK = 0x52,
PS2_KEY_ENTER = 0x5A,
PS2_KEY_SHIFT_LEFT = 0x12,
PS2_KEY_Z = 0x1A,
PS2_KEY_X = 0x22,
PS2_KEY_C = 0x21,
PS2_KEY_V = 0x2A,
PS2_KEY_B = 0x32,
PS2_KEY_N = 0x31,
PS2_KEY_M = 0x3A,
PS2_KEY_COMMA = 0x41,
PS2_KEY_DOT = 0x49,
PS2_KEY_SLASH = 0x4A,
PS2_KEY_SHIFT_RIGHT = 0x59,
PS2_KEY_CTRL_LEFT = 0x14,
PS2_KEY_ALT_LEFT = 0x11,
PS2_KEY_SPACEBAR = 0x29,
PS2_KEY_NUM_LOCK = 0x77,
PS2_KEY_NUM_MULTIPLY = 0x7C,
PS2_KEY_NUM_MINUS = 0x7B,
PS2_KEY_NUM_7 = 0x6C,
PS2_KEY_NUM_8 = 0x75,
PS2_KEY_NUM_9 = 0x7D,
PS2_KEY_NUM_PLUS = 0x79,
PS2_KEY_NUM_4 = 0x6B,
PS2_KEY_NUM_5 = 0x73,
PS2_KEY_NUM_6 = 0x74,
PS2_KEY_NUM_1 = 0x69,
PS2_KEY_NUM_2 = 0x72,
PS2_KEY_NUM_3 = 0x7A,
PS2_KEY_NUM_0 = 0x70,
PS2_KEY_NUM_DOT = 0x71,
PS2_KEY_PRTSCR = 0xE012, /* 0xE012E07C */
PS2_KEY_PAUSE = 0xE114, /* 0xE11477E1F014E077 */
PS2_KEY_WINDOWS_LEFT = 0xE01F,
PS2_KEY_ALT_RIGHT = 0xE011,
PS2_KEY_WINDOWS_RIGHT = 0xE027,
PS2_KEY_MENUS = 0xE02F,
PS2_KEY_CTRL_RIGHT = 0xE014,
PS2_KEY_INSERT = 0xE070,
PS2_KEY_HOME = 0xE06C,
PS2_KEY_PAGE_UP = 0xE07D,
PS2_KEY_DELETE = 0xE071,
PS2_KEY_END = 0xE069,
PS2_KEY_PAGE_DOWN = 0xE07A,
PS2_KEY_UP_ARROW = 0xE075,
PS2_KEY_LEFT_ARROW = 0xE06B,
PS2_KEY_DOWN_ARROW = 0xE072,
PS2_KEY_RIGHT_ARROW = 0xE074,
PS2_KEY_NUM_DIVIDE = 0xE04A,
PS2_KEY_NUM_ENTER = 0xE05A
};
/* All callbacks are optional, set to NULL if don't care. */
void keycode_init(
keycode_state_t *s,
void (*handle_keyevent_callback)(int16_t vkey, bool pressed, void *cookie),
void (*handle_chartyped_callback)(int c, void *cookie),
void (*handle_led_state_changed_callback)(void *cookie)
);
#if KEYBOARD_KEY_DEBUG
const char* keycode_vkey_desc(uint16_t vk);
#endif
int16_t keycode_info_char_modifier(keycode_info_t *info, bool ctrl, bool shift);
int16_t keycode_info_char(keycode_state_t *s, keycode_info_t *info);
int16_t keycode_ps2_to_vkey(int32_t ps2_keycode);
keycode_info_t *keycode_process_vkey_event(keycode_state_t *s, int32_t vkey, bool pressed,
void* cookie);
int16_t keycode_process_vkey_event_to_char(keycode_state_t *s, int32_t vkey, bool pressed,
void* cookie);
bool keycode_get_async_vkey_state(keycode_state_t *s, int32_t vkey);