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