2 Console Splitter Driver. Any Handle that attatched
3 EFI_CONSOLE_IDENTIFIER_PROTOCOL can be bound by this driver.
5 So far it works like any other driver by opening a SimpleTextIn and/or
6 SimpleTextOut protocol with EFI_OPEN_PROTOCOL_BY_DRIVER attributes. The big
7 difference is this driver does not layer a protocol on the passed in
8 handle, or construct a child handle like a standard device or bus driver.
9 This driver produces three virtual handles as children, one for console input
10 splitter, one for console output splitter and one for error output splitter.
11 EFI_CONSOLE_SPLIT_PROTOCOL will be attatched onto each virtual handle to
12 identify the splitter type.
14 Each virtual handle, that supports both the EFI_CONSOLE_SPLIT_PROTOCOL
15 and Console I/O protocol, will be produced in the driver entry point.
16 The virtual handle are added on driver entry and never removed.
17 Such design ensures sytem function well during none console device situation.
19 Copyright (c) 2006 - 2008 Intel Corporation. <BR>
20 All rights reserved. This program and the accompanying materials
21 are licensed and made available under the terms and conditions of the BSD License
22 which accompanies this distribution. The full text of the license may be found at
23 http://opensource.org/licenses/bsd-license.php
25 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
26 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
30 #include "ConSplitter.h"
35 STATIC TEXT_IN_SPLITTER_PRIVATE_DATA mConIn
= {
36 TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE
,
39 ConSplitterTextInReset
,
40 ConSplitterTextInReadKeyStroke
,
44 (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
**) NULL
,
47 ConSplitterTextInResetEx
,
48 ConSplitterTextInReadKeyStrokeEx
,
50 ConSplitterTextInSetState
,
51 ConSplitterTextInRegisterKeyNotify
,
52 ConSplitterTextInUnregisterKeyNotify
55 (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
**) NULL
,
63 ConSplitterSimplePointerReset
,
64 ConSplitterSimplePointerGetState
,
66 (EFI_SIMPLE_POINTER_MODE
*) NULL
76 (EFI_SIMPLE_POINTER_PROTOCOL
**) NULL
,
80 ConSplitterAbsolutePointerReset
,
81 ConSplitterAbsolutePointerGetState
,
83 (EFI_ABSOLUTE_POINTER_MODE
*) NULL
90 0x10000, //AbsoluteMaxX
91 0x10000, //AbsoluteMaxY
92 0x10000, //AbsoluteMaxZ
96 (EFI_ABSOLUTE_POINTER_PROTOCOL
**) NULL
,
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
120 GLOBAL_REMOVE_IF_UNREFERENCED EFI_UGA_DRAW_PROTOCOL gUgaDrawProtocolTemplate
= {
121 ConSpliterUgaDrawGetMode
,
122 ConSpliterUgaDrawSetMode
,
126 GLOBAL_REMOVE_IF_UNREFERENCED EFI_GRAPHICS_OUTPUT_PROTOCOL gGraphicsOutputProtocolTemplate
= {
127 ConSpliterGraphicsOutputQueryMode
,
128 ConSpliterGraphicsOutputSetMode
,
129 ConSpliterGraphicsOutputBlt
,
133 STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut
= {
134 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE
,
137 ConSplitterTextOutReset
,
138 ConSplitterTextOutOutputString
,
139 ConSplitterTextOutTestString
,
140 ConSplitterTextOutQueryMode
,
141 ConSplitterTextOutSetMode
,
142 ConSplitterTextOutSetAttribute
,
143 ConSplitterTextOutClearScreen
,
144 ConSplitterTextOutSetCursorPosition
,
145 ConSplitterTextOutEnableCursor
,
146 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
165 (EFI_UGA_PIXEL
*) NULL
,
172 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) NULL
,
173 (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*) NULL
,
178 ConSpliterConsoleControlGetMode
,
179 ConSpliterConsoleControlSetMode
,
180 ConSpliterConsoleControlLockStdIn
184 (TEXT_OUT_AND_GOP_DATA
*) NULL
,
186 (TEXT_OUT_SPLITTER_QUERY_DATA
*) NULL
,
190 EfiConsoleControlScreenText
,
197 STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr
= {
198 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE
,
201 ConSplitterTextOutReset
,
202 ConSplitterTextOutOutputString
,
203 ConSplitterTextOutTestString
,
204 ConSplitterTextOutQueryMode
,
205 ConSplitterTextOutSetMode
,
206 ConSplitterTextOutSetAttribute
,
207 ConSplitterTextOutClearScreen
,
208 ConSplitterTextOutSetCursorPosition
,
209 ConSplitterTextOutEnableCursor
,
210 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
229 (EFI_UGA_PIXEL
*) NULL
,
236 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) NULL
,
237 (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*) NULL
,
242 ConSpliterConsoleControlGetMode
,
243 ConSpliterConsoleControlSetMode
,
244 ConSpliterConsoleControlLockStdIn
248 (TEXT_OUT_AND_GOP_DATA
*) NULL
,
250 (TEXT_OUT_SPLITTER_QUERY_DATA
*) NULL
,
254 EfiConsoleControlScreenText
,
261 EFI_DRIVER_BINDING_PROTOCOL gConSplitterConInDriverBinding
= {
262 ConSplitterConInDriverBindingSupported
,
263 ConSplitterConInDriverBindingStart
,
264 ConSplitterConInDriverBindingStop
,
270 EFI_DRIVER_BINDING_PROTOCOL gConSplitterSimplePointerDriverBinding
= {
271 ConSplitterSimplePointerDriverBindingSupported
,
272 ConSplitterSimplePointerDriverBindingStart
,
273 ConSplitterSimplePointerDriverBindingStop
,
280 // Driver binding instance for Absolute Pointer protocol
282 EFI_DRIVER_BINDING_PROTOCOL gConSplitterAbsolutePointerDriverBinding
= {
283 ConSplitterAbsolutePointerDriverBindingSupported
,
284 ConSplitterAbsolutePointerDriverBindingStart
,
285 ConSplitterAbsolutePointerDriverBindingStop
,
291 EFI_DRIVER_BINDING_PROTOCOL gConSplitterConOutDriverBinding
= {
292 ConSplitterConOutDriverBindingSupported
,
293 ConSplitterConOutDriverBindingStart
,
294 ConSplitterConOutDriverBindingStop
,
300 EFI_DRIVER_BINDING_PROTOCOL gConSplitterStdErrDriverBinding
= {
301 ConSplitterStdErrDriverBindingSupported
,
302 ConSplitterStdErrDriverBindingStart
,
303 ConSplitterStdErrDriverBindingStop
,
310 The user Entry Point for module ConSplitter. The user code starts with this function.
312 Installs driver module protocols and. Creates virtual device handles for ConIn,
313 ConOut, and StdErr. Installs Simple Text In protocol, Simple Text In Ex protocol,
314 Simple Pointer protocol, Absolute Pointer protocol on those virtual handlers.
315 Installs Graphics Output protocol and/or UGA Draw protocol if needed.
317 @param[in] ImageHandle The firmware allocated handle for the EFI image.
318 @param[in] SystemTable A pointer to the EFI System Table.
320 @retval EFI_SUCCESS The entry point is executed successfully.
321 @retval other Some error occurs when executing this entry point.
326 ConSplitterDriverEntry(
327 IN EFI_HANDLE ImageHandle
,
328 IN EFI_SYSTEM_TABLE
*SystemTable
334 // Install driver model protocol(s).
336 Status
= EfiLibInstallDriverBindingComponentName2 (
339 &gConSplitterConInDriverBinding
,
341 &gConSplitterConInComponentName
,
342 &gConSplitterConInComponentName2
344 ASSERT_EFI_ERROR (Status
);
346 Status
= EfiLibInstallDriverBindingComponentName2 (
349 &gConSplitterSimplePointerDriverBinding
,
351 &gConSplitterSimplePointerComponentName
,
352 &gConSplitterSimplePointerComponentName2
354 ASSERT_EFI_ERROR (Status
);
356 Status
= EfiLibInstallDriverBindingComponentName2 (
359 &gConSplitterAbsolutePointerDriverBinding
,
361 &gConSplitterAbsolutePointerComponentName
,
362 &gConSplitterAbsolutePointerComponentName2
364 ASSERT_EFI_ERROR (Status
);
366 Status
= EfiLibInstallDriverBindingComponentName2 (
369 &gConSplitterConOutDriverBinding
,
371 &gConSplitterConOutComponentName
,
372 &gConSplitterConOutComponentName2
374 ASSERT_EFI_ERROR (Status
);
376 Status
= EfiLibInstallDriverBindingComponentName2 (
379 &gConSplitterStdErrDriverBinding
,
381 &gConSplitterStdErrComponentName
,
382 &gConSplitterStdErrComponentName2
384 ASSERT_EFI_ERROR (Status
);
387 ASSERT (FeaturePcdGet (PcdConOutGopSupport
) ||
388 FeaturePcdGet (PcdConOutUgaSupport
));
390 // The driver creates virtual handles for ConIn, ConOut, and StdErr.
391 // The virtual handles will always exist even if no console exist in the
392 // system. This is need to support hotplug devices like USB.
395 // Create virtual device handle for StdErr Splitter
397 Status
= ConSplitterTextOutConstructor (&mStdErr
);
398 if (!EFI_ERROR (Status
)) {
399 Status
= gBS
->InstallMultipleProtocolInterfaces (
400 &mStdErr
.VirtualHandle
,
401 &gEfiSimpleTextOutProtocolGuid
,
403 &gEfiPrimaryStandardErrorDeviceGuid
,
409 // Create virtual device handle for ConIn Splitter
411 Status
= ConSplitterTextInConstructor (&mConIn
);
412 if (!EFI_ERROR (Status
)) {
413 Status
= gBS
->InstallMultipleProtocolInterfaces (
414 &mConIn
.VirtualHandle
,
415 &gEfiSimpleTextInProtocolGuid
,
417 &gEfiSimpleTextInputExProtocolGuid
,
419 &gEfiSimplePointerProtocolGuid
,
420 &mConIn
.SimplePointer
,
421 &gEfiAbsolutePointerProtocolGuid
,
422 &mConIn
.AbsolutePointer
,
423 &gEfiPrimaryConsoleInDeviceGuid
,
427 if (!EFI_ERROR (Status
)) {
429 // Update the EFI System Table with new virtual console
431 gST
->ConsoleInHandle
= mConIn
.VirtualHandle
;
432 gST
->ConIn
= &mConIn
.TextIn
;
436 // Create virtual device handle for ConOut Splitter
438 Status
= ConSplitterTextOutConstructor (&mConOut
);
439 if (!EFI_ERROR (Status
)) {
440 if (!FeaturePcdGet (PcdConOutGopSupport
)) {
442 // In EFI mode, UGA Draw protocol is installed
444 Status
= gBS
->InstallMultipleProtocolInterfaces (
445 &mConOut
.VirtualHandle
,
446 &gEfiSimpleTextOutProtocolGuid
,
448 &gEfiUgaDrawProtocolGuid
,
450 &gEfiConsoleControlProtocolGuid
,
451 &mConOut
.ConsoleControl
,
452 &gEfiPrimaryConsoleOutDeviceGuid
,
456 } else if (!FeaturePcdGet (PcdConOutUgaSupport
)) {
458 // In UEFI mode, Graphics Output Protocol is installed on virtual handle.
460 Status
= gBS
->InstallMultipleProtocolInterfaces (
461 &mConOut
.VirtualHandle
,
462 &gEfiSimpleTextOutProtocolGuid
,
464 &gEfiGraphicsOutputProtocolGuid
,
465 &mConOut
.GraphicsOutput
,
466 &gEfiConsoleControlProtocolGuid
,
467 &mConOut
.ConsoleControl
,
468 &gEfiPrimaryConsoleOutDeviceGuid
,
474 // In EFI and UEFI comptible mode, Graphics Output Protocol and UGA are
475 // installed on virtual handle.
477 Status
= gBS
->InstallMultipleProtocolInterfaces (
478 &mConOut
.VirtualHandle
,
479 &gEfiSimpleTextOutProtocolGuid
,
481 &gEfiGraphicsOutputProtocolGuid
,
482 &mConOut
.GraphicsOutput
,
483 &gEfiUgaDrawProtocolGuid
,
485 &gEfiConsoleControlProtocolGuid
,
486 &mConOut
.ConsoleControl
,
487 &gEfiPrimaryConsoleOutDeviceGuid
,
493 if (!EFI_ERROR (Status
)) {
495 // Update the EFI System Table with new virtual console
497 gST
->ConsoleOutHandle
= mConOut
.VirtualHandle
;
498 gST
->ConOut
= &mConOut
.TextOut
;
503 // Update the CRC32 in the EFI System Table header
506 gBS
->CalculateCrc32 (
518 Construct console input devices' private data.
520 @param ConInPrivate A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA
523 @retval EFI_OUT_OF_RESOURCES Out of resources.
524 @retval other Out of resources.
528 ConSplitterTextInConstructor (
529 TEXT_IN_SPLITTER_PRIVATE_DATA
*ConInPrivate
535 // Initilize console input splitter's private data.
537 Status
= ConSplitterGrowBuffer (
538 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
539 &ConInPrivate
->TextInListCount
,
540 (VOID
**) &ConInPrivate
->TextInList
542 if (EFI_ERROR (Status
)) {
543 return EFI_OUT_OF_RESOURCES
;
546 // Create Event to support locking StdIn Device
548 Status
= gBS
->CreateEvent (
549 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
551 ConSpliterConsoleControlLockStdInEvent
,
553 &ConInPrivate
->LockEvent
555 ASSERT_EFI_ERROR (Status
);
557 Status
= gBS
->CreateEvent (
560 ConSplitterTextInWaitForKey
,
562 &ConInPrivate
->TextIn
.WaitForKey
564 ASSERT_EFI_ERROR (Status
);
567 // Buffer for Simple Text Input Ex Protocol
569 Status
= ConSplitterGrowBuffer (
570 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
571 &ConInPrivate
->TextInExListCount
,
572 (VOID
**) &ConInPrivate
->TextInExList
574 if (EFI_ERROR (Status
)) {
575 return EFI_OUT_OF_RESOURCES
;
578 Status
= gBS
->CreateEvent (
581 ConSplitterTextInWaitForKey
,
583 &ConInPrivate
->TextInEx
.WaitForKeyEx
585 ASSERT_EFI_ERROR (Status
);
587 InitializeListHead (&ConInPrivate
->NotifyList
);
590 // Allocate Buffer and Create Event for Absolute Pointer and Simple Pointer Protocols
592 ConInPrivate
->AbsolutePointer
.Mode
= &ConInPrivate
->AbsolutePointerMode
;
594 Status
= ConSplitterGrowBuffer (
595 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
596 &ConInPrivate
->AbsolutePointerListCount
,
597 (VOID
**) &ConInPrivate
->AbsolutePointerList
599 if (EFI_ERROR (Status
)) {
600 return EFI_OUT_OF_RESOURCES
;
603 Status
= gBS
->CreateEvent (
606 ConSplitterAbsolutePointerWaitForInput
,
608 &ConInPrivate
->AbsolutePointer
.WaitForInput
610 ASSERT_EFI_ERROR (Status
);
612 ConInPrivate
->SimplePointer
.Mode
= &ConInPrivate
->SimplePointerMode
;
614 Status
= ConSplitterGrowBuffer (
615 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
616 &ConInPrivate
->PointerListCount
,
617 (VOID
**) &ConInPrivate
->PointerList
619 if (EFI_ERROR (Status
)) {
620 return EFI_OUT_OF_RESOURCES
;
623 Status
= gBS
->CreateEvent (
626 ConSplitterSimplePointerWaitForInput
,
628 &ConInPrivate
->SimplePointer
.WaitForInput
635 Construct console output devices' private data.
637 @param ConOutPrivate A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA
640 @retval EFI_OUT_OF_RESOURCES Out of resources.
644 ConSplitterTextOutConstructor (
645 TEXT_OUT_SPLITTER_PRIVATE_DATA
*ConOutPrivate
649 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
652 // Copy protocols template
654 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
655 CopyMem (&ConOutPrivate
->UgaDraw
, &gUgaDrawProtocolTemplate
, sizeof (EFI_UGA_DRAW_PROTOCOL
));
658 if (FeaturePcdGet (PcdConOutGopSupport
)) {
659 CopyMem (&ConOutPrivate
->GraphicsOutput
, &gGraphicsOutputProtocolTemplate
, sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL
));
663 // Initilize console output splitter's private data.
665 ConOutPrivate
->TextOut
.Mode
= &ConOutPrivate
->TextOutMode
;
668 // When new console device is added, the new mode will be set later,
669 // so put current mode back to init state.
671 ConOutPrivate
->TextOutMode
.Mode
= 0xFF;
673 Status
= ConSplitterGrowBuffer (
674 sizeof (TEXT_OUT_AND_GOP_DATA
),
675 &ConOutPrivate
->TextOutListCount
,
676 (VOID
**) &ConOutPrivate
->TextOutList
678 if (EFI_ERROR (Status
)) {
679 return EFI_OUT_OF_RESOURCES
;
682 Status
= ConSplitterGrowBuffer (
683 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
684 &ConOutPrivate
->TextOutQueryDataCount
,
685 (VOID
**) &ConOutPrivate
->TextOutQueryData
687 if (EFI_ERROR (Status
)) {
688 return EFI_OUT_OF_RESOURCES
;
691 // Setup the DevNullTextOut console to 80 x 25
693 ConOutPrivate
->TextOutQueryData
[0].Columns
= 80;
694 ConOutPrivate
->TextOutQueryData
[0].Rows
= 25;
695 DevNullTextOutSetMode (ConOutPrivate
, 0);
697 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
699 // Setup the DevNullUgaDraw to 800 x 600 x 32 bits per pixel
701 ConSpliterUgaDrawSetMode (&ConOutPrivate
->UgaDraw
, 800, 600, 32, 60);
703 if (FeaturePcdGet (PcdConOutGopSupport
)) {
705 // Setup resource for mode information in Graphics Output Protocol interface
707 if ((ConOutPrivate
->GraphicsOutput
.Mode
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
))) == NULL
) {
708 return EFI_OUT_OF_RESOURCES
;
710 if ((ConOutPrivate
->GraphicsOutput
.Mode
->Info
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
))) == NULL
) {
711 return EFI_OUT_OF_RESOURCES
;
714 // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel
715 // DevNull will be updated to user-defined mode after driver has started.
717 if ((ConOutPrivate
->GraphicsOutputModeBuffer
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
))) == NULL
) {
718 return EFI_OUT_OF_RESOURCES
;
720 Info
= &ConOutPrivate
->GraphicsOutputModeBuffer
[0];
722 Info
->HorizontalResolution
= 800;
723 Info
->VerticalResolution
= 600;
724 Info
->PixelFormat
= PixelBltOnly
;
725 Info
->PixelsPerScanLine
= 800;
726 CopyMem (ConOutPrivate
->GraphicsOutput
.Mode
->Info
, Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
727 ConOutPrivate
->GraphicsOutput
.Mode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
730 // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()
731 // GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
733 ConOutPrivate
->GraphicsOutput
.Mode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
734 ConOutPrivate
->GraphicsOutput
.Mode
->FrameBufferSize
= 0;
736 ConOutPrivate
->GraphicsOutput
.Mode
->MaxMode
= 1;
738 // Initial current mode to unknow state, and then set to mode 0
740 ConOutPrivate
->GraphicsOutput
.Mode
->Mode
= 0xffff;
741 ConOutPrivate
->GraphicsOutput
.SetMode (&ConOutPrivate
->GraphicsOutput
, 0);
749 Test to see if the specified protocol could be supported on the ControllerHandle.
751 @param This Protocol instance pointer.
752 @param ControllerHandle Handle of device to test.
753 @param Guid The specified protocol guid.
755 @retval EFI_SUCCESS The specified protocol is supported on this device.
756 @retval other The specified protocol is not supported on this device.
760 ConSplitterSupported (
761 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
762 IN EFI_HANDLE ControllerHandle
,
770 // Make sure the Console Splitter does not attempt to attach to itself
772 if (ControllerHandle
== mConIn
.VirtualHandle
) {
773 return EFI_UNSUPPORTED
;
776 if (ControllerHandle
== mConOut
.VirtualHandle
) {
777 return EFI_UNSUPPORTED
;
780 if (ControllerHandle
== mStdErr
.VirtualHandle
) {
781 return EFI_UNSUPPORTED
;
784 // Check to see whether the handle has the ConsoleInDevice GUID on it
786 Status
= gBS
->OpenProtocol (
790 This
->DriverBindingHandle
,
792 EFI_OPEN_PROTOCOL_BY_DRIVER
795 if (EFI_ERROR (Status
)) {
802 This
->DriverBindingHandle
,
810 Test to see if Console In Device could be supported on the ControllerHandle.
812 @param This Protocol instance pointer.
813 @param ControllerHandle Handle of device to test.
814 @param RemainingDevicePath Optional parameter use to pick a specific child
817 @retval EFI_SUCCESS This driver supports this device
818 @retval other This driver does not support this device
823 ConSplitterConInDriverBindingSupported (
824 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
825 IN EFI_HANDLE ControllerHandle
,
826 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
829 return ConSplitterSupported (
832 &gEfiConsoleInDeviceGuid
837 Test to see if Simple Pointer protocol could be supported on the ControllerHandle.
839 @param This Protocol instance pointer.
840 @param ControllerHandle Handle of device to test.
841 @param RemainingDevicePath Optional parameter use to pick a specific child
844 @retval EFI_SUCCESS This driver supports this device
845 @retval other This driver does not support this device
850 ConSplitterSimplePointerDriverBindingSupported (
851 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
852 IN EFI_HANDLE ControllerHandle
,
853 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
856 return ConSplitterSupported (
859 &gEfiSimplePointerProtocolGuid
865 Test to see if Absolute Pointer protocol could be supported on the ControllerHandle.
867 @param This Protocol instance pointer.
868 @param ControllerHandle Handle of device to test.
869 @param RemainingDevicePath Optional parameter use to pick a specific child
872 @retval EFI_SUCCESS This driver supports this device
873 @retval other This driver does not support this device
878 ConSplitterAbsolutePointerDriverBindingSupported (
879 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
880 IN EFI_HANDLE ControllerHandle
,
881 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
884 return ConSplitterSupported (
887 &gEfiAbsolutePointerProtocolGuid
893 Test to see if Console Out Device could be supported on the ControllerHandle.
895 @param This Protocol instance pointer.
896 @param ControllerHandle Handle of device to test.
897 @param RemainingDevicePath Optional parameter use to pick a specific child
900 @retval EFI_SUCCESS This driver supports this device
901 @retval other This driver does not support this device
906 ConSplitterConOutDriverBindingSupported (
907 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
908 IN EFI_HANDLE ControllerHandle
,
909 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
912 return ConSplitterSupported (
915 &gEfiConsoleOutDeviceGuid
920 Test to see if Standard Error Device could be supported on the ControllerHandle.
922 @param This Protocol instance pointer.
923 @param ControllerHandle Handle of device to test.
924 @param RemainingDevicePath Optional parameter use to pick a specific child
927 @retval EFI_SUCCESS This driver supports this device
928 @retval other This driver does not support this device
933 ConSplitterStdErrDriverBindingSupported (
934 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
935 IN EFI_HANDLE ControllerHandle
,
936 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
939 return ConSplitterSupported (
942 &gEfiStandardErrorDeviceGuid
948 Start ConSplitter on devcie handle by opening Console Device Guid on device handle
949 and the console virtual handle. And Get the console interface on controller handle.
951 @param This Protocol instance pointer.
952 @param ControllerHandle Handle of device.
953 @param ConSplitterVirtualHandle Console virtual Handle.
954 @param DeviceGuid The specified Console Device, such as ConInDev,
956 @param InterfaceGuid The specified protocol to be opened.
957 @param Interface Protocol interface returned.
959 @retval EFI_SUCCESS This driver supports this device
960 @retval other Failed to open the specified Console Device Guid
961 or specified protocol.
966 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
967 IN EFI_HANDLE ControllerHandle
,
968 IN EFI_HANDLE ConSplitterVirtualHandle
,
969 IN EFI_GUID
*DeviceGuid
,
970 IN EFI_GUID
*InterfaceGuid
,
978 // Check to see whether the ControllerHandle has the InterfaceGuid on it.
980 Status
= gBS
->OpenProtocol (
984 This
->DriverBindingHandle
,
986 EFI_OPEN_PROTOCOL_BY_DRIVER
988 if (EFI_ERROR (Status
)) {
992 Status
= gBS
->OpenProtocol (
996 This
->DriverBindingHandle
,
997 ConSplitterVirtualHandle
,
998 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1000 if (EFI_ERROR (Status
)) {
1004 return gBS
->OpenProtocol (
1008 This
->DriverBindingHandle
,
1009 ConSplitterVirtualHandle
,
1010 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1016 Start Console In Consplitter on device handle.
1018 @param This Protocol instance pointer.
1019 @param ControllerHandle Handle of device to bind driver to.
1020 @param RemainingDevicePath Optional parameter use to pick a specific child
1023 @retval EFI_SUCCESS Console In Consplitter is added to ControllerHandle.
1024 @retval other Console In Consplitter does not support this device.
1029 ConSplitterConInDriverBindingStart (
1030 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1031 IN EFI_HANDLE ControllerHandle
,
1032 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1036 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
1037 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
;
1040 // Start ConSplitter on ControllerHandle, and create the virtual
1041 // agrogated console device on first call Start for a SimpleTextIn handle.
1043 Status
= ConSplitterStart (
1046 mConIn
.VirtualHandle
,
1047 &gEfiConsoleInDeviceGuid
,
1048 &gEfiSimpleTextInProtocolGuid
,
1051 if (EFI_ERROR (Status
)) {
1055 Status
= ConSplitterTextInAddDevice (&mConIn
, TextIn
);
1056 if (EFI_ERROR (Status
)) {
1060 Status
= gBS
->OpenProtocol (
1062 &gEfiSimpleTextInputExProtocolGuid
,
1063 (VOID
**) &TextInEx
,
1064 This
->DriverBindingHandle
,
1065 mConIn
.VirtualHandle
,
1066 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1068 if (EFI_ERROR (Status
)) {
1072 Status
= ConSplitterTextInExAddDevice (&mConIn
, TextInEx
);
1079 Start Simple Pointer Consplitter on device handle.
1081 @param This Protocol instance pointer.
1082 @param ControllerHandle Handle of device to bind driver to.
1083 @param RemainingDevicePath Optional parameter use to pick a specific child
1086 @retval EFI_SUCCESS Simple Pointer Consplitter is added to ControllerHandle.
1087 @retval other Simple Pointer Consplitter does not support this device.
1092 ConSplitterSimplePointerDriverBindingStart (
1093 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1094 IN EFI_HANDLE ControllerHandle
,
1095 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1099 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
;
1101 Status
= ConSplitterStart (
1104 mConIn
.VirtualHandle
,
1105 &gEfiSimplePointerProtocolGuid
,
1106 &gEfiSimplePointerProtocolGuid
,
1107 (VOID
**) &SimplePointer
1109 if (EFI_ERROR (Status
)) {
1113 return ConSplitterSimplePointerAddDevice (&mConIn
, SimplePointer
);
1118 Start Absolute Pointer Consplitter on device handle.
1120 @param This Protocol instance pointer.
1121 @param ControllerHandle Handle of device to bind driver to.
1122 @param RemainingDevicePath Optional parameter use to pick a specific child
1125 @retval EFI_SUCCESS Absolute Pointer Consplitter is added to ControllerHandle.
1126 @retval other Absolute Pointer Consplitter does not support this device.
1131 ConSplitterAbsolutePointerDriverBindingStart (
1132 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1133 IN EFI_HANDLE ControllerHandle
,
1134 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1138 EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
;
1140 Status
= ConSplitterStart (
1143 mConIn
.VirtualHandle
,
1144 &gEfiAbsolutePointerProtocolGuid
,
1145 &gEfiAbsolutePointerProtocolGuid
,
1146 (VOID
**) &AbsolutePointer
1149 if (EFI_ERROR (Status
)) {
1153 return ConSplitterAbsolutePointerAddDevice (&mConIn
, AbsolutePointer
);
1158 Start Console Out Consplitter on device handle.
1160 @param This Protocol instance pointer.
1161 @param ControllerHandle Handle of device to bind driver to.
1162 @param RemainingDevicePath Optional parameter use to pick a specific child
1165 @retval EFI_SUCCESS Console Out Consplitter is added to ControllerHandle.
1166 @retval other Console Out Consplitter does not support this device.
1171 ConSplitterConOutDriverBindingStart (
1172 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1173 IN EFI_HANDLE ControllerHandle
,
1174 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1178 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1179 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1180 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1182 Status
= ConSplitterStart (
1185 mConOut
.VirtualHandle
,
1186 &gEfiConsoleOutDeviceGuid
,
1187 &gEfiSimpleTextOutProtocolGuid
,
1190 if (EFI_ERROR (Status
)) {
1194 GraphicsOutput
= NULL
;
1197 // Try to Open Graphics Output protocol
1199 Status
= gBS
->OpenProtocol (
1201 &gEfiGraphicsOutputProtocolGuid
,
1202 (VOID
**) &GraphicsOutput
,
1203 This
->DriverBindingHandle
,
1204 mConOut
.VirtualHandle
,
1205 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1208 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
1210 // Open UGA_DRAW protocol
1212 Status
= gBS
->OpenProtocol (
1214 &gEfiUgaDrawProtocolGuid
,
1216 This
->DriverBindingHandle
,
1217 mConOut
.VirtualHandle
,
1218 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1223 // When new console device is added, the new mode will be set later,
1224 // so put current mode back to init state.
1226 mConOut
.TextOutMode
.Mode
= 0xFF;
1229 // If both ConOut and StdErr incorporate the same Text Out device,
1230 // their MaxMode and QueryData should be the intersection of both.
1232 Status
= ConSplitterTextOutAddDevice (&mConOut
, TextOut
, GraphicsOutput
, UgaDraw
);
1233 ConSplitterTextOutSetAttribute (&mConOut
.TextOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
1235 if (FeaturePcdGet (PcdConOutUgaSupport
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
1237 // Match the UGA mode data of ConOut with the current mode
1239 if (UgaDraw
!= NULL
) {
1242 &mConOut
.UgaHorizontalResolution
,
1243 &mConOut
.UgaVerticalResolution
,
1244 &mConOut
.UgaColorDepth
,
1245 &mConOut
.UgaRefreshRate
1254 Start Standard Error Consplitter on device handle.
1256 @param This Protocol instance pointer.
1257 @param ControllerHandle Handle of device to bind driver to.
1258 @param RemainingDevicePath Optional parameter use to pick a specific child
1261 @retval EFI_SUCCESS Standard Error Consplitter is added to ControllerHandle.
1262 @retval other Standard Error Consplitter does not support this device.
1267 ConSplitterStdErrDriverBindingStart (
1268 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1269 IN EFI_HANDLE ControllerHandle
,
1270 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1274 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1276 Status
= ConSplitterStart (
1279 mStdErr
.VirtualHandle
,
1280 &gEfiStandardErrorDeviceGuid
,
1281 &gEfiSimpleTextOutProtocolGuid
,
1284 if (EFI_ERROR (Status
)) {
1289 // When new console device is added, the new mode will be set later,
1290 // so put current mode back to init state.
1292 mStdErr
.TextOutMode
.Mode
= 0xFF;
1295 // If both ConOut and StdErr incorporate the same Text Out device,
1296 // their MaxMode and QueryData should be the intersection of both.
1298 Status
= ConSplitterTextOutAddDevice (&mStdErr
, TextOut
, NULL
, NULL
);
1299 ConSplitterTextOutSetAttribute (&mStdErr
.TextOut
, EFI_TEXT_ATTR (EFI_MAGENTA
, EFI_BLACK
));
1300 if (EFI_ERROR (Status
)) {
1304 if (mStdErr
.CurrentNumberOfConsoles
== 1) {
1305 gST
->StandardErrorHandle
= mStdErr
.VirtualHandle
;
1306 gST
->StdErr
= &mStdErr
.TextOut
;
1308 // Update the CRC32 in the EFI System Table header
1311 gBS
->CalculateCrc32 (
1312 (UINT8
*) &gST
->Hdr
,
1313 gST
->Hdr
.HeaderSize
,
1323 Stop ConSplitter on device handle by opening Console Device Guid on device handle
1324 and the console virtual handle.
1326 @param This Protocol instance pointer.
1327 @param ControllerHandle Handle of device.
1328 @param ConSplitterVirtualHandle Console virtual Handle.
1329 @param DeviceGuid The specified Console Device, such as ConInDev,
1331 @param InterfaceGuid The specified protocol to be opened.
1332 @param Interface Protocol interface returned.
1334 @retval EFI_SUCCESS Stop ConSplitter on ControllerHandle successfully.
1335 @retval other Failed to Stop ConSplitter on ControllerHandle.
1340 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1341 IN EFI_HANDLE ControllerHandle
,
1342 IN EFI_HANDLE ConSplitterVirtualHandle
,
1343 IN EFI_GUID
*DeviceGuid
,
1344 IN EFI_GUID
*InterfaceGuid
,
1350 Status
= gBS
->OpenProtocol (
1354 This
->DriverBindingHandle
,
1356 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1358 if (EFI_ERROR (Status
)) {
1362 // close the protocol refered.
1364 gBS
->CloseProtocol (
1367 This
->DriverBindingHandle
,
1368 ConSplitterVirtualHandle
1370 gBS
->CloseProtocol (
1373 This
->DriverBindingHandle
,
1382 Stop Console In ConSplitter on ControllerHandle by closing Console In Devcice GUID.
1384 @param This Protocol instance pointer.
1385 @param ControllerHandle Handle of device to stop driver on
1386 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1387 children is zero stop the entire bus driver.
1388 @param ChildHandleBuffer List of Child Handles to Stop.
1390 @retval EFI_SUCCESS This driver is removed ControllerHandle
1391 @retval other This driver was not removed from this device
1396 ConSplitterConInDriverBindingStop (
1397 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1398 IN EFI_HANDLE ControllerHandle
,
1399 IN UINTN NumberOfChildren
,
1400 IN EFI_HANDLE
*ChildHandleBuffer
1404 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
1406 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
;
1407 if (NumberOfChildren
== 0) {
1411 Status
= gBS
->OpenProtocol (
1413 &gEfiSimpleTextInputExProtocolGuid
,
1414 (VOID
**) &TextInEx
,
1415 This
->DriverBindingHandle
,
1417 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1419 if (EFI_ERROR (Status
)) {
1423 Status
= ConSplitterTextInExDeleteDevice (&mConIn
, TextInEx
);
1424 if (EFI_ERROR (Status
)) {
1429 Status
= ConSplitterStop (
1432 mConIn
.VirtualHandle
,
1433 &gEfiConsoleInDeviceGuid
,
1434 &gEfiSimpleTextInProtocolGuid
,
1437 if (EFI_ERROR (Status
)) {
1441 // Delete this console input device's data structures.
1443 return ConSplitterTextInDeleteDevice (&mConIn
, TextIn
);
1448 Stop Simple Pointer protocol ConSplitter on ControllerHandle by closing
1449 Simple Pointer protocol.
1451 @param This Protocol instance pointer.
1452 @param ControllerHandle Handle of device to stop driver on
1453 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1454 children is zero stop the entire bus driver.
1455 @param ChildHandleBuffer List of Child Handles to Stop.
1457 @retval EFI_SUCCESS This driver is removed ControllerHandle
1458 @retval other This driver was not removed from this device
1463 ConSplitterSimplePointerDriverBindingStop (
1464 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1465 IN EFI_HANDLE ControllerHandle
,
1466 IN UINTN NumberOfChildren
,
1467 IN EFI_HANDLE
*ChildHandleBuffer
1471 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
;
1473 if (NumberOfChildren
== 0) {
1477 Status
= ConSplitterStop (
1480 mConIn
.VirtualHandle
,
1481 &gEfiSimplePointerProtocolGuid
,
1482 &gEfiSimplePointerProtocolGuid
,
1483 (VOID
**) &SimplePointer
1485 if (EFI_ERROR (Status
)) {
1489 // Delete this console input device's data structures.
1491 return ConSplitterSimplePointerDeleteDevice (&mConIn
, SimplePointer
);
1496 Stop Absolute Pointer protocol ConSplitter on ControllerHandle by closing
1497 Absolute Pointer protocol.
1499 @param This Protocol instance pointer.
1500 @param ControllerHandle Handle of device to stop driver on
1501 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1502 children is zero stop the entire bus driver.
1503 @param ChildHandleBuffer List of Child Handles to Stop.
1505 @retval EFI_SUCCESS This driver is removed ControllerHandle
1506 @retval other This driver was not removed from this device
1511 ConSplitterAbsolutePointerDriverBindingStop (
1512 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1513 IN EFI_HANDLE ControllerHandle
,
1514 IN UINTN NumberOfChildren
,
1515 IN EFI_HANDLE
*ChildHandleBuffer
1519 EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
;
1521 if (NumberOfChildren
== 0) {
1525 Status
= ConSplitterStop (
1528 mConIn
.VirtualHandle
,
1529 &gEfiAbsolutePointerProtocolGuid
,
1530 &gEfiAbsolutePointerProtocolGuid
,
1531 (VOID
**) &AbsolutePointer
1533 if (EFI_ERROR (Status
)) {
1537 // Delete this console input device's data structures.
1539 return ConSplitterAbsolutePointerDeleteDevice (&mConIn
, AbsolutePointer
);
1544 Stop Console Out ConSplitter on device handle by closing Console Out Devcice GUID.
1546 @param This Protocol instance pointer.
1547 @param ControllerHandle Handle of device to stop driver on
1548 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1549 children is zero stop the entire bus driver.
1550 @param ChildHandleBuffer List of Child Handles to Stop.
1552 @retval EFI_SUCCESS This driver is removed ControllerHandle
1553 @retval other This driver was not removed from this device
1558 ConSplitterConOutDriverBindingStop (
1559 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1560 IN EFI_HANDLE ControllerHandle
,
1561 IN UINTN NumberOfChildren
,
1562 IN EFI_HANDLE
*ChildHandleBuffer
1566 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1568 if (NumberOfChildren
== 0) {
1572 Status
= ConSplitterStop (
1575 mConOut
.VirtualHandle
,
1576 &gEfiConsoleOutDeviceGuid
,
1577 &gEfiSimpleTextOutProtocolGuid
,
1580 if (EFI_ERROR (Status
)) {
1585 // Delete this console output device's data structures.
1587 return ConSplitterTextOutDeleteDevice (&mConOut
, TextOut
);
1592 Stop Standard Error ConSplitter on ControllerHandle by closing Standard Error GUID.
1594 @param This Protocol instance pointer.
1595 @param ControllerHandle Handle of device to stop driver on
1596 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1597 children is zero stop the entire bus driver.
1598 @param ChildHandleBuffer List of Child Handles to Stop.
1600 @retval EFI_SUCCESS This driver is removed ControllerHandle
1601 @retval other This driver was not removed from this device
1606 ConSplitterStdErrDriverBindingStop (
1607 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1608 IN EFI_HANDLE ControllerHandle
,
1609 IN UINTN NumberOfChildren
,
1610 IN EFI_HANDLE
*ChildHandleBuffer
1614 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1616 if (NumberOfChildren
== 0) {
1620 Status
= ConSplitterStop (
1623 mStdErr
.VirtualHandle
,
1624 &gEfiStandardErrorDeviceGuid
,
1625 &gEfiSimpleTextOutProtocolGuid
,
1628 if (EFI_ERROR (Status
)) {
1632 // Delete this console error out device's data structures.
1634 Status
= ConSplitterTextOutDeleteDevice (&mStdErr
, TextOut
);
1635 if (EFI_ERROR (Status
)) {
1639 if (mStdErr
.CurrentNumberOfConsoles
== 0) {
1640 gST
->StandardErrorHandle
= NULL
;
1643 // Update the CRC32 in the EFI System Table header
1646 gBS
->CalculateCrc32 (
1647 (UINT8
*) &gST
->Hdr
,
1648 gST
->Hdr
.HeaderSize
,
1658 Take the passed in Buffer of size SizeOfCount and grow the buffer
1659 by MAX (CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT, MaxGrow) * SizeOfCount
1660 bytes. Copy the current data in Buffer to the new version of Buffer
1661 and free the old version of buffer.
1663 @param SizeOfCount Size of element in array
1664 @param Count Current number of elements in array
1665 @param Buffer Bigger version of passed in Buffer with all the
1668 @retval EFI_SUCCESS Buffer size has grown
1669 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1673 ConSplitterGrowBuffer (
1674 IN UINTN SizeOfCount
,
1676 IN OUT VOID
**Buffer
1684 // grow the buffer to new buffer size,
1685 // copy the old buffer's content to the new-size buffer,
1686 // then free the old buffer.
1688 OldSize
= *Count
* SizeOfCount
;
1689 *Count
+= CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT
;
1690 NewSize
= *Count
* SizeOfCount
;
1692 Ptr
= AllocateZeroPool (NewSize
);
1694 return EFI_OUT_OF_RESOURCES
;
1697 CopyMem (Ptr
, *Buffer
, OldSize
);
1699 if (*Buffer
!= NULL
) {
1710 Add Text Input Device in Consplitter Text Input list.
1712 @param Private Text In Splitter pointer.
1713 @param TextIn Simple Text Input protocol pointer.
1715 @retval EFI_SUCCESS Text Input Device added successfully.
1716 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1720 ConSplitterTextInAddDevice (
1721 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1722 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1728 // If the Text In List is full, enlarge it by calling growbuffer().
1730 if (Private
->CurrentNumberOfConsoles
>= Private
->TextInListCount
) {
1731 Status
= ConSplitterGrowBuffer (
1732 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
1733 &Private
->TextInListCount
,
1734 (VOID
**) &Private
->TextInList
1736 if (EFI_ERROR (Status
)) {
1737 return EFI_OUT_OF_RESOURCES
;
1741 // Add the new text-in device data structure into the Text In List.
1743 Private
->TextInList
[Private
->CurrentNumberOfConsoles
] = TextIn
;
1744 Private
->CurrentNumberOfConsoles
++;
1747 // Extra CheckEvent added to reduce the double CheckEvent() in UI.c
1749 gBS
->CheckEvent (TextIn
->WaitForKey
);
1756 Remove Simple Text Device in Consplitter Absolute Pointer list.
1758 @param Private Text In Splitter pointer.
1759 @param TextIn Simple Text protocol pointer.
1761 @retval EFI_SUCCESS Simple Text Device removed successfully.
1762 @retval EFI_NOT_FOUND No Simple Text Device found.
1766 ConSplitterTextInDeleteDevice (
1767 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1768 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1773 // Remove the specified text-in device data structure from the Text In List,
1774 // and rearrange the remaining data structures in the Text In List.
1776 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
1777 if (Private
->TextInList
[Index
] == TextIn
) {
1778 for (Index
= Index
; Index
< Private
->CurrentNumberOfConsoles
- 1; Index
++) {
1779 Private
->TextInList
[Index
] = Private
->TextInList
[Index
+ 1];
1782 Private
->CurrentNumberOfConsoles
--;
1787 return EFI_NOT_FOUND
;
1791 Add Text Input Ex Device in Consplitter Text Input Ex list.
1793 @param Private Text In Splitter pointer.
1794 @param TextInEx Simple Text Ex Input protocol pointer.
1796 @retval EFI_SUCCESS Text Input Ex Device added successfully.
1797 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1801 ConSplitterTextInExAddDevice (
1802 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1803 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1809 // If the TextInEx List is full, enlarge it by calling growbuffer().
1811 if (Private
->CurrentNumberOfExConsoles
>= Private
->TextInExListCount
) {
1812 Status
= ConSplitterGrowBuffer (
1813 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
1814 &Private
->TextInExListCount
,
1815 (VOID
**) &Private
->TextInExList
1817 if (EFI_ERROR (Status
)) {
1818 return EFI_OUT_OF_RESOURCES
;
1822 // Add the new text-in device data structure into the Text In List.
1824 Private
->TextInExList
[Private
->CurrentNumberOfExConsoles
] = TextInEx
;
1825 Private
->CurrentNumberOfExConsoles
++;
1828 // Extra CheckEvent added to reduce the double CheckEvent() in UI.c
1830 gBS
->CheckEvent (TextInEx
->WaitForKeyEx
);
1836 Remove Simple Text Ex Device in Consplitter Absolute Pointer list.
1838 @param Private Text In Splitter pointer.
1839 @param TextInEx Simple Text Ex protocol pointer.
1841 @retval EFI_SUCCESS Simple Text Ex Device removed successfully.
1842 @retval EFI_NOT_FOUND No Simple Text Ex Device found.
1846 ConSplitterTextInExDeleteDevice (
1847 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1848 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1853 // Remove the specified text-in device data structure from the Text In List,
1854 // and rearrange the remaining data structures in the Text In List.
1856 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
1857 if (Private
->TextInExList
[Index
] == TextInEx
) {
1858 for (Index
= Index
; Index
< Private
->CurrentNumberOfExConsoles
- 1; Index
++) {
1859 Private
->TextInExList
[Index
] = Private
->TextInExList
[Index
+ 1];
1862 Private
->CurrentNumberOfExConsoles
--;
1867 return EFI_NOT_FOUND
;
1872 Add Simple Pointer Device in Consplitter Simple Pointer list.
1874 @param Private Text In Splitter pointer.
1875 @param SimplePointer Simple Pointer protocol pointer.
1877 @retval EFI_SUCCESS Simple Pointer Device added successfully.
1878 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1882 ConSplitterSimplePointerAddDevice (
1883 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1884 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
1890 // If the Text In List is full, enlarge it by calling growbuffer().
1892 if (Private
->CurrentNumberOfPointers
>= Private
->PointerListCount
) {
1893 Status
= ConSplitterGrowBuffer (
1894 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
1895 &Private
->PointerListCount
,
1896 (VOID
**) &Private
->PointerList
1898 if (EFI_ERROR (Status
)) {
1899 return EFI_OUT_OF_RESOURCES
;
1903 // Add the new text-in device data structure into the Text In List.
1905 Private
->PointerList
[Private
->CurrentNumberOfPointers
] = SimplePointer
;
1906 Private
->CurrentNumberOfPointers
++;
1912 Remove Simple Pointer Device in Consplitter Absolute Pointer list.
1914 @param Private Text In Splitter pointer.
1915 @param SimplePointer Simple Pointer protocol pointer.
1917 @retval EFI_SUCCESS Simple Pointer Device removed successfully.
1918 @retval EFI_NOT_FOUND No Simple Pointer Device found.
1922 ConSplitterSimplePointerDeleteDevice (
1923 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1924 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
1929 // Remove the specified text-in device data structure from the Text In List,
1930 // and rearrange the remaining data structures in the Text In List.
1932 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
1933 if (Private
->PointerList
[Index
] == SimplePointer
) {
1934 for (Index
= Index
; Index
< Private
->CurrentNumberOfPointers
- 1; Index
++) {
1935 Private
->PointerList
[Index
] = Private
->PointerList
[Index
+ 1];
1938 Private
->CurrentNumberOfPointers
--;
1943 return EFI_NOT_FOUND
;
1948 Add Absolute Pointer Device in Consplitter Absolute Pointer list.
1950 @param Private Text In Splitter pointer.
1951 @param AbsolutePointer Absolute Pointer protocol pointer.
1953 @retval EFI_SUCCESS Absolute Pointer Device added successfully.
1954 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1958 ConSplitterAbsolutePointerAddDevice (
1959 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1960 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
1966 // If the Absolute Pointer List is full, enlarge it by calling growbuffer().
1968 if (Private
->CurrentNumberOfAbsolutePointers
>= Private
->AbsolutePointerListCount
) {
1969 Status
= ConSplitterGrowBuffer (
1970 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
1971 &Private
->AbsolutePointerListCount
,
1972 (VOID
**) &Private
->AbsolutePointerList
1974 if (EFI_ERROR (Status
)) {
1975 return EFI_OUT_OF_RESOURCES
;
1979 // Add the new text-in device data structure into the Text In List.
1981 Private
->AbsolutePointerList
[Private
->CurrentNumberOfAbsolutePointers
] = AbsolutePointer
;
1982 Private
->CurrentNumberOfAbsolutePointers
++;
1988 Remove Absolute Pointer Device in Consplitter Absolute Pointer list.
1990 @param Private Text In Splitter pointer.
1991 @param AbsolutePointer Absolute Pointer protocol pointer.
1993 @retval EFI_SUCCESS Absolute Pointer Device removed successfully.
1994 @retval EFI_NOT_FOUND No Absolute Pointer Device found.
1998 ConSplitterAbsolutePointerDeleteDevice (
1999 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2000 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2005 // Remove the specified text-in device data structure from the Text In List,
2006 // and rearrange the remaining data structures in the Text In List.
2008 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
2009 if (Private
->AbsolutePointerList
[Index
] == AbsolutePointer
) {
2010 for (Index
= Index
; Index
< Private
->CurrentNumberOfAbsolutePointers
- 1; Index
++) {
2011 Private
->AbsolutePointerList
[Index
] = Private
->AbsolutePointerList
[Index
+ 1];
2014 Private
->CurrentNumberOfAbsolutePointers
--;
2019 return EFI_NOT_FOUND
;
2023 Reallocate Text Out mode map.
2025 @param Private Consplitter Text Out pointer.
2027 @retval EFI_SUCCESS Buffer size has grown
2028 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2032 ConSplitterGrowMapTable (
2033 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2039 INT32
*TextOutModeMap
;
2040 INT32
*OldTextOutModeMap
;
2044 NewSize
= Private
->TextOutListCount
* sizeof (INT32
);
2045 OldTextOutModeMap
= Private
->TextOutModeMap
;
2046 TotalSize
= NewSize
* Private
->TextOutQueryDataCount
;
2048 TextOutModeMap
= AllocateZeroPool (TotalSize
);
2049 if (TextOutModeMap
== NULL
) {
2050 return EFI_OUT_OF_RESOURCES
;
2053 SetMem (TextOutModeMap
, TotalSize
, 0xFF);
2054 Private
->TextOutModeMap
= TextOutModeMap
;
2057 // If TextOutList has been enlarged, need to realloc the mode map table
2058 // The mode map table is regarded as a two dimension array.
2061 // 0 ---------> TextOutListCount ----> TextOutListCount
2062 // | -------------------------------------------
2069 // -------------------------------------------
2072 if (OldTextOutModeMap
!= NULL
) {
2074 Size
= Private
->CurrentNumberOfConsoles
* sizeof (INT32
);
2076 SrcAddress
= OldTextOutModeMap
;
2079 // Copy the old data to the new one
2081 while (Index
< Private
->TextOutMode
.MaxMode
) {
2082 CopyMem (TextOutModeMap
, SrcAddress
, Size
);
2083 TextOutModeMap
+= NewSize
;
2088 // Free the old buffer
2090 FreePool (OldTextOutModeMap
);
2098 Add the device's output mode to console splitter's mode list.
2100 @param Private Text Out Splitter pointer
2101 @param TextOut Simple Text Output protocol pointer.
2103 @retval EFI_SUCCESS Device added successfully.
2104 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2108 ConSplitterAddOutputMode (
2109 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2110 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2118 MaxMode
= TextOut
->Mode
->MaxMode
;
2119 Private
->TextOutMode
.MaxMode
= MaxMode
;
2122 // Grow the buffer if query data buffer is not large enough to
2123 // hold all the mode supported by the first console.
2125 while (MaxMode
> (INT32
) Private
->TextOutQueryDataCount
) {
2126 Status
= ConSplitterGrowBuffer (
2127 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
2128 &Private
->TextOutQueryDataCount
,
2129 (VOID
**) &Private
->TextOutQueryData
2131 if (EFI_ERROR (Status
)) {
2132 return EFI_OUT_OF_RESOURCES
;
2136 // Allocate buffer for the output mode map
2138 Status
= ConSplitterGrowMapTable (Private
);
2139 if (EFI_ERROR (Status
)) {
2140 return EFI_OUT_OF_RESOURCES
;
2143 // As the first textout device, directly add the mode in to QueryData
2144 // and at the same time record the mapping between QueryData and TextOut.
2148 while (Mode
< MaxMode
) {
2149 Status
= TextOut
->QueryMode (
2152 &Private
->TextOutQueryData
[Mode
].Columns
,
2153 &Private
->TextOutQueryData
[Mode
].Rows
2156 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData
2159 if ((EFI_ERROR(Status
)) && (Mode
== 1)) {
2160 Private
->TextOutQueryData
[Mode
].Columns
= 0;
2161 Private
->TextOutQueryData
[Mode
].Rows
= 0;
2163 Private
->TextOutModeMap
[Index
] = Mode
;
2165 Index
+= Private
->TextOutListCount
;
2172 Reconstruct TextOutModeMap to get intersection of modes
2174 This routine reconstruct TextOutModeMap to get the intersection
2175 of modes for all console out devices. Because EFI/UEFI spec require
2176 mode 0 is 80x25, mode 1 is 80x50, this routine will not check the
2177 intersection for mode 0 and mode 1.
2179 @param TextOutModeMap Current text out mode map, begin with the mode 80x25
2180 @param NewlyAddedMap New text out mode map, begin with the mode 80x25
2181 @param MapStepSize Mode step size for one console device
2182 @param NewMapStepSize Mode step size for one console device
2183 @param MaxMode Current max text mode
2184 @param CurrentMode Current text mode
2190 ConSplitterGetIntersection (
2191 IN INT32
*TextOutModeMap
,
2192 IN INT32
*NewlyAddedMap
,
2193 IN UINTN MapStepSize
,
2194 IN UINTN NewMapStepSize
,
2196 OUT INT32
*CurrentMode
2200 INT32
*CurrentMapEntry
;
2201 INT32
*NextMapEntry
;
2202 INT32 CurrentMaxMode
;
2206 // According to EFI/UEFI spec, mode 0 and mode 1 have been reserved
2207 // for 80x25 and 80x50 in Simple Text Out protocol, so don't make intersection
2208 // for mode 0 and mode 1, mode number starts from 2.
2211 CurrentMapEntry
= &TextOutModeMap
[MapStepSize
* 2];
2212 NextMapEntry
= &TextOutModeMap
[MapStepSize
* 2];
2213 NewlyAddedMap
= &NewlyAddedMap
[NewMapStepSize
* 2];
2215 CurrentMaxMode
= *MaxMode
;
2216 Mode
= *CurrentMode
;
2218 while (Index
< CurrentMaxMode
) {
2219 if (*NewlyAddedMap
== -1) {
2221 // This mode is not supported any more. Remove it. Special care
2222 // must be taken as this remove will also affect current mode;
2224 if (Index
== *CurrentMode
) {
2226 } else if (Index
< *CurrentMode
) {
2231 if (CurrentMapEntry
!= NextMapEntry
) {
2232 CopyMem (NextMapEntry
, CurrentMapEntry
, MapStepSize
* sizeof (INT32
));
2235 NextMapEntry
+= MapStepSize
;
2238 CurrentMapEntry
+= MapStepSize
;
2239 NewlyAddedMap
+= NewMapStepSize
;
2243 *CurrentMode
= Mode
;
2250 Add the device's output mode to console splitter's mode list.
2252 @param Private Text Out Splitter pointer.
2253 @param TextOut Simple Text Output protocol pointer.
2259 ConSplitterSyncOutputMode (
2260 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2261 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2264 INT32 CurrentMaxMode
;
2267 INT32
*TextOutModeMap
;
2270 TEXT_OUT_SPLITTER_QUERY_DATA
*TextOutQueryData
;
2277 // Must make sure that current mode won't change even if mode number changes
2279 CurrentMaxMode
= Private
->TextOutMode
.MaxMode
;
2280 TextOutModeMap
= Private
->TextOutModeMap
;
2281 StepSize
= Private
->TextOutListCount
;
2282 TextOutQueryData
= Private
->TextOutQueryData
;
2285 // Query all the mode that the newly added TextOut supports
2288 MapTable
= TextOutModeMap
+ Private
->CurrentNumberOfConsoles
;
2289 while (Mode
< TextOut
->Mode
->MaxMode
) {
2290 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Columns
, &Rows
);
2291 if (EFI_ERROR(Status
)) {
2293 MapTable
[StepSize
] = Mode
;
2294 TextOutQueryData
[Mode
].Columns
= 0;
2295 TextOutQueryData
[Mode
].Rows
= 0;
2301 // Search the intersection map and QueryData database to see if they intersects
2304 while (Index
< CurrentMaxMode
) {
2305 QueryMode
= *(TextOutModeMap
+ Index
* StepSize
);
2306 if ((TextOutQueryData
[QueryMode
].Rows
== Rows
) && (TextOutQueryData
[QueryMode
].Columns
== Columns
)) {
2307 MapTable
[Index
* StepSize
] = Mode
;
2317 // Now search the TextOutModeMap table to find the intersection of supported
2318 // mode between ConSplitter and the newly added device.
2320 ConSplitterGetIntersection (
2325 &Private
->TextOutMode
.MaxMode
,
2326 &Private
->TextOutMode
.Mode
2334 Sync output device between ConOut and StdErr output.
2336 @retval EFI_SUCCESS Sync implemented successfully.
2337 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2341 ConSplitterGetIntersectionBetweenConOutAndStrErr (
2345 UINTN ConOutNumOfConsoles
;
2346 UINTN StdErrNumOfConsoles
;
2347 TEXT_OUT_AND_GOP_DATA
*ConOutTextOutList
;
2348 TEXT_OUT_AND_GOP_DATA
*StdErrTextOutList
;
2352 UINTN ConOutColumns
;
2354 UINTN StdErrColumns
;
2355 INT32 ConOutMaxMode
;
2356 INT32 StdErrMaxMode
;
2361 INT32
*ConOutModeMap
;
2362 INT32
*StdErrModeMap
;
2363 INT32
*ConOutMapTable
;
2364 INT32
*StdErrMapTable
;
2365 TEXT_OUT_SPLITTER_QUERY_DATA
*ConOutQueryData
;
2366 TEXT_OUT_SPLITTER_QUERY_DATA
*StdErrQueryData
;
2367 UINTN ConOutStepSize
;
2368 UINTN StdErrStepSize
;
2369 BOOLEAN FoundTheSameTextOut
;
2370 UINTN ConOutMapTableSize
;
2371 UINTN StdErrMapTableSize
;
2373 ConOutNumOfConsoles
= mConOut
.CurrentNumberOfConsoles
;
2374 StdErrNumOfConsoles
= mStdErr
.CurrentNumberOfConsoles
;
2375 ConOutTextOutList
= mConOut
.TextOutList
;
2376 StdErrTextOutList
= mStdErr
.TextOutList
;
2379 FoundTheSameTextOut
= FALSE
;
2380 while ((Indexi
< ConOutNumOfConsoles
) && (!FoundTheSameTextOut
)) {
2382 while (Indexj
< StdErrNumOfConsoles
) {
2383 if (ConOutTextOutList
->TextOut
== StdErrTextOutList
->TextOut
) {
2384 FoundTheSameTextOut
= TRUE
;
2389 StdErrTextOutList
++;
2393 ConOutTextOutList
++;
2396 if (!FoundTheSameTextOut
) {
2400 // Must make sure that current mode won't change even if mode number changes
2402 ConOutMaxMode
= mConOut
.TextOutMode
.MaxMode
;
2403 ConOutModeMap
= mConOut
.TextOutModeMap
;
2404 ConOutStepSize
= mConOut
.TextOutListCount
;
2405 ConOutQueryData
= mConOut
.TextOutQueryData
;
2407 StdErrMaxMode
= mStdErr
.TextOutMode
.MaxMode
;
2408 StdErrModeMap
= mStdErr
.TextOutModeMap
;
2409 StdErrStepSize
= mStdErr
.TextOutListCount
;
2410 StdErrQueryData
= mStdErr
.TextOutQueryData
;
2413 // Allocate the map table and set the map table's index to -1.
2415 ConOutMapTableSize
= ConOutMaxMode
* sizeof (INT32
);
2416 ConOutMapTable
= AllocateZeroPool (ConOutMapTableSize
);
2417 if (ConOutMapTable
== NULL
) {
2418 return EFI_OUT_OF_RESOURCES
;
2421 SetMem (ConOutMapTable
, ConOutMapTableSize
, 0xFF);
2423 StdErrMapTableSize
= StdErrMaxMode
* sizeof (INT32
);
2424 StdErrMapTable
= AllocateZeroPool (StdErrMapTableSize
);
2425 if (StdErrMapTable
== NULL
) {
2426 return EFI_OUT_OF_RESOURCES
;
2429 SetMem (StdErrMapTable
, StdErrMapTableSize
, 0xFF);
2432 // Find the intersection of the two set of modes. If they actually intersect, the
2433 // correponding entry in the map table is set to 1.
2436 while (Mode
< ConOutMaxMode
) {
2438 // Search the intersection map and QueryData database to see if they intersect
2441 ConOutMode
= *(ConOutModeMap
+ Mode
* ConOutStepSize
);
2442 ConOutRows
= ConOutQueryData
[ConOutMode
].Rows
;
2443 ConOutColumns
= ConOutQueryData
[ConOutMode
].Columns
;
2444 while (Index
< StdErrMaxMode
) {
2445 StdErrMode
= *(StdErrModeMap
+ Index
* StdErrStepSize
);
2446 StdErrRows
= StdErrQueryData
[StdErrMode
].Rows
;
2447 StdErrColumns
= StdErrQueryData
[StdErrMode
].Columns
;
2448 if ((StdErrRows
== ConOutRows
) && (StdErrColumns
== ConOutColumns
)) {
2449 ConOutMapTable
[Mode
] = 1;
2450 StdErrMapTable
[Index
] = 1;
2460 // Now search the TextOutModeMap table to find the intersection of supported
2461 // mode between ConSplitter and the newly added device.
2463 ConSplitterGetIntersection (
2466 mConOut
.TextOutListCount
,
2468 &(mConOut
.TextOutMode
.MaxMode
),
2469 &(mConOut
.TextOutMode
.Mode
)
2471 if (mConOut
.TextOutMode
.Mode
< 0) {
2472 mConOut
.TextOut
.SetMode (&(mConOut
.TextOut
), 0);
2475 ConSplitterGetIntersection (
2478 mStdErr
.TextOutListCount
,
2480 &(mStdErr
.TextOutMode
.MaxMode
),
2481 &(mStdErr
.TextOutMode
.Mode
)
2483 if (mStdErr
.TextOutMode
.Mode
< 0) {
2484 mStdErr
.TextOut
.SetMode (&(mStdErr
.TextOut
), 0);
2487 FreePool (ConOutMapTable
);
2488 FreePool (StdErrMapTable
);
2495 Add GOP or UGA output mode into Consplitter Text Out list.
2497 @param Private Text Out Splitter pointer.
2498 @param GraphicsOutput Graphics Output protocol pointer.
2499 @param UgaDraw UGA Draw protocol pointer.
2501 @retval EFI_SUCCESS Output mode added successfully.
2502 @retval other Failed to add output mode.
2506 ConSplitterAddGraphicsOutputMode (
2507 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2508 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2509 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2515 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
;
2517 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
2518 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*CurrentGraphicsOutputMode
;
2519 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*ModeBuffer
;
2520 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*MatchedMode
;
2523 BOOLEAN AlreadyExist
;
2524 UINT32 UgaHorizontalResolution
;
2525 UINT32 UgaVerticalResolution
;
2526 UINT32 UgaColorDepth
;
2527 UINT32 UgaRefreshRate
;
2529 if ((GraphicsOutput
== NULL
) && (UgaDraw
== NULL
)) {
2530 return EFI_UNSUPPORTED
;
2533 CurrentGraphicsOutputMode
= Private
->GraphicsOutput
.Mode
;
2538 if (Private
->CurrentNumberOfUgaDraw
!= 0) {
2540 // If any UGA device has already been added, then there is no need to
2541 // calculate intersection of display mode of different GOP/UGA device,
2542 // since only one display mode will be exported (i.e. user-defined mode)
2547 if (GraphicsOutput
!= NULL
) {
2548 if (Private
->CurrentNumberOfGraphicsOutput
== 0) {
2550 // This is the first Graphics Output device added
2552 CurrentGraphicsOutputMode
->MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
2553 CurrentGraphicsOutputMode
->Mode
= GraphicsOutput
->Mode
->Mode
;
2554 CopyMem (CurrentGraphicsOutputMode
->Info
, GraphicsOutput
->Mode
->Info
, GraphicsOutput
->Mode
->SizeOfInfo
);
2555 CurrentGraphicsOutputMode
->SizeOfInfo
= GraphicsOutput
->Mode
->SizeOfInfo
;
2556 CurrentGraphicsOutputMode
->FrameBufferBase
= GraphicsOutput
->Mode
->FrameBufferBase
;
2557 CurrentGraphicsOutputMode
->FrameBufferSize
= GraphicsOutput
->Mode
->FrameBufferSize
;
2560 // Allocate resource for the private mode buffer
2562 ModeBuffer
= AllocatePool (GraphicsOutput
->Mode
->SizeOfInfo
* GraphicsOutput
->Mode
->MaxMode
);
2563 if (ModeBuffer
== NULL
) {
2564 return EFI_OUT_OF_RESOURCES
;
2566 FreePool (Private
->GraphicsOutputModeBuffer
);
2567 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2570 // Store all supported display modes to the private mode buffer
2573 for (Index
= 0; Index
< GraphicsOutput
->Mode
->MaxMode
; Index
++) {
2574 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) Index
, &SizeOfInfo
, &Info
);
2575 if (EFI_ERROR (Status
)) {
2578 CopyMem (Mode
, Info
, SizeOfInfo
);
2584 // Check intersection of display mode
2586 ModeBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
) * CurrentGraphicsOutputMode
->MaxMode
);
2587 if (ModeBuffer
== NULL
) {
2588 return EFI_OUT_OF_RESOURCES
;
2591 MatchedMode
= ModeBuffer
;
2592 Mode
= &Private
->GraphicsOutputModeBuffer
[0];
2593 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2596 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
2597 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
2598 if (EFI_ERROR (Status
)) {
2601 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2602 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2611 AlreadyExist
= FALSE
;
2613 for (Info
= ModeBuffer
; Info
< MatchedMode
; Info
++) {
2614 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2615 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2616 AlreadyExist
= TRUE
;
2621 if (!AlreadyExist
) {
2622 CopyMem (MatchedMode
, Mode
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2625 // Physical frame buffer is no longer available, change PixelFormat to PixelBltOnly
2627 MatchedMode
->Version
= 0;
2628 MatchedMode
->PixelFormat
= PixelBltOnly
;
2629 ZeroMem (&MatchedMode
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2639 // Drop the old mode buffer, assign it to a new one
2641 FreePool (Private
->GraphicsOutputModeBuffer
);
2642 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2645 // Physical frame buffer is no longer available when there are more than one physical GOP devices
2647 CurrentGraphicsOutputMode
->MaxMode
= (UINT32
) (((UINTN
) MatchedMode
- (UINTN
) ModeBuffer
) / sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2648 CurrentGraphicsOutputMode
->Info
->PixelFormat
= PixelBltOnly
;
2649 ZeroMem (&CurrentGraphicsOutputMode
->Info
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2650 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2651 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2652 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2656 // Graphics console driver can ensure the same mode for all GOP devices
2658 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2659 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2660 if ((Mode
->HorizontalResolution
== GraphicsOutput
->Mode
->Info
->HorizontalResolution
) &&
2661 (Mode
->VerticalResolution
== GraphicsOutput
->Mode
->Info
->VerticalResolution
)) {
2662 CurrentIndex
= Index
;
2666 if (Index
>= CurrentGraphicsOutputMode
->MaxMode
) {
2668 // if user defined mode is not found, set to default mode 800x600
2670 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2671 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2672 if ((Mode
->HorizontalResolution
== 800) && (Mode
->VerticalResolution
== 600)) {
2673 CurrentIndex
= Index
;
2679 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2681 // Graphics console driver can ensure the same mode for all GOP devices
2682 // so we can get the current mode from this video device
2686 &UgaHorizontalResolution
,
2687 &UgaVerticalResolution
,
2692 CurrentGraphicsOutputMode
->MaxMode
= 1;
2693 Info
= CurrentGraphicsOutputMode
->Info
;
2695 Info
->HorizontalResolution
= UgaHorizontalResolution
;
2696 Info
->VerticalResolution
= UgaVerticalResolution
;
2697 Info
->PixelFormat
= PixelBltOnly
;
2698 Info
->PixelsPerScanLine
= UgaHorizontalResolution
;
2699 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2700 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2701 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2704 // Update the private mode buffer
2706 CopyMem (&Private
->GraphicsOutputModeBuffer
[0], Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2709 // Only mode 0 is available to be set
2716 if (GraphicsOutput
!= NULL
) {
2717 Private
->CurrentNumberOfGraphicsOutput
++;
2719 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2720 Private
->CurrentNumberOfUgaDraw
++;
2724 // Force GraphicsOutput mode to be set,
2725 // regardless whether the console is in EfiConsoleControlScreenGraphics or EfiConsoleControlScreenText mode
2727 Private
->HardwareNeedsStarting
= TRUE
;
2729 // Current mode number may need update now, so set it to an invalid mode number
2731 CurrentGraphicsOutputMode
->Mode
= 0xffff;
2733 // Graphics console can ensure all GOP devices have the same mode which can be taken as current mode.
2735 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, (UINT32
) CurrentIndex
);
2738 // If user defined mode is not valid for UGA, set to the default mode 800x600.
2740 if (EFI_ERROR(Status
)) {
2741 (Private
->GraphicsOutputModeBuffer
[0]).HorizontalResolution
= 800;
2742 (Private
->GraphicsOutputModeBuffer
[0]).VerticalResolution
= 600;
2743 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, 0);
2751 This routine will get the current console mode information (column, row)
2752 from ConsoleOutMode variable and set it; if the variable does not exist,
2753 set to user defined console mode.
2755 @param Private Consplitter Text Out pointer.
2761 ConsplitterSetConsoleOutMode (
2762 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2773 CONSOLE_OUT_MODE
*ModeInfo
;
2774 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
2778 TextOut
= &Private
->TextOut
;
2779 MaxMode
= (UINTN
) (TextOut
->Mode
->MaxMode
);
2780 ModeInfoSize
= sizeof (CONSOLE_OUT_MODE
);
2782 ModeInfo
= AllocateZeroPool (sizeof(CONSOLE_OUT_MODE
));
2783 ASSERT(ModeInfo
!= NULL
);
2785 Status
= gRT
->GetVariable (
2787 &gEfiGenericPlatformVariableGuid
,
2794 // Set to the default mode 80 x 25 required by EFI/UEFI spec;
2795 // user can also define other valid default console mode here.
2797 if (EFI_ERROR(Status
)) {
2798 ModeInfo
->Column
= 80;
2800 Status
= gRT
->SetVariable (
2802 &gEfiGenericPlatformVariableGuid
,
2803 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
2804 sizeof (CONSOLE_OUT_MODE
),
2809 for (Mode
= 0; Mode
< MaxMode
; Mode
++) {
2810 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Col
, &Row
);
2811 if (!EFI_ERROR(Status
)) {
2812 if (Col
== ModeInfo
->Column
&& Row
== ModeInfo
->Row
) {
2815 if (Col
== 80 && Row
== 25) {
2821 Status
= TextOut
->SetMode (TextOut
, PreferMode
);
2824 // if current mode setting is failed, default 80x25 mode will be set.
2826 if (EFI_ERROR(Status
)) {
2827 Status
= TextOut
->SetMode (TextOut
, BaseMode
);
2828 ASSERT(!EFI_ERROR(Status
));
2830 ModeInfo
->Column
= 80;
2834 // Update ConOutMode variable
2836 Status
= gRT
->SetVariable (
2838 &gEfiGenericPlatformVariableGuid
,
2839 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
2840 sizeof (CONSOLE_OUT_MODE
),
2845 gBS
->FreePool (ModeInfo
);
2850 Add Text Output Device in Consplitter Text Output list.
2852 @param Private Text Out Splitter pointer.
2853 @param TextOut Simple Text Output protocol pointer.
2854 @param GraphicsOutput Graphics Output protocol pointer.
2855 @param UgaDraw UGA Draw protocol pointer.
2857 @retval EFI_SUCCESS Text Output Device added successfully.
2858 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2862 ConSplitterTextOutAddDevice (
2863 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2864 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
,
2865 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2866 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2870 UINTN CurrentNumOfConsoles
;
2873 UINT32 UgaHorizontalResolution
;
2874 UINT32 UgaVerticalResolution
;
2875 UINT32 UgaColorDepth
;
2876 UINT32 UgaRefreshRate
;
2877 TEXT_OUT_AND_GOP_DATA
*TextAndGop
;
2879 Status
= EFI_SUCCESS
;
2880 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
2883 // If the Text Out List is full, enlarge it by calling growbuffer().
2885 while (CurrentNumOfConsoles
>= Private
->TextOutListCount
) {
2886 Status
= ConSplitterGrowBuffer (
2887 sizeof (TEXT_OUT_AND_GOP_DATA
),
2888 &Private
->TextOutListCount
,
2889 (VOID
**) &Private
->TextOutList
2891 if (EFI_ERROR (Status
)) {
2892 return EFI_OUT_OF_RESOURCES
;
2895 // Also need to reallocate the TextOutModeMap table
2897 Status
= ConSplitterGrowMapTable (Private
);
2898 if (EFI_ERROR (Status
)) {
2899 return EFI_OUT_OF_RESOURCES
;
2903 TextAndGop
= &Private
->TextOutList
[CurrentNumOfConsoles
];
2905 TextAndGop
->TextOut
= TextOut
;
2906 TextAndGop
->GraphicsOutput
= GraphicsOutput
;
2907 TextAndGop
->UgaDraw
= UgaDraw
;
2909 if ((GraphicsOutput
== NULL
) && (UgaDraw
== NULL
)) {
2911 // If No GOP/UGA device then use the ConOut device
2913 TextAndGop
->TextOutEnabled
= TRUE
;
2916 // If GOP/UGA device use ConOut device only used if screen is in Text mode
2918 TextAndGop
->TextOutEnabled
= (BOOLEAN
) (Private
->ConsoleOutputMode
== EfiConsoleControlScreenText
);
2921 if (CurrentNumOfConsoles
== 0) {
2923 // Add the first device's output mode to console splitter's mode list
2925 Status
= ConSplitterAddOutputMode (Private
, TextOut
);
2927 ConSplitterSyncOutputMode (Private
, TextOut
);
2930 Private
->CurrentNumberOfConsoles
++;
2933 // Scan both TextOutList, for the intersection TextOut device
2934 // maybe both ConOut and StdErr incorporate the same Text Out
2935 // device in them, thus the output of both should be synced.
2937 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
2939 CurrentMode
= Private
->TextOutMode
.Mode
;
2940 MaxMode
= Private
->TextOutMode
.MaxMode
;
2941 ASSERT (MaxMode
>= 1);
2944 // Update DevNull mode according to current video device
2946 if (FeaturePcdGet (PcdConOutGopSupport
)) {
2947 if ((GraphicsOutput
!= NULL
) || (UgaDraw
!= NULL
)) {
2948 ConSplitterAddGraphicsOutputMode (Private
, GraphicsOutput
, UgaDraw
);
2951 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
2952 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2953 Status
= UgaDraw
->GetMode (
2955 &UgaHorizontalResolution
,
2956 &UgaVerticalResolution
,
2960 if (!EFI_ERROR (Status
)) {
2961 Status
= ConSpliterUgaDrawSetMode (
2963 UgaHorizontalResolution
,
2964 UgaVerticalResolution
,
2970 // If GetMode/SetMode is failed, set to 800x600 mode
2972 if(EFI_ERROR (Status
)) {
2973 Status
= ConSpliterUgaDrawSetMode (
2984 if (Private
->ConsoleOutputMode
== EfiConsoleControlScreenGraphics
&& GraphicsOutput
!= NULL
) {
2986 // We just added a new GOP or UGA device in graphics mode
2988 if (FeaturePcdGet (PcdConOutGopSupport
)) {
2989 DevNullGopSync (Private
, TextAndGop
->GraphicsOutput
, TextAndGop
->UgaDraw
);
2990 } else if (FeaturePcdGet (PcdConOutUgaSupport
)) {
2991 DevNullUgaSync (Private
, TextAndGop
->GraphicsOutput
, TextAndGop
->UgaDraw
);
2993 } else if ((CurrentMode
>= 0) && ((GraphicsOutput
!= NULL
) || (UgaDraw
!= NULL
)) && (CurrentMode
< Private
->TextOutMode
.MaxMode
)) {
2995 // The new console supports the same mode of the current console so sync up
2997 DevNullSyncStdOut (Private
);
3000 // If ConOut, then set the mode to Mode #0 which us 80 x 25
3002 Private
->TextOut
.SetMode (&Private
->TextOut
, 0);
3006 // After adding new console device, all existing console devices should be
3007 // synced to the current shared mode.
3009 ConsplitterSetConsoleOutMode (Private
);
3016 Remove Text Out Device in Consplitter Text Out list.
3018 @param Private Text Out Splitter pointer.
3019 @param TextOut Simple Text Output Pointer protocol pointer.
3021 @retval EFI_SUCCESS Text Out Device removed successfully.
3022 @retval EFI_NOT_FOUND No Text Out Device found.
3026 ConSplitterTextOutDeleteDevice (
3027 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
3028 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
3032 UINTN CurrentNumOfConsoles
;
3033 TEXT_OUT_AND_GOP_DATA
*TextOutList
;
3037 // Remove the specified text-out device data structure from the Text out List,
3038 // and rearrange the remaining data structures in the Text out List.
3040 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
3041 Index
= (INT32
) CurrentNumOfConsoles
- 1;
3042 TextOutList
= Private
->TextOutList
;
3043 while (Index
>= 0) {
3044 if (TextOutList
->TextOut
== TextOut
) {
3045 CopyMem (TextOutList
, TextOutList
+ 1, sizeof (TEXT_OUT_AND_GOP_DATA
) * Index
);
3046 CurrentNumOfConsoles
--;
3047 if (TextOutList
->UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3048 Private
->CurrentNumberOfUgaDraw
--;
3050 if (TextOutList
->GraphicsOutput
!= NULL
) {
3051 Private
->CurrentNumberOfGraphicsOutput
--;
3060 // The specified TextOut is not managed by the ConSplitter driver
3063 return EFI_NOT_FOUND
;
3066 if (CurrentNumOfConsoles
== 0) {
3068 // If the number of consoles is zero clear the Dev NULL device
3070 Private
->CurrentNumberOfConsoles
= 0;
3071 Private
->TextOutMode
.MaxMode
= 1;
3072 Private
->TextOutQueryData
[0].Columns
= 80;
3073 Private
->TextOutQueryData
[0].Rows
= 25;
3074 DevNullTextOutSetMode (Private
, 0);
3079 // Max Mode is realy an intersection of the QueryMode command to all
3080 // devices. So we must copy the QueryMode of the first device to
3084 Private
->TextOutQueryData
,
3085 Private
->TextOutQueryDataCount
* sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
)
3088 FreePool (Private
->TextOutModeMap
);
3089 Private
->TextOutModeMap
= NULL
;
3090 TextOutList
= Private
->TextOutList
;
3093 // Add the first TextOut to the QueryData array and ModeMap table
3095 Status
= ConSplitterAddOutputMode (Private
, TextOutList
->TextOut
);
3098 // Now add one by one
3101 Private
->CurrentNumberOfConsoles
= 1;
3103 while ((UINTN
) Index
< CurrentNumOfConsoles
) {
3104 ConSplitterSyncOutputMode (Private
, TextOutList
->TextOut
);
3106 Private
->CurrentNumberOfConsoles
++;
3110 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3115 // ConSplitter TextIn member functions
3119 Reset the input device and optionaly run diagnostics
3121 @param This Protocol instance pointer.
3122 @param ExtendedVerification Driver may perform diagnostics on reset.
3124 @retval EFI_SUCCESS The device was reset.
3125 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3131 ConSplitterTextInReset (
3132 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3133 IN BOOLEAN ExtendedVerification
3137 EFI_STATUS ReturnStatus
;
3138 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3141 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3143 Private
->KeyEventSignalState
= FALSE
;
3146 // return the worst status met
3148 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3149 Status
= Private
->TextInList
[Index
]->Reset (
3150 Private
->TextInList
[Index
],
3151 ExtendedVerification
3153 if (EFI_ERROR (Status
)) {
3154 ReturnStatus
= Status
;
3158 return ReturnStatus
;
3163 Reads the next keystroke from the input device. The WaitForKey Event can
3164 be used to test for existance of a keystroke via WaitForEvent () call.
3166 @param Private Protocol instance pointer.
3167 @param Key Driver may perform diagnostics on reset.
3169 @retval EFI_SUCCESS The keystroke information was returned.
3170 @retval EFI_NOT_READY There was no keystroke data availiable.
3171 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3177 ConSplitterTextInPrivateReadKeyStroke (
3178 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3179 OUT EFI_INPUT_KEY
*Key
3184 EFI_INPUT_KEY CurrentKey
;
3186 Key
->UnicodeChar
= 0;
3187 Key
->ScanCode
= SCAN_NULL
;
3190 // if no physical console input device exists, return EFI_NOT_READY;
3191 // if any physical console input device has key input,
3192 // return the key and EFI_SUCCESS.
3194 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3195 Status
= Private
->TextInList
[Index
]->ReadKeyStroke (
3196 Private
->TextInList
[Index
],
3199 if (!EFI_ERROR (Status
)) {
3205 return EFI_NOT_READY
;
3210 Return TRUE if StdIn is locked. The ConIn device on the virtual handle is
3211 the only device locked.
3215 @retval TRUE StdIn locked
3216 @retval FALSE StdIn working normally
3220 ConSpliterConssoleControlStdInLocked (
3224 return mConIn
.PasswordEnabled
;
3229 This timer event will fire when StdIn is locked. It will check the key
3230 sequence on StdIn to see if it matches the password. Any error in the
3231 password will cause the check to reset. As long a mConIn.PasswordEnabled is
3232 TRUE the StdIn splitter will not report any input.
3234 @param Event The Event this notify function registered to.
3235 @param Context Pointer to the context data registerd to the
3243 ConSpliterConsoleControlLockStdInEvent (
3250 CHAR16 BackSpaceString
[2];
3251 CHAR16 SpaceString
[2];
3254 Status
= ConSplitterTextInPrivateReadKeyStroke (&mConIn
, &Key
);
3255 if (!EFI_ERROR (Status
)) {
3257 // if it's an ENTER, match password
3259 if ((Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) && (Key
.ScanCode
== SCAN_NULL
)) {
3260 mConIn
.PwdAttempt
[mConIn
.PwdIndex
] = CHAR_NULL
;
3261 if (StrCmp (mConIn
.Password
, mConIn
.PwdAttempt
)) {
3263 // Password not match
3265 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"\n\rPassword not correct\n\r");
3266 mConIn
.PwdIndex
= 0;
3269 // Key matches password sequence
3271 gBS
->SetTimer (mConIn
.LockEvent
, TimerPeriodic
, 0);
3272 mConIn
.PasswordEnabled
= FALSE
;
3273 Status
= EFI_NOT_READY
;
3275 } else if ((Key
.UnicodeChar
== CHAR_BACKSPACE
) && (Key
.ScanCode
== SCAN_NULL
)) {
3279 if (mConIn
.PwdIndex
> 0) {
3280 BackSpaceString
[0] = CHAR_BACKSPACE
;
3281 BackSpaceString
[1] = 0;
3283 SpaceString
[0] = ' ';
3286 ConSplitterTextOutOutputString (&mConOut
.TextOut
, BackSpaceString
);
3287 ConSplitterTextOutOutputString (&mConOut
.TextOut
, SpaceString
);
3288 ConSplitterTextOutOutputString (&mConOut
.TextOut
, BackSpaceString
);
3292 } else if ((Key
.ScanCode
== SCAN_NULL
) && (Key
.UnicodeChar
>= 32)) {
3294 // If it's not an ENTER, neigher a function key, nor a CTRL-X or ALT-X, record the input
3296 if (mConIn
.PwdIndex
< (MAX_STD_IN_PASSWORD
- 1)) {
3297 if (mConIn
.PwdIndex
== 0) {
3298 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"\n\r");
3301 ConSplitterTextOutOutputString (&mConOut
.TextOut
, (CHAR16
*) L
"*");
3302 mConIn
.PwdAttempt
[mConIn
.PwdIndex
] = Key
.UnicodeChar
;
3307 } while (!EFI_ERROR (Status
));
3312 If Password is NULL unlock the password state variable and set the event
3313 timer. If the Password is too big return an error. If the Password is valid
3314 Copy the Password and enable state variable and then arm the periodic timer
3316 @param This Console Control protocol pointer.
3317 @param Password The password input.
3319 @retval EFI_SUCCESS Lock the StdIn device
3320 @retval EFI_INVALID_PARAMETER Password is NULL
3321 @retval EFI_OUT_OF_RESOURCES Buffer allocation to store the password fails
3326 ConSpliterConsoleControlLockStdIn (
3327 IN EFI_CONSOLE_CONTROL_PROTOCOL
*This
,
3331 if (Password
== NULL
) {
3332 return EFI_INVALID_PARAMETER
;
3335 if (StrLen (Password
) >= MAX_STD_IN_PASSWORD
) {
3337 // Currently have a max password size
3339 return EFI_OUT_OF_RESOURCES
;
3342 // Save the password, initialize state variables and arm event timer
3344 StrCpy (mConIn
.Password
, Password
);
3345 mConIn
.PasswordEnabled
= TRUE
;
3346 mConIn
.PwdIndex
= 0;
3347 gBS
->SetTimer (mConIn
.LockEvent
, TimerPeriodic
, (10000 * 25));
3354 Reads the next keystroke from the input device. The WaitForKey Event can
3355 be used to test for existance of a keystroke via WaitForEvent () call.
3356 If the ConIn is password locked make it look like no keystroke is availible
3358 @param This Protocol instance pointer.
3359 @param Key Driver may perform diagnostics on reset.
3361 @retval EFI_SUCCESS The keystroke information was returned.
3362 @retval EFI_NOT_READY There was no keystroke data availiable.
3363 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3369 ConSplitterTextInReadKeyStroke (
3370 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3371 OUT EFI_INPUT_KEY
*Key
3374 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3376 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3377 if (Private
->PasswordEnabled
) {
3379 // If StdIn Locked return not ready
3381 return EFI_NOT_READY
;
3384 Private
->KeyEventSignalState
= FALSE
;
3386 return ConSplitterTextInPrivateReadKeyStroke (Private
, Key
);
3391 This event agregates all the events of the ConIn devices in the spliter.
3392 If the ConIn is password locked then return.
3393 If any events of physical ConIn devices are signaled, signal the ConIn
3394 spliter event. This will cause the calling code to call
3395 ConSplitterTextInReadKeyStroke ().
3397 @param Event The Event assoicated with callback.
3398 @param Context Context registered when Event was created.
3405 ConSplitterTextInWaitForKey (
3411 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3414 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
3415 if (Private
->PasswordEnabled
) {
3417 // If StdIn Locked return not ready
3423 // if KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
3425 if (Private
->KeyEventSignalState
) {
3426 gBS
->SignalEvent (Event
);
3430 // if any physical console input device has key input, signal the event.
3432 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3433 Status
= gBS
->CheckEvent (Private
->TextInList
[Index
]->WaitForKey
);
3434 if (!EFI_ERROR (Status
)) {
3435 gBS
->SignalEvent (Event
);
3436 Private
->KeyEventSignalState
= TRUE
;
3445 @param RegsiteredData A pointer to a buffer that is filled in with the
3446 keystroke state data for the key that was
3448 @param InputData A pointer to a buffer that is filled in with the
3449 keystroke state data for the key that was
3452 @retval TRUE Key be pressed matches a registered key.
3453 @retval FLASE Match failed.
3458 IN EFI_KEY_DATA
*RegsiteredData
,
3459 IN EFI_KEY_DATA
*InputData
3462 ASSERT (RegsiteredData
!= NULL
&& InputData
!= NULL
);
3464 if ((RegsiteredData
->Key
.ScanCode
!= InputData
->Key
.ScanCode
) ||
3465 (RegsiteredData
->Key
.UnicodeChar
!= InputData
->Key
.UnicodeChar
)) {
3470 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
3472 if (RegsiteredData
->KeyState
.KeyShiftState
!= 0 &&
3473 RegsiteredData
->KeyState
.KeyShiftState
!= InputData
->KeyState
.KeyShiftState
) {
3476 if (RegsiteredData
->KeyState
.KeyToggleState
!= 0 &&
3477 RegsiteredData
->KeyState
.KeyToggleState
!= InputData
->KeyState
.KeyToggleState
) {
3486 // Simple Text Input Ex protocol functions
3491 Reset the input device and optionaly run diagnostics
3493 @param This Protocol instance pointer.
3494 @param ExtendedVerification Driver may perform diagnostics on reset.
3496 @retval EFI_SUCCESS The device was reset.
3497 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3503 ConSplitterTextInResetEx (
3504 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3505 IN BOOLEAN ExtendedVerification
3509 EFI_STATUS ReturnStatus
;
3510 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3513 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3515 Private
->KeyEventSignalState
= FALSE
;
3518 // return the worst status met
3520 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3521 Status
= Private
->TextInExList
[Index
]->Reset (
3522 Private
->TextInExList
[Index
],
3523 ExtendedVerification
3525 if (EFI_ERROR (Status
)) {
3526 ReturnStatus
= Status
;
3530 return ReturnStatus
;
3536 Reads the next keystroke from the input device. The WaitForKey Event can
3537 be used to test for existance of a keystroke via WaitForEvent () call.
3539 @param This Protocol instance pointer.
3540 @param KeyData A pointer to a buffer that is filled in with the
3541 keystroke state data for the key that was
3544 @retval EFI_SUCCESS The keystroke information was returned.
3545 @retval EFI_NOT_READY There was no keystroke data availiable.
3546 @retval EFI_DEVICE_ERROR The keystroke information was not returned due
3548 @retval EFI_INVALID_PARAMETER KeyData is NULL.
3553 ConSplitterTextInReadKeyStrokeEx (
3554 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3555 OUT EFI_KEY_DATA
*KeyData
3558 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3561 EFI_KEY_DATA CurrentKeyData
;
3564 if (KeyData
== NULL
) {
3565 return EFI_INVALID_PARAMETER
;
3568 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3569 if (Private
->PasswordEnabled
) {
3571 // If StdIn Locked return not ready
3573 return EFI_NOT_READY
;
3576 Private
->KeyEventSignalState
= FALSE
;
3578 KeyData
->Key
.UnicodeChar
= 0;
3579 KeyData
->Key
.ScanCode
= SCAN_NULL
;
3582 // if no physical console input device exists, return EFI_NOT_READY;
3583 // if any physical console input device has key input,
3584 // return the key and EFI_SUCCESS.
3586 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3587 Status
= Private
->TextInExList
[Index
]->ReadKeyStrokeEx (
3588 Private
->TextInExList
[Index
],
3591 if (!EFI_ERROR (Status
)) {
3592 CopyMem (KeyData
, &CurrentKeyData
, sizeof (CurrentKeyData
));
3597 return EFI_NOT_READY
;
3602 Set certain state for the input device.
3604 @param This Protocol instance pointer.
3605 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
3606 state for the input device.
3608 @retval EFI_SUCCESS The device state was set successfully.
3609 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
3610 could not have the setting adjusted.
3611 @retval EFI_UNSUPPORTED The device does not have the ability to set its
3613 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
3618 ConSplitterTextInSetState (
3619 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3620 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
3623 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3627 if (KeyToggleState
== NULL
) {
3628 return EFI_INVALID_PARAMETER
;
3631 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3634 // if no physical console input device exists, return EFI_SUCCESS;
3635 // otherwise return the status of setting state of physical console input device
3637 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3638 Status
= Private
->TextInExList
[Index
]->SetState (
3639 Private
->TextInExList
[Index
],
3642 if (EFI_ERROR (Status
)) {
3653 Register a notification function for a particular keystroke for the input device.
3655 @param This Protocol instance pointer.
3656 @param KeyData A pointer to a buffer that is filled in with the
3657 keystroke information data for the key that was
3659 @param KeyNotificationFunction Points to the function to be called when the key
3660 sequence is typed specified by KeyData.
3661 @param NotifyHandle Points to the unique handle assigned to the
3662 registered notification.
3664 @retval EFI_SUCCESS The notification function was registered
3666 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data
3668 @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.
3673 ConSplitterTextInRegisterKeyNotify (
3674 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3675 IN EFI_KEY_DATA
*KeyData
,
3676 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction
,
3677 OUT EFI_HANDLE
*NotifyHandle
3680 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3683 TEXT_IN_EX_SPLITTER_NOTIFY
*NewNotify
;
3685 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3688 if (KeyData
== NULL
|| NotifyHandle
== NULL
|| KeyNotificationFunction
== NULL
) {
3689 return EFI_INVALID_PARAMETER
;
3692 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3695 // if no physical console input device exists,
3696 // return EFI_SUCCESS directly.
3698 if (Private
->CurrentNumberOfExConsoles
<= 0) {
3703 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
3705 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3706 CurrentNotify
= CR (
3708 TEXT_IN_EX_SPLITTER_NOTIFY
,
3710 TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
3712 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
3713 if (CurrentNotify
->KeyNotificationFn
== KeyNotificationFunction
) {
3714 *NotifyHandle
= CurrentNotify
->NotifyHandle
;
3721 // Allocate resource to save the notification function
3723 NewNotify
= (TEXT_IN_EX_SPLITTER_NOTIFY
*) AllocateZeroPool (sizeof (TEXT_IN_EX_SPLITTER_NOTIFY
));
3724 if (NewNotify
== NULL
) {
3725 return EFI_OUT_OF_RESOURCES
;
3727 NewNotify
->NotifyHandleList
= (EFI_HANDLE
*) AllocateZeroPool (sizeof (EFI_HANDLE
) * Private
->CurrentNumberOfExConsoles
);
3728 if (NewNotify
->NotifyHandleList
== NULL
) {
3729 gBS
->FreePool (NewNotify
);
3730 return EFI_OUT_OF_RESOURCES
;
3732 NewNotify
->Signature
= TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
;
3733 NewNotify
->KeyNotificationFn
= KeyNotificationFunction
;
3734 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (KeyData
));
3737 // Return the wrong status of registering key notify of
3738 // physical console input device if meet problems
3740 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3741 Status
= Private
->TextInExList
[Index
]->RegisterKeyNotify (
3742 Private
->TextInExList
[Index
],
3744 KeyNotificationFunction
,
3745 &NewNotify
->NotifyHandleList
[Index
]
3747 if (EFI_ERROR (Status
)) {
3748 gBS
->FreePool (NewNotify
->NotifyHandleList
);
3749 gBS
->FreePool (NewNotify
);
3755 // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE
3757 Status
= gBS
->InstallMultipleProtocolInterfaces (
3758 &NewNotify
->NotifyHandle
,
3759 &gSimpleTextInExNotifyGuid
,
3763 ASSERT_EFI_ERROR (Status
);
3765 InsertTailList (&mConIn
.NotifyList
, &NewNotify
->NotifyEntry
);
3767 *NotifyHandle
= NewNotify
->NotifyHandle
;
3775 Remove a registered notification function from a particular keystroke.
3777 @param This Protocol instance pointer.
3778 @param NotificationHandle The handle of the notification function being
3781 @retval EFI_SUCCESS The notification function was unregistered
3783 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
3784 @retval EFI_NOT_FOUND Can not find the matching entry in database.
3789 ConSplitterTextInUnregisterKeyNotify (
3790 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3791 IN EFI_HANDLE NotificationHandle
3794 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3797 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3800 if (NotificationHandle
== NULL
) {
3801 return EFI_INVALID_PARAMETER
;
3804 Status
= gBS
->OpenProtocol (
3806 &gSimpleTextInExNotifyGuid
,
3810 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
3812 if (EFI_ERROR (Status
)) {
3813 return EFI_INVALID_PARAMETER
;
3816 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3819 // if no physical console input device exists,
3820 // return EFI_SUCCESS directly.
3822 if (Private
->CurrentNumberOfExConsoles
<= 0) {
3826 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3827 CurrentNotify
= CR (Link
, TEXT_IN_EX_SPLITTER_NOTIFY
, NotifyEntry
, TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
);
3828 if (CurrentNotify
->NotifyHandle
== NotificationHandle
) {
3829 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3830 Status
= Private
->TextInExList
[Index
]->UnregisterKeyNotify (
3831 Private
->TextInExList
[Index
],
3832 CurrentNotify
->NotifyHandleList
[Index
]
3834 if (EFI_ERROR (Status
)) {
3838 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
3839 Status
= gBS
->UninstallMultipleProtocolInterfaces (
3840 CurrentNotify
->NotifyHandle
,
3841 &gSimpleTextInExNotifyGuid
,
3845 ASSERT_EFI_ERROR (Status
);
3846 gBS
->FreePool (CurrentNotify
->NotifyHandleList
);
3847 gBS
->FreePool (CurrentNotify
);
3852 return EFI_NOT_FOUND
;
3858 Reset the input device and optionaly run diagnostics
3860 @param This Protocol instance pointer.
3861 @param ExtendedVerification Driver may perform diagnostics on reset.
3863 @retval EFI_SUCCESS The device was reset.
3864 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3870 ConSplitterSimplePointerReset (
3871 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
3872 IN BOOLEAN ExtendedVerification
3876 EFI_STATUS ReturnStatus
;
3877 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3880 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
3882 Private
->InputEventSignalState
= FALSE
;
3884 if (Private
->CurrentNumberOfPointers
== 0) {
3888 // return the worst status met
3890 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3891 Status
= Private
->PointerList
[Index
]->Reset (
3892 Private
->PointerList
[Index
],
3893 ExtendedVerification
3895 if (EFI_ERROR (Status
)) {
3896 ReturnStatus
= Status
;
3900 return ReturnStatus
;
3905 Reads the next keystroke from the input device. The WaitForKey Event can
3906 be used to test for existance of a keystroke via WaitForEvent () call.
3908 @param Private Protocol instance pointer.
3909 @param State The state information of simple pointer device.
3911 @retval EFI_SUCCESS The keystroke information was returned.
3912 @retval EFI_NOT_READY There was no keystroke data availiable.
3913 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3919 ConSplitterSimplePointerPrivateGetState (
3920 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3921 IN OUT EFI_SIMPLE_POINTER_STATE
*State
3925 EFI_STATUS ReturnStatus
;
3927 EFI_SIMPLE_POINTER_STATE CurrentState
;
3929 State
->RelativeMovementX
= 0;
3930 State
->RelativeMovementY
= 0;
3931 State
->RelativeMovementZ
= 0;
3932 State
->LeftButton
= FALSE
;
3933 State
->RightButton
= FALSE
;
3936 // if no physical console input device exists, return EFI_NOT_READY;
3937 // if any physical console input device has key input,
3938 // return the key and EFI_SUCCESS.
3940 ReturnStatus
= EFI_NOT_READY
;
3941 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3943 Status
= Private
->PointerList
[Index
]->GetState (
3944 Private
->PointerList
[Index
],
3947 if (!EFI_ERROR (Status
)) {
3948 if (ReturnStatus
== EFI_NOT_READY
) {
3949 ReturnStatus
= EFI_SUCCESS
;
3952 if (CurrentState
.LeftButton
) {
3953 State
->LeftButton
= TRUE
;
3956 if (CurrentState
.RightButton
) {
3957 State
->RightButton
= TRUE
;
3960 if (CurrentState
.RelativeMovementX
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionX
!= 0) {
3961 State
->RelativeMovementX
+= (CurrentState
.RelativeMovementX
* (INT32
) Private
->SimplePointerMode
.ResolutionX
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionX
;
3964 if (CurrentState
.RelativeMovementY
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionY
!= 0) {
3965 State
->RelativeMovementY
+= (CurrentState
.RelativeMovementY
* (INT32
) Private
->SimplePointerMode
.ResolutionY
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionY
;
3968 if (CurrentState
.RelativeMovementZ
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionZ
!= 0) {
3969 State
->RelativeMovementZ
+= (CurrentState
.RelativeMovementZ
* (INT32
) Private
->SimplePointerMode
.ResolutionZ
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionZ
;
3971 } else if (Status
== EFI_DEVICE_ERROR
) {
3972 ReturnStatus
= EFI_DEVICE_ERROR
;
3976 return ReturnStatus
;
3981 Reads the next keystroke from the input device. The WaitForKey Event can
3982 be used to test for existance of a keystroke via WaitForEvent () call.
3983 If the ConIn is password locked make it look like no keystroke is availible
3985 @param This A pointer to protocol instance.
3986 @param State A pointer to state information on the pointer device
3988 @retval EFI_SUCCESS The keystroke information was returned in State.
3989 @retval EFI_NOT_READY There was no keystroke data availiable.
3990 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3996 ConSplitterSimplePointerGetState (
3997 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
3998 IN OUT EFI_SIMPLE_POINTER_STATE
*State
4001 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4003 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
4004 if (Private
->PasswordEnabled
) {
4006 // If StdIn Locked return not ready
4008 return EFI_NOT_READY
;
4011 Private
->InputEventSignalState
= FALSE
;
4013 return ConSplitterSimplePointerPrivateGetState (Private
, State
);
4018 This event agregates all the events of the ConIn devices in the spliter.
4019 If the ConIn is password locked then return.
4020 If any events of physical ConIn devices are signaled, signal the ConIn
4021 spliter event. This will cause the calling code to call
4022 ConSplitterTextInReadKeyStroke ().
4024 @param Event The Event assoicated with callback.
4025 @param Context Context registered when Event was created.
4032 ConSplitterSimplePointerWaitForInput (
4038 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4041 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4042 if (Private
->PasswordEnabled
) {
4044 // If StdIn Locked return not ready
4050 // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
4052 if (Private
->InputEventSignalState
) {
4053 gBS
->SignalEvent (Event
);
4057 // if any physical console input device has key input, signal the event.
4059 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
4060 Status
= gBS
->CheckEvent (Private
->PointerList
[Index
]->WaitForInput
);
4061 if (!EFI_ERROR (Status
)) {
4062 gBS
->SignalEvent (Event
);
4063 Private
->InputEventSignalState
= TRUE
;
4069 // Absolute Pointer Protocol functions
4074 Resets the pointer device hardware.
4076 @param This Protocol instance pointer.
4077 @param ExtendedVerification Driver may perform diagnostics on reset.
4079 @retval EFI_SUCCESS The device was reset.
4080 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
4086 ConSplitterAbsolutePointerReset (
4087 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4088 IN BOOLEAN ExtendedVerification
4092 EFI_STATUS ReturnStatus
;
4093 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4096 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4098 Private
->AbsoluteInputEventSignalState
= FALSE
;
4100 if (Private
->CurrentNumberOfAbsolutePointers
== 0) {
4104 // return the worst status met
4106 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4107 Status
= Private
->AbsolutePointerList
[Index
]->Reset (
4108 Private
->AbsolutePointerList
[Index
],
4109 ExtendedVerification
4111 if (EFI_ERROR (Status
)) {
4112 ReturnStatus
= Status
;
4116 return ReturnStatus
;
4121 Retrieves the current state of a pointer device.
4123 @param This Protocol instance pointer.
4124 @param State A pointer to the state information on the
4127 @retval EFI_SUCCESS The state of the pointer device was returned in
4129 @retval EFI_NOT_READY The state of the pointer device has not changed
4130 since the last call to GetState().
4131 @retval EFI_DEVICE_ERROR A device error occurred while attempting to
4132 retrieve the pointer device's current state.
4137 ConSplitterAbsolutePointerGetState (
4138 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4139 IN OUT EFI_ABSOLUTE_POINTER_STATE
*State
4142 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4144 EFI_STATUS ReturnStatus
;
4146 EFI_ABSOLUTE_POINTER_STATE CurrentState
;
4149 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4150 if (Private
->PasswordEnabled
) {
4152 // If StdIn Locked return not ready
4154 return EFI_NOT_READY
;
4157 Private
->AbsoluteInputEventSignalState
= FALSE
;
4159 State
->CurrentX
= 0;
4160 State
->CurrentY
= 0;
4161 State
->CurrentZ
= 0;
4162 State
->ActiveButtons
= 0;
4165 // if no physical pointer device exists, return EFI_NOT_READY;
4166 // if any physical pointer device has changed state,
4167 // return the state and EFI_SUCCESS.
4169 ReturnStatus
= EFI_NOT_READY
;
4170 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4172 Status
= Private
->AbsolutePointerList
[Index
]->GetState (
4173 Private
->AbsolutePointerList
[Index
],
4176 if (!EFI_ERROR (Status
)) {
4177 if (ReturnStatus
== EFI_NOT_READY
) {
4178 ReturnStatus
= EFI_SUCCESS
;
4181 State
->ActiveButtons
= CurrentState
.ActiveButtons
;
4183 if (!(Private
->AbsolutePointerMode
.AbsoluteMinX
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxX
== 0)) {
4184 State
->CurrentX
= CurrentState
.CurrentX
;
4186 if (!(Private
->AbsolutePointerMode
.AbsoluteMinY
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxY
== 0)) {
4187 State
->CurrentY
= CurrentState
.CurrentY
;
4189 if (!(Private
->AbsolutePointerMode
.AbsoluteMinZ
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxZ
== 0)) {
4190 State
->CurrentZ
= CurrentState
.CurrentZ
;
4193 } else if (Status
== EFI_DEVICE_ERROR
) {
4194 ReturnStatus
= EFI_DEVICE_ERROR
;
4198 return ReturnStatus
;
4203 This event agregates all the events of the pointer devices in the splitter.
4204 If the ConIn is password locked then return.
4205 If any events of physical pointer devices are signaled, signal the pointer
4206 splitter event. This will cause the calling code to call
4207 ConSplitterAbsolutePointerGetState ().
4209 @param Event The Event assoicated with callback.
4210 @param Context Context registered when Event was created.
4217 ConSplitterAbsolutePointerWaitForInput (
4223 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4226 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4227 if (Private
->PasswordEnabled
) {
4229 // If StdIn Locked return not ready
4235 // if AbsoluteInputEventSignalState is flagged before,
4236 // and not cleared by Reset() or GetState(), signal it
4238 if (Private
->AbsoluteInputEventSignalState
) {
4239 gBS
->SignalEvent (Event
);
4243 // if any physical console input device has key input, signal the event.
4245 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4246 Status
= gBS
->CheckEvent (Private
->AbsolutePointerList
[Index
]->WaitForInput
);
4247 if (!EFI_ERROR (Status
)) {
4248 gBS
->SignalEvent (Event
);
4249 Private
->AbsoluteInputEventSignalState
= TRUE
;
4256 Reset the text output device hardware and optionaly run diagnostics
4258 @param This Protocol instance pointer.
4259 @param ExtendedVerification Driver may perform more exhaustive verfication
4260 operation of the device during reset.
4262 @retval EFI_SUCCESS The text output device was reset.
4263 @retval EFI_DEVICE_ERROR The text output device is not functioning
4264 correctly and could not be reset.
4269 ConSplitterTextOutReset (
4270 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4271 IN BOOLEAN ExtendedVerification
4275 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4277 EFI_STATUS ReturnStatus
;
4279 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4282 // return the worst status met
4284 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4286 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4288 Status
= Private
->TextOutList
[Index
].TextOut
->Reset (
4289 Private
->TextOutList
[Index
].TextOut
,
4290 ExtendedVerification
4292 if (EFI_ERROR (Status
)) {
4293 ReturnStatus
= Status
;
4298 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BLACK
));
4300 Status
= DevNullTextOutSetMode (Private
, 0);
4301 if (EFI_ERROR (Status
)) {
4302 ReturnStatus
= Status
;
4305 return ReturnStatus
;
4310 Write a Unicode string to the output device.
4312 @param This Protocol instance pointer.
4313 @param WString The NULL-terminated Unicode string to be
4314 displayed on the output device(s). All output
4315 devices must also support the Unicode drawing
4316 defined in this file.
4318 @retval EFI_SUCCESS The string was output to the device.
4319 @retval EFI_DEVICE_ERROR The device reported an error while attempting to
4321 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
4323 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
4324 characters in the Unicode string could not be
4325 rendered and were skipped.
4330 ConSplitterTextOutOutputString (
4331 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4336 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4338 UINTN BackSpaceCount
;
4339 EFI_STATUS ReturnStatus
;
4340 CHAR16
*TargetString
;
4342 This
->SetAttribute (This
, This
->Mode
->Attribute
);
4344 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4347 for (TargetString
= WString
; *TargetString
!= L
'\0'; TargetString
++) {
4348 if (*TargetString
== CHAR_BACKSPACE
) {
4354 if (BackSpaceCount
== 0) {
4355 TargetString
= WString
;
4357 TargetString
= AllocatePool (sizeof (CHAR16
) * (StrLen (WString
) + BackSpaceCount
+ 1));
4358 StrCpy (TargetString
, WString
);
4361 // return the worst status met
4363 Status
= DevNullTextOutOutputString (Private
, TargetString
);
4364 if (EFI_ERROR (Status
)) {
4365 ReturnStatus
= Status
;
4368 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4370 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4371 Status
= Private
->TextOutList
[Index
].TextOut
->OutputString (
4372 Private
->TextOutList
[Index
].TextOut
,
4375 if (EFI_ERROR (Status
)) {
4376 ReturnStatus
= Status
;
4381 if (BackSpaceCount
> 0) {
4382 FreePool (TargetString
);
4385 return ReturnStatus
;
4390 Verifies that all characters in a Unicode string can be output to the
4393 @param This Protocol instance pointer.
4394 @param WString The NULL-terminated Unicode string to be
4395 examined for the output device(s).
4397 @retval EFI_SUCCESS The device(s) are capable of rendering the
4399 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string
4400 cannot be rendered by one or more of the output
4401 devices mapped by the EFI handle.
4406 ConSplitterTextOutTestString (
4407 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4412 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4414 EFI_STATUS ReturnStatus
;
4416 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4419 // return the worst status met
4421 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4422 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4423 Status
= Private
->TextOutList
[Index
].TextOut
->TestString (
4424 Private
->TextOutList
[Index
].TextOut
,
4427 if (EFI_ERROR (Status
)) {
4428 ReturnStatus
= Status
;
4433 // There is no DevNullTextOutTestString () since a Unicode buffer would
4434 // always return EFI_SUCCESS.
4435 // ReturnStatus will be EFI_SUCCESS if no consoles are present
4437 return ReturnStatus
;
4442 Returns information for an available text mode that the output device(s)
4445 @param This Protocol instance pointer.
4446 @param ModeNumber The mode number to return information on.
4447 @param Columns Returns the columns of the text output device
4448 for the requested ModeNumber.
4449 @param Rows Returns the rows of the text output device
4450 for the requested ModeNumber.
4452 @retval EFI_SUCCESS The requested mode information was returned.
4453 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4455 @retval EFI_UNSUPPORTED The mode number was not valid.
4460 ConSplitterTextOutQueryMode (
4461 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4462 IN UINTN ModeNumber
,
4467 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4469 INT32
*TextOutModeMap
;
4471 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4474 // Check whether param ModeNumber is valid.
4475 // ModeNumber should be within range 0 ~ MaxMode - 1.
4477 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4478 return EFI_UNSUPPORTED
;
4481 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4482 return EFI_UNSUPPORTED
;
4486 // We get the available mode from mode intersection map if it's available
4488 if (Private
->TextOutModeMap
!= NULL
) {
4489 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4490 CurrentMode
= (UINTN
)(*TextOutModeMap
);
4491 *Columns
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4492 *Rows
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4494 *Columns
= Private
->TextOutQueryData
[ModeNumber
].Columns
;
4495 *Rows
= Private
->TextOutQueryData
[ModeNumber
].Rows
;
4498 if (*Columns
<= 0 && *Rows
<= 0) {
4499 return EFI_UNSUPPORTED
;
4508 Sets the output device(s) to a specified mode.
4510 @param This Protocol instance pointer.
4511 @param ModeNumber The mode number to set.
4513 @retval EFI_SUCCESS The requested text mode was set.
4514 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4516 @retval EFI_UNSUPPORTED The mode number was not valid.
4521 ConSplitterTextOutSetMode (
4522 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4527 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4529 INT32
*TextOutModeMap
;
4530 EFI_STATUS ReturnStatus
;
4532 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4535 // Check whether param ModeNumber is valid.
4536 // ModeNumber should be within range 0 ~ MaxMode - 1.
4538 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4539 return EFI_UNSUPPORTED
;
4542 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4543 return EFI_UNSUPPORTED
;
4546 // If the mode is being set to the curent mode, then just clear the screen and return.
4548 if (Private
->TextOutMode
.Mode
== (INT32
) ModeNumber
) {
4549 return ConSplitterTextOutClearScreen (This
);
4552 // return the worst status met
4554 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4555 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4557 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4558 Status
= Private
->TextOutList
[Index
].TextOut
->SetMode (
4559 Private
->TextOutList
[Index
].TextOut
,
4560 TextOutModeMap
[Index
]
4563 // If this console device is based on a GOP or UGA device, then sync up the bitmap from
4564 // the GOP/UGA splitter and reclear the text portion of the display in the new mode.
4566 if ((Private
->TextOutList
[Index
].GraphicsOutput
!= NULL
) || (Private
->TextOutList
[Index
].UgaDraw
!= NULL
)) {
4567 Private
->TextOutList
[Index
].TextOut
->ClearScreen (Private
->TextOutList
[Index
].TextOut
);
4570 if (EFI_ERROR (Status
)) {
4571 ReturnStatus
= Status
;
4576 // The DevNull Console will support any possible mode as it allocates memory
4578 Status
= DevNullTextOutSetMode (Private
, ModeNumber
);
4579 if (EFI_ERROR (Status
)) {
4580 ReturnStatus
= Status
;
4583 return ReturnStatus
;
4588 Sets the background and foreground colors for the OutputString () and
4589 ClearScreen () functions.
4591 @param This Protocol instance pointer.
4592 @param Attribute The attribute to set. Bits 0..3 are the
4593 foreground color, and bits 4..6 are the
4594 background color. All other bits are undefined
4595 and must be zero. The valid Attributes are
4596 defined in this file.
4598 @retval EFI_SUCCESS The attribute was set.
4599 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4601 @retval EFI_UNSUPPORTED The attribute requested is not defined.
4606 ConSplitterTextOutSetAttribute (
4607 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4612 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4614 EFI_STATUS ReturnStatus
;
4616 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4619 // Check whether param Attribute is valid.
4621 if ( (Attribute
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4622 return EFI_UNSUPPORTED
;
4626 // return the worst status met
4628 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4630 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4631 Status
= Private
->TextOutList
[Index
].TextOut
->SetAttribute (
4632 Private
->TextOutList
[Index
].TextOut
,
4635 if (EFI_ERROR (Status
)) {
4636 ReturnStatus
= Status
;
4641 Private
->TextOutMode
.Attribute
= (INT32
) Attribute
;
4643 return ReturnStatus
;
4648 Clears the output device(s) display to the currently selected background
4651 @param This Protocol instance pointer.
4653 @retval EFI_SUCCESS The operation completed successfully.
4654 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4656 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4661 ConSplitterTextOutClearScreen (
4662 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
4666 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4668 EFI_STATUS ReturnStatus
;
4670 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4673 // return the worst status met
4675 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4677 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4678 Status
= Private
->TextOutList
[Index
].TextOut
->ClearScreen (Private
->TextOutList
[Index
].TextOut
);
4679 if (EFI_ERROR (Status
)) {
4680 ReturnStatus
= Status
;
4685 Status
= DevNullTextOutClearScreen (Private
);
4686 if (EFI_ERROR (Status
)) {
4687 ReturnStatus
= Status
;
4690 return ReturnStatus
;
4695 Sets the current coordinates of the cursor position
4697 @param This Protocol instance pointer.
4698 @param Column The column position to set the cursor to. Must be
4699 greater than or equal to zero and less than the
4700 number of columns by QueryMode ().
4701 @param Row The row position to set the cursor to. Must be
4702 greater than or equal to zero and less than the
4703 number of rows by QueryMode ().
4705 @retval EFI_SUCCESS The operation completed successfully.
4706 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4708 @retval EFI_UNSUPPORTED The output device is not in a valid text mode,
4709 or the cursor position is invalid for the
4715 ConSplitterTextOutSetCursorPosition (
4716 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4722 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4724 EFI_STATUS ReturnStatus
;
4727 INT32
*TextOutModeMap
;
4731 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4732 TextOutModeMap
= NULL
;
4733 ModeNumber
= Private
->TextOutMode
.Mode
;
4736 // Get current MaxColumn and MaxRow from intersection map
4738 if (Private
->TextOutModeMap
!= NULL
) {
4739 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4740 CurrentMode
= *TextOutModeMap
;
4742 CurrentMode
= ModeNumber
;
4745 MaxColumn
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4746 MaxRow
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4748 if (Column
>= MaxColumn
|| Row
>= MaxRow
) {
4749 return EFI_UNSUPPORTED
;
4752 // return the worst status met
4754 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4756 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4757 Status
= Private
->TextOutList
[Index
].TextOut
->SetCursorPosition (
4758 Private
->TextOutList
[Index
].TextOut
,
4762 if (EFI_ERROR (Status
)) {
4763 ReturnStatus
= Status
;
4768 DevNullTextOutSetCursorPosition (Private
, Column
, Row
);
4770 return ReturnStatus
;
4775 Makes the cursor visible or invisible
4777 @param This Protocol instance pointer.
4778 @param Visible If TRUE, the cursor is set to be visible. If
4779 FALSE, the cursor is set to be invisible.
4781 @retval EFI_SUCCESS The operation completed successfully.
4782 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4783 the request, or the device does not support
4784 changing the cursor mode.
4785 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4790 ConSplitterTextOutEnableCursor (
4791 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4796 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4798 EFI_STATUS ReturnStatus
;
4800 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4803 // return the worst status met
4805 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4807 if (Private
->TextOutList
[Index
].TextOutEnabled
) {
4808 Status
= Private
->TextOutList
[Index
].TextOut
->EnableCursor (
4809 Private
->TextOutList
[Index
].TextOut
,
4812 if (EFI_ERROR (Status
)) {
4813 ReturnStatus
= Status
;
4818 DevNullTextOutEnableCursor (Private
, Visible
);
4820 return ReturnStatus
;