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 - 2012, 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, StdErr.
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
;
470 // Create virtual device handle for StdErr Splitter
472 Status
= ConSplitterTextOutConstructor (&mStdErr
);
473 if (!EFI_ERROR (Status
)) {
474 Status
= gBS
->InstallMultipleProtocolInterfaces (
475 &mStdErr
.VirtualHandle
,
476 &gEfiSimpleTextOutProtocolGuid
,
480 if (!EFI_ERROR (Status
)) {
482 // Update the EFI System Table with new virtual console
483 // and update the pointer to Text Output protocol.
485 gST
->StandardErrorHandle
= mStdErr
.VirtualHandle
;
486 gST
->StdErr
= &mStdErr
.TextOut
;
491 // Update the CRC32 in the EFI System Table header
494 gBS
->CalculateCrc32 (
505 Construct console input devices' private data.
507 @param ConInPrivate A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA
510 @retval EFI_OUT_OF_RESOURCES Out of resources.
511 @retval EFI_SUCCESS Text Input Devcie's private data has been constructed.
512 @retval other Failed to construct private data.
516 ConSplitterTextInConstructor (
517 TEXT_IN_SPLITTER_PRIVATE_DATA
*ConInPrivate
523 // Allocate buffer for Simple Text Input device
525 Status
= ConSplitterGrowBuffer (
526 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
527 &ConInPrivate
->TextInListCount
,
528 (VOID
**) &ConInPrivate
->TextInList
530 if (EFI_ERROR (Status
)) {
531 return EFI_OUT_OF_RESOURCES
;
535 // Create Event to wait for a key
537 Status
= gBS
->CreateEvent (
540 ConSplitterTextInWaitForKey
,
542 &ConInPrivate
->TextIn
.WaitForKey
544 ASSERT_EFI_ERROR (Status
);
547 // Allocate buffer for Simple Text Input Ex device
549 Status
= ConSplitterGrowBuffer (
550 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
551 &ConInPrivate
->TextInExListCount
,
552 (VOID
**) &ConInPrivate
->TextInExList
554 if (EFI_ERROR (Status
)) {
555 return EFI_OUT_OF_RESOURCES
;
558 // Create Event to wait for a key Ex
560 Status
= gBS
->CreateEvent (
563 ConSplitterTextInWaitForKey
,
565 &ConInPrivate
->TextInEx
.WaitForKeyEx
567 ASSERT_EFI_ERROR (Status
);
569 InitializeListHead (&ConInPrivate
->NotifyList
);
571 ConInPrivate
->AbsolutePointer
.Mode
= &ConInPrivate
->AbsolutePointerMode
;
573 // Allocate buffer for Absolute Pointer device
575 Status
= ConSplitterGrowBuffer (
576 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
577 &ConInPrivate
->AbsolutePointerListCount
,
578 (VOID
**) &ConInPrivate
->AbsolutePointerList
580 if (EFI_ERROR (Status
)) {
581 return EFI_OUT_OF_RESOURCES
;
584 // Create Event to wait for device input for Absolute pointer device
586 Status
= gBS
->CreateEvent (
589 ConSplitterAbsolutePointerWaitForInput
,
591 &ConInPrivate
->AbsolutePointer
.WaitForInput
593 ASSERT_EFI_ERROR (Status
);
595 ConInPrivate
->SimplePointer
.Mode
= &ConInPrivate
->SimplePointerMode
;
597 // Allocate buffer for Simple Pointer device
599 Status
= ConSplitterGrowBuffer (
600 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
601 &ConInPrivate
->PointerListCount
,
602 (VOID
**) &ConInPrivate
->PointerList
604 if (EFI_ERROR (Status
)) {
605 return EFI_OUT_OF_RESOURCES
;
608 // Create Event to wait for device input for Simple pointer device
610 Status
= gBS
->CreateEvent (
613 ConSplitterSimplePointerWaitForInput
,
615 &ConInPrivate
->SimplePointer
.WaitForInput
622 Construct console output devices' private data.
624 @param ConOutPrivate A pointer to the TEXT_OUT_SPLITTER_PRIVATE_DATA
627 @retval EFI_OUT_OF_RESOURCES Out of resources.
628 @retval EFI_SUCCESS Text Input Devcie's private data has been constructed.
632 ConSplitterTextOutConstructor (
633 TEXT_OUT_SPLITTER_PRIVATE_DATA
*ConOutPrivate
637 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
640 // Copy protocols template
642 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
643 CopyMem (&ConOutPrivate
->UgaDraw
, &mUgaDrawProtocolTemplate
, sizeof (EFI_UGA_DRAW_PROTOCOL
));
645 if (FeaturePcdGet (PcdConOutGopSupport
)) {
646 CopyMem (&ConOutPrivate
->GraphicsOutput
, &mGraphicsOutputProtocolTemplate
, sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL
));
650 // Initilize console output splitter's private data.
652 ConOutPrivate
->TextOut
.Mode
= &ConOutPrivate
->TextOutMode
;
655 // When new console device is added, the new mode will be set later,
656 // so put current mode back to init state.
658 ConOutPrivate
->TextOutMode
.Mode
= 0xFF;
660 // Allocate buffer for Console Out device
662 Status
= ConSplitterGrowBuffer (
663 sizeof (TEXT_OUT_AND_GOP_DATA
),
664 &ConOutPrivate
->TextOutListCount
,
665 (VOID
**) &ConOutPrivate
->TextOutList
667 if (EFI_ERROR (Status
)) {
668 return EFI_OUT_OF_RESOURCES
;
671 // Allocate buffer for Text Out query data
673 Status
= ConSplitterGrowBuffer (
674 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
675 &ConOutPrivate
->TextOutQueryDataCount
,
676 (VOID
**) &ConOutPrivate
->TextOutQueryData
678 if (EFI_ERROR (Status
)) {
679 return EFI_OUT_OF_RESOURCES
;
683 // Setup the default console to 80 x 25 and mode to 0
685 ConOutPrivate
->TextOutQueryData
[0].Columns
= 80;
686 ConOutPrivate
->TextOutQueryData
[0].Rows
= 25;
687 TextOutSetMode (ConOutPrivate
, 0);
690 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
692 // Setup the UgaDraw to 800 x 600 x 32 bits per pixel, 60Hz.
694 ConSplitterUgaDrawSetMode (&ConOutPrivate
->UgaDraw
, 800, 600, 32, 60);
696 if (FeaturePcdGet (PcdConOutGopSupport
)) {
698 // Setup resource for mode information in Graphics Output Protocol interface
700 if ((ConOutPrivate
->GraphicsOutput
.Mode
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
))) == NULL
) {
701 return EFI_OUT_OF_RESOURCES
;
703 if ((ConOutPrivate
->GraphicsOutput
.Mode
->Info
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
))) == NULL
) {
704 return EFI_OUT_OF_RESOURCES
;
707 // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel
708 // DevNull will be updated to user-defined mode after driver has started.
710 if ((ConOutPrivate
->GraphicsOutputModeBuffer
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
))) == NULL
) {
711 return EFI_OUT_OF_RESOURCES
;
713 Info
= &ConOutPrivate
->GraphicsOutputModeBuffer
[0];
715 Info
->HorizontalResolution
= 800;
716 Info
->VerticalResolution
= 600;
717 Info
->PixelFormat
= PixelBltOnly
;
718 Info
->PixelsPerScanLine
= 800;
719 CopyMem (ConOutPrivate
->GraphicsOutput
.Mode
->Info
, Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
720 ConOutPrivate
->GraphicsOutput
.Mode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
723 // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()
724 // GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
726 ConOutPrivate
->GraphicsOutput
.Mode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
727 ConOutPrivate
->GraphicsOutput
.Mode
->FrameBufferSize
= 0;
729 ConOutPrivate
->GraphicsOutput
.Mode
->MaxMode
= 1;
731 // Initial current mode to unknown state, and then set to mode 0
733 ConOutPrivate
->GraphicsOutput
.Mode
->Mode
= 0xffff;
734 ConOutPrivate
->GraphicsOutput
.SetMode (&ConOutPrivate
->GraphicsOutput
, 0);
742 Test to see if the specified protocol could be supported on the specified device.
744 @param This Driver Binding protocol pointer.
745 @param ControllerHandle Handle of device to test.
746 @param Guid The specified protocol.
748 @retval EFI_SUCCESS The specified protocol is supported on this device.
749 @retval EFI_UNSUPPORTED The specified protocol attempts to be installed on virtul handle.
750 @retval other Failed to open specified protocol on this device.
754 ConSplitterSupported (
755 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
756 IN EFI_HANDLE ControllerHandle
,
764 // Make sure the Console Splitter does not attempt to attach to itself
766 if (ControllerHandle
== mConIn
.VirtualHandle
||
767 ControllerHandle
== mConOut
.VirtualHandle
||
768 ControllerHandle
== mStdErr
.VirtualHandle
770 return EFI_UNSUPPORTED
;
774 // Check to see whether the specific protocol could be opened BY_DRIVER
776 Status
= gBS
->OpenProtocol (
780 This
->DriverBindingHandle
,
782 EFI_OPEN_PROTOCOL_BY_DRIVER
785 if (EFI_ERROR (Status
)) {
792 This
->DriverBindingHandle
,
800 Test to see if Console In Device could be supported on the Controller.
802 @param This Driver Binding protocol instance pointer.
803 @param ControllerHandle Handle of device to test.
804 @param RemainingDevicePath Optional parameter use to pick a specific child
807 @retval EFI_SUCCESS This driver supports this device.
808 @retval other This driver does not support this device.
813 ConSplitterConInDriverBindingSupported (
814 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
815 IN EFI_HANDLE ControllerHandle
,
816 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
819 return ConSplitterSupported (
822 &gEfiConsoleInDeviceGuid
827 Test to see if Simple Pointer protocol could be supported on the Controller.
829 @param This Driver Binding protocol instance pointer.
830 @param ControllerHandle Handle of device to test.
831 @param RemainingDevicePath Optional parameter use to pick a specific child
834 @retval EFI_SUCCESS This driver supports this device.
835 @retval other This driver does not support this device.
840 ConSplitterSimplePointerDriverBindingSupported (
841 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
842 IN EFI_HANDLE ControllerHandle
,
843 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
846 return ConSplitterSupported (
849 &gEfiSimplePointerProtocolGuid
854 Test to see if Absolute Pointer protocol could be supported on the Controller.
856 @param This Driver Binding protocol instance pointer.
857 @param ControllerHandle Handle of device to test.
858 @param RemainingDevicePath Optional parameter use to pick a specific child
861 @retval EFI_SUCCESS This driver supports this device.
862 @retval other This driver does not support this device.
867 ConSplitterAbsolutePointerDriverBindingSupported (
868 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
869 IN EFI_HANDLE ControllerHandle
,
870 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
873 return ConSplitterSupported (
876 &gEfiAbsolutePointerProtocolGuid
882 Test to see if Console Out Device could be supported on the Controller.
884 @param This Driver Binding protocol instance pointer.
885 @param ControllerHandle Handle of device to test.
886 @param RemainingDevicePath Optional parameter use to pick a specific child
889 @retval EFI_SUCCESS This driver supports this device.
890 @retval other This driver does not support this device.
895 ConSplitterConOutDriverBindingSupported (
896 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
897 IN EFI_HANDLE ControllerHandle
,
898 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
901 return ConSplitterSupported (
904 &gEfiConsoleOutDeviceGuid
909 Test to see if Standard Error Device could be supported on the Controller.
911 @param This Driver Binding protocol instance pointer.
912 @param ControllerHandle Handle of device to test.
913 @param RemainingDevicePath Optional parameter use to pick a specific child
916 @retval EFI_SUCCESS This driver supports this device.
917 @retval other This driver does not support this device.
922 ConSplitterStdErrDriverBindingSupported (
923 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
924 IN EFI_HANDLE ControllerHandle
,
925 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
928 return ConSplitterSupported (
931 &gEfiStandardErrorDeviceGuid
937 Start ConSplitter on devcie handle by opening Console Device Guid on device handle
938 and the console virtual handle. And Get the console interface on controller handle.
940 @param This Driver Binding protocol instance pointer.
941 @param ControllerHandle Handle of device.
942 @param ConSplitterVirtualHandle Console virtual Handle.
943 @param DeviceGuid The specified Console Device, such as ConInDev,
945 @param InterfaceGuid The specified protocol to be opened.
946 @param Interface Protocol interface returned.
948 @retval EFI_SUCCESS This driver supports this device.
949 @retval other Failed to open the specified Console Device Guid
950 or specified protocol.
955 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
956 IN EFI_HANDLE ControllerHandle
,
957 IN EFI_HANDLE ConSplitterVirtualHandle
,
958 IN EFI_GUID
*DeviceGuid
,
959 IN EFI_GUID
*InterfaceGuid
,
967 // Check to see whether the ControllerHandle has the DeviceGuid on it.
969 Status
= gBS
->OpenProtocol (
973 This
->DriverBindingHandle
,
975 EFI_OPEN_PROTOCOL_BY_DRIVER
977 if (EFI_ERROR (Status
)) {
982 // Open the Parent Handle for the child.
984 Status
= gBS
->OpenProtocol (
988 This
->DriverBindingHandle
,
989 ConSplitterVirtualHandle
,
990 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
992 if (EFI_ERROR (Status
)) {
997 // Open InterfaceGuid on the virtul handle.
999 Status
= gBS
->OpenProtocol (
1003 This
->DriverBindingHandle
,
1004 ConSplitterVirtualHandle
,
1005 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1008 if (!EFI_ERROR (Status
)) {
1013 // close the DeviceGuid on ConSplitter VirtualHandle.
1015 gBS
->CloseProtocol (
1018 This
->DriverBindingHandle
,
1019 ConSplitterVirtualHandle
1024 // close the DeviceGuid on ControllerHandle.
1026 gBS
->CloseProtocol (
1029 This
->DriverBindingHandle
,
1038 Start Console In Consplitter on device handle.
1040 @param This Driver Binding protocol instance pointer.
1041 @param ControllerHandle Handle of device to bind driver to.
1042 @param RemainingDevicePath Optional parameter use to pick a specific child
1045 @retval EFI_SUCCESS Console In Consplitter is added to ControllerHandle.
1046 @retval other Console In Consplitter does not support this device.
1051 ConSplitterConInDriverBindingStart (
1052 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1053 IN EFI_HANDLE ControllerHandle
,
1054 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1058 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
1059 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
;
1062 // Start ConSplitter on ControllerHandle, and create the virtual
1063 // agrogated console device on first call Start for a SimpleTextIn handle.
1065 Status
= ConSplitterStart (
1068 mConIn
.VirtualHandle
,
1069 &gEfiConsoleInDeviceGuid
,
1070 &gEfiSimpleTextInProtocolGuid
,
1073 if (EFI_ERROR (Status
)) {
1078 // Add this device into Text In devices list.
1080 Status
= ConSplitterTextInAddDevice (&mConIn
, TextIn
);
1081 if (EFI_ERROR (Status
)) {
1085 Status
= gBS
->OpenProtocol (
1087 &gEfiSimpleTextInputExProtocolGuid
,
1088 (VOID
**) &TextInEx
,
1089 This
->DriverBindingHandle
,
1090 mConIn
.VirtualHandle
,
1091 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1093 if (!EFI_ERROR (Status
)) {
1095 // If Simple Text Input Ex protocol exists,
1096 // add this device into Text In Ex devices list.
1098 Status
= ConSplitterTextInExAddDevice (&mConIn
, TextInEx
);
1106 Start Simple Pointer Consplitter on device handle.
1108 @param This Driver Binding protocol instance pointer.
1109 @param ControllerHandle Handle of device to bind driver to.
1110 @param RemainingDevicePath Optional parameter use to pick a specific child
1113 @retval EFI_SUCCESS Simple Pointer Consplitter is added to ControllerHandle.
1114 @retval other Simple Pointer Consplitter does not support this device.
1119 ConSplitterSimplePointerDriverBindingStart (
1120 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1121 IN EFI_HANDLE ControllerHandle
,
1122 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1126 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
;
1129 // Start ConSplitter on ControllerHandle, and create the virtual
1130 // agrogated console device on first call Start for a SimplePointer handle.
1132 Status
= ConSplitterStart (
1135 mConIn
.VirtualHandle
,
1136 &gEfiSimplePointerProtocolGuid
,
1137 &gEfiSimplePointerProtocolGuid
,
1138 (VOID
**) &SimplePointer
1140 if (EFI_ERROR (Status
)) {
1145 // Add this devcie into Simple Pointer devices list.
1147 return ConSplitterSimplePointerAddDevice (&mConIn
, SimplePointer
);
1152 Start Absolute Pointer Consplitter on device handle.
1154 @param This Driver Binding protocol instance pointer.
1155 @param ControllerHandle Handle of device to bind driver to.
1156 @param RemainingDevicePath Optional parameter use to pick a specific child
1159 @retval EFI_SUCCESS Absolute Pointer Consplitter is added to ControllerHandle.
1160 @retval other Absolute Pointer Consplitter does not support this device.
1165 ConSplitterAbsolutePointerDriverBindingStart (
1166 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1167 IN EFI_HANDLE ControllerHandle
,
1168 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1172 EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
;
1175 // Start ConSplitter on ControllerHandle, and create the virtual
1176 // agrogated console device on first call Start for a AbsolutePointer handle.
1178 Status
= ConSplitterStart (
1181 mConIn
.VirtualHandle
,
1182 &gEfiAbsolutePointerProtocolGuid
,
1183 &gEfiAbsolutePointerProtocolGuid
,
1184 (VOID
**) &AbsolutePointer
1187 if (EFI_ERROR (Status
)) {
1192 // Add this devcie into Absolute Pointer devices list.
1194 return ConSplitterAbsolutePointerAddDevice (&mConIn
, AbsolutePointer
);
1199 Start Console Out Consplitter on device handle.
1201 @param This Driver Binding protocol instance pointer.
1202 @param ControllerHandle Handle of device to bind driver to.
1203 @param RemainingDevicePath Optional parameter use to pick a specific child
1206 @retval EFI_SUCCESS Console Out Consplitter is added to ControllerHandle.
1207 @retval other Console Out Consplitter does not support this device.
1212 ConSplitterConOutDriverBindingStart (
1213 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1214 IN EFI_HANDLE ControllerHandle
,
1215 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1219 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1220 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1221 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1223 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
1226 // Start ConSplitter on ControllerHandle, and create the virtual
1227 // agrogated console device on first call Start for a ConsoleOut handle.
1229 Status
= ConSplitterStart (
1232 mConOut
.VirtualHandle
,
1233 &gEfiConsoleOutDeviceGuid
,
1234 &gEfiSimpleTextOutProtocolGuid
,
1237 if (EFI_ERROR (Status
)) {
1241 GraphicsOutput
= NULL
;
1244 // Try to Open Graphics Output protocol
1246 Status
= gBS
->OpenProtocol (
1248 &gEfiGraphicsOutputProtocolGuid
,
1249 (VOID
**) &GraphicsOutput
,
1250 This
->DriverBindingHandle
,
1251 mConOut
.VirtualHandle
,
1252 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1255 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
1257 // Open UGA DRAW protocol
1261 &gEfiUgaDrawProtocolGuid
,
1263 This
->DriverBindingHandle
,
1264 mConOut
.VirtualHandle
,
1265 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1270 // When new console device is added, the new mode will be set later,
1271 // so put current mode back to init state.
1273 mConOut
.TextOutMode
.Mode
= 0xFF;
1276 // If both ConOut and StdErr incorporate the same Text Out device,
1277 // their MaxMode and QueryData should be the intersection of both.
1279 Status
= ConSplitterTextOutAddDevice (&mConOut
, TextOut
, GraphicsOutput
, UgaDraw
);
1280 ConSplitterTextOutSetAttribute (&mConOut
.TextOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
1282 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
1284 // Get the UGA mode data of ConOut from the current mode
1286 if (GraphicsOutput
!= NULL
) {
1287 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, GraphicsOutput
->Mode
->Mode
, &SizeOfInfo
, &Info
);
1288 if (EFI_ERROR (Status
)) {
1291 ASSERT ( SizeOfInfo
<= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
1293 mConOut
.UgaHorizontalResolution
= Info
->HorizontalResolution
;
1294 mConOut
.UgaVerticalResolution
= Info
->VerticalResolution
;
1295 mConOut
.UgaColorDepth
= 32;
1296 mConOut
.UgaRefreshRate
= 60;
1300 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1301 Status
= UgaDraw
->GetMode (
1303 &mConOut
.UgaHorizontalResolution
,
1304 &mConOut
.UgaVerticalResolution
,
1305 &mConOut
.UgaColorDepth
,
1306 &mConOut
.UgaRefreshRate
1316 Start Standard Error Consplitter on device handle.
1318 @param This Driver Binding protocol instance pointer.
1319 @param ControllerHandle Handle of device to bind driver to.
1320 @param RemainingDevicePath Optional parameter use to pick a specific child
1323 @retval EFI_SUCCESS Standard Error Consplitter is added to ControllerHandle.
1324 @retval other Standard Error Consplitter does not support this device.
1329 ConSplitterStdErrDriverBindingStart (
1330 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1331 IN EFI_HANDLE ControllerHandle
,
1332 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1336 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1339 // Start ConSplitter on ControllerHandle, and create the virtual
1340 // agrogated console device on first call Start for a StandardError handle.
1342 Status
= ConSplitterStart (
1345 mStdErr
.VirtualHandle
,
1346 &gEfiStandardErrorDeviceGuid
,
1347 &gEfiSimpleTextOutProtocolGuid
,
1350 if (EFI_ERROR (Status
)) {
1355 // When new console device is added, the new mode will be set later,
1356 // so put current mode back to init state.
1358 mStdErr
.TextOutMode
.Mode
= 0xFF;
1361 // If both ConOut and StdErr incorporate the same Text Out device,
1362 // their MaxMode and QueryData should be the intersection of both.
1364 Status
= ConSplitterTextOutAddDevice (&mStdErr
, TextOut
, NULL
, NULL
);
1365 ConSplitterTextOutSetAttribute (&mStdErr
.TextOut
, EFI_TEXT_ATTR (EFI_MAGENTA
, EFI_BLACK
));
1366 if (EFI_ERROR (Status
)) {
1375 Stop ConSplitter on device handle by closing Console Device Guid on device handle
1376 and the console virtual handle.
1378 @param This Protocol instance pointer.
1379 @param ControllerHandle Handle of device.
1380 @param ConSplitterVirtualHandle Console virtual Handle.
1381 @param DeviceGuid The specified Console Device, such as ConInDev,
1383 @param InterfaceGuid The specified protocol to be opened.
1384 @param Interface Protocol interface returned.
1386 @retval EFI_SUCCESS Stop ConSplitter on ControllerHandle successfully.
1387 @retval other Failed to Stop ConSplitter on ControllerHandle.
1392 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1393 IN EFI_HANDLE ControllerHandle
,
1394 IN EFI_HANDLE ConSplitterVirtualHandle
,
1395 IN EFI_GUID
*DeviceGuid
,
1396 IN EFI_GUID
*InterfaceGuid
,
1402 Status
= gBS
->OpenProtocol (
1406 This
->DriverBindingHandle
,
1408 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1410 if (EFI_ERROR (Status
)) {
1414 // close the protocol refered.
1416 gBS
->CloseProtocol (
1419 This
->DriverBindingHandle
,
1420 ConSplitterVirtualHandle
1423 gBS
->CloseProtocol (
1426 This
->DriverBindingHandle
,
1435 Stop Console In ConSplitter on ControllerHandle by closing Console In Devcice GUID.
1437 @param This Driver Binding protocol instance pointer.
1438 @param ControllerHandle Handle of device to stop driver on
1439 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1440 children is zero stop the entire bus driver.
1441 @param ChildHandleBuffer List of Child Handles to Stop.
1443 @retval EFI_SUCCESS This driver is removed ControllerHandle
1444 @retval other This driver was not removed from this device
1449 ConSplitterConInDriverBindingStop (
1450 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1451 IN EFI_HANDLE ControllerHandle
,
1452 IN UINTN NumberOfChildren
,
1453 IN EFI_HANDLE
*ChildHandleBuffer
1457 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
1458 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
;
1460 if (NumberOfChildren
== 0) {
1464 Status
= gBS
->OpenProtocol (
1466 &gEfiSimpleTextInputExProtocolGuid
,
1467 (VOID
**) &TextInEx
,
1468 This
->DriverBindingHandle
,
1470 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1472 if (!EFI_ERROR (Status
)) {
1474 // If Simple Text Input Ex protocol exists,
1475 // remove device from Text Input Ex devices list.
1477 Status
= ConSplitterTextInExDeleteDevice (&mConIn
, TextInEx
);
1478 if (EFI_ERROR (Status
)) {
1484 // Close Simple Text In protocol on controller handle and virtual handle.
1486 Status
= ConSplitterStop (
1489 mConIn
.VirtualHandle
,
1490 &gEfiConsoleInDeviceGuid
,
1491 &gEfiSimpleTextInProtocolGuid
,
1494 if (EFI_ERROR (Status
)) {
1499 // Remove device from Text Input devices list.
1501 return ConSplitterTextInDeleteDevice (&mConIn
, TextIn
);
1506 Stop Simple Pointer protocol ConSplitter on ControllerHandle by closing
1507 Simple Pointer protocol.
1509 @param This Driver Binding protocol instance pointer.
1510 @param ControllerHandle Handle of device to stop driver on
1511 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1512 children is zero stop the entire bus driver.
1513 @param ChildHandleBuffer List of Child Handles to Stop.
1515 @retval EFI_SUCCESS This driver is removed ControllerHandle
1516 @retval other This driver was not removed from this device
1521 ConSplitterSimplePointerDriverBindingStop (
1522 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1523 IN EFI_HANDLE ControllerHandle
,
1524 IN UINTN NumberOfChildren
,
1525 IN EFI_HANDLE
*ChildHandleBuffer
1529 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
;
1531 if (NumberOfChildren
== 0) {
1536 // Close Simple Pointer protocol on controller handle and virtual handle.
1538 Status
= ConSplitterStop (
1541 mConIn
.VirtualHandle
,
1542 &gEfiSimplePointerProtocolGuid
,
1543 &gEfiSimplePointerProtocolGuid
,
1544 (VOID
**) &SimplePointer
1546 if (EFI_ERROR (Status
)) {
1551 // Remove this device from Simple Pointer device list.
1553 return ConSplitterSimplePointerDeleteDevice (&mConIn
, SimplePointer
);
1558 Stop Absolute Pointer protocol ConSplitter on ControllerHandle by closing
1559 Absolute Pointer protocol.
1561 @param This Driver Binding protocol instance pointer.
1562 @param ControllerHandle Handle of device to stop driver on
1563 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1564 children is zero stop the entire bus driver.
1565 @param ChildHandleBuffer List of Child Handles to Stop.
1567 @retval EFI_SUCCESS This driver is removed ControllerHandle
1568 @retval other This driver was not removed from this device
1573 ConSplitterAbsolutePointerDriverBindingStop (
1574 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1575 IN EFI_HANDLE ControllerHandle
,
1576 IN UINTN NumberOfChildren
,
1577 IN EFI_HANDLE
*ChildHandleBuffer
1581 EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
;
1583 if (NumberOfChildren
== 0) {
1588 // Close Absolute Pointer protocol on controller handle and virtual handle.
1590 Status
= ConSplitterStop (
1593 mConIn
.VirtualHandle
,
1594 &gEfiAbsolutePointerProtocolGuid
,
1595 &gEfiAbsolutePointerProtocolGuid
,
1596 (VOID
**) &AbsolutePointer
1598 if (EFI_ERROR (Status
)) {
1603 // Remove this device from Absolute Pointer device list.
1605 return ConSplitterAbsolutePointerDeleteDevice (&mConIn
, AbsolutePointer
);
1610 Stop Console Out ConSplitter on device handle by closing Console Out Devcice GUID.
1612 @param This Driver Binding protocol instance pointer.
1613 @param ControllerHandle Handle of device to stop driver on
1614 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1615 children is zero stop the entire bus driver.
1616 @param ChildHandleBuffer List of Child Handles to Stop.
1618 @retval EFI_SUCCESS This driver is removed ControllerHandle
1619 @retval other This driver was not removed from this device
1624 ConSplitterConOutDriverBindingStop (
1625 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1626 IN EFI_HANDLE ControllerHandle
,
1627 IN UINTN NumberOfChildren
,
1628 IN EFI_HANDLE
*ChildHandleBuffer
1632 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1634 if (NumberOfChildren
== 0) {
1639 // Close Absolute Pointer protocol on controller handle and virtual handle.
1641 Status
= ConSplitterStop (
1644 mConOut
.VirtualHandle
,
1645 &gEfiConsoleOutDeviceGuid
,
1646 &gEfiSimpleTextOutProtocolGuid
,
1649 if (EFI_ERROR (Status
)) {
1654 // Remove this device from Text Out device list.
1656 return ConSplitterTextOutDeleteDevice (&mConOut
, TextOut
);
1661 Stop Standard Error ConSplitter on ControllerHandle by closing Standard Error GUID.
1663 @param This Driver Binding protocol instance pointer.
1664 @param ControllerHandle Handle of device to stop driver on
1665 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1666 children is zero stop the entire bus driver.
1667 @param ChildHandleBuffer List of Child Handles to Stop.
1669 @retval EFI_SUCCESS This driver is removed ControllerHandle
1670 @retval other This driver was not removed from this device
1675 ConSplitterStdErrDriverBindingStop (
1676 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1677 IN EFI_HANDLE ControllerHandle
,
1678 IN UINTN NumberOfChildren
,
1679 IN EFI_HANDLE
*ChildHandleBuffer
1683 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1685 if (NumberOfChildren
== 0) {
1690 // Close Standard Error Device on controller handle and virtual handle.
1692 Status
= ConSplitterStop (
1695 mStdErr
.VirtualHandle
,
1696 &gEfiStandardErrorDeviceGuid
,
1697 &gEfiSimpleTextOutProtocolGuid
,
1700 if (EFI_ERROR (Status
)) {
1704 // Delete this console error out device's data structures.
1706 return ConSplitterTextOutDeleteDevice (&mStdErr
, TextOut
);
1711 Take the passed in Buffer of size ElementSize and grow the buffer
1712 by CONSOLE_SPLITTER_ALLOC_UNIT * ElementSize bytes.
1713 Copy the current data in Buffer to the new version of Buffer and
1714 free the old version of buffer.
1716 @param ElementSize Size of element in array.
1717 @param Count Current number of elements in array.
1718 @param Buffer Bigger version of passed in Buffer with all the
1721 @retval EFI_SUCCESS Buffer size has grown.
1722 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1726 ConSplitterGrowBuffer (
1727 IN UINTN ElementSize
,
1728 IN OUT UINTN
*Count
,
1729 IN OUT VOID
**Buffer
1735 // grow the buffer to new buffer size,
1736 // copy the old buffer's content to the new-size buffer,
1737 // then free the old buffer.
1739 Ptr
= ReallocatePool (
1740 ElementSize
* (*Count
),
1741 ElementSize
* ((*Count
) + CONSOLE_SPLITTER_ALLOC_UNIT
),
1745 return EFI_OUT_OF_RESOURCES
;
1747 *Count
+= CONSOLE_SPLITTER_ALLOC_UNIT
;
1754 Add Text Input Device in Consplitter Text Input list.
1756 @param Private Text In Splitter pointer.
1757 @param TextIn Simple Text Input protocol pointer.
1759 @retval EFI_SUCCESS Text Input Device added successfully.
1760 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1764 ConSplitterTextInAddDevice (
1765 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1766 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1772 // If the Text In List is full, enlarge it by calling ConSplitterGrowBuffer().
1774 if (Private
->CurrentNumberOfConsoles
>= Private
->TextInListCount
) {
1775 Status
= ConSplitterGrowBuffer (
1776 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
1777 &Private
->TextInListCount
,
1778 (VOID
**) &Private
->TextInList
1780 if (EFI_ERROR (Status
)) {
1781 return EFI_OUT_OF_RESOURCES
;
1785 // Add the new text-in device data structure into the Text In List.
1787 Private
->TextInList
[Private
->CurrentNumberOfConsoles
] = TextIn
;
1788 Private
->CurrentNumberOfConsoles
++;
1791 // Extra CheckEvent added to reduce the double CheckEvent().
1793 gBS
->CheckEvent (TextIn
->WaitForKey
);
1800 Remove Text Input Device from Consplitter Text Input list.
1802 @param Private Text In Splitter pointer.
1803 @param TextIn Simple Text protocol pointer.
1805 @retval EFI_SUCCESS Simple Text Device removed successfully.
1806 @retval EFI_NOT_FOUND No Simple Text Device found.
1810 ConSplitterTextInDeleteDevice (
1811 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1812 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1817 // Remove the specified text-in device data structure from the Text In List,
1818 // and rearrange the remaining data structures in the Text In List.
1820 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
1821 if (Private
->TextInList
[Index
] == TextIn
) {
1822 for (; Index
< Private
->CurrentNumberOfConsoles
- 1; Index
++) {
1823 Private
->TextInList
[Index
] = Private
->TextInList
[Index
+ 1];
1826 Private
->CurrentNumberOfConsoles
--;
1831 return EFI_NOT_FOUND
;
1835 Add Text Input Ex Device in Consplitter Text Input Ex list.
1837 @param Private Text In Splitter pointer.
1838 @param TextInEx Simple Text Input Ex Input protocol pointer.
1840 @retval EFI_SUCCESS Text Input Ex Device added successfully.
1841 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1845 ConSplitterTextInExAddDevice (
1846 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1847 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1852 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
1853 UINTN TextInExListCount
;
1856 // Enlarge the NotifyHandleList and the TextInExList
1858 if (Private
->CurrentNumberOfExConsoles
>= Private
->TextInExListCount
) {
1859 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
1860 CurrentNotify
= TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link
);
1861 TextInExListCount
= Private
->TextInExListCount
;
1863 Status
= ConSplitterGrowBuffer (
1864 sizeof (EFI_HANDLE
),
1866 (VOID
**) &CurrentNotify
->NotifyHandleList
1868 if (EFI_ERROR (Status
)) {
1869 return EFI_OUT_OF_RESOURCES
;
1872 Status
= ConSplitterGrowBuffer (
1873 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
1874 &Private
->TextInExListCount
,
1875 (VOID
**) &Private
->TextInExList
1877 if (EFI_ERROR (Status
)) {
1878 return EFI_OUT_OF_RESOURCES
;
1883 // Register the key notify in the new text-in device
1885 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
1886 CurrentNotify
= TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link
);
1887 Status
= TextInEx
->RegisterKeyNotify (
1889 &CurrentNotify
->KeyData
,
1890 CurrentNotify
->KeyNotificationFn
,
1891 &CurrentNotify
->NotifyHandleList
[Private
->CurrentNumberOfExConsoles
]
1893 if (EFI_ERROR (Status
)) {
1894 for (Link
= Link
->BackLink
; Link
!= &Private
->NotifyList
; Link
= Link
->BackLink
) {
1895 CurrentNotify
= TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link
);
1896 TextInEx
->UnregisterKeyNotify (
1898 CurrentNotify
->NotifyHandleList
[Private
->CurrentNumberOfExConsoles
]
1906 // Add the new text-in device data structure into the Text Input Ex List.
1908 Private
->TextInExList
[Private
->CurrentNumberOfExConsoles
] = TextInEx
;
1909 Private
->CurrentNumberOfExConsoles
++;
1912 // Extra CheckEvent added to reduce the double CheckEvent().
1914 gBS
->CheckEvent (TextInEx
->WaitForKeyEx
);
1920 Remove Text Ex Device from Consplitter Text Input Ex list.
1922 @param Private Text In Splitter pointer.
1923 @param TextInEx Simple Text Ex protocol pointer.
1925 @retval EFI_SUCCESS Simple Text Input Ex Device removed successfully.
1926 @retval EFI_NOT_FOUND No Simple Text Input Ex Device found.
1930 ConSplitterTextInExDeleteDevice (
1931 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1932 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1937 // Remove the specified text-in device data structure from the Text Input Ex List,
1938 // and rearrange the remaining data structures in the Text In List.
1940 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
1941 if (Private
->TextInExList
[Index
] == TextInEx
) {
1942 for (; Index
< Private
->CurrentNumberOfExConsoles
- 1; Index
++) {
1943 Private
->TextInExList
[Index
] = Private
->TextInExList
[Index
+ 1];
1946 Private
->CurrentNumberOfExConsoles
--;
1951 return EFI_NOT_FOUND
;
1956 Add Simple Pointer Device in Consplitter Simple Pointer list.
1958 @param Private Text In Splitter pointer.
1959 @param SimplePointer Simple Pointer protocol pointer.
1961 @retval EFI_SUCCESS Simple Pointer Device added successfully.
1962 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1966 ConSplitterSimplePointerAddDevice (
1967 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1968 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
1974 // If the Simple Pointer List is full, enlarge it by calling ConSplitterGrowBuffer().
1976 if (Private
->CurrentNumberOfPointers
>= Private
->PointerListCount
) {
1977 Status
= ConSplitterGrowBuffer (
1978 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
1979 &Private
->PointerListCount
,
1980 (VOID
**) &Private
->PointerList
1982 if (EFI_ERROR (Status
)) {
1983 return EFI_OUT_OF_RESOURCES
;
1987 // Add the new text-in device data structure into the Simple Pointer List.
1989 Private
->PointerList
[Private
->CurrentNumberOfPointers
] = SimplePointer
;
1990 Private
->CurrentNumberOfPointers
++;
1997 Remove Simple Pointer Device from Consplitter Simple Pointer list.
1999 @param Private Text In Splitter pointer.
2000 @param SimplePointer Simple Pointer protocol pointer.
2002 @retval EFI_SUCCESS Simple Pointer Device removed successfully.
2003 @retval EFI_NOT_FOUND No Simple Pointer Device found.
2007 ConSplitterSimplePointerDeleteDevice (
2008 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2009 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
2014 // Remove the specified text-in device data structure from the Simple Pointer List,
2015 // and rearrange the remaining data structures in the Text In List.
2017 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
2018 if (Private
->PointerList
[Index
] == SimplePointer
) {
2019 for (; Index
< Private
->CurrentNumberOfPointers
- 1; Index
++) {
2020 Private
->PointerList
[Index
] = Private
->PointerList
[Index
+ 1];
2023 Private
->CurrentNumberOfPointers
--;
2028 return EFI_NOT_FOUND
;
2033 Add Absolute Pointer Device in Consplitter Absolute Pointer list.
2035 @param Private Text In Splitter pointer.
2036 @param AbsolutePointer Absolute Pointer protocol pointer.
2038 @retval EFI_SUCCESS Absolute Pointer Device added successfully.
2039 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2043 ConSplitterAbsolutePointerAddDevice (
2044 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2045 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2051 // If the Absolute Pointer List is full, enlarge it by calling ConSplitterGrowBuffer().
2053 if (Private
->CurrentNumberOfAbsolutePointers
>= Private
->AbsolutePointerListCount
) {
2054 Status
= ConSplitterGrowBuffer (
2055 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
2056 &Private
->AbsolutePointerListCount
,
2057 (VOID
**) &Private
->AbsolutePointerList
2059 if (EFI_ERROR (Status
)) {
2060 return EFI_OUT_OF_RESOURCES
;
2064 // Add the new text-in device data structure into the Absolute Pointer List.
2066 Private
->AbsolutePointerList
[Private
->CurrentNumberOfAbsolutePointers
] = AbsolutePointer
;
2067 Private
->CurrentNumberOfAbsolutePointers
++;
2074 Remove Absolute Pointer Device from Consplitter Absolute Pointer list.
2076 @param Private Text In Splitter pointer.
2077 @param AbsolutePointer Absolute Pointer protocol pointer.
2079 @retval EFI_SUCCESS Absolute Pointer Device removed successfully.
2080 @retval EFI_NOT_FOUND No Absolute Pointer Device found.
2084 ConSplitterAbsolutePointerDeleteDevice (
2085 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2086 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2091 // Remove the specified text-in device data structure from the Absolute Pointer List,
2092 // and rearrange the remaining data structures from the Absolute Pointer List.
2094 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
2095 if (Private
->AbsolutePointerList
[Index
] == AbsolutePointer
) {
2096 for (; Index
< Private
->CurrentNumberOfAbsolutePointers
- 1; Index
++) {
2097 Private
->AbsolutePointerList
[Index
] = Private
->AbsolutePointerList
[Index
+ 1];
2100 Private
->CurrentNumberOfAbsolutePointers
--;
2105 return EFI_NOT_FOUND
;
2109 Reallocate Text Out mode map.
2111 Allocate new buffer and copy original buffer into the new buffer.
2113 @param Private Consplitter Text Out pointer.
2115 @retval EFI_SUCCESS Buffer size has grown
2116 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2120 ConSplitterGrowMapTable (
2121 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2127 INT32
*TextOutModeMap
;
2128 INT32
*OldTextOutModeMap
;
2132 NewSize
= Private
->TextOutListCount
* sizeof (INT32
);
2133 OldTextOutModeMap
= Private
->TextOutModeMap
;
2134 TotalSize
= NewSize
* (Private
->TextOutQueryDataCount
);
2137 // Allocate new buffer for Text Out List.
2139 TextOutModeMap
= AllocatePool (TotalSize
);
2140 if (TextOutModeMap
== NULL
) {
2141 return EFI_OUT_OF_RESOURCES
;
2144 SetMem (TextOutModeMap
, TotalSize
, 0xFF);
2145 Private
->TextOutModeMap
= TextOutModeMap
;
2148 // If TextOutList has been enlarged, need to realloc the mode map table
2149 // The mode map table is regarded as a two dimension array.
2152 // 0 ---------> TextOutListCount ----> TextOutListCount
2153 // | -------------------------------------------
2160 // -------------------------------------------
2163 if (OldTextOutModeMap
!= NULL
) {
2165 Size
= Private
->CurrentNumberOfConsoles
* sizeof (INT32
);
2167 SrcAddress
= OldTextOutModeMap
;
2170 // Copy the old data to the new one
2172 while (Index
< Private
->TextOutMode
.MaxMode
) {
2173 CopyMem (TextOutModeMap
, SrcAddress
, Size
);
2174 TextOutModeMap
+= NewSize
;
2179 // Free the old buffer
2181 FreePool (OldTextOutModeMap
);
2189 Add new device's output mode to console splitter's mode list.
2191 @param Private Text Out Splitter pointer
2192 @param TextOut Simple Text Output protocol pointer.
2194 @retval EFI_SUCCESS Device added successfully.
2195 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2199 ConSplitterAddOutputMode (
2200 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2201 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2209 MaxMode
= TextOut
->Mode
->MaxMode
;
2210 Private
->TextOutMode
.MaxMode
= MaxMode
;
2213 // Grow the buffer if query data buffer is not large enough to
2214 // hold all the mode supported by the first console.
2216 while (MaxMode
> (INT32
) Private
->TextOutQueryDataCount
) {
2217 Status
= ConSplitterGrowBuffer (
2218 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
2219 &Private
->TextOutQueryDataCount
,
2220 (VOID
**) &Private
->TextOutQueryData
2222 if (EFI_ERROR (Status
)) {
2223 return EFI_OUT_OF_RESOURCES
;
2227 // Allocate buffer for the output mode map
2229 Status
= ConSplitterGrowMapTable (Private
);
2230 if (EFI_ERROR (Status
)) {
2231 return EFI_OUT_OF_RESOURCES
;
2234 // As the first textout device, directly add the mode in to QueryData
2235 // and at the same time record the mapping between QueryData and TextOut.
2239 while (Mode
< MaxMode
) {
2240 Status
= TextOut
->QueryMode (
2243 &Private
->TextOutQueryData
[Mode
].Columns
,
2244 &Private
->TextOutQueryData
[Mode
].Rows
2247 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData
2250 if ((EFI_ERROR(Status
)) && (Mode
== 1)) {
2251 Private
->TextOutQueryData
[Mode
].Columns
= 0;
2252 Private
->TextOutQueryData
[Mode
].Rows
= 0;
2254 Private
->TextOutModeMap
[Index
] = Mode
;
2256 Index
+= Private
->TextOutListCount
;
2263 Reconstruct TextOutModeMap to get intersection of modes.
2265 This routine reconstruct TextOutModeMap to get the intersection
2266 of modes for all console out devices. Because EFI/UEFI spec require
2267 mode 0 is 80x25, mode 1 is 80x50, this routine will not check the
2268 intersection for mode 0 and mode 1.
2270 @param TextOutModeMap Current text out mode map, begin with the mode 80x25
2271 @param NewlyAddedMap New text out mode map, begin with the mode 80x25
2272 @param MapStepSize Mode step size for one console device
2273 @param NewMapStepSize New Mode step size for one console device
2274 @param MaxMode IN: Current max text mode, OUT: Updated max text mode.
2275 @param CurrentMode IN: Current text mode, OUT: Updated current text mode.
2279 ConSplitterGetIntersection (
2280 IN INT32
*TextOutModeMap
,
2281 IN INT32
*NewlyAddedMap
,
2282 IN UINTN MapStepSize
,
2283 IN UINTN NewMapStepSize
,
2284 IN OUT INT32
*MaxMode
,
2285 IN OUT INT32
*CurrentMode
2289 INT32
*CurrentMapEntry
;
2290 INT32
*NextMapEntry
;
2292 INT32 CurrentMaxMode
;
2296 // According to EFI/UEFI spec, mode 0 and mode 1 have been reserved
2297 // for 80x25 and 80x50 in Simple Text Out protocol, so don't make intersection
2298 // for mode 0 and mode 1, mode number starts from 2.
2301 CurrentMapEntry
= &TextOutModeMap
[MapStepSize
* 2];
2302 NextMapEntry
= CurrentMapEntry
;
2303 NewMapEntry
= &NewlyAddedMap
[NewMapStepSize
* 2];
2305 CurrentMaxMode
= *MaxMode
;
2306 Mode
= *CurrentMode
;
2308 while (Index
< CurrentMaxMode
) {
2309 if (*NewMapEntry
== -1) {
2311 // This mode is not supported any more. Remove it. Special care
2312 // must be taken as this remove will also affect current mode;
2314 if (Index
== *CurrentMode
) {
2316 } else if (Index
< *CurrentMode
) {
2321 if (CurrentMapEntry
!= NextMapEntry
) {
2322 CopyMem (NextMapEntry
, CurrentMapEntry
, MapStepSize
* sizeof (INT32
));
2325 NextMapEntry
+= MapStepSize
;
2328 CurrentMapEntry
+= MapStepSize
;
2329 NewMapEntry
+= NewMapStepSize
;
2333 *CurrentMode
= Mode
;
2339 Sync the device's output mode to console splitter's mode list.
2341 @param Private Text Out Splitter pointer.
2342 @param TextOut Simple Text Output protocol pointer.
2346 ConSplitterSyncOutputMode (
2347 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2348 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2351 INT32 CurrentMaxMode
;
2354 INT32
*TextOutModeMap
;
2357 TEXT_OUT_SPLITTER_QUERY_DATA
*TextOutQueryData
;
2364 // Must make sure that current mode won't change even if mode number changes
2366 CurrentMaxMode
= Private
->TextOutMode
.MaxMode
;
2367 TextOutModeMap
= Private
->TextOutModeMap
;
2368 StepSize
= Private
->TextOutListCount
;
2369 TextOutQueryData
= Private
->TextOutQueryData
;
2372 // Query all the mode that the newly added TextOut supports
2375 MapTable
= TextOutModeMap
+ Private
->CurrentNumberOfConsoles
;
2376 while (Mode
< TextOut
->Mode
->MaxMode
) {
2377 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Columns
, &Rows
);
2379 if (EFI_ERROR(Status
)) {
2382 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData
2385 MapTable
[StepSize
] = Mode
;
2386 TextOutQueryData
[Mode
].Columns
= 0;
2387 TextOutQueryData
[Mode
].Rows
= 0;
2393 // Search the intersection map and QueryData database to see if they intersects
2396 while (Index
< CurrentMaxMode
) {
2397 QueryMode
= *(TextOutModeMap
+ Index
* StepSize
);
2398 if ((TextOutQueryData
[QueryMode
].Rows
== Rows
) && (TextOutQueryData
[QueryMode
].Columns
== Columns
)) {
2399 MapTable
[Index
* StepSize
] = Mode
;
2407 // Now search the TextOutModeMap table to find the intersection of supported
2408 // mode between ConSplitter and the newly added device.
2410 ConSplitterGetIntersection (
2415 &Private
->TextOutMode
.MaxMode
,
2416 &Private
->TextOutMode
.Mode
2424 Sync output device between ConOut and StdErr output.
2426 @retval EFI_SUCCESS Sync implemented successfully.
2427 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2431 ConSplitterGetIntersectionBetweenConOutAndStrErr (
2435 UINTN ConOutNumOfConsoles
;
2436 UINTN StdErrNumOfConsoles
;
2437 TEXT_OUT_AND_GOP_DATA
*ConOutTextOutList
;
2438 TEXT_OUT_AND_GOP_DATA
*StdErrTextOutList
;
2442 UINTN ConOutColumns
;
2444 UINTN StdErrColumns
;
2445 INT32 ConOutMaxMode
;
2446 INT32 StdErrMaxMode
;
2451 INT32
*ConOutModeMap
;
2452 INT32
*StdErrModeMap
;
2453 INT32
*ConOutMapTable
;
2454 INT32
*StdErrMapTable
;
2455 TEXT_OUT_SPLITTER_QUERY_DATA
*ConOutQueryData
;
2456 TEXT_OUT_SPLITTER_QUERY_DATA
*StdErrQueryData
;
2457 UINTN ConOutStepSize
;
2458 UINTN StdErrStepSize
;
2459 BOOLEAN FoundTheSameTextOut
;
2460 UINTN ConOutMapTableSize
;
2461 UINTN StdErrMapTableSize
;
2463 ConOutNumOfConsoles
= mConOut
.CurrentNumberOfConsoles
;
2464 StdErrNumOfConsoles
= mStdErr
.CurrentNumberOfConsoles
;
2465 ConOutTextOutList
= mConOut
.TextOutList
;
2466 StdErrTextOutList
= mStdErr
.TextOutList
;
2469 FoundTheSameTextOut
= FALSE
;
2470 while ((Indexi
< ConOutNumOfConsoles
) && (!FoundTheSameTextOut
)) {
2472 while (Indexj
< StdErrNumOfConsoles
) {
2473 if (ConOutTextOutList
->TextOut
== StdErrTextOutList
->TextOut
) {
2474 FoundTheSameTextOut
= TRUE
;
2479 StdErrTextOutList
++;
2483 ConOutTextOutList
++;
2486 if (!FoundTheSameTextOut
) {
2490 // Must make sure that current mode won't change even if mode number changes
2492 ConOutMaxMode
= mConOut
.TextOutMode
.MaxMode
;
2493 ConOutModeMap
= mConOut
.TextOutModeMap
;
2494 ConOutStepSize
= mConOut
.TextOutListCount
;
2495 ConOutQueryData
= mConOut
.TextOutQueryData
;
2497 StdErrMaxMode
= mStdErr
.TextOutMode
.MaxMode
;
2498 StdErrModeMap
= mStdErr
.TextOutModeMap
;
2499 StdErrStepSize
= mStdErr
.TextOutListCount
;
2500 StdErrQueryData
= mStdErr
.TextOutQueryData
;
2503 // Allocate the map table and set the map table's index to -1.
2505 ConOutMapTableSize
= ConOutMaxMode
* sizeof (INT32
);
2506 ConOutMapTable
= AllocateZeroPool (ConOutMapTableSize
);
2507 if (ConOutMapTable
== NULL
) {
2508 return EFI_OUT_OF_RESOURCES
;
2511 SetMem (ConOutMapTable
, ConOutMapTableSize
, 0xFF);
2513 StdErrMapTableSize
= StdErrMaxMode
* sizeof (INT32
);
2514 StdErrMapTable
= AllocateZeroPool (StdErrMapTableSize
);
2515 if (StdErrMapTable
== NULL
) {
2516 return EFI_OUT_OF_RESOURCES
;
2519 SetMem (StdErrMapTable
, StdErrMapTableSize
, 0xFF);
2522 // Find the intersection of the two set of modes. If they actually intersect, the
2523 // correponding entry in the map table is set to 1.
2526 while (Mode
< ConOutMaxMode
) {
2528 // Search the intersection map and QueryData database to see if they intersect
2531 ConOutMode
= *(ConOutModeMap
+ Mode
* ConOutStepSize
);
2532 ConOutRows
= ConOutQueryData
[ConOutMode
].Rows
;
2533 ConOutColumns
= ConOutQueryData
[ConOutMode
].Columns
;
2534 while (Index
< StdErrMaxMode
) {
2535 StdErrMode
= *(StdErrModeMap
+ Index
* StdErrStepSize
);
2536 StdErrRows
= StdErrQueryData
[StdErrMode
].Rows
;
2537 StdErrColumns
= StdErrQueryData
[StdErrMode
].Columns
;
2538 if ((StdErrRows
== ConOutRows
) && (StdErrColumns
== ConOutColumns
)) {
2539 ConOutMapTable
[Mode
] = 1;
2540 StdErrMapTable
[Index
] = 1;
2550 // Now search the TextOutModeMap table to find the intersection of supported
2551 // mode between ConSplitter and the newly added device.
2553 ConSplitterGetIntersection (
2556 mConOut
.TextOutListCount
,
2558 &(mConOut
.TextOutMode
.MaxMode
),
2559 &(mConOut
.TextOutMode
.Mode
)
2562 if (mConOut
.TextOutMode
.Mode
< 0) {
2563 mConOut
.TextOut
.SetMode (&(mConOut
.TextOut
), 0);
2566 ConSplitterGetIntersection (
2569 mStdErr
.TextOutListCount
,
2571 &(mStdErr
.TextOutMode
.MaxMode
),
2572 &(mStdErr
.TextOutMode
.Mode
)
2575 if (mStdErr
.TextOutMode
.Mode
< 0) {
2576 mStdErr
.TextOut
.SetMode (&(mStdErr
.TextOut
), 0);
2579 FreePool (ConOutMapTable
);
2580 FreePool (StdErrMapTable
);
2587 Add Grahpics Output modes into Consplitter Text Out list.
2589 @param Private Text Out Splitter pointer.
2590 @param GraphicsOutput Graphics Output protocol pointer.
2591 @param UgaDraw UGA Draw protocol pointer.
2593 @retval EFI_SUCCESS Output mode added successfully.
2594 @retval other Failed to add output mode.
2598 ConSplitterAddGraphicsOutputMode (
2599 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2600 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2601 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2607 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
;
2609 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
2610 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*CurrentGraphicsOutputMode
;
2611 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*ModeBuffer
;
2612 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*MatchedMode
;
2615 BOOLEAN AlreadyExist
;
2616 UINT32 UgaHorizontalResolution
;
2617 UINT32 UgaVerticalResolution
;
2618 UINT32 UgaColorDepth
;
2619 UINT32 UgaRefreshRate
;
2621 ASSERT (GraphicsOutput
!= NULL
|| UgaDraw
!= NULL
);
2623 CurrentGraphicsOutputMode
= Private
->GraphicsOutput
.Mode
;
2627 Status
= EFI_SUCCESS
;
2629 if (Private
->CurrentNumberOfUgaDraw
!= 0) {
2631 // If any UGA device has already been added, then there is no need to
2632 // calculate intersection of display mode of different GOP/UGA device,
2633 // since only one display mode will be exported (i.e. user-defined mode)
2638 if (GraphicsOutput
!= NULL
) {
2639 if (Private
->CurrentNumberOfGraphicsOutput
== 0) {
2641 // This is the first Graphics Output device added
2643 CurrentGraphicsOutputMode
->MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
2644 CurrentGraphicsOutputMode
->Mode
= GraphicsOutput
->Mode
->Mode
;
2645 CopyMem (CurrentGraphicsOutputMode
->Info
, GraphicsOutput
->Mode
->Info
, GraphicsOutput
->Mode
->SizeOfInfo
);
2646 CurrentGraphicsOutputMode
->SizeOfInfo
= GraphicsOutput
->Mode
->SizeOfInfo
;
2647 CurrentGraphicsOutputMode
->FrameBufferBase
= GraphicsOutput
->Mode
->FrameBufferBase
;
2648 CurrentGraphicsOutputMode
->FrameBufferSize
= GraphicsOutput
->Mode
->FrameBufferSize
;
2651 // Allocate resource for the private mode buffer
2653 ModeBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
) * GraphicsOutput
->Mode
->MaxMode
);
2654 if (ModeBuffer
== NULL
) {
2655 return EFI_OUT_OF_RESOURCES
;
2657 FreePool (Private
->GraphicsOutputModeBuffer
);
2658 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2661 // Store all supported display modes to the private mode buffer
2664 for (Index
= 0; Index
< GraphicsOutput
->Mode
->MaxMode
; Index
++) {
2666 // The Info buffer would be allocated by callee
2668 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) Index
, &SizeOfInfo
, &Info
);
2669 if (EFI_ERROR (Status
)) {
2672 ASSERT ( SizeOfInfo
<= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2673 CopyMem (Mode
, Info
, SizeOfInfo
);
2679 // Check intersection of display mode
2681 ModeBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
) * CurrentGraphicsOutputMode
->MaxMode
);
2682 if (ModeBuffer
== NULL
) {
2683 return EFI_OUT_OF_RESOURCES
;
2686 MatchedMode
= ModeBuffer
;
2687 Mode
= &Private
->GraphicsOutputModeBuffer
[0];
2688 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2691 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
2693 // The Info buffer would be allocated by callee
2695 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
2696 if (EFI_ERROR (Status
)) {
2699 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2700 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2702 // If GOP device supports one mode in current mode buffer,
2703 // it will be added into matched mode buffer
2713 AlreadyExist
= FALSE
;
2716 // Check if GOP mode has been in the mode buffer, ModeBuffer = MatchedMode at begin.
2718 for (Info
= ModeBuffer
; Info
< MatchedMode
; Info
++) {
2719 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2720 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2721 AlreadyExist
= TRUE
;
2726 if (!AlreadyExist
) {
2727 CopyMem (MatchedMode
, Mode
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2730 // Physical frame buffer is no longer available, change PixelFormat to PixelBltOnly
2732 MatchedMode
->Version
= 0;
2733 MatchedMode
->PixelFormat
= PixelBltOnly
;
2734 ZeroMem (&MatchedMode
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2744 // Drop the old mode buffer, assign it to a new one
2746 FreePool (Private
->GraphicsOutputModeBuffer
);
2747 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2750 // Physical frame buffer is no longer available when there are more than one physical GOP devices
2752 CurrentGraphicsOutputMode
->MaxMode
= (UINT32
) (((UINTN
) MatchedMode
- (UINTN
) ModeBuffer
) / sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2753 CurrentGraphicsOutputMode
->Info
->PixelFormat
= PixelBltOnly
;
2754 ZeroMem (&CurrentGraphicsOutputMode
->Info
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2755 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2756 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2757 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2761 // Graphics console driver can ensure the same mode for all GOP devices
2763 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2764 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2765 if ((Mode
->HorizontalResolution
== GraphicsOutput
->Mode
->Info
->HorizontalResolution
) &&
2766 (Mode
->VerticalResolution
== GraphicsOutput
->Mode
->Info
->VerticalResolution
)) {
2767 CurrentIndex
= Index
;
2771 if (Index
>= CurrentGraphicsOutputMode
->MaxMode
) {
2773 // if user defined mode is not found, set to default mode 800x600
2775 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2776 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2777 if ((Mode
->HorizontalResolution
== 800) && (Mode
->VerticalResolution
== 600)) {
2778 CurrentIndex
= Index
;
2783 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2785 // Graphics console driver can ensure the same mode for all GOP devices
2786 // so we can get the current mode from this video device
2790 &UgaHorizontalResolution
,
2791 &UgaVerticalResolution
,
2796 CurrentGraphicsOutputMode
->MaxMode
= 1;
2797 Info
= CurrentGraphicsOutputMode
->Info
;
2799 Info
->HorizontalResolution
= UgaHorizontalResolution
;
2800 Info
->VerticalResolution
= UgaVerticalResolution
;
2801 Info
->PixelFormat
= PixelBltOnly
;
2802 Info
->PixelsPerScanLine
= UgaHorizontalResolution
;
2803 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2804 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2805 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2808 // Update the private mode buffer
2810 CopyMem (&Private
->GraphicsOutputModeBuffer
[0], Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2813 // Only mode 0 is available to be set
2820 if (GraphicsOutput
!= NULL
) {
2821 Private
->CurrentNumberOfGraphicsOutput
++;
2823 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2824 Private
->CurrentNumberOfUgaDraw
++;
2828 // Force GraphicsOutput mode to be set,
2831 Mode
= &Private
->GraphicsOutputModeBuffer
[CurrentIndex
];
2832 if ((GraphicsOutput
!= NULL
) &&
2833 (Mode
->HorizontalResolution
== CurrentGraphicsOutputMode
->Info
->HorizontalResolution
) &&
2834 (Mode
->VerticalResolution
== CurrentGraphicsOutputMode
->Info
->VerticalResolution
)) {
2835 CurrentGraphicsOutputMode
->Mode
= (UINT32
) CurrentIndex
;
2836 if ((Mode
->HorizontalResolution
!= GraphicsOutput
->Mode
->Info
->HorizontalResolution
) ||
2837 (Mode
->VerticalResolution
!= GraphicsOutput
->Mode
->Info
->VerticalResolution
)) {
2839 // If all existing video device has been set to common mode, only set new GOP device to
2842 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
2843 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
2844 if (EFI_ERROR (Status
)) {
2847 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) && (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2853 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
2857 // Current mode number may need update now, so set it to an invalid mode number
2859 CurrentGraphicsOutputMode
->Mode
= 0xffff;
2861 // Graphics console can ensure all GOP devices have the same mode which can be taken as current mode.
2863 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, (UINT32
) CurrentIndex
);
2864 if (EFI_ERROR(Status
)) {
2866 // If user defined mode is not valid for display device, set to the default mode 800x600.
2868 (Private
->GraphicsOutputModeBuffer
[0]).HorizontalResolution
= 800;
2869 (Private
->GraphicsOutputModeBuffer
[0]).VerticalResolution
= 600;
2870 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, 0);
2878 Set the current console out mode.
2880 This routine will get the current console mode information (column, row)
2881 from ConsoleOutMode variable and set it; if the variable does not exist,
2882 set to user defined console mode.
2884 @param Private Consplitter Text Out pointer.
2888 ConsplitterSetConsoleOutMode (
2889 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2899 CONSOLE_OUT_MODE ModeInfo
;
2900 CONSOLE_OUT_MODE MaxModeInfo
;
2901 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
2905 TextOut
= &Private
->TextOut
;
2906 MaxMode
= (UINTN
) (TextOut
->Mode
->MaxMode
);
2908 MaxModeInfo
.Column
= 0;
2909 MaxModeInfo
.Row
= 0;
2910 ModeInfo
.Column
= PcdGet32 (PcdConOutColumn
);
2911 ModeInfo
.Row
= PcdGet32 (PcdConOutRow
);
2914 // To find the prefer mode and basic mode from Text Out mode list
2916 for (Mode
= 0; Mode
< MaxMode
; Mode
++) {
2917 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Col
, &Row
);
2918 if (!EFI_ERROR(Status
)) {
2919 if ((ModeInfo
.Column
!= 0) && (ModeInfo
.Row
!= 0)) {
2921 // Use user defined column and row
2923 if (Col
== ModeInfo
.Column
&& Row
== ModeInfo
.Row
) {
2928 // If user sets PcdConOutColumn or PcdConOutRow to 0,
2929 // find and set the highest text mode.
2931 if ((Col
>= MaxModeInfo
.Column
) && (Row
>= MaxModeInfo
.Row
)) {
2932 MaxModeInfo
.Column
= Col
;
2933 MaxModeInfo
.Row
= Row
;
2937 if (Col
== 80 && Row
== 25) {
2944 // Set prefer mode to Text Out devices.
2946 Status
= TextOut
->SetMode (TextOut
, PreferMode
);
2947 if (EFI_ERROR(Status
)) {
2949 // if current mode setting is failed, default 80x25 mode will be set.
2951 Status
= TextOut
->SetMode (TextOut
, BaseMode
);
2952 ASSERT(!EFI_ERROR(Status
));
2954 PcdSet32 (PcdConOutColumn
, 80);
2955 PcdSet32 (PcdConOutRow
, 25);
2963 Add Text Output Device in Consplitter Text Output list.
2965 @param Private Text Out Splitter pointer.
2966 @param TextOut Simple Text Output protocol pointer.
2967 @param GraphicsOutput Graphics Output protocol pointer.
2968 @param UgaDraw UGA Draw protocol pointer.
2970 @retval EFI_SUCCESS Text Output Device added successfully.
2971 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2975 ConSplitterTextOutAddDevice (
2976 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2977 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
,
2978 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2979 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2983 UINTN CurrentNumOfConsoles
;
2985 UINT32 UgaHorizontalResolution
;
2986 UINT32 UgaVerticalResolution
;
2987 UINT32 UgaColorDepth
;
2988 UINT32 UgaRefreshRate
;
2989 TEXT_OUT_AND_GOP_DATA
*TextAndGop
;
2991 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
2992 EFI_STATUS DeviceStatus
;
2994 Status
= EFI_SUCCESS
;
2995 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
2998 // If the Text Out List is full, enlarge it by calling ConSplitterGrowBuffer().
3000 while (CurrentNumOfConsoles
>= Private
->TextOutListCount
) {
3001 Status
= ConSplitterGrowBuffer (
3002 sizeof (TEXT_OUT_AND_GOP_DATA
),
3003 &Private
->TextOutListCount
,
3004 (VOID
**) &Private
->TextOutList
3006 if (EFI_ERROR (Status
)) {
3007 return EFI_OUT_OF_RESOURCES
;
3010 // Also need to reallocate the TextOutModeMap table
3012 Status
= ConSplitterGrowMapTable (Private
);
3013 if (EFI_ERROR (Status
)) {
3014 return EFI_OUT_OF_RESOURCES
;
3018 TextAndGop
= &Private
->TextOutList
[CurrentNumOfConsoles
];
3020 TextAndGop
->TextOut
= TextOut
;
3021 TextAndGop
->GraphicsOutput
= GraphicsOutput
;
3022 TextAndGop
->UgaDraw
= UgaDraw
;
3024 if (CurrentNumOfConsoles
== 0) {
3026 // Add the first device's output mode to console splitter's mode list
3028 Status
= ConSplitterAddOutputMode (Private
, TextOut
);
3030 ConSplitterSyncOutputMode (Private
, TextOut
);
3033 Private
->CurrentNumberOfConsoles
++;
3036 // Scan both TextOutList, for the intersection TextOut device
3037 // maybe both ConOut and StdErr incorporate the same Text Out
3038 // device in them, thus the output of both should be synced.
3040 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3042 MaxMode
= Private
->TextOutMode
.MaxMode
;
3043 ASSERT (MaxMode
>= 1);
3045 DeviceStatus
= EFI_DEVICE_ERROR
;
3046 if (FeaturePcdGet (PcdConOutGopSupport
)) {
3048 // If GOP is produced by Consplitter, this device display mode will be added into Graphics Ouput modes.
3050 if ((GraphicsOutput
!= NULL
) || (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
))) {
3051 DeviceStatus
= ConSplitterAddGraphicsOutputMode (Private
, GraphicsOutput
, UgaDraw
);
3055 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
3057 // If UGA is produced by Consplitter
3059 if (GraphicsOutput
!= NULL
) {
3060 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, GraphicsOutput
->Mode
->Mode
, &SizeOfInfo
, &Info
);
3061 if (EFI_ERROR (Status
)) {
3064 ASSERT ( SizeOfInfo
<= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
3066 UgaHorizontalResolution
= Info
->HorizontalResolution
;
3067 UgaVerticalResolution
= Info
->VerticalResolution
;
3071 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3072 Status
= UgaDraw
->GetMode (
3074 &UgaHorizontalResolution
,
3075 &UgaVerticalResolution
,
3079 if (!EFI_ERROR (Status
) && EFI_ERROR (DeviceStatus
)) {
3081 // if GetMode is successfully and UGA device hasn't been set, set it
3083 Status
= ConSplitterUgaDrawSetMode (
3085 UgaHorizontalResolution
,
3086 UgaVerticalResolution
,
3092 // If GetMode/SetMode is failed, set to 800x600 mode
3094 if(EFI_ERROR (Status
)) {
3095 Status
= ConSplitterUgaDrawSetMode (
3107 // After adding new console device, all existing console devices should be
3108 // synced to the current shared mode.
3110 ConsplitterSetConsoleOutMode (Private
);
3117 Remove Text Out Device in Consplitter Text Out list.
3119 @param Private Text Out Splitter pointer.
3120 @param TextOut Simple Text Output Pointer protocol pointer.
3122 @retval EFI_SUCCESS Text Out Device removed successfully.
3123 @retval EFI_NOT_FOUND No Text Out Device found.
3127 ConSplitterTextOutDeleteDevice (
3128 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
3129 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
3133 UINTN CurrentNumOfConsoles
;
3134 TEXT_OUT_AND_GOP_DATA
*TextOutList
;
3138 // Remove the specified text-out device data structure from the Text out List,
3139 // and rearrange the remaining data structures in the Text out List.
3141 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
3142 Index
= (INT32
) CurrentNumOfConsoles
- 1;
3143 TextOutList
= Private
->TextOutList
;
3144 while (Index
>= 0) {
3145 if (TextOutList
->TextOut
== TextOut
) {
3146 if (TextOutList
->UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3147 Private
->CurrentNumberOfUgaDraw
--;
3149 if (TextOutList
->GraphicsOutput
!= NULL
) {
3150 Private
->CurrentNumberOfGraphicsOutput
--;
3152 CopyMem (TextOutList
, TextOutList
+ 1, sizeof (TEXT_OUT_AND_GOP_DATA
) * Index
);
3153 CurrentNumOfConsoles
--;
3161 // The specified TextOut is not managed by the ConSplitter driver
3164 return EFI_NOT_FOUND
;
3167 if (CurrentNumOfConsoles
== 0) {
3169 // If the number of consoles is zero, reset all parameters
3171 Private
->CurrentNumberOfConsoles
= 0;
3172 Private
->TextOutMode
.MaxMode
= 1;
3173 Private
->TextOutQueryData
[0].Columns
= 80;
3174 Private
->TextOutQueryData
[0].Rows
= 25;
3175 TextOutSetMode (Private
, 0);
3180 // Max Mode is realy an intersection of the QueryMode command to all
3181 // devices. So we must copy the QueryMode of the first device to
3185 Private
->TextOutQueryData
,
3186 Private
->TextOutQueryDataCount
* sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
)
3189 FreePool (Private
->TextOutModeMap
);
3190 Private
->TextOutModeMap
= NULL
;
3191 TextOutList
= Private
->TextOutList
;
3194 // Add the first TextOut to the QueryData array and ModeMap table
3196 Status
= ConSplitterAddOutputMode (Private
, TextOutList
->TextOut
);
3199 // Now add one by one
3202 Private
->CurrentNumberOfConsoles
= 1;
3204 while ((UINTN
) Index
< CurrentNumOfConsoles
) {
3205 ConSplitterSyncOutputMode (Private
, TextOutList
->TextOut
);
3207 Private
->CurrentNumberOfConsoles
++;
3211 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3218 Reset the input device and optionaly run diagnostics
3220 @param This Protocol instance pointer.
3221 @param ExtendedVerification Driver may perform diagnostics on reset.
3223 @retval EFI_SUCCESS The device was reset.
3224 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3230 ConSplitterTextInReset (
3231 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3232 IN BOOLEAN ExtendedVerification
3236 EFI_STATUS ReturnStatus
;
3237 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3240 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3242 Private
->KeyEventSignalState
= FALSE
;
3245 // return the worst status met
3247 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3248 Status
= Private
->TextInList
[Index
]->Reset (
3249 Private
->TextInList
[Index
],
3250 ExtendedVerification
3252 if (EFI_ERROR (Status
)) {
3253 ReturnStatus
= Status
;
3257 return ReturnStatus
;
3262 Reads the next keystroke from the input device. The WaitForKey Event can
3263 be used to test for existance of a keystroke via WaitForEvent () call.
3265 @param Private Protocol instance pointer.
3266 @param Key Driver may perform diagnostics on reset.
3268 @retval EFI_SUCCESS The keystroke information was returned.
3269 @retval EFI_NOT_READY There was no keystroke data availiable.
3270 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3276 ConSplitterTextInPrivateReadKeyStroke (
3277 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3278 OUT EFI_INPUT_KEY
*Key
3283 EFI_INPUT_KEY CurrentKey
;
3285 Key
->UnicodeChar
= 0;
3286 Key
->ScanCode
= SCAN_NULL
;
3289 // if no physical console input device exists, return EFI_NOT_READY;
3290 // if any physical console input device has key input,
3291 // return the key and EFI_SUCCESS.
3293 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3294 Status
= Private
->TextInList
[Index
]->ReadKeyStroke (
3295 Private
->TextInList
[Index
],
3298 if (!EFI_ERROR (Status
)) {
3304 return EFI_NOT_READY
;
3309 Reads the next keystroke from the input device. The WaitForKey Event can
3310 be used to test for existance of a keystroke via WaitForEvent () call.
3312 @param This Protocol instance pointer.
3313 @param Key Driver may perform diagnostics on reset.
3315 @retval EFI_SUCCESS The keystroke information was returned.
3316 @retval EFI_NOT_READY There was no keystroke data availiable.
3317 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3323 ConSplitterTextInReadKeyStroke (
3324 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3325 OUT EFI_INPUT_KEY
*Key
3328 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3330 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3332 Private
->KeyEventSignalState
= FALSE
;
3334 return ConSplitterTextInPrivateReadKeyStroke (Private
, Key
);
3339 This event aggregates all the events of the ConIn devices in the spliter.
3341 If any events of physical ConIn devices are signaled, signal the ConIn
3342 spliter event. This will cause the calling code to call
3343 ConSplitterTextInReadKeyStroke ().
3345 @param Event The Event assoicated with callback.
3346 @param Context Context registered when Event was created.
3351 ConSplitterTextInWaitForKey (
3357 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3360 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
3362 if (Private
->KeyEventSignalState
) {
3364 // If KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
3366 gBS
->SignalEvent (Event
);
3371 // If any physical console input device has key input, signal the event.
3373 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3374 Status
= gBS
->CheckEvent (Private
->TextInList
[Index
]->WaitForKey
);
3375 if (!EFI_ERROR (Status
)) {
3376 gBS
->SignalEvent (Event
);
3377 Private
->KeyEventSignalState
= TRUE
;
3385 Test if the key has been registered on input device.
3387 @param RegsiteredData A pointer to a buffer that is filled in with the
3388 keystroke state data for the key that was
3390 @param InputData A pointer to a buffer that is filled in with the
3391 keystroke state data for the key that was
3394 @retval TRUE Key be pressed matches a registered key.
3395 @retval FLASE Match failed.
3400 IN EFI_KEY_DATA
*RegsiteredData
,
3401 IN EFI_KEY_DATA
*InputData
3404 ASSERT (RegsiteredData
!= NULL
&& InputData
!= NULL
);
3406 if ((RegsiteredData
->Key
.ScanCode
!= InputData
->Key
.ScanCode
) ||
3407 (RegsiteredData
->Key
.UnicodeChar
!= InputData
->Key
.UnicodeChar
)) {
3412 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
3414 if (RegsiteredData
->KeyState
.KeyShiftState
!= 0 &&
3415 RegsiteredData
->KeyState
.KeyShiftState
!= InputData
->KeyState
.KeyShiftState
) {
3418 if (RegsiteredData
->KeyState
.KeyToggleState
!= 0 &&
3419 RegsiteredData
->KeyState
.KeyToggleState
!= InputData
->KeyState
.KeyToggleState
) {
3429 Reset the input device and optionaly run diagnostics
3431 @param This Protocol instance pointer.
3432 @param ExtendedVerification Driver may perform diagnostics on reset.
3434 @retval EFI_SUCCESS The device was reset.
3435 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3441 ConSplitterTextInResetEx (
3442 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3443 IN BOOLEAN ExtendedVerification
3447 EFI_STATUS ReturnStatus
;
3448 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3451 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3453 Private
->KeyEventSignalState
= FALSE
;
3456 // return the worst status met
3458 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3459 Status
= Private
->TextInExList
[Index
]->Reset (
3460 Private
->TextInExList
[Index
],
3461 ExtendedVerification
3463 if (EFI_ERROR (Status
)) {
3464 ReturnStatus
= Status
;
3468 return ReturnStatus
;
3474 Reads the next keystroke from the input device. The WaitForKey Event can
3475 be used to test for existance of a keystroke via WaitForEvent () call.
3477 @param This Protocol instance pointer.
3478 @param KeyData A pointer to a buffer that is filled in with the
3479 keystroke state data for the key that was
3482 @retval EFI_SUCCESS The keystroke information was returned.
3483 @retval EFI_NOT_READY There was no keystroke data availiable.
3484 @retval EFI_DEVICE_ERROR The keystroke information was not returned due
3486 @retval EFI_INVALID_PARAMETER KeyData is NULL.
3491 ConSplitterTextInReadKeyStrokeEx (
3492 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3493 OUT EFI_KEY_DATA
*KeyData
3496 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3499 EFI_KEY_DATA CurrentKeyData
;
3502 if (KeyData
== NULL
) {
3503 return EFI_INVALID_PARAMETER
;
3506 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3508 Private
->KeyEventSignalState
= FALSE
;
3510 KeyData
->Key
.UnicodeChar
= 0;
3511 KeyData
->Key
.ScanCode
= SCAN_NULL
;
3514 // if no physical console input device exists, return EFI_NOT_READY;
3515 // if any physical console input device has key input,
3516 // return the key and EFI_SUCCESS.
3518 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3519 Status
= Private
->TextInExList
[Index
]->ReadKeyStrokeEx (
3520 Private
->TextInExList
[Index
],
3523 if (!EFI_ERROR (Status
)) {
3524 CopyMem (KeyData
, &CurrentKeyData
, sizeof (CurrentKeyData
));
3529 return EFI_NOT_READY
;
3534 Set certain state for the input device.
3536 @param This Protocol instance pointer.
3537 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
3538 state for the input device.
3540 @retval EFI_SUCCESS The device state was set successfully.
3541 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
3542 could not have the setting adjusted.
3543 @retval EFI_UNSUPPORTED The device does not have the ability to set its
3545 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
3550 ConSplitterTextInSetState (
3551 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3552 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
3555 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3559 if (KeyToggleState
== NULL
) {
3560 return EFI_INVALID_PARAMETER
;
3563 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3566 // if no physical console input device exists, return EFI_SUCCESS;
3567 // otherwise return the status of setting state of physical console input device
3569 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3570 Status
= Private
->TextInExList
[Index
]->SetState (
3571 Private
->TextInExList
[Index
],
3574 if (EFI_ERROR (Status
)) {
3585 Register a notification function for a particular keystroke for the input device.
3587 @param This Protocol instance pointer.
3588 @param KeyData A pointer to a buffer that is filled in with the
3589 keystroke information data for the key that was
3591 @param KeyNotificationFunction Points to the function to be called when the key
3592 sequence is typed specified by KeyData.
3593 @param NotifyHandle Points to the unique handle assigned to the
3594 registered notification.
3596 @retval EFI_SUCCESS The notification function was registered
3598 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data
3600 @retval EFI_INVALID_PARAMETER KeyData or KeyNotificationFunction or NotifyHandle is NULL.
3605 ConSplitterTextInRegisterKeyNotify (
3606 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3607 IN EFI_KEY_DATA
*KeyData
,
3608 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction
,
3609 OUT EFI_HANDLE
*NotifyHandle
3612 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3615 TEXT_IN_EX_SPLITTER_NOTIFY
*NewNotify
;
3617 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3620 if (KeyData
== NULL
|| NotifyHandle
== NULL
|| KeyNotificationFunction
== NULL
) {
3621 return EFI_INVALID_PARAMETER
;
3624 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3627 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
3629 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3630 CurrentNotify
= TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link
);
3631 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
3632 if (CurrentNotify
->KeyNotificationFn
== KeyNotificationFunction
) {
3633 *NotifyHandle
= CurrentNotify
->NotifyHandle
;
3640 // Allocate resource to save the notification function
3642 NewNotify
= (TEXT_IN_EX_SPLITTER_NOTIFY
*) AllocateZeroPool (sizeof (TEXT_IN_EX_SPLITTER_NOTIFY
));
3643 if (NewNotify
== NULL
) {
3644 return EFI_OUT_OF_RESOURCES
;
3646 NewNotify
->NotifyHandleList
= (EFI_HANDLE
*) AllocateZeroPool (sizeof (EFI_HANDLE
) * Private
->TextInExListCount
);
3647 if (NewNotify
->NotifyHandleList
== NULL
) {
3648 gBS
->FreePool (NewNotify
);
3649 return EFI_OUT_OF_RESOURCES
;
3651 NewNotify
->Signature
= TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
;
3652 NewNotify
->KeyNotificationFn
= KeyNotificationFunction
;
3653 NewNotify
->NotifyHandle
= (EFI_HANDLE
) NewNotify
;
3654 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (EFI_KEY_DATA
));
3657 // Return the wrong status of registering key notify of
3658 // physical console input device if meet problems
3660 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3661 Status
= Private
->TextInExList
[Index
]->RegisterKeyNotify (
3662 Private
->TextInExList
[Index
],
3664 KeyNotificationFunction
,
3665 &NewNotify
->NotifyHandleList
[Index
]
3667 if (EFI_ERROR (Status
)) {
3669 // Un-register the key notify on all physical console input devices
3671 while (Index
-- != 0) {
3672 Private
->TextInExList
[Index
]->UnregisterKeyNotify (
3673 Private
->TextInExList
[Index
],
3674 NewNotify
->NotifyHandleList
[Index
]
3677 gBS
->FreePool (NewNotify
->NotifyHandleList
);
3678 gBS
->FreePool (NewNotify
);
3683 InsertTailList (&mConIn
.NotifyList
, &NewNotify
->NotifyEntry
);
3685 *NotifyHandle
= NewNotify
->NotifyHandle
;
3693 Remove a registered notification function from a particular keystroke.
3695 @param This Protocol instance pointer.
3696 @param NotificationHandle The handle of the notification function being
3699 @retval EFI_SUCCESS The notification function was unregistered
3701 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
3706 ConSplitterTextInUnregisterKeyNotify (
3707 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3708 IN EFI_HANDLE NotificationHandle
3711 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3713 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3716 if (NotificationHandle
== NULL
) {
3717 return EFI_INVALID_PARAMETER
;
3720 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3722 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3723 CurrentNotify
= TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link
);
3724 if (CurrentNotify
->NotifyHandle
== NotificationHandle
) {
3725 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3726 Private
->TextInExList
[Index
]->UnregisterKeyNotify (
3727 Private
->TextInExList
[Index
],
3728 CurrentNotify
->NotifyHandleList
[Index
]
3731 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
3733 gBS
->FreePool (CurrentNotify
->NotifyHandleList
);
3734 gBS
->FreePool (CurrentNotify
);
3740 // NotificationHandle is not found in database
3742 return EFI_INVALID_PARAMETER
;
3747 Reset the input device and optionaly run diagnostics
3749 @param This Protocol instance pointer.
3750 @param ExtendedVerification Driver may perform diagnostics on reset.
3752 @retval EFI_SUCCESS The device was reset.
3753 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3759 ConSplitterSimplePointerReset (
3760 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
3761 IN BOOLEAN ExtendedVerification
3765 EFI_STATUS ReturnStatus
;
3766 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3769 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
3771 Private
->InputEventSignalState
= FALSE
;
3773 if (Private
->CurrentNumberOfPointers
== 0) {
3777 // return the worst status met
3779 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3780 Status
= Private
->PointerList
[Index
]->Reset (
3781 Private
->PointerList
[Index
],
3782 ExtendedVerification
3784 if (EFI_ERROR (Status
)) {
3785 ReturnStatus
= Status
;
3789 return ReturnStatus
;
3794 Reads the next keystroke from the input device. The WaitForKey Event can
3795 be used to test for existance of a keystroke via WaitForEvent () call.
3797 @param Private Protocol instance pointer.
3798 @param State The state information of simple pointer device.
3800 @retval EFI_SUCCESS The keystroke information was returned.
3801 @retval EFI_NOT_READY There was no keystroke data availiable.
3802 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3808 ConSplitterSimplePointerPrivateGetState (
3809 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3810 IN OUT EFI_SIMPLE_POINTER_STATE
*State
3814 EFI_STATUS ReturnStatus
;
3816 EFI_SIMPLE_POINTER_STATE CurrentState
;
3818 State
->RelativeMovementX
= 0;
3819 State
->RelativeMovementY
= 0;
3820 State
->RelativeMovementZ
= 0;
3821 State
->LeftButton
= FALSE
;
3822 State
->RightButton
= FALSE
;
3825 // if no physical console input device exists, return EFI_NOT_READY;
3826 // if any physical console input device has key input,
3827 // return the key and EFI_SUCCESS.
3829 ReturnStatus
= EFI_NOT_READY
;
3830 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3832 Status
= Private
->PointerList
[Index
]->GetState (
3833 Private
->PointerList
[Index
],
3836 if (!EFI_ERROR (Status
)) {
3837 if (ReturnStatus
== EFI_NOT_READY
) {
3838 ReturnStatus
= EFI_SUCCESS
;
3841 if (CurrentState
.LeftButton
) {
3842 State
->LeftButton
= TRUE
;
3845 if (CurrentState
.RightButton
) {
3846 State
->RightButton
= TRUE
;
3849 if (CurrentState
.RelativeMovementX
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionX
!= 0) {
3850 State
->RelativeMovementX
+= (CurrentState
.RelativeMovementX
* (INT32
) Private
->SimplePointerMode
.ResolutionX
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionX
;
3853 if (CurrentState
.RelativeMovementY
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionY
!= 0) {
3854 State
->RelativeMovementY
+= (CurrentState
.RelativeMovementY
* (INT32
) Private
->SimplePointerMode
.ResolutionY
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionY
;
3857 if (CurrentState
.RelativeMovementZ
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionZ
!= 0) {
3858 State
->RelativeMovementZ
+= (CurrentState
.RelativeMovementZ
* (INT32
) Private
->SimplePointerMode
.ResolutionZ
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionZ
;
3860 } else if (Status
== EFI_DEVICE_ERROR
) {
3861 ReturnStatus
= EFI_DEVICE_ERROR
;
3865 return ReturnStatus
;
3870 Reads the next keystroke from the input device. The WaitForKey Event can
3871 be used to test for existance of a keystroke via WaitForEvent () call.
3873 @param This A pointer to protocol instance.
3874 @param State A pointer to state information on the pointer device
3876 @retval EFI_SUCCESS The keystroke information was returned in State.
3877 @retval EFI_NOT_READY There was no keystroke data availiable.
3878 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3884 ConSplitterSimplePointerGetState (
3885 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
3886 IN OUT EFI_SIMPLE_POINTER_STATE
*State
3889 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3891 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
3893 Private
->InputEventSignalState
= FALSE
;
3895 return ConSplitterSimplePointerPrivateGetState (Private
, State
);
3900 This event agregates all the events of the ConIn devices in the spliter.
3901 If any events of physical ConIn devices are signaled, signal the ConIn
3902 spliter event. This will cause the calling code to call
3903 ConSplitterTextInReadKeyStroke ().
3905 @param Event The Event assoicated with callback.
3906 @param Context Context registered when Event was created.
3911 ConSplitterSimplePointerWaitForInput (
3917 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3920 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
3923 // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
3925 if (Private
->InputEventSignalState
) {
3926 gBS
->SignalEvent (Event
);
3930 // if any physical console input device has key input, signal the event.
3932 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3933 Status
= gBS
->CheckEvent (Private
->PointerList
[Index
]->WaitForInput
);
3934 if (!EFI_ERROR (Status
)) {
3935 gBS
->SignalEvent (Event
);
3936 Private
->InputEventSignalState
= TRUE
;
3942 Resets the pointer device hardware.
3944 @param This Protocol instance pointer.
3945 @param ExtendedVerification Driver may perform diagnostics on reset.
3947 @retval EFI_SUCCESS The device was reset.
3948 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
3954 ConSplitterAbsolutePointerReset (
3955 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
3956 IN BOOLEAN ExtendedVerification
3960 EFI_STATUS ReturnStatus
;
3961 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3964 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
3966 Private
->AbsoluteInputEventSignalState
= FALSE
;
3968 if (Private
->CurrentNumberOfAbsolutePointers
== 0) {
3972 // return the worst status met
3974 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
3975 Status
= Private
->AbsolutePointerList
[Index
]->Reset (
3976 Private
->AbsolutePointerList
[Index
],
3977 ExtendedVerification
3979 if (EFI_ERROR (Status
)) {
3980 ReturnStatus
= Status
;
3984 return ReturnStatus
;
3989 Retrieves the current state of a pointer device.
3991 @param This Protocol instance pointer.
3992 @param State A pointer to the state information on the
3995 @retval EFI_SUCCESS The state of the pointer device was returned in
3997 @retval EFI_NOT_READY The state of the pointer device has not changed
3998 since the last call to GetState().
3999 @retval EFI_DEVICE_ERROR A device error occurred while attempting to
4000 retrieve the pointer device's current state.
4005 ConSplitterAbsolutePointerGetState (
4006 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4007 IN OUT EFI_ABSOLUTE_POINTER_STATE
*State
4010 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4012 EFI_STATUS ReturnStatus
;
4014 EFI_ABSOLUTE_POINTER_STATE CurrentState
;
4017 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4019 Private
->AbsoluteInputEventSignalState
= FALSE
;
4021 State
->CurrentX
= 0;
4022 State
->CurrentY
= 0;
4023 State
->CurrentZ
= 0;
4024 State
->ActiveButtons
= 0;
4027 // if no physical pointer device exists, return EFI_NOT_READY;
4028 // if any physical pointer device has changed state,
4029 // return the state and EFI_SUCCESS.
4031 ReturnStatus
= EFI_NOT_READY
;
4032 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4034 Status
= Private
->AbsolutePointerList
[Index
]->GetState (
4035 Private
->AbsolutePointerList
[Index
],
4038 if (!EFI_ERROR (Status
)) {
4039 if (ReturnStatus
== EFI_NOT_READY
) {
4040 ReturnStatus
= EFI_SUCCESS
;
4043 State
->ActiveButtons
= CurrentState
.ActiveButtons
;
4045 if (!(Private
->AbsolutePointerMode
.AbsoluteMinX
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxX
== 0)) {
4046 State
->CurrentX
= CurrentState
.CurrentX
;
4048 if (!(Private
->AbsolutePointerMode
.AbsoluteMinY
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxY
== 0)) {
4049 State
->CurrentY
= CurrentState
.CurrentY
;
4051 if (!(Private
->AbsolutePointerMode
.AbsoluteMinZ
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxZ
== 0)) {
4052 State
->CurrentZ
= CurrentState
.CurrentZ
;
4055 } else if (Status
== EFI_DEVICE_ERROR
) {
4056 ReturnStatus
= EFI_DEVICE_ERROR
;
4060 return ReturnStatus
;
4065 This event agregates all the events of the pointer devices in the splitter.
4066 If any events of physical pointer devices are signaled, signal the pointer
4067 splitter event. This will cause the calling code to call
4068 ConSplitterAbsolutePointerGetState ().
4070 @param Event The Event assoicated with callback.
4071 @param Context Context registered when Event was created.
4076 ConSplitterAbsolutePointerWaitForInput (
4082 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4085 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4088 // if AbsoluteInputEventSignalState is flagged before,
4089 // and not cleared by Reset() or GetState(), signal it
4091 if (Private
->AbsoluteInputEventSignalState
) {
4092 gBS
->SignalEvent (Event
);
4096 // if any physical console input device has key input, signal the event.
4098 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4099 Status
= gBS
->CheckEvent (Private
->AbsolutePointerList
[Index
]->WaitForInput
);
4100 if (!EFI_ERROR (Status
)) {
4101 gBS
->SignalEvent (Event
);
4102 Private
->AbsoluteInputEventSignalState
= TRUE
;
4109 Reset the text output device hardware and optionaly run diagnostics
4111 @param This Protocol instance pointer.
4112 @param ExtendedVerification Driver may perform more exhaustive verfication
4113 operation of the device during reset.
4115 @retval EFI_SUCCESS The text output device was reset.
4116 @retval EFI_DEVICE_ERROR The text output device is not functioning
4117 correctly and could not be reset.
4122 ConSplitterTextOutReset (
4123 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4124 IN BOOLEAN ExtendedVerification
4128 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4130 EFI_STATUS ReturnStatus
;
4132 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4135 // return the worst status met
4137 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4138 Status
= Private
->TextOutList
[Index
].TextOut
->Reset (
4139 Private
->TextOutList
[Index
].TextOut
,
4140 ExtendedVerification
4142 if (EFI_ERROR (Status
)) {
4143 ReturnStatus
= Status
;
4147 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BLACK
));
4150 // reset all mode parameters
4152 TextOutSetMode (Private
, 0);
4154 return ReturnStatus
;
4159 Write a Unicode string to the output device.
4161 @param This Protocol instance pointer.
4162 @param WString The NULL-terminated Unicode string to be
4163 displayed on the output device(s). All output
4164 devices must also support the Unicode drawing
4165 defined in this file.
4167 @retval EFI_SUCCESS The string was output to the device.
4168 @retval EFI_DEVICE_ERROR The device reported an error while attempting to
4170 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
4172 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
4173 characters in the Unicode string could not be
4174 rendered and were skipped.
4179 ConSplitterTextOutOutputString (
4180 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4185 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4187 EFI_STATUS ReturnStatus
;
4191 This
->SetAttribute (This
, This
->Mode
->Attribute
);
4193 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4196 // return the worst status met
4198 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4199 Status
= Private
->TextOutList
[Index
].TextOut
->OutputString (
4200 Private
->TextOutList
[Index
].TextOut
,
4203 if (EFI_ERROR (Status
)) {
4204 ReturnStatus
= Status
;
4208 if (Private
->CurrentNumberOfConsoles
> 0) {
4209 Private
->TextOutMode
.CursorColumn
= Private
->TextOutList
[0].TextOut
->Mode
->CursorColumn
;
4210 Private
->TextOutMode
.CursorRow
= Private
->TextOutList
[0].TextOut
->Mode
->CursorRow
;
4213 // When there is no real console devices in system,
4214 // update cursor position for the virtual device in consplitter.
4216 Private
->TextOut
.QueryMode (
4218 Private
->TextOutMode
.Mode
,
4222 for (; *WString
!= CHAR_NULL
; WString
++) {
4224 case CHAR_BACKSPACE
:
4225 if (Private
->TextOutMode
.CursorColumn
== 0 && Private
->TextOutMode
.CursorRow
> 0) {
4226 Private
->TextOutMode
.CursorRow
--;
4227 Private
->TextOutMode
.CursorColumn
= (INT32
) (MaxColumn
- 1);
4228 } else if (Private
->TextOutMode
.CursorColumn
> 0) {
4229 Private
->TextOutMode
.CursorColumn
--;
4234 if (Private
->TextOutMode
.CursorRow
< (INT32
) (MaxRow
- 1)) {
4235 Private
->TextOutMode
.CursorRow
++;
4239 case CHAR_CARRIAGE_RETURN
:
4240 Private
->TextOutMode
.CursorColumn
= 0;
4244 if (Private
->TextOutMode
.CursorColumn
< (INT32
) (MaxColumn
- 1)) {
4245 Private
->TextOutMode
.CursorColumn
++;
4247 Private
->TextOutMode
.CursorColumn
= 0;
4248 if (Private
->TextOutMode
.CursorRow
< (INT32
) (MaxRow
- 1)) {
4249 Private
->TextOutMode
.CursorRow
++;
4257 return ReturnStatus
;
4262 Verifies that all characters in a Unicode string can be output to the
4265 @param This Protocol instance pointer.
4266 @param WString The NULL-terminated Unicode string to be
4267 examined for the output device(s).
4269 @retval EFI_SUCCESS The device(s) are capable of rendering the
4271 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string
4272 cannot be rendered by one or more of the output
4273 devices mapped by the EFI handle.
4278 ConSplitterTextOutTestString (
4279 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4284 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4286 EFI_STATUS ReturnStatus
;
4288 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4291 // return the worst status met
4293 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4294 Status
= Private
->TextOutList
[Index
].TextOut
->TestString (
4295 Private
->TextOutList
[Index
].TextOut
,
4298 if (EFI_ERROR (Status
)) {
4299 ReturnStatus
= Status
;
4303 // There is no DevNullTextOutTestString () since a Unicode buffer would
4304 // always return EFI_SUCCESS.
4305 // ReturnStatus will be EFI_SUCCESS if no consoles are present
4307 return ReturnStatus
;
4312 Returns information for an available text mode that the output device(s)
4315 @param This Protocol instance pointer.
4316 @param ModeNumber The mode number to return information on.
4317 @param Columns Returns the columns of the text output device
4318 for the requested ModeNumber.
4319 @param Rows Returns the rows of the text output device
4320 for the requested ModeNumber.
4322 @retval EFI_SUCCESS The requested mode information was returned.
4323 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4325 @retval EFI_UNSUPPORTED The mode number was not valid.
4330 ConSplitterTextOutQueryMode (
4331 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4332 IN UINTN ModeNumber
,
4337 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4339 INT32
*TextOutModeMap
;
4341 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4344 // Check whether param ModeNumber is valid.
4345 // ModeNumber should be within range 0 ~ MaxMode - 1.
4347 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4348 return EFI_UNSUPPORTED
;
4351 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4352 return EFI_UNSUPPORTED
;
4356 // We get the available mode from mode intersection map if it's available
4358 if (Private
->TextOutModeMap
!= NULL
) {
4359 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4360 CurrentMode
= (UINTN
)(*TextOutModeMap
);
4361 *Columns
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4362 *Rows
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4364 *Columns
= Private
->TextOutQueryData
[ModeNumber
].Columns
;
4365 *Rows
= Private
->TextOutQueryData
[ModeNumber
].Rows
;
4368 if (*Columns
<= 0 && *Rows
<= 0) {
4369 return EFI_UNSUPPORTED
;
4378 Sets the output device(s) to a specified mode.
4380 @param This Protocol instance pointer.
4381 @param ModeNumber The mode number to set.
4383 @retval EFI_SUCCESS The requested text mode was set.
4384 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4386 @retval EFI_UNSUPPORTED The mode number was not valid.
4391 ConSplitterTextOutSetMode (
4392 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4397 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4399 INT32
*TextOutModeMap
;
4400 EFI_STATUS ReturnStatus
;
4402 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4405 // Check whether param ModeNumber is valid.
4406 // ModeNumber should be within range 0 ~ MaxMode - 1.
4408 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4409 return EFI_UNSUPPORTED
;
4412 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4413 return EFI_UNSUPPORTED
;
4416 // If the mode is being set to the curent mode, then just clear the screen and return.
4418 if (Private
->TextOutMode
.Mode
== (INT32
) ModeNumber
) {
4419 return ConSplitterTextOutClearScreen (This
);
4422 // return the worst status met
4424 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4425 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4426 Status
= Private
->TextOutList
[Index
].TextOut
->SetMode (
4427 Private
->TextOutList
[Index
].TextOut
,
4428 TextOutModeMap
[Index
]
4430 if (EFI_ERROR (Status
)) {
4431 ReturnStatus
= Status
;
4436 // Set mode parameter to specified mode number
4438 TextOutSetMode (Private
, ModeNumber
);
4440 return ReturnStatus
;
4445 Sets the background and foreground colors for the OutputString () and
4446 ClearScreen () functions.
4448 @param This Protocol instance pointer.
4449 @param Attribute The attribute to set. Bits 0..3 are the
4450 foreground color, and bits 4..6 are the
4451 background color. All other bits are undefined
4452 and must be zero. The valid Attributes are
4453 defined in this file.
4455 @retval EFI_SUCCESS The attribute was set.
4456 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4458 @retval EFI_UNSUPPORTED The attribute requested is not defined.
4463 ConSplitterTextOutSetAttribute (
4464 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4469 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4471 EFI_STATUS ReturnStatus
;
4473 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4476 // Check whether param Attribute is valid.
4478 if ( (Attribute
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4479 return EFI_UNSUPPORTED
;
4483 // return the worst status met
4485 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4486 Status
= Private
->TextOutList
[Index
].TextOut
->SetAttribute (
4487 Private
->TextOutList
[Index
].TextOut
,
4490 if (EFI_ERROR (Status
)) {
4491 ReturnStatus
= Status
;
4495 Private
->TextOutMode
.Attribute
= (INT32
) Attribute
;
4497 return ReturnStatus
;
4502 Clears the output device(s) display to the currently selected background
4505 @param This Protocol instance pointer.
4507 @retval EFI_SUCCESS The operation completed successfully.
4508 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4510 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4515 ConSplitterTextOutClearScreen (
4516 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
4520 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4522 EFI_STATUS ReturnStatus
;
4524 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4527 // return the worst status met
4529 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4530 Status
= Private
->TextOutList
[Index
].TextOut
->ClearScreen (Private
->TextOutList
[Index
].TextOut
);
4531 if (EFI_ERROR (Status
)) {
4532 ReturnStatus
= Status
;
4537 // No need to do extra check here as whether (Column, Row) is valid has
4538 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
4539 // always be supported.
4541 Private
->TextOutMode
.CursorColumn
= 0;
4542 Private
->TextOutMode
.CursorRow
= 0;
4543 Private
->TextOutMode
.CursorVisible
= TRUE
;
4545 return ReturnStatus
;
4550 Sets the current coordinates of the cursor position
4552 @param This Protocol instance pointer.
4553 @param Column The column position to set the cursor to. Must be
4554 greater than or equal to zero and less than the
4555 number of columns by QueryMode ().
4556 @param Row The row position to set the cursor to. Must be
4557 greater than or equal to zero and less than the
4558 number of rows by QueryMode ().
4560 @retval EFI_SUCCESS The operation completed successfully.
4561 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4563 @retval EFI_UNSUPPORTED The output device is not in a valid text mode,
4564 or the cursor position is invalid for the
4570 ConSplitterTextOutSetCursorPosition (
4571 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4577 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4579 EFI_STATUS ReturnStatus
;
4582 INT32
*TextOutModeMap
;
4586 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4587 TextOutModeMap
= NULL
;
4588 ModeNumber
= Private
->TextOutMode
.Mode
;
4591 // Get current MaxColumn and MaxRow from intersection map
4593 if (Private
->TextOutModeMap
!= NULL
) {
4594 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4595 CurrentMode
= *TextOutModeMap
;
4597 CurrentMode
= ModeNumber
;
4600 MaxColumn
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4601 MaxRow
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4603 if (Column
>= MaxColumn
|| Row
>= MaxRow
) {
4604 return EFI_UNSUPPORTED
;
4607 // return the worst status met
4609 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4610 Status
= Private
->TextOutList
[Index
].TextOut
->SetCursorPosition (
4611 Private
->TextOutList
[Index
].TextOut
,
4615 if (EFI_ERROR (Status
)) {
4616 ReturnStatus
= Status
;
4621 // No need to do extra check here as whether (Column, Row) is valid has
4622 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
4623 // always be supported.
4625 Private
->TextOutMode
.CursorColumn
= (INT32
) Column
;
4626 Private
->TextOutMode
.CursorRow
= (INT32
) Row
;
4628 return ReturnStatus
;
4633 Makes the cursor visible or invisible
4635 @param This Protocol instance pointer.
4636 @param Visible If TRUE, the cursor is set to be visible. If
4637 FALSE, the cursor is set to be invisible.
4639 @retval EFI_SUCCESS The operation completed successfully.
4640 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4641 the request, or the device does not support
4642 changing the cursor mode.
4643 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4648 ConSplitterTextOutEnableCursor (
4649 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4654 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4656 EFI_STATUS ReturnStatus
;
4658 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4661 // return the worst status met
4663 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4664 Status
= Private
->TextOutList
[Index
].TextOut
->EnableCursor (
4665 Private
->TextOutList
[Index
].TextOut
,
4668 if (EFI_ERROR (Status
)) {
4669 ReturnStatus
= Status
;
4673 Private
->TextOutMode
.CursorVisible
= Visible
;
4675 return ReturnStatus
;