/** @file\r
\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
Module Name:\r
\r
Abstract:\r
\r
This file produces the graphics abstration of GOP. It is called by\r
- WinNtGopDriver.c file which deals with the EFI 1.1 driver model.\r
+ WinNtGopDriver.c file which deals with the UEFI 2.0 driver model.\r
This file just does graphics.\r
\r
\r
EFI_WIN_NT_THUNK_PROTOCOL *mWinNt;\r
DWORD mTlsIndex = TLS_OUT_OF_INDEXES;\r
DWORD mTlsIndexUseCount = 0; // lets us know when we can free mTlsIndex.\r
-static EFI_EVENT mGopScreenExitBootServicesEvent;\r
+EFI_EVENT mGopScreenExitBootServicesEvent;\r
GOP_MODE_DATA mGopModeData[] = {\r
{800, 600, 0, 0},\r
{640, 480, 0, 0},\r
IN UINT32 RefreshRate\r
);\r
\r
-STATIC\r
VOID\r
EFIAPI\r
KillNtGopThread (\r
IN VOID *Context\r
);\r
\r
-STATIC\r
-VOID\r
+BOOLEAN\r
WinNtGopConvertParamToEfiKeyShiftState (\r
IN GOP_PRIVATE_DATA *Private,\r
IN WPARAM *wParam,\r
+ IN LPARAM *lParam,\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
+ // 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
+ //\r
+ case VK_SHIFT:\r
+ if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {\r
+ Private->RightShift = Flag;\r
+ } else {\r
+ Private->LeftShift = Flag;\r
+ }\r
+ return TRUE;\r
+\r
+ case VK_LSHIFT:\r
+ Private->LeftShift = Flag;\r
+ return TRUE;\r
+\r
+ case VK_RSHIFT:\r
+ Private->RightShift = Flag;\r
+ return TRUE;\r
+\r
case VK_CONTROL:\r
- Private->LeftCtrl = Flag;\r
- break;\r
- case VK_LWIN: \r
+ if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {\r
+ Private->RightCtrl= Flag;\r
+ } else {\r
+ Private->LeftCtrl = Flag;\r
+ }\r
+ return TRUE;\r
+\r
+ case VK_LCONTROL:\r
+ Private->LeftCtrl = Flag;\r
+ return TRUE;\r
+\r
+ case VK_RCONTROL:\r
+ Private->RightCtrl = Flag;\r
+ return TRUE;\r
+\r
+ case VK_LWIN:\r
Private->LeftLogo = Flag;\r
- break;\r
- case VK_RWIN: \r
+ return TRUE;\r
+\r
+ case VK_RWIN:\r
Private->RightLogo = Flag;\r
- break;\r
- case VK_APPS: \r
+ return TRUE;\r
+\r
+ case VK_APPS:\r
Private->Menu = Flag;\r
- break;\r
+ return TRUE;\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
+ case VK_PRINT:\r
Private->SysReq = Flag;\r
- break;\r
+ return TRUE;\r
+ //\r
+ // For Alt Keystroke.\r
+ //\r
+ case VK_MENU:\r
+ if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {\r
+ Private->RightAlt = Flag;\r
+ } else {\r
+ Private->LeftAlt = Flag;\r
+ }\r
+ return TRUE;\r
+\r
+ default:\r
+ return FALSE;\r
}\r
}\r
\r
-STATIC\r
-VOID\r
+BOOLEAN\r
WinNtGopConvertParamToEfiKey (\r
IN GOP_PRIVATE_DATA *Private,\r
IN WPARAM *wParam,\r
+ IN LPARAM *lParam,\r
IN EFI_INPUT_KEY *Key\r
)\r
{\r
+ BOOLEAN Flag;\r
+ Flag = FALSE;\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
+ case VK_HOME: Key->ScanCode = SCAN_HOME; Flag = TRUE; break;\r
+ case VK_END: Key->ScanCode = SCAN_END; Flag = TRUE; break;\r
+ case VK_LEFT: Key->ScanCode = SCAN_LEFT; Flag = TRUE; break;\r
+ case VK_RIGHT: Key->ScanCode = SCAN_RIGHT; Flag = TRUE; break;\r
+ case VK_UP: Key->ScanCode = SCAN_UP; Flag = TRUE; break;\r
+ case VK_DOWN: Key->ScanCode = SCAN_DOWN; Flag = TRUE; break;\r
+ case VK_DELETE: Key->ScanCode = SCAN_DELETE; Flag = TRUE; break;\r
+ case VK_INSERT: Key->ScanCode = SCAN_INSERT; Flag = TRUE; break;\r
+ case VK_PRIOR: Key->ScanCode = SCAN_PAGE_UP; Flag = TRUE; break;\r
+ case VK_NEXT: Key->ScanCode = SCAN_PAGE_DOWN; Flag = TRUE; break;\r
+ case VK_ESCAPE: Key->ScanCode = SCAN_ESC; Flag = TRUE; break;\r
+\r
+ case VK_F1: Key->ScanCode = SCAN_F1; Flag = TRUE; break;\r
+ case VK_F2: Key->ScanCode = SCAN_F2; Flag = TRUE; break;\r
+ case VK_F3: Key->ScanCode = SCAN_F3; Flag = TRUE; break;\r
+ case VK_F4: Key->ScanCode = SCAN_F4; Flag = TRUE; break;\r
+ case VK_F5: Key->ScanCode = SCAN_F5; Flag = TRUE; break;\r
+ case VK_F6: Key->ScanCode = SCAN_F6; Flag = TRUE; break;\r
+ case VK_F7: Key->ScanCode = SCAN_F7; Flag = TRUE; break;\r
+ case VK_F8: Key->ScanCode = SCAN_F8; Flag = TRUE; break;\r
+ case VK_F9: Key->ScanCode = SCAN_F9; Flag = TRUE; break;\r
+ case VK_F11: Key->ScanCode = SCAN_F11; Flag = TRUE; break;\r
+ case VK_F12: Key->ScanCode = SCAN_F12; Flag = TRUE; break;\r
+\r
+ case VK_F13: Key->ScanCode = SCAN_F13; Flag = TRUE; break;\r
+ case VK_F14: Key->ScanCode = SCAN_F14; Flag = TRUE; break;\r
+ case VK_F15: Key->ScanCode = SCAN_F15; Flag = TRUE; break;\r
+ case VK_F16: Key->ScanCode = SCAN_F16; Flag = TRUE; break;\r
+ case VK_F17: Key->ScanCode = SCAN_F17; Flag = TRUE; break;\r
+ case VK_F18: Key->ScanCode = SCAN_F18; Flag = TRUE; break;\r
+ case VK_F19: Key->ScanCode = SCAN_F19; Flag = TRUE; break;\r
+ case VK_F20: Key->ScanCode = SCAN_F20; Flag = TRUE; break;\r
+ case VK_F21: Key->ScanCode = SCAN_F21; Flag = TRUE; break;\r
+ case VK_F22: Key->ScanCode = SCAN_F22; Flag = TRUE; break;\r
+ case VK_F23: Key->ScanCode = SCAN_F23; Flag = TRUE; break;\r
+ case VK_F24: Key->ScanCode = SCAN_F24; Flag = TRUE; break;\r
+ case VK_PAUSE: Key->ScanCode = SCAN_PAUSE; Flag = TRUE; break;\r
\r
//\r
// Set toggle state\r
- // \r
- case VK_NUMLOCK: \r
- Private->NumLock = !Private->NumLock;\r
+ //\r
+ case VK_NUMLOCK:\r
+ Private->NumLock = (BOOLEAN)(!Private->NumLock);\r
+ Flag = TRUE;\r
break;\r
case VK_SCROLL:\r
- Private->ScrollLock = !Private->ScrollLock;\r
- break; \r
+ Private->ScrollLock = (BOOLEAN)(!Private->ScrollLock);\r
+ Flag = TRUE;\r
+ break;\r
case VK_CAPITAL:\r
- Private->CapsLock = !Private->CapsLock;\r
- break; \r
+ Private->CapsLock = (BOOLEAN)(!Private->CapsLock);\r
+ Flag = TRUE;\r
+ break;\r
}\r
\r
- WinNtGopConvertParamToEfiKeyShiftState (Private, wParam, TRUE); \r
+ return (WinNtGopConvertParamToEfiKeyShiftState (Private, wParam, lParam, TRUE)) == TRUE ? TRUE : Flag;\r
}\r
\r
\r
return EFI_UNSUPPORTED;\r
}\r
\r
- if (ModeNumber == This->Mode->Mode) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
ModeData = &Private->ModeData[ModeNumber];\r
This->Mode->Mode = ModeNumber;\r
Private->GraphicsOutput.Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;\r
//\r
// Adjust the window size\r
//\r
- Private->WinNtThunk->MoveWindow (Private->WindowHandle, Rect.left, Rect.top, Width, Height, TRUE);\r
+ Private->WinNtThunk->MoveWindow (Private->WindowHandle, Rect.left, Rect.top, (INT32)Width, (INT32)Height, TRUE);\r
\r
}\r
\r
//\r
// Mark the area we just blted as Invalid so WM_PAINT will update.\r
//\r
- Rect.left = DestinationX;\r
- Rect.top = DestinationY;\r
- Rect.right = DestinationX + Width;\r
- Rect.bottom = DestinationY + Height;\r
+ Rect.left = (LONG)DestinationX;\r
+ Rect.top = (LONG)DestinationY;\r
+ Rect.right = (LONG)(DestinationX + Width);\r
+ Rect.bottom = (LONG)(DestinationY + Height);\r
Private->WinNtThunk->InvalidateRect (Private->WindowHandle, &Rect, FALSE);\r
\r
//\r
PAINTSTRUCT PaintStruct;\r
LPARAM Index;\r
EFI_INPUT_KEY Key;\r
+ BOOLEAN AltIsPress;\r
\r
//\r
// BugBug - if there are two instances of this DLL in memory (such as is\r
// This works since each Gop protocol has a unique Private data instance and\r
// a unique thread.\r
//\r
+ AltIsPress = FALSE;\r
Private = mWinNt->TlsGetValue (mTlsIndex);\r
ASSERT (NULL != Private);\r
\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
+ // 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
+\r
+ Key.ScanCode = 0;\r
+ Key.UnicodeChar = CHAR_NULL;\r
switch (wParam) {\r
case VK_F10:\r
Key.ScanCode = SCAN_F10;\r
- Key.UnicodeChar = 0;\r
- GopPrivateAddQ (Private, Key);\r
+ Key.UnicodeChar = CHAR_NULL;\r
+ GopPrivateAddKey (Private, Key);\r
return 0;\r
}\r
\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
+ //\r
+ // If ALT or ALT + modifier key is pressed.\r
+ //\r
+ if (WinNtGopConvertParamToEfiKey (Private, &wParam, &lParam, &Key)) {\r
+ if (Key.ScanCode != 0){\r
+ //\r
+ // If ALT is pressed with other ScanCode.\r
+ // Always revers the left Alt for simple.\r
+ //\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
+ GopPrivateAddKey (Private, Key);\r
+ //\r
+ // When Alt is released there is no windoes message, so \r
+ // clean it after using it.\r
+ //\r
+ Private->RightAlt = FALSE;\r
+ Private->LeftAlt = FALSE;\r
+ return 0;\r
}\r
+ AltIsPress = TRUE;\r
\r
- return 0;\r
+ case WM_CHAR: \r
+ //\r
+ // The ESC key also generate WM_CHAR.\r
+ //\r
+ if (wParam == 0x1B) {\r
+ return 0;\r
+ } \r
\r
- case WM_SYSKEYUP:\r
- if ((lParam & GOP_ALT_KEY_PRESSED) == GOP_ALT_KEY_PRESSED) {\r
+ if (AltIsPress == TRUE) {\r
//\r
- // ALT is pressed with another key released\r
+ // If AltIsPress is true that means the Alt key is pressed.\r
//\r
- WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, FALSE); \r
+ Private->LeftAlt = TRUE;\r
+ }\r
+ for (Index = 0; Index < (lParam & 0xffff); Index++) {\r
+ if (wParam != 0) {\r
+ Key.UnicodeChar = (CHAR16) wParam;\r
+ Key.ScanCode = SCAN_NULL; \r
+ GopPrivateAddKey (Private, Key); \r
+ }\r
+ }\r
+ if (AltIsPress == TRUE) {\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
+ // When Alt is released there is no windoes message, so \r
+ // clean it after using it.\r
//\r
+ Private->LeftAlt = FALSE;\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
-\r
- return 0;\r
-\r
- case WM_KEYUP:\r
- WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, FALSE); \r
+ case WM_SYSKEYUP:\r
+ //\r
+ // ALT is pressed with another key released\r
+ //\r
+ WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, &lParam, FALSE);\r
return 0;\r
\r
- case WM_CHAR:\r
+ case WM_KEYDOWN:\r
+ Key.ScanCode = SCAN_NULL;\r
+ Key.UnicodeChar = CHAR_NULL;\r
//\r
- // The ESC key also generate WM_CHAR.\r
+ // A value key press will cause a WM_KEYDOWN first, then cause a WM_CHAR\r
+ // So if there is no modifier key updated, skip the WM_KEYDOWN even.\r
//\r
- if (wParam == 0x1B) {\r
- return 0;\r
- }\r
-\r
- for (Index = 0; Index < (lParam & 0xffff); Index++) {\r
- if (wParam != 0) {\r
- Key.UnicodeChar = (CHAR16) wParam;\r
- Key.ScanCode = 0;\r
- GopPrivateAddQ (Private, Key);\r
- }\r
+ if (WinNtGopConvertParamToEfiKey (Private, &wParam, &lParam, &Key)) {\r
+ //\r
+ // Support the partial keystroke, add all keydown event into the queue.\r
+ //\r
+ GopPrivateAddKey (Private, Key);\r
}\r
+ return 0;\r
\r
+ case WM_KEYUP:\r
+ WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, &lParam, FALSE);\r
return 0;\r
\r
case WM_CLOSE:\r
{\r
MSG Message;\r
GOP_PRIVATE_DATA *Private;\r
- ATOM Atom;\r
RECT Rect;\r
\r
Private = (GOP_PRIVATE_DATA *) lpParameter;\r
Private->WindowsClass.hInstance = NULL;\r
Private->WindowsClass.hIcon = Private->WinNtThunk->LoadIcon (NULL, IDI_APPLICATION);\r
Private->WindowsClass.hCursor = Private->WinNtThunk->LoadCursor (NULL, IDC_ARROW);\r
- Private->WindowsClass.hbrBackground = (HBRUSH) COLOR_WINDOW;\r
+ Private->WindowsClass.hbrBackground = (HBRUSH)(UINTN)COLOR_WINDOW;\r
Private->WindowsClass.lpszMenuName = NULL;\r
Private->WindowsClass.lpszClassName = WIN_NT_GOP_CLASS_NAME;\r
Private->WindowsClass.hIconSm = Private->WinNtThunk->LoadIcon (NULL, IDI_APPLICATION);\r
// Class, including the callback function, unless the Class is unregistered and\r
// successfully registered again.\r
//\r
- Atom = Private->WinNtThunk->RegisterClassEx (&Private->WindowsClass);\r
+ Private->WinNtThunk->RegisterClassEx (&Private->WindowsClass);\r
\r
//\r
// Setting Rect values to allow for the AdjustWindowRect to provide\r
NULL,\r
NULL,\r
NULL,\r
- &Private\r
+ (VOID **)&Private\r
);\r
\r
//\r
Private->WinNtThunk->DispatchMessage (&Message);\r
}\r
\r
- return Message.wParam;\r
+ return (DWORD)Message.wParam;\r
}\r
\r
\r
//\r
// Register to be notified on exit boot services so we can destroy the window.\r
//\r
- Status = gBS->CreateEvent (\r
- EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
TPL_CALLBACK,\r
KillNtGopThread,\r
Private,\r
+ &gEfiEventExitBootServicesGuid,\r
&mGopScreenExitBootServicesEvent\r
);\r
\r
Private->GraphicsOutput.Mode->Info->VerticalResolution = 0;\r
Private->GraphicsOutput.Mode->Info->PixelFormat = PixelBltOnly;\r
Private->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
- Private->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;\r
+ Private->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;\r
Private->GraphicsOutput.Mode->FrameBufferSize = 0;\r
\r
Private->HardwareNeedsStarting = TRUE;\r
GOP_PRIVATE_DATA *Private\r
)\r
{\r
- UINT32 UnregisterReturn;\r
-\r
if (!Private->HardwareNeedsStarting) {\r
//\r
// BugBug: Shutdown GOP Hardware and any child devices.\r
Private->WinNtThunk->TlsFree (mTlsIndex);\r
mTlsIndex = TLS_OUT_OF_INDEXES;\r
\r
- UnregisterReturn = Private->WinNtThunk->UnregisterClass (\r
- Private->WindowsClass.lpszClassName,\r
- Private->WindowsClass.hInstance\r
- );\r
+ Private->WinNtThunk->UnregisterClass (\r
+ Private->WindowsClass.lpszClassName,\r
+ Private->WindowsClass.hInstance\r
+ );\r
}\r
\r
WinNtGopDestroySimpleTextInForWindow (Private);\r
@return None.\r
\r
**/\r
-STATIC\r
VOID\r
EFIAPI\r
KillNtGopThread (\r
IN VOID *Context\r
)\r
{\r
- EFI_STATUS Status;\r
- Status = WinNtGopDestructor (Context);\r
+ WinNtGopDestructor (Context);\r
}\r