1 /*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 12 /**************************************************************************/ 13 /**************************************************************************/ 14 /** */ 15 /** USBX Component */ 16 /** */ 17 /** HID Keyboard Client */ 18 /** */ 19 /**************************************************************************/ 20 /**************************************************************************/ 21 22 23 /**************************************************************************/ 24 /* */ 25 /* COMPONENT DEFINITION RELEASE */ 26 /* */ 27 /* ux_host_class_hid_keyboard.h PORTABLE C */ 28 /* 6.2.0 */ 29 /* AUTHOR */ 30 /* */ 31 /* Chaoqiong Xiao, Microsoft Corporation */ 32 /* */ 33 /* DESCRIPTION */ 34 /* */ 35 /* This file contains all the header and extern functions used by the */ 36 /* USBX HID keyboard client. */ 37 /* */ 38 /* RELEASE HISTORY */ 39 /* */ 40 /* DATE NAME DESCRIPTION */ 41 /* */ 42 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ 43 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ 44 /* used UX prefix to refer to */ 45 /* TX symbols instead of using */ 46 /* them directly, */ 47 /* resulting in version 6.1 */ 48 /* 08-02-2021 Wen Wang Modified comment(s), */ 49 /* added extern "C" keyword */ 50 /* for compatibility with C++, */ 51 /* resulting in version 6.1.8 */ 52 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ 53 /* added standalone support, */ 54 /* resulting in version 6.1.10 */ 55 /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ 56 /* fixed clients management, */ 57 /* resulting in version 6.1.11 */ 58 /* 10-31-2022 Chaoqiong Xiao Modified comment(s), */ 59 /* improved HID OUTPUT report */ 60 /* handling in standalone mode,*/ 61 /* resulting in version 6.2.0 */ 62 /* */ 63 /**************************************************************************/ 64 65 #ifndef UX_HOST_CLASS_HID_KEYBOARD_H 66 #define UX_HOST_CLASS_HID_KEYBOARD_H 67 68 /* Determine if a C++ compiler is being used. If so, ensure that standard 69 C is used to process the API information. */ 70 71 #ifdef __cplusplus 72 73 /* Yes, C++ compiler is present. Use standard C. */ 74 extern "C" { 75 76 #endif 77 78 79 /* Internal option: enable the basic USBX error checking. This define is typically used 80 while debugging application. */ 81 #if defined(UX_ENABLE_ERROR_CHECKING) && !defined(UX_DEVICE_CLASS_HID_KEYBOARD_ENABLE_ERROR_CHECKING) 82 #define UX_DEVICE_CLASS_HID_KEYBOARD_ENABLE_ERROR_CHECKING 83 #endif 84 85 86 /* Define HID Keyboard Class constants. */ 87 88 #define UX_HOST_CLASS_HID_KEYBOARD_BUFFER_LENGTH 128 89 #define UX_HOST_CLASS_HID_KEYBOARD_USAGE_ARRAY_LENGTH 64 90 91 /* Each item in usage array takes 4 bytes. Check memory bytes calculation overflow here. */ 92 #if UX_OVERFLOW_CHECK_MULC_ULONG(UX_HOST_CLASS_HID_KEYBOARD_USAGE_ARRAY_LENGTH, 4) 93 #error UX_HOST_CLASS_HID_KEYBOARD_USAGE_ARRAY_LENGTH too large for memory allocation 94 #endif 95 96 /* Define HID Keyboard Class LED keys. */ 97 98 #define UX_HID_LED_KEY_CAPS_LOCK 0x39 99 #define UX_HID_LED_KEY_NUM_LOCK 0x53 100 #define UX_HID_LED_KEY_SCROLL_LOCK 0x47 101 102 103 /* Define HID Keyboard Class Modifier Keys. */ 104 105 #define UX_HID_MODIFIER_KEY_LEFT_CONTROL 0xe0 106 #define UX_HID_MODIFIER_KEY_LEFT_SHIFT 0xe1 107 #define UX_HID_MODIFIER_KEY_LEFT_ALT 0xe2 108 #define UX_HID_MODIFIER_KEY_LEFT_GUI 0xe3 109 #define UX_HID_MODIFIER_KEY_RIGHT_CONTROL 0xe4 110 #define UX_HID_MODIFIER_KEY_RIGHT_SHIFT 0xe5 111 #define UX_HID_MODIFIER_KEY_RIGHT_ALT 0xe6 112 #define UX_HID_MODIFIER_KEY_RIGHT_GUI 0xe7 113 114 115 /* Define HID Keyboard States. */ 116 117 #define UX_HID_KEYBOARD_STATE_NUM_LOCK 0x0001 118 #define UX_HID_KEYBOARD_STATE_CAPS_LOCK 0x0002 119 #define UX_HID_KEYBOARD_STATE_SCROLL_LOCK 0x0004 120 #define UX_HID_KEYBOARD_STATE_MASK_LOCK 0x0007 121 122 #define UX_HID_KEYBOARD_STATE_LEFT_SHIFT 0x0100 123 #define UX_HID_KEYBOARD_STATE_RIGHT_SHIFT 0x0200 124 #define UX_HID_KEYBOARD_STATE_SHIFT 0x0300 125 126 #define UX_HID_KEYBOARD_STATE_LEFT_ALT 0x0400 127 #define UX_HID_KEYBOARD_STATE_RIGHT_ALT 0x0800 128 #define UX_HID_KEYBOARD_STATE_ALT 0x0a00 129 130 #define UX_HID_KEYBOARD_STATE_LEFT_CTRL 0x1000 131 #define UX_HID_KEYBOARD_STATE_RIGHT_CTRL 0x2000 132 #define UX_HID_KEYBOARD_STATE_CTRL 0x3000 133 134 #define UX_HID_KEYBOARD_STATE_LEFT_GUI 0x4000 135 #define UX_HID_KEYBOARD_STATE_RIGHT_GUI 0x8000 136 #define UX_HID_KEYBOARD_STATE_GUI 0xa000 137 138 #define UX_HID_KEYBOARD_STATE_KEY_UP 0x10000 139 #define UX_HID_KEYBOARD_STATE_FUNCTION 0x20000 140 141 /* Define HID keyboard generic equivalences. */ 142 143 #define UX_HID_KEYBOARD_NO_KEY 0 144 #define UX_HID_KEYBOARD_PHANTOM_STATE 0x01 145 #define UX_HID_KEYBOARD_KEY_LETTER_A 0x04 146 #define UX_HID_KEYBOARD_KEY_LETTER_Z 0x1D 147 #define UX_HID_KEYBOARD_KEYS_KEYPAD_LOWER_RANGE 0x54 148 #define UX_HID_KEYBOARD_KEYS_KEYPAD_UPPER_RANGE 0x67 149 #define UX_HID_KEYBOARD_KEYS_UPPER_RANGE 115 150 151 /* Define HID keyboard ioctl Functions. */ 152 153 #define UX_HID_KEYBOARD_IOCTL_SET_LAYOUT 0 154 #define UX_HID_KEYBOARD_IOCTL_DISABLE_KEYS_DECODE 1 155 #define UX_HID_KEYBOARD_IOCTL_ENABLE_KEYS_DECODE 2 156 157 /* Define HID keyboard layout array. */ 158 159 #define UX_HID_KEYBOARD_REGULAR_ARRAY_US \ 160 0,0,0,0, \ 161 'a','b','c','d','e','f','g','h','i','j','k','l','m','n', \ 162 'o','p','q','r','s','t','u','v','w','x','y','z', \ 163 '1','2','3','4','5','6','7','8','9','0', \ 164 0x0d,0x1b,0x08,0x07,0x20,'-','=','[',']', \ 165 '\\','#',';',0x27,'`',',','.','/',0xf0, \ 166 0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6, \ 167 0x00,0xf1,0x00,0xd2,0xc7,0xc9,0xd3,0xcf,0xd1,0xcd,0xcb,0xd0,0xc8,0xf2, \ 168 '/','*','-','+', \ 169 0x0d,'1','2','3','4','5','6','7','8','9','0','.','\\',0x00,0x00,'=', \ 170 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 171 172 #define UX_HID_KEYBOARD_SHIFT_ARRAY_US \ 173 0,0,0,0, \ 174 'A','B','C','D','E','F','G','H','I','J','K','L','M','N', \ 175 'O','P','Q','R','S','T','U','V','W','X','Y','Z', \ 176 '!','@','#','$','%','^','&','*','(',')', \ 177 0x0d,0x1b,0x08,0x07,0x20,'_','+','{','}', \ 178 '|','~',':','"','~','<','>','?',0xf0, \ 179 0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6, \ 180 0x00,0xf1,0x00,0xd2,0xc7,0xc9,0xd3,0xcf,0xd1,0xcd,0xcb,0xd0,0xc8,0xf2, \ 181 '/','*','-','+', \ 182 0x0d,'1','2','3','4','5','6','7','8','9','0','.','\\',0x00,0x00,'=', \ 183 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 184 185 #define UX_HID_KEYBOARD_NUMLOCK_ON_ARRAY \ 186 '/','*','-','+', \ 187 0x0d, \ 188 '1','2','3','4','5','6','7','8','9','0', \ 189 '.','\\',0x00,0x00,'=', 190 191 #define UX_HID_KEYBOARD_NUMLOCK_OFF_ARRAY \ 192 '/','*','-','+', \ 193 0x0d, \ 194 0xcf,0xd0,0xd1,0xcb,'5',0xcd,0xc7,0xc8,0xc9,0xd2, \ 195 0xd3,'\\',0x00,0x00,'=', 196 197 /* Define HID Keyboard layout (key mapping) structure. */ 198 199 typedef struct UX_HOST_CLASS_HID_KEYBOARD_LAYOUT_STRUCT 200 { 201 202 UCHAR *ux_host_class_hid_keyboard_layout_regular_array; 203 UCHAR *ux_host_class_hid_keyboard_layout_shift_array; 204 UCHAR *ux_host_class_hid_keyboard_layout_numlock_on_array; 205 UCHAR *ux_host_class_hid_keyboard_layout_numlock_off_array; 206 ULONG ux_host_class_hid_keyboard_layout_keys_upper_range; 207 ULONG ux_host_class_hid_keyboard_layout_letters_lower_range; 208 ULONG ux_host_class_hid_keyboard_layout_letters_upper_range; 209 ULONG ux_host_class_hid_keyboard_layout_keypad_lower_range; 210 ULONG ux_host_class_hid_keyboard_layout_keypad_upper_range; 211 } UX_HOST_CLASS_HID_KEYBOARD_LAYOUT; 212 213 /* Define HID Keyboard Class structure. */ 214 215 typedef struct UX_HOST_CLASS_HID_KEYBOARD_STRUCT 216 { 217 218 ULONG ux_host_class_hid_keyboard_state; 219 UCHAR *ux_host_class_hid_keyboard_key_state; 220 ULONG ux_host_class_hid_keyboard_key_count; 221 UX_HOST_CLASS_HID *ux_host_class_hid_keyboard_hid; 222 USHORT ux_host_class_hid_keyboard_id; 223 #if !defined(UX_HOST_STANDALONE) 224 VOID *ux_host_class_hid_keyboard_thread_stack; 225 UX_THREAD ux_host_class_hid_keyboard_thread; 226 UX_SEMAPHORE ux_host_class_hid_keyboard_semaphore; 227 #else 228 UX_HOST_CLASS_HID_REPORT 229 *ux_host_class_hid_keyboard_out_report; 230 UINT ux_host_class_hid_keyboard_status; 231 UCHAR ux_host_class_hid_keyboard_enum_state; 232 UCHAR ux_host_class_hid_keyboard_next_state; 233 UCHAR ux_host_class_hid_keyboard_out_state; 234 UCHAR reserved; 235 #endif 236 ULONG ux_host_class_hid_keyboard_alternate_key_state; 237 ULONG ux_host_class_hid_keyboard_led_mask; 238 ULONG *ux_host_class_hid_keyboard_usage_array; 239 ULONG *ux_host_class_hid_keyboard_usage_array_head; 240 ULONG *ux_host_class_hid_keyboard_usage_array_tail; 241 UX_HOST_CLASS_HID_KEYBOARD_LAYOUT *ux_host_class_hid_keyboard_layout; 242 ULONG ux_host_class_hid_keyboard_keys_decode_disable; 243 } UX_HOST_CLASS_HID_KEYBOARD; 244 245 typedef struct UX_HOST_CLASS_HID_CLIENT_KEYBOARD_STRUCT 246 { 247 UX_HOST_CLASS_HID_KEYBOARD ux_host_class_hid_client_keyboard_keyboard; 248 UX_HOST_CLASS_HID_CLIENT ux_host_class_hid_client_keyboard_client; 249 } UX_HOST_CLASS_HID_CLIENT_KEYBOARD; 250 251 /* Define HID Keyboard Class function prototypes. */ 252 253 VOID _ux_host_class_hid_keyboard_callback(UX_HOST_CLASS_HID_REPORT_CALLBACK *callback); 254 UINT _ux_host_class_hid_keyboard_activate(UX_HOST_CLASS_HID_CLIENT_COMMAND *command); 255 UINT _ux_host_class_hid_keyboard_deactivate(UX_HOST_CLASS_HID_CLIENT_COMMAND *command); 256 UINT _ux_host_class_hid_keyboard_entry(UX_HOST_CLASS_HID_CLIENT_COMMAND *command); 257 VOID _ux_host_class_hid_keyboard_thread(ULONG thread_entry); 258 UINT _ux_host_class_hid_keyboard_key_get(UX_HOST_CLASS_HID_KEYBOARD *keyboard_instance, 259 ULONG *keyboard_key, ULONG *keyboard_state); 260 UINT _ux_host_class_hid_keyboard_ioctl(UX_HOST_CLASS_HID_KEYBOARD *keyboard_instance, 261 ULONG ioctl_function, VOID *parameter); 262 263 VOID _ux_host_class_hid_keyboard_tasks_run(UX_HOST_CLASS_HID_CLIENT *client); 264 265 266 UINT _uxe_host_class_hid_keyboard_key_get(UX_HOST_CLASS_HID_KEYBOARD *keyboard_instance, 267 ULONG *keyboard_key, ULONG *keyboard_state); 268 UINT _uxe_host_class_hid_keyboard_ioctl(UX_HOST_CLASS_HID_KEYBOARD *keyboard_instance, 269 ULONG ioctl_function, VOID *parameter); 270 271 272 /* Define HID Keyboard Class API prototypes. */ 273 274 #define ux_host_class_hid_keyboard_entry _ux_host_class_hid_keyboard_entry 275 276 #if defined(UX_DEVICE_CLASS_HID_KEYBOARD_ENABLE_ERROR_CHECKING) 277 278 #define ux_host_class_hid_keyboard_key_get _uxe_host_class_hid_keyboard_key_get 279 #define ux_host_class_hid_keyboard_ioctl _uxe_host_class_hid_keyboard_ioctl 280 281 #else 282 283 #define ux_host_class_hid_keyboard_key_get _ux_host_class_hid_keyboard_key_get 284 #define ux_host_class_hid_keyboard_ioctl _ux_host_class_hid_keyboard_ioctl 285 286 #endif 287 288 /* Determine if a C++ compiler is being used. If so, complete the standard 289 C conditional started above. */ 290 #ifdef __cplusplus 291 } 292 #endif 293 294 #endif 295 296