]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
K8:
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Ui.c
index 2869c587c52e5f3966416140e1cbdd09e79f1f28..cc9652ee1767cb18c8216822bb11e19e4e5e3c08 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Utility functions for User Interface functions.\r
 \r
-Copyright (c) 2004 - 2007, Intel Corporation\r
+Copyright (c) 2004 - 2008, Intel Corporation\r
 All rights reserved. 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
@@ -116,6 +116,9 @@ SCREEN_OPERATION_T0_CONTROL_FLAG  gScreenOperationToControlFlag[] = {
   }\r
 };\r
 \r
+BOOLEAN  mInputError;\r
+BOOLEAN GetLineByWidthFinished = FALSE;\r
+\r
 \r
 /**\r
   Set Buffer to Value for Size bytes.\r
@@ -188,7 +191,7 @@ UiRemoveMenuListEntry (
     Selection->FormId = UiMenuList->FormId;\r
     Selection->QuestionId = UiMenuList->QuestionId;\r
     RemoveEntryList (&UiMenuList->MenuLink);\r
-    gBS->FreePool (UiMenuList);\r
+    FreePool (UiMenuList);\r
   }\r
 }\r
 \r
@@ -207,7 +210,7 @@ UiFreeMenuList (
   while (!IsListEmpty (&gMenuList)) {\r
     UiMenuList = CR (gMenuList.ForwardLink, UI_MENU_LIST, MenuLink, UI_MENU_LIST_SIGNATURE);\r
     RemoveEntryList (&UiMenuList->MenuLink);\r
-    gBS->FreePool (UiMenuList);\r
+    FreePool (UiMenuList);\r
   }\r
 }\r
 \r
@@ -260,9 +263,9 @@ UiFreeMenu (
       // Data format :      [01/02/2004]      [11:22:33]\r
       // Line number :        0  0    1         0  0  1\r
       //\r
-      gBS->FreePool (MenuOption->Description);\r
+      FreePool (MenuOption->Description);\r
     }\r
-    gBS->FreePool (MenuOption);\r
+    FreePool (MenuOption);\r
   }\r
 }\r
 \r
@@ -280,7 +283,7 @@ UiFreeRefreshList (
 \r
   while (gMenuRefreshHead != NULL) {\r
     OldMenuRefreshEntry = gMenuRefreshHead->Next;\r
-    gBS->FreePool (gMenuRefreshHead);\r
+    FreePool (gMenuRefreshHead);\r
     gMenuRefreshHead = OldMenuRefreshEntry;\r
   }\r
 \r
@@ -293,66 +296,122 @@ UiFreeRefreshList (
   Refresh screen.\r
 \r
 **/\r
-VOID\r
+EFI_STATUS\r
 RefreshForm (\r
   VOID\r
   )\r
 {\r
-  CHAR16                  *OptionString;\r
-  MENU_REFRESH_ENTRY      *MenuRefreshEntry;\r
-  UINTN                   Index;\r
-  UINTN                   Loop;\r
-  EFI_STATUS              Status;\r
-  UI_MENU_SELECTION       *Selection;\r
-  FORM_BROWSER_STATEMENT  *Question;\r
-\r
-  OptionString = NULL;\r
+  CHAR16                          *OptionString;\r
+  MENU_REFRESH_ENTRY              *MenuRefreshEntry;\r
+  UINTN                           Index;\r
+  EFI_STATUS                      Status;\r
+  UI_MENU_SELECTION               *Selection;\r
+  FORM_BROWSER_STATEMENT          *Question;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+  EFI_HII_VALUE                   *HiiValue;\r
+  EFI_BROWSER_ACTION_REQUEST      ActionRequest;\r
 \r
   if (gMenuRefreshHead != NULL) {\r
 \r
     MenuRefreshEntry = gMenuRefreshHead;\r
 \r
+    //\r
+    // Reset FormPackage update flag\r
+    //\r
+    mHiiPackageListUpdated = FALSE;\r
+\r
     do {\r
       gST->ConOut->SetAttribute (gST->ConOut, MenuRefreshEntry->CurrentAttribute);\r
 \r
       Selection = MenuRefreshEntry->Selection;\r
       Question = MenuRefreshEntry->MenuOption->ThisTag;\r
 \r
+      Status = GetQuestionValue (Selection->FormSet, Selection->Form, Question, FALSE);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      OptionString = NULL;\r
+      ProcessOptions (Selection, MenuRefreshEntry->MenuOption, FALSE, &OptionString);\r
+\r
+      if (OptionString != NULL) {\r
+        //\r
+        // If leading spaces on OptionString - remove the spaces\r
+        //\r
+        for (Index = 0; OptionString[Index] == L' '; Index++)\r
+          ;\r
+\r
+        PrintStringAt (MenuRefreshEntry->CurrentColumn, MenuRefreshEntry->CurrentRow, &OptionString[Index]);\r
+        FreePool (OptionString);\r
+      }\r
+\r
       //\r
-      // Don't update Question being edited\r
+      // Question value may be changed, need invoke its Callback()\r
       //\r
-      if (Question != MenuRefreshEntry->Selection->Statement) {\r
+      ConfigAccess = Selection->FormSet->ConfigAccess;\r
+      if (((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) && (ConfigAccess != NULL)) {\r
+        ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
 \r
-        Status = GetQuestionValue (Selection->FormSet, Selection->Form, Question, FALSE);\r
-        if (EFI_ERROR (Status)) {\r
-          return;\r
+        HiiValue = &Question->HiiValue;\r
+        if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
+          //\r
+          // Create String in HII database for Configuration Driver to retrieve\r
+          //\r
+          HiiValue->Value.string = NewString ((CHAR16 *) Question->BufferValue, Selection->FormSet->HiiHandle);\r
         }\r
 \r
-        ProcessOptions (Selection, MenuRefreshEntry->MenuOption, FALSE, &OptionString);\r
+        Status = ConfigAccess->Callback (\r
+                                 ConfigAccess,\r
+                                 EFI_BROWSER_ACTION_CHANGING,\r
+                                 Question->QuestionId,\r
+                                 HiiValue->Type,\r
+                                 &HiiValue->Value,\r
+                                 &ActionRequest\r
+                                 );\r
 \r
-        if (OptionString != NULL) {\r
+        if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
           //\r
-          // If leading spaces on OptionString - remove the spaces\r
+          // Clean the String in HII Database\r
           //\r
-          for (Index = 0; OptionString[Index] == L' '; Index++)\r
-            ;\r
+          DeleteString (HiiValue->Value.string, Selection->FormSet->HiiHandle);\r
+        }\r
 \r
-          for (Loop = 0; OptionString[Index] != CHAR_NULL; Index++) {\r
-            OptionString[Loop] = OptionString[Index];\r
-            Loop++;\r
-          }\r
+        if (!EFI_ERROR (Status)) {\r
+          switch (ActionRequest) {\r
+          case EFI_BROWSER_ACTION_REQUEST_RESET:\r
+            gResetRequired = TRUE;\r
+            break;\r
+\r
+          case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
+            SubmitForm (Selection->FormSet, Selection->Form);\r
+            break;\r
 \r
-          OptionString[Loop] = CHAR_NULL;\r
+          case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
+            Selection->Action = UI_ACTION_EXIT;\r
+            gNvUpdateRequired = FALSE;\r
+            break;\r
 \r
-          PrintStringAt (MenuRefreshEntry->CurrentColumn, MenuRefreshEntry->CurrentRow, OptionString);\r
-          gBS->FreePool (OptionString);\r
+          default:\r
+            break;\r
+          }\r
         }\r
       }\r
 \r
       MenuRefreshEntry = MenuRefreshEntry->Next;\r
 \r
     } while (MenuRefreshEntry != NULL);\r
+\r
+    if (mHiiPackageListUpdated) {\r
+      //\r
+      // Package list is updated, force to reparse IFR binary of target Formset\r
+      //\r
+      mHiiPackageListUpdated = FALSE;\r
+      Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+      return EFI_SUCCESS;\r
+    }\r
   }\r
+\r
+  return EFI_TIMEOUT;\r
 }\r
 \r
 \r
@@ -444,7 +503,7 @@ UiWaitForSingleEvent (
       if (!EFI_ERROR (Status) && Index == 1) {\r
         Status = EFI_TIMEOUT;\r
         if (RefreshInterval != 0) {\r
-          RefreshForm ();\r
+          Status = RefreshForm ();\r
         }\r
       }\r
 \r
@@ -670,8 +729,8 @@ CreateDialog (
       case CHAR_NULL:\r
         switch (Key.ScanCode) {\r
         case SCAN_ESC:\r
-          gBS->FreePool (TempString);\r
-          gBS->FreePool (BufferedString);\r
+          FreePool (TempString);\r
+          FreePool (BufferedString);\r
           gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);\r
           gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
           return EFI_DEVICE_ERROR;\r
@@ -684,8 +743,8 @@ CreateDialog (
 \r
       case CHAR_CARRIAGE_RETURN:\r
         SelectionComplete = TRUE;\r
-        gBS->FreePool (TempString);\r
-        gBS->FreePool (BufferedString);\r
+        FreePool (TempString);\r
+        FreePool (BufferedString);\r
         gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);\r
         gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
         return EFI_SUCCESS;\r
@@ -892,7 +951,6 @@ UpdateStatusBar (
   )\r
 {\r
   UINTN           Index;\r
-  STATIC BOOLEAN  InputError;\r
   CHAR16          *NvUpdateMessage;\r
   CHAR16          *InputErrorMessage;\r
 \r
@@ -908,14 +966,14 @@ UpdateStatusBar (
         gScreenDimensions.BottomRow - 1,\r
         InputErrorMessage\r
         );\r
-      InputError = TRUE;\r
+      mInputError = TRUE;\r
     } else {\r
       gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_HIGHLIGHT);\r
       for (Index = 0; Index < (GetStringWidth (InputErrorMessage) - 2) / 2; Index++) {\r
         PrintAt (gScreenDimensions.LeftColumn + gPromptBlockWidth + Index, gScreenDimensions.BottomRow - 1, L"  ");\r
       }\r
 \r
-      InputError = FALSE;\r
+      mInputError = FALSE;\r
     }\r
     break;\r
 \r
@@ -947,7 +1005,7 @@ UpdateStatusBar (
     break;\r
 \r
   case REFRESH_STATUS_BAR:\r
-    if (InputError) {\r
+    if (mInputError) {\r
       UpdateStatusBar (INPUT_ERROR, Flags, TRUE);\r
     }\r
 \r
@@ -960,8 +1018,8 @@ UpdateStatusBar (
     break;\r
   }\r
 \r
-  gBS->FreePool (InputErrorMessage);\r
-  gBS->FreePool (NvUpdateMessage);\r
+  FreePool (InputErrorMessage);\r
+  FreePool (NvUpdateMessage);\r
   return ;\r
 }\r
 \r
@@ -993,7 +1051,7 @@ GetWidth (
   if ((Statement->Operand == EFI_IFR_TEXT_OP) && (Statement->TextTwo != 0)) {\r
     String = GetToken (Statement->TextTwo, Handle);\r
     Size   = StrLen (String);\r
-    gBS->FreePool (String);\r
+    FreePool (String);\r
   }\r
 \r
   if ((Statement->Operand == EFI_IFR_SUBTITLE_OP) ||\r
@@ -1018,9 +1076,6 @@ GetWidth (
   return Width;\r
 }\r
 \r
-\r
-STATIC BOOLEAN GetLineByWidthFinished = FALSE;\r
-\r
 /**\r
   Will copy LineWidth amount of a string in the OutputString buffer and return the\r
   number of CHAR16 characters that were copied into the OutputString buffer.\r
@@ -1177,7 +1232,7 @@ UpdateOptionSkipLines (
         }\r
       }\r
 \r
-      gBS->FreePool (OutputString);\r
+      FreePool (OutputString);\r
       if (SkipValue != 0) {\r
         SkipValue--;\r
       }\r
@@ -1584,7 +1639,7 @@ UiDisplayMenu (
               }\r
             }\r
 \r
-            gBS->FreePool (OutputString);\r
+            FreePool (OutputString);\r
             if (Temp != 0) {\r
               Temp--;\r
             }\r
@@ -1594,7 +1649,16 @@ UiDisplayMenu (
           Row   = OriginalRow;\r
 \r
           gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);\r
-          ProcessOptions (Selection, MenuOption, FALSE, &OptionString);\r
+          Status = ProcessOptions (Selection, MenuOption, FALSE, &OptionString);\r
+          if (EFI_ERROR (Status)) {\r
+            //\r
+            // Repaint to clear possible error prompt pop-up\r
+            //\r
+            Repaint = TRUE;\r
+            NewLine = TRUE;\r
+            ControlFlag = CfRepaint;\r
+            break;\r
+          }\r
 \r
           if (OptionString != NULL) {\r
             if (Statement->Operand == EFI_IFR_DATE_OP || Statement->Operand == EFI_IFR_TIME_OP) {\r
@@ -1680,7 +1744,7 @@ UiDisplayMenu (
                 }\r
               }\r
 \r
-              gBS->FreePool (OutputString);\r
+              FreePool (OutputString);\r
               if (Temp2 != 0) {\r
                 Temp2--;\r
               }\r
@@ -1689,7 +1753,7 @@ UiDisplayMenu (
             Temp2 = 0;\r
             Row   = OriginalRow;\r
 \r
-            gBS->FreePool (OptionString);\r
+            FreePool (OptionString);\r
           }\r
           //\r
           // If this is a text op with secondary text information\r
@@ -1723,14 +1787,14 @@ UiDisplayMenu (
                 }\r
               }\r
 \r
-              gBS->FreePool (OutputString);\r
+              FreePool (OutputString);\r
               if (Temp2 != 0) {\r
                 Temp2--;\r
               }\r
             }\r
 \r
             Row = OriginalRow;\r
-            gBS->FreePool (StringPtr);\r
+            FreePool (StringPtr);\r
           }\r
 \r
           //\r
@@ -1885,12 +1949,12 @@ UiDisplayMenu (
                 MenuOption->Row++;\r
               }\r
 \r
-              gBS->FreePool (OutputString);\r
+              FreePool (OutputString);\r
             }\r
 \r
             MenuOption->Row = OriginalRow;\r
 \r
-            gBS->FreePool (OptionString);\r
+            FreePool (OptionString);\r
           } else {\r
             if (NewLine) {\r
               if (MenuOption->GrayOut) {\r
@@ -1913,7 +1977,7 @@ UiDisplayMenu (
                   MenuOption->Row++;\r
                 }\r
 \r
-                gBS->FreePool (OutputString);\r
+                FreePool (OutputString);\r
               }\r
 \r
               MenuOption->Row = OriginalRow;\r
@@ -1991,12 +2055,12 @@ UiDisplayMenu (
               MenuOption->Row++;\r
             }\r
 \r
-            gBS->FreePool (OutputString);\r
+            FreePool (OutputString);\r
           }\r
 \r
           MenuOption->Row = OriginalRow;\r
 \r
-          gBS->FreePool (OptionString);\r
+          FreePool (OptionString);\r
         } else {\r
           if (NewLine) {\r
             OriginalRow = MenuOption->Row;\r
@@ -2014,7 +2078,7 @@ UiDisplayMenu (
                 MenuOption->Row++;\r
               }\r
 \r
-              gBS->FreePool (OutputString);\r
+              FreePool (OutputString);\r
             }\r
 \r
             MenuOption->Row = OriginalRow;\r
@@ -2022,12 +2086,8 @@ UiDisplayMenu (
           }\r
         }\r
 \r
-        if (((NewPos->ForwardLink != &Menu) && (ScreenOperation == UiDown)) ||\r
-            ((NewPos->BackLink != &Menu) && (ScreenOperation == UiUp)) ||\r
-            (ScreenOperation == UiNoOperation)\r
-            ) {\r
-          UpdateKeyHelp (MenuOption, FALSE);\r
-        }\r
+        UpdateKeyHelp (MenuOption, FALSE);\r
+\r
         //\r
         // Clear reverse attribute\r
         //\r
@@ -2094,17 +2154,22 @@ UiDisplayMenu (
         Status = UiWaitForSingleEvent (gST->ConIn->WaitForKey, 0, MinRefreshInterval);\r
       } while (Status == EFI_TIMEOUT);\r
 \r
-      if (Status == EFI_TIMEOUT) {\r
-        Key.UnicodeChar = CHAR_CARRIAGE_RETURN;\r
-      } else {\r
-        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+      if (Selection->Action == UI_ACTION_REFRESH_FORMSET) {\r
         //\r
-        // if we encounter error, continue to read another key in.\r
+        // IFR is updated in Callback of refresh opcode, re-parse it\r
         //\r
-        if (EFI_ERROR (Status)) {\r
-          ControlFlag = CfReadKey;\r
-          continue;\r
-        }\r
+        ControlFlag = CfUiReset;\r
+        Selection->Statement = NULL;\r
+        break;\r
+      }\r
+\r
+      Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+      //\r
+      // if we encounter error, continue to read another key in.\r
+      //\r
+      if (EFI_ERROR (Status)) {\r
+        ControlFlag = CfReadKey;\r
+        break;\r
       }\r
 \r
       if (IsListEmpty (&Menu) && Key.UnicodeChar != CHAR_NULL) {\r
@@ -2137,7 +2202,16 @@ UiDisplayMenu (
             gDirection = SCAN_LEFT;\r
           }\r
           Status = ProcessOptions (Selection, MenuOption, TRUE, &OptionString);\r
-          SafeFreePool (OptionString);\r
+          if (EFI_ERROR (Status)) {\r
+            //\r
+            // Repaint to clear possible error prompt pop-up\r
+            //\r
+            Repaint = TRUE;\r
+            NewLine = TRUE;\r
+          }\r
+          if (OptionString != NULL) {\r
+            FreePool (OptionString);\r
+          }\r
         }\r
         break;\r
 \r
@@ -2296,8 +2370,8 @@ UiDisplayMenu (
             break;\r
           }\r
 \r
-          gBS->FreePool (StringPtr);\r
-          gBS->FreePool (DevicePath);\r
+          FreePool (StringPtr);\r
+          FreePool (DevicePath);\r
 \r
           CopyMem (&Selection->FormSetGuid, &Statement->RefFormSetId, sizeof (EFI_GUID));\r
           Selection->FormId = Statement->RefFormId;\r
@@ -2375,15 +2449,14 @@ UiDisplayMenu (
         if (EFI_ERROR (Status)) {\r
           Repaint = TRUE;\r
           NewLine = TRUE;\r
-          break;\r
-        }\r
-\r
-        if (OptionString != NULL) {\r
-          PrintStringAt (LocalScreen.LeftColumn + gPromptBlockWidth + 1, MenuOption->Row, OptionString);\r
-          gBS->FreePool (OptionString);\r
-        }\r
+            UpdateKeyHelp (MenuOption, FALSE);\r
+          } else {\r
+            Selection->Action = UI_ACTION_REFRESH_FORM;\r
+          }\r
 \r
-        Selection->Action = UI_ACTION_REFRESH_FORM;\r
+          if (OptionString != NULL) {\r
+            FreePool (OptionString);\r
+          }\r
         break;\r
       }\r
       break;\r