427 lines
14 KiB
C
427 lines
14 KiB
C
/** @file
|
|
Provide OEM to customize resolution and SCU resolution. .
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2014 - 2016, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include <PiPei.h>
|
|
#include <ChipsetSetupConfig.h>
|
|
#include <Protocol/GraphicsOutput.h>
|
|
#include <Protocol/OEMBadgingSupport.h>
|
|
#include <Protocol/JpegDecoder.h>
|
|
#include <Protocol/PcxDecoder.h>
|
|
#include <Protocol/TgaDecoder.h>
|
|
#include <Protocol/GifDecoder.h>
|
|
#include <Protocol/BmpDecoder.h>
|
|
#include <Protocol/SetupUtility.h>
|
|
#include <Library/PcdLib.h>
|
|
#include <Library/HobLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/DxeOemSvcKernelLib.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/VariableLib.h>
|
|
|
|
//
|
|
// data type definitions
|
|
//
|
|
#define OEM_LOGO_RESOULTION 0x00
|
|
|
|
//
|
|
// module variables
|
|
//
|
|
OEM_LOGO_RESOLUTION_DEFINITION mOemLogoResolutionTable = {
|
|
//
|
|
// If set logo resolution to 0, the logo resolution will be get from GetLogoResolution() function.
|
|
// Otherwise, it will use user prefer Resolution: 1024x768, 800x600, 640x480... .
|
|
// OEM_LOGO_RESOULTION(resoultion depend on OEM logo)
|
|
//
|
|
OEM_LOGO_RESOULTION, // LogoResolutionX;
|
|
OEM_LOGO_RESOULTION, // LogoResolutionY;
|
|
//
|
|
// SCU can support different resolutions ex:640x480, 800x600, 1024x768...
|
|
// If user changes the resolution, please make sure
|
|
// $(EFI_SOURCE)\$(PROJECT_FAMILY)\$(PROJECT_FAMILY)\OemServices\Dxe\UpdateFormLen\UpdateFormLen.c
|
|
// also updating to correct value.
|
|
//
|
|
1024, // SCUResolutionX;
|
|
768 // SCUResolutionY;
|
|
};
|
|
|
|
BOOLEAN mUpdateLogoResolution = FALSE;
|
|
STATIC OEM_LOGO_RESOLUTION_DEFINITION mReturnResolutionTable;
|
|
|
|
STATIC
|
|
VOID
|
|
SwapResolutionTableXY (
|
|
OEM_LOGO_RESOLUTION_DEFINITION *ResolutionTable
|
|
)
|
|
{
|
|
UINT32 TmpX;
|
|
|
|
TmpX = ResolutionTable->LogoResolutionX;
|
|
ResolutionTable->LogoResolutionX = ResolutionTable->LogoResolutionY;
|
|
ResolutionTable->LogoResolutionY = TmpX;
|
|
|
|
TmpX = ResolutionTable->ScuResolutionX;
|
|
ResolutionTable->ScuResolutionX = ResolutionTable->ScuResolutionY;
|
|
ResolutionTable->ScuResolutionY = TmpX;
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// helper function prototypes
|
|
//
|
|
EFI_STATUS
|
|
GetLogoResolution (
|
|
OUT UINT32 *LogoResolutionX,
|
|
OUT UINT32 *LogoResolutionY
|
|
);
|
|
|
|
/**
|
|
Initialize module variable mPostKeyToOperation.
|
|
|
|
@param LogoResolutionX Horizontal Logo resolution.
|
|
@param LogoResolutionY Vertical Logo resolution.
|
|
|
|
@retval EFI_UNSUPPORTED Unsupported logo format.
|
|
**/
|
|
EFI_STATUS
|
|
GetLogoResolution (
|
|
OUT UINT32 *LogoResolutionX,
|
|
OUT UINT32 *LogoResolutionY
|
|
)
|
|
{
|
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
|
|
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
|
|
UINTN BltSize;
|
|
EFI_JPEG_DECODER_PROTOCOL *JpegDecoder;
|
|
EFI_JPEG_DECODER_STATUS DecoderStatus;
|
|
EFI_PCX_DECODER_PROTOCOL *PcxDecoder;
|
|
EFI_TGA_DECODER_PROTOCOL *TgaDecoder;
|
|
EFI_BMP_DECODER_PROTOCOL *BmpDecoder;
|
|
TGA_FORMAT TgaFormate;
|
|
BOOLEAN HasAlphaChannel;
|
|
EFI_OEM_BADGING_SUPPORT_PROTOCOL *Badging;
|
|
EFI_BADGING_SUPPORT_DISPLAY_ATTRIBUTE Attribute;
|
|
EFI_BADGING_SUPPORT_FORMAT Format;
|
|
EFI_BADGING_SUPPORT_IMAGE_TYPE Type;
|
|
UINT8 *ImageData;
|
|
UINTN ImageSize;
|
|
UINTN CoordinateX;
|
|
UINTN CoordinateY;
|
|
UINT32 Instance;
|
|
UINTN Height;
|
|
UINTN Width;
|
|
UINTN LocX;
|
|
UINTN LocY;
|
|
EFI_STATUS Status;
|
|
EFI_GIF_DECODER_PROTOCOL *GifDecoder;
|
|
ANIMATION *Animation;
|
|
|
|
Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Badging = NULL;
|
|
Status = gBS->LocateProtocol (&gEfiOEMBadgingSupportProtocolGuid, NULL, (VOID **)&Badging);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//
|
|
// Set the request for the first image of type Logo
|
|
//
|
|
Instance = 0;
|
|
Type = EfiBadgingSupportImageLogo;
|
|
Format = EfiBadgingSupportFormatBMP;
|
|
|
|
while (TRUE) {
|
|
ImageData = NULL;
|
|
ImageSize = 0;
|
|
|
|
Status = Badging->GetImage (
|
|
Badging,
|
|
&Instance,
|
|
&Type,
|
|
&Format,
|
|
&ImageData,
|
|
&ImageSize,
|
|
&Attribute,
|
|
&CoordinateX,
|
|
&CoordinateY
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
//
|
|
// Determine and video resolution based on the logo
|
|
//
|
|
if (Type != EfiBadgingSupportImageLogo) {
|
|
gBS->FreePool (ImageData);
|
|
continue;
|
|
}
|
|
Blt = NULL;
|
|
BltSize = 0;
|
|
Height = 0;
|
|
Width = 0;
|
|
TgaFormate = UnsupportedTgaFormat;
|
|
HasAlphaChannel = FALSE;
|
|
|
|
switch (Format) {
|
|
|
|
case EfiBadgingSupportFormatBMP:
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiBmpDecoderProtocolGuid,
|
|
NULL,
|
|
(VOID **)&BmpDecoder
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = BmpDecoder->DecodeImage (
|
|
BmpDecoder,
|
|
ImageData,
|
|
ImageSize,
|
|
(UINT8 **)&Blt,
|
|
&BltSize,
|
|
&Height,
|
|
&Width
|
|
);
|
|
}
|
|
break;
|
|
|
|
case EfiBadgingSupportFormatTGA:
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiTgaDecoderProtocolGuid,
|
|
NULL,
|
|
(VOID **)&TgaDecoder
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = TgaDecoder->DecodeImage (
|
|
TgaDecoder,
|
|
ImageData,
|
|
ImageSize,
|
|
(UINT8 **)&Blt,
|
|
&BltSize,
|
|
&Height,
|
|
&Width,
|
|
&TgaFormate,
|
|
&HasAlphaChannel
|
|
);
|
|
}
|
|
break;
|
|
|
|
case EfiBadgingSupportFormatJPEG:
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiJpegDecoderProtocolGuid,
|
|
NULL,
|
|
(VOID **)&JpegDecoder
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = JpegDecoder->DecodeImage (
|
|
JpegDecoder,
|
|
ImageData,
|
|
ImageSize,
|
|
(UINT8 **)&Blt,
|
|
&BltSize,
|
|
&Height,
|
|
&Width,
|
|
&DecoderStatus
|
|
);
|
|
}
|
|
break;
|
|
|
|
case EfiBadgingSupportFormatPCX:
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiPcxDecoderProtocolGuid,
|
|
NULL,
|
|
(VOID **)&PcxDecoder
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = PcxDecoder->DecodeImage (
|
|
PcxDecoder,
|
|
ImageData,
|
|
ImageSize,
|
|
(UINT8 **)&Blt,
|
|
&BltSize,
|
|
&Height,
|
|
&Width
|
|
);
|
|
}
|
|
break;
|
|
|
|
case EfiBadgingSupportFormatGIF:
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiGifDecoderProtocolGuid,
|
|
NULL,
|
|
(VOID **)&GifDecoder
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = GifDecoder->CreateAnimationFromMem (
|
|
GifDecoder,
|
|
ImageData,
|
|
ImageSize,
|
|
NULL,
|
|
&Animation
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
Width = Animation->Width;
|
|
Height = Animation->Height;
|
|
|
|
GifDecoder->DestroyAnimation (
|
|
GifDecoder,
|
|
Animation
|
|
);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
Status = EFI_UNSUPPORTED;
|
|
break;
|
|
}
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
gBS->FreePool (ImageData);
|
|
continue;
|
|
}
|
|
|
|
gBS->FreePool (ImageData);
|
|
gBS->FreePool (Blt);
|
|
|
|
if (Badging->OemVideoModeScrStrXY (Badging, OemSupportedVideoMode, (UINT32)Width, (UINT32)Height, &LocX, &LocY)) {
|
|
*LogoResolutionX = (UINT32) Width;
|
|
*LogoResolutionY = (UINT32) Height;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Get OEM customization resolution and SCU resolution.
|
|
Customization resolution provides OEM to define logo resolution directly or call GetLogoResolution () function to get logo resolution automatically.
|
|
|
|
@param[out] **OemLogoResolutionTable A double pointer to OEM_LOGO_RESOLUTION_DEFINITION
|
|
|
|
@retval EFI_MEDIA_CHANGED Get resolution information successful.
|
|
@retval Others Base on OEM design.
|
|
**/
|
|
EFI_STATUS
|
|
OemSvcLogoResolution (
|
|
IN OUT OEM_LOGO_RESOLUTION_DEFINITION **OemLogoResolutionTable
|
|
)
|
|
{
|
|
EFI_SETUP_UTILITY_PROTOCOL *SetupUtility;
|
|
CHIPSET_CONFIGURATION *SystemConfiguration = NULL;
|
|
EFI_STATUS Status;
|
|
EFI_BOOT_MODE BootMode;
|
|
UINT32 OemLogoX;
|
|
UINT32 OemLogoY;
|
|
|
|
SetupUtility = NULL;
|
|
Status = EFI_SUCCESS;
|
|
|
|
if (*OemLogoResolutionTable != NULL) {
|
|
if ((*OemLogoResolutionTable)->LogoResolutionX != 800 &&
|
|
(*OemLogoResolutionTable)->LogoResolutionY != 600) {
|
|
//
|
|
// Please refer to gInsydeTokenSpaceGuid.PcdDefaultLogoResolution for default resolution
|
|
//
|
|
|
|
//
|
|
// If the resolution is different from default vaules,
|
|
// that means native resolution was found, and we only provides SCU resolution here
|
|
//
|
|
(*OemLogoResolutionTable)->ScuResolutionX = mOemLogoResolutionTable.ScuResolutionX;
|
|
(*OemLogoResolutionTable)->ScuResolutionY = mOemLogoResolutionTable.ScuResolutionY;
|
|
|
|
if (FeaturePcdGet (PcdH2ORotateScreenSupported) && PcdGetBool (PcdH2ORotateScreenRotateLogo)) {
|
|
SwapResolutionTableXY (*OemLogoResolutionTable);
|
|
}
|
|
return EFI_MEDIA_CHANGED;
|
|
}
|
|
}
|
|
if (!mUpdateLogoResolution) {
|
|
BootMode = GetBootModeHob ();
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiSetupUtilityProtocolGuid,
|
|
NULL,
|
|
(VOID **)&SetupUtility
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
if (*OemLogoResolutionTable == NULL) {
|
|
(*OemLogoResolutionTable) = &mOemLogoResolutionTable;
|
|
if (FeaturePcdGet (PcdH2ORotateScreenSupported) && PcdGetBool (PcdH2ORotateScreenRotateLogo)) {
|
|
CopyMem (&mReturnResolutionTable, &mOemLogoResolutionTable, sizeof (OEM_LOGO_RESOLUTION_DEFINITION));
|
|
SwapResolutionTableXY (&mReturnResolutionTable);
|
|
(*OemLogoResolutionTable) = &mReturnResolutionTable;
|
|
}
|
|
}
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
SystemConfiguration = CommonGetVariableData (SETUP_VARIABLE_NAME, &gSystemConfigurationGuid);
|
|
if (SystemConfiguration == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if ( ( BootMode == BOOT_IN_RECOVERY_MODE ) || ( SystemConfiguration->QuietBoot == FALSE ) ) {
|
|
mOemLogoResolutionTable.LogoResolutionX = mOemLogoResolutionTable.ScuResolutionX;
|
|
mOemLogoResolutionTable.LogoResolutionY = mOemLogoResolutionTable.ScuResolutionY;
|
|
} else if ( mOemLogoResolutionTable.LogoResolutionX == OEM_LOGO_RESOULTION ) {
|
|
Status = GetLogoResolution (&OemLogoX, &OemLogoY);
|
|
if (!EFI_ERROR (Status)) {
|
|
mOemLogoResolutionTable.LogoResolutionX = OemLogoX;
|
|
mOemLogoResolutionTable.LogoResolutionY = OemLogoY;
|
|
if (*OemLogoResolutionTable != NULL) {
|
|
(*OemLogoResolutionTable)->LogoResolutionX = mOemLogoResolutionTable.LogoResolutionX;
|
|
(*OemLogoResolutionTable)->LogoResolutionY = mOemLogoResolutionTable.LogoResolutionY;
|
|
}
|
|
} else {
|
|
mOemLogoResolutionTable.LogoResolutionX = 800;
|
|
mOemLogoResolutionTable.LogoResolutionY = 600;
|
|
}
|
|
}
|
|
mUpdateLogoResolution = TRUE;
|
|
gBS->FreePool (SystemConfiguration);
|
|
}
|
|
|
|
if (*OemLogoResolutionTable == NULL) {
|
|
//
|
|
// The table is only NULL when the caller is an Ecp driver,
|
|
// this case can be removed when there's no Ecp caller.
|
|
//
|
|
|
|
//
|
|
// No native resolution is found
|
|
// Use resolution table above
|
|
//
|
|
(*OemLogoResolutionTable) = &mOemLogoResolutionTable;
|
|
if (FeaturePcdGet (PcdH2ORotateScreenSupported) && PcdGetBool (PcdH2ORotateScreenRotateLogo)) {
|
|
CopyMem (&mReturnResolutionTable, &mOemLogoResolutionTable, sizeof (OEM_LOGO_RESOLUTION_DEFINITION));
|
|
SwapResolutionTableXY (&mReturnResolutionTable);
|
|
(*OemLogoResolutionTable) = &mReturnResolutionTable;
|
|
}
|
|
|
|
} else {
|
|
(*OemLogoResolutionTable)->ScuResolutionX = mOemLogoResolutionTable.ScuResolutionX;
|
|
(*OemLogoResolutionTable)->ScuResolutionY = mOemLogoResolutionTable.ScuResolutionY;
|
|
if (FeaturePcdGet (PcdH2ORotateScreenSupported) && PcdGetBool (PcdH2ORotateScreenRotateLogo)) {
|
|
SwapResolutionTableXY (*OemLogoResolutionTable);
|
|
}
|
|
}
|
|
return EFI_MEDIA_CHANGED;
|
|
}
|
|
|