From bfae1330cc2e7749fcf349a3a633e2e77f5f01c9 Mon Sep 17 00:00:00 2001 From: Eric Dong Date: Tue, 15 Apr 2014 15:38:48 +0000 Subject: Update question validation logic, move the check pointer from after user input to after finish call the CHANGING callback. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Eric Dong Reviewed-by: Liming, Gao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15468 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/DisplayEngineDxe/FormDisplay.c | 109 +++++++++++++-- .../Universal/DisplayEngineDxe/FormDisplay.h | 34 ++++- .../Universal/DisplayEngineDxe/InputHandler.c | 4 +- .../Universal/DisplayEngineDxe/ProcessOptions.c | 149 +-------------------- 4 files changed, 128 insertions(+), 168 deletions(-) (limited to 'MdeModulePkg/Universal/DisplayEngineDxe') diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c index fe3d875..df0fbfe 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c +++ b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c @@ -3197,14 +3197,53 @@ BrowserStatusProcess ( VOID ) { - CHAR16 *ErrorInfo; - EFI_INPUT_KEY Key; + CHAR16 *ErrorInfo; + EFI_INPUT_KEY Key; + EFI_EVENT WaitList[2]; + EFI_EVENT RefreshIntervalEvent; + EFI_EVENT TimeOutEvent; + UINT8 TimeOut; + EFI_STATUS Status; + UINTN Index; + WARNING_IF_CONTEXT EventContext; + EFI_IFR_OP_HEADER *OpCodeBuf; + EFI_STRING_ID StringToken; if (gFormData->BrowserStatus == BROWSER_SUCCESS) { return; } - if (gFormData->ErrorString != NULL) { + StringToken = 0; + TimeOutEvent = NULL; + RefreshIntervalEvent = NULL; + OpCodeBuf = NULL; + if (gFormData->HighLightedStatement != NULL) { + OpCodeBuf = gFormData->HighLightedStatement->OpCode; + } + + if (gFormData->BrowserStatus == (BROWSER_WARNING_IF)) { + ASSERT (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_WARNING_IF_OP); + + TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeBuf)->TimeOut; + StringToken = ((EFI_IFR_WARNING_IF *) OpCodeBuf)->Warning; + } else { + TimeOut = 0; + if ((gFormData->BrowserStatus == (BROWSER_NO_SUBMIT_IF)) && + (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_NO_SUBMIT_IF_OP)) { + StringToken = ((EFI_IFR_NO_SUBMIT_IF *) OpCodeBuf)->Error; + } else if ((gFormData->BrowserStatus == (BROWSER_INCONSISTENT_IF)) && + (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_INCONSISTENT_IF_OP)) { + StringToken = ((EFI_IFR_INCONSISTENT_IF *) OpCodeBuf)->Error; + } + } + + if (StringToken != 0) { + ErrorInfo = GetToken (StringToken, gFormData->HiiHandle); + } else if (gFormData->ErrorString != NULL) { + // + // Only used to compatible with old setup browser. + // Not use this field in new browser core. + // ErrorInfo = gFormData->ErrorString; } else { switch (gFormData->BrowserStatus) { @@ -3212,10 +3251,6 @@ BrowserStatusProcess ( ErrorInfo = gSaveFailed; break; - case BROWSER_NO_SUBMIT_IF: - ErrorInfo = gNoSubmitIf; - break; - case BROWSER_FORM_NOT_FOUND: ErrorInfo = gFormNotFound; break; @@ -3234,12 +3269,60 @@ BrowserStatusProcess ( } } - // - // Error occur, prompt error message. - // - do { - CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL); - } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + if (TimeOut == 0) { + do { + CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + } else { + Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_CALLBACK, EmptyEventProcess, NULL, &TimeOutEvent); + ASSERT_EFI_ERROR (Status); + + EventContext.SyncEvent = TimeOutEvent; + EventContext.TimeOut = &TimeOut; + EventContext.ErrorInfo = ErrorInfo; + + Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshTimeOutProcess, &EventContext, &RefreshIntervalEvent); + ASSERT_EFI_ERROR (Status); + + // + // Show the dialog first to avoid long time not reaction. + // + gBS->SignalEvent (RefreshIntervalEvent); + + Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, ONE_SECOND); + ASSERT_EFI_ERROR (Status); + + while (TRUE) { + Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + if (!EFI_ERROR (Status) && Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { + break; + } + + if (Status != EFI_NOT_READY) { + continue; + } + + WaitList[0] = TimeOutEvent; + WaitList[1] = gST->ConIn->WaitForKey; + + Status = gBS->WaitForEvent (2, WaitList, &Index); + ASSERT_EFI_ERROR (Status); + + if (Index == 0) { + // + // Timeout occur, close the hoot time out event. + // + break; + } + } + } + + gBS->CloseEvent (TimeOutEvent); + gBS->CloseEvent (RefreshIntervalEvent); + + if (StringToken != 0) { + FreePool (ErrorInfo); + } } /** diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h index a0638ca..3f045cc 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h +++ b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h @@ -201,6 +201,12 @@ typedef struct { UINT16 SkipValue; } DISPLAY_HIGHLIGHT_MENU_INFO; +typedef struct { + EFI_EVENT SyncEvent; + UINT8 *TimeOut; + CHAR16 *ErrorInfo; +} WARNING_IF_CONTEXT; + #define UI_MENU_OPTION_SIGNATURE SIGNATURE_32 ('u', 'i', 'm', 'm') typedef struct { @@ -576,17 +582,31 @@ ExitDisplay ( ); /** - Process validate for one question. + Process nothing. - @param Question The question which need to validate. + @param Event The Event need to be process + @param Context The context of the event. - @retval EFI_SUCCESS Question Option process success. - @retval Other Question Option process fail. +**/ +VOID +EFIAPI +EmptyEventProcess ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Process for the refresh interval statement. + + @param Event The Event need to be process + @param Context The context of the event. **/ -EFI_STATUS -ValidateQuestion ( - IN FORM_DISPLAY_ENGINE_STATEMENT *Question +VOID +EFIAPI +RefreshTimeOutProcess ( + IN EFI_EVENT Event, + IN VOID *Context ); #endif diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c b/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c index a58e12f..78dd104 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c +++ b/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c @@ -872,7 +872,7 @@ EnterCarriageReturn: AdjustQuestionValue (QuestionValue, (UINT8)MenuOption->Sequence); } - return ValidateQuestion (Question); + return EFI_SUCCESS; break; case CHAR_BACKSPACE: @@ -1520,7 +1520,7 @@ TheKey: gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute); - return ValidateQuestion (Question); + return EFI_SUCCESS; default: break; diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c index 8da563b..1ab38b1 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c +++ b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c @@ -15,12 +15,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "FormDisplay.h" -typedef struct { - EFI_EVENT SyncEvent; - UINT8 *TimeOut; - CHAR16 *ErrorInfo; -} WARNING_IF_CONTEXT; - #define MAX_TIME_OUT_LEN 0x10 /** @@ -668,143 +662,6 @@ RefreshTimeOutProcess ( } /** - Show the warning message. - - @param RetInfo The input warning string and timeout info. - -**/ -VOID -WarningIfCheck ( - IN STATEMENT_ERROR_INFO *RetInfo - ) -{ - CHAR16 *ErrorInfo; - EFI_EVENT WaitList[2]; - EFI_EVENT RefreshIntervalEvent; - EFI_EVENT TimeOutEvent; - UINT8 TimeOut; - EFI_STATUS Status; - UINTN Index; - WARNING_IF_CONTEXT EventContext; - EFI_INPUT_KEY Key; - - TimeOutEvent = NULL; - RefreshIntervalEvent = NULL; - - ASSERT (RetInfo->StringId != 0); - ErrorInfo = GetToken (RetInfo->StringId, gFormData->HiiHandle); - TimeOut = RetInfo->TimeOut; - if (RetInfo->TimeOut == 0) { - do { - CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL); - } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); - } else { - Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_CALLBACK, EmptyEventProcess, NULL, &TimeOutEvent); - ASSERT_EFI_ERROR (Status); - - EventContext.SyncEvent = TimeOutEvent; - EventContext.TimeOut = &TimeOut; - EventContext.ErrorInfo = ErrorInfo; - - Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshTimeOutProcess, &EventContext, &RefreshIntervalEvent); - ASSERT_EFI_ERROR (Status); - - // - // Show the dialog first to avoid long time not reaction. - // - gBS->SignalEvent (RefreshIntervalEvent); - - Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, ONE_SECOND); - ASSERT_EFI_ERROR (Status); - - while (TRUE) { - Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); - if (!EFI_ERROR (Status) && Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { - break; - } - - if (Status != EFI_NOT_READY) { - continue; - } - - WaitList[0] = TimeOutEvent; - WaitList[1] = gST->ConIn->WaitForKey; - - Status = gBS->WaitForEvent (2, WaitList, &Index); - ASSERT_EFI_ERROR (Status); - - if (Index == 0) { - // - // Timeout occur, close the hoot time out event. - // - break; - } - } - } - - gBS->CloseEvent (TimeOutEvent); - gBS->CloseEvent (RefreshIntervalEvent); - - FreePool (ErrorInfo); -} - -/** - Process validate for one question. - - @param Question The question need to be validate. - - @retval EFI_SUCCESS Question Option process success. - @retval EFI_INVALID_PARAMETER Question Option process fail. - -**/ -EFI_STATUS -ValidateQuestion ( - IN FORM_DISPLAY_ENGINE_STATEMENT *Question - ) -{ - CHAR16 *ErrorInfo; - EFI_INPUT_KEY Key; - EFI_STATUS Status; - STATEMENT_ERROR_INFO RetInfo; - UINT32 RetVal; - - if (Question->ValidateQuestion == NULL) { - return EFI_SUCCESS; - } - - Status = EFI_SUCCESS; - RetVal = Question->ValidateQuestion(gFormData, Question, &gUserInput->InputValue, &RetInfo); - - switch (RetVal) { - case INCOSISTENT_IF_TRUE: - // - // Condition meet, show up error message - // - ASSERT (RetInfo.StringId != 0); - ErrorInfo = GetToken (RetInfo.StringId, gFormData->HiiHandle); - do { - CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL); - } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); - FreePool (ErrorInfo); - - Status = EFI_INVALID_PARAMETER; - break; - - case WARNING_IF_TRUE: - // - // Condition meet, show up warning message - // - WarningIfCheck (&RetInfo); - break; - - default: - break; - } - - return Status; -} - -/** Display error message for invalid password. **/ @@ -935,7 +792,7 @@ PasswordProcess ( gUserInput->InputValue.Value.string = HiiSetString(gFormData->HiiHandle, gUserInput->InputValue.Value.string, StringPtr, NULL); FreePool (StringPtr); - Status = ValidateQuestion (Question); + Status = EFI_SUCCESS; if (EFI_ERROR (Status)) { // @@ -1277,7 +1134,7 @@ ProcessOptions ( // // Perform inconsistent check // - return ValidateQuestion (Question); + return EFI_SUCCESS; } else { *OptionString = AllocateZeroPool (BufferSize); ASSERT (*OptionString); @@ -1397,7 +1254,7 @@ ProcessOptions ( gUserInput->InputValue.Type = Question->CurrentValue.Type; gUserInput->InputValue.Value.string = HiiSetString(gFormData->HiiHandle, gUserInput->InputValue.Value.string, StringPtr, NULL); FreePool (StringPtr); - return ValidateQuestion (Question); + return EFI_SUCCESS; } else { *OptionString = AllocateZeroPool (BufferSize); ASSERT (*OptionString); -- cgit v1.1