X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FConsole%2FGraphicsConsoleDxe%2FGraphicsConsole.c;h=037fb5adaa22fe1199593c57e00eac366b49e335;hp=ff4b0c209a0792428ec699a2e0175b86d56694c2;hb=6cb9566f264e2fa2dcde695317945114e1b011c7;hpb=9226efe5ebb83ad0d5882e3eb7a54f3d63f81e9d diff --git a/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c b/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c index ff4b0c209a..037fb5adaa 100644 --- a/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c +++ b/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c @@ -1,58 +1,23 @@ -/**@file +/** @file This is the main routine for initializing the Graphics Console support routines. -Remaining Tasks - Add all standard Glyphs from UEFI 2.0 Specification - Implement optimal automatic Mode creation algorithm - Solve palette issues for mixed graphics and text - When does this protocol reset the palette? - -Copyright (c) 2006 - 2007 Intel Corporation.
-All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "GraphicsConsole.h" +Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php -STATIC -EFI_STATUS -GetTextColors ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground, - OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background - ); +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -STATIC -EFI_STATUS -DrawUnicodeWeightAtCursorN ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN CHAR16 *UnicodeWeight, - IN UINTN Count - ); - -STATIC -EFI_STATUS -EraseCursor ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - ); +**/ -EFI_STATUS -CheckModeSupported ( - EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput, - IN UINT32 HorizontalResolution, - IN UINT32 VerticalResolution, - OUT UINT32 *CurrentModeNumber - ); +#include "GraphicsConsole.h" // -// Globals +// Graphics Console Device Private Data template // -GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate = { +GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate = { GRAPHICS_CONSOLE_DEV_SIGNATURE, (EFI_GRAPHICS_OUTPUT_PROTOCOL *) NULL, (EFI_UGA_DRAW_PROTOCOL *) NULL, @@ -70,63 +35,64 @@ GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate = { }, { 0, - 0, + -1, EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_BLACK), 0, 0, TRUE }, - { - { 80, 25, 0, 0, 0, 0 }, // Mode 0 - { 80, 50, 0, 0, 0, 0 }, // Mode 1 - { 100,31, 0, 0, 0, 0 }, // Mode 2 - { 0, 0, 0, 0, 0, 0 } // Mode 3 - }, - (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL, - (EFI_HII_HANDLE ) 0 + (GRAPHICS_CONSOLE_MODE_DATA *) NULL, + (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL +}; + +GRAPHICS_CONSOLE_MODE_DATA mGraphicsConsoleModeData[] = { + {100, 31}, + // + // New modes can be added here. + // The last entry is specific for full screen mode. + // + {0, 0} }; -#if (EFI_SPECIFICATION_VERSION >= 0x0002000A) EFI_HII_DATABASE_PROTOCOL *mHiiDatabase; EFI_HII_FONT_PROTOCOL *mHiiFont; -BOOLEAN mFirstAccessFlag = TRUE; +EFI_HII_HANDLE mHiiHandle; +VOID *mHiiRegistration; -STATIC EFI_GUID mFontPackageListGuid = {0xf5f219d3, 0x7006, 0x4648, 0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad}; +EFI_GUID mFontPackageListGuid = {0xf5f219d3, 0x7006, 0x4648, {0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad}}; -#else -EFI_HII_PROTOCOL *mHii; -#endif +CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL }; -static CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL }; - -static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = { +EFI_GRAPHICS_OUTPUT_BLT_PIXEL mGraphicsEfiColors[16] = { // - // B G R + // B G R reserved // {0x00, 0x00, 0x00, 0x00}, // BLACK - {0x98, 0x00, 0x00, 0x00}, // BLUE - {0x00, 0x98, 0x00, 0x00}, // GREEN - {0x98, 0x98, 0x00, 0x00}, // CYAN - {0x00, 0x00, 0x98, 0x00}, // RED + {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}, // LIGHTBLUE - ? - {0x00, 0xff, 0x00, 0x00}, // LIGHTGREEN - ? - {0xff, 0xff, 0x00, 0x00}, // LIGHTCYAN - {0x00, 0x00, 0xff, 0x00}, // LIGHTRED - {0xff, 0x00, 0xff, 0x00}, // LIGHTMAGENTA - {0x00, 0xff, 0xff, 0x00}, // LIGHTBROWN - {0xff, 0xff, 0xff, 0x00} // WHITE + {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 }; -static EFI_NARROW_GLYPH mCursorGlyph = { +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, @@ -136,6 +102,22 @@ EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding = { 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 ( @@ -144,12 +126,13 @@ GraphicsConsoleControllerDriverSupported ( IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { - EFI_STATUS Status; + EFI_STATUS Status; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; - EFI_UGA_DRAW_PROTOCOL *UgaDraw; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_UGA_DRAW_PROTOCOL *UgaDraw; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; - UgaDraw = NULL; + GraphicsOutput = NULL; + UgaDraw = NULL; // // Open the IO Abstraction(s) needed to perform the supported test // @@ -161,9 +144,8 @@ GraphicsConsoleControllerDriverSupported ( Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); - - if (EFI_ERROR (Status)) { - GraphicsOutput = NULL; + + if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) { // // Open Graphics Output Protocol failed, try to open UGA Draw Protocol // @@ -175,9 +157,9 @@ GraphicsConsoleControllerDriverSupported ( Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); - if (EFI_ERROR (Status)) { - return Status; - } + } + if (EFI_ERROR (Status)) { + return Status; } // @@ -220,7 +202,7 @@ Error: This->DriverBindingHandle, Controller ); - } else { + } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { gBS->CloseProtocol ( Controller, &gEfiUgaDrawProtocolGuid, @@ -231,44 +213,184 @@ Error: 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 graphis 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 -EFIAPI -GraphicsConsoleControllerDriverStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +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); - Routine Description: + // + // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec. + // + ValidCount = 0; - Start the controller. + 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++; - Arguments: + 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 ( + for (Index = 0; Index < ValidCount; Index++) { + DEBUG ((EFI_D_INFO, "Graphics - Mode %d, Column = %d, Row = %d\n", + Index, NewModeBuffer[Index].Columns, NewModeBuffer[Index].Rows)); + } + ); + + // + // Return valid mode count and mode information buffer. + // + *TextModeCount = ValidCount; + *TextModeData = NewModeBuffer; + return EFI_SUCCESS; +} - This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - Controller - The handle of the controller to start. - RemainingDevicePath - A pointer to the remaining portion of a devcie path. +/** + 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.) - Returns: + @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. - EFI_SUCCESS - Return successfully. - EFI_OUT_OF_RESOURCES - Out of resources. + @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; - UINTN NarrowFontSize; UINT32 HorizontalResolution; UINT32 VerticalResolution; UINT32 ColorDepth; UINT32 RefreshRate; + UINT32 ModeIndex; UINTN MaxMode; - UINTN Columns; - UINTN Rows; UINT32 ModeNumber; - + EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode; + UINTN SizeOfInfo; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + ModeNumber = 0; // @@ -292,9 +414,8 @@ GraphicsConsoleControllerDriverStart ( Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); - if (EFI_ERROR(Status)) { - Private->GraphicsOutput = NULL; + if (EFI_ERROR(Status) && FeaturePcdGet (PcdUgaConsumeSupport)) { Status = gBS->OpenProtocol ( Controller, &gEfiUgaDrawProtocolGuid, @@ -303,87 +424,93 @@ GraphicsConsoleControllerDriverStart ( Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); - if (EFI_ERROR (Status)) { - goto Error; - } } - NarrowFontSize = ReturnNarrowFontSize (); - -#if 1 - if (mFirstAccessFlag) { - HiiLibAddFontPackageToHiiDatabase (NarrowFontSize, (UINT8 *) UsStdNarrowGlyphData, &mFontPackageListGuid, &(Private->HiiHandle)); - mFirstAccessFlag = FALSE; + if (EFI_ERROR (Status)) { + goto Error; } -#else - FontPack = AllocateZeroPool (sizeof (EFI_HII_FONT_PACK) + NarrowFontSize); - ASSERT (FontPack); - - FontPack->Header.Length = (UINT32) (sizeof (EFI_HII_FONT_PACK) + NarrowFontSize); - FontPack->Header.Type = EFI_HII_FONT; - FontPack->NumberOfNarrowGlyphs = (UINT16) (NarrowFontSize / sizeof (EFI_NARROW_GLYPH)); - - Location = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8)); - CopyMem (Location, UsStdNarrowGlyphData, NarrowFontSize); - // - // Register our Fonts into the global database - // - Package = PreparePackages (1, NULL, FontPack); - mHii->NewPack (mHii, Package, &(Private->HiiHandle)); - FreePool (Package); - - // - // Free the font database - // - FreePool (FontPack); -#endif - // - // If the current mode information can not be retrieved, then attemp to set the default mode - // of 800x600, 32 bit colot, 60 Hz refresh. - // - HorizontalResolution = 800; - VerticalResolution = 600; + HorizontalResolution = PcdGet32 (PcdVideoHorizontalResolution); + VerticalResolution = PcdGet32 (PcdVideoVerticalResolution); if (Private->GraphicsOutput != NULL) { // - // The console is build on top of Graphics Output Protocol, find the mode number + // 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. // - Status = CheckModeSupported ( - Private->GraphicsOutput, - CURRENT_HORIZONTAL_RESOLUTION, - CURRENT_VERTICAL_RESOLUTION, - &ModeNumber - ); - if (!EFI_ERROR(Status)) { + if ((HorizontalResolution == 0x0) || (VerticalResolution == 0x0)) { // - // Update default mode to current mode - // - HorizontalResolution = CURRENT_HORIZONTAL_RESOLUTION; - VerticalResolution = CURRENT_VERTICAL_RESOLUTION; + // 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 { // - // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec + // Use user-defined resolution // Status = CheckModeSupported ( - Private->GraphicsOutput, - 800, - 600, + Private->GraphicsOutput, + HorizontalResolution, + VerticalResolution, &ModeNumber ); + if (EFI_ERROR (Status)) { + // + // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec + // + Status = CheckModeSupported ( + Private->GraphicsOutput, + 800, + 600, + &ModeNumber + ); + Mode = Private->GraphicsOutput->Mode; + if (EFI_ERROR (Status) && Mode->MaxMode != 0) { + // + // Set default mode failed or device don'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->MaxMode)) { + if (ModeNumber != Private->GraphicsOutput->Mode->Mode) { // - // Set default mode failed or device don't support default mode, then get the current mode information + // Current graphics mode is not set or is not set to the mode which we has found, + // set the new graphic mode. // - HorizontalResolution = Private->GraphicsOutput->Mode->Info->HorizontalResolution; - VerticalResolution = Private->GraphicsOutput->Mode->Info->VerticalResolution; - ModeNumber = Private->GraphicsOutput->Mode->Mode; + Status = Private->GraphicsOutput->SetMode (Private->GraphicsOutput, ModeNumber); + if (EFI_ERROR (Status)) { + // + // The mode set operation failed + // + goto Error; + } } - } else { + } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { // // At first try to set user-defined resolution // @@ -391,22 +518,19 @@ GraphicsConsoleControllerDriverStart ( RefreshRate = 60; Status = Private->UgaDraw->SetMode ( Private->UgaDraw, - CURRENT_HORIZONTAL_RESOLUTION, - CURRENT_VERTICAL_RESOLUTION, + HorizontalResolution, + VerticalResolution, ColorDepth, RefreshRate ); - if (!EFI_ERROR (Status)) { - HorizontalResolution = CURRENT_HORIZONTAL_RESOLUTION; - VerticalResolution = CURRENT_VERTICAL_RESOLUTION; - } else { + if (EFI_ERROR (Status)) { // // Try to set 800*600 which is required by UEFI/EFI spec // Status = Private->UgaDraw->SetMode ( Private->UgaDraw, - HorizontalResolution, - VerticalResolution, + 800, + 600, ColorDepth, RefreshRate ); @@ -425,96 +549,37 @@ GraphicsConsoleControllerDriverStart ( } } - // - // Compute the maximum number of text Rows and Columns that this current graphics mode can support - // - Columns = HorizontalResolution / GLYPH_WIDTH; - Rows = VerticalResolution / GLYPH_HEIGHT; - - // - // See if the mode is too small to support the required 80x25 text mode - // - if (Columns < 80 || Rows < 25) { - goto Error; - } - // - // Add Mode #0 that must be 80x25 - // - MaxMode = 0; - Private->ModeData[MaxMode].GopWidth = HorizontalResolution; - Private->ModeData[MaxMode].GopHeight = VerticalResolution; - Private->ModeData[MaxMode].GopModeNumber = ModeNumber; - Private->ModeData[MaxMode].DeltaX = (HorizontalResolution - (80 * GLYPH_WIDTH)) >> 1; - Private->ModeData[MaxMode].DeltaY = (VerticalResolution - (25 * GLYPH_HEIGHT)) >> 1; - MaxMode++; + DEBUG ((EFI_D_INFO, "GraphicsConsole video resolution %d x %d\n", HorizontalResolution, VerticalResolution)); // - // If it is possible to support Mode #1 - 80x50, than add it as an active mode + // Initialize the mode which GraphicsConsole supports. // - if (Rows >= 50) { - Private->ModeData[MaxMode].GopWidth = HorizontalResolution; - Private->ModeData[MaxMode].GopHeight = VerticalResolution; - Private->ModeData[MaxMode].GopModeNumber = ModeNumber; - Private->ModeData[MaxMode].DeltaX = (HorizontalResolution - (80 * GLYPH_WIDTH)) >> 1; - Private->ModeData[MaxMode].DeltaY = (VerticalResolution - (50 * GLYPH_HEIGHT)) >> 1; - MaxMode++; - } + Status = InitializeGraphicsConsoleTextMode ( + HorizontalResolution, + VerticalResolution, + ModeNumber, + &MaxMode, + &Private->ModeData + ); - // - // If it is not to support Mode #1 - 80x50, then skip it - // - if (MaxMode < 2) { - Private->ModeData[MaxMode].Columns = 0; - Private->ModeData[MaxMode].Rows = 0; - Private->ModeData[MaxMode].GopWidth = HorizontalResolution; - Private->ModeData[MaxMode].GopHeight = VerticalResolution; - Private->ModeData[MaxMode].GopModeNumber = ModeNumber; - Private->ModeData[MaxMode].DeltaX = 0; - Private->ModeData[MaxMode].DeltaY = 0; - MaxMode++; - } - - // - // Add Mode #2 that must be 100x31 (graphic mode >= 800x600) - // - if (Columns >= 100 && Rows >= 31) { - Private->ModeData[MaxMode].GopWidth = HorizontalResolution; - Private->ModeData[MaxMode].GopHeight = VerticalResolution; - Private->ModeData[MaxMode].GopModeNumber = ModeNumber; - Private->ModeData[MaxMode].DeltaX = (HorizontalResolution - (100 * GLYPH_WIDTH)) >> 1; - Private->ModeData[MaxMode].DeltaY = (VerticalResolution - (31 * GLYPH_HEIGHT)) >> 1; - MaxMode++; + if (EFI_ERROR (Status)) { + goto Error; } - // - // Add Mode #3 that uses the entire display for user-defined mode - // - if (HorizontalResolution > 800 && VerticalResolution > 600) { - Private->ModeData[MaxMode].Columns = HorizontalResolution/GLYPH_WIDTH; - Private->ModeData[MaxMode].Rows = VerticalResolution/GLYPH_HEIGHT; - Private->ModeData[MaxMode].GopWidth = HorizontalResolution; - Private->ModeData[MaxMode].GopHeight = VerticalResolution; - Private->ModeData[MaxMode].GopModeNumber = ModeNumber; - Private->ModeData[MaxMode].DeltaX = (HorizontalResolution % GLYPH_WIDTH) >> 1; - Private->ModeData[MaxMode].DeltaY = (VerticalResolution % GLYPH_HEIGHT) >> 1; - MaxMode++; - } - // // Update the maximum number of modes // Private->SimpleTextOutputMode.MaxMode = (INT32) MaxMode; - // - // Determine the number of text modes that this protocol can support - // - Status = GraphicsConsoleConOutSetMode (&Private->SimpleTextOutput, 0); - if (EFI_ERROR (Status)) { - goto Error; - } - DEBUG_CODE_BEGIN (); - GraphicsConsoleConOutOutputString (&Private->SimpleTextOutput, (CHAR16 *)L"Graphics Console Started\n\r"); + Status = GraphicsConsoleConOutSetMode (&Private->SimpleTextOutput, 0); + if (EFI_ERROR (Status)) { + goto Error; + } + Status = GraphicsConsoleConOutOutputString (&Private->SimpleTextOutput, (CHAR16 *)L"Graphics Console Started\n\r"); + if (EFI_ERROR (Status)) { + goto Error; + } DEBUG_CODE_END (); // @@ -530,38 +595,59 @@ GraphicsConsoleControllerDriverStart ( Error: if (EFI_ERROR (Status)) { // - // Close the GOP or UGA IO Protocol + // Close the GOP and UGA Draw Protocol // if (Private->GraphicsOutput != NULL) { gBS->CloseProtocol ( - Controller, - &gEfiGraphicsOutputProtocolGuid, - This->DriverBindingHandle, - Controller - ); - } else { + Controller, + &gEfiGraphicsOutputProtocolGuid, + This->DriverBindingHandle, + Controller + ); + } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { gBS->CloseProtocol ( - Controller, - &gEfiUgaDrawProtocolGuid, - This->DriverBindingHandle, - Controller - ); + Controller, + &gEfiUgaDrawProtocolGuid, + This->DriverBindingHandle, + Controller + ); + } + + if (Private->LineBuffer != NULL) { + FreePool (Private->LineBuffer); + } + + if (Private->ModeData != NULL) { + FreePool (Private->ModeData); } // // Free private data // - if (Private != NULL) { - if (Private->LineBuffer != NULL) { - FreePool (Private->LineBuffer); - } - FreePool (Private); - } + 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 ( @@ -606,7 +692,7 @@ GraphicsConsoleControllerDriverStop ( This->DriverBindingHandle, Controller ); - } else { + } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { gBS->CloseProtocol ( Controller, &gEfiUgaDrawProtocolGuid, @@ -615,44 +701,60 @@ GraphicsConsoleControllerDriverStop ( ); } - // - // Remove the font pack - // -#if 1 - HiiLibRemovePackages (Private->HiiHandle); - mFirstAccessFlag = TRUE; -#else - mHii->RemovePack (mHii, Private->HiiHandle); -#endif + if (Private->LineBuffer != NULL) { + FreePool (Private->LineBuffer); + } + + if (Private->ModeData != NULL) { + FreePool (Private->ModeData); + } // // Free our instance data // - if (Private != NULL) { - FreePool (Private->LineBuffer); - FreePool (Private); - } + 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 devcice'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 + IN UINT32 HorizontalResolution, + IN UINT32 VerticalResolution, + OUT UINT32 *CurrentModeNumber ) { UINT32 ModeNumber; EFI_STATUS Status; - UINTN SizeOfInfo; + UINTN SizeOfInfo; EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; - - Status = EFI_SUCCESS; - - for (ModeNumber = 0; ModeNumber < GraphicsOutput->Mode->MaxMode; ModeNumber++) { + UINT32 MaxMode; + + Status = EFI_SUCCESS; + MaxMode = GraphicsOutput->Mode->MaxMode; + + for (ModeNumber = 0; ModeNumber < MaxMode; ModeNumber++) { Status = GraphicsOutput->QueryMode ( GraphicsOutput, ModeNumber, @@ -662,179 +764,126 @@ CheckModeSupported ( if (!EFI_ERROR (Status)) { if ((Info->HorizontalResolution == HorizontalResolution) && (Info->VerticalResolution == VerticalResolution)) { - Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber); - if (!EFI_ERROR (Status)) { - gBS->FreePool (Info); + 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; + } } } - gBS->FreePool (Info); + FreePool (Info); } } - + if (ModeNumber == GraphicsOutput->Mode->MaxMode) { Status = EFI_UNSUPPORTED; } - + *CurrentModeNumber = ModeNumber; - return Status; + 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 ) -/*++ - - Routine Description: - Locate HII protocols for future usage. - - Arguments: - - Returns: - ---*/ { - EFI_HANDLE Handle; - UINTN Size; EFI_STATUS Status; -#if (EFI_SPECIFICATION_VERSION >= 0x0002000A) - - // - // There should only be one - so buffer size is this - // - Size = sizeof (EFI_HANDLE); - - Status = gBS->LocateHandle ( - ByProtocol, - &gEfiHiiDatabaseProtocolGuid, - NULL, - &Size, - (VOID **) &Handle - ); - + Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &mHiiDatabase); if (EFI_ERROR (Status)) { return Status; } - Status = gBS->HandleProtocol ( - Handle, - &gEfiHiiDatabaseProtocolGuid, - (VOID **) &mHiiDatabase - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = gBS->HandleProtocol ( - Handle, - &gEfiHiiFontProtocolGuid, - (VOID **) &mHiiFont - ); + Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **) &mHiiFont); return Status; -#else +} - // - // There should only be one - so buffer size is this - // - Size = sizeof (EFI_HANDLE); +// +// Body of the STO functions +// - Status = gBS->LocateHandle ( - ByProtocol, - &gEfiHiiProtocolGuid, - NULL, - &Size, - &Handle - ); +/** + Reset the text output device hardware and optionally run diagnostics. - if (EFI_ERROR (Status)) { - return Status; - } + Implements SIMPLE_TEXT_OUTPUT.Reset(). + If ExtendeVerification 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. - Status = gBS->HandleProtocol ( - Handle, - &gEfiHiiProtocolGuid, - &mHii - ); + @param This Protocol instance pointer. + @param ExtendedVerification Indicates that the driver may perform a more + exhaustive verification operation of the device + during reset. - return Status; -#endif -} + @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. -// -// Body of the STO functions -// +**/ EFI_STATUS EFIAPI GraphicsConsoleConOutReset ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN BOOLEAN ExtendedVerification ) -/*++ - Routine Description: - - Implements SIMPLE_TEXT_OUTPUT.Reset(). - If ExtendeVerification 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. - - Arguments: - - This - Indicates the calling context. - - ExtendedVerification - Indicates that the driver may perform a more exhaustive - verification operation of the device during reset. - - Returns: - - EFI_SUCCESS - The reset operation succeeds. - - EFI_DEVICE_ERROR - The Graphics Console is not functioning correctly - ---*/ { - This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK)); - return This->SetMode (This, 0); + 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 ) -/*++ - Routine Description: - - Implements SIMPLE_TEXT_OUTPUT.OutputString(). - The Unicode string will be converted to Glyphs and will be - sent to the Graphics Console. - - - Arguments: - - This - Indicates the calling context. - - WString - The Null-terminated Unicode string to be displayed on - the Graphics Console. - - Returns: - - EFI_SUCCESS - The string is output successfully. - - EFI_DEVICE_ERROR - The Graphics Console failed to send the string out. - - EFI_WARN_UNKNOWN_GLYPH - Indicates that some of the characters in the Unicode string could not - be rendered and are skipped. - ---*/ { GRAPHICS_CONSOLE_DEV *Private; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; @@ -855,10 +904,16 @@ GraphicsConsoleConOutOutputString ( UINTN Index; INT32 OriginAttribute; EFI_TPL OldTpl; - CHAR16 SpaceStr[] = { NARROW_CHAR, ' ', 0 }; - Status = EFI_SUCCESS; + 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 @@ -870,10 +925,10 @@ GraphicsConsoleConOutOutputString ( MaxColumn = Private->ModeData[Mode].Columns; MaxRow = Private->ModeData[Mode].Rows; - DeltaX = Private->ModeData[Mode].DeltaX; - DeltaY = Private->ModeData[Mode].DeltaY; - Width = MaxColumn * GLYPH_WIDTH; - Height = (MaxRow - 1) * GLYPH_HEIGHT; + 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); // @@ -881,7 +936,7 @@ GraphicsConsoleConOutOutputString ( // GetTextColors (This, &Foreground, &Background); - EraseCursor (This); + FlushCursor (This); Warning = FALSE; @@ -890,7 +945,7 @@ GraphicsConsoleConOutOutputString ( // OriginAttribute = This->Mode->Attribute; - while (*WString) { + while (*WString != L'\0') { if (*WString == CHAR_BACKSPACE) { // @@ -901,7 +956,7 @@ GraphicsConsoleConOutOutputString ( This->Mode->CursorRow--; This->Mode->CursorColumn = (INT32) (MaxColumn - 1); This->OutputString (This, SpaceStr); - EraseCursor (This); + FlushCursor (This); This->Mode->CursorRow--; This->Mode->CursorColumn = (INT32) (MaxColumn - 1); } else if (This->Mode->CursorColumn > 0) { @@ -911,7 +966,7 @@ GraphicsConsoleConOutOutputString ( // This->Mode->CursorColumn--; This->OutputString (This, SpaceStr); - EraseCursor (This); + FlushCursor (This); This->Mode->CursorColumn--; } @@ -933,7 +988,7 @@ GraphicsConsoleConOutOutputString ( NULL, EfiBltVideoToVideo, DeltaX, - DeltaY + GLYPH_HEIGHT, + DeltaY + EFI_GLYPH_HEIGHT, DeltaX, DeltaY, Width, @@ -953,10 +1008,10 @@ GraphicsConsoleConOutOutputString ( DeltaX, DeltaY + Height, Width, - GLYPH_HEIGHT, + EFI_GLYPH_HEIGHT, Delta ); - } else { + } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { // // Scroll Screen Up One Row // @@ -965,7 +1020,7 @@ GraphicsConsoleConOutOutputString ( NULL, EfiUgaVideoToVideo, DeltaX, - DeltaY + GLYPH_HEIGHT, + DeltaY + EFI_GLYPH_HEIGHT, DeltaX, DeltaY, Width, @@ -985,7 +1040,7 @@ GraphicsConsoleConOutOutputString ( DeltaX, DeltaY + Height, Width, - GLYPH_HEIGHT, + EFI_GLYPH_HEIGHT, Delta ); } @@ -1027,33 +1082,18 @@ GraphicsConsoleConOutOutputString ( // 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) { - break; - } - - if (WString[Count] == CHAR_BACKSPACE) { - break; - } - - if (WString[Count] == CHAR_LINEFEED) { - break; - } - - if (WString[Count] == CHAR_CARRIAGE_RETURN) { - break; - } - - if (WString[Count] == WIDE_CHAR) { - break; - } - - if (WString[Count] == NARROW_CHAR) { + 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) { + 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 // @@ -1085,16 +1125,16 @@ GraphicsConsoleConOutOutputString ( } if (This->Mode->CursorColumn >= (INT32) MaxColumn) { - EraseCursor (This); + FlushCursor (This); This->OutputString (This, mCrLfString); - EraseCursor (This); + FlushCursor (This); } } } This->Mode->Attribute = OriginAttribute; - EraseCursor (This); + FlushCursor (This); if (Warning) { Status = EFI_WARN_UNKNOWN_GLYPH; @@ -1105,53 +1145,41 @@ GraphicsConsoleConOutOutputString ( } +/** + 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 ) -/*++ - Routine Description: - - 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. - - - Arguments: - - This - Indicates the calling context. - - WString - The Null-terminated Unicode string to be tested. - - Returns: - - EFI_SUCCESS - The Graphics Console is capable of rendering the output string. - - EFI_UNSUPPORTED - Some of the characters in the Unicode string cannot be rendered. - ---*/ { EFI_STATUS Status; UINT16 Count; -#if (EFI_SPECIFICATION_VERSION >= 0x0002000A) - EFI_IMAGE_OUTPUT *Blt = NULL; -#else - UINT16 GlyphWidth; - UINT32 GlyphStatus = 0; - GLYPH_UNION *Glyph; -#endif + EFI_IMAGE_OUTPUT *Blt; + Blt = NULL; Count = 0; while (WString[Count] != 0) { -#if (EFI_SPECIFICATION_VERSION >= 0x0002000A) Status = mHiiFont->GetGlyph ( mHiiFont, WString[Count], @@ -1159,19 +1187,12 @@ GraphicsConsoleConOutTestString ( &Blt, NULL ); - SafeFreePool (Blt); - Blt = NULL; + if (Blt != NULL) { + FreePool (Blt); + Blt = NULL; + } Count++; -#else - Status = mHii->GetGlyph ( - mHii, - WString, - &Count, - (UINT8 **) &Glyph, - &GlyphWidth, - &GlyphStatus - ); -#endif + if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } @@ -1180,6 +1201,24 @@ GraphicsConsoleConOutTestString ( 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 ( @@ -1188,53 +1227,24 @@ GraphicsConsoleConOutQueryMode ( OUT UINTN *Columns, OUT UINTN *Rows ) -/*++ - Routine Description: - - 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. - - - Arguments: - - This - Indicates the calling context. - - ModeNumber - The mode number to return information on. - - Columns - The returned columns of the requested mode. - - Rows - The returned rows of the requested mode. - - Returns: - - EFI_SUCCESS - The requested mode information is returned. - - EFI_UNSUPPORTED - The mode number is not valid. - ---*/ { 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) { + if (*Columns <= 0 || *Rows <= 0) { Status = EFI_UNSUPPORTED; goto Done; @@ -1245,37 +1255,28 @@ Done: 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 - ) -/*++ - Routine Description: - - Implements SIMPLE_TEXT_OUTPUT.SetMode(). - Set the Graphics Console to a specified mode. - In this driver, we only support mode 0. - - Arguments: - - This - Indicates the calling context. - - ModeNumber - The text mode to set. - - Returns: - - EFI_SUCCESS - The requested text mode is set. - - EFI_DEVICE_ERROR - The requested text mode cannot be set because of Graphics Console device error. - - EFI_UNSUPPORTED - The text mode number is not valid. - ---*/ + ) { EFI_STATUS Status; GRAPHICS_CONSOLE_DEV *Private; @@ -1294,12 +1295,6 @@ GraphicsConsoleConOutSetMode ( Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This); GraphicsOutput = Private->GraphicsOutput; UgaDraw = Private->UgaDraw; - ModeData = &(Private->ModeData[ModeNumber]); - - if (ModeData->Columns <= 0 && ModeData->Rows <= 0) { - Status = EFI_UNSUPPORTED; - goto Done; - } // // Make sure the requested mode number is supported @@ -1308,38 +1303,26 @@ GraphicsConsoleConOutSetMode ( Status = EFI_UNSUPPORTED; goto Done; } + + ModeData = &(Private->ModeData[ModeNumber]); if (ModeData->Columns <= 0 && ModeData->Rows <= 0) { Status = EFI_UNSUPPORTED; goto Done; } - // - // Attempt to allocate a line buffer for the requested mode number - // - NewLineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * GLYPH_WIDTH * 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; - } // // If the mode has been set at least one other time, then LineBuffer will not be NULL // if (Private->LineBuffer != NULL) { - // - // Clear the current text window on the current graphics console - // - This->ClearScreen (This); - // // If the new mode is the same as the old mode, then just return EFI_SUCCESS // if ((INT32) ModeNumber == This->Mode->Mode) { - FreePool (NewLineBuffer); + // + // Clear the current text window on the current graphics console + // + This->ClearScreen (This); Status = EFI_SUCCESS; goto Done; } @@ -1347,10 +1330,25 @@ GraphicsConsoleConOutSetMode ( // 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 // - EraseCursor (This); + 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 // @@ -1359,7 +1357,7 @@ GraphicsConsoleConOutSetMode ( 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 grapghics 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)) { @@ -1374,7 +1372,7 @@ GraphicsConsoleConOutSetMode ( // Status = GraphicsOutput->Blt ( GraphicsOutput, - &mEfiColors[0], + &mGraphicsEfiColors[0], EfiBltVideoFill, 0, 0, @@ -1385,7 +1383,7 @@ GraphicsConsoleConOutSetMode ( 0 ); } - } else { + } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { // // Get the current UGA Draw mode information // @@ -1398,7 +1396,7 @@ GraphicsConsoleConOutSetMode ( ); 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 grapghics mode + // 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, @@ -1419,7 +1417,7 @@ GraphicsConsoleConOutSetMode ( // Status = UgaDraw->Blt ( UgaDraw, - (EFI_UGA_PIXEL *) (UINTN) &mEfiColors[0], + (EFI_UGA_PIXEL *) (UINTN) &mGraphicsEfiColors[0], EfiUgaVideoFill, 0, 0, @@ -1438,9 +1436,12 @@ GraphicsConsoleConOutSetMode ( This->Mode->Mode = (INT32) ModeNumber; // - // Move the text cursor to the upper left hand corner of the displat and enable it + // Move the text cursor to the upper left hand corner of the display and flush it // - This->SetCursorPosition (This, 0, 0); + This->Mode->CursorColumn = 0; + This->Mode->CursorRow = 0; + + FlushCursor (This); Status = EFI_SUCCESS; @@ -1449,40 +1450,40 @@ Done: 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 ) -/*++ - Routine Description: - - Implements SIMPLE_TEXT_OUTPUT.SetAttribute(). - - Arguments: - - This - Indicates the calling context. - - Attrubute - The attribute to set. Only bit0..6 are valid, all other bits - are undefined and must be zero. - - Returns: - - EFI_SUCCESS - The requested attribute is set. - - EFI_DEVICE_ERROR - The requested attribute cannot be set due to Graphics Console port error. - - EFI_UNSUPPORTED - The attribute requested is not defined by EFI spec. - ---*/ { EFI_TPL OldTpl; - - if ((Attribute | 0xFF) != 0xFF) { + + if ((Attribute | 0x7F) != 0x7F) { + return EFI_UNSUPPORTED; + } + + if (This->Mode->Mode == -1) { + // + // If current mode is not valid, return error. + // return EFI_UNSUPPORTED; } @@ -1492,46 +1493,36 @@ GraphicsConsoleConOutSetAttribute ( OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - EraseCursor (This); + FlushCursor (This); This->Mode->Attribute = (INT32) Attribute; - EraseCursor (This); + 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 ) -/*++ - Routine Description: - - Implements SIMPLE_TEXT_OUTPUT.ClearScreen(). - It clears the Graphics Console's display to the - currently selected background color. - - - Arguments: - - This - Indicates the calling context. - - Returns: - - EFI_SUCCESS - The operation completed successfully. - - EFI_DEVICE_ERROR - The Graphics Console cannot be cleared due to Graphics Console device error. - - EFI_UNSUPPORTED - The Graphics Console is not in a valid text mode. - ---*/ { EFI_STATUS Status; GRAPHICS_CONSOLE_DEV *Private; @@ -1541,6 +1532,13 @@ GraphicsConsoleConOutClearScreen ( 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); @@ -1563,7 +1561,7 @@ GraphicsConsoleConOutClearScreen ( ModeData->GopHeight, 0 ); - } else { + } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { Status = UgaDraw->Blt ( UgaDraw, (EFI_UGA_PIXEL *) (UINTN) &Background, @@ -1576,18 +1574,40 @@ GraphicsConsoleConOutClearScreen ( ModeData->GopHeight, 0 ); + } else { + Status = EFI_UNSUPPORTED; } This->Mode->CursorColumn = 0; This->Mode->CursorRow = 0; - EraseCursor (This); + 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 ( @@ -1595,38 +1615,19 @@ GraphicsConsoleConOutSetCursorPosition ( IN UINTN Column, IN UINTN Row ) -/*++ - Routine Description: - - Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition(). - - Arguments: - - This - Indicates the calling context. - - Column - The row to set cursor to. - - Row - The column to set cursor to. - - Returns: - - EFI_SUCCESS - The operation completed successfully. - - EFI_DEVICE_ERROR - The request fails due to Graphics Console device error. - - EFI_UNSUPPORTED - The Graphics Console is not in a valid text mode, or the cursor position - is invalid for current mode. - ---*/ { 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); @@ -1639,17 +1640,17 @@ GraphicsConsoleConOutSetCursorPosition ( goto Done; } - if (((INT32) Column == This->Mode->CursorColumn) && ((INT32) Row == This->Mode->CursorRow)) { + if ((This->Mode->CursorColumn == (INT32) Column) && (This->Mode->CursorRow == (INT32) Row)) { Status = EFI_SUCCESS; goto Done; } - EraseCursor (This); + FlushCursor (This); This->Mode->CursorColumn = (INT32) Column; This->Mode->CursorRow = (INT32) Row; - EraseCursor (This); + FlushCursor (This); Done: gBS->RestoreTPL (OldTpl); @@ -1657,50 +1658,59 @@ Done: 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 ) -/*++ - Routine Description: - - Implements SIMPLE_TEXT_OUTPUT.EnableCursor(). - In this driver, the cursor cannot be hidden. - - Arguments: - - This - Indicates the calling context. - - Visible - If TRUE, the cursor is set to be visible, - If FALSE, the cursor is set to be invisible. - - Returns: - - EFI_SUCCESS - The request is valid. - - EFI_UNSUPPORTED - The Graphics Console does not support a hidden cursor. - ---*/ { EFI_TPL OldTpl; - + + if (This->Mode->Mode == -1) { + // + // If current mode is not valid, return error. + // + return EFI_UNSUPPORTED; + } + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - - EraseCursor (This); + + FlushCursor (This); This->Mode->CursorVisible = Visible; - EraseCursor (This); + FlushCursor (This); gBS->RestoreTPL (OldTpl); return EFI_SUCCESS; } -STATIC +/** + Gets Graphics Console devcie'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, @@ -1712,18 +1722,30 @@ GetTextColors ( Attribute = This->Mode->Attribute & 0x7F; - *Foreground = mEfiColors[Attribute & 0x0f]; - *Background = mEfiColors[Attribute >> 4]; + *Foreground = mGraphicsEfiColors[Attribute & 0x0f]; + *Background = mGraphicsEfiColors[Attribute >> 4]; return EFI_SUCCESS; } -#if (EFI_SPECIFICATION_VERSION >= 0x0002000A) +/** + 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 + IN CHAR16 *UnicodeWeight, + IN UINTN Count ) { EFI_STATUS Status; @@ -1731,13 +1753,11 @@ DrawUnicodeWeightAtCursorN ( 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); - // - // GOP protocol is required in UEFI mode. - // - ASSERT (Private->GraphicsOutput != NULL); - Blt = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT)); if (Blt == NULL) { return EFI_OUT_OF_RESOURCES; @@ -1745,201 +1765,149 @@ DrawUnicodeWeightAtCursorN ( Blt->Width = (UINT16) (Private->ModeData[This->Mode->Mode].GopWidth); Blt->Height = (UINT16) (Private->ModeData[This->Mode->Mode].GopHeight); - Blt->Image.Screen = Private->GraphicsOutput; String = AllocateCopyPool ((Count + 1) * sizeof (CHAR16), UnicodeWeight); if (String == NULL) { - SafeFreePool (Blt); + FreePool (Blt); return EFI_OUT_OF_RESOURCES; } - *(String + Count) = 0; + // + // Set the end character + // + *(String + Count) = L'\0'; FontInfo = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO)); if (FontInfo == NULL) { - SafeFreePool (Blt); - SafeFreePool (String); + FreePool (Blt); + FreePool (String); return EFI_OUT_OF_RESOURCES; } + // + // Get current foreground and background colors. + // GetTextColors (This, &FontInfo->ForegroundColor, &FontInfo->BackgroundColor); - Status = mHiiFont->StringToImage ( - mHiiFont, - EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN, - String, - FontInfo, - &Blt, - This->Mode->CursorColumn * GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX, - This->Mode->CursorRow * GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY, - NULL, - NULL, - NULL - ); - - SafeFreePool (Blt); - SafeFreePool (String); - SafeFreePool (FontInfo); - return Status; -} -#else -STATIC -EFI_STATUS -DrawUnicodeWeightAtCursorN ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN CHAR16 *UnicodeWeight, - IN UINTN Count - ) -{ - GRAPHICS_CONSOLE_DEV *Private; - EFI_STATUS Status; - EFI_STATUS ReturnStatus; - GLYPH_UNION *Glyph; - GLYPH_UNION GlyphData; - INTN GlyphX; - INTN GlyphY; - EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; - EFI_UGA_DRAW_PROTOCOL *UgaDraw; - EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground; - EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background; - UINTN Index; - UINTN ArrayIndex; - UINTN Counts; - UINT16 GlyphWidth; - UINT32 GlyphStatus; - - Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This); + if (Private->GraphicsOutput != NULL) { + // + // If Graphics Output protocol exists, using HII Font protocol to draw. + // + Blt->Image.Screen = Private->GraphicsOutput; - ReturnStatus = EFI_SUCCESS; - GlyphStatus = 0; - GlyphWidth = 0x08; + 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 + ); - GetTextColors (This, &Foreground, &Background); + } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { + // + // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled, + // using UGA Draw protocol to draw. + // + ASSERT (Private->UgaDraw!= NULL); - Index = 0; - ArrayIndex = 0; - while (Index < Count) { - if (This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) { - GlyphStatus = WIDE_CHAR; - } else { - GlyphStatus = NARROW_CHAR; - } + UgaDraw = Private->UgaDraw; - Status = mHii->GetGlyph ( - mHii, - UnicodeWeight, - (UINT16 *) &Index, - (UINT8 **) &Glyph, - &GlyphWidth, - &GlyphStatus - ); - if (EFI_ERROR (Status)) { - ReturnStatus = Status; + 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; } - Counts = 0; - - CopyMem (&GlyphData, Glyph, sizeof (GLYPH_UNION)); + 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 + ); - do { + if (!EFI_ERROR (Status)) { // - // We are creating the second half of the wide character's BLT buffer + // 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. // - if (GlyphWidth == 0x10 && Counts == 1) { - CopyMem (&GlyphData.NarrowGlyph.GlyphCol1, &Glyph->WideGlyph.GlyphCol2, sizeof (Glyph->WideGlyph.GlyphCol2)); - } - - Counts++; - - if (GlyphWidth == 0x10) { - mHii->GlyphToBlt ( - mHii, - (UINT8 *) &GlyphData, - Foreground, - Background, - Count * 2, - GLYPH_WIDTH, - GLYPH_HEIGHT, - &Private->LineBuffer[ArrayIndex * GLYPH_WIDTH] - ); - } else { - mHii->GlyphToBlt ( - mHii, - (UINT8 *) &GlyphData, - Foreground, - Background, - Count, - GLYPH_WIDTH, - GLYPH_HEIGHT, - &Private->LineBuffer[ArrayIndex * GLYPH_WIDTH] - ); - } + ASSERT (RowInfoArraySize <= 1); - ArrayIndex++; + 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) + ); + } - } while (Counts < 2 && GlyphWidth == 0x10); + FreePool (RowInfoArray); + FreePool (Blt->Image.Bitmap); + } else { + Status = EFI_UNSUPPORTED; + } + if (Blt != NULL) { + FreePool (Blt); } - // - // If we are printing Wide characters, treat the BLT as if it is twice as many characters - // - if (GlyphWidth == 0x10) { - Count = Count * 2; + if (String != NULL) { + FreePool (String); } - // - // Blt a character to the screen - // - GlyphX = This->Mode->CursorColumn * GLYPH_WIDTH; - GlyphY = This->Mode->CursorRow * GLYPH_HEIGHT; - GraphicsOutput = Private->GraphicsOutput; - UgaDraw = Private->UgaDraw; - if (GraphicsOutput != NULL) { - GraphicsOutput->Blt ( - GraphicsOutput, - Private->LineBuffer, - EfiBltBufferToVideo, - 0, - 0, - GlyphX + Private->ModeData[This->Mode->Mode].DeltaX, - GlyphY + Private->ModeData[This->Mode->Mode].DeltaY, - GLYPH_WIDTH * Count, - GLYPH_HEIGHT, - GLYPH_WIDTH * Count * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) - ); - } else { - UgaDraw->Blt ( - UgaDraw, - (EFI_UGA_PIXEL *) (UINTN) Private->LineBuffer, - EfiUgaBltBufferToVideo, - 0, - 0, - GlyphX + Private->ModeData[This->Mode->Mode].DeltaX, - GlyphY + Private->ModeData[This->Mode->Mode].DeltaY, - GLYPH_WIDTH * Count, - GLYPH_HEIGHT, - GLYPH_WIDTH * Count * sizeof (EFI_UGA_PIXEL) - ); + if (FontInfo != NULL) { + FreePool (FontInfo); } - - return ReturnStatus; + return Status; } -#endif -STATIC +/** + 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 -EraseCursor ( +FlushCursor ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This ) { - GRAPHICS_CONSOLE_DEV *Private; - EFI_SIMPLE_TEXT_OUTPUT_MODE *CurrentMode; - INTN GlyphX; - INTN GlyphY; + 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_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[GLYPH_HEIGHT][GLYPH_WIDTH]; - UINTN X; - UINTN Y; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar[EFI_GLYPH_HEIGHT][EFI_GLYPH_WIDTH]; + UINTN PosX; + UINTN PosY; CurrentMode = This->Mode; @@ -1952,13 +1920,13 @@ EraseCursor ( UgaDraw = Private->UgaDraw; // - // BUGBUG - we need to think about what to do with wide and narrow character deletions. + // In this driver, only narrow character was supported. // // // Blt a character to the screen // - GlyphX = (CurrentMode->CursorColumn * GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX; - GlyphY = (CurrentMode->CursorRow * GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY; + 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, @@ -1968,11 +1936,11 @@ EraseCursor ( GlyphY, 0, 0, - GLYPH_WIDTH, - GLYPH_HEIGHT, - GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + EFI_GLYPH_WIDTH, + EFI_GLYPH_HEIGHT, + EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) ); - } else { + } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { UgaDraw->Blt ( UgaDraw, (EFI_UGA_PIXEL *) (UINTN) BltChar, @@ -1981,9 +1949,9 @@ EraseCursor ( GlyphY, 0, 0, - GLYPH_WIDTH, - GLYPH_HEIGHT, - GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL) + EFI_GLYPH_WIDTH, + EFI_GLYPH_HEIGHT, + EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL) ); } @@ -1992,10 +1960,10 @@ EraseCursor ( // // Convert Monochrome bitmap of the Glyph to BltBuffer structure // - for (Y = 0; Y < GLYPH_HEIGHT; Y++) { - for (X = 0; X < GLYPH_WIDTH; X++) { - if ((mCursorGlyph.GlyphCol1[Y] & (1 << X)) != 0) { - BltChar[Y][GLYPH_WIDTH - X - 1].Raw ^= Foreground.Raw; + 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; } } } @@ -2009,11 +1977,11 @@ EraseCursor ( 0, GlyphX, GlyphY, - GLYPH_WIDTH, - GLYPH_HEIGHT, - GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + EFI_GLYPH_WIDTH, + EFI_GLYPH_HEIGHT, + EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) ); - } else { + } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { UgaDraw->Blt ( UgaDraw, (EFI_UGA_PIXEL *) (UINTN) BltChar, @@ -2022,23 +1990,100 @@ EraseCursor ( 0, GlyphX, GlyphY, - GLYPH_WIDTH, - GLYPH_HEIGHT, - GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL) + 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] 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. - @retval other Some error occurs when executing this entry point. + + @retval EFI_SUCCESS The entry point is executed successfully. + @return other Some error occurs when executing this entry point. **/ EFI_STATUS @@ -2050,6 +2095,17 @@ InitializeGraphicsConsole ( { 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). // @@ -2063,7 +2119,7 @@ InitializeGraphicsConsole ( ); ASSERT_EFI_ERROR (Status); - return Status; } +