1c2c66affSColin Finck /*
2c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory
3c2c66affSColin Finck * PROJECT: ReactOS Console Server DLL
4c2c66affSColin Finck * FILE: win32ss/user/winsrv/consrv/frontends/input.c
5c2c66affSColin Finck * PURPOSE: Common Front-Ends Input functions
6c2c66affSColin Finck * PROGRAMMERS: Jeffrey Morlan
7c2c66affSColin Finck * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8c2c66affSColin Finck */
9c2c66affSColin Finck
10c2c66affSColin Finck /* INCLUDES *******************************************************************/
11c2c66affSColin Finck
12c2c66affSColin Finck #include "consrv.h"
13c2c66affSColin Finck #include "include/term.h"
14c2c66affSColin Finck #include "coninput.h"
15c2c66affSColin Finck
16c2c66affSColin Finck #define NDEBUG
17c2c66affSColin Finck #include <debug.h>
18c2c66affSColin Finck
19c2c66affSColin Finck
20c2c66affSColin Finck /* PRIVATE FUNCTIONS **********************************************************/
21c2c66affSColin Finck
22c2c66affSColin Finck static DWORD
ConioGetShiftState(PBYTE KeyState,LPARAM lParam)23c2c66affSColin Finck ConioGetShiftState(PBYTE KeyState, LPARAM lParam)
24c2c66affSColin Finck {
25c2c66affSColin Finck DWORD ssOut = 0;
26c2c66affSColin Finck
27c2c66affSColin Finck if (KeyState[VK_CAPITAL] & 0x01)
28c2c66affSColin Finck ssOut |= CAPSLOCK_ON;
29c2c66affSColin Finck
30c2c66affSColin Finck if (KeyState[VK_NUMLOCK] & 0x01)
31c2c66affSColin Finck ssOut |= NUMLOCK_ON;
32c2c66affSColin Finck
33c2c66affSColin Finck if (KeyState[VK_SCROLL] & 0x01)
34c2c66affSColin Finck ssOut |= SCROLLLOCK_ON;
35c2c66affSColin Finck
36c2c66affSColin Finck if (KeyState[VK_SHIFT] & 0x80)
377babd931SHermès Bélusca-Maïto // || (KeyState[VK_LSHIFT] & 0x80) || (KeyState[VK_RSHIFT] & 0x80)
38c2c66affSColin Finck ssOut |= SHIFT_PRESSED;
39c2c66affSColin Finck
40c2c66affSColin Finck if (KeyState[VK_LCONTROL] & 0x80)
41c2c66affSColin Finck ssOut |= LEFT_CTRL_PRESSED;
42c2c66affSColin Finck if (KeyState[VK_RCONTROL] & 0x80)
43c2c66affSColin Finck ssOut |= RIGHT_CTRL_PRESSED;
447babd931SHermès Bélusca-Maïto // if (KeyState[VK_CONTROL] & 0x80) { ... }
45c2c66affSColin Finck
46c2c66affSColin Finck if (KeyState[VK_LMENU] & 0x80)
47c2c66affSColin Finck ssOut |= LEFT_ALT_PRESSED;
48c2c66affSColin Finck if (KeyState[VK_RMENU] & 0x80)
49c2c66affSColin Finck ssOut |= RIGHT_ALT_PRESSED;
507babd931SHermès Bélusca-Maïto // if (KeyState[VK_MENU] & 0x80) { ... }
51c2c66affSColin Finck
52c2c66affSColin Finck /* See WM_CHAR MSDN documentation for instance */
53*89f36bcfSHermès Bélusca-Maïto if (HIWORD(lParam) & KF_EXTENDED)
54c2c66affSColin Finck ssOut |= ENHANCED_KEY;
55c2c66affSColin Finck
56c2c66affSColin Finck return ssOut;
57c2c66affSColin Finck }
58c2c66affSColin Finck
59c2c66affSColin Finck VOID NTAPI
ConioProcessKey(PCONSRV_CONSOLE Console,MSG * msg)60c2c66affSColin Finck ConioProcessKey(PCONSRV_CONSOLE Console, MSG* msg)
61c2c66affSColin Finck {
62c2c66affSColin Finck static BYTE KeyState[256] = { 0 };
63c2c66affSColin Finck /* MSDN mentions that you should use the last virtual key code received
64c2c66affSColin Finck * when putting a virtual key identity to a WM_CHAR message since multiple
65c2c66affSColin Finck * or translated keys may be involved. */
66c2c66affSColin Finck static UINT LastVirtualKey = 0;
67c2c66affSColin Finck DWORD ShiftState;
68c2c66affSColin Finck WCHAR UnicodeChar;
69c2c66affSColin Finck UINT VirtualKeyCode;
70c2c66affSColin Finck UINT VirtualScanCode;
71*89f36bcfSHermès Bélusca-Maïto BOOL Down;
72c2c66affSColin Finck BOOLEAN Fake; // Synthesized, not a real event
73c2c66affSColin Finck BOOLEAN NotChar; // Message should not be used to return a character
74c2c66affSColin Finck
75c2c66affSColin Finck INPUT_RECORD er;
76c2c66affSColin Finck
77c2c66affSColin Finck if (Console == NULL)
78c2c66affSColin Finck {
79c2c66affSColin Finck DPRINT1("No Active Console!\n");
80c2c66affSColin Finck return;
81c2c66affSColin Finck }
82c2c66affSColin Finck
83c2c66affSColin Finck VirtualScanCode = HIWORD(msg->lParam) & 0xFF;
84c2c66affSColin Finck Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
85c2c66affSColin Finck msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
86c2c66affSColin Finck
87c2c66affSColin Finck GetKeyboardState(KeyState);
88c2c66affSColin Finck ShiftState = ConioGetShiftState(KeyState, msg->lParam);
89c2c66affSColin Finck
90c2c66affSColin Finck if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
91c2c66affSColin Finck {
92c2c66affSColin Finck VirtualKeyCode = LastVirtualKey;
93c2c66affSColin Finck UnicodeChar = msg->wParam;
94c2c66affSColin Finck }
95c2c66affSColin Finck else
96c2c66affSColin Finck {
97c2c66affSColin Finck WCHAR Chars[2];
98c2c66affSColin Finck INT RetChars = 0;
99c2c66affSColin Finck
100c2c66affSColin Finck VirtualKeyCode = msg->wParam;
101c2c66affSColin Finck RetChars = ToUnicodeEx(VirtualKeyCode,
102c2c66affSColin Finck VirtualScanCode,
103c2c66affSColin Finck KeyState,
104c2c66affSColin Finck Chars,
105c2c66affSColin Finck 2,
106c2c66affSColin Finck 0,
107c2c66affSColin Finck NULL);
108c2c66affSColin Finck UnicodeChar = (RetChars == 1 ? Chars[0] : 0);
109c2c66affSColin Finck }
110c2c66affSColin Finck
111c2c66affSColin Finck Fake = UnicodeChar &&
112c2c66affSColin Finck (msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
113c2c66affSColin Finck msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
114c2c66affSColin Finck NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
115c2c66affSColin Finck if (NotChar) LastVirtualKey = msg->wParam;
116c2c66affSColin Finck
117c2c66affSColin Finck DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n",
118c2c66affSColin Finck Down ? "down" : "up ",
119c2c66affSColin Finck (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
120c2c66affSColin Finck "char" : "key ",
121c2c66affSColin Finck Fake ? "fake" : "real",
122c2c66affSColin Finck NotChar ? "notc" : "char",
123c2c66affSColin Finck VirtualScanCode,
124c2c66affSColin Finck VirtualKeyCode,
125c2c66affSColin Finck (UnicodeChar >= L' ') ? UnicodeChar : L'.',
126c2c66affSColin Finck ShiftState);
127c2c66affSColin Finck
128c2c66affSColin Finck if (Fake) return;
129c2c66affSColin Finck
130fe3d655bSHermès Bélusca-Maïto //
131fe3d655bSHermès Bélusca-Maïto // FIXME: Scrolling via keyboard shortcuts must be done differently,
132fe3d655bSHermès Bélusca-Maïto // without touching the internal VirtualY variable.
133fe3d655bSHermès Bélusca-Maïto //
134fe3d655bSHermès Bélusca-Maïto #if 0
135c2c66affSColin Finck if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 &&
136c2c66affSColin Finck (VirtualKeyCode == VK_UP || VirtualKeyCode == VK_DOWN) )
137c2c66affSColin Finck {
138c2c66affSColin Finck if (!Down) return;
139c2c66affSColin Finck
140c2c66affSColin Finck /* Scroll up or down */
141c2c66affSColin Finck if (VirtualKeyCode == VK_UP)
142c2c66affSColin Finck {
143c2c66affSColin Finck /* Only scroll up if there is room to scroll up into */
144c2c66affSColin Finck if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
145c2c66affSColin Finck {
146c2c66affSColin Finck Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
147c2c66affSColin Finck Console->ActiveBuffer->ScreenBufferSize.Y - 1) %
148c2c66affSColin Finck Console->ActiveBuffer->ScreenBufferSize.Y;
149c2c66affSColin Finck Console->ActiveBuffer->CursorPosition.Y++;
150c2c66affSColin Finck }
151c2c66affSColin Finck }
152c2c66affSColin Finck else
153c2c66affSColin Finck {
154c2c66affSColin Finck /* Only scroll down if there is room to scroll down into */
155c2c66affSColin Finck if (Console->ActiveBuffer->CursorPosition.Y != 0)
156c2c66affSColin Finck {
157c2c66affSColin Finck Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
158c2c66affSColin Finck Console->ActiveBuffer->ScreenBufferSize.Y;
159c2c66affSColin Finck Console->ActiveBuffer->CursorPosition.Y--;
160c2c66affSColin Finck }
161c2c66affSColin Finck }
162c2c66affSColin Finck
163c2c66affSColin Finck ConioDrawConsole(Console);
164c2c66affSColin Finck return;
165c2c66affSColin Finck }
166fe3d655bSHermès Bélusca-Maïto #endif
167c2c66affSColin Finck
168c2c66affSColin Finck /* Send the key press to the console driver */
169c2c66affSColin Finck
170c2c66affSColin Finck er.EventType = KEY_EVENT;
171c2c66affSColin Finck er.Event.KeyEvent.bKeyDown = Down;
172c2c66affSColin Finck er.Event.KeyEvent.wRepeatCount = 1;
173c2c66affSColin Finck er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
174c2c66affSColin Finck er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
175c2c66affSColin Finck er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
176c2c66affSColin Finck er.Event.KeyEvent.dwControlKeyState = ShiftState;
177c2c66affSColin Finck
178c2c66affSColin Finck ConioProcessInputEvent(Console, &er);
179c2c66affSColin Finck }
180c2c66affSColin Finck
181c2c66affSColin Finck DWORD
ConioEffectiveCursorSize(PCONSRV_CONSOLE Console,DWORD Scale)182c2c66affSColin Finck ConioEffectiveCursorSize(PCONSRV_CONSOLE Console, DWORD Scale)
183c2c66affSColin Finck {
184c2c66affSColin Finck DWORD Size = (Console->ActiveBuffer->CursorInfo.dwSize * Scale + 99) / 100;
185c2c66affSColin Finck /* If line input in progress, perhaps adjust for insert toggle */
186c2c66affSColin Finck if (Console->LineBuffer && !Console->LineComplete && (Console->InsertMode ? !Console->LineInsertToggle : Console->LineInsertToggle))
187c2c66affSColin Finck return (Size * 2 <= Scale) ? (Size * 2) : (Size / 2);
188c2c66affSColin Finck return Size;
189c2c66affSColin Finck }
190c2c66affSColin Finck
191c2c66affSColin Finck /* EOF */
192