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