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