]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c
Add four PCDs for the different color settings of Subtitle and Text Filed on Browser.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / ProcessOptions.c
index 49c7ff8c5a71ddc04bf0477a0c0f1b9fbb71757e..2e77522ca17f0efe2c6c1fe6e26e0dafc92b7ed6 100644 (file)
@@ -2,8 +2,8 @@
 Implementation for handling the User Interface option processing.\r
 \r
 \r
-Copyright (c) 2004 - 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2004 - 2011, 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
 http://opensource.org/licenses/bsd-license.php\r
@@ -13,7 +13,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include "Ui.h"\r
 #include "Setup.h"\r
 \r
 \r
@@ -101,6 +100,96 @@ ValueToOption (
 }\r
 \r
 \r
+/**\r
+  Return data element in an Array by its Index.\r
+\r
+  @param  Array                  The data array.\r
+  @param  Type                   Type of the data in this array.\r
+  @param  Index                  Zero based index for data in this array.\r
+\r
+  @retval Value                  The data to be returned\r
+\r
+**/\r
+UINT64\r
+GetArrayData (\r
+  IN VOID                     *Array,\r
+  IN UINT8                    Type,\r
+  IN UINTN                    Index\r
+  )\r
+{\r
+  UINT64 Data;\r
+\r
+  ASSERT (Array != NULL);\r
+\r
+  Data = 0;\r
+  switch (Type) {\r
+  case EFI_IFR_TYPE_NUM_SIZE_8:\r
+    Data = (UINT64) *(((UINT8 *) Array) + Index);\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_16:\r
+    Data = (UINT64) *(((UINT16 *) Array) + Index);\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_32:\r
+    Data = (UINT64) *(((UINT32 *) Array) + Index);\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_64:\r
+    Data = (UINT64) *(((UINT64 *) Array) + Index);\r
+    break;\r
+\r
+  default:\r
+    break;\r
+  }\r
+\r
+  return Data;\r
+}\r
+\r
+\r
+/**\r
+  Set value of a data element in an Array by its Index.\r
+\r
+  @param  Array                  The data array.\r
+  @param  Type                   Type of the data in this array.\r
+  @param  Index                  Zero based index for data in this array.\r
+  @param  Value                  The value to be set.\r
+\r
+**/\r
+VOID\r
+SetArrayData (\r
+  IN VOID                     *Array,\r
+  IN UINT8                    Type,\r
+  IN UINTN                    Index,\r
+  IN UINT64                   Value\r
+  )\r
+{\r
+\r
+  ASSERT (Array != NULL);\r
+\r
+  switch (Type) {\r
+  case EFI_IFR_TYPE_NUM_SIZE_8:\r
+    *(((UINT8 *) Array) + Index) = (UINT8) Value;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_16:\r
+    *(((UINT16 *) Array) + Index) = (UINT16) Value;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_32:\r
+    *(((UINT32 *) Array) + Index) = (UINT32) Value;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_64:\r
+    *(((UINT64 *) Array) + Index) = (UINT64) Value;\r
+    break;\r
+\r
+  default:\r
+    break;\r
+  }\r
+}\r
+\r
+\r
 /**\r
   Print Question Value according to it's storage width and display attributes.\r
 \r
@@ -213,9 +302,8 @@ PasswordCallback (
   EFI_STATUS                      Status;\r
   EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
   EFI_BROWSER_ACTION_REQUEST      ActionRequest;\r
-  EFI_HII_VALUE                   *QuestionValue;\r
+  EFI_IFR_TYPE_VALUE              IfrTypeValue;\r
 \r
-  QuestionValue = &MenuOption->ThisTag->HiiValue;\r
   ConfigAccess = Selection->FormSet->ConfigAccess;\r
   if (ConfigAccess == NULL) {\r
     return EFI_UNSUPPORTED;\r
@@ -225,9 +313,9 @@ PasswordCallback (
   // Prepare password string in HII database\r
   //\r
   if (String != NULL) {\r
-    QuestionValue->Value.string = NewString (String, Selection->FormSet->HiiHandle);\r
+    IfrTypeValue.string = NewString (String, Selection->FormSet->HiiHandle);\r
   } else {\r
-    QuestionValue->Value.string = 0;\r
+    IfrTypeValue.string = 0;\r
   }\r
 \r
   //\r
@@ -237,8 +325,8 @@ PasswordCallback (
                            ConfigAccess,\r
                            EFI_BROWSER_ACTION_CHANGING,\r
                            MenuOption->ThisTag->QuestionId,\r
-                           QuestionValue->Type,\r
-                           &QuestionValue->Value,\r
+                           MenuOption->ThisTag->HiiValue.Type,\r
+                           &IfrTypeValue,\r
                            &ActionRequest\r
                            );\r
 \r
@@ -246,7 +334,7 @@ PasswordCallback (
   // Remove password string from HII database\r
   //\r
   if (String != NULL) {\r
-    DeleteString (QuestionValue->Value.string, Selection->FormSet->HiiHandle);\r
+    DeleteString (IfrTypeValue.string, Selection->FormSet->HiiHandle);\r
   }\r
 \r
   return Status;\r
@@ -311,12 +399,16 @@ ProcessOptions (
   UINT16                          Maximum;\r
   QUESTION_OPTION                 *Option;\r
   UINTN                           Index2;\r
+  UINT8                           *ValueArray;\r
+  UINT8                           ValueType;\r
+  EFI_STRING_ID                   StringId;\r
 \r
   Status        = EFI_SUCCESS;\r
 \r
   StringPtr     = NULL;\r
   Character[1]  = L'\0';\r
   *OptionString = NULL;\r
+  StringId      = 0;\r
 \r
   ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));\r
   BufferSize = (gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow;\r
@@ -325,13 +417,21 @@ ProcessOptions (
   QuestionValue = &Question->HiiValue;\r
   Maximum = (UINT16) Question->Maximum;\r
 \r
+  ValueArray = Question->BufferValue;\r
+  ValueType = Question->ValueType;\r
+\r
   switch (Question->Operand) {\r
   case EFI_IFR_ORDERED_LIST_OP:\r
+    //\r
+    // Check whether there are Options of this OrderedList\r
+    //\r
+    if (IsListEmpty (&Question->OptionListHead)) {\r
+      break;\r
+    }\r
     //\r
     // Initialize Option value array\r
     //\r
-\r
-    if (Question->BufferValue[0] == 0) {\r
+    if (GetArrayData (ValueArray, ValueType, 0) == 0) {\r
       GetQuestionDefault (Selection->FormSet, Selection->Form, Question, 0);\r
     }\r
 \r
@@ -348,11 +448,11 @@ ProcessOptions (
       *OptionString = AllocateZeroPool (Question->MaxContainers * BufferSize);\r
       ASSERT (*OptionString);\r
 \r
-      HiiValue.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+      HiiValue.Type = ValueType;\r
       HiiValue.Value.u64 = 0;\r
       for (Index = 0; Index < Question->MaxContainers; Index++) {\r
-        HiiValue.Value.u8 = Question->BufferValue[Index];\r
-        if (HiiValue.Value.u8 == 0) {\r
+        HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);\r
+        if (HiiValue.Value.u64 == 0) {\r
           //\r
           // Values for the options in ordered lists should never be a 0\r
           //\r
@@ -375,15 +475,16 @@ ProcessOptions (
           Index2 = 0;\r
           while (!IsNull (&Question->OptionListHead, Link) && Index2 < Question->MaxContainers) {\r
             Option = QUESTION_OPTION_FROM_LINK (Link);\r
-            Question->BufferValue[Index2++] = Option->Value.Value.u8;\r
+            SetArrayData (ValueArray, ValueType, Index2, Option->Value.Value.u64);\r
+            Index2++;\r
             Link = GetNextNode (&Question->OptionListHead, Link);\r
           }\r
-          Question->BufferValue[Index2] = 0;\r
+          SetArrayData (ValueArray, ValueType, Index2, 0);\r
 \r
           Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
           UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
 \r
-          gBS->FreePool (*OptionString);\r
+          FreePool (*OptionString);\r
           *OptionString = NULL;\r
           return EFI_NOT_FOUND;\r
         }\r
@@ -407,13 +508,19 @@ ProcessOptions (
           Character[0] = CHAR_CARRIAGE_RETURN;\r
           NewStrCat (OptionString[0], Character);\r
 \r
-          gBS->FreePool (StringPtr);\r
+          FreePool (StringPtr);\r
         }\r
       }\r
     }\r
     break;\r
 \r
   case EFI_IFR_ONE_OF_OP:\r
+    //\r
+    // Check whether there are Options of this OneOf\r
+    //\r
+    if (IsListEmpty (&Question->OptionListHead)) {\r
+      break;\r
+    }\r
     if (Selected) {\r
       //\r
       // Go ask for input\r
@@ -450,8 +557,9 @@ ProcessOptions (
           Link = GetNextNode (&Question->OptionListHead, Link);\r
         }\r
 \r
-        gBS->FreePool (*OptionString);\r
+        FreePool (*OptionString);\r
         *OptionString = NULL;\r
+        return EFI_NOT_FOUND;\r
       }\r
 \r
       if ((OneOfOption->SuppressExpression != NULL) &&\r
@@ -479,7 +587,7 @@ ProcessOptions (
             CopyMem (QuestionValue, &OneOfOption->Value, sizeof (EFI_HII_VALUE));\r
             SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
             UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
-            gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);\r
+            gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);\r
             break;\r
           }\r
 \r
@@ -495,7 +603,7 @@ ProcessOptions (
         Character[0] = RIGHT_ONEOF_DELIMITER;\r
         NewStrCat (OptionString[0], Character);\r
 \r
-        gBS->FreePool (StringPtr);\r
+        FreePool (StringPtr);\r
       }\r
     }\r
     break;\r
@@ -521,7 +629,7 @@ ProcessOptions (
         // Inconsistent check fail, restore Question Value\r
         //\r
         QuestionValue->Value.b = (BOOLEAN) (QuestionValue->Value.b ? FALSE : TRUE);\r
-        gBS->FreePool (*OptionString);\r
+        FreePool (*OptionString);\r
         *OptionString = NULL;\r
         return Status;\r
       }\r
@@ -635,13 +743,19 @@ ProcessOptions (
 \r
       Status = ReadString (MenuOption, gPromptForData, StringPtr);\r
       if (!EFI_ERROR (Status)) {\r
-        CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));\r
-        SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
+        HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, StringPtr, NULL);\r
+        Status = ValidateQuestion(Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);\r
+        if (EFI_ERROR (Status)) {\r
+          HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);\r
+        } else {\r
+          CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));\r
+          SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
 \r
-        UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+          UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+        }\r
       }\r
 \r
-      gBS->FreePool (StringPtr);\r
+      FreePool (StringPtr);\r
     } else {\r
       *OptionString = AllocateZeroPool (BufferSize);\r
       ASSERT (*OptionString);\r
@@ -671,11 +785,12 @@ ProcessOptions (
         //\r
         *StringPtr = 0;\r
         Status = PasswordCallback (Selection, MenuOption, StringPtr);\r
-        if (Status == EFI_NOT_AVAILABLE_YET) {\r
+        if (Status == EFI_NOT_AVAILABLE_YET || Status == EFI_UNSUPPORTED) {\r
           //\r
+          // Callback is not supported, or\r
           // Callback request to terminate password input\r
           //\r
-          gBS->FreePool (StringPtr);\r
+          FreePool (StringPtr);\r
           return EFI_SUCCESS;\r
         }\r
 \r
@@ -685,7 +800,7 @@ ProcessOptions (
           //\r
           Status = ReadString (MenuOption, gPromptForPassword, StringPtr);\r
           if (EFI_ERROR (Status)) {\r
-            gBS->FreePool (StringPtr);\r
+            FreePool (StringPtr);\r
             return Status;\r
           }\r
 \r
@@ -703,7 +818,7 @@ ProcessOptions (
               Status = EFI_SUCCESS;\r
             }\r
 \r
-            gBS->FreePool (StringPtr);\r
+            FreePool (StringPtr);\r
             return Status;\r
           }\r
         }\r
@@ -717,11 +832,13 @@ ProcessOptions (
           //\r
           Status = ReadString (MenuOption, gPromptForPassword, StringPtr);\r
           if (EFI_ERROR (Status)) {\r
-            gBS->FreePool (StringPtr);\r
+            FreePool (StringPtr);\r
             return Status;\r
           }\r
 \r
           TempString = AllocateCopyPool ((Maximum + 1) * sizeof (CHAR16), Question->BufferValue);\r
+          ASSERT (TempString != NULL);\r
+\r
           TempString[Maximum] = L'\0';\r
 \r
           if (StrCmp (StringPtr, TempString) != 0) {\r
@@ -730,12 +847,12 @@ ProcessOptions (
             //\r
             PasswordInvalid ();\r
 \r
-            gBS->FreePool (StringPtr);\r
-            gBS->FreePool (TempString);\r
+            FreePool (StringPtr);\r
+            FreePool (TempString);\r
             return Status;\r
           }\r
 \r
-          gBS->FreePool (TempString);\r
+          FreePool (TempString);\r
         }\r
       }\r
 \r
@@ -752,7 +869,7 @@ ProcessOptions (
           PasswordCallback (Selection, MenuOption, NULL);\r
         }\r
 \r
-        gBS->FreePool (StringPtr);\r
+        FreePool (StringPtr);\r
         return Status;\r
       }\r
 \r
@@ -770,8 +887,8 @@ ProcessOptions (
           PasswordCallback (Selection, MenuOption, NULL);\r
         }\r
 \r
-        gBS->FreePool (StringPtr);\r
-        gBS->FreePool (TempString);\r
+        FreePool (StringPtr);\r
+        FreePool (TempString);\r
         return Status;\r
       }\r
 \r
@@ -780,13 +897,47 @@ ProcessOptions (
       //\r
       if (StrCmp (StringPtr, TempString) == 0) {\r
         //\r
-        // Two password match, send it to Configuration Driver\r
+        // Prepare the  Question->HiiValue.Value.string for ValidateQuestion use.\r
         //\r
-        if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
-          PasswordCallback (Selection, MenuOption, StringPtr);\r
+        if((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+          StringId = Question->HiiValue.Value.string;\r
+          Question->HiiValue.Value.string = NewString (StringPtr, Selection->FormSet->HiiHandle);\r
         } else {\r
-          CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));\r
-          SetQuestionValue (Selection->FormSet, Selection->Form, Question, FALSE);\r
+          HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, StringPtr, NULL);\r
+        }\r
+        \r
+        Status = ValidateQuestion(Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);\r
+\r
+        //\r
+        //  Researve the Question->HiiValue.Value.string.\r
+        //\r
+        if((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+          DeleteString(Question->HiiValue.Value.string, Selection->FormSet->HiiHandle);\r
+          Question->HiiValue.Value.string = StringId;\r
+        }   \r
+        \r
+        if (EFI_ERROR (Status)) {\r
+          //\r
+          // Reset state machine for interactive password\r
+          //\r
+          if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+            PasswordCallback (Selection, MenuOption, NULL);\r
+          } else {\r
+            //\r
+            // Researve the Question->HiiValue.Value.string.\r
+            //\r
+            HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);            \r
+          }\r
+        } else {\r
+          //\r
+          // Two password match, send it to Configuration Driver\r
+          //\r
+          if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+            PasswordCallback (Selection, MenuOption, StringPtr);\r
+          } else {\r
+            CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));\r
+            SetQuestionValue (Selection->FormSet, Selection->Form, Question, FALSE);\r
+          }\r
         }\r
       } else {\r
         //\r
@@ -804,8 +955,8 @@ ProcessOptions (
         } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
       }\r
 \r
-      gBS->FreePool (TempString);\r
-      gBS->FreePool (StringPtr);\r
+      FreePool (TempString);\r
+      FreePool (StringPtr);\r
     }\r
     break;\r
 \r
@@ -833,7 +984,7 @@ ProcessHelpString (
   IN  UINTN   RowCount\r
   )\r
 {\r
-  CONST UINTN BlockWidth = (UINTN) gHelpBlockWidth - 1;\r
+  UINTN BlockWidth;\r
   UINTN AllocateSize;\r
   //\r
   // [PrevCurrIndex, CurrIndex) forms a range of a screen-line\r
@@ -866,6 +1017,8 @@ ProcessHelpString (
   UINTN *IndexArray;\r
   UINTN *OldIndexArray;\r
 \r
+  BlockWidth = (UINTN) gHelpBlockWidth - 1;\r
+\r
   //\r
   // every three elements of IndexArray form a screen-line of string:[ IndexArray[i*3], IndexArray[i*3+1] )\r
   // IndexArray[i*3+2] stores the initial glyph width of single character. to save this is because we want\r
@@ -875,9 +1028,10 @@ ProcessHelpString (
   //\r
   AllocateSize  = 0x20;\r
   IndexArray    = AllocatePool (AllocateSize * sizeof (UINTN) * 3);\r
+  ASSERT (IndexArray != NULL);\r
 \r
   if (*FormattedString != NULL) {\r
-    gBS->FreePool (*FormattedString);\r
+    FreePool (*FormattedString);\r
     *FormattedString = NULL;\r
   }\r
 \r
@@ -890,8 +1044,10 @@ ProcessHelpString (
       AllocateSize += 0x10;\r
       OldIndexArray  = IndexArray;\r
       IndexArray = AllocatePool (AllocateSize * sizeof (UINTN) * 3);\r
+      ASSERT (IndexArray != NULL);\r
+\r
       CopyMem (IndexArray, OldIndexArray, LineCount * sizeof (UINTN) * 3);\r
-      gBS->FreePool (OldIndexArray);\r
+      FreePool (OldIndexArray);\r
     }\r
     switch (StringPtr[CurrIndex]) {\r
 \r
@@ -1010,6 +1166,7 @@ ProcessHelpString (
 \r
   VirtualLineCount = RowCount * (LineCount / RowCount + (LineCount % RowCount > 0));\r
   *FormattedString = AllocateZeroPool (VirtualLineCount * (BlockWidth + 1) * sizeof (CHAR16) * 2);\r
+  ASSERT (*FormattedString != NULL);\r
 \r
   for (CurrIndex = 0; CurrIndex < LineCount; CurrIndex ++) {\r
     *(*FormattedString + CurrIndex * 2 * (BlockWidth + 1)) = (CHAR16) ((IndexArray[CurrIndex*3+2] == 2) ? WIDE_CHAR : NARROW_CHAR);\r
@@ -1020,5 +1177,5 @@ ProcessHelpString (
       );\r
   }\r
 \r
-  gBS->FreePool (IndexArray);\r
+  FreePool (IndexArray);\r
 }\r