482 lines
7.8 KiB
C
482 lines
7.8 KiB
C
/** @file
|
|
UI Manager
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2012 - 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 "UiControls.h"
|
|
|
|
EFI_SETUP_MOUSE_PROTOCOL *mSetupMouse = NULL;
|
|
|
|
UI_CONTROL *
|
|
EFIAPI
|
|
UiManagerFindControlByName (
|
|
IN UI_MANAGER *This,
|
|
IN CHAR16 *Name
|
|
)
|
|
{
|
|
return (UI_CONTROL *)StringMapFind (&This->NameList, Name);
|
|
}
|
|
|
|
VOID
|
|
EFIAPI
|
|
UiManagerGetControlRect (
|
|
IN UI_MANAGER *This,
|
|
IN UI_CONTROL *Control,
|
|
OUT RECT *Rect
|
|
)
|
|
{
|
|
|
|
RECT RootRc;
|
|
|
|
GetWindowRect (This->Root, &RootRc);
|
|
GetWindowRect (Control->Wnd, Rect);
|
|
|
|
OffsetRect (Rect, -RootRc.left, -RootRc.top);
|
|
}
|
|
|
|
VOID
|
|
EFIAPI
|
|
UiManagerSetControlRect (
|
|
IN UI_MANAGER *This,
|
|
IN UI_CONTROL *Control,
|
|
IN RECT *Rect
|
|
)
|
|
{
|
|
|
|
RECT RootRc;
|
|
|
|
GetWindowRect (This->Root, &RootRc);
|
|
OffsetRect (Rect, RootRc.left, RootRc.top);
|
|
|
|
ScreenToClient (Control->Wnd->parent, (POINT *)Rect);
|
|
ScreenToClient (Control->Wnd->parent, (POINT *)Rect + 1);
|
|
|
|
MoveWindow (Control->Wnd, Rect->left, Rect->top,
|
|
Rect->right - Rect->left + 1, Rect->bottom - Rect->top + 1, TRUE);
|
|
}
|
|
|
|
#define DEFAULT_FONT_SIZE 19
|
|
|
|
UINT32
|
|
EFIAPI
|
|
UiManagerGetDefaultFontSize (
|
|
IN UI_MANAGER *This
|
|
)
|
|
{
|
|
|
|
return This->DefaultFontSize;
|
|
}
|
|
|
|
UINTN
|
|
EFIAPI
|
|
UiManagerSetDefaultFontSize (
|
|
IN UI_MANAGER *This,
|
|
IN UINT32 FontSize
|
|
)
|
|
{
|
|
|
|
UINTN OldFontSize;
|
|
|
|
OldFontSize = This->DefaultFontSize;
|
|
This->DefaultFontSize = FontSize;
|
|
|
|
return OldFontSize;
|
|
}
|
|
|
|
VOID
|
|
EFIAPI
|
|
InitUiManager (
|
|
IN UI_MANAGER *This
|
|
)
|
|
{
|
|
ZeroMem (This, sizeof (UI_MANAGER));
|
|
|
|
This->Root = NULL;
|
|
This->Instance = NULL;
|
|
This->NeedUpdatePos = TRUE;
|
|
This->DefaultFontSize = DEFAULT_FONT_SIZE;
|
|
This->DoOffScreen = TRUE;
|
|
|
|
InitializeListHead (&This->OptionGroup.Link);
|
|
InitializeListHead (&This->NameList.Link);
|
|
|
|
This->FindControlByName = UiManagerFindControlByName;
|
|
This->GetControlRect = UiManagerGetControlRect;
|
|
This->SetControlRect = UiManagerSetControlRect;
|
|
This->SetDefaultFontSize = UiManagerSetDefaultFontSize;
|
|
This->GetDefaultFontSize = UiManagerGetDefaultFontSize;
|
|
}
|
|
|
|
VOID
|
|
EFIAPI
|
|
DestroyUiManager (
|
|
IN UI_MANAGER *This
|
|
)
|
|
{
|
|
StringMapRemoveAll (&This->OptionGroup);
|
|
StringMapRemoveAll (&This->NameList);
|
|
FreePool (This);
|
|
}
|
|
|
|
VOID
|
|
EFIAPI
|
|
StrTrim (
|
|
IN OUT CHAR16 *str,
|
|
IN CHAR16 c
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Removes (trims) specified leading and trailing characters from a string.
|
|
|
|
Arguments:
|
|
|
|
str - Pointer to the null-terminated string to be trimmed. On return,
|
|
str will hold the trimmed string.
|
|
c - Character will be trimmed from str.
|
|
|
|
Returns:
|
|
|
|
--*/
|
|
{
|
|
CHAR16 *p1;
|
|
|
|
CHAR16 *p2;
|
|
|
|
ASSERT (str != NULL);
|
|
|
|
if (*str == 0) {
|
|
return ;
|
|
}
|
|
//
|
|
// Trim off the leading characters c
|
|
//
|
|
for (p1 = str; *p1 && *p1 == c; p1++) {
|
|
;
|
|
}
|
|
|
|
p2 = str;
|
|
if (p2 == p1) {
|
|
while (*p1) {
|
|
p2++;
|
|
p1++;
|
|
}
|
|
} else {
|
|
while (*p1) {
|
|
*p2 = *p1;
|
|
p1++;
|
|
p2++;
|
|
}
|
|
|
|
*p2 = 0;
|
|
}
|
|
|
|
for (p1 = str + StrLen (str) - 1; p1 >= str && *p1 == c; p1--) {
|
|
;
|
|
}
|
|
|
|
if (p1 != str + StrLen (str) - 1) {
|
|
*(p1 + 1) = 0;
|
|
}
|
|
}
|
|
|
|
|
|
UINT64
|
|
StrToUInt (
|
|
IN CHAR16 *Str,
|
|
IN UINTN Base,
|
|
OUT EFI_STATUS *Status
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Transfer a string to an unsigned integer
|
|
|
|
Arguments:
|
|
Str Source string
|
|
Base Base
|
|
Status The status
|
|
|
|
Returns:
|
|
|
|
The value about the string
|
|
|
|
--*/
|
|
{
|
|
UINT64 Value;
|
|
UINT64 NewValue;
|
|
CHAR16 *StrTail;
|
|
CHAR16 c;
|
|
UINTN Len;
|
|
|
|
Value = 0;
|
|
*Status = EFI_ABORTED;
|
|
|
|
if (!*Str) {
|
|
return 0;
|
|
}
|
|
|
|
StrTrim (Str, L' ');
|
|
|
|
Len = StrLen (Str);
|
|
StrTail = Str + Len - 1;
|
|
//
|
|
// Check hex prefix '0x'
|
|
//
|
|
if (Len >= 2 && *Str == '0' && (*(Str + 1) == 'x' || *(Str + 1) == 'X')) {
|
|
Str += 2;
|
|
Len -= 2;
|
|
if (Base == 10) {
|
|
Base = 16;
|
|
}
|
|
if (Base != 16) {
|
|
*Status = EFI_ABORTED;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (!Len) {
|
|
return 0;
|
|
}
|
|
//
|
|
// Convert the string to value
|
|
//
|
|
for (; Str <= StrTail; Str++) {
|
|
|
|
c = *Str;
|
|
|
|
if (Base == 16) {
|
|
if (RShiftU64 (Value, 60)) {
|
|
//
|
|
// Overflow here x16
|
|
//
|
|
return 0;
|
|
}
|
|
|
|
NewValue = LShiftU64 (Value, 4);
|
|
} else {
|
|
if (RShiftU64 (Value, 61)) {
|
|
//
|
|
// Overflow here x8
|
|
//
|
|
return 0;
|
|
}
|
|
|
|
NewValue = LShiftU64 (Value, 3);
|
|
Value = LShiftU64 (Value, 1);
|
|
NewValue += Value;
|
|
if (NewValue < Value) {
|
|
//
|
|
// Overflow here
|
|
//
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Value = NewValue;
|
|
|
|
if (Base == 16 && c >= 'a' && c <= 'f') {
|
|
c = (CHAR16) (c - 'a' + 'A');
|
|
}
|
|
|
|
if (Base == 16 && c >= 'A' && c <= 'F') {
|
|
Value += (c - 'A') + 10;
|
|
} else if (c >= '0' && c <= '9') {
|
|
Value += (c - '0');
|
|
} else {
|
|
//
|
|
// Unexpected char is encountered
|
|
//
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
*Status = EFI_SUCCESS;
|
|
return Value;
|
|
}
|
|
|
|
STATIC
|
|
STRING_MAP *
|
|
EFIAPI
|
|
StringMapFindItem (
|
|
STRING_MAP *Head,
|
|
CHAR16 *Key
|
|
)
|
|
{
|
|
LIST_ENTRY *Link;
|
|
STRING_MAP *Item;
|
|
|
|
Link = GetFirstNode ((LIST_ENTRY *)Head);
|
|
|
|
while (!IsNull ((LIST_ENTRY *)Head, Link)) {
|
|
Item = (STRING_MAP *)Link;
|
|
if (StrCmp (Item->Key, Key) == 0) {
|
|
return Item;
|
|
}
|
|
Link = GetNextNode ((LIST_ENTRY *)Head, Link);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
EFIAPI
|
|
StringMapAdd (
|
|
STRING_MAP *Head,
|
|
CHAR16 *Key,
|
|
VOID *Data
|
|
)
|
|
{
|
|
STRING_MAP *Item;
|
|
|
|
ASSERT (Key != NULL);
|
|
|
|
if (StringMapFindItem (Head, Key) != NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
Item = AllocatePool (sizeof (STRING_MAP));
|
|
if (Item == NULL) {
|
|
return FALSE;
|
|
}
|
|
InsertTailList((LIST_ENTRY *)Head, (LIST_ENTRY *)Item);
|
|
|
|
Item->Key = AllocateCopyPool (StrSize (Key), Key);
|
|
Item->Data = Data;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID *
|
|
EFIAPI
|
|
StringMapFind (
|
|
STRING_MAP *Head,
|
|
CHAR16 *Key
|
|
)
|
|
{
|
|
STRING_MAP *Item;
|
|
|
|
Item = StringMapFindItem (Head, Key);
|
|
if (Item != NULL) {
|
|
return Item->Data;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
VOID *
|
|
EFIAPI
|
|
StringMapSet (
|
|
STRING_MAP *Head,
|
|
CHAR16 *Key,
|
|
VOID *Data
|
|
)
|
|
{
|
|
STRING_MAP *Item;
|
|
VOID *OldData;
|
|
|
|
Item = StringMapFind (Head, Key);
|
|
if (Item != NULL) {
|
|
OldData = Item->Data;
|
|
Item->Data = Data;
|
|
return OldData;
|
|
}
|
|
|
|
StringMapAdd (Head, Key, Data);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
EFIAPI
|
|
StringMapRemove (
|
|
STRING_MAP *Head,
|
|
CHAR16 *Key
|
|
)
|
|
{
|
|
STRING_MAP *Item;
|
|
|
|
Item = StringMapFindItem (Head, Key);
|
|
if (Item != NULL) {
|
|
RemoveEntryList((LIST_ENTRY *)Item);
|
|
ASSERT (Item->Key);
|
|
FreePool (Item->Key);
|
|
FreePool (Item);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
VOID
|
|
EFIAPI
|
|
StringMapRemoveAll (
|
|
STRING_MAP *Head
|
|
)
|
|
{
|
|
STRING_MAP *Item;
|
|
|
|
while (!IsListEmpty ((LIST_ENTRY *)Head)) {
|
|
Item = (STRING_MAP *)GetFirstNode ((LIST_ENTRY *)Head);
|
|
RemoveEntryList((LIST_ENTRY *)Item);
|
|
ASSERT (Item->Key);
|
|
FreePool (Item->Key);
|
|
FreePool (Item);
|
|
}
|
|
}
|
|
|
|
|
|
STRING_MAP *
|
|
EFIAPI
|
|
StringMapGetAtItem (
|
|
STRING_MAP *Head,
|
|
UINTN Index
|
|
)
|
|
{
|
|
UINTN Pos;
|
|
LIST_ENTRY *Link;
|
|
STRING_MAP *Item;
|
|
|
|
Pos = 0;
|
|
Link = GetFirstNode ((LIST_ENTRY *)Head);
|
|
|
|
while (!IsNull ((LIST_ENTRY *)Head, Link)) {
|
|
Item = (STRING_MAP *)Link;
|
|
if (Pos++ == Index) {
|
|
return Item;
|
|
}
|
|
|
|
Link = GetNextNode ((LIST_ENTRY *)Head, Link);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
UINTN
|
|
EFIAPI
|
|
StringMapGetSize (
|
|
STRING_MAP *Head
|
|
)
|
|
{
|
|
UINTN Count;
|
|
LIST_ENTRY *Link;
|
|
|
|
Count = 0;
|
|
|
|
Link = GetFirstNode ((LIST_ENTRY *)Head);
|
|
|
|
while (!IsNull ((LIST_ENTRY *)Head, Link)) {
|
|
Count++;
|
|
Link = GetNextNode ((LIST_ENTRY *)Head, Link);
|
|
}
|
|
|
|
return Count;
|
|
}
|
|
|