graphicsconsole.c

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

C
1,437
字号
{
  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 (
                 Private->Handle,       
                 &gEfiSimpleTextOutProtocolGuid,   
                 &Private->SimpleTextOutput
                 );
  if (!EFI_ERROR (Status)) {
    //
    // Close the UGA IO Protocol
    //
    gBS->CloseProtocol (
           Private->Handle,       
           &gEfiUgaDrawProtocolGuid, 
           This->DriverBindingHandle, 
           Private->Handle       
           );

    //
    // Free our instance data
    //
    if (Private != NULL) {
      gBS->FreePool (Private);
    }
  }
  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:
  
    SIMPLE_TEXT_OUTPUT_PROTOCOL  IN    *This
        Indicates the calling context.
    
    BOOLEAN             IN    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 
                
--*/  
{
  //
  //reset the background and keep the foreground unchanged
  //
  This->SetAttribute(This,This->Mode->Attribute & 0xf);
  
  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:
  
    SIMPLE_TEXT_OUTPUT_PROTOCOL  IN    *This
        Indicates the calling context.
    
    CHAR16                        IN    *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_UGA_DRAW_PROTOCOL                 *UgaDraw;
  UINTN                                 MaxColumn;
  UINTN                                 MaxRow;
  EFI_STATUS                            Status;
  BOOLEAN                               Warning;
  EFI_UGA_PIXEL                         Foreground;
  EFI_UGA_PIXEL                         Background;
  UINTN                                 DeltaX;
  UINTN                                 DeltaY;
  UINTN                                 Count;
  
  Status = This->QueryMode(
                   This, 
                   This->Mode->Mode, 
                   &MaxColumn, 
                   &MaxRow
                   );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS(This);
  UgaDraw = Private->UgaDraw;
  
  DeltaX = Private->ModeData[This->Mode->Mode].DeltaX, 
  DeltaY = Private->ModeData[This->Mode->Mode].DeltaY,  

  EraseCursor (This);

  Warning = FALSE;
  for (;*WString != CHAR_NULL; ) {

    switch (*WString) {

      case CHAR_NULL :
        //
        //Ignore the character, and do not move the cursor.
        //
        WString++;
        break;

      case CHAR_BACKSPACE : 
        //  
        //If the cursor is not at the left edge of the display, then move the cursor
        //left one column.
        //
        if (This->Mode->CursorColumn > 0) {
            This->Mode->CursorColumn--;
        }
        WString++;
        break;
  
      case 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)) {
          //
          // Scroll Screen Up One Row 
          //
          Status = UgaDraw->Blt (
                              UgaDraw, 
                              NULL,
                              EfiUgaVideoToVideo,
                              DeltaX,
                              DeltaY + GLYPH_HEIGHT,
                              DeltaX, 
                              DeltaY,  
                              MaxColumn * GLYPH_WIDTH, 
                              (MaxRow-1) * GLYPH_HEIGHT, 
                              MaxColumn * GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
                              );

          //
          // Print Blank Line at last line
          //
          Status = GetTextColors (This, &Foreground, &Background);
          Status = UgaDraw->Blt (
                              UgaDraw,
                              &Background,
                              EfiUgaVideoFill,
                              0,
                              0,
                              DeltaX, 
                              DeltaY + ((MaxRow - 1) * GLYPH_HEIGHT),
                              MaxColumn * GLYPH_WIDTH, 
                              GLYPH_HEIGHT, 
                              MaxColumn * GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
                              );

        }
        
        if (This->Mode->CursorRow < (INT32)(MaxRow-1)) {
            This->Mode->CursorRow++;
        }
        WString++;
        break;
      
      case CHAR_CARRIAGE_RETURN:
        //
        //Move the cursor to the beginning of the current row.
        //
        This->Mode->CursorColumn = 0;
        WString++;
        break;

      default:
        //  
        //Print the character at the current cursor position and move the cursor
        //right one column. If this moves the cursor past the right edge of the
        //display, then the line should wrap to the beginning of the next line. This
        //is equivalent to inserting a CR and an LF. Note that if the cursor is at the
        //bottom of the display, and the line wraps, then the display will be scrolled
        //one line.
        //
        for (Count = 0; (This->Mode->CursorColumn + Count) <= (MaxColumn - 1); Count++) {
          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;
          }
        }

        Status = DrawUnicodeWeightAtCursorN (This, WString, Count);
        if (EFI_ERROR (Status)) {
          Warning = TRUE;
        }

        //
        // At the end of line, output carriage return and line feed
        //
        This->Mode->CursorColumn += (INT32)Count;
        WString += Count;
        if (This->Mode->CursorColumn > (INT32)(MaxColumn-1)) {
          DrawCursor (This);
          This->OutputString (This, mCrLfString);
          EraseCursor (This);
        } 
        break;
    }
  }
  
  DrawCursor (This);

  if (Warning) {
    return EFI_WARN_UNKNOWN_GLYPH;
  }

  return EFI_SUCCESS;
}

EFI_STATUS 
EFIAPI
GraphicsConsoleConOutTestString (
  IN  EFI_SIMPLE_TEXT_OUT_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:
  
    SIMPLE_TEXT_OUTPUT_PROTOCOL  IN    *This
        Indicates the calling context.
    
    CHAR16                        IN    *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;

  for (;*WString != CHAR_NULL; WString++) {
    Status = ConvertUnicodeWeightToGlyph (*WString, NULL);
    if (EFI_ERROR (Status)) {
      return EFI_UNSUPPORTED;
    }
  }
  return EFI_SUCCESS;
}


EFI_STATUS 
EFIAPI
GraphicsConsoleConOutQueryMode (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,
  IN  UINTN                         ModeNumber,
  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:
  
    SIMPLE_TEXT_OUTPUT_PROTOCOL  IN    *This
        Indicates the calling context.
    
    UINTN                         IN    ModeNumber
        The mode number to return information on.
        
    UINTN                         OUT   *Columns
        The returned columns of the requested mode.
        
    UINTN                         OUT   *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;

  if (ModeNumber >= (UINTN)This->Mode->MaxMode) {
    return EFI_UNSUPPORTED;
  }

  Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS(This);

  *Columns = Private->ModeData[ModeNumber].Columns;
  *Rows    = Private->ModeData[ModeNumber].Rows;

  return EFI_SUCCESS;
}


EFI_STATUS 
EFIAPI
GraphicsConsoleConOutSetMode (
  IN  EFI_SIMPLE_TEXT_OUT_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:
  
    SIMPLE_TEXT_OUTPUT_PROTOCOL  IN    *This
        Indicates the calling context.
    
    UINTN                         IN    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;
  
  Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS(This);

  if (Private->LineBuffer) {
    This->ClearScreen (This);
    This->EnableCursor (This, FALSE);

    gBS->FreePool (Private->LineBuffer);
  }

  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  sizeof(EFI_UGA_PIXEL) * Private->ModeData[ModeNumber].Columns * GLYPH_WIDTH * GLYPH_HEIGHT,
                  (VOID **)&Private->LineBuffer
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
    
  This->Mode->Mode = (INT32) ModeNumber;

  Status = This->SetCursorPosition (This, 0, 0);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = This->EnableCursor (This, TRUE);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}


EFI_STATUS 
EFIAPI
GraphicsConsoleConOutSetAttribute (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,
  IN  UINTN                         Attribute
  )
/*++
  Routine Description:
  
    Implements SIMPLE_TEXT_OUTPUT.SetAttribute().       
  
  Arguments:
  
    SIMPLE_TEXT_OUTPUT_PROTOCOL  IN    *This
        Indicates the calling context.
    

⌨️ 快捷键说明

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