/*++ @file | |
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> | |
Portions copyright (c) 2010 0 2011,Apple Inc. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "Gop.h" | |
BOOLEAN | |
GopPrivateIsKeyRegistered ( | |
IN EFI_KEY_DATA *RegsiteredData, | |
IN EFI_KEY_DATA *InputData | |
) | |
/*++ | |
Routine Description: | |
Arguments: | |
RegsiteredData - A pointer to a buffer that is filled in with the keystroke | |
state data for the key that was registered. | |
InputData - A pointer to a buffer that is filled in with the keystroke | |
state data for the key that was pressed. | |
Returns: | |
TRUE - Key be pressed matches a registered key. | |
FLASE - Match failed. | |
**/ | |
{ | |
ASSERT (RegsiteredData != NULL && InputData != NULL); | |
if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) || | |
(RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) | |
{ | |
return FALSE; | |
} | |
// | |
// Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored. | |
// | |
if ((RegsiteredData->KeyState.KeyShiftState != 0) && | |
(RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState)) | |
{ | |
return FALSE; | |
} | |
if ((RegsiteredData->KeyState.KeyToggleState != 0) && | |
(RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState)) | |
{ | |
return FALSE; | |
} | |
return TRUE; | |
} | |
VOID | |
EFIAPI | |
GopPrivateMakeCallbackFunction ( | |
IN VOID *Context, | |
IN EFI_KEY_DATA *KeyData | |
) | |
{ | |
LIST_ENTRY *Link; | |
EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify; | |
GOP_PRIVATE_DATA *Private = (GOP_PRIVATE_DATA *)Context; | |
KeyMapMake (KeyData); | |
for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) { | |
CurrentNotify = CR ( | |
Link, | |
EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY, | |
NotifyEntry, | |
EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE | |
); | |
if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { | |
// We could be called at a high TPL so signal an event to call the registered function | |
// at a lower TPL. | |
gBS->SignalEvent (CurrentNotify->Event); | |
} | |
} | |
} | |
VOID | |
EFIAPI | |
GopPrivateBreakCallbackFunction ( | |
IN VOID *Context, | |
IN EFI_KEY_DATA *KeyData | |
) | |
{ | |
KeyMapBreak (KeyData); | |
} | |
// | |
// Simple Text In implementation. | |
// | |
/** | |
Reset the input device and optionally run diagnostics | |
@param This Protocol instance pointer. | |
@param ExtendedVerification Driver may perform diagnostics on reset. | |
@retval EFI_SUCCESS The device was reset. | |
@retval EFI_DEVICE_ERROR The device is not functioning properly and could not be reset. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
EmuGopSimpleTextInReset ( | |
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, | |
IN BOOLEAN ExtendedVerification | |
) | |
{ | |
GOP_PRIVATE_DATA *Private; | |
EFI_KEY_DATA KeyData; | |
EFI_TPL OldTpl; | |
Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This); | |
if (Private->EmuGraphicsWindow == NULL) { | |
return EFI_SUCCESS; | |
} | |
// | |
// Enter critical section | |
// | |
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
// | |
// A reset is draining the Queue | |
// | |
while (Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData) == EFI_SUCCESS) { | |
} | |
// | |
// Leave critical section and return | |
// | |
gBS->RestoreTPL (OldTpl); | |
return EFI_SUCCESS; | |
} | |
/** | |
Reads the next keystroke from the input device. The WaitForKey Event can | |
be used to test for existence of a keystroke via WaitForEvent () call. | |
@param This Protocol instance pointer. | |
@param Key A pointer to a buffer that is filled in with the keystroke | |
information for the key that was pressed. | |
@retval EFI_SUCCESS The keystroke information was returned. | |
@retval EFI_NOT_READY There was no keystroke data available. | |
@retval EFI_DEVICE_ERROR The keystroke information was not returned due to | |
hardware errors. | |
@retval EFI_UNSUPPORTED The device does not support the ability to read keystroke data. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
EmuGopSimpleTextInReadKeyStroke ( | |
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, | |
OUT EFI_INPUT_KEY *Key | |
) | |
{ | |
GOP_PRIVATE_DATA *Private; | |
EFI_STATUS Status; | |
EFI_TPL OldTpl; | |
EFI_KEY_DATA KeyData; | |
Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This); | |
if (Private->EmuGraphicsWindow == NULL) { | |
return EFI_NOT_READY; | |
} | |
// | |
// Enter critical section | |
// | |
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
Status = Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData); | |
if (!EFI_ERROR (Status)) { | |
if ((KeyData.Key.ScanCode == 0) && (KeyData.Key.UnicodeChar == 0)) { | |
// Modifier key was pressed | |
Status = EFI_NOT_READY; | |
} else { | |
CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY)); | |
} | |
} | |
// | |
// Leave critical section and return | |
// | |
gBS->RestoreTPL (OldTpl); | |
return Status; | |
} | |
/** | |
SimpleTextIn and SimpleTextInEx Notify Wait Event | |
@param Event Event whose notification function is being invoked. | |
@param Context Pointer to GOP_PRIVATE_DATA. | |
**/ | |
VOID | |
EFIAPI | |
EmuGopSimpleTextInWaitForKey ( | |
IN EFI_EVENT Event, | |
IN VOID *Context | |
) | |
{ | |
GOP_PRIVATE_DATA *Private; | |
EFI_STATUS Status; | |
EFI_TPL OldTpl; | |
Private = (GOP_PRIVATE_DATA *)Context; | |
if (Private->EmuGraphicsWindow == NULL) { | |
return; | |
} | |
// | |
// Enter critical section | |
// | |
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
Status = Private->EmuGraphicsWindow->CheckKey (Private->EmuGraphicsWindow); | |
if (!EFI_ERROR (Status)) { | |
// | |
// If a there is a key in the queue signal our event. | |
// | |
gBS->SignalEvent (Event); | |
} | |
// | |
// Leave critical section and return | |
// | |
gBS->RestoreTPL (OldTpl); | |
} | |
// | |
// Simple Text Input Ex protocol functions | |
// | |
/** | |
The Reset() function resets the input device hardware. As part | |
of initialization process, the firmware/device will make a quick | |
but reasonable attempt to verify that the device is functioning. | |
If the ExtendedVerification flag is TRUE the firmware may take | |
an extended amount of time to verify the device is operating on | |
reset. Otherwise the reset operation is to occur as quickly as | |
possible. The hardware verification process is not defined by | |
this specification and is left up to the platform firmware or | |
driver to implement. | |
@param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. | |
@param ExtendedVerification Indicates that the driver may | |
perform a more exhaustive | |
verification operation of the | |
device during reset. | |
@retval EFI_SUCCESS The device was reset. | |
@retval EFI_DEVICE_ERROR The device is not functioning | |
correctly and could not be reset. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
EmuGopSimpleTextInExResetEx ( | |
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, | |
IN BOOLEAN ExtendedVerification | |
) | |
/*++ | |
Routine Description: | |
Reset the input device and optionaly run diagnostics | |
Arguments: | |
This - Protocol instance pointer. | |
ExtendedVerification - Driver may perform diagnostics on reset. | |
Returns: | |
EFI_SUCCESS - The device was reset. | |
**/ | |
{ | |
return EFI_SUCCESS; | |
} | |
/** | |
The function reads the next keystroke from the input device. If | |
there is no pending keystroke the function returns | |
EFI_NOT_READY. If there is a pending keystroke, then | |
KeyData.Key.ScanCode is the EFI scan code defined in Error! | |
Reference source not found. The KeyData.Key.UnicodeChar is the | |
actual printable character or is zero if the key does not | |
represent a printable character (control key, function key, | |
etc.). The KeyData.KeyState is shift state for the character | |
reflected in KeyData.Key.UnicodeChar or KeyData.Key.ScanCode . | |
When interpreting the data from this function, it should be | |
noted that if a class of printable characters that are | |
normally adjusted by shift modifiers (e.g. Shift Key + "f" | |
key) would be presented solely as a KeyData.Key.UnicodeChar | |
without the associated shift state. So in the previous example | |
of a Shift Key + "f" key being pressed, the only pertinent | |
data returned would be KeyData.Key.UnicodeChar with the value | |
of "F". This of course would not typically be the case for | |
non-printable characters such as the pressing of the Right | |
Shift Key + F10 key since the corresponding returned data | |
would be reflected both in the KeyData.KeyState.KeyShiftState | |
and KeyData.Key.ScanCode values. UEFI drivers which implement | |
the EFI_SIMPLE_TEXT_INPUT_EX protocol are required to return | |
KeyData.Key and KeyData.KeyState values. These drivers must | |
always return the most current state of | |
KeyData.KeyState.KeyShiftState and | |
KeyData.KeyState.KeyToggleState. It should also be noted that | |
certain input devices may not be able to produce shift or toggle | |
state information, and in those cases the high order bit in the | |
respective Toggle and Shift state fields should not be active. | |
@param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. | |
@param KeyData A pointer to a buffer that is filled in with | |
the keystroke state data for the key that was | |
pressed. | |
@retval EFI_SUCCESS The keystroke information was | |
returned. | |
@retval EFI_NOT_READY There was no keystroke data available. | |
EFI_DEVICE_ERROR The keystroke | |
information was not returned due to | |
hardware errors. | |
@retval EFI_UNSUPPORTED The device does not support the ability to read keystroke data. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
EmuGopSimpleTextInExReadKeyStrokeEx ( | |
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, | |
OUT EFI_KEY_DATA *KeyData | |
) | |
/*++ | |
Routine Description: | |
Reads the next keystroke from the input device. The WaitForKey Event can | |
be used to test for existance of a keystroke via WaitForEvent () call. | |
Arguments: | |
This - Protocol instance pointer. | |
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 availiable. | |
EFI_DEVICE_ERROR - The keystroke information was not returned due to | |
hardware errors. | |
EFI_INVALID_PARAMETER - KeyData is NULL. | |
**/ | |
{ | |
EFI_STATUS Status; | |
GOP_PRIVATE_DATA *Private; | |
EFI_TPL OldTpl; | |
if (KeyData == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); | |
if (Private->EmuGraphicsWindow == NULL) { | |
return EFI_NOT_READY; | |
} | |
// | |
// Enter critical section | |
// | |
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
Status = Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, KeyData); | |
// | |
// Leave critical section and return | |
// | |
gBS->RestoreTPL (OldTpl); | |
return Status; | |
} | |
/** | |
The SetState() function allows the input device hardware to | |
have state settings adjusted. | |
@param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. | |
@param KeyToggleState Pointer to the EFI_KEY_TOGGLE_STATE to | |
set the state for the input device. | |
@retval EFI_SUCCESS The device state was set appropriately. | |
@retval EFI_DEVICE_ERROR The device is not functioning | |
correctly and could not have the | |
setting adjusted. | |
@retval EFI_UNSUPPORTED The device does not support the | |
ability to have its state set. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
EmuGopSimpleTextInExSetState ( | |
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, | |
IN EFI_KEY_TOGGLE_STATE *KeyToggleState | |
) | |
{ | |
GOP_PRIVATE_DATA *Private; | |
EFI_STATUS Status; | |
EFI_TPL OldTpl; | |
if (KeyToggleState == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); | |
if (Private->EmuGraphicsWindow == NULL) { | |
return EFI_NOT_READY; | |
} | |
if (((Private->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) || | |
((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) | |
{ | |
return EFI_UNSUPPORTED; | |
} | |
// | |
// Enter critical section | |
// | |
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
Status = Private->EmuGraphicsWindow->KeySetState (Private->EmuGraphicsWindow, KeyToggleState); | |
// | |
// Leave critical section and return | |
// | |
gBS->RestoreTPL (OldTpl); | |
return Status; | |
} | |
/** | |
SimpleTextIn and SimpleTextInEx Notify Wait Event | |
@param Event Event whose notification function is being invoked. | |
@param Context Pointer to GOP_PRIVATE_DATA. | |
**/ | |
VOID | |
EFIAPI | |
EmuGopRegisterKeyCallback ( | |
IN EFI_EVENT Event, | |
IN VOID *Context | |
) | |
{ | |
EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *ExNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *)Context; | |
ExNotify->KeyNotificationFn (&ExNotify->KeyData); | |
} | |
/** | |
The RegisterKeystrokeNotify() function registers a function | |
which will be called when a specified keystroke will occur. | |
@param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. | |
@param KeyData A pointer to a buffer that is filled in with | |
the keystroke information for the key that was | |
pressed. | |
@param KeyNotificationFunction Points to the function to be | |
called when the key sequence | |
is typed specified by KeyData. | |
@param NotifyHandle Points to the unique handle assigned to | |
the registered notification. | |
@retval EFI_SUCCESS The device state was set | |
appropriately. | |
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary | |
data structures. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
EmuGopSimpleTextInExRegisterKeyNotify ( | |
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, | |
IN EFI_KEY_DATA *KeyData, | |
IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, | |
OUT VOID **NotifyHandle | |
) | |
{ | |
EFI_STATUS Status; | |
GOP_PRIVATE_DATA *Private; | |
EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify; | |
LIST_ENTRY *Link; | |
EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify; | |
if ((KeyData == NULL) || (KeyNotificationFunction == NULL) || (NotifyHandle == NULL)) { | |
return EFI_INVALID_PARAMETER; | |
} | |
Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); | |
// | |
// Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered. | |
// | |
for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) { | |
CurrentNotify = CR ( | |
Link, | |
EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY, | |
NotifyEntry, | |
EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE | |
); | |
if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { | |
if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) { | |
*NotifyHandle = CurrentNotify->NotifyHandle; | |
return EFI_SUCCESS; | |
} | |
} | |
} | |
// | |
// Allocate resource to save the notification function | |
// | |
NewNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *)AllocateZeroPool (sizeof (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY)); | |
if (NewNotify == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
NewNotify->Signature = EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE; | |
NewNotify->KeyNotificationFn = KeyNotificationFunction; | |
NewNotify->NotifyHandle = (EFI_HANDLE)NewNotify; | |
CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData)); | |
InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry); | |
Status = gBS->CreateEvent ( | |
EVT_NOTIFY_SIGNAL, | |
TPL_NOTIFY, | |
EmuGopRegisterKeyCallback, | |
NewNotify, | |
&NewNotify->Event | |
); | |
ASSERT_EFI_ERROR (Status); | |
*NotifyHandle = NewNotify->NotifyHandle; | |
return EFI_SUCCESS; | |
} | |
/** | |
The UnregisterKeystrokeNotify() function removes the | |
notification which was previously registered. | |
@param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. | |
@param NotificationHandle The handle of the notification | |
function being unregistered. | |
@retval EFI_SUCCESS The device state was set appropriately. | |
@retval EFI_INVALID_PARAMETER The NotificationHandle is | |
invalid. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
EmuGopSimpleTextInExUnregisterKeyNotify ( | |
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, | |
IN VOID *NotificationHandle | |
) | |
/*++ | |
Routine Description: | |
Remove a registered notification function from a particular keystroke. | |
Arguments: | |
This - Protocol instance pointer. | |
NotificationHandle - The handle of the notification function being unregistered. | |
Returns: | |
EFI_SUCCESS - The notification function was unregistered successfully. | |
EFI_INVALID_PARAMETER - The NotificationHandle is invalid. | |
**/ | |
{ | |
GOP_PRIVATE_DATA *Private; | |
LIST_ENTRY *Link; | |
EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify; | |
if (NotificationHandle == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
if (((EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *)NotificationHandle)->Signature != EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE) { | |
return EFI_INVALID_PARAMETER; | |
} | |
Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); | |
for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) { | |
CurrentNotify = CR ( | |
Link, | |
EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY, | |
NotifyEntry, | |
EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE | |
); | |
if (CurrentNotify->NotifyHandle == NotificationHandle) { | |
// | |
// Remove the notification function from NotifyList and free resources | |
// | |
RemoveEntryList (&CurrentNotify->NotifyEntry); | |
gBS->CloseEvent (CurrentNotify->Event); | |
gBS->FreePool (CurrentNotify); | |
return EFI_SUCCESS; | |
} | |
} | |
// | |
// Can not find the specified Notification Handle | |
// | |
return EFI_INVALID_PARAMETER; | |
} | |
/** | |
Initialize SimplelTextIn and SimpleTextInEx protocols in the Private | |
context structure. | |
@param Private Context structure to fill in. | |
@return EFI_SUCCESS Initialization was a success | |
**/ | |
EFI_STATUS | |
EmuGopInitializeSimpleTextInForWindow ( | |
IN GOP_PRIVATE_DATA *Private | |
) | |
{ | |
EFI_STATUS Status; | |
// | |
// Initialize Simple Text In protoocol | |
// | |
Private->SimpleTextIn.Reset = EmuGopSimpleTextInReset; | |
Private->SimpleTextIn.ReadKeyStroke = EmuGopSimpleTextInReadKeyStroke; | |
Status = gBS->CreateEvent ( | |
EVT_NOTIFY_WAIT, | |
TPL_NOTIFY, | |
EmuGopSimpleTextInWaitForKey, | |
Private, | |
&Private->SimpleTextIn.WaitForKey | |
); | |
ASSERT_EFI_ERROR (Status); | |
// | |
// Initialize Simple Text In Ex | |
// | |
Private->SimpleTextInEx.Reset = EmuGopSimpleTextInExResetEx; | |
Private->SimpleTextInEx.ReadKeyStrokeEx = EmuGopSimpleTextInExReadKeyStrokeEx; | |
Private->SimpleTextInEx.SetState = EmuGopSimpleTextInExSetState; | |
Private->SimpleTextInEx.RegisterKeyNotify = EmuGopSimpleTextInExRegisterKeyNotify; | |
Private->SimpleTextInEx.UnregisterKeyNotify = EmuGopSimpleTextInExUnregisterKeyNotify; | |
Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE); | |
InitializeListHead (&Private->NotifyList); | |
Status = gBS->CreateEvent ( | |
EVT_NOTIFY_WAIT, | |
TPL_NOTIFY, | |
EmuGopSimpleTextInWaitForKey, | |
Private, | |
&Private->SimpleTextInEx.WaitForKeyEx | |
); | |
ASSERT_EFI_ERROR (Status); | |
return Status; | |
} | |
// | |
// Simple Pointer implementation. | |
// | |
/** | |
Resets the pointer device hardware. | |
@param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL | |
instance. | |
@param ExtendedVerification Indicates that the driver may perform a more exhaustive | |
verification operation of the device during reset. | |
@retval EFI_SUCCESS The device was reset. | |
@retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
EmuGopSimplePointerReset ( | |
IN EFI_SIMPLE_POINTER_PROTOCOL *This, | |
IN BOOLEAN ExtendedVerification | |
) | |
{ | |
GOP_PRIVATE_DATA *Private; | |
EFI_SIMPLE_POINTER_STATE State; | |
EFI_TPL OldTpl; | |
Private = GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This); | |
if (Private->EmuGraphicsWindow == NULL) { | |
return EFI_SUCCESS; | |
} | |
// | |
// Enter critical section | |
// | |
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
// | |
// A reset is draining the Queue | |
// | |
while (Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, &State) == EFI_SUCCESS) { | |
} | |
// | |
// Leave critical section and return | |
// | |
gBS->RestoreTPL (OldTpl); | |
return EFI_SUCCESS; | |
} | |
/** | |
Retrieves the current state of a pointer device. | |
@param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL | |
instance. | |
@param State A pointer to the state information on the pointer device. | |
@retval EFI_SUCCESS The state of the pointer device was returned in State. | |
@retval EFI_NOT_READY The state of the pointer device has not changed since the last call to | |
GetState(). | |
@retval EFI_DEVICE_ERROR A device error occurred while attempting to retrieve the pointer device's | |
current state. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
EmuGopSimplePointerGetState ( | |
IN EFI_SIMPLE_POINTER_PROTOCOL *This, | |
IN OUT EFI_SIMPLE_POINTER_STATE *State | |
) | |
{ | |
GOP_PRIVATE_DATA *Private; | |
EFI_STATUS Status; | |
EFI_TPL OldTpl; | |
Private = GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This); | |
if (Private->EmuGraphicsWindow == NULL) { | |
return EFI_NOT_READY; | |
} | |
// | |
// Enter critical section | |
// | |
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
Status = Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, State); | |
// | |
// Leave critical section and return | |
// | |
gBS->RestoreTPL (OldTpl); | |
return Status; | |
} | |
/** | |
SimplePointer Notify Wait Event | |
@param Event Event whose notification function is being invoked. | |
@param Context Pointer to GOP_PRIVATE_DATA. | |
**/ | |
VOID | |
EFIAPI | |
EmuGopSimplePointerWaitForInput ( | |
IN EFI_EVENT Event, | |
IN VOID *Context | |
) | |
{ | |
GOP_PRIVATE_DATA *Private; | |
EFI_STATUS Status; | |
EFI_TPL OldTpl; | |
Private = (GOP_PRIVATE_DATA *)Context; | |
if (Private->EmuGraphicsWindow == NULL) { | |
return; | |
} | |
// | |
// Enter critical section | |
// | |
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); | |
Status = Private->EmuGraphicsWindow->CheckPointer (Private->EmuGraphicsWindow); | |
if (!EFI_ERROR (Status)) { | |
// | |
// If the pointer state has changed, signal our event. | |
// | |
gBS->SignalEvent (Event); | |
} | |
// | |
// Leave critical section and return | |
// | |
gBS->RestoreTPL (OldTpl); | |
} | |
/** | |
SimplePointer constructor | |
@param Private Context structure to fill in. | |
@retval EFI_SUCCESS Constructor had success | |
**/ | |
EFI_STATUS | |
EmuGopInitializeSimplePointerForWindow ( | |
IN GOP_PRIVATE_DATA *Private | |
) | |
{ | |
EFI_STATUS Status; | |
// | |
// Initialize Simple Pointer protoocol | |
// | |
Private->PointerMode.ResolutionX = 1; | |
Private->PointerMode.ResolutionY = 1; | |
Private->PointerMode.ResolutionZ = 1; | |
Private->PointerMode.LeftButton = TRUE; | |
Private->PointerMode.RightButton = TRUE; | |
Private->SimplePointer.Reset = EmuGopSimplePointerReset; | |
Private->SimplePointer.GetState = EmuGopSimplePointerGetState; | |
Private->SimplePointer.Mode = &Private->PointerMode; | |
Status = gBS->CreateEvent ( | |
EVT_NOTIFY_WAIT, | |
TPL_NOTIFY, | |
EmuGopSimplePointerWaitForInput, | |
Private, | |
&Private->SimplePointer.WaitForInput | |
); | |
return Status; | |
} |