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