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