Add modes for a few common display resolutions higher than 800x600, specifically 1024x768, 1280x800 and 1920x1080, so ConSplitterDxe has more options available. The mode list is not use as-is, InitializeGraphicsConsoleTextMode() will check the list and filter out any modes which don't fit to the screen, so this will also work fine for small displays. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn> Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
		
			
				
	
	
		
			2156 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2156 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  This is the main routine for initializing the Graphics Console support routines.
 | 
						|
 | 
						|
Copyright (c) 2006 - 2022, Intel Corporation. All rights reserved.<BR>
 | 
						|
SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "GraphicsConsole.h"
 | 
						|
 | 
						|
//
 | 
						|
// Graphics Console Device Private Data template
 | 
						|
//
 | 
						|
GRAPHICS_CONSOLE_DEV  mGraphicsConsoleDevTemplate = {
 | 
						|
  GRAPHICS_CONSOLE_DEV_SIGNATURE,
 | 
						|
  (EFI_GRAPHICS_OUTPUT_PROTOCOL *)NULL,
 | 
						|
  (EFI_UGA_DRAW_PROTOCOL *)NULL,
 | 
						|
  {
 | 
						|
    GraphicsConsoleConOutReset,
 | 
						|
    GraphicsConsoleConOutOutputString,
 | 
						|
    GraphicsConsoleConOutTestString,
 | 
						|
    GraphicsConsoleConOutQueryMode,
 | 
						|
    GraphicsConsoleConOutSetMode,
 | 
						|
    GraphicsConsoleConOutSetAttribute,
 | 
						|
    GraphicsConsoleConOutClearScreen,
 | 
						|
    GraphicsConsoleConOutSetCursorPosition,
 | 
						|
    GraphicsConsoleConOutEnableCursor,
 | 
						|
    (EFI_SIMPLE_TEXT_OUTPUT_MODE *)NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    0,
 | 
						|
    -1,
 | 
						|
    EFI_TEXT_ATTR (EFI_LIGHTGRAY,          EFI_BLACK),
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    FALSE
 | 
						|
  },
 | 
						|
  (GRAPHICS_CONSOLE_MODE_DATA *)NULL,
 | 
						|
  (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)NULL
 | 
						|
};
 | 
						|
 | 
						|
GRAPHICS_CONSOLE_MODE_DATA  mGraphicsConsoleModeData[] = {
 | 
						|
  { 100, 31 },  //  800 x 600
 | 
						|
  { 128, 40 },  // 1024 x 768
 | 
						|
  { 160, 42 },  // 1280 x 800
 | 
						|
  { 240, 56 },  // 1920 x 1080
 | 
						|
  //
 | 
						|
  // New modes can be added here.
 | 
						|
  // The last entry is specific for full screen mode.
 | 
						|
  //
 | 
						|
  { 0,   0  }
 | 
						|
};
 | 
						|
 | 
						|
EFI_HII_DATABASE_PROTOCOL  *mHiiDatabase;
 | 
						|
EFI_HII_FONT_PROTOCOL      *mHiiFont;
 | 
						|
EFI_HII_HANDLE             mHiiHandle;
 | 
						|
VOID                       *mHiiRegistration;
 | 
						|
 | 
						|
EFI_GUID  mFontPackageListGuid = {
 | 
						|
  0xf5f219d3, 0x7006, 0x4648, { 0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad }
 | 
						|
};
 | 
						|
 | 
						|
CHAR16  mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };
 | 
						|
 | 
						|
EFI_GRAPHICS_OUTPUT_BLT_PIXEL  mGraphicsEfiColors[16] = {
 | 
						|
  //
 | 
						|
  // B    G    R   reserved
 | 
						|
  //
 | 
						|
  { 0x00, 0x00, 0x00, 0x00 },  // BLACK
 | 
						|
  { 0x98, 0x00, 0x00, 0x00 },  // LIGHTBLUE
 | 
						|
  { 0x00, 0x98, 0x00, 0x00 },  // LIGHGREEN
 | 
						|
  { 0x98, 0x98, 0x00, 0x00 },  // LIGHCYAN
 | 
						|
  { 0x00, 0x00, 0x98, 0x00 },  // LIGHRED
 | 
						|
  { 0x98, 0x00, 0x98, 0x00 },  // MAGENTA
 | 
						|
  { 0x00, 0x98, 0x98, 0x00 },  // BROWN
 | 
						|
  { 0x98, 0x98, 0x98, 0x00 },  // LIGHTGRAY
 | 
						|
  { 0x30, 0x30, 0x30, 0x00 },  // DARKGRAY - BRIGHT BLACK
 | 
						|
  { 0xff, 0x00, 0x00, 0x00 },  // BLUE
 | 
						|
  { 0x00, 0xff, 0x00, 0x00 },  // LIME
 | 
						|
  { 0xff, 0xff, 0x00, 0x00 },  // CYAN
 | 
						|
  { 0x00, 0x00, 0xff, 0x00 },  // RED
 | 
						|
  { 0xff, 0x00, 0xff, 0x00 },  // FUCHSIA
 | 
						|
  { 0x00, 0xff, 0xff, 0x00 },  // YELLOW
 | 
						|
  { 0xff, 0xff, 0xff, 0x00 }   // WHITE
 | 
						|
};
 | 
						|
 | 
						|
EFI_NARROW_GLYPH  mCursorGlyph = {
 | 
						|
  0x0000,
 | 
						|
  0x00,
 | 
						|
  { 0x00,0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }
 | 
						|
};
 | 
						|
 | 
						|
CHAR16  SpaceStr[] = { NARROW_CHAR, ' ', 0 };
 | 
						|
 | 
						|
EFI_DRIVER_BINDING_PROTOCOL  gGraphicsConsoleDriverBinding = {
 | 
						|
  GraphicsConsoleControllerDriverSupported,
 | 
						|
  GraphicsConsoleControllerDriverStart,
 | 
						|
  GraphicsConsoleControllerDriverStop,
 | 
						|
  0xa,
 | 
						|
  NULL,
 | 
						|
  NULL
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  Test to see if Graphics Console could be supported on the Controller.
 | 
						|
 | 
						|
  Graphics Console could be supported if Graphics Output Protocol or UGA Draw
 | 
						|
  Protocol exists on the Controller. (UGA Draw Protocol could be skipped
 | 
						|
  if PcdUgaConsumeSupport is set to FALSE.)
 | 
						|
 | 
						|
  @param  This                Protocol instance pointer.
 | 
						|
  @param  Controller          Handle of device to test.
 | 
						|
  @param  RemainingDevicePath Optional parameter use to pick a specific child
 | 
						|
                              device to start.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS         This driver supports this device.
 | 
						|
  @retval other               This driver does not support this device.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GraphicsConsoleControllerDriverSupported (
 | 
						|
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | 
						|
  IN EFI_HANDLE                   Controller,
 | 
						|
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                    Status;
 | 
						|
  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;
 | 
						|
  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;
 | 
						|
  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
 | 
						|
 | 
						|
  GraphicsOutput = NULL;
 | 
						|
  UgaDraw        = NULL;
 | 
						|
  //
 | 
						|
  // Open the IO Abstraction(s) needed to perform the supported test
 | 
						|
  //
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  Controller,
 | 
						|
                  &gEfiGraphicsOutputProtocolGuid,
 | 
						|
                  (VOID **)&GraphicsOutput,
 | 
						|
                  This->DriverBindingHandle,
 | 
						|
                  Controller,
 | 
						|
                  EFI_OPEN_PROTOCOL_BY_DRIVER
 | 
						|
                  );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
 | 
						|
    //
 | 
						|
    // Open Graphics Output Protocol failed, try to open UGA Draw Protocol
 | 
						|
    //
 | 
						|
    Status = gBS->OpenProtocol (
 | 
						|
                    Controller,
 | 
						|
                    &gEfiUgaDrawProtocolGuid,
 | 
						|
                    (VOID **)&UgaDraw,
 | 
						|
                    This->DriverBindingHandle,
 | 
						|
                    Controller,
 | 
						|
                    EFI_OPEN_PROTOCOL_BY_DRIVER
 | 
						|
                    );
 | 
						|
  }
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // We need to ensure that we do not layer on top of a virtual handle.
 | 
						|
  // We need to ensure that the handles produced by the conspliter do not
 | 
						|
  // get used.
 | 
						|
  //
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  Controller,
 | 
						|
                  &gEfiDevicePathProtocolGuid,
 | 
						|
                  (VOID **)&DevicePath,
 | 
						|
                  This->DriverBindingHandle,
 | 
						|
                  Controller,
 | 
						|
                  EFI_OPEN_PROTOCOL_BY_DRIVER
 | 
						|
                  );
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    gBS->CloseProtocol (
 | 
						|
           Controller,
 | 
						|
           &gEfiDevicePathProtocolGuid,
 | 
						|
           This->DriverBindingHandle,
 | 
						|
           Controller
 | 
						|
           );
 | 
						|
  } else {
 | 
						|
    goto Error;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Does Hii Exist?  If not, we aren't ready to run
 | 
						|
  //
 | 
						|
  Status = EfiLocateHiiProtocol ();
 | 
						|
 | 
						|
  //
 | 
						|
  // Close the I/O Abstraction(s) used to perform the supported test
 | 
						|
  //
 | 
						|
Error:
 | 
						|
  if (GraphicsOutput != NULL) {
 | 
						|
    gBS->CloseProtocol (
 | 
						|
           Controller,
 | 
						|
           &gEfiGraphicsOutputProtocolGuid,
 | 
						|
           This->DriverBindingHandle,
 | 
						|
           Controller
 | 
						|
           );
 | 
						|
  } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
 | 
						|
    gBS->CloseProtocol (
 | 
						|
           Controller,
 | 
						|
           &gEfiUgaDrawProtocolGuid,
 | 
						|
           This->DriverBindingHandle,
 | 
						|
           Controller
 | 
						|
           );
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Initialize all the text modes which the graphics console supports.
 | 
						|
 | 
						|
  It returns information for available text modes that the graphics can support.
 | 
						|
 | 
						|
  @param[in]  HorizontalResolution     The size of video screen in pixels in the X dimension.
 | 
						|
  @param[in]  VerticalResolution       The size of video screen in pixels in the Y dimension.
 | 
						|
  @param[in]  GopModeNumber            The graphics mode number which graphics console is based on.
 | 
						|
  @param[out] TextModeCount            The total number of text modes that graphics console supports.
 | 
						|
  @param[out] TextModeData             The buffer to the text modes column and row information.
 | 
						|
                                       Caller is responsible to free it when it's non-NULL.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS                  The supporting mode information is returned.
 | 
						|
  @retval EFI_INVALID_PARAMETER        The parameters are invalid.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
InitializeGraphicsConsoleTextMode (
 | 
						|
  IN UINT32                       HorizontalResolution,
 | 
						|
  IN UINT32                       VerticalResolution,
 | 
						|
  IN UINT32                       GopModeNumber,
 | 
						|
  OUT UINTN                       *TextModeCount,
 | 
						|
  OUT GRAPHICS_CONSOLE_MODE_DATA  **TextModeData
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN                       Index;
 | 
						|
  UINTN                       Count;
 | 
						|
  GRAPHICS_CONSOLE_MODE_DATA  *ModeBuffer;
 | 
						|
  GRAPHICS_CONSOLE_MODE_DATA  *NewModeBuffer;
 | 
						|
  UINTN                       ValidCount;
 | 
						|
  UINTN                       ValidIndex;
 | 
						|
  UINTN                       MaxColumns;
 | 
						|
  UINTN                       MaxRows;
 | 
						|
 | 
						|
  if ((TextModeCount == NULL) || (TextModeData == NULL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Count = sizeof (mGraphicsConsoleModeData) / sizeof (GRAPHICS_CONSOLE_MODE_DATA);
 | 
						|
 | 
						|
  //
 | 
						|
  // Compute the maximum number of text Rows and Columns that this current graphics mode can support.
 | 
						|
  // To make graphics console work well, MaxColumns and MaxRows should not be zero.
 | 
						|
  //
 | 
						|
  MaxColumns = HorizontalResolution / EFI_GLYPH_WIDTH;
 | 
						|
  MaxRows    = VerticalResolution / EFI_GLYPH_HEIGHT;
 | 
						|
 | 
						|
  //
 | 
						|
  // According to UEFI spec, all output devices support at least 80x25 text mode.
 | 
						|
  //
 | 
						|
  ASSERT ((MaxColumns >= 80) && (MaxRows >= 25));
 | 
						|
 | 
						|
  //
 | 
						|
  // Add full screen mode to the last entry.
 | 
						|
  //
 | 
						|
  mGraphicsConsoleModeData[Count - 1].Columns = MaxColumns;
 | 
						|
  mGraphicsConsoleModeData[Count - 1].Rows    = MaxRows;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get defined mode buffer pointer.
 | 
						|
  //
 | 
						|
  ModeBuffer = mGraphicsConsoleModeData;
 | 
						|
 | 
						|
  //
 | 
						|
  // Here we make sure that the final mode exposed does not include the duplicated modes,
 | 
						|
  // and does not include the invalid modes which exceed the max column and row.
 | 
						|
  // Reserve 2 modes for 80x25, 80x50 of graphics console.
 | 
						|
  //
 | 
						|
  NewModeBuffer = AllocateZeroPool (sizeof (GRAPHICS_CONSOLE_MODE_DATA) * (Count + 2));
 | 
						|
  ASSERT (NewModeBuffer != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
 | 
						|
  //
 | 
						|
  ValidCount = 0;
 | 
						|
 | 
						|
  NewModeBuffer[ValidCount].Columns       = 80;
 | 
						|
  NewModeBuffer[ValidCount].Rows          = 25;
 | 
						|
  NewModeBuffer[ValidCount].GopWidth      = HorizontalResolution;
 | 
						|
  NewModeBuffer[ValidCount].GopHeight     = VerticalResolution;
 | 
						|
  NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;
 | 
						|
  NewModeBuffer[ValidCount].DeltaX        = (HorizontalResolution - (NewModeBuffer[ValidCount].Columns * EFI_GLYPH_WIDTH)) >> 1;
 | 
						|
  NewModeBuffer[ValidCount].DeltaY        = (VerticalResolution - (NewModeBuffer[ValidCount].Rows * EFI_GLYPH_HEIGHT)) >> 1;
 | 
						|
  ValidCount++;
 | 
						|
 | 
						|
  if ((MaxColumns >= 80) && (MaxRows >= 50)) {
 | 
						|
    NewModeBuffer[ValidCount].Columns = 80;
 | 
						|
    NewModeBuffer[ValidCount].Rows    = 50;
 | 
						|
    NewModeBuffer[ValidCount].DeltaX  = (HorizontalResolution - (80 * EFI_GLYPH_WIDTH)) >> 1;
 | 
						|
    NewModeBuffer[ValidCount].DeltaY  = (VerticalResolution - (50 * EFI_GLYPH_HEIGHT)) >> 1;
 | 
						|
  }
 | 
						|
 | 
						|
  NewModeBuffer[ValidCount].GopWidth      = HorizontalResolution;
 | 
						|
  NewModeBuffer[ValidCount].GopHeight     = VerticalResolution;
 | 
						|
  NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;
 | 
						|
  ValidCount++;
 | 
						|
 | 
						|
  //
 | 
						|
  // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
 | 
						|
  //
 | 
						|
  for (Index = 0; Index < Count; Index++) {
 | 
						|
    if ((ModeBuffer[Index].Columns == 0) || (ModeBuffer[Index].Rows == 0) ||
 | 
						|
        (ModeBuffer[Index].Columns > MaxColumns) || (ModeBuffer[Index].Rows > MaxRows))
 | 
						|
    {
 | 
						|
      //
 | 
						|
      // Skip the pre-defined mode which is invalid or exceeds the max column and row.
 | 
						|
      //
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    for (ValidIndex = 0; ValidIndex < ValidCount; ValidIndex++) {
 | 
						|
      if ((ModeBuffer[Index].Columns == NewModeBuffer[ValidIndex].Columns) &&
 | 
						|
          (ModeBuffer[Index].Rows == NewModeBuffer[ValidIndex].Rows))
 | 
						|
      {
 | 
						|
        //
 | 
						|
        // Skip the duplicated mode.
 | 
						|
        //
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (ValidIndex == ValidCount) {
 | 
						|
      NewModeBuffer[ValidCount].Columns       = ModeBuffer[Index].Columns;
 | 
						|
      NewModeBuffer[ValidCount].Rows          = ModeBuffer[Index].Rows;
 | 
						|
      NewModeBuffer[ValidCount].GopWidth      = HorizontalResolution;
 | 
						|
      NewModeBuffer[ValidCount].GopHeight     = VerticalResolution;
 | 
						|
      NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;
 | 
						|
      NewModeBuffer[ValidCount].DeltaX        = (HorizontalResolution - (NewModeBuffer[ValidCount].Columns * EFI_GLYPH_WIDTH)) >> 1;
 | 
						|
      NewModeBuffer[ValidCount].DeltaY        = (VerticalResolution - (NewModeBuffer[ValidCount].Rows * EFI_GLYPH_HEIGHT)) >> 1;
 | 
						|
      ValidCount++;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  DEBUG_CODE_BEGIN ();
 | 
						|
  for (Index = 0; Index < ValidCount; Index++) {
 | 
						|
    DEBUG ((
 | 
						|
      DEBUG_INFO,
 | 
						|
      "Graphics - Mode %d, Column = %d, Row = %d\n",
 | 
						|
      Index,
 | 
						|
      NewModeBuffer[Index].Columns,
 | 
						|
      NewModeBuffer[Index].Rows
 | 
						|
      ));
 | 
						|
  }
 | 
						|
 | 
						|
  DEBUG_CODE_END ();
 | 
						|
 | 
						|
  //
 | 
						|
  // Return valid mode count and mode information buffer.
 | 
						|
  //
 | 
						|
  *TextModeCount = ValidCount;
 | 
						|
  *TextModeData  = NewModeBuffer;
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Start this driver on Controller by opening Graphics Output protocol or
 | 
						|
  UGA Draw protocol, and installing Simple Text Out protocol on Controller.
 | 
						|
  (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
 | 
						|
 | 
						|
  @param  This                 Protocol instance pointer.
 | 
						|
  @param  Controller           Handle of device to bind driver to
 | 
						|
  @param  RemainingDevicePath  Optional parameter use to pick a specific child
 | 
						|
                               device to start.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS          This driver is added to Controller.
 | 
						|
  @retval other                This driver does not support this device.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GraphicsConsoleControllerDriverStart (
 | 
						|
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | 
						|
  IN EFI_HANDLE                   Controller,
 | 
						|
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                            Status;
 | 
						|
  GRAPHICS_CONSOLE_DEV                  *Private;
 | 
						|
  UINT32                                HorizontalResolution;
 | 
						|
  UINT32                                VerticalResolution;
 | 
						|
  UINT32                                ColorDepth;
 | 
						|
  UINT32                                RefreshRate;
 | 
						|
  UINT32                                ModeIndex;
 | 
						|
  UINTN                                 MaxMode;
 | 
						|
  UINT32                                ModeNumber;
 | 
						|
  EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE     *Mode;
 | 
						|
  UINTN                                 SizeOfInfo;
 | 
						|
  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;
 | 
						|
  INT32                                 PreferMode;
 | 
						|
  INT32                                 Index;
 | 
						|
  UINTN                                 Column;
 | 
						|
  UINTN                                 Row;
 | 
						|
  UINTN                                 DefaultColumn;
 | 
						|
  UINTN                                 DefaultRow;
 | 
						|
 | 
						|
  ModeNumber = 0;
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize the Graphics Console device instance
 | 
						|
  //
 | 
						|
  Private = AllocateCopyPool (
 | 
						|
              sizeof (GRAPHICS_CONSOLE_DEV),
 | 
						|
              &mGraphicsConsoleDevTemplate
 | 
						|
              );
 | 
						|
  if (Private == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  Private->SimpleTextOutput.Mode = &(Private->SimpleTextOutputMode);
 | 
						|
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  Controller,
 | 
						|
                  &gEfiGraphicsOutputProtocolGuid,
 | 
						|
                  (VOID **)&Private->GraphicsOutput,
 | 
						|
                  This->DriverBindingHandle,
 | 
						|
                  Controller,
 | 
						|
                  EFI_OPEN_PROTOCOL_BY_DRIVER
 | 
						|
                  );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
 | 
						|
    Status = gBS->OpenProtocol (
 | 
						|
                    Controller,
 | 
						|
                    &gEfiUgaDrawProtocolGuid,
 | 
						|
                    (VOID **)&Private->UgaDraw,
 | 
						|
                    This->DriverBindingHandle,
 | 
						|
                    Controller,
 | 
						|
                    EFI_OPEN_PROTOCOL_BY_DRIVER
 | 
						|
                    );
 | 
						|
  }
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    goto Error;
 | 
						|
  }
 | 
						|
 | 
						|
  HorizontalResolution = PcdGet32 (PcdVideoHorizontalResolution);
 | 
						|
  VerticalResolution   = PcdGet32 (PcdVideoVerticalResolution);
 | 
						|
 | 
						|
  if (Private->GraphicsOutput != NULL) {
 | 
						|
    //
 | 
						|
    // The console is build on top of Graphics Output Protocol, find the mode number
 | 
						|
    // for the user-defined mode; if there are multiple video devices,
 | 
						|
    // graphic console driver will set all the video devices to the same mode.
 | 
						|
    //
 | 
						|
    if ((HorizontalResolution == 0x0) || (VerticalResolution == 0x0)) {
 | 
						|
      //
 | 
						|
      // Find the highest resolution which GOP supports.
 | 
						|
      //
 | 
						|
      MaxMode = Private->GraphicsOutput->Mode->MaxMode;
 | 
						|
 | 
						|
      for (ModeIndex = 0; ModeIndex < MaxMode; ModeIndex++) {
 | 
						|
        Status = Private->GraphicsOutput->QueryMode (
 | 
						|
                                            Private->GraphicsOutput,
 | 
						|
                                            ModeIndex,
 | 
						|
                                            &SizeOfInfo,
 | 
						|
                                            &Info
 | 
						|
                                            );
 | 
						|
        if (!EFI_ERROR (Status)) {
 | 
						|
          if ((Info->HorizontalResolution > HorizontalResolution) ||
 | 
						|
              ((Info->HorizontalResolution == HorizontalResolution) && (Info->VerticalResolution > VerticalResolution)))
 | 
						|
          {
 | 
						|
            HorizontalResolution = Info->HorizontalResolution;
 | 
						|
            VerticalResolution   = Info->VerticalResolution;
 | 
						|
            ModeNumber           = ModeIndex;
 | 
						|
          }
 | 
						|
 | 
						|
          FreePool (Info);
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if ((HorizontalResolution == 0x0) || (VerticalResolution == 0x0)) {
 | 
						|
        Status = EFI_UNSUPPORTED;
 | 
						|
        goto Error;
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // Use user-defined resolution
 | 
						|
      //
 | 
						|
      Status = CheckModeSupported (
 | 
						|
                 Private->GraphicsOutput,
 | 
						|
                 HorizontalResolution,
 | 
						|
                 VerticalResolution,
 | 
						|
                 &ModeNumber
 | 
						|
                 );
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        //
 | 
						|
        // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec
 | 
						|
        //
 | 
						|
        HorizontalResolution = 800;
 | 
						|
        VerticalResolution   = 600;
 | 
						|
        Status               = CheckModeSupported (
 | 
						|
                                 Private->GraphicsOutput,
 | 
						|
                                 HorizontalResolution,
 | 
						|
                                 VerticalResolution,
 | 
						|
                                 &ModeNumber
 | 
						|
                                 );
 | 
						|
        Mode = Private->GraphicsOutput->Mode;
 | 
						|
        if (EFI_ERROR (Status) && (Mode->MaxMode != 0)) {
 | 
						|
          //
 | 
						|
          // If set default mode failed or device doesn't support default mode, then get the current mode information
 | 
						|
          //
 | 
						|
          HorizontalResolution = Mode->Info->HorizontalResolution;
 | 
						|
          VerticalResolution   = Mode->Info->VerticalResolution;
 | 
						|
          ModeNumber           = Mode->Mode;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (EFI_ERROR (Status) || (ModeNumber != Private->GraphicsOutput->Mode->Mode)) {
 | 
						|
      //
 | 
						|
      // Current graphics mode is not set or is not set to the mode which we have found,
 | 
						|
      // set the new graphic mode.
 | 
						|
      //
 | 
						|
      Status = Private->GraphicsOutput->SetMode (Private->GraphicsOutput, ModeNumber);
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        //
 | 
						|
        // The mode set operation failed
 | 
						|
        //
 | 
						|
        goto Error;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
 | 
						|
    //
 | 
						|
    // At first try to set user-defined resolution
 | 
						|
    //
 | 
						|
    ColorDepth  = 32;
 | 
						|
    RefreshRate = 60;
 | 
						|
    Status      = Private->UgaDraw->SetMode (
 | 
						|
                                      Private->UgaDraw,
 | 
						|
                                      HorizontalResolution,
 | 
						|
                                      VerticalResolution,
 | 
						|
                                      ColorDepth,
 | 
						|
                                      RefreshRate
 | 
						|
                                      );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      //
 | 
						|
      // Try to set 800*600 which is required by UEFI/EFI spec
 | 
						|
      //
 | 
						|
      Status = Private->UgaDraw->SetMode (
 | 
						|
                                   Private->UgaDraw,
 | 
						|
                                   800,
 | 
						|
                                   600,
 | 
						|
                                   ColorDepth,
 | 
						|
                                   RefreshRate
 | 
						|
                                   );
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        Status = Private->UgaDraw->GetMode (
 | 
						|
                                     Private->UgaDraw,
 | 
						|
                                     &HorizontalResolution,
 | 
						|
                                     &VerticalResolution,
 | 
						|
                                     &ColorDepth,
 | 
						|
                                     &RefreshRate
 | 
						|
                                     );
 | 
						|
        if (EFI_ERROR (Status)) {
 | 
						|
          goto Error;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  DEBUG ((DEBUG_INFO, "GraphicsConsole video resolution %d x %d\n", HorizontalResolution, VerticalResolution));
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize the mode which GraphicsConsole supports.
 | 
						|
  //
 | 
						|
  Status = InitializeGraphicsConsoleTextMode (
 | 
						|
             HorizontalResolution,
 | 
						|
             VerticalResolution,
 | 
						|
             ModeNumber,
 | 
						|
             &MaxMode,
 | 
						|
             &Private->ModeData
 | 
						|
             );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    goto Error;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Update the maximum number of modes
 | 
						|
  //
 | 
						|
  Private->SimpleTextOutputMode.MaxMode = (INT32)MaxMode;
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize the Mode of graphics console devices
 | 
						|
  //
 | 
						|
  PreferMode    = -1;
 | 
						|
  DefaultColumn = PcdGet32 (PcdConOutColumn);
 | 
						|
  DefaultRow    = PcdGet32 (PcdConOutRow);
 | 
						|
  Column        = 0;
 | 
						|
  Row           = 0;
 | 
						|
  for (Index = 0; Index < (INT32)MaxMode; Index++) {
 | 
						|
    if ((DefaultColumn != 0) && (DefaultRow != 0)) {
 | 
						|
      if ((Private->ModeData[Index].Columns == DefaultColumn) &&
 | 
						|
          (Private->ModeData[Index].Rows == DefaultRow))
 | 
						|
      {
 | 
						|
        PreferMode = Index;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      if ((Private->ModeData[Index].Columns > Column) &&
 | 
						|
          (Private->ModeData[Index].Rows > Row))
 | 
						|
      {
 | 
						|
        Column     = Private->ModeData[Index].Columns;
 | 
						|
        Row        = Private->ModeData[Index].Rows;
 | 
						|
        PreferMode = Index;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Private->SimpleTextOutput.Mode->Mode = (INT32)PreferMode;
 | 
						|
  DEBUG ((DEBUG_INFO, "Graphics Console Started, Mode: %d\n", PreferMode));
 | 
						|
 | 
						|
  //
 | 
						|
  // Install protocol interfaces for the Graphics Console device.
 | 
						|
  //
 | 
						|
  Status = gBS->InstallMultipleProtocolInterfaces (
 | 
						|
                  &Controller,
 | 
						|
                  &gEfiSimpleTextOutProtocolGuid,
 | 
						|
                  &Private->SimpleTextOutput,
 | 
						|
                  NULL
 | 
						|
                  );
 | 
						|
 | 
						|
Error:
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    //
 | 
						|
    // Close the GOP and UGA Draw Protocol
 | 
						|
    //
 | 
						|
    if (Private->GraphicsOutput != NULL) {
 | 
						|
      gBS->CloseProtocol (
 | 
						|
             Controller,
 | 
						|
             &gEfiGraphicsOutputProtocolGuid,
 | 
						|
             This->DriverBindingHandle,
 | 
						|
             Controller
 | 
						|
             );
 | 
						|
    } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
 | 
						|
      gBS->CloseProtocol (
 | 
						|
             Controller,
 | 
						|
             &gEfiUgaDrawProtocolGuid,
 | 
						|
             This->DriverBindingHandle,
 | 
						|
             Controller
 | 
						|
             );
 | 
						|
    }
 | 
						|
 | 
						|
    if (Private->LineBuffer != NULL) {
 | 
						|
      FreePool (Private->LineBuffer);
 | 
						|
    }
 | 
						|
 | 
						|
    if (Private->ModeData != NULL) {
 | 
						|
      FreePool (Private->ModeData);
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Free private data
 | 
						|
    //
 | 
						|
    FreePool (Private);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Stop this driver on Controller by removing Simple Text Out protocol
 | 
						|
  and closing the Graphics Output Protocol or UGA Draw protocol on Controller.
 | 
						|
  (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
 | 
						|
 | 
						|
 | 
						|
  @param  This              Protocol instance pointer.
 | 
						|
  @param  Controller        Handle of device to stop driver on
 | 
						|
  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
 | 
						|
                            children is zero stop the entire bus driver.
 | 
						|
  @param  ChildHandleBuffer List of Child Handles to Stop.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       This driver is removed Controller.
 | 
						|
  @retval EFI_NOT_STARTED   Simple Text Out protocol could not be found the
 | 
						|
                            Controller.
 | 
						|
  @retval other             This driver was not removed from this device.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GraphicsConsoleControllerDriverStop (
 | 
						|
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
 | 
						|
  IN  EFI_HANDLE                   Controller,
 | 
						|
  IN  UINTN                        NumberOfChildren,
 | 
						|
  IN  EFI_HANDLE                   *ChildHandleBuffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                       Status;
 | 
						|
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *SimpleTextOutput;
 | 
						|
  GRAPHICS_CONSOLE_DEV             *Private;
 | 
						|
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  Controller,
 | 
						|
                  &gEfiSimpleTextOutProtocolGuid,
 | 
						|
                  (VOID **)&SimpleTextOutput,
 | 
						|
                  This->DriverBindingHandle,
 | 
						|
                  Controller,
 | 
						|
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_NOT_STARTED;
 | 
						|
  }
 | 
						|
 | 
						|
  Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);
 | 
						|
 | 
						|
  Status = gBS->UninstallProtocolInterface (
 | 
						|
                  Controller,
 | 
						|
                  &gEfiSimpleTextOutProtocolGuid,
 | 
						|
                  &Private->SimpleTextOutput
 | 
						|
                  );
 | 
						|
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    //
 | 
						|
    // Close the GOP or UGA IO Protocol
 | 
						|
    //
 | 
						|
    if (Private->GraphicsOutput != NULL) {
 | 
						|
      gBS->CloseProtocol (
 | 
						|
             Controller,
 | 
						|
             &gEfiGraphicsOutputProtocolGuid,
 | 
						|
             This->DriverBindingHandle,
 | 
						|
             Controller
 | 
						|
             );
 | 
						|
    } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
 | 
						|
      gBS->CloseProtocol (
 | 
						|
             Controller,
 | 
						|
             &gEfiUgaDrawProtocolGuid,
 | 
						|
             This->DriverBindingHandle,
 | 
						|
             Controller
 | 
						|
             );
 | 
						|
    }
 | 
						|
 | 
						|
    if (Private->LineBuffer != NULL) {
 | 
						|
      FreePool (Private->LineBuffer);
 | 
						|
    }
 | 
						|
 | 
						|
    if (Private->ModeData != NULL) {
 | 
						|
      FreePool (Private->ModeData);
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Free our instance data
 | 
						|
    //
 | 
						|
    FreePool (Private);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Check if the current specific mode supported the user defined resolution
 | 
						|
  for the Graphics Console device based on Graphics Output Protocol.
 | 
						|
 | 
						|
  If yes, set the graphic device's current mode to this specific mode.
 | 
						|
 | 
						|
  @param  GraphicsOutput        Graphics Output Protocol instance pointer.
 | 
						|
  @param  HorizontalResolution  User defined horizontal resolution
 | 
						|
  @param  VerticalResolution    User defined vertical resolution.
 | 
						|
  @param  CurrentModeNumber     Current specific mode to be check.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The mode is supported.
 | 
						|
  @retval EFI_UNSUPPORTED   The specific mode is out of range of graphics
 | 
						|
                            device supported.
 | 
						|
  @retval other             The specific mode does not support user defined
 | 
						|
                            resolution or failed to set the current mode to the
 | 
						|
                            specific mode on graphics device.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
CheckModeSupported (
 | 
						|
  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput,
 | 
						|
  IN  UINT32                    HorizontalResolution,
 | 
						|
  IN  UINT32                    VerticalResolution,
 | 
						|
  OUT UINT32                    *CurrentModeNumber
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32                                ModeNumber;
 | 
						|
  EFI_STATUS                            Status;
 | 
						|
  UINTN                                 SizeOfInfo;
 | 
						|
  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;
 | 
						|
  UINT32                                MaxMode;
 | 
						|
 | 
						|
  Status  = EFI_SUCCESS;
 | 
						|
  MaxMode = GraphicsOutput->Mode->MaxMode;
 | 
						|
 | 
						|
  for (ModeNumber = 0; ModeNumber < MaxMode; ModeNumber++) {
 | 
						|
    Status = GraphicsOutput->QueryMode (
 | 
						|
                               GraphicsOutput,
 | 
						|
                               ModeNumber,
 | 
						|
                               &SizeOfInfo,
 | 
						|
                               &Info
 | 
						|
                               );
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      if ((Info->HorizontalResolution == HorizontalResolution) &&
 | 
						|
          (Info->VerticalResolution == VerticalResolution))
 | 
						|
      {
 | 
						|
        if ((GraphicsOutput->Mode->Info->HorizontalResolution == HorizontalResolution) &&
 | 
						|
            (GraphicsOutput->Mode->Info->VerticalResolution == VerticalResolution))
 | 
						|
        {
 | 
						|
          //
 | 
						|
          // If video device has been set to this mode, we do not need to SetMode again
 | 
						|
          //
 | 
						|
          FreePool (Info);
 | 
						|
          break;
 | 
						|
        } else {
 | 
						|
          Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
 | 
						|
          if (!EFI_ERROR (Status)) {
 | 
						|
            FreePool (Info);
 | 
						|
            break;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      FreePool (Info);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (ModeNumber == GraphicsOutput->Mode->MaxMode) {
 | 
						|
    Status = EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  *CurrentModeNumber = ModeNumber;
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Locate HII Database protocol and HII Font protocol.
 | 
						|
 | 
						|
  @retval  EFI_SUCCESS     HII Database protocol and HII Font protocol
 | 
						|
                           are located successfully.
 | 
						|
  @return  other           Failed to locate HII Database protocol or
 | 
						|
                           HII Font protocol.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EfiLocateHiiProtocol (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&mHiiDatabase);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **)&mHiiFont);
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// Body of the STO functions
 | 
						|
//
 | 
						|
 | 
						|
/**
 | 
						|
  Reset the text output device hardware and optionally run diagnostics.
 | 
						|
 | 
						|
  Implements SIMPLE_TEXT_OUTPUT.Reset().
 | 
						|
  If ExtendedVerification is TRUE, then perform dependent Graphics Console
 | 
						|
  device reset, and set display mode to mode 0.
 | 
						|
  If ExtendedVerification is FALSE, only set display mode to mode 0.
 | 
						|
 | 
						|
  @param  This                  Protocol instance pointer.
 | 
						|
  @param  ExtendedVerification  Indicates that the driver may perform a more
 | 
						|
                                exhaustive verification operation of the device
 | 
						|
                                during reset.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS          The text output device was reset.
 | 
						|
  @retval EFI_DEVICE_ERROR     The text output device is not functioning correctly and
 | 
						|
                               could not be reset.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GraphicsConsoleConOutReset (
 | 
						|
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | 
						|
  IN  BOOLEAN                          ExtendedVerification
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  Status = This->SetMode (This, 0);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Write a Unicode string to the output device.
 | 
						|
 | 
						|
  Implements SIMPLE_TEXT_OUTPUT.OutputString().
 | 
						|
  The Unicode string will be converted to Glyphs and will be
 | 
						|
  sent to the Graphics Console.
 | 
						|
 | 
						|
  @param  This                    Protocol instance pointer.
 | 
						|
  @param  WString                 The NULL-terminated Unicode string to be displayed
 | 
						|
                                  on the output device(s). All output devices must
 | 
						|
                                  also support the Unicode drawing defined in this file.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The string was output to the device.
 | 
						|
  @retval EFI_DEVICE_ERROR        The device reported an error while attempting to output
 | 
						|
                                  the text.
 | 
						|
  @retval EFI_UNSUPPORTED         The output device's mode is not currently in a
 | 
						|
                                  defined text mode.
 | 
						|
  @retval EFI_WARN_UNKNOWN_GLYPH  This warning code indicates that some of the
 | 
						|
                                  characters in the Unicode string could not be
 | 
						|
                                  rendered and were skipped.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GraphicsConsoleConOutOutputString (
 | 
						|
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | 
						|
  IN  CHAR16                           *WString
 | 
						|
  )
 | 
						|
{
 | 
						|
  GRAPHICS_CONSOLE_DEV           *Private;
 | 
						|
  EFI_GRAPHICS_OUTPUT_PROTOCOL   *GraphicsOutput;
 | 
						|
  EFI_UGA_DRAW_PROTOCOL          *UgaDraw;
 | 
						|
  INTN                           Mode;
 | 
						|
  UINTN                          MaxColumn;
 | 
						|
  UINTN                          MaxRow;
 | 
						|
  UINTN                          Width;
 | 
						|
  UINTN                          Height;
 | 
						|
  UINTN                          Delta;
 | 
						|
  EFI_STATUS                     Status;
 | 
						|
  BOOLEAN                        Warning;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Foreground;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Background;
 | 
						|
  UINTN                          DeltaX;
 | 
						|
  UINTN                          DeltaY;
 | 
						|
  UINTN                          Count;
 | 
						|
  UINTN                          Index;
 | 
						|
  INT32                          OriginAttribute;
 | 
						|
  EFI_TPL                        OldTpl;
 | 
						|
 | 
						|
  if (This->Mode->Mode == -1) {
 | 
						|
    //
 | 
						|
    // If current mode is not valid, return error.
 | 
						|
    //
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
 | 
						|
  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
 | 
						|
  //
 | 
						|
  // Current mode
 | 
						|
  //
 | 
						|
  Mode           = This->Mode->Mode;
 | 
						|
  Private        = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
 | 
						|
  GraphicsOutput = Private->GraphicsOutput;
 | 
						|
  UgaDraw        = Private->UgaDraw;
 | 
						|
 | 
						|
  MaxColumn = Private->ModeData[Mode].Columns;
 | 
						|
  MaxRow    = Private->ModeData[Mode].Rows;
 | 
						|
  DeltaX    = (UINTN)Private->ModeData[Mode].DeltaX;
 | 
						|
  DeltaY    = (UINTN)Private->ModeData[Mode].DeltaY;
 | 
						|
  Width     = MaxColumn * EFI_GLYPH_WIDTH;
 | 
						|
  Height    = (MaxRow - 1) * EFI_GLYPH_HEIGHT;
 | 
						|
  Delta     = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
 | 
						|
 | 
						|
  //
 | 
						|
  // The Attributes won't change when during the time OutputString is called
 | 
						|
  //
 | 
						|
  GetTextColors (This, &Foreground, &Background);
 | 
						|
 | 
						|
  FlushCursor (This);
 | 
						|
 | 
						|
  Warning = FALSE;
 | 
						|
 | 
						|
  //
 | 
						|
  // Backup attribute
 | 
						|
  //
 | 
						|
  OriginAttribute = This->Mode->Attribute;
 | 
						|
 | 
						|
  while (*WString != L'\0') {
 | 
						|
    if (*WString == CHAR_BACKSPACE) {
 | 
						|
      //
 | 
						|
      // If the cursor is at the left edge of the display, then move the cursor
 | 
						|
      // one row up.
 | 
						|
      //
 | 
						|
      if ((This->Mode->CursorColumn == 0) && (This->Mode->CursorRow > 0)) {
 | 
						|
        This->Mode->CursorRow--;
 | 
						|
        This->Mode->CursorColumn = (INT32)(MaxColumn - 1);
 | 
						|
        This->OutputString (This, SpaceStr);
 | 
						|
        FlushCursor (This);
 | 
						|
        This->Mode->CursorRow--;
 | 
						|
        This->Mode->CursorColumn = (INT32)(MaxColumn - 1);
 | 
						|
      } else if (This->Mode->CursorColumn > 0) {
 | 
						|
        //
 | 
						|
        // If the cursor is not at the left edge of the display, then move the cursor
 | 
						|
        // left one column.
 | 
						|
        //
 | 
						|
        This->Mode->CursorColumn--;
 | 
						|
        This->OutputString (This, SpaceStr);
 | 
						|
        FlushCursor (This);
 | 
						|
        This->Mode->CursorColumn--;
 | 
						|
      }
 | 
						|
 | 
						|
      WString++;
 | 
						|
    } else if (*WString == CHAR_LINEFEED) {
 | 
						|
      //
 | 
						|
      // If the cursor is at the bottom of the display, then scroll the display one
 | 
						|
      // row, and do not update the cursor position. Otherwise, move the cursor
 | 
						|
      // down one row.
 | 
						|
      //
 | 
						|
      if (This->Mode->CursorRow == (INT32)(MaxRow - 1)) {
 | 
						|
        if (GraphicsOutput != NULL) {
 | 
						|
          //
 | 
						|
          // Scroll Screen Up One Row
 | 
						|
          //
 | 
						|
          GraphicsOutput->Blt (
 | 
						|
                            GraphicsOutput,
 | 
						|
                            NULL,
 | 
						|
                            EfiBltVideoToVideo,
 | 
						|
                            DeltaX,
 | 
						|
                            DeltaY + EFI_GLYPH_HEIGHT,
 | 
						|
                            DeltaX,
 | 
						|
                            DeltaY,
 | 
						|
                            Width,
 | 
						|
                            Height,
 | 
						|
                            Delta
 | 
						|
                            );
 | 
						|
 | 
						|
          //
 | 
						|
          // Print Blank Line at last line
 | 
						|
          //
 | 
						|
          GraphicsOutput->Blt (
 | 
						|
                            GraphicsOutput,
 | 
						|
                            &Background,
 | 
						|
                            EfiBltVideoFill,
 | 
						|
                            0,
 | 
						|
                            0,
 | 
						|
                            DeltaX,
 | 
						|
                            DeltaY + Height,
 | 
						|
                            Width,
 | 
						|
                            EFI_GLYPH_HEIGHT,
 | 
						|
                            Delta
 | 
						|
                            );
 | 
						|
        } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
 | 
						|
          //
 | 
						|
          // Scroll Screen Up One Row
 | 
						|
          //
 | 
						|
          UgaDraw->Blt (
 | 
						|
                     UgaDraw,
 | 
						|
                     NULL,
 | 
						|
                     EfiUgaVideoToVideo,
 | 
						|
                     DeltaX,
 | 
						|
                     DeltaY + EFI_GLYPH_HEIGHT,
 | 
						|
                     DeltaX,
 | 
						|
                     DeltaY,
 | 
						|
                     Width,
 | 
						|
                     Height,
 | 
						|
                     Delta
 | 
						|
                     );
 | 
						|
 | 
						|
          //
 | 
						|
          // Print Blank Line at last line
 | 
						|
          //
 | 
						|
          UgaDraw->Blt (
 | 
						|
                     UgaDraw,
 | 
						|
                     (EFI_UGA_PIXEL *)(UINTN)&Background,
 | 
						|
                     EfiUgaVideoFill,
 | 
						|
                     0,
 | 
						|
                     0,
 | 
						|
                     DeltaX,
 | 
						|
                     DeltaY + Height,
 | 
						|
                     Width,
 | 
						|
                     EFI_GLYPH_HEIGHT,
 | 
						|
                     Delta
 | 
						|
                     );
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        This->Mode->CursorRow++;
 | 
						|
      }
 | 
						|
 | 
						|
      WString++;
 | 
						|
    } else if (*WString == CHAR_CARRIAGE_RETURN) {
 | 
						|
      //
 | 
						|
      // Move the cursor to the beginning of the current row.
 | 
						|
      //
 | 
						|
      This->Mode->CursorColumn = 0;
 | 
						|
      WString++;
 | 
						|
    } else if (*WString == WIDE_CHAR) {
 | 
						|
      This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;
 | 
						|
      WString++;
 | 
						|
    } else if (*WString == NARROW_CHAR) {
 | 
						|
      This->Mode->Attribute &= (~(UINT32)EFI_WIDE_ATTRIBUTE);
 | 
						|
      WString++;
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // Print the character at the current cursor position and move the cursor
 | 
						|
      // right one column. If this moves the cursor past the right edge of the
 | 
						|
      // display, then the line should wrap to the beginning of the next line. This
 | 
						|
      // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
 | 
						|
      // bottom of the display, and the line wraps, then the display will be scrolled
 | 
						|
      // one line.
 | 
						|
      // If wide char is going to be displayed, need to display one character at a time
 | 
						|
      // Or, need to know the display length of a certain string.
 | 
						|
      //
 | 
						|
      // Index is used to determine how many character width units (wide = 2, narrow = 1)
 | 
						|
      // Count is used to determine how many characters are used regardless of their attributes
 | 
						|
      //
 | 
						|
      for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {
 | 
						|
        if ((WString[Count] == CHAR_NULL) ||
 | 
						|
            (WString[Count] == CHAR_BACKSPACE) ||
 | 
						|
            (WString[Count] == CHAR_LINEFEED) ||
 | 
						|
            (WString[Count] == CHAR_CARRIAGE_RETURN) ||
 | 
						|
            (WString[Count] == WIDE_CHAR) ||
 | 
						|
            (WString[Count] == NARROW_CHAR))
 | 
						|
        {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
 | 
						|
        //
 | 
						|
        // Is the wide attribute on?
 | 
						|
        //
 | 
						|
        if ((This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) != 0) {
 | 
						|
          //
 | 
						|
          // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
 | 
						|
          //
 | 
						|
          Index++;
 | 
						|
          //
 | 
						|
          // This is the end-case where if we are at column 79 and about to print a wide character
 | 
						|
          // We should prevent this from happening because we will wrap inappropriately.  We should
 | 
						|
          // not print this character until the next line.
 | 
						|
          //
 | 
						|
          if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {
 | 
						|
            Index++;
 | 
						|
            break;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      Status = DrawUnicodeWeightAtCursorN (This, WString, Count);
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        Warning = TRUE;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // At the end of line, output carriage return and line feed
 | 
						|
      //
 | 
						|
      WString                  += Count;
 | 
						|
      This->Mode->CursorColumn += (INT32)Index;
 | 
						|
      if (This->Mode->CursorColumn > (INT32)MaxColumn) {
 | 
						|
        This->Mode->CursorColumn -= 2;
 | 
						|
        This->OutputString (This, SpaceStr);
 | 
						|
      }
 | 
						|
 | 
						|
      if (This->Mode->CursorColumn >= (INT32)MaxColumn) {
 | 
						|
        FlushCursor (This);
 | 
						|
        This->OutputString (This, mCrLfString);
 | 
						|
        FlushCursor (This);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  This->Mode->Attribute = OriginAttribute;
 | 
						|
 | 
						|
  FlushCursor (This);
 | 
						|
 | 
						|
  if (Warning) {
 | 
						|
    Status = EFI_WARN_UNKNOWN_GLYPH;
 | 
						|
  }
 | 
						|
 | 
						|
  gBS->RestoreTPL (OldTpl);
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Verifies that all characters in a Unicode string can be output to the
 | 
						|
  target device.
 | 
						|
 | 
						|
  Implements SIMPLE_TEXT_OUTPUT.TestString().
 | 
						|
  If one of the characters in the *Wstring is neither valid valid Unicode
 | 
						|
  drawing characters, not ASCII code, then this function will return
 | 
						|
  EFI_UNSUPPORTED
 | 
						|
 | 
						|
  @param  This    Protocol instance pointer.
 | 
						|
  @param  WString The NULL-terminated Unicode string to be examined for the output
 | 
						|
                  device(s).
 | 
						|
 | 
						|
  @retval EFI_SUCCESS      The device(s) are capable of rendering the output string.
 | 
						|
  @retval EFI_UNSUPPORTED  Some of the characters in the Unicode string cannot be
 | 
						|
                           rendered by one or more of the output devices mapped
 | 
						|
                           by the EFI handle.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GraphicsConsoleConOutTestString (
 | 
						|
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | 
						|
  IN  CHAR16                           *WString
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  UINT16      Count;
 | 
						|
 | 
						|
  EFI_IMAGE_OUTPUT  *Blt;
 | 
						|
 | 
						|
  Blt   = NULL;
 | 
						|
  Count = 0;
 | 
						|
 | 
						|
  while (WString[Count] != 0) {
 | 
						|
    Status = mHiiFont->GetGlyph (
 | 
						|
                         mHiiFont,
 | 
						|
                         WString[Count],
 | 
						|
                         NULL,
 | 
						|
                         &Blt,
 | 
						|
                         NULL
 | 
						|
                         );
 | 
						|
    if (Blt != NULL) {
 | 
						|
      FreePool (Blt);
 | 
						|
      Blt = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    Count++;
 | 
						|
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return EFI_UNSUPPORTED;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Returns information for an available text mode that the output device(s)
 | 
						|
  supports
 | 
						|
 | 
						|
  Implements SIMPLE_TEXT_OUTPUT.QueryMode().
 | 
						|
  It returnes information for an available text mode that the Graphics Console supports.
 | 
						|
  In this driver,we only support text mode 80x25, which is defined as mode 0.
 | 
						|
 | 
						|
  @param  This                  Protocol instance pointer.
 | 
						|
  @param  ModeNumber            The mode number to return information on.
 | 
						|
  @param  Columns               The returned columns of the requested mode.
 | 
						|
  @param  Rows                  The returned rows of the requested mode.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The requested mode information is returned.
 | 
						|
  @retval EFI_UNSUPPORTED       The mode number is not valid.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GraphicsConsoleConOutQueryMode (
 | 
						|
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | 
						|
  IN  UINTN                            ModeNumber,
 | 
						|
  OUT UINTN                            *Columns,
 | 
						|
  OUT UINTN                            *Rows
 | 
						|
  )
 | 
						|
{
 | 
						|
  GRAPHICS_CONSOLE_DEV  *Private;
 | 
						|
  EFI_STATUS            Status;
 | 
						|
  EFI_TPL               OldTpl;
 | 
						|
 | 
						|
  if (ModeNumber >= (UINTN)This->Mode->MaxMode) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
 | 
						|
  Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
 | 
						|
 | 
						|
  *Columns = Private->ModeData[ModeNumber].Columns;
 | 
						|
  *Rows    = Private->ModeData[ModeNumber].Rows;
 | 
						|
 | 
						|
  if ((*Columns <= 0) || (*Rows <= 0)) {
 | 
						|
    Status = EFI_UNSUPPORTED;
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
Done:
 | 
						|
  gBS->RestoreTPL (OldTpl);
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Sets the output device(s) to a specified mode.
 | 
						|
 | 
						|
  Implements SIMPLE_TEXT_OUTPUT.SetMode().
 | 
						|
  Set the Graphics Console to a specified mode. In this driver, we only support mode 0.
 | 
						|
 | 
						|
  @param  This                  Protocol instance pointer.
 | 
						|
  @param  ModeNumber            The text mode to set.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The requested text mode is set.
 | 
						|
  @retval EFI_DEVICE_ERROR      The requested text mode cannot be set because of
 | 
						|
                                Graphics Console device error.
 | 
						|
  @retval EFI_UNSUPPORTED       The text mode number is not valid.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GraphicsConsoleConOutSetMode (
 | 
						|
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | 
						|
  IN  UINTN                            ModeNumber
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                     Status;
 | 
						|
  GRAPHICS_CONSOLE_DEV           *Private;
 | 
						|
  GRAPHICS_CONSOLE_MODE_DATA     *ModeData;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *NewLineBuffer;
 | 
						|
  UINT32                         HorizontalResolution;
 | 
						|
  UINT32                         VerticalResolution;
 | 
						|
  EFI_GRAPHICS_OUTPUT_PROTOCOL   *GraphicsOutput;
 | 
						|
  EFI_UGA_DRAW_PROTOCOL          *UgaDraw;
 | 
						|
  UINT32                         ColorDepth;
 | 
						|
  UINT32                         RefreshRate;
 | 
						|
  EFI_TPL                        OldTpl;
 | 
						|
 | 
						|
  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
 | 
						|
 | 
						|
  Private        = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
 | 
						|
  GraphicsOutput = Private->GraphicsOutput;
 | 
						|
  UgaDraw        = Private->UgaDraw;
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure the requested mode number is supported
 | 
						|
  //
 | 
						|
  if (ModeNumber >= (UINTN)This->Mode->MaxMode) {
 | 
						|
    Status = EFI_UNSUPPORTED;
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  ModeData = &(Private->ModeData[ModeNumber]);
 | 
						|
 | 
						|
  if ((ModeData->Columns <= 0) && (ModeData->Rows <= 0)) {
 | 
						|
    Status = EFI_UNSUPPORTED;
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // If the mode has been set at least one other time, then LineBuffer will not be NULL
 | 
						|
  //
 | 
						|
  if (Private->LineBuffer != NULL) {
 | 
						|
    //
 | 
						|
    // If the new mode is the same as the old mode, then just return EFI_SUCCESS
 | 
						|
    //
 | 
						|
    if ((INT32)ModeNumber == This->Mode->Mode) {
 | 
						|
      //
 | 
						|
      // Clear the current text window on the current graphics console
 | 
						|
      //
 | 
						|
      This->ClearScreen (This);
 | 
						|
      Status = EFI_SUCCESS;
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,
 | 
						|
    // so erase the cursor, and free the LineBuffer for the current mode
 | 
						|
    //
 | 
						|
    FlushCursor (This);
 | 
						|
 | 
						|
    FreePool (Private->LineBuffer);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Attempt to allocate a line buffer for the requested mode number
 | 
						|
  //
 | 
						|
  NewLineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT);
 | 
						|
 | 
						|
  if (NewLineBuffer == NULL) {
 | 
						|
    //
 | 
						|
    // The new line buffer could not be allocated, so return an error.
 | 
						|
    // No changes to the state of the current console have been made, so the current console is still valid
 | 
						|
    //
 | 
						|
    Status = EFI_OUT_OF_RESOURCES;
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Assign the current line buffer to the newly allocated line buffer
 | 
						|
  //
 | 
						|
  Private->LineBuffer = NewLineBuffer;
 | 
						|
 | 
						|
  if (GraphicsOutput != NULL) {
 | 
						|
    if (ModeData->GopModeNumber != GraphicsOutput->Mode->Mode) {
 | 
						|
      //
 | 
						|
      // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
 | 
						|
      //
 | 
						|
      Status = GraphicsOutput->SetMode (GraphicsOutput, ModeData->GopModeNumber);
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        //
 | 
						|
        // The mode set operation failed
 | 
						|
        //
 | 
						|
        goto Done;
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // The current graphics mode is correct, so simply clear the entire display
 | 
						|
      //
 | 
						|
      Status = GraphicsOutput->Blt (
 | 
						|
                                 GraphicsOutput,
 | 
						|
                                 &mGraphicsEfiColors[0],
 | 
						|
                                 EfiBltVideoFill,
 | 
						|
                                 0,
 | 
						|
                                 0,
 | 
						|
                                 0,
 | 
						|
                                 0,
 | 
						|
                                 ModeData->GopWidth,
 | 
						|
                                 ModeData->GopHeight,
 | 
						|
                                 0
 | 
						|
                                 );
 | 
						|
    }
 | 
						|
  } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
 | 
						|
    //
 | 
						|
    // Get the current UGA Draw mode information
 | 
						|
    //
 | 
						|
    Status = UgaDraw->GetMode (
 | 
						|
                        UgaDraw,
 | 
						|
                        &HorizontalResolution,
 | 
						|
                        &VerticalResolution,
 | 
						|
                        &ColorDepth,
 | 
						|
                        &RefreshRate
 | 
						|
                        );
 | 
						|
    if (EFI_ERROR (Status) || (HorizontalResolution != ModeData->GopWidth) || (VerticalResolution != ModeData->GopHeight)) {
 | 
						|
      //
 | 
						|
      // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
 | 
						|
      //
 | 
						|
      Status = UgaDraw->SetMode (
 | 
						|
                          UgaDraw,
 | 
						|
                          ModeData->GopWidth,
 | 
						|
                          ModeData->GopHeight,
 | 
						|
                          32,
 | 
						|
                          60
 | 
						|
                          );
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        //
 | 
						|
        // The mode set operation failed
 | 
						|
        //
 | 
						|
        goto Done;
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // The current graphics mode is correct, so simply clear the entire display
 | 
						|
      //
 | 
						|
      Status = UgaDraw->Blt (
 | 
						|
                          UgaDraw,
 | 
						|
                          (EFI_UGA_PIXEL *)(UINTN)&mGraphicsEfiColors[0],
 | 
						|
                          EfiUgaVideoFill,
 | 
						|
                          0,
 | 
						|
                          0,
 | 
						|
                          0,
 | 
						|
                          0,
 | 
						|
                          ModeData->GopWidth,
 | 
						|
                          ModeData->GopHeight,
 | 
						|
                          0
 | 
						|
                          );
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // The new mode is valid, so commit the mode change
 | 
						|
  //
 | 
						|
  This->Mode->Mode = (INT32)ModeNumber;
 | 
						|
 | 
						|
  //
 | 
						|
  // Move the text cursor to the upper left hand corner of the display and flush it
 | 
						|
  //
 | 
						|
  This->Mode->CursorColumn = 0;
 | 
						|
  This->Mode->CursorRow    = 0;
 | 
						|
 | 
						|
  FlushCursor (This);
 | 
						|
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
 | 
						|
Done:
 | 
						|
  gBS->RestoreTPL (OldTpl);
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Sets the background and foreground colors for the OutputString () and
 | 
						|
  ClearScreen () functions.
 | 
						|
 | 
						|
  Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
 | 
						|
 | 
						|
  @param  This                  Protocol instance pointer.
 | 
						|
  @param  Attribute             The attribute to set. Bits 0..3 are the foreground
 | 
						|
                                color, and bits 4..6 are the background color.
 | 
						|
                                All other bits are undefined and must be zero.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The requested attribute is set.
 | 
						|
  @retval EFI_DEVICE_ERROR      The requested attribute cannot be set due to Graphics Console port error.
 | 
						|
  @retval EFI_UNSUPPORTED       The attribute requested is not defined.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GraphicsConsoleConOutSetAttribute (
 | 
						|
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | 
						|
  IN  UINTN                            Attribute
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_TPL  OldTpl;
 | 
						|
 | 
						|
  if ((Attribute | 0x7F) != 0x7F) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((INT32)Attribute == This->Mode->Attribute) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
 | 
						|
 | 
						|
  FlushCursor (This);
 | 
						|
 | 
						|
  This->Mode->Attribute = (INT32)Attribute;
 | 
						|
 | 
						|
  FlushCursor (This);
 | 
						|
 | 
						|
  gBS->RestoreTPL (OldTpl);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Clears the output device(s) display to the currently selected background
 | 
						|
  color.
 | 
						|
 | 
						|
  Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
 | 
						|
 | 
						|
  @param  This                  Protocol instance pointer.
 | 
						|
 | 
						|
  @retval  EFI_SUCCESS      The operation completed successfully.
 | 
						|
  @retval  EFI_DEVICE_ERROR The device had an error and could not complete the request.
 | 
						|
  @retval  EFI_UNSUPPORTED  The output device is not in a valid text mode.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GraphicsConsoleConOutClearScreen (
 | 
						|
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                     Status;
 | 
						|
  GRAPHICS_CONSOLE_DEV           *Private;
 | 
						|
  GRAPHICS_CONSOLE_MODE_DATA     *ModeData;
 | 
						|
  EFI_GRAPHICS_OUTPUT_PROTOCOL   *GraphicsOutput;
 | 
						|
  EFI_UGA_DRAW_PROTOCOL          *UgaDraw;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Foreground;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Background;
 | 
						|
  EFI_TPL                        OldTpl;
 | 
						|
 | 
						|
  if (This->Mode->Mode == -1) {
 | 
						|
    //
 | 
						|
    // If current mode is not valid, return error.
 | 
						|
    //
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
 | 
						|
 | 
						|
  Private        = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
 | 
						|
  GraphicsOutput = Private->GraphicsOutput;
 | 
						|
  UgaDraw        = Private->UgaDraw;
 | 
						|
  ModeData       = &(Private->ModeData[This->Mode->Mode]);
 | 
						|
 | 
						|
  GetTextColors (This, &Foreground, &Background);
 | 
						|
  if (GraphicsOutput != NULL) {
 | 
						|
    Status = GraphicsOutput->Blt (
 | 
						|
                               GraphicsOutput,
 | 
						|
                               &Background,
 | 
						|
                               EfiBltVideoFill,
 | 
						|
                               0,
 | 
						|
                               0,
 | 
						|
                               0,
 | 
						|
                               0,
 | 
						|
                               ModeData->GopWidth,
 | 
						|
                               ModeData->GopHeight,
 | 
						|
                               0
 | 
						|
                               );
 | 
						|
  } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
 | 
						|
    Status = UgaDraw->Blt (
 | 
						|
                        UgaDraw,
 | 
						|
                        (EFI_UGA_PIXEL *)(UINTN)&Background,
 | 
						|
                        EfiUgaVideoFill,
 | 
						|
                        0,
 | 
						|
                        0,
 | 
						|
                        0,
 | 
						|
                        0,
 | 
						|
                        ModeData->GopWidth,
 | 
						|
                        ModeData->GopHeight,
 | 
						|
                        0
 | 
						|
                        );
 | 
						|
  } else {
 | 
						|
    Status = EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  This->Mode->CursorColumn = 0;
 | 
						|
  This->Mode->CursorRow    = 0;
 | 
						|
 | 
						|
  FlushCursor (This);
 | 
						|
 | 
						|
  gBS->RestoreTPL (OldTpl);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Sets the current coordinates of the cursor position.
 | 
						|
 | 
						|
  Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
 | 
						|
 | 
						|
  @param  This        Protocol instance pointer.
 | 
						|
  @param  Column      The position to set the cursor to. Must be greater than or
 | 
						|
                      equal to zero and less than the number of columns and rows
 | 
						|
                      by QueryMode ().
 | 
						|
  @param  Row         The position to set the cursor to. Must be greater than or
 | 
						|
                      equal to zero and less than the number of columns and rows
 | 
						|
                      by QueryMode ().
 | 
						|
 | 
						|
  @retval EFI_SUCCESS      The operation completed successfully.
 | 
						|
  @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
 | 
						|
  @retval EFI_UNSUPPORTED  The output device is not in a valid text mode, or the
 | 
						|
                           cursor position is invalid for the current mode.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GraphicsConsoleConOutSetCursorPosition (
 | 
						|
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | 
						|
  IN  UINTN                            Column,
 | 
						|
  IN  UINTN                            Row
 | 
						|
  )
 | 
						|
{
 | 
						|
  GRAPHICS_CONSOLE_DEV        *Private;
 | 
						|
  GRAPHICS_CONSOLE_MODE_DATA  *ModeData;
 | 
						|
  EFI_STATUS                  Status;
 | 
						|
  EFI_TPL                     OldTpl;
 | 
						|
 | 
						|
  if (This->Mode->Mode == -1) {
 | 
						|
    //
 | 
						|
    // If current mode is not valid, return error.
 | 
						|
    //
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
 | 
						|
  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
 | 
						|
 | 
						|
  Private  = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
 | 
						|
  ModeData = &(Private->ModeData[This->Mode->Mode]);
 | 
						|
 | 
						|
  if ((Column >= ModeData->Columns) || (Row >= ModeData->Rows)) {
 | 
						|
    Status = EFI_UNSUPPORTED;
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((This->Mode->CursorColumn == (INT32)Column) && (This->Mode->CursorRow == (INT32)Row)) {
 | 
						|
    Status = EFI_SUCCESS;
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  FlushCursor (This);
 | 
						|
 | 
						|
  This->Mode->CursorColumn = (INT32)Column;
 | 
						|
  This->Mode->CursorRow    = (INT32)Row;
 | 
						|
 | 
						|
  FlushCursor (This);
 | 
						|
 | 
						|
Done:
 | 
						|
  gBS->RestoreTPL (OldTpl);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Makes the cursor visible or invisible.
 | 
						|
 | 
						|
  Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
 | 
						|
 | 
						|
  @param  This                  Protocol instance pointer.
 | 
						|
  @param  Visible               If TRUE, the cursor is set to be visible, If FALSE,
 | 
						|
                                the cursor is set to be invisible.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The operation completed successfully.
 | 
						|
  @retval EFI_UNSUPPORTED       The output device's mode is not currently in a
 | 
						|
                                defined text mode.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GraphicsConsoleConOutEnableCursor (
 | 
						|
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | 
						|
  IN  BOOLEAN                          Visible
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_TPL  OldTpl;
 | 
						|
 | 
						|
  if (This->Mode->Mode == -1) {
 | 
						|
    //
 | 
						|
    // If current mode is not valid, return error.
 | 
						|
    //
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
 | 
						|
 | 
						|
  FlushCursor (This);
 | 
						|
 | 
						|
  This->Mode->CursorVisible = Visible;
 | 
						|
 | 
						|
  FlushCursor (This);
 | 
						|
 | 
						|
  gBS->RestoreTPL (OldTpl);
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Gets Graphics Console device's foreground color and background color.
 | 
						|
 | 
						|
  @param  This                  Protocol instance pointer.
 | 
						|
  @param  Foreground            Returned text foreground color.
 | 
						|
  @param  Background            Returned text background color.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           It returned always.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
GetTextColors (
 | 
						|
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | 
						|
  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *Foreground,
 | 
						|
  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *Background
 | 
						|
  )
 | 
						|
{
 | 
						|
  INTN  Attribute;
 | 
						|
 | 
						|
  Attribute = This->Mode->Attribute & 0x7F;
 | 
						|
 | 
						|
  *Foreground = mGraphicsEfiColors[Attribute & 0x0f];
 | 
						|
  *Background = mGraphicsEfiColors[Attribute >> 4];
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Draw Unicode string on the Graphics Console device's screen.
 | 
						|
 | 
						|
  @param  This                  Protocol instance pointer.
 | 
						|
  @param  UnicodeWeight         One Unicode string to be displayed.
 | 
						|
  @param  Count                 The count of Unicode string.
 | 
						|
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  If no memory resource to use.
 | 
						|
  @retval EFI_UNSUPPORTED       If no Graphics Output protocol and UGA Draw
 | 
						|
                                protocol exist.
 | 
						|
  @retval EFI_SUCCESS           Drawing Unicode string implemented successfully.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
DrawUnicodeWeightAtCursorN (
 | 
						|
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | 
						|
  IN  CHAR16                           *UnicodeWeight,
 | 
						|
  IN  UINTN                            Count
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS             Status;
 | 
						|
  GRAPHICS_CONSOLE_DEV   *Private;
 | 
						|
  EFI_IMAGE_OUTPUT       *Blt;
 | 
						|
  EFI_STRING             String;
 | 
						|
  EFI_FONT_DISPLAY_INFO  *FontInfo;
 | 
						|
  EFI_UGA_DRAW_PROTOCOL  *UgaDraw;
 | 
						|
  EFI_HII_ROW_INFO       *RowInfoArray;
 | 
						|
  UINTN                  RowInfoArraySize;
 | 
						|
 | 
						|
  Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
 | 
						|
  Blt     = (EFI_IMAGE_OUTPUT *)AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
 | 
						|
  if (Blt == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  Blt->Width  = (UINT16)(Private->ModeData[This->Mode->Mode].GopWidth);
 | 
						|
  Blt->Height = (UINT16)(Private->ModeData[This->Mode->Mode].GopHeight);
 | 
						|
 | 
						|
  String = AllocateCopyPool ((Count + 1) * sizeof (CHAR16), UnicodeWeight);
 | 
						|
  if (String == NULL) {
 | 
						|
    FreePool (Blt);
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Set the end character
 | 
						|
  //
 | 
						|
  *(String + Count) = L'\0';
 | 
						|
 | 
						|
  FontInfo = (EFI_FONT_DISPLAY_INFO *)AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));
 | 
						|
  if (FontInfo == NULL) {
 | 
						|
    FreePool (Blt);
 | 
						|
    FreePool (String);
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Get current foreground and background colors.
 | 
						|
  //
 | 
						|
  GetTextColors (This, &FontInfo->ForegroundColor, &FontInfo->BackgroundColor);
 | 
						|
 | 
						|
  if (Private->GraphicsOutput != NULL) {
 | 
						|
    //
 | 
						|
    // If Graphics Output protocol exists, using HII Font protocol to draw.
 | 
						|
    //
 | 
						|
    Blt->Image.Screen = Private->GraphicsOutput;
 | 
						|
 | 
						|
    Status = mHiiFont->StringToImage (
 | 
						|
                         mHiiFont,
 | 
						|
                         EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN | EFI_HII_IGNORE_LINE_BREAK,
 | 
						|
                         String,
 | 
						|
                         FontInfo,
 | 
						|
                         &Blt,
 | 
						|
                         This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
 | 
						|
                         This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
 | 
						|
                         NULL,
 | 
						|
                         NULL,
 | 
						|
                         NULL
 | 
						|
                         );
 | 
						|
  } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
 | 
						|
    //
 | 
						|
    // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,
 | 
						|
    // using UGA Draw protocol to draw.
 | 
						|
    //
 | 
						|
    ASSERT (Private->UgaDraw != NULL);
 | 
						|
 | 
						|
    UgaDraw = Private->UgaDraw;
 | 
						|
 | 
						|
    Blt->Image.Bitmap = AllocateZeroPool (Blt->Width * Blt->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
 | 
						|
    if (Blt->Image.Bitmap == NULL) {
 | 
						|
      FreePool (Blt);
 | 
						|
      FreePool (String);
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
 | 
						|
    RowInfoArray = NULL;
 | 
						|
    //
 | 
						|
    //  StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,
 | 
						|
    //  we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.
 | 
						|
    //
 | 
						|
    Status = mHiiFont->StringToImage (
 | 
						|
                         mHiiFont,
 | 
						|
                         EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK,
 | 
						|
                         String,
 | 
						|
                         FontInfo,
 | 
						|
                         &Blt,
 | 
						|
                         This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
 | 
						|
                         This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
 | 
						|
                         &RowInfoArray,
 | 
						|
                         &RowInfoArraySize,
 | 
						|
                         NULL
 | 
						|
                         );
 | 
						|
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      //
 | 
						|
      // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will
 | 
						|
      // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.
 | 
						|
      //
 | 
						|
      ASSERT (RowInfoArraySize <= 1);
 | 
						|
 | 
						|
      Status = UgaDraw->Blt (
 | 
						|
                          UgaDraw,
 | 
						|
                          (EFI_UGA_PIXEL *)Blt->Image.Bitmap,
 | 
						|
                          EfiUgaBltBufferToVideo,
 | 
						|
                          This->Mode->CursorColumn * EFI_GLYPH_WIDTH  + Private->ModeData[This->Mode->Mode].DeltaX,
 | 
						|
                          (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
 | 
						|
                          This->Mode->CursorColumn * EFI_GLYPH_WIDTH  + Private->ModeData[This->Mode->Mode].DeltaX,
 | 
						|
                          (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
 | 
						|
                          RowInfoArray[0].LineWidth,
 | 
						|
                          RowInfoArray[0].LineHeight,
 | 
						|
                          Blt->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
 | 
						|
                          );
 | 
						|
    }
 | 
						|
 | 
						|
    FreePool (RowInfoArray);
 | 
						|
    FreePool (Blt->Image.Bitmap);
 | 
						|
  } else {
 | 
						|
    Status = EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Blt != NULL) {
 | 
						|
    FreePool (Blt);
 | 
						|
  }
 | 
						|
 | 
						|
  if (String != NULL) {
 | 
						|
    FreePool (String);
 | 
						|
  }
 | 
						|
 | 
						|
  if (FontInfo != NULL) {
 | 
						|
    FreePool (FontInfo);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Flush the cursor on the screen.
 | 
						|
 | 
						|
  If CursorVisible is FALSE, nothing to do and return directly.
 | 
						|
  If CursorVisible is TRUE,
 | 
						|
     i) If the cursor shows on screen, it will be erased.
 | 
						|
    ii) If the cursor does not show on screen, it will be shown.
 | 
						|
 | 
						|
  @param  This                  Protocol instance pointer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The cursor is erased successfully.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
FlushCursor (
 | 
						|
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This
 | 
						|
  )
 | 
						|
{
 | 
						|
  GRAPHICS_CONSOLE_DEV                 *Private;
 | 
						|
  EFI_SIMPLE_TEXT_OUTPUT_MODE          *CurrentMode;
 | 
						|
  INTN                                 GlyphX;
 | 
						|
  INTN                                 GlyphY;
 | 
						|
  EFI_GRAPHICS_OUTPUT_PROTOCOL         *GraphicsOutput;
 | 
						|
  EFI_UGA_DRAW_PROTOCOL                *UgaDraw;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  Foreground;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  Background;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  BltChar[EFI_GLYPH_HEIGHT][EFI_GLYPH_WIDTH];
 | 
						|
  UINTN                                PosX;
 | 
						|
  UINTN                                PosY;
 | 
						|
 | 
						|
  CurrentMode = This->Mode;
 | 
						|
 | 
						|
  if (!CurrentMode->CursorVisible) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  Private        = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
 | 
						|
  GraphicsOutput = Private->GraphicsOutput;
 | 
						|
  UgaDraw        = Private->UgaDraw;
 | 
						|
 | 
						|
  //
 | 
						|
  // In this driver, only narrow character was supported.
 | 
						|
  //
 | 
						|
  //
 | 
						|
  // Blt a character to the screen
 | 
						|
  //
 | 
						|
  GlyphX = (CurrentMode->CursorColumn * EFI_GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;
 | 
						|
  GlyphY = (CurrentMode->CursorRow * EFI_GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;
 | 
						|
  if (GraphicsOutput != NULL) {
 | 
						|
    GraphicsOutput->Blt (
 | 
						|
                      GraphicsOutput,
 | 
						|
                      (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)BltChar,
 | 
						|
                      EfiBltVideoToBltBuffer,
 | 
						|
                      GlyphX,
 | 
						|
                      GlyphY,
 | 
						|
                      0,
 | 
						|
                      0,
 | 
						|
                      EFI_GLYPH_WIDTH,
 | 
						|
                      EFI_GLYPH_HEIGHT,
 | 
						|
                      EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
 | 
						|
                      );
 | 
						|
  } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
 | 
						|
    UgaDraw->Blt (
 | 
						|
               UgaDraw,
 | 
						|
               (EFI_UGA_PIXEL *)(UINTN)BltChar,
 | 
						|
               EfiUgaVideoToBltBuffer,
 | 
						|
               GlyphX,
 | 
						|
               GlyphY,
 | 
						|
               0,
 | 
						|
               0,
 | 
						|
               EFI_GLYPH_WIDTH,
 | 
						|
               EFI_GLYPH_HEIGHT,
 | 
						|
               EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
 | 
						|
               );
 | 
						|
  }
 | 
						|
 | 
						|
  GetTextColors (This, &Foreground.Pixel, &Background.Pixel);
 | 
						|
 | 
						|
  //
 | 
						|
  // Convert Monochrome bitmap of the Glyph to BltBuffer structure
 | 
						|
  //
 | 
						|
  for (PosY = 0; PosY < EFI_GLYPH_HEIGHT; PosY++) {
 | 
						|
    for (PosX = 0; PosX < EFI_GLYPH_WIDTH; PosX++) {
 | 
						|
      if ((mCursorGlyph.GlyphCol1[PosY] & (BIT0 << PosX)) != 0) {
 | 
						|
        BltChar[PosY][EFI_GLYPH_WIDTH - PosX - 1].Raw ^= Foreground.Raw;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (GraphicsOutput != NULL) {
 | 
						|
    GraphicsOutput->Blt (
 | 
						|
                      GraphicsOutput,
 | 
						|
                      (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)BltChar,
 | 
						|
                      EfiBltBufferToVideo,
 | 
						|
                      0,
 | 
						|
                      0,
 | 
						|
                      GlyphX,
 | 
						|
                      GlyphY,
 | 
						|
                      EFI_GLYPH_WIDTH,
 | 
						|
                      EFI_GLYPH_HEIGHT,
 | 
						|
                      EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
 | 
						|
                      );
 | 
						|
  } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
 | 
						|
    UgaDraw->Blt (
 | 
						|
               UgaDraw,
 | 
						|
               (EFI_UGA_PIXEL *)(UINTN)BltChar,
 | 
						|
               EfiUgaBltBufferToVideo,
 | 
						|
               0,
 | 
						|
               0,
 | 
						|
               GlyphX,
 | 
						|
               GlyphY,
 | 
						|
               EFI_GLYPH_WIDTH,
 | 
						|
               EFI_GLYPH_HEIGHT,
 | 
						|
               EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
 | 
						|
               );
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  HII Database Protocol notification event handler.
 | 
						|
 | 
						|
  Register font package when HII Database Protocol has been installed.
 | 
						|
 | 
						|
  @param[in] Event    Event whose notification function is being invoked.
 | 
						|
  @param[in] Context  Pointer to the notification function's context.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
RegisterFontPackage (
 | 
						|
  IN  EFI_EVENT  Event,
 | 
						|
  IN  VOID       *Context
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                       Status;
 | 
						|
  EFI_HII_SIMPLE_FONT_PACKAGE_HDR  *SimplifiedFont;
 | 
						|
  UINT32                           PackageLength;
 | 
						|
  UINT8                            *Package;
 | 
						|
  UINT8                            *Location;
 | 
						|
  EFI_HII_DATABASE_PROTOCOL        *HiiDatabase;
 | 
						|
 | 
						|
  //
 | 
						|
  // Locate HII Database Protocol
 | 
						|
  //
 | 
						|
  Status = gBS->LocateProtocol (
 | 
						|
                  &gEfiHiiDatabaseProtocolGuid,
 | 
						|
                  NULL,
 | 
						|
                  (VOID **)&HiiDatabase
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Add 4 bytes to the header for entire length for HiiAddPackages use only.
 | 
						|
  //
 | 
						|
  //    +--------------------------------+ <-- Package
 | 
						|
  //    |                                |
 | 
						|
  //    |    PackageLength(4 bytes)      |
 | 
						|
  //    |                                |
 | 
						|
  //    |--------------------------------| <-- SimplifiedFont
 | 
						|
  //    |                                |
 | 
						|
  //    |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
 | 
						|
  //    |                                |
 | 
						|
  //    |--------------------------------| <-- Location
 | 
						|
  //    |                                |
 | 
						|
  //    |     gUsStdNarrowGlyphData      |
 | 
						|
  //    |                                |
 | 
						|
  //    +--------------------------------+
 | 
						|
 | 
						|
  PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + mNarrowFontSize + 4;
 | 
						|
  Package       = AllocateZeroPool (PackageLength);
 | 
						|
  ASSERT (Package != NULL);
 | 
						|
 | 
						|
  WriteUnaligned32 ((UINT32 *)Package, PackageLength);
 | 
						|
  SimplifiedFont                       = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR *)(Package + 4);
 | 
						|
  SimplifiedFont->Header.Length        = (UINT32)(PackageLength - 4);
 | 
						|
  SimplifiedFont->Header.Type          = EFI_HII_PACKAGE_SIMPLE_FONTS;
 | 
						|
  SimplifiedFont->NumberOfNarrowGlyphs = (UINT16)(mNarrowFontSize / sizeof (EFI_NARROW_GLYPH));
 | 
						|
 | 
						|
  Location = (UINT8 *)(&SimplifiedFont->NumberOfWideGlyphs + 1);
 | 
						|
  CopyMem (Location, gUsStdNarrowGlyphData, mNarrowFontSize);
 | 
						|
 | 
						|
  //
 | 
						|
  // Add this simplified font package to a package list then install it.
 | 
						|
  //
 | 
						|
  mHiiHandle = HiiAddPackages (
 | 
						|
                 &mFontPackageListGuid,
 | 
						|
                 NULL,
 | 
						|
                 Package,
 | 
						|
                 NULL
 | 
						|
                 );
 | 
						|
  ASSERT (mHiiHandle != NULL);
 | 
						|
  FreePool (Package);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  The user Entry Point for module GraphicsConsole. The user code starts with this function.
 | 
						|
 | 
						|
  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
 | 
						|
  @param[in] SystemTable    A pointer to the EFI System Table.
 | 
						|
 | 
						|
  @retval  EFI_SUCCESS       The entry point is executed successfully.
 | 
						|
  @return  other             Some error occurs when executing this entry point.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
InitializeGraphicsConsole (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  //
 | 
						|
  // Register notify function on HII Database Protocol to add font package.
 | 
						|
  //
 | 
						|
  EfiCreateProtocolNotifyEvent (
 | 
						|
    &gEfiHiiDatabaseProtocolGuid,
 | 
						|
    TPL_CALLBACK,
 | 
						|
    RegisterFontPackage,
 | 
						|
    NULL,
 | 
						|
    &mHiiRegistration
 | 
						|
    );
 | 
						|
 | 
						|
  //
 | 
						|
  // Install driver model protocol(s).
 | 
						|
  //
 | 
						|
  Status = EfiLibInstallDriverBindingComponentName2 (
 | 
						|
             ImageHandle,
 | 
						|
             SystemTable,
 | 
						|
             &gGraphicsConsoleDriverBinding,
 | 
						|
             ImageHandle,
 | 
						|
             &gGraphicsConsoleComponentName,
 | 
						|
             &gGraphicsConsoleComponentName2
 | 
						|
             );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 |