/** @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 "UiControls.h" #include "H2ODialogs.h" #include "MetroDialog.h" #include "MetroUi.h" #include extern H2O_DISPLAY_ENGINE_METRO_PRIVATE_DATA *mMetroPrivate; extern HWND gWnd; extern EFI_ABSOLUTE_POINTER_STATE mPreviousAbsPtrState; HWND mDialogWnd = NULL; HWND mOverlayWnd = NULL; H2O_FORM_BROWSER_D *mFbDialog; BOOLEAN mTitleVisible; BOOLEAN mIsSendForm; typedef struct { UINT8 Operand; CHAR16 *ClassName; } DIALOG_CLASS_NAME; DIALOG_CLASS_NAME mDialogClassNameList[] = { //{EFI_IFR_CHECKBOX_OP , L"H2OCheckboxDialog" }, {EFI_IFR_DATE_OP , L"H2ODateTimeDialog" }, {EFI_IFR_ONE_OF_OP , L"H2OOneOfInputDialog" }, {EFI_IFR_ORDERED_LIST_OP, L"H2OOrderedListDialog"}, {EFI_IFR_NUMERIC_OP , L"H2ONumericDialog" }, {EFI_IFR_PASSWORD_OP , L"H2OPasswordDialog" }, {EFI_IFR_STRING_OP , L"H2OStringDialog" }, {EFI_IFR_TIME_OP , L"H2ODateTimeDialog" }, {0 , NULL } }; STATIC CHAR16 * GetClassNameByOperand ( IN UINT8 Operand ) { UINT32 Index; if (Operand == 0) { return NULL; } for (Index = 0; mDialogClassNameList[Index].Operand != 0; Index ++) { if (mDialogClassNameList[Index].Operand == Operand) { return mDialogClassNameList[Index].ClassName; } } return NULL; } VOID H2OCommonDialogWithHelpOnSetState ( UI_CONTROL *Control, UI_STATE SetState, UI_STATE ClearState ) { UI_CONTROL *Child; if (SetState & UISTATE_FOCUSED) { Child = UiFindChildByName (Control, L"DialogText"); UiSetAttribute (Child, L"textcolor", L"0xFFFFFFFF"); } if (ClearState & UISTATE_FOCUSED) { Child = UiFindChildByName (Control, L"DialogText"); UiSetAttribute (Child, L"textcolor", L"0xFFA8D2DF"); } } #if FixedPcdGet32(PcdH2OLmdeMultiLayout) == 0 CHAR16 *mCommonDialogChilds = L"" L"" L"" L"" L"" L"" L"" L"" L"" L"" L""; CHAR16 *mCommonDialogWithHelpChilds = L"" L"" L"" L"" L"" L"" L"" L"" L"" L"" L"" L"" L"" L""; CHAR16 *mDialogWithoutSendFormChilds = L"" L"" L"" L"" L"" L"" L"" L"" L"" L"" L"" L"" L"" L"" L""; #endif VOID FreeDialogEvent ( IN H2O_FORM_BROWSER_D **DialogEvt ) { H2O_FORM_BROWSER_D *Event; if (DialogEvt == NULL || *DialogEvt == NULL) { return; } Event = *DialogEvt; if (Event->TitleString != NULL) { FreePool (Event->TitleString); } if (Event->BodyStringArray != NULL && Event->BodyStringCount != 0) { FreeStringArray (Event->BodyStringArray, Event->BodyStringCount); } if (Event->BodyInputStringArray != NULL && Event->BodyInputCount != 0) { FreeStringArray (Event->BodyInputStringArray, Event->BodyInputCount); } if (Event->ButtonStringArray != NULL && Event->ButtonCount != 0) { FreeStringArray (Event->ButtonStringArray, Event->ButtonCount); } if (Event->BodyHiiValueArray != NULL && Event->BodyStringCount != 0) { FreeHiiValueArray (Event->BodyHiiValueArray, Event->BodyStringCount); } if (Event->ButtonHiiValueArray != NULL && Event->ButtonCount != 0) { FreeHiiValueArray (Event->ButtonHiiValueArray, Event->ButtonCount); } if (Event->ConfirmHiiValue.Type == EFI_IFR_TYPE_BUFFER && Event->ConfirmHiiValue.Buffer != NULL && Event->ConfirmHiiValue.BufferLen != 0) { FreePool (Event->ConfirmHiiValue.Buffer); } FreePool (Event); *DialogEvt = NULL; } H2O_FORM_BROWSER_D * CopyDialogEvent ( IN H2O_FORM_BROWSER_D *SrcDialogEvt ) { H2O_FORM_BROWSER_D *DialogEvt; if (SrcDialogEvt == NULL) { return NULL; } DialogEvt = AllocateCopyPool (sizeof (H2O_FORM_BROWSER_D), SrcDialogEvt); if (DialogEvt == NULL) { return NULL; } if (SrcDialogEvt->TitleString != NULL) { DialogEvt->TitleString = AllocateCopyPool (StrSize (SrcDialogEvt->TitleString), SrcDialogEvt->TitleString); if (DialogEvt->TitleString == NULL) { goto Error; } } if (SrcDialogEvt->BodyStringArray != NULL && SrcDialogEvt->BodyStringCount != 0) { DialogEvt->BodyStringArray = CopyStringArray (SrcDialogEvt->BodyStringArray, SrcDialogEvt->BodyStringCount); if (DialogEvt->BodyStringArray == NULL) { goto Error; } } if (SrcDialogEvt->BodyInputStringArray != NULL && SrcDialogEvt->BodyInputCount != 0) { DialogEvt->BodyInputStringArray = CopyStringArray (SrcDialogEvt->BodyInputStringArray, SrcDialogEvt->BodyInputCount); if (DialogEvt->BodyInputStringArray == NULL) { goto Error; } } if (SrcDialogEvt->ButtonStringArray != NULL && SrcDialogEvt->ButtonCount != 0) { DialogEvt->ButtonStringArray = CopyStringArray (SrcDialogEvt->ButtonStringArray, SrcDialogEvt->ButtonCount); if (DialogEvt->ButtonStringArray == NULL) { goto Error; } } if (SrcDialogEvt->BodyHiiValueArray != NULL && SrcDialogEvt->BodyStringCount != 0) { DialogEvt->BodyHiiValueArray = CopyHiiValueArray (SrcDialogEvt->BodyHiiValueArray, SrcDialogEvt->BodyStringCount); if (DialogEvt->BodyHiiValueArray == NULL) { goto Error; } } if (SrcDialogEvt->ButtonHiiValueArray != NULL && SrcDialogEvt->ButtonCount != 0) { DialogEvt->ButtonHiiValueArray = CopyHiiValueArray (SrcDialogEvt->ButtonHiiValueArray, SrcDialogEvt->ButtonCount); if (DialogEvt->ButtonHiiValueArray == NULL) { goto Error; } } if (SrcDialogEvt->ConfirmHiiValue.Type == EFI_IFR_TYPE_BUFFER && SrcDialogEvt->ConfirmHiiValue.Buffer != NULL && SrcDialogEvt->ConfirmHiiValue.BufferLen != 0) { DialogEvt->ConfirmHiiValue.Buffer = AllocateCopyPool (SrcDialogEvt->ConfirmHiiValue.BufferLen, SrcDialogEvt->ConfirmHiiValue.Buffer); if (DialogEvt->ConfirmHiiValue.Buffer == NULL) { goto Error; } } return DialogEvt; Error: FreeDialogEvent (&DialogEvt); return NULL; } STATIC HWND CreateModalDialog ( CHAR16 *ClassName, HINSTANCE Instance, HWND ParentWnd, LPARAM Param, INT32 X, INT32 Y, INT32 Width, INT32 Height, BOOLEAN CloseDlgWhenTouchOutside ) { UI_DIALOG *DialogData; HWND Dlg; UI_CONTROL *Control; UI_MANAGER *Manager; DialogData = AllocateZeroPool (sizeof (UI_DIALOG)); if (DialogData == NULL) { return NULL; } DialogData->Instance = Instance; DialogData->ParentWnd = ParentWnd; DialogData->Param = Param; DialogData->Running = TRUE; DialogData->CloseDlgWhenTouchOutside = CloseDlgWhenTouchOutside; Dlg = CreateWindowEx ( WS_EX_NOACTIVATE, ClassName, L"", WS_VISIBLE | WS_POPUP, X, Y, Width, Height, ParentWnd, NULL, Instance, DialogData ); // ASSERT (Dlg != NULL); if (Dlg == NULL) { return NULL; } Control = (UI_CONTROL *) (UINTN) GetWindowLongPtr (Dlg, 0); Manager = Control->Manager; SetWindowLongPtr (Control->Wnd, GWLP_USERDATA, (INTN)mFbDialog); SendMessage (Manager->MainWnd, UI_NOTIFY_WINDOWINIT, (WPARAM)Manager->Root, 0); return Dlg; } BOOLEAN ClickOnOutsideOfDlgRegion ( IN EFI_ABSOLUTE_POINTER_STATE *AbsPtrState ) { RECT DlgRect; POINT Pt; ASSERT (mDialogWnd != NULL); ASSERT (AbsPtrState != NULL); if (GetCapture () != NULL) { return FALSE; } if (AbsPtrState->ActiveButtons == 0) { return FALSE; } Pt.x = (INT32) AbsPtrState->CurrentX; Pt.y = (INT32) AbsPtrState->CurrentY; GetWindowRect (mDialogWnd, &DlgRect); if (PtInRect (&DlgRect, Pt)) { return FALSE; } return TRUE; } UINT32 GetButtonWidthByStr ( VOID ) { UINT32 Index; UINT32 ButtonWidth; ButtonWidth = 0; for (Index = 0; Index < mFbDialog->ButtonCount; Index++) { if (mFbDialog->ButtonStringArray[Index] != NULL) { ButtonWidth = (UINT32) MAX (GetStringWidth (mFbDialog->ButtonStringArray[Index]), ButtonWidth); } } return (ButtonWidth * 5 + 4); } VOID EnableTitle ( HWND Wnd, BOOLEAN Enable ) { CHAR16 *Str; UI_DIALOG *Dialog; UI_CONTROL *Control; HWND FocusedWnd; // // Prevent from button location change to cause invalid button press, NOT do // enable/disable password during this period. // FocusedWnd = GetFocus (); Control = (UI_CONTROL *) GetWindowLongPtr (FocusedWnd, 0); if (Control != NULL && (StrCmp (Control->Name, L"Ok") == 0 || StrCmp (Control->Name, L"Cancel") == 0) && (CONTROL_CLASS_GET_STATE(Control) & UISTATE_PRESSED)) { return; } Dialog = (UI_DIALOG *) GetWindowLongPtr (Wnd, 0); Str = Enable ? L"true" : L"false"; Control = UiFindChildByName (Dialog, L"TitleLayout"); UiSetAttribute (Control, L"visibility", Str); mTitleVisible = Enable; CONTROL_CLASS_INVALIDATE (Dialog); } LRESULT WINAPI DialogCallback ( HWND Wnd, UINT Msg, WPARAM WParam, LPARAM LParam ) { KEYBOARD_ATTRIBUTES KeyboardAttributes; if (mSetupMouse == NULL) { return 0; } mSetupMouse->GetKeyboardAttributes (mSetupMouse, &KeyboardAttributes); if (KeyboardAttributes.IsStart && mTitleVisible) { EnableTitle (Wnd, FALSE); } else if (!KeyboardAttributes.IsStart && !mTitleVisible) { EnableTitle (Wnd, TRUE); } return 0; } EFI_STATUS GetDialogRegion ( IN CHAR16 *PanelName, OUT RECT *DlgRect ) { EFI_STATUS Status; RECT PanelRect; UINT32 PanelWidth; UINT32 PanelHeight; UINT32 DlgWidth; UINT32 DlgHeight; ASSERT (PanelName != NULL); ASSERT (DlgRect != NULL); Status = GetRectByName (gWnd, PanelName, &PanelRect); if (EFI_ERROR (Status)) { return Status; } PanelWidth = PanelRect.right - PanelRect.left; PanelHeight = PanelRect.bottom - PanelRect.top; if ((mFbDialog->DialogType & H2O_FORM_BROWSER_D_TYPE_QUESTIONS) == 0) { if ((mFbDialog->DialogType & H2O_FORM_BROWSER_D_TYPE_SELECTION) == H2O_FORM_BROWSER_D_TYPE_SELECTION) { DlgWidth = 360; DlgHeight = PanelHeight; } else if ((mFbDialog->DialogType & H2O_FORM_BROWSER_D_TYPE_MSG ) == H2O_FORM_BROWSER_D_TYPE_MSG || (mFbDialog->DialogType & H2O_FORM_BROWSER_D_TYPE_CONFIRM) == H2O_FORM_BROWSER_D_TYPE_CONFIRM) { DlgWidth = 360; DlgHeight = PanelHeight; } else if ((mFbDialog->DialogType & H2O_FORM_BROWSER_D_TYPE_SHOW_CONFIRM_PAGE) == H2O_FORM_BROWSER_D_TYPE_SHOW_CONFIRM_PAGE) { DlgWidth = PanelWidth; DlgHeight = PanelHeight; } else { return EFI_UNSUPPORTED; } } else { switch (GetOpCodeByDialogType (mFbDialog->DialogType)) { case EFI_IFR_ONE_OF_OP: DlgWidth = PanelWidth; DlgHeight = PanelHeight; break; case EFI_IFR_NUMERIC_OP: DlgWidth = 360; DlgHeight = 200; break; case EFI_IFR_PASSWORD_OP: DlgWidth = 400; DlgHeight = PanelHeight; break; default: return EFI_UNSUPPORTED; break; } } DlgRect->left = PanelRect.left + ((PanelWidth - DlgWidth) / 2); DlgRect->top = PanelRect.top + ((PanelHeight - DlgHeight) / 2); DlgRect->right = DlgRect->left + DlgWidth; DlgRect->bottom = DlgRect->top + DlgHeight; return EFI_SUCCESS; } HWND FindOverlayDialog ( ) { UI_CONTROL *Control; UI_CONTROL *Overlay; UI_MANAGER *Manager; Control = GetUiControl (gWnd); Manager = Control->Manager; Overlay = Manager->FindControlByName (Manager, L"overlay"); if (Overlay != NULL) { CONTROL_CLASS(Overlay)->SetAttribute (Overlay, L"visibility", L"true"); return Overlay->Wnd; } return NULL; } HWND LocalMetroCreateDialog ( IN CONST H2O_DISPLAY_ENGINE_EVT *Notify ) { HWND Wnd; H2O_DISPLAY_ENGINE_EVT_OPEN_D *OpenDNotify; H2O_FORM_BROWSER_D *Dialog; BOOLEAN CloseOnTouchOutside; UINT8 OpCode; HWND ParentWnd; RECT DlgRect; EFI_STATUS Status; INT32 Id; CHAR16 *ClassName; EFI_GUID PopUpFormsetId; UINT16 PopUpFormId; OpenDNotify = (H2O_DISPLAY_ENGINE_EVT_OPEN_D *) Notify; Dialog = &OpenDNotify->Dialog; Wnd = NULL; if (gFB->CurrentP != NULL) { CloseOnTouchOutside = TRUE; mIsSendForm = TRUE; } else { CloseOnTouchOutside = FALSE; mIsSendForm = FALSE; ZeroMem (&mPreviousAbsPtrState, sizeof (EFI_ABSOLUTE_POINTER_STATE)); } SetRectEmpty (&DlgRect); ParentWnd = GetFocus(); mFbDialog = Dialog; if (mIsSendForm) { Status = GetRectByName (gWnd, L"H2OHelpTextPanel", &DlgRect); } else { Status = GetDialogRegion (L"DialogPanel", &DlgRect); } ASSERT_EFI_ERROR (Status); if ((Dialog->DialogType & H2O_FORM_BROWSER_D_TYPE_QUESTIONS) == 0) { if ((Dialog->DialogType & H2O_FORM_BROWSER_D_TYPE_SHOW_HELP) == H2O_FORM_BROWSER_D_TYPE_SHOW_HELP) { Status = GetInformationField (&DlgRect); ASSERT (!EFI_ERROR (Status)); ClassName = L"H2OHelpDialog"; } else if ((Dialog->DialogType & H2O_FORM_BROWSER_D_TYPE_SHOW_CONFIRM_PAGE) == H2O_FORM_BROWSER_D_TYPE_SHOW_CONFIRM_PAGE) { Status = GetInformationField (&DlgRect); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "GetInformationField(): %r", Status)); } ClassName = L"H2OConfirmPageDialog"; } else if ((Dialog->DialogType & H2O_FORM_BROWSER_D_TYPE_SELECTION) == H2O_FORM_BROWSER_D_TYPE_SELECTION) { mFbDialog = CopyDialogEvent (Dialog); if (mFbDialog == NULL) { return NULL; } ClassName = L"H2OPopupDialog"; } else if ((Dialog->DialogType & H2O_FORM_BROWSER_D_TYPE_MSG ) == H2O_FORM_BROWSER_D_TYPE_MSG || (Dialog->DialogType & H2O_FORM_BROWSER_D_TYPE_CONFIRM) == H2O_FORM_BROWSER_D_TYPE_CONFIRM) { mFbDialog = CopyDialogEvent (Dialog); if (mFbDialog == NULL) { return NULL; } ClassName = L"H2OMsgPopUpDialog"; } else { return NULL; } } else { OpCode = GetOpCodeByDialogType (Dialog->DialogType); mFbDialog = CopyDialogEvent (Dialog); if (mFbDialog == NULL) { return NULL; } // // Question dialog is determined by Pop Up form (highest priority), VFCF control-type or LMDE XML strings (lowest priority). // ClassName = NULL; if (GetPopUpForm (mFbDialog->H2OStatement, &PopUpFormsetId, &PopUpFormId) == EFI_SUCCESS) { GetPopUpFormRect (&PopUpFormsetId, PopUpFormId, &DlgRect); ClassName = L"H2OFormDialog"; } if (ClassName == NULL) { ClassName = GetClassNameBySetupPageStatementControlType (mFbDialog->H2OStatement); } if (ClassName == NULL) { ClassName = GetClassNameByOperand (OpCode); } if (ClassName == NULL) { ClassName = L"DIALOG"; } switch (OpCode) { case EFI_IFR_NUMERIC_OP: case EFI_IFR_ORDERED_LIST_OP: case EFI_IFR_CHECKBOX_OP: case EFI_IFR_PASSWORD_OP: case EFI_IFR_STRING_OP: // // TODO: Need receive and sending H2O_DISPLAY_ENGINE_EVT_TYPE_CHANGING_Q to synchronize // with other display engine. // CloseOnTouchOutside = FALSE; break; case EFI_IFR_ONE_OF_OP: case EFI_IFR_DATE_OP: case EFI_IFR_TIME_OP: break; default: ASSERT (FALSE); break; } } Id = 1; while (TRUE) { if (!UnregisterHotKey (Wnd, Id++)) { break; } } Wnd = CreateModalDialog ( ClassName, NULL, ParentWnd, 0, DlgRect.left, DlgRect.top, DlgRect.right - DlgRect.left, DlgRect.bottom - DlgRect.top, CloseOnTouchOutside ); MwRegisterHotKey (Wnd, 1, 0, VK_ESCAPE); return Wnd; } VOID LocalMetroRegisterHotkey ( HWND Wnd ); HWND GetNextTabItemByTabOrder ( IN HWND Dialog, IN UI_CONTROL *Current, IN BOOL Previous ) { INTN Style; INTN ExStyle; HWND Child; HWND Node; UI_CONTROL *Candidate; UI_CONTROL *Next; UI_CONTROL *Control; Next = NULL; Candidate = NULL; Node = GetWindow (Dialog, GW_CHILD); while (Node != NULL && Node != Dialog) { Child = GetWindow (Node, GW_CHILD); Style = GetWindowLongPtr (Node, GWL_STYLE); ExStyle = GetWindowLongPtr (Node, GWL_EXSTYLE); do { if (!((Style & WS_VISIBLE) && !(Style & WS_DISABLED))) { Child = NULL; break; } if (!(ExStyle & WS_EX_CONTROLPARENT)) { Child = NULL; break; } if (Style & WS_TABSTOP) { Child = NULL; Control = GetUiControl (Node); ASSERT (Control != NULL); if (Control == NULL) { break; } if (Control->TabOrder == (Current->TabOrder + 1)) { return Control->Wnd; } if ((Control->TabOrder > Current->TabOrder) && ((Next == NULL) || (Next->TabOrder > Control->TabOrder))) { Next = Control; } if ((Control->TabOrder < Current->TabOrder) && ((Candidate == NULL) || (Candidate->TabOrder > Control->TabOrder))) { Candidate = Control; } } } while (0); if (Child != NULL) { Node = Child; } else if (GetWindow (Node, GW_HWNDNEXT) != NULL) { Node = GetWindow (Node, GW_HWNDNEXT); } else { Node = GetParent (Node); while (Node != NULL && Node != Dialog) { if (GetWindow (Node, GW_HWNDNEXT) != NULL) { Node = GetWindow (Node, GW_HWNDNEXT); break; } else { Node = GetParent (Node); } } } } if (Next == NULL) { Next = Candidate; } if (Next != NULL) { return Next->Wnd; } return NULL; } HWND GetNextTabItem ( IN HWND MainWnd, IN HWND DlgWnd, IN HWND CtrlWnd, IN BOOL Previous ) { INTN Style; INTN ExStyle; UINT32 WndSearch; HWND ChildFirst; HWND RetWnd; WndSearch = Previous ? GW_HWNDPREV : GW_HWNDNEXT; if (DlgWnd == CtrlWnd) { CtrlWnd = NULL; } ChildFirst = NULL; RetWnd = NULL; if (!CtrlWnd) { ChildFirst = GetWindow (DlgWnd, GW_CHILD); if (Previous) { ChildFirst = GetWindow (ChildFirst, GW_HWNDLAST); } } else if (IsChild (MainWnd, CtrlWnd)) { ChildFirst = GetWindow (CtrlWnd, WndSearch); if (!ChildFirst) { if (GetParent (CtrlWnd) != MainWnd) { ChildFirst = GetWindow (GetParent (CtrlWnd), WndSearch); } else { ChildFirst = GetWindow (CtrlWnd, Previous ? GW_HWNDLAST : GW_HWNDFIRST); } } } while (ChildFirst != NULL) { Style = GetWindowLongPtr (ChildFirst, GWL_STYLE); ExStyle = GetWindowLongPtr (ChildFirst, GWL_EXSTYLE); if ((Style & WS_TABSTOP) && (Style & WS_VISIBLE) && !(Style & WS_DISABLED)) { return ChildFirst; } else if ((ExStyle & WS_EX_CONTROLPARENT) && (Style & WS_VISIBLE) && !(Style &WS_DISABLED)) { RetWnd = GetNextTabItem (MainWnd, ChildFirst, NULL, Previous); if (RetWnd != NULL) { return RetWnd; } } ChildFirst = GetWindow (ChildFirst, WndSearch); } if (CtrlWnd != NULL) { HWND Parent; Parent = GetParent (CtrlWnd); while (Parent != NULL) { if (Parent == MainWnd) { break; } RetWnd = GetNextTabItem (MainWnd, GetParent (Parent), Parent, Previous); if (RetWnd != NULL) { break; } } if(RetWnd == NULL) { RetWnd = GetNextTabItem (MainWnd, MainWnd, NULL, Previous); } } return RetWnd ? RetWnd : CtrlWnd; } BOOLEAN IsUiDialogMessage ( HWND DlgWnd, LPMSG Msg ) { HWND Focus; HWND Next; LRESULT DlgCode; if (Msg->message == WM_TIMER) { return FALSE; } if ((DlgWnd != Msg->hwnd) && !IsChild(DlgWnd, Msg->hwnd)) { return FALSE; } switch(Msg->message) { case WM_KEYDOWN: DlgCode = SendMessage (Msg->hwnd, WM_GETDLGCODE, Msg->wParam, (LPARAM) Msg); if (DlgCode & (DLGC_WANTMESSAGE)) break; switch (Msg->wParam) { case VK_TAB: if (DlgCode & DLGC_WANTTAB) break; Focus = GetFocus (); Next = GetNextTabItemByTabOrder (DlgWnd, GetUiControl (Focus), FALSE); if (Next == NULL) { Next = GetNextTabItem (DlgWnd, DlgWnd, Focus == DlgWnd ? NULL : Focus, FALSE); } if (Next != NULL) { SetFocus (Next); return TRUE; } break; } } TranslateMessage (Msg); DispatchMessage (Msg); return TRUE; } EFI_STATUS EFIAPI LocalMetroDialogNotify ( IN H2O_DISPLAY_ENGINE_PROTOCOL *This, IN CONST H2O_DISPLAY_ENGINE_EVT *Notify ) { MSG Msg; H2O_DISPLAY_ENGINE_EVT_ABS_PTR_MOVE *AbsPtr; H2O_DISPLAY_ENGINE_EVT_KEYPRESS *KeyPress; UI_DIALOG *Dialog; UI_CONTROL *Control; STATIC HWND FocusWnd = NULL; switch (Notify->Type) { case H2O_DISPLAY_ENGINE_EVT_TYPE_OPEN_D: if (mDialogWnd != NULL) { if (((H2O_DISPLAY_ENGINE_EVT_OPEN_D *) Notify)->Dialog.DialogType != mFbDialog->DialogType) { return EFI_ALREADY_STARTED; } EnableWindow (gWnd, FALSE); EnableWindow (GetDesktopWindow(), FALSE); Control = (UI_CONTROL *) GetWindowLongPtr (mDialogWnd, 0); CONTROL_CLASS_INVALIDATE (Control ); LocalMetroRegisterHotkey (mDialogWnd); if (FocusWnd != NULL) { SetFocus (FocusWnd); FocusWnd = NULL; } break; } EnableWindow (gWnd, FALSE); EnableWindow (GetDesktopWindow(), FALSE); mDialogWnd = LocalMetroCreateDialog (Notify); if (mDialogWnd == NULL) { SendShutDNotify (); } GrayOutBackground (gWnd, TRUE); break; case H2O_DISPLAY_ENGINE_EVT_TYPE_SHUT_D: if (mDialogWnd != NULL) { if (!(mFbDialog->DialogType == (H2O_FORM_BROWSER_D_TYPE_MSG|H2O_FORM_BROWSER_D_TYPE_FROM_H2O_DIALOG))) { DestroyWindow(mDialogWnd); mDialogWnd = NULL; } } This->Notify = LocalMetroNotify; EnableWindow (gWnd, TRUE); GrayOutBackground (gWnd, FALSE); SetFocus (gWnd); LocalMetroRegisterHotkey (gWnd); break; case H2O_DISPLAY_ENGINE_EVT_TYPE_OPEN_L: case H2O_DISPLAY_ENGINE_EVT_TYPE_OPEN_P: // // OPEN_L and OPEN_P should be handled by LocalMetroNotify. For example: Triggering repaint in dialog screen. // FocusWnd = GetFocus (); This->Notify = LocalMetroNotify; This->Notify (This, Notify); break; case H2O_DISPLAY_ENGINE_EVT_TYPE_ABS_PTR_MOVE: AbsPtr = (H2O_DISPLAY_ENGINE_EVT_ABS_PTR_MOVE *) Notify; Dialog = (UI_DIALOG *) GetWindowLongPtr (mDialogWnd, 0); if (Dialog->CloseDlgWhenTouchOutside && ClickOnOutsideOfDlgRegion (&AbsPtr->AbsPtrState) && mPreviousAbsPtrState.ActiveButtons == 0) { CopyMem (&mPreviousAbsPtrState, &AbsPtr->AbsPtrState, sizeof (EFI_ABSOLUTE_POINTER_STATE)); SendShutDNotify (); break; } CopyMem (&mPreviousAbsPtrState, &AbsPtr->AbsPtrState, sizeof (EFI_ABSOLUTE_POINTER_STATE)); GdAddPointerData (NULL, &AbsPtr->AbsPtrState); break; case H2O_DISPLAY_ENGINE_EVT_TYPE_KEYPRESS: KeyPress = (H2O_DISPLAY_ENGINE_EVT_KEYPRESS *) Notify; GdAddEfiKeyData (&KeyPress->KeyData); 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); } break; case H2O_DISPLAY_ENGINE_EVT_TYPE_REFRESH_Q: break; case H2O_DISPLAY_ENGINE_EVT_TYPE_CHANGING_Q: break; case H2O_DISPLAY_ENGINE_EVT_TYPE_SUBMIT_EXIT: break; default: ASSERT (FALSE); } while (PeekMessage (&Msg, NULL, 0, 0, PM_REMOVE)) { if (Msg.message == WM_RBUTTONUP && GetCapture () == NULL) { SendMessage (mDialogWnd, WM_HOTKEY, 0, MAKELPARAM(0, VK_ESCAPE)); } else if (mDialogWnd == NULL || !IsUiDialogMessage (mDialogWnd, &Msg)) { TranslateMessage (&Msg); DispatchMessage (&Msg); } } return EFI_SUCCESS; }