graphicsconsole.c

来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 1,437 行 · 第 1/3 页

C
1,437
字号
/*++

Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.


Module Name:

  GraphicsConsole.c
  
Abstract:

  This is the main routine for initializing the Graphics Console support routines.

Revision History

Remaining Tasks
  Add all standard Glyphs from EFI 1.02 Specification
  Implement optimal automatic Mode creation algorithm
  Solve palette issues for mixed graphics and text
  When does this protocol reset the palette?

--*/

#include "GraphicsConsole.h"

//
// Function Prototypes
//
EFI_STATUS
GraphicsConsoleControllerDriverSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  );

EFI_STATUS
GraphicsConsoleControllerDriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  );

EFI_STATUS
GraphicsConsoleControllerDriverStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN  EFI_HANDLE                     Controller,
  IN  UINTN                          NumberOfChildren,
  IN  EFI_HANDLE                     *ChildHandleBuffer
  );


EFI_STATUS
ConvertUnicodeWeightToGlyph (
  IN  CHAR16        UnicodeWeight,
  OUT NARROW_GLYPH  **Glyph  OPTIONAL
  );

EFI_STATUS
GetTextColors (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,
  OUT EFI_UGA_PIXEL                 *Foreground,
  OUT EFI_UGA_PIXEL                 *Background
  );

EFI_STATUS 
DrawUnicodeWeightAtCursor (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,
  IN  CHAR16                        UnicodeWeight
  );

EFI_STATUS 
DrawUnicodeWeightAtCursorN (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,
  IN  CHAR16                        *UnicodeWeight,
  IN  UINTN                         Count
  );

EFI_STATUS
DrawCursor (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This
  );

EFI_STATUS
EraseCursor (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This
  );

//
// Globals
//
static CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };

static EFI_UGA_PIXEL mEfiColors[16] = {
  0x00, 0x00, 0x00, 0x00,
  0x98, 0x00, 0x00, 0x00,
  0x00, 0x98, 0x00, 0x00,
  0x98, 0x98, 0x00, 0x00,
  0x00, 0x00, 0x98, 0x00,
  0x98, 0x00, 0x98, 0x00,
  0x00, 0x98, 0x98, 0x00,
  0x98, 0x98, 0x98, 0x00,
  0x10, 0x10, 0x10, 0x00,
  0xff, 0x10, 0x10, 0x00,
  0x10, 0xff, 0x10, 0x00,
  0xff, 0xff, 0x10, 0x00,
  0x10, 0x10, 0xff, 0x00,
  0xf0, 0x10, 0xff, 0x00,
  0x10, 0xff, 0xff, 0x00,
  0xff, 0xff, 0xff, 0x00,
};

static NARROW_GLYPH mCursorGlyph = 
{ 0x0000, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF}};

static NARROW_GLYPH mUnknownGlyph = 
{ 0x0000, 0x00, {0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0x00}};

EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding = {
  GraphicsConsoleControllerDriverSupported,
  GraphicsConsoleControllerDriverStart,
  GraphicsConsoleControllerDriverStop,
  0x10,
  NULL,
  NULL
};

//
// Body of the driver
//

EFI_DRIVER_ENTRY_POINT (InitializeGraphicsConsole)

EFI_STATUS
InitializeGraphicsConsole (
  IN  EFI_HANDLE         ImageHandle,
  IN  EFI_SYSTEM_TABLE   *SystemTable
  )
/*++
  Routine Description:
  
    This function is the entry point of Graphics Console driver. It will install a Graphics Console.
  
  Arguments:
  
    EFI_HANDLE        IN    ImageHandle
         A handle for the image that is initializing this driver.
         
    EFI_SYSTEM_TABLE  IN    *SystemTable
        A pointer to the EFI system table.
        
  Returns:
  
    EFI_SUCCESS
       only returns this status code.

--*/
{
  return EfiLibInstallAllDriverProtocols (
          ImageHandle, 
          SystemTable, 
          &gGraphicsConsoleDriverBinding, 
          ImageHandle,
          &gGraphicsConsoleComponentName,
          NULL,
          NULL
          );
}

EFI_STATUS
GraphicsConsoleControllerDriverSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )

/*++

  Routine Description:

  Arguments:

  Returns:

--*/

{
  EFI_STATUS            Status;
  EFI_UGA_DRAW_PROTOCOL *UgaDraw;

  //
  // Open the IO Abstraction(s) needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  Controller,       
                  &gEfiDevicePathProtocolGuid,  
                  NULL,
                  This->DriverBindingHandle,   
                  Controller,   
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open the IO Abstraction(s) needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  Controller,       
                  &gEfiUgaDrawProtocolGuid,  
                  (VOID **)&UgaDraw,
                  This->DriverBindingHandle,   
                  Controller,   
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Close the I/O Abstraction(s) used to perform the supported test
  //
  gBS->CloseProtocol (
         Controller,       
         &gEfiUgaDrawProtocolGuid,  
         This->DriverBindingHandle,   
         Controller   
         );

  return Status;
}


EFI_STATUS
GraphicsConsoleControllerDriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )

/*++

  Routine Description:

  Arguments:

  Returns:

--*/

{
  EFI_STATUS                           Status;
  GRAPHICS_CONSOLE_DEV                 *Private;
  EFI_SIMPLE_TEXT_OUT_PROTOCOL         *Sto;
  UINT32                               HorizontalResolution;
  UINT32                               VerticalResolution;
  UINT32                               ColorDepth;
  UINT32                               RefreshRate;
  UINTN                                MaxMode;
  UINTN                                Columns;
  UINTN                                Rows;

  //
  // Initialize the Graphics Console device instance
  //
  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  sizeof (GRAPHICS_CONSOLE_DEV),
                  (VOID **)&Private
                  );
  if (EFI_ERROR (Status)) {
    Private = NULL;
    goto Error;
  }
  EfiZeroMem(Private, sizeof (GRAPHICS_CONSOLE_DEV));

  Private->Signature = GRAPHICS_CONSOLE_DEV_SIGNATURE;
  Private->Handle    = Controller;

  Status = gBS->OpenProtocol (
                  Private->Handle,
                  &gEfiDevicePathProtocolGuid,  
                  NULL,
                  This->DriverBindingHandle,   
                  Controller,   
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->OpenProtocol (
                  Private->Handle,       
                  &gEfiUgaDrawProtocolGuid,  
                  (VOID **)&Private->UgaDraw,
                  This->DriverBindingHandle,   
                  Private->Handle,   
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto Error;
  }


  //
  // Atempt to set the 800x600, 32 bit color, 60 Hz refresh mode
  //
  HorizontalResolution = 800;
  VerticalResolution   = 600;
  ColorDepth           = 32;
  RefreshRate          = 60;
  Status = Private->UgaDraw->SetMode (
                               Private->UgaDraw, 
                               HorizontalResolution, 
                               VerticalResolution, 
                               ColorDepth, 
                               RefreshRate
                               );
  if (EFI_ERROR (Status)) {
    //
    // If the SetMode() fails, then get the current mode information from 
    // the UGA Draw Protocol
    //
    Status = Private->UgaDraw->GetMode (
                                 Private->UgaDraw, 
                                 &HorizontalResolution, 
                                 &VerticalResolution, 
                                 &ColorDepth, 
                                 &RefreshRate
                                 );
    if (EFI_ERROR (Status)) {
      goto Error;
    }
  }

  GraphicsConsoleDrawLogo (Private->UgaDraw);

  //
  // 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].Columns     = 80;
  Private->ModeData[MaxMode].Rows        = 25;
  Private->ModeData[MaxMode].ClearWidth  = HorizontalResolution;
  Private->ModeData[MaxMode].ClearHeight = VerticalResolution;
  Private->ModeData[MaxMode].DeltaX      = (HorizontalResolution - (80 * GLYPH_WIDTH)) >> 1;
  Private->ModeData[MaxMode].DeltaY      = (VerticalResolution - (25 * GLYPH_HEIGHT)) >> 1;
  MaxMode++;

  //
  // If it is possible to support Mode #1 - 80x50, than add it as an active mode
  //
  if (Rows >= 50) {
    Private->ModeData[MaxMode].Columns     = 80;
    Private->ModeData[MaxMode].Rows        = 50;
    Private->ModeData[MaxMode].ClearWidth  = HorizontalResolution;
    Private->ModeData[MaxMode].ClearHeight = VerticalResolution;
    Private->ModeData[MaxMode].DeltaX      = (HorizontalResolution - (80 * GLYPH_WIDTH)) >> 1;
    Private->ModeData[MaxMode].DeltaY      = (VerticalResolution - (50 * GLYPH_HEIGHT)) >> 1;
    MaxMode++;
  }

  //
  // If the graphics mode is 800x600, than add a text mode that uses the entire display
  //
  if (HorizontalResolution == 800 && VerticalResolution == 600) {
    Private->ModeData[MaxMode].Columns     = 800 / GLYPH_WIDTH;
    Private->ModeData[MaxMode].Rows        = 600 / GLYPH_HEIGHT;
    Private->ModeData[MaxMode].ClearWidth  = 800;
    Private->ModeData[MaxMode].ClearHeight = 600;
    Private->ModeData[MaxMode].DeltaX      = (800 % GLYPH_WIDTH) >> 1;
    Private->ModeData[MaxMode].DeltaY      = (600 % GLYPH_HEIGHT) >> 1;
    MaxMode++;
  }

  //
  // Update the maximum number of modes
  //
  Private->SimpleTextOutputMode.MaxMode = (INT32)MaxMode;

  //
  // Simple Text Output Protocol
  //
  Sto = &Private->SimpleTextOutput;
  Sto->Reset             = GraphicsConsoleConOutReset;
  Sto->OutputString      = GraphicsConsoleConOutOutputString;
  Sto->TestString        = GraphicsConsoleConOutTestString;
  Sto->QueryMode         = GraphicsConsoleConOutQueryMode;
  Sto->SetMode           = GraphicsConsoleConOutSetMode;
  Sto->SetAttribute      = GraphicsConsoleConOutSetAttribute;
  Sto->ClearScreen       = GraphicsConsoleConOutClearScreen;
  Sto->SetCursorPosition = GraphicsConsoleConOutSetCursorPosition; 
  Sto->EnableCursor      = GraphicsConsoleConOutEnableCursor;
  Sto->Mode              = &Private->SimpleTextOutputMode;

  Private->SimpleTextOutputMode.Mode          = 0;
  Private->SimpleTextOutputMode.Attribute     = EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK);
  Private->SimpleTextOutputMode.CursorColumn  = 0;
  Private->SimpleTextOutputMode.CursorRow     = 0;
  Private->SimpleTextOutputMode.CursorVisible = TRUE;

  Status = Private->SimpleTextOutput.Reset (&Private->SimpleTextOutput, FALSE);
  if (EFI_ERROR (Status)) {   
    goto Error;
  }

  Status = Private->SimpleTextOutput.OutputString (&Private->SimpleTextOutput, L"Graphics Console Started\n\r");

  //
  // Install protocol interfaces for the Graphics Console device.
  //
  Status = gBS->InstallProtocolInterface (
                  &Private->Handle,            
                  &gEfiSimpleTextOutProtocolGuid,   
                  EFI_NATIVE_INTERFACE,
                  &Private->SimpleTextOutput
                  );

Error:
  if (EFI_ERROR (Status)) {

    //
    // Close the UGA IO Protocol
    //
    gBS->CloseProtocol (
           Private->Handle,       
           &gEfiUgaDrawProtocolGuid, 
           This->DriverBindingHandle, 
           Private->Handle       
           );

    //
    // Free private data
    //
    if (Private != NULL) {
      gBS->FreePool (Private);
    }
  }
  return Status;
}

EFI_STATUS
GraphicsConsoleControllerDriverStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
  IN  EFI_HANDLE                    Controller,
  IN  UINTN                         NumberOfChildren,
  IN  EFI_HANDLE                    *ChildHandleBuffer
  )

/*++

  Routine Description:

  Arguments:

  Returns:

--*/

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?