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 - 2011, Intel Corporation. All rights reserved.<BR>
20 This program and the accompanying materials
21 are licensed and made available under the terms and conditions of the BSD License
22 which accompanies this distribution. The full text of the license may be found at
23 http://opensource.org/licenses/bsd-license.php
25 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
26 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
30 #include "ConSplitter.h"
33 // Text In Splitter Private Data template
35 GLOBAL_REMOVE_IF_UNREFERENCED TEXT_IN_SPLITTER_PRIVATE_DATA mConIn
= {
36 TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE
,
40 ConSplitterTextInReset
,
41 ConSplitterTextInReadKeyStroke
,
45 (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
**) NULL
,
49 ConSplitterTextInResetEx
,
50 ConSplitterTextInReadKeyStrokeEx
,
52 ConSplitterTextInSetState
,
53 ConSplitterTextInRegisterKeyNotify
,
54 ConSplitterTextInUnregisterKeyNotify
57 (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
**) NULL
,
65 ConSplitterSimplePointerReset
,
66 ConSplitterSimplePointerGetState
,
68 (EFI_SIMPLE_POINTER_MODE
*) NULL
78 (EFI_SIMPLE_POINTER_PROTOCOL
**) NULL
,
82 ConSplitterAbsolutePointerReset
,
83 ConSplitterAbsolutePointerGetState
,
85 (EFI_ABSOLUTE_POINTER_MODE
*) NULL
91 0x10000, // AbsoluteMaxX
92 0x10000, // AbsoluteMaxY
93 0x10000, // AbsoluteMaxZ
97 (EFI_ABSOLUTE_POINTER_PROTOCOL
**) NULL
,
107 // Uga Draw Protocol Private Data template
109 GLOBAL_REMOVE_IF_UNREFERENCED EFI_UGA_DRAW_PROTOCOL mUgaDrawProtocolTemplate
= {
110 ConSplitterUgaDrawGetMode
,
111 ConSplitterUgaDrawSetMode
,
112 ConSplitterUgaDrawBlt
116 // Graphics Output Protocol Private Data template
118 GLOBAL_REMOVE_IF_UNREFERENCED EFI_GRAPHICS_OUTPUT_PROTOCOL mGraphicsOutputProtocolTemplate
= {
119 ConSplitterGraphicsOutputQueryMode
,
120 ConSplitterGraphicsOutputSetMode
,
121 ConSplitterGraphicsOutputBlt
,
127 // Text Out Splitter Private Data template
129 GLOBAL_REMOVE_IF_UNREFERENCED TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut
= {
130 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE
,
133 ConSplitterTextOutReset
,
134 ConSplitterTextOutOutputString
,
135 ConSplitterTextOutTestString
,
136 ConSplitterTextOutQueryMode
,
137 ConSplitterTextOutSetMode
,
138 ConSplitterTextOutSetAttribute
,
139 ConSplitterTextOutClearScreen
,
140 ConSplitterTextOutSetCursorPosition
,
141 ConSplitterTextOutEnableCursor
,
142 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
169 (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*) NULL
,
174 (TEXT_OUT_AND_GOP_DATA
*) NULL
,
176 (TEXT_OUT_SPLITTER_QUERY_DATA
*) NULL
,
182 // Standard Error Text Out Splitter Data Template
184 GLOBAL_REMOVE_IF_UNREFERENCED TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr
= {
185 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE
,
188 ConSplitterTextOutReset
,
189 ConSplitterTextOutOutputString
,
190 ConSplitterTextOutTestString
,
191 ConSplitterTextOutQueryMode
,
192 ConSplitterTextOutSetMode
,
193 ConSplitterTextOutSetAttribute
,
194 ConSplitterTextOutClearScreen
,
195 ConSplitterTextOutSetCursorPosition
,
196 ConSplitterTextOutEnableCursor
,
197 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
224 (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*) NULL
,
229 (TEXT_OUT_AND_GOP_DATA
*) NULL
,
231 (TEXT_OUT_SPLITTER_QUERY_DATA
*) NULL
,
237 // Driver binding instance for Console Input Device
239 EFI_DRIVER_BINDING_PROTOCOL gConSplitterConInDriverBinding
= {
240 ConSplitterConInDriverBindingSupported
,
241 ConSplitterConInDriverBindingStart
,
242 ConSplitterConInDriverBindingStop
,
249 // Driver binding instance for Console Out device
251 EFI_DRIVER_BINDING_PROTOCOL gConSplitterConOutDriverBinding
= {
252 ConSplitterConOutDriverBindingSupported
,
253 ConSplitterConOutDriverBindingStart
,
254 ConSplitterConOutDriverBindingStop
,
261 // Driver binding instance for Standard Error device
263 EFI_DRIVER_BINDING_PROTOCOL gConSplitterStdErrDriverBinding
= {
264 ConSplitterStdErrDriverBindingSupported
,
265 ConSplitterStdErrDriverBindingStart
,
266 ConSplitterStdErrDriverBindingStop
,
273 // Driver binding instance for Simple Pointer protocol
275 EFI_DRIVER_BINDING_PROTOCOL gConSplitterSimplePointerDriverBinding
= {
276 ConSplitterSimplePointerDriverBindingSupported
,
277 ConSplitterSimplePointerDriverBindingStart
,
278 ConSplitterSimplePointerDriverBindingStop
,
285 // Driver binding instance for Absolute Pointer protocol
287 EFI_DRIVER_BINDING_PROTOCOL gConSplitterAbsolutePointerDriverBinding
= {
288 ConSplitterAbsolutePointerDriverBindingSupported
,
289 ConSplitterAbsolutePointerDriverBindingStart
,
290 ConSplitterAbsolutePointerDriverBindingStop
,
297 The Entry Point for module ConSplitter. The user code starts with this function.
299 Installs driver module protocols and. Creates virtual device handles for ConIn,
300 ConOut, and StdErr. Installs Simple Text In protocol, Simple Text In Ex protocol,
301 Simple Pointer protocol, Absolute Pointer protocol on those virtual handlers.
302 Installs Graphics Output protocol and/or UGA Draw protocol if needed.
304 @param[in] ImageHandle The firmware allocated handle for the EFI image.
305 @param[in] SystemTable A pointer to the EFI System Table.
307 @retval EFI_SUCCESS The entry point is executed successfully.
308 @retval other Some error occurs when executing this entry point.
313 ConSplitterDriverEntry(
314 IN EFI_HANDLE ImageHandle
,
315 IN EFI_SYSTEM_TABLE
*SystemTable
321 // Install driver model protocol(s).
323 Status
= EfiLibInstallDriverBindingComponentName2 (
326 &gConSplitterConInDriverBinding
,
328 &gConSplitterConInComponentName
,
329 &gConSplitterConInComponentName2
331 ASSERT_EFI_ERROR (Status
);
333 Status
= EfiLibInstallDriverBindingComponentName2 (
336 &gConSplitterSimplePointerDriverBinding
,
338 &gConSplitterSimplePointerComponentName
,
339 &gConSplitterSimplePointerComponentName2
341 ASSERT_EFI_ERROR (Status
);
343 Status
= EfiLibInstallDriverBindingComponentName2 (
346 &gConSplitterAbsolutePointerDriverBinding
,
348 &gConSplitterAbsolutePointerComponentName
,
349 &gConSplitterAbsolutePointerComponentName2
351 ASSERT_EFI_ERROR (Status
);
353 Status
= EfiLibInstallDriverBindingComponentName2 (
356 &gConSplitterConOutDriverBinding
,
358 &gConSplitterConOutComponentName
,
359 &gConSplitterConOutComponentName2
361 ASSERT_EFI_ERROR (Status
);
363 Status
= EfiLibInstallDriverBindingComponentName2 (
366 &gConSplitterStdErrDriverBinding
,
368 &gConSplitterStdErrComponentName
,
369 &gConSplitterStdErrComponentName2
371 ASSERT_EFI_ERROR (Status
);
374 // Either Graphics Output protocol or UGA Draw protocol must be supported.
376 ASSERT (FeaturePcdGet (PcdConOutGopSupport
) ||
377 FeaturePcdGet (PcdConOutUgaSupport
));
380 // The driver creates virtual handles for ConIn, ConOut.
381 // The virtual handles will always exist even if no console exist in the
382 // system. This is need to support hotplug devices like USB.
385 // Create virtual device handle for ConIn Splitter
387 Status
= ConSplitterTextInConstructor (&mConIn
);
388 if (!EFI_ERROR (Status
)) {
389 Status
= gBS
->InstallMultipleProtocolInterfaces (
390 &mConIn
.VirtualHandle
,
391 &gEfiSimpleTextInProtocolGuid
,
393 &gEfiSimpleTextInputExProtocolGuid
,
395 &gEfiSimplePointerProtocolGuid
,
396 &mConIn
.SimplePointer
,
397 &gEfiAbsolutePointerProtocolGuid
,
398 &mConIn
.AbsolutePointer
,
401 if (!EFI_ERROR (Status
)) {
403 // Update the EFI System Table with new virtual console
404 // and update the pointer to Simple Text Input protocol.
406 gST
->ConsoleInHandle
= mConIn
.VirtualHandle
;
407 gST
->ConIn
= &mConIn
.TextIn
;
411 // Create virtual device handle for ConOut Splitter
413 Status
= ConSplitterTextOutConstructor (&mConOut
);
414 if (!EFI_ERROR (Status
)) {
415 if (!FeaturePcdGet (PcdConOutGopSupport
)) {
417 // If Graphics Outpurt protocol not supported, UGA Draw protocol is installed
418 // on the virtual handle.
420 Status
= gBS
->InstallMultipleProtocolInterfaces (
421 &mConOut
.VirtualHandle
,
422 &gEfiSimpleTextOutProtocolGuid
,
424 &gEfiUgaDrawProtocolGuid
,
428 } else if (!FeaturePcdGet (PcdConOutUgaSupport
)) {
430 // If UGA Draw protocol not supported, Graphics Output Protocol is installed
431 // on virtual handle.
433 Status
= gBS
->InstallMultipleProtocolInterfaces (
434 &mConOut
.VirtualHandle
,
435 &gEfiSimpleTextOutProtocolGuid
,
437 &gEfiGraphicsOutputProtocolGuid
,
438 &mConOut
.GraphicsOutput
,
443 // Boot Graphics Output protocol and UGA Draw protocol are supported,
444 // both they will be installed on virtual handle.
446 Status
= gBS
->InstallMultipleProtocolInterfaces (
447 &mConOut
.VirtualHandle
,
448 &gEfiSimpleTextOutProtocolGuid
,
450 &gEfiGraphicsOutputProtocolGuid
,
451 &mConOut
.GraphicsOutput
,
452 &gEfiUgaDrawProtocolGuid
,
458 if (!EFI_ERROR (Status
)) {
460 // Update the EFI System Table with new virtual console
461 // and Update the pointer to Text Output protocol.
463 gST
->ConsoleOutHandle
= mConOut
.VirtualHandle
;
464 gST
->ConOut
= &mConOut
.TextOut
;
469 // Update the CRC32 in the EFI System Table header
472 gBS
->CalculateCrc32 (
483 Construct console input devices' private data.
485 @param ConInPrivate A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA
488 @retval EFI_OUT_OF_RESOURCES Out of resources.
489 @retval EFI_SUCCESS Text Input Devcie's private data has been constructed.
490 @retval other Failed to construct private data.
494 ConSplitterTextInConstructor (
495 TEXT_IN_SPLITTER_PRIVATE_DATA
*ConInPrivate
501 // Allocate buffer for Simple Text Input device
503 Status
= ConSplitterGrowBuffer (
504 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
505 &ConInPrivate
->TextInListCount
,
506 (VOID
**) &ConInPrivate
->TextInList
508 if (EFI_ERROR (Status
)) {
509 return EFI_OUT_OF_RESOURCES
;
513 // Create Event to wait for a key
515 Status
= gBS
->CreateEvent (
518 ConSplitterTextInWaitForKey
,
520 &ConInPrivate
->TextIn
.WaitForKey
522 ASSERT_EFI_ERROR (Status
);
525 // Allocate buffer for Simple Text Input Ex device
527 Status
= ConSplitterGrowBuffer (
528 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
529 &ConInPrivate
->TextInExListCount
,
530 (VOID
**) &ConInPrivate
->TextInExList
532 if (EFI_ERROR (Status
)) {
533 return EFI_OUT_OF_RESOURCES
;
536 // Create Event to wait for a key Ex
538 Status
= gBS
->CreateEvent (
541 ConSplitterTextInWaitForKey
,
543 &ConInPrivate
->TextInEx
.WaitForKeyEx
545 ASSERT_EFI_ERROR (Status
);
547 InitializeListHead (&ConInPrivate
->NotifyList
);
549 ConInPrivate
->AbsolutePointer
.Mode
= &ConInPrivate
->AbsolutePointerMode
;
551 // Allocate buffer for Absolute Pointer device
553 Status
= ConSplitterGrowBuffer (
554 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
555 &ConInPrivate
->AbsolutePointerListCount
,
556 (VOID
**) &ConInPrivate
->AbsolutePointerList
558 if (EFI_ERROR (Status
)) {
559 return EFI_OUT_OF_RESOURCES
;
562 // Create Event to wait for device input for Absolute pointer device
564 Status
= gBS
->CreateEvent (
567 ConSplitterAbsolutePointerWaitForInput
,
569 &ConInPrivate
->AbsolutePointer
.WaitForInput
571 ASSERT_EFI_ERROR (Status
);
573 ConInPrivate
->SimplePointer
.Mode
= &ConInPrivate
->SimplePointerMode
;
575 // Allocate buffer for Simple Pointer device
577 Status
= ConSplitterGrowBuffer (
578 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
579 &ConInPrivate
->PointerListCount
,
580 (VOID
**) &ConInPrivate
->PointerList
582 if (EFI_ERROR (Status
)) {
583 return EFI_OUT_OF_RESOURCES
;
586 // Create Event to wait for device input for Simple pointer device
588 Status
= gBS
->CreateEvent (
591 ConSplitterSimplePointerWaitForInput
,
593 &ConInPrivate
->SimplePointer
.WaitForInput
600 Construct console output devices' private data.
602 @param ConOutPrivate A pointer to the TEXT_OUT_SPLITTER_PRIVATE_DATA
605 @retval EFI_OUT_OF_RESOURCES Out of resources.
606 @retval EFI_SUCCESS Text Input Devcie's private data has been constructed.
610 ConSplitterTextOutConstructor (
611 TEXT_OUT_SPLITTER_PRIVATE_DATA
*ConOutPrivate
615 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
618 // Copy protocols template
620 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
621 CopyMem (&ConOutPrivate
->UgaDraw
, &mUgaDrawProtocolTemplate
, sizeof (EFI_UGA_DRAW_PROTOCOL
));
623 if (FeaturePcdGet (PcdConOutGopSupport
)) {
624 CopyMem (&ConOutPrivate
->GraphicsOutput
, &mGraphicsOutputProtocolTemplate
, sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL
));
628 // Initilize console output splitter's private data.
630 ConOutPrivate
->TextOut
.Mode
= &ConOutPrivate
->TextOutMode
;
633 // When new console device is added, the new mode will be set later,
634 // so put current mode back to init state.
636 ConOutPrivate
->TextOutMode
.Mode
= 0xFF;
638 // Allocate buffer for Console Out device
640 Status
= ConSplitterGrowBuffer (
641 sizeof (TEXT_OUT_AND_GOP_DATA
),
642 &ConOutPrivate
->TextOutListCount
,
643 (VOID
**) &ConOutPrivate
->TextOutList
645 if (EFI_ERROR (Status
)) {
646 return EFI_OUT_OF_RESOURCES
;
649 // Allocate buffer for Text Out query data
651 Status
= ConSplitterGrowBuffer (
652 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
653 &ConOutPrivate
->TextOutQueryDataCount
,
654 (VOID
**) &ConOutPrivate
->TextOutQueryData
656 if (EFI_ERROR (Status
)) {
657 return EFI_OUT_OF_RESOURCES
;
661 // Setup the default console to 80 x 25 and mode to 0
663 ConOutPrivate
->TextOutQueryData
[0].Columns
= 80;
664 ConOutPrivate
->TextOutQueryData
[0].Rows
= 25;
665 TextOutSetMode (ConOutPrivate
, 0);
668 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
670 // Setup the UgaDraw to 800 x 600 x 32 bits per pixel, 60Hz.
672 ConSplitterUgaDrawSetMode (&ConOutPrivate
->UgaDraw
, 800, 600, 32, 60);
674 if (FeaturePcdGet (PcdConOutGopSupport
)) {
676 // Setup resource for mode information in Graphics Output Protocol interface
678 if ((ConOutPrivate
->GraphicsOutput
.Mode
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
))) == NULL
) {
679 return EFI_OUT_OF_RESOURCES
;
681 if ((ConOutPrivate
->GraphicsOutput
.Mode
->Info
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
))) == NULL
) {
682 return EFI_OUT_OF_RESOURCES
;
685 // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel
686 // DevNull will be updated to user-defined mode after driver has started.
688 if ((ConOutPrivate
->GraphicsOutputModeBuffer
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
))) == NULL
) {
689 return EFI_OUT_OF_RESOURCES
;
691 Info
= &ConOutPrivate
->GraphicsOutputModeBuffer
[0];
693 Info
->HorizontalResolution
= 800;
694 Info
->VerticalResolution
= 600;
695 Info
->PixelFormat
= PixelBltOnly
;
696 Info
->PixelsPerScanLine
= 800;
697 CopyMem (ConOutPrivate
->GraphicsOutput
.Mode
->Info
, Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
698 ConOutPrivate
->GraphicsOutput
.Mode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
701 // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()
702 // GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
704 ConOutPrivate
->GraphicsOutput
.Mode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
705 ConOutPrivate
->GraphicsOutput
.Mode
->FrameBufferSize
= 0;
707 ConOutPrivate
->GraphicsOutput
.Mode
->MaxMode
= 1;
709 // Initial current mode to unknown state, and then set to mode 0
711 ConOutPrivate
->GraphicsOutput
.Mode
->Mode
= 0xffff;
712 ConOutPrivate
->GraphicsOutput
.SetMode (&ConOutPrivate
->GraphicsOutput
, 0);
720 Test to see if the specified protocol could be supported on the specified device.
722 @param This Driver Binding protocol pointer.
723 @param ControllerHandle Handle of device to test.
724 @param Guid The specified protocol.
726 @retval EFI_SUCCESS The specified protocol is supported on this device.
727 @retval EFI_UNSUPPORTED The specified protocol attempts to be installed on virtul handle.
728 @retval other Failed to open specified protocol on this device.
732 ConSplitterSupported (
733 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
734 IN EFI_HANDLE ControllerHandle
,
742 // Make sure the Console Splitter does not attempt to attach to itself
744 if (ControllerHandle
== mConIn
.VirtualHandle
||
745 ControllerHandle
== mConOut
.VirtualHandle
||
746 ControllerHandle
== mStdErr
.VirtualHandle
748 return EFI_UNSUPPORTED
;
752 // Check to see whether the specific protocol could be opened BY_DRIVER
754 Status
= gBS
->OpenProtocol (
758 This
->DriverBindingHandle
,
760 EFI_OPEN_PROTOCOL_BY_DRIVER
763 if (EFI_ERROR (Status
)) {
770 This
->DriverBindingHandle
,
778 Test to see if Console In Device could be supported on the Controller.
780 @param This Driver Binding protocol instance pointer.
781 @param ControllerHandle Handle of device to test.
782 @param RemainingDevicePath Optional parameter use to pick a specific child
785 @retval EFI_SUCCESS This driver supports this device.
786 @retval other This driver does not support this device.
791 ConSplitterConInDriverBindingSupported (
792 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
793 IN EFI_HANDLE ControllerHandle
,
794 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
797 return ConSplitterSupported (
800 &gEfiConsoleInDeviceGuid
805 Test to see if Simple Pointer protocol could be supported on the Controller.
807 @param This Driver Binding protocol instance pointer.
808 @param ControllerHandle Handle of device to test.
809 @param RemainingDevicePath Optional parameter use to pick a specific child
812 @retval EFI_SUCCESS This driver supports this device.
813 @retval other This driver does not support this device.
818 ConSplitterSimplePointerDriverBindingSupported (
819 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
820 IN EFI_HANDLE ControllerHandle
,
821 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
824 return ConSplitterSupported (
827 &gEfiSimplePointerProtocolGuid
832 Test to see if Absolute Pointer protocol could be supported on the Controller.
834 @param This Driver Binding protocol instance pointer.
835 @param ControllerHandle Handle of device to test.
836 @param RemainingDevicePath Optional parameter use to pick a specific child
839 @retval EFI_SUCCESS This driver supports this device.
840 @retval other This driver does not support this device.
845 ConSplitterAbsolutePointerDriverBindingSupported (
846 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
847 IN EFI_HANDLE ControllerHandle
,
848 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
851 return ConSplitterSupported (
854 &gEfiAbsolutePointerProtocolGuid
860 Test to see if Console Out Device could be supported on the Controller.
862 @param This Driver Binding protocol instance pointer.
863 @param ControllerHandle Handle of device to test.
864 @param RemainingDevicePath Optional parameter use to pick a specific child
867 @retval EFI_SUCCESS This driver supports this device.
868 @retval other This driver does not support this device.
873 ConSplitterConOutDriverBindingSupported (
874 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
875 IN EFI_HANDLE ControllerHandle
,
876 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
879 return ConSplitterSupported (
882 &gEfiConsoleOutDeviceGuid
887 Test to see if Standard Error Device could be supported on the Controller.
889 @param This Driver Binding protocol instance pointer.
890 @param ControllerHandle Handle of device to test.
891 @param RemainingDevicePath Optional parameter use to pick a specific child
894 @retval EFI_SUCCESS This driver supports this device.
895 @retval other This driver does not support this device.
900 ConSplitterStdErrDriverBindingSupported (
901 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
902 IN EFI_HANDLE ControllerHandle
,
903 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
906 return ConSplitterSupported (
909 &gEfiStandardErrorDeviceGuid
915 Start ConSplitter on devcie handle by opening Console Device Guid on device handle
916 and the console virtual handle. And Get the console interface on controller handle.
918 @param This Driver Binding protocol instance pointer.
919 @param ControllerHandle Handle of device.
920 @param ConSplitterVirtualHandle Console virtual Handle.
921 @param DeviceGuid The specified Console Device, such as ConInDev,
923 @param InterfaceGuid The specified protocol to be opened.
924 @param Interface Protocol interface returned.
926 @retval EFI_SUCCESS This driver supports this device.
927 @retval other Failed to open the specified Console Device Guid
928 or specified protocol.
933 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
934 IN EFI_HANDLE ControllerHandle
,
935 IN EFI_HANDLE ConSplitterVirtualHandle
,
936 IN EFI_GUID
*DeviceGuid
,
937 IN EFI_GUID
*InterfaceGuid
,
945 // Check to see whether the ControllerHandle has the DeviceGuid on it.
947 Status
= gBS
->OpenProtocol (
951 This
->DriverBindingHandle
,
953 EFI_OPEN_PROTOCOL_BY_DRIVER
955 if (EFI_ERROR (Status
)) {
960 // Open the Parent Handle for the child.
962 Status
= gBS
->OpenProtocol (
966 This
->DriverBindingHandle
,
967 ConSplitterVirtualHandle
,
968 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
970 if (EFI_ERROR (Status
)) {
975 // Open InterfaceGuid on the virtul handle.
977 Status
= gBS
->OpenProtocol (
981 This
->DriverBindingHandle
,
982 ConSplitterVirtualHandle
,
983 EFI_OPEN_PROTOCOL_GET_PROTOCOL
986 if (!EFI_ERROR (Status
)) {
991 // close the DeviceGuid on ConSplitter VirtualHandle.
996 This
->DriverBindingHandle
,
997 ConSplitterVirtualHandle
1002 // close the DeviceGuid on ControllerHandle.
1004 gBS
->CloseProtocol (
1007 This
->DriverBindingHandle
,
1016 Start Console In Consplitter on device handle.
1018 @param This Driver Binding protocol instance pointer.
1019 @param ControllerHandle Handle of device to bind driver to.
1020 @param RemainingDevicePath Optional parameter use to pick a specific child
1023 @retval EFI_SUCCESS Console In Consplitter is added to ControllerHandle.
1024 @retval other Console In Consplitter does not support this device.
1029 ConSplitterConInDriverBindingStart (
1030 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1031 IN EFI_HANDLE ControllerHandle
,
1032 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1036 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
1037 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
;
1040 // Start ConSplitter on ControllerHandle, and create the virtual
1041 // agrogated console device on first call Start for a SimpleTextIn handle.
1043 Status
= ConSplitterStart (
1046 mConIn
.VirtualHandle
,
1047 &gEfiConsoleInDeviceGuid
,
1048 &gEfiSimpleTextInProtocolGuid
,
1051 if (EFI_ERROR (Status
)) {
1056 // Add this device into Text In devices list.
1058 Status
= ConSplitterTextInAddDevice (&mConIn
, TextIn
);
1059 if (EFI_ERROR (Status
)) {
1063 Status
= gBS
->OpenProtocol (
1065 &gEfiSimpleTextInputExProtocolGuid
,
1066 (VOID
**) &TextInEx
,
1067 This
->DriverBindingHandle
,
1068 mConIn
.VirtualHandle
,
1069 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1071 if (!EFI_ERROR (Status
)) {
1073 // If Simple Text Input Ex protocol exists,
1074 // add this device into Text In Ex devices list.
1076 Status
= ConSplitterTextInExAddDevice (&mConIn
, TextInEx
);
1084 Start Simple Pointer Consplitter on device handle.
1086 @param This Driver Binding protocol instance pointer.
1087 @param ControllerHandle Handle of device to bind driver to.
1088 @param RemainingDevicePath Optional parameter use to pick a specific child
1091 @retval EFI_SUCCESS Simple Pointer Consplitter is added to ControllerHandle.
1092 @retval other Simple Pointer Consplitter does not support this device.
1097 ConSplitterSimplePointerDriverBindingStart (
1098 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1099 IN EFI_HANDLE ControllerHandle
,
1100 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1104 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
;
1107 // Start ConSplitter on ControllerHandle, and create the virtual
1108 // agrogated console device on first call Start for a SimplePointer handle.
1110 Status
= ConSplitterStart (
1113 mConIn
.VirtualHandle
,
1114 &gEfiSimplePointerProtocolGuid
,
1115 &gEfiSimplePointerProtocolGuid
,
1116 (VOID
**) &SimplePointer
1118 if (EFI_ERROR (Status
)) {
1123 // Add this devcie into Simple Pointer devices list.
1125 return ConSplitterSimplePointerAddDevice (&mConIn
, SimplePointer
);
1130 Start Absolute Pointer Consplitter on device handle.
1132 @param This Driver Binding protocol instance pointer.
1133 @param ControllerHandle Handle of device to bind driver to.
1134 @param RemainingDevicePath Optional parameter use to pick a specific child
1137 @retval EFI_SUCCESS Absolute Pointer Consplitter is added to ControllerHandle.
1138 @retval other Absolute Pointer Consplitter does not support this device.
1143 ConSplitterAbsolutePointerDriverBindingStart (
1144 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1145 IN EFI_HANDLE ControllerHandle
,
1146 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1150 EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
;
1153 // Start ConSplitter on ControllerHandle, and create the virtual
1154 // agrogated console device on first call Start for a AbsolutePointer handle.
1156 Status
= ConSplitterStart (
1159 mConIn
.VirtualHandle
,
1160 &gEfiAbsolutePointerProtocolGuid
,
1161 &gEfiAbsolutePointerProtocolGuid
,
1162 (VOID
**) &AbsolutePointer
1165 if (EFI_ERROR (Status
)) {
1170 // Add this devcie into Absolute Pointer devices list.
1172 return ConSplitterAbsolutePointerAddDevice (&mConIn
, AbsolutePointer
);
1177 Start Console Out Consplitter on device handle.
1179 @param This Driver Binding protocol instance pointer.
1180 @param ControllerHandle Handle of device to bind driver to.
1181 @param RemainingDevicePath Optional parameter use to pick a specific child
1184 @retval EFI_SUCCESS Console Out Consplitter is added to ControllerHandle.
1185 @retval other Console Out Consplitter does not support this device.
1190 ConSplitterConOutDriverBindingStart (
1191 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1192 IN EFI_HANDLE ControllerHandle
,
1193 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1197 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1198 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1199 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1201 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
1204 // Start ConSplitter on ControllerHandle, and create the virtual
1205 // agrogated console device on first call Start for a ConsoleOut handle.
1207 Status
= ConSplitterStart (
1210 mConOut
.VirtualHandle
,
1211 &gEfiConsoleOutDeviceGuid
,
1212 &gEfiSimpleTextOutProtocolGuid
,
1215 if (EFI_ERROR (Status
)) {
1219 GraphicsOutput
= NULL
;
1222 // Try to Open Graphics Output protocol
1224 Status
= gBS
->OpenProtocol (
1226 &gEfiGraphicsOutputProtocolGuid
,
1227 (VOID
**) &GraphicsOutput
,
1228 This
->DriverBindingHandle
,
1229 mConOut
.VirtualHandle
,
1230 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1233 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
1235 // Open UGA DRAW protocol
1239 &gEfiUgaDrawProtocolGuid
,
1241 This
->DriverBindingHandle
,
1242 mConOut
.VirtualHandle
,
1243 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1248 // When new console device is added, the new mode will be set later,
1249 // so put current mode back to init state.
1251 mConOut
.TextOutMode
.Mode
= 0xFF;
1254 // If both ConOut and StdErr incorporate the same Text Out device,
1255 // their MaxMode and QueryData should be the intersection of both.
1257 Status
= ConSplitterTextOutAddDevice (&mConOut
, TextOut
, GraphicsOutput
, UgaDraw
);
1258 ConSplitterTextOutSetAttribute (&mConOut
.TextOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
1260 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
1262 // Get the UGA mode data of ConOut from the current mode
1264 if (GraphicsOutput
!= NULL
) {
1265 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, GraphicsOutput
->Mode
->Mode
, &SizeOfInfo
, &Info
);
1266 if (EFI_ERROR (Status
)) {
1269 ASSERT ( SizeOfInfo
<= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
1271 mConOut
.UgaHorizontalResolution
= Info
->HorizontalResolution
;
1272 mConOut
.UgaVerticalResolution
= Info
->VerticalResolution
;
1273 mConOut
.UgaColorDepth
= 32;
1274 mConOut
.UgaRefreshRate
= 60;
1278 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1279 Status
= UgaDraw
->GetMode (
1281 &mConOut
.UgaHorizontalResolution
,
1282 &mConOut
.UgaVerticalResolution
,
1283 &mConOut
.UgaColorDepth
,
1284 &mConOut
.UgaRefreshRate
1294 Start Standard Error Consplitter on device handle.
1296 @param This Driver Binding protocol instance pointer.
1297 @param ControllerHandle Handle of device to bind driver to.
1298 @param RemainingDevicePath Optional parameter use to pick a specific child
1301 @retval EFI_SUCCESS Standard Error Consplitter is added to ControllerHandle.
1302 @retval other Standard Error Consplitter does not support this device.
1307 ConSplitterStdErrDriverBindingStart (
1308 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1309 IN EFI_HANDLE ControllerHandle
,
1310 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1314 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1316 if (mStdErr
.CurrentNumberOfConsoles
== 0) {
1318 // Construct console output devices' private data
1320 Status
= ConSplitterTextOutConstructor (&mStdErr
);
1321 if (!EFI_ERROR (Status
)) {
1323 // Create virtual device handle for StdErr Splitter
1325 Status
= gBS
->InstallMultipleProtocolInterfaces (
1326 &mStdErr
.VirtualHandle
,
1327 &gEfiSimpleTextOutProtocolGuid
,
1332 if (EFI_ERROR (Status
)) {
1338 // Start ConSplitter on ControllerHandle, and create the virtual
1339 // agrogated console device on first call Start for a StandardError handle.
1341 Status
= ConSplitterStart (
1344 mStdErr
.VirtualHandle
,
1345 &gEfiStandardErrorDeviceGuid
,
1346 &gEfiSimpleTextOutProtocolGuid
,
1349 if (EFI_ERROR (Status
)) {
1354 // When new console device is added, the new mode will be set later,
1355 // so put current mode back to init state.
1357 mStdErr
.TextOutMode
.Mode
= 0xFF;
1360 // If both ConOut and StdErr incorporate the same Text Out device,
1361 // their MaxMode and QueryData should be the intersection of both.
1363 Status
= ConSplitterTextOutAddDevice (&mStdErr
, TextOut
, NULL
, NULL
);
1364 ConSplitterTextOutSetAttribute (&mStdErr
.TextOut
, EFI_TEXT_ATTR (EFI_MAGENTA
, EFI_BLACK
));
1365 if (EFI_ERROR (Status
)) {
1369 if (mStdErr
.CurrentNumberOfConsoles
== 1) {
1370 gST
->StandardErrorHandle
= mStdErr
.VirtualHandle
;
1371 gST
->StdErr
= &mStdErr
.TextOut
;
1373 // Update the CRC32 in the EFI System Table header
1376 gBS
->CalculateCrc32 (
1377 (UINT8
*) &gST
->Hdr
,
1378 gST
->Hdr
.HeaderSize
,
1388 Stop ConSplitter on device handle by closing Console Device Guid on device handle
1389 and the console virtual handle.
1391 @param This Protocol instance pointer.
1392 @param ControllerHandle Handle of device.
1393 @param ConSplitterVirtualHandle Console virtual Handle.
1394 @param DeviceGuid The specified Console Device, such as ConInDev,
1396 @param InterfaceGuid The specified protocol to be opened.
1397 @param Interface Protocol interface returned.
1399 @retval EFI_SUCCESS Stop ConSplitter on ControllerHandle successfully.
1400 @retval other Failed to Stop ConSplitter on ControllerHandle.
1405 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1406 IN EFI_HANDLE ControllerHandle
,
1407 IN EFI_HANDLE ConSplitterVirtualHandle
,
1408 IN EFI_GUID
*DeviceGuid
,
1409 IN EFI_GUID
*InterfaceGuid
,
1415 Status
= gBS
->OpenProtocol (
1419 This
->DriverBindingHandle
,
1421 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1423 if (EFI_ERROR (Status
)) {
1427 // close the protocol refered.
1429 gBS
->CloseProtocol (
1432 This
->DriverBindingHandle
,
1433 ConSplitterVirtualHandle
1436 gBS
->CloseProtocol (
1439 This
->DriverBindingHandle
,
1448 Stop Console In ConSplitter on ControllerHandle by closing Console In Devcice GUID.
1450 @param This Driver Binding protocol instance pointer.
1451 @param ControllerHandle Handle of device to stop driver on
1452 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1453 children is zero stop the entire bus driver.
1454 @param ChildHandleBuffer List of Child Handles to Stop.
1456 @retval EFI_SUCCESS This driver is removed ControllerHandle
1457 @retval other This driver was not removed from this device
1462 ConSplitterConInDriverBindingStop (
1463 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1464 IN EFI_HANDLE ControllerHandle
,
1465 IN UINTN NumberOfChildren
,
1466 IN EFI_HANDLE
*ChildHandleBuffer
1470 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
1471 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
;
1473 if (NumberOfChildren
== 0) {
1477 Status
= gBS
->OpenProtocol (
1479 &gEfiSimpleTextInputExProtocolGuid
,
1480 (VOID
**) &TextInEx
,
1481 This
->DriverBindingHandle
,
1483 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1485 if (!EFI_ERROR (Status
)) {
1487 // If Simple Text Input Ex protocol exists,
1488 // remove device from Text Input Ex devices list.
1490 Status
= ConSplitterTextInExDeleteDevice (&mConIn
, TextInEx
);
1491 if (EFI_ERROR (Status
)) {
1497 // Close Simple Text In protocol on controller handle and virtual handle.
1499 Status
= ConSplitterStop (
1502 mConIn
.VirtualHandle
,
1503 &gEfiConsoleInDeviceGuid
,
1504 &gEfiSimpleTextInProtocolGuid
,
1507 if (EFI_ERROR (Status
)) {
1512 // Remove device from Text Input devices list.
1514 return ConSplitterTextInDeleteDevice (&mConIn
, TextIn
);
1519 Stop Simple Pointer protocol ConSplitter on ControllerHandle by closing
1520 Simple Pointer protocol.
1522 @param This Driver Binding protocol instance pointer.
1523 @param ControllerHandle Handle of device to stop driver on
1524 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1525 children is zero stop the entire bus driver.
1526 @param ChildHandleBuffer List of Child Handles to Stop.
1528 @retval EFI_SUCCESS This driver is removed ControllerHandle
1529 @retval other This driver was not removed from this device
1534 ConSplitterSimplePointerDriverBindingStop (
1535 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1536 IN EFI_HANDLE ControllerHandle
,
1537 IN UINTN NumberOfChildren
,
1538 IN EFI_HANDLE
*ChildHandleBuffer
1542 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
;
1544 if (NumberOfChildren
== 0) {
1549 // Close Simple Pointer protocol on controller handle and virtual handle.
1551 Status
= ConSplitterStop (
1554 mConIn
.VirtualHandle
,
1555 &gEfiSimplePointerProtocolGuid
,
1556 &gEfiSimplePointerProtocolGuid
,
1557 (VOID
**) &SimplePointer
1559 if (EFI_ERROR (Status
)) {
1564 // Remove this device from Simple Pointer device list.
1566 return ConSplitterSimplePointerDeleteDevice (&mConIn
, SimplePointer
);
1571 Stop Absolute Pointer protocol ConSplitter on ControllerHandle by closing
1572 Absolute Pointer protocol.
1574 @param This Driver Binding protocol instance pointer.
1575 @param ControllerHandle Handle of device to stop driver on
1576 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1577 children is zero stop the entire bus driver.
1578 @param ChildHandleBuffer List of Child Handles to Stop.
1580 @retval EFI_SUCCESS This driver is removed ControllerHandle
1581 @retval other This driver was not removed from this device
1586 ConSplitterAbsolutePointerDriverBindingStop (
1587 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1588 IN EFI_HANDLE ControllerHandle
,
1589 IN UINTN NumberOfChildren
,
1590 IN EFI_HANDLE
*ChildHandleBuffer
1594 EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
;
1596 if (NumberOfChildren
== 0) {
1601 // Close Absolute Pointer protocol on controller handle and virtual handle.
1603 Status
= ConSplitterStop (
1606 mConIn
.VirtualHandle
,
1607 &gEfiAbsolutePointerProtocolGuid
,
1608 &gEfiAbsolutePointerProtocolGuid
,
1609 (VOID
**) &AbsolutePointer
1611 if (EFI_ERROR (Status
)) {
1616 // Remove this device from Absolute Pointer device list.
1618 return ConSplitterAbsolutePointerDeleteDevice (&mConIn
, AbsolutePointer
);
1623 Stop Console Out ConSplitter on device handle by closing Console Out Devcice GUID.
1625 @param This Driver Binding protocol instance pointer.
1626 @param ControllerHandle Handle of device to stop driver on
1627 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1628 children is zero stop the entire bus driver.
1629 @param ChildHandleBuffer List of Child Handles to Stop.
1631 @retval EFI_SUCCESS This driver is removed ControllerHandle
1632 @retval other This driver was not removed from this device
1637 ConSplitterConOutDriverBindingStop (
1638 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1639 IN EFI_HANDLE ControllerHandle
,
1640 IN UINTN NumberOfChildren
,
1641 IN EFI_HANDLE
*ChildHandleBuffer
1645 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1647 if (NumberOfChildren
== 0) {
1652 // Close Absolute Pointer protocol on controller handle and virtual handle.
1654 Status
= ConSplitterStop (
1657 mConOut
.VirtualHandle
,
1658 &gEfiConsoleOutDeviceGuid
,
1659 &gEfiSimpleTextOutProtocolGuid
,
1662 if (EFI_ERROR (Status
)) {
1667 // Remove this device from Text Out device list.
1669 return ConSplitterTextOutDeleteDevice (&mConOut
, TextOut
);
1674 Stop Standard Error ConSplitter on ControllerHandle by closing Standard Error GUID.
1676 @param This Driver Binding protocol instance pointer.
1677 @param ControllerHandle Handle of device to stop driver on
1678 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1679 children is zero stop the entire bus driver.
1680 @param ChildHandleBuffer List of Child Handles to Stop.
1682 @retval EFI_SUCCESS This driver is removed ControllerHandle
1683 @retval other This driver was not removed from this device
1688 ConSplitterStdErrDriverBindingStop (
1689 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1690 IN EFI_HANDLE ControllerHandle
,
1691 IN UINTN NumberOfChildren
,
1692 IN EFI_HANDLE
*ChildHandleBuffer
1696 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1698 if (NumberOfChildren
== 0) {
1703 // Close Standard Error Device on controller handle and virtual handle.
1705 Status
= ConSplitterStop (
1708 mStdErr
.VirtualHandle
,
1709 &gEfiStandardErrorDeviceGuid
,
1710 &gEfiSimpleTextOutProtocolGuid
,
1713 if (EFI_ERROR (Status
)) {
1717 // Delete this console error out device's data structures.
1719 Status
= ConSplitterTextOutDeleteDevice (&mStdErr
, TextOut
);
1720 if (EFI_ERROR (Status
)) {
1724 if (mStdErr
.CurrentNumberOfConsoles
== 0) {
1725 mStdErr
.VirtualHandle
= NULL
;
1727 gST
->StandardErrorHandle
= NULL
;
1730 // Update the CRC32 in the EFI System Table header
1733 gBS
->CalculateCrc32 (
1734 (UINT8
*) &gST
->Hdr
,
1735 gST
->Hdr
.HeaderSize
,
1740 // Uninstall Simple Text Output protocol from StdErr Handle.
1742 gBS
->UninstallMultipleProtocolInterfaces (
1743 mStdErr
.VirtualHandle
,
1744 &gEfiSimpleTextOutProtocolGuid
,
1755 Take the passed in Buffer of size SizeOfCount and grow the buffer
1756 by MAX (CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT, MaxGrow) * SizeOfCount
1757 bytes. Copy the current data in Buffer to the new version of Buffer
1758 and free the old version of buffer.
1760 @param SizeOfCount Size of element in array.
1761 @param Count Current number of elements in array.
1762 @param Buffer Bigger version of passed in Buffer with all the
1765 @retval EFI_SUCCESS Buffer size has grown.
1766 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1770 ConSplitterGrowBuffer (
1771 IN UINTN SizeOfCount
,
1772 IN OUT UINTN
*Count
,
1773 IN OUT VOID
**Buffer
1779 // grow the buffer to new buffer size,
1780 // copy the old buffer's content to the new-size buffer,
1781 // then free the old buffer.
1783 *Count
+= CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT
;
1784 Ptr
= ReallocatePool (
1785 SizeOfCount
* ((*Count
) - CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT
),
1786 SizeOfCount
* (*Count
),
1790 return EFI_OUT_OF_RESOURCES
;
1798 Add Text Input Device in Consplitter Text Input list.
1800 @param Private Text In Splitter pointer.
1801 @param TextIn Simple Text Input protocol pointer.
1803 @retval EFI_SUCCESS Text Input Device added successfully.
1804 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1808 ConSplitterTextInAddDevice (
1809 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1810 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1816 // If the Text In List is full, enlarge it by calling ConSplitterGrowBuffer().
1818 if (Private
->CurrentNumberOfConsoles
>= Private
->TextInListCount
) {
1819 Status
= ConSplitterGrowBuffer (
1820 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
1821 &Private
->TextInListCount
,
1822 (VOID
**) &Private
->TextInList
1824 if (EFI_ERROR (Status
)) {
1825 return EFI_OUT_OF_RESOURCES
;
1829 // Add the new text-in device data structure into the Text In List.
1831 Private
->TextInList
[Private
->CurrentNumberOfConsoles
] = TextIn
;
1832 Private
->CurrentNumberOfConsoles
++;
1835 // Extra CheckEvent added to reduce the double CheckEvent().
1837 gBS
->CheckEvent (TextIn
->WaitForKey
);
1844 Remove Text Input Device from Consplitter Text Input list.
1846 @param Private Text In Splitter pointer.
1847 @param TextIn Simple Text protocol pointer.
1849 @retval EFI_SUCCESS Simple Text Device removed successfully.
1850 @retval EFI_NOT_FOUND No Simple Text Device found.
1854 ConSplitterTextInDeleteDevice (
1855 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1856 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1861 // Remove the specified text-in device data structure from the Text In List,
1862 // and rearrange the remaining data structures in the Text In List.
1864 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
1865 if (Private
->TextInList
[Index
] == TextIn
) {
1866 for (; Index
< Private
->CurrentNumberOfConsoles
- 1; Index
++) {
1867 Private
->TextInList
[Index
] = Private
->TextInList
[Index
+ 1];
1870 Private
->CurrentNumberOfConsoles
--;
1875 return EFI_NOT_FOUND
;
1879 Add Text Input Ex Device in Consplitter Text Input Ex list.
1881 @param Private Text In Splitter pointer.
1882 @param TextInEx Simple Text Input Ex Input protocol pointer.
1884 @retval EFI_SUCCESS Text Input Ex Device added successfully.
1885 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1889 ConSplitterTextInExAddDevice (
1890 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1891 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1897 // If the Text Input Ex List is full, enlarge it by calling ConSplitterGrowBuffer().
1899 if (Private
->CurrentNumberOfExConsoles
>= Private
->TextInExListCount
) {
1900 Status
= ConSplitterGrowBuffer (
1901 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
1902 &Private
->TextInExListCount
,
1903 (VOID
**) &Private
->TextInExList
1905 if (EFI_ERROR (Status
)) {
1906 return EFI_OUT_OF_RESOURCES
;
1910 // Add the new text-in device data structure into the Text Input Ex List.
1912 Private
->TextInExList
[Private
->CurrentNumberOfExConsoles
] = TextInEx
;
1913 Private
->CurrentNumberOfExConsoles
++;
1916 // Extra CheckEvent added to reduce the double CheckEvent().
1918 gBS
->CheckEvent (TextInEx
->WaitForKeyEx
);
1924 Remove Text Ex Device from Consplitter Text Input Ex list.
1926 @param Private Text In Splitter pointer.
1927 @param TextInEx Simple Text Ex protocol pointer.
1929 @retval EFI_SUCCESS Simple Text Input Ex Device removed successfully.
1930 @retval EFI_NOT_FOUND No Simple Text Input Ex Device found.
1934 ConSplitterTextInExDeleteDevice (
1935 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1936 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1941 // Remove the specified text-in device data structure from the Text Input Ex List,
1942 // and rearrange the remaining data structures in the Text In List.
1944 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
1945 if (Private
->TextInExList
[Index
] == TextInEx
) {
1946 for (; Index
< Private
->CurrentNumberOfExConsoles
- 1; Index
++) {
1947 Private
->TextInExList
[Index
] = Private
->TextInExList
[Index
+ 1];
1950 Private
->CurrentNumberOfExConsoles
--;
1955 return EFI_NOT_FOUND
;
1960 Add Simple Pointer Device in Consplitter Simple Pointer list.
1962 @param Private Text In Splitter pointer.
1963 @param SimplePointer Simple Pointer protocol pointer.
1965 @retval EFI_SUCCESS Simple Pointer Device added successfully.
1966 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1970 ConSplitterSimplePointerAddDevice (
1971 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1972 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
1978 // If the Simple Pointer List is full, enlarge it by calling ConSplitterGrowBuffer().
1980 if (Private
->CurrentNumberOfPointers
>= Private
->PointerListCount
) {
1981 Status
= ConSplitterGrowBuffer (
1982 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
1983 &Private
->PointerListCount
,
1984 (VOID
**) &Private
->PointerList
1986 if (EFI_ERROR (Status
)) {
1987 return EFI_OUT_OF_RESOURCES
;
1991 // Add the new text-in device data structure into the Simple Pointer List.
1993 Private
->PointerList
[Private
->CurrentNumberOfPointers
] = SimplePointer
;
1994 Private
->CurrentNumberOfPointers
++;
2001 Remove Simple Pointer Device from Consplitter Simple Pointer list.
2003 @param Private Text In Splitter pointer.
2004 @param SimplePointer Simple Pointer protocol pointer.
2006 @retval EFI_SUCCESS Simple Pointer Device removed successfully.
2007 @retval EFI_NOT_FOUND No Simple Pointer Device found.
2011 ConSplitterSimplePointerDeleteDevice (
2012 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2013 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
2018 // Remove the specified text-in device data structure from the Simple Pointer List,
2019 // and rearrange the remaining data structures in the Text In List.
2021 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
2022 if (Private
->PointerList
[Index
] == SimplePointer
) {
2023 for (; Index
< Private
->CurrentNumberOfPointers
- 1; Index
++) {
2024 Private
->PointerList
[Index
] = Private
->PointerList
[Index
+ 1];
2027 Private
->CurrentNumberOfPointers
--;
2032 return EFI_NOT_FOUND
;
2037 Add Absolute Pointer Device in Consplitter Absolute Pointer list.
2039 @param Private Text In Splitter pointer.
2040 @param AbsolutePointer Absolute Pointer protocol pointer.
2042 @retval EFI_SUCCESS Absolute Pointer Device added successfully.
2043 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2047 ConSplitterAbsolutePointerAddDevice (
2048 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2049 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2055 // If the Absolute Pointer List is full, enlarge it by calling ConSplitterGrowBuffer().
2057 if (Private
->CurrentNumberOfAbsolutePointers
>= Private
->AbsolutePointerListCount
) {
2058 Status
= ConSplitterGrowBuffer (
2059 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
2060 &Private
->AbsolutePointerListCount
,
2061 (VOID
**) &Private
->AbsolutePointerList
2063 if (EFI_ERROR (Status
)) {
2064 return EFI_OUT_OF_RESOURCES
;
2068 // Add the new text-in device data structure into the Absolute Pointer List.
2070 Private
->AbsolutePointerList
[Private
->CurrentNumberOfAbsolutePointers
] = AbsolutePointer
;
2071 Private
->CurrentNumberOfAbsolutePointers
++;
2078 Remove Absolute Pointer Device from Consplitter Absolute Pointer list.
2080 @param Private Text In Splitter pointer.
2081 @param AbsolutePointer Absolute Pointer protocol pointer.
2083 @retval EFI_SUCCESS Absolute Pointer Device removed successfully.
2084 @retval EFI_NOT_FOUND No Absolute Pointer Device found.
2088 ConSplitterAbsolutePointerDeleteDevice (
2089 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2090 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2095 // Remove the specified text-in device data structure from the Absolute Pointer List,
2096 // and rearrange the remaining data structures from the Absolute Pointer List.
2098 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
2099 if (Private
->AbsolutePointerList
[Index
] == AbsolutePointer
) {
2100 for (; Index
< Private
->CurrentNumberOfAbsolutePointers
- 1; Index
++) {
2101 Private
->AbsolutePointerList
[Index
] = Private
->AbsolutePointerList
[Index
+ 1];
2104 Private
->CurrentNumberOfAbsolutePointers
--;
2109 return EFI_NOT_FOUND
;
2113 Reallocate Text Out mode map.
2115 Allocate new buffer and copy original buffer into the new buffer.
2117 @param Private Consplitter Text Out pointer.
2119 @retval EFI_SUCCESS Buffer size has grown
2120 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2124 ConSplitterGrowMapTable (
2125 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2131 INT32
*TextOutModeMap
;
2132 INT32
*OldTextOutModeMap
;
2136 NewSize
= Private
->TextOutListCount
* sizeof (INT32
);
2137 OldTextOutModeMap
= Private
->TextOutModeMap
;
2138 TotalSize
= NewSize
* (Private
->TextOutQueryDataCount
);
2141 // Allocate new buffer for Text Out List.
2143 TextOutModeMap
= AllocatePool (TotalSize
);
2144 if (TextOutModeMap
== NULL
) {
2145 return EFI_OUT_OF_RESOURCES
;
2148 SetMem (TextOutModeMap
, TotalSize
, 0xFF);
2149 Private
->TextOutModeMap
= TextOutModeMap
;
2152 // If TextOutList has been enlarged, need to realloc the mode map table
2153 // The mode map table is regarded as a two dimension array.
2156 // 0 ---------> TextOutListCount ----> TextOutListCount
2157 // | -------------------------------------------
2164 // -------------------------------------------
2167 if (OldTextOutModeMap
!= NULL
) {
2169 Size
= Private
->CurrentNumberOfConsoles
* sizeof (INT32
);
2171 SrcAddress
= OldTextOutModeMap
;
2174 // Copy the old data to the new one
2176 while (Index
< Private
->TextOutMode
.MaxMode
) {
2177 CopyMem (TextOutModeMap
, SrcAddress
, Size
);
2178 TextOutModeMap
+= NewSize
;
2183 // Free the old buffer
2185 FreePool (OldTextOutModeMap
);
2193 Add new device's output mode to console splitter's mode list.
2195 @param Private Text Out Splitter pointer
2196 @param TextOut Simple Text Output protocol pointer.
2198 @retval EFI_SUCCESS Device added successfully.
2199 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2203 ConSplitterAddOutputMode (
2204 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2205 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2213 MaxMode
= TextOut
->Mode
->MaxMode
;
2214 Private
->TextOutMode
.MaxMode
= MaxMode
;
2217 // Grow the buffer if query data buffer is not large enough to
2218 // hold all the mode supported by the first console.
2220 while (MaxMode
> (INT32
) Private
->TextOutQueryDataCount
) {
2221 Status
= ConSplitterGrowBuffer (
2222 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
2223 &Private
->TextOutQueryDataCount
,
2224 (VOID
**) &Private
->TextOutQueryData
2226 if (EFI_ERROR (Status
)) {
2227 return EFI_OUT_OF_RESOURCES
;
2231 // Allocate buffer for the output mode map
2233 Status
= ConSplitterGrowMapTable (Private
);
2234 if (EFI_ERROR (Status
)) {
2235 return EFI_OUT_OF_RESOURCES
;
2238 // As the first textout device, directly add the mode in to QueryData
2239 // and at the same time record the mapping between QueryData and TextOut.
2243 while (Mode
< MaxMode
) {
2244 Status
= TextOut
->QueryMode (
2247 &Private
->TextOutQueryData
[Mode
].Columns
,
2248 &Private
->TextOutQueryData
[Mode
].Rows
2251 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData
2254 if ((EFI_ERROR(Status
)) && (Mode
== 1)) {
2255 Private
->TextOutQueryData
[Mode
].Columns
= 0;
2256 Private
->TextOutQueryData
[Mode
].Rows
= 0;
2258 Private
->TextOutModeMap
[Index
] = Mode
;
2260 Index
+= Private
->TextOutListCount
;
2267 Reconstruct TextOutModeMap to get intersection of modes.
2269 This routine reconstruct TextOutModeMap to get the intersection
2270 of modes for all console out devices. Because EFI/UEFI spec require
2271 mode 0 is 80x25, mode 1 is 80x50, this routine will not check the
2272 intersection for mode 0 and mode 1.
2274 @param TextOutModeMap Current text out mode map, begin with the mode 80x25
2275 @param NewlyAddedMap New text out mode map, begin with the mode 80x25
2276 @param MapStepSize Mode step size for one console device
2277 @param NewMapStepSize New Mode step size for one console device
2278 @param MaxMode IN: Current max text mode, OUT: Updated max text mode.
2279 @param CurrentMode IN: Current text mode, OUT: Updated current text mode.
2283 ConSplitterGetIntersection (
2284 IN INT32
*TextOutModeMap
,
2285 IN INT32
*NewlyAddedMap
,
2286 IN UINTN MapStepSize
,
2287 IN UINTN NewMapStepSize
,
2288 IN OUT INT32
*MaxMode
,
2289 IN OUT INT32
*CurrentMode
2293 INT32
*CurrentMapEntry
;
2294 INT32
*NextMapEntry
;
2296 INT32 CurrentMaxMode
;
2300 // According to EFI/UEFI spec, mode 0 and mode 1 have been reserved
2301 // for 80x25 and 80x50 in Simple Text Out protocol, so don't make intersection
2302 // for mode 0 and mode 1, mode number starts from 2.
2305 CurrentMapEntry
= &TextOutModeMap
[MapStepSize
* 2];
2306 NextMapEntry
= CurrentMapEntry
;
2307 NewMapEntry
= &NewlyAddedMap
[NewMapStepSize
* 2];
2309 CurrentMaxMode
= *MaxMode
;
2310 Mode
= *CurrentMode
;
2312 while (Index
< CurrentMaxMode
) {
2313 if (*NewMapEntry
== -1) {
2315 // This mode is not supported any more. Remove it. Special care
2316 // must be taken as this remove will also affect current mode;
2318 if (Index
== *CurrentMode
) {
2320 } else if (Index
< *CurrentMode
) {
2325 if (CurrentMapEntry
!= NextMapEntry
) {
2326 CopyMem (NextMapEntry
, CurrentMapEntry
, MapStepSize
* sizeof (INT32
));
2329 NextMapEntry
+= MapStepSize
;
2332 CurrentMapEntry
+= MapStepSize
;
2333 NewMapEntry
+= NewMapStepSize
;
2337 *CurrentMode
= Mode
;
2343 Sync the device's output mode to console splitter's mode list.
2345 @param Private Text Out Splitter pointer.
2346 @param TextOut Simple Text Output protocol pointer.
2350 ConSplitterSyncOutputMode (
2351 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2352 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2355 INT32 CurrentMaxMode
;
2358 INT32
*TextOutModeMap
;
2361 TEXT_OUT_SPLITTER_QUERY_DATA
*TextOutQueryData
;
2368 // Must make sure that current mode won't change even if mode number changes
2370 CurrentMaxMode
= Private
->TextOutMode
.MaxMode
;
2371 TextOutModeMap
= Private
->TextOutModeMap
;
2372 StepSize
= Private
->TextOutListCount
;
2373 TextOutQueryData
= Private
->TextOutQueryData
;
2376 // Query all the mode that the newly added TextOut supports
2379 MapTable
= TextOutModeMap
+ Private
->CurrentNumberOfConsoles
;
2380 while (Mode
< TextOut
->Mode
->MaxMode
) {
2381 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Columns
, &Rows
);
2383 if (EFI_ERROR(Status
)) {
2386 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData
2389 MapTable
[StepSize
] = Mode
;
2390 TextOutQueryData
[Mode
].Columns
= 0;
2391 TextOutQueryData
[Mode
].Rows
= 0;
2397 // Search the intersection map and QueryData database to see if they intersects
2400 while (Index
< CurrentMaxMode
) {
2401 QueryMode
= *(TextOutModeMap
+ Index
* StepSize
);
2402 if ((TextOutQueryData
[QueryMode
].Rows
== Rows
) && (TextOutQueryData
[QueryMode
].Columns
== Columns
)) {
2403 MapTable
[Index
* StepSize
] = Mode
;
2411 // Now search the TextOutModeMap table to find the intersection of supported
2412 // mode between ConSplitter and the newly added device.
2414 ConSplitterGetIntersection (
2419 &Private
->TextOutMode
.MaxMode
,
2420 &Private
->TextOutMode
.Mode
2428 Sync output device between ConOut and StdErr output.
2430 @retval EFI_SUCCESS Sync implemented successfully.
2431 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2435 ConSplitterGetIntersectionBetweenConOutAndStrErr (
2439 UINTN ConOutNumOfConsoles
;
2440 UINTN StdErrNumOfConsoles
;
2441 TEXT_OUT_AND_GOP_DATA
*ConOutTextOutList
;
2442 TEXT_OUT_AND_GOP_DATA
*StdErrTextOutList
;
2446 UINTN ConOutColumns
;
2448 UINTN StdErrColumns
;
2449 INT32 ConOutMaxMode
;
2450 INT32 StdErrMaxMode
;
2455 INT32
*ConOutModeMap
;
2456 INT32
*StdErrModeMap
;
2457 INT32
*ConOutMapTable
;
2458 INT32
*StdErrMapTable
;
2459 TEXT_OUT_SPLITTER_QUERY_DATA
*ConOutQueryData
;
2460 TEXT_OUT_SPLITTER_QUERY_DATA
*StdErrQueryData
;
2461 UINTN ConOutStepSize
;
2462 UINTN StdErrStepSize
;
2463 BOOLEAN FoundTheSameTextOut
;
2464 UINTN ConOutMapTableSize
;
2465 UINTN StdErrMapTableSize
;
2467 ConOutNumOfConsoles
= mConOut
.CurrentNumberOfConsoles
;
2468 StdErrNumOfConsoles
= mStdErr
.CurrentNumberOfConsoles
;
2469 ConOutTextOutList
= mConOut
.TextOutList
;
2470 StdErrTextOutList
= mStdErr
.TextOutList
;
2473 FoundTheSameTextOut
= FALSE
;
2474 while ((Indexi
< ConOutNumOfConsoles
) && (!FoundTheSameTextOut
)) {
2476 while (Indexj
< StdErrNumOfConsoles
) {
2477 if (ConOutTextOutList
->TextOut
== StdErrTextOutList
->TextOut
) {
2478 FoundTheSameTextOut
= TRUE
;
2483 StdErrTextOutList
++;
2487 ConOutTextOutList
++;
2490 if (!FoundTheSameTextOut
) {
2494 // Must make sure that current mode won't change even if mode number changes
2496 ConOutMaxMode
= mConOut
.TextOutMode
.MaxMode
;
2497 ConOutModeMap
= mConOut
.TextOutModeMap
;
2498 ConOutStepSize
= mConOut
.TextOutListCount
;
2499 ConOutQueryData
= mConOut
.TextOutQueryData
;
2501 StdErrMaxMode
= mStdErr
.TextOutMode
.MaxMode
;
2502 StdErrModeMap
= mStdErr
.TextOutModeMap
;
2503 StdErrStepSize
= mStdErr
.TextOutListCount
;
2504 StdErrQueryData
= mStdErr
.TextOutQueryData
;
2507 // Allocate the map table and set the map table's index to -1.
2509 ConOutMapTableSize
= ConOutMaxMode
* sizeof (INT32
);
2510 ConOutMapTable
= AllocateZeroPool (ConOutMapTableSize
);
2511 if (ConOutMapTable
== NULL
) {
2512 return EFI_OUT_OF_RESOURCES
;
2515 SetMem (ConOutMapTable
, ConOutMapTableSize
, 0xFF);
2517 StdErrMapTableSize
= StdErrMaxMode
* sizeof (INT32
);
2518 StdErrMapTable
= AllocateZeroPool (StdErrMapTableSize
);
2519 if (StdErrMapTable
== NULL
) {
2520 return EFI_OUT_OF_RESOURCES
;
2523 SetMem (StdErrMapTable
, StdErrMapTableSize
, 0xFF);
2526 // Find the intersection of the two set of modes. If they actually intersect, the
2527 // correponding entry in the map table is set to 1.
2530 while (Mode
< ConOutMaxMode
) {
2532 // Search the intersection map and QueryData database to see if they intersect
2535 ConOutMode
= *(ConOutModeMap
+ Mode
* ConOutStepSize
);
2536 ConOutRows
= ConOutQueryData
[ConOutMode
].Rows
;
2537 ConOutColumns
= ConOutQueryData
[ConOutMode
].Columns
;
2538 while (Index
< StdErrMaxMode
) {
2539 StdErrMode
= *(StdErrModeMap
+ Index
* StdErrStepSize
);
2540 StdErrRows
= StdErrQueryData
[StdErrMode
].Rows
;
2541 StdErrColumns
= StdErrQueryData
[StdErrMode
].Columns
;
2542 if ((StdErrRows
== ConOutRows
) && (StdErrColumns
== ConOutColumns
)) {
2543 ConOutMapTable
[Mode
] = 1;
2544 StdErrMapTable
[Index
] = 1;
2554 // Now search the TextOutModeMap table to find the intersection of supported
2555 // mode between ConSplitter and the newly added device.
2557 ConSplitterGetIntersection (
2560 mConOut
.TextOutListCount
,
2562 &(mConOut
.TextOutMode
.MaxMode
),
2563 &(mConOut
.TextOutMode
.Mode
)
2566 if (mConOut
.TextOutMode
.Mode
< 0) {
2567 mConOut
.TextOut
.SetMode (&(mConOut
.TextOut
), 0);
2570 ConSplitterGetIntersection (
2573 mStdErr
.TextOutListCount
,
2575 &(mStdErr
.TextOutMode
.MaxMode
),
2576 &(mStdErr
.TextOutMode
.Mode
)
2579 if (mStdErr
.TextOutMode
.Mode
< 0) {
2580 mStdErr
.TextOut
.SetMode (&(mStdErr
.TextOut
), 0);
2583 FreePool (ConOutMapTable
);
2584 FreePool (StdErrMapTable
);
2591 Add Grahpics Output modes into Consplitter Text Out list.
2593 @param Private Text Out Splitter pointer.
2594 @param GraphicsOutput Graphics Output protocol pointer.
2595 @param UgaDraw UGA Draw protocol pointer.
2597 @retval EFI_SUCCESS Output mode added successfully.
2598 @retval other Failed to add output mode.
2602 ConSplitterAddGraphicsOutputMode (
2603 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2604 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2605 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2611 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
;
2613 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
2614 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*CurrentGraphicsOutputMode
;
2615 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*ModeBuffer
;
2616 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*MatchedMode
;
2619 BOOLEAN AlreadyExist
;
2620 UINT32 UgaHorizontalResolution
;
2621 UINT32 UgaVerticalResolution
;
2622 UINT32 UgaColorDepth
;
2623 UINT32 UgaRefreshRate
;
2625 ASSERT (GraphicsOutput
!= NULL
|| UgaDraw
!= NULL
);
2627 CurrentGraphicsOutputMode
= Private
->GraphicsOutput
.Mode
;
2631 Status
= EFI_SUCCESS
;
2633 if (Private
->CurrentNumberOfUgaDraw
!= 0) {
2635 // If any UGA device has already been added, then there is no need to
2636 // calculate intersection of display mode of different GOP/UGA device,
2637 // since only one display mode will be exported (i.e. user-defined mode)
2642 if (GraphicsOutput
!= NULL
) {
2643 if (Private
->CurrentNumberOfGraphicsOutput
== 0) {
2645 // This is the first Graphics Output device added
2647 CurrentGraphicsOutputMode
->MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
2648 CurrentGraphicsOutputMode
->Mode
= GraphicsOutput
->Mode
->Mode
;
2649 CopyMem (CurrentGraphicsOutputMode
->Info
, GraphicsOutput
->Mode
->Info
, GraphicsOutput
->Mode
->SizeOfInfo
);
2650 CurrentGraphicsOutputMode
->SizeOfInfo
= GraphicsOutput
->Mode
->SizeOfInfo
;
2651 CurrentGraphicsOutputMode
->FrameBufferBase
= GraphicsOutput
->Mode
->FrameBufferBase
;
2652 CurrentGraphicsOutputMode
->FrameBufferSize
= GraphicsOutput
->Mode
->FrameBufferSize
;
2655 // Allocate resource for the private mode buffer
2657 ModeBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
) * GraphicsOutput
->Mode
->MaxMode
);
2658 if (ModeBuffer
== NULL
) {
2659 return EFI_OUT_OF_RESOURCES
;
2661 FreePool (Private
->GraphicsOutputModeBuffer
);
2662 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2665 // Store all supported display modes to the private mode buffer
2668 for (Index
= 0; Index
< GraphicsOutput
->Mode
->MaxMode
; Index
++) {
2670 // The Info buffer would be allocated by callee
2672 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) Index
, &SizeOfInfo
, &Info
);
2673 if (EFI_ERROR (Status
)) {
2676 ASSERT ( SizeOfInfo
<= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2677 CopyMem (Mode
, Info
, SizeOfInfo
);
2683 // Check intersection of display mode
2685 ModeBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
) * CurrentGraphicsOutputMode
->MaxMode
);
2686 if (ModeBuffer
== NULL
) {
2687 return EFI_OUT_OF_RESOURCES
;
2690 MatchedMode
= ModeBuffer
;
2691 Mode
= &Private
->GraphicsOutputModeBuffer
[0];
2692 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2695 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
2697 // The Info buffer would be allocated by callee
2699 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
2700 if (EFI_ERROR (Status
)) {
2703 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2704 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2706 // If GOP device supports one mode in current mode buffer,
2707 // it will be added into matched mode buffer
2717 AlreadyExist
= FALSE
;
2720 // Check if GOP mode has been in the mode buffer, ModeBuffer = MatchedMode at begin.
2722 for (Info
= ModeBuffer
; Info
< MatchedMode
; Info
++) {
2723 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2724 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2725 AlreadyExist
= TRUE
;
2730 if (!AlreadyExist
) {
2731 CopyMem (MatchedMode
, Mode
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2734 // Physical frame buffer is no longer available, change PixelFormat to PixelBltOnly
2736 MatchedMode
->Version
= 0;
2737 MatchedMode
->PixelFormat
= PixelBltOnly
;
2738 ZeroMem (&MatchedMode
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2748 // Drop the old mode buffer, assign it to a new one
2750 FreePool (Private
->GraphicsOutputModeBuffer
);
2751 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2754 // Physical frame buffer is no longer available when there are more than one physical GOP devices
2756 CurrentGraphicsOutputMode
->MaxMode
= (UINT32
) (((UINTN
) MatchedMode
- (UINTN
) ModeBuffer
) / sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2757 CurrentGraphicsOutputMode
->Info
->PixelFormat
= PixelBltOnly
;
2758 ZeroMem (&CurrentGraphicsOutputMode
->Info
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2759 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2760 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2761 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2765 // Graphics console driver can ensure the same mode for all GOP devices
2767 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2768 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2769 if ((Mode
->HorizontalResolution
== GraphicsOutput
->Mode
->Info
->HorizontalResolution
) &&
2770 (Mode
->VerticalResolution
== GraphicsOutput
->Mode
->Info
->VerticalResolution
)) {
2771 CurrentIndex
= Index
;
2775 if (Index
>= CurrentGraphicsOutputMode
->MaxMode
) {
2777 // if user defined mode is not found, set to default mode 800x600
2779 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2780 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2781 if ((Mode
->HorizontalResolution
== 800) && (Mode
->VerticalResolution
== 600)) {
2782 CurrentIndex
= Index
;
2787 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2789 // Graphics console driver can ensure the same mode for all GOP devices
2790 // so we can get the current mode from this video device
2794 &UgaHorizontalResolution
,
2795 &UgaVerticalResolution
,
2800 CurrentGraphicsOutputMode
->MaxMode
= 1;
2801 Info
= CurrentGraphicsOutputMode
->Info
;
2803 Info
->HorizontalResolution
= UgaHorizontalResolution
;
2804 Info
->VerticalResolution
= UgaVerticalResolution
;
2805 Info
->PixelFormat
= PixelBltOnly
;
2806 Info
->PixelsPerScanLine
= UgaHorizontalResolution
;
2807 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2808 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2809 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2812 // Update the private mode buffer
2814 CopyMem (&Private
->GraphicsOutputModeBuffer
[0], Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2817 // Only mode 0 is available to be set
2824 if (GraphicsOutput
!= NULL
) {
2825 Private
->CurrentNumberOfGraphicsOutput
++;
2827 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2828 Private
->CurrentNumberOfUgaDraw
++;
2832 // Force GraphicsOutput mode to be set,
2835 Mode
= &Private
->GraphicsOutputModeBuffer
[CurrentIndex
];
2836 if ((GraphicsOutput
!= NULL
) &&
2837 (Mode
->HorizontalResolution
== CurrentGraphicsOutputMode
->Info
->HorizontalResolution
) &&
2838 (Mode
->VerticalResolution
== CurrentGraphicsOutputMode
->Info
->VerticalResolution
)) {
2839 CurrentGraphicsOutputMode
->Mode
= (UINT32
) CurrentIndex
;
2840 if ((Mode
->HorizontalResolution
!= GraphicsOutput
->Mode
->Info
->HorizontalResolution
) ||
2841 (Mode
->VerticalResolution
!= GraphicsOutput
->Mode
->Info
->VerticalResolution
)) {
2843 // If all existing video device has been set to common mode, only set new GOP device to
2846 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
2847 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
2848 if (EFI_ERROR (Status
)) {
2851 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) && (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2857 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
2861 // Current mode number may need update now, so set it to an invalid mode number
2863 CurrentGraphicsOutputMode
->Mode
= 0xffff;
2865 // Graphics console can ensure all GOP devices have the same mode which can be taken as current mode.
2867 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, (UINT32
) CurrentIndex
);
2868 if (EFI_ERROR(Status
)) {
2870 // If user defined mode is not valid for display device, set to the default mode 800x600.
2872 (Private
->GraphicsOutputModeBuffer
[0]).HorizontalResolution
= 800;
2873 (Private
->GraphicsOutputModeBuffer
[0]).VerticalResolution
= 600;
2874 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, 0);
2882 Set the current console out mode.
2884 This routine will get the current console mode information (column, row)
2885 from ConsoleOutMode variable and set it; if the variable does not exist,
2886 set to user defined console mode.
2888 @param Private Consplitter Text Out pointer.
2892 ConsplitterSetConsoleOutMode (
2893 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2903 CONSOLE_OUT_MODE ModeInfo
;
2904 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
2908 TextOut
= &Private
->TextOut
;
2909 MaxMode
= (UINTN
) (TextOut
->Mode
->MaxMode
);
2911 ModeInfo
.Column
= PcdGet32 (PcdConOutColumn
);
2912 ModeInfo
.Row
= PcdGet32 (PcdConOutRow
);
2915 // To find the prefer mode and basic mode from Text Out mode list
2917 for (Mode
= 0; Mode
< MaxMode
; Mode
++) {
2918 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Col
, &Row
);
2919 if (!EFI_ERROR(Status
)) {
2920 if (Col
== ModeInfo
.Column
&& Row
== ModeInfo
.Row
) {
2923 if (Col
== 80 && Row
== 25) {
2930 // Set prefer mode to Text Out devices.
2932 Status
= TextOut
->SetMode (TextOut
, PreferMode
);
2933 if (EFI_ERROR(Status
)) {
2935 // if current mode setting is failed, default 80x25 mode will be set.
2937 Status
= TextOut
->SetMode (TextOut
, BaseMode
);
2938 ASSERT(!EFI_ERROR(Status
));
2940 PcdSet32 (PcdConOutColumn
, 80);
2941 PcdSet32 (PcdConOutRow
, 25);
2949 Add Text Output Device in Consplitter Text Output list.
2951 @param Private Text Out Splitter pointer.
2952 @param TextOut Simple Text Output protocol pointer.
2953 @param GraphicsOutput Graphics Output protocol pointer.
2954 @param UgaDraw UGA Draw protocol pointer.
2956 @retval EFI_SUCCESS Text Output Device added successfully.
2957 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2961 ConSplitterTextOutAddDevice (
2962 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2963 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
,
2964 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2965 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2969 UINTN CurrentNumOfConsoles
;
2971 UINT32 UgaHorizontalResolution
;
2972 UINT32 UgaVerticalResolution
;
2973 UINT32 UgaColorDepth
;
2974 UINT32 UgaRefreshRate
;
2975 TEXT_OUT_AND_GOP_DATA
*TextAndGop
;
2977 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
2978 EFI_STATUS DeviceStatus
;
2980 Status
= EFI_SUCCESS
;
2981 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
2984 // If the Text Out List is full, enlarge it by calling ConSplitterGrowBuffer().
2986 while (CurrentNumOfConsoles
>= Private
->TextOutListCount
) {
2987 Status
= ConSplitterGrowBuffer (
2988 sizeof (TEXT_OUT_AND_GOP_DATA
),
2989 &Private
->TextOutListCount
,
2990 (VOID
**) &Private
->TextOutList
2992 if (EFI_ERROR (Status
)) {
2993 return EFI_OUT_OF_RESOURCES
;
2996 // Also need to reallocate the TextOutModeMap table
2998 Status
= ConSplitterGrowMapTable (Private
);
2999 if (EFI_ERROR (Status
)) {
3000 return EFI_OUT_OF_RESOURCES
;
3004 TextAndGop
= &Private
->TextOutList
[CurrentNumOfConsoles
];
3006 TextAndGop
->TextOut
= TextOut
;
3007 TextAndGop
->GraphicsOutput
= GraphicsOutput
;
3008 TextAndGop
->UgaDraw
= UgaDraw
;
3010 if (CurrentNumOfConsoles
== 0) {
3012 // Add the first device's output mode to console splitter's mode list
3014 Status
= ConSplitterAddOutputMode (Private
, TextOut
);
3016 ConSplitterSyncOutputMode (Private
, TextOut
);
3019 Private
->CurrentNumberOfConsoles
++;
3022 // Scan both TextOutList, for the intersection TextOut device
3023 // maybe both ConOut and StdErr incorporate the same Text Out
3024 // device in them, thus the output of both should be synced.
3026 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3028 MaxMode
= Private
->TextOutMode
.MaxMode
;
3029 ASSERT (MaxMode
>= 1);
3031 DeviceStatus
= EFI_DEVICE_ERROR
;
3032 if (FeaturePcdGet (PcdConOutGopSupport
)) {
3034 // If GOP is produced by Consplitter, this device display mode will be added into Graphics Ouput modes.
3036 if ((GraphicsOutput
!= NULL
) || (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
))) {
3037 DeviceStatus
= ConSplitterAddGraphicsOutputMode (Private
, GraphicsOutput
, UgaDraw
);
3041 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
3043 // If UGA is produced by Consplitter
3045 if (GraphicsOutput
!= NULL
) {
3046 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, GraphicsOutput
->Mode
->Mode
, &SizeOfInfo
, &Info
);
3047 if (EFI_ERROR (Status
)) {
3050 ASSERT ( SizeOfInfo
<= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
3052 UgaHorizontalResolution
= Info
->HorizontalResolution
;
3053 UgaVerticalResolution
= Info
->VerticalResolution
;
3057 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3058 Status
= UgaDraw
->GetMode (
3060 &UgaHorizontalResolution
,
3061 &UgaVerticalResolution
,
3065 if (!EFI_ERROR (Status
) && EFI_ERROR (DeviceStatus
)) {
3067 // if GetMode is successfully and UGA device hasn't been set, set it
3069 Status
= ConSplitterUgaDrawSetMode (
3071 UgaHorizontalResolution
,
3072 UgaVerticalResolution
,
3078 // If GetMode/SetMode is failed, set to 800x600 mode
3080 if(EFI_ERROR (Status
)) {
3081 Status
= ConSplitterUgaDrawSetMode (
3093 // After adding new console device, all existing console devices should be
3094 // synced to the current shared mode.
3096 ConsplitterSetConsoleOutMode (Private
);
3103 Remove Text Out Device in Consplitter Text Out list.
3105 @param Private Text Out Splitter pointer.
3106 @param TextOut Simple Text Output Pointer protocol pointer.
3108 @retval EFI_SUCCESS Text Out Device removed successfully.
3109 @retval EFI_NOT_FOUND No Text Out Device found.
3113 ConSplitterTextOutDeleteDevice (
3114 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
3115 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
3119 UINTN CurrentNumOfConsoles
;
3120 TEXT_OUT_AND_GOP_DATA
*TextOutList
;
3124 // Remove the specified text-out device data structure from the Text out List,
3125 // and rearrange the remaining data structures in the Text out List.
3127 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
3128 Index
= (INT32
) CurrentNumOfConsoles
- 1;
3129 TextOutList
= Private
->TextOutList
;
3130 while (Index
>= 0) {
3131 if (TextOutList
->TextOut
== TextOut
) {
3132 if (TextOutList
->UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3133 Private
->CurrentNumberOfUgaDraw
--;
3135 if (TextOutList
->GraphicsOutput
!= NULL
) {
3136 Private
->CurrentNumberOfGraphicsOutput
--;
3138 CopyMem (TextOutList
, TextOutList
+ 1, sizeof (TEXT_OUT_AND_GOP_DATA
) * Index
);
3139 CurrentNumOfConsoles
--;
3147 // The specified TextOut is not managed by the ConSplitter driver
3150 return EFI_NOT_FOUND
;
3153 if (CurrentNumOfConsoles
== 0) {
3155 // If the number of consoles is zero, reset all parameters
3157 Private
->CurrentNumberOfConsoles
= 0;
3158 Private
->TextOutMode
.MaxMode
= 1;
3159 Private
->TextOutQueryData
[0].Columns
= 80;
3160 Private
->TextOutQueryData
[0].Rows
= 25;
3161 TextOutSetMode (Private
, 0);
3166 // Max Mode is realy an intersection of the QueryMode command to all
3167 // devices. So we must copy the QueryMode of the first device to
3171 Private
->TextOutQueryData
,
3172 Private
->TextOutQueryDataCount
* sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
)
3175 FreePool (Private
->TextOutModeMap
);
3176 Private
->TextOutModeMap
= NULL
;
3177 TextOutList
= Private
->TextOutList
;
3180 // Add the first TextOut to the QueryData array and ModeMap table
3182 Status
= ConSplitterAddOutputMode (Private
, TextOutList
->TextOut
);
3185 // Now add one by one
3188 Private
->CurrentNumberOfConsoles
= 1;
3190 while ((UINTN
) Index
< CurrentNumOfConsoles
) {
3191 ConSplitterSyncOutputMode (Private
, TextOutList
->TextOut
);
3193 Private
->CurrentNumberOfConsoles
++;
3197 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3204 Reset the input device and optionaly run diagnostics
3206 @param This Protocol instance pointer.
3207 @param ExtendedVerification Driver may perform diagnostics on reset.
3209 @retval EFI_SUCCESS The device was reset.
3210 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3216 ConSplitterTextInReset (
3217 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3218 IN BOOLEAN ExtendedVerification
3222 EFI_STATUS ReturnStatus
;
3223 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3226 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3228 Private
->KeyEventSignalState
= FALSE
;
3231 // return the worst status met
3233 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3234 Status
= Private
->TextInList
[Index
]->Reset (
3235 Private
->TextInList
[Index
],
3236 ExtendedVerification
3238 if (EFI_ERROR (Status
)) {
3239 ReturnStatus
= Status
;
3243 return ReturnStatus
;
3248 Reads the next keystroke from the input device. The WaitForKey Event can
3249 be used to test for existance of a keystroke via WaitForEvent () call.
3251 @param Private Protocol instance pointer.
3252 @param Key Driver may perform diagnostics on reset.
3254 @retval EFI_SUCCESS The keystroke information was returned.
3255 @retval EFI_NOT_READY There was no keystroke data availiable.
3256 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3262 ConSplitterTextInPrivateReadKeyStroke (
3263 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3264 OUT EFI_INPUT_KEY
*Key
3269 EFI_INPUT_KEY CurrentKey
;
3271 Key
->UnicodeChar
= 0;
3272 Key
->ScanCode
= SCAN_NULL
;
3275 // if no physical console input device exists, return EFI_NOT_READY;
3276 // if any physical console input device has key input,
3277 // return the key and EFI_SUCCESS.
3279 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3280 Status
= Private
->TextInList
[Index
]->ReadKeyStroke (
3281 Private
->TextInList
[Index
],
3284 if (!EFI_ERROR (Status
)) {
3290 return EFI_NOT_READY
;
3295 Reads the next keystroke from the input device. The WaitForKey Event can
3296 be used to test for existance of a keystroke via WaitForEvent () call.
3298 @param This Protocol instance pointer.
3299 @param Key Driver may perform diagnostics on reset.
3301 @retval EFI_SUCCESS The keystroke information was returned.
3302 @retval EFI_NOT_READY There was no keystroke data availiable.
3303 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3309 ConSplitterTextInReadKeyStroke (
3310 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3311 OUT EFI_INPUT_KEY
*Key
3314 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3316 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3318 Private
->KeyEventSignalState
= FALSE
;
3320 return ConSplitterTextInPrivateReadKeyStroke (Private
, Key
);
3325 This event aggregates all the events of the ConIn devices in the spliter.
3327 If any events of physical ConIn devices are signaled, signal the ConIn
3328 spliter event. This will cause the calling code to call
3329 ConSplitterTextInReadKeyStroke ().
3331 @param Event The Event assoicated with callback.
3332 @param Context Context registered when Event was created.
3337 ConSplitterTextInWaitForKey (
3343 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3346 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
3348 if (Private
->KeyEventSignalState
) {
3350 // If KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
3352 gBS
->SignalEvent (Event
);
3357 // If any physical console input device has key input, signal the event.
3359 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3360 Status
= gBS
->CheckEvent (Private
->TextInList
[Index
]->WaitForKey
);
3361 if (!EFI_ERROR (Status
)) {
3362 gBS
->SignalEvent (Event
);
3363 Private
->KeyEventSignalState
= TRUE
;
3371 Test if the key has been registered on input device.
3373 @param RegsiteredData A pointer to a buffer that is filled in with the
3374 keystroke state data for the key that was
3376 @param InputData A pointer to a buffer that is filled in with the
3377 keystroke state data for the key that was
3380 @retval TRUE Key be pressed matches a registered key.
3381 @retval FLASE Match failed.
3386 IN EFI_KEY_DATA
*RegsiteredData
,
3387 IN EFI_KEY_DATA
*InputData
3390 ASSERT (RegsiteredData
!= NULL
&& InputData
!= NULL
);
3392 if ((RegsiteredData
->Key
.ScanCode
!= InputData
->Key
.ScanCode
) ||
3393 (RegsiteredData
->Key
.UnicodeChar
!= InputData
->Key
.UnicodeChar
)) {
3398 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
3400 if (RegsiteredData
->KeyState
.KeyShiftState
!= 0 &&
3401 RegsiteredData
->KeyState
.KeyShiftState
!= InputData
->KeyState
.KeyShiftState
) {
3404 if (RegsiteredData
->KeyState
.KeyToggleState
!= 0 &&
3405 RegsiteredData
->KeyState
.KeyToggleState
!= InputData
->KeyState
.KeyToggleState
) {
3415 Reset the input device and optionaly run diagnostics
3417 @param This Protocol instance pointer.
3418 @param ExtendedVerification Driver may perform diagnostics on reset.
3420 @retval EFI_SUCCESS The device was reset.
3421 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3427 ConSplitterTextInResetEx (
3428 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3429 IN BOOLEAN ExtendedVerification
3433 EFI_STATUS ReturnStatus
;
3434 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3437 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3439 Private
->KeyEventSignalState
= FALSE
;
3442 // return the worst status met
3444 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3445 Status
= Private
->TextInExList
[Index
]->Reset (
3446 Private
->TextInExList
[Index
],
3447 ExtendedVerification
3449 if (EFI_ERROR (Status
)) {
3450 ReturnStatus
= Status
;
3454 return ReturnStatus
;
3460 Reads the next keystroke from the input device. The WaitForKey Event can
3461 be used to test for existance of a keystroke via WaitForEvent () call.
3463 @param This Protocol instance pointer.
3464 @param KeyData A pointer to a buffer that is filled in with the
3465 keystroke state data for the key that was
3468 @retval EFI_SUCCESS The keystroke information was returned.
3469 @retval EFI_NOT_READY There was no keystroke data availiable.
3470 @retval EFI_DEVICE_ERROR The keystroke information was not returned due
3472 @retval EFI_INVALID_PARAMETER KeyData is NULL.
3477 ConSplitterTextInReadKeyStrokeEx (
3478 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3479 OUT EFI_KEY_DATA
*KeyData
3482 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3485 EFI_KEY_DATA CurrentKeyData
;
3488 if (KeyData
== NULL
) {
3489 return EFI_INVALID_PARAMETER
;
3492 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3494 Private
->KeyEventSignalState
= FALSE
;
3496 KeyData
->Key
.UnicodeChar
= 0;
3497 KeyData
->Key
.ScanCode
= SCAN_NULL
;
3500 // if no physical console input device exists, return EFI_NOT_READY;
3501 // if any physical console input device has key input,
3502 // return the key and EFI_SUCCESS.
3504 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3505 Status
= Private
->TextInExList
[Index
]->ReadKeyStrokeEx (
3506 Private
->TextInExList
[Index
],
3509 if (!EFI_ERROR (Status
)) {
3510 CopyMem (KeyData
, &CurrentKeyData
, sizeof (CurrentKeyData
));
3515 return EFI_NOT_READY
;
3520 Set certain state for the input device.
3522 @param This Protocol instance pointer.
3523 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
3524 state for the input device.
3526 @retval EFI_SUCCESS The device state was set successfully.
3527 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
3528 could not have the setting adjusted.
3529 @retval EFI_UNSUPPORTED The device does not have the ability to set its
3531 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
3536 ConSplitterTextInSetState (
3537 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3538 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
3541 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3545 if (KeyToggleState
== NULL
) {
3546 return EFI_INVALID_PARAMETER
;
3549 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3552 // if no physical console input device exists, return EFI_SUCCESS;
3553 // otherwise return the status of setting state of physical console input device
3555 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3556 Status
= Private
->TextInExList
[Index
]->SetState (
3557 Private
->TextInExList
[Index
],
3560 if (EFI_ERROR (Status
)) {
3571 Register a notification function for a particular keystroke for the input device.
3573 @param This Protocol instance pointer.
3574 @param KeyData A pointer to a buffer that is filled in with the
3575 keystroke information data for the key that was
3577 @param KeyNotificationFunction Points to the function to be called when the key
3578 sequence is typed specified by KeyData.
3579 @param NotifyHandle Points to the unique handle assigned to the
3580 registered notification.
3582 @retval EFI_SUCCESS The notification function was registered
3584 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data
3586 @retval EFI_INVALID_PARAMETER KeyData or KeyNotificationFunction or NotifyHandle is NULL.
3591 ConSplitterTextInRegisterKeyNotify (
3592 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3593 IN EFI_KEY_DATA
*KeyData
,
3594 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction
,
3595 OUT EFI_HANDLE
*NotifyHandle
3598 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3601 TEXT_IN_EX_SPLITTER_NOTIFY
*NewNotify
;
3603 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3606 if (KeyData
== NULL
|| NotifyHandle
== NULL
|| KeyNotificationFunction
== NULL
) {
3607 return EFI_INVALID_PARAMETER
;
3610 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3613 // If no physical console input device exists,
3614 // return EFI_SUCCESS directly.
3616 if (Private
->CurrentNumberOfExConsoles
<= 0) {
3621 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
3623 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3624 CurrentNotify
= TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link
);
3625 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
3626 if (CurrentNotify
->KeyNotificationFn
== KeyNotificationFunction
) {
3627 *NotifyHandle
= CurrentNotify
->NotifyHandle
;
3634 // Allocate resource to save the notification function
3636 NewNotify
= (TEXT_IN_EX_SPLITTER_NOTIFY
*) AllocateZeroPool (sizeof (TEXT_IN_EX_SPLITTER_NOTIFY
));
3637 if (NewNotify
== NULL
) {
3638 return EFI_OUT_OF_RESOURCES
;
3640 NewNotify
->NotifyHandleList
= (EFI_HANDLE
*) AllocateZeroPool (sizeof (EFI_HANDLE
) * Private
->CurrentNumberOfExConsoles
);
3641 if (NewNotify
->NotifyHandleList
== NULL
) {
3642 gBS
->FreePool (NewNotify
);
3643 return EFI_OUT_OF_RESOURCES
;
3645 NewNotify
->Signature
= TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
;
3646 NewNotify
->KeyNotificationFn
= KeyNotificationFunction
;
3647 NewNotify
->NotifyHandle
= (EFI_HANDLE
) NewNotify
;
3648 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (EFI_KEY_DATA
));
3651 // Return the wrong status of registering key notify of
3652 // physical console input device if meet problems
3654 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3655 Status
= Private
->TextInExList
[Index
]->RegisterKeyNotify (
3656 Private
->TextInExList
[Index
],
3658 KeyNotificationFunction
,
3659 &NewNotify
->NotifyHandleList
[Index
]
3661 if (EFI_ERROR (Status
)) {
3662 gBS
->FreePool (NewNotify
->NotifyHandleList
);
3663 gBS
->FreePool (NewNotify
);
3668 InsertTailList (&mConIn
.NotifyList
, &NewNotify
->NotifyEntry
);
3670 *NotifyHandle
= NewNotify
->NotifyHandle
;
3678 Remove a registered notification function from a particular keystroke.
3680 @param This Protocol instance pointer.
3681 @param NotificationHandle The handle of the notification function being
3684 @retval EFI_SUCCESS The notification function was unregistered
3686 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
3691 ConSplitterTextInUnregisterKeyNotify (
3692 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3693 IN EFI_HANDLE NotificationHandle
3696 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3699 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3702 if (NotificationHandle
== NULL
) {
3703 return EFI_INVALID_PARAMETER
;
3706 if (((TEXT_IN_EX_SPLITTER_NOTIFY
*) NotificationHandle
)->Signature
!= TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
) {
3707 return EFI_INVALID_PARAMETER
;
3710 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3713 // if no physical console input device exists,
3714 // return EFI_SUCCESS directly.
3716 if (Private
->CurrentNumberOfExConsoles
<= 0) {
3720 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3721 CurrentNotify
= TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link
);
3722 if (CurrentNotify
->NotifyHandle
== NotificationHandle
) {
3723 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3724 Status
= Private
->TextInExList
[Index
]->UnregisterKeyNotify (
3725 Private
->TextInExList
[Index
],
3726 CurrentNotify
->NotifyHandleList
[Index
]
3728 if (EFI_ERROR (Status
)) {
3732 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
3734 gBS
->FreePool (CurrentNotify
->NotifyHandleList
);
3735 gBS
->FreePool (CurrentNotify
);
3741 // NotificationHandle is not found in database
3743 return EFI_INVALID_PARAMETER
;
3748 Reset the input device and optionaly run diagnostics
3750 @param This Protocol instance pointer.
3751 @param ExtendedVerification Driver may perform diagnostics on reset.
3753 @retval EFI_SUCCESS The device was reset.
3754 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3760 ConSplitterSimplePointerReset (
3761 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
3762 IN BOOLEAN ExtendedVerification
3766 EFI_STATUS ReturnStatus
;
3767 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3770 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
3772 Private
->InputEventSignalState
= FALSE
;
3774 if (Private
->CurrentNumberOfPointers
== 0) {
3778 // return the worst status met
3780 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3781 Status
= Private
->PointerList
[Index
]->Reset (
3782 Private
->PointerList
[Index
],
3783 ExtendedVerification
3785 if (EFI_ERROR (Status
)) {
3786 ReturnStatus
= Status
;
3790 return ReturnStatus
;
3795 Reads the next keystroke from the input device. The WaitForKey Event can
3796 be used to test for existance of a keystroke via WaitForEvent () call.
3798 @param Private Protocol instance pointer.
3799 @param State The state information of simple pointer device.
3801 @retval EFI_SUCCESS The keystroke information was returned.
3802 @retval EFI_NOT_READY There was no keystroke data availiable.
3803 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3809 ConSplitterSimplePointerPrivateGetState (
3810 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3811 IN OUT EFI_SIMPLE_POINTER_STATE
*State
3815 EFI_STATUS ReturnStatus
;
3817 EFI_SIMPLE_POINTER_STATE CurrentState
;
3819 State
->RelativeMovementX
= 0;
3820 State
->RelativeMovementY
= 0;
3821 State
->RelativeMovementZ
= 0;
3822 State
->LeftButton
= FALSE
;
3823 State
->RightButton
= FALSE
;
3826 // if no physical console input device exists, return EFI_NOT_READY;
3827 // if any physical console input device has key input,
3828 // return the key and EFI_SUCCESS.
3830 ReturnStatus
= EFI_NOT_READY
;
3831 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3833 Status
= Private
->PointerList
[Index
]->GetState (
3834 Private
->PointerList
[Index
],
3837 if (!EFI_ERROR (Status
)) {
3838 if (ReturnStatus
== EFI_NOT_READY
) {
3839 ReturnStatus
= EFI_SUCCESS
;
3842 if (CurrentState
.LeftButton
) {
3843 State
->LeftButton
= TRUE
;
3846 if (CurrentState
.RightButton
) {
3847 State
->RightButton
= TRUE
;
3850 if (CurrentState
.RelativeMovementX
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionX
!= 0) {
3851 State
->RelativeMovementX
+= (CurrentState
.RelativeMovementX
* (INT32
) Private
->SimplePointerMode
.ResolutionX
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionX
;
3854 if (CurrentState
.RelativeMovementY
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionY
!= 0) {
3855 State
->RelativeMovementY
+= (CurrentState
.RelativeMovementY
* (INT32
) Private
->SimplePointerMode
.ResolutionY
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionY
;
3858 if (CurrentState
.RelativeMovementZ
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionZ
!= 0) {
3859 State
->RelativeMovementZ
+= (CurrentState
.RelativeMovementZ
* (INT32
) Private
->SimplePointerMode
.ResolutionZ
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionZ
;
3861 } else if (Status
== EFI_DEVICE_ERROR
) {
3862 ReturnStatus
= EFI_DEVICE_ERROR
;
3866 return ReturnStatus
;
3871 Reads the next keystroke from the input device. The WaitForKey Event can
3872 be used to test for existance of a keystroke via WaitForEvent () call.
3874 @param This A pointer to protocol instance.
3875 @param State A pointer to state information on the pointer device
3877 @retval EFI_SUCCESS The keystroke information was returned in State.
3878 @retval EFI_NOT_READY There was no keystroke data availiable.
3879 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3885 ConSplitterSimplePointerGetState (
3886 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
3887 IN OUT EFI_SIMPLE_POINTER_STATE
*State
3890 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3892 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
3894 Private
->InputEventSignalState
= FALSE
;
3896 return ConSplitterSimplePointerPrivateGetState (Private
, State
);
3901 This event agregates all the events of the ConIn devices in the spliter.
3902 If any events of physical ConIn devices are signaled, signal the ConIn
3903 spliter event. This will cause the calling code to call
3904 ConSplitterTextInReadKeyStroke ().
3906 @param Event The Event assoicated with callback.
3907 @param Context Context registered when Event was created.
3912 ConSplitterSimplePointerWaitForInput (
3918 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3921 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
3924 // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
3926 if (Private
->InputEventSignalState
) {
3927 gBS
->SignalEvent (Event
);
3931 // if any physical console input device has key input, signal the event.
3933 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3934 Status
= gBS
->CheckEvent (Private
->PointerList
[Index
]->WaitForInput
);
3935 if (!EFI_ERROR (Status
)) {
3936 gBS
->SignalEvent (Event
);
3937 Private
->InputEventSignalState
= TRUE
;
3943 Resets the pointer device hardware.
3945 @param This Protocol instance pointer.
3946 @param ExtendedVerification Driver may perform diagnostics on reset.
3948 @retval EFI_SUCCESS The device was reset.
3949 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
3955 ConSplitterAbsolutePointerReset (
3956 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
3957 IN BOOLEAN ExtendedVerification
3961 EFI_STATUS ReturnStatus
;
3962 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3965 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
3967 Private
->AbsoluteInputEventSignalState
= FALSE
;
3969 if (Private
->CurrentNumberOfAbsolutePointers
== 0) {
3973 // return the worst status met
3975 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
3976 Status
= Private
->AbsolutePointerList
[Index
]->Reset (
3977 Private
->AbsolutePointerList
[Index
],
3978 ExtendedVerification
3980 if (EFI_ERROR (Status
)) {
3981 ReturnStatus
= Status
;
3985 return ReturnStatus
;
3990 Retrieves the current state of a pointer device.
3992 @param This Protocol instance pointer.
3993 @param State A pointer to the state information on the
3996 @retval EFI_SUCCESS The state of the pointer device was returned in
3998 @retval EFI_NOT_READY The state of the pointer device has not changed
3999 since the last call to GetState().
4000 @retval EFI_DEVICE_ERROR A device error occurred while attempting to
4001 retrieve the pointer device's current state.
4006 ConSplitterAbsolutePointerGetState (
4007 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4008 IN OUT EFI_ABSOLUTE_POINTER_STATE
*State
4011 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4013 EFI_STATUS ReturnStatus
;
4015 EFI_ABSOLUTE_POINTER_STATE CurrentState
;
4018 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4020 Private
->AbsoluteInputEventSignalState
= FALSE
;
4022 State
->CurrentX
= 0;
4023 State
->CurrentY
= 0;
4024 State
->CurrentZ
= 0;
4025 State
->ActiveButtons
= 0;
4028 // if no physical pointer device exists, return EFI_NOT_READY;
4029 // if any physical pointer device has changed state,
4030 // return the state and EFI_SUCCESS.
4032 ReturnStatus
= EFI_NOT_READY
;
4033 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4035 Status
= Private
->AbsolutePointerList
[Index
]->GetState (
4036 Private
->AbsolutePointerList
[Index
],
4039 if (!EFI_ERROR (Status
)) {
4040 if (ReturnStatus
== EFI_NOT_READY
) {
4041 ReturnStatus
= EFI_SUCCESS
;
4044 State
->ActiveButtons
= CurrentState
.ActiveButtons
;
4046 if (!(Private
->AbsolutePointerMode
.AbsoluteMinX
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxX
== 0)) {
4047 State
->CurrentX
= CurrentState
.CurrentX
;
4049 if (!(Private
->AbsolutePointerMode
.AbsoluteMinY
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxY
== 0)) {
4050 State
->CurrentY
= CurrentState
.CurrentY
;
4052 if (!(Private
->AbsolutePointerMode
.AbsoluteMinZ
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxZ
== 0)) {
4053 State
->CurrentZ
= CurrentState
.CurrentZ
;
4056 } else if (Status
== EFI_DEVICE_ERROR
) {
4057 ReturnStatus
= EFI_DEVICE_ERROR
;
4061 return ReturnStatus
;
4066 This event agregates all the events of the pointer devices in the splitter.
4067 If any events of physical pointer devices are signaled, signal the pointer
4068 splitter event. This will cause the calling code to call
4069 ConSplitterAbsolutePointerGetState ().
4071 @param Event The Event assoicated with callback.
4072 @param Context Context registered when Event was created.
4077 ConSplitterAbsolutePointerWaitForInput (
4083 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4086 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4089 // if AbsoluteInputEventSignalState is flagged before,
4090 // and not cleared by Reset() or GetState(), signal it
4092 if (Private
->AbsoluteInputEventSignalState
) {
4093 gBS
->SignalEvent (Event
);
4097 // if any physical console input device has key input, signal the event.
4099 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4100 Status
= gBS
->CheckEvent (Private
->AbsolutePointerList
[Index
]->WaitForInput
);
4101 if (!EFI_ERROR (Status
)) {
4102 gBS
->SignalEvent (Event
);
4103 Private
->AbsoluteInputEventSignalState
= TRUE
;
4110 Reset the text output device hardware and optionaly run diagnostics
4112 @param This Protocol instance pointer.
4113 @param ExtendedVerification Driver may perform more exhaustive verfication
4114 operation of the device during reset.
4116 @retval EFI_SUCCESS The text output device was reset.
4117 @retval EFI_DEVICE_ERROR The text output device is not functioning
4118 correctly and could not be reset.
4123 ConSplitterTextOutReset (
4124 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4125 IN BOOLEAN ExtendedVerification
4129 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4131 EFI_STATUS ReturnStatus
;
4133 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4136 // return the worst status met
4138 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4139 Status
= Private
->TextOutList
[Index
].TextOut
->Reset (
4140 Private
->TextOutList
[Index
].TextOut
,
4141 ExtendedVerification
4143 if (EFI_ERROR (Status
)) {
4144 ReturnStatus
= Status
;
4148 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BLACK
));
4151 // reset all mode parameters
4153 TextOutSetMode (Private
, 0);
4155 return ReturnStatus
;
4160 Write a Unicode string to the output device.
4162 @param This Protocol instance pointer.
4163 @param WString The NULL-terminated Unicode string to be
4164 displayed on the output device(s). All output
4165 devices must also support the Unicode drawing
4166 defined in this file.
4168 @retval EFI_SUCCESS The string was output to the device.
4169 @retval EFI_DEVICE_ERROR The device reported an error while attempting to
4171 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
4173 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
4174 characters in the Unicode string could not be
4175 rendered and were skipped.
4180 ConSplitterTextOutOutputString (
4181 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4186 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4188 UINTN BackSpaceCount
;
4189 EFI_STATUS ReturnStatus
;
4190 CHAR16
*TargetString
;
4192 This
->SetAttribute (This
, This
->Mode
->Attribute
);
4194 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4198 for (TargetString
= WString
; *TargetString
!= L
'\0'; TargetString
++) {
4199 if (*TargetString
== CHAR_BACKSPACE
) {
4204 if (BackSpaceCount
== 0) {
4205 TargetString
= WString
;
4207 TargetString
= AllocatePool (sizeof (CHAR16
) * (StrLen (WString
) + BackSpaceCount
+ 1));
4208 ASSERT (TargetString
!= NULL
);
4210 StrCpy (TargetString
, WString
);
4213 // return the worst status met
4215 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4216 Status
= Private
->TextOutList
[Index
].TextOut
->OutputString (
4217 Private
->TextOutList
[Index
].TextOut
,
4220 if (EFI_ERROR (Status
)) {
4221 ReturnStatus
= Status
;
4225 if (Private
->CurrentNumberOfConsoles
> 0) {
4226 Private
->TextOutMode
.CursorColumn
= Private
->TextOutList
[0].TextOut
->Mode
->CursorColumn
;
4227 Private
->TextOutMode
.CursorRow
= Private
->TextOutList
[0].TextOut
->Mode
->CursorRow
;
4230 if (BackSpaceCount
> 0) {
4231 FreePool (TargetString
);
4234 return ReturnStatus
;
4239 Verifies that all characters in a Unicode string can be output to the
4242 @param This Protocol instance pointer.
4243 @param WString The NULL-terminated Unicode string to be
4244 examined for the output device(s).
4246 @retval EFI_SUCCESS The device(s) are capable of rendering the
4248 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string
4249 cannot be rendered by one or more of the output
4250 devices mapped by the EFI handle.
4255 ConSplitterTextOutTestString (
4256 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4261 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4263 EFI_STATUS ReturnStatus
;
4265 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4268 // return the worst status met
4270 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4271 Status
= Private
->TextOutList
[Index
].TextOut
->TestString (
4272 Private
->TextOutList
[Index
].TextOut
,
4275 if (EFI_ERROR (Status
)) {
4276 ReturnStatus
= Status
;
4280 // There is no DevNullTextOutTestString () since a Unicode buffer would
4281 // always return EFI_SUCCESS.
4282 // ReturnStatus will be EFI_SUCCESS if no consoles are present
4284 return ReturnStatus
;
4289 Returns information for an available text mode that the output device(s)
4292 @param This Protocol instance pointer.
4293 @param ModeNumber The mode number to return information on.
4294 @param Columns Returns the columns of the text output device
4295 for the requested ModeNumber.
4296 @param Rows Returns the rows of the text output device
4297 for the requested ModeNumber.
4299 @retval EFI_SUCCESS The requested mode information was returned.
4300 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4302 @retval EFI_UNSUPPORTED The mode number was not valid.
4307 ConSplitterTextOutQueryMode (
4308 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4309 IN UINTN ModeNumber
,
4314 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4316 INT32
*TextOutModeMap
;
4318 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4321 // Check whether param ModeNumber is valid.
4322 // ModeNumber should be within range 0 ~ MaxMode - 1.
4324 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4325 return EFI_UNSUPPORTED
;
4328 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4329 return EFI_UNSUPPORTED
;
4333 // We get the available mode from mode intersection map if it's available
4335 if (Private
->TextOutModeMap
!= NULL
) {
4336 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4337 CurrentMode
= (UINTN
)(*TextOutModeMap
);
4338 *Columns
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4339 *Rows
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4341 *Columns
= Private
->TextOutQueryData
[ModeNumber
].Columns
;
4342 *Rows
= Private
->TextOutQueryData
[ModeNumber
].Rows
;
4345 if (*Columns
<= 0 && *Rows
<= 0) {
4346 return EFI_UNSUPPORTED
;
4355 Sets the output device(s) to a specified mode.
4357 @param This Protocol instance pointer.
4358 @param ModeNumber The mode number to set.
4360 @retval EFI_SUCCESS The requested text mode was set.
4361 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4363 @retval EFI_UNSUPPORTED The mode number was not valid.
4368 ConSplitterTextOutSetMode (
4369 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4374 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4376 INT32
*TextOutModeMap
;
4377 EFI_STATUS ReturnStatus
;
4379 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4382 // Check whether param ModeNumber is valid.
4383 // ModeNumber should be within range 0 ~ MaxMode - 1.
4385 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4386 return EFI_UNSUPPORTED
;
4389 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4390 return EFI_UNSUPPORTED
;
4393 // If the mode is being set to the curent mode, then just clear the screen and return.
4395 if (Private
->TextOutMode
.Mode
== (INT32
) ModeNumber
) {
4396 return ConSplitterTextOutClearScreen (This
);
4399 // return the worst status met
4401 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4402 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4403 Status
= Private
->TextOutList
[Index
].TextOut
->SetMode (
4404 Private
->TextOutList
[Index
].TextOut
,
4405 TextOutModeMap
[Index
]
4407 if (EFI_ERROR (Status
)) {
4408 ReturnStatus
= Status
;
4413 // Set mode parameter to specified mode number
4415 TextOutSetMode (Private
, ModeNumber
);
4417 return ReturnStatus
;
4422 Sets the background and foreground colors for the OutputString () and
4423 ClearScreen () functions.
4425 @param This Protocol instance pointer.
4426 @param Attribute The attribute to set. Bits 0..3 are the
4427 foreground color, and bits 4..6 are the
4428 background color. All other bits are undefined
4429 and must be zero. The valid Attributes are
4430 defined in this file.
4432 @retval EFI_SUCCESS The attribute was set.
4433 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4435 @retval EFI_UNSUPPORTED The attribute requested is not defined.
4440 ConSplitterTextOutSetAttribute (
4441 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4446 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4448 EFI_STATUS ReturnStatus
;
4450 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4453 // Check whether param Attribute is valid.
4455 if ( (Attribute
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4456 return EFI_UNSUPPORTED
;
4460 // return the worst status met
4462 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4463 Status
= Private
->TextOutList
[Index
].TextOut
->SetAttribute (
4464 Private
->TextOutList
[Index
].TextOut
,
4467 if (EFI_ERROR (Status
)) {
4468 ReturnStatus
= Status
;
4472 Private
->TextOutMode
.Attribute
= (INT32
) Attribute
;
4474 return ReturnStatus
;
4479 Clears the output device(s) display to the currently selected background
4482 @param This Protocol instance pointer.
4484 @retval EFI_SUCCESS The operation completed successfully.
4485 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4487 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4492 ConSplitterTextOutClearScreen (
4493 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
4497 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4499 EFI_STATUS ReturnStatus
;
4501 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4504 // return the worst status met
4506 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4507 Status
= Private
->TextOutList
[Index
].TextOut
->ClearScreen (Private
->TextOutList
[Index
].TextOut
);
4508 if (EFI_ERROR (Status
)) {
4509 ReturnStatus
= Status
;
4514 // No need to do extra check here as whether (Column, Row) is valid has
4515 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
4516 // always be supported.
4518 Private
->TextOutMode
.CursorColumn
= 0;
4519 Private
->TextOutMode
.CursorRow
= 0;
4520 Private
->TextOutMode
.CursorVisible
= TRUE
;
4522 return ReturnStatus
;
4527 Sets the current coordinates of the cursor position
4529 @param This Protocol instance pointer.
4530 @param Column The column position to set the cursor to. Must be
4531 greater than or equal to zero and less than the
4532 number of columns by QueryMode ().
4533 @param Row The row position to set the cursor to. Must be
4534 greater than or equal to zero and less than the
4535 number of rows by QueryMode ().
4537 @retval EFI_SUCCESS The operation completed successfully.
4538 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4540 @retval EFI_UNSUPPORTED The output device is not in a valid text mode,
4541 or the cursor position is invalid for the
4547 ConSplitterTextOutSetCursorPosition (
4548 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4554 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4556 EFI_STATUS ReturnStatus
;
4559 INT32
*TextOutModeMap
;
4563 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4564 TextOutModeMap
= NULL
;
4565 ModeNumber
= Private
->TextOutMode
.Mode
;
4568 // Get current MaxColumn and MaxRow from intersection map
4570 if (Private
->TextOutModeMap
!= NULL
) {
4571 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4572 CurrentMode
= *TextOutModeMap
;
4574 CurrentMode
= ModeNumber
;
4577 MaxColumn
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4578 MaxRow
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4580 if (Column
>= MaxColumn
|| Row
>= MaxRow
) {
4581 return EFI_UNSUPPORTED
;
4584 // return the worst status met
4586 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4587 Status
= Private
->TextOutList
[Index
].TextOut
->SetCursorPosition (
4588 Private
->TextOutList
[Index
].TextOut
,
4592 if (EFI_ERROR (Status
)) {
4593 ReturnStatus
= Status
;
4598 // No need to do extra check here as whether (Column, Row) is valid has
4599 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
4600 // always be supported.
4602 Private
->TextOutMode
.CursorColumn
= (INT32
) Column
;
4603 Private
->TextOutMode
.CursorRow
= (INT32
) Row
;
4605 return ReturnStatus
;
4610 Makes the cursor visible or invisible
4612 @param This Protocol instance pointer.
4613 @param Visible If TRUE, the cursor is set to be visible. If
4614 FALSE, the cursor is set to be invisible.
4616 @retval EFI_SUCCESS The operation completed successfully.
4617 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4618 the request, or the device does not support
4619 changing the cursor mode.
4620 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4625 ConSplitterTextOutEnableCursor (
4626 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4631 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4633 EFI_STATUS ReturnStatus
;
4635 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4638 // return the worst status met
4640 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4641 Status
= Private
->TextOutList
[Index
].TextOut
->EnableCursor (
4642 Private
->TextOutList
[Index
].TextOut
,
4645 if (EFI_ERROR (Status
)) {
4646 ReturnStatus
= Status
;
4650 Private
->TextOutMode
.CursorVisible
= Visible
;
4652 return ReturnStatus
;