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.
19 #include "ConSplitter.h"
22 CHAR16 mCrLfString
[3] = { CHAR_CARRIAGE_RETURN
, CHAR_LINEFEED
, CHAR_NULL
};
26 Return the current video mode information. Also returns info about existence
27 of Graphics Output devices or UGA Draw devices in system, and whether the Std
28 In device is locked. GopUgaExists and StdInLocked parameters are optional, and
29 only returned if a non NULL pointer is passed in.
31 @param This Protocol instance pointer.
32 @param Mode Current video mode.
33 @param GopUgaExists TRUE if GOP Spliter has found a GOP/UGA device
34 @param StdInLocked TRUE if StdIn device is keyboard locked
36 @retval EFI_SUCCESS Video mode information is returned.
37 @retval EFI_INVALID_PARAMETER Invalid parameters if Mode == NULL.
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 video mode to either text or graphics. Graphics is
82 @param This Console Control Protocol instance pointer.
83 @param Mode Video mode is to be set.
85 @retval EFI_SUCCESS Mode is set successfully.
86 @retval EFI_INVALID_PARAMETER Mode is not the valid mode value.
87 @retval EFI_UNSUPPORTED Mode is unsupported by console device.
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 Returns information for an available graphics mode that the graphics device
155 and the set of active video output devices supports.
157 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
158 @param ModeNumber The mode number to return information on.
159 @param SizeOfInfo A pointer to the size, in bytes, of the Info buffer.
160 @param Info A pointer to callee allocated buffer that returns information about ModeNumber.
162 @retval EFI_SUCCESS Mode information returned.
163 @retval EFI_BUFFER_TOO_SMALL The Info buffer was too small.
164 @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode.
165 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
166 @retval EFI_INVALID_PARAMETER One of the input args was NULL.
167 @retval EFI_OUT_OF_RESOURCES No resource available.
172 ConSpliterGraphicsOutputQueryMode (
173 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
174 IN UINT32 ModeNumber
,
175 OUT UINTN
*SizeOfInfo
,
176 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
**Info
179 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
181 if (This
== NULL
|| Info
== NULL
|| SizeOfInfo
== NULL
|| ModeNumber
>= This
->Mode
->MaxMode
) {
182 return EFI_INVALID_PARAMETER
;
186 // retrieve private data
188 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
190 if (Private
->HardwareNeedsStarting
) {
191 return EFI_NOT_STARTED
;
194 *Info
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
196 return EFI_OUT_OF_RESOURCES
;
199 *SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
201 CopyMem (*Info
, &Private
->GraphicsOutputModeBuffer
[ModeNumber
], *SizeOfInfo
);
208 Set the video device into the specified mode and clears the visible portions of
209 the output display to black.
211 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
212 @param ModeNumber Abstraction that defines the current video mode.
214 @retval EFI_SUCCESS The graphics mode specified by ModeNumber was selected.
215 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
216 @retval EFI_UNSUPPORTED ModeNumber is not supported by this device.
217 @retval EFI_OUT_OF_RESOURCES No resource available.
222 ConSpliterGraphicsOutputSetMode (
223 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
* This
,
228 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
230 EFI_STATUS ReturnStatus
;
231 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
;
233 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
236 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
237 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
239 if (ModeNumber
>= This
->Mode
->MaxMode
) {
240 return EFI_UNSUPPORTED
;
243 if (ModeNumber
== This
->Mode
->Mode
) {
247 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
249 ReturnStatus
= EFI_SUCCESS
;
252 // Free the old version
254 if (Private
->GraphicsOutputBlt
!= NULL
) {
255 FreePool (Private
->GraphicsOutputBlt
);
259 // Allocate the virtual Blt buffer
261 Mode
= &Private
->GraphicsOutputModeBuffer
[ModeNumber
];
262 Size
= Mode
->HorizontalResolution
* Mode
->VerticalResolution
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
263 Private
->GraphicsOutputBlt
= AllocateZeroPool (Size
);
265 if (Private
->GraphicsOutputBlt
== NULL
) {
266 return EFI_OUT_OF_RESOURCES
;
270 // return the worst status met
272 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
273 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
274 if (GraphicsOutput
!= NULL
) {
276 // Find corresponding ModeNumber of this GraphicsOutput instance
278 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
279 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
280 if (EFI_ERROR (Status
)) {
283 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) && (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
290 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
291 if (EFI_ERROR (Status
)) {
292 ReturnStatus
= Status
;
294 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
295 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
296 if (UgaDraw
!= NULL
) {
297 Status
= UgaDraw
->SetMode (
299 Mode
->HorizontalResolution
,
300 Mode
->VerticalResolution
,
304 if (EFI_ERROR (Status
)) {
305 ReturnStatus
= Status
;
311 This
->Mode
->Mode
= ModeNumber
;
313 CopyMem (This
->Mode
->Info
, &Private
->GraphicsOutputModeBuffer
[ModeNumber
], This
->Mode
->SizeOfInfo
);
316 // Information is not enough here, so the following items remain unchanged:
317 // GraphicsOutputMode->Info->Version, GraphicsOutputMode->Info->PixelFormat
318 // GraphicsOutputMode->SizeOfInfo, GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
319 // These items will be initialized/updated when a new GOP device is added into ConsoleSplitter.
322 Private
->HardwareNeedsStarting
= FALSE
;
328 The following table defines actions for BltOperations.
330 EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
331 directly to every pixel of the video display rectangle
332 (DestinationX, DestinationY)
333 (DestinationX + Width, DestinationY + Height).
334 Only one pixel will be used from the BltBuffer. Delta is NOT used.
335 EfiBltVideoToBltBuffer - Read data from the video display rectangle
336 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
337 the BltBuffer rectangle (DestinationX, DestinationY )
338 (DestinationX + Width, DestinationY + Height). If DestinationX or
339 DestinationY is not zero then Delta must be set to the length in bytes
340 of a row in the BltBuffer.
341 EfiBltBufferToVideo - Write data from the BltBuffer rectangle
342 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
343 video display rectangle (DestinationX, DestinationY)
344 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
345 not zero then Delta must be set to the length in bytes of a row in the
347 EfiBltVideoToVideo - Copy from the video display rectangle
348 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
349 to the video display rectangle (DestinationX, DestinationY)
350 (DestinationX + Width, DestinationY + Height).
351 The BltBuffer and Delta are not used in this mode.
353 @param Private Protocol instance pointer.
354 @param BltBuffer Buffer containing data to blit into video buffer.
355 This buffer has a size of
356 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
357 @param BltOperation Operation to perform on BlitBuffer and video
359 @param SourceX X coordinate of source for the BltBuffer.
360 @param SourceY Y coordinate of source for the BltBuffer.
361 @param DestinationX X coordinate of destination for the BltBuffer.
362 @param DestinationY Y coordinate of destination for the BltBuffer.
363 @param Width Width of rectangle in BltBuffer in pixels.
364 @param Height Hight of rectangle in BltBuffer in pixels.
365 @param Delta OPTIONAL.
367 @retval EFI_SUCCESS The Blt operation completed.
368 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
369 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
374 DevNullGraphicsOutputBlt (
375 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
376 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
377 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
380 IN UINTN DestinationX
,
381 IN UINTN DestinationY
,
384 IN UINTN Delta OPTIONAL
390 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltPtr
;
391 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*ScreenPtr
;
392 UINTN HorizontalResolution
;
393 UINTN VerticalResolution
;
395 if ((BltOperation
< EfiBltVideoFill
) || (BltOperation
>= EfiGraphicsOutputBltOperationMax
)) {
396 return EFI_INVALID_PARAMETER
;
399 if (Width
== 0 || Height
== 0) {
400 return EFI_INVALID_PARAMETER
;
404 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
407 HorizontalResolution
= Private
->GraphicsOutput
.Mode
->Info
->HorizontalResolution
;
408 VerticalResolution
= Private
->GraphicsOutput
.Mode
->Info
->VerticalResolution
;
411 // We need to fill the Virtual Screen buffer with the blt data.
413 if (BltOperation
== EfiBltVideoToBltBuffer
) {
415 // Video to BltBuffer: Source is Video, destination is BltBuffer
417 if ((SourceY
+ Height
) > VerticalResolution
) {
418 return EFI_INVALID_PARAMETER
;
421 if ((SourceX
+ Width
) > HorizontalResolution
) {
422 return EFI_INVALID_PARAMETER
;
425 BltPtr
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltBuffer
+ DestinationY
* Delta
+ DestinationX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
426 ScreenPtr
= &Private
->GraphicsOutputBlt
[SourceY
* HorizontalResolution
+ SourceX
];
428 CopyMem (BltPtr
, ScreenPtr
, Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
429 BltPtr
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltPtr
+ Delta
);
430 ScreenPtr
+= HorizontalResolution
;
435 // BltBuffer to Video: Source is BltBuffer, destination is Video
437 if (DestinationY
+ Height
> VerticalResolution
) {
438 return EFI_INVALID_PARAMETER
;
441 if (DestinationX
+ Width
> HorizontalResolution
) {
442 return EFI_INVALID_PARAMETER
;
445 if ((BltOperation
== EfiBltVideoToVideo
) && (DestinationY
> SourceY
)) {
447 // Copy backwards, only care the Video to Video Blt
449 ScreenPtr
= &Private
->GraphicsOutputBlt
[(DestinationY
+ Height
- 1) * HorizontalResolution
+ DestinationX
];
450 SrcY
= SourceY
+ Height
- 1;
454 // Copy forwards, for other cases
456 ScreenPtr
= &Private
->GraphicsOutputBlt
[DestinationY
* HorizontalResolution
+ DestinationX
];
461 while (Height
!= 0) {
462 if (BltOperation
== EfiBltVideoFill
) {
463 for (Index
= 0; Index
< Width
; Index
++) {
464 ScreenPtr
[Index
] = *BltBuffer
;
467 if (BltOperation
== EfiBltBufferToVideo
) {
468 BltPtr
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltBuffer
+ SrcY
* Delta
+ SourceX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
470 BltPtr
= &Private
->GraphicsOutputBlt
[SrcY
* HorizontalResolution
+ SourceX
];
473 CopyMem (ScreenPtr
, BltPtr
, Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
477 ScreenPtr
+= HorizontalResolution
;
480 ScreenPtr
-= HorizontalResolution
;
492 The following table defines actions for BltOperations.
494 EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
495 directly to every pixel of the video display rectangle
496 (DestinationX, DestinationY)
497 (DestinationX + Width, DestinationY + Height).
498 Only one pixel will be used from the BltBuffer. Delta is NOT used.
499 EfiBltVideoToBltBuffer - Read data from the video display rectangle
500 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
501 the BltBuffer rectangle (DestinationX, DestinationY )
502 (DestinationX + Width, DestinationY + Height). If DestinationX or
503 DestinationY is not zero then Delta must be set to the length in bytes
504 of a row in the BltBuffer.
505 EfiBltBufferToVideo - Write data from the BltBuffer rectangle
506 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
507 video display rectangle (DestinationX, DestinationY)
508 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
509 not zero then Delta must be set to the length in bytes of a row in the
511 EfiBltVideoToVideo - Copy from the video display rectangle
512 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
513 to the video display rectangle (DestinationX, DestinationY)
514 (DestinationX + Width, DestinationY + Height).
515 The BltBuffer and Delta are not used in this mode.
517 @param This Protocol instance pointer.
518 @param BltBuffer Buffer containing data to blit into video buffer.
519 This buffer has a size of
520 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
521 @param BltOperation Operation to perform on BlitBuffer and video
523 @param SourceX X coordinate of source for the BltBuffer.
524 @param SourceY Y coordinate of source for the BltBuffer.
525 @param DestinationX X coordinate of destination for the BltBuffer.
526 @param DestinationY Y coordinate of destination for the BltBuffer.
527 @param Width Width of rectangle in BltBuffer in pixels.
528 @param Height Hight of rectangle in BltBuffer in pixels.
529 @param Delta OPTIONAL.
531 @retval EFI_SUCCESS The Blt operation completed.
532 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
533 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
539 ConSpliterGraphicsOutputBlt (
540 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
541 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
542 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
545 IN UINTN DestinationX
,
546 IN UINTN DestinationY
,
549 IN UINTN Delta OPTIONAL
553 EFI_STATUS ReturnStatus
= EFI_DEVICE_ERROR
;
554 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
556 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
557 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
559 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
562 // return the worst status met
564 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
565 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
566 if (GraphicsOutput
!= NULL
) {
567 Status
= GraphicsOutput
->Blt (
579 if (EFI_ERROR (Status
)) {
580 ReturnStatus
= Status
;
581 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
583 // Only need to read the data into buffer one time
589 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
590 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
591 Status
= UgaDraw
->Blt (
593 (EFI_UGA_PIXEL
*) BltBuffer
,
594 (EFI_UGA_BLT_OPERATION
) BltOperation
,
603 if (EFI_ERROR (Status
)) {
604 ReturnStatus
= Status
;
605 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
607 // Only need to read the data into buffer one time
618 Write data from the buffer to video display based on Graphics Output setting.
620 @param Private Consplitter Text Out pointer.
621 @param GraphicsOutput Graphics Output protocol pointer.
622 @param UgaDraw UGA Draw protocol pointer.
624 @retval EFI_UNSUPPORTED No graphics devcie available .
625 @retval EFI_SUCCESS The Blt operation completed.
626 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
627 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video buffer.
633 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
634 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
635 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
638 if (GraphicsOutput
!= NULL
) {
639 return GraphicsOutput
->Blt (
641 Private
->GraphicsOutputBlt
,
647 Private
->GraphicsOutput
.Mode
->Info
->HorizontalResolution
,
648 Private
->GraphicsOutput
.Mode
->Info
->VerticalResolution
,
651 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
652 return UgaDraw
->Blt (
654 (EFI_UGA_PIXEL
*) Private
->GraphicsOutputBlt
,
655 EfiUgaBltBufferToVideo
,
660 Private
->GraphicsOutput
.Mode
->Info
->HorizontalResolution
,
661 Private
->GraphicsOutput
.Mode
->Info
->VerticalResolution
,
665 return EFI_UNSUPPORTED
;
670 Return the current video mode information.
672 @param This The EFI_UGA_DRAW_PROTOCOL instance.
673 @param HorizontalResolution The size of video screen in pixels in the X dimension.
674 @param VerticalResolution The size of video screen in pixels in the Y dimension.
675 @param ColorDepth Number of bits per pixel, currently defined to be 32.
676 @param RefreshRate The refresh rate of the monitor in Hertz.
678 @retval EFI_SUCCESS Mode information returned.
679 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
680 @retval EFI_INVALID_PARAMETER One of the input args was NULL.
685 ConSpliterUgaDrawGetMode (
686 IN EFI_UGA_DRAW_PROTOCOL
*This
,
687 OUT UINT32
*HorizontalResolution
,
688 OUT UINT32
*VerticalResolution
,
689 OUT UINT32
*ColorDepth
,
690 OUT UINT32
*RefreshRate
693 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
695 if ((HorizontalResolution
== NULL
) ||
696 (VerticalResolution
== NULL
) ||
697 (RefreshRate
== NULL
) ||
698 (ColorDepth
== NULL
)) {
699 return EFI_INVALID_PARAMETER
;
702 // retrieve private data
704 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
706 *HorizontalResolution
= Private
->UgaHorizontalResolution
;
707 *VerticalResolution
= Private
->UgaVerticalResolution
;
708 *ColorDepth
= Private
->UgaColorDepth
;
709 *RefreshRate
= Private
->UgaRefreshRate
;
716 Set the current video mode information.
718 @param This The EFI_UGA_DRAW_PROTOCOL instance.
719 @param HorizontalResolution The size of video screen in pixels in the X dimension.
720 @param VerticalResolution The size of video screen in pixels in the Y dimension.
721 @param ColorDepth Number of bits per pixel, currently defined to be 32.
722 @param RefreshRate The refresh rate of the monitor in Hertz.
724 @retval EFI_SUCCESS Mode information returned.
725 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
726 @retval EFI_OUT_OF_RESOURCES Out of resources.
731 ConSpliterUgaDrawSetMode (
732 IN EFI_UGA_DRAW_PROTOCOL
*This
,
733 IN UINT32 HorizontalResolution
,
734 IN UINT32 VerticalResolution
,
735 IN UINT32 ColorDepth
,
736 IN UINT32 RefreshRate
740 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
742 EFI_STATUS ReturnStatus
;
744 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
747 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
748 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
750 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
753 // UgaDevNullSetMode ()
755 ReturnStatus
= EFI_SUCCESS
;
758 // Free the old version
760 if (Private
->UgaBlt
!= NULL
) {
761 FreePool (Private
->UgaBlt
);
765 // Allocate the virtual Blt buffer
767 Size
= HorizontalResolution
* VerticalResolution
* sizeof (EFI_UGA_PIXEL
);
768 Private
->UgaBlt
= AllocateZeroPool (Size
);
769 if (Private
->UgaBlt
== NULL
) {
770 return EFI_OUT_OF_RESOURCES
;
774 // Update the Mode data
776 Private
->UgaHorizontalResolution
= HorizontalResolution
;
777 Private
->UgaVerticalResolution
= VerticalResolution
;
778 Private
->UgaColorDepth
= ColorDepth
;
779 Private
->UgaRefreshRate
= RefreshRate
;
781 if (Private
->ConsoleOutputMode
!= EfiConsoleControlScreenGraphics
) {
785 // return the worst status met
787 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
789 ReturnStatus
= EFI_UNSUPPORTED
;
791 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
792 if (GraphicsOutput
!= NULL
) {
794 // Find corresponding ModeNumber of this GraphicsOutput instance
796 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
797 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
798 if (EFI_ERROR (Status
)) {
801 if ((Info
->HorizontalResolution
== HorizontalResolution
) && (Info
->VerticalResolution
== VerticalResolution
)) {
808 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
809 if (EFI_ERROR (Status
)) {
810 ReturnStatus
= Status
;
812 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)){
813 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
814 if (UgaDraw
!= NULL
) {
815 Status
= UgaDraw
->SetMode (
817 HorizontalResolution
,
822 if (EFI_ERROR (Status
)) {
823 ReturnStatus
= Status
;
833 Blt a rectangle of pixels on the graphics screen.
835 The following table defines actions for BltOperations.
838 Write data from the BltBuffer pixel (SourceX, SourceY)
839 directly to every pixel of the video display rectangle
840 (DestinationX, DestinationY)
841 (DestinationX + Width, DestinationY + Height).
842 Only one pixel will be used from the BltBuffer. Delta is NOT used.
843 EfiUgaVideoToBltBuffer:
844 Read data from the video display rectangle
845 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
846 the BltBuffer rectangle (DestinationX, DestinationY )
847 (DestinationX + Width, DestinationY + Height). If DestinationX or
848 DestinationY is not zero then Delta must be set to the length in bytes
849 of a row in the BltBuffer.
850 EfiUgaBltBufferToVideo:
851 Write data from the BltBuffer rectangle
852 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
853 video display rectangle (DestinationX, DestinationY)
854 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
855 not zero then Delta must be set to the length in bytes of a row in the
858 Copy from the video display rectangle
859 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
860 to the video display rectangle (DestinationX, DestinationY)
861 (DestinationX + Width, DestinationY + Height).
862 The BltBuffer and Delta are not used in this mode.
864 @param Private Text Out Splitter pointer.
865 @param BltBuffer Buffer containing data to blit into video buffer.
866 This buffer has a size of
867 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
868 @param BltOperation Operation to perform on BlitBuffer and video
870 @param SourceX X coordinate of source for the BltBuffer.
871 @param SourceY Y coordinate of source for the BltBuffer.
872 @param DestinationX X coordinate of destination for the BltBuffer.
873 @param DestinationY Y coordinate of destination for the BltBuffer.
874 @param Width Width of rectangle in BltBuffer in pixels.
875 @param Height Hight of rectangle in BltBuffer in pixels.
876 @param Delta OPTIONAL.
878 @retval EFI_SUCCESS The Blt operation completed.
879 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
880 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video
886 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
887 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
888 IN EFI_UGA_BLT_OPERATION BltOperation
,
891 IN UINTN DestinationX
,
892 IN UINTN DestinationY
,
895 IN UINTN Delta OPTIONAL
901 EFI_UGA_PIXEL
*BltPtr
;
902 EFI_UGA_PIXEL
*ScreenPtr
;
903 UINT32 HorizontalResolution
;
904 UINT32 VerticalResolution
;
906 if ((BltOperation
< 0) || (BltOperation
>= EfiUgaBltMax
)) {
907 return EFI_INVALID_PARAMETER
;
910 if (Width
== 0 || Height
== 0) {
911 return EFI_INVALID_PARAMETER
;
915 Delta
= Width
* sizeof (EFI_UGA_PIXEL
);
918 HorizontalResolution
= Private
->UgaHorizontalResolution
;
919 VerticalResolution
= Private
->UgaVerticalResolution
;
922 // We need to fill the Virtual Screen buffer with the blt data.
924 if (BltOperation
== EfiUgaVideoToBltBuffer
) {
926 // Video to BltBuffer: Source is Video, destination is BltBuffer
928 if ((SourceY
+ Height
) > VerticalResolution
) {
929 return EFI_INVALID_PARAMETER
;
932 if ((SourceX
+ Width
) > HorizontalResolution
) {
933 return EFI_INVALID_PARAMETER
;
936 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ DestinationY
* Delta
+ DestinationX
* sizeof (EFI_UGA_PIXEL
));
937 ScreenPtr
= &Private
->UgaBlt
[SourceY
* HorizontalResolution
+ SourceX
];
939 CopyMem (BltPtr
, ScreenPtr
, Width
* sizeof (EFI_UGA_PIXEL
));
940 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltPtr
+ Delta
);
941 ScreenPtr
+= HorizontalResolution
;
946 // BltBuffer to Video: Source is BltBuffer, destination is Video
948 if (DestinationY
+ Height
> VerticalResolution
) {
949 return EFI_INVALID_PARAMETER
;
952 if (DestinationX
+ Width
> HorizontalResolution
) {
953 return EFI_INVALID_PARAMETER
;
956 if ((BltOperation
== EfiUgaVideoToVideo
) && (DestinationY
> SourceY
)) {
958 // Copy backwards, only care the Video to Video Blt
960 ScreenPtr
= &Private
->UgaBlt
[(DestinationY
+ Height
- 1) * HorizontalResolution
+ DestinationX
];
961 SrcY
= SourceY
+ Height
- 1;
965 // Copy forwards, for other cases
967 ScreenPtr
= &Private
->UgaBlt
[DestinationY
* HorizontalResolution
+ DestinationX
];
972 while (Height
!= 0) {
973 if (BltOperation
== EfiUgaVideoFill
) {
974 for (Index
= 0; Index
< Width
; Index
++) {
975 ScreenPtr
[Index
] = *BltBuffer
;
978 if (BltOperation
== EfiUgaBltBufferToVideo
) {
979 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ SrcY
* Delta
+ SourceX
* sizeof (EFI_UGA_PIXEL
));
981 BltPtr
= &Private
->UgaBlt
[SrcY
* HorizontalResolution
+ SourceX
];
984 CopyMem (ScreenPtr
, BltPtr
, Width
* sizeof (EFI_UGA_PIXEL
));
988 ScreenPtr
+= HorizontalResolution
;
991 ScreenPtr
-= HorizontalResolution
;
1002 Blt a rectangle of pixels on the graphics screen.
1004 The following table defines actions for BltOperations.
1007 Write data from the BltBuffer pixel (SourceX, SourceY)
1008 directly to every pixel of the video display rectangle
1009 (DestinationX, DestinationY)
1010 (DestinationX + Width, DestinationY + Height).
1011 Only one pixel will be used from the BltBuffer. Delta is NOT used.
1012 EfiUgaVideoToBltBuffer:
1013 Read data from the video display rectangle
1014 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
1015 the BltBuffer rectangle (DestinationX, DestinationY )
1016 (DestinationX + Width, DestinationY + Height). If DestinationX or
1017 DestinationY is not zero then Delta must be set to the length in bytes
1018 of a row in the BltBuffer.
1019 EfiUgaBltBufferToVideo:
1020 Write data from the BltBuffer rectangle
1021 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
1022 video display rectangle (DestinationX, DestinationY)
1023 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
1024 not zero then Delta must be set to the length in bytes of a row in the
1027 Copy from the video display rectangle
1028 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
1029 to the video display rectangle (DestinationX, DestinationY)
1030 (DestinationX + Width, DestinationY + Height).
1031 The BltBuffer and Delta are not used in this mode.
1033 @param This Protocol instance pointer.
1034 @param BltBuffer Buffer containing data to blit into video buffer. This
1035 buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
1036 @param BltOperation Operation to perform on BlitBuffer and video memory
1037 @param SourceX X coordinate of source for the BltBuffer.
1038 @param SourceY Y coordinate of source for the BltBuffer.
1039 @param DestinationX X coordinate of destination for the BltBuffer.
1040 @param DestinationY Y coordinate of destination for the BltBuffer.
1041 @param Width Width of rectangle in BltBuffer in pixels.
1042 @param Height Hight of rectangle in BltBuffer in pixels.
1043 @param Delta OPTIONAL
1045 @retval EFI_SUCCESS The Blt operation completed.
1046 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
1047 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video buffer.
1052 ConSpliterUgaDrawBlt (
1053 IN EFI_UGA_DRAW_PROTOCOL
*This
,
1054 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
1055 IN EFI_UGA_BLT_OPERATION BltOperation
,
1058 IN UINTN DestinationX
,
1059 IN UINTN DestinationY
,
1062 IN UINTN Delta OPTIONAL
1066 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
1068 EFI_STATUS ReturnStatus
;
1069 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1071 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
1074 // Sync up DevNull UGA device
1076 ReturnStatus
= DevNullUgaBlt (
1088 if (Private
->ConsoleOutputMode
!= EfiConsoleControlScreenGraphics
) {
1089 return ReturnStatus
;
1092 // return the worst status met
1094 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
1095 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
1096 if (GraphicsOutput
!= NULL
) {
1097 Status
= GraphicsOutput
->Blt (
1099 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltBuffer
,
1100 (EFI_GRAPHICS_OUTPUT_BLT_OPERATION
) BltOperation
,
1109 if (EFI_ERROR (Status
)) {
1110 ReturnStatus
= Status
;
1111 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
1113 // Only need to read the data into buffer one time
1119 if (Private
->TextOutList
[Index
].UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1120 Status
= Private
->TextOutList
[Index
].UgaDraw
->Blt (
1121 Private
->TextOutList
[Index
].UgaDraw
,
1132 if (EFI_ERROR (Status
)) {
1133 ReturnStatus
= Status
;
1134 } else if (BltOperation
== EfiUgaVideoToBltBuffer
) {
1136 // Only need to read the data into buffer one time
1143 return ReturnStatus
;
1147 Write data from the buffer to video display based on UGA Draw setting.
1149 @param Private Consplitter Text Out pointer.
1150 @param GraphicsOutput Graphics Output protocol pointer.
1151 @param UgaDraw UGA Draw protocol pointer.
1153 @retval EFI_UNSUPPORTED No graphics devcie available .
1154 @retval EFI_SUCCESS The Blt operation completed.
1155 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
1156 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video buffer.
1161 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1162 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
1163 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
1166 if (GraphicsOutput
!= NULL
) {
1167 return GraphicsOutput
->Blt (
1169 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) Private
->UgaBlt
,
1170 EfiBltBufferToVideo
,
1175 Private
->UgaHorizontalResolution
,
1176 Private
->UgaVerticalResolution
,
1179 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1180 return UgaDraw
->Blt (
1183 EfiUgaBltBufferToVideo
,
1188 Private
->UgaHorizontalResolution
,
1189 Private
->UgaVerticalResolution
,
1190 Private
->UgaHorizontalResolution
* sizeof (EFI_UGA_PIXEL
)
1193 return EFI_UNSUPPORTED
;
1199 Write a Unicode string to the output device.
1201 @param Private Pointer to the console output splitter's private
1202 data. It indicates the calling context.
1203 @param WString The NULL-terminated Unicode string to be
1204 displayed on the output device(s). All output
1205 devices must also support the Unicode drawing
1206 defined in this file.
1208 @retval EFI_SUCCESS The string was output to the device.
1209 @retval EFI_DEVICE_ERROR The device reported an error while attempting to
1211 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
1213 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
1214 characters in the Unicode string could not be
1215 rendered and were skipped.
1219 DevNullTextOutOutputString (
1220 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1225 UINTN SizeAttribute
;
1227 EFI_SIMPLE_TEXT_OUTPUT_MODE
*Mode
;
1234 INT32
*NullAttributes
;
1239 Mode
= &Private
->TextOutMode
;
1240 NullScreen
= Private
->DevNullScreen
;
1241 NullAttributes
= Private
->DevNullAttributes
;
1242 LastRow
= Private
->DevNullRows
- 1;
1243 MaxColumn
= Private
->DevNullColumns
;
1245 if ((Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) != 0) {
1251 while (*WString
!= L
'\0') {
1253 if (*WString
== CHAR_BACKSPACE
) {
1255 // If the cursor is at the left edge of the display, then move the cursor
1258 if (Mode
->CursorColumn
== 0 && Mode
->CursorRow
> 0) {
1260 Mode
->CursorColumn
= (INT32
) MaxColumn
;
1264 // If the cursor is not at the left edge of the display,
1265 // then move the cursor left one column.
1267 if (Mode
->CursorColumn
> 0) {
1268 Mode
->CursorColumn
--;
1269 if (Mode
->CursorColumn
> 0 &&
1270 NullAttributes
[Mode
->CursorRow
* MaxColumn
+ Mode
->CursorColumn
- 1] & EFI_WIDE_ATTRIBUTE
1272 Mode
->CursorColumn
--;
1275 // Insert an extra backspace
1277 InsertChar
= CHAR_BACKSPACE
;
1279 while (*PStr
!= L
'\0') {
1282 InsertChar
= TempChar
;
1295 } else if (*WString
== CHAR_LINEFEED
) {
1297 // If the cursor is at the bottom of the display,
1298 // then scroll the display one row, and do not update
1299 // the cursor position. Otherwise, move the cursor down one row.
1301 if (Mode
->CursorRow
== (INT32
) (LastRow
)) {
1303 // Scroll Screen Up One Row
1305 SizeAttribute
= LastRow
* MaxColumn
;
1308 NullAttributes
+ MaxColumn
,
1309 SizeAttribute
* sizeof (INT32
)
1313 // Each row has an ending CHAR_NULL. So one more character each line
1314 // for DevNullScreen than DevNullAttributes
1316 SizeScreen
= SizeAttribute
+ LastRow
;
1319 NullScreen
+ (MaxColumn
+ 1),
1320 SizeScreen
* sizeof (CHAR16
)
1324 // Print Blank Line at last line
1326 Screen
= NullScreen
+ SizeScreen
;
1327 Attribute
= NullAttributes
+ SizeAttribute
;
1329 for (Index
= 0; Index
< MaxColumn
; Index
++, Screen
++, Attribute
++) {
1331 *Attribute
= Mode
->Attribute
;
1338 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
1340 // Move the cursor to the beginning of the current row.
1342 Mode
->CursorColumn
= 0;
1346 // Print the character at the current cursor position and
1347 // move the cursor right one column. If this moves the cursor
1348 // past the right edge of the display, then the line should wrap to
1349 // the beginning of the next line. This is equivalent to inserting
1350 // a CR and an LF. Note that if the cursor is at the bottom of the
1351 // display, and the line wraps, then the display will be scrolled
1354 Index
= Mode
->CursorRow
* MaxColumn
+ Mode
->CursorColumn
;
1356 while (Mode
->CursorColumn
< (INT32
) MaxColumn
) {
1357 if (*WString
== CHAR_NULL
) {
1361 if (*WString
== CHAR_BACKSPACE
) {
1365 if (*WString
== CHAR_LINEFEED
) {
1369 if (*WString
== CHAR_CARRIAGE_RETURN
) {
1373 if (*WString
== UNICODE_WIDE_CHAR
|| *WString
== UNICODE_NARROW_CHAR
) {
1374 CurrentWidth
= (*WString
== UNICODE_WIDE_CHAR
) ? 2 : 1;
1379 if (Mode
->CursorColumn
+ CurrentWidth
> (INT32
) MaxColumn
) {
1381 // If a wide char is at the rightmost column, then move the char
1382 // to the beginning of the next row
1384 NullScreen
[Index
+ Mode
->CursorRow
] = L
' ';
1385 NullAttributes
[Index
] = Mode
->Attribute
| (UINT32
) EFI_WIDE_ATTRIBUTE
;
1387 Mode
->CursorColumn
++;
1389 NullScreen
[Index
+ Mode
->CursorRow
] = *WString
;
1390 NullAttributes
[Index
] = Mode
->Attribute
;
1391 if (CurrentWidth
== 1) {
1392 NullAttributes
[Index
] &= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
1394 NullAttributes
[Index
] |= (UINT32
) EFI_WIDE_ATTRIBUTE
;
1395 NullAttributes
[Index
+ 1] &= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
1398 Index
+= CurrentWidth
;
1400 Mode
->CursorColumn
+= CurrentWidth
;
1404 // At the end of line, output carriage return and line feed
1406 if (Mode
->CursorColumn
>= (INT32
) MaxColumn
) {
1407 DevNullTextOutOutputString (Private
, mCrLfString
);
1417 Sets the output device(s) to a specified mode.
1419 @param Private Text Out Splitter pointer.
1420 @param ModeNumber The mode number to set.
1422 @retval EFI_SUCCESS The requested text mode was set.
1423 @retval EFI_DEVICE_ERROR The device had an error and could not complete
1425 @retval EFI_UNSUPPORTED The mode number was not valid.
1426 @retval EFI_OUT_OF_RESOURCES Out of resources.
1430 DevNullTextOutSetMode (
1431 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1439 TEXT_OUT_SPLITTER_QUERY_DATA
*Mode
;
1442 // No extra check for ModeNumber here, as it has been checked in
1443 // ConSplitterTextOutSetMode. And mode 0 should always be supported.
1444 // Row and Column should be fetched from intersection map.
1446 if (Private
->TextOutModeMap
!= NULL
) {
1447 CurrentMode
= *(Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
);
1449 CurrentMode
= (INT32
) (ModeNumber
);
1451 Mode
= &(Private
->TextOutQueryData
[CurrentMode
]);
1453 Column
= Mode
->Columns
;
1455 if (Row
== 0 || Column
== 0) {
1456 return EFI_UNSUPPORTED
;
1459 if (Private
->TextOutMode
.Mode
!= (INT32
) ModeNumber
) {
1461 Private
->TextOutMode
.Mode
= (INT32
) ModeNumber
;
1462 Private
->DevNullColumns
= Column
;
1463 Private
->DevNullRows
= Row
;
1465 if (Private
->DevNullScreen
!= NULL
) {
1466 FreePool (Private
->DevNullScreen
);
1469 Size
= (Row
* (Column
+ 1)) * sizeof (CHAR16
);
1470 Private
->DevNullScreen
= AllocateZeroPool (Size
);
1471 if (Private
->DevNullScreen
== NULL
) {
1472 return EFI_OUT_OF_RESOURCES
;
1475 if (Private
->DevNullAttributes
!= NULL
) {
1476 FreePool (Private
->DevNullAttributes
);
1479 Size
= Row
* Column
* sizeof (INT32
);
1480 Private
->DevNullAttributes
= AllocateZeroPool (Size
);
1481 if (Private
->DevNullAttributes
== NULL
) {
1482 return EFI_OUT_OF_RESOURCES
;
1486 DevNullTextOutClearScreen (Private
);
1493 Clears the output device(s) display to the currently selected background
1496 @param Private Text Out Splitter pointer.
1498 @retval EFI_SUCCESS The operation completed successfully.
1499 @retval EFI_DEVICE_ERROR The device had an error and could not complete
1501 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
1505 DevNullTextOutClearScreen (
1506 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
1513 INT32 CurrentAttribute
;
1516 // Clear the DevNull Text Out Buffers.
1517 // The screen is filled with spaces.
1518 // The attributes are all synced with the current Simple Text Out Attribute
1520 Screen
= Private
->DevNullScreen
;
1521 Attributes
= Private
->DevNullAttributes
;
1522 CurrentAttribute
= Private
->TextOutMode
.Attribute
;
1524 for (Row
= 0; Row
< Private
->DevNullRows
; Row
++) {
1525 for (Column
= 0; Column
< Private
->DevNullColumns
; Column
++, Screen
++, Attributes
++) {
1527 *Attributes
= CurrentAttribute
;
1530 // Each line of the screen has a NULL on the end so we must skip over it
1535 DevNullTextOutSetCursorPosition (Private
, 0, 0);
1537 return DevNullTextOutEnableCursor (Private
, TRUE
);
1542 Sets the current coordinates of the cursor position on NULL device.
1544 @param Private Text Out Splitter pointer.
1545 @param Column The column position to set the cursor to. Must be
1546 greater than or equal to zero and less than the
1547 number of columns by QueryMode ().
1548 @param Row The row position to set the cursor to. Must be
1549 greater than or equal to zero and less than the
1550 number of rows by QueryMode ().
1552 @retval EFI_SUCCESS Always returned.
1556 DevNullTextOutSetCursorPosition (
1557 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1563 // No need to do extra check here as whether (Column, Row) is valid has
1564 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
1565 // always be supported.
1567 Private
->TextOutMode
.CursorColumn
= (INT32
) Column
;
1568 Private
->TextOutMode
.CursorRow
= (INT32
) Row
;
1575 Set cursor visibility property on NULL device.
1577 @param Private Text Out Splitter pointer.
1578 @param Visible If TRUE, the cursor is set to be visible, If
1579 FALSE, the cursor is set to be invisible.
1581 @retval EFI_SUCCESS Always returned.
1585 DevNullTextOutEnableCursor (
1586 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
1590 Private
->TextOutMode
.CursorVisible
= Visible
;
1597 Take the DevNull TextOut device and update the Simple Text Out on every
1600 @param Private Text Out Splitter pointer.
1602 @retval EFI_SUCCESS The request is valid.
1603 @retval other Return status of TextOut->OutputString ()
1608 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
1612 EFI_STATUS ReturnStatus
;
1617 UINTN CurrentColumn
;
1620 INT32 StartAttribute
;
1621 BOOLEAN StartCursorState
;
1626 CHAR16
*ScreenStart
;
1627 INT32 CurrentAttribute
;
1629 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Sto
;
1632 // Save the devices Attributes, Cursor enable state and location
1634 StartColumn
= Private
->TextOutMode
.CursorColumn
;
1635 StartRow
= Private
->TextOutMode
.CursorRow
;
1636 StartAttribute
= Private
->TextOutMode
.Attribute
;
1637 StartCursorState
= Private
->TextOutMode
.CursorVisible
;
1639 for (List
= 0; List
< Private
->CurrentNumberOfConsoles
; List
++) {
1641 Sto
= Private
->TextOutList
[List
].TextOut
;
1644 // Skip non GOP/UGA devices
1646 if ((Private
->TextOutList
[List
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[List
].UgaDraw
!= NULL
)) {
1647 Sto
->EnableCursor (Sto
, FALSE
);
1648 Sto
->ClearScreen (Sto
);
1652 ReturnStatus
= EFI_SUCCESS
;
1653 Screen
= Private
->DevNullScreen
;
1654 Attributes
= Private
->DevNullAttributes
;
1655 MaxColumn
= Private
->DevNullColumns
;
1657 Buffer
= AllocateZeroPool ((MaxColumn
+ 1) * sizeof (CHAR16
));
1658 if (Buffer
== NULL
) {
1659 return ReturnStatus
;
1662 for (Row
= 0; Row
< Private
->DevNullRows
; Row
++, Screen
+= (MaxColumn
+ 1), Attributes
+= MaxColumn
) {
1664 if (Row
== (Private
->DevNullRows
- 1)) {
1666 // Don't ever sync the last character as it will scroll the screen
1668 Screen
[MaxColumn
- 1] = 0x00;
1672 while (Column
< MaxColumn
) {
1673 if (Screen
[Column
] > 0) {
1674 CurrentAttribute
= Attributes
[Column
];
1675 CurrentColumn
= Column
;
1676 ScreenStart
= &Screen
[Column
];
1679 // the line end is alway 0x0. So Column should be less than MaxColumn
1680 // It should be still in the same row
1682 for (Str
= ScreenStart
, BufferTail
= Buffer
; *Str
!= 0; Str
++, Column
++) {
1684 if (Attributes
[Column
] != CurrentAttribute
) {
1691 if ((Attributes
[Column
] & EFI_WIDE_ATTRIBUTE
) != 0) {
1699 for (List
= 0; List
< Private
->CurrentNumberOfConsoles
; List
++) {
1701 Sto
= Private
->TextOutList
[List
].TextOut
;
1704 // Skip non GOP/UGA devices
1706 if ((Private
->TextOutList
[List
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[List
].UgaDraw
!= NULL
)) {
1707 Sto
->SetAttribute (Sto
, CurrentAttribute
);
1708 Sto
->SetCursorPosition (Sto
, CurrentColumn
, Row
);
1709 Status
= Sto
->OutputString (Sto
, Buffer
);
1710 if (EFI_ERROR (Status
)) {
1711 ReturnStatus
= Status
;
1722 // Restore the devices Attributes, Cursor enable state and location
1724 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
, StartAttribute
);
1732 Sto
->SetCursorPosition (Sto
, StartColumn
, StartRow
);
1733 Status
= Sto
->EnableCursor (Sto
, StartCursorState
);
1734 if (EFI_ERROR (Status
)) {
1735 ReturnStatus
= Status
;
1742 return ReturnStatus
;