[CONSRV]: Merge again ConDrvProcessKey and ConioProcessKey.
[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/term.h"
14 #include "coninput.h"
15
16 #define NDEBUG
17 #include <debug.h>
18
19
20 /* PRIVATE FUNCTIONS **********************************************************/
21
22 static DWORD
23 ConioGetShiftState(PBYTE KeyState, LPARAM lParam)
24 {
25 DWORD ssOut = 0;
26
27 if (KeyState[VK_CAPITAL] & 0x01)
28 ssOut |= CAPSLOCK_ON;
29
30 if (KeyState[VK_NUMLOCK] & 0x01)
31 ssOut |= NUMLOCK_ON;
32
33 if (KeyState[VK_SCROLL] & 0x01)
34 ssOut |= SCROLLLOCK_ON;
35
36 if (KeyState[VK_SHIFT] & 0x80)
37 ssOut |= SHIFT_PRESSED;
38
39 if (KeyState[VK_LCONTROL] & 0x80)
40 ssOut |= LEFT_CTRL_PRESSED;
41 if (KeyState[VK_RCONTROL] & 0x80)
42 ssOut |= RIGHT_CTRL_PRESSED;
43
44 if (KeyState[VK_LMENU] & 0x80)
45 ssOut |= LEFT_ALT_PRESSED;
46 if (KeyState[VK_RMENU] & 0x80)
47 ssOut |= RIGHT_ALT_PRESSED;
48
49 /* See WM_CHAR MSDN documentation for instance */
50 if (lParam & 0x01000000)
51 ssOut |= ENHANCED_KEY;
52
53 return ssOut;
54 }
55
56 VOID NTAPI
57 ConioProcessKey(PCONSRV_CONSOLE Console, MSG* msg)
58 {
59 static BYTE KeyState[256] = { 0 };
60 /* MSDN mentions that you should use the last virtual key code received
61 * when putting a virtual key identity to a WM_CHAR message since multiple
62 * or translated keys may be involved. */
63 static UINT LastVirtualKey = 0;
64 DWORD ShiftState;
65 WCHAR UnicodeChar;
66 UINT VirtualKeyCode;
67 UINT VirtualScanCode;
68 BOOL Down = FALSE;
69 BOOLEAN Fake; // Synthesized, not a real event
70 BOOLEAN NotChar; // Message should not be used to return a character
71
72 INPUT_RECORD er;
73
74 if (NULL == Console)
75 {
76 DPRINT1("No Active Console!\n");
77 return;
78 }
79
80 VirtualScanCode = HIWORD(msg->lParam) & 0xFF;
81 Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
82 msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
83
84 GetKeyboardState(KeyState);
85 ShiftState = ConioGetShiftState(KeyState, msg->lParam);
86
87 if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
88 {
89 VirtualKeyCode = LastVirtualKey;
90 UnicodeChar = msg->wParam;
91 }
92 else
93 {
94 WCHAR Chars[2];
95 INT RetChars = 0;
96
97 VirtualKeyCode = msg->wParam;
98 RetChars = ToUnicodeEx(VirtualKeyCode,
99 VirtualScanCode,
100 KeyState,
101 Chars,
102 2,
103 0,
104 NULL);
105 UnicodeChar = (RetChars == 1 ? Chars[0] : 0);
106 }
107
108 Fake = UnicodeChar &&
109 (msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
110 msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
111 NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
112 if (NotChar) LastVirtualKey = msg->wParam;
113
114 DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n",
115 Down ? "down" : "up ",
116 (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
117 "char" : "key ",
118 Fake ? "fake" : "real",
119 NotChar ? "notc" : "char",
120 VirtualScanCode,
121 VirtualKeyCode,
122 (UnicodeChar >= L' ') ? UnicodeChar : L'.',
123 ShiftState);
124
125 if (Fake) return;
126
127 /* Process Ctrl-C and Ctrl-Break */
128 if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
129 Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') &&
130 (ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyState[VK_CONTROL] & 0x80) )
131 {
132 DPRINT1("Console_Api Ctrl-C\n");
133 ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT);
134
135 if (Console->LineBuffer && !Console->LineComplete)
136 {
137 /* Line input is in progress; end it */
138 Console->LinePos = Console->LineSize = 0;
139 Console->LineComplete = TRUE;
140 }
141 return;
142 }
143
144 if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 &&
145 (VirtualKeyCode == VK_UP || VirtualKeyCode == VK_DOWN) )
146 {
147 if (!Down) return;
148
149 /* Scroll up or down */
150 if (VirtualKeyCode == VK_UP)
151 {
152 /* Only scroll up if there is room to scroll up into */
153 if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
154 {
155 Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
156 Console->ActiveBuffer->ScreenBufferSize.Y - 1) %
157 Console->ActiveBuffer->ScreenBufferSize.Y;
158 Console->ActiveBuffer->CursorPosition.Y++;
159 }
160 }
161 else
162 {
163 /* Only scroll down if there is room to scroll down into */
164 if (Console->ActiveBuffer->CursorPosition.Y != 0)
165 {
166 Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
167 Console->ActiveBuffer->ScreenBufferSize.Y;
168 Console->ActiveBuffer->CursorPosition.Y--;
169 }
170 }
171
172 ConioDrawConsole((PCONSOLE)Console);
173 return;
174 }
175
176 /* Send the key press to the console driver */
177
178 er.EventType = KEY_EVENT;
179 er.Event.KeyEvent.bKeyDown = Down;
180 er.Event.KeyEvent.wRepeatCount = 1;
181 er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
182 er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
183 er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
184 er.Event.KeyEvent.dwControlKeyState = ShiftState;
185
186 ConioProcessInputEvent(Console, &er);
187 }
188
189 DWORD
190 ConioEffectiveCursorSize(PCONSRV_CONSOLE Console, DWORD Scale)
191 {
192 DWORD Size = (Console->ActiveBuffer->CursorInfo.dwSize * Scale + 99) / 100;
193 /* If line input in progress, perhaps adjust for insert toggle */
194 if (Console->LineBuffer && !Console->LineComplete && (Console->InsertMode ? !Console->LineInsertToggle : Console->LineInsertToggle))
195 return (Size * 2 <= Scale) ? (Size * 2) : (Size / 2);
196 return Size;
197 }
198
199 /* EOF */