UEFI 学习 (1) —— GUI 单一颜色界面

代码:

/*Function: 
 * 1. 
 * 2. 
 *
 * ERSAN 1351171889@qq.com
*/

#include <Uefi.h>
#include <Base.h>
#include <Library/PcdLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseLib.h>
#include <Protocol/SimpleTextIn.h>
#include <Protocol/SimpleTextInEx.h>
#include <Protocol/GraphicsOutput.h>
#include <Protocol/HiiFont.h>

/* Global variables */
EFI_SIMPLE_TEXT_INPUT_PROTOCOL * SimpleTextInput;
EFI_GRAPHICS_OUTPUT_PROTOCOL * g_GraphicsOutput;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL * g_SimpleTextInputEx;
EFI_HII_FONT_PROTOCOL * g_HiiFont;
UINT32 SetModeNumber;


/* Functions declare */
EFI_STATUS LocateGraphicsOutputProtocol(void);
EFI_STATUS QueryDisplayMode(void);
EFI_STATUS UseBltOutput(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer);
EFI_STATUS LocateHiiFontProtocol(void);



/* Marco define */
#define SCAN_CODE_ESC 0x0017


EFI_GRAPHICS_OUTPUT_BLT_PIXEL ColorTable[10] = {
	{0,0,0,0},              /* 0 - black */
	{255,255,255,0},        /* 1 - white */
	{200,208,212,0},        /* 2 - light gray */
	{167,95,18,0},          /* 3 - deep blue */
	{64,64,64,0},           /* 4 - dark black */
	{128,128,128,0},        /* 5 - light black */
	{0,255,255,0},          /* 6 - yellow */
	{0,153,0,0},            /* 7 - green */
	{0,0,153,0},            /* 8 - red */
	{192,0,0,0},            /* 9 - blue */
};

EFI_FONT_DISPLAY_INFO DefaultSimpleFont = {
	{0,0,255,0}, //BGRA
	{192,0,0,0},
	EFI_FONT_INFO_ANY_FONT,
	{EFI_HII_FONT_STYLE_NORMAL, 1000, L'0'}
};

EFI_IMAGE_OUTPUT ImageOutput = {1024,768,NULL};
EFI_IMAGE_OUTPUT * g_ImageOutput = &ImageOutput;

EFI_STATUS LocateGraphicsOutputProtocol(void)
{
	EFI_STATUS Status;
	
	// locate protocol
	Status = gBS->LocateProtocol(&gEfiGraphicsOutputProtocolGuid, NULL, (void **)&g_GraphicsOutput);
	
	if(EFI_ERROR(Status))
	{
		Print(L"Locate GraphicsOutput Protocol Failed!\n");
	}
	return Status;
}

EFI_STATUS QueryDisplayMode(void)
{
	EFI_STATUS Status;
	
	UINT32 i, MaxModeNumber = 0, CurrentMode;
	UINTN SizeOfInfo;
	EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
	UINT32 Version, HorRes, VerRes, PixelsPerScanLine;
	EFI_GRAPHICS_PIXEL_FORMAT PixelFormat, buf;
	EFI_PIXEL_BITMASK PixelInformation;
	UINT32 RedMask, GreenMask, BlueMask;
	
	
	MaxModeNumber = g_GraphicsOutput->Mode->MaxMode;
	CurrentMode = g_GraphicsOutput->Mode->Mode;
	
	Print(L"MaxModeNumber = %d\n", MaxModeNumber);
	Print(L"CurrentMode = %d\n", CurrentMode);
	
	
	for(i=0; i<MaxModeNumber; i++)
	{
		Status = g_GraphicsOutput->QueryMode(g_GraphicsOutput, i, &SizeOfInfo, &Info);
		
		if(EFI_ERROR(Status))
		{
			Print(L"ModeNumber[%d]  failed\n", i);
			continue;
		}
		
		Version = Info->Version;
		HorRes = Info->HorizontalResolution;
		VerRes = Info->VerticalResolution;
		PixelFormat = Info->PixelFormat;
		PixelsPerScanLine = Info->PixelsPerScanLine;

		Print(L"Support Mode:%d\n", i);
		Print(L"Version = %d  %d x %d  ", Version, HorRes, VerRes);
		Print(L"PixelFormat = %d ", PixelFormat);
		
		if(HorRes == 1024 &&  VerRes == 768)
			SetModeNumber = i;
		else
			SetModeNumber = CurrentMode;
		
		buf = PixelFormat + 1;
		switch(buf)
		{
			// RGBA 8bit
			case 1:
				Print(L"(RGBA 8bit)  ");
			    break;
			
			// BGRA 8bit
			case 2:
				Print(L"(BGRA 8bit)  ");
				break;
			
			// BitMask
			case 3:
				PixelInformation = Info->PixelInformation;
				RedMask = PixelInformation.RedMask;
				GreenMask = PixelInformation.GreenMask;
				BlueMask = PixelInformation.BlueMask;
				Print(L"(BitMask)  PixelInformation = %d  [%d,%d,%d]", PixelInformation, RedMask, GreenMask, BlueMask);
				break;
			
			// BltOnly
			case 4:
				Print(L"(BltOnly)  ");
				break;
			
			// PixelFormatMax
			case 5:
				Print(L"(PixelFormatMax)  ");
				break;
		}
		
		Print(L"PixelsPerScanLine = %d\n",PixelsPerScanLine);
	}
	
	return Status;
}


EFI_STATUS UseBltOutput(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer)
{
	EFI_STATUS Status;
	Status = g_GraphicsOutput->Blt(g_GraphicsOutput, 
								   BltBuffer, 
								   EfiBltVideoFill,
								   0, 0,
								   0, 0,
								   1024, 768,
								   0);
	if(EFI_ERROR(Status))
	{
		Print(L"UseBltOutput() failed\n");
		return Status;
	}
	
	return Status;
}

EFI_STATUS LocateHiiFontProtocol(void)
{
	EFI_STATUS Status;
	
	// locate protocol
	Status = gBS->LocateProtocol(&gEfiHiiFontProtocolGuid, NULL, (void **)&g_HiiFont);
	
	if(EFI_ERROR(Status))
	{
		Print(L"Locate Hii Font Protocol Failed!\n");
	}
	return Status;
}

EFI_STATUS LocateSimpleTextInputExProtocol(void)
{
	EFI_STATUS Status;
	
	// locate protocol
	Status = gBS->LocateProtocol(&gEfiSimpleTextInputExProtocolGuid, NULL, (void **)&g_SimpleTextInputEx);
	
	if(EFI_ERROR(Status))
	{
		Print(L"Locate SimpleTextInputEx Protocol Failed!\n");
	}
	return Status;
}

EFI_STATUS OutText(CHAR16 * str, UINTN x, UINTN y)
{
	EFI_STATUS Status;
	
	// ImageOutput.Image.Bitmap = {1024,768,NULL};
	g_ImageOutput->Image.Bitmap = AllocateZeroPool(1024*768);
	
	Status = g_HiiFont->StringToImage( g_HiiFont,
									   // EFI_HII_OUT_FLAG_CLIP |
									   // EFI_HII_OUT_FLAG_CLIP_CLEAN_Y | EFI_HII_OUT_FLAG_CLIP_CLEAN_X |
									   EFI_HII_IGNORE_LINE_BREAK | EFI_HII_OUT_FLAG_TRANSPARENT,
									   (CHAR16 *)str,
									   (const EFI_FONT_DISPLAY_INFO *)(&DefaultSimpleFont),
									   &g_ImageOutput,
									   (UINTN) x,
									   (UINTN) y,
									   NULL,
									   NULL,
									   NULL
 									  );
	FreePool(g_ImageOutput->Image.Bitmap);
	return Status;
}

EFI_STATUS ShowText(CHAR16 * str, UINTN x, UINTN y)
{
	EFI_STATUS Status;
	
	EFI_IMAGE_OUTPUT Screen = {1024,768,NULL};
	EFI_IMAGE_OUTPUT * g_Screen = &Screen;
	
	Screen.Image.Screen = g_GraphicsOutput;
	
	
	Status = g_HiiFont->StringToImage( g_HiiFont,
									   EFI_HII_IGNORE_IF_NO_GLYPH | 
									   // EFI_HII_OUT_FLAG_CLIP |
									   // EFI_HII_OUT_FLAG_CLIP_CLEAN_X | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y |   
									   EFI_HII_IGNORE_LINE_BREAK |  EFI_HII_DIRECT_TO_SCREEN , 
									   (CHAR16 *)str,
									   (const EFI_FONT_DISPLAY_INFO *)(&DefaultSimpleFont),
									   &g_Screen,
									   (UINTN) x,
									   (UINTN) y,
									   NULL,
									   NULL,
									   NULL
 									  );
	return Status;
}

EFI_STATUS
EFIAPI
UefiMain(
	IN EFI_HANDLE ImageHandle,
	IN EFI_SYSTEM_TABLE *SystemTable
)
{
	EFI_STATUS Status;
	EFI_INPUT_KEY Key;
	UINTN Event = 0;
	
	
	Status = LocateGraphicsOutputProtocol();
	if(EFI_ERROR(Status))
	{
		return Status;
	}
	
	Status = LocateHiiFontProtocol();
	if(EFI_ERROR(Status))
	{
		return Status;
	}
	
	
	Status = QueryDisplayMode();
	if(EFI_ERROR(Status))
	{
		return Status;
	}
	
	gST->ConOut->ClearScreen(gST->ConOut);
	gST->ConOut->EnableCursor(gST->ConOut, FALSE);
	
	// set display ouput mode: 1024x768
	Status = g_GraphicsOutput->SetMode(g_GraphicsOutput, SetModeNumber);
	if(EFI_ERROR(Status))
	{
		Print(L"SetMode failed!\n");
		return Status;
	}
	
	
	// set background color
	Status = UseBltOutput(&ColorTable[9]); // bule
	if(EFI_ERROR(Status))
	{
		return Status;
	}
	
	Status = OutText(L"Test0", 100, 100);
	if(EFI_ERROR(Status))
	{
		Print(L"OutText fail\n");
		return Status;
	}
	
	Status = ShowText(L"Test0", 100, 100);
	if(EFI_ERROR(Status))
	{
		Print(L"ShowText fail\n");
		return Status;
	}

	
	// clear screen
	gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &Event);
    gST->ConIn->ReadKeyStroke(gST->ConIn,&Key);
	
	if( Key.ScanCode ==  SCAN_CODE_ESC)
	{
		Status = UseBltOutput(&ColorTable[0]); // black
		gST->ConOut->EnableCursor(gST->ConOut, TRUE);
	}
	
	return EFI_SUCCESS;
}

效果展现:
在这里插入图片描述

字体大小无法改变,猜测可能是在 HIIDATABASE 中没有 FontInfo 指定的 Font。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hi小黄人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值