]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c
Removed SetMode in GraphicsConsole Start() in release BIOS to improve performance...
[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
d0d0c1b3 4Copyright (c) 2006 - 2012, 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
d0d0c1b3 38 -1,\r
95276127 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
95276127 562 DEBUG_CODE_BEGIN ();\r
d0d0c1b3 563 Status = GraphicsConsoleConOutSetMode (&Private->SimpleTextOutput, 0);\r
564 if (EFI_ERROR (Status)) {\r
565 goto Error;\r
566 }\r
567 Status = GraphicsConsoleConOutOutputString (&Private->SimpleTextOutput, (CHAR16 *)L"Graphics Console Started\n\r");\r
568 if (EFI_ERROR (Status)) {\r
569 goto Error;\r
570 } \r
95276127 571 DEBUG_CODE_END ();\r
572\r
573 //\r
574 // Install protocol interfaces for the Graphics Console device.\r
575 //\r
576 Status = gBS->InstallMultipleProtocolInterfaces (\r
577 &Controller,\r
578 &gEfiSimpleTextOutProtocolGuid,\r
579 &Private->SimpleTextOutput,\r
580 NULL\r
581 );\r
582\r
583Error:\r
584 if (EFI_ERROR (Status)) {\r
585 //\r
8595bdaf 586 // Close the GOP and UGA Draw Protocol\r
95276127 587 //\r
588 if (Private->GraphicsOutput != NULL) {\r
589 gBS->CloseProtocol (\r
60c65d37 590 Controller,\r
591 &gEfiGraphicsOutputProtocolGuid,\r
592 This->DriverBindingHandle,\r
593 Controller\r
594 );\r
8541adab 595 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 596 gBS->CloseProtocol (\r
60c65d37 597 Controller,\r
598 &gEfiUgaDrawProtocolGuid,\r
599 This->DriverBindingHandle,\r
600 Controller\r
601 );\r
602 }\r
603\r
604 if (Private->LineBuffer != NULL) {\r
605 FreePool (Private->LineBuffer);\r
95276127 606 }\r
607\r
79d07c66 608 if (Private->ModeData != NULL) {\r
609 FreePool (Private->ModeData);\r
610 }\r
611\r
95276127 612 //\r
613 // Free private data\r
614 //\r
60c65d37 615 FreePool (Private);\r
95276127 616 }\r
617\r
618 return Status;\r
619}\r
620\r
24248368 621/**\r
677fdb90 622 Stop this driver on Controller by removing Simple Text Out protocol\r
8595bdaf 623 and closing the Graphics Output Protocol or UGA Draw protocol on Controller.\r
878670ea 624 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)\r
677fdb90 625\r
24248368 626\r
627 @param This Protocol instance pointer.\r
8595bdaf 628 @param Controller Handle of device to stop driver on\r
24248368 629 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
630 children is zero stop the entire bus driver.\r
631 @param ChildHandleBuffer List of Child Handles to Stop.\r
632\r
8595bdaf 633 @retval EFI_SUCCESS This driver is removed Controller.\r
677fdb90 634 @retval EFI_NOT_STARTED Simple Text Out protocol could not be found the\r
8595bdaf 635 Controller.\r
24248368 636 @retval other This driver was not removed from this device.\r
637\r
638**/\r
95276127 639EFI_STATUS\r
640EFIAPI\r
641GraphicsConsoleControllerDriverStop (\r
642 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
643 IN EFI_HANDLE Controller,\r
644 IN UINTN NumberOfChildren,\r
645 IN EFI_HANDLE *ChildHandleBuffer\r
646 )\r
647{\r
648 EFI_STATUS Status;\r
649 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOutput;\r
650 GRAPHICS_CONSOLE_DEV *Private;\r
651\r
652 Status = gBS->OpenProtocol (\r
653 Controller,\r
654 &gEfiSimpleTextOutProtocolGuid,\r
655 (VOID **) &SimpleTextOutput,\r
656 This->DriverBindingHandle,\r
657 Controller,\r
658 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
659 );\r
660 if (EFI_ERROR (Status)) {\r
661 return EFI_NOT_STARTED;\r
662 }\r
663\r
664 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);\r
665\r
666 Status = gBS->UninstallProtocolInterface (\r
667 Controller,\r
668 &gEfiSimpleTextOutProtocolGuid,\r
669 &Private->SimpleTextOutput\r
670 );\r
671\r
672 if (!EFI_ERROR (Status)) {\r
673 //\r
674 // Close the GOP or UGA IO Protocol\r
675 //\r
676 if (Private->GraphicsOutput != NULL) {\r
677 gBS->CloseProtocol (\r
678 Controller,\r
679 &gEfiGraphicsOutputProtocolGuid,\r
680 This->DriverBindingHandle,\r
681 Controller\r
682 );\r
8541adab 683 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 684 gBS->CloseProtocol (\r
685 Controller,\r
686 &gEfiUgaDrawProtocolGuid,\r
687 This->DriverBindingHandle,\r
688 Controller\r
689 );\r
690 }\r
691\r
60c65d37 692 if (Private->LineBuffer != NULL) {\r
693 FreePool (Private->LineBuffer);\r
694 }\r
695\r
79d07c66 696 if (Private->ModeData != NULL) {\r
697 FreePool (Private->ModeData);\r
698 }\r
699\r
95276127 700 //\r
701 // Free our instance data\r
702 //\r
60c65d37 703 FreePool (Private);\r
95276127 704 }\r
705\r
706 return Status;\r
707}\r
708\r
24248368 709/**\r
710 Check if the current specific mode supported the user defined resolution\r
878670ea 711 for the Graphics Console device based on Graphics Output Protocol.\r
24248368 712\r
713 If yes, set the graphic devcice's current mode to this specific mode.\r
677fdb90 714\r
24248368 715 @param GraphicsOutput Graphics Output Protocol instance pointer.\r
716 @param HorizontalResolution User defined horizontal resolution\r
717 @param VerticalResolution User defined vertical resolution.\r
718 @param CurrentModeNumber Current specific mode to be check.\r
719\r
8595bdaf 720 @retval EFI_SUCCESS The mode is supported.\r
677fdb90 721 @retval EFI_UNSUPPORTED The specific mode is out of range of graphics\r
878670ea 722 device supported.\r
677fdb90 723 @retval other The specific mode does not support user defined\r
724 resolution or failed to set the current mode to the\r
24248368 725 specific mode on graphics device.\r
726\r
727**/\r
3012ce5c 728EFI_STATUS\r
729CheckModeSupported (\r
730 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
24248368 731 IN UINT32 HorizontalResolution,\r
732 IN UINT32 VerticalResolution,\r
733 OUT UINT32 *CurrentModeNumber\r
3012ce5c 734 )\r
735{\r
736 UINT32 ModeNumber;\r
737 EFI_STATUS Status;\r
8541adab 738 UINTN SizeOfInfo;\r
3012ce5c 739 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
0322ed7a 740 UINT32 MaxMode;\r
8541adab 741\r
0322ed7a 742 Status = EFI_SUCCESS;\r
743 MaxMode = GraphicsOutput->Mode->MaxMode;\r
677fdb90 744\r
0322ed7a 745 for (ModeNumber = 0; ModeNumber < MaxMode; ModeNumber++) {\r
3012ce5c 746 Status = GraphicsOutput->QueryMode (\r
747 GraphicsOutput,\r
748 ModeNumber,\r
749 &SizeOfInfo,\r
750 &Info\r
751 );\r
752 if (!EFI_ERROR (Status)) {\r
753 if ((Info->HorizontalResolution == HorizontalResolution) &&\r
754 (Info->VerticalResolution == VerticalResolution)) {\r
46f0e2a9 755 if ((GraphicsOutput->Mode->Info->HorizontalResolution == HorizontalResolution) &&\r
756 (GraphicsOutput->Mode->Info->VerticalResolution == VerticalResolution)) {\r
757 //\r
758 // If video device has been set to this mode, we do not need to SetMode again\r
759 //\r
7c9fbd79 760 FreePool (Info);\r
3012ce5c 761 break;\r
46f0e2a9 762 } else {\r
763 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);\r
764 if (!EFI_ERROR (Status)) {\r
765 FreePool (Info);\r
766 break;\r
767 }\r
3012ce5c 768 }\r
769 }\r
0322ed7a 770 FreePool (Info);\r
3012ce5c 771 }\r
772 }\r
8541adab 773\r
3012ce5c 774 if (ModeNumber == GraphicsOutput->Mode->MaxMode) {\r
775 Status = EFI_UNSUPPORTED;\r
776 }\r
8541adab 777\r
3012ce5c 778 *CurrentModeNumber = ModeNumber;\r
8541adab 779 return Status;\r
3012ce5c 780}\r
781\r
95276127 782\r
6dcf9abc 783/**\r
24248368 784 Locate HII Database protocol and HII Font protocol.\r
95276127 785\r
677fdb90 786 @retval EFI_SUCCESS HII Database protocol and HII Font protocol\r
24248368 787 are located successfully.\r
677fdb90 788 @return other Failed to locate HII Database protocol or\r
24248368 789 HII Font protocol.\r
95276127 790\r
6dcf9abc 791**/\r
792EFI_STATUS\r
793EfiLocateHiiProtocol (\r
794 VOID\r
795 )\r
95276127 796{\r
797 EFI_HANDLE Handle;\r
798 UINTN Size;\r
799 EFI_STATUS Status;\r
800\r
93e3992d 801 //\r
802 // There should only be one - so buffer size is this\r
803 //\r
804 Size = sizeof (EFI_HANDLE);\r
805\r
806 Status = gBS->LocateHandle (\r
807 ByProtocol,\r
808 &gEfiHiiDatabaseProtocolGuid,\r
809 NULL,\r
810 &Size,\r
811 (VOID **) &Handle\r
812 );\r
813\r
814 if (EFI_ERROR (Status)) {\r
815 return Status;\r
816 }\r
817\r
818 Status = gBS->HandleProtocol (\r
819 Handle,\r
820 &gEfiHiiDatabaseProtocolGuid,\r
821 (VOID **) &mHiiDatabase\r
822 );\r
823\r
824 if (EFI_ERROR (Status)) {\r
825 return Status;\r
826 }\r
827\r
828 Status = gBS->HandleProtocol (\r
829 Handle,\r
830 &gEfiHiiFontProtocolGuid,\r
831 (VOID **) &mHiiFont\r
832 );\r
833 return Status;\r
95276127 834}\r
93e3992d 835\r
95276127 836//\r
837// Body of the STO functions\r
838//\r
6dcf9abc 839\r
840/**\r
878670ea 841 Reset the text output device hardware and optionally run diagnostics.\r
677fdb90 842\r
6dcf9abc 843 Implements SIMPLE_TEXT_OUTPUT.Reset().\r
844 If ExtendeVerification is TRUE, then perform dependent Graphics Console\r
845 device reset, and set display mode to mode 0.\r
846 If ExtendedVerification is FALSE, only set display mode to mode 0.\r
847\r
24248368 848 @param This Protocol instance pointer.\r
6dcf9abc 849 @param ExtendedVerification Indicates that the driver may perform a more\r
850 exhaustive verification operation of the device\r
851 during reset.\r
852\r
24248368 853 @retval EFI_SUCCESS The text output device was reset.\r
854 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and\r
855 could not be reset.\r
6dcf9abc 856\r
857**/\r
95276127 858EFI_STATUS\r
859EFIAPI\r
860GraphicsConsoleConOutReset (\r
861 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
862 IN BOOLEAN ExtendedVerification\r
863 )\r
95276127 864{\r
d0d0c1b3 865 EFI_STATUS Status;\r
866 Status = This->SetMode (This, 0);\r
867 if (EFI_ERROR (Status)) {\r
868 return Status;\r
869 }\r
870 Status = This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
871 return Status;\r
95276127 872}\r
873\r
6dcf9abc 874\r
875/**\r
24248368 876 Write a Unicode string to the output device.\r
877\r
677fdb90 878 Implements SIMPLE_TEXT_OUTPUT.OutputString().\r
6dcf9abc 879 The Unicode string will be converted to Glyphs and will be\r
880 sent to the Graphics Console.\r
881\r
24248368 882 @param This Protocol instance pointer.\r
883 @param WString The NULL-terminated Unicode string to be displayed\r
884 on the output device(s). All output devices must\r
885 also support the Unicode drawing defined in this file.\r
6dcf9abc 886\r
24248368 887 @retval EFI_SUCCESS The string was output to the device.\r
888 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output\r
889 the text.\r
890 @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
891 defined text mode.\r
892 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
893 characters in the Unicode string could not be\r
894 rendered and were skipped.\r
6dcf9abc 895\r
896**/\r
95276127 897EFI_STATUS\r
898EFIAPI\r
899GraphicsConsoleConOutOutputString (\r
900 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
901 IN CHAR16 *WString\r
902 )\r
95276127 903{\r
904 GRAPHICS_CONSOLE_DEV *Private;\r
905 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
906 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
907 INTN Mode;\r
908 UINTN MaxColumn;\r
909 UINTN MaxRow;\r
910 UINTN Width;\r
911 UINTN Height;\r
912 UINTN Delta;\r
913 EFI_STATUS Status;\r
914 BOOLEAN Warning;\r
915 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
916 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
917 UINTN DeltaX;\r
918 UINTN DeltaY;\r
919 UINTN Count;\r
920 UINTN Index;\r
921 INT32 OriginAttribute;\r
922 EFI_TPL OldTpl;\r
95276127 923\r
d0d0c1b3 924 if (This->Mode->Mode == -1) {\r
925 //\r
926 // If current mode is not valid, return error.\r
927 //\r
928 return EFI_UNSUPPORTED;\r
929 }\r
95276127 930\r
d0d0c1b3 931 Status = EFI_SUCCESS;\r
932 \r
95276127 933 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
934 //\r
935 // Current mode\r
936 //\r
937 Mode = This->Mode->Mode;\r
938 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
939 GraphicsOutput = Private->GraphicsOutput;\r
940 UgaDraw = Private->UgaDraw;\r
941\r
942 MaxColumn = Private->ModeData[Mode].Columns;\r
943 MaxRow = Private->ModeData[Mode].Rows;\r
cd7bfc2c
ED
944 DeltaX = (UINTN) Private->ModeData[Mode].DeltaX;\r
945 DeltaY = (UINTN) Private->ModeData[Mode].DeltaY;\r
0898c57c 946 Width = MaxColumn * EFI_GLYPH_WIDTH;\r
947 Height = (MaxRow - 1) * EFI_GLYPH_HEIGHT;\r
95276127 948 Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
949\r
950 //\r
951 // The Attributes won't change when during the time OutputString is called\r
952 //\r
953 GetTextColors (This, &Foreground, &Background);\r
954\r
f44e8c16 955 FlushCursor (This);\r
95276127 956\r
957 Warning = FALSE;\r
958\r
959 //\r
960 // Backup attribute\r
961 //\r
962 OriginAttribute = This->Mode->Attribute;\r
963\r
6dcf9abc 964 while (*WString != L'\0') {\r
95276127 965\r
966 if (*WString == CHAR_BACKSPACE) {\r
967 //\r
968 // If the cursor is at the left edge of the display, then move the cursor\r
969 // one row up.\r
970 //\r
971 if (This->Mode->CursorColumn == 0 && This->Mode->CursorRow > 0) {\r
972 This->Mode->CursorRow--;\r
973 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);\r
974 This->OutputString (This, SpaceStr);\r
f44e8c16 975 FlushCursor (This);\r
95276127 976 This->Mode->CursorRow--;\r
977 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);\r
978 } else if (This->Mode->CursorColumn > 0) {\r
979 //\r
980 // If the cursor is not at the left edge of the display, then move the cursor\r
981 // left one column.\r
982 //\r
983 This->Mode->CursorColumn--;\r
984 This->OutputString (This, SpaceStr);\r
f44e8c16 985 FlushCursor (This);\r
95276127 986 This->Mode->CursorColumn--;\r
987 }\r
988\r
989 WString++;\r
990\r
991 } else if (*WString == CHAR_LINEFEED) {\r
992 //\r
993 // If the cursor is at the bottom of the display, then scroll the display one\r
994 // row, and do not update the cursor position. Otherwise, move the cursor\r
995 // down one row.\r
996 //\r
997 if (This->Mode->CursorRow == (INT32) (MaxRow - 1)) {\r
998 if (GraphicsOutput != NULL) {\r
999 //\r
1000 // Scroll Screen Up One Row\r
1001 //\r
1002 GraphicsOutput->Blt (\r
1003 GraphicsOutput,\r
1004 NULL,\r
1005 EfiBltVideoToVideo,\r
1006 DeltaX,\r
0898c57c 1007 DeltaY + EFI_GLYPH_HEIGHT,\r
95276127 1008 DeltaX,\r
1009 DeltaY,\r
1010 Width,\r
1011 Height,\r
1012 Delta\r
1013 );\r
1014\r
1015 //\r
1016 // Print Blank Line at last line\r
1017 //\r
1018 GraphicsOutput->Blt (\r
1019 GraphicsOutput,\r
1020 &Background,\r
1021 EfiBltVideoFill,\r
1022 0,\r
1023 0,\r
1024 DeltaX,\r
1025 DeltaY + Height,\r
1026 Width,\r
0898c57c 1027 EFI_GLYPH_HEIGHT,\r
95276127 1028 Delta\r
1029 );\r
8541adab 1030 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1031 //\r
1032 // Scroll Screen Up One Row\r
1033 //\r
1034 UgaDraw->Blt (\r
1035 UgaDraw,\r
1036 NULL,\r
1037 EfiUgaVideoToVideo,\r
1038 DeltaX,\r
0898c57c 1039 DeltaY + EFI_GLYPH_HEIGHT,\r
95276127 1040 DeltaX,\r
1041 DeltaY,\r
1042 Width,\r
1043 Height,\r
1044 Delta\r
1045 );\r
1046\r
1047 //\r
1048 // Print Blank Line at last line\r
1049 //\r
1050 UgaDraw->Blt (\r
1051 UgaDraw,\r
1052 (EFI_UGA_PIXEL *) (UINTN) &Background,\r
1053 EfiUgaVideoFill,\r
1054 0,\r
1055 0,\r
1056 DeltaX,\r
1057 DeltaY + Height,\r
1058 Width,\r
0898c57c 1059 EFI_GLYPH_HEIGHT,\r
95276127 1060 Delta\r
1061 );\r
1062 }\r
1063 } else {\r
1064 This->Mode->CursorRow++;\r
1065 }\r
1066\r
1067 WString++;\r
1068\r
1069 } else if (*WString == CHAR_CARRIAGE_RETURN) {\r
1070 //\r
1071 // Move the cursor to the beginning of the current row.\r
1072 //\r
1073 This->Mode->CursorColumn = 0;\r
1074 WString++;\r
1075\r
1076 } else if (*WString == WIDE_CHAR) {\r
1077\r
1078 This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;\r
1079 WString++;\r
1080\r
1081 } else if (*WString == NARROW_CHAR) {\r
1082\r
1083 This->Mode->Attribute &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);\r
1084 WString++;\r
1085\r
1086 } else {\r
1087 //\r
1088 // Print the character at the current cursor position and move the cursor\r
1089 // right one column. If this moves the cursor past the right edge of the\r
1090 // display, then the line should wrap to the beginning of the next line. This\r
1091 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the\r
1092 // bottom of the display, and the line wraps, then the display will be scrolled\r
1093 // one line.\r
1094 // If wide char is going to be displayed, need to display one character at a time\r
1095 // Or, need to know the display length of a certain string.\r
1096 //\r
1097 // Index is used to determine how many character width units (wide = 2, narrow = 1)\r
1098 // Count is used to determine how many characters are used regardless of their attributes\r
1099 //\r
1100 for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {\r
677fdb90 1101 if (WString[Count] == CHAR_NULL ||\r
1102 WString[Count] == CHAR_BACKSPACE ||\r
878670ea 1103 WString[Count] == CHAR_LINEFEED ||\r
1104 WString[Count] == CHAR_CARRIAGE_RETURN ||\r
1105 WString[Count] == WIDE_CHAR ||\r
1106 WString[Count] == NARROW_CHAR) {\r
95276127 1107 break;\r
1108 }\r
1109 //\r
1110 // Is the wide attribute on?\r
1111 //\r
677fdb90 1112 if ((This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) != 0) {\r
95276127 1113 //\r
1114 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop\r
1115 //\r
1116 Index++;\r
1117 //\r
1118 // This is the end-case where if we are at column 79 and about to print a wide character\r
1119 // We should prevent this from happening because we will wrap inappropriately. We should\r
1120 // not print this character until the next line.\r
1121 //\r
1122 if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {\r
1123 Index++;\r
1124 break;\r
1125 }\r
1126 }\r
1127 }\r
1128\r
1129 Status = DrawUnicodeWeightAtCursorN (This, WString, Count);\r
1130 if (EFI_ERROR (Status)) {\r
1131 Warning = TRUE;\r
1132 }\r
1133 //\r
1134 // At the end of line, output carriage return and line feed\r
1135 //\r
1136 WString += Count;\r
1137 This->Mode->CursorColumn += (INT32) Index;\r
1138 if (This->Mode->CursorColumn > (INT32) MaxColumn) {\r
1139 This->Mode->CursorColumn -= 2;\r
1140 This->OutputString (This, SpaceStr);\r
1141 }\r
1142\r
1143 if (This->Mode->CursorColumn >= (INT32) MaxColumn) {\r
f44e8c16 1144 FlushCursor (This);\r
95276127 1145 This->OutputString (This, mCrLfString);\r
f44e8c16 1146 FlushCursor (This);\r
95276127 1147 }\r
1148 }\r
1149 }\r
1150\r
1151 This->Mode->Attribute = OriginAttribute;\r
1152\r
f44e8c16 1153 FlushCursor (This);\r
95276127 1154\r
1155 if (Warning) {\r
1156 Status = EFI_WARN_UNKNOWN_GLYPH;\r
1157 }\r
1158\r
1159 gBS->RestoreTPL (OldTpl);\r
1160 return Status;\r
1161\r
1162}\r
1163\r
6dcf9abc 1164/**\r
677fdb90 1165 Verifies that all characters in a Unicode string can be output to the\r
24248368 1166 target device.\r
6dcf9abc 1167\r
5c03ed0a 1168 Implements SIMPLE_TEXT_OUTPUT.TestString().\r
24248368 1169 If one of the characters in the *Wstring is neither valid valid Unicode\r
1170 drawing characters, not ASCII code, then this function will return\r
1171 EFI_UNSUPPORTED\r
1172\r
1173 @param This Protocol instance pointer.\r
1174 @param WString The NULL-terminated Unicode string to be examined for the output\r
1175 device(s).\r
6dcf9abc 1176\r
24248368 1177 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.\r
1178 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be\r
1179 rendered by one or more of the output devices mapped\r
1180 by the EFI handle.\r
6dcf9abc 1181\r
1182**/\r
95276127 1183EFI_STATUS\r
1184EFIAPI\r
1185GraphicsConsoleConOutTestString (\r
1186 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1187 IN CHAR16 *WString\r
1188 )\r
95276127 1189{\r
1190 EFI_STATUS Status;\r
95276127 1191 UINT16 Count;\r
95276127 1192\r
6dcf9abc 1193 EFI_IMAGE_OUTPUT *Blt;\r
93e3992d 1194\r
6dcf9abc 1195 Blt = NULL;\r
93e3992d 1196 Count = 0;\r
1197\r
1198 while (WString[Count] != 0) {\r
93e3992d 1199 Status = mHiiFont->GetGlyph (\r
1200 mHiiFont,\r
1201 WString[Count],\r
1202 NULL,\r
1203 &Blt,\r
1204 NULL\r
1205 );\r
676df92c 1206 if (Blt != NULL) {\r
1207 FreePool (Blt);\r
1208 Blt = NULL;\r
1209 }\r
93e3992d 1210 Count++;\r
d42d853e 1211\r
95276127 1212 if (EFI_ERROR (Status)) {\r
1213 return EFI_UNSUPPORTED;\r
1214 }\r
1215 }\r
1216\r
1217 return EFI_SUCCESS;\r
1218}\r
1219\r
6dcf9abc 1220\r
1221/**\r
24248368 1222 Returns information for an available text mode that the output device(s)\r
1223 supports\r
1224\r
6dcf9abc 1225 Implements SIMPLE_TEXT_OUTPUT.QueryMode().\r
24248368 1226 It returnes information for an available text mode that the Graphics Console supports.\r
1227 In this driver,we only support text mode 80x25, which is defined as mode 0.\r
6dcf9abc 1228\r
24248368 1229 @param This Protocol instance pointer.\r
6dcf9abc 1230 @param ModeNumber The mode number to return information on.\r
1231 @param Columns The returned columns of the requested mode.\r
1232 @param Rows The returned rows of the requested mode.\r
1233\r
24248368 1234 @retval EFI_SUCCESS The requested mode information is returned.\r
1235 @retval EFI_UNSUPPORTED The mode number is not valid.\r
6dcf9abc 1236\r
1237**/\r
95276127 1238EFI_STATUS\r
1239EFIAPI\r
1240GraphicsConsoleConOutQueryMode (\r
1241 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1242 IN UINTN ModeNumber,\r
1243 OUT UINTN *Columns,\r
1244 OUT UINTN *Rows\r
1245 )\r
95276127 1246{\r
1247 GRAPHICS_CONSOLE_DEV *Private;\r
1248 EFI_STATUS Status;\r
1249 EFI_TPL OldTpl;\r
8541adab 1250\r
95276127 1251 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {\r
1252 return EFI_UNSUPPORTED;\r
1253 }\r
1254\r
1255 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1256 Status = EFI_SUCCESS;\r
8541adab 1257\r
95276127 1258 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1259\r
1260 *Columns = Private->ModeData[ModeNumber].Columns;\r
1261 *Rows = Private->ModeData[ModeNumber].Rows;\r
1262\r
79d07c66 1263 if (*Columns <= 0 || *Rows <= 0) {\r
95276127 1264 Status = EFI_UNSUPPORTED;\r
1265 goto Done;\r
1266\r
1267 }\r
1268\r
1269Done:\r
1270 gBS->RestoreTPL (OldTpl);\r
1271 return Status;\r
1272}\r
1273\r
6dcf9abc 1274\r
1275/**\r
24248368 1276 Sets the output device(s) to a specified mode.\r
677fdb90 1277\r
6dcf9abc 1278 Implements SIMPLE_TEXT_OUTPUT.SetMode().\r
24248368 1279 Set the Graphics Console to a specified mode. In this driver, we only support mode 0.\r
6dcf9abc 1280\r
24248368 1281 @param This Protocol instance pointer.\r
6dcf9abc 1282 @param ModeNumber The text mode to set.\r
1283\r
24248368 1284 @retval EFI_SUCCESS The requested text mode is set.\r
677fdb90 1285 @retval EFI_DEVICE_ERROR The requested text mode cannot be set because of\r
24248368 1286 Graphics Console device error.\r
1287 @retval EFI_UNSUPPORTED The text mode number is not valid.\r
6dcf9abc 1288\r
1289**/\r
95276127 1290EFI_STATUS\r
1291EFIAPI\r
1292GraphicsConsoleConOutSetMode (\r
1293 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1294 IN UINTN ModeNumber\r
1295 )\r
95276127 1296{\r
1297 EFI_STATUS Status;\r
1298 GRAPHICS_CONSOLE_DEV *Private;\r
1299 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1300 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewLineBuffer;\r
1301 UINT32 HorizontalResolution;\r
1302 UINT32 VerticalResolution;\r
1303 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1304 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1305 UINT32 ColorDepth;\r
1306 UINT32 RefreshRate;\r
1307 EFI_TPL OldTpl;\r
1308\r
1309 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1310\r
1311 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1312 GraphicsOutput = Private->GraphicsOutput;\r
1313 UgaDraw = Private->UgaDraw;\r
95276127 1314\r
95276127 1315 //\r
1316 // Make sure the requested mode number is supported\r
1317 //\r
1318 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {\r
1319 Status = EFI_UNSUPPORTED;\r
1320 goto Done;\r
1321 }\r
d0d0c1b3 1322 \r
1323 ModeData = &(Private->ModeData[ModeNumber]);\r
95276127 1324\r
1325 if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {\r
1326 Status = EFI_UNSUPPORTED;\r
1327 goto Done;\r
1328 }\r
95276127 1329\r
95276127 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
95276127 1334 //\r
1335 // If the new mode is the same as the old mode, then just return EFI_SUCCESS\r
1336 //\r
1337 if ((INT32) ModeNumber == This->Mode->Mode) {\r
d0d0c1b3 1338 //\r
1339 // Clear the current text window on the current graphics console\r
1340 //\r
1341 This->ClearScreen (This);\r
95276127 1342 Status = EFI_SUCCESS;\r
1343 goto Done;\r
1344 }\r
1345 //\r
7347d5d6 1346 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,\r
1347 // so erase the cursor, and free the LineBuffer for the current mode\r
95276127 1348 //\r
f44e8c16 1349 FlushCursor (This);\r
95276127 1350\r
1351 FreePool (Private->LineBuffer);\r
1352 }\r
d0d0c1b3 1353\r
1354 //\r
1355 // Attempt to allocate a line buffer for the requested mode number\r
1356 //\r
1357 NewLineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT);\r
1358\r
1359 if (NewLineBuffer == NULL) {\r
1360 //\r
1361 // The new line buffer could not be allocated, so return an error.\r
1362 // No changes to the state of the current console have been made, so the current console is still valid\r
1363 //\r
1364 Status = EFI_OUT_OF_RESOURCES;\r
1365 goto Done;\r
1366 }\r
1367\r
95276127 1368 //\r
1369 // Assign the current line buffer to the newly allocated line buffer\r
1370 //\r
1371 Private->LineBuffer = NewLineBuffer;\r
1372\r
1373 if (GraphicsOutput != NULL) {\r
1374 if (ModeData->GopModeNumber != GraphicsOutput->Mode->Mode) {\r
1375 //\r
878670ea 1376 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode\r
95276127 1377 //\r
1378 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeData->GopModeNumber);\r
1379 if (EFI_ERROR (Status)) {\r
1380 //\r
1381 // The mode set operation failed\r
1382 //\r
1383 goto Done;\r
1384 }\r
1385 } else {\r
1386 //\r
1387 // The current graphics mode is correct, so simply clear the entire display\r
1388 //\r
1389 Status = GraphicsOutput->Blt (\r
1390 GraphicsOutput,\r
f618b2fa 1391 &mGraphicsEfiColors[0],\r
95276127 1392 EfiBltVideoFill,\r
1393 0,\r
1394 0,\r
1395 0,\r
1396 0,\r
1397 ModeData->GopWidth,\r
1398 ModeData->GopHeight,\r
1399 0\r
1400 );\r
1401 }\r
8541adab 1402 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1403 //\r
1404 // Get the current UGA Draw mode information\r
1405 //\r
1406 Status = UgaDraw->GetMode (\r
1407 UgaDraw,\r
1408 &HorizontalResolution,\r
1409 &VerticalResolution,\r
1410 &ColorDepth,\r
1411 &RefreshRate\r
1412 );\r
1413 if (EFI_ERROR (Status) || HorizontalResolution != ModeData->GopWidth || VerticalResolution != ModeData->GopHeight) {\r
1414 //\r
878670ea 1415 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode\r
95276127 1416 //\r
1417 Status = UgaDraw->SetMode (\r
1418 UgaDraw,\r
1419 ModeData->GopWidth,\r
1420 ModeData->GopHeight,\r
1421 32,\r
1422 60\r
1423 );\r
1424 if (EFI_ERROR (Status)) {\r
1425 //\r
1426 // The mode set operation failed\r
1427 //\r
1428 goto Done;\r
1429 }\r
1430 } else {\r
1431 //\r
1432 // The current graphics mode is correct, so simply clear the entire display\r
1433 //\r
1434 Status = UgaDraw->Blt (\r
1435 UgaDraw,\r
f618b2fa 1436 (EFI_UGA_PIXEL *) (UINTN) &mGraphicsEfiColors[0],\r
95276127 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
1446 }\r
1447 }\r
1448\r
1449 //\r
1450 // The new mode is valid, so commit the mode change\r
1451 //\r
1452 This->Mode->Mode = (INT32) ModeNumber;\r
1453\r
1454 //\r
f44e8c16 1455 // Move the text cursor to the upper left hand corner of the display and flush it\r
95276127 1456 //\r
f44e8c16 1457 This->Mode->CursorColumn = 0;\r
1458 This->Mode->CursorRow = 0;\r
1459\r
1460 FlushCursor (This); \r
95276127 1461\r
1462 Status = EFI_SUCCESS;\r
1463\r
1464Done:\r
1465 gBS->RestoreTPL (OldTpl);\r
1466 return Status;\r
1467}\r
1468\r
6dcf9abc 1469\r
1470/**\r
24248368 1471 Sets the background and foreground colors for the OutputString () and\r
1472 ClearScreen () functions.\r
1473\r
6dcf9abc 1474 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().\r
1475\r
24248368 1476 @param This Protocol instance pointer.\r
1477 @param Attribute The attribute to set. Bits 0..3 are the foreground\r
677fdb90 1478 color, and bits 4..6 are the background color.\r
24248368 1479 All other bits are undefined and must be zero.\r
6dcf9abc 1480\r
24248368 1481 @retval EFI_SUCCESS The requested attribute is set.\r
1482 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to Graphics Console port error.\r
1483 @retval EFI_UNSUPPORTED The attribute requested is not defined.\r
6dcf9abc 1484\r
1485**/\r
95276127 1486EFI_STATUS\r
1487EFIAPI\r
1488GraphicsConsoleConOutSetAttribute (\r
1489 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1490 IN UINTN Attribute\r
1491 )\r
95276127 1492{\r
1493 EFI_TPL OldTpl;\r
8541adab 1494\r
95276127 1495 if ((Attribute | 0xFF) != 0xFF) {\r
1496 return EFI_UNSUPPORTED;\r
1497 }\r
1498\r
d0d0c1b3 1499 if (This->Mode->Mode == -1) {\r
1500 //\r
1501 // If current mode is not valid, return error.\r
1502 //\r
1503 return EFI_UNSUPPORTED;\r
1504 }\r
1505\r
95276127 1506 if ((INT32) Attribute == This->Mode->Attribute) {\r
1507 return EFI_SUCCESS;\r
1508 }\r
1509\r
1510 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1511\r
f44e8c16 1512 FlushCursor (This);\r
95276127 1513\r
1514 This->Mode->Attribute = (INT32) Attribute;\r
1515\r
f44e8c16 1516 FlushCursor (This);\r
95276127 1517\r
1518 gBS->RestoreTPL (OldTpl);\r
1519\r
1520 return EFI_SUCCESS;\r
1521}\r
1522\r
6dcf9abc 1523\r
1524/**\r
677fdb90 1525 Clears the output device(s) display to the currently selected background\r
24248368 1526 color.\r
1527\r
6dcf9abc 1528 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().\r
6dcf9abc 1529\r
24248368 1530 @param This Protocol instance pointer.\r
6dcf9abc 1531\r
24248368 1532 @retval EFI_SUCCESS The operation completed successfully.\r
1533 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.\r
1534 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.\r
6dcf9abc 1535\r
1536**/\r
95276127 1537EFI_STATUS\r
1538EFIAPI\r
1539GraphicsConsoleConOutClearScreen (\r
1540 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
1541 )\r
95276127 1542{\r
1543 EFI_STATUS Status;\r
1544 GRAPHICS_CONSOLE_DEV *Private;\r
1545 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1546 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1547 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1548 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
1549 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
1550 EFI_TPL OldTpl;\r
d0d0c1b3 1551 \r
1552 if (This->Mode->Mode == -1) {\r
1553 //\r
1554 // If current mode is not valid, return error.\r
1555 //\r
1556 return EFI_UNSUPPORTED;\r
1557 }\r
95276127 1558\r
1559 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1560\r
1561 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1562 GraphicsOutput = Private->GraphicsOutput;\r
1563 UgaDraw = Private->UgaDraw;\r
1564 ModeData = &(Private->ModeData[This->Mode->Mode]);\r
1565\r
1566 GetTextColors (This, &Foreground, &Background);\r
1567 if (GraphicsOutput != NULL) {\r
1568 Status = GraphicsOutput->Blt (\r
1569 GraphicsOutput,\r
1570 &Background,\r
1571 EfiBltVideoFill,\r
1572 0,\r
1573 0,\r
1574 0,\r
1575 0,\r
1576 ModeData->GopWidth,\r
1577 ModeData->GopHeight,\r
1578 0\r
1579 );\r
8541adab 1580 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1581 Status = UgaDraw->Blt (\r
1582 UgaDraw,\r
1583 (EFI_UGA_PIXEL *) (UINTN) &Background,\r
1584 EfiUgaVideoFill,\r
1585 0,\r
1586 0,\r
1587 0,\r
1588 0,\r
1589 ModeData->GopWidth,\r
1590 ModeData->GopHeight,\r
1591 0\r
1592 );\r
8541adab 1593 } else {\r
1594 Status = EFI_UNSUPPORTED;\r
95276127 1595 }\r
1596\r
1597 This->Mode->CursorColumn = 0;\r
1598 This->Mode->CursorRow = 0;\r
1599\r
f44e8c16 1600 FlushCursor (This);\r
95276127 1601\r
1602 gBS->RestoreTPL (OldTpl);\r
1603\r
1604 return Status;\r
1605}\r
1606\r
6dcf9abc 1607\r
1608/**\r
24248368 1609 Sets the current coordinates of the cursor position.\r
1610\r
6dcf9abc 1611 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().\r
1612\r
24248368 1613 @param This Protocol instance pointer.\r
1614 @param Column The position to set the cursor to. Must be greater than or\r
1615 equal to zero and less than the number of columns and rows\r
1616 by QueryMode ().\r
1617 @param Row The position to set the cursor to. Must be greater than or\r
1618 equal to zero and less than the number of columns and rows\r
1619 by QueryMode ().\r
6dcf9abc 1620\r
24248368 1621 @retval EFI_SUCCESS The operation completed successfully.\r
1622 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.\r
1623 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the\r
1624 cursor position is invalid for the current mode.\r
6dcf9abc 1625\r
1626**/\r
95276127 1627EFI_STATUS\r
1628EFIAPI\r
1629GraphicsConsoleConOutSetCursorPosition (\r
1630 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1631 IN UINTN Column,\r
1632 IN UINTN Row\r
1633 )\r
95276127 1634{\r
1635 GRAPHICS_CONSOLE_DEV *Private;\r
1636 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1637 EFI_STATUS Status;\r
1638 EFI_TPL OldTpl;\r
1639\r
d0d0c1b3 1640 if (This->Mode->Mode == -1) {\r
1641 //\r
1642 // If current mode is not valid, return error.\r
1643 //\r
1644 return EFI_UNSUPPORTED;\r
1645 }\r
1646\r
95276127 1647 Status = EFI_SUCCESS;\r
1648\r
1649 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1650\r
1651 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1652 ModeData = &(Private->ModeData[This->Mode->Mode]);\r
1653\r
1654 if ((Column >= ModeData->Columns) || (Row >= ModeData->Rows)) {\r
1655 Status = EFI_UNSUPPORTED;\r
1656 goto Done;\r
1657 }\r
1658\r
8595bdaf 1659 if ((This->Mode->CursorColumn == (INT32) Column) && (This->Mode->CursorRow == (INT32) Row)) {\r
95276127 1660 Status = EFI_SUCCESS;\r
1661 goto Done;\r
1662 }\r
1663\r
f44e8c16 1664 FlushCursor (This);\r
95276127 1665\r
1666 This->Mode->CursorColumn = (INT32) Column;\r
1667 This->Mode->CursorRow = (INT32) Row;\r
1668\r
f44e8c16 1669 FlushCursor (This);\r
95276127 1670\r
1671Done:\r
1672 gBS->RestoreTPL (OldTpl);\r
1673\r
1674 return Status;\r
1675}\r
1676\r
6dcf9abc 1677\r
1678/**\r
24248368 1679 Makes the cursor visible or invisible.\r
1680\r
6dcf9abc 1681 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().\r
6dcf9abc 1682\r
24248368 1683 @param This Protocol instance pointer.\r
6dcf9abc 1684 @param Visible If TRUE, the cursor is set to be visible, If FALSE,\r
1685 the cursor is set to be invisible.\r
1686\r
24248368 1687 @retval EFI_SUCCESS The operation completed successfully.\r
d0d0c1b3 1688 @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
1689 defined text mode.\r
6dcf9abc 1690\r
1691**/\r
95276127 1692EFI_STATUS\r
1693EFIAPI\r
1694GraphicsConsoleConOutEnableCursor (\r
1695 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1696 IN BOOLEAN Visible\r
1697 )\r
95276127 1698{\r
1699 EFI_TPL OldTpl;\r
8541adab 1700\r
d0d0c1b3 1701 if (This->Mode->Mode == -1) {\r
1702 //\r
1703 // If current mode is not valid, return error.\r
1704 //\r
1705 return EFI_UNSUPPORTED;\r
1706 }\r
1707\r
95276127 1708 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
8541adab 1709\r
f44e8c16 1710 FlushCursor (This);\r
95276127 1711\r
1712 This->Mode->CursorVisible = Visible;\r
1713\r
f44e8c16 1714 FlushCursor (This);\r
95276127 1715\r
1716 gBS->RestoreTPL (OldTpl);\r
1717 return EFI_SUCCESS;\r
1718}\r
1719\r
24248368 1720/**\r
1721 Gets Graphics Console devcie's foreground color and background color.\r
1722\r
1723 @param This Protocol instance pointer.\r
1724 @param Foreground Returned text foreground color.\r
1725 @param Background Returned text background color.\r
1726\r
1727 @retval EFI_SUCCESS It returned always.\r
1728\r
1729**/\r
95276127 1730EFI_STATUS\r
1731GetTextColors (\r
1732 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1733 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
1734 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background\r
1735 )\r
1736{\r
1737 INTN Attribute;\r
1738\r
1739 Attribute = This->Mode->Attribute & 0x7F;\r
1740\r
f618b2fa 1741 *Foreground = mGraphicsEfiColors[Attribute & 0x0f];\r
1742 *Background = mGraphicsEfiColors[Attribute >> 4];\r
95276127 1743\r
1744 return EFI_SUCCESS;\r
1745}\r
1746\r
24248368 1747/**\r
878670ea 1748 Draw Unicode string on the Graphics Console device's screen.\r
24248368 1749\r
1750 @param This Protocol instance pointer.\r
1751 @param UnicodeWeight One Unicode string to be displayed.\r
1752 @param Count The count of Unicode string.\r
1753\r
1754 @retval EFI_OUT_OF_RESOURCES If no memory resource to use.\r
1755 @retval EFI_UNSUPPORTED If no Graphics Output protocol and UGA Draw\r
1756 protocol exist.\r
1757 @retval EFI_SUCCESS Drawing Unicode string implemented successfully.\r
1758\r
1759**/\r
93e3992d 1760EFI_STATUS\r
1761DrawUnicodeWeightAtCursorN (\r
1762 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
24248368 1763 IN CHAR16 *UnicodeWeight,\r
1764 IN UINTN Count\r
93e3992d 1765 )\r
1766{\r
1767 EFI_STATUS Status;\r
1768 GRAPHICS_CONSOLE_DEV *Private;\r
1769 EFI_IMAGE_OUTPUT *Blt;\r
1770 EFI_STRING String;\r
1771 EFI_FONT_DISPLAY_INFO *FontInfo;\r
d42d853e 1772 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1773 EFI_HII_ROW_INFO *RowInfoArray;\r
1774 UINTN RowInfoArraySize;\r
93e3992d 1775\r
1776 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
93e3992d 1777 Blt = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
1778 if (Blt == NULL) {\r
1779 return EFI_OUT_OF_RESOURCES;\r
1780 }\r
1781\r
1782 Blt->Width = (UINT16) (Private->ModeData[This->Mode->Mode].GopWidth);\r
1783 Blt->Height = (UINT16) (Private->ModeData[This->Mode->Mode].GopHeight);\r
93e3992d 1784\r
1785 String = AllocateCopyPool ((Count + 1) * sizeof (CHAR16), UnicodeWeight);\r
1786 if (String == NULL) {\r
676df92c 1787 FreePool (Blt);\r
93e3992d 1788 return EFI_OUT_OF_RESOURCES;\r
1789 }\r
8595bdaf 1790 //\r
1791 // Set the end character\r
1792 //\r
1793 *(String + Count) = L'\0';\r
93e3992d 1794\r
1795 FontInfo = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));\r
1796 if (FontInfo == NULL) {\r
676df92c 1797 FreePool (Blt);\r
1798 FreePool (String);\r
93e3992d 1799 return EFI_OUT_OF_RESOURCES;\r
1800 }\r
8595bdaf 1801 //\r
1802 // Get current foreground and background colors.\r
1803 //\r
93e3992d 1804 GetTextColors (This, &FontInfo->ForegroundColor, &FontInfo->BackgroundColor);\r
1805\r
d42d853e 1806 if (Private->GraphicsOutput != NULL) {\r
8595bdaf 1807 //\r
677fdb90 1808 // If Graphics Output protocol exists, using HII Font protocol to draw.\r
8595bdaf 1809 //\r
d42d853e 1810 Blt->Image.Screen = Private->GraphicsOutput;\r
95276127 1811\r
d42d853e 1812 Status = mHiiFont->StringToImage (\r
1813 mHiiFont,\r
5e0b1e3f 1814 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN | EFI_HII_IGNORE_LINE_BREAK,\r
d42d853e 1815 String,\r
1816 FontInfo,\r
1817 &Blt,\r
0898c57c 1818 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1819 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
d42d853e 1820 NULL,\r
1821 NULL,\r
1822 NULL\r
1823 );\r
95276127 1824\r
8541adab 1825 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
8595bdaf 1826 //\r
677fdb90 1827 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,\r
8595bdaf 1828 // using UGA Draw protocol to draw.\r
1829 //\r
d42d853e 1830 ASSERT (Private->UgaDraw!= NULL);\r
95276127 1831\r
d42d853e 1832 UgaDraw = Private->UgaDraw;\r
95276127 1833\r
d42d853e 1834 Blt->Image.Bitmap = AllocateZeroPool (Blt->Width * Blt->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
1835 if (Blt->Image.Bitmap == NULL) {\r
676df92c 1836 FreePool (Blt);\r
1837 FreePool (String);\r
d42d853e 1838 return EFI_OUT_OF_RESOURCES;\r
95276127 1839 }\r
1840\r
d42d853e 1841 RowInfoArray = NULL;\r
1842 //\r
1843 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,\r
1844 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.\r
1845 //\r
1846 Status = mHiiFont->StringToImage (\r
1847 mHiiFont,\r
5e0b1e3f 1848 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK,\r
d42d853e 1849 String,\r
1850 FontInfo,\r
1851 &Blt,\r
0898c57c 1852 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1853 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
d42d853e 1854 &RowInfoArray,\r
1855 &RowInfoArraySize,\r
1856 NULL\r
1857 );\r
95276127 1858\r
d42d853e 1859 if (!EFI_ERROR (Status)) {\r
95276127 1860 //\r
d42d853e 1861 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will\r
bd1d34ee 1862 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.\r
95276127 1863 //\r
bd1d34ee 1864 ASSERT (RowInfoArraySize <= 1);\r
8541adab 1865\r
d42d853e 1866 Status = UgaDraw->Blt (\r
1867 UgaDraw,\r
1868 (EFI_UGA_PIXEL *) Blt->Image.Bitmap,\r
1869 EfiUgaBltBufferToVideo,\r
0898c57c 1870 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1871 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
1872 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1873 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
d42d853e 1874 RowInfoArray[0].LineWidth,\r
1875 RowInfoArray[0].LineHeight,\r
1876 Blt->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1877 );\r
1878 }\r
95276127 1879\r
676df92c 1880 FreePool (RowInfoArray);\r
1881 FreePool (Blt->Image.Bitmap);\r
8541adab 1882 } else {\r
1883 Status = EFI_UNSUPPORTED;\r
95276127 1884 }\r
1885\r
676df92c 1886 if (Blt != NULL) {\r
1887 FreePool (Blt);\r
1888 }\r
1889 if (String != NULL) {\r
1890 FreePool (String);\r
1891 }\r
1892 if (FontInfo != NULL) {\r
1893 FreePool (FontInfo);\r
1894 }\r
d42d853e 1895 return Status;\r
95276127 1896}\r
d42d853e 1897\r
24248368 1898/**\r
f44e8c16 1899 Flush the cursor on the screen.\r
1900 \r
1901 If CursorVisible is FALSE, nothing to do and return directly.\r
1902 If CursorVisible is TRUE, \r
1903 i) If the cursor shows on screen, it will be erased.\r
1904 ii) If the cursor does not show on screen, it will be shown. \r
95276127 1905\r
24248368 1906 @param This Protocol instance pointer.\r
1907\r
1908 @retval EFI_SUCCESS The cursor is erased successfully.\r
1909\r
1910**/\r
95276127 1911EFI_STATUS\r
f44e8c16 1912FlushCursor (\r
95276127 1913 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
1914 )\r
1915{\r
7601dbe7 1916 GRAPHICS_CONSOLE_DEV *Private;\r
1917 EFI_SIMPLE_TEXT_OUTPUT_MODE *CurrentMode;\r
1918 INTN GlyphX;\r
1919 INTN GlyphY;\r
95276127 1920 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
7601dbe7 1921 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
95276127 1922 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground;\r
1923 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background;\r
0898c57c 1924 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar[EFI_GLYPH_HEIGHT][EFI_GLYPH_WIDTH];\r
7601dbe7 1925 UINTN PosX;\r
1926 UINTN PosY;\r
95276127 1927\r
1928 CurrentMode = This->Mode;\r
1929\r
1930 if (!CurrentMode->CursorVisible) {\r
1931 return EFI_SUCCESS;\r
1932 }\r
1933\r
1934 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1935 GraphicsOutput = Private->GraphicsOutput;\r
1936 UgaDraw = Private->UgaDraw;\r
1937\r
1938 //\r
24248368 1939 // In this driver, only narrow character was supported.\r
95276127 1940 //\r
1941 //\r
1942 // Blt a character to the screen\r
1943 //\r
0898c57c 1944 GlyphX = (CurrentMode->CursorColumn * EFI_GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;\r
1945 GlyphY = (CurrentMode->CursorRow * EFI_GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;\r
95276127 1946 if (GraphicsOutput != NULL) {\r
1947 GraphicsOutput->Blt (\r
1948 GraphicsOutput,\r
1949 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,\r
1950 EfiBltVideoToBltBuffer,\r
1951 GlyphX,\r
1952 GlyphY,\r
1953 0,\r
1954 0,\r
0898c57c 1955 EFI_GLYPH_WIDTH,\r
1956 EFI_GLYPH_HEIGHT,\r
1957 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
95276127 1958 );\r
8541adab 1959 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1960 UgaDraw->Blt (\r
1961 UgaDraw,\r
1962 (EFI_UGA_PIXEL *) (UINTN) BltChar,\r
1963 EfiUgaVideoToBltBuffer,\r
1964 GlyphX,\r
1965 GlyphY,\r
1966 0,\r
1967 0,\r
0898c57c 1968 EFI_GLYPH_WIDTH,\r
1969 EFI_GLYPH_HEIGHT,\r
1970 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
95276127 1971 );\r
1972 }\r
1973\r
1974 GetTextColors (This, &Foreground.Pixel, &Background.Pixel);\r
1975\r
1976 //\r
1977 // Convert Monochrome bitmap of the Glyph to BltBuffer structure\r
1978 //\r
6dcf9abc 1979 for (PosY = 0; PosY < EFI_GLYPH_HEIGHT; PosY++) {\r
1980 for (PosX = 0; PosX < EFI_GLYPH_WIDTH; PosX++) {\r
878670ea 1981 if ((mCursorGlyph.GlyphCol1[PosY] & (BIT0 << PosX)) != 0) {\r
6dcf9abc 1982 BltChar[PosY][EFI_GLYPH_WIDTH - PosX - 1].Raw ^= Foreground.Raw;\r
95276127 1983 }\r
1984 }\r
1985 }\r
1986\r
1987 if (GraphicsOutput != NULL) {\r
1988 GraphicsOutput->Blt (\r
1989 GraphicsOutput,\r
1990 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,\r
1991 EfiBltBufferToVideo,\r
1992 0,\r
1993 0,\r
1994 GlyphX,\r
1995 GlyphY,\r
0898c57c 1996 EFI_GLYPH_WIDTH,\r
1997 EFI_GLYPH_HEIGHT,\r
1998 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
95276127 1999 );\r
8541adab 2000 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 2001 UgaDraw->Blt (\r
2002 UgaDraw,\r
2003 (EFI_UGA_PIXEL *) (UINTN) BltChar,\r
2004 EfiUgaBltBufferToVideo,\r
2005 0,\r
2006 0,\r
2007 GlyphX,\r
2008 GlyphY,\r
0898c57c 2009 EFI_GLYPH_WIDTH,\r
2010 EFI_GLYPH_HEIGHT,\r
2011 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
95276127 2012 );\r
2013 }\r
2014\r
2015 return EFI_SUCCESS;\r
2016}\r
97a079ed 2017\r
aa75dfec 2018/**\r
2019 HII Database Protocol notification event handler.\r
2020\r
2021 Register font package when HII Database Protocol has been installed.\r
2022\r
2023 @param[in] Event Event whose notification function is being invoked.\r
2024 @param[in] Context Pointer to the notification function's context.\r
2025**/\r
28487361 2026VOID\r
2027EFIAPI\r
2028RegisterFontPackage (\r
2029 IN EFI_EVENT Event,\r
2030 IN VOID *Context\r
2031 )\r
2032{\r
2033 EFI_STATUS Status;\r
2034 EFI_HII_SIMPLE_FONT_PACKAGE_HDR *SimplifiedFont;\r
2035 UINT32 PackageLength;\r
28487361 2036 UINT8 *Package;\r
2037 UINT8 *Location;\r
2038 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
2039\r
2040 //\r
2041 // Locate HII Database Protocol\r
2042 //\r
2043 Status = gBS->LocateProtocol (\r
2044 &gEfiHiiDatabaseProtocolGuid,\r
2045 NULL,\r
2046 (VOID **) &HiiDatabase\r
2047 );\r
2048 ASSERT_EFI_ERROR (Status);\r
2049\r
2050 //\r
cb7d01c0 2051 // Add 4 bytes to the header for entire length for HiiAddPackages use only.\r
28487361 2052 //\r
2053 // +--------------------------------+ <-- Package\r
2054 // | |\r
2055 // | PackageLength(4 bytes) |\r
2056 // | |\r
2057 // |--------------------------------| <-- SimplifiedFont\r
2058 // | |\r
2059 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |\r
2060 // | |\r
2061 // |--------------------------------| <-- Location\r
2062 // | |\r
2063 // | gUsStdNarrowGlyphData |\r
2064 // | |\r
2065 // +--------------------------------+\r
2066\r
2067 PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + mNarrowFontSize + 4;\r
2068 Package = AllocateZeroPool (PackageLength);\r
2069 ASSERT (Package != NULL);\r
2070\r
2071 WriteUnaligned32((UINT32 *) Package,PackageLength);\r
2072 SimplifiedFont = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR *) (Package + 4);\r
2073 SimplifiedFont->Header.Length = (UINT32) (PackageLength - 4);\r
2074 SimplifiedFont->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;\r
2075 SimplifiedFont->NumberOfNarrowGlyphs = (UINT16) (mNarrowFontSize / sizeof (EFI_NARROW_GLYPH));\r
2076\r
2077 Location = (UINT8 *) (&SimplifiedFont->NumberOfWideGlyphs + 1);\r
2078 CopyMem (Location, gUsStdNarrowGlyphData, mNarrowFontSize);\r
2079\r
2080 //\r
2081 // Add this simplified font package to a package list then install it.\r
2082 //\r
cb7d01c0 2083 mHiiHandle = HiiAddPackages (\r
2084 &mFontPackageListGuid,\r
2085 NULL,\r
2086 Package,\r
2087 NULL\r
2088 );\r
2089 ASSERT (mHiiHandle != NULL);\r
28487361 2090 FreePool (Package);\r
2091}\r
2092\r
97a079ed
A
2093/**\r
2094 The user Entry Point for module GraphicsConsole. The user code starts with this function.\r
2095\r
8541adab 2096 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
97a079ed 2097 @param[in] SystemTable A pointer to the EFI System Table.\r
8541adab 2098\r
7601dbe7 2099 @retval EFI_SUCCESS The entry point is executed successfully.\r
2100 @return other Some error occurs when executing this entry point.\r
97a079ed
A
2101\r
2102**/\r
2103EFI_STATUS\r
2104EFIAPI\r
2105InitializeGraphicsConsole (\r
2106 IN EFI_HANDLE ImageHandle,\r
2107 IN EFI_SYSTEM_TABLE *SystemTable\r
2108 )\r
2109{\r
2110 EFI_STATUS Status;\r
2111\r
28487361 2112 //\r
2113 // Register notify function on HII Database Protocol to add font package.\r
78c0686b 2114 //\r
28487361 2115 EfiCreateProtocolNotifyEvent (\r
2116 &gEfiHiiDatabaseProtocolGuid,\r
2117 TPL_CALLBACK,\r
2118 RegisterFontPackage,\r
2119 NULL,\r
2120 &mHiiRegistration\r
2121 );\r
2122\r
97a079ed
A
2123 //\r
2124 // Install driver model protocol(s).\r
2125 //\r
5bca971e 2126 Status = EfiLibInstallDriverBindingComponentName2 (\r
97a079ed
A
2127 ImageHandle,\r
2128 SystemTable,\r
2129 &gGraphicsConsoleDriverBinding,\r
2130 ImageHandle,\r
2131 &gGraphicsConsoleComponentName,\r
5bca971e 2132 &gGraphicsConsoleComponentName2\r
97a079ed
A
2133 );\r
2134 ASSERT_EFI_ERROR (Status);\r
2135\r
97a079ed
A
2136 return Status;\r
2137}\r
2138\r
d42d853e 2139\r