/** @file\r
- Support for ConsoleControl protocol. Support for Graphics output spliter.\r
- Support for DevNull Console Out. This console uses memory buffers\r
- to represnt the console. It allows a console to start very early and\r
- when a new console is added it is synced up with the current console.\r
+ Support for Graphics output spliter.\r
\r
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>\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
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
\r
**/\r
\r
CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };\r
\r
-\r
-/**\r
- Return the current video mode information. Also returns info about existence\r
- of Graphics Output devices or UGA Draw devices in system, and whether the Std\r
- In device is locked. GopUgaExists and StdInLocked parameters are optional, and\r
- only returned if a non NULL pointer is passed in.\r
-\r
- @param This Protocol instance pointer.\r
- @param Mode Current video mode.\r
- @param GopUgaExists TRUE if GOP Spliter has found a GOP/UGA device\r
- @param StdInLocked TRUE if StdIn device is keyboard locked\r
-\r
- @retval EFI_SUCCESS Video mode information is returned.\r
- @retval EFI_INVALID_PARAMETER Invalid parameters if Mode == NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ConSpliterConsoleControlGetMode (\r
- IN EFI_CONSOLE_CONTROL_PROTOCOL *This,\r
- OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,\r
- OUT BOOLEAN *GopUgaExists,\r
- OUT BOOLEAN *StdInLocked\r
- )\r
-{\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
- UINTN Index;\r
-\r
- Private = CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- if (Mode == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *Mode = Private->ConsoleOutputMode;\r
-\r
- if (GopUgaExists != NULL) {\r
- *GopUgaExists = FALSE;\r
- for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
- if ((Private->TextOutList[Index].GraphicsOutput != NULL) || (Private->TextOutList[Index].UgaDraw != NULL)) {\r
- *GopUgaExists = TRUE;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- if (StdInLocked != NULL) {\r
- *StdInLocked = ConSpliterConssoleControlStdInLocked ();\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Set the current video mode to either text or graphics. Graphics is\r
- for Quiet Boot.\r
-\r
- @param This Console Control Protocol instance pointer.\r
- @param Mode Video mode is to be set.\r
-\r
- @retval EFI_SUCCESS Mode is set successfully.\r
- @retval EFI_INVALID_PARAMETER Mode is not the valid mode value.\r
- @retval EFI_UNSUPPORTED Mode is unsupported by console device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ConSpliterConsoleControlSetMode (\r
- IN EFI_CONSOLE_CONTROL_PROTOCOL *This,\r
- IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode\r
- )\r
-{\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
- UINTN Index;\r
- TEXT_OUT_AND_GOP_DATA *TextAndGop;\r
- BOOLEAN Supported;\r
-\r
- Private = CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- if (Mode >= EfiConsoleControlScreenMaxValue) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Judge current mode with wanted mode at first.\r
- //\r
- if (Private->ConsoleOutputMode == Mode) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Supported = FALSE;\r
- TextAndGop = &Private->TextOutList[0];\r
- for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++, TextAndGop++) {\r
- if ((TextAndGop->GraphicsOutput != NULL) || (TextAndGop->UgaDraw != NULL)) {\r
- Supported = TRUE;\r
- break;\r
- }\r
- }\r
-\r
- if ((!Supported) && (Mode == EfiConsoleControlScreenGraphics)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Private->ConsoleOutputMode = Mode;\r
-\r
- TextAndGop = &Private->TextOutList[0];\r
- for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++, TextAndGop++) {\r
-\r
- TextAndGop->TextOutEnabled = TRUE;\r
- //\r
- // If we are going into Graphics mode disable ConOut to any UGA device\r
- //\r
- if ((Mode == EfiConsoleControlScreenGraphics) &&((TextAndGop->GraphicsOutput != NULL) || (TextAndGop->UgaDraw != NULL))) {\r
- TextAndGop->TextOutEnabled = FALSE;\r
- if (FeaturePcdGet (PcdConOutGopSupport)) {\r
- DevNullGopSync (Private, TextAndGop->GraphicsOutput, TextAndGop->UgaDraw);\r
- } else if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
- DevNullUgaSync (Private, TextAndGop->GraphicsOutput, TextAndGop->UgaDraw);\r
- }\r
- }\r
- }\r
- if (Mode == EfiConsoleControlScreenText) {\r
- DevNullSyncStdOut (Private);\r
- }\r
- return EFI_SUCCESS;\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
@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
@retval EFI_OUT_OF_RESOURCES No resource available.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-ConSpliterGraphicsOutputQueryMode (\r
+ConSplitterGraphicsOutputQueryMode (\r
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
IN UINT32 ModeNumber,\r
OUT UINTN *SizeOfInfo,\r
)\r
{\r
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
\r
if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {\r
return EFI_INVALID_PARAMETER;\r
//\r
Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
\r
- if (Private->HardwareNeedsStarting) {\r
- return EFI_NOT_STARTED;\r
- }\r
+ GraphicsOutput = NULL;\r
\r
- *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
- if (*Info == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
+ if (Private->CurrentNumberOfGraphicsOutput == 1) {\r
+ //\r
+ // Find the only one GraphicsOutput.\r
+ //\r
+ for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
+ GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;\r
+ if (GraphicsOutput != NULL) {\r
+ break;\r
+ }\r
+ }\r
}\r
\r
- *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
-\r
- CopyMem (*Info, &Private->GraphicsOutputModeBuffer[ModeNumber], *SizeOfInfo);\r
+ if (GraphicsOutput != NULL) {\r
+ //\r
+ // If only one physical GOP device exist, return its information.\r
+ //\r
+ Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) ModeNumber, SizeOfInfo, Info);\r
+ return Status;\r
+ } else {\r
+ //\r
+ // If 2 more phyiscal GOP device exist or GOP protocol does not exist,\r
+ // return GOP information (PixelFormat is PixelBltOnly) created in ConSplitterAddGraphicsOutputMode ().\r
+ //\r
+ *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+ if (*Info == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+ CopyMem (*Info, &Private->GraphicsOutputModeBuffer[ModeNumber], *SizeOfInfo);\r
+ }\r
\r
return EFI_SUCCESS;\r
}\r
**/\r
EFI_STATUS\r
EFIAPI\r
-ConSpliterGraphicsOutputSetMode (\r
+ConSplitterGraphicsOutputSetMode (\r
IN EFI_GRAPHICS_OUTPUT_PROTOCOL * This,\r
IN UINT32 ModeNumber\r
)\r
UINTN Index;\r
EFI_STATUS ReturnStatus;\r
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Mode;\r
- UINTN Size;\r
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *PhysicalGraphicsOutput;\r
UINTN NumberIndex;\r
UINTN SizeOfInfo;\r
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
return EFI_UNSUPPORTED;\r
}\r
\r
- if (ModeNumber == This->Mode->Mode) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- ReturnStatus = EFI_SUCCESS;\r
-\r
- //\r
- // Free the old version\r
- //\r
- if (Private->GraphicsOutputBlt != NULL) {\r
- FreePool (Private->GraphicsOutputBlt);\r
- }\r
-\r
- //\r
- // Allocate the virtual Blt buffer\r
- //\r
Mode = &Private->GraphicsOutputModeBuffer[ModeNumber];\r
- Size = Mode->HorizontalResolution * Mode->VerticalResolution * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
- Private->GraphicsOutputBlt = AllocateZeroPool (Size);\r
-\r
- if (Private->GraphicsOutputBlt == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
\r
+ ReturnStatus = EFI_SUCCESS;\r
+ GraphicsOutput = NULL;\r
+ PhysicalGraphicsOutput = NULL;\r
//\r
// return the worst status met\r
//\r
for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;\r
if (GraphicsOutput != NULL) {\r
+ PhysicalGraphicsOutput = GraphicsOutput;\r
//\r
// Find corresponding ModeNumber of this GraphicsOutput instance\r
//\r
\r
This->Mode->Mode = ModeNumber;\r
\r
- CopyMem (This->Mode->Info, &Private->GraphicsOutputModeBuffer[ModeNumber], This->Mode->SizeOfInfo);\r
-\r
- //\r
- // Information is not enough here, so the following items remain unchanged:\r
- // GraphicsOutputMode->Info->Version, GraphicsOutputMode->Info->PixelFormat\r
- // GraphicsOutputMode->SizeOfInfo, GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize\r
- // These items will be initialized/updated when a new GOP device is added into ConsoleSplitter.\r
- //\r
-\r
- Private->HardwareNeedsStarting = FALSE;\r
-\r
- return ReturnStatus;\r
-}\r
-\r
-/**\r
- The following table defines actions for BltOperations.\r
-\r
- EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)\r
- directly to every pixel of the video display rectangle\r
- (DestinationX, DestinationY)\r
- (DestinationX + Width, DestinationY + Height).\r
- Only one pixel will be used from the BltBuffer. Delta is NOT used.\r
- EfiBltVideoToBltBuffer - Read data from the video display rectangle\r
- (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in\r
- the BltBuffer rectangle (DestinationX, DestinationY )\r
- (DestinationX + Width, DestinationY + Height). If DestinationX or\r
- DestinationY is not zero then Delta must be set to the length in bytes\r
- of a row in the BltBuffer.\r
- EfiBltBufferToVideo - Write data from the BltBuffer rectangle\r
- (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the\r
- video display rectangle (DestinationX, DestinationY)\r
- (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is\r
- not zero then Delta must be set to the length in bytes of a row in the\r
- BltBuffer.\r
- EfiBltVideoToVideo - Copy from the video display rectangle\r
- (SourceX, SourceY) (SourceX + Width, SourceY + Height) .\r
- to the video display rectangle (DestinationX, DestinationY)\r
- (DestinationX + Width, DestinationY + Height).\r
- The BltBuffer and Delta are not used in this mode.\r
-\r
- @param Private Protocol instance pointer.\r
- @param BltBuffer Buffer containing data to blit into video buffer.\r
- This buffer has a size of\r
- Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
- @param BltOperation Operation to perform on BlitBuffer and video\r
- 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\r
- buffer.\r
-\r
-**/\r
-EFI_STATUS\r
-DevNullGraphicsOutputBlt (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\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
- UINTN SrcY;\r
- BOOLEAN Forward;\r
- UINTN Index;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltPtr;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ScreenPtr;\r
- UINTN HorizontalResolution;\r
- UINTN VerticalResolution;\r
-\r
- if ((BltOperation < EfiBltVideoFill) || (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 == 0) {\r
- Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
- }\r
-\r
- HorizontalResolution = Private->GraphicsOutput.Mode->Info->HorizontalResolution;\r
- VerticalResolution = Private->GraphicsOutput.Mode->Info->VerticalResolution;\r
-\r
- //\r
- // We need to fill the Virtual Screen buffer with the blt data.\r
- //\r
- if (BltOperation == EfiBltVideoToBltBuffer) {\r
+ if ((Private->CurrentNumberOfGraphicsOutput == 1) && (PhysicalGraphicsOutput != NULL)) {\r
//\r
- // Video to BltBuffer: Source is Video, destination is BltBuffer\r
+ // If only one physical GOP device exist, copy physical information to consplitter.\r
//\r
- if ((SourceY + Height) > VerticalResolution) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((SourceX + Width) > HorizontalResolution) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- BltPtr = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + DestinationY * Delta + DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
- ScreenPtr = &Private->GraphicsOutputBlt[SourceY * HorizontalResolution + SourceX];\r
- while (Height > 0) {\r
- CopyMem (BltPtr, ScreenPtr, Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
- BltPtr = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltPtr + Delta);\r
- ScreenPtr += HorizontalResolution;\r
- Height--;\r
- }\r
+ CopyMem (This->Mode->Info, PhysicalGraphicsOutput->Mode->Info, PhysicalGraphicsOutput->Mode->SizeOfInfo);\r
+ This->Mode->SizeOfInfo = PhysicalGraphicsOutput->Mode->SizeOfInfo;\r
+ This->Mode->FrameBufferBase = PhysicalGraphicsOutput->Mode->FrameBufferBase;\r
+ This->Mode->FrameBufferSize = PhysicalGraphicsOutput->Mode->FrameBufferSize;\r
} else {\r
//\r
- // BltBuffer to Video: Source is BltBuffer, destination is Video\r
+ // If 2 more phyiscal GOP device exist or GOP protocol does not exist,\r
+ // return GOP information (PixelFormat is PixelBltOnly) created in ConSplitterAddGraphicsOutputMode ().\r
//\r
- if (DestinationY + Height > VerticalResolution) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (DestinationX + Width > HorizontalResolution) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((BltOperation == EfiBltVideoToVideo) && (DestinationY > SourceY)) {\r
- //\r
- // Copy backwards, only care the Video to Video Blt\r
- //\r
- ScreenPtr = &Private->GraphicsOutputBlt[(DestinationY + Height - 1) * HorizontalResolution + DestinationX];\r
- SrcY = SourceY + Height - 1;\r
- Forward = FALSE;\r
- } else {\r
- //\r
- // Copy forwards, for other cases\r
- //\r
- ScreenPtr = &Private->GraphicsOutputBlt[DestinationY * HorizontalResolution + DestinationX];\r
- SrcY = SourceY;\r
- Forward = TRUE;\r
- }\r
-\r
- while (Height != 0) {\r
- if (BltOperation == EfiBltVideoFill) {\r
- for (Index = 0; Index < Width; Index++) {\r
- ScreenPtr[Index] = *BltBuffer;\r
- }\r
- } else {\r
- if (BltOperation == EfiBltBufferToVideo) {\r
- BltPtr = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + SrcY * Delta + SourceX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
- } else {\r
- BltPtr = &Private->GraphicsOutputBlt[SrcY * HorizontalResolution + SourceX];\r
- }\r
-\r
- CopyMem (ScreenPtr, BltPtr, Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
- }\r
-\r
- if (Forward) {\r
- ScreenPtr += HorizontalResolution;\r
- SrcY ++;\r
- } else {\r
- ScreenPtr -= HorizontalResolution;\r
- SrcY --;\r
- }\r
- Height--;\r
- }\r
+ CopyMem (This->Mode->Info, &Private->GraphicsOutputModeBuffer[ModeNumber], This->Mode->SizeOfInfo);\r
}\r
\r
- return EFI_SUCCESS;\r
+ return ReturnStatus;\r
}\r
\r
\r
+\r
/**\r
The following table defines actions for BltOperations.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-ConSpliterGraphicsOutputBlt (\r
+ConSplitterGraphicsOutputBlt (\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
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
\r
+ if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
\r
ReturnStatus = EFI_SUCCESS;\r
+\r
//\r
// return the worst status met\r
//\r
return ReturnStatus;\r
}\r
\r
-/**\r
- Write data from the buffer to video display based on Graphics Output setting.\r
-\r
- @param Private Consplitter Text Out pointer.\r
- @param GraphicsOutput Graphics Output protocol pointer.\r
- @param UgaDraw UGA Draw protocol pointer.\r
-\r
- @retval EFI_UNSUPPORTED No graphics devcie available .\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
-**/\r
-EFI_STATUS\r
-DevNullGopSync (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
- IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
- IN EFI_UGA_DRAW_PROTOCOL *UgaDraw\r
- )\r
-{\r
- if (GraphicsOutput != NULL) {\r
- return GraphicsOutput->Blt (\r
- GraphicsOutput,\r
- Private->GraphicsOutputBlt,\r
- EfiBltBufferToVideo,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- Private->GraphicsOutput.Mode->Info->HorizontalResolution,\r
- Private->GraphicsOutput.Mode->Info->VerticalResolution,\r
- 0\r
- );\r
- } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
- return UgaDraw->Blt (\r
- UgaDraw,\r
- (EFI_UGA_PIXEL *) Private->GraphicsOutputBlt,\r
- EfiUgaBltBufferToVideo,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- Private->GraphicsOutput.Mode->Info->HorizontalResolution,\r
- Private->GraphicsOutput.Mode->Info->VerticalResolution,\r
- 0\r
- );\r
- } else {\r
- return EFI_UNSUPPORTED;\r
- }\r
-}\r
-\r
/**\r
Return the current video mode information.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-ConSpliterUgaDrawGetMode (\r
+ConSplitterUgaDrawGetMode (\r
IN EFI_UGA_DRAW_PROTOCOL *This,\r
OUT UINT32 *HorizontalResolution,\r
OUT UINT32 *VerticalResolution,\r
**/\r
EFI_STATUS\r
EFIAPI\r
-ConSpliterUgaDrawSetMode (\r
+ConSplitterUgaDrawSetMode (\r
IN EFI_UGA_DRAW_PROTOCOL *This,\r
IN UINT32 HorizontalResolution,\r
IN UINT32 VerticalResolution,\r
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
UINTN Index;\r
EFI_STATUS ReturnStatus;\r
- UINTN Size;\r
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
UINTN NumberIndex;\r
UINTN SizeOfInfo;\r
\r
Private = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
\r
- //\r
- // UgaDevNullSetMode ()\r
- //\r
ReturnStatus = EFI_SUCCESS;\r
\r
- //\r
- // Free the old version\r
- //\r
- if (Private->UgaBlt != NULL) {\r
- FreePool (Private->UgaBlt);\r
- }\r
-\r
- //\r
- // Allocate the virtual Blt buffer\r
- //\r
- Size = HorizontalResolution * VerticalResolution * sizeof (EFI_UGA_PIXEL);\r
- Private->UgaBlt = AllocateZeroPool (Size);\r
- if (Private->UgaBlt == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
//\r
// Update the Mode data\r
//\r
Private->UgaColorDepth = ColorDepth;\r
Private->UgaRefreshRate = RefreshRate;\r
\r
- if (Private->ConsoleOutputMode != EfiConsoleControlScreenGraphics) {\r
- return ReturnStatus;\r
- }\r
//\r
// return the worst status met\r
//\r
for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
\r
- ReturnStatus = EFI_UNSUPPORTED;\r
-\r
GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;\r
if (GraphicsOutput != NULL) {\r
//\r
return ReturnStatus;\r
}\r
\r
-/**\r
- Blt a rectangle of pixels on the graphics screen.\r
-\r
- The following table defines actions for BltOperations.\r
-\r
- EfiUgaVideoFill:\r
- Write data from the BltBuffer pixel (SourceX, SourceY)\r
- directly to every pixel of the video display rectangle\r
- (DestinationX, DestinationY)\r
- (DestinationX + Width, DestinationY + Height).\r
- Only one pixel will be used from the BltBuffer. Delta is NOT used.\r
- EfiUgaVideoToBltBuffer:\r
- Read data from the video display rectangle\r
- (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in\r
- the BltBuffer rectangle (DestinationX, DestinationY )\r
- (DestinationX + Width, DestinationY + Height). If DestinationX or\r
- DestinationY is not zero then Delta must be set to the length in bytes\r
- of a row in the BltBuffer.\r
- EfiUgaBltBufferToVideo:\r
- Write data from the BltBuffer rectangle\r
- (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the\r
- video display rectangle (DestinationX, DestinationY)\r
- (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is\r
- not zero then Delta must be set to the length in bytes of a row in the\r
- BltBuffer.\r
- EfiUgaVideoToVideo:\r
- Copy from the video display rectangle\r
- (SourceX, SourceY) (SourceX + Width, SourceY + Height) .\r
- to the video display rectangle (DestinationX, DestinationY)\r
- (DestinationX + Width, DestinationY + Height).\r
- The BltBuffer and Delta are not used in this mode.\r
-\r
- @param Private Text Out Splitter pointer.\r
- @param BltBuffer Buffer containing data to blit into video buffer.\r
- This buffer has a size of\r
- Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
- @param BltOperation Operation to perform on BlitBuffer and video\r
- 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\r
- buffer.\r
-\r
-**/\r
-EFI_STATUS\r
-DevNullUgaBlt (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\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
- UINTN SrcY;\r
- BOOLEAN Forward;\r
- UINTN Index;\r
- EFI_UGA_PIXEL *BltPtr;\r
- EFI_UGA_PIXEL *ScreenPtr;\r
- UINT32 HorizontalResolution;\r
- UINT32 VerticalResolution;\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 == 0) {\r
- Delta = Width * sizeof (EFI_UGA_PIXEL);\r
- }\r
-\r
- HorizontalResolution = Private->UgaHorizontalResolution;\r
- VerticalResolution = Private->UgaVerticalResolution;\r
-\r
- //\r
- // We need to fill the Virtual Screen buffer with the blt data.\r
- //\r
- if (BltOperation == EfiUgaVideoToBltBuffer) {\r
- //\r
- // Video to BltBuffer: Source is Video, destination is BltBuffer\r
- //\r
- if ((SourceY + Height) > VerticalResolution) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((SourceX + Width) > HorizontalResolution) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- BltPtr = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + DestinationY * Delta + DestinationX * sizeof (EFI_UGA_PIXEL));\r
- ScreenPtr = &Private->UgaBlt[SourceY * HorizontalResolution + SourceX];\r
- while (Height > 0) {\r
- CopyMem (BltPtr, ScreenPtr, Width * sizeof (EFI_UGA_PIXEL));\r
- BltPtr = (EFI_UGA_PIXEL *) ((UINT8 *) BltPtr + Delta);\r
- ScreenPtr += HorizontalResolution;\r
- Height--;\r
- }\r
- } else {\r
- //\r
- // BltBuffer to Video: Source is BltBuffer, destination is Video\r
- //\r
- if (DestinationY + Height > VerticalResolution) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (DestinationX + Width > HorizontalResolution) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((BltOperation == EfiUgaVideoToVideo) && (DestinationY > SourceY)) {\r
- //\r
- // Copy backwards, only care the Video to Video Blt\r
- //\r
- ScreenPtr = &Private->UgaBlt[(DestinationY + Height - 1) * HorizontalResolution + DestinationX];\r
- SrcY = SourceY + Height - 1;\r
- Forward = FALSE;\r
- } else {\r
- //\r
- // Copy forwards, for other cases\r
- //\r
- ScreenPtr = &Private->UgaBlt[DestinationY * HorizontalResolution + DestinationX];\r
- SrcY = SourceY;\r
- Forward = TRUE;\r
- }\r
-\r
- while (Height != 0) {\r
- if (BltOperation == EfiUgaVideoFill) {\r
- for (Index = 0; Index < Width; Index++) {\r
- ScreenPtr[Index] = *BltBuffer;\r
- }\r
- } else {\r
- if (BltOperation == EfiUgaBltBufferToVideo) {\r
- BltPtr = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + SrcY * Delta + SourceX * sizeof (EFI_UGA_PIXEL));\r
- } else {\r
- BltPtr = &Private->UgaBlt[SrcY * HorizontalResolution + SourceX];\r
- }\r
-\r
- CopyMem (ScreenPtr, BltPtr, Width * sizeof (EFI_UGA_PIXEL));\r
- }\r
-\r
- if (Forward) {\r
- ScreenPtr += HorizontalResolution;\r
- SrcY ++;\r
- } else {\r
- ScreenPtr -= HorizontalResolution;\r
- SrcY --;\r
- }\r
- Height--;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
+\r
/**\r
Blt a rectangle of pixels on the graphics screen.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-ConSpliterUgaDrawBlt (\r
+ConSplitterUgaDrawBlt (\r
IN EFI_UGA_DRAW_PROTOCOL *This,\r
IN EFI_UGA_PIXEL *BltBuffer, OPTIONAL\r
IN EFI_UGA_BLT_OPERATION BltOperation,\r
\r
Private = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
\r
- //\r
- // Sync up DevNull UGA device\r
- //\r
- ReturnStatus = DevNullUgaBlt (\r
- Private,\r
- BltBuffer,\r
- BltOperation,\r
- SourceX,\r
- SourceY,\r
- DestinationX,\r
- DestinationY,\r
- Width,\r
- Height,\r
- Delta\r
- );\r
- if (Private->ConsoleOutputMode != EfiConsoleControlScreenGraphics) {\r
- return ReturnStatus;\r
- }\r
+ ReturnStatus = EFI_SUCCESS;\r
//\r
// return the worst status met\r
//\r
);\r
if (EFI_ERROR (Status)) {\r
ReturnStatus = Status;\r
- } else if (BltOperation == EfiBltVideoToBltBuffer) {\r
+ } else if (BltOperation == EfiUgaVideoToBltBuffer) {\r
//\r
// Only need to read the data into buffer one time\r
//\r
return ReturnStatus;\r
}\r
\r
-/**\r
- Write data from the buffer to video display based on UGA Draw setting.\r
-\r
- @param Private Consplitter Text Out pointer.\r
- @param GraphicsOutput Graphics Output protocol pointer.\r
- @param UgaDraw UGA Draw protocol pointer.\r
-\r
- @retval EFI_UNSUPPORTED No graphics devcie available .\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
-DevNullUgaSync (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
- IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
- IN EFI_UGA_DRAW_PROTOCOL *UgaDraw\r
- )\r
-{\r
- if (GraphicsOutput != NULL) {\r
- return GraphicsOutput->Blt (\r
- GraphicsOutput,\r
- (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) Private->UgaBlt,\r
- EfiBltBufferToVideo,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- Private->UgaHorizontalResolution,\r
- Private->UgaVerticalResolution,\r
- 0\r
- );\r
- } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
- return UgaDraw->Blt (\r
- UgaDraw,\r
- Private->UgaBlt,\r
- EfiUgaBltBufferToVideo,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- Private->UgaHorizontalResolution,\r
- Private->UgaVerticalResolution,\r
- Private->UgaHorizontalResolution * sizeof (EFI_UGA_PIXEL)\r
- );\r
- } else {\r
- return EFI_UNSUPPORTED;\r
- }\r
-}\r
-\r
-\r
-/**\r
- Write a Unicode string to the output device.\r
-\r
- @param Private Pointer to the console output splitter's private\r
- data. It indicates the calling context.\r
- @param WString The NULL-terminated Unicode string to be\r
- displayed on the output device(s). All output\r
- devices must also support the Unicode drawing\r
- defined in this file.\r
-\r
- @retval EFI_SUCCESS The string was output to the device.\r
- @retval EFI_DEVICE_ERROR The device reported an error while attempting to\r
- output the text.\r
- @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
- defined text mode.\r
- @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
- characters in the Unicode string could not be\r
- rendered and were skipped.\r
-\r
-**/\r
-EFI_STATUS\r
-DevNullTextOutOutputString (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
- IN CHAR16 *WString\r
- )\r
-{\r
- UINTN SizeScreen;\r
- UINTN SizeAttribute;\r
- UINTN Index;\r
- EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;\r
- CHAR16 *Screen;\r
- CHAR16 *NullScreen;\r
- CHAR16 InsertChar;\r
- CHAR16 TempChar;\r
- CHAR16 *PStr;\r
- INT32 *Attribute;\r
- INT32 *NullAttributes;\r
- INT32 CurrentWidth;\r
- UINTN LastRow;\r
- UINTN MaxColumn;\r
-\r
- Mode = &Private->TextOutMode;\r
- NullScreen = Private->DevNullScreen;\r
- NullAttributes = Private->DevNullAttributes;\r
- LastRow = Private->DevNullRows - 1;\r
- MaxColumn = Private->DevNullColumns;\r
-\r
- if ((Mode->Attribute & EFI_WIDE_ATTRIBUTE) != 0) {\r
- CurrentWidth = 2;\r
- } else {\r
- CurrentWidth = 1;\r
- }\r
-\r
- while (*WString != L'\0') {\r
-\r
- if (*WString == CHAR_BACKSPACE) {\r
- //\r
- // If the cursor is at the left edge of the display, then move the cursor\r
- // one row up.\r
- //\r
- if (Mode->CursorColumn == 0 && Mode->CursorRow > 0) {\r
- Mode->CursorRow--;\r
- Mode->CursorColumn = (INT32) MaxColumn;\r
- }\r
-\r
- //\r
- // If the cursor is not at the left edge of the display,\r
- // then move the cursor left one column.\r
- //\r
- if (Mode->CursorColumn > 0) {\r
- Mode->CursorColumn--;\r
- if (Mode->CursorColumn > 0 &&\r
- NullAttributes[Mode->CursorRow * MaxColumn + Mode->CursorColumn - 1] & EFI_WIDE_ATTRIBUTE\r
- ) {\r
- Mode->CursorColumn--;\r
-\r
- //\r
- // Insert an extra backspace\r
- //\r
- InsertChar = CHAR_BACKSPACE;\r
- PStr = WString + 1;\r
- while (*PStr != L'\0') {\r
- TempChar = *PStr;\r
- *PStr = InsertChar;\r
- InsertChar = TempChar;\r
- PStr++;\r
- }\r
-\r
- *PStr = InsertChar;\r
- *(++PStr) = 0;\r
-\r
- WString++;\r
- }\r
- }\r
-\r
- WString++;\r
-\r
- } else if (*WString == CHAR_LINEFEED) {\r
- //\r
- // If the cursor is at the bottom of the display,\r
- // then scroll the display one row, and do not update\r
- // the cursor position. Otherwise, move the cursor down one row.\r
- //\r
- if (Mode->CursorRow == (INT32) (LastRow)) {\r
- //\r
- // Scroll Screen Up One Row\r
- //\r
- SizeAttribute = LastRow * MaxColumn;\r
- CopyMem (\r
- NullAttributes,\r
- NullAttributes + MaxColumn,\r
- SizeAttribute * sizeof (INT32)\r
- );\r
-\r
- //\r
- // Each row has an ending CHAR_NULL. So one more character each line\r
- // for DevNullScreen than DevNullAttributes\r
- //\r
- SizeScreen = SizeAttribute + LastRow;\r
- CopyMem (\r
- NullScreen,\r
- NullScreen + (MaxColumn + 1),\r
- SizeScreen * sizeof (CHAR16)\r
- );\r
-\r
- //\r
- // Print Blank Line at last line\r
- //\r
- Screen = NullScreen + SizeScreen;\r
- Attribute = NullAttributes + SizeAttribute;\r
-\r
- for (Index = 0; Index < MaxColumn; Index++, Screen++, Attribute++) {\r
- *Screen = L' ';\r
- *Attribute = Mode->Attribute;\r
- }\r
- } else {\r
- Mode->CursorRow++;\r
- }\r
-\r
- WString++;\r
- } else if (*WString == CHAR_CARRIAGE_RETURN) {\r
- //\r
- // Move the cursor to the beginning of the current row.\r
- //\r
- Mode->CursorColumn = 0;\r
- WString++;\r
- } else {\r
- //\r
- // Print the character at the current cursor position and\r
- // move the cursor right one column. If this moves the cursor\r
- // past the right edge of the display, then the line should wrap to\r
- // the beginning of the next line. This is equivalent to inserting\r
- // a CR and an LF. Note that if the cursor is at the bottom of the\r
- // display, and the line wraps, then the display will be scrolled\r
- // one line.\r
- //\r
- Index = Mode->CursorRow * MaxColumn + Mode->CursorColumn;\r
-\r
- while (Mode->CursorColumn < (INT32) MaxColumn) {\r
- if (*WString == CHAR_NULL) {\r
- break;\r
- }\r
-\r
- if (*WString == CHAR_BACKSPACE) {\r
- break;\r
- }\r
-\r
- if (*WString == CHAR_LINEFEED) {\r
- break;\r
- }\r
-\r
- if (*WString == CHAR_CARRIAGE_RETURN) {\r
- break;\r
- }\r
-\r
- if (*WString == UNICODE_WIDE_CHAR || *WString == UNICODE_NARROW_CHAR) {\r
- CurrentWidth = (*WString == UNICODE_WIDE_CHAR) ? 2 : 1;\r
- WString++;\r
- continue;\r
- }\r
-\r
- if (Mode->CursorColumn + CurrentWidth > (INT32) MaxColumn) {\r
- //\r
- // If a wide char is at the rightmost column, then move the char\r
- // to the beginning of the next row\r
- //\r
- NullScreen[Index + Mode->CursorRow] = L' ';\r
- NullAttributes[Index] = Mode->Attribute | (UINT32) EFI_WIDE_ATTRIBUTE;\r
- Index++;\r
- Mode->CursorColumn++;\r
- } else {\r
- NullScreen[Index + Mode->CursorRow] = *WString;\r
- NullAttributes[Index] = Mode->Attribute;\r
- if (CurrentWidth == 1) {\r
- NullAttributes[Index] &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);\r
- } else {\r
- NullAttributes[Index] |= (UINT32) EFI_WIDE_ATTRIBUTE;\r
- NullAttributes[Index + 1] &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);\r
- }\r
-\r
- Index += CurrentWidth;\r
- WString++;\r
- Mode->CursorColumn += CurrentWidth;\r
- }\r
- }\r
- //\r
- // At the end of line, output carriage return and line feed\r
- //\r
- if (Mode->CursorColumn >= (INT32) MaxColumn) {\r
- DevNullTextOutOutputString (Private, mCrLfString);\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
/**\r
Sets the output device(s) to a specified mode.\r
\r
@param Private Text Out Splitter pointer.\r
@param ModeNumber The mode number to set.\r
\r
- @retval EFI_SUCCESS The requested text mode was set.\r
- @retval EFI_DEVICE_ERROR The device had an error and could not complete\r
- the request.\r
- @retval EFI_UNSUPPORTED The mode number was not valid.\r
- @retval EFI_OUT_OF_RESOURCES Out of resources.\r
-\r
**/\r
-EFI_STATUS\r
-DevNullTextOutSetMode (\r
+VOID\r
+TextOutSetMode (\r
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
IN UINTN ModeNumber\r
)\r
-{\r
- UINTN Size;\r
- INT32 CurrentMode;\r
- UINTN Row;\r
- UINTN Column;\r
- TEXT_OUT_SPLITTER_QUERY_DATA *Mode;\r
-\r
- //\r
- // No extra check for ModeNumber here, as it has been checked in\r
- // ConSplitterTextOutSetMode. And mode 0 should always be supported.\r
- // Row and Column should be fetched from intersection map.\r
- //\r
- if (Private->TextOutModeMap != NULL) {\r
- CurrentMode = *(Private->TextOutModeMap + Private->TextOutListCount * ModeNumber);\r
- } else {\r
- CurrentMode = (INT32) (ModeNumber);\r
- }\r
- Mode = &(Private->TextOutQueryData[CurrentMode]);\r
- Row = Mode->Rows;\r
- Column = Mode->Columns;\r
-\r
- if (Row == 0 || Column == 0) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (Private->TextOutMode.Mode != (INT32) ModeNumber) {\r
-\r
- Private->TextOutMode.Mode = (INT32) ModeNumber;\r
- Private->DevNullColumns = Column;\r
- Private->DevNullRows = Row;\r
-\r
- if (Private->DevNullScreen != NULL) {\r
- FreePool (Private->DevNullScreen);\r
- }\r
-\r
- Size = (Row * (Column + 1)) * sizeof (CHAR16);\r
- Private->DevNullScreen = AllocateZeroPool (Size);\r
- if (Private->DevNullScreen == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- if (Private->DevNullAttributes != NULL) {\r
- FreePool (Private->DevNullAttributes);\r
- }\r
-\r
- Size = Row * Column * sizeof (INT32);\r
- Private->DevNullAttributes = AllocateZeroPool (Size);\r
- if (Private->DevNullAttributes == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
-\r
- DevNullTextOutClearScreen (Private);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Clears the output device(s) display to the currently selected background\r
- color.\r
-\r
- @param Private Text Out Splitter pointer.\r
-\r
- @retval EFI_SUCCESS The operation completed successfully.\r
- @retval EFI_DEVICE_ERROR The device had an error and could not complete\r
- the request.\r
- @retval EFI_UNSUPPORTED The output device is not in a valid text mode.\r
-\r
-**/\r
-EFI_STATUS\r
-DevNullTextOutClearScreen (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private\r
- )\r
-{\r
- UINTN Row;\r
- UINTN Column;\r
- CHAR16 *Screen;\r
- INT32 *Attributes;\r
- INT32 CurrentAttribute;\r
-\r
- //\r
- // Clear the DevNull Text Out Buffers.\r
- // The screen is filled with spaces.\r
- // The attributes are all synced with the current Simple Text Out Attribute\r
- //\r
- Screen = Private->DevNullScreen;\r
- Attributes = Private->DevNullAttributes;\r
- CurrentAttribute = Private->TextOutMode.Attribute;\r
-\r
- for (Row = 0; Row < Private->DevNullRows; Row++) {\r
- for (Column = 0; Column < Private->DevNullColumns; Column++, Screen++, Attributes++) {\r
- *Screen = L' ';\r
- *Attributes = CurrentAttribute;\r
- }\r
- //\r
- // Each line of the screen has a NULL on the end so we must skip over it\r
- //\r
- Screen++;\r
- }\r
-\r
- DevNullTextOutSetCursorPosition (Private, 0, 0);\r
-\r
- return DevNullTextOutEnableCursor (Private, TRUE);\r
-}\r
-\r
-\r
-/**\r
- Sets the current coordinates of the cursor position on NULL device.\r
-\r
- @param Private Text Out Splitter pointer.\r
- @param Column The column position to set the cursor to. Must be\r
- greater than or equal to zero and less than the\r
- number of columns by QueryMode ().\r
- @param Row The row position to set the cursor to. Must be\r
- greater than or equal to zero and less than the\r
- number of rows by QueryMode ().\r
-\r
- @retval EFI_SUCCESS Always returned.\r
-\r
-**/\r
-EFI_STATUS\r
-DevNullTextOutSetCursorPosition (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
- IN UINTN Column,\r
- IN UINTN Row\r
- )\r
{\r
//\r
// No need to do extra check here as whether (Column, Row) is valid has\r
// been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should\r
// always be supported.\r
//\r
- Private->TextOutMode.CursorColumn = (INT32) Column;\r
- Private->TextOutMode.CursorRow = (INT32) Row;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Set cursor visibility property on NULL device.\r
-\r
- @param Private Text Out Splitter pointer.\r
- @param Visible If TRUE, the cursor is set to be visible, If\r
- FALSE, the cursor is set to be invisible.\r
-\r
- @retval EFI_SUCCESS Always returned.\r
-\r
-**/\r
-EFI_STATUS\r
-DevNullTextOutEnableCursor (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
- IN BOOLEAN Visible\r
- )\r
-{\r
- Private->TextOutMode.CursorVisible = Visible;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Take the DevNull TextOut device and update the Simple Text Out on every\r
- UGA device.\r
-\r
- @param Private Text Out Splitter pointer.\r
-\r
- @retval EFI_SUCCESS The request is valid.\r
- @retval other Return status of TextOut->OutputString ()\r
-\r
-**/\r
-EFI_STATUS\r
-DevNullSyncStdOut (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS ReturnStatus;\r
- UINTN Row;\r
- UINTN Column;\r
- UINTN List;\r
- UINTN MaxColumn;\r
- UINTN CurrentColumn;\r
- UINTN StartRow;\r
- UINTN StartColumn;\r
- INT32 StartAttribute;\r
- BOOLEAN StartCursorState;\r
- CHAR16 *Screen;\r
- CHAR16 *Str;\r
- CHAR16 *Buffer;\r
- CHAR16 *BufferTail;\r
- CHAR16 *ScreenStart;\r
- INT32 CurrentAttribute;\r
- INT32 *Attributes;\r
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto;\r
-\r
- //\r
- // Save the devices Attributes, Cursor enable state and location\r
- //\r
- StartColumn = Private->TextOutMode.CursorColumn;\r
- StartRow = Private->TextOutMode.CursorRow;\r
- StartAttribute = Private->TextOutMode.Attribute;\r
- StartCursorState = Private->TextOutMode.CursorVisible;\r
-\r
- for (List = 0; List < Private->CurrentNumberOfConsoles; List++) {\r
-\r
- Sto = Private->TextOutList[List].TextOut;\r
-\r
- //\r
- // Skip non GOP/UGA devices\r
- //\r
- if ((Private->TextOutList[List].GraphicsOutput != NULL) || (Private->TextOutList[List].UgaDraw != NULL)) {\r
- Sto->EnableCursor (Sto, FALSE);\r
- Sto->ClearScreen (Sto);\r
- }\r
- }\r
-\r
- ReturnStatus = EFI_SUCCESS;\r
- Screen = Private->DevNullScreen;\r
- Attributes = Private->DevNullAttributes;\r
- MaxColumn = Private->DevNullColumns;\r
-\r
- Buffer = AllocateZeroPool ((MaxColumn + 1) * sizeof (CHAR16));\r
- if (Buffer == NULL) {\r
- return ReturnStatus;\r
- }\r
-\r
- for (Row = 0; Row < Private->DevNullRows; Row++, Screen += (MaxColumn + 1), Attributes += MaxColumn) {\r
-\r
- if (Row == (Private->DevNullRows - 1)) {\r
- //\r
- // Don't ever sync the last character as it will scroll the screen\r
- //\r
- Screen[MaxColumn - 1] = 0x00;\r
- }\r
-\r
- Column = 0;\r
- while (Column < MaxColumn) {\r
- if (Screen[Column] > 0) {\r
- CurrentAttribute = Attributes[Column];\r
- CurrentColumn = Column;\r
- ScreenStart = &Screen[Column];\r
-\r
- //\r
- // the line end is alway 0x0. So Column should be less than MaxColumn\r
- // It should be still in the same row\r
- //\r
- for (Str = ScreenStart, BufferTail = Buffer; *Str != 0; Str++, Column++) {\r
-\r
- if (Attributes[Column] != CurrentAttribute) {\r
- Column--;\r
- break;\r
- }\r
-\r
- *BufferTail = *Str;\r
- BufferTail++;\r
- if ((Attributes[Column] & EFI_WIDE_ATTRIBUTE) != 0) {\r
- Str++;\r
- Column++;\r
- }\r
- }\r
-\r
- *BufferTail = 0;\r
-\r
- for (List = 0; List < Private->CurrentNumberOfConsoles; List++) {\r
-\r
- Sto = Private->TextOutList[List].TextOut;\r
-\r
- //\r
- // Skip non GOP/UGA devices\r
- //\r
- if ((Private->TextOutList[List].GraphicsOutput != NULL) || (Private->TextOutList[List].UgaDraw != NULL)) {\r
- Sto->SetAttribute (Sto, CurrentAttribute);\r
- Sto->SetCursorPosition (Sto, CurrentColumn, Row);\r
- Status = Sto->OutputString (Sto, Buffer);\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
- }\r
- }\r
-\r
- }\r
-\r
- Column++;\r
- }\r
- }\r
- //\r
- // Restore the devices Attributes, Cursor enable state and location\r
- //\r
- for (List = 0; List < Private->CurrentNumberOfConsoles; List++) {\r
- Sto = Private->TextOutList[List].TextOut;\r
+ Private->TextOutMode.Mode = (INT32) ModeNumber;\r
+ Private->TextOutMode.CursorColumn = 0;\r
+ Private->TextOutMode.CursorRow = 0;\r
+ Private->TextOutMode.CursorVisible = TRUE;\r
\r
- //\r
- // Skip non GOP/UGA devices\r
- //\r
- if ((Private->TextOutList[List].GraphicsOutput != NULL) || (Private->TextOutList[List].UgaDraw != NULL)) {\r
- Sto->SetAttribute (Sto, StartAttribute);\r
- Sto->SetCursorPosition (Sto, StartColumn, StartRow);\r
- Status = Sto->EnableCursor (Sto, StartCursorState);\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
- }\r
- }\r
-\r
- FreePool (Buffer);\r
-\r
- return ReturnStatus;\r
+ return;\r
}\r