Check comments, format and fix some typo.
[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
8541adab 3\r
6dcf9abc 4Copyright (c) 2006 - 2008 Intel Corporation. <BR>\r
8541adab 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
95276127 12\r
13**/\r
14\r
95276127 15#include "GraphicsConsole.h"\r
16\r
95276127 17//\r
878670ea 18// Graphics Console Device Private Data template\r
95276127 19//\r
fe1e36e5 20GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate = {\r
95276127 21 GRAPHICS_CONSOLE_DEV_SIGNATURE,\r
22 (EFI_GRAPHICS_OUTPUT_PROTOCOL *) NULL,\r
23 (EFI_UGA_DRAW_PROTOCOL *) NULL,\r
24 {\r
25 GraphicsConsoleConOutReset,\r
26 GraphicsConsoleConOutOutputString,\r
27 GraphicsConsoleConOutTestString,\r
28 GraphicsConsoleConOutQueryMode,\r
29 GraphicsConsoleConOutSetMode,\r
30 GraphicsConsoleConOutSetAttribute,\r
31 GraphicsConsoleConOutClearScreen,\r
32 GraphicsConsoleConOutSetCursorPosition,\r
33 GraphicsConsoleConOutEnableCursor,\r
34 (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL\r
35 },\r
36 {\r
37 0,\r
38 0,\r
39 EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_BLACK),\r
40 0,\r
41 0,\r
42 TRUE\r
43 },\r
44 {\r
45 { 80, 25, 0, 0, 0, 0 }, // Mode 0\r
3012ce5c 46 { 80, 50, 0, 0, 0, 0 }, // Mode 1\r
47 { 100,31, 0, 0, 0, 0 }, // Mode 2\r
48 { 0, 0, 0, 0, 0, 0 } // Mode 3\r
95276127 49 },\r
50 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
93e3992d 51 (EFI_HII_HANDLE ) 0\r
95276127 52};\r
53\r
93e3992d 54EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;\r
55EFI_HII_FONT_PROTOCOL *mHiiFont;\r
56BOOLEAN mFirstAccessFlag = TRUE;\r
57\r
555e76f8 58EFI_GUID mFontPackageListGuid = {0xf5f219d3, 0x7006, 0x4648, {0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad}};\r
93e3992d 59\r
fe1e36e5 60CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };\r
95276127 61\r
fe1e36e5 62EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {\r
95276127 63 //\r
878670ea 64 // B G R reserved\r
95276127 65 //\r
66 {0x00, 0x00, 0x00, 0x00}, // BLACK\r
878670ea 67 {0x98, 0x00, 0x00, 0x00}, // LIGHTBLUE\r
68 {0x00, 0x98, 0x00, 0x00}, // LIGHGREEN\r
69 {0x98, 0x98, 0x00, 0x00}, // LIGHCYAN\r
70 {0x00, 0x00, 0x98, 0x00}, // LIGHRED\r
95276127 71 {0x98, 0x00, 0x98, 0x00}, // MAGENTA\r
72 {0x00, 0x98, 0x98, 0x00}, // BROWN\r
73 {0x98, 0x98, 0x98, 0x00}, // LIGHTGRAY\r
74 {0x30, 0x30, 0x30, 0x00}, // DARKGRAY - BRIGHT BLACK\r
878670ea 75 {0xff, 0x00, 0x00, 0x00}, // BLUE\r
76 {0x00, 0xff, 0x00, 0x00}, // LIME\r
77 {0xff, 0xff, 0x00, 0x00}, // CYAN\r
78 {0x00, 0x00, 0xff, 0x00}, // RED\r
79 {0xff, 0x00, 0xff, 0x00}, // FUCHSIA\r
80 {0x00, 0xff, 0xff, 0x00}, // YELLOW\r
81 {0xff, 0xff, 0xff, 0x00} // WHITE\r
95276127 82};\r
83\r
fe1e36e5 84EFI_NARROW_GLYPH mCursorGlyph = {\r
95276127 85 0x0000,\r
86 0x00,\r
87 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }\r
88};\r
89\r
fe1e36e5 90CHAR16 SpaceStr[] = { NARROW_CHAR, ' ', 0 };\r
6dcf9abc 91\r
95276127 92EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding = {\r
93 GraphicsConsoleControllerDriverSupported,\r
94 GraphicsConsoleControllerDriverStart,\r
95 GraphicsConsoleControllerDriverStop,\r
96 0xa,\r
97 NULL,\r
98 NULL\r
99};\r
100\r
aa79b0b3 101/**\r
102 Gets Graphics Console devcie's foreground color and background color.\r
103\r
104 @param This Protocol instance pointer.\r
105 @param Foreground Returned text foreground color.\r
106 @param Background Returned text background color.\r
107\r
108 @retval EFI_SUCCESS It returned always.\r
109\r
110**/\r
111EFI_STATUS\r
112GetTextColors (\r
113 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
114 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
115 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background\r
116 );\r
117\r
118/**\r
878670ea 119 Draw Unicode string on the Graphics Console device's screen.\r
aa79b0b3 120\r
121 @param This Protocol instance pointer.\r
122 @param UnicodeWeight One Unicode string to be displayed.\r
123 @param Count The count of Unicode string.\r
124\r
125 @retval EFI_OUT_OF_RESOURCES If no memory resource to use.\r
126 @retval EFI_UNSUPPORTED If no Graphics Output protocol and UGA Draw\r
127 protocol exist.\r
128 @retval EFI_SUCCESS Drawing Unicode string implemented successfully.\r
129\r
130**/\r
131EFI_STATUS\r
132DrawUnicodeWeightAtCursorN (\r
133 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
134 IN CHAR16 *UnicodeWeight,\r
135 IN UINTN Count\r
136 );\r
137\r
138/**\r
139 Erase the cursor on the screen.\r
140\r
141 @param This Protocol instance pointer.\r
142\r
143 @retval EFI_SUCCESS The cursor is erased successfully.\r
144\r
145**/\r
146EFI_STATUS\r
147EraseCursor (\r
148 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
149 );\r
150\r
151/**\r
152 Check if the current specific mode supported the user defined resolution\r
878670ea 153 for the Graphics Console device based on Graphics Output Protocol.\r
aa79b0b3 154\r
878670ea 155 If yes, set the graphic device's current mode to this specific mode.\r
aa79b0b3 156 \r
157 @param GraphicsOutput Graphics Output Protocol instance pointer.\r
158 @param HorizontalResolution User defined horizontal resolution\r
159 @param VerticalResolution User defined vertical resolution.\r
160 @param CurrentModeNumber Current specific mode to be check.\r
161\r
162 @retval EFI_SUCCESS The mode is supported.\r
163 @retval EFI_UNSUPPORTED The specific mode is out of range of graphics \r
878670ea 164 device supported.\r
aa79b0b3 165 @retval other The specific mode does not support user defined \r
166 resolution or failed to set the current mode to the \r
167 specific mode on graphics device.\r
168\r
169**/\r
170EFI_STATUS\r
171CheckModeSupported (\r
172 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
173 IN UINT32 HorizontalResolution,\r
174 IN UINT32 VerticalResolution,\r
175 OUT UINT32 *CurrentModeNumber\r
176 );\r
177\r
24248368 178\r
179/**\r
8595bdaf 180 Test to see if Graphics Console could be supported on the Controller.\r
24248368 181\r
182 Graphics Console could be supported if Graphics Output Protocol or UGA Draw\r
8595bdaf 183 Protocol exists on the Controller. (UGA Draw Protocol could be skipped\r
24248368 184 if PcdUgaConsumeSupport is set to FALSE.)\r
185\r
186 @param This Protocol instance pointer.\r
8595bdaf 187 @param Controller Handle of device to test.\r
24248368 188 @param RemainingDevicePath Optional parameter use to pick a specific child\r
189 device to start.\r
190\r
8595bdaf 191 @retval EFI_SUCCESS This driver supports this device.\r
192 @retval other This driver does not support this device.\r
24248368 193\r
194**/\r
95276127 195EFI_STATUS\r
196EFIAPI\r
197GraphicsConsoleControllerDriverSupported (\r
198 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
199 IN EFI_HANDLE Controller,\r
200 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
201 )\r
202{\r
8541adab 203 EFI_STATUS Status;\r
95276127 204 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
8541adab 205 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
206 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
95276127 207\r
8541adab 208 GraphicsOutput = NULL;\r
209 UgaDraw = NULL;\r
95276127 210 //\r
211 // Open the IO Abstraction(s) needed to perform the supported test\r
212 //\r
213 Status = gBS->OpenProtocol (\r
214 Controller,\r
215 &gEfiGraphicsOutputProtocolGuid,\r
216 (VOID **) &GraphicsOutput,\r
217 This->DriverBindingHandle,\r
218 Controller,\r
219 EFI_OPEN_PROTOCOL_BY_DRIVER\r
220 );\r
8541adab 221\r
222 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 223 //\r
224 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol\r
225 //\r
226 Status = gBS->OpenProtocol (\r
227 Controller,\r
228 &gEfiUgaDrawProtocolGuid,\r
229 (VOID **) &UgaDraw,\r
230 This->DriverBindingHandle,\r
231 Controller,\r
232 EFI_OPEN_PROTOCOL_BY_DRIVER\r
233 );\r
8541adab 234 }\r
235 if (EFI_ERROR (Status)) {\r
236 return Status;\r
95276127 237 }\r
238\r
239 //\r
240 // We need to ensure that we do not layer on top of a virtual handle.\r
241 // We need to ensure that the handles produced by the conspliter do not\r
242 // get used.\r
243 //\r
244 Status = gBS->OpenProtocol (\r
245 Controller,\r
246 &gEfiDevicePathProtocolGuid,\r
247 (VOID **) &DevicePath,\r
248 This->DriverBindingHandle,\r
249 Controller,\r
250 EFI_OPEN_PROTOCOL_BY_DRIVER\r
251 );\r
252 if (!EFI_ERROR (Status)) {\r
253 gBS->CloseProtocol (\r
254 Controller,\r
255 &gEfiDevicePathProtocolGuid,\r
256 This->DriverBindingHandle,\r
257 Controller\r
258 );\r
259 } else {\r
260 goto Error;\r
261 }\r
93e3992d 262\r
95276127 263 //\r
264 // Does Hii Exist? If not, we aren't ready to run\r
265 //\r
266 Status = EfiLocateHiiProtocol ();\r
267\r
268 //\r
269 // Close the I/O Abstraction(s) used to perform the supported test\r
270 //\r
271Error:\r
272 if (GraphicsOutput != NULL) {\r
273 gBS->CloseProtocol (\r
274 Controller,\r
275 &gEfiGraphicsOutputProtocolGuid,\r
276 This->DriverBindingHandle,\r
277 Controller\r
278 );\r
8541adab 279 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 280 gBS->CloseProtocol (\r
281 Controller,\r
282 &gEfiUgaDrawProtocolGuid,\r
283 This->DriverBindingHandle,\r
284 Controller\r
285 );\r
286 }\r
287 return Status;\r
288}\r
289\r
6dcf9abc 290\r
291/**\r
8595bdaf 292 Start this driver on Controller by opening Graphics Output protocol or \r
293 UGA Draw protocol, and installing Simple Text Out protocol on Controller.\r
878670ea 294 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)\r
24248368 295 \r
296 @param This Protocol instance pointer.\r
8595bdaf 297 @param Controller Handle of device to bind driver to\r
24248368 298 @param RemainingDevicePath Optional parameter use to pick a specific child\r
299 device to start.\r
300\r
8595bdaf 301 @retval EFI_SUCCESS This driver is added to Controller.\r
302 @retval other This driver does not support this device.\r
6dcf9abc 303\r
304**/\r
95276127 305EFI_STATUS\r
306EFIAPI\r
307GraphicsConsoleControllerDriverStart (\r
308 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
309 IN EFI_HANDLE Controller,\r
310 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
311 )\r
95276127 312{\r
3012ce5c 313 EFI_STATUS Status;\r
314 GRAPHICS_CONSOLE_DEV *Private;\r
878670ea 315 UINT32 NarrowFontSize;\r
3012ce5c 316 UINT32 HorizontalResolution;\r
317 UINT32 VerticalResolution;\r
318 UINT32 ColorDepth;\r
319 UINT32 RefreshRate;\r
320 UINTN MaxMode;\r
321 UINTN Columns;\r
322 UINTN Rows;\r
95276127 323 UINT32 ModeNumber;\r
dca8c6d8 324 EFI_HII_SIMPLE_FONT_PACKAGE_HDR *SimplifiedFont;\r
878670ea 325 UINT32 PackageLength;\r
dca8c6d8 326 EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
327 UINT8 *Package;\r
328 UINT8 *Location;\r
878670ea 329 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;\r
95276127 330 ModeNumber = 0;\r
331\r
332 //\r
333 // Initialize the Graphics Console device instance\r
334 //\r
335 Private = AllocateCopyPool (\r
336 sizeof (GRAPHICS_CONSOLE_DEV),\r
337 &mGraphicsConsoleDevTemplate\r
338 );\r
339 if (Private == NULL) {\r
340 return EFI_OUT_OF_RESOURCES;\r
341 }\r
342\r
343 Private->SimpleTextOutput.Mode = &(Private->SimpleTextOutputMode);\r
344\r
345 Status = gBS->OpenProtocol (\r
346 Controller,\r
347 &gEfiGraphicsOutputProtocolGuid,\r
348 (VOID **) &Private->GraphicsOutput,\r
349 This->DriverBindingHandle,\r
350 Controller,\r
351 EFI_OPEN_PROTOCOL_BY_DRIVER\r
352 );\r
95276127 353\r
8541adab 354 if (EFI_ERROR(Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 355 Status = gBS->OpenProtocol (\r
356 Controller,\r
357 &gEfiUgaDrawProtocolGuid,\r
358 (VOID **) &Private->UgaDraw,\r
359 This->DriverBindingHandle,\r
360 Controller,\r
361 EFI_OPEN_PROTOCOL_BY_DRIVER\r
362 );\r
8541adab 363 }\r
364\r
365 if (EFI_ERROR (Status)) {\r
366 goto Error;\r
95276127 367 }\r
368\r
95276127 369 NarrowFontSize = ReturnNarrowFontSize ();\r
370\r
93e3992d 371 if (mFirstAccessFlag) {\r
dca8c6d8 372 //\r
373 // Add 4 bytes to the header for entire length for HiiLibPreparePackageList use only.\r
374 // Looks ugly. Might be updated when font tool is ready.\r
375 //\r
878670ea 376 // +--------------------------------+ <-- Package\r
377 // | |\r
378 // | PackageLength(4 bytes) | \r
379 // | |\r
380 // |--------------------------------| <-- SimplifiedFont\r
381 // | |\r
382 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR | \r
383 // | |\r
384 // |--------------------------------| <-- Location\r
385 // | |\r
386 // | gUsStdNarrowGlyphData |\r
387 // | |\r
388 // +--------------------------------+\r
389 \r
dca8c6d8 390 PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + NarrowFontSize + 4;\r
391 Package = AllocateZeroPool (PackageLength);\r
392 if (Package == NULL) {\r
393 return EFI_OUT_OF_RESOURCES;\r
394 }\r
878670ea 395 WriteUnaligned32((UINT32 *) Package,PackageLength);\r
396 SimplifiedFont = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR *) (Package + 4);\r
dca8c6d8 397 SimplifiedFont->Header.Length = (UINT32) (PackageLength - 4);\r
398 SimplifiedFont->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;\r
399 SimplifiedFont->NumberOfNarrowGlyphs = (UINT16) (NarrowFontSize / sizeof (EFI_NARROW_GLYPH));\r
8541adab 400\r
dca8c6d8 401 Location = (UINT8 *) (&SimplifiedFont->NumberOfWideGlyphs + 1);\r
8595bdaf 402 CopyMem (Location, gUsStdNarrowGlyphData, NarrowFontSize);\r
8541adab 403\r
dca8c6d8 404 //\r
405 // Add this simplified font package to a package list then install it.\r
406 //\r
407 PackageList = HiiLibPreparePackageList (1, &mFontPackageListGuid, Package);\r
408 Status = mHiiDatabase->NewPackageList (mHiiDatabase, PackageList, NULL, &(Private->HiiHandle));\r
409 ASSERT_EFI_ERROR (Status);\r
676df92c 410 FreePool (PackageList);\r
411 FreePool (Package);\r
dca8c6d8 412\r
93e3992d 413 mFirstAccessFlag = FALSE;\r
414 }\r
95276127 415 //\r
878670ea 416 // If the current mode information can not be retrieved, then attempt to set the default mode\r
417 // of 800x600, 32 bit color, 60 Hz refresh.\r
95276127 418 //\r
419 HorizontalResolution = 800;\r
420 VerticalResolution = 600;\r
421\r
422 if (Private->GraphicsOutput != NULL) {\r
423 //\r
8541adab 424 // The console is build on top of Graphics Output Protocol, find the mode number\r
3012ce5c 425 // for the user-defined mode; if there are multiple video devices,\r
426 // graphic console driver will set all the video devices to the same mode.\r
95276127 427 //\r
3012ce5c 428 Status = CheckModeSupported (\r
8541adab 429 Private->GraphicsOutput,\r
430 CURRENT_HORIZONTAL_RESOLUTION,\r
3012ce5c 431 CURRENT_VERTICAL_RESOLUTION,\r
432 &ModeNumber\r
433 );\r
434 if (!EFI_ERROR(Status)) {\r
435 //\r
436 // Update default mode to current mode\r
437 //\r
438 HorizontalResolution = CURRENT_HORIZONTAL_RESOLUTION;\r
439 VerticalResolution = CURRENT_VERTICAL_RESOLUTION;\r
440 } else {\r
441 //\r
442 // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec\r
443 //\r
444 Status = CheckModeSupported (\r
8541adab 445 Private->GraphicsOutput,\r
446 800,\r
447 600,\r
3012ce5c 448 &ModeNumber\r
449 );\r
95276127 450 }\r
878670ea 451 \r
452 Mode = Private->GraphicsOutput->Mode;\r
453 \r
454 if (EFI_ERROR (Status) || (Mode->MaxMode)) {\r
95276127 455 //\r
456 // Set default mode failed or device don't support default mode, then get the current mode information\r
457 //\r
878670ea 458 HorizontalResolution = Mode->Info->HorizontalResolution;\r
459 VerticalResolution = Mode->Info->VerticalResolution;\r
460 ModeNumber = Mode->Mode;\r
95276127 461 }\r
8541adab 462 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 463 //\r
3012ce5c 464 // At first try to set user-defined resolution\r
95276127 465 //\r
466 ColorDepth = 32;\r
467 RefreshRate = 60;\r
468 Status = Private->UgaDraw->SetMode (\r
469 Private->UgaDraw,\r
3012ce5c 470 CURRENT_HORIZONTAL_RESOLUTION,\r
471 CURRENT_VERTICAL_RESOLUTION,\r
95276127 472 ColorDepth,\r
473 RefreshRate\r
474 );\r
3012ce5c 475 if (!EFI_ERROR (Status)) {\r
476 HorizontalResolution = CURRENT_HORIZONTAL_RESOLUTION;\r
477 VerticalResolution = CURRENT_VERTICAL_RESOLUTION;\r
8541adab 478 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 479 //\r
3012ce5c 480 // Try to set 800*600 which is required by UEFI/EFI spec\r
95276127 481 //\r
3012ce5c 482 Status = Private->UgaDraw->SetMode (\r
95276127 483 Private->UgaDraw,\r
3012ce5c 484 HorizontalResolution,\r
485 VerticalResolution,\r
486 ColorDepth,\r
487 RefreshRate\r
95276127 488 );\r
489 if (EFI_ERROR (Status)) {\r
3012ce5c 490 Status = Private->UgaDraw->GetMode (\r
491 Private->UgaDraw,\r
492 &HorizontalResolution,\r
493 &VerticalResolution,\r
494 &ColorDepth,\r
495 &RefreshRate\r
496 );\r
497 if (EFI_ERROR (Status)) {\r
498 goto Error;\r
499 }\r
95276127 500 }\r
695f7e98 501 } else {\r
502 Status = EFI_UNSUPPORTED;\r
503 goto Error;\r
95276127 504 }\r
505 }\r
506\r
507 //\r
508 // Compute the maximum number of text Rows and Columns that this current graphics mode can support\r
509 //\r
0898c57c 510 Columns = HorizontalResolution / EFI_GLYPH_WIDTH;\r
511 Rows = VerticalResolution / EFI_GLYPH_HEIGHT;\r
95276127 512\r
513 //\r
514 // See if the mode is too small to support the required 80x25 text mode\r
515 //\r
516 if (Columns < 80 || Rows < 25) {\r
517 goto Error;\r
518 }\r
519 //\r
520 // Add Mode #0 that must be 80x25\r
521 //\r
522 MaxMode = 0;\r
8595bdaf 523 Private->ModeData[MaxMode].GopWidth = HorizontalResolution;\r
524 Private->ModeData[MaxMode].GopHeight = VerticalResolution;\r
95276127 525 Private->ModeData[MaxMode].GopModeNumber = ModeNumber;\r
8595bdaf 526 Private->ModeData[MaxMode].DeltaX = (HorizontalResolution - (80 * EFI_GLYPH_WIDTH)) >> 1;\r
527 Private->ModeData[MaxMode].DeltaY = (VerticalResolution - (25 * EFI_GLYPH_HEIGHT)) >> 1;\r
95276127 528 MaxMode++;\r
529\r
530 //\r
531 // If it is possible to support Mode #1 - 80x50, than add it as an active mode\r
532 //\r
533 if (Rows >= 50) {\r
8595bdaf 534 Private->ModeData[MaxMode].GopWidth = HorizontalResolution;\r
535 Private->ModeData[MaxMode].GopHeight = VerticalResolution;\r
95276127 536 Private->ModeData[MaxMode].GopModeNumber = ModeNumber;\r
8595bdaf 537 Private->ModeData[MaxMode].DeltaX = (HorizontalResolution - (80 * EFI_GLYPH_WIDTH)) >> 1;\r
538 Private->ModeData[MaxMode].DeltaY = (VerticalResolution - (50 * EFI_GLYPH_HEIGHT)) >> 1;\r
95276127 539 MaxMode++;\r
540 }\r
3012ce5c 541\r
95276127 542 //\r
3012ce5c 543 // If it is not to support Mode #1 - 80x50, then skip it\r
95276127 544 //\r
3012ce5c 545 if (MaxMode < 2) {\r
8595bdaf 546 Private->ModeData[MaxMode].Columns = 0;\r
547 Private->ModeData[MaxMode].Rows = 0;\r
548 Private->ModeData[MaxMode].GopWidth = HorizontalResolution;\r
549 Private->ModeData[MaxMode].GopHeight = VerticalResolution;\r
3012ce5c 550 Private->ModeData[MaxMode].GopModeNumber = ModeNumber;\r
8595bdaf 551 Private->ModeData[MaxMode].DeltaX = 0;\r
552 Private->ModeData[MaxMode].DeltaY = 0;\r
3012ce5c 553 MaxMode++;\r
554 }\r
8541adab 555\r
3012ce5c 556 //\r
557 // Add Mode #2 that must be 100x31 (graphic mode >= 800x600)\r
558 //\r
8541adab 559 if (Columns >= 100 && Rows >= 31) {\r
8595bdaf 560 Private->ModeData[MaxMode].GopWidth = HorizontalResolution;\r
561 Private->ModeData[MaxMode].GopHeight = VerticalResolution;\r
3012ce5c 562 Private->ModeData[MaxMode].GopModeNumber = ModeNumber;\r
8595bdaf 563 Private->ModeData[MaxMode].DeltaX = (HorizontalResolution - (100 * EFI_GLYPH_WIDTH)) >> 1;\r
564 Private->ModeData[MaxMode].DeltaY = (VerticalResolution - (31 * EFI_GLYPH_HEIGHT)) >> 1;\r
3012ce5c 565 MaxMode++;\r
566 }\r
95276127 567\r
3012ce5c 568 //\r
569 // Add Mode #3 that uses the entire display for user-defined mode\r
570 //\r
571 if (HorizontalResolution > 800 && VerticalResolution > 600) {\r
8595bdaf 572 Private->ModeData[MaxMode].Columns = HorizontalResolution/EFI_GLYPH_WIDTH;\r
573 Private->ModeData[MaxMode].Rows = VerticalResolution/EFI_GLYPH_HEIGHT;\r
574 Private->ModeData[MaxMode].GopWidth = HorizontalResolution;\r
575 Private->ModeData[MaxMode].GopHeight = VerticalResolution;\r
95276127 576 Private->ModeData[MaxMode].GopModeNumber = ModeNumber;\r
8595bdaf 577 Private->ModeData[MaxMode].DeltaX = (HorizontalResolution % EFI_GLYPH_WIDTH) >> 1;\r
578 Private->ModeData[MaxMode].DeltaY = (VerticalResolution % EFI_GLYPH_HEIGHT) >> 1;\r
95276127 579 MaxMode++;\r
580 }\r
8541adab 581\r
95276127 582 //\r
583 // Update the maximum number of modes\r
584 //\r
585 Private->SimpleTextOutputMode.MaxMode = (INT32) MaxMode;\r
586\r
587 //\r
588 // Determine the number of text modes that this protocol can support\r
589 //\r
590 Status = GraphicsConsoleConOutSetMode (&Private->SimpleTextOutput, 0);\r
591 if (EFI_ERROR (Status)) {\r
592 goto Error;\r
593 }\r
594\r
595 DEBUG_CODE_BEGIN ();\r
596 GraphicsConsoleConOutOutputString (&Private->SimpleTextOutput, (CHAR16 *)L"Graphics Console Started\n\r");\r
597 DEBUG_CODE_END ();\r
598\r
599 //\r
600 // Install protocol interfaces for the Graphics Console device.\r
601 //\r
602 Status = gBS->InstallMultipleProtocolInterfaces (\r
603 &Controller,\r
604 &gEfiSimpleTextOutProtocolGuid,\r
605 &Private->SimpleTextOutput,\r
606 NULL\r
607 );\r
608\r
609Error:\r
610 if (EFI_ERROR (Status)) {\r
611 //\r
8595bdaf 612 // Close the GOP and UGA Draw Protocol\r
95276127 613 //\r
614 if (Private->GraphicsOutput != NULL) {\r
615 gBS->CloseProtocol (\r
616 Controller,\r
617 &gEfiGraphicsOutputProtocolGuid,\r
618 This->DriverBindingHandle,\r
619 Controller\r
620 );\r
8541adab 621 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 622 gBS->CloseProtocol (\r
623 Controller,\r
624 &gEfiUgaDrawProtocolGuid,\r
625 This->DriverBindingHandle,\r
626 Controller\r
627 );\r
628 }\r
629\r
630 //\r
631 // Free private data\r
632 //\r
633 if (Private != NULL) {\r
634 if (Private->LineBuffer != NULL) {\r
635 FreePool (Private->LineBuffer);\r
636 }\r
637 FreePool (Private);\r
638 }\r
639 }\r
640\r
641 return Status;\r
642}\r
643\r
24248368 644/**\r
8595bdaf 645 Stop this driver on Controller by removing Simple Text Out protocol \r
646 and closing the Graphics Output Protocol or UGA Draw protocol on Controller.\r
878670ea 647 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)\r
24248368 648 \r
649\r
650 @param This Protocol instance pointer.\r
8595bdaf 651 @param Controller Handle of device to stop driver on\r
24248368 652 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
653 children is zero stop the entire bus driver.\r
654 @param ChildHandleBuffer List of Child Handles to Stop.\r
655\r
8595bdaf 656 @retval EFI_SUCCESS This driver is removed Controller.\r
24248368 657 @retval EFI_NOT_STARTED Simple Text Out protocol could not be found the \r
8595bdaf 658 Controller.\r
24248368 659 @retval other This driver was not removed from this device.\r
660\r
661**/\r
95276127 662EFI_STATUS\r
663EFIAPI\r
664GraphicsConsoleControllerDriverStop (\r
665 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
666 IN EFI_HANDLE Controller,\r
667 IN UINTN NumberOfChildren,\r
668 IN EFI_HANDLE *ChildHandleBuffer\r
669 )\r
670{\r
671 EFI_STATUS Status;\r
672 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOutput;\r
673 GRAPHICS_CONSOLE_DEV *Private;\r
674\r
675 Status = gBS->OpenProtocol (\r
676 Controller,\r
677 &gEfiSimpleTextOutProtocolGuid,\r
678 (VOID **) &SimpleTextOutput,\r
679 This->DriverBindingHandle,\r
680 Controller,\r
681 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
682 );\r
683 if (EFI_ERROR (Status)) {\r
684 return EFI_NOT_STARTED;\r
685 }\r
686\r
687 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);\r
688\r
689 Status = gBS->UninstallProtocolInterface (\r
690 Controller,\r
691 &gEfiSimpleTextOutProtocolGuid,\r
692 &Private->SimpleTextOutput\r
693 );\r
694\r
695 if (!EFI_ERROR (Status)) {\r
696 //\r
697 // Close the GOP or UGA IO Protocol\r
698 //\r
699 if (Private->GraphicsOutput != NULL) {\r
700 gBS->CloseProtocol (\r
701 Controller,\r
702 &gEfiGraphicsOutputProtocolGuid,\r
703 This->DriverBindingHandle,\r
704 Controller\r
705 );\r
8541adab 706 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 707 gBS->CloseProtocol (\r
708 Controller,\r
709 &gEfiUgaDrawProtocolGuid,\r
710 This->DriverBindingHandle,\r
711 Controller\r
712 );\r
713 }\r
714\r
715 //\r
716 // Remove the font pack\r
717 //\r
38c0d70a 718 if (Private->HiiHandle != NULL) {\r
719 HiiLibRemovePackages (Private->HiiHandle);\r
720 mFirstAccessFlag = TRUE;\r
721 }\r
95276127 722\r
723 //\r
724 // Free our instance data\r
725 //\r
726 if (Private != NULL) {\r
727 FreePool (Private->LineBuffer);\r
728 FreePool (Private);\r
729 }\r
730 }\r
731\r
732 return Status;\r
733}\r
734\r
24248368 735/**\r
736 Check if the current specific mode supported the user defined resolution\r
878670ea 737 for the Graphics Console device based on Graphics Output Protocol.\r
24248368 738\r
739 If yes, set the graphic devcice's current mode to this specific mode.\r
740 \r
741 @param GraphicsOutput Graphics Output Protocol instance pointer.\r
742 @param HorizontalResolution User defined horizontal resolution\r
743 @param VerticalResolution User defined vertical resolution.\r
744 @param CurrentModeNumber Current specific mode to be check.\r
745\r
8595bdaf 746 @retval EFI_SUCCESS The mode is supported.\r
24248368 747 @retval EFI_UNSUPPORTED The specific mode is out of range of graphics \r
878670ea 748 device supported.\r
24248368 749 @retval other The specific mode does not support user defined \r
750 resolution or failed to set the current mode to the \r
751 specific mode on graphics device.\r
752\r
753**/\r
3012ce5c 754EFI_STATUS\r
755CheckModeSupported (\r
756 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
24248368 757 IN UINT32 HorizontalResolution,\r
758 IN UINT32 VerticalResolution,\r
759 OUT UINT32 *CurrentModeNumber\r
3012ce5c 760 )\r
761{\r
762 UINT32 ModeNumber;\r
763 EFI_STATUS Status;\r
8541adab 764 UINTN SizeOfInfo;\r
3012ce5c 765 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
0322ed7a 766 UINT32 MaxMode;\r
8541adab 767\r
0322ed7a 768 Status = EFI_SUCCESS;\r
769 MaxMode = GraphicsOutput->Mode->MaxMode;\r
770 \r
771 for (ModeNumber = 0; ModeNumber < MaxMode; ModeNumber++) {\r
3012ce5c 772 Status = GraphicsOutput->QueryMode (\r
773 GraphicsOutput,\r
774 ModeNumber,\r
775 &SizeOfInfo,\r
776 &Info\r
777 );\r
778 if (!EFI_ERROR (Status)) {\r
779 if ((Info->HorizontalResolution == HorizontalResolution) &&\r
780 (Info->VerticalResolution == VerticalResolution)) {\r
781 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);\r
782 if (!EFI_ERROR (Status)) {\r
0322ed7a 783 FreePool (Info);\r
3012ce5c 784 break;\r
785 }\r
786 }\r
0322ed7a 787 FreePool (Info);\r
3012ce5c 788 }\r
789 }\r
8541adab 790\r
3012ce5c 791 if (ModeNumber == GraphicsOutput->Mode->MaxMode) {\r
792 Status = EFI_UNSUPPORTED;\r
793 }\r
8541adab 794\r
3012ce5c 795 *CurrentModeNumber = ModeNumber;\r
8541adab 796 return Status;\r
3012ce5c 797}\r
798\r
95276127 799\r
6dcf9abc 800/**\r
24248368 801 Locate HII Database protocol and HII Font protocol.\r
95276127 802\r
24248368 803 @retval EFI_SUCCESS HII Database protocol and HII Font protocol \r
804 are located successfully.\r
805 @return other Failed to locate HII Database protocol or \r
806 HII Font protocol.\r
95276127 807\r
6dcf9abc 808**/\r
809EFI_STATUS\r
810EfiLocateHiiProtocol (\r
811 VOID\r
812 )\r
95276127 813{\r
814 EFI_HANDLE Handle;\r
815 UINTN Size;\r
816 EFI_STATUS Status;\r
817\r
93e3992d 818 //\r
819 // There should only be one - so buffer size is this\r
820 //\r
821 Size = sizeof (EFI_HANDLE);\r
822\r
823 Status = gBS->LocateHandle (\r
824 ByProtocol,\r
825 &gEfiHiiDatabaseProtocolGuid,\r
826 NULL,\r
827 &Size,\r
828 (VOID **) &Handle\r
829 );\r
830\r
831 if (EFI_ERROR (Status)) {\r
832 return Status;\r
833 }\r
834\r
835 Status = gBS->HandleProtocol (\r
836 Handle,\r
837 &gEfiHiiDatabaseProtocolGuid,\r
838 (VOID **) &mHiiDatabase\r
839 );\r
840\r
841 if (EFI_ERROR (Status)) {\r
842 return Status;\r
843 }\r
844\r
845 Status = gBS->HandleProtocol (\r
846 Handle,\r
847 &gEfiHiiFontProtocolGuid,\r
848 (VOID **) &mHiiFont\r
849 );\r
850 return Status;\r
95276127 851}\r
93e3992d 852\r
95276127 853//\r
854// Body of the STO functions\r
855//\r
6dcf9abc 856\r
857/**\r
878670ea 858 Reset the text output device hardware and optionally run diagnostics.\r
24248368 859 \r
6dcf9abc 860 Implements SIMPLE_TEXT_OUTPUT.Reset().\r
861 If ExtendeVerification is TRUE, then perform dependent Graphics Console\r
862 device reset, and set display mode to mode 0.\r
863 If ExtendedVerification is FALSE, only set display mode to mode 0.\r
864\r
24248368 865 @param This Protocol instance pointer.\r
6dcf9abc 866 @param ExtendedVerification Indicates that the driver may perform a more\r
867 exhaustive verification operation of the device\r
868 during reset.\r
869\r
24248368 870 @retval EFI_SUCCESS The text output device was reset.\r
871 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and\r
872 could not be reset.\r
6dcf9abc 873\r
874**/\r
95276127 875EFI_STATUS\r
876EFIAPI\r
877GraphicsConsoleConOutReset (\r
878 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
879 IN BOOLEAN ExtendedVerification\r
880 )\r
95276127 881{\r
882 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
883 return This->SetMode (This, 0);\r
884}\r
885\r
6dcf9abc 886\r
887/**\r
24248368 888 Write a Unicode string to the output device.\r
889\r
890 Implements SIMPLE_TEXT_OUTPUT.OutputString(). \r
6dcf9abc 891 The Unicode string will be converted to Glyphs and will be\r
892 sent to the Graphics Console.\r
893\r
24248368 894 @param This Protocol instance pointer.\r
895 @param WString The NULL-terminated Unicode string to be displayed\r
896 on the output device(s). All output devices must\r
897 also support the Unicode drawing defined in this file.\r
6dcf9abc 898\r
24248368 899 @retval EFI_SUCCESS The string was output to the device.\r
900 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output\r
901 the text.\r
902 @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
903 defined text mode.\r
904 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
905 characters in the Unicode string could not be\r
906 rendered and were skipped.\r
6dcf9abc 907\r
908**/\r
95276127 909EFI_STATUS\r
910EFIAPI\r
911GraphicsConsoleConOutOutputString (\r
912 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
913 IN CHAR16 *WString\r
914 )\r
95276127 915{\r
916 GRAPHICS_CONSOLE_DEV *Private;\r
917 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
918 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
919 INTN Mode;\r
920 UINTN MaxColumn;\r
921 UINTN MaxRow;\r
922 UINTN Width;\r
923 UINTN Height;\r
924 UINTN Delta;\r
925 EFI_STATUS Status;\r
926 BOOLEAN Warning;\r
927 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
928 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
929 UINTN DeltaX;\r
930 UINTN DeltaY;\r
931 UINTN Count;\r
932 UINTN Index;\r
933 INT32 OriginAttribute;\r
934 EFI_TPL OldTpl;\r
95276127 935\r
936 Status = EFI_SUCCESS;\r
937\r
938 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
939 //\r
940 // Current mode\r
941 //\r
942 Mode = This->Mode->Mode;\r
943 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
944 GraphicsOutput = Private->GraphicsOutput;\r
945 UgaDraw = Private->UgaDraw;\r
946\r
947 MaxColumn = Private->ModeData[Mode].Columns;\r
948 MaxRow = Private->ModeData[Mode].Rows;\r
949 DeltaX = Private->ModeData[Mode].DeltaX;\r
950 DeltaY = Private->ModeData[Mode].DeltaY;\r
0898c57c 951 Width = MaxColumn * EFI_GLYPH_WIDTH;\r
952 Height = (MaxRow - 1) * EFI_GLYPH_HEIGHT;\r
95276127 953 Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
954\r
955 //\r
956 // The Attributes won't change when during the time OutputString is called\r
957 //\r
958 GetTextColors (This, &Foreground, &Background);\r
959\r
960 EraseCursor (This);\r
961\r
962 Warning = FALSE;\r
963\r
964 //\r
965 // Backup attribute\r
966 //\r
967 OriginAttribute = This->Mode->Attribute;\r
968\r
6dcf9abc 969 while (*WString != L'\0') {\r
95276127 970\r
971 if (*WString == CHAR_BACKSPACE) {\r
972 //\r
973 // If the cursor is at the left edge of the display, then move the cursor\r
974 // one row up.\r
975 //\r
976 if (This->Mode->CursorColumn == 0 && This->Mode->CursorRow > 0) {\r
977 This->Mode->CursorRow--;\r
978 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);\r
979 This->OutputString (This, SpaceStr);\r
980 EraseCursor (This);\r
981 This->Mode->CursorRow--;\r
982 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);\r
983 } else if (This->Mode->CursorColumn > 0) {\r
984 //\r
985 // If the cursor is not at the left edge of the display, then move the cursor\r
986 // left one column.\r
987 //\r
988 This->Mode->CursorColumn--;\r
989 This->OutputString (This, SpaceStr);\r
990 EraseCursor (This);\r
991 This->Mode->CursorColumn--;\r
992 }\r
993\r
994 WString++;\r
995\r
996 } else if (*WString == CHAR_LINEFEED) {\r
997 //\r
998 // If the cursor is at the bottom of the display, then scroll the display one\r
999 // row, and do not update the cursor position. Otherwise, move the cursor\r
1000 // down one row.\r
1001 //\r
1002 if (This->Mode->CursorRow == (INT32) (MaxRow - 1)) {\r
1003 if (GraphicsOutput != NULL) {\r
1004 //\r
1005 // Scroll Screen Up One Row\r
1006 //\r
1007 GraphicsOutput->Blt (\r
1008 GraphicsOutput,\r
1009 NULL,\r
1010 EfiBltVideoToVideo,\r
1011 DeltaX,\r
0898c57c 1012 DeltaY + EFI_GLYPH_HEIGHT,\r
95276127 1013 DeltaX,\r
1014 DeltaY,\r
1015 Width,\r
1016 Height,\r
1017 Delta\r
1018 );\r
1019\r
1020 //\r
1021 // Print Blank Line at last line\r
1022 //\r
1023 GraphicsOutput->Blt (\r
1024 GraphicsOutput,\r
1025 &Background,\r
1026 EfiBltVideoFill,\r
1027 0,\r
1028 0,\r
1029 DeltaX,\r
1030 DeltaY + Height,\r
1031 Width,\r
0898c57c 1032 EFI_GLYPH_HEIGHT,\r
95276127 1033 Delta\r
1034 );\r
8541adab 1035 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1036 //\r
1037 // Scroll Screen Up One Row\r
1038 //\r
1039 UgaDraw->Blt (\r
1040 UgaDraw,\r
1041 NULL,\r
1042 EfiUgaVideoToVideo,\r
1043 DeltaX,\r
0898c57c 1044 DeltaY + EFI_GLYPH_HEIGHT,\r
95276127 1045 DeltaX,\r
1046 DeltaY,\r
1047 Width,\r
1048 Height,\r
1049 Delta\r
1050 );\r
1051\r
1052 //\r
1053 // Print Blank Line at last line\r
1054 //\r
1055 UgaDraw->Blt (\r
1056 UgaDraw,\r
1057 (EFI_UGA_PIXEL *) (UINTN) &Background,\r
1058 EfiUgaVideoFill,\r
1059 0,\r
1060 0,\r
1061 DeltaX,\r
1062 DeltaY + Height,\r
1063 Width,\r
0898c57c 1064 EFI_GLYPH_HEIGHT,\r
95276127 1065 Delta\r
1066 );\r
1067 }\r
1068 } else {\r
1069 This->Mode->CursorRow++;\r
1070 }\r
1071\r
1072 WString++;\r
1073\r
1074 } else if (*WString == CHAR_CARRIAGE_RETURN) {\r
1075 //\r
1076 // Move the cursor to the beginning of the current row.\r
1077 //\r
1078 This->Mode->CursorColumn = 0;\r
1079 WString++;\r
1080\r
1081 } else if (*WString == WIDE_CHAR) {\r
1082\r
1083 This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;\r
1084 WString++;\r
1085\r
1086 } else if (*WString == NARROW_CHAR) {\r
1087\r
1088 This->Mode->Attribute &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);\r
1089 WString++;\r
1090\r
1091 } else {\r
1092 //\r
1093 // Print the character at the current cursor position and move the cursor\r
1094 // right one column. If this moves the cursor past the right edge of the\r
1095 // display, then the line should wrap to the beginning of the next line. This\r
1096 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the\r
1097 // bottom of the display, and the line wraps, then the display will be scrolled\r
1098 // one line.\r
1099 // If wide char is going to be displayed, need to display one character at a time\r
1100 // Or, need to know the display length of a certain string.\r
1101 //\r
1102 // Index is used to determine how many character width units (wide = 2, narrow = 1)\r
1103 // Count is used to determine how many characters are used regardless of their attributes\r
1104 //\r
1105 for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {\r
878670ea 1106 if (WString[Count] == CHAR_NULL || \r
1107 WString[Count] == CHAR_BACKSPACE || \r
1108 WString[Count] == CHAR_LINEFEED ||\r
1109 WString[Count] == CHAR_CARRIAGE_RETURN ||\r
1110 WString[Count] == WIDE_CHAR ||\r
1111 WString[Count] == NARROW_CHAR) {\r
95276127 1112 break;\r
1113 }\r
1114 //\r
1115 // Is the wide attribute on?\r
1116 //\r
1117 if (This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) {\r
1118 //\r
1119 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop\r
1120 //\r
1121 Index++;\r
1122 //\r
1123 // This is the end-case where if we are at column 79 and about to print a wide character\r
1124 // We should prevent this from happening because we will wrap inappropriately. We should\r
1125 // not print this character until the next line.\r
1126 //\r
1127 if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {\r
1128 Index++;\r
1129 break;\r
1130 }\r
1131 }\r
1132 }\r
1133\r
1134 Status = DrawUnicodeWeightAtCursorN (This, WString, Count);\r
1135 if (EFI_ERROR (Status)) {\r
1136 Warning = TRUE;\r
1137 }\r
1138 //\r
1139 // At the end of line, output carriage return and line feed\r
1140 //\r
1141 WString += Count;\r
1142 This->Mode->CursorColumn += (INT32) Index;\r
1143 if (This->Mode->CursorColumn > (INT32) MaxColumn) {\r
1144 This->Mode->CursorColumn -= 2;\r
1145 This->OutputString (This, SpaceStr);\r
1146 }\r
1147\r
1148 if (This->Mode->CursorColumn >= (INT32) MaxColumn) {\r
1149 EraseCursor (This);\r
1150 This->OutputString (This, mCrLfString);\r
1151 EraseCursor (This);\r
1152 }\r
1153 }\r
1154 }\r
1155\r
1156 This->Mode->Attribute = OriginAttribute;\r
1157\r
1158 EraseCursor (This);\r
1159\r
1160 if (Warning) {\r
1161 Status = EFI_WARN_UNKNOWN_GLYPH;\r
1162 }\r
1163\r
1164 gBS->RestoreTPL (OldTpl);\r
1165 return Status;\r
1166\r
1167}\r
1168\r
6dcf9abc 1169/**\r
24248368 1170 Verifies that all characters in a Unicode string can be output to the \r
1171 target device.\r
6dcf9abc 1172\r
24248368 1173 Implements SIMPLE_TEXT_OUTPUT.QueryMode().\r
1174 If one of the characters in the *Wstring is neither valid valid Unicode\r
1175 drawing characters, not ASCII code, then this function will return\r
1176 EFI_UNSUPPORTED\r
1177\r
1178 @param This Protocol instance pointer.\r
1179 @param WString The NULL-terminated Unicode string to be examined for the output\r
1180 device(s).\r
6dcf9abc 1181\r
24248368 1182 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.\r
1183 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be\r
1184 rendered by one or more of the output devices mapped\r
1185 by the EFI handle.\r
6dcf9abc 1186\r
1187**/\r
95276127 1188EFI_STATUS\r
1189EFIAPI\r
1190GraphicsConsoleConOutTestString (\r
1191 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1192 IN CHAR16 *WString\r
1193 )\r
95276127 1194{\r
1195 EFI_STATUS Status;\r
95276127 1196 UINT16 Count;\r
95276127 1197\r
6dcf9abc 1198 EFI_IMAGE_OUTPUT *Blt;\r
93e3992d 1199\r
6dcf9abc 1200 Blt = NULL;\r
93e3992d 1201 Count = 0;\r
1202\r
1203 while (WString[Count] != 0) {\r
93e3992d 1204 Status = mHiiFont->GetGlyph (\r
1205 mHiiFont,\r
1206 WString[Count],\r
1207 NULL,\r
1208 &Blt,\r
1209 NULL\r
1210 );\r
676df92c 1211 if (Blt != NULL) {\r
1212 FreePool (Blt);\r
1213 Blt = NULL;\r
1214 }\r
93e3992d 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
878670ea 1384 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode\r
95276127 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
878670ea 1423 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode\r
95276127 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
878670ea 1463 // Move the text cursor to the upper left hand corner of the display and enable it\r
95276127 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
8595bdaf 1643 if ((This->Mode->CursorColumn == (INT32) Column) && (This->Mode->CursorRow == (INT32) Row)) {\r
95276127 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
878670ea 1723 Draw Unicode string on the Graphics Console device's screen.\r
24248368 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
676df92c 1762 FreePool (Blt);\r
93e3992d 1763 return EFI_OUT_OF_RESOURCES;\r
1764 }\r
8595bdaf 1765 //\r
1766 // Set the end character\r
1767 //\r
1768 *(String + Count) = L'\0';\r
93e3992d 1769\r
1770 FontInfo = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));\r
1771 if (FontInfo == NULL) {\r
676df92c 1772 FreePool (Blt);\r
1773 FreePool (String);\r
93e3992d 1774 return EFI_OUT_OF_RESOURCES;\r
1775 }\r
8595bdaf 1776 //\r
1777 // Get current foreground and background colors.\r
1778 //\r
93e3992d 1779 GetTextColors (This, &FontInfo->ForegroundColor, &FontInfo->BackgroundColor);\r
1780\r
d42d853e 1781 if (Private->GraphicsOutput != NULL) {\r
8595bdaf 1782 //\r
878670ea 1783 // If Graphics Output protocol exists, using HII Font protocol to draw. \r
8595bdaf 1784 //\r
d42d853e 1785 Blt->Image.Screen = Private->GraphicsOutput;\r
95276127 1786\r
d42d853e 1787 Status = mHiiFont->StringToImage (\r
1788 mHiiFont,\r
1789 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN,\r
1790 String,\r
1791 FontInfo,\r
1792 &Blt,\r
0898c57c 1793 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1794 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
d42d853e 1795 NULL,\r
1796 NULL,\r
1797 NULL\r
1798 );\r
95276127 1799\r
8541adab 1800 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
8595bdaf 1801 //\r
1802 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled, \r
1803 // using UGA Draw protocol to draw.\r
1804 //\r
d42d853e 1805 ASSERT (Private->UgaDraw!= NULL);\r
95276127 1806\r
d42d853e 1807 UgaDraw = Private->UgaDraw;\r
95276127 1808\r
d42d853e 1809 Blt->Image.Bitmap = AllocateZeroPool (Blt->Width * Blt->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
1810 if (Blt->Image.Bitmap == NULL) {\r
676df92c 1811 FreePool (Blt);\r
1812 FreePool (String);\r
d42d853e 1813 return EFI_OUT_OF_RESOURCES;\r
95276127 1814 }\r
1815\r
d42d853e 1816 RowInfoArray = NULL;\r
1817 //\r
1818 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,\r
1819 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.\r
1820 //\r
1821 Status = mHiiFont->StringToImage (\r
1822 mHiiFont,\r
1823 EFI_HII_IGNORE_IF_NO_GLYPH,\r
1824 String,\r
1825 FontInfo,\r
1826 &Blt,\r
0898c57c 1827 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1828 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
d42d853e 1829 &RowInfoArray,\r
1830 &RowInfoArraySize,\r
1831 NULL\r
1832 );\r
95276127 1833\r
d42d853e 1834 if (!EFI_ERROR (Status)) {\r
95276127 1835 //\r
d42d853e 1836 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will\r
bd1d34ee 1837 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.\r
95276127 1838 //\r
bd1d34ee 1839 ASSERT (RowInfoArraySize <= 1);\r
8541adab 1840\r
d42d853e 1841 Status = UgaDraw->Blt (\r
1842 UgaDraw,\r
1843 (EFI_UGA_PIXEL *) Blt->Image.Bitmap,\r
1844 EfiUgaBltBufferToVideo,\r
0898c57c 1845 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1846 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
1847 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1848 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
d42d853e 1849 RowInfoArray[0].LineWidth,\r
1850 RowInfoArray[0].LineHeight,\r
1851 Blt->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1852 );\r
1853 }\r
95276127 1854\r
676df92c 1855 FreePool (RowInfoArray);\r
1856 FreePool (Blt->Image.Bitmap);\r
8541adab 1857 } else {\r
1858 Status = EFI_UNSUPPORTED;\r
95276127 1859 }\r
1860\r
676df92c 1861 if (Blt != NULL) {\r
1862 FreePool (Blt);\r
1863 }\r
1864 if (String != NULL) {\r
1865 FreePool (String);\r
1866 }\r
1867 if (FontInfo != NULL) {\r
1868 FreePool (FontInfo);\r
1869 }\r
d42d853e 1870 return Status;\r
95276127 1871}\r
d42d853e 1872\r
24248368 1873/**\r
1874 Erase the cursor on the screen.\r
95276127 1875\r
24248368 1876 @param This Protocol instance pointer.\r
1877\r
1878 @retval EFI_SUCCESS The cursor is erased successfully.\r
1879\r
1880**/\r
95276127 1881EFI_STATUS\r
1882EraseCursor (\r
1883 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
1884 )\r
1885{\r
7601dbe7 1886 GRAPHICS_CONSOLE_DEV *Private;\r
1887 EFI_SIMPLE_TEXT_OUTPUT_MODE *CurrentMode;\r
1888 INTN GlyphX;\r
1889 INTN GlyphY;\r
95276127 1890 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
7601dbe7 1891 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
95276127 1892 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground;\r
1893 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background;\r
0898c57c 1894 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar[EFI_GLYPH_HEIGHT][EFI_GLYPH_WIDTH];\r
7601dbe7 1895 UINTN PosX;\r
1896 UINTN PosY;\r
95276127 1897\r
1898 CurrentMode = This->Mode;\r
1899\r
1900 if (!CurrentMode->CursorVisible) {\r
1901 return EFI_SUCCESS;\r
1902 }\r
1903\r
1904 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1905 GraphicsOutput = Private->GraphicsOutput;\r
1906 UgaDraw = Private->UgaDraw;\r
1907\r
1908 //\r
24248368 1909 // In this driver, only narrow character was supported.\r
95276127 1910 //\r
1911 //\r
1912 // Blt a character to the screen\r
1913 //\r
0898c57c 1914 GlyphX = (CurrentMode->CursorColumn * EFI_GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;\r
1915 GlyphY = (CurrentMode->CursorRow * EFI_GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;\r
95276127 1916 if (GraphicsOutput != NULL) {\r
1917 GraphicsOutput->Blt (\r
1918 GraphicsOutput,\r
1919 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,\r
1920 EfiBltVideoToBltBuffer,\r
1921 GlyphX,\r
1922 GlyphY,\r
1923 0,\r
1924 0,\r
0898c57c 1925 EFI_GLYPH_WIDTH,\r
1926 EFI_GLYPH_HEIGHT,\r
1927 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
95276127 1928 );\r
8541adab 1929 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1930 UgaDraw->Blt (\r
1931 UgaDraw,\r
1932 (EFI_UGA_PIXEL *) (UINTN) BltChar,\r
1933 EfiUgaVideoToBltBuffer,\r
1934 GlyphX,\r
1935 GlyphY,\r
1936 0,\r
1937 0,\r
0898c57c 1938 EFI_GLYPH_WIDTH,\r
1939 EFI_GLYPH_HEIGHT,\r
1940 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
95276127 1941 );\r
1942 }\r
1943\r
1944 GetTextColors (This, &Foreground.Pixel, &Background.Pixel);\r
1945\r
1946 //\r
1947 // Convert Monochrome bitmap of the Glyph to BltBuffer structure\r
1948 //\r
6dcf9abc 1949 for (PosY = 0; PosY < EFI_GLYPH_HEIGHT; PosY++) {\r
1950 for (PosX = 0; PosX < EFI_GLYPH_WIDTH; PosX++) {\r
878670ea 1951 if ((mCursorGlyph.GlyphCol1[PosY] & (BIT0 << PosX)) != 0) {\r
6dcf9abc 1952 BltChar[PosY][EFI_GLYPH_WIDTH - PosX - 1].Raw ^= Foreground.Raw;\r
95276127 1953 }\r
1954 }\r
1955 }\r
1956\r
1957 if (GraphicsOutput != NULL) {\r
1958 GraphicsOutput->Blt (\r
1959 GraphicsOutput,\r
1960 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,\r
1961 EfiBltBufferToVideo,\r
1962 0,\r
1963 0,\r
1964 GlyphX,\r
1965 GlyphY,\r
0898c57c 1966 EFI_GLYPH_WIDTH,\r
1967 EFI_GLYPH_HEIGHT,\r
1968 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
95276127 1969 );\r
8541adab 1970 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1971 UgaDraw->Blt (\r
1972 UgaDraw,\r
1973 (EFI_UGA_PIXEL *) (UINTN) BltChar,\r
1974 EfiUgaBltBufferToVideo,\r
1975 0,\r
1976 0,\r
1977 GlyphX,\r
1978 GlyphY,\r
0898c57c 1979 EFI_GLYPH_WIDTH,\r
1980 EFI_GLYPH_HEIGHT,\r
1981 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
95276127 1982 );\r
1983 }\r
1984\r
1985 return EFI_SUCCESS;\r
1986}\r
97a079ed
A
1987\r
1988/**\r
1989 The user Entry Point for module GraphicsConsole. The user code starts with this function.\r
1990\r
8541adab 1991 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
97a079ed 1992 @param[in] SystemTable A pointer to the EFI System Table.\r
8541adab 1993\r
7601dbe7 1994 @retval EFI_SUCCESS The entry point is executed successfully.\r
1995 @return other Some error occurs when executing this entry point.\r
97a079ed
A
1996\r
1997**/\r
1998EFI_STATUS\r
1999EFIAPI\r
2000InitializeGraphicsConsole (\r
2001 IN EFI_HANDLE ImageHandle,\r
2002 IN EFI_SYSTEM_TABLE *SystemTable\r
2003 )\r
2004{\r
2005 EFI_STATUS Status;\r
2006\r
2007 //\r
2008 // Install driver model protocol(s).\r
2009 //\r
5bca971e 2010 Status = EfiLibInstallDriverBindingComponentName2 (\r
97a079ed
A
2011 ImageHandle,\r
2012 SystemTable,\r
2013 &gGraphicsConsoleDriverBinding,\r
2014 ImageHandle,\r
2015 &gGraphicsConsoleComponentName,\r
5bca971e 2016 &gGraphicsConsoleComponentName2\r
97a079ed
A
2017 );\r
2018 ASSERT_EFI_ERROR (Status);\r
2019\r
97a079ed
A
2020 return Status;\r
2021}\r
2022\r
d42d853e 2023\r