]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.c
Fix component name bugs when input Controller Name is invalid
[mirror_edk2.git] / EdkModulePkg / Universal / Console / GraphicsConsole / Dxe / GraphicsConsole.c
CommitLineData
7a2729d4 1/**@file\r
2 This is the main routine for initializing the Graphics Console support routines.\r
3Remaining Tasks\r
4 Add all standard Glyphs from EFI 1.02 Specification\r
5 Implement optimal automatic Mode creation algorithm\r
6 Solve palette issues for mixed graphics and text\r
7 When does this protocol reset the palette?\r
8 \r
9Copyright (c) 2006 Intel Corporation. <BR>\r
878ddf1f 10All rights reserved. This program and the accompanying materials \r
11are licensed and made available under the terms and conditions of the BSD License \r
12which accompanies this distribution. The full text of the license may be found at \r
13http://opensource.org/licenses/bsd-license.php \r
14 \r
15THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
16WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
17\r
7a2729d4 18**/\r
878ddf1f 19\r
20#include "GraphicsConsole.h"\r
21\r
22//\r
23// Function Prototypes\r
24//\r
25EFI_STATUS\r
26EFIAPI\r
27GraphicsConsoleControllerDriverSupported (\r
28 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
29 IN EFI_HANDLE Controller,\r
30 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
31 );\r
32\r
33EFI_STATUS\r
34EFIAPI\r
35GraphicsConsoleControllerDriverStart (\r
36 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
37 IN EFI_HANDLE Controller,\r
38 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
39 );\r
40\r
41EFI_STATUS\r
42EFIAPI\r
43GraphicsConsoleControllerDriverStop (\r
44 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
45 IN EFI_HANDLE Controller,\r
46 IN UINTN NumberOfChildren,\r
47 IN EFI_HANDLE *ChildHandleBuffer\r
48 );\r
49\r
50EFI_STATUS\r
51GetTextColors (\r
52 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
406adcd1 53 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
54 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background\r
878ddf1f 55 );\r
56\r
57EFI_STATUS\r
58DrawUnicodeWeightAtCursor (\r
59 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
60 IN CHAR16 UnicodeWeight\r
61 );\r
62\r
63EFI_STATUS\r
64DrawUnicodeWeightAtCursorN (\r
65 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
66 IN CHAR16 *UnicodeWeight,\r
67 IN UINTN Count\r
68 );\r
69\r
70EFI_STATUS\r
71EraseCursor (\r
72 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This\r
73 );\r
74\r
75//\r
76// Globals\r
77//\r
78GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate = {\r
79 GRAPHICS_CONSOLE_DEV_SIGNATURE,\r
406adcd1 80 (EFI_GRAPHICS_OUTPUT_PROTOCOL *) NULL,\r
878ddf1f 81 (EFI_UGA_DRAW_PROTOCOL *) NULL,\r
82 {\r
83 GraphicsConsoleConOutReset,\r
84 GraphicsConsoleConOutOutputString,\r
85 GraphicsConsoleConOutTestString,\r
86 GraphicsConsoleConOutQueryMode,\r
87 GraphicsConsoleConOutSetMode,\r
88 GraphicsConsoleConOutSetAttribute,\r
89 GraphicsConsoleConOutClearScreen,\r
90 GraphicsConsoleConOutSetCursorPosition,\r
91 GraphicsConsoleConOutEnableCursor,\r
92 (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL\r
93 },\r
94 {\r
95 0,\r
96 0,\r
97 EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_BLACK),\r
98 0,\r
99 0,\r
100 TRUE\r
101 },\r
102 {\r
103 { 80, 25, 0, 0, 0, 0 }, // Mode 0\r
3bc85e36 104 { 80, 50, 0, 0, 0, 0 }, // Mode 1 \r
878ddf1f 105 { 0, 0, 0, 0, 0, 0 } // Mode 2\r
106 },\r
406adcd1 107 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
878ddf1f 108 (EFI_HII_HANDLE) 0\r
109};\r
110\r
111EFI_HII_PROTOCOL *mHii;\r
112\r
113static CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };\r
114\r
406adcd1 115static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {\r
878ddf1f 116 //\r
117 // B G R\r
118 //\r
7a2729d4 119 {0x00, 0x00, 0x00, 0x00}, // BLACK\r
120 {0x98, 0x00, 0x00, 0x00}, // BLUE\r
121 {0x00, 0x98, 0x00, 0x00}, // GREEN\r
122 {0x98, 0x98, 0x00, 0x00}, // CYAN\r
123 {0x00, 0x00, 0x98, 0x00}, // RED\r
124 {0x98, 0x00, 0x98, 0x00}, // MAGENTA\r
125 {0x00, 0x98, 0x98, 0x00}, // BROWN\r
126 {0x98, 0x98, 0x98, 0x00}, // LIGHTGRAY\r
127 {0x30, 0x30, 0x30, 0x00}, // DARKGRAY - BRIGHT BLACK\r
128 {0xff, 0x00, 0x00, 0x00}, // LIGHTBLUE - ?\r
129 {0x00, 0xff, 0x00, 0x00}, // LIGHTGREEN - ?\r
130 {0xff, 0xff, 0x00, 0x00}, // LIGHTCYAN\r
131 {0x00, 0x00, 0xff, 0x00}, // LIGHTRED\r
132 {0xff, 0x00, 0xff, 0x00}, // LIGHTMAGENTA\r
133 {0x00, 0xff, 0xff, 0x00}, // LIGHTBROWN\r
134 {0xff, 0xff, 0xff, 0x00} // WHITE\r
878ddf1f 135};\r
136\r
137static EFI_NARROW_GLYPH mCursorGlyph = {\r
138 0x0000,\r
139 0x00,\r
140 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }\r
141};\r
142\r
878ddf1f 143EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding = {\r
144 GraphicsConsoleControllerDriverSupported,\r
145 GraphicsConsoleControllerDriverStart,\r
146 GraphicsConsoleControllerDriverStop,\r
147 0x10,\r
148 NULL,\r
149 NULL\r
150};\r
151\r
152EFI_STATUS\r
153EFIAPI\r
154GraphicsConsoleControllerDriverSupported (\r
155 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
156 IN EFI_HANDLE Controller,\r
157 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
158 )\r
159{\r
160 EFI_STATUS Status;\r
406adcd1 161 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
878ddf1f 162 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
163 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
164\r
406adcd1 165 UgaDraw = NULL;\r
878ddf1f 166 //\r
167 // Open the IO Abstraction(s) needed to perform the supported test\r
168 //\r
169 Status = gBS->OpenProtocol (\r
170 Controller,\r
406adcd1 171 &gEfiGraphicsOutputProtocolGuid,\r
172 (VOID **) &GraphicsOutput,\r
878ddf1f 173 This->DriverBindingHandle,\r
174 Controller,\r
175 EFI_OPEN_PROTOCOL_BY_DRIVER\r
176 );\r
406adcd1 177 \r
878ddf1f 178 if (EFI_ERROR (Status)) {\r
406adcd1 179 GraphicsOutput = NULL;\r
180 //\r
181 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol\r
182 //\r
183 Status = gBS->OpenProtocol (\r
184 Controller,\r
185 &gEfiUgaDrawProtocolGuid,\r
186 (VOID **) &UgaDraw,\r
187 This->DriverBindingHandle,\r
188 Controller,\r
189 EFI_OPEN_PROTOCOL_BY_DRIVER\r
190 );\r
191 if (EFI_ERROR (Status)) {\r
192 return Status;\r
193 }\r
878ddf1f 194 }\r
406adcd1 195\r
878ddf1f 196 //\r
197 // We need to ensure that we do not layer on top of a virtual handle.\r
198 // We need to ensure that the handles produced by the conspliter do not\r
199 // get used.\r
200 //\r
201 Status = gBS->OpenProtocol (\r
202 Controller,\r
203 &gEfiDevicePathProtocolGuid,\r
204 (VOID **) &DevicePath,\r
205 This->DriverBindingHandle,\r
206 Controller,\r
207 EFI_OPEN_PROTOCOL_BY_DRIVER\r
208 );\r
209 if (!EFI_ERROR (Status)) {\r
210 gBS->CloseProtocol (\r
211 Controller,\r
212 &gEfiDevicePathProtocolGuid,\r
213 This->DriverBindingHandle,\r
214 Controller\r
215 );\r
216 } else {\r
217 goto Error;\r
218 }\r
219 //\r
220 // Does Hii Exist? If not, we aren't ready to run\r
221 //\r
222 Status = EfiLocateHiiProtocol ();\r
223\r
224 //\r
225 // Close the I/O Abstraction(s) used to perform the supported test\r
226 //\r
227Error:\r
406adcd1 228 if (GraphicsOutput != NULL) {\r
229 gBS->CloseProtocol (\r
230 Controller,\r
231 &gEfiGraphicsOutputProtocolGuid,\r
232 This->DriverBindingHandle,\r
233 Controller\r
234 );\r
235 } else {\r
236 gBS->CloseProtocol (\r
237 Controller,\r
238 &gEfiUgaDrawProtocolGuid,\r
239 This->DriverBindingHandle,\r
240 Controller\r
241 );\r
242 }\r
878ddf1f 243 return Status;\r
244}\r
245\r
246EFI_STATUS\r
247EFIAPI\r
248GraphicsConsoleControllerDriverStart (\r
249 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
250 IN EFI_HANDLE Controller,\r
251 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
252 )\r
253/*++\r
254\r
255 Routine Description:\r
256\r
257 Start the controller.\r
258\r
259 Arguments:\r
260\r
261 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
262 Controller - The handle of the controller to start.\r
263 RemainingDevicePath - A pointer to the remaining portion of a devcie path.\r
264\r
265 Returns:\r
266\r
267 EFI_SUCCESS - Return successfully.\r
268 EFI_OUT_OF_RESOURCES - Out of resources.\r
269\r
270--*/\r
271{\r
272 EFI_STATUS Status;\r
273 GRAPHICS_CONSOLE_DEV *Private;\r
274 EFI_HII_PACKAGES *Package;\r
275 EFI_HII_FONT_PACK *FontPack;\r
276 UINTN NarrowFontSize;\r
277 UINT32 HorizontalResolution;\r
278 UINT32 VerticalResolution;\r
279 UINT32 ColorDepth;\r
280 UINT32 RefreshRate;\r
281 UINTN MaxMode;\r
282 UINTN Columns;\r
283 UINTN Rows;\r
284 UINT8 *Location;\r
406adcd1 285 UINT32 ModeNumber;\r
286 UINTN SizeOfInfo;\r
287 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
288 \r
289 ModeNumber = 0;\r
290\r
878ddf1f 291 //\r
292 // Initialize the Graphics Console device instance\r
293 //\r
294 Private = AllocateCopyPool (\r
295 sizeof (GRAPHICS_CONSOLE_DEV),\r
296 &mGraphicsConsoleDevTemplate\r
297 );\r
298 if (Private == NULL) {\r
299 return EFI_OUT_OF_RESOURCES;\r
300 }\r
301\r
302 Private->SimpleTextOutput.Mode = &(Private->SimpleTextOutputMode);\r
303\r
304 Status = gBS->OpenProtocol (\r
305 Controller,\r
406adcd1 306 &gEfiGraphicsOutputProtocolGuid,\r
307 (VOID **) &Private->GraphicsOutput,\r
878ddf1f 308 This->DriverBindingHandle,\r
309 Controller,\r
310 EFI_OPEN_PROTOCOL_BY_DRIVER\r
311 );\r
406adcd1 312 if (EFI_ERROR(Status)) {\r
313 Private->GraphicsOutput = NULL;\r
314\r
315 Status = gBS->OpenProtocol (\r
316 Controller,\r
317 &gEfiUgaDrawProtocolGuid,\r
318 (VOID **) &Private->UgaDraw,\r
319 This->DriverBindingHandle,\r
320 Controller,\r
321 EFI_OPEN_PROTOCOL_BY_DRIVER\r
322 );\r
323 if (EFI_ERROR (Status)) {\r
324 goto Error;\r
325 }\r
878ddf1f 326 }\r
406adcd1 327\r
878ddf1f 328 //\r
329 // Get the HII protocol. If Supported() succeeds, do we really\r
330 // need to get HII protocol again?\r
331 //\r
332 Status = EfiLocateHiiProtocol ();\r
333 if (EFI_ERROR (Status)) {\r
334 goto Error;\r
335 }\r
336\r
337 NarrowFontSize = ReturnNarrowFontSize ();\r
338\r
339 FontPack = AllocateZeroPool (sizeof (EFI_HII_FONT_PACK) + NarrowFontSize);\r
340 ASSERT (FontPack);\r
341\r
342 FontPack->Header.Length = (UINT32) (sizeof (EFI_HII_FONT_PACK) + NarrowFontSize);\r
343 FontPack->Header.Type = EFI_HII_FONT;\r
344 FontPack->NumberOfNarrowGlyphs = (UINT16) (NarrowFontSize / sizeof (EFI_NARROW_GLYPH));\r
345\r
346 Location = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8));\r
347 CopyMem (Location, UsStdNarrowGlyphData, NarrowFontSize);\r
348\r
349 //\r
350 // Register our Fonts into the global database\r
351 //\r
352 Package = PreparePackages (1, NULL, FontPack);\r
353 mHii->NewPack (mHii, Package, &(Private->HiiHandle));\r
354 gBS->FreePool (Package);\r
355\r
356 //\r
357 // Free the font database\r
358 //\r
359 gBS->FreePool (FontPack);\r
360\r
361 //\r
362 // If the current mode information can not be retrieved, then attemp to set the default mode\r
363 // of 800x600, 32 bit colot, 60 Hz refresh.\r
364 //\r
365 HorizontalResolution = 800;\r
366 VerticalResolution = 600;\r
406adcd1 367\r
368 if (Private->GraphicsOutput != NULL) {\r
878ddf1f 369 //\r
406adcd1 370 // The console is build on top of Graphics Output Protocol, find the mode number for 800x600\r
878ddf1f 371 //\r
406adcd1 372 for (ModeNumber = 0; ModeNumber < Private->GraphicsOutput->Mode->MaxMode; ModeNumber++) {\r
373 Status = Private->GraphicsOutput->QueryMode (\r
374 Private->GraphicsOutput,\r
375 ModeNumber,\r
376 &SizeOfInfo,\r
377 &Info\r
378 );\r
379 if (!EFI_ERROR (Status)) {\r
380 if ((Info->HorizontalResolution == 800) &&\r
e313deb9 381 (Info->VerticalResolution == 600)) {\r
406adcd1 382 Status = Private->GraphicsOutput->SetMode (Private->GraphicsOutput, ModeNumber);\r
383 if (!EFI_ERROR (Status)) {\r
384 gBS->FreePool (Info);\r
385 break;\r
386 }\r
387 }\r
388 gBS->FreePool (Info);\r
389 }\r
390 }\r
391\r
392 if (EFI_ERROR (Status) || (ModeNumber == Private->GraphicsOutput->Mode->MaxMode)) {\r
393 //\r
394 // Set default mode failed or device don't support default mode, then get the current mode information\r
395 //\r
396 HorizontalResolution = Private->GraphicsOutput->Mode->Info->HorizontalResolution;\r
397 VerticalResolution = Private->GraphicsOutput->Mode->Info->VerticalResolution;\r
398 ModeNumber = Private->GraphicsOutput->Mode->Mode;\r
399 }\r
400 } else {\r
401 //\r
402 // The console is build on top of UGA Draw Protocol\r
403 //\r
404 ColorDepth = 32;\r
405 RefreshRate = 60;\r
406 Status = Private->UgaDraw->SetMode (\r
878ddf1f 407 Private->UgaDraw,\r
406adcd1 408 HorizontalResolution,\r
409 VerticalResolution,\r
410 ColorDepth,\r
411 RefreshRate\r
878ddf1f 412 );\r
413 if (EFI_ERROR (Status)) {\r
406adcd1 414 //\r
415 // Get the current mode information from the UGA Draw Protocol\r
416 //\r
417 Status = Private->UgaDraw->GetMode (\r
418 Private->UgaDraw,\r
419 &HorizontalResolution,\r
420 &VerticalResolution,\r
421 &ColorDepth,\r
422 &RefreshRate\r
423 );\r
424 if (EFI_ERROR (Status)) {\r
425 goto Error;\r
426 }\r
878ddf1f 427 }\r
428 }\r
406adcd1 429\r
878ddf1f 430 //\r
431 // Compute the maximum number of text Rows and Columns that this current graphics mode can support\r
432 //\r
433 Columns = HorizontalResolution / GLYPH_WIDTH;\r
434 Rows = VerticalResolution / GLYPH_HEIGHT;\r
435\r
436 //\r
437 // See if the mode is too small to support the required 80x25 text mode\r
438 //\r
439 if (Columns < 80 || Rows < 25) {\r
440 goto Error;\r
441 }\r
442 //\r
443 // Add Mode #0 that must be 80x25\r
444 //\r
445 MaxMode = 0;\r
406adcd1 446 Private->ModeData[MaxMode].GopWidth = HorizontalResolution;\r
447 Private->ModeData[MaxMode].GopHeight = VerticalResolution;\r
448 Private->ModeData[MaxMode].GopModeNumber = ModeNumber;\r
878ddf1f 449 Private->ModeData[MaxMode].DeltaX = (HorizontalResolution - (80 * GLYPH_WIDTH)) >> 1;\r
450 Private->ModeData[MaxMode].DeltaY = (VerticalResolution - (25 * GLYPH_HEIGHT)) >> 1;\r
451 MaxMode++;\r
452\r
453 //\r
454 // If it is possible to support Mode #1 - 80x50, than add it as an active mode\r
455 //\r
456 if (Rows >= 50) {\r
406adcd1 457 Private->ModeData[MaxMode].GopWidth = HorizontalResolution;\r
458 Private->ModeData[MaxMode].GopHeight = VerticalResolution;\r
459 Private->ModeData[MaxMode].GopModeNumber = ModeNumber;\r
878ddf1f 460 Private->ModeData[MaxMode].DeltaX = (HorizontalResolution - (80 * GLYPH_WIDTH)) >> 1;\r
461 Private->ModeData[MaxMode].DeltaY = (VerticalResolution - (50 * GLYPH_HEIGHT)) >> 1;\r
462 MaxMode++;\r
463 }\r
464 //\r
465 // If the graphics mode is 800x600, than add a text mode that uses the entire display\r
466 //\r
467 if (HorizontalResolution == 800 && VerticalResolution == 600) {\r
468\r
469 if (MaxMode < 2) {\r
470 Private->ModeData[MaxMode].Columns = 0;\r
471 Private->ModeData[MaxMode].Rows = 0;\r
406adcd1 472 Private->ModeData[MaxMode].GopWidth = 800;\r
473 Private->ModeData[MaxMode].GopHeight = 600;\r
474 Private->ModeData[MaxMode].GopModeNumber = ModeNumber;\r
878ddf1f 475 Private->ModeData[MaxMode].DeltaX = 0;\r
476 Private->ModeData[MaxMode].DeltaY = 0;\r
477 MaxMode++;\r
478 }\r
479\r
480 Private->ModeData[MaxMode].Columns = 800 / GLYPH_WIDTH;\r
481 Private->ModeData[MaxMode].Rows = 600 / GLYPH_HEIGHT;\r
406adcd1 482 Private->ModeData[MaxMode].GopWidth = 800;\r
483 Private->ModeData[MaxMode].GopHeight = 600;\r
484 Private->ModeData[MaxMode].GopModeNumber = ModeNumber;\r
878ddf1f 485 Private->ModeData[MaxMode].DeltaX = (800 % GLYPH_WIDTH) >> 1;\r
486 Private->ModeData[MaxMode].DeltaY = (600 % GLYPH_HEIGHT) >> 1;\r
487 MaxMode++;\r
488 }\r
489 //\r
490 // Update the maximum number of modes\r
491 //\r
492 Private->SimpleTextOutputMode.MaxMode = (INT32) MaxMode;\r
493\r
494 //\r
495 // Determine the number of text modes that this protocol can support\r
496 //\r
497 Status = GraphicsConsoleConOutSetMode (&Private->SimpleTextOutput, 0);\r
498 if (EFI_ERROR (Status)) {\r
499 goto Error;\r
500 }\r
501\r
2ce31132 502 DEBUG_CODE_BEGIN ();\r
878ddf1f 503 GraphicsConsoleConOutOutputString (&Private->SimpleTextOutput, (CHAR16 *)L"Graphics Console Started\n\r");\r
2ce31132 504 DEBUG_CODE_END ();\r
878ddf1f 505\r
506 //\r
507 // Install protocol interfaces for the Graphics Console device.\r
508 //\r
509 Status = gBS->InstallMultipleProtocolInterfaces (\r
510 &Controller,\r
511 &gEfiSimpleTextOutProtocolGuid,\r
512 &Private->SimpleTextOutput,\r
513 NULL\r
514 );\r
515\r
516Error:\r
517 if (EFI_ERROR (Status)) {\r
518 //\r
406adcd1 519 // Close the GOP or UGA IO Protocol\r
878ddf1f 520 //\r
406adcd1 521 if (Private->GraphicsOutput != NULL) {\r
522 gBS->CloseProtocol (\r
523 Controller,\r
524 &gEfiGraphicsOutputProtocolGuid,\r
525 This->DriverBindingHandle,\r
526 Controller\r
527 );\r
528 } else {\r
529 gBS->CloseProtocol (\r
530 Controller,\r
531 &gEfiUgaDrawProtocolGuid,\r
532 This->DriverBindingHandle,\r
533 Controller\r
534 );\r
535 }\r
878ddf1f 536\r
537 //\r
538 // Free private data\r
539 //\r
540 if (Private != NULL) {\r
541 gBS->FreePool (Private->LineBuffer);\r
542 gBS->FreePool (Private);\r
543 }\r
544 }\r
545\r
546 return Status;\r
547}\r
548\r
549EFI_STATUS\r
550EFIAPI\r
551GraphicsConsoleControllerDriverStop (\r
552 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
553 IN EFI_HANDLE Controller,\r
554 IN UINTN NumberOfChildren,\r
555 IN EFI_HANDLE *ChildHandleBuffer\r
556 )\r
557{\r
558 EFI_STATUS Status;\r
559 EFI_SIMPLE_TEXT_OUT_PROTOCOL *SimpleTextOutput;\r
560 GRAPHICS_CONSOLE_DEV *Private;\r
561\r
562 Status = gBS->OpenProtocol (\r
563 Controller,\r
564 &gEfiSimpleTextOutProtocolGuid,\r
565 (VOID **) &SimpleTextOutput,\r
566 This->DriverBindingHandle,\r
567 Controller,\r
568 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
569 );\r
570 if (EFI_ERROR (Status)) {\r
571 return EFI_NOT_STARTED;\r
572 }\r
573\r
574 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);\r
575\r
576 Status = gBS->UninstallProtocolInterface (\r
577 Controller,\r
578 &gEfiSimpleTextOutProtocolGuid,\r
579 &Private->SimpleTextOutput\r
580 );\r
581\r
582 if (!EFI_ERROR (Status)) {\r
583 //\r
406adcd1 584 // Close the GOP or UGA IO Protocol\r
878ddf1f 585 //\r
406adcd1 586 if (Private->GraphicsOutput != NULL) {\r
587 gBS->CloseProtocol (\r
588 Controller,\r
589 &gEfiGraphicsOutputProtocolGuid,\r
590 This->DriverBindingHandle,\r
591 Controller\r
592 );\r
593 } else {\r
594 gBS->CloseProtocol (\r
595 Controller,\r
596 &gEfiUgaDrawProtocolGuid,\r
597 This->DriverBindingHandle,\r
598 Controller\r
599 );\r
600 }\r
878ddf1f 601\r
602 //\r
603 // Remove the font pack\r
604 //\r
605 mHii->RemovePack (mHii, Private->HiiHandle);\r
606\r
607 //\r
608 // Free our instance data\r
609 //\r
610 if (Private != NULL) {\r
611 gBS->FreePool (Private->LineBuffer);\r
612 gBS->FreePool (Private);\r
613 }\r
614 }\r
615\r
616 return Status;\r
617}\r
618\r
619EFI_STATUS\r
620EfiLocateHiiProtocol (\r
621 VOID\r
622 )\r
623/*++\r
624\r
625 Routine Description:\r
626 Find if the HII protocol is available. If yes, locate the HII protocol\r
627\r
628 Arguments:\r
629\r
630 Returns:\r
631\r
632--*/\r
633{\r
634 EFI_HANDLE Handle;\r
635 UINTN Size;\r
636 EFI_STATUS Status;\r
637\r
638 //\r
639 // There should only be one - so buffer size is this\r
640 //\r
641 Size = sizeof (EFI_HANDLE);\r
642\r
643 Status = gBS->LocateHandle (\r
644 ByProtocol,\r
645 &gEfiHiiProtocolGuid,\r
646 NULL,\r
647 &Size,\r
648 &Handle\r
649 );\r
650\r
651 if (EFI_ERROR (Status)) {\r
652 return Status;\r
653 }\r
654\r
655 Status = gBS->HandleProtocol (\r
656 Handle,\r
657 &gEfiHiiProtocolGuid,\r
658 (VOID **)&mHii\r
659 );\r
660\r
661 return Status;\r
662}\r
663//\r
664// Body of the STO functions\r
665//\r
666EFI_STATUS\r
667EFIAPI\r
668GraphicsConsoleConOutReset (\r
669 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
670 IN BOOLEAN ExtendedVerification\r
671 )\r
672/*++\r
673 Routine Description:\r
674 \r
675 Implements SIMPLE_TEXT_OUTPUT.Reset().\r
676 If ExtendeVerification is TRUE, then perform dependent Graphics Console \r
677 device reset, and set display mode to mode 0.\r
678 If ExtendedVerification is FALSE, only set display mode to mode 0.\r
679 \r
680 Arguments:\r
681 \r
682 This - Indicates the calling context.\r
683 \r
684 ExtendedVerification - Indicates that the driver may perform a more exhaustive\r
685 verification operation of the device during reset.\r
686 \r
687 Returns:\r
688 \r
689 EFI_SUCCESS\r
690 The reset operation succeeds. \r
691 \r
692 EFI_DEVICE_ERROR\r
693 The Graphics Console is not functioning correctly \r
694 \r
695--*/\r
696{\r
697 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
698 return This->SetMode (This, 0);\r
699}\r
700\r
701EFI_STATUS\r
702EFIAPI\r
703GraphicsConsoleConOutOutputString (\r
704 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
705 IN CHAR16 *WString\r
706 )\r
707/*++\r
708 Routine Description:\r
709 \r
710 Implements SIMPLE_TEXT_OUTPUT.OutputString().\r
711 The Unicode string will be converted to Glyphs and will be \r
712 sent to the Graphics Console.\r
713 \r
714 \r
715 Arguments:\r
716 \r
717 This - Indicates the calling context.\r
718 \r
719 WString - The Null-terminated Unicode string to be displayed on \r
720 the Graphics Console.\r
721 \r
722 Returns:\r
723 \r
724 EFI_SUCCESS\r
725 The string is output successfully. \r
726 \r
727 EFI_DEVICE_ERROR\r
728 The Graphics Console failed to send the string out.\r
729 \r
730 EFI_WARN_UNKNOWN_GLYPH\r
731 Indicates that some of the characters in the Unicode string could not \r
732 be rendered and are skipped. \r
733 \r
734--*/\r
735{\r
736 GRAPHICS_CONSOLE_DEV *Private;\r
406adcd1 737 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
878ddf1f 738 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
739 INTN Mode;\r
740 UINTN MaxColumn;\r
741 UINTN MaxRow;\r
742 UINTN Width;\r
743 UINTN Height;\r
744 UINTN Delta;\r
745 EFI_STATUS Status;\r
746 BOOLEAN Warning;\r
406adcd1 747 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
748 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
878ddf1f 749 UINTN DeltaX;\r
750 UINTN DeltaY;\r
751 UINTN Count;\r
752 UINTN Index;\r
753 INT32 OriginAttribute;\r
406adcd1 754 CHAR16 SpaceStr[] = { NARROW_CHAR, ' ', 0 };\r
878ddf1f 755\r
756 //\r
757 // Current mode\r
758 //\r
759 Mode = This->Mode->Mode;\r
760 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
406adcd1 761 GraphicsOutput = Private->GraphicsOutput;\r
878ddf1f 762 UgaDraw = Private->UgaDraw;\r
763\r
764 MaxColumn = Private->ModeData[Mode].Columns;\r
765 MaxRow = Private->ModeData[Mode].Rows;\r
766 DeltaX = Private->ModeData[Mode].DeltaX;\r
767 DeltaY = Private->ModeData[Mode].DeltaY;\r
768 Width = MaxColumn * GLYPH_WIDTH;\r
769 Height = (MaxRow - 1) * GLYPH_HEIGHT;\r
406adcd1 770 Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
878ddf1f 771\r
772 //\r
773 // The Attributes won't change when during the time OutputString is called\r
774 //\r
775 GetTextColors (This, &Foreground, &Background);\r
776\r
777 EraseCursor (This);\r
778\r
779 Warning = FALSE;\r
780\r
781 //\r
782 // Backup attribute\r
783 //\r
784 OriginAttribute = This->Mode->Attribute;\r
785\r
786 while (*WString) {\r
787\r
788 if (*WString == CHAR_BACKSPACE) {\r
789 //\r
790 // If the cursor is at the left edge of the display, then move the cursor\r
791 // one row up.\r
792 //\r
793 if (This->Mode->CursorColumn == 0 && This->Mode->CursorRow > 0) {\r
794 This->Mode->CursorRow--;\r
795 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);\r
796 This->OutputString (This, SpaceStr);\r
797 EraseCursor (This);\r
798 This->Mode->CursorRow--;\r
799 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);\r
800 } else if (This->Mode->CursorColumn > 0) {\r
801 //\r
802 // If the cursor is not at the left edge of the display, then move the cursor\r
803 // left one column.\r
804 //\r
805 This->Mode->CursorColumn--;\r
806 This->OutputString (This, SpaceStr);\r
807 EraseCursor (This);\r
808 This->Mode->CursorColumn--;\r
809 }\r
810\r
811 WString++;\r
812\r
813 } else if (*WString == CHAR_LINEFEED) {\r
814 //\r
815 // If the cursor is at the bottom of the display, then scroll the display one\r
816 // row, and do not update the cursor position. Otherwise, move the cursor\r
817 // down one row.\r
818 //\r
819 if (This->Mode->CursorRow == (INT32) (MaxRow - 1)) {\r
406adcd1 820 if (GraphicsOutput != NULL) {\r
821 //\r
822 // Scroll Screen Up One Row\r
823 //\r
824 GraphicsOutput->Blt (\r
825 GraphicsOutput,\r
826 NULL,\r
827 EfiBltVideoToVideo,\r
828 DeltaX,\r
829 DeltaY + GLYPH_HEIGHT,\r
830 DeltaX,\r
831 DeltaY,\r
832 Width,\r
833 Height,\r
834 Delta\r
835 );\r
878ddf1f 836\r
406adcd1 837 //\r
838 // Print Blank Line at last line\r
839 //\r
840 GraphicsOutput->Blt (\r
841 GraphicsOutput,\r
842 &Background,\r
843 EfiBltVideoFill,\r
844 0,\r
845 0,\r
846 DeltaX,\r
847 DeltaY + Height,\r
848 Width,\r
849 GLYPH_HEIGHT,\r
850 Delta\r
851 );\r
852 } else {\r
853 //\r
854 // Scroll Screen Up One Row\r
855 //\r
856 UgaDraw->Blt (\r
857 UgaDraw,\r
858 NULL,\r
859 EfiUgaVideoToVideo,\r
860 DeltaX,\r
861 DeltaY + GLYPH_HEIGHT,\r
862 DeltaX,\r
863 DeltaY,\r
864 Width,\r
865 Height,\r
866 Delta\r
867 );\r
878ddf1f 868\r
406adcd1 869 //\r
870 // Print Blank Line at last line\r
871 //\r
872 UgaDraw->Blt (\r
873 UgaDraw,\r
874 (EFI_UGA_PIXEL *) (UINTN) &Background,\r
875 EfiUgaVideoFill,\r
876 0,\r
877 0,\r
878 DeltaX,\r
879 DeltaY + Height,\r
880 Width,\r
881 GLYPH_HEIGHT,\r
882 Delta\r
883 );\r
884 }\r
878ddf1f 885 } else {\r
886 This->Mode->CursorRow++;\r
887 }\r
888\r
889 WString++;\r
890\r
891 } else if (*WString == CHAR_CARRIAGE_RETURN) {\r
892 //\r
893 // Move the cursor to the beginning of the current row.\r
894 //\r
895 This->Mode->CursorColumn = 0;\r
896 WString++;\r
897\r
898 } else if (*WString == WIDE_CHAR) {\r
899\r
900 This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;\r
901 WString++;\r
902\r
903 } else if (*WString == NARROW_CHAR) {\r
904\r
905 This->Mode->Attribute &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);\r
906 WString++;\r
907\r
908 } else {\r
909 //\r
910 // Print the character at the current cursor position and move the cursor\r
911 // right one column. If this moves the cursor past the right edge of the\r
912 // display, then the line should wrap to the beginning of the next line. This\r
913 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the\r
914 // bottom of the display, and the line wraps, then the display will be scrolled\r
915 // one line.\r
916 // If wide char is going to be displayed, need to display one character at a time\r
917 // Or, need to know the display length of a certain string.\r
918 //\r
919 // Index is used to determine how many character width units (wide = 2, narrow = 1)\r
920 // Count is used to determine how many characters are used regardless of their attributes\r
921 //\r
922 for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {\r
923 if (WString[Count] == CHAR_NULL) {\r
924 break;\r
925 }\r
926\r
927 if (WString[Count] == CHAR_BACKSPACE) {\r
928 break;\r
929 }\r
930\r
931 if (WString[Count] == CHAR_LINEFEED) {\r
932 break;\r
933 }\r
934\r
935 if (WString[Count] == CHAR_CARRIAGE_RETURN) {\r
936 break;\r
937 }\r
938\r
939 if (WString[Count] == WIDE_CHAR) {\r
940 break;\r
941 }\r
942\r
943 if (WString[Count] == NARROW_CHAR) {\r
944 break;\r
945 }\r
946 //\r
947 // Is the wide attribute on?\r
948 //\r
949 if (This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) {\r
950 //\r
951 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop\r
952 //\r
953 Index++;\r
954 //\r
955 // This is the end-case where if we are at column 79 and about to print a wide character\r
956 // We should prevent this from happening because we will wrap inappropriately. We should\r
957 // not print this character until the next line.\r
958 //\r
959 if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {\r
960 Index++;\r
961 break;\r
962 }\r
963 }\r
964 }\r
965\r
966 Status = DrawUnicodeWeightAtCursorN (This, WString, Count);\r
967 if (EFI_ERROR (Status)) {\r
968 Warning = TRUE;\r
969 }\r
970 //\r
971 // At the end of line, output carriage return and line feed\r
972 //\r
973 WString += Count;\r
974 This->Mode->CursorColumn += (INT32) Index;\r
975 if (This->Mode->CursorColumn > (INT32) MaxColumn) {\r
976 This->Mode->CursorColumn -= 2;\r
977 This->OutputString (This, SpaceStr);\r
978 }\r
979\r
980 if (This->Mode->CursorColumn >= (INT32) MaxColumn) {\r
981 EraseCursor (This);\r
982 This->OutputString (This, mCrLfString);\r
983 EraseCursor (This);\r
984 }\r
985 }\r
986 }\r
987\r
988 This->Mode->Attribute = OriginAttribute;\r
989\r
990 EraseCursor (This);\r
991\r
992 if (Warning) {\r
993 return EFI_WARN_UNKNOWN_GLYPH;\r
994 }\r
995\r
996 return EFI_SUCCESS;\r
997}\r
998\r
999EFI_STATUS\r
1000EFIAPI\r
1001GraphicsConsoleConOutTestString (\r
1002 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
1003 IN CHAR16 *WString\r
1004 )\r
1005/*++\r
1006 Routine Description:\r
1007 \r
1008 Implements SIMPLE_TEXT_OUTPUT.TestString().\r
1009 If one of the characters in the *Wstring is\r
1010 neither valid valid Unicode drawing characters,\r
1011 not ASCII code, then this function will return\r
1012 EFI_UNSUPPORTED.\r
1013 \r
1014 \r
1015 Arguments:\r
1016 \r
1017 This - Indicates the calling context.\r
1018 \r
1019 WString - The Null-terminated Unicode string to be tested.\r
1020 \r
1021 Returns:\r
1022 \r
1023 EFI_SUCCESS\r
1024 The Graphics Console is capable of rendering the output string. \r
1025 \r
1026 EFI_UNSUPPORTED\r
1027 Some of the characters in the Unicode string cannot be rendered. \r
1028 \r
1029--*/\r
1030{\r
1031 EFI_STATUS Status;\r
1032 UINT16 GlyphWidth;\r
1033 UINT32 GlyphStatus;\r
1034 UINT16 Count;\r
1035 GRAPHICS_CONSOLE_DEV *Private;\r
1036 GLYPH_UNION *Glyph;\r
1037\r
1038 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1039 GlyphStatus = 0;\r
1040 Count = 0;\r
1041\r
1042 while (WString[Count]) {\r
1043 Status = mHii->GetGlyph (\r
1044 mHii,\r
1045 WString,\r
1046 &Count,\r
1047 (UINT8 **) &Glyph,\r
1048 &GlyphWidth,\r
1049 &GlyphStatus\r
1050 );\r
1051\r
1052 if (EFI_ERROR (Status)) {\r
1053 return EFI_UNSUPPORTED;\r
1054 }\r
1055 }\r
1056\r
1057 return EFI_SUCCESS;\r
1058}\r
1059\r
1060EFI_STATUS\r
1061EFIAPI\r
1062GraphicsConsoleConOutQueryMode (\r
1063 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
1064 IN UINTN ModeNumber,\r
1065 OUT UINTN *Columns,\r
1066 OUT UINTN *Rows\r
1067 )\r
1068/*++\r
1069 Routine Description:\r
1070 \r
1071 Implements SIMPLE_TEXT_OUTPUT.QueryMode().\r
1072 It returnes information for an available text mode\r
1073 that the Graphics Console supports.\r
1074 In this driver,we only support text mode 80x25, which is\r
1075 defined as mode 0.\r
1076 \r
1077 \r
1078 Arguments:\r
1079 \r
1080 This - Indicates the calling context.\r
1081 \r
1082 ModeNumber - The mode number to return information on.\r
1083 \r
1084 Columns - The returned columns of the requested mode.\r
1085 \r
1086 Rows - The returned rows of the requested mode. \r
1087 \r
1088 Returns:\r
1089 \r
1090 EFI_SUCCESS\r
1091 The requested mode information is returned. \r
1092 \r
1093 EFI_UNSUPPORTED\r
1094 The mode number is not valid. \r
1095 \r
1096--*/\r
1097{\r
1098 GRAPHICS_CONSOLE_DEV *Private;\r
1099\r
1100 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {\r
1101 return EFI_UNSUPPORTED;\r
1102 }\r
1103\r
1104 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1105\r
1106 *Columns = Private->ModeData[ModeNumber].Columns;\r
1107 *Rows = Private->ModeData[ModeNumber].Rows;\r
1108\r
1109 if (*Columns <= 0 && *Rows <= 0) {\r
1110 return EFI_UNSUPPORTED;\r
1111\r
1112 }\r
1113\r
1114 return EFI_SUCCESS;\r
1115}\r
1116\r
1117EFI_STATUS\r
1118EFIAPI\r
1119GraphicsConsoleConOutSetMode (\r
1120 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
1121 IN UINTN ModeNumber\r
1122 )\r
1123/*++\r
1124 Routine Description:\r
1125 \r
1126 Implements SIMPLE_TEXT_OUTPUT.SetMode().\r
1127 Set the Graphics Console to a specified mode.\r
1128 In this driver, we only support mode 0. \r
1129 \r
1130 Arguments:\r
1131 \r
1132 This - Indicates the calling context.\r
1133 \r
1134 ModeNumber - The text mode to set.\r
1135 \r
1136 Returns:\r
1137 \r
1138 EFI_SUCCESS\r
1139 The requested text mode is set.\r
1140 \r
1141 EFI_DEVICE_ERROR\r
1142 The requested text mode cannot be set because of Graphics Console device error.\r
1143 \r
1144 EFI_UNSUPPORTED\r
1145 The text mode number is not valid. \r
1146 \r
1147--*/\r
1148{\r
1149 EFI_STATUS Status;\r
1150 GRAPHICS_CONSOLE_DEV *Private;\r
878ddf1f 1151 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
406adcd1 1152 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewLineBuffer;\r
878ddf1f 1153 UINT32 HorizontalResolution;\r
1154 UINT32 VerticalResolution;\r
406adcd1 1155 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1156 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
878ddf1f 1157 UINT32 ColorDepth;\r
1158 UINT32 RefreshRate;\r
1159\r
1160 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
406adcd1 1161 GraphicsOutput = Private->GraphicsOutput;\r
878ddf1f 1162 UgaDraw = Private->UgaDraw;\r
1163 ModeData = &(Private->ModeData[ModeNumber]);\r
1164\r
e313deb9 1165 if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {\r
1166 return EFI_UNSUPPORTED;\r
1167 }\r
1168\r
878ddf1f 1169 //\r
1170 // Make sure the requested mode number is supported\r
1171 //\r
1172 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {\r
1173 return EFI_UNSUPPORTED;\r
1174 }\r
1175\r
1176 if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {\r
1177 return EFI_UNSUPPORTED;\r
1178 }\r
1179 //\r
1180 // Attempt to allocate a line buffer for the requested mode number\r
1181 //\r
1182 Status = gBS->AllocatePool (\r
1183 EfiBootServicesData,\r
406adcd1 1184 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * GLYPH_WIDTH * GLYPH_HEIGHT,\r
878ddf1f 1185 (VOID **) &NewLineBuffer\r
1186 );\r
1187 if (EFI_ERROR (Status)) {\r
1188 //\r
1189 // The new line buffer could not be allocated, so return an error.\r
1190 // No changes to the state of the current console have been made, so the current console is still valid\r
1191 //\r
1192 return Status;\r
1193 }\r
1194 //\r
1195 // If the mode has been set at least one other time, then LineBuffer will not be NULL\r
1196 //\r
1197 if (Private->LineBuffer != NULL) {\r
1198 //\r
1199 // Clear the current text window on the current graphics console\r
1200 //\r
1201 This->ClearScreen (This);\r
1202\r
1203 //\r
1204 // If the new mode is the same as the old mode, then just return EFI_SUCCESS\r
1205 //\r
1206 if ((INT32) ModeNumber == This->Mode->Mode) {\r
1207 gBS->FreePool (NewLineBuffer);\r
1208 return EFI_SUCCESS;\r
1209 }\r
1210 //\r
1211 // Otherwise, the size of the text console and/or the UGA mode will be changed,\r
1212 // so turn off the cursor, and free the LineBuffer for the current mode\r
1213 //\r
1214 This->EnableCursor (This, FALSE);\r
1215\r
1216 gBS->FreePool (Private->LineBuffer);\r
1217 }\r
1218 //\r
1219 // Assign the current line buffer to the newly allocated line buffer\r
1220 //\r
1221 Private->LineBuffer = NewLineBuffer;\r
1222\r
406adcd1 1223 if (GraphicsOutput != NULL) {\r
1224 if (ModeData->GopModeNumber != GraphicsOutput->Mode->Mode) {\r
878ddf1f 1225 //\r
406adcd1 1226 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode\r
878ddf1f 1227 //\r
406adcd1 1228 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeData->GopModeNumber);\r
1229 if (EFI_ERROR (Status)) {\r
1230 //\r
1231 // The mode set operation failed\r
1232 //\r
1233 return Status;\r
1234 }\r
1235 } else {\r
1236 //\r
1237 // The current graphics mode is correct, so simply clear the entire display\r
1238 //\r
1239 Status = GraphicsOutput->Blt (\r
1240 GraphicsOutput,\r
1241 &mEfiColors[0],\r
1242 EfiBltVideoFill,\r
1243 0,\r
1244 0,\r
1245 0,\r
1246 0,\r
1247 ModeData->GopWidth,\r
1248 ModeData->GopHeight,\r
1249 0\r
1250 );\r
878ddf1f 1251 }\r
1252 } else {\r
1253 //\r
406adcd1 1254 // Get the current UGA Draw mode information\r
878ddf1f 1255 //\r
406adcd1 1256 Status = UgaDraw->GetMode (\r
878ddf1f 1257 UgaDraw,\r
406adcd1 1258 &HorizontalResolution,\r
1259 &VerticalResolution,\r
1260 &ColorDepth,\r
1261 &RefreshRate\r
878ddf1f 1262 );\r
406adcd1 1263 if (EFI_ERROR (Status) || HorizontalResolution != ModeData->GopWidth || VerticalResolution != ModeData->GopHeight) {\r
1264 //\r
1265 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode\r
1266 //\r
1267 Status = UgaDraw->SetMode (\r
1268 UgaDraw,\r
1269 ModeData->GopWidth,\r
1270 ModeData->GopHeight,\r
1271 32,\r
1272 60\r
1273 );\r
1274 if (EFI_ERROR (Status)) {\r
1275 //\r
1276 // The mode set operation failed\r
1277 //\r
1278 return Status;\r
1279 }\r
1280 } else {\r
1281 //\r
1282 // The current graphics mode is correct, so simply clear the entire display\r
1283 //\r
1284 Status = UgaDraw->Blt (\r
1285 UgaDraw,\r
1286 (EFI_UGA_PIXEL *) (UINTN) &mEfiColors[0],\r
1287 EfiUgaVideoFill,\r
1288 0,\r
1289 0,\r
1290 0,\r
1291 0,\r
1292 ModeData->GopWidth,\r
1293 ModeData->GopHeight,\r
1294 0\r
1295 );\r
1296 }\r
878ddf1f 1297 }\r
406adcd1 1298\r
878ddf1f 1299 //\r
1300 // The new mode is valid, so commit the mode change\r
1301 //\r
1302 This->Mode->Mode = (INT32) ModeNumber;\r
1303\r
1304 //\r
1305 // Move the text cursor to the upper left hand corner of the displat and enable it\r
1306 //\r
1307 This->SetCursorPosition (This, 0, 0);\r
1308 This->EnableCursor (This, TRUE);\r
1309\r
1310 return EFI_SUCCESS;\r
1311}\r
1312\r
1313EFI_STATUS\r
1314EFIAPI\r
1315GraphicsConsoleConOutSetAttribute (\r
1316 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
1317 IN UINTN Attribute\r
1318 )\r
1319/*++\r
1320 Routine Description:\r
1321 \r
1322 Implements SIMPLE_TEXT_OUTPUT.SetAttribute(). \r
1323 \r
1324 Arguments:\r
1325 \r
1326 This - Indicates the calling context.\r
1327 \r
1328 Attrubute - The attribute to set. Only bit0..6 are valid, all other bits\r
1329 are undefined and must be zero.\r
1330 \r
1331 Returns:\r
1332 \r
1333 EFI_SUCCESS\r
1334 The requested attribute is set. \r
1335 \r
1336 EFI_DEVICE_ERROR\r
1337 The requested attribute cannot be set due to Graphics Console port error.\r
1338 \r
1339 EFI_UNSUPPORTED\r
1340 The attribute requested is not defined by EFI spec. \r
1341 \r
1342--*/\r
1343{\r
1344 if ((Attribute | 0xFF) != 0xFF) {\r
1345 return EFI_UNSUPPORTED;\r
1346 }\r
1347\r
1348 if ((INT32) Attribute == This->Mode->Attribute) {\r
1349 return EFI_SUCCESS;\r
1350 }\r
1351\r
1352 EraseCursor (This);\r
1353\r
1354 This->Mode->Attribute = (INT32) Attribute;\r
1355\r
1356 EraseCursor (This);\r
1357\r
1358 return EFI_SUCCESS;\r
1359}\r
1360\r
1361EFI_STATUS\r
1362EFIAPI\r
1363GraphicsConsoleConOutClearScreen (\r
1364 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This\r
1365 )\r
1366/*++\r
1367 Routine Description:\r
1368 \r
1369 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().\r
1370 It clears the Graphics Console's display to the \r
1371 currently selected background color.\r
1372 \r
1373 \r
1374 Arguments:\r
1375 \r
1376 This - Indicates the calling context.\r
1377\r
1378 Returns:\r
1379 \r
1380 EFI_SUCCESS\r
1381 The operation completed successfully.\r
1382 \r
1383 EFI_DEVICE_ERROR\r
1384 The Graphics Console cannot be cleared due to Graphics Console device error. \r
1385 \r
1386 EFI_UNSUPPORTED\r
1387 The Graphics Console is not in a valid text mode. \r
1388 \r
1389--*/\r
1390{\r
1391 EFI_STATUS Status;\r
1392 GRAPHICS_CONSOLE_DEV *Private;\r
1393 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
406adcd1 1394 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
878ddf1f 1395 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
406adcd1 1396 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
1397 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
878ddf1f 1398\r
1399 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
406adcd1 1400 GraphicsOutput = Private->GraphicsOutput;\r
878ddf1f 1401 UgaDraw = Private->UgaDraw;\r
1402 ModeData = &(Private->ModeData[This->Mode->Mode]);\r
1403\r
1404 GetTextColors (This, &Foreground, &Background);\r
406adcd1 1405 if (GraphicsOutput != NULL) {\r
1406 Status = GraphicsOutput->Blt (\r
1407 GraphicsOutput,\r
1408 &Background,\r
1409 EfiBltVideoFill,\r
1410 0,\r
1411 0,\r
1412 0,\r
1413 0,\r
1414 ModeData->GopWidth,\r
1415 ModeData->GopHeight,\r
1416 0\r
1417 );\r
1418 } else {\r
1419 Status = UgaDraw->Blt (\r
1420 UgaDraw,\r
1421 (EFI_UGA_PIXEL *) (UINTN) &Background,\r
1422 EfiUgaVideoFill,\r
1423 0,\r
1424 0,\r
1425 0,\r
1426 0,\r
1427 ModeData->GopWidth,\r
1428 ModeData->GopHeight,\r
1429 0\r
1430 );\r
1431 }\r
878ddf1f 1432\r
1433 This->Mode->CursorColumn = 0;\r
1434 This->Mode->CursorRow = 0;\r
1435\r
1436 EraseCursor (This);\r
1437\r
1438 return Status;\r
1439}\r
1440\r
1441EFI_STATUS\r
1442EFIAPI\r
1443GraphicsConsoleConOutSetCursorPosition (\r
1444 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
1445 IN UINTN Column,\r
1446 IN UINTN Row\r
1447 )\r
1448/*++\r
1449 Routine Description:\r
1450 \r
1451 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition(). \r
1452 \r
1453 Arguments:\r
1454 \r
1455 This - Indicates the calling context.\r
1456 \r
1457 Column - The row to set cursor to.\r
1458 \r
1459 Row - The column to set cursor to. \r
1460\r
1461 Returns:\r
1462 \r
1463 EFI_SUCCESS\r
1464 The operation completed successfully.\r
1465 \r
1466 EFI_DEVICE_ERROR\r
1467 The request fails due to Graphics Console device error. \r
1468 \r
1469 EFI_UNSUPPORTED\r
1470 The Graphics Console is not in a valid text mode, or the cursor position\r
1471 is invalid for current mode. \r
1472 \r
1473--*/\r
1474{\r
1475 GRAPHICS_CONSOLE_DEV *Private;\r
1476 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1477\r
1478 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1479 ModeData = &(Private->ModeData[This->Mode->Mode]);\r
1480\r
1481 if ((Column >= ModeData->Columns) || (Row >= ModeData->Rows)) {\r
1482 return EFI_UNSUPPORTED;\r
1483 }\r
1484\r
1485 if (((INT32) Column == This->Mode->CursorColumn) && ((INT32) Row == This->Mode->CursorRow)) {\r
1486 return EFI_SUCCESS;\r
1487 }\r
1488\r
1489 EraseCursor (This);\r
1490\r
1491 This->Mode->CursorColumn = (INT32) Column;\r
1492 This->Mode->CursorRow = (INT32) Row;\r
1493\r
1494 EraseCursor (This);\r
1495\r
1496 return EFI_SUCCESS;\r
1497}\r
1498\r
1499EFI_STATUS\r
1500EFIAPI\r
1501GraphicsConsoleConOutEnableCursor (\r
1502 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
1503 IN BOOLEAN Visible\r
1504 )\r
1505/*++\r
1506 Routine Description:\r
1507 \r
1508 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().\r
1509 In this driver, the cursor cannot be hidden. \r
1510 \r
1511 Arguments:\r
1512 \r
1513 This - Indicates the calling context.\r
1514 \r
1515 Visible - If TRUE, the cursor is set to be visible,\r
1516 If FALSE, the cursor is set to be invisible. \r
1517\r
1518 Returns:\r
1519 \r
1520 EFI_SUCCESS\r
1521 The request is valid.\r
1522 \r
1523 EFI_UNSUPPORTED\r
1524 The Graphics Console does not support a hidden cursor. \r
1525 \r
1526--*/\r
1527{\r
1528 EraseCursor (This);\r
1529\r
1530 This->Mode->CursorVisible = Visible;\r
1531\r
1532 EraseCursor (This);\r
1533\r
1534 return EFI_SUCCESS;\r
1535}\r
1536\r
1537EFI_STATUS\r
1538GetTextColors (\r
1539 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
406adcd1 1540 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
1541 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background\r
878ddf1f 1542 )\r
1543{\r
1544 INTN Attribute;\r
1545\r
1546 Attribute = This->Mode->Attribute & 0x7F;\r
1547\r
1548 *Foreground = mEfiColors[Attribute & 0x0f];\r
1549 *Background = mEfiColors[Attribute >> 4];\r
1550\r
1551 return EFI_SUCCESS;\r
1552}\r
1553\r
1554EFI_STATUS\r
1555DrawUnicodeWeightAtCursorN (\r
1556 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
1557 IN CHAR16 *UnicodeWeight,\r
1558 IN UINTN Count\r
1559 )\r
1560{\r
1561 GRAPHICS_CONSOLE_DEV *Private;\r
1562 EFI_STATUS Status;\r
1563 EFI_STATUS ReturnStatus;\r
1564 GLYPH_UNION *Glyph;\r
1565 GLYPH_UNION GlyphData;\r
1566 INTN GlyphX;\r
1567 INTN GlyphY;\r
406adcd1 1568 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
878ddf1f 1569 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
406adcd1 1570 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
1571 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
878ddf1f 1572 UINTN Index;\r
1573 UINTN ArrayIndex;\r
1574 UINTN Counts;\r
1575 UINT16 GlyphWidth;\r
1576 UINT32 GlyphStatus;\r
1577\r
1578 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1579\r
1580 ReturnStatus = EFI_SUCCESS;\r
1581 GlyphStatus = 0;\r
1582 GlyphWidth = 0x08;\r
1583\r
1584 GetTextColors (This, &Foreground, &Background);\r
1585\r
1586 Index = 0;\r
1587 ArrayIndex = 0;\r
1588 while (Index < Count) {\r
1589 if (This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) {\r
1590 GlyphStatus = WIDE_CHAR;\r
1591 } else {\r
1592 GlyphStatus = NARROW_CHAR;\r
1593 }\r
1594\r
1595 Status = mHii->GetGlyph (\r
1596 mHii,\r
1597 UnicodeWeight,\r
1598 (UINT16 *) &Index,\r
1599 (UINT8 **) &Glyph,\r
1600 &GlyphWidth,\r
1601 &GlyphStatus\r
1602 );\r
1603 if (EFI_ERROR (Status)) {\r
1604 ReturnStatus = Status;\r
1605 }\r
1606\r
1607 Counts = 0;\r
1608\r
1609 CopyMem (&GlyphData, Glyph, sizeof (GLYPH_UNION));\r
1610\r
1611 do {\r
1612 //\r
1613 // We are creating the second half of the wide character's BLT buffer\r
1614 //\r
1615 if (GlyphWidth == 0x10 && Counts == 1) {\r
1616 CopyMem (&GlyphData.NarrowGlyph.GlyphCol1, &Glyph->WideGlyph.GlyphCol2, sizeof (Glyph->WideGlyph.GlyphCol2));\r
1617 }\r
1618\r
1619 Counts++;\r
1620\r
1621 if (GlyphWidth == 0x10) {\r
1622 mHii->GlyphToBlt (\r
1623 mHii,\r
1624 (UINT8 *) &GlyphData,\r
1625 Foreground,\r
1626 Background,\r
1627 Count * 2,\r
1628 GLYPH_WIDTH,\r
1629 GLYPH_HEIGHT,\r
1630 &Private->LineBuffer[ArrayIndex * GLYPH_WIDTH]\r
1631 );\r
1632 } else {\r
1633 mHii->GlyphToBlt (\r
1634 mHii,\r
1635 (UINT8 *) &GlyphData,\r
1636 Foreground,\r
1637 Background,\r
1638 Count,\r
1639 GLYPH_WIDTH,\r
1640 GLYPH_HEIGHT,\r
1641 &Private->LineBuffer[ArrayIndex * GLYPH_WIDTH]\r
1642 );\r
1643 }\r
1644\r
1645 ArrayIndex++;\r
1646\r
1647 } while (Counts < 2 && GlyphWidth == 0x10);\r
1648\r
1649 }\r
1650 //\r
1651 // If we are printing Wide characters, treat the BLT as if it is twice as many characters\r
1652 //\r
1653 if (GlyphWidth == 0x10) {\r
1654 Count = Count * 2;\r
1655 }\r
1656 //\r
1657 // Blt a character to the screen\r
1658 //\r
1659 GlyphX = This->Mode->CursorColumn * GLYPH_WIDTH;\r
1660 GlyphY = This->Mode->CursorRow * GLYPH_HEIGHT;\r
406adcd1 1661 GraphicsOutput = Private->GraphicsOutput;\r
878ddf1f 1662 UgaDraw = Private->UgaDraw;\r
406adcd1 1663 if (GraphicsOutput != NULL) {\r
1664 GraphicsOutput->Blt (\r
1665 GraphicsOutput,\r
1666 Private->LineBuffer,\r
1667 EfiBltBufferToVideo,\r
1668 0,\r
1669 0,\r
1670 GlyphX + Private->ModeData[This->Mode->Mode].DeltaX,\r
1671 GlyphY + Private->ModeData[This->Mode->Mode].DeltaY,\r
1672 GLYPH_WIDTH * Count,\r
1673 GLYPH_HEIGHT,\r
1674 GLYPH_WIDTH * Count * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1675 );\r
1676 } else {\r
1677 UgaDraw->Blt (\r
1678 UgaDraw,\r
1679 (EFI_UGA_PIXEL *) (UINTN) Private->LineBuffer,\r
1680 EfiUgaBltBufferToVideo,\r
1681 0,\r
1682 0,\r
1683 GlyphX + Private->ModeData[This->Mode->Mode].DeltaX,\r
1684 GlyphY + Private->ModeData[This->Mode->Mode].DeltaY,\r
1685 GLYPH_WIDTH * Count,\r
1686 GLYPH_HEIGHT,\r
1687 GLYPH_WIDTH * Count * sizeof (EFI_UGA_PIXEL)\r
1688 );\r
1689 }\r
878ddf1f 1690\r
1691 return ReturnStatus;\r
1692}\r
1693\r
1694EFI_STATUS\r
1695EraseCursor (\r
1696 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This\r
1697 )\r
1698{\r
1699 GRAPHICS_CONSOLE_DEV *Private;\r
1700 EFI_SIMPLE_TEXT_OUTPUT_MODE *CurrentMode;\r
1701 INTN GlyphX;\r
1702 INTN GlyphY;\r
406adcd1 1703 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
878ddf1f 1704 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
406adcd1 1705 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground;\r
1706 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background;\r
1707 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar[GLYPH_HEIGHT][GLYPH_WIDTH];\r
878ddf1f 1708 UINTN X;\r
1709 UINTN Y;\r
1710\r
1711 CurrentMode = This->Mode;\r
1712\r
1713 if (!CurrentMode->CursorVisible) {\r
1714 return EFI_SUCCESS;\r
1715 }\r
1716\r
1717 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
406adcd1 1718 GraphicsOutput = Private->GraphicsOutput;\r
878ddf1f 1719 UgaDraw = Private->UgaDraw;\r
1720\r
1721 //\r
1722 // BUGBUG - we need to think about what to do with wide and narrow character deletions.\r
1723 //\r
1724 //\r
1725 // Blt a character to the screen\r
1726 //\r
1727 GlyphX = (CurrentMode->CursorColumn * GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;\r
1728 GlyphY = (CurrentMode->CursorRow * GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;\r
406adcd1 1729 if (GraphicsOutput != NULL) {\r
1730 GraphicsOutput->Blt (\r
1731 GraphicsOutput,\r
1732 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,\r
1733 EfiBltVideoToBltBuffer,\r
1734 GlyphX,\r
1735 GlyphY,\r
1736 0,\r
1737 0,\r
1738 GLYPH_WIDTH,\r
1739 GLYPH_HEIGHT,\r
1740 GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1741 );\r
1742 } else {\r
1743 UgaDraw->Blt (\r
1744 UgaDraw,\r
1745 (EFI_UGA_PIXEL *) (UINTN) BltChar,\r
1746 EfiUgaVideoToBltBuffer,\r
1747 GlyphX,\r
1748 GlyphY,\r
1749 0,\r
1750 0,\r
1751 GLYPH_WIDTH,\r
1752 GLYPH_HEIGHT,\r
1753 GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
1754 );\r
1755 }\r
878ddf1f 1756\r
1757 GetTextColors (This, &Foreground.Pixel, &Background.Pixel);\r
1758\r
1759 //\r
1760 // Convert Monochrome bitmap of the Glyph to BltBuffer structure\r
1761 //\r
1762 for (Y = 0; Y < GLYPH_HEIGHT; Y++) {\r
1763 for (X = 0; X < GLYPH_WIDTH; X++) {\r
1764 if ((mCursorGlyph.GlyphCol1[Y] & (1 << X)) != 0) {\r
1765 BltChar[Y][GLYPH_WIDTH - X - 1].Raw ^= Foreground.Raw;\r
1766 }\r
1767 }\r
1768 }\r
1769\r
406adcd1 1770 if (GraphicsOutput != NULL) {\r
1771 GraphicsOutput->Blt (\r
1772 GraphicsOutput,\r
1773 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,\r
1774 EfiBltBufferToVideo,\r
1775 0,\r
1776 0,\r
1777 GlyphX,\r
1778 GlyphY,\r
1779 GLYPH_WIDTH,\r
1780 GLYPH_HEIGHT,\r
1781 GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1782 );\r
1783 } else {\r
1784 UgaDraw->Blt (\r
1785 UgaDraw,\r
1786 (EFI_UGA_PIXEL *) (UINTN) BltChar,\r
1787 EfiUgaBltBufferToVideo,\r
1788 0,\r
1789 0,\r
1790 GlyphX,\r
1791 GlyphY,\r
1792 GLYPH_WIDTH,\r
1793 GLYPH_HEIGHT,\r
1794 GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
1795 );\r
1796 }\r
878ddf1f 1797\r
1798 return EFI_SUCCESS;\r
1799}\r