3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Support for ConsoleControl protocol. Support for UGA Draw spliter.
19 Support for DevNull Console Out. This console uses memory buffers
20 to represnt the console. It allows a console to start very early and
21 when a new console is added it is synced up with the current console
26 #include "ConSplitter.h"
28 static CHAR16 mCrLfString
[3] = { CHAR_CARRIAGE_RETURN
, CHAR_LINEFEED
, CHAR_NULL
};
32 ConSpliterConsoleControlGetMode (
33 IN EFI_CONSOLE_CONTROL_PROTOCOL
*This
,
34 OUT EFI_CONSOLE_CONTROL_SCREEN_MODE
*Mode
,
35 OUT BOOLEAN
*UgaExists
,
36 OUT BOOLEAN
*StdInLocked
41 Return the current video mode information. Also returns info about existence
42 of UGA Draw devices in system, and if the Std In device is locked. All the
43 arguments are optional and only returned if a non NULL pointer is passed in.
46 This - Protocol instance pointer.
47 Mode - Are we in text of grahics mode.
48 UgaExists - TRUE if UGA Spliter has found a UGA device
49 StdInLocked - TRUE if StdIn device is keyboard locked
52 EFI_SUCCESS - Mode information returned.
53 EFI_INVALID_PARAMETER - Invalid parameters.
57 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
60 Private
= CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
63 return EFI_INVALID_PARAMETER
;
66 *Mode
= Private
->UgaMode
;
68 if (UgaExists
!= NULL
) {
70 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
71 if (Private
->TextOutList
[Index
].UgaDraw
!= NULL
) {
78 if (StdInLocked
!= NULL
) {
79 *StdInLocked
= ConSpliterConssoleControlStdInLocked ();
87 ConSpliterConsoleControlSetMode (
88 IN EFI_CONSOLE_CONTROL_PROTOCOL
*This
,
89 IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
94 Set the current mode to either text or graphics. Graphics is
98 This - Protocol instance pointer.
99 Mode - Mode to set the
102 EFI_SUCCESS - Mode information returned.
103 EFI_INVALID_PARAMETER - Invalid parameter.
104 EFI_UNSUPPORTED - Operation unsupported.
108 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
110 TEXT_OUT_AND_UGA_DATA
*TextAndUga
;
113 Private
= CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
115 if (Mode
>= EfiConsoleControlScreenMaxValue
) {
116 return EFI_INVALID_PARAMETER
;
120 TextAndUga
= &Private
->TextOutList
[0];
121 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++, TextAndUga
++) {
122 if (TextAndUga
->UgaDraw
!= NULL
) {
128 if ((!Supported
) && (Mode
== EfiConsoleControlScreenGraphics
)) {
129 return EFI_UNSUPPORTED
;
132 Private
->UgaMode
= Mode
;
134 TextAndUga
= &Private
->TextOutList
[0];
135 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++, TextAndUga
++) {
137 TextAndUga
->TextOutEnabled
= TRUE
;
139 // If we are going into Graphics mode disable ConOut to any UGA device
141 if ((Mode
== EfiConsoleControlScreenGraphics
) && (TextAndUga
->UgaDraw
!= NULL
)) {
142 TextAndUga
->TextOutEnabled
= FALSE
;
143 DevNullUgaSync (Private
, TextAndUga
->UgaDraw
);
147 if (Mode
== EfiConsoleControlScreenText
) {
148 DevNullSyncUgaStdOut (Private
);
156 ConSpliterUgaDrawGetMode (
157 IN EFI_UGA_DRAW_PROTOCOL
*This
,
158 OUT UINT32
*HorizontalResolution
,
159 OUT UINT32
*VerticalResolution
,
160 OUT UINT32
*ColorDepth
,
161 OUT UINT32
*RefreshRate
166 Return the current video mode information.
169 This - Protocol instance pointer.
170 HorizontalResolution - Current video horizontal resolution in pixels
171 VerticalResolution - Current video vertical resolution in pixels
172 ColorDepth - Current video color depth in bits per pixel
173 RefreshRate - Current video refresh rate in Hz.
176 EFI_SUCCESS - Mode information returned.
177 EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
178 EFI_INVALID_PARAMETER - One of the input args was NULL.
182 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
184 if (!(HorizontalResolution
&& VerticalResolution
&& RefreshRate
&& ColorDepth
)) {
185 return EFI_INVALID_PARAMETER
;
188 // retrieve private data
190 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
192 *HorizontalResolution
= Private
->UgaHorizontalResolution
;
193 *VerticalResolution
= Private
->UgaVerticalResolution
;
194 *ColorDepth
= Private
->UgaColorDepth
;
195 *RefreshRate
= Private
->UgaRefreshRate
;
202 ConSpliterUgaDrawSetMode (
203 IN EFI_UGA_DRAW_PROTOCOL
*This
,
204 IN UINT32 HorizontalResolution
,
205 IN UINT32 VerticalResolution
,
206 IN UINT32 ColorDepth
,
207 IN UINT32 RefreshRate
212 Return the current video mode information.
215 This - Protocol instance pointer.
216 HorizontalResolution - Current video horizontal resolution in pixels
217 VerticalResolution - Current video vertical resolution in pixels
218 ColorDepth - Current video color depth in bits per pixel
219 RefreshRate - Current video refresh rate in Hz.
222 EFI_SUCCESS - Mode information returned.
223 EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
224 EFI_OUT_OF_RESOURCES - Out of resources.
229 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
231 EFI_STATUS ReturnStatus
;
234 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
237 // UgaDevNullSetMode ()
239 ReturnStatus
= EFI_SUCCESS
;
242 // Free the old version
244 gBS
->FreePool (Private
->UgaBlt
);
247 // Allocate the virtual Blt buffer
249 Size
= HorizontalResolution
* VerticalResolution
* sizeof (EFI_UGA_PIXEL
);
250 Private
->UgaBlt
= AllocateZeroPool (Size
);
251 if (Private
->UgaBlt
== NULL
) {
252 return EFI_OUT_OF_RESOURCES
;
256 // Update the Mode data
258 Private
->UgaHorizontalResolution
= HorizontalResolution
;
259 Private
->UgaVerticalResolution
= VerticalResolution
;
260 Private
->UgaColorDepth
= ColorDepth
;
261 Private
->UgaRefreshRate
= RefreshRate
;
263 if (Private
->UgaMode
!= EfiConsoleControlScreenGraphics
) {
267 // return the worst status met
269 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
270 if (Private
->TextOutList
[Index
].UgaDraw
!= NULL
) {
271 Status
= Private
->TextOutList
[Index
].UgaDraw
->SetMode (
272 Private
->TextOutList
[Index
].UgaDraw
,
273 HorizontalResolution
,
278 if (EFI_ERROR (Status
)) {
279 ReturnStatus
= Status
;
289 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
290 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
291 IN EFI_UGA_BLT_OPERATION BltOperation
,
294 IN UINTN DestinationX
,
295 IN UINTN DestinationY
,
298 IN UINTN Delta OPTIONAL
303 EFI_UGA_PIXEL
*BltPtr
;
304 EFI_UGA_PIXEL
*ScreenPtr
;
305 UINT32 HorizontalResolution
;
306 UINT32 VerticalResolution
;
308 if ((BltOperation
< 0) || (BltOperation
>= EfiUgaBltMax
)) {
309 return EFI_INVALID_PARAMETER
;
312 if (Width
== 0 || Height
== 0) {
313 return EFI_INVALID_PARAMETER
;
317 Delta
= Width
* sizeof (EFI_UGA_PIXEL
);
320 HorizontalResolution
= Private
->UgaHorizontalResolution
;
321 VerticalResolution
= Private
->UgaVerticalResolution
;
324 // We need to fill the Virtual Screen buffer with the blt data.
326 if (BltOperation
== EfiUgaVideoToBltBuffer
) {
328 // Video to BltBuffer: Source is Video, destination is BltBuffer
330 if ((SourceY
+ Height
) > VerticalResolution
) {
331 return EFI_INVALID_PARAMETER
;
334 if ((SourceX
+ Width
) > HorizontalResolution
) {
335 return EFI_INVALID_PARAMETER
;
338 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ DestinationY
* Delta
+ DestinationX
* sizeof (EFI_UGA_PIXEL
));
339 ScreenPtr
= &Private
->UgaBlt
[SourceY
* HorizontalResolution
+ SourceX
];
341 CopyMem (BltPtr
, ScreenPtr
, Width
* sizeof (EFI_UGA_PIXEL
));
342 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltPtr
+ Delta
);
343 ScreenPtr
+= HorizontalResolution
;
348 // BltBuffer to Video: Source is BltBuffer, destination is Video
350 if (DestinationY
+ Height
> VerticalResolution
) {
351 return EFI_INVALID_PARAMETER
;
354 if (DestinationX
+ Width
> HorizontalResolution
) {
355 return EFI_INVALID_PARAMETER
;
358 ScreenPtr
= &Private
->UgaBlt
[DestinationY
* HorizontalResolution
+ DestinationX
];
361 if (BltOperation
== EfiUgaVideoFill
) {
362 for (Index
= 0; Index
< Width
; Index
++) {
363 ScreenPtr
[Index
] = *BltBuffer
;
366 if (BltOperation
== EfiUgaBltBufferToVideo
) {
367 BltPtr
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ SrcY
* Delta
+ SourceX
* sizeof (EFI_UGA_PIXEL
));
369 BltPtr
= &Private
->UgaBlt
[SrcY
* HorizontalResolution
+ SourceX
];
372 CopyMem (ScreenPtr
, BltPtr
, Width
* sizeof (EFI_UGA_PIXEL
));
375 ScreenPtr
+= HorizontalResolution
;
386 ConSpliterUgaDrawBlt (
387 IN EFI_UGA_DRAW_PROTOCOL
*This
,
388 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
389 IN EFI_UGA_BLT_OPERATION BltOperation
,
392 IN UINTN DestinationX
,
393 IN UINTN DestinationY
,
396 IN UINTN Delta OPTIONAL
401 The following table defines actions for BltOperations:
402 EfiUgaVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
403 directly to every pixel of the video display rectangle
404 (DestinationX, DestinationY)
405 (DestinationX + Width, DestinationY + Height).
406 Only one pixel will be used from the BltBuffer. Delta is NOT used.
407 EfiUgaVideoToBltBuffer - Read data from the video display rectangle
408 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
409 the BltBuffer rectangle (DestinationX, DestinationY )
410 (DestinationX + Width, DestinationY + Height). If DestinationX or
411 DestinationY is not zero then Delta must be set to the length in bytes
412 of a row in the BltBuffer.
413 EfiUgaBltBufferToVideo - Write data from the BltBuffer rectangle
414 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
415 video display rectangle (DestinationX, DestinationY)
416 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
417 not zero then Delta must be set to the length in bytes of a row in the
419 EfiUgaVideoToVideo - Copy from the video display rectangle
420 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
421 to the video display rectangle (DestinationX, DestinationY)
422 (DestinationX + Width, DestinationY + Height).
423 The BltBuffer and Delta are not used in this mode.
426 This - Protocol instance pointer.
427 BltBuffer - Buffer containing data to blit into video buffer. This
428 buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
429 BltOperation - Operation to perform on BlitBuffer and video memory
430 SourceX - X coordinate of source for the BltBuffer.
431 SourceY - Y coordinate of source for the BltBuffer.
432 DestinationX - X coordinate of destination for the BltBuffer.
433 DestinationY - Y coordinate of destination for the BltBuffer.
434 Width - Width of rectangle in BltBuffer in pixels.
435 Height - Hight of rectangle in BltBuffer in pixels.
439 EFI_SUCCESS - The Blt operation completed.
440 EFI_INVALID_PARAMETER - BltOperation is not valid.
441 EFI_DEVICE_ERROR - A hardware error occured writting to the video
447 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
449 EFI_STATUS ReturnStatus
;
451 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
454 // Sync up DevNull UGA device
456 ReturnStatus
= DevNullUgaBlt (
468 if (Private
->UgaMode
!= EfiConsoleControlScreenGraphics
) {
472 // return the worst status met
474 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
475 if (Private
->TextOutList
[Index
].UgaDraw
!= NULL
) {
476 Status
= Private
->TextOutList
[Index
].UgaDraw
->Blt (
477 Private
->TextOutList
[Index
].UgaDraw
,
488 if (EFI_ERROR (Status
)) {
489 ReturnStatus
= Status
;
490 } else if (BltOperation
== EfiUgaVideoToBltBuffer
) {
492 // Only need to read the data into buffer one time
504 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
505 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
508 return UgaDraw
->Blt (
511 EfiUgaBltBufferToVideo
,
516 Private
->UgaHorizontalResolution
,
517 Private
->UgaVerticalResolution
,
518 Private
->UgaHorizontalResolution
* sizeof (EFI_UGA_PIXEL
)
523 DevNullTextOutOutputString (
524 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
530 Write a Unicode string to the output device.
533 Private - Pointer to the console output splitter's private data. It
534 indicates the calling context.
535 WString - The NULL-terminated Unicode string to be displayed on the output
536 device(s). All output devices must also support the Unicode
537 drawing defined in this file.
540 EFI_SUCCESS - The string was output to the device.
541 EFI_DEVICE_ERROR - The device reported an error while attempting to
543 EFI_UNSUPPORTED - The output device's mode is not currently in a
545 EFI_WARN_UNKNOWN_GLYPH - This warning code indicates that some of the
546 characters in the Unicode string could not be
547 rendered and were skipped.
554 EFI_SIMPLE_TEXT_OUTPUT_MODE
*Mode
;
561 INT32
*NullAttributes
;
566 Mode
= &Private
->TextOutMode
;
567 NullScreen
= Private
->DevNullScreen
;
568 NullAttributes
= Private
->DevNullAttributes
;
569 LastRow
= Private
->DevNullRows
- 1;
570 MaxColumn
= Private
->DevNullColumns
;
572 if (Mode
->Attribute
& EFI_WIDE_ATTRIBUTE
) {
580 if (*WString
== CHAR_BACKSPACE
) {
582 // If the cursor is at the left edge of the display, then move the cursor
585 if (Mode
->CursorColumn
== 0 && Mode
->CursorRow
> 0) {
587 Mode
->CursorColumn
= (INT32
) MaxColumn
;
591 // If the cursor is not at the left edge of the display,
592 // then move the cursor left one column.
594 if (Mode
->CursorColumn
> 0) {
595 Mode
->CursorColumn
--;
596 if (Mode
->CursorColumn
> 0 &&
597 NullAttributes
[Mode
->CursorRow
* MaxColumn
+ Mode
->CursorColumn
- 1] & EFI_WIDE_ATTRIBUTE
599 Mode
->CursorColumn
--;
602 // Insert an extra backspace
604 InsertChar
= CHAR_BACKSPACE
;
609 InsertChar
= TempChar
;
622 } else if (*WString
== CHAR_LINEFEED
) {
624 // If the cursor is at the bottom of the display,
625 // then scroll the display one row, and do not update
626 // the cursor position. Otherwise, move the cursor down one row.
628 if (Mode
->CursorRow
== (INT32
) (LastRow
)) {
630 // Scroll Screen Up One Row
632 SizeAttribute
= LastRow
* MaxColumn
;
635 NullAttributes
+ MaxColumn
,
636 SizeAttribute
* sizeof (INT32
)
640 // Each row has an ending CHAR_NULL. So one more character each line
641 // for DevNullScreen than DevNullAttributes
643 SizeScreen
= SizeAttribute
+ LastRow
;
646 NullScreen
+ (MaxColumn
+ 1),
647 SizeScreen
* sizeof (CHAR16
)
651 // Print Blank Line at last line
653 Screen
= NullScreen
+ SizeScreen
;
654 Attribute
= NullAttributes
+ SizeAttribute
;
656 for (Index
= 0; Index
< MaxColumn
; Index
++, Screen
++, Attribute
++) {
658 *Attribute
= Mode
->Attribute
;
665 } else if (*WString
== CHAR_CARRIAGE_RETURN
) {
667 // Move the cursor to the beginning of the current row.
669 Mode
->CursorColumn
= 0;
673 // Print the character at the current cursor position and
674 // move the cursor right one column. If this moves the cursor
675 // past the right edge of the display, then the line should wrap to
676 // the beginning of the next line. This is equivalent to inserting
677 // a CR and an LF. Note that if the cursor is at the bottom of the
678 // display, and the line wraps, then the display will be scrolled
681 Index
= Mode
->CursorRow
* MaxColumn
+ Mode
->CursorColumn
;
683 while (Mode
->CursorColumn
< (INT32
) MaxColumn
) {
684 if (*WString
== CHAR_NULL
) {
688 if (*WString
== CHAR_BACKSPACE
) {
692 if (*WString
== CHAR_LINEFEED
) {
696 if (*WString
== CHAR_CARRIAGE_RETURN
) {
700 if (*WString
== WIDE_CHAR
|| *WString
== NARROW_CHAR
) {
701 CurrentWidth
= (*WString
== WIDE_CHAR
) ? 2 : 1;
706 if (Mode
->CursorColumn
+ CurrentWidth
> (INT32
) MaxColumn
) {
708 // If a wide char is at the rightmost column, then move the char
709 // to the beginning of the next row
711 NullScreen
[Index
+ Mode
->CursorRow
] = L
' ';
712 NullAttributes
[Index
] = Mode
->Attribute
| (UINT32
) EFI_WIDE_ATTRIBUTE
;
714 Mode
->CursorColumn
++;
716 NullScreen
[Index
+ Mode
->CursorRow
] = *WString
;
717 NullAttributes
[Index
] = Mode
->Attribute
;
718 if (CurrentWidth
== 1) {
719 NullAttributes
[Index
] &= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
721 NullAttributes
[Index
] |= (UINT32
) EFI_WIDE_ATTRIBUTE
;
722 NullAttributes
[Index
+ 1] &= (~ (UINT32
) EFI_WIDE_ATTRIBUTE
);
725 Index
+= CurrentWidth
;
727 Mode
->CursorColumn
+= CurrentWidth
;
731 // At the end of line, output carriage return and line feed
733 if (Mode
->CursorColumn
>= (INT32
) MaxColumn
) {
734 DevNullTextOutOutputString (Private
, mCrLfString
);
743 DevNullTextOutSetMode (
744 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
750 Sets the output device(s) to a specified mode.
753 Private - Private data structure pointer.
754 ModeNumber - The mode number to set.
757 EFI_SUCCESS - The requested text mode was set.
758 EFI_DEVICE_ERROR - The device had an error and
759 could not complete the request.
760 EFI_UNSUPPORTED - The mode number was not valid.
761 EFI_OUT_OF_RESOURCES - Out of resources.
768 TEXT_OUT_SPLITTER_QUERY_DATA
*Mode
;
771 // No extra check for ModeNumber here, as it has been checked in
772 // ConSplitterTextOutSetMode. And mode 0 should always be supported.
774 Mode
= &(Private
->TextOutQueryData
[ModeNumber
]);
776 Column
= Mode
->Columns
;
778 if (Row
<= 0 && Column
<= 0) {
779 return EFI_UNSUPPORTED
;
782 if (Private
->DevNullColumns
!= Column
|| Private
->DevNullRows
!= Row
) {
784 Private
->TextOutMode
.Mode
= (INT32
) ModeNumber
;
785 Private
->DevNullColumns
= Column
;
786 Private
->DevNullRows
= Row
;
788 gBS
->FreePool (Private
->DevNullScreen
);
790 Size
= (Row
* (Column
+ 1)) * sizeof (CHAR16
);
791 Private
->DevNullScreen
= AllocateZeroPool (Size
);
792 if (Private
->DevNullScreen
== NULL
) {
793 return EFI_OUT_OF_RESOURCES
;
796 gBS
->FreePool (Private
->DevNullAttributes
);
798 Size
= Row
* Column
* sizeof (INT32
);
799 Private
->DevNullAttributes
= AllocateZeroPool (Size
);
800 if (Private
->DevNullAttributes
== NULL
) {
801 return EFI_OUT_OF_RESOURCES
;
805 DevNullTextOutClearScreen (Private
);
811 DevNullTextOutClearScreen (
812 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
817 Clears the output device(s) display to the currently selected background
821 Private - Protocol instance pointer.
824 EFI_SUCCESS - The operation completed successfully.
825 EFI_DEVICE_ERROR - The device had an error and
826 could not complete the request.
827 EFI_UNSUPPORTED - The output device is not in a valid text mode.
835 INT32 CurrentAttribute
;
838 // Clear the DevNull Text Out Buffers.
839 // The screen is filled with spaces.
840 // The attributes are all synced with the current Simple Text Out Attribute
842 Screen
= Private
->DevNullScreen
;
843 Attributes
= Private
->DevNullAttributes
;
844 CurrentAttribute
= Private
->TextOutMode
.Attribute
;
846 for (Row
= 0; Row
< Private
->DevNullRows
; Row
++) {
847 for (Column
= 0; Column
< Private
->DevNullColumns
; Column
++, Screen
++, Attributes
++) {
849 *Attributes
= CurrentAttribute
;
852 // Each line of the screen has a NULL on the end so we must skip over it
857 DevNullTextOutSetCursorPosition (Private
, 0, 0);
859 return DevNullTextOutEnableCursor (Private
, TRUE
);
863 DevNullTextOutSetCursorPosition (
864 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
871 Sets the current coordinates of the cursor position
874 Private - Protocol instance pointer.
875 Column, Row - the position to set the cursor to. Must be greater than or
876 equal to zero and less than the number of columns and rows
880 EFI_SUCCESS - The operation completed successfully.
881 EFI_DEVICE_ERROR - The device had an error and
882 could not complete the request.
883 EFI_UNSUPPORTED - The output device is not in a valid text mode, or the
884 cursor position is invalid for the current mode.
889 // No need to do extra check here as whether (Column, Row) is valid has
890 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
891 // always be supported.
893 Private
->TextOutMode
.CursorColumn
= (INT32
) Column
;
894 Private
->TextOutMode
.CursorRow
= (INT32
) Row
;
900 DevNullTextOutEnableCursor (
901 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
907 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
908 In this driver, the cursor cannot be hidden.
912 Private - Indicates the calling context.
914 Visible - If TRUE, the cursor is set to be visible, If FALSE, the cursor
915 is set to be invisible.
919 EFI_SUCCESS - The request is valid.
924 Private
->TextOutMode
.CursorVisible
= Visible
;
930 DevNullSyncUgaStdOut (
931 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
935 Take the DevNull TextOut device and update the Simple Text Out on every
939 Private - Indicates the calling context.
942 EFI_SUCCESS - The request is valid.
943 other - Return status of TextOut->OutputString ()
948 EFI_STATUS ReturnStatus
;
956 INT32 StartAttribute
;
957 BOOLEAN StartCursorState
;
963 INT32 CurrentAttribute
;
965 EFI_SIMPLE_TEXT_OUT_PROTOCOL
*Sto
;
968 // Save the devices Attributes, Cursor enable state and location
970 StartColumn
= Private
->TextOutMode
.CursorColumn
;
971 StartRow
= Private
->TextOutMode
.CursorRow
;
972 StartAttribute
= Private
->TextOutMode
.Attribute
;
973 StartCursorState
= Private
->TextOutMode
.CursorVisible
;
975 for (List
= 0; List
< Private
->CurrentNumberOfConsoles
; List
++) {
977 Sto
= Private
->TextOutList
[List
].TextOut
;
980 // Skip non UGA devices
982 if (Private
->TextOutList
[List
].UgaDraw
!= NULL
) {
983 Sto
->EnableCursor (Sto
, FALSE
);
984 Sto
->ClearScreen (Sto
);
988 ReturnStatus
= EFI_SUCCESS
;
989 Screen
= Private
->DevNullScreen
;
990 Attributes
= Private
->DevNullAttributes
;
991 MaxColumn
= Private
->DevNullColumns
;
993 Buffer
= AllocateZeroPool ((MaxColumn
+ 1) * sizeof (CHAR16
));
995 for (Row
= 0; Row
< Private
->DevNullRows
; Row
++, Screen
+= (MaxColumn
+ 1), Attributes
+= MaxColumn
) {
997 if (Row
== (Private
->DevNullRows
- 1)) {
999 // Don't ever sync the last character as it will scroll the screen
1001 Screen
[MaxColumn
- 1] = 0x00;
1005 while (Column
< MaxColumn
) {
1006 if (Screen
[Column
]) {
1007 CurrentAttribute
= Attributes
[Column
];
1008 CurrentColumn
= Column
;
1009 ScreenStart
= &Screen
[Column
];
1012 // the line end is alway 0x0. So Column should be less than MaxColumn
1013 // It should be still in the same row
1015 for (Str
= ScreenStart
, BufferTail
= Buffer
; *Str
!= 0; Str
++, Column
++) {
1017 if (Attributes
[Column
] != CurrentAttribute
) {
1024 if (Attributes
[Column
] & EFI_WIDE_ATTRIBUTE
) {
1032 for (List
= 0; List
< Private
->CurrentNumberOfConsoles
; List
++) {
1034 Sto
= Private
->TextOutList
[List
].TextOut
;
1037 // Skip non UGA devices
1039 if (Private
->TextOutList
[List
].UgaDraw
!= NULL
) {
1040 Sto
->SetAttribute (Sto
, CurrentAttribute
);
1041 Sto
->SetCursorPosition (Sto
, CurrentColumn
, Row
);
1042 Status
= Sto
->OutputString (Sto
, Buffer
);
1043 if (EFI_ERROR (Status
)) {
1044 ReturnStatus
= Status
;
1055 // Restore the devices Attributes, Cursor enable state and location
1057 for (List
= 0; List
< Private
->CurrentNumberOfConsoles
; List
++) {
1058 Sto
= Private
->TextOutList
[List
].TextOut
;
1061 // Skip non UGA devices
1063 if (Private
->TextOutList
[List
].UgaDraw
!= NULL
) {
1064 Sto
->SetAttribute (Sto
, StartAttribute
);
1065 Sto
->SetCursorPosition (Sto
, StartColumn
, StartRow
);
1066 Status
= Sto
->EnableCursor (Sto
, StartCursorState
);
1067 if (EFI_ERROR (Status
)) {
1068 ReturnStatus
= Status
;
1073 gBS
->FreePool (Buffer
);
1075 return ReturnStatus
;