graphicsconsole.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,847 行 · 第 1/4 页

C
1,847
字号
                                );
    if (EFI_ERROR (Status)) {
      //
      // 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;
      }
    }
  }

  //
  // 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++;

  //
  // If it is possible to support Mode #1 - 80x50, than add it as an active mode
  //
  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++;
  }
  //
  // If the graphics mode is 800x600, than add a text mode that uses the entire display
  //
  if (HorizontalResolution == 800 && VerticalResolution == 600) {

    if (MaxMode < 2) {
      Private->ModeData[MaxMode].Columns    = 0;
      Private->ModeData[MaxMode].Rows       = 0;
      Private->ModeData[MaxMode].GopWidth   = 800;
      Private->ModeData[MaxMode].GopHeight  = 600;
      Private->ModeData[MaxMode].GopModeNumber = ModeNumber;
      Private->ModeData[MaxMode].DeltaX     = 0;
      Private->ModeData[MaxMode].DeltaY     = 0;
      MaxMode++;
    }

    Private->ModeData[MaxMode].Columns    = 800 / GLYPH_WIDTH;
    Private->ModeData[MaxMode].Rows       = 600 / GLYPH_HEIGHT;
    Private->ModeData[MaxMode].GopWidth   = 800;
    Private->ModeData[MaxMode].GopHeight  = 600;
    Private->ModeData[MaxMode].GopModeNumber = ModeNumber;
    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;

  //
  // Determine the number of text modes that this protocol can support
  //
  Status = GraphicsConsoleConOutSetMode (&Private->SimpleTextOutput, 0);
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  DEBUG_CODE (
    GraphicsConsoleConOutOutputString (&Private->SimpleTextOutput, L"Graphics Console Started\n\r");
  )
  //
  // Install protocol interfaces for the Graphics Console device.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiSimpleTextOutProtocolGuid,
                  &Private->SimpleTextOutput,
                  NULL
                  );

Error:
  if (EFI_ERROR (Status)) {
    //
    // Close the GOP or UGA IO Protocol
    //
    if (Private->GraphicsOutput != NULL) {
      gBS->CloseProtocol (
            Controller,
            &gEfiGraphicsOutputProtocolGuid,
            This->DriverBindingHandle,
            Controller
            );
    } else {
      gBS->CloseProtocol (
            Controller,
            &gEfiUgaDrawProtocolGuid,
            This->DriverBindingHandle,
            Controller
            );
    }

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

  return Status;
}

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_OUT_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 {
      gBS->CloseProtocol (
            Controller,
            &gEfiUgaDrawProtocolGuid,
            This->DriverBindingHandle,
            Controller
            );
    }

    //
    // Remove the font pack
    //
    mHii->RemovePack (mHii, Private->HiiHandle);

    //
    // Free our instance data
    //
    if (Private != NULL) {
      gBS->FreePool (Private->LineBuffer);
      gBS->FreePool (Private);
    }
  }

  return Status;
}

EFI_STATUS
EfiLocateHiiProtocol (
  VOID
  )
/*++

  Routine Description:
    Find if the HII protocol is available. If yes, locate the HII protocol

  Arguments:

  Returns:

--*/
{
  EFI_HANDLE  Handle;
  UINTN       Size;
  EFI_STATUS  Status;

  //
  // There should only be one - so buffer size is this
  //
  Size = sizeof (EFI_HANDLE);

  Status = gBS->LocateHandle (
                  ByProtocol,
                  &gEfiHiiProtocolGuid,
                  NULL,
                  &Size,
                  &Handle
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->HandleProtocol (
                  Handle,
                  &gEfiHiiProtocolGuid,
                  &mHii
                  );

  return Status;
}
//
// Body of the STO functions
//
EFI_STATUS
EFIAPI
GraphicsConsoleConOutReset (
  IN  EFI_SIMPLE_TEXT_OUT_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
EFIAPI
GraphicsConsoleConOutOutputString (
  IN  EFI_SIMPLE_TEXT_OUT_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;
  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;
  CHAR16                         SpaceStr[] = { NARROW_CHAR, ' ', 0 };

  //
  // 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    = Private->ModeData[Mode].DeltaX;
  DeltaY    = Private->ModeData[Mode].DeltaY;
  Width     = MaxColumn * GLYPH_WIDTH;
  Height    = (MaxRow - 1) * 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);

  EraseCursor (This);

  Warning = FALSE;

  //
  // Backup attribute
  //
  OriginAttribute = This->Mode->Attribute;

  while (*WString) {

    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);
        EraseCursor (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);
        EraseCursor (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 + GLYPH_HEIGHT,
                    DeltaX,
                    DeltaY,
                    Width,
                    Height,
                    Delta
                    );

          //
          // Print Blank Line at last line
          //
          GraphicsOutput->Blt (
                    GraphicsOutput,
                    &Background,
                    EfiBltVideoFill,
                    0,
                    0,
                    DeltaX,
                    DeltaY + Height,
                    Width,
                    GLYPH_HEIGHT,
                    Delta
                    );
        } else {
          //
          // Scroll Screen Up One Row
          //
          UgaDraw->Blt (
                    UgaDraw,
                    NULL,
                    EfiUgaVideoToVideo,
                    DeltaX,
                    DeltaY + GLYPH_HEIGHT,
                    DeltaX,
                    DeltaY,
                    Width,
                    Height,
                    Delta
                    );

          //
          // Print Blank Line at last line
          //
          UgaDraw->Blt (
                    UgaDraw,
                    (EFI_UGA_PIXEL *) &Background,

⌨️ 快捷键说明

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