]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add new "Refresh guid" opcode, also add sample code to use it.
authorydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 8 Jun 2011 08:09:47 +0000 (08:09 +0000)
committerydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 8 Jun 2011 08:09:47 +0000 (08:09 +0000)
Signed-off-by: ydong10
Reviewed-by: lgao4
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11767 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf
MdeModulePkg/Universal/DriverSampleDxe/NVDataStruc.h
MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni
MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
MdeModulePkg/Universal/SetupBrowserDxe/Ui.h

index 021fe6112927b977d802f09ed80d2ca5ea420d0a..e20e030be8fbf0fba1c20855a9bf2ab3eecc70b8 100644 (file)
@@ -20,10 +20,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 EFI_GUID   mFormSetGuid = FORMSET_GUID;\r
 EFI_GUID   mInventoryGuid = INVENTORY_GUID;\r
+EFI_GUID   MyEventGroupGuid = EFI_IFR_REFRESH_ID_OP_GUID;\r
 \r
 CHAR16     VariableName[] = L"MyIfrNVData";\r
 EFI_HANDLE                      DriverHandle[2] = {NULL, NULL};\r
 DRIVER_SAMPLE_PRIVATE_DATA      *PrivateData = NULL;\r
+EFI_EVENT                       mEvent;\r
 \r
 HII_VENDOR_DEVICE_PATH  mHiiVendorDevicePath0 = {\r
   {\r
@@ -75,6 +77,158 @@ HII_VENDOR_DEVICE_PATH  mHiiVendorDevicePath1 = {
   }\r
 };\r
 \r
+/**\r
+  Add empty function for event process function.\r
+\r
+  @param Event    The Event need to be process\r
+  @param Context  The context of the event.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DriverSampleInternalEmptyFunction (\r
+  IN  EFI_EVENT Event,\r
+  IN  VOID      *Context\r
+  )\r
+{\r
+}\r
+\r
+/**\r
+  Notification function for keystrokes.\r
+\r
+  @param[in] KeyData    The key that was pressed.\r
+\r
+  @retval EFI_SUCCESS   The operation was successful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+NotificationFunction(\r
+  IN EFI_KEY_DATA *KeyData\r
+  )\r
+{\r
+  gBS->SignalEvent (mEvent);\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Function to start monitoring for CTRL-C using SimpleTextInputEx. \r
+\r
+  @retval EFI_SUCCESS           The feature is enabled.\r
+  @retval EFI_OUT_OF_RESOURCES  There is not enough mnemory available.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InternalStartMonitor(\r
+  VOID\r
+  )\r
+{\r
+  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;\r
+  EFI_KEY_DATA                      KeyData;\r
+  EFI_STATUS                        Status;\r
+  EFI_HANDLE                        *Handles;\r
+  UINTN                             HandleCount;\r
+  UINTN                             HandleIndex;\r
+  EFI_HANDLE                        NotifyHandle;\r
+\r
+  Status = gBS->LocateHandleBuffer (\r
+              ByProtocol,\r
+              &gEfiSimpleTextInputExProtocolGuid,\r
+              NULL,\r
+              &HandleCount,\r
+              &Handles\r
+              );\r
+  for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
+    Status = gBS->HandleProtocol (Handles[HandleIndex], &gEfiSimpleTextInputExProtocolGuid, (VOID **) &SimpleEx);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    KeyData.KeyState.KeyToggleState = 0;\r
+    KeyData.Key.ScanCode            = 0;\r
+    KeyData.KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;\r
+    KeyData.Key.UnicodeChar         = L'c';\r
+\r
+    Status = SimpleEx->RegisterKeyNotify(\r
+      SimpleEx,\r
+      &KeyData,\r
+      NotificationFunction,\r
+      &NotifyHandle);\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+    \r
+    KeyData.KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;\r
+    Status = SimpleEx->RegisterKeyNotify(\r
+      SimpleEx,\r
+      &KeyData,\r
+      NotificationFunction,\r
+      &NotifyHandle);\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Function to stop monitoring for CTRL-C using SimpleTextInputEx.  \r
+\r
+  @retval EFI_SUCCESS           The feature is enabled.\r
+  @retval EFI_OUT_OF_RESOURCES  There is not enough mnemory available.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InternalStopMonitor(\r
+  VOID\r
+  )\r
+{\r
+  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;\r
+  EFI_STATUS                        Status;\r
+  EFI_HANDLE                        *Handles;\r
+  EFI_KEY_DATA                      KeyData;  \r
+  UINTN                             HandleCount;\r
+  UINTN                             HandleIndex;\r
+  EFI_HANDLE                        NotifyHandle;\r
+\r
+  Status = gBS->LocateHandleBuffer (\r
+                ByProtocol,\r
+                &gEfiSimpleTextInputExProtocolGuid,\r
+                NULL,\r
+                &HandleCount,\r
+                &Handles\r
+                );\r
+  for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
+    Status = gBS->HandleProtocol (Handles[HandleIndex], &gEfiSimpleTextInputExProtocolGuid, (VOID **) &SimpleEx);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    KeyData.KeyState.KeyToggleState = 0;\r
+    KeyData.Key.ScanCode            = 0;\r
+    KeyData.KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;\r
+    KeyData.Key.UnicodeChar         = L'c';\r
+\r
+    Status = SimpleEx->RegisterKeyNotify(\r
+      SimpleEx,\r
+      &KeyData,\r
+      NotificationFunction,\r
+      &NotifyHandle);\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = SimpleEx->UnregisterKeyNotify (SimpleEx, NotifyHandle);\r
+    }\r
+\r
+    KeyData.KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;\r
+    Status = SimpleEx->RegisterKeyNotify(\r
+      SimpleEx,\r
+      &KeyData,\r
+      NotificationFunction,\r
+      &NotifyHandle);\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = SimpleEx->UnregisterKeyNotify (SimpleEx, NotifyHandle);\r
+    }\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
 /**\r
   Encode the password using a simple algorithm.\r
 \r
@@ -1124,6 +1278,7 @@ DriverCallback (
   EFI_INPUT_KEY                   Key;\r
   DRIVER_SAMPLE_CONFIGURATION     *Configuration;\r
   UINTN                           MyVarSize;\r
+  EFI_FORM_ID                     FormId;\r
   \r
   if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))||\r
     (ActionRequest == NULL)) {\r
@@ -1131,6 +1286,7 @@ DriverCallback (
   }\r
 \r
 \r
+  FormId = 0;\r
   Status = EFI_SUCCESS;\r
   PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
 \r
@@ -1177,6 +1333,11 @@ DriverCallback (
 \r
         HiiFreeOpCodeHandle (StartOpCodeHandle);\r
       }\r
+\r
+      if (QuestionId == 0x1247) {\r
+        Status = InternalStartMonitor ();\r
+        ASSERT_EFI_ERROR (Status);\r
+      }\r
     }\r
     break;\r
 \r
@@ -1199,6 +1360,11 @@ DriverCallback (
             );\r
         } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
       }\r
+\r
+      if (QuestionId == 0x1247) {\r
+        Status = InternalStopMonitor ();\r
+        ASSERT_EFI_ERROR (Status);\r
+      }\r
     }\r
     break;\r
     \r
@@ -1424,6 +1590,7 @@ DriverCallback (
       break;\r
 \r
     case 0x5678:\r
+    case 0x1247:\r
       //\r
       // We will reach here once the Question is refreshed\r
       //\r
@@ -1439,7 +1606,15 @@ DriverCallback (
       //\r
       StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
       StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
-      StartLabel->Number       = LABEL_UPDATE2;\r
+      if (QuestionId == 0x5678) {\r
+        StartLabel->Number       = LABEL_UPDATE2;\r
+        FormId                   = 0x03;\r
+        PrivateData->Configuration.DynamicRefresh++;\r
+      } else if (QuestionId == 0x1247 ) {\r
+        StartLabel->Number       = LABEL_UPDATE3;\r
+        FormId                   = 0x05;\r
+        PrivateData->Configuration.RefreshGuidCount++;\r
+      }\r
 \r
       HiiCreateActionOpCode (\r
         StartOpCodeHandle,                // Container for dynamic created opcodes\r
@@ -1453,7 +1628,7 @@ DriverCallback (
       HiiUpdateForm (\r
         PrivateData->HiiHandle[0],  // HII handle\r
         &mFormSetGuid,              // Formset GUID\r
-        0x3,                        // Form ID\r
+        FormId,                        // Form ID\r
         StartOpCodeHandle,          // Label for where to insert opcodes\r
         NULL                        // Insert data\r
         );\r
@@ -1463,7 +1638,6 @@ DriverCallback (
       //\r
       // Refresh the Question value\r
       //\r
-      PrivateData->Configuration.DynamicRefresh++;\r
       Status = gRT->SetVariable(\r
                       VariableName,\r
                       &mFormSetGuid,\r
@@ -1472,19 +1646,21 @@ DriverCallback (
                       &PrivateData->Configuration\r
                       );\r
 \r
-      //\r
-      // Change an EFI Variable storage (MyEfiVar) asynchronous, this will cause\r
-      // the first statement in Form 3 be suppressed\r
-      //\r
-      MyVarSize = 1;\r
-      MyVar = 111;\r
-      Status = gRT->SetVariable(\r
-                      L"MyVar",\r
-                      &mFormSetGuid,\r
-                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
-                      MyVarSize,\r
-                      &MyVar\r
-                      );\r
+      if (QuestionId == 0x5678) {\r
+        //\r
+        // Change an EFI Variable storage (MyEfiVar) asynchronous, this will cause\r
+        // the first statement in Form 3 be suppressed\r
+        //\r
+        MyVarSize = 1;\r
+        MyVar = 111;\r
+        Status = gRT->SetVariable(\r
+                        L"MyVar",\r
+                        &mFormSetGuid,\r
+                        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+                        MyVarSize,\r
+                        &MyVar\r
+                        );\r
+      }\r
       break;\r
 \r
     case 0x1237:\r
@@ -1805,7 +1981,15 @@ DriverSampleInit (
 \r
   FreePool (ConfigRequestHdr);\r
 \r
-\r
+  Status = gBS->CreateEventEx (\r
+        EVT_NOTIFY_SIGNAL, \r
+        TPL_NOTIFY,\r
+        DriverSampleInternalEmptyFunction,\r
+        NULL,\r
+        &MyEventGroupGuid,\r
+        &mEvent\r
+        );\r
+  ASSERT_EFI_ERROR (Status);\r
   //\r
   // In default, this driver is built into Flash device image,\r
   // the following code doesn't run.\r
@@ -1893,5 +2077,7 @@ DriverSampleUnload (
   FreePool (PrivateData);\r
   PrivateData = NULL;\r
 \r
+  gBS->CloseEvent (mEvent);\r
+\r
   return EFI_SUCCESS;\r
 }\r
index 678a12ece7d0c1d4b63ce12f40bc96c3c0fc2426..81a51864142a48a947765707e6707953d53dd7f8 100644 (file)
@@ -65,6 +65,7 @@
   gEfiHiiConfigAccessProtocolGuid               ## PRODUCES\r
   gEfiFormBrowser2ProtocolGuid                  ## CONSUMES\r
   gEfiHiiDatabaseProtocolGuid                   ## CONSUMES\r
+  gEfiSimpleTextInputExProtocolGuid             ## CONSUMES\r
 \r
 \r
 [Depex]\r
index 8926ab017789c661fed63248372f868d19a17c9b..f0240301f06aa0eb62481ae13c4d1aff82eae382 100644 (file)
@@ -41,6 +41,11 @@ Revision History:
 #define EFI_USER_INFO_ACCESS_SETUP_ADMIN_GUID \\r
   { 0x85b75607, 0xf7ce, 0x471e, { 0xb7, 0xe4, 0x2a, 0xea, 0x5f, 0x72, 0x32, 0xee } }\r
 \r
+#define EFI_IFR_REFRESH_ID_OP_GUID \\r
+  { \\r
+    0xF5E655D9, 0x02A6, 0x46f2, {0x9E, 0x76, 0xB8, 0xBE, 0x8E, 0x60, 0xAB, 0x22} \\r
+  }\r
+\r
 #define CONFIGURATION_VARSTORE_ID    0x1234\r
 \r
 #pragma pack(1)\r
@@ -77,6 +82,7 @@ typedef struct {
   UINT8   GetDefaultValueFromCallBack;\r
   UINT8   GetDefaultValueFromAccess;\r
   EFI_HII_TIME  Time;\r
+  UINT8   RefreshGuidCount;\r
 } DRIVER_SAMPLE_CONFIGURATION;\r
 \r
 //\r
@@ -93,6 +99,7 @@ typedef struct {
 //\r
 #define LABEL_UPDATE1               0x1234\r
 #define LABEL_UPDATE2               0x2234\r
+#define LABEL_UPDATE3               0x3234\r
 #define LABEL_END                   0x2223\r
 \r
 #pragma pack()\r
index d0aa85266310c325c7aeca0ef786d61f5789fc7b..d09fa5f26553bb6eacbf6a819bf7aa5ffb67a043 100644 (file)
Binary files a/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni and b/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni differ
index 469b274b4411de61adabe0a8ef7edbe550b799de..d13a89797a98956f10d2e3e014a3faa7479c9bc3 100644 (file)
@@ -2068,6 +2068,14 @@ ParseOpCodes (
       CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
       break;\r
 \r
+    //\r
+    // Refresh guid.\r
+    //\r
+    case EFI_IFR_REFRESH_ID_OP:\r
+      ASSERT (CurrentStatement != NULL);\r
+      CopyMem (&CurrentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));\r
+      break;\r
+\r
     //\r
     // Modal tag\r
     //\r
index cb09fee34485d766774180731ba2ffd632a3a8cf..40d18de690fa83d8d042ced36e8759a3e8f4c2f3 100644 (file)
@@ -376,6 +376,7 @@ typedef struct {
   EFI_QUESTION_ID       RefQuestionId;    // for EFI_IFR_REF2\r
   EFI_GUID              RefFormSetId;     // for EFI_IFR_REF3\r
   EFI_STRING_ID         RefDevicePath;    // for EFI_IFR_REF4\r
+  EFI_GUID              RefreshGuid;      // for EFI_IFR_REFRESH_ID\r
 \r
   //\r
   // Get from IFR parsing\r
index 9d08c130e7a5f36137361bdbebc41dfd9fa1e129..d5f3b58b25839512955127de3dc9e8b86396c279 100644 (file)
@@ -16,7 +16,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 LIST_ENTRY          gMenuOption;\r
 LIST_ENTRY          gMenuList = INITIALIZE_LIST_HEAD_VARIABLE (gMenuList);\r
-MENU_REFRESH_ENTRY  *gMenuRefreshHead;\r
+MENU_REFRESH_ENTRY  *gMenuRefreshHead;                // Menu list used for refresh timer opcode.\r
+MENU_REFRESH_ENTRY  *gMenuEventGuidRefreshHead;       // Menu list used for refresh event guid opcode.\r
 \r
 //\r
 // Search table for UiDisplayMenu()\r
@@ -320,79 +321,142 @@ UiFreeRefreshList (
     gMenuRefreshHead = OldMenuRefreshEntry;\r
   }\r
 \r
-  gMenuRefreshHead = NULL;\r
+  while (gMenuEventGuidRefreshHead != NULL) {\r
+    OldMenuRefreshEntry = gMenuEventGuidRefreshHead->Next;\r
+    if (gMenuEventGuidRefreshHead != NULL) {\r
+      gBS->CloseEvent(gMenuEventGuidRefreshHead->Event);\r
+    }\r
+    FreePool (gMenuEventGuidRefreshHead);\r
+    gMenuEventGuidRefreshHead = OldMenuRefreshEntry;\r
+  }\r
 }\r
 \r
 \r
 \r
 /**\r
-  Refresh screen.\r
+  Refresh question.\r
 \r
+  @param     MenuRefreshEntry    Menu refresh structure which has info about the refresh question.\r
 **/\r
-EFI_STATUS\r
-RefreshForm (\r
-  VOID\r
+EFI_STATUS \r
+RefreshQuestion (\r
+  IN   MENU_REFRESH_ENTRY    *MenuRefreshEntry\r
   )\r
 {\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
 \r
-  if (gMenuRefreshHead != NULL) {\r
+  Selection = MenuRefreshEntry->Selection;\r
+  Question = MenuRefreshEntry->MenuOption->ThisTag;\r
 \r
-    MenuRefreshEntry = gMenuRefreshHead;\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
-    // Reset FormPackage update flag\r
+    // If leading spaces on OptionString - remove the spaces\r
     //\r
-    mHiiPackageListUpdated = FALSE;\r
+    for (Index = 0; OptionString[Index] == L' '; Index++)\r
+      ;\r
 \r
-    do {\r
-      Selection = MenuRefreshEntry->Selection;\r
-      Question = MenuRefreshEntry->MenuOption->ThisTag;\r
+    //\r
+    // If old Text is longer than new string, need to clean the old string before paint the newer.\r
+    // This option is no need for time/date opcode, because time/data opcode has fixed string length.\r
+    //\r
+    if ((MenuRefreshEntry->MenuOption->ThisTag->Operand != EFI_IFR_DATE_OP) &&\r
+      (MenuRefreshEntry->MenuOption->ThisTag->Operand != EFI_IFR_TIME_OP)) {\r
+      ClearLines (\r
+        MenuRefreshEntry->CurrentColumn, \r
+        MenuRefreshEntry->CurrentColumn + gOptionBlockWidth - 1,\r
+        MenuRefreshEntry->CurrentRow,\r
+        MenuRefreshEntry->CurrentRow,\r
+        PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND\r
+        );\r
+    }\r
 \r
-      Status = GetQuestionValue (Selection->FormSet, Selection->Form, Question, FALSE);\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
+    gST->ConOut->SetAttribute (gST->ConOut, MenuRefreshEntry->CurrentAttribute);\r
+    PrintStringAt (MenuRefreshEntry->CurrentColumn, MenuRefreshEntry->CurrentRow, &OptionString[Index]);\r
+    FreePool (OptionString);\r
+  }\r
 \r
-      OptionString = NULL;\r
-      ProcessOptions (Selection, MenuRefreshEntry->MenuOption, FALSE, &OptionString);\r
+  //\r
+  // Question value may be changed, need invoke its Callback()\r
+  //\r
+  Status = ProcessCallBackFunction (Selection, Question, EFI_BROWSER_ACTION_CHANGING, FALSE);\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
+  return Status;\r
+}\r
 \r
-        //\r
-        // If old Text is longer than new string, need to clean the old string before paint the newer.\r
-        // This option is no need for time/date opcode, because time/data opcode has fixed string length.\r
-        //\r
-        if ((MenuRefreshEntry->MenuOption->ThisTag->Operand != EFI_IFR_DATE_OP) &&\r
-          (MenuRefreshEntry->MenuOption->ThisTag->Operand != EFI_IFR_TIME_OP)) {\r
-          ClearLines (\r
-            MenuRefreshEntry->CurrentColumn, \r
-            MenuRefreshEntry->CurrentColumn + gOptionBlockWidth - 1,\r
-            MenuRefreshEntry->CurrentRow,\r
-            MenuRefreshEntry->CurrentRow,\r
-            PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND\r
-            );\r
-        }\r
+/**\r
+  Refresh the question which has refresh guid event attribute.\r
+  \r
+  @param Event    The event which has this function related.     \r
+  @param Context  The input context info related to this event or the status code return to the caller.\r
+**/\r
+VOID\r
+RefreshQuestionNotify(\r
+  IN      EFI_EVENT Event,\r
+  IN      VOID      *Context\r
+  )\r
+{\r
+  MENU_REFRESH_ENTRY              *MenuRefreshEntry;\r
+  UI_MENU_SELECTION               *Selection;\r
 \r
-        gST->ConOut->SetAttribute (gST->ConOut, MenuRefreshEntry->CurrentAttribute);\r
-        PrintStringAt (MenuRefreshEntry->CurrentColumn, MenuRefreshEntry->CurrentRow, &OptionString[Index]);\r
-        FreePool (OptionString);\r
-      }\r
+  //\r
+  // Reset FormPackage update flag\r
+  //\r
+  mHiiPackageListUpdated = FALSE;\r
 \r
-      //\r
-      // Question value may be changed, need invoke its Callback()\r
-      //\r
-      Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
+  MenuRefreshEntry = (MENU_REFRESH_ENTRY *)Context;\r
+  ASSERT (MenuRefreshEntry != NULL);\r
+  Selection = MenuRefreshEntry->Selection;\r
+\r
+  RefreshQuestion (MenuRefreshEntry);\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
+  } \r
+}\r
+\r
+\r
+/**\r
+  Refresh screen.\r
+\r
+**/\r
+EFI_STATUS\r
+RefreshForm (\r
+  VOID\r
+  )\r
+{\r
+  MENU_REFRESH_ENTRY              *MenuRefreshEntry;\r
+  EFI_STATUS                      Status;\r
+  UI_MENU_SELECTION               *Selection;\r
+\r
+  if (gMenuRefreshHead != NULL) {\r
+    //\r
+    // call from refresh interval process.\r
+    //\r
+    MenuRefreshEntry = gMenuRefreshHead;\r
+    Selection = MenuRefreshEntry->Selection;\r
+    //\r
+    // Reset FormPackage update flag\r
+    //\r
+    mHiiPackageListUpdated = FALSE;\r
+\r
+    do {\r
+      Status = RefreshQuestion (MenuRefreshEntry);\r
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
@@ -1636,6 +1700,7 @@ UiDisplayMenu (
   UI_CONTROL_FLAG                 ControlFlag;\r
   EFI_SCREEN_DESCRIPTOR           LocalScreen;\r
   MENU_REFRESH_ENTRY              *MenuRefreshEntry;\r
+  MENU_REFRESH_ENTRY              *MenuUpdateEntry;  \r
   UI_SCREEN_OPERATION             ScreenOperation;\r
   UINT8                           MinRefreshInterval;\r
   UINTN                           BufferSize;\r
@@ -1872,6 +1937,34 @@ UiDisplayMenu (
               OptionString[Count] = CHAR_NULL;\r
             }\r
 \r
+            //\r
+            // If Question has refresh guid, register the op-code.\r
+            //\r
+            if (!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) {\r
+              if (gMenuEventGuidRefreshHead == NULL) {\r
+                MenuUpdateEntry = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));\r
+                gMenuEventGuidRefreshHead = MenuUpdateEntry;\r
+              } else {\r
+                MenuUpdateEntry = gMenuEventGuidRefreshHead;\r
+                while (MenuUpdateEntry->Next != NULL) {\r
+                  MenuUpdateEntry = MenuUpdateEntry->Next; \r
+                }\r
+                MenuUpdateEntry->Next = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));\r
+              }\r
+              ASSERT (MenuUpdateEntry != NULL);\r
+              Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_NOTIFY, RefreshQuestionNotify, MenuUpdateEntry, &Statement->RefreshGuid, &MenuUpdateEntry->Event);\r
+              ASSERT (!EFI_ERROR (Status));\r
+              MenuUpdateEntry->MenuOption        = MenuOption;\r
+              MenuUpdateEntry->Selection         = Selection;\r
+              MenuUpdateEntry->CurrentColumn     = MenuOption->OptCol;\r
+              MenuUpdateEntry->CurrentRow        = MenuOption->Row;\r
+              if (MenuOption->GrayOut) {\r
+                MenuUpdateEntry->CurrentAttribute = FIELD_TEXT_GRAYED | FIELD_BACKGROUND;\r
+              } else {\r
+                MenuUpdateEntry->CurrentAttribute = PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND;\r
+              }\r
+            }\r
+\r
             //\r
             // If Question request refresh, register the op-code\r
             //\r
index a9f679b3d2a7986d5cb5ac3ba28b779e36be4d6c..321bdaceab287b5c550f17f13dacf70dbf0de41d 100644 (file)
@@ -178,6 +178,7 @@ struct _MENU_REFRESH_ENTRY {
   UINTN                       CurrentColumn;\r
   UINTN                       CurrentRow;\r
   UINTN                       CurrentAttribute;\r
+  EFI_EVENT                   Event;\r
 };\r
 \r
 typedef struct {\r