--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. 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
+ UnixUgaScreen.c\r
+\r
+Abstract:\r
+\r
+ This file produces the graphics abstration of UGA. It is called by \r
+ UnixUgaDriver.c file which deals with the EFI 1.1 driver model. \r
+ This file just does graphics.\r
+\r
+--*/\r
+\r
+#include "UnixUga.h"\r
+\r
+EFI_UNIX_THUNK_PROTOCOL *mUnix;\r
+static EFI_EVENT mUgaScreenExitBootServicesEvent;\r
+\r
+STATIC
+EFI_STATUS\r
+UnixUgaStartWindow (\r
+ IN UGA_PRIVATE_DATA *Private,\r
+ IN UINT32 HorizontalResolution,\r
+ IN UINT32 VerticalResolution,\r
+ IN UINT32 ColorDepth,\r
+ IN UINT32 RefreshRate\r
+ );\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+KillNtUgaThread (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ );\r
+\r
+//\r
+// UGA Protocol Member Functions\r
+//\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UnixUgaGetMode (\r
+ EFI_UGA_DRAW_PROTOCOL *This,\r
+ UINT32 *HorizontalResolution,\r
+ UINT32 *VerticalResolution,\r
+ UINT32 *ColorDepth,\r
+ UINT32 *RefreshRate\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Return the current video mode information.\r
+\r
+ Arguments:\r
+ This - Protocol instance pointer.\r
+ HorizontalResolution - Current video horizontal resolution in pixels\r
+ VerticalResolution - Current video Vertical resolution in pixels\r
+ ColorDepth - Current video color depth in bits per pixel\r
+ RefreshRate - Current video refresh rate in Hz.\r
+\r
+ Returns:\r
+ EFI_SUCCESS - Mode information returned.\r
+ EFI_NOT_STARTED - Video display is not initialized. Call SetMode () \r
+ EFI_INVALID_PARAMETER - One of the input args was NULL.\r
+\r
+--*/\r
+// TODO: ADD IN/OUT description here\r
+{\r
+ UGA_PRIVATE_DATA *Private;\r
+\r
+ Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+ if (Private->HardwareNeedsStarting) {\r
+ return EFI_NOT_STARTED;\r
+ }\r
+\r
+ if ((HorizontalResolution == NULL) ||\r
+ (VerticalResolution == NULL) ||\r
+ (ColorDepth == NULL) ||\r
+ (RefreshRate == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *HorizontalResolution = Private->HorizontalResolution;\r
+ *VerticalResolution = Private->VerticalResolution;\r
+ *ColorDepth = Private->ColorDepth;\r
+ *RefreshRate = Private->RefreshRate;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UnixUgaSetMode (\r
+ EFI_UGA_DRAW_PROTOCOL *This,\r
+ UINT32 HorizontalResolution,\r
+ UINT32 VerticalResolution,\r
+ UINT32 ColorDepth,\r
+ UINT32 RefreshRate\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Return the current video mode information.\r
+\r
+ Arguments:\r
+ This - Protocol instance pointer.\r
+ HorizontalResolution - Current video horizontal resolution in pixels\r
+ VerticalResolution - Current video Vertical resolution in pixels\r
+ ColorDepth - Current video color depth in bits per pixel\r
+ RefreshRate - Current video refresh rate in Hz.\r
+\r
+ Returns:\r
+ EFI_SUCCESS - Mode information returned.\r
+ EFI_NOT_STARTED - Video display is not initialized. Call SetMode () \r
+ EFI_INVALID_PARAMETER - One of the input args was NULL.\r
+\r
+--*/\r
+// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+// TODO: ADD IN/OUT description here\r
+{\r
+ EFI_STATUS Status;\r
+ UGA_PRIVATE_DATA *Private;\r
+ EFI_UGA_PIXEL Fill;\r
+\r
+ Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+ if (Private->HardwareNeedsStarting) {\r
+ Status = UnixUgaStartWindow (\r
+ Private,\r
+ HorizontalResolution,\r
+ VerticalResolution,\r
+ ColorDepth,\r
+ RefreshRate\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Private->HardwareNeedsStarting = FALSE;\r
+ }
+ Status = Private->UgaIo->UgaSize(Private->UgaIo,
+ HorizontalResolution,
+ VerticalResolution);
+\r
+ Private->HorizontalResolution = HorizontalResolution;\r
+ Private->VerticalResolution = VerticalResolution;\r
+ Private->ColorDepth = ColorDepth;\r
+ Private->RefreshRate = RefreshRate;\r
+\r
+ Fill.Red = 0x00;\r
+ Fill.Green = 0x00;\r
+ Fill.Blue = 0x00;\r
+ This->Blt (\r
+ This,\r
+ &Fill,\r
+ EfiUgaVideoFill,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ HorizontalResolution,\r
+ VerticalResolution,\r
+ HorizontalResolution * sizeof (EFI_UGA_PIXEL)\r
+ );\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UnixUgaBlt (\r
+ IN EFI_UGA_DRAW_PROTOCOL *This,\r
+ IN EFI_UGA_PIXEL *BltBuffer, OPTIONAL\r
+ IN EFI_UGA_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
+\r
+ Routine Description:\r
+ Blt pixels from the rectangle (Width X Height) formed by the BltBuffer\r
+ onto the graphics screen starting a location (X, Y). (0, 0) is defined as\r
+ the upper left hand side of the screen. (X, Y) can be outside of the \r
+ current screen geometry and the BltBuffer will be cliped when it is \r
+ displayed. X and Y can be negative or positive. If Width or Height is \r
+ bigger than the current video screen the image will be clipped.\r
+\r
+ Arguments:\r
+ This - Protocol instance pointer.\r
+ X - X location on graphics screen. \r
+ Y - Y location on the graphics screen.\r
+ Width - Width of BltBuffer.\r
+ Height - Hight of BltBuffer\r
+ BltOperation - Operation to perform on BltBuffer and video memory\r
+ BltBuffer - Buffer containing data to blt into video buffer. This \r
+ buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)\r
+ SourceX - If the BltOperation is a EfiCopyBlt this is the source\r
+ of the copy. For other BLT operations this argument is not\r
+ used.\r
+ SourceX - If the BltOperation is a EfiCopyBlt this is the source\r
+ of the copy. For other BLT operations this argument is not\r
+ used.\r
+ \r
+ Returns:\r
+ EFI_SUCCESS - The palette is updated with PaletteArray.\r
+ EFI_INVALID_PARAMETER - BltOperation is not valid.\r
+ EFI_DEVICE_ERROR - A hardware error occured writting to the video \r
+ buffer.\r
+\r
+--*/\r
+// TODO: SourceY - add argument and description to function comment\r
+// TODO: DestinationX - add argument and description to function comment\r
+// TODO: DestinationY - add argument and description to function comment\r
+// TODO: Delta - add argument and description to function comment\r
+{\r
+ UGA_PRIVATE_DATA *Private;\r
+ EFI_TPL OriginalTPL;\r
+ EFI_STATUS Status;\r
+\r
+ Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+ if ((BltOperation < 0) || (BltOperation >= EfiUgaBltMax)) {\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 (EFI_TPL_NOTIFY);\r
+\r
+ Status = Private->UgaIo->UgaBlt (Private->UgaIo,
+ BltBuffer,
+ BltOperation,
+ SourceX, SourceY,
+ DestinationX, DestinationY,
+ Width, Height,
+ Delta);
+\r
+ gBS->RestoreTPL (OriginalTPL);\r
+\r
+ return Status;
+}\r
+\r
+\r
+//\r
+// Construction and Destruction functions\r
+//\r
+\r
+EFI_STATUS\r
+UnixUgaSupported (\r
+ IN EFI_UNIX_IO_PROTOCOL *UnixIo\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: UnixIo - add argument and description to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\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 (UnixIo->TypeGuid, &gEfiUnixUgaGuid)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+STATIC
+EFI_STATUS\r
+UnixUgaStartWindow (\r
+ IN UGA_PRIVATE_DATA *Private,\r
+ IN UINT32 HorizontalResolution,\r
+ IN UINT32 VerticalResolution,\r
+ IN UINT32 ColorDepth,\r
+ IN UINT32 RefreshRate\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Private - TODO: add argument description\r
+ HorizontalResolution - TODO: add argument description\r
+ VerticalResolution - TODO: add argument description\r
+ ColorDepth - TODO: add argument description\r
+ RefreshRate - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ mUnix = Private->UnixThunk;\r
+\r
+ Private->HorizontalResolution = HorizontalResolution;\r
+ Private->VerticalResolution = VerticalResolution;\r
+\r
+ //\r
+ // Register to be notified on exit boot services so we can destroy the window.\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,\r
+ EFI_TPL_CALLBACK,\r
+ KillNtUgaThread,\r
+ Private,\r
+ &mUgaScreenExitBootServicesEvent\r
+ );\r
+\r
+ Status = Private->UnixThunk->UgaCreate(&Private->UgaIo, Private->WindowName);
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+UnixUgaConstructor (\r
+ UGA_PRIVATE_DATA *Private\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Private - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ Private->UgaDraw.GetMode = UnixUgaGetMode;\r
+ Private->UgaDraw.SetMode = UnixUgaSetMode;\r
+ Private->UgaDraw.Blt = UnixUgaBlt;\r
+\r
+ Private->HardwareNeedsStarting = TRUE;\r
+ Private->UgaIo = NULL;
+\r
+ UnixUgaInitializeSimpleTextInForWindow (Private);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+UnixUgaDestructor (\r
+ UGA_PRIVATE_DATA *Private\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Private - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ if (!Private->HardwareNeedsStarting) {\r
+ Private->UgaIo->UgaClose(Private->UgaIo);
+ Private->UgaIo = NULL;
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+KillNtUgaThread (\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 UnixUgaDestructor().\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
+ EFI_STATUS Status;\r
+ Status = UnixUgaDestructor (Context);\r
+}\r