Generate the options for the drop-down list from the GOP resolutions.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <ler...@redhat.com>
---
 OvmfPkg/PlatformConfigDxe/PlatformConfig.inf |   5 +-
 OvmfPkg/PlatformConfigDxe/PlatformConfig.c   | 148 +++++++++++++++++++++++----
 2 files changed, 132 insertions(+), 21 deletions(-)

diff --git a/OvmfPkg/PlatformConfigDxe/PlatformConfig.inf 
b/OvmfPkg/PlatformConfigDxe/PlatformConfig.inf
index c3834c9..8d04ae0 100644
--- a/OvmfPkg/PlatformConfigDxe/PlatformConfig.inf
+++ b/OvmfPkg/PlatformConfigDxe/PlatformConfig.inf
@@ -38,12 +38,15 @@
   DebugLib
   DevicePathLib
   HiiLib
+  MemoryAllocationLib
+  PrintLib
   UefiBootServicesTableLib
   UefiHiiServicesLib
   UefiDriverEntryPoint
 
 [Protocols]
   gEfiDevicePathProtocolGuid      ## PRODUCES
+  gEfiGraphicsOutputProtocolGuid  ## CONSUMES
   gEfiHiiConfigAccessProtocolGuid ## PRODUCES
 
 [Guids]
@@ -51,4 +54,4 @@
   gOvmfPlatformConfigGuid
 
 [Depex]
-  TRUE
+  gEfiGraphicsOutputProtocolGuid
diff --git a/OvmfPkg/PlatformConfigDxe/PlatformConfig.c 
b/OvmfPkg/PlatformConfigDxe/PlatformConfig.c
index 49fefaf..1ab4232 100644
--- a/OvmfPkg/PlatformConfigDxe/PlatformConfig.c
+++ b/OvmfPkg/PlatformConfigDxe/PlatformConfig.c
@@ -17,9 +17,12 @@
 #include <Library/DebugLib.h>
 #include <Library/DevicePathLib.h>
 #include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/UefiHiiServicesLib.h>
 #include <Protocol/DevicePath.h>
+#include <Protocol/GraphicsOutput.h>
 #include <Protocol/HiiConfigAccess.h>
 #include <Guid/MdeModuleHii.h>
 #include <Guid/OvmfPlatformConfig.h>
@@ -96,6 +99,17 @@ STATIC EFI_HII_HANDLE mInstalledPackages;
 extern UINT8 PlatformConfigDxeStrings[];
 extern UINT8 PlatformConfigFormsBin[];
 
+//
+// Cache the resolutions we get from the GOP.
+//
+typedef struct {
+  UINT32 X;
+  UINT32 Y;
+} GOP_MODE;
+
+STATIC UINTN    mNumGopModes;
+STATIC GOP_MODE *mGopModes;
+
 
 /**
   This function is called by the HII machinery when it fetches the form state.
@@ -178,6 +192,72 @@ Callback (
 
 
 /**
+  Query and save all resolutions supported by the GOP.
+
+  @param[out] NumGopModes  The number of modes supported by the GOP. On output,
+                           this parameter will be positive.
+
+  @param[out] GopModes     On output, a dynamically allocated array containing
+                           the resolutions returned by the GOP. The caller is
+                           responsible for freeing the array after use.
+
+  @retval EFI_UNSUPPORTED       No modes found.
+  @retval EFI_OUT_OF_RESOURCES  Failed to allocate GopModes.
+  @return                       Error codes from LocateProtocol() and
+                                QueryMode().
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+QueryGopModes (
+  OUT UINTN    *NumGopModes,
+  OUT GOP_MODE **GopModes
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
+  UINT32                       ModeNumber;
+
+  Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, NULL,
+                  (VOID **) &Gop);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  if (Gop->Mode->MaxMode == 0) {
+    return EFI_UNSUPPORTED;
+  }
+  *NumGopModes = Gop->Mode->MaxMode;
+
+  *GopModes = AllocatePool (Gop->Mode->MaxMode * sizeof **GopModes);
+  if (*GopModes == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  for (ModeNumber = 0; ModeNumber < Gop->Mode->MaxMode; ++ModeNumber) {
+    EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+    UINTN                                SizeOfInfo;
+
+    Status = Gop->QueryMode (Gop, ModeNumber, &SizeOfInfo, &Info);
+    if (EFI_ERROR (Status)) {
+      goto FreeGopModes;
+    }
+
+    (*GopModes)[ModeNumber].X = Info->HorizontalResolution;
+    (*GopModes)[ModeNumber].Y = Info->VerticalResolution;
+    FreePool (Info);
+  }
+
+  return EFI_SUCCESS;
+
+FreeGopModes:
+  FreePool (*GopModes);
+
+  return Status;
+}
+
+
+/**
   Create a set of "one-of-many" (ie. "drop down list") option IFR opcodes,
   based on available GOP resolutions, to be placed under a "one-of-many" (ie.
   "drop down list") opcode.
@@ -191,6 +271,10 @@ Callback (
                             resolutions. The caller is responsible for freeing
                             OpCodeBuffer with HiiFreeOpCodeHandle() after use.
 
+  @param[in]  NumGopModes   Number of entries in GopModes.
+
+  @param[in]  GopModes      Array of resolutions retrieved from the GOP.
+
   @retval EFI_SUCESS  Opcodes have been successfully produced.
 
   @return             Status codes from underlying functions. PackageList may
@@ -202,30 +286,39 @@ EFI_STATUS
 EFIAPI
 CreateResolutionOptions (
   IN  EFI_HII_HANDLE  *PackageList,
-  OUT VOID            **OpCodeBuffer
+  OUT VOID            **OpCodeBuffer,
+  IN  UINTN           NumGopModes,
+  IN  GOP_MODE        *GopModes
   )
 {
-  EFI_STATUS                   Status;
-  VOID                         *OutputBuffer;
-  EFI_STRING_ID                NewString;
-  VOID                         *OpCode;
+  EFI_STATUS Status;
+  VOID       *OutputBuffer;
+  UINTN      ModeNumber;
 
   OutputBuffer = HiiAllocateOpCodeHandle ();
   if (OutputBuffer == NULL) {
     return EFI_OUT_OF_RESOURCES;
   }
 
-  NewString = HiiSetString (PackageList, 0 /* new string */, L"800x600",
-                NULL /* for all languages */);
-  if (NewString == 0) {
-    Status = EFI_OUT_OF_RESOURCES;
-    goto FreeOutputBuffer;
-  }
-  OpCode = HiiCreateOneOfOptionOpCode (OutputBuffer, NewString,
-             0 /* Flags */, EFI_IFR_NUMERIC_SIZE_4, 0 /* Value */);
-  if (OpCode == NULL) {
-    Status = EFI_OUT_OF_RESOURCES;
-    goto FreeOutputBuffer;
+  for (ModeNumber = 0; ModeNumber < NumGopModes; ++ModeNumber) {
+    CHAR16        Desc[MAXSIZE_RES_CUR];
+    EFI_STRING_ID NewString;
+    VOID          *OpCode;
+
+    UnicodeSPrintAsciiFormat (Desc, sizeof Desc, "%Ldx%Ld",
+      (INT64) GopModes[ModeNumber].X, (INT64) GopModes[ModeNumber].Y);
+    NewString = HiiSetString (PackageList, 0 /* new string */, Desc,
+                  NULL /* for all languages */);
+    if (NewString == 0) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto FreeOutputBuffer;
+    }
+    OpCode = HiiCreateOneOfOptionOpCode (OutputBuffer, NewString,
+               0 /* Flags */, EFI_IFR_NUMERIC_SIZE_4, ModeNumber);
+    if (OpCode == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto FreeOutputBuffer;
+    }
   }
 
   *OpCodeBuffer = OutputBuffer;
@@ -242,6 +335,9 @@ FreeOutputBuffer:
   Populate the form identified by the (PackageList, FormSetGuid, FormId)
   triplet.
 
+  The drop down list of video resolutions is generated from (NumGopModes,
+  GopModes).
+
   @retval EFI_SUCESS  Form successfully updated.
   @return             Status codes from underlying functions.
 
@@ -252,7 +348,9 @@ EFIAPI
 PopulateForm (
   IN  EFI_HII_HANDLE  *PackageList,
   IN  EFI_GUID        *FormSetGuid,
-  IN  EFI_FORM_ID     FormId
+  IN  EFI_FORM_ID     FormId,
+  IN  UINTN           NumGopModes,
+  IN  GOP_MODE        *GopModes
   )
 {
   EFI_STATUS         Status;
@@ -289,7 +387,8 @@ PopulateForm (
   //
   // 3.1. Get a list of resolutions.
   //
-  Status = CreateResolutionOptions (PackageList, &OpCodeBuffer2);
+  Status = CreateResolutionOptions (PackageList, &OpCodeBuffer2,
+             NumGopModes, GopModes);
   if (EFI_ERROR (Status)) {
     goto FreeOpCodeBuffer;
   }
@@ -389,14 +488,22 @@ PlatformConfigInit (
     goto UninstallProtocols;
   }
 
-  Status = PopulateForm (mInstalledPackages, &gOvmfPlatformConfigGuid,
-             FORMID_MAIN_FORM);
+  Status = QueryGopModes (&mNumGopModes, &mGopModes);
   if (EFI_ERROR (Status)) {
     goto RemovePackages;
   }
 
+  Status = PopulateForm (mInstalledPackages, &gOvmfPlatformConfigGuid,
+             FORMID_MAIN_FORM, mNumGopModes, mGopModes);
+  if (EFI_ERROR (Status)) {
+    goto FreeGopModes;
+  }
+
   return EFI_SUCCESS;
 
+FreeGopModes:
+  FreePool (mGopModes);
+
 RemovePackages:
   HiiRemovePackages (mInstalledPackages);
 
@@ -421,6 +528,7 @@ PlatformConfigUnload (
   IN  EFI_HANDLE  ImageHandle
   )
 {
+  FreePool (mGopModes);
   HiiRemovePackages (mInstalledPackages);
   gBS->UninstallMultipleProtocolInterfaces (ImageHandle,
          &gEfiDevicePathProtocolGuid,      &mPkgDevicePath,
-- 
1.8.3.1



------------------------------------------------------------------------------
Managing the Performance of Cloud-Based Applications
Take advantage of what the Cloud has to offer - Avoid Common Pitfalls.
Read the Whitepaper.
http://pubads.g.doubleclick.net/gampad/clk?id=121054471&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to