/** @file
  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.

Copyright (c) 2006 - 2008, Intel Corporation. <BR>
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.


**/

#include "ConSplitter.h"


CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };


/**
  Return the current video mode information. Also returns info about existence
  of Graphics Output devices or UGA Draw devices in system, and whether the Std
  In device is locked. GopUgaExists and StdInLocked parameters are optional, and
  only returned if a non NULL pointer is passed in.

  @param  This                    Protocol instance pointer.
  @param  Mode                    Current video mode.
  @param  GopUgaExists            TRUE if GOP Spliter has found a GOP/UGA device
  @param  StdInLocked             TRUE if StdIn device is keyboard locked

  @retval EFI_SUCCESS             Video mode information is returned.
  @retval EFI_INVALID_PARAMETER   Invalid parameters if Mode == NULL.

**/
EFI_STATUS
EFIAPI
ConSpliterConsoleControlGetMode (
  IN  EFI_CONSOLE_CONTROL_PROTOCOL    *This,
  OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,
  OUT BOOLEAN                         *GopUgaExists,
  OUT BOOLEAN                         *StdInLocked
  )
{
  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 (GopUgaExists != NULL) {
    *GopUgaExists = FALSE;
    for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
      if ((Private->TextOutList[Index].GraphicsOutput != NULL) || (Private->TextOutList[Index].UgaDraw != NULL)) {
        *GopUgaExists = TRUE;
        break;
      }
    }
  }

  if (StdInLocked != NULL) {
    *StdInLocked = ConSpliterConssoleControlStdInLocked ();
  }

  return EFI_SUCCESS;
}


/**
  Set the current mode to either text or graphics. Graphics is
  for Quiet Boot.

  @param  This                    Console Control Protocol instance pointer.
  @param  Mode                    Mode to set.

  @retval EFI_SUCCESS             Mode information returned.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_UNSUPPORTED         Operation unsupported.

**/
EFI_STATUS
EFIAPI
ConSpliterConsoleControlSetMode (
  IN  EFI_CONSOLE_CONTROL_PROTOCOL    *This,
  IN  EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
  )
{
  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;
  }

  //
  // Judge current mode with wanted mode at first.
  //
  if (Private->ConsoleOutputMode == Mode) {
    return EFI_SUCCESS;
  }

  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 UGA device
    //
    if ((Mode == EfiConsoleControlScreenGraphics) &&((TextAndGop->GraphicsOutput != NULL) || (TextAndGop->UgaDraw != NULL))) {
      TextAndGop->TextOutEnabled = FALSE;
      if (FeaturePcdGet (PcdConOutGopSupport)) {
        DevNullGopSync (Private, TextAndGop->GraphicsOutput, TextAndGop->UgaDraw);
      } else if (FeaturePcdGet (PcdConOutUgaSupport)) {
        DevNullUgaSync (Private, TextAndGop->GraphicsOutput, TextAndGop->UgaDraw);
      }
    }
  }
  if (Mode == EfiConsoleControlScreenText) {
    DevNullSyncStdOut (Private);
  }
  return EFI_SUCCESS;
}


/**
  Returns information for an available graphics mode that the graphics device
  and the set of active video output devices supports.

  @param  This                  The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
  @param  ModeNumber            The mode number to return information on.
  @param  SizeOfInfo            A pointer to the size, in bytes, of the Info buffer.
  @param  Info                  A pointer to callee allocated buffer that returns information about ModeNumber.

  @retval EFI_SUCCESS           Mode information returned.
  @retval EFI_BUFFER_TOO_SMALL  The Info buffer was too small.
  @retval EFI_DEVICE_ERROR      A hardware error occurred trying to retrieve the video mode.
  @retval EFI_NOT_STARTED       Video display is not initialized. Call SetMode ()
  @retval EFI_INVALID_PARAMETER One of the input args was NULL.
  @retval EFI_OUT_OF_RESOURCES  No resource available.

**/
EFI_STATUS
EFIAPI
ConSpliterGraphicsOutputQueryMode (
  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
  IN  UINT32                                ModeNumber,
  OUT UINTN                                 *SizeOfInfo,
  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info
  )
{
  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

  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;
  }

  *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
  if (*Info == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);

  CopyMem (*Info, &Private->GraphicsOutputModeBuffer[ModeNumber], *SizeOfInfo);

  return EFI_SUCCESS;
}


/**
  Set the video device into the specified mode and clears the visible portions of 
  the output display to black.

  @param  This                  The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
  @param  ModeNumber            Abstraction that defines the current video mode.

  @retval EFI_SUCCESS           The graphics mode specified by ModeNumber was selected.
  @retval EFI_DEVICE_ERROR      The device had an error and could not complete the request.
  @retval EFI_UNSUPPORTED       ModeNumber is not supported by this device.
  @retval EFI_OUT_OF_RESOURCES  No resource available.

**/
EFI_STATUS
EFIAPI
ConSpliterGraphicsOutputSetMode (
  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL * This,
  IN  UINT32                       ModeNumber
  )
{
  EFI_STATUS                             Status;
  TEXT_OUT_SPLITTER_PRIVATE_DATA         *Private;
  UINTN                                  Index;
  EFI_STATUS                             ReturnStatus;
  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   *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);

  ReturnStatus = EFI_SUCCESS;

  //
  // Free the old version
  //
  if (Private->GraphicsOutputBlt != NULL) {
    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 = AllocateZeroPool (Size);

  if (Private->GraphicsOutputBlt == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // 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)) {
          FreePool (Info);
          break;
        }
        FreePool (Info);
      }

      Status = GraphicsOutput->SetMode (GraphicsOutput, (UINT32) NumberIndex);
      if (EFI_ERROR (Status)) {
        ReturnStatus = Status;
      }
    } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
      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;

  CopyMem (This->Mode->Info, &Private->GraphicsOutputModeBuffer[ModeNumber], This->Mode->SizeOfInfo);

  //
  // 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;
}

/**
  The following table defines actions for BltOperations.

  EfiBltVideoFill - Write data from the  BltBuffer pixel (SourceX, SourceY)
  directly to every pixel of the video display rectangle
  (DestinationX, DestinationY)
  (DestinationX + Width, DestinationY + Height).
  Only one pixel will be used from the BltBuffer. Delta is NOT used.
  EfiBltVideoToBltBuffer - Read data from the video display rectangle
  (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
  the BltBuffer rectangle (DestinationX, DestinationY )
  (DestinationX + Width, DestinationY + Height). If DestinationX or
  DestinationY is not zero then Delta must be set to the length in bytes
  of a row in the BltBuffer.
  EfiBltBufferToVideo - Write data from the  BltBuffer rectangle
  (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
  video display rectangle (DestinationX, DestinationY)
  (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
  not zero then Delta must be set to the length in bytes of a row in the
  BltBuffer.
  EfiBltVideoToVideo - Copy from the video display rectangle
  (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
  to the video display rectangle (DestinationX, DestinationY)
  (DestinationX + Width, DestinationY + Height).
  The BltBuffer and Delta  are not used in this mode.

  @param  Private                 Protocol instance pointer.
  @param  BltBuffer               Buffer containing data to blit into video buffer.
                                  This buffer has a size of
                                  Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
  @param  BltOperation            Operation to perform on BlitBuffer and video
                                  memory
  @param  SourceX                 X coordinate of source for the BltBuffer.
  @param  SourceY                 Y coordinate of source for the BltBuffer.
  @param  DestinationX            X coordinate of destination for the BltBuffer.
  @param  DestinationY            Y coordinate of destination for the BltBuffer.
  @param  Width                   Width of rectangle in BltBuffer in pixels.
  @param  Height                  Hight of rectangle in BltBuffer in pixels. 
  @param  Delta                   OPTIONAL.

  @retval EFI_SUCCESS             The Blt operation completed.
  @retval EFI_INVALID_PARAMETER   BltOperation is not valid.
  @retval EFI_DEVICE_ERROR        A hardware error occured writting to the video
                                  buffer.

**/
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;
  BOOLEAN                       Forward;
  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;
  VerticalResolution    = Private->GraphicsOutput.Mode->Info->VerticalResolution;

  //
  // We need to fill the Virtual Screen buffer with the blt data.
  //
  if (BltOperation == EfiBltVideoToBltBuffer) {
    //
    // Video to BltBuffer: Source is Video, destination is BltBuffer
    //
    if ((SourceY + Height) > VerticalResolution) {
      return EFI_INVALID_PARAMETER;
    }

    if ((SourceX + Width) > HorizontalResolution) {
      return EFI_INVALID_PARAMETER;
    }

    BltPtr    = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + DestinationY * Delta + DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
    ScreenPtr = &Private->GraphicsOutputBlt[SourceY * HorizontalResolution + SourceX];
    while (Height > 0) {
      CopyMem (BltPtr, ScreenPtr, Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
      BltPtr = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltPtr + Delta);
      ScreenPtr += HorizontalResolution;
      Height--;
    }
  } else {
    //
    // BltBuffer to Video: Source is BltBuffer, destination is Video
    //
    if (DestinationY + Height > VerticalResolution) {
      return EFI_INVALID_PARAMETER;
    }

    if (DestinationX + Width > HorizontalResolution) {
      return EFI_INVALID_PARAMETER;
    }

    if ((BltOperation == EfiBltVideoToVideo) && (DestinationY > SourceY)) {
      //
      // Copy backwards, only care the Video to Video Blt
      //
      ScreenPtr = &Private->GraphicsOutputBlt[(DestinationY + Height - 1) * HorizontalResolution + DestinationX];
      SrcY      = SourceY + Height - 1;
      Forward   = FALSE;
    } else {
      //
      // Copy forwards, for other cases
      //
      ScreenPtr = &Private->GraphicsOutputBlt[DestinationY * HorizontalResolution + DestinationX];
      SrcY      = SourceY;
      Forward   = TRUE;
    }

    while (Height != 0) {
      if (BltOperation == EfiBltVideoFill) {
        for (Index = 0; Index < Width; Index++) {
          ScreenPtr[Index] = *BltBuffer;
        }
      } else {
        if (BltOperation == EfiBltBufferToVideo) {
          BltPtr = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + SrcY * Delta + SourceX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
        } else {
          BltPtr = &Private->GraphicsOutputBlt[SrcY * HorizontalResolution + SourceX];
        }

        CopyMem (ScreenPtr, BltPtr, Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
      }

      if (Forward) {
        ScreenPtr += HorizontalResolution;
        SrcY ++;
      } else {
        ScreenPtr -= HorizontalResolution;
        SrcY --;
      }
      Height--;
    }
  }

  return EFI_SUCCESS;
}


/**
  The following table defines actions for BltOperations.

  EfiBltVideoFill - Write data from the  BltBuffer pixel (SourceX, SourceY)
  directly to every pixel of the video display rectangle
  (DestinationX, DestinationY)
  (DestinationX + Width, DestinationY + Height).
  Only one pixel will be used from the BltBuffer. Delta is NOT used.
  EfiBltVideoToBltBuffer - Read data from the video display rectangle
  (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
  the BltBuffer rectangle (DestinationX, DestinationY )
  (DestinationX + Width, DestinationY + Height). If DestinationX or
  DestinationY is not zero then Delta must be set to the length in bytes
  of a row in the BltBuffer.
  EfiBltBufferToVideo - Write data from the  BltBuffer rectangle
  (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
  video display rectangle (DestinationX, DestinationY)
  (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
  not zero then Delta must be set to the length in bytes of a row in the
  BltBuffer.
  EfiBltVideoToVideo - Copy from the video display rectangle
  (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
  to the video display rectangle (DestinationX, DestinationY)
  (DestinationX + Width, DestinationY + Height).
  The BltBuffer and Delta  are not used in this mode.

  @param  This                    Protocol instance pointer.
  @param  BltBuffer               Buffer containing data to blit into video buffer.
                                  This buffer has a size of
                                  Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
  @param  BltOperation            Operation to perform on BlitBuffer and video
                                  memory
  @param  SourceX                 X coordinate of source for the BltBuffer.
  @param  SourceY                 Y coordinate of source for the BltBuffer.
  @param  DestinationX            X coordinate of destination for the BltBuffer.
  @param  DestinationY            Y coordinate of destination for the BltBuffer.
  @param  Width                   Width of rectangle in BltBuffer in pixels.
  @param  Height                  Hight of rectangle in BltBuffer in pixels. 
  @param  Delta                   OPTIONAL.

  @retval EFI_SUCCESS             The Blt operation completed.
  @retval EFI_INVALID_PARAMETER   BltOperation is not valid.
  @retval EFI_DEVICE_ERROR        A hardware error occured writting to the video
                                  buffer.

**/
EFI_STATUS
EFIAPI
ConSpliterGraphicsOutputBlt (
  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL                  *This,
  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
  )
{
  EFI_STATUS                      Status;
  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;
  UINTN                           Index;
  EFI_STATUS                      ReturnStatus;
  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
  EFI_UGA_DRAW_PROTOCOL           *UgaDraw;

  Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

  //
  // Sync up DevNull GOP device
  //
  ReturnStatus = DevNullGraphicsOutputBlt (
                  Private,
                  BltBuffer,
                  BltOperation,
                  SourceX,
                  SourceY,
                  DestinationX,
                  DestinationY,
                  Width,
                  Height,
                  Delta
                  );

  if (Private->ConsoleOutputMode != EfiConsoleControlScreenGraphics) {
    return ReturnStatus;
  }
  //
  // return the worst status met
  //
  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
    GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
    if (GraphicsOutput != NULL) {
      Status = GraphicsOutput->Blt (
                              GraphicsOutput,
                              BltBuffer,
                              BltOperation,
                              SourceX,
                              SourceY,
                              DestinationX,
                              DestinationY,
                              Width,
                              Height,
                              Delta
                              );
      if (EFI_ERROR (Status)) {
        ReturnStatus = Status;
      } else if (BltOperation == EfiBltVideoToBltBuffer) {
        //
        // Only need to read the data into buffer one time
        //
        return EFI_SUCCESS;
      }
    }

    UgaDraw = Private->TextOutList[Index].UgaDraw;
    if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
      Status = UgaDraw->Blt (
                              UgaDraw,
                              (EFI_UGA_PIXEL *) BltBuffer,
                              (EFI_UGA_BLT_OPERATION) BltOperation,
                              SourceX,
                              SourceY,
                              DestinationX,
                              DestinationY,
                              Width,
                              Height,
                              Delta
                              );
      if (EFI_ERROR (Status)) {
        ReturnStatus = Status;
      } else if (BltOperation == EfiBltVideoToBltBuffer) {
        //
        // Only need to read the data into buffer one time
        //
        return EFI_SUCCESS;
      }
    }
  }

  return ReturnStatus;
}

/**
  Write data from the buffer to video display based on Graphics Output setting. 

  @param  Private                 Consplitter Text Out pointer.
  @param  GraphicsOutput          Graphics Output protocol pointer.
  @param  UgaDraw                 UGA Draw protocol pointer.

  @retval EFI_UNSUPPORTED         No graphics devcie available .
  @retval EFI_SUCCESS             The Blt operation completed.
  @retval EFI_INVALID_PARAMETER   BltOperation is not valid.
  @retval EFI_DEVICE_ERROR        A hardware error occured writting to the video buffer.
                 

**/
EFI_STATUS
DevNullGopSync (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,
  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput,
  IN  EFI_UGA_DRAW_PROTOCOL           *UgaDraw
  )
{
  if (GraphicsOutput != NULL) {
    return GraphicsOutput->Blt (
                      GraphicsOutput,
                      Private->GraphicsOutputBlt,
                      EfiBltBufferToVideo,
                      0,
                      0,
                      0,
                      0,
                      Private->GraphicsOutput.Mode->Info->HorizontalResolution,
                      Private->GraphicsOutput.Mode->Info->VerticalResolution,
                      0
                      );
  } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
    return UgaDraw->Blt (
                      UgaDraw,
                      (EFI_UGA_PIXEL *) Private->GraphicsOutputBlt,
                      EfiUgaBltBufferToVideo,
                      0,
                      0,
                      0,
                      0,
                      Private->GraphicsOutput.Mode->Info->HorizontalResolution,
                      Private->GraphicsOutput.Mode->Info->VerticalResolution,
                      0
                      );
  } else {
    return EFI_UNSUPPORTED;
  }
}

/**
  Return the current video mode information.

  @param  This                  The EFI_UGA_DRAW_PROTOCOL instance.
  @param  HorizontalResolution  The size of video screen in pixels in the X dimension.
  @param  VerticalResolution    The size of video screen in pixels in the Y dimension.
  @param  ColorDepth            Number of bits per pixel, currently defined to be 32.
  @param  RefreshRate           The refresh rate of the monitor in Hertz.

  @retval EFI_SUCCESS           Mode information returned.
  @retval EFI_NOT_STARTED       Video display is not initialized. Call SetMode ()
  @retval EFI_INVALID_PARAMETER One of the input args was NULL.

**/
EFI_STATUS
EFIAPI
ConSpliterUgaDrawGetMode (
  IN  EFI_UGA_DRAW_PROTOCOL           *This,
  OUT UINT32                          *HorizontalResolution,
  OUT UINT32                          *VerticalResolution,
  OUT UINT32                          *ColorDepth,
  OUT UINT32                          *RefreshRate
  )
{
  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

  if ((HorizontalResolution == NULL) ||
      (VerticalResolution   == NULL) ||
      (RefreshRate          == NULL) ||
      (ColorDepth           == NULL)) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // retrieve private data
  //
  Private               = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

  *HorizontalResolution = Private->UgaHorizontalResolution;
  *VerticalResolution   = Private->UgaVerticalResolution;
  *ColorDepth           = Private->UgaColorDepth;
  *RefreshRate          = Private->UgaRefreshRate;

  return EFI_SUCCESS;
}


/**
  Set the current video mode information.

  @param  This                 The EFI_UGA_DRAW_PROTOCOL instance.
  @param  HorizontalResolution The size of video screen in pixels in the X dimension.
  @param  VerticalResolution   The size of video screen in pixels in the Y dimension.
  @param  ColorDepth           Number of bits per pixel, currently defined to be 32.
  @param  RefreshRate          The refresh rate of the monitor in Hertz.

  @retval EFI_SUCCESS          Mode information returned.
  @retval EFI_NOT_STARTED      Video display is not initialized. Call SetMode ()
  @retval EFI_OUT_OF_RESOURCES Out of resources.

**/
EFI_STATUS
EFIAPI
ConSpliterUgaDrawSetMode (
  IN  EFI_UGA_DRAW_PROTOCOL           *This,
  IN UINT32                           HorizontalResolution,
  IN UINT32                           VerticalResolution,
  IN UINT32                           ColorDepth,
  IN UINT32                           RefreshRate
  )
{
  EFI_STATUS                             Status;
  TEXT_OUT_SPLITTER_PRIVATE_DATA         *Private;
  UINTN                                  Index;
  EFI_STATUS                             ReturnStatus;
  UINTN                                  Size;
  EFI_GRAPHICS_OUTPUT_PROTOCOL           *GraphicsOutput;
  UINTN                                  NumberIndex;
  UINTN                                  SizeOfInfo;
  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   *Info;
  EFI_UGA_DRAW_PROTOCOL                  *UgaDraw;

  Private = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

  //
  // UgaDevNullSetMode ()
  //
  ReturnStatus = EFI_SUCCESS;

  //
  // Free the old version
  //
  if (Private->UgaBlt != NULL) {
    FreePool (Private->UgaBlt);
  }

  //
  // Allocate the virtual Blt buffer
  //
  Size            = HorizontalResolution * VerticalResolution * sizeof (EFI_UGA_PIXEL);
  Private->UgaBlt = AllocateZeroPool (Size);
  if (Private->UgaBlt == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Update the Mode data
  //
  Private->UgaHorizontalResolution  = HorizontalResolution;
  Private->UgaVerticalResolution    = VerticalResolution;
  Private->UgaColorDepth            = ColorDepth;
  Private->UgaRefreshRate           = RefreshRate;

  if (Private->ConsoleOutputMode != EfiConsoleControlScreenGraphics) {
    return ReturnStatus;
  }
  //
  // return the worst status met
  //
  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {

    ReturnStatus = EFI_UNSUPPORTED;

    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 == HorizontalResolution) && (Info->VerticalResolution == VerticalResolution)) {
          FreePool (Info);
          break;
        }
        FreePool (Info);
      }

      Status = GraphicsOutput->SetMode (GraphicsOutput, (UINT32) NumberIndex);
      if (EFI_ERROR (Status)) {
        ReturnStatus = Status;
      }
    } else if (FeaturePcdGet (PcdUgaConsumeSupport)){
      UgaDraw = Private->TextOutList[Index].UgaDraw;
      if (UgaDraw != NULL) {
        Status = UgaDraw->SetMode (
                          UgaDraw,
                          HorizontalResolution,
                          VerticalResolution,
                          ColorDepth,
                          RefreshRate
                          );
        if (EFI_ERROR (Status)) {
          ReturnStatus = Status;
        }
      }
    } 
  }

  return ReturnStatus;
}

/**
  Blt a rectangle of pixels on the graphics screen.

  The following table defines actions for BltOperations.

  EfiUgaVideoFill:
    Write data from the  BltBuffer pixel (SourceX, SourceY)
    directly to every pixel of the video display rectangle
    (DestinationX, DestinationY)
    (DestinationX + Width, DestinationY + Height).
    Only one pixel will be used from the BltBuffer. Delta is NOT used.
  EfiUgaVideoToBltBuffer: 
    Read data from the video display rectangle
    (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
    the BltBuffer rectangle (DestinationX, DestinationY )
    (DestinationX + Width, DestinationY + Height). If DestinationX or
    DestinationY is not zero then Delta must be set to the length in bytes
    of a row in the BltBuffer.
  EfiUgaBltBufferToVideo:
    Write data from the  BltBuffer rectangle
    (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
    video display rectangle (DestinationX, DestinationY)
    (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
    not zero then Delta must be set to the length in bytes of a row in the
    BltBuffer.
  EfiUgaVideoToVideo:
    Copy from the video display rectangle
    (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
    to the video display rectangle (DestinationX, DestinationY)
    (DestinationX + Width, DestinationY + Height).
    The BltBuffer and Delta  are not used in this mode.

  @param  Private                 Text Out Splitter pointer.
  @param  BltBuffer               Buffer containing data to blit into video buffer.
                                  This buffer has a size of
                                  Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
  @param  BltOperation            Operation to perform on BlitBuffer and video
                                  memory
  @param  SourceX                 X coordinate of source for the BltBuffer.
  @param  SourceY                 Y coordinate of source for the BltBuffer.
  @param  DestinationX            X coordinate of destination for the BltBuffer.
  @param  DestinationY            Y coordinate of destination for the BltBuffer.
  @param  Width                   Width of rectangle in BltBuffer in pixels.
  @param  Height                  Hight of rectangle in BltBuffer in pixels. 
  @param  Delta                   OPTIONAL.

  @retval EFI_SUCCESS             The Blt operation completed.
  @retval EFI_INVALID_PARAMETER   BltOperation is not valid.
  @retval EFI_DEVICE_ERROR        A hardware error occured writting to the video
                                  buffer.

**/
EFI_STATUS
DevNullUgaBlt (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA                *Private,
  IN  EFI_UGA_PIXEL                                 *BltBuffer, OPTIONAL
  IN  EFI_UGA_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;
  BOOLEAN       Forward;
  UINTN         Index;
  EFI_UGA_PIXEL *BltPtr;
  EFI_UGA_PIXEL *ScreenPtr;
  UINT32        HorizontalResolution;
  UINT32        VerticalResolution;

  if ((BltOperation < 0) || (BltOperation >= EfiUgaBltMax)) {
    return EFI_INVALID_PARAMETER;
  }

  if (Width == 0 || Height == 0) {
    return EFI_INVALID_PARAMETER;
  }

  if (Delta == 0) {
    Delta = Width * sizeof (EFI_UGA_PIXEL);
  }

  HorizontalResolution  = Private->UgaHorizontalResolution;
  VerticalResolution    = Private->UgaVerticalResolution;

  //
  // We need to fill the Virtual Screen buffer with the blt data.
  //
  if (BltOperation == EfiUgaVideoToBltBuffer) {
    //
    // Video to BltBuffer: Source is Video, destination is BltBuffer
    //
    if ((SourceY + Height) > VerticalResolution) {
      return EFI_INVALID_PARAMETER;
    }

    if ((SourceX + Width) > HorizontalResolution) {
      return EFI_INVALID_PARAMETER;
    }

    BltPtr    = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + DestinationY * Delta + DestinationX * sizeof (EFI_UGA_PIXEL));
    ScreenPtr = &Private->UgaBlt[SourceY * HorizontalResolution + SourceX];
    while (Height > 0) {
      CopyMem (BltPtr, ScreenPtr, Width * sizeof (EFI_UGA_PIXEL));
      BltPtr = (EFI_UGA_PIXEL *) ((UINT8 *) BltPtr + Delta);
      ScreenPtr += HorizontalResolution;
      Height--;
    }
  } else {
    //
    // BltBuffer to Video: Source is BltBuffer, destination is Video
    //
    if (DestinationY + Height > VerticalResolution) {
      return EFI_INVALID_PARAMETER;
    }

    if (DestinationX + Width > HorizontalResolution) {
      return EFI_INVALID_PARAMETER;
    }

    if ((BltOperation == EfiUgaVideoToVideo) && (DestinationY > SourceY)) {
      //
      // Copy backwards, only care the Video to Video Blt
      //
      ScreenPtr = &Private->UgaBlt[(DestinationY + Height - 1) * HorizontalResolution + DestinationX];
      SrcY      = SourceY + Height - 1;
      Forward   = FALSE;
    } else {
      //
      // Copy forwards, for other cases
      //
      ScreenPtr = &Private->UgaBlt[DestinationY * HorizontalResolution + DestinationX];
      SrcY      = SourceY;
      Forward   = TRUE;
    }

    while (Height != 0) {
      if (BltOperation == EfiUgaVideoFill) {
        for (Index = 0; Index < Width; Index++) {
          ScreenPtr[Index] = *BltBuffer;
        }
      } else {
        if (BltOperation == EfiUgaBltBufferToVideo) {
          BltPtr = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + SrcY * Delta + SourceX * sizeof (EFI_UGA_PIXEL));
        } else {
          BltPtr = &Private->UgaBlt[SrcY * HorizontalResolution + SourceX];
        }

        CopyMem (ScreenPtr, BltPtr, Width * sizeof (EFI_UGA_PIXEL));
      }

      if (Forward) {
        ScreenPtr += HorizontalResolution;
        SrcY ++;
      } else {
        ScreenPtr -= HorizontalResolution;
        SrcY --;
      }
      Height--;
    }
  }

  return EFI_SUCCESS;
}

/**
  Blt a rectangle of pixels on the graphics screen.

  The following table defines actions for BltOperations.

  EfiUgaVideoFill:
    Write data from the  BltBuffer pixel (SourceX, SourceY)
    directly to every pixel of the video display rectangle
    (DestinationX, DestinationY)
    (DestinationX + Width, DestinationY + Height).
    Only one pixel will be used from the BltBuffer. Delta is NOT used.
  EfiUgaVideoToBltBuffer: 
    Read data from the video display rectangle
    (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
    the BltBuffer rectangle (DestinationX, DestinationY )
    (DestinationX + Width, DestinationY + Height). If DestinationX or
    DestinationY is not zero then Delta must be set to the length in bytes
    of a row in the BltBuffer.
  EfiUgaBltBufferToVideo:
    Write data from the  BltBuffer rectangle
    (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
    video display rectangle (DestinationX, DestinationY)
    (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
    not zero then Delta must be set to the length in bytes of a row in the
    BltBuffer.
  EfiUgaVideoToVideo:
    Copy from the video display rectangle
    (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
    to the video display rectangle (DestinationX, DestinationY)
    (DestinationX + Width, DestinationY + Height).
    The BltBuffer and Delta  are not used in this mode.

  @param  This           Protocol instance pointer.
  @param  BltBuffer      Buffer containing data to blit into video buffer. This
                         buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
  @param  BltOperation   Operation to perform on BlitBuffer and video memory
  @param  SourceX        X coordinate of source for the BltBuffer.
  @param  SourceY        Y coordinate of source for the BltBuffer.
  @param  DestinationX   X coordinate of destination for the BltBuffer.
  @param  DestinationY   Y coordinate of destination for the BltBuffer.
  @param  Width          Width of rectangle in BltBuffer in pixels.
  @param  Height         Hight of rectangle in BltBuffer in pixels.
  @param  Delta          OPTIONAL

  @retval EFI_SUCCESS            The Blt operation completed.
  @retval EFI_INVALID_PARAMETER  BltOperation is not valid.
  @retval EFI_DEVICE_ERROR       A hardware error occured writting to the video buffer.

**/
EFI_STATUS
EFIAPI
ConSpliterUgaDrawBlt (
  IN  EFI_UGA_DRAW_PROTOCOL                         *This,
  IN  EFI_UGA_PIXEL                                 *BltBuffer, OPTIONAL
  IN  EFI_UGA_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
  )
{
  EFI_STATUS                      Status;
  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;
  UINTN                           Index;
  EFI_STATUS                      ReturnStatus;
  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;

  Private = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

  //
  // Sync up DevNull UGA device
  //
  ReturnStatus = DevNullUgaBlt (
                  Private,
                  BltBuffer,
                  BltOperation,
                  SourceX,
                  SourceY,
                  DestinationX,
                  DestinationY,
                  Width,
                  Height,
                  Delta
                  );
  if (Private->ConsoleOutputMode != EfiConsoleControlScreenGraphics) {
    return ReturnStatus;
  }
  //
  // return the worst status met
  //
  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
    GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
    if (GraphicsOutput != NULL) {
      Status = GraphicsOutput->Blt (
                              GraphicsOutput,
                              (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltBuffer,
                              (EFI_GRAPHICS_OUTPUT_BLT_OPERATION) BltOperation,
                              SourceX,
                              SourceY,
                              DestinationX,
                              DestinationY,
                              Width,
                              Height,
                              Delta
                              );
      if (EFI_ERROR (Status)) {
        ReturnStatus = Status;
      } else if (BltOperation == EfiBltVideoToBltBuffer) {
        //
        // Only need to read the data into buffer one time
        //
        return EFI_SUCCESS;
      }
    }

    if (Private->TextOutList[Index].UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
      Status = Private->TextOutList[Index].UgaDraw->Blt (
                                                      Private->TextOutList[Index].UgaDraw,
                                                      BltBuffer,
                                                      BltOperation,
                                                      SourceX,
                                                      SourceY,
                                                      DestinationX,
                                                      DestinationY,
                                                      Width,
                                                      Height,
                                                      Delta
                                                      );
      if (EFI_ERROR (Status)) {
        ReturnStatus = Status;
      } else if (BltOperation == EfiUgaVideoToBltBuffer) {
        //
        // Only need to read the data into buffer one time
        //
        return EFI_SUCCESS;
      }
    }
  }

  return ReturnStatus;
}

/**
  Write data from the buffer to video display based on UGA Draw setting. 

  @param  Private                 Consplitter Text Out pointer.
  @param  GraphicsOutput          Graphics Output protocol pointer.
  @param  UgaDraw                 UGA Draw protocol pointer.

  @retval EFI_UNSUPPORTED         No graphics devcie available .
  @retval EFI_SUCCESS             The Blt operation completed.
  @retval EFI_INVALID_PARAMETER   BltOperation is not valid.
  @retval EFI_DEVICE_ERROR        A hardware error occured writting to the video buffer.
                  
**/
EFI_STATUS
DevNullUgaSync (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,
  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput,
  IN  EFI_UGA_DRAW_PROTOCOL           *UgaDraw
  )
{
  if (GraphicsOutput != NULL) {
    return GraphicsOutput->Blt (
                      GraphicsOutput,
                      (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) Private->UgaBlt,
                      EfiBltBufferToVideo,
                      0,
                      0,
                      0,
                      0,
                      Private->UgaHorizontalResolution,
                      Private->UgaVerticalResolution,
                      0
                      );
  } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
    return UgaDraw->Blt (
                      UgaDraw,
                      Private->UgaBlt,
                      EfiUgaBltBufferToVideo,
                      0,
                      0,
                      0,
                      0,
                      Private->UgaHorizontalResolution,
                      Private->UgaVerticalResolution,
                      Private->UgaHorizontalResolution * sizeof (EFI_UGA_PIXEL)
                      );
  } else {
    return EFI_UNSUPPORTED;
  }
}


/**
  Write a Unicode string to the output device.

  @param  Private                 Pointer to the console output splitter's private
                                  data. It indicates the calling context.
  @param  WString                 The NULL-terminated Unicode string to be
                                  displayed on the output device(s). All output
                                  devices must also support the Unicode drawing
                                  defined in this file.

  @retval EFI_SUCCESS             The string was output to the device.
  @retval EFI_DEVICE_ERROR        The device reported an error while attempting to
                                  output the text.
  @retval EFI_UNSUPPORTED         The output device's mode is not currently in a
                                  defined text mode.
  @retval EFI_WARN_UNKNOWN_GLYPH  This warning code indicates that some of the
                                  characters in the Unicode string could not be
                                  rendered and were skipped.

**/
EFI_STATUS
DevNullTextOutOutputString (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,
  IN  CHAR16                          *WString
  )
{
  UINTN                       SizeScreen;
  UINTN                       SizeAttribute;
  UINTN                       Index;
  EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
  CHAR16                      *Screen;
  CHAR16                      *NullScreen;
  CHAR16                      InsertChar;
  CHAR16                      TempChar;
  CHAR16                      *PStr;
  INT32                       *Attribute;
  INT32                       *NullAttributes;
  INT32                       CurrentWidth;
  UINTN                       LastRow;
  UINTN                       MaxColumn;

  Mode            = &Private->TextOutMode;
  NullScreen      = Private->DevNullScreen;
  NullAttributes  = Private->DevNullAttributes;
  LastRow         = Private->DevNullRows - 1;
  MaxColumn       = Private->DevNullColumns;

  if (Mode->Attribute & EFI_WIDE_ATTRIBUTE) {
    CurrentWidth = 2;
  } else {
    CurrentWidth = 1;
  }

  while (*WString != L'\0') {

    if (*WString == CHAR_BACKSPACE) {
      //
      // If the cursor is at the left edge of the display, then move the cursor
      // one row up.
      //
      if (Mode->CursorColumn == 0 && Mode->CursorRow > 0) {
        Mode->CursorRow--;
        Mode->CursorColumn = (INT32) MaxColumn;
      }

      //
      // If the cursor is not at the left edge of the display,
      // then move the cursor left one column.
      //
      if (Mode->CursorColumn > 0) {
        Mode->CursorColumn--;
        if (Mode->CursorColumn > 0 &&
            NullAttributes[Mode->CursorRow * MaxColumn + Mode->CursorColumn - 1] & EFI_WIDE_ATTRIBUTE
            ) {
          Mode->CursorColumn--;

          //
          // Insert an extra backspace
          //
          InsertChar  = CHAR_BACKSPACE;
          PStr        = WString + 1;
          while (*PStr != L'\0') {
            TempChar    = *PStr;
            *PStr       = InsertChar;
            InsertChar  = TempChar;
            PStr++;
          }

          *PStr     = InsertChar;
          *(++PStr) = 0;

          WString++;
        }
      }

      WString++;

    } else if (*WString == 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 (Mode->CursorRow == (INT32) (LastRow)) {
        //
        // Scroll Screen Up One Row
        //
        SizeAttribute = LastRow * MaxColumn;
        CopyMem (
          NullAttributes,
          NullAttributes + MaxColumn,
          SizeAttribute * sizeof (INT32)
          );

        //
        // Each row has an ending CHAR_NULL. So one more character each line
        // for DevNullScreen than DevNullAttributes
        //
        SizeScreen = SizeAttribute + LastRow;
        CopyMem (
          NullScreen,
          NullScreen + (MaxColumn + 1),
          SizeScreen * sizeof (CHAR16)
          );

        //
        // Print Blank Line at last line
        //
        Screen    = NullScreen + SizeScreen;
        Attribute = NullAttributes + SizeAttribute;

        for (Index = 0; Index < MaxColumn; Index++, Screen++, Attribute++) {
          *Screen     = L' ';
          *Attribute  = Mode->Attribute;
        }
      } else {
        Mode->CursorRow++;
      }

      WString++;
    } else if (*WString == CHAR_CARRIAGE_RETURN) {
      //
      // Move the cursor to the beginning of the current row.
      //
      Mode->CursorColumn = 0;
      WString++;
    } else {
      //
      // 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.
      //
      Index = Mode->CursorRow * MaxColumn + Mode->CursorColumn;

      while (Mode->CursorColumn < (INT32) MaxColumn) {
        if (*WString == CHAR_NULL) {
          break;
        }

        if (*WString == CHAR_BACKSPACE) {
          break;
        }

        if (*WString == CHAR_LINEFEED) {
          break;
        }

        if (*WString == CHAR_CARRIAGE_RETURN) {
          break;
        }

        if (*WString == UNICODE_WIDE_CHAR || *WString == UNICODE_NARROW_CHAR) {
          CurrentWidth = (*WString == UNICODE_WIDE_CHAR) ? 2 : 1;
          WString++;
          continue;
        }

        if (Mode->CursorColumn + CurrentWidth > (INT32) MaxColumn) {
          //
          // If a wide char is at the rightmost column, then move the char
          // to the beginning of the next row
          //
          NullScreen[Index + Mode->CursorRow] = L' ';
          NullAttributes[Index]               = Mode->Attribute | (UINT32) EFI_WIDE_ATTRIBUTE;
          Index++;
          Mode->CursorColumn++;
        } else {
          NullScreen[Index + Mode->CursorRow] = *WString;
          NullAttributes[Index]               = Mode->Attribute;
          if (CurrentWidth == 1) {
            NullAttributes[Index] &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);
          } else {
            NullAttributes[Index] |= (UINT32) EFI_WIDE_ATTRIBUTE;
            NullAttributes[Index + 1] &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);
          }

          Index += CurrentWidth;
          WString++;
          Mode->CursorColumn += CurrentWidth;
        }
      }
      //
      // At the end of line, output carriage return and line feed
      //
      if (Mode->CursorColumn >= (INT32) MaxColumn) {
        DevNullTextOutOutputString (Private, mCrLfString);
      }
    }
  }

  return EFI_SUCCESS;
}


/**
  Sets the output device(s) to a specified mode.

  @param  Private                 Text Out Splitter pointer.
  @param  ModeNumber              The mode number to set.

  @retval EFI_SUCCESS             The requested text mode was set.
  @retval EFI_DEVICE_ERROR        The device had an error and could not complete
                                  the request.
  @retval EFI_UNSUPPORTED         The mode number was not valid.
  @retval EFI_OUT_OF_RESOURCES    Out of resources.

**/
EFI_STATUS
DevNullTextOutSetMode (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,
  IN  UINTN                           ModeNumber
  )
{
  UINTN                         Size;
  INT32                         CurrentMode;
  UINTN                         Row;
  UINTN                         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.
  // Row and Column should be fetched from intersection map.
  //
  if (Private->TextOutModeMap != NULL) {
    CurrentMode = *(Private->TextOutModeMap + Private->TextOutListCount * ModeNumber);
  } else {
    CurrentMode = (INT32) (ModeNumber);
  }
  Mode    = &(Private->TextOutQueryData[CurrentMode]);
  Row     = Mode->Rows;
  Column  = Mode->Columns;

  if (Row <= 0 && Column <= 0) {
    return EFI_UNSUPPORTED;
  }

  if (Private->TextOutMode.Mode != (INT32) ModeNumber) {

    Private->TextOutMode.Mode = (INT32) ModeNumber;
    Private->DevNullColumns   = Column;
    Private->DevNullRows      = Row;

    if (Private->DevNullScreen != NULL) {
      FreePool (Private->DevNullScreen);
    }

    Size                    = (Row * (Column + 1)) * sizeof (CHAR16);
    Private->DevNullScreen  = AllocateZeroPool (Size);
    if (Private->DevNullScreen == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    if (Private->DevNullAttributes != NULL) {
      FreePool (Private->DevNullAttributes);
    }

    Size                        = Row * Column * sizeof (INT32);
    Private->DevNullAttributes  = AllocateZeroPool (Size);
    if (Private->DevNullAttributes == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  DevNullTextOutClearScreen (Private);

  return EFI_SUCCESS;
}


/**
  Clears the output device(s) display to the currently selected background
  color.

  @param  Private                 Text Out Splitter pointer.

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_DEVICE_ERROR        The device had an error and could not complete
                                  the request.
  @retval EFI_UNSUPPORTED         The output device is not in a valid text mode.

**/
EFI_STATUS
DevNullTextOutClearScreen (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private
  )
{
  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     = L' ';
      *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);
}


/**
  Sets the current coordinates of the cursor position.

  @param  Private                 Text Out Splitter pointer.
  @param  Column                  
  @param  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 ().

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_DEVICE_ERROR        The device had an error and could not complete
                                  the request.
  @retval EFI_UNSUPPORTED         The output device is not in a valid text mode, or
                                  the cursor position is invalid for the current
                                  mode.

**/
EFI_STATUS
DevNullTextOutSetCursorPosition (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,
  IN  UINTN                           Column,
  IN  UINTN                           Row
  )
{
  //
  // 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;
}


/**
  Set cursor visibility property.

  @param  Private                 Text Out Splitter pointer.
  @param  Visible                 If TRUE, the cursor is set to be visible, If
                                  FALSE, the cursor is set to be invisible.

  @retval EFI_SUCCESS             Returns always.

**/
EFI_STATUS
DevNullTextOutEnableCursor (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,
  IN  BOOLEAN                         Visible
  )
{
  Private->TextOutMode.CursorVisible = Visible;

  return EFI_SUCCESS;
}


/**
  Take the DevNull TextOut device and update the Simple Text Out on every
  UGA device.

  @param  Private                 Text Out Splitter pointer.

  @retval EFI_SUCCESS             The request is valid.
  @retval other                   Return status of TextOut->OutputString ()

**/
EFI_STATUS
DevNullSyncStdOut (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private
  )
{
  EFI_STATUS                       Status;
  EFI_STATUS                       ReturnStatus;
  UINTN                            Row;
  UINTN                            Column;
  UINTN                            List;
  UINTN                            MaxColumn;
  UINTN                            CurrentColumn;
  UINTN                            StartRow;
  UINTN                            StartColumn;
  INT32                            StartAttribute;
  BOOLEAN                          StartCursorState;
  CHAR16                           *Screen;
  CHAR16                           *Str;
  CHAR16                           *Buffer;
  CHAR16                           *BufferTail;
  CHAR16                           *ScreenStart;
  INT32                            CurrentAttribute;
  INT32                            *Attributes;
  EFI_SIMPLE_TEXT_OUTPUT_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 GOP/UGA devices
    //
    if ((Private->TextOutList[List].GraphicsOutput != NULL) || (Private->TextOutList[List].UgaDraw != NULL)) {
      Sto->EnableCursor (Sto, FALSE);
      Sto->ClearScreen (Sto);
    }
  }

  ReturnStatus  = EFI_SUCCESS;
  Screen        = Private->DevNullScreen;
  Attributes    = Private->DevNullAttributes;
  MaxColumn     = Private->DevNullColumns;

  Buffer        = AllocateZeroPool ((MaxColumn + 1) * sizeof (CHAR16));
  if (Buffer == NULL) {
    return ReturnStatus;
  }

  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] > 0) {
        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, BufferTail = Buffer; *Str != 0; Str++, Column++) {

          if (Attributes[Column] != CurrentAttribute) {
            Column--;
            break;
          }

          *BufferTail = *Str;
          BufferTail++;
          if ((Attributes[Column] & EFI_WIDE_ATTRIBUTE) != 0) {
            Str++;
            Column++;
          }
        }

        *BufferTail = 0;

        for (List = 0; List < Private->CurrentNumberOfConsoles; List++) {

          Sto = Private->TextOutList[List].TextOut;

          //
          // Skip non GOP/UGA devices
          //
          if ((Private->TextOutList[List].GraphicsOutput != NULL) || (Private->TextOutList[List].UgaDraw != NULL)) {
            Sto->SetAttribute (Sto, CurrentAttribute);
            Sto->SetCursorPosition (Sto, CurrentColumn, Row);
            Status = Sto->OutputString (Sto, Buffer);
            if (EFI_ERROR (Status)) {
              ReturnStatus = Status;
            }
          }
        }

      }

      Column++;
    }
  }
  //
  // Restore the devices Attributes, Cursor enable state and location
  //
  for (List = 0; List < Private->CurrentNumberOfConsoles; List++) {
    Sto = Private->TextOutList[List].TextOut;

    //
    // Skip non GOP/UGA devices
    //
    if ((Private->TextOutList[List].GraphicsOutput != NULL) || (Private->TextOutList[List].UgaDraw != NULL)) {
      Sto->SetAttribute (Sto, StartAttribute);
      Sto->SetCursorPosition (Sto, StartColumn, StartRow);
      Status = Sto->EnableCursor (Sto, StartCursorState);
      if (EFI_ERROR (Status)) {
        ReturnStatus = Status;
      }
    }
  }

  FreePool (Buffer);

  return ReturnStatus;
}
