2 Support for Graphics output spliter.
4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "ConSplitter.h"
19 CHAR16 mCrLfString
[3] = { CHAR_CARRIAGE_RETURN
, CHAR_LINEFEED
, CHAR_NULL
};
22 Returns information for an available graphics mode that the graphics device
23 and the set of active video output devices supports.
25 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
26 @param ModeNumber The mode number to return information on.
27 @param SizeOfInfo A pointer to the size, in bytes, of the Info buffer.
28 @param Info A pointer to callee allocated buffer that returns information about ModeNumber.
30 @retval EFI_SUCCESS Mode information returned.
31 @retval EFI_BUFFER_TOO_SMALL The Info buffer was too small.
32 @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode.
33 @retval EFI_INVALID_PARAMETER One of the input args was NULL.
34 @retval EFI_OUT_OF_RESOURCES No resource available.
39 ConSplitterGraphicsOutputQueryMode (
40 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
42 OUT UINTN
*SizeOfInfo
,
43 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
**Info
46 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
47 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
51 if (This
== NULL
|| Info
== NULL
|| SizeOfInfo
== NULL
|| ModeNumber
>= This
->Mode
->MaxMode
) {
52 return EFI_INVALID_PARAMETER
;
56 // retrieve private data
58 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
60 GraphicsOutput
= NULL
;
62 if (Private
->CurrentNumberOfGraphicsOutput
== 1) {
64 // Find the only one GraphicsOutput.
66 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
67 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
68 if (GraphicsOutput
!= NULL
) {
74 if (GraphicsOutput
!= NULL
) {
76 // If only one physical GOP device exist, return its information.
78 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) ModeNumber
, SizeOfInfo
, Info
);
82 // If 2 more phyiscal GOP device exist or GOP protocol does not exist,
83 // return GOP information (PixelFormat is PixelBltOnly) created in ConSplitterAddGraphicsOutputMode ().
85 *Info
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
87 return EFI_OUT_OF_RESOURCES
;
89 *SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
90 CopyMem (*Info
, &Private
->GraphicsOutputModeBuffer
[ModeNumber
], *SizeOfInfo
);
98 Set the video device into the specified mode and clears the visible portions of
99 the output display to black.
101 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
102 @param ModeNumber Abstraction that defines the current video mode.
104 @retval EFI_SUCCESS The graphics mode specified by ModeNumber was selected.
105 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
106 @retval EFI_UNSUPPORTED ModeNumber is not supported by this device.
107 @retval EFI_OUT_OF_RESOURCES No resource available.
112 ConSplitterGraphicsOutputSetMode (
113 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
* This
,
118 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
120 EFI_STATUS ReturnStatus
;
121 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
;
122 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
123 EFI_GRAPHICS_OUTPUT_PROTOCOL
*PhysicalGraphicsOutput
;
126 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
127 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
129 if (ModeNumber
>= This
->Mode
->MaxMode
) {
130 return EFI_UNSUPPORTED
;
133 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
134 Mode
= &Private
->GraphicsOutputModeBuffer
[ModeNumber
];
136 ReturnStatus
= EFI_SUCCESS
;
137 GraphicsOutput
= NULL
;
138 PhysicalGraphicsOutput
= NULL
;
140 // return the worst status met
142 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
143 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
144 if (GraphicsOutput
!= NULL
) {
145 PhysicalGraphicsOutput
= GraphicsOutput
;
147 // Find corresponding ModeNumber of this GraphicsOutput instance
149 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
150 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
151 if (EFI_ERROR (Status
)) {
154 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) && (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
161 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
162 if (EFI_ERROR (Status
)) {
163 ReturnStatus
= Status
;
165 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
166 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
167 if (UgaDraw
!= NULL
) {
168 Status
= UgaDraw
->SetMode (
170 Mode
->HorizontalResolution
,
171 Mode
->VerticalResolution
,
175 if (EFI_ERROR (Status
)) {
176 ReturnStatus
= Status
;
182 This
->Mode
->Mode
= ModeNumber
;
184 if ((Private
->CurrentNumberOfGraphicsOutput
== 1) && (PhysicalGraphicsOutput
!= NULL
)) {
186 // If only one physical GOP device exist, copy physical information to consplitter.
188 CopyMem (This
->Mode
->Info
, PhysicalGraphicsOutput
->Mode
->Info
, PhysicalGraphicsOutput
->Mode
->SizeOfInfo
);
189 This
->Mode
->SizeOfInfo
= PhysicalGraphicsOutput
->Mode
->SizeOfInfo
;
190 This
->Mode
->FrameBufferBase
= PhysicalGraphicsOutput
->Mode
->FrameBufferBase
;
191 This
->Mode
->FrameBufferSize
= PhysicalGraphicsOutput
->Mode
->FrameBufferSize
;
194 // If 2 more phyiscal GOP device exist or GOP protocol does not exist,
195 // return GOP information (PixelFormat is PixelBltOnly) created in ConSplitterAddGraphicsOutputMode ().
197 CopyMem (This
->Mode
->Info
, &Private
->GraphicsOutputModeBuffer
[ModeNumber
], This
->Mode
->SizeOfInfo
);
206 The following table defines actions for BltOperations.
208 EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
209 directly to every pixel of the video display rectangle
210 (DestinationX, DestinationY)
211 (DestinationX + Width, DestinationY + Height).
212 Only one pixel will be used from the BltBuffer. Delta is NOT used.
213 EfiBltVideoToBltBuffer - Read data from the video display rectangle
214 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
215 the BltBuffer rectangle (DestinationX, DestinationY )
216 (DestinationX + Width, DestinationY + Height). If DestinationX or
217 DestinationY is not zero then Delta must be set to the length in bytes
218 of a row in the BltBuffer.
219 EfiBltBufferToVideo - Write data from the BltBuffer rectangle
220 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
221 video display rectangle (DestinationX, DestinationY)
222 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
223 not zero then Delta must be set to the length in bytes of a row in the
225 EfiBltVideoToVideo - Copy from the video display rectangle
226 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
227 to the video display rectangle (DestinationX, DestinationY)
228 (DestinationX + Width, DestinationY + Height).
229 The BltBuffer and Delta are not used in this mode.
231 @param This Protocol instance pointer.
232 @param BltBuffer Buffer containing data to blit into video buffer.
233 This buffer has a size of
234 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
235 @param BltOperation Operation to perform on BlitBuffer and video
237 @param SourceX X coordinate of source for the BltBuffer.
238 @param SourceY Y coordinate of source for the BltBuffer.
239 @param DestinationX X coordinate of destination for the BltBuffer.
240 @param DestinationY Y coordinate of destination for the BltBuffer.
241 @param Width Width of rectangle in BltBuffer in pixels.
242 @param Height Hight of rectangle in BltBuffer in pixels.
243 @param Delta OPTIONAL.
245 @retval EFI_SUCCESS The Blt operation completed.
246 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
247 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
253 ConSplitterGraphicsOutputBlt (
254 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
255 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
256 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
259 IN UINTN DestinationX
,
260 IN UINTN DestinationY
,
263 IN UINTN Delta OPTIONAL
267 EFI_STATUS ReturnStatus
;
268 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
270 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
271 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
273 if (This
== NULL
|| ((UINTN
) BltOperation
) >= EfiGraphicsOutputBltOperationMax
) {
274 return EFI_INVALID_PARAMETER
;
277 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
279 ReturnStatus
= EFI_SUCCESS
;
282 // return the worst status met
284 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
285 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
286 if (GraphicsOutput
!= NULL
) {
287 Status
= GraphicsOutput
->Blt (
299 if (EFI_ERROR (Status
)) {
300 ReturnStatus
= Status
;
301 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
303 // Only need to read the data into buffer one time
309 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
310 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
311 Status
= UgaDraw
->Blt (
313 (EFI_UGA_PIXEL
*) BltBuffer
,
314 (EFI_UGA_BLT_OPERATION
) BltOperation
,
323 if (EFI_ERROR (Status
)) {
324 ReturnStatus
= Status
;
325 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
327 // Only need to read the data into buffer one time
338 Return the current video mode information.
340 @param This The EFI_UGA_DRAW_PROTOCOL instance.
341 @param HorizontalResolution The size of video screen in pixels in the X dimension.
342 @param VerticalResolution The size of video screen in pixels in the Y dimension.
343 @param ColorDepth Number of bits per pixel, currently defined to be 32.
344 @param RefreshRate The refresh rate of the monitor in Hertz.
346 @retval EFI_SUCCESS Mode information returned.
347 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
348 @retval EFI_INVALID_PARAMETER One of the input args was NULL.
353 ConSplitterUgaDrawGetMode (
354 IN EFI_UGA_DRAW_PROTOCOL
*This
,
355 OUT UINT32
*HorizontalResolution
,
356 OUT UINT32
*VerticalResolution
,
357 OUT UINT32
*ColorDepth
,
358 OUT UINT32
*RefreshRate
361 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
363 if ((HorizontalResolution
== NULL
) ||
364 (VerticalResolution
== NULL
) ||
365 (RefreshRate
== NULL
) ||
366 (ColorDepth
== NULL
)) {
367 return EFI_INVALID_PARAMETER
;
370 // retrieve private data
372 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
374 *HorizontalResolution
= Private
->UgaHorizontalResolution
;
375 *VerticalResolution
= Private
->UgaVerticalResolution
;
376 *ColorDepth
= Private
->UgaColorDepth
;
377 *RefreshRate
= Private
->UgaRefreshRate
;
384 Set the current video mode information.
386 @param This The EFI_UGA_DRAW_PROTOCOL instance.
387 @param HorizontalResolution The size of video screen in pixels in the X dimension.
388 @param VerticalResolution The size of video screen in pixels in the Y dimension.
389 @param ColorDepth Number of bits per pixel, currently defined to be 32.
390 @param RefreshRate The refresh rate of the monitor in Hertz.
392 @retval EFI_SUCCESS Mode information returned.
393 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
394 @retval EFI_OUT_OF_RESOURCES Out of resources.
399 ConSplitterUgaDrawSetMode (
400 IN EFI_UGA_DRAW_PROTOCOL
*This
,
401 IN UINT32 HorizontalResolution
,
402 IN UINT32 VerticalResolution
,
403 IN UINT32 ColorDepth
,
404 IN UINT32 RefreshRate
408 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
410 EFI_STATUS ReturnStatus
;
411 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
414 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
415 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
417 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
419 ReturnStatus
= EFI_SUCCESS
;
422 // Update the Mode data
424 Private
->UgaHorizontalResolution
= HorizontalResolution
;
425 Private
->UgaVerticalResolution
= VerticalResolution
;
426 Private
->UgaColorDepth
= ColorDepth
;
427 Private
->UgaRefreshRate
= RefreshRate
;
430 // return the worst status met
432 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
434 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
435 if (GraphicsOutput
!= NULL
) {
437 // Find corresponding ModeNumber of this GraphicsOutput instance
439 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
440 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
441 if (EFI_ERROR (Status
)) {
444 if ((Info
->HorizontalResolution
== HorizontalResolution
) && (Info
->VerticalResolution
== VerticalResolution
)) {
451 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
452 if (EFI_ERROR (Status
)) {
453 ReturnStatus
= Status
;
455 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)){
456 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
457 if (UgaDraw
!= NULL
) {
458 Status
= UgaDraw
->SetMode (
460 HorizontalResolution
,
465 if (EFI_ERROR (Status
)) {
466 ReturnStatus
= Status
;
477 Blt a rectangle of pixels on the graphics screen.
479 The following table defines actions for BltOperations.
482 Write data from the BltBuffer pixel (SourceX, SourceY)
483 directly to every pixel of the video display rectangle
484 (DestinationX, DestinationY)
485 (DestinationX + Width, DestinationY + Height).
486 Only one pixel will be used from the BltBuffer. Delta is NOT used.
487 EfiUgaVideoToBltBuffer:
488 Read data from the video display rectangle
489 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
490 the BltBuffer rectangle (DestinationX, DestinationY )
491 (DestinationX + Width, DestinationY + Height). If DestinationX or
492 DestinationY is not zero then Delta must be set to the length in bytes
493 of a row in the BltBuffer.
494 EfiUgaBltBufferToVideo:
495 Write data from the BltBuffer rectangle
496 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
497 video display rectangle (DestinationX, DestinationY)
498 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
499 not zero then Delta must be set to the length in bytes of a row in the
502 Copy from the video display rectangle
503 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
504 to the video display rectangle (DestinationX, DestinationY)
505 (DestinationX + Width, DestinationY + Height).
506 The BltBuffer and Delta are not used in this mode.
508 @param This Protocol instance pointer.
509 @param BltBuffer Buffer containing data to blit into video buffer. This
510 buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
511 @param BltOperation Operation to perform on BlitBuffer and video memory
512 @param SourceX X coordinate of source for the BltBuffer.
513 @param SourceY Y coordinate of source for the BltBuffer.
514 @param DestinationX X coordinate of destination for the BltBuffer.
515 @param DestinationY Y coordinate of destination for the BltBuffer.
516 @param Width Width of rectangle in BltBuffer in pixels.
517 @param Height Hight of rectangle in BltBuffer in pixels.
518 @param Delta OPTIONAL
520 @retval EFI_SUCCESS The Blt operation completed.
521 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
522 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video buffer.
527 ConSplitterUgaDrawBlt (
528 IN EFI_UGA_DRAW_PROTOCOL
*This
,
529 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
530 IN EFI_UGA_BLT_OPERATION BltOperation
,
533 IN UINTN DestinationX
,
534 IN UINTN DestinationY
,
537 IN UINTN Delta OPTIONAL
541 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
543 EFI_STATUS ReturnStatus
;
544 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
546 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
548 ReturnStatus
= EFI_SUCCESS
;
550 // return the worst status met
552 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
553 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
554 if (GraphicsOutput
!= NULL
) {
555 Status
= GraphicsOutput
->Blt (
557 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltBuffer
,
558 (EFI_GRAPHICS_OUTPUT_BLT_OPERATION
) BltOperation
,
567 if (EFI_ERROR (Status
)) {
568 ReturnStatus
= Status
;
569 } else if (BltOperation
== EfiUgaVideoToBltBuffer
) {
571 // Only need to read the data into buffer one time
577 if (Private
->TextOutList
[Index
].UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
578 Status
= Private
->TextOutList
[Index
].UgaDraw
->Blt (
579 Private
->TextOutList
[Index
].UgaDraw
,
590 if (EFI_ERROR (Status
)) {
591 ReturnStatus
= Status
;
592 } else if (BltOperation
== EfiUgaVideoToBltBuffer
) {
594 // Only need to read the data into buffer one time
605 Sets the output device(s) to a specified mode.
607 @param Private Text Out Splitter pointer.
608 @param ModeNumber The mode number to set.
613 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
618 // No need to do extra check here as whether (Column, Row) is valid has
619 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
620 // always be supported.
622 Private
->TextOutMode
.Mode
= (INT32
) ModeNumber
;
623 Private
->TextOutMode
.CursorColumn
= 0;
624 Private
->TextOutMode
.CursorRow
= 0;
625 Private
->TextOutMode
.CursorVisible
= TRUE
;