]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.c
6cea2e11b60def5cecdf8996a12a1152fc82e243
[mirror_edk2.git] / EdkModulePkg / Universal / Console / GraphicsConsole / Dxe / GraphicsConsole.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 GraphicsConsole.c
15
16 Abstract:
17
18 This is the main routine for initializing the Graphics Console support routines.
19
20 Revision History
21
22 Remaining Tasks
23 Add all standard Glyphs from EFI 1.02 Specification
24 Implement optimal automatic Mode creation algorithm
25 Solve palette issues for mixed graphics and text
26 When does this protocol reset the palette?
27
28 --*/
29
30 #include "GraphicsConsole.h"
31
32 //
33 // Function Prototypes
34 //
35 EFI_STATUS
36 EFIAPI
37 GraphicsConsoleControllerDriverSupported (
38 IN EFI_DRIVER_BINDING_PROTOCOL *This,
39 IN EFI_HANDLE Controller,
40 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
41 );
42
43 EFI_STATUS
44 EFIAPI
45 GraphicsConsoleControllerDriverStart (
46 IN EFI_DRIVER_BINDING_PROTOCOL *This,
47 IN EFI_HANDLE Controller,
48 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
49 );
50
51 EFI_STATUS
52 EFIAPI
53 GraphicsConsoleControllerDriverStop (
54 IN EFI_DRIVER_BINDING_PROTOCOL *This,
55 IN EFI_HANDLE Controller,
56 IN UINTN NumberOfChildren,
57 IN EFI_HANDLE *ChildHandleBuffer
58 );
59
60 EFI_STATUS
61 GetTextColors (
62 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
63 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,
64 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background
65 );
66
67 EFI_STATUS
68 DrawUnicodeWeightAtCursor (
69 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
70 IN CHAR16 UnicodeWeight
71 );
72
73 EFI_STATUS
74 DrawUnicodeWeightAtCursorN (
75 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
76 IN CHAR16 *UnicodeWeight,
77 IN UINTN Count
78 );
79
80 EFI_STATUS
81 EraseCursor (
82 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This
83 );
84
85 //
86 // Globals
87 //
88 GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate = {
89 GRAPHICS_CONSOLE_DEV_SIGNATURE,
90 (EFI_GRAPHICS_OUTPUT_PROTOCOL *) NULL,
91 (EFI_UGA_DRAW_PROTOCOL *) NULL,
92 {
93 GraphicsConsoleConOutReset,
94 GraphicsConsoleConOutOutputString,
95 GraphicsConsoleConOutTestString,
96 GraphicsConsoleConOutQueryMode,
97 GraphicsConsoleConOutSetMode,
98 GraphicsConsoleConOutSetAttribute,
99 GraphicsConsoleConOutClearScreen,
100 GraphicsConsoleConOutSetCursorPosition,
101 GraphicsConsoleConOutEnableCursor,
102 (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL
103 },
104 {
105 0,
106 0,
107 EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_BLACK),
108 0,
109 0,
110 TRUE
111 },
112 {
113 { 80, 25, 0, 0, 0, 0 }, // Mode 0
114 { 80, 50, 0, 0, 0, 0 }, // Mode 1
115 { 0, 0, 0, 0, 0, 0 } // Mode 2
116 },
117 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,
118 (EFI_HII_HANDLE) 0
119 };
120
121 EFI_HII_PROTOCOL *mHii;
122
123 static CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };
124
125 static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {
126 //
127 // B G R
128 //
129 0x00, 0x00, 0x00, 0x00, // BLACK
130 0x98, 0x00, 0x00, 0x00, // BLUE
131 0x00, 0x98, 0x00, 0x00, // GREEN
132 0x98, 0x98, 0x00, 0x00, // CYAN
133 0x00, 0x00, 0x98, 0x00, // RED
134 0x98, 0x00, 0x98, 0x00, // MAGENTA
135 0x00, 0x98, 0x98, 0x00, // BROWN
136 0x98, 0x98, 0x98, 0x00, // LIGHTGRAY
137 0x30, 0x30, 0x30, 0x00, // DARKGRAY - BRIGHT BLACK
138 0xff, 0x00, 0x00, 0x00, // LIGHTBLUE - ?
139 0x00, 0xff, 0x00, 0x00, // LIGHTGREEN - ?
140 0xff, 0xff, 0x00, 0x00, // LIGHTCYAN
141 0x00, 0x00, 0xff, 0x00, // LIGHTRED
142 0xff, 0x00, 0xff, 0x00, // LIGHTMAGENTA
143 0x00, 0xff, 0xff, 0x00, // LIGHTBROWN
144 0xff, 0xff, 0xff, 0x00, // WHITE
145 };
146
147 static EFI_NARROW_GLYPH mCursorGlyph = {
148 0x0000,
149 0x00,
150 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }
151 };
152
153 EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding = {
154 GraphicsConsoleControllerDriverSupported,
155 GraphicsConsoleControllerDriverStart,
156 GraphicsConsoleControllerDriverStop,
157 0x10,
158 NULL,
159 NULL
160 };
161
162 EFI_STATUS
163 EFIAPI
164 GraphicsConsoleControllerDriverSupported (
165 IN EFI_DRIVER_BINDING_PROTOCOL *This,
166 IN EFI_HANDLE Controller,
167 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
168 )
169 {
170 EFI_STATUS Status;
171 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
172 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
173 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
174
175 UgaDraw = NULL;
176 //
177 // Open the IO Abstraction(s) needed to perform the supported test
178 //
179 Status = gBS->OpenProtocol (
180 Controller,
181 &gEfiGraphicsOutputProtocolGuid,
182 (VOID **) &GraphicsOutput,
183 This->DriverBindingHandle,
184 Controller,
185 EFI_OPEN_PROTOCOL_BY_DRIVER
186 );
187
188 if (EFI_ERROR (Status)) {
189 GraphicsOutput = NULL;
190 //
191 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol
192 //
193 Status = gBS->OpenProtocol (
194 Controller,
195 &gEfiUgaDrawProtocolGuid,
196 (VOID **) &UgaDraw,
197 This->DriverBindingHandle,
198 Controller,
199 EFI_OPEN_PROTOCOL_BY_DRIVER
200 );
201 if (EFI_ERROR (Status)) {
202 return Status;
203 }
204 }
205
206 //
207 // We need to ensure that we do not layer on top of a virtual handle.
208 // We need to ensure that the handles produced by the conspliter do not
209 // get used.
210 //
211 Status = gBS->OpenProtocol (
212 Controller,
213 &gEfiDevicePathProtocolGuid,
214 (VOID **) &DevicePath,
215 This->DriverBindingHandle,
216 Controller,
217 EFI_OPEN_PROTOCOL_BY_DRIVER
218 );
219 if (!EFI_ERROR (Status)) {
220 gBS->CloseProtocol (
221 Controller,
222 &gEfiDevicePathProtocolGuid,
223 This->DriverBindingHandle,
224 Controller
225 );
226 } else {
227 goto Error;
228 }
229 //
230 // Does Hii Exist? If not, we aren't ready to run
231 //
232 Status = EfiLocateHiiProtocol ();
233
234 //
235 // Close the I/O Abstraction(s) used to perform the supported test
236 //
237 Error:
238 if (GraphicsOutput != NULL) {
239 gBS->CloseProtocol (
240 Controller,
241 &gEfiGraphicsOutputProtocolGuid,
242 This->DriverBindingHandle,
243 Controller
244 );
245 } else {
246 gBS->CloseProtocol (
247 Controller,
248 &gEfiUgaDrawProtocolGuid,
249 This->DriverBindingHandle,
250 Controller
251 );
252 }
253 return Status;
254 }
255
256 EFI_STATUS
257 EFIAPI
258 GraphicsConsoleControllerDriverStart (
259 IN EFI_DRIVER_BINDING_PROTOCOL *This,
260 IN EFI_HANDLE Controller,
261 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
262 )
263 /*++
264
265 Routine Description:
266
267 Start the controller.
268
269 Arguments:
270
271 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
272 Controller - The handle of the controller to start.
273 RemainingDevicePath - A pointer to the remaining portion of a devcie path.
274
275 Returns:
276
277 EFI_SUCCESS - Return successfully.
278 EFI_OUT_OF_RESOURCES - Out of resources.
279
280 --*/
281 {
282 EFI_STATUS Status;
283 GRAPHICS_CONSOLE_DEV *Private;
284 EFI_HII_PACKAGES *Package;
285 EFI_HII_FONT_PACK *FontPack;
286 UINTN NarrowFontSize;
287 UINT32 HorizontalResolution;
288 UINT32 VerticalResolution;
289 UINT32 ColorDepth;
290 UINT32 RefreshRate;
291 UINTN MaxMode;
292 UINTN Columns;
293 UINTN Rows;
294 UINT8 *Location;
295 UINT32 ModeNumber;
296 UINTN SizeOfInfo;
297 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
298
299 ModeNumber = 0;
300
301 //
302 // Initialize the Graphics Console device instance
303 //
304 Private = AllocateCopyPool (
305 sizeof (GRAPHICS_CONSOLE_DEV),
306 &mGraphicsConsoleDevTemplate
307 );
308 if (Private == NULL) {
309 return EFI_OUT_OF_RESOURCES;
310 }
311
312 Private->SimpleTextOutput.Mode = &(Private->SimpleTextOutputMode);
313
314 Status = gBS->OpenProtocol (
315 Controller,
316 &gEfiGraphicsOutputProtocolGuid,
317 (VOID **) &Private->GraphicsOutput,
318 This->DriverBindingHandle,
319 Controller,
320 EFI_OPEN_PROTOCOL_BY_DRIVER
321 );
322 if (EFI_ERROR(Status)) {
323 Private->GraphicsOutput = NULL;
324
325 Status = gBS->OpenProtocol (
326 Controller,
327 &gEfiUgaDrawProtocolGuid,
328 (VOID **) &Private->UgaDraw,
329 This->DriverBindingHandle,
330 Controller,
331 EFI_OPEN_PROTOCOL_BY_DRIVER
332 );
333 if (EFI_ERROR (Status)) {
334 goto Error;
335 }
336 }
337
338 //
339 // Get the HII protocol. If Supported() succeeds, do we really
340 // need to get HII protocol again?
341 //
342 Status = EfiLocateHiiProtocol ();
343 if (EFI_ERROR (Status)) {
344 goto Error;
345 }
346
347 NarrowFontSize = ReturnNarrowFontSize ();
348
349 FontPack = AllocateZeroPool (sizeof (EFI_HII_FONT_PACK) + NarrowFontSize);
350 ASSERT (FontPack);
351
352 FontPack->Header.Length = (UINT32) (sizeof (EFI_HII_FONT_PACK) + NarrowFontSize);
353 FontPack->Header.Type = EFI_HII_FONT;
354 FontPack->NumberOfNarrowGlyphs = (UINT16) (NarrowFontSize / sizeof (EFI_NARROW_GLYPH));
355
356 Location = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8));
357 CopyMem (Location, UsStdNarrowGlyphData, NarrowFontSize);
358
359 //
360 // Register our Fonts into the global database
361 //
362 Package = PreparePackages (1, NULL, FontPack);
363 mHii->NewPack (mHii, Package, &(Private->HiiHandle));
364 gBS->FreePool (Package);
365
366 //
367 // Free the font database
368 //
369 gBS->FreePool (FontPack);
370
371 //
372 // If the current mode information can not be retrieved, then attemp to set the default mode
373 // of 800x600, 32 bit colot, 60 Hz refresh.
374 //
375 HorizontalResolution = 800;
376 VerticalResolution = 600;
377
378 if (Private->GraphicsOutput != NULL) {
379 //
380 // The console is build on top of Graphics Output Protocol, find the mode number for 800x600
381 //
382 for (ModeNumber = 0; ModeNumber < Private->GraphicsOutput->Mode->MaxMode; ModeNumber++) {
383 Status = Private->GraphicsOutput->QueryMode (
384 Private->GraphicsOutput,
385 ModeNumber,
386 &SizeOfInfo,
387 &Info
388 );
389 if (!EFI_ERROR (Status)) {
390 if ((Info->HorizontalResolution == 800) &&
391 (Info->VerticalResolution == 600) &&
392 ((Info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor) ||
393 (Info->PixelFormat == PixelBlueGreenRedReserved8BitPerColor))) {
394 Status = Private->GraphicsOutput->SetMode (Private->GraphicsOutput, ModeNumber);
395 if (!EFI_ERROR (Status)) {
396 gBS->FreePool (Info);
397 break;
398 }
399 }
400 gBS->FreePool (Info);
401 }
402 }
403
404 if (EFI_ERROR (Status) || (ModeNumber == Private->GraphicsOutput->Mode->MaxMode)) {
405 //
406 // Set default mode failed or device don't support default mode, then get the current mode information
407 //
408 HorizontalResolution = Private->GraphicsOutput->Mode->Info->HorizontalResolution;
409 VerticalResolution = Private->GraphicsOutput->Mode->Info->VerticalResolution;
410 ModeNumber = Private->GraphicsOutput->Mode->Mode;
411 }
412 } else {
413 //
414 // The console is build on top of UGA Draw Protocol
415 //
416 ColorDepth = 32;
417 RefreshRate = 60;
418 Status = Private->UgaDraw->SetMode (
419 Private->UgaDraw,
420 HorizontalResolution,
421 VerticalResolution,
422 ColorDepth,
423 RefreshRate
424 );
425 if (EFI_ERROR (Status)) {
426 //
427 // Get the current mode information from the UGA Draw Protocol
428 //
429 Status = Private->UgaDraw->GetMode (
430 Private->UgaDraw,
431 &HorizontalResolution,
432 &VerticalResolution,
433 &ColorDepth,
434 &RefreshRate
435 );
436 if (EFI_ERROR (Status)) {
437 goto Error;
438 }
439 }
440 }
441
442 //
443 // Compute the maximum number of text Rows and Columns that this current graphics mode can support
444 //
445 Columns = HorizontalResolution / GLYPH_WIDTH;
446 Rows = VerticalResolution / GLYPH_HEIGHT;
447
448 //
449 // See if the mode is too small to support the required 80x25 text mode
450 //
451 if (Columns < 80 || Rows < 25) {
452 goto Error;
453 }
454 //
455 // Add Mode #0 that must be 80x25
456 //
457 MaxMode = 0;
458 Private->ModeData[MaxMode].GopWidth = HorizontalResolution;
459 Private->ModeData[MaxMode].GopHeight = VerticalResolution;
460 Private->ModeData[MaxMode].GopModeNumber = ModeNumber;
461 Private->ModeData[MaxMode].DeltaX = (HorizontalResolution - (80 * GLYPH_WIDTH)) >> 1;
462 Private->ModeData[MaxMode].DeltaY = (VerticalResolution - (25 * GLYPH_HEIGHT)) >> 1;
463 MaxMode++;
464
465 //
466 // If it is possible to support Mode #1 - 80x50, than add it as an active mode
467 //
468 if (Rows >= 50) {
469 Private->ModeData[MaxMode].GopWidth = HorizontalResolution;
470 Private->ModeData[MaxMode].GopHeight = VerticalResolution;
471 Private->ModeData[MaxMode].GopModeNumber = ModeNumber;
472 Private->ModeData[MaxMode].DeltaX = (HorizontalResolution - (80 * GLYPH_WIDTH)) >> 1;
473 Private->ModeData[MaxMode].DeltaY = (VerticalResolution - (50 * GLYPH_HEIGHT)) >> 1;
474 MaxMode++;
475 }
476 //
477 // If the graphics mode is 800x600, than add a text mode that uses the entire display
478 //
479 if (HorizontalResolution == 800 && VerticalResolution == 600) {
480
481 if (MaxMode < 2) {
482 Private->ModeData[MaxMode].Columns = 0;
483 Private->ModeData[MaxMode].Rows = 0;
484 Private->ModeData[MaxMode].GopWidth = 800;
485 Private->ModeData[MaxMode].GopHeight = 600;
486 Private->ModeData[MaxMode].GopModeNumber = ModeNumber;
487 Private->ModeData[MaxMode].DeltaX = 0;
488 Private->ModeData[MaxMode].DeltaY = 0;
489 MaxMode++;
490 }
491
492 Private->ModeData[MaxMode].Columns = 800 / GLYPH_WIDTH;
493 Private->ModeData[MaxMode].Rows = 600 / GLYPH_HEIGHT;
494 Private->ModeData[MaxMode].GopWidth = 800;
495 Private->ModeData[MaxMode].GopHeight = 600;
496 Private->ModeData[MaxMode].GopModeNumber = ModeNumber;
497 Private->ModeData[MaxMode].DeltaX = (800 % GLYPH_WIDTH) >> 1;
498 Private->ModeData[MaxMode].DeltaY = (600 % GLYPH_HEIGHT) >> 1;
499 MaxMode++;
500 }
501 //
502 // Update the maximum number of modes
503 //
504 Private->SimpleTextOutputMode.MaxMode = (INT32) MaxMode;
505
506 //
507 // Determine the number of text modes that this protocol can support
508 //
509 Status = GraphicsConsoleConOutSetMode (&Private->SimpleTextOutput, 0);
510 if (EFI_ERROR (Status)) {
511 goto Error;
512 }
513
514 DEBUG_CODE_BEGIN ();
515 GraphicsConsoleConOutOutputString (&Private->SimpleTextOutput, (CHAR16 *)L"Graphics Console Started\n\r");
516 DEBUG_CODE_END ();
517
518 //
519 // Install protocol interfaces for the Graphics Console device.
520 //
521 Status = gBS->InstallMultipleProtocolInterfaces (
522 &Controller,
523 &gEfiSimpleTextOutProtocolGuid,
524 &Private->SimpleTextOutput,
525 NULL
526 );
527
528 Error:
529 if (EFI_ERROR (Status)) {
530 //
531 // Close the GOP or UGA IO Protocol
532 //
533 if (Private->GraphicsOutput != NULL) {
534 gBS->CloseProtocol (
535 Controller,
536 &gEfiGraphicsOutputProtocolGuid,
537 This->DriverBindingHandle,
538 Controller
539 );
540 } else {
541 gBS->CloseProtocol (
542 Controller,
543 &gEfiUgaDrawProtocolGuid,
544 This->DriverBindingHandle,
545 Controller
546 );
547 }
548
549 //
550 // Free private data
551 //
552 if (Private != NULL) {
553 gBS->FreePool (Private->LineBuffer);
554 gBS->FreePool (Private);
555 }
556 }
557
558 return Status;
559 }
560
561 EFI_STATUS
562 EFIAPI
563 GraphicsConsoleControllerDriverStop (
564 IN EFI_DRIVER_BINDING_PROTOCOL *This,
565 IN EFI_HANDLE Controller,
566 IN UINTN NumberOfChildren,
567 IN EFI_HANDLE *ChildHandleBuffer
568 )
569 {
570 EFI_STATUS Status;
571 EFI_SIMPLE_TEXT_OUT_PROTOCOL *SimpleTextOutput;
572 GRAPHICS_CONSOLE_DEV *Private;
573
574 Status = gBS->OpenProtocol (
575 Controller,
576 &gEfiSimpleTextOutProtocolGuid,
577 (VOID **) &SimpleTextOutput,
578 This->DriverBindingHandle,
579 Controller,
580 EFI_OPEN_PROTOCOL_GET_PROTOCOL
581 );
582 if (EFI_ERROR (Status)) {
583 return EFI_NOT_STARTED;
584 }
585
586 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);
587
588 Status = gBS->UninstallProtocolInterface (
589 Controller,
590 &gEfiSimpleTextOutProtocolGuid,
591 &Private->SimpleTextOutput
592 );
593
594 if (!EFI_ERROR (Status)) {
595 //
596 // Close the GOP or UGA IO Protocol
597 //
598 if (Private->GraphicsOutput != NULL) {
599 gBS->CloseProtocol (
600 Controller,
601 &gEfiGraphicsOutputProtocolGuid,
602 This->DriverBindingHandle,
603 Controller
604 );
605 } else {
606 gBS->CloseProtocol (
607 Controller,
608 &gEfiUgaDrawProtocolGuid,
609 This->DriverBindingHandle,
610 Controller
611 );
612 }
613
614 //
615 // Remove the font pack
616 //
617 mHii->RemovePack (mHii, Private->HiiHandle);
618
619 //
620 // Free our instance data
621 //
622 if (Private != NULL) {
623 gBS->FreePool (Private->LineBuffer);
624 gBS->FreePool (Private);
625 }
626 }
627
628 return Status;
629 }
630
631 EFI_STATUS
632 EfiLocateHiiProtocol (
633 VOID
634 )
635 /*++
636
637 Routine Description:
638 Find if the HII protocol is available. If yes, locate the HII protocol
639
640 Arguments:
641
642 Returns:
643
644 --*/
645 {
646 EFI_HANDLE Handle;
647 UINTN Size;
648 EFI_STATUS Status;
649
650 //
651 // There should only be one - so buffer size is this
652 //
653 Size = sizeof (EFI_HANDLE);
654
655 Status = gBS->LocateHandle (
656 ByProtocol,
657 &gEfiHiiProtocolGuid,
658 NULL,
659 &Size,
660 &Handle
661 );
662
663 if (EFI_ERROR (Status)) {
664 return Status;
665 }
666
667 Status = gBS->HandleProtocol (
668 Handle,
669 &gEfiHiiProtocolGuid,
670 (VOID **)&mHii
671 );
672
673 return Status;
674 }
675 //
676 // Body of the STO functions
677 //
678 EFI_STATUS
679 EFIAPI
680 GraphicsConsoleConOutReset (
681 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
682 IN BOOLEAN ExtendedVerification
683 )
684 /*++
685 Routine Description:
686
687 Implements SIMPLE_TEXT_OUTPUT.Reset().
688 If ExtendeVerification is TRUE, then perform dependent Graphics Console
689 device reset, and set display mode to mode 0.
690 If ExtendedVerification is FALSE, only set display mode to mode 0.
691
692 Arguments:
693
694 This - Indicates the calling context.
695
696 ExtendedVerification - Indicates that the driver may perform a more exhaustive
697 verification operation of the device during reset.
698
699 Returns:
700
701 EFI_SUCCESS
702 The reset operation succeeds.
703
704 EFI_DEVICE_ERROR
705 The Graphics Console is not functioning correctly
706
707 --*/
708 {
709 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));
710 return This->SetMode (This, 0);
711 }
712
713 EFI_STATUS
714 EFIAPI
715 GraphicsConsoleConOutOutputString (
716 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
717 IN CHAR16 *WString
718 )
719 /*++
720 Routine Description:
721
722 Implements SIMPLE_TEXT_OUTPUT.OutputString().
723 The Unicode string will be converted to Glyphs and will be
724 sent to the Graphics Console.
725
726
727 Arguments:
728
729 This - Indicates the calling context.
730
731 WString - The Null-terminated Unicode string to be displayed on
732 the Graphics Console.
733
734 Returns:
735
736 EFI_SUCCESS
737 The string is output successfully.
738
739 EFI_DEVICE_ERROR
740 The Graphics Console failed to send the string out.
741
742 EFI_WARN_UNKNOWN_GLYPH
743 Indicates that some of the characters in the Unicode string could not
744 be rendered and are skipped.
745
746 --*/
747 {
748 GRAPHICS_CONSOLE_DEV *Private;
749 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
750 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
751 INTN Mode;
752 UINTN MaxColumn;
753 UINTN MaxRow;
754 UINTN Width;
755 UINTN Height;
756 UINTN Delta;
757 EFI_STATUS Status;
758 BOOLEAN Warning;
759 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
760 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
761 UINTN DeltaX;
762 UINTN DeltaY;
763 UINTN Count;
764 UINTN Index;
765 INT32 OriginAttribute;
766 CHAR16 SpaceStr[] = { NARROW_CHAR, ' ', 0 };
767
768 //
769 // Current mode
770 //
771 Mode = This->Mode->Mode;
772 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
773 GraphicsOutput = Private->GraphicsOutput;
774 UgaDraw = Private->UgaDraw;
775
776 MaxColumn = Private->ModeData[Mode].Columns;
777 MaxRow = Private->ModeData[Mode].Rows;
778 DeltaX = Private->ModeData[Mode].DeltaX;
779 DeltaY = Private->ModeData[Mode].DeltaY;
780 Width = MaxColumn * GLYPH_WIDTH;
781 Height = (MaxRow - 1) * GLYPH_HEIGHT;
782 Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
783
784 //
785 // The Attributes won't change when during the time OutputString is called
786 //
787 GetTextColors (This, &Foreground, &Background);
788
789 EraseCursor (This);
790
791 Warning = FALSE;
792
793 //
794 // Backup attribute
795 //
796 OriginAttribute = This->Mode->Attribute;
797
798 while (*WString) {
799
800 if (*WString == CHAR_BACKSPACE) {
801 //
802 // If the cursor is at the left edge of the display, then move the cursor
803 // one row up.
804 //
805 if (This->Mode->CursorColumn == 0 && This->Mode->CursorRow > 0) {
806 This->Mode->CursorRow--;
807 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);
808 This->OutputString (This, SpaceStr);
809 EraseCursor (This);
810 This->Mode->CursorRow--;
811 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);
812 } else if (This->Mode->CursorColumn > 0) {
813 //
814 // If the cursor is not at the left edge of the display, then move the cursor
815 // left one column.
816 //
817 This->Mode->CursorColumn--;
818 This->OutputString (This, SpaceStr);
819 EraseCursor (This);
820 This->Mode->CursorColumn--;
821 }
822
823 WString++;
824
825 } else if (*WString == CHAR_LINEFEED) {
826 //
827 // If the cursor is at the bottom of the display, then scroll the display one
828 // row, and do not update the cursor position. Otherwise, move the cursor
829 // down one row.
830 //
831 if (This->Mode->CursorRow == (INT32) (MaxRow - 1)) {
832 if (GraphicsOutput != NULL) {
833 //
834 // Scroll Screen Up One Row
835 //
836 GraphicsOutput->Blt (
837 GraphicsOutput,
838 NULL,
839 EfiBltVideoToVideo,
840 DeltaX,
841 DeltaY + GLYPH_HEIGHT,
842 DeltaX,
843 DeltaY,
844 Width,
845 Height,
846 Delta
847 );
848
849 //
850 // Print Blank Line at last line
851 //
852 GraphicsOutput->Blt (
853 GraphicsOutput,
854 &Background,
855 EfiBltVideoFill,
856 0,
857 0,
858 DeltaX,
859 DeltaY + Height,
860 Width,
861 GLYPH_HEIGHT,
862 Delta
863 );
864 } else {
865 //
866 // Scroll Screen Up One Row
867 //
868 UgaDraw->Blt (
869 UgaDraw,
870 NULL,
871 EfiUgaVideoToVideo,
872 DeltaX,
873 DeltaY + GLYPH_HEIGHT,
874 DeltaX,
875 DeltaY,
876 Width,
877 Height,
878 Delta
879 );
880
881 //
882 // Print Blank Line at last line
883 //
884 UgaDraw->Blt (
885 UgaDraw,
886 (EFI_UGA_PIXEL *) (UINTN) &Background,
887 EfiUgaVideoFill,
888 0,
889 0,
890 DeltaX,
891 DeltaY + Height,
892 Width,
893 GLYPH_HEIGHT,
894 Delta
895 );
896 }
897 } else {
898 This->Mode->CursorRow++;
899 }
900
901 WString++;
902
903 } else if (*WString == CHAR_CARRIAGE_RETURN) {
904 //
905 // Move the cursor to the beginning of the current row.
906 //
907 This->Mode->CursorColumn = 0;
908 WString++;
909
910 } else if (*WString == WIDE_CHAR) {
911
912 This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;
913 WString++;
914
915 } else if (*WString == NARROW_CHAR) {
916
917 This->Mode->Attribute &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);
918 WString++;
919
920 } else {
921 //
922 // Print the character at the current cursor position and move the cursor
923 // right one column. If this moves the cursor past the right edge of the
924 // display, then the line should wrap to the beginning of the next line. This
925 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
926 // bottom of the display, and the line wraps, then the display will be scrolled
927 // one line.
928 // If wide char is going to be displayed, need to display one character at a time
929 // Or, need to know the display length of a certain string.
930 //
931 // Index is used to determine how many character width units (wide = 2, narrow = 1)
932 // Count is used to determine how many characters are used regardless of their attributes
933 //
934 for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {
935 if (WString[Count] == CHAR_NULL) {
936 break;
937 }
938
939 if (WString[Count] == CHAR_BACKSPACE) {
940 break;
941 }
942
943 if (WString[Count] == CHAR_LINEFEED) {
944 break;
945 }
946
947 if (WString[Count] == CHAR_CARRIAGE_RETURN) {
948 break;
949 }
950
951 if (WString[Count] == WIDE_CHAR) {
952 break;
953 }
954
955 if (WString[Count] == NARROW_CHAR) {
956 break;
957 }
958 //
959 // Is the wide attribute on?
960 //
961 if (This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) {
962 //
963 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
964 //
965 Index++;
966 //
967 // This is the end-case where if we are at column 79 and about to print a wide character
968 // We should prevent this from happening because we will wrap inappropriately. We should
969 // not print this character until the next line.
970 //
971 if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {
972 Index++;
973 break;
974 }
975 }
976 }
977
978 Status = DrawUnicodeWeightAtCursorN (This, WString, Count);
979 if (EFI_ERROR (Status)) {
980 Warning = TRUE;
981 }
982 //
983 // At the end of line, output carriage return and line feed
984 //
985 WString += Count;
986 This->Mode->CursorColumn += (INT32) Index;
987 if (This->Mode->CursorColumn > (INT32) MaxColumn) {
988 This->Mode->CursorColumn -= 2;
989 This->OutputString (This, SpaceStr);
990 }
991
992 if (This->Mode->CursorColumn >= (INT32) MaxColumn) {
993 EraseCursor (This);
994 This->OutputString (This, mCrLfString);
995 EraseCursor (This);
996 }
997 }
998 }
999
1000 This->Mode->Attribute = OriginAttribute;
1001
1002 EraseCursor (This);
1003
1004 if (Warning) {
1005 return EFI_WARN_UNKNOWN_GLYPH;
1006 }
1007
1008 return EFI_SUCCESS;
1009 }
1010
1011 EFI_STATUS
1012 EFIAPI
1013 GraphicsConsoleConOutTestString (
1014 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
1015 IN CHAR16 *WString
1016 )
1017 /*++
1018 Routine Description:
1019
1020 Implements SIMPLE_TEXT_OUTPUT.TestString().
1021 If one of the characters in the *Wstring is
1022 neither valid valid Unicode drawing characters,
1023 not ASCII code, then this function will return
1024 EFI_UNSUPPORTED.
1025
1026
1027 Arguments:
1028
1029 This - Indicates the calling context.
1030
1031 WString - The Null-terminated Unicode string to be tested.
1032
1033 Returns:
1034
1035 EFI_SUCCESS
1036 The Graphics Console is capable of rendering the output string.
1037
1038 EFI_UNSUPPORTED
1039 Some of the characters in the Unicode string cannot be rendered.
1040
1041 --*/
1042 {
1043 EFI_STATUS Status;
1044 UINT16 GlyphWidth;
1045 UINT32 GlyphStatus;
1046 UINT16 Count;
1047 GRAPHICS_CONSOLE_DEV *Private;
1048 GLYPH_UNION *Glyph;
1049
1050 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1051 GlyphStatus = 0;
1052 Count = 0;
1053
1054 while (WString[Count]) {
1055 Status = mHii->GetGlyph (
1056 mHii,
1057 WString,
1058 &Count,
1059 (UINT8 **) &Glyph,
1060 &GlyphWidth,
1061 &GlyphStatus
1062 );
1063
1064 if (EFI_ERROR (Status)) {
1065 return EFI_UNSUPPORTED;
1066 }
1067 }
1068
1069 return EFI_SUCCESS;
1070 }
1071
1072 EFI_STATUS
1073 EFIAPI
1074 GraphicsConsoleConOutQueryMode (
1075 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
1076 IN UINTN ModeNumber,
1077 OUT UINTN *Columns,
1078 OUT UINTN *Rows
1079 )
1080 /*++
1081 Routine Description:
1082
1083 Implements SIMPLE_TEXT_OUTPUT.QueryMode().
1084 It returnes information for an available text mode
1085 that the Graphics Console supports.
1086 In this driver,we only support text mode 80x25, which is
1087 defined as mode 0.
1088
1089
1090 Arguments:
1091
1092 This - Indicates the calling context.
1093
1094 ModeNumber - The mode number to return information on.
1095
1096 Columns - The returned columns of the requested mode.
1097
1098 Rows - The returned rows of the requested mode.
1099
1100 Returns:
1101
1102 EFI_SUCCESS
1103 The requested mode information is returned.
1104
1105 EFI_UNSUPPORTED
1106 The mode number is not valid.
1107
1108 --*/
1109 {
1110 GRAPHICS_CONSOLE_DEV *Private;
1111
1112 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {
1113 return EFI_UNSUPPORTED;
1114 }
1115
1116 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1117
1118 *Columns = Private->ModeData[ModeNumber].Columns;
1119 *Rows = Private->ModeData[ModeNumber].Rows;
1120
1121 if (*Columns <= 0 && *Rows <= 0) {
1122 return EFI_UNSUPPORTED;
1123
1124 }
1125
1126 return EFI_SUCCESS;
1127 }
1128
1129 EFI_STATUS
1130 EFIAPI
1131 GraphicsConsoleConOutSetMode (
1132 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
1133 IN UINTN ModeNumber
1134 )
1135 /*++
1136 Routine Description:
1137
1138 Implements SIMPLE_TEXT_OUTPUT.SetMode().
1139 Set the Graphics Console to a specified mode.
1140 In this driver, we only support mode 0.
1141
1142 Arguments:
1143
1144 This - Indicates the calling context.
1145
1146 ModeNumber - The text mode to set.
1147
1148 Returns:
1149
1150 EFI_SUCCESS
1151 The requested text mode is set.
1152
1153 EFI_DEVICE_ERROR
1154 The requested text mode cannot be set because of Graphics Console device error.
1155
1156 EFI_UNSUPPORTED
1157 The text mode number is not valid.
1158
1159 --*/
1160 {
1161 EFI_STATUS Status;
1162 GRAPHICS_CONSOLE_DEV *Private;
1163 GRAPHICS_CONSOLE_MODE_DATA *ModeData;
1164 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewLineBuffer;
1165 UINT32 HorizontalResolution;
1166 UINT32 VerticalResolution;
1167 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1168 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1169 UINT32 ColorDepth;
1170 UINT32 RefreshRate;
1171
1172 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1173 GraphicsOutput = Private->GraphicsOutput;
1174 UgaDraw = Private->UgaDraw;
1175 ModeData = &(Private->ModeData[ModeNumber]);
1176
1177 //
1178 // Make sure the requested mode number is supported
1179 //
1180 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {
1181 return EFI_UNSUPPORTED;
1182 }
1183
1184 if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {
1185 return EFI_UNSUPPORTED;
1186 }
1187 //
1188 // Attempt to allocate a line buffer for the requested mode number
1189 //
1190 Status = gBS->AllocatePool (
1191 EfiBootServicesData,
1192 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * GLYPH_WIDTH * GLYPH_HEIGHT,
1193 (VOID **) &NewLineBuffer
1194 );
1195 if (EFI_ERROR (Status)) {
1196 //
1197 // The new line buffer could not be allocated, so return an error.
1198 // No changes to the state of the current console have been made, so the current console is still valid
1199 //
1200 return Status;
1201 }
1202 //
1203 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1204 //
1205 if (Private->LineBuffer != NULL) {
1206 //
1207 // Clear the current text window on the current graphics console
1208 //
1209 This->ClearScreen (This);
1210
1211 //
1212 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1213 //
1214 if ((INT32) ModeNumber == This->Mode->Mode) {
1215 gBS->FreePool (NewLineBuffer);
1216 return EFI_SUCCESS;
1217 }
1218 //
1219 // Otherwise, the size of the text console and/or the UGA mode will be changed,
1220 // so turn off the cursor, and free the LineBuffer for the current mode
1221 //
1222 This->EnableCursor (This, FALSE);
1223
1224 gBS->FreePool (Private->LineBuffer);
1225 }
1226 //
1227 // Assign the current line buffer to the newly allocated line buffer
1228 //
1229 Private->LineBuffer = NewLineBuffer;
1230
1231 if (GraphicsOutput != NULL) {
1232 if (ModeData->GopModeNumber != GraphicsOutput->Mode->Mode) {
1233 //
1234 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode
1235 //
1236 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeData->GopModeNumber);
1237 if (EFI_ERROR (Status)) {
1238 //
1239 // The mode set operation failed
1240 //
1241 return Status;
1242 }
1243 } else {
1244 //
1245 // The current graphics mode is correct, so simply clear the entire display
1246 //
1247 Status = GraphicsOutput->Blt (
1248 GraphicsOutput,
1249 &mEfiColors[0],
1250 EfiBltVideoFill,
1251 0,
1252 0,
1253 0,
1254 0,
1255 ModeData->GopWidth,
1256 ModeData->GopHeight,
1257 0
1258 );
1259 }
1260 } else {
1261 //
1262 // Get the current UGA Draw mode information
1263 //
1264 Status = UgaDraw->GetMode (
1265 UgaDraw,
1266 &HorizontalResolution,
1267 &VerticalResolution,
1268 &ColorDepth,
1269 &RefreshRate
1270 );
1271 if (EFI_ERROR (Status) || HorizontalResolution != ModeData->GopWidth || VerticalResolution != ModeData->GopHeight) {
1272 //
1273 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode
1274 //
1275 Status = UgaDraw->SetMode (
1276 UgaDraw,
1277 ModeData->GopWidth,
1278 ModeData->GopHeight,
1279 32,
1280 60
1281 );
1282 if (EFI_ERROR (Status)) {
1283 //
1284 // The mode set operation failed
1285 //
1286 return Status;
1287 }
1288 } else {
1289 //
1290 // The current graphics mode is correct, so simply clear the entire display
1291 //
1292 Status = UgaDraw->Blt (
1293 UgaDraw,
1294 (EFI_UGA_PIXEL *) (UINTN) &mEfiColors[0],
1295 EfiUgaVideoFill,
1296 0,
1297 0,
1298 0,
1299 0,
1300 ModeData->GopWidth,
1301 ModeData->GopHeight,
1302 0
1303 );
1304 }
1305 }
1306
1307 //
1308 // The new mode is valid, so commit the mode change
1309 //
1310 This->Mode->Mode = (INT32) ModeNumber;
1311
1312 //
1313 // Move the text cursor to the upper left hand corner of the displat and enable it
1314 //
1315 This->SetCursorPosition (This, 0, 0);
1316 This->EnableCursor (This, TRUE);
1317
1318 return EFI_SUCCESS;
1319 }
1320
1321 EFI_STATUS
1322 EFIAPI
1323 GraphicsConsoleConOutSetAttribute (
1324 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
1325 IN UINTN Attribute
1326 )
1327 /*++
1328 Routine Description:
1329
1330 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
1331
1332 Arguments:
1333
1334 This - Indicates the calling context.
1335
1336 Attrubute - The attribute to set. Only bit0..6 are valid, all other bits
1337 are undefined and must be zero.
1338
1339 Returns:
1340
1341 EFI_SUCCESS
1342 The requested attribute is set.
1343
1344 EFI_DEVICE_ERROR
1345 The requested attribute cannot be set due to Graphics Console port error.
1346
1347 EFI_UNSUPPORTED
1348 The attribute requested is not defined by EFI spec.
1349
1350 --*/
1351 {
1352 if ((Attribute | 0xFF) != 0xFF) {
1353 return EFI_UNSUPPORTED;
1354 }
1355
1356 if ((INT32) Attribute == This->Mode->Attribute) {
1357 return EFI_SUCCESS;
1358 }
1359
1360 EraseCursor (This);
1361
1362 This->Mode->Attribute = (INT32) Attribute;
1363
1364 EraseCursor (This);
1365
1366 return EFI_SUCCESS;
1367 }
1368
1369 EFI_STATUS
1370 EFIAPI
1371 GraphicsConsoleConOutClearScreen (
1372 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This
1373 )
1374 /*++
1375 Routine Description:
1376
1377 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
1378 It clears the Graphics Console's display to the
1379 currently selected background color.
1380
1381
1382 Arguments:
1383
1384 This - Indicates the calling context.
1385
1386 Returns:
1387
1388 EFI_SUCCESS
1389 The operation completed successfully.
1390
1391 EFI_DEVICE_ERROR
1392 The Graphics Console cannot be cleared due to Graphics Console device error.
1393
1394 EFI_UNSUPPORTED
1395 The Graphics Console is not in a valid text mode.
1396
1397 --*/
1398 {
1399 EFI_STATUS Status;
1400 GRAPHICS_CONSOLE_DEV *Private;
1401 GRAPHICS_CONSOLE_MODE_DATA *ModeData;
1402 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1403 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1404 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
1405 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
1406
1407 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1408 GraphicsOutput = Private->GraphicsOutput;
1409 UgaDraw = Private->UgaDraw;
1410 ModeData = &(Private->ModeData[This->Mode->Mode]);
1411
1412 GetTextColors (This, &Foreground, &Background);
1413 if (GraphicsOutput != NULL) {
1414 Status = GraphicsOutput->Blt (
1415 GraphicsOutput,
1416 &Background,
1417 EfiBltVideoFill,
1418 0,
1419 0,
1420 0,
1421 0,
1422 ModeData->GopWidth,
1423 ModeData->GopHeight,
1424 0
1425 );
1426 } else {
1427 Status = UgaDraw->Blt (
1428 UgaDraw,
1429 (EFI_UGA_PIXEL *) (UINTN) &Background,
1430 EfiUgaVideoFill,
1431 0,
1432 0,
1433 0,
1434 0,
1435 ModeData->GopWidth,
1436 ModeData->GopHeight,
1437 0
1438 );
1439 }
1440
1441 This->Mode->CursorColumn = 0;
1442 This->Mode->CursorRow = 0;
1443
1444 EraseCursor (This);
1445
1446 return Status;
1447 }
1448
1449 EFI_STATUS
1450 EFIAPI
1451 GraphicsConsoleConOutSetCursorPosition (
1452 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
1453 IN UINTN Column,
1454 IN UINTN Row
1455 )
1456 /*++
1457 Routine Description:
1458
1459 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
1460
1461 Arguments:
1462
1463 This - Indicates the calling context.
1464
1465 Column - The row to set cursor to.
1466
1467 Row - The column to set cursor to.
1468
1469 Returns:
1470
1471 EFI_SUCCESS
1472 The operation completed successfully.
1473
1474 EFI_DEVICE_ERROR
1475 The request fails due to Graphics Console device error.
1476
1477 EFI_UNSUPPORTED
1478 The Graphics Console is not in a valid text mode, or the cursor position
1479 is invalid for current mode.
1480
1481 --*/
1482 {
1483 GRAPHICS_CONSOLE_DEV *Private;
1484 GRAPHICS_CONSOLE_MODE_DATA *ModeData;
1485
1486 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1487 ModeData = &(Private->ModeData[This->Mode->Mode]);
1488
1489 if ((Column >= ModeData->Columns) || (Row >= ModeData->Rows)) {
1490 return EFI_UNSUPPORTED;
1491 }
1492
1493 if (((INT32) Column == This->Mode->CursorColumn) && ((INT32) Row == This->Mode->CursorRow)) {
1494 return EFI_SUCCESS;
1495 }
1496
1497 EraseCursor (This);
1498
1499 This->Mode->CursorColumn = (INT32) Column;
1500 This->Mode->CursorRow = (INT32) Row;
1501
1502 EraseCursor (This);
1503
1504 return EFI_SUCCESS;
1505 }
1506
1507 EFI_STATUS
1508 EFIAPI
1509 GraphicsConsoleConOutEnableCursor (
1510 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
1511 IN BOOLEAN Visible
1512 )
1513 /*++
1514 Routine Description:
1515
1516 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1517 In this driver, the cursor cannot be hidden.
1518
1519 Arguments:
1520
1521 This - Indicates the calling context.
1522
1523 Visible - If TRUE, the cursor is set to be visible,
1524 If FALSE, the cursor is set to be invisible.
1525
1526 Returns:
1527
1528 EFI_SUCCESS
1529 The request is valid.
1530
1531 EFI_UNSUPPORTED
1532 The Graphics Console does not support a hidden cursor.
1533
1534 --*/
1535 {
1536 EraseCursor (This);
1537
1538 This->Mode->CursorVisible = Visible;
1539
1540 EraseCursor (This);
1541
1542 return EFI_SUCCESS;
1543 }
1544
1545 EFI_STATUS
1546 GetTextColors (
1547 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
1548 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,
1549 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background
1550 )
1551 {
1552 INTN Attribute;
1553
1554 Attribute = This->Mode->Attribute & 0x7F;
1555
1556 *Foreground = mEfiColors[Attribute & 0x0f];
1557 *Background = mEfiColors[Attribute >> 4];
1558
1559 return EFI_SUCCESS;
1560 }
1561
1562 EFI_STATUS
1563 DrawUnicodeWeightAtCursorN (
1564 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
1565 IN CHAR16 *UnicodeWeight,
1566 IN UINTN Count
1567 )
1568 {
1569 GRAPHICS_CONSOLE_DEV *Private;
1570 EFI_STATUS Status;
1571 EFI_STATUS ReturnStatus;
1572 GLYPH_UNION *Glyph;
1573 GLYPH_UNION GlyphData;
1574 INTN GlyphX;
1575 INTN GlyphY;
1576 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1577 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1578 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
1579 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
1580 UINTN Index;
1581 UINTN ArrayIndex;
1582 UINTN Counts;
1583 UINT16 GlyphWidth;
1584 UINT32 GlyphStatus;
1585
1586 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1587
1588 ReturnStatus = EFI_SUCCESS;
1589 GlyphStatus = 0;
1590 GlyphWidth = 0x08;
1591
1592 GetTextColors (This, &Foreground, &Background);
1593
1594 Index = 0;
1595 ArrayIndex = 0;
1596 while (Index < Count) {
1597 if (This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) {
1598 GlyphStatus = WIDE_CHAR;
1599 } else {
1600 GlyphStatus = NARROW_CHAR;
1601 }
1602
1603 Status = mHii->GetGlyph (
1604 mHii,
1605 UnicodeWeight,
1606 (UINT16 *) &Index,
1607 (UINT8 **) &Glyph,
1608 &GlyphWidth,
1609 &GlyphStatus
1610 );
1611 if (EFI_ERROR (Status)) {
1612 ReturnStatus = Status;
1613 }
1614
1615 Counts = 0;
1616
1617 CopyMem (&GlyphData, Glyph, sizeof (GLYPH_UNION));
1618
1619 do {
1620 //
1621 // We are creating the second half of the wide character's BLT buffer
1622 //
1623 if (GlyphWidth == 0x10 && Counts == 1) {
1624 CopyMem (&GlyphData.NarrowGlyph.GlyphCol1, &Glyph->WideGlyph.GlyphCol2, sizeof (Glyph->WideGlyph.GlyphCol2));
1625 }
1626
1627 Counts++;
1628
1629 if (GlyphWidth == 0x10) {
1630 mHii->GlyphToBlt (
1631 mHii,
1632 (UINT8 *) &GlyphData,
1633 Foreground,
1634 Background,
1635 Count * 2,
1636 GLYPH_WIDTH,
1637 GLYPH_HEIGHT,
1638 &Private->LineBuffer[ArrayIndex * GLYPH_WIDTH]
1639 );
1640 } else {
1641 mHii->GlyphToBlt (
1642 mHii,
1643 (UINT8 *) &GlyphData,
1644 Foreground,
1645 Background,
1646 Count,
1647 GLYPH_WIDTH,
1648 GLYPH_HEIGHT,
1649 &Private->LineBuffer[ArrayIndex * GLYPH_WIDTH]
1650 );
1651 }
1652
1653 ArrayIndex++;
1654
1655 } while (Counts < 2 && GlyphWidth == 0x10);
1656
1657 }
1658 //
1659 // If we are printing Wide characters, treat the BLT as if it is twice as many characters
1660 //
1661 if (GlyphWidth == 0x10) {
1662 Count = Count * 2;
1663 }
1664 //
1665 // Blt a character to the screen
1666 //
1667 GlyphX = This->Mode->CursorColumn * GLYPH_WIDTH;
1668 GlyphY = This->Mode->CursorRow * GLYPH_HEIGHT;
1669 GraphicsOutput = Private->GraphicsOutput;
1670 UgaDraw = Private->UgaDraw;
1671 if (GraphicsOutput != NULL) {
1672 GraphicsOutput->Blt (
1673 GraphicsOutput,
1674 Private->LineBuffer,
1675 EfiBltBufferToVideo,
1676 0,
1677 0,
1678 GlyphX + Private->ModeData[This->Mode->Mode].DeltaX,
1679 GlyphY + Private->ModeData[This->Mode->Mode].DeltaY,
1680 GLYPH_WIDTH * Count,
1681 GLYPH_HEIGHT,
1682 GLYPH_WIDTH * Count * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
1683 );
1684 } else {
1685 UgaDraw->Blt (
1686 UgaDraw,
1687 (EFI_UGA_PIXEL *) (UINTN) Private->LineBuffer,
1688 EfiUgaBltBufferToVideo,
1689 0,
1690 0,
1691 GlyphX + Private->ModeData[This->Mode->Mode].DeltaX,
1692 GlyphY + Private->ModeData[This->Mode->Mode].DeltaY,
1693 GLYPH_WIDTH * Count,
1694 GLYPH_HEIGHT,
1695 GLYPH_WIDTH * Count * sizeof (EFI_UGA_PIXEL)
1696 );
1697 }
1698
1699 return ReturnStatus;
1700 }
1701
1702 EFI_STATUS
1703 EraseCursor (
1704 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This
1705 )
1706 {
1707 GRAPHICS_CONSOLE_DEV *Private;
1708 EFI_SIMPLE_TEXT_OUTPUT_MODE *CurrentMode;
1709 INTN GlyphX;
1710 INTN GlyphY;
1711 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1712 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1713 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground;
1714 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background;
1715 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar[GLYPH_HEIGHT][GLYPH_WIDTH];
1716 UINTN X;
1717 UINTN Y;
1718
1719 CurrentMode = This->Mode;
1720
1721 if (!CurrentMode->CursorVisible) {
1722 return EFI_SUCCESS;
1723 }
1724
1725 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1726 GraphicsOutput = Private->GraphicsOutput;
1727 UgaDraw = Private->UgaDraw;
1728
1729 //
1730 // BUGBUG - we need to think about what to do with wide and narrow character deletions.
1731 //
1732 //
1733 // Blt a character to the screen
1734 //
1735 GlyphX = (CurrentMode->CursorColumn * GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;
1736 GlyphY = (CurrentMode->CursorRow * GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;
1737 if (GraphicsOutput != NULL) {
1738 GraphicsOutput->Blt (
1739 GraphicsOutput,
1740 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,
1741 EfiBltVideoToBltBuffer,
1742 GlyphX,
1743 GlyphY,
1744 0,
1745 0,
1746 GLYPH_WIDTH,
1747 GLYPH_HEIGHT,
1748 GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
1749 );
1750 } else {
1751 UgaDraw->Blt (
1752 UgaDraw,
1753 (EFI_UGA_PIXEL *) (UINTN) BltChar,
1754 EfiUgaVideoToBltBuffer,
1755 GlyphX,
1756 GlyphY,
1757 0,
1758 0,
1759 GLYPH_WIDTH,
1760 GLYPH_HEIGHT,
1761 GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
1762 );
1763 }
1764
1765 GetTextColors (This, &Foreground.Pixel, &Background.Pixel);
1766
1767 //
1768 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1769 //
1770 for (Y = 0; Y < GLYPH_HEIGHT; Y++) {
1771 for (X = 0; X < GLYPH_WIDTH; X++) {
1772 if ((mCursorGlyph.GlyphCol1[Y] & (1 << X)) != 0) {
1773 BltChar[Y][GLYPH_WIDTH - X - 1].Raw ^= Foreground.Raw;
1774 }
1775 }
1776 }
1777
1778 if (GraphicsOutput != NULL) {
1779 GraphicsOutput->Blt (
1780 GraphicsOutput,
1781 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,
1782 EfiBltBufferToVideo,
1783 0,
1784 0,
1785 GlyphX,
1786 GlyphY,
1787 GLYPH_WIDTH,
1788 GLYPH_HEIGHT,
1789 GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
1790 );
1791 } else {
1792 UgaDraw->Blt (
1793 UgaDraw,
1794 (EFI_UGA_PIXEL *) (UINTN) BltChar,
1795 EfiUgaBltBufferToVideo,
1796 0,
1797 0,
1798 GlyphX,
1799 GlyphY,
1800 GLYPH_WIDTH,
1801 GLYPH_HEIGHT,
1802 GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
1803 );
1804 }
1805
1806 return EFI_SUCCESS;
1807 }