Sync with trunk r62529.
[reactos.git] / win32ss / user / winsrv / consrv / frontends / input.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Server DLL
4 * FILE: win32ss/user/winsrv/consrv/frontends/input.c
5 * PURPOSE: Common Front-Ends Input functions
6 * PROGRAMMERS: Jeffrey Morlan
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8 */
9
10 /* INCLUDES *******************************************************************/
11
12 #include "consrv.h"
13 #include "include/conio.h"
14 #include "include/term.h"
15 #include "coninput.h"
16
17 #define NDEBUG
18 #include <debug.h>
19
20
21 /* PRIVATE FUNCTIONS **********************************************************/
22
23 static DWORD FASTCALL
24 ConioGetShiftState(PBYTE KeyState, LPARAM lParam)
25 {
26 DWORD ssOut = 0;
27
28 if (KeyState[VK_CAPITAL] & 0x01)
29 ssOut |= CAPSLOCK_ON;
30
31 if (KeyState[VK_NUMLOCK] & 0x01)
32 ssOut |= NUMLOCK_ON;
33
34 if (KeyState[VK_SCROLL] & 0x01)
35 ssOut |= SCROLLLOCK_ON;
36
37 if (KeyState[VK_SHIFT] & 0x80)
38 ssOut |= SHIFT_PRESSED;
39
40 if (KeyState[VK_LCONTROL] & 0x80)
41 ssOut |= LEFT_CTRL_PRESSED;
42 if (KeyState[VK_RCONTROL] & 0x80)
43 ssOut |= RIGHT_CTRL_PRESSED;
44
45 if (KeyState[VK_LMENU] & 0x80)
46 ssOut |= LEFT_ALT_PRESSED;
47 if (KeyState[VK_RMENU] & 0x80)
48 ssOut |= RIGHT_ALT_PRESSED;
49
50 /* See WM_CHAR MSDN documentation for instance */
51 if (lParam & 0x01000000)
52 ssOut |= ENHANCED_KEY;
53
54 return ssOut;
55 }
56
57 VOID NTAPI
58 ConioProcessKey(PCONSOLE Console, MSG* msg)
59 {
60 static BYTE KeyState[256] = { 0 };
61 /* MSDN mentions that you should use the last virtual key code received
62 * when putting a virtual key identity to a WM_CHAR message since multiple
63 * or translated keys may be involved. */
64 static UINT LastVirtualKey = 0;
65 DWORD ShiftState;
66 WCHAR UnicodeChar;
67 UINT VirtualKeyCode;
68 UINT VirtualScanCode;
69 BOOL Down = FALSE;
70 BOOLEAN Fake; // synthesized, not a real event
71 BOOLEAN NotChar; // message should not be used to return a character
72
73 if (NULL == Console)
74 {
75 DPRINT1("No Active Console!\n");
76 return;
77 }
78
79 VirtualScanCode = HIWORD(msg->lParam) & 0xFF;
80 Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
81 msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
82
83 GetKeyboardState(KeyState);
84 ShiftState = ConioGetShiftState(KeyState, msg->lParam);
85
86 if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
87 {
88 VirtualKeyCode = LastVirtualKey;
89 UnicodeChar = msg->wParam;
90 }
91 else
92 {
93 WCHAR Chars[2];
94 INT RetChars = 0;
95
96 VirtualKeyCode = msg->wParam;
97 RetChars = ToUnicodeEx(VirtualKeyCode,
98 VirtualScanCode,
99 KeyState,
100 Chars,
101 2,
102 0,
103 NULL);
104 UnicodeChar = (1 == RetChars ? Chars[0] : 0);
105 }
106
107 if (TermProcessKeyCallback(Console,
108 msg,
109 KeyState[VK_MENU],
110 ShiftState,
111 VirtualKeyCode,
112 Down))
113 {
114 return;
115 }
116
117 Fake = UnicodeChar &&
118 (msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
119 msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
120 NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
121 if (NotChar) LastVirtualKey = msg->wParam;
122
123 DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n",
124 Down ? "down" : "up ",
125 (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
126 "char" : "key ",
127 Fake ? "fake" : "real",
128 NotChar ? "notc" : "char",
129 VirtualScanCode,
130 VirtualKeyCode,
131 (UnicodeChar >= L' ') ? UnicodeChar : L'.',
132 ShiftState);
133
134 if (Fake) return;
135
136 /* Send the key press to the console driver */
137 ConDrvProcessKey(Console,
138 Down,
139 VirtualKeyCode,
140 VirtualScanCode,
141 UnicodeChar,
142 ShiftState,
143 KeyState[VK_CONTROL]);
144 }
145
146 /* EOF */