2 Console Splitter Driver. Any Handle that attatched console I/O protocols
3 (Console In device, Console Out device, Console Error device, Simple Pointer
4 protocol, Absolute Pointer protocol) can be bound by this driver.
6 So far it works like any other driver by opening a SimpleTextIn and/or
7 SimpleTextOut protocol with EFI_OPEN_PROTOCOL_BY_DRIVER attributes. The big
8 difference is this driver does not layer a protocol on the passed in
9 handle, or construct a child handle like a standard device or bus driver.
10 This driver produces three virtual handles as children, one for console input
11 splitter, one for console output splitter and one for error output splitter.
12 These 3 virtual handles would be installed on gST.
14 Each virtual handle, that supports the Console I/O protocol, will be produced
15 in the driver entry point. The virtual handle are added on driver entry and
16 never removed. Such design ensures sytem function well during none console
19 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
20 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
21 This program and the accompanying materials
22 are licensed and made available under the terms and conditions of the BSD License
23 which accompanies this distribution. The full text of the license may be found at
24 http://opensource.org/licenses/bsd-license.php
26 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
27 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
31 #include "ConSplitter.h"
34 // Identify if ConIn is connected in PcdConInConnectOnDemand enabled mode.
35 // default not connect
37 BOOLEAN mConInIsConnect
= FALSE
;
40 // Text In Splitter Private Data template
42 GLOBAL_REMOVE_IF_UNREFERENCED TEXT_IN_SPLITTER_PRIVATE_DATA mConIn
= {
43 TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE
,
47 ConSplitterTextInReset
,
48 ConSplitterTextInReadKeyStroke
,
52 (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
**) NULL
,
56 ConSplitterTextInResetEx
,
57 ConSplitterTextInReadKeyStrokeEx
,
59 ConSplitterTextInSetState
,
60 ConSplitterTextInRegisterKeyNotify
,
61 ConSplitterTextInUnregisterKeyNotify
64 (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
**) NULL
,
72 ConSplitterSimplePointerReset
,
73 ConSplitterSimplePointerGetState
,
75 (EFI_SIMPLE_POINTER_MODE
*) NULL
85 (EFI_SIMPLE_POINTER_PROTOCOL
**) NULL
,
89 ConSplitterAbsolutePointerReset
,
90 ConSplitterAbsolutePointerGetState
,
92 (EFI_ABSOLUTE_POINTER_MODE
*) NULL
98 0x10000, // AbsoluteMaxX
99 0x10000, // AbsoluteMaxY
100 0x10000, // AbsoluteMaxZ
104 (EFI_ABSOLUTE_POINTER_PROTOCOL
**) NULL
,
114 // Uga Draw Protocol Private Data template
116 GLOBAL_REMOVE_IF_UNREFERENCED EFI_UGA_DRAW_PROTOCOL mUgaDrawProtocolTemplate
= {
117 ConSplitterUgaDrawGetMode
,
118 ConSplitterUgaDrawSetMode
,
119 ConSplitterUgaDrawBlt
123 // Graphics Output Protocol Private Data template
125 GLOBAL_REMOVE_IF_UNREFERENCED EFI_GRAPHICS_OUTPUT_PROTOCOL mGraphicsOutputProtocolTemplate
= {
126 ConSplitterGraphicsOutputQueryMode
,
127 ConSplitterGraphicsOutputSetMode
,
128 ConSplitterGraphicsOutputBlt
,
134 // Text Out Splitter Private Data template
136 GLOBAL_REMOVE_IF_UNREFERENCED TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut
= {
137 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE
,
140 ConSplitterTextOutReset
,
141 ConSplitterTextOutOutputString
,
142 ConSplitterTextOutTestString
,
143 ConSplitterTextOutQueryMode
,
144 ConSplitterTextOutSetMode
,
145 ConSplitterTextOutSetAttribute
,
146 ConSplitterTextOutClearScreen
,
147 ConSplitterTextOutSetCursorPosition
,
148 ConSplitterTextOutEnableCursor
,
149 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
176 (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*) NULL
,
181 (TEXT_OUT_AND_GOP_DATA
*) NULL
,
183 (TEXT_OUT_SPLITTER_QUERY_DATA
*) NULL
,
189 // Standard Error Text Out Splitter Data Template
191 GLOBAL_REMOVE_IF_UNREFERENCED TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr
= {
192 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE
,
195 ConSplitterTextOutReset
,
196 ConSplitterTextOutOutputString
,
197 ConSplitterTextOutTestString
,
198 ConSplitterTextOutQueryMode
,
199 ConSplitterTextOutSetMode
,
200 ConSplitterTextOutSetAttribute
,
201 ConSplitterTextOutClearScreen
,
202 ConSplitterTextOutSetCursorPosition
,
203 ConSplitterTextOutEnableCursor
,
204 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
231 (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*) NULL
,
236 (TEXT_OUT_AND_GOP_DATA
*) NULL
,
238 (TEXT_OUT_SPLITTER_QUERY_DATA
*) NULL
,
244 // Driver binding instance for Console Input Device
246 EFI_DRIVER_BINDING_PROTOCOL gConSplitterConInDriverBinding
= {
247 ConSplitterConInDriverBindingSupported
,
248 ConSplitterConInDriverBindingStart
,
249 ConSplitterConInDriverBindingStop
,
256 // Driver binding instance for Console Out device
258 EFI_DRIVER_BINDING_PROTOCOL gConSplitterConOutDriverBinding
= {
259 ConSplitterConOutDriverBindingSupported
,
260 ConSplitterConOutDriverBindingStart
,
261 ConSplitterConOutDriverBindingStop
,
268 // Driver binding instance for Standard Error device
270 EFI_DRIVER_BINDING_PROTOCOL gConSplitterStdErrDriverBinding
= {
271 ConSplitterStdErrDriverBindingSupported
,
272 ConSplitterStdErrDriverBindingStart
,
273 ConSplitterStdErrDriverBindingStop
,
280 // Driver binding instance for Simple Pointer protocol
282 EFI_DRIVER_BINDING_PROTOCOL gConSplitterSimplePointerDriverBinding
= {
283 ConSplitterSimplePointerDriverBindingSupported
,
284 ConSplitterSimplePointerDriverBindingStart
,
285 ConSplitterSimplePointerDriverBindingStop
,
292 // Driver binding instance for Absolute Pointer protocol
294 EFI_DRIVER_BINDING_PROTOCOL gConSplitterAbsolutePointerDriverBinding
= {
295 ConSplitterAbsolutePointerDriverBindingSupported
,
296 ConSplitterAbsolutePointerDriverBindingStart
,
297 ConSplitterAbsolutePointerDriverBindingStop
,
304 The Entry Point for module ConSplitter. The user code starts with this function.
306 Installs driver module protocols and. Creates virtual device handles for ConIn,
307 ConOut, and StdErr. Installs Simple Text In protocol, Simple Text In Ex protocol,
308 Simple Pointer protocol, Absolute Pointer protocol on those virtual handlers.
309 Installs Graphics Output protocol and/or UGA Draw protocol if needed.
311 @param[in] ImageHandle The firmware allocated handle for the EFI image.
312 @param[in] SystemTable A pointer to the EFI System Table.
314 @retval EFI_SUCCESS The entry point is executed successfully.
315 @retval other Some error occurs when executing this entry point.
320 ConSplitterDriverEntry(
321 IN EFI_HANDLE ImageHandle
,
322 IN EFI_SYSTEM_TABLE
*SystemTable
328 // Install driver model protocol(s).
330 Status
= EfiLibInstallDriverBindingComponentName2 (
333 &gConSplitterConInDriverBinding
,
335 &gConSplitterConInComponentName
,
336 &gConSplitterConInComponentName2
338 ASSERT_EFI_ERROR (Status
);
340 Status
= EfiLibInstallDriverBindingComponentName2 (
343 &gConSplitterSimplePointerDriverBinding
,
345 &gConSplitterSimplePointerComponentName
,
346 &gConSplitterSimplePointerComponentName2
348 ASSERT_EFI_ERROR (Status
);
350 Status
= EfiLibInstallDriverBindingComponentName2 (
353 &gConSplitterAbsolutePointerDriverBinding
,
355 &gConSplitterAbsolutePointerComponentName
,
356 &gConSplitterAbsolutePointerComponentName2
358 ASSERT_EFI_ERROR (Status
);
360 Status
= EfiLibInstallDriverBindingComponentName2 (
363 &gConSplitterConOutDriverBinding
,
365 &gConSplitterConOutComponentName
,
366 &gConSplitterConOutComponentName2
368 ASSERT_EFI_ERROR (Status
);
370 Status
= EfiLibInstallDriverBindingComponentName2 (
373 &gConSplitterStdErrDriverBinding
,
375 &gConSplitterStdErrComponentName
,
376 &gConSplitterStdErrComponentName2
378 ASSERT_EFI_ERROR (Status
);
381 // Either Graphics Output protocol or UGA Draw protocol must be supported.
383 ASSERT (FeaturePcdGet (PcdConOutGopSupport
) ||
384 FeaturePcdGet (PcdConOutUgaSupport
));
387 // The driver creates virtual handles for ConIn, ConOut, StdErr.
388 // The virtual handles will always exist even if no console exist in the
389 // system. This is need to support hotplug devices like USB.
392 // Create virtual device handle for ConIn Splitter
394 Status
= ConSplitterTextInConstructor (&mConIn
);
395 if (!EFI_ERROR (Status
)) {
396 Status
= gBS
->InstallMultipleProtocolInterfaces (
397 &mConIn
.VirtualHandle
,
398 &gEfiSimpleTextInProtocolGuid
,
400 &gEfiSimpleTextInputExProtocolGuid
,
402 &gEfiSimplePointerProtocolGuid
,
403 &mConIn
.SimplePointer
,
404 &gEfiAbsolutePointerProtocolGuid
,
405 &mConIn
.AbsolutePointer
,
408 if (!EFI_ERROR (Status
)) {
410 // Update the EFI System Table with new virtual console
411 // and update the pointer to Simple Text Input protocol.
413 gST
->ConsoleInHandle
= mConIn
.VirtualHandle
;
414 gST
->ConIn
= &mConIn
.TextIn
;
418 // Create virtual device handle for ConOut Splitter
420 Status
= ConSplitterTextOutConstructor (&mConOut
);
421 if (!EFI_ERROR (Status
)) {
422 Status
= gBS
->InstallMultipleProtocolInterfaces (
423 &mConOut
.VirtualHandle
,
424 &gEfiSimpleTextOutProtocolGuid
,
428 if (!EFI_ERROR (Status
)) {
430 // Update the EFI System Table with new virtual console
431 // and Update the pointer to Text Output protocol.
433 gST
->ConsoleOutHandle
= mConOut
.VirtualHandle
;
434 gST
->ConOut
= &mConOut
.TextOut
;
440 // Create virtual device handle for StdErr Splitter
442 Status
= ConSplitterTextOutConstructor (&mStdErr
);
443 if (!EFI_ERROR (Status
)) {
444 Status
= gBS
->InstallMultipleProtocolInterfaces (
445 &mStdErr
.VirtualHandle
,
446 &gEfiSimpleTextOutProtocolGuid
,
450 if (!EFI_ERROR (Status
)) {
452 // Update the EFI System Table with new virtual console
453 // and update the pointer to Text Output protocol.
455 gST
->StandardErrorHandle
= mStdErr
.VirtualHandle
;
456 gST
->StdErr
= &mStdErr
.TextOut
;
461 // Update the CRC32 in the EFI System Table header
464 gBS
->CalculateCrc32 (
475 Construct console input devices' private data.
477 @param ConInPrivate A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA
480 @retval EFI_OUT_OF_RESOURCES Out of resources.
481 @retval EFI_SUCCESS Text Input Devcie's private data has been constructed.
482 @retval other Failed to construct private data.
486 ConSplitterTextInConstructor (
487 TEXT_IN_SPLITTER_PRIVATE_DATA
*ConInPrivate
493 // Allocate buffer for Simple Text Input device
495 Status
= ConSplitterGrowBuffer (
496 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
497 &ConInPrivate
->TextInListCount
,
498 (VOID
**) &ConInPrivate
->TextInList
500 if (EFI_ERROR (Status
)) {
501 return EFI_OUT_OF_RESOURCES
;
505 // Create Event to wait for a key
507 Status
= gBS
->CreateEvent (
510 ConSplitterTextInWaitForKey
,
512 &ConInPrivate
->TextIn
.WaitForKey
514 ASSERT_EFI_ERROR (Status
);
517 // Allocate buffer for Simple Text Input Ex device
519 Status
= ConSplitterGrowBuffer (
520 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
521 &ConInPrivate
->TextInExListCount
,
522 (VOID
**) &ConInPrivate
->TextInExList
524 if (EFI_ERROR (Status
)) {
525 return EFI_OUT_OF_RESOURCES
;
528 // Create Event to wait for a key Ex
530 Status
= gBS
->CreateEvent (
533 ConSplitterTextInWaitForKey
,
535 &ConInPrivate
->TextInEx
.WaitForKeyEx
537 ASSERT_EFI_ERROR (Status
);
539 InitializeListHead (&ConInPrivate
->NotifyList
);
541 ConInPrivate
->AbsolutePointer
.Mode
= &ConInPrivate
->AbsolutePointerMode
;
543 // Allocate buffer for Absolute Pointer device
545 Status
= ConSplitterGrowBuffer (
546 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
547 &ConInPrivate
->AbsolutePointerListCount
,
548 (VOID
**) &ConInPrivate
->AbsolutePointerList
550 if (EFI_ERROR (Status
)) {
551 return EFI_OUT_OF_RESOURCES
;
554 // Create Event to wait for device input for Absolute pointer device
556 Status
= gBS
->CreateEvent (
559 ConSplitterAbsolutePointerWaitForInput
,
561 &ConInPrivate
->AbsolutePointer
.WaitForInput
563 ASSERT_EFI_ERROR (Status
);
565 ConInPrivate
->SimplePointer
.Mode
= &ConInPrivate
->SimplePointerMode
;
567 // Allocate buffer for Simple Pointer device
569 Status
= ConSplitterGrowBuffer (
570 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
571 &ConInPrivate
->PointerListCount
,
572 (VOID
**) &ConInPrivate
->PointerList
574 if (EFI_ERROR (Status
)) {
575 return EFI_OUT_OF_RESOURCES
;
578 // Create Event to wait for device input for Simple pointer device
580 Status
= gBS
->CreateEvent (
583 ConSplitterSimplePointerWaitForInput
,
585 &ConInPrivate
->SimplePointer
.WaitForInput
587 ASSERT_EFI_ERROR (Status
);
589 // Create Event to signal ConIn connection request
591 Status
= gBS
->CreateEventEx (
594 ConSplitterEmptyCallbackFunction
,
596 &gConnectConInEventGuid
,
597 &ConInPrivate
->ConnectConInEvent
604 Construct console output devices' private data.
606 @param ConOutPrivate A pointer to the TEXT_OUT_SPLITTER_PRIVATE_DATA
609 @retval EFI_OUT_OF_RESOURCES Out of resources.
610 @retval EFI_SUCCESS Text Input Devcie's private data has been constructed.
614 ConSplitterTextOutConstructor (
615 TEXT_OUT_SPLITTER_PRIVATE_DATA
*ConOutPrivate
619 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
622 // Copy protocols template
624 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
625 CopyMem (&ConOutPrivate
->UgaDraw
, &mUgaDrawProtocolTemplate
, sizeof (EFI_UGA_DRAW_PROTOCOL
));
627 if (FeaturePcdGet (PcdConOutGopSupport
)) {
628 CopyMem (&ConOutPrivate
->GraphicsOutput
, &mGraphicsOutputProtocolTemplate
, sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL
));
632 // Initilize console output splitter's private data.
634 ConOutPrivate
->TextOut
.Mode
= &ConOutPrivate
->TextOutMode
;
637 // When new console device is added, the new mode will be set later,
638 // so put current mode back to init state.
640 ConOutPrivate
->TextOutMode
.Mode
= 0xFF;
642 // Allocate buffer for Console Out device
644 Status
= ConSplitterGrowBuffer (
645 sizeof (TEXT_OUT_AND_GOP_DATA
),
646 &ConOutPrivate
->TextOutListCount
,
647 (VOID
**) &ConOutPrivate
->TextOutList
649 if (EFI_ERROR (Status
)) {
650 return EFI_OUT_OF_RESOURCES
;
653 // Allocate buffer for Text Out query data
655 Status
= ConSplitterGrowBuffer (
656 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
657 &ConOutPrivate
->TextOutQueryDataCount
,
658 (VOID
**) &ConOutPrivate
->TextOutQueryData
660 if (EFI_ERROR (Status
)) {
661 return EFI_OUT_OF_RESOURCES
;
665 // Setup the default console to 80 x 25 and mode to 0
667 ConOutPrivate
->TextOutQueryData
[0].Columns
= 80;
668 ConOutPrivate
->TextOutQueryData
[0].Rows
= 25;
669 TextOutSetMode (ConOutPrivate
, 0);
672 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
674 // Setup the UgaDraw to 800 x 600 x 32 bits per pixel, 60Hz.
676 ConSplitterUgaDrawSetMode (&ConOutPrivate
->UgaDraw
, 800, 600, 32, 60);
678 if (FeaturePcdGet (PcdConOutGopSupport
)) {
680 // Setup resource for mode information in Graphics Output Protocol interface
682 if ((ConOutPrivate
->GraphicsOutput
.Mode
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
))) == NULL
) {
683 return EFI_OUT_OF_RESOURCES
;
685 if ((ConOutPrivate
->GraphicsOutput
.Mode
->Info
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
))) == NULL
) {
686 return EFI_OUT_OF_RESOURCES
;
689 // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel
690 // DevNull will be updated to user-defined mode after driver has started.
692 if ((ConOutPrivate
->GraphicsOutputModeBuffer
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
))) == NULL
) {
693 return EFI_OUT_OF_RESOURCES
;
695 Info
= &ConOutPrivate
->GraphicsOutputModeBuffer
[0];
697 Info
->HorizontalResolution
= 800;
698 Info
->VerticalResolution
= 600;
699 Info
->PixelFormat
= PixelBltOnly
;
700 Info
->PixelsPerScanLine
= 800;
701 CopyMem (ConOutPrivate
->GraphicsOutput
.Mode
->Info
, Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
702 ConOutPrivate
->GraphicsOutput
.Mode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
705 // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()
706 // GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
708 ConOutPrivate
->GraphicsOutput
.Mode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
709 ConOutPrivate
->GraphicsOutput
.Mode
->FrameBufferSize
= 0;
711 ConOutPrivate
->GraphicsOutput
.Mode
->MaxMode
= 1;
713 // Initial current mode to unknown state, and then set to mode 0
715 ConOutPrivate
->GraphicsOutput
.Mode
->Mode
= 0xffff;
716 ConOutPrivate
->GraphicsOutput
.SetMode (&ConOutPrivate
->GraphicsOutput
, 0);
724 Test to see if the specified protocol could be supported on the specified device.
726 @param This Driver Binding protocol pointer.
727 @param ControllerHandle Handle of device to test.
728 @param Guid The specified protocol.
730 @retval EFI_SUCCESS The specified protocol is supported on this device.
731 @retval EFI_UNSUPPORTED The specified protocol attempts to be installed on virtul handle.
732 @retval other Failed to open specified protocol on this device.
736 ConSplitterSupported (
737 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
738 IN EFI_HANDLE ControllerHandle
,
746 // Make sure the Console Splitter does not attempt to attach to itself
748 if (ControllerHandle
== mConIn
.VirtualHandle
||
749 ControllerHandle
== mConOut
.VirtualHandle
||
750 ControllerHandle
== mStdErr
.VirtualHandle
752 return EFI_UNSUPPORTED
;
756 // Check to see whether the specific protocol could be opened BY_DRIVER
758 Status
= gBS
->OpenProtocol (
762 This
->DriverBindingHandle
,
764 EFI_OPEN_PROTOCOL_BY_DRIVER
767 if (EFI_ERROR (Status
)) {
774 This
->DriverBindingHandle
,
782 Test to see if Console In Device could be supported on the Controller.
784 @param This Driver Binding protocol instance pointer.
785 @param ControllerHandle Handle of device to test.
786 @param RemainingDevicePath Optional parameter use to pick a specific child
789 @retval EFI_SUCCESS This driver supports this device.
790 @retval other This driver does not support this device.
795 ConSplitterConInDriverBindingSupported (
796 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
797 IN EFI_HANDLE ControllerHandle
,
798 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
801 return ConSplitterSupported (
804 &gEfiConsoleInDeviceGuid
809 Test to see if Simple Pointer protocol could be supported on the Controller.
811 @param This Driver Binding protocol instance pointer.
812 @param ControllerHandle Handle of device to test.
813 @param RemainingDevicePath Optional parameter use to pick a specific child
816 @retval EFI_SUCCESS This driver supports this device.
817 @retval other This driver does not support this device.
822 ConSplitterSimplePointerDriverBindingSupported (
823 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
824 IN EFI_HANDLE ControllerHandle
,
825 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
828 return ConSplitterSupported (
831 &gEfiSimplePointerProtocolGuid
836 Test to see if Absolute Pointer protocol could be supported on the Controller.
838 @param This Driver Binding 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 ConSplitterAbsolutePointerDriverBindingSupported (
850 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
851 IN EFI_HANDLE ControllerHandle
,
852 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
855 return ConSplitterSupported (
858 &gEfiAbsolutePointerProtocolGuid
864 Test to see if Console Out Device could be supported on the Controller.
866 @param This Driver Binding protocol instance pointer.
867 @param ControllerHandle Handle of device to test.
868 @param RemainingDevicePath Optional parameter use to pick a specific child
871 @retval EFI_SUCCESS This driver supports this device.
872 @retval other This driver does not support this device.
877 ConSplitterConOutDriverBindingSupported (
878 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
879 IN EFI_HANDLE ControllerHandle
,
880 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
883 return ConSplitterSupported (
886 &gEfiConsoleOutDeviceGuid
891 Test to see if Standard Error Device could be supported on the Controller.
893 @param This Driver Binding 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 ConSplitterStdErrDriverBindingSupported (
905 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
906 IN EFI_HANDLE ControllerHandle
,
907 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
910 return ConSplitterSupported (
913 &gEfiStandardErrorDeviceGuid
919 Start ConSplitter on devcie handle by opening Console Device Guid on device handle
920 and the console virtual handle. And Get the console interface on controller handle.
922 @param This Driver Binding protocol instance pointer.
923 @param ControllerHandle Handle of device.
924 @param ConSplitterVirtualHandle Console virtual Handle.
925 @param DeviceGuid The specified Console Device, such as ConInDev,
927 @param InterfaceGuid The specified protocol to be opened.
928 @param Interface Protocol interface returned.
930 @retval EFI_SUCCESS This driver supports this device.
931 @retval other Failed to open the specified Console Device Guid
932 or specified protocol.
937 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
938 IN EFI_HANDLE ControllerHandle
,
939 IN EFI_HANDLE ConSplitterVirtualHandle
,
940 IN EFI_GUID
*DeviceGuid
,
941 IN EFI_GUID
*InterfaceGuid
,
949 // Check to see whether the ControllerHandle has the DeviceGuid on it.
951 Status
= gBS
->OpenProtocol (
955 This
->DriverBindingHandle
,
957 EFI_OPEN_PROTOCOL_BY_DRIVER
959 if (EFI_ERROR (Status
)) {
964 // Open the Parent Handle for the child.
966 Status
= gBS
->OpenProtocol (
970 This
->DriverBindingHandle
,
971 ConSplitterVirtualHandle
,
972 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
974 if (EFI_ERROR (Status
)) {
979 // Open InterfaceGuid on the virtul handle.
981 Status
= gBS
->OpenProtocol (
985 This
->DriverBindingHandle
,
986 ConSplitterVirtualHandle
,
987 EFI_OPEN_PROTOCOL_GET_PROTOCOL
990 if (!EFI_ERROR (Status
)) {
995 // close the DeviceGuid on ConSplitter VirtualHandle.
1000 This
->DriverBindingHandle
,
1001 ConSplitterVirtualHandle
1006 // close the DeviceGuid on ControllerHandle.
1008 gBS
->CloseProtocol (
1011 This
->DriverBindingHandle
,
1020 Start Console In Consplitter on device handle.
1022 @param This Driver Binding protocol instance pointer.
1023 @param ControllerHandle Handle of device to bind driver to.
1024 @param RemainingDevicePath Optional parameter use to pick a specific child
1027 @retval EFI_SUCCESS Console In Consplitter is added to ControllerHandle.
1028 @retval other Console In Consplitter does not support this device.
1033 ConSplitterConInDriverBindingStart (
1034 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1035 IN EFI_HANDLE ControllerHandle
,
1036 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1040 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
1041 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
;
1044 // Start ConSplitter on ControllerHandle, and create the virtual
1045 // agrogated console device on first call Start for a SimpleTextIn handle.
1047 Status
= ConSplitterStart (
1050 mConIn
.VirtualHandle
,
1051 &gEfiConsoleInDeviceGuid
,
1052 &gEfiSimpleTextInProtocolGuid
,
1055 if (EFI_ERROR (Status
)) {
1060 // Add this device into Text In devices list.
1062 Status
= ConSplitterTextInAddDevice (&mConIn
, TextIn
);
1063 if (EFI_ERROR (Status
)) {
1067 Status
= gBS
->OpenProtocol (
1069 &gEfiSimpleTextInputExProtocolGuid
,
1070 (VOID
**) &TextInEx
,
1071 This
->DriverBindingHandle
,
1072 mConIn
.VirtualHandle
,
1073 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1075 if (!EFI_ERROR (Status
)) {
1077 // If Simple Text Input Ex protocol exists,
1078 // add this device into Text In Ex devices list.
1080 Status
= ConSplitterTextInExAddDevice (&mConIn
, TextInEx
);
1088 Start Simple Pointer Consplitter on device handle.
1090 @param This Driver Binding protocol instance pointer.
1091 @param ControllerHandle Handle of device to bind driver to.
1092 @param RemainingDevicePath Optional parameter use to pick a specific child
1095 @retval EFI_SUCCESS Simple Pointer Consplitter is added to ControllerHandle.
1096 @retval other Simple Pointer Consplitter does not support this device.
1101 ConSplitterSimplePointerDriverBindingStart (
1102 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1103 IN EFI_HANDLE ControllerHandle
,
1104 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1108 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
;
1111 // Start ConSplitter on ControllerHandle, and create the virtual
1112 // agrogated console device on first call Start for a SimplePointer handle.
1114 Status
= ConSplitterStart (
1117 mConIn
.VirtualHandle
,
1118 &gEfiSimplePointerProtocolGuid
,
1119 &gEfiSimplePointerProtocolGuid
,
1120 (VOID
**) &SimplePointer
1122 if (EFI_ERROR (Status
)) {
1127 // Add this devcie into Simple Pointer devices list.
1129 return ConSplitterSimplePointerAddDevice (&mConIn
, SimplePointer
);
1134 Start Absolute Pointer Consplitter on device handle.
1136 @param This Driver Binding protocol instance pointer.
1137 @param ControllerHandle Handle of device to bind driver to.
1138 @param RemainingDevicePath Optional parameter use to pick a specific child
1141 @retval EFI_SUCCESS Absolute Pointer Consplitter is added to ControllerHandle.
1142 @retval other Absolute Pointer Consplitter does not support this device.
1147 ConSplitterAbsolutePointerDriverBindingStart (
1148 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1149 IN EFI_HANDLE ControllerHandle
,
1150 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1154 EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
;
1157 // Start ConSplitter on ControllerHandle, and create the virtual
1158 // agrogated console device on first call Start for a AbsolutePointer handle.
1160 Status
= ConSplitterStart (
1163 mConIn
.VirtualHandle
,
1164 &gEfiAbsolutePointerProtocolGuid
,
1165 &gEfiAbsolutePointerProtocolGuid
,
1166 (VOID
**) &AbsolutePointer
1169 if (EFI_ERROR (Status
)) {
1174 // Add this devcie into Absolute Pointer devices list.
1176 return ConSplitterAbsolutePointerAddDevice (&mConIn
, AbsolutePointer
);
1181 Start Console Out Consplitter on device handle.
1183 @param This Driver Binding protocol instance pointer.
1184 @param ControllerHandle Handle of device to bind driver to.
1185 @param RemainingDevicePath Optional parameter use to pick a specific child
1188 @retval EFI_SUCCESS Console Out Consplitter is added to ControllerHandle.
1189 @retval other Console Out Consplitter does not support this device.
1194 ConSplitterConOutDriverBindingStart (
1195 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1196 IN EFI_HANDLE ControllerHandle
,
1197 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1201 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1202 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1203 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1205 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
1208 // Start ConSplitter on ControllerHandle, and create the virtual
1209 // agrogated console device on first call Start for a ConsoleOut handle.
1211 Status
= ConSplitterStart (
1214 mConOut
.VirtualHandle
,
1215 &gEfiConsoleOutDeviceGuid
,
1216 &gEfiSimpleTextOutProtocolGuid
,
1219 if (EFI_ERROR (Status
)) {
1223 GraphicsOutput
= NULL
;
1226 // Try to Open Graphics Output protocol
1228 Status
= gBS
->OpenProtocol (
1230 &gEfiGraphicsOutputProtocolGuid
,
1231 (VOID
**) &GraphicsOutput
,
1232 This
->DriverBindingHandle
,
1233 mConOut
.VirtualHandle
,
1234 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1237 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
1239 // Open UGA DRAW protocol
1243 &gEfiUgaDrawProtocolGuid
,
1245 This
->DriverBindingHandle
,
1246 mConOut
.VirtualHandle
,
1247 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1252 // When new console device is added, the new mode will be set later,
1253 // so put current mode back to init state.
1255 mConOut
.TextOutMode
.Mode
= 0xFF;
1258 // If both ConOut and StdErr incorporate the same Text Out device,
1259 // their MaxMode and QueryData should be the intersection of both.
1261 Status
= ConSplitterTextOutAddDevice (&mConOut
, TextOut
, GraphicsOutput
, UgaDraw
);
1262 ConSplitterTextOutSetAttribute (&mConOut
.TextOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
1264 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
1266 // Get the UGA mode data of ConOut from the current mode
1268 if (GraphicsOutput
!= NULL
) {
1269 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, GraphicsOutput
->Mode
->Mode
, &SizeOfInfo
, &Info
);
1270 if (EFI_ERROR (Status
)) {
1273 ASSERT ( SizeOfInfo
<= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
1275 mConOut
.UgaHorizontalResolution
= Info
->HorizontalResolution
;
1276 mConOut
.UgaVerticalResolution
= Info
->VerticalResolution
;
1277 mConOut
.UgaColorDepth
= 32;
1278 mConOut
.UgaRefreshRate
= 60;
1282 } else if (UgaDraw
!= NULL
) {
1283 Status
= UgaDraw
->GetMode (
1285 &mConOut
.UgaHorizontalResolution
,
1286 &mConOut
.UgaVerticalResolution
,
1287 &mConOut
.UgaColorDepth
,
1288 &mConOut
.UgaRefreshRate
1298 Start Standard Error Consplitter on device handle.
1300 @param This Driver Binding protocol instance pointer.
1301 @param ControllerHandle Handle of device to bind driver to.
1302 @param RemainingDevicePath Optional parameter use to pick a specific child
1305 @retval EFI_SUCCESS Standard Error Consplitter is added to ControllerHandle.
1306 @retval other Standard Error Consplitter does not support this device.
1311 ConSplitterStdErrDriverBindingStart (
1312 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1313 IN EFI_HANDLE ControllerHandle
,
1314 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1318 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1321 // Start ConSplitter on ControllerHandle, and create the virtual
1322 // agrogated console device on first call Start for a StandardError handle.
1324 Status
= ConSplitterStart (
1327 mStdErr
.VirtualHandle
,
1328 &gEfiStandardErrorDeviceGuid
,
1329 &gEfiSimpleTextOutProtocolGuid
,
1332 if (EFI_ERROR (Status
)) {
1337 // When new console device is added, the new mode will be set later,
1338 // so put current mode back to init state.
1340 mStdErr
.TextOutMode
.Mode
= 0xFF;
1343 // If both ConOut and StdErr incorporate the same Text Out device,
1344 // their MaxMode and QueryData should be the intersection of both.
1346 Status
= ConSplitterTextOutAddDevice (&mStdErr
, TextOut
, NULL
, NULL
);
1347 ConSplitterTextOutSetAttribute (&mStdErr
.TextOut
, EFI_TEXT_ATTR (EFI_MAGENTA
, EFI_BLACK
));
1348 if (EFI_ERROR (Status
)) {
1357 Stop ConSplitter on device handle by closing Console Device Guid on device handle
1358 and the console virtual handle.
1360 @param This Protocol instance pointer.
1361 @param ControllerHandle Handle of device.
1362 @param ConSplitterVirtualHandle Console virtual Handle.
1363 @param DeviceGuid The specified Console Device, such as ConInDev,
1365 @param InterfaceGuid The specified protocol to be opened.
1366 @param Interface Protocol interface returned.
1368 @retval EFI_SUCCESS Stop ConSplitter on ControllerHandle successfully.
1369 @retval other Failed to Stop ConSplitter on ControllerHandle.
1374 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1375 IN EFI_HANDLE ControllerHandle
,
1376 IN EFI_HANDLE ConSplitterVirtualHandle
,
1377 IN EFI_GUID
*DeviceGuid
,
1378 IN EFI_GUID
*InterfaceGuid
,
1384 Status
= gBS
->OpenProtocol (
1388 This
->DriverBindingHandle
,
1390 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1392 if (EFI_ERROR (Status
)) {
1396 // close the protocol refered.
1398 gBS
->CloseProtocol (
1401 This
->DriverBindingHandle
,
1402 ConSplitterVirtualHandle
1405 gBS
->CloseProtocol (
1408 This
->DriverBindingHandle
,
1417 Stop Console In ConSplitter on ControllerHandle by closing Console In Devcice GUID.
1419 @param This Driver Binding protocol instance pointer.
1420 @param ControllerHandle Handle of device to stop driver on
1421 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1422 children is zero stop the entire bus driver.
1423 @param ChildHandleBuffer List of Child Handles to Stop.
1425 @retval EFI_SUCCESS This driver is removed ControllerHandle
1426 @retval other This driver was not removed from this device
1431 ConSplitterConInDriverBindingStop (
1432 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1433 IN EFI_HANDLE ControllerHandle
,
1434 IN UINTN NumberOfChildren
,
1435 IN EFI_HANDLE
*ChildHandleBuffer
1439 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
1440 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
;
1442 if (NumberOfChildren
== 0) {
1446 Status
= gBS
->OpenProtocol (
1448 &gEfiSimpleTextInputExProtocolGuid
,
1449 (VOID
**) &TextInEx
,
1450 This
->DriverBindingHandle
,
1452 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1454 if (!EFI_ERROR (Status
)) {
1456 // If Simple Text Input Ex protocol exists,
1457 // remove device from Text Input Ex devices list.
1459 Status
= ConSplitterTextInExDeleteDevice (&mConIn
, TextInEx
);
1460 if (EFI_ERROR (Status
)) {
1466 // Close Simple Text In protocol on controller handle and virtual handle.
1468 Status
= ConSplitterStop (
1471 mConIn
.VirtualHandle
,
1472 &gEfiConsoleInDeviceGuid
,
1473 &gEfiSimpleTextInProtocolGuid
,
1476 if (EFI_ERROR (Status
)) {
1481 // Remove device from Text Input devices list.
1483 return ConSplitterTextInDeleteDevice (&mConIn
, TextIn
);
1488 Stop Simple Pointer protocol ConSplitter on ControllerHandle by closing
1489 Simple Pointer protocol.
1491 @param This Driver Binding protocol instance pointer.
1492 @param ControllerHandle Handle of device to stop driver on
1493 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1494 children is zero stop the entire bus driver.
1495 @param ChildHandleBuffer List of Child Handles to Stop.
1497 @retval EFI_SUCCESS This driver is removed ControllerHandle
1498 @retval other This driver was not removed from this device
1503 ConSplitterSimplePointerDriverBindingStop (
1504 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1505 IN EFI_HANDLE ControllerHandle
,
1506 IN UINTN NumberOfChildren
,
1507 IN EFI_HANDLE
*ChildHandleBuffer
1511 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
;
1513 if (NumberOfChildren
== 0) {
1518 // Close Simple Pointer protocol on controller handle and virtual handle.
1520 Status
= ConSplitterStop (
1523 mConIn
.VirtualHandle
,
1524 &gEfiSimplePointerProtocolGuid
,
1525 &gEfiSimplePointerProtocolGuid
,
1526 (VOID
**) &SimplePointer
1528 if (EFI_ERROR (Status
)) {
1533 // Remove this device from Simple Pointer device list.
1535 return ConSplitterSimplePointerDeleteDevice (&mConIn
, SimplePointer
);
1540 Stop Absolute Pointer protocol ConSplitter on ControllerHandle by closing
1541 Absolute Pointer protocol.
1543 @param This Driver Binding protocol instance pointer.
1544 @param ControllerHandle Handle of device to stop driver on
1545 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1546 children is zero stop the entire bus driver.
1547 @param ChildHandleBuffer List of Child Handles to Stop.
1549 @retval EFI_SUCCESS This driver is removed ControllerHandle
1550 @retval other This driver was not removed from this device
1555 ConSplitterAbsolutePointerDriverBindingStop (
1556 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1557 IN EFI_HANDLE ControllerHandle
,
1558 IN UINTN NumberOfChildren
,
1559 IN EFI_HANDLE
*ChildHandleBuffer
1563 EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
;
1565 if (NumberOfChildren
== 0) {
1570 // Close Absolute Pointer protocol on controller handle and virtual handle.
1572 Status
= ConSplitterStop (
1575 mConIn
.VirtualHandle
,
1576 &gEfiAbsolutePointerProtocolGuid
,
1577 &gEfiAbsolutePointerProtocolGuid
,
1578 (VOID
**) &AbsolutePointer
1580 if (EFI_ERROR (Status
)) {
1585 // Remove this device from Absolute Pointer device list.
1587 return ConSplitterAbsolutePointerDeleteDevice (&mConIn
, AbsolutePointer
);
1592 Stop Console Out ConSplitter on device handle by closing Console Out Devcice GUID.
1594 @param This Driver Binding protocol instance pointer.
1595 @param ControllerHandle Handle of device to stop driver on
1596 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1597 children is zero stop the entire bus driver.
1598 @param ChildHandleBuffer List of Child Handles to Stop.
1600 @retval EFI_SUCCESS This driver is removed ControllerHandle
1601 @retval other This driver was not removed from this device
1606 ConSplitterConOutDriverBindingStop (
1607 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1608 IN EFI_HANDLE ControllerHandle
,
1609 IN UINTN NumberOfChildren
,
1610 IN EFI_HANDLE
*ChildHandleBuffer
1614 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1616 if (NumberOfChildren
== 0) {
1621 // Close Absolute Pointer protocol on controller handle and virtual handle.
1623 Status
= ConSplitterStop (
1626 mConOut
.VirtualHandle
,
1627 &gEfiConsoleOutDeviceGuid
,
1628 &gEfiSimpleTextOutProtocolGuid
,
1631 if (EFI_ERROR (Status
)) {
1636 // Remove this device from Text Out device list.
1638 return ConSplitterTextOutDeleteDevice (&mConOut
, TextOut
);
1643 Stop Standard Error ConSplitter on ControllerHandle by closing Standard Error GUID.
1645 @param This Driver Binding protocol instance pointer.
1646 @param ControllerHandle Handle of device to stop driver on
1647 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1648 children is zero stop the entire bus driver.
1649 @param ChildHandleBuffer List of Child Handles to Stop.
1651 @retval EFI_SUCCESS This driver is removed ControllerHandle
1652 @retval other This driver was not removed from this device
1657 ConSplitterStdErrDriverBindingStop (
1658 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1659 IN EFI_HANDLE ControllerHandle
,
1660 IN UINTN NumberOfChildren
,
1661 IN EFI_HANDLE
*ChildHandleBuffer
1665 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1667 if (NumberOfChildren
== 0) {
1672 // Close Standard Error Device on controller handle and virtual handle.
1674 Status
= ConSplitterStop (
1677 mStdErr
.VirtualHandle
,
1678 &gEfiStandardErrorDeviceGuid
,
1679 &gEfiSimpleTextOutProtocolGuid
,
1682 if (EFI_ERROR (Status
)) {
1686 // Delete this console error out device's data structures.
1688 return ConSplitterTextOutDeleteDevice (&mStdErr
, TextOut
);
1693 Take the passed in Buffer of size ElementSize and grow the buffer
1694 by CONSOLE_SPLITTER_ALLOC_UNIT * ElementSize bytes.
1695 Copy the current data in Buffer to the new version of Buffer and
1696 free the old version of buffer.
1698 @param ElementSize Size of element in array.
1699 @param Count Current number of elements in array.
1700 @param Buffer Bigger version of passed in Buffer with all the
1703 @retval EFI_SUCCESS Buffer size has grown.
1704 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1708 ConSplitterGrowBuffer (
1709 IN UINTN ElementSize
,
1710 IN OUT UINTN
*Count
,
1711 IN OUT VOID
**Buffer
1717 // grow the buffer to new buffer size,
1718 // copy the old buffer's content to the new-size buffer,
1719 // then free the old buffer.
1721 Ptr
= ReallocatePool (
1722 ElementSize
* (*Count
),
1723 ElementSize
* ((*Count
) + CONSOLE_SPLITTER_ALLOC_UNIT
),
1727 return EFI_OUT_OF_RESOURCES
;
1729 *Count
+= CONSOLE_SPLITTER_ALLOC_UNIT
;
1736 Add Text Input Device in Consplitter Text Input list.
1738 @param Private Text In Splitter pointer.
1739 @param TextIn Simple Text Input protocol pointer.
1741 @retval EFI_SUCCESS Text Input Device added successfully.
1742 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1746 ConSplitterTextInAddDevice (
1747 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1748 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1754 // If the Text In List is full, enlarge it by calling ConSplitterGrowBuffer().
1756 if (Private
->CurrentNumberOfConsoles
>= Private
->TextInListCount
) {
1757 Status
= ConSplitterGrowBuffer (
1758 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
1759 &Private
->TextInListCount
,
1760 (VOID
**) &Private
->TextInList
1762 if (EFI_ERROR (Status
)) {
1763 return EFI_OUT_OF_RESOURCES
;
1767 // Add the new text-in device data structure into the Text In List.
1769 Private
->TextInList
[Private
->CurrentNumberOfConsoles
] = TextIn
;
1770 Private
->CurrentNumberOfConsoles
++;
1773 // Extra CheckEvent added to reduce the double CheckEvent().
1775 gBS
->CheckEvent (TextIn
->WaitForKey
);
1782 Remove Text Input Device from Consplitter Text Input list.
1784 @param Private Text In Splitter pointer.
1785 @param TextIn Simple Text protocol pointer.
1787 @retval EFI_SUCCESS Simple Text Device removed successfully.
1788 @retval EFI_NOT_FOUND No Simple Text Device found.
1792 ConSplitterTextInDeleteDevice (
1793 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1794 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1799 // Remove the specified text-in device data structure from the Text In List,
1800 // and rearrange the remaining data structures in the Text In List.
1802 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
1803 if (Private
->TextInList
[Index
] == TextIn
) {
1804 for (; Index
< Private
->CurrentNumberOfConsoles
- 1; Index
++) {
1805 Private
->TextInList
[Index
] = Private
->TextInList
[Index
+ 1];
1808 Private
->CurrentNumberOfConsoles
--;
1813 return EFI_NOT_FOUND
;
1817 Add Text Input Ex Device in Consplitter Text Input Ex list.
1819 @param Private Text In Splitter pointer.
1820 @param TextInEx Simple Text Input Ex Input protocol pointer.
1822 @retval EFI_SUCCESS Text Input Ex Device added successfully.
1823 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1827 ConSplitterTextInExAddDevice (
1828 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1829 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1834 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
1835 UINTN TextInExListCount
;
1838 // Enlarge the NotifyHandleList and the TextInExList
1840 if (Private
->CurrentNumberOfExConsoles
>= Private
->TextInExListCount
) {
1841 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
1842 CurrentNotify
= TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link
);
1843 TextInExListCount
= Private
->TextInExListCount
;
1845 Status
= ConSplitterGrowBuffer (
1846 sizeof (EFI_HANDLE
),
1848 (VOID
**) &CurrentNotify
->NotifyHandleList
1850 if (EFI_ERROR (Status
)) {
1851 return EFI_OUT_OF_RESOURCES
;
1854 Status
= ConSplitterGrowBuffer (
1855 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
1856 &Private
->TextInExListCount
,
1857 (VOID
**) &Private
->TextInExList
1859 if (EFI_ERROR (Status
)) {
1860 return EFI_OUT_OF_RESOURCES
;
1865 // Register the key notify in the new text-in device
1867 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
1868 CurrentNotify
= TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link
);
1869 Status
= TextInEx
->RegisterKeyNotify (
1871 &CurrentNotify
->KeyData
,
1872 CurrentNotify
->KeyNotificationFn
,
1873 &CurrentNotify
->NotifyHandleList
[Private
->CurrentNumberOfExConsoles
]
1875 if (EFI_ERROR (Status
)) {
1876 for (Link
= Link
->BackLink
; Link
!= &Private
->NotifyList
; Link
= Link
->BackLink
) {
1877 CurrentNotify
= TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link
);
1878 TextInEx
->UnregisterKeyNotify (
1880 CurrentNotify
->NotifyHandleList
[Private
->CurrentNumberOfExConsoles
]
1888 // Add the new text-in device data structure into the Text Input Ex List.
1890 Private
->TextInExList
[Private
->CurrentNumberOfExConsoles
] = TextInEx
;
1891 Private
->CurrentNumberOfExConsoles
++;
1894 // Extra CheckEvent added to reduce the double CheckEvent().
1896 gBS
->CheckEvent (TextInEx
->WaitForKeyEx
);
1902 Remove Text Ex Device from Consplitter Text Input Ex list.
1904 @param Private Text In Splitter pointer.
1905 @param TextInEx Simple Text Ex protocol pointer.
1907 @retval EFI_SUCCESS Simple Text Input Ex Device removed successfully.
1908 @retval EFI_NOT_FOUND No Simple Text Input Ex Device found.
1912 ConSplitterTextInExDeleteDevice (
1913 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1914 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1919 // Remove the specified text-in device data structure from the Text Input Ex List,
1920 // and rearrange the remaining data structures in the Text In List.
1922 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
1923 if (Private
->TextInExList
[Index
] == TextInEx
) {
1924 for (; Index
< Private
->CurrentNumberOfExConsoles
- 1; Index
++) {
1925 Private
->TextInExList
[Index
] = Private
->TextInExList
[Index
+ 1];
1928 Private
->CurrentNumberOfExConsoles
--;
1933 return EFI_NOT_FOUND
;
1938 Add Simple Pointer Device in Consplitter Simple Pointer list.
1940 @param Private Text In Splitter pointer.
1941 @param SimplePointer Simple Pointer protocol pointer.
1943 @retval EFI_SUCCESS Simple Pointer Device added successfully.
1944 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1948 ConSplitterSimplePointerAddDevice (
1949 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1950 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
1956 // If the Simple Pointer List is full, enlarge it by calling ConSplitterGrowBuffer().
1958 if (Private
->CurrentNumberOfPointers
>= Private
->PointerListCount
) {
1959 Status
= ConSplitterGrowBuffer (
1960 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
1961 &Private
->PointerListCount
,
1962 (VOID
**) &Private
->PointerList
1964 if (EFI_ERROR (Status
)) {
1965 return EFI_OUT_OF_RESOURCES
;
1969 // Add the new text-in device data structure into the Simple Pointer List.
1971 Private
->PointerList
[Private
->CurrentNumberOfPointers
] = SimplePointer
;
1972 Private
->CurrentNumberOfPointers
++;
1979 Remove Simple Pointer Device from Consplitter Simple Pointer list.
1981 @param Private Text In Splitter pointer.
1982 @param SimplePointer Simple Pointer protocol pointer.
1984 @retval EFI_SUCCESS Simple Pointer Device removed successfully.
1985 @retval EFI_NOT_FOUND No Simple Pointer Device found.
1989 ConSplitterSimplePointerDeleteDevice (
1990 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1991 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
1996 // Remove the specified text-in device data structure from the Simple Pointer List,
1997 // and rearrange the remaining data structures in the Text In List.
1999 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
2000 if (Private
->PointerList
[Index
] == SimplePointer
) {
2001 for (; Index
< Private
->CurrentNumberOfPointers
- 1; Index
++) {
2002 Private
->PointerList
[Index
] = Private
->PointerList
[Index
+ 1];
2005 Private
->CurrentNumberOfPointers
--;
2010 return EFI_NOT_FOUND
;
2015 Add Absolute Pointer Device in Consplitter Absolute Pointer list.
2017 @param Private Text In Splitter pointer.
2018 @param AbsolutePointer Absolute Pointer protocol pointer.
2020 @retval EFI_SUCCESS Absolute Pointer Device added successfully.
2021 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2025 ConSplitterAbsolutePointerAddDevice (
2026 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2027 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2033 // If the Absolute Pointer List is full, enlarge it by calling ConSplitterGrowBuffer().
2035 if (Private
->CurrentNumberOfAbsolutePointers
>= Private
->AbsolutePointerListCount
) {
2036 Status
= ConSplitterGrowBuffer (
2037 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
2038 &Private
->AbsolutePointerListCount
,
2039 (VOID
**) &Private
->AbsolutePointerList
2041 if (EFI_ERROR (Status
)) {
2042 return EFI_OUT_OF_RESOURCES
;
2046 // Add the new text-in device data structure into the Absolute Pointer List.
2048 Private
->AbsolutePointerList
[Private
->CurrentNumberOfAbsolutePointers
] = AbsolutePointer
;
2049 Private
->CurrentNumberOfAbsolutePointers
++;
2056 Remove Absolute Pointer Device from Consplitter Absolute Pointer list.
2058 @param Private Text In Splitter pointer.
2059 @param AbsolutePointer Absolute Pointer protocol pointer.
2061 @retval EFI_SUCCESS Absolute Pointer Device removed successfully.
2062 @retval EFI_NOT_FOUND No Absolute Pointer Device found.
2066 ConSplitterAbsolutePointerDeleteDevice (
2067 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2068 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2073 // Remove the specified text-in device data structure from the Absolute Pointer List,
2074 // and rearrange the remaining data structures from the Absolute Pointer List.
2076 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
2077 if (Private
->AbsolutePointerList
[Index
] == AbsolutePointer
) {
2078 for (; Index
< Private
->CurrentNumberOfAbsolutePointers
- 1; Index
++) {
2079 Private
->AbsolutePointerList
[Index
] = Private
->AbsolutePointerList
[Index
+ 1];
2082 Private
->CurrentNumberOfAbsolutePointers
--;
2087 return EFI_NOT_FOUND
;
2091 Reallocate Text Out mode map.
2093 Allocate new buffer and copy original buffer into the new buffer.
2095 @param Private Consplitter Text Out pointer.
2097 @retval EFI_SUCCESS Buffer size has grown
2098 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2102 ConSplitterGrowMapTable (
2103 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2109 INT32
*TextOutModeMap
;
2110 INT32
*OldTextOutModeMap
;
2116 NewSize
= Private
->TextOutListCount
* sizeof (INT32
);
2117 OldTextOutModeMap
= Private
->TextOutModeMap
;
2118 TotalSize
= NewSize
* (Private
->TextOutQueryDataCount
);
2121 // Allocate new buffer for Text Out List.
2123 TextOutModeMap
= AllocatePool (TotalSize
);
2124 if (TextOutModeMap
== NULL
) {
2125 return EFI_OUT_OF_RESOURCES
;
2128 SetMem (TextOutModeMap
, TotalSize
, 0xFF);
2129 Private
->TextOutModeMap
= TextOutModeMap
;
2132 // If TextOutList has been enlarged, need to realloc the mode map table
2133 // The mode map table is regarded as a two dimension array.
2136 // 0 ---------> TextOutListCount ----> TextOutListCount
2137 // | -------------------------------------------
2144 // -------------------------------------------
2147 if (OldTextOutModeMap
!= NULL
) {
2149 Size
= Private
->CurrentNumberOfConsoles
* sizeof (INT32
);
2151 SrcAddress
= OldTextOutModeMap
;
2152 NewStepSize
= NewSize
/ sizeof(INT32
);
2153 // If Private->CurrentNumberOfConsoles is not zero and OldTextOutModeMap
2154 // is not NULL, it indicates that the original TextOutModeMap is not enough
2155 // for the new console devices and has been enlarged by CONSOLE_SPLITTER_ALLOC_UNIT columns.
2157 OldStepSize
= NewStepSize
- CONSOLE_SPLITTER_ALLOC_UNIT
;
2160 // Copy the old data to the new one
2162 while (Index
< Private
->TextOutMode
.MaxMode
) {
2163 CopyMem (TextOutModeMap
, SrcAddress
, Size
);
2165 // Go to next row of new TextOutModeMap.
2167 TextOutModeMap
+= NewStepSize
;
2169 // Go to next row of old TextOutModeMap.
2171 SrcAddress
+= OldStepSize
;
2175 // Free the old buffer
2177 FreePool (OldTextOutModeMap
);
2185 Add new device's output mode to console splitter's mode list.
2187 @param Private Text Out Splitter pointer
2188 @param TextOut Simple Text Output protocol pointer.
2190 @retval EFI_SUCCESS Device added successfully.
2191 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2195 ConSplitterAddOutputMode (
2196 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2197 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2205 MaxMode
= TextOut
->Mode
->MaxMode
;
2206 Private
->TextOutMode
.MaxMode
= MaxMode
;
2209 // Grow the buffer if query data buffer is not large enough to
2210 // hold all the mode supported by the first console.
2212 while (MaxMode
> (INT32
) Private
->TextOutQueryDataCount
) {
2213 Status
= ConSplitterGrowBuffer (
2214 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
2215 &Private
->TextOutQueryDataCount
,
2216 (VOID
**) &Private
->TextOutQueryData
2218 if (EFI_ERROR (Status
)) {
2219 return EFI_OUT_OF_RESOURCES
;
2223 // Allocate buffer for the output mode map
2225 Status
= ConSplitterGrowMapTable (Private
);
2226 if (EFI_ERROR (Status
)) {
2227 return EFI_OUT_OF_RESOURCES
;
2230 // As the first textout device, directly add the mode in to QueryData
2231 // and at the same time record the mapping between QueryData and TextOut.
2235 while (Mode
< MaxMode
) {
2236 Status
= TextOut
->QueryMode (
2239 &Private
->TextOutQueryData
[Mode
].Columns
,
2240 &Private
->TextOutQueryData
[Mode
].Rows
2243 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData
2246 if ((EFI_ERROR(Status
)) && (Mode
== 1)) {
2247 Private
->TextOutQueryData
[Mode
].Columns
= 0;
2248 Private
->TextOutQueryData
[Mode
].Rows
= 0;
2250 Private
->TextOutModeMap
[Index
] = Mode
;
2252 Index
+= Private
->TextOutListCount
;
2259 Reconstruct TextOutModeMap to get intersection of modes.
2261 This routine reconstruct TextOutModeMap to get the intersection
2262 of modes for all console out devices. Because EFI/UEFI spec require
2263 mode 0 is 80x25, mode 1 is 80x50, this routine will not check the
2264 intersection for mode 0 and mode 1.
2266 @param TextOutModeMap Current text out mode map, begin with the mode 80x25
2267 @param NewlyAddedMap New text out mode map, begin with the mode 80x25
2268 @param MapStepSize Mode step size for one console device
2269 @param NewMapStepSize New Mode step size for one console device
2270 @param MaxMode IN: Current max text mode, OUT: Updated max text mode.
2271 @param CurrentMode IN: Current text mode, OUT: Updated current text mode.
2275 ConSplitterGetIntersection (
2276 IN INT32
*TextOutModeMap
,
2277 IN INT32
*NewlyAddedMap
,
2278 IN UINTN MapStepSize
,
2279 IN UINTN NewMapStepSize
,
2280 IN OUT INT32
*MaxMode
,
2281 IN OUT INT32
*CurrentMode
2285 INT32
*CurrentMapEntry
;
2286 INT32
*NextMapEntry
;
2288 INT32 CurrentMaxMode
;
2292 // According to EFI/UEFI spec, mode 0 and mode 1 have been reserved
2293 // for 80x25 and 80x50 in Simple Text Out protocol, so don't make intersection
2294 // for mode 0 and mode 1, mode number starts from 2.
2297 CurrentMapEntry
= &TextOutModeMap
[MapStepSize
* 2];
2298 NextMapEntry
= CurrentMapEntry
;
2299 NewMapEntry
= &NewlyAddedMap
[NewMapStepSize
* 2];
2301 CurrentMaxMode
= *MaxMode
;
2302 Mode
= *CurrentMode
;
2304 while (Index
< CurrentMaxMode
) {
2305 if (*NewMapEntry
== -1) {
2307 // This mode is not supported any more. Remove it. Special care
2308 // must be taken as this remove will also affect current mode;
2310 if (Index
== *CurrentMode
) {
2312 } else if (Index
< *CurrentMode
) {
2317 if (CurrentMapEntry
!= NextMapEntry
) {
2318 CopyMem (NextMapEntry
, CurrentMapEntry
, MapStepSize
* sizeof (INT32
));
2321 NextMapEntry
+= MapStepSize
;
2324 CurrentMapEntry
+= MapStepSize
;
2325 NewMapEntry
+= NewMapStepSize
;
2329 *CurrentMode
= Mode
;
2335 Sync the device's output mode to console splitter's mode list.
2337 @param Private Text Out Splitter pointer.
2338 @param TextOut Simple Text Output protocol pointer.
2342 ConSplitterSyncOutputMode (
2343 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2344 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2347 INT32 CurrentMaxMode
;
2350 INT32
*TextOutModeMap
;
2353 TEXT_OUT_SPLITTER_QUERY_DATA
*TextOutQueryData
;
2360 // Must make sure that current mode won't change even if mode number changes
2362 CurrentMaxMode
= Private
->TextOutMode
.MaxMode
;
2363 TextOutModeMap
= Private
->TextOutModeMap
;
2364 StepSize
= Private
->TextOutListCount
;
2365 TextOutQueryData
= Private
->TextOutQueryData
;
2368 // Query all the mode that the newly added TextOut supports
2371 MapTable
= TextOutModeMap
+ Private
->CurrentNumberOfConsoles
;
2372 while (Mode
< TextOut
->Mode
->MaxMode
) {
2373 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Columns
, &Rows
);
2375 if (EFI_ERROR(Status
)) {
2378 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData
2381 MapTable
[StepSize
] = Mode
;
2382 TextOutQueryData
[Mode
].Columns
= 0;
2383 TextOutQueryData
[Mode
].Rows
= 0;
2389 // Search the intersection map and QueryData database to see if they intersects
2392 while (Index
< CurrentMaxMode
) {
2393 QueryMode
= *(TextOutModeMap
+ Index
* StepSize
);
2394 if ((TextOutQueryData
[QueryMode
].Rows
== Rows
) && (TextOutQueryData
[QueryMode
].Columns
== Columns
)) {
2395 MapTable
[Index
* StepSize
] = Mode
;
2403 // Now search the TextOutModeMap table to find the intersection of supported
2404 // mode between ConSplitter and the newly added device.
2406 ConSplitterGetIntersection (
2411 &Private
->TextOutMode
.MaxMode
,
2412 &Private
->TextOutMode
.Mode
2420 Sync output device between ConOut and StdErr output.
2422 @retval EFI_SUCCESS Sync implemented successfully.
2423 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2427 ConSplitterGetIntersectionBetweenConOutAndStrErr (
2431 UINTN ConOutNumOfConsoles
;
2432 UINTN StdErrNumOfConsoles
;
2433 TEXT_OUT_AND_GOP_DATA
*ConOutTextOutList
;
2434 TEXT_OUT_AND_GOP_DATA
*StdErrTextOutList
;
2438 UINTN ConOutColumns
;
2440 UINTN StdErrColumns
;
2441 INT32 ConOutMaxMode
;
2442 INT32 StdErrMaxMode
;
2447 INT32
*ConOutModeMap
;
2448 INT32
*StdErrModeMap
;
2449 INT32
*ConOutMapTable
;
2450 INT32
*StdErrMapTable
;
2451 TEXT_OUT_SPLITTER_QUERY_DATA
*ConOutQueryData
;
2452 TEXT_OUT_SPLITTER_QUERY_DATA
*StdErrQueryData
;
2453 UINTN ConOutStepSize
;
2454 UINTN StdErrStepSize
;
2455 BOOLEAN FoundTheSameTextOut
;
2456 UINTN ConOutMapTableSize
;
2457 UINTN StdErrMapTableSize
;
2459 ConOutNumOfConsoles
= mConOut
.CurrentNumberOfConsoles
;
2460 StdErrNumOfConsoles
= mStdErr
.CurrentNumberOfConsoles
;
2461 ConOutTextOutList
= mConOut
.TextOutList
;
2462 StdErrTextOutList
= mStdErr
.TextOutList
;
2465 FoundTheSameTextOut
= FALSE
;
2466 while ((Indexi
< ConOutNumOfConsoles
) && (!FoundTheSameTextOut
)) {
2468 while (Indexj
< StdErrNumOfConsoles
) {
2469 if (ConOutTextOutList
->TextOut
== StdErrTextOutList
->TextOut
) {
2470 FoundTheSameTextOut
= TRUE
;
2475 StdErrTextOutList
++;
2479 ConOutTextOutList
++;
2482 if (!FoundTheSameTextOut
) {
2486 // Must make sure that current mode won't change even if mode number changes
2488 ConOutMaxMode
= mConOut
.TextOutMode
.MaxMode
;
2489 ConOutModeMap
= mConOut
.TextOutModeMap
;
2490 ConOutStepSize
= mConOut
.TextOutListCount
;
2491 ConOutQueryData
= mConOut
.TextOutQueryData
;
2493 StdErrMaxMode
= mStdErr
.TextOutMode
.MaxMode
;
2494 StdErrModeMap
= mStdErr
.TextOutModeMap
;
2495 StdErrStepSize
= mStdErr
.TextOutListCount
;
2496 StdErrQueryData
= mStdErr
.TextOutQueryData
;
2499 // Allocate the map table and set the map table's index to -1.
2501 ConOutMapTableSize
= ConOutMaxMode
* sizeof (INT32
);
2502 ConOutMapTable
= AllocateZeroPool (ConOutMapTableSize
);
2503 if (ConOutMapTable
== NULL
) {
2504 return EFI_OUT_OF_RESOURCES
;
2507 SetMem (ConOutMapTable
, ConOutMapTableSize
, 0xFF);
2509 StdErrMapTableSize
= StdErrMaxMode
* sizeof (INT32
);
2510 StdErrMapTable
= AllocateZeroPool (StdErrMapTableSize
);
2511 if (StdErrMapTable
== NULL
) {
2512 return EFI_OUT_OF_RESOURCES
;
2515 SetMem (StdErrMapTable
, StdErrMapTableSize
, 0xFF);
2518 // Find the intersection of the two set of modes. If they actually intersect, the
2519 // correponding entry in the map table is set to 1.
2522 while (Mode
< ConOutMaxMode
) {
2524 // Search the intersection map and QueryData database to see if they intersect
2527 ConOutMode
= *(ConOutModeMap
+ Mode
* ConOutStepSize
);
2528 ConOutRows
= ConOutQueryData
[ConOutMode
].Rows
;
2529 ConOutColumns
= ConOutQueryData
[ConOutMode
].Columns
;
2530 while (Index
< StdErrMaxMode
) {
2531 StdErrMode
= *(StdErrModeMap
+ Index
* StdErrStepSize
);
2532 StdErrRows
= StdErrQueryData
[StdErrMode
].Rows
;
2533 StdErrColumns
= StdErrQueryData
[StdErrMode
].Columns
;
2534 if ((StdErrRows
== ConOutRows
) && (StdErrColumns
== ConOutColumns
)) {
2535 ConOutMapTable
[Mode
] = 1;
2536 StdErrMapTable
[Index
] = 1;
2546 // Now search the TextOutModeMap table to find the intersection of supported
2547 // mode between ConSplitter and the newly added device.
2549 ConSplitterGetIntersection (
2552 mConOut
.TextOutListCount
,
2554 &(mConOut
.TextOutMode
.MaxMode
),
2555 &(mConOut
.TextOutMode
.Mode
)
2558 if (mConOut
.TextOutMode
.Mode
< 0) {
2559 mConOut
.TextOut
.SetMode (&(mConOut
.TextOut
), 0);
2562 ConSplitterGetIntersection (
2565 mStdErr
.TextOutListCount
,
2567 &(mStdErr
.TextOutMode
.MaxMode
),
2568 &(mStdErr
.TextOutMode
.Mode
)
2571 if (mStdErr
.TextOutMode
.Mode
< 0) {
2572 mStdErr
.TextOut
.SetMode (&(mStdErr
.TextOut
), 0);
2575 FreePool (ConOutMapTable
);
2576 FreePool (StdErrMapTable
);
2583 Add Grahpics Output modes into Consplitter Text Out list.
2585 @param Private Text Out Splitter pointer.
2586 @param GraphicsOutput Graphics Output protocol pointer.
2587 @param UgaDraw UGA Draw protocol pointer.
2589 @retval EFI_SUCCESS Output mode added successfully.
2590 @retval other Failed to add output mode.
2594 ConSplitterAddGraphicsOutputMode (
2595 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2596 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2597 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2603 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
;
2605 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
2606 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*CurrentGraphicsOutputMode
;
2607 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*ModeBuffer
;
2608 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*MatchedMode
;
2611 BOOLEAN AlreadyExist
;
2612 UINT32 UgaHorizontalResolution
;
2613 UINT32 UgaVerticalResolution
;
2614 UINT32 UgaColorDepth
;
2615 UINT32 UgaRefreshRate
;
2617 ASSERT (GraphicsOutput
!= NULL
|| UgaDraw
!= NULL
);
2619 CurrentGraphicsOutputMode
= Private
->GraphicsOutput
.Mode
;
2623 Status
= EFI_SUCCESS
;
2625 if (Private
->CurrentNumberOfUgaDraw
!= 0) {
2627 // If any UGA device has already been added, then there is no need to
2628 // calculate intersection of display mode of different GOP/UGA device,
2629 // since only one display mode will be exported (i.e. user-defined mode)
2634 if (GraphicsOutput
!= NULL
) {
2635 if (Private
->CurrentNumberOfGraphicsOutput
== 0) {
2637 // This is the first Graphics Output device added
2639 CurrentGraphicsOutputMode
->MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
2640 CurrentGraphicsOutputMode
->Mode
= GraphicsOutput
->Mode
->Mode
;
2641 CopyMem (CurrentGraphicsOutputMode
->Info
, GraphicsOutput
->Mode
->Info
, GraphicsOutput
->Mode
->SizeOfInfo
);
2642 CurrentGraphicsOutputMode
->SizeOfInfo
= GraphicsOutput
->Mode
->SizeOfInfo
;
2643 CurrentGraphicsOutputMode
->FrameBufferBase
= GraphicsOutput
->Mode
->FrameBufferBase
;
2644 CurrentGraphicsOutputMode
->FrameBufferSize
= GraphicsOutput
->Mode
->FrameBufferSize
;
2647 // Allocate resource for the private mode buffer
2649 ModeBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
) * GraphicsOutput
->Mode
->MaxMode
);
2650 if (ModeBuffer
== NULL
) {
2651 return EFI_OUT_OF_RESOURCES
;
2653 FreePool (Private
->GraphicsOutputModeBuffer
);
2654 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2657 // Store all supported display modes to the private mode buffer
2660 for (Index
= 0; Index
< GraphicsOutput
->Mode
->MaxMode
; Index
++) {
2662 // The Info buffer would be allocated by callee
2664 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) Index
, &SizeOfInfo
, &Info
);
2665 if (EFI_ERROR (Status
)) {
2668 ASSERT ( SizeOfInfo
<= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2669 CopyMem (Mode
, Info
, SizeOfInfo
);
2675 // Check intersection of display mode
2677 ModeBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
) * CurrentGraphicsOutputMode
->MaxMode
);
2678 if (ModeBuffer
== NULL
) {
2679 return EFI_OUT_OF_RESOURCES
;
2682 MatchedMode
= ModeBuffer
;
2683 Mode
= &Private
->GraphicsOutputModeBuffer
[0];
2684 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2687 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
2689 // The Info buffer would be allocated by callee
2691 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
2692 if (EFI_ERROR (Status
)) {
2695 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2696 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2698 // If GOP device supports one mode in current mode buffer,
2699 // it will be added into matched mode buffer
2709 AlreadyExist
= FALSE
;
2712 // Check if GOP mode has been in the mode buffer, ModeBuffer = MatchedMode at begin.
2714 for (Info
= ModeBuffer
; Info
< MatchedMode
; Info
++) {
2715 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2716 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2717 AlreadyExist
= TRUE
;
2722 if (!AlreadyExist
) {
2723 CopyMem (MatchedMode
, Mode
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2726 // Physical frame buffer is no longer available, change PixelFormat to PixelBltOnly
2728 MatchedMode
->Version
= 0;
2729 MatchedMode
->PixelFormat
= PixelBltOnly
;
2730 ZeroMem (&MatchedMode
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2740 // Drop the old mode buffer, assign it to a new one
2742 FreePool (Private
->GraphicsOutputModeBuffer
);
2743 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2746 // Physical frame buffer is no longer available when there are more than one physical GOP devices
2748 CurrentGraphicsOutputMode
->MaxMode
= (UINT32
) (((UINTN
) MatchedMode
- (UINTN
) ModeBuffer
) / sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2749 CurrentGraphicsOutputMode
->Info
->PixelFormat
= PixelBltOnly
;
2750 ZeroMem (&CurrentGraphicsOutputMode
->Info
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2751 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2752 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2753 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2757 // Graphics console driver can ensure the same mode for all GOP devices
2759 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2760 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2761 if ((Mode
->HorizontalResolution
== GraphicsOutput
->Mode
->Info
->HorizontalResolution
) &&
2762 (Mode
->VerticalResolution
== GraphicsOutput
->Mode
->Info
->VerticalResolution
)) {
2763 CurrentIndex
= Index
;
2767 if (Index
>= CurrentGraphicsOutputMode
->MaxMode
) {
2769 // if user defined mode is not found, set to default mode 800x600
2771 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2772 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2773 if ((Mode
->HorizontalResolution
== 800) && (Mode
->VerticalResolution
== 600)) {
2774 CurrentIndex
= Index
;
2779 } else if (UgaDraw
!= NULL
) {
2781 // Graphics console driver can ensure the same mode for all GOP devices
2782 // so we can get the current mode from this video device
2786 &UgaHorizontalResolution
,
2787 &UgaVerticalResolution
,
2792 CurrentGraphicsOutputMode
->MaxMode
= 1;
2793 Info
= CurrentGraphicsOutputMode
->Info
;
2795 Info
->HorizontalResolution
= UgaHorizontalResolution
;
2796 Info
->VerticalResolution
= UgaVerticalResolution
;
2797 Info
->PixelFormat
= PixelBltOnly
;
2798 Info
->PixelsPerScanLine
= UgaHorizontalResolution
;
2799 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2800 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2801 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2804 // Update the private mode buffer
2806 CopyMem (&Private
->GraphicsOutputModeBuffer
[0], Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2809 // Only mode 0 is available to be set
2816 if (GraphicsOutput
!= NULL
) {
2817 Private
->CurrentNumberOfGraphicsOutput
++;
2819 if (UgaDraw
!= NULL
) {
2820 Private
->CurrentNumberOfUgaDraw
++;
2824 // Force GraphicsOutput mode to be set,
2827 Mode
= &Private
->GraphicsOutputModeBuffer
[CurrentIndex
];
2828 if ((GraphicsOutput
!= NULL
) &&
2829 (Mode
->HorizontalResolution
== CurrentGraphicsOutputMode
->Info
->HorizontalResolution
) &&
2830 (Mode
->VerticalResolution
== CurrentGraphicsOutputMode
->Info
->VerticalResolution
)) {
2831 CurrentGraphicsOutputMode
->Mode
= (UINT32
) CurrentIndex
;
2832 if ((Mode
->HorizontalResolution
!= GraphicsOutput
->Mode
->Info
->HorizontalResolution
) ||
2833 (Mode
->VerticalResolution
!= GraphicsOutput
->Mode
->Info
->VerticalResolution
)) {
2835 // If all existing video device has been set to common mode, only set new GOP device to
2838 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
2839 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
2840 if (EFI_ERROR (Status
)) {
2843 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) && (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2849 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
2853 // Current mode number may need update now, so set it to an invalid mode number
2855 CurrentGraphicsOutputMode
->Mode
= 0xffff;
2857 // Graphics console can ensure all GOP devices have the same mode which can be taken as current mode.
2859 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, (UINT32
) CurrentIndex
);
2860 if (EFI_ERROR(Status
)) {
2862 // If user defined mode is not valid for display device, set to the default mode 800x600.
2864 (Private
->GraphicsOutputModeBuffer
[0]).HorizontalResolution
= 800;
2865 (Private
->GraphicsOutputModeBuffer
[0]).VerticalResolution
= 600;
2866 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, 0);
2874 Set the current console out mode.
2876 This routine will get the current console mode information (column, row)
2877 from ConsoleOutMode variable and set it; if the variable does not exist,
2878 set to user defined console mode.
2880 @param Private Consplitter Text Out pointer.
2884 ConsplitterSetConsoleOutMode (
2885 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2895 CONSOLE_OUT_MODE ModeInfo
;
2896 CONSOLE_OUT_MODE MaxModeInfo
;
2897 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
2901 TextOut
= &Private
->TextOut
;
2902 MaxMode
= (UINTN
) (TextOut
->Mode
->MaxMode
);
2904 MaxModeInfo
.Column
= 0;
2905 MaxModeInfo
.Row
= 0;
2906 ModeInfo
.Column
= PcdGet32 (PcdConOutColumn
);
2907 ModeInfo
.Row
= PcdGet32 (PcdConOutRow
);
2910 // To find the prefer mode and basic mode from Text Out mode list
2912 for (Mode
= 0; Mode
< MaxMode
; Mode
++) {
2913 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Col
, &Row
);
2914 if (!EFI_ERROR(Status
)) {
2915 if ((ModeInfo
.Column
!= 0) && (ModeInfo
.Row
!= 0)) {
2917 // Use user defined column and row
2919 if (Col
== ModeInfo
.Column
&& Row
== ModeInfo
.Row
) {
2924 // If user sets PcdConOutColumn or PcdConOutRow to 0,
2925 // find and set the highest text mode.
2927 if ((Col
>= MaxModeInfo
.Column
) && (Row
>= MaxModeInfo
.Row
)) {
2928 MaxModeInfo
.Column
= Col
;
2929 MaxModeInfo
.Row
= Row
;
2933 if (Col
== 80 && Row
== 25) {
2940 // Set prefer mode to Text Out devices.
2942 Status
= TextOut
->SetMode (TextOut
, PreferMode
);
2943 if (EFI_ERROR(Status
)) {
2945 // if current mode setting is failed, default 80x25 mode will be set.
2947 Status
= TextOut
->SetMode (TextOut
, BaseMode
);
2948 ASSERT(!EFI_ERROR(Status
));
2950 Status
= PcdSet32S (PcdConOutColumn
, 80);
2951 ASSERT(!EFI_ERROR(Status
));
2952 Status
= PcdSet32S (PcdConOutRow
, 25);
2953 ASSERT(!EFI_ERROR(Status
));
2961 Add Text Output Device in Consplitter Text Output list.
2963 @param Private Text Out Splitter pointer.
2964 @param TextOut Simple Text Output protocol pointer.
2965 @param GraphicsOutput Graphics Output protocol pointer.
2966 @param UgaDraw UGA Draw protocol pointer.
2968 @retval EFI_SUCCESS Text Output Device added successfully.
2969 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2973 ConSplitterTextOutAddDevice (
2974 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2975 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
,
2976 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2977 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2981 UINTN CurrentNumOfConsoles
;
2983 UINT32 UgaHorizontalResolution
;
2984 UINT32 UgaVerticalResolution
;
2985 UINT32 UgaColorDepth
;
2986 UINT32 UgaRefreshRate
;
2987 TEXT_OUT_AND_GOP_DATA
*TextAndGop
;
2989 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
2990 EFI_STATUS DeviceStatus
;
2992 Status
= EFI_SUCCESS
;
2993 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
2996 // If the Text Out List is full, enlarge it by calling ConSplitterGrowBuffer().
2998 while (CurrentNumOfConsoles
>= Private
->TextOutListCount
) {
2999 Status
= ConSplitterGrowBuffer (
3000 sizeof (TEXT_OUT_AND_GOP_DATA
),
3001 &Private
->TextOutListCount
,
3002 (VOID
**) &Private
->TextOutList
3004 if (EFI_ERROR (Status
)) {
3005 return EFI_OUT_OF_RESOURCES
;
3008 // Also need to reallocate the TextOutModeMap table
3010 Status
= ConSplitterGrowMapTable (Private
);
3011 if (EFI_ERROR (Status
)) {
3012 return EFI_OUT_OF_RESOURCES
;
3016 TextAndGop
= &Private
->TextOutList
[CurrentNumOfConsoles
];
3018 TextAndGop
->TextOut
= TextOut
;
3019 TextAndGop
->GraphicsOutput
= GraphicsOutput
;
3020 TextAndGop
->UgaDraw
= UgaDraw
;
3022 if (CurrentNumOfConsoles
== 0) {
3024 // Add the first device's output mode to console splitter's mode list
3026 Status
= ConSplitterAddOutputMode (Private
, TextOut
);
3028 ConSplitterSyncOutputMode (Private
, TextOut
);
3031 Private
->CurrentNumberOfConsoles
++;
3034 // Scan both TextOutList, for the intersection TextOut device
3035 // maybe both ConOut and StdErr incorporate the same Text Out
3036 // device in them, thus the output of both should be synced.
3038 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3040 MaxMode
= Private
->TextOutMode
.MaxMode
;
3041 ASSERT (MaxMode
>= 1);
3043 DeviceStatus
= EFI_DEVICE_ERROR
;
3044 Status
= EFI_DEVICE_ERROR
;
3047 // This device display mode will be added into Graphics Ouput modes.
3049 if ((GraphicsOutput
!= NULL
) || (UgaDraw
!= NULL
)) {
3050 DeviceStatus
= ConSplitterAddGraphicsOutputMode (Private
, GraphicsOutput
, UgaDraw
);
3053 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
3055 // If UGA is produced by Consplitter
3057 if (GraphicsOutput
!= NULL
) {
3058 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, GraphicsOutput
->Mode
->Mode
, &SizeOfInfo
, &Info
);
3059 if (EFI_ERROR (Status
)) {
3062 ASSERT ( SizeOfInfo
<= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
3064 UgaHorizontalResolution
= Info
->HorizontalResolution
;
3065 UgaVerticalResolution
= Info
->VerticalResolution
;
3069 } else if (UgaDraw
!= NULL
) {
3070 Status
= UgaDraw
->GetMode (
3072 &UgaHorizontalResolution
,
3073 &UgaVerticalResolution
,
3077 if (!EFI_ERROR (Status
) && EFI_ERROR (DeviceStatus
)) {
3079 // if GetMode is successfully and UGA device hasn't been set, set it
3081 Status
= ConSplitterUgaDrawSetMode (
3083 UgaHorizontalResolution
,
3084 UgaVerticalResolution
,
3090 // If GetMode/SetMode is failed, set to 800x600 mode
3092 if(EFI_ERROR (Status
)) {
3093 Status
= ConSplitterUgaDrawSetMode (
3104 if (((!EFI_ERROR (DeviceStatus
)) || (!EFI_ERROR (Status
))) &&
3105 ((Private
->CurrentNumberOfGraphicsOutput
+ Private
->CurrentNumberOfUgaDraw
) == 1)) {
3106 if (!FeaturePcdGet (PcdConOutGopSupport
)) {
3108 // If Graphics Outpurt protocol not supported, UGA Draw protocol is installed
3109 // on the virtual handle.
3111 Status
= gBS
->InstallMultipleProtocolInterfaces (
3112 &mConOut
.VirtualHandle
,
3113 &gEfiUgaDrawProtocolGuid
,
3117 } else if (!FeaturePcdGet (PcdConOutUgaSupport
)) {
3119 // If UGA Draw protocol not supported, Graphics Output Protocol is installed
3120 // on virtual handle.
3122 Status
= gBS
->InstallMultipleProtocolInterfaces (
3123 &mConOut
.VirtualHandle
,
3124 &gEfiGraphicsOutputProtocolGuid
,
3125 &mConOut
.GraphicsOutput
,
3130 // Boot Graphics Output protocol and UGA Draw protocol are supported,
3131 // both they will be installed on virtual handle.
3133 Status
= gBS
->InstallMultipleProtocolInterfaces (
3134 &mConOut
.VirtualHandle
,
3135 &gEfiGraphicsOutputProtocolGuid
,
3136 &mConOut
.GraphicsOutput
,
3137 &gEfiUgaDrawProtocolGuid
,
3145 // After adding new console device, all existing console devices should be
3146 // synced to the current shared mode.
3148 ConsplitterSetConsoleOutMode (Private
);
3155 Remove Text Out Device in Consplitter Text Out list.
3157 @param Private Text Out Splitter pointer.
3158 @param TextOut Simple Text Output Pointer protocol pointer.
3160 @retval EFI_SUCCESS Text Out Device removed successfully.
3161 @retval EFI_NOT_FOUND No Text Out Device found.
3165 ConSplitterTextOutDeleteDevice (
3166 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
3167 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
3171 UINTN CurrentNumOfConsoles
;
3172 TEXT_OUT_AND_GOP_DATA
*TextOutList
;
3176 // Remove the specified text-out device data structure from the Text out List,
3177 // and rearrange the remaining data structures in the Text out List.
3179 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
3180 Index
= (INT32
) CurrentNumOfConsoles
- 1;
3181 TextOutList
= Private
->TextOutList
;
3182 while (Index
>= 0) {
3183 if (TextOutList
->TextOut
== TextOut
) {
3184 if (TextOutList
->UgaDraw
!= NULL
) {
3185 Private
->CurrentNumberOfUgaDraw
--;
3187 if (TextOutList
->GraphicsOutput
!= NULL
) {
3188 Private
->CurrentNumberOfGraphicsOutput
--;
3190 CopyMem (TextOutList
, TextOutList
+ 1, sizeof (TEXT_OUT_AND_GOP_DATA
) * Index
);
3191 CurrentNumOfConsoles
--;
3199 // The specified TextOut is not managed by the ConSplitter driver
3202 return EFI_NOT_FOUND
;
3205 if ((Private
->CurrentNumberOfGraphicsOutput
== 0) && (Private
->CurrentNumberOfUgaDraw
== 0)) {
3207 // If there is not any physical GOP and UGA device in system,
3208 // Consplitter GOP or UGA protocol will be uninstalled
3210 if (!FeaturePcdGet (PcdConOutGopSupport
)) {
3211 Status
= gBS
->UninstallProtocolInterface (
3212 Private
->VirtualHandle
,
3213 &gEfiUgaDrawProtocolGuid
,
3216 } else if (!FeaturePcdGet (PcdConOutUgaSupport
)) {
3217 Status
= gBS
->UninstallProtocolInterface (
3218 Private
->VirtualHandle
,
3219 &gEfiGraphicsOutputProtocolGuid
,
3220 &Private
->GraphicsOutput
3223 Status
= gBS
->UninstallMultipleProtocolInterfaces (
3224 Private
->VirtualHandle
,
3225 &gEfiUgaDrawProtocolGuid
,
3227 &gEfiGraphicsOutputProtocolGuid
,
3228 &Private
->GraphicsOutput
,
3234 if (CurrentNumOfConsoles
== 0) {
3236 // If the number of consoles is zero, reset all parameters
3238 Private
->CurrentNumberOfConsoles
= 0;
3239 Private
->TextOutMode
.MaxMode
= 1;
3240 Private
->TextOutQueryData
[0].Columns
= 80;
3241 Private
->TextOutQueryData
[0].Rows
= 25;
3242 TextOutSetMode (Private
, 0);
3247 // Max Mode is realy an intersection of the QueryMode command to all
3248 // devices. So we must copy the QueryMode of the first device to
3252 Private
->TextOutQueryData
,
3253 Private
->TextOutQueryDataCount
* sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
)
3256 FreePool (Private
->TextOutModeMap
);
3257 Private
->TextOutModeMap
= NULL
;
3258 TextOutList
= Private
->TextOutList
;
3261 // Add the first TextOut to the QueryData array and ModeMap table
3263 Status
= ConSplitterAddOutputMode (Private
, TextOutList
->TextOut
);
3266 // Now add one by one
3269 Private
->CurrentNumberOfConsoles
= 1;
3271 while ((UINTN
) Index
< CurrentNumOfConsoles
) {
3272 ConSplitterSyncOutputMode (Private
, TextOutList
->TextOut
);
3274 Private
->CurrentNumberOfConsoles
++;
3278 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3285 Reset the input device and optionaly run diagnostics
3287 @param This Protocol instance pointer.
3288 @param ExtendedVerification Driver may perform diagnostics on reset.
3290 @retval EFI_SUCCESS The device was reset.
3291 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3297 ConSplitterTextInReset (
3298 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3299 IN BOOLEAN ExtendedVerification
3303 EFI_STATUS ReturnStatus
;
3304 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3307 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3309 Private
->KeyEventSignalState
= FALSE
;
3312 // return the worst status met
3314 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3315 Status
= Private
->TextInList
[Index
]->Reset (
3316 Private
->TextInList
[Index
],
3317 ExtendedVerification
3319 if (EFI_ERROR (Status
)) {
3320 ReturnStatus
= Status
;
3324 return ReturnStatus
;
3329 Reads the next keystroke from the input device. The WaitForKey Event can
3330 be used to test for existance of a keystroke via WaitForEvent () call.
3332 @param Private Protocol instance pointer.
3333 @param Key Driver may perform diagnostics on reset.
3335 @retval EFI_SUCCESS The keystroke information was returned.
3336 @retval EFI_NOT_READY There was no keystroke data availiable.
3337 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3343 ConSplitterTextInPrivateReadKeyStroke (
3344 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3345 OUT EFI_INPUT_KEY
*Key
3350 EFI_INPUT_KEY CurrentKey
;
3352 Key
->UnicodeChar
= 0;
3353 Key
->ScanCode
= SCAN_NULL
;
3356 // if no physical console input device exists, return EFI_NOT_READY;
3357 // if any physical console input device has key input,
3358 // return the key and EFI_SUCCESS.
3360 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3361 Status
= Private
->TextInList
[Index
]->ReadKeyStroke (
3362 Private
->TextInList
[Index
],
3365 if (!EFI_ERROR (Status
)) {
3371 return EFI_NOT_READY
;
3377 Reads the next keystroke from the input device. The WaitForKey Event can
3378 be used to test for existance of a keystroke via WaitForEvent () call.
3380 @param This Protocol instance pointer.
3381 @param Key Driver may perform diagnostics on reset.
3383 @retval EFI_SUCCESS The keystroke information was returned.
3384 @retval EFI_NOT_READY There was no keystroke data availiable.
3385 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3391 ConSplitterTextInReadKeyStroke (
3392 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3393 OUT EFI_INPUT_KEY
*Key
3396 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3398 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3400 Private
->KeyEventSignalState
= FALSE
;
3403 // Signal ConnectConIn event on first call in Lazy ConIn mode
3405 if (!mConInIsConnect
&& PcdGetBool (PcdConInConnectOnDemand
)) {
3406 DEBUG ((EFI_D_INFO
, "Connect ConIn in first ReadKeyStoke in Lazy ConIn mode.\n"));
3407 gBS
->SignalEvent (Private
->ConnectConInEvent
);
3408 mConInIsConnect
= TRUE
;
3411 return ConSplitterTextInPrivateReadKeyStroke (Private
, Key
);
3416 This event aggregates all the events of the ConIn devices in the spliter.
3418 If any events of physical ConIn devices are signaled, signal the ConIn
3419 spliter event. This will cause the calling code to call
3420 ConSplitterTextInReadKeyStroke ().
3422 @param Event The Event assoicated with callback.
3423 @param Context Context registered when Event was created.
3428 ConSplitterTextInWaitForKey (
3434 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3437 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
3439 if (Private
->KeyEventSignalState
) {
3441 // If KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
3443 gBS
->SignalEvent (Event
);
3448 // If any physical console input device has key input, signal the event.
3450 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3451 Status
= gBS
->CheckEvent (Private
->TextInList
[Index
]->WaitForKey
);
3452 if (!EFI_ERROR (Status
)) {
3453 gBS
->SignalEvent (Event
);
3454 Private
->KeyEventSignalState
= TRUE
;
3462 Test if the key has been registered on input device.
3464 @param RegsiteredData A pointer to a buffer that is filled in with the
3465 keystroke state data for the key that was
3467 @param InputData A pointer to a buffer that is filled in with the
3468 keystroke state data for the key that was
3471 @retval TRUE Key be pressed matches a registered key.
3472 @retval FLASE Match failed.
3477 IN EFI_KEY_DATA
*RegsiteredData
,
3478 IN EFI_KEY_DATA
*InputData
3481 ASSERT (RegsiteredData
!= NULL
&& InputData
!= NULL
);
3483 if ((RegsiteredData
->Key
.ScanCode
!= InputData
->Key
.ScanCode
) ||
3484 (RegsiteredData
->Key
.UnicodeChar
!= InputData
->Key
.UnicodeChar
)) {
3489 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
3491 if (RegsiteredData
->KeyState
.KeyShiftState
!= 0 &&
3492 RegsiteredData
->KeyState
.KeyShiftState
!= InputData
->KeyState
.KeyShiftState
) {
3495 if (RegsiteredData
->KeyState
.KeyToggleState
!= 0 &&
3496 RegsiteredData
->KeyState
.KeyToggleState
!= InputData
->KeyState
.KeyToggleState
) {
3506 Reset the input device and optionaly run diagnostics
3508 @param This Protocol instance pointer.
3509 @param ExtendedVerification Driver may perform diagnostics on reset.
3511 @retval EFI_SUCCESS The device was reset.
3512 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3518 ConSplitterTextInResetEx (
3519 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3520 IN BOOLEAN ExtendedVerification
3524 EFI_STATUS ReturnStatus
;
3525 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3528 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3530 Private
->KeyEventSignalState
= FALSE
;
3533 // return the worst status met
3535 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3536 Status
= Private
->TextInExList
[Index
]->Reset (
3537 Private
->TextInExList
[Index
],
3538 ExtendedVerification
3540 if (EFI_ERROR (Status
)) {
3541 ReturnStatus
= Status
;
3545 return ReturnStatus
;
3551 Reads the next keystroke from the input device. The WaitForKey Event can
3552 be used to test for existance of a keystroke via WaitForEvent () call.
3554 @param This Protocol instance pointer.
3555 @param KeyData A pointer to a buffer that is filled in with the
3556 keystroke state data for the key that was
3559 @retval EFI_SUCCESS The keystroke information was returned.
3560 @retval EFI_NOT_READY There was no keystroke data availiable.
3561 @retval EFI_DEVICE_ERROR The keystroke information was not returned due
3563 @retval EFI_INVALID_PARAMETER KeyData is NULL.
3568 ConSplitterTextInReadKeyStrokeEx (
3569 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3570 OUT EFI_KEY_DATA
*KeyData
3573 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3576 EFI_KEY_DATA CurrentKeyData
;
3579 if (KeyData
== NULL
) {
3580 return EFI_INVALID_PARAMETER
;
3583 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3585 Private
->KeyEventSignalState
= FALSE
;
3587 KeyData
->Key
.UnicodeChar
= 0;
3588 KeyData
->Key
.ScanCode
= SCAN_NULL
;
3591 // Signal ConnectConIn event on first call in Lazy ConIn mode
3593 if (!mConInIsConnect
&& PcdGetBool (PcdConInConnectOnDemand
)) {
3594 DEBUG ((EFI_D_INFO
, "Connect ConIn in first ReadKeyStoke in Lazy ConIn mode.\n"));
3595 gBS
->SignalEvent (Private
->ConnectConInEvent
);
3596 mConInIsConnect
= TRUE
;
3600 // if no physical console input device exists, return EFI_NOT_READY;
3601 // if any physical console input device has key input,
3602 // return the key and EFI_SUCCESS.
3604 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3605 Status
= Private
->TextInExList
[Index
]->ReadKeyStrokeEx (
3606 Private
->TextInExList
[Index
],
3609 if (!EFI_ERROR (Status
)) {
3610 CopyMem (KeyData
, &CurrentKeyData
, sizeof (CurrentKeyData
));
3615 return EFI_NOT_READY
;
3620 Set certain state for the input device.
3622 @param This Protocol instance pointer.
3623 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
3624 state for the input device.
3626 @retval EFI_SUCCESS The device state was set successfully.
3627 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
3628 could not have the setting adjusted.
3629 @retval EFI_UNSUPPORTED The device does not have the ability to set its
3631 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
3636 ConSplitterTextInSetState (
3637 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3638 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
3641 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3645 if (KeyToggleState
== NULL
) {
3646 return EFI_INVALID_PARAMETER
;
3649 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3652 // if no physical console input device exists, return EFI_SUCCESS;
3653 // otherwise return the status of setting state of physical console input device
3655 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3656 Status
= Private
->TextInExList
[Index
]->SetState (
3657 Private
->TextInExList
[Index
],
3660 if (EFI_ERROR (Status
)) {
3671 Register a notification function for a particular keystroke for the input device.
3673 @param This Protocol instance pointer.
3674 @param KeyData A pointer to a buffer that is filled in with the
3675 keystroke information data for the key that was
3677 @param KeyNotificationFunction Points to the function to be called when the key
3678 sequence is typed specified by KeyData.
3679 @param NotifyHandle Points to the unique handle assigned to the
3680 registered notification.
3682 @retval EFI_SUCCESS The notification function was registered
3684 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data
3686 @retval EFI_INVALID_PARAMETER KeyData or KeyNotificationFunction or NotifyHandle is NULL.
3691 ConSplitterTextInRegisterKeyNotify (
3692 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3693 IN EFI_KEY_DATA
*KeyData
,
3694 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction
,
3695 OUT VOID
**NotifyHandle
3698 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3701 TEXT_IN_EX_SPLITTER_NOTIFY
*NewNotify
;
3703 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3706 if (KeyData
== NULL
|| NotifyHandle
== NULL
|| KeyNotificationFunction
== NULL
) {
3707 return EFI_INVALID_PARAMETER
;
3710 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3713 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
3715 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3716 CurrentNotify
= TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link
);
3717 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
3718 if (CurrentNotify
->KeyNotificationFn
== KeyNotificationFunction
) {
3719 *NotifyHandle
= CurrentNotify
;
3726 // Allocate resource to save the notification function
3728 NewNotify
= (TEXT_IN_EX_SPLITTER_NOTIFY
*) AllocateZeroPool (sizeof (TEXT_IN_EX_SPLITTER_NOTIFY
));
3729 if (NewNotify
== NULL
) {
3730 return EFI_OUT_OF_RESOURCES
;
3732 NewNotify
->NotifyHandleList
= (EFI_HANDLE
*) AllocateZeroPool (sizeof (EFI_HANDLE
) * Private
->TextInExListCount
);
3733 if (NewNotify
->NotifyHandleList
== NULL
) {
3734 gBS
->FreePool (NewNotify
);
3735 return EFI_OUT_OF_RESOURCES
;
3737 NewNotify
->Signature
= TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
;
3738 NewNotify
->KeyNotificationFn
= KeyNotificationFunction
;
3739 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (EFI_KEY_DATA
));
3742 // Return the wrong status of registering key notify of
3743 // physical console input device if meet problems
3745 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3746 Status
= Private
->TextInExList
[Index
]->RegisterKeyNotify (
3747 Private
->TextInExList
[Index
],
3749 KeyNotificationFunction
,
3750 &NewNotify
->NotifyHandleList
[Index
]
3752 if (EFI_ERROR (Status
)) {
3754 // Un-register the key notify on all physical console input devices
3756 while (Index
-- != 0) {
3757 Private
->TextInExList
[Index
]->UnregisterKeyNotify (
3758 Private
->TextInExList
[Index
],
3759 NewNotify
->NotifyHandleList
[Index
]
3762 gBS
->FreePool (NewNotify
->NotifyHandleList
);
3763 gBS
->FreePool (NewNotify
);
3768 InsertTailList (&mConIn
.NotifyList
, &NewNotify
->NotifyEntry
);
3770 *NotifyHandle
= NewNotify
;
3778 Remove a registered notification function from a particular keystroke.
3780 @param This Protocol instance pointer.
3781 @param NotificationHandle The handle of the notification function being
3784 @retval EFI_SUCCESS The notification function was unregistered
3786 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
3791 ConSplitterTextInUnregisterKeyNotify (
3792 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3793 IN VOID
*NotificationHandle
3796 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3798 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3801 if (NotificationHandle
== NULL
) {
3802 return EFI_INVALID_PARAMETER
;
3805 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3807 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3808 CurrentNotify
= TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link
);
3809 if (CurrentNotify
== NotificationHandle
) {
3810 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3811 Private
->TextInExList
[Index
]->UnregisterKeyNotify (
3812 Private
->TextInExList
[Index
],
3813 CurrentNotify
->NotifyHandleList
[Index
]
3816 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
3818 gBS
->FreePool (CurrentNotify
->NotifyHandleList
);
3819 gBS
->FreePool (CurrentNotify
);
3825 // NotificationHandle is not found in database
3827 return EFI_INVALID_PARAMETER
;
3832 Reset the input device and optionaly run diagnostics
3834 @param This Protocol instance pointer.
3835 @param ExtendedVerification Driver may perform diagnostics on reset.
3837 @retval EFI_SUCCESS The device was reset.
3838 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3844 ConSplitterSimplePointerReset (
3845 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
3846 IN BOOLEAN ExtendedVerification
3850 EFI_STATUS ReturnStatus
;
3851 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3854 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
3856 Private
->InputEventSignalState
= FALSE
;
3858 if (Private
->CurrentNumberOfPointers
== 0) {
3862 // return the worst status met
3864 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3865 Status
= Private
->PointerList
[Index
]->Reset (
3866 Private
->PointerList
[Index
],
3867 ExtendedVerification
3869 if (EFI_ERROR (Status
)) {
3870 ReturnStatus
= Status
;
3874 return ReturnStatus
;
3879 Reads the next keystroke from the input device. The WaitForKey Event can
3880 be used to test for existance of a keystroke via WaitForEvent () call.
3882 @param Private Protocol instance pointer.
3883 @param State The state information of simple pointer device.
3885 @retval EFI_SUCCESS The keystroke information was returned.
3886 @retval EFI_NOT_READY There was no keystroke data availiable.
3887 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3893 ConSplitterSimplePointerPrivateGetState (
3894 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3895 IN OUT EFI_SIMPLE_POINTER_STATE
*State
3899 EFI_STATUS ReturnStatus
;
3901 EFI_SIMPLE_POINTER_STATE CurrentState
;
3903 State
->RelativeMovementX
= 0;
3904 State
->RelativeMovementY
= 0;
3905 State
->RelativeMovementZ
= 0;
3906 State
->LeftButton
= FALSE
;
3907 State
->RightButton
= FALSE
;
3910 // if no physical console input device exists, return EFI_NOT_READY;
3911 // if any physical console input device has key input,
3912 // return the key and EFI_SUCCESS.
3914 ReturnStatus
= EFI_NOT_READY
;
3915 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3917 Status
= Private
->PointerList
[Index
]->GetState (
3918 Private
->PointerList
[Index
],
3921 if (!EFI_ERROR (Status
)) {
3922 if (ReturnStatus
== EFI_NOT_READY
) {
3923 ReturnStatus
= EFI_SUCCESS
;
3926 if (CurrentState
.LeftButton
) {
3927 State
->LeftButton
= TRUE
;
3930 if (CurrentState
.RightButton
) {
3931 State
->RightButton
= TRUE
;
3934 if (CurrentState
.RelativeMovementX
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionX
!= 0) {
3935 State
->RelativeMovementX
+= (CurrentState
.RelativeMovementX
* (INT32
) Private
->SimplePointerMode
.ResolutionX
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionX
;
3938 if (CurrentState
.RelativeMovementY
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionY
!= 0) {
3939 State
->RelativeMovementY
+= (CurrentState
.RelativeMovementY
* (INT32
) Private
->SimplePointerMode
.ResolutionY
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionY
;
3942 if (CurrentState
.RelativeMovementZ
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionZ
!= 0) {
3943 State
->RelativeMovementZ
+= (CurrentState
.RelativeMovementZ
* (INT32
) Private
->SimplePointerMode
.ResolutionZ
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionZ
;
3945 } else if (Status
== EFI_DEVICE_ERROR
) {
3946 ReturnStatus
= EFI_DEVICE_ERROR
;
3950 return ReturnStatus
;
3955 Reads the next keystroke from the input device. The WaitForKey Event can
3956 be used to test for existance of a keystroke via WaitForEvent () call.
3958 @param This A pointer to protocol instance.
3959 @param State A pointer to state information on the pointer device
3961 @retval EFI_SUCCESS The keystroke information was returned in State.
3962 @retval EFI_NOT_READY There was no keystroke data availiable.
3963 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3969 ConSplitterSimplePointerGetState (
3970 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
3971 IN OUT EFI_SIMPLE_POINTER_STATE
*State
3974 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3976 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
3978 Private
->InputEventSignalState
= FALSE
;
3980 return ConSplitterSimplePointerPrivateGetState (Private
, State
);
3985 This event agregates all the events of the ConIn devices in the spliter.
3986 If any events of physical ConIn devices are signaled, signal the ConIn
3987 spliter event. This will cause the calling code to call
3988 ConSplitterTextInReadKeyStroke ().
3990 @param Event The Event assoicated with callback.
3991 @param Context Context registered when Event was created.
3996 ConSplitterSimplePointerWaitForInput (
4002 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4005 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4008 // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
4010 if (Private
->InputEventSignalState
) {
4011 gBS
->SignalEvent (Event
);
4015 // if any physical console input device has key input, signal the event.
4017 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
4018 Status
= gBS
->CheckEvent (Private
->PointerList
[Index
]->WaitForInput
);
4019 if (!EFI_ERROR (Status
)) {
4020 gBS
->SignalEvent (Event
);
4021 Private
->InputEventSignalState
= TRUE
;
4027 Resets the pointer device hardware.
4029 @param This Protocol instance pointer.
4030 @param ExtendedVerification Driver may perform diagnostics on reset.
4032 @retval EFI_SUCCESS The device was reset.
4033 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
4039 ConSplitterAbsolutePointerReset (
4040 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4041 IN BOOLEAN ExtendedVerification
4045 EFI_STATUS ReturnStatus
;
4046 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4049 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4051 Private
->AbsoluteInputEventSignalState
= FALSE
;
4053 if (Private
->CurrentNumberOfAbsolutePointers
== 0) {
4057 // return the worst status met
4059 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4060 Status
= Private
->AbsolutePointerList
[Index
]->Reset (
4061 Private
->AbsolutePointerList
[Index
],
4062 ExtendedVerification
4064 if (EFI_ERROR (Status
)) {
4065 ReturnStatus
= Status
;
4069 return ReturnStatus
;
4074 Retrieves the current state of a pointer device.
4076 @param This Protocol instance pointer.
4077 @param State A pointer to the state information on the
4080 @retval EFI_SUCCESS The state of the pointer device was returned in
4082 @retval EFI_NOT_READY The state of the pointer device has not changed
4083 since the last call to GetState().
4084 @retval EFI_DEVICE_ERROR A device error occurred while attempting to
4085 retrieve the pointer device's current state.
4090 ConSplitterAbsolutePointerGetState (
4091 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4092 IN OUT EFI_ABSOLUTE_POINTER_STATE
*State
4095 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4097 EFI_STATUS ReturnStatus
;
4099 EFI_ABSOLUTE_POINTER_STATE CurrentState
;
4113 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4115 Private
->AbsoluteInputEventSignalState
= FALSE
;
4117 State
->CurrentX
= 0;
4118 State
->CurrentY
= 0;
4119 State
->CurrentZ
= 0;
4120 State
->ActiveButtons
= 0;
4122 VirtualMinX
= Private
->AbsolutePointerMode
.AbsoluteMinX
;
4123 VirtualMinY
= Private
->AbsolutePointerMode
.AbsoluteMinY
;
4124 VirtualMinZ
= Private
->AbsolutePointerMode
.AbsoluteMinZ
;
4125 VirtualMaxX
= Private
->AbsolutePointerMode
.AbsoluteMaxX
;
4126 VirtualMaxY
= Private
->AbsolutePointerMode
.AbsoluteMaxY
;
4127 VirtualMaxZ
= Private
->AbsolutePointerMode
.AbsoluteMaxZ
;
4130 // if no physical pointer device exists, return EFI_NOT_READY;
4131 // if any physical pointer device has changed state,
4132 // return the state and EFI_SUCCESS.
4134 ReturnStatus
= EFI_NOT_READY
;
4135 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4137 Status
= Private
->AbsolutePointerList
[Index
]->GetState (
4138 Private
->AbsolutePointerList
[Index
],
4141 if (!EFI_ERROR (Status
)) {
4142 if (ReturnStatus
== EFI_NOT_READY
) {
4143 ReturnStatus
= EFI_SUCCESS
;
4146 MinX
= Private
->AbsolutePointerList
[Index
]->Mode
->AbsoluteMinX
;
4147 MinY
= Private
->AbsolutePointerList
[Index
]->Mode
->AbsoluteMinY
;
4148 MinZ
= Private
->AbsolutePointerList
[Index
]->Mode
->AbsoluteMinZ
;
4149 MaxX
= Private
->AbsolutePointerList
[Index
]->Mode
->AbsoluteMaxX
;
4150 MaxY
= Private
->AbsolutePointerList
[Index
]->Mode
->AbsoluteMaxY
;
4151 MaxZ
= Private
->AbsolutePointerList
[Index
]->Mode
->AbsoluteMaxZ
;
4153 State
->ActiveButtons
= CurrentState
.ActiveButtons
;
4156 // Rescale to Con Splitter virtual Absolute Pointer's resolution.
4158 if (!(MinX
== 0 && MaxX
== 0)) {
4159 State
->CurrentX
= VirtualMinX
+ (CurrentState
.CurrentX
* (VirtualMaxX
- VirtualMinX
)) / (MaxX
- MinX
);
4161 if (!(MinY
== 0 && MaxY
== 0)) {
4162 State
->CurrentY
= VirtualMinY
+ (CurrentState
.CurrentY
* (VirtualMaxY
- VirtualMinY
)) / (MaxY
- MinY
);
4164 if (!(MinZ
== 0 && MaxZ
== 0)) {
4165 State
->CurrentZ
= VirtualMinZ
+ (CurrentState
.CurrentZ
* (VirtualMaxZ
- VirtualMinZ
)) / (MaxZ
- MinZ
);
4168 } else if (Status
== EFI_DEVICE_ERROR
) {
4169 ReturnStatus
= EFI_DEVICE_ERROR
;
4173 return ReturnStatus
;
4178 This event agregates all the events of the pointer devices in the splitter.
4179 If any events of physical pointer devices are signaled, signal the pointer
4180 splitter event. This will cause the calling code to call
4181 ConSplitterAbsolutePointerGetState ().
4183 @param Event The Event assoicated with callback.
4184 @param Context Context registered when Event was created.
4189 ConSplitterAbsolutePointerWaitForInput (
4195 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4198 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4201 // if AbsoluteInputEventSignalState is flagged before,
4202 // and not cleared by Reset() or GetState(), signal it
4204 if (Private
->AbsoluteInputEventSignalState
) {
4205 gBS
->SignalEvent (Event
);
4209 // if any physical console input device has key input, signal the event.
4211 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4212 Status
= gBS
->CheckEvent (Private
->AbsolutePointerList
[Index
]->WaitForInput
);
4213 if (!EFI_ERROR (Status
)) {
4214 gBS
->SignalEvent (Event
);
4215 Private
->AbsoluteInputEventSignalState
= TRUE
;
4222 Reset the text output device hardware and optionaly run diagnostics
4224 @param This Protocol instance pointer.
4225 @param ExtendedVerification Driver may perform more exhaustive verfication
4226 operation of the device during reset.
4228 @retval EFI_SUCCESS The text output device was reset.
4229 @retval EFI_DEVICE_ERROR The text output device is not functioning
4230 correctly and could not be reset.
4235 ConSplitterTextOutReset (
4236 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4237 IN BOOLEAN ExtendedVerification
4241 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4243 EFI_STATUS ReturnStatus
;
4245 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4248 // return the worst status met
4250 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4251 Status
= Private
->TextOutList
[Index
].TextOut
->Reset (
4252 Private
->TextOutList
[Index
].TextOut
,
4253 ExtendedVerification
4255 if (EFI_ERROR (Status
)) {
4256 ReturnStatus
= Status
;
4260 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BLACK
));
4263 // reset all mode parameters
4265 TextOutSetMode (Private
, 0);
4267 return ReturnStatus
;
4272 Write a Unicode string to the output device.
4274 @param This Protocol instance pointer.
4275 @param WString The NULL-terminated Unicode string to be
4276 displayed on the output device(s). All output
4277 devices must also support the Unicode drawing
4278 defined in this file.
4280 @retval EFI_SUCCESS The string was output to the device.
4281 @retval EFI_DEVICE_ERROR The device reported an error while attempting to
4283 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
4285 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
4286 characters in the Unicode string could not be
4287 rendered and were skipped.
4292 ConSplitterTextOutOutputString (
4293 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4298 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4300 EFI_STATUS ReturnStatus
;
4304 This
->SetAttribute (This
, This
->Mode
->Attribute
);
4306 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4309 // return the worst status met
4311 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4312 Status
= Private
->TextOutList
[Index
].TextOut
->OutputString (
4313 Private
->TextOutList
[Index
].TextOut
,
4316 if (EFI_ERROR (Status
)) {
4317 ReturnStatus
= Status
;
4321 if (Private
->CurrentNumberOfConsoles
> 0) {
4322 Private
->TextOutMode
.CursorColumn
= Private
->TextOutList
[0].TextOut
->Mode
->CursorColumn
;
4323 Private
->TextOutMode
.CursorRow
= Private
->TextOutList
[0].TextOut
->Mode
->CursorRow
;
4326 // When there is no real console devices in system,
4327 // update cursor position for the virtual device in consplitter.
4329 Private
->TextOut
.QueryMode (
4331 Private
->TextOutMode
.Mode
,
4335 for (; *WString
!= CHAR_NULL
; WString
++) {
4337 case CHAR_BACKSPACE
:
4338 if (Private
->TextOutMode
.CursorColumn
== 0 && Private
->TextOutMode
.CursorRow
> 0) {
4339 Private
->TextOutMode
.CursorRow
--;
4340 Private
->TextOutMode
.CursorColumn
= (INT32
) (MaxColumn
- 1);
4341 } else if (Private
->TextOutMode
.CursorColumn
> 0) {
4342 Private
->TextOutMode
.CursorColumn
--;
4347 if (Private
->TextOutMode
.CursorRow
< (INT32
) (MaxRow
- 1)) {
4348 Private
->TextOutMode
.CursorRow
++;
4352 case CHAR_CARRIAGE_RETURN
:
4353 Private
->TextOutMode
.CursorColumn
= 0;
4357 if (Private
->TextOutMode
.CursorColumn
< (INT32
) (MaxColumn
- 1)) {
4358 Private
->TextOutMode
.CursorColumn
++;
4360 Private
->TextOutMode
.CursorColumn
= 0;
4361 if (Private
->TextOutMode
.CursorRow
< (INT32
) (MaxRow
- 1)) {
4362 Private
->TextOutMode
.CursorRow
++;
4370 return ReturnStatus
;
4375 Verifies that all characters in a Unicode string can be output to the
4378 @param This Protocol instance pointer.
4379 @param WString The NULL-terminated Unicode string to be
4380 examined for the output device(s).
4382 @retval EFI_SUCCESS The device(s) are capable of rendering the
4384 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string
4385 cannot be rendered by one or more of the output
4386 devices mapped by the EFI handle.
4391 ConSplitterTextOutTestString (
4392 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4397 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4399 EFI_STATUS ReturnStatus
;
4401 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4404 // return the worst status met
4406 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4407 Status
= Private
->TextOutList
[Index
].TextOut
->TestString (
4408 Private
->TextOutList
[Index
].TextOut
,
4411 if (EFI_ERROR (Status
)) {
4412 ReturnStatus
= Status
;
4416 // There is no DevNullTextOutTestString () since a Unicode buffer would
4417 // always return EFI_SUCCESS.
4418 // ReturnStatus will be EFI_SUCCESS if no consoles are present
4420 return ReturnStatus
;
4425 Returns information for an available text mode that the output device(s)
4428 @param This Protocol instance pointer.
4429 @param ModeNumber The mode number to return information on.
4430 @param Columns Returns the columns of the text output device
4431 for the requested ModeNumber.
4432 @param Rows Returns the rows of the text output device
4433 for the requested ModeNumber.
4435 @retval EFI_SUCCESS The requested mode information was returned.
4436 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4438 @retval EFI_UNSUPPORTED The mode number was not valid.
4443 ConSplitterTextOutQueryMode (
4444 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4445 IN UINTN ModeNumber
,
4450 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4452 INT32
*TextOutModeMap
;
4454 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4457 // Check whether param ModeNumber is valid.
4458 // ModeNumber should be within range 0 ~ MaxMode - 1.
4460 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4461 return EFI_UNSUPPORTED
;
4464 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4465 return EFI_UNSUPPORTED
;
4469 // We get the available mode from mode intersection map if it's available
4471 if (Private
->TextOutModeMap
!= NULL
) {
4472 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4473 CurrentMode
= (UINTN
)(*TextOutModeMap
);
4474 *Columns
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4475 *Rows
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4477 *Columns
= Private
->TextOutQueryData
[ModeNumber
].Columns
;
4478 *Rows
= Private
->TextOutQueryData
[ModeNumber
].Rows
;
4481 if (*Columns
<= 0 && *Rows
<= 0) {
4482 return EFI_UNSUPPORTED
;
4491 Sets the output device(s) to a specified mode.
4493 @param This Protocol instance pointer.
4494 @param ModeNumber The mode number to set.
4496 @retval EFI_SUCCESS The requested text mode was set.
4497 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4499 @retval EFI_UNSUPPORTED The mode number was not valid.
4504 ConSplitterTextOutSetMode (
4505 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4510 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4512 INT32
*TextOutModeMap
;
4513 EFI_STATUS ReturnStatus
;
4515 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4518 // Check whether param ModeNumber is valid.
4519 // ModeNumber should be within range 0 ~ MaxMode - 1.
4521 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4522 return EFI_UNSUPPORTED
;
4525 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4526 return EFI_UNSUPPORTED
;
4529 // If the mode is being set to the curent mode, then just clear the screen and return.
4531 if (Private
->TextOutMode
.Mode
== (INT32
) ModeNumber
) {
4532 return ConSplitterTextOutClearScreen (This
);
4535 // return the worst status met
4537 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4538 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4539 Status
= Private
->TextOutList
[Index
].TextOut
->SetMode (
4540 Private
->TextOutList
[Index
].TextOut
,
4541 TextOutModeMap
[Index
]
4543 if (EFI_ERROR (Status
)) {
4544 ReturnStatus
= Status
;
4549 // Set mode parameter to specified mode number
4551 TextOutSetMode (Private
, ModeNumber
);
4553 return ReturnStatus
;
4558 Sets the background and foreground colors for the OutputString () and
4559 ClearScreen () functions.
4561 @param This Protocol instance pointer.
4562 @param Attribute The attribute to set. Bits 0..3 are the
4563 foreground color, and bits 4..6 are the
4564 background color. All other bits are undefined
4565 and must be zero. The valid Attributes are
4566 defined in this file.
4568 @retval EFI_SUCCESS The attribute was set.
4569 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4571 @retval EFI_UNSUPPORTED The attribute requested is not defined.
4576 ConSplitterTextOutSetAttribute (
4577 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4582 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4584 EFI_STATUS ReturnStatus
;
4586 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4589 // Check whether param Attribute is valid.
4591 if ((Attribute
| 0x7F) != 0x7F) {
4592 return EFI_UNSUPPORTED
;
4596 // return the worst status met
4598 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4599 Status
= Private
->TextOutList
[Index
].TextOut
->SetAttribute (
4600 Private
->TextOutList
[Index
].TextOut
,
4603 if (EFI_ERROR (Status
)) {
4604 ReturnStatus
= Status
;
4608 Private
->TextOutMode
.Attribute
= (INT32
) Attribute
;
4610 return ReturnStatus
;
4615 Clears the output device(s) display to the currently selected background
4618 @param This Protocol instance pointer.
4620 @retval EFI_SUCCESS The operation completed successfully.
4621 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4623 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4628 ConSplitterTextOutClearScreen (
4629 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
4633 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4635 EFI_STATUS ReturnStatus
;
4637 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4640 // return the worst status met
4642 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4643 Status
= Private
->TextOutList
[Index
].TextOut
->ClearScreen (Private
->TextOutList
[Index
].TextOut
);
4644 if (EFI_ERROR (Status
)) {
4645 ReturnStatus
= Status
;
4650 // No need to do extra check here as whether (Column, Row) is valid has
4651 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
4652 // always be supported.
4654 Private
->TextOutMode
.CursorColumn
= 0;
4655 Private
->TextOutMode
.CursorRow
= 0;
4656 Private
->TextOutMode
.CursorVisible
= TRUE
;
4658 return ReturnStatus
;
4663 Sets the current coordinates of the cursor position
4665 @param This Protocol instance pointer.
4666 @param Column The column position to set the cursor to. Must be
4667 greater than or equal to zero and less than the
4668 number of columns by QueryMode ().
4669 @param Row The row position to set the cursor to. Must be
4670 greater than or equal to zero and less than the
4671 number of rows by QueryMode ().
4673 @retval EFI_SUCCESS The operation completed successfully.
4674 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4676 @retval EFI_UNSUPPORTED The output device is not in a valid text mode,
4677 or the cursor position is invalid for the
4683 ConSplitterTextOutSetCursorPosition (
4684 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4690 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4692 EFI_STATUS ReturnStatus
;
4695 INT32
*TextOutModeMap
;
4699 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4700 TextOutModeMap
= NULL
;
4701 ModeNumber
= Private
->TextOutMode
.Mode
;
4704 // Get current MaxColumn and MaxRow from intersection map
4706 if (Private
->TextOutModeMap
!= NULL
) {
4707 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4708 CurrentMode
= *TextOutModeMap
;
4710 CurrentMode
= ModeNumber
;
4713 MaxColumn
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4714 MaxRow
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4716 if (Column
>= MaxColumn
|| Row
>= MaxRow
) {
4717 return EFI_UNSUPPORTED
;
4720 // return the worst status met
4722 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4723 Status
= Private
->TextOutList
[Index
].TextOut
->SetCursorPosition (
4724 Private
->TextOutList
[Index
].TextOut
,
4728 if (EFI_ERROR (Status
)) {
4729 ReturnStatus
= Status
;
4734 // No need to do extra check here as whether (Column, Row) is valid has
4735 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
4736 // always be supported.
4738 Private
->TextOutMode
.CursorColumn
= (INT32
) Column
;
4739 Private
->TextOutMode
.CursorRow
= (INT32
) Row
;
4741 return ReturnStatus
;
4746 Makes the cursor visible or invisible
4748 @param This Protocol instance pointer.
4749 @param Visible If TRUE, the cursor is set to be visible. If
4750 FALSE, the cursor is set to be invisible.
4752 @retval EFI_SUCCESS The operation completed successfully.
4753 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4754 the request, or the device does not support
4755 changing the cursor mode.
4756 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4761 ConSplitterTextOutEnableCursor (
4762 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4767 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4769 EFI_STATUS ReturnStatus
;
4771 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4774 // return the worst status met
4776 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4777 Status
= Private
->TextOutList
[Index
].TextOut
->EnableCursor (
4778 Private
->TextOutList
[Index
].TextOut
,
4781 if (EFI_ERROR (Status
)) {
4782 ReturnStatus
= Status
;
4786 Private
->TextOutMode
.CursorVisible
= Visible
;
4788 return ReturnStatus
;
4793 An empty function to pass error checking of CreateEventEx ().
4795 @param Event Event whose notification function is being invoked.
4796 @param Context Pointer to the notification function's context,
4797 which is implementation-dependent.
4802 ConSplitterEmptyCallbackFunction (