UI_MENU_OPTION *SavedMenuOption;\r
UINTN TmpValue;\r
\r
+ TmpValue = 0;\r
TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT;\r
BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;\r
\r
UpdateOptionSkipLines (SavedMenuOption);\r
\r
//\r
- // If highlight opcode is date/time, keep the highlight row info not change.\r
+ // FormRefreshEvent != NULL means this form will auto exit at an interval, display engine \r
+ // will try to keep highlight on the current position after this form exit and re-enter.\r
//\r
- if ((SavedMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP || SavedMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP) &&\r
- (gHighligthMenuInfo.QuestionId != 0) && \r
- (gHighligthMenuInfo.QuestionId == GetQuestionIdInfo(SavedMenuOption->ThisTag->OpCode))) {\r
- //\r
- // Still show the highlight menu before exit from display engine.\r
- //\r
- BottomRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;\r
+ // HiiHandle + QuestionId can find the only one question in the system.\r
+ //\r
+ // If this question has question id, save the question id info to find the question.\r
+ // else save the opcode buffer to find it.\r
+ //\r
+ if (gFormData->FormRefreshEvent != NULL && gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle) {\r
+ if (gHighligthMenuInfo.QuestionId != 0) { \r
+ if (gHighligthMenuInfo.QuestionId == GetQuestionIdInfo(SavedMenuOption->ThisTag->OpCode)) {\r
+ BottomRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;\r
+ //\r
+ // SkipValue only used for menu at the top of the form.\r
+ // If Highlight menu is not at the top, this value will be update later.\r
+ //\r
+ TmpValue = gHighligthMenuInfo.SkipValue;\r
+ }\r
+ } else if (gHighligthMenuInfo.OpCode != NULL){\r
+ if (!CompareMem (gHighligthMenuInfo.OpCode, SavedMenuOption->ThisTag->OpCode, gHighligthMenuInfo.OpCode->Length)) {\r
+ BottomRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;\r
+ //\r
+ // SkipValue only used for menu at the top of the form.\r
+ // If Highlight menu is not at the top, this value will be update later.\r
+ //\r
+ TmpValue = gHighligthMenuInfo.SkipValue;\r
+ }\r
+ }\r
}\r
\r
if (SavedMenuOption->Skip >= BottomRow - TopRow) {\r
- TmpValue = 0;\r
*TopOfScreen = NewPos;\r
} else {\r
*TopOfScreen = FindTopOfScreenMenu(NewPos, BottomRow - TopRow - SavedMenuOption->Skip, &TmpValue);\r
}\r
+ AdjustDateAndTimePosition(TRUE, TopOfScreen);\r
\r
*SkipValue = TmpValue;\r
}\r
Update highlight menu info.\r
\r
@param MenuOption The menu opton which is highlight.\r
+ @param SkipValue The skipvalue info for this menu.\r
+ SkipValue only used for the menu at the top of the form.\r
\r
**/\r
VOID\r
UpdateHighlightMenuInfo (\r
- IN UI_MENU_OPTION *MenuOption\r
+ IN UI_MENU_OPTION *MenuOption,\r
+ IN UINTN SkipValue\r
)\r
{\r
FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
gSequence = (UINT16) MenuOption->Sequence;\r
\r
//\r
- // Record highlight row info for date/time opcode.\r
+ // FormRefreshEvent != NULL means this form will auto exit at an interval, display engine \r
+ // will try to keep highlight on the current position after this form exit and re-enter.\r
//\r
- if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
+ // HiiHandle + QuestionId can find the only one question in the system.\r
+ //\r
+ // If this question has question id, base on the question id info to find the question.\r
+ // else base on the opcode buffer to find it.\r
+ //\r
+ if (gFormData->FormRefreshEvent != NULL) {\r
+ gHighligthMenuInfo.HiiHandle = gFormData->HiiHandle;\r
gHighligthMenuInfo.QuestionId = GetQuestionIdInfo(Statement->OpCode);\r
+\r
+ //\r
+ // if question id == 0, save the opcode buffer for later use.\r
+ //\r
+ if (gHighligthMenuInfo.QuestionId == 0) {\r
+ if (gHighligthMenuInfo.OpCode != NULL) {\r
+ FreePool (gHighligthMenuInfo.OpCode);\r
+ }\r
+ gHighligthMenuInfo.OpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode);\r
+ ASSERT (gHighligthMenuInfo.OpCode != NULL);\r
+ }\r
gHighligthMenuInfo.DisplayRow = (UINT16) MenuOption->Row;\r
+ gHighligthMenuInfo.SkipValue = (UINT16) SkipValue;\r
} else {\r
+ gHighligthMenuInfo.HiiHandle = NULL;\r
gHighligthMenuInfo.QuestionId = 0;\r
+ if (gHighligthMenuInfo.OpCode != NULL) {\r
+ FreePool (gHighligthMenuInfo.OpCode);\r
+ gHighligthMenuInfo.OpCode = NULL;\r
+ }\r
gHighligthMenuInfo.DisplayRow = 0;\r
+ gHighligthMenuInfo.SkipValue = 0;\r
}\r
\r
RefreshKeyHelp(gFormData, Statement, FALSE);\r
if (SkipHighLight) {\r
MenuOption = SavedMenuOption;\r
SkipHighLight = FALSE;\r
- UpdateHighlightMenuInfo (MenuOption);\r
+ UpdateHighlightMenuInfo (MenuOption, TopOfScreen == &MenuOption->Link ? SkipValue : 0);\r
break;\r
}\r
\r
MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
Statement = MenuOption->ThisTag;\r
\r
- UpdateHighlightMenuInfo (MenuOption);\r
+ UpdateHighlightMenuInfo (MenuOption, Temp2);\r
\r
if (!IsSelectable (MenuOption)) {\r
break;\r
VOID\r
)\r
{\r
- CHAR16 *ErrorInfo;\r
- EFI_INPUT_KEY Key;\r
+ CHAR16 *ErrorInfo;\r
+ EFI_INPUT_KEY Key;\r
+ EFI_EVENT WaitList[2];\r
+ EFI_EVENT RefreshIntervalEvent;\r
+ EFI_EVENT TimeOutEvent;\r
+ UINT8 TimeOut;\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ WARNING_IF_CONTEXT EventContext;\r
+ EFI_IFR_OP_HEADER *OpCodeBuf;\r
+ EFI_STRING_ID StringToken;\r
\r
if (gFormData->BrowserStatus == BROWSER_SUCCESS) {\r
return;\r
}\r
\r
- if (gFormData->ErrorString != NULL) {\r
+ StringToken = 0;\r
+ TimeOutEvent = NULL;\r
+ RefreshIntervalEvent = NULL;\r
+ OpCodeBuf = NULL;\r
+ if (gFormData->HighLightedStatement != NULL) {\r
+ OpCodeBuf = gFormData->HighLightedStatement->OpCode;\r
+ }\r
+\r
+ if (gFormData->BrowserStatus == (BROWSER_WARNING_IF)) {\r
+ ASSERT (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_WARNING_IF_OP);\r
+\r
+ TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeBuf)->TimeOut;\r
+ StringToken = ((EFI_IFR_WARNING_IF *) OpCodeBuf)->Warning;\r
+ } else {\r
+ TimeOut = 0;\r
+ if ((gFormData->BrowserStatus == (BROWSER_NO_SUBMIT_IF)) &&\r
+ (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_NO_SUBMIT_IF_OP)) {\r
+ StringToken = ((EFI_IFR_NO_SUBMIT_IF *) OpCodeBuf)->Error;\r
+ } else if ((gFormData->BrowserStatus == (BROWSER_INCONSISTENT_IF)) &&\r
+ (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_INCONSISTENT_IF_OP)) {\r
+ StringToken = ((EFI_IFR_INCONSISTENT_IF *) OpCodeBuf)->Error;\r
+ }\r
+ }\r
+\r
+ if (StringToken != 0) {\r
+ ErrorInfo = GetToken (StringToken, gFormData->HiiHandle);\r
+ } else if (gFormData->ErrorString != NULL) {\r
+ //\r
+ // Only used to compatible with old setup browser.\r
+ // Not use this field in new browser core.\r
+ //\r
ErrorInfo = gFormData->ErrorString;\r
} else {\r
switch (gFormData->BrowserStatus) {\r
ErrorInfo = gSaveFailed;\r
break;\r
\r
- case BROWSER_NO_SUBMIT_IF:\r
- ErrorInfo = gNoSubmitIf;\r
- break;\r
-\r
case BROWSER_FORM_NOT_FOUND:\r
ErrorInfo = gFormNotFound;\r
break;\r
}\r
}\r
\r
- //\r
- // Error occur, prompt error message.\r
- //\r
- do {\r
- CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);\r
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+ if (TimeOut == 0) {\r
+ do {\r
+ CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);\r
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+ } else {\r
+ Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_CALLBACK, EmptyEventProcess, NULL, &TimeOutEvent);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ EventContext.SyncEvent = TimeOutEvent;\r
+ EventContext.TimeOut = &TimeOut;\r
+ EventContext.ErrorInfo = ErrorInfo;\r
+\r
+ Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshTimeOutProcess, &EventContext, &RefreshIntervalEvent);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Show the dialog first to avoid long time not reaction.\r
+ //\r
+ gBS->SignalEvent (RefreshIntervalEvent);\r
+\r
+ Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, ONE_SECOND);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ while (TRUE) {\r
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+ if (!EFI_ERROR (Status) && Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
+ break;\r
+ }\r
+\r
+ if (Status != EFI_NOT_READY) {\r
+ continue;\r
+ }\r
+\r
+ WaitList[0] = TimeOutEvent;\r
+ WaitList[1] = gST->ConIn->WaitForKey;\r
+\r
+ Status = gBS->WaitForEvent (2, WaitList, &Index);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ if (Index == 0) {\r
+ //\r
+ // Timeout occur, close the hoot time out event.\r
+ //\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ gBS->CloseEvent (TimeOutEvent);\r
+ gBS->CloseEvent (RefreshIntervalEvent);\r
+\r
+ if (StringToken != 0) {\r
+ FreePool (ErrorInfo);\r
+ }\r
}\r
\r
/**\r
\r
FreeDisplayStrings ();\r
\r
+ if (gHighligthMenuInfo.OpCode != NULL) {\r
+ FreePool (gHighligthMenuInfo.OpCode);\r
+ }\r
+\r
return EFI_SUCCESS;\r
}\r