]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c
Remove PCD usage for console driver, PcdConOutRow and PcdConOutColumn are current...
[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
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
865 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
866 return This->SetMode (This, 0);\r
867}\r
868\r
6dcf9abc 869\r
870/**\r
24248368 871 Write a Unicode string to the output device.\r
872\r
677fdb90 873 Implements SIMPLE_TEXT_OUTPUT.OutputString().\r
6dcf9abc 874 The Unicode string will be converted to Glyphs and will be\r
875 sent to the Graphics Console.\r
876\r
24248368 877 @param This Protocol instance pointer.\r
878 @param WString The NULL-terminated Unicode string to be displayed\r
879 on the output device(s). All output devices must\r
880 also support the Unicode drawing defined in this file.\r
6dcf9abc 881\r
24248368 882 @retval EFI_SUCCESS The string was output to the device.\r
883 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output\r
884 the text.\r
885 @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
886 defined text mode.\r
887 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
888 characters in the Unicode string could not be\r
889 rendered and were skipped.\r
6dcf9abc 890\r
891**/\r
95276127 892EFI_STATUS\r
893EFIAPI\r
894GraphicsConsoleConOutOutputString (\r
895 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
896 IN CHAR16 *WString\r
897 )\r
95276127 898{\r
899 GRAPHICS_CONSOLE_DEV *Private;\r
900 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
901 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
902 INTN Mode;\r
903 UINTN MaxColumn;\r
904 UINTN MaxRow;\r
905 UINTN Width;\r
906 UINTN Height;\r
907 UINTN Delta;\r
908 EFI_STATUS Status;\r
909 BOOLEAN Warning;\r
910 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
911 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
912 UINTN DeltaX;\r
913 UINTN DeltaY;\r
914 UINTN Count;\r
915 UINTN Index;\r
916 INT32 OriginAttribute;\r
917 EFI_TPL OldTpl;\r
95276127 918\r
919 Status = EFI_SUCCESS;\r
920\r
921 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
922 //\r
923 // Current mode\r
924 //\r
925 Mode = This->Mode->Mode;\r
926 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
927 GraphicsOutput = Private->GraphicsOutput;\r
928 UgaDraw = Private->UgaDraw;\r
929\r
930 MaxColumn = Private->ModeData[Mode].Columns;\r
931 MaxRow = Private->ModeData[Mode].Rows;\r
cd7bfc2c
ED
932 DeltaX = (UINTN) Private->ModeData[Mode].DeltaX;\r
933 DeltaY = (UINTN) Private->ModeData[Mode].DeltaY;\r
0898c57c 934 Width = MaxColumn * EFI_GLYPH_WIDTH;\r
935 Height = (MaxRow - 1) * EFI_GLYPH_HEIGHT;\r
95276127 936 Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
937\r
938 //\r
939 // The Attributes won't change when during the time OutputString is called\r
940 //\r
941 GetTextColors (This, &Foreground, &Background);\r
942\r
f44e8c16 943 FlushCursor (This);\r
95276127 944\r
945 Warning = FALSE;\r
946\r
947 //\r
948 // Backup attribute\r
949 //\r
950 OriginAttribute = This->Mode->Attribute;\r
951\r
6dcf9abc 952 while (*WString != L'\0') {\r
95276127 953\r
954 if (*WString == CHAR_BACKSPACE) {\r
955 //\r
956 // If the cursor is at the left edge of the display, then move the cursor\r
957 // one row up.\r
958 //\r
959 if (This->Mode->CursorColumn == 0 && This->Mode->CursorRow > 0) {\r
960 This->Mode->CursorRow--;\r
961 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);\r
962 This->OutputString (This, SpaceStr);\r
f44e8c16 963 FlushCursor (This);\r
95276127 964 This->Mode->CursorRow--;\r
965 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);\r
966 } else if (This->Mode->CursorColumn > 0) {\r
967 //\r
968 // If the cursor is not at the left edge of the display, then move the cursor\r
969 // left one column.\r
970 //\r
971 This->Mode->CursorColumn--;\r
972 This->OutputString (This, SpaceStr);\r
f44e8c16 973 FlushCursor (This);\r
95276127 974 This->Mode->CursorColumn--;\r
975 }\r
976\r
977 WString++;\r
978\r
979 } else if (*WString == CHAR_LINEFEED) {\r
980 //\r
981 // If the cursor is at the bottom of the display, then scroll the display one\r
982 // row, and do not update the cursor position. Otherwise, move the cursor\r
983 // down one row.\r
984 //\r
985 if (This->Mode->CursorRow == (INT32) (MaxRow - 1)) {\r
986 if (GraphicsOutput != NULL) {\r
987 //\r
988 // Scroll Screen Up One Row\r
989 //\r
990 GraphicsOutput->Blt (\r
991 GraphicsOutput,\r
992 NULL,\r
993 EfiBltVideoToVideo,\r
994 DeltaX,\r
0898c57c 995 DeltaY + EFI_GLYPH_HEIGHT,\r
95276127 996 DeltaX,\r
997 DeltaY,\r
998 Width,\r
999 Height,\r
1000 Delta\r
1001 );\r
1002\r
1003 //\r
1004 // Print Blank Line at last line\r
1005 //\r
1006 GraphicsOutput->Blt (\r
1007 GraphicsOutput,\r
1008 &Background,\r
1009 EfiBltVideoFill,\r
1010 0,\r
1011 0,\r
1012 DeltaX,\r
1013 DeltaY + Height,\r
1014 Width,\r
0898c57c 1015 EFI_GLYPH_HEIGHT,\r
95276127 1016 Delta\r
1017 );\r
8541adab 1018 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1019 //\r
1020 // Scroll Screen Up One Row\r
1021 //\r
1022 UgaDraw->Blt (\r
1023 UgaDraw,\r
1024 NULL,\r
1025 EfiUgaVideoToVideo,\r
1026 DeltaX,\r
0898c57c 1027 DeltaY + EFI_GLYPH_HEIGHT,\r
95276127 1028 DeltaX,\r
1029 DeltaY,\r
1030 Width,\r
1031 Height,\r
1032 Delta\r
1033 );\r
1034\r
1035 //\r
1036 // Print Blank Line at last line\r
1037 //\r
1038 UgaDraw->Blt (\r
1039 UgaDraw,\r
1040 (EFI_UGA_PIXEL *) (UINTN) &Background,\r
1041 EfiUgaVideoFill,\r
1042 0,\r
1043 0,\r
1044 DeltaX,\r
1045 DeltaY + Height,\r
1046 Width,\r
0898c57c 1047 EFI_GLYPH_HEIGHT,\r
95276127 1048 Delta\r
1049 );\r
1050 }\r
1051 } else {\r
1052 This->Mode->CursorRow++;\r
1053 }\r
1054\r
1055 WString++;\r
1056\r
1057 } else if (*WString == CHAR_CARRIAGE_RETURN) {\r
1058 //\r
1059 // Move the cursor to the beginning of the current row.\r
1060 //\r
1061 This->Mode->CursorColumn = 0;\r
1062 WString++;\r
1063\r
1064 } else if (*WString == WIDE_CHAR) {\r
1065\r
1066 This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;\r
1067 WString++;\r
1068\r
1069 } else if (*WString == NARROW_CHAR) {\r
1070\r
1071 This->Mode->Attribute &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);\r
1072 WString++;\r
1073\r
1074 } else {\r
1075 //\r
1076 // Print the character at the current cursor position and move the cursor\r
1077 // right one column. If this moves the cursor past the right edge of the\r
1078 // display, then the line should wrap to the beginning of the next line. This\r
1079 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the\r
1080 // bottom of the display, and the line wraps, then the display will be scrolled\r
1081 // one line.\r
1082 // If wide char is going to be displayed, need to display one character at a time\r
1083 // Or, need to know the display length of a certain string.\r
1084 //\r
1085 // Index is used to determine how many character width units (wide = 2, narrow = 1)\r
1086 // Count is used to determine how many characters are used regardless of their attributes\r
1087 //\r
1088 for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {\r
677fdb90 1089 if (WString[Count] == CHAR_NULL ||\r
1090 WString[Count] == CHAR_BACKSPACE ||\r
878670ea 1091 WString[Count] == CHAR_LINEFEED ||\r
1092 WString[Count] == CHAR_CARRIAGE_RETURN ||\r
1093 WString[Count] == WIDE_CHAR ||\r
1094 WString[Count] == NARROW_CHAR) {\r
95276127 1095 break;\r
1096 }\r
1097 //\r
1098 // Is the wide attribute on?\r
1099 //\r
677fdb90 1100 if ((This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) != 0) {\r
95276127 1101 //\r
1102 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop\r
1103 //\r
1104 Index++;\r
1105 //\r
1106 // This is the end-case where if we are at column 79 and about to print a wide character\r
1107 // We should prevent this from happening because we will wrap inappropriately. We should\r
1108 // not print this character until the next line.\r
1109 //\r
1110 if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {\r
1111 Index++;\r
1112 break;\r
1113 }\r
1114 }\r
1115 }\r
1116\r
1117 Status = DrawUnicodeWeightAtCursorN (This, WString, Count);\r
1118 if (EFI_ERROR (Status)) {\r
1119 Warning = TRUE;\r
1120 }\r
1121 //\r
1122 // At the end of line, output carriage return and line feed\r
1123 //\r
1124 WString += Count;\r
1125 This->Mode->CursorColumn += (INT32) Index;\r
1126 if (This->Mode->CursorColumn > (INT32) MaxColumn) {\r
1127 This->Mode->CursorColumn -= 2;\r
1128 This->OutputString (This, SpaceStr);\r
1129 }\r
1130\r
1131 if (This->Mode->CursorColumn >= (INT32) MaxColumn) {\r
f44e8c16 1132 FlushCursor (This);\r
95276127 1133 This->OutputString (This, mCrLfString);\r
f44e8c16 1134 FlushCursor (This);\r
95276127 1135 }\r
1136 }\r
1137 }\r
1138\r
1139 This->Mode->Attribute = OriginAttribute;\r
1140\r
f44e8c16 1141 FlushCursor (This);\r
95276127 1142\r
1143 if (Warning) {\r
1144 Status = EFI_WARN_UNKNOWN_GLYPH;\r
1145 }\r
1146\r
1147 gBS->RestoreTPL (OldTpl);\r
1148 return Status;\r
1149\r
1150}\r
1151\r
6dcf9abc 1152/**\r
677fdb90 1153 Verifies that all characters in a Unicode string can be output to the\r
24248368 1154 target device.\r
6dcf9abc 1155\r
5c03ed0a 1156 Implements SIMPLE_TEXT_OUTPUT.TestString().\r
24248368 1157 If one of the characters in the *Wstring is neither valid valid Unicode\r
1158 drawing characters, not ASCII code, then this function will return\r
1159 EFI_UNSUPPORTED\r
1160\r
1161 @param This Protocol instance pointer.\r
1162 @param WString The NULL-terminated Unicode string to be examined for the output\r
1163 device(s).\r
6dcf9abc 1164\r
24248368 1165 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.\r
1166 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be\r
1167 rendered by one or more of the output devices mapped\r
1168 by the EFI handle.\r
6dcf9abc 1169\r
1170**/\r
95276127 1171EFI_STATUS\r
1172EFIAPI\r
1173GraphicsConsoleConOutTestString (\r
1174 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1175 IN CHAR16 *WString\r
1176 )\r
95276127 1177{\r
1178 EFI_STATUS Status;\r
95276127 1179 UINT16 Count;\r
95276127 1180\r
6dcf9abc 1181 EFI_IMAGE_OUTPUT *Blt;\r
93e3992d 1182\r
6dcf9abc 1183 Blt = NULL;\r
93e3992d 1184 Count = 0;\r
1185\r
1186 while (WString[Count] != 0) {\r
93e3992d 1187 Status = mHiiFont->GetGlyph (\r
1188 mHiiFont,\r
1189 WString[Count],\r
1190 NULL,\r
1191 &Blt,\r
1192 NULL\r
1193 );\r
676df92c 1194 if (Blt != NULL) {\r
1195 FreePool (Blt);\r
1196 Blt = NULL;\r
1197 }\r
93e3992d 1198 Count++;\r
d42d853e 1199\r
95276127 1200 if (EFI_ERROR (Status)) {\r
1201 return EFI_UNSUPPORTED;\r
1202 }\r
1203 }\r
1204\r
1205 return EFI_SUCCESS;\r
1206}\r
1207\r
6dcf9abc 1208\r
1209/**\r
24248368 1210 Returns information for an available text mode that the output device(s)\r
1211 supports\r
1212\r
6dcf9abc 1213 Implements SIMPLE_TEXT_OUTPUT.QueryMode().\r
24248368 1214 It returnes information for an available text mode that the Graphics Console supports.\r
1215 In this driver,we only support text mode 80x25, which is defined as mode 0.\r
6dcf9abc 1216\r
24248368 1217 @param This Protocol instance pointer.\r
6dcf9abc 1218 @param ModeNumber The mode number to return information on.\r
1219 @param Columns The returned columns of the requested mode.\r
1220 @param Rows The returned rows of the requested mode.\r
1221\r
24248368 1222 @retval EFI_SUCCESS The requested mode information is returned.\r
1223 @retval EFI_UNSUPPORTED The mode number is not valid.\r
6dcf9abc 1224\r
1225**/\r
95276127 1226EFI_STATUS\r
1227EFIAPI\r
1228GraphicsConsoleConOutQueryMode (\r
1229 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1230 IN UINTN ModeNumber,\r
1231 OUT UINTN *Columns,\r
1232 OUT UINTN *Rows\r
1233 )\r
95276127 1234{\r
1235 GRAPHICS_CONSOLE_DEV *Private;\r
1236 EFI_STATUS Status;\r
1237 EFI_TPL OldTpl;\r
8541adab 1238\r
95276127 1239 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {\r
1240 return EFI_UNSUPPORTED;\r
1241 }\r
1242\r
1243 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1244 Status = EFI_SUCCESS;\r
8541adab 1245\r
95276127 1246 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1247\r
1248 *Columns = Private->ModeData[ModeNumber].Columns;\r
1249 *Rows = Private->ModeData[ModeNumber].Rows;\r
1250\r
79d07c66 1251 if (*Columns <= 0 || *Rows <= 0) {\r
95276127 1252 Status = EFI_UNSUPPORTED;\r
1253 goto Done;\r
1254\r
1255 }\r
1256\r
1257Done:\r
1258 gBS->RestoreTPL (OldTpl);\r
1259 return Status;\r
1260}\r
1261\r
6dcf9abc 1262\r
1263/**\r
24248368 1264 Sets the output device(s) to a specified mode.\r
677fdb90 1265\r
6dcf9abc 1266 Implements SIMPLE_TEXT_OUTPUT.SetMode().\r
24248368 1267 Set the Graphics Console to a specified mode. In this driver, we only support mode 0.\r
6dcf9abc 1268\r
24248368 1269 @param This Protocol instance pointer.\r
6dcf9abc 1270 @param ModeNumber The text mode to set.\r
1271\r
24248368 1272 @retval EFI_SUCCESS The requested text mode is set.\r
677fdb90 1273 @retval EFI_DEVICE_ERROR The requested text mode cannot be set because of\r
24248368 1274 Graphics Console device error.\r
1275 @retval EFI_UNSUPPORTED The text mode number is not valid.\r
6dcf9abc 1276\r
1277**/\r
95276127 1278EFI_STATUS\r
1279EFIAPI\r
1280GraphicsConsoleConOutSetMode (\r
1281 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1282 IN UINTN ModeNumber\r
1283 )\r
95276127 1284{\r
1285 EFI_STATUS Status;\r
1286 GRAPHICS_CONSOLE_DEV *Private;\r
1287 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1288 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewLineBuffer;\r
1289 UINT32 HorizontalResolution;\r
1290 UINT32 VerticalResolution;\r
1291 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1292 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1293 UINT32 ColorDepth;\r
1294 UINT32 RefreshRate;\r
1295 EFI_TPL OldTpl;\r
1296\r
1297 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1298\r
1299 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1300 GraphicsOutput = Private->GraphicsOutput;\r
1301 UgaDraw = Private->UgaDraw;\r
1302 ModeData = &(Private->ModeData[ModeNumber]);\r
1303\r
95276127 1304 //\r
1305 // Make sure the requested mode number is supported\r
1306 //\r
1307 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {\r
1308 Status = EFI_UNSUPPORTED;\r
1309 goto Done;\r
1310 }\r
1311\r
1312 if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {\r
1313 Status = EFI_UNSUPPORTED;\r
1314 goto Done;\r
1315 }\r
1316 //\r
1317 // Attempt to allocate a line buffer for the requested mode number\r
1318 //\r
0898c57c 1319 NewLineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT);\r
95276127 1320\r
1321 if (NewLineBuffer == NULL) {\r
1322 //\r
1323 // The new line buffer could not be allocated, so return an error.\r
1324 // No changes to the state of the current console have been made, so the current console is still valid\r
1325 //\r
1326 Status = EFI_OUT_OF_RESOURCES;\r
1327 goto Done;\r
1328 }\r
1329 //\r
1330 // If the mode has been set at least one other time, then LineBuffer will not be NULL\r
1331 //\r
1332 if (Private->LineBuffer != NULL) {\r
1333 //\r
1334 // Clear the current text window on the current graphics console\r
1335 //\r
1336 This->ClearScreen (This);\r
1337\r
1338 //\r
1339 // If the new mode is the same as the old mode, then just return EFI_SUCCESS\r
1340 //\r
1341 if ((INT32) ModeNumber == This->Mode->Mode) {\r
1342 FreePool (NewLineBuffer);\r
1343 Status = EFI_SUCCESS;\r
1344 goto Done;\r
1345 }\r
1346 //\r
7347d5d6 1347 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,\r
1348 // so erase the cursor, and free the LineBuffer for the current mode\r
95276127 1349 //\r
f44e8c16 1350 FlushCursor (This);\r
95276127 1351\r
1352 FreePool (Private->LineBuffer);\r
1353 }\r
1354 //\r
1355 // Assign the current line buffer to the newly allocated line buffer\r
1356 //\r
1357 Private->LineBuffer = NewLineBuffer;\r
1358\r
1359 if (GraphicsOutput != NULL) {\r
1360 if (ModeData->GopModeNumber != GraphicsOutput->Mode->Mode) {\r
1361 //\r
878670ea 1362 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode\r
95276127 1363 //\r
1364 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeData->GopModeNumber);\r
1365 if (EFI_ERROR (Status)) {\r
1366 //\r
1367 // The mode set operation failed\r
1368 //\r
1369 goto Done;\r
1370 }\r
1371 } else {\r
1372 //\r
1373 // The current graphics mode is correct, so simply clear the entire display\r
1374 //\r
1375 Status = GraphicsOutput->Blt (\r
1376 GraphicsOutput,\r
f618b2fa 1377 &mGraphicsEfiColors[0],\r
95276127 1378 EfiBltVideoFill,\r
1379 0,\r
1380 0,\r
1381 0,\r
1382 0,\r
1383 ModeData->GopWidth,\r
1384 ModeData->GopHeight,\r
1385 0\r
1386 );\r
1387 }\r
8541adab 1388 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1389 //\r
1390 // Get the current UGA Draw mode information\r
1391 //\r
1392 Status = UgaDraw->GetMode (\r
1393 UgaDraw,\r
1394 &HorizontalResolution,\r
1395 &VerticalResolution,\r
1396 &ColorDepth,\r
1397 &RefreshRate\r
1398 );\r
1399 if (EFI_ERROR (Status) || HorizontalResolution != ModeData->GopWidth || VerticalResolution != ModeData->GopHeight) {\r
1400 //\r
878670ea 1401 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode\r
95276127 1402 //\r
1403 Status = UgaDraw->SetMode (\r
1404 UgaDraw,\r
1405 ModeData->GopWidth,\r
1406 ModeData->GopHeight,\r
1407 32,\r
1408 60\r
1409 );\r
1410 if (EFI_ERROR (Status)) {\r
1411 //\r
1412 // The mode set operation failed\r
1413 //\r
1414 goto Done;\r
1415 }\r
1416 } else {\r
1417 //\r
1418 // The current graphics mode is correct, so simply clear the entire display\r
1419 //\r
1420 Status = UgaDraw->Blt (\r
1421 UgaDraw,\r
f618b2fa 1422 (EFI_UGA_PIXEL *) (UINTN) &mGraphicsEfiColors[0],\r
95276127 1423 EfiUgaVideoFill,\r
1424 0,\r
1425 0,\r
1426 0,\r
1427 0,\r
1428 ModeData->GopWidth,\r
1429 ModeData->GopHeight,\r
1430 0\r
1431 );\r
1432 }\r
1433 }\r
1434\r
1435 //\r
1436 // The new mode is valid, so commit the mode change\r
1437 //\r
1438 This->Mode->Mode = (INT32) ModeNumber;\r
1439\r
1440 //\r
f44e8c16 1441 // Move the text cursor to the upper left hand corner of the display and flush it\r
95276127 1442 //\r
f44e8c16 1443 This->Mode->CursorColumn = 0;\r
1444 This->Mode->CursorRow = 0;\r
1445\r
1446 FlushCursor (This); \r
95276127 1447\r
1448 Status = EFI_SUCCESS;\r
1449\r
1450Done:\r
1451 gBS->RestoreTPL (OldTpl);\r
1452 return Status;\r
1453}\r
1454\r
6dcf9abc 1455\r
1456/**\r
24248368 1457 Sets the background and foreground colors for the OutputString () and\r
1458 ClearScreen () functions.\r
1459\r
6dcf9abc 1460 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().\r
1461\r
24248368 1462 @param This Protocol instance pointer.\r
1463 @param Attribute The attribute to set. Bits 0..3 are the foreground\r
677fdb90 1464 color, and bits 4..6 are the background color.\r
24248368 1465 All other bits are undefined and must be zero.\r
6dcf9abc 1466\r
24248368 1467 @retval EFI_SUCCESS The requested attribute is set.\r
1468 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to Graphics Console port error.\r
1469 @retval EFI_UNSUPPORTED The attribute requested is not defined.\r
6dcf9abc 1470\r
1471**/\r
95276127 1472EFI_STATUS\r
1473EFIAPI\r
1474GraphicsConsoleConOutSetAttribute (\r
1475 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1476 IN UINTN Attribute\r
1477 )\r
95276127 1478{\r
1479 EFI_TPL OldTpl;\r
8541adab 1480\r
95276127 1481 if ((Attribute | 0xFF) != 0xFF) {\r
1482 return EFI_UNSUPPORTED;\r
1483 }\r
1484\r
1485 if ((INT32) Attribute == This->Mode->Attribute) {\r
1486 return EFI_SUCCESS;\r
1487 }\r
1488\r
1489 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1490\r
f44e8c16 1491 FlushCursor (This);\r
95276127 1492\r
1493 This->Mode->Attribute = (INT32) Attribute;\r
1494\r
f44e8c16 1495 FlushCursor (This);\r
95276127 1496\r
1497 gBS->RestoreTPL (OldTpl);\r
1498\r
1499 return EFI_SUCCESS;\r
1500}\r
1501\r
6dcf9abc 1502\r
1503/**\r
677fdb90 1504 Clears the output device(s) display to the currently selected background\r
24248368 1505 color.\r
1506\r
6dcf9abc 1507 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().\r
6dcf9abc 1508\r
24248368 1509 @param This Protocol instance pointer.\r
6dcf9abc 1510\r
24248368 1511 @retval EFI_SUCCESS The operation completed successfully.\r
1512 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.\r
1513 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.\r
6dcf9abc 1514\r
1515**/\r
95276127 1516EFI_STATUS\r
1517EFIAPI\r
1518GraphicsConsoleConOutClearScreen (\r
1519 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
1520 )\r
95276127 1521{\r
1522 EFI_STATUS Status;\r
1523 GRAPHICS_CONSOLE_DEV *Private;\r
1524 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1525 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1526 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1527 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
1528 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
1529 EFI_TPL OldTpl;\r
1530\r
1531 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1532\r
1533 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1534 GraphicsOutput = Private->GraphicsOutput;\r
1535 UgaDraw = Private->UgaDraw;\r
1536 ModeData = &(Private->ModeData[This->Mode->Mode]);\r
1537\r
1538 GetTextColors (This, &Foreground, &Background);\r
1539 if (GraphicsOutput != NULL) {\r
1540 Status = GraphicsOutput->Blt (\r
1541 GraphicsOutput,\r
1542 &Background,\r
1543 EfiBltVideoFill,\r
1544 0,\r
1545 0,\r
1546 0,\r
1547 0,\r
1548 ModeData->GopWidth,\r
1549 ModeData->GopHeight,\r
1550 0\r
1551 );\r
8541adab 1552 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1553 Status = UgaDraw->Blt (\r
1554 UgaDraw,\r
1555 (EFI_UGA_PIXEL *) (UINTN) &Background,\r
1556 EfiUgaVideoFill,\r
1557 0,\r
1558 0,\r
1559 0,\r
1560 0,\r
1561 ModeData->GopWidth,\r
1562 ModeData->GopHeight,\r
1563 0\r
1564 );\r
8541adab 1565 } else {\r
1566 Status = EFI_UNSUPPORTED;\r
95276127 1567 }\r
1568\r
1569 This->Mode->CursorColumn = 0;\r
1570 This->Mode->CursorRow = 0;\r
1571\r
f44e8c16 1572 FlushCursor (This);\r
95276127 1573\r
1574 gBS->RestoreTPL (OldTpl);\r
1575\r
1576 return Status;\r
1577}\r
1578\r
6dcf9abc 1579\r
1580/**\r
24248368 1581 Sets the current coordinates of the cursor position.\r
1582\r
6dcf9abc 1583 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().\r
1584\r
24248368 1585 @param This Protocol instance pointer.\r
1586 @param Column The position to set the cursor to. Must be greater than or\r
1587 equal to zero and less than the number of columns and rows\r
1588 by QueryMode ().\r
1589 @param Row The position to set the cursor to. Must be greater than or\r
1590 equal to zero and less than the number of columns and rows\r
1591 by QueryMode ().\r
6dcf9abc 1592\r
24248368 1593 @retval EFI_SUCCESS The operation completed successfully.\r
1594 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.\r
1595 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the\r
1596 cursor position is invalid for the current mode.\r
6dcf9abc 1597\r
1598**/\r
95276127 1599EFI_STATUS\r
1600EFIAPI\r
1601GraphicsConsoleConOutSetCursorPosition (\r
1602 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1603 IN UINTN Column,\r
1604 IN UINTN Row\r
1605 )\r
95276127 1606{\r
1607 GRAPHICS_CONSOLE_DEV *Private;\r
1608 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1609 EFI_STATUS Status;\r
1610 EFI_TPL OldTpl;\r
1611\r
1612 Status = EFI_SUCCESS;\r
1613\r
1614 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1615\r
1616 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1617 ModeData = &(Private->ModeData[This->Mode->Mode]);\r
1618\r
1619 if ((Column >= ModeData->Columns) || (Row >= ModeData->Rows)) {\r
1620 Status = EFI_UNSUPPORTED;\r
1621 goto Done;\r
1622 }\r
1623\r
8595bdaf 1624 if ((This->Mode->CursorColumn == (INT32) Column) && (This->Mode->CursorRow == (INT32) Row)) {\r
95276127 1625 Status = EFI_SUCCESS;\r
1626 goto Done;\r
1627 }\r
1628\r
f44e8c16 1629 FlushCursor (This);\r
95276127 1630\r
1631 This->Mode->CursorColumn = (INT32) Column;\r
1632 This->Mode->CursorRow = (INT32) Row;\r
1633\r
f44e8c16 1634 FlushCursor (This);\r
95276127 1635\r
1636Done:\r
1637 gBS->RestoreTPL (OldTpl);\r
1638\r
1639 return Status;\r
1640}\r
1641\r
6dcf9abc 1642\r
1643/**\r
24248368 1644 Makes the cursor visible or invisible.\r
1645\r
6dcf9abc 1646 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().\r
6dcf9abc 1647\r
24248368 1648 @param This Protocol instance pointer.\r
6dcf9abc 1649 @param Visible If TRUE, the cursor is set to be visible, If FALSE,\r
1650 the cursor is set to be invisible.\r
1651\r
24248368 1652 @retval EFI_SUCCESS The operation completed successfully.\r
6dcf9abc 1653\r
1654**/\r
95276127 1655EFI_STATUS\r
1656EFIAPI\r
1657GraphicsConsoleConOutEnableCursor (\r
1658 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1659 IN BOOLEAN Visible\r
1660 )\r
95276127 1661{\r
1662 EFI_TPL OldTpl;\r
8541adab 1663\r
95276127 1664 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
8541adab 1665\r
f44e8c16 1666 FlushCursor (This);\r
95276127 1667\r
1668 This->Mode->CursorVisible = Visible;\r
1669\r
f44e8c16 1670 FlushCursor (This);\r
95276127 1671\r
1672 gBS->RestoreTPL (OldTpl);\r
1673 return EFI_SUCCESS;\r
1674}\r
1675\r
24248368 1676/**\r
1677 Gets Graphics Console devcie's foreground color and background color.\r
1678\r
1679 @param This Protocol instance pointer.\r
1680 @param Foreground Returned text foreground color.\r
1681 @param Background Returned text background color.\r
1682\r
1683 @retval EFI_SUCCESS It returned always.\r
1684\r
1685**/\r
95276127 1686EFI_STATUS\r
1687GetTextColors (\r
1688 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1689 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
1690 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background\r
1691 )\r
1692{\r
1693 INTN Attribute;\r
1694\r
1695 Attribute = This->Mode->Attribute & 0x7F;\r
1696\r
f618b2fa 1697 *Foreground = mGraphicsEfiColors[Attribute & 0x0f];\r
1698 *Background = mGraphicsEfiColors[Attribute >> 4];\r
95276127 1699\r
1700 return EFI_SUCCESS;\r
1701}\r
1702\r
24248368 1703/**\r
878670ea 1704 Draw Unicode string on the Graphics Console device's screen.\r
24248368 1705\r
1706 @param This Protocol instance pointer.\r
1707 @param UnicodeWeight One Unicode string to be displayed.\r
1708 @param Count The count of Unicode string.\r
1709\r
1710 @retval EFI_OUT_OF_RESOURCES If no memory resource to use.\r
1711 @retval EFI_UNSUPPORTED If no Graphics Output protocol and UGA Draw\r
1712 protocol exist.\r
1713 @retval EFI_SUCCESS Drawing Unicode string implemented successfully.\r
1714\r
1715**/\r
93e3992d 1716EFI_STATUS\r
1717DrawUnicodeWeightAtCursorN (\r
1718 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
24248368 1719 IN CHAR16 *UnicodeWeight,\r
1720 IN UINTN Count\r
93e3992d 1721 )\r
1722{\r
1723 EFI_STATUS Status;\r
1724 GRAPHICS_CONSOLE_DEV *Private;\r
1725 EFI_IMAGE_OUTPUT *Blt;\r
1726 EFI_STRING String;\r
1727 EFI_FONT_DISPLAY_INFO *FontInfo;\r
d42d853e 1728 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1729 EFI_HII_ROW_INFO *RowInfoArray;\r
1730 UINTN RowInfoArraySize;\r
93e3992d 1731\r
1732 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
93e3992d 1733 Blt = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
1734 if (Blt == NULL) {\r
1735 return EFI_OUT_OF_RESOURCES;\r
1736 }\r
1737\r
1738 Blt->Width = (UINT16) (Private->ModeData[This->Mode->Mode].GopWidth);\r
1739 Blt->Height = (UINT16) (Private->ModeData[This->Mode->Mode].GopHeight);\r
93e3992d 1740\r
1741 String = AllocateCopyPool ((Count + 1) * sizeof (CHAR16), UnicodeWeight);\r
1742 if (String == NULL) {\r
676df92c 1743 FreePool (Blt);\r
93e3992d 1744 return EFI_OUT_OF_RESOURCES;\r
1745 }\r
8595bdaf 1746 //\r
1747 // Set the end character\r
1748 //\r
1749 *(String + Count) = L'\0';\r
93e3992d 1750\r
1751 FontInfo = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));\r
1752 if (FontInfo == NULL) {\r
676df92c 1753 FreePool (Blt);\r
1754 FreePool (String);\r
93e3992d 1755 return EFI_OUT_OF_RESOURCES;\r
1756 }\r
8595bdaf 1757 //\r
1758 // Get current foreground and background colors.\r
1759 //\r
93e3992d 1760 GetTextColors (This, &FontInfo->ForegroundColor, &FontInfo->BackgroundColor);\r
1761\r
d42d853e 1762 if (Private->GraphicsOutput != NULL) {\r
8595bdaf 1763 //\r
677fdb90 1764 // If Graphics Output protocol exists, using HII Font protocol to draw.\r
8595bdaf 1765 //\r
d42d853e 1766 Blt->Image.Screen = Private->GraphicsOutput;\r
95276127 1767\r
d42d853e 1768 Status = mHiiFont->StringToImage (\r
1769 mHiiFont,\r
5e0b1e3f 1770 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN | EFI_HII_IGNORE_LINE_BREAK,\r
d42d853e 1771 String,\r
1772 FontInfo,\r
1773 &Blt,\r
0898c57c 1774 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1775 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
d42d853e 1776 NULL,\r
1777 NULL,\r
1778 NULL\r
1779 );\r
95276127 1780\r
8541adab 1781 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
8595bdaf 1782 //\r
677fdb90 1783 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,\r
8595bdaf 1784 // using UGA Draw protocol to draw.\r
1785 //\r
d42d853e 1786 ASSERT (Private->UgaDraw!= NULL);\r
95276127 1787\r
d42d853e 1788 UgaDraw = Private->UgaDraw;\r
95276127 1789\r
d42d853e 1790 Blt->Image.Bitmap = AllocateZeroPool (Blt->Width * Blt->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
1791 if (Blt->Image.Bitmap == NULL) {\r
676df92c 1792 FreePool (Blt);\r
1793 FreePool (String);\r
d42d853e 1794 return EFI_OUT_OF_RESOURCES;\r
95276127 1795 }\r
1796\r
d42d853e 1797 RowInfoArray = NULL;\r
1798 //\r
1799 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,\r
1800 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.\r
1801 //\r
1802 Status = mHiiFont->StringToImage (\r
1803 mHiiFont,\r
5e0b1e3f 1804 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK,\r
d42d853e 1805 String,\r
1806 FontInfo,\r
1807 &Blt,\r
0898c57c 1808 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1809 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
d42d853e 1810 &RowInfoArray,\r
1811 &RowInfoArraySize,\r
1812 NULL\r
1813 );\r
95276127 1814\r
d42d853e 1815 if (!EFI_ERROR (Status)) {\r
95276127 1816 //\r
d42d853e 1817 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will\r
bd1d34ee 1818 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.\r
95276127 1819 //\r
bd1d34ee 1820 ASSERT (RowInfoArraySize <= 1);\r
8541adab 1821\r
d42d853e 1822 Status = UgaDraw->Blt (\r
1823 UgaDraw,\r
1824 (EFI_UGA_PIXEL *) Blt->Image.Bitmap,\r
1825 EfiUgaBltBufferToVideo,\r
0898c57c 1826 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1827 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
1828 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1829 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
d42d853e 1830 RowInfoArray[0].LineWidth,\r
1831 RowInfoArray[0].LineHeight,\r
1832 Blt->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1833 );\r
1834 }\r
95276127 1835\r
676df92c 1836 FreePool (RowInfoArray);\r
1837 FreePool (Blt->Image.Bitmap);\r
8541adab 1838 } else {\r
1839 Status = EFI_UNSUPPORTED;\r
95276127 1840 }\r
1841\r
676df92c 1842 if (Blt != NULL) {\r
1843 FreePool (Blt);\r
1844 }\r
1845 if (String != NULL) {\r
1846 FreePool (String);\r
1847 }\r
1848 if (FontInfo != NULL) {\r
1849 FreePool (FontInfo);\r
1850 }\r
d42d853e 1851 return Status;\r
95276127 1852}\r
d42d853e 1853\r
24248368 1854/**\r
f44e8c16 1855 Flush the cursor on the screen.\r
1856 \r
1857 If CursorVisible is FALSE, nothing to do and return directly.\r
1858 If CursorVisible is TRUE, \r
1859 i) If the cursor shows on screen, it will be erased.\r
1860 ii) If the cursor does not show on screen, it will be shown. \r
95276127 1861\r
24248368 1862 @param This Protocol instance pointer.\r
1863\r
1864 @retval EFI_SUCCESS The cursor is erased successfully.\r
1865\r
1866**/\r
95276127 1867EFI_STATUS\r
f44e8c16 1868FlushCursor (\r
95276127 1869 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
1870 )\r
1871{\r
7601dbe7 1872 GRAPHICS_CONSOLE_DEV *Private;\r
1873 EFI_SIMPLE_TEXT_OUTPUT_MODE *CurrentMode;\r
1874 INTN GlyphX;\r
1875 INTN GlyphY;\r
95276127 1876 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
7601dbe7 1877 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
95276127 1878 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground;\r
1879 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background;\r
0898c57c 1880 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar[EFI_GLYPH_HEIGHT][EFI_GLYPH_WIDTH];\r
7601dbe7 1881 UINTN PosX;\r
1882 UINTN PosY;\r
95276127 1883\r
1884 CurrentMode = This->Mode;\r
1885\r
1886 if (!CurrentMode->CursorVisible) {\r
1887 return EFI_SUCCESS;\r
1888 }\r
1889\r
1890 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1891 GraphicsOutput = Private->GraphicsOutput;\r
1892 UgaDraw = Private->UgaDraw;\r
1893\r
1894 //\r
24248368 1895 // In this driver, only narrow character was supported.\r
95276127 1896 //\r
1897 //\r
1898 // Blt a character to the screen\r
1899 //\r
0898c57c 1900 GlyphX = (CurrentMode->CursorColumn * EFI_GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;\r
1901 GlyphY = (CurrentMode->CursorRow * EFI_GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;\r
95276127 1902 if (GraphicsOutput != NULL) {\r
1903 GraphicsOutput->Blt (\r
1904 GraphicsOutput,\r
1905 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,\r
1906 EfiBltVideoToBltBuffer,\r
1907 GlyphX,\r
1908 GlyphY,\r
1909 0,\r
1910 0,\r
0898c57c 1911 EFI_GLYPH_WIDTH,\r
1912 EFI_GLYPH_HEIGHT,\r
1913 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
95276127 1914 );\r
8541adab 1915 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1916 UgaDraw->Blt (\r
1917 UgaDraw,\r
1918 (EFI_UGA_PIXEL *) (UINTN) BltChar,\r
1919 EfiUgaVideoToBltBuffer,\r
1920 GlyphX,\r
1921 GlyphY,\r
1922 0,\r
1923 0,\r
0898c57c 1924 EFI_GLYPH_WIDTH,\r
1925 EFI_GLYPH_HEIGHT,\r
1926 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
95276127 1927 );\r
1928 }\r
1929\r
1930 GetTextColors (This, &Foreground.Pixel, &Background.Pixel);\r
1931\r
1932 //\r
1933 // Convert Monochrome bitmap of the Glyph to BltBuffer structure\r
1934 //\r
6dcf9abc 1935 for (PosY = 0; PosY < EFI_GLYPH_HEIGHT; PosY++) {\r
1936 for (PosX = 0; PosX < EFI_GLYPH_WIDTH; PosX++) {\r
878670ea 1937 if ((mCursorGlyph.GlyphCol1[PosY] & (BIT0 << PosX)) != 0) {\r
6dcf9abc 1938 BltChar[PosY][EFI_GLYPH_WIDTH - PosX - 1].Raw ^= Foreground.Raw;\r
95276127 1939 }\r
1940 }\r
1941 }\r
1942\r
1943 if (GraphicsOutput != NULL) {\r
1944 GraphicsOutput->Blt (\r
1945 GraphicsOutput,\r
1946 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,\r
1947 EfiBltBufferToVideo,\r
1948 0,\r
1949 0,\r
1950 GlyphX,\r
1951 GlyphY,\r
0898c57c 1952 EFI_GLYPH_WIDTH,\r
1953 EFI_GLYPH_HEIGHT,\r
1954 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
95276127 1955 );\r
8541adab 1956 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
95276127 1957 UgaDraw->Blt (\r
1958 UgaDraw,\r
1959 (EFI_UGA_PIXEL *) (UINTN) BltChar,\r
1960 EfiUgaBltBufferToVideo,\r
1961 0,\r
1962 0,\r
1963 GlyphX,\r
1964 GlyphY,\r
0898c57c 1965 EFI_GLYPH_WIDTH,\r
1966 EFI_GLYPH_HEIGHT,\r
1967 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
95276127 1968 );\r
1969 }\r
1970\r
1971 return EFI_SUCCESS;\r
1972}\r
97a079ed 1973\r
aa75dfec 1974/**\r
1975 HII Database Protocol notification event handler.\r
1976\r
1977 Register font package when HII Database Protocol has been installed.\r
1978\r
1979 @param[in] Event Event whose notification function is being invoked.\r
1980 @param[in] Context Pointer to the notification function's context.\r
1981**/\r
28487361 1982VOID\r
1983EFIAPI\r
1984RegisterFontPackage (\r
1985 IN EFI_EVENT Event,\r
1986 IN VOID *Context\r
1987 )\r
1988{\r
1989 EFI_STATUS Status;\r
1990 EFI_HII_SIMPLE_FONT_PACKAGE_HDR *SimplifiedFont;\r
1991 UINT32 PackageLength;\r
28487361 1992 UINT8 *Package;\r
1993 UINT8 *Location;\r
1994 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
1995\r
1996 //\r
1997 // Locate HII Database Protocol\r
1998 //\r
1999 Status = gBS->LocateProtocol (\r
2000 &gEfiHiiDatabaseProtocolGuid,\r
2001 NULL,\r
2002 (VOID **) &HiiDatabase\r
2003 );\r
2004 ASSERT_EFI_ERROR (Status);\r
2005\r
2006 //\r
cb7d01c0 2007 // Add 4 bytes to the header for entire length for HiiAddPackages use only.\r
28487361 2008 //\r
2009 // +--------------------------------+ <-- Package\r
2010 // | |\r
2011 // | PackageLength(4 bytes) |\r
2012 // | |\r
2013 // |--------------------------------| <-- SimplifiedFont\r
2014 // | |\r
2015 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |\r
2016 // | |\r
2017 // |--------------------------------| <-- Location\r
2018 // | |\r
2019 // | gUsStdNarrowGlyphData |\r
2020 // | |\r
2021 // +--------------------------------+\r
2022\r
2023 PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + mNarrowFontSize + 4;\r
2024 Package = AllocateZeroPool (PackageLength);\r
2025 ASSERT (Package != NULL);\r
2026\r
2027 WriteUnaligned32((UINT32 *) Package,PackageLength);\r
2028 SimplifiedFont = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR *) (Package + 4);\r
2029 SimplifiedFont->Header.Length = (UINT32) (PackageLength - 4);\r
2030 SimplifiedFont->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;\r
2031 SimplifiedFont->NumberOfNarrowGlyphs = (UINT16) (mNarrowFontSize / sizeof (EFI_NARROW_GLYPH));\r
2032\r
2033 Location = (UINT8 *) (&SimplifiedFont->NumberOfWideGlyphs + 1);\r
2034 CopyMem (Location, gUsStdNarrowGlyphData, mNarrowFontSize);\r
2035\r
2036 //\r
2037 // Add this simplified font package to a package list then install it.\r
2038 //\r
cb7d01c0 2039 mHiiHandle = HiiAddPackages (\r
2040 &mFontPackageListGuid,\r
2041 NULL,\r
2042 Package,\r
2043 NULL\r
2044 );\r
2045 ASSERT (mHiiHandle != NULL);\r
28487361 2046 FreePool (Package);\r
2047}\r
2048\r
97a079ed
A
2049/**\r
2050 The user Entry Point for module GraphicsConsole. The user code starts with this function.\r
2051\r
8541adab 2052 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
97a079ed 2053 @param[in] SystemTable A pointer to the EFI System Table.\r
8541adab 2054\r
7601dbe7 2055 @retval EFI_SUCCESS The entry point is executed successfully.\r
2056 @return other Some error occurs when executing this entry point.\r
97a079ed
A
2057\r
2058**/\r
2059EFI_STATUS\r
2060EFIAPI\r
2061InitializeGraphicsConsole (\r
2062 IN EFI_HANDLE ImageHandle,\r
2063 IN EFI_SYSTEM_TABLE *SystemTable\r
2064 )\r
2065{\r
2066 EFI_STATUS Status;\r
2067\r
28487361 2068 //\r
2069 // Register notify function on HII Database Protocol to add font package.\r
78c0686b 2070 //\r
28487361 2071 EfiCreateProtocolNotifyEvent (\r
2072 &gEfiHiiDatabaseProtocolGuid,\r
2073 TPL_CALLBACK,\r
2074 RegisterFontPackage,\r
2075 NULL,\r
2076 &mHiiRegistration\r
2077 );\r
2078\r
97a079ed
A
2079 //\r
2080 // Install driver model protocol(s).\r
2081 //\r
5bca971e 2082 Status = EfiLibInstallDriverBindingComponentName2 (\r
97a079ed
A
2083 ImageHandle,\r
2084 SystemTable,\r
2085 &gGraphicsConsoleDriverBinding,\r
2086 ImageHandle,\r
2087 &gGraphicsConsoleComponentName,\r
5bca971e 2088 &gGraphicsConsoleComponentName2\r
97a079ed
A
2089 );\r
2090 ASSERT_EFI_ERROR (Status);\r
2091\r
97a079ed
A
2092 return Status;\r
2093}\r
2094\r
d42d853e 2095\r