alder_lake_bios/Insyde/InsydeModulePkg/Universal/Console/SnapScreenDxe/SnapDialog.c

522 lines
11 KiB
C

/** @file
SnapScree driver for capature screen image to BMP file.
;******************************************************************************
;* Copyright (c) 2012 - 2021, 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 "SnapDialog.h"
#include "SnapLib.h"
#include "SnapWin.h"
//#include EFI_PROTOCOL_DEFINITION (FileInfo)
//#include EFI_PROTOCOL_DEFINITION (FileSystemInfo)
//#include EFI_PROTOCOL_DEFINITION (SimpleFileSystem)
#include <Guid/FileInfo.h>
#include <Guid/FileSystemInfo.h>
#include <Protocol/SimpleFileSystem.h>
#define DIALOG_NORMAL_ATTR EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLUE)
#define DIALOG_ACCENT_ATTR EFI_TEXT_ATTR (EFI_WHITE, EFI_CYAN)
#define MSG_DIALOG_HEIGHT 3
#define MAX_DISK_NAME_SIZE 256
#define MAX_DIALOG_ITEM 10
#define FS_ITEM_SIGNATURE SIGNATURE_32('D','I','A','i')
#define FS_ITEM_FROM_LINK(a) CR(a, FS_ITEM, Link, SIGNATURE_32('D','I','A','i'));
//
// Global variable
//
FS_DIALOG gFsDialog;
CHAR16 *gDiskTypeStr[] = {
L" IDE",
L"SCSI",
L" USB",
L"AHCI",
L"UNKN"
};
CHAR16 *
MakeFsName (
UINTN AIndex,
DISK_TYPE DiskType,
CHAR16 *ADiskName,
CHAR16 *AVolumeName,
CHAR16 *AVolumeSize
)
{
CHAR16 *FsName;
CHAR16 *FsSeparate = L":";
CHAR16 *DsSeparate = L"\\";
CHAR16 FsIndexStr[3] = L" 1";
CHAR16 DiskName[13] = L" ";
CHAR16 VolumeName[12] = L" ";
CHAR16 VolumeSize[12] = L" MB ";
CHAR16 *DiskTypeStr;
UINTN FsNameSize;
UINTN Index;
UINTN Len;
UINTN FsNameLen;
FsIndexStr[1] = (CHAR16) (FsIndexStr[1] + AIndex);
DiskTypeStr = gDiskTypeStr[DiskType];
if (ADiskName != NULL) {
StrnCpyS (DiskName, sizeof (DiskName) / sizeof (CHAR16), ADiskName, 12);
}
if (AVolumeName != NULL) {
StrnCpyS (VolumeName, sizeof (VolumeName) / sizeof (CHAR16), AVolumeName, 11);
}
if (AVolumeSize != NULL) {
Len = StrLen (AVolumeSize);
if (Len > 9) {
Len = 9;
}
Index = 9 - Len;
StrnCpyS (&VolumeSize[Index], sizeof (VolumeName) / sizeof (CHAR16) - Index, AVolumeSize, 9-Index);
}
// 1: AHCI\JetFlash \MURPHY_128M 120.5 MB
// 2: IDE \ST300845AS \WINDOW2008 1 TB
FsNameLen = 2+ 4 + 12 + 11 + 11 + 3;
FsNameSize = (FsNameLen + 1) * sizeof(CHAR16);
FsName = AllocatePool(FsNameSize);
if (FsName == NULL) {
return NULL;
}
for (Index=0; Index < FsNameLen; Index++)
FsName[Index] = L' ';
StrCpyS (FsName, FsNameLen + 1, FsIndexStr); // FS1
StrCatS (FsName, FsNameLen + 1, FsSeparate); // FS1:
StrCatS (FsName, FsNameLen + 1, DiskTypeStr); // FS1: USB
StrCatS (FsName, FsNameLen + 1, DsSeparate); // FS1: USB/
StrCatS (FsName, FsNameLen + 1, DiskName); // FS1: USB/JetFlash
StrCatS (FsName, FsNameLen + 1, DsSeparate); // FS1: USB/JetFlash /
StrCatS (FsName, FsNameLen + 1, VolumeName); // FS1: USB/JetFlash /MURPHY_128M
Len = StrLen (FsName);
for (Index = Len; Index < 32; Index++)
FsName[Index] = L' ';
FsName[Index] = 0;
StrCatS (FsName, FsNameLen + 1, VolumeSize); // FS1: USB/JetFlash /MURPHY_128M 120.8 MB
return FsName;
}
EFI_STATUS
TFsDialogAddItem (
FS_DIALOG *FsDialog,
EFI_HANDLE FsHandle
)
{
EFI_STATUS Status;
EFI_HANDLE ParentHandle;
DISK_TYPE DiskType = DT_UNKNOW;
CHAR16 *DiskName = NULL;
CHAR16 *VolumnName = NULL;
CHAR16 *VolumnSize = NULL;
FS_ITEM *FsItem;
Status = GetParentHandle (FsHandle, &ParentHandle);
if (EFI_ERROR(Status))
return EFI_UNSUPPORTED;
if (IsRecordableDevice (ParentHandle) == FALSE)
return EFI_UNSUPPORTED;
if (Status == EFI_SUCCESS) {
DiskType = GetDiskInfoType (ParentHandle);
DiskName = GetDiskInfoName (ParentHandle);
}
else {
ParentHandle = NULL;
}
VolumnName = GetVolumnName ( FsHandle);
VolumnSize = GetVolumnSizeAsString ( FsHandle);
FsItem = (FS_ITEM *) AllocateZeroPool (sizeof(FS_ITEM));
if (FsItem != NULL) {
FsItem->Signature = FS_ITEM_SIGNATURE;
FsItem->FsHandle = FsHandle;
FsItem->ParentHandle = ParentHandle;
FsItem->Title = MakeFsName (FsDialog->ItemCount, DiskType, DiskName, VolumnName, VolumnSize);
InsertTailList(&FsDialog->ItemHead, &FsItem->Link);
FsDialog->ItemCount++;
Status = EFI_SUCCESS;
}
else {
Status = EFI_OUT_OF_RESOURCES;
}
if (DiskName != NULL)
FreePool (DiskName);
if (VolumnName != NULL)
FreePool (VolumnName);
if (VolumnSize != NULL)
FreePool (VolumnSize);
return Status;
}
EFI_STATUS
TFsDialogCreate (
UINT16 X,
UINT16 Y,
CHAR16 *Title,
DIALOG_PROC DialogProc,
FS_DIALOG **AFsDialog
)
{
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer;
UINTN HandleCount;
UINTN Index;
UINTN Len;
UINTN MaxLen = 0;
FS_DIALOG *FsDialog;
FS_ITEM *FsItem;
LIST_ENTRY *Link;
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleFileSystemProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
if (EFI_ERROR(Status))
return Status;
FsDialog = (FS_DIALOG *) AllocateZeroPool (sizeof(FS_DIALOG));
if (FsDialog == NULL) {
return EFI_OUT_OF_RESOURCES;
}
InitializeListHead(&FsDialog->ItemHead);
FsDialog->DialogProc = DialogProc;
// Add Item to FsDialog
for (Index=0; Index < HandleCount; Index++) {
Status = TFsDialogAddItem (FsDialog, HandleBuffer[Index]);
if (FsDialog->ItemCount >= MAX_DIALOG_ITEM)
break;
}
if (FsDialog->ItemCount == 0) {
FreePool (FsDialog);
return EFI_NOT_FOUND;
}
// looking for max string length
Link = FsDialog->ItemHead.ForwardLink;
while (Link != &FsDialog->ItemHead) {
FsItem = FS_ITEM_FROM_LINK(Link);
Len = StrLen (FsItem->Title);
if (Len > MaxLen)
MaxLen = Len;
Link = Link->ForwardLink;
}
// initialize default item as selection
FsDialog->Index = 0;
FsDialog->CurrLink = FsDialog->ItemHead.ForwardLink;
// Create a window object
Status = TWinCreate (
X,
Y,
(UINT16) MaxLen,
(UINT16) FsDialog->ItemCount,
TRUE,
Title,
&FsDialog->Win
);
if (EFI_ERROR(Status)) {
TFsDialogDestroy (FsDialog);
}
else {
*AFsDialog = FsDialog;
}
FreePool (HandleBuffer);
return Status;
}
VOID
TFsDialogPrintItem (
FS_DIALOG *Dialog,
UINTN Index,
UINTN Attribute
)
{
LIST_ENTRY *Link;
FS_ITEM *FsItem;
UINT16 Y;
if (Index >= Dialog->ItemCount)
return;
Y = (UINT16) Index;
Link = Dialog->ItemHead.ForwardLink;
while (Index > 0) {
Link = Link->ForwardLink;
Index--;
}
FsItem = FS_ITEM_FROM_LINK (Link);
TWinSetAttribue (Dialog->Win, Attribute);
TWinPrintAt (Dialog->Win, 0, Y, L"%s", FsItem->Title);
}
EFI_STATUS
TFsDialogExec (
FS_DIALOG *Dialog,
EFI_HANDLE *Result
)
{
UINTN Index;
TWINDOW *Win;
EFI_INPUT_KEY EfiKey;
INT16 OldIndex;
FS_ITEM *FsItem;
Win = Dialog->Win;
TWinShow (Win);
// Print all item
for (Index = 0; Index < Dialog->ItemCount; Index++) {
TFsDialogPrintItem (Dialog, Index, DIALOG_NORMAL_ATTR);
}
TFsDialogPrintItem (Dialog, Dialog->Index, DIALOG_ACCENT_ATTR);
OldIndex = Dialog->Index;
while (TRUE) {
GetKey(&EfiKey);
switch (EfiKey.ScanCode) {
case SCAN_UP :
Dialog->Index--;
Dialog->CurrLink = Dialog->CurrLink->BackLink;
if (Dialog->Index < 0) {
Dialog->Index = (INT16)(Dialog->ItemCount - 1);
Dialog->CurrLink = Dialog->ItemHead.BackLink;
}
break;
case SCAN_DOWN :
Dialog->Index++;
Dialog->CurrLink = Dialog->CurrLink->ForwardLink;
if (Dialog->Index >= (INT16)Dialog->ItemCount) {
Dialog->Index = 0;
Dialog->CurrLink = Dialog->ItemHead.ForwardLink;
}
break;
case SCAN_ESC :
return EFI_ABORTED;
default :
if (EfiKey.UnicodeChar == CHAR_CARRIAGE_RETURN) {
FsItem = FS_ITEM_FROM_LINK(Dialog->CurrLink);
*Result = FsItem->FsHandle;
return EFI_SUCCESS;
}
}
if (Dialog->Index != OldIndex) {
TFsDialogPrintItem (Dialog, OldIndex, DIALOG_NORMAL_ATTR);
TFsDialogPrintItem (Dialog, Dialog->Index, DIALOG_ACCENT_ATTR);
OldIndex = Dialog->Index;
}
}
}
EFI_STATUS
TFsDialogDestroy (
FS_DIALOG *FsDialog
)
{
LIST_ENTRY *Link;
FS_ITEM *FsItem;
Link = FsDialog->ItemHead.ForwardLink;
while (Link != &FsDialog->ItemHead) {
FsItem = FS_ITEM_FROM_LINK(Link);
Link = Link->ForwardLink;
RemoveEntryList (&(FsItem->Link));
if (FsItem->Title != NULL)
FreePool (FsItem->Title);
FreePool (FsItem);
}
TWinDestroy (FsDialog->Win);
FreePool (FsDialog);
return EFI_SUCCESS;
}
EFI_STATUS
TMsgDialogCreate (
CHAR16 *MessageStr,
MSG_DIALOG **AMsgDialog
)
{
TWINDOW *Win;
MSG_DIALOG *MsgDialog;
UINT16 Width;
UINT16 Height;
UINTN BufferSize;
Width = (UINT16)(StrLen(MessageStr) + 2);
Height = MSG_DIALOG_HEIGHT;
BufferSize = sizeof (MSG_DIALOG) + Width * sizeof(CHAR16);
MsgDialog = (MSG_DIALOG *) AllocateZeroPool (BufferSize);
if (MsgDialog == NULL) {
return EFI_OUT_OF_RESOURCES;
}
MsgDialog->Message = (CHAR16 *)((UINT8 *)MsgDialog + sizeof (MSG_DIALOG));
StrCpyS (MsgDialog->Message, Width, MessageStr);
TWinCreate(WIN_SCR_CENTER, WIN_SCR_CENTER, Width, Height, TRUE, L"Message", &Win);
MsgDialog->Win = Win;
*AMsgDialog = MsgDialog;
return EFI_SUCCESS;
}
EFI_STATUS
TMsgDialogShow (
MSG_DIALOG *MsgDialog
)
{
if (MsgDialog->IsShow == TRUE)
return EFI_SUCCESS;
MsgDialog->IsShow = TRUE;
TWinShow (MsgDialog->Win);
TWinPrintAt ( MsgDialog->Win, 1, 1, L"%s", MsgDialog->Message);
return EFI_SUCCESS;
}
EFI_STATUS
TMsgDialogRun (
MSG_DIALOG *MsgDialog
)
{
EFI_INPUT_KEY Key;
if (MsgDialog->IsShow == FALSE) {
TMsgDialogShow (MsgDialog);
}
GetKey(&Key);
return EFI_SUCCESS;
}
EFI_STATUS
TMsgDialogDestroy (
MSG_DIALOG *MsgDialog
)
{
if (MsgDialog != NULL) {
TWinDestroy (MsgDialog->Win);
FreePool (MsgDialog);
}
return EFI_SUCCESS;
}
EFI_STATUS
PopUpMessage (
CHAR16 *MessageStr
)
{
EFI_STATUS Status;
MSG_DIALOG *MsgDialog;
Status = TMsgDialogCreate ( MessageStr, &MsgDialog);
if (EFI_ERROR(Status))
return Status;
TMsgDialogRun( MsgDialog);
Status = TMsgDialogDestroy (MsgDialog);
return Status;
}