terminalconout.c

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

C
937
字号
EFIAPI
TerminalConOutSetMode (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,
  IN  UINTN                         ModeNumber
  )
/*++
  Routine Description:
  
    Implements EFI_SIMPLE_TEXT_OUT.SetMode().
    Set the terminal to a specified display mode.
    In this driver, we only support mode 0.        
  
  Arguments:
  
    EFI_SIMPLE_TEXT_OUT_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 serial device error.
    
    EFI_UNSUPPORTED
      The text mode number is not valid.       
                
--*/      
{ 
  EFI_STATUS    Status;  
  TERMINAL_DEV  *TerminalDevice;
  
  //
  //  get Terminal device data structure pointer.
  //
  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS(This);
  
  if (ModeNumber != 0) {
    return EFI_UNSUPPORTED;
  }
  
  This->Mode->Mode = 0;
    
  This->ClearScreen(This);
  
  TerminalDevice->OutputEscChar = TRUE;
  Status = This->OutputString(This, mSetModeString);
  TerminalDevice->OutputEscChar = FALSE;
  
  if (EFI_ERROR(Status)) {
    return EFI_DEVICE_ERROR;
  }
    
  This->Mode->Mode = 0;

  Status = This->ClearScreen(This);
  if (EFI_ERROR(Status)) {
    return EFI_DEVICE_ERROR;
  }
    
  return EFI_SUCCESS;
  
}

EFI_STATUS 
EFIAPI
TerminalConOutSetAttribute (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,
  IN  UINTN                         Attribute
  )
/*++
  Routine Description:
  
    Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.SetAttribute().       
  
  Arguments:
  
    EFI_SIMPLE_TEXT_OUT_PROTOCOL  IN    *This
        Indicates the calling context.
    
    UINTN                         IN    Attribute
        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 serial port error.
          
    EFI_UNSUPPORTED
      The attribute requested is not defined by EFI spec.   
                
--*/      
{
  UINT8           ForegroundControl;
  UINT8           BackgroundControl;
  UINT8           BrightControl;
  INT32           SavedColumn;
  INT32           SavedRow;
  EFI_STATUS      Status;
  TERMINAL_DEV    *TerminalDevice;
  
  SavedColumn = 0;
  SavedRow = 0;
  
  //
  //  get Terminal device data structure pointer.
  //
  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS(This);  

  //
  //  only the bit0..6 of the Attribute is valid
  //  
  if ((Attribute | 0x7f) != 0x7f) {
    return EFI_UNSUPPORTED;
  }
  
  //
  //  convert Attribute value to terminal emulator
  //  understandable foreground color
  //
  switch (Attribute & 0x07) {
      
    case EFI_BLACK      : ForegroundControl = 30; break;
    case EFI_BLUE       : ForegroundControl = 34; break;
    case EFI_GREEN      : ForegroundControl = 32; break;
    case EFI_CYAN       : ForegroundControl = 36; break;
    case EFI_RED        : ForegroundControl = 31; break;
    case EFI_MAGENTA    : ForegroundControl = 35; break;
    case EFI_BROWN      : ForegroundControl = 33; break;
    default:
    case EFI_LIGHTGRAY  : ForegroundControl = 37; break;

  }
  
  //
  //  bit4 of the Attribute indicates bright control
  //  of terminal emulator.
  //
  BrightControl = (UINT8)((Attribute>>3) & 1);

  //
  //  convert Attribute value to terminal emulator
  //  understandable background color.
  //
  switch ((Attribute>>4) & 0x07) {
      
    case EFI_BLACK     : BackgroundControl = 40; break;
    case EFI_BLUE      : BackgroundControl = 44; break;
    case EFI_GREEN     : BackgroundControl = 42; break;
    case EFI_CYAN      : BackgroundControl = 46; break;
    case EFI_RED       : BackgroundControl = 41; break;
    case EFI_MAGENTA   : BackgroundControl = 45; break;
    case EFI_BROWN     : BackgroundControl = 43; break;
    default:
    case EFI_LIGHTGRAY : BackgroundControl = 47; break;
  }
  
  //
  // terminal emulator's control sequence to set attributes
  //
  mSetAttributeString[BRIGHT_CONTROL_OFFSET]         = (CHAR16)('0' + BrightControl);
  mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 0] = (CHAR16)('0' + (ForegroundControl / 10));
  mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 1] = (CHAR16)('0' + (ForegroundControl % 10));
  mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 0] = (CHAR16)('0' + (BackgroundControl / 10));
  mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 1] = (CHAR16)('0' + (BackgroundControl % 10));
 
  // 
  // save current column and row 
  // for future scrolling back use.
  //
  SavedColumn = This->Mode->CursorColumn;
  SavedRow  = This->Mode->CursorRow;
  
  TerminalDevice->OutputEscChar = TRUE;
  Status = This->OutputString(This, mSetAttributeString);
  TerminalDevice->OutputEscChar = FALSE;
  
  if (EFI_ERROR(Status)) {
    return EFI_DEVICE_ERROR;
  } 
  
  //
  //  scroll back to saved cursor position.
  //
  This->Mode->CursorColumn = SavedColumn;
  This->Mode->CursorRow  = SavedRow;

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

  return EFI_SUCCESS;
  
}

EFI_STATUS 
EFIAPI
TerminalConOutClearScreen (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This
  )
/*++
  Routine Description:
  
    Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.ClearScreen().
    It clears the ANSI terminal's display to the 
    currently selected background color.
        
  
  Arguments:
  
    EFI_SIMPLE_TEXT_OUT_PROTOCOL  IN    *This
        Indicates the calling context.

  Returns:
  
    EFI_SUCCESS
      The operation completed successfully.
       
    EFI_DEVICE_ERROR
      The terminal screen cannot be cleared due to serial port error.        
    
    EFI_UNSUPPORTED
      The terminal is not in a valid display mode.       
                
--*/      
{
  EFI_STATUS      Status;
  TERMINAL_DEV    *TerminalDevice;
  
  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS(This);
 
  //
  //  control sequence for clear screen request
  //
  TerminalDevice->OutputEscChar = TRUE;
  Status = This->OutputString(This, mClearScreenString);
  TerminalDevice->OutputEscChar = FALSE;
  
  if (EFI_ERROR(Status)) {
    return EFI_DEVICE_ERROR;
  }

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

EFI_STATUS 
EFIAPI
TerminalConOutSetCursorPosition (
  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,
  IN  UINTN                         Column,
  IN  UINTN                         Row
  )
/*++
  Routine Description:
  
    Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.SetCursorPosition().          
  
  Arguments:
  
    EFI_SIMPLE_TEXT_OUT_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 serial port error.        
    
    EFI_UNSUPPORTED
      The terminal is not in a valid text mode, or the cursor position
      is invalid for current mode.     
                
--*/        
{
  EFI_SIMPLE_TEXT_OUTPUT_MODE   *Mode;
  UINTN                         MaxColumn;
  UINTN                         MaxRow;
  EFI_STATUS                    Status;
  TERMINAL_DEV                  *TerminalDevice;
  
  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS(This);  

  //
  //  get current mode
  //
  Mode = This->Mode;
  
  //
  //  get geometry of current mode
  //
  Status = This->QueryMode(
        This, 
        Mode->Mode, 
        &MaxColumn, 
        &MaxRow
        );
  if (EFI_ERROR(Status)) {
    return EFI_UNSUPPORTED;          
  }

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

  //
  // control sequence to move the cursor
  //

  mSetCursorPositionString[ROW_OFFSET + 0]    = (CHAR16)('0' + ((Row + 1) / 10));
  mSetCursorPositionString[ROW_OFFSET + 1]    = (CHAR16)('0' + ((Row + 1) % 10));
  mSetCursorPositionString[COLUMN_OFFSET + 0] = (CHAR16)('0' + ((Column + 1) / 10));
  mSetCursorPositionString[COLUMN_OFFSET + 1] = (CHAR16)('0' + ((Column + 1) % 10));
  
  TerminalDevice->OutputEscChar = TRUE;
  Status = This->OutputString(This, mSetCursorPositionString);
  TerminalDevice->OutputEscChar = FALSE;
  
  if (EFI_ERROR(Status)) {
    return EFI_DEVICE_ERROR;
  }

  //
  //  update current cursor position
  //  in the Mode data structure.
  //
  Mode->CursorColumn = (INT32) Column;
  Mode->CursorRow    = (INT32) Row;
  
  return EFI_SUCCESS;
}

EFI_STATUS 
EFIAPI
TerminalConOutEnableCursor (
  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:
  
    SERIAL_IO_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 terminal does not support cursor hidden.   
                
--*/        
{
  if (Visible == FALSE) {
    return EFI_UNSUPPORTED;
  }
  
  return EFI_SUCCESS;
}


BOOLEAN
TerminalIsValidTextGraphics (
    IN  CHAR16  Graphic,
    OUT CHAR8   *PcAnsi,    OPTIONAL
    OUT CHAR8   *Ascii      OPTIONAL
    )
/*++

Routine Description:

    Detects if a Unicode char is for Box Drawing text graphics.

Arguments:

    Graphic  - Unicode char to test.

    PcAnsi  - Optional pointer to return PCANSI equivalent of Graphic.

    Ascii   - Optional pointer to return ASCII equivalent of Graphic.

Returns:

    TRUE if Graphic is a supported Unicode Box Drawing character.

--*/
{
  UNICODE_TO_CHAR     *Table;

  if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {
     
    //
    // Unicode drawing code charts are all in the 0x25xx range, 
    //  arrows are 0x21xx
    //
    return FALSE;
  }

  for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {
    if (Graphic == Table->Unicode) {
      if (PcAnsi) {
        *PcAnsi = Table->PcAnsi; 
      }
      if (Ascii) {
        *Ascii = Table->Ascii;
      }
      return TRUE;
    }
  }
  
  return FALSE;
}

BOOLEAN
TerminalIsValidAscii (
    IN  CHAR16  Ascii
    )
{
  //
  // valid ascii code lies in the extent of 0x20 ~ 0x7f
  //
  if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {
    return TRUE;
  }              
  return FALSE;
}

BOOLEAN
TerminalIsValidEfiCntlChar (
    IN  CHAR16  c
    )
{
  //
  // only support four control characters.
  //
  if (c == CHAR_NULL || c == CHAR_BACKSPACE 
      || c == CHAR_LINEFEED || c == CHAR_CARRIAGE_RETURN
      || c == CHAR_TAB) {
    return TRUE;
  }              
  return FALSE;
}

⌨️ 快捷键说明

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