2 Console Splitter Driver. Any Handle that attatched
3 EFI_CONSOLE_IDENTIFIER_PROTOCOL can be bound by this driver.
5 So far it works like any other driver by opening a SimpleTextIn and/or
6 SimpleTextOut protocol with EFI_OPEN_PROTOCOL_BY_DRIVER attributes. The big
7 difference is this driver does not layer a protocol on the passed in
8 handle, or construct a child handle like a standard device or bus driver.
9 This driver produces three virtual handles as children, one for console input
10 splitter, one for console output splitter and one for error output splitter.
11 EFI_CONSOLE_SPLIT_PROTOCOL will be attatched onto each virtual handle to
12 identify the splitter type.
14 Each virtual handle, that supports both the EFI_CONSOLE_SPLIT_PROTOCOL
15 and Console I/O protocol, will be produced in the driver entry point.
16 The virtual handle are added on driver entry and never removed.
17 Such design ensures sytem function well during none console device situation.
19 Copyright (c) 2006 - 2008 Intel Corporation. <BR>
20 All rights reserved. This program and the accompanying materials
21 are licensed and made available under the terms and conditions of the BSD License
22 which accompanies this distribution. The full text of the license may be found at
23 http://opensource.org/licenses/bsd-license.php
25 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
26 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
30 #include "ConSplitter.h"
33 // Template for Text In Splitter
35 STATIC TEXT_IN_SPLITTER_PRIVATE_DATA mConIn
= {
36 TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE
,
39 ConSplitterTextInReset
,
40 ConSplitterTextInReadKeyStroke
,
44 (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
**) NULL
,
47 ConSplitterTextInResetEx
,
48 ConSplitterTextInReadKeyStrokeEx
,
50 ConSplitterTextInSetState
,
51 ConSplitterTextInRegisterKeyNotify
,
52 ConSplitterTextInUnregisterKeyNotify
55 (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
**) NULL
,
63 ConSplitterSimplePointerReset
,
64 ConSplitterSimplePointerGetState
,
66 (EFI_SIMPLE_POINTER_MODE
*) NULL
76 (EFI_SIMPLE_POINTER_PROTOCOL
**) NULL
,
80 ConSplitterAbsolutePointerReset
,
81 ConSplitterAbsolutePointerGetState
,
83 (EFI_ABSOLUTE_POINTER_MODE
*) NULL
90 0x10000, //AbsoluteMaxX
91 0x10000, //AbsoluteMaxY
92 0x10000, //AbsoluteMaxZ
96 (EFI_ABSOLUTE_POINTER_PROTOCOL
**) NULL
,
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
121 // Template for Uga Draw Protocol
123 GLOBAL_REMOVE_IF_UNREFERENCED EFI_UGA_DRAW_PROTOCOL mUgaDrawProtocolTemplate
= {
124 ConSpliterUgaDrawGetMode
,
125 ConSpliterUgaDrawSetMode
,
130 // Template for Graphics Output Protocol
132 GLOBAL_REMOVE_IF_UNREFERENCED EFI_GRAPHICS_OUTPUT_PROTOCOL mGraphicsOutputProtocolTemplate
= {
133 ConSpliterGraphicsOutputQueryMode
,
134 ConSpliterGraphicsOutputSetMode
,
135 ConSpliterGraphicsOutputBlt
,
140 // Template for Text Out Splitter
142 STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut
= {
143 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE
,
146 ConSplitterTextOutReset
,
147 ConSplitterTextOutOutputString
,
148 ConSplitterTextOutTestString
,
149 ConSplitterTextOutQueryMode
,
150 ConSplitterTextOutSetMode
,
151 ConSplitterTextOutSetAttribute
,
152 ConSplitterTextOutClearScreen
,
153 ConSplitterTextOutSetCursorPosition
,
154 ConSplitterTextOutEnableCursor
,
155 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
174 (EFI_UGA_PIXEL
*) NULL
,
181 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) NULL
,
182 (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*) NULL
,
187 ConSpliterConsoleControlGetMode
,
188 ConSpliterConsoleControlSetMode
,
189 ConSpliterConsoleControlLockStdIn
193 (TEXT_OUT_AND_GOP_DATA
*) NULL
,
195 (TEXT_OUT_SPLITTER_QUERY_DATA
*) NULL
,
199 EfiConsoleControlScreenText
,
207 // Template for Standard Error Text Out Splitter
209 STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr
= {
210 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE
,
213 ConSplitterTextOutReset
,
214 ConSplitterTextOutOutputString
,
215 ConSplitterTextOutTestString
,
216 ConSplitterTextOutQueryMode
,
217 ConSplitterTextOutSetMode
,
218 ConSplitterTextOutSetAttribute
,
219 ConSplitterTextOutClearScreen
,
220 ConSplitterTextOutSetCursorPosition
,
221 ConSplitterTextOutEnableCursor
,
222 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
241 (EFI_UGA_PIXEL
*) NULL
,
248 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) NULL
,
249 (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*) NULL
,
254 ConSpliterConsoleControlGetMode
,
255 ConSpliterConsoleControlSetMode
,
256 ConSpliterConsoleControlLockStdIn
260 (TEXT_OUT_AND_GOP_DATA
*) NULL
,
262 (TEXT_OUT_SPLITTER_QUERY_DATA
*) NULL
,
266 EfiConsoleControlScreenText
,
274 // Driver binding instance for Console Input Device
276 EFI_DRIVER_BINDING_PROTOCOL gConSplitterConInDriverBinding
= {
277 ConSplitterConInDriverBindingSupported
,
278 ConSplitterConInDriverBindingStart
,
279 ConSplitterConInDriverBindingStop
,
286 // Driver binding instance for Simple Pointer protocol
288 EFI_DRIVER_BINDING_PROTOCOL gConSplitterSimplePointerDriverBinding
= {
289 ConSplitterSimplePointerDriverBindingSupported
,
290 ConSplitterSimplePointerDriverBindingStart
,
291 ConSplitterSimplePointerDriverBindingStop
,
298 // Driver binding instance for Absolute Pointer protocol
300 EFI_DRIVER_BINDING_PROTOCOL gConSplitterAbsolutePointerDriverBinding
= {
301 ConSplitterAbsolutePointerDriverBindingSupported
,
302 ConSplitterAbsolutePointerDriverBindingStart
,
303 ConSplitterAbsolutePointerDriverBindingStop
,
310 // Driver binding instance for Console Out device
312 EFI_DRIVER_BINDING_PROTOCOL gConSplitterConOutDriverBinding
= {
313 ConSplitterConOutDriverBindingSupported
,
314 ConSplitterConOutDriverBindingStart
,
315 ConSplitterConOutDriverBindingStop
,
322 // Driver binding instance for Standard Error device
324 EFI_DRIVER_BINDING_PROTOCOL gConSplitterStdErrDriverBinding
= {
325 ConSplitterStdErrDriverBindingSupported
,
326 ConSplitterStdErrDriverBindingStart
,
327 ConSplitterStdErrDriverBindingStop
,
334 The user Entry Point for module ConSplitter. The user code starts with this function.
336 Installs driver module protocols and. Creates virtual device handles for ConIn,
337 ConOut, and StdErr. Installs Simple Text In protocol, Simple Text In Ex protocol,
338 Simple Pointer protocol, Absolute Pointer protocol on those virtual handlers.
339 Installs Graphics Output protocol and/or UGA Draw protocol if needed.
341 @param[in] ImageHandle The firmware allocated handle for the EFI image.
342 @param[in] SystemTable A pointer to the EFI System Table.
344 @retval EFI_SUCCESS The entry point is executed successfully.
345 @retval other Some error occurs when executing this entry point.
350 ConSplitterDriverEntry(
351 IN EFI_HANDLE ImageHandle
,
352 IN EFI_SYSTEM_TABLE
*SystemTable
358 // Install driver model protocol(s).
360 Status
= EfiLibInstallDriverBindingComponentName2 (
363 &gConSplitterConInDriverBinding
,
365 &gConSplitterConInComponentName
,
366 &gConSplitterConInComponentName2
368 ASSERT_EFI_ERROR (Status
);
370 Status
= EfiLibInstallDriverBindingComponentName2 (
373 &gConSplitterSimplePointerDriverBinding
,
375 &gConSplitterSimplePointerComponentName
,
376 &gConSplitterSimplePointerComponentName2
378 ASSERT_EFI_ERROR (Status
);
380 Status
= EfiLibInstallDriverBindingComponentName2 (
383 &gConSplitterAbsolutePointerDriverBinding
,
385 &gConSplitterAbsolutePointerComponentName
,
386 &gConSplitterAbsolutePointerComponentName2
388 ASSERT_EFI_ERROR (Status
);
390 Status
= EfiLibInstallDriverBindingComponentName2 (
393 &gConSplitterConOutDriverBinding
,
395 &gConSplitterConOutComponentName
,
396 &gConSplitterConOutComponentName2
398 ASSERT_EFI_ERROR (Status
);
400 Status
= EfiLibInstallDriverBindingComponentName2 (
403 &gConSplitterStdErrDriverBinding
,
405 &gConSplitterStdErrComponentName
,
406 &gConSplitterStdErrComponentName2
408 ASSERT_EFI_ERROR (Status
);
411 ASSERT (FeaturePcdGet (PcdConOutGopSupport
) ||
412 FeaturePcdGet (PcdConOutUgaSupport
));
414 // The driver creates virtual handles for ConIn, ConOut, and StdErr.
415 // The virtual handles will always exist even if no console exist in the
416 // system. This is need to support hotplug devices like USB.
419 // Create virtual device handle for StdErr Splitter
421 Status
= ConSplitterTextOutConstructor (&mStdErr
);
422 if (!EFI_ERROR (Status
)) {
423 Status
= gBS
->InstallMultipleProtocolInterfaces (
424 &mStdErr
.VirtualHandle
,
425 &gEfiSimpleTextOutProtocolGuid
,
427 &gEfiPrimaryStandardErrorDeviceGuid
,
433 // Create virtual device handle for ConIn Splitter
435 Status
= ConSplitterTextInConstructor (&mConIn
);
436 if (!EFI_ERROR (Status
)) {
437 Status
= gBS
->InstallMultipleProtocolInterfaces (
438 &mConIn
.VirtualHandle
,
439 &gEfiSimpleTextInProtocolGuid
,
441 &gEfiSimpleTextInputExProtocolGuid
,
443 &gEfiSimplePointerProtocolGuid
,
444 &mConIn
.SimplePointer
,
445 &gEfiAbsolutePointerProtocolGuid
,
446 &mConIn
.AbsolutePointer
,
447 &gEfiPrimaryConsoleInDeviceGuid
,
451 if (!EFI_ERROR (Status
)) {
453 // Update the EFI System Table with new virtual console
455 gST
->ConsoleInHandle
= mConIn
.VirtualHandle
;
456 gST
->ConIn
= &mConIn
.TextIn
;
460 // Create virtual device handle for ConOut Splitter
462 Status
= ConSplitterTextOutConstructor (&mConOut
);
463 if (!EFI_ERROR (Status
)) {
464 if (!FeaturePcdGet (PcdConOutGopSupport
)) {
466 // In EFI mode, UGA Draw protocol is installed
468 Status
= gBS
->InstallMultipleProtocolInterfaces (
469 &mConOut
.VirtualHandle
,
470 &gEfiSimpleTextOutProtocolGuid
,
472 &gEfiUgaDrawProtocolGuid
,
474 &gEfiConsoleControlProtocolGuid
,
475 &mConOut
.ConsoleControl
,
476 &gEfiPrimaryConsoleOutDeviceGuid
,
480 } else if (!FeaturePcdGet (PcdConOutUgaSupport
)) {
482 // In UEFI mode, Graphics Output Protocol is installed on virtual handle.
484 Status
= gBS
->InstallMultipleProtocolInterfaces (
485 &mConOut
.VirtualHandle
,
486 &gEfiSimpleTextOutProtocolGuid
,
488 &gEfiGraphicsOutputProtocolGuid
,
489 &mConOut
.GraphicsOutput
,
490 &gEfiConsoleControlProtocolGuid
,
491 &mConOut
.ConsoleControl
,
492 &gEfiPrimaryConsoleOutDeviceGuid
,
498 // In EFI and UEFI comptible mode, Graphics Output Protocol and UGA are
499 // installed on virtual handle.
501 Status
= gBS
->InstallMultipleProtocolInterfaces (
502 &mConOut
.VirtualHandle
,
503 &gEfiSimpleTextOutProtocolGuid
,
505 &gEfiGraphicsOutputProtocolGuid
,
506 &mConOut
.GraphicsOutput
,
507 &gEfiUgaDrawProtocolGuid
,
509 &gEfiConsoleControlProtocolGuid
,
510 &mConOut
.ConsoleControl
,
511 &gEfiPrimaryConsoleOutDeviceGuid
,
517 if (!EFI_ERROR (Status
)) {
519 // Update the EFI System Table with new virtual console
521 gST
->ConsoleOutHandle
= mConOut
.VirtualHandle
;
522 gST
->ConOut
= &mConOut
.TextOut
;
527 // Update the CRC32 in the EFI System Table header
530 gBS
->CalculateCrc32 (
542 Construct console input devices' private data.
544 @param ConInPrivate A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA
547 @retval EFI_OUT_OF_RESOURCES Out of resources.
548 @retval EFI_SUCCESS Text Input Devcie's private data has been constructed.
549 @retval other Failed to construct private data.
553 ConSplitterTextInConstructor (
554 TEXT_IN_SPLITTER_PRIVATE_DATA
*ConInPrivate
560 // Initilize console input splitter's private data.
562 Status
= ConSplitterGrowBuffer (
563 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
564 &ConInPrivate
->TextInListCount
,
565 (VOID
**) &ConInPrivate
->TextInList
567 if (EFI_ERROR (Status
)) {
568 return EFI_OUT_OF_RESOURCES
;
571 // Create Event to support locking StdIn Device
573 Status
= gBS
->CreateEvent (
574 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
576 ConSpliterConsoleControlLockStdInEvent
,
578 &ConInPrivate
->LockEvent
580 ASSERT_EFI_ERROR (Status
);
582 Status
= gBS
->CreateEvent (
585 ConSplitterTextInWaitForKey
,
587 &ConInPrivate
->TextIn
.WaitForKey
589 ASSERT_EFI_ERROR (Status
);
592 // Buffer for Simple Text Input Ex Protocol
594 Status
= ConSplitterGrowBuffer (
595 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
596 &ConInPrivate
->TextInExListCount
,
597 (VOID
**) &ConInPrivate
->TextInExList
599 if (EFI_ERROR (Status
)) {
600 return EFI_OUT_OF_RESOURCES
;
603 Status
= gBS
->CreateEvent (
606 ConSplitterTextInWaitForKey
,
608 &ConInPrivate
->TextInEx
.WaitForKeyEx
610 ASSERT_EFI_ERROR (Status
);
612 InitializeListHead (&ConInPrivate
->NotifyList
);
615 // Allocate Buffer and Create Event for Absolute Pointer and Simple Pointer Protocols
617 ConInPrivate
->AbsolutePointer
.Mode
= &ConInPrivate
->AbsolutePointerMode
;
619 Status
= ConSplitterGrowBuffer (
620 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
621 &ConInPrivate
->AbsolutePointerListCount
,
622 (VOID
**) &ConInPrivate
->AbsolutePointerList
624 if (EFI_ERROR (Status
)) {
625 return EFI_OUT_OF_RESOURCES
;
628 Status
= gBS
->CreateEvent (
631 ConSplitterAbsolutePointerWaitForInput
,
633 &ConInPrivate
->AbsolutePointer
.WaitForInput
635 ASSERT_EFI_ERROR (Status
);
637 ConInPrivate
->SimplePointer
.Mode
= &ConInPrivate
->SimplePointerMode
;
639 Status
= ConSplitterGrowBuffer (
640 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
641 &ConInPrivate
->PointerListCount
,
642 (VOID
**) &ConInPrivate
->PointerList
644 if (EFI_ERROR (Status
)) {
645 return EFI_OUT_OF_RESOURCES
;
648 Status
= gBS
->CreateEvent (
651 ConSplitterSimplePointerWaitForInput
,
653 &ConInPrivate
->SimplePointer
.WaitForInput
660 Construct console output devices' private data.
662 @param ConOutPrivate A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA
665 @retval EFI_OUT_OF_RESOURCES Out of resources.
666 @retval EFI_SUCCESS Text Input Devcie's private data has been constructed.
670 ConSplitterTextOutConstructor (
671 TEXT_OUT_SPLITTER_PRIVATE_DATA
*ConOutPrivate
675 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
678 // Copy protocols template
680 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
681 CopyMem (&ConOutPrivate
->UgaDraw
, &mUgaDrawProtocolTemplate
, sizeof (EFI_UGA_DRAW_PROTOCOL
));
684 if (FeaturePcdGet (PcdConOutGopSupport
)) {
685 CopyMem (&ConOutPrivate
->GraphicsOutput
, &mGraphicsOutputProtocolTemplate
, sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL
));
689 // Initilize console output splitter's private data.
691 ConOutPrivate
->TextOut
.Mode
= &ConOutPrivate
->TextOutMode
;
694 // When new console device is added, the new mode will be set later,
695 // so put current mode back to init state.
697 ConOutPrivate
->TextOutMode
.Mode
= 0xFF;
699 Status
= ConSplitterGrowBuffer (
700 sizeof (TEXT_OUT_AND_GOP_DATA
),
701 &ConOutPrivate
->TextOutListCount
,
702 (VOID
**) &ConOutPrivate
->TextOutList
704 if (EFI_ERROR (Status
)) {
705 return EFI_OUT_OF_RESOURCES
;
708 Status
= ConSplitterGrowBuffer (
709 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
710 &ConOutPrivate
->TextOutQueryDataCount
,
711 (VOID
**) &ConOutPrivate
->TextOutQueryData
713 if (EFI_ERROR (Status
)) {
714 return EFI_OUT_OF_RESOURCES
;
717 // Setup the DevNullTextOut console to 80 x 25
719 ConOutPrivate
->TextOutQueryData
[0].Columns
= 80;
720 ConOutPrivate
->TextOutQueryData
[0].Rows
= 25;
721 DevNullTextOutSetMode (ConOutPrivate
, 0);
723 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
725 // Setup the DevNullUgaDraw to 800 x 600 x 32 bits per pixel
727 ConSpliterUgaDrawSetMode (&ConOutPrivate
->UgaDraw
, 800, 600, 32, 60);
729 if (FeaturePcdGet (PcdConOutGopSupport
)) {
731 // Setup resource for mode information in Graphics Output Protocol interface
733 if ((ConOutPrivate
->GraphicsOutput
.Mode
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
))) == NULL
) {
734 return EFI_OUT_OF_RESOURCES
;
736 if ((ConOutPrivate
->GraphicsOutput
.Mode
->Info
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
))) == NULL
) {
737 return EFI_OUT_OF_RESOURCES
;
740 // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel
741 // DevNull will be updated to user-defined mode after driver has started.
743 if ((ConOutPrivate
->GraphicsOutputModeBuffer
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
))) == NULL
) {
744 return EFI_OUT_OF_RESOURCES
;
746 Info
= &ConOutPrivate
->GraphicsOutputModeBuffer
[0];
748 Info
->HorizontalResolution
= 800;
749 Info
->VerticalResolution
= 600;
750 Info
->PixelFormat
= PixelBltOnly
;
751 Info
->PixelsPerScanLine
= 800;
752 CopyMem (ConOutPrivate
->GraphicsOutput
.Mode
->Info
, Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
753 ConOutPrivate
->GraphicsOutput
.Mode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
756 // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()
757 // GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
759 ConOutPrivate
->GraphicsOutput
.Mode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
760 ConOutPrivate
->GraphicsOutput
.Mode
->FrameBufferSize
= 0;
762 ConOutPrivate
->GraphicsOutput
.Mode
->MaxMode
= 1;
764 // Initial current mode to unknown state, and then set to mode 0
766 ConOutPrivate
->GraphicsOutput
.Mode
->Mode
= 0xffff;
767 ConOutPrivate
->GraphicsOutput
.SetMode (&ConOutPrivate
->GraphicsOutput
, 0);
775 Test to see if the specified protocol could be supported on the ControllerHandle.
777 @param This Protocol instance pointer.
778 @param ControllerHandle Handle of device to test.
779 @param Guid The specified protocol guid.
781 @retval EFI_SUCCESS The specified protocol is supported on this device.
782 @retval other The specified protocol is not supported on this device.
786 ConSplitterSupported (
787 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
788 IN EFI_HANDLE ControllerHandle
,
796 // Make sure the Console Splitter does not attempt to attach to itself
798 if (ControllerHandle
== mConIn
.VirtualHandle
) {
799 return EFI_UNSUPPORTED
;
802 if (ControllerHandle
== mConOut
.VirtualHandle
) {
803 return EFI_UNSUPPORTED
;
806 if (ControllerHandle
== mStdErr
.VirtualHandle
) {
807 return EFI_UNSUPPORTED
;
810 // Check to see whether the handle has the ConsoleInDevice GUID on it
812 Status
= gBS
->OpenProtocol (
816 This
->DriverBindingHandle
,
818 EFI_OPEN_PROTOCOL_BY_DRIVER
821 if (EFI_ERROR (Status
)) {
828 This
->DriverBindingHandle
,
836 Test to see if Console In Device could be supported on the ControllerHandle.
838 @param This Protocol instance pointer.
839 @param ControllerHandle Handle of device to test.
840 @param RemainingDevicePath Optional parameter use to pick a specific child
843 @retval EFI_SUCCESS This driver supports this device.
844 @retval other This driver does not support this device.
849 ConSplitterConInDriverBindingSupported (
850 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
851 IN EFI_HANDLE ControllerHandle
,
852 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
855 return ConSplitterSupported (
858 &gEfiConsoleInDeviceGuid
863 Test to see if Simple Pointer protocol could be supported on the ControllerHandle.
865 @param This Protocol instance pointer.
866 @param ControllerHandle Handle of device to test.
867 @param RemainingDevicePath Optional parameter use to pick a specific child
870 @retval EFI_SUCCESS This driver supports this device.
871 @retval other This driver does not support this device.
876 ConSplitterSimplePointerDriverBindingSupported (
877 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
878 IN EFI_HANDLE ControllerHandle
,
879 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
882 return ConSplitterSupported (
885 &gEfiSimplePointerProtocolGuid
891 Test to see if Absolute Pointer protocol could be supported on the ControllerHandle.
893 @param This Protocol instance pointer.
894 @param ControllerHandle Handle of device to test.
895 @param RemainingDevicePath Optional parameter use to pick a specific child
898 @retval EFI_SUCCESS This driver supports this device.
899 @retval other This driver does not support this device.
904 ConSplitterAbsolutePointerDriverBindingSupported (
905 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
906 IN EFI_HANDLE ControllerHandle
,
907 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
910 return ConSplitterSupported (
913 &gEfiAbsolutePointerProtocolGuid
919 Test to see if Console Out Device could be supported on the ControllerHandle.
921 @param This Protocol instance pointer.
922 @param ControllerHandle Handle of device to test.
923 @param RemainingDevicePath Optional parameter use to pick a specific child
926 @retval EFI_SUCCESS This driver supports this device.
927 @retval other This driver does not support this device.
932 ConSplitterConOutDriverBindingSupported (
933 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
934 IN EFI_HANDLE ControllerHandle
,
935 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
938 return ConSplitterSupported (
941 &gEfiConsoleOutDeviceGuid
946 Test to see if Standard Error Device could be supported on the ControllerHandle.
948 @param This Protocol instance pointer.
949 @param ControllerHandle Handle of device to test.
950 @param RemainingDevicePath Optional parameter use to pick a specific child
953 @retval EFI_SUCCESS This driver supports this device.
954 @retval other This driver does not support this device.
959 ConSplitterStdErrDriverBindingSupported (
960 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
961 IN EFI_HANDLE ControllerHandle
,
962 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
965 return ConSplitterSupported (
968 &gEfiStandardErrorDeviceGuid
974 Start ConSplitter on devcie handle by opening Console Device Guid on device handle
975 and the console virtual handle. And Get the console interface on controller handle.
977 @param This Protocol instance pointer.
978 @param ControllerHandle Handle of device.
979 @param ConSplitterVirtualHandle Console virtual Handle.
980 @param DeviceGuid The specified Console Device, such as ConInDev,
982 @param InterfaceGuid The specified protocol to be opened.
983 @param Interface Protocol interface returned.
985 @retval EFI_SUCCESS This driver supports this device.
986 @retval other Failed to open the specified Console Device Guid
987 or specified protocol.
992 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
993 IN EFI_HANDLE ControllerHandle
,
994 IN EFI_HANDLE ConSplitterVirtualHandle
,
995 IN EFI_GUID
*DeviceGuid
,
996 IN EFI_GUID
*InterfaceGuid
,
1004 // Check to see whether the ControllerHandle has the InterfaceGuid on it.
1006 Status
= gBS
->OpenProtocol (
1010 This
->DriverBindingHandle
,
1012 EFI_OPEN_PROTOCOL_BY_DRIVER
1014 if (EFI_ERROR (Status
)) {
1018 Status
= gBS
->OpenProtocol (
1022 This
->DriverBindingHandle
,
1023 ConSplitterVirtualHandle
,
1024 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1026 if (EFI_ERROR (Status
)) {
1030 return gBS
->OpenProtocol (
1034 This
->DriverBindingHandle
,
1035 ConSplitterVirtualHandle
,
1036 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1042 Start Console In Consplitter on device handle.
1044 @param This Protocol instance pointer.
1045 @param ControllerHandle Handle of device to bind driver to.
1046 @param RemainingDevicePath Optional parameter use to pick a specific child
1049 @retval EFI_SUCCESS Console In Consplitter is added to ControllerHandle.
1050 @retval other Console In Consplitter does not support this device.
1055 ConSplitterConInDriverBindingStart (
1056 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1057 IN EFI_HANDLE ControllerHandle
,
1058 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1062 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
1063 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
;
1066 // Start ConSplitter on ControllerHandle, and create the virtual
1067 // agrogated console device on first call Start for a SimpleTextIn handle.
1069 Status
= ConSplitterStart (
1072 mConIn
.VirtualHandle
,
1073 &gEfiConsoleInDeviceGuid
,
1074 &gEfiSimpleTextInProtocolGuid
,
1077 if (EFI_ERROR (Status
)) {
1082 // Add this device into Text In devices list.
1084 Status
= ConSplitterTextInAddDevice (&mConIn
, TextIn
);
1085 if (EFI_ERROR (Status
)) {
1089 Status
= gBS
->OpenProtocol (
1091 &gEfiSimpleTextInputExProtocolGuid
,
1092 (VOID
**) &TextInEx
,
1093 This
->DriverBindingHandle
,
1094 mConIn
.VirtualHandle
,
1095 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1097 if (EFI_ERROR (Status
)) {
1102 // Add this device into Text In Ex devices list.
1104 Status
= ConSplitterTextInExAddDevice (&mConIn
, TextInEx
);
1111 Start Simple Pointer Consplitter on device handle.
1113 @param This Protocol instance pointer.
1114 @param ControllerHandle Handle of device to bind driver to.
1115 @param RemainingDevicePath Optional parameter use to pick a specific child
1118 @retval EFI_SUCCESS Simple Pointer Consplitter is added to ControllerHandle.
1119 @retval other Simple Pointer Consplitter does not support this device.
1124 ConSplitterSimplePointerDriverBindingStart (
1125 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1126 IN EFI_HANDLE ControllerHandle
,
1127 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1131 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
;
1134 // Start ConSplitter on ControllerHandle, and create the virtual
1135 // agrogated console device on first call Start for a SimplePointer handle.
1137 Status
= ConSplitterStart (
1140 mConIn
.VirtualHandle
,
1141 &gEfiSimplePointerProtocolGuid
,
1142 &gEfiSimplePointerProtocolGuid
,
1143 (VOID
**) &SimplePointer
1145 if (EFI_ERROR (Status
)) {
1150 // Add this devcie into Simple Pointer devices list.
1152 return ConSplitterSimplePointerAddDevice (&mConIn
, SimplePointer
);
1157 Start Absolute Pointer Consplitter on device handle.
1159 @param This Protocol instance pointer.
1160 @param ControllerHandle Handle of device to bind driver to.
1161 @param RemainingDevicePath Optional parameter use to pick a specific child
1164 @retval EFI_SUCCESS Absolute Pointer Consplitter is added to ControllerHandle.
1165 @retval other Absolute Pointer Consplitter does not support this device.
1170 ConSplitterAbsolutePointerDriverBindingStart (
1171 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1172 IN EFI_HANDLE ControllerHandle
,
1173 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1177 EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
;
1180 // Start ConSplitter on ControllerHandle, and create the virtual
1181 // agrogated console device on first call Start for a AbsolutePointer handle.
1183 Status
= ConSplitterStart (
1186 mConIn
.VirtualHandle
,
1187 &gEfiAbsolutePointerProtocolGuid
,
1188 &gEfiAbsolutePointerProtocolGuid
,
1189 (VOID
**) &AbsolutePointer
1192 if (EFI_ERROR (Status
)) {
1197 // Add this devcie into Absolute Pointer devices list.
1199 return ConSplitterAbsolutePointerAddDevice (&mConIn
, AbsolutePointer
);
1204 Start Console Out Consplitter on device handle.
1206 @param This Protocol instance pointer.
1207 @param ControllerHandle Handle of device to bind driver to.
1208 @param RemainingDevicePath Optional parameter use to pick a specific child
1211 @retval EFI_SUCCESS Console Out Consplitter is added to ControllerHandle.
1212 @retval other Console Out Consplitter does not support this device.
1217 ConSplitterConOutDriverBindingStart (
1218 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1219 IN EFI_HANDLE ControllerHandle
,
1220 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1224 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1225 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1226 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1229 // Start ConSplitter on ControllerHandle, and create the virtual
1230 // agrogated console device on first call Start for a ConsoleOut handle.
1232 Status
= ConSplitterStart (
1235 mConOut
.VirtualHandle
,
1236 &gEfiConsoleOutDeviceGuid
,
1237 &gEfiSimpleTextOutProtocolGuid
,
1240 if (EFI_ERROR (Status
)) {
1244 GraphicsOutput
= NULL
;
1247 // Try to Open Graphics Output protocol
1249 Status
= gBS
->OpenProtocol (
1251 &gEfiGraphicsOutputProtocolGuid
,
1252 (VOID
**) &GraphicsOutput
,
1253 This
->DriverBindingHandle
,
1254 mConOut
.VirtualHandle
,
1255 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1258 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
1260 // Open UGA DRAW protocol
1262 Status
= gBS
->OpenProtocol (
1264 &gEfiUgaDrawProtocolGuid
,
1266 This
->DriverBindingHandle
,
1267 mConOut
.VirtualHandle
,
1268 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1273 // When new console device is added, the new mode will be set later,
1274 // so put current mode back to init state.
1276 mConOut
.TextOutMode
.Mode
= 0xFF;
1279 // If both ConOut and StdErr incorporate the same Text Out device,
1280 // their MaxMode and QueryData should be the intersection of both.
1282 Status
= ConSplitterTextOutAddDevice (&mConOut
, TextOut
, GraphicsOutput
, UgaDraw
);
1283 ConSplitterTextOutSetAttribute (&mConOut
.TextOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
1285 if (FeaturePcdGet (PcdConOutUgaSupport
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
1287 // Match the UGA mode data of ConOut with the current mode
1289 if (UgaDraw
!= NULL
) {
1292 &mConOut
.UgaHorizontalResolution
,
1293 &mConOut
.UgaVerticalResolution
,
1294 &mConOut
.UgaColorDepth
,
1295 &mConOut
.UgaRefreshRate
1304 Start Standard Error Consplitter on device handle.
1306 @param This Protocol instance pointer.
1307 @param ControllerHandle Handle of device to bind driver to.
1308 @param RemainingDevicePath Optional parameter use to pick a specific child
1311 @retval EFI_SUCCESS Standard Error Consplitter is added to ControllerHandle.
1312 @retval other Standard Error Consplitter does not support this device.
1317 ConSplitterStdErrDriverBindingStart (
1318 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1319 IN EFI_HANDLE ControllerHandle
,
1320 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1324 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1327 // Start ConSplitter on ControllerHandle, and create the virtual
1328 // agrogated console device on first call Start for a StandardError handle.
1330 Status
= ConSplitterStart (
1333 mStdErr
.VirtualHandle
,
1334 &gEfiStandardErrorDeviceGuid
,
1335 &gEfiSimpleTextOutProtocolGuid
,
1338 if (EFI_ERROR (Status
)) {
1343 // When new console device is added, the new mode will be set later,
1344 // so put current mode back to init state.
1346 mStdErr
.TextOutMode
.Mode
= 0xFF;
1349 // If both ConOut and StdErr incorporate the same Text Out device,
1350 // their MaxMode and QueryData should be the intersection of both.
1352 Status
= ConSplitterTextOutAddDevice (&mStdErr
, TextOut
, NULL
, NULL
);
1353 ConSplitterTextOutSetAttribute (&mStdErr
.TextOut
, EFI_TEXT_ATTR (EFI_MAGENTA
, EFI_BLACK
));
1354 if (EFI_ERROR (Status
)) {
1358 if (mStdErr
.CurrentNumberOfConsoles
== 1) {
1359 gST
->StandardErrorHandle
= mStdErr
.VirtualHandle
;
1360 gST
->StdErr
= &mStdErr
.TextOut
;
1362 // Update the CRC32 in the EFI System Table header
1365 gBS
->CalculateCrc32 (
1366 (UINT8
*) &gST
->Hdr
,
1367 gST
->Hdr
.HeaderSize
,
1377 Stop ConSplitter on device handle by closing Console Device Guid on device handle
1378 and the console virtual handle.
1380 @param This Protocol instance pointer.
1381 @param ControllerHandle Handle of device.
1382 @param ConSplitterVirtualHandle Console virtual Handle.
1383 @param DeviceGuid The specified Console Device, such as ConInDev,
1385 @param InterfaceGuid The specified protocol to be opened.
1386 @param Interface Protocol interface returned.
1388 @retval EFI_SUCCESS Stop ConSplitter on ControllerHandle successfully.
1389 @retval other Failed to Stop ConSplitter on ControllerHandle.
1394 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1395 IN EFI_HANDLE ControllerHandle
,
1396 IN EFI_HANDLE ConSplitterVirtualHandle
,
1397 IN EFI_GUID
*DeviceGuid
,
1398 IN EFI_GUID
*InterfaceGuid
,
1404 Status
= gBS
->OpenProtocol (
1408 This
->DriverBindingHandle
,
1410 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1412 if (EFI_ERROR (Status
)) {
1416 // close the protocol refered.
1418 gBS
->CloseProtocol (
1421 This
->DriverBindingHandle
,
1422 ConSplitterVirtualHandle
1425 gBS
->CloseProtocol (
1428 This
->DriverBindingHandle
,
1437 Stop Console In ConSplitter on ControllerHandle by closing Console In Devcice GUID.
1439 @param This Protocol instance pointer.
1440 @param ControllerHandle Handle of device to stop driver on
1441 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1442 children is zero stop the entire bus driver.
1443 @param ChildHandleBuffer List of Child Handles to Stop.
1445 @retval EFI_SUCCESS This driver is removed ControllerHandle
1446 @retval other This driver was not removed from this device
1451 ConSplitterConInDriverBindingStop (
1452 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1453 IN EFI_HANDLE ControllerHandle
,
1454 IN UINTN NumberOfChildren
,
1455 IN EFI_HANDLE
*ChildHandleBuffer
1459 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
1461 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
;
1462 if (NumberOfChildren
== 0) {
1466 Status
= gBS
->OpenProtocol (
1468 &gEfiSimpleTextInputExProtocolGuid
,
1469 (VOID
**) &TextInEx
,
1470 This
->DriverBindingHandle
,
1472 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1474 if (EFI_ERROR (Status
)) {
1479 // Remove device from Text Input Ex devices list.
1481 Status
= ConSplitterTextInExDeleteDevice (&mConIn
, TextInEx
);
1482 if (EFI_ERROR (Status
)) {
1488 // Close Simple Text In protocol on controller handle and virtual handle.
1490 Status
= ConSplitterStop (
1493 mConIn
.VirtualHandle
,
1494 &gEfiConsoleInDeviceGuid
,
1495 &gEfiSimpleTextInProtocolGuid
,
1498 if (EFI_ERROR (Status
)) {
1503 // Remove device from Text Input devices list.
1505 return ConSplitterTextInDeleteDevice (&mConIn
, TextIn
);
1510 Stop Simple Pointer protocol ConSplitter on ControllerHandle by closing
1511 Simple Pointer protocol.
1513 @param This Protocol instance pointer.
1514 @param ControllerHandle Handle of device to stop driver on
1515 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1516 children is zero stop the entire bus driver.
1517 @param ChildHandleBuffer List of Child Handles to Stop.
1519 @retval EFI_SUCCESS This driver is removed ControllerHandle
1520 @retval other This driver was not removed from this device
1525 ConSplitterSimplePointerDriverBindingStop (
1526 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1527 IN EFI_HANDLE ControllerHandle
,
1528 IN UINTN NumberOfChildren
,
1529 IN EFI_HANDLE
*ChildHandleBuffer
1533 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
;
1535 if (NumberOfChildren
== 0) {
1540 // Close Simple Pointer protocol on controller handle and virtual handle.
1542 Status
= ConSplitterStop (
1545 mConIn
.VirtualHandle
,
1546 &gEfiSimplePointerProtocolGuid
,
1547 &gEfiSimplePointerProtocolGuid
,
1548 (VOID
**) &SimplePointer
1550 if (EFI_ERROR (Status
)) {
1555 // Remove this device from Simple Pointer device list.
1557 return ConSplitterSimplePointerDeleteDevice (&mConIn
, SimplePointer
);
1562 Stop Absolute Pointer protocol ConSplitter on ControllerHandle by closing
1563 Absolute Pointer protocol.
1565 @param This Protocol instance pointer.
1566 @param ControllerHandle Handle of device to stop driver on
1567 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1568 children is zero stop the entire bus driver.
1569 @param ChildHandleBuffer List of Child Handles to Stop.
1571 @retval EFI_SUCCESS This driver is removed ControllerHandle
1572 @retval other This driver was not removed from this device
1577 ConSplitterAbsolutePointerDriverBindingStop (
1578 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1579 IN EFI_HANDLE ControllerHandle
,
1580 IN UINTN NumberOfChildren
,
1581 IN EFI_HANDLE
*ChildHandleBuffer
1585 EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
;
1587 if (NumberOfChildren
== 0) {
1592 // Close Absolute Pointer protocol on controller handle and virtual handle.
1594 Status
= ConSplitterStop (
1597 mConIn
.VirtualHandle
,
1598 &gEfiAbsolutePointerProtocolGuid
,
1599 &gEfiAbsolutePointerProtocolGuid
,
1600 (VOID
**) &AbsolutePointer
1602 if (EFI_ERROR (Status
)) {
1607 // Remove this device from Absolute Pointer device list.
1609 return ConSplitterAbsolutePointerDeleteDevice (&mConIn
, AbsolutePointer
);
1614 Stop Console Out ConSplitter on device handle by closing Console Out Devcice GUID.
1616 @param This Protocol instance pointer.
1617 @param ControllerHandle Handle of device to stop driver on
1618 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1619 children is zero stop the entire bus driver.
1620 @param ChildHandleBuffer List of Child Handles to Stop.
1622 @retval EFI_SUCCESS This driver is removed ControllerHandle
1623 @retval other This driver was not removed from this device
1628 ConSplitterConOutDriverBindingStop (
1629 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1630 IN EFI_HANDLE ControllerHandle
,
1631 IN UINTN NumberOfChildren
,
1632 IN EFI_HANDLE
*ChildHandleBuffer
1636 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1638 if (NumberOfChildren
== 0) {
1643 // Close Absolute Pointer protocol on controller handle and virtual handle.
1645 Status
= ConSplitterStop (
1648 mConOut
.VirtualHandle
,
1649 &gEfiConsoleOutDeviceGuid
,
1650 &gEfiSimpleTextOutProtocolGuid
,
1653 if (EFI_ERROR (Status
)) {
1658 // Remove this device from Text Out device list.
1660 return ConSplitterTextOutDeleteDevice (&mConOut
, TextOut
);
1665 Stop Standard Error ConSplitter on ControllerHandle by closing Standard Error GUID.
1667 @param This Protocol instance pointer.
1668 @param ControllerHandle Handle of device to stop driver on
1669 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1670 children is zero stop the entire bus driver.
1671 @param ChildHandleBuffer List of Child Handles to Stop.
1673 @retval EFI_SUCCESS This driver is removed ControllerHandle
1674 @retval other This driver was not removed from this device
1679 ConSplitterStdErrDriverBindingStop (
1680 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1681 IN EFI_HANDLE ControllerHandle
,
1682 IN UINTN NumberOfChildren
,
1683 IN EFI_HANDLE
*ChildHandleBuffer
1687 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1689 if (NumberOfChildren
== 0) {
1694 // Close Standard Error Device on controller handle and virtual handle.
1696 Status
= ConSplitterStop (
1699 mStdErr
.VirtualHandle
,
1700 &gEfiStandardErrorDeviceGuid
,
1701 &gEfiSimpleTextOutProtocolGuid
,
1704 if (EFI_ERROR (Status
)) {
1708 // Delete this console error out device's data structures.
1710 Status
= ConSplitterTextOutDeleteDevice (&mStdErr
, TextOut
);
1711 if (EFI_ERROR (Status
)) {
1715 if (mStdErr
.CurrentNumberOfConsoles
== 0) {
1716 gST
->StandardErrorHandle
= NULL
;
1719 // Update the CRC32 in the EFI System Table header
1722 gBS
->CalculateCrc32 (
1723 (UINT8
*) &gST
->Hdr
,
1724 gST
->Hdr
.HeaderSize
,
1734 Take the passed in Buffer of size SizeOfCount and grow the buffer
1735 by MAX (CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT, MaxGrow) * SizeOfCount
1736 bytes. Copy the current data in Buffer to the new version of Buffer
1737 and free the old version of buffer.
1739 @param SizeOfCount Size of element in array
1740 @param Count Current number of elements in array
1741 @param Buffer Bigger version of passed in Buffer with all the
1744 @retval EFI_SUCCESS Buffer size has grown
1745 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1749 ConSplitterGrowBuffer (
1750 IN UINTN SizeOfCount
,
1752 IN OUT VOID
**Buffer
1760 // grow the buffer to new buffer size,
1761 // copy the old buffer's content to the new-size buffer,
1762 // then free the old buffer.
1764 OldSize
= *Count
* SizeOfCount
;
1765 *Count
+= CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT
;
1766 NewSize
= *Count
* SizeOfCount
;
1768 Ptr
= AllocateZeroPool (NewSize
);
1770 return EFI_OUT_OF_RESOURCES
;
1773 CopyMem (Ptr
, *Buffer
, OldSize
);
1775 if (*Buffer
!= NULL
) {
1786 Add Text Input Device in Consplitter Text Input list.
1788 @param Private Text In Splitter pointer.
1789 @param TextIn Simple Text Input protocol pointer.
1791 @retval EFI_SUCCESS Text Input Device added successfully.
1792 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1796 ConSplitterTextInAddDevice (
1797 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1798 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1804 // If the Text In List is full, enlarge it by calling growbuffer().
1806 if (Private
->CurrentNumberOfConsoles
>= Private
->TextInListCount
) {
1807 Status
= ConSplitterGrowBuffer (
1808 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
1809 &Private
->TextInListCount
,
1810 (VOID
**) &Private
->TextInList
1812 if (EFI_ERROR (Status
)) {
1813 return EFI_OUT_OF_RESOURCES
;
1817 // Add the new text-in device data structure into the Text In List.
1819 Private
->TextInList
[Private
->CurrentNumberOfConsoles
] = TextIn
;
1820 Private
->CurrentNumberOfConsoles
++;
1823 // Extra CheckEvent added to reduce the double CheckEvent() in UI.c
1825 gBS
->CheckEvent (TextIn
->WaitForKey
);
1832 Remove Simple Text Device in Consplitter Absolute Pointer list.
1834 @param Private Text In Splitter pointer.
1835 @param TextIn Simple Text protocol pointer.
1837 @retval EFI_SUCCESS Simple Text Device removed successfully.
1838 @retval EFI_NOT_FOUND No Simple Text Device found.
1842 ConSplitterTextInDeleteDevice (
1843 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1844 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1849 // Remove the specified text-in device data structure from the Text In List,
1850 // and rearrange the remaining data structures in the Text In List.
1852 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
1853 if (Private
->TextInList
[Index
] == TextIn
) {
1854 for (Index
= Index
; Index
< Private
->CurrentNumberOfConsoles
- 1; Index
++) {
1855 Private
->TextInList
[Index
] = Private
->TextInList
[Index
+ 1];
1858 Private
->CurrentNumberOfConsoles
--;
1863 return EFI_NOT_FOUND
;
1867 Add Text Input Ex Device in Consplitter Text Input Ex list.
1869 @param Private Text In Splitter pointer.
1870 @param TextInEx Simple Text Ex Input protocol pointer.
1872 @retval EFI_SUCCESS Text Input Ex Device added successfully.
1873 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1877 ConSplitterTextInExAddDevice (
1878 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1879 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1885 // If the TextInEx List is full, enlarge it by calling growbuffer().
1887 if (Private
->CurrentNumberOfExConsoles
>= Private
->TextInExListCount
) {
1888 Status
= ConSplitterGrowBuffer (
1889 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
1890 &Private
->TextInExListCount
,
1891 (VOID
**) &Private
->TextInExList
1893 if (EFI_ERROR (Status
)) {
1894 return EFI_OUT_OF_RESOURCES
;
1898 // Add the new text-in device data structure into the Text In List.
1900 Private
->TextInExList
[Private
->CurrentNumberOfExConsoles
] = TextInEx
;
1901 Private
->CurrentNumberOfExConsoles
++;
1904 // Extra CheckEvent added to reduce the double CheckEvent() in UI.c
1906 gBS
->CheckEvent (TextInEx
->WaitForKeyEx
);
1912 Remove Simple Text Ex Device in Consplitter Absolute Pointer list.
1914 @param Private Text In Splitter pointer.
1915 @param TextInEx Simple Text Ex protocol pointer.
1917 @retval EFI_SUCCESS Simple Text Ex Device removed successfully.
1918 @retval EFI_NOT_FOUND No Simple Text Ex Device found.
1922 ConSplitterTextInExDeleteDevice (
1923 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1924 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1929 // Remove the specified text-in device data structure from the Text In List,
1930 // and rearrange the remaining data structures in the Text In List.
1932 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
1933 if (Private
->TextInExList
[Index
] == TextInEx
) {
1934 for (Index
= Index
; Index
< Private
->CurrentNumberOfExConsoles
- 1; Index
++) {
1935 Private
->TextInExList
[Index
] = Private
->TextInExList
[Index
+ 1];
1938 Private
->CurrentNumberOfExConsoles
--;
1943 return EFI_NOT_FOUND
;
1948 Add Simple Pointer Device in Consplitter Simple Pointer list.
1950 @param Private Text In Splitter pointer.
1951 @param SimplePointer Simple Pointer protocol pointer.
1953 @retval EFI_SUCCESS Simple Pointer Device added successfully.
1954 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1958 ConSplitterSimplePointerAddDevice (
1959 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1960 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
1966 // If the Text In List is full, enlarge it by calling growbuffer().
1968 if (Private
->CurrentNumberOfPointers
>= Private
->PointerListCount
) {
1969 Status
= ConSplitterGrowBuffer (
1970 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
1971 &Private
->PointerListCount
,
1972 (VOID
**) &Private
->PointerList
1974 if (EFI_ERROR (Status
)) {
1975 return EFI_OUT_OF_RESOURCES
;
1979 // Add the new text-in device data structure into the Text In List.
1981 Private
->PointerList
[Private
->CurrentNumberOfPointers
] = SimplePointer
;
1982 Private
->CurrentNumberOfPointers
++;
1988 Remove Simple Pointer Device in Consplitter Absolute Pointer list.
1990 @param Private Text In Splitter pointer.
1991 @param SimplePointer Simple Pointer protocol pointer.
1993 @retval EFI_SUCCESS Simple Pointer Device removed successfully.
1994 @retval EFI_NOT_FOUND No Simple Pointer Device found.
1998 ConSplitterSimplePointerDeleteDevice (
1999 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2000 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
2005 // Remove the specified text-in device data structure from the Text In List,
2006 // and rearrange the remaining data structures in the Text In List.
2008 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
2009 if (Private
->PointerList
[Index
] == SimplePointer
) {
2010 for (Index
= Index
; Index
< Private
->CurrentNumberOfPointers
- 1; Index
++) {
2011 Private
->PointerList
[Index
] = Private
->PointerList
[Index
+ 1];
2014 Private
->CurrentNumberOfPointers
--;
2019 return EFI_NOT_FOUND
;
2024 Add Absolute Pointer Device in Consplitter Absolute Pointer list.
2026 @param Private Text In Splitter pointer.
2027 @param AbsolutePointer Absolute Pointer protocol pointer.
2029 @retval EFI_SUCCESS Absolute Pointer Device added successfully.
2030 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2034 ConSplitterAbsolutePointerAddDevice (
2035 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2036 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2042 // If the Absolute Pointer List is full, enlarge it by calling growbuffer().
2044 if (Private
->CurrentNumberOfAbsolutePointers
>= Private
->AbsolutePointerListCount
) {
2045 Status
= ConSplitterGrowBuffer (
2046 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
2047 &Private
->AbsolutePointerListCount
,
2048 (VOID
**) &Private
->AbsolutePointerList
2050 if (EFI_ERROR (Status
)) {
2051 return EFI_OUT_OF_RESOURCES
;
2055 // Add the new text-in device data structure into the Text In List.
2057 Private
->AbsolutePointerList
[Private
->CurrentNumberOfAbsolutePointers
] = AbsolutePointer
;
2058 Private
->CurrentNumberOfAbsolutePointers
++;
2064 Remove Absolute Pointer Device in Consplitter Absolute Pointer list.
2066 @param Private Text In Splitter pointer.
2067 @param AbsolutePointer Absolute Pointer protocol pointer.
2069 @retval EFI_SUCCESS Absolute Pointer Device removed successfully.
2070 @retval EFI_NOT_FOUND No Absolute Pointer Device found.
2074 ConSplitterAbsolutePointerDeleteDevice (
2075 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2076 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2081 // Remove the specified text-in device data structure from the Text In List,
2082 // and rearrange the remaining data structures in the Text In List.
2084 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
2085 if (Private
->AbsolutePointerList
[Index
] == AbsolutePointer
) {
2086 for (Index
= Index
; Index
< Private
->CurrentNumberOfAbsolutePointers
- 1; Index
++) {
2087 Private
->AbsolutePointerList
[Index
] = Private
->AbsolutePointerList
[Index
+ 1];
2090 Private
->CurrentNumberOfAbsolutePointers
--;
2095 return EFI_NOT_FOUND
;
2099 Reallocate Text Out mode map.
2101 @param Private Consplitter Text Out pointer.
2103 @retval EFI_SUCCESS Buffer size has grown
2104 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2108 ConSplitterGrowMapTable (
2109 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2115 INT32
*TextOutModeMap
;
2116 INT32
*OldTextOutModeMap
;
2120 NewSize
= Private
->TextOutListCount
* sizeof (INT32
);
2121 OldTextOutModeMap
= Private
->TextOutModeMap
;
2122 TotalSize
= NewSize
* Private
->TextOutQueryDataCount
;
2124 TextOutModeMap
= AllocateZeroPool (TotalSize
);
2125 if (TextOutModeMap
== NULL
) {
2126 return EFI_OUT_OF_RESOURCES
;
2129 SetMem (TextOutModeMap
, TotalSize
, 0xFF);
2130 Private
->TextOutModeMap
= TextOutModeMap
;
2133 // If TextOutList has been enlarged, need to realloc the mode map table
2134 // The mode map table is regarded as a two dimension array.
2137 // 0 ---------> TextOutListCount ----> TextOutListCount
2138 // | -------------------------------------------
2145 // -------------------------------------------
2148 if (OldTextOutModeMap
!= NULL
) {
2150 Size
= Private
->CurrentNumberOfConsoles
* sizeof (INT32
);
2152 SrcAddress
= OldTextOutModeMap
;
2155 // Copy the old data to the new one
2157 while (Index
< Private
->TextOutMode
.MaxMode
) {
2158 CopyMem (TextOutModeMap
, SrcAddress
, Size
);
2159 TextOutModeMap
+= NewSize
;
2164 // Free the old buffer
2166 FreePool (OldTextOutModeMap
);
2174 Add the device's output mode to console splitter's mode list.
2176 @param Private Text Out Splitter pointer
2177 @param TextOut Simple Text Output protocol pointer.
2179 @retval EFI_SUCCESS Device added successfully.
2180 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2184 ConSplitterAddOutputMode (
2185 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2186 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2194 MaxMode
= TextOut
->Mode
->MaxMode
;
2195 Private
->TextOutMode
.MaxMode
= MaxMode
;
2198 // Grow the buffer if query data buffer is not large enough to
2199 // hold all the mode supported by the first console.
2201 while (MaxMode
> (INT32
) Private
->TextOutQueryDataCount
) {
2202 Status
= ConSplitterGrowBuffer (
2203 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
2204 &Private
->TextOutQueryDataCount
,
2205 (VOID
**) &Private
->TextOutQueryData
2207 if (EFI_ERROR (Status
)) {
2208 return EFI_OUT_OF_RESOURCES
;
2212 // Allocate buffer for the output mode map
2214 Status
= ConSplitterGrowMapTable (Private
);
2215 if (EFI_ERROR (Status
)) {
2216 return EFI_OUT_OF_RESOURCES
;
2219 // As the first textout device, directly add the mode in to QueryData
2220 // and at the same time record the mapping between QueryData and TextOut.
2224 while (Mode
< MaxMode
) {
2225 Status
= TextOut
->QueryMode (
2228 &Private
->TextOutQueryData
[Mode
].Columns
,
2229 &Private
->TextOutQueryData
[Mode
].Rows
2232 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData
2235 if ((EFI_ERROR(Status
)) && (Mode
== 1)) {
2236 Private
->TextOutQueryData
[Mode
].Columns
= 0;
2237 Private
->TextOutQueryData
[Mode
].Rows
= 0;
2239 Private
->TextOutModeMap
[Index
] = Mode
;
2241 Index
+= Private
->TextOutListCount
;
2248 Reconstruct TextOutModeMap to get intersection of modes
2250 This routine reconstruct TextOutModeMap to get the intersection
2251 of modes for all console out devices. Because EFI/UEFI spec require
2252 mode 0 is 80x25, mode 1 is 80x50, this routine will not check the
2253 intersection for mode 0 and mode 1.
2255 @param TextOutModeMap Current text out mode map, begin with the mode 80x25
2256 @param NewlyAddedMap New text out mode map, begin with the mode 80x25
2257 @param MapStepSize Mode step size for one console device
2258 @param NewMapStepSize Mode step size for one console device
2259 @param MaxMode Current max text mode
2260 @param CurrentMode Current text mode
2266 ConSplitterGetIntersection (
2267 IN INT32
*TextOutModeMap
,
2268 IN INT32
*NewlyAddedMap
,
2269 IN UINTN MapStepSize
,
2270 IN UINTN NewMapStepSize
,
2272 OUT INT32
*CurrentMode
2276 INT32
*CurrentMapEntry
;
2277 INT32
*NextMapEntry
;
2278 INT32 CurrentMaxMode
;
2282 // According to EFI/UEFI spec, mode 0 and mode 1 have been reserved
2283 // for 80x25 and 80x50 in Simple Text Out protocol, so don't make intersection
2284 // for mode 0 and mode 1, mode number starts from 2.
2287 CurrentMapEntry
= &TextOutModeMap
[MapStepSize
* 2];
2288 NextMapEntry
= &TextOutModeMap
[MapStepSize
* 2];
2289 NewlyAddedMap
= &NewlyAddedMap
[NewMapStepSize
* 2];
2291 CurrentMaxMode
= *MaxMode
;
2292 Mode
= *CurrentMode
;
2294 while (Index
< CurrentMaxMode
) {
2295 if (*NewlyAddedMap
== -1) {
2297 // This mode is not supported any more. Remove it. Special care
2298 // must be taken as this remove will also affect current mode;
2300 if (Index
== *CurrentMode
) {
2302 } else if (Index
< *CurrentMode
) {
2307 if (CurrentMapEntry
!= NextMapEntry
) {
2308 CopyMem (NextMapEntry
, CurrentMapEntry
, MapStepSize
* sizeof (INT32
));
2311 NextMapEntry
+= MapStepSize
;
2314 CurrentMapEntry
+= MapStepSize
;
2315 NewlyAddedMap
+= NewMapStepSize
;
2319 *CurrentMode
= Mode
;
2326 Add the device's output mode to console splitter's mode list.
2328 @param Private Text Out Splitter pointer.
2329 @param TextOut Simple Text Output protocol pointer.
2335 ConSplitterSyncOutputMode (
2336 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2337 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2340 INT32 CurrentMaxMode
;
2343 INT32
*TextOutModeMap
;
2346 TEXT_OUT_SPLITTER_QUERY_DATA
*TextOutQueryData
;
2353 // Must make sure that current mode won't change even if mode number changes
2355 CurrentMaxMode
= Private
->TextOutMode
.MaxMode
;
2356 TextOutModeMap
= Private
->TextOutModeMap
;
2357 StepSize
= Private
->TextOutListCount
;
2358 TextOutQueryData
= Private
->TextOutQueryData
;
2361 // Query all the mode that the newly added TextOut supports
2364 MapTable
= TextOutModeMap
+ Private
->CurrentNumberOfConsoles
;
2365 while (Mode
< TextOut
->Mode
->MaxMode
) {
2366 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Columns
, &Rows
);
2367 if (EFI_ERROR(Status
)) {
2369 MapTable
[StepSize
] = Mode
;
2370 TextOutQueryData
[Mode
].Columns
= 0;
2371 TextOutQueryData
[Mode
].Rows
= 0;
2377 // Search the intersection map and QueryData database to see if they intersects
2380 while (Index
< CurrentMaxMode
) {
2381 QueryMode
= *(TextOutModeMap
+ Index
* StepSize
);
2382 if ((TextOutQueryData
[QueryMode
].Rows
== Rows
) && (TextOutQueryData
[QueryMode
].Columns
== Columns
)) {
2383 MapTable
[Index
* StepSize
] = Mode
;
2393 // Now search the TextOutModeMap table to find the intersection of supported
2394 // mode between ConSplitter and the newly added device.
2396 ConSplitterGetIntersection (
2401 &Private
->TextOutMode
.MaxMode
,
2402 &Private
->TextOutMode
.Mode
2410 Sync output device between ConOut and StdErr output.
2412 @retval EFI_SUCCESS Sync implemented successfully.
2413 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2417 ConSplitterGetIntersectionBetweenConOutAndStrErr (
2421 UINTN ConOutNumOfConsoles
;
2422 UINTN StdErrNumOfConsoles
;
2423 TEXT_OUT_AND_GOP_DATA
*ConOutTextOutList
;
2424 TEXT_OUT_AND_GOP_DATA
*StdErrTextOutList
;
2428 UINTN ConOutColumns
;
2430 UINTN StdErrColumns
;
2431 INT32 ConOutMaxMode
;
2432 INT32 StdErrMaxMode
;
2437 INT32
*ConOutModeMap
;
2438 INT32
*StdErrModeMap
;
2439 INT32
*ConOutMapTable
;
2440 INT32
*StdErrMapTable
;
2441 TEXT_OUT_SPLITTER_QUERY_DATA
*ConOutQueryData
;
2442 TEXT_OUT_SPLITTER_QUERY_DATA
*StdErrQueryData
;
2443 UINTN ConOutStepSize
;
2444 UINTN StdErrStepSize
;
2445 BOOLEAN FoundTheSameTextOut
;
2446 UINTN ConOutMapTableSize
;
2447 UINTN StdErrMapTableSize
;
2449 ConOutNumOfConsoles
= mConOut
.CurrentNumberOfConsoles
;
2450 StdErrNumOfConsoles
= mStdErr
.CurrentNumberOfConsoles
;
2451 ConOutTextOutList
= mConOut
.TextOutList
;
2452 StdErrTextOutList
= mStdErr
.TextOutList
;
2455 FoundTheSameTextOut
= FALSE
;
2456 while ((Indexi
< ConOutNumOfConsoles
) && (!FoundTheSameTextOut
)) {
2458 while (Indexj
< StdErrNumOfConsoles
) {
2459 if (ConOutTextOutList
->TextOut
== StdErrTextOutList
->TextOut
) {
2460 FoundTheSameTextOut
= TRUE
;
2465 StdErrTextOutList
++;
2469 ConOutTextOutList
++;
2472 if (!FoundTheSameTextOut
) {
2476 // Must make sure that current mode won't change even if mode number changes
2478 ConOutMaxMode
= mConOut
.TextOutMode
.MaxMode
;
2479 ConOutModeMap
= mConOut
.TextOutModeMap
;
2480 ConOutStepSize
= mConOut
.TextOutListCount
;
2481 ConOutQueryData
= mConOut
.TextOutQueryData
;
2483 StdErrMaxMode
= mStdErr
.TextOutMode
.MaxMode
;
2484 StdErrModeMap
= mStdErr
.TextOutModeMap
;
2485 StdErrStepSize
= mStdErr
.TextOutListCount
;
2486 StdErrQueryData
= mStdErr
.TextOutQueryData
;
2489 // Allocate the map table and set the map table's index to -1.
2491 ConOutMapTableSize
= ConOutMaxMode
* sizeof (INT32
);
2492 ConOutMapTable
= AllocateZeroPool (ConOutMapTableSize
);
2493 if (ConOutMapTable
== NULL
) {
2494 return EFI_OUT_OF_RESOURCES
;
2497 SetMem (ConOutMapTable
, ConOutMapTableSize
, 0xFF);
2499 StdErrMapTableSize
= StdErrMaxMode
* sizeof (INT32
);
2500 StdErrMapTable
= AllocateZeroPool (StdErrMapTableSize
);
2501 if (StdErrMapTable
== NULL
) {
2502 return EFI_OUT_OF_RESOURCES
;
2505 SetMem (StdErrMapTable
, StdErrMapTableSize
, 0xFF);
2508 // Find the intersection of the two set of modes. If they actually intersect, the
2509 // correponding entry in the map table is set to 1.
2512 while (Mode
< ConOutMaxMode
) {
2514 // Search the intersection map and QueryData database to see if they intersect
2517 ConOutMode
= *(ConOutModeMap
+ Mode
* ConOutStepSize
);
2518 ConOutRows
= ConOutQueryData
[ConOutMode
].Rows
;
2519 ConOutColumns
= ConOutQueryData
[ConOutMode
].Columns
;
2520 while (Index
< StdErrMaxMode
) {
2521 StdErrMode
= *(StdErrModeMap
+ Index
* StdErrStepSize
);
2522 StdErrRows
= StdErrQueryData
[StdErrMode
].Rows
;
2523 StdErrColumns
= StdErrQueryData
[StdErrMode
].Columns
;
2524 if ((StdErrRows
== ConOutRows
) && (StdErrColumns
== ConOutColumns
)) {
2525 ConOutMapTable
[Mode
] = 1;
2526 StdErrMapTable
[Index
] = 1;
2536 // Now search the TextOutModeMap table to find the intersection of supported
2537 // mode between ConSplitter and the newly added device.
2539 ConSplitterGetIntersection (
2542 mConOut
.TextOutListCount
,
2544 &(mConOut
.TextOutMode
.MaxMode
),
2545 &(mConOut
.TextOutMode
.Mode
)
2547 if (mConOut
.TextOutMode
.Mode
< 0) {
2548 mConOut
.TextOut
.SetMode (&(mConOut
.TextOut
), 0);
2551 ConSplitterGetIntersection (
2554 mStdErr
.TextOutListCount
,
2556 &(mStdErr
.TextOutMode
.MaxMode
),
2557 &(mStdErr
.TextOutMode
.Mode
)
2559 if (mStdErr
.TextOutMode
.Mode
< 0) {
2560 mStdErr
.TextOut
.SetMode (&(mStdErr
.TextOut
), 0);
2563 FreePool (ConOutMapTable
);
2564 FreePool (StdErrMapTable
);
2571 Add GOP or UGA output mode into Consplitter Text Out list.
2573 @param Private Text Out Splitter pointer.
2574 @param GraphicsOutput Graphics Output protocol pointer.
2575 @param UgaDraw UGA Draw protocol pointer.
2577 @retval EFI_SUCCESS Output mode added successfully.
2578 @retval other Failed to add output mode.
2582 ConSplitterAddGraphicsOutputMode (
2583 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2584 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2585 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2591 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
;
2593 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
2594 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*CurrentGraphicsOutputMode
;
2595 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*ModeBuffer
;
2596 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*MatchedMode
;
2599 BOOLEAN AlreadyExist
;
2600 UINT32 UgaHorizontalResolution
;
2601 UINT32 UgaVerticalResolution
;
2602 UINT32 UgaColorDepth
;
2603 UINT32 UgaRefreshRate
;
2605 if ((GraphicsOutput
== NULL
) && (UgaDraw
== NULL
)) {
2606 return EFI_UNSUPPORTED
;
2609 CurrentGraphicsOutputMode
= Private
->GraphicsOutput
.Mode
;
2614 if (Private
->CurrentNumberOfUgaDraw
!= 0) {
2616 // If any UGA device has already been added, then there is no need to
2617 // calculate intersection of display mode of different GOP/UGA device,
2618 // since only one display mode will be exported (i.e. user-defined mode)
2623 if (GraphicsOutput
!= NULL
) {
2624 if (Private
->CurrentNumberOfGraphicsOutput
== 0) {
2626 // This is the first Graphics Output device added
2628 CurrentGraphicsOutputMode
->MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
2629 CurrentGraphicsOutputMode
->Mode
= GraphicsOutput
->Mode
->Mode
;
2630 CopyMem (CurrentGraphicsOutputMode
->Info
, GraphicsOutput
->Mode
->Info
, GraphicsOutput
->Mode
->SizeOfInfo
);
2631 CurrentGraphicsOutputMode
->SizeOfInfo
= GraphicsOutput
->Mode
->SizeOfInfo
;
2632 CurrentGraphicsOutputMode
->FrameBufferBase
= GraphicsOutput
->Mode
->FrameBufferBase
;
2633 CurrentGraphicsOutputMode
->FrameBufferSize
= GraphicsOutput
->Mode
->FrameBufferSize
;
2636 // Allocate resource for the private mode buffer
2638 ModeBuffer
= AllocatePool (GraphicsOutput
->Mode
->SizeOfInfo
* GraphicsOutput
->Mode
->MaxMode
);
2639 if (ModeBuffer
== NULL
) {
2640 return EFI_OUT_OF_RESOURCES
;
2642 FreePool (Private
->GraphicsOutputModeBuffer
);
2643 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2646 // Store all supported display modes to the private mode buffer
2649 for (Index
= 0; Index
< GraphicsOutput
->Mode
->MaxMode
; Index
++) {
2650 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) Index
, &SizeOfInfo
, &Info
);
2651 if (EFI_ERROR (Status
)) {
2654 CopyMem (Mode
, Info
, SizeOfInfo
);
2660 // Check intersection of display mode
2662 ModeBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
) * CurrentGraphicsOutputMode
->MaxMode
);
2663 if (ModeBuffer
== NULL
) {
2664 return EFI_OUT_OF_RESOURCES
;
2667 MatchedMode
= ModeBuffer
;
2668 Mode
= &Private
->GraphicsOutputModeBuffer
[0];
2669 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2672 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
2673 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
2674 if (EFI_ERROR (Status
)) {
2677 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2678 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2687 AlreadyExist
= FALSE
;
2689 for (Info
= ModeBuffer
; Info
< MatchedMode
; Info
++) {
2690 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2691 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2692 AlreadyExist
= TRUE
;
2697 if (!AlreadyExist
) {
2698 CopyMem (MatchedMode
, Mode
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2701 // Physical frame buffer is no longer available, change PixelFormat to PixelBltOnly
2703 MatchedMode
->Version
= 0;
2704 MatchedMode
->PixelFormat
= PixelBltOnly
;
2705 ZeroMem (&MatchedMode
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2715 // Drop the old mode buffer, assign it to a new one
2717 FreePool (Private
->GraphicsOutputModeBuffer
);
2718 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2721 // Physical frame buffer is no longer available when there are more than one physical GOP devices
2723 CurrentGraphicsOutputMode
->MaxMode
= (UINT32
) (((UINTN
) MatchedMode
- (UINTN
) ModeBuffer
) / sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2724 CurrentGraphicsOutputMode
->Info
->PixelFormat
= PixelBltOnly
;
2725 ZeroMem (&CurrentGraphicsOutputMode
->Info
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2726 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2727 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2728 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2732 // Graphics console driver can ensure the same mode for all GOP devices
2734 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2735 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2736 if ((Mode
->HorizontalResolution
== GraphicsOutput
->Mode
->Info
->HorizontalResolution
) &&
2737 (Mode
->VerticalResolution
== GraphicsOutput
->Mode
->Info
->VerticalResolution
)) {
2738 CurrentIndex
= Index
;
2742 if (Index
>= CurrentGraphicsOutputMode
->MaxMode
) {
2744 // if user defined mode is not found, set to default mode 800x600
2746 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2747 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2748 if ((Mode
->HorizontalResolution
== 800) && (Mode
->VerticalResolution
== 600)) {
2749 CurrentIndex
= Index
;
2755 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2757 // Graphics console driver can ensure the same mode for all GOP devices
2758 // so we can get the current mode from this video device
2762 &UgaHorizontalResolution
,
2763 &UgaVerticalResolution
,
2768 CurrentGraphicsOutputMode
->MaxMode
= 1;
2769 Info
= CurrentGraphicsOutputMode
->Info
;
2771 Info
->HorizontalResolution
= UgaHorizontalResolution
;
2772 Info
->VerticalResolution
= UgaVerticalResolution
;
2773 Info
->PixelFormat
= PixelBltOnly
;
2774 Info
->PixelsPerScanLine
= UgaHorizontalResolution
;
2775 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2776 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2777 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2780 // Update the private mode buffer
2782 CopyMem (&Private
->GraphicsOutputModeBuffer
[0], Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2785 // Only mode 0 is available to be set
2792 if (GraphicsOutput
!= NULL
) {
2793 Private
->CurrentNumberOfGraphicsOutput
++;
2795 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2796 Private
->CurrentNumberOfUgaDraw
++;
2800 // Force GraphicsOutput mode to be set,
2801 // regardless whether the console is in EfiConsoleControlScreenGraphics or EfiConsoleControlScreenText mode
2803 Private
->HardwareNeedsStarting
= TRUE
;
2805 // Current mode number may need update now, so set it to an invalid mode number
2807 CurrentGraphicsOutputMode
->Mode
= 0xffff;
2809 // Graphics console can ensure all GOP devices have the same mode which can be taken as current mode.
2811 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, (UINT32
) CurrentIndex
);
2814 // If user defined mode is not valid for UGA, set to the default mode 800x600.
2816 if (EFI_ERROR(Status
)) {
2817 (Private
->GraphicsOutputModeBuffer
[0]).HorizontalResolution
= 800;
2818 (Private
->GraphicsOutputModeBuffer
[0]).VerticalResolution
= 600;
2819 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, 0);
2827 This routine will get the current console mode information (column, row)
2828 from ConsoleOutMode variable and set it; if the variable does not exist,
2829 set to user defined console mode.
2831 @param Private Consplitter Text Out pointer.
2837 ConsplitterSetConsoleOutMode (
2838 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2849 CONSOLE_OUT_MODE
*ModeInfo
;
2850 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
2854 TextOut
= &Private
->TextOut
;
2855 MaxMode
= (UINTN
) (TextOut
->Mode
->MaxMode
);
2856 ModeInfoSize
= sizeof (CONSOLE_OUT_MODE
);
2858 ModeInfo
= AllocateZeroPool (sizeof(CONSOLE_OUT_MODE
));
2859 ASSERT(ModeInfo
!= NULL
);
2861 Status
= gRT
->GetVariable (
2863 &gEfiGenericPlatformVariableGuid
,
2870 // Set to the default mode 80 x 25 required by EFI/UEFI spec;
2871 // user can also define other valid default console mode here.
2873 if (EFI_ERROR(Status
)) {
2874 ModeInfo
->Column
= 80;
2876 Status
= gRT
->SetVariable (
2878 &gEfiGenericPlatformVariableGuid
,
2879 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
2880 sizeof (CONSOLE_OUT_MODE
),
2885 for (Mode
= 0; Mode
< MaxMode
; Mode
++) {
2886 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Col
, &Row
);
2887 if (!EFI_ERROR(Status
)) {
2888 if (Col
== ModeInfo
->Column
&& Row
== ModeInfo
->Row
) {
2891 if (Col
== 80 && Row
== 25) {
2897 Status
= TextOut
->SetMode (TextOut
, PreferMode
);
2900 // if current mode setting is failed, default 80x25 mode will be set.
2902 if (EFI_ERROR(Status
)) {
2903 Status
= TextOut
->SetMode (TextOut
, BaseMode
);
2904 ASSERT(!EFI_ERROR(Status
));
2906 ModeInfo
->Column
= 80;
2910 // Update ConOutMode variable
2912 Status
= gRT
->SetVariable (
2914 &gEfiGenericPlatformVariableGuid
,
2915 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
2916 sizeof (CONSOLE_OUT_MODE
),
2921 gBS
->FreePool (ModeInfo
);
2926 Add Text Output Device in Consplitter Text Output list.
2928 @param Private Text Out Splitter pointer.
2929 @param TextOut Simple Text Output protocol pointer.
2930 @param GraphicsOutput Graphics Output protocol pointer.
2931 @param UgaDraw UGA Draw protocol pointer.
2933 @retval EFI_SUCCESS Text Output Device added successfully.
2934 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2938 ConSplitterTextOutAddDevice (
2939 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2940 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
,
2941 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2942 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2946 UINTN CurrentNumOfConsoles
;
2949 UINT32 UgaHorizontalResolution
;
2950 UINT32 UgaVerticalResolution
;
2951 UINT32 UgaColorDepth
;
2952 UINT32 UgaRefreshRate
;
2953 TEXT_OUT_AND_GOP_DATA
*TextAndGop
;
2955 Status
= EFI_SUCCESS
;
2956 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
2959 // If the Text Out List is full, enlarge it by calling growbuffer().
2961 while (CurrentNumOfConsoles
>= Private
->TextOutListCount
) {
2962 Status
= ConSplitterGrowBuffer (
2963 sizeof (TEXT_OUT_AND_GOP_DATA
),
2964 &Private
->TextOutListCount
,
2965 (VOID
**) &Private
->TextOutList
2967 if (EFI_ERROR (Status
)) {
2968 return EFI_OUT_OF_RESOURCES
;
2971 // Also need to reallocate the TextOutModeMap table
2973 Status
= ConSplitterGrowMapTable (Private
);
2974 if (EFI_ERROR (Status
)) {
2975 return EFI_OUT_OF_RESOURCES
;
2979 TextAndGop
= &Private
->TextOutList
[CurrentNumOfConsoles
];
2981 TextAndGop
->TextOut
= TextOut
;
2982 TextAndGop
->GraphicsOutput
= GraphicsOutput
;
2983 TextAndGop
->UgaDraw
= UgaDraw
;
2985 if ((GraphicsOutput
== NULL
) && (UgaDraw
== NULL
)) {
2987 // If No GOP/UGA device then use the ConOut device
2989 TextAndGop
->TextOutEnabled
= TRUE
;
2992 // If GOP/UGA device use ConOut device only used if screen is in Text mode
2994 TextAndGop
->TextOutEnabled
= (BOOLEAN
) (Private
->ConsoleOutputMode
== EfiConsoleControlScreenText
);
2997 if (CurrentNumOfConsoles
== 0) {
2999 // Add the first device's output mode to console splitter's mode list
3001 Status
= ConSplitterAddOutputMode (Private
, TextOut
);
3003 ConSplitterSyncOutputMode (Private
, TextOut
);
3006 Private
->CurrentNumberOfConsoles
++;
3009 // Scan both TextOutList, for the intersection TextOut device
3010 // maybe both ConOut and StdErr incorporate the same Text Out
3011 // device in them, thus the output of both should be synced.
3013 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3015 CurrentMode
= Private
->TextOutMode
.Mode
;
3016 MaxMode
= Private
->TextOutMode
.MaxMode
;
3017 ASSERT (MaxMode
>= 1);
3020 // Update DevNull mode according to current video device
3022 if (FeaturePcdGet (PcdConOutGopSupport
)) {
3023 if ((GraphicsOutput
!= NULL
) || (UgaDraw
!= NULL
)) {
3024 ConSplitterAddGraphicsOutputMode (Private
, GraphicsOutput
, UgaDraw
);
3027 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
3028 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3029 Status
= UgaDraw
->GetMode (
3031 &UgaHorizontalResolution
,
3032 &UgaVerticalResolution
,
3036 if (!EFI_ERROR (Status
)) {
3037 Status
= ConSpliterUgaDrawSetMode (
3039 UgaHorizontalResolution
,
3040 UgaVerticalResolution
,
3046 // If GetMode/SetMode is failed, set to 800x600 mode
3048 if(EFI_ERROR (Status
)) {
3049 Status
= ConSpliterUgaDrawSetMode (
3060 if (Private
->ConsoleOutputMode
== EfiConsoleControlScreenGraphics
&& GraphicsOutput
!= NULL
) {
3062 // We just added a new GOP or UGA device in graphics mode
3064 if (FeaturePcdGet (PcdConOutGopSupport
)) {
3065 DevNullGopSync (Private
, TextAndGop
->GraphicsOutput
, TextAndGop
->UgaDraw
);
3066 } else if (FeaturePcdGet (PcdConOutUgaSupport
)) {
3067 DevNullUgaSync (Private
, TextAndGop
->GraphicsOutput
, TextAndGop
->UgaDraw
);
3069 } else if ((CurrentMode
>= 0) && ((GraphicsOutput
!= NULL
) || (UgaDraw
!= NULL
)) && (CurrentMode
< Private
->TextOutMode
.MaxMode
)) {
3071 // The new console supports the same mode of the current console so sync up
3073 DevNullSyncStdOut (Private
);
3076 // If ConOut, then set the mode to Mode #0 which us 80 x 25
3078 Private
->TextOut
.SetMode (&Private
->TextOut
, 0);
3082 // After adding new console device, all existing console devices should be
3083 // synced to the current shared mode.
3085 ConsplitterSetConsoleOutMode (Private
);
3092 Remove Text Out Device in Consplitter Text Out list.
3094 @param Private Text Out Splitter pointer.
3095 @param TextOut Simple Text Output Pointer protocol pointer.
3097 @retval EFI_SUCCESS Text Out Device removed successfully.
3098 @retval EFI_NOT_FOUND No Text Out Device found.
3102 ConSplitterTextOutDeleteDevice (
3103 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
3104 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
3108 UINTN CurrentNumOfConsoles
;
3109 TEXT_OUT_AND_GOP_DATA
*TextOutList
;
3113 // Remove the specified text-out device data structure from the Text out List,
3114 // and rearrange the remaining data structures in the Text out List.
3116 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
3117 Index
= (INT32
) CurrentNumOfConsoles
- 1;
3118 TextOutList
= Private
->TextOutList
;
3119 while (Index
>= 0) {
3120 if (TextOutList
->TextOut
== TextOut
) {
3121 CopyMem (TextOutList
, TextOutList
+ 1, sizeof (TEXT_OUT_AND_GOP_DATA
) * Index
);
3122 CurrentNumOfConsoles
--;
3123 if (TextOutList
->UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3124 Private
->CurrentNumberOfUgaDraw
--;
3126 if (TextOutList
->GraphicsOutput
!= NULL
) {
3127 Private
->CurrentNumberOfGraphicsOutput
--;
3136 // The specified TextOut is not managed by the ConSplitter driver
3139 return EFI_NOT_FOUND
;
3142 if (CurrentNumOfConsoles
== 0) {
3144 // If the number of consoles is zero clear the Dev NULL device
3146 Private
->CurrentNumberOfConsoles
= 0;
3147 Private
->TextOutMode
.MaxMode
= 1;
3148 Private
->TextOutQueryData
[0].Columns
= 80;
3149 Private
->TextOutQueryData
[0].Rows
= 25;
3150 DevNullTextOutSetMode (Private
, 0);
3155 // Max Mode is realy an intersection of the QueryMode command to all
3156 // devices. So we must copy the QueryMode of the first device to
3160 Private
->TextOutQueryData
,
3161 Private
->TextOutQueryDataCount
* sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
)
3164 FreePool (Private
->TextOutModeMap
);
3165 Private
->TextOutModeMap
= NULL
;
3166 TextOutList
= Private
->TextOutList
;
3169 // Add the first TextOut to the QueryData array and ModeMap table
3171 Status
= ConSplitterAddOutputMode (Private
, TextOutList
->TextOut
);
3174 // Now add one by one
3177 Private
->CurrentNumberOfConsoles
= 1;
3179 while ((UINTN
) Index
< CurrentNumOfConsoles
) {
3180 ConSplitterSyncOutputMode (Private
, TextOutList
->TextOut
);
3182 Private
->CurrentNumberOfConsoles
++;
3186 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3193 Reset the input device and optionaly run diagnostics
3195 @param This Protocol instance pointer.
3196 @param ExtendedVerification Driver may perform diagnostics on reset.
3198 @retval EFI_SUCCESS The device was reset.
3199 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3205 ConSplitterTextInReset (
3206 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3207 IN BOOLEAN ExtendedVerification
3211 EFI_STATUS ReturnStatus
;
3212 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3215 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3217 Private
->KeyEventSignalState
= FALSE
;
3220 // return the worst status met
3222 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3223 Status
= Private
->TextInList
[Index
]->Reset (
3224 Private
->TextInList
[Index
],
3225 ExtendedVerification
3227 if (EFI_ERROR (Status
)) {
3228 ReturnStatus
= Status
;
3232 return ReturnStatus
;
3237 Reads the next keystroke from the input device. The WaitForKey Event can
3238 be used to test for existance of a keystroke via WaitForEvent () call.
3240 @param Private Protocol instance pointer.
3241 @param Key Driver may perform diagnostics on reset.
3243 @retval EFI_SUCCESS The keystroke information was returned.
3244 @retval EFI_NOT_READY There was no keystroke data availiable.
3245 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3251 ConSplitterTextInPrivateReadKeyStroke (
3252 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3253 OUT EFI_INPUT_KEY
*Key
3258 EFI_INPUT_KEY CurrentKey
;
3260 Key
->UnicodeChar
= 0;
3261 Key
->ScanCode
= SCAN_NULL
;
3264 // if no physical console input device exists, return EFI_NOT_READY;
3265 // if any physical console input device has key input,
3266 // return the key and EFI_SUCCESS.
3268 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3269 Status
= Private
->TextInList
[Index
]->ReadKeyStroke (
3270 Private
->TextInList
[Index
],
3273 if (!EFI_ERROR (Status
)) {
3279 return EFI_NOT_READY
;
3284 Return TRUE if StdIn is locked. The ConIn device on the virtual handle is
3285 the only device locked.
3289 @retval TRUE StdIn locked
3290 @retval FALSE StdIn working normally
3294 ConSpliterConssoleControlStdInLocked (
3298 return mConIn
.PasswordEnabled
;
3303 This timer event will fire when StdIn is locked. It will check the key
3304 sequence on StdIn to see if it matches the password. Any error in the
3305 password will cause the check to reset. As long a mConIn.PasswordEnabled is
3306 TRUE the StdIn splitter will not report any input.
3308 @param Event The Event this notify function registered to.
3309 @param Context Pointer to the context data registerd to the
3317 ConSpliterConsoleControlLockStdInEvent (
3324 CHAR16 BackSpaceString
[2];
3325 CHAR16 SpaceString
[2];
3328 Status
= ConSplitterTextInPrivateReadKeyStroke (&mConIn
, &Key
);
3329 if (!EFI_ERROR (Status
)) {
3331 // if it's an ENTER, match password
3333 if ((Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) && (Key
.ScanCode
== SCAN_NULL
)) {
3334 mConIn
.PwdAttempt
[mConIn
.PwdIndex
] = CHAR_NULL
;
3335 if (StrCmp (mConIn
.Password
, mConIn
.PwdAttempt
)) {
3337 // Password not match
3339 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"\n\rPassword not correct\n\r");
3340 mConIn
.PwdIndex
= 0;
3343 // Key matches password sequence
3345 gBS
->SetTimer (mConIn
.LockEvent
, TimerPeriodic
, 0);
3346 mConIn
.PasswordEnabled
= FALSE
;
3347 Status
= EFI_NOT_READY
;
3349 } else if ((Key
.UnicodeChar
== CHAR_BACKSPACE
) && (Key
.ScanCode
== SCAN_NULL
)) {
3353 if (mConIn
.PwdIndex
> 0) {
3354 BackSpaceString
[0] = CHAR_BACKSPACE
;
3355 BackSpaceString
[1] = 0;
3357 SpaceString
[0] = L
' ';
3360 ConSplitterTextOutOutputString (&mConOut
.TextOut
, BackSpaceString
);
3361 ConSplitterTextOutOutputString (&mConOut
.TextOut
, SpaceString
);
3362 ConSplitterTextOutOutputString (&mConOut
.TextOut
, BackSpaceString
);
3366 } else if ((Key
.ScanCode
== SCAN_NULL
) && (Key
.UnicodeChar
>= 32)) {
3368 // If it's not an ENTER, neigher a function key, nor a CTRL-X or ALT-X, record the input
3370 if (mConIn
.PwdIndex
< (MAX_STD_IN_PASSWORD
- 1)) {
3371 if (mConIn
.PwdIndex
== 0) {
3372 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"\n\r");
3375 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"*");
3376 mConIn
.PwdAttempt
[mConIn
.PwdIndex
] = Key
.UnicodeChar
;
3381 } while (!EFI_ERROR (Status
));
3386 If Password is NULL unlock the password state variable and set the event
3387 timer. If the Password is too big return an error. If the Password is valid
3388 Copy the Password and enable state variable and then arm the periodic timer
3390 @param This Console Control protocol pointer.
3391 @param Password The password input.
3393 @retval EFI_SUCCESS Lock the StdIn device
3394 @retval EFI_INVALID_PARAMETER Password is NULL
3395 @retval EFI_OUT_OF_RESOURCES Buffer allocation to store the password fails
3400 ConSpliterConsoleControlLockStdIn (
3401 IN EFI_CONSOLE_CONTROL_PROTOCOL
*This
,
3405 if (Password
== NULL
) {
3406 return EFI_INVALID_PARAMETER
;
3409 if (StrLen (Password
) >= MAX_STD_IN_PASSWORD
) {
3411 // Currently have a max password size
3413 return EFI_OUT_OF_RESOURCES
;
3416 // Save the password, initialize state variables and arm event timer
3418 StrCpy (mConIn
.Password
, Password
);
3419 mConIn
.PasswordEnabled
= TRUE
;
3420 mConIn
.PwdIndex
= 0;
3421 gBS
->SetTimer (mConIn
.LockEvent
, TimerPeriodic
, (10000 * 25));
3428 Reads the next keystroke from the input device. The WaitForKey Event can
3429 be used to test for existance of a keystroke via WaitForEvent () call.
3430 If the ConIn is password locked make it look like no keystroke is availible
3432 @param This Protocol instance pointer.
3433 @param Key Driver may perform diagnostics on reset.
3435 @retval EFI_SUCCESS The keystroke information was returned.
3436 @retval EFI_NOT_READY There was no keystroke data availiable.
3437 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3443 ConSplitterTextInReadKeyStroke (
3444 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3445 OUT EFI_INPUT_KEY
*Key
3448 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3450 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3451 if (Private
->PasswordEnabled
) {
3453 // If StdIn Locked return not ready
3455 return EFI_NOT_READY
;
3458 Private
->KeyEventSignalState
= FALSE
;
3460 return ConSplitterTextInPrivateReadKeyStroke (Private
, Key
);
3465 This event agregates all the events of the ConIn devices in the spliter.
3466 If the ConIn is password locked then return.
3467 If any events of physical ConIn devices are signaled, signal the ConIn
3468 spliter event. This will cause the calling code to call
3469 ConSplitterTextInReadKeyStroke ().
3471 @param Event The Event assoicated with callback.
3472 @param Context Context registered when Event was created.
3479 ConSplitterTextInWaitForKey (
3485 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3488 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
3489 if (Private
->PasswordEnabled
) {
3491 // If StdIn Locked return not ready
3497 // if KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
3499 if (Private
->KeyEventSignalState
) {
3500 gBS
->SignalEvent (Event
);
3504 // if any physical console input device has key input, signal the event.
3506 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3507 Status
= gBS
->CheckEvent (Private
->TextInList
[Index
]->WaitForKey
);
3508 if (!EFI_ERROR (Status
)) {
3509 gBS
->SignalEvent (Event
);
3510 Private
->KeyEventSignalState
= TRUE
;
3518 Test if the key has been registered on input device.
3520 @param RegsiteredData A pointer to a buffer that is filled in with the
3521 keystroke state data for the key that was
3523 @param InputData A pointer to a buffer that is filled in with the
3524 keystroke state data for the key that was
3527 @retval TRUE Key be pressed matches a registered key.
3528 @retval FLASE Match failed.
3533 IN EFI_KEY_DATA
*RegsiteredData
,
3534 IN EFI_KEY_DATA
*InputData
3537 ASSERT (RegsiteredData
!= NULL
&& InputData
!= NULL
);
3539 if ((RegsiteredData
->Key
.ScanCode
!= InputData
->Key
.ScanCode
) ||
3540 (RegsiteredData
->Key
.UnicodeChar
!= InputData
->Key
.UnicodeChar
)) {
3545 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
3547 if (RegsiteredData
->KeyState
.KeyShiftState
!= 0 &&
3548 RegsiteredData
->KeyState
.KeyShiftState
!= InputData
->KeyState
.KeyShiftState
) {
3551 if (RegsiteredData
->KeyState
.KeyToggleState
!= 0 &&
3552 RegsiteredData
->KeyState
.KeyToggleState
!= InputData
->KeyState
.KeyToggleState
) {
3562 Reset the input device and optionaly run diagnostics
3564 @param This Protocol instance pointer.
3565 @param ExtendedVerification Driver may perform diagnostics on reset.
3567 @retval EFI_SUCCESS The device was reset.
3568 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3574 ConSplitterTextInResetEx (
3575 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3576 IN BOOLEAN ExtendedVerification
3580 EFI_STATUS ReturnStatus
;
3581 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3584 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3586 Private
->KeyEventSignalState
= FALSE
;
3589 // return the worst status met
3591 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3592 Status
= Private
->TextInExList
[Index
]->Reset (
3593 Private
->TextInExList
[Index
],
3594 ExtendedVerification
3596 if (EFI_ERROR (Status
)) {
3597 ReturnStatus
= Status
;
3601 return ReturnStatus
;
3607 Reads the next keystroke from the input device. The WaitForKey Event can
3608 be used to test for existance of a keystroke via WaitForEvent () call.
3610 @param This Protocol instance pointer.
3611 @param KeyData A pointer to a buffer that is filled in with the
3612 keystroke state data for the key that was
3615 @retval EFI_SUCCESS The keystroke information was returned.
3616 @retval EFI_NOT_READY There was no keystroke data availiable.
3617 @retval EFI_DEVICE_ERROR The keystroke information was not returned due
3619 @retval EFI_INVALID_PARAMETER KeyData is NULL.
3624 ConSplitterTextInReadKeyStrokeEx (
3625 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3626 OUT EFI_KEY_DATA
*KeyData
3629 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3632 EFI_KEY_DATA CurrentKeyData
;
3635 if (KeyData
== NULL
) {
3636 return EFI_INVALID_PARAMETER
;
3639 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3640 if (Private
->PasswordEnabled
) {
3642 // If StdIn Locked return not ready
3644 return EFI_NOT_READY
;
3647 Private
->KeyEventSignalState
= FALSE
;
3649 KeyData
->Key
.UnicodeChar
= 0;
3650 KeyData
->Key
.ScanCode
= SCAN_NULL
;
3653 // if no physical console input device exists, return EFI_NOT_READY;
3654 // if any physical console input device has key input,
3655 // return the key and EFI_SUCCESS.
3657 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3658 Status
= Private
->TextInExList
[Index
]->ReadKeyStrokeEx (
3659 Private
->TextInExList
[Index
],
3662 if (!EFI_ERROR (Status
)) {
3663 CopyMem (KeyData
, &CurrentKeyData
, sizeof (CurrentKeyData
));
3668 return EFI_NOT_READY
;
3673 Set certain state for the input device.
3675 @param This Protocol instance pointer.
3676 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
3677 state for the input device.
3679 @retval EFI_SUCCESS The device state was set successfully.
3680 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
3681 could not have the setting adjusted.
3682 @retval EFI_UNSUPPORTED The device does not have the ability to set its
3684 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
3689 ConSplitterTextInSetState (
3690 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3691 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
3694 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3698 if (KeyToggleState
== NULL
) {
3699 return EFI_INVALID_PARAMETER
;
3702 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3705 // if no physical console input device exists, return EFI_SUCCESS;
3706 // otherwise return the status of setting state of physical console input device
3708 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3709 Status
= Private
->TextInExList
[Index
]->SetState (
3710 Private
->TextInExList
[Index
],
3713 if (EFI_ERROR (Status
)) {
3724 Register a notification function for a particular keystroke for the input device.
3726 @param This Protocol instance pointer.
3727 @param KeyData A pointer to a buffer that is filled in with the
3728 keystroke information data for the key that was
3730 @param KeyNotificationFunction Points to the function to be called when the key
3731 sequence is typed specified by KeyData.
3732 @param NotifyHandle Points to the unique handle assigned to the
3733 registered notification.
3735 @retval EFI_SUCCESS The notification function was registered
3737 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data
3739 @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.
3744 ConSplitterTextInRegisterKeyNotify (
3745 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3746 IN EFI_KEY_DATA
*KeyData
,
3747 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction
,
3748 OUT EFI_HANDLE
*NotifyHandle
3751 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3754 TEXT_IN_EX_SPLITTER_NOTIFY
*NewNotify
;
3756 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3759 if (KeyData
== NULL
|| NotifyHandle
== NULL
|| KeyNotificationFunction
== NULL
) {
3760 return EFI_INVALID_PARAMETER
;
3763 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3766 // if no physical console input device exists,
3767 // return EFI_SUCCESS directly.
3769 if (Private
->CurrentNumberOfExConsoles
<= 0) {
3774 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
3776 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3777 CurrentNotify
= CR (
3779 TEXT_IN_EX_SPLITTER_NOTIFY
,
3781 TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
3783 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
3784 if (CurrentNotify
->KeyNotificationFn
== KeyNotificationFunction
) {
3785 *NotifyHandle
= CurrentNotify
->NotifyHandle
;
3792 // Allocate resource to save the notification function
3794 NewNotify
= (TEXT_IN_EX_SPLITTER_NOTIFY
*) AllocateZeroPool (sizeof (TEXT_IN_EX_SPLITTER_NOTIFY
));
3795 if (NewNotify
== NULL
) {
3796 return EFI_OUT_OF_RESOURCES
;
3798 NewNotify
->NotifyHandleList
= (EFI_HANDLE
*) AllocateZeroPool (sizeof (EFI_HANDLE
) * Private
->CurrentNumberOfExConsoles
);
3799 if (NewNotify
->NotifyHandleList
== NULL
) {
3800 gBS
->FreePool (NewNotify
);
3801 return EFI_OUT_OF_RESOURCES
;
3803 NewNotify
->Signature
= TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
;
3804 NewNotify
->KeyNotificationFn
= KeyNotificationFunction
;
3805 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (KeyData
));
3808 // Return the wrong status of registering key notify of
3809 // physical console input device if meet problems
3811 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3812 Status
= Private
->TextInExList
[Index
]->RegisterKeyNotify (
3813 Private
->TextInExList
[Index
],
3815 KeyNotificationFunction
,
3816 &NewNotify
->NotifyHandleList
[Index
]
3818 if (EFI_ERROR (Status
)) {
3819 gBS
->FreePool (NewNotify
->NotifyHandleList
);
3820 gBS
->FreePool (NewNotify
);
3826 // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE
3828 Status
= gBS
->InstallMultipleProtocolInterfaces (
3829 &NewNotify
->NotifyHandle
,
3830 &gSimpleTextInExNotifyGuid
,
3834 ASSERT_EFI_ERROR (Status
);
3836 InsertTailList (&mConIn
.NotifyList
, &NewNotify
->NotifyEntry
);
3838 *NotifyHandle
= NewNotify
->NotifyHandle
;
3846 Remove a registered notification function from a particular keystroke.
3848 @param This Protocol instance pointer.
3849 @param NotificationHandle The handle of the notification function being
3852 @retval EFI_SUCCESS The notification function was unregistered
3854 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
3855 @retval EFI_NOT_FOUND Can not find the matching entry in database.
3860 ConSplitterTextInUnregisterKeyNotify (
3861 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3862 IN EFI_HANDLE NotificationHandle
3865 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3868 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3871 if (NotificationHandle
== NULL
) {
3872 return EFI_INVALID_PARAMETER
;
3875 Status
= gBS
->OpenProtocol (
3877 &gSimpleTextInExNotifyGuid
,
3881 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
3883 if (EFI_ERROR (Status
)) {
3884 return EFI_INVALID_PARAMETER
;
3887 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3890 // if no physical console input device exists,
3891 // return EFI_SUCCESS directly.
3893 if (Private
->CurrentNumberOfExConsoles
<= 0) {
3897 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3898 CurrentNotify
= CR (Link
, TEXT_IN_EX_SPLITTER_NOTIFY
, NotifyEntry
, TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
);
3899 if (CurrentNotify
->NotifyHandle
== NotificationHandle
) {
3900 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3901 Status
= Private
->TextInExList
[Index
]->UnregisterKeyNotify (
3902 Private
->TextInExList
[Index
],
3903 CurrentNotify
->NotifyHandleList
[Index
]
3905 if (EFI_ERROR (Status
)) {
3909 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
3910 Status
= gBS
->UninstallMultipleProtocolInterfaces (
3911 CurrentNotify
->NotifyHandle
,
3912 &gSimpleTextInExNotifyGuid
,
3916 ASSERT_EFI_ERROR (Status
);
3917 gBS
->FreePool (CurrentNotify
->NotifyHandleList
);
3918 gBS
->FreePool (CurrentNotify
);
3923 return EFI_NOT_FOUND
;
3929 Reset the input device and optionaly run diagnostics
3931 @param This Protocol instance pointer.
3932 @param ExtendedVerification Driver may perform diagnostics on reset.
3934 @retval EFI_SUCCESS The device was reset.
3935 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3941 ConSplitterSimplePointerReset (
3942 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
3943 IN BOOLEAN ExtendedVerification
3947 EFI_STATUS ReturnStatus
;
3948 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3951 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
3953 Private
->InputEventSignalState
= FALSE
;
3955 if (Private
->CurrentNumberOfPointers
== 0) {
3959 // return the worst status met
3961 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3962 Status
= Private
->PointerList
[Index
]->Reset (
3963 Private
->PointerList
[Index
],
3964 ExtendedVerification
3966 if (EFI_ERROR (Status
)) {
3967 ReturnStatus
= Status
;
3971 return ReturnStatus
;
3976 Reads the next keystroke from the input device. The WaitForKey Event can
3977 be used to test for existance of a keystroke via WaitForEvent () call.
3979 @param Private Protocol instance pointer.
3980 @param State The state information of simple pointer device.
3982 @retval EFI_SUCCESS The keystroke information was returned.
3983 @retval EFI_NOT_READY There was no keystroke data availiable.
3984 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3990 ConSplitterSimplePointerPrivateGetState (
3991 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3992 IN OUT EFI_SIMPLE_POINTER_STATE
*State
3996 EFI_STATUS ReturnStatus
;
3998 EFI_SIMPLE_POINTER_STATE CurrentState
;
4000 State
->RelativeMovementX
= 0;
4001 State
->RelativeMovementY
= 0;
4002 State
->RelativeMovementZ
= 0;
4003 State
->LeftButton
= FALSE
;
4004 State
->RightButton
= FALSE
;
4007 // if no physical console input device exists, return EFI_NOT_READY;
4008 // if any physical console input device has key input,
4009 // return the key and EFI_SUCCESS.
4011 ReturnStatus
= EFI_NOT_READY
;
4012 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
4014 Status
= Private
->PointerList
[Index
]->GetState (
4015 Private
->PointerList
[Index
],
4018 if (!EFI_ERROR (Status
)) {
4019 if (ReturnStatus
== EFI_NOT_READY
) {
4020 ReturnStatus
= EFI_SUCCESS
;
4023 if (CurrentState
.LeftButton
) {
4024 State
->LeftButton
= TRUE
;
4027 if (CurrentState
.RightButton
) {
4028 State
->RightButton
= TRUE
;
4031 if (CurrentState
.RelativeMovementX
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionX
!= 0) {
4032 State
->RelativeMovementX
+= (CurrentState
.RelativeMovementX
* (INT32
) Private
->SimplePointerMode
.ResolutionX
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionX
;
4035 if (CurrentState
.RelativeMovementY
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionY
!= 0) {
4036 State
->RelativeMovementY
+= (CurrentState
.RelativeMovementY
* (INT32
) Private
->SimplePointerMode
.ResolutionY
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionY
;
4039 if (CurrentState
.RelativeMovementZ
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionZ
!= 0) {
4040 State
->RelativeMovementZ
+= (CurrentState
.RelativeMovementZ
* (INT32
) Private
->SimplePointerMode
.ResolutionZ
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionZ
;
4042 } else if (Status
== EFI_DEVICE_ERROR
) {
4043 ReturnStatus
= EFI_DEVICE_ERROR
;
4047 return ReturnStatus
;
4052 Reads the next keystroke from the input device. The WaitForKey Event can
4053 be used to test for existance of a keystroke via WaitForEvent () call.
4054 If the ConIn is password locked make it look like no keystroke is availible
4056 @param This A pointer to protocol instance.
4057 @param State A pointer to state information on the pointer device
4059 @retval EFI_SUCCESS The keystroke information was returned in State.
4060 @retval EFI_NOT_READY There was no keystroke data availiable.
4061 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
4067 ConSplitterSimplePointerGetState (
4068 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
4069 IN OUT EFI_SIMPLE_POINTER_STATE
*State
4072 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4074 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
4075 if (Private
->PasswordEnabled
) {
4077 // If StdIn Locked return not ready
4079 return EFI_NOT_READY
;
4082 Private
->InputEventSignalState
= FALSE
;
4084 return ConSplitterSimplePointerPrivateGetState (Private
, State
);
4089 This event agregates all the events of the ConIn devices in the spliter.
4090 If the ConIn is password locked then return.
4091 If any events of physical ConIn devices are signaled, signal the ConIn
4092 spliter event. This will cause the calling code to call
4093 ConSplitterTextInReadKeyStroke ().
4095 @param Event The Event assoicated with callback.
4096 @param Context Context registered when Event was created.
4103 ConSplitterSimplePointerWaitForInput (
4109 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4112 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4113 if (Private
->PasswordEnabled
) {
4115 // If StdIn Locked return not ready
4121 // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
4123 if (Private
->InputEventSignalState
) {
4124 gBS
->SignalEvent (Event
);
4128 // if any physical console input device has key input, signal the event.
4130 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
4131 Status
= gBS
->CheckEvent (Private
->PointerList
[Index
]->WaitForInput
);
4132 if (!EFI_ERROR (Status
)) {
4133 gBS
->SignalEvent (Event
);
4134 Private
->InputEventSignalState
= TRUE
;
4140 Resets the pointer device hardware.
4142 @param This Protocol instance pointer.
4143 @param ExtendedVerification Driver may perform diagnostics on reset.
4145 @retval EFI_SUCCESS The device was reset.
4146 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
4152 ConSplitterAbsolutePointerReset (
4153 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4154 IN BOOLEAN ExtendedVerification
4158 EFI_STATUS ReturnStatus
;
4159 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4162 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4164 Private
->AbsoluteInputEventSignalState
= FALSE
;
4166 if (Private
->CurrentNumberOfAbsolutePointers
== 0) {
4170 // return the worst status met
4172 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4173 Status
= Private
->AbsolutePointerList
[Index
]->Reset (
4174 Private
->AbsolutePointerList
[Index
],
4175 ExtendedVerification
4177 if (EFI_ERROR (Status
)) {
4178 ReturnStatus
= Status
;
4182 return ReturnStatus
;
4187 Retrieves the current state of a pointer device.
4189 @param This Protocol instance pointer.
4190 @param State A pointer to the state information on the
4193 @retval EFI_SUCCESS The state of the pointer device was returned in
4195 @retval EFI_NOT_READY The state of the pointer device has not changed
4196 since the last call to GetState().
4197 @retval EFI_DEVICE_ERROR A device error occurred while attempting to
4198 retrieve the pointer device's current state.
4203 ConSplitterAbsolutePointerGetState (
4204 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4205 IN OUT EFI_ABSOLUTE_POINTER_STATE
*State
4208 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4210 EFI_STATUS ReturnStatus
;
4212 EFI_ABSOLUTE_POINTER_STATE CurrentState
;
4215 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4216 if (Private
->PasswordEnabled
) {
4218 // If StdIn Locked return not ready
4220 return EFI_NOT_READY
;
4223 Private
->AbsoluteInputEventSignalState
= FALSE
;
4225 State
->CurrentX
= 0;
4226 State
->CurrentY
= 0;
4227 State
->CurrentZ
= 0;
4228 State
->ActiveButtons
= 0;
4231 // if no physical pointer device exists, return EFI_NOT_READY;
4232 // if any physical pointer device has changed state,
4233 // return the state and EFI_SUCCESS.
4235 ReturnStatus
= EFI_NOT_READY
;
4236 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4238 Status
= Private
->AbsolutePointerList
[Index
]->GetState (
4239 Private
->AbsolutePointerList
[Index
],
4242 if (!EFI_ERROR (Status
)) {
4243 if (ReturnStatus
== EFI_NOT_READY
) {
4244 ReturnStatus
= EFI_SUCCESS
;
4247 State
->ActiveButtons
= CurrentState
.ActiveButtons
;
4249 if (!(Private
->AbsolutePointerMode
.AbsoluteMinX
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxX
== 0)) {
4250 State
->CurrentX
= CurrentState
.CurrentX
;
4252 if (!(Private
->AbsolutePointerMode
.AbsoluteMinY
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxY
== 0)) {
4253 State
->CurrentY
= CurrentState
.CurrentY
;
4255 if (!(Private
->AbsolutePointerMode
.AbsoluteMinZ
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxZ
== 0)) {
4256 State
->CurrentZ
= CurrentState
.CurrentZ
;
4259 } else if (Status
== EFI_DEVICE_ERROR
) {
4260 ReturnStatus
= EFI_DEVICE_ERROR
;
4264 return ReturnStatus
;
4269 This event agregates all the events of the pointer devices in the splitter.
4270 If the ConIn is password locked then return.
4271 If any events of physical pointer devices are signaled, signal the pointer
4272 splitter event. This will cause the calling code to call
4273 ConSplitterAbsolutePointerGetState ().
4275 @param Event The Event assoicated with callback.
4276 @param Context Context registered when Event was created.
4283 ConSplitterAbsolutePointerWaitForInput (
4289 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4292 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4293 if (Private
->PasswordEnabled
) {
4295 // If StdIn Locked return not ready
4301 // if AbsoluteInputEventSignalState is flagged before,
4302 // and not cleared by Reset() or GetState(), signal it
4304 if (Private
->AbsoluteInputEventSignalState
) {
4305 gBS
->SignalEvent (Event
);
4309 // if any physical console input device has key input, signal the event.
4311 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4312 Status
= gBS
->CheckEvent (Private
->AbsolutePointerList
[Index
]->WaitForInput
);
4313 if (!EFI_ERROR (Status
)) {
4314 gBS
->SignalEvent (Event
);
4315 Private
->AbsoluteInputEventSignalState
= TRUE
;
4322 Reset the text output device hardware and optionaly run diagnostics
4324 @param This Protocol instance pointer.
4325 @param ExtendedVerification Driver may perform more exhaustive verfication
4326 operation of the device during reset.
4328 @retval EFI_SUCCESS The text output device was reset.
4329 @retval EFI_DEVICE_ERROR The text output device is not functioning
4330 correctly and could not be reset.
4335 ConSplitterTextOutReset (
4336 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4337 IN BOOLEAN ExtendedVerification
4341 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4343 EFI_STATUS ReturnStatus
;
4345 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4348 // return the worst status met
4350 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4352 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4354 Status
= Private
->TextOutList
[Index
].TextOut
->Reset (
4355 Private
->TextOutList
[Index
].TextOut
,
4356 ExtendedVerification
4358 if (EFI_ERROR (Status
)) {
4359 ReturnStatus
= Status
;
4364 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BLACK
));
4366 Status
= DevNullTextOutSetMode (Private
, 0);
4367 if (EFI_ERROR (Status
)) {
4368 ReturnStatus
= Status
;
4371 return ReturnStatus
;
4376 Write a Unicode string to the output device.
4378 @param This Protocol instance pointer.
4379 @param WString The NULL-terminated Unicode string to be
4380 displayed on the output device(s). All output
4381 devices must also support the Unicode drawing
4382 defined in this file.
4384 @retval EFI_SUCCESS The string was output to the device.
4385 @retval EFI_DEVICE_ERROR The device reported an error while attempting to
4387 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
4389 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
4390 characters in the Unicode string could not be
4391 rendered and were skipped.
4396 ConSplitterTextOutOutputString (
4397 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4402 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4404 UINTN BackSpaceCount
;
4405 EFI_STATUS ReturnStatus
;
4406 CHAR16
*TargetString
;
4408 This
->SetAttribute (This
, This
->Mode
->Attribute
);
4410 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4413 for (TargetString
= WString
; *TargetString
!= L
'\0'; TargetString
++) {
4414 if (*TargetString
== CHAR_BACKSPACE
) {
4420 if (BackSpaceCount
== 0) {
4421 TargetString
= WString
;
4423 TargetString
= AllocatePool (sizeof (CHAR16
) * (StrLen (WString
) + BackSpaceCount
+ 1));
4424 StrCpy (TargetString
, WString
);
4427 // return the worst status met
4429 Status
= DevNullTextOutOutputString (Private
, TargetString
);
4430 if (EFI_ERROR (Status
)) {
4431 ReturnStatus
= Status
;
4434 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4436 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4437 Status
= Private
->TextOutList
[Index
].TextOut
->OutputString (
4438 Private
->TextOutList
[Index
].TextOut
,
4441 if (EFI_ERROR (Status
)) {
4442 ReturnStatus
= Status
;
4447 if (BackSpaceCount
> 0) {
4448 FreePool (TargetString
);
4451 return ReturnStatus
;
4456 Verifies that all characters in a Unicode string can be output to the
4459 @param This Protocol instance pointer.
4460 @param WString The NULL-terminated Unicode string to be
4461 examined for the output device(s).
4463 @retval EFI_SUCCESS The device(s) are capable of rendering the
4465 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string
4466 cannot be rendered by one or more of the output
4467 devices mapped by the EFI handle.
4472 ConSplitterTextOutTestString (
4473 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4478 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4480 EFI_STATUS ReturnStatus
;
4482 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4485 // return the worst status met
4487 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4488 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4489 Status
= Private
->TextOutList
[Index
].TextOut
->TestString (
4490 Private
->TextOutList
[Index
].TextOut
,
4493 if (EFI_ERROR (Status
)) {
4494 ReturnStatus
= Status
;
4499 // There is no DevNullTextOutTestString () since a Unicode buffer would
4500 // always return EFI_SUCCESS.
4501 // ReturnStatus will be EFI_SUCCESS if no consoles are present
4503 return ReturnStatus
;
4508 Returns information for an available text mode that the output device(s)
4511 @param This Protocol instance pointer.
4512 @param ModeNumber The mode number to return information on.
4513 @param Columns Returns the columns of the text output device
4514 for the requested ModeNumber.
4515 @param Rows Returns the rows of the text output device
4516 for the requested ModeNumber.
4518 @retval EFI_SUCCESS The requested mode information was returned.
4519 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4521 @retval EFI_UNSUPPORTED The mode number was not valid.
4526 ConSplitterTextOutQueryMode (
4527 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4528 IN UINTN ModeNumber
,
4533 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4535 INT32
*TextOutModeMap
;
4537 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4540 // Check whether param ModeNumber is valid.
4541 // ModeNumber should be within range 0 ~ MaxMode - 1.
4543 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4544 return EFI_UNSUPPORTED
;
4547 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4548 return EFI_UNSUPPORTED
;
4552 // We get the available mode from mode intersection map if it's available
4554 if (Private
->TextOutModeMap
!= NULL
) {
4555 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4556 CurrentMode
= (UINTN
)(*TextOutModeMap
);
4557 *Columns
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4558 *Rows
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4560 *Columns
= Private
->TextOutQueryData
[ModeNumber
].Columns
;
4561 *Rows
= Private
->TextOutQueryData
[ModeNumber
].Rows
;
4564 if (*Columns
<= 0 && *Rows
<= 0) {
4565 return EFI_UNSUPPORTED
;
4574 Sets the output device(s) to a specified mode.
4576 @param This Protocol instance pointer.
4577 @param ModeNumber The mode number to set.
4579 @retval EFI_SUCCESS The requested text mode was set.
4580 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4582 @retval EFI_UNSUPPORTED The mode number was not valid.
4587 ConSplitterTextOutSetMode (
4588 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4593 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4595 INT32
*TextOutModeMap
;
4596 EFI_STATUS ReturnStatus
;
4598 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4601 // Check whether param ModeNumber is valid.
4602 // ModeNumber should be within range 0 ~ MaxMode - 1.
4604 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4605 return EFI_UNSUPPORTED
;
4608 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4609 return EFI_UNSUPPORTED
;
4612 // If the mode is being set to the curent mode, then just clear the screen and return.
4614 if (Private
->TextOutMode
.Mode
== (INT32
) ModeNumber
) {
4615 return ConSplitterTextOutClearScreen (This
);
4618 // return the worst status met
4620 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4621 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4623 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4624 Status
= Private
->TextOutList
[Index
].TextOut
->SetMode (
4625 Private
->TextOutList
[Index
].TextOut
,
4626 TextOutModeMap
[Index
]
4629 // If this console device is based on a GOP or UGA device, then sync up the bitmap from
4630 // the GOP/UGA splitter and reclear the text portion of the display in the new mode.
4632 if ((Private
->TextOutList
[Index
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[Index
].UgaDraw
!= NULL
)) {
4633 Private
->TextOutList
[Index
].TextOut
->ClearScreen (Private
->TextOutList
[Index
].TextOut
);
4636 if (EFI_ERROR (Status
)) {
4637 ReturnStatus
= Status
;
4642 // The DevNull Console will support any possible mode as it allocates memory
4644 Status
= DevNullTextOutSetMode (Private
, ModeNumber
);
4645 if (EFI_ERROR (Status
)) {
4646 ReturnStatus
= Status
;
4649 return ReturnStatus
;
4654 Sets the background and foreground colors for the OutputString () and
4655 ClearScreen () functions.
4657 @param This Protocol instance pointer.
4658 @param Attribute The attribute to set. Bits 0..3 are the
4659 foreground color, and bits 4..6 are the
4660 background color. All other bits are undefined
4661 and must be zero. The valid Attributes are
4662 defined in this file.
4664 @retval EFI_SUCCESS The attribute was set.
4665 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4667 @retval EFI_UNSUPPORTED The attribute requested is not defined.
4672 ConSplitterTextOutSetAttribute (
4673 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4678 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4680 EFI_STATUS ReturnStatus
;
4682 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4685 // Check whether param Attribute is valid.
4687 if ( (Attribute
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4688 return EFI_UNSUPPORTED
;
4692 // return the worst status met
4694 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4696 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4697 Status
= Private
->TextOutList
[Index
].TextOut
->SetAttribute (
4698 Private
->TextOutList
[Index
].TextOut
,
4701 if (EFI_ERROR (Status
)) {
4702 ReturnStatus
= Status
;
4707 Private
->TextOutMode
.Attribute
= (INT32
) Attribute
;
4709 return ReturnStatus
;
4714 Clears the output device(s) display to the currently selected background
4717 @param This Protocol instance pointer.
4719 @retval EFI_SUCCESS The operation completed successfully.
4720 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4722 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4727 ConSplitterTextOutClearScreen (
4728 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
4732 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4734 EFI_STATUS ReturnStatus
;
4736 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4739 // return the worst status met
4741 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4743 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4744 Status
= Private
->TextOutList
[Index
].TextOut
->ClearScreen (Private
->TextOutList
[Index
].TextOut
);
4745 if (EFI_ERROR (Status
)) {
4746 ReturnStatus
= Status
;
4751 Status
= DevNullTextOutClearScreen (Private
);
4752 if (EFI_ERROR (Status
)) {
4753 ReturnStatus
= Status
;
4756 return ReturnStatus
;
4761 Sets the current coordinates of the cursor position
4763 @param This Protocol instance pointer.
4764 @param Column The column position to set the cursor to. Must be
4765 greater than or equal to zero and less than the
4766 number of columns by QueryMode ().
4767 @param Row The row position to set the cursor to. Must be
4768 greater than or equal to zero and less than the
4769 number of rows by QueryMode ().
4771 @retval EFI_SUCCESS The operation completed successfully.
4772 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4774 @retval EFI_UNSUPPORTED The output device is not in a valid text mode,
4775 or the cursor position is invalid for the
4781 ConSplitterTextOutSetCursorPosition (
4782 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4788 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4790 EFI_STATUS ReturnStatus
;
4793 INT32
*TextOutModeMap
;
4797 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4798 TextOutModeMap
= NULL
;
4799 ModeNumber
= Private
->TextOutMode
.Mode
;
4802 // Get current MaxColumn and MaxRow from intersection map
4804 if (Private
->TextOutModeMap
!= NULL
) {
4805 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4806 CurrentMode
= *TextOutModeMap
;
4808 CurrentMode
= ModeNumber
;
4811 MaxColumn
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4812 MaxRow
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4814 if (Column
>= MaxColumn
|| Row
>= MaxRow
) {
4815 return EFI_UNSUPPORTED
;
4818 // return the worst status met
4820 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4822 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4823 Status
= Private
->TextOutList
[Index
].TextOut
->SetCursorPosition (
4824 Private
->TextOutList
[Index
].TextOut
,
4828 if (EFI_ERROR (Status
)) {
4829 ReturnStatus
= Status
;
4834 DevNullTextOutSetCursorPosition (Private
, Column
, Row
);
4836 return ReturnStatus
;
4841 Makes the cursor visible or invisible
4843 @param This Protocol instance pointer.
4844 @param Visible If TRUE, the cursor is set to be visible. If
4845 FALSE, the cursor is set to be invisible.
4847 @retval EFI_SUCCESS The operation completed successfully.
4848 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4849 the request, or the device does not support
4850 changing the cursor mode.
4851 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4856 ConSplitterTextOutEnableCursor (
4857 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4862 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4864 EFI_STATUS ReturnStatus
;
4866 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4869 // return the worst status met
4871 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4873 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4874 Status
= Private
->TextOutList
[Index
].TextOut
->EnableCursor (
4875 Private
->TextOutList
[Index
].TextOut
,
4878 if (EFI_ERROR (Status
)) {
4879 ReturnStatus
= Status
;
4884 DevNullTextOutEnableCursor (Private
, Visible
);
4886 return ReturnStatus
;