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
1757 // grow the buffer to new buffer size,
1758 // copy the old buffer's content to the new-size buffer,
1759 // then free the old buffer.
1761 OldSize
= *Count
* SizeOfCount
;
1762 *Count
+= CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT
;
1763 NewSize
= *Count
* SizeOfCount
;
1765 Ptr
= AllocateZeroPool (NewSize
);
1767 return EFI_OUT_OF_RESOURCES
;
1770 CopyMem (Ptr
, *Buffer
, OldSize
);
1772 if (*Buffer
!= NULL
) {
1783 Add Text Input Device in Consplitter Text Input list.
1785 @param Private Text In Splitter pointer.
1786 @param TextIn Simple Text Input protocol pointer.
1788 @retval EFI_SUCCESS Text Input Device added successfully.
1789 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1793 ConSplitterTextInAddDevice (
1794 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1795 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1801 // If the Text In List is full, enlarge it by calling growbuffer().
1803 if (Private
->CurrentNumberOfConsoles
>= Private
->TextInListCount
) {
1804 Status
= ConSplitterGrowBuffer (
1805 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
1806 &Private
->TextInListCount
,
1807 (VOID
**) &Private
->TextInList
1809 if (EFI_ERROR (Status
)) {
1810 return EFI_OUT_OF_RESOURCES
;
1814 // Add the new text-in device data structure into the Text In List.
1816 Private
->TextInList
[Private
->CurrentNumberOfConsoles
] = TextIn
;
1817 Private
->CurrentNumberOfConsoles
++;
1820 // Extra CheckEvent added to reduce the double CheckEvent() in UI.c
1822 gBS
->CheckEvent (TextIn
->WaitForKey
);
1829 Remove Simple Text Device in Consplitter Absolute Pointer list.
1831 @param Private Text In Splitter pointer.
1832 @param TextIn Simple Text protocol pointer.
1834 @retval EFI_SUCCESS Simple Text Device removed successfully.
1835 @retval EFI_NOT_FOUND No Simple Text Device found.
1839 ConSplitterTextInDeleteDevice (
1840 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1841 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1846 // Remove the specified text-in device data structure from the Text In List,
1847 // and rearrange the remaining data structures in the Text In List.
1849 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
1850 if (Private
->TextInList
[Index
] == TextIn
) {
1851 for (Index
= Index
; Index
< Private
->CurrentNumberOfConsoles
- 1; Index
++) {
1852 Private
->TextInList
[Index
] = Private
->TextInList
[Index
+ 1];
1855 Private
->CurrentNumberOfConsoles
--;
1860 return EFI_NOT_FOUND
;
1864 Add Text Input Ex Device in Consplitter Text Input Ex list.
1866 @param Private Text In Splitter pointer.
1867 @param TextInEx Simple Text Ex Input protocol pointer.
1869 @retval EFI_SUCCESS Text Input Ex Device added successfully.
1870 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1874 ConSplitterTextInExAddDevice (
1875 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1876 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1882 // If the TextInEx List is full, enlarge it by calling growbuffer().
1884 if (Private
->CurrentNumberOfExConsoles
>= Private
->TextInExListCount
) {
1885 Status
= ConSplitterGrowBuffer (
1886 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
1887 &Private
->TextInExListCount
,
1888 (VOID
**) &Private
->TextInExList
1890 if (EFI_ERROR (Status
)) {
1891 return EFI_OUT_OF_RESOURCES
;
1895 // Add the new text-in device data structure into the Text In List.
1897 Private
->TextInExList
[Private
->CurrentNumberOfExConsoles
] = TextInEx
;
1898 Private
->CurrentNumberOfExConsoles
++;
1901 // Extra CheckEvent added to reduce the double CheckEvent() in UI.c
1903 gBS
->CheckEvent (TextInEx
->WaitForKeyEx
);
1909 Remove Simple Text Ex Device in Consplitter Absolute Pointer list.
1911 @param Private Text In Splitter pointer.
1912 @param TextInEx Simple Text Ex protocol pointer.
1914 @retval EFI_SUCCESS Simple Text Ex Device removed successfully.
1915 @retval EFI_NOT_FOUND No Simple Text Ex Device found.
1919 ConSplitterTextInExDeleteDevice (
1920 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1921 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1926 // Remove the specified text-in device data structure from the Text In List,
1927 // and rearrange the remaining data structures in the Text In List.
1929 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
1930 if (Private
->TextInExList
[Index
] == TextInEx
) {
1931 for (Index
= Index
; Index
< Private
->CurrentNumberOfExConsoles
- 1; Index
++) {
1932 Private
->TextInExList
[Index
] = Private
->TextInExList
[Index
+ 1];
1935 Private
->CurrentNumberOfExConsoles
--;
1940 return EFI_NOT_FOUND
;
1945 Add Simple Pointer Device in Consplitter Simple Pointer list.
1947 @param Private Text In Splitter pointer.
1948 @param SimplePointer Simple Pointer protocol pointer.
1950 @retval EFI_SUCCESS Simple Pointer Device added successfully.
1951 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1955 ConSplitterSimplePointerAddDevice (
1956 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1957 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
1963 // If the Text In List is full, enlarge it by calling growbuffer().
1965 if (Private
->CurrentNumberOfPointers
>= Private
->PointerListCount
) {
1966 Status
= ConSplitterGrowBuffer (
1967 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
1968 &Private
->PointerListCount
,
1969 (VOID
**) &Private
->PointerList
1971 if (EFI_ERROR (Status
)) {
1972 return EFI_OUT_OF_RESOURCES
;
1976 // Add the new text-in device data structure into the Text In List.
1978 Private
->PointerList
[Private
->CurrentNumberOfPointers
] = SimplePointer
;
1979 Private
->CurrentNumberOfPointers
++;
1985 Remove Simple Pointer Device in Consplitter Absolute Pointer list.
1987 @param Private Text In Splitter pointer.
1988 @param SimplePointer Simple Pointer protocol pointer.
1990 @retval EFI_SUCCESS Simple Pointer Device removed successfully.
1991 @retval EFI_NOT_FOUND No Simple Pointer Device found.
1995 ConSplitterSimplePointerDeleteDevice (
1996 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1997 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
2002 // Remove the specified text-in device data structure from the Text In List,
2003 // and rearrange the remaining data structures in the Text In List.
2005 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
2006 if (Private
->PointerList
[Index
] == SimplePointer
) {
2007 for (Index
= Index
; Index
< Private
->CurrentNumberOfPointers
- 1; Index
++) {
2008 Private
->PointerList
[Index
] = Private
->PointerList
[Index
+ 1];
2011 Private
->CurrentNumberOfPointers
--;
2016 return EFI_NOT_FOUND
;
2021 Add Absolute Pointer Device in Consplitter Absolute Pointer list.
2023 @param Private Text In Splitter pointer.
2024 @param AbsolutePointer Absolute Pointer protocol pointer.
2026 @retval EFI_SUCCESS Absolute Pointer Device added successfully.
2027 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2031 ConSplitterAbsolutePointerAddDevice (
2032 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2033 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2039 // If the Absolute Pointer List is full, enlarge it by calling growbuffer().
2041 if (Private
->CurrentNumberOfAbsolutePointers
>= Private
->AbsolutePointerListCount
) {
2042 Status
= ConSplitterGrowBuffer (
2043 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
2044 &Private
->AbsolutePointerListCount
,
2045 (VOID
**) &Private
->AbsolutePointerList
2047 if (EFI_ERROR (Status
)) {
2048 return EFI_OUT_OF_RESOURCES
;
2052 // Add the new text-in device data structure into the Text In List.
2054 Private
->AbsolutePointerList
[Private
->CurrentNumberOfAbsolutePointers
] = AbsolutePointer
;
2055 Private
->CurrentNumberOfAbsolutePointers
++;
2061 Remove Absolute Pointer Device in Consplitter Absolute Pointer list.
2063 @param Private Text In Splitter pointer.
2064 @param AbsolutePointer Absolute Pointer protocol pointer.
2066 @retval EFI_SUCCESS Absolute Pointer Device removed successfully.
2067 @retval EFI_NOT_FOUND No Absolute Pointer Device found.
2071 ConSplitterAbsolutePointerDeleteDevice (
2072 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2073 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2078 // Remove the specified text-in device data structure from the Text In List,
2079 // and rearrange the remaining data structures in the Text In List.
2081 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
2082 if (Private
->AbsolutePointerList
[Index
] == AbsolutePointer
) {
2083 for (Index
= Index
; Index
< Private
->CurrentNumberOfAbsolutePointers
- 1; Index
++) {
2084 Private
->AbsolutePointerList
[Index
] = Private
->AbsolutePointerList
[Index
+ 1];
2087 Private
->CurrentNumberOfAbsolutePointers
--;
2092 return EFI_NOT_FOUND
;
2096 Reallocate Text Out mode map.
2098 @param Private Consplitter Text Out pointer.
2100 @retval EFI_SUCCESS Buffer size has grown
2101 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2105 ConSplitterGrowMapTable (
2106 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2112 INT32
*TextOutModeMap
;
2113 INT32
*OldTextOutModeMap
;
2117 NewSize
= Private
->TextOutListCount
* sizeof (INT32
);
2118 OldTextOutModeMap
= Private
->TextOutModeMap
;
2119 TotalSize
= NewSize
* Private
->TextOutQueryDataCount
;
2121 TextOutModeMap
= AllocateZeroPool (TotalSize
);
2122 if (TextOutModeMap
== NULL
) {
2123 return EFI_OUT_OF_RESOURCES
;
2126 SetMem (TextOutModeMap
, TotalSize
, 0xFF);
2127 Private
->TextOutModeMap
= TextOutModeMap
;
2130 // If TextOutList has been enlarged, need to realloc the mode map table
2131 // The mode map table is regarded as a two dimension array.
2134 // 0 ---------> TextOutListCount ----> TextOutListCount
2135 // | -------------------------------------------
2142 // -------------------------------------------
2145 if (OldTextOutModeMap
!= NULL
) {
2147 Size
= Private
->CurrentNumberOfConsoles
* sizeof (INT32
);
2149 SrcAddress
= OldTextOutModeMap
;
2152 // Copy the old data to the new one
2154 while (Index
< Private
->TextOutMode
.MaxMode
) {
2155 CopyMem (TextOutModeMap
, SrcAddress
, Size
);
2156 TextOutModeMap
+= NewSize
;
2161 // Free the old buffer
2163 FreePool (OldTextOutModeMap
);
2171 Add the device's output mode to console splitter's mode list.
2173 @param Private Text Out Splitter pointer
2174 @param TextOut Simple Text Output protocol pointer.
2176 @retval EFI_SUCCESS Device added successfully.
2177 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2181 ConSplitterAddOutputMode (
2182 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2183 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2191 MaxMode
= TextOut
->Mode
->MaxMode
;
2192 Private
->TextOutMode
.MaxMode
= MaxMode
;
2195 // Grow the buffer if query data buffer is not large enough to
2196 // hold all the mode supported by the first console.
2198 while (MaxMode
> (INT32
) Private
->TextOutQueryDataCount
) {
2199 Status
= ConSplitterGrowBuffer (
2200 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
2201 &Private
->TextOutQueryDataCount
,
2202 (VOID
**) &Private
->TextOutQueryData
2204 if (EFI_ERROR (Status
)) {
2205 return EFI_OUT_OF_RESOURCES
;
2209 // Allocate buffer for the output mode map
2211 Status
= ConSplitterGrowMapTable (Private
);
2212 if (EFI_ERROR (Status
)) {
2213 return EFI_OUT_OF_RESOURCES
;
2216 // As the first textout device, directly add the mode in to QueryData
2217 // and at the same time record the mapping between QueryData and TextOut.
2221 while (Mode
< MaxMode
) {
2222 Status
= TextOut
->QueryMode (
2225 &Private
->TextOutQueryData
[Mode
].Columns
,
2226 &Private
->TextOutQueryData
[Mode
].Rows
2229 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData
2232 if ((EFI_ERROR(Status
)) && (Mode
== 1)) {
2233 Private
->TextOutQueryData
[Mode
].Columns
= 0;
2234 Private
->TextOutQueryData
[Mode
].Rows
= 0;
2236 Private
->TextOutModeMap
[Index
] = Mode
;
2238 Index
+= Private
->TextOutListCount
;
2245 Reconstruct TextOutModeMap to get intersection of modes.
2247 This routine reconstruct TextOutModeMap to get the intersection
2248 of modes for all console out devices. Because EFI/UEFI spec require
2249 mode 0 is 80x25, mode 1 is 80x50, this routine will not check the
2250 intersection for mode 0 and mode 1.
2252 @param TextOutModeMap Current text out mode map, begin with the mode 80x25
2253 @param NewlyAddedMap New text out mode map, begin with the mode 80x25
2254 @param MapStepSize Mode step size for one console device
2255 @param NewMapStepSize Mode step size for one console device
2256 @param MaxMode Current max text mode
2257 @param CurrentMode Current text mode
2261 ConSplitterGetIntersection (
2262 IN INT32
*TextOutModeMap
,
2263 IN INT32
*NewlyAddedMap
,
2264 IN UINTN MapStepSize
,
2265 IN UINTN NewMapStepSize
,
2267 OUT INT32
*CurrentMode
2271 INT32
*CurrentMapEntry
;
2272 INT32
*NextMapEntry
;
2273 INT32 CurrentMaxMode
;
2277 // According to EFI/UEFI spec, mode 0 and mode 1 have been reserved
2278 // for 80x25 and 80x50 in Simple Text Out protocol, so don't make intersection
2279 // for mode 0 and mode 1, mode number starts from 2.
2282 CurrentMapEntry
= &TextOutModeMap
[MapStepSize
* 2];
2283 NextMapEntry
= &TextOutModeMap
[MapStepSize
* 2];
2284 NewlyAddedMap
= &NewlyAddedMap
[NewMapStepSize
* 2];
2286 CurrentMaxMode
= *MaxMode
;
2287 Mode
= *CurrentMode
;
2289 while (Index
< CurrentMaxMode
) {
2290 if (*NewlyAddedMap
== -1) {
2292 // This mode is not supported any more. Remove it. Special care
2293 // must be taken as this remove will also affect current mode;
2295 if (Index
== *CurrentMode
) {
2297 } else if (Index
< *CurrentMode
) {
2302 if (CurrentMapEntry
!= NextMapEntry
) {
2303 CopyMem (NextMapEntry
, CurrentMapEntry
, MapStepSize
* sizeof (INT32
));
2306 NextMapEntry
+= MapStepSize
;
2309 CurrentMapEntry
+= MapStepSize
;
2310 NewlyAddedMap
+= NewMapStepSize
;
2314 *CurrentMode
= Mode
;
2321 Add the device's output mode to console splitter's mode list.
2323 @param Private Text Out Splitter pointer.
2324 @param TextOut Simple Text Output protocol pointer.
2330 ConSplitterSyncOutputMode (
2331 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2332 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2335 INT32 CurrentMaxMode
;
2338 INT32
*TextOutModeMap
;
2341 TEXT_OUT_SPLITTER_QUERY_DATA
*TextOutQueryData
;
2348 // Must make sure that current mode won't change even if mode number changes
2350 CurrentMaxMode
= Private
->TextOutMode
.MaxMode
;
2351 TextOutModeMap
= Private
->TextOutModeMap
;
2352 StepSize
= Private
->TextOutListCount
;
2353 TextOutQueryData
= Private
->TextOutQueryData
;
2356 // Query all the mode that the newly added TextOut supports
2359 MapTable
= TextOutModeMap
+ Private
->CurrentNumberOfConsoles
;
2360 while (Mode
< TextOut
->Mode
->MaxMode
) {
2361 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Columns
, &Rows
);
2362 if (EFI_ERROR(Status
)) {
2364 MapTable
[StepSize
] = Mode
;
2365 TextOutQueryData
[Mode
].Columns
= 0;
2366 TextOutQueryData
[Mode
].Rows
= 0;
2372 // Search the intersection map and QueryData database to see if they intersects
2375 while (Index
< CurrentMaxMode
) {
2376 QueryMode
= *(TextOutModeMap
+ Index
* StepSize
);
2377 if ((TextOutQueryData
[QueryMode
].Rows
== Rows
) && (TextOutQueryData
[QueryMode
].Columns
== Columns
)) {
2378 MapTable
[Index
* StepSize
] = Mode
;
2388 // Now search the TextOutModeMap table to find the intersection of supported
2389 // mode between ConSplitter and the newly added device.
2391 ConSplitterGetIntersection (
2396 &Private
->TextOutMode
.MaxMode
,
2397 &Private
->TextOutMode
.Mode
2405 Sync output device between ConOut and StdErr output.
2407 @retval EFI_SUCCESS Sync implemented successfully.
2408 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2412 ConSplitterGetIntersectionBetweenConOutAndStrErr (
2416 UINTN ConOutNumOfConsoles
;
2417 UINTN StdErrNumOfConsoles
;
2418 TEXT_OUT_AND_GOP_DATA
*ConOutTextOutList
;
2419 TEXT_OUT_AND_GOP_DATA
*StdErrTextOutList
;
2423 UINTN ConOutColumns
;
2425 UINTN StdErrColumns
;
2426 INT32 ConOutMaxMode
;
2427 INT32 StdErrMaxMode
;
2432 INT32
*ConOutModeMap
;
2433 INT32
*StdErrModeMap
;
2434 INT32
*ConOutMapTable
;
2435 INT32
*StdErrMapTable
;
2436 TEXT_OUT_SPLITTER_QUERY_DATA
*ConOutQueryData
;
2437 TEXT_OUT_SPLITTER_QUERY_DATA
*StdErrQueryData
;
2438 UINTN ConOutStepSize
;
2439 UINTN StdErrStepSize
;
2440 BOOLEAN FoundTheSameTextOut
;
2441 UINTN ConOutMapTableSize
;
2442 UINTN StdErrMapTableSize
;
2444 ConOutNumOfConsoles
= mConOut
.CurrentNumberOfConsoles
;
2445 StdErrNumOfConsoles
= mStdErr
.CurrentNumberOfConsoles
;
2446 ConOutTextOutList
= mConOut
.TextOutList
;
2447 StdErrTextOutList
= mStdErr
.TextOutList
;
2450 FoundTheSameTextOut
= FALSE
;
2451 while ((Indexi
< ConOutNumOfConsoles
) && (!FoundTheSameTextOut
)) {
2453 while (Indexj
< StdErrNumOfConsoles
) {
2454 if (ConOutTextOutList
->TextOut
== StdErrTextOutList
->TextOut
) {
2455 FoundTheSameTextOut
= TRUE
;
2460 StdErrTextOutList
++;
2464 ConOutTextOutList
++;
2467 if (!FoundTheSameTextOut
) {
2471 // Must make sure that current mode won't change even if mode number changes
2473 ConOutMaxMode
= mConOut
.TextOutMode
.MaxMode
;
2474 ConOutModeMap
= mConOut
.TextOutModeMap
;
2475 ConOutStepSize
= mConOut
.TextOutListCount
;
2476 ConOutQueryData
= mConOut
.TextOutQueryData
;
2478 StdErrMaxMode
= mStdErr
.TextOutMode
.MaxMode
;
2479 StdErrModeMap
= mStdErr
.TextOutModeMap
;
2480 StdErrStepSize
= mStdErr
.TextOutListCount
;
2481 StdErrQueryData
= mStdErr
.TextOutQueryData
;
2484 // Allocate the map table and set the map table's index to -1.
2486 ConOutMapTableSize
= ConOutMaxMode
* sizeof (INT32
);
2487 ConOutMapTable
= AllocateZeroPool (ConOutMapTableSize
);
2488 if (ConOutMapTable
== NULL
) {
2489 return EFI_OUT_OF_RESOURCES
;
2492 SetMem (ConOutMapTable
, ConOutMapTableSize
, 0xFF);
2494 StdErrMapTableSize
= StdErrMaxMode
* sizeof (INT32
);
2495 StdErrMapTable
= AllocateZeroPool (StdErrMapTableSize
);
2496 if (StdErrMapTable
== NULL
) {
2497 return EFI_OUT_OF_RESOURCES
;
2500 SetMem (StdErrMapTable
, StdErrMapTableSize
, 0xFF);
2503 // Find the intersection of the two set of modes. If they actually intersect, the
2504 // correponding entry in the map table is set to 1.
2507 while (Mode
< ConOutMaxMode
) {
2509 // Search the intersection map and QueryData database to see if they intersect
2512 ConOutMode
= *(ConOutModeMap
+ Mode
* ConOutStepSize
);
2513 ConOutRows
= ConOutQueryData
[ConOutMode
].Rows
;
2514 ConOutColumns
= ConOutQueryData
[ConOutMode
].Columns
;
2515 while (Index
< StdErrMaxMode
) {
2516 StdErrMode
= *(StdErrModeMap
+ Index
* StdErrStepSize
);
2517 StdErrRows
= StdErrQueryData
[StdErrMode
].Rows
;
2518 StdErrColumns
= StdErrQueryData
[StdErrMode
].Columns
;
2519 if ((StdErrRows
== ConOutRows
) && (StdErrColumns
== ConOutColumns
)) {
2520 ConOutMapTable
[Mode
] = 1;
2521 StdErrMapTable
[Index
] = 1;
2531 // Now search the TextOutModeMap table to find the intersection of supported
2532 // mode between ConSplitter and the newly added device.
2534 ConSplitterGetIntersection (
2537 mConOut
.TextOutListCount
,
2539 &(mConOut
.TextOutMode
.MaxMode
),
2540 &(mConOut
.TextOutMode
.Mode
)
2542 if (mConOut
.TextOutMode
.Mode
< 0) {
2543 mConOut
.TextOut
.SetMode (&(mConOut
.TextOut
), 0);
2546 ConSplitterGetIntersection (
2549 mStdErr
.TextOutListCount
,
2551 &(mStdErr
.TextOutMode
.MaxMode
),
2552 &(mStdErr
.TextOutMode
.Mode
)
2554 if (mStdErr
.TextOutMode
.Mode
< 0) {
2555 mStdErr
.TextOut
.SetMode (&(mStdErr
.TextOut
), 0);
2558 FreePool (ConOutMapTable
);
2559 FreePool (StdErrMapTable
);
2566 Add GOP or UGA output mode into Consplitter Text Out list.
2568 @param Private Text Out Splitter pointer.
2569 @param GraphicsOutput Graphics Output protocol pointer.
2570 @param UgaDraw UGA Draw protocol pointer.
2572 @retval EFI_SUCCESS Output mode added successfully.
2573 @retval other Failed to add output mode.
2577 ConSplitterAddGraphicsOutputMode (
2578 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2579 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2580 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2586 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
;
2588 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
2589 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*CurrentGraphicsOutputMode
;
2590 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*ModeBuffer
;
2591 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*MatchedMode
;
2594 BOOLEAN AlreadyExist
;
2595 UINT32 UgaHorizontalResolution
;
2596 UINT32 UgaVerticalResolution
;
2597 UINT32 UgaColorDepth
;
2598 UINT32 UgaRefreshRate
;
2600 if ((GraphicsOutput
== NULL
) && (UgaDraw
== NULL
)) {
2601 return EFI_UNSUPPORTED
;
2604 CurrentGraphicsOutputMode
= Private
->GraphicsOutput
.Mode
;
2609 if (Private
->CurrentNumberOfUgaDraw
!= 0) {
2611 // If any UGA device has already been added, then there is no need to
2612 // calculate intersection of display mode of different GOP/UGA device,
2613 // since only one display mode will be exported (i.e. user-defined mode)
2618 if (GraphicsOutput
!= NULL
) {
2619 if (Private
->CurrentNumberOfGraphicsOutput
== 0) {
2621 // This is the first Graphics Output device added
2623 CurrentGraphicsOutputMode
->MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
2624 CurrentGraphicsOutputMode
->Mode
= GraphicsOutput
->Mode
->Mode
;
2625 CopyMem (CurrentGraphicsOutputMode
->Info
, GraphicsOutput
->Mode
->Info
, GraphicsOutput
->Mode
->SizeOfInfo
);
2626 CurrentGraphicsOutputMode
->SizeOfInfo
= GraphicsOutput
->Mode
->SizeOfInfo
;
2627 CurrentGraphicsOutputMode
->FrameBufferBase
= GraphicsOutput
->Mode
->FrameBufferBase
;
2628 CurrentGraphicsOutputMode
->FrameBufferSize
= GraphicsOutput
->Mode
->FrameBufferSize
;
2631 // Allocate resource for the private mode buffer
2633 ModeBuffer
= AllocatePool (GraphicsOutput
->Mode
->SizeOfInfo
* GraphicsOutput
->Mode
->MaxMode
);
2634 if (ModeBuffer
== NULL
) {
2635 return EFI_OUT_OF_RESOURCES
;
2637 FreePool (Private
->GraphicsOutputModeBuffer
);
2638 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2641 // Store all supported display modes to the private mode buffer
2644 for (Index
= 0; Index
< GraphicsOutput
->Mode
->MaxMode
; Index
++) {
2645 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) Index
, &SizeOfInfo
, &Info
);
2646 if (EFI_ERROR (Status
)) {
2649 CopyMem (Mode
, Info
, SizeOfInfo
);
2655 // Check intersection of display mode
2657 ModeBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
) * CurrentGraphicsOutputMode
->MaxMode
);
2658 if (ModeBuffer
== NULL
) {
2659 return EFI_OUT_OF_RESOURCES
;
2662 MatchedMode
= ModeBuffer
;
2663 Mode
= &Private
->GraphicsOutputModeBuffer
[0];
2664 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2667 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
2668 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
2669 if (EFI_ERROR (Status
)) {
2672 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2673 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2682 AlreadyExist
= FALSE
;
2684 for (Info
= ModeBuffer
; Info
< MatchedMode
; Info
++) {
2685 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2686 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2687 AlreadyExist
= TRUE
;
2692 if (!AlreadyExist
) {
2693 CopyMem (MatchedMode
, Mode
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2696 // Physical frame buffer is no longer available, change PixelFormat to PixelBltOnly
2698 MatchedMode
->Version
= 0;
2699 MatchedMode
->PixelFormat
= PixelBltOnly
;
2700 ZeroMem (&MatchedMode
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2710 // Drop the old mode buffer, assign it to a new one
2712 FreePool (Private
->GraphicsOutputModeBuffer
);
2713 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2716 // Physical frame buffer is no longer available when there are more than one physical GOP devices
2718 CurrentGraphicsOutputMode
->MaxMode
= (UINT32
) (((UINTN
) MatchedMode
- (UINTN
) ModeBuffer
) / sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2719 CurrentGraphicsOutputMode
->Info
->PixelFormat
= PixelBltOnly
;
2720 ZeroMem (&CurrentGraphicsOutputMode
->Info
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2721 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2722 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2723 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2727 // Graphics console driver can ensure the same mode for all GOP devices
2729 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2730 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2731 if ((Mode
->HorizontalResolution
== GraphicsOutput
->Mode
->Info
->HorizontalResolution
) &&
2732 (Mode
->VerticalResolution
== GraphicsOutput
->Mode
->Info
->VerticalResolution
)) {
2733 CurrentIndex
= Index
;
2737 if (Index
>= CurrentGraphicsOutputMode
->MaxMode
) {
2739 // if user defined mode is not found, set to default mode 800x600
2741 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2742 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2743 if ((Mode
->HorizontalResolution
== 800) && (Mode
->VerticalResolution
== 600)) {
2744 CurrentIndex
= Index
;
2750 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2752 // Graphics console driver can ensure the same mode for all GOP devices
2753 // so we can get the current mode from this video device
2757 &UgaHorizontalResolution
,
2758 &UgaVerticalResolution
,
2763 CurrentGraphicsOutputMode
->MaxMode
= 1;
2764 Info
= CurrentGraphicsOutputMode
->Info
;
2766 Info
->HorizontalResolution
= UgaHorizontalResolution
;
2767 Info
->VerticalResolution
= UgaVerticalResolution
;
2768 Info
->PixelFormat
= PixelBltOnly
;
2769 Info
->PixelsPerScanLine
= UgaHorizontalResolution
;
2770 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2771 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2772 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2775 // Update the private mode buffer
2777 CopyMem (&Private
->GraphicsOutputModeBuffer
[0], Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2780 // Only mode 0 is available to be set
2787 if (GraphicsOutput
!= NULL
) {
2788 Private
->CurrentNumberOfGraphicsOutput
++;
2790 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2791 Private
->CurrentNumberOfUgaDraw
++;
2795 // Force GraphicsOutput mode to be set,
2796 // regardless whether the console is in EfiConsoleControlScreenGraphics or EfiConsoleControlScreenText mode
2798 Private
->HardwareNeedsStarting
= TRUE
;
2800 // Current mode number may need update now, so set it to an invalid mode number
2802 CurrentGraphicsOutputMode
->Mode
= 0xffff;
2804 // Graphics console can ensure all GOP devices have the same mode which can be taken as current mode.
2806 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, (UINT32
) CurrentIndex
);
2809 // If user defined mode is not valid for UGA, set to the default mode 800x600.
2811 if (EFI_ERROR(Status
)) {
2812 (Private
->GraphicsOutputModeBuffer
[0]).HorizontalResolution
= 800;
2813 (Private
->GraphicsOutputModeBuffer
[0]).VerticalResolution
= 600;
2814 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, 0);
2822 This routine will get the current console mode information (column, row)
2823 from ConsoleOutMode variable and set it; if the variable does not exist,
2824 set to user defined console mode.
2826 @param Private Consplitter Text Out pointer.
2832 ConsplitterSetConsoleOutMode (
2833 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2844 CONSOLE_OUT_MODE
*ModeInfo
;
2845 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
2849 TextOut
= &Private
->TextOut
;
2850 MaxMode
= (UINTN
) (TextOut
->Mode
->MaxMode
);
2851 ModeInfoSize
= sizeof (CONSOLE_OUT_MODE
);
2853 ModeInfo
= AllocateZeroPool (sizeof(CONSOLE_OUT_MODE
));
2854 ASSERT(ModeInfo
!= NULL
);
2856 Status
= gRT
->GetVariable (
2858 &gEfiGenericPlatformVariableGuid
,
2865 // Set to the default mode 80 x 25 required by EFI/UEFI spec;
2866 // user can also define other valid default console mode here.
2868 if (EFI_ERROR(Status
)) {
2869 ModeInfo
->Column
= 80;
2871 Status
= gRT
->SetVariable (
2873 &gEfiGenericPlatformVariableGuid
,
2874 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
2875 sizeof (CONSOLE_OUT_MODE
),
2880 for (Mode
= 0; Mode
< MaxMode
; Mode
++) {
2881 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Col
, &Row
);
2882 if (!EFI_ERROR(Status
)) {
2883 if (Col
== ModeInfo
->Column
&& Row
== ModeInfo
->Row
) {
2886 if (Col
== 80 && Row
== 25) {
2892 Status
= TextOut
->SetMode (TextOut
, PreferMode
);
2895 // if current mode setting is failed, default 80x25 mode will be set.
2897 if (EFI_ERROR(Status
)) {
2898 Status
= TextOut
->SetMode (TextOut
, BaseMode
);
2899 ASSERT(!EFI_ERROR(Status
));
2901 ModeInfo
->Column
= 80;
2905 // Update ConOutMode variable
2907 Status
= gRT
->SetVariable (
2909 &gEfiGenericPlatformVariableGuid
,
2910 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
2911 sizeof (CONSOLE_OUT_MODE
),
2916 gBS
->FreePool (ModeInfo
);
2921 Add Text Output Device in Consplitter Text Output list.
2923 @param Private Text Out Splitter pointer.
2924 @param TextOut Simple Text Output protocol pointer.
2925 @param GraphicsOutput Graphics Output protocol pointer.
2926 @param UgaDraw UGA Draw protocol pointer.
2928 @retval EFI_SUCCESS Text Output Device added successfully.
2929 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2933 ConSplitterTextOutAddDevice (
2934 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2935 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
,
2936 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2937 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2941 UINTN CurrentNumOfConsoles
;
2944 UINT32 UgaHorizontalResolution
;
2945 UINT32 UgaVerticalResolution
;
2946 UINT32 UgaColorDepth
;
2947 UINT32 UgaRefreshRate
;
2948 TEXT_OUT_AND_GOP_DATA
*TextAndGop
;
2950 Status
= EFI_SUCCESS
;
2951 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
2954 // If the Text Out List is full, enlarge it by calling growbuffer().
2956 while (CurrentNumOfConsoles
>= Private
->TextOutListCount
) {
2957 Status
= ConSplitterGrowBuffer (
2958 sizeof (TEXT_OUT_AND_GOP_DATA
),
2959 &Private
->TextOutListCount
,
2960 (VOID
**) &Private
->TextOutList
2962 if (EFI_ERROR (Status
)) {
2963 return EFI_OUT_OF_RESOURCES
;
2966 // Also need to reallocate the TextOutModeMap table
2968 Status
= ConSplitterGrowMapTable (Private
);
2969 if (EFI_ERROR (Status
)) {
2970 return EFI_OUT_OF_RESOURCES
;
2974 TextAndGop
= &Private
->TextOutList
[CurrentNumOfConsoles
];
2976 TextAndGop
->TextOut
= TextOut
;
2977 TextAndGop
->GraphicsOutput
= GraphicsOutput
;
2978 TextAndGop
->UgaDraw
= UgaDraw
;
2980 if ((GraphicsOutput
== NULL
) && (UgaDraw
== NULL
)) {
2982 // If No GOP/UGA device then use the ConOut device
2984 TextAndGop
->TextOutEnabled
= TRUE
;
2987 // If GOP/UGA device use ConOut device only used if screen is in Text mode
2989 TextAndGop
->TextOutEnabled
= (BOOLEAN
) (Private
->ConsoleOutputMode
== EfiConsoleControlScreenText
);
2992 if (CurrentNumOfConsoles
== 0) {
2994 // Add the first device's output mode to console splitter's mode list
2996 Status
= ConSplitterAddOutputMode (Private
, TextOut
);
2998 ConSplitterSyncOutputMode (Private
, TextOut
);
3001 Private
->CurrentNumberOfConsoles
++;
3004 // Scan both TextOutList, for the intersection TextOut device
3005 // maybe both ConOut and StdErr incorporate the same Text Out
3006 // device in them, thus the output of both should be synced.
3008 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3010 CurrentMode
= Private
->TextOutMode
.Mode
;
3011 MaxMode
= Private
->TextOutMode
.MaxMode
;
3012 ASSERT (MaxMode
>= 1);
3015 // Update DevNull mode according to current video device
3017 if (FeaturePcdGet (PcdConOutGopSupport
)) {
3018 if ((GraphicsOutput
!= NULL
) || (UgaDraw
!= NULL
)) {
3019 ConSplitterAddGraphicsOutputMode (Private
, GraphicsOutput
, UgaDraw
);
3022 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
3023 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3024 Status
= UgaDraw
->GetMode (
3026 &UgaHorizontalResolution
,
3027 &UgaVerticalResolution
,
3031 if (!EFI_ERROR (Status
)) {
3032 Status
= ConSpliterUgaDrawSetMode (
3034 UgaHorizontalResolution
,
3035 UgaVerticalResolution
,
3041 // If GetMode/SetMode is failed, set to 800x600 mode
3043 if(EFI_ERROR (Status
)) {
3044 Status
= ConSpliterUgaDrawSetMode (
3055 if (Private
->ConsoleOutputMode
== EfiConsoleControlScreenGraphics
&& GraphicsOutput
!= NULL
) {
3057 // We just added a new GOP or UGA device in graphics mode
3059 if (FeaturePcdGet (PcdConOutGopSupport
)) {
3060 DevNullGopSync (Private
, TextAndGop
->GraphicsOutput
, TextAndGop
->UgaDraw
);
3061 } else if (FeaturePcdGet (PcdConOutUgaSupport
)) {
3062 DevNullUgaSync (Private
, TextAndGop
->GraphicsOutput
, TextAndGop
->UgaDraw
);
3064 } else if ((CurrentMode
>= 0) && ((GraphicsOutput
!= NULL
) || (UgaDraw
!= NULL
)) && (CurrentMode
< Private
->TextOutMode
.MaxMode
)) {
3066 // The new console supports the same mode of the current console so sync up
3068 DevNullSyncStdOut (Private
);
3071 // If ConOut, then set the mode to Mode #0 which us 80 x 25
3073 Private
->TextOut
.SetMode (&Private
->TextOut
, 0);
3077 // After adding new console device, all existing console devices should be
3078 // synced to the current shared mode.
3080 ConsplitterSetConsoleOutMode (Private
);
3087 Remove Text Out Device in Consplitter Text Out list.
3089 @param Private Text Out Splitter pointer.
3090 @param TextOut Simple Text Output Pointer protocol pointer.
3092 @retval EFI_SUCCESS Text Out Device removed successfully.
3093 @retval EFI_NOT_FOUND No Text Out Device found.
3097 ConSplitterTextOutDeleteDevice (
3098 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
3099 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
3103 UINTN CurrentNumOfConsoles
;
3104 TEXT_OUT_AND_GOP_DATA
*TextOutList
;
3108 // Remove the specified text-out device data structure from the Text out List,
3109 // and rearrange the remaining data structures in the Text out List.
3111 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
3112 Index
= (INT32
) CurrentNumOfConsoles
- 1;
3113 TextOutList
= Private
->TextOutList
;
3114 while (Index
>= 0) {
3115 if (TextOutList
->TextOut
== TextOut
) {
3116 CopyMem (TextOutList
, TextOutList
+ 1, sizeof (TEXT_OUT_AND_GOP_DATA
) * Index
);
3117 CurrentNumOfConsoles
--;
3118 if (TextOutList
->UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3119 Private
->CurrentNumberOfUgaDraw
--;
3121 if (TextOutList
->GraphicsOutput
!= NULL
) {
3122 Private
->CurrentNumberOfGraphicsOutput
--;
3131 // The specified TextOut is not managed by the ConSplitter driver
3134 return EFI_NOT_FOUND
;
3137 if (CurrentNumOfConsoles
== 0) {
3139 // If the number of consoles is zero clear the Dev NULL device
3141 Private
->CurrentNumberOfConsoles
= 0;
3142 Private
->TextOutMode
.MaxMode
= 1;
3143 Private
->TextOutQueryData
[0].Columns
= 80;
3144 Private
->TextOutQueryData
[0].Rows
= 25;
3145 DevNullTextOutSetMode (Private
, 0);
3150 // Max Mode is realy an intersection of the QueryMode command to all
3151 // devices. So we must copy the QueryMode of the first device to
3155 Private
->TextOutQueryData
,
3156 Private
->TextOutQueryDataCount
* sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
)
3159 FreePool (Private
->TextOutModeMap
);
3160 Private
->TextOutModeMap
= NULL
;
3161 TextOutList
= Private
->TextOutList
;
3164 // Add the first TextOut to the QueryData array and ModeMap table
3166 Status
= ConSplitterAddOutputMode (Private
, TextOutList
->TextOut
);
3169 // Now add one by one
3172 Private
->CurrentNumberOfConsoles
= 1;
3174 while ((UINTN
) Index
< CurrentNumOfConsoles
) {
3175 ConSplitterSyncOutputMode (Private
, TextOutList
->TextOut
);
3177 Private
->CurrentNumberOfConsoles
++;
3181 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3188 Reset the input device and optionaly run diagnostics
3190 @param This Protocol instance pointer.
3191 @param ExtendedVerification Driver may perform diagnostics on reset.
3193 @retval EFI_SUCCESS The device was reset.
3194 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3200 ConSplitterTextInReset (
3201 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3202 IN BOOLEAN ExtendedVerification
3206 EFI_STATUS ReturnStatus
;
3207 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3210 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3212 Private
->KeyEventSignalState
= FALSE
;
3215 // return the worst status met
3217 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3218 Status
= Private
->TextInList
[Index
]->Reset (
3219 Private
->TextInList
[Index
],
3220 ExtendedVerification
3222 if (EFI_ERROR (Status
)) {
3223 ReturnStatus
= Status
;
3227 return ReturnStatus
;
3232 Reads the next keystroke from the input device. The WaitForKey Event can
3233 be used to test for existance of a keystroke via WaitForEvent () call.
3235 @param Private Protocol instance pointer.
3236 @param Key Driver may perform diagnostics on reset.
3238 @retval EFI_SUCCESS The keystroke information was returned.
3239 @retval EFI_NOT_READY There was no keystroke data availiable.
3240 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3246 ConSplitterTextInPrivateReadKeyStroke (
3247 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3248 OUT EFI_INPUT_KEY
*Key
3253 EFI_INPUT_KEY CurrentKey
;
3255 Key
->UnicodeChar
= 0;
3256 Key
->ScanCode
= SCAN_NULL
;
3259 // if no physical console input device exists, return EFI_NOT_READY;
3260 // if any physical console input device has key input,
3261 // return the key and EFI_SUCCESS.
3263 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3264 Status
= Private
->TextInList
[Index
]->ReadKeyStroke (
3265 Private
->TextInList
[Index
],
3268 if (!EFI_ERROR (Status
)) {
3274 return EFI_NOT_READY
;
3279 Return TRUE if StdIn is locked. The ConIn device on the virtual handle is
3280 the only device locked.
3284 @retval TRUE StdIn locked
3285 @retval FALSE StdIn working normally
3289 ConSpliterConssoleControlStdInLocked (
3293 return mConIn
.PasswordEnabled
;
3298 This timer event will fire when StdIn is locked. It will check the key
3299 sequence on StdIn to see if it matches the password. Any error in the
3300 password will cause the check to reset. As long a mConIn.PasswordEnabled is
3301 TRUE the StdIn splitter will not report any input.
3303 @param Event The Event this notify function registered to.
3304 @param Context Pointer to the context data registerd to the
3312 ConSpliterConsoleControlLockStdInEvent (
3319 CHAR16 BackSpaceString
[2];
3320 CHAR16 SpaceString
[2];
3323 Status
= ConSplitterTextInPrivateReadKeyStroke (&mConIn
, &Key
);
3324 if (!EFI_ERROR (Status
)) {
3326 // if it's an ENTER, match password
3328 if ((Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) && (Key
.ScanCode
== SCAN_NULL
)) {
3329 mConIn
.PwdAttempt
[mConIn
.PwdIndex
] = CHAR_NULL
;
3330 if (StrCmp (mConIn
.Password
, mConIn
.PwdAttempt
)) {
3332 // Password not match
3334 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"\n\rPassword not correct\n\r");
3335 mConIn
.PwdIndex
= 0;
3338 // Key matches password sequence
3340 gBS
->SetTimer (mConIn
.LockEvent
, TimerPeriodic
, 0);
3341 mConIn
.PasswordEnabled
= FALSE
;
3342 Status
= EFI_NOT_READY
;
3344 } else if ((Key
.UnicodeChar
== CHAR_BACKSPACE
) && (Key
.ScanCode
== SCAN_NULL
)) {
3348 if (mConIn
.PwdIndex
> 0) {
3349 BackSpaceString
[0] = CHAR_BACKSPACE
;
3350 BackSpaceString
[1] = 0;
3352 SpaceString
[0] = L
' ';
3355 ConSplitterTextOutOutputString (&mConOut
.TextOut
, BackSpaceString
);
3356 ConSplitterTextOutOutputString (&mConOut
.TextOut
, SpaceString
);
3357 ConSplitterTextOutOutputString (&mConOut
.TextOut
, BackSpaceString
);
3361 } else if ((Key
.ScanCode
== SCAN_NULL
) && (Key
.UnicodeChar
>= 32)) {
3363 // If it's not an ENTER, neigher a function key, nor a CTRL-X or ALT-X, record the input
3365 if (mConIn
.PwdIndex
< (MAX_STD_IN_PASSWORD
- 1)) {
3366 if (mConIn
.PwdIndex
== 0) {
3367 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"\n\r");
3370 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"*");
3371 mConIn
.PwdAttempt
[mConIn
.PwdIndex
] = Key
.UnicodeChar
;
3376 } while (!EFI_ERROR (Status
));
3381 If Password is NULL unlock the password state variable and set the event
3382 timer. If the Password is too big return an error. If the Password is valid
3383 Copy the Password and enable state variable and then arm the periodic timer
3385 @param This Console Control protocol pointer.
3386 @param Password The password input.
3388 @retval EFI_SUCCESS Lock the StdIn device
3389 @retval EFI_INVALID_PARAMETER Password is NULL
3390 @retval EFI_OUT_OF_RESOURCES Buffer allocation to store the password fails
3395 ConSpliterConsoleControlLockStdIn (
3396 IN EFI_CONSOLE_CONTROL_PROTOCOL
*This
,
3400 if (Password
== NULL
) {
3401 return EFI_INVALID_PARAMETER
;
3404 if (StrLen (Password
) >= MAX_STD_IN_PASSWORD
) {
3406 // Currently have a max password size
3408 return EFI_OUT_OF_RESOURCES
;
3411 // Save the password, initialize state variables and arm event timer
3413 StrCpy (mConIn
.Password
, Password
);
3414 mConIn
.PasswordEnabled
= TRUE
;
3415 mConIn
.PwdIndex
= 0;
3416 gBS
->SetTimer (mConIn
.LockEvent
, TimerPeriodic
, (10000 * 25));
3423 Reads the next keystroke from the input device. The WaitForKey Event can
3424 be used to test for existance of a keystroke via WaitForEvent () call.
3425 If the ConIn is password locked make it look like no keystroke is availible
3427 @param This Protocol instance pointer.
3428 @param Key Driver may perform diagnostics on reset.
3430 @retval EFI_SUCCESS The keystroke information was returned.
3431 @retval EFI_NOT_READY There was no keystroke data availiable.
3432 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3438 ConSplitterTextInReadKeyStroke (
3439 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3440 OUT EFI_INPUT_KEY
*Key
3443 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3445 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3446 if (Private
->PasswordEnabled
) {
3448 // If StdIn Locked return not ready
3450 return EFI_NOT_READY
;
3453 Private
->KeyEventSignalState
= FALSE
;
3455 return ConSplitterTextInPrivateReadKeyStroke (Private
, Key
);
3460 This event agregates all the events of the ConIn devices in the spliter.
3461 If the ConIn is password locked then return.
3462 If any events of physical ConIn devices are signaled, signal the ConIn
3463 spliter event. This will cause the calling code to call
3464 ConSplitterTextInReadKeyStroke ().
3466 @param Event The Event assoicated with callback.
3467 @param Context Context registered when Event was created.
3474 ConSplitterTextInWaitForKey (
3480 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3483 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
3484 if (Private
->PasswordEnabled
) {
3486 // If StdIn Locked return not ready
3492 // if KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
3494 if (Private
->KeyEventSignalState
) {
3495 gBS
->SignalEvent (Event
);
3499 // if any physical console input device has key input, signal the event.
3501 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3502 Status
= gBS
->CheckEvent (Private
->TextInList
[Index
]->WaitForKey
);
3503 if (!EFI_ERROR (Status
)) {
3504 gBS
->SignalEvent (Event
);
3505 Private
->KeyEventSignalState
= TRUE
;
3513 Test if the key has been registered on input device.
3515 @param RegsiteredData A pointer to a buffer that is filled in with the
3516 keystroke state data for the key that was
3518 @param InputData A pointer to a buffer that is filled in with the
3519 keystroke state data for the key that was
3522 @retval TRUE Key be pressed matches a registered key.
3523 @retval FLASE Match failed.
3528 IN EFI_KEY_DATA
*RegsiteredData
,
3529 IN EFI_KEY_DATA
*InputData
3532 ASSERT (RegsiteredData
!= NULL
&& InputData
!= NULL
);
3534 if ((RegsiteredData
->Key
.ScanCode
!= InputData
->Key
.ScanCode
) ||
3535 (RegsiteredData
->Key
.UnicodeChar
!= InputData
->Key
.UnicodeChar
)) {
3540 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
3542 if (RegsiteredData
->KeyState
.KeyShiftState
!= 0 &&
3543 RegsiteredData
->KeyState
.KeyShiftState
!= InputData
->KeyState
.KeyShiftState
) {
3546 if (RegsiteredData
->KeyState
.KeyToggleState
!= 0 &&
3547 RegsiteredData
->KeyState
.KeyToggleState
!= InputData
->KeyState
.KeyToggleState
) {
3557 Reset the input device and optionaly run diagnostics
3559 @param This Protocol instance pointer.
3560 @param ExtendedVerification Driver may perform diagnostics on reset.
3562 @retval EFI_SUCCESS The device was reset.
3563 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3569 ConSplitterTextInResetEx (
3570 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3571 IN BOOLEAN ExtendedVerification
3575 EFI_STATUS ReturnStatus
;
3576 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3579 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3581 Private
->KeyEventSignalState
= FALSE
;
3584 // return the worst status met
3586 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3587 Status
= Private
->TextInExList
[Index
]->Reset (
3588 Private
->TextInExList
[Index
],
3589 ExtendedVerification
3591 if (EFI_ERROR (Status
)) {
3592 ReturnStatus
= Status
;
3596 return ReturnStatus
;
3602 Reads the next keystroke from the input device. The WaitForKey Event can
3603 be used to test for existance of a keystroke via WaitForEvent () call.
3605 @param This Protocol instance pointer.
3606 @param KeyData A pointer to a buffer that is filled in with the
3607 keystroke state data for the key that was
3610 @retval EFI_SUCCESS The keystroke information was returned.
3611 @retval EFI_NOT_READY There was no keystroke data availiable.
3612 @retval EFI_DEVICE_ERROR The keystroke information was not returned due
3614 @retval EFI_INVALID_PARAMETER KeyData is NULL.
3619 ConSplitterTextInReadKeyStrokeEx (
3620 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3621 OUT EFI_KEY_DATA
*KeyData
3624 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3627 EFI_KEY_DATA CurrentKeyData
;
3630 if (KeyData
== NULL
) {
3631 return EFI_INVALID_PARAMETER
;
3634 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3635 if (Private
->PasswordEnabled
) {
3637 // If StdIn Locked return not ready
3639 return EFI_NOT_READY
;
3642 Private
->KeyEventSignalState
= FALSE
;
3644 KeyData
->Key
.UnicodeChar
= 0;
3645 KeyData
->Key
.ScanCode
= SCAN_NULL
;
3648 // if no physical console input device exists, return EFI_NOT_READY;
3649 // if any physical console input device has key input,
3650 // return the key and EFI_SUCCESS.
3652 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3653 Status
= Private
->TextInExList
[Index
]->ReadKeyStrokeEx (
3654 Private
->TextInExList
[Index
],
3657 if (!EFI_ERROR (Status
)) {
3658 CopyMem (KeyData
, &CurrentKeyData
, sizeof (CurrentKeyData
));
3663 return EFI_NOT_READY
;
3668 Set certain state for the input device.
3670 @param This Protocol instance pointer.
3671 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
3672 state for the input device.
3674 @retval EFI_SUCCESS The device state was set successfully.
3675 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
3676 could not have the setting adjusted.
3677 @retval EFI_UNSUPPORTED The device does not have the ability to set its
3679 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
3684 ConSplitterTextInSetState (
3685 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3686 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
3689 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3693 if (KeyToggleState
== NULL
) {
3694 return EFI_INVALID_PARAMETER
;
3697 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3700 // if no physical console input device exists, return EFI_SUCCESS;
3701 // otherwise return the status of setting state of physical console input device
3703 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3704 Status
= Private
->TextInExList
[Index
]->SetState (
3705 Private
->TextInExList
[Index
],
3708 if (EFI_ERROR (Status
)) {
3719 Register a notification function for a particular keystroke for the input device.
3721 @param This Protocol instance pointer.
3722 @param KeyData A pointer to a buffer that is filled in with the
3723 keystroke information data for the key that was
3725 @param KeyNotificationFunction Points to the function to be called when the key
3726 sequence is typed specified by KeyData.
3727 @param NotifyHandle Points to the unique handle assigned to the
3728 registered notification.
3730 @retval EFI_SUCCESS The notification function was registered
3732 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data
3734 @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.
3739 ConSplitterTextInRegisterKeyNotify (
3740 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3741 IN EFI_KEY_DATA
*KeyData
,
3742 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction
,
3743 OUT EFI_HANDLE
*NotifyHandle
3746 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3749 TEXT_IN_EX_SPLITTER_NOTIFY
*NewNotify
;
3751 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3754 if (KeyData
== NULL
|| NotifyHandle
== NULL
|| KeyNotificationFunction
== NULL
) {
3755 return EFI_INVALID_PARAMETER
;
3758 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3761 // if no physical console input device exists,
3762 // return EFI_SUCCESS directly.
3764 if (Private
->CurrentNumberOfExConsoles
<= 0) {
3769 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
3771 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3772 CurrentNotify
= CR (
3774 TEXT_IN_EX_SPLITTER_NOTIFY
,
3776 TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
3778 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
3779 if (CurrentNotify
->KeyNotificationFn
== KeyNotificationFunction
) {
3780 *NotifyHandle
= CurrentNotify
->NotifyHandle
;
3787 // Allocate resource to save the notification function
3789 NewNotify
= (TEXT_IN_EX_SPLITTER_NOTIFY
*) AllocateZeroPool (sizeof (TEXT_IN_EX_SPLITTER_NOTIFY
));
3790 if (NewNotify
== NULL
) {
3791 return EFI_OUT_OF_RESOURCES
;
3793 NewNotify
->NotifyHandleList
= (EFI_HANDLE
*) AllocateZeroPool (sizeof (EFI_HANDLE
) * Private
->CurrentNumberOfExConsoles
);
3794 if (NewNotify
->NotifyHandleList
== NULL
) {
3795 gBS
->FreePool (NewNotify
);
3796 return EFI_OUT_OF_RESOURCES
;
3798 NewNotify
->Signature
= TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
;
3799 NewNotify
->KeyNotificationFn
= KeyNotificationFunction
;
3800 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (KeyData
));
3803 // Return the wrong status of registering key notify of
3804 // physical console input device if meet problems
3806 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3807 Status
= Private
->TextInExList
[Index
]->RegisterKeyNotify (
3808 Private
->TextInExList
[Index
],
3810 KeyNotificationFunction
,
3811 &NewNotify
->NotifyHandleList
[Index
]
3813 if (EFI_ERROR (Status
)) {
3814 gBS
->FreePool (NewNotify
->NotifyHandleList
);
3815 gBS
->FreePool (NewNotify
);
3821 // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE
3823 Status
= gBS
->InstallMultipleProtocolInterfaces (
3824 &NewNotify
->NotifyHandle
,
3825 &gSimpleTextInExNotifyGuid
,
3829 ASSERT_EFI_ERROR (Status
);
3831 InsertTailList (&mConIn
.NotifyList
, &NewNotify
->NotifyEntry
);
3833 *NotifyHandle
= NewNotify
->NotifyHandle
;
3841 Remove a registered notification function from a particular keystroke.
3843 @param This Protocol instance pointer.
3844 @param NotificationHandle The handle of the notification function being
3847 @retval EFI_SUCCESS The notification function was unregistered
3849 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
3850 @retval EFI_NOT_FOUND Can not find the matching entry in database.
3855 ConSplitterTextInUnregisterKeyNotify (
3856 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3857 IN EFI_HANDLE NotificationHandle
3860 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3863 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3866 if (NotificationHandle
== NULL
) {
3867 return EFI_INVALID_PARAMETER
;
3870 Status
= gBS
->OpenProtocol (
3872 &gSimpleTextInExNotifyGuid
,
3876 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
3878 if (EFI_ERROR (Status
)) {
3879 return EFI_INVALID_PARAMETER
;
3882 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3885 // if no physical console input device exists,
3886 // return EFI_SUCCESS directly.
3888 if (Private
->CurrentNumberOfExConsoles
<= 0) {
3892 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3893 CurrentNotify
= CR (Link
, TEXT_IN_EX_SPLITTER_NOTIFY
, NotifyEntry
, TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
);
3894 if (CurrentNotify
->NotifyHandle
== NotificationHandle
) {
3895 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3896 Status
= Private
->TextInExList
[Index
]->UnregisterKeyNotify (
3897 Private
->TextInExList
[Index
],
3898 CurrentNotify
->NotifyHandleList
[Index
]
3900 if (EFI_ERROR (Status
)) {
3904 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
3905 Status
= gBS
->UninstallMultipleProtocolInterfaces (
3906 CurrentNotify
->NotifyHandle
,
3907 &gSimpleTextInExNotifyGuid
,
3911 ASSERT_EFI_ERROR (Status
);
3912 gBS
->FreePool (CurrentNotify
->NotifyHandleList
);
3913 gBS
->FreePool (CurrentNotify
);
3918 return EFI_NOT_FOUND
;
3924 Reset the input device and optionaly run diagnostics
3926 @param This Protocol instance pointer.
3927 @param ExtendedVerification Driver may perform diagnostics on reset.
3929 @retval EFI_SUCCESS The device was reset.
3930 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3936 ConSplitterSimplePointerReset (
3937 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
3938 IN BOOLEAN ExtendedVerification
3942 EFI_STATUS ReturnStatus
;
3943 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3946 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
3948 Private
->InputEventSignalState
= FALSE
;
3950 if (Private
->CurrentNumberOfPointers
== 0) {
3954 // return the worst status met
3956 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3957 Status
= Private
->PointerList
[Index
]->Reset (
3958 Private
->PointerList
[Index
],
3959 ExtendedVerification
3961 if (EFI_ERROR (Status
)) {
3962 ReturnStatus
= Status
;
3966 return ReturnStatus
;
3971 Reads the next keystroke from the input device. The WaitForKey Event can
3972 be used to test for existance of a keystroke via WaitForEvent () call.
3974 @param Private Protocol instance pointer.
3975 @param State The state information of simple pointer device.
3977 @retval EFI_SUCCESS The keystroke information was returned.
3978 @retval EFI_NOT_READY There was no keystroke data availiable.
3979 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3985 ConSplitterSimplePointerPrivateGetState (
3986 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3987 IN OUT EFI_SIMPLE_POINTER_STATE
*State
3991 EFI_STATUS ReturnStatus
;
3993 EFI_SIMPLE_POINTER_STATE CurrentState
;
3995 State
->RelativeMovementX
= 0;
3996 State
->RelativeMovementY
= 0;
3997 State
->RelativeMovementZ
= 0;
3998 State
->LeftButton
= FALSE
;
3999 State
->RightButton
= FALSE
;
4002 // if no physical console input device exists, return EFI_NOT_READY;
4003 // if any physical console input device has key input,
4004 // return the key and EFI_SUCCESS.
4006 ReturnStatus
= EFI_NOT_READY
;
4007 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
4009 Status
= Private
->PointerList
[Index
]->GetState (
4010 Private
->PointerList
[Index
],
4013 if (!EFI_ERROR (Status
)) {
4014 if (ReturnStatus
== EFI_NOT_READY
) {
4015 ReturnStatus
= EFI_SUCCESS
;
4018 if (CurrentState
.LeftButton
) {
4019 State
->LeftButton
= TRUE
;
4022 if (CurrentState
.RightButton
) {
4023 State
->RightButton
= TRUE
;
4026 if (CurrentState
.RelativeMovementX
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionX
!= 0) {
4027 State
->RelativeMovementX
+= (CurrentState
.RelativeMovementX
* (INT32
) Private
->SimplePointerMode
.ResolutionX
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionX
;
4030 if (CurrentState
.RelativeMovementY
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionY
!= 0) {
4031 State
->RelativeMovementY
+= (CurrentState
.RelativeMovementY
* (INT32
) Private
->SimplePointerMode
.ResolutionY
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionY
;
4034 if (CurrentState
.RelativeMovementZ
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionZ
!= 0) {
4035 State
->RelativeMovementZ
+= (CurrentState
.RelativeMovementZ
* (INT32
) Private
->SimplePointerMode
.ResolutionZ
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionZ
;
4037 } else if (Status
== EFI_DEVICE_ERROR
) {
4038 ReturnStatus
= EFI_DEVICE_ERROR
;
4042 return ReturnStatus
;
4047 Reads the next keystroke from the input device. The WaitForKey Event can
4048 be used to test for existance of a keystroke via WaitForEvent () call.
4049 If the ConIn is password locked make it look like no keystroke is availible
4051 @param This A pointer to protocol instance.
4052 @param State A pointer to state information on the pointer device
4054 @retval EFI_SUCCESS The keystroke information was returned in State.
4055 @retval EFI_NOT_READY There was no keystroke data availiable.
4056 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
4062 ConSplitterSimplePointerGetState (
4063 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
4064 IN OUT EFI_SIMPLE_POINTER_STATE
*State
4067 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4069 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
4070 if (Private
->PasswordEnabled
) {
4072 // If StdIn Locked return not ready
4074 return EFI_NOT_READY
;
4077 Private
->InputEventSignalState
= FALSE
;
4079 return ConSplitterSimplePointerPrivateGetState (Private
, State
);
4084 This event agregates all the events of the ConIn devices in the spliter.
4085 If the ConIn is password locked then return.
4086 If any events of physical ConIn devices are signaled, signal the ConIn
4087 spliter event. This will cause the calling code to call
4088 ConSplitterTextInReadKeyStroke ().
4090 @param Event The Event assoicated with callback.
4091 @param Context Context registered when Event was created.
4098 ConSplitterSimplePointerWaitForInput (
4104 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4107 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4108 if (Private
->PasswordEnabled
) {
4110 // If StdIn Locked return not ready
4116 // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
4118 if (Private
->InputEventSignalState
) {
4119 gBS
->SignalEvent (Event
);
4123 // if any physical console input device has key input, signal the event.
4125 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
4126 Status
= gBS
->CheckEvent (Private
->PointerList
[Index
]->WaitForInput
);
4127 if (!EFI_ERROR (Status
)) {
4128 gBS
->SignalEvent (Event
);
4129 Private
->InputEventSignalState
= TRUE
;
4135 Resets the pointer device hardware.
4137 @param This Protocol instance pointer.
4138 @param ExtendedVerification Driver may perform diagnostics on reset.
4140 @retval EFI_SUCCESS The device was reset.
4141 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
4147 ConSplitterAbsolutePointerReset (
4148 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4149 IN BOOLEAN ExtendedVerification
4153 EFI_STATUS ReturnStatus
;
4154 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4157 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4159 Private
->AbsoluteInputEventSignalState
= FALSE
;
4161 if (Private
->CurrentNumberOfAbsolutePointers
== 0) {
4165 // return the worst status met
4167 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4168 Status
= Private
->AbsolutePointerList
[Index
]->Reset (
4169 Private
->AbsolutePointerList
[Index
],
4170 ExtendedVerification
4172 if (EFI_ERROR (Status
)) {
4173 ReturnStatus
= Status
;
4177 return ReturnStatus
;
4182 Retrieves the current state of a pointer device.
4184 @param This Protocol instance pointer.
4185 @param State A pointer to the state information on the
4188 @retval EFI_SUCCESS The state of the pointer device was returned in
4190 @retval EFI_NOT_READY The state of the pointer device has not changed
4191 since the last call to GetState().
4192 @retval EFI_DEVICE_ERROR A device error occurred while attempting to
4193 retrieve the pointer device's current state.
4198 ConSplitterAbsolutePointerGetState (
4199 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4200 IN OUT EFI_ABSOLUTE_POINTER_STATE
*State
4203 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4205 EFI_STATUS ReturnStatus
;
4207 EFI_ABSOLUTE_POINTER_STATE CurrentState
;
4210 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4211 if (Private
->PasswordEnabled
) {
4213 // If StdIn Locked return not ready
4215 return EFI_NOT_READY
;
4218 Private
->AbsoluteInputEventSignalState
= FALSE
;
4220 State
->CurrentX
= 0;
4221 State
->CurrentY
= 0;
4222 State
->CurrentZ
= 0;
4223 State
->ActiveButtons
= 0;
4226 // if no physical pointer device exists, return EFI_NOT_READY;
4227 // if any physical pointer device has changed state,
4228 // return the state and EFI_SUCCESS.
4230 ReturnStatus
= EFI_NOT_READY
;
4231 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4233 Status
= Private
->AbsolutePointerList
[Index
]->GetState (
4234 Private
->AbsolutePointerList
[Index
],
4237 if (!EFI_ERROR (Status
)) {
4238 if (ReturnStatus
== EFI_NOT_READY
) {
4239 ReturnStatus
= EFI_SUCCESS
;
4242 State
->ActiveButtons
= CurrentState
.ActiveButtons
;
4244 if (!(Private
->AbsolutePointerMode
.AbsoluteMinX
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxX
== 0)) {
4245 State
->CurrentX
= CurrentState
.CurrentX
;
4247 if (!(Private
->AbsolutePointerMode
.AbsoluteMinY
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxY
== 0)) {
4248 State
->CurrentY
= CurrentState
.CurrentY
;
4250 if (!(Private
->AbsolutePointerMode
.AbsoluteMinZ
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxZ
== 0)) {
4251 State
->CurrentZ
= CurrentState
.CurrentZ
;
4254 } else if (Status
== EFI_DEVICE_ERROR
) {
4255 ReturnStatus
= EFI_DEVICE_ERROR
;
4259 return ReturnStatus
;
4264 This event agregates all the events of the pointer devices in the splitter.
4265 If the ConIn is password locked then return.
4266 If any events of physical pointer devices are signaled, signal the pointer
4267 splitter event. This will cause the calling code to call
4268 ConSplitterAbsolutePointerGetState ().
4270 @param Event The Event assoicated with callback.
4271 @param Context Context registered when Event was created.
4278 ConSplitterAbsolutePointerWaitForInput (
4284 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4287 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4288 if (Private
->PasswordEnabled
) {
4290 // If StdIn Locked return not ready
4296 // if AbsoluteInputEventSignalState is flagged before,
4297 // and not cleared by Reset() or GetState(), signal it
4299 if (Private
->AbsoluteInputEventSignalState
) {
4300 gBS
->SignalEvent (Event
);
4304 // if any physical console input device has key input, signal the event.
4306 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4307 Status
= gBS
->CheckEvent (Private
->AbsolutePointerList
[Index
]->WaitForInput
);
4308 if (!EFI_ERROR (Status
)) {
4309 gBS
->SignalEvent (Event
);
4310 Private
->AbsoluteInputEventSignalState
= TRUE
;
4317 Reset the text output device hardware and optionaly run diagnostics
4319 @param This Protocol instance pointer.
4320 @param ExtendedVerification Driver may perform more exhaustive verfication
4321 operation of the device during reset.
4323 @retval EFI_SUCCESS The text output device was reset.
4324 @retval EFI_DEVICE_ERROR The text output device is not functioning
4325 correctly and could not be reset.
4330 ConSplitterTextOutReset (
4331 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4332 IN BOOLEAN ExtendedVerification
4336 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4338 EFI_STATUS ReturnStatus
;
4340 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4343 // return the worst status met
4345 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4347 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4349 Status
= Private
->TextOutList
[Index
].TextOut
->Reset (
4350 Private
->TextOutList
[Index
].TextOut
,
4351 ExtendedVerification
4353 if (EFI_ERROR (Status
)) {
4354 ReturnStatus
= Status
;
4359 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BLACK
));
4361 Status
= DevNullTextOutSetMode (Private
, 0);
4362 if (EFI_ERROR (Status
)) {
4363 ReturnStatus
= Status
;
4366 return ReturnStatus
;
4371 Write a Unicode string to the output device.
4373 @param This Protocol instance pointer.
4374 @param WString The NULL-terminated Unicode string to be
4375 displayed on the output device(s). All output
4376 devices must also support the Unicode drawing
4377 defined in this file.
4379 @retval EFI_SUCCESS The string was output to the device.
4380 @retval EFI_DEVICE_ERROR The device reported an error while attempting to
4382 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
4384 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
4385 characters in the Unicode string could not be
4386 rendered and were skipped.
4391 ConSplitterTextOutOutputString (
4392 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4397 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4399 UINTN BackSpaceCount
;
4400 EFI_STATUS ReturnStatus
;
4401 CHAR16
*TargetString
;
4403 This
->SetAttribute (This
, This
->Mode
->Attribute
);
4405 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4408 for (TargetString
= WString
; *TargetString
!= L
'\0'; TargetString
++) {
4409 if (*TargetString
== CHAR_BACKSPACE
) {
4415 if (BackSpaceCount
== 0) {
4416 TargetString
= WString
;
4418 TargetString
= AllocatePool (sizeof (CHAR16
) * (StrLen (WString
) + BackSpaceCount
+ 1));
4419 StrCpy (TargetString
, WString
);
4422 // return the worst status met
4424 Status
= DevNullTextOutOutputString (Private
, TargetString
);
4425 if (EFI_ERROR (Status
)) {
4426 ReturnStatus
= Status
;
4429 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4431 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4432 Status
= Private
->TextOutList
[Index
].TextOut
->OutputString (
4433 Private
->TextOutList
[Index
].TextOut
,
4436 if (EFI_ERROR (Status
)) {
4437 ReturnStatus
= Status
;
4442 if (BackSpaceCount
> 0) {
4443 FreePool (TargetString
);
4446 return ReturnStatus
;
4451 Verifies that all characters in a Unicode string can be output to the
4454 @param This Protocol instance pointer.
4455 @param WString The NULL-terminated Unicode string to be
4456 examined for the output device(s).
4458 @retval EFI_SUCCESS The device(s) are capable of rendering the
4460 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string
4461 cannot be rendered by one or more of the output
4462 devices mapped by the EFI handle.
4467 ConSplitterTextOutTestString (
4468 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4473 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4475 EFI_STATUS ReturnStatus
;
4477 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4480 // return the worst status met
4482 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4483 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4484 Status
= Private
->TextOutList
[Index
].TextOut
->TestString (
4485 Private
->TextOutList
[Index
].TextOut
,
4488 if (EFI_ERROR (Status
)) {
4489 ReturnStatus
= Status
;
4494 // There is no DevNullTextOutTestString () since a Unicode buffer would
4495 // always return EFI_SUCCESS.
4496 // ReturnStatus will be EFI_SUCCESS if no consoles are present
4498 return ReturnStatus
;
4503 Returns information for an available text mode that the output device(s)
4506 @param This Protocol instance pointer.
4507 @param ModeNumber The mode number to return information on.
4508 @param Columns Returns the columns of the text output device
4509 for the requested ModeNumber.
4510 @param Rows Returns the rows of the text output device
4511 for the requested ModeNumber.
4513 @retval EFI_SUCCESS The requested mode information was returned.
4514 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4516 @retval EFI_UNSUPPORTED The mode number was not valid.
4521 ConSplitterTextOutQueryMode (
4522 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4523 IN UINTN ModeNumber
,
4528 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4530 INT32
*TextOutModeMap
;
4532 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4535 // Check whether param ModeNumber is valid.
4536 // ModeNumber should be within range 0 ~ MaxMode - 1.
4538 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4539 return EFI_UNSUPPORTED
;
4542 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4543 return EFI_UNSUPPORTED
;
4547 // We get the available mode from mode intersection map if it's available
4549 if (Private
->TextOutModeMap
!= NULL
) {
4550 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4551 CurrentMode
= (UINTN
)(*TextOutModeMap
);
4552 *Columns
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4553 *Rows
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4555 *Columns
= Private
->TextOutQueryData
[ModeNumber
].Columns
;
4556 *Rows
= Private
->TextOutQueryData
[ModeNumber
].Rows
;
4559 if (*Columns
<= 0 && *Rows
<= 0) {
4560 return EFI_UNSUPPORTED
;
4569 Sets the output device(s) to a specified mode.
4571 @param This Protocol instance pointer.
4572 @param ModeNumber The mode number to set.
4574 @retval EFI_SUCCESS The requested text mode was set.
4575 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4577 @retval EFI_UNSUPPORTED The mode number was not valid.
4582 ConSplitterTextOutSetMode (
4583 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4588 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4590 INT32
*TextOutModeMap
;
4591 EFI_STATUS ReturnStatus
;
4593 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4596 // Check whether param ModeNumber is valid.
4597 // ModeNumber should be within range 0 ~ MaxMode - 1.
4599 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4600 return EFI_UNSUPPORTED
;
4603 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4604 return EFI_UNSUPPORTED
;
4607 // If the mode is being set to the curent mode, then just clear the screen and return.
4609 if (Private
->TextOutMode
.Mode
== (INT32
) ModeNumber
) {
4610 return ConSplitterTextOutClearScreen (This
);
4613 // return the worst status met
4615 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4616 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4618 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4619 Status
= Private
->TextOutList
[Index
].TextOut
->SetMode (
4620 Private
->TextOutList
[Index
].TextOut
,
4621 TextOutModeMap
[Index
]
4624 // If this console device is based on a GOP or UGA device, then sync up the bitmap from
4625 // the GOP/UGA splitter and reclear the text portion of the display in the new mode.
4627 if ((Private
->TextOutList
[Index
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[Index
].UgaDraw
!= NULL
)) {
4628 Private
->TextOutList
[Index
].TextOut
->ClearScreen (Private
->TextOutList
[Index
].TextOut
);
4631 if (EFI_ERROR (Status
)) {
4632 ReturnStatus
= Status
;
4637 // The DevNull Console will support any possible mode as it allocates memory
4639 Status
= DevNullTextOutSetMode (Private
, ModeNumber
);
4640 if (EFI_ERROR (Status
)) {
4641 ReturnStatus
= Status
;
4644 return ReturnStatus
;
4649 Sets the background and foreground colors for the OutputString () and
4650 ClearScreen () functions.
4652 @param This Protocol instance pointer.
4653 @param Attribute The attribute to set. Bits 0..3 are the
4654 foreground color, and bits 4..6 are the
4655 background color. All other bits are undefined
4656 and must be zero. The valid Attributes are
4657 defined in this file.
4659 @retval EFI_SUCCESS The attribute was set.
4660 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4662 @retval EFI_UNSUPPORTED The attribute requested is not defined.
4667 ConSplitterTextOutSetAttribute (
4668 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4673 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4675 EFI_STATUS ReturnStatus
;
4677 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4680 // Check whether param Attribute is valid.
4682 if ( (Attribute
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4683 return EFI_UNSUPPORTED
;
4687 // return the worst status met
4689 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4691 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4692 Status
= Private
->TextOutList
[Index
].TextOut
->SetAttribute (
4693 Private
->TextOutList
[Index
].TextOut
,
4696 if (EFI_ERROR (Status
)) {
4697 ReturnStatus
= Status
;
4702 Private
->TextOutMode
.Attribute
= (INT32
) Attribute
;
4704 return ReturnStatus
;
4709 Clears the output device(s) display to the currently selected background
4712 @param This Protocol instance pointer.
4714 @retval EFI_SUCCESS The operation completed successfully.
4715 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4717 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4722 ConSplitterTextOutClearScreen (
4723 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
4727 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4729 EFI_STATUS ReturnStatus
;
4731 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4734 // return the worst status met
4736 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4738 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4739 Status
= Private
->TextOutList
[Index
].TextOut
->ClearScreen (Private
->TextOutList
[Index
].TextOut
);
4740 if (EFI_ERROR (Status
)) {
4741 ReturnStatus
= Status
;
4746 Status
= DevNullTextOutClearScreen (Private
);
4747 if (EFI_ERROR (Status
)) {
4748 ReturnStatus
= Status
;
4751 return ReturnStatus
;
4756 Sets the current coordinates of the cursor position
4758 @param This Protocol instance pointer.
4759 @param Column The column position to set the cursor to. Must be
4760 greater than or equal to zero and less than the
4761 number of columns by QueryMode ().
4762 @param Row The row position to set the cursor to. Must be
4763 greater than or equal to zero and less than the
4764 number of rows by QueryMode ().
4766 @retval EFI_SUCCESS The operation completed successfully.
4767 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4769 @retval EFI_UNSUPPORTED The output device is not in a valid text mode,
4770 or the cursor position is invalid for the
4776 ConSplitterTextOutSetCursorPosition (
4777 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4783 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4785 EFI_STATUS ReturnStatus
;
4788 INT32
*TextOutModeMap
;
4792 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4793 TextOutModeMap
= NULL
;
4794 ModeNumber
= Private
->TextOutMode
.Mode
;
4797 // Get current MaxColumn and MaxRow from intersection map
4799 if (Private
->TextOutModeMap
!= NULL
) {
4800 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4801 CurrentMode
= *TextOutModeMap
;
4803 CurrentMode
= ModeNumber
;
4806 MaxColumn
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4807 MaxRow
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4809 if (Column
>= MaxColumn
|| Row
>= MaxRow
) {
4810 return EFI_UNSUPPORTED
;
4813 // return the worst status met
4815 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4817 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4818 Status
= Private
->TextOutList
[Index
].TextOut
->SetCursorPosition (
4819 Private
->TextOutList
[Index
].TextOut
,
4823 if (EFI_ERROR (Status
)) {
4824 ReturnStatus
= Status
;
4829 DevNullTextOutSetCursorPosition (Private
, Column
, Row
);
4831 return ReturnStatus
;
4836 Makes the cursor visible or invisible
4838 @param This Protocol instance pointer.
4839 @param Visible If TRUE, the cursor is set to be visible. If
4840 FALSE, the cursor is set to be invisible.
4842 @retval EFI_SUCCESS The operation completed successfully.
4843 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4844 the request, or the device does not support
4845 changing the cursor mode.
4846 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4851 ConSplitterTextOutEnableCursor (
4852 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4857 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4859 EFI_STATUS ReturnStatus
;
4861 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4864 // return the worst status met
4866 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4868 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4869 Status
= Private
->TextOutList
[Index
].TextOut
->EnableCursor (
4870 Private
->TextOutList
[Index
].TextOut
,
4873 if (EFI_ERROR (Status
)) {
4874 ReturnStatus
= Status
;
4879 DevNullTextOutEnableCursor (Private
, Visible
);
4881 return ReturnStatus
;