reactos/win32ss/user/winsrv/consrv/frontends/input.c
2020-12-27 00:52:01 +01:00

192 lines
6.1 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: win32ss/user/winsrv/consrv/frontends/input.c
* PURPOSE: Common Front-Ends Input functions
* PROGRAMMERS: Jeffrey Morlan
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
/* INCLUDES *******************************************************************/
#include "consrv.h"
#include "include/term.h"
#include "coninput.h"
#define NDEBUG
#include <debug.h>
/* PRIVATE FUNCTIONS **********************************************************/
static DWORD
ConioGetShiftState(PBYTE KeyState, LPARAM lParam)
{
DWORD ssOut = 0;
if (KeyState[VK_CAPITAL] & 0x01)
ssOut |= CAPSLOCK_ON;
if (KeyState[VK_NUMLOCK] & 0x01)
ssOut |= NUMLOCK_ON;
if (KeyState[VK_SCROLL] & 0x01)
ssOut |= SCROLLLOCK_ON;
if (KeyState[VK_SHIFT] & 0x80)
// || (KeyState[VK_LSHIFT] & 0x80) || (KeyState[VK_RSHIFT] & 0x80)
ssOut |= SHIFT_PRESSED;
if (KeyState[VK_LCONTROL] & 0x80)
ssOut |= LEFT_CTRL_PRESSED;
if (KeyState[VK_RCONTROL] & 0x80)
ssOut |= RIGHT_CTRL_PRESSED;
// if (KeyState[VK_CONTROL] & 0x80) { ... }
if (KeyState[VK_LMENU] & 0x80)
ssOut |= LEFT_ALT_PRESSED;
if (KeyState[VK_RMENU] & 0x80)
ssOut |= RIGHT_ALT_PRESSED;
// if (KeyState[VK_MENU] & 0x80) { ... }
/* See WM_CHAR MSDN documentation for instance */
if (HIWORD(lParam) & KF_EXTENDED)
ssOut |= ENHANCED_KEY;
return ssOut;
}
VOID NTAPI
ConioProcessKey(PCONSRV_CONSOLE Console, MSG* msg)
{
static BYTE KeyState[256] = { 0 };
/* MSDN mentions that you should use the last virtual key code received
* when putting a virtual key identity to a WM_CHAR message since multiple
* or translated keys may be involved. */
static UINT LastVirtualKey = 0;
DWORD ShiftState;
WCHAR UnicodeChar;
UINT VirtualKeyCode;
UINT VirtualScanCode;
BOOL Down;
BOOLEAN Fake; // Synthesized, not a real event
BOOLEAN NotChar; // Message should not be used to return a character
INPUT_RECORD er;
if (Console == NULL)
{
DPRINT1("No Active Console!\n");
return;
}
VirtualScanCode = HIWORD(msg->lParam) & 0xFF;
Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
GetKeyboardState(KeyState);
ShiftState = ConioGetShiftState(KeyState, msg->lParam);
if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
{
VirtualKeyCode = LastVirtualKey;
UnicodeChar = msg->wParam;
}
else
{
WCHAR Chars[2];
INT RetChars = 0;
VirtualKeyCode = msg->wParam;
RetChars = ToUnicodeEx(VirtualKeyCode,
VirtualScanCode,
KeyState,
Chars,
2,
0,
NULL);
UnicodeChar = (RetChars == 1 ? Chars[0] : 0);
}
Fake = UnicodeChar &&
(msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
if (NotChar) LastVirtualKey = msg->wParam;
DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n",
Down ? "down" : "up ",
(msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
"char" : "key ",
Fake ? "fake" : "real",
NotChar ? "notc" : "char",
VirtualScanCode,
VirtualKeyCode,
(UnicodeChar >= L' ') ? UnicodeChar : L'.',
ShiftState);
if (Fake) return;
//
// FIXME: Scrolling via keyboard shortcuts must be done differently,
// without touching the internal VirtualY variable.
//
#if 0
if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 &&
(VirtualKeyCode == VK_UP || VirtualKeyCode == VK_DOWN) )
{
if (!Down) return;
/* Scroll up or down */
if (VirtualKeyCode == VK_UP)
{
/* Only scroll up if there is room to scroll up into */
if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
{
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
Console->ActiveBuffer->ScreenBufferSize.Y - 1) %
Console->ActiveBuffer->ScreenBufferSize.Y;
Console->ActiveBuffer->CursorPosition.Y++;
}
}
else
{
/* Only scroll down if there is room to scroll down into */
if (Console->ActiveBuffer->CursorPosition.Y != 0)
{
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
Console->ActiveBuffer->ScreenBufferSize.Y;
Console->ActiveBuffer->CursorPosition.Y--;
}
}
ConioDrawConsole(Console);
return;
}
#endif
/* Send the key press to the console driver */
er.EventType = KEY_EVENT;
er.Event.KeyEvent.bKeyDown = Down;
er.Event.KeyEvent.wRepeatCount = 1;
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
er.Event.KeyEvent.dwControlKeyState = ShiftState;
ConioProcessInputEvent(Console, &er);
}
DWORD
ConioEffectiveCursorSize(PCONSRV_CONSOLE Console, DWORD Scale)
{
DWORD Size = (Console->ActiveBuffer->CursorInfo.dwSize * Scale + 99) / 100;
/* If line input in progress, perhaps adjust for insert toggle */
if (Console->LineBuffer && !Console->LineComplete && (Console->InsertMode ? !Console->LineInsertToggle : Console->LineInsertToggle))
return (Size * 2 <= Scale) ? (Size * 2) : (Size / 2);
return Size;
}
/* EOF */