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