scancode.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. /*++
  2. Copyright (c) 2012 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. scancode.c
  5. Abstract:
  6. This module impelements support for converting between scancodes used
  7. in keyboards to OS key abstractions.
  8. Author:
  9. Evan Green 21-Dec-2012
  10. Environment:
  11. Kernel
  12. --*/
  13. //
  14. // ------------------------------------------------------------------- Includes
  15. //
  16. #include <minoca/kernel/driver.h>
  17. #include "i8042.h"
  18. //
  19. // ---------------------------------------------------------------- Definitions
  20. //
  21. #define MAX_SCAN_CODE_1 0x7F
  22. #define SCAN_CODE_1_KEY_UP 0x80
  23. #define SCAN_CODE_1_EXTENDED_KEY_COUNT 41
  24. #define SCAN_CODE_1_EXTENDED_2_KEY_COUNT 1
  25. //
  26. // ------------------------------------------------------ Data Type Definitions
  27. //
  28. typedef struct _EXTENDED_KEY_DESCRIPTION {
  29. UCHAR ScanCode;
  30. KEYBOARD_KEY Key;
  31. } EXTENDED_KEY_DESCRIPTION, *PEXTENDED_KEY_DESCRIPTION;
  32. typedef struct _EXTENDED_2_KEY_DESCRIPTION {
  33. UCHAR ScanCode1;
  34. UCHAR ScanCode2;
  35. KEYBOARD_KEY Key;
  36. } EXTENDED_2_KEY_DESCRIPTION, *PEXTENDED_2_KEY_DESCRIPTION;
  37. //
  38. // ----------------------------------------------- Internal Function Prototypes
  39. //
  40. //
  41. // -------------------------------------------------------------------- Globals
  42. //
  43. KEYBOARD_KEY I8042ScanCodeSet1KeyTable[MAX_SCAN_CODE_1] = {
  44. KeyboardKeyInvalid, /* 00 */
  45. KeyboardKeyEscape,
  46. KeyboardKey1,
  47. KeyboardKey2,
  48. KeyboardKey3,
  49. KeyboardKey4,
  50. KeyboardKey5,
  51. KeyboardKey6,
  52. KeyboardKey7,
  53. KeyboardKey8,
  54. KeyboardKey9,
  55. KeyboardKey0,
  56. KeyboardKeyDash,
  57. KeyboardKeyEquals,
  58. KeyboardKeyBackspace,
  59. KeyboardKeyTab,
  60. KeyboardKeyQ, /* 10 */
  61. KeyboardKeyW,
  62. KeyboardKeyE,
  63. KeyboardKeyR,
  64. KeyboardKeyT,
  65. KeyboardKeyY,
  66. KeyboardKeyU,
  67. KeyboardKeyI,
  68. KeyboardKeyO,
  69. KeyboardKeyP,
  70. KeyboardKeyLeftBracket,
  71. KeyboardKeyRightBracket,
  72. KeyboardKeyEnter,
  73. KeyboardKeyLeftControl,
  74. KeyboardKeyA,
  75. KeyboardKeyS,
  76. KeyboardKeyD, /* 20 */
  77. KeyboardKeyF,
  78. KeyboardKeyG,
  79. KeyboardKeyH,
  80. KeyboardKeyJ,
  81. KeyboardKeyK,
  82. KeyboardKeyL,
  83. KeyboardKeySemicolon,
  84. KeyboardKeyApostrophe,
  85. KeyboardKeyTilde,
  86. KeyboardKeyLeftShift,
  87. KeyboardKeyBackslash,
  88. KeyboardKeyZ,
  89. KeyboardKeyX,
  90. KeyboardKeyC,
  91. KeyboardKeyV,
  92. KeyboardKeyB, /* 30 */
  93. KeyboardKeyN,
  94. KeyboardKeyM,
  95. KeyboardKeyComma,
  96. KeyboardKeyPeriod,
  97. KeyboardKeySlash,
  98. KeyboardKeyRightShift,
  99. KeyboardKeyKeypadAsterisk,
  100. KeyboardKeyLeftAlt,
  101. KeyboardKeySpace,
  102. KeyboardKeyCapsLock,
  103. KeyboardKeyF1,
  104. KeyboardKeyF2,
  105. KeyboardKeyF3,
  106. KeyboardKeyF4,
  107. KeyboardKeyF5,
  108. KeyboardKeyF6, /* 40 */
  109. KeyboardKeyF7,
  110. KeyboardKeyF8,
  111. KeyboardKeyF9,
  112. KeyboardKeyF10,
  113. KeyboardKeyNumLock,
  114. KeyboardKeyScrollLock,
  115. KeyboardKeyKeypad7,
  116. KeyboardKeyKeypad8,
  117. KeyboardKeyKeypad9,
  118. KeyboardKeyKeypadMinus,
  119. KeyboardKeyKeypad4,
  120. KeyboardKeyKeypad5,
  121. KeyboardKeyKeypad6,
  122. KeyboardKeyKeypadPlus,
  123. KeyboardKeyKeypad1,
  124. KeyboardKeyKeypad2, /* 50 */
  125. KeyboardKeyKeypad3,
  126. KeyboardKeyKeypad0,
  127. KeyboardKeyKeypadPeriod,
  128. KeyboardKeySysRq,
  129. KeyboardKeyInvalid,
  130. KeyboardKeyInternational1,
  131. KeyboardKeyF11,
  132. KeyboardKeyF12,
  133. KeyboardKeyInvalid,
  134. KeyboardKeyInvalid,
  135. KeyboardKeyF13,
  136. KeyboardKeyF14,
  137. KeyboardKeyF15,
  138. KeyboardKeyInvalid,
  139. KeyboardKeyInvalid,
  140. KeyboardKeyInvalid, /* 60 */
  141. KeyboardKeyInvalid,
  142. KeyboardKeyInvalid,
  143. KeyboardKeyF16,
  144. KeyboardKeyF17,
  145. KeyboardKeyF18,
  146. KeyboardKeyF19,
  147. KeyboardKeyF20,
  148. KeyboardKeyF21,
  149. KeyboardKeyF22,
  150. KeyboardKeyF23,
  151. KeyboardKeyF24,
  152. KeyboardKeyInvalid,
  153. KeyboardKeyInvalid,
  154. KeyboardKeyInvalid,
  155. KeyboardKeyInvalid,
  156. KeyboardKeyKatakana, /* 70 */
  157. KeyboardKeyInvalid,
  158. KeyboardKeyInvalid,
  159. KeyboardKeyInternational3,
  160. KeyboardKeyInvalid,
  161. KeyboardKeyInvalid,
  162. KeyboardKeyInvalid,
  163. KeyboardKeyFurigana,
  164. KeyboardKeyInvalid,
  165. KeyboardKeyKanji,
  166. KeyboardKeyInvalid,
  167. KeyboardKeyHirijana,
  168. KeyboardKeyInvalid,
  169. KeyboardKeyInternational4,
  170. KeyboardKeyInternational5,
  171. };
  172. EXTENDED_KEY_DESCRIPTION
  173. I8042ScanCodeSet1ExtendedKeyTable[SCAN_CODE_1_EXTENDED_KEY_COUNT] = {
  174. {0x07, KeyboardKeyRedo},
  175. {0x08, KeyboardKeyUndo},
  176. {0x0A, KeyboardKeyPaste},
  177. {0x10, KeyboardKeySkipBack},
  178. {0x17, KeyboardKeyCut},
  179. {0x18, KeyboardKeyCopy},
  180. {0x19, KeyboardKeySkipForward},
  181. {0x1C, KeyboardKeyKeypadEnter},
  182. {0x1D, KeyboardKeyRightControl},
  183. {0x1E, KeyboardKeyMail},
  184. {0x20, KeyboardKeyMute},
  185. {0x22, KeyboardKeyPlay},
  186. {0x24, KeyboardKeyStop},
  187. {0x2C, KeyboardKeyEject},
  188. {0x2E, KeyboardKeyVolumeDown},
  189. {0x30, KeyboardKeyVolumeUp},
  190. {0x32, KeyboardKeyWeb},
  191. {0x35, KeyboardKeyKeypadSlash},
  192. {0x37, KeyboardKeyPrintScreen},
  193. {0x38, KeyboardKeyRightAlt},
  194. {0x3B, KeyboardKeyHelp},
  195. {0x3C, KeyboardKeyMusic},
  196. {0x46, KeyboardKeyBreak},
  197. {0x47, KeyboardKeyHome},
  198. {0x48, KeyboardKeyUp},
  199. {0x49, KeyboardKeyPageUp},
  200. {0x4B, KeyboardKeyLeft},
  201. {0x4D, KeyboardKeyRight},
  202. {0x4F, KeyboardKeyEnd},
  203. {0x50, KeyboardKeyDown},
  204. {0x51, KeyboardKeyPageDown},
  205. {0x52, KeyboardKeyInsert},
  206. {0x53, KeyboardKeyDelete},
  207. {0x5B, KeyboardKeyLeftWindows},
  208. {0x5C, KeyboardKeyRightWindows},
  209. {0x5D, KeyboardKeyMenu},
  210. {0x5E, KeyboardKeyPower},
  211. {0x5F, KeyboardKeySleep},
  212. {0x63, KeyboardKeyWake},
  213. {0x64, KeyboardKeyPictures},
  214. {0x6D, KeyboardKeyVideo},
  215. };
  216. EXTENDED_2_KEY_DESCRIPTION
  217. I8042ScanCodeSet1Extended2KeyTable[SCAN_CODE_1_EXTENDED_2_KEY_COUNT] = {
  218. {0x1D, 0x45, KeyboardKeyBreak},
  219. };
  220. //
  221. // ------------------------------------------------------------------ Functions
  222. //
  223. KEYBOARD_KEY
  224. I8042ConvertScanCodeToKey (
  225. UCHAR ScanCode1,
  226. UCHAR ScanCode2,
  227. UCHAR ScanCode3,
  228. PBOOL KeyUp
  229. )
  230. /*++
  231. Routine Description:
  232. This routine converts a scan code sequence into a key.
  233. Arguments:
  234. ScanCode1 - Supplies the first scan code.
  235. ScanCode2 - Supplies an optional second scan code.
  236. ScanCode3 - Supplies an optional third scan code.
  237. KeyUp - Supplies a pointer where a boolean will be returned indicating
  238. whether the key is being released (TRUE) or pressed (FALSE).
  239. Return Value:
  240. Returns the keyboard key code associated with this scan code sequence.
  241. --*/
  242. {
  243. ULONG ExtendedIndex;
  244. KEYBOARD_KEY Key;
  245. *KeyUp = FALSE;
  246. if (ScanCode1 == SCAN_CODE_1_EXTENDED_2_CODE) {
  247. if ((ScanCode2 & SCAN_CODE_1_KEY_UP) != 0) {
  248. *KeyUp = TRUE;
  249. ScanCode2 &= ~SCAN_CODE_1_KEY_UP;
  250. ASSERT((ScanCode3 & SCAN_CODE_1_KEY_UP) != 0);
  251. ScanCode3 &= ~ SCAN_CODE_1_KEY_UP;
  252. }
  253. for (ExtendedIndex = 0;
  254. ExtendedIndex < SCAN_CODE_1_EXTENDED_2_KEY_COUNT;
  255. ExtendedIndex += 1) {
  256. if ((I8042ScanCodeSet1Extended2KeyTable[ExtendedIndex].ScanCode1 ==
  257. ScanCode2) &&
  258. (I8042ScanCodeSet1Extended2KeyTable[ExtendedIndex].ScanCode2 ==
  259. ScanCode3)) {
  260. break;
  261. }
  262. }
  263. if (ExtendedIndex == SCAN_CODE_1_EXTENDED_2_KEY_COUNT) {
  264. Key = KeyboardKeyInvalid;
  265. } else {
  266. Key = I8042ScanCodeSet1Extended2KeyTable[ExtendedIndex].Key;
  267. }
  268. } else if (ScanCode1 == SCAN_CODE_1_EXTENDED_CODE) {
  269. if ((ScanCode2 & SCAN_CODE_1_KEY_UP) != 0) {
  270. *KeyUp = TRUE;
  271. ScanCode2 &= ~SCAN_CODE_1_KEY_UP;
  272. }
  273. for (ExtendedIndex = 0;
  274. ExtendedIndex < SCAN_CODE_1_EXTENDED_KEY_COUNT;
  275. ExtendedIndex += 1) {
  276. if (I8042ScanCodeSet1ExtendedKeyTable[ExtendedIndex].ScanCode ==
  277. ScanCode2) {
  278. break;
  279. }
  280. }
  281. if (ExtendedIndex == SCAN_CODE_1_EXTENDED_KEY_COUNT) {
  282. Key = KeyboardKeyInvalid;
  283. } else {
  284. Key = I8042ScanCodeSet1ExtendedKeyTable[ExtendedIndex].Key;
  285. }
  286. } else {
  287. if ((ScanCode1 & SCAN_CODE_1_KEY_UP) != 0) {
  288. *KeyUp = TRUE;
  289. ScanCode1 &= ~SCAN_CODE_1_KEY_UP;
  290. }
  291. Key = I8042ScanCodeSet1KeyTable[ScanCode1];
  292. }
  293. return Key;
  294. }
  295. //
  296. // --------------------------------------------------------- Internal Functions
  297. //