mirror of
https://github.com/acidanthera/audk.git
synced 2025-08-23 02:28:08 +02:00
When updating MdePkg's CR macro to enforce signature checking in all usages, it was discovered that EmulatorPkg was initializing a structure without setting the signature for it, causing an error to be returned when CR now checked the signature. This commit updates the graphics stack in EmulatorPkg to set the signature of the data structure and check the return value of the wrapper for the CR macro. Signed-off-by: Oliver Smith-Denny <osde@linux.microsoft.com>
464 lines
12 KiB
C
464 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);
|
|
|
|
if (Private == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
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;
|
|
}
|