[CMDUTILS][WHERE] Implement WHERE command (#3642)
[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 // || (KeyState[VK_LSHIFT] & 0x80) || (KeyState[VK_RSHIFT] & 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 // if (KeyState[VK_CONTROL] & 0x80) { ... }
45
46 if (KeyState[VK_LMENU] & 0x80)
47 ssOut |= LEFT_ALT_PRESSED;
48 if (KeyState[VK_RMENU] & 0x80)
49 ssOut |= RIGHT_ALT_PRESSED;
50 // if (KeyState[VK_MENU] & 0x80) { ... }
51
52 /* See WM_CHAR MSDN documentation for instance */
53 if (HIWORD(lParam) & KF_EXTENDED)
54 ssOut |= ENHANCED_KEY;
55
56 return ssOut;
57 }
58
59 VOID NTAPI
60 ConioProcessKey(PCONSRV_CONSOLE Console, MSG* msg)
61 {
62 static BYTE KeyState[256] = { 0 };
63 /* MSDN mentions that you should use the last virtual key code received
64 * when putting a virtual key identity to a WM_CHAR message since multiple
65 * or translated keys may be involved. */
66 static UINT LastVirtualKey = 0;
67 DWORD ShiftState;
68 WCHAR UnicodeChar;
69 UINT VirtualKeyCode;
70 UINT VirtualScanCode;
71 BOOL Down;
72 BOOLEAN Fake; // Synthesized, not a real event
73 BOOLEAN NotChar; // Message should not be used to return a character
74
75 INPUT_RECORD er;
76
77 if (Console == NULL)
78 {
79 DPRINT1("No Active Console!\n");
80 return;
81 }
82
83 VirtualScanCode = HIWORD(msg->lParam) & 0xFF;
84 Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
85 msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
86
87 GetKeyboardState(KeyState);
88 ShiftState = ConioGetShiftState(KeyState, msg->lParam);
89
90 if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
91 {
92 VirtualKeyCode = LastVirtualKey;
93 UnicodeChar = msg->wParam;
94 }
95 else
96 {
97 WCHAR Chars[2];
98 INT RetChars = 0;
99
100 VirtualKeyCode = msg->wParam;
101 RetChars = ToUnicodeEx(VirtualKeyCode,
102 VirtualScanCode,
103 KeyState,
104 Chars,
105 2,
106 0,
107 NULL);
108 UnicodeChar = (RetChars == 1 ? Chars[0] : 0);
109 }
110
111 Fake = UnicodeChar &&
112 (msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
113 msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
114 NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
115 if (NotChar) LastVirtualKey = msg->wParam;
116
117 DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n",
118 Down ? "down" : "up ",
119 (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
120 "char" : "key ",
121 Fake ? "fake" : "real",
122 NotChar ? "notc" : "char",
123 VirtualScanCode,
124 VirtualKeyCode,
125 (UnicodeChar >= L' ') ? UnicodeChar : L'.',
126 ShiftState);
127
128 if (Fake) return;
129
130 //
131 // FIXME: Scrolling via keyboard shortcuts must be done differently,
132 // without touching the internal VirtualY variable.
133 //
134 #if 0
135 if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 &&
136 (VirtualKeyCode == VK_UP || VirtualKeyCode == VK_DOWN) )
137 {
138 if (!Down) return;
139
140 /* Scroll up or down */
141 if (VirtualKeyCode == VK_UP)
142 {
143 /* Only scroll up if there is room to scroll up into */
144 if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
145 {
146 Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
147 Console->ActiveBuffer->ScreenBufferSize.Y - 1) %
148 Console->ActiveBuffer->ScreenBufferSize.Y;
149 Console->ActiveBuffer->CursorPosition.Y++;
150 }
151 }
152 else
153 {
154 /* Only scroll down if there is room to scroll down into */
155 if (Console->ActiveBuffer->CursorPosition.Y != 0)
156 {
157 Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
158 Console->ActiveBuffer->ScreenBufferSize.Y;
159 Console->ActiveBuffer->CursorPosition.Y--;
160 }
161 }
162
163 ConioDrawConsole(Console);
164 return;
165 }
166 #endif
167
168 /* Send the key press to the console driver */
169
170 er.EventType = KEY_EVENT;
171 er.Event.KeyEvent.bKeyDown = Down;
172 er.Event.KeyEvent.wRepeatCount = 1;
173 er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
174 er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
175 er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
176 er.Event.KeyEvent.dwControlKeyState = ShiftState;
177
178 ConioProcessInputEvent(Console, &er);
179 }
180
181 DWORD
182 ConioEffectiveCursorSize(PCONSRV_CONSOLE Console, DWORD Scale)
183 {
184 DWORD Size = (Console->ActiveBuffer->CursorInfo.dwSize * Scale + 99) / 100;
185 /* If line input in progress, perhaps adjust for insert toggle */
186 if (Console->LineBuffer && !Console->LineComplete && (Console->InsertMode ? !Console->LineInsertToggle : Console->LineInsertToggle))
187 return (Size * 2 <= Scale) ? (Size * 2) : (Size / 2);
188 return Size;
189 }
190
191 /* EOF */