]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c
UEFI HII: Merge UEFI HII support changes from branch.
[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
93e3992d 621#if 1\r
622 Status = HiiLibRemovePackagesFromHiiDatabase (Private->HiiHandle);\r
623 if (!EFI_ERROR (Status)) {\r
624 mFirstAccessFlag = TRUE;\r
625 }\r
626#else \r
95276127 627 mHii->RemovePack (mHii, Private->HiiHandle);\r
93e3992d 628#endif\r
95276127 629\r
630 //\r
631 // Free our instance data\r
632 //\r
633 if (Private != NULL) {\r
634 FreePool (Private->LineBuffer);\r
635 FreePool (Private);\r
636 }\r
637 }\r
638\r
639 return Status;\r
640}\r
641\r
3012ce5c 642EFI_STATUS\r
643CheckModeSupported (\r
644 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
645 IN UINT32 HorizontalResolution,\r
646 IN UINT32 VerticalResolution,\r
647 OUT UINT32 *CurrentModeNumber\r
648 )\r
649{\r
650 UINT32 ModeNumber;\r
651 EFI_STATUS Status;\r
652 UINTN SizeOfInfo; \r
653 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
654 \r
655 Status = EFI_SUCCESS;\r
656 \r
657 for (ModeNumber = 0; ModeNumber < GraphicsOutput->Mode->MaxMode; ModeNumber++) {\r
658 Status = GraphicsOutput->QueryMode (\r
659 GraphicsOutput,\r
660 ModeNumber,\r
661 &SizeOfInfo,\r
662 &Info\r
663 );\r
664 if (!EFI_ERROR (Status)) {\r
665 if ((Info->HorizontalResolution == HorizontalResolution) &&\r
666 (Info->VerticalResolution == VerticalResolution)) {\r
667 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);\r
668 if (!EFI_ERROR (Status)) {\r
669 gBS->FreePool (Info);\r
670 break;\r
671 }\r
672 }\r
673 gBS->FreePool (Info);\r
674 }\r
675 }\r
676 \r
677 if (ModeNumber == GraphicsOutput->Mode->MaxMode) {\r
678 Status = EFI_UNSUPPORTED;\r
679 }\r
680 \r
681 *CurrentModeNumber = ModeNumber;\r
682 return Status; \r
683}\r
684\r
95276127 685EFI_STATUS\r
686EfiLocateHiiProtocol (\r
687 VOID\r
688 )\r
689/*++\r
690\r
691 Routine Description:\r
93e3992d 692 Locate HII protocols for future usage.\r
95276127 693\r
694 Arguments:\r
695\r
696 Returns:\r
697\r
698--*/\r
699{\r
700 EFI_HANDLE Handle;\r
701 UINTN Size;\r
702 EFI_STATUS Status;\r
703\r
93e3992d 704#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)\r
705\r
706 //\r
707 // There should only be one - so buffer size is this\r
708 //\r
709 Size = sizeof (EFI_HANDLE);\r
710\r
711 Status = gBS->LocateHandle (\r
712 ByProtocol,\r
713 &gEfiHiiDatabaseProtocolGuid,\r
714 NULL,\r
715 &Size,\r
716 (VOID **) &Handle\r
717 );\r
718\r
719 if (EFI_ERROR (Status)) {\r
720 return Status;\r
721 }\r
722\r
723 Status = gBS->HandleProtocol (\r
724 Handle,\r
725 &gEfiHiiDatabaseProtocolGuid,\r
726 (VOID **) &mHiiDatabase\r
727 );\r
728\r
729 if (EFI_ERROR (Status)) {\r
730 return Status;\r
731 }\r
732\r
733 Status = gBS->HandleProtocol (\r
734 Handle,\r
735 &gEfiHiiFontProtocolGuid,\r
736 (VOID **) &mHiiFont\r
737 );\r
738 return Status;\r
739#else\r
740\r
95276127 741 //\r
742 // There should only be one - so buffer size is this\r
743 //\r
744 Size = sizeof (EFI_HANDLE);\r
745\r
746 Status = gBS->LocateHandle (\r
747 ByProtocol,\r
748 &gEfiHiiProtocolGuid,\r
749 NULL,\r
750 &Size,\r
751 &Handle\r
752 );\r
753\r
754 if (EFI_ERROR (Status)) {\r
755 return Status;\r
756 }\r
757\r
758 Status = gBS->HandleProtocol (\r
759 Handle,\r
760 &gEfiHiiProtocolGuid,\r
93e3992d 761 &mHii\r
95276127 762 );\r
763\r
764 return Status;\r
93e3992d 765#endif\r
95276127 766}\r
93e3992d 767\r
95276127 768//\r
769// Body of the STO functions\r
770//\r
771EFI_STATUS\r
772EFIAPI\r
773GraphicsConsoleConOutReset (\r
774 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
775 IN BOOLEAN ExtendedVerification\r
776 )\r
777/*++\r
778 Routine Description:\r
779 \r
780 Implements SIMPLE_TEXT_OUTPUT.Reset().\r
781 If ExtendeVerification is TRUE, then perform dependent Graphics Console \r
782 device reset, and set display mode to mode 0.\r
783 If ExtendedVerification is FALSE, only set display mode to mode 0.\r
784 \r
785 Arguments:\r
786 \r
787 This - Indicates the calling context.\r
788 \r
789 ExtendedVerification - Indicates that the driver may perform a more exhaustive\r
790 verification operation of the device during reset.\r
791 \r
792 Returns:\r
793 \r
794 EFI_SUCCESS\r
795 The reset operation succeeds. \r
796 \r
797 EFI_DEVICE_ERROR\r
798 The Graphics Console is not functioning correctly \r
799 \r
800--*/\r
801{\r
802 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
803 return This->SetMode (This, 0);\r
804}\r
805\r
806EFI_STATUS\r
807EFIAPI\r
808GraphicsConsoleConOutOutputString (\r
809 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
810 IN CHAR16 *WString\r
811 )\r
812/*++\r
813 Routine Description:\r
814 \r
815 Implements SIMPLE_TEXT_OUTPUT.OutputString().\r
816 The Unicode string will be converted to Glyphs and will be \r
817 sent to the Graphics Console.\r
818 \r
819 \r
820 Arguments:\r
821 \r
822 This - Indicates the calling context.\r
823 \r
824 WString - The Null-terminated Unicode string to be displayed on \r
825 the Graphics Console.\r
826 \r
827 Returns:\r
828 \r
829 EFI_SUCCESS\r
830 The string is output successfully. \r
831 \r
832 EFI_DEVICE_ERROR\r
833 The Graphics Console failed to send the string out.\r
834 \r
835 EFI_WARN_UNKNOWN_GLYPH\r
836 Indicates that some of the characters in the Unicode string could not \r
837 be rendered and are skipped. \r
838 \r
839--*/\r
840{\r
841 GRAPHICS_CONSOLE_DEV *Private;\r
842 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
843 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
844 INTN Mode;\r
845 UINTN MaxColumn;\r
846 UINTN MaxRow;\r
847 UINTN Width;\r
848 UINTN Height;\r
849 UINTN Delta;\r
850 EFI_STATUS Status;\r
851 BOOLEAN Warning;\r
852 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
853 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
854 UINTN DeltaX;\r
855 UINTN DeltaY;\r
856 UINTN Count;\r
857 UINTN Index;\r
858 INT32 OriginAttribute;\r
859 EFI_TPL OldTpl;\r
860 CHAR16 SpaceStr[] = { NARROW_CHAR, ' ', 0 };\r
861\r
862 Status = EFI_SUCCESS;\r
863\r
864 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
865 //\r
866 // Current mode\r
867 //\r
868 Mode = This->Mode->Mode;\r
869 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
870 GraphicsOutput = Private->GraphicsOutput;\r
871 UgaDraw = Private->UgaDraw;\r
872\r
873 MaxColumn = Private->ModeData[Mode].Columns;\r
874 MaxRow = Private->ModeData[Mode].Rows;\r
875 DeltaX = Private->ModeData[Mode].DeltaX;\r
876 DeltaY = Private->ModeData[Mode].DeltaY;\r
877 Width = MaxColumn * GLYPH_WIDTH;\r
878 Height = (MaxRow - 1) * GLYPH_HEIGHT;\r
879 Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
880\r
881 //\r
882 // The Attributes won't change when during the time OutputString is called\r
883 //\r
884 GetTextColors (This, &Foreground, &Background);\r
885\r
886 EraseCursor (This);\r
887\r
888 Warning = FALSE;\r
889\r
890 //\r
891 // Backup attribute\r
892 //\r
893 OriginAttribute = This->Mode->Attribute;\r
894\r
895 while (*WString) {\r
896\r
897 if (*WString == CHAR_BACKSPACE) {\r
898 //\r
899 // If the cursor is at the left edge of the display, then move the cursor\r
900 // one row up.\r
901 //\r
902 if (This->Mode->CursorColumn == 0 && This->Mode->CursorRow > 0) {\r
903 This->Mode->CursorRow--;\r
904 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);\r
905 This->OutputString (This, SpaceStr);\r
906 EraseCursor (This);\r
907 This->Mode->CursorRow--;\r
908 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);\r
909 } else if (This->Mode->CursorColumn > 0) {\r
910 //\r
911 // If the cursor is not at the left edge of the display, then move the cursor\r
912 // left one column.\r
913 //\r
914 This->Mode->CursorColumn--;\r
915 This->OutputString (This, SpaceStr);\r
916 EraseCursor (This);\r
917 This->Mode->CursorColumn--;\r
918 }\r
919\r
920 WString++;\r
921\r
922 } else if (*WString == CHAR_LINEFEED) {\r
923 //\r
924 // If the cursor is at the bottom of the display, then scroll the display one\r
925 // row, and do not update the cursor position. Otherwise, move the cursor\r
926 // down one row.\r
927 //\r
928 if (This->Mode->CursorRow == (INT32) (MaxRow - 1)) {\r
929 if (GraphicsOutput != NULL) {\r
930 //\r
931 // Scroll Screen Up One Row\r
932 //\r
933 GraphicsOutput->Blt (\r
934 GraphicsOutput,\r
935 NULL,\r
936 EfiBltVideoToVideo,\r
937 DeltaX,\r
938 DeltaY + GLYPH_HEIGHT,\r
939 DeltaX,\r
940 DeltaY,\r
941 Width,\r
942 Height,\r
943 Delta\r
944 );\r
945\r
946 //\r
947 // Print Blank Line at last line\r
948 //\r
949 GraphicsOutput->Blt (\r
950 GraphicsOutput,\r
951 &Background,\r
952 EfiBltVideoFill,\r
953 0,\r
954 0,\r
955 DeltaX,\r
956 DeltaY + Height,\r
957 Width,\r
958 GLYPH_HEIGHT,\r
959 Delta\r
960 );\r
961 } else {\r
962 //\r
963 // Scroll Screen Up One Row\r
964 //\r
965 UgaDraw->Blt (\r
966 UgaDraw,\r
967 NULL,\r
968 EfiUgaVideoToVideo,\r
969 DeltaX,\r
970 DeltaY + GLYPH_HEIGHT,\r
971 DeltaX,\r
972 DeltaY,\r
973 Width,\r
974 Height,\r
975 Delta\r
976 );\r
977\r
978 //\r
979 // Print Blank Line at last line\r
980 //\r
981 UgaDraw->Blt (\r
982 UgaDraw,\r
983 (EFI_UGA_PIXEL *) (UINTN) &Background,\r
984 EfiUgaVideoFill,\r
985 0,\r
986 0,\r
987 DeltaX,\r
988 DeltaY + Height,\r
989 Width,\r
990 GLYPH_HEIGHT,\r
991 Delta\r
992 );\r
993 }\r
994 } else {\r
995 This->Mode->CursorRow++;\r
996 }\r
997\r
998 WString++;\r
999\r
1000 } else if (*WString == CHAR_CARRIAGE_RETURN) {\r
1001 //\r
1002 // Move the cursor to the beginning of the current row.\r
1003 //\r
1004 This->Mode->CursorColumn = 0;\r
1005 WString++;\r
1006\r
1007 } else if (*WString == WIDE_CHAR) {\r
1008\r
1009 This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;\r
1010 WString++;\r
1011\r
1012 } else if (*WString == NARROW_CHAR) {\r
1013\r
1014 This->Mode->Attribute &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);\r
1015 WString++;\r
1016\r
1017 } else {\r
1018 //\r
1019 // Print the character at the current cursor position and move the cursor\r
1020 // right one column. If this moves the cursor past the right edge of the\r
1021 // display, then the line should wrap to the beginning of the next line. This\r
1022 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the\r
1023 // bottom of the display, and the line wraps, then the display will be scrolled\r
1024 // one line.\r
1025 // If wide char is going to be displayed, need to display one character at a time\r
1026 // Or, need to know the display length of a certain string.\r
1027 //\r
1028 // Index is used to determine how many character width units (wide = 2, narrow = 1)\r
1029 // Count is used to determine how many characters are used regardless of their attributes\r
1030 //\r
1031 for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {\r
1032 if (WString[Count] == CHAR_NULL) {\r
1033 break;\r
1034 }\r
1035\r
1036 if (WString[Count] == CHAR_BACKSPACE) {\r
1037 break;\r
1038 }\r
1039\r
1040 if (WString[Count] == CHAR_LINEFEED) {\r
1041 break;\r
1042 }\r
1043\r
1044 if (WString[Count] == CHAR_CARRIAGE_RETURN) {\r
1045 break;\r
1046 }\r
1047\r
1048 if (WString[Count] == WIDE_CHAR) {\r
1049 break;\r
1050 }\r
1051\r
1052 if (WString[Count] == NARROW_CHAR) {\r
1053 break;\r
1054 }\r
1055 //\r
1056 // Is the wide attribute on?\r
1057 //\r
1058 if (This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) {\r
1059 //\r
1060 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop\r
1061 //\r
1062 Index++;\r
1063 //\r
1064 // This is the end-case where if we are at column 79 and about to print a wide character\r
1065 // We should prevent this from happening because we will wrap inappropriately. We should\r
1066 // not print this character until the next line.\r
1067 //\r
1068 if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {\r
1069 Index++;\r
1070 break;\r
1071 }\r
1072 }\r
1073 }\r
1074\r
1075 Status = DrawUnicodeWeightAtCursorN (This, WString, Count);\r
1076 if (EFI_ERROR (Status)) {\r
1077 Warning = TRUE;\r
1078 }\r
1079 //\r
1080 // At the end of line, output carriage return and line feed\r
1081 //\r
1082 WString += Count;\r
1083 This->Mode->CursorColumn += (INT32) Index;\r
1084 if (This->Mode->CursorColumn > (INT32) MaxColumn) {\r
1085 This->Mode->CursorColumn -= 2;\r
1086 This->OutputString (This, SpaceStr);\r
1087 }\r
1088\r
1089 if (This->Mode->CursorColumn >= (INT32) MaxColumn) {\r
1090 EraseCursor (This);\r
1091 This->OutputString (This, mCrLfString);\r
1092 EraseCursor (This);\r
1093 }\r
1094 }\r
1095 }\r
1096\r
1097 This->Mode->Attribute = OriginAttribute;\r
1098\r
1099 EraseCursor (This);\r
1100\r
1101 if (Warning) {\r
1102 Status = EFI_WARN_UNKNOWN_GLYPH;\r
1103 }\r
1104\r
1105 gBS->RestoreTPL (OldTpl);\r
1106 return Status;\r
1107\r
1108}\r
1109\r
1110EFI_STATUS\r
1111EFIAPI\r
1112GraphicsConsoleConOutTestString (\r
1113 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1114 IN CHAR16 *WString\r
1115 )\r
1116/*++\r
1117 Routine Description:\r
1118 \r
1119 Implements SIMPLE_TEXT_OUTPUT.TestString().\r
1120 If one of the characters in the *Wstring is\r
1121 neither valid valid Unicode drawing characters,\r
1122 not ASCII code, then this function will return\r
1123 EFI_UNSUPPORTED.\r
1124 \r
1125 \r
1126 Arguments:\r
1127 \r
1128 This - Indicates the calling context.\r
1129 \r
1130 WString - The Null-terminated Unicode string to be tested.\r
1131 \r
1132 Returns:\r
1133 \r
1134 EFI_SUCCESS\r
1135 The Graphics Console is capable of rendering the output string. \r
1136 \r
1137 EFI_UNSUPPORTED\r
1138 Some of the characters in the Unicode string cannot be rendered. \r
1139 \r
1140--*/\r
1141{\r
1142 EFI_STATUS Status;\r
95276127 1143 UINT16 Count;\r
95276127 1144\r
93e3992d 1145#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)\r
1146 EFI_IMAGE_OUTPUT *Blt = NULL;\r
1147#else\r
1148 UINT16 GlyphWidth;\r
1149 UINT32 GlyphStatus = 0;\r
1150 GLYPH_UNION *Glyph; \r
1151#endif\r
1152\r
1153 Count = 0;\r
1154\r
1155 while (WString[Count] != 0) {\r
1156#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)\r
1157 Status = mHiiFont->GetGlyph (\r
1158 mHiiFont,\r
1159 WString[Count],\r
1160 NULL,\r
1161 &Blt,\r
1162 NULL\r
1163 );\r
1164 SafeFreePool (Blt);\r
1165 Blt = NULL;\r
1166 Count++;\r
1167#else\r
95276127 1168 Status = mHii->GetGlyph (\r
1169 mHii,\r
1170 WString,\r
1171 &Count,\r
1172 (UINT8 **) &Glyph,\r
1173 &GlyphWidth,\r
1174 &GlyphStatus\r
1175 );\r
93e3992d 1176#endif\r
95276127 1177 if (EFI_ERROR (Status)) {\r
1178 return EFI_UNSUPPORTED;\r
1179 }\r
1180 }\r
1181\r
1182 return EFI_SUCCESS;\r
1183}\r
1184\r
1185EFI_STATUS\r
1186EFIAPI\r
1187GraphicsConsoleConOutQueryMode (\r
1188 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1189 IN UINTN ModeNumber,\r
1190 OUT UINTN *Columns,\r
1191 OUT UINTN *Rows\r
1192 )\r
1193/*++\r
1194 Routine Description:\r
1195 \r
1196 Implements SIMPLE_TEXT_OUTPUT.QueryMode().\r
1197 It returnes information for an available text mode\r
1198 that the Graphics Console supports.\r
1199 In this driver,we only support text mode 80x25, which is\r
1200 defined as mode 0.\r
1201 \r
1202 \r
1203 Arguments:\r
1204 \r
1205 This - Indicates the calling context.\r
1206 \r
1207 ModeNumber - The mode number to return information on.\r
1208 \r
1209 Columns - The returned columns of the requested mode.\r
1210 \r
1211 Rows - The returned rows of the requested mode. \r
1212 \r
1213 Returns:\r
1214 \r
1215 EFI_SUCCESS\r
1216 The requested mode information is returned. \r
1217 \r
1218 EFI_UNSUPPORTED\r
1219 The mode number is not valid. \r
1220 \r
1221--*/\r
1222{\r
1223 GRAPHICS_CONSOLE_DEV *Private;\r
1224 EFI_STATUS Status;\r
1225 EFI_TPL OldTpl;\r
7347d5d6 1226 \r
95276127 1227 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {\r
1228 return EFI_UNSUPPORTED;\r
1229 }\r
1230\r
1231 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1232 Status = EFI_SUCCESS;\r
1233 \r
1234 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1235\r
1236 *Columns = Private->ModeData[ModeNumber].Columns;\r
1237 *Rows = Private->ModeData[ModeNumber].Rows;\r
1238\r
1239 if (*Columns <= 0 && *Rows <= 0) {\r
1240 Status = EFI_UNSUPPORTED;\r
1241 goto Done;\r
1242\r
1243 }\r
1244\r
1245Done:\r
1246 gBS->RestoreTPL (OldTpl);\r
1247 return Status;\r
1248}\r
1249\r
1250EFI_STATUS\r
1251EFIAPI\r
1252GraphicsConsoleConOutSetMode (\r
1253 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1254 IN UINTN ModeNumber\r
1255 )\r
1256/*++\r
1257 Routine Description:\r
1258 \r
1259 Implements SIMPLE_TEXT_OUTPUT.SetMode().\r
1260 Set the Graphics Console to a specified mode.\r
1261 In this driver, we only support mode 0. \r
1262 \r
1263 Arguments:\r
1264 \r
1265 This - Indicates the calling context.\r
1266 \r
1267 ModeNumber - The text mode to set.\r
1268 \r
1269 Returns:\r
1270 \r
1271 EFI_SUCCESS\r
1272 The requested text mode is set.\r
1273 \r
1274 EFI_DEVICE_ERROR\r
1275 The requested text mode cannot be set because of Graphics Console device error.\r
1276 \r
1277 EFI_UNSUPPORTED\r
1278 The text mode number is not valid. \r
1279 \r
1280--*/\r
1281{\r
1282 EFI_STATUS Status;\r
1283 GRAPHICS_CONSOLE_DEV *Private;\r
1284 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1285 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewLineBuffer;\r
1286 UINT32 HorizontalResolution;\r
1287 UINT32 VerticalResolution;\r
1288 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1289 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1290 UINT32 ColorDepth;\r
1291 UINT32 RefreshRate;\r
1292 EFI_TPL OldTpl;\r
1293\r
1294 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1295\r
1296 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1297 GraphicsOutput = Private->GraphicsOutput;\r
1298 UgaDraw = Private->UgaDraw;\r
1299 ModeData = &(Private->ModeData[ModeNumber]);\r
1300\r
1301 if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {\r
1302 Status = EFI_UNSUPPORTED;\r
1303 goto Done;\r
1304 }\r
1305\r
1306 //\r
1307 // Make sure the requested mode number is supported\r
1308 //\r
1309 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {\r
1310 Status = EFI_UNSUPPORTED;\r
1311 goto Done;\r
1312 }\r
1313\r
1314 if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {\r
1315 Status = EFI_UNSUPPORTED;\r
1316 goto Done;\r
1317 }\r
1318 //\r
1319 // Attempt to allocate a line buffer for the requested mode number\r
1320 //\r
1321 NewLineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * GLYPH_WIDTH * GLYPH_HEIGHT);\r
1322\r
1323 if (NewLineBuffer == NULL) {\r
1324 //\r
1325 // The new line buffer could not be allocated, so return an error.\r
1326 // No changes to the state of the current console have been made, so the current console is still valid\r
1327 //\r
1328 Status = EFI_OUT_OF_RESOURCES;\r
1329 goto Done;\r
1330 }\r
1331 //\r
1332 // If the mode has been set at least one other time, then LineBuffer will not be NULL\r
1333 //\r
1334 if (Private->LineBuffer != NULL) {\r
1335 //\r
1336 // Clear the current text window on the current graphics console\r
1337 //\r
1338 This->ClearScreen (This);\r
1339\r
1340 //\r
1341 // If the new mode is the same as the old mode, then just return EFI_SUCCESS\r
1342 //\r
1343 if ((INT32) ModeNumber == This->Mode->Mode) {\r
1344 FreePool (NewLineBuffer);\r
1345 Status = EFI_SUCCESS;\r
1346 goto Done;\r
1347 }\r
1348 //\r
7347d5d6 1349 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,\r
1350 // so erase the cursor, and free the LineBuffer for the current mode\r
95276127 1351 //\r
7347d5d6 1352 EraseCursor (This);\r
95276127 1353\r
1354 FreePool (Private->LineBuffer);\r
1355 }\r
1356 //\r
1357 // Assign the current line buffer to the newly allocated line buffer\r
1358 //\r
1359 Private->LineBuffer = NewLineBuffer;\r
1360\r
1361 if (GraphicsOutput != NULL) {\r
1362 if (ModeData->GopModeNumber != GraphicsOutput->Mode->Mode) {\r
1363 //\r
1364 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode\r
1365 //\r
1366 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeData->GopModeNumber);\r
1367 if (EFI_ERROR (Status)) {\r
1368 //\r
1369 // The mode set operation failed\r
1370 //\r
1371 goto Done;\r
1372 }\r
1373 } else {\r
1374 //\r
1375 // The current graphics mode is correct, so simply clear the entire display\r
1376 //\r
1377 Status = GraphicsOutput->Blt (\r
1378 GraphicsOutput,\r
1379 &mEfiColors[0],\r
1380 EfiBltVideoFill,\r
1381 0,\r
1382 0,\r
1383 0,\r
1384 0,\r
1385 ModeData->GopWidth,\r
1386 ModeData->GopHeight,\r
1387 0\r
1388 );\r
1389 }\r
1390 } else {\r
1391 //\r
1392 // Get the current UGA Draw mode information\r
1393 //\r
1394 Status = UgaDraw->GetMode (\r
1395 UgaDraw,\r
1396 &HorizontalResolution,\r
1397 &VerticalResolution,\r
1398 &ColorDepth,\r
1399 &RefreshRate\r
1400 );\r
1401 if (EFI_ERROR (Status) || HorizontalResolution != ModeData->GopWidth || VerticalResolution != ModeData->GopHeight) {\r
1402 //\r
1403 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode\r
1404 //\r
1405 Status = UgaDraw->SetMode (\r
1406 UgaDraw,\r
1407 ModeData->GopWidth,\r
1408 ModeData->GopHeight,\r
1409 32,\r
1410 60\r
1411 );\r
1412 if (EFI_ERROR (Status)) {\r
1413 //\r
1414 // The mode set operation failed\r
1415 //\r
1416 goto Done;\r
1417 }\r
1418 } else {\r
1419 //\r
1420 // The current graphics mode is correct, so simply clear the entire display\r
1421 //\r
1422 Status = UgaDraw->Blt (\r
1423 UgaDraw,\r
1424 (EFI_UGA_PIXEL *) (UINTN) &mEfiColors[0],\r
1425 EfiUgaVideoFill,\r
1426 0,\r
1427 0,\r
1428 0,\r
1429 0,\r
1430 ModeData->GopWidth,\r
1431 ModeData->GopHeight,\r
1432 0\r
1433 );\r
1434 }\r
1435 }\r
1436\r
1437 //\r
1438 // The new mode is valid, so commit the mode change\r
1439 //\r
1440 This->Mode->Mode = (INT32) ModeNumber;\r
1441\r
1442 //\r
1443 // Move the text cursor to the upper left hand corner of the displat and enable it\r
1444 //\r
1445 This->SetCursorPosition (This, 0, 0);\r
95276127 1446\r
1447 Status = EFI_SUCCESS;\r
1448\r
1449Done:\r
1450 gBS->RestoreTPL (OldTpl);\r
1451 return Status;\r
1452}\r
1453\r
1454EFI_STATUS\r
1455EFIAPI\r
1456GraphicsConsoleConOutSetAttribute (\r
1457 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1458 IN UINTN Attribute\r
1459 )\r
1460/*++\r
1461 Routine Description:\r
1462 \r
1463 Implements SIMPLE_TEXT_OUTPUT.SetAttribute(). \r
1464 \r
1465 Arguments:\r
1466 \r
1467 This - Indicates the calling context.\r
1468 \r
1469 Attrubute - The attribute to set. Only bit0..6 are valid, all other bits\r
1470 are undefined and must be zero.\r
1471 \r
1472 Returns:\r
1473 \r
1474 EFI_SUCCESS\r
1475 The requested attribute is set. \r
1476 \r
1477 EFI_DEVICE_ERROR\r
1478 The requested attribute cannot be set due to Graphics Console port error.\r
1479 \r
1480 EFI_UNSUPPORTED\r
1481 The attribute requested is not defined by EFI spec. \r
1482 \r
1483--*/\r
1484{\r
1485 EFI_TPL OldTpl;\r
1486 \r
1487 if ((Attribute | 0xFF) != 0xFF) {\r
1488 return EFI_UNSUPPORTED;\r
1489 }\r
1490\r
1491 if ((INT32) Attribute == This->Mode->Attribute) {\r
1492 return EFI_SUCCESS;\r
1493 }\r
1494\r
1495 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1496\r
1497 EraseCursor (This);\r
1498\r
1499 This->Mode->Attribute = (INT32) Attribute;\r
1500\r
1501 EraseCursor (This);\r
1502\r
1503 gBS->RestoreTPL (OldTpl);\r
1504\r
1505 return EFI_SUCCESS;\r
1506}\r
1507\r
1508EFI_STATUS\r
1509EFIAPI\r
1510GraphicsConsoleConOutClearScreen (\r
1511 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
1512 )\r
1513/*++\r
1514 Routine Description:\r
1515 \r
1516 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().\r
1517 It clears the Graphics Console's display to the \r
1518 currently selected background color.\r
1519 \r
1520 \r
1521 Arguments:\r
1522 \r
1523 This - Indicates the calling context.\r
1524\r
1525 Returns:\r
1526 \r
1527 EFI_SUCCESS\r
1528 The operation completed successfully.\r
1529 \r
1530 EFI_DEVICE_ERROR\r
1531 The Graphics Console cannot be cleared due to Graphics Console device error. \r
1532 \r
1533 EFI_UNSUPPORTED\r
1534 The Graphics Console is not in a valid text mode. \r
1535 \r
1536--*/\r
1537{\r
1538 EFI_STATUS Status;\r
1539 GRAPHICS_CONSOLE_DEV *Private;\r
1540 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1541 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1542 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1543 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
1544 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
1545 EFI_TPL OldTpl;\r
1546\r
1547 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1548\r
1549 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1550 GraphicsOutput = Private->GraphicsOutput;\r
1551 UgaDraw = Private->UgaDraw;\r
1552 ModeData = &(Private->ModeData[This->Mode->Mode]);\r
1553\r
1554 GetTextColors (This, &Foreground, &Background);\r
1555 if (GraphicsOutput != NULL) {\r
1556 Status = GraphicsOutput->Blt (\r
1557 GraphicsOutput,\r
1558 &Background,\r
1559 EfiBltVideoFill,\r
1560 0,\r
1561 0,\r
1562 0,\r
1563 0,\r
1564 ModeData->GopWidth,\r
1565 ModeData->GopHeight,\r
1566 0\r
1567 );\r
1568 } else {\r
1569 Status = UgaDraw->Blt (\r
1570 UgaDraw,\r
1571 (EFI_UGA_PIXEL *) (UINTN) &Background,\r
1572 EfiUgaVideoFill,\r
1573 0,\r
1574 0,\r
1575 0,\r
1576 0,\r
1577 ModeData->GopWidth,\r
1578 ModeData->GopHeight,\r
1579 0\r
1580 );\r
1581 }\r
1582\r
1583 This->Mode->CursorColumn = 0;\r
1584 This->Mode->CursorRow = 0;\r
1585\r
1586 EraseCursor (This);\r
1587\r
1588 gBS->RestoreTPL (OldTpl);\r
1589\r
1590 return Status;\r
1591}\r
1592\r
1593EFI_STATUS\r
1594EFIAPI\r
1595GraphicsConsoleConOutSetCursorPosition (\r
1596 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1597 IN UINTN Column,\r
1598 IN UINTN Row\r
1599 )\r
1600/*++\r
1601 Routine Description:\r
1602 \r
1603 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition(). \r
1604 \r
1605 Arguments:\r
1606 \r
1607 This - Indicates the calling context.\r
1608 \r
1609 Column - The row to set cursor to.\r
1610 \r
1611 Row - The column to set cursor to. \r
1612\r
1613 Returns:\r
1614 \r
1615 EFI_SUCCESS\r
1616 The operation completed successfully.\r
1617 \r
1618 EFI_DEVICE_ERROR\r
1619 The request fails due to Graphics Console device error. \r
1620 \r
1621 EFI_UNSUPPORTED\r
1622 The Graphics Console is not in a valid text mode, or the cursor position\r
1623 is invalid for current mode. \r
1624 \r
1625--*/\r
1626{\r
1627 GRAPHICS_CONSOLE_DEV *Private;\r
1628 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1629 EFI_STATUS Status;\r
1630 EFI_TPL OldTpl;\r
1631\r
1632 Status = EFI_SUCCESS;\r
1633\r
1634 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1635\r
1636 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1637 ModeData = &(Private->ModeData[This->Mode->Mode]);\r
1638\r
1639 if ((Column >= ModeData->Columns) || (Row >= ModeData->Rows)) {\r
1640 Status = EFI_UNSUPPORTED;\r
1641 goto Done;\r
1642 }\r
1643\r
1644 if (((INT32) Column == This->Mode->CursorColumn) && ((INT32) Row == This->Mode->CursorRow)) {\r
1645 Status = EFI_SUCCESS;\r
1646 goto Done;\r
1647 }\r
1648\r
1649 EraseCursor (This);\r
1650\r
1651 This->Mode->CursorColumn = (INT32) Column;\r
1652 This->Mode->CursorRow = (INT32) Row;\r
1653\r
1654 EraseCursor (This);\r
1655\r
1656Done:\r
1657 gBS->RestoreTPL (OldTpl);\r
1658\r
1659 return Status;\r
1660}\r
1661\r
1662EFI_STATUS\r
1663EFIAPI\r
1664GraphicsConsoleConOutEnableCursor (\r
1665 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1666 IN BOOLEAN Visible\r
1667 )\r
1668/*++\r
1669 Routine Description:\r
1670 \r
1671 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().\r
1672 In this driver, the cursor cannot be hidden. \r
1673 \r
1674 Arguments:\r
1675 \r
1676 This - Indicates the calling context.\r
1677 \r
1678 Visible - If TRUE, the cursor is set to be visible,\r
1679 If FALSE, the cursor is set to be invisible. \r
1680\r
1681 Returns:\r
1682 \r
1683 EFI_SUCCESS\r
1684 The request is valid.\r
1685 \r
1686 EFI_UNSUPPORTED\r
1687 The Graphics Console does not support a hidden cursor. \r
1688 \r
1689--*/\r
1690{\r
1691 EFI_TPL OldTpl;\r
1692 \r
1693 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1694 \r
1695 EraseCursor (This);\r
1696\r
1697 This->Mode->CursorVisible = Visible;\r
1698\r
1699 EraseCursor (This);\r
1700\r
1701 gBS->RestoreTPL (OldTpl);\r
1702 return EFI_SUCCESS;\r
1703}\r
1704\r
1705STATIC\r
1706EFI_STATUS\r
1707GetTextColors (\r
1708 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1709 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
1710 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background\r
1711 )\r
1712{\r
1713 INTN Attribute;\r
1714\r
1715 Attribute = This->Mode->Attribute & 0x7F;\r
1716\r
1717 *Foreground = mEfiColors[Attribute & 0x0f];\r
1718 *Background = mEfiColors[Attribute >> 4];\r
1719\r
1720 return EFI_SUCCESS;\r
1721}\r
1722\r
93e3992d 1723#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)\r
1724EFI_STATUS\r
1725DrawUnicodeWeightAtCursorN (\r
1726 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1727 IN CHAR16 *UnicodeWeight,\r
1728 IN UINTN Count\r
1729 )\r
1730{\r
1731 EFI_STATUS Status;\r
1732 GRAPHICS_CONSOLE_DEV *Private;\r
1733 EFI_IMAGE_OUTPUT *Blt;\r
1734 EFI_STRING String;\r
1735 EFI_FONT_DISPLAY_INFO *FontInfo;\r
1736\r
1737 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1738 //\r
1739 // GOP protocol is required in UEFI mode.\r
1740 //\r
1741 ASSERT (Private->GraphicsOutput != NULL);\r
1742\r
1743 Blt = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
1744 if (Blt == NULL) {\r
1745 return EFI_OUT_OF_RESOURCES;\r
1746 }\r
1747\r
1748 Blt->Width = (UINT16) (Private->ModeData[This->Mode->Mode].GopWidth);\r
1749 Blt->Height = (UINT16) (Private->ModeData[This->Mode->Mode].GopHeight);\r
1750 Blt->Image.Screen = Private->GraphicsOutput;\r
1751\r
1752 String = AllocateCopyPool ((Count + 1) * sizeof (CHAR16), UnicodeWeight);\r
1753 if (String == NULL) {\r
1754 SafeFreePool (Blt);\r
1755 return EFI_OUT_OF_RESOURCES;\r
1756 }\r
1757 *(String + Count) = 0;\r
1758\r
1759 FontInfo = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));\r
1760 if (FontInfo == NULL) {\r
1761 SafeFreePool (Blt);\r
1762 SafeFreePool (String);\r
1763 return EFI_OUT_OF_RESOURCES;\r
1764 }\r
1765 GetTextColors (This, &FontInfo->ForegroundColor, &FontInfo->BackgroundColor);\r
1766\r
1767 Status = mHiiFont->StringToImage (\r
1768 mHiiFont,\r
1769 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN,\r
1770 String,\r
1771 FontInfo,\r
1772 &Blt,\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 NULL,\r
1776 NULL,\r
1777 NULL\r
1778 );\r
1779\r
1780 SafeFreePool (Blt);\r
1781 SafeFreePool (String);\r
1782 SafeFreePool (FontInfo);\r
1783 return Status;\r
1784}\r
1785#else\r
95276127 1786STATIC\r
1787EFI_STATUS\r
1788DrawUnicodeWeightAtCursorN (\r
1789 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1790 IN CHAR16 *UnicodeWeight,\r
1791 IN UINTN Count\r
1792 )\r
1793{\r
1794 GRAPHICS_CONSOLE_DEV *Private;\r
1795 EFI_STATUS Status;\r
1796 EFI_STATUS ReturnStatus;\r
1797 GLYPH_UNION *Glyph;\r
1798 GLYPH_UNION GlyphData;\r
1799 INTN GlyphX;\r
1800 INTN GlyphY;\r
1801 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1802 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1803 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
1804 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
1805 UINTN Index;\r
1806 UINTN ArrayIndex;\r
1807 UINTN Counts;\r
1808 UINT16 GlyphWidth;\r
1809 UINT32 GlyphStatus;\r
1810\r
1811 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1812\r
1813 ReturnStatus = EFI_SUCCESS;\r
1814 GlyphStatus = 0;\r
1815 GlyphWidth = 0x08;\r
1816\r
1817 GetTextColors (This, &Foreground, &Background);\r
1818\r
1819 Index = 0;\r
1820 ArrayIndex = 0;\r
1821 while (Index < Count) {\r
1822 if (This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) {\r
1823 GlyphStatus = WIDE_CHAR;\r
1824 } else {\r
1825 GlyphStatus = NARROW_CHAR;\r
1826 }\r
1827\r
1828 Status = mHii->GetGlyph (\r
1829 mHii,\r
1830 UnicodeWeight,\r
1831 (UINT16 *) &Index,\r
1832 (UINT8 **) &Glyph,\r
1833 &GlyphWidth,\r
1834 &GlyphStatus\r
1835 );\r
1836 if (EFI_ERROR (Status)) {\r
1837 ReturnStatus = Status;\r
1838 }\r
1839\r
1840 Counts = 0;\r
1841\r
1842 CopyMem (&GlyphData, Glyph, sizeof (GLYPH_UNION));\r
1843\r
1844 do {\r
1845 //\r
1846 // We are creating the second half of the wide character's BLT buffer\r
1847 //\r
1848 if (GlyphWidth == 0x10 && Counts == 1) {\r
1849 CopyMem (&GlyphData.NarrowGlyph.GlyphCol1, &Glyph->WideGlyph.GlyphCol2, sizeof (Glyph->WideGlyph.GlyphCol2));\r
1850 }\r
1851\r
1852 Counts++;\r
1853\r
1854 if (GlyphWidth == 0x10) {\r
1855 mHii->GlyphToBlt (\r
1856 mHii,\r
1857 (UINT8 *) &GlyphData,\r
1858 Foreground,\r
1859 Background,\r
1860 Count * 2,\r
1861 GLYPH_WIDTH,\r
1862 GLYPH_HEIGHT,\r
1863 &Private->LineBuffer[ArrayIndex * GLYPH_WIDTH]\r
1864 );\r
1865 } else {\r
1866 mHii->GlyphToBlt (\r
1867 mHii,\r
1868 (UINT8 *) &GlyphData,\r
1869 Foreground,\r
1870 Background,\r
1871 Count,\r
1872 GLYPH_WIDTH,\r
1873 GLYPH_HEIGHT,\r
1874 &Private->LineBuffer[ArrayIndex * GLYPH_WIDTH]\r
1875 );\r
1876 }\r
1877\r
1878 ArrayIndex++;\r
1879\r
1880 } while (Counts < 2 && GlyphWidth == 0x10);\r
1881\r
1882 }\r
1883 //\r
1884 // If we are printing Wide characters, treat the BLT as if it is twice as many characters\r
1885 //\r
1886 if (GlyphWidth == 0x10) {\r
1887 Count = Count * 2;\r
1888 }\r
1889 //\r
1890 // Blt a character to the screen\r
1891 //\r
1892 GlyphX = This->Mode->CursorColumn * GLYPH_WIDTH;\r
1893 GlyphY = This->Mode->CursorRow * GLYPH_HEIGHT;\r
1894 GraphicsOutput = Private->GraphicsOutput;\r
1895 UgaDraw = Private->UgaDraw;\r
1896 if (GraphicsOutput != NULL) {\r
1897 GraphicsOutput->Blt (\r
1898 GraphicsOutput,\r
1899 Private->LineBuffer,\r
1900 EfiBltBufferToVideo,\r
1901 0,\r
1902 0,\r
1903 GlyphX + Private->ModeData[This->Mode->Mode].DeltaX,\r
1904 GlyphY + Private->ModeData[This->Mode->Mode].DeltaY,\r
1905 GLYPH_WIDTH * Count,\r
1906 GLYPH_HEIGHT,\r
1907 GLYPH_WIDTH * Count * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1908 );\r
1909 } else {\r
1910 UgaDraw->Blt (\r
1911 UgaDraw,\r
1912 (EFI_UGA_PIXEL *) (UINTN) Private->LineBuffer,\r
1913 EfiUgaBltBufferToVideo,\r
1914 0,\r
1915 0,\r
1916 GlyphX + Private->ModeData[This->Mode->Mode].DeltaX,\r
1917 GlyphY + Private->ModeData[This->Mode->Mode].DeltaY,\r
1918 GLYPH_WIDTH * Count,\r
1919 GLYPH_HEIGHT,\r
1920 GLYPH_WIDTH * Count * sizeof (EFI_UGA_PIXEL)\r
1921 );\r
1922 }\r
1923\r
1924 return ReturnStatus;\r
1925}\r
93e3992d 1926#endif\r
95276127 1927\r
1928STATIC\r
1929EFI_STATUS\r
1930EraseCursor (\r
1931 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
1932 )\r
1933{\r
1934 GRAPHICS_CONSOLE_DEV *Private;\r
1935 EFI_SIMPLE_TEXT_OUTPUT_MODE *CurrentMode;\r
1936 INTN GlyphX;\r
1937 INTN GlyphY;\r
1938 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1939 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1940 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground;\r
1941 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background;\r
1942 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar[GLYPH_HEIGHT][GLYPH_WIDTH];\r
1943 UINTN X;\r
1944 UINTN Y;\r
1945\r
1946 CurrentMode = This->Mode;\r
1947\r
1948 if (!CurrentMode->CursorVisible) {\r
1949 return EFI_SUCCESS;\r
1950 }\r
1951\r
1952 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1953 GraphicsOutput = Private->GraphicsOutput;\r
1954 UgaDraw = Private->UgaDraw;\r
1955\r
1956 //\r
1957 // BUGBUG - we need to think about what to do with wide and narrow character deletions.\r
1958 //\r
1959 //\r
1960 // Blt a character to the screen\r
1961 //\r
1962 GlyphX = (CurrentMode->CursorColumn * GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;\r
1963 GlyphY = (CurrentMode->CursorRow * GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;\r
1964 if (GraphicsOutput != NULL) {\r
1965 GraphicsOutput->Blt (\r
1966 GraphicsOutput,\r
1967 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,\r
1968 EfiBltVideoToBltBuffer,\r
1969 GlyphX,\r
1970 GlyphY,\r
1971 0,\r
1972 0,\r
1973 GLYPH_WIDTH,\r
1974 GLYPH_HEIGHT,\r
1975 GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1976 );\r
1977 } else {\r
1978 UgaDraw->Blt (\r
1979 UgaDraw,\r
1980 (EFI_UGA_PIXEL *) (UINTN) BltChar,\r
1981 EfiUgaVideoToBltBuffer,\r
1982 GlyphX,\r
1983 GlyphY,\r
1984 0,\r
1985 0,\r
1986 GLYPH_WIDTH,\r
1987 GLYPH_HEIGHT,\r
1988 GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
1989 );\r
1990 }\r
1991\r
1992 GetTextColors (This, &Foreground.Pixel, &Background.Pixel);\r
1993\r
1994 //\r
1995 // Convert Monochrome bitmap of the Glyph to BltBuffer structure\r
1996 //\r
1997 for (Y = 0; Y < GLYPH_HEIGHT; Y++) {\r
1998 for (X = 0; X < GLYPH_WIDTH; X++) {\r
1999 if ((mCursorGlyph.GlyphCol1[Y] & (1 << X)) != 0) {\r
2000 BltChar[Y][GLYPH_WIDTH - X - 1].Raw ^= Foreground.Raw;\r
2001 }\r
2002 }\r
2003 }\r
2004\r
2005 if (GraphicsOutput != NULL) {\r
2006 GraphicsOutput->Blt (\r
2007 GraphicsOutput,\r
2008 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,\r
2009 EfiBltBufferToVideo,\r
2010 0,\r
2011 0,\r
2012 GlyphX,\r
2013 GlyphY,\r
2014 GLYPH_WIDTH,\r
2015 GLYPH_HEIGHT,\r
2016 GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
2017 );\r
2018 } else {\r
2019 UgaDraw->Blt (\r
2020 UgaDraw,\r
2021 (EFI_UGA_PIXEL *) (UINTN) BltChar,\r
2022 EfiUgaBltBufferToVideo,\r
2023 0,\r
2024 0,\r
2025 GlyphX,\r
2026 GlyphY,\r
2027 GLYPH_WIDTH,\r
2028 GLYPH_HEIGHT,\r
2029 GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
2030 );\r
2031 }\r
2032\r
2033 return EFI_SUCCESS;\r
2034}\r
97a079ed
A
2035\r
2036/**\r
2037 The user Entry Point for module GraphicsConsole. The user code starts with this function.\r
2038\r
2039 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
2040 @param[in] SystemTable A pointer to the EFI System Table.\r
2041 \r
2042 @retval EFI_SUCCESS The entry point is executed successfully.\r
2043 @retval other Some error occurs when executing this entry point.\r
2044\r
2045**/\r
2046EFI_STATUS\r
2047EFIAPI\r
2048InitializeGraphicsConsole (\r
2049 IN EFI_HANDLE ImageHandle,\r
2050 IN EFI_SYSTEM_TABLE *SystemTable\r
2051 )\r
2052{\r
2053 EFI_STATUS Status;\r
2054\r
2055 //\r
2056 // Install driver model protocol(s).\r
2057 //\r
5bca971e 2058 Status = EfiLibInstallDriverBindingComponentName2 (\r
97a079ed
A
2059 ImageHandle,\r
2060 SystemTable,\r
2061 &gGraphicsConsoleDriverBinding,\r
2062 ImageHandle,\r
2063 &gGraphicsConsoleComponentName,\r
5bca971e 2064 &gGraphicsConsoleComponentName2\r
97a079ed
A
2065 );\r
2066 ASSERT_EFI_ERROR (Status);\r
2067\r
2068\r
2069 return Status;\r
2070}\r
2071\r