\r
**/\r
\r
-//\r
-// The package level header files this module uses\r
-//\r
-#include <Uefi.h>\r
-#include <WinNtDxe.h>\r
-//\r
-// The protocols, PPI and GUID defintions for this module\r
-//\r
-#include <Guid/EventGroup.h>\r
-#include <Protocol/WinNtIo.h>\r
-#include <Protocol/ComponentName.h>\r
-#include <Protocol/SimpleTextIn.h>\r
-#include <Protocol/DriverBinding.h>\r
-#include <Protocol/GraphicsOutput.h>\r
-//\r
-// The Library classes this module consumes\r
-//\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
\r
#include "WinNtGop.h"\r
\r
return EFI_SUCCESS;\r
}\r
\r
-//\r
-// Simple Text In implementation.\r
-//\r
+STATIC\r
+BOOLEAN\r
+GopPrivateIsKeyRegistered (\r
+ IN EFI_KEY_DATA *RegsiteredData,\r
+ IN EFI_KEY_DATA *InputData\r
+ )\r
+/*++\r
\r
+Routine Description:\r
\r
-/**\r
- TODO: Add function description\r
+Arguments:\r
\r
- @param This TODO: add argument description\r
- @param ExtendedVerification TODO: add argument description\r
+ RegsiteredData - A pointer to a buffer that is filled in with the keystroke \r
+ state data for the key that was registered.\r
+ InputData - A pointer to a buffer that is filled in with the keystroke \r
+ state data for the key that was pressed.\r
\r
- @retval EFI_SUCCESS TODO: Add description for return value\r
+Returns:\r
+ TRUE - Key be pressed matches a registered key.\r
+ FLASE - Match failed. \r
+ \r
+--*/\r
+{\r
+ ASSERT (RegsiteredData != NULL && InputData != NULL);\r
+ \r
+ if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||\r
+ (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
+ return FALSE; \r
+ } \r
+ \r
+ //\r
+ // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.\r
+ //\r
+ if (RegsiteredData->KeyState.KeyShiftState != 0 &&\r
+ RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {\r
+ return FALSE; \r
+ } \r
+ if (RegsiteredData->KeyState.KeyToggleState != 0 &&\r
+ RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {\r
+ return FALSE; \r
+ } \r
+ \r
+ return TRUE;\r
\r
-**/\r
+}\r
+\r
+\r
+STATIC\r
+VOID\r
+GopPrivateInvokeRegisteredFunction (\r
+ IN GOP_PRIVATE_DATA *Private,\r
+ IN EFI_KEY_DATA *KeyData\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function updates the status light of NumLock, ScrollLock and CapsLock.\r
+\r
+Arguments:\r
+\r
+ Private - The private structure of WinNt Gop device.\r
+ KeyData - A pointer to a buffer that is filled in with the keystroke \r
+ state data for the key that was pressed.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - The status light is updated successfully.\r
+\r
+--*/ \r
+{ \r
+ LIST_ENTRY *Link;\r
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;\r
+ \r
+ for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
+ CurrentNotify = CR (\r
+ Link, \r
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY, \r
+ NotifyEntry, \r
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE\r
+ );\r
+ if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { \r
+ CurrentNotify->KeyNotificationFn (KeyData);\r
+ }\r
+ } \r
+}\r
+\r
+STATIC\r
EFI_STATUS\r
-EFIAPI\r
-WinNtGopSimpleTextInReset (\r
- IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
- IN BOOLEAN ExtendedVerification\r
+GopPrivateUpdateStatusLight (\r
+ IN GOP_PRIVATE_DATA *Private\r
)\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function updates the status light of NumLock, ScrollLock and CapsLock.\r
+\r
+Arguments:\r
+\r
+ Private - The private structure of WinNt console In/Out.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - The status light is updated successfully.\r
+\r
+--*/ \r
+{ \r
+ //\r
+ // BUGBUG:Only SendInput/keybd_event function can toggle \r
+ // NumLock, CapsLock and ScrollLock keys.\r
+ // Neither of these functions is included in EFI_WIN_NT_THUNK_PROTOCOL.\r
+ // Thus, return immediately without operation.\r
+ //\r
+ return EFI_SUCCESS;\r
+ \r
+}\r
+\r
+\r
+STATIC\r
+EFI_STATUS\r
+GopPrivateResetWorker (\r
+ IN GOP_PRIVATE_DATA *Private\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is a worker function for SimpleTextIn/SimpleTextInEx.Reset().\r
+\r
+Arguments:\r
+\r
+ Private - WinNT GOP private structure\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - Reset successfully\r
+\r
+--*/\r
{\r
- GOP_PRIVATE_DATA *Private;\r
EFI_INPUT_KEY Key;\r
EFI_TPL OldTpl;\r
\r
- Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);\r
-\r
//\r
// Enter critical section\r
//\r
while (GopPrivateDeleteQ (Private, &Key) == EFI_SUCCESS)\r
;\r
\r
+ Private->LeftShift = FALSE;\r
+ Private->RightShift = FALSE;\r
+ Private->LeftAlt = FALSE;\r
+ Private->RightAlt = FALSE;\r
+ Private->LeftCtrl = FALSE;\r
+ Private->RightCtrl = FALSE;\r
+ Private->LeftLogo = FALSE;\r
+ Private->RightLogo = FALSE;\r
+ Private->Menu = FALSE;\r
+ Private->SysReq = FALSE;\r
+ \r
+ Private->CapsLock = FALSE;\r
+ Private->NumLock = FALSE;\r
+ Private->ScrollLock = FALSE;\r
+ \r
+ Private->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;\r
+ Private->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
+\r
//\r
// Leave critical section and return\r
//\r
gBS->RestoreTPL (OldTpl);\r
+\r
return EFI_SUCCESS;\r
}\r
\r
+STATIC\r
+EFI_STATUS\r
+GopPrivateReadKeyStrokeWorker (\r
+ IN GOP_PRIVATE_DATA *Private,\r
+ OUT EFI_KEY_DATA *KeyData\r
+ )\r
+/*++\r
\r
-/**\r
- TODO: Add function description\r
+ Routine Description:\r
+ Reads the next keystroke from the input device. The WaitForKey Event can \r
+ be used to test for existance of a keystroke via WaitForEvent () call.\r
\r
- @param This TODO: add argument description\r
- @param Key TODO: add argument description\r
+ Arguments:\r
+ Private - The private structure of WinNt Gop device.\r
+ KeyData - A pointer to a buffer that is filled in with the keystroke \r
+ state data for the key that was pressed.\r
\r
- @return TODO: add return values\r
+ Returns:\r
+ EFI_SUCCESS - The keystroke information was returned.\r
+ EFI_NOT_READY - There was no keystroke data availiable.\r
+ EFI_DEVICE_ERROR - The keystroke information was not returned due to \r
+ hardware errors.\r
+ EFI_INVALID_PARAMETER - KeyData is NULL. \r
\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtGopSimpleTextInReadKeyStroke (\r
- IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
- OUT EFI_INPUT_KEY *Key\r
- )\r
+--*/\r
{\r
- GOP_PRIVATE_DATA *Private;\r
- EFI_STATUS Status;\r
- EFI_TPL OldTpl;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl; \r
\r
- Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);\r
+ if (KeyData == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
//\r
// Enter critical section\r
//\r
// If a Key press exists try and read it.\r
//\r
- Status = GopPrivateDeleteQ (Private, Key);\r
+ Status = GopPrivateDeleteQ (Private, &KeyData->Key);\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Record Key shift state and toggle state\r
+ // \r
+ if (Private->LeftCtrl) {\r
+ Private->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;\r
+ } \r
+ if (Private->RightCtrl) {\r
+ Private->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;\r
+ } \r
+ if (Private->LeftAlt) { \r
+ Private->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;\r
+ } \r
+ if (Private->RightAlt) { \r
+ Private->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;\r
+ } \r
+ if (Private->LeftShift) { \r
+ Private->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;\r
+ } \r
+ if (Private->RightShift) { \r
+ Private->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;\r
+ } \r
+ if (Private->LeftLogo) { \r
+ Private->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;\r
+ } \r
+ if (Private->RightLogo) { \r
+ Private->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;\r
+ } \r
+ if (Private->Menu) { \r
+ Private->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;\r
+ } \r
+ if (Private->SysReq) { \r
+ Private->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;\r
+ } \r
+ if (Private->CapsLock) {\r
+ Private->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
+ }\r
+ if (Private->NumLock) {\r
+ Private->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
+ }\r
+ if (Private->ScrollLock) {\r
+ Private->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
+ }\r
+ \r
+ KeyData->KeyState.KeyShiftState = Private->KeyState.KeyShiftState;\r
+ KeyData->KeyState.KeyToggleState = Private->KeyState.KeyToggleState;\r
+ \r
+ Private->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;\r
+ Private->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
+ \r
+ //\r
+ // Leave critical section and return\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
+ \r
+ GopPrivateInvokeRegisteredFunction (Private, KeyData);\r
+ \r
+ return EFI_SUCCESS;\r
+ }\r
}\r
\r
//\r
gBS->RestoreTPL (OldTpl);\r
\r
return Status;\r
+\r
+}\r
+\r
+\r
+//\r
+// Simple Text In implementation.\r
+//\r
+\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param ExtendedVerification TODO: add argument description\r
+\r
+ @retval EFI_SUCCESS TODO: Add description for return value\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInReset (\r
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
+{\r
+ GOP_PRIVATE_DATA *Private;\r
+\r
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);\r
+\r
+ return GopPrivateResetWorker (Private);\r
+}\r
+\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param Key TODO: add argument description\r
+\r
+ @return TODO: add return values\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInReadKeyStroke (\r
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
+ OUT EFI_INPUT_KEY *Key\r
+ )\r
+{\r
+ GOP_PRIVATE_DATA *Private;\r
+ EFI_STATUS Status;\r
+ EFI_KEY_DATA KeyData;\r
+\r
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);\r
+\r
+ Status = GopPrivateReadKeyStrokeWorker (Private, &KeyData);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
+ \r
+ return EFI_SUCCESS; \r
}\r
\r
\r
gBS->RestoreTPL (OldTpl);\r
}\r
\r
+//\r
+// Simple Text Input Ex protocol functions\r
+//\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInExResetEx (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Reset the input device and optionaly run diagnostics\r
+\r
+ Arguments:\r
+ This - Protocol instance pointer.\r
+ ExtendedVerification - Driver may perform diagnostics on reset.\r
+\r
+ Returns:\r
+ EFI_SUCCESS - The device was reset.\r
+\r
+--*/\r
+{\r
+ GOP_PRIVATE_DATA *Private;\r
+\r
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
+ \r
+ return GopPrivateResetWorker (Private);\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInExReadKeyStrokeEx (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ OUT EFI_KEY_DATA *KeyData\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Reads the next keystroke from the input device. The WaitForKey Event can \r
+ be used to test for existance of a keystroke via WaitForEvent () call.\r
+\r
+ Arguments:\r
+ This - Protocol instance pointer.\r
+ KeyData - A pointer to a buffer that is filled in with the keystroke \r
+ state data for the key that was pressed.\r
+\r
+ Returns:\r
+ EFI_SUCCESS - The keystroke information was returned.\r
+ EFI_NOT_READY - There was no keystroke data availiable.\r
+ EFI_DEVICE_ERROR - The keystroke information was not returned due to \r
+ hardware errors.\r
+ EFI_INVALID_PARAMETER - KeyData is NULL. \r
+\r
+--*/\r
+{\r
+ GOP_PRIVATE_DATA *Private;\r
+\r
+ if (KeyData == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
+ \r
+ return GopPrivateReadKeyStrokeWorker (Private, KeyData);\r
+\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInExSetState (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Set certain state for the input device.\r
+\r
+ Arguments:\r
+ This - Protocol instance pointer.\r
+ KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the \r
+ state for the input device.\r
+ \r
+ Returns: \r
+ EFI_SUCCESS - The device state was set successfully.\r
+ EFI_DEVICE_ERROR - The device is not functioning correctly and could \r
+ not have the setting adjusted.\r
+ EFI_UNSUPPORTED - The device does not have the ability to set its state.\r
+ EFI_INVALID_PARAMETER - KeyToggleState is NULL. \r
+\r
+--*/ \r
+{\r
+ EFI_STATUS Status;\r
+ GOP_PRIVATE_DATA *Private;\r
+\r
+ if (KeyToggleState == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
+\r
+ if (((Private->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||\r
+ ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) {\r
+ return EFI_UNSUPPORTED; \r
+ }\r
+\r
+ Private->ScrollLock = FALSE;\r
+ Private->NumLock = FALSE;\r
+ Private->CapsLock = FALSE;\r
+\r
+ if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {\r
+ Private->ScrollLock = TRUE;\r
+ } \r
+ if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {\r
+ Private->NumLock = TRUE;\r
+ }\r
+ if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {\r
+ Private->CapsLock = TRUE;\r
+ }\r
+\r
+ Status = GopPrivateUpdateStatusLight (Private); \r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Private->KeyState.KeyToggleState = *KeyToggleState;\r
+ return EFI_SUCCESS;\r
+ \r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInExRegisterKeyNotify (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN EFI_KEY_DATA *KeyData,\r
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,\r
+ OUT EFI_HANDLE *NotifyHandle\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Register a notification function for a particular keystroke for the input device.\r
+\r
+ Arguments:\r
+ This - Protocol instance pointer.\r
+ KeyData - A pointer to a buffer that is filled in with the keystroke \r
+ information data for the key that was pressed.\r
+ KeyNotificationFunction - Points to the function to be called when the key \r
+ sequence is typed specified by KeyData. \r
+ NotifyHandle - Points to the unique handle assigned to the registered notification. \r
+\r
+ Returns:\r
+ EFI_SUCCESS - The notification function was registered successfully.\r
+ EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures.\r
+ EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL. \r
+ \r
+--*/ \r
+{\r
+ EFI_STATUS Status;\r
+ GOP_PRIVATE_DATA *Private;\r
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;\r
+ LIST_ENTRY *Link;\r
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify; \r
+\r
+ if (KeyData == NULL || NotifyHandle == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ } \r
+\r
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
+\r
+ //\r
+ // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.\r
+ //\r
+ for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
+ CurrentNotify = CR (\r
+ Link, \r
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY, \r
+ NotifyEntry, \r
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE\r
+ );\r
+ if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { \r
+ if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
+ *NotifyHandle = CurrentNotify->NotifyHandle;\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ } \r
+ \r
+ //\r
+ // Allocate resource to save the notification function\r
+ // \r
+ NewNotify = (WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) AllocateZeroPool (sizeof (WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY));\r
+ if (NewNotify == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ NewNotify->Signature = WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE; \r
+ NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
+ CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));\r
+ InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry);\r
+\r
+ //\r
+ // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE\r
+ // \r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &NewNotify->NotifyHandle,\r
+ &gSimpleTextInExNotifyGuid,\r
+ NULL,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ *NotifyHandle = NewNotify->NotifyHandle; \r
+ \r
+ return EFI_SUCCESS;\r
+ \r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInExUnregisterKeyNotify (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN EFI_HANDLE NotificationHandle\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Remove a registered notification function from a particular keystroke.\r
+\r
+ Arguments:\r
+ This - Protocol instance pointer. \r
+ NotificationHandle - The handle of the notification function being unregistered.\r
+\r
+ Returns:\r
+ EFI_SUCCESS - The notification function was unregistered successfully.\r
+ EFI_INVALID_PARAMETER - The NotificationHandle is invalid.\r
+ EFI_NOT_FOUND - Can not find the matching entry in database. \r
+ \r
+--*/ \r
+{\r
+ EFI_STATUS Status;\r
+ GOP_PRIVATE_DATA *Private;\r
+ LIST_ENTRY *Link;\r
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;\r
+\r
+ if (NotificationHandle == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ } \r
+ \r
+ Status = gBS->OpenProtocol (\r
+ NotificationHandle,\r
+ &gSimpleTextInExNotifyGuid,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
+\r
+ for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
+ CurrentNotify = CR (\r
+ Link, \r
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY, \r
+ NotifyEntry, \r
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE\r
+ ); \r
+ if (CurrentNotify->NotifyHandle == NotificationHandle) {\r
+ //\r
+ // Remove the notification function from NotifyList and free resources\r
+ //\r
+ RemoveEntryList (&CurrentNotify->NotifyEntry); \r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ CurrentNotify->NotifyHandle,\r
+ &gSimpleTextInExNotifyGuid,\r
+ NULL,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ gBS->FreePool (CurrentNotify); \r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Can not find the specified Notification Handle\r
+ //\r
+ return EFI_NOT_FOUND;\r
+}\r
\r
/**\r
TODO: Add function description\r
&Private->SimpleTextIn.WaitForKey\r
);\r
\r
+ \r
+ Private->SimpleTextInEx.Reset = WinNtGopSimpleTextInExResetEx;\r
+ Private->SimpleTextInEx.ReadKeyStrokeEx = WinNtGopSimpleTextInExReadKeyStrokeEx;\r
+ Private->SimpleTextInEx.SetState = WinNtGopSimpleTextInExSetState;\r
+ Private->SimpleTextInEx.RegisterKeyNotify = WinNtGopSimpleTextInExRegisterKeyNotify;\r
+ Private->SimpleTextInEx.UnregisterKeyNotify = WinNtGopSimpleTextInExUnregisterKeyNotify;\r
+\r
+ Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE);\r
+ \r
+ InitializeListHead (&Private->NotifyList);\r
+\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_WAIT,\r
+ TPL_NOTIFY,\r
+ WinNtGopSimpleTextInWaitForKey,\r
+ Private,\r
+ &Private->SimpleTextInEx.WaitForKeyEx\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+\r
return Status;\r
}\r
\r
\r
+\r
/**\r
TODO: Add function description\r
\r
\r
\r
**/\r
-//\r
-// The package level header files this module uses\r
-//\r
-#include <Uefi.h>\r
-#include <WinNtDxe.h>\r
-//\r
-// The protocols, PPI and GUID defintions for this module\r
-//\r
-#include <Guid/EventGroup.h>\r
-#include <Protocol/WinNtIo.h>\r
-#include <Protocol/ComponentName.h>\r
-#include <Protocol/SimpleTextIn.h>\r
-#include <Protocol/DriverBinding.h>\r
-#include <Protocol/GraphicsOutput.h>\r
-//\r
-// The Library classes this module consumes\r
-//\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
\r
#include "WinNtGop.h"\r
\r
IN VOID *Context\r
);\r
\r
+STATIC\r
+VOID\r
+WinNtGopConvertParamToEfiKeyShiftState (\r
+ IN GOP_PRIVATE_DATA *Private,\r
+ IN WPARAM *wParam,\r
+ IN BOOLEAN Flag\r
+ )\r
+{\r
+ switch (*wParam) {\r
+ //\r
+ // BUGBUG: Only GetAsyncKeyState() and GetKeyState() can distinguish\r
+ // left and right Ctrl, and Shift key. \r
+ // Neither of the two is defined in EFI_WIN_NT_THUNK_PROTOCOL. \r
+ // Therefor, we can not set the correct Shift state here.\r
+ // \r
+ case VK_SHIFT: \r
+ Private->LeftShift = Flag;\r
+ break; \r
+ case VK_CONTROL:\r
+ Private->LeftCtrl = Flag;\r
+ break;\r
+ case VK_LWIN: \r
+ Private->LeftLogo = Flag;\r
+ break;\r
+ case VK_RWIN: \r
+ Private->RightLogo = Flag;\r
+ break;\r
+ case VK_APPS: \r
+ Private->Menu = Flag;\r
+ break;\r
+ //\r
+ // BUGBUG: PrintScreen/SysRq can not trigger WM_KEYDOWN message,\r
+ // so SySReq shift state is not supported here.\r
+ //\r
+ case VK_PRINT: \r
+ Private->SysReq = Flag;\r
+ break;\r
+ }\r
+}\r
+\r
+STATIC\r
+VOID\r
+WinNtGopConvertParamToEfiKey (\r
+ IN GOP_PRIVATE_DATA *Private,\r
+ IN WPARAM *wParam,\r
+ IN EFI_INPUT_KEY *Key\r
+ )\r
+{\r
+ switch (*wParam) {\r
+ case VK_HOME: Key->ScanCode = SCAN_HOME; break;\r
+ case VK_END: Key->ScanCode = SCAN_END; break;\r
+ case VK_LEFT: Key->ScanCode = SCAN_LEFT; break;\r
+ case VK_RIGHT: Key->ScanCode = SCAN_RIGHT; break;\r
+ case VK_UP: Key->ScanCode = SCAN_UP; break;\r
+ case VK_DOWN: Key->ScanCode = SCAN_DOWN; break;\r
+ case VK_DELETE: Key->ScanCode = SCAN_DELETE; break;\r
+ case VK_INSERT: Key->ScanCode = SCAN_INSERT; break;\r
+ case VK_PRIOR: Key->ScanCode = SCAN_PAGE_UP; break;\r
+ case VK_NEXT: Key->ScanCode = SCAN_PAGE_DOWN; break;\r
+ case VK_ESCAPE: Key->ScanCode = SCAN_ESC; break;\r
+ \r
+ case VK_F1: Key->ScanCode = SCAN_F1; break;\r
+ case VK_F2: Key->ScanCode = SCAN_F2; break;\r
+ case VK_F3: Key->ScanCode = SCAN_F3; break;\r
+ case VK_F4: Key->ScanCode = SCAN_F4; break;\r
+ case VK_F5: Key->ScanCode = SCAN_F5; break;\r
+ case VK_F6: Key->ScanCode = SCAN_F6; break;\r
+ case VK_F7: Key->ScanCode = SCAN_F7; break;\r
+ case VK_F8: Key->ScanCode = SCAN_F8; break;\r
+ case VK_F9: Key->ScanCode = SCAN_F9; break;\r
+ case VK_F11: Key->ScanCode = SCAN_F11; break;\r
+ case VK_F12: Key->ScanCode = SCAN_F12; break;\r
+\r
+ case VK_F13: Key->ScanCode = SCAN_F13; break;\r
+ case VK_F14: Key->ScanCode = SCAN_F14; break;\r
+ case VK_F15: Key->ScanCode = SCAN_F15; break;\r
+ case VK_F16: Key->ScanCode = SCAN_F16; break;\r
+ case VK_F17: Key->ScanCode = SCAN_F17; break;\r
+ case VK_F18: Key->ScanCode = SCAN_F18; break;\r
+ case VK_F19: Key->ScanCode = SCAN_F19; break;\r
+ case VK_F20: Key->ScanCode = SCAN_F20; break;\r
+ case VK_F21: Key->ScanCode = SCAN_F21; break;\r
+ case VK_F22: Key->ScanCode = SCAN_F22; break;\r
+ case VK_F23: Key->ScanCode = SCAN_F23; break;\r
+ case VK_F24: Key->ScanCode = SCAN_F24; break;\r
+\r
+ //\r
+ // Set toggle state\r
+ // \r
+ case VK_NUMLOCK: \r
+ Private->NumLock = !Private->NumLock;\r
+ break;\r
+ case VK_SCROLL:\r
+ Private->ScrollLock = !Private->ScrollLock;\r
+ break; \r
+ case VK_CAPITAL:\r
+ Private->CapsLock = !Private->CapsLock;\r
+ break; \r
+ }\r
+ \r
+ WinNtGopConvertParamToEfiKeyShiftState (Private, wParam, TRUE); \r
+}\r
+\r
+\r
//\r
// GOP Protocol Member Functions\r
//\r
(*Info)->Version = 0;\r
(*Info)->HorizontalResolution = Private->ModeData[ModeNumber].HorizontalResolution;\r
(*Info)->VerticalResolution = Private->ModeData[ModeNumber].VerticalResolution;\r
- (*Info)->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;\r
+ (*Info)->PixelFormat = PixelBltOnly;\r
(*Info)->PixelsPerScanLine = (*Info)->HorizontalResolution;\r
\r
return EFI_SUCCESS;\r
\r
//\r
// F10 and the ALT key do not create a WM_KEYDOWN message, thus this special case\r
+ // WM_SYSKEYDOWN is posted when F10 is pressed or \r
+ // holds down ALT key and then presses another key.\r
//\r
case WM_SYSKEYDOWN:\r
Key.ScanCode = 0;\r
GopPrivateAddQ (Private, Key);\r
return 0;\r
}\r
- break;\r
\r
- case WM_KEYDOWN:\r
- Key.ScanCode = 0;\r
- switch (wParam) {\r
- case VK_HOME: Key.ScanCode = SCAN_HOME; break;\r
- case VK_END: Key.ScanCode = SCAN_END; break;\r
- case VK_LEFT: Key.ScanCode = SCAN_LEFT; break;\r
- case VK_RIGHT: Key.ScanCode = SCAN_RIGHT; break;\r
- case VK_UP: Key.ScanCode = SCAN_UP; break;\r
- case VK_DOWN: Key.ScanCode = SCAN_DOWN; break;\r
- case VK_DELETE: Key.ScanCode = SCAN_DELETE; break;\r
- case VK_INSERT: Key.ScanCode = SCAN_INSERT; break;\r
- case VK_PRIOR: Key.ScanCode = SCAN_PAGE_UP; break;\r
- case VK_NEXT: Key.ScanCode = SCAN_PAGE_DOWN; break;\r
- case VK_ESCAPE: Key.ScanCode = SCAN_ESC; break;\r
-\r
- case VK_F1: Key.ScanCode = SCAN_F1; break;\r
- case VK_F2: Key.ScanCode = SCAN_F2; break;\r
- case VK_F3: Key.ScanCode = SCAN_F3; break;\r
- case VK_F4: Key.ScanCode = SCAN_F4; break;\r
- case VK_F5: Key.ScanCode = SCAN_F5; break;\r
- case VK_F6: Key.ScanCode = SCAN_F6; break;\r
- case VK_F7: Key.ScanCode = SCAN_F7; break;\r
- case VK_F8: Key.ScanCode = SCAN_F8; break;\r
- case VK_F9: Key.ScanCode = SCAN_F9; break;\r
- case VK_F11: Key.ScanCode = SCAN_F11; break;\r
- case VK_F12: Key.ScanCode = SCAN_F12; break;\r
+ if ((lParam & GOP_ALT_KEY_PRESSED) == GOP_ALT_KEY_PRESSED) {\r
+ //\r
+ // ALT is pressed with another key pressed\r
+ //\r
+ WinNtGopConvertParamToEfiKey (Private, &wParam, &Key);\r
+\r
+ if ((lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {\r
+ Private->RightAlt = TRUE;\r
+ } else {\r
+ Private->LeftAlt = TRUE;\r
+ }\r
+\r
+ if (Private->RightAlt && Private->LeftAlt) {\r
+ Private->LeftAlt = FALSE;\r
+ }\r
+ }\r
+\r
+ if (Key.ScanCode != 0) {\r
+ Key.UnicodeChar = 0;\r
+ GopPrivateAddQ (Private, Key);\r
+ }\r
+\r
+ return 0;\r
+\r
+ case WM_SYSKEYUP:\r
+ if ((lParam & GOP_ALT_KEY_PRESSED) == GOP_ALT_KEY_PRESSED) {\r
+ //\r
+ // ALT is pressed with another key released\r
+ //\r
+ WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, FALSE); \r
+ //\r
+ // Actually ALT key is still held down here.\r
+ // Change the ALT key state when another key is released\r
+ // by user because we did not find a better solution to\r
+ // get a released ALT key. \r
+ //\r
+ Private->RightAlt = FALSE;\r
+ Private->LeftAlt = FALSE;\r
}\r
\r
+ return 0;\r
+\r
+\r
+ case WM_KEYDOWN:\r
+ Key.ScanCode = 0;\r
+ WinNtGopConvertParamToEfiKey (Private, &wParam, &Key);\r
if (Key.ScanCode != 0) {\r
Key.UnicodeChar = 0;\r
GopPrivateAddQ (Private, Key);\r
\r
return 0;\r
\r
+ case WM_KEYUP:\r
+ WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, FALSE); \r
+ return 0;\r
+\r
case WM_CHAR:\r
//\r
// The ESC key also generate WM_CHAR.\r