]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c
MdeModulePkg:Support delete key
[mirror_edk2.git] / MdeModulePkg / Universal / DisplayEngineDxe / ProcessOptions.c
index 8da563ba700cc7ee3a5ffbe7a20ccdf53b498c4f..84ae03eea70fb3d01b6f361ddd3efd02b5904cb1 100644 (file)
@@ -2,7 +2,7 @@
 Implementation for handling the User Interface option processing.\r
 \r
 \r
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -15,12 +15,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "FormDisplay.h"\r
 \r
-typedef struct {\r
-  EFI_EVENT   SyncEvent;\r
-  UINT8       *TimeOut;\r
-  CHAR16      *ErrorInfo;\r
-} WARNING_IF_CONTEXT;\r
-\r
 #define MAX_TIME_OUT_LEN  0x10\r
 \r
 /**\r
@@ -104,6 +98,107 @@ HiiValueToUINT64 (
   return RetVal;\r
 }\r
 \r
+/**\r
+  Check whether this value type can be transfer to EFI_IFR_TYPE_BUFFER type.\r
+  \r
+  EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to \r
+  EFI_IFR_TYPE_BUFFER when do the value compare.\r
+\r
+  @param  Value                  Expression value to compare on.\r
+\r
+  @retval TRUE                   This value type can be transter to EFI_IFR_TYPE_BUFFER type.\r
+  @retval FALSE                  This value type can't be transter to EFI_IFR_TYPE_BUFFER type.\r
+\r
+**/\r
+BOOLEAN\r
+IsTypeInBuffer (\r
+  IN  EFI_HII_VALUE   *Value\r
+  )\r
+{\r
+  switch (Value->Type) {\r
+  case EFI_IFR_TYPE_BUFFER:\r
+  case EFI_IFR_TYPE_DATE:\r
+  case EFI_IFR_TYPE_TIME:\r
+  case EFI_IFR_TYPE_REF:\r
+    return TRUE;\r
+\r
+  default:\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/**\r
+  Check whether this value type can be transfer to EFI_IFR_TYPE_UINT64\r
+\r
+  @param  Value                  Expression value to compare on.\r
+\r
+  @retval TRUE                   This value type can be transter to EFI_IFR_TYPE_BUFFER type.\r
+  @retval FALSE                  This value type can't be transter to EFI_IFR_TYPE_BUFFER type.\r
+\r
+**/\r
+BOOLEAN\r
+IsTypeInUINT64 (\r
+  IN  EFI_HII_VALUE   *Value\r
+  )\r
+{\r
+  switch (Value->Type) {\r
+  case EFI_IFR_TYPE_NUM_SIZE_8:\r
+  case EFI_IFR_TYPE_NUM_SIZE_16:\r
+  case EFI_IFR_TYPE_NUM_SIZE_32:\r
+  case EFI_IFR_TYPE_NUM_SIZE_64:\r
+  case EFI_IFR_TYPE_BOOLEAN:\r
+    return TRUE;\r
+\r
+  default:\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/**\r
+  Return the buffer length and buffer pointer for this value.\r
+  \r
+  EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to \r
+  EFI_IFR_TYPE_BUFFER when do the value compare.\r
+\r
+  @param  Value                  Expression value to compare on.\r
+  @param  Buf                    Return the buffer pointer.\r
+  @param  BufLen                 Return the buffer length.\r
+\r
+**/\r
+VOID\r
+GetBufAndLenForValue (\r
+  IN  EFI_HII_VALUE   *Value,\r
+  OUT UINT8           **Buf,\r
+  OUT UINT16          *BufLen\r
+  )\r
+{\r
+  switch (Value->Type) {\r
+  case EFI_IFR_TYPE_BUFFER:\r
+    *Buf    = Value->Buffer;\r
+    *BufLen = Value->BufferLen;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_DATE:\r
+    *Buf    = (UINT8 *) (&Value->Value.date);\r
+    *BufLen = (UINT16) sizeof (EFI_HII_DATE);\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_TIME:\r
+    *Buf    = (UINT8 *) (&Value->Value.time);\r
+    *BufLen = (UINT16) sizeof (EFI_HII_TIME);\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_REF:\r
+    *Buf    = (UINT8 *) (&Value->Value.ref);\r
+    *BufLen = (UINT16) sizeof (EFI_HII_REF);\r
+    break;\r
+\r
+  default:\r
+    *Buf    = NULL;\r
+    *BufLen = 0;\r
+  }\r
+}\r
+\r
 /**\r
   Compare two Hii value.\r
 \r
@@ -131,21 +226,12 @@ CompareHiiValue (
   CHAR16  *Str1;\r
   CHAR16  *Str2;\r
   UINTN   Len;\r
+  UINT8   *Buf1;\r
+  UINT16  Buf1Len;\r
+  UINT8   *Buf2;\r
+  UINT16  Buf2Len;\r
 \r
-  if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) {\r
-    if (Value1->Type != EFI_IFR_TYPE_BUFFER && Value2->Type != EFI_IFR_TYPE_BUFFER) {\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-  }\r
-\r
-  if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) {\r
-    if (Value1->Type != Value2->Type) {\r
-      //\r
-      // Both Operator should be type of String\r
-      //\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-\r
+  if (Value1->Type == EFI_IFR_TYPE_STRING && Value2->Type == EFI_IFR_TYPE_STRING) {\r
     if (Value1->Value.string == 0 || Value2->Value.string == 0) {\r
       //\r
       // StringId 0 is reserved\r
@@ -180,22 +266,21 @@ CompareHiiValue (
     return EFI_SUCCESS;\r
   }\r
 \r
-  if (Value1->Type == EFI_IFR_TYPE_BUFFER || Value2->Type == EFI_IFR_TYPE_BUFFER ) {\r
-    if (Value1->Type != Value2->Type) {\r
-      //\r
-      // Both Operator should be type of Buffer.\r
-      //\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-    Len = Value1->BufferLen > Value2->BufferLen ? Value2->BufferLen : Value1->BufferLen;\r
-    *Result = CompareMem (Value1->Buffer, Value2->Buffer, Len);\r
-    if ((*Result == 0) && (Value1->BufferLen != Value2->BufferLen))\r
-    {\r
+  //\r
+  // Take types(date, time, ref, buffer) as buffer\r
+  //\r
+  if (IsTypeInBuffer(Value1) && IsTypeInBuffer(Value2)) {\r
+    GetBufAndLenForValue(Value1, &Buf1, &Buf1Len);\r
+    GetBufAndLenForValue(Value2, &Buf2, &Buf2Len);\r
+\r
+    Len = Buf1Len > Buf2Len ? Buf2Len : Buf1Len;\r
+    *Result = CompareMem (Buf1, Buf2, Len);\r
+    if ((*Result == 0) && (Buf1Len != Buf2Len)) {\r
       //\r
       // In this case, means base on samll number buffer, the data is same\r
       // So which value has more data, which value is bigger.\r
       //\r
-      *Result = Value1->BufferLen > Value2->BufferLen ? 1 : -1;\r
+      *Result = Buf1Len > Buf2Len ? 1 : -1;\r
     }\r
     return EFI_SUCCESS;\r
   }  \r
@@ -203,16 +288,19 @@ CompareHiiValue (
   //\r
   // Take remain types(integer, boolean, date/time) as integer\r
   //\r
-  Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2);\r
-  if (Temp64 > 0) {\r
-    *Result = 1;\r
-  } else if (Temp64 < 0) {\r
-    *Result = -1;\r
-  } else {\r
-    *Result = 0;\r
+  if (IsTypeInUINT64(Value1) && IsTypeInUINT64(Value2)) {\r
+    Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2);\r
+    if (Temp64 > 0) {\r
+      *Result = 1;\r
+    } else if (Temp64 < 0) {\r
+      *Result = -1;\r
+    } else {\r
+      *Result = 0;\r
+    }\r
+    return EFI_SUCCESS;\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  return EFI_UNSUPPORTED;\r
 }\r
 \r
 /**\r
@@ -667,143 +755,6 @@ RefreshTimeOutProcess (
   *(EventInfo->TimeOut) -= 1;\r
 }\r
 \r
-/**\r
-  Show the warning message.\r
-\r
-  @param   RetInfo    The input warning string and timeout info.\r
-\r
-**/\r
-VOID\r
-WarningIfCheck (\r
-  IN STATEMENT_ERROR_INFO  *RetInfo\r
-  )\r
-{\r
-  CHAR16             *ErrorInfo;\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_INPUT_KEY      Key;\r
-\r
-  TimeOutEvent         = NULL;\r
-  RefreshIntervalEvent = NULL;\r
-\r
-  ASSERT (RetInfo->StringId != 0);\r
-  ErrorInfo = GetToken (RetInfo->StringId, gFormData->HiiHandle);\r
-  TimeOut   = RetInfo->TimeOut;\r
-  if (RetInfo->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
-  FreePool (ErrorInfo);\r
-}\r
-\r
-/**\r
-  Process validate for one question.\r
-\r
-  @param  Question               The question need to be validate.\r
-\r
-  @retval EFI_SUCCESS            Question Option process success.\r
-  @retval EFI_INVALID_PARAMETER  Question Option process fail.\r
-\r
-**/\r
-EFI_STATUS \r
-ValidateQuestion (\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT   *Question\r
-  )\r
-{\r
-  CHAR16                          *ErrorInfo;\r
-  EFI_INPUT_KEY                   Key;\r
-  EFI_STATUS                      Status;\r
-  STATEMENT_ERROR_INFO            RetInfo;\r
-  UINT32                          RetVal;\r
-\r
-  if (Question->ValidateQuestion == NULL) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  Status = EFI_SUCCESS; \r
-  RetVal = Question->ValidateQuestion(gFormData, Question, &gUserInput->InputValue, &RetInfo);\r
\r
-  switch (RetVal) {\r
-  case INCOSISTENT_IF_TRUE:\r
-    //\r
-    // Condition meet, show up error message\r
-    //\r
-    ASSERT (RetInfo.StringId != 0);\r
-    ErrorInfo = GetToken (RetInfo.StringId, gFormData->HiiHandle);\r
-    do {\r
-      CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);\r
-    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
-    FreePool (ErrorInfo);\r
-\r
-    Status = EFI_INVALID_PARAMETER;\r
-    break;\r
-\r
-  case WARNING_IF_TRUE:\r
-    //\r
-    // Condition meet, show up warning message\r
-    //\r
-    WarningIfCheck (&RetInfo);\r
-    break;\r
-\r
-  default:\r
-    break;\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
 /**\r
   Display error message for invalid password.\r
 \r
@@ -935,7 +886,7 @@ PasswordProcess (
     gUserInput->InputValue.Value.string = HiiSetString(gFormData->HiiHandle, gUserInput->InputValue.Value.string, StringPtr, NULL);\r
     FreePool (StringPtr); \r
 \r
-    Status = ValidateQuestion (Question);\r
+    Status = EFI_SUCCESS;\r
 \r
     if (EFI_ERROR (Status)) {\r
       //\r
@@ -1004,7 +955,6 @@ ProcessOptions (
   UINTN                           Index2;\r
   UINT8                           *ValueArray;\r
   UINT8                           ValueType;\r
-  EFI_STRING_ID                   StringId;\r
   EFI_IFR_ORDERED_LIST            *OrderList;\r
   BOOLEAN                         ValueInvalid;\r
 \r
@@ -1013,7 +963,6 @@ ProcessOptions (
   StringPtr     = NULL;\r
   Character[1]  = L'\0';\r
   *OptionString = NULL;\r
-  StringId      = 0;\r
   ValueInvalid  = FALSE;\r
 \r
   ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));\r
@@ -1085,7 +1034,7 @@ ProcessOptions (
           // Exit current DisplayForm with new value.\r
           //\r
           gUserInput->SelectedStatement = Question;\r
-          \r
+          gMisMatch = TRUE;\r
           ValueArray = AllocateZeroPool (Question->CurrentValue.BufferLen);\r
           ASSERT (ValueArray != NULL);\r
           gUserInput->InputValue.Buffer    = ValueArray;\r
@@ -1170,7 +1119,7 @@ ProcessOptions (
           // Exit current DisplayForm with new value.\r
           //\r
           gUserInput->SelectedStatement = Question;\r
-          \r
+          gMisMatch = TRUE;\r
           ValueArray = AllocateCopyPool (Question->CurrentValue.BufferLen, Question->CurrentValue.Buffer);\r
           ASSERT (ValueArray != NULL);\r
           gUserInput->InputValue.Buffer    = ValueArray;\r
@@ -1247,7 +1196,7 @@ ProcessOptions (
             break;\r
           }\r
           gUserInput->SelectedStatement = Question;\r
-\r
+          gMisMatch = TRUE;\r
           FreePool (*OptionString);\r
           *OptionString = NULL;\r
           return EFI_NOT_FOUND;\r
@@ -1277,7 +1226,7 @@ ProcessOptions (
       //\r
       // Perform inconsistent check\r
       //\r
-      return ValidateQuestion (Question);\r
+      return EFI_SUCCESS;\r
     } else {    \r
       *OptionString = AllocateZeroPool (BufferSize);\r
       ASSERT (*OptionString);\r
@@ -1397,7 +1346,7 @@ ProcessOptions (
       gUserInput->InputValue.Type = Question->CurrentValue.Type;\r
       gUserInput->InputValue.Value.string = HiiSetString(gFormData->HiiHandle, gUserInput->InputValue.Value.string, StringPtr, NULL);\r
       FreePool (StringPtr);\r
-      return ValidateQuestion (Question);\r
+      return EFI_SUCCESS;\r
     } else {\r
       *OptionString = AllocateZeroPool (BufferSize);\r
       ASSERT (*OptionString);\r