graphicsconsole.c

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

C
1,437
字号
    UINTN                         IN    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.   
                
--*/      
{
  if ((Attribute | 0x7f) != 0x7f) {
    return EFI_UNSUPPORTED;
  }

  if ((INT32)Attribute == This->Mode->Attribute) {
    return EFI_SUCCESS;
  }

  EraseCursor(This);

  This->Mode->Attribute = (INT32) Attribute; 

  DrawCursor(This);

  return EFI_SUCCESS;
}


EFI_STATUS 
EFIAPI
GraphicsConsoleConOutClearScreen (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This
  )
/*++
  Routine Description:
  
    Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
    It clears the Graphics Console's display to the 
    currently selected background color.
        
  
  Arguments:
  
    SIMPLE_TEXT_OUTPUT_PROTOCOL  IN    *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;
  EFI_UGA_DRAW_PROTOCOL   *UgaDraw;
  UINTN                   MaxColumn;
  UINTN                   MaxRow;
  EFI_UGA_PIXEL           Foreground;
  EFI_UGA_PIXEL           Background;
  UINTN                   DeltaX;
  UINTN                   DeltaY;
   
  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;  

  Status = GetTextColors (This, &Foreground, &Background);
  Status = UgaDraw->Blt (
                      UgaDraw, 
                      &Background,
                      EfiUgaVideoFill,
                      0,
                      0,
                      0,
                      0,
                      Private->ModeData[This->Mode->Mode].ClearWidth, 
                      Private->ModeData[This->Mode->Mode].ClearHeight, 
                      0
                      );

  This->Mode->CursorColumn = 0;
  This->Mode->CursorRow    = 0;
  
  DrawCursor(This);
  
  return Status ;
}


EFI_STATUS 
EFIAPI
GraphicsConsoleConOutSetCursorPosition (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,
  IN  UINTN                         Column,
  IN  UINTN                         Row
  )
/*++
  Routine Description:
  
    Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().          
  
  Arguments:
  
    SIMPLE_TEXT_OUTPUT_PROTOCOL  IN    *This
        Indicates the calling context.
        
    UINTN                         IN    Column
        The row to set cursor to.
        
    UINTN                         IN    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.     
                
--*/        
{
  EFI_STATUS  Status;
  UINTN       MaxColumn;
  UINTN       MaxRow;

  Status = This->QueryMode(
        This, 
        This->Mode->Mode, 
        &MaxColumn, 
        &MaxRow
        );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;          
  }

  if (Column >= MaxColumn || Row >= MaxRow) {
    return EFI_UNSUPPORTED;
  }

  if (((INT32)Column == This->Mode->CursorColumn) && ((INT32)Row == This->Mode->CursorRow)) {
    return EFI_SUCCESS;
  }

  EraseCursor (This);

  This->Mode->CursorColumn = (INT32) Column;
  This->Mode->CursorRow    = (INT32) Row;
  
  DrawCursor (This);

  return EFI_SUCCESS;
}

EFI_STATUS 
EFIAPI
GraphicsConsoleConOutEnableCursor (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,
  IN  BOOLEAN                       Visible
  )
/*++
  Routine Description:
  
    Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
    In this driver, the cursor cannot be hidden.        
  
  Arguments:
  
    SIMPLE_TEXT_OUTPUT_PROTOCOL  IN    *This
        Indicates the calling context.
        
    BOOLEAN                       IN    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.   
                
--*/        
{
  EraseCursor (This);

  This->Mode->CursorVisible = Visible;

  DrawCursor (This);
  
  return EFI_SUCCESS;
}


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

{
  *Foreground = mEfiColors[This->Mode->Attribute & 0x0f];
  *Background = mEfiColors[This->Mode->Attribute >> 4];
  return EFI_SUCCESS;
}



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

{
  UINTN  Index;

  //
  // Search Glyph database for the Unicode Character UnicodeWeight
  //
  for (Index = 0; UsStdGlyphData[Index].UnicodeWeight != UnicodeWeight; Index++) {
    if (UsStdGlyphData[Index].UnicodeWeight == 0x0000) {
      *Glyph = &mUnknownGlyph;
      return EFI_NOT_FOUND;
    }
  }
  if (Glyph != NULL) {
    *Glyph = &UsStdGlyphData[Index];
  }
  return EFI_SUCCESS;
}


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

{
  GRAPHICS_CONSOLE_DEV    *Private;
  EFI_STATUS              Status;
  EFI_STATUS              ReturnStatus;
  NARROW_GLYPH            *Glyph;
  INTN                    GlyphX;
  INTN                    GlyphY;
  EFI_UGA_DRAW_PROTOCOL   *UgaDraw;
  EFI_UGA_PIXEL           Foreground;
  EFI_UGA_PIXEL           Background;
  EFI_UGA_PIXEL           BltChar[GLYPH_HEIGHT][GLYPH_WIDTH];
  UINTN                   X;
  UINTN                   Y;

  Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);

  ReturnStatus = EFI_SUCCESS;
  Status = ConvertUnicodeWeightToGlyph (UnicodeWeight, &Glyph);
  if (EFI_ERROR (Status)) {
    ReturnStatus = Status;
  }

  GetTextColors (This, &Foreground, &Background);

  //
  // Convert Monochrome bitmap of the Glyph to BltBuffer structure
  //
  for (Y = 0; Y < GLYPH_HEIGHT; Y++) {
    for (X = 0; X < GLYPH_WIDTH; X++) {
      if ((Glyph->Glyph[Y] & (1 << X)) != 0) {
        BltChar[Y][GLYPH_WIDTH - X - 1] = Foreground;
      } else {
        BltChar[Y][GLYPH_WIDTH - X - 1] = Background;
      }
    }
  }

  //
  // Blt a character to the screen
  //
  GlyphX = This->Mode->CursorColumn * GLYPH_WIDTH;
  GlyphY = This->Mode->CursorRow    * GLYPH_HEIGHT;
  UgaDraw = Private->UgaDraw;
  Status = UgaDraw->Blt (
                      UgaDraw, 
                      (EFI_UGA_PIXEL *)BltChar,
                      EfiUgaBltBufferToVideo, 
                      0,
                      0,
                      GlyphX + Private->ModeData[This->Mode->Mode].DeltaX, 
                      GlyphY + Private->ModeData[This->Mode->Mode].DeltaY, 
                      GLYPH_WIDTH, 
                      GLYPH_HEIGHT, 
                      GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
                      );

  return ReturnStatus;
}

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

{
  GRAPHICS_CONSOLE_DEV    *Private;
  EFI_STATUS              Status;
  EFI_STATUS              ReturnStatus;
  NARROW_GLYPH            *Glyph;
  INTN                    GlyphX;
  INTN                    GlyphY;
  EFI_UGA_DRAW_PROTOCOL   *UgaDraw;
  EFI_UGA_PIXEL           Foreground;
  EFI_UGA_PIXEL           Background;
  UINTN                   X;
  UINTN                   Y;
  UINTN                   Index;

  Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);

  ReturnStatus = EFI_SUCCESS;

  GetTextColors (This, &Foreground, &Background);

  for (Index = 0; Index < Count; Index++, UnicodeWeight++) {

    Status = ConvertUnicodeWeightToGlyph (*UnicodeWeight, &Glyph);
    if (EFI_ERROR (Status)) {
      ReturnStatus = Status;
    }

    //
    // Convert Monochrome bitmap of the Glyph to BltBuffer structure
    //
    for (Y = 0; Y < GLYPH_HEIGHT; Y++) {
      for (X = 0; X < GLYPH_WIDTH; X++) {
        if ((Glyph->Glyph[Y] & (1 << X)) != 0) {
          Private->LineBuffer[Y * GLYPH_WIDTH * Count + Index * GLYPH_WIDTH + (GLYPH_WIDTH - X - 1)] = Foreground;
        } else {
          Private->LineBuffer[Y * GLYPH_WIDTH * Count + Index * GLYPH_WIDTH + (GLYPH_WIDTH - X - 1)] = Background;
        }
      }
    }
  }

  //
  // Blt a character to the screen
  //
  GlyphX = This->Mode->CursorColumn * GLYPH_WIDTH;
  GlyphY = This->Mode->CursorRow    * GLYPH_HEIGHT;
  UgaDraw = Private->UgaDraw;
  Status = UgaDraw->Blt (
                      UgaDraw, 
                      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)
                      );

  return ReturnStatus;
}

EFI_STATUS
DrawCursor (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This
  )

{
  return EraseCursor (This);
}


EFI_STATUS
EraseCursor (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This
  )

{
  GRAPHICS_CONSOLE_DEV    *Private;
  EFI_STATUS              Status;
  INTN                    GlyphX;
  INTN                    GlyphY;
  EFI_UGA_DRAW_PROTOCOL   *UgaDraw;
  EFI_UGA_PIXEL_UNION     Foreground;
  EFI_UGA_PIXEL_UNION     Background;
  EFI_UGA_PIXEL_UNION     BltChar[GLYPH_HEIGHT][GLYPH_WIDTH];
  UINTN                   X;
  UINTN                   Y;

  if (!This->Mode->CursorVisible) {
    return EFI_SUCCESS;
  }

  Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);

  //
  // Blt a character to the screen
  //
  GlyphX = (This->Mode->CursorColumn * GLYPH_WIDTH) + Private->ModeData[This->Mode->Mode].DeltaX;
  GlyphY = (This->Mode->CursorRow    * GLYPH_HEIGHT) + Private->ModeData[This->Mode->Mode].DeltaY;
  UgaDraw = Private->UgaDraw;
  Status = UgaDraw->Blt (
                      UgaDraw, 
                      (EFI_UGA_PIXEL *)BltChar,
                      EfiUgaVideoToBltBuffer, 
                      GlyphX, 
                      GlyphY, 
                      0,
                      0,
                      GLYPH_WIDTH, 
                      GLYPH_HEIGHT, 
                      GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
                      );

  GetTextColors (This, &Foreground.Pixel, &Background.Pixel);

  //
  // 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.Glyph[Y] & (1 << X)) != 0) {
        BltChar[Y][GLYPH_WIDTH - X - 1].Raw ^= Foreground.Raw;
      }
    }
  }

  Status = UgaDraw->Blt (
                      UgaDraw, 
                      (EFI_UGA_PIXEL *)BltChar,
                      EfiUgaBltBufferToVideo, 
                      0,
                      0,
                      GlyphX, 
                      GlyphY, 
                      GLYPH_WIDTH, 
                      GLYPH_HEIGHT, 
                      GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
                      );
  return EFI_SUCCESS;
}

⌨️ 快捷键说明

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