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