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