/** @file
  Support for Graphics output spliter.
  
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
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 };

/**
  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_INVALID_PARAMETER One of the input args was NULL.
  @retval EFI_OUT_OF_RESOURCES  No resource available.

**/
EFI_STATUS
EFIAPI
ConSplitterGraphicsOutputQueryMode (
  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;
  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
  EFI_STATUS                      Status;
  UINTN                           Index;

  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);

  GraphicsOutput = NULL;
  
  if (Private->CurrentNumberOfGraphicsOutput == 1) {
    //
    // Find the only one GraphicsOutput.
    //
    for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
      GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
      if (GraphicsOutput != NULL) {
        break;
      }
    }
  }
  
  if (GraphicsOutput != NULL) {
    //
    // If only one physical GOP device exist, return its information.
    //
    Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) ModeNumber, SizeOfInfo, Info);
    return Status;
  } else {
    //
    // If 2 more phyiscal GOP device exist or GOP protocol does not exist, 
    // return GOP information (PixelFormat is PixelBltOnly) created in ConSplitterAddGraphicsOutputMode ().
    //
    *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
ConSplitterGraphicsOutputSetMode (
  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;
  EFI_GRAPHICS_OUTPUT_PROTOCOL           *GraphicsOutput;
  EFI_GRAPHICS_OUTPUT_PROTOCOL           *PhysicalGraphicsOutput;
  UINTN                                  NumberIndex;
  UINTN                                  SizeOfInfo;
  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   *Info;
  EFI_UGA_DRAW_PROTOCOL                  *UgaDraw;

  if (ModeNumber >= This->Mode->MaxMode) {
    return EFI_UNSUPPORTED;
  }

  Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
  Mode = &Private->GraphicsOutputModeBuffer[ModeNumber];

  ReturnStatus = EFI_SUCCESS;
  GraphicsOutput = NULL;
  PhysicalGraphicsOutput = NULL;
  //
  // return the worst status met
  //
  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
    GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
    if (GraphicsOutput != NULL) {
      PhysicalGraphicsOutput = GraphicsOutput;
      //
      // 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;

  if ((Private->CurrentNumberOfGraphicsOutput == 1) && (PhysicalGraphicsOutput != NULL)) {
    //
    // If only one physical GOP device exist, copy physical information to consplitter.
    //
    CopyMem (This->Mode->Info, PhysicalGraphicsOutput->Mode->Info, PhysicalGraphicsOutput->Mode->SizeOfInfo);
    This->Mode->SizeOfInfo = PhysicalGraphicsOutput->Mode->SizeOfInfo;
    This->Mode->FrameBufferBase = PhysicalGraphicsOutput->Mode->FrameBufferBase;
    This->Mode->FrameBufferSize = PhysicalGraphicsOutput->Mode->FrameBufferSize;
  } else {
    //
    // If 2 more phyiscal GOP device exist or GOP protocol does not exist, 
    // return GOP information (PixelFormat is PixelBltOnly) created in ConSplitterAddGraphicsOutputMode ().
    //
    CopyMem (This->Mode->Info, &Private->GraphicsOutputModeBuffer[ModeNumber], This->Mode->SizeOfInfo);
  }

  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  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
ConSplitterGraphicsOutputBlt (
  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;
  EFI_STATUS                      ReturnStatus;
  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;
  UINTN                           Index;
  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
  EFI_UGA_DRAW_PROTOCOL           *UgaDraw;

  if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) {
    return EFI_INVALID_PARAMETER;
  }
  
  Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

  ReturnStatus = EFI_SUCCESS;

  //
  // 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;
}

/**
  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
ConSplitterUgaDrawGetMode (
  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
ConSplitterUgaDrawSetMode (
  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;
  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);

  ReturnStatus = EFI_SUCCESS;

  //
  // Update the Mode data
  //
  Private->UgaHorizontalResolution  = HorizontalResolution;
  Private->UgaVerticalResolution    = VerticalResolution;
  Private->UgaColorDepth            = ColorDepth;
  Private->UgaRefreshRate           = RefreshRate;

  //
  // 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 == 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  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
ConSplitterUgaDrawBlt (
  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);

  ReturnStatus = EFI_SUCCESS;
  //
  // 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 == EfiUgaVideoToBltBuffer) {
        //
        // 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;
}

/**
  Sets the output device(s) to a specified mode.

  @param  Private                 Text Out Splitter pointer.
  @param  ModeNumber              The mode number to set.

**/
VOID
TextOutSetMode (
  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,
  IN  UINTN                           ModeNumber
  )
{
  //
  // 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.Mode          = (INT32) ModeNumber;
  Private->TextOutMode.CursorColumn  = 0;
  Private->TextOutMode.CursorRow     = 0;
  Private->TextOutMode.CursorVisible = TRUE;

  return;
}
