/** @file ;****************************************************************************** ;* Copyright (c) 2013 - 2020, 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 "LayoutSupportLib.h" typedef struct { UINT32 Value; CHAR8 *Str; } SUB_ELEMENT_NAME; SUB_ELEMENT_NAME mSubElementNameMap[] = { {DISPLAY_SUB_ELEMENT_NAME_FORM_IMAGE , "form-image" }, {DISPLAY_SUB_ELEMENT_NAME_FORM_TITLE , "form-title" }, {DISPLAY_SUB_ELEMENT_NAME_FORMSET_HELP , "formset-help" }, {DISPLAY_SUB_ELEMENT_NAME_FORMSET_HELP_IMAGE, "formset-help-image"}, {DISPLAY_SUB_ELEMENT_NAME_FORMSET_IMAGE , "formset-image" }, {DISPLAY_SUB_ELEMENT_NAME_FORMSET_TITLE , "formset-title" }, {DISPLAY_SUB_ELEMENT_NAME_HELP_IMAGE , "help-image" }, {DISPLAY_SUB_ELEMENT_NAME_VALUE_IMAGE , "value-image" }, {DISPLAY_SUB_ELEMENT_NAME_GROUP , "group" }, {DISPLAY_SUB_ELEMENT_NAME_HELP , "help" }, {DISPLAY_SUB_ELEMENT_NAME_IMAGE , "image" }, {DISPLAY_SUB_ELEMENT_NAME_IMG_0 , "img0" }, {DISPLAY_SUB_ELEMENT_NAME_IMG_1 , "img1" }, {DISPLAY_SUB_ELEMENT_NAME_IMG_2 , "img2" }, {DISPLAY_SUB_ELEMENT_NAME_IMG_3 , "img3" }, {DISPLAY_SUB_ELEMENT_NAME_IMG_4 , "img4" }, {DISPLAY_SUB_ELEMENT_NAME_IMG_5 , "img5" }, {DISPLAY_SUB_ELEMENT_NAME_IMG_6 , "img6" }, {DISPLAY_SUB_ELEMENT_NAME_IMG_7 , "img7" }, {DISPLAY_SUB_ELEMENT_NAME_IMG_8 , "img8" }, {DISPLAY_SUB_ELEMENT_NAME_IMG_9 , "img9" }, {DISPLAY_SUB_ELEMENT_NAME_PROMPT , "prompt" }, {DISPLAY_SUB_ELEMENT_NAME_STR_0 , "str0" }, {DISPLAY_SUB_ELEMENT_NAME_STR_1 , "str1" }, {DISPLAY_SUB_ELEMENT_NAME_STR_2 , "str2" }, {DISPLAY_SUB_ELEMENT_NAME_STR_3 , "str3" }, {DISPLAY_SUB_ELEMENT_NAME_STR_4 , "str4" }, {DISPLAY_SUB_ELEMENT_NAME_STR_5 , "str5" }, {DISPLAY_SUB_ELEMENT_NAME_STR_6 , "str6" }, {DISPLAY_SUB_ELEMENT_NAME_STR_7 , "str7" }, {DISPLAY_SUB_ELEMENT_NAME_STR_8 , "str8" }, {DISPLAY_SUB_ELEMENT_NAME_STR_9 , "str9" }, {DISPLAY_SUB_ELEMENT_NAME_TEXT2 , "text2" }, {DISPLAY_SUB_ELEMENT_NAME_VALUE , "value" }, {DISPLAY_SUB_ELEMENT_NAME_NONE , NULL } }; typedef struct { UINT16 Value; CHAR8 *ValueStr; CHAR8 *identifierStr; } PROPERTY_KEYWORD_MAP; PROPERTY_KEYWORD_MAP mPropertyKeywordMap[] = { {KEYWORD_ALIGN_CONTENT_FLEX_START , "flex-start" , "align-content"}, {KEYWORD_ALIGN_CONTENT_FLEX_END , "flex-start" , "align-content"}, {KEYWORD_ALIGN_CONTENT_CENTER , "center" , "align-content"}, {KEYWORD_ALIGN_CONTENT_SPACE_BETWEEN , "space-between" , "align-content"}, {KEYWORD_ALIGN_CONTENT_SPACE_AROUND , "space-around" , "align-content"}, {KEYWORD_ALIGN_CONTENT_STRETCH , "stretch" , "align-content"}, {KEYWORD_ALIGN_ITEMS_FLEX_START , "flex-start" , "align-items"}, {KEYWORD_ALIGN_ITEMS_FLEX_END , "flex-start" , "align-items"}, {KEYWORD_ALIGN_ITEMS_CENTER , "center" , "align-items"}, {KEYWORD_ALIGN_ITEMS_STRETCH , "stretch" , "align-items"}, {KEYWORD_BACKGROUND_REPEAT_NO_REPEAT , "no-repeat" , "background-repeat"}, {KEYWORD_BACKGROUND_REPEAT_REPEAT_X , "repeat-y" , "background-repeat"}, {KEYWORD_BACKGROUND_REPEAT_REPEAT_Y , "repeat-x" , "background-repeat"}, {KEYWORD_BACKGROUND_REPEAT_REPEAT , "repeat" , "background-repeat"}, {KEYWORD_BORDER_SHADOW_NONE , "none" , "border-shadow"}, {KEYWORD_BORDER_SHADOW_OUTSET , "outset" , "border-shadow"}, {KEYWORD_BORDER_SHADOW_INSET , "inset" , "border-shadow"}, {KEYWORD_BORDER_STYLE_NONE , "none" , "border-style"}, {KEYWORD_BORDER_STYLE_SOLID , "solid" , "border-style"}, {KEYWORD_BORDER_STYLE_DOTTED , "dotted" , "border-style"}, {KEYWORD_BORDER_STYLE_DASHED , "dashed" , "border-style"}, {KEYWORD_BORDER_STYLE_DOUBLE , "double" , "border-style"}, {KEYWORD_BORDER_STYLE_GROOVE , "groove" , "border-style"}, {KEYWORD_BORDER_STYLE_RIDGE , "ridge" , "border-style"}, {KEYWORD_BORDER_STYLE_INSET , "inset" , "border-style"}, {KEYWORD_BORDER_STYLE_OUTSET , "outset" , "border-style"}, {KEYWORD_BORDER_STYLE_HIDDEN , "hidden" , "border-style"}, {KEYWORD_DISPLAY_NONE , "none" , "display"}, {KEYWORD_DISPLAY_INLINE , "inline" , "display"}, {KEYWORD_DISPLAY_BLOCK , "block" , "display"}, {KEYWORD_DISPLAY_FLEX , "flex" , "display"}, {KEYWORD_FILTER_NONE , "none" , "filter"}, {KEYWORD_FILTER_BRIGHTNESS , "brightness" , "filter"}, {KEYWORD_FILTER_GRAYSCALE , "grayscale" , "filter"}, {KEYWORD_FLEX_DIRECTION_NONE , "none" , "flex-direction"}, {KEYWORD_FLEX_DIRECTION_ROW , "row" , "flex-direction"}, {KEYWORD_FLEX_DIRECTION_COLUMN , "column" , "flex-direction"}, {KEYWORD_FLEX_WRAP_NOWRAP , "nowrap" , "flex-wrap"}, {KEYWORD_FLEX_WRAP_WRAP , "wrap" , "flex-wrap"}, {KEYWORD_JUSTIFY_CONTENT_FLEX_START , "flex-start" , "justify-content"}, {KEYWORD_JUSTIFY_CONTENT_FLEX_END , "flex-start" , "justify-content"}, {KEYWORD_JUSTIFY_CONTENT_CENTER , "center" , "justify-content"}, {KEYWORD_JUSTIFY_CONTENT_SPACE_BETWEEN , "space-between" , "justify-content"}, {KEYWORD_JUSTIFY_CONTENT_SPACE_AROUND , "space-around" , "justify-content"}, {KEYWORD_LINEAR_GRADIENT_NONE , "none" , "linear-gradient"}, {KEYWORD_LINEAR_GRADIENT_DIRECTION_LEFT , "direction-left" , "linear-gradient"}, {KEYWORD_LINEAR_GRADIENT_DIRECTION_RIGHT , "direction-right" , "linear-gradient"}, {KEYWORD_LINEAR_GRADIENT_DIRECTION_TOP , "direction-top" , "linear-gradient"}, {KEYWORD_LINEAR_GRADIENT_DIRECTION_BOTTOM , "direction-bottom" , "linear-gradient"}, {KEYWORD_LINEAR_GRADIENT_COLOR_START , "color-start" , "linear-gradient"}, {KEYWORD_LINEAR_GRADIENT_COLOR_STOP , "color-stop" , "linear-gradient"}, {KEYWORD_LINEAR_GRADIENT_COLOR_END , "color-end" , "linear-gradient"}, {KEYWORD_OVERFLOW_AUTO , "auto" , "overflow"}, {KEYWORD_OVERFLOW_VISIBLE , "visible" , "overflow"}, {KEYWORD_OVERFLOW_HIDDEN , "hidden" , "overflow"}, {KEYWORD_OVERFLOW_SCROLL , "scroll" , "overflow"}, {KEYWORD_POSITION_ABSOLUTE , "absolute" , "position"}, {KEYWORD_POSITION_RELATIVE , "relative" , "position"}, {KEYWORD_POSITION_FIXED , "static" , "position"}, {KEYWORD_POSITION_STATIC , "fixed" , "position"}, {KEYWORD_TEXT_ALIGN_LEFT , "left" , "text-align"}, {KEYWORD_TEXT_ALIGN_RIGHT , "right" , "text-align"}, {KEYWORD_TEXT_ALIGN_CENTER , "center" , "text-align"}, {KEYWORD_TEXT_ALIGN_JUSTIFY , "justify" , "text-align"}, {KEYWORD_TEXT_CONTROL_ELLIPSIS , "ellipsis" , "text-control"}, {KEYWORD_TEXT_CONTROL_NOWRAP , "nowrap" , "text-control"}, {KEYWORD_TEXT_CONTROL_WRAP , "wrap" , "text-control"}, {KEYWORD_TEXT_CONTROL_TRUNCATE , "truncate" , "text-control"}, {KEYWORD_VISIBILITY_VISIBLE , "visible" , "visibility"}, {KEYWORD_VISIBILITY_HIDDEN , "hidden" , "visibility"}, {KEYWORD_VISIBILITY_INHERIT , "inherit" , "visibility"}, {0 , NULL , NULL} }; STATIC UINT16 GetKeywordValueByStr ( IN CHAR8 *identifierStr, IN CHAR8 *ValueStr ) { UINT32 Index; PROPERTY_KEYWORD_MAP *Map = mPropertyKeywordMap; Index = 0; while (Map [Index].identifierStr != NULL) { if (AsciiStrStr (identifierStr, Map[Index].identifierStr) != NULL && AsciiStrStr (ValueStr, Map[Index].ValueStr) != NULL) { return Map[Index].Value; } Index ++; } return 0; } STATIC VOID BubbleSortHotkey ( IN UINT32 HotKeyCount, IN OUT HOT_KEY_INFO *HotKeyList ) { UINT32 Index; UINT32 ArrayIndex; HOT_KEY_INFO Temp; if (HotKeyCount == 0 || HotKeyList == NULL) { return; } for (Index = 0; Index < HotKeyCount - 1; Index++) { for (ArrayIndex = 1; ArrayIndex < HotKeyCount; ArrayIndex++) { if (HotKeyList[ArrayIndex - 1].HotkeyId > HotKeyList[ArrayIndex].HotkeyId) { CopyMem (&Temp, &HotKeyList[ArrayIndex - 1], sizeof (HOT_KEY_INFO)); CopyMem (&HotKeyList[ArrayIndex - 1], &HotKeyList[ArrayIndex], sizeof (HOT_KEY_INFO)); CopyMem (&HotKeyList[ArrayIndex], &Temp, sizeof (HOT_KEY_INFO)); } } } } STATIC EFI_STATUS ConvertToHiiValue ( IN H2O_VALUE *H2OValue, OUT EFI_HII_VALUE *HiiValue ) { EFI_STATUS Status; CHAR16 *String; UINTN StringSize; LAYOUT_DATABASE_PROTOCOL *LayoutDatabase; if (H2OValue == NULL || HiiValue == NULL) { return EFI_INVALID_PARAMETER; } ZeroMem (HiiValue, sizeof(EFI_HII_VALUE)); switch (H2OValue->Type) { case H2O_VALUE_TYPE_BOOLEAN: HiiValue->Type = EFI_IFR_TYPE_BOOLEAN; HiiValue->Value.b = H2OValue->Value.Bool; break; case H2O_VALUE_TYPE_UINT8: HiiValue->Type = EFI_IFR_TYPE_NUM_SIZE_8; HiiValue->Value.u8 = H2OValue->Value.U8; break; case H2O_VALUE_TYPE_UINT16: HiiValue->Type = EFI_IFR_TYPE_NUM_SIZE_16; HiiValue->Value.u16 = H2OValue->Value.U16; break; case H2O_VALUE_TYPE_UINT32: HiiValue->Type = EFI_IFR_TYPE_NUM_SIZE_32; HiiValue->Value.u32 = H2OValue->Value.U32; break; case H2O_VALUE_TYPE_UINT64: HiiValue->Type = EFI_IFR_TYPE_NUM_SIZE_64; HiiValue->Value.u64 = H2OValue->Value.U64; break; case H2O_VALUE_TYPE_STR16: HiiValue->Type = EFI_IFR_TYPE_STRING; HiiValue->BufferLen = (UINT16) StrSize (H2OValue->Value.Str16); HiiValue->Buffer = AllocateCopyPool ((UINTN) HiiValue->BufferLen, H2OValue->Value.Str16); break; case H2O_VALUE_TYPE_STRID: Status = gBS->LocateProtocol (&gLayoutDatabaseProtocolGuid, NULL, (VOID **) &LayoutDatabase); if (EFI_ERROR (Status)) { return Status; } HiiValue->Type = EFI_IFR_TYPE_STRING; String = HiiGetString (LayoutDatabase->ImagePkgHiiHandle, H2OValue->Value.U16, NULL); if (String == NULL) { return EFI_NOT_FOUND; } StringSize = StrSize (String); HiiValue->Value.string = (EFI_STRING_ID) H2OValue->Value.U16; HiiValue->BufferLen = (UINT16) StringSize + sizeof (EFI_HII_HANDLE); HiiValue->Buffer = AllocateZeroPool (HiiValue->BufferLen); if (HiiValue->Buffer == NULL) { FreePool (String); return EFI_OUT_OF_RESOURCES; } CopyMem (HiiValue->Buffer, String, StringSize); CopyMem (&HiiValue->Buffer[StringSize], &LayoutDatabase->ImagePkgHiiHandle, sizeof (EFI_HII_HANDLE)); FreePool (String); break; case H2O_VALUE_TYPE_BUFFER: HiiValue->Type = EFI_IFR_TYPE_BUFFER; HiiValue->BufferLen = (UINT16) H2OValue->Value.Buffer.BufferSize; HiiValue->Buffer = AllocateCopyPool ((UINTN) HiiValue->BufferLen, H2OValue->Value.Buffer.Buffer); break; case H2O_VALUE_TYPE_TIME: HiiValue->Type = EFI_IFR_TYPE_TIME; HiiValue->Value.time.Hour = H2OValue->Value.Time.Hour; HiiValue->Value.time.Minute = H2OValue->Value.Time.Minute; HiiValue->Value.time.Second = H2OValue->Value.Time.Second; break; case H2O_VALUE_TYPE_DATE: HiiValue->Type = EFI_IFR_TYPE_DATE; HiiValue->Value.date.Year = H2OValue->Value.Date.Year; HiiValue->Value.date.Month = H2OValue->Value.Date.Month; HiiValue->Value.date.Day = H2OValue->Value.Date.Day; break; default: ASSERT (FALSE); break; } return EFI_SUCCESS; } CHAR16 * GetStringById ( IN EFI_STRING_ID StringId ) { EFI_STATUS Status; LAYOUT_DATABASE_PROTOCOL *LayoutDatabase; Status = gBS->LocateProtocol (&gLayoutDatabaseProtocolGuid, NULL, (VOID **) &LayoutDatabase); if (EFI_ERROR (Status)) { return NULL; } return HiiGetString (LayoutDatabase->ImagePkgHiiHandle, StringId, NULL); } STATIC UINT32 Abs ( IN UINT32 First, IN UINT32 Second ) { UINT32 Result; Result = 0; if (First >= Second) { Result = First - Second; } else { Result = Second - First; } return Result; } STATIC UINT32 ColorGap ( IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color1, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color2 ) { UINT32 Result; UINT32 GapR; UINT32 GapG; UINT32 GapB; GapR = Abs ((UINT32)Color1->Red, (UINT32)Color2->Red); GapG = Abs ((UINT32)Color1->Green, (UINT32)Color2->Green); GapB = Abs ((UINT32)Color1->Blue, (UINT32)Color2->Blue); Result = GapR * GapR + GapG * GapG + GapB * GapB; return Result; } STATIC UINT32 RgbToAttribute ( IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Rgb ) { UINT32 Index; UINT32 Gap; UINT32 MinGap; UINT32 MinIndex; UINT32 Attribute; RGB_ATTR RgbAttr[] = { // // B G R reserved // {{0x00, 0x00, 0x00, 0xff}, EFI_BLACK }, {{0x98, 0x00, 0x00, 0xff}, EFI_LIGHTBLUE }, {{0x00, 0x98, 0x00, 0xff}, EFI_LIGHTGREEN }, {{0x98, 0x98, 0x00, 0xff}, EFI_LIGHTCYAN }, {{0x00, 0x00, 0x98, 0xff}, EFI_LIGHTRED }, {{0x98, 0x00, 0x98, 0xff}, EFI_MAGENTA }, {{0x00, 0x98, 0x98, 0xff}, EFI_BROWN }, {{0x98, 0x98, 0x98, 0xff}, EFI_LIGHTGRAY }, {{0x30, 0x30, 0x30, 0xff}, EFI_DARKGRAY }, {{0xff, 0x00, 0x00, 0xff}, EFI_BLUE }, {{0x00, 0xff, 0x00, 0xff}, EFI_GREEN }, {{0xff, 0xff, 0x00, 0xff}, EFI_CYAN }, {{0x00, 0x00, 0xff, 0xff}, EFI_RED }, {{0xff, 0x00, 0xff, 0xff}, EFI_LIGHTMAGENTA}, {{0x00, 0xff, 0xff, 0xff}, EFI_YELLOW }, {{0xff, 0xff, 0xff, 0xff}, EFI_WHITE }, {{0x00, 0x00, 0x00, 0x00}, EFI_BLACK } }; MinGap = 0; MinIndex = 0; for (Index = 0; RgbAttr[Index].Rgb.Reserved != 0; Index ++) { Gap = ColorGap (Rgb, &RgbAttr[Index].Rgb); if (Gap <= MinGap) { // // Get Most Closest Attribute // MinGap = Gap; MinIndex = Index; if (MinGap == 0) { // // Same Color // break; } } } Attribute = RgbAttr[MinIndex].Attribute; return Attribute; } STATIC EFI_STATUS ParseH2OValue ( IN H2O_PROPERTY_INFO *Property, OUT H2O_PROPERTY_VALUE *PropValue ) { CopyMem (&PropValue->H2OValue, &Property->H2OValue, sizeof (H2O_VALUE)); switch (Property->H2OValue.Type) { case H2O_VALUE_TYPE_STR8: PropValue->H2OValue.Value.Str8 = (CHAR8 *)Property->ValueStr; break; case H2O_VALUE_TYPE_STR16: PropValue->H2OValue.Value.Str16 = (CHAR16 *)Property->ValueStr; break; case H2O_VALUE_TYPE_BUFFER: PropValue->H2OValue.Value.Buffer.Buffer = (UINT8 *)Property->ValueStr; break; case H2O_VALUE_TYPE_GUID: AsciiStrToGuid (Property->ValueStr, &PropValue->H2OValue.Value.Guid); break; default: break; } return EFI_SUCCESS; } STATIC EFI_STATUS ParseSizeValue ( IN INT32 RelativeSize, IN H2O_PROPERTY_INFO *Property, OUT H2O_PROPERTY_VALUE *PropValue ) { UINTN Length; Length = AsciiStrLen (Property->ValueStr); if (Length > 1 && Property->ValueStr[Length - 1] == '%') { PropValue->Value.Length.Type = H2O_CSS_LENGTH_TYPE_PERCENTAGE; PropValue->Value.Length.Value.Percentage = Property->H2OValue.Value.U32; } else if (Length > 2 && Property->ValueStr[Length - 2] == 'p' && Property->ValueStr[Length - 1] == 'x') { PropValue->Value.Length.Type = H2O_CSS_LENGTH_TYPE_PX; PropValue->Value.Length.Value.Px = Property->H2OValue.Value.U32; } else if (Length > 2 && Property->ValueStr[Length - 2] == 'e' && Property->ValueStr[Length - 1] == 'm') { PropValue->Value.Length.Type = H2O_CSS_LENGTH_TYPE_EM; PropValue->Value.Length.Value.Em = Property->H2OValue.Value.U32; } else if (AsciiStrCmp (Property->ValueStr, "auto") == 0) { PropValue->Value.Length.Type = H2O_CSS_LENGTH_TYPE_AUTO; } if (Property->H2OValue.Type == H2O_VALUE_TYPE_PERCENTAGE) { PropValue->H2OValue.Type = H2O_VALUE_TYPE_UINT32; PropValue->H2OValue.Value.U32 = (UINT32)RelativeSize * Property->H2OValue.Value.U32 / 100; } else if (Property->H2OValue.Type == H2O_VALUE_TYPE_INT32 || Property->H2OValue.Type == H2O_VALUE_TYPE_INT64) { PropValue->H2OValue.Type = H2O_VALUE_TYPE_UINT32; if (Property->H2OValue.Value.I32 < 0) { PropValue->H2OValue.Value.U32 = (UINT32)(RelativeSize + Property->H2OValue.Value.I32); } else { PropValue->H2OValue.Value.U32 = (UINT32)(Property->H2OValue.Value.I32); } } else { CopyMem (&PropValue->H2OValue, &Property->H2OValue, sizeof (H2O_VALUE)); } return EFI_SUCCESS; } STATIC EFI_STATUS ParseCoordValue ( IN RECT *RelativeField, IN H2O_PROPERTY_INFO *Property, OUT H2O_PROPERTY_VALUE *PropValue ) { INT32 RelativeSize; RelativeSize = 1; if (RelativeField != NULL) { if (AsciiStrStr (Property->IdentifierStr, "left") != NULL || AsciiStrStr (Property->IdentifierStr, "right") != NULL || AsciiStrStr (Property->IdentifierStr, "width") != NULL) { RelativeSize = RelativeField->right - RelativeField->left; } else if (AsciiStrStr (Property->IdentifierStr, "top") != NULL || AsciiStrStr (Property->IdentifierStr, "bottom") != NULL || AsciiStrStr (Property->IdentifierStr, "height") != NULL) { RelativeSize = RelativeField->bottom - RelativeField->top; } } ParseSizeValue (RelativeSize, Property, PropValue); return EFI_SUCCESS; } STATIC EFI_STATUS ParseColorValue ( IN H2O_PROPERTY_INFO *Property, OUT H2O_PROPERTY_VALUE *PropValue ) { EFI_GRAPHICS_OUTPUT_BLT_PIXEL Rgb; UINT32 Attribute; UINT32 RgbNumber; UINT32 TempAttribute; CHAR8 *StrPtr; BOOLEAN Background; StrPtr = Property->ValueStr; TempAttribute = 0; Background = FALSE; if (AsciiStrStr (Property->IdentifierStr, "background") != NULL) { Background = TRUE; } if (Property->H2OValue.Type == H2O_VALUE_TYPE_UINT32) { RgbNumber = (UINT32)Property->H2OValue.Value.U32; CopyMem (&Rgb, &RgbNumber, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); TempAttribute = RgbToAttribute (&Rgb); } else if (Property->H2OValue.Type == H2O_VALUE_TYPE_COLOR) { CopyMem (&PropValue->Value.Color.Rgb, &Property->H2OValue.Value.Color.Argb, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); PropValue->Value.Color.Attribute = Property->H2OValue.Value.Color.TextModeAttribute; return EFI_SUCCESS; } else { return EFI_NOT_FOUND; } Attribute = 0; if (Background) { if (TempAttribute == EFI_WHITE) { TempAttribute = EFI_LIGHTGRAY; } TempAttribute <<= 4; Attribute &= 0x0f; Attribute |= TempAttribute; } else { Attribute &= 0xf0; Attribute |= TempAttribute; } CopyMem (&PropValue->Value.Color.Rgb, &Rgb, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); PropValue->Value.Color.Attribute = Attribute; return EFI_SUCCESS; } STATIC EFI_STATUS ParseImageValue ( IN H2O_PROPERTY_INFO *Property, OUT H2O_PROPERTY_VALUE *PropValue ) { if (Property->H2OValue.Type == H2O_VALUE_TYPE_STR16) { PropValue->Value.Image.ImageMapStr = (CHAR16 *)Property->ValueStr; } else { CopyMem (&PropValue->H2OValue, &Property->H2OValue, sizeof (H2O_VALUE)); } return EFI_SUCCESS; } STATIC EFI_STATUS ParseKeywordValue ( IN H2O_PROPERTY_INFO *Property, OUT H2O_PROPERTY_VALUE *PropValue ) { CHAR8 *ValueStrPtr; UINT32 ValueStrSize; UINT16 ResultValue; if (Property->H2OValue.Type != H2O_VALUE_TYPE_STR8) { return EFI_UNSUPPORTED; } ValueStrSize = Property->H2OValue.Value.Buffer.BufferSize; ValueStrPtr = Property->ValueStr; ResultValue = 0; while (ValueStrPtr < (Property->ValueStr + ValueStrSize)) { ResultValue |= GetKeywordValueByStr (Property->IdentifierStr, ValueStrPtr); ValueStrPtr += AsciiStrSize (ValueStrPtr); } PropValue->H2OValue.Type = H2O_VALUE_TYPE_UINT16; PropValue->H2OValue.Value.U16 = ResultValue; return EFI_SUCCESS; } EFI_STATUS ParseProperty ( IN RECT *RelativeField OPTIONAL, IN H2O_PROPERTY_INFO *Property, OUT H2O_PROPERTY_VALUE *PropValue ) { ZeroMem (PropValue, sizeof (H2O_PROPERTY_VALUE)); PropValue->Type = Property->ValueType; ParseH2OValue (Property, PropValue); switch (Property->ValueType){ case H2O_PROPERTY_VALUE_TYPE_SIZE: case H2O_PROPERTY_VALUE_TYPE_SIZES: ParseSizeValue (1, Property, PropValue); break; case H2O_PROPERTY_VALUE_TYPE_COORD: ParseCoordValue (RelativeField, Property, PropValue); break; case H2O_PROPERTY_VALUE_TYPE_COLOR: ParseColorValue (Property, PropValue); break; case H2O_PROPERTY_VALUE_TYPE_IMAGE: case H2O_PROPERTY_VALUE_TYPE_ANIMATION: ParseImageValue (Property, PropValue); break; case H2O_PROPERTY_VALUE_TYPE_KEYWORD: case H2O_PROPERTY_VALUE_TYPE_KEYWORDS: ParseKeywordValue (Property, PropValue); break; case H2O_PROPERTY_VALUE_TYPE_BOOLEAN: case H2O_PROPERTY_VALUE_TYPE_ID: case H2O_PROPERTY_VALUE_TYPE_TOKEN: case H2O_PROPERTY_VALUE_TYPE_ENUM: case H2O_PROPERTY_VALUE_TYPE_ENUMS: case H2O_PROPERTY_VALUE_TYPE_STRING: case H2O_PROPERTY_VALUE_TYPE_GUID: case H2O_PROPERTY_VALUE_TYPE_VALUE: case H2O_PROPERTY_VALUE_TYPE_OVERRIDE: case H2O_PROPERTY_VALUE_TYPE_SUBELEMENT: break; default: // // Mismatched IdentifierStr String // return EFI_NOT_FOUND; } return EFI_SUCCESS; } EFI_STATUS GetPropertyFromPropertyList ( IN LIST_ENTRY *PropertyListHead, IN CHAR8 *IdentifierStr, IN RECT *RelativeField OPTIONAL, OUT H2O_PROPERTY_INFO **Property, OUT H2O_PROPERTY_VALUE *PropValue ) { EFI_STATUS Status; LIST_ENTRY *Link; H2O_PROPERTY_INFO *CurrentProperty; if (PropertyListHead == NULL) { return EFI_INVALID_PARAMETER; } if (IdentifierStr == NULL || Property == NULL) { return EFI_INVALID_PARAMETER; } Link = PropertyListHead; if (IsNull (Link, Link->ForwardLink)) { return EFI_NOT_FOUND; } Status = EFI_NOT_FOUND; *Property = NULL; CurrentProperty = NULL; do { Link = Link->ForwardLink; CurrentProperty = H2O_PROPERTY_INFO_NODE_FROM_LINK (Link); if (AsciiStrCmp (CurrentProperty->IdentifierStr, IdentifierStr) == 0) { ParseProperty (RelativeField, CurrentProperty, PropValue); *Property = CurrentProperty; Status = EFI_SUCCESS; } } while (!IsNodeAtEnd (PropertyListHead, Link)); return Status; } EFI_STATUS GetPropertyFromStyleList ( IN LIST_ENTRY *StyleListHead, IN UINT32 StyleType, IN UINT32 PseudoClass, IN CHAR8 *IdentifierStr, IN RECT *RelativeField OPTIONAL, OUT H2O_PROPERTY_INFO **Property, OUT H2O_PROPERTY_VALUE *PropValue ) { EFI_STATUS Status; LIST_ENTRY *Link; H2O_STYLE_INFO *CurrentStyle; H2O_PROPERTY_INFO *TempProperty; UINT8 Priority; UINT8 PriorityOld; BOOLEAN Changed; if (StyleListHead == NULL) { return EFI_INVALID_PARAMETER; } if (IdentifierStr == NULL || Property == NULL) { return EFI_INVALID_PARAMETER; } Link = StyleListHead; if (IsNull (Link, Link->ForwardLink)) { return EFI_NOT_FOUND; } Status = EFI_NOT_FOUND; Priority = 0xff; PriorityOld = Priority; Changed = FALSE; *Property = NULL; CurrentStyle = NULL; do { Link = Link->ForwardLink; CurrentStyle = H2O_STYLE_INFO_NODE_FROM_LINK (Link); if ((CurrentStyle->StyleType & H2O_IFR_STYLE_TYPE_VFR_TREE_FLAG) != 0) { // // If StyleType is from vfr...endvfr, the formsetguid and formid and hotkeyid are already checked. // Priority = 0; Changed = TRUE; } else if (StyleType != 0 && CurrentStyle->StyleType != 0 && StyleType != CurrentStyle->StyleType) { continue; } if ((PseudoClass != 0 && CurrentStyle->PseudoClass != 0 && PseudoClass != CurrentStyle->PseudoClass) || (PseudoClass == 0 && CurrentStyle->PseudoClass != 0)) { continue; } if (StyleType != 0 && CurrentStyle->StyleType != 0 && PseudoClass != 0 && CurrentStyle->PseudoClass != 0) { if (StyleType == CurrentStyle->StyleType && (PseudoClass == CurrentStyle->PseudoClass)) { // // ".ClassName StyleType : PseudoClass" priority is the highest // if (Priority >= 1) { Priority = 1; Changed = TRUE; } } } else if (StyleType != 0 && CurrentStyle->StyleType != 0) { if (StyleType == CurrentStyle->StyleType) { // // ".ClassName StyleType" priority is the second // if (Priority >= 2) { Priority = 2; Changed = TRUE; } } } else if (PseudoClass != 0 && CurrentStyle->PseudoClass != 0) { if (PseudoClass == CurrentStyle->PseudoClass) { // // ".ClassName : PseudoClass" priority is the third // if (Priority >= 3) { Priority = 3; Changed = TRUE; } } } else if (CurrentStyle->StyleType == 0 && CurrentStyle->PseudoClass == 0) { // // ".ClassName" priority is the last // if (Priority >= 4) { Priority = 4; Changed = TRUE; } } if (Changed) { Status = GetPropertyFromPropertyList (&CurrentStyle->PropertyListHead, IdentifierStr, RelativeField, &TempProperty, PropValue); if (Status == EFI_SUCCESS) { *Property = TempProperty; PriorityOld = Priority; } else { Priority = PriorityOld; } Changed = FALSE; } } while (!IsNodeAtEnd (StyleListHead, Link)); if (*Property == NULL) { return EFI_NOT_FOUND; } return EFI_SUCCESS; } STATIC EFI_STATUS GetPropertyFromHotkeyList ( IN LIST_ENTRY *HotkeyListHead, IN UINT32 HotkeyId, IN UINT32 StyleType, IN UINT32 PseudoClass, IN CHAR8 *IdentifierStr, IN RECT *RelativeField OPTIONAL, OUT H2O_PROPERTY_INFO **Property, OUT H2O_PROPERTY_VALUE *PropValue ) { EFI_STATUS Status; LIST_ENTRY *HotkeyLink; H2O_HOTKEY_INFO *CurrentHotkey; if (HotkeyId == 0) { return EFI_INVALID_PARAMETER; } if (IdentifierStr == NULL || Property == NULL) { return EFI_INVALID_PARAMETER; } HotkeyLink = HotkeyListHead; if (IsNull (HotkeyLink, HotkeyLink->ForwardLink)) { return EFI_NOT_FOUND; } do { HotkeyLink = HotkeyLink->ForwardLink; CurrentHotkey = H2O_HOTKEY_INFO_NODE_FROM_LINK (HotkeyLink); if (CurrentHotkey->HotkeyBlock->HotkeyId == HotkeyId) { // // Style of hotkey // Status = GetPropertyFromStyleList (&CurrentHotkey->StyleListHead, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } } } while (!IsNodeAtEnd (HotkeyListHead, HotkeyLink)); return EFI_NOT_FOUND; } STATIC EFI_STATUS GetPropertyFromStatementInVfrTree ( IN LIST_ENTRY *StatementListHead, IN BOOLEAN IsQuestion, IN UINT16 Id, IN UINT32 HotkeyId, IN UINT32 StyleType, IN UINT32 PseudoClass, IN CHAR8 *IdentifierStr, IN RECT *RelativeField OPTIONAL, OUT H2O_PROPERTY_INFO **Property, OUT H2O_PROPERTY_VALUE *PropValue ) { EFI_STATUS Status; LIST_ENTRY *StatementLink; H2O_STATEMENT_INFO *CurrentStatement; if (IdentifierStr == NULL || Property == NULL) { return EFI_INVALID_PARAMETER; } StatementLink = StatementListHead; if (IsNull (StatementLink, StatementLink->ForwardLink)) { return EFI_NOT_FOUND; } do { StatementLink = StatementLink->ForwardLink; CurrentStatement = H2O_STATEMENT_INFO_NODE_FROM_LINK (StatementLink); if (CurrentStatement->IsQuestion == IsQuestion && CurrentStatement->QuestionId == Id) { // // Hotkey of statement // Status = GetPropertyFromHotkeyList (&CurrentStatement->HotkeyListHead, HotkeyId, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } // // Style of statement // Status = GetPropertyFromStyleList (&CurrentStatement->StyleListHead, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } } } while (!IsNodeAtEnd (StatementListHead, StatementLink)); return EFI_NOT_FOUND; } STATIC EFI_STATUS GetPropertyFromFormInVfrTree ( IN LIST_ENTRY *FormListHead, IN UINT32 FormId, IN BOOLEAN IsQuestion, IN UINT16 Id, IN UINT32 HotkeyId, IN UINT32 StyleType, IN UINT32 PseudoClass, IN CHAR8 *IdentifierStr, IN RECT *RelativeField OPTIONAL, OUT H2O_PROPERTY_INFO **Property, OUT H2O_PROPERTY_VALUE *PropValue ) { EFI_STATUS Status; LIST_ENTRY *FormLink; H2O_FORM_INFO *CurrentForm; if (FormId == 0) { return EFI_INVALID_PARAMETER; } if (IdentifierStr == NULL || Property == NULL) { return EFI_INVALID_PARAMETER; } FormLink = FormListHead; if (IsNull (FormLink, FormLink->ForwardLink)) { return EFI_NOT_FOUND; } do { FormLink = FormLink->ForwardLink; CurrentForm = H2O_FORM_INFO_NODE_FROM_LINK (FormLink); if (CurrentForm->FormBlock->FormId == FormId) { // // Statement // if ((IsQuestion && Id != 0) || !IsQuestion) { Status = GetPropertyFromStatementInVfrTree (&CurrentForm->StatementListHead, IsQuestion, Id, HotkeyId, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } } // // Hotkey of form // Status = GetPropertyFromHotkeyList (&CurrentForm->HotkeyListHead, HotkeyId, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } // // Style of form // Status = GetPropertyFromStyleList (&CurrentForm->StyleListHead, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } } } while (!IsNodeAtEnd (FormListHead, FormLink)); return EFI_NOT_FOUND; } STATIC EFI_STATUS GetPropertyFromFormsetInVfrTree ( IN LIST_ENTRY *FormsetListHead, IN EFI_GUID *FormsetGuid, IN UINT32 FormId, IN BOOLEAN IsQuestion, IN UINT16 Id, IN UINT32 HotkeyId, IN UINT32 StyleType, IN UINT32 PseudoClass, IN CHAR8 *IdentifierStr, IN RECT *RelativeField OPTIONAL, OUT H2O_PROPERTY_INFO **Property, OUT H2O_PROPERTY_VALUE *PropValue ) { EFI_STATUS Status; LIST_ENTRY *FormsetLink; H2O_FORMSET_INFO *CurrentFormset; if (FormsetGuid == NULL) { return EFI_INVALID_PARAMETER; } if (IdentifierStr == NULL || Property == NULL) { return EFI_INVALID_PARAMETER; } FormsetLink = FormsetListHead; if (IsNull (FormsetLink, FormsetLink->ForwardLink)) { return EFI_NOT_FOUND; } do { FormsetLink = FormsetLink->ForwardLink; CurrentFormset = H2O_FORMSET_INFO_NODE_FROM_LINK (FormsetLink); if (CompareGuid (&(CurrentFormset->FormsetId), FormsetGuid)) { // // Form // Status = GetPropertyFromFormInVfrTree (&CurrentFormset->FormListHead, FormId, IsQuestion, Id, HotkeyId, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } // // Hotkey of formset // Status = GetPropertyFromHotkeyList (&CurrentFormset->HotkeyListHead, HotkeyId, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } // // Style of formset // Status = GetPropertyFromStyleList (&CurrentFormset->StyleListHead, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } } } while (!IsNodeAtEnd (FormsetListHead, FormsetLink)); return EFI_NOT_FOUND; } EFI_STATUS GetPropertyFromVfrInVfrTree ( IN LIST_ENTRY *VfrListHead, IN EFI_GUID *FormsetGuid, IN UINT32 FormId, IN BOOLEAN IsQuestion, IN UINT16 Id, IN UINT32 HotkeyId, IN UINT32 StyleType, IN UINT32 PseudoClass, IN CHAR8 *IdentifierStr, IN RECT *RelativeField OPTIONAL, OUT H2O_PROPERTY_INFO **Property, OUT H2O_PROPERTY_VALUE *PropValue ) { EFI_STATUS Status; LIST_ENTRY *VfrLink; H2O_VFR_INFO *CurrentVfr; if (FormsetGuid == NULL) { return EFI_INVALID_PARAMETER; } if (IdentifierStr == NULL || Property == NULL) { return EFI_INVALID_PARAMETER; } VfrLink = VfrListHead; if (IsNull (VfrLink, VfrLink->ForwardLink)) { return EFI_NOT_FOUND; } do { VfrLink = VfrLink->ForwardLink; CurrentVfr = H2O_VFR_INFO_NODE_FROM_LINK (VfrLink); // // Formset // Status = GetPropertyFromFormsetInVfrTree (&CurrentVfr->FormsetListHead, FormsetGuid, FormId, IsQuestion, Id, HotkeyId, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } } while (!IsNodeAtEnd (VfrListHead, VfrLink)); return EFI_NOT_FOUND; } EFI_STATUS GetPropertyFromVfrInVfcf ( IN EFI_GUID *FormsetGuid, IN UINT32 FormId, IN BOOLEAN IsQuestion, IN UINT16 Id, IN UINT32 HotkeyId, IN UINT32 StyleType, IN UINT32 PseudoClass, IN CHAR8 *IdentifierStr, IN RECT *RelativeField OPTIONAL, OUT H2O_PROPERTY_INFO **Property, OUT H2O_PROPERTY_VALUE *PropValue ) { EFI_STATUS Status; LAYOUT_DATABASE_PROTOCOL *LayoutDatabase; if (FormsetGuid == NULL) { return EFI_INVALID_PARAMETER; } if (IdentifierStr == NULL || Property == NULL) { return EFI_INVALID_PARAMETER; } Status = EFI_NOT_FOUND; Status = gBS->LocateProtocol (&gLayoutDatabaseProtocolGuid, NULL, (VOID **) &LayoutDatabase); if (EFI_ERROR (Status)) { return Status; } // // Vfr // Status = GetPropertyFromVfrInVfrTree (LayoutDatabase->VfrListHead, FormsetGuid, FormId, IsQuestion, Id, HotkeyId, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } return Status; } STATIC EFI_STATUS GetPropertyFromPanel ( IN H2O_PANEL_INFO *Panel, IN UINT32 HotkeyId, IN UINT32 StyleType, IN UINT32 PseudoClass, IN CHAR8 *IdentifierStr, IN RECT *RelativeField OPTIONAL, OUT H2O_PROPERTY_INFO **Property, OUT H2O_PROPERTY_VALUE *PropValue ) { EFI_STATUS Status; if (Panel == NULL) { return EFI_INVALID_PARAMETER; } if (IdentifierStr == NULL || Property == NULL) { return EFI_INVALID_PARAMETER; } Status = EFI_NOT_FOUND; // // Panel itself style // Status = GetPropertyFromStyleList (&Panel->StyleListHead, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } // // Panel's parent layout style // Status = GetPropertyFromStyleList (&Panel->ParentLayout->StyleListHead, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); // // Hotkey of panel's parent layout // Status = GetPropertyFromHotkeyList (&Panel->ParentLayout->HotkeyListHead, HotkeyId, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } return Status; } EFI_STATUS GetPropertyFromVfrAndPanel ( IN H2O_PANEL_INFO *Panel, IN H2O_VFR_PROPERTY *VfrProperty, IN UINT32 StyleType, IN UINT32 PseudoClass, IN CHAR8 *IdentifierStr, IN RECT *RelativeField OPTIONAL, OUT H2O_PROPERTY_INFO **Property, OUT H2O_PROPERTY_VALUE *PropValue ) { EFI_STATUS Status; H2O_VFR_PROPERTY EmptyVfrProperty; if (IdentifierStr == NULL || Property == NULL) { return EFI_INVALID_PARAMETER; } if (VfrProperty == NULL) { ZeroMem (&EmptyVfrProperty, sizeof (H2O_VFR_PROPERTY)); VfrProperty = &EmptyVfrProperty; } Status = EFI_NOT_FOUND; // // Priority: Vfr Option > Vfr Statement > Vfr Form > Vfr Formset > Vfr in Vfcf > Vfcf // Status = GetPropertyFromPropertyList (VfrProperty->OptionPropList, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } Status = GetPropertyFromPropertyList (VfrProperty->StatementPropList, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } Status = GetPropertyFromPropertyList (VfrProperty->FormPropList, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } Status = GetPropertyFromPropertyList (VfrProperty->FormsetPropList, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } Status = GetPropertyFromVfrInVfcf (&VfrProperty->FormsetGuid, VfrProperty->FormId, TRUE, 0, VfrProperty->HotkeyId, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); if (Status == EFI_SUCCESS) { return EFI_SUCCESS; } if (Panel != NULL) { Status = GetPropertyFromPanel (Panel, VfrProperty->HotkeyId, StyleType, PseudoClass, IdentifierStr, RelativeField, Property, PropValue); } return Status; } BOOLEAN IsVisibility ( IN H2O_PANEL_INFO *Panel, IN H2O_VFR_PROPERTY *VfrProperty, IN UINT32 StyleType, IN UINT32 PseudoClass ) { EFI_STATUS Status; H2O_PROPERTY_INFO *Property; H2O_PROPERTY_VALUE PropValue; if (Panel == NULL) { return FALSE; } Status = EFI_NOT_FOUND; Status = GetPropertyFromVfrAndPanel (Panel, VfrProperty, StyleType, PseudoClass, "visibility", NULL, &Property, &PropValue); if (!EFI_ERROR (Status)) { if (PropValue.Type == H2O_PROPERTY_VALUE_TYPE_KEYWORD && PropValue.H2OValue.Type == H2O_VALUE_TYPE_UINT16 && (PropValue.H2OValue.Value.U16 | KEYWORD_VISIBILITY_HIDDEN) == KEYWORD_VISIBILITY_HIDDEN) { return FALSE; } else if (!PropValue.H2OValue.Value.Bool) { return FALSE; } } return TRUE; } EFI_STATUS GetPanelField ( IN H2O_PANEL_INFO *Panel, IN H2O_VFR_PROPERTY *VfrProperty, IN UINT32 StyleType, IN UINT32 PseudoClass, IN RECT *RelativeField, OUT RECT *PanelField ) { EFI_STATUS Status; H2O_PROPERTY_INFO *Property; H2O_PROPERTY_VALUE PropValue; INT32 Left; INT32 Top; INT32 Right; INT32 Bottom; INT32 Width; INT32 Height; BOOLEAN HasLeft; BOOLEAN HasTop; BOOLEAN HasRight; BOOLEAN HasBottom; BOOLEAN HasWidth; BOOLEAN HasHeight; RECT ResultRect; INT32 RelativeWidth; INT32 RelativeHeight; if ((Panel == NULL && VfrProperty == NULL) || PanelField == NULL) { return EFI_INVALID_PARAMETER; } Left = 0; Top = 0; Right = 0; Bottom = 0; Width = 0; Height = 0; HasLeft = FALSE; HasTop = FALSE; HasRight = FALSE; HasBottom = FALSE; HasWidth = FALSE; HasHeight = FALSE; Status = GetPropertyFromVfrAndPanel (Panel, VfrProperty, StyleType, PseudoClass, "left", RelativeField, &Property, &PropValue); if (!EFI_ERROR (Status)) { HasLeft = TRUE; Left = PropValue.H2OValue.Value.I32; } Status = GetPropertyFromVfrAndPanel (Panel, VfrProperty, StyleType, PseudoClass, "top", RelativeField, &Property, &PropValue); if (!EFI_ERROR (Status)) { HasTop = TRUE; Top = PropValue.H2OValue.Value.I32; } Status = GetPropertyFromVfrAndPanel (Panel, VfrProperty, StyleType, PseudoClass, "right", RelativeField, &Property, &PropValue); if (!EFI_ERROR (Status)) { HasRight = TRUE; Right = PropValue.H2OValue.Value.I32; } Status = GetPropertyFromVfrAndPanel (Panel, VfrProperty, StyleType, PseudoClass, "bottom", RelativeField, &Property, &PropValue); if (!EFI_ERROR (Status)) { HasBottom = TRUE; Bottom = PropValue.H2OValue.Value.I32; } Status = GetPropertyFromVfrAndPanel (Panel, VfrProperty, StyleType, PseudoClass, "width", RelativeField, &Property, &PropValue); if (!EFI_ERROR (Status) && (PropValue.H2OValue.Value.I32 > 0)) { HasWidth = TRUE; Width = PropValue.H2OValue.Value.I32; } Status = GetPropertyFromVfrAndPanel (Panel, VfrProperty, StyleType, PseudoClass, "height", RelativeField, &Property, &PropValue); if (!EFI_ERROR (Status) && (PropValue.H2OValue.Value.I32 > 0)) { HasHeight = TRUE; Height = PropValue.H2OValue.Value.I32; } RelativeWidth = RelativeField->right - RelativeField->left; RelativeHeight = RelativeField->bottom - RelativeField->top; ZeroMem (&ResultRect, sizeof (RECT)); if (HasLeft) { ResultRect.left = Left; if (Panel != NULL && Panel->ParentLayout->Revision >= LAYOUT_REVISION_2 && Left > 0) { ResultRect.left ++; } } if (HasTop) { ResultRect.top = Top; } if (HasRight) { if (Panel != NULL && Panel->ParentLayout->Revision < LAYOUT_REVISION_2) { ResultRect.right = Right; } else { ResultRect.right = RelativeWidth - Right; } } if (HasBottom) { if (Panel != NULL && Panel->ParentLayout->Revision < LAYOUT_REVISION_2) { ResultRect.bottom = Bottom; } else { ResultRect.bottom = RelativeHeight - Bottom; } } if (HasWidth) { if (!HasLeft && HasRight) { ResultRect.left = ResultRect.right - Width + 1; } else { ResultRect.right = ResultRect.left + Width - 1; } } if (HasHeight) { if (!HasTop && HasBottom) { ResultRect.top = ResultRect.bottom - Height + 1; } else { ResultRect.bottom = ResultRect.top + Height - 1; } } if (ResultRect.left < RelativeField->left || ResultRect.left >= RelativeField->right) { ResultRect.left = RelativeField->left; } if (ResultRect.right <= RelativeField->left || ResultRect.right > RelativeField->right) { ResultRect.right = RelativeField->right; } if (ResultRect.top < RelativeField->top || ResultRect.top >= RelativeField->bottom) { ResultRect.top = RelativeField->top; } if (ResultRect.bottom <= RelativeField->top || ResultRect.bottom > RelativeField->bottom) { ResultRect.bottom = RelativeField->bottom; } CopyRect (PanelField, &ResultRect); return EFI_SUCCESS; } EFI_STATUS GetForegroundColor ( IN H2O_PANEL_INFO *Panel, IN H2O_VFR_PROPERTY *VfrProperty, IN UINT32 StyleType, IN UINT32 PseudoClass, OUT H2O_COLOR_INFO *Color ) { EFI_STATUS Status; H2O_PROPERTY_INFO *Property; H2O_PROPERTY_VALUE PropValue; if (Panel == NULL || Color == NULL) { return EFI_INVALID_PARAMETER; } if (Panel->ParentLayout->Revision < LAYOUT_REVISION_2) { Status = GetPropertyFromVfrAndPanel (Panel, VfrProperty, StyleType, PseudoClass, "foreground-color", NULL, &Property, &PropValue); } else { Status = GetPropertyFromVfrAndPanel (Panel, VfrProperty, StyleType, PseudoClass, "color", NULL, &Property, &PropValue); } if (EFI_ERROR (Status)) { return Status; } CopyMem (Color, &PropValue.Value.Color, sizeof (H2O_COLOR_INFO)); return EFI_SUCCESS; } EFI_STATUS GetBackgroundColor ( IN H2O_PANEL_INFO *Panel, IN H2O_VFR_PROPERTY *VfrProperty, IN UINT32 StyleType, IN UINT32 PseudoClass, OUT H2O_COLOR_INFO *Color ) { EFI_STATUS Status; H2O_PROPERTY_INFO *Property; H2O_PROPERTY_VALUE PropValue; if (Panel == NULL || Color == NULL) { return EFI_INVALID_PARAMETER; } Status = GetPropertyFromVfrAndPanel (Panel, VfrProperty, StyleType, PseudoClass, "background-color", NULL, &Property, &PropValue); if (EFI_ERROR (Status)) { return Status; } CopyMem (Color, &PropValue.Value.Color, sizeof (H2O_COLOR_INFO)); return EFI_SUCCESS; } EFI_STATUS GetPanelColorAttribute ( IN H2O_PANEL_INFO *Panel, IN H2O_VFR_PROPERTY *VfrProperty, IN UINT32 StyleType, IN UINT32 PseudoClass, OUT UINT32 *PanelColorAttribute ) { EFI_STATUS Status; H2O_COLOR_INFO Color; UINT32 Attribute; Attribute = 0; Status = GetForegroundColor (Panel, VfrProperty, StyleType, PseudoClass, &Color); if (EFI_ERROR (Status)) { return Status; } Attribute |= Color.Attribute; Status = GetBackgroundColor (Panel, VfrProperty, StyleType, PseudoClass, &Color); if (EFI_ERROR (Status)) { return Status; } Attribute |= Color.Attribute; *PanelColorAttribute = Attribute; return EFI_SUCCESS; } UINT32 GetBorderWidth ( IN H2O_PANEL_INFO *Panel, IN H2O_VFR_PROPERTY *VfrProperty, IN UINT32 StyleType, IN UINT32 PseudoClass ) { EFI_STATUS Status; H2O_PROPERTY_INFO *Property; H2O_PROPERTY_VALUE PropValue; if (Panel == NULL) { return 0; } Status = GetPropertyFromVfrAndPanel (Panel, VfrProperty, StyleType, PseudoClass, "border-width", NULL, &Property, &PropValue); if (EFI_ERROR (Status)) { // // Not found, default border width is 0 // return 0; } return PropValue.H2OValue.Value.U32; } EFI_STATUS GetHeight( IN H2O_PANEL_INFO *Panel, IN H2O_VFR_PROPERTY *VfrProperty, IN UINT32 StyleType, IN UINT32 PseudoClass, IN RECT *RelativeField, OUT INT32 *Height ) { EFI_STATUS Status; H2O_PROPERTY_INFO *Property; H2O_PROPERTY_VALUE PropValue; if (Panel == NULL || Height == NULL) { return EFI_INVALID_PARAMETER; } Status = GetPropertyFromVfrAndPanel (Panel, VfrProperty, StyleType, PseudoClass, "height", RelativeField, &Property, &PropValue); if (EFI_ERROR (Status)) { return Status; } *Height = PropValue.H2OValue.Value.U32; return EFI_SUCCESS; } EFI_STATUS GetWidth( IN H2O_PANEL_INFO *Panel, IN H2O_VFR_PROPERTY *VfrProperty, IN UINT32 StyleType, IN UINT32 PseudoClass, IN RECT *RelativeField, OUT INT32 *Width ) { EFI_STATUS Status; H2O_PROPERTY_INFO *Property; H2O_PROPERTY_VALUE PropValue; if (Panel == NULL || Width == NULL) { return EFI_INVALID_PARAMETER; } Status = GetPropertyFromVfrAndPanel (Panel, VfrProperty, StyleType, PseudoClass, "width", RelativeField, &Property, &PropValue); if (EFI_ERROR (Status)) { return Status; } *Width = PropValue.H2OValue.Value.U32; return EFI_SUCCESS; } STATIC EFI_STATUS GetPropertyOfHotkey ( IN LIST_ENTRY *StyleListHead, IN CHAR8 *IdentifierStr, IN UINT32 BufferSize, OUT UINT8 *Buffer ) { EFI_STATUS Status; CHAR16 *Str; UINTN AsciiStringSize; EFI_IMAGE_INPUT *Image; EFI_HII_VALUE HiiValue; H2O_PROPERTY_INFO *PropertyInfo; H2O_PROPERTY_VALUE PropertyValue; LAYOUT_DATABASE_PROTOCOL *LayoutDatabase; UINT32 ResultSize; UINT8 *ResultPtr; Status = GetPropertyFromStyleList ( StyleListHead, H2O_IFR_STYLE_TYPE_HOTKEY, H2O_STYLE_PSEUDO_CLASS_NORMAL, IdentifierStr, NULL, &PropertyInfo, &PropertyValue ); if (EFI_ERROR (Status)) { return Status; } switch (PropertyValue.Type) { case H2O_PROPERTY_VALUE_TYPE_BOOLEAN: ResultSize = sizeof (BOOLEAN); ResultPtr = (UINT8 *) &PropertyValue.H2OValue.Value.Bool; break; case H2O_PROPERTY_VALUE_TYPE_STRING: if (PropertyValue.H2OValue.Type == H2O_VALUE_TYPE_STR16) { Str = AllocateCopyPool (StrSize (PropertyValue.H2OValue.Value.Str16), PropertyValue.H2OValue.Value.Str16); if (Str == NULL) { return EFI_OUT_OF_RESOURCES; } } else { AsciiStringSize = AsciiStrLen (PropertyInfo->ValueStr) + 1; Str = (CHAR16 *)AllocateZeroPool (AsciiStringSize * sizeof (CHAR16)); if (Str == NULL) { return EFI_OUT_OF_RESOURCES; } AsciiStrToUnicodeStrS (PropertyInfo->ValueStr, Str, AsciiStringSize); } ResultSize = sizeof (CHAR16 *); ResultPtr = (UINT8 *) &Str; break; case H2O_PROPERTY_VALUE_TYPE_TOKEN: Status = gBS->LocateProtocol (&gLayoutDatabaseProtocolGuid, NULL, (VOID **) &LayoutDatabase); if (EFI_ERROR (Status)) { return Status; } if (PropertyValue.H2OValue.Type == H2O_VALUE_TYPE_STRID && PropertyValue.H2OValue.Value.U16 != 0) { Str = HiiGetString (LayoutDatabase->ImagePkgHiiHandle, PropertyValue.H2OValue.Value.U16, NULL); if (Str == NULL) { return EFI_NOT_FOUND; } ResultSize = sizeof (CHAR16 *); ResultPtr = (UINT8 *) &Str; } else if (PropertyValue.H2OValue.Type == H2O_VALUE_TYPE_IMGID) { Image = AllocateZeroPool (sizeof(EFI_IMAGE_INPUT)); if (Image == NULL) { return EFI_NOT_FOUND; } gHiiImage->GetImage (gHiiImage, LayoutDatabase->ImagePkgHiiHandle, PropertyValue.H2OValue.Value.U16, Image); ResultSize = sizeof (EFI_IMAGE_INPUT *); ResultPtr = (UINT8 *) &Image; } else { return EFI_UNSUPPORTED; } break; case H2O_PROPERTY_VALUE_TYPE_GUID: ResultSize = sizeof (EFI_GUID); ResultPtr = (UINT8 *) &PropertyValue.H2OValue.Value.Guid; break; case H2O_PROPERTY_VALUE_TYPE_ID: switch (PropertyValue.H2OValue.Type) { case H2O_VALUE_TYPE_UINT8: ResultSize = MIN(sizeof (UINT8), BufferSize); ResultPtr = (UINT8 *) &PropertyValue.H2OValue.Value.U8; break; case H2O_VALUE_TYPE_UINT16: ResultSize = MIN(sizeof (UINT16), BufferSize); ResultPtr = (UINT8 *) &PropertyValue.H2OValue.Value.U16; break; case H2O_VALUE_TYPE_UINT32: ResultSize = MIN(sizeof (UINT32), BufferSize); ResultPtr = (UINT8 *) &PropertyValue.H2OValue.Value.U32; break; case H2O_VALUE_TYPE_UINT64: ResultSize = MIN(sizeof (UINT64), BufferSize); ResultPtr = (UINT8 *) &PropertyValue.H2OValue.Value.U64; break; default: return EFI_UNSUPPORTED; } break; case H2O_PROPERTY_VALUE_TYPE_VALUE: Status = ConvertToHiiValue (&PropertyValue.H2OValue, &HiiValue); if (EFI_ERROR (Status)) { return Status; } ResultSize = sizeof (EFI_HII_VALUE); ResultPtr = (UINT8 *) &HiiValue; break; case H2O_PROPERTY_VALUE_TYPE_KEYWORD: ResultSize = sizeof (UINT16); ResultPtr = (UINT8 *) &PropertyValue.H2OValue.Value.U16; break; default: return EFI_UNSUPPORTED; } if (BufferSize < ResultSize) { return EFI_BUFFER_TOO_SMALL; } ZeroMem (Buffer, BufferSize); CopyMem (Buffer, ResultPtr, ResultSize); return EFI_SUCCESS; } STATIC EFI_STATUS CompatibleHotkey ( IN H2O_HOTKEY_INFO *H2OHotKey, IN OUT HOT_KEY_INFO *Hotkey ) { EFI_STATUS Status; BOOLEAN BooleanValue; CHAR16 *Str; UINT64 Num; EFI_GUID Guid; EFI_IMAGE_INPUT *Img; EFI_HII_VALUE HiiValue; if (H2OHotKey == NULL || Hotkey == NULL) { return EFI_INVALID_PARAMETER; } Status = GetPropertyOfHotkey (&H2OHotKey->StyleListHead, "enable", sizeof (BOOLEAN), (UINT8 *) &BooleanValue); if (!EFI_ERROR (Status)) { Hotkey->Display = BooleanValue; } Status = GetPropertyOfHotkey (&H2OHotKey->StyleListHead, "prompt-string-token", sizeof(CHAR16 *), (UINT8 *) &Str); if (!EFI_ERROR (Status)) { SafeFreePool (&Hotkey->Mark); Hotkey->Mark = Str; } Status = GetPropertyOfHotkey (&H2OHotKey->StyleListHead, "help-string-token", sizeof(CHAR16 *), (UINT8 *) &Str); if (!EFI_ERROR (Status)) { SafeFreePool (&Hotkey->String); Hotkey->String = Str; } Status = GetPropertyOfHotkey (&H2OHotKey->StyleListHead, "prompt-image-token", sizeof(EFI_IMAGE_INPUT *), (UINT8 *) &Img); if (!EFI_ERROR (Status)) { SafeFreePool (&Hotkey->ImageBuffer); Hotkey->ImageBuffer = Img; } Status = GetPropertyOfHotkey (&H2OHotKey->StyleListHead, "group-id", sizeof(UINT8), (UINT8 *) &Num); if (!EFI_ERROR (Status)) { Hotkey->GroupId = (UINT8) Num; } Status = GetPropertyOfHotkey (&H2OHotKey->StyleListHead, "key-action", sizeof(UINT32), (UINT8 *) &Num); if (!EFI_ERROR (Status)) { Hotkey->HotKeyAction = (UINT32)Num; } Status = GetPropertyOfHotkey (&H2OHotKey->StyleListHead, "action-defaultid", sizeof(UINT16), (UINT8 *) &Num); if (!EFI_ERROR (Status)) { Hotkey->HotKeyDefaultId = (UINT16)Num; } Status = GetPropertyOfHotkey (&H2OHotKey->StyleListHead, "action-target-formsetguid", sizeof(EFI_GUID), (UINT8 *) &Guid); if (!EFI_ERROR (Status)) { CopyMem (&Hotkey->HotKeyTargetFormSetGuid, &Guid, sizeof (EFI_GUID)); } Status = GetPropertyOfHotkey (&H2OHotKey->StyleListHead, "action-target-formid", sizeof(UINT16), (UINT8 *) &Num); if (!EFI_ERROR (Status)) { Hotkey->HotKeyTargetFormId = (UINT16)Num; } Status = GetPropertyOfHotkey (&H2OHotKey->StyleListHead, "action-target-questionid", sizeof(UINT16), (UINT8 *) &Num); if (!EFI_ERROR (Status)) { Hotkey->HotKeyTargetQuestionId = (UINT16)Num; } Status = GetPropertyOfHotkey (&H2OHotKey->StyleListHead, "action-target-questionvalue", sizeof(EFI_HII_VALUE), (UINT8 *) &HiiValue); if (!EFI_ERROR (Status)) { CopyMem (&Hotkey->HotKeyHiiValue, &HiiValue, sizeof (EFI_HII_VALUE)); } return EFI_SUCCESS; } STATIC EFI_STATUS PrepareHotkey ( IN LIST_ENTRY *VfcfHotKeyListHead, IN OUT UINT32 *HotKeyCount, IN OUT HOT_KEY_INFO **HotKeyList ) { EFI_STATUS Status; LAYOUT_DATABASE_PROTOCOL *LayoutDatabase; H2O_KEY_DESC_PROTOCOL *KeyDesc; EFI_HII_HANDLE HiiHandle; H2O_HII_LIBT_EXT_HOTKEY_BLOCK *HotkeyBlock; HOT_KEY_INFO *Hotkey; CHAR16 *Str; UINT16 GroupId; EFI_IMAGE_INPUT *Image; H2O_PROPERTY_INFO *PropertyInfo; H2O_PROPERTY_VALUE PropertyValue; LIST_ENTRY *HotKeyLink; H2O_HOTKEY_INFO *H2OHotKey; HOT_KEY_INFO *List; UINT32 Count; UINT32 Index; if (VfcfHotKeyListHead == NULL || HotKeyCount == NULL || HotKeyList == NULL) { return EFI_INVALID_PARAMETER; } if (IsListEmpty (VfcfHotKeyListHead)) { return EFI_SUCCESS; } Status = gBS->LocateProtocol (&gLayoutDatabaseProtocolGuid, NULL, (VOID **) &LayoutDatabase); if (EFI_ERROR (Status)) { return Status; } HiiHandle = LayoutDatabase->ImagePkgHiiHandle; Status = gBS->LocateProtocol (&gH2OKeyDescProtocolGuid, NULL, (VOID **) &KeyDesc); if (EFI_ERROR (Status)) { return Status; } List = *HotKeyList; Count = *HotKeyCount; for (HotKeyLink = GetFirstNode (VfcfHotKeyListHead); !IsNull (VfcfHotKeyListHead, HotKeyLink); HotKeyLink = GetNextNode (VfcfHotKeyListHead, HotKeyLink)) { H2OHotKey = H2O_HOTKEY_INFO_NODE_FROM_LINK (HotKeyLink); HotkeyBlock = H2OHotKey->HotkeyBlock; if (HotkeyBlock->Action >= HotKeyMax) { continue; } Hotkey = NULL; for (Index = 0; Index < Count; Index++) { if (List[Index].HotkeyId == HotkeyBlock->HotkeyId) { Hotkey = &List[Index]; break; } } if (Hotkey == NULL) { List = ReallocatePool (sizeof (HOT_KEY_INFO) * Count, sizeof (HOT_KEY_INFO) * (Count + 1), List); if (List == NULL) { return EFI_OUT_OF_RESOURCES; } Hotkey = &List[Count++]; Hotkey->Display = TRUE; Hotkey->HotkeyId = HotkeyBlock->HotkeyId; } Status = GetPropertyOfHotkey (&H2OHotKey->StyleListHead, "key-string", sizeof(CHAR16 *), (UINT8 *) &Str); if (!EFI_ERROR (Status)) { KeyDesc->KeyFromString (KeyDesc, Str, &Hotkey->KeyData); FreePool (Str); } if (HotkeyBlock->Prompt != 0) { SafeFreePool (&Hotkey->Mark); Hotkey->Mark = HiiGetString (LayoutDatabase->ImagePkgHiiHandle, HotkeyBlock->Prompt, NULL); } if (HotkeyBlock->Help != 0) { SafeFreePool (&Hotkey->String); Hotkey->String = HiiGetString (LayoutDatabase->ImagePkgHiiHandle, HotkeyBlock->Help, NULL); } if (HotkeyBlock->Action != 0) { Hotkey->HotKeyAction = (HOT_KEY_ACTION)HotkeyBlock->Action; } if (HotkeyBlock->Group != 0) { Hotkey->GroupId = (UINT8)HotkeyBlock->Group; } Status = GetPropertyOfHotkey (&H2OHotKey->StyleListHead, "group-id", sizeof(UINT16), (UINT8 *) &GroupId); if (!EFI_ERROR (Status)) { Hotkey->GroupId = (UINT8)GroupId; } if (HotkeyBlock->Image != 0) { Image = AllocateZeroPool (sizeof(EFI_IMAGE_INPUT)); if (Image != NULL) { Status = gHiiImage->GetImage (gHiiImage, LayoutDatabase->ImagePkgHiiHandle, HotkeyBlock->Image, Image); if (!EFI_ERROR (Status)) { Hotkey->ImageBuffer = Image; } else { Hotkey->ImageBuffer = NULL; FreePool (Image); } } } Status = GetPropertyFromStyleList (&H2OHotKey->StyleListHead, H2O_IFR_STYLE_TYPE_HOTKEY, H2O_STYLE_PSEUDO_CLASS_NORMAL, "visibility", NULL, &PropertyInfo, &PropertyValue); if (!EFI_ERROR (Status)) { if (PropertyValue.Type == H2O_PROPERTY_VALUE_TYPE_KEYWORD && PropertyValue.H2OValue.Type == H2O_VALUE_TYPE_UINT16 && (PropertyValue.H2OValue.Value.U16 | KEYWORD_VISIBILITY_HIDDEN) == KEYWORD_VISIBILITY_HIDDEN) { Hotkey->Display = FALSE; } else if (!PropertyValue.H2OValue.Value.Bool) { Hotkey->Display = FALSE; } } if (HotkeyBlock->ActionDefaultId != 0) { Hotkey->HotKeyDefaultId = HotkeyBlock->ActionDefaultId; } if (!IsZeroGuid (&HotkeyBlock->ActionFormsetId)) { CopyGuid (&Hotkey->HotKeyTargetFormSetGuid, &HotkeyBlock->ActionFormsetId); } if (HotkeyBlock->ActionFormId != 0) { Hotkey->HotKeyTargetFormId = HotkeyBlock->ActionFormId; } if (HotkeyBlock->ActionQuestionId != 0) { Hotkey->HotKeyTargetQuestionId = HotkeyBlock->ActionQuestionId; } if (HotkeyBlock->ActionQuestionValue.Type != H2O_VALUE_TYPE_UNDEFINED) { ConvertToHiiValue (&HotkeyBlock->ActionQuestionValue, &Hotkey->HotKeyHiiValue); } CompatibleHotkey (H2OHotKey, Hotkey); } *HotKeyList = List; *HotKeyCount = Count; return EFI_SUCCESS; } EFI_STATUS GetHotKeyList ( IN EFI_GUID *FormsetGuid, IN H2O_FORM_ID FormId, OUT UINT32 *HotKeyInfoCount, OUT HOT_KEY_INFO **HotKeyInfo ) { EFI_STATUS Status; Status = GetHotKeyListByQuestion (FormsetGuid, FormId, TRUE, 0, HotKeyInfoCount, HotKeyInfo); if (EFI_ERROR (Status)) { return Status; } return EFI_SUCCESS; } EFI_STATUS GetHotKeyListByQuestion ( IN EFI_GUID *FormsetGuid, IN H2O_FORM_ID FormId, IN BOOLEAN IsQuestion, IN UINT16 Id, OUT UINT32 *HotKeyInfoCount, OUT HOT_KEY_INFO **HotKeyInfo ) { EFI_STATUS Status; UINT32 HotKeyCount; HOT_KEY_INFO *HotkeyList; UINT32 Index; LIST_ENTRY *LayoutListHead; LIST_ENTRY *VfrListHead; LIST_ENTRY *VfrLink; H2O_VFR_INFO *VfrInfo; LIST_ENTRY *FormsetListHead; LIST_ENTRY *FormsetLink; H2O_FORMSET_INFO *FormsetInfo; LIST_ENTRY *FormListHead; LIST_ENTRY *FormLink; H2O_FORM_INFO *FormInfo; LIST_ENTRY *StatementListHead; LIST_ENTRY *StatementLink; H2O_STATEMENT_INFO *StatementInfo; UINT8 EnumerateOrder[] = {H2O_HII_LIBT_EXT_FORMSET, H2O_HII_LIBT_EXT_FORM, H2O_HII_LIBT_EXT_STATEMENT}; if (FormsetGuid == NULL || HotKeyInfoCount == NULL || HotKeyInfo == NULL) { return EFI_INVALID_PARAMETER; } Status = GetLayoutTreeAndVfrTree (&LayoutListHead, &VfrListHead); if (EFI_ERROR (Status) || VfrListHead == NULL) { return EFI_NOT_FOUND; } // // Enumerate all hot keys in sequence and the later has higher priority. // HotKeyCount = 0; HotkeyList = NULL; for (Index = 0; Index < sizeof (EnumerateOrder); Index++) { if ((EnumerateOrder[Index] == H2O_HII_LIBT_EXT_FORM && FormId == 0) || (EnumerateOrder[Index] == H2O_HII_LIBT_EXT_STATEMENT && (FormId == 0 || (IsQuestion && Id == 0)))) { continue; } for (VfrLink = GetFirstNode (VfrListHead); !IsNull (VfrListHead, VfrLink); VfrLink = GetNextNode (VfrListHead, VfrLink)) { VfrInfo = H2O_VFR_INFO_NODE_FROM_LINK (VfrLink); FormsetListHead = &VfrInfo->FormsetListHead; for (FormsetLink = GetFirstNode (FormsetListHead); !IsNull (FormsetListHead, FormsetLink); FormsetLink = GetNextNode (FormsetListHead, FormsetLink)) { FormsetInfo = H2O_FORMSET_INFO_NODE_FROM_LINK (FormsetLink); if (!CompareGuid (&FormsetInfo->FormsetId, FormsetGuid)) { continue; } if (EnumerateOrder[Index] == H2O_HII_LIBT_EXT_FORMSET) { PrepareHotkey (&FormsetInfo->HotkeyListHead, &HotKeyCount, &HotkeyList); continue; } FormListHead = &FormsetInfo->FormListHead; for (FormLink = GetFirstNode (FormListHead); !IsNull (FormListHead, FormLink); FormLink = GetNextNode (FormListHead, FormLink)) { FormInfo = H2O_FORM_INFO_NODE_FROM_LINK (FormLink); if (FormInfo->FormBlock->FormId != FormId) { continue; } if (EnumerateOrder[Index] == H2O_HII_LIBT_EXT_FORM) { PrepareHotkey (&FormInfo->HotkeyListHead, &HotKeyCount, &HotkeyList); continue; } StatementListHead = &FormInfo->StatementListHead; for (StatementLink = GetFirstNode (StatementListHead); !IsNull (StatementListHead, StatementLink); StatementLink = GetNextNode (StatementListHead, StatementLink)) { StatementInfo = H2O_STATEMENT_INFO_NODE_FROM_LINK (StatementLink); if (StatementInfo->IsQuestion != IsQuestion || StatementInfo->QuestionId != Id) { continue; } if (EnumerateOrder[Index] == H2O_HII_LIBT_EXT_STATEMENT) { PrepareHotkey (&StatementInfo->HotkeyListHead, &HotKeyCount, &HotkeyList); } } } } } } // // Remove invalid hot key from list. // Index = 0; while (Index < HotKeyCount) { if (HotkeyList[Index].KeyData.Key.ScanCode == SCAN_NULL && HotkeyList[Index].KeyData.Key.UnicodeChar == CHAR_NULL) { CopyMem (&HotkeyList[Index], &HotkeyList[Index + 1], (HotKeyCount - Index - 1) * sizeof (HOT_KEY_INFO)); HotKeyCount--; continue; } Index++; } if (HotKeyCount == 0) { SafeFreePool (&HotkeyList); return EFI_NOT_FOUND; } BubbleSortHotkey (HotKeyCount, HotkeyList); // // Always append an empty HOT_KEY_INFO in the end of list for H2O_FORM_BROWSER_P.HotKeyInfo consumer (i.e. IS_END_OF_HOT_KEY_INFO). // *HotKeyInfoCount = HotKeyCount; *HotKeyInfo = ReallocatePool (HotKeyCount * sizeof (HOT_KEY_INFO), (HotKeyCount + 1) * sizeof (HOT_KEY_INFO), HotkeyList); return EFI_SUCCESS; } EFI_STATUS GetHotKeyListByLayoutInfo ( IN H2O_LAYOUT_INFO *LayoutInfo, IN EFI_GUID *FormsetGuid, IN H2O_FORM_ID FormId, IN EFI_QUESTION_ID QuestionId, OUT UINT32 *HotKeyInfoCount, OUT HOT_KEY_INFO **HotKeyInfo ) { EFI_STATUS Status; Status = GetHotKeyListByQuestion (FormsetGuid, FormId, (BOOLEAN)(QuestionId != 0), QuestionId, HotKeyInfoCount, HotKeyInfo); if (EFI_ERROR (Status)) { return Status; } return EFI_SUCCESS; } EFI_STATUS GetVfrPropertyByStatement ( IN EFI_GUID *FormsetId, IN UINT16 FormId OPTIONAL, IN UINT32 StatementId OPTIONAL, IN UINT64 Value OPTIONAL, OUT H2O_VFR_PROPERTY *VfrProperty ) { EFI_STATUS Status; H2O_FORM_BROWSER_PROTOCOL *FB; if (FormsetId == NULL || VfrProperty == NULL) { return EFI_INVALID_PARAMETER; } Status = gBS->LocateProtocol (&gH2OFormBrowserProtocolGuid, NULL, (VOID **) &FB); if (EFI_ERROR (Status)) { return Status; } ZeroMem (VfrProperty, sizeof (H2O_VFR_PROPERTY)); CopyMem (&VfrProperty->FormsetGuid, FormsetId, sizeof (EFI_GUID)); VfrProperty->FormId = FormId; VfrProperty->StatementId = StatementId; VfrProperty->OptionValue = Value; Status = FB->GetVfrProp (FB, VfrProperty); if (EFI_ERROR (Status)) { return Status; } return EFI_SUCCESS; } EFI_STATUS GetPopUpTargetByQuestion ( IN H2O_FORM_BROWSER_Q *Question, IN H2O_PANEL_INFO *Panel, OUT EFI_GUID *PopUpFormsetId, OUT UINT16 *PopUpFormId ) { EFI_STATUS Status; H2O_VFR_PROPERTY VfrProperty; UINT32 StyleType; H2O_PROPERTY_INFO *Property; H2O_PROPERTY_VALUE PropValue; if (Question == NULL || Panel == NULL) { return EFI_INVALID_PARAMETER; } if (PopUpFormsetId == NULL || PopUpFormId == NULL) { return EFI_INVALID_PARAMETER; } ZeroMem (PopUpFormsetId, sizeof (EFI_GUID)); *PopUpFormId = 0; ZeroMem (&VfrProperty, sizeof (H2O_VFR_PROPERTY)); Status = GetVfrPropertyByStatement ( &Question->FormsetGuid, Question->FormId, Question->StatementId, Question->HiiValue.Value.u64, &VfrProperty ); if (EFI_ERROR (Status)) { //return Status; } StyleType = GetStyleTypeByOpCode (Question->Operand); Status = GetPropertyFromVfrAndPanel (Panel, &VfrProperty, StyleType, H2O_STYLE_PSEUDO_CLASS_NORMAL, "pop-up-formset-id", NULL, &Property, &PropValue); if (EFI_ERROR (Status)) { return EFI_NOT_FOUND; } CopyMem (PopUpFormsetId, &PropValue.H2OValue.Value.Guid, sizeof (EFI_GUID)); Status = GetPropertyFromVfrAndPanel (Panel, &VfrProperty, StyleType, H2O_STYLE_PSEUDO_CLASS_NORMAL, "pop-up-form-id", NULL, &Property, &PropValue); if (EFI_ERROR (Status)) { return EFI_SUCCESS; } *PopUpFormId = PropValue.H2OValue.Value.U16; return EFI_SUCCESS; } EFI_STATUS GetFormPanelRect ( IN EFI_GUID *FormsetId, IN UINT16 FormId, IN H2O_PANEL_INFO *Panel, IN RECT *RelativeField, OUT RECT *FormPanelRect ) { EFI_STATUS Status; H2O_VFR_PROPERTY VfrProperty; RECT Rect; if (FormsetId == NULL || RelativeField == NULL) { return EFI_INVALID_PARAMETER; } if (FormPanelRect == NULL) { return EFI_INVALID_PARAMETER; } ZeroMem (FormPanelRect, sizeof (RECT)); // // Properties from VFR // ZeroMem (&VfrProperty, sizeof (H2O_VFR_PROPERTY)); GetVfrPropertyByStatement (FormsetId, FormId, 0xFFFF, 0, &VfrProperty); CopyMem (FormPanelRect, RelativeField, sizeof (RECT)); Status = GetPanelField (Panel, &VfrProperty, H2O_IFR_STYLE_TYPE_PANEL, H2O_STYLE_PSEUDO_CLASS_NORMAL, RelativeField, &Rect); if (!EFI_ERROR (Status)) { CopyMem (FormPanelRect, &Rect, sizeof (RECT)); } return EFI_SUCCESS; } EFI_STATUS GetStatementRect ( IN H2O_FORM_BROWSER_S *Statement, IN H2O_PANEL_INFO *Panel, IN RECT *RelativeField, OUT RECT *StatementRect ) { EFI_STATUS Status; H2O_PROPERTY_VALUE PropValue; INT32 Left; INT32 Top; INT32 Right; INT32 Bottom; INT32 Width; INT32 Height; BOOLEAN HasLeft; BOOLEAN HasTop; BOOLEAN HasRight; BOOLEAN HasBottom; BOOLEAN HasWidth; BOOLEAN HasHeight; RECT ResultRect; INT32 RelativeWidth; INT32 RelativeHeight; if (Statement == NULL || RelativeField == NULL || StatementRect == NULL) { return EFI_INVALID_PARAMETER; } Left = 0; Top = 0; Right = 0; Bottom = 0; Width = 0; Height = 0; HasLeft = FALSE; HasTop = FALSE; HasRight = FALSE; HasBottom = FALSE; HasWidth = FALSE; HasHeight = FALSE; Status = GetStatementPropValue ("left", Statement, Panel, 0, 0, RelativeField, &PropValue); if (!EFI_ERROR (Status)) { Left = PropValue.H2OValue.Value.U32; HasLeft = TRUE; } Status = GetStatementPropValue ("top", Statement, Panel, 0, 0, RelativeField, &PropValue); if (!EFI_ERROR (Status)) { Top = PropValue.H2OValue.Value.U32; HasTop = TRUE; } Status = GetStatementPropValue ("right", Statement, Panel, 0, 0, RelativeField, &PropValue); if (!EFI_ERROR (Status)) { Right = PropValue.H2OValue.Value.U32; HasRight = TRUE; } Status = GetStatementPropValue ("bottom", Statement, Panel, 0, 0, RelativeField, &PropValue); if (!EFI_ERROR (Status)) { Bottom = PropValue.H2OValue.Value.U32; HasBottom = TRUE; } Status = GetStatementPropValue ("width", Statement, Panel, 0, 0, RelativeField, &PropValue); if (!EFI_ERROR (Status)) { Width = PropValue.H2OValue.Value.U32; HasWidth = TRUE; } Status = GetStatementPropValue ("height", Statement, Panel, 0, 0, RelativeField, &PropValue); if (!EFI_ERROR (Status)) { Height = PropValue.H2OValue.Value.U32; HasHeight = TRUE; } RelativeWidth = RelativeField->right - RelativeField->left; RelativeHeight = RelativeField->bottom - RelativeField->top; ZeroMem (&ResultRect, sizeof (RECT)); if (HasLeft) { ResultRect.left = Left; if (Panel != NULL && Panel->ParentLayout->Revision >= LAYOUT_REVISION_2 && Left > 0) { ResultRect.left ++; } } if (HasTop) { ResultRect.top = Top; } if (HasRight) { if (Panel != NULL && Panel->ParentLayout->Revision < LAYOUT_REVISION_2) { ResultRect.right = Right; } else { ResultRect.right = RelativeWidth - Right; } } if (HasBottom) { if (Panel != NULL && Panel->ParentLayout->Revision < LAYOUT_REVISION_2) { ResultRect.bottom = Bottom; } else { ResultRect.bottom = RelativeHeight - Bottom; } } if (HasWidth && (RelativeWidth >= Width) && Width > 0) { if (!HasLeft && HasRight) { ResultRect.left = ResultRect.right - Width; } else { ResultRect.right = ResultRect.left + Width; } } if (HasHeight && (RelativeHeight >= Height) && Height > 0) { if (!HasTop && HasBottom) { ResultRect.top = ResultRect.bottom - Height; } else { ResultRect.bottom = ResultRect.top + Height; } } if (ResultRect.right <= ResultRect.left) { ResultRect.right = RelativeWidth; } if (ResultRect.bottom <= ResultRect.top) { ResultRect.bottom = RelativeHeight; } CopyRect (StatementRect, &ResultRect); return Status; } STATIC EFI_STATUS GetPropValue ( IN CHAR8 *PropStr, IN EFI_GUID *FormsetId, IN UINT16 FormId, IN UINT32 StatementId, IN UINT64 Value, IN H2O_PANEL_INFO *Panel, IN UINT32 StyleType, IN UINT32 PseudoClass, IN RECT *RelativeField, OUT H2O_PROPERTY_VALUE *PropValue ) { EFI_STATUS Status; H2O_VFR_PROPERTY VfrProperty; H2O_PROPERTY_INFO *Property; if (PropStr == NULL || PropValue == NULL) { return EFI_INVALID_PARAMETER; } ZeroMem (PropValue, sizeof (H2O_PROPERTY_VALUE)); ZeroMem (&VfrProperty, sizeof (H2O_VFR_PROPERTY)); Status = GetVfrPropertyByStatement ( FormsetId, FormId, StatementId, Value, &VfrProperty ); if (EFI_ERROR (Status)) { //return Status; } Status = GetPropertyFromVfrAndPanel (Panel, &VfrProperty, StyleType, PseudoClass, PropStr, RelativeField, &Property, PropValue); if (EFI_ERROR (Status)) { return Status; } return EFI_SUCCESS; } EFI_STATUS GetStatementPropValue ( IN CHAR8 *PropStr, IN H2O_FORM_BROWSER_S *Statement, IN H2O_PANEL_INFO *Panel, IN UINT32 StyleType, IN UINT32 PseudoClass, IN RECT *RelativeField, OUT H2O_PROPERTY_VALUE *PropValue ) { EFI_STATUS Status; if (PropStr == NULL || Statement == NULL || PropValue == NULL) { return EFI_INVALID_PARAMETER; } Status = GetPropValue ( PropStr, &Statement->FormsetGuid, Statement->FormId, Statement->StatementId, Statement->HiiValue.Value.u64, Panel, StyleType, PseudoClass, RelativeField, PropValue ); if (!EFI_ERROR (Status)) { return EFI_SUCCESS; } Status = GetPropValue ( PropStr, &Statement->FormsetGuid, Statement->FormId, Statement->StatementId, Statement->HiiValue.Value.u64, Panel, GetStyleTypeByOpCode (Statement->Operand), PseudoClass, RelativeField, PropValue ); if (!EFI_ERROR (Status)) { return EFI_SUCCESS; } return Status; } H2O_PANEL_INFO * GetPanelInfo ( IN H2O_LAYOUT_INFO *LayoutInfo, IN UINT32 PanelId ) { LIST_ENTRY *PanelLink; H2O_PANEL_INFO *Panel; ASSERT (LayoutInfo != NULL); if (LayoutInfo == NULL) { return NULL; } PanelLink = &LayoutInfo->PanelListHead; if (IsNull (PanelLink, PanelLink->ForwardLink)) { return NULL; } do { PanelLink = PanelLink->ForwardLink; Panel = H2O_PANEL_INFO_NODE_FROM_LINK (PanelLink); if (Panel->PanelId == PanelId) { return Panel; } } while (!IsNodeAtEnd (&LayoutInfo->PanelListHead, PanelLink)); return NULL; } UINT32 GetPseudoClassByStatement ( IN H2O_FORM_BROWSER_S *Statement ) { UINT32 PseudoClass; PseudoClass = H2O_STYLE_PSEUDO_CLASS_NORMAL; if (Statement->Selectable) { PseudoClass = H2O_STYLE_PSEUDO_CLASS_SELECTABLE; } if (Statement->GrayedOut) { PseudoClass = H2O_STYLE_PSEUDO_CLASS_GRAYOUT; } if (Statement->Locked) { PseudoClass = H2O_STYLE_PSEUDO_CLASS_GRAYOUT; } if (Statement->ReadOnly) { PseudoClass = H2O_STYLE_PSEUDO_CLASS_GRAYOUT; } return PseudoClass; }