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