]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c
HII Library Class interface refine.
[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
28487361 4Copyright (c) 2006 - 2009 Intel Corporation. <BR>\r
8541adab 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
95276127 12\r
13**/\r
14\r
95276127 15#include "GraphicsConsole.h"\r
16\r
95276127 17//\r
878670ea 18// Graphics Console Device Private Data template\r
95276127 19//\r
fe1e36e5 20GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate = {\r
95276127 21 GRAPHICS_CONSOLE_DEV_SIGNATURE,\r
22 (EFI_GRAPHICS_OUTPUT_PROTOCOL *) NULL,\r
23 (EFI_UGA_DRAW_PROTOCOL *) NULL,\r
24 {\r
25 GraphicsConsoleConOutReset,\r
26 GraphicsConsoleConOutOutputString,\r
27 GraphicsConsoleConOutTestString,\r
28 GraphicsConsoleConOutQueryMode,\r
29 GraphicsConsoleConOutSetMode,\r
30 GraphicsConsoleConOutSetAttribute,\r
31 GraphicsConsoleConOutClearScreen,\r
32 GraphicsConsoleConOutSetCursorPosition,\r
33 GraphicsConsoleConOutEnableCursor,\r
34 (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL\r
35 },\r
36 {\r
37 0,\r
38 0,\r
39 EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_BLACK),\r
40 0,\r
41 0,\r
42 TRUE\r
43 },\r
44 {\r
45 { 80, 25, 0, 0, 0, 0 }, // Mode 0\r
3012ce5c 46 { 80, 50, 0, 0, 0, 0 }, // Mode 1\r
47 { 100,31, 0, 0, 0, 0 }, // Mode 2\r
48 { 0, 0, 0, 0, 0, 0 } // Mode 3\r
95276127 49 },\r
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
fe1e36e5 62EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {\r
95276127 63 //\r
878670ea 64 // B G R reserved\r
95276127 65 //\r
66 {0x00, 0x00, 0x00, 0x00}, // BLACK\r
878670ea 67 {0x98, 0x00, 0x00, 0x00}, // LIGHTBLUE\r
68 {0x00, 0x98, 0x00, 0x00}, // LIGHGREEN\r
69 {0x98, 0x98, 0x00, 0x00}, // LIGHCYAN\r
70 {0x00, 0x00, 0x98, 0x00}, // LIGHRED\r
95276127 71 {0x98, 0x00, 0x98, 0x00}, // MAGENTA\r
72 {0x00, 0x98, 0x98, 0x00}, // BROWN\r
73 {0x98, 0x98, 0x98, 0x00}, // LIGHTGRAY\r
74 {0x30, 0x30, 0x30, 0x00}, // DARKGRAY - BRIGHT BLACK\r
878670ea 75 {0xff, 0x00, 0x00, 0x00}, // BLUE\r
76 {0x00, 0xff, 0x00, 0x00}, // LIME\r
77 {0xff, 0xff, 0x00, 0x00}, // CYAN\r
78 {0x00, 0x00, 0xff, 0x00}, // RED\r
79 {0xff, 0x00, 0xff, 0x00}, // FUCHSIA\r
80 {0x00, 0xff, 0xff, 0x00}, // YELLOW\r
81 {0xff, 0xff, 0xff, 0x00} // WHITE\r
95276127 82};\r
83\r
fe1e36e5 84EFI_NARROW_GLYPH mCursorGlyph = {\r
95276127 85 0x0000,\r
86 0x00,\r
87 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }\r
88};\r
89\r
fe1e36e5 90CHAR16 SpaceStr[] = { NARROW_CHAR, ' ', 0 };\r
6dcf9abc 91\r
95276127 92EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding = {\r
93 GraphicsConsoleControllerDriverSupported,\r
94 GraphicsConsoleControllerDriverStart,\r
95 GraphicsConsoleControllerDriverStop,\r
96 0xa,\r
97 NULL,\r
98 NULL\r
99};\r
100\r
24248368 101/**\r
8595bdaf 102 Test to see if Graphics Console could be supported on the Controller.\r
24248368 103\r
104 Graphics Console could be supported if Graphics Output Protocol or UGA Draw\r
8595bdaf 105 Protocol exists on the Controller. (UGA Draw Protocol could be skipped\r
24248368 106 if PcdUgaConsumeSupport is set to FALSE.)\r
107\r
108 @param This Protocol instance pointer.\r
8595bdaf 109 @param Controller Handle of device to test.\r
24248368 110 @param RemainingDevicePath Optional parameter use to pick a specific child\r
111 device to start.\r
112\r
8595bdaf 113 @retval EFI_SUCCESS This driver supports this device.\r
114 @retval other This driver does not support this device.\r
24248368 115\r
116**/\r
95276127 117EFI_STATUS\r
118EFIAPI\r
119GraphicsConsoleControllerDriverSupported (\r
120 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
121 IN EFI_HANDLE Controller,\r
122 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
123 )\r
124{\r
8541adab 125 EFI_STATUS Status;\r
95276127 126 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
8541adab 127 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
128 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
95276127 129\r
8541adab 130 GraphicsOutput = NULL;\r
131 UgaDraw = NULL;\r
95276127 132 //\r
133 // Open the IO Abstraction(s) needed to perform the supported test\r
134 //\r
135 Status = gBS->OpenProtocol (\r
136 Controller,\r
137 &gEfiGraphicsOutputProtocolGuid,\r
138 (VOID **) &GraphicsOutput,\r
139 This->DriverBindingHandle,\r
140 Controller,\r
141 EFI_OPEN_PROTOCOL_BY_DRIVER\r
142 );\r
8541adab 143\r
144 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 145 //\r
146 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol\r
147 //\r
148 Status = gBS->OpenProtocol (\r
149 Controller,\r
150 &gEfiUgaDrawProtocolGuid,\r
151 (VOID **) &UgaDraw,\r
152 This->DriverBindingHandle,\r
153 Controller,\r
154 EFI_OPEN_PROTOCOL_BY_DRIVER\r
155 );\r
8541adab 156 }\r
157 if (EFI_ERROR (Status)) {\r
158 return Status;\r
95276127 159 }\r
160\r
161 //\r
162 // We need to ensure that we do not layer on top of a virtual handle.\r
163 // We need to ensure that the handles produced by the conspliter do not\r
164 // get used.\r
165 //\r
166 Status = gBS->OpenProtocol (\r
167 Controller,\r
168 &gEfiDevicePathProtocolGuid,\r
169 (VOID **) &DevicePath,\r
170 This->DriverBindingHandle,\r
171 Controller,\r
172 EFI_OPEN_PROTOCOL_BY_DRIVER\r
173 );\r
174 if (!EFI_ERROR (Status)) {\r
175 gBS->CloseProtocol (\r
176 Controller,\r
177 &gEfiDevicePathProtocolGuid,\r
178 This->DriverBindingHandle,\r
179 Controller\r
180 );\r
181 } else {\r
182 goto Error;\r
183 }\r
93e3992d 184\r
95276127 185 //\r
186 // Does Hii Exist? If not, we aren't ready to run\r
187 //\r
188 Status = EfiLocateHiiProtocol ();\r
189\r
190 //\r
191 // Close the I/O Abstraction(s) used to perform the supported test\r
192 //\r
193Error:\r
194 if (GraphicsOutput != NULL) {\r
195 gBS->CloseProtocol (\r
196 Controller,\r
197 &gEfiGraphicsOutputProtocolGuid,\r
198 This->DriverBindingHandle,\r
199 Controller\r
200 );\r
8541adab 201 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 202 gBS->CloseProtocol (\r
203 Controller,\r
204 &gEfiUgaDrawProtocolGuid,\r
205 This->DriverBindingHandle,\r
206 Controller\r
207 );\r
208 }\r
209 return Status;\r
210}\r
211\r
6dcf9abc 212\r
213/**\r
677fdb90 214 Start this driver on Controller by opening Graphics Output protocol or\r
8595bdaf 215 UGA Draw protocol, and installing Simple Text Out protocol on Controller.\r
878670ea 216 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)\r
677fdb90 217\r
24248368 218 @param This Protocol instance pointer.\r
8595bdaf 219 @param Controller Handle of device to bind driver to\r
24248368 220 @param RemainingDevicePath Optional parameter use to pick a specific child\r
221 device to start.\r
222\r
8595bdaf 223 @retval EFI_SUCCESS This driver is added to Controller.\r
224 @retval other This driver does not support this device.\r
6dcf9abc 225\r
226**/\r
95276127 227EFI_STATUS\r
228EFIAPI\r
229GraphicsConsoleControllerDriverStart (\r
230 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
231 IN EFI_HANDLE Controller,\r
232 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
233 )\r
95276127 234{\r
3012ce5c 235 EFI_STATUS Status;\r
236 GRAPHICS_CONSOLE_DEV *Private;\r
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
643 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);\r
644 if (!EFI_ERROR (Status)) {\r
0322ed7a 645 FreePool (Info);\r
3012ce5c 646 break;\r
647 }\r
648 }\r
0322ed7a 649 FreePool (Info);\r
3012ce5c 650 }\r
651 }\r
8541adab 652\r
3012ce5c 653 if (ModeNumber == GraphicsOutput->Mode->MaxMode) {\r
654 Status = EFI_UNSUPPORTED;\r
655 }\r
8541adab 656\r
3012ce5c 657 *CurrentModeNumber = ModeNumber;\r
8541adab 658 return Status;\r
3012ce5c 659}\r
660\r
95276127 661\r
6dcf9abc 662/**\r
24248368 663 Locate HII Database protocol and HII Font protocol.\r
95276127 664\r
677fdb90 665 @retval EFI_SUCCESS HII Database protocol and HII Font protocol\r
24248368 666 are located successfully.\r
677fdb90 667 @return other Failed to locate HII Database protocol or\r
24248368 668 HII Font protocol.\r
95276127 669\r
6dcf9abc 670**/\r
671EFI_STATUS\r
672EfiLocateHiiProtocol (\r
673 VOID\r
674 )\r
95276127 675{\r
676 EFI_HANDLE Handle;\r
677 UINTN Size;\r
678 EFI_STATUS Status;\r
679\r
93e3992d 680 //\r
681 // There should only be one - so buffer size is this\r
682 //\r
683 Size = sizeof (EFI_HANDLE);\r
684\r
685 Status = gBS->LocateHandle (\r
686 ByProtocol,\r
687 &gEfiHiiDatabaseProtocolGuid,\r
688 NULL,\r
689 &Size,\r
690 (VOID **) &Handle\r
691 );\r
692\r
693 if (EFI_ERROR (Status)) {\r
694 return Status;\r
695 }\r
696\r
697 Status = gBS->HandleProtocol (\r
698 Handle,\r
699 &gEfiHiiDatabaseProtocolGuid,\r
700 (VOID **) &mHiiDatabase\r
701 );\r
702\r
703 if (EFI_ERROR (Status)) {\r
704 return Status;\r
705 }\r
706\r
707 Status = gBS->HandleProtocol (\r
708 Handle,\r
709 &gEfiHiiFontProtocolGuid,\r
710 (VOID **) &mHiiFont\r
711 );\r
712 return Status;\r
95276127 713}\r
93e3992d 714\r
95276127 715//\r
716// Body of the STO functions\r
717//\r
6dcf9abc 718\r
719/**\r
878670ea 720 Reset the text output device hardware and optionally run diagnostics.\r
677fdb90 721\r
6dcf9abc 722 Implements SIMPLE_TEXT_OUTPUT.Reset().\r
723 If ExtendeVerification is TRUE, then perform dependent Graphics Console\r
724 device reset, and set display mode to mode 0.\r
725 If ExtendedVerification is FALSE, only set display mode to mode 0.\r
726\r
24248368 727 @param This Protocol instance pointer.\r
6dcf9abc 728 @param ExtendedVerification Indicates that the driver may perform a more\r
729 exhaustive verification operation of the device\r
730 during reset.\r
731\r
24248368 732 @retval EFI_SUCCESS The text output device was reset.\r
733 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and\r
734 could not be reset.\r
6dcf9abc 735\r
736**/\r
95276127 737EFI_STATUS\r
738EFIAPI\r
739GraphicsConsoleConOutReset (\r
740 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
741 IN BOOLEAN ExtendedVerification\r
742 )\r
95276127 743{\r
744 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
745 return This->SetMode (This, 0);\r
746}\r
747\r
6dcf9abc 748\r
749/**\r
24248368 750 Write a Unicode string to the output device.\r
751\r
677fdb90 752 Implements SIMPLE_TEXT_OUTPUT.OutputString().\r
6dcf9abc 753 The Unicode string will be converted to Glyphs and will be\r
754 sent to the Graphics Console.\r
755\r
24248368 756 @param This Protocol instance pointer.\r
757 @param WString The NULL-terminated Unicode string to be displayed\r
758 on the output device(s). All output devices must\r
759 also support the Unicode drawing defined in this file.\r
6dcf9abc 760\r
24248368 761 @retval EFI_SUCCESS The string was output to the device.\r
762 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output\r
763 the text.\r
764 @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
765 defined text mode.\r
766 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
767 characters in the Unicode string could not be\r
768 rendered and were skipped.\r
6dcf9abc 769\r
770**/\r
95276127 771EFI_STATUS\r
772EFIAPI\r
773GraphicsConsoleConOutOutputString (\r
774 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
775 IN CHAR16 *WString\r
776 )\r
95276127 777{\r
778 GRAPHICS_CONSOLE_DEV *Private;\r
779 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
780 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
781 INTN Mode;\r
782 UINTN MaxColumn;\r
783 UINTN MaxRow;\r
784 UINTN Width;\r
785 UINTN Height;\r
786 UINTN Delta;\r
787 EFI_STATUS Status;\r
788 BOOLEAN Warning;\r
789 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
790 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
791 UINTN DeltaX;\r
792 UINTN DeltaY;\r
793 UINTN Count;\r
794 UINTN Index;\r
795 INT32 OriginAttribute;\r
796 EFI_TPL OldTpl;\r
95276127 797\r
798 Status = EFI_SUCCESS;\r
799\r
800 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
801 //\r
802 // Current mode\r
803 //\r
804 Mode = This->Mode->Mode;\r
805 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
806 GraphicsOutput = Private->GraphicsOutput;\r
807 UgaDraw = Private->UgaDraw;\r
808\r
809 MaxColumn = Private->ModeData[Mode].Columns;\r
810 MaxRow = Private->ModeData[Mode].Rows;\r
811 DeltaX = Private->ModeData[Mode].DeltaX;\r
812 DeltaY = Private->ModeData[Mode].DeltaY;\r
0898c57c 813 Width = MaxColumn * EFI_GLYPH_WIDTH;\r
814 Height = (MaxRow - 1) * EFI_GLYPH_HEIGHT;\r
95276127 815 Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
816\r
817 //\r
818 // The Attributes won't change when during the time OutputString is called\r
819 //\r
820 GetTextColors (This, &Foreground, &Background);\r
821\r
822 EraseCursor (This);\r
823\r
824 Warning = FALSE;\r
825\r
826 //\r
827 // Backup attribute\r
828 //\r
829 OriginAttribute = This->Mode->Attribute;\r
830\r
6dcf9abc 831 while (*WString != L'\0') {\r
95276127 832\r
833 if (*WString == CHAR_BACKSPACE) {\r
834 //\r
835 // If the cursor is at the left edge of the display, then move the cursor\r
836 // one row up.\r
837 //\r
838 if (This->Mode->CursorColumn == 0 && This->Mode->CursorRow > 0) {\r
839 This->Mode->CursorRow--;\r
840 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);\r
841 This->OutputString (This, SpaceStr);\r
842 EraseCursor (This);\r
843 This->Mode->CursorRow--;\r
844 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);\r
845 } else if (This->Mode->CursorColumn > 0) {\r
846 //\r
847 // If the cursor is not at the left edge of the display, then move the cursor\r
848 // left one column.\r
849 //\r
850 This->Mode->CursorColumn--;\r
851 This->OutputString (This, SpaceStr);\r
852 EraseCursor (This);\r
853 This->Mode->CursorColumn--;\r
854 }\r
855\r
856 WString++;\r
857\r
858 } else if (*WString == CHAR_LINEFEED) {\r
859 //\r
860 // If the cursor is at the bottom of the display, then scroll the display one\r
861 // row, and do not update the cursor position. Otherwise, move the cursor\r
862 // down one row.\r
863 //\r
864 if (This->Mode->CursorRow == (INT32) (MaxRow - 1)) {\r
865 if (GraphicsOutput != NULL) {\r
866 //\r
867 // Scroll Screen Up One Row\r
868 //\r
869 GraphicsOutput->Blt (\r
870 GraphicsOutput,\r
871 NULL,\r
872 EfiBltVideoToVideo,\r
873 DeltaX,\r
0898c57c 874 DeltaY + EFI_GLYPH_HEIGHT,\r
95276127 875 DeltaX,\r
876 DeltaY,\r
877 Width,\r
878 Height,\r
879 Delta\r
880 );\r
881\r
882 //\r
883 // Print Blank Line at last line\r
884 //\r
885 GraphicsOutput->Blt (\r
886 GraphicsOutput,\r
887 &Background,\r
888 EfiBltVideoFill,\r
889 0,\r
890 0,\r
891 DeltaX,\r
892 DeltaY + Height,\r
893 Width,\r
0898c57c 894 EFI_GLYPH_HEIGHT,\r
95276127 895 Delta\r
896 );\r
8541adab 897 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 898 //\r
899 // Scroll Screen Up One Row\r
900 //\r
901 UgaDraw->Blt (\r
902 UgaDraw,\r
903 NULL,\r
904 EfiUgaVideoToVideo,\r
905 DeltaX,\r
0898c57c 906 DeltaY + EFI_GLYPH_HEIGHT,\r
95276127 907 DeltaX,\r
908 DeltaY,\r
909 Width,\r
910 Height,\r
911 Delta\r
912 );\r
913\r
914 //\r
915 // Print Blank Line at last line\r
916 //\r
917 UgaDraw->Blt (\r
918 UgaDraw,\r
919 (EFI_UGA_PIXEL *) (UINTN) &Background,\r
920 EfiUgaVideoFill,\r
921 0,\r
922 0,\r
923 DeltaX,\r
924 DeltaY + Height,\r
925 Width,\r
0898c57c 926 EFI_GLYPH_HEIGHT,\r
95276127 927 Delta\r
928 );\r
929 }\r
930 } else {\r
931 This->Mode->CursorRow++;\r
932 }\r
933\r
934 WString++;\r
935\r
936 } else if (*WString == CHAR_CARRIAGE_RETURN) {\r
937 //\r
938 // Move the cursor to the beginning of the current row.\r
939 //\r
940 This->Mode->CursorColumn = 0;\r
941 WString++;\r
942\r
943 } else if (*WString == WIDE_CHAR) {\r
944\r
945 This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;\r
946 WString++;\r
947\r
948 } else if (*WString == NARROW_CHAR) {\r
949\r
950 This->Mode->Attribute &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);\r
951 WString++;\r
952\r
953 } else {\r
954 //\r
955 // Print the character at the current cursor position and move the cursor\r
956 // right one column. If this moves the cursor past the right edge of the\r
957 // display, then the line should wrap to the beginning of the next line. This\r
958 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the\r
959 // bottom of the display, and the line wraps, then the display will be scrolled\r
960 // one line.\r
961 // If wide char is going to be displayed, need to display one character at a time\r
962 // Or, need to know the display length of a certain string.\r
963 //\r
964 // Index is used to determine how many character width units (wide = 2, narrow = 1)\r
965 // Count is used to determine how many characters are used regardless of their attributes\r
966 //\r
967 for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {\r
677fdb90 968 if (WString[Count] == CHAR_NULL ||\r
969 WString[Count] == CHAR_BACKSPACE ||\r
878670ea 970 WString[Count] == CHAR_LINEFEED ||\r
971 WString[Count] == CHAR_CARRIAGE_RETURN ||\r
972 WString[Count] == WIDE_CHAR ||\r
973 WString[Count] == NARROW_CHAR) {\r
95276127 974 break;\r
975 }\r
976 //\r
977 // Is the wide attribute on?\r
978 //\r
677fdb90 979 if ((This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) != 0) {\r
95276127 980 //\r
981 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop\r
982 //\r
983 Index++;\r
984 //\r
985 // This is the end-case where if we are at column 79 and about to print a wide character\r
986 // We should prevent this from happening because we will wrap inappropriately. We should\r
987 // not print this character until the next line.\r
988 //\r
989 if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {\r
990 Index++;\r
991 break;\r
992 }\r
993 }\r
994 }\r
995\r
996 Status = DrawUnicodeWeightAtCursorN (This, WString, Count);\r
997 if (EFI_ERROR (Status)) {\r
998 Warning = TRUE;\r
999 }\r
1000 //\r
1001 // At the end of line, output carriage return and line feed\r
1002 //\r
1003 WString += Count;\r
1004 This->Mode->CursorColumn += (INT32) Index;\r
1005 if (This->Mode->CursorColumn > (INT32) MaxColumn) {\r
1006 This->Mode->CursorColumn -= 2;\r
1007 This->OutputString (This, SpaceStr);\r
1008 }\r
1009\r
1010 if (This->Mode->CursorColumn >= (INT32) MaxColumn) {\r
1011 EraseCursor (This);\r
1012 This->OutputString (This, mCrLfString);\r
1013 EraseCursor (This);\r
1014 }\r
1015 }\r
1016 }\r
1017\r
1018 This->Mode->Attribute = OriginAttribute;\r
1019\r
1020 EraseCursor (This);\r
1021\r
1022 if (Warning) {\r
1023 Status = EFI_WARN_UNKNOWN_GLYPH;\r
1024 }\r
1025\r
1026 gBS->RestoreTPL (OldTpl);\r
1027 return Status;\r
1028\r
1029}\r
1030\r
6dcf9abc 1031/**\r
677fdb90 1032 Verifies that all characters in a Unicode string can be output to the\r
24248368 1033 target device.\r
6dcf9abc 1034\r
5c03ed0a 1035 Implements SIMPLE_TEXT_OUTPUT.TestString().\r
24248368 1036 If one of the characters in the *Wstring is neither valid valid Unicode\r
1037 drawing characters, not ASCII code, then this function will return\r
1038 EFI_UNSUPPORTED\r
1039\r
1040 @param This Protocol instance pointer.\r
1041 @param WString The NULL-terminated Unicode string to be examined for the output\r
1042 device(s).\r
6dcf9abc 1043\r
24248368 1044 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.\r
1045 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be\r
1046 rendered by one or more of the output devices mapped\r
1047 by the EFI handle.\r
6dcf9abc 1048\r
1049**/\r
95276127 1050EFI_STATUS\r
1051EFIAPI\r
1052GraphicsConsoleConOutTestString (\r
1053 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1054 IN CHAR16 *WString\r
1055 )\r
95276127 1056{\r
1057 EFI_STATUS Status;\r
95276127 1058 UINT16 Count;\r
95276127 1059\r
6dcf9abc 1060 EFI_IMAGE_OUTPUT *Blt;\r
93e3992d 1061\r
6dcf9abc 1062 Blt = NULL;\r
93e3992d 1063 Count = 0;\r
1064\r
1065 while (WString[Count] != 0) {\r
93e3992d 1066 Status = mHiiFont->GetGlyph (\r
1067 mHiiFont,\r
1068 WString[Count],\r
1069 NULL,\r
1070 &Blt,\r
1071 NULL\r
1072 );\r
676df92c 1073 if (Blt != NULL) {\r
1074 FreePool (Blt);\r
1075 Blt = NULL;\r
1076 }\r
93e3992d 1077 Count++;\r
d42d853e 1078\r
95276127 1079 if (EFI_ERROR (Status)) {\r
1080 return EFI_UNSUPPORTED;\r
1081 }\r
1082 }\r
1083\r
1084 return EFI_SUCCESS;\r
1085}\r
1086\r
6dcf9abc 1087\r
1088/**\r
24248368 1089 Returns information for an available text mode that the output device(s)\r
1090 supports\r
1091\r
6dcf9abc 1092 Implements SIMPLE_TEXT_OUTPUT.QueryMode().\r
24248368 1093 It returnes information for an available text mode that the Graphics Console supports.\r
1094 In this driver,we only support text mode 80x25, which is defined as mode 0.\r
6dcf9abc 1095\r
24248368 1096 @param This Protocol instance pointer.\r
6dcf9abc 1097 @param ModeNumber The mode number to return information on.\r
1098 @param Columns The returned columns of the requested mode.\r
1099 @param Rows The returned rows of the requested mode.\r
1100\r
24248368 1101 @retval EFI_SUCCESS The requested mode information is returned.\r
1102 @retval EFI_UNSUPPORTED The mode number is not valid.\r
6dcf9abc 1103\r
1104**/\r
95276127 1105EFI_STATUS\r
1106EFIAPI\r
1107GraphicsConsoleConOutQueryMode (\r
1108 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1109 IN UINTN ModeNumber,\r
1110 OUT UINTN *Columns,\r
1111 OUT UINTN *Rows\r
1112 )\r
95276127 1113{\r
1114 GRAPHICS_CONSOLE_DEV *Private;\r
1115 EFI_STATUS Status;\r
1116 EFI_TPL OldTpl;\r
8541adab 1117\r
95276127 1118 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {\r
1119 return EFI_UNSUPPORTED;\r
1120 }\r
1121\r
1122 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1123 Status = EFI_SUCCESS;\r
8541adab 1124\r
95276127 1125 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1126\r
1127 *Columns = Private->ModeData[ModeNumber].Columns;\r
1128 *Rows = Private->ModeData[ModeNumber].Rows;\r
1129\r
1130 if (*Columns <= 0 && *Rows <= 0) {\r
1131 Status = EFI_UNSUPPORTED;\r
1132 goto Done;\r
1133\r
1134 }\r
1135\r
1136Done:\r
1137 gBS->RestoreTPL (OldTpl);\r
1138 return Status;\r
1139}\r
1140\r
6dcf9abc 1141\r
1142/**\r
24248368 1143 Sets the output device(s) to a specified mode.\r
677fdb90 1144\r
6dcf9abc 1145 Implements SIMPLE_TEXT_OUTPUT.SetMode().\r
24248368 1146 Set the Graphics Console to a specified mode. In this driver, we only support mode 0.\r
6dcf9abc 1147\r
24248368 1148 @param This Protocol instance pointer.\r
6dcf9abc 1149 @param ModeNumber The text mode to set.\r
1150\r
24248368 1151 @retval EFI_SUCCESS The requested text mode is set.\r
677fdb90 1152 @retval EFI_DEVICE_ERROR The requested text mode cannot be set because of\r
24248368 1153 Graphics Console device error.\r
1154 @retval EFI_UNSUPPORTED The text mode number is not valid.\r
6dcf9abc 1155\r
1156**/\r
95276127 1157EFI_STATUS\r
1158EFIAPI\r
1159GraphicsConsoleConOutSetMode (\r
1160 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1161 IN UINTN ModeNumber\r
1162 )\r
95276127 1163{\r
1164 EFI_STATUS Status;\r
1165 GRAPHICS_CONSOLE_DEV *Private;\r
1166 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1167 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewLineBuffer;\r
1168 UINT32 HorizontalResolution;\r
1169 UINT32 VerticalResolution;\r
1170 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1171 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1172 UINT32 ColorDepth;\r
1173 UINT32 RefreshRate;\r
1174 EFI_TPL OldTpl;\r
1175\r
1176 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1177\r
1178 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1179 GraphicsOutput = Private->GraphicsOutput;\r
1180 UgaDraw = Private->UgaDraw;\r
1181 ModeData = &(Private->ModeData[ModeNumber]);\r
1182\r
1183 if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {\r
1184 Status = EFI_UNSUPPORTED;\r
1185 goto Done;\r
1186 }\r
1187\r
1188 //\r
1189 // Make sure the requested mode number is supported\r
1190 //\r
1191 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {\r
1192 Status = EFI_UNSUPPORTED;\r
1193 goto Done;\r
1194 }\r
1195\r
1196 if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {\r
1197 Status = EFI_UNSUPPORTED;\r
1198 goto Done;\r
1199 }\r
1200 //\r
1201 // Attempt to allocate a line buffer for the requested mode number\r
1202 //\r
0898c57c 1203 NewLineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT);\r
95276127 1204\r
1205 if (NewLineBuffer == NULL) {\r
1206 //\r
1207 // The new line buffer could not be allocated, so return an error.\r
1208 // No changes to the state of the current console have been made, so the current console is still valid\r
1209 //\r
1210 Status = EFI_OUT_OF_RESOURCES;\r
1211 goto Done;\r
1212 }\r
1213 //\r
1214 // If the mode has been set at least one other time, then LineBuffer will not be NULL\r
1215 //\r
1216 if (Private->LineBuffer != NULL) {\r
1217 //\r
1218 // Clear the current text window on the current graphics console\r
1219 //\r
1220 This->ClearScreen (This);\r
1221\r
1222 //\r
1223 // If the new mode is the same as the old mode, then just return EFI_SUCCESS\r
1224 //\r
1225 if ((INT32) ModeNumber == This->Mode->Mode) {\r
1226 FreePool (NewLineBuffer);\r
1227 Status = EFI_SUCCESS;\r
1228 goto Done;\r
1229 }\r
1230 //\r
7347d5d6 1231 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,\r
1232 // so erase the cursor, and free the LineBuffer for the current mode\r
95276127 1233 //\r
7347d5d6 1234 EraseCursor (This);\r
95276127 1235\r
1236 FreePool (Private->LineBuffer);\r
1237 }\r
1238 //\r
1239 // Assign the current line buffer to the newly allocated line buffer\r
1240 //\r
1241 Private->LineBuffer = NewLineBuffer;\r
1242\r
1243 if (GraphicsOutput != NULL) {\r
1244 if (ModeData->GopModeNumber != GraphicsOutput->Mode->Mode) {\r
1245 //\r
878670ea 1246 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode\r
95276127 1247 //\r
1248 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeData->GopModeNumber);\r
1249 if (EFI_ERROR (Status)) {\r
1250 //\r
1251 // The mode set operation failed\r
1252 //\r
1253 goto Done;\r
1254 }\r
1255 } else {\r
1256 //\r
1257 // The current graphics mode is correct, so simply clear the entire display\r
1258 //\r
1259 Status = GraphicsOutput->Blt (\r
1260 GraphicsOutput,\r
1261 &mEfiColors[0],\r
1262 EfiBltVideoFill,\r
1263 0,\r
1264 0,\r
1265 0,\r
1266 0,\r
1267 ModeData->GopWidth,\r
1268 ModeData->GopHeight,\r
1269 0\r
1270 );\r
1271 }\r
8541adab 1272 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1273 //\r
1274 // Get the current UGA Draw mode information\r
1275 //\r
1276 Status = UgaDraw->GetMode (\r
1277 UgaDraw,\r
1278 &HorizontalResolution,\r
1279 &VerticalResolution,\r
1280 &ColorDepth,\r
1281 &RefreshRate\r
1282 );\r
1283 if (EFI_ERROR (Status) || HorizontalResolution != ModeData->GopWidth || VerticalResolution != ModeData->GopHeight) {\r
1284 //\r
878670ea 1285 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode\r
95276127 1286 //\r
1287 Status = UgaDraw->SetMode (\r
1288 UgaDraw,\r
1289 ModeData->GopWidth,\r
1290 ModeData->GopHeight,\r
1291 32,\r
1292 60\r
1293 );\r
1294 if (EFI_ERROR (Status)) {\r
1295 //\r
1296 // The mode set operation failed\r
1297 //\r
1298 goto Done;\r
1299 }\r
1300 } else {\r
1301 //\r
1302 // The current graphics mode is correct, so simply clear the entire display\r
1303 //\r
1304 Status = UgaDraw->Blt (\r
1305 UgaDraw,\r
1306 (EFI_UGA_PIXEL *) (UINTN) &mEfiColors[0],\r
1307 EfiUgaVideoFill,\r
1308 0,\r
1309 0,\r
1310 0,\r
1311 0,\r
1312 ModeData->GopWidth,\r
1313 ModeData->GopHeight,\r
1314 0\r
1315 );\r
1316 }\r
1317 }\r
1318\r
1319 //\r
1320 // The new mode is valid, so commit the mode change\r
1321 //\r
1322 This->Mode->Mode = (INT32) ModeNumber;\r
1323\r
1324 //\r
878670ea 1325 // Move the text cursor to the upper left hand corner of the display and enable it\r
95276127 1326 //\r
1327 This->SetCursorPosition (This, 0, 0);\r
95276127 1328\r
1329 Status = EFI_SUCCESS;\r
1330\r
1331Done:\r
1332 gBS->RestoreTPL (OldTpl);\r
1333 return Status;\r
1334}\r
1335\r
6dcf9abc 1336\r
1337/**\r
24248368 1338 Sets the background and foreground colors for the OutputString () and\r
1339 ClearScreen () functions.\r
1340\r
6dcf9abc 1341 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().\r
1342\r
24248368 1343 @param This Protocol instance pointer.\r
1344 @param Attribute The attribute to set. Bits 0..3 are the foreground\r
677fdb90 1345 color, and bits 4..6 are the background color.\r
24248368 1346 All other bits are undefined and must be zero.\r
6dcf9abc 1347\r
24248368 1348 @retval EFI_SUCCESS The requested attribute is set.\r
1349 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to Graphics Console port error.\r
1350 @retval EFI_UNSUPPORTED The attribute requested is not defined.\r
6dcf9abc 1351\r
1352**/\r
95276127 1353EFI_STATUS\r
1354EFIAPI\r
1355GraphicsConsoleConOutSetAttribute (\r
1356 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1357 IN UINTN Attribute\r
1358 )\r
95276127 1359{\r
1360 EFI_TPL OldTpl;\r
8541adab 1361\r
95276127 1362 if ((Attribute | 0xFF) != 0xFF) {\r
1363 return EFI_UNSUPPORTED;\r
1364 }\r
1365\r
1366 if ((INT32) Attribute == This->Mode->Attribute) {\r
1367 return EFI_SUCCESS;\r
1368 }\r
1369\r
1370 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1371\r
1372 EraseCursor (This);\r
1373\r
1374 This->Mode->Attribute = (INT32) Attribute;\r
1375\r
1376 EraseCursor (This);\r
1377\r
1378 gBS->RestoreTPL (OldTpl);\r
1379\r
1380 return EFI_SUCCESS;\r
1381}\r
1382\r
6dcf9abc 1383\r
1384/**\r
677fdb90 1385 Clears the output device(s) display to the currently selected background\r
24248368 1386 color.\r
1387\r
6dcf9abc 1388 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().\r
6dcf9abc 1389\r
24248368 1390 @param This Protocol instance pointer.\r
6dcf9abc 1391\r
24248368 1392 @retval EFI_SUCCESS The operation completed successfully.\r
1393 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.\r
1394 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.\r
6dcf9abc 1395\r
1396**/\r
95276127 1397EFI_STATUS\r
1398EFIAPI\r
1399GraphicsConsoleConOutClearScreen (\r
1400 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
1401 )\r
95276127 1402{\r
1403 EFI_STATUS Status;\r
1404 GRAPHICS_CONSOLE_DEV *Private;\r
1405 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1406 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1407 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1408 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
1409 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
1410 EFI_TPL OldTpl;\r
1411\r
1412 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1413\r
1414 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1415 GraphicsOutput = Private->GraphicsOutput;\r
1416 UgaDraw = Private->UgaDraw;\r
1417 ModeData = &(Private->ModeData[This->Mode->Mode]);\r
1418\r
1419 GetTextColors (This, &Foreground, &Background);\r
1420 if (GraphicsOutput != NULL) {\r
1421 Status = GraphicsOutput->Blt (\r
1422 GraphicsOutput,\r
1423 &Background,\r
1424 EfiBltVideoFill,\r
1425 0,\r
1426 0,\r
1427 0,\r
1428 0,\r
1429 ModeData->GopWidth,\r
1430 ModeData->GopHeight,\r
1431 0\r
1432 );\r
8541adab 1433 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1434 Status = UgaDraw->Blt (\r
1435 UgaDraw,\r
1436 (EFI_UGA_PIXEL *) (UINTN) &Background,\r
1437 EfiUgaVideoFill,\r
1438 0,\r
1439 0,\r
1440 0,\r
1441 0,\r
1442 ModeData->GopWidth,\r
1443 ModeData->GopHeight,\r
1444 0\r
1445 );\r
8541adab 1446 } else {\r
1447 Status = EFI_UNSUPPORTED;\r
95276127 1448 }\r
1449\r
1450 This->Mode->CursorColumn = 0;\r
1451 This->Mode->CursorRow = 0;\r
1452\r
1453 EraseCursor (This);\r
1454\r
1455 gBS->RestoreTPL (OldTpl);\r
1456\r
1457 return Status;\r
1458}\r
1459\r
6dcf9abc 1460\r
1461/**\r
24248368 1462 Sets the current coordinates of the cursor position.\r
1463\r
6dcf9abc 1464 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().\r
1465\r
24248368 1466 @param This Protocol instance pointer.\r
1467 @param Column The position to set the cursor to. Must be greater than or\r
1468 equal to zero and less than the number of columns and rows\r
1469 by QueryMode ().\r
1470 @param Row 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
6dcf9abc 1473\r
24248368 1474 @retval EFI_SUCCESS The operation completed successfully.\r
1475 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.\r
1476 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the\r
1477 cursor position is invalid for the current mode.\r
6dcf9abc 1478\r
1479**/\r
95276127 1480EFI_STATUS\r
1481EFIAPI\r
1482GraphicsConsoleConOutSetCursorPosition (\r
1483 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1484 IN UINTN Column,\r
1485 IN UINTN Row\r
1486 )\r
95276127 1487{\r
1488 GRAPHICS_CONSOLE_DEV *Private;\r
1489 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1490 EFI_STATUS Status;\r
1491 EFI_TPL OldTpl;\r
1492\r
1493 Status = EFI_SUCCESS;\r
1494\r
1495 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1496\r
1497 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1498 ModeData = &(Private->ModeData[This->Mode->Mode]);\r
1499\r
1500 if ((Column >= ModeData->Columns) || (Row >= ModeData->Rows)) {\r
1501 Status = EFI_UNSUPPORTED;\r
1502 goto Done;\r
1503 }\r
1504\r
8595bdaf 1505 if ((This->Mode->CursorColumn == (INT32) Column) && (This->Mode->CursorRow == (INT32) Row)) {\r
95276127 1506 Status = EFI_SUCCESS;\r
1507 goto Done;\r
1508 }\r
1509\r
1510 EraseCursor (This);\r
1511\r
1512 This->Mode->CursorColumn = (INT32) Column;\r
1513 This->Mode->CursorRow = (INT32) Row;\r
1514\r
1515 EraseCursor (This);\r
1516\r
1517Done:\r
1518 gBS->RestoreTPL (OldTpl);\r
1519\r
1520 return Status;\r
1521}\r
1522\r
6dcf9abc 1523\r
1524/**\r
24248368 1525 Makes the cursor visible or invisible.\r
1526\r
6dcf9abc 1527 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().\r
6dcf9abc 1528\r
24248368 1529 @param This Protocol instance pointer.\r
6dcf9abc 1530 @param Visible If TRUE, the cursor is set to be visible, If FALSE,\r
1531 the cursor is set to be invisible.\r
1532\r
24248368 1533 @retval EFI_SUCCESS The operation completed successfully.\r
6dcf9abc 1534\r
1535**/\r
95276127 1536EFI_STATUS\r
1537EFIAPI\r
1538GraphicsConsoleConOutEnableCursor (\r
1539 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1540 IN BOOLEAN Visible\r
1541 )\r
95276127 1542{\r
1543 EFI_TPL OldTpl;\r
8541adab 1544\r
95276127 1545 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
8541adab 1546\r
95276127 1547 EraseCursor (This);\r
1548\r
1549 This->Mode->CursorVisible = Visible;\r
1550\r
1551 EraseCursor (This);\r
1552\r
1553 gBS->RestoreTPL (OldTpl);\r
1554 return EFI_SUCCESS;\r
1555}\r
1556\r
24248368 1557/**\r
1558 Gets Graphics Console devcie's foreground color and background color.\r
1559\r
1560 @param This Protocol instance pointer.\r
1561 @param Foreground Returned text foreground color.\r
1562 @param Background Returned text background color.\r
1563\r
1564 @retval EFI_SUCCESS It returned always.\r
1565\r
1566**/\r
95276127 1567EFI_STATUS\r
1568GetTextColors (\r
1569 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1570 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
1571 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background\r
1572 )\r
1573{\r
1574 INTN Attribute;\r
1575\r
1576 Attribute = This->Mode->Attribute & 0x7F;\r
1577\r
1578 *Foreground = mEfiColors[Attribute & 0x0f];\r
1579 *Background = mEfiColors[Attribute >> 4];\r
1580\r
1581 return EFI_SUCCESS;\r
1582}\r
1583\r
24248368 1584/**\r
878670ea 1585 Draw Unicode string on the Graphics Console device's screen.\r
24248368 1586\r
1587 @param This Protocol instance pointer.\r
1588 @param UnicodeWeight One Unicode string to be displayed.\r
1589 @param Count The count of Unicode string.\r
1590\r
1591 @retval EFI_OUT_OF_RESOURCES If no memory resource to use.\r
1592 @retval EFI_UNSUPPORTED If no Graphics Output protocol and UGA Draw\r
1593 protocol exist.\r
1594 @retval EFI_SUCCESS Drawing Unicode string implemented successfully.\r
1595\r
1596**/\r
93e3992d 1597EFI_STATUS\r
1598DrawUnicodeWeightAtCursorN (\r
1599 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
24248368 1600 IN CHAR16 *UnicodeWeight,\r
1601 IN UINTN Count\r
93e3992d 1602 )\r
1603{\r
1604 EFI_STATUS Status;\r
1605 GRAPHICS_CONSOLE_DEV *Private;\r
1606 EFI_IMAGE_OUTPUT *Blt;\r
1607 EFI_STRING String;\r
1608 EFI_FONT_DISPLAY_INFO *FontInfo;\r
d42d853e 1609 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1610 EFI_HII_ROW_INFO *RowInfoArray;\r
1611 UINTN RowInfoArraySize;\r
93e3992d 1612\r
1613 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
93e3992d 1614 Blt = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
1615 if (Blt == NULL) {\r
1616 return EFI_OUT_OF_RESOURCES;\r
1617 }\r
1618\r
1619 Blt->Width = (UINT16) (Private->ModeData[This->Mode->Mode].GopWidth);\r
1620 Blt->Height = (UINT16) (Private->ModeData[This->Mode->Mode].GopHeight);\r
93e3992d 1621\r
1622 String = AllocateCopyPool ((Count + 1) * sizeof (CHAR16), UnicodeWeight);\r
1623 if (String == NULL) {\r
676df92c 1624 FreePool (Blt);\r
93e3992d 1625 return EFI_OUT_OF_RESOURCES;\r
1626 }\r
8595bdaf 1627 //\r
1628 // Set the end character\r
1629 //\r
1630 *(String + Count) = L'\0';\r
93e3992d 1631\r
1632 FontInfo = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));\r
1633 if (FontInfo == NULL) {\r
676df92c 1634 FreePool (Blt);\r
1635 FreePool (String);\r
93e3992d 1636 return EFI_OUT_OF_RESOURCES;\r
1637 }\r
8595bdaf 1638 //\r
1639 // Get current foreground and background colors.\r
1640 //\r
93e3992d 1641 GetTextColors (This, &FontInfo->ForegroundColor, &FontInfo->BackgroundColor);\r
1642\r
d42d853e 1643 if (Private->GraphicsOutput != NULL) {\r
8595bdaf 1644 //\r
677fdb90 1645 // If Graphics Output protocol exists, using HII Font protocol to draw.\r
8595bdaf 1646 //\r
d42d853e 1647 Blt->Image.Screen = Private->GraphicsOutput;\r
95276127 1648\r
d42d853e 1649 Status = mHiiFont->StringToImage (\r
1650 mHiiFont,\r
1651 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN,\r
1652 String,\r
1653 FontInfo,\r
1654 &Blt,\r
0898c57c 1655 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1656 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
d42d853e 1657 NULL,\r
1658 NULL,\r
1659 NULL\r
1660 );\r
95276127 1661\r
8541adab 1662 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
8595bdaf 1663 //\r
677fdb90 1664 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,\r
8595bdaf 1665 // using UGA Draw protocol to draw.\r
1666 //\r
d42d853e 1667 ASSERT (Private->UgaDraw!= NULL);\r
95276127 1668\r
d42d853e 1669 UgaDraw = Private->UgaDraw;\r
95276127 1670\r
d42d853e 1671 Blt->Image.Bitmap = AllocateZeroPool (Blt->Width * Blt->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
1672 if (Blt->Image.Bitmap == NULL) {\r
676df92c 1673 FreePool (Blt);\r
1674 FreePool (String);\r
d42d853e 1675 return EFI_OUT_OF_RESOURCES;\r
95276127 1676 }\r
1677\r
d42d853e 1678 RowInfoArray = NULL;\r
1679 //\r
1680 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,\r
1681 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.\r
1682 //\r
1683 Status = mHiiFont->StringToImage (\r
1684 mHiiFont,\r
1685 EFI_HII_IGNORE_IF_NO_GLYPH,\r
1686 String,\r
1687 FontInfo,\r
1688 &Blt,\r
0898c57c 1689 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1690 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
d42d853e 1691 &RowInfoArray,\r
1692 &RowInfoArraySize,\r
1693 NULL\r
1694 );\r
95276127 1695\r
d42d853e 1696 if (!EFI_ERROR (Status)) {\r
95276127 1697 //\r
d42d853e 1698 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will\r
bd1d34ee 1699 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.\r
95276127 1700 //\r
bd1d34ee 1701 ASSERT (RowInfoArraySize <= 1);\r
8541adab 1702\r
d42d853e 1703 Status = UgaDraw->Blt (\r
1704 UgaDraw,\r
1705 (EFI_UGA_PIXEL *) Blt->Image.Bitmap,\r
1706 EfiUgaBltBufferToVideo,\r
0898c57c 1707 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1708 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
1709 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1710 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
d42d853e 1711 RowInfoArray[0].LineWidth,\r
1712 RowInfoArray[0].LineHeight,\r
1713 Blt->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1714 );\r
1715 }\r
95276127 1716\r
676df92c 1717 FreePool (RowInfoArray);\r
1718 FreePool (Blt->Image.Bitmap);\r
8541adab 1719 } else {\r
1720 Status = EFI_UNSUPPORTED;\r
95276127 1721 }\r
1722\r
676df92c 1723 if (Blt != NULL) {\r
1724 FreePool (Blt);\r
1725 }\r
1726 if (String != NULL) {\r
1727 FreePool (String);\r
1728 }\r
1729 if (FontInfo != NULL) {\r
1730 FreePool (FontInfo);\r
1731 }\r
d42d853e 1732 return Status;\r
95276127 1733}\r
d42d853e 1734\r
24248368 1735/**\r
1736 Erase the cursor on the screen.\r
95276127 1737\r
24248368 1738 @param This Protocol instance pointer.\r
1739\r
1740 @retval EFI_SUCCESS The cursor is erased successfully.\r
1741\r
1742**/\r
95276127 1743EFI_STATUS\r
1744EraseCursor (\r
1745 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
1746 )\r
1747{\r
7601dbe7 1748 GRAPHICS_CONSOLE_DEV *Private;\r
1749 EFI_SIMPLE_TEXT_OUTPUT_MODE *CurrentMode;\r
1750 INTN GlyphX;\r
1751 INTN GlyphY;\r
95276127 1752 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
7601dbe7 1753 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
95276127 1754 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground;\r
1755 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background;\r
0898c57c 1756 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar[EFI_GLYPH_HEIGHT][EFI_GLYPH_WIDTH];\r
7601dbe7 1757 UINTN PosX;\r
1758 UINTN PosY;\r
95276127 1759\r
1760 CurrentMode = This->Mode;\r
1761\r
1762 if (!CurrentMode->CursorVisible) {\r
1763 return EFI_SUCCESS;\r
1764 }\r
1765\r
1766 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1767 GraphicsOutput = Private->GraphicsOutput;\r
1768 UgaDraw = Private->UgaDraw;\r
1769\r
1770 //\r
24248368 1771 // In this driver, only narrow character was supported.\r
95276127 1772 //\r
1773 //\r
1774 // Blt a character to the screen\r
1775 //\r
0898c57c 1776 GlyphX = (CurrentMode->CursorColumn * EFI_GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;\r
1777 GlyphY = (CurrentMode->CursorRow * EFI_GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;\r
95276127 1778 if (GraphicsOutput != NULL) {\r
1779 GraphicsOutput->Blt (\r
1780 GraphicsOutput,\r
1781 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,\r
1782 EfiBltVideoToBltBuffer,\r
1783 GlyphX,\r
1784 GlyphY,\r
1785 0,\r
1786 0,\r
0898c57c 1787 EFI_GLYPH_WIDTH,\r
1788 EFI_GLYPH_HEIGHT,\r
1789 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
95276127 1790 );\r
8541adab 1791 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1792 UgaDraw->Blt (\r
1793 UgaDraw,\r
1794 (EFI_UGA_PIXEL *) (UINTN) BltChar,\r
1795 EfiUgaVideoToBltBuffer,\r
1796 GlyphX,\r
1797 GlyphY,\r
1798 0,\r
1799 0,\r
0898c57c 1800 EFI_GLYPH_WIDTH,\r
1801 EFI_GLYPH_HEIGHT,\r
1802 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
95276127 1803 );\r
1804 }\r
1805\r
1806 GetTextColors (This, &Foreground.Pixel, &Background.Pixel);\r
1807\r
1808 //\r
1809 // Convert Monochrome bitmap of the Glyph to BltBuffer structure\r
1810 //\r
6dcf9abc 1811 for (PosY = 0; PosY < EFI_GLYPH_HEIGHT; PosY++) {\r
1812 for (PosX = 0; PosX < EFI_GLYPH_WIDTH; PosX++) {\r
878670ea 1813 if ((mCursorGlyph.GlyphCol1[PosY] & (BIT0 << PosX)) != 0) {\r
6dcf9abc 1814 BltChar[PosY][EFI_GLYPH_WIDTH - PosX - 1].Raw ^= Foreground.Raw;\r
95276127 1815 }\r
1816 }\r
1817 }\r
1818\r
1819 if (GraphicsOutput != NULL) {\r
1820 GraphicsOutput->Blt (\r
1821 GraphicsOutput,\r
1822 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,\r
1823 EfiBltBufferToVideo,\r
1824 0,\r
1825 0,\r
1826 GlyphX,\r
1827 GlyphY,\r
0898c57c 1828 EFI_GLYPH_WIDTH,\r
1829 EFI_GLYPH_HEIGHT,\r
1830 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
95276127 1831 );\r
8541adab 1832 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1833 UgaDraw->Blt (\r
1834 UgaDraw,\r
1835 (EFI_UGA_PIXEL *) (UINTN) BltChar,\r
1836 EfiUgaBltBufferToVideo,\r
1837 0,\r
1838 0,\r
1839 GlyphX,\r
1840 GlyphY,\r
0898c57c 1841 EFI_GLYPH_WIDTH,\r
1842 EFI_GLYPH_HEIGHT,\r
1843 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
95276127 1844 );\r
1845 }\r
1846\r
1847 return EFI_SUCCESS;\r
1848}\r
97a079ed 1849\r
28487361 1850VOID\r
1851EFIAPI\r
1852RegisterFontPackage (\r
1853 IN EFI_EVENT Event,\r
1854 IN VOID *Context\r
1855 )\r
1856{\r
1857 EFI_STATUS Status;\r
1858 EFI_HII_SIMPLE_FONT_PACKAGE_HDR *SimplifiedFont;\r
1859 UINT32 PackageLength;\r
28487361 1860 UINT8 *Package;\r
1861 UINT8 *Location;\r
1862 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
1863\r
1864 //\r
1865 // Locate HII Database Protocol\r
1866 //\r
1867 Status = gBS->LocateProtocol (\r
1868 &gEfiHiiDatabaseProtocolGuid,\r
1869 NULL,\r
1870 (VOID **) &HiiDatabase\r
1871 );\r
1872 ASSERT_EFI_ERROR (Status);\r
1873\r
1874 //\r
cb7d01c0 1875 // Add 4 bytes to the header for entire length for HiiAddPackages use only.\r
28487361 1876 //\r
1877 // +--------------------------------+ <-- Package\r
1878 // | |\r
1879 // | PackageLength(4 bytes) |\r
1880 // | |\r
1881 // |--------------------------------| <-- SimplifiedFont\r
1882 // | |\r
1883 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |\r
1884 // | |\r
1885 // |--------------------------------| <-- Location\r
1886 // | |\r
1887 // | gUsStdNarrowGlyphData |\r
1888 // | |\r
1889 // +--------------------------------+\r
1890\r
1891 PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + mNarrowFontSize + 4;\r
1892 Package = AllocateZeroPool (PackageLength);\r
1893 ASSERT (Package != NULL);\r
1894\r
1895 WriteUnaligned32((UINT32 *) Package,PackageLength);\r
1896 SimplifiedFont = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR *) (Package + 4);\r
1897 SimplifiedFont->Header.Length = (UINT32) (PackageLength - 4);\r
1898 SimplifiedFont->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;\r
1899 SimplifiedFont->NumberOfNarrowGlyphs = (UINT16) (mNarrowFontSize / sizeof (EFI_NARROW_GLYPH));\r
1900\r
1901 Location = (UINT8 *) (&SimplifiedFont->NumberOfWideGlyphs + 1);\r
1902 CopyMem (Location, gUsStdNarrowGlyphData, mNarrowFontSize);\r
1903\r
1904 //\r
1905 // Add this simplified font package to a package list then install it.\r
1906 //\r
cb7d01c0 1907 mHiiHandle = HiiAddPackages (\r
1908 &mFontPackageListGuid,\r
1909 NULL,\r
1910 Package,\r
1911 NULL\r
1912 );\r
1913 ASSERT (mHiiHandle != NULL);\r
28487361 1914 FreePool (Package);\r
1915}\r
1916\r
97a079ed
A
1917/**\r
1918 The user Entry Point for module GraphicsConsole. The user code starts with this function.\r
1919\r
8541adab 1920 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
97a079ed 1921 @param[in] SystemTable A pointer to the EFI System Table.\r
8541adab 1922\r
7601dbe7 1923 @retval EFI_SUCCESS The entry point is executed successfully.\r
1924 @return other Some error occurs when executing this entry point.\r
97a079ed
A
1925\r
1926**/\r
1927EFI_STATUS\r
1928EFIAPI\r
1929InitializeGraphicsConsole (\r
1930 IN EFI_HANDLE ImageHandle,\r
1931 IN EFI_SYSTEM_TABLE *SystemTable\r
1932 )\r
1933{\r
1934 EFI_STATUS Status;\r
1935\r
28487361 1936 //\r
1937 // Register notify function on HII Database Protocol to add font package.\r
1938 // \r
1939 EfiCreateProtocolNotifyEvent (\r
1940 &gEfiHiiDatabaseProtocolGuid,\r
1941 TPL_CALLBACK,\r
1942 RegisterFontPackage,\r
1943 NULL,\r
1944 &mHiiRegistration\r
1945 );\r
1946\r
97a079ed
A
1947 //\r
1948 // Install driver model protocol(s).\r
1949 //\r
5bca971e 1950 Status = EfiLibInstallDriverBindingComponentName2 (\r
97a079ed
A
1951 ImageHandle,\r
1952 SystemTable,\r
1953 &gGraphicsConsoleDriverBinding,\r
1954 ImageHandle,\r
1955 &gGraphicsConsoleComponentName,\r
5bca971e 1956 &gGraphicsConsoleComponentName2\r
97a079ed
A
1957 );\r
1958 ASSERT_EFI_ERROR (Status);\r
1959\r
97a079ed
A
1960 return Status;\r
1961}\r
1962\r
d42d853e 1963\r