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