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