]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmulatorPkg/EmuGopDxe/GopScreen.c
EmulatorPkg: formalize line endings
[mirror_edk2.git] / EmulatorPkg / EmuGopDxe / GopScreen.c
index aa21fa68def6c043d6316970ba965b22834330be..761d945c15520bbd22ec3f5f8429847c4681d04e 100644 (file)
-/*++ @file
-
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
-Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved.
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-Module Name:
-
-    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];
-  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;
-
-  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;
-  }
-
-
-  Status = Private->EmuGraphicsWindow->Size(
-                            Private->EmuGraphicsWindow,
-                            ModeData->HorizontalResolution,
-                            ModeData->VerticalResolution
-                            );
-
-
-  Fill.Red                      = 0x7f;
-  Fill.Green                    = 0x7F;
-  Fill.Blue                     = 0x7f;
-  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 occured 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);
-}
-
+/*++ @file\r
+\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved.\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+    EmuGopScreen.c\r
+\r
+Abstract:\r
+\r
+  This file produces the graphics abstration of UGA. It is called by\r
+  EmuGopDriver.c file which deals with the EFI 1.1 driver model.\r
+  This file just does graphics.\r
+\r
+**/\r
+\r
+#include "Gop.h"\r
+\r
+\r
+EFI_EVENT               mGopScreenExitBootServicesEvent;\r
+\r
+GOP_MODE_DATA mGopModeData[] = {\r
+    { 800,  600, 0, 0 },\r
+    { 640,  480, 0, 0 },\r
+    { 720,  400, 0, 0 },\r
+    {1024,  768, 0, 0 },\r
+    {1280, 1024, 0, 0 }\r
+    };\r
+\r
+\r
+/**\r
+  Returns information for an available graphics mode that the graphics device\r
+  and the set of active video output devices supports.\r
+\r
+  @param  This                  The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.\r
+  @param  ModeNumber            The mode number to return information on.\r
+  @param  SizeOfInfo            A pointer to the size, in bytes, of the Info buffer.\r
+  @param  Info                  A pointer to callee allocated buffer that returns information about ModeNumber.\r
+\r
+  @retval EFI_SUCCESS           Mode information returned.\r
+  @retval EFI_BUFFER_TOO_SMALL  The Info buffer was too small.\r
+  @retval EFI_DEVICE_ERROR      A hardware error occurred trying to retrieve the video mode.\r
+  @retval EFI_NOT_STARTED       Video display is not initialized. Call SetMode ()\r
+  @retval EFI_INVALID_PARAMETER One of the input args was NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EmuGopQuerytMode (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,\r
+  IN  UINT32                                ModeNumber,\r
+  OUT UINTN                                 *SizeOfInfo,\r
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info\r
+  )\r
+{\r
+  GOP_PRIVATE_DATA  *Private;\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if (Info == NULL || SizeOfInfo == NULL || (UINTN) ModeNumber >= This->Mode->MaxMode) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+  if (*Info == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+\r
+  (*Info)->Version = 0;\r
+  (*Info)->HorizontalResolution = Private->ModeData[ModeNumber].HorizontalResolution;\r
+  (*Info)->VerticalResolution   = Private->ModeData[ModeNumber].VerticalResolution;\r
+  (*Info)->PixelFormat = PixelBltOnly;\r
+  (*Info)->PixelsPerScanLine = (*Info)->HorizontalResolution;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Set the video device into the specified mode and clears the visible portions of\r
+  the output display to black.\r
+\r
+  @param  This              The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.\r
+  @param  ModeNumber        Abstraction that defines the current video mode.\r
+\r
+  @retval EFI_SUCCESS       The graphics mode specified by ModeNumber was selected.\r
+  @retval EFI_DEVICE_ERROR  The device had an error and could not complete the request.\r
+  @retval EFI_UNSUPPORTED   ModeNumber is not supported by this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EmuGopSetMode (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL  *This,\r
+  IN  UINT32                        ModeNumber\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  GOP_PRIVATE_DATA                *Private;\r
+  GOP_MODE_DATA                   *ModeData;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   Fill;\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if (ModeNumber >= This->Mode->MaxMode) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  ModeData = &Private->ModeData[ModeNumber];\r
+  This->Mode->Mode = ModeNumber;\r
+  Private->GraphicsOutput.Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;\r
+  Private->GraphicsOutput.Mode->Info->VerticalResolution = ModeData->VerticalResolution;\r
+  Private->GraphicsOutput.Mode->Info->PixelsPerScanLine = ModeData->HorizontalResolution;\r
+\r
+  if (Private->HardwareNeedsStarting) {\r
+    Status = EmuGopStartWindow (\r
+              Private,\r
+              ModeData->HorizontalResolution,\r
+              ModeData->VerticalResolution,\r
+              ModeData->ColorDepth,\r
+              ModeData->RefreshRate\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+\r
+    Private->HardwareNeedsStarting = FALSE;\r
+  }\r
+\r
+\r
+  Status = Private->EmuGraphicsWindow->Size(\r
+                            Private->EmuGraphicsWindow,\r
+                            ModeData->HorizontalResolution,\r
+                            ModeData->VerticalResolution\r
+                            );\r
+\r
+\r
+  Fill.Red                      = 0x7f;\r
+  Fill.Green                    = 0x7F;\r
+  Fill.Blue                     = 0x7f;\r
+  This->Blt (\r
+          This,\r
+          &Fill,\r
+          EfiBltVideoFill,\r
+          0,\r
+          0,\r
+          0,\r
+          0,\r
+          ModeData->HorizontalResolution,\r
+          ModeData->VerticalResolution,\r
+          ModeData->HorizontalResolution * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+          );\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer.\r
+\r
+  @param  This         Protocol instance pointer.\r
+  @param  BltBuffer    Buffer containing data to blit into video buffer. This\r
+                       buffer has a size of Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+  @param  BltOperation Operation to perform on BlitBuffer and video memory\r
+  @param  SourceX      X coordinate of source for the BltBuffer.\r
+  @param  SourceY      Y coordinate of source for the BltBuffer.\r
+  @param  DestinationX X coordinate of destination for the BltBuffer.\r
+  @param  DestinationY Y coordinate of destination for the BltBuffer.\r
+  @param  Width        Width of rectangle in BltBuffer in pixels.\r
+  @param  Height       Hight of rectangle in BltBuffer in pixels.\r
+  @param  Delta        OPTIONAL\r
+\r
+  @retval EFI_SUCCESS           The Blt operation completed.\r
+  @retval EFI_INVALID_PARAMETER BltOperation is not valid.\r
+  @retval EFI_DEVICE_ERROR      A hardware error occured writting to the video buffer.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EmuGopBlt (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL            *This,\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL           *BltBuffer,   OPTIONAL\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION       BltOperation,\r
+  IN  UINTN                                   SourceX,\r
+  IN  UINTN                                   SourceY,\r
+  IN  UINTN                                   DestinationX,\r
+  IN  UINTN                                   DestinationY,\r
+  IN  UINTN                                   Width,\r
+  IN  UINTN                                   Height,\r
+  IN  UINTN                                   Delta         OPTIONAL\r
+  )\r
+{\r
+  GOP_PRIVATE_DATA  *Private;\r
+  EFI_TPL           OriginalTPL;\r
+  EFI_STATUS        Status;\r
+  EMU_GRAPHICS_WINDOWS__BLT_ARGS      GopBltArgs;\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if ((UINT32)BltOperation >= EfiGraphicsOutputBltOperationMax) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Width == 0 || Height == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // If Delta is zero, then the entire BltBuffer is being used, so Delta\r
+  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width pixels size,\r
+  // the number of bytes in each row can be computed.\r
+  //\r
+  if (Delta == 0) {\r
+    Delta = Width * sizeof (EFI_UGA_PIXEL);\r
+  }\r
+\r
+  //\r
+  // We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
+  // We would not want a timer based event (Cursor, ...) to come in while we are\r
+  // doing this operation.\r
+  //\r
+  OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+  //\r
+  // Pack UGA Draw protocol parameters to EMU_GRAPHICS_WINDOWS__BLT_ARGS structure to adapt to\r
+  // GopBlt() API of Unix UGA IO protocol.\r
+  //\r
+  GopBltArgs.DestinationX = DestinationX;\r
+  GopBltArgs.DestinationY = DestinationY;\r
+  GopBltArgs.Height       = Height;\r
+  GopBltArgs.Width        = Width;\r
+  GopBltArgs.SourceX      = SourceX;\r
+  GopBltArgs.SourceY      = SourceY;\r
+  GopBltArgs.Delta        = Delta;\r
+  Status = Private->EmuGraphicsWindow->Blt (\r
+                            Private->EmuGraphicsWindow,\r
+                            (EFI_UGA_PIXEL *)BltBuffer,\r
+                            (EFI_UGA_BLT_OPERATION)BltOperation,\r
+                            &GopBltArgs\r
+                            );\r
+\r
+  gBS->RestoreTPL (OriginalTPL);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+//\r
+// Construction and Destruction functions\r
+//\r
+\r
+EFI_STATUS\r
+EmuGopSupported (\r
+  IN  EMU_IO_THUNK_PROTOCOL  *EmuIoThunk\r
+  )\r
+{\r
+  //\r
+  // Check to see if the IO abstraction represents a device type we support.\r
+  //\r
+  // This would be replaced a check of PCI subsystem ID, etc.\r
+  //\r
+  if (!CompareGuid (EmuIoThunk->Protocol, &gEmuGraphicsWindowProtocolGuid)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EmuGopStartWindow (\r
+  IN  GOP_PRIVATE_DATA    *Private,\r
+  IN  UINT32              HorizontalResolution,\r
+  IN  UINT32              VerticalResolution,\r
+  IN  UINT32              ColorDepth,\r
+  IN  UINT32              RefreshRate\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+\r
+  //\r
+  // Register to be notified on exit boot services so we can destroy the window.\r
+  //\r
+  Status = gBS->CreateEvent (\r
+                  EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
+                  TPL_CALLBACK,\r
+                  ShutdownGopEvent,\r
+                  Private,\r
+                  &mGopScreenExitBootServicesEvent\r
+                  );\r
+\r
+  Status = Private->EmuIoThunk->Open (Private->EmuIoThunk);\r
+  if (!EFI_ERROR (Status)) {\r
+    Private->EmuGraphicsWindow = Private->EmuIoThunk->Interface;\r
+\r
+    // Register callback to support RegisterKeyNotify()\r
+    Status  = Private->EmuGraphicsWindow->RegisterKeyNotify (\r
+                                            Private->EmuGraphicsWindow,\r
+                                            GopPrivateMakeCallbackFunction,\r
+                                            GopPrivateBreakCallbackFunction,\r
+                                            Private\r
+                                            );\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EmuGopConstructor (\r
+  GOP_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  Private->ModeData = mGopModeData;\r
+\r
+  Private->GraphicsOutput.QueryMode      = EmuGopQuerytMode;\r
+  Private->GraphicsOutput.SetMode        = EmuGopSetMode;\r
+  Private->GraphicsOutput.Blt            = EmuGopBlt;\r
+\r
+  //\r
+  // Allocate buffer for Graphics Output Protocol mode information\r
+  //\r
+  Private->GraphicsOutput.Mode = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE));\r
+  if (Private->GraphicsOutput.Mode == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  Private->GraphicsOutput.Mode->Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+  if (Private->GraphicsOutput.Mode->Info == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Private->GraphicsOutput.Mode->MaxMode = sizeof(mGopModeData) / sizeof(GOP_MODE_DATA);\r
+  //\r
+  // Till now, we have no idea about the window size.\r
+  //\r
+  Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;\r
+  Private->GraphicsOutput.Mode->Info->Version = 0;\r
+  Private->GraphicsOutput.Mode->Info->HorizontalResolution = 0;\r
+  Private->GraphicsOutput.Mode->Info->VerticalResolution = 0;\r
+  Private->GraphicsOutput.Mode->Info->PixelFormat = PixelBltOnly;\r
+  Private->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+  Private->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;\r
+  Private->GraphicsOutput.Mode->FrameBufferSize = 0;\r
+\r
+  Private->HardwareNeedsStarting  = TRUE;\r
+  Private->EmuGraphicsWindow                  = NULL;\r
+\r
+  EmuGopInitializeSimpleTextInForWindow (Private);\r
+\r
+  EmuGopInitializeSimplePointerForWindow (Private);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EmuGopDestructor (\r
+  GOP_PRIVATE_DATA     *Private\r
+  )\r
+{\r
+  if (!Private->HardwareNeedsStarting) {\r
+    Private->EmuIoThunk->Close (Private->EmuIoThunk);\r
+    Private->EmuGraphicsWindow = NULL;\r
+  }\r
+\r
+  //\r
+  // Free graphics output protocol occupied resource\r
+  //\r
+  if (Private->GraphicsOutput.Mode != NULL) {\r
+    if (Private->GraphicsOutput.Mode->Info != NULL) {\r
+      FreePool (Private->GraphicsOutput.Mode->Info);\r
+    }\r
+    FreePool (Private->GraphicsOutput.Mode);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+VOID\r
+EFIAPI\r
+ShutdownGopEvent (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This is the UGA screen's callback notification function for exit-boot-services.\r
+  All we do here is call EmuGopDestructor().\r
+\r
+Arguments:\r
+\r
+  Event   - not used\r
+  Context - pointer to the Private structure.\r
+\r
+Returns:\r
+\r
+  None.\r
+\r
+**/\r
+{\r
+  EmuGopDestructor (Context);\r
+}\r
+\r