TianoCore EDK2 master
Loading...
Searching...
No Matches
ConSplitter.c
Go to the documentation of this file.
1
25#include "ConSplitter.h"
26
27//
28// Identify if ConIn is connected in PcdConInConnectOnDemand enabled mode.
29// default not connect
30//
31BOOLEAN mConInIsConnect = FALSE;
32
33//
34// Text In Splitter Private Data template
35//
37 TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE,
39
40 {
44 },
45 0,
47 0,
48
49 {
56 },
57 0,
59 0,
60 {
63 },
65 0,
66 0,
67 FALSE,
68
69 {
74 },
75 {
76 0x10000,
77 0x10000,
78 0x10000,
79 TRUE,
80 TRUE
81 },
82 0,
84 0,
85
86 {
91 },
92 {
93 0, // AbsoluteMinX
94 0, // AbsoluteMinY
95 0, // AbsoluteMinZ
96 0x10000, // AbsoluteMaxX
97 0x10000, // AbsoluteMaxY
98 0x10000, // AbsoluteMaxZ
99 0 // Attributes
100 },
101 0,
103 0,
104 FALSE,
105
106 FALSE,
107 FALSE
108};
109
110//
111// Uga Draw Protocol Private Data template
112//
113GLOBAL_REMOVE_IF_UNREFERENCED EFI_UGA_DRAW_PROTOCOL mUgaDrawProtocolTemplate = {
117};
118
119//
120// Graphics Output Protocol Private Data template
121//
122GLOBAL_REMOVE_IF_UNREFERENCED EFI_GRAPHICS_OUTPUT_PROTOCOL mGraphicsOutputProtocolTemplate = {
126 NULL
127};
128
129//
130// Text Out Splitter Private Data template
131//
133 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,
135 {
146 },
147 {
148 1,
149 0,
150 0,
151 0,
152 0,
153 FALSE,
154 },
155
156 {
157 NULL,
158 NULL,
159 NULL
160 },
161 0,
162 0,
163 0,
164 0,
165
166 {
167 NULL,
168 NULL,
169 NULL,
170 NULL
171 },
173 0,
174 0,
175
176 0,
178 0,
180 0,
181 (INT32 *)NULL,
182 FALSE
183};
184
185//
186// Standard Error Text Out Splitter Data Template
187//
189 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,
191 {
202 },
203 {
204 1,
205 0,
206 0,
207 0,
208 0,
209 FALSE,
210 },
211
212 {
213 NULL,
214 NULL,
215 NULL
216 },
217 0,
218 0,
219 0,
220 0,
221
222 {
223 NULL,
224 NULL,
225 NULL,
226 NULL
227 },
229 0,
230 0,
231
232 0,
234 0,
236 0,
237 (INT32 *)NULL,
238 FALSE
239};
240
241//
242// Driver binding instance for Console Input Device
243//
244EFI_DRIVER_BINDING_PROTOCOL gConSplitterConInDriverBinding = {
248 0xa,
249 NULL,
250 NULL
251};
252
253//
254// Driver binding instance for Console Out device
255//
256EFI_DRIVER_BINDING_PROTOCOL gConSplitterConOutDriverBinding = {
260 0xa,
261 NULL,
262 NULL
263};
264
265//
266// Driver binding instance for Standard Error device
267//
268EFI_DRIVER_BINDING_PROTOCOL gConSplitterStdErrDriverBinding = {
272 0xa,
273 NULL,
274 NULL
275};
276
277//
278// Driver binding instance for Simple Pointer protocol
279//
280EFI_DRIVER_BINDING_PROTOCOL gConSplitterSimplePointerDriverBinding = {
284 0xa,
285 NULL,
286 NULL
287};
288
289//
290// Driver binding instance for Absolute Pointer protocol
291//
292EFI_DRIVER_BINDING_PROTOCOL gConSplitterAbsolutePointerDriverBinding = {
296 0xa,
297 NULL,
298 NULL
299};
300
312EFIAPI
314 IN EFI_KEY_DATA *KeyData
315 )
316{
317 UINTN Index;
318
319 if (((KeyData->KeyState.KeyToggleState & KEY_STATE_VALID_EXPOSED) == KEY_STATE_VALID_EXPOSED) &&
320 (KeyData->KeyState.KeyToggleState != mConIn.PhysicalKeyToggleState))
321 {
322 //
323 // There is toggle state change, sync to other console input devices.
324 //
325 for (Index = 0; Index < mConIn.CurrentNumberOfExConsoles; Index++) {
326 mConIn.TextInExList[Index]->SetState (
327 mConIn.TextInExList[Index],
328 &KeyData->KeyState.KeyToggleState
329 );
330 }
331
332 mConIn.PhysicalKeyToggleState = KeyData->KeyState.KeyToggleState;
333 DEBUG ((DEBUG_INFO, "Current toggle state is 0x%02x\n", mConIn.PhysicalKeyToggleState));
334 }
335
336 return EFI_SUCCESS;
337}
338
345VOID
348 )
349{
350 EFI_KEY_DATA KeyData;
351 VOID *NotifyHandle;
352
353 //
354 // Initialize PhysicalKeyToggleState that will be synced to new console
355 // input device to turn on physical TextInEx partial key report for
356 // toggle state sync.
357 //
358 Private->PhysicalKeyToggleState = KEY_STATE_VALID_EXPOSED;
359
360 //
361 // Initialize VirtualKeyStateExported to let the virtual TextInEx not report
362 // the partial key even though the physical TextInEx turns on the partial
363 // key report. The virtual TextInEx will report the partial key after it is
364 // required by calling SetState(X | KEY_STATE_VALID_EXPOSED) explicitly.
365 //
366 Private->VirtualKeyStateExported = FALSE;
367
368 //
369 // Register key notify for toggle state sync.
370 //
371 KeyData.Key.ScanCode = SCAN_NULL;
372 KeyData.Key.UnicodeChar = CHAR_NULL;
373 KeyData.KeyState.KeyShiftState = 0;
374 KeyData.KeyState.KeyToggleState = 0;
375 Private->TextInEx.RegisterKeyNotify (
376 &Private->TextInEx,
377 &KeyData,
379 &NotifyHandle
380 );
381}
382
389VOID
392 )
393{
394 UINTN Index;
395
396 //
397 // Reinitialize PhysicalKeyToggleState that will be synced to new console
398 // input device to turn on physical TextInEx partial key report for
399 // toggle state sync.
400 //
401 Private->PhysicalKeyToggleState = KEY_STATE_VALID_EXPOSED;
402
403 //
404 // Reinitialize VirtualKeyStateExported to let the virtual TextInEx not report
405 // the partial key even though the physical TextInEx turns on the partial
406 // key report. The virtual TextInEx will report the partial key after it is
407 // required by calling SetState(X | KEY_STATE_VALID_EXPOSED) explicitly.
408 //
409 Private->VirtualKeyStateExported = FALSE;
410
411 for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
412 Private->TextInExList[Index]->SetState (
413 Private->TextInExList[Index],
414 &Private->PhysicalKeyToggleState
415 );
416 }
417}
418
435EFIAPI
437 IN EFI_HANDLE ImageHandle,
438 IN EFI_SYSTEM_TABLE *SystemTable
439 )
440{
441 EFI_STATUS Status;
442
443 //
444 // Install driver model protocol(s).
445 //
447 ImageHandle,
448 SystemTable,
449 &gConSplitterConInDriverBinding,
450 ImageHandle,
451 &gConSplitterConInComponentName,
452 &gConSplitterConInComponentName2
453 );
454 ASSERT_EFI_ERROR (Status);
455
457 ImageHandle,
458 SystemTable,
459 &gConSplitterSimplePointerDriverBinding,
460 NULL,
461 &gConSplitterSimplePointerComponentName,
462 &gConSplitterSimplePointerComponentName2
463 );
464 ASSERT_EFI_ERROR (Status);
465
467 ImageHandle,
468 SystemTable,
469 &gConSplitterAbsolutePointerDriverBinding,
470 NULL,
471 &gConSplitterAbsolutePointerComponentName,
472 &gConSplitterAbsolutePointerComponentName2
473 );
474 ASSERT_EFI_ERROR (Status);
475
477 ImageHandle,
478 SystemTable,
479 &gConSplitterConOutDriverBinding,
480 NULL,
481 &gConSplitterConOutComponentName,
482 &gConSplitterConOutComponentName2
483 );
484 ASSERT_EFI_ERROR (Status);
485
487 ImageHandle,
488 SystemTable,
489 &gConSplitterStdErrDriverBinding,
490 NULL,
491 &gConSplitterStdErrComponentName,
492 &gConSplitterStdErrComponentName2
493 );
494 ASSERT_EFI_ERROR (Status);
495
496 //
497 // Either Graphics Output protocol or UGA Draw protocol must be supported.
498 //
499 ASSERT (
500 FeaturePcdGet (PcdConOutGopSupport) ||
501 FeaturePcdGet (PcdConOutUgaSupport)
502 );
503
504 //
505 // The driver creates virtual handles for ConIn, ConOut, StdErr.
506 // The virtual handles will always exist even if no console exist in the
507 // system. This is need to support hotplug devices like USB.
508 //
509 //
510 // Create virtual device handle for ConIn Splitter
511 //
512 Status = ConSplitterTextInConstructor (&mConIn);
513 if (!EFI_ERROR (Status)) {
514 Status = gBS->InstallMultipleProtocolInterfaces (
515 &mConIn.VirtualHandle,
516 &gEfiSimpleTextInProtocolGuid,
517 &mConIn.TextIn,
518 &gEfiSimpleTextInputExProtocolGuid,
519 &mConIn.TextInEx,
520 &gEfiSimplePointerProtocolGuid,
521 &mConIn.SimplePointer,
522 &gEfiAbsolutePointerProtocolGuid,
523 &mConIn.AbsolutePointer,
524 NULL
525 );
526 if (!EFI_ERROR (Status)) {
527 //
528 // Update the EFI System Table with new virtual console
529 // and update the pointer to Simple Text Input protocol.
530 //
531 gST->ConsoleInHandle = mConIn.VirtualHandle;
532 gST->ConIn = &mConIn.TextIn;
533 }
534 }
535
536 //
537 // Create virtual device handle for ConOut Splitter
538 //
539 Status = ConSplitterTextOutConstructor (&mConOut);
540 if (!EFI_ERROR (Status)) {
541 Status = gBS->InstallMultipleProtocolInterfaces (
542 &mConOut.VirtualHandle,
543 &gEfiSimpleTextOutProtocolGuid,
544 &mConOut.TextOut,
545 NULL
546 );
547 if (!EFI_ERROR (Status)) {
548 //
549 // Update the EFI System Table with new virtual console
550 // and Update the pointer to Text Output protocol.
551 //
552 gST->ConsoleOutHandle = mConOut.VirtualHandle;
553 gST->ConOut = &mConOut.TextOut;
554 }
555 }
556
557 //
558 // Create virtual device handle for StdErr Splitter
559 //
560 Status = ConSplitterTextOutConstructor (&mStdErr);
561 if (!EFI_ERROR (Status)) {
562 Status = gBS->InstallMultipleProtocolInterfaces (
563 &mStdErr.VirtualHandle,
564 &gEfiSimpleTextOutProtocolGuid,
565 &mStdErr.TextOut,
566 NULL
567 );
568 if (!EFI_ERROR (Status)) {
569 //
570 // Update the EFI System Table with new virtual console
571 // and update the pointer to Text Output protocol.
572 //
573 gST->StandardErrorHandle = mStdErr.VirtualHandle;
574 gST->StdErr = &mStdErr.TextOut;
575 }
576 }
577
578 //
579 // Update the CRC32 in the EFI System Table header
580 //
581 gST->Hdr.CRC32 = 0;
582 gBS->CalculateCrc32 (
583 (UINT8 *)&gST->Hdr,
585 &gST->Hdr.CRC32
586 );
587
588 return EFI_SUCCESS;
589}
590
605 )
606{
607 EFI_STATUS Status;
608 UINTN TextInExListCount;
609
610 //
611 // Allocate buffer for Simple Text Input device
612 //
613 Status = ConSplitterGrowBuffer (
615 &ConInPrivate->TextInListCount,
616 (VOID **)&ConInPrivate->TextInList
617 );
618 if (EFI_ERROR (Status)) {
619 return EFI_OUT_OF_RESOURCES;
620 }
621
622 //
623 // Create Event to wait for a key
624 //
625 Status = gBS->CreateEvent (
626 EVT_NOTIFY_WAIT,
627 TPL_NOTIFY,
629 ConInPrivate,
630 &ConInPrivate->TextIn.WaitForKey
631 );
632 ASSERT_EFI_ERROR (Status);
633
634 //
635 // Allocate buffer for KeyQueue
636 //
637 TextInExListCount = ConInPrivate->TextInExListCount;
638 Status = ConSplitterGrowBuffer (
639 sizeof (EFI_KEY_DATA),
640 &TextInExListCount,
641 (VOID **)&ConInPrivate->KeyQueue
642 );
643 if (EFI_ERROR (Status)) {
644 return EFI_OUT_OF_RESOURCES;
645 }
646
647 //
648 // Allocate buffer for Simple Text Input Ex device
649 //
650 Status = ConSplitterGrowBuffer (
652 &ConInPrivate->TextInExListCount,
653 (VOID **)&ConInPrivate->TextInExList
654 );
655 if (EFI_ERROR (Status)) {
656 return EFI_OUT_OF_RESOURCES;
657 }
658
659 //
660 // Create Event to wait for a key Ex
661 //
662 Status = gBS->CreateEvent (
663 EVT_NOTIFY_WAIT,
664 TPL_NOTIFY,
666 ConInPrivate,
667 &ConInPrivate->TextInEx.WaitForKeyEx
668 );
669 ASSERT_EFI_ERROR (Status);
670
671 InitializeListHead (&ConInPrivate->NotifyList);
672
673 ToggleStateSyncInitialization (ConInPrivate);
674
675 ConInPrivate->AbsolutePointer.Mode = &ConInPrivate->AbsolutePointerMode;
676 //
677 // Allocate buffer for Absolute Pointer device
678 //
679 Status = ConSplitterGrowBuffer (
681 &ConInPrivate->AbsolutePointerListCount,
682 (VOID **)&ConInPrivate->AbsolutePointerList
683 );
684 if (EFI_ERROR (Status)) {
685 return EFI_OUT_OF_RESOURCES;
686 }
687
688 //
689 // Create Event to wait for device input for Absolute pointer device
690 //
691 Status = gBS->CreateEvent (
692 EVT_NOTIFY_WAIT,
693 TPL_NOTIFY,
695 ConInPrivate,
696 &ConInPrivate->AbsolutePointer.WaitForInput
697 );
698 ASSERT_EFI_ERROR (Status);
699
700 ConInPrivate->SimplePointer.Mode = &ConInPrivate->SimplePointerMode;
701 //
702 // Allocate buffer for Simple Pointer device
703 //
704 Status = ConSplitterGrowBuffer (
706 &ConInPrivate->PointerListCount,
707 (VOID **)&ConInPrivate->PointerList
708 );
709 if (EFI_ERROR (Status)) {
710 return EFI_OUT_OF_RESOURCES;
711 }
712
713 //
714 // Create Event to wait for device input for Simple pointer device
715 //
716 Status = gBS->CreateEvent (
717 EVT_NOTIFY_WAIT,
718 TPL_NOTIFY,
720 ConInPrivate,
721 &ConInPrivate->SimplePointer.WaitForInput
722 );
723 ASSERT_EFI_ERROR (Status);
724 //
725 // Create Event to signal ConIn connection request
726 //
727 Status = gBS->CreateEventEx (
728 EVT_NOTIFY_SIGNAL,
729 TPL_CALLBACK,
731 NULL,
732 &gConnectConInEventGuid,
733 &ConInPrivate->ConnectConInEvent
734 );
735
736 return Status;
737}
738
751 TEXT_OUT_SPLITTER_PRIVATE_DATA *ConOutPrivate
752 )
753{
754 EFI_STATUS Status;
756
757 //
758 // Copy protocols template
759 //
760 if (FeaturePcdGet (PcdConOutUgaSupport)) {
761 CopyMem (&ConOutPrivate->UgaDraw, &mUgaDrawProtocolTemplate, sizeof (EFI_UGA_DRAW_PROTOCOL));
762 }
763
764 if (FeaturePcdGet (PcdConOutGopSupport)) {
765 CopyMem (&ConOutPrivate->GraphicsOutput, &mGraphicsOutputProtocolTemplate, sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL));
766 }
767
768 //
769 // Initialize console output splitter's private data.
770 //
771 ConOutPrivate->TextOut.Mode = &ConOutPrivate->TextOutMode;
772
773 //
774 // When new console device is added, the new mode will be set later,
775 // so put current mode back to init state.
776 //
777 ConOutPrivate->TextOutMode.Mode = 0xFF;
778 //
779 // Allocate buffer for Console Out device
780 //
781 Status = ConSplitterGrowBuffer (
782 sizeof (TEXT_OUT_AND_GOP_DATA),
783 &ConOutPrivate->TextOutListCount,
784 (VOID **)&ConOutPrivate->TextOutList
785 );
786 if (EFI_ERROR (Status)) {
787 return EFI_OUT_OF_RESOURCES;
788 }
789
790 //
791 // Allocate buffer for Text Out query data
792 //
793 Status = ConSplitterGrowBuffer (
795 &ConOutPrivate->TextOutQueryDataCount,
796 (VOID **)&ConOutPrivate->TextOutQueryData
797 );
798 if (EFI_ERROR (Status)) {
799 return EFI_OUT_OF_RESOURCES;
800 }
801
802 //
803 // Setup the default console to 80 x 25 and mode to 0
804 //
805 ConOutPrivate->TextOutQueryData[0].Columns = 80;
806 ConOutPrivate->TextOutQueryData[0].Rows = 25;
807 TextOutSetMode (ConOutPrivate, 0);
808
809 if (FeaturePcdGet (PcdConOutUgaSupport)) {
810 //
811 // Setup the UgaDraw to 800 x 600 x 32 bits per pixel, 60Hz.
812 //
813 ConSplitterUgaDrawSetMode (&ConOutPrivate->UgaDraw, 800, 600, 32, 60);
814 }
815
816 if (FeaturePcdGet (PcdConOutGopSupport)) {
817 //
818 // Setup resource for mode information in Graphics Output Protocol interface
819 //
820 if ((ConOutPrivate->GraphicsOutput.Mode = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE))) == NULL) {
821 return EFI_OUT_OF_RESOURCES;
822 }
823
824 if ((ConOutPrivate->GraphicsOutput.Mode->Info = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION))) == NULL) {
825 return EFI_OUT_OF_RESOURCES;
826 }
827
828 //
829 // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel
830 // DevNull will be updated to user-defined mode after driver has started.
831 //
832 if ((ConOutPrivate->GraphicsOutputModeBuffer = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION))) == NULL) {
833 return EFI_OUT_OF_RESOURCES;
834 }
835
836 Info = &ConOutPrivate->GraphicsOutputModeBuffer[0];
837 Info->Version = 0;
838 Info->HorizontalResolution = 800;
839 Info->VerticalResolution = 600;
841 Info->PixelsPerScanLine = 800;
842 CopyMem (ConOutPrivate->GraphicsOutput.Mode->Info, Info, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
843 ConOutPrivate->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
844
845 //
846 // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()
847 // GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
848 //
849 ConOutPrivate->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS)(UINTN)NULL;
850 ConOutPrivate->GraphicsOutput.Mode->FrameBufferSize = 0;
851
852 ConOutPrivate->GraphicsOutput.Mode->MaxMode = 1;
853 //
854 // Initial current mode to unknown state, and then set to mode 0
855 //
856 ConOutPrivate->GraphicsOutput.Mode->Mode = 0xffff;
857 ConOutPrivate->GraphicsOutput.SetMode (&ConOutPrivate->GraphicsOutput, 0);
858 }
859
860 return EFI_SUCCESS;
861}
862
878 IN EFI_HANDLE ControllerHandle,
879 IN EFI_GUID *Guid
880 )
881{
882 EFI_STATUS Status;
883 VOID *Instance;
884
885 //
886 // Make sure the Console Splitter does not attempt to attach to itself
887 //
888 if ((ControllerHandle == mConIn.VirtualHandle) ||
889 (ControllerHandle == mConOut.VirtualHandle) ||
890 (ControllerHandle == mStdErr.VirtualHandle)
891 )
892 {
893 return EFI_UNSUPPORTED;
894 }
895
896 //
897 // Check to see whether the specific protocol could be opened BY_DRIVER
898 //
899 Status = gBS->OpenProtocol (
900 ControllerHandle,
901 Guid,
902 &Instance,
903 This->DriverBindingHandle,
904 ControllerHandle,
905 EFI_OPEN_PROTOCOL_BY_DRIVER
906 );
907
908 if (EFI_ERROR (Status)) {
909 return Status;
910 }
911
912 gBS->CloseProtocol (
913 ControllerHandle,
914 Guid,
915 This->DriverBindingHandle,
916 ControllerHandle
917 );
918
919 return EFI_SUCCESS;
920}
921
935EFIAPI
938 IN EFI_HANDLE ControllerHandle,
939 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
940 )
941{
942 return ConSplitterSupported (
943 This,
944 ControllerHandle,
945 &gEfiConsoleInDeviceGuid
946 );
947}
948
962EFIAPI
965 IN EFI_HANDLE ControllerHandle,
966 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
967 )
968{
969 return ConSplitterSupported (
970 This,
971 ControllerHandle,
972 &gEfiSimplePointerProtocolGuid
973 );
974}
975
989EFIAPI
992 IN EFI_HANDLE ControllerHandle,
993 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
994 )
995{
996 return ConSplitterSupported (
997 This,
998 ControllerHandle,
999 &gEfiAbsolutePointerProtocolGuid
1000 );
1001}
1002
1016EFIAPI
1019 IN EFI_HANDLE ControllerHandle,
1020 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
1021 )
1022{
1023 return ConSplitterSupported (
1024 This,
1025 ControllerHandle,
1026 &gEfiConsoleOutDeviceGuid
1027 );
1028}
1029
1043EFIAPI
1046 IN EFI_HANDLE ControllerHandle,
1047 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
1048 )
1049{
1050 return ConSplitterSupported (
1051 This,
1052 ControllerHandle,
1053 &gEfiStandardErrorDeviceGuid
1054 );
1055}
1056
1077 IN EFI_HANDLE ControllerHandle,
1078 IN EFI_HANDLE ConSplitterVirtualHandle,
1079 IN EFI_GUID *DeviceGuid,
1080 IN EFI_GUID *InterfaceGuid,
1081 OUT VOID **Interface
1082 )
1083{
1084 EFI_STATUS Status;
1085 VOID *Instance;
1086
1087 //
1088 // Check to see whether the ControllerHandle has the DeviceGuid on it.
1089 //
1090 Status = gBS->OpenProtocol (
1091 ControllerHandle,
1092 DeviceGuid,
1093 &Instance,
1094 This->DriverBindingHandle,
1095 ControllerHandle,
1096 EFI_OPEN_PROTOCOL_BY_DRIVER
1097 );
1098 if (EFI_ERROR (Status)) {
1099 return Status;
1100 }
1101
1102 //
1103 // Open the Parent Handle for the child.
1104 //
1105 Status = gBS->OpenProtocol (
1106 ControllerHandle,
1107 DeviceGuid,
1108 &Instance,
1109 This->DriverBindingHandle,
1110 ConSplitterVirtualHandle,
1111 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1112 );
1113 if (EFI_ERROR (Status)) {
1114 goto Err;
1115 }
1116
1117 //
1118 // Open InterfaceGuid on the virtual handle.
1119 //
1120 Status = gBS->OpenProtocol (
1121 ControllerHandle,
1122 InterfaceGuid,
1123 Interface,
1124 This->DriverBindingHandle,
1125 ConSplitterVirtualHandle,
1126 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1127 );
1128
1129 if (!EFI_ERROR (Status)) {
1130 return EFI_SUCCESS;
1131 }
1132
1133 //
1134 // close the DeviceGuid on ConSplitter VirtualHandle.
1135 //
1136 gBS->CloseProtocol (
1137 ControllerHandle,
1138 DeviceGuid,
1139 This->DriverBindingHandle,
1140 ConSplitterVirtualHandle
1141 );
1142
1143Err:
1144 //
1145 // close the DeviceGuid on ControllerHandle.
1146 //
1147 gBS->CloseProtocol (
1148 ControllerHandle,
1149 DeviceGuid,
1150 This->DriverBindingHandle,
1151 ControllerHandle
1152 );
1153
1154 return Status;
1155}
1156
1170EFIAPI
1173 IN EFI_HANDLE ControllerHandle,
1174 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
1175 )
1176{
1177 EFI_STATUS Status;
1180
1181 //
1182 // Start ConSplitter on ControllerHandle, and create the virtual
1183 // aggregated console device on first call Start for a SimpleTextIn handle.
1184 //
1185 Status = ConSplitterStart (
1186 This,
1187 ControllerHandle,
1188 mConIn.VirtualHandle,
1189 &gEfiConsoleInDeviceGuid,
1190 &gEfiSimpleTextInProtocolGuid,
1191 (VOID **)&TextIn
1192 );
1193 if (EFI_ERROR (Status)) {
1194 return Status;
1195 }
1196
1197 //
1198 // Add this device into Text In devices list.
1199 //
1200 Status = ConSplitterTextInAddDevice (&mConIn, TextIn);
1201 if (EFI_ERROR (Status)) {
1202 return Status;
1203 }
1204
1205 Status = gBS->OpenProtocol (
1206 ControllerHandle,
1207 &gEfiSimpleTextInputExProtocolGuid,
1208 (VOID **)&TextInEx,
1209 This->DriverBindingHandle,
1210 mConIn.VirtualHandle,
1211 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1212 );
1213 if (!EFI_ERROR (Status)) {
1214 //
1215 // If Simple Text Input Ex protocol exists,
1216 // add this device into Text In Ex devices list.
1217 //
1218 Status = ConSplitterTextInExAddDevice (&mConIn, TextInEx);
1219 }
1220
1221 return Status;
1222}
1223
1237EFIAPI
1240 IN EFI_HANDLE ControllerHandle,
1241 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
1242 )
1243{
1244 EFI_STATUS Status;
1245 EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;
1246
1247 //
1248 // Start ConSplitter on ControllerHandle, and create the virtual
1249 // aggregated console device on first call Start for a SimplePointer handle.
1250 //
1251 Status = ConSplitterStart (
1252 This,
1253 ControllerHandle,
1254 mConIn.VirtualHandle,
1255 &gEfiSimplePointerProtocolGuid,
1256 &gEfiSimplePointerProtocolGuid,
1257 (VOID **)&SimplePointer
1258 );
1259 if (EFI_ERROR (Status)) {
1260 return Status;
1261 }
1262
1263 //
1264 // Add this devcie into Simple Pointer devices list.
1265 //
1266 return ConSplitterSimplePointerAddDevice (&mConIn, SimplePointer);
1267}
1268
1282EFIAPI
1285 IN EFI_HANDLE ControllerHandle,
1286 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
1287 )
1288{
1289 EFI_STATUS Status;
1290 EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer;
1291
1292 //
1293 // Start ConSplitter on ControllerHandle, and create the virtual
1294 // aggregated console device on first call Start for a AbsolutePointer handle.
1295 //
1296 Status = ConSplitterStart (
1297 This,
1298 ControllerHandle,
1299 mConIn.VirtualHandle,
1300 &gEfiAbsolutePointerProtocolGuid,
1301 &gEfiAbsolutePointerProtocolGuid,
1302 (VOID **)&AbsolutePointer
1303 );
1304
1305 if (EFI_ERROR (Status)) {
1306 return Status;
1307 }
1308
1309 //
1310 // Add this devcie into Absolute Pointer devices list.
1311 //
1312 return ConSplitterAbsolutePointerAddDevice (&mConIn, AbsolutePointer);
1313}
1314
1328EFIAPI
1331 IN EFI_HANDLE ControllerHandle,
1332 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
1333 )
1334{
1335 EFI_STATUS Status;
1337 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1338 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1339 UINTN SizeOfInfo;
1341
1342 //
1343 // Start ConSplitter on ControllerHandle, and create the virtual
1344 // aggregated console device on first call Start for a ConsoleOut handle.
1345 //
1346 Status = ConSplitterStart (
1347 This,
1348 ControllerHandle,
1349 mConOut.VirtualHandle,
1350 &gEfiConsoleOutDeviceGuid,
1351 &gEfiSimpleTextOutProtocolGuid,
1352 (VOID **)&TextOut
1353 );
1354 if (EFI_ERROR (Status)) {
1355 return Status;
1356 }
1357
1358 GraphicsOutput = NULL;
1359 UgaDraw = NULL;
1360 //
1361 // Try to Open Graphics Output protocol
1362 //
1363 Status = gBS->OpenProtocol (
1364 ControllerHandle,
1365 &gEfiGraphicsOutputProtocolGuid,
1366 (VOID **)&GraphicsOutput,
1367 This->DriverBindingHandle,
1368 mConOut.VirtualHandle,
1369 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1370 );
1371
1372 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
1373 //
1374 // Open UGA DRAW protocol
1375 //
1376 gBS->OpenProtocol (
1377 ControllerHandle,
1378 &gEfiUgaDrawProtocolGuid,
1379 (VOID **)&UgaDraw,
1380 This->DriverBindingHandle,
1381 mConOut.VirtualHandle,
1382 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1383 );
1384 }
1385
1386 //
1387 // When new console device is added, the new mode will be set later,
1388 // so put current mode back to init state.
1389 //
1390 mConOut.TextOutMode.Mode = 0xFF;
1391
1392 //
1393 // If both ConOut and StdErr incorporate the same Text Out device,
1394 // their MaxMode and QueryData should be the intersection of both.
1395 //
1396 Status = ConSplitterTextOutAddDevice (&mConOut, TextOut, GraphicsOutput, UgaDraw);
1397 ConSplitterTextOutSetAttribute (&mConOut.TextOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
1398
1399 if (FeaturePcdGet (PcdConOutUgaSupport)) {
1400 //
1401 // Get the UGA mode data of ConOut from the current mode
1402 //
1403 if (GraphicsOutput != NULL) {
1404 Status = GraphicsOutput->QueryMode (GraphicsOutput, GraphicsOutput->Mode->Mode, &SizeOfInfo, &Info);
1405 if (EFI_ERROR (Status)) {
1406 return Status;
1407 }
1408
1409 ASSERT (SizeOfInfo <= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
1410
1411 mConOut.UgaHorizontalResolution = Info->HorizontalResolution;
1412 mConOut.UgaVerticalResolution = Info->VerticalResolution;
1413 mConOut.UgaColorDepth = 32;
1414 mConOut.UgaRefreshRate = 60;
1415
1416 FreePool (Info);
1417 } else if (UgaDraw != NULL) {
1418 Status = UgaDraw->GetMode (
1419 UgaDraw,
1420 &mConOut.UgaHorizontalResolution,
1421 &mConOut.UgaVerticalResolution,
1422 &mConOut.UgaColorDepth,
1423 &mConOut.UgaRefreshRate
1424 );
1425 }
1426 }
1427
1428 return Status;
1429}
1430
1444EFIAPI
1447 IN EFI_HANDLE ControllerHandle,
1448 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
1449 )
1450{
1451 EFI_STATUS Status;
1453
1454 //
1455 // Start ConSplitter on ControllerHandle, and create the virtual
1456 // aggregated console device on first call Start for a StandardError handle.
1457 //
1458 Status = ConSplitterStart (
1459 This,
1460 ControllerHandle,
1461 mStdErr.VirtualHandle,
1462 &gEfiStandardErrorDeviceGuid,
1463 &gEfiSimpleTextOutProtocolGuid,
1464 (VOID **)&TextOut
1465 );
1466 if (EFI_ERROR (Status)) {
1467 return Status;
1468 }
1469
1470 //
1471 // When new console device is added, the new mode will be set later,
1472 // so put current mode back to init state.
1473 //
1474 mStdErr.TextOutMode.Mode = 0xFF;
1475
1476 //
1477 // If both ConOut and StdErr incorporate the same Text Out device,
1478 // their MaxMode and QueryData should be the intersection of both.
1479 //
1480 Status = ConSplitterTextOutAddDevice (&mStdErr, TextOut, NULL, NULL);
1481 ConSplitterTextOutSetAttribute (&mStdErr.TextOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
1482
1483 return Status;
1484}
1485
1505 IN EFI_HANDLE ControllerHandle,
1506 IN EFI_HANDLE ConSplitterVirtualHandle,
1507 IN EFI_GUID *DeviceGuid,
1508 IN EFI_GUID *InterfaceGuid,
1509 IN VOID **Interface
1510 )
1511{
1512 EFI_STATUS Status;
1513
1514 Status = gBS->OpenProtocol (
1515 ControllerHandle,
1516 InterfaceGuid,
1517 Interface,
1518 This->DriverBindingHandle,
1519 ControllerHandle,
1520 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1521 );
1522 if (EFI_ERROR (Status)) {
1523 return Status;
1524 }
1525
1526 //
1527 // close the protocol referred.
1528 //
1529 gBS->CloseProtocol (
1530 ControllerHandle,
1531 DeviceGuid,
1532 This->DriverBindingHandle,
1533 ConSplitterVirtualHandle
1534 );
1535
1536 gBS->CloseProtocol (
1537 ControllerHandle,
1538 DeviceGuid,
1539 This->DriverBindingHandle,
1540 ControllerHandle
1541 );
1542
1543 return EFI_SUCCESS;
1544}
1545
1560EFIAPI
1563 IN EFI_HANDLE ControllerHandle,
1564 IN UINTN NumberOfChildren,
1565 IN EFI_HANDLE *ChildHandleBuffer
1566 )
1567{
1568 EFI_STATUS Status;
1571
1572 if (NumberOfChildren == 0) {
1573 return EFI_SUCCESS;
1574 }
1575
1576 Status = gBS->OpenProtocol (
1577 ControllerHandle,
1578 &gEfiSimpleTextInputExProtocolGuid,
1579 (VOID **)&TextInEx,
1580 This->DriverBindingHandle,
1581 ControllerHandle,
1582 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1583 );
1584 if (!EFI_ERROR (Status)) {
1585 //
1586 // If Simple Text Input Ex protocol exists,
1587 // remove device from Text Input Ex devices list.
1588 //
1589 Status = ConSplitterTextInExDeleteDevice (&mConIn, TextInEx);
1590 if (EFI_ERROR (Status)) {
1591 return Status;
1592 }
1593 }
1594
1595 //
1596 // Close Simple Text In protocol on controller handle and virtual handle.
1597 //
1598 Status = ConSplitterStop (
1599 This,
1600 ControllerHandle,
1601 mConIn.VirtualHandle,
1602 &gEfiConsoleInDeviceGuid,
1603 &gEfiSimpleTextInProtocolGuid,
1604 (VOID **)&TextIn
1605 );
1606 if (EFI_ERROR (Status)) {
1607 return Status;
1608 }
1609
1610 //
1611 // Remove device from Text Input devices list.
1612 //
1613 return ConSplitterTextInDeleteDevice (&mConIn, TextIn);
1614}
1615
1631EFIAPI
1634 IN EFI_HANDLE ControllerHandle,
1635 IN UINTN NumberOfChildren,
1636 IN EFI_HANDLE *ChildHandleBuffer
1637 )
1638{
1639 EFI_STATUS Status;
1640 EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;
1641
1642 if (NumberOfChildren == 0) {
1643 return EFI_SUCCESS;
1644 }
1645
1646 //
1647 // Close Simple Pointer protocol on controller handle and virtual handle.
1648 //
1649 Status = ConSplitterStop (
1650 This,
1651 ControllerHandle,
1652 mConIn.VirtualHandle,
1653 &gEfiSimplePointerProtocolGuid,
1654 &gEfiSimplePointerProtocolGuid,
1655 (VOID **)&SimplePointer
1656 );
1657 if (EFI_ERROR (Status)) {
1658 return Status;
1659 }
1660
1661 //
1662 // Remove this device from Simple Pointer device list.
1663 //
1664 return ConSplitterSimplePointerDeleteDevice (&mConIn, SimplePointer);
1665}
1666
1682EFIAPI
1685 IN EFI_HANDLE ControllerHandle,
1686 IN UINTN NumberOfChildren,
1687 IN EFI_HANDLE *ChildHandleBuffer
1688 )
1689{
1690 EFI_STATUS Status;
1691 EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer;
1692
1693 if (NumberOfChildren == 0) {
1694 return EFI_SUCCESS;
1695 }
1696
1697 //
1698 // Close Absolute Pointer protocol on controller handle and virtual handle.
1699 //
1700 Status = ConSplitterStop (
1701 This,
1702 ControllerHandle,
1703 mConIn.VirtualHandle,
1704 &gEfiAbsolutePointerProtocolGuid,
1705 &gEfiAbsolutePointerProtocolGuid,
1706 (VOID **)&AbsolutePointer
1707 );
1708 if (EFI_ERROR (Status)) {
1709 return Status;
1710 }
1711
1712 //
1713 // Remove this device from Absolute Pointer device list.
1714 //
1715 return ConSplitterAbsolutePointerDeleteDevice (&mConIn, AbsolutePointer);
1716}
1717
1732EFIAPI
1735 IN EFI_HANDLE ControllerHandle,
1736 IN UINTN NumberOfChildren,
1737 IN EFI_HANDLE *ChildHandleBuffer
1738 )
1739{
1740 EFI_STATUS Status;
1742
1743 if (NumberOfChildren == 0) {
1744 return EFI_SUCCESS;
1745 }
1746
1747 //
1748 // Close Absolute Pointer protocol on controller handle and virtual handle.
1749 //
1750 Status = ConSplitterStop (
1751 This,
1752 ControllerHandle,
1753 mConOut.VirtualHandle,
1754 &gEfiConsoleOutDeviceGuid,
1755 &gEfiSimpleTextOutProtocolGuid,
1756 (VOID **)&TextOut
1757 );
1758 if (EFI_ERROR (Status)) {
1759 return Status;
1760 }
1761
1762 //
1763 // Remove this device from Text Out device list.
1764 //
1765 return ConSplitterTextOutDeleteDevice (&mConOut, TextOut);
1766}
1767
1782EFIAPI
1785 IN EFI_HANDLE ControllerHandle,
1786 IN UINTN NumberOfChildren,
1787 IN EFI_HANDLE *ChildHandleBuffer
1788 )
1789{
1790 EFI_STATUS Status;
1792
1793 if (NumberOfChildren == 0) {
1794 return EFI_SUCCESS;
1795 }
1796
1797 //
1798 // Close Standard Error Device on controller handle and virtual handle.
1799 //
1800 Status = ConSplitterStop (
1801 This,
1802 ControllerHandle,
1803 mStdErr.VirtualHandle,
1804 &gEfiStandardErrorDeviceGuid,
1805 &gEfiSimpleTextOutProtocolGuid,
1806 (VOID **)&TextOut
1807 );
1808 if (EFI_ERROR (Status)) {
1809 return Status;
1810 }
1811
1812 //
1813 // Delete this console error out device's data structures.
1814 //
1815 return ConSplitterTextOutDeleteDevice (&mStdErr, TextOut);
1816}
1817
1835 IN UINTN ElementSize,
1836 IN OUT UINTN *Count,
1837 IN OUT VOID **Buffer
1838 )
1839{
1840 VOID *Ptr;
1841
1842 //
1843 // grow the buffer to new buffer size,
1844 // copy the old buffer's content to the new-size buffer,
1845 // then free the old buffer.
1846 //
1847 Ptr = ReallocatePool (
1848 ElementSize * (*Count),
1849 ElementSize * ((*Count) + CONSOLE_SPLITTER_ALLOC_UNIT),
1850 *Buffer
1851 );
1852 if (Ptr == NULL) {
1853 return EFI_OUT_OF_RESOURCES;
1854 }
1855
1856 *Count += CONSOLE_SPLITTER_ALLOC_UNIT;
1857 *Buffer = Ptr;
1858 return EFI_SUCCESS;
1859}
1860
1875 )
1876{
1877 EFI_STATUS Status;
1878
1879 //
1880 // If the Text In List is full, enlarge it by calling ConSplitterGrowBuffer().
1881 //
1882 if (Private->CurrentNumberOfConsoles >= Private->TextInListCount) {
1883 Status = ConSplitterGrowBuffer (
1885 &Private->TextInListCount,
1886 (VOID **)&Private->TextInList
1887 );
1888 if (EFI_ERROR (Status)) {
1889 return EFI_OUT_OF_RESOURCES;
1890 }
1891 }
1892
1893 //
1894 // Add the new text-in device data structure into the Text In List.
1895 //
1896 Private->TextInList[Private->CurrentNumberOfConsoles] = TextIn;
1897 Private->CurrentNumberOfConsoles++;
1898
1899 //
1900 // Extra CheckEvent added to reduce the double CheckEvent().
1901 //
1902 gBS->CheckEvent (TextIn->WaitForKey);
1903
1904 return EFI_SUCCESS;
1905}
1906
1921 )
1922{
1923 UINTN Index;
1924
1925 //
1926 // Remove the specified text-in device data structure from the Text In List,
1927 // and rearrange the remaining data structures in the Text In List.
1928 //
1929 for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
1930 if (Private->TextInList[Index] == TextIn) {
1931 for ( ; Index < Private->CurrentNumberOfConsoles - 1; Index++) {
1932 Private->TextInList[Index] = Private->TextInList[Index + 1];
1933 }
1934
1935 Private->CurrentNumberOfConsoles--;
1936 return EFI_SUCCESS;
1937 }
1938 }
1939
1940 return EFI_NOT_FOUND;
1941}
1942
1957 )
1958{
1959 EFI_STATUS Status;
1960 LIST_ENTRY *Link;
1961 TEXT_IN_EX_SPLITTER_NOTIFY *CurrentNotify;
1962 UINTN TextInExListCount;
1963
1964 //
1965 // Enlarge the NotifyHandleList and the TextInExList
1966 //
1967 if (Private->CurrentNumberOfExConsoles >= Private->TextInExListCount) {
1968 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
1969 CurrentNotify = TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link);
1970 TextInExListCount = Private->TextInExListCount;
1971
1972 Status = ConSplitterGrowBuffer (
1973 sizeof (EFI_HANDLE),
1974 &TextInExListCount,
1975 (VOID **)&CurrentNotify->NotifyHandleList
1976 );
1977 if (EFI_ERROR (Status)) {
1978 return EFI_OUT_OF_RESOURCES;
1979 }
1980 }
1981
1982 TextInExListCount = Private->TextInExListCount;
1983 Status = ConSplitterGrowBuffer (
1984 sizeof (EFI_KEY_DATA),
1985 &TextInExListCount,
1986 (VOID **)&Private->KeyQueue
1987 );
1988 if (EFI_ERROR (Status)) {
1989 return EFI_OUT_OF_RESOURCES;
1990 }
1991
1992 Status = ConSplitterGrowBuffer (
1994 &Private->TextInExListCount,
1995 (VOID **)&Private->TextInExList
1996 );
1997 if (EFI_ERROR (Status)) {
1998 return EFI_OUT_OF_RESOURCES;
1999 }
2000 }
2001
2002 //
2003 // Register the key notify in the new text-in device
2004 //
2005 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
2006 CurrentNotify = TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link);
2007 Status = TextInEx->RegisterKeyNotify (
2008 TextInEx,
2009 &CurrentNotify->KeyData,
2010 CurrentNotify->KeyNotificationFn,
2011 &CurrentNotify->NotifyHandleList[Private->CurrentNumberOfExConsoles]
2012 );
2013 if (EFI_ERROR (Status)) {
2014 for (Link = Link->BackLink; Link != &Private->NotifyList; Link = Link->BackLink) {
2015 CurrentNotify = TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link);
2016 TextInEx->UnregisterKeyNotify (
2017 TextInEx,
2018 CurrentNotify->NotifyHandleList[Private->CurrentNumberOfExConsoles]
2019 );
2020 }
2021
2022 return Status;
2023 }
2024 }
2025
2026 //
2027 // Add the new text-in device data structure into the Text Input Ex List.
2028 //
2029 Private->TextInExList[Private->CurrentNumberOfExConsoles] = TextInEx;
2030 Private->CurrentNumberOfExConsoles++;
2031
2032 //
2033 // Sync current toggle state to this new console input device.
2034 //
2035 TextInEx->SetState (TextInEx, &Private->PhysicalKeyToggleState);
2036
2037 //
2038 // Extra CheckEvent added to reduce the double CheckEvent().
2039 //
2040 gBS->CheckEvent (TextInEx->WaitForKeyEx);
2041
2042 return EFI_SUCCESS;
2043}
2044
2059 )
2060{
2061 UINTN Index;
2062
2063 //
2064 // Remove the specified text-in device data structure from the Text Input Ex List,
2065 // and rearrange the remaining data structures in the Text In List.
2066 //
2067 for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
2068 if (Private->TextInExList[Index] == TextInEx) {
2069 for ( ; Index < Private->CurrentNumberOfExConsoles - 1; Index++) {
2070 Private->TextInExList[Index] = Private->TextInExList[Index + 1];
2071 }
2072
2073 Private->CurrentNumberOfExConsoles--;
2074 return EFI_SUCCESS;
2075 }
2076 }
2077
2078 return EFI_NOT_FOUND;
2079}
2080
2094 IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer
2095 )
2096{
2097 EFI_STATUS Status;
2098
2099 //
2100 // If the Simple Pointer List is full, enlarge it by calling ConSplitterGrowBuffer().
2101 //
2102 if (Private->CurrentNumberOfPointers >= Private->PointerListCount) {
2103 Status = ConSplitterGrowBuffer (
2104 sizeof (EFI_SIMPLE_POINTER_PROTOCOL *),
2105 &Private->PointerListCount,
2106 (VOID **)&Private->PointerList
2107 );
2108 if (EFI_ERROR (Status)) {
2109 return EFI_OUT_OF_RESOURCES;
2110 }
2111 }
2112
2113 //
2114 // Add the new text-in device data structure into the Simple Pointer List.
2115 //
2116 Private->PointerList[Private->CurrentNumberOfPointers] = SimplePointer;
2117 Private->CurrentNumberOfPointers++;
2118
2119 return EFI_SUCCESS;
2120}
2121
2135 IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer
2136 )
2137{
2138 UINTN Index;
2139
2140 //
2141 // Remove the specified text-in device data structure from the Simple Pointer List,
2142 // and rearrange the remaining data structures in the Text In List.
2143 //
2144 for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {
2145 if (Private->PointerList[Index] == SimplePointer) {
2146 for ( ; Index < Private->CurrentNumberOfPointers - 1; Index++) {
2147 Private->PointerList[Index] = Private->PointerList[Index + 1];
2148 }
2149
2150 Private->CurrentNumberOfPointers--;
2151 return EFI_SUCCESS;
2152 }
2153 }
2154
2155 return EFI_NOT_FOUND;
2156}
2157
2171 IN EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer
2172 )
2173{
2174 EFI_STATUS Status;
2175
2176 //
2177 // If the Absolute Pointer List is full, enlarge it by calling ConSplitterGrowBuffer().
2178 //
2179 if (Private->CurrentNumberOfAbsolutePointers >= Private->AbsolutePointerListCount) {
2180 Status = ConSplitterGrowBuffer (
2182 &Private->AbsolutePointerListCount,
2183 (VOID **)&Private->AbsolutePointerList
2184 );
2185 if (EFI_ERROR (Status)) {
2186 return EFI_OUT_OF_RESOURCES;
2187 }
2188 }
2189
2190 //
2191 // Add the new text-in device data structure into the Absolute Pointer List.
2192 //
2193 Private->AbsolutePointerList[Private->CurrentNumberOfAbsolutePointers] = AbsolutePointer;
2194 Private->CurrentNumberOfAbsolutePointers++;
2195
2196 return EFI_SUCCESS;
2197}
2198
2212 IN EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer
2213 )
2214{
2215 UINTN Index;
2216
2217 //
2218 // Remove the specified text-in device data structure from the Absolute Pointer List,
2219 // and rearrange the remaining data structures from the Absolute Pointer List.
2220 //
2221 for (Index = 0; Index < Private->CurrentNumberOfAbsolutePointers; Index++) {
2222 if (Private->AbsolutePointerList[Index] == AbsolutePointer) {
2223 for ( ; Index < Private->CurrentNumberOfAbsolutePointers - 1; Index++) {
2224 Private->AbsolutePointerList[Index] = Private->AbsolutePointerList[Index + 1];
2225 }
2226
2227 Private->CurrentNumberOfAbsolutePointers--;
2228 return EFI_SUCCESS;
2229 }
2230 }
2231
2232 return EFI_NOT_FOUND;
2233}
2234
2249 )
2250{
2251 UINTN Size;
2252 UINTN NewSize;
2253 UINTN TotalSize;
2254 INT32 *TextOutModeMap;
2255 INT32 *OldTextOutModeMap;
2256 INT32 *SrcAddress;
2257 INT32 Index;
2258 UINTN OldStepSize;
2259 UINTN NewStepSize;
2260
2261 NewSize = Private->TextOutListCount * sizeof (INT32);
2262 OldTextOutModeMap = Private->TextOutModeMap;
2263 TotalSize = NewSize * (Private->TextOutQueryDataCount);
2264
2265 //
2266 // Allocate new buffer for Text Out List.
2267 //
2268 TextOutModeMap = AllocatePool (TotalSize);
2269 if (TextOutModeMap == NULL) {
2270 return EFI_OUT_OF_RESOURCES;
2271 }
2272
2273 SetMem (TextOutModeMap, TotalSize, 0xFF);
2274 Private->TextOutModeMap = TextOutModeMap;
2275
2276 //
2277 // If TextOutList has been enlarged, need to realloc the mode map table
2278 // The mode map table is regarded as a two dimension array.
2279 //
2280 // Old New
2281 // 0 ---------> TextOutListCount ----> TextOutListCount
2282 // | -------------------------------------------
2283 // | | | |
2284 // | | | |
2285 // | | | |
2286 // | | | |
2287 // | | | |
2288 // \/ | | |
2289 // -------------------------------------------
2290 // QueryDataCount
2291 //
2292 if (OldTextOutModeMap != NULL) {
2293 Size = Private->CurrentNumberOfConsoles * sizeof (INT32);
2294 Index = 0;
2295 SrcAddress = OldTextOutModeMap;
2296 NewStepSize = NewSize / sizeof (INT32);
2297 // If Private->CurrentNumberOfConsoles is not zero and OldTextOutModeMap
2298 // is not NULL, it indicates that the original TextOutModeMap is not enough
2299 // for the new console devices and has been enlarged by CONSOLE_SPLITTER_ALLOC_UNIT columns.
2300 //
2301 OldStepSize = NewStepSize - CONSOLE_SPLITTER_ALLOC_UNIT;
2302
2303 //
2304 // Copy the old data to the new one
2305 //
2306 while (Index < Private->TextOutMode.MaxMode) {
2307 CopyMem (TextOutModeMap, SrcAddress, Size);
2308 //
2309 // Go to next row of new TextOutModeMap.
2310 //
2311 TextOutModeMap += NewStepSize;
2312 //
2313 // Go to next row of old TextOutModeMap.
2314 //
2315 SrcAddress += OldStepSize;
2316 Index++;
2317 }
2318
2319 //
2320 // Free the old buffer
2321 //
2322 FreePool (OldTextOutModeMap);
2323 }
2324
2325 return EFI_SUCCESS;
2326}
2327
2342 )
2343{
2344 EFI_STATUS Status;
2345 INT32 MaxMode;
2346 INT32 Mode;
2347 UINTN Index;
2348
2349 MaxMode = TextOut->Mode->MaxMode;
2350 Private->TextOutMode.MaxMode = MaxMode;
2351
2352 //
2353 // Grow the buffer if query data buffer is not large enough to
2354 // hold all the mode supported by the first console.
2355 //
2356 while (MaxMode > (INT32)Private->TextOutQueryDataCount) {
2357 Status = ConSplitterGrowBuffer (
2359 &Private->TextOutQueryDataCount,
2360 (VOID **)&Private->TextOutQueryData
2361 );
2362 if (EFI_ERROR (Status)) {
2363 return EFI_OUT_OF_RESOURCES;
2364 }
2365 }
2366
2367 //
2368 // Allocate buffer for the output mode map
2369 //
2370 Status = ConSplitterGrowMapTable (Private);
2371 if (EFI_ERROR (Status)) {
2372 return EFI_OUT_OF_RESOURCES;
2373 }
2374
2375 //
2376 // As the first textout device, directly add the mode in to QueryData
2377 // and at the same time record the mapping between QueryData and TextOut.
2378 //
2379 Mode = 0;
2380 Index = 0;
2381 while (Mode < MaxMode) {
2382 Status = TextOut->QueryMode (
2383 TextOut,
2384 Mode,
2385 &Private->TextOutQueryData[Mode].Columns,
2386 &Private->TextOutQueryData[Mode].Rows
2387 );
2388 //
2389 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData
2390 // is clear to 0x0.
2391 //
2392 if ((EFI_ERROR (Status)) && (Mode == 1)) {
2393 Private->TextOutQueryData[Mode].Columns = 0;
2394 Private->TextOutQueryData[Mode].Rows = 0;
2395 }
2396
2397 Private->TextOutModeMap[Index] = Mode;
2398 Mode++;
2399 Index += Private->TextOutListCount;
2400 }
2401
2402 return EFI_SUCCESS;
2403}
2404
2421VOID
2423 IN INT32 *TextOutModeMap,
2424 IN INT32 *NewlyAddedMap,
2425 IN UINTN MapStepSize,
2426 IN UINTN NewMapStepSize,
2427 IN OUT INT32 *MaxMode,
2428 IN OUT INT32 *CurrentMode
2429 )
2430{
2431 INT32 Index;
2432 INT32 *CurrentMapEntry;
2433 INT32 *NextMapEntry;
2434 INT32 *NewMapEntry;
2435 INT32 CurrentMaxMode;
2436 INT32 Mode;
2437
2438 //
2439 // According to EFI/UEFI spec, mode 0 and mode 1 have been reserved
2440 // for 80x25 and 80x50 in Simple Text Out protocol, so don't make intersection
2441 // for mode 0 and mode 1, mode number starts from 2.
2442 //
2443 Index = 2;
2444 CurrentMapEntry = &TextOutModeMap[MapStepSize * 2];
2445 NextMapEntry = CurrentMapEntry;
2446 NewMapEntry = &NewlyAddedMap[NewMapStepSize * 2];
2447
2448 CurrentMaxMode = *MaxMode;
2449 Mode = *CurrentMode;
2450
2451 while (Index < CurrentMaxMode) {
2452 if (*NewMapEntry == -1) {
2453 //
2454 // This mode is not supported any more. Remove it. Special care
2455 // must be taken as this remove will also affect current mode;
2456 //
2457 if (Index == *CurrentMode) {
2458 Mode = -1;
2459 } else if (Index < *CurrentMode) {
2460 Mode--;
2461 }
2462
2463 (*MaxMode)--;
2464 } else {
2465 if (CurrentMapEntry != NextMapEntry) {
2466 CopyMem (NextMapEntry, CurrentMapEntry, MapStepSize * sizeof (INT32));
2467 }
2468
2469 NextMapEntry += MapStepSize;
2470 }
2471
2472 CurrentMapEntry += MapStepSize;
2473 NewMapEntry += NewMapStepSize;
2474 Index++;
2475 }
2476
2477 *CurrentMode = Mode;
2478
2479 return;
2480}
2481
2489VOID
2493 )
2494{
2495 INT32 CurrentMaxMode;
2496 INT32 Mode;
2497 INT32 Index;
2498 INT32 *TextOutModeMap;
2499 INT32 *MapTable;
2500 INT32 QueryMode;
2501 TEXT_OUT_SPLITTER_QUERY_DATA *TextOutQueryData;
2502 UINTN Rows;
2503 UINTN Columns;
2504 UINTN StepSize;
2505 EFI_STATUS Status;
2506
2507 //
2508 // Must make sure that current mode won't change even if mode number changes
2509 //
2510 CurrentMaxMode = Private->TextOutMode.MaxMode;
2511 TextOutModeMap = Private->TextOutModeMap;
2512 StepSize = Private->TextOutListCount;
2513 TextOutQueryData = Private->TextOutQueryData;
2514
2515 //
2516 // Query all the mode that the newly added TextOut supports
2517 //
2518 Mode = 0;
2519 MapTable = TextOutModeMap + Private->CurrentNumberOfConsoles;
2520 while (Mode < TextOut->Mode->MaxMode) {
2521 Status = TextOut->QueryMode (TextOut, Mode, &Columns, &Rows);
2522
2523 if (EFI_ERROR (Status)) {
2524 if (Mode == 1) {
2525 //
2526 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData
2527 // is clear to 0x0.
2528 //
2529 MapTable[StepSize] = Mode;
2530 TextOutQueryData[Mode].Columns = 0;
2531 TextOutQueryData[Mode].Rows = 0;
2532 }
2533
2534 Mode++;
2535 continue;
2536 }
2537
2538 //
2539 // Search the intersection map and QueryData database to see if they intersects
2540 //
2541 Index = 0;
2542 while (Index < CurrentMaxMode) {
2543 QueryMode = *(TextOutModeMap + Index * StepSize);
2544 if ((TextOutQueryData[QueryMode].Rows == Rows) && (TextOutQueryData[QueryMode].Columns == Columns)) {
2545 MapTable[Index * StepSize] = Mode;
2546 break;
2547 }
2548
2549 Index++;
2550 }
2551
2552 Mode++;
2553 }
2554
2555 //
2556 // Now search the TextOutModeMap table to find the intersection of supported
2557 // mode between ConSplitter and the newly added device.
2558 //
2560 TextOutModeMap,
2561 MapTable,
2562 StepSize,
2563 StepSize,
2564 &Private->TextOutMode.MaxMode,
2565 &Private->TextOutMode.Mode
2566 );
2567
2568 return;
2569}
2570
2580 VOID
2581 )
2582{
2583 UINTN ConOutNumOfConsoles;
2584 UINTN StdErrNumOfConsoles;
2585 TEXT_OUT_AND_GOP_DATA *ConOutTextOutList;
2586 TEXT_OUT_AND_GOP_DATA *StdErrTextOutList;
2587 UINTN Indexi;
2588 UINTN Indexj;
2589 UINTN ConOutRows;
2590 UINTN ConOutColumns;
2591 UINTN StdErrRows;
2592 UINTN StdErrColumns;
2593 INT32 ConOutMaxMode;
2594 INT32 StdErrMaxMode;
2595 INT32 ConOutMode;
2596 INT32 StdErrMode;
2597 INT32 Mode;
2598 INT32 Index;
2599 INT32 *ConOutModeMap;
2600 INT32 *StdErrModeMap;
2601 INT32 *ConOutMapTable;
2602 INT32 *StdErrMapTable;
2603 TEXT_OUT_SPLITTER_QUERY_DATA *ConOutQueryData;
2604 TEXT_OUT_SPLITTER_QUERY_DATA *StdErrQueryData;
2605 UINTN ConOutStepSize;
2606 UINTN StdErrStepSize;
2607 BOOLEAN FoundTheSameTextOut;
2608 UINTN ConOutMapTableSize;
2609 UINTN StdErrMapTableSize;
2610
2611 ConOutNumOfConsoles = mConOut.CurrentNumberOfConsoles;
2612 StdErrNumOfConsoles = mStdErr.CurrentNumberOfConsoles;
2613 ConOutTextOutList = mConOut.TextOutList;
2614 StdErrTextOutList = mStdErr.TextOutList;
2615
2616 Indexi = 0;
2617 FoundTheSameTextOut = FALSE;
2618 while ((Indexi < ConOutNumOfConsoles) && (!FoundTheSameTextOut)) {
2619 Indexj = 0;
2620 while (Indexj < StdErrNumOfConsoles) {
2621 if (ConOutTextOutList->TextOut == StdErrTextOutList->TextOut) {
2622 FoundTheSameTextOut = TRUE;
2623 break;
2624 }
2625
2626 Indexj++;
2627 StdErrTextOutList++;
2628 }
2629
2630 Indexi++;
2631 ConOutTextOutList++;
2632 }
2633
2634 if (!FoundTheSameTextOut) {
2635 return EFI_SUCCESS;
2636 }
2637
2638 //
2639 // Must make sure that current mode won't change even if mode number changes
2640 //
2641 ConOutMaxMode = mConOut.TextOutMode.MaxMode;
2642 ConOutModeMap = mConOut.TextOutModeMap;
2643 ConOutStepSize = mConOut.TextOutListCount;
2644 ConOutQueryData = mConOut.TextOutQueryData;
2645
2646 StdErrMaxMode = mStdErr.TextOutMode.MaxMode;
2647 StdErrModeMap = mStdErr.TextOutModeMap;
2648 StdErrStepSize = mStdErr.TextOutListCount;
2649 StdErrQueryData = mStdErr.TextOutQueryData;
2650
2651 //
2652 // Allocate the map table and set the map table's index to -1.
2653 //
2654 ConOutMapTableSize = ConOutMaxMode * sizeof (INT32);
2655 ConOutMapTable = AllocateZeroPool (ConOutMapTableSize);
2656 if (ConOutMapTable == NULL) {
2657 return EFI_OUT_OF_RESOURCES;
2658 }
2659
2660 SetMem (ConOutMapTable, ConOutMapTableSize, 0xFF);
2661
2662 StdErrMapTableSize = StdErrMaxMode * sizeof (INT32);
2663 StdErrMapTable = AllocateZeroPool (StdErrMapTableSize);
2664 if (StdErrMapTable == NULL) {
2665 return EFI_OUT_OF_RESOURCES;
2666 }
2667
2668 SetMem (StdErrMapTable, StdErrMapTableSize, 0xFF);
2669
2670 //
2671 // Find the intersection of the two set of modes. If they actually intersect, the
2672 // corresponding entry in the map table is set to 1.
2673 //
2674 Mode = 0;
2675 while (Mode < ConOutMaxMode) {
2676 //
2677 // Search the intersection map and QueryData database to see if they intersect
2678 //
2679 Index = 0;
2680 ConOutMode = *(ConOutModeMap + Mode * ConOutStepSize);
2681 ConOutRows = ConOutQueryData[ConOutMode].Rows;
2682 ConOutColumns = ConOutQueryData[ConOutMode].Columns;
2683 while (Index < StdErrMaxMode) {
2684 StdErrMode = *(StdErrModeMap + Index * StdErrStepSize);
2685 StdErrRows = StdErrQueryData[StdErrMode].Rows;
2686 StdErrColumns = StdErrQueryData[StdErrMode].Columns;
2687 if ((StdErrRows == ConOutRows) && (StdErrColumns == ConOutColumns)) {
2688 ConOutMapTable[Mode] = 1;
2689 StdErrMapTable[Index] = 1;
2690 break;
2691 }
2692
2693 Index++;
2694 }
2695
2696 Mode++;
2697 }
2698
2699 //
2700 // Now search the TextOutModeMap table to find the intersection of supported
2701 // mode between ConSplitter and the newly added device.
2702 //
2704 ConOutModeMap,
2705 ConOutMapTable,
2706 mConOut.TextOutListCount,
2707 1,
2708 &(mConOut.TextOutMode.MaxMode),
2709 &(mConOut.TextOutMode.Mode)
2710 );
2711
2712 if (mConOut.TextOutMode.Mode < 0) {
2713 mConOut.TextOut.SetMode (&(mConOut.TextOut), 0);
2714 }
2715
2717 StdErrModeMap,
2718 StdErrMapTable,
2719 mStdErr.TextOutListCount,
2720 1,
2721 &(mStdErr.TextOutMode.MaxMode),
2722 &(mStdErr.TextOutMode.Mode)
2723 );
2724
2725 if (mStdErr.TextOutMode.Mode < 0) {
2726 mStdErr.TextOut.SetMode (&(mStdErr.TextOut), 0);
2727 }
2728
2729 FreePool (ConOutMapTable);
2730 FreePool (StdErrMapTable);
2731
2732 return EFI_SUCCESS;
2733}
2734
2749 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,
2750 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw
2751 )
2752{
2753 EFI_STATUS Status;
2754 UINTN Index;
2755 UINTN CurrentIndex;
2757 UINTN SizeOfInfo;
2759 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *CurrentGraphicsOutputMode;
2762 UINTN NumberIndex;
2763 BOOLEAN Match;
2764 BOOLEAN AlreadyExist;
2765 UINT32 UgaHorizontalResolution;
2766 UINT32 UgaVerticalResolution;
2767 UINT32 UgaColorDepth;
2768 UINT32 UgaRefreshRate;
2769
2770 ASSERT (GraphicsOutput != NULL || UgaDraw != NULL);
2771
2772 CurrentGraphicsOutputMode = Private->GraphicsOutput.Mode;
2773
2774 Index = 0;
2775 CurrentIndex = 0;
2776 Status = EFI_SUCCESS;
2777
2778 if (Private->CurrentNumberOfUgaDraw != 0) {
2779 //
2780 // If any UGA device has already been added, then there is no need to
2781 // calculate intersection of display mode of different GOP/UGA device,
2782 // since only one display mode will be exported (i.e. user-defined mode)
2783 //
2784 goto Done;
2785 }
2786
2787 if (GraphicsOutput != NULL) {
2788 if (Private->CurrentNumberOfGraphicsOutput == 0) {
2789 //
2790 // This is the first Graphics Output device added
2791 //
2792 CurrentGraphicsOutputMode->MaxMode = GraphicsOutput->Mode->MaxMode;
2793 CurrentGraphicsOutputMode->Mode = GraphicsOutput->Mode->Mode;
2794 CopyMem (CurrentGraphicsOutputMode->Info, GraphicsOutput->Mode->Info, GraphicsOutput->Mode->SizeOfInfo);
2795 CurrentGraphicsOutputMode->SizeOfInfo = GraphicsOutput->Mode->SizeOfInfo;
2796 CurrentGraphicsOutputMode->FrameBufferBase = GraphicsOutput->Mode->FrameBufferBase;
2797 CurrentGraphicsOutputMode->FrameBufferSize = GraphicsOutput->Mode->FrameBufferSize;
2798
2799 //
2800 // Allocate resource for the private mode buffer
2801 //
2802 ModeBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION) * GraphicsOutput->Mode->MaxMode);
2803 if (ModeBuffer == NULL) {
2804 return EFI_OUT_OF_RESOURCES;
2805 }
2806
2807 FreePool (Private->GraphicsOutputModeBuffer);
2808 Private->GraphicsOutputModeBuffer = ModeBuffer;
2809
2810 //
2811 // Store all supported display modes to the private mode buffer
2812 //
2813 Mode = ModeBuffer;
2814 for (Index = 0; Index < GraphicsOutput->Mode->MaxMode; Index++) {
2815 //
2816 // The Info buffer would be allocated by callee
2817 //
2818 Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32)Index, &SizeOfInfo, &Info);
2819 if (EFI_ERROR (Status)) {
2820 return Status;
2821 }
2822
2823 ASSERT (SizeOfInfo <= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
2824 CopyMem (Mode, Info, SizeOfInfo);
2825 Mode++;
2826 FreePool (Info);
2827 }
2828 } else {
2829 //
2830 // Check intersection of display mode
2831 //
2832 ModeBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION) * CurrentGraphicsOutputMode->MaxMode);
2833 if (ModeBuffer == NULL) {
2834 return EFI_OUT_OF_RESOURCES;
2835 }
2836
2837 MatchedMode = ModeBuffer;
2838 Mode = &Private->GraphicsOutputModeBuffer[0];
2839 for (Index = 0; Index < CurrentGraphicsOutputMode->MaxMode; Index++) {
2840 Match = FALSE;
2841
2842 for (NumberIndex = 0; NumberIndex < GraphicsOutput->Mode->MaxMode; NumberIndex++) {
2843 //
2844 // The Info buffer would be allocated by callee
2845 //
2846 Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32)NumberIndex, &SizeOfInfo, &Info);
2847 if (EFI_ERROR (Status)) {
2848 return Status;
2849 }
2850
2851 if ((Info->HorizontalResolution == Mode->HorizontalResolution) &&
2852 (Info->VerticalResolution == Mode->VerticalResolution))
2853 {
2854 //
2855 // If GOP device supports one mode in current mode buffer,
2856 // it will be added into matched mode buffer
2857 //
2858 Match = TRUE;
2859 FreePool (Info);
2860 break;
2861 }
2862
2863 FreePool (Info);
2864 }
2865
2866 if (Match) {
2867 AlreadyExist = FALSE;
2868
2869 //
2870 // Check if GOP mode has been in the mode buffer, ModeBuffer = MatchedMode at begin.
2871 //
2872 for (Info = ModeBuffer; Info < MatchedMode; Info++) {
2873 if ((Info->HorizontalResolution == Mode->HorizontalResolution) &&
2874 (Info->VerticalResolution == Mode->VerticalResolution))
2875 {
2876 AlreadyExist = TRUE;
2877 break;
2878 }
2879 }
2880
2881 if (!AlreadyExist) {
2882 CopyMem (MatchedMode, Mode, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
2883
2884 //
2885 // Physical frame buffer is no longer available, change PixelFormat to PixelBltOnly
2886 //
2887 MatchedMode->Version = 0;
2888 MatchedMode->PixelFormat = PixelBltOnly;
2889 ZeroMem (&MatchedMode->PixelInformation, sizeof (EFI_PIXEL_BITMASK));
2890
2891 MatchedMode++;
2892 }
2893 }
2894
2895 Mode++;
2896 }
2897
2898 //
2899 // Drop the old mode buffer, assign it to a new one
2900 //
2901 FreePool (Private->GraphicsOutputModeBuffer);
2902 Private->GraphicsOutputModeBuffer = ModeBuffer;
2903
2904 //
2905 // Physical frame buffer is no longer available when there are more than one physical GOP devices
2906 //
2907 CurrentGraphicsOutputMode->MaxMode = (UINT32)(((UINTN)MatchedMode - (UINTN)ModeBuffer) / sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
2908 CurrentGraphicsOutputMode->Info->PixelFormat = PixelBltOnly;
2909 ZeroMem (&CurrentGraphicsOutputMode->Info->PixelInformation, sizeof (EFI_PIXEL_BITMASK));
2910 CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
2911 CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS)(UINTN)NULL;
2912 CurrentGraphicsOutputMode->FrameBufferSize = 0;
2913 }
2914
2915 //
2916 // Graphics console driver can ensure the same mode for all GOP devices
2917 //
2918 for (Index = 0; Index < CurrentGraphicsOutputMode->MaxMode; Index++) {
2919 Mode = &Private->GraphicsOutputModeBuffer[Index];
2920 if ((Mode->HorizontalResolution == GraphicsOutput->Mode->Info->HorizontalResolution) &&
2921 (Mode->VerticalResolution == GraphicsOutput->Mode->Info->VerticalResolution))
2922 {
2923 CurrentIndex = Index;
2924 break;
2925 }
2926 }
2927
2928 if (Index >= CurrentGraphicsOutputMode->MaxMode) {
2929 //
2930 // if user defined mode is not found, set to default mode 800x600
2931 //
2932 for (Index = 0; Index < CurrentGraphicsOutputMode->MaxMode; Index++) {
2933 Mode = &Private->GraphicsOutputModeBuffer[Index];
2934 if ((Mode->HorizontalResolution == 800) && (Mode->VerticalResolution == 600)) {
2935 CurrentIndex = Index;
2936 break;
2937 }
2938 }
2939 }
2940 } else if (UgaDraw != NULL) {
2941 //
2942 // Graphics console driver can ensure the same mode for all GOP devices
2943 // so we can get the current mode from this video device
2944 //
2945 UgaDraw->GetMode (
2946 UgaDraw,
2947 &UgaHorizontalResolution,
2948 &UgaVerticalResolution,
2949 &UgaColorDepth,
2950 &UgaRefreshRate
2951 );
2952
2953 CurrentGraphicsOutputMode->MaxMode = 1;
2954 Info = CurrentGraphicsOutputMode->Info;
2955 Info->Version = 0;
2956 Info->HorizontalResolution = UgaHorizontalResolution;
2957 Info->VerticalResolution = UgaVerticalResolution;
2958 Info->PixelFormat = PixelBltOnly;
2959 Info->PixelsPerScanLine = UgaHorizontalResolution;
2960 CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
2961 CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS)(UINTN)NULL;
2962 CurrentGraphicsOutputMode->FrameBufferSize = 0;
2963
2964 //
2965 // Update the private mode buffer
2966 //
2967 CopyMem (&Private->GraphicsOutputModeBuffer[0], Info, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
2968
2969 //
2970 // Only mode 0 is available to be set
2971 //
2972 CurrentIndex = 0;
2973 }
2974
2975Done:
2976
2977 if (GraphicsOutput != NULL) {
2978 Private->CurrentNumberOfGraphicsOutput++;
2979 }
2980
2981 if (UgaDraw != NULL) {
2982 Private->CurrentNumberOfUgaDraw++;
2983 }
2984
2985 //
2986 // Force GraphicsOutput mode to be set,
2987 //
2988
2989 Mode = &Private->GraphicsOutputModeBuffer[CurrentIndex];
2990 if ((GraphicsOutput != NULL) &&
2991 (Mode->HorizontalResolution == CurrentGraphicsOutputMode->Info->HorizontalResolution) &&
2992 (Mode->VerticalResolution == CurrentGraphicsOutputMode->Info->VerticalResolution))
2993 {
2994 CurrentGraphicsOutputMode->Mode = (UINT32)CurrentIndex;
2995 if ((Mode->HorizontalResolution != GraphicsOutput->Mode->Info->HorizontalResolution) ||
2996 (Mode->VerticalResolution != GraphicsOutput->Mode->Info->VerticalResolution))
2997 {
2998 //
2999 // If all existing video device has been set to common mode, only set new GOP device to
3000 // the common mode
3001 //
3002 for (NumberIndex = 0; NumberIndex < GraphicsOutput->Mode->MaxMode; NumberIndex++) {
3003 Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32)NumberIndex, &SizeOfInfo, &Info);
3004 if (EFI_ERROR (Status)) {
3005 return Status;
3006 }
3007
3008 if ((Info->HorizontalResolution == Mode->HorizontalResolution) && (Info->VerticalResolution == Mode->VerticalResolution)) {
3009 FreePool (Info);
3010 break;
3011 }
3012
3013 FreePool (Info);
3014 }
3015
3016 Status = GraphicsOutput->SetMode (GraphicsOutput, (UINT32)NumberIndex);
3017 }
3018 } else {
3019 //
3020 // Current mode number may need update now, so set it to an invalid mode number
3021 //
3022 CurrentGraphicsOutputMode->Mode = 0xffff;
3023 //
3024 // Graphics console can ensure all GOP devices have the same mode which can be taken as current mode.
3025 //
3026 Status = Private->GraphicsOutput.SetMode (&Private->GraphicsOutput, (UINT32)CurrentIndex);
3027 if (EFI_ERROR (Status)) {
3028 //
3029 // If user defined mode is not valid for display device, set to the default mode 800x600.
3030 //
3031 (Private->GraphicsOutputModeBuffer[0]).HorizontalResolution = 800;
3032 (Private->GraphicsOutputModeBuffer[0]).VerticalResolution = 600;
3033 Status = Private->GraphicsOutput.SetMode (&Private->GraphicsOutput, 0);
3034 }
3035 }
3036
3037 return Status;
3038}
3039
3050VOID
3053 )
3054{
3055 UINTN Col;
3056 UINTN Row;
3057 UINTN Mode;
3058 UINTN PreferMode;
3059 UINTN BaseMode;
3060 UINTN MaxMode;
3061 EFI_STATUS Status;
3062 CONSOLE_OUT_MODE ModeInfo;
3063 CONSOLE_OUT_MODE MaxModeInfo;
3065
3066 PreferMode = 0xFF;
3067 BaseMode = 0xFF;
3068 TextOut = &Private->TextOut;
3069 MaxMode = (UINTN)(TextOut->Mode->MaxMode);
3070
3071 MaxModeInfo.Column = 0;
3072 MaxModeInfo.Row = 0;
3073 ModeInfo.Column = PcdGet32 (PcdConOutColumn);
3074 ModeInfo.Row = PcdGet32 (PcdConOutRow);
3075
3076 //
3077 // To find the prefer mode and basic mode from Text Out mode list
3078 //
3079 for (Mode = 0; Mode < MaxMode; Mode++) {
3080 Status = TextOut->QueryMode (TextOut, Mode, &Col, &Row);
3081 if (!EFI_ERROR (Status)) {
3082 if ((ModeInfo.Column != 0) && (ModeInfo.Row != 0)) {
3083 //
3084 // Use user defined column and row
3085 //
3086 if ((Col == ModeInfo.Column) && (Row == ModeInfo.Row)) {
3087 PreferMode = Mode;
3088 }
3089 } else {
3090 //
3091 // If user sets PcdConOutColumn or PcdConOutRow to 0,
3092 // find and set the highest text mode.
3093 //
3094 if ((Col >= MaxModeInfo.Column) && (Row >= MaxModeInfo.Row)) {
3095 MaxModeInfo.Column = Col;
3096 MaxModeInfo.Row = Row;
3097 PreferMode = Mode;
3098 }
3099 }
3100
3101 if ((Col == 80) && (Row == 25)) {
3102 BaseMode = Mode;
3103 }
3104 }
3105 }
3106
3107 //
3108 // Set prefer mode to Text Out devices.
3109 //
3110 Status = TextOut->SetMode (TextOut, PreferMode);
3111 if (EFI_ERROR (Status)) {
3112 //
3113 // if current mode setting is failed, default 80x25 mode will be set.
3114 //
3115 Status = TextOut->SetMode (TextOut, BaseMode);
3116 ASSERT (!EFI_ERROR (Status));
3117
3118 Status = PcdSet32S (PcdConOutColumn, 80);
3119 ASSERT (!EFI_ERROR (Status));
3120 Status = PcdSet32S (PcdConOutRow, 25);
3121 ASSERT (!EFI_ERROR (Status));
3122 }
3123
3124 return;
3125}
3126
3143 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,
3144 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw
3145 )
3146{
3147 EFI_STATUS Status;
3148 UINTN CurrentNumOfConsoles;
3149 INT32 MaxMode;
3150 UINT32 UgaHorizontalResolution;
3151 UINT32 UgaVerticalResolution;
3152 UINT32 UgaColorDepth;
3153 UINT32 UgaRefreshRate;
3154 TEXT_OUT_AND_GOP_DATA *TextAndGop;
3155 UINTN SizeOfInfo;
3157 EFI_STATUS DeviceStatus;
3158
3159 Status = EFI_SUCCESS;
3160 CurrentNumOfConsoles = Private->CurrentNumberOfConsoles;
3161 Private->AddingConOutDevice = TRUE;
3162
3163 //
3164 // If the Text Out List is full, enlarge it by calling ConSplitterGrowBuffer().
3165 //
3166 while (CurrentNumOfConsoles >= Private->TextOutListCount) {
3167 Status = ConSplitterGrowBuffer (
3168 sizeof (TEXT_OUT_AND_GOP_DATA),
3169 &Private->TextOutListCount,
3170 (VOID **)&Private->TextOutList
3171 );
3172 if (EFI_ERROR (Status)) {
3173 return EFI_OUT_OF_RESOURCES;
3174 }
3175
3176 //
3177 // Also need to reallocate the TextOutModeMap table
3178 //
3179 Status = ConSplitterGrowMapTable (Private);
3180 if (EFI_ERROR (Status)) {
3181 return EFI_OUT_OF_RESOURCES;
3182 }
3183 }
3184
3185 TextAndGop = &Private->TextOutList[CurrentNumOfConsoles];
3186
3187 TextAndGop->TextOut = TextOut;
3188 TextAndGop->GraphicsOutput = GraphicsOutput;
3189 TextAndGop->UgaDraw = UgaDraw;
3190
3191 if (CurrentNumOfConsoles == 0) {
3192 //
3193 // Add the first device's output mode to console splitter's mode list
3194 //
3195 Status = ConSplitterAddOutputMode (Private, TextOut);
3196 } else {
3197 ConSplitterSyncOutputMode (Private, TextOut);
3198 }
3199
3200 Private->CurrentNumberOfConsoles++;
3201
3202 //
3203 // Scan both TextOutList, for the intersection TextOut device
3204 // maybe both ConOut and StdErr incorporate the same Text Out
3205 // device in them, thus the output of both should be synced.
3206 //
3208
3209 MaxMode = Private->TextOutMode.MaxMode;
3210 ASSERT (MaxMode >= 1);
3211
3212 DeviceStatus = EFI_DEVICE_ERROR;
3213 Status = EFI_DEVICE_ERROR;
3214
3215 //
3216 // This device display mode will be added into Graphics Ouput modes.
3217 //
3218 if ((GraphicsOutput != NULL) || (UgaDraw != NULL)) {
3219 DeviceStatus = ConSplitterAddGraphicsOutputMode (Private, GraphicsOutput, UgaDraw);
3220 }
3221
3222 if (FeaturePcdGet (PcdConOutUgaSupport)) {
3223 //
3224 // If UGA is produced by Consplitter
3225 //
3226 if (GraphicsOutput != NULL) {
3227 Status = GraphicsOutput->QueryMode (GraphicsOutput, GraphicsOutput->Mode->Mode, &SizeOfInfo, &Info);
3228 if (EFI_ERROR (Status)) {
3229 return Status;
3230 }
3231
3232 ASSERT (SizeOfInfo <= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
3233
3234 UgaHorizontalResolution = Info->HorizontalResolution;
3235 UgaVerticalResolution = Info->VerticalResolution;
3236
3237 FreePool (Info);
3238 } else if (UgaDraw != NULL) {
3239 Status = UgaDraw->GetMode (
3240 UgaDraw,
3241 &UgaHorizontalResolution,
3242 &UgaVerticalResolution,
3243 &UgaColorDepth,
3244 &UgaRefreshRate
3245 );
3246 if (!EFI_ERROR (Status) && EFI_ERROR (DeviceStatus)) {
3247 //
3248 // if GetMode is successfully and UGA device hasn't been set, set it
3249 //
3250 Status = ConSplitterUgaDrawSetMode (
3251 &Private->UgaDraw,
3252 UgaHorizontalResolution,
3253 UgaVerticalResolution,
3254 UgaColorDepth,
3255 UgaRefreshRate
3256 );
3257 }
3258
3259 //
3260 // If GetMode/SetMode is failed, set to 800x600 mode
3261 //
3262 if (EFI_ERROR (Status)) {
3263 Status = ConSplitterUgaDrawSetMode (
3264 &Private->UgaDraw,
3265 800,
3266 600,
3267 32,
3268 60
3269 );
3270 }
3271 }
3272 }
3273
3274 if (((!EFI_ERROR (DeviceStatus)) || (!EFI_ERROR (Status))) &&
3275 ((Private->CurrentNumberOfGraphicsOutput + Private->CurrentNumberOfUgaDraw) == 1))
3276 {
3277 if (!FeaturePcdGet (PcdConOutGopSupport)) {
3278 //
3279 // If Graphics Outpurt protocol not supported, UGA Draw protocol is installed
3280 // on the virtual handle.
3281 //
3282 Status = gBS->InstallMultipleProtocolInterfaces (
3283 &mConOut.VirtualHandle,
3284 &gEfiUgaDrawProtocolGuid,
3285 &mConOut.UgaDraw,
3286 NULL
3287 );
3288 } else if (!FeaturePcdGet (PcdConOutUgaSupport)) {
3289 //
3290 // If UGA Draw protocol not supported, Graphics Output Protocol is installed
3291 // on virtual handle.
3292 //
3293 Status = gBS->InstallMultipleProtocolInterfaces (
3294 &mConOut.VirtualHandle,
3295 &gEfiGraphicsOutputProtocolGuid,
3296 &mConOut.GraphicsOutput,
3297 NULL
3298 );
3299 } else {
3300 //
3301 // Boot Graphics Output protocol and UGA Draw protocol are supported,
3302 // both they will be installed on virtual handle.
3303 //
3304 Status = gBS->InstallMultipleProtocolInterfaces (
3305 &mConOut.VirtualHandle,
3306 &gEfiGraphicsOutputProtocolGuid,
3307 &mConOut.GraphicsOutput,
3308 &gEfiUgaDrawProtocolGuid,
3309 &mConOut.UgaDraw,
3310 NULL
3311 );
3312 }
3313 }
3314
3315 //
3316 // After adding new console device, all existing console devices should be
3317 // synced to the current shared mode.
3318 //
3320
3321 Private->AddingConOutDevice = FALSE;
3322
3323 return Status;
3324}
3325
3340 )
3341{
3342 INT32 Index;
3343 UINTN CurrentNumOfConsoles;
3344 TEXT_OUT_AND_GOP_DATA *TextOutList;
3345 EFI_STATUS Status;
3346
3347 //
3348 // Remove the specified text-out device data structure from the Text out List,
3349 // and rearrange the remaining data structures in the Text out List.
3350 //
3351 CurrentNumOfConsoles = Private->CurrentNumberOfConsoles;
3352 Index = (INT32)CurrentNumOfConsoles - 1;
3353 TextOutList = Private->TextOutList;
3354 while (Index >= 0) {
3355 if (TextOutList->TextOut == TextOut) {
3356 if (TextOutList->UgaDraw != NULL) {
3357 Private->CurrentNumberOfUgaDraw--;
3358 }
3359
3360 if (TextOutList->GraphicsOutput != NULL) {
3361 Private->CurrentNumberOfGraphicsOutput--;
3362 }
3363
3364 CopyMem (TextOutList, TextOutList + 1, sizeof (TEXT_OUT_AND_GOP_DATA) * Index);
3365 CurrentNumOfConsoles--;
3366 break;
3367 }
3368
3369 Index--;
3370 TextOutList++;
3371 }
3372
3373 //
3374 // The specified TextOut is not managed by the ConSplitter driver
3375 //
3376 if (Index < 0) {
3377 return EFI_NOT_FOUND;
3378 }
3379
3380 if ((Private->CurrentNumberOfGraphicsOutput == 0) && (Private->CurrentNumberOfUgaDraw == 0)) {
3381 //
3382 // If there is not any physical GOP and UGA device in system,
3383 // Consplitter GOP or UGA protocol will be uninstalled
3384 //
3385 if (!FeaturePcdGet (PcdConOutGopSupport)) {
3386 Status = gBS->UninstallProtocolInterface (
3387 Private->VirtualHandle,
3388 &gEfiUgaDrawProtocolGuid,
3389 &Private->UgaDraw
3390 );
3391 } else if (!FeaturePcdGet (PcdConOutUgaSupport)) {
3392 Status = gBS->UninstallProtocolInterface (
3393 Private->VirtualHandle,
3394 &gEfiGraphicsOutputProtocolGuid,
3395 &Private->GraphicsOutput
3396 );
3397 } else {
3398 Status = gBS->UninstallMultipleProtocolInterfaces (
3399 Private->VirtualHandle,
3400 &gEfiUgaDrawProtocolGuid,
3401 &Private->UgaDraw,
3402 &gEfiGraphicsOutputProtocolGuid,
3403 &Private->GraphicsOutput,
3404 NULL
3405 );
3406 }
3407 }
3408
3409 if (CurrentNumOfConsoles == 0) {
3410 //
3411 // If the number of consoles is zero, reset all parameters
3412 //
3413 Private->CurrentNumberOfConsoles = 0;
3414 Private->TextOutMode.MaxMode = 1;
3415 Private->TextOutQueryData[0].Columns = 80;
3416 Private->TextOutQueryData[0].Rows = 25;
3417 TextOutSetMode (Private, 0);
3418
3419 return EFI_SUCCESS;
3420 }
3421
3422 //
3423 // Max Mode is really an intersection of the QueryMode command to all
3424 // devices. So we must copy the QueryMode of the first device to
3425 // QueryData.
3426 //
3427 ZeroMem (
3428 Private->TextOutQueryData,
3429 Private->TextOutQueryDataCount * sizeof (TEXT_OUT_SPLITTER_QUERY_DATA)
3430 );
3431
3432 FreePool (Private->TextOutModeMap);
3433 Private->TextOutModeMap = NULL;
3434 TextOutList = Private->TextOutList;
3435
3436 //
3437 // Add the first TextOut to the QueryData array and ModeMap table
3438 //
3439 Status = ConSplitterAddOutputMode (Private, TextOutList->TextOut);
3440
3441 //
3442 // Now add one by one
3443 //
3444 Index = 1;
3445 Private->CurrentNumberOfConsoles = 1;
3446 TextOutList++;
3447 while ((UINTN)Index < CurrentNumOfConsoles) {
3448 ConSplitterSyncOutputMode (Private, TextOutList->TextOut);
3449 Index++;
3450 Private->CurrentNumberOfConsoles++;
3451 TextOutList++;
3452 }
3453
3455
3456 return Status;
3457}
3458
3471EFIAPI
3474 IN BOOLEAN ExtendedVerification
3475 )
3476{
3477 EFI_STATUS Status;
3478 EFI_STATUS ReturnStatus;
3480 UINTN Index;
3481
3482 Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
3483
3484 Private->KeyEventSignalState = FALSE;
3485
3486 //
3487 // return the worst status met
3488 //
3489 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
3490 Status = Private->TextInList[Index]->Reset (
3491 Private->TextInList[Index],
3492 ExtendedVerification
3493 );
3494 if (EFI_ERROR (Status)) {
3495 ReturnStatus = Status;
3496 }
3497 }
3498
3499 if (!EFI_ERROR (ReturnStatus)) {
3501 //
3502 // Empty the key queue.
3503 //
3504 Private->CurrentNumberOfKeys = 0;
3505 }
3506
3507 return ReturnStatus;
3508}
3509
3523 OUT EFI_KEY_DATA *KeyData
3524 )
3525{
3526 if (Private->CurrentNumberOfKeys == 0) {
3527 return EFI_NOT_FOUND;
3528 }
3529
3530 //
3531 // Return the first saved key.
3532 //
3533 CopyMem (KeyData, &Private->KeyQueue[0], sizeof (EFI_KEY_DATA));
3534 Private->CurrentNumberOfKeys--;
3535 CopyMem (
3536 &Private->KeyQueue[0],
3537 &Private->KeyQueue[1],
3538 Private->CurrentNumberOfKeys * sizeof (EFI_KEY_DATA)
3539 );
3540 return EFI_SUCCESS;
3541}
3542
3559EFIAPI
3562 OUT EFI_INPUT_KEY *Key
3563 )
3564{
3565 EFI_STATUS Status;
3566 UINTN Index;
3567 EFI_KEY_DATA KeyData;
3568
3569 //
3570 // Return the first saved non-NULL key.
3571 //
3572 while (TRUE) {
3573 Status = ConSplitterTextInExDequeueKey (Private, &KeyData);
3574 if (EFI_ERROR (Status)) {
3575 break;
3576 }
3577
3578 if ((KeyData.Key.ScanCode != CHAR_NULL) || (KeyData.Key.UnicodeChar != SCAN_NULL)) {
3579 CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
3580 return Status;
3581 }
3582 }
3583
3584 Key->UnicodeChar = 0;
3585 Key->ScanCode = SCAN_NULL;
3586
3587 //
3588 // if no physical console input device exists, return EFI_NOT_READY;
3589 // if any physical console input device has key input,
3590 // return the key and EFI_SUCCESS.
3591 //
3592 for (Index = 0; Index < Private->CurrentNumberOfConsoles;) {
3593 Status = Private->TextInList[Index]->ReadKeyStroke (
3594 Private->TextInList[Index],
3595 &KeyData.Key
3596 );
3597 if (!EFI_ERROR (Status)) {
3598 //
3599 // If it is not partial keystorke, return the key. Otherwise, continue
3600 // to read key from THIS physical console input device.
3601 //
3602 if ((KeyData.Key.ScanCode != CHAR_NULL) || (KeyData.Key.UnicodeChar != SCAN_NULL)) {
3603 CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
3604 return Status;
3605 }
3606 } else {
3607 //
3608 // Continue to read key from NEXT physical console input device.
3609 //
3610 Index++;
3611 }
3612 }
3613
3614 return EFI_NOT_READY;
3615}
3616
3633EFIAPI
3636 OUT EFI_INPUT_KEY *Key
3637 )
3638{
3640
3641 Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
3642
3643 Private->KeyEventSignalState = FALSE;
3644
3645 //
3646 // Signal ConnectConIn event on first call in Lazy ConIn mode
3647 //
3648 if (!mConInIsConnect && PcdGetBool (PcdConInConnectOnDemand)) {
3649 DEBUG ((DEBUG_INFO, "Connect ConIn in first ReadKeyStoke in Lazy ConIn mode.\n"));
3650 gBS->SignalEvent (Private->ConnectConInEvent);
3651 mConInIsConnect = TRUE;
3652 }
3653
3654 return ConSplitterTextInPrivateReadKeyStroke (Private, Key);
3655}
3656
3668VOID
3669EFIAPI
3671 IN EFI_EVENT Event,
3672 IN VOID *Context
3673 )
3674{
3675 EFI_STATUS Status;
3677 UINTN Index;
3678
3679 Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *)Context;
3680
3681 if (Private->KeyEventSignalState) {
3682 //
3683 // If KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
3684 //
3685 gBS->SignalEvent (Event);
3686 return;
3687 }
3688
3689 //
3690 // If any physical console input device has key input, signal the event.
3691 //
3692 for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
3693 Status = gBS->CheckEvent (Private->TextInList[Index]->WaitForKey);
3694 if (!EFI_ERROR (Status)) {
3695 gBS->SignalEvent (Event);
3696 Private->KeyEventSignalState = TRUE;
3697 }
3698 }
3699}
3700
3715BOOLEAN
3717 IN EFI_KEY_DATA *RegsiteredData,
3718 IN EFI_KEY_DATA *InputData
3719 )
3720{
3721 ASSERT (RegsiteredData != NULL && InputData != NULL);
3722
3723 if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
3724 (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar))
3725 {
3726 return FALSE;
3727 }
3728
3729 //
3730 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
3731 //
3732 if ((RegsiteredData->KeyState.KeyShiftState != 0) &&
3733 (RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState))
3734 {
3735 return FALSE;
3736 }
3737
3738 if ((RegsiteredData->KeyState.KeyToggleState != 0) &&
3739 (RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState))
3740 {
3741 return FALSE;
3742 }
3743
3744 return TRUE;
3745}
3746
3759EFIAPI
3762 IN BOOLEAN ExtendedVerification
3763 )
3764{
3765 EFI_STATUS Status;
3766 EFI_STATUS ReturnStatus;
3768 UINTN Index;
3769
3770 Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
3771
3772 Private->KeyEventSignalState = FALSE;
3773
3774 //
3775 // return the worst status met
3776 //
3777 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfExConsoles; Index++) {
3778 Status = Private->TextInExList[Index]->Reset (
3779 Private->TextInExList[Index],
3780 ExtendedVerification
3781 );
3782 if (EFI_ERROR (Status)) {
3783 ReturnStatus = Status;
3784 }
3785 }
3786
3787 if (!EFI_ERROR (ReturnStatus)) {
3789 //
3790 // Empty the key queue.
3791 //
3792 Private->CurrentNumberOfKeys = 0;
3793 }
3794
3795 return ReturnStatus;
3796}
3797
3817EFIAPI
3820 OUT EFI_KEY_DATA *KeyData
3821 )
3822{
3824 EFI_STATUS Status;
3825 UINTN Index;
3826 EFI_KEY_STATE KeyState;
3827 EFI_KEY_DATA CurrentKeyData;
3828
3829 if (KeyData == NULL) {
3830 return EFI_INVALID_PARAMETER;
3831 }
3832
3833 Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
3834
3835 Private->KeyEventSignalState = FALSE;
3836
3837 //
3838 // Signal ConnectConIn event on first call in Lazy ConIn mode
3839 //
3840 if (!mConInIsConnect && PcdGetBool (PcdConInConnectOnDemand)) {
3841 DEBUG ((DEBUG_INFO, "Connect ConIn in first ReadKeyStoke in Lazy ConIn mode.\n"));
3842 gBS->SignalEvent (Private->ConnectConInEvent);
3843 mConInIsConnect = TRUE;
3844 }
3845
3846 //
3847 // Return the first saved key.
3848 //
3849 Status = ConSplitterTextInExDequeueKey (Private, KeyData);
3850 if (!EFI_ERROR (Status)) {
3851 return Status;
3852 }
3853
3854 ASSERT (Private->CurrentNumberOfKeys == 0);
3855
3856 ZeroMem (&KeyState, sizeof (KeyState));
3857
3858 //
3859 // Iterate through all physical consoles to get key state.
3860 // Some physical consoles may return valid key.
3861 // Queue the valid keys.
3862 //
3863 for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
3864 ZeroMem (&CurrentKeyData, sizeof (EFI_KEY_DATA));
3865 Status = Private->TextInExList[Index]->ReadKeyStrokeEx (
3866 Private->TextInExList[Index],
3867 &CurrentKeyData
3868 );
3869 if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) {
3870 continue;
3871 }
3872
3873 //
3874 // Consolidate the key state from all physical consoles.
3875 //
3876 if ((CurrentKeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) {
3877 KeyState.KeyShiftState |= CurrentKeyData.KeyState.KeyShiftState;
3878 }
3879
3880 if ((CurrentKeyData.KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != 0) {
3881 KeyState.KeyToggleState |= CurrentKeyData.KeyState.KeyToggleState;
3882 }
3883
3884 if (!EFI_ERROR (Status)) {
3885 //
3886 // If virtual KeyState has been required to be exposed, or it is not
3887 // partial keystorke, queue the key.
3888 // It's possible that user presses at multiple keyboards at the same moment,
3889 // Private->KeyQueue[] are the storage to save all the keys.
3890 //
3891 if ((Private->VirtualKeyStateExported) ||
3892 (CurrentKeyData.Key.ScanCode != CHAR_NULL) ||
3893 (CurrentKeyData.Key.UnicodeChar != SCAN_NULL))
3894 {
3895 CopyMem (
3896 &Private->KeyQueue[Private->CurrentNumberOfKeys],
3897 &CurrentKeyData,
3898 sizeof (EFI_KEY_DATA)
3899 );
3900 Private->CurrentNumberOfKeys++;
3901 }
3902 }
3903 }
3904
3905 //
3906 // Consolidate the key state for all keys in Private->KeyQueue[]
3907 //
3908 for (Index = 0; Index < Private->CurrentNumberOfKeys; Index++) {
3909 CopyMem (&Private->KeyQueue[Index].KeyState, &KeyState, sizeof (EFI_KEY_STATE));
3910 }
3911
3912 //
3913 // Return the first saved key.
3914 //
3915 Status = ConSplitterTextInExDequeueKey (Private, KeyData);
3916 if (!EFI_ERROR (Status)) {
3917 return Status;
3918 }
3919
3920 //
3921 // Always return the key state even there is no key pressed.
3922 //
3923 ZeroMem (&KeyData->Key, sizeof (KeyData->Key));
3924 CopyMem (&KeyData->KeyState, &KeyState, sizeof (KeyData->KeyState));
3925 return EFI_NOT_READY;
3926}
3927
3944EFIAPI
3947 IN EFI_KEY_TOGGLE_STATE *KeyToggleState
3948 )
3949{
3951 EFI_STATUS Status;
3952 UINTN Index;
3953 EFI_KEY_TOGGLE_STATE PhysicalKeyToggleState;
3954
3955 if (KeyToggleState == NULL) {
3956 return EFI_INVALID_PARAMETER;
3957 }
3958
3959 Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
3960
3961 //
3962 // Always turn on physical TextInEx partial key report for
3963 // toggle state sync.
3964 //
3965 PhysicalKeyToggleState = *KeyToggleState | EFI_KEY_STATE_EXPOSED;
3966
3967 //
3968 // if no physical console input device exists, return EFI_SUCCESS;
3969 // otherwise return the status of setting state of physical console input device
3970 //
3971 for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
3972 Status = Private->TextInExList[Index]->SetState (
3973 Private->TextInExList[Index],
3974 &PhysicalKeyToggleState
3975 );
3976 if (EFI_ERROR (Status)) {
3977 return Status;
3978 }
3979 }
3980
3981 //
3982 // Record the physical KeyToggleState.
3983 //
3984 Private->PhysicalKeyToggleState = PhysicalKeyToggleState;
3985 //
3986 // Get if virtual KeyState has been required to be exposed.
3987 //
3988 Private->VirtualKeyStateExported = (((*KeyToggleState) & EFI_KEY_STATE_EXPOSED) != 0);
3989
3990 return EFI_SUCCESS;
3991}
3992
4016EFIAPI
4019 IN EFI_KEY_DATA *KeyData,
4020 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
4021 OUT VOID **NotifyHandle
4022 )
4023{
4025 EFI_STATUS Status;
4026 UINTN Index;
4027 TEXT_IN_EX_SPLITTER_NOTIFY *NewNotify;
4028 LIST_ENTRY *Link;
4029 TEXT_IN_EX_SPLITTER_NOTIFY *CurrentNotify;
4030
4031 if ((KeyData == NULL) || (NotifyHandle == NULL) || (KeyNotificationFunction == NULL)) {
4032 return EFI_INVALID_PARAMETER;
4033 }
4034
4035 Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
4036
4037 //
4038 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
4039 //
4040 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
4041 CurrentNotify = TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link);
4042 if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
4043 if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
4044 *NotifyHandle = CurrentNotify;
4045 return EFI_SUCCESS;
4046 }
4047 }
4048 }
4049
4050 //
4051 // Allocate resource to save the notification function
4052 //
4054 if (NewNotify == NULL) {
4055 return EFI_OUT_OF_RESOURCES;
4056 }
4057
4058 NewNotify->NotifyHandleList = (VOID **)AllocateZeroPool (sizeof (VOID *) * Private->TextInExListCount);
4059 if (NewNotify->NotifyHandleList == NULL) {
4060 gBS->FreePool (NewNotify);
4061 return EFI_OUT_OF_RESOURCES;
4062 }
4063
4064 NewNotify->Signature = TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE;
4065 NewNotify->KeyNotificationFn = KeyNotificationFunction;
4066 CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));
4067
4068 //
4069 // Return the wrong status of registering key notify of
4070 // physical console input device if meet problems
4071 //
4072 for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
4073 Status = Private->TextInExList[Index]->RegisterKeyNotify (
4074 Private->TextInExList[Index],
4075 KeyData,
4076 KeyNotificationFunction,
4077 &NewNotify->NotifyHandleList[Index]
4078 );
4079 if (EFI_ERROR (Status)) {
4080 //
4081 // Un-register the key notify on all physical console input devices
4082 //
4083 while (Index-- != 0) {
4084 Private->TextInExList[Index]->UnregisterKeyNotify (
4085 Private->TextInExList[Index],
4086 NewNotify->NotifyHandleList[Index]
4087 );
4088 }
4089
4090 gBS->FreePool (NewNotify->NotifyHandleList);
4091 gBS->FreePool (NewNotify);
4092 return Status;
4093 }
4094 }
4095
4096 InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry);
4097
4098 *NotifyHandle = NewNotify;
4099
4100 return EFI_SUCCESS;
4101}
4102
4116EFIAPI
4119 IN VOID *NotificationHandle
4120 )
4121{
4123 UINTN Index;
4124 TEXT_IN_EX_SPLITTER_NOTIFY *CurrentNotify;
4125 LIST_ENTRY *Link;
4126
4127 if (NotificationHandle == NULL) {
4128 return EFI_INVALID_PARAMETER;
4129 }
4130
4131 Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
4132
4133 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
4134 CurrentNotify = TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link);
4135 if (CurrentNotify == NotificationHandle) {
4136 for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
4137 Private->TextInExList[Index]->UnregisterKeyNotify (
4138 Private->TextInExList[Index],
4139 CurrentNotify->NotifyHandleList[Index]
4140 );
4141 }
4142
4143 RemoveEntryList (&CurrentNotify->NotifyEntry);
4144
4145 gBS->FreePool (CurrentNotify->NotifyHandleList);
4146 gBS->FreePool (CurrentNotify);
4147 return EFI_SUCCESS;
4148 }
4149 }
4150
4151 //
4152 // NotificationHandle is not found in database
4153 //
4154 return EFI_INVALID_PARAMETER;
4155}
4156
4169EFIAPI
4172 IN BOOLEAN ExtendedVerification
4173 )
4174{
4175 EFI_STATUS Status;
4176 EFI_STATUS ReturnStatus;
4178 UINTN Index;
4179
4180 Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This);
4181
4182 Private->InputEventSignalState = FALSE;
4183
4184 if (Private->CurrentNumberOfPointers == 0) {
4185 return EFI_SUCCESS;
4186 }
4187
4188 //
4189 // return the worst status met
4190 //
4191 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfPointers; Index++) {
4192 Status = Private->PointerList[Index]->Reset (
4193 Private->PointerList[Index],
4194 ExtendedVerification
4195 );
4196 if (EFI_ERROR (Status)) {
4197 ReturnStatus = Status;
4198 }
4199 }
4200
4201 return ReturnStatus;
4202}
4203
4218EFIAPI
4222 )
4223{
4224 EFI_STATUS Status;
4225 EFI_STATUS ReturnStatus;
4226 UINTN Index;
4227 EFI_SIMPLE_POINTER_STATE CurrentState;
4228
4229 State->RelativeMovementX = 0;
4230 State->RelativeMovementY = 0;
4231 State->RelativeMovementZ = 0;
4232 State->LeftButton = FALSE;
4233 State->RightButton = FALSE;
4234
4235 //
4236 // if no physical console input device exists, return EFI_NOT_READY;
4237 // if any physical console input device has key input,
4238 // return the key and EFI_SUCCESS.
4239 //
4240 ReturnStatus = EFI_NOT_READY;
4241 for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {
4242 Status = Private->PointerList[Index]->GetState (
4243 Private->PointerList[Index],
4244 &CurrentState
4245 );
4246 if (!EFI_ERROR (Status)) {
4247 if (ReturnStatus == EFI_NOT_READY) {
4248 ReturnStatus = EFI_SUCCESS;
4249 }
4250
4251 if (CurrentState.LeftButton) {
4252 State->LeftButton = TRUE;
4253 }
4254
4255 if (CurrentState.RightButton) {
4256 State->RightButton = TRUE;
4257 }
4258
4259 if ((CurrentState.RelativeMovementX != 0) && (Private->PointerList[Index]->Mode->ResolutionX != 0)) {
4260 State->RelativeMovementX += (CurrentState.RelativeMovementX * (INT32)Private->SimplePointerMode.ResolutionX) / (INT32)Private->PointerList[Index]->Mode->ResolutionX;
4261 }
4262
4263 if ((CurrentState.RelativeMovementY != 0) && (Private->PointerList[Index]->Mode->ResolutionY != 0)) {
4264 State->RelativeMovementY += (CurrentState.RelativeMovementY * (INT32)Private->SimplePointerMode.ResolutionY) / (INT32)Private->PointerList[Index]->Mode->ResolutionY;
4265 }
4266
4267 if ((CurrentState.RelativeMovementZ != 0) && (Private->PointerList[Index]->Mode->ResolutionZ != 0)) {
4268 State->RelativeMovementZ += (CurrentState.RelativeMovementZ * (INT32)Private->SimplePointerMode.ResolutionZ) / (INT32)Private->PointerList[Index]->Mode->ResolutionZ;
4269 }
4270 } else if (Status == EFI_DEVICE_ERROR) {
4271 ReturnStatus = EFI_DEVICE_ERROR;
4272 }
4273 }
4274
4275 return ReturnStatus;
4276}
4277
4292EFIAPI
4296 )
4297{
4299
4300 Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This);
4301
4302 Private->InputEventSignalState = FALSE;
4303
4304 return ConSplitterSimplePointerPrivateGetState (Private, State);
4305}
4306
4317VOID
4318EFIAPI
4320 IN EFI_EVENT Event,
4321 IN VOID *Context
4322 )
4323{
4324 EFI_STATUS Status;
4326 UINTN Index;
4327
4328 Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *)Context;
4329
4330 //
4331 // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
4332 //
4333 if (Private->InputEventSignalState) {
4334 gBS->SignalEvent (Event);
4335 return;
4336 }
4337
4338 //
4339 // if any physical console input device has key input, signal the event.
4340 //
4341 for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {
4342 Status = gBS->CheckEvent (Private->PointerList[Index]->WaitForInput);
4343 if (!EFI_ERROR (Status)) {
4344 gBS->SignalEvent (Event);
4345 Private->InputEventSignalState = TRUE;
4346 }
4347 }
4348}
4349
4362EFIAPI
4365 IN BOOLEAN ExtendedVerification
4366 )
4367{
4368 EFI_STATUS Status;
4369 EFI_STATUS ReturnStatus;
4371 UINTN Index;
4372
4373 Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This);
4374
4375 Private->AbsoluteInputEventSignalState = FALSE;
4376
4377 if (Private->CurrentNumberOfAbsolutePointers == 0) {
4378 return EFI_SUCCESS;
4379 }
4380
4381 //
4382 // return the worst status met
4383 //
4384 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfAbsolutePointers; Index++) {
4385 Status = Private->AbsolutePointerList[Index]->Reset (
4386 Private->AbsolutePointerList[Index],
4387 ExtendedVerification
4388 );
4389 if (EFI_ERROR (Status)) {
4390 ReturnStatus = Status;
4391 }
4392 }
4393
4394 return ReturnStatus;
4395}
4396
4413EFIAPI
4417 )
4418{
4420 EFI_STATUS Status;
4421 EFI_STATUS ReturnStatus;
4422 UINTN Index;
4423 EFI_ABSOLUTE_POINTER_STATE CurrentState;
4424 UINT64 MinX;
4425 UINT64 MinY;
4426 UINT64 MinZ;
4427 UINT64 MaxX;
4428 UINT64 MaxY;
4429 UINT64 MaxZ;
4430 UINT64 VirtualMinX;
4431 UINT64 VirtualMinY;
4432 UINT64 VirtualMinZ;
4433 UINT64 VirtualMaxX;
4434 UINT64 VirtualMaxY;
4435 UINT64 VirtualMaxZ;
4436
4437 Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This);
4438
4439 Private->AbsoluteInputEventSignalState = FALSE;
4440
4441 State->CurrentX = 0;
4442 State->CurrentY = 0;
4443 State->CurrentZ = 0;
4444 State->ActiveButtons = 0;
4445
4446 VirtualMinX = Private->AbsolutePointerMode.AbsoluteMinX;
4447 VirtualMinY = Private->AbsolutePointerMode.AbsoluteMinY;
4448 VirtualMinZ = Private->AbsolutePointerMode.AbsoluteMinZ;
4449 VirtualMaxX = Private->AbsolutePointerMode.AbsoluteMaxX;
4450 VirtualMaxY = Private->AbsolutePointerMode.AbsoluteMaxY;
4451 VirtualMaxZ = Private->AbsolutePointerMode.AbsoluteMaxZ;
4452
4453 //
4454 // if no physical pointer device exists, return EFI_NOT_READY;
4455 // if any physical pointer device has changed state,
4456 // return the state and EFI_SUCCESS.
4457 //
4458 ReturnStatus = EFI_NOT_READY;
4459 for (Index = 0; Index < Private->CurrentNumberOfAbsolutePointers; Index++) {
4460 Status = Private->AbsolutePointerList[Index]->GetState (
4461 Private->AbsolutePointerList[Index],
4462 &CurrentState
4463 );
4464 if (!EFI_ERROR (Status)) {
4465 if (ReturnStatus == EFI_NOT_READY) {
4466 ReturnStatus = EFI_SUCCESS;
4467 }
4468
4469 MinX = Private->AbsolutePointerList[Index]->Mode->AbsoluteMinX;
4470 MinY = Private->AbsolutePointerList[Index]->Mode->AbsoluteMinY;
4471 MinZ = Private->AbsolutePointerList[Index]->Mode->AbsoluteMinZ;
4472 MaxX = Private->AbsolutePointerList[Index]->Mode->AbsoluteMaxX;
4473 MaxY = Private->AbsolutePointerList[Index]->Mode->AbsoluteMaxY;
4474 MaxZ = Private->AbsolutePointerList[Index]->Mode->AbsoluteMaxZ;
4475
4476 State->ActiveButtons = CurrentState.ActiveButtons;
4477
4478 //
4479 // Rescale to Con Splitter virtual Absolute Pointer's resolution.
4480 //
4481 if (!((MinX == 0) && (MaxX == 0))) {
4482 State->CurrentX = VirtualMinX + DivU64x64Remainder (
4483 MultU64x64 (
4484 CurrentState.CurrentX,
4485 VirtualMaxX - VirtualMinX
4486 ),
4487 MaxX - MinX,
4488 NULL
4489 );
4490 }
4491
4492 if (!((MinY == 0) && (MaxY == 0))) {
4493 State->CurrentY = VirtualMinY + DivU64x64Remainder (
4494 MultU64x64 (
4495 CurrentState.CurrentY,
4496 VirtualMaxY - VirtualMinY
4497 ),
4498 MaxY - MinY,
4499 NULL
4500 );
4501 }
4502
4503 if (!((MinZ == 0) && (MaxZ == 0))) {
4504 State->CurrentZ = VirtualMinZ + DivU64x64Remainder (
4505 MultU64x64 (
4506 CurrentState.CurrentZ,
4507 VirtualMaxZ - VirtualMinZ
4508 ),
4509 MaxZ - MinZ,
4510 NULL
4511 );
4512 }
4513 } else if (Status == EFI_DEVICE_ERROR) {
4514 ReturnStatus = EFI_DEVICE_ERROR;
4515 }
4516 }
4517
4518 return ReturnStatus;
4519}
4520
4531VOID
4532EFIAPI
4534 IN EFI_EVENT Event,
4535 IN VOID *Context
4536 )
4537{
4538 EFI_STATUS Status;
4540 UINTN Index;
4541
4542 Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *)Context;
4543
4544 //
4545 // if AbsoluteInputEventSignalState is flagged before,
4546 // and not cleared by Reset() or GetState(), signal it
4547 //
4548 if (Private->AbsoluteInputEventSignalState) {
4549 gBS->SignalEvent (Event);
4550 return;
4551 }
4552
4553 //
4554 // if any physical console input device has key input, signal the event.
4555 //
4556 for (Index = 0; Index < Private->CurrentNumberOfAbsolutePointers; Index++) {
4557 Status = gBS->CheckEvent (Private->AbsolutePointerList[Index]->WaitForInput);
4558 if (!EFI_ERROR (Status)) {
4559 gBS->SignalEvent (Event);
4560 Private->AbsoluteInputEventSignalState = TRUE;
4561 }
4562 }
4563}
4564
4578EFIAPI
4581 IN BOOLEAN ExtendedVerification
4582 )
4583{
4584 EFI_STATUS Status;
4586 UINTN Index;
4587 EFI_STATUS ReturnStatus;
4588
4589 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
4590
4591 //
4592 // return the worst status met
4593 //
4594 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
4595 Status = Private->TextOutList[Index].TextOut->Reset (
4596 Private->TextOutList[Index].TextOut,
4597 ExtendedVerification
4598 );
4599 if (EFI_ERROR (Status)) {
4600 ReturnStatus = Status;
4601 }
4602 }
4603
4604 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BLACK));
4605
4606 //
4607 // reset all mode parameters
4608 //
4609 TextOutSetMode (Private, 0);
4610
4611 return ReturnStatus;
4612}
4613
4634EFIAPI
4637 IN CHAR16 *WString
4638 )
4639{
4640 EFI_STATUS Status;
4642 UINTN Index;
4643 EFI_STATUS ReturnStatus;
4644 UINTN MaxColumn;
4645 UINTN MaxRow;
4646
4647 This->SetAttribute (This, This->Mode->Attribute);
4648
4649 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
4650
4651 //
4652 // return the worst status met
4653 //
4654 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
4655 Status = Private->TextOutList[Index].TextOut->OutputString (
4656 Private->TextOutList[Index].TextOut,
4657 WString
4658 );
4659 if (EFI_ERROR (Status)) {
4660 ReturnStatus = Status;
4661 }
4662 }
4663
4664 if (Private->CurrentNumberOfConsoles > 0) {
4665 Private->TextOutMode.CursorColumn = Private->TextOutList[0].TextOut->Mode->CursorColumn;
4666 Private->TextOutMode.CursorRow = Private->TextOutList[0].TextOut->Mode->CursorRow;
4667 } else {
4668 //
4669 // When there is no real console devices in system,
4670 // update cursor position for the virtual device in consplitter.
4671 //
4672 Private->TextOut.QueryMode (
4673 &Private->TextOut,
4674 Private->TextOutMode.Mode,
4675 &MaxColumn,
4676 &MaxRow
4677 );
4678 for ( ; *WString != CHAR_NULL; WString++) {
4679 switch (*WString) {
4680 case CHAR_BACKSPACE:
4681 if ((Private->TextOutMode.CursorColumn == 0) && (Private->TextOutMode.CursorRow > 0)) {
4682 Private->TextOutMode.CursorRow--;
4683 Private->TextOutMode.CursorColumn = (INT32)(MaxColumn - 1);
4684 } else if (Private->TextOutMode.CursorColumn > 0) {
4685 Private->TextOutMode.CursorColumn--;
4686 }
4687
4688 break;
4689
4690 case CHAR_LINEFEED:
4691 if (Private->TextOutMode.CursorRow < (INT32)(MaxRow - 1)) {
4692 Private->TextOutMode.CursorRow++;
4693 }
4694
4695 break;
4696
4697 case CHAR_CARRIAGE_RETURN:
4698 Private->TextOutMode.CursorColumn = 0;
4699 break;
4700
4701 default:
4702 if (Private->TextOutMode.CursorColumn < (INT32)(MaxColumn - 1)) {
4703 Private->TextOutMode.CursorColumn++;
4704 } else {
4705 Private->TextOutMode.CursorColumn = 0;
4706 if (Private->TextOutMode.CursorRow < (INT32)(MaxRow - 1)) {
4707 Private->TextOutMode.CursorRow++;
4708 }
4709 }
4710
4711 break;
4712 }
4713 }
4714 }
4715
4716 return ReturnStatus;
4717}
4718
4735EFIAPI
4738 IN CHAR16 *WString
4739 )
4740{
4741 EFI_STATUS Status;
4743 UINTN Index;
4744 EFI_STATUS ReturnStatus;
4745
4746 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
4747
4748 //
4749 // return the worst status met
4750 //
4751 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
4752 Status = Private->TextOutList[Index].TextOut->TestString (
4753 Private->TextOutList[Index].TextOut,
4754 WString
4755 );
4756 if (EFI_ERROR (Status)) {
4757 ReturnStatus = Status;
4758 }
4759 }
4760
4761 //
4762 // There is no DevNullTextOutTestString () since a Unicode buffer would
4763 // always return EFI_SUCCESS.
4764 // ReturnStatus will be EFI_SUCCESS if no consoles are present
4765 //
4766 return ReturnStatus;
4767}
4768
4787EFIAPI
4790 IN UINTN ModeNumber,
4791 OUT UINTN *Columns,
4792 OUT UINTN *Rows
4793 )
4794{
4796 UINTN CurrentMode;
4797 INT32 *TextOutModeMap;
4798
4799 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
4800
4801 //
4802 // Check whether param ModeNumber is valid.
4803 // ModeNumber should be within range 0 ~ MaxMode - 1.
4804 //
4805 if ((ModeNumber > (UINTN)(((UINT32)-1)>>1))) {
4806 return EFI_UNSUPPORTED;
4807 }
4808
4809 if ((INT32)ModeNumber >= This->Mode->MaxMode) {
4810 return EFI_UNSUPPORTED;
4811 }
4812
4813 //
4814 // We get the available mode from mode intersection map if it's available
4815 //
4816 if (Private->TextOutModeMap != NULL) {
4817 TextOutModeMap = Private->TextOutModeMap + Private->TextOutListCount * ModeNumber;
4818 CurrentMode = (UINTN)(*TextOutModeMap);
4819 *Columns = Private->TextOutQueryData[CurrentMode].Columns;
4820 *Rows = Private->TextOutQueryData[CurrentMode].Rows;
4821 } else {
4822 *Columns = Private->TextOutQueryData[ModeNumber].Columns;
4823 *Rows = Private->TextOutQueryData[ModeNumber].Rows;
4824 }
4825
4826 if ((*Columns <= 0) && (*Rows <= 0)) {
4827 return EFI_UNSUPPORTED;
4828 }
4829
4830 return EFI_SUCCESS;
4831}
4832
4846EFIAPI
4849 IN UINTN ModeNumber
4850 )
4851{
4852 EFI_STATUS Status;
4854 UINTN Index;
4855 INT32 *TextOutModeMap;
4856 EFI_STATUS ReturnStatus;
4857
4858 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
4859
4860 //
4861 // Check whether param ModeNumber is valid.
4862 // ModeNumber should be within range 0 ~ MaxMode - 1.
4863 //
4864 if ((ModeNumber > (UINTN)(((UINT32)-1)>>1))) {
4865 return EFI_UNSUPPORTED;
4866 }
4867
4868 if ((INT32)ModeNumber >= This->Mode->MaxMode) {
4869 return EFI_UNSUPPORTED;
4870 }
4871
4872 //
4873 // If the mode is being set to the curent mode, then just clear the screen and return.
4874 //
4875 if (Private->TextOutMode.Mode == (INT32)ModeNumber) {
4876 return ConSplitterTextOutClearScreen (This);
4877 }
4878
4879 //
4880 // return the worst status met
4881 //
4882 TextOutModeMap = Private->TextOutModeMap + Private->TextOutListCount * ModeNumber;
4883 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
4884 //
4885 // While adding a console out device do not set same mode again for the same device.
4886 //
4887 if ((!Private->AddingConOutDevice) ||
4888 (TextOutModeMap[Index] != Private->TextOutList[Index].TextOut->Mode->Mode))
4889 {
4890 Status = Private->TextOutList[Index].TextOut->SetMode (
4891 Private->TextOutList[Index].TextOut,
4892 TextOutModeMap[Index]
4893 );
4894 if (EFI_ERROR (Status)) {
4895 ReturnStatus = Status;
4896 }
4897 }
4898 }
4899
4900 //
4901 // Set mode parameter to specified mode number
4902 //
4903 TextOutSetMode (Private, ModeNumber);
4904
4905 return ReturnStatus;
4906}
4907
4926EFIAPI
4929 IN UINTN Attribute
4930 )
4931{
4932 EFI_STATUS Status;
4934 UINTN Index;
4935 EFI_STATUS ReturnStatus;
4936
4937 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
4938
4939 //
4940 // Check whether param Attribute is valid.
4941 //
4942 if ((Attribute | 0x7F) != 0x7F) {
4943 return EFI_UNSUPPORTED;
4944 }
4945
4946 //
4947 // return the worst status met
4948 //
4949 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
4950 Status = Private->TextOutList[Index].TextOut->SetAttribute (
4951 Private->TextOutList[Index].TextOut,
4952 Attribute
4953 );
4954 if (EFI_ERROR (Status)) {
4955 ReturnStatus = Status;
4956 }
4957 }
4958
4959 Private->TextOutMode.Attribute = (INT32)Attribute;
4960
4961 return ReturnStatus;
4962}
4963
4977EFIAPI
4980 )
4981{
4982 EFI_STATUS Status;
4984 UINTN Index;
4985 EFI_STATUS ReturnStatus;
4986
4987 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
4988
4989 //
4990 // return the worst status met
4991 //
4992 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
4993 Status = Private->TextOutList[Index].TextOut->ClearScreen (Private->TextOutList[Index].TextOut);
4994 if (EFI_ERROR (Status)) {
4995 ReturnStatus = Status;
4996 }
4997 }
4998
4999 //
5000 // No need to do extra check here as whether (Column, Row) is valid has
5001 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
5002 // always be supported.
5003 //
5004 Private->TextOutMode.CursorColumn = 0;
5005 Private->TextOutMode.CursorRow = 0;
5006 Private->TextOutMode.CursorVisible = TRUE;
5007
5008 return ReturnStatus;
5009}
5010
5031EFIAPI
5034 IN UINTN Column,
5035 IN UINTN Row
5036 )
5037{
5038 EFI_STATUS Status;
5040 UINTN Index;
5041 EFI_STATUS ReturnStatus;
5042 UINTN MaxColumn;
5043 UINTN MaxRow;
5044 INT32 *TextOutModeMap;
5045 INT32 ModeNumber;
5046 INT32 CurrentMode;
5047
5048 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
5049 TextOutModeMap = NULL;
5050 ModeNumber = Private->TextOutMode.Mode;
5051
5052 //
5053 // Get current MaxColumn and MaxRow from intersection map
5054 //
5055 if (Private->TextOutModeMap != NULL) {
5056 TextOutModeMap = Private->TextOutModeMap + Private->TextOutListCount * ModeNumber;
5057 CurrentMode = *TextOutModeMap;
5058 } else {
5059 CurrentMode = ModeNumber;
5060 }
5061
5062 MaxColumn = Private->TextOutQueryData[CurrentMode].Columns;
5063 MaxRow = Private->TextOutQueryData[CurrentMode].Rows;
5064
5065 if ((Column >= MaxColumn) || (Row >= MaxRow)) {
5066 return EFI_UNSUPPORTED;
5067 }
5068
5069 //
5070 // return the worst status met
5071 //
5072 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
5073 Status = Private->TextOutList[Index].TextOut->SetCursorPosition (
5074 Private->TextOutList[Index].TextOut,
5075 Column,
5076 Row
5077 );
5078 if (EFI_ERROR (Status)) {
5079 ReturnStatus = Status;
5080 }
5081 }
5082
5083 //
5084 // No need to do extra check here as whether (Column, Row) is valid has
5085 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
5086 // always be supported.
5087 //
5088 Private->TextOutMode.CursorColumn = (INT32)Column;
5089 Private->TextOutMode.CursorRow = (INT32)Row;
5090
5091 return ReturnStatus;
5092}
5093
5109EFIAPI
5112 IN BOOLEAN Visible
5113 )
5114{
5115 EFI_STATUS Status;
5117 UINTN Index;
5118 EFI_STATUS ReturnStatus;
5119
5120 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
5121
5122 //
5123 // return the worst status met
5124 //
5125 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
5126 Status = Private->TextOutList[Index].TextOut->EnableCursor (
5127 Private->TextOutList[Index].TextOut,
5128 Visible
5129 );
5130 if (EFI_ERROR (Status)) {
5131 ReturnStatus = Status;
5132 }
5133 }
5134
5135 Private->TextOutMode.CursorVisible = Visible;
5136
5137 return ReturnStatus;
5138}
UINT64 UINTN
UINT64 EFIAPI MultU64x64(IN UINT64 Multiplicand, IN UINT64 Multiplier)
Definition: MultU64x64.c:27
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
UINT64 EFIAPI DivU64x64Remainder(IN UINT64 Dividend, IN UINT64 Divisor, OUT UINT64 *Remainder OPTIONAL)
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
Definition: SetMemWrapper.c:38
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI ConSplitterTextInReset(IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
Definition: ConSplitter.c:3472
EFI_STATUS ConSplitterAddOutputMode(IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private, IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut)
Definition: ConSplitter.c:2339
EFI_STATUS EFIAPI ConSplitterTextOutSetCursorPosition(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN Column, IN UINTN Row)
Definition: ConSplitter.c:5032
VOID ConSplitterSyncOutputMode(IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private, IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut)
Definition: ConSplitter.c:2490
EFI_STATUS EFIAPI ConSplitterConOutDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: ConSplitter.c:1329
EFI_STATUS EFIAPI ConSplitterConOutDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: ConSplitter.c:1733
EFI_STATUS ConSplitterAbsolutePointerAddDevice(IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, IN EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer)
Definition: ConSplitter.c:2169
EFI_STATUS EFIAPI ConSplitterAbsolutePointerDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: ConSplitter.c:990
EFI_STATUS EFIAPI ConSplitterTextOutOutputString(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *WString)
Definition: ConSplitter.c:4635
EFI_STATUS EFIAPI ConSplitterConInDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: ConSplitter.c:1171
EFI_STATUS EFIAPI ConSplitterSimplePointerDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: ConSplitter.c:963
EFI_STATUS EFIAPI ConSplitterTextOutSetAttribute(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN Attribute)
Definition: ConSplitter.c:4927
EFI_STATUS EFIAPI ConSplitterTextOutTestString(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *WString)
Definition: ConSplitter.c:4736
EFI_STATUS ConSplitterGrowBuffer(IN UINTN ElementSize, IN OUT UINTN *Count, IN OUT VOID **Buffer)
Definition: ConSplitter.c:1834
EFI_STATUS EFIAPI ConSplitterTextOutQueryMode(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN ModeNumber, OUT UINTN *Columns, OUT UINTN *Rows)
Definition: ConSplitter.c:4788
EFI_STATUS EFIAPI ConSplitterTextOutReset(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
Definition: ConSplitter.c:4579
EFI_STATUS EFIAPI ConSplitterTextInResetEx(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
Definition: ConSplitter.c:3760
EFI_STATUS EFIAPI ConSplitterStdErrDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: ConSplitter.c:1783
VOID EFIAPI ConSplitterSimplePointerWaitForInput(IN EFI_EVENT Event, IN VOID *Context)
Definition: ConSplitter.c:4319
EFI_STATUS ConSplitterSimplePointerDeleteDevice(IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer)
Definition: ConSplitter.c:2133
EFI_STATUS EFIAPI ToggleStateSyncKeyNotify(IN EFI_KEY_DATA *KeyData)
Definition: ConSplitter.c:313
EFI_STATUS EFIAPI ConSplitterConInDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: ConSplitter.c:1561
EFI_STATUS ConSplitterTextOutDeleteDevice(IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private, IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut)
Definition: ConSplitter.c:3337
VOID EFIAPI ConSplitterTextInWaitForKey(IN EFI_EVENT Event, IN VOID *Context)
Definition: ConSplitter.c:3670
EFI_STATUS EFIAPI ConSplitterTextInReadKeyStrokeEx(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, OUT EFI_KEY_DATA *KeyData)
Definition: ConSplitter.c:3818
EFI_STATUS ConSplitterStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ConSplitterVirtualHandle, IN EFI_GUID *DeviceGuid, IN EFI_GUID *InterfaceGuid, IN VOID **Interface)
Definition: ConSplitter.c:1503
EFI_STATUS EFIAPI ConSplitterTextOutEnableCursor(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN BOOLEAN Visible)
Definition: ConSplitter.c:5110
EFI_STATUS EFIAPI ConSplitterConOutDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: ConSplitter.c:1017
EFI_STATUS EFIAPI ConSplitterSimplePointerReset(IN EFI_SIMPLE_POINTER_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
Definition: ConSplitter.c:4170
VOID ToggleStateSyncInitialization(IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private)
Definition: ConSplitter.c:346
EFI_STATUS ConSplitterTextOutAddDevice(IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private, IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut, IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput, IN EFI_UGA_DRAW_PROTOCOL *UgaDraw)
Definition: ConSplitter.c:3140
EFI_STATUS ConSplitterAddGraphicsOutputMode(IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private, IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput, IN EFI_UGA_DRAW_PROTOCOL *UgaDraw)
Definition: ConSplitter.c:2747
EFI_STATUS ConSplitterTextInAddDevice(IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn)
Definition: ConSplitter.c:1872
EFI_STATUS EFIAPI ConSplitterSimplePointerPrivateGetState(IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, IN OUT EFI_SIMPLE_POINTER_STATE *State)
Definition: ConSplitter.c:4219
EFI_STATUS EFIAPI ConSplitterConInDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: ConSplitter.c:936
VOID ConSplitterGetIntersection(IN INT32 *TextOutModeMap, IN INT32 *NewlyAddedMap, IN UINTN MapStepSize, IN UINTN NewMapStepSize, IN OUT INT32 *MaxMode, IN OUT INT32 *CurrentMode)
Definition: ConSplitter.c:2422
EFI_STATUS ConSplitterSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_GUID *Guid)
Definition: ConSplitter.c:876
EFI_STATUS EFIAPI ConSplitterTextOutSetMode(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN ModeNumber)
Definition: ConSplitter.c:4847
EFI_STATUS ConSplitterAbsolutePointerDeleteDevice(IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, IN EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer)
Definition: ConSplitter.c:2210
EFI_STATUS EFIAPI ConSplitterStdErrDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: ConSplitter.c:1044
VOID EFIAPI ConSplitterAbsolutePointerWaitForInput(IN EFI_EVENT Event, IN VOID *Context)
Definition: ConSplitter.c:4533
EFI_STATUS EFIAPI ConSplitterSimplePointerGetState(IN EFI_SIMPLE_POINTER_PROTOCOL *This, IN OUT EFI_SIMPLE_POINTER_STATE *State)
Definition: ConSplitter.c:4293
EFI_STATUS ConSplitterTextInConstructor(TEXT_IN_SPLITTER_PRIVATE_DATA *ConInPrivate)
Definition: ConSplitter.c:603
EFI_STATUS EFIAPI ConSplitterAbsolutePointerDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: ConSplitter.c:1683
EFI_STATUS EFIAPI ConSplitterAbsolutePointerReset(IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
Definition: ConSplitter.c:4363
VOID ConsplitterSetConsoleOutMode(IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private)
Definition: ConSplitter.c:3051
EFI_STATUS EFIAPI ConSplitterStdErrDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: ConSplitter.c:1445
EFI_STATUS ConSplitterStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ConSplitterVirtualHandle, IN EFI_GUID *DeviceGuid, IN EFI_GUID *InterfaceGuid, OUT VOID **Interface)
Definition: ConSplitter.c:1075
EFI_STATUS EFIAPI ConSplitterAbsolutePointerGetState(IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, IN OUT EFI_ABSOLUTE_POINTER_STATE *State)
Definition: ConSplitter.c:4414
EFI_STATUS EFIAPI ConSplitterSimplePointerDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: ConSplitter.c:1238
EFI_STATUS EFIAPI ConSplitterAbsolutePointerDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: ConSplitter.c:1283
EFI_STATUS EFIAPI ConSplitterTextInUnregisterKeyNotify(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN VOID *NotificationHandle)
Definition: ConSplitter.c:4117
EFI_STATUS EFIAPI ConSplitterTextInReadKeyStroke(IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, OUT EFI_INPUT_KEY *Key)
Definition: ConSplitter.c:3634
EFI_STATUS EFIAPI ConSplitterTextInRegisterKeyNotify(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_KEY_DATA *KeyData, IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, OUT VOID **NotifyHandle)
Definition: ConSplitter.c:4017
VOID ToggleStateSyncReInitialization(IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private)
Definition: ConSplitter.c:390
EFI_STATUS ConSplitterTextInExDeleteDevice(IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx)
Definition: ConSplitter.c:2056
EFI_STATUS ConSplitterTextInExAddDevice(IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx)
Definition: ConSplitter.c:1954
EFI_STATUS ConSplitterSimplePointerAddDevice(IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer)
Definition: ConSplitter.c:2092
EFI_STATUS EFIAPI ConSplitterTextOutClearScreen(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This)
Definition: ConSplitter.c:4978
EFI_STATUS EFIAPI ConSplitterTextInPrivateReadKeyStroke(IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, OUT EFI_INPUT_KEY *Key)
Definition: ConSplitter.c:3560
EFI_STATUS ConSplitterGrowMapTable(IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private)
Definition: ConSplitter.c:2247
EFI_STATUS ConSplitterTextInDeleteDevice(IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn)
Definition: ConSplitter.c:1918
EFI_STATUS EFIAPI ConSplitterDriverEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: ConSplitter.c:436
EFI_STATUS ConSplitterTextInExDequeueKey(IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private, OUT EFI_KEY_DATA *KeyData)
Definition: ConSplitter.c:3521
EFI_STATUS ConSplitterTextOutConstructor(TEXT_OUT_SPLITTER_PRIVATE_DATA *ConOutPrivate)
Definition: ConSplitter.c:750
EFI_STATUS ConSplitterGetIntersectionBetweenConOutAndStrErr(VOID)
Definition: ConSplitter.c:2579
EFI_STATUS EFIAPI ConSplitterSimplePointerDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: ConSplitter.c:1632
BOOLEAN IsKeyRegistered(IN EFI_KEY_DATA *RegsiteredData, IN EFI_KEY_DATA *InputData)
Definition: ConSplitter.c:3716
EFI_STATUS EFIAPI ConSplitterTextInSetState(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_KEY_TOGGLE_STATE *KeyToggleState)
Definition: ConSplitter.c:3945
EFI_STATUS EFIAPI ConSplitterUgaDrawGetMode(IN EFI_UGA_DRAW_PROTOCOL *This, OUT UINT32 *HorizontalResolution, OUT UINT32 *VerticalResolution, OUT UINT32 *ColorDepth, OUT UINT32 *RefreshRate)
EFI_STATUS EFIAPI ConSplitterGraphicsOutputBlt(IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL, IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height, IN UINTN Delta OPTIONAL)
VOID TextOutSetMode(IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private, IN UINTN ModeNumber)
EFI_STATUS EFIAPI ConSplitterGraphicsOutputSetMode(IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber)
EFI_STATUS EFIAPI ConSplitterGraphicsOutputQueryMode(IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber, OUT UINTN *SizeOfInfo, OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info)
EFI_STATUS EFIAPI ConSplitterUgaDrawBlt(IN EFI_UGA_DRAW_PROTOCOL *This, IN EFI_UGA_PIXEL *BltBuffer OPTIONAL, IN EFI_UGA_BLT_OPERATION BltOperation, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height, IN UINTN Delta OPTIONAL)
EFI_STATUS EFIAPI ConSplitterUgaDrawSetMode(IN EFI_UGA_DRAW_PROTOCOL *This, IN UINT32 HorizontalResolution, IN UINT32 VerticalResolution, IN UINT32 ColorDepth, IN UINT32 RefreshRate)
VOID *EFIAPI ReallocatePool(IN UINTN OldSize, IN UINTN NewSize, IN VOID *OldBuffer OPTIONAL)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
@ PixelBltOnly
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
#define PcdSet32S(TokenName, Value)
Definition: PcdLib.h:497
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
STATIC BOOLEAN Match(IN CONST CHAR16 *Translated, IN UINTN TranslatedLength, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
UINT8 EFI_KEY_TOGGLE_STATE
EFI_STATUS(EFIAPI * EFI_KEY_NOTIFY_FUNCTION)(IN EFI_KEY_DATA *KeyData)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_SYSTEM_TABLE * gST
EFI_BOOT_SERVICES * gBS
VOID EFIAPI EfiEventEmptyFunction(IN EFI_EVENT Event, IN VOID *Context)
Definition: UefiLib.c:354
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_ABSOLUTE_POINTER_MODE * Mode
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE * Mode
EFI_KEY_TOGGLE_STATE KeyToggleState
UINT32 KeyShiftState
EFI_SIMPLE_POINTER_MODE * Mode
EFI_SIMPLE_TEXT_OUTPUT_MODE * Mode
UINT64 AbsoluteMinX
The Absolute Minimum of the device on the x-axis.
UINT64 AbsoluteMinZ
The Absolute Minimum of the device on the z-axis.
UINT64 AbsoluteMinY
The Absolute Minimum of the device on the y axis.
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat
EFI_PHYSICAL_ADDRESS FrameBufferBase
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION * Info
EFI_INPUT_KEY Key
EFI_KEY_STATE KeyState
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * StdErr
Definition: UefiSpec.h:2075
EFI_HANDLE ConsoleInHandle
Definition: UefiSpec.h:2048
EFI_HANDLE ConsoleOutHandle
Definition: UefiSpec.h:2059
EFI_HANDLE StandardErrorHandle
Definition: UefiSpec.h:2070
EFI_SIMPLE_TEXT_INPUT_PROTOCOL * ConIn
Definition: UefiSpec.h:2053
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * ConOut
Definition: UefiSpec.h:2064
EFI_TABLE_HEADER Hdr
Definition: UefiSpec.h:2032
Definition: Base.h:213