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