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.

385 lines
14 KiB

  1. /****************************** Module Header ******************************\,
  2. * Module Name: kbd.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * OEM-specific tables and routines for IBM Extended 101/102 style keyboards
  7. *
  8. * History:
  9. * 30-04-91 IanJa Created.
  10. \***************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. /***************************************************************************\
  14. * aVkToVsc[] - table associating Virtual Key codes with Virtual Scancodes
  15. *
  16. * Ordered, 0-terminated.
  17. *
  18. * This is used for those Virtual Keys that do not appear in ausVK_???[]
  19. * These are not the base Virtual Keys. They require some modifier key
  20. * depression (CTRL, ALT, SHIFT) or NumLock On to be generated.
  21. *
  22. * All the scancodes listed below should be marked KBDMULTIVK or KBDNUMPAD in
  23. * ausVK_???[].
  24. *
  25. * This table is used by MapVirtualKey(wVk, 0).
  26. \***************************************************************************/
  27. BYTE aVkNumpad[] = {
  28. VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9, 0xFF, // 0x47 0x48 0x49 (0x4A)
  29. VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, 0xFF, // 0x4B 0x4C 0x4D (0x4E)
  30. VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, // 0x4F 0x50 0x51
  31. VK_NUMPAD0, VK_DECIMAL, 0 // 0x50 0x51
  32. };
  33. /***************************************************************************\
  34. * How some Virtual Key values change when a SHIFT key is held down.
  35. \***************************************************************************/
  36. ULONG aulShiftCvt_VK[] = {
  37. MAKELONG(VK_MULTIPLY, VK_SNAPSHOT),
  38. MAKELONG(0,0)
  39. };
  40. // JPN IMB02
  41. ULONG aulShiftControlCvt_VK_IBM02[] = {
  42. MAKELONG(VK_SCROLL, VK_CANCEL | KBDEXT),
  43. MAKELONG(VK_NUMLOCK, VK_PAUSE | KBDEXT),
  44. MAKELONG(0,0)
  45. };
  46. /***************************************************************************\
  47. * How some Virtual Key values change when a CONTROL key is held down.
  48. \***************************************************************************/
  49. ULONG aulControlCvt_VK[] = {
  50. MAKELONG(VK_NUMLOCK, VK_PAUSE | KBDEXT),
  51. MAKELONG(VK_SCROLL, VK_CANCEL),
  52. MAKELONG(0,0)
  53. };
  54. // JPN IBM02
  55. ULONG aulControlCvt_VK_IBM02[] = {
  56. MAKELONG(VK_PAUSE, VK_CANCEL | KBDEXT),
  57. MAKELONG(VK_SCROLL, VK_CANCEL | KBDEXT),
  58. MAKELONG(0,0)
  59. };
  60. /***************************************************************************\
  61. * How some Virtual Key values change when an ALT key is held down.
  62. * The SHIFT and ALT keys both alter VK values the same way!!
  63. \***************************************************************************/
  64. #define aulAltCvt_VK aulShiftCvt_VK
  65. /***************************************************************************\
  66. * This table list keys that may affect Virtual Key values when held down.
  67. *
  68. * See kbd.h for a full description.
  69. *
  70. * 101/102key keyboard (type 4):
  71. * Virtual Key values vary only if CTRL is held down.
  72. * 84-86 key keyboards (type 3):
  73. * Virtual Key values vary if one of SHIFT, CTRL or ALT is held down.
  74. \***************************************************************************/
  75. VK_TO_BIT aVkToBits_VK[] = {
  76. { VK_SHIFT, KBDSHIFT }, // 0x01
  77. { VK_CONTROL, KBDCTRL }, // 0x02
  78. { VK_MENU, KBDALT }, // 0x04
  79. { 0, 0 }
  80. };
  81. // JPN IBM02
  82. VK_TO_BIT aVkToBits_VK_IBM02[] = {
  83. { VK_SHIFT, KBDSHIFT }, // 0x01
  84. { VK_CONTROL, KBDCTRL }, // 0x02
  85. { 0, 0 }
  86. };
  87. /***************************************************************************\
  88. * Tables defining how some Virtual Key values are modified when other keys
  89. * are held down.
  90. * Translates key combinations into indices for gapulCvt_VK_101[] or for
  91. * gapulCvt_VK_84[] or for
  92. *
  93. * See kbd.h for a full description.
  94. *
  95. \***************************************************************************/
  96. MODIFIERS Modifiers_VK_STANDARD = {
  97. &aVkToBits_VK[0],
  98. 4, // Maximum modifier bitmask/index
  99. {
  100. SHFT_INVALID, // no keys held down (no VKs are modified)
  101. 0, // SHIFT held down 84-86 key kbd
  102. 1, // CTRL held down 101/102 key kbd
  103. SHFT_INVALID, // CTRL-SHIFT held down (no VKs are modified)
  104. 2 // ALT held down 84-86 key kbd
  105. }
  106. };
  107. MODIFIERS Modifiers_VK_IBM02 = {
  108. &aVkToBits_VK_IBM02[0],
  109. 3, // Maximum modifier bitmask/index
  110. {
  111. SHFT_INVALID, // no modifier keys (no VK modification)
  112. SHFT_INVALID, // Shift (no VK modification)
  113. 0, // Control (VK modification number 0)
  114. 1 // Control Shift (VK modification number 1)
  115. }
  116. };
  117. /***************************************************************************\
  118. * A tables of pointers indexed by the number obtained from Modify_VK.
  119. * If a pointer is non-NULL then the table it points to is searched for
  120. * Virtual Key that should have their values changed.
  121. * There are two versions: one for 84-86 key kbds, one for 101/102 key kbds.
  122. * gapulCvt_VK is initialized with the default (101/102 key kbd).
  123. \***************************************************************************/
  124. ULONG *gapulCvt_VK_101[] = {
  125. NULL, // No VKs are changed by SHIFT being held down
  126. aulControlCvt_VK, // Some VKs are changed by CTRL being held down
  127. NULL // No VKs are changed by ALT being held down
  128. };
  129. ULONG *gapulCvt_VK_84[] = {
  130. aulShiftCvt_VK, // Some VKs are changed by SHIFT being held down
  131. aulControlCvt_VK, // Some VKs are changed by CTRL being held down
  132. aulAltCvt_VK // Some VKs are changed by ALT being held down
  133. };
  134. ULONG *gapulCvt_VK_IBM02[] = {
  135. aulControlCvt_VK_IBM02, // VK modification number 0 (Control key)
  136. aulShiftControlCvt_VK_IBM02,// VK modification number 1 (Shift Control key)
  137. };
  138. PULONG *gapulCvt_VK = gapulCvt_VK_101;
  139. PMODIFIERS gpModifiers_VK = &Modifiers_VK_STANDARD;
  140. /***************************************************************************\
  141. * The table ausNumPadCvt is used to convert a cursor movement
  142. * virtual key value (obtained from ausVK_???[]) into a VK_NUMPAD
  143. * virtual key value. This translation is done when NumLock is
  144. * on and no shift keys are pressed.
  145. \***************************************************************************/
  146. USHORT ausNumPadCvt[] =
  147. {
  148. MAKEWORD(VK_INSERT, VK_NUMPAD0),
  149. MAKEWORD(VK_END, VK_NUMPAD1),
  150. MAKEWORD(VK_DOWN, VK_NUMPAD2),
  151. MAKEWORD(VK_NEXT, VK_NUMPAD3),
  152. MAKEWORD(VK_LEFT, VK_NUMPAD4),
  153. MAKEWORD(VK_CLEAR, VK_NUMPAD5),
  154. MAKEWORD(VK_RIGHT, VK_NUMPAD6),
  155. MAKEWORD(VK_HOME, VK_NUMPAD7),
  156. MAKEWORD(VK_UP, VK_NUMPAD8),
  157. MAKEWORD(VK_PRIOR, VK_NUMPAD9),
  158. MAKEWORD(VK_DELETE, VK_DECIMAL),
  159. MAKEWORD(0, 0)
  160. };
  161. /***************************************************************************\
  162. * xxxNumpadCursor() - handle special case Numpad Cursor-movement Keys
  163. *
  164. * If NumLock is on, and Shift is up then:
  165. * VK_INSERT -> VK_NUMPAD0
  166. * VK_END -> VK_NUMPAD1
  167. * VK_DOWN -> VK_NUMPAD2
  168. * VK_NEXT -> VK_NUMPAD3
  169. * VK_LEFT -> VK_NUMPAD4
  170. * VK_CLEAR -> VK_NUMPAD5
  171. * VK_RIGHT -> VK_NUMPAD6
  172. * VK_HOME -> VK_NUMPAD7
  173. * VK_UP -> VK_NUMPAD8
  174. * VK_PRIOR -> VK_NUMPAD9
  175. * VK_DELETE -> VK_DECIMAL (unless CTRL-ALT-DEL)
  176. * If Numlock is on, and Shift is down then precede first Numpad Cursor key
  177. * going down with a fake Shift key coming up & follow the Numpad Cursor key
  178. * coming up with with a fake Shift key going down.
  179. *
  180. * Return value:
  181. * TRUE: keep this routine active: continue passing Key Events through here
  182. * FALSE: deactivet this routine: stop sending Key Events through here.
  183. *
  184. * This function will leave the critical section only if low level hooks
  185. * are installed and the call to xxxKeyEvent is made
  186. *
  187. \***************************************************************************/
  188. BOOL
  189. xxxNumpadCursor(
  190. PKE pKe)
  191. {
  192. static BYTE bLastNumpadCursor = 0;
  193. static USHORT VkFakedShiftUp; // VK_LSHIFT or VK_RSHIFT
  194. static BYTE VscFakedShiftUp; // 0x2A or 0x36 resp.
  195. int i;
  196. CheckCritIn();
  197. if (bLastNumpadCursor) {
  198. if (bLastNumpadCursor == (BYTE)(pKe->usFlaggedVk)) {
  199. /*
  200. * Same key as last one: if coming up, or going down?
  201. */
  202. if (pKe->usFlaggedVk & KBDBREAK) {
  203. /*
  204. * Numpad Cursor key came back up. Send this key now, and make
  205. * sure that the Shift key will then appear to go back down
  206. * again.
  207. */
  208. xxxKeyEvent(pKe->usFlaggedVk, pKe->bScanCode,
  209. pKe->dwTime, 0,
  210. #ifdef GENERIC_INPUT
  211. pKe->hDevice,
  212. &pKe->data,
  213. #endif
  214. FALSE);
  215. bLastNumpadCursor = 0;
  216. pKe->usFlaggedVk = VkFakedShiftUp;
  217. pKe->bScanCode = VscFakedShiftUp;
  218. }
  219. /*
  220. * Going down: this key is repeating, so just pass it on
  221. * unaltered and keep the KEProc active
  222. */
  223. return TRUE;
  224. } else {
  225. /*
  226. * It is a different key. Fake the Shift key back down again,
  227. * and continue (it may be another Numpad Cursor key)
  228. */
  229. xxxKeyEvent(VkFakedShiftUp,
  230. (WORD)(VscFakedShiftUp | SCANCODE_SIMULATED),
  231. pKe->dwTime, 0,
  232. #ifdef GENERIC_INPUT
  233. pKe->hDevice,
  234. &pKe->data,
  235. #endif
  236. FALSE);
  237. bLastNumpadCursor = 0;
  238. }
  239. }
  240. if (pKe->usFlaggedVk & KBDNUMPAD) {
  241. UINT fsModifiers;
  242. /*
  243. * This is the numeric pad.
  244. * Here, if NumLock is set, we change the virtual keycodes to
  245. * numeric VK_NUMPAD codes, so the keys will be translated
  246. * as numbers etc. But if a shift key is down, we handle
  247. * these as cursor keys, but we need to make sure that these
  248. * are seen as UNSHIFTED
  249. */
  250. /*
  251. * Check for SAS.
  252. */
  253. if (IsSAS((BYTE)(pKe->usFlaggedVk), &fsModifiers)) {
  254. return TRUE;
  255. } else if (TestRawKeyToggle(VK_NUMLOCK)) {
  256. if (TestRawKeyDown(VK_SHIFT)) {
  257. /*
  258. * key is down (bit(s) set in BIOS key state), so we are going
  259. * to keep this as a cursor key. To do this, we need to
  260. * make sure that Windows' state vector entry for VK_SHIFT is
  261. * OFF even though a shift key is actually down.
  262. */
  263. bLastNumpadCursor = (BYTE)(pKe->usFlaggedVk);
  264. if (TestRawKeyDown(VK_RSHIFT)) {
  265. VkFakedShiftUp = VK_RSHIFT | KBDEXT;
  266. VscFakedShiftUp = 0x36;
  267. } else {
  268. VkFakedShiftUp = VK_LSHIFT;
  269. VscFakedShiftUp = 0x2A;
  270. }
  271. xxxKeyEvent((USHORT)(VkFakedShiftUp | KBDBREAK),
  272. (WORD)(VscFakedShiftUp | SCANCODE_SIMULATED),
  273. pKe->dwTime, 0,
  274. #ifdef GENERIC_INPUT
  275. pKe->hDevice,
  276. &pKe->data,
  277. #endif
  278. FALSE);
  279. return TRUE;
  280. }
  281. /*
  282. * NumLock ON but Shift key up: Alter the Virtual Key event,
  283. * but not for injected virtual keys.
  284. */
  285. if ((pKe->usFlaggedVk & KBDINJECTEDVK) == 0) {
  286. for (i = 0; ausNumPadCvt[i] != 0; i++) {
  287. if (LOBYTE(ausNumPadCvt[i]) == LOBYTE(pKe->usFlaggedVk)) {
  288. /*
  289. * keep extra bits, but change VK value
  290. */
  291. pKe->usFlaggedVk &= ~0xFF;
  292. pKe->usFlaggedVk |= (UINT)(HIBYTE(ausNumPadCvt[i]));
  293. break;
  294. }
  295. }
  296. }
  297. }
  298. }
  299. return TRUE;
  300. }
  301. /***************************************************************************\
  302. *
  303. * xxxICO_00() - handle special case '00' key
  304. *
  305. * LATER IanJa: should only be in ICO OEM file for kbd with '00' key
  306. *
  307. * This function will leave the critical section only if low level hooks
  308. * are installed ant the call to xxxKeyEvent is made
  309. *
  310. \***************************************************************************/
  311. BOOL
  312. xxxICO_00(
  313. PKE pKe)
  314. {
  315. CheckCritIn();
  316. if ((pKe->usFlaggedVk & 0xFF) != VK_ICO_00) {
  317. /*
  318. * Pass the keystroke on unaltered
  319. */
  320. return TRUE;
  321. }
  322. if (pKe->usFlaggedVk & KBDBREAK) {
  323. /*
  324. * '0' key comes up
  325. */
  326. pKe->usFlaggedVk = '0' | KBDEXT | KBDBREAK;
  327. } else {
  328. /*
  329. * '0' down, up, down
  330. */
  331. xxxKeyEvent('0', pKe->bScanCode, pKe->dwTime, 0,
  332. #ifdef GENERIC_INPUT
  333. pKe->hDevice,
  334. &pKe->data,
  335. #endif
  336. FALSE);
  337. xxxKeyEvent('0' | KBDBREAK, pKe->bScanCode, pKe->dwTime, 0,
  338. #ifdef GENERIC_INPUT
  339. pKe->hDevice,
  340. &pKe->data,
  341. #endif
  342. FALSE);
  343. pKe->usFlaggedVk = '0' | KBDEXT;
  344. }
  345. return TRUE;
  346. }
  347. KEPROC aKEProcOEM[] = {
  348. xxxICO_00, // Bitmask 0x01
  349. xxxNumpadCursor, // Bitmask 0x02
  350. NULL
  351. };