2 Console Splitter Driver. Any Handle that attatched
3 EFI_CONSOLE_IDENTIFIER_PROTOCOL can be bound by this driver.
5 So far it works like any other driver by opening a SimpleTextIn and/or
6 SimpleTextOut protocol with EFI_OPEN_PROTOCOL_BY_DRIVER attributes. The big
7 difference is this driver does not layer a protocol on the passed in
8 handle, or construct a child handle like a standard device or bus driver.
9 This driver produces three virtual handles as children, one for console input
10 splitter, one for console output splitter and one for error output splitter.
11 EFI_CONSOLE_SPLIT_PROTOCOL will be attatched onto each virtual handle to
12 identify the splitter type.
14 Each virtual handle, that supports both the EFI_CONSOLE_SPLIT_PROTOCOL
15 and Console I/O protocol, will be produced in the driver entry point.
16 The virtual handle are added on driver entry and never removed.
17 Such design ensures sytem function well during none console device situation.
19 Copyright (c) 2006 - 2008 Intel Corporation. <BR>
20 All rights reserved. This program and the accompanying materials
21 are licensed and made available under the terms and conditions of the BSD License
22 which accompanies this distribution. The full text of the license may be found at
23 http://opensource.org/licenses/bsd-license.php
25 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
26 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
30 #include "ConSplitter.h"
33 // Template for Text In Splitter
35 STATIC TEXT_IN_SPLITTER_PRIVATE_DATA mConIn
= {
36 TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE
,
39 ConSplitterTextInReset
,
40 ConSplitterTextInReadKeyStroke
,
44 (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
**) NULL
,
47 ConSplitterTextInResetEx
,
48 ConSplitterTextInReadKeyStrokeEx
,
50 ConSplitterTextInSetState
,
51 ConSplitterTextInRegisterKeyNotify
,
52 ConSplitterTextInUnregisterKeyNotify
55 (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
**) NULL
,
63 ConSplitterSimplePointerReset
,
64 ConSplitterSimplePointerGetState
,
66 (EFI_SIMPLE_POINTER_MODE
*) NULL
76 (EFI_SIMPLE_POINTER_PROTOCOL
**) NULL
,
80 ConSplitterAbsolutePointerReset
,
81 ConSplitterAbsolutePointerGetState
,
83 (EFI_ABSOLUTE_POINTER_MODE
*) NULL
90 0x10000, //AbsoluteMaxX
91 0x10000, //AbsoluteMaxY
92 0x10000, //AbsoluteMaxZ
96 (EFI_ABSOLUTE_POINTER_PROTOCOL
**) NULL
,
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
121 // Template for Uga Draw Protocol
123 GLOBAL_REMOVE_IF_UNREFERENCED EFI_UGA_DRAW_PROTOCOL mUgaDrawProtocolTemplate
= {
124 ConSpliterUgaDrawGetMode
,
125 ConSpliterUgaDrawSetMode
,
130 // Template for Graphics Output Protocol
132 GLOBAL_REMOVE_IF_UNREFERENCED EFI_GRAPHICS_OUTPUT_PROTOCOL mGraphicsOutputProtocolTemplate
= {
133 ConSpliterGraphicsOutputQueryMode
,
134 ConSpliterGraphicsOutputSetMode
,
135 ConSpliterGraphicsOutputBlt
,
140 // Template for Text Out Splitter
142 STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut
= {
143 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE
,
146 ConSplitterTextOutReset
,
147 ConSplitterTextOutOutputString
,
148 ConSplitterTextOutTestString
,
149 ConSplitterTextOutQueryMode
,
150 ConSplitterTextOutSetMode
,
151 ConSplitterTextOutSetAttribute
,
152 ConSplitterTextOutClearScreen
,
153 ConSplitterTextOutSetCursorPosition
,
154 ConSplitterTextOutEnableCursor
,
155 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
174 (EFI_UGA_PIXEL
*) NULL
,
181 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) NULL
,
182 (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*) NULL
,
187 ConSpliterConsoleControlGetMode
,
188 ConSpliterConsoleControlSetMode
,
189 ConSpliterConsoleControlLockStdIn
193 (TEXT_OUT_AND_GOP_DATA
*) NULL
,
195 (TEXT_OUT_SPLITTER_QUERY_DATA
*) NULL
,
199 EfiConsoleControlScreenText
,
207 // Template for Standard Error Text Out Splitter
209 STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr
= {
210 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE
,
213 ConSplitterTextOutReset
,
214 ConSplitterTextOutOutputString
,
215 ConSplitterTextOutTestString
,
216 ConSplitterTextOutQueryMode
,
217 ConSplitterTextOutSetMode
,
218 ConSplitterTextOutSetAttribute
,
219 ConSplitterTextOutClearScreen
,
220 ConSplitterTextOutSetCursorPosition
,
221 ConSplitterTextOutEnableCursor
,
222 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
241 (EFI_UGA_PIXEL
*) NULL
,
248 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) NULL
,
249 (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*) NULL
,
254 ConSpliterConsoleControlGetMode
,
255 ConSpliterConsoleControlSetMode
,
256 ConSpliterConsoleControlLockStdIn
260 (TEXT_OUT_AND_GOP_DATA
*) NULL
,
262 (TEXT_OUT_SPLITTER_QUERY_DATA
*) NULL
,
266 EfiConsoleControlScreenText
,
274 // Driver binding instance for Console Input Device
276 EFI_DRIVER_BINDING_PROTOCOL gConSplitterConInDriverBinding
= {
277 ConSplitterConInDriverBindingSupported
,
278 ConSplitterConInDriverBindingStart
,
279 ConSplitterConInDriverBindingStop
,
286 // Driver binding instance for Simple Pointer protocol
288 EFI_DRIVER_BINDING_PROTOCOL gConSplitterSimplePointerDriverBinding
= {
289 ConSplitterSimplePointerDriverBindingSupported
,
290 ConSplitterSimplePointerDriverBindingStart
,
291 ConSplitterSimplePointerDriverBindingStop
,
298 // Driver binding instance for Absolute Pointer protocol
300 EFI_DRIVER_BINDING_PROTOCOL gConSplitterAbsolutePointerDriverBinding
= {
301 ConSplitterAbsolutePointerDriverBindingSupported
,
302 ConSplitterAbsolutePointerDriverBindingStart
,
303 ConSplitterAbsolutePointerDriverBindingStop
,
310 // Driver binding instance for Console Out device
312 EFI_DRIVER_BINDING_PROTOCOL gConSplitterConOutDriverBinding
= {
313 ConSplitterConOutDriverBindingSupported
,
314 ConSplitterConOutDriverBindingStart
,
315 ConSplitterConOutDriverBindingStop
,
322 // Driver binding instance for Standard Error device
324 EFI_DRIVER_BINDING_PROTOCOL gConSplitterStdErrDriverBinding
= {
325 ConSplitterStdErrDriverBindingSupported
,
326 ConSplitterStdErrDriverBindingStart
,
327 ConSplitterStdErrDriverBindingStop
,
334 The user Entry Point for module ConSplitter. The user code starts with this function.
336 Installs driver module protocols and. Creates virtual device handles for ConIn,
337 ConOut, and StdErr. Installs Simple Text In protocol, Simple Text In Ex protocol,
338 Simple Pointer protocol, Absolute Pointer protocol on those virtual handlers.
339 Installs Graphics Output protocol and/or UGA Draw protocol if needed.
341 @param[in] ImageHandle The firmware allocated handle for the EFI image.
342 @param[in] SystemTable A pointer to the EFI System Table.
344 @retval EFI_SUCCESS The entry point is executed successfully.
345 @retval other Some error occurs when executing this entry point.
350 ConSplitterDriverEntry(
351 IN EFI_HANDLE ImageHandle
,
352 IN EFI_SYSTEM_TABLE
*SystemTable
358 // Install driver model protocol(s).
360 Status
= EfiLibInstallDriverBindingComponentName2 (
363 &gConSplitterConInDriverBinding
,
365 &gConSplitterConInComponentName
,
366 &gConSplitterConInComponentName2
368 ASSERT_EFI_ERROR (Status
);
370 Status
= EfiLibInstallDriverBindingComponentName2 (
373 &gConSplitterSimplePointerDriverBinding
,
375 &gConSplitterSimplePointerComponentName
,
376 &gConSplitterSimplePointerComponentName2
378 ASSERT_EFI_ERROR (Status
);
380 Status
= EfiLibInstallDriverBindingComponentName2 (
383 &gConSplitterAbsolutePointerDriverBinding
,
385 &gConSplitterAbsolutePointerComponentName
,
386 &gConSplitterAbsolutePointerComponentName2
388 ASSERT_EFI_ERROR (Status
);
390 Status
= EfiLibInstallDriverBindingComponentName2 (
393 &gConSplitterConOutDriverBinding
,
395 &gConSplitterConOutComponentName
,
396 &gConSplitterConOutComponentName2
398 ASSERT_EFI_ERROR (Status
);
400 Status
= EfiLibInstallDriverBindingComponentName2 (
403 &gConSplitterStdErrDriverBinding
,
405 &gConSplitterStdErrComponentName
,
406 &gConSplitterStdErrComponentName2
408 ASSERT_EFI_ERROR (Status
);
411 ASSERT (FeaturePcdGet (PcdConOutGopSupport
) ||
412 FeaturePcdGet (PcdConOutUgaSupport
));
414 // The driver creates virtual handles for ConIn, ConOut, and StdErr.
415 // The virtual handles will always exist even if no console exist in the
416 // system. This is need to support hotplug devices like USB.
419 // Create virtual device handle for StdErr Splitter
421 Status
= ConSplitterTextOutConstructor (&mStdErr
);
422 if (!EFI_ERROR (Status
)) {
423 Status
= gBS
->InstallMultipleProtocolInterfaces (
424 &mStdErr
.VirtualHandle
,
425 &gEfiSimpleTextOutProtocolGuid
,
427 &gEfiPrimaryStandardErrorDeviceGuid
,
433 // Create virtual device handle for ConIn Splitter
435 Status
= ConSplitterTextInConstructor (&mConIn
);
436 if (!EFI_ERROR (Status
)) {
437 Status
= gBS
->InstallMultipleProtocolInterfaces (
438 &mConIn
.VirtualHandle
,
439 &gEfiSimpleTextInProtocolGuid
,
441 &gEfiSimpleTextInputExProtocolGuid
,
443 &gEfiSimplePointerProtocolGuid
,
444 &mConIn
.SimplePointer
,
445 &gEfiAbsolutePointerProtocolGuid
,
446 &mConIn
.AbsolutePointer
,
447 &gEfiPrimaryConsoleInDeviceGuid
,
451 if (!EFI_ERROR (Status
)) {
453 // Update the EFI System Table with new virtual console
455 gST
->ConsoleInHandle
= mConIn
.VirtualHandle
;
456 gST
->ConIn
= &mConIn
.TextIn
;
460 // Create virtual device handle for ConOut Splitter
462 Status
= ConSplitterTextOutConstructor (&mConOut
);
463 if (!EFI_ERROR (Status
)) {
464 if (!FeaturePcdGet (PcdConOutGopSupport
)) {
466 // In EFI mode, UGA Draw protocol is installed
468 Status
= gBS
->InstallMultipleProtocolInterfaces (
469 &mConOut
.VirtualHandle
,
470 &gEfiSimpleTextOutProtocolGuid
,
472 &gEfiUgaDrawProtocolGuid
,
474 &gEfiConsoleControlProtocolGuid
,
475 &mConOut
.ConsoleControl
,
476 &gEfiPrimaryConsoleOutDeviceGuid
,
480 } else if (!FeaturePcdGet (PcdConOutUgaSupport
)) {
482 // In UEFI mode, Graphics Output Protocol is installed on virtual handle.
484 Status
= gBS
->InstallMultipleProtocolInterfaces (
485 &mConOut
.VirtualHandle
,
486 &gEfiSimpleTextOutProtocolGuid
,
488 &gEfiGraphicsOutputProtocolGuid
,
489 &mConOut
.GraphicsOutput
,
490 &gEfiConsoleControlProtocolGuid
,
491 &mConOut
.ConsoleControl
,
492 &gEfiPrimaryConsoleOutDeviceGuid
,
498 // In EFI and UEFI comptible mode, Graphics Output Protocol and UGA are
499 // installed on virtual handle.
501 Status
= gBS
->InstallMultipleProtocolInterfaces (
502 &mConOut
.VirtualHandle
,
503 &gEfiSimpleTextOutProtocolGuid
,
505 &gEfiGraphicsOutputProtocolGuid
,
506 &mConOut
.GraphicsOutput
,
507 &gEfiUgaDrawProtocolGuid
,
509 &gEfiConsoleControlProtocolGuid
,
510 &mConOut
.ConsoleControl
,
511 &gEfiPrimaryConsoleOutDeviceGuid
,
517 if (!EFI_ERROR (Status
)) {
519 // Update the EFI System Table with new virtual console
521 gST
->ConsoleOutHandle
= mConOut
.VirtualHandle
;
522 gST
->ConOut
= &mConOut
.TextOut
;
527 // Update the CRC32 in the EFI System Table header
530 gBS
->CalculateCrc32 (
542 Construct console input devices' private data.
544 @param ConInPrivate A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA
547 @retval EFI_OUT_OF_RESOURCES Out of resources.
548 @retval EFI_SUCCESS Text Input Devcie's private data has been constructed.
549 @retval other Failed to construct private data.
553 ConSplitterTextInConstructor (
554 TEXT_IN_SPLITTER_PRIVATE_DATA
*ConInPrivate
560 // Initilize console input splitter's private data.
562 Status
= ConSplitterGrowBuffer (
563 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
564 &ConInPrivate
->TextInListCount
,
565 (VOID
**) &ConInPrivate
->TextInList
567 if (EFI_ERROR (Status
)) {
568 return EFI_OUT_OF_RESOURCES
;
571 // Create Event to support locking StdIn Device
573 Status
= gBS
->CreateEvent (
574 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
576 ConSpliterConsoleControlLockStdInEvent
,
578 &ConInPrivate
->LockEvent
580 ASSERT_EFI_ERROR (Status
);
582 Status
= gBS
->CreateEvent (
585 ConSplitterTextInWaitForKey
,
587 &ConInPrivate
->TextIn
.WaitForKey
589 ASSERT_EFI_ERROR (Status
);
592 // Buffer for Simple Text Input Ex Protocol
594 Status
= ConSplitterGrowBuffer (
595 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
596 &ConInPrivate
->TextInExListCount
,
597 (VOID
**) &ConInPrivate
->TextInExList
599 if (EFI_ERROR (Status
)) {
600 return EFI_OUT_OF_RESOURCES
;
603 Status
= gBS
->CreateEvent (
606 ConSplitterTextInWaitForKey
,
608 &ConInPrivate
->TextInEx
.WaitForKeyEx
610 ASSERT_EFI_ERROR (Status
);
612 InitializeListHead (&ConInPrivate
->NotifyList
);
615 // Allocate Buffer and Create Event for Absolute Pointer and Simple Pointer Protocols
617 ConInPrivate
->AbsolutePointer
.Mode
= &ConInPrivate
->AbsolutePointerMode
;
619 Status
= ConSplitterGrowBuffer (
620 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
621 &ConInPrivate
->AbsolutePointerListCount
,
622 (VOID
**) &ConInPrivate
->AbsolutePointerList
624 if (EFI_ERROR (Status
)) {
625 return EFI_OUT_OF_RESOURCES
;
628 Status
= gBS
->CreateEvent (
631 ConSplitterAbsolutePointerWaitForInput
,
633 &ConInPrivate
->AbsolutePointer
.WaitForInput
635 ASSERT_EFI_ERROR (Status
);
637 ConInPrivate
->SimplePointer
.Mode
= &ConInPrivate
->SimplePointerMode
;
639 Status
= ConSplitterGrowBuffer (
640 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
641 &ConInPrivate
->PointerListCount
,
642 (VOID
**) &ConInPrivate
->PointerList
644 if (EFI_ERROR (Status
)) {
645 return EFI_OUT_OF_RESOURCES
;
648 Status
= gBS
->CreateEvent (
651 ConSplitterSimplePointerWaitForInput
,
653 &ConInPrivate
->SimplePointer
.WaitForInput
660 Construct console output devices' private data.
662 @param ConOutPrivate A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA
665 @retval EFI_OUT_OF_RESOURCES Out of resources.
666 @retval EFI_SUCCESS Text Input Devcie's private data has been constructed.
670 ConSplitterTextOutConstructor (
671 TEXT_OUT_SPLITTER_PRIVATE_DATA
*ConOutPrivate
675 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
678 // Copy protocols template
680 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
681 CopyMem (&ConOutPrivate
->UgaDraw
, &mUgaDrawProtocolTemplate
, sizeof (EFI_UGA_DRAW_PROTOCOL
));
684 if (FeaturePcdGet (PcdConOutGopSupport
)) {
685 CopyMem (&ConOutPrivate
->GraphicsOutput
, &mGraphicsOutputProtocolTemplate
, sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL
));
689 // Initilize console output splitter's private data.
691 ConOutPrivate
->TextOut
.Mode
= &ConOutPrivate
->TextOutMode
;
694 // When new console device is added, the new mode will be set later,
695 // so put current mode back to init state.
697 ConOutPrivate
->TextOutMode
.Mode
= 0xFF;
699 Status
= ConSplitterGrowBuffer (
700 sizeof (TEXT_OUT_AND_GOP_DATA
),
701 &ConOutPrivate
->TextOutListCount
,
702 (VOID
**) &ConOutPrivate
->TextOutList
704 if (EFI_ERROR (Status
)) {
705 return EFI_OUT_OF_RESOURCES
;
708 Status
= ConSplitterGrowBuffer (
709 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
710 &ConOutPrivate
->TextOutQueryDataCount
,
711 (VOID
**) &ConOutPrivate
->TextOutQueryData
713 if (EFI_ERROR (Status
)) {
714 return EFI_OUT_OF_RESOURCES
;
717 // Setup the DevNullTextOut console to 80 x 25
719 ConOutPrivate
->TextOutQueryData
[0].Columns
= 80;
720 ConOutPrivate
->TextOutQueryData
[0].Rows
= 25;
721 DevNullTextOutSetMode (ConOutPrivate
, 0);
723 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
725 // Setup the DevNullUgaDraw to 800 x 600 x 32 bits per pixel
727 ConSpliterUgaDrawSetMode (&ConOutPrivate
->UgaDraw
, 800, 600, 32, 60);
729 if (FeaturePcdGet (PcdConOutGopSupport
)) {
731 // Setup resource for mode information in Graphics Output Protocol interface
733 if ((ConOutPrivate
->GraphicsOutput
.Mode
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
))) == NULL
) {
734 return EFI_OUT_OF_RESOURCES
;
736 if ((ConOutPrivate
->GraphicsOutput
.Mode
->Info
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
))) == NULL
) {
737 return EFI_OUT_OF_RESOURCES
;
740 // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel
741 // DevNull will be updated to user-defined mode after driver has started.
743 if ((ConOutPrivate
->GraphicsOutputModeBuffer
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
))) == NULL
) {
744 return EFI_OUT_OF_RESOURCES
;
746 Info
= &ConOutPrivate
->GraphicsOutputModeBuffer
[0];
748 Info
->HorizontalResolution
= 800;
749 Info
->VerticalResolution
= 600;
750 Info
->PixelFormat
= PixelBltOnly
;
751 Info
->PixelsPerScanLine
= 800;
752 CopyMem (ConOutPrivate
->GraphicsOutput
.Mode
->Info
, Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
753 ConOutPrivate
->GraphicsOutput
.Mode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
756 // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()
757 // GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
759 ConOutPrivate
->GraphicsOutput
.Mode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
760 ConOutPrivate
->GraphicsOutput
.Mode
->FrameBufferSize
= 0;
762 ConOutPrivate
->GraphicsOutput
.Mode
->MaxMode
= 1;
764 // Initial current mode to unknown state, and then set to mode 0
766 ConOutPrivate
->GraphicsOutput
.Mode
->Mode
= 0xffff;
767 ConOutPrivate
->GraphicsOutput
.SetMode (&ConOutPrivate
->GraphicsOutput
, 0);
775 Test to see if the specified protocol could be supported on the ControllerHandle.
777 @param This Protocol instance pointer.
778 @param ControllerHandle Handle of device to test.
779 @param Guid The specified protocol guid.
781 @retval EFI_SUCCESS The specified protocol is supported on this device.
782 @retval other The specified protocol is not supported on this device.
786 ConSplitterSupported (
787 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
788 IN EFI_HANDLE ControllerHandle
,
796 // Make sure the Console Splitter does not attempt to attach to itself
798 if (ControllerHandle
== mConIn
.VirtualHandle
) {
799 return EFI_UNSUPPORTED
;
802 if (ControllerHandle
== mConOut
.VirtualHandle
) {
803 return EFI_UNSUPPORTED
;
806 if (ControllerHandle
== mStdErr
.VirtualHandle
) {
807 return EFI_UNSUPPORTED
;
810 // Check to see whether the handle has the ConsoleInDevice GUID on it
812 Status
= gBS
->OpenProtocol (
816 This
->DriverBindingHandle
,
818 EFI_OPEN_PROTOCOL_BY_DRIVER
821 if (EFI_ERROR (Status
)) {
828 This
->DriverBindingHandle
,
836 Test to see if Console In Device could be supported on the ControllerHandle.
838 @param This Protocol instance pointer.
839 @param ControllerHandle Handle of device to test.
840 @param RemainingDevicePath Optional parameter use to pick a specific child
843 @retval EFI_SUCCESS This driver supports this device.
844 @retval other This driver does not support this device.
849 ConSplitterConInDriverBindingSupported (
850 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
851 IN EFI_HANDLE ControllerHandle
,
852 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
855 return ConSplitterSupported (
858 &gEfiConsoleInDeviceGuid
863 Test to see if Simple Pointer protocol could be supported on the ControllerHandle.
865 @param This Protocol instance pointer.
866 @param ControllerHandle Handle of device to test.
867 @param RemainingDevicePath Optional parameter use to pick a specific child
870 @retval EFI_SUCCESS This driver supports this device.
871 @retval other This driver does not support this device.
876 ConSplitterSimplePointerDriverBindingSupported (
877 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
878 IN EFI_HANDLE ControllerHandle
,
879 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
882 return ConSplitterSupported (
885 &gEfiSimplePointerProtocolGuid
891 Test to see if Absolute Pointer protocol could be supported on the ControllerHandle.
893 @param This Protocol instance pointer.
894 @param ControllerHandle Handle of device to test.
895 @param RemainingDevicePath Optional parameter use to pick a specific child
898 @retval EFI_SUCCESS This driver supports this device.
899 @retval other This driver does not support this device.
904 ConSplitterAbsolutePointerDriverBindingSupported (
905 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
906 IN EFI_HANDLE ControllerHandle
,
907 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
910 return ConSplitterSupported (
913 &gEfiAbsolutePointerProtocolGuid
919 Test to see if Console Out Device could be supported on the ControllerHandle.
921 @param This Protocol instance pointer.
922 @param ControllerHandle Handle of device to test.
923 @param RemainingDevicePath Optional parameter use to pick a specific child
926 @retval EFI_SUCCESS This driver supports this device.
927 @retval other This driver does not support this device.
932 ConSplitterConOutDriverBindingSupported (
933 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
934 IN EFI_HANDLE ControllerHandle
,
935 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
938 return ConSplitterSupported (
941 &gEfiConsoleOutDeviceGuid
946 Test to see if Standard Error Device could be supported on the ControllerHandle.
948 @param This Protocol instance pointer.
949 @param ControllerHandle Handle of device to test.
950 @param RemainingDevicePath Optional parameter use to pick a specific child
953 @retval EFI_SUCCESS This driver supports this device.
954 @retval other This driver does not support this device.
959 ConSplitterStdErrDriverBindingSupported (
960 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
961 IN EFI_HANDLE ControllerHandle
,
962 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
965 return ConSplitterSupported (
968 &gEfiStandardErrorDeviceGuid
974 Start ConSplitter on devcie handle by opening Console Device Guid on device handle
975 and the console virtual handle. And Get the console interface on controller handle.
977 @param This Protocol instance pointer.
978 @param ControllerHandle Handle of device.
979 @param ConSplitterVirtualHandle Console virtual Handle.
980 @param DeviceGuid The specified Console Device, such as ConInDev,
982 @param InterfaceGuid The specified protocol to be opened.
983 @param Interface Protocol interface returned.
985 @retval EFI_SUCCESS This driver supports this device.
986 @retval other Failed to open the specified Console Device Guid
987 or specified protocol.
992 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
993 IN EFI_HANDLE ControllerHandle
,
994 IN EFI_HANDLE ConSplitterVirtualHandle
,
995 IN EFI_GUID
*DeviceGuid
,
996 IN EFI_GUID
*InterfaceGuid
,
1004 // Check to see whether the ControllerHandle has the InterfaceGuid on it.
1006 Status
= gBS
->OpenProtocol (
1010 This
->DriverBindingHandle
,
1012 EFI_OPEN_PROTOCOL_BY_DRIVER
1014 if (EFI_ERROR (Status
)) {
1018 Status
= gBS
->OpenProtocol (
1022 This
->DriverBindingHandle
,
1023 ConSplitterVirtualHandle
,
1024 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1026 if (EFI_ERROR (Status
)) {
1030 return gBS
->OpenProtocol (
1034 This
->DriverBindingHandle
,
1035 ConSplitterVirtualHandle
,
1036 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1042 Start Console In Consplitter on device handle.
1044 @param This Protocol instance pointer.
1045 @param ControllerHandle Handle of device to bind driver to.
1046 @param RemainingDevicePath Optional parameter use to pick a specific child
1049 @retval EFI_SUCCESS Console In Consplitter is added to ControllerHandle.
1050 @retval other Console In Consplitter does not support this device.
1055 ConSplitterConInDriverBindingStart (
1056 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1057 IN EFI_HANDLE ControllerHandle
,
1058 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1062 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
1063 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
;
1066 // Start ConSplitter on ControllerHandle, and create the virtual
1067 // agrogated console device on first call Start for a SimpleTextIn handle.
1069 Status
= ConSplitterStart (
1072 mConIn
.VirtualHandle
,
1073 &gEfiConsoleInDeviceGuid
,
1074 &gEfiSimpleTextInProtocolGuid
,
1077 if (EFI_ERROR (Status
)) {
1082 // Add this device into Text In devices list.
1084 Status
= ConSplitterTextInAddDevice (&mConIn
, TextIn
);
1085 if (EFI_ERROR (Status
)) {
1089 Status
= gBS
->OpenProtocol (
1091 &gEfiSimpleTextInputExProtocolGuid
,
1092 (VOID
**) &TextInEx
,
1093 This
->DriverBindingHandle
,
1094 mConIn
.VirtualHandle
,
1095 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1097 if (!EFI_ERROR (Status
)) {
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
2263 ConSplitterGetIntersection (
2264 IN INT32
*TextOutModeMap
,
2265 IN INT32
*NewlyAddedMap
,
2266 IN UINTN MapStepSize
,
2267 IN UINTN NewMapStepSize
,
2269 OUT INT32
*CurrentMode
2273 INT32
*CurrentMapEntry
;
2274 INT32
*NextMapEntry
;
2275 INT32 CurrentMaxMode
;
2279 // According to EFI/UEFI spec, mode 0 and mode 1 have been reserved
2280 // for 80x25 and 80x50 in Simple Text Out protocol, so don't make intersection
2281 // for mode 0 and mode 1, mode number starts from 2.
2284 CurrentMapEntry
= &TextOutModeMap
[MapStepSize
* 2];
2285 NextMapEntry
= &TextOutModeMap
[MapStepSize
* 2];
2286 NewlyAddedMap
= &NewlyAddedMap
[NewMapStepSize
* 2];
2288 CurrentMaxMode
= *MaxMode
;
2289 Mode
= *CurrentMode
;
2291 while (Index
< CurrentMaxMode
) {
2292 if (*NewlyAddedMap
== -1) {
2294 // This mode is not supported any more. Remove it. Special care
2295 // must be taken as this remove will also affect current mode;
2297 if (Index
== *CurrentMode
) {
2299 } else if (Index
< *CurrentMode
) {
2304 if (CurrentMapEntry
!= NextMapEntry
) {
2305 CopyMem (NextMapEntry
, CurrentMapEntry
, MapStepSize
* sizeof (INT32
));
2308 NextMapEntry
+= MapStepSize
;
2311 CurrentMapEntry
+= MapStepSize
;
2312 NewlyAddedMap
+= NewMapStepSize
;
2316 *CurrentMode
= Mode
;
2323 Add the device's output mode to console splitter's mode list.
2325 @param Private Text Out Splitter pointer.
2326 @param TextOut Simple Text Output protocol pointer.
2332 ConSplitterSyncOutputMode (
2333 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2334 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2337 INT32 CurrentMaxMode
;
2340 INT32
*TextOutModeMap
;
2343 TEXT_OUT_SPLITTER_QUERY_DATA
*TextOutQueryData
;
2350 // Must make sure that current mode won't change even if mode number changes
2352 CurrentMaxMode
= Private
->TextOutMode
.MaxMode
;
2353 TextOutModeMap
= Private
->TextOutModeMap
;
2354 StepSize
= Private
->TextOutListCount
;
2355 TextOutQueryData
= Private
->TextOutQueryData
;
2358 // Query all the mode that the newly added TextOut supports
2361 MapTable
= TextOutModeMap
+ Private
->CurrentNumberOfConsoles
;
2362 while (Mode
< TextOut
->Mode
->MaxMode
) {
2363 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Columns
, &Rows
);
2364 if (EFI_ERROR(Status
)) {
2366 MapTable
[StepSize
] = Mode
;
2367 TextOutQueryData
[Mode
].Columns
= 0;
2368 TextOutQueryData
[Mode
].Rows
= 0;
2374 // Search the intersection map and QueryData database to see if they intersects
2377 while (Index
< CurrentMaxMode
) {
2378 QueryMode
= *(TextOutModeMap
+ Index
* StepSize
);
2379 if ((TextOutQueryData
[QueryMode
].Rows
== Rows
) && (TextOutQueryData
[QueryMode
].Columns
== Columns
)) {
2380 MapTable
[Index
* StepSize
] = Mode
;
2390 // Now search the TextOutModeMap table to find the intersection of supported
2391 // mode between ConSplitter and the newly added device.
2393 ConSplitterGetIntersection (
2398 &Private
->TextOutMode
.MaxMode
,
2399 &Private
->TextOutMode
.Mode
2407 Sync output device between ConOut and StdErr output.
2409 @retval EFI_SUCCESS Sync implemented successfully.
2410 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2414 ConSplitterGetIntersectionBetweenConOutAndStrErr (
2418 UINTN ConOutNumOfConsoles
;
2419 UINTN StdErrNumOfConsoles
;
2420 TEXT_OUT_AND_GOP_DATA
*ConOutTextOutList
;
2421 TEXT_OUT_AND_GOP_DATA
*StdErrTextOutList
;
2425 UINTN ConOutColumns
;
2427 UINTN StdErrColumns
;
2428 INT32 ConOutMaxMode
;
2429 INT32 StdErrMaxMode
;
2434 INT32
*ConOutModeMap
;
2435 INT32
*StdErrModeMap
;
2436 INT32
*ConOutMapTable
;
2437 INT32
*StdErrMapTable
;
2438 TEXT_OUT_SPLITTER_QUERY_DATA
*ConOutQueryData
;
2439 TEXT_OUT_SPLITTER_QUERY_DATA
*StdErrQueryData
;
2440 UINTN ConOutStepSize
;
2441 UINTN StdErrStepSize
;
2442 BOOLEAN FoundTheSameTextOut
;
2443 UINTN ConOutMapTableSize
;
2444 UINTN StdErrMapTableSize
;
2446 ConOutNumOfConsoles
= mConOut
.CurrentNumberOfConsoles
;
2447 StdErrNumOfConsoles
= mStdErr
.CurrentNumberOfConsoles
;
2448 ConOutTextOutList
= mConOut
.TextOutList
;
2449 StdErrTextOutList
= mStdErr
.TextOutList
;
2452 FoundTheSameTextOut
= FALSE
;
2453 while ((Indexi
< ConOutNumOfConsoles
) && (!FoundTheSameTextOut
)) {
2455 while (Indexj
< StdErrNumOfConsoles
) {
2456 if (ConOutTextOutList
->TextOut
== StdErrTextOutList
->TextOut
) {
2457 FoundTheSameTextOut
= TRUE
;
2462 StdErrTextOutList
++;
2466 ConOutTextOutList
++;
2469 if (!FoundTheSameTextOut
) {
2473 // Must make sure that current mode won't change even if mode number changes
2475 ConOutMaxMode
= mConOut
.TextOutMode
.MaxMode
;
2476 ConOutModeMap
= mConOut
.TextOutModeMap
;
2477 ConOutStepSize
= mConOut
.TextOutListCount
;
2478 ConOutQueryData
= mConOut
.TextOutQueryData
;
2480 StdErrMaxMode
= mStdErr
.TextOutMode
.MaxMode
;
2481 StdErrModeMap
= mStdErr
.TextOutModeMap
;
2482 StdErrStepSize
= mStdErr
.TextOutListCount
;
2483 StdErrQueryData
= mStdErr
.TextOutQueryData
;
2486 // Allocate the map table and set the map table's index to -1.
2488 ConOutMapTableSize
= ConOutMaxMode
* sizeof (INT32
);
2489 ConOutMapTable
= AllocateZeroPool (ConOutMapTableSize
);
2490 if (ConOutMapTable
== NULL
) {
2491 return EFI_OUT_OF_RESOURCES
;
2494 SetMem (ConOutMapTable
, ConOutMapTableSize
, 0xFF);
2496 StdErrMapTableSize
= StdErrMaxMode
* sizeof (INT32
);
2497 StdErrMapTable
= AllocateZeroPool (StdErrMapTableSize
);
2498 if (StdErrMapTable
== NULL
) {
2499 return EFI_OUT_OF_RESOURCES
;
2502 SetMem (StdErrMapTable
, StdErrMapTableSize
, 0xFF);
2505 // Find the intersection of the two set of modes. If they actually intersect, the
2506 // correponding entry in the map table is set to 1.
2509 while (Mode
< ConOutMaxMode
) {
2511 // Search the intersection map and QueryData database to see if they intersect
2514 ConOutMode
= *(ConOutModeMap
+ Mode
* ConOutStepSize
);
2515 ConOutRows
= ConOutQueryData
[ConOutMode
].Rows
;
2516 ConOutColumns
= ConOutQueryData
[ConOutMode
].Columns
;
2517 while (Index
< StdErrMaxMode
) {
2518 StdErrMode
= *(StdErrModeMap
+ Index
* StdErrStepSize
);
2519 StdErrRows
= StdErrQueryData
[StdErrMode
].Rows
;
2520 StdErrColumns
= StdErrQueryData
[StdErrMode
].Columns
;
2521 if ((StdErrRows
== ConOutRows
) && (StdErrColumns
== ConOutColumns
)) {
2522 ConOutMapTable
[Mode
] = 1;
2523 StdErrMapTable
[Index
] = 1;
2533 // Now search the TextOutModeMap table to find the intersection of supported
2534 // mode between ConSplitter and the newly added device.
2536 ConSplitterGetIntersection (
2539 mConOut
.TextOutListCount
,
2541 &(mConOut
.TextOutMode
.MaxMode
),
2542 &(mConOut
.TextOutMode
.Mode
)
2544 if (mConOut
.TextOutMode
.Mode
< 0) {
2545 mConOut
.TextOut
.SetMode (&(mConOut
.TextOut
), 0);
2548 ConSplitterGetIntersection (
2551 mStdErr
.TextOutListCount
,
2553 &(mStdErr
.TextOutMode
.MaxMode
),
2554 &(mStdErr
.TextOutMode
.Mode
)
2556 if (mStdErr
.TextOutMode
.Mode
< 0) {
2557 mStdErr
.TextOut
.SetMode (&(mStdErr
.TextOut
), 0);
2560 FreePool (ConOutMapTable
);
2561 FreePool (StdErrMapTable
);
2568 Add GOP or UGA output mode into Consplitter Text Out list.
2570 @param Private Text Out Splitter pointer.
2571 @param GraphicsOutput Graphics Output protocol pointer.
2572 @param UgaDraw UGA Draw protocol pointer.
2574 @retval EFI_SUCCESS Output mode added successfully.
2575 @retval other Failed to add output mode.
2579 ConSplitterAddGraphicsOutputMode (
2580 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2581 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2582 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2588 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
;
2590 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
2591 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*CurrentGraphicsOutputMode
;
2592 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*ModeBuffer
;
2593 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*MatchedMode
;
2596 BOOLEAN AlreadyExist
;
2597 UINT32 UgaHorizontalResolution
;
2598 UINT32 UgaVerticalResolution
;
2599 UINT32 UgaColorDepth
;
2600 UINT32 UgaRefreshRate
;
2602 if ((GraphicsOutput
== NULL
) && (UgaDraw
== NULL
)) {
2603 return EFI_UNSUPPORTED
;
2606 CurrentGraphicsOutputMode
= Private
->GraphicsOutput
.Mode
;
2611 if (Private
->CurrentNumberOfUgaDraw
!= 0) {
2613 // If any UGA device has already been added, then there is no need to
2614 // calculate intersection of display mode of different GOP/UGA device,
2615 // since only one display mode will be exported (i.e. user-defined mode)
2620 if (GraphicsOutput
!= NULL
) {
2621 if (Private
->CurrentNumberOfGraphicsOutput
== 0) {
2623 // This is the first Graphics Output device added
2625 CurrentGraphicsOutputMode
->MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
2626 CurrentGraphicsOutputMode
->Mode
= GraphicsOutput
->Mode
->Mode
;
2627 CopyMem (CurrentGraphicsOutputMode
->Info
, GraphicsOutput
->Mode
->Info
, GraphicsOutput
->Mode
->SizeOfInfo
);
2628 CurrentGraphicsOutputMode
->SizeOfInfo
= GraphicsOutput
->Mode
->SizeOfInfo
;
2629 CurrentGraphicsOutputMode
->FrameBufferBase
= GraphicsOutput
->Mode
->FrameBufferBase
;
2630 CurrentGraphicsOutputMode
->FrameBufferSize
= GraphicsOutput
->Mode
->FrameBufferSize
;
2633 // Allocate resource for the private mode buffer
2635 ModeBuffer
= AllocatePool (GraphicsOutput
->Mode
->SizeOfInfo
* GraphicsOutput
->Mode
->MaxMode
);
2636 if (ModeBuffer
== NULL
) {
2637 return EFI_OUT_OF_RESOURCES
;
2639 FreePool (Private
->GraphicsOutputModeBuffer
);
2640 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2643 // Store all supported display modes to the private mode buffer
2646 for (Index
= 0; Index
< GraphicsOutput
->Mode
->MaxMode
; Index
++) {
2647 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) Index
, &SizeOfInfo
, &Info
);
2648 if (EFI_ERROR (Status
)) {
2651 CopyMem (Mode
, Info
, SizeOfInfo
);
2657 // Check intersection of display mode
2659 ModeBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
) * CurrentGraphicsOutputMode
->MaxMode
);
2660 if (ModeBuffer
== NULL
) {
2661 return EFI_OUT_OF_RESOURCES
;
2664 MatchedMode
= ModeBuffer
;
2665 Mode
= &Private
->GraphicsOutputModeBuffer
[0];
2666 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2669 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
2670 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
2671 if (EFI_ERROR (Status
)) {
2674 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2675 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2684 AlreadyExist
= FALSE
;
2686 for (Info
= ModeBuffer
; Info
< MatchedMode
; Info
++) {
2687 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2688 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2689 AlreadyExist
= TRUE
;
2694 if (!AlreadyExist
) {
2695 CopyMem (MatchedMode
, Mode
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2698 // Physical frame buffer is no longer available, change PixelFormat to PixelBltOnly
2700 MatchedMode
->Version
= 0;
2701 MatchedMode
->PixelFormat
= PixelBltOnly
;
2702 ZeroMem (&MatchedMode
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2712 // Drop the old mode buffer, assign it to a new one
2714 FreePool (Private
->GraphicsOutputModeBuffer
);
2715 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2718 // Physical frame buffer is no longer available when there are more than one physical GOP devices
2720 CurrentGraphicsOutputMode
->MaxMode
= (UINT32
) (((UINTN
) MatchedMode
- (UINTN
) ModeBuffer
) / sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2721 CurrentGraphicsOutputMode
->Info
->PixelFormat
= PixelBltOnly
;
2722 ZeroMem (&CurrentGraphicsOutputMode
->Info
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2723 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2724 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2725 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2729 // Graphics console driver can ensure the same mode for all GOP devices
2731 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2732 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2733 if ((Mode
->HorizontalResolution
== GraphicsOutput
->Mode
->Info
->HorizontalResolution
) &&
2734 (Mode
->VerticalResolution
== GraphicsOutput
->Mode
->Info
->VerticalResolution
)) {
2735 CurrentIndex
= Index
;
2739 if (Index
>= CurrentGraphicsOutputMode
->MaxMode
) {
2741 // if user defined mode is not found, set to default mode 800x600
2743 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2744 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2745 if ((Mode
->HorizontalResolution
== 800) && (Mode
->VerticalResolution
== 600)) {
2746 CurrentIndex
= Index
;
2752 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2754 // Graphics console driver can ensure the same mode for all GOP devices
2755 // so we can get the current mode from this video device
2759 &UgaHorizontalResolution
,
2760 &UgaVerticalResolution
,
2765 CurrentGraphicsOutputMode
->MaxMode
= 1;
2766 Info
= CurrentGraphicsOutputMode
->Info
;
2768 Info
->HorizontalResolution
= UgaHorizontalResolution
;
2769 Info
->VerticalResolution
= UgaVerticalResolution
;
2770 Info
->PixelFormat
= PixelBltOnly
;
2771 Info
->PixelsPerScanLine
= UgaHorizontalResolution
;
2772 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2773 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2774 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2777 // Update the private mode buffer
2779 CopyMem (&Private
->GraphicsOutputModeBuffer
[0], Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2782 // Only mode 0 is available to be set
2789 if (GraphicsOutput
!= NULL
) {
2790 Private
->CurrentNumberOfGraphicsOutput
++;
2792 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2793 Private
->CurrentNumberOfUgaDraw
++;
2797 // Force GraphicsOutput mode to be set,
2798 // regardless whether the console is in EfiConsoleControlScreenGraphics or EfiConsoleControlScreenText mode
2800 Private
->HardwareNeedsStarting
= TRUE
;
2802 // Current mode number may need update now, so set it to an invalid mode number
2804 CurrentGraphicsOutputMode
->Mode
= 0xffff;
2806 // Graphics console can ensure all GOP devices have the same mode which can be taken as current mode.
2808 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, (UINT32
) CurrentIndex
);
2811 // If user defined mode is not valid for UGA, set to the default mode 800x600.
2813 if (EFI_ERROR(Status
)) {
2814 (Private
->GraphicsOutputModeBuffer
[0]).HorizontalResolution
= 800;
2815 (Private
->GraphicsOutputModeBuffer
[0]).VerticalResolution
= 600;
2816 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, 0);
2824 This routine will get the current console mode information (column, row)
2825 from ConsoleOutMode variable and set it; if the variable does not exist,
2826 set to user defined console mode.
2828 @param Private Consplitter Text Out pointer.
2834 ConsplitterSetConsoleOutMode (
2835 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2846 CONSOLE_OUT_MODE
*ModeInfo
;
2847 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
2851 TextOut
= &Private
->TextOut
;
2852 MaxMode
= (UINTN
) (TextOut
->Mode
->MaxMode
);
2853 ModeInfoSize
= sizeof (CONSOLE_OUT_MODE
);
2855 ModeInfo
= AllocateZeroPool (sizeof(CONSOLE_OUT_MODE
));
2856 ASSERT(ModeInfo
!= NULL
);
2858 Status
= gRT
->GetVariable (
2860 &gEfiGenericPlatformVariableGuid
,
2867 // Set to the default mode 80 x 25 required by EFI/UEFI spec;
2868 // user can also define other valid default console mode here.
2870 if (EFI_ERROR(Status
)) {
2871 ModeInfo
->Column
= 80;
2873 Status
= gRT
->SetVariable (
2875 &gEfiGenericPlatformVariableGuid
,
2876 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
2877 sizeof (CONSOLE_OUT_MODE
),
2882 for (Mode
= 0; Mode
< MaxMode
; Mode
++) {
2883 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Col
, &Row
);
2884 if (!EFI_ERROR(Status
)) {
2885 if (Col
== ModeInfo
->Column
&& Row
== ModeInfo
->Row
) {
2888 if (Col
== 80 && Row
== 25) {
2894 Status
= TextOut
->SetMode (TextOut
, PreferMode
);
2897 // if current mode setting is failed, default 80x25 mode will be set.
2899 if (EFI_ERROR(Status
)) {
2900 Status
= TextOut
->SetMode (TextOut
, BaseMode
);
2901 ASSERT(!EFI_ERROR(Status
));
2903 ModeInfo
->Column
= 80;
2907 // Update ConOutMode variable
2909 Status
= gRT
->SetVariable (
2911 &gEfiGenericPlatformVariableGuid
,
2912 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
2913 sizeof (CONSOLE_OUT_MODE
),
2918 gBS
->FreePool (ModeInfo
);
2923 Add Text Output Device in Consplitter Text Output list.
2925 @param Private Text Out Splitter pointer.
2926 @param TextOut Simple Text Output protocol pointer.
2927 @param GraphicsOutput Graphics Output protocol pointer.
2928 @param UgaDraw UGA Draw protocol pointer.
2930 @retval EFI_SUCCESS Text Output Device added successfully.
2931 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2935 ConSplitterTextOutAddDevice (
2936 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2937 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
,
2938 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2939 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2943 UINTN CurrentNumOfConsoles
;
2946 UINT32 UgaHorizontalResolution
;
2947 UINT32 UgaVerticalResolution
;
2948 UINT32 UgaColorDepth
;
2949 UINT32 UgaRefreshRate
;
2950 TEXT_OUT_AND_GOP_DATA
*TextAndGop
;
2952 Status
= EFI_SUCCESS
;
2953 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
2956 // If the Text Out List is full, enlarge it by calling growbuffer().
2958 while (CurrentNumOfConsoles
>= Private
->TextOutListCount
) {
2959 Status
= ConSplitterGrowBuffer (
2960 sizeof (TEXT_OUT_AND_GOP_DATA
),
2961 &Private
->TextOutListCount
,
2962 (VOID
**) &Private
->TextOutList
2964 if (EFI_ERROR (Status
)) {
2965 return EFI_OUT_OF_RESOURCES
;
2968 // Also need to reallocate the TextOutModeMap table
2970 Status
= ConSplitterGrowMapTable (Private
);
2971 if (EFI_ERROR (Status
)) {
2972 return EFI_OUT_OF_RESOURCES
;
2976 TextAndGop
= &Private
->TextOutList
[CurrentNumOfConsoles
];
2978 TextAndGop
->TextOut
= TextOut
;
2979 TextAndGop
->GraphicsOutput
= GraphicsOutput
;
2980 TextAndGop
->UgaDraw
= UgaDraw
;
2982 if ((GraphicsOutput
== NULL
) && (UgaDraw
== NULL
)) {
2984 // If No GOP/UGA device then use the ConOut device
2986 TextAndGop
->TextOutEnabled
= TRUE
;
2989 // If GOP/UGA device use ConOut device only used if screen is in Text mode
2991 TextAndGop
->TextOutEnabled
= (BOOLEAN
) (Private
->ConsoleOutputMode
== EfiConsoleControlScreenText
);
2994 if (CurrentNumOfConsoles
== 0) {
2996 // Add the first device's output mode to console splitter's mode list
2998 Status
= ConSplitterAddOutputMode (Private
, TextOut
);
3000 ConSplitterSyncOutputMode (Private
, TextOut
);
3003 Private
->CurrentNumberOfConsoles
++;
3006 // Scan both TextOutList, for the intersection TextOut device
3007 // maybe both ConOut and StdErr incorporate the same Text Out
3008 // device in them, thus the output of both should be synced.
3010 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3012 CurrentMode
= Private
->TextOutMode
.Mode
;
3013 MaxMode
= Private
->TextOutMode
.MaxMode
;
3014 ASSERT (MaxMode
>= 1);
3017 // Update DevNull mode according to current video device
3019 if (FeaturePcdGet (PcdConOutGopSupport
)) {
3020 if ((GraphicsOutput
!= NULL
) || (UgaDraw
!= NULL
)) {
3021 ConSplitterAddGraphicsOutputMode (Private
, GraphicsOutput
, UgaDraw
);
3024 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
3025 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3026 Status
= UgaDraw
->GetMode (
3028 &UgaHorizontalResolution
,
3029 &UgaVerticalResolution
,
3033 if (!EFI_ERROR (Status
)) {
3034 Status
= ConSpliterUgaDrawSetMode (
3036 UgaHorizontalResolution
,
3037 UgaVerticalResolution
,
3043 // If GetMode/SetMode is failed, set to 800x600 mode
3045 if(EFI_ERROR (Status
)) {
3046 Status
= ConSpliterUgaDrawSetMode (
3057 if (Private
->ConsoleOutputMode
== EfiConsoleControlScreenGraphics
&& GraphicsOutput
!= NULL
) {
3059 // We just added a new GOP or UGA device in graphics mode
3061 if (FeaturePcdGet (PcdConOutGopSupport
)) {
3062 DevNullGopSync (Private
, TextAndGop
->GraphicsOutput
, TextAndGop
->UgaDraw
);
3063 } else if (FeaturePcdGet (PcdConOutUgaSupport
)) {
3064 DevNullUgaSync (Private
, TextAndGop
->GraphicsOutput
, TextAndGop
->UgaDraw
);
3066 } else if ((CurrentMode
>= 0) && ((GraphicsOutput
!= NULL
) || (UgaDraw
!= NULL
)) && (CurrentMode
< Private
->TextOutMode
.MaxMode
)) {
3068 // The new console supports the same mode of the current console so sync up
3070 DevNullSyncStdOut (Private
);
3073 // If ConOut, then set the mode to Mode #0 which us 80 x 25
3075 Private
->TextOut
.SetMode (&Private
->TextOut
, 0);
3079 // After adding new console device, all existing console devices should be
3080 // synced to the current shared mode.
3082 ConsplitterSetConsoleOutMode (Private
);
3089 Remove Text Out Device in Consplitter Text Out list.
3091 @param Private Text Out Splitter pointer.
3092 @param TextOut Simple Text Output Pointer protocol pointer.
3094 @retval EFI_SUCCESS Text Out Device removed successfully.
3095 @retval EFI_NOT_FOUND No Text Out Device found.
3099 ConSplitterTextOutDeleteDevice (
3100 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
3101 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
3105 UINTN CurrentNumOfConsoles
;
3106 TEXT_OUT_AND_GOP_DATA
*TextOutList
;
3110 // Remove the specified text-out device data structure from the Text out List,
3111 // and rearrange the remaining data structures in the Text out List.
3113 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
3114 Index
= (INT32
) CurrentNumOfConsoles
- 1;
3115 TextOutList
= Private
->TextOutList
;
3116 while (Index
>= 0) {
3117 if (TextOutList
->TextOut
== TextOut
) {
3118 CopyMem (TextOutList
, TextOutList
+ 1, sizeof (TEXT_OUT_AND_GOP_DATA
) * Index
);
3119 CurrentNumOfConsoles
--;
3120 if (TextOutList
->UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3121 Private
->CurrentNumberOfUgaDraw
--;
3123 if (TextOutList
->GraphicsOutput
!= NULL
) {
3124 Private
->CurrentNumberOfGraphicsOutput
--;
3133 // The specified TextOut is not managed by the ConSplitter driver
3136 return EFI_NOT_FOUND
;
3139 if (CurrentNumOfConsoles
== 0) {
3141 // If the number of consoles is zero clear the Dev NULL device
3143 Private
->CurrentNumberOfConsoles
= 0;
3144 Private
->TextOutMode
.MaxMode
= 1;
3145 Private
->TextOutQueryData
[0].Columns
= 80;
3146 Private
->TextOutQueryData
[0].Rows
= 25;
3147 DevNullTextOutSetMode (Private
, 0);
3152 // Max Mode is realy an intersection of the QueryMode command to all
3153 // devices. So we must copy the QueryMode of the first device to
3157 Private
->TextOutQueryData
,
3158 Private
->TextOutQueryDataCount
* sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
)
3161 FreePool (Private
->TextOutModeMap
);
3162 Private
->TextOutModeMap
= NULL
;
3163 TextOutList
= Private
->TextOutList
;
3166 // Add the first TextOut to the QueryData array and ModeMap table
3168 Status
= ConSplitterAddOutputMode (Private
, TextOutList
->TextOut
);
3171 // Now add one by one
3174 Private
->CurrentNumberOfConsoles
= 1;
3176 while ((UINTN
) Index
< CurrentNumOfConsoles
) {
3177 ConSplitterSyncOutputMode (Private
, TextOutList
->TextOut
);
3179 Private
->CurrentNumberOfConsoles
++;
3183 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3190 Reset the input device and optionaly run diagnostics
3192 @param This Protocol instance pointer.
3193 @param ExtendedVerification Driver may perform diagnostics on reset.
3195 @retval EFI_SUCCESS The device was reset.
3196 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3202 ConSplitterTextInReset (
3203 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3204 IN BOOLEAN ExtendedVerification
3208 EFI_STATUS ReturnStatus
;
3209 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3212 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3214 Private
->KeyEventSignalState
= FALSE
;
3217 // return the worst status met
3219 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3220 Status
= Private
->TextInList
[Index
]->Reset (
3221 Private
->TextInList
[Index
],
3222 ExtendedVerification
3224 if (EFI_ERROR (Status
)) {
3225 ReturnStatus
= Status
;
3229 return ReturnStatus
;
3234 Reads the next keystroke from the input device. The WaitForKey Event can
3235 be used to test for existance of a keystroke via WaitForEvent () call.
3237 @param Private Protocol instance pointer.
3238 @param Key Driver may perform diagnostics on reset.
3240 @retval EFI_SUCCESS The keystroke information was returned.
3241 @retval EFI_NOT_READY There was no keystroke data availiable.
3242 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3248 ConSplitterTextInPrivateReadKeyStroke (
3249 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3250 OUT EFI_INPUT_KEY
*Key
3255 EFI_INPUT_KEY CurrentKey
;
3257 Key
->UnicodeChar
= 0;
3258 Key
->ScanCode
= SCAN_NULL
;
3261 // if no physical console input device exists, return EFI_NOT_READY;
3262 // if any physical console input device has key input,
3263 // return the key and EFI_SUCCESS.
3265 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3266 Status
= Private
->TextInList
[Index
]->ReadKeyStroke (
3267 Private
->TextInList
[Index
],
3270 if (!EFI_ERROR (Status
)) {
3276 return EFI_NOT_READY
;
3281 Return TRUE if StdIn is locked. The ConIn device on the virtual handle is
3282 the only device locked.
3286 @retval TRUE StdIn locked
3287 @retval FALSE StdIn working normally
3291 ConSpliterConssoleControlStdInLocked (
3295 return mConIn
.PasswordEnabled
;
3300 This timer event will fire when StdIn is locked. It will check the key
3301 sequence on StdIn to see if it matches the password. Any error in the
3302 password will cause the check to reset. As long a mConIn.PasswordEnabled is
3303 TRUE the StdIn splitter will not report any input.
3305 @param Event The Event this notify function registered to.
3306 @param Context Pointer to the context data registerd to the
3314 ConSpliterConsoleControlLockStdInEvent (
3321 CHAR16 BackSpaceString
[2];
3322 CHAR16 SpaceString
[2];
3325 Status
= ConSplitterTextInPrivateReadKeyStroke (&mConIn
, &Key
);
3326 if (!EFI_ERROR (Status
)) {
3328 // if it's an ENTER, match password
3330 if ((Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) && (Key
.ScanCode
== SCAN_NULL
)) {
3331 mConIn
.PwdAttempt
[mConIn
.PwdIndex
] = CHAR_NULL
;
3332 if (StrCmp (mConIn
.Password
, mConIn
.PwdAttempt
)) {
3334 // Password not match
3336 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"\n\rPassword not correct\n\r");
3337 mConIn
.PwdIndex
= 0;
3340 // Key matches password sequence
3342 gBS
->SetTimer (mConIn
.LockEvent
, TimerPeriodic
, 0);
3343 mConIn
.PasswordEnabled
= FALSE
;
3344 Status
= EFI_NOT_READY
;
3346 } else if ((Key
.UnicodeChar
== CHAR_BACKSPACE
) && (Key
.ScanCode
== SCAN_NULL
)) {
3350 if (mConIn
.PwdIndex
> 0) {
3351 BackSpaceString
[0] = CHAR_BACKSPACE
;
3352 BackSpaceString
[1] = 0;
3354 SpaceString
[0] = L
' ';
3357 ConSplitterTextOutOutputString (&mConOut
.TextOut
, BackSpaceString
);
3358 ConSplitterTextOutOutputString (&mConOut
.TextOut
, SpaceString
);
3359 ConSplitterTextOutOutputString (&mConOut
.TextOut
, BackSpaceString
);
3363 } else if ((Key
.ScanCode
== SCAN_NULL
) && (Key
.UnicodeChar
>= 32)) {
3365 // If it's not an ENTER, neigher a function key, nor a CTRL-X or ALT-X, record the input
3367 if (mConIn
.PwdIndex
< (MAX_STD_IN_PASSWORD
- 1)) {
3368 if (mConIn
.PwdIndex
== 0) {
3369 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"\n\r");
3372 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"*");
3373 mConIn
.PwdAttempt
[mConIn
.PwdIndex
] = Key
.UnicodeChar
;
3378 } while (!EFI_ERROR (Status
));
3383 If Password is NULL unlock the password state variable and set the event
3384 timer. If the Password is too big return an error. If the Password is valid
3385 Copy the Password and enable state variable and then arm the periodic timer
3387 @param This Console Control protocol pointer.
3388 @param Password The password input.
3390 @retval EFI_SUCCESS Lock the StdIn device
3391 @retval EFI_INVALID_PARAMETER Password is NULL
3392 @retval EFI_OUT_OF_RESOURCES Buffer allocation to store the password fails
3397 ConSpliterConsoleControlLockStdIn (
3398 IN EFI_CONSOLE_CONTROL_PROTOCOL
*This
,
3402 if (Password
== NULL
) {
3403 return EFI_INVALID_PARAMETER
;
3406 if (StrLen (Password
) >= MAX_STD_IN_PASSWORD
) {
3408 // Currently have a max password size
3410 return EFI_OUT_OF_RESOURCES
;
3413 // Save the password, initialize state variables and arm event timer
3415 StrCpy (mConIn
.Password
, Password
);
3416 mConIn
.PasswordEnabled
= TRUE
;
3417 mConIn
.PwdIndex
= 0;
3418 gBS
->SetTimer (mConIn
.LockEvent
, TimerPeriodic
, (10000 * 25));
3425 Reads the next keystroke from the input device. The WaitForKey Event can
3426 be used to test for existance of a keystroke via WaitForEvent () call.
3427 If the ConIn is password locked make it look like no keystroke is availible
3429 @param This Protocol instance pointer.
3430 @param Key Driver may perform diagnostics on reset.
3432 @retval EFI_SUCCESS The keystroke information was returned.
3433 @retval EFI_NOT_READY There was no keystroke data availiable.
3434 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3440 ConSplitterTextInReadKeyStroke (
3441 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3442 OUT EFI_INPUT_KEY
*Key
3445 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3447 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3448 if (Private
->PasswordEnabled
) {
3450 // If StdIn Locked return not ready
3452 return EFI_NOT_READY
;
3455 Private
->KeyEventSignalState
= FALSE
;
3457 return ConSplitterTextInPrivateReadKeyStroke (Private
, Key
);
3462 This event agregates all the events of the ConIn devices in the spliter.
3463 If the ConIn is password locked then return.
3464 If any events of physical ConIn devices are signaled, signal the ConIn
3465 spliter event. This will cause the calling code to call
3466 ConSplitterTextInReadKeyStroke ().
3468 @param Event The Event assoicated with callback.
3469 @param Context Context registered when Event was created.
3476 ConSplitterTextInWaitForKey (
3482 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3485 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
3486 if (Private
->PasswordEnabled
) {
3488 // If StdIn Locked return not ready
3494 // if KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
3496 if (Private
->KeyEventSignalState
) {
3497 gBS
->SignalEvent (Event
);
3501 // if any physical console input device has key input, signal the event.
3503 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3504 Status
= gBS
->CheckEvent (Private
->TextInList
[Index
]->WaitForKey
);
3505 if (!EFI_ERROR (Status
)) {
3506 gBS
->SignalEvent (Event
);
3507 Private
->KeyEventSignalState
= TRUE
;
3515 Test if the key has been registered on input device.
3517 @param RegsiteredData A pointer to a buffer that is filled in with the
3518 keystroke state data for the key that was
3520 @param InputData A pointer to a buffer that is filled in with the
3521 keystroke state data for the key that was
3524 @retval TRUE Key be pressed matches a registered key.
3525 @retval FLASE Match failed.
3530 IN EFI_KEY_DATA
*RegsiteredData
,
3531 IN EFI_KEY_DATA
*InputData
3534 ASSERT (RegsiteredData
!= NULL
&& InputData
!= NULL
);
3536 if ((RegsiteredData
->Key
.ScanCode
!= InputData
->Key
.ScanCode
) ||
3537 (RegsiteredData
->Key
.UnicodeChar
!= InputData
->Key
.UnicodeChar
)) {
3542 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
3544 if (RegsiteredData
->KeyState
.KeyShiftState
!= 0 &&
3545 RegsiteredData
->KeyState
.KeyShiftState
!= InputData
->KeyState
.KeyShiftState
) {
3548 if (RegsiteredData
->KeyState
.KeyToggleState
!= 0 &&
3549 RegsiteredData
->KeyState
.KeyToggleState
!= InputData
->KeyState
.KeyToggleState
) {
3559 Reset the input device and optionaly run diagnostics
3561 @param This Protocol instance pointer.
3562 @param ExtendedVerification Driver may perform diagnostics on reset.
3564 @retval EFI_SUCCESS The device was reset.
3565 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3571 ConSplitterTextInResetEx (
3572 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3573 IN BOOLEAN ExtendedVerification
3577 EFI_STATUS ReturnStatus
;
3578 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3581 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3583 Private
->KeyEventSignalState
= FALSE
;
3586 // return the worst status met
3588 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3589 Status
= Private
->TextInExList
[Index
]->Reset (
3590 Private
->TextInExList
[Index
],
3591 ExtendedVerification
3593 if (EFI_ERROR (Status
)) {
3594 ReturnStatus
= Status
;
3598 return ReturnStatus
;
3604 Reads the next keystroke from the input device. The WaitForKey Event can
3605 be used to test for existance of a keystroke via WaitForEvent () call.
3607 @param This Protocol instance pointer.
3608 @param KeyData A pointer to a buffer that is filled in with the
3609 keystroke state data for the key that was
3612 @retval EFI_SUCCESS The keystroke information was returned.
3613 @retval EFI_NOT_READY There was no keystroke data availiable.
3614 @retval EFI_DEVICE_ERROR The keystroke information was not returned due
3616 @retval EFI_INVALID_PARAMETER KeyData is NULL.
3621 ConSplitterTextInReadKeyStrokeEx (
3622 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3623 OUT EFI_KEY_DATA
*KeyData
3626 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3629 EFI_KEY_DATA CurrentKeyData
;
3632 if (KeyData
== NULL
) {
3633 return EFI_INVALID_PARAMETER
;
3636 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3637 if (Private
->PasswordEnabled
) {
3639 // If StdIn Locked return not ready
3641 return EFI_NOT_READY
;
3644 Private
->KeyEventSignalState
= FALSE
;
3646 KeyData
->Key
.UnicodeChar
= 0;
3647 KeyData
->Key
.ScanCode
= SCAN_NULL
;
3650 // if no physical console input device exists, return EFI_NOT_READY;
3651 // if any physical console input device has key input,
3652 // return the key and EFI_SUCCESS.
3654 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3655 Status
= Private
->TextInExList
[Index
]->ReadKeyStrokeEx (
3656 Private
->TextInExList
[Index
],
3659 if (!EFI_ERROR (Status
)) {
3660 CopyMem (KeyData
, &CurrentKeyData
, sizeof (CurrentKeyData
));
3665 return EFI_NOT_READY
;
3670 Set certain state for the input device.
3672 @param This Protocol instance pointer.
3673 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
3674 state for the input device.
3676 @retval EFI_SUCCESS The device state was set successfully.
3677 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
3678 could not have the setting adjusted.
3679 @retval EFI_UNSUPPORTED The device does not have the ability to set its
3681 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
3686 ConSplitterTextInSetState (
3687 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3688 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
3691 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3695 if (KeyToggleState
== NULL
) {
3696 return EFI_INVALID_PARAMETER
;
3699 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3702 // if no physical console input device exists, return EFI_SUCCESS;
3703 // otherwise return the status of setting state of physical console input device
3705 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3706 Status
= Private
->TextInExList
[Index
]->SetState (
3707 Private
->TextInExList
[Index
],
3710 if (EFI_ERROR (Status
)) {
3721 Register a notification function for a particular keystroke for the input device.
3723 @param This Protocol instance pointer.
3724 @param KeyData A pointer to a buffer that is filled in with the
3725 keystroke information data for the key that was
3727 @param KeyNotificationFunction Points to the function to be called when the key
3728 sequence is typed specified by KeyData.
3729 @param NotifyHandle Points to the unique handle assigned to the
3730 registered notification.
3732 @retval EFI_SUCCESS The notification function was registered
3734 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data
3736 @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.
3741 ConSplitterTextInRegisterKeyNotify (
3742 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3743 IN EFI_KEY_DATA
*KeyData
,
3744 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction
,
3745 OUT EFI_HANDLE
*NotifyHandle
3748 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3751 TEXT_IN_EX_SPLITTER_NOTIFY
*NewNotify
;
3753 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3756 if (KeyData
== NULL
|| NotifyHandle
== NULL
|| KeyNotificationFunction
== NULL
) {
3757 return EFI_INVALID_PARAMETER
;
3760 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3763 // if no physical console input device exists,
3764 // return EFI_SUCCESS directly.
3766 if (Private
->CurrentNumberOfExConsoles
<= 0) {
3771 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
3773 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3774 CurrentNotify
= CR (
3776 TEXT_IN_EX_SPLITTER_NOTIFY
,
3778 TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
3780 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
3781 if (CurrentNotify
->KeyNotificationFn
== KeyNotificationFunction
) {
3782 *NotifyHandle
= CurrentNotify
->NotifyHandle
;
3789 // Allocate resource to save the notification function
3791 NewNotify
= (TEXT_IN_EX_SPLITTER_NOTIFY
*) AllocateZeroPool (sizeof (TEXT_IN_EX_SPLITTER_NOTIFY
));
3792 if (NewNotify
== NULL
) {
3793 return EFI_OUT_OF_RESOURCES
;
3795 NewNotify
->NotifyHandleList
= (EFI_HANDLE
*) AllocateZeroPool (sizeof (EFI_HANDLE
) * Private
->CurrentNumberOfExConsoles
);
3796 if (NewNotify
->NotifyHandleList
== NULL
) {
3797 gBS
->FreePool (NewNotify
);
3798 return EFI_OUT_OF_RESOURCES
;
3800 NewNotify
->Signature
= TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
;
3801 NewNotify
->KeyNotificationFn
= KeyNotificationFunction
;
3802 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (KeyData
));
3805 // Return the wrong status of registering key notify of
3806 // physical console input device if meet problems
3808 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3809 Status
= Private
->TextInExList
[Index
]->RegisterKeyNotify (
3810 Private
->TextInExList
[Index
],
3812 KeyNotificationFunction
,
3813 &NewNotify
->NotifyHandleList
[Index
]
3815 if (EFI_ERROR (Status
)) {
3816 gBS
->FreePool (NewNotify
->NotifyHandleList
);
3817 gBS
->FreePool (NewNotify
);
3823 // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE
3825 Status
= gBS
->InstallMultipleProtocolInterfaces (
3826 &NewNotify
->NotifyHandle
,
3827 &gSimpleTextInExNotifyGuid
,
3831 ASSERT_EFI_ERROR (Status
);
3833 InsertTailList (&mConIn
.NotifyList
, &NewNotify
->NotifyEntry
);
3835 *NotifyHandle
= NewNotify
->NotifyHandle
;
3843 Remove a registered notification function from a particular keystroke.
3845 @param This Protocol instance pointer.
3846 @param NotificationHandle The handle of the notification function being
3849 @retval EFI_SUCCESS The notification function was unregistered
3851 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
3852 @retval EFI_NOT_FOUND Can not find the matching entry in database.
3857 ConSplitterTextInUnregisterKeyNotify (
3858 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3859 IN EFI_HANDLE NotificationHandle
3862 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3865 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3868 if (NotificationHandle
== NULL
) {
3869 return EFI_INVALID_PARAMETER
;
3872 Status
= gBS
->OpenProtocol (
3874 &gSimpleTextInExNotifyGuid
,
3878 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
3880 if (EFI_ERROR (Status
)) {
3881 return EFI_INVALID_PARAMETER
;
3884 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3887 // if no physical console input device exists,
3888 // return EFI_SUCCESS directly.
3890 if (Private
->CurrentNumberOfExConsoles
<= 0) {
3894 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3895 CurrentNotify
= CR (Link
, TEXT_IN_EX_SPLITTER_NOTIFY
, NotifyEntry
, TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
);
3896 if (CurrentNotify
->NotifyHandle
== NotificationHandle
) {
3897 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3898 Status
= Private
->TextInExList
[Index
]->UnregisterKeyNotify (
3899 Private
->TextInExList
[Index
],
3900 CurrentNotify
->NotifyHandleList
[Index
]
3902 if (EFI_ERROR (Status
)) {
3906 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
3907 Status
= gBS
->UninstallMultipleProtocolInterfaces (
3908 CurrentNotify
->NotifyHandle
,
3909 &gSimpleTextInExNotifyGuid
,
3913 ASSERT_EFI_ERROR (Status
);
3914 gBS
->FreePool (CurrentNotify
->NotifyHandleList
);
3915 gBS
->FreePool (CurrentNotify
);
3920 return EFI_NOT_FOUND
;
3926 Reset the input device and optionaly run diagnostics
3928 @param This Protocol instance pointer.
3929 @param ExtendedVerification Driver may perform diagnostics on reset.
3931 @retval EFI_SUCCESS The device was reset.
3932 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3938 ConSplitterSimplePointerReset (
3939 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
3940 IN BOOLEAN ExtendedVerification
3944 EFI_STATUS ReturnStatus
;
3945 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3948 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
3950 Private
->InputEventSignalState
= FALSE
;
3952 if (Private
->CurrentNumberOfPointers
== 0) {
3956 // return the worst status met
3958 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3959 Status
= Private
->PointerList
[Index
]->Reset (
3960 Private
->PointerList
[Index
],
3961 ExtendedVerification
3963 if (EFI_ERROR (Status
)) {
3964 ReturnStatus
= Status
;
3968 return ReturnStatus
;
3973 Reads the next keystroke from the input device. The WaitForKey Event can
3974 be used to test for existance of a keystroke via WaitForEvent () call.
3976 @param Private Protocol instance pointer.
3977 @param State The state information of simple pointer device.
3979 @retval EFI_SUCCESS The keystroke information was returned.
3980 @retval EFI_NOT_READY There was no keystroke data availiable.
3981 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3987 ConSplitterSimplePointerPrivateGetState (
3988 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3989 IN OUT EFI_SIMPLE_POINTER_STATE
*State
3993 EFI_STATUS ReturnStatus
;
3995 EFI_SIMPLE_POINTER_STATE CurrentState
;
3997 State
->RelativeMovementX
= 0;
3998 State
->RelativeMovementY
= 0;
3999 State
->RelativeMovementZ
= 0;
4000 State
->LeftButton
= FALSE
;
4001 State
->RightButton
= FALSE
;
4004 // if no physical console input device exists, return EFI_NOT_READY;
4005 // if any physical console input device has key input,
4006 // return the key and EFI_SUCCESS.
4008 ReturnStatus
= EFI_NOT_READY
;
4009 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
4011 Status
= Private
->PointerList
[Index
]->GetState (
4012 Private
->PointerList
[Index
],
4015 if (!EFI_ERROR (Status
)) {
4016 if (ReturnStatus
== EFI_NOT_READY
) {
4017 ReturnStatus
= EFI_SUCCESS
;
4020 if (CurrentState
.LeftButton
) {
4021 State
->LeftButton
= TRUE
;
4024 if (CurrentState
.RightButton
) {
4025 State
->RightButton
= TRUE
;
4028 if (CurrentState
.RelativeMovementX
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionX
!= 0) {
4029 State
->RelativeMovementX
+= (CurrentState
.RelativeMovementX
* (INT32
) Private
->SimplePointerMode
.ResolutionX
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionX
;
4032 if (CurrentState
.RelativeMovementY
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionY
!= 0) {
4033 State
->RelativeMovementY
+= (CurrentState
.RelativeMovementY
* (INT32
) Private
->SimplePointerMode
.ResolutionY
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionY
;
4036 if (CurrentState
.RelativeMovementZ
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionZ
!= 0) {
4037 State
->RelativeMovementZ
+= (CurrentState
.RelativeMovementZ
* (INT32
) Private
->SimplePointerMode
.ResolutionZ
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionZ
;
4039 } else if (Status
== EFI_DEVICE_ERROR
) {
4040 ReturnStatus
= EFI_DEVICE_ERROR
;
4044 return ReturnStatus
;
4049 Reads the next keystroke from the input device. The WaitForKey Event can
4050 be used to test for existance of a keystroke via WaitForEvent () call.
4051 If the ConIn is password locked make it look like no keystroke is availible
4053 @param This A pointer to protocol instance.
4054 @param State A pointer to state information on the pointer device
4056 @retval EFI_SUCCESS The keystroke information was returned in State.
4057 @retval EFI_NOT_READY There was no keystroke data availiable.
4058 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
4064 ConSplitterSimplePointerGetState (
4065 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
4066 IN OUT EFI_SIMPLE_POINTER_STATE
*State
4069 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4071 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
4072 if (Private
->PasswordEnabled
) {
4074 // If StdIn Locked return not ready
4076 return EFI_NOT_READY
;
4079 Private
->InputEventSignalState
= FALSE
;
4081 return ConSplitterSimplePointerPrivateGetState (Private
, State
);
4086 This event agregates all the events of the ConIn devices in the spliter.
4087 If the ConIn is password locked then return.
4088 If any events of physical ConIn devices are signaled, signal the ConIn
4089 spliter event. This will cause the calling code to call
4090 ConSplitterTextInReadKeyStroke ().
4092 @param Event The Event assoicated with callback.
4093 @param Context Context registered when Event was created.
4100 ConSplitterSimplePointerWaitForInput (
4106 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4109 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4110 if (Private
->PasswordEnabled
) {
4112 // If StdIn Locked return not ready
4118 // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
4120 if (Private
->InputEventSignalState
) {
4121 gBS
->SignalEvent (Event
);
4125 // if any physical console input device has key input, signal the event.
4127 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
4128 Status
= gBS
->CheckEvent (Private
->PointerList
[Index
]->WaitForInput
);
4129 if (!EFI_ERROR (Status
)) {
4130 gBS
->SignalEvent (Event
);
4131 Private
->InputEventSignalState
= TRUE
;
4137 Resets the pointer device hardware.
4139 @param This Protocol instance pointer.
4140 @param ExtendedVerification Driver may perform diagnostics on reset.
4142 @retval EFI_SUCCESS The device was reset.
4143 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
4149 ConSplitterAbsolutePointerReset (
4150 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4151 IN BOOLEAN ExtendedVerification
4155 EFI_STATUS ReturnStatus
;
4156 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4159 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4161 Private
->AbsoluteInputEventSignalState
= FALSE
;
4163 if (Private
->CurrentNumberOfAbsolutePointers
== 0) {
4167 // return the worst status met
4169 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4170 Status
= Private
->AbsolutePointerList
[Index
]->Reset (
4171 Private
->AbsolutePointerList
[Index
],
4172 ExtendedVerification
4174 if (EFI_ERROR (Status
)) {
4175 ReturnStatus
= Status
;
4179 return ReturnStatus
;
4184 Retrieves the current state of a pointer device.
4186 @param This Protocol instance pointer.
4187 @param State A pointer to the state information on the
4190 @retval EFI_SUCCESS The state of the pointer device was returned in
4192 @retval EFI_NOT_READY The state of the pointer device has not changed
4193 since the last call to GetState().
4194 @retval EFI_DEVICE_ERROR A device error occurred while attempting to
4195 retrieve the pointer device's current state.
4200 ConSplitterAbsolutePointerGetState (
4201 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4202 IN OUT EFI_ABSOLUTE_POINTER_STATE
*State
4205 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4207 EFI_STATUS ReturnStatus
;
4209 EFI_ABSOLUTE_POINTER_STATE CurrentState
;
4212 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4213 if (Private
->PasswordEnabled
) {
4215 // If StdIn Locked return not ready
4217 return EFI_NOT_READY
;
4220 Private
->AbsoluteInputEventSignalState
= FALSE
;
4222 State
->CurrentX
= 0;
4223 State
->CurrentY
= 0;
4224 State
->CurrentZ
= 0;
4225 State
->ActiveButtons
= 0;
4228 // if no physical pointer device exists, return EFI_NOT_READY;
4229 // if any physical pointer device has changed state,
4230 // return the state and EFI_SUCCESS.
4232 ReturnStatus
= EFI_NOT_READY
;
4233 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4235 Status
= Private
->AbsolutePointerList
[Index
]->GetState (
4236 Private
->AbsolutePointerList
[Index
],
4239 if (!EFI_ERROR (Status
)) {
4240 if (ReturnStatus
== EFI_NOT_READY
) {
4241 ReturnStatus
= EFI_SUCCESS
;
4244 State
->ActiveButtons
= CurrentState
.ActiveButtons
;
4246 if (!(Private
->AbsolutePointerMode
.AbsoluteMinX
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxX
== 0)) {
4247 State
->CurrentX
= CurrentState
.CurrentX
;
4249 if (!(Private
->AbsolutePointerMode
.AbsoluteMinY
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxY
== 0)) {
4250 State
->CurrentY
= CurrentState
.CurrentY
;
4252 if (!(Private
->AbsolutePointerMode
.AbsoluteMinZ
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxZ
== 0)) {
4253 State
->CurrentZ
= CurrentState
.CurrentZ
;
4256 } else if (Status
== EFI_DEVICE_ERROR
) {
4257 ReturnStatus
= EFI_DEVICE_ERROR
;
4261 return ReturnStatus
;
4266 This event agregates all the events of the pointer devices in the splitter.
4267 If the ConIn is password locked then return.
4268 If any events of physical pointer devices are signaled, signal the pointer
4269 splitter event. This will cause the calling code to call
4270 ConSplitterAbsolutePointerGetState ().
4272 @param Event The Event assoicated with callback.
4273 @param Context Context registered when Event was created.
4280 ConSplitterAbsolutePointerWaitForInput (
4286 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4289 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4290 if (Private
->PasswordEnabled
) {
4292 // If StdIn Locked return not ready
4298 // if AbsoluteInputEventSignalState is flagged before,
4299 // and not cleared by Reset() or GetState(), signal it
4301 if (Private
->AbsoluteInputEventSignalState
) {
4302 gBS
->SignalEvent (Event
);
4306 // if any physical console input device has key input, signal the event.
4308 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4309 Status
= gBS
->CheckEvent (Private
->AbsolutePointerList
[Index
]->WaitForInput
);
4310 if (!EFI_ERROR (Status
)) {
4311 gBS
->SignalEvent (Event
);
4312 Private
->AbsoluteInputEventSignalState
= TRUE
;
4319 Reset the text output device hardware and optionaly run diagnostics
4321 @param This Protocol instance pointer.
4322 @param ExtendedVerification Driver may perform more exhaustive verfication
4323 operation of the device during reset.
4325 @retval EFI_SUCCESS The text output device was reset.
4326 @retval EFI_DEVICE_ERROR The text output device is not functioning
4327 correctly and could not be reset.
4332 ConSplitterTextOutReset (
4333 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4334 IN BOOLEAN ExtendedVerification
4338 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4340 EFI_STATUS ReturnStatus
;
4342 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4345 // return the worst status met
4347 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4349 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4351 Status
= Private
->TextOutList
[Index
].TextOut
->Reset (
4352 Private
->TextOutList
[Index
].TextOut
,
4353 ExtendedVerification
4355 if (EFI_ERROR (Status
)) {
4356 ReturnStatus
= Status
;
4361 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BLACK
));
4363 Status
= DevNullTextOutSetMode (Private
, 0);
4364 if (EFI_ERROR (Status
)) {
4365 ReturnStatus
= Status
;
4368 return ReturnStatus
;
4373 Write a Unicode string to the output device.
4375 @param This Protocol instance pointer.
4376 @param WString The NULL-terminated Unicode string to be
4377 displayed on the output device(s). All output
4378 devices must also support the Unicode drawing
4379 defined in this file.
4381 @retval EFI_SUCCESS The string was output to the device.
4382 @retval EFI_DEVICE_ERROR The device reported an error while attempting to
4384 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
4386 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
4387 characters in the Unicode string could not be
4388 rendered and were skipped.
4393 ConSplitterTextOutOutputString (
4394 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4399 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4401 UINTN BackSpaceCount
;
4402 EFI_STATUS ReturnStatus
;
4403 CHAR16
*TargetString
;
4405 This
->SetAttribute (This
, This
->Mode
->Attribute
);
4407 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4410 for (TargetString
= WString
; *TargetString
!= L
'\0'; TargetString
++) {
4411 if (*TargetString
== CHAR_BACKSPACE
) {
4417 if (BackSpaceCount
== 0) {
4418 TargetString
= WString
;
4420 TargetString
= AllocatePool (sizeof (CHAR16
) * (StrLen (WString
) + BackSpaceCount
+ 1));
4421 StrCpy (TargetString
, WString
);
4424 // return the worst status met
4426 Status
= DevNullTextOutOutputString (Private
, TargetString
);
4427 if (EFI_ERROR (Status
)) {
4428 ReturnStatus
= Status
;
4431 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4433 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4434 Status
= Private
->TextOutList
[Index
].TextOut
->OutputString (
4435 Private
->TextOutList
[Index
].TextOut
,
4438 if (EFI_ERROR (Status
)) {
4439 ReturnStatus
= Status
;
4444 if (BackSpaceCount
> 0) {
4445 FreePool (TargetString
);
4448 return ReturnStatus
;
4453 Verifies that all characters in a Unicode string can be output to the
4456 @param This Protocol instance pointer.
4457 @param WString The NULL-terminated Unicode string to be
4458 examined for the output device(s).
4460 @retval EFI_SUCCESS The device(s) are capable of rendering the
4462 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string
4463 cannot be rendered by one or more of the output
4464 devices mapped by the EFI handle.
4469 ConSplitterTextOutTestString (
4470 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4475 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4477 EFI_STATUS ReturnStatus
;
4479 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4482 // return the worst status met
4484 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4485 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4486 Status
= Private
->TextOutList
[Index
].TextOut
->TestString (
4487 Private
->TextOutList
[Index
].TextOut
,
4490 if (EFI_ERROR (Status
)) {
4491 ReturnStatus
= Status
;
4496 // There is no DevNullTextOutTestString () since a Unicode buffer would
4497 // always return EFI_SUCCESS.
4498 // ReturnStatus will be EFI_SUCCESS if no consoles are present
4500 return ReturnStatus
;
4505 Returns information for an available text mode that the output device(s)
4508 @param This Protocol instance pointer.
4509 @param ModeNumber The mode number to return information on.
4510 @param Columns Returns the columns of the text output device
4511 for the requested ModeNumber.
4512 @param Rows Returns the rows of the text output device
4513 for the requested ModeNumber.
4515 @retval EFI_SUCCESS The requested mode information was returned.
4516 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4518 @retval EFI_UNSUPPORTED The mode number was not valid.
4523 ConSplitterTextOutQueryMode (
4524 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4525 IN UINTN ModeNumber
,
4530 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4532 INT32
*TextOutModeMap
;
4534 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4537 // Check whether param ModeNumber is valid.
4538 // ModeNumber should be within range 0 ~ MaxMode - 1.
4540 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4541 return EFI_UNSUPPORTED
;
4544 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4545 return EFI_UNSUPPORTED
;
4549 // We get the available mode from mode intersection map if it's available
4551 if (Private
->TextOutModeMap
!= NULL
) {
4552 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4553 CurrentMode
= (UINTN
)(*TextOutModeMap
);
4554 *Columns
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4555 *Rows
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4557 *Columns
= Private
->TextOutQueryData
[ModeNumber
].Columns
;
4558 *Rows
= Private
->TextOutQueryData
[ModeNumber
].Rows
;
4561 if (*Columns
<= 0 && *Rows
<= 0) {
4562 return EFI_UNSUPPORTED
;
4571 Sets the output device(s) to a specified mode.
4573 @param This Protocol instance pointer.
4574 @param ModeNumber The mode number to set.
4576 @retval EFI_SUCCESS The requested text mode was set.
4577 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4579 @retval EFI_UNSUPPORTED The mode number was not valid.
4584 ConSplitterTextOutSetMode (
4585 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4590 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4592 INT32
*TextOutModeMap
;
4593 EFI_STATUS ReturnStatus
;
4595 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4598 // Check whether param ModeNumber is valid.
4599 // ModeNumber should be within range 0 ~ MaxMode - 1.
4601 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4602 return EFI_UNSUPPORTED
;
4605 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4606 return EFI_UNSUPPORTED
;
4609 // If the mode is being set to the curent mode, then just clear the screen and return.
4611 if (Private
->TextOutMode
.Mode
== (INT32
) ModeNumber
) {
4612 return ConSplitterTextOutClearScreen (This
);
4615 // return the worst status met
4617 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4618 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4620 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4621 Status
= Private
->TextOutList
[Index
].TextOut
->SetMode (
4622 Private
->TextOutList
[Index
].TextOut
,
4623 TextOutModeMap
[Index
]
4626 // If this console device is based on a GOP or UGA device, then sync up the bitmap from
4627 // the GOP/UGA splitter and reclear the text portion of the display in the new mode.
4629 if ((Private
->TextOutList
[Index
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[Index
].UgaDraw
!= NULL
)) {
4630 Private
->TextOutList
[Index
].TextOut
->ClearScreen (Private
->TextOutList
[Index
].TextOut
);
4633 if (EFI_ERROR (Status
)) {
4634 ReturnStatus
= Status
;
4639 // The DevNull Console will support any possible mode as it allocates memory
4641 Status
= DevNullTextOutSetMode (Private
, ModeNumber
);
4642 if (EFI_ERROR (Status
)) {
4643 ReturnStatus
= Status
;
4646 return ReturnStatus
;
4651 Sets the background and foreground colors for the OutputString () and
4652 ClearScreen () functions.
4654 @param This Protocol instance pointer.
4655 @param Attribute The attribute to set. Bits 0..3 are the
4656 foreground color, and bits 4..6 are the
4657 background color. All other bits are undefined
4658 and must be zero. The valid Attributes are
4659 defined in this file.
4661 @retval EFI_SUCCESS The attribute was set.
4662 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4664 @retval EFI_UNSUPPORTED The attribute requested is not defined.
4669 ConSplitterTextOutSetAttribute (
4670 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4675 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4677 EFI_STATUS ReturnStatus
;
4679 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4682 // Check whether param Attribute is valid.
4684 if ( (Attribute
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4685 return EFI_UNSUPPORTED
;
4689 // return the worst status met
4691 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4693 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4694 Status
= Private
->TextOutList
[Index
].TextOut
->SetAttribute (
4695 Private
->TextOutList
[Index
].TextOut
,
4698 if (EFI_ERROR (Status
)) {
4699 ReturnStatus
= Status
;
4704 Private
->TextOutMode
.Attribute
= (INT32
) Attribute
;
4706 return ReturnStatus
;
4711 Clears the output device(s) display to the currently selected background
4714 @param This Protocol instance pointer.
4716 @retval EFI_SUCCESS The operation completed successfully.
4717 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4719 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4724 ConSplitterTextOutClearScreen (
4725 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
4729 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4731 EFI_STATUS ReturnStatus
;
4733 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4736 // return the worst status met
4738 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4740 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4741 Status
= Private
->TextOutList
[Index
].TextOut
->ClearScreen (Private
->TextOutList
[Index
].TextOut
);
4742 if (EFI_ERROR (Status
)) {
4743 ReturnStatus
= Status
;
4748 Status
= DevNullTextOutClearScreen (Private
);
4749 if (EFI_ERROR (Status
)) {
4750 ReturnStatus
= Status
;
4753 return ReturnStatus
;
4758 Sets the current coordinates of the cursor position
4760 @param This Protocol instance pointer.
4761 @param Column The column position to set the cursor to. Must be
4762 greater than or equal to zero and less than the
4763 number of columns by QueryMode ().
4764 @param Row The row position to set the cursor to. Must be
4765 greater than or equal to zero and less than the
4766 number of rows by QueryMode ().
4768 @retval EFI_SUCCESS The operation completed successfully.
4769 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4771 @retval EFI_UNSUPPORTED The output device is not in a valid text mode,
4772 or the cursor position is invalid for the
4778 ConSplitterTextOutSetCursorPosition (
4779 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4785 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4787 EFI_STATUS ReturnStatus
;
4790 INT32
*TextOutModeMap
;
4794 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4795 TextOutModeMap
= NULL
;
4796 ModeNumber
= Private
->TextOutMode
.Mode
;
4799 // Get current MaxColumn and MaxRow from intersection map
4801 if (Private
->TextOutModeMap
!= NULL
) {
4802 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4803 CurrentMode
= *TextOutModeMap
;
4805 CurrentMode
= ModeNumber
;
4808 MaxColumn
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4809 MaxRow
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4811 if (Column
>= MaxColumn
|| Row
>= MaxRow
) {
4812 return EFI_UNSUPPORTED
;
4815 // return the worst status met
4817 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4819 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4820 Status
= Private
->TextOutList
[Index
].TextOut
->SetCursorPosition (
4821 Private
->TextOutList
[Index
].TextOut
,
4825 if (EFI_ERROR (Status
)) {
4826 ReturnStatus
= Status
;
4831 DevNullTextOutSetCursorPosition (Private
, Column
, Row
);
4833 return ReturnStatus
;
4838 Makes the cursor visible or invisible
4840 @param This Protocol instance pointer.
4841 @param Visible If TRUE, the cursor is set to be visible. If
4842 FALSE, the cursor is set to be invisible.
4844 @retval EFI_SUCCESS The operation completed successfully.
4845 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4846 the request, or the device does not support
4847 changing the cursor mode.
4848 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4853 ConSplitterTextOutEnableCursor (
4854 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4859 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4861 EFI_STATUS ReturnStatus
;
4863 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4866 // return the worst status met
4868 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4870 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4871 Status
= Private
->TextOutList
[Index
].TextOut
->EnableCursor (
4872 Private
->TextOutList
[Index
].TextOut
,
4875 if (EFI_ERROR (Status
)) {
4876 ReturnStatus
= Status
;
4881 DevNullTextOutEnableCursor (Private
, Visible
);
4883 return ReturnStatus
;