]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
MdeModulePkg: Use IsZeroGuid API for zero GUID checking
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Presentation.c
index 251025b309d59057046456975ffcb940bd2a54fe..6856cc5d96c9da2526307506fa4a78a5b21663ce 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
 Utility functions for UI presentation.\r
 \r
-Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<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
@@ -357,7 +358,7 @@ InitializeDisplayStatement (
   //\r
   // Create the refresh event process function.\r
   //\r
-  if (!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) {\r
+  if (!IsZeroGuid (&Statement->RefreshGuid)) {\r
     CreateRefreshEventForStatement (Statement);\r
   }\r
 \r
@@ -372,7 +373,7 @@ InitializeDisplayStatement (
   // Create the refresh guid hook event.\r
   // If the statement in this form has refresh event or refresh interval, browser will create this event for display engine.\r
   //\r
-  if ((!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) || (Statement->RefreshInterval != 0)) {\r
+  if ((!IsZeroGuid (&Statement->RefreshGuid)) || (Statement->RefreshInterval != 0)) {\r
     gDisplayFormData.FormRefreshEvent = mValueChangedEvent;\r
   }\r
 \r
@@ -545,6 +546,21 @@ AddStatementToDisplayForm (
     InsertTailList(&gDisplayFormData.StatementListOSF, &DisplayStatement->DisplayLink);\r
   }\r
 \r
+  //\r
+  // treat formset as statement outside the form,get its opcode.\r
+  //\r
+  DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));\r
+  ASSERT (DisplayStatement != NULL);\r
+\r
+  DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;\r
+  DisplayStatement->Version   = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;\r
+  DisplayStatement->OpCode = gCurrentSelection->FormSet->OpCode;\r
+\r
+  InitializeListHead (&DisplayStatement->NestStatementList);\r
+  InitializeListHead (&DisplayStatement->OptionListHead);\r
+\r
+  InsertTailList(&gDisplayFormData.StatementListOSF, &DisplayStatement->DisplayLink);\r
+\r
   //\r
   // Process the statement in this form.\r
   //\r
@@ -612,7 +628,7 @@ AddStatementToDisplayForm (
   //\r
   // Create the refresh event process function for Form.\r
   //\r
-  if (!CompareGuid (&gCurrentSelection->Form->RefreshGuid, &gZeroGuid)) {\r
+  if (!IsZeroGuid (&gCurrentSelection->Form->RefreshGuid)) {\r
     CreateRefreshEventForForm (gCurrentSelection->Form);\r
     if (gDisplayFormData.FormRefreshEvent == NULL) {\r
       gDisplayFormData.FormRefreshEvent = mValueChangedEvent;\r
@@ -1394,7 +1410,7 @@ ProcessGotoOpCode (
     CopyMem (&Selection->FormSetGuid,&Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));\r
     Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
     Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
-  } else if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &gZeroGuid)) {\r
+  } else if (!IsZeroGuid (&Statement->HiiValue.Value.ref.FormSetGuid)) {\r
     if (Selection->Form->ModalForm) {\r
       return Status;\r
     }\r
@@ -1884,6 +1900,30 @@ FindNextMenu (
   return TRUE;\r
 }\r
 \r
+/**\r
+  Reconnect the controller.\r
+\r
+  @param DriverHandle          The controller handle which need to be reconnect.\r
+\r
+  @retval   TRUE     do the reconnect behavior success.\r
+  @retval   FALSE    do the reconnect behavior failed.\r
+  \r
+**/\r
+BOOLEAN\r
+ReconnectController (\r
+  IN EFI_HANDLE   DriverHandle\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+\r
+  Status = gBS->DisconnectController(DriverHandle, NULL, NULL);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = gBS->ConnectController(DriverHandle, NULL, NULL, TRUE);\r
+  }\r
+\r
+  return Status == EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Call the call back function for the question and process the return action.\r
 \r
@@ -2004,6 +2044,7 @@ ProcessCallBackFunction (
 \r
         ASSERT (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth);\r
         if (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth) {\r
+          ZeroMem (Statement->BufferValue, Statement->StorageWidth);\r
           CopyMem (Statement->BufferValue, NewString, StrSize (NewString));\r
         } else {\r
           CopyMem (Statement->BufferValue, NewString, Statement->StorageWidth);\r
@@ -2055,6 +2096,10 @@ ProcessCallBackFunction (
           SettingLevel          = FormLevel;\r
           break;\r
 \r
+        case EFI_BROWSER_ACTION_REQUEST_RECONNECT:\r
+          gCallbackReconnect    = TRUE;\r
+          break;\r
+\r
         default:\r
           break;\r
         }\r
@@ -2066,6 +2111,11 @@ ProcessCallBackFunction (
         //\r
         Status = ValueChangedValidation (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement);\r
         if (!EFI_ERROR (Status)) {\r
+          //\r
+          //check whether the question value  changed compared with edit buffer before updating edit buffer\r
+          // if changed, set the ValueChanged flag to TRUE,in order to trig the CHANGED callback function\r
+          //\r
+          IsQuestionValueChanged(gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\r
           //\r
           // According the spec, return value from call back of "changing" and \r
           // "retrieve" should update to the question's temp buffer.\r
@@ -2103,6 +2153,11 @@ ProcessCallBackFunction (
         //\r
         InternalStatus = ValueChangedValidation (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement);\r
         if (!EFI_ERROR (InternalStatus)) {\r
+          //\r
+          //check whether the question value  changed compared with edit buffer before updating edit buffer\r
+          // if changed, set the ValueChanged flag to TRUE,in order to trig the CHANGED callback function\r
+          //\r
+          IsQuestionValueChanged(gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\r
           SetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
         }\r
       }\r
@@ -2145,6 +2200,28 @@ ProcessCallBackFunction (
     }\r
   }\r
 \r
+  if (gCallbackReconnect && (EFI_BROWSER_ACTION_CHANGED == Action)) {\r
+    //\r
+    // Confirm changes with user first.\r
+    //\r
+    if (IsNvUpdateRequiredForFormSet(FormSet)) {\r
+      if (BROWSER_ACTION_DISCARD == PopupErrorMessage(BROWSER_RECONNECT_SAVE_CHANGES, NULL, NULL, NULL)) {\r
+        gCallbackReconnect = FALSE;\r
+        DiscardFormIsRequired = TRUE;\r
+      } else {\r
+        SubmitFormIsRequired = TRUE;\r
+      }\r
+    } else {\r
+      PopupErrorMessage(BROWSER_RECONNECT_REQUIRED, NULL, NULL, NULL);\r
+    }\r
+\r
+    //\r
+    // Exit current formset before do the reconnect.\r
+    //\r
+    NeedExit = TRUE;\r
+    SettingLevel = FormSetLevel;\r
+  }\r
+\r
   if (SubmitFormIsRequired && !SkipSaveOrDiscard) {\r
     SubmitForm (FormSet, Form, SettingLevel);\r
   }\r
@@ -2217,6 +2294,7 @@ ProcessRetrieveForQuestion (
 \r
     ASSERT (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth);\r
     if (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth) {\r
+      ZeroMem (Statement->BufferValue, Statement->StorageWidth);\r
       CopyMem (Statement->BufferValue, NewString, StrSize (NewString));\r
     } else {\r
       CopyMem (Statement->BufferValue, NewString, Statement->StorageWidth);\r
@@ -2284,6 +2362,12 @@ SetupBrowser (
   mCurFakeQestId = 0;\r
 \r
   do {\r
+\r
+    //\r
+    // Reset Status to prevent the next break from returning incorrect error status.\r
+    //\r
+    Status = EFI_SUCCESS;\r
+\r
     //\r
     // IFR is updated, force to reparse the IFR binary\r
     // This check is shared by EFI_BROWSER_ACTION_FORM_CLOSE and \r
@@ -2430,17 +2514,16 @@ SetupBrowser (
           //\r
           if (EFI_ERROR (Status)) {\r
             //\r
-            // Cross reference will not be taken\r
+            // Cross reference will not be taken, restore all essential field\r
             //\r
-            Selection->FormId = Selection->Form->FormId;\r
+            Selection->Handle = mCurrentHiiHandle;\r
+            CopyMem (&Selection->FormSetGuid, &mCurrentFormSetGuid, sizeof (EFI_GUID));\r
+            Selection->FormId = mCurrentFormId;\r
             Selection->QuestionId = 0;\r
+            Selection->Action = UI_ACTION_REFRESH_FORM;\r
           }\r
         }\r
 \r
-        //\r
-        // Verify whether question value has checked, update the ValueChanged flag in Question.\r
-        //\r
-        IsQuestionValueChanged(gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithBuffer);\r
 \r
         if (!EFI_ERROR (Status) && \r
             (Statement->Operand != EFI_IFR_REF_OP) && \r
@@ -2449,6 +2532,11 @@ SetupBrowser (
           // Only question value has been changed, browser will trig CHANGED callback.\r
           //\r
           ProcessCallBackFunction(Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGED, FALSE);\r
+          //\r
+          //check whether the question value changed compared with buffer value\r
+          //if doesn't change ,set the ValueChanged flag to FALSE ,in order not to display the "configuration changed "information on the screen\r
+          //\r
+          IsQuestionValueChanged(gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithBuffer);\r
         }\r
       } else {\r
         //\r
@@ -2465,13 +2553,18 @@ SetupBrowser (
       }\r
 \r
       //\r
-      // If question has EFI_IFR_FLAG_RESET_REQUIRED flag and without storage and process question success till here, \r
-      // trig the gResetFlag.\r
+      // If question has EFI_IFR_FLAG_RESET_REQUIRED/EFI_IFR_FLAG_RECONNECT_REQUIRED flag and without storage \r
+      // and process question success till here, trig the gResetFlag/gFlagReconnect.\r
       //\r
       if ((Status == EFI_SUCCESS) && \r
-          (Statement->Storage == NULL) && \r
-          ((Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) != 0)) {\r
-        gResetRequired = TRUE;\r
+          (Statement->Storage == NULL)) { \r
+        if ((Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) != 0) {\r
+          gResetRequired = TRUE;\r
+        }\r
+\r
+        if ((Statement->QuestionFlags & EFI_IFR_FLAG_RECONNECT_REQUIRED) != 0) {\r
+          gFlagReconnect = TRUE;\r
+        }\r
       }\r
     }\r
 \r