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