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