consplittergraphics.c

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

C
1,003
字号

  return EFI_SUCCESS;
}

EFI_STATUS
DevNullTextOutSetMode (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,
  IN  UINTN                           ModeNumber
  )
/*++

  Routine Description:
    Sets the output device(s) to a specified mode.

  Arguments:
    This       - Protocol instance pointer.
    ModeNumber - The mode number to set.

  Returns:
    EFI_SUCCES       - The requested text mode was set.
    EFI_DEVICE_ERROR - The device had an error and 
                       could not complete the request.
    EFI_UNSUPPORTED - The mode number was not valid.

--*/
{
  UINTN                           Size;
  UINTN                           Row, Column;
  TEXT_OUT_SPLITTER_QUERY_DATA    *Mode;

  //
  // No extra check for ModeNumber here, as it has been checked in
  // ConSplitterTextOutSetMode. And mode 0 should always be supported.
  //

  Mode    = & (Private->TextOutQueryData[ModeNumber]);
  Row     = Mode->Rows;
  Column  = Mode->Columns;

  if (Private->DevNullColumns != Column ||
      Private->DevNullRows    != Row     ) {

    Private->TextOutMode.Mode = (INT32)ModeNumber;
    Private->DevNullColumns   = Column;
    Private->DevNullRows      = Row;

    gBS->FreePool (Private->DevNullScreen);

    Size = (Row * (Column + 1)) * sizeof (CHAR16);
    Private->DevNullScreen = EfiLibAllocateZeroPool (Size);
    if ( Private->DevNullScreen == NULL ) {
      return EFI_OUT_OF_RESOURCES;
    }

    gBS->FreePool (Private->DevNullAttributes);

    Size = Row * Column * sizeof (INT32);
    Private->DevNullAttributes = EfiLibAllocateZeroPool (Size);
    if ( Private->DevNullAttributes == NULL ) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  DevNullTextOutClearScreen (Private);

  return EFI_SUCCESS;
}

EFI_STATUS  
DevNullTextOutClearScreen (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private
  )
/*++

  Routine Description:
    Clears the output device(s) display to the currently selected background 
    color.

  Arguments:
    This      - Protocol instance pointer.

  Returns:
    EFI_SUCCES       - The operation completed successfully.
    EFI_DEVICE_ERROR - The device had an error and 
                       could not complete the request.
    EFI_UNSUPPORTED - The output device is not in a valid text mode.

--*/  
{  
  UINTN                               Row;
  UINTN                               Column;
  CHAR16                              *Screen;
  INT32                               *Attributes;
  INT32                               CurrentAttribute;

  //
  // Clear the DevNull Text Out Buffers.
  // The screen is filled with spaces.
  // The attributes are all synced with the current Simple Text Out Attribute
  //
  Screen = Private->DevNullScreen;
  Attributes = Private->DevNullAttributes;
  CurrentAttribute = Private->TextOutMode.Attribute;

  for (Row = 0; Row < Private->DevNullRows; Row++) {
    for (Column = 0; Column < Private->DevNullColumns; 
          Column++, Screen++, Attributes++) {
      *Screen = ' ';
      *Attributes = CurrentAttribute;
    }
    //
    // Each line of the screen has a NULL on the end so we must skip over it
    //
    Screen++;
  }

  DevNullTextOutSetCursorPosition (Private, 0, 0);

  return DevNullTextOutEnableCursor (Private, TRUE);
}

EFI_STATUS  
DevNullTextOutSetCursorPosition (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,
  IN  UINTN                           Column,
  IN  UINTN                           Row
  )
/*++

  Routine Description:
    Sets the current coordinates of the cursor position

  Arguments:
    This        - Protocol instance pointer.
    Column, Row - the position to set the cursor to. Must be greater than or
                  equal to zero and less than the number of columns and rows
                  by QueryMode ().

  Returns:
    EFI_SUCCES       - The operation completed successfully.
    EFI_DEVICE_ERROR - The device had an error and 
                       could not complete the request.
    EFI_UNSUPPORTED - The output device is not in a valid text mode, or the 
                       cursor position is invalid for the current mode.

--*/  
{
  //
  // No need to do extra check here as whether (Column, Row) is valid has 
  // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
  // always be supported.
  //

  Private->TextOutMode.CursorColumn = (INT32) Column;
  Private->TextOutMode.CursorRow    = (INT32) Row;

  return EFI_SUCCESS;
}

EFI_STATUS 
DevNullTextOutEnableCursor (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,
  IN  BOOLEAN                         Visible
  )
/*++
  Routine Description:
  
    Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
    In this driver, the cursor cannot be hidden.        
  
  Arguments:
  
    This - Indicates the calling context.
        
    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.
       
               
--*/        
{
  Private->TextOutMode.CursorVisible = Visible;
  
  return EFI_SUCCESS;
}

EFI_STATUS
DevNullSyncUgaStdOut (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private
  )
/*++
  Routine Description:
    Take the DevNull TextOut device and update the Simple Text Out on every
    UGA device. 
 
  Arguments:
    Private - Indicates the calling context.

  Returns:
    EFI_SUCCESS - The request is valid.
    other       - Return status of TextOut->OutputString ()
               
--*/        
{
  EFI_STATUS                          Status;
  EFI_STATUS                          ReturnStatus;
  UINTN                               Row, Column, List;
  UINTN                               MaxColumn;
  UINTN                               CurrentColumn;
  UINTN                               StartRow, StartColumn;
  INT32                               StartAttribute;
  BOOLEAN                             StartCursorState;
  CHAR16                              *Screen;
  CHAR16                              *Str;
  CHAR16                              *ScreenStart;
  CHAR16                              RememberTempNull;
  INT32                               CurrentAttribute;
  INT32                               *Attributes;
  EFI_SIMPLE_TEXT_OUT_PROTOCOL        *Sto;

  //
  // Save the devices Attributes, Cursor enable state and location
  //
  StartColumn       = Private->TextOutMode.CursorColumn;
  StartRow          = Private->TextOutMode.CursorRow;
  StartAttribute    = Private->TextOutMode.Attribute;
  StartCursorState  = Private->TextOutMode.CursorVisible;

  for ( List = 0; List < Private->CurrentNumberOfConsoles; List++ ) {

    Sto = Private->TextOutList[List].TextOut;

    //
    // Skip non UGA devices
    //
    if ( Private->TextOutList[List].UgaDraw ) {
      Sto->EnableCursor (Sto, FALSE);
      Sto->ClearScreen (Sto);
    }
  }

  ReturnStatus  = EFI_SUCCESS;
  Screen        = Private->DevNullScreen;
  Attributes    = Private->DevNullAttributes;
  MaxColumn     = Private->DevNullColumns;
  for ( Row = 0; Row < Private->DevNullRows; 
        Row++, Screen += (MaxColumn + 1), Attributes += MaxColumn ) {
          
    if (Row == (Private->DevNullRows - 1)) {
      //
      // Don't ever sync the last character as it will scroll the screen
      //
      Screen[MaxColumn - 1] = 0x00;
    }
    Column      = 0;
    while ( Column < MaxColumn ) {
      if ( Screen[Column] ) {
        CurrentAttribute  = Attributes[Column];
        CurrentColumn     = Column;
        ScreenStart       = &Screen[Column];

        //
        // the line end is alway 0x0. So Column should be less than MaxColumn
        // It should be still in the same row
        //
        for ( Str = ScreenStart, RememberTempNull = 0; 
              *Str != 0; Str++, Column++ ) {

          if ( Attributes[Column] != CurrentAttribute ) {
            RememberTempNull = *Str;
            *Str = 0;
            break;
          }
        }

        //
        // BugBug: One character at a time is 
        //         a bad optimization algorithm!!!!!!!!!!!!!!
        //
        for ( List = 0; List < Private->CurrentNumberOfConsoles; List++ ) {

          Sto = Private->TextOutList[List].TextOut;

          //
          // Skip non UGA devices
          //
          if ( Private->TextOutList[List].UgaDraw ) {
            Sto->SetAttribute (Sto, CurrentAttribute);
            Sto->SetCursorPosition (Sto, CurrentColumn, Row);
            Status = Sto->OutputString (Sto, ScreenStart);
            if (EFI_ERROR (Status)) {
              ReturnStatus = Status;
            }
          }
        }
        
        if ( RememberTempNull ) {
          *Str = RememberTempNull;
          //
          // Make sure we process the character with the new attributes
          //
          Column --;
        }
      }
      Column ++;
    }
  }

  //
  // Restore the devices Attributes, Cursor enable state and location
  //
  for ( List = 0; List < Private->CurrentNumberOfConsoles; List++ ) {
    Sto = Private->TextOutList[List].TextOut;

    //
    // Skip non UGA devices
    //
    if ( Private->TextOutList[List].UgaDraw ) {
      Sto->SetAttribute (Sto, StartAttribute);
      Sto->SetCursorPosition (Sto, StartColumn, StartRow);
      Status = Sto->EnableCursor (Sto, StartCursorState);
      if (EFI_ERROR (Status)) {
        ReturnStatus = Status;
      }
    }
  }

  return ReturnStatus;
}

⌨️ 快捷键说明

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