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