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/conio.h"
14 #include "include/term.h"
21 /* PRIVATE FUNCTIONS **********************************************************/
24 ConDrvProcessKey(IN PCONSOLE Console
,
26 IN UINT VirtualKeyCode
,
27 IN UINT VirtualScanCode
,
34 /* process Ctrl-C and Ctrl-Break */
35 if ( Console
->InputBuffer
.Mode
& ENABLE_PROCESSED_INPUT
&&
36 Down
&& (VirtualKeyCode
== VK_PAUSE
|| VirtualKeyCode
== 'C') &&
37 (ShiftState
& (LEFT_CTRL_PRESSED
| RIGHT_CTRL_PRESSED
) || KeyStateCtrl
& 0x80) )
39 DPRINT1("Console_Api Ctrl-C\n");
40 ConSrvConsoleProcessCtrlEvent(Console
, 0, CTRL_C_EVENT
);
42 if (Console
->LineBuffer
&& !Console
->LineComplete
)
44 /* Line input is in progress; end it */
45 Console
->LinePos
= Console
->LineSize
= 0;
46 Console
->LineComplete
= TRUE
;
51 if ( (ShiftState
& (RIGHT_ALT_PRESSED
| LEFT_ALT_PRESSED
)) != 0 &&
52 (VK_UP
== VirtualKeyCode
|| VK_DOWN
== VirtualKeyCode
) )
56 /* scroll up or down */
57 if (VK_UP
== VirtualKeyCode
)
59 /* only scroll up if there is room to scroll up into */
60 if (Console
->ActiveBuffer
->CursorPosition
.Y
!= Console
->ActiveBuffer
->ScreenBufferSize
.Y
- 1)
62 Console
->ActiveBuffer
->VirtualY
= (Console
->ActiveBuffer
->VirtualY
+
63 Console
->ActiveBuffer
->ScreenBufferSize
.Y
- 1) %
64 Console
->ActiveBuffer
->ScreenBufferSize
.Y
;
65 Console
->ActiveBuffer
->CursorPosition
.Y
++;
70 /* only scroll down if there is room to scroll down into */
71 if (Console
->ActiveBuffer
->CursorPosition
.Y
!= 0)
73 Console
->ActiveBuffer
->VirtualY
= (Console
->ActiveBuffer
->VirtualY
+ 1) %
74 Console
->ActiveBuffer
->ScreenBufferSize
.Y
;
75 Console
->ActiveBuffer
->CursorPosition
.Y
--;
79 ConioDrawConsole(Console
);
83 er
.EventType
= KEY_EVENT
;
84 er
.Event
.KeyEvent
.bKeyDown
= Down
;
85 er
.Event
.KeyEvent
.wRepeatCount
= 1;
86 er
.Event
.KeyEvent
.wVirtualKeyCode
= VirtualKeyCode
;
87 er
.Event
.KeyEvent
.wVirtualScanCode
= VirtualScanCode
;
88 er
.Event
.KeyEvent
.uChar
.UnicodeChar
= UnicodeChar
;
89 er
.Event
.KeyEvent
.dwControlKeyState
= ShiftState
;
91 ConioProcessInputEvent(Console
, &er
);
95 ConioGetShiftState(PBYTE KeyState
, LPARAM lParam
)
99 if (KeyState
[VK_CAPITAL
] & 0x01)
100 ssOut
|= CAPSLOCK_ON
;
102 if (KeyState
[VK_NUMLOCK
] & 0x01)
105 if (KeyState
[VK_SCROLL
] & 0x01)
106 ssOut
|= SCROLLLOCK_ON
;
108 if (KeyState
[VK_SHIFT
] & 0x80)
109 ssOut
|= SHIFT_PRESSED
;
111 if (KeyState
[VK_LCONTROL
] & 0x80)
112 ssOut
|= LEFT_CTRL_PRESSED
;
113 if (KeyState
[VK_RCONTROL
] & 0x80)
114 ssOut
|= RIGHT_CTRL_PRESSED
;
116 if (KeyState
[VK_LMENU
] & 0x80)
117 ssOut
|= LEFT_ALT_PRESSED
;
118 if (KeyState
[VK_RMENU
] & 0x80)
119 ssOut
|= RIGHT_ALT_PRESSED
;
121 /* See WM_CHAR MSDN documentation for instance */
122 if (lParam
& 0x01000000)
123 ssOut
|= ENHANCED_KEY
;
129 ConioProcessKey(PCONSOLE Console
, MSG
* msg
)
131 static BYTE KeyState
[256] = { 0 };
132 /* MSDN mentions that you should use the last virtual key code received
133 * when putting a virtual key identity to a WM_CHAR message since multiple
134 * or translated keys may be involved. */
135 static UINT LastVirtualKey
= 0;
139 UINT VirtualScanCode
;
141 BOOLEAN Fake
; // synthesized, not a real event
142 BOOLEAN NotChar
; // message should not be used to return a character
146 DPRINT1("No Active Console!\n");
150 VirtualScanCode
= HIWORD(msg
->lParam
) & 0xFF;
151 Down
= msg
->message
== WM_KEYDOWN
|| msg
->message
== WM_CHAR
||
152 msg
->message
== WM_SYSKEYDOWN
|| msg
->message
== WM_SYSCHAR
;
154 GetKeyboardState(KeyState
);
155 ShiftState
= ConioGetShiftState(KeyState
, msg
->lParam
);
157 if (msg
->message
== WM_CHAR
|| msg
->message
== WM_SYSCHAR
)
159 VirtualKeyCode
= LastVirtualKey
;
160 UnicodeChar
= msg
->wParam
;
167 VirtualKeyCode
= msg
->wParam
;
168 RetChars
= ToUnicodeEx(VirtualKeyCode
,
175 UnicodeChar
= (1 == RetChars
? Chars
[0] : 0);
178 Fake
= UnicodeChar
&&
179 (msg
->message
!= WM_CHAR
&& msg
->message
!= WM_SYSCHAR
&&
180 msg
->message
!= WM_KEYUP
&& msg
->message
!= WM_SYSKEYUP
);
181 NotChar
= (msg
->message
!= WM_CHAR
&& msg
->message
!= WM_SYSCHAR
);
182 if (NotChar
) LastVirtualKey
= msg
->wParam
;
184 DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n",
185 Down
? "down" : "up ",
186 (msg
->message
== WM_CHAR
|| msg
->message
== WM_SYSCHAR
) ?
188 Fake
? "fake" : "real",
189 NotChar
? "notc" : "char",
192 (UnicodeChar
>= L
' ') ? UnicodeChar
: L
'.',
197 /* Send the key press to the console driver */
198 ConDrvProcessKey(Console
,
204 KeyState
[VK_CONTROL
]);
208 ConioEffectiveCursorSize(PCONSOLE Console
, DWORD Scale
)
210 DWORD Size
= (Console
->ActiveBuffer
->CursorInfo
.dwSize
* Scale
+ 99) / 100;
211 /* If line input in progress, perhaps adjust for insert toggle */
212 if (Console
->LineBuffer
&& !Console
->LineComplete
&& (Console
->InsertMode
? !Console
->LineInsertToggle
: Console
->LineInsertToggle
))
213 return (Size
* 2 <= Scale
) ? (Size
* 2) : (Size
/ 2);