Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

836 lines
35 KiB

  1. // @doc
  2. /**********************************************************************
  3. *
  4. * @module KeyboardXfer.cpp |
  5. *
  6. * Implements MakeKeyboardXfer
  7. *
  8. * History
  9. * ----------------------------------------------------------
  10. * Mitchell S. Dernis Original
  11. *
  12. * (c) 1986-1998 Microsoft Corporation. All right reserved.
  13. *
  14. * @topic KeyboardXfer |
  15. * This module implements access function for Keyboard data in
  16. * CONTROL_ITEM_XFER packets. At this time, there is only one:
  17. * <f MakeKeyboardXfer>.
  18. **********************************************************************/
  19. #include "stdhdrs.h"
  20. #include "scancodedefines.h"
  21. //
  22. // Define the Keyboard usages
  23. // Unfortunately, HIDUSAGE.H, included as part of the Win98 and Win2k
  24. // DDK's. contains only a subset of these codes. Thus we will define them
  25. // all here. With a slight name change. HID_USAGE_INDEX_ is used
  26. // instead of HID USAGE, which makes sense, since these are really
  27. // an 8 bit index into a 16-bit USAGE with a base of 0. Notice that the
  28. // entries in HIDUSAGE.H are cast to type USAGE. For us, we prefer that they
  29. // are naturally UCHARS. (See discussion on Selectors in HID spec. for more
  30. // info).
  31. //
  32. // Technically they are all 16 bit usages. However, all these
  33. // usages are only 8 bits long, and furthermore our CONTROL_ITEM_XFER only
  34. // stores an 8 bit offset from a range of usages starting with zero.
  35. // Thus for our purposes it makes sense to make this byte long.
  36. //
  37. // The HID spec does not provide good identifier names. I followed the notation in HIDUSAGE.H
  38. // as much as possible. However, I arbitrarily named many keys after only one of its functions. For
  39. // example, "Keyboard , and <" is called HID_USAGE_INDEX_KEYBOARD_COMMA.
  40. #define HID_USAGE_INDEX_KEYBOARD_NOEVENT 0x00
  41. #define HID_USAGE_INDEX_KEYBOARD_ROLLOVER 0x01
  42. #define HID_USAGE_INDEX_KEYBOARD_POSTFAIL 0x02
  43. #define HID_USAGE_INDEX_KEYBOARD_UNDEFINED 0x03
  44. // Letters
  45. #define HID_USAGE_INDEX_KEYBOARD_aA 0x04
  46. #define HID_USAGE_INDEX_KEYBOARD_bB 0x05
  47. #define HID_USAGE_INDEX_KEYBOARD_cC 0x06
  48. #define HID_USAGE_INDEX_KEYBOARD_dD 0x07
  49. #define HID_USAGE_INDEX_KEYBOARD_eE 0x08
  50. #define HID_USAGE_INDEX_KEYBOARD_fF 0x09
  51. #define HID_USAGE_INDEX_KEYBOARD_gG 0x0A
  52. #define HID_USAGE_INDEX_KEYBOARD_hH 0x0B
  53. #define HID_USAGE_INDEX_KEYBOARD_iI 0x0C
  54. #define HID_USAGE_INDEX_KEYBOARD_jJ 0x0D
  55. #define HID_USAGE_INDEX_KEYBOARD_kK 0x0E
  56. #define HID_USAGE_INDEX_KEYBOARD_lL 0x0F
  57. #define HID_USAGE_INDEX_KEYBOARD_mM 0x10
  58. #define HID_USAGE_INDEX_KEYBOARD_nN 0x11
  59. #define HID_USAGE_INDEX_KEYBOARD_oO 0x12
  60. #define HID_USAGE_INDEX_KEYBOARD_pP 0x13
  61. #define HID_USAGE_INDEX_KEYBOARD_qQ 0x14
  62. #define HID_USAGE_INDEX_KEYBOARD_rR 0x15
  63. #define HID_USAGE_INDEX_KEYBOARD_sS 0x16
  64. #define HID_USAGE_INDEX_KEYBOARD_tT 0x17
  65. #define HID_USAGE_INDEX_KEYBOARD_uU 0x18
  66. #define HID_USAGE_INDEX_KEYBOARD_vV 0x19
  67. #define HID_USAGE_INDEX_KEYBOARD_wW 0x1A
  68. #define HID_USAGE_INDEX_KEYBOARD_xX 0x1B
  69. #define HID_USAGE_INDEX_KEYBOARD_yY 0x1C
  70. #define HID_USAGE_INDEX_KEYBOARD_zZ 0x1D
  71. // Numbers
  72. #define HID_USAGE_INDEX_KEYBOARD_ONE 0x1E
  73. #define HID_USAGE_INDEX_KEYBOARD_TWO 0x1F
  74. #define HID_USAGE_INDEX_KEYBOARD_THREE 0x20
  75. #define HID_USAGE_INDEX_KEYBOARD_FOUR 0x21
  76. #define HID_USAGE_INDEX_KEYBOARD_FIVE 0x22
  77. #define HID_USAGE_INDEX_KEYBOARD_SIX 0x23
  78. #define HID_USAGE_INDEX_KEYBOARD_SEVEN 0x24
  79. #define HID_USAGE_INDEX_KEYBOARD_EIGHT 0x25
  80. #define HID_USAGE_INDEX_KEYBOARD_NINE 0x26
  81. #define HID_USAGE_INDEX_KEYBOARD_ZERO 0x27
  82. //Editing Keys
  83. #define HID_USAGE_INDEX_KEYBOARD_RETURN 0x28
  84. #define HID_USAGE_INDEX_KEYBOARD_ESCAPE 0x29
  85. #define HID_USAGE_INDEX_KEYBOARD_BACKSPACE 0x2A //HID spec calls this "delete(backspace)", what we later call delete HID calls "delete forward"
  86. #define HID_USAGE_INDEX_KEYBOARD_TAB 0x2B
  87. #define HID_USAGE_INDEX_KEYBOARD_SPACEBAR 0x2C
  88. #define HID_USAGE_INDEX_KEYBOARD_MINUS 0x2D
  89. #define HID_USAGE_INDEX_KEYBOARD_EQUALS 0x2E
  90. #define HID_USAGE_INDEX_KEYBOARD_OPEN_BRACE 0x2F
  91. #define HID_USAGE_INDEX_KEYBOARD_CLOSE_BRACE 0x30
  92. #define HID_USAGE_INDEX_KEYBOARD_BACKSLASH 0x31
  93. #define HID_USAGE_INDEX_KEYBOARD_NON_US_TILDE 0x32
  94. #define HID_USAGE_INDEX_KEYBOARD_COLON 0x33
  95. #define HID_USAGE_INDEX_KEYBOARD_QUOTE 0x34
  96. #define HID_USAGE_INDEX_KEYBOARD_TILDE 0x35
  97. #define HID_USAGE_INDEX_KEYBOARD_COMMA 0x36
  98. #define HID_USAGE_INDEX_KEYBOARD_PERIOD 0x37
  99. #define HID_USAGE_INDEX_KEYBOARD_QUESTION 0x38
  100. #define HID_USAGE_INDEX_KEYBOARD_CAPS_LOCK 0x39
  101. // Funtion keys
  102. #define HID_USAGE_INDEX_KEYBOARD_F1 0x3A
  103. #define HID_USAGE_INDEX_KEYBOARD_F2 0x3B
  104. #define HID_USAGE_INDEX_KEYBOARD_F3 0x3C
  105. #define HID_USAGE_INDEX_KEYBOARD_F4 0x3D
  106. #define HID_USAGE_INDEX_KEYBOARD_F5 0x3E
  107. #define HID_USAGE_INDEX_KEYBOARD_F6 0x3F
  108. #define HID_USAGE_INDEX_KEYBOARD_F7 0x40
  109. #define HID_USAGE_INDEX_KEYBOARD_F8 0x41
  110. #define HID_USAGE_INDEX_KEYBOARD_F9 0x42
  111. #define HID_USAGE_INDEX_KEYBOARD_F10 0x43
  112. #define HID_USAGE_INDEX_KEYBOARD_F11 0x44
  113. #define HID_USAGE_INDEX_KEYBOARD_F12 0x45
  114. //More Edit Keys
  115. #define HID_USAGE_INDEX_KEYBOARD_PRINT_SCREEN 0x46
  116. #define HID_USAGE_INDEX_KEYBOARD_SCROLL_LOCK 0x47
  117. #define HID_USAGE_INDEX_KEYBOARD_PAUSE 0x48
  118. #define HID_USAGE_INDEX_KEYBOARD_INSERT 0x49
  119. #define HID_USAGE_INDEX_KEYBOARD_HOME 0x4A
  120. #define HID_USAGE_INDEX_KEYBOARD_PAGE_UP 0x4B
  121. #define HID_USAGE_INDEX_KEYBOARD_DELETE 0x4C //HID spec, DELETE FORWARD, DELETE is used for backspace
  122. #define HID_USAGE_INDEX_KEYBOARD_END 0x4D
  123. #define HID_USAGE_INDEX_KEYBOARD_PAGE_DOWN 0x4E
  124. #define HID_USAGE_INDEX_KEYBOARD_RIGHT_ARROW 0x4F
  125. #define HID_USAGE_INDEX_KEYBOARD_LEFT_ARROW 0x50
  126. #define HID_USAGE_INDEX_KEYBOARD_DOWN_ARROW 0x51
  127. #define HID_USAGE_INDEX_KEYBOARD_UP_ARROW 0x52
  128. #define HID_USAGE_INDEX_KEYPAD_NUM_LOCK 0x53
  129. #define HID_USAGE_INDEX_KEYPAD_BACKSLASH 0x54
  130. #define HID_USAGE_INDEX_KEYPAD_ASTERICK 0x55
  131. #define HID_USAGE_INDEX_KEYPAD_MINUS 0x56
  132. #define HID_USAGE_INDEX_KEYPAD_PLUS 0x57
  133. #define HID_USAGE_INDEX_KEYPAD_ENTER 0x58
  134. #define HID_USAGE_INDEX_KEYPAD_ONE 0x59
  135. #define HID_USAGE_INDEX_KEYPAD_TWO 0x5A
  136. #define HID_USAGE_INDEX_KEYPAD_THREE 0x5B
  137. #define HID_USAGE_INDEX_KEYPAD_FOUR 0x5C
  138. #define HID_USAGE_INDEX_KEYPAD_FIVE 0x5D
  139. #define HID_USAGE_INDEX_KEYPAD_SIX 0x5E
  140. #define HID_USAGE_INDEX_KEYPAD_SEVEN 0x5F
  141. #define HID_USAGE_INDEX_KEYPAD_EIGHT 0x60
  142. #define HID_USAGE_INDEX_KEYPAD_NINE 0x61
  143. #define HID_USAGE_INDEX_KEYPAD_ZERO 0x62
  144. #define HID_USAGE_INDEX_KEYPAD_DECIMAL 0x63
  145. #define HID_USAGE_INDEX_KEYBOARD_NON_US_BACKSLASH 0x64
  146. #define HID_USAGE_INDEX_KEYBOARD_APPLICATION 0x65 //This is the Windows(R)TM Key
  147. #define HID_USAGE_INDEX_KEYBOARD_POWER 0x66 //Not on standard 101 or 104
  148. #define HID_USAGE_INDEX_KEYPAD_EQUALS 0x67 //Not on standard 101 or 104
  149. //Bunch o' function keys not on supported keyboards
  150. #define HID_USAGE_INDEX_KEYBOARD_F13 0x68
  151. #define HID_USAGE_INDEX_KEYBOARD_F14 0x69
  152. #define HID_USAGE_INDEX_KEYBOARD_F15 0x6A
  153. #define HID_USAGE_INDEX_KEYBOARD_F16 0x6B
  154. #define HID_USAGE_INDEX_KEYBOARD_F17 0x6C
  155. #define HID_USAGE_INDEX_KEYBOARD_F18 0x6D
  156. #define HID_USAGE_INDEX_KEYBOARD_F19 0x6E
  157. #define HID_USAGE_INDEX_KEYBOARD_F20 0x6F
  158. #define HID_USAGE_INDEX_KEYBOARD_F21 0x70
  159. #define HID_USAGE_INDEX_KEYBOARD_F22 0x71
  160. #define HID_USAGE_INDEX_KEYBOARD_F23 0x72
  161. #define HID_USAGE_INDEX_KEYBOARD_F24 0x73
  162. //More unsupported usages
  163. #define HID_USAGE_INDEX_KEYBOARD_EXECUTE 0x74
  164. #define HID_USAGE_INDEX_KEYBOARD_HELP 0x75
  165. #define HID_USAGE_INDEX_KEYBOARD_MENU 0x76
  166. #define HID_USAGE_INDEX_KEYBOARD_SELECT 0x77
  167. #define HID_USAGE_INDEX_KEYBOARD_STOP 0x78
  168. #define HID_USAGE_INDEX_KEYBOARD_AGAIN 0x79
  169. #define HID_USAGE_INDEX_KEYBOARD_UNDO 0x7A
  170. #define HID_USAGE_INDEX_KEYBOARD_CUT 0x7B
  171. #define HID_USAGE_INDEX_KEYBOARD_COPY 0x7C
  172. #define HID_USAGE_INDEX_KEYBOARD_PASTE 0x7D
  173. #define HID_USAGE_INDEX_KEYBOARD_FIND 0x7E
  174. #define HID_USAGE_INDEX_KEYBOARD_MUTE 0x7F
  175. #define HID_USAGE_INDEX_KEYBOARD_VOLUME_UP 0x80
  176. #define HID_USAGE_INDEX_KEYBOARD_VOLUME_DOWN 0x81
  177. #define HID_USAGE_INDEX_KEYBOARD_LOCKING_CAPS 0x82 //sent as a toggle, see HID USAGE Tables spec.
  178. #define HID_USAGE_INDEX_KEYBOARD_LOCKING_NUM 0x83 //sent as a toggle, see HID USAGE Tables spec.
  179. #define HID_USAGE_INDEX_KEYBOARD_LOCKING_SCROLL 0x84 //sent as a toggle, see HID USAGE Tables spec
  180. //Stuff that we use on foreign keyboards, some needed, some not
  181. #define HID_USAGE_INDEX_KEYPAD_COMMA 0x85 //According to HID usage table 1.1rc3 2/16/99, use for Brazilian keypad "."
  182. #define HID_USAGE_INDEX_KEYPAD_EQUALS_AS400 0x86 //Only As\400, so we don't need to worry.
  183. #define HID_USAGE_INDEX_KEYBOARD_INTERNATIONAL1 0x87 //Brazilian forward slash "/", and Japanese backslash slash
  184. #define HID_USAGE_INDEX_KEYBOARD_INTERNALIONAL2 0x88 //Picture looks like Hiragana according to Emi
  185. #define HID_USAGE_INDEX_KEYBOARD_INTERNATIONAL3 0x89 //Picture looks like Yen
  186. #define HID_USAGE_INDEX_KEYBOARD_INTERNATIONAL4 0x8A //Picture looks like Henkan
  187. #define HID_USAGE_INDEX_KEYBOARD_INTERNATIONAL5 0x8B //Picture looks like Mu-Henkan
  188. #define HID_USAGE_INDEX_KEYBOARD_INTERNATIONAL6 0x8C
  189. #define HID_USAGE_INDEX_KEYBOARD_INTERNATIONAL7 0x8D //Single byte/double byte toggle
  190. #define HID_USAGE_INDEX_KEYBOARD_INTERNATIONAL8 0x8E //left undefined in spec
  191. #define HID_USAGE_INDEX_KEYBOARD_INTERNATIONAL9 0x8F //left undefined in spec
  192. #define HID_USAGE_INDEX_KEYBOARD_LANG1 0x90 //Hangul/English
  193. #define HID_USAGE_INDEX_KEYBOARD_LANG2 0x91 //Hanja conversion key
  194. #define HID_USAGE_INDEX_KEYBOARD_LANG3 0x92 //Katakana key Japanese USB word-processing keyboard
  195. #define HID_USAGE_INDEX_KEYBOARD_LANG4 0x93 //Hiragana key Japanese USB word-processing keyboard
  196. #define HID_USAGE_INDEX_KEYBOARD_LANG5 0x94 //Defines the Zenkaku/Hankaku key for Japanese USB word-processing keyboard
  197. #define HID_USAGE_INDEX_KEYBOARD_LANG6 0x95 //reserved for IME
  198. #define HID_USAGE_INDEX_KEYBOARD_LANG7 0x96 //reserved for IME
  199. #define HID_USAGE_INDEX_KEYBOARD_LANG8 0x97 //reserved for IME
  200. #define HID_USAGE_INDEX_KEYBOARD_LANG9 0x98 //reserved for IME
  201. // . . .
  202. // Modifier Keys
  203. #define HID_USAGE_INDEX_KEYBOARD_LCTRL 0xE0
  204. #define HID_USAGE_INDEX_KEYBOARD_LSHFT 0xE1
  205. #define HID_USAGE_INDEX_KEYBOARD_LALT 0xE2
  206. #define HID_USAGE_INDEX_KEYBOARD_LGUI 0xE3
  207. #define HID_USAGE_INDEX_KEYBOARD_RCTRL 0xE4
  208. #define HID_USAGE_INDEX_KEYBOARD_RSHFT 0xE5
  209. #define HID_USAGE_INDEX_KEYBOARD_RALT 0xE6
  210. #define HID_USAGE_INDEX_KEYBOARD_RGUI 0xE7
  211. //
  212. // The following table has each of our keyboard "USAGES"
  213. // (see note above on we these are UCHAR's) at the index
  214. // corresponding to their scan code. Note there is always
  215. // a one-to-one correspondence between scan code and USAGE.
  216. // This table only works for one byte scan codes. Scan codes
  217. // beginning with E0 have a second byte. The next table
  218. // is used for those. This table has 83 keys.
  219. //
  220. UCHAR XlateScanCodeToUsageTable[] =
  221. {
  222. /*SCANCODE*/ /*HID USAGE*/
  223. /*0x00*/ HID_USAGE_INDEX_KEYBOARD_NOEVENT, //SCAN CODE ZERO IS UNUSED
  224. /*0x01*/ HID_USAGE_INDEX_KEYBOARD_ESCAPE,
  225. /*0x02*/ HID_USAGE_INDEX_KEYBOARD_ONE,
  226. /*0x03*/ HID_USAGE_INDEX_KEYBOARD_TWO,
  227. /*0x04*/ HID_USAGE_INDEX_KEYBOARD_THREE,
  228. /*0x05*/ HID_USAGE_INDEX_KEYBOARD_FOUR,
  229. /*0x06*/ HID_USAGE_INDEX_KEYBOARD_FIVE,
  230. /*0x07*/ HID_USAGE_INDEX_KEYBOARD_SIX,
  231. /*0x08*/ HID_USAGE_INDEX_KEYBOARD_SEVEN,
  232. /*0x09*/ HID_USAGE_INDEX_KEYBOARD_EIGHT,
  233. /*0x0A*/ HID_USAGE_INDEX_KEYBOARD_NINE,
  234. /*0x0B*/ HID_USAGE_INDEX_KEYBOARD_ZERO,
  235. /*0x0C*/ HID_USAGE_INDEX_KEYBOARD_MINUS,
  236. /*0x0D*/ HID_USAGE_INDEX_KEYBOARD_EQUALS,
  237. /*0x0E*/ HID_USAGE_INDEX_KEYBOARD_BACKSPACE,
  238. /*0x0F*/ HID_USAGE_INDEX_KEYBOARD_TAB,
  239. /*0x10*/ HID_USAGE_INDEX_KEYBOARD_qQ,
  240. /*0x11*/ HID_USAGE_INDEX_KEYBOARD_wW,
  241. /*0x12*/ HID_USAGE_INDEX_KEYBOARD_eE,
  242. /*0x13*/ HID_USAGE_INDEX_KEYBOARD_rR,
  243. /*0x14*/ HID_USAGE_INDEX_KEYBOARD_tT,
  244. /*0x15*/ HID_USAGE_INDEX_KEYBOARD_yY,
  245. /*0x16*/ HID_USAGE_INDEX_KEYBOARD_uU,
  246. /*0x17*/ HID_USAGE_INDEX_KEYBOARD_iI,
  247. /*0x18*/ HID_USAGE_INDEX_KEYBOARD_oO,
  248. /*0x19*/ HID_USAGE_INDEX_KEYBOARD_pP,
  249. /*0x1A*/ HID_USAGE_INDEX_KEYBOARD_OPEN_BRACE,
  250. /*0x1B*/ HID_USAGE_INDEX_KEYBOARD_CLOSE_BRACE,
  251. /*0x1C*/ HID_USAGE_INDEX_KEYBOARD_RETURN,
  252. /*0x1D*/ HID_USAGE_INDEX_KEYBOARD_LCTRL,
  253. /*0x1E*/ HID_USAGE_INDEX_KEYBOARD_aA,
  254. /*0x1F*/ HID_USAGE_INDEX_KEYBOARD_sS,
  255. /*0x20*/ HID_USAGE_INDEX_KEYBOARD_dD,
  256. /*0x21*/ HID_USAGE_INDEX_KEYBOARD_fF,
  257. /*0x22*/ HID_USAGE_INDEX_KEYBOARD_gG,
  258. /*0x23*/ HID_USAGE_INDEX_KEYBOARD_hH,
  259. /*0x24*/ HID_USAGE_INDEX_KEYBOARD_jJ,
  260. /*0x25*/ HID_USAGE_INDEX_KEYBOARD_kK,
  261. /*0x26*/ HID_USAGE_INDEX_KEYBOARD_lL,
  262. /*0x27*/ HID_USAGE_INDEX_KEYBOARD_COLON,
  263. /*0x28*/ HID_USAGE_INDEX_KEYBOARD_QUOTE,
  264. /*0x29*/ HID_USAGE_INDEX_KEYBOARD_TILDE,
  265. /*0x2A*/ HID_USAGE_INDEX_KEYBOARD_LSHFT,
  266. /*0x2B*/ HID_USAGE_INDEX_KEYBOARD_BACKSLASH,
  267. /*0x2C*/ HID_USAGE_INDEX_KEYBOARD_zZ,
  268. /*0x2D*/ HID_USAGE_INDEX_KEYBOARD_xX,
  269. /*0x2E*/ HID_USAGE_INDEX_KEYBOARD_cC,
  270. /*0x2F*/ HID_USAGE_INDEX_KEYBOARD_vV,
  271. /*0x30*/ HID_USAGE_INDEX_KEYBOARD_bB,
  272. /*0x31*/ HID_USAGE_INDEX_KEYBOARD_nN,
  273. /*0x32*/ HID_USAGE_INDEX_KEYBOARD_mM,
  274. /*0x33*/ HID_USAGE_INDEX_KEYBOARD_COMMA,
  275. /*0x34*/ HID_USAGE_INDEX_KEYBOARD_PERIOD,
  276. /*0x35*/ HID_USAGE_INDEX_KEYBOARD_QUESTION,
  277. /*0x36*/ HID_USAGE_INDEX_KEYBOARD_RSHFT,
  278. /*0x37*/ HID_USAGE_INDEX_KEYPAD_ASTERICK, //Print screen, but it always comes with EO (for some reason Mitch had printscreen)
  279. /*0x38*/ HID_USAGE_INDEX_KEYBOARD_LALT,
  280. /*0x39*/ HID_USAGE_INDEX_KEYBOARD_SPACEBAR,
  281. /*0x3A*/ HID_USAGE_INDEX_KEYBOARD_CAPS_LOCK,
  282. /*0x3B*/ HID_USAGE_INDEX_KEYBOARD_F1,
  283. /*0x3C*/ HID_USAGE_INDEX_KEYBOARD_F2,
  284. /*0x3D*/ HID_USAGE_INDEX_KEYBOARD_F3,
  285. /*0x3E*/ HID_USAGE_INDEX_KEYBOARD_F4,
  286. /*0x3F*/ HID_USAGE_INDEX_KEYBOARD_F5,
  287. /*0x40*/ HID_USAGE_INDEX_KEYBOARD_F6,
  288. /*0x41*/ HID_USAGE_INDEX_KEYBOARD_F7,
  289. /*0x42*/ HID_USAGE_INDEX_KEYBOARD_F8,
  290. /*0x43*/ HID_USAGE_INDEX_KEYBOARD_F9,
  291. /*0x44*/ HID_USAGE_INDEX_KEYBOARD_F10,
  292. /*0x45*/ HID_USAGE_INDEX_KEYPAD_NUM_LOCK,
  293. /*0x46*/ HID_USAGE_INDEX_KEYBOARD_SCROLL_LOCK,
  294. /*0x47*/ HID_USAGE_INDEX_KEYPAD_SEVEN, //a.k.a. HOME on Keypad
  295. /*0x48*/ HID_USAGE_INDEX_KEYPAD_EIGHT, //a.k.a. UP ARROW on Keypad
  296. /*0x49*/ HID_USAGE_INDEX_KEYPAD_NINE, //a.k.a. PAGE UP on Keypad
  297. /*0x4A*/ HID_USAGE_INDEX_KEYPAD_MINUS, //a.k.a. GREY - on Keypad
  298. /*0x4B*/ HID_USAGE_INDEX_KEYPAD_FOUR, //a.k.a. LEFT ARROW on Keypad
  299. /*0x4C*/ HID_USAGE_INDEX_KEYPAD_FIVE, //a.k.a. CENTER on Keypad
  300. /*0x4D*/ HID_USAGE_INDEX_KEYPAD_SIX, //a.k.a. RIGHT on Keypad
  301. /*0x4E*/ HID_USAGE_INDEX_KEYPAD_PLUS, //a.k.a. GREY + on Keypad
  302. /*0x4F*/ HID_USAGE_INDEX_KEYPAD_ONE, //a.k.a. END on Keypad
  303. /*0x50*/ HID_USAGE_INDEX_KEYPAD_TWO, //a.k.a. DOWN ARROW on Keypad
  304. /*0x51*/ HID_USAGE_INDEX_KEYPAD_THREE, //a.k.a. PAGE DOWN on Keypad
  305. /*0x52*/ HID_USAGE_INDEX_KEYPAD_ZERO, //a.k.a. INSERT on Keypad
  306. /*0x53*/ HID_USAGE_INDEX_KEYPAD_DECIMAL, //a.k.a. DELETE on Keypad
  307. /*0x54*/ 0x00,
  308. /*0x55*/ 0x00,
  309. /*0x56*/ HID_USAGE_INDEX_KEYBOARD_NON_US_BACKSLASH,
  310. /*0x57*/ HID_USAGE_INDEX_KEYBOARD_F11,
  311. /*0x58*/ HID_USAGE_INDEX_KEYBOARD_F12,
  312. };
  313. UCHAR XlateScanCodeToUsageTable2[] =
  314. {
  315. /*0x70*/ HID_USAGE_INDEX_KEYBOARD_LANG4, //Hiragana
  316. /*0x71*/ 0x00,
  317. /*0x72*/ 0x00,
  318. /*0x73*/ HID_USAGE_INDEX_KEYBOARD_INTERNATIONAL1, //Brazilian forward slash
  319. /*0x74*/ 0x00,
  320. /*0x75*/ 0x00,
  321. /*0x76*/ 0x00,
  322. /*0x77*/ 0x00,
  323. /*0x78*/ 0x00,
  324. /*0x79*/ HID_USAGE_INDEX_KEYBOARD_INTERNATIONAL4, //Japanese Henkan
  325. /*0x7A*/ 0x00,
  326. /*0x7B*/ HID_USAGE_INDEX_KEYBOARD_INTERNATIONAL5, //Japanese Mu-Henkan
  327. /*0x7C*/ 0x00,
  328. /*0x7D*/ HID_USAGE_INDEX_KEYBOARD_INTERNATIONAL3, //Japanese Yen
  329. /*0x7E*/ HID_USAGE_INDEX_KEYPAD_COMMA //Brazilian Number Pad "."
  330. };
  331. //The keys in this table appear only on extended (101 and 104 key, keyboards).
  332. //These are two byte scan codes, where the first byte is 0xE0
  333. struct EXT_SC_2_USAGE_ENTRY
  334. {
  335. UCHAR ucScanCodeLowByte; //Low Byte of Extended Scan Code (High Byte is 0xE0
  336. UCHAR ucHidUsageIndex; //0 biased index to HID USAGE
  337. };
  338. EXT_SC_2_USAGE_ENTRY XlateExtendedScanCodeToUsageTable[] =
  339. {
  340. {0x1C, HID_USAGE_INDEX_KEYPAD_ENTER},
  341. {0x1D, HID_USAGE_INDEX_KEYBOARD_RCTRL},
  342. //0x1E
  343. // . . .
  344. //0x34
  345. {0x35, HID_USAGE_INDEX_KEYPAD_BACKSLASH},
  346. //0x36
  347. {0x37, HID_USAGE_INDEX_KEYBOARD_PRINT_SCREEN},
  348. {0x38, HID_USAGE_INDEX_KEYBOARD_RALT},
  349. //0x39
  350. //. . .
  351. //0x44
  352. {0x45, HID_USAGE_INDEX_KEYPAD_NUM_LOCK},
  353. //0x46
  354. {0x47, HID_USAGE_INDEX_KEYBOARD_HOME},
  355. {0x48, HID_USAGE_INDEX_KEYBOARD_UP_ARROW},
  356. {0x49, HID_USAGE_INDEX_KEYBOARD_PAGE_UP},
  357. //0x4A
  358. {0x4B, HID_USAGE_INDEX_KEYBOARD_LEFT_ARROW},
  359. //0x4C
  360. {0x4D, HID_USAGE_INDEX_KEYBOARD_RIGHT_ARROW},
  361. //0x4E
  362. {0x4F, HID_USAGE_INDEX_KEYBOARD_END},
  363. {0x50, HID_USAGE_INDEX_KEYBOARD_DOWN_ARROW},
  364. {0x51, HID_USAGE_INDEX_KEYBOARD_PAGE_DOWN},
  365. {0x52, HID_USAGE_INDEX_KEYBOARD_INSERT},
  366. {0x53, HID_USAGE_INDEX_KEYBOARD_DELETE},
  367. {0x00, 0x00} //terminates table
  368. };
  369. #define HIGHBYTEi2(__X__) (UCHAR)(__X__>>8) //Acts on USHORT (2 byte integer)
  370. #define LOWBYTEi2(__X__) (UCHAR)(__X__&0x00FF) //Acts on USHORT (2 byte integer)
  371. /***********************************************************************************
  372. **
  373. ** void NonGameDeviceXfer::MakeKeyboardXfer(CONTROL_ITEM_XFER& rControlItemXfer, ULONG ulScanCodeCount, const PUSHORT pusScanCodes)
  374. **
  375. ** @mfunc Converts an array of scancodes into a ControlItemXfer for a keyboard.
  376. **
  377. ** @rdesc None
  378. **
  379. *************************************************************************************/
  380. void NonGameDeviceXfer::MakeKeyboardXfer
  381. (
  382. CONTROL_ITEM_XFER& rControlItemXfer, // @parm [out] caller allocated ControlItemXfer which is initialized by routine
  383. ULONG ulScanCodeCount, // @parm [in] Count of Scan codes in Array
  384. const USHORT* pusScanCodes // @parm [in] Pointer to array of scan codes
  385. )
  386. {
  387. //Clear out the data completely first
  388. memset(&rControlItemXfer, 0, sizeof(CONTROL_ITEM_XFER));
  389. //This routine only supports up to six scan codes
  390. ASSERT(ulScanCodeCount <= c_ulMaxXFerKeys);
  391. UCHAR ucUsageIndex;
  392. ULONG ulKeyArrayIndex = 0;
  393. //Mark as Keyboard CONTROL_ITEM_XFER
  394. rControlItemXfer.ulItemIndex = NonGameDeviceXfer::ulKeyboardIndex;
  395. //Start with no modifier keys down
  396. rControlItemXfer.Keyboard.ucModifierByte = 0;
  397. //Loop over all scan codes
  398. for(ULONG ulScanCodeIndex = 0; ulScanCodeIndex < ulScanCodeCount; ulScanCodeIndex++)
  399. {
  400. //Check High Byte to determine which table
  401. if( 0xE0 == HIGHBYTEi2(pusScanCodes[ulScanCodeIndex]) )
  402. {
  403. //Use Extended keytable - need a search algorithm rather than direct lookup
  404. UCHAR ucScanCodeLowByte = LOWBYTEi2(pusScanCodes[ulScanCodeIndex]);
  405. ucUsageIndex = HID_USAGE_INDEX_KEYBOARD_UNDEFINED;
  406. //Sequential Search (there are only 15 items) BUGBUG - change to Binary search time permitting
  407. for(ULONG ulTableIndex=0; XlateExtendedScanCodeToUsageTable[ulTableIndex].ucScanCodeLowByte != 0; ulTableIndex++)
  408. {
  409. if( XlateExtendedScanCodeToUsageTable[ulTableIndex].ucScanCodeLowByte == ucScanCodeLowByte)
  410. {
  411. ucUsageIndex = XlateExtendedScanCodeToUsageTable[ulTableIndex].ucHidUsageIndex;
  412. break;
  413. }
  414. }
  415. ASSERT(HID_USAGE_INDEX_KEYBOARD_UNDEFINED != ucUsageIndex);
  416. }
  417. else
  418. {
  419. //Use Main Lookup table
  420. ASSERT( 0x7E >= LOWBYTEi2(pusScanCodes[ulScanCodeIndex]) &&
  421. 0x54 != LOWBYTEi2(pusScanCodes[ulScanCodeIndex]) &&
  422. 0x55 != LOWBYTEi2(pusScanCodes[ulScanCodeIndex])
  423. );
  424. if( 0x58 >= LOWBYTEi2(pusScanCodes[ulScanCodeIndex]) )
  425. {
  426. ucUsageIndex = XlateScanCodeToUsageTable[ LOWBYTEi2(pusScanCodes[ulScanCodeIndex]) ];
  427. }
  428. //Try lookup table 2
  429. else if(
  430. 0x70 <= LOWBYTEi2(pusScanCodes[ulScanCodeIndex]) &&
  431. 0x7E >= LOWBYTEi2(pusScanCodes[ulScanCodeIndex])
  432. )
  433. {
  434. ucUsageIndex = XlateScanCodeToUsageTable2[ LOWBYTEi2(pusScanCodes[ulScanCodeIndex])-0x70 ];
  435. }
  436. else
  437. {
  438. ucUsageIndex = 0x00;
  439. }
  440. }
  441. //Check if USAGE is a special one that belongs in modifier byte
  442. if(0xE0 <= ucUsageIndex && 0xE7 >= ucUsageIndex)
  443. {
  444. //Set bit in modifier byte
  445. UCHAR ucModifierBitMask = 1 << (ucUsageIndex - 0xE0);
  446. rControlItemXfer.Keyboard.ucModifierByte |= ucModifierBitMask;
  447. }
  448. else
  449. //otherwise add to array of down keys
  450. {
  451. rControlItemXfer.Keyboard.rgucKeysDown[ulKeyArrayIndex++] = ucUsageIndex;
  452. }
  453. }//end of loop over scan codes
  454. //Clean up unused spots in rgucKeysDownArray
  455. while(ulKeyArrayIndex < c_ulMaxXFerKeys)
  456. {
  457. rControlItemXfer.Keyboard.rgucKeysDown[ulKeyArrayIndex++] = HID_USAGE_INDEX_KEYBOARD_NOEVENT;
  458. }
  459. }
  460. void NonGameDeviceXfer::MakeKeyboardXfer(CONTROL_ITEM_XFER& rControlItemXfer, const IE_KEYEVENT& rKeyEvent)
  461. {
  462. //This routine only supports up to six scan codes
  463. ASSERT(rKeyEvent.uCount <= c_ulMaxXFerKeys);
  464. UCHAR ucUsageIndex;
  465. ULONG ulKeyArrayIndex = 0;
  466. //Clear out the data completely first
  467. memset(&rControlItemXfer, 0, sizeof(CONTROL_ITEM_XFER));
  468. //Mark as Keyboard CONTROL_ITEM_XFER
  469. rControlItemXfer.ulItemIndex = NonGameDeviceXfer::ulKeyboardIndex;
  470. //Start with no modifier keys down
  471. rControlItemXfer.Keyboard.ucModifierByte = 0;
  472. //Loop over all scan codes
  473. for(ULONG ulScanCodeIndex = 0; ulScanCodeIndex < rKeyEvent.uCount; ulScanCodeIndex++)
  474. {
  475. WORD wScanCode = rKeyEvent.KeyStrokes[ulScanCodeIndex].wScanCode;
  476. //Check High Byte to determine which table
  477. if( 0xE0 == HIGHBYTEi2(wScanCode) )
  478. {
  479. //Use Extended keytable - need a search algorithm rather than direct lookup
  480. UCHAR ucScanCodeLowByte = LOWBYTEi2(wScanCode);
  481. ucUsageIndex = HID_USAGE_INDEX_KEYBOARD_UNDEFINED;
  482. //Sequential Search (there are only 15 items) BUGBUG - change to Binary search time permitting
  483. for(ULONG ulTableIndex=0; XlateExtendedScanCodeToUsageTable[ulTableIndex].ucScanCodeLowByte != 0; ulTableIndex++)
  484. {
  485. if( XlateExtendedScanCodeToUsageTable[ulTableIndex].ucScanCodeLowByte == ucScanCodeLowByte)
  486. {
  487. ucUsageIndex = XlateExtendedScanCodeToUsageTable[ulTableIndex].ucHidUsageIndex;
  488. break;
  489. }
  490. }
  491. ASSERT(HID_USAGE_INDEX_KEYBOARD_UNDEFINED != ucUsageIndex);
  492. }
  493. else
  494. {
  495. //Use Main Lookup table
  496. ASSERT( 0x53 >= LOWBYTEi2(wScanCode) || 0x56 == LOWBYTEi2(wScanCode));
  497. ucUsageIndex = XlateScanCodeToUsageTable[ LOWBYTEi2(wScanCode) ];
  498. }
  499. //Check if USAGE is a special one that belongs in modifier byte
  500. if(0xE0 <= ucUsageIndex && 0xE7 >= ucUsageIndex)
  501. {
  502. //Set bit in modifier byte
  503. UCHAR ucModifierBitMask = 1 << (ucUsageIndex - 0xE0);
  504. rControlItemXfer.Keyboard.ucModifierByte |= ucModifierBitMask;
  505. }
  506. else
  507. //otherwise add to array of down keys
  508. {
  509. rControlItemXfer.Keyboard.rgucKeysDown[ulKeyArrayIndex++] = ucUsageIndex;
  510. }
  511. }//end of loop over scan codes
  512. //Clean up unused spots in rgucKeysDownArray
  513. while(ulKeyArrayIndex < c_ulMaxXFerKeys)
  514. {
  515. rControlItemXfer.Keyboard.rgucKeysDown[ulKeyArrayIndex++] = HID_USAGE_INDEX_KEYBOARD_NOEVENT;
  516. }
  517. }
  518. void NonGameDeviceXfer::AddScanCodeToXfer(CONTROL_ITEM_XFER& rControlItemXfer, WORD wScanCode)
  519. {
  520. // Is the xfer event a keyboard one?
  521. _ASSERTE(rControlItemXfer.ulItemIndex == NonGameDeviceXfer::ulKeyboardIndex);
  522. if (rControlItemXfer.ulItemIndex != NonGameDeviceXfer::ulKeyboardIndex)
  523. {
  524. return;
  525. }
  526. UCHAR ucUsageIndex;
  527. //Check High Byte to determine which table
  528. if (0xE0 == HIGHBYTEi2(wScanCode))
  529. {
  530. //Use Extended keytable - need a search algorithm rather than direct lookup
  531. UCHAR ucScanCodeLowByte = LOWBYTEi2(wScanCode);
  532. ucUsageIndex = HID_USAGE_INDEX_KEYBOARD_UNDEFINED;
  533. //Sequential Search (there are only 15 items) BUGBUG - change to Binary search time permitting
  534. for (ULONG ulTableIndex=0; XlateExtendedScanCodeToUsageTable[ulTableIndex].ucScanCodeLowByte != 0; ulTableIndex++)
  535. {
  536. if (XlateExtendedScanCodeToUsageTable[ulTableIndex].ucScanCodeLowByte == ucScanCodeLowByte)
  537. {
  538. ucUsageIndex = XlateExtendedScanCodeToUsageTable[ulTableIndex].ucHidUsageIndex;
  539. break;
  540. }
  541. }
  542. ASSERT(HID_USAGE_INDEX_KEYBOARD_UNDEFINED != ucUsageIndex);
  543. }
  544. else
  545. { //Use Main Lookup table
  546. ASSERT (0x53 >= LOWBYTEi2(wScanCode) || 0x56 == LOWBYTEi2(wScanCode));
  547. ucUsageIndex = XlateScanCodeToUsageTable[LOWBYTEi2(wScanCode)];
  548. }
  549. // Check if USAGE is a special one that belongs in modifier byte
  550. if (0xE0 <= ucUsageIndex && 0xE7 >= ucUsageIndex)
  551. { //Set bit in modifier byte
  552. UCHAR ucModifierBitMask = 1 << (ucUsageIndex - 0xE0);
  553. rControlItemXfer.Keyboard.ucModifierByte |= ucModifierBitMask;
  554. }
  555. else
  556. { //otherwise add to array of down keys
  557. ULONG ulKeyArrayIndex = 0;
  558. while (rControlItemXfer.Keyboard.rgucKeysDown[ulKeyArrayIndex] != HID_USAGE_INDEX_KEYBOARD_NOEVENT)
  559. {
  560. if (ulKeyArrayIndex >= c_ulMaxXFerKeys)
  561. {
  562. return; // There is no space left
  563. }
  564. ulKeyArrayIndex++;
  565. }
  566. rControlItemXfer.Keyboard.rgucKeysDown[ulKeyArrayIndex] = ucUsageIndex;
  567. }
  568. }
  569. USHORT XlateUsageToScanCodeTable[] =
  570. {
  571. /*HID_USAGE_INDEX_KEYBOARD_NOEVENT(0x00)*/
  572. /*HID_USAGE_INDEX_KEYBOARD_ROLLOVER(0x01)*/
  573. /*HID_USAGE_INDEX_KEYBOARD_POSTFAIL(0x02)*/
  574. /*HID_USAGE_INDEX_KEYBOARD_UNDEFINED(0x03)*/
  575. //Due to above four special codes, 4 should be subtracted
  576. //from the usage before lookup
  577. /*HID_USAGE_INDEX_KEYBOARD_aA(0x04)*/ SCANCODE_A,
  578. /*HID_USAGE_INDEX_KEYBOARD_bB(0x05)*/ SCANCODE_B,
  579. /*HID_USAGE_INDEX_KEYBOARD_cC(0x06)*/ SCANCODE_C,
  580. /*HID_USAGE_INDEX_KEYBOARD_dD(0x07)*/ SCANCODE_D,
  581. /*HID_USAGE_INDEX_KEYBOARD_eE(0x08)*/ SCANCODE_E,
  582. /*HID_USAGE_INDEX_KEYBOARD_fF(0x09)*/ SCANCODE_F,
  583. /*HID_USAGE_INDEX_KEYBOARD_gG(0x0A)*/ SCANCODE_G,
  584. /*HID_USAGE_INDEX_KEYBOARD_hH(0x0B)*/ SCANCODE_H,
  585. /*HID_USAGE_INDEX_KEYBOARD_iI(0x0C)*/ SCANCODE_I,
  586. /*HID_USAGE_INDEX_KEYBOARD_jJ(0x0D)*/ SCANCODE_J,
  587. /*HID_USAGE_INDEX_KEYBOARD_kK(0x0E)*/ SCANCODE_K,
  588. /*HID_USAGE_INDEX_KEYBOARD_lL(0x0F)*/ SCANCODE_L,
  589. /*HID_USAGE_INDEX_KEYBOARD_mM(0x10)*/ SCANCODE_M,
  590. /*HID_USAGE_INDEX_KEYBOARD_nN(0x11)*/ SCANCODE_N,
  591. /*HID_USAGE_INDEX_KEYBOARD_oO(0x12)*/ SCANCODE_O,
  592. /*HID_USAGE_INDEX_KEYBOARD_pP(0x13)*/ SCANCODE_P,
  593. /*HID_USAGE_INDEX_KEYBOARD_qQ(0x14)*/ SCANCODE_Q,
  594. /*HID_USAGE_INDEX_KEYBOARD_rR(0x15)*/ SCANCODE_R,
  595. /*HID_USAGE_INDEX_KEYBOARD_sS(0x16)*/ SCANCODE_S,
  596. /*HID_USAGE_INDEX_KEYBOARD_tT(0x17)*/ SCANCODE_T,
  597. /*HID_USAGE_INDEX_KEYBOARD_uU(0x18)*/ SCANCODE_U,
  598. /*HID_USAGE_INDEX_KEYBOARD_vV(0x19)*/ SCANCODE_V,
  599. /*HID_USAGE_INDEX_KEYBOARD_wW(0x1A)*/ SCANCODE_W,
  600. /*HID_USAGE_INDEX_KEYBOARD_xX(0x1B)*/ SCANCODE_X,
  601. /*HID_USAGE_INDEX_KEYBOARD_yY(0x1C)*/ SCANCODE_Y,
  602. /*HID_USAGE_INDEX_KEYBOARD_zZ(0x1D)*/ SCANCODE_Z,
  603. /*HID_USAGE_INDEX_KEYBOARD_ONE(0x1E)*/ SCANCODE_1,
  604. /*HID_USAGE_INDEX_KEYBOARD_TWO(0x1F)*/ SCANCODE_2,
  605. /*HID_USAGE_INDEX_KEYBOARD_THREE(0x20)*/ SCANCODE_3,
  606. /*HID_USAGE_INDEX_KEYBOARD_FOUR(0x21)*/ SCANCODE_4,
  607. /*HID_USAGE_INDEX_KEYBOARD_FIVE(0x22)*/ SCANCODE_5,
  608. /*HID_USAGE_INDEX_KEYBOARD_SIX(0x23)*/ SCANCODE_6,
  609. /*HID_USAGE_INDEX_KEYBOARD_SEVEN(0x24)*/ SCANCODE_7,
  610. /*HID_USAGE_INDEX_KEYBOARD_EIGHT(0x25)*/ SCANCODE_8,
  611. /*HID_USAGE_INDEX_KEYBOARD_NINE(0x26)*/ SCANCODE_9,
  612. /*HID_USAGE_INDEX_KEYBOARD_ZERO(0x27)*/ SCANCODE_0,
  613. /*HID_USAGE_INDEX_KEYBOARD_RETURN(0x28)*/ SCANCODE_RETURN,
  614. /*HID_USAGE_INDEX_KEYBOARD_ESCAPE(0x29)*/ SCANCODE_ESCAPE,
  615. /*HID_USAGE_INDEX_KEYBOARD_BACKSPACE(0x2A)*/ SCANCODE_BACKSPACE,
  616. /*HID_USAGE_INDEX_KEYBOARD_TAB(0x2B)*/ SCANCODE_TAB,
  617. /*HID_USAGE_INDEX_KEYBOARD_SPACEBAR(0x2C)*/ SCANCODE_SPACE,
  618. /*HID_USAGE_INDEX_KEYBOARD_MINUS(0x2D)*/ SCANCODE_MINUS,
  619. /*HID_USAGE_INDEX_KEYBOARD_EQUALS(0x2E)*/ SCANCODE_EQUALS,
  620. /*HID_USAGE_INDEX_KEYBOARD_OPEN_BRACE(0x2F)*/ SCANCODE_LEFT_BRACKET,
  621. /*HID_USAGE_INDEX_KEYBOARD_CLOSE_BRACE(0x30)*/ SCANCODE_RIGHT_BRACKET,
  622. /*HID_USAGE_INDEX_KEYBOARD_BACKSLASH(0x31)*/ SCANCODE_BACKSLASH,
  623. /*HID_USAGE_INDEX_KEYBOARD_NON_US_TILDE(0x32)*/ SCANCODE_BACKSLASH, //NOT SURE, got from hidparse.sys code
  624. /*HID_USAGE_INDEX_KEYBOARD_COLON(0x33)*/ SCANCODE_SEMICOLON,
  625. /*HID_USAGE_INDEX_KEYBOARD_QUOTE(0x34)*/ SCANCODE_APOSTROPHE,
  626. /*HID_USAGE_INDEX_KEYBOARD_TILDE(0x35)*/ SCANCODE_TILDE,
  627. /*HID_USAGE_INDEX_KEYBOARD_COMMA(0x36)*/ SCANCODE_COMMA,
  628. /*HID_USAGE_INDEX_KEYBOARD_PERIOD(0x37)*/ SCANCODE_PERIOD,
  629. /*HID_USAGE_INDEX_KEYBOARD_QUESTION(0x38)*/ SCANCODE_QUESTIONMARK,
  630. /*HID_USAGE_INDEX_KEYBOARD_CAPS_LOCK(0x39)*/ SCANCODE_CAPSLOCK,
  631. /*HID_USAGE_INDEX_KEYBOARD_F1(0x3A)*/ SCANCODE_F1,
  632. /*HID_USAGE_INDEX_KEYBOARD_F2(0x3B)*/ SCANCODE_F2,
  633. /*HID_USAGE_INDEX_KEYBOARD_F3(0x3C)*/ SCANCODE_F3,
  634. /*HID_USAGE_INDEX_KEYBOARD_F4(0x3D)*/ SCANCODE_F4,
  635. /*HID_USAGE_INDEX_KEYBOARD_F5(0x3E)*/ SCANCODE_F5,
  636. /*HID_USAGE_INDEX_KEYBOARD_F6(0x3F)*/ SCANCODE_F6,
  637. /*HID_USAGE_INDEX_KEYBOARD_F7(0x40)*/ SCANCODE_F7,
  638. /*HID_USAGE_INDEX_KEYBOARD_F8(0x41)*/ SCANCODE_F8,
  639. /*HID_USAGE_INDEX_KEYBOARD_F9(0x42)*/ SCANCODE_F9,
  640. /*HID_USAGE_INDEX_KEYBOARD_F10(0x43)*/ SCANCODE_F10,
  641. /*HID_USAGE_INDEX_KEYBOARD_F11(0x44)*/ SCANCODE_F11,
  642. /*HID_USAGE_INDEX_KEYBOARD_F12(0x45)*/ SCANCODE_F12,
  643. /*HID_USAGE_INDEX_KEYBOARD_PRINT_SCREEN(0x46)*/ SCANCODE_PRINT_SCREEN,
  644. /*HID_USAGE_INDEX_KEYBOARD_SCROLL_LOCK(0x47)*/ SCANCODE_SCROLL_LOCK,
  645. /*HID_USAGE_INDEX_KEYBOARD_PAUSE(0x48)*/ SCANCODE_PAUSE_BREAK,
  646. /*HID_USAGE_INDEX_KEYBOARD_INSERT(0x49)*/ SCANCODE_INSERT,
  647. /*HID_USAGE_INDEX_KEYBOARD_HOME(0x4A)*/ SCANCODE_HOME,
  648. /*HID_USAGE_INDEX_KEYBOARD_PAGE_UP(0x4B)*/ SCANCODE_PAGE_UP,
  649. /*HID_USAGE_INDEX_KEYBOARD_DELETE(0x4C)*/ SCANCODE_DELETE,
  650. /*HID_USAGE_INDEX_KEYBOARD_END(0x4D)*/ SCANCODE_END,
  651. /*HID_USAGE_INDEX_KEYBOARD_PAGE_DOWN(0x4E)*/ SCANCODE_PAGEDOWN,
  652. /*HID_USAGE_INDEX_KEYBOARD_RIGHT_ARROW(0x4F)*/ SCANCODE_EAST,
  653. /*HID_USAGE_INDEX_KEYBOARD_LEFT_ARROW(0x50)*/ SCANCODE_WEST,
  654. /*HID_USAGE_INDEX_KEYBOARD_DOWN_ARROW(0x51)*/ SCANCODE_SOUTH,
  655. /*HID_USAGE_INDEX_KEYBOARD_UP_ARROW(0x52)*/ SCANCODE_NORTH,
  656. /*HID_USAGE_INDEX_KEYPAD_NUM_LOCK(0x53)*/ SCANCODE_NUMPAD_NUMLOCK,
  657. /*HID_USAGE_INDEX_KEYPAD_BACKSLASH(0x54)*/ SCANCODE_NUMPAD_DIVIDE,
  658. /*HID_USAGE_INDEX_KEYPAD_ASTERICK(0x55)*/ SCANCODE_NUMPAD_MULTIPLY,
  659. /*HID_USAGE_INDEX_KEYPAD_MINUS(0x56)*/ SCANCODE_NUMPAD_SUBTRACT,
  660. /*HID_USAGE_INDEX_KEYPAD_PLUS(0x57)*/ SCANCODE_NUMPAD_ADD,
  661. /*HID_USAGE_INDEX_KEYPAD_ENTER(0x58)*/ SCANCODE_NUMPAD_ENTER,
  662. /*HID_USAGE_INDEX_KEYPAD_ONE(0x59)*/ SCANCODE_NUMPAD_1,
  663. /*HID_USAGE_INDEX_KEYPAD_TWO(0x5A)*/ SCANCODE_NUMPAD_2,
  664. /*HID_USAGE_INDEX_KEYPAD_THREE(0x5B)*/ SCANCODE_NUMPAD_3,
  665. /*HID_USAGE_INDEX_KEYPAD_FOUR(0x5C)*/ SCANCODE_NUMPAD_4,
  666. /*HID_USAGE_INDEX_KEYPAD_FIVE(0x5D)*/ SCANCODE_NUMPAD_5,
  667. /*HID_USAGE_INDEX_KEYPAD_SIX(0x5E)*/ SCANCODE_NUMPAD_6,
  668. /*HID_USAGE_INDEX_KEYPAD_SEVEN(0x5F)*/ SCANCODE_NUMPAD_7,
  669. /*HID_USAGE_INDEX_KEYPAD_EIGHT(0x60)*/ SCANCODE_NUMPAD_8,
  670. /*HID_USAGE_INDEX_KEYPAD_NINE(0x61)*/ SCANCODE_NUMPAD_9,
  671. /*HID_USAGE_INDEX_KEYPAD_ZERO(0x62)*/ SCANCODE_NUMPAD_0,
  672. /*HID_USAGE_INDEX_KEYPAD_DECIMAL(0x63)*/ SCANCODE_NUMPAD_DELETE,
  673. /*HID_USAGE_INDEX_KEYBOARD_NON_US_BACKSLASH(0x64)*/ SCANCODE_NON_US_BACKSLASH,
  674. /*HID_USAGE_INDEX_KEYBOARD_APPLICATION(0x65)*/ SCANCODE_APPLICATION
  675. /*HID_USAGE_INDEX_KEYBOARD_POWER(0x66)*/ //Not a real key
  676. /*HID_USAGE_INDEX_KEYPAD_EQUALS(0x67)*/ //Not on supported keyboards
  677. };
  678. USHORT XlateUsageToScanCodeTable2[] =
  679. {
  680. /*HID_USAGE_INDEX_KEYPAD_COMMA*/ SCANCODE_BRAZILIAN_PERIOD,
  681. /*HID_USAGE_INDEX_KEYPAD_EQUALS*/ SCANCODE_UNUSED,
  682. /*HID_USAGE_INDEX_KEYBOARD_INTERNATIONAL1*/ SCANCODE_INTERNATIONAL1,
  683. /*HID_USAGE_INDEX_KEYBOARD_INTERNALIONAL2*/ SCANCODE_UNUSED,
  684. /*HID_USAGE_INDEX_KEYBOARD_INTERNALIONAL3*/ SCANCODE_INTERNATIONAL3,
  685. /*HID_USAGE_INDEX_KEYBOARD_INTERNALIONAL4*/ SCANCODE_INTERNATIONAL4,
  686. /*HID_USAGE_INDEX_KEYBOARD_INTERNALIONAL5*/ SCANCODE_INTERNATIONAL5
  687. /*HID_USAGE_INDEX_KEYBOARD_INTERNALIONAL6*/
  688. /*HID_USAGE_INDEX_KEYBOARD_INTERNALIONAL7*/
  689. /*HID_USAGE_INDEX_KEYBOARD_INTERNALIONAL8*/
  690. /*HID_USAGE_INDEX_KEYBOARD_INTERNALIONAL9*/
  691. /*HID_USAGE_INDEX_KEYBOARD_LANG1*/
  692. /*HID_USAGE_INDEX_KEYBOARD_LANG2*/
  693. /*HID_USAGE_INDEX_KEYBOARD_LANG3*/
  694. /*HID_USAGE_INDEX_KEYBOARD_LANG4*/
  695. /*HID_USAGE_INDEX_KEYBOARD_LANG5*/
  696. };
  697. USHORT XlateUsageModByteToScanCodeTable[] =
  698. {
  699. /*HID_USAGE_INDEX_KEYBOARD_LCTRL(0xE0)*/ SCANCODE_CTRL_LEFT,
  700. /*HID_USAGE_INDEX_KEYBOARD_LSHFT(0xE1)*/ SCANCODE_SHIFT_LEFT,
  701. /*HID_USAGE_INDEX_KEYBOARD_LALT(0xE2)*/ SCANCODE_ALT_LEFT,
  702. /*HID_USAGE_INDEX_KEYBOARD_LGUI(0xE3)*/ SCANCODE_LEFT_WIN,
  703. /*HID_USAGE_INDEX_KEYBOARD_RCTRL(0xE4)*/ SCANCODE_CTRL_RIGHT,
  704. /*HID_USAGE_INDEX_KEYBOARD_RSHFT(0xE5)*/ SCANCODE_SHIFT_RIGHT,
  705. /*HID_USAGE_INDEX_KEYBOARD_RALT(0xE6)*/ SCANCODE_ALT_RIGHT,
  706. /*HID_USAGE_INDEX_KEYBOARD_RGUI(0xE7)*/ SCANCODE_RIGHT_WIN
  707. };
  708. /***********************************************************************************
  709. **
  710. ** void NonGameDeviceXfer::ScanCodesFromKeyboardXfer(const CONTROL_ITEM_XFER& crControlItemXfer, ULONG& rulScanCodeCount, PUSHORT pusScanCodes)
  711. **
  712. ** @mfunc Reads a ControlItemXfer for a keyboard into an array of scan codes.
  713. **
  714. **
  715. *************************************************************************************/
  716. void NonGameDeviceXfer::ScanCodesFromKeyboardXfer
  717. (
  718. const CONTROL_ITEM_XFER& crControlItemXfer, // @parm [in] ControlItemXfer to read scan code from
  719. ULONG& rulScanCodeCount, // @parm [in\out] Allocated space on entry, count returned on exit
  720. USHORT* pusScanCodes // @parm [out] Pointer to array to receive scancode
  721. )
  722. {
  723. ULONG ulMaxScanCodes;
  724. ULONG ulIndex;
  725. ulMaxScanCodes = rulScanCodeCount;
  726. ASSERT(ulMaxScanCodes > 0);
  727. if(0==ulMaxScanCodes) return;
  728. rulScanCodeCount = 0;
  729. //make sure this really contains keyboard data.
  730. ASSERT( IsKeyboardXfer(crControlItemXfer) );
  731. if(!IsKeyboardXfer(crControlItemXfer))
  732. return;
  733. //Process modifier Byte
  734. for(ulIndex = 0; ulIndex < 8; ulIndex++)
  735. {
  736. ULONG ulMask = (1 << ulIndex);
  737. if(crControlItemXfer.Keyboard.ucModifierByte & ulMask)
  738. {
  739. //lookup scan code
  740. pusScanCodes[rulScanCodeCount] = XlateUsageModByteToScanCodeTable[ulIndex];
  741. //move to next free spot in output, return if output is full
  742. if(ulMaxScanCodes == ++rulScanCodeCount)
  743. return;
  744. }
  745. }
  746. //Process array of up to six keys down first
  747. for(ulIndex = 0; ulIndex < c_ulMaxXFerKeys; ulIndex++)
  748. {
  749. //check main conversion table
  750. if(
  751. HID_USAGE_INDEX_KEYBOARD_aA <= crControlItemXfer.Keyboard.rgucKeysDown[ulIndex] &&
  752. HID_USAGE_INDEX_KEYBOARD_APPLICATION >= crControlItemXfer.Keyboard.rgucKeysDown[ulIndex]
  753. )
  754. {
  755. //lookup scan code
  756. pusScanCodes[rulScanCodeCount] = XlateUsageToScanCodeTable[crControlItemXfer.Keyboard.rgucKeysDown[ulIndex]-4];
  757. if( SCANCODE_UNUSED == pusScanCodes[rulScanCodeCount]) continue;
  758. }
  759. //check secondary table
  760. else if(
  761. HID_USAGE_INDEX_KEYPAD_COMMA <= crControlItemXfer.Keyboard.rgucKeysDown[ulIndex] &&
  762. HID_USAGE_INDEX_KEYBOARD_INTERNATIONAL5 >= crControlItemXfer.Keyboard.rgucKeysDown[ulIndex]
  763. )
  764. {
  765. //lookup scan code in secondary table
  766. pusScanCodes[rulScanCodeCount] = XlateUsageToScanCodeTable2[crControlItemXfer.Keyboard.rgucKeysDown[ulIndex]-HID_USAGE_INDEX_KEYPAD_COMMA];
  767. if( SCANCODE_UNUSED == pusScanCodes[rulScanCodeCount]) continue;
  768. }
  769. else
  770. {
  771. //not a supported key
  772. continue;
  773. }
  774. //move to next free spot in output, return if output is full
  775. if(ulMaxScanCodes == ++rulScanCodeCount)
  776. return;
  777. }
  778. return;
  779. }
  780. /************** Dealy XFer Functions ***************************/
  781. void NonGameDeviceXfer::MakeDelayXfer(CONTROL_ITEM_XFER& rControlItemXfer, DWORD dwDelay)
  782. {
  783. // Clear out the data completely first
  784. memset(&rControlItemXfer, 0, sizeof(CONTROL_ITEM_XFER));
  785. // Mark as Delay CONTROL_ITEM_XFER
  786. rControlItemXfer.ulItemIndex = NonGameDeviceXfer::ulKeyboardIndex;
  787. rControlItemXfer.Delay.dwValue = dwDelay;
  788. }