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