996 lines
30 KiB
C
996 lines
30 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 "UiControls.h"
|
|
#include "H2ODialogs.h"
|
|
#include "MetroDialog.h"
|
|
#include "MetroUi.h"
|
|
#include <Library/ConsoleLib.h>
|
|
|
|
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"<VerticalLayout padding='40,30,40,30' background-color='@menucolor' name='PopUpDialog'>"
|
|
L"<VerticalLayout name='TitleLayout'>"
|
|
L"<Label padding='0,0,30,0' textcolor='0xFFFFFFFF' font-size='29' name='DialogTitle' height='80'/>"
|
|
L"<Label padding='0,0,45,0' textcolor='0xFFA8D2DF' font-size='19' name='DialogText'/>"
|
|
L"</VerticalLayout>"
|
|
L"<Control background-image='@DialogSeparator' background-color='0x0' name='DialogSeparator' height='10'/>"
|
|
L"<VerticalLayout>"
|
|
L"<HorizontalLayout padding='10,0,0,0' visibility='false' name='DialogPasswordInput' height='41'>"
|
|
L"<Label name='ConfirmNewPasswordLabel' height='41' width='119' font-size='16' background-color='0xFFF2F2F2' textcolor='0xFF4D4D4D'/>"
|
|
L"<VerticalLayout padding='6,8,6,8' background-color='0xFFF2F2F2' height='29'>"
|
|
L"<Control padding='1,1,1,1' background-color='0xFF999999' height='27'>"
|
|
L"<UiEdit name='ConfirmPasswordInput' focusbkcolor='@menulightcolor' height='20' padding='7,3,0,3' background-color='0xFFF2F2F2' password='true'/>"
|
|
L"</Control>"
|
|
L"</VerticalLayout>"
|
|
L"</HorizontalLayout>"
|
|
L"<HorizontalLayout padding='10,0,0,0' child-padding='2' name='DialogButtonList'/>"
|
|
L"</VerticalLayout>"
|
|
L"</VerticalLayout>";
|
|
|
|
CHAR16 *mCommonDialogWithHelpChilds = L""
|
|
L"<VerticalLayout padding='40,30,40,30' width='-1' float='true' name='HelpMenu' height='-1' background-color='@menucolor' name='Dialog'>"
|
|
L"<VerticalLayout name='TitleLayout'>"
|
|
L"<HorizontalLayout padding='0,0,8,0' min-height='50' height='wrap_content'>"
|
|
L"<Label width='200' textcolor='0xFFFFFFFF' font-size='29' name='DialogTitle' height='wrap_content'/>"
|
|
L"<Control padding='0,25,0,25' height='50'>"
|
|
L"<Texture width='50' height='50' name='DialogImage' background-image-style='stretch|light'/>"
|
|
L"</Control>"
|
|
L"</HorizontalLayout>"
|
|
L"<ScrollView taborder='20' name='DialogTextScrollView' vscrollbar='true' scale9grid='1,13,1,13'>"
|
|
L"<Label name='DialogText' height='wrap_content' width='match_parent' font-size='19' textcolor='0xFFA8D2DF'/>"
|
|
L"</ScrollView>"
|
|
L"</VerticalLayout>"
|
|
L"<VerticalLayout>"
|
|
L"<Control background-image='@DialogSeparator' background-color='0x0' height='2'/>"
|
|
L"<Control height='5'/>"
|
|
L"<Control name='Content'/>"
|
|
L"</VerticalLayout>"
|
|
L"</VerticalLayout>";
|
|
|
|
CHAR16 *mDialogWithoutSendFormChilds = L""
|
|
L"<VerticalLayout name='DialogWithoutSendForm'>"
|
|
L"<Control/>"
|
|
L"<Control background-color='@menucolor' name='parent' height='wrap_content'>"
|
|
L"<VerticalLayout padding='20,30,20,30' background-color='@menucolor' height='wrap_content'>"
|
|
L"<VerticalLayout name='TitleLayout' height='wrap_content'>"
|
|
L"<Label name='DialogTitle' text-align='center' height='40' visibility='false' font-size='19' textcolor='0xFFFFFFFF'/>"
|
|
L"<Label width='match_parent' textcolor='0xFFFFFFFF' font-size='19' name='DialogText' height='wrap_content'/>"
|
|
L"<Control height='15'/>"
|
|
L"<Control height='10' background-image='@DialogSeparator' background-color='0x0' background-image-style='center'/>"
|
|
L"<Control height='15'/>"
|
|
L"</VerticalLayout>"
|
|
L"<VerticalLayout padding='0,0,10,0' visibility='false' min-height='51' name='DialogPasswordInput' height='wrap_content'>"
|
|
L"<Label name='ConfirmNewPasswordLabel' height='wrap_content' padding='0,0,2,0' width='match_parent' font-size='18' textcolor='0xFFFFFFFF'/>"
|
|
L"<Control padding='2,2,2,2' background-color='0xFFCCCCCC' height='wrap_content'>"
|
|
L"<UiEdit name='ConfirmPasswordInput' focusbkcolor='0xFFFFFFFF' tabstop='true' height='20' padding='7,3,0,3' taborder='1' background-color='@menulightcolor' password='true'/>"
|
|
L"</Control>"
|
|
L"</VerticalLayout>"
|
|
L"<HorizontalLayout padding='1,0,0,0' child-padding='2' visibility='false' name='DialogButtonList' height='31'/>"
|
|
L"</VerticalLayout>"
|
|
L"<Texture name='FormHalo' float='true' height='-1' width='-1' background-image='@FormHalo' scale9grid='23,26,22,31'/>"
|
|
L"</Control>"
|
|
L"<Control/>"
|
|
L"</VerticalLayout>";
|
|
#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;
|
|
}
|
|
|