2 Support for ConsoleControl protocol. Support for Graphics output spliter.
3 Support for DevNull Console Out. This console uses memory buffers
4 to represnt the console. It allows a console to start very early and
5 when a new console is added it is synced up with the current console.
7 Copyright (c) 2006 - 2008, Intel Corporation. <BR>
8 All rights reserved. This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 #include "ConSplitter.h"
23 CHAR16 mCrLfString
[3] = { CHAR_CARRIAGE_RETURN
, CHAR_LINEFEED
, CHAR_NULL
};
27 Return the current video mode information. Also returns info about existence
28 of Graphics Output devices or UGA Draw devices in system, and if the Std In device is locked. All the
29 arguments are optional and only returned if a non NULL pointer is passed in.
31 @param This Protocol instance pointer.
32 @param Mode Are we in text of grahics mode.
33 @param GopUgaExists TRUE if Console Spliter has found a GOP or UGA device
34 @param StdInLocked TRUE if StdIn device is keyboard locked
36 @retval EFI_SUCCESS Mode information returned.
37 @retval EFI_INVALID_PARAMETER Invalid parameters.
42 ConSpliterConsoleControlGetMode (
43 IN EFI_CONSOLE_CONTROL_PROTOCOL
*This
,
44 OUT EFI_CONSOLE_CONTROL_SCREEN_MODE
*Mode
,
45 OUT BOOLEAN
*GopUgaExists
,
46 OUT BOOLEAN
*StdInLocked
49 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
52 Private
= CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
55 return EFI_INVALID_PARAMETER
;
58 *Mode
= Private
->ConsoleOutputMode
;
60 if (GopUgaExists
!= NULL
) {
61 *GopUgaExists
= FALSE
;
62 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
63 if ((Private
->TextOutList
[Index
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[Index
].UgaDraw
!= NULL
)) {
70 if (StdInLocked
!= NULL
) {
71 *StdInLocked
= ConSpliterConssoleControlStdInLocked ();
79 Set the current mode to either text or graphics. Graphics is
82 @param This Protocol instance pointer.
83 @param Mode Mode to set the
85 @retval EFI_SUCCESS Mode information returned.
86 @retval EFI_INVALID_PARAMETER Invalid parameter.
87 @retval EFI_UNSUPPORTED Operation unsupported.
92 ConSpliterConsoleControlSetMode (
93 IN EFI_CONSOLE_CONTROL_PROTOCOL
*This
,
94 IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
97 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
99 TEXT_OUT_AND_GOP_DATA
*TextAndGop
;
102 Private
= CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
104 if (Mode
>= EfiConsoleControlScreenMaxValue
) {
105 return EFI_INVALID_PARAMETER
;
109 // Judge current mode with wanted mode at first.
111 if (Private
->ConsoleOutputMode
== Mode
) {
116 TextAndGop
= &Private
->TextOutList
[0];
117 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++, TextAndGop
++) {
118 if ((TextAndGop
->GraphicsOutput
!= NULL
) || (TextAndGop
->UgaDraw
!= NULL
)) {
124 if ((!Supported
) && (Mode
== EfiConsoleControlScreenGraphics
)) {
125 return EFI_UNSUPPORTED
;
128 Private
->ConsoleOutputMode
= Mode
;
130 TextAndGop
= &Private
->TextOutList
[0];
131 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++, TextAndGop
++) {
133 TextAndGop
->TextOutEnabled
= TRUE
;
135 // If we are going into Graphics mode disable ConOut to any UGA device
137 if ((Mode
== EfiConsoleControlScreenGraphics
) &&((TextAndGop
->GraphicsOutput
!= NULL
) || (TextAndGop
->UgaDraw
!= NULL
))) {
138 TextAndGop
->TextOutEnabled
= FALSE
;
139 if (FeaturePcdGet (PcdConOutGopSupport
)) {
140 DevNullGopSync (Private
, TextAndGop
->GraphicsOutput
, TextAndGop
->UgaDraw
);
141 } else if (FeaturePcdGet (PcdConOutUgaSupport
)) {
142 DevNullUgaSync (Private
, TextAndGop
->GraphicsOutput
, TextAndGop
->UgaDraw
);
146 if (Mode
== EfiConsoleControlScreenText
) {
147 DevNullSyncStdOut (Private
);
154 Return the current video mode information.
156 @param This Protocol instance pointer.
157 @param ModeNumber The mode number to return information on.
158 @param SizeOfInfo A pointer to the size, in bytes, of the Info
160 @param Info Caller allocated buffer that returns information
163 @retval EFI_SUCCESS Mode information returned.
164 @retval EFI_BUFFER_TOO_SMALL The Info buffer was too small.
165 @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the
167 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
168 @retval EFI_INVALID_PARAMETER One of the input args was NULL.
173 ConSpliterGraphicsOutputQueryMode (
174 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
175 IN UINT32 ModeNumber
,
176 OUT UINTN
*SizeOfInfo
,
177 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
**Info
180 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
182 if (This
== NULL
|| Info
== NULL
|| SizeOfInfo
== NULL
|| ModeNumber
>= This
->Mode
->MaxMode
) {
183 return EFI_INVALID_PARAMETER
;
187 // retrieve private data
189 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
191 if (Private
->HardwareNeedsStarting
) {
192 return EFI_NOT_STARTED
;
195 *Info
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
198 return EFI_OUT_OF_RESOURCES
;
201 *SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
203 CopyMem (*Info
, &Private
->GraphicsOutputModeBuffer
[ModeNumber
], *SizeOfInfo
);
210 Graphics output protocol interface to set video mode.
212 @param This Protocol instance pointer.
213 @param ModeNumber The mode number to be set.
215 @retval EFI_SUCCESS Graphics mode was changed.
216 @retval EFI_DEVICE_ERROR The device had an error and could not complete
218 @retval EFI_UNSUPPORTED ModeNumber is not supported by this device.
223 ConSpliterGraphicsOutputSetMode (
224 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
* This
,
229 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
231 EFI_STATUS ReturnStatus
;
232 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
;
234 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
237 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
238 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
240 if (ModeNumber
>= This
->Mode
->MaxMode
) {
241 return EFI_UNSUPPORTED
;
244 if (ModeNumber
== This
->Mode
->Mode
) {
248 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
250 ReturnStatus
= EFI_SUCCESS
;
253 // Free the old version
255 if (Private
->GraphicsOutputBlt
!= NULL
) {
256 FreePool (Private
->GraphicsOutputBlt
);
260 // Allocate the virtual Blt buffer
262 Mode
= &Private
->GraphicsOutputModeBuffer
[ModeNumber
];
263 Size
= Mode
->HorizontalResolution
* Mode
->VerticalResolution
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
264 Private
->GraphicsOutputBlt
= AllocateZeroPool (Size
);
266 if (Private
->GraphicsOutputBlt
== NULL
) {
267 return EFI_OUT_OF_RESOURCES
;
271 // return the worst status met
273 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
274 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
275 if (GraphicsOutput
!= NULL
) {
277 // Find corresponding ModeNumber of this GraphicsOutput instance
279 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
280 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
281 if (EFI_ERROR (Status
)) {
284 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) && (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
291 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
292 if (EFI_ERROR (Status
)) {
293 ReturnStatus
= Status
;
297 if (EFI_ERROR (ReturnStatus
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
298 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
299 if (UgaDraw
!= NULL
) {
300 Status
= UgaDraw
->SetMode (
302 Mode
->HorizontalResolution
,
303 Mode
->VerticalResolution
,
307 if (EFI_ERROR (Status
)) {
308 ReturnStatus
= Status
;
314 This
->Mode
->Mode
= ModeNumber
;
316 CopyMem (This
->Mode
->Info
, &Private
->GraphicsOutputModeBuffer
[ModeNumber
], This
->Mode
->SizeOfInfo
);
319 // Information is not enough here, so the following items remain unchanged:
320 // GraphicsOutputMode->Info->Version, GraphicsOutputMode->Info->PixelFormat
321 // GraphicsOutputMode->SizeOfInfo, GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
322 // These items will be initialized/updated when a new GOP device is added into ConsoleSplitter.
325 Private
->HardwareNeedsStarting
= FALSE
;
331 The following table defines actions for BltOperations.
333 EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
334 directly to every pixel of the video display rectangle
335 (DestinationX, DestinationY)
336 (DestinationX + Width, DestinationY + Height).
337 Only one pixel will be used from the BltBuffer. Delta is NOT used.
338 EfiBltVideoToBltBuffer - Read data from the video display rectangle
339 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
340 the BltBuffer rectangle (DestinationX, DestinationY )
341 (DestinationX + Width, DestinationY + Height). If DestinationX or
342 DestinationY is not zero then Delta must be set to the length in bytes
343 of a row in the BltBuffer.
344 EfiBltBufferToVideo - Write data from the BltBuffer rectangle
345 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
346 video display rectangle (DestinationX, DestinationY)
347 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
348 not zero then Delta must be set to the length in bytes of a row in the
350 EfiBltVideoToVideo - Copy from the video display rectangle
351 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
352 to the video display rectangle (DestinationX, DestinationY)
353 (DestinationX + Width, DestinationY + Height).
354 The BltBuffer and Delta are not used in this mode.
356 @param Private Protocol instance pointer.
357 @param BltBuffer Buffer containing data to blit into video buffer.
358 This buffer has a size of
359 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
360 @param BltOperation Operation to perform on BlitBuffer and video
362 @param SourceX X coordinate of source for the BltBuffer.
363 @param SourceY Y coordinate of source for the BltBuffer.
364 @param DestinationX X coordinate of destination for the BltBuffer.
365 @param DestinationY Y coordinate of destination for the BltBuffer.
366 @param Width Width of rectangle in BltBuffer in pixels.
367 @param Height Hight of rectangle in BltBuffer in pixels.
368 @param Delta OPTIONAL.
370 @retval EFI_SUCCESS The Blt operation completed.
371 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
372 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
377 DevNullGraphicsOutputBlt (
378 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
379 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
380 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
383 IN UINTN DestinationX
,
384 IN UINTN DestinationY
,
387 IN UINTN Delta OPTIONAL
393 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltPtr
;
394 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*ScreenPtr
;
395 UINTN HorizontalResolution
;
396 UINTN VerticalResolution
;
398 if ((BltOperation
< EfiBltVideoFill
) || (BltOperation
>= EfiGraphicsOutputBltOperationMax
)) {
399 return EFI_INVALID_PARAMETER
;
402 if (Width
== 0 || Height
== 0) {
403 return EFI_INVALID_PARAMETER
;
407 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
410 HorizontalResolution
= Private
->GraphicsOutput
.Mode
->Info
->HorizontalResolution
;
411 VerticalResolution
= Private
->GraphicsOutput
.Mode
->Info
->VerticalResolution
;
414 // We need to fill the Virtual Screen buffer with the blt data.
416 if (BltOperation
== EfiBltVideoToBltBuffer
) {
418 // Video to BltBuffer: Source is Video, destination is BltBuffer
420 if ((SourceY
+ Height
) > VerticalResolution
) {
421 return EFI_INVALID_PARAMETER
;
424 if ((SourceX
+ Width
) > HorizontalResolution
) {
425 return EFI_INVALID_PARAMETER
;
428 BltPtr
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltBuffer
+ DestinationY
* Delta
+ DestinationX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
429 ScreenPtr
= &Private
->GraphicsOutputBlt
[SourceY
* HorizontalResolution
+ SourceX
];
431 CopyMem (BltPtr
, ScreenPtr
, Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
432 BltPtr
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltPtr
+ Delta
);
433 ScreenPtr
+= HorizontalResolution
;
438 // BltBuffer to Video: Source is BltBuffer, destination is Video
440 if (DestinationY
+ Height
> VerticalResolution
) {
441 return EFI_INVALID_PARAMETER
;
444 if (DestinationX
+ Width
> HorizontalResolution
) {
445 return EFI_INVALID_PARAMETER
;
448 if ((BltOperation
== EfiBltVideoToVideo
) && (DestinationY
> SourceY
)) {
450 // Copy backwards, only care the Video to Video Blt
452 ScreenPtr
= &Private
->GraphicsOutputBlt
[(DestinationY
+ Height
- 1) * HorizontalResolution
+ DestinationX
];
453 SrcY
= SourceY
+ Height
- 1;
457 // Copy forwards, for other cases
459 ScreenPtr
= &Private
->GraphicsOutputBlt
[DestinationY
* HorizontalResolution
+ DestinationX
];
464 while (Height
!= 0) {
465 if (BltOperation
== EfiBltVideoFill
) {
466 for (Index
= 0; Index
< Width
; Index
++) {
467 ScreenPtr
[Index
] = *BltBuffer
;
470 if (BltOperation
== EfiBltBufferToVideo
) {
471 BltPtr
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltBuffer
+ SrcY
* Delta
+ SourceX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
473 BltPtr
= &Private
->GraphicsOutputBlt
[SrcY
* HorizontalResolution
+ SourceX
];
476 CopyMem (ScreenPtr
, BltPtr
, Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
480 ScreenPtr
+= HorizontalResolution
;
483 ScreenPtr
-= HorizontalResolution
;
495 The following table defines actions for BltOperations.
497 EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
498 directly to every pixel of the video display rectangle
499 (DestinationX, DestinationY)
500 (DestinationX + Width, DestinationY + Height).
501 Only one pixel will be used from the BltBuffer. Delta is NOT used.
502 EfiBltVideoToBltBuffer - Read data from the video display rectangle
503 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
504 the BltBuffer rectangle (DestinationX, DestinationY )
505 (DestinationX + Width, DestinationY + Height). If DestinationX or
506 DestinationY is not zero then Delta must be set to the length in bytes
507 of a row in the BltBuffer.
508 EfiBltBufferToVideo - Write data from the BltBuffer rectangle
509 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
510 video display rectangle (DestinationX, DestinationY)
511 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
512 not zero then Delta must be set to the length in bytes of a row in the
514 EfiBltVideoToVideo - Copy from the video display rectangle
515 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
516 to the video display rectangle (DestinationX, DestinationY)
517 (DestinationX + Width, DestinationY + Height).
518 The BltBuffer and Delta are not used in this mode.
520 @param This Protocol instance pointer.
521 @param BltBuffer Buffer containing data to blit into video buffer.
522 This buffer has a size of
523 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
524 @param BltOperation Operation to perform on BlitBuffer and video
526 @param SourceX X coordinate of source for the BltBuffer.
527 @param SourceY Y coordinate of source for the BltBuffer.
528 @param DestinationX X coordinate of destination for the BltBuffer.
529 @param DestinationY Y coordinate of destination for the BltBuffer.
530 @param Width Width of rectangle in BltBuffer in pixels.
531 @param Height Hight of rectangle in BltBuffer in pixels.
532 @param Delta OPTIONAL.
534 @retval EFI_SUCCESS The Blt operation completed.
535 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
536 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
542 ConSpliterGraphicsOutputBlt (
543 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
544 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
545 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
548 IN UINTN DestinationX
,
549 IN UINTN DestinationY
,
552 IN UINTN Delta OPTIONAL
556 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
558 EFI_STATUS ReturnStatus
;
559 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
560 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
562 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
565 // Sync up DevNull GOP device
567 ReturnStatus
= DevNullGraphicsOutputBlt (
580 if (Private
->ConsoleOutputMode
!= EfiConsoleControlScreenGraphics
) {
584 // return the worst status met
586 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
587 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
588 if (GraphicsOutput
!= NULL
) {
589 Status
= GraphicsOutput
->Blt (
601 if (EFI_ERROR (Status
)) {
602 ReturnStatus
= Status
;
603 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
605 // Only need to read the data into buffer one time
611 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
612 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
613 Status
= UgaDraw
->Blt (
615 (EFI_UGA_PIXEL
*) BltBuffer
,
616 (EFI_UGA_BLT_OPERATION
) BltOperation
,
625 if (EFI_ERROR (Status
)) {
626 ReturnStatus
= Status
;
627 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
629 // Only need to read the data into buffer one time
640 Write data from the buffer to video display based on Graphics Output setting.
642 @param Private Consplitter Text Out pointer.
643 @param GraphicsOutput Graphics Output protocol pointer.
644 @param UgaDraw UGA Draw protocol pointer.
646 @retval EFI_UNSUPPORTED No graphics devcie available .
647 @retval EFI_SUCCESS The Blt operation completed.
648 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
649 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video buffer.
655 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
656 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
657 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
660 if (GraphicsOutput
!= NULL
) {
661 return GraphicsOutput
->Blt (
663 Private
->GraphicsOutputBlt
,
669 Private
->GraphicsOutput
.Mode
->Info
->HorizontalResolution
,
670 Private
->GraphicsOutput
.Mode
->Info
->VerticalResolution
,
673 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
674 return UgaDraw
->Blt (
676 (EFI_UGA_PIXEL
*) Private
->GraphicsOutputBlt
,
677 EfiUgaBltBufferToVideo
,
682 Private
->GraphicsOutput
.Mode
->Info
->HorizontalResolution
,
683 Private
->GraphicsOutput
.Mode
->Info
->VerticalResolution
,
687 return EFI_UNSUPPORTED
;
693 Return the current video mode information.
695 @param This Protocol instance pointer.
696 @param HorizontalResolution Current video horizontal resolution in pixels
697 @param VerticalResolution Current video vertical resolution in pixels
698 @param ColorDepth Current video color depth in bits per pixel
699 @param RefreshRate Current video refresh rate in Hz.
701 @retval EFI_SUCCESS Mode information returned.
702 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
703 @retval EFI_INVALID_PARAMETER One of the input args was NULL.
708 ConSpliterUgaDrawGetMode (
709 IN EFI_UGA_DRAW_PROTOCOL
*This
,
710 OUT UINT32
*HorizontalResolution
,
711 OUT UINT32
*VerticalResolution
,
712 OUT UINT32
*ColorDepth
,
713 OUT UINT32
*RefreshRate
716 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
718 if ((HorizontalResolution
== NULL
) ||
719 (VerticalResolution
== NULL
) ||
720 (RefreshRate
== NULL
) ||
721 (ColorDepth
== NULL
)) {
722 return EFI_INVALID_PARAMETER
;
725 // retrieve private data
727 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
729 *HorizontalResolution
= Private
->UgaHorizontalResolution
;
730 *VerticalResolution
= Private
->UgaVerticalResolution
;
731 *ColorDepth
= Private
->UgaColorDepth
;
732 *RefreshRate
= Private
->UgaRefreshRate
;
739 Return the current video mode information.
741 @param This Protocol instance pointer.
742 @param HorizontalResolution Current video horizontal resolution in pixels
743 @param VerticalResolution Current video vertical resolution in pixels
744 @param ColorDepth Current video color depth in bits per pixel
745 @param RefreshRate Current video refresh rate in Hz.
747 @retval EFI_SUCCESS Mode information returned.
748 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
749 @retval EFI_OUT_OF_RESOURCES Out of resources.
754 ConSpliterUgaDrawSetMode (
755 IN EFI_UGA_DRAW_PROTOCOL
*This
,
756 IN UINT32 HorizontalResolution
,
757 IN UINT32 VerticalResolution
,
758 IN UINT32 ColorDepth
,
759 IN UINT32 RefreshRate
763 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
765 EFI_STATUS ReturnStatus
;
767 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
770 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
771 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
773 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
776 // UgaDevNullSetMode ()
778 ReturnStatus
= EFI_SUCCESS
;
781 // Free the old version
783 if (Private
->UgaBlt
!= NULL
) {
784 FreePool (Private
->UgaBlt
);
788 // Allocate the virtual Blt buffer
790 Size
= HorizontalResolution
* VerticalResolution
* sizeof (EFI_UGA_PIXEL
);
791 Private
->UgaBlt
= AllocateZeroPool (Size
);
792 if (Private
->UgaBlt
== NULL
) {
793 return EFI_OUT_OF_RESOURCES
;
797 // Update the Mode data
799 Private
->UgaHorizontalResolution
= HorizontalResolution
;
800 Private
->UgaVerticalResolution
= VerticalResolution
;
801 Private
->UgaColorDepth
= ColorDepth
;
802 Private
->UgaRefreshRate
= RefreshRate
;
804 if (Private
->ConsoleOutputMode
!= EfiConsoleControlScreenGraphics
) {
808 // return the worst status met
810 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
812 ReturnStatus
= EFI_UNSUPPORTED
;
814 if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
815 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
816 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
817 Status
= UgaDraw
->SetMode (
819 HorizontalResolution
,
824 if (EFI_ERROR (Status
)) {
825 ReturnStatus
= Status
;
830 if (EFI_ERROR (ReturnStatus
)) {
831 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
832 if (GraphicsOutput
!= NULL
) {
834 // Find corresponding ModeNumber of this GraphicsOutput instance
836 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
837 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
838 if (EFI_ERROR (Status
)) {
841 if ((Info
->HorizontalResolution
== HorizontalResolution
) && (Info
->VerticalResolution
== VerticalResolution
)) {
848 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
849 if (EFI_ERROR (Status
)) {
850 ReturnStatus
= Status
;
860 The following table defines actions for BltOperations.
862 EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
863 directly to every pixel of the video display rectangle
864 (DestinationX, DestinationY)
865 (DestinationX + Width, DestinationY + Height).
866 Only one pixel will be used from the BltBuffer. Delta is NOT used.
867 EfiBltVideoToBltBuffer - Read data from the video display rectangle
868 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
869 the BltBuffer rectangle (DestinationX, DestinationY )
870 (DestinationX + Width, DestinationY + Height). If DestinationX or
871 DestinationY is not zero then Delta must be set to the length in bytes
872 of a row in the BltBuffer.
873 EfiBltBufferToVideo - Write data from the BltBuffer rectangle
874 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
875 video display rectangle (DestinationX, DestinationY)
876 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
877 not zero then Delta must be set to the length in bytes of a row in the
879 EfiBltVideoToVideo - Copy from the video display rectangle
880 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
881 to the video display rectangle (DestinationX, DestinationY)
882 (DestinationX + Width, DestinationY + Height).
883 The BltBuffer and Delta are not used in this mode.
885 @param Private Protocol instance pointer.
886 @param BltBuffer Buffer containing data to blit into video buffer.
887 This buffer has a size of
888 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
889 @param BltOperation Operation to perform on BlitBuffer and video
891 @param SourceX X coordinate of source for the BltBuffer.
892 @param SourceY Y coordinate of source for the BltBuffer.
893 @param DestinationX X coordinate of destination for the BltBuffer.
894 @param DestinationY Y coordinate of destination for the BltBuffer.
895 @param Width Width of rectangle in BltBuffer in pixels.
896 @param Height Hight of rectangle in BltBuffer in pixels.
897 @param Delta OPTIONAL.
899 @retval EFI_SUCCESS The Blt operation completed.
900 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
901 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
907 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
908 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
909 IN EFI_UGA_BLT_OPERATION BltOperation
,
912 IN UINTN DestinationX
,
913 IN UINTN DestinationY
,
916 IN UINTN Delta OPTIONAL
922 EFI_UGA_PIXEL
*BltPtr
;
923 EFI_UGA_PIXEL
*ScreenPtr
;
924 UINT32 HorizontalResolution
;
925 UINT32 VerticalResolution
;
927 if ((BltOperation
< 0) || (BltOperation
>= EfiUgaBltMax
)) {
928 return EFI_INVALID_PARAMETER
;
931 if (Width
== 0 || Height
== 0) {
932 return EFI_INVALID_PARAMETER
;
936 Delta
= Width
* sizeof (EFI_UGA_PIXEL
);
939 HorizontalResolution
= Private
->UgaHorizontalResolution
;
940 VerticalResolution
= Private
->UgaVerticalResolution
;
943 // We need to fill the Virtual Screen buffer with the blt data.
945 if (BltOperation
== EfiUgaVideoToBltBuffer
) {
947 // Video to BltBuffer: Source is Video, destination is BltBuffer
949 if ((SourceY
+ Height
) > VerticalResolution
) {
950 return EFI_INVALID_PARAMETER
;
953 if ((SourceX
+ Width
) > HorizontalResolution
) {
954 return EFI_INVALID_PARAMETER
;
957 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ DestinationY
* Delta
+ DestinationX
* sizeof (EFI_UGA_PIXEL
));
958 ScreenPtr
= &Private
->UgaBlt
[SourceY
* HorizontalResolution
+ SourceX
];
960 CopyMem (BltPtr
, ScreenPtr
, Width
* sizeof (EFI_UGA_PIXEL
));
961 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltPtr
+ Delta
);
962 ScreenPtr
+= HorizontalResolution
;
967 // BltBuffer to Video: Source is BltBuffer, destination is Video
969 if (DestinationY
+ Height
> VerticalResolution
) {
970 return EFI_INVALID_PARAMETER
;
973 if (DestinationX
+ Width
> HorizontalResolution
) {
974 return EFI_INVALID_PARAMETER
;
977 if ((BltOperation
== EfiUgaVideoToVideo
) && (DestinationY
> SourceY
)) {
979 // Copy backwards, only care the Video to Video Blt
981 ScreenPtr
= &Private
->UgaBlt
[(DestinationY
+ Height
- 1) * HorizontalResolution
+ DestinationX
];
982 SrcY
= SourceY
+ Height
- 1;
986 // Copy forwards, for other cases
988 ScreenPtr
= &Private
->UgaBlt
[DestinationY
* HorizontalResolution
+ DestinationX
];
993 while (Height
!= 0) {
994 if (BltOperation
== EfiUgaVideoFill
) {
995 for (Index
= 0; Index
< Width
; Index
++) {
996 ScreenPtr
[Index
] = *BltBuffer
;
999 if (BltOperation
== EfiUgaBltBufferToVideo
) {
1000 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ SrcY
* Delta
+ SourceX
* sizeof (EFI_UGA_PIXEL
));
1002 BltPtr
= &Private
->UgaBlt
[SrcY
* HorizontalResolution
+ SourceX
];
1005 CopyMem (ScreenPtr
, BltPtr
, Width
* sizeof (EFI_UGA_PIXEL
));
1009 ScreenPtr
+= HorizontalResolution
;
1012 ScreenPtr
-= HorizontalResolution
;
1024 The following table defines actions for BltOperations.
1026 EfiUgaVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
1027 directly to every pixel of the video display rectangle
1028 (DestinationX, DestinationY)
1029 (DestinationX + Width, DestinationY + Height).
1030 Only one pixel will be used from the BltBuffer. Delta is NOT used.
1031 EfiUgaVideoToBltBuffer - Read data from the video display rectangle
1032 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
1033 the BltBuffer rectangle (DestinationX, DestinationY )
1034 (DestinationX + Width, DestinationY + Height). If DestinationX or
1035 DestinationY is not zero then Delta must be set to the length in bytes
1036 of a row in the BltBuffer.
1037 EfiUgaBltBufferToVideo - Write data from the BltBuffer rectangle
1038 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
1039 video display rectangle (DestinationX, DestinationY)
1040 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
1041 not zero then Delta must be set to the length in bytes of a row in the
1043 EfiUgaVideoToVideo - Copy from the video display rectangle
1044 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
1045 to the video display rectangle (DestinationX, DestinationY)
1046 (DestinationX + Width, DestinationY + Height).
1047 The BltBuffer and Delta are not used in this mode.
1049 @param This Protocol instance pointer.
1050 @param BltBuffer Buffer containing data to blit into video buffer.
1051 This buffer has a size of
1052 Width*Height*sizeof(EFI_UGA_PIXEL)
1053 @param BltOperation Operation to perform on BlitBuffer and video
1055 @param SourceX X coordinate of source for the BltBuffer.
1056 @param SourceY Y coordinate of source for the BltBuffer.
1057 @param DestinationX X coordinate of destination for the BltBuffer.
1058 @param DestinationY Y coordinate of destination for the BltBuffer.
1059 @param Width Width of rectangle in BltBuffer in pixels.
1060 @param Height Hight of rectangle in BltBuffer in pixels.
1061 @param Delta OPTIONAL.
1063 @retval EFI_SUCCESS The Blt operation completed.
1064 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
1065 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
1071 ConSpliterUgaDrawBlt (
1072 IN EFI_UGA_DRAW_PROTOCOL
*This
,
1073 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
1074 IN EFI_UGA_BLT_OPERATION BltOperation
,
1077 IN UINTN DestinationX
,
1078 IN UINTN DestinationY
,
1081 IN UINTN Delta OPTIONAL
1085 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
1087 EFI_STATUS ReturnStatus
;
1088 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1090 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
1093 // Sync up DevNull UGA device
1095 ReturnStatus
= DevNullUgaBlt (
1107 if (Private
->ConsoleOutputMode
!= EfiConsoleControlScreenGraphics
) {
1108 return ReturnStatus
;
1111 // return the worst status met
1113 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
1114 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
1115 if (GraphicsOutput
!= NULL
) {
1116 Status
= GraphicsOutput
->Blt (
1118 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltBuffer
,
1119 (EFI_GRAPHICS_OUTPUT_BLT_OPERATION
) BltOperation
,
1128 if (EFI_ERROR (Status
)) {
1129 ReturnStatus
= Status
;
1130 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
1132 // Only need to read the data into buffer one time
1138 if (Private
->TextOutList
[Index
].UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1139 Status
= Private
->TextOutList
[Index
].UgaDraw
->Blt (
1140 Private
->TextOutList
[Index
].UgaDraw
,
1151 if (EFI_ERROR (Status
)) {
1152 ReturnStatus
= Status
;
1153 } else if (BltOperation
== EfiUgaVideoToBltBuffer
) {
1155 // Only need to read the data into buffer one time
1162 return ReturnStatus
;
1166 Write data from the buffer to video display based on UGA Draw setting.
1168 @param Private Consplitter Text Out pointer.
1169 @param GraphicsOutput Graphics Output protocol pointer.
1170 @param UgaDraw UGA Draw protocol pointer.
1172 @retval EFI_UNSUPPORTED No graphics devcie available .
1173 @retval EFI_SUCCESS The Blt operation completed.
1174 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
1175 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video buffer.
1180 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1181 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
1182 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
1185 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1186 return UgaDraw
->Blt (
1189 EfiUgaBltBufferToVideo
,
1194 Private
->UgaHorizontalResolution
,
1195 Private
->UgaVerticalResolution
,
1196 Private
->UgaHorizontalResolution
* sizeof (EFI_UGA_PIXEL
)
1198 } else if (GraphicsOutput
!= NULL
) {
1199 return GraphicsOutput
->Blt (
1201 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) Private
->UgaBlt
,
1202 EfiBltBufferToVideo
,
1207 Private
->UgaHorizontalResolution
,
1208 Private
->UgaVerticalResolution
,
1212 return EFI_UNSUPPORTED
;
1218 Write a Unicode string to the output device.
1220 @param Private Pointer to the console output splitter's private
1221 data. It indicates the calling context.
1222 @param WString The NULL-terminated Unicode string to be
1223 displayed on the output device(s). All output
1224 devices must also support the Unicode drawing
1225 defined in this file.
1227 @retval EFI_SUCCESS The string was output to the device.
1228 @retval EFI_DEVICE_ERROR The device reported an error while attempting to
1230 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
1232 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
1233 characters in the Unicode string could not be
1234 rendered and were skipped.
1238 DevNullTextOutOutputString (
1239 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1244 UINTN SizeAttribute
;
1246 EFI_SIMPLE_TEXT_OUTPUT_MODE
*Mode
;
1253 INT32
*NullAttributes
;
1258 Mode
= &Private
->TextOutMode
;
1259 NullScreen
= Private
->DevNullScreen
;
1260 NullAttributes
= Private
->DevNullAttributes
;
1261 LastRow
= Private
->DevNullRows
- 1;
1262 MaxColumn
= Private
->DevNullColumns
;
1264 if (Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) {
1270 while (*WString
!= L
'\0') {
1272 if (*WString
== CHAR_BACKSPACE
) {
1274 // If the cursor is at the left edge of the display, then move the cursor
1277 if (Mode
->CursorColumn
== 0 && Mode
->CursorRow
> 0) {
1279 Mode
->CursorColumn
= (INT32
) MaxColumn
;
1283 // If the cursor is not at the left edge of the display,
1284 // then move the cursor left one column.
1286 if (Mode
->CursorColumn
> 0) {
1287 Mode
->CursorColumn
--;
1288 if (Mode
->CursorColumn
> 0 &&
1289 NullAttributes
[Mode
->CursorRow
* MaxColumn
+ Mode
->CursorColumn
- 1] & EFI_WIDE_ATTRIBUTE
1291 Mode
->CursorColumn
--;
1294 // Insert an extra backspace
1296 InsertChar
= CHAR_BACKSPACE
;
1298 while (*PStr
!= L
'\0') {
1301 InsertChar
= TempChar
;
1314 } else if (*WString
== CHAR_LINEFEED
) {
1316 // If the cursor is at the bottom of the display,
1317 // then scroll the display one row, and do not update
1318 // the cursor position. Otherwise, move the cursor down one row.
1320 if (Mode
->CursorRow
== (INT32
) (LastRow
)) {
1322 // Scroll Screen Up One Row
1324 SizeAttribute
= LastRow
* MaxColumn
;
1327 NullAttributes
+ MaxColumn
,
1328 SizeAttribute
* sizeof (INT32
)
1332 // Each row has an ending CHAR_NULL. So one more character each line
1333 // for DevNullScreen than DevNullAttributes
1335 SizeScreen
= SizeAttribute
+ LastRow
;
1338 NullScreen
+ (MaxColumn
+ 1),
1339 SizeScreen
* sizeof (CHAR16
)
1343 // Print Blank Line at last line
1345 Screen
= NullScreen
+ SizeScreen
;
1346 Attribute
= NullAttributes
+ SizeAttribute
;
1348 for (Index
= 0; Index
< MaxColumn
; Index
++, Screen
++, Attribute
++) {
1350 *Attribute
= Mode
->Attribute
;
1357 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
1359 // Move the cursor to the beginning of the current row.
1361 Mode
->CursorColumn
= 0;
1365 // Print the character at the current cursor position and
1366 // move the cursor right one column. If this moves the cursor
1367 // past the right edge of the display, then the line should wrap to
1368 // the beginning of the next line. This is equivalent to inserting
1369 // a CR and an LF. Note that if the cursor is at the bottom of the
1370 // display, and the line wraps, then the display will be scrolled
1373 Index
= Mode
->CursorRow
* MaxColumn
+ Mode
->CursorColumn
;
1375 while (Mode
->CursorColumn
< (INT32
) MaxColumn
) {
1376 if (*WString
== CHAR_NULL
) {
1380 if (*WString
== CHAR_BACKSPACE
) {
1384 if (*WString
== CHAR_LINEFEED
) {
1388 if (*WString
== CHAR_CARRIAGE_RETURN
) {
1392 if (*WString
== UNICODE_WIDE_CHAR
|| *WString
== UNICODE_NARROW_CHAR
) {
1393 CurrentWidth
= (*WString
== UNICODE_WIDE_CHAR
) ? 2 : 1;
1398 if (Mode
->CursorColumn
+ CurrentWidth
> (INT32
) MaxColumn
) {
1400 // If a wide char is at the rightmost column, then move the char
1401 // to the beginning of the next row
1403 NullScreen
[Index
+ Mode
->CursorRow
] = L
' ';
1404 NullAttributes
[Index
] = Mode
->Attribute
| (UINT32
) EFI_WIDE_ATTRIBUTE
;
1406 Mode
->CursorColumn
++;
1408 NullScreen
[Index
+ Mode
->CursorRow
] = *WString
;
1409 NullAttributes
[Index
] = Mode
->Attribute
;
1410 if (CurrentWidth
== 1) {
1411 NullAttributes
[Index
] &= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
1413 NullAttributes
[Index
] |= (UINT32
) EFI_WIDE_ATTRIBUTE
;
1414 NullAttributes
[Index
+ 1] &= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
1417 Index
+= CurrentWidth
;
1419 Mode
->CursorColumn
+= CurrentWidth
;
1423 // At the end of line, output carriage return and line feed
1425 if (Mode
->CursorColumn
>= (INT32
) MaxColumn
) {
1426 DevNullTextOutOutputString (Private
, mCrLfString
);
1436 Sets the output device(s) to a specified mode.
1438 @param Private Private data structure pointer.
1439 @param ModeNumber The mode number to set.
1441 @retval EFI_SUCCESS The requested text mode was set.
1442 @retval EFI_DEVICE_ERROR The device had an error and could not complete
1444 @retval EFI_UNSUPPORTED The mode number was not valid.
1445 @retval EFI_OUT_OF_RESOURCES Out of resources.
1449 DevNullTextOutSetMode (
1450 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1458 TEXT_OUT_SPLITTER_QUERY_DATA
*Mode
;
1461 // No extra check for ModeNumber here, as it has been checked in
1462 // ConSplitterTextOutSetMode. And mode 0 should always be supported.
1463 // Row and Column should be fetched from intersection map.
1465 if (Private
->TextOutModeMap
!= NULL
) {
1466 CurrentMode
= *(Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
);
1468 CurrentMode
= (INT32
)(ModeNumber
);
1470 Mode
= &(Private
->TextOutQueryData
[CurrentMode
]);
1472 Column
= Mode
->Columns
;
1474 if (Row
<= 0 && Column
<= 0) {
1475 return EFI_UNSUPPORTED
;
1478 if (Private
->TextOutMode
.Mode
!= (INT32
) ModeNumber
) {
1480 Private
->TextOutMode
.Mode
= (INT32
) ModeNumber
;
1481 Private
->DevNullColumns
= Column
;
1482 Private
->DevNullRows
= Row
;
1484 if (Private
->DevNullScreen
!= NULL
) {
1485 FreePool (Private
->DevNullScreen
);
1488 Size
= (Row
* (Column
+ 1)) * sizeof (CHAR16
);
1489 Private
->DevNullScreen
= AllocateZeroPool (Size
);
1490 if (Private
->DevNullScreen
== NULL
) {
1491 return EFI_OUT_OF_RESOURCES
;
1494 if (Private
->DevNullAttributes
!= NULL
) {
1495 FreePool (Private
->DevNullAttributes
);
1498 Size
= Row
* Column
* sizeof (INT32
);
1499 Private
->DevNullAttributes
= AllocateZeroPool (Size
);
1500 if (Private
->DevNullAttributes
== NULL
) {
1501 return EFI_OUT_OF_RESOURCES
;
1505 DevNullTextOutClearScreen (Private
);
1512 Clears the output device(s) display to the currently selected background
1515 @param Private Protocol instance pointer.
1517 @retval EFI_SUCCESS The operation completed successfully.
1518 @retval EFI_DEVICE_ERROR The device had an error and could not complete
1520 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
1524 DevNullTextOutClearScreen (
1525 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
1532 INT32 CurrentAttribute
;
1535 // Clear the DevNull Text Out Buffers.
1536 // The screen is filled with spaces.
1537 // The attributes are all synced with the current Simple Text Out Attribute
1539 Screen
= Private
->DevNullScreen
;
1540 Attributes
= Private
->DevNullAttributes
;
1541 CurrentAttribute
= Private
->TextOutMode
.Attribute
;
1543 for (Row
= 0; Row
< Private
->DevNullRows
; Row
++) {
1544 for (Column
= 0; Column
< Private
->DevNullColumns
; Column
++, Screen
++, Attributes
++) {
1546 *Attributes
= CurrentAttribute
;
1549 // Each line of the screen has a NULL on the end so we must skip over it
1554 DevNullTextOutSetCursorPosition (Private
, 0, 0);
1556 return DevNullTextOutEnableCursor (Private
, TRUE
);
1561 Sets the current coordinates of the cursor position.
1563 @param Private Protocol instance pointer.
1565 @param Row the position to set the cursor to. Must be
1566 greater than or equal to zero and less than the
1567 number of columns and rows by QueryMode ().
1569 @retval EFI_SUCCESS The operation completed successfully.
1570 @retval EFI_DEVICE_ERROR The device had an error and could not complete
1572 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or
1573 the cursor position is invalid for the current
1578 DevNullTextOutSetCursorPosition (
1579 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1585 // No need to do extra check here as whether (Column, Row) is valid has
1586 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
1587 // always be supported.
1589 Private
->TextOutMode
.CursorColumn
= (INT32
) Column
;
1590 Private
->TextOutMode
.CursorRow
= (INT32
) Row
;
1597 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1598 In this driver, the cursor cannot be hidden.
1600 @param Private Indicates the calling context.
1601 @param Visible If TRUE, the cursor is set to be visible, If
1602 FALSE, the cursor is set to be invisible.
1604 @retval EFI_SUCCESS The request is valid.
1608 DevNullTextOutEnableCursor (
1609 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1613 Private
->TextOutMode
.CursorVisible
= Visible
;
1620 Take the DevNull TextOut device and update the Simple Text Out on every
1623 @param Private Indicates the calling context.
1625 @retval EFI_SUCCESS The request is valid.
1626 @retval other Return status of TextOut->OutputString ()
1631 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
1635 EFI_STATUS ReturnStatus
;
1640 UINTN CurrentColumn
;
1643 INT32 StartAttribute
;
1644 BOOLEAN StartCursorState
;
1649 CHAR16
*ScreenStart
;
1650 INT32 CurrentAttribute
;
1652 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Sto
;
1655 // Save the devices Attributes, Cursor enable state and location
1657 StartColumn
= Private
->TextOutMode
.CursorColumn
;
1658 StartRow
= Private
->TextOutMode
.CursorRow
;
1659 StartAttribute
= Private
->TextOutMode
.Attribute
;
1660 StartCursorState
= Private
->TextOutMode
.CursorVisible
;
1662 for (List
= 0; List
< Private
->CurrentNumberOfConsoles
; List
++) {
1664 Sto
= Private
->TextOutList
[List
].TextOut
;
1667 // Skip non GOP/UGA devices
1669 if ((Private
->TextOutList
[List
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[List
].UgaDraw
!= NULL
)) {
1670 Sto
->EnableCursor (Sto
, FALSE
);
1671 Sto
->ClearScreen (Sto
);
1675 ReturnStatus
= EFI_SUCCESS
;
1676 Screen
= Private
->DevNullScreen
;
1677 Attributes
= Private
->DevNullAttributes
;
1678 MaxColumn
= Private
->DevNullColumns
;
1680 Buffer
= AllocateZeroPool ((MaxColumn
+ 1) * sizeof (CHAR16
));
1681 if (Buffer
== NULL
) {
1682 return ReturnStatus
;
1685 for (Row
= 0; Row
< Private
->DevNullRows
; Row
++, Screen
+= (MaxColumn
+ 1), Attributes
+= MaxColumn
) {
1687 if (Row
== (Private
->DevNullRows
- 1)) {
1689 // Don't ever sync the last character as it will scroll the screen
1691 Screen
[MaxColumn
- 1] = 0x00;
1695 while (Column
< MaxColumn
) {
1696 if (Screen
[Column
] > 0) {
1697 CurrentAttribute
= Attributes
[Column
];
1698 CurrentColumn
= Column
;
1699 ScreenStart
= &Screen
[Column
];
1702 // the line end is alway 0x0. So Column should be less than MaxColumn
1703 // It should be still in the same row
1705 for (Str
= ScreenStart
, BufferTail
= Buffer
; *Str
!= 0; Str
++, Column
++) {
1707 if (Attributes
[Column
] != CurrentAttribute
) {
1714 if ((Attributes
[Column
] & EFI_WIDE_ATTRIBUTE
) != 0) {
1722 for (List
= 0; List
< Private
->CurrentNumberOfConsoles
; List
++) {
1724 Sto
= Private
->TextOutList
[List
].TextOut
;
1727 // Skip non GOP/UGA devices
1729 if ((Private
->TextOutList
[List
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[List
].UgaDraw
!= NULL
)) {
1730 Sto
->SetAttribute (Sto
, CurrentAttribute
);
1731 Sto
->SetCursorPosition (Sto
, CurrentColumn
, Row
);
1732 Status
= Sto
->OutputString (Sto
, Buffer
);
1733 if (EFI_ERROR (Status
)) {
1734 ReturnStatus
= Status
;
1745 // Restore the devices Attributes, Cursor enable state and location
1747 for (List
= 0; List
< Private
->CurrentNumberOfConsoles
; List
++) {
1748 Sto
= Private
->TextOutList
[List
].TextOut
;
1751 // Skip non GOP/UGA devices
1753 if ((Private
->TextOutList
[List
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[List
].UgaDraw
!= NULL
)) {
1754 Sto
->SetAttribute (Sto
, StartAttribute
);
1755 Sto
->SetCursorPosition (Sto
, StartColumn
, StartRow
);
1756 Status
= Sto
->EnableCursor (Sto
, StartCursorState
);
1757 if (EFI_ERROR (Status
)) {
1758 ReturnStatus
= Status
;
1765 return ReturnStatus
;