/*++ @file

Copyright (c) 2006 - 2022, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

Module Name:

    EmuGopScreen.c

Abstract:

  This file produces the graphics abstration of UGA. It is called by
  EmuGopDriver.c file which deals with the EFI 1.1 driver model.
  This file just does graphics.

**/

#include "Gop.h"

EFI_EVENT  mGopScreenExitBootServicesEvent;

GOP_MODE_DATA  mGopModeData[] = {
  { 800,  600,  0, 0 },
  { 640,  480,  0, 0 },
  { 720,  400,  0, 0 },
  { 1024, 768,  0, 0 },
  { 1280, 1024, 0, 0 }
};

/**
  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.

**/
EFI_STATUS
EFIAPI
EmuGopQuerytMode (
  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
  IN  UINT32                                ModeNumber,
  OUT UINTN                                 *SizeOfInfo,
  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info
  )
{
  GOP_PRIVATE_DATA  *Private;

  Private = GOP_PRIVATE_DATA_FROM_THIS (This);

  if ((Info == NULL) || (SizeOfInfo == NULL) || ((UINTN)ModeNumber >= This->Mode->MaxMode)) {
    return EFI_INVALID_PARAMETER;
  }

  *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
  if (*Info == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);

  (*Info)->Version              = 0;
  (*Info)->HorizontalResolution = Private->ModeData[ModeNumber].HorizontalResolution;
  (*Info)->VerticalResolution   = Private->ModeData[ModeNumber].VerticalResolution;
  (*Info)->PixelFormat          = PixelBltOnly;
  (*Info)->PixelsPerScanLine    = (*Info)->HorizontalResolution;

  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.

**/
EFI_STATUS
EFIAPI
EmuGopSetMode (
  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL  *This,
  IN  UINT32                        ModeNumber
  )
{
  EFI_STATUS                     Status;
  GOP_PRIVATE_DATA               *Private;
  GOP_MODE_DATA                  *ModeData;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Fill;

  Private = GOP_PRIVATE_DATA_FROM_THIS (This);

  if (ModeNumber >= This->Mode->MaxMode) {
    return EFI_UNSUPPORTED;
  }

  ModeData = &Private->ModeData[ModeNumber];

  if (Private->HardwareNeedsStarting) {
    Status = EmuGopStartWindow (
               Private,
               ModeData->HorizontalResolution,
               ModeData->VerticalResolution,
               ModeData->ColorDepth,
               ModeData->RefreshRate
               );
    if (EFI_ERROR (Status)) {
      return EFI_DEVICE_ERROR;
    }

    Private->HardwareNeedsStarting = FALSE;
  }

  This->Mode->Mode                                         = ModeNumber;
  Private->GraphicsOutput.Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;
  Private->GraphicsOutput.Mode->Info->VerticalResolution   = ModeData->VerticalResolution;
  Private->GraphicsOutput.Mode->Info->PixelsPerScanLine    = ModeData->HorizontalResolution;

  Status = Private->EmuGraphicsWindow->Size (
                                         Private->EmuGraphicsWindow,
                                         ModeData->HorizontalResolution,
                                         ModeData->VerticalResolution
                                         );

  Fill.Red   = 0;
  Fill.Green = 0;
  Fill.Blue  = 0;
  This->Blt (
          This,
          &Fill,
          EfiBltVideoFill,
          0,
          0,
          0,
          0,
          ModeData->HorizontalResolution,
          ModeData->VerticalResolution,
          ModeData->HorizontalResolution * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
          );
  return EFI_SUCCESS;
}

/**
  Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer.

  @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 occurred writting to the video buffer.

**/
EFI_STATUS
EFIAPI
EmuGopBlt (
  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
  )
{
  GOP_PRIVATE_DATA                *Private;
  EFI_TPL                         OriginalTPL;
  EFI_STATUS                      Status;
  EMU_GRAPHICS_WINDOWS__BLT_ARGS  GopBltArgs;

  Private = GOP_PRIVATE_DATA_FROM_THIS (This);

  if ((UINT32)BltOperation >= EfiGraphicsOutputBltOperationMax) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Width == 0) || (Height == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // If Delta is zero, then the entire BltBuffer is being used, so Delta
  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width pixels size,
  // the number of bytes in each row can be computed.
  //
  if (Delta == 0) {
    Delta = Width * sizeof (EFI_UGA_PIXEL);
  }

  //
  // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
  // We would not want a timer based event (Cursor, ...) to come in while we are
  // doing this operation.
  //
  OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);

  //
  // Pack UGA Draw protocol parameters to EMU_GRAPHICS_WINDOWS__BLT_ARGS structure to adapt to
  // GopBlt() API of Unix UGA IO protocol.
  //
  GopBltArgs.DestinationX = DestinationX;
  GopBltArgs.DestinationY = DestinationY;
  GopBltArgs.Height       = Height;
  GopBltArgs.Width        = Width;
  GopBltArgs.SourceX      = SourceX;
  GopBltArgs.SourceY      = SourceY;
  GopBltArgs.Delta        = Delta;
  Status                  = Private->EmuGraphicsWindow->Blt (
                                                          Private->EmuGraphicsWindow,
                                                          (EFI_UGA_PIXEL *)BltBuffer,
                                                          (EFI_UGA_BLT_OPERATION)BltOperation,
                                                          &GopBltArgs
                                                          );

  gBS->RestoreTPL (OriginalTPL);

  return Status;
}

//
// Construction and Destruction functions
//

EFI_STATUS
EmuGopSupported (
  IN  EMU_IO_THUNK_PROTOCOL  *EmuIoThunk
  )
{
  //
  // Check to see if the IO abstraction represents a device type we support.
  //
  // This would be replaced a check of PCI subsystem ID, etc.
  //
  if (!CompareGuid (EmuIoThunk->Protocol, &gEmuGraphicsWindowProtocolGuid)) {
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
EmuGopStartWindow (
  IN  GOP_PRIVATE_DATA  *Private,
  IN  UINT32            HorizontalResolution,
  IN  UINT32            VerticalResolution,
  IN  UINT32            ColorDepth,
  IN  UINT32            RefreshRate
  )
{
  EFI_STATUS  Status;

  //
  // Register to be notified on exit boot services so we can destroy the window.
  //
  Status = gBS->CreateEvent (
                  EVT_SIGNAL_EXIT_BOOT_SERVICES,
                  TPL_CALLBACK,
                  ShutdownGopEvent,
                  Private,
                  &mGopScreenExitBootServicesEvent
                  );

  Status = Private->EmuIoThunk->Open (Private->EmuIoThunk);
  if (!EFI_ERROR (Status)) {
    Private->EmuGraphicsWindow = Private->EmuIoThunk->Interface;

    // Register callback to support RegisterKeyNotify()
    Status = Private->EmuGraphicsWindow->RegisterKeyNotify (
                                           Private->EmuGraphicsWindow,
                                           GopPrivateMakeCallbackFunction,
                                           GopPrivateBreakCallbackFunction,
                                           Private
                                           );
    ASSERT_EFI_ERROR (Status);
  }

  return Status;
}

EFI_STATUS
EmuGopConstructor (
  GOP_PRIVATE_DATA  *Private
  )
{
  Private->ModeData = mGopModeData;

  Private->GraphicsOutput.QueryMode = EmuGopQuerytMode;
  Private->GraphicsOutput.SetMode   = EmuGopSetMode;
  Private->GraphicsOutput.Blt       = EmuGopBlt;

  //
  // Allocate buffer for Graphics Output Protocol mode information
  //
  Private->GraphicsOutput.Mode = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE));
  if (Private->GraphicsOutput.Mode == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Private->GraphicsOutput.Mode->Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
  if (Private->GraphicsOutput.Mode->Info == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Private->GraphicsOutput.Mode->MaxMode = sizeof (mGopModeData) / sizeof (GOP_MODE_DATA);
  //
  // Till now, we have no idea about the window size.
  //
  Private->GraphicsOutput.Mode->Mode                       = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
  Private->GraphicsOutput.Mode->Info->Version              = 0;
  Private->GraphicsOutput.Mode->Info->HorizontalResolution = 0;
  Private->GraphicsOutput.Mode->Info->VerticalResolution   = 0;
  Private->GraphicsOutput.Mode->Info->PixelFormat          = PixelBltOnly;
  Private->GraphicsOutput.Mode->SizeOfInfo                 = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
  Private->GraphicsOutput.Mode->FrameBufferBase            = (EFI_PHYSICAL_ADDRESS)(UINTN)NULL;
  Private->GraphicsOutput.Mode->FrameBufferSize            = 0;

  Private->HardwareNeedsStarting = TRUE;
  Private->EmuGraphicsWindow     = NULL;

  EmuGopInitializeSimpleTextInForWindow (Private);

  EmuGopInitializeSimplePointerForWindow (Private);

  return EFI_SUCCESS;
}

EFI_STATUS
EmuGopDestructor (
  GOP_PRIVATE_DATA  *Private
  )
{
  if (!Private->HardwareNeedsStarting) {
    Private->EmuIoThunk->Close (Private->EmuIoThunk);
    Private->EmuGraphicsWindow = NULL;
  }

  //
  // Free graphics output protocol occupied resource
  //
  if (Private->GraphicsOutput.Mode != NULL) {
    if (Private->GraphicsOutput.Mode->Info != NULL) {
      FreePool (Private->GraphicsOutput.Mode->Info);
    }

    FreePool (Private->GraphicsOutput.Mode);
  }

  return EFI_SUCCESS;
}

VOID
EFIAPI
ShutdownGopEvent (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )

/*++

Routine Description:

  This is the UGA screen's callback notification function for exit-boot-services.
  All we do here is call EmuGopDestructor().

Arguments:

  Event   - not used
  Context - pointer to the Private structure.

Returns:

  None.

**/
{
  EmuGopDestructor (Context);
}
