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