]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c
1. Sync the tracker for supporting the ModeNumber larger than 2.
[mirror_edk2.git] / MdeModulePkg / Universal / Console / ConSplitterDxe / ConSplitter.c
CommitLineData
95276127 1/**@file\r
2 Console Splitter Driver. Any Handle that attatched\r
3 EFI_CONSOLE_IDENTIFIER_PROTOCOL can be bound by this driver.\r
4\r
5 So far it works like any other driver by opening a SimpleTextIn and/or\r
6 SimpleTextOut protocol with EFI_OPEN_PROTOCOL_BY_DRIVER attributes. The big\r
7 difference is this driver does not layer a protocol on the passed in\r
8 handle, or construct a child handle like a standard device or bus driver.\r
9 This driver produces three virtual handles as children, one for console input\r
10 splitter, one for console output splitter and one for error output splitter.\r
11 EFI_CONSOLE_SPLIT_PROTOCOL will be attatched onto each virtual handle to\r
12 identify the splitter type.\r
13\r
14 Each virtual handle, that supports both the EFI_CONSOLE_SPLIT_PROTOCOL\r
15 and Console I/O protocol, will be produced in the driver entry point.\r
16 The virtual handle are added on driver entry and never removed.\r
17 Such design ensures sytem function well during none console device situation.\r
18\r
19Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
20All rights reserved. This program and the accompanying materials\r
21are licensed and made available under the terms and conditions of the BSD License\r
22which accompanies this distribution. The full text of the license may be found at\r
23http://opensource.org/licenses/bsd-license.php\r
24\r
25THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
26WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
27\r
28**/\r
29\r
95276127 30#include "ConSplitter.h"\r
31\r
32//\r
33// Global Variables\r
34//\r
35STATIC TEXT_IN_SPLITTER_PRIVATE_DATA mConIn = {\r
36 TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE,\r
37 (EFI_HANDLE) NULL,\r
38 {\r
39 ConSplitterTextInReset,\r
40 ConSplitterTextInReadKeyStroke,\r
41 (EFI_EVENT) NULL\r
42 },\r
43 0,\r
44 (EFI_SIMPLE_TEXT_INPUT_PROTOCOL **) NULL,\r
45 0,\r
66aa04e4 46 {\r
47 ConSplitterTextInResetEx,\r
48 ConSplitterTextInReadKeyStrokeEx,\r
49 (EFI_EVENT) NULL,\r
50 ConSplitterTextInSetState,\r
51 ConSplitterTextInRegisterKeyNotify,\r
52 ConSplitterTextInUnregisterKeyNotify\r
53 },\r
54 0,\r
55 (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL **) NULL,\r
56 0,\r
57 {\r
58 (struct _LIST_ENTRY *) NULL,\r
59 (struct _LIST_ENTRY *) NULL\r
60 },\r
95276127 61\r
62 {\r
63 ConSplitterSimplePointerReset,\r
64 ConSplitterSimplePointerGetState,\r
65 (EFI_EVENT) NULL,\r
66 (EFI_SIMPLE_POINTER_MODE *) NULL\r
67 },\r
68 {\r
69 0x10000,\r
70 0x10000,\r
71 0x10000,\r
72 TRUE,\r
73 TRUE\r
74 },\r
75 0,\r
76 (EFI_SIMPLE_POINTER_PROTOCOL **) NULL,\r
77 0,\r
78\r
8ae0b360 79 {\r
80 ConSplitterAbsolutePointerReset,\r
81 ConSplitterAbsolutePointerGetState,\r
82 (EFI_EVENT) NULL,\r
83 (EFI_ABSOLUTE_POINTER_MODE *) NULL\r
84 },\r
85\r
86 {\r
87 0, //AbsoluteMinX\r
88 0, //AbsoluteMinY\r
89 0, //AbsoluteMinZ\r
90 0x10000, //AbsoluteMaxX\r
91 0x10000, //AbsoluteMaxY\r
92 0x10000, //AbsoluteMaxZ\r
7a5064ce 93 0 //Attributes\r
8ae0b360 94 },\r
95 0,\r
96 (EFI_ABSOLUTE_POINTER_PROTOCOL **) NULL,\r
97 0,\r
98 FALSE,\r
99\r
95276127 100 FALSE,\r
101 {\r
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
106 },\r
107 0,\r
108 {\r
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
113 },\r
114 (EFI_EVENT) NULL,\r
115\r
116 FALSE,\r
117 FALSE\r
118};\r
119\r
7a5064ce 120GLOBAL_REMOVE_IF_UNREFERENCED EFI_UGA_DRAW_PROTOCOL gUgaDrawProtocolTemplate = {\r
121 ConSpliterUgaDrawGetMode,\r
122 ConSpliterUgaDrawSetMode,\r
123 ConSpliterUgaDrawBlt\r
124};\r
125\r
126GLOBAL_REMOVE_IF_UNREFERENCED EFI_GRAPHICS_OUTPUT_PROTOCOL gGraphicsOutputProtocolTemplate = {\r
127 ConSpliterGraphicsOutputQueryMode,\r
128 ConSpliterGraphicsOutputSetMode,\r
129 ConSpliterGraphicsOutputBlt,\r
130 NULL\r
131};\r
132\r
95276127 133STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {\r
134 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,\r
135 (EFI_HANDLE) NULL,\r
136 {\r
137 ConSplitterTextOutReset,\r
138 ConSplitterTextOutOutputString,\r
139 ConSplitterTextOutTestString,\r
140 ConSplitterTextOutQueryMode,\r
141 ConSplitterTextOutSetMode,\r
142 ConSplitterTextOutSetAttribute,\r
143 ConSplitterTextOutClearScreen,\r
144 ConSplitterTextOutSetCursorPosition,\r
145 ConSplitterTextOutEnableCursor,\r
146 (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL\r
147 },\r
148 {\r
149 1,\r
150 0,\r
151 0,\r
152 0,\r
153 0,\r
154 FALSE,\r
155 },\r
d0c64728 156 {\r
7a5064ce 157 NULL,\r
158 NULL,\r
159 NULL\r
d0c64728 160 },\r
161 0,\r
162 0,\r
163 0,\r
164 0,\r
165 (EFI_UGA_PIXEL *) NULL,\r
95276127 166 {\r
7a5064ce 167 NULL,\r
168 NULL,\r
169 NULL,\r
95276127 170 NULL\r
171 },\r
172 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
aec072ad 173 (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *) NULL,\r
174 0,\r
95276127 175 0,\r
176 TRUE,\r
177 {\r
178 ConSpliterConsoleControlGetMode,\r
179 ConSpliterConsoleControlSetMode,\r
180 ConSpliterConsoleControlLockStdIn\r
181 },\r
182\r
183 0,\r
184 (TEXT_OUT_AND_GOP_DATA *) NULL,\r
185 0,\r
186 (TEXT_OUT_SPLITTER_QUERY_DATA *) NULL,\r
187 0,\r
188 (INT32 *) NULL,\r
189\r
190 EfiConsoleControlScreenText,\r
191 0,\r
192 0,\r
193 (CHAR16 *) NULL,\r
194 (INT32 *) NULL\r
195};\r
196\r
197STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr = {\r
198 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,\r
199 (EFI_HANDLE) NULL,\r
200 {\r
201 ConSplitterTextOutReset,\r
202 ConSplitterTextOutOutputString,\r
203 ConSplitterTextOutTestString,\r
204 ConSplitterTextOutQueryMode,\r
205 ConSplitterTextOutSetMode,\r
206 ConSplitterTextOutSetAttribute,\r
207 ConSplitterTextOutClearScreen,\r
208 ConSplitterTextOutSetCursorPosition,\r
209 ConSplitterTextOutEnableCursor,\r
210 (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL\r
211 },\r
212 {\r
213 1,\r
214 0,\r
215 0,\r
216 0,\r
217 0,\r
218 FALSE,\r
219 },\r
d0c64728 220 {\r
7a5064ce 221 NULL,\r
222 NULL,\r
223 NULL\r
d0c64728 224 },\r
225 0,\r
226 0,\r
227 0,\r
228 0,\r
229 (EFI_UGA_PIXEL *) NULL,\r
95276127 230 {\r
7a5064ce 231 NULL,\r
232 NULL,\r
233 NULL,\r
95276127 234 NULL\r
235 },\r
236 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
aec072ad 237 (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *) NULL,\r
238 0,\r
95276127 239 0,\r
240 TRUE,\r
241 {\r
242 ConSpliterConsoleControlGetMode,\r
243 ConSpliterConsoleControlSetMode,\r
244 ConSpliterConsoleControlLockStdIn\r
245 },\r
246\r
247 0,\r
248 (TEXT_OUT_AND_GOP_DATA *) NULL,\r
249 0,\r
250 (TEXT_OUT_SPLITTER_QUERY_DATA *) NULL,\r
251 0,\r
252 (INT32 *) NULL,\r
253\r
254 EfiConsoleControlScreenText,\r
255 0,\r
256 0,\r
257 (CHAR16 *) NULL,\r
258 (INT32 *) NULL\r
259};\r
260\r
261EFI_DRIVER_BINDING_PROTOCOL gConSplitterConInDriverBinding = {\r
262 ConSplitterConInDriverBindingSupported,\r
263 ConSplitterConInDriverBindingStart,\r
264 ConSplitterConInDriverBindingStop,\r
265 0xa,\r
266 NULL,\r
267 NULL\r
268};\r
269\r
270EFI_DRIVER_BINDING_PROTOCOL gConSplitterSimplePointerDriverBinding = {\r
271 ConSplitterSimplePointerDriverBindingSupported,\r
272 ConSplitterSimplePointerDriverBindingStart,\r
273 ConSplitterSimplePointerDriverBindingStop,\r
274 0xa,\r
275 NULL,\r
276 NULL\r
277};\r
278\r
8ae0b360 279//\r
280// Driver binding instance for Absolute Pointer protocol\r
281//\r
282EFI_DRIVER_BINDING_PROTOCOL gConSplitterAbsolutePointerDriverBinding = {\r
283 ConSplitterAbsolutePointerDriverBindingSupported,\r
284 ConSplitterAbsolutePointerDriverBindingStart,\r
285 ConSplitterAbsolutePointerDriverBindingStop,\r
286 0xa,\r
287 NULL,\r
288 NULL\r
289};\r
290\r
95276127 291EFI_DRIVER_BINDING_PROTOCOL gConSplitterConOutDriverBinding = {\r
292 ConSplitterConOutDriverBindingSupported,\r
293 ConSplitterConOutDriverBindingStart,\r
294 ConSplitterConOutDriverBindingStop,\r
295 0xa,\r
296 NULL,\r
297 NULL\r
298};\r
299\r
300EFI_DRIVER_BINDING_PROTOCOL gConSplitterStdErrDriverBinding = {\r
301 ConSplitterStdErrDriverBindingSupported,\r
302 ConSplitterStdErrDriverBindingStart,\r
303 ConSplitterStdErrDriverBindingStop,\r
304 0xa,\r
305 NULL,\r
306 NULL\r
307};\r
308\r
309/**\r
310 The user Entry Point for module ConSplitter. The user code starts with this function.\r
311\r
d0c64728 312 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
95276127 313 @param[in] SystemTable A pointer to the EFI System Table.\r
d0c64728 314\r
95276127 315 @retval EFI_SUCCESS The entry point is executed successfully.\r
316 @retval other Some error occurs when executing this entry point.\r
317\r
318**/\r
319EFI_STATUS\r
320EFIAPI\r
321InitializeConSplitter(\r
322 IN EFI_HANDLE ImageHandle,\r
323 IN EFI_SYSTEM_TABLE *SystemTable\r
324 )\r
325{\r
326 EFI_STATUS Status;\r
327\r
328 //\r
329 // Install driver model protocol(s).\r
330 //\r
5bca971e 331 Status = EfiLibInstallDriverBindingComponentName2 (\r
95276127 332 ImageHandle,\r
333 SystemTable,\r
334 &gConSplitterConInDriverBinding,\r
335 ImageHandle,\r
336 &gConSplitterConInComponentName,\r
5bca971e 337 &gConSplitterConInComponentName2\r
95276127 338 );\r
339 ASSERT_EFI_ERROR (Status);\r
340\r
5bca971e 341 Status = EfiLibInstallDriverBindingComponentName2 (\r
95276127 342 ImageHandle,\r
343 SystemTable,\r
344 &gConSplitterSimplePointerDriverBinding,\r
345 NULL,\r
346 &gConSplitterSimplePointerComponentName,\r
5bca971e 347 &gConSplitterSimplePointerComponentName2\r
95276127 348 );\r
349 ASSERT_EFI_ERROR (Status);\r
350\r
8ae0b360 351 Status = EfiLibInstallDriverBindingComponentName2 (\r
352 ImageHandle,\r
353 SystemTable,\r
354 &gConSplitterAbsolutePointerDriverBinding,\r
355 NULL,\r
356 &gConSplitterAbsolutePointerComponentName,\r
357 &gConSplitterAbsolutePointerComponentName2\r
358 );\r
359 ASSERT_EFI_ERROR (Status);\r
360\r
5bca971e 361 Status = EfiLibInstallDriverBindingComponentName2 (\r
95276127 362 ImageHandle,\r
363 SystemTable,\r
364 &gConSplitterConOutDriverBinding,\r
365 NULL,\r
366 &gConSplitterConOutComponentName,\r
5bca971e 367 &gConSplitterConOutComponentName2\r
95276127 368 );\r
369 ASSERT_EFI_ERROR (Status);\r
370\r
5bca971e 371 Status = EfiLibInstallDriverBindingComponentName2 (\r
95276127 372 ImageHandle,\r
373 SystemTable,\r
374 &gConSplitterStdErrDriverBinding,\r
375 NULL,\r
376 &gConSplitterStdErrComponentName,\r
5bca971e 377 &gConSplitterStdErrComponentName2\r
95276127 378 );\r
379 ASSERT_EFI_ERROR (Status);\r
380\r
381\r
382 //\r
383 // Call the original Entry Point\r
384 //\r
385 Status = ConSplitterDriverEntry (ImageHandle, SystemTable);\r
386\r
387 return Status;\r
388}\r
389\r
390\r
391EFI_STATUS\r
392EFIAPI\r
393ConSplitterDriverEntry (\r
394 IN EFI_HANDLE ImageHandle,\r
395 IN EFI_SYSTEM_TABLE *SystemTable\r
396 )\r
397/*++\r
398\r
399Routine Description:\r
400 Intialize a virtual console device to act as an agrigator of physical console\r
401 devices.\r
402\r
403Arguments:\r
404 ImageHandle - (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
405 SystemTable - (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
406Returns:\r
407 EFI_SUCCESS\r
408\r
409--*/\r
410{\r
411 EFI_STATUS Status;\r
412\r
d0c64728 413 ASSERT (FeaturePcdGet (PcdConOutGopSupport) ||\r
414 FeaturePcdGet (PcdConOutUgaSupport));\r
95276127 415 //\r
416 // The driver creates virtual handles for ConIn, ConOut, and StdErr.\r
417 // The virtual handles will always exist even if no console exist in the\r
418 // system. This is need to support hotplug devices like USB.\r
419 //\r
420 //\r
421 // Create virtual device handle for StdErr Splitter\r
422 //\r
423 Status = ConSplitterTextOutConstructor (&mStdErr);\r
424 if (!EFI_ERROR (Status)) {\r
425 Status = gBS->InstallMultipleProtocolInterfaces (\r
426 &mStdErr.VirtualHandle,\r
427 &gEfiSimpleTextOutProtocolGuid,\r
428 &mStdErr.TextOut,\r
429 &gEfiPrimaryStandardErrorDeviceGuid,\r
430 NULL,\r
431 NULL\r
432 );\r
433 }\r
434 //\r
435 // Create virtual device handle for ConIn Splitter\r
436 //\r
437 Status = ConSplitterTextInConstructor (&mConIn);\r
438 if (!EFI_ERROR (Status)) {\r
439 Status = gBS->InstallMultipleProtocolInterfaces (\r
440 &mConIn.VirtualHandle,\r
441 &gEfiSimpleTextInProtocolGuid,\r
442 &mConIn.TextIn,\r
66aa04e4 443 &gEfiSimpleTextInputExProtocolGuid,\r
444 &mConIn.TextInEx,\r
95276127 445 &gEfiSimplePointerProtocolGuid,\r
446 &mConIn.SimplePointer,\r
b819abbb 447 &gEfiAbsolutePointerProtocolGuid,\r
448 &mConIn.AbsolutePointer,\r
95276127 449 &gEfiPrimaryConsoleInDeviceGuid,\r
450 NULL,\r
451 NULL\r
452 );\r
453 if (!EFI_ERROR (Status)) {\r
454 //\r
455 // Update the EFI System Table with new virtual console\r
456 //\r
457 gST->ConsoleInHandle = mConIn.VirtualHandle;\r
458 gST->ConIn = &mConIn.TextIn;\r
459 }\r
460 }\r
461 //\r
462 // Create virtual device handle for ConOut Splitter\r
463 //\r
464 Status = ConSplitterTextOutConstructor (&mConOut);\r
465 if (!EFI_ERROR (Status)) {\r
d0c64728 466 if (!FeaturePcdGet (PcdConOutGopSupport)) {\r
467 //\r
468 // In EFI mode, UGA Draw protocol is installed\r
469 //\r
470 Status = gBS->InstallMultipleProtocolInterfaces (\r
471 &mConOut.VirtualHandle,\r
472 &gEfiSimpleTextOutProtocolGuid,\r
473 &mConOut.TextOut,\r
474 &gEfiUgaDrawProtocolGuid,\r
475 &mConOut.UgaDraw,\r
476 &gEfiConsoleControlProtocolGuid,\r
477 &mConOut.ConsoleControl,\r
478 &gEfiPrimaryConsoleOutDeviceGuid,\r
479 NULL,\r
480 NULL\r
481 );\r
482 } else if (!FeaturePcdGet (PcdConOutUgaSupport)) {\r
483 //\r
484 // In UEFI mode, Graphics Output Protocol is installed on virtual handle.\r
485 //\r
486 Status = gBS->InstallMultipleProtocolInterfaces (\r
487 &mConOut.VirtualHandle,\r
488 &gEfiSimpleTextOutProtocolGuid,\r
489 &mConOut.TextOut,\r
490 &gEfiGraphicsOutputProtocolGuid,\r
491 &mConOut.GraphicsOutput,\r
492 &gEfiConsoleControlProtocolGuid,\r
493 &mConOut.ConsoleControl,\r
494 &gEfiPrimaryConsoleOutDeviceGuid,\r
495 NULL,\r
496 NULL\r
497 );\r
498 } else {\r
499 //\r
500 // In EFI and UEFI comptible mode, Graphics Output Protocol and UGA are\r
501 // installed on virtual handle.\r
502 //\r
503 Status = gBS->InstallMultipleProtocolInterfaces (\r
504 &mConOut.VirtualHandle,\r
505 &gEfiSimpleTextOutProtocolGuid,\r
506 &mConOut.TextOut,\r
507 &gEfiGraphicsOutputProtocolGuid,\r
508 &mConOut.GraphicsOutput,\r
509 &gEfiUgaDrawProtocolGuid,\r
510 &mConOut.UgaDraw,\r
511 &gEfiConsoleControlProtocolGuid,\r
512 &mConOut.ConsoleControl,\r
513 &gEfiPrimaryConsoleOutDeviceGuid,\r
514 NULL,\r
515 NULL\r
516 );\r
517 }\r
95276127 518\r
519 if (!EFI_ERROR (Status)) {\r
520 //\r
521 // Update the EFI System Table with new virtual console\r
522 //\r
523 gST->ConsoleOutHandle = mConOut.VirtualHandle;\r
524 gST->ConOut = &mConOut.TextOut;\r
525 }\r
526\r
527 }\r
528 //\r
529 // Update the CRC32 in the EFI System Table header\r
530 //\r
531 gST->Hdr.CRC32 = 0;\r
532 gBS->CalculateCrc32 (\r
533 (UINT8 *) &gST->Hdr,\r
534 gST->Hdr.HeaderSize,\r
535 &gST->Hdr.CRC32\r
536 );\r
537\r
538 return EFI_SUCCESS;\r
539}\r
540\r
541EFI_STATUS\r
542ConSplitterTextInConstructor (\r
543 TEXT_IN_SPLITTER_PRIVATE_DATA *ConInPrivate\r
544 )\r
545/*++\r
546\r
547Routine Description:\r
548\r
549 Construct the ConSplitter.\r
550\r
551Arguments:\r
552\r
553 ConInPrivate - A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA structure.\r
554\r
555Returns:\r
556 EFI_OUT_OF_RESOURCES - Out of resources.\r
557\r
558--*/\r
559{\r
560 EFI_STATUS Status;\r
561\r
562 //\r
563 // Initilize console input splitter's private data.\r
564 //\r
565 Status = ConSplitterGrowBuffer (\r
566 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *),\r
567 &ConInPrivate->TextInListCount,\r
568 (VOID **) &ConInPrivate->TextInList\r
569 );\r
570 if (EFI_ERROR (Status)) {\r
571 return EFI_OUT_OF_RESOURCES;\r
572 }\r
573 //\r
574 // Create Event to support locking StdIn Device\r
575 //\r
576 Status = gBS->CreateEvent (\r
577 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
578 TPL_CALLBACK,\r
579 ConSpliterConsoleControlLockStdInEvent,\r
580 NULL,\r
581 &ConInPrivate->LockEvent\r
582 );\r
583 ASSERT_EFI_ERROR (Status);\r
584\r
585 Status = gBS->CreateEvent (\r
586 EVT_NOTIFY_WAIT,\r
587 TPL_NOTIFY,\r
588 ConSplitterTextInWaitForKey,\r
589 ConInPrivate,\r
590 &ConInPrivate->TextIn.WaitForKey\r
591 );\r
592 ASSERT_EFI_ERROR (Status);\r
593\r
66aa04e4 594 //\r
595 // Buffer for Simple Text Input Ex Protocol\r
7a5064ce 596 //\r
66aa04e4 597 Status = ConSplitterGrowBuffer (\r
598 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *),\r
599 &ConInPrivate->TextInExListCount,\r
600 (VOID **) &ConInPrivate->TextInExList\r
601 );\r
602 if (EFI_ERROR (Status)) {\r
603 return EFI_OUT_OF_RESOURCES;\r
604 }\r
605\r
606 Status = gBS->CreateEvent (\r
607 EVT_NOTIFY_WAIT,\r
608 TPL_NOTIFY,\r
609 ConSplitterTextInWaitForKey,\r
610 ConInPrivate,\r
611 &ConInPrivate->TextInEx.WaitForKeyEx\r
612 );\r
613 ASSERT_EFI_ERROR (Status);\r
614\r
7a5064ce 615 InitializeListHead (&ConInPrivate->NotifyList);\r
66aa04e4 616\r
8ae0b360 617 //\r
618 // Allocate Buffer and Create Event for Absolute Pointer and Simple Pointer Protocols\r
619 //\r
620 ConInPrivate->AbsolutePointer.Mode = &ConInPrivate->AbsolutePointerMode;\r
621\r
622 Status = ConSplitterGrowBuffer (\r
b819abbb 623 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL *),\r
624 &ConInPrivate->AbsolutePointerListCount,\r
625 (VOID **) &ConInPrivate->AbsolutePointerList\r
626 );\r
8ae0b360 627 if (EFI_ERROR (Status)) {\r
b819abbb 628 return EFI_OUT_OF_RESOURCES;\r
8ae0b360 629 }\r
630\r
631 Status = gBS->CreateEvent (\r
b819abbb 632 EVT_NOTIFY_WAIT,\r
633 TPL_NOTIFY,\r
634 ConSplitterAbsolutePointerWaitForInput,\r
635 ConInPrivate,\r
636 &ConInPrivate->AbsolutePointer.WaitForInput\r
637 );\r
8ae0b360 638 ASSERT_EFI_ERROR (Status);\r
66aa04e4 639\r
95276127 640 ConInPrivate->SimplePointer.Mode = &ConInPrivate->SimplePointerMode;\r
641\r
642 Status = ConSplitterGrowBuffer (\r
643 sizeof (EFI_SIMPLE_POINTER_PROTOCOL *),\r
644 &ConInPrivate->PointerListCount,\r
645 (VOID **) &ConInPrivate->PointerList\r
646 );\r
647 if (EFI_ERROR (Status)) {\r
648 return EFI_OUT_OF_RESOURCES;\r
649 }\r
650\r
651 Status = gBS->CreateEvent (\r
652 EVT_NOTIFY_WAIT,\r
653 TPL_NOTIFY,\r
654 ConSplitterSimplePointerWaitForInput,\r
655 ConInPrivate,\r
656 &ConInPrivate->SimplePointer.WaitForInput\r
657 );\r
658\r
659 return Status;\r
660}\r
661\r
662EFI_STATUS\r
663ConSplitterTextOutConstructor (\r
664 TEXT_OUT_SPLITTER_PRIVATE_DATA *ConOutPrivate\r
665 )\r
666{\r
667 EFI_STATUS Status;\r
aec072ad 668 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
95276127 669\r
7a5064ce 670 //\r
671 // Copy protocols template\r
672 //\r
673 if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
674 CopyMem (&ConOutPrivate->UgaDraw, &gUgaDrawProtocolTemplate, sizeof (EFI_UGA_DRAW_PROTOCOL));\r
675 }\r
676\r
677 if (FeaturePcdGet (PcdConOutGopSupport)) {\r
678 CopyMem (&ConOutPrivate->GraphicsOutput, &gGraphicsOutputProtocolTemplate, sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL));\r
679 }\r
680\r
95276127 681 //\r
682 // Initilize console output splitter's private data.\r
683 //\r
684 ConOutPrivate->TextOut.Mode = &ConOutPrivate->TextOutMode;\r
685\r
686 Status = ConSplitterGrowBuffer (\r
687 sizeof (TEXT_OUT_AND_GOP_DATA),\r
688 &ConOutPrivate->TextOutListCount,\r
689 (VOID **) &ConOutPrivate->TextOutList\r
690 );\r
691 if (EFI_ERROR (Status)) {\r
692 return EFI_OUT_OF_RESOURCES;\r
693 }\r
694\r
695 Status = ConSplitterGrowBuffer (\r
696 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA),\r
697 &ConOutPrivate->TextOutQueryDataCount,\r
698 (VOID **) &ConOutPrivate->TextOutQueryData\r
699 );\r
700 if (EFI_ERROR (Status)) {\r
701 return EFI_OUT_OF_RESOURCES;\r
702 }\r
703 //\r
704 // Setup the DevNullTextOut console to 80 x 25\r
705 //\r
706 ConOutPrivate->TextOutQueryData[0].Columns = 80;\r
707 ConOutPrivate->TextOutQueryData[0].Rows = 25;\r
708 DevNullTextOutSetMode (ConOutPrivate, 0);\r
709\r
d0c64728 710 if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
711 //\r
712 // Setup the DevNullUgaDraw to 800 x 600 x 32 bits per pixel\r
713 //\r
714 ConSpliterUgaDrawSetMode (&ConOutPrivate->UgaDraw, 800, 600, 32, 60);\r
95276127 715 }\r
d0c64728 716 if (FeaturePcdGet (PcdConOutGopSupport)) {\r
717 //\r
718 // Setup resource for mode information in Graphics Output Protocol interface\r
719 //\r
720 if ((ConOutPrivate->GraphicsOutput.Mode = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE))) == NULL) {\r
721 return EFI_OUT_OF_RESOURCES;\r
722 }\r
723 if ((ConOutPrivate->GraphicsOutput.Mode->Info = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION))) == NULL) {\r
724 return EFI_OUT_OF_RESOURCES;\r
725 }\r
726 //\r
727 // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel\r
aec072ad 728 // DevNull will be updated to user-defined mode after driver has started.\r
d0c64728 729 //\r
aec072ad 730 if ((ConOutPrivate->GraphicsOutputModeBuffer = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION))) == NULL) {\r
d0c64728 731 return EFI_OUT_OF_RESOURCES;\r
732 }\r
aec072ad 733 Info = &ConOutPrivate->GraphicsOutputModeBuffer[0];\r
734 Info->Version = 0;\r
735 Info->HorizontalResolution = 800;\r
736 Info->VerticalResolution = 600;\r
737 Info->PixelFormat = PixelBltOnly;\r
738 Info->PixelsPerScanLine = 800;\r
739 CopyMem (ConOutPrivate->GraphicsOutput.Mode->Info, Info, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
740 ConOutPrivate->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
95276127 741\r
d0c64728 742 //\r
743 // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()\r
aec072ad 744 // GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize\r
d0c64728 745 //\r
d0c64728 746 ConOutPrivate->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;\r
747 ConOutPrivate->GraphicsOutput.Mode->FrameBufferSize = 0;\r
95276127 748\r
d0c64728 749 ConOutPrivate->GraphicsOutput.Mode->MaxMode = 1;\r
750 //\r
751 // Initial current mode to unknow state, and then set to mode 0\r
752 //\r
753 ConOutPrivate->GraphicsOutput.Mode->Mode = 0xffff;\r
754 ConOutPrivate->GraphicsOutput.SetMode (&ConOutPrivate->GraphicsOutput, 0);\r
755 }\r
95276127 756\r
757 return Status;\r
758}\r
759\r
760STATIC\r
761EFI_STATUS\r
762ConSplitterSupported (\r
763 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
764 IN EFI_HANDLE ControllerHandle,\r
765 IN EFI_GUID *Guid\r
766 )\r
767/*++\r
768\r
769Routine Description:\r
770 Generic Supported Check\r
771\r
772Arguments:\r
773 This - Pointer to protocol.\r
774 ControllerHandle - Controller Handle.\r
775 Guid - Guid.\r
776\r
777Returns:\r
778\r
779 EFI_UNSUPPORTED - unsupported.\r
780 EFI_SUCCESS - operation is OK.\r
781\r
782--*/\r
783{\r
784 EFI_STATUS Status;\r
785 VOID *Instance;\r
786\r
787 //\r
788 // Make sure the Console Splitter does not attempt to attach to itself\r
789 //\r
790 if (ControllerHandle == mConIn.VirtualHandle) {\r
791 return EFI_UNSUPPORTED;\r
792 }\r
793\r
794 if (ControllerHandle == mConOut.VirtualHandle) {\r
795 return EFI_UNSUPPORTED;\r
796 }\r
797\r
798 if (ControllerHandle == mStdErr.VirtualHandle) {\r
799 return EFI_UNSUPPORTED;\r
800 }\r
801 //\r
802 // Check to see whether the handle has the ConsoleInDevice GUID on it\r
803 //\r
804 Status = gBS->OpenProtocol (\r
805 ControllerHandle,\r
806 Guid,\r
807 &Instance,\r
808 This->DriverBindingHandle,\r
809 ControllerHandle,\r
810 EFI_OPEN_PROTOCOL_BY_DRIVER\r
811 );\r
812\r
813 if (EFI_ERROR (Status)) {\r
814 return Status;\r
815 }\r
816\r
817 gBS->CloseProtocol (\r
818 ControllerHandle,\r
819 Guid,\r
820 This->DriverBindingHandle,\r
821 ControllerHandle\r
822 );\r
823\r
824 return EFI_SUCCESS;\r
825}\r
826\r
827EFI_STATUS\r
828EFIAPI\r
829ConSplitterConInDriverBindingSupported (\r
830 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
831 IN EFI_HANDLE ControllerHandle,\r
832 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
833 )\r
834/*++\r
835\r
836Routine Description:\r
837 Console In Supported Check\r
838\r
839Arguments:\r
840 This - Pointer to protocol.\r
841 ControllerHandle - Controller handle.\r
842 RemainingDevicePath - Remaining device path.\r
843\r
844Returns:\r
845\r
846 EFI_STATUS\r
847\r
848--*/\r
849{\r
850 return ConSplitterSupported (\r
851 This,\r
852 ControllerHandle,\r
853 &gEfiConsoleInDeviceGuid\r
854 );\r
855}\r
856\r
857EFI_STATUS\r
858EFIAPI\r
859ConSplitterSimplePointerDriverBindingSupported (\r
860 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
861 IN EFI_HANDLE ControllerHandle,\r
862 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
863 )\r
864/*++\r
865\r
866Routine Description:\r
867 Standard Error Supported Check\r
868\r
869Arguments:\r
870 This - Pointer to protocol.\r
871 ControllerHandle - Controller handle.\r
872 RemainingDevicePath - Remaining device path.\r
873\r
874Returns:\r
875\r
876 EFI_STATUS\r
877\r
878--*/\r
879{\r
880 return ConSplitterSupported (\r
881 This,\r
882 ControllerHandle,\r
883 &gEfiSimplePointerProtocolGuid\r
884 );\r
885}\r
886\r
8ae0b360 887EFI_STATUS\r
888EFIAPI\r
889ConSplitterAbsolutePointerDriverBindingSupported (\r
890 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
891 IN EFI_HANDLE ControllerHandle,\r
892 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
893 )\r
894/*++\r
895\r
896Routine Description:\r
897 Absolute Pointer Supported Check\r
898\r
899Arguments:\r
900 This - Pointer to protocol.\r
901 ControllerHandle - Controller handle.\r
902 RemainingDevicePath - Remaining device path.\r
903\r
904Returns:\r
905\r
906 EFI_STATUS\r
907\r
908--*/\r
909{\r
910 return ConSplitterSupported (\r
911 This,\r
912 ControllerHandle,\r
913 &gEfiAbsolutePointerProtocolGuid\r
914 );\r
915}\r
916\r
95276127 917EFI_STATUS\r
918EFIAPI\r
919ConSplitterConOutDriverBindingSupported (\r
920 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
921 IN EFI_HANDLE ControllerHandle,\r
922 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
923 )\r
924/*++\r
925\r
926Routine Description:\r
927 Console Out Supported Check\r
928\r
929Arguments:\r
930 This - Pointer to protocol.\r
931 ControllerHandle - Controller handle.\r
932 RemainingDevicePath - Remaining device path.\r
933\r
934Returns:\r
935\r
936 EFI_STATUS\r
937\r
938--*/\r
939{\r
940 return ConSplitterSupported (\r
941 This,\r
942 ControllerHandle,\r
943 &gEfiConsoleOutDeviceGuid\r
944 );\r
945}\r
946\r
947EFI_STATUS\r
948EFIAPI\r
949ConSplitterStdErrDriverBindingSupported (\r
950 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
951 IN EFI_HANDLE ControllerHandle,\r
952 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
953 )\r
954/*++\r
955\r
956Routine Description:\r
957 Standard Error Supported Check\r
958\r
959Arguments:\r
960 This - Pointer to protocol.\r
961 ControllerHandle - Controller handle.\r
962 RemainingDevicePath - Remaining device path.\r
963\r
964Returns:\r
965\r
966 EFI_STATUS\r
967\r
968--*/\r
969{\r
970 return ConSplitterSupported (\r
971 This,\r
972 ControllerHandle,\r
973 &gEfiStandardErrorDeviceGuid\r
974 );\r
975}\r
976\r
977STATIC\r
978EFI_STATUS\r
979EFIAPI\r
980ConSplitterStart (\r
981 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
982 IN EFI_HANDLE ControllerHandle,\r
983 IN EFI_HANDLE ConSplitterVirtualHandle,\r
984 IN EFI_GUID *DeviceGuid,\r
985 IN EFI_GUID *InterfaceGuid,\r
986 IN VOID **Interface\r
987 )\r
988/*++\r
989\r
990Routine Description:\r
991 Start ConSplitter on ControllerHandle, and create the virtual\r
992 agrogated console device on first call Start for a SimpleTextIn handle.\r
993\r
994Arguments:\r
995 (Standard DriverBinding Protocol Start() function)\r
996\r
997Returns:\r
998 EFI_ERROR if a SimpleTextIn protocol is not started.\r
999\r
1000--*/\r
1001{\r
1002 EFI_STATUS Status;\r
1003 VOID *Instance;\r
1004\r
1005 //\r
1006 // Check to see whether the handle has the ConsoleInDevice GUID on it\r
1007 //\r
1008 Status = gBS->OpenProtocol (\r
1009 ControllerHandle,\r
1010 DeviceGuid,\r
1011 &Instance,\r
1012 This->DriverBindingHandle,\r
1013 ControllerHandle,\r
1014 EFI_OPEN_PROTOCOL_BY_DRIVER\r
1015 );\r
1016 if (EFI_ERROR (Status)) {\r
1017 return Status;\r
1018 }\r
1019\r
1020 Status = gBS->OpenProtocol (\r
1021 ControllerHandle,\r
1022 DeviceGuid,\r
1023 &Instance,\r
1024 This->DriverBindingHandle,\r
1025 ConSplitterVirtualHandle,\r
1026 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
1027 );\r
1028 if (EFI_ERROR (Status)) {\r
1029 return Status;\r
1030 }\r
1031\r
1032 return gBS->OpenProtocol (\r
1033 ControllerHandle,\r
1034 InterfaceGuid,\r
1035 Interface,\r
1036 This->DriverBindingHandle,\r
1037 ConSplitterVirtualHandle,\r
1038 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1039 );\r
1040}\r
1041\r
1042EFI_STATUS\r
1043EFIAPI\r
1044ConSplitterConInDriverBindingStart (\r
1045 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1046 IN EFI_HANDLE ControllerHandle,\r
1047 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
1048 )\r
1049/*++\r
1050\r
1051Routine Description:\r
1052 Start ConSplitter on ControllerHandle, and create the virtual\r
1053 agrogated console device on first call Start for a SimpleTextIn handle.\r
1054\r
1055Arguments:\r
1056 This - Pointer to protocol.\r
1057 ControllerHandle - Controller handle.\r
1058 RemainingDevicePath - Remaining device path.\r
1059\r
1060Returns:\r
1061\r
1062 EFI_STATUS\r
1063 EFI_ERROR if a SimpleTextIn protocol is not started.\r
1064\r
1065--*/\r
1066{\r
1067 EFI_STATUS Status;\r
1068 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;\r
66aa04e4 1069 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx;\r
95276127 1070\r
1071 //\r
1072 // Start ConSplitter on ControllerHandle, and create the virtual\r
1073 // agrogated console device on first call Start for a SimpleTextIn handle.\r
1074 //\r
1075 Status = ConSplitterStart (\r
1076 This,\r
1077 ControllerHandle,\r
1078 mConIn.VirtualHandle,\r
1079 &gEfiConsoleInDeviceGuid,\r
1080 &gEfiSimpleTextInProtocolGuid,\r
1081 (VOID **) &TextIn\r
1082 );\r
1083 if (EFI_ERROR (Status)) {\r
1084 return Status;\r
1085 }\r
1086\r
0cadafc8 1087 Status = ConSplitterTextInAddDevice (&mConIn, TextIn);\r
1088 if (EFI_ERROR (Status)) {\r
1089 return Status;\r
1090 }\r
1091\r
66aa04e4 1092 Status = gBS->OpenProtocol (\r
1093 ControllerHandle,\r
1094 &gEfiSimpleTextInputExProtocolGuid,\r
1095 (VOID **) &TextInEx,\r
1096 This->DriverBindingHandle,\r
1097 mConIn.VirtualHandle,\r
1098 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1099 );\r
1100 if (EFI_ERROR (Status)) {\r
1101 return Status;\r
1102 }\r
1103\r
1104 Status = ConSplitterTextInExAddDevice (&mConIn, TextInEx);\r
7a5064ce 1105\r
0cadafc8 1106 return Status;\r
95276127 1107}\r
1108\r
1109EFI_STATUS\r
1110EFIAPI\r
1111ConSplitterSimplePointerDriverBindingStart (\r
1112 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1113 IN EFI_HANDLE ControllerHandle,\r
1114 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
1115 )\r
1116/*++\r
1117\r
1118Routine Description:\r
1119 Start ConSplitter on ControllerHandle, and create the virtual\r
1120 agrogated console device on first call Start for a SimpleTextIn handle.\r
1121\r
1122Arguments:\r
1123 This - Pointer to protocol.\r
1124 ControllerHandle - Controller handle.\r
1125 RemainingDevicePath - Remaining device path.\r
1126\r
1127Returns:\r
1128\r
1129 EFI_ERROR if a SimpleTextIn protocol is not started.\r
1130\r
1131--*/\r
1132{\r
1133 EFI_STATUS Status;\r
1134 EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;\r
1135\r
1136 Status = ConSplitterStart (\r
1137 This,\r
1138 ControllerHandle,\r
1139 mConIn.VirtualHandle,\r
1140 &gEfiSimplePointerProtocolGuid,\r
1141 &gEfiSimplePointerProtocolGuid,\r
1142 (VOID **) &SimplePointer\r
1143 );\r
1144 if (EFI_ERROR (Status)) {\r
1145 return Status;\r
1146 }\r
1147\r
1148 return ConSplitterSimplePointerAddDevice (&mConIn, SimplePointer);\r
1149}\r
1150\r
8ae0b360 1151EFI_STATUS\r
1152EFIAPI\r
1153ConSplitterAbsolutePointerDriverBindingStart (\r
1154 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1155 IN EFI_HANDLE ControllerHandle,\r
1156 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
1157 )\r
1158/*++\r
1159\r
1160Routine Description:\r
1161 Start ConSplitter on ControllerHandle, and create the virtual\r
1162 agrogated console device on first call Start for a ConIn handle.\r
1163\r
1164Arguments:\r
1165 This - Pointer to protocol.\r
1166 ControllerHandle - Controller handle.\r
1167 RemainingDevicePath - Remaining device path.\r
1168\r
1169Returns:\r
1170\r
1171 EFI_ERROR if a AbsolutePointer protocol is not started.\r
1172\r
1173--*/\r
1174{\r
1175 EFI_STATUS Status;\r
1176 EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer;\r
1177\r
1178 Status = ConSplitterStart (\r
1179 This,\r
1180 ControllerHandle,\r
1181 mConIn.VirtualHandle,\r
1182 &gEfiAbsolutePointerProtocolGuid,\r
1183 &gEfiAbsolutePointerProtocolGuid,\r
1184 (VOID **) &AbsolutePointer\r
1185 );\r
7a5064ce 1186\r
8ae0b360 1187 if (EFI_ERROR (Status)) {\r
1188 return Status;\r
1189 }\r
1190\r
1191 return ConSplitterAbsolutePointerAddDevice (&mConIn, AbsolutePointer);\r
1192}\r
1193\r
95276127 1194EFI_STATUS\r
1195EFIAPI\r
1196ConSplitterConOutDriverBindingStart (\r
1197 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1198 IN EFI_HANDLE ControllerHandle,\r
1199 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
1200 )\r
1201/*++\r
1202\r
1203Routine Description:\r
1204 Start ConSplitter on ControllerHandle, and create the virtual\r
1205 agrogated console device on first call Start for a SimpleTextIn handle.\r
1206\r
1207Arguments:\r
1208 This - Pointer to protocol.\r
1209 ControllerHandle - Controller handle.\r
1210 RemainingDevicePath - Remaining device path.\r
1211\r
1212Returns:\r
1213 EFI_ERROR if a SimpleTextIn protocol is not started.\r
1214\r
1215--*/\r
1216{\r
1217 EFI_STATUS Status;\r
1218 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;\r
1219 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1220 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1221\r
1222 Status = ConSplitterStart (\r
1223 This,\r
1224 ControllerHandle,\r
1225 mConOut.VirtualHandle,\r
1226 &gEfiConsoleOutDeviceGuid,\r
1227 &gEfiSimpleTextOutProtocolGuid,\r
1228 (VOID **) &TextOut\r
1229 );\r
1230 if (EFI_ERROR (Status)) {\r
1231 return Status;\r
1232 }\r
1233 //\r
1234 // Try to Open Graphics Output protocol\r
1235 //\r
1236 Status = gBS->OpenProtocol (\r
1237 ControllerHandle,\r
1238 &gEfiGraphicsOutputProtocolGuid,\r
1239 (VOID **) &GraphicsOutput,\r
1240 This->DriverBindingHandle,\r
1241 mConOut.VirtualHandle,\r
1242 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1243 );\r
1244 if (EFI_ERROR (Status)) {\r
1245 GraphicsOutput = NULL;\r
1246 }\r
1247 //\r
1248 // Open UGA_DRAW protocol\r
1249 //\r
1250 Status = gBS->OpenProtocol (\r
1251 ControllerHandle,\r
1252 &gEfiUgaDrawProtocolGuid,\r
1253 (VOID **) &UgaDraw,\r
1254 This->DriverBindingHandle,\r
1255 mConOut.VirtualHandle,\r
1256 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1257 );\r
1258 if (EFI_ERROR (Status)) {\r
1259 UgaDraw = NULL;\r
1260 }\r
1261 //\r
1262 // If both ConOut and StdErr incorporate the same Text Out device,\r
1263 // their MaxMode and QueryData should be the intersection of both.\r
1264 //\r
1265 Status = ConSplitterTextOutAddDevice (&mConOut, TextOut, GraphicsOutput, UgaDraw);\r
1266 ConSplitterTextOutSetAttribute (&mConOut.TextOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
1267\r
d0c64728 1268 if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
1269 //\r
1270 // Match the UGA mode data of ConOut with the current mode\r
1271 //\r
1272 if (UgaDraw != NULL) {\r
1273 UgaDraw->GetMode (\r
1274 UgaDraw,\r
1275 &mConOut.UgaHorizontalResolution,\r
1276 &mConOut.UgaVerticalResolution,\r
1277 &mConOut.UgaColorDepth,\r
1278 &mConOut.UgaRefreshRate\r
1279 );\r
1280 }\r
1281 }\r
95276127 1282 return Status;\r
1283}\r
1284\r
1285EFI_STATUS\r
1286EFIAPI\r
1287ConSplitterStdErrDriverBindingStart (\r
1288 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1289 IN EFI_HANDLE ControllerHandle,\r
1290 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
1291 )\r
1292/*++\r
1293\r
1294Routine Description:\r
1295 Start ConSplitter on ControllerHandle, and create the virtual\r
1296 agrogated console device on first call Start for a SimpleTextIn handle.\r
1297\r
1298Arguments:\r
1299 This - Pointer to protocol.\r
1300 ControllerHandle - Controller handle.\r
1301 RemainingDevicePath - Remaining device path.\r
1302\r
1303Returns:\r
1304 EFI_ERROR if a SimpleTextIn protocol is not started.\r
1305\r
1306--*/\r
1307{\r
1308 EFI_STATUS Status;\r
1309 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;\r
1310\r
1311 Status = ConSplitterStart (\r
1312 This,\r
1313 ControllerHandle,\r
1314 mStdErr.VirtualHandle,\r
1315 &gEfiStandardErrorDeviceGuid,\r
1316 &gEfiSimpleTextOutProtocolGuid,\r
1317 (VOID **) &TextOut\r
1318 );\r
1319 if (EFI_ERROR (Status)) {\r
1320 return Status;\r
1321 }\r
1322 //\r
1323 // If both ConOut and StdErr incorporate the same Text Out device,\r
1324 // their MaxMode and QueryData should be the intersection of both.\r
1325 //\r
1326 Status = ConSplitterTextOutAddDevice (&mStdErr, TextOut, NULL, NULL);\r
1327 ConSplitterTextOutSetAttribute (&mStdErr.TextOut, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK));\r
1328 if (EFI_ERROR (Status)) {\r
1329 return Status;\r
1330 }\r
1331\r
1332 if (mStdErr.CurrentNumberOfConsoles == 1) {\r
1333 gST->StandardErrorHandle = mStdErr.VirtualHandle;\r
1334 gST->StdErr = &mStdErr.TextOut;\r
1335 //\r
1336 // Update the CRC32 in the EFI System Table header\r
1337 //\r
1338 gST->Hdr.CRC32 = 0;\r
1339 gBS->CalculateCrc32 (\r
1340 (UINT8 *) &gST->Hdr,\r
1341 gST->Hdr.HeaderSize,\r
1342 &gST->Hdr.CRC32\r
1343 );\r
1344 }\r
1345\r
1346 return Status;\r
1347}\r
1348\r
1349STATIC\r
1350EFI_STATUS\r
1351EFIAPI\r
1352ConSplitterStop (\r
1353 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1354 IN EFI_HANDLE ControllerHandle,\r
1355 IN EFI_HANDLE ConSplitterVirtualHandle,\r
1356 IN EFI_GUID *DeviceGuid,\r
1357 IN EFI_GUID *InterfaceGuid,\r
1358 IN VOID **Interface\r
1359 )\r
1360/*++\r
1361\r
1362Routine Description:\r
1363\r
1364Arguments:\r
1365 (Standard DriverBinding Protocol Stop() function)\r
1366\r
1367Returns:\r
1368\r
1369 None\r
1370\r
1371--*/\r
1372{\r
1373 EFI_STATUS Status;\r
1374\r
1375 Status = gBS->OpenProtocol (\r
1376 ControllerHandle,\r
1377 InterfaceGuid,\r
1378 Interface,\r
1379 This->DriverBindingHandle,\r
1380 ControllerHandle,\r
1381 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1382 );\r
1383 if (EFI_ERROR (Status)) {\r
1384 return Status;\r
1385 }\r
1386 //\r
1387 // close the protocol refered.\r
1388 //\r
1389 gBS->CloseProtocol (\r
1390 ControllerHandle,\r
1391 DeviceGuid,\r
1392 This->DriverBindingHandle,\r
1393 ConSplitterVirtualHandle\r
1394 );\r
1395 gBS->CloseProtocol (\r
1396 ControllerHandle,\r
1397 DeviceGuid,\r
1398 This->DriverBindingHandle,\r
1399 ControllerHandle\r
1400 );\r
1401\r
1402 return EFI_SUCCESS;\r
1403}\r
1404\r
1405EFI_STATUS\r
1406EFIAPI\r
1407ConSplitterConInDriverBindingStop (\r
1408 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1409 IN EFI_HANDLE ControllerHandle,\r
1410 IN UINTN NumberOfChildren,\r
1411 IN EFI_HANDLE *ChildHandleBuffer\r
1412 )\r
1413/*++\r
1414\r
1415Routine Description:\r
1416\r
1417Arguments:\r
1418 (Standard DriverBinding Protocol Stop() function)\r
1419\r
1420Returns:\r
1421\r
1422 None\r
1423\r
1424--*/\r
1425{\r
1426 EFI_STATUS Status;\r
1427 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;\r
1428\r
66aa04e4 1429 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx;\r
95276127 1430 if (NumberOfChildren == 0) {\r
1431 return EFI_SUCCESS;\r
1432 }\r
1433\r
66aa04e4 1434 Status = gBS->OpenProtocol (\r
1435 ControllerHandle,\r
1436 &gEfiSimpleTextInputExProtocolGuid,\r
1437 (VOID **) &TextInEx,\r
1438 This->DriverBindingHandle,\r
1439 ControllerHandle,\r
1440 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1441 );\r
1442 if (EFI_ERROR (Status)) {\r
1443 return Status;\r
1444 }\r
1445\r
1446 Status = ConSplitterTextInExDeleteDevice (&mConIn, TextInEx);\r
1447 if (EFI_ERROR (Status)) {\r
1448 return Status;\r
1449 }\r
7a5064ce 1450\r
1451\r
95276127 1452 Status = ConSplitterStop (\r
1453 This,\r
1454 ControllerHandle,\r
1455 mConIn.VirtualHandle,\r
1456 &gEfiConsoleInDeviceGuid,\r
1457 &gEfiSimpleTextInProtocolGuid,\r
1458 (VOID **) &TextIn\r
1459 );\r
1460 if (EFI_ERROR (Status)) {\r
1461 return Status;\r
1462 }\r
1463 //\r
1464 // Delete this console input device's data structures.\r
1465 //\r
1466 return ConSplitterTextInDeleteDevice (&mConIn, TextIn);\r
1467}\r
1468\r
1469EFI_STATUS\r
1470EFIAPI\r
1471ConSplitterSimplePointerDriverBindingStop (\r
1472 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1473 IN EFI_HANDLE ControllerHandle,\r
1474 IN UINTN NumberOfChildren,\r
1475 IN EFI_HANDLE *ChildHandleBuffer\r
1476 )\r
1477/*++\r
1478\r
1479Routine Description:\r
1480\r
1481Arguments:\r
1482 (Standard DriverBinding Protocol Stop() function)\r
1483\r
1484Returns:\r
1485\r
1486 None\r
1487\r
1488--*/\r
1489{\r
1490 EFI_STATUS Status;\r
1491 EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;\r
1492\r
1493 if (NumberOfChildren == 0) {\r
1494 return EFI_SUCCESS;\r
1495 }\r
1496\r
1497 Status = ConSplitterStop (\r
1498 This,\r
1499 ControllerHandle,\r
1500 mConIn.VirtualHandle,\r
1501 &gEfiSimplePointerProtocolGuid,\r
1502 &gEfiSimplePointerProtocolGuid,\r
1503 (VOID **) &SimplePointer\r
1504 );\r
1505 if (EFI_ERROR (Status)) {\r
1506 return Status;\r
1507 }\r
1508 //\r
1509 // Delete this console input device's data structures.\r
1510 //\r
1511 return ConSplitterSimplePointerDeleteDevice (&mConIn, SimplePointer);\r
1512}\r
1513\r
8ae0b360 1514EFI_STATUS\r
1515EFIAPI\r
1516ConSplitterAbsolutePointerDriverBindingStop (\r
1517 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1518 IN EFI_HANDLE ControllerHandle,\r
1519 IN UINTN NumberOfChildren,\r
1520 IN EFI_HANDLE *ChildHandleBuffer\r
1521 )\r
1522/*++\r
1523\r
1524Routine Description:\r
1525\r
1526Arguments:\r
1527 (Standard DriverBinding Protocol Stop() function)\r
1528\r
1529Returns:\r
1530\r
1531 None\r
1532\r
1533--*/\r
1534{\r
1535 EFI_STATUS Status;\r
1536 EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer;\r
1537\r
1538 if (NumberOfChildren == 0) {\r
1539 return EFI_SUCCESS;\r
1540 }\r
1541\r
1542 Status = ConSplitterStop (\r
1543 This,\r
1544 ControllerHandle,\r
1545 mConIn.VirtualHandle,\r
1546 &gEfiAbsolutePointerProtocolGuid,\r
1547 &gEfiAbsolutePointerProtocolGuid,\r
1548 (VOID **) &AbsolutePointer\r
1549 );\r
1550 if (EFI_ERROR (Status)) {\r
1551 return Status;\r
1552 }\r
1553 //\r
1554 // Delete this console input device's data structures.\r
1555 //\r
1556 return ConSplitterAbsolutePointerDeleteDevice (&mConIn, AbsolutePointer);\r
1557}\r
1558\r
95276127 1559EFI_STATUS\r
1560EFIAPI\r
1561ConSplitterConOutDriverBindingStop (\r
1562 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1563 IN EFI_HANDLE ControllerHandle,\r
1564 IN UINTN NumberOfChildren,\r
1565 IN EFI_HANDLE *ChildHandleBuffer\r
1566 )\r
1567/*++\r
1568\r
1569Routine Description:\r
1570\r
1571Arguments:\r
1572 (Standard DriverBinding Protocol Stop() function)\r
1573\r
1574Returns:\r
1575\r
1576 None\r
1577\r
1578--*/\r
1579{\r
1580 EFI_STATUS Status;\r
1581 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;\r
1582\r
1583 if (NumberOfChildren == 0) {\r
1584 return EFI_SUCCESS;\r
1585 }\r
1586\r
1587 Status = ConSplitterStop (\r
1588 This,\r
1589 ControllerHandle,\r
1590 mConOut.VirtualHandle,\r
1591 &gEfiConsoleOutDeviceGuid,\r
1592 &gEfiSimpleTextOutProtocolGuid,\r
1593 (VOID **) &TextOut\r
1594 );\r
1595 if (EFI_ERROR (Status)) {\r
1596 return Status;\r
1597 }\r
1598\r
1599 //\r
1600 // Delete this console output device's data structures.\r
1601 //\r
1602 return ConSplitterTextOutDeleteDevice (&mConOut, TextOut);\r
1603}\r
1604\r
1605EFI_STATUS\r
1606EFIAPI\r
1607ConSplitterStdErrDriverBindingStop (\r
1608 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1609 IN EFI_HANDLE ControllerHandle,\r
1610 IN UINTN NumberOfChildren,\r
1611 IN EFI_HANDLE *ChildHandleBuffer\r
1612 )\r
1613/*++\r
1614\r
1615Routine Description:\r
1616\r
1617Arguments:\r
1618 (Standard DriverBinding Protocol Stop() function)\r
1619\r
1620Returns:\r
1621\r
1622 EFI_SUCCESS - Complete successfully.\r
1623\r
1624--*/\r
1625{\r
1626 EFI_STATUS Status;\r
1627 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;\r
1628\r
1629 if (NumberOfChildren == 0) {\r
1630 return EFI_SUCCESS;\r
1631 }\r
1632\r
1633 Status = ConSplitterStop (\r
1634 This,\r
1635 ControllerHandle,\r
1636 mStdErr.VirtualHandle,\r
1637 &gEfiStandardErrorDeviceGuid,\r
1638 &gEfiSimpleTextOutProtocolGuid,\r
1639 (VOID **) &TextOut\r
1640 );\r
1641 if (EFI_ERROR (Status)) {\r
1642 return Status;\r
1643 }\r
1644 //\r
1645 // Delete this console error out device's data structures.\r
1646 //\r
1647 Status = ConSplitterTextOutDeleteDevice (&mStdErr, TextOut);\r
1648 if (EFI_ERROR (Status)) {\r
1649 return Status;\r
1650 }\r
1651\r
1652 if (mStdErr.CurrentNumberOfConsoles == 0) {\r
1653 gST->StandardErrorHandle = NULL;\r
1654 gST->StdErr = NULL;\r
1655 //\r
1656 // Update the CRC32 in the EFI System Table header\r
1657 //\r
1658 gST->Hdr.CRC32 = 0;\r
1659 gBS->CalculateCrc32 (\r
1660 (UINT8 *) &gST->Hdr,\r
1661 gST->Hdr.HeaderSize,\r
1662 &gST->Hdr.CRC32\r
1663 );\r
1664 }\r
1665\r
1666 return Status;\r
1667}\r
1668\r
1669EFI_STATUS\r
1670ConSplitterGrowBuffer (\r
1671 IN UINTN SizeOfCount,\r
1672 IN UINTN *Count,\r
1673 IN OUT VOID **Buffer\r
1674 )\r
1675/*++\r
1676\r
1677Routine Description:\r
1678 Take the passed in Buffer of size SizeOfCount and grow the buffer\r
1679 by MAX (CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT, MaxGrow) * SizeOfCount\r
1680 bytes. Copy the current data in Buffer to the new version of Buffer\r
1681 and free the old version of buffer.\r
1682\r
1683\r
1684Arguments:\r
1685 SizeOfCount - Size of element in array\r
1686 Count - Current number of elements in array\r
1687 Buffer - Bigger version of passed in Buffer with all the data\r
1688\r
1689Returns:\r
1690 EFI_SUCCESS - Buffer size has grown\r
1691 EFI_OUT_OF_RESOURCES - Could not grow the buffer size\r
1692\r
1693 None\r
1694\r
1695--*/\r
1696{\r
1697 UINTN NewSize;\r
1698 UINTN OldSize;\r
1699 VOID *Ptr;\r
1700\r
1701 //\r
1702 // grow the buffer to new buffer size,\r
1703 // copy the old buffer's content to the new-size buffer,\r
1704 // then free the old buffer.\r
1705 //\r
1706 OldSize = *Count * SizeOfCount;\r
1707 *Count += CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT;\r
1708 NewSize = *Count * SizeOfCount;\r
1709\r
1710 Ptr = AllocateZeroPool (NewSize);\r
1711 if (Ptr == NULL) {\r
1712 return EFI_OUT_OF_RESOURCES;\r
1713 }\r
1714\r
1715 CopyMem (Ptr, *Buffer, OldSize);\r
1716\r
1717 if (*Buffer != NULL) {\r
1718 FreePool (*Buffer);\r
1719 }\r
1720\r
1721 *Buffer = Ptr;\r
1722\r
1723 return EFI_SUCCESS;\r
1724}\r
1725\r
1726EFI_STATUS\r
1727ConSplitterTextInAddDevice (\r
1728 IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
1729 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn\r
1730 )\r
1731/*++\r
1732\r
1733Routine Description:\r
1734\r
1735Arguments:\r
1736\r
1737Returns:\r
1738\r
1739 EFI_SUCCESS\r
1740 EFI_OUT_OF_RESOURCES\r
1741\r
1742--*/\r
1743{\r
1744 EFI_STATUS Status;\r
1745\r
1746 //\r
1747 // If the Text In List is full, enlarge it by calling growbuffer().\r
1748 //\r
1749 if (Private->CurrentNumberOfConsoles >= Private->TextInListCount) {\r
1750 Status = ConSplitterGrowBuffer (\r
1751 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *),\r
1752 &Private->TextInListCount,\r
1753 (VOID **) &Private->TextInList\r
1754 );\r
1755 if (EFI_ERROR (Status)) {\r
1756 return EFI_OUT_OF_RESOURCES;\r
1757 }\r
1758 }\r
1759 //\r
1760 // Add the new text-in device data structure into the Text In List.\r
1761 //\r
1762 Private->TextInList[Private->CurrentNumberOfConsoles] = TextIn;\r
1763 Private->CurrentNumberOfConsoles++;\r
1764\r
1765 //\r
1766 // Extra CheckEvent added to reduce the double CheckEvent() in UI.c\r
1767 //\r
1768 gBS->CheckEvent (TextIn->WaitForKey);\r
1769\r
1770 return EFI_SUCCESS;\r
1771}\r
1772\r
1773EFI_STATUS\r
1774ConSplitterTextInDeleteDevice (\r
1775 IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
1776 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn\r
1777 )\r
1778/*++\r
1779\r
1780Routine Description:\r
1781\r
1782Arguments:\r
1783\r
1784Returns:\r
1785\r
1786 EFI_SUCCESS\r
1787 EFI_NOT_FOUND\r
1788\r
1789--*/\r
1790{\r
1791 UINTN Index;\r
1792 //\r
1793 // Remove the specified text-in device data structure from the Text In List,\r
1794 // and rearrange the remaining data structures in the Text In List.\r
1795 //\r
1796 for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
1797 if (Private->TextInList[Index] == TextIn) {\r
1798 for (Index = Index; Index < Private->CurrentNumberOfConsoles - 1; Index++) {\r
1799 Private->TextInList[Index] = Private->TextInList[Index + 1];\r
1800 }\r
1801\r
1802 Private->CurrentNumberOfConsoles--;\r
1803 return EFI_SUCCESS;\r
1804 }\r
1805 }\r
1806\r
1807 return EFI_NOT_FOUND;\r
1808}\r
1809\r
66aa04e4 1810EFI_STATUS\r
1811ConSplitterTextInExAddDevice (\r
1812 IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
1813 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx\r
1814 )\r
1815{\r
1816 EFI_STATUS Status;\r
1817\r
1818 //\r
1819 // If the TextInEx List is full, enlarge it by calling growbuffer().\r
1820 //\r
1821 if (Private->CurrentNumberOfExConsoles >= Private->TextInExListCount) {\r
1822 Status = ConSplitterGrowBuffer (\r
1823 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *),\r
1824 &Private->TextInExListCount,\r
1825 (VOID **) &Private->TextInExList\r
1826 );\r
1827 if (EFI_ERROR (Status)) {\r
1828 return EFI_OUT_OF_RESOURCES;\r
1829 }\r
1830 }\r
1831 //\r
1832 // Add the new text-in device data structure into the Text In List.\r
1833 //\r
1834 Private->TextInExList[Private->CurrentNumberOfExConsoles] = TextInEx;\r
1835 Private->CurrentNumberOfExConsoles++;\r
1836\r
1837 //\r
1838 // Extra CheckEvent added to reduce the double CheckEvent() in UI.c\r
1839 //\r
1840 gBS->CheckEvent (TextInEx->WaitForKeyEx);\r
1841\r
1842 return EFI_SUCCESS;\r
1843}\r
1844\r
1845EFI_STATUS\r
1846ConSplitterTextInExDeleteDevice (\r
1847 IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
1848 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx\r
1849 )\r
1850{\r
1851 UINTN Index;\r
1852 //\r
1853 // Remove the specified text-in device data structure from the Text In List,\r
1854 // and rearrange the remaining data structures in the Text In List.\r
1855 //\r
1856 for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
1857 if (Private->TextInExList[Index] == TextInEx) {\r
1858 for (Index = Index; Index < Private->CurrentNumberOfExConsoles - 1; Index++) {\r
1859 Private->TextInExList[Index] = Private->TextInExList[Index + 1];\r
1860 }\r
1861\r
1862 Private->CurrentNumberOfExConsoles--;\r
1863 return EFI_SUCCESS;\r
1864 }\r
1865 }\r
1866\r
1867 return EFI_NOT_FOUND;\r
1868}\r
1869\r
95276127 1870EFI_STATUS\r
1871ConSplitterSimplePointerAddDevice (\r
1872 IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
1873 IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer\r
1874 )\r
1875/*++\r
1876\r
1877Routine Description:\r
1878\r
1879Arguments:\r
1880\r
1881Returns:\r
1882\r
1883 EFI_OUT_OF_RESOURCES\r
1884 EFI_SUCCESS\r
1885\r
1886--*/\r
1887{\r
1888 EFI_STATUS Status;\r
1889\r
1890 //\r
1891 // If the Text In List is full, enlarge it by calling growbuffer().\r
1892 //\r
1893 if (Private->CurrentNumberOfPointers >= Private->PointerListCount) {\r
1894 Status = ConSplitterGrowBuffer (\r
1895 sizeof (EFI_SIMPLE_POINTER_PROTOCOL *),\r
1896 &Private->PointerListCount,\r
1897 (VOID **) &Private->PointerList\r
1898 );\r
1899 if (EFI_ERROR (Status)) {\r
1900 return EFI_OUT_OF_RESOURCES;\r
1901 }\r
1902 }\r
1903 //\r
1904 // Add the new text-in device data structure into the Text In List.\r
1905 //\r
1906 Private->PointerList[Private->CurrentNumberOfPointers] = SimplePointer;\r
1907 Private->CurrentNumberOfPointers++;\r
1908 return EFI_SUCCESS;\r
1909}\r
1910\r
1911EFI_STATUS\r
1912ConSplitterSimplePointerDeleteDevice (\r
1913 IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
1914 IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer\r
1915 )\r
1916/*++\r
1917\r
1918Routine Description:\r
1919\r
1920Arguments:\r
1921\r
1922Returns:\r
1923\r
1924 None\r
1925\r
1926--*/\r
1927{\r
1928 UINTN Index;\r
1929 //\r
1930 // Remove the specified text-in device data structure from the Text In List,\r
1931 // and rearrange the remaining data structures in the Text In List.\r
1932 //\r
1933 for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {\r
1934 if (Private->PointerList[Index] == SimplePointer) {\r
1935 for (Index = Index; Index < Private->CurrentNumberOfPointers - 1; Index++) {\r
1936 Private->PointerList[Index] = Private->PointerList[Index + 1];\r
1937 }\r
1938\r
1939 Private->CurrentNumberOfPointers--;\r
1940 return EFI_SUCCESS;\r
1941 }\r
1942 }\r
1943\r
1944 return EFI_NOT_FOUND;\r
1945}\r
1946\r
8ae0b360 1947EFI_STATUS\r
1948ConSplitterAbsolutePointerAddDevice (\r
1949 IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
1950 IN EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer\r
1951 )\r
1952/*++\r
1953\r
1954Routine Description:\r
1955\r
1956Arguments:\r
1957\r
1958Returns:\r
1959\r
1960 EFI_OUT_OF_RESOURCES\r
1961 EFI_SUCCESS\r
1962\r
1963--*/\r
1964{\r
1965 EFI_STATUS Status;\r
1966\r
1967 //\r
1968 // If the Absolute Pointer List is full, enlarge it by calling growbuffer().\r
1969 //\r
1970 if (Private->CurrentNumberOfAbsolutePointers >= Private->AbsolutePointerListCount) {\r
1971 Status = ConSplitterGrowBuffer (\r
1972 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL *),\r
1973 &Private->AbsolutePointerListCount,\r
1974 (VOID **) &Private->AbsolutePointerList\r
1975 );\r
1976 if (EFI_ERROR (Status)) {\r
1977 return EFI_OUT_OF_RESOURCES;\r
1978 }\r
1979 }\r
1980 //\r
1981 // Add the new text-in device data structure into the Text In List.\r
1982 //\r
1983 Private->AbsolutePointerList[Private->CurrentNumberOfAbsolutePointers] = AbsolutePointer;\r
1984 Private->CurrentNumberOfAbsolutePointers++;\r
1985 return EFI_SUCCESS;\r
1986}\r
1987\r
1988EFI_STATUS\r
1989ConSplitterAbsolutePointerDeleteDevice (\r
1990 IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
1991 IN EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer\r
1992 )\r
1993/*++\r
1994\r
1995Routine Description:\r
1996\r
1997Arguments:\r
1998\r
1999Returns:\r
2000\r
2001 None\r
2002\r
2003--*/\r
2004{\r
2005 UINTN Index;\r
2006 //\r
2007 // Remove the specified text-in device data structure from the Text In List,\r
2008 // and rearrange the remaining data structures in the Text In List.\r
2009 //\r
2010 for (Index = 0; Index < Private->CurrentNumberOfAbsolutePointers; Index++) {\r
2011 if (Private->AbsolutePointerList[Index] == AbsolutePointer) {\r
2012 for (Index = Index; Index < Private->CurrentNumberOfAbsolutePointers - 1; Index++) {\r
2013 Private->AbsolutePointerList[Index] = Private->AbsolutePointerList[Index + 1];\r
2014 }\r
2015\r
2016 Private->CurrentNumberOfAbsolutePointers--;\r
2017 return EFI_SUCCESS;\r
2018 }\r
2019 }\r
2020\r
2021 return EFI_NOT_FOUND;\r
2022}\r
2023\r
95276127 2024STATIC\r
2025EFI_STATUS\r
2026ConSplitterGrowMapTable (\r
2027 IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private\r
2028 )\r
2029/*++\r
2030\r
2031Routine Description:\r
2032\r
2033Arguments:\r
2034\r
2035Returns:\r
2036\r
2037 None\r
2038\r
2039--*/\r
2040{\r
2041 UINTN Size;\r
2042 UINTN NewSize;\r
2043 UINTN TotalSize;\r
2044 INT32 *TextOutModeMap;\r
2045 INT32 *OldTextOutModeMap;\r
2046 INT32 *SrcAddress;\r
2047 INT32 Index;\r
2048\r
2049 NewSize = Private->TextOutListCount * sizeof (INT32);\r
2050 OldTextOutModeMap = Private->TextOutModeMap;\r
2051 TotalSize = NewSize * Private->TextOutQueryDataCount;\r
2052\r
2053 TextOutModeMap = AllocateZeroPool (TotalSize);\r
2054 if (TextOutModeMap == NULL) {\r
2055 return EFI_OUT_OF_RESOURCES;\r
2056 }\r
2057\r
2058 SetMem (TextOutModeMap, TotalSize, 0xFF);\r
2059 Private->TextOutModeMap = TextOutModeMap;\r
2060\r
2061 //\r
2062 // If TextOutList has been enlarged, need to realloc the mode map table\r
2063 // The mode map table is regarded as a two dimension array.\r
2064 //\r
2065 // Old New\r
2066 // 0 ---------> TextOutListCount ----> TextOutListCount\r
2067 // | -------------------------------------------\r
2068 // | | | |\r
2069 // | | | |\r
2070 // | | | |\r
2071 // | | | |\r
2072 // | | | |\r
2073 // \/ | | |\r
2074 // -------------------------------------------\r
2075 // QueryDataCount\r
2076 //\r
2077 if (OldTextOutModeMap != NULL) {\r
2078\r
2079 Size = Private->CurrentNumberOfConsoles * sizeof (INT32);\r
2080 Index = 0;\r
2081 SrcAddress = OldTextOutModeMap;\r
2082\r
2083 //\r
2084 // Copy the old data to the new one\r
2085 //\r
2086 while (Index < Private->TextOutMode.MaxMode) {\r
2087 CopyMem (TextOutModeMap, SrcAddress, Size);\r
2088 TextOutModeMap += NewSize;\r
2089 SrcAddress += Size;\r
2090 Index++;\r
2091 }\r
2092 //\r
2093 // Free the old buffer\r
2094 //\r
2095 FreePool (OldTextOutModeMap);\r
2096 }\r
2097\r
2098 return EFI_SUCCESS;\r
2099}\r
2100\r
2101STATIC\r
2102EFI_STATUS\r
2103ConSplitterAddOutputMode (\r
2104 IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
2105 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut\r
2106 )\r
2107/*++\r
2108\r
2109Routine Description:\r
2110\r
2111Arguments:\r
2112\r
2113Returns:\r
2114\r
2115 None\r
2116\r
2117--*/\r
2118{\r
2119 EFI_STATUS Status;\r
2120 INT32 MaxMode;\r
2121 INT32 Mode;\r
2122 UINTN Index;\r
2123\r
2124 MaxMode = TextOut->Mode->MaxMode;\r
2125 Private->TextOutMode.MaxMode = MaxMode;\r
2126\r
2127 //\r
2128 // Grow the buffer if query data buffer is not large enough to\r
2129 // hold all the mode supported by the first console.\r
2130 //\r
2131 while (MaxMode > (INT32) Private->TextOutQueryDataCount) {\r
2132 Status = ConSplitterGrowBuffer (\r
2133 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA),\r
2134 &Private->TextOutQueryDataCount,\r
2135 (VOID **) &Private->TextOutQueryData\r
2136 );\r
2137 if (EFI_ERROR (Status)) {\r
2138 return EFI_OUT_OF_RESOURCES;\r
2139 }\r
2140 }\r
2141 //\r
2142 // Allocate buffer for the output mode map\r
2143 //\r
2144 Status = ConSplitterGrowMapTable (Private);\r
2145 if (EFI_ERROR (Status)) {\r
2146 return EFI_OUT_OF_RESOURCES;\r
2147 }\r
2148 //\r
2149 // As the first textout device, directly add the mode in to QueryData\r
2150 // and at the same time record the mapping between QueryData and TextOut.\r
2151 //\r
2152 Mode = 0;\r
2153 Index = 0;\r
2154 while (Mode < MaxMode) {\r
7347d5d6 2155 Status = TextOut->QueryMode (\r
2156 TextOut,\r
2157 Mode,\r
2158 &Private->TextOutQueryData[Mode].Columns,\r
2159 &Private->TextOutQueryData[Mode].Rows\r
2160 );\r
2161 //\r
2162 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData\r
2163 // is clear to 0x0.\r
2164 //\r
2165 if ((EFI_ERROR(Status)) && (Mode == 1)) {\r
2166 Private->TextOutQueryData[Mode].Columns = 0;\r
2167 Private->TextOutQueryData[Mode].Rows = 0;\r
2168 }\r
95276127 2169 Private->TextOutModeMap[Index] = Mode;\r
2170 Mode++;\r
2171 Index += Private->TextOutListCount;\r
2172 }\r
2173\r
2174 return EFI_SUCCESS;\r
2175}\r
2176\r
7347d5d6 2177/**\r
2178 Reconstruct TextOutModeMap to get intersection of modes\r
2179\r
2180 This routine reconstruct TextOutModeMap to get the intersection\r
2181 of modes for all console out devices. Because EFI/UEFI spec require\r
2182 mode 0 is 80x25, mode 1 is 80x50, this routine will not check the\r
2183 intersection for mode 0 and mode 1.\r
2184\r
2185 @parm TextOutModeMap Current text out mode map, begin with the mode 80x25\r
2186 @parm NewlyAddedMap New text out mode map, begin with the mode 80x25\r
2187 @parm MapStepSize Mode step size for one console device\r
2188 @parm NewMapStepSize Mode step size for one console device\r
2189 @parm MaxMode Current max text mode\r
2190 @parm CurrentMode Current text mode\r
2191\r
2192 @retval None\r
2193\r
2194**/\r
95276127 2195STATIC\r
2196VOID\r
2197ConSplitterGetIntersection (\r
2198 IN INT32 *TextOutModeMap,\r
2199 IN INT32 *NewlyAddedMap,\r
2200 IN UINTN MapStepSize,\r
2201 IN UINTN NewMapStepSize,\r
2202 OUT INT32 *MaxMode,\r
2203 OUT INT32 *CurrentMode\r
2204 )\r
2205{\r
2206 INT32 Index;\r
2207 INT32 *CurrentMapEntry;\r
2208 INT32 *NextMapEntry;\r
2209 INT32 CurrentMaxMode;\r
2210 INT32 Mode;\r
2211\r
7347d5d6 2212 //\r
2213 // According to EFI/UEFI spec, mode 0 and mode 1 have been reserved\r
2214 // for 80x25 and 80x50 in Simple Text Out protocol, so don't make intersection\r
2215 // for mode 0 and mode 1, mode number starts from 2.\r
2216 //\r
2217 Index = 2;\r
2218 CurrentMapEntry = &TextOutModeMap[MapStepSize * 2];\r
2219 NextMapEntry = &TextOutModeMap[MapStepSize * 2];\r
2220 NewlyAddedMap = &NewlyAddedMap[NewMapStepSize * 2];\r
2221\r
95276127 2222 CurrentMaxMode = *MaxMode;\r
2223 Mode = *CurrentMode;\r
2224\r
2225 while (Index < CurrentMaxMode) {\r
2226 if (*NewlyAddedMap == -1) {\r
2227 //\r
2228 // This mode is not supported any more. Remove it. Special care\r
2229 // must be taken as this remove will also affect current mode;\r
2230 //\r
2231 if (Index == *CurrentMode) {\r
2232 Mode = -1;\r
2233 } else if (Index < *CurrentMode) {\r
2234 Mode--;\r
2235 }\r
2236 (*MaxMode)--;\r
2237 } else {\r
2238 if (CurrentMapEntry != NextMapEntry) {\r
2239 CopyMem (NextMapEntry, CurrentMapEntry, MapStepSize * sizeof (INT32));\r
2240 }\r
2241\r
2242 NextMapEntry += MapStepSize;\r
2243 }\r
2244\r
2245 CurrentMapEntry += MapStepSize;\r
2246 NewlyAddedMap += NewMapStepSize;\r
2247 Index++;\r
2248 }\r
2249\r
2250 *CurrentMode = Mode;\r
2251\r
2252 return ;\r
2253}\r
2254\r
2255STATIC\r
2256VOID\r
2257ConSplitterSyncOutputMode (\r
2258 IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
2259 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut\r
2260 )\r
2261/*++\r
2262\r
2263Routine Description:\r
2264\r
2265Arguments:\r
2266 Private - Private data structure.\r
2267 TextOut - Text Out Protocol.\r
2268Returns:\r
2269\r
2270 None\r
2271\r
2272--*/\r
2273{\r
2274 INT32 CurrentMaxMode;\r
2275 INT32 Mode;\r
2276 INT32 Index;\r
2277 INT32 *TextOutModeMap;\r
2278 INT32 *MapTable;\r
3012ce5c 2279 INT32 QueryMode;\r
95276127 2280 TEXT_OUT_SPLITTER_QUERY_DATA *TextOutQueryData;\r
2281 UINTN Rows;\r
2282 UINTN Columns;\r
2283 UINTN StepSize;\r
7347d5d6 2284 EFI_STATUS Status;\r
95276127 2285\r
2286 //\r
2287 // Must make sure that current mode won't change even if mode number changes\r
2288 //\r
2289 CurrentMaxMode = Private->TextOutMode.MaxMode;\r
2290 TextOutModeMap = Private->TextOutModeMap;\r
2291 StepSize = Private->TextOutListCount;\r
2292 TextOutQueryData = Private->TextOutQueryData;\r
2293\r
2294 //\r
2295 // Query all the mode that the newly added TextOut supports\r
2296 //\r
2297 Mode = 0;\r
2298 MapTable = TextOutModeMap + Private->CurrentNumberOfConsoles;\r
2299 while (Mode < TextOut->Mode->MaxMode) {\r
7347d5d6 2300 Status = TextOut->QueryMode (TextOut, Mode, &Columns, &Rows);\r
2301 if (EFI_ERROR(Status)) {\r
2302 if (Mode == 1) {\r
3012ce5c 2303 MapTable[StepSize] = Mode;\r
7347d5d6 2304 TextOutQueryData[Mode].Columns = 0;\r
2305 TextOutQueryData[Mode].Rows = 0;\r
2306 }\r
2307 Mode++;\r
2308 continue;\r
2309 }\r
95276127 2310 //\r
3012ce5c 2311 // Search the intersection map and QueryData database to see if they intersects\r
95276127 2312 //\r
2313 Index = 0;\r
2314 while (Index < CurrentMaxMode) {\r
3012ce5c 2315 QueryMode = *(TextOutModeMap + Index * StepSize);\r
2316 if ((TextOutQueryData[QueryMode].Rows == Rows) && (TextOutQueryData[QueryMode].Columns == Columns)) {\r
95276127 2317 MapTable[Index * StepSize] = Mode;\r
2318 break;\r
2319 }\r
2320\r
2321 Index++;\r
2322 }\r
2323\r
2324 Mode++;\r
2325 }\r
2326 //\r
2327 // Now search the TextOutModeMap table to find the intersection of supported\r
2328 // mode between ConSplitter and the newly added device.\r
2329 //\r
2330 ConSplitterGetIntersection (\r
2331 TextOutModeMap,\r
2332 MapTable,\r
2333 StepSize,\r
2334 StepSize,\r
2335 &Private->TextOutMode.MaxMode,\r
2336 &Private->TextOutMode.Mode\r
2337 );\r
2338\r
2339 return ;\r
2340}\r
2341\r
2342STATIC\r
2343EFI_STATUS\r
2344ConSplitterGetIntersectionBetweenConOutAndStrErr (\r
2345 VOID\r
2346 )\r
2347/*++\r
2348\r
2349Routine Description:\r
2350\r
2351Arguments:\r
2352\r
2353Returns:\r
2354\r
3012ce5c 2355 EFI_SUCCESS\r
95276127 2356 EFI_OUT_OF_RESOURCES\r
2357\r
2358--*/\r
2359{\r
2360 UINTN ConOutNumOfConsoles;\r
2361 UINTN StdErrNumOfConsoles;\r
2362 TEXT_OUT_AND_GOP_DATA *ConOutTextOutList;\r
2363 TEXT_OUT_AND_GOP_DATA *StdErrTextOutList;\r
2364 UINTN Indexi;\r
2365 UINTN Indexj;\r
3012ce5c 2366 UINTN ConOutRows;\r
2367 UINTN ConOutColumns;\r
2368 UINTN StdErrRows;\r
2369 UINTN StdErrColumns;\r
95276127 2370 INT32 ConOutMaxMode;\r
2371 INT32 StdErrMaxMode;\r
3012ce5c 2372 INT32 ConOutMode;\r
2373 INT32 StdErrMode;\r
95276127 2374 INT32 Mode;\r
2375 INT32 Index;\r
2376 INT32 *ConOutModeMap;\r
2377 INT32 *StdErrModeMap;\r
2378 INT32 *ConOutMapTable;\r
2379 INT32 *StdErrMapTable;\r
2380 TEXT_OUT_SPLITTER_QUERY_DATA *ConOutQueryData;\r
2381 TEXT_OUT_SPLITTER_QUERY_DATA *StdErrQueryData;\r
3012ce5c 2382 UINTN ConOutStepSize;\r
2383 UINTN StdErrStepSize;\r
95276127 2384 BOOLEAN FoundTheSameTextOut;\r
2385 UINTN ConOutMapTableSize;\r
2386 UINTN StdErrMapTableSize;\r
2387\r
2388 ConOutNumOfConsoles = mConOut.CurrentNumberOfConsoles;\r
2389 StdErrNumOfConsoles = mStdErr.CurrentNumberOfConsoles;\r
2390 ConOutTextOutList = mConOut.TextOutList;\r
2391 StdErrTextOutList = mStdErr.TextOutList;\r
2392\r
2393 Indexi = 0;\r
2394 FoundTheSameTextOut = FALSE;\r
2395 while ((Indexi < ConOutNumOfConsoles) && (!FoundTheSameTextOut)) {\r
2396 Indexj = 0;\r
2397 while (Indexj < StdErrNumOfConsoles) {\r
2398 if (ConOutTextOutList->TextOut == StdErrTextOutList->TextOut) {\r
2399 FoundTheSameTextOut = TRUE;\r
2400 break;\r
2401 }\r
2402\r
2403 Indexj++;\r
2404 StdErrTextOutList++;\r
2405 }\r
2406\r
2407 Indexi++;\r
2408 ConOutTextOutList++;\r
2409 }\r
2410\r
2411 if (!FoundTheSameTextOut) {\r
2412 return EFI_SUCCESS;\r
2413 }\r
2414 //\r
2415 // Must make sure that current mode won't change even if mode number changes\r
2416 //\r
2417 ConOutMaxMode = mConOut.TextOutMode.MaxMode;\r
2418 ConOutModeMap = mConOut.TextOutModeMap;\r
3012ce5c 2419 ConOutStepSize = mConOut.TextOutListCount;\r
95276127 2420 ConOutQueryData = mConOut.TextOutQueryData;\r
2421\r
2422 StdErrMaxMode = mStdErr.TextOutMode.MaxMode;\r
2423 StdErrModeMap = mStdErr.TextOutModeMap;\r
3012ce5c 2424 StdErrStepSize = mStdErr.TextOutListCount;\r
95276127 2425 StdErrQueryData = mStdErr.TextOutQueryData;\r
2426\r
2427 //\r
2428 // Allocate the map table and set the map table's index to -1.\r
2429 //\r
2430 ConOutMapTableSize = ConOutMaxMode * sizeof (INT32);\r
2431 ConOutMapTable = AllocateZeroPool (ConOutMapTableSize);\r
2432 if (ConOutMapTable == NULL) {\r
2433 return EFI_OUT_OF_RESOURCES;\r
2434 }\r
2435\r
2436 SetMem (ConOutMapTable, ConOutMapTableSize, 0xFF);\r
2437\r
2438 StdErrMapTableSize = StdErrMaxMode * sizeof (INT32);\r
2439 StdErrMapTable = AllocateZeroPool (StdErrMapTableSize);\r
2440 if (StdErrMapTable == NULL) {\r
2441 return EFI_OUT_OF_RESOURCES;\r
2442 }\r
2443\r
2444 SetMem (StdErrMapTable, StdErrMapTableSize, 0xFF);\r
2445\r
2446 //\r
2447 // Find the intersection of the two set of modes. If they actually intersect, the\r
2448 // correponding entry in the map table is set to 1.\r
2449 //\r
2450 Mode = 0;\r
2451 while (Mode < ConOutMaxMode) {\r
2452 //\r
3012ce5c 2453 // Search the intersection map and QueryData database to see if they intersect\r
95276127 2454 //\r
3012ce5c 2455 Index = 0;\r
2456 ConOutMode = *(ConOutModeMap + Mode * ConOutStepSize);\r
2457 ConOutRows = ConOutQueryData[ConOutMode].Rows;\r
2458 ConOutColumns = ConOutQueryData[ConOutMode].Columns;\r
95276127 2459 while (Index < StdErrMaxMode) {\r
3012ce5c 2460 StdErrMode = *(StdErrModeMap + Index * StdErrStepSize);\r
2461 StdErrRows = StdErrQueryData[StdErrMode].Rows;\r
2462 StdErrColumns = StdErrQueryData[StdErrMode].Columns;\r
2463 if ((StdErrRows == ConOutRows) && (StdErrColumns == ConOutColumns)) {\r
95276127 2464 ConOutMapTable[Mode] = 1;\r
2465 StdErrMapTable[Index] = 1;\r
2466 break;\r
2467 }\r
2468\r
2469 Index++;\r
2470 }\r
2471\r
2472 Mode++;\r
2473 }\r
2474 //\r
2475 // Now search the TextOutModeMap table to find the intersection of supported\r
2476 // mode between ConSplitter and the newly added device.\r
2477 //\r
2478 ConSplitterGetIntersection (\r
2479 ConOutModeMap,\r
2480 ConOutMapTable,\r
2481 mConOut.TextOutListCount,\r
2482 1,\r
2483 &(mConOut.TextOutMode.MaxMode),\r
2484 &(mConOut.TextOutMode.Mode)\r
2485 );\r
2486 if (mConOut.TextOutMode.Mode < 0) {\r
2487 mConOut.TextOut.SetMode (&(mConOut.TextOut), 0);\r
2488 }\r
2489\r
2490 ConSplitterGetIntersection (\r
2491 StdErrModeMap,\r
2492 StdErrMapTable,\r
2493 mStdErr.TextOutListCount,\r
2494 1,\r
2495 &(mStdErr.TextOutMode.MaxMode),\r
2496 &(mStdErr.TextOutMode.Mode)\r
2497 );\r
2498 if (mStdErr.TextOutMode.Mode < 0) {\r
2499 mStdErr.TextOut.SetMode (&(mStdErr.TextOut), 0);\r
2500 }\r
2501\r
2502 FreePool (ConOutMapTable);\r
2503 FreePool (StdErrMapTable);\r
2504\r
2505 return EFI_SUCCESS;\r
2506}\r
2507\r
2508STATIC\r
2509EFI_STATUS\r
2510ConSplitterAddGraphicsOutputMode (\r
2511 IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
2512 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
2513 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw\r
2514 )\r
2515/*++\r
2516\r
2517Routine Description:\r
2518\r
2519Arguments:\r
2520\r
2521Returns:\r
2522\r
2523 None\r
2524\r
2525--*/\r
2526{\r
2527 EFI_STATUS Status;\r
2528 UINTN Index;\r
3012ce5c 2529 UINTN CurrentIndex;\r
aec072ad 2530 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Mode;\r
95276127 2531 UINTN SizeOfInfo;\r
2532 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
2533 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *CurrentGraphicsOutputMode;\r
aec072ad 2534 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *ModeBuffer;\r
2535 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *MatchedMode;\r
95276127 2536 UINTN NumberIndex;\r
2537 BOOLEAN Match;\r
aec072ad 2538 BOOLEAN AlreadyExist;\r
3012ce5c 2539 UINT32 UgaHorizontalResolution;\r
2540 UINT32 UgaVerticalResolution;\r
2541 UINT32 UgaColorDepth;\r
2542 UINT32 UgaRefreshRate;\r
95276127 2543\r
2544 if ((GraphicsOutput == NULL) && (UgaDraw == NULL)) {\r
2545 return EFI_UNSUPPORTED;\r
2546 }\r
2547\r
2548 CurrentGraphicsOutputMode = Private->GraphicsOutput.Mode;\r
2549\r
aec072ad 2550 Index = 0;\r
3012ce5c 2551 CurrentIndex = 0;\r
aec072ad 2552\r
2553 if (Private->CurrentNumberOfUgaDraw != 0) {\r
2554 //\r
2555 // If any UGA device has already been added, then there is no need to\r
2556 // calculate intersection of display mode of different GOP/UGA device,\r
2557 // since only one display mode will be exported (i.e. user-defined mode)\r
2558 //\r
2559 goto Done;\r
2560 }\r
2561\r
95276127 2562 if (GraphicsOutput != NULL) {\r
2563 if (Private->CurrentNumberOfGraphicsOutput == 0) {\r
2564 //\r
2565 // This is the first Graphics Output device added\r
2566 //\r
2567 CurrentGraphicsOutputMode->MaxMode = GraphicsOutput->Mode->MaxMode;\r
2568 CurrentGraphicsOutputMode->Mode = GraphicsOutput->Mode->Mode;\r
2569 CopyMem (CurrentGraphicsOutputMode->Info, GraphicsOutput->Mode->Info, GraphicsOutput->Mode->SizeOfInfo);\r
2570 CurrentGraphicsOutputMode->SizeOfInfo = GraphicsOutput->Mode->SizeOfInfo;\r
2571 CurrentGraphicsOutputMode->FrameBufferBase = GraphicsOutput->Mode->FrameBufferBase;\r
2572 CurrentGraphicsOutputMode->FrameBufferSize = GraphicsOutput->Mode->FrameBufferSize;\r
2573\r
2574 //\r
2575 // Allocate resource for the private mode buffer\r
2576 //\r
aec072ad 2577 ModeBuffer = AllocatePool (GraphicsOutput->Mode->SizeOfInfo * GraphicsOutput->Mode->MaxMode);\r
95276127 2578 if (ModeBuffer == NULL) {\r
2579 return EFI_OUT_OF_RESOURCES;\r
2580 }\r
2581 FreePool (Private->GraphicsOutputModeBuffer);\r
2582 Private->GraphicsOutputModeBuffer = ModeBuffer;\r
2583\r
2584 //\r
2585 // Store all supported display modes to the private mode buffer\r
2586 //\r
2587 Mode = ModeBuffer;\r
2588 for (Index = 0; Index < GraphicsOutput->Mode->MaxMode; Index++) {\r
2589 Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) Index, &SizeOfInfo, &Info);\r
2590 if (EFI_ERROR (Status)) {\r
2591 return Status;\r
2592 }\r
aec072ad 2593 CopyMem (Mode, Info, SizeOfInfo);\r
95276127 2594 Mode++;\r
2595 FreePool (Info);\r
2596 }\r
2597 } else {\r
2598 //\r
2599 // Check intersection of display mode\r
2600 //\r
aec072ad 2601 ModeBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION) * CurrentGraphicsOutputMode->MaxMode);\r
95276127 2602 if (ModeBuffer == NULL) {\r
2603 return EFI_OUT_OF_RESOURCES;\r
2604 }\r
2605\r
2606 MatchedMode = ModeBuffer;\r
2607 Mode = &Private->GraphicsOutputModeBuffer[0];\r
2608 for (Index = 0; Index < CurrentGraphicsOutputMode->MaxMode; Index++) {\r
2609 Match = FALSE;\r
2610\r
2611 for (NumberIndex = 0; NumberIndex < GraphicsOutput->Mode->MaxMode; NumberIndex++) {\r
2612 Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) NumberIndex, &SizeOfInfo, &Info);\r
2613 if (EFI_ERROR (Status)) {\r
2614 return Status;\r
2615 }\r
2616 if ((Info->HorizontalResolution == Mode->HorizontalResolution) &&\r
aec072ad 2617 (Info->VerticalResolution == Mode->VerticalResolution)) {\r
95276127 2618 Match = TRUE;\r
2619 FreePool (Info);\r
2620 break;\r
2621 }\r
2622 FreePool (Info);\r
2623 }\r
2624\r
2625 if (Match) {\r
aec072ad 2626 AlreadyExist = FALSE;\r
2627\r
2628 for (Info = ModeBuffer; Info < MatchedMode; Info++) {\r
2629 if ((Info->HorizontalResolution == Mode->HorizontalResolution) &&\r
2630 (Info->VerticalResolution == Mode->VerticalResolution)) {\r
2631 AlreadyExist = TRUE;\r
2632 break;\r
2633 }\r
2634 }\r
2635\r
2636 if (!AlreadyExist) {\r
2637 CopyMem (MatchedMode, Mode, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
2638\r
2639 //\r
2640 // Physical frame buffer is no longer available, change PixelFormat to PixelBltOnly\r
2641 //\r
2642 MatchedMode->Version = 0;\r
2643 MatchedMode->PixelFormat = PixelBltOnly;\r
2644 ZeroMem (&MatchedMode->PixelInformation, sizeof (EFI_PIXEL_BITMASK));\r
2645\r
2646 MatchedMode++;\r
2647 }\r
95276127 2648 }\r
2649\r
2650 Mode++;\r
2651 }\r
2652\r
2653 //\r
2654 // Drop the old mode buffer, assign it to a new one\r
2655 //\r
2656 FreePool (Private->GraphicsOutputModeBuffer);\r
2657 Private->GraphicsOutputModeBuffer = ModeBuffer;\r
2658\r
2659 //\r
2660 // Physical frame buffer is no longer available when there are more than one physical GOP devices\r
2661 //\r
aec072ad 2662 CurrentGraphicsOutputMode->MaxMode = (UINT32) (((UINTN) MatchedMode - (UINTN) ModeBuffer) / sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
95276127 2663 CurrentGraphicsOutputMode->Info->PixelFormat = PixelBltOnly;\r
2664 ZeroMem (&CurrentGraphicsOutputMode->Info->PixelInformation, sizeof (EFI_PIXEL_BITMASK));\r
2665 CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
2666 CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;\r
2667 CurrentGraphicsOutputMode->FrameBufferSize = 0;\r
2668 }\r
2669\r
2670 //\r
3012ce5c 2671 // Graphics console driver can ensure the same mode for all GOP devices\r
95276127 2672 //\r
2673 for (Index = 0; Index < CurrentGraphicsOutputMode->MaxMode; Index++) {\r
2674 Mode = &Private->GraphicsOutputModeBuffer[Index];\r
3012ce5c 2675 if ((Mode->HorizontalResolution == GraphicsOutput->Mode->Info->HorizontalResolution) &&\r
2676 (Mode->VerticalResolution == GraphicsOutput->Mode->Info->VerticalResolution)) {\r
2677 CurrentIndex = Index;\r
95276127 2678 break;\r
2679 }\r
2680 }\r
95276127 2681 if (Index >= CurrentGraphicsOutputMode->MaxMode) {\r
3012ce5c 2682 //\r
2683 // if user defined mode is not found, set to default mode 800x600\r
2684 //\r
2685 for (Index = 0; Index < CurrentGraphicsOutputMode->MaxMode; Index++) {\r
2686 Mode = &Private->GraphicsOutputModeBuffer[Index];\r
2687 if ((Mode->HorizontalResolution == 800) && (Mode->VerticalResolution == 600)) {\r
2688 CurrentIndex = Index;\r
2689 break;\r
2690 }\r
2691 }\r
95276127 2692 }\r
aec072ad 2693 }\r
2694 if (UgaDraw != NULL) {\r
95276127 2695 //\r
3012ce5c 2696 // Graphics console driver can ensure the same mode for all GOP devices\r
2697 // so we can get the current mode from this video device\r
95276127 2698 //\r
3012ce5c 2699 UgaDraw->GetMode (\r
2700 UgaDraw,\r
2701 &UgaHorizontalResolution,\r
2702 &UgaVerticalResolution,\r
2703 &UgaColorDepth,\r
2704 &UgaRefreshRate\r
2705 );\r
2706\r
95276127 2707 CurrentGraphicsOutputMode->MaxMode = 1;\r
aec072ad 2708 Info = CurrentGraphicsOutputMode->Info;\r
2709 Info->Version = 0;\r
3012ce5c 2710 Info->HorizontalResolution = UgaHorizontalResolution;\r
2711 Info->VerticalResolution = UgaVerticalResolution;\r
aec072ad 2712 Info->PixelFormat = PixelBltOnly;\r
3012ce5c 2713 Info->PixelsPerScanLine = UgaHorizontalResolution;\r
95276127 2714 CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
2715 CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;\r
2716 CurrentGraphicsOutputMode->FrameBufferSize = 0;\r
2717\r
2718 //\r
2719 // Update the private mode buffer\r
2720 //\r
aec072ad 2721 CopyMem (&Private->GraphicsOutputModeBuffer[0], Info, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
95276127 2722\r
2723 //\r
aec072ad 2724 // Only mode 0 is available to be set\r
95276127 2725 //\r
3012ce5c 2726 CurrentIndex = 0;\r
95276127 2727 }\r
2728\r
aec072ad 2729Done:\r
2730\r
2731 if (GraphicsOutput != NULL) {\r
2732 Private->CurrentNumberOfGraphicsOutput++;\r
2733 }\r
2734 if (UgaDraw != NULL) {\r
2735 Private->CurrentNumberOfUgaDraw++;\r
2736 }\r
2737\r
95276127 2738 //\r
2739 // Force GraphicsOutput mode to be set,\r
2740 // regardless whether the console is in EfiConsoleControlScreenGraphics or EfiConsoleControlScreenText mode\r
2741 //\r
2742 Private->HardwareNeedsStarting = TRUE;\r
aec072ad 2743 //\r
2744 // Current mode number may need update now, so set it to an invalid mode number\r
2745 //\r
3012ce5c 2746 CurrentGraphicsOutputMode->Mode = 0xffff;\r
2747 //\r
2748 // Graphics console can ensure all GOP devices have the same mode which can be taken as current mode.\r
2749 //\r
2750 Status = Private->GraphicsOutput.SetMode (&Private->GraphicsOutput, (UINT32) CurrentIndex);\r
2751\r
2752 //\r
2753 // If user defined mode is not valid for UGA, set to the default mode 800x600.\r
2754 //\r
2755 if (EFI_ERROR(Status)) {\r
2756 (Private->GraphicsOutputModeBuffer[0]).HorizontalResolution = 800;\r
2757 (Private->GraphicsOutputModeBuffer[0]).VerticalResolution = 600;\r
2758 Status = Private->GraphicsOutput.SetMode (&Private->GraphicsOutput, 0);\r
2759 }\r
95276127 2760\r
95276127 2761 return Status;\r
2762}\r
2763\r
2764EFI_STATUS\r
2765ConSplitterTextOutAddDevice (\r
2766 IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
2767 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut,\r
2768 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
2769 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw\r
2770 )\r
2771/*++\r
2772\r
2773Routine Description:\r
2774\r
2775Arguments:\r
2776\r
2777Returns:\r
2778\r
2779 None\r
2780\r
2781--*/\r
2782{\r
2783 EFI_STATUS Status;\r
2784 UINTN CurrentNumOfConsoles;\r
2785 INT32 CurrentMode;\r
2786 INT32 MaxMode;\r
3012ce5c 2787 UINT32 UgaHorizontalResolution;\r
2788 UINT32 UgaVerticalResolution;\r
2789 UINT32 UgaColorDepth;\r
2790 UINT32 UgaRefreshRate;\r
95276127 2791 TEXT_OUT_AND_GOP_DATA *TextAndGop;\r
2792\r
2793 Status = EFI_SUCCESS;\r
2794 CurrentNumOfConsoles = Private->CurrentNumberOfConsoles;\r
2795\r
2796 //\r
2797 // If the Text Out List is full, enlarge it by calling growbuffer().\r
2798 //\r
2799 while (CurrentNumOfConsoles >= Private->TextOutListCount) {\r
2800 Status = ConSplitterGrowBuffer (\r
2801 sizeof (TEXT_OUT_AND_GOP_DATA),\r
2802 &Private->TextOutListCount,\r
2803 (VOID **) &Private->TextOutList\r
2804 );\r
2805 if (EFI_ERROR (Status)) {\r
2806 return EFI_OUT_OF_RESOURCES;\r
2807 }\r
2808 //\r
2809 // Also need to reallocate the TextOutModeMap table\r
2810 //\r
2811 Status = ConSplitterGrowMapTable (Private);\r
2812 if (EFI_ERROR (Status)) {\r
2813 return EFI_OUT_OF_RESOURCES;\r
2814 }\r
2815 }\r
2816\r
2817 TextAndGop = &Private->TextOutList[CurrentNumOfConsoles];\r
2818\r
2819 TextAndGop->TextOut = TextOut;\r
2820 TextAndGop->GraphicsOutput = GraphicsOutput;\r
2821 TextAndGop->UgaDraw = UgaDraw;\r
2822\r
2823 if ((GraphicsOutput == NULL) && (UgaDraw == NULL)) {\r
2824 //\r
3012ce5c 2825 // If No GOP/UGA device then use the ConOut device\r
95276127 2826 //\r
2827 TextAndGop->TextOutEnabled = TRUE;\r
2828 } else {\r
2829 //\r
3012ce5c 2830 // If GOP/UGA device use ConOut device only used if screen is in Text mode\r
95276127 2831 //\r
2832 TextAndGop->TextOutEnabled = (BOOLEAN) (Private->ConsoleOutputMode == EfiConsoleControlScreenText);\r
2833 }\r
2834\r
2835 if (CurrentNumOfConsoles == 0) {\r
2836 //\r
2837 // Add the first device's output mode to console splitter's mode list\r
2838 //\r
2839 Status = ConSplitterAddOutputMode (Private, TextOut);\r
2840 } else {\r
2841 ConSplitterSyncOutputMode (Private, TextOut);\r
2842 }\r
2843\r
2844 Private->CurrentNumberOfConsoles++;\r
2845\r
2846 //\r
2847 // Scan both TextOutList, for the intersection TextOut device\r
2848 // maybe both ConOut and StdErr incorporate the same Text Out\r
2849 // device in them, thus the output of both should be synced.\r
2850 //\r
2851 ConSplitterGetIntersectionBetweenConOutAndStrErr ();\r
2852\r
2853 CurrentMode = Private->TextOutMode.Mode;\r
2854 MaxMode = Private->TextOutMode.MaxMode;\r
2855 ASSERT (MaxMode >= 1);\r
2856\r
3012ce5c 2857 //\r
2858 // Update DevNull mode according to current video device\r
2859 //\r
d0c64728 2860 if (FeaturePcdGet (PcdConOutGopSupport)) {\r
2861 if ((GraphicsOutput != NULL) || (UgaDraw != NULL)) {\r
2862 ConSplitterAddGraphicsOutputMode (Private, GraphicsOutput, UgaDraw);\r
2863 }\r
95276127 2864 }\r
3012ce5c 2865 if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
2866 if (UgaDraw != NULL) {\r
2867 Status = UgaDraw->GetMode (\r
2868 UgaDraw,\r
2869 &UgaHorizontalResolution,\r
2870 &UgaVerticalResolution,\r
2871 &UgaColorDepth,\r
2872 &UgaRefreshRate\r
2873 );\r
2874 if (!EFI_ERROR (Status)) {\r
2875 Status = ConSpliterUgaDrawSetMode (\r
2876 &Private->UgaDraw,\r
2877 UgaHorizontalResolution,\r
2878 UgaVerticalResolution,\r
2879 UgaColorDepth,\r
2880 UgaRefreshRate\r
2881 );\r
2882 }\r
2883 //\r
2884 // If GetMode/SetMode is failed, set to 800x600 mode\r
2885 //\r
2886 if(EFI_ERROR (Status)) {\r
2887 Status = ConSpliterUgaDrawSetMode (\r
2888 &Private->UgaDraw,\r
2889 800,\r
2890 600,\r
2891 32,\r
2892 60\r
2893 );\r
2894 }\r
2895 }\r
2896 }\r
95276127 2897\r
2898 if (Private->ConsoleOutputMode == EfiConsoleControlScreenGraphics && GraphicsOutput != NULL) {\r
2899 //\r
3012ce5c 2900 // We just added a new GOP or UGA device in graphics mode\r
95276127 2901 //\r
d0c64728 2902 if (FeaturePcdGet (PcdConOutGopSupport)) {\r
2903 DevNullGopSync (Private, TextAndGop->GraphicsOutput, TextAndGop->UgaDraw);\r
2904 } else if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
2905 DevNullUgaSync (Private, TextAndGop->GraphicsOutput, TextAndGop->UgaDraw);\r
2906 }\r
95276127 2907 } else if ((CurrentMode >= 0) && ((GraphicsOutput != NULL) || (UgaDraw != NULL)) && (CurrentMode < Private->TextOutMode.MaxMode)) {\r
2908 //\r
2909 // The new console supports the same mode of the current console so sync up\r
2910 //\r
aec072ad 2911 DevNullSyncStdOut (Private);\r
95276127 2912 } else {\r
2913 //\r
2914 // If ConOut, then set the mode to Mode #0 which us 80 x 25\r
2915 //\r
2916 Private->TextOut.SetMode (&Private->TextOut, 0);\r
2917 }\r
2918\r
2919 return Status;\r
2920}\r
2921\r
2922EFI_STATUS\r
2923ConSplitterTextOutDeleteDevice (\r
2924 IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
2925 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut\r
2926 )\r
2927/*++\r
2928\r
2929Routine Description:\r
2930\r
2931Arguments:\r
2932\r
2933Returns:\r
2934\r
2935 None\r
2936\r
2937--*/\r
2938{\r
2939 INT32 Index;\r
2940 UINTN CurrentNumOfConsoles;\r
2941 TEXT_OUT_AND_GOP_DATA *TextOutList;\r
2942 EFI_STATUS Status;\r
2943\r
2944 //\r
2945 // Remove the specified text-out device data structure from the Text out List,\r
2946 // and rearrange the remaining data structures in the Text out List.\r
2947 //\r
2948 CurrentNumOfConsoles = Private->CurrentNumberOfConsoles;\r
2949 Index = (INT32) CurrentNumOfConsoles - 1;\r
2950 TextOutList = Private->TextOutList;\r
2951 while (Index >= 0) {\r
2952 if (TextOutList->TextOut == TextOut) {\r
2953 CopyMem (TextOutList, TextOutList + 1, sizeof (TEXT_OUT_AND_GOP_DATA) * Index);\r
2954 CurrentNumOfConsoles--;\r
aec072ad 2955 if (TextOutList->UgaDraw != NULL) {\r
2956 Private->CurrentNumberOfUgaDraw--;\r
2957 }\r
2958 if (TextOutList->GraphicsOutput != NULL) {\r
2959 Private->CurrentNumberOfGraphicsOutput--;\r
2960 }\r
95276127 2961 break;\r
2962 }\r
2963\r
2964 Index--;\r
2965 TextOutList++;\r
2966 }\r
2967 //\r
2968 // The specified TextOut is not managed by the ConSplitter driver\r
2969 //\r
2970 if (Index < 0) {\r
2971 return EFI_NOT_FOUND;\r
2972 }\r
2973\r
2974 if (CurrentNumOfConsoles == 0) {\r
2975 //\r
2976 // If the number of consoles is zero clear the Dev NULL device\r
2977 //\r
2978 Private->CurrentNumberOfConsoles = 0;\r
2979 Private->TextOutMode.MaxMode = 1;\r
2980 Private->TextOutQueryData[0].Columns = 80;\r
2981 Private->TextOutQueryData[0].Rows = 25;\r
2982 DevNullTextOutSetMode (Private, 0);\r
2983\r
2984 return EFI_SUCCESS;\r
2985 }\r
2986 //\r
2987 // Max Mode is realy an intersection of the QueryMode command to all\r
2988 // devices. So we must copy the QueryMode of the first device to\r
2989 // QueryData.\r
2990 //\r
2991 ZeroMem (\r
2992 Private->TextOutQueryData,\r
2993 Private->TextOutQueryDataCount * sizeof (TEXT_OUT_SPLITTER_QUERY_DATA)\r
2994 );\r
2995\r
2996 FreePool (Private->TextOutModeMap);\r
2997 Private->TextOutModeMap = NULL;\r
2998 TextOutList = Private->TextOutList;\r
2999\r
3000 //\r
3001 // Add the first TextOut to the QueryData array and ModeMap table\r
3002 //\r
3003 Status = ConSplitterAddOutputMode (Private, TextOutList->TextOut);\r
3004\r
3005 //\r
3006 // Now add one by one\r
3007 //\r
3008 Index = 1;\r
3009 Private->CurrentNumberOfConsoles = 1;\r
3010 TextOutList++;\r
3011 while ((UINTN) Index < CurrentNumOfConsoles) {\r
3012 ConSplitterSyncOutputMode (Private, TextOutList->TextOut);\r
3013 Index++;\r
3014 Private->CurrentNumberOfConsoles++;\r
3015 TextOutList++;\r
3016 }\r
3017\r
3018 ConSplitterGetIntersectionBetweenConOutAndStrErr ();\r
3019\r
3020 return Status;\r
3021}\r
3022//\r
3023// ConSplitter TextIn member functions\r
3024//\r
3025EFI_STATUS\r
3026EFIAPI\r
3027ConSplitterTextInReset (\r
3028 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
3029 IN BOOLEAN ExtendedVerification\r
3030 )\r
3031/*++\r
3032\r
3033 Routine Description:\r
3034 Reset the input device and optionaly run diagnostics\r
3035\r
3036 Arguments:\r
3037 This - Protocol instance pointer.\r
3038 ExtendedVerification - Driver may perform diagnostics on reset.\r
3039\r
3040 Returns:\r
3041 EFI_SUCCESS - The device was reset.\r
3042 EFI_DEVICE_ERROR - The device is not functioning properly and could\r
3043 not be reset.\r
3044\r
3045--*/\r
3046{\r
3047 EFI_STATUS Status;\r
3048 EFI_STATUS ReturnStatus;\r
3049 TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
3050 UINTN Index;\r
3051\r
3052 Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
3053\r
3054 Private->KeyEventSignalState = FALSE;\r
3055\r
3056 //\r
3057 // return the worst status met\r
3058 //\r
3059 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
3060 Status = Private->TextInList[Index]->Reset (\r
3061 Private->TextInList[Index],\r
3062 ExtendedVerification\r
3063 );\r
3064 if (EFI_ERROR (Status)) {\r
3065 ReturnStatus = Status;\r
3066 }\r
3067 }\r
3068\r
3069 return ReturnStatus;\r
3070}\r
3071\r
3072EFI_STATUS\r
3073EFIAPI\r
3074ConSplitterTextInPrivateReadKeyStroke (\r
3075 IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
3076 OUT EFI_INPUT_KEY *Key\r
3077 )\r
3078/*++\r
3079\r
3080 Routine Description:\r
3081 Reads the next keystroke from the input device. The WaitForKey Event can\r
3082 be used to test for existance of a keystroke via WaitForEvent () call.\r
3083\r
3084 Arguments:\r
3085 This - Protocol instance pointer.\r
3086 Key - Driver may perform diagnostics on reset.\r
3087\r
3088 Returns:\r
3089 EFI_SUCCESS - The keystroke information was returned.\r
3090 EFI_NOT_READY - There was no keystroke data availiable.\r
3091 EFI_DEVICE_ERROR - The keydtroke information was not returned due to\r
3092 hardware errors.\r
3093\r
3094--*/\r
3095{\r
3096 EFI_STATUS Status;\r
3097 UINTN Index;\r
3098 EFI_INPUT_KEY CurrentKey;\r
3099\r
3100 Key->UnicodeChar = 0;\r
3101 Key->ScanCode = SCAN_NULL;\r
3102\r
3103 //\r
3104 // if no physical console input device exists, return EFI_NOT_READY;\r
3105 // if any physical console input device has key input,\r
3106 // return the key and EFI_SUCCESS.\r
3107 //\r
3108 for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
3109 Status = Private->TextInList[Index]->ReadKeyStroke (\r
3110 Private->TextInList[Index],\r
3111 &CurrentKey\r
3112 );\r
3113 if (!EFI_ERROR (Status)) {\r
3114 *Key = CurrentKey;\r
3115 return Status;\r
3116 }\r
3117 }\r
3118\r
3119 return EFI_NOT_READY;\r
3120}\r
3121\r
3122BOOLEAN\r
3123ConSpliterConssoleControlStdInLocked (\r
3124 VOID\r
3125 )\r
3126/*++\r
3127\r
3128Routine Description:\r
3129 Return TRUE if StdIn is locked. The ConIn device on the virtual handle is\r
3130 the only device locked.\r
3131\r
3132Arguments:\r
3133 NONE\r
3134\r
3135Returns:\r
3136 TRUE - StdIn locked\r
3137 FALSE - StdIn working normally\r
3138\r
3139--*/\r
3140{\r
3141 return mConIn.PasswordEnabled;\r
3142}\r
3143\r
3144VOID\r
3145EFIAPI\r
3146ConSpliterConsoleControlLockStdInEvent (\r
3147 IN EFI_EVENT Event,\r
3148 IN VOID *Context\r
3149 )\r
3150/*++\r
3151\r
3152Routine Description:\r
3153 This timer event will fire when StdIn is locked. It will check the key\r
3154 sequence on StdIn to see if it matches the password. Any error in the\r
3155 password will cause the check to reset. As long a mConIn.PasswordEnabled is\r
3156 TRUE the StdIn splitter will not report any input.\r
3157\r
3158Arguments:\r
3159 (Standard EFI_EVENT_NOTIFY)\r
3160\r
3161Returns:\r
3162 None\r
3163\r
3164--*/\r
3165{\r
3166 EFI_STATUS Status;\r
3167 EFI_INPUT_KEY Key;\r
3168 CHAR16 BackSpaceString[2];\r
3169 CHAR16 SpaceString[2];\r
3170\r
3171 do {\r
3172 Status = ConSplitterTextInPrivateReadKeyStroke (&mConIn, &Key);\r
3173 if (!EFI_ERROR (Status)) {\r
3174 //\r
3175 // if it's an ENTER, match password\r
3176 //\r
3177 if ((Key.UnicodeChar == CHAR_CARRIAGE_RETURN) && (Key.ScanCode == SCAN_NULL)) {\r
3178 mConIn.PwdAttempt[mConIn.PwdIndex] = CHAR_NULL;\r
3179 if (StrCmp (mConIn.Password, mConIn.PwdAttempt)) {\r
3180 //\r
3181 // Password not match\r
3182 //\r
3183 ConSplitterTextOutOutputString (&mConOut.TextOut, (CHAR16 *) L"\n\rPassword not correct\n\r");\r
3184 mConIn.PwdIndex = 0;\r
3185 } else {\r
3186 //\r
3187 // Key matches password sequence\r
3188 //\r
3189 gBS->SetTimer (mConIn.LockEvent, TimerPeriodic, 0);\r
3190 mConIn.PasswordEnabled = FALSE;\r
3191 Status = EFI_NOT_READY;\r
3192 }\r
3193 } else if ((Key.UnicodeChar == CHAR_BACKSPACE) && (Key.ScanCode == SCAN_NULL)) {\r
3194 //\r
3195 // BackSpace met\r
3196 //\r
3197 if (mConIn.PwdIndex > 0) {\r
3198 BackSpaceString[0] = CHAR_BACKSPACE;\r
3199 BackSpaceString[1] = 0;\r
3200\r
3201 SpaceString[0] = ' ';\r
3202 SpaceString[1] = 0;\r
3203\r
3204 ConSplitterTextOutOutputString (&mConOut.TextOut, BackSpaceString);\r
3205 ConSplitterTextOutOutputString (&mConOut.TextOut, SpaceString);\r
3206 ConSplitterTextOutOutputString (&mConOut.TextOut, BackSpaceString);\r
3207\r
3208 mConIn.PwdIndex--;\r
3209 }\r
3210 } else if ((Key.ScanCode == SCAN_NULL) && (Key.UnicodeChar >= 32)) {\r
3211 //\r
3212 // If it's not an ENTER, neigher a function key, nor a CTRL-X or ALT-X, record the input\r
3213 //\r
3214 if (mConIn.PwdIndex < (MAX_STD_IN_PASSWORD - 1)) {\r
3215 if (mConIn.PwdIndex == 0) {\r
3216 ConSplitterTextOutOutputString (&mConOut.TextOut, (CHAR16 *) L"\n\r");\r
3217 }\r
3218\r
3219 ConSplitterTextOutOutputString (&mConOut.TextOut, (CHAR16 *) L"*");\r
3220 mConIn.PwdAttempt[mConIn.PwdIndex] = Key.UnicodeChar;\r
3221 mConIn.PwdIndex++;\r
3222 }\r
3223 }\r
3224 }\r
3225 } while (!EFI_ERROR (Status));\r
3226}\r
3227\r
3228EFI_STATUS\r
3229EFIAPI\r
3230ConSpliterConsoleControlLockStdIn (\r
3231 IN EFI_CONSOLE_CONTROL_PROTOCOL *This,\r
3232 IN CHAR16 *Password\r
3233 )\r
3234/*++\r
3235\r
3236Routine Description:\r
3237 If Password is NULL unlock the password state variable and set the event\r
3238 timer. If the Password is too big return an error. If the Password is valid\r
3239 Copy the Password and enable state variable and then arm the periodic timer\r
3240\r
3241Arguments:\r
3242\r
3243Returns:\r
3244 EFI_SUCCESS - Lock the StdIn device\r
3245 EFI_INVALID_PARAMETER - Password is NULL\r
3246 EFI_OUT_OF_RESOURCES - Buffer allocation to store the password fails\r
3247\r
3248--*/\r
3249{\r
3250 if (Password == NULL) {\r
3251 return EFI_INVALID_PARAMETER;\r
3252 }\r
3253\r
3254 if (StrLen (Password) >= MAX_STD_IN_PASSWORD) {\r
3255 //\r
3256 // Currently have a max password size\r
3257 //\r
3258 return EFI_OUT_OF_RESOURCES;\r
3259 }\r
3260 //\r
3261 // Save the password, initialize state variables and arm event timer\r
3262 //\r
3263 StrCpy (mConIn.Password, Password);\r
3264 mConIn.PasswordEnabled = TRUE;\r
3265 mConIn.PwdIndex = 0;\r
3266 gBS->SetTimer (mConIn.LockEvent, TimerPeriodic, (10000 * 25));\r
3267\r
3268 return EFI_SUCCESS;\r
3269}\r
3270\r
3271EFI_STATUS\r
3272EFIAPI\r
3273ConSplitterTextInReadKeyStroke (\r
3274 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
3275 OUT EFI_INPUT_KEY *Key\r
3276 )\r
3277/*++\r
3278\r
3279 Routine Description:\r
3280 Reads the next keystroke from the input device. The WaitForKey Event can\r
3281 be used to test for existance of a keystroke via WaitForEvent () call.\r
3282 If the ConIn is password locked make it look like no keystroke is availible\r
3283\r
3284 Arguments:\r
3285 This - Protocol instance pointer.\r
3286 Key - Driver may perform diagnostics on reset.\r
3287\r
3288 Returns:\r
3289 EFI_SUCCESS - The keystroke information was returned.\r
3290 EFI_NOT_READY - There was no keystroke data availiable.\r
3291 EFI_DEVICE_ERROR - The keydtroke information was not returned due to\r
3292 hardware errors.\r
3293\r
3294--*/\r
3295{\r
3296 TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
3297\r
3298 Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
3299 if (Private->PasswordEnabled) {\r
3300 //\r
3301 // If StdIn Locked return not ready\r
3302 //\r
3303 return EFI_NOT_READY;\r
3304 }\r
3305\r
3306 Private->KeyEventSignalState = FALSE;\r
3307\r
3308 return ConSplitterTextInPrivateReadKeyStroke (Private, Key);\r
3309}\r
3310\r
3311VOID\r
3312EFIAPI\r
3313ConSplitterTextInWaitForKey (\r
3314 IN EFI_EVENT Event,\r
3315 IN VOID *Context\r
3316 )\r
3317/*++\r
3318\r
3319Routine Description:\r
3320 This event agregates all the events of the ConIn devices in the spliter.\r
3321 If the ConIn is password locked then return.\r
3322 If any events of physical ConIn devices are signaled, signal the ConIn\r
3323 spliter event. This will cause the calling code to call\r
3324 ConSplitterTextInReadKeyStroke ().\r
3325\r
3326Arguments:\r
3327 Event - The Event assoicated with callback.\r
3328 Context - Context registered when Event was created.\r
3329\r
3330Returns:\r
3331 None\r
3332\r
3333--*/\r
3334{\r
3335 EFI_STATUS Status;\r
3336 TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
3337 UINTN Index;\r
3338\r
3339 Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *) Context;\r
3340 if (Private->PasswordEnabled) {\r
3341 //\r
3342 // If StdIn Locked return not ready\r
3343 //\r
3344 return ;\r
3345 }\r
3346\r
3347 //\r
3348 // if KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()\r
3349 //\r
3350 if (Private->KeyEventSignalState) {\r
3351 gBS->SignalEvent (Event);\r
3352 return ;\r
3353 }\r
3354 //\r
3355 // if any physical console input device has key input, signal the event.\r
3356 //\r
3357 for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
3358 Status = gBS->CheckEvent (Private->TextInList[Index]->WaitForKey);\r
3359 if (!EFI_ERROR (Status)) {\r
3360 gBS->SignalEvent (Event);\r
3361 Private->KeyEventSignalState = TRUE;\r
3362 }\r
3363 }\r
3364}\r
3365\r
66aa04e4 3366\r
3367STATIC\r
3368BOOLEAN\r
3369IsKeyRegistered (\r
3370 IN EFI_KEY_DATA *RegsiteredData,\r
3371 IN EFI_KEY_DATA *InputData\r
3372 )\r
3373/*++\r
3374\r
3375Routine Description:\r
3376\r
3377Arguments:\r
3378\r
7a5064ce 3379 RegsiteredData - A pointer to a buffer that is filled in with the keystroke\r
66aa04e4 3380 state data for the key that was registered.\r
7a5064ce 3381 InputData - A pointer to a buffer that is filled in with the keystroke\r
66aa04e4 3382 state data for the key that was pressed.\r
3383\r
3384Returns:\r
3385 TRUE - Key be pressed matches a registered key.\r
7a5064ce 3386 FLASE - Match failed.\r
3387\r
66aa04e4 3388--*/\r
3389{\r
3390 ASSERT (RegsiteredData != NULL && InputData != NULL);\r
7a5064ce 3391\r
66aa04e4 3392 if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||\r
3393 (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
7a5064ce 3394 return FALSE;\r
3395 }\r
3396\r
66aa04e4 3397 //\r
3398 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.\r
3399 //\r
3400 if (RegsiteredData->KeyState.KeyShiftState != 0 &&\r
3401 RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {\r
7a5064ce 3402 return FALSE;\r
3403 }\r
66aa04e4 3404 if (RegsiteredData->KeyState.KeyToggleState != 0 &&\r
3405 RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {\r
7a5064ce 3406 return FALSE;\r
3407 }\r
3408\r
66aa04e4 3409 return TRUE;\r
3410\r
3411}\r
3412\r
3413//\r
3414// Simple Text Input Ex protocol functions\r
3415//\r
3416\r
3417EFI_STATUS\r
3418EFIAPI\r
3419ConSplitterTextInResetEx (\r
3420 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
3421 IN BOOLEAN ExtendedVerification\r
3422 )\r
3423/*++\r
3424\r
3425 Routine Description:\r
3426 Reset the input device and optionaly run diagnostics\r
3427\r
3428 Arguments:\r
3429 This - Protocol instance pointer.\r
3430 ExtendedVerification - Driver may perform diagnostics on reset.\r
3431\r
3432 Returns:\r
3433 EFI_SUCCESS - The device was reset.\r
7a5064ce 3434 EFI_DEVICE_ERROR - The device is not functioning properly and could\r
66aa04e4 3435 not be reset.\r
3436\r
3437--*/\r
3438{\r
3439 EFI_STATUS Status;\r
3440 EFI_STATUS ReturnStatus;\r
3441 TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
3442 UINTN Index;\r
3443\r
3444 Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
3445\r
3446 Private->KeyEventSignalState = FALSE;\r
3447\r
3448 //\r
3449 // return the worst status met\r
3450 //\r
3451 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
3452 Status = Private->TextInExList[Index]->Reset (\r
3453 Private->TextInExList[Index],\r
3454 ExtendedVerification\r
3455 );\r
3456 if (EFI_ERROR (Status)) {\r
3457 ReturnStatus = Status;\r
3458 }\r
3459 }\r
3460\r
3461 return ReturnStatus;\r
3462\r
3463}\r
3464\r
3465EFI_STATUS\r
3466EFIAPI\r
3467ConSplitterTextInReadKeyStrokeEx (\r
3468 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
3469 OUT EFI_KEY_DATA *KeyData\r
3470 )\r
3471/*++\r
3472\r
3473 Routine Description:\r
7a5064ce 3474 Reads the next keystroke from the input device. The WaitForKey Event can\r
66aa04e4 3475 be used to test for existance of a keystroke via WaitForEvent () call.\r
3476\r
3477 Arguments:\r
3478 This - Protocol instance pointer.\r
7a5064ce 3479 KeyData - A pointer to a buffer that is filled in with the keystroke\r
66aa04e4 3480 state data for the key that was pressed.\r
3481\r
3482 Returns:\r
3483 EFI_SUCCESS - The keystroke information was returned.\r
3484 EFI_NOT_READY - There was no keystroke data availiable.\r
7a5064ce 3485 EFI_DEVICE_ERROR - The keystroke information was not returned due to\r
66aa04e4 3486 hardware errors.\r
7a5064ce 3487 EFI_INVALID_PARAMETER - KeyData is NULL.\r
66aa04e4 3488\r
3489--*/\r
3490{\r
3491 TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
3492 EFI_STATUS Status;\r
3493 UINTN Index;\r
3494 EFI_KEY_DATA CurrentKeyData;\r
3495\r
7a5064ce 3496\r
66aa04e4 3497 if (KeyData == NULL) {\r
3498 return EFI_INVALID_PARAMETER;\r
3499 }\r
3500\r
3501 Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
3502 if (Private->PasswordEnabled) {\r
3503 //\r
3504 // If StdIn Locked return not ready\r
3505 //\r
3506 return EFI_NOT_READY;\r
3507 }\r
3508\r
3509 Private->KeyEventSignalState = FALSE;\r
3510\r
3511 KeyData->Key.UnicodeChar = 0;\r
3512 KeyData->Key.ScanCode = SCAN_NULL;\r
3513\r
3514 //\r
3515 // if no physical console input device exists, return EFI_NOT_READY;\r
3516 // if any physical console input device has key input,\r
3517 // return the key and EFI_SUCCESS.\r
3518 //\r
3519 for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
3520 Status = Private->TextInExList[Index]->ReadKeyStrokeEx (\r
3521 Private->TextInExList[Index],\r
3522 &CurrentKeyData\r
3523 );\r
3524 if (!EFI_ERROR (Status)) {\r
3525 CopyMem (KeyData, &CurrentKeyData, sizeof (CurrentKeyData));\r
3526 return Status;\r
3527 }\r
3528 }\r
3529\r
7a5064ce 3530 return EFI_NOT_READY;\r
66aa04e4 3531}\r
3532\r
3533EFI_STATUS\r
3534EFIAPI\r
3535ConSplitterTextInSetState (\r
3536 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
3537 IN EFI_KEY_TOGGLE_STATE *KeyToggleState\r
3538 )\r
3539/*++\r
3540\r
3541 Routine Description:\r
3542 Set certain state for the input device.\r
3543\r
3544 Arguments:\r
3545 This - Protocol instance pointer.\r
7a5064ce 3546 KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the\r
66aa04e4 3547 state for the input device.\r
7a5064ce 3548\r
3549 Returns:\r
66aa04e4 3550 EFI_SUCCESS - The device state was set successfully.\r
7a5064ce 3551 EFI_DEVICE_ERROR - The device is not functioning correctly and could\r
66aa04e4 3552 not have the setting adjusted.\r
3553 EFI_UNSUPPORTED - The device does not have the ability to set its state.\r
7a5064ce 3554 EFI_INVALID_PARAMETER - KeyToggleState is NULL.\r
66aa04e4 3555\r
7a5064ce 3556--*/\r
66aa04e4 3557{\r
3558 TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
3559 EFI_STATUS Status;\r
3560 UINTN Index;\r
3561\r
3562 if (KeyToggleState == NULL) {\r
3563 return EFI_INVALID_PARAMETER;\r
3564 }\r
3565\r
3566 Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
3567\r
3568 //\r
3569 // if no physical console input device exists, return EFI_SUCCESS;\r
3570 // otherwise return the status of setting state of physical console input device\r
3571 //\r
3572 for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
3573 Status = Private->TextInExList[Index]->SetState (\r
3574 Private->TextInExList[Index],\r
3575 KeyToggleState\r
3576 );\r
3577 if (EFI_ERROR (Status)) {\r
3578 return Status;\r
3579 }\r
3580 }\r
3581\r
7a5064ce 3582 return EFI_SUCCESS;\r
66aa04e4 3583\r
3584}\r
3585\r
3586EFI_STATUS\r
3587EFIAPI\r
3588ConSplitterTextInRegisterKeyNotify (\r
3589 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
3590 IN EFI_KEY_DATA *KeyData,\r
3591 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,\r
3592 OUT EFI_HANDLE *NotifyHandle\r
3593 )\r
3594/*++\r
3595\r
3596 Routine Description:\r
3597 Register a notification function for a particular keystroke for the input device.\r
3598\r
3599 Arguments:\r
3600 This - Protocol instance pointer.\r
7a5064ce 3601 KeyData - A pointer to a buffer that is filled in with the keystroke\r
66aa04e4 3602 information data for the key that was pressed.\r
7a5064ce 3603 KeyNotificationFunction - Points to the function to be called when the key\r
3604 sequence is typed specified by KeyData.\r
3605 NotifyHandle - Points to the unique handle assigned to the registered notification.\r
66aa04e4 3606\r
3607 Returns:\r
3608 EFI_SUCCESS - The notification function was registered successfully.\r
3609 EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures.\r
7a5064ce 3610 EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.\r
3611\r
3612--*/\r
66aa04e4 3613{\r
3614 TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
3615 EFI_STATUS Status;\r
3616 UINTN Index;\r
3617 TEXT_IN_EX_SPLITTER_NOTIFY *NewNotify;\r
3618 LIST_ENTRY *Link;\r
7a5064ce 3619 TEXT_IN_EX_SPLITTER_NOTIFY *CurrentNotify;\r
3620\r
66aa04e4 3621\r
3622 if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {\r
3623 return EFI_INVALID_PARAMETER;\r
3624 }\r
3625\r
3626 Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
3627\r
3628 //\r
7a5064ce 3629 // if no physical console input device exists,\r
66aa04e4 3630 // return EFI_SUCCESS directly.\r
3631 //\r
3632 if (Private->CurrentNumberOfExConsoles <= 0) {\r
3633 return EFI_SUCCESS;\r
3634 }\r
3635\r
3636 //\r
3637 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.\r
3638 //\r
3639 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
3640 CurrentNotify = CR (\r
7a5064ce 3641 Link,\r
3642 TEXT_IN_EX_SPLITTER_NOTIFY,\r
3643 NotifyEntry,\r
66aa04e4 3644 TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE\r
3645 );\r
7a5064ce 3646 if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
66aa04e4 3647 if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
7a5064ce 3648 *NotifyHandle = CurrentNotify->NotifyHandle;\r
66aa04e4 3649 return EFI_SUCCESS;\r
3650 }\r
3651 }\r
3652 }\r
7a5064ce 3653\r
66aa04e4 3654 //\r
3655 // Allocate resource to save the notification function\r
7a5064ce 3656 //\r
66aa04e4 3657 NewNotify = (TEXT_IN_EX_SPLITTER_NOTIFY *) AllocateZeroPool (sizeof (TEXT_IN_EX_SPLITTER_NOTIFY));\r
3658 if (NewNotify == NULL) {\r
3659 return EFI_OUT_OF_RESOURCES;\r
3660 }\r
3661 NewNotify->NotifyHandleList = (EFI_HANDLE *) AllocateZeroPool (sizeof (EFI_HANDLE) * Private->CurrentNumberOfExConsoles);\r
3662 if (NewNotify->NotifyHandleList == NULL) {\r
3663 gBS->FreePool (NewNotify);\r
3664 return EFI_OUT_OF_RESOURCES;\r
3665 }\r
7a5064ce 3666 NewNotify->Signature = TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE;\r
66aa04e4 3667 NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
3668 CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));\r
7a5064ce 3669\r
66aa04e4 3670 //\r
7a5064ce 3671 // Return the wrong status of registering key notify of\r
66aa04e4 3672 // physical console input device if meet problems\r
3673 //\r
3674 for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
3675 Status = Private->TextInExList[Index]->RegisterKeyNotify (\r
3676 Private->TextInExList[Index],\r
3677 KeyData,\r
3678 KeyNotificationFunction,\r
3679 &NewNotify->NotifyHandleList[Index]\r
3680 );\r
3681 if (EFI_ERROR (Status)) {\r
3682 gBS->FreePool (NewNotify->NotifyHandleList);\r
3683 gBS->FreePool (NewNotify);\r
3684 return Status;\r
3685 }\r
3686 }\r
3687\r
3688 //\r
3689 // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE\r
7a5064ce 3690 //\r
66aa04e4 3691 Status = gBS->InstallMultipleProtocolInterfaces (\r
3692 &NewNotify->NotifyHandle,\r
3693 &gSimpleTextInExNotifyGuid,\r
3694 NULL,\r
3695 NULL\r
3696 );\r
3697 ASSERT_EFI_ERROR (Status);\r
3698\r
3699 InsertTailList (&mConIn.NotifyList, &NewNotify->NotifyEntry);\r
7a5064ce 3700\r
3701 *NotifyHandle = NewNotify->NotifyHandle;\r
3702\r
3703 return EFI_SUCCESS;\r
3704\r
66aa04e4 3705}\r
3706\r
3707EFI_STATUS\r
3708EFIAPI\r
3709ConSplitterTextInUnregisterKeyNotify (\r
3710 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
3711 IN EFI_HANDLE NotificationHandle\r
3712 )\r
3713/*++\r
3714\r
3715 Routine Description:\r
3716 Remove a registered notification function from a particular keystroke.\r
3717\r
3718 Arguments:\r
7a5064ce 3719 This - Protocol instance pointer.\r
66aa04e4 3720 NotificationHandle - The handle of the notification function being unregistered.\r
3721\r
3722 Returns:\r
3723 EFI_SUCCESS - The notification function was unregistered successfully.\r
3724 EFI_INVALID_PARAMETER - The NotificationHandle is invalid.\r
7a5064ce 3725 EFI_NOT_FOUND - Can not find the matching entry in database.\r
3726\r
3727--*/\r
66aa04e4 3728{\r
3729 TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
3730 EFI_STATUS Status;\r
3731 UINTN Index;\r
3732 TEXT_IN_EX_SPLITTER_NOTIFY *CurrentNotify;\r
7a5064ce 3733 LIST_ENTRY *Link;\r
66aa04e4 3734\r
3735 if (NotificationHandle == NULL) {\r
3736 return EFI_INVALID_PARAMETER;\r
3737 }\r
3738\r
3739 Status = gBS->OpenProtocol (\r
3740 NotificationHandle,\r
3741 &gSimpleTextInExNotifyGuid,\r
3742 NULL,\r
3743 NULL,\r
3744 NULL,\r
3745 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
3746 );\r
3747 if (EFI_ERROR (Status)) {\r
3748 return EFI_INVALID_PARAMETER;\r
3749 }\r
3750\r
3751 Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
3752\r
3753 //\r
7a5064ce 3754 // if no physical console input device exists,\r
66aa04e4 3755 // return EFI_SUCCESS directly.\r
3756 //\r
3757 if (Private->CurrentNumberOfExConsoles <= 0) {\r
3758 return EFI_SUCCESS;\r
3759 }\r
3760\r
3761 for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
3762 CurrentNotify = CR (Link, TEXT_IN_EX_SPLITTER_NOTIFY, NotifyEntry, TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE);\r
3763 if (CurrentNotify->NotifyHandle == NotificationHandle) {\r
3764 for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
3765 Status = Private->TextInExList[Index]->UnregisterKeyNotify (\r
7a5064ce 3766 Private->TextInExList[Index],\r
66aa04e4 3767 CurrentNotify->NotifyHandleList[Index]\r
3768 );\r
3769 if (EFI_ERROR (Status)) {\r
3770 return Status;\r
7a5064ce 3771 }\r
66aa04e4 3772 }\r
7a5064ce 3773 RemoveEntryList (&CurrentNotify->NotifyEntry);\r
66aa04e4 3774 Status = gBS->UninstallMultipleProtocolInterfaces (\r
3775 CurrentNotify->NotifyHandle,\r
3776 &gSimpleTextInExNotifyGuid,\r
3777 NULL,\r
3778 NULL\r
3779 );\r
3780 ASSERT_EFI_ERROR (Status);\r
3781 gBS->FreePool (CurrentNotify->NotifyHandleList);\r
3782 gBS->FreePool (CurrentNotify);\r
7a5064ce 3783 return EFI_SUCCESS;\r
3784 }\r
66aa04e4 3785 }\r
3786\r
7a5064ce 3787 return EFI_NOT_FOUND;\r
3788\r
66aa04e4 3789}\r
3790\r
95276127 3791EFI_STATUS\r
3792EFIAPI\r
3793ConSplitterSimplePointerReset (\r
3794 IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
3795 IN BOOLEAN ExtendedVerification\r
3796 )\r
3797/*++\r
3798\r
3799 Routine Description:\r
3800 Reset the input device and optionaly run diagnostics\r
3801\r
3802 Arguments:\r
3803 This - Protocol instance pointer.\r
3804 ExtendedVerification - Driver may perform diagnostics on reset.\r
3805\r
3806 Returns:\r
3807 EFI_SUCCESS - The device was reset.\r
3808 EFI_DEVICE_ERROR - The device is not functioning properly and could\r
3809 not be reset.\r
3810\r
3811--*/\r
3812{\r
3813 EFI_STATUS Status;\r
3814 EFI_STATUS ReturnStatus;\r
3815 TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
3816 UINTN Index;\r
3817\r
3818 Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This);\r
3819\r
3820 Private->InputEventSignalState = FALSE;\r
3821\r
3822 if (Private->CurrentNumberOfPointers == 0) {\r
3823 return EFI_SUCCESS;\r
3824 }\r
3825 //\r
3826 // return the worst status met\r
3827 //\r
3828 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfPointers; Index++) {\r
3829 Status = Private->PointerList[Index]->Reset (\r
3830 Private->PointerList[Index],\r
3831 ExtendedVerification\r
3832 );\r
3833 if (EFI_ERROR (Status)) {\r
3834 ReturnStatus = Status;\r
3835 }\r
3836 }\r
3837\r
3838 return ReturnStatus;\r
3839}\r
3840\r
3841STATIC\r
3842EFI_STATUS\r
3843EFIAPI\r
3844ConSplitterSimplePointerPrivateGetState (\r
3845 IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
3846 IN OUT EFI_SIMPLE_POINTER_STATE *State\r
3847 )\r
3848/*++\r
3849\r
3850 Routine Description:\r
3851 Reads the next keystroke from the input device. The WaitForKey Event can\r
3852 be used to test for existance of a keystroke via WaitForEvent () call.\r
3853\r
3854 Arguments:\r
3855 This - Protocol instance pointer.\r
3856 State -\r
3857\r
3858 Returns:\r
3859 EFI_SUCCESS - The keystroke information was returned.\r
3860 EFI_NOT_READY - There was no keystroke data availiable.\r
3861 EFI_DEVICE_ERROR - The keydtroke information was not returned due to\r
3862 hardware errors.\r
3863\r
3864--*/\r
3865{\r
3866 EFI_STATUS Status;\r
3867 EFI_STATUS ReturnStatus;\r
3868 UINTN Index;\r
3869 EFI_SIMPLE_POINTER_STATE CurrentState;\r
3870\r
3871 State->RelativeMovementX = 0;\r
3872 State->RelativeMovementY = 0;\r
3873 State->RelativeMovementZ = 0;\r
3874 State->LeftButton = FALSE;\r
3875 State->RightButton = FALSE;\r
3876\r
3877 //\r
3878 // if no physical console input device exists, return EFI_NOT_READY;\r
3879 // if any physical console input device has key input,\r
3880 // return the key and EFI_SUCCESS.\r
3881 //\r
3882 ReturnStatus = EFI_NOT_READY;\r
3883 for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {\r
3884\r
3885 Status = Private->PointerList[Index]->GetState (\r
3886 Private->PointerList[Index],\r
3887 &CurrentState\r
3888 );\r
3889 if (!EFI_ERROR (Status)) {\r
3890 if (ReturnStatus == EFI_NOT_READY) {\r
3891 ReturnStatus = EFI_SUCCESS;\r
3892 }\r
3893\r
3894 if (CurrentState.LeftButton) {\r
3895 State->LeftButton = TRUE;\r
3896 }\r
3897\r
3898 if (CurrentState.RightButton) {\r
3899 State->RightButton = TRUE;\r
3900 }\r
3901\r
3902 if (CurrentState.RelativeMovementX != 0 && Private->PointerList[Index]->Mode->ResolutionX != 0) {\r
3903 State->RelativeMovementX += (CurrentState.RelativeMovementX * (INT32) Private->SimplePointerMode.ResolutionX) / (INT32) Private->PointerList[Index]->Mode->ResolutionX;\r
3904 }\r
3905\r
3906 if (CurrentState.RelativeMovementY != 0 && Private->PointerList[Index]->Mode->ResolutionY != 0) {\r
3907 State->RelativeMovementY += (CurrentState.RelativeMovementY * (INT32) Private->SimplePointerMode.ResolutionY) / (INT32) Private->PointerList[Index]->Mode->ResolutionY;\r
3908 }\r
3909\r
3910 if (CurrentState.RelativeMovementZ != 0 && Private->PointerList[Index]->Mode->ResolutionZ != 0) {\r
3911 State->RelativeMovementZ += (CurrentState.RelativeMovementZ * (INT32) Private->SimplePointerMode.ResolutionZ) / (INT32) Private->PointerList[Index]->Mode->ResolutionZ;\r
3912 }\r
3913 } else if (Status == EFI_DEVICE_ERROR) {\r
3914 ReturnStatus = EFI_DEVICE_ERROR;\r
3915 }\r
3916 }\r
3917\r
3918 return ReturnStatus;\r
3919}\r
3920\r
3921EFI_STATUS\r
3922EFIAPI\r
3923ConSplitterSimplePointerGetState (\r
3924 IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
3925 IN OUT EFI_SIMPLE_POINTER_STATE *State\r
3926 )\r
3927/*++\r
3928\r
3929 Routine Description:\r
3930 Reads the next keystroke from the input device. The WaitForKey Event can\r
3931 be used to test for existance of a keystroke via WaitForEvent () call.\r
3932 If the ConIn is password locked make it look like no keystroke is availible\r
3933\r
3934 Arguments:\r
3935 This - Protocol instance pointer.\r
3936 State -\r
3937\r
3938 Returns:\r
3939 EFI_SUCCESS - The keystroke information was returned.\r
3940 EFI_NOT_READY - There was no keystroke data availiable.\r
3941 EFI_DEVICE_ERROR - The keydtroke information was not returned due to\r
3942 hardware errors.\r
3943\r
3944--*/\r
3945{\r
3946 TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
3947\r
3948 Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This);\r
3949 if (Private->PasswordEnabled) {\r
3950 //\r
3951 // If StdIn Locked return not ready\r
3952 //\r
3953 return EFI_NOT_READY;\r
3954 }\r
3955\r
3956 Private->InputEventSignalState = FALSE;\r
3957\r
3958 return ConSplitterSimplePointerPrivateGetState (Private, State);\r
3959}\r
3960\r
3961VOID\r
3962EFIAPI\r
3963ConSplitterSimplePointerWaitForInput (\r
3964 IN EFI_EVENT Event,\r
3965 IN VOID *Context\r
3966 )\r
3967/*++\r
3968\r
3969Routine Description:\r
3970 This event agregates all the events of the ConIn devices in the spliter.\r
3971 If the ConIn is password locked then return.\r
3972 If any events of physical ConIn devices are signaled, signal the ConIn\r
3973 spliter event. This will cause the calling code to call\r
3974 ConSplitterTextInReadKeyStroke ().\r
3975\r
3976Arguments:\r
3977 Event - The Event assoicated with callback.\r
3978 Context - Context registered when Event was created.\r
3979\r
3980Returns:\r
3981 None\r
3982\r
3983--*/\r
3984{\r
3985 EFI_STATUS Status;\r
3986 TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
3987 UINTN Index;\r
3988\r
3989 Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *) Context;\r
3990 if (Private->PasswordEnabled) {\r
3991 //\r
3992 // If StdIn Locked return not ready\r
3993 //\r
3994 return ;\r
3995 }\r
3996\r
3997 //\r
3998 // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()\r
3999 //\r
4000 if (Private->InputEventSignalState) {\r
4001 gBS->SignalEvent (Event);\r
4002 return ;\r
4003 }\r
4004 //\r
4005 // if any physical console input device has key input, signal the event.\r
4006 //\r
4007 for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {\r
4008 Status = gBS->CheckEvent (Private->PointerList[Index]->WaitForInput);\r
4009 if (!EFI_ERROR (Status)) {\r
4010 gBS->SignalEvent (Event);\r
4011 Private->InputEventSignalState = TRUE;\r
4012 }\r
4013 }\r
4014}\r
4015\r
8ae0b360 4016//\r
4017// Absolute Pointer Protocol functions\r
4018//\r
4019\r
4020EFI_STATUS\r
4021EFIAPI\r
4022ConSplitterAbsolutePointerReset (\r
4023 IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,\r
4024 IN BOOLEAN ExtendedVerification\r
4025 )\r
4026/*++\r
4027\r
4028 Routine Description:\r
4029 Resets the pointer device hardware.\r
4030\r
4031 Arguments:\r
4032 This - Protocol instance pointer.\r
4033 ExtendedVerification - Driver may perform diagnostics on reset.\r
4034\r
4035 Returns:\r
4036 EFI_SUCCESS - The device was reset.\r
7a5064ce 4037 EFI_DEVICE_ERROR - The device is not functioning correctly and could\r
8ae0b360 4038 not be reset.\r
7a5064ce 4039\r
8ae0b360 4040--*/\r
4041{\r
4042 EFI_STATUS Status;\r
4043 EFI_STATUS ReturnStatus;\r
4044 TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
4045 UINTN Index;\r
4046\r
4047 Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This);\r
4048\r
4049 Private->AbsoluteInputEventSignalState = FALSE;\r
7a5064ce 4050\r
8ae0b360 4051 if (Private->CurrentNumberOfAbsolutePointers == 0) {\r
4052 return EFI_SUCCESS;\r
4053 }\r
4054 //\r
4055 // return the worst status met\r
4056 //\r
4057 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfAbsolutePointers; Index++) {\r
4058 Status = Private->AbsolutePointerList[Index]->Reset (\r
4059 Private->AbsolutePointerList[Index],\r
4060 ExtendedVerification\r
4061 );\r
4062 if (EFI_ERROR (Status)) {\r
4063 ReturnStatus = Status;\r
4064 }\r
4065 }\r
4066\r
4067 return ReturnStatus;\r
4068}\r
4069\r
4070EFI_STATUS\r
7a5064ce 4071EFIAPI\r
8ae0b360 4072ConSplitterAbsolutePointerGetState (\r
4073 IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,\r
4074 IN OUT EFI_ABSOLUTE_POINTER_STATE *State\r
4075 )\r
4076/*++\r
4077\r
4078 Routine Description:\r
4079 Retrieves the current state of a pointer device.\r
4080\r
4081 Arguments:\r
4082 This - Protocol instance pointer.\r
4083 State - A pointer to the state information on the pointer device.\r
4084\r
4085 Returns:\r
4086 EFI_SUCCESS - The state of the pointer device was returned in State..\r
4087 EFI_NOT_READY - The state of the pointer device has not changed since the last call to\r
7a5064ce 4088 GetState().\r
8ae0b360 4089 EFI_DEVICE_ERROR - A device error occurred while attempting to retrieve the pointer\r
7a5064ce 4090 device's current state.\r
8ae0b360 4091--*/\r
4092{\r
4093 TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
4094 EFI_STATUS Status;\r
4095 EFI_STATUS ReturnStatus;\r
4096 UINTN Index;\r
4097 EFI_ABSOLUTE_POINTER_STATE CurrentState;\r
4098\r
4099\r
4100 Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This);\r
4101 if (Private->PasswordEnabled) {\r
4102 //\r
4103 // If StdIn Locked return not ready\r
4104 //\r
4105 return EFI_NOT_READY;\r
4106 }\r
4107\r
4108 Private->AbsoluteInputEventSignalState = FALSE;\r
4109\r
4110 State->CurrentX = 0;\r
4111 State->CurrentY = 0;\r
4112 State->CurrentZ = 0;\r
4113 State->ActiveButtons = 0;\r
7a5064ce 4114\r
8ae0b360 4115 //\r
4116 // if no physical pointer device exists, return EFI_NOT_READY;\r
4117 // if any physical pointer device has changed state,\r
4118 // return the state and EFI_SUCCESS.\r
4119 //\r
4120 ReturnStatus = EFI_NOT_READY;\r
4121 for (Index = 0; Index < Private->CurrentNumberOfAbsolutePointers; Index++) {\r
4122\r
4123 Status = Private->AbsolutePointerList[Index]->GetState (\r
4124 Private->AbsolutePointerList[Index],\r
4125 &CurrentState\r
4126 );\r
4127 if (!EFI_ERROR (Status)) {\r
4128 if (ReturnStatus == EFI_NOT_READY) {\r
4129 ReturnStatus = EFI_SUCCESS;\r
4130 }\r
4131\r
4132 State->ActiveButtons = CurrentState.ActiveButtons;\r
4133\r
4134 if (!(Private->AbsolutePointerMode.AbsoluteMinX == 0 && Private->AbsolutePointerMode.AbsoluteMaxX == 0)) {\r
4135 State->CurrentX = CurrentState.CurrentX;\r
4136 }\r
4137 if (!(Private->AbsolutePointerMode.AbsoluteMinY == 0 && Private->AbsolutePointerMode.AbsoluteMaxY == 0)) {\r
4138 State->CurrentY = CurrentState.CurrentY;\r
4139 }\r
4140 if (!(Private->AbsolutePointerMode.AbsoluteMinZ == 0 && Private->AbsolutePointerMode.AbsoluteMaxZ == 0)) {\r
4141 State->CurrentZ = CurrentState.CurrentZ;\r
4142 }\r
7a5064ce 4143\r
8ae0b360 4144 } else if (Status == EFI_DEVICE_ERROR) {\r
4145 ReturnStatus = EFI_DEVICE_ERROR;\r
4146 }\r
4147 }\r
4148\r
4149 return ReturnStatus;\r
4150}\r
4151\r
4152VOID\r
4153EFIAPI\r
4154ConSplitterAbsolutePointerWaitForInput (\r
4155 IN EFI_EVENT Event,\r
4156 IN VOID *Context\r
4157 )\r
4158/*++\r
4159\r
4160Routine Description:\r
4161 This event agregates all the events of the pointer devices in the splitter.\r
4162 If the ConIn is password locked then return.\r
4163 If any events of physical pointer devices are signaled, signal the pointer\r
4164 splitter event. This will cause the calling code to call\r
4165 ConSplitterAbsolutePointerGetState ().\r
4166\r
4167Arguments:\r
4168 Event - The Event assoicated with callback.\r
4169 Context - Context registered when Event was created.\r
4170\r
4171Returns:\r
4172 None\r
4173\r
4174--*/\r
4175{\r
4176 EFI_STATUS Status;\r
4177 TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
4178 UINTN Index;\r
4179\r
4180 Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *) Context;\r
4181 if (Private->PasswordEnabled) {\r
4182 //\r
4183 // If StdIn Locked return not ready\r
4184 //\r
4185 return ;\r
4186 }\r
4187\r
4188 //\r
7a5064ce 4189 // if AbsoluteInputEventSignalState is flagged before,\r
8ae0b360 4190 // and not cleared by Reset() or GetState(), signal it\r
4191 //\r
4192 if (Private->AbsoluteInputEventSignalState) {\r
4193 gBS->SignalEvent (Event);\r
4194 return ;\r
4195 }\r
4196 //\r
4197 // if any physical console input device has key input, signal the event.\r
4198 //\r
4199 for (Index = 0; Index < Private->CurrentNumberOfAbsolutePointers; Index++) {\r
4200 Status = gBS->CheckEvent (Private->AbsolutePointerList[Index]->WaitForInput);\r
4201 if (!EFI_ERROR (Status)) {\r
4202 gBS->SignalEvent (Event);\r
4203 Private->AbsoluteInputEventSignalState = TRUE;\r
4204 }\r
4205 }\r
4206}\r
4207\r
95276127 4208EFI_STATUS\r
4209EFIAPI\r
4210ConSplitterTextOutReset (\r
4211 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
4212 IN BOOLEAN ExtendedVerification\r
4213 )\r
4214/*++\r
4215\r
4216 Routine Description:\r
4217 Reset the text output device hardware and optionaly run diagnostics\r
4218\r
4219 Arguments:\r
4220 This - Protocol instance pointer.\r
4221 ExtendedVerification - Driver may perform more exhaustive verfication\r
4222 operation of the device during reset.\r
4223\r
4224 Returns:\r
4225 EFI_SUCCESS - The text output device was reset.\r
4226 EFI_DEVICE_ERROR - The text output device is not functioning correctly and\r
4227 could not be reset.\r
4228\r
4229--*/\r
4230{\r
4231 EFI_STATUS Status;\r
4232 TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
4233 UINTN Index;\r
4234 EFI_STATUS ReturnStatus;\r
4235\r
4236 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
4237\r
4238 //\r
4239 // return the worst status met\r
4240 //\r
4241 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
4242\r
4243 if (Private->TextOutList[Index].TextOutEnabled) {\r
4244\r
4245 Status = Private->TextOutList[Index].TextOut->Reset (\r
4246 Private->TextOutList[Index].TextOut,\r
4247 ExtendedVerification\r
4248 );\r
4249 if (EFI_ERROR (Status)) {\r
4250 ReturnStatus = Status;\r
4251 }\r
4252 }\r
4253 }\r
4254\r
4255 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
4256\r
4257 Status = DevNullTextOutSetMode (Private, 0);\r
4258 if (EFI_ERROR (Status)) {\r
4259 ReturnStatus = Status;\r
4260 }\r
4261\r
4262 return ReturnStatus;\r
4263}\r
4264\r
4265EFI_STATUS\r
4266EFIAPI\r
4267ConSplitterTextOutOutputString (\r
4268 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
4269 IN CHAR16 *WString\r
4270 )\r
4271/*++\r
4272\r
4273 Routine Description:\r
4274 Write a Unicode string to the output device.\r
4275\r
4276 Arguments:\r
4277 This - Protocol instance pointer.\r
4278 String - The NULL-terminated Unicode string to be displayed on the output\r
4279 device(s). All output devices must also support the Unicode\r
4280 drawing defined in this file.\r
4281\r
4282 Returns:\r
4283 EFI_SUCCESS - The string was output to the device.\r
4284 EFI_DEVICE_ERROR - The device reported an error while attempting to output\r
4285 the text.\r
4286 EFI_UNSUPPORTED - The output device's mode is not currently in a\r
4287 defined text mode.\r
4288 EFI_WARN_UNKNOWN_GLYPH - This warning code indicates that some of the\r
4289 characters in the Unicode string could not be\r
4290 rendered and were skipped.\r
4291\r
4292--*/\r
4293{\r
4294 EFI_STATUS Status;\r
4295 TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
4296 UINTN Index;\r
4297 UINTN BackSpaceCount;\r
4298 EFI_STATUS ReturnStatus;\r
4299 CHAR16 *TargetString;\r
4300\r
4301 This->SetAttribute (This, This->Mode->Attribute);\r
4302\r
4303 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
4304\r
4305 BackSpaceCount = 0;\r
4306 for (TargetString = WString; *TargetString; TargetString++) {\r
4307 if (*TargetString == CHAR_BACKSPACE) {\r
4308 BackSpaceCount++;\r
4309 }\r
4310\r
4311 }\r
4312\r
4313 if (BackSpaceCount == 0) {\r
4314 TargetString = WString;\r
4315 } else {\r
4316 TargetString = AllocatePool (sizeof (CHAR16) * (StrLen (WString) + BackSpaceCount + 1));\r
4317 StrCpy (TargetString, WString);\r
4318 }\r
4319 //\r
4320 // return the worst status met\r
4321 //\r
4322 Status = DevNullTextOutOutputString (Private, TargetString);\r
4323 if (EFI_ERROR (Status)) {\r
4324 ReturnStatus = Status;\r
4325 }\r
4326\r
4327 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
4328\r
4329 if (Private->TextOutList[Index].TextOutEnabled) {\r
4330 Status = Private->TextOutList[Index].TextOut->OutputString (\r
4331 Private->TextOutList[Index].TextOut,\r
4332 TargetString\r
4333 );\r
4334 if (EFI_ERROR (Status)) {\r
4335 ReturnStatus = Status;\r
4336 }\r
4337 }\r
4338 }\r
4339\r
4340 if (BackSpaceCount) {\r
4341 FreePool (TargetString);\r
4342 }\r
4343\r
4344 return ReturnStatus;\r
4345}\r
4346\r
4347EFI_STATUS\r
4348EFIAPI\r
4349ConSplitterTextOutTestString (\r
4350 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
4351 IN CHAR16 *WString\r
4352 )\r
4353/*++\r
4354\r
4355 Routine Description:\r
4356 Verifies that all characters in a Unicode string can be output to the\r
4357 target device.\r
4358\r
4359 Arguments:\r
4360 This - Protocol instance pointer.\r
4361 String - The NULL-terminated Unicode string to be examined for the output\r
4362 device(s).\r
4363\r
4364 Returns:\r
4365 EFI_SUCCESS - The device(s) are capable of rendering the output string.\r
4366 EFI_UNSUPPORTED - Some of the characters in the Unicode string cannot be\r
4367 rendered by one or more of the output devices mapped\r
4368 by the EFI handle.\r
4369\r
4370--*/\r
4371{\r
4372 EFI_STATUS Status;\r
4373 TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
4374 UINTN Index;\r
4375 EFI_STATUS ReturnStatus;\r
4376\r
4377 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
4378\r
4379 //\r
4380 // return the worst status met\r
4381 //\r
4382 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
4383 if (Private->TextOutList[Index].TextOutEnabled) {\r
4384 Status = Private->TextOutList[Index].TextOut->TestString (\r
4385 Private->TextOutList[Index].TextOut,\r
4386 WString\r
4387 );\r
4388 if (EFI_ERROR (Status)) {\r
4389 ReturnStatus = Status;\r
4390 }\r
4391 }\r
4392 }\r
4393 //\r
4394 // There is no DevNullTextOutTestString () since a Unicode buffer would\r
4395 // always return EFI_SUCCESS.\r
4396 // ReturnStatus will be EFI_SUCCESS if no consoles are present\r
4397 //\r
4398 return ReturnStatus;\r
4399}\r
4400\r
4401EFI_STATUS\r
4402EFIAPI\r
4403ConSplitterTextOutQueryMode (\r
4404 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
4405 IN UINTN ModeNumber,\r
4406 OUT UINTN *Columns,\r
4407 OUT UINTN *Rows\r
4408 )\r
4409/*++\r
4410\r
4411 Routine Description:\r
4412 Returns information for an available text mode that the output device(s)\r
4413 supports.\r
4414\r
4415 Arguments:\r
4416 This - Protocol instance pointer.\r
4417 ModeNumber - The mode number to return information on.\r
4418 Columns, Rows - Returns the geometry of the text output device for the\r
4419 requested ModeNumber.\r
4420\r
4421 Returns:\r
4422 EFI_SUCCESS - The requested mode information was returned.\r
4423 EFI_DEVICE_ERROR - The device had an error and could not\r
4424 complete the request.\r
4425 EFI_UNSUPPORTED - The mode number was not valid.\r
4426\r
4427--*/\r
4428{\r
4429 TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
3012ce5c 4430 UINTN CurrentMode;\r
4431 INT32 *TextOutModeMap;\r
95276127 4432\r
4433 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
4434\r
4435 //\r
4436 // Check whether param ModeNumber is valid.\r
4437 // ModeNumber should be within range 0 ~ MaxMode - 1.\r
4438 //\r
4439 if ( (ModeNumber > (UINTN)(((UINT32)-1)>>1)) ) {\r
4440 return EFI_UNSUPPORTED;\r
4441 }\r
4442\r
4443 if ((INT32) ModeNumber >= This->Mode->MaxMode) {\r
4444 return EFI_UNSUPPORTED;\r
4445 }\r
4446\r
3012ce5c 4447 //\r
4448 // We get the available mode from mode intersection map if it's available\r
4449 //\r
4450 if (Private->TextOutModeMap != NULL) {\r
4451 TextOutModeMap = Private->TextOutModeMap + Private->TextOutListCount * ModeNumber;\r
4452 CurrentMode = (UINTN)(*TextOutModeMap);\r
4453 *Columns = Private->TextOutQueryData[CurrentMode].Columns;\r
4454 *Rows = Private->TextOutQueryData[CurrentMode].Rows;\r
4455 } else {\r
4456 *Columns = Private->TextOutQueryData[ModeNumber].Columns;\r
4457 *Rows = Private->TextOutQueryData[ModeNumber].Rows;\r
4458 }\r
95276127 4459\r
4460 if (*Columns <= 0 && *Rows <= 0) {\r
4461 return EFI_UNSUPPORTED;\r
4462\r
4463 }\r
4464\r
4465 return EFI_SUCCESS;\r
4466}\r
4467\r
4468EFI_STATUS\r
4469EFIAPI\r
4470ConSplitterTextOutSetMode (\r
4471 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
4472 IN UINTN ModeNumber\r
4473 )\r
4474/*++\r
4475\r
4476 Routine Description:\r
4477 Sets the output device(s) to a specified mode.\r
4478\r
4479 Arguments:\r
4480 This - Protocol instance pointer.\r
4481 ModeNumber - The mode number to set.\r
4482\r
4483 Returns:\r
4484 EFI_SUCCESS - The requested text mode was set.\r
4485 EFI_DEVICE_ERROR - The device had an error and\r
4486 could not complete the request.\r
4487 EFI_UNSUPPORTED - The mode number was not valid.\r
4488\r
4489--*/\r
4490{\r
4491 EFI_STATUS Status;\r
4492 TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
4493 UINTN Index;\r
4494 INT32 *TextOutModeMap;\r
4495 EFI_STATUS ReturnStatus;\r
4496\r
4497 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
4498\r
4499 //\r
4500 // Check whether param ModeNumber is valid.\r
4501 // ModeNumber should be within range 0 ~ MaxMode - 1.\r
4502 //\r
4503 if ( (ModeNumber > (UINTN)(((UINT32)-1)>>1)) ) {\r
4504 return EFI_UNSUPPORTED;\r
4505 }\r
4506\r
4507 if ((INT32) ModeNumber >= This->Mode->MaxMode) {\r
4508 return EFI_UNSUPPORTED;\r
4509 }\r
4510 //\r
4511 // If the mode is being set to the curent mode, then just clear the screen and return.\r
4512 //\r
4513 if (Private->TextOutMode.Mode == (INT32) ModeNumber) {\r
4514 return ConSplitterTextOutClearScreen (This);\r
4515 }\r
4516 //\r
4517 // return the worst status met\r
4518 //\r
4519 TextOutModeMap = Private->TextOutModeMap + Private->TextOutListCount * ModeNumber;\r
4520 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
4521\r
4522 if (Private->TextOutList[Index].TextOutEnabled) {\r
4523 Status = Private->TextOutList[Index].TextOut->SetMode (\r
4524 Private->TextOutList[Index].TextOut,\r
4525 TextOutModeMap[Index]\r
4526 );\r
4527 //\r
3012ce5c 4528 // If this console device is based on a GOP or UGA device, then sync up the bitmap from\r
4529 // the GOP/UGA splitter and reclear the text portion of the display in the new mode.\r
95276127 4530 //\r
4531 if ((Private->TextOutList[Index].GraphicsOutput != NULL) || (Private->TextOutList[Index].UgaDraw != NULL)) {\r
4532 Private->TextOutList[Index].TextOut->ClearScreen (Private->TextOutList[Index].TextOut);\r
4533 }\r
4534\r
4535 if (EFI_ERROR (Status)) {\r
4536 ReturnStatus = Status;\r
4537 }\r
4538 }\r
4539 }\r
4540 //\r
4541 // The DevNull Console will support any possible mode as it allocates memory\r
4542 //\r
4543 Status = DevNullTextOutSetMode (Private, ModeNumber);\r
4544 if (EFI_ERROR (Status)) {\r
4545 ReturnStatus = Status;\r
4546 }\r
4547\r
4548 return ReturnStatus;\r
4549}\r
4550\r
4551EFI_STATUS\r
4552EFIAPI\r
4553ConSplitterTextOutSetAttribute (\r
4554 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
4555 IN UINTN Attribute\r
4556 )\r
4557/*++\r
4558\r
4559 Routine Description:\r
4560 Sets the background and foreground colors for the OutputString () and\r
4561 ClearScreen () functions.\r
4562\r
4563 Arguments:\r
4564 This - Protocol instance pointer.\r
4565 Attribute - The attribute to set. Bits 0..3 are the foreground color, and\r
4566 bits 4..6 are the background color. All other bits are undefined\r
4567 and must be zero. The valid Attributes are defined in this file.\r
4568\r
4569 Returns:\r
4570 EFI_SUCCESS - The attribute was set.\r
4571 EFI_DEVICE_ERROR - The device had an error and\r
4572 could not complete the request.\r
4573 EFI_UNSUPPORTED - The attribute requested is not defined.\r
4574\r
4575--*/\r
4576{\r
4577 EFI_STATUS Status;\r
4578 TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
4579 UINTN Index;\r
4580 EFI_STATUS ReturnStatus;\r
4581\r
4582 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
4583\r
4584 //\r
4585 // Check whether param Attribute is valid.\r
4586 //\r
4587 if ( (Attribute > (UINTN)(((UINT32)-1)>>1)) ) {\r
4588 return EFI_UNSUPPORTED;\r
4589 }\r
4590\r
4591 //\r
4592 // return the worst status met\r
4593 //\r
4594 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
4595\r
4596 if (Private->TextOutList[Index].TextOutEnabled) {\r
4597 Status = Private->TextOutList[Index].TextOut->SetAttribute (\r
4598 Private->TextOutList[Index].TextOut,\r
4599 Attribute\r
4600 );\r
4601 if (EFI_ERROR (Status)) {\r
4602 ReturnStatus = Status;\r
4603 }\r
4604 }\r
4605 }\r
4606\r
4607 Private->TextOutMode.Attribute = (INT32) Attribute;\r
4608\r
4609 return ReturnStatus;\r
4610}\r
4611\r
4612EFI_STATUS\r
4613EFIAPI\r
4614ConSplitterTextOutClearScreen (\r
4615 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
4616 )\r
4617/*++\r
4618\r
4619 Routine Description:\r
4620 Clears the output device(s) display to the currently selected background\r
4621 color.\r
4622\r
4623 Arguments:\r
4624 This - Protocol instance pointer.\r
4625\r
4626 Returns:\r
4627 EFI_SUCCESS - The operation completed successfully.\r
4628 EFI_DEVICE_ERROR - The device had an error and\r
4629 could not complete the request.\r
4630 EFI_UNSUPPORTED - The output device is not in a valid text mode.\r
4631\r
4632--*/\r
4633{\r
4634 EFI_STATUS Status;\r
4635 TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
4636 UINTN Index;\r
4637 EFI_STATUS ReturnStatus;\r
4638\r
4639 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
4640\r
4641 //\r
4642 // return the worst status met\r
4643 //\r
4644 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
4645\r
4646 if (Private->TextOutList[Index].TextOutEnabled) {\r
4647 Status = Private->TextOutList[Index].TextOut->ClearScreen (Private->TextOutList[Index].TextOut);\r
4648 if (EFI_ERROR (Status)) {\r
4649 ReturnStatus = Status;\r
4650 }\r
4651 }\r
4652 }\r
4653\r
4654 Status = DevNullTextOutClearScreen (Private);\r
4655 if (EFI_ERROR (Status)) {\r
4656 ReturnStatus = Status;\r
4657 }\r
4658\r
4659 return ReturnStatus;\r
4660}\r
4661\r
4662EFI_STATUS\r
4663EFIAPI\r
4664ConSplitterTextOutSetCursorPosition (\r
4665 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
4666 IN UINTN Column,\r
4667 IN UINTN Row\r
4668 )\r
4669/*++\r
4670\r
4671 Routine Description:\r
4672 Sets the current coordinates of the cursor position\r
4673\r
4674 Arguments:\r
4675 This - Protocol instance pointer.\r
4676 Column, Row - the position to set the cursor to. Must be greater than or\r
4677 equal to zero and less than the number of columns and rows\r
4678 by QueryMode ().\r
4679\r
4680 Returns:\r
4681 EFI_SUCCESS - The operation completed successfully.\r
4682 EFI_DEVICE_ERROR - The device had an error and\r
4683 could not complete the request.\r
4684 EFI_UNSUPPORTED - The output device is not in a valid text mode, or the\r
4685 cursor position is invalid for the current mode.\r
4686\r
4687--*/\r
4688{\r
4689 EFI_STATUS Status;\r
4690 TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
4691 UINTN Index;\r
4692 EFI_STATUS ReturnStatus;\r
4693 UINTN MaxColumn;\r
4694 UINTN MaxRow;\r
de8fe2c2 4695 INT32 *TextOutModeMap;\r
4696 INT32 ModeNumber;\r
4697 INT32 CurrentMode;\r
95276127 4698\r
4699 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
de8fe2c2 4700 TextOutModeMap = NULL;\r
4701 ModeNumber = Private->TextOutMode.Mode;\r
7a5064ce 4702\r
de8fe2c2 4703 //\r
4704 // Get current MaxColumn and MaxRow from intersection map\r
4705 //\r
4706 if (Private->TextOutModeMap != NULL) {\r
4707 TextOutModeMap = Private->TextOutModeMap + Private->TextOutListCount * ModeNumber;\r
4708 CurrentMode = *TextOutModeMap;\r
4709 } else {\r
4710 CurrentMode = ModeNumber;\r
4711 }\r
7a5064ce 4712\r
de8fe2c2 4713 MaxColumn = Private->TextOutQueryData[CurrentMode].Columns;\r
4714 MaxRow = Private->TextOutQueryData[CurrentMode].Rows;\r
95276127 4715\r
4716 if (Column >= MaxColumn || Row >= MaxRow) {\r
4717 return EFI_UNSUPPORTED;\r
4718 }\r
4719 //\r
4720 // return the worst status met\r
4721 //\r
4722 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
4723\r
4724 if (Private->TextOutList[Index].TextOutEnabled) {\r
4725 Status = Private->TextOutList[Index].TextOut->SetCursorPosition (\r
4726 Private->TextOutList[Index].TextOut,\r
4727 Column,\r
4728 Row\r
4729 );\r
4730 if (EFI_ERROR (Status)) {\r
4731 ReturnStatus = Status;\r
4732 }\r
4733 }\r
4734 }\r
4735\r
4736 DevNullTextOutSetCursorPosition (Private, Column, Row);\r
4737\r
4738 return ReturnStatus;\r
4739}\r
4740\r
4741EFI_STATUS\r
4742EFIAPI\r
4743ConSplitterTextOutEnableCursor (\r
4744 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
4745 IN BOOLEAN Visible\r
4746 )\r
4747/*++\r
4748\r
4749 Routine Description:\r
4750 Makes the cursor visible or invisible\r
4751\r
4752 Arguments:\r
4753 This - Protocol instance pointer.\r
4754 Visible - If TRUE, the cursor is set to be visible. If FALSE, the cursor is\r
4755 set to be invisible.\r
4756\r
4757 Returns:\r
4758 EFI_SUCCESS - The operation completed successfully.\r
4759 EFI_DEVICE_ERROR - The device had an error and could not complete the\r
4760 request, or the device does not support changing\r
4761 the cursor mode.\r
4762 EFI_UNSUPPORTED - The output device is not in a valid text mode.\r
4763\r
4764--*/\r
4765{\r
4766 EFI_STATUS Status;\r
4767 TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
4768 UINTN Index;\r
4769 EFI_STATUS ReturnStatus;\r
4770\r
4771 Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
4772\r
4773 //\r
4774 // return the worst status met\r
4775 //\r
4776 for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
4777\r
4778 if (Private->TextOutList[Index].TextOutEnabled) {\r
4779 Status = Private->TextOutList[Index].TextOut->EnableCursor (\r
4780 Private->TextOutList[Index].TextOut,\r
4781 Visible\r
4782 );\r
4783 if (EFI_ERROR (Status)) {\r
4784 ReturnStatus = Status;\r
4785 }\r
4786 }\r
4787 }\r
4788\r
4789 DevNullTextOutEnableCursor (Private, Visible);\r
4790\r
4791 return ReturnStatus;\r
4792}\r
3012ce5c 4793\r