mirror of https://github.com/acidanthera/audk.git
879 lines
25 KiB
C
879 lines
25 KiB
C
/*++ @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.
|
|
|
|
**/
|
|
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.
|
|
|
|
|
|
**/
|
|
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;
|
|
}
|