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