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