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