1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13#pragma once 14 15#include <stdint.h> 16#include <stdbool.h> 17 18#define VK_MAX_ENUM 0xFF 19#define PS2_MAX_KEYCODES_BASIC 0xFF 20 21#define KEYBOARD_KEY_DEBUG false 22 23typedef struct keycode_info { 24 int16_t ch; 25 int16_t uppercase; 26 int16_t ctrlchar; 27} keycode_info_t; 28 29typedef struct keycode_state { 30 bool keystate[VK_MAX_ENUM]; 31 32 bool scroll_lock; 33 bool num_lock; 34 bool caps_lock; 35 bool led_state_changed; 36 37 /* Optional callback, called when a vkey has been pressed or released. */ 38 void (*handle_keyevent_callback)(int16_t vkey, bool pressed, void *cookie); 39 /* Optional callback, called when a character has been typed. */ 40 void (*handle_chartyped_callback)(int c, void *cookie); 41 /* Optional callback, called when num/scroll/caps lock LED state has changed. */ 42 void (*handle_led_state_changed_callback)(void *cookie); 43 44} keycode_state_t; 45 46/* ref: 47 http://nehe.gamedev.net/article/msdn_virtualkey_codes/15009/ 48 http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx 49*/ 50enum virtual_keycode_enum { 51 VK_LBUTTON = 0x1 , /* Left mouse button */ 52 VK_RBUTTON = 0x2 , /* Right mouse button */ 53 VK_CANCEL = 0x3 , /* Control-break processing */ 54 VK_MBUTTON = 0x4 , /* Middle mouse button (three-button mouse) */ 55 VK_XBUTTON1 = 0x5 , /* X1 mouse button */ 56 VK_XBUTTON2 = 0x6 , /* X2 mouse button */ 57 VK_BACK = 0x8 , /* BACKSPACE key */ 58 VK_TAB = 0x9 , /* TAB key */ 59 VK_CLEAR = 0x0C, /* CLEAR key */ 60 VK_RETURN = 0x0D, /* ENTER key */ 61 VK_CONTROL = 0x11, /* CTRL key */ 62 VK_SHIFT = 0x10, /* SHIFT key */ 63 VK_MENU = 0x12, /* ALT key */ 64 VK_PAUSE = 0x13, /* PAUSE key */ 65 VK_CAPITAL = 0x14, /* CAPS LOCK key */ 66 VK_KANA = 0x15, /* IME Kana mode */ 67 VK_HANGUEL = 0x15, /* IME Hanguel mode (maintained for compatibility; use VK_HANGUL) */ 68 VK_HANGUL = 0x15, /* IME Hangul mode */ 69 VK_JUNJA = 0x17, /* IME Junja mode */ 70 VK_FINAL = 0x18, /* IME final mode */ 71 VK_HANJA = 0x19, /* IME Hanja mode */ 72 VK_KANJI = 0x19, /* IME Kanji mode */ 73 VK_ESCAPE = 0x1B, /* ESC key */ 74 VK_CONVERT = 0x1C, /* IME convert */ 75 VK_NONCONVERT = 0x1D, /* IME nonconvert */ 76 VK_ACCEPT = 0x1E, /* IME accept */ 77 VK_MODECHANGE = 0x1F, /* IME mode change request */ 78 VK_SPACE = 0x20, /* SPACEBAR */ 79 VK_PRIOR = 0x21, /* PAGE UP key */ 80 VK_NEXT = 0x22, /* PAGE DOWN key */ 81 VK_END = 0x23, /* END key */ 82 VK_HOME = 0x24, /* HOME key */ 83 VK_LEFT = 0x25, /* LEFT ARROW key */ 84 VK_UP = 0x26, /* UP ARROW key */ 85 VK_RIGHT = 0x27, /* RIGHT ARROW key */ 86 VK_DOWN = 0x28, /* DOWN ARROW key */ 87 VK_SELECT = 0x29, /* SELECT key */ 88 VK_PRINT = 0x2A, /* PRINT key */ 89 VK_EXECUTE = 0x2B, /* EXECUTE key */ 90 VK_SNAPSHOT = 0x2C, /* PRINT SCREEN key */ 91 VK_INSERT = 0x2D, /* INS key */ 92 VK_DELETE = 0x2E, /* DEL key */ 93 VK_HELP = 0x2F, /* HELP key */ 94 VK_0 = 0x30, /* 0 key */ 95 VK_1 = 0x31, /* 1 key */ 96 VK_2 = 0x32, /* 2 key */ 97 VK_3 = 0x33, /* 3 key */ 98 VK_4 = 0x34, /* 4 key */ 99 VK_5 = 0x35, /* 5 key */ 100 VK_6 = 0x36, /* 6 key */ 101 VK_7 = 0x37, /* 7 key */ 102 VK_8 = 0x38, /* 8 key */ 103 VK_9 = 0x39, /* 9 key */ 104 VK_A = 0x41, /* A key */ 105 VK_B = 0x42, /* B key */ 106 VK_C = 0x43, /* C key */ 107 VK_D = 0x44, /* D key */ 108 VK_E = 0x45, /* E key */ 109 VK_F = 0x46, /* F key */ 110 VK_G = 0x47, /* G key */ 111 VK_H = 0x48, /* H key */ 112 VK_I = 0x49, /* I key */ 113 VK_J = 0x4A, /* J key */ 114 VK_K = 0x4B, /* K key */ 115 VK_L = 0x4C, /* L key */ 116 VK_M = 0x4D, /* M key */ 117 VK_N = 0x4E, /* N key */ 118 VK_O = 0x4F, /* O key */ 119 VK_P = 0x50, /* P key */ 120 VK_Q = 0x51, /* Q key */ 121 VK_R = 0x52, /* R key */ 122 VK_S = 0x53, /* S key */ 123 VK_T = 0x54, /* T key */ 124 VK_U = 0x55, /* U key */ 125 VK_V = 0x56, /* V key */ 126 VK_W = 0x57, /* W key */ 127 VK_X = 0x58, /* X key */ 128 VK_Y = 0x59, /* Y key */ 129 VK_Z = 0x5A, /* Z key */ 130 VK_LWIN = 0x5B, /* Left Windows key (Microsoft Natural Keyboard) */ 131 VK_RWIN = 0x5C, /* Right Windows key (Microsoft Natural Keyboard) */ 132 VK_APPS = 0x5D, /* Applications key (Microsoft Natural Keyboard) */ 133 VK_SLEEP = 0x5F, /* Computer Sleep key */ 134 VK_NUMPAD0 = 0x60, /* Numeric keypad 0 key */ 135 VK_NUMPAD1 = 0x61, /* Numeric keypad 1 key */ 136 VK_NUMPAD2 = 0x62, /* Numeric keypad 2 key */ 137 VK_NUMPAD3 = 0x63, /* Numeric keypad 3 key */ 138 VK_NUMPAD4 = 0x64, /* Numeric keypad 4 key */ 139 VK_NUMPAD5 = 0x65, /* Numeric keypad 5 key */ 140 VK_NUMPAD6 = 0x66, /* Numeric keypad 6 key */ 141 VK_NUMPAD7 = 0x67, /* Numeric keypad 7 key */ 142 VK_NUMPAD8 = 0x68, /* Numeric keypad 8 key */ 143 VK_NUMPAD9 = 0x69, /* Numeric keypad 9 key */ 144 VK_MULTIPLY = 0x6A, /* Multiply key */ 145 VK_ADD = 0x6B, /* Add key */ 146 VK_SEPARATOR = 0x6C, /* Separator key */ 147 VK_SUBTRACT = 0x6D, /* Subtract key */ 148 VK_DECIMAL = 0x6E, /* Decimal key */ 149 VK_DIVIDE = 0x6F, /* Divide key */ 150 VK_F1 = 0x70, /* F1 key */ 151 VK_F2 = 0x71, /* F2 key */ 152 VK_F3 = 0x72, /* F3 key */ 153 VK_F4 = 0x73, /* F4 key */ 154 VK_F5 = 0x74, /* F5 key */ 155 VK_F6 = 0x75, /* F6 key */ 156 VK_F7 = 0x76, /* F7 key */ 157 VK_F8 = 0x77, /* F8 key */ 158 VK_F9 = 0x78, /* F9 key */ 159 VK_F10 = 0x79, /* F10 key */ 160 VK_F11 = 0x7A, /* F11 key */ 161 VK_F12 = 0x7B, /* F12 key */ 162 VK_F13 = 0x7C, /* F13 key */ 163 VK_F14 = 0x7D, /* F14 key */ 164 VK_F15 = 0x7E, /* F15 key */ 165 VK_F16 = 0x7F, /* F16 key */ 166 VK_F17 = 0x80, /* F17 key */ 167 VK_F18 = 0x81, /* F18 key */ 168 VK_F19 = 0x82, /* F19 key */ 169 VK_F20 = 0x83, /* F20 key */ 170 VK_F21 = 0x84, /* F21 key */ 171 VK_F22 = 0x85, /* F22 key */ 172 VK_F23 = 0x86, /* F23 key */ 173 VK_F24 = 0x87, /* F24 key */ 174 VK_NUMLOCK = 0x90, /* NUM LOCK key */ 175 VK_SCROLL = 0x91, /* SCROLL LOCK key */ 176 VK_LSHIFT = 0xA0, /* Left SHIFT key */ 177 VK_RSHIFT = 0xA1, /* Right SHIFT key */ 178 VK_LCONTROL = 0xA2, /* Left CONTROL key */ 179 VK_RCONTROL = 0xA3, /* Right CONTROL key */ 180 VK_LMENU = 0xA4, /* Left MENU key */ 181 VK_RMENU = 0xA5, /* Right MENU key */ 182 VK_BROWSER_BACK = 0xA6, /* Browser Back key */ 183 VK_BROWSER_FORWARD = 0xA7, /* Browser Forward key */ 184 VK_BROWSER_REFRESH = 0xA8, /* Browser Refresh key */ 185 VK_BROWSER_STOP = 0xA9, /* Browser Stop key */ 186 VK_BROWSER_SEARCH = 0xAA, /* Browser Search key */ 187 VK_BROWSER_FAVORITES = 0xAB, /* Browser Favorites key */ 188 VK_BROWSER_HOME = 0xAC, /* Browser Launch and Home key */ 189 VK_VOLUME_MUTE = 0xAD, /* Volume Mute key */ 190 VK_VOLUME_DOWN = 0xAE, /* Volume Down key */ 191 VK_VOLUME_UP = 0xAF, /* Volume Up key */ 192 VK_MEDIA_NEXT_TRACK = 0xB0, /* Next Track key */ 193 VK_MEDIA_PREV_TRACK = 0xB1, /* Previous Track key */ 194 VK_MEDIA_STOP = 0xB2, /* Stop Media key */ 195 VK_MEDIA_PLAY_PAUSE = 0xB3, /* Play/Pause Media key */ 196 VK_LAUNCH_MAIL = 0xB4, /* Launch Mail key */ 197 VK_LAUNCH_MEDIA_SELECT = 0xB5, /* Select Media key */ 198 VK_LAUNCH_APP1 = 0xB6, /* Launch Application 1 key */ 199 VK_LAUNCH_APP2 = 0xB7, /* Launch Application 2 key */ 200 VK_OEM_1 = 0xBA, /* For the US standard keyboard, the ';:' key */ 201 VK_OEM_PLUS = 0xBB, /* For any country/region, the '+' key */ 202 VK_OEM_COMMA = 0xBC, /* For any country/region, the ',' key */ 203 VK_OEM_MINUS = 0xBD, /* For any country/region, the '-' key */ 204 VK_OEM_PERIOD = 0xBE, /* For any country/region, the '.' key */ 205 VK_OEM_2 = 0xBF, /* For the US standard keyboard, the '/?' key */ 206 VK_OEM_3 = 0xC0, /* For the US standard keyboard, the '`~' key */ 207 VK_OEM_4 = 0xDB, /* For the US standard keyboard, the '[{' key */ 208 VK_OEM_5 = 0xDC, /* For the US standard keyboard, the '\|' key */ 209 VK_OEM_6 = 0xDD, /* For the US standard keyboard, the ']}' key */ 210 VK_OEM_7 = 0xDE, /* For the US standard keyboard, the 'single-quote/double-quote' key */ 211 VK_OEM_8 = 0xDF, /* �� */ 212 VK_OEM_102 = 0xE2, /* either the '<>' key or the '\|' key on the RT 102-key keyboard */ 213 VK_PROCESSKEY = 0xE5, /* Windows 95, Windows NT 4.0, and IME PROCESS key */ 214 VK_PACKET = 0xE7, /* Used to pass Unicode characters as if they were keystrokes. */ 215 VK_ATTN = 0xF6, /* Attn key */ 216 VK_CRSEL = 0xF7, /* CrSel key */ 217 VK_EXSEL = 0xF8, /* ExSel key */ 218 VK_EREOF = 0xF9, /* Erase EOF key */ 219 VK_PLAY = 0xFA, /* Play key */ 220 VK_ZOOM = 0xFB, /* Zoom key */ 221 VK_NONAME = 0xFC, /* Reserved for future use */ 222 VK_PA1 = 0xFD, /* PA1 key */ 223 VK_OEM_CLEAR = 0xFE /* Clear key */ 224}; 225 226/* ref: http://techdocs.altium.com/display/FPGA/PS2+Keyboard+Scan+Codes */ 227enum ps2_keycode_scanmode2_enum { 228 PS2_KEY_ESC = 0x76, 229 PS2_KEY_F1 = 0x05, 230 PS2_KEY_F2 = 0x06, 231 PS2_KEY_F3 = 0x04, 232 PS2_KEY_F4 = 0x0C, 233 PS2_KEY_F5 = 0x03, 234 PS2_KEY_F6 = 0x0B, 235 PS2_KEY_F7 = 0x83, 236 PS2_KEY_F8 = 0x0A, 237 PS2_KEY_F9 = 0x01, 238 PS2_KEY_F10 = 0x09, 239 PS2_KEY_F11 = 0x78, 240 PS2_KEY_F12 = 0x07, 241 PS2_KEY_SCROLL_LOCK = 0x7E, 242 PS2_KEY_TILDE = 0x0E, 243 PS2_KEY_1 = 0x16, 244 PS2_KEY_2 = 0x1E, 245 PS2_KEY_3 = 0x26, 246 PS2_KEY_4 = 0x25, 247 PS2_KEY_5 = 0x2E, 248 PS2_KEY_6 = 0x36, 249 PS2_KEY_7 = 0x3D, 250 PS2_KEY_8 = 0x3E, 251 PS2_KEY_9 = 0x46, 252 PS2_KEY_0 = 0x45, 253 PS2_KEY_SUBTRACT = 0x4E, 254 PS2_KEY_EQUALS = 0x55, 255 PS2_KEY_BACKSPACE = 0x66, 256 PS2_KEY_TAB = 0x0D, 257 PS2_KEY_Q = 0x15, 258 PS2_KEY_W = 0x1D, 259 PS2_KEY_E = 0x24, 260 PS2_KEY_R = 0x2D, 261 PS2_KEY_T = 0x2C, 262 PS2_KEY_Y = 0x35, 263 PS2_KEY_U = 0x3C, 264 PS2_KEY_I = 0x43, 265 PS2_KEY_O = 0x44, 266 PS2_KEY_P = 0x4D, 267 PS2_KEY_LBRACKET = 0x54, 268 PS2_KEY_RBRACKET = 0x5B, 269 PS2_KEY_BACKSLASH = 0x5D, 270 PS2_KEY_CAPS_LOCK = 0x58, 271 PS2_KEY_A = 0x1C, 272 PS2_KEY_S = 0x1B, 273 PS2_KEY_D = 0x23, 274 PS2_KEY_F = 0x2B, 275 PS2_KEY_G = 0x34, 276 PS2_KEY_H = 0x33, 277 PS2_KEY_J = 0x3B, 278 PS2_KEY_K = 0x42, 279 PS2_KEY_L = 0x4B, 280 PS2_KEY_COLON = 0x4C, 281 PS2_KEY_TICK = 0x52, 282 PS2_KEY_ENTER = 0x5A, 283 PS2_KEY_SHIFT_LEFT = 0x12, 284 PS2_KEY_Z = 0x1A, 285 PS2_KEY_X = 0x22, 286 PS2_KEY_C = 0x21, 287 PS2_KEY_V = 0x2A, 288 PS2_KEY_B = 0x32, 289 PS2_KEY_N = 0x31, 290 PS2_KEY_M = 0x3A, 291 PS2_KEY_COMMA = 0x41, 292 PS2_KEY_DOT = 0x49, 293 PS2_KEY_SLASH = 0x4A, 294 PS2_KEY_SHIFT_RIGHT = 0x59, 295 PS2_KEY_CTRL_LEFT = 0x14, 296 PS2_KEY_ALT_LEFT = 0x11, 297 PS2_KEY_SPACEBAR = 0x29, 298 PS2_KEY_NUM_LOCK = 0x77, 299 PS2_KEY_NUM_MULTIPLY = 0x7C, 300 PS2_KEY_NUM_MINUS = 0x7B, 301 PS2_KEY_NUM_7 = 0x6C, 302 PS2_KEY_NUM_8 = 0x75, 303 PS2_KEY_NUM_9 = 0x7D, 304 PS2_KEY_NUM_PLUS = 0x79, 305 PS2_KEY_NUM_4 = 0x6B, 306 PS2_KEY_NUM_5 = 0x73, 307 PS2_KEY_NUM_6 = 0x74, 308 PS2_KEY_NUM_1 = 0x69, 309 PS2_KEY_NUM_2 = 0x72, 310 PS2_KEY_NUM_3 = 0x7A, 311 PS2_KEY_NUM_0 = 0x70, 312 PS2_KEY_NUM_DOT = 0x71, 313 314 PS2_KEY_PRTSCR = 0xE012, /* 0xE012E07C */ 315 PS2_KEY_PAUSE = 0xE114, /* 0xE11477E1F014E077 */ 316 PS2_KEY_WINDOWS_LEFT = 0xE01F, 317 PS2_KEY_ALT_RIGHT = 0xE011, 318 PS2_KEY_WINDOWS_RIGHT = 0xE027, 319 PS2_KEY_MENUS = 0xE02F, 320 PS2_KEY_CTRL_RIGHT = 0xE014, 321 PS2_KEY_INSERT = 0xE070, 322 PS2_KEY_HOME = 0xE06C, 323 PS2_KEY_PAGE_UP = 0xE07D, 324 PS2_KEY_DELETE = 0xE071, 325 PS2_KEY_END = 0xE069, 326 PS2_KEY_PAGE_DOWN = 0xE07A, 327 PS2_KEY_UP_ARROW = 0xE075, 328 PS2_KEY_LEFT_ARROW = 0xE06B, 329 PS2_KEY_DOWN_ARROW = 0xE072, 330 PS2_KEY_RIGHT_ARROW = 0xE074, 331 PS2_KEY_NUM_DIVIDE = 0xE04A, 332 PS2_KEY_NUM_ENTER = 0xE05A 333}; 334 335/* All callbacks are optional, set to NULL if don't care. */ 336void keycode_init( 337 keycode_state_t *s, 338 void (*handle_keyevent_callback)(int16_t vkey, bool pressed, void *cookie), 339 void (*handle_chartyped_callback)(int c, void *cookie), 340 void (*handle_led_state_changed_callback)(void *cookie) 341); 342 343#if KEYBOARD_KEY_DEBUG 344const char* keycode_vkey_desc(uint16_t vk); 345#endif 346 347int16_t keycode_info_char_modifier(keycode_info_t *info, bool ctrl, bool shift); 348 349int16_t keycode_info_char(keycode_state_t *s, keycode_info_t *info); 350 351int16_t keycode_ps2_to_vkey(int32_t ps2_keycode); 352 353keycode_info_t *keycode_process_vkey_event(keycode_state_t *s, int32_t vkey, bool pressed, 354 void* cookie); 355 356int16_t keycode_process_vkey_event_to_char(keycode_state_t *s, int32_t vkey, bool pressed, 357 void* cookie); 358 359bool keycode_get_async_vkey_state(keycode_state_t *s, int32_t vkey); 360 361