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)
10 /* INCLUDES *******************************************************************/
13 #include "include/term.h"
20 /* PRIVATE FUNCTIONS **********************************************************/
23 ConioGetShiftState(PBYTE KeyState
, LPARAM lParam
)
27 if (KeyState
[VK_CAPITAL
] & 0x01)
30 if (KeyState
[VK_NUMLOCK
] & 0x01)
33 if (KeyState
[VK_SCROLL
] & 0x01)
34 ssOut
|= SCROLLLOCK_ON
;
36 if (KeyState
[VK_SHIFT
] & 0x80)
37 ssOut
|= SHIFT_PRESSED
;
39 if (KeyState
[VK_LCONTROL
] & 0x80)
40 ssOut
|= LEFT_CTRL_PRESSED
;
41 if (KeyState
[VK_RCONTROL
] & 0x80)
42 ssOut
|= RIGHT_CTRL_PRESSED
;
44 if (KeyState
[VK_LMENU
] & 0x80)
45 ssOut
|= LEFT_ALT_PRESSED
;
46 if (KeyState
[VK_RMENU
] & 0x80)
47 ssOut
|= RIGHT_ALT_PRESSED
;
49 /* See WM_CHAR MSDN documentation for instance */
50 if (lParam
& 0x01000000)
51 ssOut
|= ENHANCED_KEY
;
57 ConioProcessKey(PCONSRV_CONSOLE Console
, MSG
* msg
)
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;
69 BOOLEAN Fake
; // Synthesized, not a real event
70 BOOLEAN NotChar
; // Message should not be used to return a character
76 DPRINT1("No Active Console!\n");
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
;
84 GetKeyboardState(KeyState
);
85 ShiftState
= ConioGetShiftState(KeyState
, msg
->lParam
);
87 if (msg
->message
== WM_CHAR
|| msg
->message
== WM_SYSCHAR
)
89 VirtualKeyCode
= LastVirtualKey
;
90 UnicodeChar
= msg
->wParam
;
97 VirtualKeyCode
= msg
->wParam
;
98 RetChars
= ToUnicodeEx(VirtualKeyCode
,
105 UnicodeChar
= (RetChars
== 1 ? Chars
[0] : 0);
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
;
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
) ?
118 Fake
? "fake" : "real",
119 NotChar
? "notc" : "char",
122 (UnicodeChar
>= L
' ') ? UnicodeChar
: L
'.',
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) )
132 DPRINT1("Console_Api Ctrl-C\n");
133 ConSrvConsoleProcessCtrlEvent(Console
, 0, CTRL_C_EVENT
);
135 if (Console
->LineBuffer
&& !Console
->LineComplete
)
137 /* Line input is in progress; end it */
138 Console
->LinePos
= Console
->LineSize
= 0;
139 Console
->LineComplete
= TRUE
;
144 if ( (ShiftState
& (RIGHT_ALT_PRESSED
| LEFT_ALT_PRESSED
)) != 0 &&
145 (VirtualKeyCode
== VK_UP
|| VirtualKeyCode
== VK_DOWN
) )
149 /* Scroll up or down */
150 if (VirtualKeyCode
== VK_UP
)
152 /* Only scroll up if there is room to scroll up into */
153 if (Console
->ActiveBuffer
->CursorPosition
.Y
!= Console
->ActiveBuffer
->ScreenBufferSize
.Y
- 1)
155 Console
->ActiveBuffer
->VirtualY
= (Console
->ActiveBuffer
->VirtualY
+
156 Console
->ActiveBuffer
->ScreenBufferSize
.Y
- 1) %
157 Console
->ActiveBuffer
->ScreenBufferSize
.Y
;
158 Console
->ActiveBuffer
->CursorPosition
.Y
++;
163 /* Only scroll down if there is room to scroll down into */
164 if (Console
->ActiveBuffer
->CursorPosition
.Y
!= 0)
166 Console
->ActiveBuffer
->VirtualY
= (Console
->ActiveBuffer
->VirtualY
+ 1) %
167 Console
->ActiveBuffer
->ScreenBufferSize
.Y
;
168 Console
->ActiveBuffer
->CursorPosition
.Y
--;
172 ConioDrawConsole((PCONSOLE
)Console
);
176 /* Send the key press to the console driver */
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
;
186 ConioProcessInputEvent(Console
, &er
);
190 ConioEffectiveCursorSize(PCONSRV_CONSOLE Console
, DWORD Scale
)
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);