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 whether the Std
29 In device is locked. GopUgaExists and StdInLocked parameters are optional, and
30 only returned if a non NULL pointer is passed in.
32 @param This Protocol instance pointer.
33 @param Mode Current video mode.
34 @param GopExists TRUE if GOP Spliter has found a GOP/UGA device
35 @param StdInLocked TRUE if StdIn device is keyboard locked
37 @retval EFI_SUCCESS Video mode information is returned.
38 @retval EFI_INVALID_PARAMETER Invalid parameters if Mode == NULL.
43 ConSpliterConsoleControlGetMode (
44 IN EFI_CONSOLE_CONTROL_PROTOCOL
*This
,
45 OUT EFI_CONSOLE_CONTROL_SCREEN_MODE
*Mode
,
46 OUT BOOLEAN
*GopUgaExists
,
47 OUT BOOLEAN
*StdInLocked
50 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
53 Private
= CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
56 return EFI_INVALID_PARAMETER
;
59 *Mode
= Private
->ConsoleOutputMode
;
61 if (GopUgaExists
!= NULL
) {
62 *GopUgaExists
= FALSE
;
63 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
64 if ((Private
->TextOutList
[Index
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[Index
].UgaDraw
!= NULL
)) {
71 if (StdInLocked
!= NULL
) {
72 *StdInLocked
= ConSpliterConssoleControlStdInLocked ();
80 Set the current mode to either text or graphics. Graphics is
83 @param This Protocol instance pointer.
84 @param Mode Mode to set the
86 @retval EFI_SUCCESS Mode information returned.
87 @retval EFI_INVALID_PARAMETER Invalid parameter.
88 @retval EFI_UNSUPPORTED Operation unsupported.
93 ConSpliterConsoleControlSetMode (
94 IN EFI_CONSOLE_CONTROL_PROTOCOL
*This
,
95 IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
98 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
100 TEXT_OUT_AND_GOP_DATA
*TextAndGop
;
103 Private
= CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
105 if (Mode
>= EfiConsoleControlScreenMaxValue
) {
106 return EFI_INVALID_PARAMETER
;
110 // Judge current mode with wanted mode at first.
112 if (Private
->ConsoleOutputMode
== Mode
) {
117 TextAndGop
= &Private
->TextOutList
[0];
118 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++, TextAndGop
++) {
119 if ((TextAndGop
->GraphicsOutput
!= NULL
) || (TextAndGop
->UgaDraw
!= NULL
)) {
125 if ((!Supported
) && (Mode
== EfiConsoleControlScreenGraphics
)) {
126 return EFI_UNSUPPORTED
;
129 Private
->ConsoleOutputMode
= Mode
;
131 TextAndGop
= &Private
->TextOutList
[0];
132 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++, TextAndGop
++) {
134 TextAndGop
->TextOutEnabled
= TRUE
;
136 // If we are going into Graphics mode disable ConOut to any UGA device
138 if ((Mode
== EfiConsoleControlScreenGraphics
) &&((TextAndGop
->GraphicsOutput
!= NULL
) || (TextAndGop
->UgaDraw
!= NULL
))) {
139 TextAndGop
->TextOutEnabled
= FALSE
;
140 if (FeaturePcdGet (PcdConOutGopSupport
)) {
141 DevNullGopSync (Private
, TextAndGop
->GraphicsOutput
, TextAndGop
->UgaDraw
);
142 } else if (FeaturePcdGet (PcdConOutUgaSupport
)) {
143 DevNullUgaSync (Private
, TextAndGop
->GraphicsOutput
, TextAndGop
->UgaDraw
);
147 if (Mode
== EfiConsoleControlScreenText
) {
148 DevNullSyncStdOut (Private
);
155 Return the current video mode information.
157 @param This Protocol instance pointer.
158 @param ModeNumber The mode number to return information on.
159 @param SizeOfInfo A pointer to the size, in bytes, of the Info
161 @param Info Caller allocated buffer that returns information
164 @retval EFI_SUCCESS Mode information returned.
165 @retval EFI_BUFFER_TOO_SMALL The Info buffer was too small.
166 @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the
168 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
169 @retval EFI_INVALID_PARAMETER One of the input args was NULL.
174 ConSpliterGraphicsOutputQueryMode (
175 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
176 IN UINT32 ModeNumber
,
177 OUT UINTN
*SizeOfInfo
,
178 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
**Info
181 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
183 if (This
== NULL
|| Info
== NULL
|| SizeOfInfo
== NULL
|| ModeNumber
>= This
->Mode
->MaxMode
) {
184 return EFI_INVALID_PARAMETER
;
188 // retrieve private data
190 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
192 if (Private
->HardwareNeedsStarting
) {
193 return EFI_NOT_STARTED
;
196 *Info
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
199 return EFI_OUT_OF_RESOURCES
;
202 *SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
204 CopyMem (*Info
, &Private
->GraphicsOutputModeBuffer
[ModeNumber
], *SizeOfInfo
);
211 Graphics output protocol interface to set video mode.
213 @param This Protocol instance pointer.
214 @param ModeNumber The mode number to be set.
216 @retval EFI_SUCCESS Graphics mode was changed.
217 @retval EFI_DEVICE_ERROR The device had an error and could not complete
219 @retval EFI_UNSUPPORTED ModeNumber is not supported by this device.
224 ConSpliterGraphicsOutputSetMode (
225 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
* This
,
230 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
232 EFI_STATUS ReturnStatus
;
233 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
;
235 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
238 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
239 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
241 if (ModeNumber
>= This
->Mode
->MaxMode
) {
242 return EFI_UNSUPPORTED
;
245 if (ModeNumber
== This
->Mode
->Mode
) {
249 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
251 ReturnStatus
= EFI_SUCCESS
;
254 // Free the old version
256 if (Private
->GraphicsOutputBlt
!= NULL
) {
257 FreePool (Private
->GraphicsOutputBlt
);
261 // Allocate the virtual Blt buffer
263 Mode
= &Private
->GraphicsOutputModeBuffer
[ModeNumber
];
264 Size
= Mode
->HorizontalResolution
* Mode
->VerticalResolution
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
265 Private
->GraphicsOutputBlt
= AllocateZeroPool (Size
);
267 if (Private
->GraphicsOutputBlt
== NULL
) {
268 return EFI_OUT_OF_RESOURCES
;
272 // return the worst status met
274 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
275 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
276 if (GraphicsOutput
!= NULL
) {
278 // Find corresponding ModeNumber of this GraphicsOutput instance
280 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
281 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
282 if (EFI_ERROR (Status
)) {
285 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) && (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
292 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
293 if (EFI_ERROR (Status
)) {
294 ReturnStatus
= Status
;
298 if (EFI_ERROR (ReturnStatus
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
299 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
300 if (UgaDraw
!= NULL
) {
301 Status
= UgaDraw
->SetMode (
303 Mode
->HorizontalResolution
,
304 Mode
->VerticalResolution
,
308 if (EFI_ERROR (Status
)) {
309 ReturnStatus
= Status
;
315 This
->Mode
->Mode
= ModeNumber
;
317 CopyMem (This
->Mode
->Info
, &Private
->GraphicsOutputModeBuffer
[ModeNumber
], This
->Mode
->SizeOfInfo
);
320 // Information is not enough here, so the following items remain unchanged:
321 // GraphicsOutputMode->Info->Version, GraphicsOutputMode->Info->PixelFormat
322 // GraphicsOutputMode->SizeOfInfo, GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
323 // These items will be initialized/updated when a new GOP device is added into ConsoleSplitter.
326 Private
->HardwareNeedsStarting
= FALSE
;
332 The following table defines actions for BltOperations.
334 EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
335 directly to every pixel of the video display rectangle
336 (DestinationX, DestinationY)
337 (DestinationX + Width, DestinationY + Height).
338 Only one pixel will be used from the BltBuffer. Delta is NOT used.
339 EfiBltVideoToBltBuffer - Read data from the video display rectangle
340 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
341 the BltBuffer rectangle (DestinationX, DestinationY )
342 (DestinationX + Width, DestinationY + Height). If DestinationX or
343 DestinationY is not zero then Delta must be set to the length in bytes
344 of a row in the BltBuffer.
345 EfiBltBufferToVideo - Write data from the BltBuffer rectangle
346 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
347 video display rectangle (DestinationX, DestinationY)
348 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
349 not zero then Delta must be set to the length in bytes of a row in the
351 EfiBltVideoToVideo - Copy from the video display rectangle
352 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
353 to the video display rectangle (DestinationX, DestinationY)
354 (DestinationX + Width, DestinationY + Height).
355 The BltBuffer and Delta are not used in this mode.
357 @param Private Protocol instance pointer.
358 @param BltBuffer Buffer containing data to blit into video buffer.
359 This buffer has a size of
360 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
361 @param BltOperation Operation to perform on BlitBuffer and video
363 @param SourceX X coordinate of source for the BltBuffer.
364 @param SourceY Y coordinate of source for the BltBuffer.
365 @param DestinationX X coordinate of destination for the BltBuffer.
366 @param DestinationY Y coordinate of destination for the BltBuffer.
367 @param Width Width of rectangle in BltBuffer in pixels.
368 @param Height Hight of rectangle in BltBuffer in pixels.
369 @param Delta OPTIONAL.
371 @retval EFI_SUCCESS The Blt operation completed.
372 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
373 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
378 DevNullGraphicsOutputBlt (
379 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
380 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
381 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
384 IN UINTN DestinationX
,
385 IN UINTN DestinationY
,
388 IN UINTN Delta OPTIONAL
394 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltPtr
;
395 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*ScreenPtr
;
396 UINTN HorizontalResolution
;
397 UINTN VerticalResolution
;
399 if ((BltOperation
< EfiBltVideoFill
) || (BltOperation
>= EfiGraphicsOutputBltOperationMax
)) {
400 return EFI_INVALID_PARAMETER
;
403 if (Width
== 0 || Height
== 0) {
404 return EFI_INVALID_PARAMETER
;
408 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
411 HorizontalResolution
= Private
->GraphicsOutput
.Mode
->Info
->HorizontalResolution
;
412 VerticalResolution
= Private
->GraphicsOutput
.Mode
->Info
->VerticalResolution
;
415 // We need to fill the Virtual Screen buffer with the blt data.
417 if (BltOperation
== EfiBltVideoToBltBuffer
) {
419 // Video to BltBuffer: Source is Video, destination is BltBuffer
421 if ((SourceY
+ Height
) > VerticalResolution
) {
422 return EFI_INVALID_PARAMETER
;
425 if ((SourceX
+ Width
) > HorizontalResolution
) {
426 return EFI_INVALID_PARAMETER
;
429 BltPtr
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltBuffer
+ DestinationY
* Delta
+ DestinationX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
430 ScreenPtr
= &Private
->GraphicsOutputBlt
[SourceY
* HorizontalResolution
+ SourceX
];
432 CopyMem (BltPtr
, ScreenPtr
, Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
433 BltPtr
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltPtr
+ Delta
);
434 ScreenPtr
+= HorizontalResolution
;
439 // BltBuffer to Video: Source is BltBuffer, destination is Video
441 if (DestinationY
+ Height
> VerticalResolution
) {
442 return EFI_INVALID_PARAMETER
;
445 if (DestinationX
+ Width
> HorizontalResolution
) {
446 return EFI_INVALID_PARAMETER
;
449 if ((BltOperation
== EfiBltVideoToVideo
) && (DestinationY
> SourceY
)) {
451 // Copy backwards, only care the Video to Video Blt
453 ScreenPtr
= &Private
->GraphicsOutputBlt
[(DestinationY
+ Height
- 1) * HorizontalResolution
+ DestinationX
];
454 SrcY
= SourceY
+ Height
- 1;
458 // Copy forwards, for other cases
460 ScreenPtr
= &Private
->GraphicsOutputBlt
[DestinationY
* HorizontalResolution
+ DestinationX
];
465 while (Height
!= 0) {
466 if (BltOperation
== EfiBltVideoFill
) {
467 for (Index
= 0; Index
< Width
; Index
++) {
468 ScreenPtr
[Index
] = *BltBuffer
;
471 if (BltOperation
== EfiBltBufferToVideo
) {
472 BltPtr
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltBuffer
+ SrcY
* Delta
+ SourceX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
474 BltPtr
= &Private
->GraphicsOutputBlt
[SrcY
* HorizontalResolution
+ SourceX
];
477 CopyMem (ScreenPtr
, BltPtr
, Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
481 ScreenPtr
+= HorizontalResolution
;
484 ScreenPtr
-= HorizontalResolution
;
496 The following table defines actions for BltOperations.
498 EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
499 directly to every pixel of the video display rectangle
500 (DestinationX, DestinationY)
501 (DestinationX + Width, DestinationY + Height).
502 Only one pixel will be used from the BltBuffer. Delta is NOT used.
503 EfiBltVideoToBltBuffer - Read data from the video display rectangle
504 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
505 the BltBuffer rectangle (DestinationX, DestinationY )
506 (DestinationX + Width, DestinationY + Height). If DestinationX or
507 DestinationY is not zero then Delta must be set to the length in bytes
508 of a row in the BltBuffer.
509 EfiBltBufferToVideo - Write data from the BltBuffer rectangle
510 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
511 video display rectangle (DestinationX, DestinationY)
512 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
513 not zero then Delta must be set to the length in bytes of a row in the
515 EfiBltVideoToVideo - Copy from the video display rectangle
516 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
517 to the video display rectangle (DestinationX, DestinationY)
518 (DestinationX + Width, DestinationY + Height).
519 The BltBuffer and Delta are not used in this mode.
521 @param This Protocol instance pointer.
522 @param BltBuffer Buffer containing data to blit into video buffer.
523 This buffer has a size of
524 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
525 @param BltOperation Operation to perform on BlitBuffer and video
527 @param SourceX X coordinate of source for the BltBuffer.
528 @param SourceY Y coordinate of source for the BltBuffer.
529 @param DestinationX X coordinate of destination for the BltBuffer.
530 @param DestinationY Y coordinate of destination for the BltBuffer.
531 @param Width Width of rectangle in BltBuffer in pixels.
532 @param Height Hight of rectangle in BltBuffer in pixels.
533 @param Delta OPTIONAL.
535 @retval EFI_SUCCESS The Blt operation completed.
536 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
537 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
543 ConSpliterGraphicsOutputBlt (
544 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
545 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
546 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
549 IN UINTN DestinationX
,
550 IN UINTN DestinationY
,
553 IN UINTN Delta OPTIONAL
557 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
559 EFI_STATUS ReturnStatus
;
560 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
561 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
563 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
566 // Sync up DevNull GOP device
568 ReturnStatus
= DevNullGraphicsOutputBlt (
581 if (Private
->ConsoleOutputMode
!= EfiConsoleControlScreenGraphics
) {
585 // return the worst status met
587 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
588 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
589 if (GraphicsOutput
!= NULL
) {
590 Status
= GraphicsOutput
->Blt (
602 if (EFI_ERROR (Status
)) {
603 ReturnStatus
= Status
;
604 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
606 // Only need to read the data into buffer one time
612 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
613 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
614 Status
= UgaDraw
->Blt (
616 (EFI_UGA_PIXEL
*) BltBuffer
,
617 (EFI_UGA_BLT_OPERATION
) BltOperation
,
626 if (EFI_ERROR (Status
)) {
627 ReturnStatus
= Status
;
628 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
630 // Only need to read the data into buffer one time
641 Write data from the buffer to video display based on Graphics Output setting.
643 @param Private Consplitter Text Out pointer.
644 @param GraphicsOutput Graphics Output protocol pointer.
645 @param UgaDraw UGA Draw protocol pointer.
647 @retval EFI_UNSUPPORTED No graphics devcie available .
648 @retval EFI_SUCCESS The Blt operation completed.
649 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
650 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video buffer.
656 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
657 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
658 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
661 if (GraphicsOutput
!= NULL
) {
662 return GraphicsOutput
->Blt (
664 Private
->GraphicsOutputBlt
,
670 Private
->GraphicsOutput
.Mode
->Info
->HorizontalResolution
,
671 Private
->GraphicsOutput
.Mode
->Info
->VerticalResolution
,
674 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
675 return UgaDraw
->Blt (
677 (EFI_UGA_PIXEL
*) Private
->GraphicsOutputBlt
,
678 EfiUgaBltBufferToVideo
,
683 Private
->GraphicsOutput
.Mode
->Info
->HorizontalResolution
,
684 Private
->GraphicsOutput
.Mode
->Info
->VerticalResolution
,
688 return EFI_UNSUPPORTED
;
694 Return the current video mode information.
696 @param This Protocol instance pointer.
697 @param HorizontalResolution Current video horizontal resolution in pixels
698 @param VerticalResolution Current video vertical resolution in pixels
699 @param ColorDepth Current video color depth in bits per pixel
700 @param RefreshRate Current video refresh rate in Hz.
702 @retval EFI_SUCCESS Mode information returned.
703 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
704 @retval EFI_INVALID_PARAMETER One of the input args was NULL.
709 ConSpliterUgaDrawGetMode (
710 IN EFI_UGA_DRAW_PROTOCOL
*This
,
711 OUT UINT32
*HorizontalResolution
,
712 OUT UINT32
*VerticalResolution
,
713 OUT UINT32
*ColorDepth
,
714 OUT UINT32
*RefreshRate
717 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
719 if ((HorizontalResolution
== NULL
) ||
720 (VerticalResolution
== NULL
) ||
721 (RefreshRate
== NULL
) ||
722 (ColorDepth
== NULL
)) {
723 return EFI_INVALID_PARAMETER
;
726 // retrieve private data
728 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
730 *HorizontalResolution
= Private
->UgaHorizontalResolution
;
731 *VerticalResolution
= Private
->UgaVerticalResolution
;
732 *ColorDepth
= Private
->UgaColorDepth
;
733 *RefreshRate
= Private
->UgaRefreshRate
;
740 Return the current video mode information.
742 @param This Protocol instance pointer.
743 @param HorizontalResolution Current video horizontal resolution in pixels
744 @param VerticalResolution Current video vertical resolution in pixels
745 @param ColorDepth Current video color depth in bits per pixel
746 @param RefreshRate Current video refresh rate in Hz.
748 @retval EFI_SUCCESS Mode information returned.
749 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
750 @retval EFI_OUT_OF_RESOURCES Out of resources.
755 ConSpliterUgaDrawSetMode (
756 IN EFI_UGA_DRAW_PROTOCOL
*This
,
757 IN UINT32 HorizontalResolution
,
758 IN UINT32 VerticalResolution
,
759 IN UINT32 ColorDepth
,
760 IN UINT32 RefreshRate
764 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
766 EFI_STATUS ReturnStatus
;
768 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
771 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
772 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
774 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
777 // UgaDevNullSetMode ()
779 ReturnStatus
= EFI_SUCCESS
;
782 // Free the old version
784 if (Private
->UgaBlt
!= NULL
) {
785 FreePool (Private
->UgaBlt
);
789 // Allocate the virtual Blt buffer
791 Size
= HorizontalResolution
* VerticalResolution
* sizeof (EFI_UGA_PIXEL
);
792 Private
->UgaBlt
= AllocateZeroPool (Size
);
793 if (Private
->UgaBlt
== NULL
) {
794 return EFI_OUT_OF_RESOURCES
;
798 // Update the Mode data
800 Private
->UgaHorizontalResolution
= HorizontalResolution
;
801 Private
->UgaVerticalResolution
= VerticalResolution
;
802 Private
->UgaColorDepth
= ColorDepth
;
803 Private
->UgaRefreshRate
= RefreshRate
;
805 if (Private
->ConsoleOutputMode
!= EfiConsoleControlScreenGraphics
) {
809 // return the worst status met
811 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
813 ReturnStatus
= EFI_UNSUPPORTED
;
815 if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
816 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
817 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
818 Status
= UgaDraw
->SetMode (
820 HorizontalResolution
,
825 if (EFI_ERROR (Status
)) {
826 ReturnStatus
= Status
;
831 if (EFI_ERROR (ReturnStatus
)) {
832 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
833 if (GraphicsOutput
!= NULL
) {
835 // Find corresponding ModeNumber of this GraphicsOutput instance
837 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
838 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
839 if (EFI_ERROR (Status
)) {
842 if ((Info
->HorizontalResolution
== HorizontalResolution
) && (Info
->VerticalResolution
== VerticalResolution
)) {
849 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
850 if (EFI_ERROR (Status
)) {
851 ReturnStatus
= Status
;
861 The following table defines actions for BltOperations.
863 EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
864 directly to every pixel of the video display rectangle
865 (DestinationX, DestinationY)
866 (DestinationX + Width, DestinationY + Height).
867 Only one pixel will be used from the BltBuffer. Delta is NOT used.
868 EfiBltVideoToBltBuffer - Read data from the video display rectangle
869 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
870 the BltBuffer rectangle (DestinationX, DestinationY )
871 (DestinationX + Width, DestinationY + Height). If DestinationX or
872 DestinationY is not zero then Delta must be set to the length in bytes
873 of a row in the BltBuffer.
874 EfiBltBufferToVideo - Write data from the BltBuffer rectangle
875 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
876 video display rectangle (DestinationX, DestinationY)
877 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
878 not zero then Delta must be set to the length in bytes of a row in the
880 EfiBltVideoToVideo - Copy from the video display rectangle
881 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
882 to the video display rectangle (DestinationX, DestinationY)
883 (DestinationX + Width, DestinationY + Height).
884 The BltBuffer and Delta are not used in this mode.
886 @param Private Protocol instance pointer.
887 @param BltBuffer Buffer containing data to blit into video buffer.
888 This buffer has a size of
889 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
890 @param BltOperation Operation to perform on BlitBuffer and video
892 @param SourceX X coordinate of source for the BltBuffer.
893 @param SourceY Y coordinate of source for the BltBuffer.
894 @param DestinationX X coordinate of destination for the BltBuffer.
895 @param DestinationY Y coordinate of destination for the BltBuffer.
896 @param Width Width of rectangle in BltBuffer in pixels.
897 @param Height Hight of rectangle in BltBuffer in pixels.
898 @param Delta OPTIONAL.
900 @retval EFI_SUCCESS The Blt operation completed.
901 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
902 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
908 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
909 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
910 IN EFI_UGA_BLT_OPERATION BltOperation
,
913 IN UINTN DestinationX
,
914 IN UINTN DestinationY
,
917 IN UINTN Delta OPTIONAL
923 EFI_UGA_PIXEL
*BltPtr
;
924 EFI_UGA_PIXEL
*ScreenPtr
;
925 UINT32 HorizontalResolution
;
926 UINT32 VerticalResolution
;
928 if ((BltOperation
< 0) || (BltOperation
>= EfiUgaBltMax
)) {
929 return EFI_INVALID_PARAMETER
;
932 if (Width
== 0 || Height
== 0) {
933 return EFI_INVALID_PARAMETER
;
937 Delta
= Width
* sizeof (EFI_UGA_PIXEL
);
940 HorizontalResolution
= Private
->UgaHorizontalResolution
;
941 VerticalResolution
= Private
->UgaVerticalResolution
;
944 // We need to fill the Virtual Screen buffer with the blt data.
946 if (BltOperation
== EfiUgaVideoToBltBuffer
) {
948 // Video to BltBuffer: Source is Video, destination is BltBuffer
950 if ((SourceY
+ Height
) > VerticalResolution
) {
951 return EFI_INVALID_PARAMETER
;
954 if ((SourceX
+ Width
) > HorizontalResolution
) {
955 return EFI_INVALID_PARAMETER
;
958 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ DestinationY
* Delta
+ DestinationX
* sizeof (EFI_UGA_PIXEL
));
959 ScreenPtr
= &Private
->UgaBlt
[SourceY
* HorizontalResolution
+ SourceX
];
961 CopyMem (BltPtr
, ScreenPtr
, Width
* sizeof (EFI_UGA_PIXEL
));
962 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltPtr
+ Delta
);
963 ScreenPtr
+= HorizontalResolution
;
968 // BltBuffer to Video: Source is BltBuffer, destination is Video
970 if (DestinationY
+ Height
> VerticalResolution
) {
971 return EFI_INVALID_PARAMETER
;
974 if (DestinationX
+ Width
> HorizontalResolution
) {
975 return EFI_INVALID_PARAMETER
;
978 if ((BltOperation
== EfiUgaVideoToVideo
) && (DestinationY
> SourceY
)) {
980 // Copy backwards, only care the Video to Video Blt
982 ScreenPtr
= &Private
->UgaBlt
[(DestinationY
+ Height
- 1) * HorizontalResolution
+ DestinationX
];
983 SrcY
= SourceY
+ Height
- 1;
987 // Copy forwards, for other cases
989 ScreenPtr
= &Private
->UgaBlt
[DestinationY
* HorizontalResolution
+ DestinationX
];
994 while (Height
!= 0) {
995 if (BltOperation
== EfiUgaVideoFill
) {
996 for (Index
= 0; Index
< Width
; Index
++) {
997 ScreenPtr
[Index
] = *BltBuffer
;
1000 if (BltOperation
== EfiUgaBltBufferToVideo
) {
1001 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ SrcY
* Delta
+ SourceX
* sizeof (EFI_UGA_PIXEL
));
1003 BltPtr
= &Private
->UgaBlt
[SrcY
* HorizontalResolution
+ SourceX
];
1006 CopyMem (ScreenPtr
, BltPtr
, Width
* sizeof (EFI_UGA_PIXEL
));
1010 ScreenPtr
+= HorizontalResolution
;
1013 ScreenPtr
-= HorizontalResolution
;
1025 The following table defines actions for BltOperations.
1027 EfiUgaVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
1028 directly to every pixel of the video display rectangle
1029 (DestinationX, DestinationY)
1030 (DestinationX + Width, DestinationY + Height).
1031 Only one pixel will be used from the BltBuffer. Delta is NOT used.
1032 EfiUgaVideoToBltBuffer - Read data from the video display rectangle
1033 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
1034 the BltBuffer rectangle (DestinationX, DestinationY )
1035 (DestinationX + Width, DestinationY + Height). If DestinationX or
1036 DestinationY is not zero then Delta must be set to the length in bytes
1037 of a row in the BltBuffer.
1038 EfiUgaBltBufferToVideo - Write data from the BltBuffer rectangle
1039 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
1040 video display rectangle (DestinationX, DestinationY)
1041 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
1042 not zero then Delta must be set to the length in bytes of a row in the
1044 EfiUgaVideoToVideo - Copy from the video display rectangle
1045 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
1046 to the video display rectangle (DestinationX, DestinationY)
1047 (DestinationX + Width, DestinationY + Height).
1048 The BltBuffer and Delta are not used in this mode.
1050 @param This Protocol instance pointer.
1051 @param BltBuffer Buffer containing data to blit into video buffer.
1052 This buffer has a size of
1053 Width*Height*sizeof(EFI_UGA_PIXEL)
1054 @param BltOperation Operation to perform on BlitBuffer and video
1056 @param SourceX X coordinate of source for the BltBuffer.
1057 @param SourceY Y coordinate of source for the BltBuffer.
1058 @param DestinationX X coordinate of destination for the BltBuffer.
1059 @param DestinationY Y coordinate of destination for the BltBuffer.
1060 @param Width Width of rectangle in BltBuffer in pixels.
1061 @param Height Hight of rectangle in BltBuffer in pixels.
1062 @param Delta OPTIONAL.
1064 @retval EFI_SUCCESS The Blt operation completed.
1065 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
1066 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
1072 ConSpliterUgaDrawBlt (
1073 IN EFI_UGA_DRAW_PROTOCOL
*This
,
1074 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
1075 IN EFI_UGA_BLT_OPERATION BltOperation
,
1078 IN UINTN DestinationX
,
1079 IN UINTN DestinationY
,
1082 IN UINTN Delta OPTIONAL
1086 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
1088 EFI_STATUS ReturnStatus
;
1089 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1091 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
1094 // Sync up DevNull UGA device
1096 ReturnStatus
= DevNullUgaBlt (
1108 if (Private
->ConsoleOutputMode
!= EfiConsoleControlScreenGraphics
) {
1109 return ReturnStatus
;
1112 // return the worst status met
1114 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
1115 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
1116 if (GraphicsOutput
!= NULL
) {
1117 Status
= GraphicsOutput
->Blt (
1119 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltBuffer
,
1120 (EFI_GRAPHICS_OUTPUT_BLT_OPERATION
) BltOperation
,
1129 if (EFI_ERROR (Status
)) {
1130 ReturnStatus
= Status
;
1131 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
1133 // Only need to read the data into buffer one time
1139 if (Private
->TextOutList
[Index
].UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1140 Status
= Private
->TextOutList
[Index
].UgaDraw
->Blt (
1141 Private
->TextOutList
[Index
].UgaDraw
,
1152 if (EFI_ERROR (Status
)) {
1153 ReturnStatus
= Status
;
1154 } else if (BltOperation
== EfiUgaVideoToBltBuffer
) {
1156 // Only need to read the data into buffer one time
1163 return ReturnStatus
;
1167 Write data from the buffer to video display based on UGA Draw setting.
1169 @param Private Consplitter Text Out pointer.
1170 @param GraphicsOutput Graphics Output protocol pointer.
1171 @param UgaDraw UGA Draw protocol pointer.
1173 @retval EFI_UNSUPPORTED No graphics devcie available .
1174 @retval EFI_SUCCESS The Blt operation completed.
1175 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
1176 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video buffer.
1181 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1182 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
1183 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
1186 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1187 return UgaDraw
->Blt (
1190 EfiUgaBltBufferToVideo
,
1195 Private
->UgaHorizontalResolution
,
1196 Private
->UgaVerticalResolution
,
1197 Private
->UgaHorizontalResolution
* sizeof (EFI_UGA_PIXEL
)
1199 } else if (GraphicsOutput
!= NULL
) {
1200 return GraphicsOutput
->Blt (
1202 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) Private
->UgaBlt
,
1203 EfiBltBufferToVideo
,
1208 Private
->UgaHorizontalResolution
,
1209 Private
->UgaVerticalResolution
,
1213 return EFI_UNSUPPORTED
;
1219 Write a Unicode string to the output device.
1221 @param Private Pointer to the console output splitter's private
1222 data. It indicates the calling context.
1223 @param WString The NULL-terminated Unicode string to be
1224 displayed on the output device(s). All output
1225 devices must also support the Unicode drawing
1226 defined in this file.
1228 @retval EFI_SUCCESS The string was output to the device.
1229 @retval EFI_DEVICE_ERROR The device reported an error while attempting to
1231 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
1233 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
1234 characters in the Unicode string could not be
1235 rendered and were skipped.
1239 DevNullTextOutOutputString (
1240 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1245 UINTN SizeAttribute
;
1247 EFI_SIMPLE_TEXT_OUTPUT_MODE
*Mode
;
1254 INT32
*NullAttributes
;
1259 Mode
= &Private
->TextOutMode
;
1260 NullScreen
= Private
->DevNullScreen
;
1261 NullAttributes
= Private
->DevNullAttributes
;
1262 LastRow
= Private
->DevNullRows
- 1;
1263 MaxColumn
= Private
->DevNullColumns
;
1265 if (Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) {
1271 while (*WString
!= L
'\0') {
1273 if (*WString
== CHAR_BACKSPACE
) {
1275 // If the cursor is at the left edge of the display, then move the cursor
1278 if (Mode
->CursorColumn
== 0 && Mode
->CursorRow
> 0) {
1280 Mode
->CursorColumn
= (INT32
) MaxColumn
;
1284 // If the cursor is not at the left edge of the display,
1285 // then move the cursor left one column.
1287 if (Mode
->CursorColumn
> 0) {
1288 Mode
->CursorColumn
--;
1289 if (Mode
->CursorColumn
> 0 &&
1290 NullAttributes
[Mode
->CursorRow
* MaxColumn
+ Mode
->CursorColumn
- 1] & EFI_WIDE_ATTRIBUTE
1292 Mode
->CursorColumn
--;
1295 // Insert an extra backspace
1297 InsertChar
= CHAR_BACKSPACE
;
1299 while (*PStr
!= L
'\0') {
1302 InsertChar
= TempChar
;
1315 } else if (*WString
== CHAR_LINEFEED
) {
1317 // If the cursor is at the bottom of the display,
1318 // then scroll the display one row, and do not update
1319 // the cursor position. Otherwise, move the cursor down one row.
1321 if (Mode
->CursorRow
== (INT32
) (LastRow
)) {
1323 // Scroll Screen Up One Row
1325 SizeAttribute
= LastRow
* MaxColumn
;
1328 NullAttributes
+ MaxColumn
,
1329 SizeAttribute
* sizeof (INT32
)
1333 // Each row has an ending CHAR_NULL. So one more character each line
1334 // for DevNullScreen than DevNullAttributes
1336 SizeScreen
= SizeAttribute
+ LastRow
;
1339 NullScreen
+ (MaxColumn
+ 1),
1340 SizeScreen
* sizeof (CHAR16
)
1344 // Print Blank Line at last line
1346 Screen
= NullScreen
+ SizeScreen
;
1347 Attribute
= NullAttributes
+ SizeAttribute
;
1349 for (Index
= 0; Index
< MaxColumn
; Index
++, Screen
++, Attribute
++) {
1351 *Attribute
= Mode
->Attribute
;
1358 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
1360 // Move the cursor to the beginning of the current row.
1362 Mode
->CursorColumn
= 0;
1366 // Print the character at the current cursor position and
1367 // move the cursor right one column. If this moves the cursor
1368 // past the right edge of the display, then the line should wrap to
1369 // the beginning of the next line. This is equivalent to inserting
1370 // a CR and an LF. Note that if the cursor is at the bottom of the
1371 // display, and the line wraps, then the display will be scrolled
1374 Index
= Mode
->CursorRow
* MaxColumn
+ Mode
->CursorColumn
;
1376 while (Mode
->CursorColumn
< (INT32
) MaxColumn
) {
1377 if (*WString
== CHAR_NULL
) {
1381 if (*WString
== CHAR_BACKSPACE
) {
1385 if (*WString
== CHAR_LINEFEED
) {
1389 if (*WString
== CHAR_CARRIAGE_RETURN
) {
1393 if (*WString
== UNICODE_WIDE_CHAR
|| *WString
== UNICODE_NARROW_CHAR
) {
1394 CurrentWidth
= (*WString
== UNICODE_WIDE_CHAR
) ? 2 : 1;
1399 if (Mode
->CursorColumn
+ CurrentWidth
> (INT32
) MaxColumn
) {
1401 // If a wide char is at the rightmost column, then move the char
1402 // to the beginning of the next row
1404 NullScreen
[Index
+ Mode
->CursorRow
] = L
' ';
1405 NullAttributes
[Index
] = Mode
->Attribute
| (UINT32
) EFI_WIDE_ATTRIBUTE
;
1407 Mode
->CursorColumn
++;
1409 NullScreen
[Index
+ Mode
->CursorRow
] = *WString
;
1410 NullAttributes
[Index
] = Mode
->Attribute
;
1411 if (CurrentWidth
== 1) {
1412 NullAttributes
[Index
] &= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
1414 NullAttributes
[Index
] |= (UINT32
) EFI_WIDE_ATTRIBUTE
;
1415 NullAttributes
[Index
+ 1] &= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
1418 Index
+= CurrentWidth
;
1420 Mode
->CursorColumn
+= CurrentWidth
;
1424 // At the end of line, output carriage return and line feed
1426 if (Mode
->CursorColumn
>= (INT32
) MaxColumn
) {
1427 DevNullTextOutOutputString (Private
, mCrLfString
);
1437 Sets the output device(s) to a specified mode.
1439 @param Private Private data structure pointer.
1440 @param ModeNumber The mode number to set.
1442 @retval EFI_SUCCESS The requested text mode was set.
1443 @retval EFI_DEVICE_ERROR The device had an error and could not complete
1445 @retval EFI_UNSUPPORTED The mode number was not valid.
1446 @retval EFI_OUT_OF_RESOURCES Out of resources.
1450 DevNullTextOutSetMode (
1451 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1459 TEXT_OUT_SPLITTER_QUERY_DATA
*Mode
;
1462 // No extra check for ModeNumber here, as it has been checked in
1463 // ConSplitterTextOutSetMode. And mode 0 should always be supported.
1464 // Row and Column should be fetched from intersection map.
1466 if (Private
->TextOutModeMap
!= NULL
) {
1467 CurrentMode
= *(Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
);
1469 CurrentMode
= (INT32
) (ModeNumber
);
1471 Mode
= &(Private
->TextOutQueryData
[CurrentMode
]);
1473 Column
= Mode
->Columns
;
1475 if (Row
<= 0 && Column
<= 0) {
1476 return EFI_UNSUPPORTED
;
1479 if (Private
->TextOutMode
.Mode
!= (INT32
) ModeNumber
) {
1481 Private
->TextOutMode
.Mode
= (INT32
) ModeNumber
;
1482 Private
->DevNullColumns
= Column
;
1483 Private
->DevNullRows
= Row
;
1485 if (Private
->DevNullScreen
!= NULL
) {
1486 FreePool (Private
->DevNullScreen
);
1489 Size
= (Row
* (Column
+ 1)) * sizeof (CHAR16
);
1490 Private
->DevNullScreen
= AllocateZeroPool (Size
);
1491 if (Private
->DevNullScreen
== NULL
) {
1492 return EFI_OUT_OF_RESOURCES
;
1495 if (Private
->DevNullAttributes
!= NULL
) {
1496 FreePool (Private
->DevNullAttributes
);
1499 Size
= Row
* Column
* sizeof (INT32
);
1500 Private
->DevNullAttributes
= AllocateZeroPool (Size
);
1501 if (Private
->DevNullAttributes
== NULL
) {
1502 return EFI_OUT_OF_RESOURCES
;
1506 DevNullTextOutClearScreen (Private
);
1513 Clears the output device(s) display to the currently selected background
1516 @param Private Protocol instance pointer.
1518 @retval EFI_SUCCESS The operation completed successfully.
1519 @retval EFI_DEVICE_ERROR The device had an error and could not complete
1521 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
1525 DevNullTextOutClearScreen (
1526 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
1533 INT32 CurrentAttribute
;
1536 // Clear the DevNull Text Out Buffers.
1537 // The screen is filled with spaces.
1538 // The attributes are all synced with the current Simple Text Out Attribute
1540 Screen
= Private
->DevNullScreen
;
1541 Attributes
= Private
->DevNullAttributes
;
1542 CurrentAttribute
= Private
->TextOutMode
.Attribute
;
1544 for (Row
= 0; Row
< Private
->DevNullRows
; Row
++) {
1545 for (Column
= 0; Column
< Private
->DevNullColumns
; Column
++, Screen
++, Attributes
++) {
1547 *Attributes
= CurrentAttribute
;
1550 // Each line of the screen has a NULL on the end so we must skip over it
1555 DevNullTextOutSetCursorPosition (Private
, 0, 0);
1557 return DevNullTextOutEnableCursor (Private
, TRUE
);
1562 Sets the current coordinates of the cursor position.
1564 @param Private Protocol instance pointer.
1566 @param Row the position to set the cursor to. Must be
1567 greater than or equal to zero and less than the
1568 number of columns and rows by QueryMode ().
1570 @retval EFI_SUCCESS The operation completed successfully.
1571 @retval EFI_DEVICE_ERROR The device had an error and could not complete
1573 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or
1574 the cursor position is invalid for the current
1579 DevNullTextOutSetCursorPosition (
1580 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1586 // No need to do extra check here as whether (Column, Row) is valid has
1587 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
1588 // always be supported.
1590 Private
->TextOutMode
.CursorColumn
= (INT32
) Column
;
1591 Private
->TextOutMode
.CursorRow
= (INT32
) Row
;
1598 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1599 In this driver, the cursor cannot be hidden.
1601 @param Private Indicates the calling context.
1602 @param Visible If TRUE, the cursor is set to be visible, If
1603 FALSE, the cursor is set to be invisible.
1605 @retval EFI_SUCCESS The request is valid.
1609 DevNullTextOutEnableCursor (
1610 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1614 Private
->TextOutMode
.CursorVisible
= Visible
;
1621 Take the DevNull TextOut device and update the Simple Text Out on every
1624 @param Private Indicates the calling context.
1626 @retval EFI_SUCCESS The request is valid.
1627 @retval other Return status of TextOut->OutputString ()
1632 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
1636 EFI_STATUS ReturnStatus
;
1641 UINTN CurrentColumn
;
1644 INT32 StartAttribute
;
1645 BOOLEAN StartCursorState
;
1650 CHAR16
*ScreenStart
;
1651 INT32 CurrentAttribute
;
1653 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Sto
;
1656 // Save the devices Attributes, Cursor enable state and location
1658 StartColumn
= Private
->TextOutMode
.CursorColumn
;
1659 StartRow
= Private
->TextOutMode
.CursorRow
;
1660 StartAttribute
= Private
->TextOutMode
.Attribute
;
1661 StartCursorState
= Private
->TextOutMode
.CursorVisible
;
1663 for (List
= 0; List
< Private
->CurrentNumberOfConsoles
; List
++) {
1665 Sto
= Private
->TextOutList
[List
].TextOut
;
1668 // Skip non GOP/UGA devices
1670 if ((Private
->TextOutList
[List
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[List
].UgaDraw
!= NULL
)) {
1671 Sto
->EnableCursor (Sto
, FALSE
);
1672 Sto
->ClearScreen (Sto
);
1676 ReturnStatus
= EFI_SUCCESS
;
1677 Screen
= Private
->DevNullScreen
;
1678 Attributes
= Private
->DevNullAttributes
;
1679 MaxColumn
= Private
->DevNullColumns
;
1681 Buffer
= AllocateZeroPool ((MaxColumn
+ 1) * sizeof (CHAR16
));
1682 if (Buffer
== NULL
) {
1683 return ReturnStatus
;
1686 for (Row
= 0; Row
< Private
->DevNullRows
; Row
++, Screen
+= (MaxColumn
+ 1), Attributes
+= MaxColumn
) {
1688 if (Row
== (Private
->DevNullRows
- 1)) {
1690 // Don't ever sync the last character as it will scroll the screen
1692 Screen
[MaxColumn
- 1] = 0x00;
1696 while (Column
< MaxColumn
) {
1697 if (Screen
[Column
] > 0) {
1698 CurrentAttribute
= Attributes
[Column
];
1699 CurrentColumn
= Column
;
1700 ScreenStart
= &Screen
[Column
];
1703 // the line end is alway 0x0. So Column should be less than MaxColumn
1704 // It should be still in the same row
1706 for (Str
= ScreenStart
, BufferTail
= Buffer
; *Str
!= 0; Str
++, Column
++) {
1708 if (Attributes
[Column
] != CurrentAttribute
) {
1715 if ((Attributes
[Column
] & EFI_WIDE_ATTRIBUTE
) != 0) {
1723 for (List
= 0; List
< Private
->CurrentNumberOfConsoles
; List
++) {
1725 Sto
= Private
->TextOutList
[List
].TextOut
;
1728 // Skip non GOP/UGA devices
1730 if ((Private
->TextOutList
[List
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[List
].UgaDraw
!= NULL
)) {
1731 Sto
->SetAttribute (Sto
, CurrentAttribute
);
1732 Sto
->SetCursorPosition (Sto
, CurrentColumn
, Row
);
1733 Status
= Sto
->OutputString (Sto
, Buffer
);
1734 if (EFI_ERROR (Status
)) {
1735 ReturnStatus
= Status
;
1746 // Restore the devices Attributes, Cursor enable state and location
1748 for (List
= 0; List
< Private
->CurrentNumberOfConsoles
; List
++) {
1749 Sto
= Private
->TextOutList
[List
].TextOut
;
1752 // Skip non GOP/UGA devices
1754 if ((Private
->TextOutList
[List
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[List
].UgaDraw
!= NULL
)) {
1755 Sto
->SetAttribute (Sto
, StartAttribute
);
1756 Sto
->SetCursorPosition (Sto
, StartColumn
, StartRow
);
1757 Status
= Sto
->EnableCursor (Sto
, StartCursorState
);
1758 if (EFI_ERROR (Status
)) {
1759 ReturnStatus
= Status
;
1766 return ReturnStatus
;