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