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