TianoCore EDK2 master
Loading...
Searching...
No Matches
GraphicsConsole.c
Go to the documentation of this file.
1
9#include "GraphicsConsole.h"
10
11//
12// Graphics Console Device Private Data template
13//
14GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate = {
15 GRAPHICS_CONSOLE_DEV_SIGNATURE,
18 {
29 },
30 {
31 0,
32 -1,
33 EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK),
34 0,
35 0,
36 FALSE
37 },
40};
41
42GRAPHICS_CONSOLE_MODE_DATA mGraphicsConsoleModeData[] = {
43 { 100, 31 }, // 800 x 600
44 { 128, 40 }, // 1024 x 768
45 { 160, 42 }, // 1280 x 800
46 { 240, 56 }, // 1920 x 1080
47 //
48 // New modes can be added here.
49 // The last entry is specific for full screen mode.
50 //
51 { 0, 0 }
52};
53
54EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;
55EFI_HII_FONT_PROTOCOL *mHiiFont;
56EFI_HII_HANDLE mHiiHandle;
57VOID *mHiiRegistration;
58
59EFI_GUID mFontPackageListGuid = {
60 0xf5f219d3, 0x7006, 0x4648, { 0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad }
61};
62
63CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };
64
65EFI_GRAPHICS_OUTPUT_BLT_PIXEL mGraphicsEfiColors[16] = {
66 //
67 // B G R reserved
68 //
69 { 0x00, 0x00, 0x00, 0x00 }, // BLACK
70 { 0x98, 0x00, 0x00, 0x00 }, // LIGHTBLUE
71 { 0x00, 0x98, 0x00, 0x00 }, // LIGHGREEN
72 { 0x98, 0x98, 0x00, 0x00 }, // LIGHCYAN
73 { 0x00, 0x00, 0x98, 0x00 }, // LIGHRED
74 { 0x98, 0x00, 0x98, 0x00 }, // MAGENTA
75 { 0x00, 0x98, 0x98, 0x00 }, // BROWN
76 { 0x98, 0x98, 0x98, 0x00 }, // LIGHTGRAY
77 { 0x30, 0x30, 0x30, 0x00 }, // DARKGRAY - BRIGHT BLACK
78 { 0xff, 0x00, 0x00, 0x00 }, // BLUE
79 { 0x00, 0xff, 0x00, 0x00 }, // LIME
80 { 0xff, 0xff, 0x00, 0x00 }, // CYAN
81 { 0x00, 0x00, 0xff, 0x00 }, // RED
82 { 0xff, 0x00, 0xff, 0x00 }, // FUCHSIA
83 { 0x00, 0xff, 0xff, 0x00 }, // YELLOW
84 { 0xff, 0xff, 0xff, 0x00 } // WHITE
85};
86
87EFI_NARROW_GLYPH mCursorGlyph = {
88 0x0000,
89 0x00,
90 { 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }
91};
92
93CHAR16 SpaceStr[] = { NARROW_CHAR, ' ', 0 };
94
95EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding = {
99 0xa,
100 NULL,
101 NULL
102};
103
121EFIAPI
124 IN EFI_HANDLE Controller,
125 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
126 )
127{
128 EFI_STATUS Status;
129 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
130 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
131 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
132
133 GraphicsOutput = NULL;
134 UgaDraw = NULL;
135 //
136 // Open the IO Abstraction(s) needed to perform the supported test
137 //
138 Status = gBS->OpenProtocol (
139 Controller,
140 &gEfiGraphicsOutputProtocolGuid,
141 (VOID **)&GraphicsOutput,
142 This->DriverBindingHandle,
143 Controller,
144 EFI_OPEN_PROTOCOL_BY_DRIVER
145 );
146
147 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
148 //
149 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol
150 //
151 Status = gBS->OpenProtocol (
152 Controller,
153 &gEfiUgaDrawProtocolGuid,
154 (VOID **)&UgaDraw,
155 This->DriverBindingHandle,
156 Controller,
157 EFI_OPEN_PROTOCOL_BY_DRIVER
158 );
159 }
160
161 if (EFI_ERROR (Status)) {
162 return Status;
163 }
164
165 //
166 // We need to ensure that we do not layer on top of a virtual handle.
167 // We need to ensure that the handles produced by the conspliter do not
168 // get used.
169 //
170 Status = gBS->OpenProtocol (
171 Controller,
172 &gEfiDevicePathProtocolGuid,
173 (VOID **)&DevicePath,
174 This->DriverBindingHandle,
175 Controller,
176 EFI_OPEN_PROTOCOL_BY_DRIVER
177 );
178 if (!EFI_ERROR (Status)) {
179 gBS->CloseProtocol (
180 Controller,
181 &gEfiDevicePathProtocolGuid,
182 This->DriverBindingHandle,
183 Controller
184 );
185 } else {
186 goto Error;
187 }
188
189 //
190 // Does Hii Exist? If not, we aren't ready to run
191 //
192 Status = EfiLocateHiiProtocol ();
193
194 //
195 // Close the I/O Abstraction(s) used to perform the supported test
196 //
197Error:
198 if (GraphicsOutput != NULL) {
199 gBS->CloseProtocol (
200 Controller,
201 &gEfiGraphicsOutputProtocolGuid,
202 This->DriverBindingHandle,
203 Controller
204 );
205 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
206 gBS->CloseProtocol (
207 Controller,
208 &gEfiUgaDrawProtocolGuid,
209 This->DriverBindingHandle,
210 Controller
211 );
212 }
213
214 return Status;
215}
216
235 IN UINT32 HorizontalResolution,
236 IN UINT32 VerticalResolution,
237 IN UINT32 GopModeNumber,
238 OUT UINTN *TextModeCount,
239 OUT GRAPHICS_CONSOLE_MODE_DATA **TextModeData
240 )
241{
242 UINTN Index;
243 UINTN Count;
244 GRAPHICS_CONSOLE_MODE_DATA *ModeBuffer;
245 GRAPHICS_CONSOLE_MODE_DATA *NewModeBuffer;
246 UINTN ValidCount;
247 UINTN ValidIndex;
248 UINTN MaxColumns;
249 UINTN MaxRows;
250
251 if ((TextModeCount == NULL) || (TextModeData == NULL)) {
252 return EFI_INVALID_PARAMETER;
253 }
254
255 Count = sizeof (mGraphicsConsoleModeData) / sizeof (GRAPHICS_CONSOLE_MODE_DATA);
256
257 //
258 // Compute the maximum number of text Rows and Columns that this current graphics mode can support.
259 // To make graphics console work well, MaxColumns and MaxRows should not be zero.
260 //
261 MaxColumns = HorizontalResolution / EFI_GLYPH_WIDTH;
262 MaxRows = VerticalResolution / EFI_GLYPH_HEIGHT;
263
264 //
265 // According to UEFI spec, all output devices support at least 80x25 text mode.
266 //
267 ASSERT ((MaxColumns >= 80) && (MaxRows >= 25));
268
269 //
270 // Add full screen mode to the last entry.
271 //
272 mGraphicsConsoleModeData[Count - 1].Columns = MaxColumns;
273 mGraphicsConsoleModeData[Count - 1].Rows = MaxRows;
274
275 //
276 // Get defined mode buffer pointer.
277 //
278 ModeBuffer = mGraphicsConsoleModeData;
279
280 //
281 // Here we make sure that the final mode exposed does not include the duplicated modes,
282 // and does not include the invalid modes which exceed the max column and row.
283 // Reserve 2 modes for 80x25, 80x50 of graphics console.
284 //
285 NewModeBuffer = AllocateZeroPool (sizeof (GRAPHICS_CONSOLE_MODE_DATA) * (Count + 2));
286 ASSERT (NewModeBuffer != NULL);
287
288 //
289 // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
290 //
291 ValidCount = 0;
292
293 NewModeBuffer[ValidCount].Columns = 80;
294 NewModeBuffer[ValidCount].Rows = 25;
295 NewModeBuffer[ValidCount].GopWidth = HorizontalResolution;
296 NewModeBuffer[ValidCount].GopHeight = VerticalResolution;
297 NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;
298 NewModeBuffer[ValidCount].DeltaX = (HorizontalResolution - (NewModeBuffer[ValidCount].Columns * EFI_GLYPH_WIDTH)) >> 1;
299 NewModeBuffer[ValidCount].DeltaY = (VerticalResolution - (NewModeBuffer[ValidCount].Rows * EFI_GLYPH_HEIGHT)) >> 1;
300 ValidCount++;
301
302 if ((MaxColumns >= 80) && (MaxRows >= 50)) {
303 NewModeBuffer[ValidCount].Columns = 80;
304 NewModeBuffer[ValidCount].Rows = 50;
305 NewModeBuffer[ValidCount].DeltaX = (HorizontalResolution - (80 * EFI_GLYPH_WIDTH)) >> 1;
306 NewModeBuffer[ValidCount].DeltaY = (VerticalResolution - (50 * EFI_GLYPH_HEIGHT)) >> 1;
307 }
308
309 NewModeBuffer[ValidCount].GopWidth = HorizontalResolution;
310 NewModeBuffer[ValidCount].GopHeight = VerticalResolution;
311 NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;
312 ValidCount++;
313
314 //
315 // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
316 //
317 for (Index = 0; Index < Count; Index++) {
318 if ((ModeBuffer[Index].Columns == 0) || (ModeBuffer[Index].Rows == 0) ||
319 (ModeBuffer[Index].Columns > MaxColumns) || (ModeBuffer[Index].Rows > MaxRows))
320 {
321 //
322 // Skip the pre-defined mode which is invalid or exceeds the max column and row.
323 //
324 continue;
325 }
326
327 for (ValidIndex = 0; ValidIndex < ValidCount; ValidIndex++) {
328 if ((ModeBuffer[Index].Columns == NewModeBuffer[ValidIndex].Columns) &&
329 (ModeBuffer[Index].Rows == NewModeBuffer[ValidIndex].Rows))
330 {
331 //
332 // Skip the duplicated mode.
333 //
334 break;
335 }
336 }
337
338 if (ValidIndex == ValidCount) {
339 NewModeBuffer[ValidCount].Columns = ModeBuffer[Index].Columns;
340 NewModeBuffer[ValidCount].Rows = ModeBuffer[Index].Rows;
341 NewModeBuffer[ValidCount].GopWidth = HorizontalResolution;
342 NewModeBuffer[ValidCount].GopHeight = VerticalResolution;
343 NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;
344 NewModeBuffer[ValidCount].DeltaX = (HorizontalResolution - (NewModeBuffer[ValidCount].Columns * EFI_GLYPH_WIDTH)) >> 1;
345 NewModeBuffer[ValidCount].DeltaY = (VerticalResolution - (NewModeBuffer[ValidCount].Rows * EFI_GLYPH_HEIGHT)) >> 1;
346 ValidCount++;
347 }
348 }
349
351 for (Index = 0; Index < ValidCount; Index++) {
352 DEBUG ((
353 DEBUG_INFO,
354 "Graphics - Mode %d, Column = %d, Row = %d\n",
355 Index,
356 NewModeBuffer[Index].Columns,
357 NewModeBuffer[Index].Rows
358 ));
359 }
360
362
363 //
364 // Return valid mode count and mode information buffer.
365 //
366 *TextModeCount = ValidCount;
367 *TextModeData = NewModeBuffer;
368 return EFI_SUCCESS;
369}
370
386EFIAPI
389 IN EFI_HANDLE Controller,
390 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
391 )
392{
393 EFI_STATUS Status;
394 GRAPHICS_CONSOLE_DEV *Private;
395 UINT32 HorizontalResolution;
396 UINT32 VerticalResolution;
397 UINT32 ColorDepth;
398 UINT32 RefreshRate;
399 UINT32 ModeIndex;
400 UINTN MaxMode;
401 UINT32 ModeNumber;
403 UINTN SizeOfInfo;
405 INT32 PreferMode;
406 INT32 Index;
407 UINTN Column;
408 UINTN Row;
409 UINTN DefaultColumn;
410 UINTN DefaultRow;
411
412 ModeNumber = 0;
413
414 //
415 // Initialize the Graphics Console device instance
416 //
417 Private = AllocateCopyPool (
418 sizeof (GRAPHICS_CONSOLE_DEV),
419 &mGraphicsConsoleDevTemplate
420 );
421 if (Private == NULL) {
422 return EFI_OUT_OF_RESOURCES;
423 }
424
425 Private->SimpleTextOutput.Mode = &(Private->SimpleTextOutputMode);
426
427 Status = gBS->OpenProtocol (
428 Controller,
429 &gEfiGraphicsOutputProtocolGuid,
430 (VOID **)&Private->GraphicsOutput,
431 This->DriverBindingHandle,
432 Controller,
433 EFI_OPEN_PROTOCOL_BY_DRIVER
434 );
435
436 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
437 Status = gBS->OpenProtocol (
438 Controller,
439 &gEfiUgaDrawProtocolGuid,
440 (VOID **)&Private->UgaDraw,
441 This->DriverBindingHandle,
442 Controller,
443 EFI_OPEN_PROTOCOL_BY_DRIVER
444 );
445 }
446
447 if (EFI_ERROR (Status)) {
448 goto Error;
449 }
450
451 HorizontalResolution = PcdGet32 (PcdVideoHorizontalResolution);
452 VerticalResolution = PcdGet32 (PcdVideoVerticalResolution);
453
454 if (Private->GraphicsOutput != NULL) {
455 //
456 // The console is build on top of Graphics Output Protocol, find the mode number
457 // for the user-defined mode; if there are multiple video devices,
458 // graphic console driver will set all the video devices to the same mode.
459 //
460 if ((HorizontalResolution == 0x0) || (VerticalResolution == 0x0)) {
461 //
462 // Find the highest resolution which GOP supports.
463 //
464 MaxMode = Private->GraphicsOutput->Mode->MaxMode;
465
466 for (ModeIndex = 0; ModeIndex < MaxMode; ModeIndex++) {
467 Status = Private->GraphicsOutput->QueryMode (
468 Private->GraphicsOutput,
469 ModeIndex,
470 &SizeOfInfo,
471 &Info
472 );
473 if (!EFI_ERROR (Status)) {
474 if ((Info->HorizontalResolution > HorizontalResolution) ||
475 ((Info->HorizontalResolution == HorizontalResolution) && (Info->VerticalResolution > VerticalResolution)))
476 {
477 HorizontalResolution = Info->HorizontalResolution;
478 VerticalResolution = Info->VerticalResolution;
479 ModeNumber = ModeIndex;
480 }
481
482 FreePool (Info);
483 }
484 }
485
486 if ((HorizontalResolution == 0x0) || (VerticalResolution == 0x0)) {
487 Status = EFI_UNSUPPORTED;
488 goto Error;
489 }
490 } else {
491 //
492 // Use user-defined resolution
493 //
494 Status = CheckModeSupported (
495 Private->GraphicsOutput,
496 HorizontalResolution,
497 VerticalResolution,
498 &ModeNumber
499 );
500 if (EFI_ERROR (Status)) {
501 //
502 // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec
503 //
504 HorizontalResolution = 800;
505 VerticalResolution = 600;
506 Status = CheckModeSupported (
507 Private->GraphicsOutput,
508 HorizontalResolution,
509 VerticalResolution,
510 &ModeNumber
511 );
512 Mode = Private->GraphicsOutput->Mode;
513 if (EFI_ERROR (Status) && (Mode->MaxMode != 0)) {
514 //
515 // If set default mode failed or device doesn't support default mode, then get the current mode information
516 //
517 HorizontalResolution = Mode->Info->HorizontalResolution;
518 VerticalResolution = Mode->Info->VerticalResolution;
519 ModeNumber = Mode->Mode;
520 }
521 }
522 }
523
524 if (EFI_ERROR (Status) || (ModeNumber != Private->GraphicsOutput->Mode->Mode)) {
525 //
526 // Current graphics mode is not set or is not set to the mode which we have found,
527 // set the new graphic mode.
528 //
529 Status = Private->GraphicsOutput->SetMode (Private->GraphicsOutput, ModeNumber);
530 if (EFI_ERROR (Status)) {
531 //
532 // The mode set operation failed
533 //
534 goto Error;
535 }
536 }
537 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
538 //
539 // At first try to set user-defined resolution
540 //
541 ColorDepth = 32;
542 RefreshRate = 60;
543 Status = Private->UgaDraw->SetMode (
544 Private->UgaDraw,
545 HorizontalResolution,
546 VerticalResolution,
547 ColorDepth,
548 RefreshRate
549 );
550 if (EFI_ERROR (Status)) {
551 //
552 // Try to set 800*600 which is required by UEFI/EFI spec
553 //
554 Status = Private->UgaDraw->SetMode (
555 Private->UgaDraw,
556 800,
557 600,
558 ColorDepth,
559 RefreshRate
560 );
561 if (EFI_ERROR (Status)) {
562 Status = Private->UgaDraw->GetMode (
563 Private->UgaDraw,
564 &HorizontalResolution,
565 &VerticalResolution,
566 &ColorDepth,
567 &RefreshRate
568 );
569 if (EFI_ERROR (Status)) {
570 goto Error;
571 }
572 }
573 }
574 }
575
576 DEBUG ((DEBUG_INFO, "GraphicsConsole video resolution %d x %d\n", HorizontalResolution, VerticalResolution));
577
578 //
579 // Initialize the mode which GraphicsConsole supports.
580 //
582 HorizontalResolution,
583 VerticalResolution,
584 ModeNumber,
585 &MaxMode,
586 &Private->ModeData
587 );
588
589 if (EFI_ERROR (Status)) {
590 goto Error;
591 }
592
593 //
594 // Update the maximum number of modes
595 //
596 Private->SimpleTextOutputMode.MaxMode = (INT32)MaxMode;
597
598 //
599 // Initialize the Mode of graphics console devices
600 //
601 PreferMode = -1;
602 DefaultColumn = PcdGet32 (PcdConOutColumn);
603 DefaultRow = PcdGet32 (PcdConOutRow);
604 Column = 0;
605 Row = 0;
606 for (Index = 0; Index < (INT32)MaxMode; Index++) {
607 if ((DefaultColumn != 0) && (DefaultRow != 0)) {
608 if ((Private->ModeData[Index].Columns == DefaultColumn) &&
609 (Private->ModeData[Index].Rows == DefaultRow))
610 {
611 PreferMode = Index;
612 break;
613 }
614 } else {
615 if ((Private->ModeData[Index].Columns > Column) &&
616 (Private->ModeData[Index].Rows > Row))
617 {
618 Column = Private->ModeData[Index].Columns;
619 Row = Private->ModeData[Index].Rows;
620 PreferMode = Index;
621 }
622 }
623 }
624
625 Private->SimpleTextOutput.Mode->Mode = (INT32)PreferMode;
626 DEBUG ((DEBUG_INFO, "Graphics Console Started, Mode: %d\n", PreferMode));
627
628 //
629 // Install protocol interfaces for the Graphics Console device.
630 //
631 Status = gBS->InstallMultipleProtocolInterfaces (
632 &Controller,
633 &gEfiSimpleTextOutProtocolGuid,
634 &Private->SimpleTextOutput,
635 NULL
636 );
637
638Error:
639 if (EFI_ERROR (Status)) {
640 //
641 // Close the GOP and UGA Draw Protocol
642 //
643 if (Private->GraphicsOutput != NULL) {
644 gBS->CloseProtocol (
645 Controller,
646 &gEfiGraphicsOutputProtocolGuid,
647 This->DriverBindingHandle,
648 Controller
649 );
650 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
651 gBS->CloseProtocol (
652 Controller,
653 &gEfiUgaDrawProtocolGuid,
654 This->DriverBindingHandle,
655 Controller
656 );
657 }
658
659 if (Private->LineBuffer != NULL) {
660 FreePool (Private->LineBuffer);
661 }
662
663 if (Private->ModeData != NULL) {
664 FreePool (Private->ModeData);
665 }
666
667 //
668 // Free private data
669 //
670 FreePool (Private);
671 }
672
673 return Status;
674}
675
695EFIAPI
698 IN EFI_HANDLE Controller,
699 IN UINTN NumberOfChildren,
700 IN EFI_HANDLE *ChildHandleBuffer
701 )
702{
703 EFI_STATUS Status;
704 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOutput;
705 GRAPHICS_CONSOLE_DEV *Private;
706
707 Status = gBS->OpenProtocol (
708 Controller,
709 &gEfiSimpleTextOutProtocolGuid,
710 (VOID **)&SimpleTextOutput,
711 This->DriverBindingHandle,
712 Controller,
713 EFI_OPEN_PROTOCOL_GET_PROTOCOL
714 );
715 if (EFI_ERROR (Status)) {
716 return EFI_NOT_STARTED;
717 }
718
719 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);
720
721 Status = gBS->UninstallProtocolInterface (
722 Controller,
723 &gEfiSimpleTextOutProtocolGuid,
724 &Private->SimpleTextOutput
725 );
726
727 if (!EFI_ERROR (Status)) {
728 //
729 // Close the GOP or UGA IO Protocol
730 //
731 if (Private->GraphicsOutput != NULL) {
732 gBS->CloseProtocol (
733 Controller,
734 &gEfiGraphicsOutputProtocolGuid,
735 This->DriverBindingHandle,
736 Controller
737 );
738 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
739 gBS->CloseProtocol (
740 Controller,
741 &gEfiUgaDrawProtocolGuid,
742 This->DriverBindingHandle,
743 Controller
744 );
745 }
746
747 if (Private->LineBuffer != NULL) {
748 FreePool (Private->LineBuffer);
749 }
750
751 if (Private->ModeData != NULL) {
752 FreePool (Private->ModeData);
753 }
754
755 //
756 // Free our instance data
757 //
758 FreePool (Private);
759 }
760
761 return Status;
762}
763
785 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,
786 IN UINT32 HorizontalResolution,
787 IN UINT32 VerticalResolution,
788 OUT UINT32 *CurrentModeNumber
789 )
790{
791 UINT32 ModeNumber;
792 EFI_STATUS Status;
793 UINTN SizeOfInfo;
795 UINT32 MaxMode;
796
797 Status = EFI_SUCCESS;
798 MaxMode = GraphicsOutput->Mode->MaxMode;
799
800 for (ModeNumber = 0; ModeNumber < MaxMode; ModeNumber++) {
801 Status = GraphicsOutput->QueryMode (
802 GraphicsOutput,
803 ModeNumber,
804 &SizeOfInfo,
805 &Info
806 );
807 if (!EFI_ERROR (Status)) {
808 if ((Info->HorizontalResolution == HorizontalResolution) &&
809 (Info->VerticalResolution == VerticalResolution))
810 {
811 if ((GraphicsOutput->Mode->Info->HorizontalResolution == HorizontalResolution) &&
812 (GraphicsOutput->Mode->Info->VerticalResolution == VerticalResolution))
813 {
814 //
815 // If video device has been set to this mode, we do not need to SetMode again
816 //
817 FreePool (Info);
818 break;
819 } else {
820 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
821 if (!EFI_ERROR (Status)) {
822 FreePool (Info);
823 break;
824 }
825 }
826 }
827
828 FreePool (Info);
829 }
830 }
831
832 if (ModeNumber == GraphicsOutput->Mode->MaxMode) {
833 Status = EFI_UNSUPPORTED;
834 }
835
836 *CurrentModeNumber = ModeNumber;
837 return Status;
838}
839
851 VOID
852 )
853{
854 EFI_STATUS Status;
855
856 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&mHiiDatabase);
857 if (EFI_ERROR (Status)) {
858 return Status;
859 }
860
861 Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **)&mHiiFont);
862 return Status;
863}
864
865//
866// Body of the STO functions
867//
868
888EFIAPI
891 IN BOOLEAN ExtendedVerification
892 )
893{
894 EFI_STATUS Status;
895
896 Status = This->SetMode (This, 0);
897 if (EFI_ERROR (Status)) {
898 return Status;
899 }
900
901 Status = This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));
902 return Status;
903}
904
928EFIAPI
931 IN CHAR16 *WString
932 )
933{
934 GRAPHICS_CONSOLE_DEV *Private;
935 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
936 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
937 INTN Mode;
938 UINTN MaxColumn;
939 UINTN MaxRow;
940 UINTN Width;
941 UINTN Height;
942 UINTN Delta;
943 EFI_STATUS Status;
944 BOOLEAN Warning;
947 UINTN DeltaX;
948 UINTN DeltaY;
949 UINTN Count;
950 UINTN Index;
951 INT32 OriginAttribute;
952 EFI_TPL OldTpl;
953
954 if (This->Mode->Mode == -1) {
955 //
956 // If current mode is not valid, return error.
957 //
958 return EFI_UNSUPPORTED;
959 }
960
961 Status = EFI_SUCCESS;
962
963 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
964 //
965 // Current mode
966 //
967 Mode = This->Mode->Mode;
968 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
969 GraphicsOutput = Private->GraphicsOutput;
970 UgaDraw = Private->UgaDraw;
971
972 MaxColumn = Private->ModeData[Mode].Columns;
973 MaxRow = Private->ModeData[Mode].Rows;
974 DeltaX = (UINTN)Private->ModeData[Mode].DeltaX;
975 DeltaY = (UINTN)Private->ModeData[Mode].DeltaY;
976 Width = MaxColumn * EFI_GLYPH_WIDTH;
977 Height = (MaxRow - 1) * EFI_GLYPH_HEIGHT;
978 Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
979
980 //
981 // The Attributes won't change when during the time OutputString is called
982 //
983 GetTextColors (This, &Foreground, &Background);
984
985 FlushCursor (This);
986
987 Warning = FALSE;
988
989 //
990 // Backup attribute
991 //
992 OriginAttribute = This->Mode->Attribute;
993
994 while (*WString != L'\0') {
995 if (*WString == CHAR_BACKSPACE) {
996 //
997 // If the cursor is at the left edge of the display, then move the cursor
998 // one row up.
999 //
1000 if ((This->Mode->CursorColumn == 0) && (This->Mode->CursorRow > 0)) {
1001 This->Mode->CursorRow--;
1002 This->Mode->CursorColumn = (INT32)(MaxColumn - 1);
1003 This->OutputString (This, SpaceStr);
1004 FlushCursor (This);
1005 This->Mode->CursorRow--;
1006 This->Mode->CursorColumn = (INT32)(MaxColumn - 1);
1007 } else if (This->Mode->CursorColumn > 0) {
1008 //
1009 // If the cursor is not at the left edge of the display, then move the cursor
1010 // left one column.
1011 //
1012 This->Mode->CursorColumn--;
1013 This->OutputString (This, SpaceStr);
1014 FlushCursor (This);
1015 This->Mode->CursorColumn--;
1016 }
1017
1018 WString++;
1019 } else if (*WString == CHAR_LINEFEED) {
1020 //
1021 // If the cursor is at the bottom of the display, then scroll the display one
1022 // row, and do not update the cursor position. Otherwise, move the cursor
1023 // down one row.
1024 //
1025 if (This->Mode->CursorRow == (INT32)(MaxRow - 1)) {
1026 if (GraphicsOutput != NULL) {
1027 //
1028 // Scroll Screen Up One Row
1029 //
1030 GraphicsOutput->Blt (
1031 GraphicsOutput,
1032 NULL,
1034 DeltaX,
1035 DeltaY + EFI_GLYPH_HEIGHT,
1036 DeltaX,
1037 DeltaY,
1038 Width,
1039 Height,
1040 Delta
1041 );
1042
1043 //
1044 // Print Blank Line at last line
1045 //
1046 GraphicsOutput->Blt (
1047 GraphicsOutput,
1048 &Background,
1050 0,
1051 0,
1052 DeltaX,
1053 DeltaY + Height,
1054 Width,
1055 EFI_GLYPH_HEIGHT,
1056 Delta
1057 );
1058 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1059 //
1060 // Scroll Screen Up One Row
1061 //
1062 UgaDraw->Blt (
1063 UgaDraw,
1064 NULL,
1066 DeltaX,
1067 DeltaY + EFI_GLYPH_HEIGHT,
1068 DeltaX,
1069 DeltaY,
1070 Width,
1071 Height,
1072 Delta
1073 );
1074
1075 //
1076 // Print Blank Line at last line
1077 //
1078 UgaDraw->Blt (
1079 UgaDraw,
1080 (EFI_UGA_PIXEL *)(UINTN)&Background,
1082 0,
1083 0,
1084 DeltaX,
1085 DeltaY + Height,
1086 Width,
1087 EFI_GLYPH_HEIGHT,
1088 Delta
1089 );
1090 }
1091 } else {
1092 This->Mode->CursorRow++;
1093 }
1094
1095 WString++;
1096 } else if (*WString == CHAR_CARRIAGE_RETURN) {
1097 //
1098 // Move the cursor to the beginning of the current row.
1099 //
1100 This->Mode->CursorColumn = 0;
1101 WString++;
1102 } else if (*WString == WIDE_CHAR) {
1103 This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;
1104 WString++;
1105 } else if (*WString == NARROW_CHAR) {
1106 This->Mode->Attribute &= (~(UINT32)EFI_WIDE_ATTRIBUTE);
1107 WString++;
1108 } else {
1109 //
1110 // Print the character at the current cursor position and move the cursor
1111 // right one column. If this moves the cursor past the right edge of the
1112 // display, then the line should wrap to the beginning of the next line. This
1113 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
1114 // bottom of the display, and the line wraps, then the display will be scrolled
1115 // one line.
1116 // If wide char is going to be displayed, need to display one character at a time
1117 // Or, need to know the display length of a certain string.
1118 //
1119 // Index is used to determine how many character width units (wide = 2, narrow = 1)
1120 // Count is used to determine how many characters are used regardless of their attributes
1121 //
1122 for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {
1123 if ((WString[Count] == CHAR_NULL) ||
1124 (WString[Count] == CHAR_BACKSPACE) ||
1125 (WString[Count] == CHAR_LINEFEED) ||
1126 (WString[Count] == CHAR_CARRIAGE_RETURN) ||
1127 (WString[Count] == WIDE_CHAR) ||
1128 (WString[Count] == NARROW_CHAR))
1129 {
1130 break;
1131 }
1132
1133 //
1134 // Is the wide attribute on?
1135 //
1136 if ((This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) != 0) {
1137 //
1138 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
1139 //
1140 Index++;
1141 //
1142 // This is the end-case where if we are at column 79 and about to print a wide character
1143 // We should prevent this from happening because we will wrap inappropriately. We should
1144 // not print this character until the next line.
1145 //
1146 if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {
1147 Index++;
1148 break;
1149 }
1150 }
1151 }
1152
1153 Status = DrawUnicodeWeightAtCursorN (This, WString, Count);
1154 if (EFI_ERROR (Status)) {
1155 Warning = TRUE;
1156 }
1157
1158 //
1159 // At the end of line, output carriage return and line feed
1160 //
1161 WString += Count;
1162 This->Mode->CursorColumn += (INT32)Index;
1163 if (This->Mode->CursorColumn > (INT32)MaxColumn) {
1164 This->Mode->CursorColumn -= 2;
1165 This->OutputString (This, SpaceStr);
1166 }
1167
1168 if (This->Mode->CursorColumn >= (INT32)MaxColumn) {
1169 FlushCursor (This);
1170 This->OutputString (This, mCrLfString);
1171 FlushCursor (This);
1172 }
1173 }
1174 }
1175
1176 This->Mode->Attribute = OriginAttribute;
1177
1178 FlushCursor (This);
1179
1180 if (Warning) {
1181 Status = EFI_WARN_UNKNOWN_GLYPH;
1182 }
1183
1184 gBS->RestoreTPL (OldTpl);
1185 return Status;
1186}
1187
1208EFIAPI
1211 IN CHAR16 *WString
1212 )
1213{
1214 EFI_STATUS Status;
1215 UINT16 Count;
1216
1217 EFI_IMAGE_OUTPUT *Blt;
1218
1219 Blt = NULL;
1220 Count = 0;
1221
1222 while (WString[Count] != 0) {
1223 Status = mHiiFont->GetGlyph (
1224 mHiiFont,
1225 WString[Count],
1226 NULL,
1227 &Blt,
1228 NULL
1229 );
1230 if (Blt != NULL) {
1231 FreePool (Blt);
1232 Blt = NULL;
1233 }
1234
1235 Count++;
1236
1237 if (EFI_ERROR (Status)) {
1238 return EFI_UNSUPPORTED;
1239 }
1240 }
1241
1242 return EFI_SUCCESS;
1243}
1244
1263EFIAPI
1266 IN UINTN ModeNumber,
1267 OUT UINTN *Columns,
1268 OUT UINTN *Rows
1269 )
1270{
1271 GRAPHICS_CONSOLE_DEV *Private;
1272 EFI_STATUS Status;
1273 EFI_TPL OldTpl;
1274
1275 if (ModeNumber >= (UINTN)This->Mode->MaxMode) {
1276 return EFI_UNSUPPORTED;
1277 }
1278
1279 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1280 Status = EFI_SUCCESS;
1281
1282 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1283
1284 *Columns = Private->ModeData[ModeNumber].Columns;
1285 *Rows = Private->ModeData[ModeNumber].Rows;
1286
1287 if ((*Columns <= 0) || (*Rows <= 0)) {
1288 Status = EFI_UNSUPPORTED;
1289 goto Done;
1290 }
1291
1292Done:
1293 gBS->RestoreTPL (OldTpl);
1294 return Status;
1295}
1296
1313EFIAPI
1316 IN UINTN ModeNumber
1317 )
1318{
1319 EFI_STATUS Status;
1320 GRAPHICS_CONSOLE_DEV *Private;
1322 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewLineBuffer;
1323 UINT32 HorizontalResolution;
1324 UINT32 VerticalResolution;
1325 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1326 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1327 UINT32 ColorDepth;
1328 UINT32 RefreshRate;
1329 EFI_TPL OldTpl;
1330
1331 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1332
1333 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1334 GraphicsOutput = Private->GraphicsOutput;
1335 UgaDraw = Private->UgaDraw;
1336
1337 //
1338 // Make sure the requested mode number is supported
1339 //
1340 if (ModeNumber >= (UINTN)This->Mode->MaxMode) {
1341 Status = EFI_UNSUPPORTED;
1342 goto Done;
1343 }
1344
1345 ModeData = &(Private->ModeData[ModeNumber]);
1346
1347 if ((ModeData->Columns <= 0) && (ModeData->Rows <= 0)) {
1348 Status = EFI_UNSUPPORTED;
1349 goto Done;
1350 }
1351
1352 //
1353 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1354 //
1355 if (Private->LineBuffer != NULL) {
1356 //
1357 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1358 //
1359 if ((INT32)ModeNumber == This->Mode->Mode) {
1360 //
1361 // Clear the current text window on the current graphics console
1362 //
1363 This->ClearScreen (This);
1364 Status = EFI_SUCCESS;
1365 goto Done;
1366 }
1367
1368 //
1369 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,
1370 // so erase the cursor, and free the LineBuffer for the current mode
1371 //
1372 FlushCursor (This);
1373
1374 FreePool (Private->LineBuffer);
1375 }
1376
1377 //
1378 // Attempt to allocate a line buffer for the requested mode number
1379 //
1380 NewLineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT);
1381
1382 if (NewLineBuffer == NULL) {
1383 //
1384 // The new line buffer could not be allocated, so return an error.
1385 // No changes to the state of the current console have been made, so the current console is still valid
1386 //
1387 Status = EFI_OUT_OF_RESOURCES;
1388 goto Done;
1389 }
1390
1391 //
1392 // Assign the current line buffer to the newly allocated line buffer
1393 //
1394 Private->LineBuffer = NewLineBuffer;
1395
1396 if (GraphicsOutput != NULL) {
1397 if (ModeData->GopModeNumber != GraphicsOutput->Mode->Mode) {
1398 //
1399 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1400 //
1401 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeData->GopModeNumber);
1402 if (EFI_ERROR (Status)) {
1403 //
1404 // The mode set operation failed
1405 //
1406 goto Done;
1407 }
1408 } else {
1409 //
1410 // The current graphics mode is correct, so simply clear the entire display
1411 //
1412 Status = GraphicsOutput->Blt (
1413 GraphicsOutput,
1414 &mGraphicsEfiColors[0],
1416 0,
1417 0,
1418 0,
1419 0,
1420 ModeData->GopWidth,
1421 ModeData->GopHeight,
1422 0
1423 );
1424 }
1425 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1426 //
1427 // Get the current UGA Draw mode information
1428 //
1429 Status = UgaDraw->GetMode (
1430 UgaDraw,
1431 &HorizontalResolution,
1432 &VerticalResolution,
1433 &ColorDepth,
1434 &RefreshRate
1435 );
1436 if (EFI_ERROR (Status) || (HorizontalResolution != ModeData->GopWidth) || (VerticalResolution != ModeData->GopHeight)) {
1437 //
1438 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1439 //
1440 Status = UgaDraw->SetMode (
1441 UgaDraw,
1442 ModeData->GopWidth,
1443 ModeData->GopHeight,
1444 32,
1445 60
1446 );
1447 if (EFI_ERROR (Status)) {
1448 //
1449 // The mode set operation failed
1450 //
1451 goto Done;
1452 }
1453 } else {
1454 //
1455 // The current graphics mode is correct, so simply clear the entire display
1456 //
1457 Status = UgaDraw->Blt (
1458 UgaDraw,
1459 (EFI_UGA_PIXEL *)(UINTN)&mGraphicsEfiColors[0],
1461 0,
1462 0,
1463 0,
1464 0,
1465 ModeData->GopWidth,
1466 ModeData->GopHeight,
1467 0
1468 );
1469 }
1470 }
1471
1472 //
1473 // The new mode is valid, so commit the mode change
1474 //
1475 This->Mode->Mode = (INT32)ModeNumber;
1476
1477 //
1478 // Move the text cursor to the upper left hand corner of the display and flush it
1479 //
1480 This->Mode->CursorColumn = 0;
1481 This->Mode->CursorRow = 0;
1482
1483 FlushCursor (This);
1484
1485 Status = EFI_SUCCESS;
1486
1487Done:
1488 gBS->RestoreTPL (OldTpl);
1489 return Status;
1490}
1491
1509EFIAPI
1512 IN UINTN Attribute
1513 )
1514{
1515 EFI_TPL OldTpl;
1516
1517 if ((Attribute | 0x7F) != 0x7F) {
1518 return EFI_UNSUPPORTED;
1519 }
1520
1521 if ((INT32)Attribute == This->Mode->Attribute) {
1522 return EFI_SUCCESS;
1523 }
1524
1525 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1526
1527 FlushCursor (This);
1528
1529 This->Mode->Attribute = (INT32)Attribute;
1530
1531 FlushCursor (This);
1532
1533 gBS->RestoreTPL (OldTpl);
1534
1535 return EFI_SUCCESS;
1536}
1537
1552EFIAPI
1555 )
1556{
1557 EFI_STATUS Status;
1558 GRAPHICS_CONSOLE_DEV *Private;
1560 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1561 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1564 EFI_TPL OldTpl;
1565
1566 if (This->Mode->Mode == -1) {
1567 //
1568 // If current mode is not valid, return error.
1569 //
1570 return EFI_UNSUPPORTED;
1571 }
1572
1573 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1574
1575 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1576 GraphicsOutput = Private->GraphicsOutput;
1577 UgaDraw = Private->UgaDraw;
1578 ModeData = &(Private->ModeData[This->Mode->Mode]);
1579
1580 GetTextColors (This, &Foreground, &Background);
1581 if (GraphicsOutput != NULL) {
1582 Status = GraphicsOutput->Blt (
1583 GraphicsOutput,
1584 &Background,
1586 0,
1587 0,
1588 0,
1589 0,
1590 ModeData->GopWidth,
1591 ModeData->GopHeight,
1592 0
1593 );
1594 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1595 Status = UgaDraw->Blt (
1596 UgaDraw,
1597 (EFI_UGA_PIXEL *)(UINTN)&Background,
1599 0,
1600 0,
1601 0,
1602 0,
1603 ModeData->GopWidth,
1604 ModeData->GopHeight,
1605 0
1606 );
1607 } else {
1608 Status = EFI_UNSUPPORTED;
1609 }
1610
1611 This->Mode->CursorColumn = 0;
1612 This->Mode->CursorRow = 0;
1613
1614 FlushCursor (This);
1615
1616 gBS->RestoreTPL (OldTpl);
1617
1618 return Status;
1619}
1620
1641EFIAPI
1644 IN UINTN Column,
1645 IN UINTN Row
1646 )
1647{
1648 GRAPHICS_CONSOLE_DEV *Private;
1650 EFI_STATUS Status;
1651 EFI_TPL OldTpl;
1652
1653 if (This->Mode->Mode == -1) {
1654 //
1655 // If current mode is not valid, return error.
1656 //
1657 return EFI_UNSUPPORTED;
1658 }
1659
1660 Status = EFI_SUCCESS;
1661
1662 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1663
1664 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1665 ModeData = &(Private->ModeData[This->Mode->Mode]);
1666
1667 if ((Column >= ModeData->Columns) || (Row >= ModeData->Rows)) {
1668 Status = EFI_UNSUPPORTED;
1669 goto Done;
1670 }
1671
1672 if ((This->Mode->CursorColumn == (INT32)Column) && (This->Mode->CursorRow == (INT32)Row)) {
1673 Status = EFI_SUCCESS;
1674 goto Done;
1675 }
1676
1677 FlushCursor (This);
1678
1679 This->Mode->CursorColumn = (INT32)Column;
1680 This->Mode->CursorRow = (INT32)Row;
1681
1682 FlushCursor (This);
1683
1684Done:
1685 gBS->RestoreTPL (OldTpl);
1686
1687 return Status;
1688}
1689
1705EFIAPI
1708 IN BOOLEAN Visible
1709 )
1710{
1711 EFI_TPL OldTpl;
1712
1713 if (This->Mode->Mode == -1) {
1714 //
1715 // If current mode is not valid, return error.
1716 //
1717 return EFI_UNSUPPORTED;
1718 }
1719
1720 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1721
1722 FlushCursor (This);
1723
1724 This->Mode->CursorVisible = Visible;
1725
1726 FlushCursor (This);
1727
1728 gBS->RestoreTPL (OldTpl);
1729 return EFI_SUCCESS;
1730}
1731
1747 )
1748{
1749 INTN Attribute;
1750
1751 Attribute = This->Mode->Attribute & 0x7F;
1752
1753 *Foreground = mGraphicsEfiColors[Attribute & 0x0f];
1754 *Background = mGraphicsEfiColors[Attribute >> 4];
1755
1756 return EFI_SUCCESS;
1757}
1758
1775 IN CHAR16 *UnicodeWeight,
1776 IN UINTN Count
1777 )
1778{
1779 EFI_STATUS Status;
1780 GRAPHICS_CONSOLE_DEV *Private;
1781 EFI_IMAGE_OUTPUT *Blt;
1782 EFI_STRING String;
1783 EFI_FONT_DISPLAY_INFO *FontInfo;
1784 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1785 EFI_HII_ROW_INFO *RowInfoArray;
1786 UINTN RowInfoArraySize;
1787
1788 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1790 if (Blt == NULL) {
1791 return EFI_OUT_OF_RESOURCES;
1792 }
1793
1794 Blt->Width = (UINT16)(Private->ModeData[This->Mode->Mode].GopWidth);
1795 Blt->Height = (UINT16)(Private->ModeData[This->Mode->Mode].GopHeight);
1796
1797 String = AllocateCopyPool ((Count + 1) * sizeof (CHAR16), UnicodeWeight);
1798 if (String == NULL) {
1799 FreePool (Blt);
1800 return EFI_OUT_OF_RESOURCES;
1801 }
1802
1803 //
1804 // Set the end character
1805 //
1806 *(String + Count) = L'\0';
1807
1809 if (FontInfo == NULL) {
1810 FreePool (Blt);
1811 FreePool (String);
1812 return EFI_OUT_OF_RESOURCES;
1813 }
1814
1815 //
1816 // Get current foreground and background colors.
1817 //
1818 GetTextColors (This, &FontInfo->ForegroundColor, &FontInfo->BackgroundColor);
1819
1820 if (Private->GraphicsOutput != NULL) {
1821 //
1822 // If Graphics Output protocol exists, using HII Font protocol to draw.
1823 //
1824 Blt->Image.Screen = Private->GraphicsOutput;
1825
1826 Status = mHiiFont->StringToImage (
1827 mHiiFont,
1828 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN | EFI_HII_IGNORE_LINE_BREAK,
1829 String,
1830 FontInfo,
1831 &Blt,
1832 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
1833 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
1834 NULL,
1835 NULL,
1836 NULL
1837 );
1838 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1839 //
1840 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,
1841 // using UGA Draw protocol to draw.
1842 //
1843 ASSERT (Private->UgaDraw != NULL);
1844
1845 UgaDraw = Private->UgaDraw;
1846
1847 Blt->Image.Bitmap = AllocateZeroPool (Blt->Width * Blt->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
1848 if (Blt->Image.Bitmap == NULL) {
1849 FreePool (Blt);
1850 FreePool (String);
1851 return EFI_OUT_OF_RESOURCES;
1852 }
1853
1854 RowInfoArray = NULL;
1855 //
1856 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,
1857 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.
1858 //
1859 Status = mHiiFont->StringToImage (
1860 mHiiFont,
1861 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK,
1862 String,
1863 FontInfo,
1864 &Blt,
1865 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
1866 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
1867 &RowInfoArray,
1868 &RowInfoArraySize,
1869 NULL
1870 );
1871
1872 if (!EFI_ERROR (Status)) {
1873 //
1874 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will
1875 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.
1876 //
1877 ASSERT (RowInfoArraySize <= 1);
1878
1879 Status = UgaDraw->Blt (
1880 UgaDraw,
1881 (EFI_UGA_PIXEL *)Blt->Image.Bitmap,
1883 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
1884 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
1885 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
1886 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
1887 RowInfoArray[0].LineWidth,
1888 RowInfoArray[0].LineHeight,
1889 Blt->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
1890 );
1891 }
1892
1893 FreePool (RowInfoArray);
1894 FreePool (Blt->Image.Bitmap);
1895 } else {
1896 Status = EFI_UNSUPPORTED;
1897 }
1898
1899 if (Blt != NULL) {
1900 FreePool (Blt);
1901 }
1902
1903 if (String != NULL) {
1904 FreePool (String);
1905 }
1906
1907 if (FontInfo != NULL) {
1908 FreePool (FontInfo);
1909 }
1910
1911 return Status;
1912}
1913
1930 )
1931{
1932 GRAPHICS_CONSOLE_DEV *Private;
1933 EFI_SIMPLE_TEXT_OUTPUT_MODE *CurrentMode;
1934 INTN GlyphX;
1935 INTN GlyphY;
1936 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1937 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1940 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar[EFI_GLYPH_HEIGHT][EFI_GLYPH_WIDTH];
1941 UINTN PosX;
1942 UINTN PosY;
1943
1944 CurrentMode = This->Mode;
1945
1946 if (!CurrentMode->CursorVisible) {
1947 return EFI_SUCCESS;
1948 }
1949
1950 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1951 GraphicsOutput = Private->GraphicsOutput;
1952 UgaDraw = Private->UgaDraw;
1953
1954 //
1955 // In this driver, only narrow character was supported.
1956 //
1957 //
1958 // Blt a character to the screen
1959 //
1960 GlyphX = (CurrentMode->CursorColumn * EFI_GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;
1961 GlyphY = (CurrentMode->CursorRow * EFI_GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;
1962 if (GraphicsOutput != NULL) {
1963 GraphicsOutput->Blt (
1964 GraphicsOutput,
1967 GlyphX,
1968 GlyphY,
1969 0,
1970 0,
1971 EFI_GLYPH_WIDTH,
1972 EFI_GLYPH_HEIGHT,
1973 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
1974 );
1975 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1976 UgaDraw->Blt (
1977 UgaDraw,
1978 (EFI_UGA_PIXEL *)(UINTN)BltChar,
1980 GlyphX,
1981 GlyphY,
1982 0,
1983 0,
1984 EFI_GLYPH_WIDTH,
1985 EFI_GLYPH_HEIGHT,
1986 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
1987 );
1988 }
1989
1990 GetTextColors (This, &Foreground.Pixel, &Background.Pixel);
1991
1992 //
1993 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1994 //
1995 for (PosY = 0; PosY < EFI_GLYPH_HEIGHT; PosY++) {
1996 for (PosX = 0; PosX < EFI_GLYPH_WIDTH; PosX++) {
1997 if ((mCursorGlyph.GlyphCol1[PosY] & (BIT0 << PosX)) != 0) {
1998 BltChar[PosY][EFI_GLYPH_WIDTH - PosX - 1].Raw ^= Foreground.Raw;
1999 }
2000 }
2001 }
2002
2003 if (GraphicsOutput != NULL) {
2004 GraphicsOutput->Blt (
2005 GraphicsOutput,
2008 0,
2009 0,
2010 GlyphX,
2011 GlyphY,
2012 EFI_GLYPH_WIDTH,
2013 EFI_GLYPH_HEIGHT,
2014 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
2015 );
2016 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
2017 UgaDraw->Blt (
2018 UgaDraw,
2019 (EFI_UGA_PIXEL *)(UINTN)BltChar,
2021 0,
2022 0,
2023 GlyphX,
2024 GlyphY,
2025 EFI_GLYPH_WIDTH,
2026 EFI_GLYPH_HEIGHT,
2027 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
2028 );
2029 }
2030
2031 return EFI_SUCCESS;
2032}
2033
2042VOID
2043EFIAPI
2045 IN EFI_EVENT Event,
2046 IN VOID *Context
2047 )
2048{
2049 EFI_STATUS Status;
2050 EFI_HII_SIMPLE_FONT_PACKAGE_HDR *SimplifiedFont;
2051 UINT32 PackageLength;
2052 UINT8 *Package;
2053 UINT8 *Location;
2054 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
2055
2056 //
2057 // Locate HII Database Protocol
2058 //
2059 Status = gBS->LocateProtocol (
2060 &gEfiHiiDatabaseProtocolGuid,
2061 NULL,
2062 (VOID **)&HiiDatabase
2063 );
2064 if (EFI_ERROR (Status)) {
2065 return;
2066 }
2067
2068 //
2069 // Add 4 bytes to the header for entire length for HiiAddPackages use only.
2070 //
2071 // +--------------------------------+ <-- Package
2072 // | |
2073 // | PackageLength(4 bytes) |
2074 // | |
2075 // |--------------------------------| <-- SimplifiedFont
2076 // | |
2077 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
2078 // | |
2079 // |--------------------------------| <-- Location
2080 // | |
2081 // | gUsStdNarrowGlyphData |
2082 // | |
2083 // +--------------------------------+
2084
2085 PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + mNarrowFontSize + 4;
2086 Package = AllocateZeroPool (PackageLength);
2087 ASSERT (Package != NULL);
2088
2089 WriteUnaligned32 ((UINT32 *)Package, PackageLength);
2090 SimplifiedFont = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR *)(Package + 4);
2091 SimplifiedFont->Header.Length = (UINT32)(PackageLength - 4);
2092 SimplifiedFont->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;
2093 SimplifiedFont->NumberOfNarrowGlyphs = (UINT16)(mNarrowFontSize / sizeof (EFI_NARROW_GLYPH));
2094
2095 Location = (UINT8 *)(&SimplifiedFont->NumberOfWideGlyphs + 1);
2096 CopyMem (Location, gUsStdNarrowGlyphData, mNarrowFontSize);
2097
2098 //
2099 // Add this simplified font package to a package list then install it.
2100 //
2101 mHiiHandle = HiiAddPackages (
2102 &mFontPackageListGuid,
2103 NULL,
2104 Package,
2105 NULL
2106 );
2107 ASSERT (mHiiHandle != NULL);
2108 FreePool (Package);
2109}
2110
2122EFIAPI
2124 IN EFI_HANDLE ImageHandle,
2125 IN EFI_SYSTEM_TABLE *SystemTable
2126 )
2127{
2128 EFI_STATUS Status;
2129
2130 //
2131 // Register notify function on HII Database Protocol to add font package.
2132 //
2134 &gEfiHiiDatabaseProtocolGuid,
2135 TPL_CALLBACK,
2137 NULL,
2138 &mHiiRegistration
2139 );
2140
2141 //
2142 // Install driver model protocol(s).
2143 //
2145 ImageHandle,
2146 SystemTable,
2147 &gGraphicsConsoleDriverBinding,
2148 ImageHandle,
2149 &gGraphicsConsoleComponentName,
2150 &gGraphicsConsoleComponentName2
2151 );
2152 ASSERT_EFI_ERROR (Status);
2153
2154 return Status;
2155}
UINT64 UINTN
INT64 INTN
UINT32 EFIAPI WriteUnaligned32(OUT UINT32 *Buffer, IN UINT32 Value)
Definition: Unaligned.c:177
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
EFI_STATUS EFIAPI GraphicsConsoleConOutQueryMode(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN ModeNumber, OUT UINTN *Columns, OUT UINTN *Rows)
EFI_STATUS EFIAPI GraphicsConsoleConOutSetAttribute(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN Attribute)
EFI_STATUS DrawUnicodeWeightAtCursorN(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *UnicodeWeight, IN UINTN Count)
EFI_STATUS EFIAPI InitializeGraphicsConsole(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS EFIAPI GraphicsConsoleConOutClearScreen(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This)
EFI_STATUS InitializeGraphicsConsoleTextMode(IN UINT32 HorizontalResolution, IN UINT32 VerticalResolution, IN UINT32 GopModeNumber, OUT UINTN *TextModeCount, OUT GRAPHICS_CONSOLE_MODE_DATA **TextModeData)
EFI_STATUS EFIAPI GraphicsConsoleConOutSetMode(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN ModeNumber)
EFI_STATUS EFIAPI GraphicsConsoleConOutEnableCursor(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN BOOLEAN Visible)
EFI_STATUS EFIAPI GraphicsConsoleControllerDriverStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
VOID EFIAPI RegisterFontPackage(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS EFIAPI GraphicsConsoleConOutTestString(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *WString)
EFI_STATUS EfiLocateHiiProtocol(VOID)
EFI_STATUS EFIAPI GraphicsConsoleControllerDriverStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
EFI_STATUS EFIAPI GraphicsConsoleConOutReset(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
EFI_STATUS EFIAPI GraphicsConsoleConOutSetCursorPosition(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN Column, IN UINTN Row)
EFI_STATUS EFIAPI GraphicsConsoleControllerDriverSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
EFI_STATUS EFIAPI GraphicsConsoleConOutOutputString(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *WString)
EFI_STATUS CheckModeSupported(EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput, IN UINT32 HorizontalResolution, IN UINT32 VerticalResolution, OUT UINT32 *CurrentModeNumber)
EFI_STATUS GetTextColors(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground, OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background)
EFI_STATUS FlushCursor(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This)
EFI_HII_HANDLE EFIAPI HiiAddPackages(IN CONST EFI_GUID *PackageListGuid, IN EFI_HANDLE DeviceHandle OPTIONAL,...)
Definition: HiiLib.c:141
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
@ EfiBltVideoToBltBuffer
@ EfiBltBufferToVideo
@ EfiBltVideoFill
@ EfiBltVideoToVideo
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
VOID * EFI_HII_HANDLE
struct _EFI_HII_SIMPLE_FONT_PACKAGE_HDR EFI_HII_SIMPLE_FONT_PACKAGE_HDR
EFI_EVENT EFIAPI EfiCreateProtocolNotifyEvent(IN EFI_GUID *ProtocolGuid, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext OPTIONAL, OUT VOID **Registration)
Definition: UefiLib.c:134
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
@ EfiUgaVideoToVideo
Definition: UgaDraw.h:103
@ EfiUgaVideoToBltBuffer
Definition: UgaDraw.h:89
@ EfiUgaBltBufferToVideo
Definition: UgaDraw.h:96
@ EfiUgaVideoFill
Definition: UgaDraw.h:84
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE * Mode
UINTN LineHeight
The height of the line, in pixels.
Definition: HiiFont.h:52
UINTN LineWidth
The width of the text on the line, in pixels.
Definition: HiiFont.h:53
EFI_SIMPLE_TEXT_OUTPUT_MODE * Mode
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION * Info
UINT8 GlyphCol1[EFI_GLYPH_HEIGHT]
Definition: Base.h:213