1 /** @file
2 This is the main routine for initializing the Graphics Console support routines.
3
4 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "GraphicsConsole.h"
16
17 //
18 // Graphics Console Device Private Data template
19 //
20 GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate = {
21 GRAPHICS_CONSOLE_DEV_SIGNATURE,
22 (EFI_GRAPHICS_OUTPUT_PROTOCOL *) NULL,
23 (EFI_UGA_DRAW_PROTOCOL *) NULL,
24 {
25 GraphicsConsoleConOutReset,
26 GraphicsConsoleConOutOutputString,
27 GraphicsConsoleConOutTestString,
28 GraphicsConsoleConOutQueryMode,
29 GraphicsConsoleConOutSetMode,
30 GraphicsConsoleConOutSetAttribute,
31 GraphicsConsoleConOutClearScreen,
32 GraphicsConsoleConOutSetCursorPosition,
33 GraphicsConsoleConOutEnableCursor,
34 (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL
35 },
36 {
37 0,
38 -1,
39 EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_BLACK),
40 0,
41 0,
42 TRUE
43 },
44 (GRAPHICS_CONSOLE_MODE_DATA *) NULL,
45 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL
46 };
47
48 GRAPHICS_CONSOLE_MODE_DATA mGraphicsConsoleModeData[] = {
49 {100, 31},
50 //
51 // New modes can be added here.
52 // The last entry is specific for full screen mode.
53 //
54 {0, 0}
55 };
56
57 EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;
58 EFI_HII_FONT_PROTOCOL *mHiiFont;
59 EFI_HII_HANDLE mHiiHandle;
60 VOID *mHiiRegistration;
61
62 EFI_GUID mFontPackageListGuid = {0xf5f219d3, 0x7006, 0x4648, {0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad}};
63
64 CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };
65
66 EFI_GRAPHICS_OUTPUT_BLT_PIXEL mGraphicsEfiColors[16] = {
67 //
68 // B G R reserved
69 //
70 {0x00, 0x00, 0x00, 0x00}, // BLACK
71 {0x98, 0x00, 0x00, 0x00}, // LIGHTBLUE
72 {0x00, 0x98, 0x00, 0x00}, // LIGHGREEN
73 {0x98, 0x98, 0x00, 0x00}, // LIGHCYAN
74 {0x00, 0x00, 0x98, 0x00}, // LIGHRED
75 {0x98, 0x00, 0x98, 0x00}, // MAGENTA
76 {0x00, 0x98, 0x98, 0x00}, // BROWN
77 {0x98, 0x98, 0x98, 0x00}, // LIGHTGRAY
78 {0x30, 0x30, 0x30, 0x00}, // DARKGRAY - BRIGHT BLACK
79 {0xff, 0x00, 0x00, 0x00}, // BLUE
80 {0x00, 0xff, 0x00, 0x00}, // LIME
81 {0xff, 0xff, 0x00, 0x00}, // CYAN
82 {0x00, 0x00, 0xff, 0x00}, // RED
83 {0xff, 0x00, 0xff, 0x00}, // FUCHSIA
84 {0x00, 0xff, 0xff, 0x00}, // YELLOW
85 {0xff, 0xff, 0xff, 0x00} // WHITE
86 };
87
88 EFI_NARROW_GLYPH mCursorGlyph = {
89 0x0000,
90 0x00,
91 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }
92 };
93
94 CHAR16 SpaceStr[] = { NARROW_CHAR, ' ', 0 };
95
96 EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding = {
97 GraphicsConsoleControllerDriverSupported,
98 GraphicsConsoleControllerDriverStart,
99 GraphicsConsoleControllerDriverStop,
100 0xa,
101 NULL,
102 NULL
103 };
104
105 /**
106 Test to see if Graphics Console could be supported on the Controller.
107
108 Graphics Console could be supported if Graphics Output Protocol or UGA Draw
109 Protocol exists on the Controller. (UGA Draw Protocol could be skipped
110 if PcdUgaConsumeSupport is set to FALSE.)
111
112 @param This Protocol instance pointer.
113 @param Controller Handle of device to test.
114 @param RemainingDevicePath Optional parameter use to pick a specific child
115 device to start.
116
117 @retval EFI_SUCCESS This driver supports this device.
118 @retval other This driver does not support this device.
119
120 **/
121 EFI_STATUS
122 EFIAPI
GraphicsConsoleControllerDriverSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)123 GraphicsConsoleControllerDriverSupported (
124 IN EFI_DRIVER_BINDING_PROTOCOL *This,
125 IN EFI_HANDLE Controller,
126 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
127 )
128 {
129 EFI_STATUS Status;
130 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
131 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
132 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
133
134 GraphicsOutput = NULL;
135 UgaDraw = NULL;
136 //
137 // Open the IO Abstraction(s) needed to perform the supported test
138 //
139 Status = gBS->OpenProtocol (
140 Controller,
141 &gEfiGraphicsOutputProtocolGuid,
142 (VOID **) &GraphicsOutput,
143 This->DriverBindingHandle,
144 Controller,
145 EFI_OPEN_PROTOCOL_BY_DRIVER
146 );
147
148 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
149 //
150 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol
151 //
152 Status = gBS->OpenProtocol (
153 Controller,
154 &gEfiUgaDrawProtocolGuid,
155 (VOID **) &UgaDraw,
156 This->DriverBindingHandle,
157 Controller,
158 EFI_OPEN_PROTOCOL_BY_DRIVER
159 );
160 }
161 if (EFI_ERROR (Status)) {
162 return Status;
163 }
164
165 //
166 // We need to ensure that we do not layer on top of a virtual handle.
167 // We need to ensure that the handles produced by the conspliter do not
168 // get used.
169 //
170 Status = gBS->OpenProtocol (
171 Controller,
172 &gEfiDevicePathProtocolGuid,
173 (VOID **) &DevicePath,
174 This->DriverBindingHandle,
175 Controller,
176 EFI_OPEN_PROTOCOL_BY_DRIVER
177 );
178 if (!EFI_ERROR (Status)) {
179 gBS->CloseProtocol (
180 Controller,
181 &gEfiDevicePathProtocolGuid,
182 This->DriverBindingHandle,
183 Controller
184 );
185 } else {
186 goto Error;
187 }
188
189 //
190 // Does Hii Exist? If not, we aren't ready to run
191 //
192 Status = EfiLocateHiiProtocol ();
193
194 //
195 // Close the I/O Abstraction(s) used to perform the supported test
196 //
197 Error:
198 if (GraphicsOutput != NULL) {
199 gBS->CloseProtocol (
200 Controller,
201 &gEfiGraphicsOutputProtocolGuid,
202 This->DriverBindingHandle,
203 Controller
204 );
205 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
206 gBS->CloseProtocol (
207 Controller,
208 &gEfiUgaDrawProtocolGuid,
209 This->DriverBindingHandle,
210 Controller
211 );
212 }
213 return Status;
214 }
215
216 /**
217 Initialize all the text modes which the graphics console supports.
218
219 It returns information for available text modes that the graphics can support.
220
221 @param[in] HorizontalResolution The size of video screen in pixels in the X dimension.
222 @param[in] VerticalResolution The size of video screen in pixels in the Y dimension.
223 @param[in] GopModeNumber The graphics mode number which graphis console is based on.
224 @param[out] TextModeCount The total number of text modes that graphics console supports.
225 @param[out] TextModeData The buffer to the text modes column and row information.
226 Caller is responsible to free it when it's non-NULL.
227
228 @retval EFI_SUCCESS The supporting mode information is returned.
229 @retval EFI_INVALID_PARAMETER The parameters are invalid.
230
231 **/
232 EFI_STATUS
InitializeGraphicsConsoleTextMode(IN UINT32 HorizontalResolution,IN UINT32 VerticalResolution,IN UINT32 GopModeNumber,OUT UINTN * TextModeCount,OUT GRAPHICS_CONSOLE_MODE_DATA ** TextModeData)233 InitializeGraphicsConsoleTextMode (
234 IN UINT32 HorizontalResolution,
235 IN UINT32 VerticalResolution,
236 IN UINT32 GopModeNumber,
237 OUT UINTN *TextModeCount,
238 OUT GRAPHICS_CONSOLE_MODE_DATA **TextModeData
239 )
240 {
241 UINTN Index;
242 UINTN Count;
243 GRAPHICS_CONSOLE_MODE_DATA *ModeBuffer;
244 GRAPHICS_CONSOLE_MODE_DATA *NewModeBuffer;
245 UINTN ValidCount;
246 UINTN ValidIndex;
247 UINTN MaxColumns;
248 UINTN MaxRows;
249
250 if ((TextModeCount == NULL) || (TextModeData == NULL)) {
251 return EFI_INVALID_PARAMETER;
252 }
253
254 Count = sizeof (mGraphicsConsoleModeData) / sizeof (GRAPHICS_CONSOLE_MODE_DATA);
255
256 //
257 // Compute the maximum number of text Rows and Columns that this current graphics mode can support.
258 // To make graphics console work well, MaxColumns and MaxRows should not be zero.
259 //
260 MaxColumns = HorizontalResolution / EFI_GLYPH_WIDTH;
261 MaxRows = VerticalResolution / EFI_GLYPH_HEIGHT;
262
263 //
264 // According to UEFI spec, all output devices support at least 80x25 text mode.
265 //
266 ASSERT ((MaxColumns >= 80) && (MaxRows >= 25));
267
268 //
269 // Add full screen mode to the last entry.
270 //
271 mGraphicsConsoleModeData[Count - 1].Columns = MaxColumns;
272 mGraphicsConsoleModeData[Count - 1].Rows = MaxRows;
273
274 //
275 // Get defined mode buffer pointer.
276 //
277 ModeBuffer = mGraphicsConsoleModeData;
278
279 //
280 // Here we make sure that the final mode exposed does not include the duplicated modes,
281 // and does not include the invalid modes which exceed the max column and row.
282 // Reserve 2 modes for 80x25, 80x50 of graphics console.
283 //
284 NewModeBuffer = AllocateZeroPool (sizeof (GRAPHICS_CONSOLE_MODE_DATA) * (Count + 2));
285 ASSERT (NewModeBuffer != NULL);
286
287 //
288 // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
289 //
290 ValidCount = 0;
291
292 NewModeBuffer[ValidCount].Columns = 80;
293 NewModeBuffer[ValidCount].Rows = 25;
294 NewModeBuffer[ValidCount].GopWidth = HorizontalResolution;
295 NewModeBuffer[ValidCount].GopHeight = VerticalResolution;
296 NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;
297 NewModeBuffer[ValidCount].DeltaX = (HorizontalResolution - (NewModeBuffer[ValidCount].Columns * EFI_GLYPH_WIDTH)) >> 1;
298 NewModeBuffer[ValidCount].DeltaY = (VerticalResolution - (NewModeBuffer[ValidCount].Rows * EFI_GLYPH_HEIGHT)) >> 1;
299 ValidCount++;
300
301 if ((MaxColumns >= 80) && (MaxRows >= 50)) {
302 NewModeBuffer[ValidCount].Columns = 80;
303 NewModeBuffer[ValidCount].Rows = 50;
304 NewModeBuffer[ValidCount].DeltaX = (HorizontalResolution - (80 * EFI_GLYPH_WIDTH)) >> 1;
305 NewModeBuffer[ValidCount].DeltaY = (VerticalResolution - (50 * EFI_GLYPH_HEIGHT)) >> 1;
306 }
307 NewModeBuffer[ValidCount].GopWidth = HorizontalResolution;
308 NewModeBuffer[ValidCount].GopHeight = VerticalResolution;
309 NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;
310 ValidCount++;
311
312 //
313 // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
314 //
315 for (Index = 0; Index < Count; Index++) {
316 if ((ModeBuffer[Index].Columns == 0) || (ModeBuffer[Index].Rows == 0) ||
317 (ModeBuffer[Index].Columns > MaxColumns) || (ModeBuffer[Index].Rows > MaxRows)) {
318 //
319 // Skip the pre-defined mode which is invalid or exceeds the max column and row.
320 //
321 continue;
322 }
323 for (ValidIndex = 0; ValidIndex < ValidCount; ValidIndex++) {
324 if ((ModeBuffer[Index].Columns == NewModeBuffer[ValidIndex].Columns) &&
325 (ModeBuffer[Index].Rows == NewModeBuffer[ValidIndex].Rows)) {
326 //
327 // Skip the duplicated mode.
328 //
329 break;
330 }
331 }
332 if (ValidIndex == ValidCount) {
333 NewModeBuffer[ValidCount].Columns = ModeBuffer[Index].Columns;
334 NewModeBuffer[ValidCount].Rows = ModeBuffer[Index].Rows;
335 NewModeBuffer[ValidCount].GopWidth = HorizontalResolution;
336 NewModeBuffer[ValidCount].GopHeight = VerticalResolution;
337 NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;
338 NewModeBuffer[ValidCount].DeltaX = (HorizontalResolution - (NewModeBuffer[ValidCount].Columns * EFI_GLYPH_WIDTH)) >> 1;
339 NewModeBuffer[ValidCount].DeltaY = (VerticalResolution - (NewModeBuffer[ValidCount].Rows * EFI_GLYPH_HEIGHT)) >> 1;
340 ValidCount++;
341 }
342 }
343
344 DEBUG_CODE (
345 for (Index = 0; Index < ValidCount; Index++) {
346 DEBUG ((EFI_D_INFO, "Graphics - Mode %d, Column = %d, Row = %d\n",
347 Index, NewModeBuffer[Index].Columns, NewModeBuffer[Index].Rows));
348 }
349 );
350
351 //
352 // Return valid mode count and mode information buffer.
353 //
354 *TextModeCount = ValidCount;
355 *TextModeData = NewModeBuffer;
356 return EFI_SUCCESS;
357 }
358
359 /**
360 Start this driver on Controller by opening Graphics Output protocol or
361 UGA Draw protocol, and installing Simple Text Out protocol on Controller.
362 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
363
364 @param This Protocol instance pointer.
365 @param Controller Handle of device to bind driver to
366 @param RemainingDevicePath Optional parameter use to pick a specific child
367 device to start.
368
369 @retval EFI_SUCCESS This driver is added to Controller.
370 @retval other This driver does not support this device.
371
372 **/
373 EFI_STATUS
374 EFIAPI
GraphicsConsoleControllerDriverStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)375 GraphicsConsoleControllerDriverStart (
376 IN EFI_DRIVER_BINDING_PROTOCOL *This,
377 IN EFI_HANDLE Controller,
378 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
379 )
380 {
381 EFI_STATUS Status;
382 GRAPHICS_CONSOLE_DEV *Private;
383 UINT32 HorizontalResolution;
384 UINT32 VerticalResolution;
385 UINT32 ColorDepth;
386 UINT32 RefreshRate;
387 UINT32 ModeIndex;
388 UINTN MaxMode;
389 UINT32 ModeNumber;
390 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
391 UINTN SizeOfInfo;
392 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
393
394 ModeNumber = 0;
395
396 //
397 // Initialize the Graphics Console device instance
398 //
399 Private = AllocateCopyPool (
400 sizeof (GRAPHICS_CONSOLE_DEV),
401 &mGraphicsConsoleDevTemplate
402 );
403 if (Private == NULL) {
404 return EFI_OUT_OF_RESOURCES;
405 }
406
407 Private->SimpleTextOutput.Mode = &(Private->SimpleTextOutputMode);
408
409 Status = gBS->OpenProtocol (
410 Controller,
411 &gEfiGraphicsOutputProtocolGuid,
412 (VOID **) &Private->GraphicsOutput,
413 This->DriverBindingHandle,
414 Controller,
415 EFI_OPEN_PROTOCOL_BY_DRIVER
416 );
417
418 if (EFI_ERROR(Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
419 Status = gBS->OpenProtocol (
420 Controller,
421 &gEfiUgaDrawProtocolGuid,
422 (VOID **) &Private->UgaDraw,
423 This->DriverBindingHandle,
424 Controller,
425 EFI_OPEN_PROTOCOL_BY_DRIVER
426 );
427 }
428
429 if (EFI_ERROR (Status)) {
430 goto Error;
431 }
432
433 HorizontalResolution = PcdGet32 (PcdVideoHorizontalResolution);
434 VerticalResolution = PcdGet32 (PcdVideoVerticalResolution);
435
436 if (Private->GraphicsOutput != NULL) {
437 //
438 // The console is build on top of Graphics Output Protocol, find the mode number
439 // for the user-defined mode; if there are multiple video devices,
440 // graphic console driver will set all the video devices to the same mode.
441 //
442 if ((HorizontalResolution == 0x0) || (VerticalResolution == 0x0)) {
443 //
444 // Find the highest resolution which GOP supports.
445 //
446 MaxMode = Private->GraphicsOutput->Mode->MaxMode;
447
448 for (ModeIndex = 0; ModeIndex < MaxMode; ModeIndex++) {
449 Status = Private->GraphicsOutput->QueryMode (
450 Private->GraphicsOutput,
451 ModeIndex,
452 &SizeOfInfo,
453 &Info
454 );
455 if (!EFI_ERROR (Status)) {
456 if ((Info->HorizontalResolution > HorizontalResolution) ||
457 ((Info->HorizontalResolution == HorizontalResolution) && (Info->VerticalResolution > VerticalResolution))) {
458 HorizontalResolution = Info->HorizontalResolution;
459 VerticalResolution = Info->VerticalResolution;
460 ModeNumber = ModeIndex;
461 }
462 FreePool (Info);
463 }
464 }
465 if ((HorizontalResolution == 0x0) || (VerticalResolution == 0x0)) {
466 Status = EFI_UNSUPPORTED;
467 goto Error;
468 }
469 } else {
470 //
471 // Use user-defined resolution
472 //
473 Status = CheckModeSupported (
474 Private->GraphicsOutput,
475 HorizontalResolution,
476 VerticalResolution,
477 &ModeNumber
478 );
479 if (EFI_ERROR (Status)) {
480 //
481 // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec
482 //
483 HorizontalResolution = 800;
484 VerticalResolution = 600;
485 Status = CheckModeSupported (
486 Private->GraphicsOutput,
487 HorizontalResolution,
488 VerticalResolution,
489 &ModeNumber
490 );
491 Mode = Private->GraphicsOutput->Mode;
492 if (EFI_ERROR (Status) && Mode->MaxMode != 0) {
493 //
494 // Set default mode failed or device don't support default mode, then get the current mode information
495 //
496 HorizontalResolution = Mode->Info->HorizontalResolution;
497 VerticalResolution = Mode->Info->VerticalResolution;
498 ModeNumber = Mode->Mode;
499 }
500 }
501 }
502 if (ModeNumber != Private->GraphicsOutput->Mode->Mode) {
503 //
504 // Current graphics mode is not set or is not set to the mode which we has found,
505 // set the new graphic mode.
506 //
507 Status = Private->GraphicsOutput->SetMode (Private->GraphicsOutput, ModeNumber);
508 if (EFI_ERROR (Status)) {
509 //
510 // The mode set operation failed
511 //
512 goto Error;
513 }
514 }
515 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
516 //
517 // At first try to set user-defined resolution
518 //
519 ColorDepth = 32;
520 RefreshRate = 60;
521 Status = Private->UgaDraw->SetMode (
522 Private->UgaDraw,
523 HorizontalResolution,
524 VerticalResolution,
525 ColorDepth,
526 RefreshRate
527 );
528 if (EFI_ERROR (Status)) {
529 //
530 // Try to set 800*600 which is required by UEFI/EFI spec
531 //
532 Status = Private->UgaDraw->SetMode (
533 Private->UgaDraw,
534 800,
535 600,
536 ColorDepth,
537 RefreshRate
538 );
539 if (EFI_ERROR (Status)) {
540 Status = Private->UgaDraw->GetMode (
541 Private->UgaDraw,
542 &HorizontalResolution,
543 &VerticalResolution,
544 &ColorDepth,
545 &RefreshRate
546 );
547 if (EFI_ERROR (Status)) {
548 goto Error;
549 }
550 }
551 }
552 }
553
554 DEBUG ((EFI_D_INFO, "GraphicsConsole video resolution %d x %d\n", HorizontalResolution, VerticalResolution));
555
556 //
557 // Initialize the mode which GraphicsConsole supports.
558 //
559 Status = InitializeGraphicsConsoleTextMode (
560 HorizontalResolution,
561 VerticalResolution,
562 ModeNumber,
563 &MaxMode,
564 &Private->ModeData
565 );
566
567 if (EFI_ERROR (Status)) {
568 goto Error;
569 }
570
571 //
572 // Update the maximum number of modes
573 //
574 Private->SimpleTextOutputMode.MaxMode = (INT32) MaxMode;
575
576 DEBUG_CODE_BEGIN ();
577 Status = GraphicsConsoleConOutSetMode (&Private->SimpleTextOutput, 0);
578 if (EFI_ERROR (Status)) {
579 goto Error;
580 }
581 Status = GraphicsConsoleConOutOutputString (&Private->SimpleTextOutput, (CHAR16 *)L"Graphics Console Started\n\r");
582 if (EFI_ERROR (Status)) {
583 goto Error;
584 }
585 DEBUG_CODE_END ();
586
587 //
588 // Install protocol interfaces for the Graphics Console device.
589 //
590 Status = gBS->InstallMultipleProtocolInterfaces (
591 &Controller,
592 &gEfiSimpleTextOutProtocolGuid,
593 &Private->SimpleTextOutput,
594 NULL
595 );
596
597 Error:
598 if (EFI_ERROR (Status)) {
599 //
600 // Close the GOP and UGA Draw Protocol
601 //
602 if (Private->GraphicsOutput != NULL) {
603 gBS->CloseProtocol (
604 Controller,
605 &gEfiGraphicsOutputProtocolGuid,
606 This->DriverBindingHandle,
607 Controller
608 );
609 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
610 gBS->CloseProtocol (
611 Controller,
612 &gEfiUgaDrawProtocolGuid,
613 This->DriverBindingHandle,
614 Controller
615 );
616 }
617
618 if (Private->LineBuffer != NULL) {
619 FreePool (Private->LineBuffer);
620 }
621
622 if (Private->ModeData != NULL) {
623 FreePool (Private->ModeData);
624 }
625
626 //
627 // Free private data
628 //
629 FreePool (Private);
630 }
631
632 return Status;
633 }
634
635 /**
636 Stop this driver on Controller by removing Simple Text Out protocol
637 and closing the Graphics Output Protocol or UGA Draw protocol on Controller.
638 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
639
640
641 @param This Protocol instance pointer.
642 @param Controller Handle of device to stop driver on
643 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
644 children is zero stop the entire bus driver.
645 @param ChildHandleBuffer List of Child Handles to Stop.
646
647 @retval EFI_SUCCESS This driver is removed Controller.
648 @retval EFI_NOT_STARTED Simple Text Out protocol could not be found the
649 Controller.
650 @retval other This driver was not removed from this device.
651
652 **/
653 EFI_STATUS
654 EFIAPI
GraphicsConsoleControllerDriverStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)655 GraphicsConsoleControllerDriverStop (
656 IN EFI_DRIVER_BINDING_PROTOCOL *This,
657 IN EFI_HANDLE Controller,
658 IN UINTN NumberOfChildren,
659 IN EFI_HANDLE *ChildHandleBuffer
660 )
661 {
662 EFI_STATUS Status;
663 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOutput;
664 GRAPHICS_CONSOLE_DEV *Private;
665
666 Status = gBS->OpenProtocol (
667 Controller,
668 &gEfiSimpleTextOutProtocolGuid,
669 (VOID **) &SimpleTextOutput,
670 This->DriverBindingHandle,
671 Controller,
672 EFI_OPEN_PROTOCOL_GET_PROTOCOL
673 );
674 if (EFI_ERROR (Status)) {
675 return EFI_NOT_STARTED;
676 }
677
678 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);
679
680 Status = gBS->UninstallProtocolInterface (
681 Controller,
682 &gEfiSimpleTextOutProtocolGuid,
683 &Private->SimpleTextOutput
684 );
685
686 if (!EFI_ERROR (Status)) {
687 //
688 // Close the GOP or UGA IO Protocol
689 //
690 if (Private->GraphicsOutput != NULL) {
691 gBS->CloseProtocol (
692 Controller,
693 &gEfiGraphicsOutputProtocolGuid,
694 This->DriverBindingHandle,
695 Controller
696 );
697 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
698 gBS->CloseProtocol (
699 Controller,
700 &gEfiUgaDrawProtocolGuid,
701 This->DriverBindingHandle,
702 Controller
703 );
704 }
705
706 if (Private->LineBuffer != NULL) {
707 FreePool (Private->LineBuffer);
708 }
709
710 if (Private->ModeData != NULL) {
711 FreePool (Private->ModeData);
712 }
713
714 //
715 // Free our instance data
716 //
717 FreePool (Private);
718 }
719
720 return Status;
721 }
722
723 /**
724 Check if the current specific mode supported the user defined resolution
725 for the Graphics Console device based on Graphics Output Protocol.
726
727 If yes, set the graphic devcice's current mode to this specific mode.
728
729 @param GraphicsOutput Graphics Output Protocol instance pointer.
730 @param HorizontalResolution User defined horizontal resolution
731 @param VerticalResolution User defined vertical resolution.
732 @param CurrentModeNumber Current specific mode to be check.
733
734 @retval EFI_SUCCESS The mode is supported.
735 @retval EFI_UNSUPPORTED The specific mode is out of range of graphics
736 device supported.
737 @retval other The specific mode does not support user defined
738 resolution or failed to set the current mode to the
739 specific mode on graphics device.
740
741 **/
742 EFI_STATUS
CheckModeSupported(EFI_GRAPHICS_OUTPUT_PROTOCOL * GraphicsOutput,IN UINT32 HorizontalResolution,IN UINT32 VerticalResolution,OUT UINT32 * CurrentModeNumber)743 CheckModeSupported (
744 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,
745 IN UINT32 HorizontalResolution,
746 IN UINT32 VerticalResolution,
747 OUT UINT32 *CurrentModeNumber
748 )
749 {
750 UINT32 ModeNumber;
751 EFI_STATUS Status;
752 UINTN SizeOfInfo;
753 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
754 UINT32 MaxMode;
755
756 Status = EFI_SUCCESS;
757 MaxMode = GraphicsOutput->Mode->MaxMode;
758
759 for (ModeNumber = 0; ModeNumber < MaxMode; ModeNumber++) {
760 Status = GraphicsOutput->QueryMode (
761 GraphicsOutput,
762 ModeNumber,
763 &SizeOfInfo,
764 &Info
765 );
766 if (!EFI_ERROR (Status)) {
767 if ((Info->HorizontalResolution == HorizontalResolution) &&
768 (Info->VerticalResolution == VerticalResolution)) {
769 if ((GraphicsOutput->Mode->Info->HorizontalResolution == HorizontalResolution) &&
770 (GraphicsOutput->Mode->Info->VerticalResolution == VerticalResolution)) {
771 //
772 // If video device has been set to this mode, we do not need to SetMode again
773 //
774 FreePool (Info);
775 break;
776 } else {
777 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
778 if (!EFI_ERROR (Status)) {
779 FreePool (Info);
780 break;
781 }
782 }
783 }
784 FreePool (Info);
785 }
786 }
787
788 if (ModeNumber == GraphicsOutput->Mode->MaxMode) {
789 Status = EFI_UNSUPPORTED;
790 }
791
792 *CurrentModeNumber = ModeNumber;
793 return Status;
794 }
795
796
797 /**
798 Locate HII Database protocol and HII Font protocol.
799
800 @retval EFI_SUCCESS HII Database protocol and HII Font protocol
801 are located successfully.
802 @return other Failed to locate HII Database protocol or
803 HII Font protocol.
804
805 **/
806 EFI_STATUS
EfiLocateHiiProtocol(VOID)807 EfiLocateHiiProtocol (
808 VOID
809 )
810 {
811 EFI_STATUS Status;
812
813 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &mHiiDatabase);
814 if (EFI_ERROR (Status)) {
815 return Status;
816 }
817
818 Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **) &mHiiFont);
819 return Status;
820 }
821
822 //
823 // Body of the STO functions
824 //
825
826 /**
827 Reset the text output device hardware and optionally run diagnostics.
828
829 Implements SIMPLE_TEXT_OUTPUT.Reset().
830 If ExtendeVerification is TRUE, then perform dependent Graphics Console
831 device reset, and set display mode to mode 0.
832 If ExtendedVerification is FALSE, only set display mode to mode 0.
833
834 @param This Protocol instance pointer.
835 @param ExtendedVerification Indicates that the driver may perform a more
836 exhaustive verification operation of the device
837 during reset.
838
839 @retval EFI_SUCCESS The text output device was reset.
840 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and
841 could not be reset.
842
843 **/
844 EFI_STATUS
845 EFIAPI
GraphicsConsoleConOutReset(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * This,IN BOOLEAN ExtendedVerification)846 GraphicsConsoleConOutReset (
847 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
848 IN BOOLEAN ExtendedVerification
849 )
850 {
851 EFI_STATUS Status;
852 Status = This->SetMode (This, 0);
853 if (EFI_ERROR (Status)) {
854 return Status;
855 }
856 Status = This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));
857 return Status;
858 }
859
860
861 /**
862 Write a Unicode string to the output device.
863
864 Implements SIMPLE_TEXT_OUTPUT.OutputString().
865 The Unicode string will be converted to Glyphs and will be
866 sent to the Graphics Console.
867
868 @param This Protocol instance pointer.
869 @param WString The NULL-terminated Unicode string to be displayed
870 on the output device(s). All output devices must
871 also support the Unicode drawing defined in this file.
872
873 @retval EFI_SUCCESS The string was output to the device.
874 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output
875 the text.
876 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
877 defined text mode.
878 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
879 characters in the Unicode string could not be
880 rendered and were skipped.
881
882 **/
883 EFI_STATUS
884 EFIAPI
GraphicsConsoleConOutOutputString(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * This,IN CHAR16 * WString)885 GraphicsConsoleConOutOutputString (
886 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
887 IN CHAR16 *WString
888 )
889 {
890 GRAPHICS_CONSOLE_DEV *Private;
891 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
892 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
893 INTN Mode;
894 UINTN MaxColumn;
895 UINTN MaxRow;
896 UINTN Width;
897 UINTN Height;
898 UINTN Delta;
899 EFI_STATUS Status;
900 BOOLEAN Warning;
901 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
902 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
903 UINTN DeltaX;
904 UINTN DeltaY;
905 UINTN Count;
906 UINTN Index;
907 INT32 OriginAttribute;
908 EFI_TPL OldTpl;
909
910 if (This->Mode->Mode == -1) {
911 //
912 // If current mode is not valid, return error.
913 //
914 return EFI_UNSUPPORTED;
915 }
916
917 Status = EFI_SUCCESS;
918
919 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
920 //
921 // Current mode
922 //
923 Mode = This->Mode->Mode;
924 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
925 GraphicsOutput = Private->GraphicsOutput;
926 UgaDraw = Private->UgaDraw;
927
928 MaxColumn = Private->ModeData[Mode].Columns;
929 MaxRow = Private->ModeData[Mode].Rows;
930 DeltaX = (UINTN) Private->ModeData[Mode].DeltaX;
931 DeltaY = (UINTN) Private->ModeData[Mode].DeltaY;
932 Width = MaxColumn * EFI_GLYPH_WIDTH;
933 Height = (MaxRow - 1) * EFI_GLYPH_HEIGHT;
934 Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
935
936 //
937 // The Attributes won't change when during the time OutputString is called
938 //
939 GetTextColors (This, &Foreground, &Background);
940
941 FlushCursor (This);
942
943 Warning = FALSE;
944
945 //
946 // Backup attribute
947 //
948 OriginAttribute = This->Mode->Attribute;
949
950 while (*WString != L'\0') {
951
952 if (*WString == CHAR_BACKSPACE) {
953 //
954 // If the cursor is at the left edge of the display, then move the cursor
955 // one row up.
956 //
957 if (This->Mode->CursorColumn == 0 && This->Mode->CursorRow > 0) {
958 This->Mode->CursorRow--;
959 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);
960 This->OutputString (This, SpaceStr);
961 FlushCursor (This);
962 This->Mode->CursorRow--;
963 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);
964 } else if (This->Mode->CursorColumn > 0) {
965 //
966 // If the cursor is not at the left edge of the display, then move the cursor
967 // left one column.
968 //
969 This->Mode->CursorColumn--;
970 This->OutputString (This, SpaceStr);
971 FlushCursor (This);
972 This->Mode->CursorColumn--;
973 }
974
975 WString++;
976
977 } else if (*WString == CHAR_LINEFEED) {
978 //
979 // If the cursor is at the bottom of the display, then scroll the display one
980 // row, and do not update the cursor position. Otherwise, move the cursor
981 // down one row.
982 //
983 if (This->Mode->CursorRow == (INT32) (MaxRow - 1)) {
984 if (GraphicsOutput != NULL) {
985 //
986 // Scroll Screen Up One Row
987 //
988 GraphicsOutput->Blt (
989 GraphicsOutput,
990 NULL,
991 EfiBltVideoToVideo,
992 DeltaX,
993 DeltaY + EFI_GLYPH_HEIGHT,
994 DeltaX,
995 DeltaY,
996 Width,
997 Height,
998 Delta
999 );
1000
1001 //
1002 // Print Blank Line at last line
1003 //
1004 GraphicsOutput->Blt (
1005 GraphicsOutput,
1006 &Background,
1007 EfiBltVideoFill,
1008 0,
1009 0,
1010 DeltaX,
1011 DeltaY + Height,
1012 Width,
1013 EFI_GLYPH_HEIGHT,
1014 Delta
1015 );
1016 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1017 //
1018 // Scroll Screen Up One Row
1019 //
1020 UgaDraw->Blt (
1021 UgaDraw,
1022 NULL,
1023 EfiUgaVideoToVideo,
1024 DeltaX,
1025 DeltaY + EFI_GLYPH_HEIGHT,
1026 DeltaX,
1027 DeltaY,
1028 Width,
1029 Height,
1030 Delta
1031 );
1032
1033 //
1034 // Print Blank Line at last line
1035 //
1036 UgaDraw->Blt (
1037 UgaDraw,
1038 (EFI_UGA_PIXEL *) (UINTN) &Background,
1039 EfiUgaVideoFill,
1040 0,
1041 0,
1042 DeltaX,
1043 DeltaY + Height,
1044 Width,
1045 EFI_GLYPH_HEIGHT,
1046 Delta
1047 );
1048 }
1049 } else {
1050 This->Mode->CursorRow++;
1051 }
1052
1053 WString++;
1054
1055 } else if (*WString == CHAR_CARRIAGE_RETURN) {
1056 //
1057 // Move the cursor to the beginning of the current row.
1058 //
1059 This->Mode->CursorColumn = 0;
1060 WString++;
1061
1062 } else if (*WString == WIDE_CHAR) {
1063
1064 This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;
1065 WString++;
1066
1067 } else if (*WString == NARROW_CHAR) {
1068
1069 This->Mode->Attribute &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);
1070 WString++;
1071
1072 } else {
1073 //
1074 // Print the character at the current cursor position and move the cursor
1075 // right one column. If this moves the cursor past the right edge of the
1076 // display, then the line should wrap to the beginning of the next line. This
1077 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
1078 // bottom of the display, and the line wraps, then the display will be scrolled
1079 // one line.
1080 // If wide char is going to be displayed, need to display one character at a time
1081 // Or, need to know the display length of a certain string.
1082 //
1083 // Index is used to determine how many character width units (wide = 2, narrow = 1)
1084 // Count is used to determine how many characters are used regardless of their attributes
1085 //
1086 for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {
1087 if (WString[Count] == CHAR_NULL ||
1088 WString[Count] == CHAR_BACKSPACE ||
1089 WString[Count] == CHAR_LINEFEED ||
1090 WString[Count] == CHAR_CARRIAGE_RETURN ||
1091 WString[Count] == WIDE_CHAR ||
1092 WString[Count] == NARROW_CHAR) {
1093 break;
1094 }
1095 //
1096 // Is the wide attribute on?
1097 //
1098 if ((This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) != 0) {
1099 //
1100 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
1101 //
1102 Index++;
1103 //
1104 // This is the end-case where if we are at column 79 and about to print a wide character
1105 // We should prevent this from happening because we will wrap inappropriately. We should
1106 // not print this character until the next line.
1107 //
1108 if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {
1109 Index++;
1110 break;
1111 }
1112 }
1113 }
1114
1115 Status = DrawUnicodeWeightAtCursorN (This, WString, Count);
1116 if (EFI_ERROR (Status)) {
1117 Warning = TRUE;
1118 }
1119 //
1120 // At the end of line, output carriage return and line feed
1121 //
1122 WString += Count;
1123 This->Mode->CursorColumn += (INT32) Index;
1124 if (This->Mode->CursorColumn > (INT32) MaxColumn) {
1125 This->Mode->CursorColumn -= 2;
1126 This->OutputString (This, SpaceStr);
1127 }
1128
1129 if (This->Mode->CursorColumn >= (INT32) MaxColumn) {
1130 FlushCursor (This);
1131 This->OutputString (This, mCrLfString);
1132 FlushCursor (This);
1133 }
1134 }
1135 }
1136
1137 This->Mode->Attribute = OriginAttribute;
1138
1139 FlushCursor (This);
1140
1141 if (Warning) {
1142 Status = EFI_WARN_UNKNOWN_GLYPH;
1143 }
1144
1145 gBS->RestoreTPL (OldTpl);
1146 return Status;
1147
1148 }
1149
1150 /**
1151 Verifies that all characters in a Unicode string can be output to the
1152 target device.
1153
1154 Implements SIMPLE_TEXT_OUTPUT.TestString().
1155 If one of the characters in the *Wstring is neither valid valid Unicode
1156 drawing characters, not ASCII code, then this function will return
1157 EFI_UNSUPPORTED
1158
1159 @param This Protocol instance pointer.
1160 @param WString The NULL-terminated Unicode string to be examined for the output
1161 device(s).
1162
1163 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.
1164 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be
1165 rendered by one or more of the output devices mapped
1166 by the EFI handle.
1167
1168 **/
1169 EFI_STATUS
1170 EFIAPI
GraphicsConsoleConOutTestString(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * This,IN CHAR16 * WString)1171 GraphicsConsoleConOutTestString (
1172 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1173 IN CHAR16 *WString
1174 )
1175 {
1176 EFI_STATUS Status;
1177 UINT16 Count;
1178
1179 EFI_IMAGE_OUTPUT *Blt;
1180
1181 Blt = NULL;
1182 Count = 0;
1183
1184 while (WString[Count] != 0) {
1185 Status = mHiiFont->GetGlyph (
1186 mHiiFont,
1187 WString[Count],
1188 NULL,
1189 &Blt,
1190 NULL
1191 );
1192 if (Blt != NULL) {
1193 FreePool (Blt);
1194 Blt = NULL;
1195 }
1196 Count++;
1197
1198 if (EFI_ERROR (Status)) {
1199 return EFI_UNSUPPORTED;
1200 }
1201 }
1202
1203 return EFI_SUCCESS;
1204 }
1205
1206
1207 /**
1208 Returns information for an available text mode that the output device(s)
1209 supports
1210
1211 Implements SIMPLE_TEXT_OUTPUT.QueryMode().
1212 It returnes information for an available text mode that the Graphics Console supports.
1213 In this driver,we only support text mode 80x25, which is defined as mode 0.
1214
1215 @param This Protocol instance pointer.
1216 @param ModeNumber The mode number to return information on.
1217 @param Columns The returned columns of the requested mode.
1218 @param Rows The returned rows of the requested mode.
1219
1220 @retval EFI_SUCCESS The requested mode information is returned.
1221 @retval EFI_UNSUPPORTED The mode number is not valid.
1222
1223 **/
1224 EFI_STATUS
1225 EFIAPI
GraphicsConsoleConOutQueryMode(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * This,IN UINTN ModeNumber,OUT UINTN * Columns,OUT UINTN * Rows)1226 GraphicsConsoleConOutQueryMode (
1227 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1228 IN UINTN ModeNumber,
1229 OUT UINTN *Columns,
1230 OUT UINTN *Rows
1231 )
1232 {
1233 GRAPHICS_CONSOLE_DEV *Private;
1234 EFI_STATUS Status;
1235 EFI_TPL OldTpl;
1236
1237 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {
1238 return EFI_UNSUPPORTED;
1239 }
1240
1241 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1242 Status = EFI_SUCCESS;
1243
1244 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1245
1246 *Columns = Private->ModeData[ModeNumber].Columns;
1247 *Rows = Private->ModeData[ModeNumber].Rows;
1248
1249 if (*Columns <= 0 || *Rows <= 0) {
1250 Status = EFI_UNSUPPORTED;
1251 goto Done;
1252
1253 }
1254
1255 Done:
1256 gBS->RestoreTPL (OldTpl);
1257 return Status;
1258 }
1259
1260
1261 /**
1262 Sets the output device(s) to a specified mode.
1263
1264 Implements SIMPLE_TEXT_OUTPUT.SetMode().
1265 Set the Graphics Console to a specified mode. In this driver, we only support mode 0.
1266
1267 @param This Protocol instance pointer.
1268 @param ModeNumber The text mode to set.
1269
1270 @retval EFI_SUCCESS The requested text mode is set.
1271 @retval EFI_DEVICE_ERROR The requested text mode cannot be set because of
1272 Graphics Console device error.
1273 @retval EFI_UNSUPPORTED The text mode number is not valid.
1274
1275 **/
1276 EFI_STATUS
1277 EFIAPI
GraphicsConsoleConOutSetMode(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * This,IN UINTN ModeNumber)1278 GraphicsConsoleConOutSetMode (
1279 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1280 IN UINTN ModeNumber
1281 )
1282 {
1283 EFI_STATUS Status;
1284 GRAPHICS_CONSOLE_DEV *Private;
1285 GRAPHICS_CONSOLE_MODE_DATA *ModeData;
1286 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewLineBuffer;
1287 UINT32 HorizontalResolution;
1288 UINT32 VerticalResolution;
1289 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1290 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1291 UINT32 ColorDepth;
1292 UINT32 RefreshRate;
1293 EFI_TPL OldTpl;
1294
1295 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1296
1297 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1298 GraphicsOutput = Private->GraphicsOutput;
1299 UgaDraw = Private->UgaDraw;
1300
1301 //
1302 // Make sure the requested mode number is supported
1303 //
1304 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {
1305 Status = EFI_UNSUPPORTED;
1306 goto Done;
1307 }
1308
1309 ModeData = &(Private->ModeData[ModeNumber]);
1310
1311 if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {
1312 Status = EFI_UNSUPPORTED;
1313 goto Done;
1314 }
1315
1316 //
1317 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1318 //
1319 if (Private->LineBuffer != NULL) {
1320 //
1321 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1322 //
1323 if ((INT32) ModeNumber == This->Mode->Mode) {
1324 //
1325 // Clear the current text window on the current graphics console
1326 //
1327 This->ClearScreen (This);
1328 Status = EFI_SUCCESS;
1329 goto Done;
1330 }
1331 //
1332 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,
1333 // so erase the cursor, and free the LineBuffer for the current mode
1334 //
1335 FlushCursor (This);
1336
1337 FreePool (Private->LineBuffer);
1338 }
1339
1340 //
1341 // Attempt to allocate a line buffer for the requested mode number
1342 //
1343 NewLineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT);
1344
1345 if (NewLineBuffer == NULL) {
1346 //
1347 // The new line buffer could not be allocated, so return an error.
1348 // No changes to the state of the current console have been made, so the current console is still valid
1349 //
1350 Status = EFI_OUT_OF_RESOURCES;
1351 goto Done;
1352 }
1353
1354 //
1355 // Assign the current line buffer to the newly allocated line buffer
1356 //
1357 Private->LineBuffer = NewLineBuffer;
1358
1359 if (GraphicsOutput != NULL) {
1360 if (ModeData->GopModeNumber != GraphicsOutput->Mode->Mode) {
1361 //
1362 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1363 //
1364 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeData->GopModeNumber);
1365 if (EFI_ERROR (Status)) {
1366 //
1367 // The mode set operation failed
1368 //
1369 goto Done;
1370 }
1371 } else {
1372 //
1373 // The current graphics mode is correct, so simply clear the entire display
1374 //
1375 Status = GraphicsOutput->Blt (
1376 GraphicsOutput,
1377 &mGraphicsEfiColors[0],
1378 EfiBltVideoFill,
1379 0,
1380 0,
1381 0,
1382 0,
1383 ModeData->GopWidth,
1384 ModeData->GopHeight,
1385 0
1386 );
1387 }
1388 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1389 //
1390 // Get the current UGA Draw mode information
1391 //
1392 Status = UgaDraw->GetMode (
1393 UgaDraw,
1394 &HorizontalResolution,
1395 &VerticalResolution,
1396 &ColorDepth,
1397 &RefreshRate
1398 );
1399 if (EFI_ERROR (Status) || HorizontalResolution != ModeData->GopWidth || VerticalResolution != ModeData->GopHeight) {
1400 //
1401 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1402 //
1403 Status = UgaDraw->SetMode (
1404 UgaDraw,
1405 ModeData->GopWidth,
1406 ModeData->GopHeight,
1407 32,
1408 60
1409 );
1410 if (EFI_ERROR (Status)) {
1411 //
1412 // The mode set operation failed
1413 //
1414 goto Done;
1415 }
1416 } else {
1417 //
1418 // The current graphics mode is correct, so simply clear the entire display
1419 //
1420 Status = UgaDraw->Blt (
1421 UgaDraw,
1422 (EFI_UGA_PIXEL *) (UINTN) &mGraphicsEfiColors[0],
1423 EfiUgaVideoFill,
1424 0,
1425 0,
1426 0,
1427 0,
1428 ModeData->GopWidth,
1429 ModeData->GopHeight,
1430 0
1431 );
1432 }
1433 }
1434
1435 //
1436 // The new mode is valid, so commit the mode change
1437 //
1438 This->Mode->Mode = (INT32) ModeNumber;
1439
1440 //
1441 // Move the text cursor to the upper left hand corner of the display and flush it
1442 //
1443 This->Mode->CursorColumn = 0;
1444 This->Mode->CursorRow = 0;
1445
1446 FlushCursor (This);
1447
1448 Status = EFI_SUCCESS;
1449
1450 Done:
1451 gBS->RestoreTPL (OldTpl);
1452 return Status;
1453 }
1454
1455
1456 /**
1457 Sets the background and foreground colors for the OutputString () and
1458 ClearScreen () functions.
1459
1460 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
1461
1462 @param This Protocol instance pointer.
1463 @param Attribute The attribute to set. Bits 0..3 are the foreground
1464 color, and bits 4..6 are the background color.
1465 All other bits are undefined and must be zero.
1466
1467 @retval EFI_SUCCESS The requested attribute is set.
1468 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to Graphics Console port error.
1469 @retval EFI_UNSUPPORTED The attribute requested is not defined.
1470
1471 **/
1472 EFI_STATUS
1473 EFIAPI
GraphicsConsoleConOutSetAttribute(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * This,IN UINTN Attribute)1474 GraphicsConsoleConOutSetAttribute (
1475 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1476 IN UINTN Attribute
1477 )
1478 {
1479 EFI_TPL OldTpl;
1480
1481 if ((Attribute | 0x7F) != 0x7F) {
1482 return EFI_UNSUPPORTED;
1483 }
1484
1485 if ((INT32) Attribute == This->Mode->Attribute) {
1486 return EFI_SUCCESS;
1487 }
1488
1489 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1490
1491 FlushCursor (This);
1492
1493 This->Mode->Attribute = (INT32) Attribute;
1494
1495 FlushCursor (This);
1496
1497 gBS->RestoreTPL (OldTpl);
1498
1499 return EFI_SUCCESS;
1500 }
1501
1502
1503 /**
1504 Clears the output device(s) display to the currently selected background
1505 color.
1506
1507 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
1508
1509 @param This Protocol instance pointer.
1510
1511 @retval EFI_SUCCESS The operation completed successfully.
1512 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1513 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
1514
1515 **/
1516 EFI_STATUS
1517 EFIAPI
GraphicsConsoleConOutClearScreen(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * This)1518 GraphicsConsoleConOutClearScreen (
1519 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
1520 )
1521 {
1522 EFI_STATUS Status;
1523 GRAPHICS_CONSOLE_DEV *Private;
1524 GRAPHICS_CONSOLE_MODE_DATA *ModeData;
1525 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1526 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1527 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
1528 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
1529 EFI_TPL OldTpl;
1530
1531 if (This->Mode->Mode == -1) {
1532 //
1533 // If current mode is not valid, return error.
1534 //
1535 return EFI_UNSUPPORTED;
1536 }
1537
1538 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1539
1540 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1541 GraphicsOutput = Private->GraphicsOutput;
1542 UgaDraw = Private->UgaDraw;
1543 ModeData = &(Private->ModeData[This->Mode->Mode]);
1544
1545 GetTextColors (This, &Foreground, &Background);
1546 if (GraphicsOutput != NULL) {
1547 Status = GraphicsOutput->Blt (
1548 GraphicsOutput,
1549 &Background,
1550 EfiBltVideoFill,
1551 0,
1552 0,
1553 0,
1554 0,
1555 ModeData->GopWidth,
1556 ModeData->GopHeight,
1557 0
1558 );
1559 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1560 Status = UgaDraw->Blt (
1561 UgaDraw,
1562 (EFI_UGA_PIXEL *) (UINTN) &Background,
1563 EfiUgaVideoFill,
1564 0,
1565 0,
1566 0,
1567 0,
1568 ModeData->GopWidth,
1569 ModeData->GopHeight,
1570 0
1571 );
1572 } else {
1573 Status = EFI_UNSUPPORTED;
1574 }
1575
1576 This->Mode->CursorColumn = 0;
1577 This->Mode->CursorRow = 0;
1578
1579 FlushCursor (This);
1580
1581 gBS->RestoreTPL (OldTpl);
1582
1583 return Status;
1584 }
1585
1586
1587 /**
1588 Sets the current coordinates of the cursor position.
1589
1590 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
1591
1592 @param This Protocol instance pointer.
1593 @param Column The position to set the cursor to. Must be greater than or
1594 equal to zero and less than the number of columns and rows
1595 by QueryMode ().
1596 @param Row The position to set the cursor to. Must be greater than or
1597 equal to zero and less than the number of columns and rows
1598 by QueryMode ().
1599
1600 @retval EFI_SUCCESS The operation completed successfully.
1601 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1602 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the
1603 cursor position is invalid for the current mode.
1604
1605 **/
1606 EFI_STATUS
1607 EFIAPI
GraphicsConsoleConOutSetCursorPosition(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * This,IN UINTN Column,IN UINTN Row)1608 GraphicsConsoleConOutSetCursorPosition (
1609 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1610 IN UINTN Column,
1611 IN UINTN Row
1612 )
1613 {
1614 GRAPHICS_CONSOLE_DEV *Private;
1615 GRAPHICS_CONSOLE_MODE_DATA *ModeData;
1616 EFI_STATUS Status;
1617 EFI_TPL OldTpl;
1618
1619 if (This->Mode->Mode == -1) {
1620 //
1621 // If current mode is not valid, return error.
1622 //
1623 return EFI_UNSUPPORTED;
1624 }
1625
1626 Status = EFI_SUCCESS;
1627
1628 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1629
1630 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1631 ModeData = &(Private->ModeData[This->Mode->Mode]);
1632
1633 if ((Column >= ModeData->Columns) || (Row >= ModeData->Rows)) {
1634 Status = EFI_UNSUPPORTED;
1635 goto Done;
1636 }
1637
1638 if ((This->Mode->CursorColumn == (INT32) Column) && (This->Mode->CursorRow == (INT32) Row)) {
1639 Status = EFI_SUCCESS;
1640 goto Done;
1641 }
1642
1643 FlushCursor (This);
1644
1645 This->Mode->CursorColumn = (INT32) Column;
1646 This->Mode->CursorRow = (INT32) Row;
1647
1648 FlushCursor (This);
1649
1650 Done:
1651 gBS->RestoreTPL (OldTpl);
1652
1653 return Status;
1654 }
1655
1656
1657 /**
1658 Makes the cursor visible or invisible.
1659
1660 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1661
1662 @param This Protocol instance pointer.
1663 @param Visible If TRUE, the cursor is set to be visible, If FALSE,
1664 the cursor is set to be invisible.
1665
1666 @retval EFI_SUCCESS The operation completed successfully.
1667 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
1668 defined text mode.
1669
1670 **/
1671 EFI_STATUS
1672 EFIAPI
GraphicsConsoleConOutEnableCursor(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * This,IN BOOLEAN Visible)1673 GraphicsConsoleConOutEnableCursor (
1674 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1675 IN BOOLEAN Visible
1676 )
1677 {
1678 EFI_TPL OldTpl;
1679
1680 if (This->Mode->Mode == -1) {
1681 //
1682 // If current mode is not valid, return error.
1683 //
1684 return EFI_UNSUPPORTED;
1685 }
1686
1687 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1688
1689 FlushCursor (This);
1690
1691 This->Mode->CursorVisible = Visible;
1692
1693 FlushCursor (This);
1694
1695 gBS->RestoreTPL (OldTpl);
1696 return EFI_SUCCESS;
1697 }
1698
1699 /**
1700 Gets Graphics Console devcie's foreground color and background color.
1701
1702 @param This Protocol instance pointer.
1703 @param Foreground Returned text foreground color.
1704 @param Background Returned text background color.
1705
1706 @retval EFI_SUCCESS It returned always.
1707
1708 **/
1709 EFI_STATUS
GetTextColors(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * This,OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL * Foreground,OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL * Background)1710 GetTextColors (
1711 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1712 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,
1713 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background
1714 )
1715 {
1716 INTN Attribute;
1717
1718 Attribute = This->Mode->Attribute & 0x7F;
1719
1720 *Foreground = mGraphicsEfiColors[Attribute & 0x0f];
1721 *Background = mGraphicsEfiColors[Attribute >> 4];
1722
1723 return EFI_SUCCESS;
1724 }
1725
1726 /**
1727 Draw Unicode string on the Graphics Console device's screen.
1728
1729 @param This Protocol instance pointer.
1730 @param UnicodeWeight One Unicode string to be displayed.
1731 @param Count The count of Unicode string.
1732
1733 @retval EFI_OUT_OF_RESOURCES If no memory resource to use.
1734 @retval EFI_UNSUPPORTED If no Graphics Output protocol and UGA Draw
1735 protocol exist.
1736 @retval EFI_SUCCESS Drawing Unicode string implemented successfully.
1737
1738 **/
1739 EFI_STATUS
DrawUnicodeWeightAtCursorN(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * This,IN CHAR16 * UnicodeWeight,IN UINTN Count)1740 DrawUnicodeWeightAtCursorN (
1741 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1742 IN CHAR16 *UnicodeWeight,
1743 IN UINTN Count
1744 )
1745 {
1746 EFI_STATUS Status;
1747 GRAPHICS_CONSOLE_DEV *Private;
1748 EFI_IMAGE_OUTPUT *Blt;
1749 EFI_STRING String;
1750 EFI_FONT_DISPLAY_INFO *FontInfo;
1751 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1752 EFI_HII_ROW_INFO *RowInfoArray;
1753 UINTN RowInfoArraySize;
1754
1755 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1756 Blt = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
1757 if (Blt == NULL) {
1758 return EFI_OUT_OF_RESOURCES;
1759 }
1760
1761 Blt->Width = (UINT16) (Private->ModeData[This->Mode->Mode].GopWidth);
1762 Blt->Height = (UINT16) (Private->ModeData[This->Mode->Mode].GopHeight);
1763
1764 String = AllocateCopyPool ((Count + 1) * sizeof (CHAR16), UnicodeWeight);
1765 if (String == NULL) {
1766 FreePool (Blt);
1767 return EFI_OUT_OF_RESOURCES;
1768 }
1769 //
1770 // Set the end character
1771 //
1772 *(String + Count) = L'\0';
1773
1774 FontInfo = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));
1775 if (FontInfo == NULL) {
1776 FreePool (Blt);
1777 FreePool (String);
1778 return EFI_OUT_OF_RESOURCES;
1779 }
1780 //
1781 // Get current foreground and background colors.
1782 //
1783 GetTextColors (This, &FontInfo->ForegroundColor, &FontInfo->BackgroundColor);
1784
1785 if (Private->GraphicsOutput != NULL) {
1786 //
1787 // If Graphics Output protocol exists, using HII Font protocol to draw.
1788 //
1789 Blt->Image.Screen = Private->GraphicsOutput;
1790
1791 Status = mHiiFont->StringToImage (
1792 mHiiFont,
1793 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN | EFI_HII_IGNORE_LINE_BREAK,
1794 String,
1795 FontInfo,
1796 &Blt,
1797 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
1798 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
1799 NULL,
1800 NULL,
1801 NULL
1802 );
1803
1804 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1805 //
1806 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,
1807 // using UGA Draw protocol to draw.
1808 //
1809 ASSERT (Private->UgaDraw!= NULL);
1810
1811 UgaDraw = Private->UgaDraw;
1812
1813 Blt->Image.Bitmap = AllocateZeroPool (Blt->Width * Blt->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
1814 if (Blt->Image.Bitmap == NULL) {
1815 FreePool (Blt);
1816 FreePool (String);
1817 return EFI_OUT_OF_RESOURCES;
1818 }
1819
1820 RowInfoArray = NULL;
1821 //
1822 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,
1823 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.
1824 //
1825 Status = mHiiFont->StringToImage (
1826 mHiiFont,
1827 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK,
1828 String,
1829 FontInfo,
1830 &Blt,
1831 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
1832 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
1833 &RowInfoArray,
1834 &RowInfoArraySize,
1835 NULL
1836 );
1837
1838 if (!EFI_ERROR (Status)) {
1839 //
1840 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will
1841 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.
1842 //
1843 ASSERT (RowInfoArraySize <= 1);
1844
1845 Status = UgaDraw->Blt (
1846 UgaDraw,
1847 (EFI_UGA_PIXEL *) Blt->Image.Bitmap,
1848 EfiUgaBltBufferToVideo,
1849 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
1850 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
1851 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
1852 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
1853 RowInfoArray[0].LineWidth,
1854 RowInfoArray[0].LineHeight,
1855 Blt->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
1856 );
1857 }
1858
1859 FreePool (RowInfoArray);
1860 FreePool (Blt->Image.Bitmap);
1861 } else {
1862 Status = EFI_UNSUPPORTED;
1863 }
1864
1865 if (Blt != NULL) {
1866 FreePool (Blt);
1867 }
1868 if (String != NULL) {
1869 FreePool (String);
1870 }
1871 if (FontInfo != NULL) {
1872 FreePool (FontInfo);
1873 }
1874 return Status;
1875 }
1876
1877 /**
1878 Flush the cursor on the screen.
1879
1880 If CursorVisible is FALSE, nothing to do and return directly.
1881 If CursorVisible is TRUE,
1882 i) If the cursor shows on screen, it will be erased.
1883 ii) If the cursor does not show on screen, it will be shown.
1884
1885 @param This Protocol instance pointer.
1886
1887 @retval EFI_SUCCESS The cursor is erased successfully.
1888
1889 **/
1890 EFI_STATUS
FlushCursor(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * This)1891 FlushCursor (
1892 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
1893 )
1894 {
1895 GRAPHICS_CONSOLE_DEV *Private;
1896 EFI_SIMPLE_TEXT_OUTPUT_MODE *CurrentMode;
1897 INTN GlyphX;
1898 INTN GlyphY;
1899 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1900 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1901 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground;
1902 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background;
1903 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar[EFI_GLYPH_HEIGHT][EFI_GLYPH_WIDTH];
1904 UINTN PosX;
1905 UINTN PosY;
1906
1907 CurrentMode = This->Mode;
1908
1909 if (!CurrentMode->CursorVisible) {
1910 return EFI_SUCCESS;
1911 }
1912
1913 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1914 GraphicsOutput = Private->GraphicsOutput;
1915 UgaDraw = Private->UgaDraw;
1916
1917 //
1918 // In this driver, only narrow character was supported.
1919 //
1920 //
1921 // Blt a character to the screen
1922 //
1923 GlyphX = (CurrentMode->CursorColumn * EFI_GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;
1924 GlyphY = (CurrentMode->CursorRow * EFI_GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;
1925 if (GraphicsOutput != NULL) {
1926 GraphicsOutput->Blt (
1927 GraphicsOutput,
1928 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,
1929 EfiBltVideoToBltBuffer,
1930 GlyphX,
1931 GlyphY,
1932 0,
1933 0,
1934 EFI_GLYPH_WIDTH,
1935 EFI_GLYPH_HEIGHT,
1936 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
1937 );
1938 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1939 UgaDraw->Blt (
1940 UgaDraw,
1941 (EFI_UGA_PIXEL *) (UINTN) BltChar,
1942 EfiUgaVideoToBltBuffer,
1943 GlyphX,
1944 GlyphY,
1945 0,
1946 0,
1947 EFI_GLYPH_WIDTH,
1948 EFI_GLYPH_HEIGHT,
1949 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
1950 );
1951 }
1952
1953 GetTextColors (This, &Foreground.Pixel, &Background.Pixel);
1954
1955 //
1956 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1957 //
1958 for (PosY = 0; PosY < EFI_GLYPH_HEIGHT; PosY++) {
1959 for (PosX = 0; PosX < EFI_GLYPH_WIDTH; PosX++) {
1960 if ((mCursorGlyph.GlyphCol1[PosY] & (BIT0 << PosX)) != 0) {
1961 BltChar[PosY][EFI_GLYPH_WIDTH - PosX - 1].Raw ^= Foreground.Raw;
1962 }
1963 }
1964 }
1965
1966 if (GraphicsOutput != NULL) {
1967 GraphicsOutput->Blt (
1968 GraphicsOutput,
1969 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,
1970 EfiBltBufferToVideo,
1971 0,
1972 0,
1973 GlyphX,
1974 GlyphY,
1975 EFI_GLYPH_WIDTH,
1976 EFI_GLYPH_HEIGHT,
1977 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
1978 );
1979 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1980 UgaDraw->Blt (
1981 UgaDraw,
1982 (EFI_UGA_PIXEL *) (UINTN) BltChar,
1983 EfiUgaBltBufferToVideo,
1984 0,
1985 0,
1986 GlyphX,
1987 GlyphY,
1988 EFI_GLYPH_WIDTH,
1989 EFI_GLYPH_HEIGHT,
1990 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
1991 );
1992 }
1993
1994 return EFI_SUCCESS;
1995 }
1996
1997 /**
1998 HII Database Protocol notification event handler.
1999
2000 Register font package when HII Database Protocol has been installed.
2001
2002 @param[in] Event Event whose notification function is being invoked.
2003 @param[in] Context Pointer to the notification function's context.
2004 **/
2005 VOID
2006 EFIAPI
RegisterFontPackage(IN EFI_EVENT Event,IN VOID * Context)2007 RegisterFontPackage (
2008 IN EFI_EVENT Event,
2009 IN VOID *Context
2010 )
2011 {
2012 EFI_STATUS Status;
2013 EFI_HII_SIMPLE_FONT_PACKAGE_HDR *SimplifiedFont;
2014 UINT32 PackageLength;
2015 UINT8 *Package;
2016 UINT8 *Location;
2017 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
2018
2019 //
2020 // Locate HII Database Protocol
2021 //
2022 Status = gBS->LocateProtocol (
2023 &gEfiHiiDatabaseProtocolGuid,
2024 NULL,
2025 (VOID **) &HiiDatabase
2026 );
2027 if (EFI_ERROR (Status)) {
2028 return;
2029 }
2030
2031 //
2032 // Add 4 bytes to the header for entire length for HiiAddPackages use only.
2033 //
2034 // +--------------------------------+ <-- Package
2035 // | |
2036 // | PackageLength(4 bytes) |
2037 // | |
2038 // |--------------------------------| <-- SimplifiedFont
2039 // | |
2040 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
2041 // | |
2042 // |--------------------------------| <-- Location
2043 // | |
2044 // | gUsStdNarrowGlyphData |
2045 // | |
2046 // +--------------------------------+
2047
2048 PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + mNarrowFontSize + 4;
2049 Package = AllocateZeroPool (PackageLength);
2050 ASSERT (Package != NULL);
2051
2052 WriteUnaligned32((UINT32 *) Package,PackageLength);
2053 SimplifiedFont = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR *) (Package + 4);
2054 SimplifiedFont->Header.Length = (UINT32) (PackageLength - 4);
2055 SimplifiedFont->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;
2056 SimplifiedFont->NumberOfNarrowGlyphs = (UINT16) (mNarrowFontSize / sizeof (EFI_NARROW_GLYPH));
2057
2058 Location = (UINT8 *) (&SimplifiedFont->NumberOfWideGlyphs + 1);
2059 CopyMem (Location, gUsStdNarrowGlyphData, mNarrowFontSize);
2060
2061 //
2062 // Add this simplified font package to a package list then install it.
2063 //
2064 mHiiHandle = HiiAddPackages (
2065 &mFontPackageListGuid,
2066 NULL,
2067 Package,
2068 NULL
2069 );
2070 ASSERT (mHiiHandle != NULL);
2071 FreePool (Package);
2072 }
2073
2074 /**
2075 The user Entry Point for module GraphicsConsole. The user code starts with this function.
2076
2077 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2078 @param[in] SystemTable A pointer to the EFI System Table.
2079
2080 @retval EFI_SUCCESS The entry point is executed successfully.
2081 @return other Some error occurs when executing this entry point.
2082
2083 **/
2084 EFI_STATUS
2085 EFIAPI
InitializeGraphicsConsole(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)2086 InitializeGraphicsConsole (
2087 IN EFI_HANDLE ImageHandle,
2088 IN EFI_SYSTEM_TABLE *SystemTable
2089 )
2090 {
2091 EFI_STATUS Status;
2092
2093 //
2094 // Register notify function on HII Database Protocol to add font package.
2095 //
2096 EfiCreateProtocolNotifyEvent (
2097 &gEfiHiiDatabaseProtocolGuid,
2098 TPL_CALLBACK,
2099 RegisterFontPackage,
2100 NULL,
2101 &mHiiRegistration
2102 );
2103
2104 //
2105 // Install driver model protocol(s).
2106 //
2107 Status = EfiLibInstallDriverBindingComponentName2 (
2108 ImageHandle,
2109 SystemTable,
2110 &gGraphicsConsoleDriverBinding,
2111 ImageHandle,
2112 &gGraphicsConsoleComponentName,
2113 &gGraphicsConsoleComponentName2
2114 );
2115 ASSERT_EFI_ERROR (Status);
2116
2117 return Status;
2118 }
2119
2120
2121