/** @file Initialization and display related functions for setup page panel. ;****************************************************************************** ;* Copyright (c) 2015 - 2020, 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 "LTDEPanels.h" #include "LTDEQuestions.h" #include "LTDEPrint.h" #include "LTDESupport.h" #include "LTDEMisc.h" #define PROMPT_VALUE_SEPARATOR_WIDTH 1 #define ARROW_TEXT (EFI_RED | EFI_BRIGHT) CHAR16 mPageUpStr[2] = {ARROW_UP, CHAR_NULL}; CHAR16 mPageDownStr[2] = {ARROW_DOWN, CHAR_NULL}; typedef enum { LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_PAGE_UP = 0, LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_PAGE_DOWN, LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_HOME, LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_END, LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_MAX, } LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION; typedef struct { UINT32 Action; EFI_INPUT_KEY InputKey; CHAR16 *String; } LTDE_SETUP_PAGE_PANEL_HOT_KEY_INFO; LTDE_SETUP_PAGE_PANEL_HOT_KEY_INFO mSetupPagePanelHotKeyInfoList[] = { {LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_PAGE_UP , {SCAN_PAGE_UP , CHAR_NULL}, mPageUpStr}, {LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_PAGE_DOWN, {SCAN_PAGE_DOWN, CHAR_NULL}, mPageDownStr}, {LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_HOME , {SCAN_HOME , CHAR_NULL}, L""}, {LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_END , {SCAN_END , CHAR_NULL}, L""}, }; /** Check if input question ID is current highlight or not @param[in] PageId Page ID @param[in] QuestionId Query question ID @param[in] IfrOpCode IFR opcode pointer of Query question @retval TRUE Query question is current highlight @retval FALSE Query question is not current highlight **/ BOOLEAN IsCurrentHighlight ( IN H2O_PAGE_ID PageId, IN EFI_QUESTION_ID QuestionId, IN EFI_IFR_OP_HEADER *IfrOpCode ) { H2O_LTDE_PANEL *SetupPagePanel; SetupPagePanel = GetPanel (SETUP_PAGE_PANEL_ID); if (SetupPagePanel != NULL && SetupPagePanel->SelectedControl != NULL && SetupPagePanel->SelectedControl->PageId == PageId && ((QuestionId != 0 && SetupPagePanel->SelectedControl->QuestionId == QuestionId) || (IfrOpCode != NULL && SetupPagePanel->SelectedControl->IfrOpCode == IfrOpCode))) { return TRUE; } return FALSE; } /** Check if input control is in the display field or not @param[in] SetupPagePanel Pointer to the setup page panel @param[in] Control Pointer to the control @retval TRUE Input control is in the display field @retval FALSE Input control is not in the display field **/ STATIC BOOLEAN IsControlInDisplayField ( IN H2O_LTDE_PANEL *SetupPagePanel, IN H2O_LTDE_CONTROL *Control ) { H2O_LTDE_PANEL_ITEM *ContentItem; INT32 StartY; INT32 EndY; if (SetupPagePanel == NULL || Control == NULL) { return FALSE; } ContentItem = GetPanelItem (SetupPagePanel, LTDE_PANEL_ITEM_ID_CONTENT); if (ContentItem == NULL) { return FALSE; } StartY = ContentItem->CurrentPos; EndY = StartY + H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField) - 1; return (BOOLEAN) IS_OVERLAP (Control->ControlField.top, Control->ControlField.bottom, StartY, EndY); } /** Get first valid control in display field @param[in] ContentItem Pointer to content item @return The pointer of first valid control or NULL if not found **/ H2O_LTDE_CONTROL * GetFirstValidControlInDisplayField ( IN H2O_LTDE_PANEL_ITEM *ContentItem ) { INT32 StartY; INT32 EndY; UINT32 Index; H2O_LTDE_CONTROL *Control; H2O_LTDE_CONTROL *TargetCtrl; StartY = ContentItem->CurrentPos; EndY = StartY + H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField) - 1; TargetCtrl = NULL; for (Index = 0; Index < ContentItem->ControlCount; Index++) { Control = &ContentItem->ControlList[Index]; if (Control->Operand == EFI_IFR_SUBTITLE_OP || !IS_OVERLAP (Control->ControlField.top, Control->ControlField.bottom, StartY, EndY)) { continue; } TargetCtrl = (TargetCtrl != NULL && TargetCtrl->ControlField.top < Control->ControlField.top) ? TargetCtrl : Control; } return TargetCtrl; } /** Get first or last selectable control in display field @param[in] ContentItem Pointer to content item @param[in] GetFirst TRUE to get first selectable control or FALSE to get last selectable control @return The pointer of selectable control or NULL if not found **/ H2O_LTDE_CONTROL * GetSelectableControlInDisplayField ( IN H2O_LTDE_PANEL_ITEM *ContentItem, IN BOOLEAN GetFirst ) { INT32 StartY; INT32 EndY; UINT32 Index; H2O_LTDE_CONTROL *Control; H2O_LTDE_CONTROL *TargetCtrl; StartY = ContentItem->CurrentPos; EndY = StartY + H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField) - 1; TargetCtrl = NULL; for (Index = 0; Index < ContentItem->ControlCount; Index++) { Control = &ContentItem->ControlList[Index]; if (!Control->Selectable || !IS_OVERLAP (Control->ControlField.top, Control->ControlField.bottom, StartY, EndY)) { continue; } if (GetFirst) { TargetCtrl = (TargetCtrl != NULL && TargetCtrl->ControlField.top < Control->ControlField.top) ? TargetCtrl : Control; } else { TargetCtrl = (TargetCtrl != NULL && TargetCtrl->ControlField.bottom >= Control->ControlField.bottom) ? TargetCtrl : Control; } } return TargetCtrl; } /** Get hot key info of setup page panel by hot key action. @param[in] HotKeyAction Hot key action. @return The pointer of hot key info or NULL if not found **/ STATIC LTDE_SETUP_PAGE_PANEL_HOT_KEY_INFO * GetSetupPageHotKeyInfo ( IN UINT32 HotKeyAction ) { UINT32 Index; for (Index = 0; Index < sizeof (mSetupPagePanelHotKeyInfoList) / sizeof (LTDE_SETUP_PAGE_PANEL_HOT_KEY_INFO); Index++) { if (mSetupPagePanelHotKeyInfoList[Index].Action == HotKeyAction) { return &mSetupPagePanelHotKeyInfoList[Index]; } } return NULL; } /** Get prompt string of question @param[in] Question A pointer to question @return The pointer of prompt string or NULL if not found **/ STATIC CHAR16 * GetQuestionPromptStr ( IN H2O_FORM_BROWSER_Q *Question ) { CHAR16 *QuestionPromptStr; UINTN QuestionPromptStrSize; CHAR16 *PromptStr; if (Question == NULL) { return NULL; } QuestionPromptStr = (Question->Prompt != NULL && *Question->Prompt != CHAR_NULL) ? Question->Prompt : L" "; QuestionPromptStrSize = StrSize (QuestionPromptStr); switch (Question->Operand) { case EFI_IFR_ORDERED_LIST_OP: PromptStr = OrderListOpCodeCreatePromptStr (Question); break; case EFI_IFR_REF_OP: PromptStr = AllocateZeroPool (QuestionPromptStrSize + sizeof (CHAR16)); if (PromptStr != NULL) { PromptStr[0] = REF_OP_DELIMITER; CopyMem (&PromptStr[1], QuestionPromptStr, QuestionPromptStrSize); } break; default: PromptStr = AllocateCopyPool (QuestionPromptStrSize, QuestionPromptStr); } return PromptStr; } /** Get value string of question @param[in] Question A pointer to question @return The pointer of value string or NULL if not found **/ CHAR16 * GetQuestionValueStr ( IN H2O_FORM_BROWSER_Q *Question ) { CHAR16 *ValueStr; H2O_FORM_BROWSER_O *Option; UINT32 Index; CHAR16 *TempStr; if (Question == NULL) { return NULL; } switch (Question->Operand) { case EFI_IFR_SUBTITLE_OP: case EFI_IFR_REF_OP: case EFI_IFR_RESET_BUTTON_OP: return NULL; case EFI_IFR_TEXT_OP: case EFI_IFR_ACTION_OP: return (Question->TextTwo != NULL) ? AllocateCopyPool (StrSize (Question->TextTwo), Question->TextTwo) : NULL; case EFI_IFR_ONE_OF_OP: for (Index = 0; Index < Question->NumberOfOptions; Index++) { Option = &(Question->Options[Index]); if ((Option->HiiValue.Value.u64 == Question->HiiValue.Value.u64)) { return CatSPrint (NULL, L"%c%s%c", LEFT_ONEOF_DELIMITER, Option->Text, RIGHT_ONEOF_DELIMITER); } } break; case EFI_IFR_ORDERED_LIST_OP: return NULL; case EFI_IFR_NUMERIC_OP: TempStr = IfrNumericPrintFormattedNumber (Question); if (TempStr == NULL) { break; } ValueStr = CatSPrint (NULL, L"%c%s%c", LEFT_NUMERIC_DELIMITER, TempStr, RIGHT_NUMERIC_DELIMITER); FreePool (TempStr); return ValueStr; case EFI_IFR_CHECKBOX_OP: return CatSPrint (NULL, L"%c%c%c", LEFT_CHECKBOX_DELIMITER, (Question->HiiValue.Value.b) ? CHECK_ON : CHECK_OFF, RIGHT_CHECKBOX_DELIMITER); case EFI_IFR_TIME_OP: case EFI_IFR_DATE_OP: return DateTimeOpCodeCreateValueStr (Question); case EFI_IFR_STRING_OP: case EFI_IFR_PASSWORD_OP: return (Question->HiiValue.Buffer != NULL) ? AllocateCopyPool (StrSize ((CHAR16 *) Question->HiiValue.Buffer), Question->HiiValue.Buffer) : NULL; default: break; } return NULL; } /** Update control in content item of setup page panel @param[in] SetupPagePanel A pointer to setup page panel @param[in] ContentItem A pointer to content item @param[in] Statement A pointer to statement @param[out] Control A pointer to control @retval EFI_SUCCESS Update control successful @retval EFI_INVALID_PARAMETER Input parameter is NULL **/ EFI_STATUS UpdateSetupPageControl ( IN H2O_LTDE_PANEL *SetupPagePanel, IN H2O_LTDE_PANEL_ITEM *ContentItem, IN H2O_FORM_BROWSER_S *Statement, OUT H2O_LTDE_CONTROL *Control ) { UINT32 PseudoClass; if (SetupPagePanel == NULL || ContentItem == NULL || Statement == NULL || Control == NULL) { return EFI_INVALID_PARAMETER; } if (Statement->GrayedOut || Statement->Locked) { PseudoClass = H2O_STYLE_PSEUDO_CLASS_GRAYOUT; } else if (Statement->Selectable) { PseudoClass = H2O_STYLE_PSEUDO_CLASS_SELECTABLE; } else { PseudoClass = H2O_STYLE_PSEUDO_CLASS_NORMAL; } CopyHiiValue (&Control->HiiValue, &Statement->HiiValue); Control->Text.String = GetQuestionPromptStr (Statement); Control->ValueStrInfo.String = GetQuestionValueStr (Statement); Control->PageId = Statement->PageId; Control->StatementId = Statement->StatementId; Control->QuestionId = Statement->QuestionId; Control->Operand = Statement->Operand; Control->IfrOpCode = Statement->IfrOpCode; Control->Selectable = Statement->Selectable; Control->ControlStyle.StyleType = GetStyleTypeByOpCode (Statement->Operand); Control->ControlStyle.PseudoClass = PseudoClass; return EFI_SUCCESS; } /** Update page up and page down items in setup page panel @param[in] SetupPagePanel A pointer to setup page panel @retval EFI_SUCCESS Update page up and page down items successful @retval EFI_INVALID_PARAMETER SetupPagePanel is NULL @retval EFI_NOT_FOUND Panel item is not found **/ STATIC EFI_STATUS UpdatePageUpPageDownItems ( IN H2O_LTDE_PANEL *SetupPagePanel ) { H2O_LTDE_PANEL_ITEM *ContentItem; H2O_LTDE_PANEL_ITEM *PageUpItem; H2O_LTDE_PANEL_ITEM *PageDownItem; BOOLEAN ErasePageUp; BOOLEAN ErasePageDown; EFI_STATUS Status; RECT *BorderLineFieldList; UINT32 BorderLineFieldCount; LTDE_PANEL_BORDER_LINE_INFO BorderLineInfo; if (SetupPagePanel == NULL) { return EFI_INVALID_PARAMETER; } ContentItem = GetPanelItem (SetupPagePanel, LTDE_PANEL_ITEM_ID_CONTENT); PageUpItem = GetPanelItem (SetupPagePanel, LTDE_PANEL_ITEM_ID_CONTENT_PAGE_UP); PageDownItem = GetPanelItem (SetupPagePanel, LTDE_PANEL_ITEM_ID_CONTENT_PAGE_DOWN); if (ContentItem == NULL || PageUpItem == NULL || PageDownItem == NULL) { return EFI_NOT_FOUND; } ErasePageUp = FALSE; PageUpItem->Hidden = (SetupPagePanel->BorderLineWidth == 0 || ContentItem->CurrentPos == 0) ? TRUE : FALSE; if (PageUpItem->Hidden) { ErasePageUp = TRUE; } else { DEConOutSetAttribute ((SetupPagePanel->ColorAttribute & 0xF0) | ARROW_TEXT); DisplayString ( PageUpItem->ItemField.left, PageUpItem->ItemField.top, PageUpItem->ControlList->Text.String ); } ErasePageDown = FALSE; if (SetupPagePanel->BorderLineWidth == 0 || (ContentItem->CurrentPos + H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField) - 1) >= ContentItem->MaxPos) { PageDownItem->Hidden = TRUE; } else { PageDownItem->Hidden = FALSE; } if (PageDownItem->Hidden) { ErasePageDown = TRUE; } else { DEConOutSetAttribute ((SetupPagePanel->ColorAttribute & 0xF0) | ARROW_TEXT); DisplayString ( PageDownItem->ItemField.left, PageDownItem->ItemField.top, PageDownItem->ControlList->Text.String );; } if ((ErasePageUp || ErasePageDown) && SetupPagePanel->BorderLineWidth != 0) { DEConOutSetAttribute (SetupPagePanel->BorderColorAttribute); Status = GetAllBorderLineField (&BorderLineFieldList, &BorderLineFieldCount); if (!EFI_ERROR (Status)) { Status = GetBorderLineInfo (&SetupPagePanel->PanelField, BorderLineFieldList, BorderLineFieldCount, &BorderLineInfo); if (!EFI_ERROR (Status)) { if (ErasePageUp) { DisplayString (SetupPagePanel->PanelField.left, SetupPagePanel->PanelField.top, BorderLineInfo.TopHorizonalLine); } if (ErasePageDown) { DisplayString (SetupPagePanel->PanelField.left, SetupPagePanel->PanelField.bottom, BorderLineInfo.BottomHorizonalLine); } SafeFreePool ((VOID **) &BorderLineInfo.TopHorizonalLine); SafeFreePool ((VOID **) &BorderLineInfo.BottomHorizonalLine); SafeFreePool ((VOID **) &BorderLineInfo.LeftVerticalLine); SafeFreePool ((VOID **) &BorderLineInfo.RightVerticalLine); } SafeFreePool ((VOID **) &BorderLineFieldList); } } return EFI_SUCCESS; } /** Set field of all controls in content item of setup page panel @param[in] SetupPagePanel A pointer to setup page panel @retval EFI_SUCCESS Set field successful @retval EFI_INVALID_PARAMETER ContentItem is NULL **/ STATIC EFI_STATUS SetContentItemControlField ( IN H2O_LTDE_PANEL_ITEM *ContentItem ) { UINT32 Index; INT32 ClientX; INT32 ClientY; UINT32 ContentItemWidth; UINT32 PromptWidth; UINT32 ValueWidth; H2O_LTDE_CONTROL *Control; INT32 ControlPromptWidth; INT32 ControlPromptHeight; INT32 ControlValueWidth; INT32 ControlValueHeight; if (ContentItem == NULL) { return EFI_INVALID_PARAMETER; } ContentItemWidth = (UINT32) H2O_LTDE_FIELD_WIDTH (&ContentItem->ItemField); PromptWidth = (ContentItemWidth - PROMPT_VALUE_SEPARATOR_WIDTH) / 2; ValueWidth = ContentItemWidth - PromptWidth - PROMPT_VALUE_SEPARATOR_WIDTH; ClientX = 0; ClientY = 0; for (Index = 0; Index < ContentItem->ControlCount; Index++) { Control = &ContentItem->ControlList[Index]; if (Control->ValueStrInfo.String == NULL) { ControlPromptWidth = ContentItemWidth; ControlValueWidth = 0; } else { ControlPromptWidth = PromptWidth; ControlValueWidth = ValueWidth; } ControlPromptHeight = GetStringHeight (Control->Text.String, ControlPromptWidth); SetRect ( &Control->Text.StringField, ClientX, ClientY, ClientX + ControlPromptWidth - 1, ClientY + ControlPromptHeight - 1 ); if (Control->ValueStrInfo.String != NULL) { ControlValueHeight = GetStringHeight (Control->ValueStrInfo.String, ControlValueWidth); SetRect ( &Control->ValueStrInfo.StringField, ClientX + PromptWidth + PROMPT_VALUE_SEPARATOR_WIDTH, ClientY, ClientX + ContentItemWidth - 1, ClientY + ControlValueHeight - 1 ); } else { ControlValueHeight = 0; } SetRect ( &Control->ControlField, ClientX, ClientY, ClientX + ContentItemWidth - 1, ClientY + MAX (ControlPromptHeight, ControlValueHeight) - 1 ); ClientY += MAX (ControlPromptHeight, ControlValueHeight); } ContentItem->MaxPos = (ClientY > 0) ? (ClientY - 1) : 0; return EFI_SUCCESS; } /** Initialize all controls in content item of setup page panel @param[in] SetupPagePanel A pointer to setup page panel @param[in, out] ContentItem A pointer to content item @retval EFI_SUCCESS Initialize all controls successful @retval EFI_INVALID_PARAMETER SetupPagePanel or ContentItem is NULL @retval EFI_OUT_OF_RESOURCES Allocate pool fail **/ STATIC EFI_STATUS InitSetupPagePanelContentItemControlList ( IN H2O_LTDE_PANEL *SetupPagePanel, IN OUT H2O_LTDE_PANEL_ITEM *ContentItem ) { EFI_STATUS Status; UINT32 Index; UINT32 Count; UINT32 ControlCount; H2O_LTDE_CONTROL *ControlList; H2O_FORM_BROWSER_S *Statement; if (SetupPagePanel == NULL || ContentItem == NULL) { return EFI_INVALID_PARAMETER; } ControlCount = mDEPrivate->FBProtocol->CurrentP->NumberOfStatementIds; ControlList = AllocateZeroPool (sizeof (H2O_LTDE_CONTROL) * ControlCount); if (ControlList == NULL) { return EFI_OUT_OF_RESOURCES; } Count = 0; for (Index = 0; Index < ControlCount; Index++) { Status = mDEPrivate->FBProtocol->GetSInfo ( mDEPrivate->FBProtocol, mDEPrivate->FBProtocol->CurrentP->PageId, mDEPrivate->FBProtocol->CurrentP->StatementIds[Index], &Statement ); if (EFI_ERROR (Status)) { continue; } Status = UpdateSetupPageControl (SetupPagePanel, ContentItem, Statement, &ControlList[Count]); SafeFreePool ((VOID **) &Statement); if (EFI_ERROR (Status)) { continue; } Count++; } ContentItem->Vertical = SetupPagePanel->Vertical; ContentItem->ControlCount = Count; ContentItem->ControlList = ControlList; SetContentItemControlField (ContentItem); return EFI_SUCCESS; } /** Initialize content item of setup page panel @param[in] SetupPagePanel A pointer to setup page panel @param[in, out] ContentItem A pointer to content item @retval EFI_SUCCESS Initialize content item successful @retval EFI_INVALID_PARAMETER SetupPagePanel or ContentItem is NULL **/ STATIC EFI_STATUS InitSetupPagePanelContentItem ( IN H2O_LTDE_PANEL *SetupPagePanel, IN OUT H2O_LTDE_PANEL_ITEM *ContentItem ) { H2O_LTDE_PANEL_ITEM *OrgContentItem; H2O_LTDE_CONTROL *Control; H2O_FORM_BROWSER_Q *CurrentQ; INT32 StartY; INT32 EndY; if (SetupPagePanel == NULL || ContentItem == NULL) { return EFI_INVALID_PARAMETER; } ContentItem->ItemId = LTDE_PANEL_ITEM_ID_CONTENT; ContentItem->Hidden = FALSE; CopyRect (&ContentItem->ItemField, &SetupPagePanel->PanelField); InflateRect (&ContentItem->ItemField, -SetupPagePanel->BorderLineWidth, -SetupPagePanel->BorderLineWidth); InitSetupPagePanelContentItemControlList (SetupPagePanel, ContentItem); // // If CurrentQ is exist and in the control list of ContentItem, update the CurrentPos and SelectedControl. // Control = NULL; CurrentQ = mDEPrivate->FBProtocol->CurrentQ; if (CurrentQ != NULL) { Control = GetControlByQuestionId ( ContentItem->ControlList, ContentItem->ControlCount, CurrentQ->QuestionId, CurrentQ->IfrOpCode ); if (Control != NULL) { if (IsCurrentHighlight (CurrentQ->PageId, CurrentQ->QuestionId, CurrentQ->IfrOpCode)) { Control->Sequence = SetupPagePanel->SelectedControl->Sequence; SetupPagePanel->SelectedControl = Control; OrgContentItem = GetPanelItem (SetupPagePanel, LTDE_PANEL_ITEM_ID_CONTENT); if (OrgContentItem != NULL) { ContentItem->CurrentPos = OrgContentItem->CurrentPos; } } else { SetupPagePanel->SelectedControl = Control; StartY = ContentItem->CurrentPos; EndY = StartY + H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField) - 1; if (!IN_RANGE (Control->ControlField.top, StartY, EndY) || !IN_RANGE (Control->ControlField.bottom, StartY, EndY)) { if (Control->ControlField.top <= ContentItem->CurrentPos) { ContentItem->CurrentPos = Control->ControlField.top; } else { ContentItem->CurrentPos = Control->ControlField.top - H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField) + 1; } } } return EFI_SUCCESS; } } // // CurrentQ is not exist or control not found, select a selectable question. // SetupPagePanel->SelectedControl = NULL; Control = GetSelectableControlInDisplayField (ContentItem, TRUE); if (Control == NULL) { return EFI_NOT_FOUND; } return SendSelectQNotify (Control->PageId, Control->QuestionId, Control->IfrOpCode); } /** Initialize control list in page up or page down item of setup page panel @param[in] SetupPagePanel A pointer to setup page panel @param[in, out] PageUpDownItem A pointer to page up or page down item @retval EFI_SUCCESS Initialize control list successful @retval EFI_INVALID_PARAMETER SetupPagePanel or PageUpDownItem is NULL @retval EFI_NOT_FOUND Hot key info is not found @retval EFI_OUT_OF_RESOURCES Allocate pool fail **/ STATIC EFI_STATUS InitSetupPagePanelContentPageUpDownItemControlList ( IN H2O_LTDE_PANEL *SetupPagePanel, IN OUT H2O_LTDE_PANEL_ITEM *PageUpDownItem ) { H2O_LTDE_CONTROL *Control; UINT32 HotKeyAction; LTDE_SETUP_PAGE_PANEL_HOT_KEY_INFO *HotKey; if (SetupPagePanel == NULL || PageUpDownItem == NULL) { return EFI_INVALID_PARAMETER; } HotKeyAction = (PageUpDownItem->ItemId == LTDE_PANEL_ITEM_ID_CONTENT_PAGE_UP) ? LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_PAGE_UP : LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_PAGE_DOWN; HotKey = GetSetupPageHotKeyInfo (HotKeyAction); if (HotKey == NULL) { return EFI_NOT_FOUND; } Control = AllocateZeroPool (sizeof (H2O_LTDE_CONTROL)); if (Control == NULL) { return EFI_OUT_OF_RESOURCES; } Control->Selectable = TRUE; Control->Text.String = AllocateCopyPool (StrSize(HotKey->String), HotKey->String); PageUpDownItem->ControlCount = 1; PageUpDownItem->ControlList = Control; return EFI_SUCCESS; } /** Initialize page up item of setup page panel @param[in] SetupPagePanel A pointer to setup page panel @param[in, out] PageUpItem A pointer to page up item @retval EFI_SUCCESS Initialize page up item successful @retval EFI_INVALID_PARAMETER SetupPagePanel or PageUpItem is NULL **/ STATIC EFI_STATUS InitSetupPagePanelContentPageUpItem ( IN H2O_LTDE_PANEL *SetupPagePanel, IN OUT H2O_LTDE_PANEL_ITEM *PageUpItem ) { if (SetupPagePanel == NULL || PageUpItem == NULL) { return EFI_INVALID_PARAMETER; } PageUpItem->ItemId = LTDE_PANEL_ITEM_ID_CONTENT_PAGE_UP; PageUpItem->Hidden = TRUE; CopyRect (&PageUpItem->ItemField, &SetupPagePanel->PanelField); PageUpItem->ItemField.left = PageUpItem->ItemField.right; PageUpItem->ItemField.bottom = PageUpItem->ItemField.top; InitSetupPagePanelContentPageUpDownItemControlList (SetupPagePanel, PageUpItem); return EFI_SUCCESS; } /** Initialize page down item of setup page panel @param[in] SetupPagePanel A pointer to setup page panel @param[in, out] PageUpItem A pointer to page down item @retval EFI_SUCCESS Initialize page down item successful @retval EFI_INVALID_PARAMETER SetupPagePanel or PageDownItem is NULL **/ STATIC EFI_STATUS InitSetupPagePanelContentPageDownItem ( IN H2O_LTDE_PANEL *SetupPagePanel, IN OUT H2O_LTDE_PANEL_ITEM *PageDownItem ) { if (SetupPagePanel == NULL || PageDownItem == NULL) { return EFI_INVALID_PARAMETER; } PageDownItem->ItemId = LTDE_PANEL_ITEM_ID_CONTENT_PAGE_DOWN; PageDownItem->Hidden = TRUE; CopyRect (&PageDownItem->ItemField, &SetupPagePanel->PanelField); PageDownItem->ItemField.left = PageDownItem->ItemField.right; PageDownItem->ItemField.top = PageDownItem->ItemField.bottom; InitSetupPagePanelContentPageUpDownItemControlList (SetupPagePanel, PageDownItem); return EFI_SUCCESS; } /** Initialize setup page panel @retval EFI_SUCCESS Initialize page down item successful @retval EFI_NOT_FOUND Setup page panel is not found @retval EFI_OUT_OF_RESOURCES Allocate pool fail **/ EFI_STATUS InitSetupPagePanel ( VOID ) { H2O_LTDE_PANEL *SetupPagePanel; UINT32 ItemCount; H2O_LTDE_PANEL_ITEM *ItemList; SetupPagePanel = GetPanel (SETUP_PAGE_PANEL_ID); if (SetupPagePanel == NULL) { return EFI_NOT_FOUND; } ItemCount = 3; ItemList = AllocateZeroPool (ItemCount * sizeof (H2O_LTDE_PANEL_ITEM)); if (ItemList == NULL) { return EFI_OUT_OF_RESOURCES; } InitSetupPagePanelContentItem (SetupPagePanel, &ItemList[0]); InitSetupPagePanelContentPageUpItem (SetupPagePanel, &ItemList[1]); InitSetupPagePanelContentPageDownItem (SetupPagePanel, &ItemList[2]); FreePanelItemList (SetupPagePanel->ItemList, SetupPagePanel->ItemCount); SetupPagePanel->ItemCount = ItemCount; SetupPagePanel->ItemList = ItemList; return EFI_SUCCESS; } /** Display control in setup page panel @param[in] SetupPagePanel A pointer to setup page panel @param[in] ContentItem A pointer to content item @param[in] Control A pointer to control @retval EFI_SUCCESS Display control successful @retval EFI_INVALID_PARAMETER Input parameter is NULL **/ EFI_STATUS DisplaySetupPagePanelContentItemControl ( IN H2O_LTDE_PANEL *SetupPagePanel, IN H2O_LTDE_PANEL_ITEM *ContentItem, IN H2O_LTDE_CONTROL *Control ) { EFI_STATUS Status; UINT32 Attribute; UINT32 Index; INT32 StartY; INT32 EndY; UINT32 ControlHeight; UINT32 PromptWidth; UINT32 PrmoptStrNum; CHAR16 **PrmoptStrArray; CHAR16 *PrmoptStr; UINT32 ValueWidth; UINT32 ValueStrNum; CHAR16 **ValueStrArray; CHAR16 *ValueStr; CHAR16 *SeparationStr; CHAR16 *DisplayStr; if (SetupPagePanel == NULL || ContentItem == NULL || Control == NULL) { return EFI_INVALID_PARAMETER; } StartY = ContentItem->CurrentPos; EndY = StartY + H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField) - 1; if (!IS_OVERLAP (Control->ControlField.top, Control->ControlField.bottom, StartY, EndY)) { return EFI_SUCCESS; } if (Control->Selectable && IsCurrentHighlight (Control->PageId, Control->QuestionId, Control->IfrOpCode)) { GetPanelColorAttribute (SetupPagePanel->VfcfPanelInfo, NULL, H2O_IFR_STYLE_TYPE_PANEL, H2O_STYLE_PSEUDO_CLASS_HIGHLIGHT , &Attribute); } else { GetPanelColorAttribute (SetupPagePanel->VfcfPanelInfo, NULL, H2O_IFR_STYLE_TYPE_PANEL, Control->ControlStyle.PseudoClass, &Attribute); } switch (Control->Operand) { case EFI_IFR_TIME_OP: case EFI_IFR_DATE_OP: return DateTimeOpCodeDisplayControl (SetupPagePanel, Control); case EFI_IFR_ORDERED_LIST_OP: return OrderListOpCodeDisplayValueStr (SetupPagePanel, ContentItem, Control); default: break; } PromptWidth = H2O_LTDE_FIELD_WIDTH (&Control->Text.StringField); Status = GetStringArrayByWidth (Control->Text.String, PromptWidth, &PrmoptStrNum, &PrmoptStrArray); if (EFI_ERROR (Status)) { return Status; } if (Control->ValueStrInfo.String != NULL) { ValueWidth = H2O_LTDE_FIELD_WIDTH (&Control->ValueStrInfo.StringField); Status = GetStringArrayByWidth (Control->ValueStrInfo.String, ValueWidth, &ValueStrNum, &ValueStrArray); if (EFI_ERROR (Status)) { ValueStrNum = 0; ValueStrArray = NULL; } } else { ValueWidth = 0; ValueStrNum = 0; ValueStrArray = NULL; } SeparationStr = CreateString (PROMPT_VALUE_SEPARATOR_WIDTH, ' '); ControlHeight = H2O_LTDE_FIELD_HEIGHT (&Control->ControlField); DEConOutSetAttribute (Attribute); for (Index = 0; Index < ControlHeight; Index++) { if (!IN_RANGE ((INT32) (Control->ControlField.top + Index), StartY, EndY)) { continue; } if (Index < PrmoptStrNum) { PrmoptStr = GetAlignmentString (PrmoptStrArray[Index], PromptWidth, LTDE_STRING_ALIGNMENT_ACTION_FLUSH_LEFT); } else { PrmoptStr = CreateString (PromptWidth, ' '); } if (Control->ValueStrInfo.String != NULL) { if (Index < ValueStrNum) { ValueStr = GetAlignmentString (ValueStrArray[Index], ValueWidth, LTDE_STRING_ALIGNMENT_ACTION_FLUSH_LEFT); } else { ValueStr = CreateString (ValueWidth, ' '); } DisplayStr = CatSPrint (NULL, L"%s%s%s", PrmoptStr, SeparationStr, ValueStr); FreePool (PrmoptStr); FreePool (ValueStr); } else { DisplayStr = PrmoptStr; } DisplayString ( ContentItem->ItemField.left, ContentItem->ItemField.top + (Control->ControlField.top - ContentItem->CurrentPos) + Index, DisplayStr ); FreePool (DisplayStr); } if (PrmoptStrArray != NULL) { for (Index = 0; Index < PrmoptStrNum; Index++) { FreePool (PrmoptStrArray[Index]); } FreePool (PrmoptStrArray); } if (ValueStrArray != NULL) { for (Index = 0; Index < ValueStrNum; Index++) { FreePool (ValueStrArray[Index]); } FreePool (ValueStrArray); } SafeFreePool ((VOID **) &SeparationStr); return EFI_SUCCESS; } /** Display content item in setup page panel @param[in] SetupPagePanel A pointer to setup page panel @param[in] ContentItem A pointer to content item @retval EFI_SUCCESS Display content item successful @retval EFI_INVALID_PARAMETER Input parameter is NULL **/ EFI_STATUS DisplaySetupPagePanelContentItem ( IN H2O_LTDE_PANEL *SetupPagePanel, IN H2O_LTDE_PANEL_ITEM *ContentItem ) { H2O_LTDE_CONTROL *Control; UINT32 Index; UINT32 EmptyHeight; RECT Field; if (SetupPagePanel == NULL || ContentItem == NULL) { return EFI_INVALID_PARAMETER; } if (ContentItem->ControlCount == 0) { ClearField (SetupPagePanel->ColorAttribute, &ContentItem->ItemField); return EFI_SUCCESS; } for (Index = 0; Index < ContentItem->ControlCount; Index++) { Control = &ContentItem->ControlList[Index]; DisplaySetupPagePanelContentItemControl (SetupPagePanel, ContentItem, Control); } if (ContentItem->CurrentPos + H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField) - 1 > ContentItem->MaxPos) { EmptyHeight = H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField) - (ContentItem->MaxPos - ContentItem->CurrentPos + 1); CopyRect (&Field, &ContentItem->ItemField); Field.top = Field.bottom - EmptyHeight + 1; ClearField (SetupPagePanel->ColorAttribute, &Field); } return EFI_SUCCESS; } /** Display setup page panel @retval EFI_SUCCESS Display setup page panel successful **/ EFI_STATUS DisplaySetupPagePanel ( VOID ) { H2O_LTDE_PANEL *SetupPagePanel; H2O_LTDE_PANEL_ITEM *ContentItem; SetupPagePanel = GetPanel (SETUP_PAGE_PANEL_ID); if (SetupPagePanel == NULL || !SetupPagePanel->Visible) { return EFI_SUCCESS; } ContentItem = GetPanelItem (SetupPagePanel, LTDE_PANEL_ITEM_ID_CONTENT); if (ContentItem != NULL) { DisplaySetupPagePanelContentItem (SetupPagePanel, ContentItem); } UpdatePageUpPageDownItems (SetupPagePanel); return EFI_SUCCESS; } /** Process select question event in setup page panel. @param[in] SetupPagePanel Pointer to setup page panel @param[in] SelectQ Pointer to select question event @retval EFI_SUCCESS Process select question event successful. @retval EFI_INVALID_PARAMETER SetupPagePanel or SelectQ is NULL. @retval EFI_NOT_FOUND Content item or control is not found. **/ EFI_STATUS SetupPagePanelProcessSelectQEvt ( IN H2O_LTDE_PANEL *SetupPagePanel, IN H2O_DISPLAY_ENGINE_EVT_SELECT_Q *SelectQ ) { H2O_LTDE_PANEL_ITEM *ContentItem; H2O_LTDE_CONTROL *OrgControl; H2O_LTDE_CONTROL *SelectQControl; INT32 StartY; INT32 EndY; if (SetupPagePanel == NULL || SelectQ == NULL) { return EFI_INVALID_PARAMETER; } ContentItem = GetPanelItem (SetupPagePanel, LTDE_PANEL_ITEM_ID_CONTENT); if (ContentItem == NULL) { return EFI_NOT_FOUND; } SelectQControl = GetControlByQuestionId ( ContentItem->ControlList, ContentItem->ControlCount, SelectQ->QuestionId, SelectQ->IfrOpCode ); if (SelectQControl == NULL) { return EFI_NOT_FOUND; } if (SelectQControl == SetupPagePanel->SelectedControl) { return EFI_SUCCESS; } OrgControl = SetupPagePanel->SelectedControl; if (OrgControl != NULL) { OrgControl->Sequence = 0; } SetupPagePanel->SelectedControl = SelectQControl; // // Update current position of ContentItem and refresh setup page if need. // StartY = ContentItem->CurrentPos; EndY = StartY + H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField) - 1; if (IN_RANGE (SelectQControl->ControlField.top, StartY, EndY) && IN_RANGE (SelectQControl->ControlField.bottom, StartY, EndY)) { DisplaySetupPagePanelContentItemControl (SetupPagePanel, ContentItem, OrgControl); DisplaySetupPagePanelContentItemControl (SetupPagePanel, ContentItem, SelectQControl); return EFI_SUCCESS; } if (SelectQControl->ControlField.top <= ContentItem->CurrentPos) { ContentItem->CurrentPos = SelectQControl->ControlField.top; } else { ContentItem->CurrentPos = SelectQControl->ControlField.bottom - H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField) + 1; } DisplaySetupPagePanel (); return EFI_SUCCESS; } /** Process select question hot key in setup page panel. @param[in] SetupPagePanel Pointer to setup page panel @param[in] GoNext TRUE if go to next control @retval EFI_SUCCESS Process select question hot key successful. @retval EFI_INVALID_PARAMETER SetupPagePanel is NULL. @retval EFI_NOT_FOUND Content item is not found. **/ EFI_STATUS SetupPagePanelProcessSelectQHotKey ( IN H2O_LTDE_PANEL *SetupPagePanel, IN BOOLEAN GoNext ) { H2O_LTDE_PANEL_ITEM *ContentItem; H2O_LTDE_CONTROL *Control; H2O_LTDE_CONTROL *NextControl; EFI_STATUS Status; INT32 StartY; INT32 EndY; UINT32 Index; BOOLEAN Loop; if (SetupPagePanel == NULL) { return EFI_INVALID_PARAMETER; } ContentItem = GetPanelItem (SetupPagePanel, LTDE_PANEL_ITEM_ID_CONTENT); if (ContentItem == NULL) { return EFI_NOT_FOUND; } StartY = ContentItem->CurrentPos; EndY = StartY + H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField) - 1; // // If it is ordered list, jump to next option value. // if (SetupPagePanel->SelectedControl != NULL && SetupPagePanel->SelectedControl->Operand == EFI_IFR_ORDERED_LIST_OP) { Status = OrderListOpCodeProcessSelectQHotKey (SetupPagePanel, ContentItem, GoNext); if (!EFI_ERROR(Status)) { return Status; } } // // If there is a next selectable control, jump to it. // Loop = FALSE; NextControl = GoNext ? GetNextSelectableControl (ContentItem, SetupPagePanel->SelectedControl, Loop) : GetPreviousSelectableControl (ContentItem, SetupPagePanel->SelectedControl, Loop); if (NextControl != NULL && ((IS_OVERLAP (NextControl->ControlField.top, NextControl->ControlField.bottom, StartY, EndY)) || (GoNext && NextControl->ControlField.top == EndY + 1) || ((!GoNext) && (NextControl->ControlField.bottom == (StartY - 1))))) { SendSelectQNotify (NextControl->PageId, NextControl->QuestionId, NextControl->IfrOpCode); return EFI_SUCCESS; } if (GoNext && EndY >= ContentItem->MaxPos || !GoNext && StartY == 0) { return EFI_SUCCESS; } // // Update current position to shift up/down in one control height and then refresh setup page. // NextControl = NULL; for (Index = 0; Index < ContentItem->ControlCount; Index++) { Control = &ContentItem->ControlList[Index]; if (GoNext && IN_RANGE(EndY, Control->ControlField.top, Control->ControlField.bottom)) { NextControl = (Index + 1 < ContentItem->ControlCount) ? &ContentItem->ControlList[Index + 1] : Control; break; } if (!GoNext && IN_RANGE(StartY, Control->ControlField.top, Control->ControlField.bottom)) { NextControl = Index > 0 ? &ContentItem->ControlList[Index - 1] : Control; break; } } if (NextControl == NULL) { return EFI_NOT_FOUND; } if (GoNext) { StartY = NextControl->ControlField.bottom - H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField) + 1; } else { StartY = NextControl->ControlField.top; } ContentItem->CurrentPos = StartY; EndY = StartY + H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField) - 1; if (!(SetupPagePanel->SelectedControl != NULL && SetupPagePanel->SelectedControl->Selectable && IS_OVERLAP (SetupPagePanel->SelectedControl->ControlField.top, SetupPagePanel->SelectedControl->ControlField.bottom, StartY, EndY))) { Control = GetFirstValidControlInDisplayField (ContentItem); if (Control != NULL) { SendSelectQNotify (Control->PageId, Control->QuestionId, Control->IfrOpCode); } } DisplaySetupPagePanel (); return EFI_SUCCESS; } /** Process open question hot key in setup page panel. @param[in] SetupPagePanel Pointer to setup page panel @param[in] Control Pointer to selected control or NULL means open current selected control @retval EFI_SUCCESS Process open question hot key successful. @retval EFI_INVALID_PARAMETER SetupPagePanel is NULL. @retval EFI_NOT_FOUND Selected control is not found. **/ EFI_STATUS SetupPagePanelProcessOpenQHotKey ( IN H2O_LTDE_PANEL *SetupPagePanel, IN H2O_LTDE_CONTROL *Control OPTIONAL ) { EFI_HII_VALUE HiiValue; H2O_LTDE_CONTROL *SelectedControl; if (SetupPagePanel == NULL) { return EFI_INVALID_PARAMETER; } if (Control == NULL) { // // If open current selected control, it should be in display field. Otherwise, do nothing. // SelectedControl = SetupPagePanel->SelectedControl; if (!IsControlInDisplayField (SetupPagePanel, SelectedControl)) { return EFI_ABORTED; } } else { SelectedControl = Control; } if (SelectedControl == NULL || !SelectedControl->Selectable) { return EFI_ABORTED; } switch (SelectedControl->Operand) { case EFI_IFR_ORDERED_LIST_OP: // // In original text UI design, don't pop dialog for these opcodes. // break; case EFI_IFR_DATE_OP: case EFI_IFR_TIME_OP: SelectedControl->Sequence = (SelectedControl->Sequence == 2) ? 0 : SelectedControl->Sequence + 1; DateTimeOpCodeDisplayControl ( SetupPagePanel, SelectedControl ); break; case EFI_IFR_CHECKBOX_OP: ZeroMem (&HiiValue, sizeof (EFI_HII_VALUE)); HiiValue.Type = EFI_IFR_TYPE_BOOLEAN; HiiValue.Value.b = (BOOLEAN) (SelectedControl->HiiValue.Value.b ? FALSE : TRUE); return SendChangeQNotify (SelectedControl->PageId, SelectedControl->QuestionId, &HiiValue); default: return SendOpenQNotify (SelectedControl->PageId, SelectedControl->QuestionId, SelectedControl->IfrOpCode); } return EFI_SUCCESS; } /** Process change question hot key in setup page panel. @param[in] SetupPagePanel Pointer to setup page panel @param[in] Increase TRUE if increase question value @retval EFI_SUCCESS Process change question hot key successful. @retval EFI_INVALID_PARAMETER SetupPagePanel is NULL. @retval EFI_NOT_FOUND Selected control is not found. **/ EFI_STATUS SetupPagePanelProcessChangeQHotKey ( IN H2O_LTDE_PANEL *SetupPagePanel, IN BOOLEAN Increase ) { EFI_STATUS Status; H2O_LTDE_CONTROL *SelectedControl; EFI_TIME EfiTime; EFI_HII_VALUE HiiValue; if (SetupPagePanel == NULL) { return EFI_INVALID_PARAMETER; } if (SetupPagePanel->SelectedControl == NULL) { return EFI_NOT_FOUND; } if (!IsControlInDisplayField (SetupPagePanel, SetupPagePanel->SelectedControl)) { return EFI_ABORTED; } SelectedControl = SetupPagePanel->SelectedControl; switch (SelectedControl->Operand) { case EFI_IFR_DATE_OP: case EFI_IFR_TIME_OP: TransferHiiValueToEfiTime (&SelectedControl->HiiValue, &EfiTime); Status = GetNextDateTimeValue ( DateTimeOpCodeGetItemValue (SelectedControl), Increase, &EfiTime ); if (EFI_ERROR (Status)) { return Status; } TransferEfiTimeToHiiValue (SelectedControl->Operand == EFI_IFR_DATE_OP, &EfiTime, &HiiValue); SendChangeQNotify (SelectedControl->PageId, SelectedControl->QuestionId, &HiiValue); break; case EFI_IFR_ORDERED_LIST_OP: return OrderListOpCodeShiftOrder (SelectedControl, !Increase); default: Status = GetNextQuestionValue (mDEPrivate->FBProtocol->CurrentQ, Increase, &HiiValue); if (EFI_ERROR (Status)) { break; } return SendChangeQNotify (SelectedControl->PageId, SelectedControl->QuestionId, &HiiValue); } return Status; } /** Process hot key in setup page panel. @param[in] UserInputKey Pointer to user input data @retval EFI_SUCCESS Process hot key successful. @retval EFI_INVALID_PARAMETER UserInputKey is NULL. @retval EFI_NOT_FOUND setup page panel is not found or user input key is not hot key of setup page panel. **/ EFI_STATUS SetupPagePanelProcessHotKey ( IN EFI_INPUT_KEY *UserInputKey ) { H2O_LTDE_PANEL *SetupPagePanel; H2O_LTDE_PANEL_ITEM *ContentItem; EFI_INPUT_KEY InputKey; UINT32 Index; UINT32 Count; UINT32 HotKeyAction; INT32 ContentItemHeight; BOOLEAN GetFirst; INT32 OrgPos; H2O_LTDE_CONTROL *Control; if (UserInputKey == NULL) { return EFI_INVALID_PARAMETER; } SetupPagePanel = GetPanel (SETUP_PAGE_PANEL_ID); if (SetupPagePanel == NULL || !SetupPagePanel->Visible) { return EFI_NOT_FOUND; } ContentItem = GetPanelItem (SetupPagePanel, LTDE_PANEL_ITEM_ID_CONTENT); if (ContentItem == NULL) { return EFI_NOT_FOUND; } CopyMem (&InputKey, UserInputKey, sizeof (EFI_INPUT_KEY)); InputKey.UnicodeChar = TO_LOWER_UNICODE_CHAR (InputKey.UnicodeChar); HotKeyAction = LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_MAX; Count = sizeof (mSetupPagePanelHotKeyInfoList) / sizeof (LTDE_SETUP_PAGE_PANEL_HOT_KEY_INFO); for (Index = 0; Index < Count; Index++) { if (mSetupPagePanelHotKeyInfoList[Index].InputKey.ScanCode == InputKey.ScanCode && mSetupPagePanelHotKeyInfoList[Index].InputKey.UnicodeChar == InputKey.UnicodeChar) { HotKeyAction = mSetupPagePanelHotKeyInfoList[Index].Action; break; } } if (Index == Count) { return EFI_NOT_FOUND; } GetFirst = TRUE; OrgPos = ContentItem->CurrentPos; ContentItemHeight = H2O_LTDE_FIELD_HEIGHT (&ContentItem->ItemField); switch (HotKeyAction) { case LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_PAGE_UP: case LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_PAGE_DOWN: GetFirst = (HotKeyAction == LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_PAGE_UP) ? TRUE : FALSE; Control = GetSelectableControlInDisplayField (ContentItem, GetFirst); if (Control != NULL && Control != SetupPagePanel->SelectedControl) { return SendSelectQNotify (Control->PageId, Control->QuestionId, Control->IfrOpCode); } if (HotKeyAction == LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_PAGE_UP) { ContentItem->CurrentPos = (ContentItem->CurrentPos > ContentItemHeight) ? (ContentItem->CurrentPos - ContentItemHeight) : 0; } else { if (ContentItem->MaxPos > ContentItem->CurrentPos + ContentItemHeight - 1) { ContentItem->CurrentPos = ContentItem->CurrentPos + ContentItemHeight; } } break; case LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_HOME: case LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_END: if (HotKeyAction == LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_HOME) { GetFirst = TRUE; ContentItem->CurrentPos = 0; } else { GetFirst = FALSE; ContentItem->CurrentPos = (ContentItem->MaxPos > ContentItem->CurrentPos + ContentItemHeight - 1) ? (ContentItem->MaxPos - ContentItemHeight + 1) : OrgPos; } break; } Control = GetSelectableControlInDisplayField (ContentItem, GetFirst); if (Control == NULL) { Control = GetFirstValidControlInDisplayField (ContentItem); } if (Control != NULL && Control != SetupPagePanel->SelectedControl) { SendSelectQNotify (Control->PageId, Control->QuestionId, Control->IfrOpCode); } if (ContentItem->CurrentPos != OrgPos) { DisplaySetupPagePanel (); } return EFI_SUCCESS; } /** Process mouse click in setup page panel. @param[in] SetupPagePanel Pointer to setup page panel @param[in] SelectedPanelItem Pointer to selected panel item @param[in] SelectedControl Pointer to selected control @param[in] UserInputData Pointer to user input data @retval EFI_SUCCESS Process hot key successful. @retval EFI_INVALID_PARAMETER Input parameter is NULL. @retval EFI_UNSUPPORTED Selected control is not selectable. **/ EFI_STATUS SetupPagePanelProcessMouseClick ( IN H2O_LTDE_PANEL *SetupPagePanel, IN H2O_LTDE_PANEL_ITEM *SelectedPanelItem, IN H2O_LTDE_CONTROL *SelectedControl, IN H2O_DISPLAY_ENGINE_USER_INPUT_DATA *UserInputData ) { UINT32 Index; UINT32 Action; HOT_KEY_INFO HotKey; if (SetupPagePanel == NULL || SelectedPanelItem == NULL || SelectedControl == NULL) { return EFI_INVALID_PARAMETER; } if (!SelectedControl->Selectable) { return EFI_UNSUPPORTED; } switch (SelectedPanelItem->ItemId) { case LTDE_PANEL_ITEM_ID_CONTENT: if (SelectedControl->Operand == EFI_IFR_ORDERED_LIST_OP) { OrderListOpCodeProcessMouseClick (SetupPagePanel, SelectedPanelItem, SelectedControl, UserInputData); } if (SelectedControl->PageId == SetupPagePanel->SelectedControl->PageId && SelectedControl->QuestionId == SetupPagePanel->SelectedControl->QuestionId && SelectedControl->IfrOpCode == SetupPagePanel->SelectedControl->IfrOpCode) { ZeroMem (&HotKey, sizeof (HOT_KEY_INFO)); HotKey.HotKeyAction = HotKeyEnter; return SendEvtByHotKey (&HotKey); } else { return SendSelectQNotify (SelectedControl->PageId, SelectedControl->QuestionId, SelectedControl->IfrOpCode); } break; case LTDE_PANEL_ITEM_ID_CONTENT_PAGE_UP: case LTDE_PANEL_ITEM_ID_CONTENT_PAGE_DOWN: Action = (SelectedPanelItem->ItemId == LTDE_PANEL_ITEM_ID_CONTENT_PAGE_UP) ? LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_PAGE_UP : LTDE_SETUP_PAGE_PANEL_HOT_KEY_ACTION_PAGE_DOWN; for (Index = 0; Index < sizeof (mSetupPagePanelHotKeyInfoList) / sizeof (LTDE_SETUP_PAGE_PANEL_HOT_KEY_INFO); Index++) { if (mSetupPagePanelHotKeyInfoList[Index].Action == Action) { SetupPagePanelProcessHotKey (&mSetupPagePanelHotKeyInfoList[Index].InputKey); break; } } break; default: return EFI_UNSUPPORTED; } return EFI_SUCCESS; }