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