]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c
Check the handle for font package before remove it.
[mirror_edk2.git] / MdeModulePkg / Universal / Console / GraphicsConsoleDxe / GraphicsConsole.c
CommitLineData
95276127 1/**@file\r
2 This is the main routine for initializing the Graphics Console support routines.\r
3Remaining Tasks\r
8a7d75b0 4 Add all standard Glyphs from UEFI 2.0 Specification\r
95276127 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
9Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
10All rights reserved. This program and the accompanying materials \r
11are licensed and made available under the terms and conditions of the BSD License \r
12which accompanies this distribution. The full text of the license may be found at \r
13http://opensource.org/licenses/bsd-license.php \r
14 \r
15THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
16WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
17\r
18**/\r
19\r
95276127 20#include "GraphicsConsole.h"\r
21\r
22STATIC\r
23EFI_STATUS\r
24GetTextColors (\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
30STATIC\r
31EFI_STATUS\r
32DrawUnicodeWeightAtCursorN (\r
33 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
34 IN CHAR16 *UnicodeWeight,\r
35 IN UINTN Count\r
36 );\r
37\r
38STATIC\r
39EFI_STATUS\r
40EraseCursor (\r
41 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
42 );\r
43\r
3012ce5c 44EFI_STATUS\r
45CheckModeSupported (\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
95276127 52//\r
53// Globals\r
54//\r
55GRAPHICS_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
3012ce5c 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
95276127 84 },\r
85 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
93e3992d 86 (EFI_HII_HANDLE ) 0\r
95276127 87};\r
88\r
93e3992d 89#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)\r
90EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;\r
91EFI_HII_FONT_PROTOCOL *mHiiFont;\r
92BOOLEAN mFirstAccessFlag = TRUE;\r
93\r
94STATIC EFI_GUID mFontPackageListGuid = {0xf5f219d3, 0x7006, 0x4648, 0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad};\r
95\r
96#else\r
95276127 97EFI_HII_PROTOCOL *mHii;\r
93e3992d 98#endif\r
95276127 99\r
100static CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };\r
101\r
102static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {\r
103 //\r
104 // B G R\r
105 //\r
106 {0x00, 0x00, 0x00, 0x00}, // BLACK\r
107 {0x98, 0x00, 0x00, 0x00}, // BLUE\r
108 {0x00, 0x98, 0x00, 0x00}, // GREEN\r
109 {0x98, 0x98, 0x00, 0x00}, // CYAN\r
110 {0x00, 0x00, 0x98, 0x00}, // RED\r
111 {0x98, 0x00, 0x98, 0x00}, // MAGENTA\r
112 {0x00, 0x98, 0x98, 0x00}, // BROWN\r
113 {0x98, 0x98, 0x98, 0x00}, // LIGHTGRAY\r
114 {0x30, 0x30, 0x30, 0x00}, // DARKGRAY - BRIGHT BLACK\r
115 {0xff, 0x00, 0x00, 0x00}, // LIGHTBLUE - ?\r
116 {0x00, 0xff, 0x00, 0x00}, // LIGHTGREEN - ?\r
117 {0xff, 0xff, 0x00, 0x00}, // LIGHTCYAN\r
118 {0x00, 0x00, 0xff, 0x00}, // LIGHTRED\r
119 {0xff, 0x00, 0xff, 0x00}, // LIGHTMAGENTA\r
120 {0x00, 0xff, 0xff, 0x00}, // LIGHTBROWN\r
121 {0xff, 0xff, 0xff, 0x00} // WHITE\r
122};\r
123\r
124static EFI_NARROW_GLYPH mCursorGlyph = {\r
125 0x0000,\r
126 0x00,\r
127 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }\r
128};\r
129\r
130EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding = {\r
131 GraphicsConsoleControllerDriverSupported,\r
132 GraphicsConsoleControllerDriverStart,\r
133 GraphicsConsoleControllerDriverStop,\r
134 0xa,\r
135 NULL,\r
136 NULL\r
137};\r
138\r
139EFI_STATUS\r
140EFIAPI\r
141GraphicsConsoleControllerDriverSupported (\r
142 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
143 IN EFI_HANDLE Controller,\r
144 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
145 )\r
146{\r
147 EFI_STATUS Status;\r
148 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
149 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
150 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
151\r
152 UgaDraw = NULL;\r
153 //\r
154 // Open the IO Abstraction(s) needed to perform the supported test\r
155 //\r
156 Status = gBS->OpenProtocol (\r
157 Controller,\r
158 &gEfiGraphicsOutputProtocolGuid,\r
159 (VOID **) &GraphicsOutput,\r
160 This->DriverBindingHandle,\r
161 Controller,\r
162 EFI_OPEN_PROTOCOL_BY_DRIVER\r
163 );\r
164 \r
165 if (EFI_ERROR (Status)) {\r
166 GraphicsOutput = NULL;\r
167 //\r
168 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol\r
169 //\r
170 Status = gBS->OpenProtocol (\r
171 Controller,\r
172 &gEfiUgaDrawProtocolGuid,\r
173 (VOID **) &UgaDraw,\r
174 This->DriverBindingHandle,\r
175 Controller,\r
176 EFI_OPEN_PROTOCOL_BY_DRIVER\r
177 );\r
178 if (EFI_ERROR (Status)) {\r
179 return Status;\r
180 }\r
181 }\r
182\r
183 //\r
184 // We need to ensure that we do not layer on top of a virtual handle.\r
185 // We need to ensure that the handles produced by the conspliter do not\r
186 // get used.\r
187 //\r
188 Status = gBS->OpenProtocol (\r
189 Controller,\r
190 &gEfiDevicePathProtocolGuid,\r
191 (VOID **) &DevicePath,\r
192 This->DriverBindingHandle,\r
193 Controller,\r
194 EFI_OPEN_PROTOCOL_BY_DRIVER\r
195 );\r
196 if (!EFI_ERROR (Status)) {\r
197 gBS->CloseProtocol (\r
198 Controller,\r
199 &gEfiDevicePathProtocolGuid,\r
200 This->DriverBindingHandle,\r
201 Controller\r
202 );\r
203 } else {\r
204 goto Error;\r
205 }\r
93e3992d 206\r
95276127 207 //\r
208 // Does Hii Exist? If not, we aren't ready to run\r
209 //\r
210 Status = EfiLocateHiiProtocol ();\r
211\r
212 //\r
213 // Close the I/O Abstraction(s) used to perform the supported test\r
214 //\r
215Error:\r
216 if (GraphicsOutput != NULL) {\r
217 gBS->CloseProtocol (\r
218 Controller,\r
219 &gEfiGraphicsOutputProtocolGuid,\r
220 This->DriverBindingHandle,\r
221 Controller\r
222 );\r
223 } else {\r
224 gBS->CloseProtocol (\r
225 Controller,\r
226 &gEfiUgaDrawProtocolGuid,\r
227 This->DriverBindingHandle,\r
228 Controller\r
229 );\r
230 }\r
231 return Status;\r
232}\r
233\r
234EFI_STATUS\r
235EFIAPI\r
236GraphicsConsoleControllerDriverStart (\r
237 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
238 IN EFI_HANDLE Controller,\r
239 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
240 )\r
241/*++\r
242\r
243 Routine Description:\r
244\r
245 Start the controller.\r
246\r
247 Arguments:\r
248\r
249 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
250 Controller - The handle of the controller to start.\r
251 RemainingDevicePath - A pointer to the remaining portion of a devcie path.\r
252\r
253 Returns:\r
254\r
255 EFI_SUCCESS - Return successfully.\r
256 EFI_OUT_OF_RESOURCES - Out of resources.\r
257\r
258--*/\r
259{\r
3012ce5c 260 EFI_STATUS Status;\r
261 GRAPHICS_CONSOLE_DEV *Private;\r
3012ce5c 262 UINTN NarrowFontSize;\r
263 UINT32 HorizontalResolution;\r
264 UINT32 VerticalResolution;\r
265 UINT32 ColorDepth;\r
266 UINT32 RefreshRate;\r
267 UINTN MaxMode;\r
268 UINTN Columns;\r
269 UINTN Rows;\r
95276127 270 UINT32 ModeNumber;\r
93e3992d 271\r
95276127 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
95276127 311 NarrowFontSize = ReturnNarrowFontSize ();\r
312\r
93e3992d 313#if 1\r
314 if (mFirstAccessFlag) {\r
315 HiiLibAddFontPackageToHiiDatabase (NarrowFontSize, (UINT8 *) UsStdNarrowGlyphData, &mFontPackageListGuid, &(Private->HiiHandle));\r
316 mFirstAccessFlag = FALSE;\r
317 }\r
318#else\r
95276127 319 FontPack = AllocateZeroPool (sizeof (EFI_HII_FONT_PACK) + NarrowFontSize);\r
320 ASSERT (FontPack);\r
321\r
322 FontPack->Header.Length = (UINT32) (sizeof (EFI_HII_FONT_PACK) + NarrowFontSize);\r
323 FontPack->Header.Type = EFI_HII_FONT;\r
324 FontPack->NumberOfNarrowGlyphs = (UINT16) (NarrowFontSize / sizeof (EFI_NARROW_GLYPH));\r
325\r
326 Location = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8));\r
327 CopyMem (Location, UsStdNarrowGlyphData, NarrowFontSize);\r
328\r
329 //\r
330 // Register our Fonts into the global database\r
331 //\r
332 Package = PreparePackages (1, NULL, FontPack);\r
333 mHii->NewPack (mHii, Package, &(Private->HiiHandle));\r
334 FreePool (Package);\r
335\r
336 //\r
337 // Free the font database\r
338 //\r
339 FreePool (FontPack);\r
93e3992d 340#endif\r
95276127 341 //\r
342 // If the current mode information can not be retrieved, then attemp to set the default mode\r
343 // of 800x600, 32 bit colot, 60 Hz refresh.\r
344 //\r
345 HorizontalResolution = 800;\r
346 VerticalResolution = 600;\r
347\r
348 if (Private->GraphicsOutput != NULL) {\r
349 //\r
3012ce5c 350 // The console is build on top of Graphics Output Protocol, find the mode number \r
351 // for the user-defined mode; if there are multiple video devices,\r
352 // graphic console driver will set all the video devices to the same mode.\r
95276127 353 //\r
3012ce5c 354 Status = CheckModeSupported (\r
355 Private->GraphicsOutput, \r
356 CURRENT_HORIZONTAL_RESOLUTION, \r
357 CURRENT_VERTICAL_RESOLUTION,\r
358 &ModeNumber\r
359 );\r
360 if (!EFI_ERROR(Status)) {\r
361 //\r
362 // Update default mode to current mode\r
363 //\r
364 HorizontalResolution = CURRENT_HORIZONTAL_RESOLUTION;\r
365 VerticalResolution = CURRENT_VERTICAL_RESOLUTION;\r
366 } else {\r
367 //\r
368 // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec\r
369 //\r
370 Status = CheckModeSupported (\r
371 Private->GraphicsOutput, \r
372 800, \r
373 600, \r
374 &ModeNumber\r
375 );\r
95276127 376 }\r
377\r
378 if (EFI_ERROR (Status) || (ModeNumber == Private->GraphicsOutput->Mode->MaxMode)) {\r
379 //\r
380 // Set default mode failed or device don't support default mode, then get the current mode information\r
381 //\r
382 HorizontalResolution = Private->GraphicsOutput->Mode->Info->HorizontalResolution;\r
383 VerticalResolution = Private->GraphicsOutput->Mode->Info->VerticalResolution;\r
384 ModeNumber = Private->GraphicsOutput->Mode->Mode;\r
385 }\r
386 } else {\r
387 //\r
3012ce5c 388 // At first try to set user-defined resolution\r
95276127 389 //\r
390 ColorDepth = 32;\r
391 RefreshRate = 60;\r
392 Status = Private->UgaDraw->SetMode (\r
393 Private->UgaDraw,\r
3012ce5c 394 CURRENT_HORIZONTAL_RESOLUTION,\r
395 CURRENT_VERTICAL_RESOLUTION,\r
95276127 396 ColorDepth,\r
397 RefreshRate\r
398 );\r
3012ce5c 399 if (!EFI_ERROR (Status)) {\r
400 HorizontalResolution = CURRENT_HORIZONTAL_RESOLUTION;\r
401 VerticalResolution = CURRENT_VERTICAL_RESOLUTION;\r
402 } else {\r
95276127 403 //\r
3012ce5c 404 // Try to set 800*600 which is required by UEFI/EFI spec\r
95276127 405 //\r
3012ce5c 406 Status = Private->UgaDraw->SetMode (\r
95276127 407 Private->UgaDraw,\r
3012ce5c 408 HorizontalResolution,\r
409 VerticalResolution,\r
410 ColorDepth,\r
411 RefreshRate\r
95276127 412 );\r
413 if (EFI_ERROR (Status)) {\r
3012ce5c 414 Status = Private->UgaDraw->GetMode (\r
415 Private->UgaDraw,\r
416 &HorizontalResolution,\r
417 &VerticalResolution,\r
418 &ColorDepth,\r
419 &RefreshRate\r
420 );\r
421 if (EFI_ERROR (Status)) {\r
422 goto Error;\r
423 }\r
95276127 424 }\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 / GLYPH_WIDTH;\r
432 Rows = VerticalResolution / 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 * GLYPH_WIDTH)) >> 1;\r
448 Private->ModeData[MaxMode].DeltaY = (VerticalResolution - (25 * 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 * GLYPH_WIDTH)) >> 1;\r
459 Private->ModeData[MaxMode].DeltaY = (VerticalResolution - (50 * GLYPH_HEIGHT)) >> 1;\r
460 MaxMode++;\r
461 }\r
3012ce5c 462\r
95276127 463 //\r
3012ce5c 464 // If it is not to support Mode #1 - 80x50, then skip it\r
95276127 465 //\r
3012ce5c 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 * GLYPH_WIDTH)) >> 1;\r
485 Private->ModeData[MaxMode].DeltaY = (VerticalResolution - (31 * GLYPH_HEIGHT)) >> 1;\r
486 MaxMode++;\r
487 }\r
95276127 488\r
3012ce5c 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/GLYPH_WIDTH;\r
494 Private->ModeData[MaxMode].Rows = VerticalResolution/GLYPH_HEIGHT; \r
495 Private->ModeData[MaxMode].GopWidth = HorizontalResolution;\r
496 Private->ModeData[MaxMode].GopHeight = VerticalResolution;\r
95276127 497 Private->ModeData[MaxMode].GopModeNumber = ModeNumber;\r
3012ce5c 498 Private->ModeData[MaxMode].DeltaX = (HorizontalResolution % GLYPH_WIDTH) >> 1;\r
499 Private->ModeData[MaxMode].DeltaY = (VerticalResolution % GLYPH_HEIGHT) >> 1;\r
95276127 500 MaxMode++;\r
501 }\r
3012ce5c 502 \r
95276127 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
530Error:\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 {\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
565EFI_STATUS\r
566EFIAPI\r
567GraphicsConsoleControllerDriverStop (\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 {\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
38c0d70a 621 if (Private->HiiHandle != NULL) {\r
622 HiiLibRemovePackages (Private->HiiHandle);\r
623 mFirstAccessFlag = TRUE;\r
624 }\r
95276127 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
3012ce5c 638EFI_STATUS\r
639CheckModeSupported (\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
95276127 681EFI_STATUS\r
682EfiLocateHiiProtocol (\r
683 VOID\r
684 )\r
685/*++\r
686\r
687 Routine Description:\r
93e3992d 688 Locate HII protocols for future usage.\r
95276127 689\r
690 Arguments:\r
691\r
692 Returns:\r
693\r
694--*/\r
695{\r
696 EFI_HANDLE Handle;\r
697 UINTN Size;\r
698 EFI_STATUS Status;\r
699\r
93e3992d 700#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)\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#else\r
736\r
95276127 737 //\r
738 // There should only be one - so buffer size is this\r
739 //\r
740 Size = sizeof (EFI_HANDLE);\r
741\r
742 Status = gBS->LocateHandle (\r
743 ByProtocol,\r
744 &gEfiHiiProtocolGuid,\r
745 NULL,\r
746 &Size,\r
747 &Handle\r
748 );\r
749\r
750 if (EFI_ERROR (Status)) {\r
751 return Status;\r
752 }\r
753\r
754 Status = gBS->HandleProtocol (\r
755 Handle,\r
756 &gEfiHiiProtocolGuid,\r
93e3992d 757 &mHii\r
95276127 758 );\r
759\r
760 return Status;\r
93e3992d 761#endif\r
95276127 762}\r
93e3992d 763\r
95276127 764//\r
765// Body of the STO functions\r
766//\r
767EFI_STATUS\r
768EFIAPI\r
769GraphicsConsoleConOutReset (\r
770 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
771 IN BOOLEAN ExtendedVerification\r
772 )\r
773/*++\r
774 Routine Description:\r
775 \r
776 Implements SIMPLE_TEXT_OUTPUT.Reset().\r
777 If ExtendeVerification is TRUE, then perform dependent Graphics Console \r
778 device reset, and set display mode to mode 0.\r
779 If ExtendedVerification is FALSE, only set display mode to mode 0.\r
780 \r
781 Arguments:\r
782 \r
783 This - Indicates the calling context.\r
784 \r
785 ExtendedVerification - Indicates that the driver may perform a more exhaustive\r
786 verification operation of the device during reset.\r
787 \r
788 Returns:\r
789 \r
790 EFI_SUCCESS\r
791 The reset operation succeeds. \r
792 \r
793 EFI_DEVICE_ERROR\r
794 The Graphics Console is not functioning correctly \r
795 \r
796--*/\r
797{\r
798 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
799 return This->SetMode (This, 0);\r
800}\r
801\r
802EFI_STATUS\r
803EFIAPI\r
804GraphicsConsoleConOutOutputString (\r
805 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
806 IN CHAR16 *WString\r
807 )\r
808/*++\r
809 Routine Description:\r
810 \r
811 Implements SIMPLE_TEXT_OUTPUT.OutputString().\r
812 The Unicode string will be converted to Glyphs and will be \r
813 sent to the Graphics Console.\r
814 \r
815 \r
816 Arguments:\r
817 \r
818 This - Indicates the calling context.\r
819 \r
820 WString - The Null-terminated Unicode string to be displayed on \r
821 the Graphics Console.\r
822 \r
823 Returns:\r
824 \r
825 EFI_SUCCESS\r
826 The string is output successfully. \r
827 \r
828 EFI_DEVICE_ERROR\r
829 The Graphics Console failed to send the string out.\r
830 \r
831 EFI_WARN_UNKNOWN_GLYPH\r
832 Indicates that some of the characters in the Unicode string could not \r
833 be rendered and are skipped. \r
834 \r
835--*/\r
836{\r
837 GRAPHICS_CONSOLE_DEV *Private;\r
838 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
839 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
840 INTN Mode;\r
841 UINTN MaxColumn;\r
842 UINTN MaxRow;\r
843 UINTN Width;\r
844 UINTN Height;\r
845 UINTN Delta;\r
846 EFI_STATUS Status;\r
847 BOOLEAN Warning;\r
848 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
849 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
850 UINTN DeltaX;\r
851 UINTN DeltaY;\r
852 UINTN Count;\r
853 UINTN Index;\r
854 INT32 OriginAttribute;\r
855 EFI_TPL OldTpl;\r
856 CHAR16 SpaceStr[] = { NARROW_CHAR, ' ', 0 };\r
857\r
858 Status = EFI_SUCCESS;\r
859\r
860 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
861 //\r
862 // Current mode\r
863 //\r
864 Mode = This->Mode->Mode;\r
865 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
866 GraphicsOutput = Private->GraphicsOutput;\r
867 UgaDraw = Private->UgaDraw;\r
868\r
869 MaxColumn = Private->ModeData[Mode].Columns;\r
870 MaxRow = Private->ModeData[Mode].Rows;\r
871 DeltaX = Private->ModeData[Mode].DeltaX;\r
872 DeltaY = Private->ModeData[Mode].DeltaY;\r
873 Width = MaxColumn * GLYPH_WIDTH;\r
874 Height = (MaxRow - 1) * GLYPH_HEIGHT;\r
875 Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
876\r
877 //\r
878 // The Attributes won't change when during the time OutputString is called\r
879 //\r
880 GetTextColors (This, &Foreground, &Background);\r
881\r
882 EraseCursor (This);\r
883\r
884 Warning = FALSE;\r
885\r
886 //\r
887 // Backup attribute\r
888 //\r
889 OriginAttribute = This->Mode->Attribute;\r
890\r
891 while (*WString) {\r
892\r
893 if (*WString == CHAR_BACKSPACE) {\r
894 //\r
895 // If the cursor is at the left edge of the display, then move the cursor\r
896 // one row up.\r
897 //\r
898 if (This->Mode->CursorColumn == 0 && This->Mode->CursorRow > 0) {\r
899 This->Mode->CursorRow--;\r
900 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);\r
901 This->OutputString (This, SpaceStr);\r
902 EraseCursor (This);\r
903 This->Mode->CursorRow--;\r
904 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);\r
905 } else if (This->Mode->CursorColumn > 0) {\r
906 //\r
907 // If the cursor is not at the left edge of the display, then move the cursor\r
908 // left one column.\r
909 //\r
910 This->Mode->CursorColumn--;\r
911 This->OutputString (This, SpaceStr);\r
912 EraseCursor (This);\r
913 This->Mode->CursorColumn--;\r
914 }\r
915\r
916 WString++;\r
917\r
918 } else if (*WString == CHAR_LINEFEED) {\r
919 //\r
920 // If the cursor is at the bottom of the display, then scroll the display one\r
921 // row, and do not update the cursor position. Otherwise, move the cursor\r
922 // down one row.\r
923 //\r
924 if (This->Mode->CursorRow == (INT32) (MaxRow - 1)) {\r
925 if (GraphicsOutput != NULL) {\r
926 //\r
927 // Scroll Screen Up One Row\r
928 //\r
929 GraphicsOutput->Blt (\r
930 GraphicsOutput,\r
931 NULL,\r
932 EfiBltVideoToVideo,\r
933 DeltaX,\r
934 DeltaY + GLYPH_HEIGHT,\r
935 DeltaX,\r
936 DeltaY,\r
937 Width,\r
938 Height,\r
939 Delta\r
940 );\r
941\r
942 //\r
943 // Print Blank Line at last line\r
944 //\r
945 GraphicsOutput->Blt (\r
946 GraphicsOutput,\r
947 &Background,\r
948 EfiBltVideoFill,\r
949 0,\r
950 0,\r
951 DeltaX,\r
952 DeltaY + Height,\r
953 Width,\r
954 GLYPH_HEIGHT,\r
955 Delta\r
956 );\r
957 } else {\r
958 //\r
959 // Scroll Screen Up One Row\r
960 //\r
961 UgaDraw->Blt (\r
962 UgaDraw,\r
963 NULL,\r
964 EfiUgaVideoToVideo,\r
965 DeltaX,\r
966 DeltaY + GLYPH_HEIGHT,\r
967 DeltaX,\r
968 DeltaY,\r
969 Width,\r
970 Height,\r
971 Delta\r
972 );\r
973\r
974 //\r
975 // Print Blank Line at last line\r
976 //\r
977 UgaDraw->Blt (\r
978 UgaDraw,\r
979 (EFI_UGA_PIXEL *) (UINTN) &Background,\r
980 EfiUgaVideoFill,\r
981 0,\r
982 0,\r
983 DeltaX,\r
984 DeltaY + Height,\r
985 Width,\r
986 GLYPH_HEIGHT,\r
987 Delta\r
988 );\r
989 }\r
990 } else {\r
991 This->Mode->CursorRow++;\r
992 }\r
993\r
994 WString++;\r
995\r
996 } else if (*WString == CHAR_CARRIAGE_RETURN) {\r
997 //\r
998 // Move the cursor to the beginning of the current row.\r
999 //\r
1000 This->Mode->CursorColumn = 0;\r
1001 WString++;\r
1002\r
1003 } else if (*WString == WIDE_CHAR) {\r
1004\r
1005 This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;\r
1006 WString++;\r
1007\r
1008 } else if (*WString == NARROW_CHAR) {\r
1009\r
1010 This->Mode->Attribute &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);\r
1011 WString++;\r
1012\r
1013 } else {\r
1014 //\r
1015 // Print the character at the current cursor position and move the cursor\r
1016 // right one column. If this moves the cursor past the right edge of the\r
1017 // display, then the line should wrap to the beginning of the next line. This\r
1018 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the\r
1019 // bottom of the display, and the line wraps, then the display will be scrolled\r
1020 // one line.\r
1021 // If wide char is going to be displayed, need to display one character at a time\r
1022 // Or, need to know the display length of a certain string.\r
1023 //\r
1024 // Index is used to determine how many character width units (wide = 2, narrow = 1)\r
1025 // Count is used to determine how many characters are used regardless of their attributes\r
1026 //\r
1027 for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {\r
1028 if (WString[Count] == CHAR_NULL) {\r
1029 break;\r
1030 }\r
1031\r
1032 if (WString[Count] == CHAR_BACKSPACE) {\r
1033 break;\r
1034 }\r
1035\r
1036 if (WString[Count] == CHAR_LINEFEED) {\r
1037 break;\r
1038 }\r
1039\r
1040 if (WString[Count] == CHAR_CARRIAGE_RETURN) {\r
1041 break;\r
1042 }\r
1043\r
1044 if (WString[Count] == WIDE_CHAR) {\r
1045 break;\r
1046 }\r
1047\r
1048 if (WString[Count] == NARROW_CHAR) {\r
1049 break;\r
1050 }\r
1051 //\r
1052 // Is the wide attribute on?\r
1053 //\r
1054 if (This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) {\r
1055 //\r
1056 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop\r
1057 //\r
1058 Index++;\r
1059 //\r
1060 // This is the end-case where if we are at column 79 and about to print a wide character\r
1061 // We should prevent this from happening because we will wrap inappropriately. We should\r
1062 // not print this character until the next line.\r
1063 //\r
1064 if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {\r
1065 Index++;\r
1066 break;\r
1067 }\r
1068 }\r
1069 }\r
1070\r
1071 Status = DrawUnicodeWeightAtCursorN (This, WString, Count);\r
1072 if (EFI_ERROR (Status)) {\r
1073 Warning = TRUE;\r
1074 }\r
1075 //\r
1076 // At the end of line, output carriage return and line feed\r
1077 //\r
1078 WString += Count;\r
1079 This->Mode->CursorColumn += (INT32) Index;\r
1080 if (This->Mode->CursorColumn > (INT32) MaxColumn) {\r
1081 This->Mode->CursorColumn -= 2;\r
1082 This->OutputString (This, SpaceStr);\r
1083 }\r
1084\r
1085 if (This->Mode->CursorColumn >= (INT32) MaxColumn) {\r
1086 EraseCursor (This);\r
1087 This->OutputString (This, mCrLfString);\r
1088 EraseCursor (This);\r
1089 }\r
1090 }\r
1091 }\r
1092\r
1093 This->Mode->Attribute = OriginAttribute;\r
1094\r
1095 EraseCursor (This);\r
1096\r
1097 if (Warning) {\r
1098 Status = EFI_WARN_UNKNOWN_GLYPH;\r
1099 }\r
1100\r
1101 gBS->RestoreTPL (OldTpl);\r
1102 return Status;\r
1103\r
1104}\r
1105\r
1106EFI_STATUS\r
1107EFIAPI\r
1108GraphicsConsoleConOutTestString (\r
1109 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1110 IN CHAR16 *WString\r
1111 )\r
1112/*++\r
1113 Routine Description:\r
1114 \r
1115 Implements SIMPLE_TEXT_OUTPUT.TestString().\r
1116 If one of the characters in the *Wstring is\r
1117 neither valid valid Unicode drawing characters,\r
1118 not ASCII code, then this function will return\r
1119 EFI_UNSUPPORTED.\r
1120 \r
1121 \r
1122 Arguments:\r
1123 \r
1124 This - Indicates the calling context.\r
1125 \r
1126 WString - The Null-terminated Unicode string to be tested.\r
1127 \r
1128 Returns:\r
1129 \r
1130 EFI_SUCCESS\r
1131 The Graphics Console is capable of rendering the output string. \r
1132 \r
1133 EFI_UNSUPPORTED\r
1134 Some of the characters in the Unicode string cannot be rendered. \r
1135 \r
1136--*/\r
1137{\r
1138 EFI_STATUS Status;\r
95276127 1139 UINT16 Count;\r
95276127 1140\r
93e3992d 1141#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)\r
1142 EFI_IMAGE_OUTPUT *Blt = NULL;\r
1143#else\r
1144 UINT16 GlyphWidth;\r
1145 UINT32 GlyphStatus = 0;\r
1146 GLYPH_UNION *Glyph; \r
1147#endif\r
1148\r
1149 Count = 0;\r
1150\r
1151 while (WString[Count] != 0) {\r
1152#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)\r
1153 Status = mHiiFont->GetGlyph (\r
1154 mHiiFont,\r
1155 WString[Count],\r
1156 NULL,\r
1157 &Blt,\r
1158 NULL\r
1159 );\r
1160 SafeFreePool (Blt);\r
1161 Blt = NULL;\r
1162 Count++;\r
1163#else\r
95276127 1164 Status = mHii->GetGlyph (\r
1165 mHii,\r
1166 WString,\r
1167 &Count,\r
1168 (UINT8 **) &Glyph,\r
1169 &GlyphWidth,\r
1170 &GlyphStatus\r
1171 );\r
93e3992d 1172#endif\r
95276127 1173 if (EFI_ERROR (Status)) {\r
1174 return EFI_UNSUPPORTED;\r
1175 }\r
1176 }\r
1177\r
1178 return EFI_SUCCESS;\r
1179}\r
1180\r
1181EFI_STATUS\r
1182EFIAPI\r
1183GraphicsConsoleConOutQueryMode (\r
1184 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1185 IN UINTN ModeNumber,\r
1186 OUT UINTN *Columns,\r
1187 OUT UINTN *Rows\r
1188 )\r
1189/*++\r
1190 Routine Description:\r
1191 \r
1192 Implements SIMPLE_TEXT_OUTPUT.QueryMode().\r
1193 It returnes information for an available text mode\r
1194 that the Graphics Console supports.\r
1195 In this driver,we only support text mode 80x25, which is\r
1196 defined as mode 0.\r
1197 \r
1198 \r
1199 Arguments:\r
1200 \r
1201 This - Indicates the calling context.\r
1202 \r
1203 ModeNumber - The mode number to return information on.\r
1204 \r
1205 Columns - The returned columns of the requested mode.\r
1206 \r
1207 Rows - The returned rows of the requested mode. \r
1208 \r
1209 Returns:\r
1210 \r
1211 EFI_SUCCESS\r
1212 The requested mode information is returned. \r
1213 \r
1214 EFI_UNSUPPORTED\r
1215 The mode number is not valid. \r
1216 \r
1217--*/\r
1218{\r
1219 GRAPHICS_CONSOLE_DEV *Private;\r
1220 EFI_STATUS Status;\r
1221 EFI_TPL OldTpl;\r
7347d5d6 1222 \r
95276127 1223 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {\r
1224 return EFI_UNSUPPORTED;\r
1225 }\r
1226\r
1227 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1228 Status = EFI_SUCCESS;\r
1229 \r
1230 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1231\r
1232 *Columns = Private->ModeData[ModeNumber].Columns;\r
1233 *Rows = Private->ModeData[ModeNumber].Rows;\r
1234\r
1235 if (*Columns <= 0 && *Rows <= 0) {\r
1236 Status = EFI_UNSUPPORTED;\r
1237 goto Done;\r
1238\r
1239 }\r
1240\r
1241Done:\r
1242 gBS->RestoreTPL (OldTpl);\r
1243 return Status;\r
1244}\r
1245\r
1246EFI_STATUS\r
1247EFIAPI\r
1248GraphicsConsoleConOutSetMode (\r
1249 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1250 IN UINTN ModeNumber\r
1251 )\r
1252/*++\r
1253 Routine Description:\r
1254 \r
1255 Implements SIMPLE_TEXT_OUTPUT.SetMode().\r
1256 Set the Graphics Console to a specified mode.\r
1257 In this driver, we only support mode 0. \r
1258 \r
1259 Arguments:\r
1260 \r
1261 This - Indicates the calling context.\r
1262 \r
1263 ModeNumber - The text mode to set.\r
1264 \r
1265 Returns:\r
1266 \r
1267 EFI_SUCCESS\r
1268 The requested text mode is set.\r
1269 \r
1270 EFI_DEVICE_ERROR\r
1271 The requested text mode cannot be set because of Graphics Console device error.\r
1272 \r
1273 EFI_UNSUPPORTED\r
1274 The text mode number is not valid. \r
1275 \r
1276--*/\r
1277{\r
1278 EFI_STATUS Status;\r
1279 GRAPHICS_CONSOLE_DEV *Private;\r
1280 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1281 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewLineBuffer;\r
1282 UINT32 HorizontalResolution;\r
1283 UINT32 VerticalResolution;\r
1284 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1285 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1286 UINT32 ColorDepth;\r
1287 UINT32 RefreshRate;\r
1288 EFI_TPL OldTpl;\r
1289\r
1290 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1291\r
1292 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1293 GraphicsOutput = Private->GraphicsOutput;\r
1294 UgaDraw = Private->UgaDraw;\r
1295 ModeData = &(Private->ModeData[ModeNumber]);\r
1296\r
1297 if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {\r
1298 Status = EFI_UNSUPPORTED;\r
1299 goto Done;\r
1300 }\r
1301\r
1302 //\r
1303 // Make sure the requested mode number is supported\r
1304 //\r
1305 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {\r
1306 Status = EFI_UNSUPPORTED;\r
1307 goto Done;\r
1308 }\r
1309\r
1310 if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {\r
1311 Status = EFI_UNSUPPORTED;\r
1312 goto Done;\r
1313 }\r
1314 //\r
1315 // Attempt to allocate a line buffer for the requested mode number\r
1316 //\r
1317 NewLineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * GLYPH_WIDTH * GLYPH_HEIGHT);\r
1318\r
1319 if (NewLineBuffer == NULL) {\r
1320 //\r
1321 // The new line buffer could not be allocated, so return an error.\r
1322 // No changes to the state of the current console have been made, so the current console is still valid\r
1323 //\r
1324 Status = EFI_OUT_OF_RESOURCES;\r
1325 goto Done;\r
1326 }\r
1327 //\r
1328 // If the mode has been set at least one other time, then LineBuffer will not be NULL\r
1329 //\r
1330 if (Private->LineBuffer != NULL) {\r
1331 //\r
1332 // Clear the current text window on the current graphics console\r
1333 //\r
1334 This->ClearScreen (This);\r
1335\r
1336 //\r
1337 // If the new mode is the same as the old mode, then just return EFI_SUCCESS\r
1338 //\r
1339 if ((INT32) ModeNumber == This->Mode->Mode) {\r
1340 FreePool (NewLineBuffer);\r
1341 Status = EFI_SUCCESS;\r
1342 goto Done;\r
1343 }\r
1344 //\r
7347d5d6 1345 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,\r
1346 // so erase the cursor, and free the LineBuffer for the current mode\r
95276127 1347 //\r
7347d5d6 1348 EraseCursor (This);\r
95276127 1349\r
1350 FreePool (Private->LineBuffer);\r
1351 }\r
1352 //\r
1353 // Assign the current line buffer to the newly allocated line buffer\r
1354 //\r
1355 Private->LineBuffer = NewLineBuffer;\r
1356\r
1357 if (GraphicsOutput != NULL) {\r
1358 if (ModeData->GopModeNumber != GraphicsOutput->Mode->Mode) {\r
1359 //\r
1360 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode\r
1361 //\r
1362 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeData->GopModeNumber);\r
1363 if (EFI_ERROR (Status)) {\r
1364 //\r
1365 // The mode set operation failed\r
1366 //\r
1367 goto Done;\r
1368 }\r
1369 } else {\r
1370 //\r
1371 // The current graphics mode is correct, so simply clear the entire display\r
1372 //\r
1373 Status = GraphicsOutput->Blt (\r
1374 GraphicsOutput,\r
1375 &mEfiColors[0],\r
1376 EfiBltVideoFill,\r
1377 0,\r
1378 0,\r
1379 0,\r
1380 0,\r
1381 ModeData->GopWidth,\r
1382 ModeData->GopHeight,\r
1383 0\r
1384 );\r
1385 }\r
1386 } else {\r
1387 //\r
1388 // Get the current UGA Draw mode information\r
1389 //\r
1390 Status = UgaDraw->GetMode (\r
1391 UgaDraw,\r
1392 &HorizontalResolution,\r
1393 &VerticalResolution,\r
1394 &ColorDepth,\r
1395 &RefreshRate\r
1396 );\r
1397 if (EFI_ERROR (Status) || HorizontalResolution != ModeData->GopWidth || VerticalResolution != ModeData->GopHeight) {\r
1398 //\r
1399 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode\r
1400 //\r
1401 Status = UgaDraw->SetMode (\r
1402 UgaDraw,\r
1403 ModeData->GopWidth,\r
1404 ModeData->GopHeight,\r
1405 32,\r
1406 60\r
1407 );\r
1408 if (EFI_ERROR (Status)) {\r
1409 //\r
1410 // The mode set operation failed\r
1411 //\r
1412 goto Done;\r
1413 }\r
1414 } else {\r
1415 //\r
1416 // The current graphics mode is correct, so simply clear the entire display\r
1417 //\r
1418 Status = UgaDraw->Blt (\r
1419 UgaDraw,\r
1420 (EFI_UGA_PIXEL *) (UINTN) &mEfiColors[0],\r
1421 EfiUgaVideoFill,\r
1422 0,\r
1423 0,\r
1424 0,\r
1425 0,\r
1426 ModeData->GopWidth,\r
1427 ModeData->GopHeight,\r
1428 0\r
1429 );\r
1430 }\r
1431 }\r
1432\r
1433 //\r
1434 // The new mode is valid, so commit the mode change\r
1435 //\r
1436 This->Mode->Mode = (INT32) ModeNumber;\r
1437\r
1438 //\r
1439 // Move the text cursor to the upper left hand corner of the displat and enable it\r
1440 //\r
1441 This->SetCursorPosition (This, 0, 0);\r
95276127 1442\r
1443 Status = EFI_SUCCESS;\r
1444\r
1445Done:\r
1446 gBS->RestoreTPL (OldTpl);\r
1447 return Status;\r
1448}\r
1449\r
1450EFI_STATUS\r
1451EFIAPI\r
1452GraphicsConsoleConOutSetAttribute (\r
1453 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1454 IN UINTN Attribute\r
1455 )\r
1456/*++\r
1457 Routine Description:\r
1458 \r
1459 Implements SIMPLE_TEXT_OUTPUT.SetAttribute(). \r
1460 \r
1461 Arguments:\r
1462 \r
1463 This - Indicates the calling context.\r
1464 \r
1465 Attrubute - The attribute to set. Only bit0..6 are valid, all other bits\r
1466 are undefined and must be zero.\r
1467 \r
1468 Returns:\r
1469 \r
1470 EFI_SUCCESS\r
1471 The requested attribute is set. \r
1472 \r
1473 EFI_DEVICE_ERROR\r
1474 The requested attribute cannot be set due to Graphics Console port error.\r
1475 \r
1476 EFI_UNSUPPORTED\r
1477 The attribute requested is not defined by EFI spec. \r
1478 \r
1479--*/\r
1480{\r
1481 EFI_TPL OldTpl;\r
1482 \r
1483 if ((Attribute | 0xFF) != 0xFF) {\r
1484 return EFI_UNSUPPORTED;\r
1485 }\r
1486\r
1487 if ((INT32) Attribute == This->Mode->Attribute) {\r
1488 return EFI_SUCCESS;\r
1489 }\r
1490\r
1491 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1492\r
1493 EraseCursor (This);\r
1494\r
1495 This->Mode->Attribute = (INT32) Attribute;\r
1496\r
1497 EraseCursor (This);\r
1498\r
1499 gBS->RestoreTPL (OldTpl);\r
1500\r
1501 return EFI_SUCCESS;\r
1502}\r
1503\r
1504EFI_STATUS\r
1505EFIAPI\r
1506GraphicsConsoleConOutClearScreen (\r
1507 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
1508 )\r
1509/*++\r
1510 Routine Description:\r
1511 \r
1512 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().\r
1513 It clears the Graphics Console's display to the \r
1514 currently selected background color.\r
1515 \r
1516 \r
1517 Arguments:\r
1518 \r
1519 This - Indicates the calling context.\r
1520\r
1521 Returns:\r
1522 \r
1523 EFI_SUCCESS\r
1524 The operation completed successfully.\r
1525 \r
1526 EFI_DEVICE_ERROR\r
1527 The Graphics Console cannot be cleared due to Graphics Console device error. \r
1528 \r
1529 EFI_UNSUPPORTED\r
1530 The Graphics Console is not in a valid text mode. \r
1531 \r
1532--*/\r
1533{\r
1534 EFI_STATUS Status;\r
1535 GRAPHICS_CONSOLE_DEV *Private;\r
1536 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1537 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1538 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1539 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
1540 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
1541 EFI_TPL OldTpl;\r
1542\r
1543 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1544\r
1545 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1546 GraphicsOutput = Private->GraphicsOutput;\r
1547 UgaDraw = Private->UgaDraw;\r
1548 ModeData = &(Private->ModeData[This->Mode->Mode]);\r
1549\r
1550 GetTextColors (This, &Foreground, &Background);\r
1551 if (GraphicsOutput != NULL) {\r
1552 Status = GraphicsOutput->Blt (\r
1553 GraphicsOutput,\r
1554 &Background,\r
1555 EfiBltVideoFill,\r
1556 0,\r
1557 0,\r
1558 0,\r
1559 0,\r
1560 ModeData->GopWidth,\r
1561 ModeData->GopHeight,\r
1562 0\r
1563 );\r
1564 } else {\r
1565 Status = UgaDraw->Blt (\r
1566 UgaDraw,\r
1567 (EFI_UGA_PIXEL *) (UINTN) &Background,\r
1568 EfiUgaVideoFill,\r
1569 0,\r
1570 0,\r
1571 0,\r
1572 0,\r
1573 ModeData->GopWidth,\r
1574 ModeData->GopHeight,\r
1575 0\r
1576 );\r
1577 }\r
1578\r
1579 This->Mode->CursorColumn = 0;\r
1580 This->Mode->CursorRow = 0;\r
1581\r
1582 EraseCursor (This);\r
1583\r
1584 gBS->RestoreTPL (OldTpl);\r
1585\r
1586 return Status;\r
1587}\r
1588\r
1589EFI_STATUS\r
1590EFIAPI\r
1591GraphicsConsoleConOutSetCursorPosition (\r
1592 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1593 IN UINTN Column,\r
1594 IN UINTN Row\r
1595 )\r
1596/*++\r
1597 Routine Description:\r
1598 \r
1599 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition(). \r
1600 \r
1601 Arguments:\r
1602 \r
1603 This - Indicates the calling context.\r
1604 \r
1605 Column - The row to set cursor to.\r
1606 \r
1607 Row - The column to set cursor to. \r
1608\r
1609 Returns:\r
1610 \r
1611 EFI_SUCCESS\r
1612 The operation completed successfully.\r
1613 \r
1614 EFI_DEVICE_ERROR\r
1615 The request fails due to Graphics Console device error. \r
1616 \r
1617 EFI_UNSUPPORTED\r
1618 The Graphics Console is not in a valid text mode, or the cursor position\r
1619 is invalid for current mode. \r
1620 \r
1621--*/\r
1622{\r
1623 GRAPHICS_CONSOLE_DEV *Private;\r
1624 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1625 EFI_STATUS Status;\r
1626 EFI_TPL OldTpl;\r
1627\r
1628 Status = EFI_SUCCESS;\r
1629\r
1630 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1631\r
1632 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1633 ModeData = &(Private->ModeData[This->Mode->Mode]);\r
1634\r
1635 if ((Column >= ModeData->Columns) || (Row >= ModeData->Rows)) {\r
1636 Status = EFI_UNSUPPORTED;\r
1637 goto Done;\r
1638 }\r
1639\r
1640 if (((INT32) Column == This->Mode->CursorColumn) && ((INT32) Row == This->Mode->CursorRow)) {\r
1641 Status = EFI_SUCCESS;\r
1642 goto Done;\r
1643 }\r
1644\r
1645 EraseCursor (This);\r
1646\r
1647 This->Mode->CursorColumn = (INT32) Column;\r
1648 This->Mode->CursorRow = (INT32) Row;\r
1649\r
1650 EraseCursor (This);\r
1651\r
1652Done:\r
1653 gBS->RestoreTPL (OldTpl);\r
1654\r
1655 return Status;\r
1656}\r
1657\r
1658EFI_STATUS\r
1659EFIAPI\r
1660GraphicsConsoleConOutEnableCursor (\r
1661 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1662 IN BOOLEAN Visible\r
1663 )\r
1664/*++\r
1665 Routine Description:\r
1666 \r
1667 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().\r
1668 In this driver, the cursor cannot be hidden. \r
1669 \r
1670 Arguments:\r
1671 \r
1672 This - Indicates the calling context.\r
1673 \r
1674 Visible - If TRUE, the cursor is set to be visible,\r
1675 If FALSE, the cursor is set to be invisible. \r
1676\r
1677 Returns:\r
1678 \r
1679 EFI_SUCCESS\r
1680 The request is valid.\r
1681 \r
1682 EFI_UNSUPPORTED\r
1683 The Graphics Console does not support a hidden cursor. \r
1684 \r
1685--*/\r
1686{\r
1687 EFI_TPL OldTpl;\r
1688 \r
1689 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1690 \r
1691 EraseCursor (This);\r
1692\r
1693 This->Mode->CursorVisible = Visible;\r
1694\r
1695 EraseCursor (This);\r
1696\r
1697 gBS->RestoreTPL (OldTpl);\r
1698 return EFI_SUCCESS;\r
1699}\r
1700\r
1701STATIC\r
1702EFI_STATUS\r
1703GetTextColors (\r
1704 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1705 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
1706 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background\r
1707 )\r
1708{\r
1709 INTN Attribute;\r
1710\r
1711 Attribute = This->Mode->Attribute & 0x7F;\r
1712\r
1713 *Foreground = mEfiColors[Attribute & 0x0f];\r
1714 *Background = mEfiColors[Attribute >> 4];\r
1715\r
1716 return EFI_SUCCESS;\r
1717}\r
1718\r
93e3992d 1719#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)\r
1720EFI_STATUS\r
1721DrawUnicodeWeightAtCursorN (\r
1722 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1723 IN CHAR16 *UnicodeWeight,\r
1724 IN UINTN Count\r
1725 )\r
1726{\r
1727 EFI_STATUS Status;\r
1728 GRAPHICS_CONSOLE_DEV *Private;\r
1729 EFI_IMAGE_OUTPUT *Blt;\r
1730 EFI_STRING String;\r
1731 EFI_FONT_DISPLAY_INFO *FontInfo;\r
1732\r
1733 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1734 //\r
1735 // GOP protocol is required in UEFI mode.\r
1736 //\r
1737 ASSERT (Private->GraphicsOutput != NULL);\r
1738\r
1739 Blt = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
1740 if (Blt == NULL) {\r
1741 return EFI_OUT_OF_RESOURCES;\r
1742 }\r
1743\r
1744 Blt->Width = (UINT16) (Private->ModeData[This->Mode->Mode].GopWidth);\r
1745 Blt->Height = (UINT16) (Private->ModeData[This->Mode->Mode].GopHeight);\r
1746 Blt->Image.Screen = Private->GraphicsOutput;\r
1747\r
1748 String = AllocateCopyPool ((Count + 1) * sizeof (CHAR16), UnicodeWeight);\r
1749 if (String == NULL) {\r
1750 SafeFreePool (Blt);\r
1751 return EFI_OUT_OF_RESOURCES;\r
1752 }\r
1753 *(String + Count) = 0;\r
1754\r
1755 FontInfo = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));\r
1756 if (FontInfo == NULL) {\r
1757 SafeFreePool (Blt);\r
1758 SafeFreePool (String);\r
1759 return EFI_OUT_OF_RESOURCES;\r
1760 }\r
1761 GetTextColors (This, &FontInfo->ForegroundColor, &FontInfo->BackgroundColor);\r
1762\r
1763 Status = mHiiFont->StringToImage (\r
1764 mHiiFont,\r
1765 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN,\r
1766 String,\r
1767 FontInfo,\r
1768 &Blt,\r
1769 This->Mode->CursorColumn * GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1770 This->Mode->CursorRow * GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
1771 NULL,\r
1772 NULL,\r
1773 NULL\r
1774 );\r
1775\r
1776 SafeFreePool (Blt);\r
1777 SafeFreePool (String);\r
1778 SafeFreePool (FontInfo);\r
1779 return Status;\r
1780}\r
1781#else\r
95276127 1782STATIC\r
1783EFI_STATUS\r
1784DrawUnicodeWeightAtCursorN (\r
1785 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1786 IN CHAR16 *UnicodeWeight,\r
1787 IN UINTN Count\r
1788 )\r
1789{\r
1790 GRAPHICS_CONSOLE_DEV *Private;\r
1791 EFI_STATUS Status;\r
1792 EFI_STATUS ReturnStatus;\r
1793 GLYPH_UNION *Glyph;\r
1794 GLYPH_UNION GlyphData;\r
1795 INTN GlyphX;\r
1796 INTN GlyphY;\r
1797 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1798 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1799 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
1800 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
1801 UINTN Index;\r
1802 UINTN ArrayIndex;\r
1803 UINTN Counts;\r
1804 UINT16 GlyphWidth;\r
1805 UINT32 GlyphStatus;\r
1806\r
1807 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1808\r
1809 ReturnStatus = EFI_SUCCESS;\r
1810 GlyphStatus = 0;\r
1811 GlyphWidth = 0x08;\r
1812\r
1813 GetTextColors (This, &Foreground, &Background);\r
1814\r
1815 Index = 0;\r
1816 ArrayIndex = 0;\r
1817 while (Index < Count) {\r
1818 if (This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) {\r
1819 GlyphStatus = WIDE_CHAR;\r
1820 } else {\r
1821 GlyphStatus = NARROW_CHAR;\r
1822 }\r
1823\r
1824 Status = mHii->GetGlyph (\r
1825 mHii,\r
1826 UnicodeWeight,\r
1827 (UINT16 *) &Index,\r
1828 (UINT8 **) &Glyph,\r
1829 &GlyphWidth,\r
1830 &GlyphStatus\r
1831 );\r
1832 if (EFI_ERROR (Status)) {\r
1833 ReturnStatus = Status;\r
1834 }\r
1835\r
1836 Counts = 0;\r
1837\r
1838 CopyMem (&GlyphData, Glyph, sizeof (GLYPH_UNION));\r
1839\r
1840 do {\r
1841 //\r
1842 // We are creating the second half of the wide character's BLT buffer\r
1843 //\r
1844 if (GlyphWidth == 0x10 && Counts == 1) {\r
1845 CopyMem (&GlyphData.NarrowGlyph.GlyphCol1, &Glyph->WideGlyph.GlyphCol2, sizeof (Glyph->WideGlyph.GlyphCol2));\r
1846 }\r
1847\r
1848 Counts++;\r
1849\r
1850 if (GlyphWidth == 0x10) {\r
1851 mHii->GlyphToBlt (\r
1852 mHii,\r
1853 (UINT8 *) &GlyphData,\r
1854 Foreground,\r
1855 Background,\r
1856 Count * 2,\r
1857 GLYPH_WIDTH,\r
1858 GLYPH_HEIGHT,\r
1859 &Private->LineBuffer[ArrayIndex * GLYPH_WIDTH]\r
1860 );\r
1861 } else {\r
1862 mHii->GlyphToBlt (\r
1863 mHii,\r
1864 (UINT8 *) &GlyphData,\r
1865 Foreground,\r
1866 Background,\r
1867 Count,\r
1868 GLYPH_WIDTH,\r
1869 GLYPH_HEIGHT,\r
1870 &Private->LineBuffer[ArrayIndex * GLYPH_WIDTH]\r
1871 );\r
1872 }\r
1873\r
1874 ArrayIndex++;\r
1875\r
1876 } while (Counts < 2 && GlyphWidth == 0x10);\r
1877\r
1878 }\r
1879 //\r
1880 // If we are printing Wide characters, treat the BLT as if it is twice as many characters\r
1881 //\r
1882 if (GlyphWidth == 0x10) {\r
1883 Count = Count * 2;\r
1884 }\r
1885 //\r
1886 // Blt a character to the screen\r
1887 //\r
1888 GlyphX = This->Mode->CursorColumn * GLYPH_WIDTH;\r
1889 GlyphY = This->Mode->CursorRow * GLYPH_HEIGHT;\r
1890 GraphicsOutput = Private->GraphicsOutput;\r
1891 UgaDraw = Private->UgaDraw;\r
1892 if (GraphicsOutput != NULL) {\r
1893 GraphicsOutput->Blt (\r
1894 GraphicsOutput,\r
1895 Private->LineBuffer,\r
1896 EfiBltBufferToVideo,\r
1897 0,\r
1898 0,\r
1899 GlyphX + Private->ModeData[This->Mode->Mode].DeltaX,\r
1900 GlyphY + Private->ModeData[This->Mode->Mode].DeltaY,\r
1901 GLYPH_WIDTH * Count,\r
1902 GLYPH_HEIGHT,\r
1903 GLYPH_WIDTH * Count * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1904 );\r
1905 } else {\r
1906 UgaDraw->Blt (\r
1907 UgaDraw,\r
1908 (EFI_UGA_PIXEL *) (UINTN) Private->LineBuffer,\r
1909 EfiUgaBltBufferToVideo,\r
1910 0,\r
1911 0,\r
1912 GlyphX + Private->ModeData[This->Mode->Mode].DeltaX,\r
1913 GlyphY + Private->ModeData[This->Mode->Mode].DeltaY,\r
1914 GLYPH_WIDTH * Count,\r
1915 GLYPH_HEIGHT,\r
1916 GLYPH_WIDTH * Count * sizeof (EFI_UGA_PIXEL)\r
1917 );\r
1918 }\r
1919\r
1920 return ReturnStatus;\r
1921}\r
93e3992d 1922#endif\r
95276127 1923\r
1924STATIC\r
1925EFI_STATUS\r
1926EraseCursor (\r
1927 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
1928 )\r
1929{\r
1930 GRAPHICS_CONSOLE_DEV *Private;\r
1931 EFI_SIMPLE_TEXT_OUTPUT_MODE *CurrentMode;\r
1932 INTN GlyphX;\r
1933 INTN GlyphY;\r
1934 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1935 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1936 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground;\r
1937 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background;\r
1938 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar[GLYPH_HEIGHT][GLYPH_WIDTH];\r
1939 UINTN X;\r
1940 UINTN Y;\r
1941\r
1942 CurrentMode = This->Mode;\r
1943\r
1944 if (!CurrentMode->CursorVisible) {\r
1945 return EFI_SUCCESS;\r
1946 }\r
1947\r
1948 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1949 GraphicsOutput = Private->GraphicsOutput;\r
1950 UgaDraw = Private->UgaDraw;\r
1951\r
1952 //\r
1953 // BUGBUG - we need to think about what to do with wide and narrow character deletions.\r
1954 //\r
1955 //\r
1956 // Blt a character to the screen\r
1957 //\r
1958 GlyphX = (CurrentMode->CursorColumn * GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;\r
1959 GlyphY = (CurrentMode->CursorRow * GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;\r
1960 if (GraphicsOutput != NULL) {\r
1961 GraphicsOutput->Blt (\r
1962 GraphicsOutput,\r
1963 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,\r
1964 EfiBltVideoToBltBuffer,\r
1965 GlyphX,\r
1966 GlyphY,\r
1967 0,\r
1968 0,\r
1969 GLYPH_WIDTH,\r
1970 GLYPH_HEIGHT,\r
1971 GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1972 );\r
1973 } else {\r
1974 UgaDraw->Blt (\r
1975 UgaDraw,\r
1976 (EFI_UGA_PIXEL *) (UINTN) BltChar,\r
1977 EfiUgaVideoToBltBuffer,\r
1978 GlyphX,\r
1979 GlyphY,\r
1980 0,\r
1981 0,\r
1982 GLYPH_WIDTH,\r
1983 GLYPH_HEIGHT,\r
1984 GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
1985 );\r
1986 }\r
1987\r
1988 GetTextColors (This, &Foreground.Pixel, &Background.Pixel);\r
1989\r
1990 //\r
1991 // Convert Monochrome bitmap of the Glyph to BltBuffer structure\r
1992 //\r
1993 for (Y = 0; Y < GLYPH_HEIGHT; Y++) {\r
1994 for (X = 0; X < GLYPH_WIDTH; X++) {\r
1995 if ((mCursorGlyph.GlyphCol1[Y] & (1 << X)) != 0) {\r
1996 BltChar[Y][GLYPH_WIDTH - X - 1].Raw ^= Foreground.Raw;\r
1997 }\r
1998 }\r
1999 }\r
2000\r
2001 if (GraphicsOutput != NULL) {\r
2002 GraphicsOutput->Blt (\r
2003 GraphicsOutput,\r
2004 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,\r
2005 EfiBltBufferToVideo,\r
2006 0,\r
2007 0,\r
2008 GlyphX,\r
2009 GlyphY,\r
2010 GLYPH_WIDTH,\r
2011 GLYPH_HEIGHT,\r
2012 GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
2013 );\r
2014 } else {\r
2015 UgaDraw->Blt (\r
2016 UgaDraw,\r
2017 (EFI_UGA_PIXEL *) (UINTN) BltChar,\r
2018 EfiUgaBltBufferToVideo,\r
2019 0,\r
2020 0,\r
2021 GlyphX,\r
2022 GlyphY,\r
2023 GLYPH_WIDTH,\r
2024 GLYPH_HEIGHT,\r
2025 GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
2026 );\r
2027 }\r
2028\r
2029 return EFI_SUCCESS;\r
2030}\r
97a079ed
A
2031\r
2032/**\r
2033 The user Entry Point for module GraphicsConsole. The user code starts with this function.\r
2034\r
2035 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
2036 @param[in] SystemTable A pointer to the EFI System Table.\r
2037 \r
2038 @retval EFI_SUCCESS The entry point is executed successfully.\r
2039 @retval other Some error occurs when executing this entry point.\r
2040\r
2041**/\r
2042EFI_STATUS\r
2043EFIAPI\r
2044InitializeGraphicsConsole (\r
2045 IN EFI_HANDLE ImageHandle,\r
2046 IN EFI_SYSTEM_TABLE *SystemTable\r
2047 )\r
2048{\r
2049 EFI_STATUS Status;\r
2050\r
2051 //\r
2052 // Install driver model protocol(s).\r
2053 //\r
5bca971e 2054 Status = EfiLibInstallDriverBindingComponentName2 (\r
97a079ed
A
2055 ImageHandle,\r
2056 SystemTable,\r
2057 &gGraphicsConsoleDriverBinding,\r
2058 ImageHandle,\r
2059 &gGraphicsConsoleComponentName,\r
5bca971e 2060 &gGraphicsConsoleComponentName2\r
97a079ed
A
2061 );\r
2062 ASSERT_EFI_ERROR (Status);\r
2063\r
2064\r
2065 return Status;\r
2066}\r
2067\r