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