text: /** @file
    This file is part of OpenCanopy, OpenCore GUI.
  
    Copyright (c) 2018-2019, Download-Fritz. All rights reserved.<BR>
    SPDX-License-Identifier: BSD-3-Clause
  **/
  
  #include <Uefi.h>
  
  #include <IndustryStandard/AppleIcon.h>
  #include <Protocol/OcInterface.h>
  
  #include <Library/DebugLib.h>
  #include <Library/MemoryAllocationLib.h>
  #include <Library/OcBootManagementLib.h>
  #include <Library/OcStorageLib.h>
  #include <Library/UefiBootServicesTableLib.h>
  #include <Library/UefiRuntimeServicesTableLib.h>
  #include <Library/PrintLib.h>
  #include <Library/BaseLib.h>
  
  #include <Guid/AppleVariable.h>
  #include <Protocol/UserInterfaceTheme.h>
  
  #include "OpenCanopy.h"
  #include "BmfLib.h"
  #include "GuiApp.h"
  
  GLOBAL_REMOVE_IF_UNREFERENCED BOOT_PICKER_GUI_CONTEXT  mGuiContext;
  
  //
  // FIXME: Should not be global here.
  //
  STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL  mHighlightPixel = { 0xAF, 0xAF, 0xAF, 0x32 };
  
  STATIC
  CONST CHAR8 *
    mLabelNames[LABEL_NUM_TOTAL] = {
    [LABEL_GENERIC_HDD]        = "EFIBoot",
    [LABEL_APPLE]              = "Apple",
    [LABEL_APPLE_RECOVERY]     = "AppleRecv",
    [LABEL_APPLE_TIME_MACHINE] = "AppleTM",
    [LABEL_WINDOWS]            = "Windows",
    [LABEL_OTHER]              = "Other",
    [LABEL_TOOL]               = "Tool",
    [LABEL_RESET_NVRAM]        = "ResetNVRAM",
    [LABEL_SHELL]              = "Shell",
    [LABEL_SIP_IS_ENABLED]     = "SIPEnabled",
    [LABEL_SIP_IS_DISABLED]    = "SIPDisabled"
  };
  
  STATIC
  CONST CHAR8 *
    mIconNames[ICON_NUM_TOTAL] = {
    [ICON_CURSOR]             = "Cursor",
    [ICON_SELECTED]           = "Selected",
    [ICON_SELECTOR]           = "Selector",
    [ICON_SET_DEFAULT]        = "SetDefault",
    [ICON_LEFT]               = "Left",
    [ICON_RIGHT]              = "Right",
    [ICON_SHUT_DOWN]          = "ShutDown",
    [ICON_RESTART]            = "Restart",
    [ICON_BUTTON_FOCUS]       = "BtnFocus",
    [ICON_PASSWORD]           = "Password",
    [ICON_DOT]                = "Dot",
    [ICON_ENTER]              = "Enter",
    [ICON_LOCK]               = "Lock",
    [ICON_GENERIC_HDD]        = "HardDrive",
    [ICON_APPLE]              = "Apple",
    [ICON_APPLE_RECOVERY]     = "AppleRecv",
    [ICON_APPLE_TIME_MACHINE] = "AppleTM",
    [ICON_WINDOWS]            = "Windows",
    [ICON_OTHER]              = "Other",
    [ICON_TOOL]               = "Tool",
    [ICON_RESET_NVRAM]        = "ResetNVRAM",
    [ICON_SHELL]              = "Shell"
  };
  
  STATIC
  VOID
  InternalSafeFreePool (
    IN CONST VOID  *Memory
    )
  {
    if (Memory != NULL) {
      FreePool ((VOID *)Memory);
    }
  }
  
  STATIC
  VOID
  InternalContextDestruct (
    IN OUT BOOT_PICKER_GUI_CONTEXT  *Context
    )
  {
    UINT32  Index;
    UINT32  Index2;
  
    for (Index = 0; Index < ICON_NUM_TOTAL; ++Index) {
      for (Index2 = 0; Index2 < ICON_TYPE_COUNT; ++Index2) {
        InternalSafeFreePool (Context->Icons[Index][Index2].Buffer);
      }
    }
  
    for (Index = 0; Index < LABEL_NUM_TOTAL; ++Index) {
      InternalSafeFreePool (Context->Labels[Index].Buffer);
    }
  
    InternalSafeFreePool (Context->Background.Buffer);
    InternalSafeFreePool (Context->FontContext.FontImage.Buffer);
  
    /*
    InternalSafeFreePool (Context->Poof[0].Buffer);
    InternalSafeFreePool (Context->Poof[1].Buffer);
    InternalSafeFreePool (Context->Poof[2].Buffer);
    InternalSafeFreePool (Context->Poof[3].Buffer);
    InternalSafeFreePool (Context->Poof[4].Buffer);
    */
  }
  
  STATIC
  EFI_STATUS
  LoadImageFileFromStorage (
    OUT GUI_IMAGE           *Images,
    IN  OC_STORAGE_CONTEXT  *Storage,
    IN  CONST CHAR8         *ImageFilePath,
    IN  UINT8               Scale,
    IN  UINT32              MatchWidth,
    IN  UINT32              MatchHeight,
    IN  BOOLEAN             Icon,
    IN  CONST CHAR8         *Prefix,
    IN  BOOLEAN             AllowLessSize
    )
  {
    EFI_STATUS  Status;
    CHAR16      Path[OC_STORAGE_SAFE_PATH_MAX];
    UINT8       *FileData;
    UINT32      FileSize;
    UINT32      ImageCount;
    UINT32      Index;
  
    ASSERT (ImageFilePath != NULL);
    ASSERT (Scale == 1 || Scale == 2);
  
    ImageCount = Icon ? ICON_TYPE_COUNT : 1; ///< Icons can be external.
  
    for (Index = 0; Index < ImageCount; ++Index) {
      Status = OcUnicodeSafeSPrint (
                 Path,
                 sizeof (Path),
                 OPEN_CORE_IMAGE_PATH L"%a\\%a%a.icns",
                 Prefix,
                 Index > 0 ? "Ext" : "",
                 ImageFilePath
                 );
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_WARN, "OCUI: Cannot fit %a\n", ImageFilePath));
        return EFI_OUT_OF_RESOURCES;
      }
  
      UnicodeUefiSlashes (Path);
      Status = EFI_NOT_FOUND;
      if (OcStorageExistsFileUnicode (Storage, Path)) {
        FileData = OcStorageReadFileUnicode (Storage, Path, &FileSize);
        if ((FileData != NULL) && (FileSize > 0)) {
          Status = GuiIcnsToImageIcon (
                     &Images[Index],
                     FileData,
                     FileSize,
                     Scale,
                     MatchWidth,
                     MatchHeight,
                     AllowLessSize
                     );
        }
  
        if (FileData != NULL) {
          FreePool (FileData);
        }
      }
  
      if (EFI_ERROR (Status)) {
        DEBUG ((
          DEBUG_INFO,
          "OCUI: Failed to load image (%u/%u) %s prefix:%a icon:%d - %r\n",
          Index+1,
          ImageCount,
          Path,
          Prefix,
          Icon,
          Status
          ));
        if (Index == ICON_TYPE_BASE) {
          STATIC_ASSERT (
            ICON_TYPE_BASE == 0,
            "Memory may be leaked due to previously loaded images."
            );
          return EFI_NOT_FOUND;
        }
  
        Images[Index].Width  = 0;
        Images[Index].Height = 0;
        Images[Index].Buffer = NULL;
      }
    }
  
    return EFI_SUCCESS;
  }
  
  STATIC
  EFI_STATUS
  LoadLabelFileFromStorageForScale (
    IN  OC_STORAGE_CONTEXT  *Storage,
    IN  CONST CHAR8         *LabelFilePath,
    IN  UINT8               Scale,
    OUT VOID                **FileData,
    OUT UINT32              *FileSize
    )
  {
    EFI_STATUS  Status;
    CHAR16      Path[OC_STORAGE_SAFE_PATH_MAX];
  
    ASSERT (Scale == 1 || Scale == 2);
  
    Status = OcUnicodeSafeSPrint (
               Path,
               sizeof (Path),
               OPEN_CORE_LABEL_PATH L"%a.%a",
               LabelFilePath,
               Scale == 2 ? "l2x" : "lbl"
               );
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_WARN, "OCUI: Cannot fit %a\n", LabelFilePath));
      return EFI_OUT_OF_RESOURCES;
    }
  
    *FileData = OcStorageReadFileUnicode (Storage, Path, FileSize);
  
    if (*FileData == NULL) {
      DEBUG ((DEBUG_WARN, "OCUI: Failed to load %s\n", Path));
      return EFI_NOT_FOUND;
    }
  
    if (*FileSize == 0) {
      FreePool (*FileData);
      DEBUG ((DEBUG_WARN, "OCUI: Empty %s\n", Path));
      return EFI_NOT_FOUND;
    }
  
    return EFI_SUCCESS;
  }
  
  EFI_STATUS
  LoadLabelFromStorage (
    IN  OC_STORAGE_CONTEXT  *Storage,
    IN  CONST CHAR8         *ImageFilePath,
    IN  UINT8               Scale,
    IN  BOOLEAN             Inverted,
    OUT GUI_IMAGE           *Image
    )
  {
    VOID        *ImageData;
    UINT32      ImageSize;
    EFI_STATUS  Status;
  
    ASSERT (Scale == 1 || Scale == 2);
  
    Status = LoadLabelFileFromStorageForScale (Storage, ImageFilePath, Scale, &ImageData, &ImageSize);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  
    Status = GuiLabelToImage (Image, ImageData, ImageSize, Scale, Inverted);
  
    FreePool (ImageData);
  
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_WARN, "OCUI: Failed to decode label %a - %r\n", ImageFilePath, Status));
    }
  
    return Status;
  }
  
  EFI_STATUS
  InternalGetFlavourIcon (
    IN  BOOT_PICKER_GUI_CONTEXT  *GuiContext,
    IN  OC_STORAGE_CONTEXT       *Storage,
    IN  CHAR8                    *FlavourName,
    IN  UINTN                    FlavourNameLen,
    IN  UINT32                   IconTypeIndex,
    IN  BOOLEAN                  UseFlavourIcon,
    OUT GUI_IMAGE                *EntryIcon,
    OUT BOOLEAN                  *CustomIcon
    )
  {
    EFI_STATUS  Status;
    CHAR16      Path[OC_STORAGE_SAFE_PATH_MAX];
    CHAR8       ImageName[OC_MAX_CONTENT_FLAVOUR_SIZE];
    UINT8       *FileData;
    UINT32      FileSize;
    UINTN       Index;
  
    ASSERT (EntryIcon != NULL);
    ASSERT (CustomIcon != NULL);
  
    if ((FlavourNameLen == 0) ||
        (OcAsciiStrniCmp (FlavourName, OC_FLAVOUR_AUTO, FlavourNameLen) == 0)
        )
    {
      return EFI_UNSUPPORTED;
    }
  
    //
    // Look in preloaded icons
    //
    for (Index = ICON_NUM_SYS; Index < ICON_NUM_TOTAL; ++Index) {
      if (OcAsciiStrniCmp (FlavourName, mIconNames[Index], FlavourNameLen) == 0) {
        if (GuiContext->Icons[Index][IconTypeIndex].Buffer != NULL) {
          CopyMem (EntryIcon, &GuiContext->Icons[Index][IconTypeIndex], sizeof (*EntryIcon));
          *CustomIcon = FALSE;
          return EFI_SUCCESS;
        }
  
        break;
      }
    }
  
    //
    // Look for custom icon
    //
    if (!UseFlavourIcon) {
      return EFI_NOT_FOUND;
    }
  
    AsciiStrnCpyS (ImageName, OC_MAX_CONTENT_FLAVOUR_SIZE, FlavourName, FlavourNameLen);
    Status = OcUnicodeSafeSPrint (
               Path,
               sizeof (Path),
               OPEN_CORE_IMAGE_PATH L"%a\\%a%a.icns",
               GuiContext->Prefix,
               IconTypeIndex > 0 ? "Ext" : "",
               ImageName
               );
  
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_WARN, "OCUI: Cannot fit %a\n", ImageName));
      return Status;
    }
  
    UnicodeUefiSlashes (Path);
    DEBUG ((DEBUG_INFO, "OCUI: Trying flavour icon %s\n", Path));
  
    Status = EFI_NOT_FOUND;
    if (OcStorageExistsFileUnicode (Storage, Path)) {
      FileData = OcStorageReadFileUnicode (Storage, Path, &FileSize);
      if ((FileData != NULL) && (FileSize > 0)) {
        Status = GuiIcnsToImageIcon (
                   EntryIcon,
                   FileData,
                   FileSize,
                   GuiContext->Scale,
                   BOOT_ENTRY_ICON_DIMENSION,
                   BOOT_ENTRY_ICON_DIMENSION,
                   FALSE
                   );
      }
  
      if (FileData != NULL) {
        FreePool (FileData);
      }
  
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_WARN, "OCUI: Invalid icon file\n"));
      }
    }
  
    if (!EFI_ERROR (Status)) {
      ASSERT (EntryIcon->Buffer != NULL);
      *CustomIcon = TRUE;
      return EFI_SUCCESS;
    }
  
    return EFI_NOT_FOUND;
  }
  
  EFI_STATUS
  InternalContextConstruct (
    OUT BOOT_PICKER_GUI_CONTEXT  *Context,
    IN  OC_STORAGE_CONTEXT       *Storage,
    IN  OC_PICKER_CONTEXT        *Picker
    )
  {
    EFI_STATUS                         Status;
    EFI_USER_INTERFACE_THEME_PROTOCOL  *UiTheme;
    VOID                               *FontImage;
    VOID                               *FontData;
    UINT32                             FontImageSize;
    UINT32                             FontDataSize;
    UINTN                              UiScaleSize;
    UINT32                             Index;
    UINT32                             ImageWidth;
    UINT32                             ImageHeight;
    BOOLEAN                            Result;
    BOOLEAN                            AllowLessSize;
  
    ASSERT (Context != NULL);
  
    Context->Scale = 1;
    UiScaleSize    = sizeof (Context->Scale);
  
    Status = gRT->GetVariable (
                    APPLE_UI_SCALE_VARIABLE_NAME,
                    &gAppleVendorVariableGuid,
                    NULL,
                    &UiScaleSize,
                    (VOID *)&Context->Scale
                    );
  
    if (EFI_ERROR (Status) || (Context->Scale != 2)) {
      Context->Scale = 1;
    }
  
    Status = gBS->LocateProtocol (
                    &gEfiUserInterfaceThemeProtocolGuid,
                    NULL,
                    (VOID **)&UiTheme
                    );
    if (!EFI_ERROR (Status)) {
      Status = UiTheme->GetBackgroundColor (&Context->BackgroundColor.Raw);
    }
  
    if (EFI_ERROR (Status)) {
      Context->BackgroundColor.Raw = APPLE_COLOR_SYRAH_BLACK;
    }
  
    if (AsciiStrCmp (Picker->PickerVariant, "Auto") == 0) {
      if (Context->BackgroundColor.Raw == APPLE_COLOR_LIGHT_GRAY) {
        Context->Prefix = "Acidanthera\\Chardonnay";
      } else {
        Context->Prefix = "Acidanthera\\GoldenGate";
      }
    } else if (AsciiStrCmp (Picker->PickerVariant, "Default") == 0) {
      Context->Prefix = "Acidanthera\\GoldenGate";
    } else {
      Context->Prefix = Picker->PickerVariant;
    }
  
    LoadImageFileFromStorage (
      &Context->Background,
      Storage,
      "Background",
      Context->Scale,
      0,
      0,
      FALSE,
      Context->Prefix,
      FALSE
      );
  
    if (Context->BackgroundColor.Raw == APPLE_COLOR_SYRAH_BLACK) {
      Context->LightBackground = FALSE;
    } else if (Context->BackgroundColor.Raw == APPLE_COLOR_LIGHT_GRAY) {
      Context->LightBackground = TRUE;
    } else {
      //
      // FIXME: Support proper W3C formula.
      //
      Context->LightBackground = (Context->BackgroundColor.Pixel.Red * 299U
                                  + Context->BackgroundColor.Pixel.Green * 587U
                                  + Context->BackgroundColor.Pixel.Blue * 114U) >= 186000;
    }
  
    //
    // Set background colour with full opacity.
    //
    Context->BackgroundColor.Pixel.Reserved = 0xFF;
  
    for (Index = 0; Index < ICON_NUM_TOTAL; ++Index) {
      AllowLessSize = FALSE;
      if (Index == ICON_CURSOR) {
        ImageWidth    = MAX_CURSOR_DIMENSION;
        ImageHeight   = MAX_CURSOR_DIMENSION;
        AllowLessSize = TRUE;
      } else if (Index == ICON_SELECTED) {
        ImageWidth  = BOOT_SELECTOR_BACKGROUND_DIMENSION;
        ImageHeight = BOOT_SELECTOR_BACKGROUND_DIMENSION;
      } else if ((Index == ICON_SELECTOR) || (Index == ICON_SET_DEFAULT)) {
        ImageWidth    = BOOT_SELECTOR_BUTTON_WIDTH;
        ImageHeight   = BOOT_SELECTOR_BUTTON_HEIGHT;
        AllowLessSize = TRUE;
      } else if ((Index == ICON_LEFT) || (Index == ICON_RIGHT)) {
        ImageWidth  = BOOT_SCROLL_BUTTON_DIMENSION;
        ImageHeight = BOOT_SCROLL_BUTTON_DIMENSION;
      } else if ((Index == ICON_SHUT_DOWN) || (Index == ICON_RESTART)) {
        ImageWidth    = BOOT_ACTION_BUTTON_DIMENSION;
        ImageHeight   = BOOT_ACTION_BUTTON_DIMENSION;
        AllowLessSize = TRUE;
      } else if (Index == ICON_BUTTON_FOCUS) {
        ImageWidth    = BOOT_ACTION_BUTTON_FOCUS_DIMENSION;
        ImageHeight   = BOOT_ACTION_BUTTON_FOCUS_DIMENSION;
        AllowLessSize = TRUE;
      } else if (Index == ICON_PASSWORD) {
        ImageWidth    = PASSWORD_BOX_WIDTH;
        ImageHeight   = PASSWORD_BOX_HEIGHT;
        AllowLessSize = TRUE;
      } else if (Index == ICON_LOCK) {
        ImageWidth    = PASSWORD_LOCK_DIMENSION;
        ImageHeight   = PASSWORD_LOCK_DIMENSION;
        AllowLessSize = TRUE;
      } else if (Index == ICON_ENTER) {
        ImageWidth    = PASSWORD_ENTER_WIDTH;
        ImageHeight   = PASSWORD_ENTER_HEIGHT;
        AllowLessSize = TRUE;
      } else if (Index == ICON_DOT) {
        ImageWidth    = PASSWORD_DOT_DIMENSION;
        ImageHeight   = PASSWORD_DOT_DIMENSION;
        AllowLessSize = TRUE;
      } else {
        ImageWidth  = BOOT_ENTRY_ICON_DIMENSION;
        ImageHeight = BOOT_ENTRY_ICON_DIMENSION;
      }
  
      Status = LoadImageFileFromStorage (
                 Context->Icons[Index],
                 Storage,
                 mIconNames[Index],
                 Context->Scale,
                 ImageWidth,
                 ImageHeight,
                 Index >= ICON_NUM_SYS,
                 Context->Prefix,
                 AllowLessSize
                 );
      if (!EFI_ERROR (Status)) {
        if ((Index == ICON_SELECTOR) || (Index == ICON_SET_DEFAULT) || (Index == ICON_LEFT) || (Index == ICON_RIGHT) || (Index == ICON_SHUT_DOWN) || (Index == ICON_RESTART) || (Index == ICON_ENTER)) {
          Status = GuiCreateHighlightedImage (
                     &Context->Icons[Index][ICON_TYPE_HELD],
                     &Context->Icons[Index][ICON_TYPE_BASE],
                     &mHighlightPixel
                     );
          if (Index == ICON_SET_DEFAULT) {
            if (Context->Icons[Index]->Width != Context->Icons[ICON_SELECTOR]->Width) {
              Status = EFI_UNSUPPORTED;
              DEBUG ((
                DEBUG_WARN,
                "OCUI: %a width %upx != %a width %upx\n",
                mIconNames[Index],
                Context->Icons[Index]->Width,
                mIconNames[ICON_SELECTOR],
                Context->Icons[ICON_SELECTOR]->Width
                ));
              STATIC_ASSERT (
                ICON_SELECTOR < ICON_SET_DEFAULT,
                "Selector must be loaded before SetDefault."
                );
            }
          }
        } else if (  (Index == ICON_GENERIC_HDD)
                  && (Context->Icons[Index][ICON_TYPE_EXTERNAL].Buffer == NULL))
        {
          //
          // For generic disk icon being able to distinguish internal and external
          // disk icons is a security requirement. These icons are used whenever
          // 'typed' external icons are not available.
          //
          Status = EFI_NOT_FOUND;
          DEBUG ((DEBUG_WARN, "OCUI: Missing external disk icon\n"));
          STATIC_ASSERT (
            ICON_GENERIC_HDD < ICON_NUM_MANDATORY,
            "The base icon should must be cleaned up explicitly."
            );
        } else if (Index == ICON_CURSOR) {
          if (  (Context->Icons[ICON_CURSOR][ICON_TYPE_BASE].Width < MIN_CURSOR_DIMENSION * Context->Scale)
             || (Context->Icons[ICON_CURSOR][ICON_TYPE_BASE].Height < MIN_CURSOR_DIMENSION * Context->Scale))
          {
            DEBUG ((
              DEBUG_INFO,
              "OCUI: Expected at least %dx%d for cursor, actual %dx%d\n",
              MIN_CURSOR_DIMENSION * Context->Scale,
              MIN_CURSOR_DIMENSION * Context->Scale,
              Context->Icons[ICON_CURSOR][ICON_TYPE_BASE].Width,
              Context->Icons[ICON_CURSOR][ICON_TYPE_BASE].Height
              ));
            Status = EFI_UNSUPPORTED;
          }
        }
      } else {
        ZeroMem (&Context->Icons[Index], sizeof (Context->Icons[Index]));
      }
  
      if (EFI_ERROR (Status) && (Index < ICON_NUM_MANDATORY)) {
        DEBUG ((DEBUG_WARN, "OCUI: Failed to load images for %a\n", Context->Prefix));
        InternalContextDestruct (Context);
        return EFI_UNSUPPORTED;
      }
    }
  
    for (Index = 0; Index < LABEL_NUM_TOTAL; ++Index) {
      Status = LoadLabelFromStorage (
                 Storage,
                 mLabelNames[Index],
                 Context->Scale,
                 Context->LightBackground,
                 &Context->Labels[Index]
                 );
      if (EFI_ERROR (Status)) {
        Context->Labels[Index].Buffer = NULL;
        DEBUG ((DEBUG_WARN, "OCUI: Failed to load images\n"));
        InternalContextDestruct (Context);
        return EFI_UNSUPPORTED;
      }
    }
  
    if (Context->Scale == 2) {
      FontImage = OcStorageReadFileUnicode (Storage, OPEN_CORE_FONT_PATH L"Font_2x.png", &FontImageSize);
      FontData  = OcStorageReadFileUnicode (Storage, OPEN_CORE_FONT_PATH L"Font_2x.bin", &FontDataSize);
    } else {
      FontImage = OcStorageReadFileUnicode (Storage, OPEN_CORE_FONT_PATH L"Font_1x.png", &FontImageSize);
      FontData  = OcStorageReadFileUnicode (Storage, OPEN_CORE_FONT_PATH L"Font_1x.bin", &FontDataSize);
    }
  
    if ((FontImage != NULL) && (FontData != NULL)) {
      Result = GuiFontConstruct (
                 &Context->FontContext,
                 FontImage,
                 FontImageSize,
                 FontData,
                 FontDataSize,
                 Context->Scale
                 );
      if (Context->FontContext.BmfContext.Height != (BOOT_ENTRY_LABEL_HEIGHT - BOOT_ENTRY_LABEL_TEXT_OFFSET) * Context->Scale) {
        DEBUG ((
          DEBUG_WARN,
          "OCUI: Font has height %d instead of %d\n",
          Context->FontContext.BmfContext.Height,
          (BOOT_ENTRY_LABEL_HEIGHT - BOOT_ENTRY_LABEL_TEXT_OFFSET) * Context->Scale
          ));
        Result = FALSE;
      }
    } else {
      Result = FALSE;
    }
  
    if (!Result) {
      DEBUG ((DEBUG_WARN, "OCUI: Font init failed\n"));
      InternalContextDestruct (Context);
      return EFI_UNSUPPORTED;
    }
  
    return EFI_SUCCESS;
  }
  
  CONST GUI_IMAGE *
  InternalGetCursorImage (
    IN BOOT_PICKER_GUI_CONTEXT  *Context
    )
  {
    ASSERT (Context != NULL);
    //
    // ATTENTION: All images must have the same dimensions.
    //
    return &Context->Icons[ICON_CURSOR][ICON_TYPE_BASE];
  }
  