lightconsplittergraphics.c

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

C
1,563
字号
/*++

Copyright (c) 2004 - 2006, Intel Corporation                                              
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module Name:
  
  LightConSplitterGraphics.c

Abstract:

  Support for ConsoleControl protocol. Support for Graphics output spliter.
  Support for DevNull Console Out. This console uses memory buffers
  to represnt the console. It allows a console to start very early and
  when a new console is added it is synced up with the current console

--*/

#include "LightConSplitter.h"
#include EFI_PROTOCOL_DEFINITION (Hii)

static CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };

EFI_STATUS
EFIAPI
ConSpliterConsoleControlGetMode (
  IN  EFI_CONSOLE_CONTROL_PROTOCOL    *This,
  OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,
  OUT BOOLEAN                         *GopExists,
  OUT BOOLEAN                         *StdInLocked
  )
/*++

  Routine Description:
    Return the current video mode information. Also returns info about existence
    of Graphics Output devices or UGA Draw devices in system, and if the Std In device is locked. All the
    arguments are optional and only returned if a non NULL pointer is passed in.

  Arguments:
    This - Protocol instance pointer.
    Mode        - Are we in text of grahics mode.
    GopExists   - TRUE if GOP Spliter has found a GOP/UGA device
    StdInLocked - TRUE if StdIn device is keyboard locked

  Returns:
    EFI_SUCCESS - Mode information returned.
    EFI_INVALID_PARAMETER - Invalid parameters.

--*/
{
  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;
  UINTN                           Index;

  Private = CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

  if (Mode == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *Mode = Private->ConsoleOutputMode;

  if (GopExists != NULL) {
    *GopExists = FALSE;
    for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
      if ((Private->TextOutList[Index].GraphicsOutput != NULL) || (Private->TextOutList[Index].UgaDraw != NULL)) {
        *GopExists = TRUE;
        break;
      }
    }
  }

  if (StdInLocked != NULL) {
    *StdInLocked = ConSpliterConssoleControlStdInLocked ();
  }

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
ConSpliterConsoleControlSetMode (
  IN  EFI_CONSOLE_CONTROL_PROTOCOL    *This,
  IN  EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
  )
/*++

  Routine Description:
    Set the current mode to either text or graphics. Graphics is
    for Quiet Boot.

  Arguments:
    This  - Protocol instance pointer.
    Mode  - Mode to set the

  Returns:
    EFI_SUCCESS     - Mode information returned.
    EFI_INVALID_PARAMETER - Invalid parameter.
    EFI_UNSUPPORTED - Operation unsupported.

--*/
{
  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;
  UINTN                           Index;
  TEXT_OUT_AND_GOP_DATA           *TextAndGop;
  BOOLEAN                         Supported;

  Private = CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

  if (Mode >= EfiConsoleControlScreenMaxValue) {
    return EFI_INVALID_PARAMETER;
  }

  Supported   = FALSE;
  TextAndGop  = &Private->TextOutList[0];
  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++, TextAndGop++) {
    if ((TextAndGop->GraphicsOutput != NULL) || (TextAndGop->UgaDraw != NULL)) {
      Supported = TRUE;
      break;
    }
  }

  if ((!Supported) && (Mode == EfiConsoleControlScreenGraphics)) {
    return EFI_UNSUPPORTED;
  }

  Private->ConsoleOutputMode  = Mode;

  TextAndGop = &Private->TextOutList[0];
  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++, TextAndGop++) {

    TextAndGop->TextOutEnabled = TRUE;
    //
    // If we are going into Graphics mode disable ConOut to any GOP/UGA device
    //
    if ((Mode == EfiConsoleControlScreenGraphics) &&((TextAndGop->GraphicsOutput != NULL) || (TextAndGop->UgaDraw != NULL))) {
      TextAndGop->TextOutEnabled = FALSE;
#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
      DevNullGopSync (Private, TextAndGop->GraphicsOutput, TextAndGop->UgaDraw);
#else
      DevNullUgaSync (Private, TextAndGop->UgaDraw);
#endif
    }
  }

  if (Mode == EfiConsoleControlScreenText) {
    DevNullSyncGopStdOut (Private);
  }

  return EFI_SUCCESS;
}

#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
EFI_STATUS
EFIAPI
ConSpliterGraphicsOutputQueryMode (
  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
  IN  UINT32                                ModeNumber,
  OUT UINTN                                 *SizeOfInfo,
  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info
  )
/*++

  Routine Description:
    Return the current video mode information.

  Arguments:
    This                  - Protocol instance pointer.
    ModeNumber            - The mode number to return information on.
    Info                  - Caller allocated buffer that returns information about ModeNumber.
    SizeOfInfo            - A pointer to the size, in bytes, of the Info buffer.

  Returns:
    EFI_SUCCESS           - Mode information returned.
    EFI_BUFFER_TOO_SMALL  - The Info buffer was too small.
    EFI_DEVICE_ERROR      - A hardware error occurred trying to retrieve the video mode.
    EFI_NOT_STARTED       - Video display is not initialized. Call SetMode ()
    EFI_INVALID_PARAMETER - One of the input args was NULL.

--*/
{
  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;
  EFI_STATUS                      Status;
  TEXT_OUT_GOP_MODE               *Mode;

  if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // retrieve private data
  //
  Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

  if (Private->HardwareNeedsStarting) {
    return EFI_NOT_STARTED;
  }

  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
                  Info
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);

  EfiCopyMem (*Info, Private->GraphicsOutput.Mode->Info, *SizeOfInfo);
  Mode = &Private->GraphicsOutputModeBuffer[ModeNumber];
  (*Info)->HorizontalResolution = Mode->HorizontalResolution;
  (*Info)->VerticalResolution = Mode->VerticalResolution;
  (*Info)->PixelsPerScanLine = Mode->HorizontalResolution;

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
ConSpliterGraphicsOutputSetMode (
  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL * This,
  IN  UINT32                       ModeNumber
  )
/*++

Routine Description:

  Graphics output protocol interface to set video mode

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

  Returns:
    EFI_SUCCESS      - Graphics mode was changed.
    EFI_DEVICE_ERROR - The device had an error and could not complete the request.
    EFI_UNSUPPORTED  - ModeNumber is not supported by this device.

--*/
{
  EFI_STATUS                             Status;
  TEXT_OUT_SPLITTER_PRIVATE_DATA         *Private;
  UINTN                                  Index;
  EFI_STATUS                             ReturnStatus;
  TEXT_OUT_GOP_MODE                      *Mode;
  UINTN                                  Size;
  EFI_GRAPHICS_OUTPUT_PROTOCOL           *GraphicsOutput;
  UINTN                                  NumberIndex;
  UINTN                                  SizeOfInfo;
  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   *Info;
  EFI_UGA_DRAW_PROTOCOL                  *UgaDraw;

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

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

  Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

  //
  // GopDevNullSetMode ()
  //
  ReturnStatus = EFI_SUCCESS;

  //
  // Free the old version
  //
  if (Private->GraphicsOutputBlt != NULL) {
    gBS->FreePool (Private->GraphicsOutputBlt);
  }

  //
  // Allocate the virtual Blt buffer
  //
  Mode = &Private->GraphicsOutputModeBuffer[ModeNumber];
  Size = Mode->HorizontalResolution * Mode->VerticalResolution * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
  Private->GraphicsOutputBlt = EfiLibAllocateZeroPool (Size);

  if (Private->GraphicsOutputBlt == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (!Private->HardwareNeedsStarting) {
    if (Private->ConsoleOutputMode != EfiConsoleControlScreenGraphics) {
      return EFI_UNSUPPORTED;
    }
  }
  //
  // return the worst status met
  //
  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
    GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
    if (GraphicsOutput != NULL) {
      //
      // Find corresponding ModeNumber of this GraphicsOutput instance
      //
      for (NumberIndex = 0; NumberIndex < GraphicsOutput->Mode->MaxMode; NumberIndex ++) {
        Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) NumberIndex, &SizeOfInfo, &Info);
        if (EFI_ERROR (Status)) {
          return Status;
        }
        if ((Info->HorizontalResolution == Mode->HorizontalResolution) && (Info->VerticalResolution == Mode->VerticalResolution)) {
          gBS->FreePool (Info);
          break;
        }
        gBS->FreePool (Info);
      }

      Status = GraphicsOutput->SetMode (GraphicsOutput, (UINT32) NumberIndex);
      if (EFI_ERROR (Status)) {
        ReturnStatus = Status;
      }
    }

    UgaDraw = Private->TextOutList[Index].UgaDraw;
    if (UgaDraw != NULL) {
      Status = UgaDraw->SetMode (
                          UgaDraw,
                          Mode->HorizontalResolution,
                          Mode->VerticalResolution,
                          32,
                          60
                          );
      if (EFI_ERROR (Status)) {
        ReturnStatus = Status;
      }
    }
  }

  This->Mode->Mode = ModeNumber;

  Info = This->Mode->Info;
  Info->HorizontalResolution = Mode->HorizontalResolution;
  Info->VerticalResolution   = Mode->VerticalResolution;
  Info->PixelsPerScanLine    = Mode->HorizontalResolution;

  //
  // Information is not enough here, so the following items remain unchanged:
  //  GraphicsOutputMode->Info->Version, GraphicsOutputMode->Info->PixelFormat
  //  GraphicsOutputMode->SizeOfInfo, GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
  // These items will be initialized/updated when a new GOP device is added into ConsoleSplitter.
  //

  Private->HardwareNeedsStarting = FALSE;

  return ReturnStatus;
}

EFI_STATUS
DevNullGraphicsOutputBlt (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA                *Private,
  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL                 *BltBuffer, OPTIONAL
  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION             BltOperation,
  IN  UINTN                                         SourceX,
  IN  UINTN                                         SourceY,
  IN  UINTN                                         DestinationX,
  IN  UINTN                                         DestinationY,
  IN  UINTN                                         Width,
  IN  UINTN                                         Height,
  IN  UINTN                                         Delta         OPTIONAL
  )
{
  UINTN                         SrcY;
  UINTN                         Index;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltPtr;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ScreenPtr;
  UINTN                         HorizontalResolution;
  UINTN                         VerticalResolution;

  if ((BltOperation < EfiBltVideoFill) || (BltOperation >= EfiGraphicsOutputBltOperationMax)) {
    return EFI_INVALID_PARAMETER;
  }

  if (Width == 0 || Height == 0) {
    return EFI_INVALID_PARAMETER;
  }

  if (Delta == 0) {
    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
  }

  HorizontalResolution  = Private->GraphicsOutput.Mode->Info->HorizontalResolution;

⌨️ 快捷键说明

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