Generate the options for the drop-down list from the GOP resolutions.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <[email protected]>
---
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel