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