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 STATIC 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 GopExists TRUE if GOP Spliter has found a GOP/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
*GopExists
,
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 (GopExists
!= NULL
) {
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
);
251 // GopDevNullSetMode ()
253 ReturnStatus
= EFI_SUCCESS
;
256 // Free the old version
258 if (Private
->GraphicsOutputBlt
!= NULL
) {
259 FreePool (Private
->GraphicsOutputBlt
);
263 // Allocate the virtual Blt buffer
265 Mode
= &Private
->GraphicsOutputModeBuffer
[ModeNumber
];
266 Size
= Mode
->HorizontalResolution
* Mode
->VerticalResolution
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
267 Private
->GraphicsOutputBlt
= AllocateZeroPool (Size
);
269 if (Private
->GraphicsOutputBlt
== NULL
) {
270 return EFI_OUT_OF_RESOURCES
;
274 // return the worst status met
276 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
277 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
278 if (GraphicsOutput
!= NULL
) {
280 // Find corresponding ModeNumber of this GraphicsOutput instance
282 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
283 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
284 if (EFI_ERROR (Status
)) {
287 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) && (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
294 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
295 if (EFI_ERROR (Status
)) {
296 ReturnStatus
= Status
;
300 if (EFI_ERROR (ReturnStatus
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
301 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
302 if (UgaDraw
!= NULL
) {
303 Status
= UgaDraw
->SetMode (
305 Mode
->HorizontalResolution
,
306 Mode
->VerticalResolution
,
310 if (EFI_ERROR (Status
)) {
311 ReturnStatus
= Status
;
317 This
->Mode
->Mode
= ModeNumber
;
319 CopyMem (This
->Mode
->Info
, &Private
->GraphicsOutputModeBuffer
[ModeNumber
], This
->Mode
->SizeOfInfo
);
322 // Information is not enough here, so the following items remain unchanged:
323 // GraphicsOutputMode->Info->Version, GraphicsOutputMode->Info->PixelFormat
324 // GraphicsOutputMode->SizeOfInfo, GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
325 // These items will be initialized/updated when a new GOP device is added into ConsoleSplitter.
328 Private
->HardwareNeedsStarting
= FALSE
;
334 The following table defines actions for BltOperations.
336 EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
337 directly to every pixel of the video display rectangle
338 (DestinationX, DestinationY)
339 (DestinationX + Width, DestinationY + Height).
340 Only one pixel will be used from the BltBuffer. Delta is NOT used.
341 EfiBltVideoToBltBuffer - Read data from the video display rectangle
342 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
343 the BltBuffer rectangle (DestinationX, DestinationY )
344 (DestinationX + Width, DestinationY + Height). If DestinationX or
345 DestinationY is not zero then Delta must be set to the length in bytes
346 of a row in the BltBuffer.
347 EfiBltBufferToVideo - Write data from the BltBuffer rectangle
348 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
349 video display rectangle (DestinationX, DestinationY)
350 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
351 not zero then Delta must be set to the length in bytes of a row in the
353 EfiBltVideoToVideo - Copy from the video display rectangle
354 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
355 to the video display rectangle (DestinationX, DestinationY)
356 (DestinationX + Width, DestinationY + Height).
357 The BltBuffer and Delta are not used in this mode.
359 @param Private Protocol instance pointer.
360 @param BltBuffer Buffer containing data to blit into video buffer.
361 This buffer has a size of
362 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
363 @param BltOperation Operation to perform on BlitBuffer and video
365 @param SourceX X coordinate of source for the BltBuffer.
366 @param SourceY Y coordinate of source for the BltBuffer.
367 @param DestinationX X coordinate of destination for the BltBuffer.
368 @param DestinationY Y coordinate of destination for the BltBuffer.
369 @param Width Width of rectangle in BltBuffer in pixels.
370 @param Height Hight of rectangle in BltBuffer in pixels.
371 @param Delta OPTIONAL.
373 @retval EFI_SUCCESS The Blt operation completed.
374 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
375 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
380 DevNullGraphicsOutputBlt (
381 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
382 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
383 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
386 IN UINTN DestinationX
,
387 IN UINTN DestinationY
,
390 IN UINTN Delta OPTIONAL
396 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltPtr
;
397 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*ScreenPtr
;
398 UINTN HorizontalResolution
;
399 UINTN VerticalResolution
;
401 if ((BltOperation
< EfiBltVideoFill
) || (BltOperation
>= EfiGraphicsOutputBltOperationMax
)) {
402 return EFI_INVALID_PARAMETER
;
405 if (Width
== 0 || Height
== 0) {
406 return EFI_INVALID_PARAMETER
;
410 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
413 HorizontalResolution
= Private
->GraphicsOutput
.Mode
->Info
->HorizontalResolution
;
414 VerticalResolution
= Private
->GraphicsOutput
.Mode
->Info
->VerticalResolution
;
417 // We need to fill the Virtual Screen buffer with the blt data.
419 if (BltOperation
== EfiBltVideoToBltBuffer
) {
421 // Video to BltBuffer: Source is Video, destination is BltBuffer
423 if ((SourceY
+ Height
) > VerticalResolution
) {
424 return EFI_INVALID_PARAMETER
;
427 if ((SourceX
+ Width
) > HorizontalResolution
) {
428 return EFI_INVALID_PARAMETER
;
431 BltPtr
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltBuffer
+ DestinationY
* Delta
+ DestinationX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
432 ScreenPtr
= &Private
->GraphicsOutputBlt
[SourceY
* HorizontalResolution
+ SourceX
];
434 CopyMem (BltPtr
, ScreenPtr
, Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
435 BltPtr
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltPtr
+ Delta
);
436 ScreenPtr
+= HorizontalResolution
;
441 // BltBuffer to Video: Source is BltBuffer, destination is Video
443 if (DestinationY
+ Height
> VerticalResolution
) {
444 return EFI_INVALID_PARAMETER
;
447 if (DestinationX
+ Width
> HorizontalResolution
) {
448 return EFI_INVALID_PARAMETER
;
451 if ((BltOperation
== EfiBltVideoToVideo
) && (DestinationY
> SourceY
)) {
453 // Copy backwards, only care the Video to Video Blt
455 ScreenPtr
= &Private
->GraphicsOutputBlt
[(DestinationY
+ Height
- 1) * HorizontalResolution
+ DestinationX
];
456 SrcY
= SourceY
+ Height
- 1;
460 // Copy forwards, for other cases
462 ScreenPtr
= &Private
->GraphicsOutputBlt
[DestinationY
* HorizontalResolution
+ DestinationX
];
467 while (Height
!= 0) {
468 if (BltOperation
== EfiBltVideoFill
) {
469 for (Index
= 0; Index
< Width
; Index
++) {
470 ScreenPtr
[Index
] = *BltBuffer
;
473 if (BltOperation
== EfiBltBufferToVideo
) {
474 BltPtr
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltBuffer
+ SrcY
* Delta
+ SourceX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
476 BltPtr
= &Private
->GraphicsOutputBlt
[SrcY
* HorizontalResolution
+ SourceX
];
479 CopyMem (ScreenPtr
, BltPtr
, Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
483 ScreenPtr
+= HorizontalResolution
;
486 ScreenPtr
-= HorizontalResolution
;
498 The following table defines actions for BltOperations.
500 EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
501 directly to every pixel of the video display rectangle
502 (DestinationX, DestinationY)
503 (DestinationX + Width, DestinationY + Height).
504 Only one pixel will be used from the BltBuffer. Delta is NOT used.
505 EfiBltVideoToBltBuffer - Read data from the video display rectangle
506 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
507 the BltBuffer rectangle (DestinationX, DestinationY )
508 (DestinationX + Width, DestinationY + Height). If DestinationX or
509 DestinationY is not zero then Delta must be set to the length in bytes
510 of a row in the BltBuffer.
511 EfiBltBufferToVideo - Write data from the BltBuffer rectangle
512 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
513 video display rectangle (DestinationX, DestinationY)
514 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
515 not zero then Delta must be set to the length in bytes of a row in the
517 EfiBltVideoToVideo - Copy from the video display rectangle
518 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
519 to the video display rectangle (DestinationX, DestinationY)
520 (DestinationX + Width, DestinationY + Height).
521 The BltBuffer and Delta are not used in this mode.
523 @param This Protocol instance pointer.
524 @param BltBuffer Buffer containing data to blit into video buffer.
525 This buffer has a size of
526 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
527 @param BltOperation Operation to perform on BlitBuffer and video
529 @param SourceX X coordinate of source for the BltBuffer.
530 @param SourceY Y coordinate of source for the BltBuffer.
531 @param DestinationX X coordinate of destination for the BltBuffer.
532 @param DestinationY Y coordinate of destination for the BltBuffer.
533 @param Width Width of rectangle in BltBuffer in pixels.
534 @param Height Hight of rectangle in BltBuffer in pixels.
535 @param Delta OPTIONAL.
537 @retval EFI_SUCCESS The Blt operation completed.
538 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
539 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
545 ConSpliterGraphicsOutputBlt (
546 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
547 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
548 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
551 IN UINTN DestinationX
,
552 IN UINTN DestinationY
,
555 IN UINTN Delta OPTIONAL
559 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
561 EFI_STATUS ReturnStatus
;
562 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
563 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
565 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
568 // Sync up DevNull GOP device
570 ReturnStatus
= DevNullGraphicsOutputBlt (
583 if (Private
->ConsoleOutputMode
!= EfiConsoleControlScreenGraphics
) {
587 // return the worst status met
589 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
590 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
591 if (GraphicsOutput
!= NULL
) {
592 Status
= GraphicsOutput
->Blt (
604 if (EFI_ERROR (Status
)) {
605 ReturnStatus
= Status
;
606 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
608 // Only need to read the data into buffer one time
614 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
615 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
616 Status
= UgaDraw
->Blt (
618 (EFI_UGA_PIXEL
*) BltBuffer
,
619 (EFI_UGA_BLT_OPERATION
) BltOperation
,
628 if (EFI_ERROR (Status
)) {
629 ReturnStatus
= Status
;
630 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
632 // Only need to read the data into buffer one time
643 Write data from the buffer to video display based on Graphics Output setting.
645 @param Private Consplitter Text Out pointer.
646 @param GraphicsOutput Graphics Output protocol pointer.
647 @param UgaDraw UGA Draw protocol pointer.
649 @retval EFI_UNSUPPORTED No graphics devcie available .
650 @retval EFI_SUCCESS The Blt operation completed.
651 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
652 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video buffer.
658 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
659 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
660 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
663 if (GraphicsOutput
!= NULL
) {
664 return GraphicsOutput
->Blt (
666 Private
->GraphicsOutputBlt
,
672 Private
->GraphicsOutput
.Mode
->Info
->HorizontalResolution
,
673 Private
->GraphicsOutput
.Mode
->Info
->VerticalResolution
,
676 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
677 return UgaDraw
->Blt (
679 (EFI_UGA_PIXEL
*) Private
->GraphicsOutputBlt
,
680 EfiUgaBltBufferToVideo
,
685 Private
->GraphicsOutput
.Mode
->Info
->HorizontalResolution
,
686 Private
->GraphicsOutput
.Mode
->Info
->VerticalResolution
,
690 return EFI_UNSUPPORTED
;
696 Return the current video mode information.
698 @param This Protocol instance pointer.
699 @param HorizontalResolution Current video horizontal resolution in pixels
700 @param VerticalResolution Current video vertical resolution in pixels
701 @param ColorDepth Current video color depth in bits per pixel
702 @param RefreshRate Current video refresh rate in Hz.
704 @retval EFI_SUCCESS Mode information returned.
705 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
706 @retval EFI_INVALID_PARAMETER One of the input args was NULL.
711 ConSpliterUgaDrawGetMode (
712 IN EFI_UGA_DRAW_PROTOCOL
*This
,
713 OUT UINT32
*HorizontalResolution
,
714 OUT UINT32
*VerticalResolution
,
715 OUT UINT32
*ColorDepth
,
716 OUT UINT32
*RefreshRate
719 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
721 if ((HorizontalResolution
== NULL
) ||
722 (VerticalResolution
== NULL
) ||
723 (RefreshRate
== NULL
) ||
724 (ColorDepth
== NULL
)) {
725 return EFI_INVALID_PARAMETER
;
728 // retrieve private data
730 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
732 *HorizontalResolution
= Private
->UgaHorizontalResolution
;
733 *VerticalResolution
= Private
->UgaVerticalResolution
;
734 *ColorDepth
= Private
->UgaColorDepth
;
735 *RefreshRate
= Private
->UgaRefreshRate
;
742 Return the current video mode information.
744 @param This Protocol instance pointer.
745 @param HorizontalResolution Current video horizontal resolution in pixels
746 @param VerticalResolution Current video vertical resolution in pixels
747 @param ColorDepth Current video color depth in bits per pixel
748 @param RefreshRate Current video refresh rate in Hz.
750 @retval EFI_SUCCESS Mode information returned.
751 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
752 @retval EFI_OUT_OF_RESOURCES Out of resources.
757 ConSpliterUgaDrawSetMode (
758 IN EFI_UGA_DRAW_PROTOCOL
*This
,
759 IN UINT32 HorizontalResolution
,
760 IN UINT32 VerticalResolution
,
761 IN UINT32 ColorDepth
,
762 IN UINT32 RefreshRate
766 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
768 EFI_STATUS ReturnStatus
;
770 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
773 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
774 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
776 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
779 // UgaDevNullSetMode ()
781 ReturnStatus
= EFI_SUCCESS
;
784 // Free the old version
786 if (Private
->UgaBlt
!= NULL
) {
787 FreePool (Private
->UgaBlt
);
791 // Allocate the virtual Blt buffer
793 Size
= HorizontalResolution
* VerticalResolution
* sizeof (EFI_UGA_PIXEL
);
794 Private
->UgaBlt
= AllocateZeroPool (Size
);
795 if (Private
->UgaBlt
== NULL
) {
796 return EFI_OUT_OF_RESOURCES
;
800 // Update the Mode data
802 Private
->UgaHorizontalResolution
= HorizontalResolution
;
803 Private
->UgaVerticalResolution
= VerticalResolution
;
804 Private
->UgaColorDepth
= ColorDepth
;
805 Private
->UgaRefreshRate
= RefreshRate
;
807 if (Private
->ConsoleOutputMode
!= EfiConsoleControlScreenGraphics
) {
811 // return the worst status met
813 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
815 ReturnStatus
= EFI_UNSUPPORTED
;
817 if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
818 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
819 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
820 Status
= UgaDraw
->SetMode (
822 HorizontalResolution
,
827 if (EFI_ERROR (Status
)) {
828 ReturnStatus
= Status
;
833 if (EFI_ERROR (ReturnStatus
)) {
834 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
835 if (GraphicsOutput
!= NULL
) {
837 // Find corresponding ModeNumber of this GraphicsOutput instance
839 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
840 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
841 if (EFI_ERROR (Status
)) {
844 if ((Info
->HorizontalResolution
== HorizontalResolution
) && (Info
->VerticalResolution
== VerticalResolution
)) {
851 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
852 if (EFI_ERROR (Status
)) {
853 ReturnStatus
= Status
;
863 The following table defines actions for BltOperations.
865 EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
866 directly to every pixel of the video display rectangle
867 (DestinationX, DestinationY)
868 (DestinationX + Width, DestinationY + Height).
869 Only one pixel will be used from the BltBuffer. Delta is NOT used.
870 EfiBltVideoToBltBuffer - Read data from the video display rectangle
871 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
872 the BltBuffer rectangle (DestinationX, DestinationY )
873 (DestinationX + Width, DestinationY + Height). If DestinationX or
874 DestinationY is not zero then Delta must be set to the length in bytes
875 of a row in the BltBuffer.
876 EfiBltBufferToVideo - Write data from the BltBuffer rectangle
877 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
878 video display rectangle (DestinationX, DestinationY)
879 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
880 not zero then Delta must be set to the length in bytes of a row in the
882 EfiBltVideoToVideo - Copy from the video display rectangle
883 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
884 to the video display rectangle (DestinationX, DestinationY)
885 (DestinationX + Width, DestinationY + Height).
886 The BltBuffer and Delta are not used in this mode.
888 @param Private Protocol instance pointer.
889 @param BltBuffer Buffer containing data to blit into video buffer.
890 This buffer has a size of
891 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
892 @param BltOperation Operation to perform on BlitBuffer and video
894 @param SourceX X coordinate of source for the BltBuffer.
895 @param SourceY Y coordinate of source for the BltBuffer.
896 @param DestinationX X coordinate of destination for the BltBuffer.
897 @param DestinationY Y coordinate of destination for the BltBuffer.
898 @param Width Width of rectangle in BltBuffer in pixels.
899 @param Height Hight of rectangle in BltBuffer in pixels.
900 @param Delta OPTIONAL.
902 @retval EFI_SUCCESS The Blt operation completed.
903 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
904 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
910 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
911 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
912 IN EFI_UGA_BLT_OPERATION BltOperation
,
915 IN UINTN DestinationX
,
916 IN UINTN DestinationY
,
919 IN UINTN Delta OPTIONAL
925 EFI_UGA_PIXEL
*BltPtr
;
926 EFI_UGA_PIXEL
*ScreenPtr
;
927 UINT32 HorizontalResolution
;
928 UINT32 VerticalResolution
;
930 if ((BltOperation
< 0) || (BltOperation
>= EfiUgaBltMax
)) {
931 return EFI_INVALID_PARAMETER
;
934 if (Width
== 0 || Height
== 0) {
935 return EFI_INVALID_PARAMETER
;
939 Delta
= Width
* sizeof (EFI_UGA_PIXEL
);
942 HorizontalResolution
= Private
->UgaHorizontalResolution
;
943 VerticalResolution
= Private
->UgaVerticalResolution
;
946 // We need to fill the Virtual Screen buffer with the blt data.
948 if (BltOperation
== EfiUgaVideoToBltBuffer
) {
950 // Video to BltBuffer: Source is Video, destination is BltBuffer
952 if ((SourceY
+ Height
) > VerticalResolution
) {
953 return EFI_INVALID_PARAMETER
;
956 if ((SourceX
+ Width
) > HorizontalResolution
) {
957 return EFI_INVALID_PARAMETER
;
960 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ DestinationY
* Delta
+ DestinationX
* sizeof (EFI_UGA_PIXEL
));
961 ScreenPtr
= &Private
->UgaBlt
[SourceY
* HorizontalResolution
+ SourceX
];
963 CopyMem (BltPtr
, ScreenPtr
, Width
* sizeof (EFI_UGA_PIXEL
));
964 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltPtr
+ Delta
);
965 ScreenPtr
+= HorizontalResolution
;
970 // BltBuffer to Video: Source is BltBuffer, destination is Video
972 if (DestinationY
+ Height
> VerticalResolution
) {
973 return EFI_INVALID_PARAMETER
;
976 if (DestinationX
+ Width
> HorizontalResolution
) {
977 return EFI_INVALID_PARAMETER
;
980 if ((BltOperation
== EfiUgaVideoToVideo
) && (DestinationY
> SourceY
)) {
982 // Copy backwards, only care the Video to Video Blt
984 ScreenPtr
= &Private
->UgaBlt
[(DestinationY
+ Height
- 1) * HorizontalResolution
+ DestinationX
];
985 SrcY
= SourceY
+ Height
- 1;
989 // Copy forwards, for other cases
991 ScreenPtr
= &Private
->UgaBlt
[DestinationY
* HorizontalResolution
+ DestinationX
];
996 while (Height
!= 0) {
997 if (BltOperation
== EfiUgaVideoFill
) {
998 for (Index
= 0; Index
< Width
; Index
++) {
999 ScreenPtr
[Index
] = *BltBuffer
;
1002 if (BltOperation
== EfiUgaBltBufferToVideo
) {
1003 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ SrcY
* Delta
+ SourceX
* sizeof (EFI_UGA_PIXEL
));
1005 BltPtr
= &Private
->UgaBlt
[SrcY
* HorizontalResolution
+ SourceX
];
1008 CopyMem (ScreenPtr
, BltPtr
, Width
* sizeof (EFI_UGA_PIXEL
));
1012 ScreenPtr
+= HorizontalResolution
;
1015 ScreenPtr
-= HorizontalResolution
;
1027 The following table defines actions for BltOperations.
1029 EfiUgaVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
1030 directly to every pixel of the video display rectangle
1031 (DestinationX, DestinationY)
1032 (DestinationX + Width, DestinationY + Height).
1033 Only one pixel will be used from the BltBuffer. Delta is NOT used.
1034 EfiUgaVideoToBltBuffer - Read data from the video display rectangle
1035 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
1036 the BltBuffer rectangle (DestinationX, DestinationY )
1037 (DestinationX + Width, DestinationY + Height). If DestinationX or
1038 DestinationY is not zero then Delta must be set to the length in bytes
1039 of a row in the BltBuffer.
1040 EfiUgaBltBufferToVideo - Write data from the BltBuffer rectangle
1041 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
1042 video display rectangle (DestinationX, DestinationY)
1043 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
1044 not zero then Delta must be set to the length in bytes of a row in the
1046 EfiUgaVideoToVideo - Copy from the video display rectangle
1047 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
1048 to the video display rectangle (DestinationX, DestinationY)
1049 (DestinationX + Width, DestinationY + Height).
1050 The BltBuffer and Delta are not used in this mode.
1052 @param This Protocol instance pointer.
1053 @param BltBuffer Buffer containing data to blit into video buffer.
1054 This buffer has a size of
1055 Width*Height*sizeof(EFI_UGA_PIXEL)
1056 @param BltOperation Operation to perform on BlitBuffer and video
1058 @param SourceX X coordinate of source for the BltBuffer.
1059 @param SourceY Y coordinate of source for the BltBuffer.
1060 @param DestinationX X coordinate of destination for the BltBuffer.
1061 @param DestinationY Y coordinate of destination for the BltBuffer.
1062 @param Width Width of rectangle in BltBuffer in pixels.
1063 @param Height Hight of rectangle in BltBuffer in pixels.
1064 @param Delta OPTIONAL.
1066 @retval EFI_SUCCESS The Blt operation completed.
1067 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
1068 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
1074 ConSpliterUgaDrawBlt (
1075 IN EFI_UGA_DRAW_PROTOCOL
*This
,
1076 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
1077 IN EFI_UGA_BLT_OPERATION BltOperation
,
1080 IN UINTN DestinationX
,
1081 IN UINTN DestinationY
,
1084 IN UINTN Delta OPTIONAL
1088 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
1090 EFI_STATUS ReturnStatus
;
1091 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1093 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
1096 // Sync up DevNull UGA device
1098 ReturnStatus
= DevNullUgaBlt (
1110 if (Private
->ConsoleOutputMode
!= EfiConsoleControlScreenGraphics
) {
1111 return ReturnStatus
;
1114 // return the worst status met
1116 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
1117 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
1118 if (GraphicsOutput
!= NULL
) {
1119 Status
= GraphicsOutput
->Blt (
1121 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltBuffer
,
1122 (EFI_GRAPHICS_OUTPUT_BLT_OPERATION
) BltOperation
,
1131 if (EFI_ERROR (Status
)) {
1132 ReturnStatus
= Status
;
1133 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
1135 // Only need to read the data into buffer one time
1141 if (Private
->TextOutList
[Index
].UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1142 Status
= Private
->TextOutList
[Index
].UgaDraw
->Blt (
1143 Private
->TextOutList
[Index
].UgaDraw
,
1154 if (EFI_ERROR (Status
)) {
1155 ReturnStatus
= Status
;
1156 } else if (BltOperation
== EfiUgaVideoToBltBuffer
) {
1158 // Only need to read the data into buffer one time
1165 return ReturnStatus
;
1169 Write data from the buffer to video display based on UGA Draw setting.
1171 @param Private Consplitter Text Out pointer.
1172 @param GraphicsOutput Graphics Output protocol pointer.
1173 @param UgaDraw UGA Draw protocol pointer.
1175 @retval EFI_UNSUPPORTED No graphics devcie available .
1176 @retval EFI_SUCCESS The Blt operation completed.
1177 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
1178 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video buffer.
1183 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1184 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
1185 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
1188 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1189 return UgaDraw
->Blt (
1192 EfiUgaBltBufferToVideo
,
1197 Private
->UgaHorizontalResolution
,
1198 Private
->UgaVerticalResolution
,
1199 Private
->UgaHorizontalResolution
* sizeof (EFI_UGA_PIXEL
)
1201 } else if (GraphicsOutput
!= NULL
) {
1202 return GraphicsOutput
->Blt (
1204 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) Private
->UgaBlt
,
1205 EfiBltBufferToVideo
,
1210 Private
->UgaHorizontalResolution
,
1211 Private
->UgaVerticalResolution
,
1215 return EFI_UNSUPPORTED
;
1221 Write a Unicode string to the output device.
1223 @param Private Pointer to the console output splitter's private
1224 data. It indicates the calling context.
1225 @param WString The NULL-terminated Unicode string to be
1226 displayed on the output device(s). All output
1227 devices must also support the Unicode drawing
1228 defined in this file.
1230 @retval EFI_SUCCESS The string was output to the device.
1231 @retval EFI_DEVICE_ERROR The device reported an error while attempting to
1233 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
1235 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
1236 characters in the Unicode string could not be
1237 rendered and were skipped.
1241 DevNullTextOutOutputString (
1242 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1247 UINTN SizeAttribute
;
1249 EFI_SIMPLE_TEXT_OUTPUT_MODE
*Mode
;
1256 INT32
*NullAttributes
;
1261 Mode
= &Private
->TextOutMode
;
1262 NullScreen
= Private
->DevNullScreen
;
1263 NullAttributes
= Private
->DevNullAttributes
;
1264 LastRow
= Private
->DevNullRows
- 1;
1265 MaxColumn
= Private
->DevNullColumns
;
1267 if (Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) {
1273 while (*WString
!= L
'\0') {
1275 if (*WString
== CHAR_BACKSPACE
) {
1277 // If the cursor is at the left edge of the display, then move the cursor
1280 if (Mode
->CursorColumn
== 0 && Mode
->CursorRow
> 0) {
1282 Mode
->CursorColumn
= (INT32
) MaxColumn
;
1286 // If the cursor is not at the left edge of the display,
1287 // then move the cursor left one column.
1289 if (Mode
->CursorColumn
> 0) {
1290 Mode
->CursorColumn
--;
1291 if (Mode
->CursorColumn
> 0 &&
1292 NullAttributes
[Mode
->CursorRow
* MaxColumn
+ Mode
->CursorColumn
- 1] & EFI_WIDE_ATTRIBUTE
1294 Mode
->CursorColumn
--;
1297 // Insert an extra backspace
1299 InsertChar
= CHAR_BACKSPACE
;
1301 while (*PStr
!= L
'\0') {
1304 InsertChar
= TempChar
;
1317 } else if (*WString
== CHAR_LINEFEED
) {
1319 // If the cursor is at the bottom of the display,
1320 // then scroll the display one row, and do not update
1321 // the cursor position. Otherwise, move the cursor down one row.
1323 if (Mode
->CursorRow
== (INT32
) (LastRow
)) {
1325 // Scroll Screen Up One Row
1327 SizeAttribute
= LastRow
* MaxColumn
;
1330 NullAttributes
+ MaxColumn
,
1331 SizeAttribute
* sizeof (INT32
)
1335 // Each row has an ending CHAR_NULL. So one more character each line
1336 // for DevNullScreen than DevNullAttributes
1338 SizeScreen
= SizeAttribute
+ LastRow
;
1341 NullScreen
+ (MaxColumn
+ 1),
1342 SizeScreen
* sizeof (CHAR16
)
1346 // Print Blank Line at last line
1348 Screen
= NullScreen
+ SizeScreen
;
1349 Attribute
= NullAttributes
+ SizeAttribute
;
1351 for (Index
= 0; Index
< MaxColumn
; Index
++, Screen
++, Attribute
++) {
1353 *Attribute
= Mode
->Attribute
;
1360 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
1362 // Move the cursor to the beginning of the current row.
1364 Mode
->CursorColumn
= 0;
1368 // Print the character at the current cursor position and
1369 // move the cursor right one column. If this moves the cursor
1370 // past the right edge of the display, then the line should wrap to
1371 // the beginning of the next line. This is equivalent to inserting
1372 // a CR and an LF. Note that if the cursor is at the bottom of the
1373 // display, and the line wraps, then the display will be scrolled
1376 Index
= Mode
->CursorRow
* MaxColumn
+ Mode
->CursorColumn
;
1378 while (Mode
->CursorColumn
< (INT32
) MaxColumn
) {
1379 if (*WString
== CHAR_NULL
) {
1383 if (*WString
== CHAR_BACKSPACE
) {
1387 if (*WString
== CHAR_LINEFEED
) {
1391 if (*WString
== CHAR_CARRIAGE_RETURN
) {
1395 if (*WString
== UNICODE_WIDE_CHAR
|| *WString
== UNICODE_NARROW_CHAR
) {
1396 CurrentWidth
= (*WString
== UNICODE_WIDE_CHAR
) ? 2 : 1;
1401 if (Mode
->CursorColumn
+ CurrentWidth
> (INT32
) MaxColumn
) {
1403 // If a wide char is at the rightmost column, then move the char
1404 // to the beginning of the next row
1406 NullScreen
[Index
+ Mode
->CursorRow
] = L
' ';
1407 NullAttributes
[Index
] = Mode
->Attribute
| (UINT32
) EFI_WIDE_ATTRIBUTE
;
1409 Mode
->CursorColumn
++;
1411 NullScreen
[Index
+ Mode
->CursorRow
] = *WString
;
1412 NullAttributes
[Index
] = Mode
->Attribute
;
1413 if (CurrentWidth
== 1) {
1414 NullAttributes
[Index
] &= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
1416 NullAttributes
[Index
] |= (UINT32
) EFI_WIDE_ATTRIBUTE
;
1417 NullAttributes
[Index
+ 1] &= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
1420 Index
+= CurrentWidth
;
1422 Mode
->CursorColumn
+= CurrentWidth
;
1426 // At the end of line, output carriage return and line feed
1428 if (Mode
->CursorColumn
>= (INT32
) MaxColumn
) {
1429 DevNullTextOutOutputString (Private
, mCrLfString
);
1439 Sets the output device(s) to a specified mode.
1441 @param Private Private data structure pointer.
1442 @param ModeNumber The mode number to set.
1444 @retval EFI_SUCCESS The requested text mode was set.
1445 @retval EFI_DEVICE_ERROR The device had an error and could not complete
1447 @retval EFI_UNSUPPORTED The mode number was not valid.
1448 @retval EFI_OUT_OF_RESOURCES Out of resources.
1452 DevNullTextOutSetMode (
1453 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1461 TEXT_OUT_SPLITTER_QUERY_DATA
*Mode
;
1464 // No extra check for ModeNumber here, as it has been checked in
1465 // ConSplitterTextOutSetMode. And mode 0 should always be supported.
1466 // Row and Column should be fetched from intersection map.
1468 if (Private
->TextOutModeMap
!= NULL
) {
1469 CurrentMode
= *(Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
);
1471 CurrentMode
= (INT32
)(ModeNumber
);
1473 Mode
= &(Private
->TextOutQueryData
[CurrentMode
]);
1475 Column
= Mode
->Columns
;
1477 if (Row
<= 0 && Column
<= 0) {
1478 return EFI_UNSUPPORTED
;
1481 if (Private
->TextOutMode
.Mode
!= (INT32
) ModeNumber
) {
1483 Private
->TextOutMode
.Mode
= (INT32
) ModeNumber
;
1484 Private
->DevNullColumns
= Column
;
1485 Private
->DevNullRows
= Row
;
1487 if (Private
->DevNullScreen
!= NULL
) {
1488 FreePool (Private
->DevNullScreen
);
1491 Size
= (Row
* (Column
+ 1)) * sizeof (CHAR16
);
1492 Private
->DevNullScreen
= AllocateZeroPool (Size
);
1493 if (Private
->DevNullScreen
== NULL
) {
1494 return EFI_OUT_OF_RESOURCES
;
1497 if (Private
->DevNullAttributes
!= NULL
) {
1498 FreePool (Private
->DevNullAttributes
);
1501 Size
= Row
* Column
* sizeof (INT32
);
1502 Private
->DevNullAttributes
= AllocateZeroPool (Size
);
1503 if (Private
->DevNullAttributes
== NULL
) {
1504 return EFI_OUT_OF_RESOURCES
;
1508 DevNullTextOutClearScreen (Private
);
1515 Clears the output device(s) display to the currently selected background
1518 @param Private Protocol instance pointer.
1520 @retval EFI_SUCCESS The operation completed successfully.
1521 @retval EFI_DEVICE_ERROR The device had an error and could not complete
1523 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
1527 DevNullTextOutClearScreen (
1528 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
1535 INT32 CurrentAttribute
;
1538 // Clear the DevNull Text Out Buffers.
1539 // The screen is filled with spaces.
1540 // The attributes are all synced with the current Simple Text Out Attribute
1542 Screen
= Private
->DevNullScreen
;
1543 Attributes
= Private
->DevNullAttributes
;
1544 CurrentAttribute
= Private
->TextOutMode
.Attribute
;
1546 for (Row
= 0; Row
< Private
->DevNullRows
; Row
++) {
1547 for (Column
= 0; Column
< Private
->DevNullColumns
; Column
++, Screen
++, Attributes
++) {
1549 *Attributes
= CurrentAttribute
;
1552 // Each line of the screen has a NULL on the end so we must skip over it
1557 DevNullTextOutSetCursorPosition (Private
, 0, 0);
1559 return DevNullTextOutEnableCursor (Private
, TRUE
);
1564 Sets the current coordinates of the cursor position.
1566 @param Private Protocol instance pointer.
1568 @param Row the position to set the cursor to. Must be
1569 greater than or equal to zero and less than the
1570 number of columns and rows by QueryMode ().
1572 @retval EFI_SUCCESS The operation completed successfully.
1573 @retval EFI_DEVICE_ERROR The device had an error and could not complete
1575 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or
1576 the cursor position is invalid for the current
1581 DevNullTextOutSetCursorPosition (
1582 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1588 // No need to do extra check here as whether (Column, Row) is valid has
1589 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
1590 // always be supported.
1592 Private
->TextOutMode
.CursorColumn
= (INT32
) Column
;
1593 Private
->TextOutMode
.CursorRow
= (INT32
) Row
;
1600 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1601 In this driver, the cursor cannot be hidden.
1603 @param Private Indicates the calling context.
1604 @param Visible If TRUE, the cursor is set to be visible, If
1605 FALSE, the cursor is set to be invisible.
1607 @retval EFI_SUCCESS The request is valid.
1611 DevNullTextOutEnableCursor (
1612 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1616 Private
->TextOutMode
.CursorVisible
= Visible
;
1623 Take the DevNull TextOut device and update the Simple Text Out on every
1626 @param Private Indicates the calling context.
1628 @retval EFI_SUCCESS The request is valid.
1629 @retval other Return status of TextOut->OutputString ()
1634 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
1638 EFI_STATUS ReturnStatus
;
1643 UINTN CurrentColumn
;
1646 INT32 StartAttribute
;
1647 BOOLEAN StartCursorState
;
1652 CHAR16
*ScreenStart
;
1653 INT32 CurrentAttribute
;
1655 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Sto
;
1658 // Save the devices Attributes, Cursor enable state and location
1660 StartColumn
= Private
->TextOutMode
.CursorColumn
;
1661 StartRow
= Private
->TextOutMode
.CursorRow
;
1662 StartAttribute
= Private
->TextOutMode
.Attribute
;
1663 StartCursorState
= Private
->TextOutMode
.CursorVisible
;
1665 for (List
= 0; List
< Private
->CurrentNumberOfConsoles
; List
++) {
1667 Sto
= Private
->TextOutList
[List
].TextOut
;
1670 // Skip non GOP/UGA devices
1672 if ((Private
->TextOutList
[List
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[List
].UgaDraw
!= NULL
)) {
1673 Sto
->EnableCursor (Sto
, FALSE
);
1674 Sto
->ClearScreen (Sto
);
1678 ReturnStatus
= EFI_SUCCESS
;
1679 Screen
= Private
->DevNullScreen
;
1680 Attributes
= Private
->DevNullAttributes
;
1681 MaxColumn
= Private
->DevNullColumns
;
1683 Buffer
= AllocateZeroPool ((MaxColumn
+ 1) * sizeof (CHAR16
));
1684 if (Buffer
== NULL
) {
1685 return ReturnStatus
;
1688 for (Row
= 0; Row
< Private
->DevNullRows
; Row
++, Screen
+= (MaxColumn
+ 1), Attributes
+= MaxColumn
) {
1690 if (Row
== (Private
->DevNullRows
- 1)) {
1692 // Don't ever sync the last character as it will scroll the screen
1694 Screen
[MaxColumn
- 1] = 0x00;
1698 while (Column
< MaxColumn
) {
1699 if (Screen
[Column
] > 0) {
1700 CurrentAttribute
= Attributes
[Column
];
1701 CurrentColumn
= Column
;
1702 ScreenStart
= &Screen
[Column
];
1705 // the line end is alway 0x0. So Column should be less than MaxColumn
1706 // It should be still in the same row
1708 for (Str
= ScreenStart
, BufferTail
= Buffer
; *Str
!= 0; Str
++, Column
++) {
1710 if (Attributes
[Column
] != CurrentAttribute
) {
1717 if ((Attributes
[Column
] & EFI_WIDE_ATTRIBUTE
) != 0) {
1725 for (List
= 0; List
< Private
->CurrentNumberOfConsoles
; List
++) {
1727 Sto
= Private
->TextOutList
[List
].TextOut
;
1730 // Skip non GOP/UGA devices
1732 if ((Private
->TextOutList
[List
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[List
].UgaDraw
!= NULL
)) {
1733 Sto
->SetAttribute (Sto
, CurrentAttribute
);
1734 Sto
->SetCursorPosition (Sto
, CurrentColumn
, Row
);
1735 Status
= Sto
->OutputString (Sto
, Buffer
);
1736 if (EFI_ERROR (Status
)) {
1737 ReturnStatus
= Status
;
1748 // Restore the devices Attributes, Cursor enable state and location
1750 for (List
= 0; List
< Private
->CurrentNumberOfConsoles
; List
++) {
1751 Sto
= Private
->TextOutList
[List
].TextOut
;
1754 // Skip non GOP/UGA devices
1756 if ((Private
->TextOutList
[List
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[List
].UgaDraw
!= NULL
)) {
1757 Sto
->SetAttribute (Sto
, StartAttribute
);
1758 Sto
->SetCursorPosition (Sto
, StartColumn
, StartRow
);
1759 Status
= Sto
->EnableCursor (Sto
, StartCursorState
);
1760 if (EFI_ERROR (Status
)) {
1761 ReturnStatus
= Status
;
1768 return ReturnStatus
;