alder_lake_bios/Insyde/InsydeSetupPkg/Drivers/H2ODisplayEngineLocalMetroDxe/H2ODisplayEngineLocalMetro.c

851 lines
25 KiB
C

/** @file
Entry point and initial functions for H2O local Metro display engine driver
;******************************************************************************
;* Copyright (c) 2013 - 2021, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include <H2ODisplayEngineLocalMetro.h>
#include <Library/HiiDbLib.h>
#include <Library/HiiStringLib.h>
#include <Library/HiiConfigAccessLib.h>
#include <Library/Win32Lib.h>
#include <Library/TimerLib.h>
#include "MetroUi.h"
#include "MetroPerfMeasure.h"
#include "UiControls.h"
BOOLEAN mIsInNotifyProcess;
H2O_DISPLAY_ENGINE_METRO_PRIVATE_DATA *mMetroPrivate = NULL;
H2O_FORM_BROWSER_PROTOCOL *gFB = NULL;
extern H2O_WINDOW_PROTOCOL *gH2OWindow;
EFI_ABSOLUTE_POINTER_STATE mPreviousAbsPtrState;
extern HWND mDialogWnd;
HWND gWnd = NULL;
HWND gLastFocus = NULL;
#define SHOW_NONE 0x00000000
#define SHOW_REFRESH_DE_FPS 0x00000001
#define SHOW_GOP_BLT_FPS 0x00000002
#define SHOW_TIMER_FPS 0x00000004
UINT32 mShowFps = SHOW_NONE;
/**
Add new console to the console list.
@param [in] This A pointer to the H2O_DISPLAY_ENGINE_PROTOCOL instance.
@param [in] ConsoleHandle A pointer to the input console handle instance.
@retval EFI_SUCCESS Add new console to console list successful.
@retval EFI_INVALID_PARAMETER This is NULL, or ConsoleDev is NULL.
**/
EFI_STATUS
EFIAPI
LocalMetroInitConsole (
IN H2O_DISPLAY_ENGINE_PROTOCOL *This,
IN H2O_FORM_BROWSER_CONSOLE_DEV *ConsoleDev
)
{
if (This == NULL || ConsoleDev == NULL) {
return EFI_INVALID_PARAMETER;
}
return EFI_SUCCESS;
}
/**
Set GOP to assigned horizontal and vertical
@param [in] Gop A pointer to the EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
@param [in] HorizontalResolution Horizontal resolution
@param [in] VerticalResolution Vertical resolution
@retval EFI_SUCCESS Find assigned resolution and then set it.
@retval EFI_NOT_FOUND Can't find assigned resolution
**/
EFI_STATUS
SetGopResolution (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,
IN UINT32 HorizontalResolution,
IN UINT32 VerticalResolution
)
{
EFI_STATUS Status;
UINT32 Mode;
UINTN SizeOfInfo;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
Status = EFI_NOT_FOUND;
for (Mode = 0; Mode < GraphicsOutput->Mode->MaxMode; Mode++) {
Info = NULL;
Status = GraphicsOutput->QueryMode (GraphicsOutput, Mode, &SizeOfInfo, &Info);
if (EFI_ERROR (Status)) {
continue;
}
if ((Info->HorizontalResolution == HorizontalResolution) &&
(Info->VerticalResolution == VerticalResolution)) {
FreePool (Info);
if (GraphicsOutput->Mode->Mode != Mode) {
Status = GraphicsOutput->SetMode (GraphicsOutput, Mode);
if (EFI_ERROR (Status)) {
return Status;
}
}
return EFI_SUCCESS;
}
FreePool (Info);
}
return EFI_NOT_FOUND;
}
/**
Set simple text out to assigned column and row.
@param[in] SimpleTextOut A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL instance.
@param[in] TargetColumn Target column
@param[in] TargetRow Target row
@retval EFI_SUCCESS Set simple text out successfully.
@retval EFI_NOT_FOUND Can't find target column and row.
**/
EFI_STATUS
SetTextOutResolution (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut,
IN UINT32 TargetColumn,
IN UINT32 TargetRow
)
{
EFI_STATUS Status;
INT32 Mode;
UINTN Columns;
UINTN Rows;
for (Mode = 0; Mode < SimpleTextOut->Mode->MaxMode; Mode++) {
Status = SimpleTextOut->QueryMode (SimpleTextOut, Mode, &Columns, &Rows);
if (!EFI_ERROR (Status) && Columns == TargetColumn && Rows == TargetRow) {
return SimpleTextOut->SetMode (SimpleTextOut, Mode);
}
}
return EFI_NOT_FOUND;
}
/**
Attach a specific console to this display engine.
@param [in] This A pointer to the H2O_DISPLAY_ENGINE_PROTOCOL instance.
@param [in] ConsoleDev A pointer to input H2O_FORM_BROWSER_CONSOLE_DEV instance.
@retval EFI_SUCCESS Attach new console successful.
@retval EFI_INVALID_PARAMETER This is NULL, or ConsoleDev is NULL.
@retval EFI_UNSUPPORTED This display engine doesn't support input console device.
**/
EFI_STATUS
EFIAPI
LocalMetroAttachConsole (
IN H2O_DISPLAY_ENGINE_PROTOCOL *This,
IN H2O_FORM_BROWSER_CONSOLE_DEV *ConsoleDev
)
{
H2O_DISPLAY_ENGINE_METRO_PRIVATE_DATA *Private;
H2O_FORM_BROWSER_CONSOLE_DEV_NODE *ConDevNode;
EFI_STATUS Status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOut;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
UINT32 HorizontalResolution;
UINT32 VerticalResolution;
if (This == NULL || ConsoleDev == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = gBS->HandleProtocol (
ConsoleDev->Handle,
&gEfiGraphicsOutputProtocolGuid,
(VOID **) &GraphicsOut
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->HandleProtocol (
ConsoleDev->Handle,
&gEfiSimpleTextOutProtocolGuid,
(VOID **) &SimpleTextOut
);
if (EFI_ERROR (Status)) {
SimpleTextOut = NULL;
}
GetDisplayEngineResolutionByPcd (&This->Id, &HorizontalResolution, &VerticalResolution);
Status = SetGopResolution (GraphicsOut, HorizontalResolution, VerticalResolution);
if (EFI_ERROR (Status)) {
Status = SetGopResolution (
GraphicsOut,
PcdGet32 (PcdDefaultHorizontalResolution),
PcdGet32 (PcdDefaultVerticalResolution)
);
}
if (EFI_ERROR (Status)) {
Status = GraphicsOut->SetMode (GraphicsOut, 0);
if (EFI_ERROR (Status)) {
return Status;
}
}
if (SimpleTextOut != NULL) {
SetTextOutResolution (
SimpleTextOut,
GraphicsOut->Mode->Info->HorizontalResolution / EFI_GLYPH_WIDTH,
GraphicsOut->Mode->Info->VerticalResolution / EFI_GLYPH_HEIGHT
);
}
Private = H2O_DISPLAY_ENGINE_METRO_PRIVATE_DATA_FROM_PROTOCOL (This);
ConDevNode = (H2O_FORM_BROWSER_CONSOLE_DEV_NODE*) AllocatePool (sizeof (H2O_FORM_BROWSER_CONSOLE_DEV_NODE));
if (ConDevNode == NULL) {
return EFI_UNSUPPORTED;
}
ConDevNode->Signature = H2O_FORM_BROWSER_CONSOLE_DEV_NODE_SIGNATURE;
ConDevNode->ConsoleDev = AllocateCopyPool (sizeof (H2O_FORM_BROWSER_CONSOLE_DEV), ConsoleDev);
ConDevNode->Handle = ConsoleDev->Handle;
ConDevNode->GraphicsOut = GraphicsOut;
ConDevNode->SimpleTextOut = SimpleTextOut;
//
// Initialize GUI
//
if (IsListEmpty (&Private->ConsoleDevListHead) && mDialogWnd == NULL) {
Status = InitializeGUI (GraphicsOut);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
} else {
GdAddGopDevice (GraphicsOut);
}
InsertTailList (&Private->ConsoleDevListHead, &ConDevNode->Link);
return EFI_SUCCESS;
}
/**
Detach a specific console from this display engine.
@param [in] This A pointer to the H2O_DISPLAY_ENGINE_PROTOCOL instance.
@param [in] ConsoleDev A pointer to input H2O_FORM_BROWSER_CONSOLE_DEV instance.
@retval EFI_SUCCESS Detach a console device from the device engine successful.
@retval EFI_INVALID_PARAMETER This is NULL, or ConsoleDev is NULL.
@retval EFI_NOT_FOUND The input device console USN't attached to the display engine.
**/
EFI_STATUS
EFIAPI
LocalMetroDetachConsole (
IN H2O_DISPLAY_ENGINE_PROTOCOL *This,
IN H2O_FORM_BROWSER_CONSOLE_DEV *ConsoleDev
)
{
EFI_STATUS Status;
H2O_DISPLAY_ENGINE_METRO_PRIVATE_DATA *Private;
H2O_FORM_BROWSER_CONSOLE_DEV_NODE *ConDevNode;
LIST_ENTRY *Link;
if (This == NULL || ConsoleDev == NULL) {
return EFI_INVALID_PARAMETER;
}
Private = H2O_DISPLAY_ENGINE_METRO_PRIVATE_DATA_FROM_PROTOCOL (This);
if (IsListEmpty (&Private->ConsoleDevListHead)) {
return EFI_NOT_FOUND;
}
//
// If call this function during processing notify function, replace fake protocol on this console device.
// It can make sure that interrupted notify function can be executed successfully.
// After interrupted notify function is finished, remove the console device.
//
if (mIsInNotifyProcess) {
// Status = DEReplaceFakeConOutDev (Private, ConsoleDev->Handle);
// return Status;
}
Status = EFI_NOT_FOUND;
Link = Private->ConsoleDevListHead.ForwardLink;
while (TRUE) {
ConDevNode = H2O_FORM_BROWSER_CONSOLE_DEV_NODE_FROM_LINK (Link);
if (ConsoleDev->Handle == ConDevNode->ConsoleDev->Handle) {
//
// Remove Console Device Node
//
GdRemoveGopDevice (ConDevNode->GraphicsOut);
RemoveEntryList (&ConDevNode->Link);
FreePool (ConDevNode->ConsoleDev);
FreePool (ConDevNode);
Status = EFI_SUCCESS;
break;
}
//
// Get Next Console
//
if (IsNodeAtEnd (&Private->ConsoleDevListHead, Link)) {
break;
}
Link = Link->ForwardLink;
}
if (IsListEmpty (&Private->ConsoleDevListHead) && mDialogWnd == NULL) {
ShutdownGUI();
}
return Status;
}
EFI_STATUS
LocalMetroGraphicsOutBlt (
IN H2O_DISPLAY_ENGINE_METRO_PRIVATE_DATA *Private,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,
IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
IN UINTN SourceX,
IN UINTN SourceY,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height,
IN UINTN Delta OPTIONAL
)
{
EFI_STATUS Status;
H2O_FORM_BROWSER_CONSOLE_DEV_NODE *ConDevNode;
LIST_ENTRY *Link;
Link = Private->ConsoleDevListHead.ForwardLink;
if (IsNull (&Private->ConsoleDevListHead, Link)) {
return EFI_NOT_FOUND;
}
while (TRUE) {
ConDevNode = H2O_FORM_BROWSER_CONSOLE_DEV_NODE_FROM_LINK (Link);
Status = ConDevNode->GraphicsOut->Blt (
ConDevNode->GraphicsOut,
BltBuffer,
BltOperation,
SourceX,
SourceY,
DestinationX,
DestinationY,
Width,
Height,
Delta
);
if (EFI_ERROR (Status)) {
return Status;
}
if (IsNodeAtEnd (&Private->ConsoleDevListHead, Link)) {
break;
}
Link = Link->ForwardLink;
};
return EFI_SUCCESS;
}
VOID
ShowFps (
HWND Wnd
)
{
STATIC HDC MemHdc = NULL;
STATIC HDC Hdc = NULL;
HDC DefaultHdc;
STATIC UINT64 Frames = 1;
STATIC UINT64 LastTime = 0;
STATIC UINT64 Fps = 0;
STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Pixel = NULL;
STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Pixel2 = NULL;
UINT64 OneSecond;
UINT64 NanoSecond;
CHAR16 Str[200];
RECT Rc;
UINT32 Y;
METRO_PERFORMANCE_MEASURE *PerfMeasure;
if (!mShowFps) {
return ;
}
OneSecond = 1000000000; // nanosecond
if (MemHdc == NULL) {
Pixel = AllocateZeroPool (1024 * 768 * 4);
if (Pixel == NULL) {
return;
}
Pixel2 = AllocateZeroPool (1024 * 768 * 4);
if (Pixel2 == NULL) {
return;
}
DefaultHdc = GetDC(NULL);
if (DefaultHdc == NULL) {
return;
}
MemHdc = CreateCompatibleDC(DefaultHdc);
ASSERT (MemHdc != NULL);
if (MemHdc == NULL) {
ReleaseDC (NULL, DefaultHdc);
return;
}
mDummyBitmap = CreateCompatibleBitmap(MemHdc, 300, 20);
SelectObject(MemHdc, mDummyBitmap);
SetRect (&Rc, 0, 0, GetDeviceCaps (MemHdc, HORZRES), GetDeviceCaps (MemHdc, VERTRES));
MwFastFillRect (MemHdc, &Rc, RGB(255,255,255));
ReleaseDC (NULL, DefaultHdc);
}
NanoSecond = GetTimeInNanoSecond(GetPerformanceCounter());
Frames++;
if ((NanoSecond - LastTime) > OneSecond) {
Fps = Frames;
Frames = 0;
LastTime = NanoSecond;
DEBUG ((EFI_D_INFO, "%020ld, %04ld fps\n", NanoSecond, Fps));
PerfMeasure = GetPerfMeasure ();
if (PerfMeasure != NULL) {
PerfMeasure->IsPrintEnable = TRUE;
PerfMeasure->End (2, TRUE, L"FPS", L"\n");
PerfMeasure->Start (2, TRUE);
PerfMeasure->IsPrintEnable = FALSE;
}
MemHdc->font->FontSize = 19;
UnicodeSPrint (Str, sizeof (Str), L"%020ld, %04ld fps", NanoSecond, Fps);
SetRect (&Rc, 0, 0, GetDeviceCaps (MemHdc, HORZRES), GetDeviceCaps (MemHdc, VERTRES));
MwFastFillRect (MemHdc, &Rc, RGB(255,255,255));
TextOut (MemHdc, 0, 0, Str, -1);
if (mShowFps & SHOW_GOP_BLT_FPS) {
for (Y = 0; Y < (UINT32)GetDeviceCaps (MemHdc, VERTRES); Y++) {
CopyMem (Pixel + Y * 1024, MemHdc->psd->addr + Y * GetDeviceCaps (MemHdc, HORZRES) * 4, GetDeviceCaps (MemHdc, HORZRES) * 4);
}
}
if (mShowFps == SHOW_TIMER_FPS) {
Hdc = GetDC(Wnd);
ASSERT (Hdc != NULL);
if (Hdc == NULL) {
return;
}
BitBlt(Hdc, 0, 0, GetDeviceCaps (MemHdc, HORZRES), GetDeviceCaps (MemHdc, VERTRES), MemHdc, 0, 0, MWROP_SRC);
ReleaseDC (Wnd, Hdc);
return ;
}
}
switch (mShowFps) {
case SHOW_GOP_BLT_FPS:
CopyMem (Pixel2, Pixel, 1024 * 768 * 4);
LocalMetroGraphicsOutBlt (
mMetroPrivate,
Pixel2,
EfiBltBufferToVideo,
0,
0,
0,
0,
1024,
768,
0
);
break;
case SHOW_REFRESH_DE_FPS:
CONTROL_CLASS_INVALIDATE (GetUiControl (Wnd));
Hdc = GetDC(Wnd);
if (Hdc != NULL) {
BitBlt(Hdc, 0, 0, GetDeviceCaps (MemHdc, HORZRES), GetDeviceCaps (MemHdc, VERTRES), MemHdc, 0, 0, MWROP_SRC);
ReleaseDC (Wnd, Hdc);
}
break;
case SHOW_TIMER_FPS:
// do nothing
break;
default:
ASSERT (FALSE);
}
}
/**
Report which console devices are supported by this display engine.
@param [in] This A pointer to the H2O_DISPLAY_ENGINE_PROTOCOL instance.
@param [in] ConsoleDev A pointer to input H2O_FORM_BROWSER_CONSOLE_DEV instance.
@retval EFI_SUCCESS Report supported console device type successful.
@retval EFI_UNSUPPORTED This display engine doesn't support input console device.
@retval EFI_INVALID_PARAMETER This is NULL or ConsoleDev is NULL.
**/
EFI_STATUS
EFIAPI
LocalMetroSupportConsole (
IN H2O_DISPLAY_ENGINE_PROTOCOL *This,
IN H2O_FORM_BROWSER_CONSOLE_DEV *ConsoleDev
)
{
EFI_STATUS Status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *ConOut;
if (This == NULL || ConsoleDev == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Check Device Path is matched Local Graphics
//
Status = gBS->HandleProtocol (
ConsoleDev->Handle,
&gEfiGraphicsOutputProtocolGuid,
(VOID **) &ConOut
);
if (!EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
return EFI_UNSUPPORTED;
}
EFI_STATUS
SelectNextSetupMenu (
BOOLEAN NextSetupMEnu
)
{
H2O_PAGE_ID CurrentPageId;
H2O_PAGE_ID NextPageId;
EFI_STATUS Status;
H2O_FORM_BROWSER_SM *SetupMenuData;
UINT32 Index;
UINT32 HiiIndex;
if (gFB == NULL || gFB->CurrentP == NULL) {
return EFI_INVALID_PARAMETER;
}
CurrentPageId = gFB->CurrentP->PageId;
HiiIndex = CurrentPageId >> 16;
Status = gFB->GetSMInfo (gFB, &SetupMenuData);
if (EFI_ERROR(Status)) {
return EFI_NOT_FOUND;
}
for (Index = 0; Index < SetupMenuData->NumberOfSetupMenus; Index++) {
if ((SetupMenuData->SetupMenuInfoList[Index].PageId >> 16) == HiiIndex) {
break;
}
}
if (NextSetupMEnu) {
if (Index >= (SetupMenuData->NumberOfSetupMenus - 1)) {
NextPageId = SetupMenuData->SetupMenuInfoList[0].PageId;
} else {
NextPageId = SetupMenuData->SetupMenuInfoList[Index + 1].PageId;
}
} else {
if (Index == 0) {
NextPageId = SetupMenuData->SetupMenuInfoList[SetupMenuData->NumberOfSetupMenus - 1].PageId;
} else {
NextPageId = SetupMenuData->SetupMenuInfoList[Index - 1].PageId;
}
}
FreeSetupMenuData (SetupMenuData);
SendSelectPNotify (NextPageId);
return EFI_SUCCESS;
}
extern BOOLEAN mShowSetPositionDbg;
/**
Add the notification to the notification queue and signal the Notification event.
@param [in] This A pointer to the H2O_DISPLAY_ENGINE_PROTOCOL instance.
@param [in] Notify A pointer to the H2O_DISPLAY_ENGINE_EVT instance.
@retval EFI_SUCCESS Register notify successful.
@retval EFI_INVALID_PARAMETER This is NULL or Notify is NULL.
**/
EFI_STATUS
EFIAPI
LocalMetroNotify (
IN H2O_DISPLAY_ENGINE_PROTOCOL *This,
IN CONST H2O_DISPLAY_ENGINE_EVT *Notify
)
{
EFI_STATUS Status;
H2O_DISPLAY_ENGINE_EVT_KEYPRESS *KeyPress;
H2O_DISPLAY_ENGINE_EVT_ABS_PTR_MOVE *AbsPtr;
MSG Msg;
RECT Rc;
UI_CONTROL *Control;
HOT_KEY_INFO SelectedHotKeyInfo;
mIsInNotifyProcess = TRUE;
Status = EFI_SUCCESS;
if (Notify->Type != H2O_DISPLAY_ENGINE_EVT_TYPE_OPEN_L &&
Notify->Type != H2O_DISPLAY_ENGINE_EVT_TYPE_OPEN_D &&
gWnd == NULL) {
return EFI_NOT_READY;
}
switch (Notify->Type) {
case H2O_DISPLAY_ENGINE_EVT_TYPE_OPEN_L:
SetCurrentFormSetImage ();
InitializeWindows ();
break;
case H2O_DISPLAY_ENGINE_EVT_TYPE_OPEN_P:
SendMessage (gWnd, FB_NOTIFY_REPAINT, 0, 0);
RegisterTimerEvent (H2O_METRO_DE_TIMER_ID_PERIODIC_TIMER, H2O_METRO_DE_TIMER_PERIODIC_TIME);
SetCurrentFormSetImage ();
break;
case H2O_DISPLAY_ENGINE_EVT_TYPE_SELECT_Q:
SendMessage (gWnd, FB_NOTIFY_SELECT_Q, 0, 0);
break;
case H2O_DISPLAY_ENGINE_EVT_TYPE_REL_PTR_MOVE:
break;
case H2O_DISPLAY_ENGINE_EVT_TYPE_ABS_PTR_MOVE:
AbsPtr = (H2O_DISPLAY_ENGINE_EVT_ABS_PTR_MOVE *) Notify;
GdAddPointerData (NULL, &AbsPtr->AbsPtrState);
CopyMem (&mPreviousAbsPtrState, &AbsPtr->AbsPtrState, sizeof (EFI_ABSOLUTE_POINTER_STATE));
break;
case H2O_DISPLAY_ENGINE_EVT_TYPE_KEYPRESS:
KeyPress = (H2O_DISPLAY_ENGINE_EVT_KEYPRESS *) Notify;
if (!IsMetroPrivateHotKey (&KeyPress->KeyData) && gFB->CurrentP != NULL) {
Status = GetSelectedHotKeyInfoByKeyData (&KeyPress->KeyData, gFB->CurrentP->HotKeyInfo, &SelectedHotKeyInfo);
if (!EFI_ERROR (Status)) {
HotKeyFunc (&SelectedHotKeyInfo);
break;
}
}
//
// skip shift, alt, or ctrl combination key
//
if (KeyPress->KeyData.Key.UnicodeChar == CHAR_NULL &&
KeyPress->KeyData.Key.ScanCode != SCAN_NULL &&
KeyPress->KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID &&
KeyPress->KeyData.KeyState.KeyShiftState & ~EFI_SHIFT_STATE_VALID) {
break;
}
if (!FeaturePcdGet(PcdH2OFormBrowserLocalMetroDEShowFpsSupport)) {
GdAddEfiKeyData (&KeyPress->KeyData);
break;
}
Control = GetUiControl (gWnd);
switch (KeyPress->KeyData.Key.UnicodeChar) {
case '1':
SetRect (&Rc, 0, 0, 1024, 768);
CONTROL_CLASS (Control)->SetPosition (Control, &Rc);
break;
case '2':
SetRect (&Rc, 0, 0, 1366, 768);
CONTROL_CLASS (Control)->SetPosition (Control, &Rc);
break;
case '3':
mShowFps &= SHOW_REFRESH_DE_FPS;
mShowFps ^= SHOW_REFRESH_DE_FPS;
CONTROL_CLASS_INVALIDATE (Control);
break;
case '4':
mShowFps &= SHOW_GOP_BLT_FPS;
mShowFps ^= SHOW_GOP_BLT_FPS;
CONTROL_CLASS_INVALIDATE (Control);
break;
case '5':
mShowFps &= SHOW_TIMER_FPS;
mShowFps ^= SHOW_TIMER_FPS;
CONTROL_CLASS_INVALIDATE (Control);
break;
case '0':
mShowSetPositionDbg = !mShowSetPositionDbg;
break;
case 'p':
case 'P':
SelectNextSetupMenu (FALSE);
break;
case 'n':
case 'N':
SelectNextSetupMenu (TRUE);
break;
default:
GdAddEfiKeyData (&KeyPress->KeyData);
break;
}
break;
//
// Open Dialog
//
case H2O_DISPLAY_ENGINE_EVT_TYPE_OPEN_D:
InitializeWindows ();
ReleaseCapture ();
This->Notify = LocalMetroDialogNotify;
This->Notify (This, Notify);
break;
case H2O_DISPLAY_ENGINE_EVT_TYPE_TIMER:
if (((H2O_DISPLAY_ENGINE_EVT_TIMER *) Notify)->TimerId == H2O_METRO_DE_TIMER_ID_PERIODIC_TIMER) {
RegisterTimerEvent (H2O_METRO_DE_TIMER_ID_PERIODIC_TIMER, H2O_METRO_DE_TIMER_PERIODIC_TIME);
ShowFps (gWnd);
}
break;
case H2O_DISPLAY_ENGINE_EVT_TYPE_REFRESH_Q:
SendMessage (gWnd, FB_NOTIFY_REFRESH_Q, 0, (LPARAM) Notify);
break;
}
while (PeekMessage (&Msg, NULL, 0, 0, PM_REMOVE)) {
if (Msg.message == WM_RBUTTONUP && GetCapture () == NULL) {
PostMessage (gWnd, WM_HOTKEY, 0, MAKELPARAM(0, VK_ESCAPE));
}
TranslateMessage (&Msg);
DispatchMessage (&Msg);
}
mIsInNotifyProcess = FALSE;
//DERemoveFakeConOutDev (mDEPrivate);
return Status;
}
/**
Initialize private data for local metro display engine and install display engine protocol
@param [in] ImageHandle The image handle
@param [in] SystemTable The system table
@retval EFI_SUCCESS Success to initialize private data and install display engine protocol
@retval Other Fail to initialize display engine private data
**/
EFI_STATUS
EFIAPI
H2ODisplayEngineLocalMetroEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
mMetroPrivate = AllocateZeroPool (sizeof (H2O_DISPLAY_ENGINE_METRO_PRIVATE_DATA));
if (mMetroPrivate == NULL) {
return EFI_OUT_OF_RESOURCES;
}
mMetroPrivate->Signature = H2O_DISPLAY_ENGINE_SIGNATURE;
mMetroPrivate->ImageHandle = ImageHandle;
mMetroPrivate->DisplayEngine.Size = (UINT32) sizeof (H2O_DISPLAY_ENGINE_PROTOCOL);
CopyGuid (&mMetroPrivate->DisplayEngine.Id, &gH2ODisplayEngineLocalMetroGuid);
mMetroPrivate->DisplayEngine.InitConsole = LocalMetroInitConsole;
mMetroPrivate->DisplayEngine.AttachConsole = LocalMetroAttachConsole;
mMetroPrivate->DisplayEngine.DetachConsole = LocalMetroDetachConsole;
mMetroPrivate->DisplayEngine.SupportConsole = LocalMetroSupportConsole;
mMetroPrivate->DisplayEngine.Notify = LocalMetroNotify;
InitializeListHead (&mMetroPrivate->ConsoleDevListHead);
ZeroMem (&mPreviousAbsPtrState, sizeof (EFI_ABSOLUTE_POINTER_STATE));
//
// Locate FBProtocol
//
Status = gBS->LocateProtocol (
&gH2OFormBrowserProtocolGuid,
NULL,
(VOID **) &mMetroPrivate->FBProtocol
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
gFB = mMetroPrivate->FBProtocol;
Status = gBS->LocateProtocol (
&gH2OWindowProtocolGuid,
NULL,
(VOID **) &gH2OWindow
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Initial Display Engine Status
//
Status = gBS->InstallMultipleProtocolInterfaces (
&ImageHandle,
&gH2ODisplayEngineProtocolGuid,
&mMetroPrivate->DisplayEngine,
NULL
);
return Status;
}