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