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