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 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 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 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
)) {
1099 // If Simple Text Input Ex protocol exists,
1100 // add this device into Text In Ex devices list.
1102 Status
= ConSplitterTextInExAddDevice (&mConIn
, TextInEx
);
1110 Start Simple Pointer Consplitter on device handle.
1112 @param This Protocol instance pointer.
1113 @param ControllerHandle Handle of device to bind driver to.
1114 @param RemainingDevicePath Optional parameter use to pick a specific child
1117 @retval EFI_SUCCESS Simple Pointer Consplitter is added to ControllerHandle.
1118 @retval other Simple Pointer Consplitter does not support this device.
1123 ConSplitterSimplePointerDriverBindingStart (
1124 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1125 IN EFI_HANDLE ControllerHandle
,
1126 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1130 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
;
1133 // Start ConSplitter on ControllerHandle, and create the virtual
1134 // agrogated console device on first call Start for a SimplePointer handle.
1136 Status
= ConSplitterStart (
1139 mConIn
.VirtualHandle
,
1140 &gEfiSimplePointerProtocolGuid
,
1141 &gEfiSimplePointerProtocolGuid
,
1142 (VOID
**) &SimplePointer
1144 if (EFI_ERROR (Status
)) {
1149 // Add this devcie into Simple Pointer devices list.
1151 return ConSplitterSimplePointerAddDevice (&mConIn
, SimplePointer
);
1156 Start Absolute Pointer Consplitter on device handle.
1158 @param This Protocol instance pointer.
1159 @param ControllerHandle Handle of device to bind driver to.
1160 @param RemainingDevicePath Optional parameter use to pick a specific child
1163 @retval EFI_SUCCESS Absolute Pointer Consplitter is added to ControllerHandle.
1164 @retval other Absolute Pointer Consplitter does not support this device.
1169 ConSplitterAbsolutePointerDriverBindingStart (
1170 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1171 IN EFI_HANDLE ControllerHandle
,
1172 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1176 EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
;
1179 // Start ConSplitter on ControllerHandle, and create the virtual
1180 // agrogated console device on first call Start for a AbsolutePointer handle.
1182 Status
= ConSplitterStart (
1185 mConIn
.VirtualHandle
,
1186 &gEfiAbsolutePointerProtocolGuid
,
1187 &gEfiAbsolutePointerProtocolGuid
,
1188 (VOID
**) &AbsolutePointer
1191 if (EFI_ERROR (Status
)) {
1196 // Add this devcie into Absolute Pointer devices list.
1198 return ConSplitterAbsolutePointerAddDevice (&mConIn
, AbsolutePointer
);
1203 Start Console Out Consplitter on device handle.
1205 @param This Protocol instance pointer.
1206 @param ControllerHandle Handle of device to bind driver to.
1207 @param RemainingDevicePath Optional parameter use to pick a specific child
1210 @retval EFI_SUCCESS Console Out Consplitter is added to ControllerHandle.
1211 @retval other Console Out Consplitter does not support this device.
1216 ConSplitterConOutDriverBindingStart (
1217 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1218 IN EFI_HANDLE ControllerHandle
,
1219 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1223 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1224 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1225 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1228 // Start ConSplitter on ControllerHandle, and create the virtual
1229 // agrogated console device on first call Start for a ConsoleOut handle.
1231 Status
= ConSplitterStart (
1234 mConOut
.VirtualHandle
,
1235 &gEfiConsoleOutDeviceGuid
,
1236 &gEfiSimpleTextOutProtocolGuid
,
1239 if (EFI_ERROR (Status
)) {
1243 GraphicsOutput
= NULL
;
1246 // Try to Open Graphics Output protocol
1248 Status
= gBS
->OpenProtocol (
1250 &gEfiGraphicsOutputProtocolGuid
,
1251 (VOID
**) &GraphicsOutput
,
1252 This
->DriverBindingHandle
,
1253 mConOut
.VirtualHandle
,
1254 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1257 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
1259 // Open UGA DRAW protocol
1261 Status
= gBS
->OpenProtocol (
1263 &gEfiUgaDrawProtocolGuid
,
1265 This
->DriverBindingHandle
,
1266 mConOut
.VirtualHandle
,
1267 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1272 // When new console device is added, the new mode will be set later,
1273 // so put current mode back to init state.
1275 mConOut
.TextOutMode
.Mode
= 0xFF;
1278 // If both ConOut and StdErr incorporate the same Text Out device,
1279 // their MaxMode and QueryData should be the intersection of both.
1281 Status
= ConSplitterTextOutAddDevice (&mConOut
, TextOut
, GraphicsOutput
, UgaDraw
);
1282 ConSplitterTextOutSetAttribute (&mConOut
.TextOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
1284 if (FeaturePcdGet (PcdConOutUgaSupport
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
1286 // Match the UGA mode data of ConOut with the current mode
1288 if (UgaDraw
!= NULL
) {
1291 &mConOut
.UgaHorizontalResolution
,
1292 &mConOut
.UgaVerticalResolution
,
1293 &mConOut
.UgaColorDepth
,
1294 &mConOut
.UgaRefreshRate
1303 Start Standard Error Consplitter on device handle.
1305 @param This Protocol instance pointer.
1306 @param ControllerHandle Handle of device to bind driver to.
1307 @param RemainingDevicePath Optional parameter use to pick a specific child
1310 @retval EFI_SUCCESS Standard Error Consplitter is added to ControllerHandle.
1311 @retval other Standard Error Consplitter does not support this device.
1316 ConSplitterStdErrDriverBindingStart (
1317 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1318 IN EFI_HANDLE ControllerHandle
,
1319 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1323 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1326 // Start ConSplitter on ControllerHandle, and create the virtual
1327 // agrogated console device on first call Start for a StandardError handle.
1329 Status
= ConSplitterStart (
1332 mStdErr
.VirtualHandle
,
1333 &gEfiStandardErrorDeviceGuid
,
1334 &gEfiSimpleTextOutProtocolGuid
,
1337 if (EFI_ERROR (Status
)) {
1342 // When new console device is added, the new mode will be set later,
1343 // so put current mode back to init state.
1345 mStdErr
.TextOutMode
.Mode
= 0xFF;
1348 // If both ConOut and StdErr incorporate the same Text Out device,
1349 // their MaxMode and QueryData should be the intersection of both.
1351 Status
= ConSplitterTextOutAddDevice (&mStdErr
, TextOut
, NULL
, NULL
);
1352 ConSplitterTextOutSetAttribute (&mStdErr
.TextOut
, EFI_TEXT_ATTR (EFI_MAGENTA
, EFI_BLACK
));
1353 if (EFI_ERROR (Status
)) {
1357 if (mStdErr
.CurrentNumberOfConsoles
== 1) {
1358 gST
->StandardErrorHandle
= mStdErr
.VirtualHandle
;
1359 gST
->StdErr
= &mStdErr
.TextOut
;
1361 // Update the CRC32 in the EFI System Table header
1364 gBS
->CalculateCrc32 (
1365 (UINT8
*) &gST
->Hdr
,
1366 gST
->Hdr
.HeaderSize
,
1376 Stop ConSplitter on device handle by closing Console Device Guid on device handle
1377 and the console virtual handle.
1379 @param This Protocol instance pointer.
1380 @param ControllerHandle Handle of device.
1381 @param ConSplitterVirtualHandle Console virtual Handle.
1382 @param DeviceGuid The specified Console Device, such as ConInDev,
1384 @param InterfaceGuid The specified protocol to be opened.
1385 @param Interface Protocol interface returned.
1387 @retval EFI_SUCCESS Stop ConSplitter on ControllerHandle successfully.
1388 @retval other Failed to Stop ConSplitter on ControllerHandle.
1393 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1394 IN EFI_HANDLE ControllerHandle
,
1395 IN EFI_HANDLE ConSplitterVirtualHandle
,
1396 IN EFI_GUID
*DeviceGuid
,
1397 IN EFI_GUID
*InterfaceGuid
,
1403 Status
= gBS
->OpenProtocol (
1407 This
->DriverBindingHandle
,
1409 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1411 if (EFI_ERROR (Status
)) {
1415 // close the protocol refered.
1417 gBS
->CloseProtocol (
1420 This
->DriverBindingHandle
,
1421 ConSplitterVirtualHandle
1424 gBS
->CloseProtocol (
1427 This
->DriverBindingHandle
,
1436 Stop Console In ConSplitter on ControllerHandle by closing Console In Devcice GUID.
1438 @param This Protocol instance pointer.
1439 @param ControllerHandle Handle of device to stop driver on
1440 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1441 children is zero stop the entire bus driver.
1442 @param ChildHandleBuffer List of Child Handles to Stop.
1444 @retval EFI_SUCCESS This driver is removed ControllerHandle
1445 @retval other This driver was not removed from this device
1450 ConSplitterConInDriverBindingStop (
1451 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1452 IN EFI_HANDLE ControllerHandle
,
1453 IN UINTN NumberOfChildren
,
1454 IN EFI_HANDLE
*ChildHandleBuffer
1458 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
1459 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
;
1461 if (NumberOfChildren
== 0) {
1465 Status
= gBS
->OpenProtocol (
1467 &gEfiSimpleTextInputExProtocolGuid
,
1468 (VOID
**) &TextInEx
,
1469 This
->DriverBindingHandle
,
1471 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1473 if (!EFI_ERROR (Status
)) {
1475 // If Simple Text Input Ex protocol exists,
1476 // remove device from Text Input Ex devices list.
1478 Status
= ConSplitterTextInExDeleteDevice (&mConIn
, TextInEx
);
1479 if (EFI_ERROR (Status
)) {
1485 // Close Simple Text In protocol on controller handle and virtual handle.
1487 Status
= ConSplitterStop (
1490 mConIn
.VirtualHandle
,
1491 &gEfiConsoleInDeviceGuid
,
1492 &gEfiSimpleTextInProtocolGuid
,
1495 if (EFI_ERROR (Status
)) {
1500 // Remove device from Text Input devices list.
1502 return ConSplitterTextInDeleteDevice (&mConIn
, TextIn
);
1507 Stop Simple Pointer protocol ConSplitter on ControllerHandle by closing
1508 Simple Pointer protocol.
1510 @param This Protocol instance pointer.
1511 @param ControllerHandle Handle of device to stop driver on
1512 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1513 children is zero stop the entire bus driver.
1514 @param ChildHandleBuffer List of Child Handles to Stop.
1516 @retval EFI_SUCCESS This driver is removed ControllerHandle
1517 @retval other This driver was not removed from this device
1522 ConSplitterSimplePointerDriverBindingStop (
1523 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1524 IN EFI_HANDLE ControllerHandle
,
1525 IN UINTN NumberOfChildren
,
1526 IN EFI_HANDLE
*ChildHandleBuffer
1530 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
;
1532 if (NumberOfChildren
== 0) {
1537 // Close Simple Pointer protocol on controller handle and virtual handle.
1539 Status
= ConSplitterStop (
1542 mConIn
.VirtualHandle
,
1543 &gEfiSimplePointerProtocolGuid
,
1544 &gEfiSimplePointerProtocolGuid
,
1545 (VOID
**) &SimplePointer
1547 if (EFI_ERROR (Status
)) {
1552 // Remove this device from Simple Pointer device list.
1554 return ConSplitterSimplePointerDeleteDevice (&mConIn
, SimplePointer
);
1559 Stop Absolute Pointer protocol ConSplitter on ControllerHandle by closing
1560 Absolute Pointer protocol.
1562 @param This Protocol instance pointer.
1563 @param ControllerHandle Handle of device to stop driver on
1564 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1565 children is zero stop the entire bus driver.
1566 @param ChildHandleBuffer List of Child Handles to Stop.
1568 @retval EFI_SUCCESS This driver is removed ControllerHandle
1569 @retval other This driver was not removed from this device
1574 ConSplitterAbsolutePointerDriverBindingStop (
1575 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1576 IN EFI_HANDLE ControllerHandle
,
1577 IN UINTN NumberOfChildren
,
1578 IN EFI_HANDLE
*ChildHandleBuffer
1582 EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
;
1584 if (NumberOfChildren
== 0) {
1589 // Close Absolute Pointer protocol on controller handle and virtual handle.
1591 Status
= ConSplitterStop (
1594 mConIn
.VirtualHandle
,
1595 &gEfiAbsolutePointerProtocolGuid
,
1596 &gEfiAbsolutePointerProtocolGuid
,
1597 (VOID
**) &AbsolutePointer
1599 if (EFI_ERROR (Status
)) {
1604 // Remove this device from Absolute Pointer device list.
1606 return ConSplitterAbsolutePointerDeleteDevice (&mConIn
, AbsolutePointer
);
1611 Stop Console Out ConSplitter on device handle by closing Console Out Devcice GUID.
1613 @param This Protocol instance pointer.
1614 @param ControllerHandle Handle of device to stop driver on
1615 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1616 children is zero stop the entire bus driver.
1617 @param ChildHandleBuffer List of Child Handles to Stop.
1619 @retval EFI_SUCCESS This driver is removed ControllerHandle
1620 @retval other This driver was not removed from this device
1625 ConSplitterConOutDriverBindingStop (
1626 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1627 IN EFI_HANDLE ControllerHandle
,
1628 IN UINTN NumberOfChildren
,
1629 IN EFI_HANDLE
*ChildHandleBuffer
1633 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1635 if (NumberOfChildren
== 0) {
1640 // Close Absolute Pointer protocol on controller handle and virtual handle.
1642 Status
= ConSplitterStop (
1645 mConOut
.VirtualHandle
,
1646 &gEfiConsoleOutDeviceGuid
,
1647 &gEfiSimpleTextOutProtocolGuid
,
1650 if (EFI_ERROR (Status
)) {
1655 // Remove this device from Text Out device list.
1657 return ConSplitterTextOutDeleteDevice (&mConOut
, TextOut
);
1662 Stop Standard Error ConSplitter on ControllerHandle by closing Standard Error GUID.
1664 @param This Protocol instance pointer.
1665 @param ControllerHandle Handle of device to stop driver on
1666 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1667 children is zero stop the entire bus driver.
1668 @param ChildHandleBuffer List of Child Handles to Stop.
1670 @retval EFI_SUCCESS This driver is removed ControllerHandle
1671 @retval other This driver was not removed from this device
1676 ConSplitterStdErrDriverBindingStop (
1677 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1678 IN EFI_HANDLE ControllerHandle
,
1679 IN UINTN NumberOfChildren
,
1680 IN EFI_HANDLE
*ChildHandleBuffer
1684 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1686 if (NumberOfChildren
== 0) {
1691 // Close Standard Error Device on controller handle and virtual handle.
1693 Status
= ConSplitterStop (
1696 mStdErr
.VirtualHandle
,
1697 &gEfiStandardErrorDeviceGuid
,
1698 &gEfiSimpleTextOutProtocolGuid
,
1701 if (EFI_ERROR (Status
)) {
1705 // Delete this console error out device's data structures.
1707 Status
= ConSplitterTextOutDeleteDevice (&mStdErr
, TextOut
);
1708 if (EFI_ERROR (Status
)) {
1712 if (mStdErr
.CurrentNumberOfConsoles
== 0) {
1713 gST
->StandardErrorHandle
= NULL
;
1716 // Update the CRC32 in the EFI System Table header
1719 gBS
->CalculateCrc32 (
1720 (UINT8
*) &gST
->Hdr
,
1721 gST
->Hdr
.HeaderSize
,
1731 Take the passed in Buffer of size SizeOfCount and grow the buffer
1732 by MAX (CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT, MaxGrow) * SizeOfCount
1733 bytes. Copy the current data in Buffer to the new version of Buffer
1734 and free the old version of buffer.
1736 @param SizeOfCount Size of element in array
1737 @param Count Current number of elements in array
1738 @param Buffer Bigger version of passed in Buffer with all the
1741 @retval EFI_SUCCESS Buffer size has grown
1742 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1746 ConSplitterGrowBuffer (
1747 IN UINTN SizeOfCount
,
1749 IN OUT VOID
**Buffer
1755 // grow the buffer to new buffer size,
1756 // copy the old buffer's content to the new-size buffer,
1757 // then free the old buffer.
1759 *Count
+= CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT
;
1760 Ptr
= ReallocatePool (
1761 SizeOfCount
* ((*Count
) - CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT
),
1762 SizeOfCount
* (*Count
),
1766 return EFI_OUT_OF_RESOURCES
;
1774 Add Text Input Device in Consplitter Text Input list.
1776 @param Private Text In Splitter pointer.
1777 @param TextIn Simple Text Input protocol pointer.
1779 @retval EFI_SUCCESS Text Input Device added successfully.
1780 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1784 ConSplitterTextInAddDevice (
1785 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1786 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1792 // If the Text In List is full, enlarge it by calling growbuffer().
1794 if (Private
->CurrentNumberOfConsoles
>= Private
->TextInListCount
) {
1795 Status
= ConSplitterGrowBuffer (
1796 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
1797 &Private
->TextInListCount
,
1798 (VOID
**) &Private
->TextInList
1800 if (EFI_ERROR (Status
)) {
1801 return EFI_OUT_OF_RESOURCES
;
1805 // Add the new text-in device data structure into the Text In List.
1807 Private
->TextInList
[Private
->CurrentNumberOfConsoles
] = TextIn
;
1808 Private
->CurrentNumberOfConsoles
++;
1811 // Extra CheckEvent added to reduce the double CheckEvent() in UI.c
1813 gBS
->CheckEvent (TextIn
->WaitForKey
);
1820 Remove Simple Text Device in Consplitter Absolute Pointer list.
1822 @param Private Text In Splitter pointer.
1823 @param TextIn Simple Text protocol pointer.
1825 @retval EFI_SUCCESS Simple Text Device removed successfully.
1826 @retval EFI_NOT_FOUND No Simple Text Device found.
1830 ConSplitterTextInDeleteDevice (
1831 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1832 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1837 // Remove the specified text-in device data structure from the Text In List,
1838 // and rearrange the remaining data structures in the Text In List.
1840 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
1841 if (Private
->TextInList
[Index
] == TextIn
) {
1842 for (Index
= Index
; Index
< Private
->CurrentNumberOfConsoles
- 1; Index
++) {
1843 Private
->TextInList
[Index
] = Private
->TextInList
[Index
+ 1];
1846 Private
->CurrentNumberOfConsoles
--;
1851 return EFI_NOT_FOUND
;
1855 Add Text Input Ex Device in Consplitter Text Input Ex list.
1857 @param Private Text In Splitter pointer.
1858 @param TextInEx Simple Text Ex Input protocol pointer.
1860 @retval EFI_SUCCESS Text Input Ex Device added successfully.
1861 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1865 ConSplitterTextInExAddDevice (
1866 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1867 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1873 // If the TextInEx List is full, enlarge it by calling growbuffer().
1875 if (Private
->CurrentNumberOfExConsoles
>= Private
->TextInExListCount
) {
1876 Status
= ConSplitterGrowBuffer (
1877 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
1878 &Private
->TextInExListCount
,
1879 (VOID
**) &Private
->TextInExList
1881 if (EFI_ERROR (Status
)) {
1882 return EFI_OUT_OF_RESOURCES
;
1886 // Add the new text-in device data structure into the Text In List.
1888 Private
->TextInExList
[Private
->CurrentNumberOfExConsoles
] = TextInEx
;
1889 Private
->CurrentNumberOfExConsoles
++;
1892 // Extra CheckEvent added to reduce the double CheckEvent() in UI.c
1894 gBS
->CheckEvent (TextInEx
->WaitForKeyEx
);
1900 Remove Simple Text Ex Device in Consplitter Absolute Pointer list.
1902 @param Private Text In Splitter pointer.
1903 @param TextInEx Simple Text Ex protocol pointer.
1905 @retval EFI_SUCCESS Simple Text Ex Device removed successfully.
1906 @retval EFI_NOT_FOUND No Simple Text Ex Device found.
1910 ConSplitterTextInExDeleteDevice (
1911 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1912 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1917 // Remove the specified text-in device data structure from the Text In List,
1918 // and rearrange the remaining data structures in the Text In List.
1920 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
1921 if (Private
->TextInExList
[Index
] == TextInEx
) {
1922 for (Index
= Index
; Index
< Private
->CurrentNumberOfExConsoles
- 1; Index
++) {
1923 Private
->TextInExList
[Index
] = Private
->TextInExList
[Index
+ 1];
1926 Private
->CurrentNumberOfExConsoles
--;
1931 return EFI_NOT_FOUND
;
1936 Add Simple Pointer Device in Consplitter Simple Pointer list.
1938 @param Private Text In Splitter pointer.
1939 @param SimplePointer Simple Pointer protocol pointer.
1941 @retval EFI_SUCCESS Simple Pointer Device added successfully.
1942 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1946 ConSplitterSimplePointerAddDevice (
1947 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1948 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
1954 // If the Text In List is full, enlarge it by calling growbuffer().
1956 if (Private
->CurrentNumberOfPointers
>= Private
->PointerListCount
) {
1957 Status
= ConSplitterGrowBuffer (
1958 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
1959 &Private
->PointerListCount
,
1960 (VOID
**) &Private
->PointerList
1962 if (EFI_ERROR (Status
)) {
1963 return EFI_OUT_OF_RESOURCES
;
1967 // Add the new text-in device data structure into the Text In List.
1969 Private
->PointerList
[Private
->CurrentNumberOfPointers
] = SimplePointer
;
1970 Private
->CurrentNumberOfPointers
++;
1976 Remove Simple Pointer Device in Consplitter Absolute Pointer list.
1978 @param Private Text In Splitter pointer.
1979 @param SimplePointer Simple Pointer protocol pointer.
1981 @retval EFI_SUCCESS Simple Pointer Device removed successfully.
1982 @retval EFI_NOT_FOUND No Simple Pointer Device found.
1986 ConSplitterSimplePointerDeleteDevice (
1987 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1988 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
1993 // Remove the specified text-in device data structure from the Text In List,
1994 // and rearrange the remaining data structures in the Text In List.
1996 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
1997 if (Private
->PointerList
[Index
] == SimplePointer
) {
1998 for (Index
= Index
; Index
< Private
->CurrentNumberOfPointers
- 1; Index
++) {
1999 Private
->PointerList
[Index
] = Private
->PointerList
[Index
+ 1];
2002 Private
->CurrentNumberOfPointers
--;
2007 return EFI_NOT_FOUND
;
2012 Add Absolute Pointer Device in Consplitter Absolute Pointer list.
2014 @param Private Text In Splitter pointer.
2015 @param AbsolutePointer Absolute Pointer protocol pointer.
2017 @retval EFI_SUCCESS Absolute Pointer Device added successfully.
2018 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2022 ConSplitterAbsolutePointerAddDevice (
2023 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2024 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2030 // If the Absolute Pointer List is full, enlarge it by calling growbuffer().
2032 if (Private
->CurrentNumberOfAbsolutePointers
>= Private
->AbsolutePointerListCount
) {
2033 Status
= ConSplitterGrowBuffer (
2034 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
2035 &Private
->AbsolutePointerListCount
,
2036 (VOID
**) &Private
->AbsolutePointerList
2038 if (EFI_ERROR (Status
)) {
2039 return EFI_OUT_OF_RESOURCES
;
2043 // Add the new text-in device data structure into the Text In List.
2045 Private
->AbsolutePointerList
[Private
->CurrentNumberOfAbsolutePointers
] = AbsolutePointer
;
2046 Private
->CurrentNumberOfAbsolutePointers
++;
2052 Remove Absolute Pointer Device in Consplitter Absolute Pointer list.
2054 @param Private Text In Splitter pointer.
2055 @param AbsolutePointer Absolute Pointer protocol pointer.
2057 @retval EFI_SUCCESS Absolute Pointer Device removed successfully.
2058 @retval EFI_NOT_FOUND No Absolute Pointer Device found.
2062 ConSplitterAbsolutePointerDeleteDevice (
2063 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2064 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2069 // Remove the specified text-in device data structure from the Text In List,
2070 // and rearrange the remaining data structures in the Text In List.
2072 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
2073 if (Private
->AbsolutePointerList
[Index
] == AbsolutePointer
) {
2074 for (Index
= Index
; Index
< Private
->CurrentNumberOfAbsolutePointers
- 1; Index
++) {
2075 Private
->AbsolutePointerList
[Index
] = Private
->AbsolutePointerList
[Index
+ 1];
2078 Private
->CurrentNumberOfAbsolutePointers
--;
2083 return EFI_NOT_FOUND
;
2087 Reallocate Text Out mode map.
2089 @param Private Consplitter Text Out pointer.
2091 @retval EFI_SUCCESS Buffer size has grown
2092 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2096 ConSplitterGrowMapTable (
2097 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2103 INT32
*TextOutModeMap
;
2104 INT32
*OldTextOutModeMap
;
2108 NewSize
= Private
->TextOutListCount
* sizeof (INT32
);
2109 OldTextOutModeMap
= Private
->TextOutModeMap
;
2110 TotalSize
= NewSize
* Private
->TextOutQueryDataCount
;
2112 TextOutModeMap
= AllocateZeroPool (TotalSize
);
2113 if (TextOutModeMap
== NULL
) {
2114 return EFI_OUT_OF_RESOURCES
;
2117 SetMem (TextOutModeMap
, TotalSize
, 0xFF);
2118 Private
->TextOutModeMap
= TextOutModeMap
;
2121 // If TextOutList has been enlarged, need to realloc the mode map table
2122 // The mode map table is regarded as a two dimension array.
2125 // 0 ---------> TextOutListCount ----> TextOutListCount
2126 // | -------------------------------------------
2133 // -------------------------------------------
2136 if (OldTextOutModeMap
!= NULL
) {
2138 Size
= Private
->CurrentNumberOfConsoles
* sizeof (INT32
);
2140 SrcAddress
= OldTextOutModeMap
;
2143 // Copy the old data to the new one
2145 while (Index
< Private
->TextOutMode
.MaxMode
) {
2146 CopyMem (TextOutModeMap
, SrcAddress
, Size
);
2147 TextOutModeMap
+= NewSize
;
2152 // Free the old buffer
2154 FreePool (OldTextOutModeMap
);
2162 Add the device's output mode to console splitter's mode list.
2164 @param Private Text Out Splitter pointer
2165 @param TextOut Simple Text Output protocol pointer.
2167 @retval EFI_SUCCESS Device added successfully.
2168 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2172 ConSplitterAddOutputMode (
2173 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2174 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2182 MaxMode
= TextOut
->Mode
->MaxMode
;
2183 Private
->TextOutMode
.MaxMode
= MaxMode
;
2186 // Grow the buffer if query data buffer is not large enough to
2187 // hold all the mode supported by the first console.
2189 while (MaxMode
> (INT32
) Private
->TextOutQueryDataCount
) {
2190 Status
= ConSplitterGrowBuffer (
2191 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
2192 &Private
->TextOutQueryDataCount
,
2193 (VOID
**) &Private
->TextOutQueryData
2195 if (EFI_ERROR (Status
)) {
2196 return EFI_OUT_OF_RESOURCES
;
2200 // Allocate buffer for the output mode map
2202 Status
= ConSplitterGrowMapTable (Private
);
2203 if (EFI_ERROR (Status
)) {
2204 return EFI_OUT_OF_RESOURCES
;
2207 // As the first textout device, directly add the mode in to QueryData
2208 // and at the same time record the mapping between QueryData and TextOut.
2212 while (Mode
< MaxMode
) {
2213 Status
= TextOut
->QueryMode (
2216 &Private
->TextOutQueryData
[Mode
].Columns
,
2217 &Private
->TextOutQueryData
[Mode
].Rows
2220 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData
2223 if ((EFI_ERROR(Status
)) && (Mode
== 1)) {
2224 Private
->TextOutQueryData
[Mode
].Columns
= 0;
2225 Private
->TextOutQueryData
[Mode
].Rows
= 0;
2227 Private
->TextOutModeMap
[Index
] = Mode
;
2229 Index
+= Private
->TextOutListCount
;
2236 Reconstruct TextOutModeMap to get intersection of modes.
2238 This routine reconstruct TextOutModeMap to get the intersection
2239 of modes for all console out devices. Because EFI/UEFI spec require
2240 mode 0 is 80x25, mode 1 is 80x50, this routine will not check the
2241 intersection for mode 0 and mode 1.
2243 @param TextOutModeMap Current text out mode map, begin with the mode 80x25
2244 @param NewlyAddedMap New text out mode map, begin with the mode 80x25
2245 @param MapStepSize Mode step size for one console device
2246 @param NewMapStepSize Mode step size for one console device
2247 @param MaxMode Current max text mode
2248 @param CurrentMode Current text mode
2252 ConSplitterGetIntersection (
2253 IN INT32
*TextOutModeMap
,
2254 IN INT32
*NewlyAddedMap
,
2255 IN UINTN MapStepSize
,
2256 IN UINTN NewMapStepSize
,
2258 OUT INT32
*CurrentMode
2262 INT32
*CurrentMapEntry
;
2263 INT32
*NextMapEntry
;
2264 INT32 CurrentMaxMode
;
2268 // According to EFI/UEFI spec, mode 0 and mode 1 have been reserved
2269 // for 80x25 and 80x50 in Simple Text Out protocol, so don't make intersection
2270 // for mode 0 and mode 1, mode number starts from 2.
2273 CurrentMapEntry
= &TextOutModeMap
[MapStepSize
* 2];
2274 NextMapEntry
= &TextOutModeMap
[MapStepSize
* 2];
2275 NewlyAddedMap
= &NewlyAddedMap
[NewMapStepSize
* 2];
2277 CurrentMaxMode
= *MaxMode
;
2278 Mode
= *CurrentMode
;
2280 while (Index
< CurrentMaxMode
) {
2281 if (*NewlyAddedMap
== -1) {
2283 // This mode is not supported any more. Remove it. Special care
2284 // must be taken as this remove will also affect current mode;
2286 if (Index
== *CurrentMode
) {
2288 } else if (Index
< *CurrentMode
) {
2293 if (CurrentMapEntry
!= NextMapEntry
) {
2294 CopyMem (NextMapEntry
, CurrentMapEntry
, MapStepSize
* sizeof (INT32
));
2297 NextMapEntry
+= MapStepSize
;
2300 CurrentMapEntry
+= MapStepSize
;
2301 NewlyAddedMap
+= NewMapStepSize
;
2305 *CurrentMode
= Mode
;
2312 Add the device's output mode to console splitter's mode list.
2314 @param Private Text Out Splitter pointer.
2315 @param TextOut Simple Text Output protocol pointer.
2321 ConSplitterSyncOutputMode (
2322 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2323 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2326 INT32 CurrentMaxMode
;
2329 INT32
*TextOutModeMap
;
2332 TEXT_OUT_SPLITTER_QUERY_DATA
*TextOutQueryData
;
2339 // Must make sure that current mode won't change even if mode number changes
2341 CurrentMaxMode
= Private
->TextOutMode
.MaxMode
;
2342 TextOutModeMap
= Private
->TextOutModeMap
;
2343 StepSize
= Private
->TextOutListCount
;
2344 TextOutQueryData
= Private
->TextOutQueryData
;
2347 // Query all the mode that the newly added TextOut supports
2350 MapTable
= TextOutModeMap
+ Private
->CurrentNumberOfConsoles
;
2351 while (Mode
< TextOut
->Mode
->MaxMode
) {
2352 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Columns
, &Rows
);
2353 if (EFI_ERROR(Status
)) {
2355 MapTable
[StepSize
] = Mode
;
2356 TextOutQueryData
[Mode
].Columns
= 0;
2357 TextOutQueryData
[Mode
].Rows
= 0;
2363 // Search the intersection map and QueryData database to see if they intersects
2366 while (Index
< CurrentMaxMode
) {
2367 QueryMode
= *(TextOutModeMap
+ Index
* StepSize
);
2368 if ((TextOutQueryData
[QueryMode
].Rows
== Rows
) && (TextOutQueryData
[QueryMode
].Columns
== Columns
)) {
2369 MapTable
[Index
* StepSize
] = Mode
;
2379 // Now search the TextOutModeMap table to find the intersection of supported
2380 // mode between ConSplitter and the newly added device.
2382 ConSplitterGetIntersection (
2387 &Private
->TextOutMode
.MaxMode
,
2388 &Private
->TextOutMode
.Mode
2396 Sync output device between ConOut and StdErr output.
2398 @retval EFI_SUCCESS Sync implemented successfully.
2399 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2403 ConSplitterGetIntersectionBetweenConOutAndStrErr (
2407 UINTN ConOutNumOfConsoles
;
2408 UINTN StdErrNumOfConsoles
;
2409 TEXT_OUT_AND_GOP_DATA
*ConOutTextOutList
;
2410 TEXT_OUT_AND_GOP_DATA
*StdErrTextOutList
;
2414 UINTN ConOutColumns
;
2416 UINTN StdErrColumns
;
2417 INT32 ConOutMaxMode
;
2418 INT32 StdErrMaxMode
;
2423 INT32
*ConOutModeMap
;
2424 INT32
*StdErrModeMap
;
2425 INT32
*ConOutMapTable
;
2426 INT32
*StdErrMapTable
;
2427 TEXT_OUT_SPLITTER_QUERY_DATA
*ConOutQueryData
;
2428 TEXT_OUT_SPLITTER_QUERY_DATA
*StdErrQueryData
;
2429 UINTN ConOutStepSize
;
2430 UINTN StdErrStepSize
;
2431 BOOLEAN FoundTheSameTextOut
;
2432 UINTN ConOutMapTableSize
;
2433 UINTN StdErrMapTableSize
;
2435 ConOutNumOfConsoles
= mConOut
.CurrentNumberOfConsoles
;
2436 StdErrNumOfConsoles
= mStdErr
.CurrentNumberOfConsoles
;
2437 ConOutTextOutList
= mConOut
.TextOutList
;
2438 StdErrTextOutList
= mStdErr
.TextOutList
;
2441 FoundTheSameTextOut
= FALSE
;
2442 while ((Indexi
< ConOutNumOfConsoles
) && (!FoundTheSameTextOut
)) {
2444 while (Indexj
< StdErrNumOfConsoles
) {
2445 if (ConOutTextOutList
->TextOut
== StdErrTextOutList
->TextOut
) {
2446 FoundTheSameTextOut
= TRUE
;
2451 StdErrTextOutList
++;
2455 ConOutTextOutList
++;
2458 if (!FoundTheSameTextOut
) {
2462 // Must make sure that current mode won't change even if mode number changes
2464 ConOutMaxMode
= mConOut
.TextOutMode
.MaxMode
;
2465 ConOutModeMap
= mConOut
.TextOutModeMap
;
2466 ConOutStepSize
= mConOut
.TextOutListCount
;
2467 ConOutQueryData
= mConOut
.TextOutQueryData
;
2469 StdErrMaxMode
= mStdErr
.TextOutMode
.MaxMode
;
2470 StdErrModeMap
= mStdErr
.TextOutModeMap
;
2471 StdErrStepSize
= mStdErr
.TextOutListCount
;
2472 StdErrQueryData
= mStdErr
.TextOutQueryData
;
2475 // Allocate the map table and set the map table's index to -1.
2477 ConOutMapTableSize
= ConOutMaxMode
* sizeof (INT32
);
2478 ConOutMapTable
= AllocateZeroPool (ConOutMapTableSize
);
2479 if (ConOutMapTable
== NULL
) {
2480 return EFI_OUT_OF_RESOURCES
;
2483 SetMem (ConOutMapTable
, ConOutMapTableSize
, 0xFF);
2485 StdErrMapTableSize
= StdErrMaxMode
* sizeof (INT32
);
2486 StdErrMapTable
= AllocateZeroPool (StdErrMapTableSize
);
2487 if (StdErrMapTable
== NULL
) {
2488 return EFI_OUT_OF_RESOURCES
;
2491 SetMem (StdErrMapTable
, StdErrMapTableSize
, 0xFF);
2494 // Find the intersection of the two set of modes. If they actually intersect, the
2495 // correponding entry in the map table is set to 1.
2498 while (Mode
< ConOutMaxMode
) {
2500 // Search the intersection map and QueryData database to see if they intersect
2503 ConOutMode
= *(ConOutModeMap
+ Mode
* ConOutStepSize
);
2504 ConOutRows
= ConOutQueryData
[ConOutMode
].Rows
;
2505 ConOutColumns
= ConOutQueryData
[ConOutMode
].Columns
;
2506 while (Index
< StdErrMaxMode
) {
2507 StdErrMode
= *(StdErrModeMap
+ Index
* StdErrStepSize
);
2508 StdErrRows
= StdErrQueryData
[StdErrMode
].Rows
;
2509 StdErrColumns
= StdErrQueryData
[StdErrMode
].Columns
;
2510 if ((StdErrRows
== ConOutRows
) && (StdErrColumns
== ConOutColumns
)) {
2511 ConOutMapTable
[Mode
] = 1;
2512 StdErrMapTable
[Index
] = 1;
2522 // Now search the TextOutModeMap table to find the intersection of supported
2523 // mode between ConSplitter and the newly added device.
2525 ConSplitterGetIntersection (
2528 mConOut
.TextOutListCount
,
2530 &(mConOut
.TextOutMode
.MaxMode
),
2531 &(mConOut
.TextOutMode
.Mode
)
2533 if (mConOut
.TextOutMode
.Mode
< 0) {
2534 mConOut
.TextOut
.SetMode (&(mConOut
.TextOut
), 0);
2537 ConSplitterGetIntersection (
2540 mStdErr
.TextOutListCount
,
2542 &(mStdErr
.TextOutMode
.MaxMode
),
2543 &(mStdErr
.TextOutMode
.Mode
)
2545 if (mStdErr
.TextOutMode
.Mode
< 0) {
2546 mStdErr
.TextOut
.SetMode (&(mStdErr
.TextOut
), 0);
2549 FreePool (ConOutMapTable
);
2550 FreePool (StdErrMapTable
);
2557 Add GOP or UGA output mode into Consplitter Text Out list.
2559 @param Private Text Out Splitter pointer.
2560 @param GraphicsOutput Graphics Output protocol pointer.
2561 @param UgaDraw UGA Draw protocol pointer.
2563 @retval EFI_SUCCESS Output mode added successfully.
2564 @retval other Failed to add output mode.
2568 ConSplitterAddGraphicsOutputMode (
2569 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2570 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2571 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2577 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
;
2579 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
2580 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*CurrentGraphicsOutputMode
;
2581 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*ModeBuffer
;
2582 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*MatchedMode
;
2585 BOOLEAN AlreadyExist
;
2586 UINT32 UgaHorizontalResolution
;
2587 UINT32 UgaVerticalResolution
;
2588 UINT32 UgaColorDepth
;
2589 UINT32 UgaRefreshRate
;
2591 if ((GraphicsOutput
== NULL
) && (UgaDraw
== NULL
)) {
2592 return EFI_UNSUPPORTED
;
2595 CurrentGraphicsOutputMode
= Private
->GraphicsOutput
.Mode
;
2600 if (Private
->CurrentNumberOfUgaDraw
!= 0) {
2602 // If any UGA device has already been added, then there is no need to
2603 // calculate intersection of display mode of different GOP/UGA device,
2604 // since only one display mode will be exported (i.e. user-defined mode)
2609 if (GraphicsOutput
!= NULL
) {
2610 if (Private
->CurrentNumberOfGraphicsOutput
== 0) {
2612 // This is the first Graphics Output device added
2614 CurrentGraphicsOutputMode
->MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
2615 CurrentGraphicsOutputMode
->Mode
= GraphicsOutput
->Mode
->Mode
;
2616 CopyMem (CurrentGraphicsOutputMode
->Info
, GraphicsOutput
->Mode
->Info
, GraphicsOutput
->Mode
->SizeOfInfo
);
2617 CurrentGraphicsOutputMode
->SizeOfInfo
= GraphicsOutput
->Mode
->SizeOfInfo
;
2618 CurrentGraphicsOutputMode
->FrameBufferBase
= GraphicsOutput
->Mode
->FrameBufferBase
;
2619 CurrentGraphicsOutputMode
->FrameBufferSize
= GraphicsOutput
->Mode
->FrameBufferSize
;
2622 // Allocate resource for the private mode buffer
2624 ModeBuffer
= AllocatePool (GraphicsOutput
->Mode
->SizeOfInfo
* GraphicsOutput
->Mode
->MaxMode
);
2625 if (ModeBuffer
== NULL
) {
2626 return EFI_OUT_OF_RESOURCES
;
2628 FreePool (Private
->GraphicsOutputModeBuffer
);
2629 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2632 // Store all supported display modes to the private mode buffer
2635 for (Index
= 0; Index
< GraphicsOutput
->Mode
->MaxMode
; Index
++) {
2636 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) Index
, &SizeOfInfo
, &Info
);
2637 if (EFI_ERROR (Status
)) {
2640 CopyMem (Mode
, Info
, SizeOfInfo
);
2646 // Check intersection of display mode
2648 ModeBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
) * CurrentGraphicsOutputMode
->MaxMode
);
2649 if (ModeBuffer
== NULL
) {
2650 return EFI_OUT_OF_RESOURCES
;
2653 MatchedMode
= ModeBuffer
;
2654 Mode
= &Private
->GraphicsOutputModeBuffer
[0];
2655 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2658 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
2659 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
2660 if (EFI_ERROR (Status
)) {
2663 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2664 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2673 AlreadyExist
= FALSE
;
2675 for (Info
= ModeBuffer
; Info
< MatchedMode
; Info
++) {
2676 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2677 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2678 AlreadyExist
= TRUE
;
2683 if (!AlreadyExist
) {
2684 CopyMem (MatchedMode
, Mode
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2687 // Physical frame buffer is no longer available, change PixelFormat to PixelBltOnly
2689 MatchedMode
->Version
= 0;
2690 MatchedMode
->PixelFormat
= PixelBltOnly
;
2691 ZeroMem (&MatchedMode
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2701 // Drop the old mode buffer, assign it to a new one
2703 FreePool (Private
->GraphicsOutputModeBuffer
);
2704 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2707 // Physical frame buffer is no longer available when there are more than one physical GOP devices
2709 CurrentGraphicsOutputMode
->MaxMode
= (UINT32
) (((UINTN
) MatchedMode
- (UINTN
) ModeBuffer
) / sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2710 CurrentGraphicsOutputMode
->Info
->PixelFormat
= PixelBltOnly
;
2711 ZeroMem (&CurrentGraphicsOutputMode
->Info
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2712 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2713 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2714 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2718 // Graphics console driver can ensure the same mode for all GOP devices
2720 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2721 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2722 if ((Mode
->HorizontalResolution
== GraphicsOutput
->Mode
->Info
->HorizontalResolution
) &&
2723 (Mode
->VerticalResolution
== GraphicsOutput
->Mode
->Info
->VerticalResolution
)) {
2724 CurrentIndex
= Index
;
2728 if (Index
>= CurrentGraphicsOutputMode
->MaxMode
) {
2730 // if user defined mode is not found, set to default mode 800x600
2732 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2733 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2734 if ((Mode
->HorizontalResolution
== 800) && (Mode
->VerticalResolution
== 600)) {
2735 CurrentIndex
= Index
;
2741 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2743 // Graphics console driver can ensure the same mode for all GOP devices
2744 // so we can get the current mode from this video device
2748 &UgaHorizontalResolution
,
2749 &UgaVerticalResolution
,
2754 CurrentGraphicsOutputMode
->MaxMode
= 1;
2755 Info
= CurrentGraphicsOutputMode
->Info
;
2757 Info
->HorizontalResolution
= UgaHorizontalResolution
;
2758 Info
->VerticalResolution
= UgaVerticalResolution
;
2759 Info
->PixelFormat
= PixelBltOnly
;
2760 Info
->PixelsPerScanLine
= UgaHorizontalResolution
;
2761 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2762 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2763 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2766 // Update the private mode buffer
2768 CopyMem (&Private
->GraphicsOutputModeBuffer
[0], Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2771 // Only mode 0 is available to be set
2778 if (GraphicsOutput
!= NULL
) {
2779 Private
->CurrentNumberOfGraphicsOutput
++;
2781 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2782 Private
->CurrentNumberOfUgaDraw
++;
2786 // Force GraphicsOutput mode to be set,
2787 // regardless whether the console is in EfiConsoleControlScreenGraphics or EfiConsoleControlScreenText mode
2789 Private
->HardwareNeedsStarting
= TRUE
;
2791 // Current mode number may need update now, so set it to an invalid mode number
2793 CurrentGraphicsOutputMode
->Mode
= 0xffff;
2795 // Graphics console can ensure all GOP devices have the same mode which can be taken as current mode.
2797 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, (UINT32
) CurrentIndex
);
2800 // If user defined mode is not valid for UGA, set to the default mode 800x600.
2802 if (EFI_ERROR(Status
)) {
2803 (Private
->GraphicsOutputModeBuffer
[0]).HorizontalResolution
= 800;
2804 (Private
->GraphicsOutputModeBuffer
[0]).VerticalResolution
= 600;
2805 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, 0);
2813 This routine will get the current console mode information (column, row)
2814 from ConsoleOutMode variable and set it; if the variable does not exist,
2815 set to user defined console mode.
2817 @param Private Consplitter Text Out pointer.
2823 ConsplitterSetConsoleOutMode (
2824 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2835 CONSOLE_OUT_MODE
*ModeInfo
;
2836 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
2840 TextOut
= &Private
->TextOut
;
2841 MaxMode
= (UINTN
) (TextOut
->Mode
->MaxMode
);
2842 ModeInfoSize
= sizeof (CONSOLE_OUT_MODE
);
2844 ModeInfo
= AllocateZeroPool (sizeof(CONSOLE_OUT_MODE
));
2845 ASSERT(ModeInfo
!= NULL
);
2847 Status
= gRT
->GetVariable (
2849 &gEfiGenericPlatformVariableGuid
,
2856 // Set to the default mode 80 x 25 required by EFI/UEFI spec;
2857 // user can also define other valid default console mode here.
2859 if (EFI_ERROR(Status
)) {
2860 ModeInfo
->Column
= 80;
2862 Status
= gRT
->SetVariable (
2864 &gEfiGenericPlatformVariableGuid
,
2865 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
2866 sizeof (CONSOLE_OUT_MODE
),
2871 for (Mode
= 0; Mode
< MaxMode
; Mode
++) {
2872 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Col
, &Row
);
2873 if (!EFI_ERROR(Status
)) {
2874 if (Col
== ModeInfo
->Column
&& Row
== ModeInfo
->Row
) {
2877 if (Col
== 80 && Row
== 25) {
2883 Status
= TextOut
->SetMode (TextOut
, PreferMode
);
2886 // if current mode setting is failed, default 80x25 mode will be set.
2888 if (EFI_ERROR(Status
)) {
2889 Status
= TextOut
->SetMode (TextOut
, BaseMode
);
2890 ASSERT(!EFI_ERROR(Status
));
2892 ModeInfo
->Column
= 80;
2896 // Update ConOutMode variable
2898 Status
= gRT
->SetVariable (
2900 &gEfiGenericPlatformVariableGuid
,
2901 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
2902 sizeof (CONSOLE_OUT_MODE
),
2907 gBS
->FreePool (ModeInfo
);
2912 Add Text Output Device in Consplitter Text Output list.
2914 @param Private Text Out Splitter pointer.
2915 @param TextOut Simple Text Output protocol pointer.
2916 @param GraphicsOutput Graphics Output protocol pointer.
2917 @param UgaDraw UGA Draw protocol pointer.
2919 @retval EFI_SUCCESS Text Output Device added successfully.
2920 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2924 ConSplitterTextOutAddDevice (
2925 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2926 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
,
2927 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2928 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2932 UINTN CurrentNumOfConsoles
;
2935 UINT32 UgaHorizontalResolution
;
2936 UINT32 UgaVerticalResolution
;
2937 UINT32 UgaColorDepth
;
2938 UINT32 UgaRefreshRate
;
2939 TEXT_OUT_AND_GOP_DATA
*TextAndGop
;
2941 Status
= EFI_SUCCESS
;
2942 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
2945 // If the Text Out List is full, enlarge it by calling growbuffer().
2947 while (CurrentNumOfConsoles
>= Private
->TextOutListCount
) {
2948 Status
= ConSplitterGrowBuffer (
2949 sizeof (TEXT_OUT_AND_GOP_DATA
),
2950 &Private
->TextOutListCount
,
2951 (VOID
**) &Private
->TextOutList
2953 if (EFI_ERROR (Status
)) {
2954 return EFI_OUT_OF_RESOURCES
;
2957 // Also need to reallocate the TextOutModeMap table
2959 Status
= ConSplitterGrowMapTable (Private
);
2960 if (EFI_ERROR (Status
)) {
2961 return EFI_OUT_OF_RESOURCES
;
2965 TextAndGop
= &Private
->TextOutList
[CurrentNumOfConsoles
];
2967 TextAndGop
->TextOut
= TextOut
;
2968 TextAndGop
->GraphicsOutput
= GraphicsOutput
;
2969 TextAndGop
->UgaDraw
= UgaDraw
;
2971 if ((GraphicsOutput
== NULL
) && (UgaDraw
== NULL
)) {
2973 // If No GOP/UGA device then use the ConOut device
2975 TextAndGop
->TextOutEnabled
= TRUE
;
2978 // If GOP/UGA device use ConOut device only used if screen is in Text mode
2980 TextAndGop
->TextOutEnabled
= (BOOLEAN
) (Private
->ConsoleOutputMode
== EfiConsoleControlScreenText
);
2983 if (CurrentNumOfConsoles
== 0) {
2985 // Add the first device's output mode to console splitter's mode list
2987 Status
= ConSplitterAddOutputMode (Private
, TextOut
);
2989 ConSplitterSyncOutputMode (Private
, TextOut
);
2992 Private
->CurrentNumberOfConsoles
++;
2995 // Scan both TextOutList, for the intersection TextOut device
2996 // maybe both ConOut and StdErr incorporate the same Text Out
2997 // device in them, thus the output of both should be synced.
2999 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3001 CurrentMode
= Private
->TextOutMode
.Mode
;
3002 MaxMode
= Private
->TextOutMode
.MaxMode
;
3003 ASSERT (MaxMode
>= 1);
3006 // Update DevNull mode according to current video device
3008 if (FeaturePcdGet (PcdConOutGopSupport
)) {
3009 if ((GraphicsOutput
!= NULL
) || (UgaDraw
!= NULL
)) {
3010 ConSplitterAddGraphicsOutputMode (Private
, GraphicsOutput
, UgaDraw
);
3013 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
3014 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3015 Status
= UgaDraw
->GetMode (
3017 &UgaHorizontalResolution
,
3018 &UgaVerticalResolution
,
3022 if (!EFI_ERROR (Status
)) {
3023 Status
= ConSpliterUgaDrawSetMode (
3025 UgaHorizontalResolution
,
3026 UgaVerticalResolution
,
3032 // If GetMode/SetMode is failed, set to 800x600 mode
3034 if(EFI_ERROR (Status
)) {
3035 Status
= ConSpliterUgaDrawSetMode (
3046 if (Private
->ConsoleOutputMode
== EfiConsoleControlScreenGraphics
&& GraphicsOutput
!= NULL
) {
3048 // We just added a new GOP or UGA device in graphics mode
3050 if (FeaturePcdGet (PcdConOutGopSupport
)) {
3051 DevNullGopSync (Private
, TextAndGop
->GraphicsOutput
, TextAndGop
->UgaDraw
);
3052 } else if (FeaturePcdGet (PcdConOutUgaSupport
)) {
3053 DevNullUgaSync (Private
, TextAndGop
->GraphicsOutput
, TextAndGop
->UgaDraw
);
3055 } else if ((CurrentMode
>= 0) && ((GraphicsOutput
!= NULL
) || (UgaDraw
!= NULL
)) && (CurrentMode
< Private
->TextOutMode
.MaxMode
)) {
3057 // The new console supports the same mode of the current console so sync up
3059 DevNullSyncStdOut (Private
);
3062 // If ConOut, then set the mode to Mode #0 which us 80 x 25
3064 Private
->TextOut
.SetMode (&Private
->TextOut
, 0);
3068 // After adding new console device, all existing console devices should be
3069 // synced to the current shared mode.
3071 ConsplitterSetConsoleOutMode (Private
);
3078 Remove Text Out Device in Consplitter Text Out list.
3080 @param Private Text Out Splitter pointer.
3081 @param TextOut Simple Text Output Pointer protocol pointer.
3083 @retval EFI_SUCCESS Text Out Device removed successfully.
3084 @retval EFI_NOT_FOUND No Text Out Device found.
3088 ConSplitterTextOutDeleteDevice (
3089 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
3090 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
3094 UINTN CurrentNumOfConsoles
;
3095 TEXT_OUT_AND_GOP_DATA
*TextOutList
;
3099 // Remove the specified text-out device data structure from the Text out List,
3100 // and rearrange the remaining data structures in the Text out List.
3102 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
3103 Index
= (INT32
) CurrentNumOfConsoles
- 1;
3104 TextOutList
= Private
->TextOutList
;
3105 while (Index
>= 0) {
3106 if (TextOutList
->TextOut
== TextOut
) {
3107 CopyMem (TextOutList
, TextOutList
+ 1, sizeof (TEXT_OUT_AND_GOP_DATA
) * Index
);
3108 CurrentNumOfConsoles
--;
3109 if (TextOutList
->UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3110 Private
->CurrentNumberOfUgaDraw
--;
3112 if (TextOutList
->GraphicsOutput
!= NULL
) {
3113 Private
->CurrentNumberOfGraphicsOutput
--;
3122 // The specified TextOut is not managed by the ConSplitter driver
3125 return EFI_NOT_FOUND
;
3128 if (CurrentNumOfConsoles
== 0) {
3130 // If the number of consoles is zero clear the Dev NULL device
3132 Private
->CurrentNumberOfConsoles
= 0;
3133 Private
->TextOutMode
.MaxMode
= 1;
3134 Private
->TextOutQueryData
[0].Columns
= 80;
3135 Private
->TextOutQueryData
[0].Rows
= 25;
3136 DevNullTextOutSetMode (Private
, 0);
3141 // Max Mode is realy an intersection of the QueryMode command to all
3142 // devices. So we must copy the QueryMode of the first device to
3146 Private
->TextOutQueryData
,
3147 Private
->TextOutQueryDataCount
* sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
)
3150 FreePool (Private
->TextOutModeMap
);
3151 Private
->TextOutModeMap
= NULL
;
3152 TextOutList
= Private
->TextOutList
;
3155 // Add the first TextOut to the QueryData array and ModeMap table
3157 Status
= ConSplitterAddOutputMode (Private
, TextOutList
->TextOut
);
3160 // Now add one by one
3163 Private
->CurrentNumberOfConsoles
= 1;
3165 while ((UINTN
) Index
< CurrentNumOfConsoles
) {
3166 ConSplitterSyncOutputMode (Private
, TextOutList
->TextOut
);
3168 Private
->CurrentNumberOfConsoles
++;
3172 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3179 Reset the input device and optionaly run diagnostics
3181 @param This Protocol instance pointer.
3182 @param ExtendedVerification Driver may perform diagnostics on reset.
3184 @retval EFI_SUCCESS The device was reset.
3185 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3191 ConSplitterTextInReset (
3192 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3193 IN BOOLEAN ExtendedVerification
3197 EFI_STATUS ReturnStatus
;
3198 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3201 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3203 Private
->KeyEventSignalState
= FALSE
;
3206 // return the worst status met
3208 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3209 Status
= Private
->TextInList
[Index
]->Reset (
3210 Private
->TextInList
[Index
],
3211 ExtendedVerification
3213 if (EFI_ERROR (Status
)) {
3214 ReturnStatus
= Status
;
3218 return ReturnStatus
;
3223 Reads the next keystroke from the input device. The WaitForKey Event can
3224 be used to test for existance of a keystroke via WaitForEvent () call.
3226 @param Private Protocol instance pointer.
3227 @param Key Driver may perform diagnostics on reset.
3229 @retval EFI_SUCCESS The keystroke information was returned.
3230 @retval EFI_NOT_READY There was no keystroke data availiable.
3231 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3237 ConSplitterTextInPrivateReadKeyStroke (
3238 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3239 OUT EFI_INPUT_KEY
*Key
3244 EFI_INPUT_KEY CurrentKey
;
3246 Key
->UnicodeChar
= 0;
3247 Key
->ScanCode
= SCAN_NULL
;
3250 // if no physical console input device exists, return EFI_NOT_READY;
3251 // if any physical console input device has key input,
3252 // return the key and EFI_SUCCESS.
3254 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3255 Status
= Private
->TextInList
[Index
]->ReadKeyStroke (
3256 Private
->TextInList
[Index
],
3259 if (!EFI_ERROR (Status
)) {
3265 return EFI_NOT_READY
;
3270 Return TRUE if StdIn is locked. The ConIn device on the virtual handle is
3271 the only device locked.
3275 @retval TRUE StdIn locked
3276 @retval FALSE StdIn working normally
3280 ConSpliterConssoleControlStdInLocked (
3284 return mConIn
.PasswordEnabled
;
3289 This timer event will fire when StdIn is locked. It will check the key
3290 sequence on StdIn to see if it matches the password. Any error in the
3291 password will cause the check to reset. As long a mConIn.PasswordEnabled is
3292 TRUE the StdIn splitter will not report any input.
3294 @param Event The Event this notify function registered to.
3295 @param Context Pointer to the context data registerd to the
3303 ConSpliterConsoleControlLockStdInEvent (
3310 CHAR16 BackSpaceString
[2];
3311 CHAR16 SpaceString
[2];
3314 Status
= ConSplitterTextInPrivateReadKeyStroke (&mConIn
, &Key
);
3315 if (!EFI_ERROR (Status
)) {
3317 // if it's an ENTER, match password
3319 if ((Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) && (Key
.ScanCode
== SCAN_NULL
)) {
3320 mConIn
.PwdAttempt
[mConIn
.PwdIndex
] = CHAR_NULL
;
3321 if (StrCmp (mConIn
.Password
, mConIn
.PwdAttempt
)) {
3323 // Password not match
3325 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"\n\rPassword not correct\n\r");
3326 mConIn
.PwdIndex
= 0;
3329 // Key matches password sequence
3331 gBS
->SetTimer (mConIn
.LockEvent
, TimerPeriodic
, 0);
3332 mConIn
.PasswordEnabled
= FALSE
;
3333 Status
= EFI_NOT_READY
;
3335 } else if ((Key
.UnicodeChar
== CHAR_BACKSPACE
) && (Key
.ScanCode
== SCAN_NULL
)) {
3339 if (mConIn
.PwdIndex
> 0) {
3340 BackSpaceString
[0] = CHAR_BACKSPACE
;
3341 BackSpaceString
[1] = 0;
3343 SpaceString
[0] = L
' ';
3346 ConSplitterTextOutOutputString (&mConOut
.TextOut
, BackSpaceString
);
3347 ConSplitterTextOutOutputString (&mConOut
.TextOut
, SpaceString
);
3348 ConSplitterTextOutOutputString (&mConOut
.TextOut
, BackSpaceString
);
3352 } else if ((Key
.ScanCode
== SCAN_NULL
) && (Key
.UnicodeChar
>= 32)) {
3354 // If it's not an ENTER, neigher a function key, nor a CTRL-X or ALT-X, record the input
3356 if (mConIn
.PwdIndex
< (MAX_STD_IN_PASSWORD
- 1)) {
3357 if (mConIn
.PwdIndex
== 0) {
3358 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"\n\r");
3361 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"*");
3362 mConIn
.PwdAttempt
[mConIn
.PwdIndex
] = Key
.UnicodeChar
;
3367 } while (!EFI_ERROR (Status
));
3372 If Password is NULL unlock the password state variable and set the event
3373 timer. If the Password is too big return an error. If the Password is valid
3374 Copy the Password and enable state variable and then arm the periodic timer
3376 @param This Console Control protocol pointer.
3377 @param Password The password input.
3379 @retval EFI_SUCCESS Lock the StdIn device
3380 @retval EFI_INVALID_PARAMETER Password is NULL
3381 @retval EFI_OUT_OF_RESOURCES Buffer allocation to store the password fails
3386 ConSpliterConsoleControlLockStdIn (
3387 IN EFI_CONSOLE_CONTROL_PROTOCOL
*This
,
3391 if (Password
== NULL
) {
3392 return EFI_INVALID_PARAMETER
;
3395 if (StrLen (Password
) >= MAX_STD_IN_PASSWORD
) {
3397 // Currently have a max password size
3399 return EFI_OUT_OF_RESOURCES
;
3402 // Save the password, initialize state variables and arm event timer
3404 StrCpy (mConIn
.Password
, Password
);
3405 mConIn
.PasswordEnabled
= TRUE
;
3406 mConIn
.PwdIndex
= 0;
3407 gBS
->SetTimer (mConIn
.LockEvent
, TimerPeriodic
, (10000 * 25));
3414 Reads the next keystroke from the input device. The WaitForKey Event can
3415 be used to test for existance of a keystroke via WaitForEvent () call.
3416 If the ConIn is password locked make it look like no keystroke is availible
3418 @param This Protocol instance pointer.
3419 @param Key Driver may perform diagnostics on reset.
3421 @retval EFI_SUCCESS The keystroke information was returned.
3422 @retval EFI_NOT_READY There was no keystroke data availiable.
3423 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3429 ConSplitterTextInReadKeyStroke (
3430 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3431 OUT EFI_INPUT_KEY
*Key
3434 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3436 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3437 if (Private
->PasswordEnabled
) {
3439 // If StdIn Locked return not ready
3441 return EFI_NOT_READY
;
3444 Private
->KeyEventSignalState
= FALSE
;
3446 return ConSplitterTextInPrivateReadKeyStroke (Private
, Key
);
3451 This event agregates all the events of the ConIn devices in the spliter.
3452 If the ConIn is password locked then return.
3453 If any events of physical ConIn devices are signaled, signal the ConIn
3454 spliter event. This will cause the calling code to call
3455 ConSplitterTextInReadKeyStroke ().
3457 @param Event The Event assoicated with callback.
3458 @param Context Context registered when Event was created.
3465 ConSplitterTextInWaitForKey (
3471 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3474 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
3475 if (Private
->PasswordEnabled
) {
3477 // If StdIn Locked return not ready
3483 // if KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
3485 if (Private
->KeyEventSignalState
) {
3486 gBS
->SignalEvent (Event
);
3490 // if any physical console input device has key input, signal the event.
3492 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3493 Status
= gBS
->CheckEvent (Private
->TextInList
[Index
]->WaitForKey
);
3494 if (!EFI_ERROR (Status
)) {
3495 gBS
->SignalEvent (Event
);
3496 Private
->KeyEventSignalState
= TRUE
;
3504 Test if the key has been registered on input device.
3506 @param RegsiteredData A pointer to a buffer that is filled in with the
3507 keystroke state data for the key that was
3509 @param InputData A pointer to a buffer that is filled in with the
3510 keystroke state data for the key that was
3513 @retval TRUE Key be pressed matches a registered key.
3514 @retval FLASE Match failed.
3519 IN EFI_KEY_DATA
*RegsiteredData
,
3520 IN EFI_KEY_DATA
*InputData
3523 ASSERT (RegsiteredData
!= NULL
&& InputData
!= NULL
);
3525 if ((RegsiteredData
->Key
.ScanCode
!= InputData
->Key
.ScanCode
) ||
3526 (RegsiteredData
->Key
.UnicodeChar
!= InputData
->Key
.UnicodeChar
)) {
3531 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
3533 if (RegsiteredData
->KeyState
.KeyShiftState
!= 0 &&
3534 RegsiteredData
->KeyState
.KeyShiftState
!= InputData
->KeyState
.KeyShiftState
) {
3537 if (RegsiteredData
->KeyState
.KeyToggleState
!= 0 &&
3538 RegsiteredData
->KeyState
.KeyToggleState
!= InputData
->KeyState
.KeyToggleState
) {
3548 Reset the input device and optionaly run diagnostics
3550 @param This Protocol instance pointer.
3551 @param ExtendedVerification Driver may perform diagnostics on reset.
3553 @retval EFI_SUCCESS The device was reset.
3554 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3560 ConSplitterTextInResetEx (
3561 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3562 IN BOOLEAN ExtendedVerification
3566 EFI_STATUS ReturnStatus
;
3567 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3570 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3572 Private
->KeyEventSignalState
= FALSE
;
3575 // return the worst status met
3577 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3578 Status
= Private
->TextInExList
[Index
]->Reset (
3579 Private
->TextInExList
[Index
],
3580 ExtendedVerification
3582 if (EFI_ERROR (Status
)) {
3583 ReturnStatus
= Status
;
3587 return ReturnStatus
;
3593 Reads the next keystroke from the input device. The WaitForKey Event can
3594 be used to test for existance of a keystroke via WaitForEvent () call.
3596 @param This Protocol instance pointer.
3597 @param KeyData A pointer to a buffer that is filled in with the
3598 keystroke state data for the key that was
3601 @retval EFI_SUCCESS The keystroke information was returned.
3602 @retval EFI_NOT_READY There was no keystroke data availiable.
3603 @retval EFI_DEVICE_ERROR The keystroke information was not returned due
3605 @retval EFI_INVALID_PARAMETER KeyData is NULL.
3610 ConSplitterTextInReadKeyStrokeEx (
3611 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3612 OUT EFI_KEY_DATA
*KeyData
3615 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3618 EFI_KEY_DATA CurrentKeyData
;
3621 if (KeyData
== NULL
) {
3622 return EFI_INVALID_PARAMETER
;
3625 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3626 if (Private
->PasswordEnabled
) {
3628 // If StdIn Locked return not ready
3630 return EFI_NOT_READY
;
3633 Private
->KeyEventSignalState
= FALSE
;
3635 KeyData
->Key
.UnicodeChar
= 0;
3636 KeyData
->Key
.ScanCode
= SCAN_NULL
;
3639 // if no physical console input device exists, return EFI_NOT_READY;
3640 // if any physical console input device has key input,
3641 // return the key and EFI_SUCCESS.
3643 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3644 Status
= Private
->TextInExList
[Index
]->ReadKeyStrokeEx (
3645 Private
->TextInExList
[Index
],
3648 if (!EFI_ERROR (Status
)) {
3649 CopyMem (KeyData
, &CurrentKeyData
, sizeof (CurrentKeyData
));
3654 return EFI_NOT_READY
;
3659 Set certain state for the input device.
3661 @param This Protocol instance pointer.
3662 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
3663 state for the input device.
3665 @retval EFI_SUCCESS The device state was set successfully.
3666 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
3667 could not have the setting adjusted.
3668 @retval EFI_UNSUPPORTED The device does not have the ability to set its
3670 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
3675 ConSplitterTextInSetState (
3676 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3677 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
3680 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3684 if (KeyToggleState
== NULL
) {
3685 return EFI_INVALID_PARAMETER
;
3688 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3691 // if no physical console input device exists, return EFI_SUCCESS;
3692 // otherwise return the status of setting state of physical console input device
3694 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3695 Status
= Private
->TextInExList
[Index
]->SetState (
3696 Private
->TextInExList
[Index
],
3699 if (EFI_ERROR (Status
)) {
3710 Register a notification function for a particular keystroke for the input device.
3712 @param This Protocol instance pointer.
3713 @param KeyData A pointer to a buffer that is filled in with the
3714 keystroke information data for the key that was
3716 @param KeyNotificationFunction Points to the function to be called when the key
3717 sequence is typed specified by KeyData.
3718 @param NotifyHandle Points to the unique handle assigned to the
3719 registered notification.
3721 @retval EFI_SUCCESS The notification function was registered
3723 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data
3725 @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.
3730 ConSplitterTextInRegisterKeyNotify (
3731 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3732 IN EFI_KEY_DATA
*KeyData
,
3733 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction
,
3734 OUT EFI_HANDLE
*NotifyHandle
3737 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3740 TEXT_IN_EX_SPLITTER_NOTIFY
*NewNotify
;
3742 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3745 if (KeyData
== NULL
|| NotifyHandle
== NULL
|| KeyNotificationFunction
== NULL
) {
3746 return EFI_INVALID_PARAMETER
;
3749 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3752 // if no physical console input device exists,
3753 // return EFI_SUCCESS directly.
3755 if (Private
->CurrentNumberOfExConsoles
<= 0) {
3760 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
3762 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3763 CurrentNotify
= CR (
3765 TEXT_IN_EX_SPLITTER_NOTIFY
,
3767 TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
3769 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
3770 if (CurrentNotify
->KeyNotificationFn
== KeyNotificationFunction
) {
3771 *NotifyHandle
= CurrentNotify
->NotifyHandle
;
3778 // Allocate resource to save the notification function
3780 NewNotify
= (TEXT_IN_EX_SPLITTER_NOTIFY
*) AllocateZeroPool (sizeof (TEXT_IN_EX_SPLITTER_NOTIFY
));
3781 if (NewNotify
== NULL
) {
3782 return EFI_OUT_OF_RESOURCES
;
3784 NewNotify
->NotifyHandleList
= (EFI_HANDLE
*) AllocateZeroPool (sizeof (EFI_HANDLE
) * Private
->CurrentNumberOfExConsoles
);
3785 if (NewNotify
->NotifyHandleList
== NULL
) {
3786 gBS
->FreePool (NewNotify
);
3787 return EFI_OUT_OF_RESOURCES
;
3789 NewNotify
->Signature
= TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
;
3790 NewNotify
->KeyNotificationFn
= KeyNotificationFunction
;
3791 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (KeyData
));
3794 // Return the wrong status of registering key notify of
3795 // physical console input device if meet problems
3797 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3798 Status
= Private
->TextInExList
[Index
]->RegisterKeyNotify (
3799 Private
->TextInExList
[Index
],
3801 KeyNotificationFunction
,
3802 &NewNotify
->NotifyHandleList
[Index
]
3804 if (EFI_ERROR (Status
)) {
3805 gBS
->FreePool (NewNotify
->NotifyHandleList
);
3806 gBS
->FreePool (NewNotify
);
3812 // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE
3814 Status
= gBS
->InstallMultipleProtocolInterfaces (
3815 &NewNotify
->NotifyHandle
,
3816 &gSimpleTextInExNotifyGuid
,
3820 ASSERT_EFI_ERROR (Status
);
3822 InsertTailList (&mConIn
.NotifyList
, &NewNotify
->NotifyEntry
);
3824 *NotifyHandle
= NewNotify
->NotifyHandle
;
3832 Remove a registered notification function from a particular keystroke.
3834 @param This Protocol instance pointer.
3835 @param NotificationHandle The handle of the notification function being
3838 @retval EFI_SUCCESS The notification function was unregistered
3840 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
3841 @retval EFI_NOT_FOUND Can not find the matching entry in database.
3846 ConSplitterTextInUnregisterKeyNotify (
3847 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3848 IN EFI_HANDLE NotificationHandle
3851 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3854 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3857 if (NotificationHandle
== NULL
) {
3858 return EFI_INVALID_PARAMETER
;
3861 Status
= gBS
->OpenProtocol (
3863 &gSimpleTextInExNotifyGuid
,
3867 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
3869 if (EFI_ERROR (Status
)) {
3870 return EFI_INVALID_PARAMETER
;
3873 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3876 // if no physical console input device exists,
3877 // return EFI_SUCCESS directly.
3879 if (Private
->CurrentNumberOfExConsoles
<= 0) {
3883 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3884 CurrentNotify
= CR (Link
, TEXT_IN_EX_SPLITTER_NOTIFY
, NotifyEntry
, TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
);
3885 if (CurrentNotify
->NotifyHandle
== NotificationHandle
) {
3886 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3887 Status
= Private
->TextInExList
[Index
]->UnregisterKeyNotify (
3888 Private
->TextInExList
[Index
],
3889 CurrentNotify
->NotifyHandleList
[Index
]
3891 if (EFI_ERROR (Status
)) {
3895 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
3896 Status
= gBS
->UninstallMultipleProtocolInterfaces (
3897 CurrentNotify
->NotifyHandle
,
3898 &gSimpleTextInExNotifyGuid
,
3902 ASSERT_EFI_ERROR (Status
);
3903 gBS
->FreePool (CurrentNotify
->NotifyHandleList
);
3904 gBS
->FreePool (CurrentNotify
);
3909 return EFI_NOT_FOUND
;
3915 Reset the input device and optionaly run diagnostics
3917 @param This Protocol instance pointer.
3918 @param ExtendedVerification Driver may perform diagnostics on reset.
3920 @retval EFI_SUCCESS The device was reset.
3921 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3927 ConSplitterSimplePointerReset (
3928 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
3929 IN BOOLEAN ExtendedVerification
3933 EFI_STATUS ReturnStatus
;
3934 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3937 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
3939 Private
->InputEventSignalState
= FALSE
;
3941 if (Private
->CurrentNumberOfPointers
== 0) {
3945 // return the worst status met
3947 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3948 Status
= Private
->PointerList
[Index
]->Reset (
3949 Private
->PointerList
[Index
],
3950 ExtendedVerification
3952 if (EFI_ERROR (Status
)) {
3953 ReturnStatus
= Status
;
3957 return ReturnStatus
;
3962 Reads the next keystroke from the input device. The WaitForKey Event can
3963 be used to test for existance of a keystroke via WaitForEvent () call.
3965 @param Private Protocol instance pointer.
3966 @param State The state information of simple pointer device.
3968 @retval EFI_SUCCESS The keystroke information was returned.
3969 @retval EFI_NOT_READY There was no keystroke data availiable.
3970 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3976 ConSplitterSimplePointerPrivateGetState (
3977 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3978 IN OUT EFI_SIMPLE_POINTER_STATE
*State
3982 EFI_STATUS ReturnStatus
;
3984 EFI_SIMPLE_POINTER_STATE CurrentState
;
3986 State
->RelativeMovementX
= 0;
3987 State
->RelativeMovementY
= 0;
3988 State
->RelativeMovementZ
= 0;
3989 State
->LeftButton
= FALSE
;
3990 State
->RightButton
= FALSE
;
3993 // if no physical console input device exists, return EFI_NOT_READY;
3994 // if any physical console input device has key input,
3995 // return the key and EFI_SUCCESS.
3997 ReturnStatus
= EFI_NOT_READY
;
3998 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
4000 Status
= Private
->PointerList
[Index
]->GetState (
4001 Private
->PointerList
[Index
],
4004 if (!EFI_ERROR (Status
)) {
4005 if (ReturnStatus
== EFI_NOT_READY
) {
4006 ReturnStatus
= EFI_SUCCESS
;
4009 if (CurrentState
.LeftButton
) {
4010 State
->LeftButton
= TRUE
;
4013 if (CurrentState
.RightButton
) {
4014 State
->RightButton
= TRUE
;
4017 if (CurrentState
.RelativeMovementX
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionX
!= 0) {
4018 State
->RelativeMovementX
+= (CurrentState
.RelativeMovementX
* (INT32
) Private
->SimplePointerMode
.ResolutionX
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionX
;
4021 if (CurrentState
.RelativeMovementY
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionY
!= 0) {
4022 State
->RelativeMovementY
+= (CurrentState
.RelativeMovementY
* (INT32
) Private
->SimplePointerMode
.ResolutionY
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionY
;
4025 if (CurrentState
.RelativeMovementZ
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionZ
!= 0) {
4026 State
->RelativeMovementZ
+= (CurrentState
.RelativeMovementZ
* (INT32
) Private
->SimplePointerMode
.ResolutionZ
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionZ
;
4028 } else if (Status
== EFI_DEVICE_ERROR
) {
4029 ReturnStatus
= EFI_DEVICE_ERROR
;
4033 return ReturnStatus
;
4038 Reads the next keystroke from the input device. The WaitForKey Event can
4039 be used to test for existance of a keystroke via WaitForEvent () call.
4040 If the ConIn is password locked make it look like no keystroke is availible
4042 @param This A pointer to protocol instance.
4043 @param State A pointer to state information on the pointer device
4045 @retval EFI_SUCCESS The keystroke information was returned in State.
4046 @retval EFI_NOT_READY There was no keystroke data availiable.
4047 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
4053 ConSplitterSimplePointerGetState (
4054 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
4055 IN OUT EFI_SIMPLE_POINTER_STATE
*State
4058 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4060 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
4061 if (Private
->PasswordEnabled
) {
4063 // If StdIn Locked return not ready
4065 return EFI_NOT_READY
;
4068 Private
->InputEventSignalState
= FALSE
;
4070 return ConSplitterSimplePointerPrivateGetState (Private
, State
);
4075 This event agregates all the events of the ConIn devices in the spliter.
4076 If the ConIn is password locked then return.
4077 If any events of physical ConIn devices are signaled, signal the ConIn
4078 spliter event. This will cause the calling code to call
4079 ConSplitterTextInReadKeyStroke ().
4081 @param Event The Event assoicated with callback.
4082 @param Context Context registered when Event was created.
4089 ConSplitterSimplePointerWaitForInput (
4095 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4098 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4099 if (Private
->PasswordEnabled
) {
4101 // If StdIn Locked return not ready
4107 // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
4109 if (Private
->InputEventSignalState
) {
4110 gBS
->SignalEvent (Event
);
4114 // if any physical console input device has key input, signal the event.
4116 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
4117 Status
= gBS
->CheckEvent (Private
->PointerList
[Index
]->WaitForInput
);
4118 if (!EFI_ERROR (Status
)) {
4119 gBS
->SignalEvent (Event
);
4120 Private
->InputEventSignalState
= TRUE
;
4126 Resets the pointer device hardware.
4128 @param This Protocol instance pointer.
4129 @param ExtendedVerification Driver may perform diagnostics on reset.
4131 @retval EFI_SUCCESS The device was reset.
4132 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
4138 ConSplitterAbsolutePointerReset (
4139 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4140 IN BOOLEAN ExtendedVerification
4144 EFI_STATUS ReturnStatus
;
4145 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4148 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4150 Private
->AbsoluteInputEventSignalState
= FALSE
;
4152 if (Private
->CurrentNumberOfAbsolutePointers
== 0) {
4156 // return the worst status met
4158 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4159 Status
= Private
->AbsolutePointerList
[Index
]->Reset (
4160 Private
->AbsolutePointerList
[Index
],
4161 ExtendedVerification
4163 if (EFI_ERROR (Status
)) {
4164 ReturnStatus
= Status
;
4168 return ReturnStatus
;
4173 Retrieves the current state of a pointer device.
4175 @param This Protocol instance pointer.
4176 @param State A pointer to the state information on the
4179 @retval EFI_SUCCESS The state of the pointer device was returned in
4181 @retval EFI_NOT_READY The state of the pointer device has not changed
4182 since the last call to GetState().
4183 @retval EFI_DEVICE_ERROR A device error occurred while attempting to
4184 retrieve the pointer device's current state.
4189 ConSplitterAbsolutePointerGetState (
4190 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4191 IN OUT EFI_ABSOLUTE_POINTER_STATE
*State
4194 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4196 EFI_STATUS ReturnStatus
;
4198 EFI_ABSOLUTE_POINTER_STATE CurrentState
;
4201 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4202 if (Private
->PasswordEnabled
) {
4204 // If StdIn Locked return not ready
4206 return EFI_NOT_READY
;
4209 Private
->AbsoluteInputEventSignalState
= FALSE
;
4211 State
->CurrentX
= 0;
4212 State
->CurrentY
= 0;
4213 State
->CurrentZ
= 0;
4214 State
->ActiveButtons
= 0;
4217 // if no physical pointer device exists, return EFI_NOT_READY;
4218 // if any physical pointer device has changed state,
4219 // return the state and EFI_SUCCESS.
4221 ReturnStatus
= EFI_NOT_READY
;
4222 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4224 Status
= Private
->AbsolutePointerList
[Index
]->GetState (
4225 Private
->AbsolutePointerList
[Index
],
4228 if (!EFI_ERROR (Status
)) {
4229 if (ReturnStatus
== EFI_NOT_READY
) {
4230 ReturnStatus
= EFI_SUCCESS
;
4233 State
->ActiveButtons
= CurrentState
.ActiveButtons
;
4235 if (!(Private
->AbsolutePointerMode
.AbsoluteMinX
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxX
== 0)) {
4236 State
->CurrentX
= CurrentState
.CurrentX
;
4238 if (!(Private
->AbsolutePointerMode
.AbsoluteMinY
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxY
== 0)) {
4239 State
->CurrentY
= CurrentState
.CurrentY
;
4241 if (!(Private
->AbsolutePointerMode
.AbsoluteMinZ
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxZ
== 0)) {
4242 State
->CurrentZ
= CurrentState
.CurrentZ
;
4245 } else if (Status
== EFI_DEVICE_ERROR
) {
4246 ReturnStatus
= EFI_DEVICE_ERROR
;
4250 return ReturnStatus
;
4255 This event agregates all the events of the pointer devices in the splitter.
4256 If the ConIn is password locked then return.
4257 If any events of physical pointer devices are signaled, signal the pointer
4258 splitter event. This will cause the calling code to call
4259 ConSplitterAbsolutePointerGetState ().
4261 @param Event The Event assoicated with callback.
4262 @param Context Context registered when Event was created.
4269 ConSplitterAbsolutePointerWaitForInput (
4275 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4278 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4279 if (Private
->PasswordEnabled
) {
4281 // If StdIn Locked return not ready
4287 // if AbsoluteInputEventSignalState is flagged before,
4288 // and not cleared by Reset() or GetState(), signal it
4290 if (Private
->AbsoluteInputEventSignalState
) {
4291 gBS
->SignalEvent (Event
);
4295 // if any physical console input device has key input, signal the event.
4297 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4298 Status
= gBS
->CheckEvent (Private
->AbsolutePointerList
[Index
]->WaitForInput
);
4299 if (!EFI_ERROR (Status
)) {
4300 gBS
->SignalEvent (Event
);
4301 Private
->AbsoluteInputEventSignalState
= TRUE
;
4308 Reset the text output device hardware and optionaly run diagnostics
4310 @param This Protocol instance pointer.
4311 @param ExtendedVerification Driver may perform more exhaustive verfication
4312 operation of the device during reset.
4314 @retval EFI_SUCCESS The text output device was reset.
4315 @retval EFI_DEVICE_ERROR The text output device is not functioning
4316 correctly and could not be reset.
4321 ConSplitterTextOutReset (
4322 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4323 IN BOOLEAN ExtendedVerification
4327 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4329 EFI_STATUS ReturnStatus
;
4331 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4334 // return the worst status met
4336 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4338 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4340 Status
= Private
->TextOutList
[Index
].TextOut
->Reset (
4341 Private
->TextOutList
[Index
].TextOut
,
4342 ExtendedVerification
4344 if (EFI_ERROR (Status
)) {
4345 ReturnStatus
= Status
;
4350 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BLACK
));
4352 Status
= DevNullTextOutSetMode (Private
, 0);
4353 if (EFI_ERROR (Status
)) {
4354 ReturnStatus
= Status
;
4357 return ReturnStatus
;
4362 Write a Unicode string to the output device.
4364 @param This Protocol instance pointer.
4365 @param WString The NULL-terminated Unicode string to be
4366 displayed on the output device(s). All output
4367 devices must also support the Unicode drawing
4368 defined in this file.
4370 @retval EFI_SUCCESS The string was output to the device.
4371 @retval EFI_DEVICE_ERROR The device reported an error while attempting to
4373 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
4375 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
4376 characters in the Unicode string could not be
4377 rendered and were skipped.
4382 ConSplitterTextOutOutputString (
4383 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4388 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4390 UINTN BackSpaceCount
;
4391 EFI_STATUS ReturnStatus
;
4392 CHAR16
*TargetString
;
4394 This
->SetAttribute (This
, This
->Mode
->Attribute
);
4396 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4399 for (TargetString
= WString
; *TargetString
!= L
'\0'; TargetString
++) {
4400 if (*TargetString
== CHAR_BACKSPACE
) {
4406 if (BackSpaceCount
== 0) {
4407 TargetString
= WString
;
4409 TargetString
= AllocatePool (sizeof (CHAR16
) * (StrLen (WString
) + BackSpaceCount
+ 1));
4410 StrCpy (TargetString
, WString
);
4413 // return the worst status met
4415 Status
= DevNullTextOutOutputString (Private
, TargetString
);
4416 if (EFI_ERROR (Status
)) {
4417 ReturnStatus
= Status
;
4420 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4422 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4423 Status
= Private
->TextOutList
[Index
].TextOut
->OutputString (
4424 Private
->TextOutList
[Index
].TextOut
,
4427 if (EFI_ERROR (Status
)) {
4428 ReturnStatus
= Status
;
4433 if (BackSpaceCount
> 0) {
4434 FreePool (TargetString
);
4437 return ReturnStatus
;
4442 Verifies that all characters in a Unicode string can be output to the
4445 @param This Protocol instance pointer.
4446 @param WString The NULL-terminated Unicode string to be
4447 examined for the output device(s).
4449 @retval EFI_SUCCESS The device(s) are capable of rendering the
4451 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string
4452 cannot be rendered by one or more of the output
4453 devices mapped by the EFI handle.
4458 ConSplitterTextOutTestString (
4459 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4464 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4466 EFI_STATUS ReturnStatus
;
4468 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4471 // return the worst status met
4473 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4474 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4475 Status
= Private
->TextOutList
[Index
].TextOut
->TestString (
4476 Private
->TextOutList
[Index
].TextOut
,
4479 if (EFI_ERROR (Status
)) {
4480 ReturnStatus
= Status
;
4485 // There is no DevNullTextOutTestString () since a Unicode buffer would
4486 // always return EFI_SUCCESS.
4487 // ReturnStatus will be EFI_SUCCESS if no consoles are present
4489 return ReturnStatus
;
4494 Returns information for an available text mode that the output device(s)
4497 @param This Protocol instance pointer.
4498 @param ModeNumber The mode number to return information on.
4499 @param Columns Returns the columns of the text output device
4500 for the requested ModeNumber.
4501 @param Rows Returns the rows of the text output device
4502 for the requested ModeNumber.
4504 @retval EFI_SUCCESS The requested mode information was returned.
4505 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4507 @retval EFI_UNSUPPORTED The mode number was not valid.
4512 ConSplitterTextOutQueryMode (
4513 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4514 IN UINTN ModeNumber
,
4519 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4521 INT32
*TextOutModeMap
;
4523 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4526 // Check whether param ModeNumber is valid.
4527 // ModeNumber should be within range 0 ~ MaxMode - 1.
4529 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4530 return EFI_UNSUPPORTED
;
4533 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4534 return EFI_UNSUPPORTED
;
4538 // We get the available mode from mode intersection map if it's available
4540 if (Private
->TextOutModeMap
!= NULL
) {
4541 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4542 CurrentMode
= (UINTN
)(*TextOutModeMap
);
4543 *Columns
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4544 *Rows
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4546 *Columns
= Private
->TextOutQueryData
[ModeNumber
].Columns
;
4547 *Rows
= Private
->TextOutQueryData
[ModeNumber
].Rows
;
4550 if (*Columns
<= 0 && *Rows
<= 0) {
4551 return EFI_UNSUPPORTED
;
4560 Sets the output device(s) to a specified mode.
4562 @param This Protocol instance pointer.
4563 @param ModeNumber The mode number to set.
4565 @retval EFI_SUCCESS The requested text mode was set.
4566 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4568 @retval EFI_UNSUPPORTED The mode number was not valid.
4573 ConSplitterTextOutSetMode (
4574 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4579 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4581 INT32
*TextOutModeMap
;
4582 EFI_STATUS ReturnStatus
;
4584 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4587 // Check whether param ModeNumber is valid.
4588 // ModeNumber should be within range 0 ~ MaxMode - 1.
4590 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4591 return EFI_UNSUPPORTED
;
4594 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4595 return EFI_UNSUPPORTED
;
4598 // If the mode is being set to the curent mode, then just clear the screen and return.
4600 if (Private
->TextOutMode
.Mode
== (INT32
) ModeNumber
) {
4601 return ConSplitterTextOutClearScreen (This
);
4604 // return the worst status met
4606 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4607 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4609 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4610 Status
= Private
->TextOutList
[Index
].TextOut
->SetMode (
4611 Private
->TextOutList
[Index
].TextOut
,
4612 TextOutModeMap
[Index
]
4615 // If this console device is based on a GOP or UGA device, then sync up the bitmap from
4616 // the GOP/UGA splitter and reclear the text portion of the display in the new mode.
4618 if ((Private
->TextOutList
[Index
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[Index
].UgaDraw
!= NULL
)) {
4619 Private
->TextOutList
[Index
].TextOut
->ClearScreen (Private
->TextOutList
[Index
].TextOut
);
4622 if (EFI_ERROR (Status
)) {
4623 ReturnStatus
= Status
;
4628 // The DevNull Console will support any possible mode as it allocates memory
4630 Status
= DevNullTextOutSetMode (Private
, ModeNumber
);
4631 if (EFI_ERROR (Status
)) {
4632 ReturnStatus
= Status
;
4635 return ReturnStatus
;
4640 Sets the background and foreground colors for the OutputString () and
4641 ClearScreen () functions.
4643 @param This Protocol instance pointer.
4644 @param Attribute The attribute to set. Bits 0..3 are the
4645 foreground color, and bits 4..6 are the
4646 background color. All other bits are undefined
4647 and must be zero. The valid Attributes are
4648 defined in this file.
4650 @retval EFI_SUCCESS The attribute was set.
4651 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4653 @retval EFI_UNSUPPORTED The attribute requested is not defined.
4658 ConSplitterTextOutSetAttribute (
4659 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4664 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4666 EFI_STATUS ReturnStatus
;
4668 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4671 // Check whether param Attribute is valid.
4673 if ( (Attribute
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4674 return EFI_UNSUPPORTED
;
4678 // return the worst status met
4680 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4682 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4683 Status
= Private
->TextOutList
[Index
].TextOut
->SetAttribute (
4684 Private
->TextOutList
[Index
].TextOut
,
4687 if (EFI_ERROR (Status
)) {
4688 ReturnStatus
= Status
;
4693 Private
->TextOutMode
.Attribute
= (INT32
) Attribute
;
4695 return ReturnStatus
;
4700 Clears the output device(s) display to the currently selected background
4703 @param This Protocol instance pointer.
4705 @retval EFI_SUCCESS The operation completed successfully.
4706 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4708 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4713 ConSplitterTextOutClearScreen (
4714 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
4718 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4720 EFI_STATUS ReturnStatus
;
4722 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4725 // return the worst status met
4727 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4729 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4730 Status
= Private
->TextOutList
[Index
].TextOut
->ClearScreen (Private
->TextOutList
[Index
].TextOut
);
4731 if (EFI_ERROR (Status
)) {
4732 ReturnStatus
= Status
;
4737 Status
= DevNullTextOutClearScreen (Private
);
4738 if (EFI_ERROR (Status
)) {
4739 ReturnStatus
= Status
;
4742 return ReturnStatus
;
4747 Sets the current coordinates of the cursor position
4749 @param This Protocol instance pointer.
4750 @param Column The column position to set the cursor to. Must be
4751 greater than or equal to zero and less than the
4752 number of columns by QueryMode ().
4753 @param Row The row position to set the cursor to. Must be
4754 greater than or equal to zero and less than the
4755 number of rows by QueryMode ().
4757 @retval EFI_SUCCESS The operation completed successfully.
4758 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4760 @retval EFI_UNSUPPORTED The output device is not in a valid text mode,
4761 or the cursor position is invalid for the
4767 ConSplitterTextOutSetCursorPosition (
4768 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4774 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4776 EFI_STATUS ReturnStatus
;
4779 INT32
*TextOutModeMap
;
4783 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4784 TextOutModeMap
= NULL
;
4785 ModeNumber
= Private
->TextOutMode
.Mode
;
4788 // Get current MaxColumn and MaxRow from intersection map
4790 if (Private
->TextOutModeMap
!= NULL
) {
4791 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4792 CurrentMode
= *TextOutModeMap
;
4794 CurrentMode
= ModeNumber
;
4797 MaxColumn
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4798 MaxRow
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4800 if (Column
>= MaxColumn
|| Row
>= MaxRow
) {
4801 return EFI_UNSUPPORTED
;
4804 // return the worst status met
4806 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4808 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4809 Status
= Private
->TextOutList
[Index
].TextOut
->SetCursorPosition (
4810 Private
->TextOutList
[Index
].TextOut
,
4814 if (EFI_ERROR (Status
)) {
4815 ReturnStatus
= Status
;
4820 DevNullTextOutSetCursorPosition (Private
, Column
, Row
);
4822 return ReturnStatus
;
4827 Makes the cursor visible or invisible
4829 @param This Protocol instance pointer.
4830 @param Visible If TRUE, the cursor is set to be visible. If
4831 FALSE, the cursor is set to be invisible.
4833 @retval EFI_SUCCESS The operation completed successfully.
4834 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4835 the request, or the device does not support
4836 changing the cursor mode.
4837 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4842 ConSplitterTextOutEnableCursor (
4843 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4848 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4850 EFI_STATUS ReturnStatus
;
4852 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4855 // return the worst status met
4857 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4859 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4860 Status
= Private
->TextOutList
[Index
].TextOut
->EnableCursor (
4861 Private
->TextOutList
[Index
].TextOut
,
4864 if (EFI_ERROR (Status
)) {
4865 ReturnStatus
= Status
;
4870 DevNullTextOutEnableCursor (Private
, Visible
);
4872 return ReturnStatus
;