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