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