mirror of https://github.com/acidanthera/audk.git
460 lines
12 KiB
C
460 lines
12 KiB
C
/** @file
|
|
|
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
Module Name:
|
|
|
|
WinGopInput.c
|
|
|
|
Abstract:
|
|
|
|
This file produces the Simple Text In for an Gop window.
|
|
|
|
This stuff is linked at the hip to the Window, since the window
|
|
processing is done in a thread kicked off in WinNtGopImplementation.c
|
|
|
|
Since the window information is processed in an other thread we need
|
|
a keyboard Queue to pass data about. The Simple Text In code just
|
|
takes data off the Queue. The WinProc message loop takes keyboard input
|
|
and places it in the Queue.
|
|
|
|
|
|
**/
|
|
|
|
#include "WinGop.h"
|
|
|
|
/**
|
|
TODO: Add function description
|
|
|
|
@param Private TODO: add argument description
|
|
|
|
@retval EFI_SUCCESS TODO: Add description for return value
|
|
|
|
**/
|
|
EFI_STATUS
|
|
GopPrivateCreateQ (
|
|
IN GRAPHICS_PRIVATE_DATA *Private,
|
|
IN GOP_QUEUE_FIXED *Queue
|
|
)
|
|
{
|
|
InitializeCriticalSection (&Queue->Cs);
|
|
Queue->Front = 0;
|
|
Queue->Rear = 0;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
TODO: Add function description
|
|
|
|
@param Private TODO: add argument description
|
|
|
|
@retval EFI_SUCCESS TODO: Add description for return value
|
|
|
|
**/
|
|
EFI_STATUS
|
|
GopPrivateDestroyQ (
|
|
IN GRAPHICS_PRIVATE_DATA *Private,
|
|
IN GOP_QUEUE_FIXED *Queue
|
|
)
|
|
{
|
|
Queue->Front = 0;
|
|
Queue->Rear = 0;
|
|
DeleteCriticalSection (&Queue->Cs);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
TODO: Add function description
|
|
|
|
@param Private TODO: add argument description
|
|
@param Key TODO: add argument description
|
|
|
|
@retval EFI_NOT_READY TODO: Add description for return value
|
|
@retval EFI_SUCCESS TODO: Add description for return value
|
|
|
|
**/
|
|
EFI_STATUS
|
|
GopPrivateAddQ (
|
|
IN GRAPHICS_PRIVATE_DATA *Private,
|
|
IN GOP_QUEUE_FIXED *Queue,
|
|
IN EFI_KEY_DATA *KeyData
|
|
)
|
|
{
|
|
EnterCriticalSection (&Queue->Cs);
|
|
|
|
if ((Queue->Rear + 1) % MAX_Q == Queue->Front) {
|
|
LeaveCriticalSection (&Queue->Cs);
|
|
return EFI_NOT_READY;
|
|
}
|
|
|
|
CopyMem (&Queue->Q[Queue->Rear], KeyData, sizeof (EFI_KEY_DATA));
|
|
Queue->Rear = (Queue->Rear + 1) % MAX_Q;
|
|
|
|
LeaveCriticalSection (&Queue->Cs);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
TODO: Add function description
|
|
|
|
@param Private TODO: add argument description
|
|
@param Key TODO: add argument description
|
|
|
|
@retval EFI_NOT_READY TODO: Add description for return value
|
|
@retval EFI_SUCCESS TODO: Add description for return value
|
|
|
|
**/
|
|
EFI_STATUS
|
|
GopPrivateDeleteQ (
|
|
IN GRAPHICS_PRIVATE_DATA *Private,
|
|
IN GOP_QUEUE_FIXED *Queue,
|
|
OUT EFI_KEY_DATA *Key
|
|
)
|
|
{
|
|
EnterCriticalSection (&Queue->Cs);
|
|
|
|
if (Queue->Front == Queue->Rear) {
|
|
LeaveCriticalSection (&Queue->Cs);
|
|
return EFI_NOT_READY;
|
|
}
|
|
|
|
CopyMem (Key, &Queue->Q[Queue->Front], sizeof (EFI_KEY_DATA));
|
|
Queue->Front = (Queue->Front + 1) % MAX_Q;
|
|
|
|
if ((Key->Key.ScanCode == SCAN_NULL) && (Key->Key.UnicodeChar == CHAR_NULL)) {
|
|
if (!Private->IsPartialKeySupport) {
|
|
//
|
|
// If partial keystrok is not enabled, don't return the partial keystroke.
|
|
//
|
|
LeaveCriticalSection (&Queue->Cs);
|
|
ZeroMem (Key, sizeof (EFI_KEY_DATA));
|
|
return EFI_NOT_READY;
|
|
}
|
|
}
|
|
|
|
LeaveCriticalSection (&Queue->Cs);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
TODO: Add function description
|
|
|
|
@param Private TODO: add argument description
|
|
|
|
@retval EFI_NOT_READY TODO: Add description for return value
|
|
@retval EFI_SUCCESS TODO: Add description for return value
|
|
|
|
**/
|
|
EFI_STATUS
|
|
GopPrivateCheckQ (
|
|
IN GOP_QUEUE_FIXED *Queue
|
|
)
|
|
{
|
|
if (Queue->Front == Queue->Rear) {
|
|
return EFI_NOT_READY;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Initialize the key state.
|
|
|
|
@param Private The GOP_PRIVATE_DATA instance.
|
|
@param KeyState A pointer to receive the key state information.
|
|
**/
|
|
VOID
|
|
InitializeKeyState (
|
|
IN GRAPHICS_PRIVATE_DATA *Private,
|
|
IN EFI_KEY_STATE *KeyState
|
|
)
|
|
{
|
|
KeyState->KeyShiftState = EFI_SHIFT_STATE_VALID;
|
|
KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID;
|
|
|
|
//
|
|
// Record Key shift state and toggle state
|
|
//
|
|
if (Private->LeftCtrl) {
|
|
KeyState->KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;
|
|
}
|
|
|
|
if (Private->RightCtrl) {
|
|
KeyState->KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;
|
|
}
|
|
|
|
if (Private->LeftAlt) {
|
|
KeyState->KeyShiftState |= EFI_LEFT_ALT_PRESSED;
|
|
}
|
|
|
|
if (Private->RightAlt) {
|
|
KeyState->KeyShiftState |= EFI_RIGHT_ALT_PRESSED;
|
|
}
|
|
|
|
if (Private->LeftShift) {
|
|
KeyState->KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
|
|
}
|
|
|
|
if (Private->RightShift) {
|
|
KeyState->KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
|
|
}
|
|
|
|
if (Private->LeftLogo) {
|
|
KeyState->KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
|
|
}
|
|
|
|
if (Private->RightLogo) {
|
|
KeyState->KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
|
|
}
|
|
|
|
if (Private->Menu) {
|
|
KeyState->KeyShiftState |= EFI_MENU_KEY_PRESSED;
|
|
}
|
|
|
|
if (Private->SysReq) {
|
|
KeyState->KeyShiftState |= EFI_SYS_REQ_PRESSED;
|
|
}
|
|
|
|
if (Private->CapsLock) {
|
|
KeyState->KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
|
|
}
|
|
|
|
if (Private->NumLock) {
|
|
KeyState->KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
|
|
}
|
|
|
|
if (Private->ScrollLock) {
|
|
KeyState->KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
|
|
}
|
|
|
|
if (Private->IsPartialKeySupport) {
|
|
KeyState->KeyToggleState |= EFI_KEY_STATE_EXPOSED;
|
|
}
|
|
}
|
|
|
|
/**
|
|
TODO: Add function description
|
|
|
|
@param Private TODO: add argument description
|
|
@param Key TODO: add argument description
|
|
|
|
@retval EFI_NOT_READY TODO: Add description for return value
|
|
@retval EFI_SUCCESS TODO: Add description for return value
|
|
|
|
**/
|
|
EFI_STATUS
|
|
GopPrivateAddKey (
|
|
IN GRAPHICS_PRIVATE_DATA *Private,
|
|
IN EFI_INPUT_KEY Key
|
|
)
|
|
{
|
|
EFI_KEY_DATA KeyData;
|
|
|
|
KeyData.Key = Key;
|
|
InitializeKeyState (Private, &KeyData.KeyState);
|
|
|
|
//
|
|
// Convert Ctrl+[1-26] to Ctrl+[A-Z]
|
|
//
|
|
if ((Private->LeftCtrl || Private->RightCtrl) &&
|
|
(KeyData.Key.UnicodeChar >= 1) && (KeyData.Key.UnicodeChar <= 26)
|
|
)
|
|
{
|
|
if ((Private->LeftShift || Private->RightShift) == Private->CapsLock) {
|
|
KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar + L'a' - 1);
|
|
} else {
|
|
KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar + L'A' - 1);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Unmask the Shift bit for printable char
|
|
//
|
|
if (((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) ||
|
|
((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z'))
|
|
)
|
|
{
|
|
KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED);
|
|
}
|
|
|
|
GopPrivateAddQ (Private, &Private->QueueForRead, &KeyData);
|
|
if (Private->MakeRegisterdKeyCallback != NULL) {
|
|
Private->MakeRegisterdKeyCallback (Private->RegisterdKeyCallbackContext, &KeyData);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
WinNtWndCheckKey (
|
|
IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo
|
|
)
|
|
{
|
|
GRAPHICS_PRIVATE_DATA *Private;
|
|
|
|
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
|
|
|
|
return GopPrivateCheckQ (&Private->QueueForRead);
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
WinNtWndGetKey (
|
|
IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo,
|
|
IN EFI_KEY_DATA *KeyData
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Reads the next keystroke from the input device. The WaitForKey Event can
|
|
be used to test for existence of a keystroke via WaitForEvent () call.
|
|
|
|
Arguments:
|
|
Private - The private structure of WinNt Gop device.
|
|
KeyData - A pointer to a buffer that is filled in with the keystroke
|
|
state data for the key that was pressed.
|
|
|
|
Returns:
|
|
EFI_SUCCESS - The keystroke information was returned.
|
|
EFI_NOT_READY - There was no keystroke data available.
|
|
EFI_DEVICE_ERROR - The keystroke information was not returned due to
|
|
hardware errors.
|
|
EFI_INVALID_PARAMETER - KeyData is NULL.
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
GRAPHICS_PRIVATE_DATA *Private;
|
|
|
|
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
|
|
|
|
ZeroMem (&KeyData->Key, sizeof (KeyData->Key));
|
|
InitializeKeyState (Private, &KeyData->KeyState);
|
|
|
|
Status = GopPrivateCheckQ (&Private->QueueForRead);
|
|
if (!EFI_ERROR (Status)) {
|
|
//
|
|
// If a Key press exists try and read it.
|
|
//
|
|
Status = GopPrivateDeleteQ (Private, &Private->QueueForRead, KeyData);
|
|
if (!EFI_ERROR (Status)) {
|
|
//
|
|
// If partial keystroke is not enabled, check whether it is value key. If not return
|
|
// EFI_NOT_READY.
|
|
//
|
|
if (!Private->IsPartialKeySupport) {
|
|
if ((KeyData->Key.ScanCode == SCAN_NULL) && (KeyData->Key.UnicodeChar == CHAR_NULL)) {
|
|
Status = EFI_NOT_READY;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
WinNtWndKeySetState (
|
|
IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo,
|
|
IN EFI_KEY_TOGGLE_STATE *KeyToggleState
|
|
)
|
|
{
|
|
GRAPHICS_PRIVATE_DATA *Private;
|
|
|
|
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
|
|
Private->ScrollLock = FALSE;
|
|
Private->NumLock = FALSE;
|
|
Private->CapsLock = FALSE;
|
|
Private->IsPartialKeySupport = FALSE;
|
|
|
|
if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {
|
|
Private->ScrollLock = TRUE;
|
|
}
|
|
|
|
if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {
|
|
Private->NumLock = TRUE;
|
|
}
|
|
|
|
if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {
|
|
Private->CapsLock = TRUE;
|
|
}
|
|
|
|
if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {
|
|
Private->IsPartialKeySupport = TRUE;
|
|
}
|
|
|
|
Private->KeyState.KeyToggleState = *KeyToggleState;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
WinNtWndRegisterKeyNotify (
|
|
IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo,
|
|
IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeCallBack,
|
|
IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakCallBack,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
GRAPHICS_PRIVATE_DATA *Private;
|
|
|
|
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
|
|
|
|
Private->MakeRegisterdKeyCallback = MakeCallBack;
|
|
Private->BreakRegisterdKeyCallback = BreakCallBack;
|
|
Private->RegisterdKeyCallbackContext = Context;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
WinNtWndCheckPointer (
|
|
IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo
|
|
)
|
|
{
|
|
GRAPHICS_PRIVATE_DATA *Private;
|
|
|
|
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
|
|
|
|
if (!Private->PointerStateChanged) {
|
|
return EFI_NOT_READY;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
WinNtWndGetPointerState (
|
|
IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo,
|
|
IN EFI_SIMPLE_POINTER_STATE *State
|
|
)
|
|
{
|
|
GRAPHICS_PRIVATE_DATA *Private;
|
|
|
|
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
|
|
|
|
if (!Private->PointerStateChanged) {
|
|
return EFI_NOT_READY;
|
|
}
|
|
|
|
State->RelativeMovementX = Private->PointerState.RelativeMovementX;
|
|
State->RelativeMovementY = Private->PointerState.RelativeMovementY;
|
|
State->RelativeMovementZ = Private->PointerState.RelativeMovementZ;
|
|
State->LeftButton = Private->PointerState.LeftButton;
|
|
State->RightButton = Private->PointerState.RightButton;
|
|
|
|
Private->PointerState.RelativeMovementX = 0;
|
|
Private->PointerState.RelativeMovementY = 0;
|
|
Private->PointerState.RelativeMovementZ = 0;
|
|
|
|
Private->PointerStateChanged = FALSE;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|