37024575eee31e0a0e15e99cd8ecc52790e6584d
[reactos.git] / reactos / boot / environ / lib / platform / display.c
1 /*
2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Library
4 * FILE: boot/environ/lib/platform/display.c
5 * PURPOSE: Boot Library Display Management Routines
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include "bl.h"
12 #include <bcd.h>
13
14 /* DATA VARIABLES ************************************************************/
15
16 typedef enum _BL_COLOR
17 {
18 Black,
19 Blue,
20 Green,
21 Cyan,
22 Red,
23 Magenta,
24 Brown,
25 LtGray,
26 Gray,
27 LtBlue,
28 LtGreen,
29 LtCyan,
30 LtRed,
31 LtMagenta,
32 Yellow,
33 White
34 } BL_COLOR, *PBL_COLOR;
35
36 typedef struct _BL_DISPLAY_STATE
37 {
38 ULONG BgColor;
39 ULONG FgColor;
40 ULONG XPos;
41 ULONG YPos;
42 ULONG CursorVisible;
43 } BL_DISPLAY_STATE, *PBL_DISPLAY_STATE;
44
45 typedef struct _BL_DISPLAY_MODE
46 {
47 ULONG HRes;
48 ULONG VRes;
49 ULONG HRes2;
50 } BL_DISPLAY_MODE, *PBL_DISPLAY_MODE;
51
52 struct _BL_TEXT_CONSOLE;
53 typedef
54 NTSTATUS
55 (*PCONSOLE_DESTRUCT) (
56 _In_ struct _BL_TEXT_CONSOLE* Console
57 );
58
59 typedef
60 NTSTATUS
61 (*PCONSOLE_REINITIALIZE) (
62 _In_ struct _BL_TEXT_CONSOLE* Console
63 );
64
65 typedef
66 NTSTATUS
67 (*PCONSOLE_GET_TEXT_STATE) (
68 _In_ struct _BL_TEXT_CONSOLE* Console,
69 _Out_ PBL_DISPLAY_STATE TextState
70 );
71
72 typedef
73 NTSTATUS
74 (*PCONSOLE_SET_TEXT_STATE) (
75 _In_ struct _BL_TEXT_CONSOLE* Console,
76 _In_ ULONG Flags,
77 _In_ PBL_DISPLAY_STATE TextState
78 );
79
80 typedef
81 NTSTATUS
82 (*PCONSOLE_GET_TEXT_RESOLUTION) (
83 _In_ struct _BL_TEXT_CONSOLE* Console,
84 _Out_ PULONG TextResolution
85 );
86
87 typedef
88 NTSTATUS
89 (*PCONSOLE_SET_TEXT_RESOLUTION) (
90 _In_ struct _BL_TEXT_CONSOLE* Console,
91 _In_ ULONG NewTextResolution,
92 _Out_ PULONG OldTextResolution
93 );
94
95 typedef
96 NTSTATUS
97 (*PCONSOLE_CLEAR_TEXT) (
98 _In_ struct _BL_TEXT_CONSOLE* Console,
99 _In_ ULONG Attribute
100 );
101
102
103 typedef
104 NTSTATUS
105 (*PCONSOLE_WRITE_TEXT) (
106 _In_ struct _BL_TEXT_CONSOLE* Console,
107 _In_ PCHAR Text,
108 _In_ ULONG Attribute
109 );
110
111 typedef struct _BL_TEXT_CONSOLE_VTABLE
112 {
113 PCONSOLE_DESTRUCT Destruct;
114 PCONSOLE_REINITIALIZE Reinitialize;
115 PCONSOLE_GET_TEXT_STATE GetTextState;
116 PCONSOLE_SET_TEXT_STATE SetTextState;
117 PCONSOLE_GET_TEXT_RESOLUTION GetTextResolution;
118 PCONSOLE_SET_TEXT_RESOLUTION SetTextResolution;
119 PCONSOLE_CLEAR_TEXT ClearText;
120 PCONSOLE_WRITE_TEXT WriteText;
121 } BL_TEXT_CONSOLE_VTABLE, *PBL_TEXT_CONSOLE_VTABLE;
122
123 typedef struct _BL_TEXT_CONSOLE
124 {
125 PBL_TEXT_CONSOLE_VTABLE Callbacks;
126 BL_DISPLAY_STATE State;
127 BL_DISPLAY_MODE DisplayMode;
128 BOOLEAN Active;
129 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* Protocol;
130 ULONG Mode;
131 EFI_SIMPLE_TEXT_OUTPUT_MODE OldMode;
132 } BL_TEXT_CONSOLE, *PBL_TEXT_CONSOLE;
133
134 PVOID BfiCachedStrikeData;
135 LIST_ENTRY BfiDeferredListHead;
136 LIST_ENTRY BfiFontFileListHead;
137
138 PVOID BfiGraphicsRectangle;
139
140 ULONG ConsoleGraphicalResolutionListFlags;
141 BL_DISPLAY_MODE ConsoleGraphicalResolutionList[3] =
142 {
143 {1024, 768, 1024},
144 {800, 600, 800},
145 {1024, 600, 1024}
146 };
147
148 BL_DISPLAY_MODE ConsoleTextResolutionList[1] =
149 {
150 {80, 31, 80}
151 };
152
153 NTSTATUS
154 ConsoleTextLocalDestruct (
155 _In_ struct _BL_TEXT_CONSOLE* Console
156 );
157
158 NTSTATUS
159 ConsoleTextLocalReinitialize (
160 _In_ struct _BL_TEXT_CONSOLE* Console
161 );
162
163 NTSTATUS
164 ConsoleTextBaseGetTextState (
165 _In_ struct _BL_TEXT_CONSOLE* Console,
166 _Out_ PBL_DISPLAY_STATE TextState
167 );
168
169 NTSTATUS
170 ConsoleTextLocalSetTextState (
171 _In_ struct _BL_TEXT_CONSOLE* Console,
172 _In_ ULONG Flags,
173 _In_ PBL_DISPLAY_STATE TextState
174 );
175
176 NTSTATUS
177 ConsoleTextBaseGetTextResolution (
178 _In_ struct _BL_TEXT_CONSOLE* Console,
179 _Out_ PULONG TextResolution
180 );
181
182 NTSTATUS
183 ConsoleTextLocalSetTextResolution (
184 _In_ struct _BL_TEXT_CONSOLE* Console,
185 _In_ ULONG NewTextResolution,
186 _Out_ PULONG OldTextResolution
187 );
188
189 NTSTATUS
190 ConsoleTextLocalClearText (
191 _In_ struct _BL_TEXT_CONSOLE* Console,
192 _In_ ULONG Attribute
193 );
194
195 NTSTATUS
196 ConsoleTextLocalWriteText (
197 _In_ struct _BL_TEXT_CONSOLE* Console,
198 _In_ PCHAR Text,
199 _In_ ULONG Attribute
200 );
201
202 BL_TEXT_CONSOLE_VTABLE ConsoleTextLocalVtbl =
203 {
204 ConsoleTextLocalDestruct,
205 ConsoleTextLocalReinitialize,
206 ConsoleTextBaseGetTextState,
207 ConsoleTextLocalSetTextState,
208 ConsoleTextBaseGetTextResolution,
209 ConsoleTextLocalSetTextResolution,
210 ConsoleTextLocalClearText,
211 ConsoleTextLocalWriteText
212 };
213
214 PVOID DspRemoteInputConsole;
215 PVOID DspTextConsole;
216 PVOID DspGraphicalConsole;
217
218 /* FUNCTIONS *****************************************************************/
219
220 BOOLEAN
221 ConsolepFindResolution (
222 _In_ PBL_DISPLAY_MODE Mode,
223 _In_ PBL_DISPLAY_MODE List,
224 _In_ ULONG MaxIndex
225 )
226 {
227 PBL_DISPLAY_MODE ListEnd;
228
229 /* Loop until we hit the maximum supported list index */
230 ListEnd = &List[MaxIndex];
231 while (List != ListEnd)
232 {
233 /* Does this resolution match? */
234 if ((Mode->HRes != List->HRes) || (Mode->VRes != List->VRes))
235 {
236 /* Try another one*/
237 List++;
238 }
239
240 /* Yep -- we got a match */
241 return TRUE;
242 }
243
244 /* No matches were found */
245 return FALSE;
246 }
247
248 BL_COLOR
249 ConsoleEfiTextGetColorForeground (
250 _In_ UINT32 Attributes
251 )
252 {
253 switch (Attributes & 0x0F)
254 {
255 case EFI_BLACK:
256 return Black;
257 case EFI_BLUE:
258 return Blue;
259 case EFI_GREEN:
260 return Green;
261 case EFI_RED:
262 return Red;
263 case EFI_CYAN:
264 return Cyan;
265 case EFI_MAGENTA:
266 return Magenta;
267 case EFI_BROWN:
268 return Brown;
269 case EFI_LIGHTGRAY:
270 return LtGray;
271 case EFI_DARKGRAY:
272 return Gray;
273 case EFI_LIGHTBLUE:
274 return LtBlue;
275 case EFI_LIGHTGREEN:
276 return LtGreen;
277 case EFI_LIGHTCYAN:
278 return LtCyan;
279 case EFI_LIGHTRED:
280 return LtRed;
281 case EFI_LIGHTMAGENTA:
282 return LtMagenta;
283 case EFI_YELLOW:
284 return Yellow;
285 case EFI_WHITE:
286 default:
287 return White;
288 }
289 }
290
291 BL_COLOR
292 ConsoleEfiTextGetColorBackground (
293 _In_ UINT32 Attributes
294 )
295 {
296 switch (Attributes & 0xF0)
297 {
298 case EFI_BACKGROUND_MAGENTA:
299 return Magenta;
300 case EFI_BACKGROUND_BROWN:
301 return Brown;
302 case EFI_BACKGROUND_LIGHTGRAY:
303 return White;
304 default:
305 case EFI_BACKGROUND_BLACK:
306 return Black;
307 case EFI_BACKGROUND_RED:
308 return Red;
309 case EFI_BACKGROUND_GREEN:
310 return Green;
311 case EFI_BACKGROUND_CYAN:
312 return Cyan;
313 case EFI_BACKGROUND_BLUE:
314 return Blue;
315 }
316 }
317
318 ULONG
319 ConsoleEfiTextGetEfiColorBackground (
320 _In_ BL_COLOR Color
321 )
322 {
323 switch (Color)
324 {
325 case Blue:
326 case LtBlue:
327 return EFI_BACKGROUND_BLUE;
328 case Green:
329 case LtGreen:
330 return EFI_BACKGROUND_GREEN;
331 case Cyan:
332 case LtCyan:
333 return EFI_BACKGROUND_CYAN;
334 case Red:
335 case LtRed:
336 return EFI_BACKGROUND_RED;
337 case Magenta:
338 case LtMagenta:
339 return EFI_BACKGROUND_MAGENTA;
340 case Brown:
341 case Yellow:
342 return EFI_BACKGROUND_BROWN;
343 case LtGray:
344 case White:
345 return EFI_BACKGROUND_LIGHTGRAY;
346 case Black:
347 case Gray:
348 default:
349 return EFI_BACKGROUND_BLACK;
350 }
351 }
352
353 ULONG
354 ConsoleEfiTextGetEfiColorForeground (
355 _In_ BL_COLOR Color
356 )
357 {
358 switch (Color)
359 {
360 case Black:
361 return EFI_BLACK;
362 case Blue:
363 return EFI_BLUE;
364 case Green:
365 return EFI_GREEN;
366 case Cyan:
367 return EFI_CYAN;
368 case Red:
369 return EFI_RED;
370 case Magenta:
371 return EFI_MAGENTA;
372 case Brown:
373 return EFI_BROWN;
374 case LtGray:
375 return EFI_LIGHTGRAY;
376 case Gray:
377 return EFI_DARKGRAY;
378 case LtBlue:
379 return EFI_LIGHTBLUE;
380 case LtGreen:
381 return EFI_LIGHTGREEN;
382 case LtCyan:
383 return EFI_LIGHTCYAN;
384 case LtRed:
385 return EFI_LIGHTRED;
386 case LtMagenta:
387 return EFI_LIGHTMAGENTA;
388 case Yellow:
389 return EFI_YELLOW;
390 case White:
391 default:
392 return EFI_WHITE;
393 }
394 }
395
396 ULONG
397 ConsoleEfiTextGetAttribute (
398 BL_COLOR BgColor,
399 BL_COLOR FgColor
400 )
401 {
402 /* Convert each part and OR into a single attribute */
403 return ConsoleEfiTextGetEfiColorBackground(BgColor) |
404 ConsoleEfiTextGetEfiColorForeground(FgColor);
405 }
406
407 VOID
408 ConsoleEfiTextGetStateFromMode (
409 _In_ EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode,
410 _Out_ PBL_DISPLAY_STATE State
411 )
412 {
413
414 ULONG TextWidth, TextHeight;
415
416 /* Get all the EFI data and convert it into our own structure */
417 BlDisplayGetTextCellResolution(&TextWidth, &TextHeight);
418 State->FgColor = ConsoleEfiTextGetColorForeground(Mode->Attribute);
419 State->BgColor = ConsoleEfiTextGetColorBackground(Mode->Attribute);
420 State->XPos = Mode->CursorColumn * TextWidth;
421 State->YPos = Mode->CursorRow * TextHeight;
422 State->CursorVisible = Mode->CursorVisible != FALSE;
423 }
424
425 NTSTATUS
426 ConsoleFirmwareTextSetState (
427 _In_ PBL_TEXT_CONSOLE TextConsole,
428 _In_ UCHAR Mask,
429 _In_ PBL_DISPLAY_STATE State
430 )
431 {
432 NTSTATUS Status;
433 ULONG FgColor, BgColor, Attribute, XPos, YPos, TextHeight, TextWidth;
434 BOOLEAN Visible;
435
436 Status = STATUS_SUCCESS;
437
438 if (Mask & 1)
439 {
440 FgColor = State->FgColor;
441
442 if (TextConsole->State.FgColor != FgColor)
443 {
444 if (FgColor >= 16)
445 {
446 return STATUS_INVALID_PARAMETER;
447 }
448
449 Attribute = ConsoleEfiTextGetAttribute(TextConsole->State.BgColor, FgColor);
450 Status = EfiConOutSetAttribute(TextConsole->Protocol, Attribute);
451
452
453 if (!NT_SUCCESS(Status))
454 {
455 return Status;
456 }
457
458 TextConsole->State.FgColor = FgColor;
459 }
460 }
461
462 if (Mask & 2)
463 {
464 BgColor = State->BgColor;
465 if (TextConsole->State.BgColor != BgColor)
466 {
467 if (BgColor >= 16)
468 {
469 return STATUS_INVALID_PARAMETER;
470 }
471
472 Attribute = ConsoleEfiTextGetAttribute(BgColor, TextConsole->State.FgColor);
473 Status = EfiConOutSetAttribute(TextConsole->Protocol, Attribute);
474
475 if (!NT_SUCCESS(Status))
476 {
477 return Status;
478 }
479
480 TextConsole->State.BgColor = BgColor;
481 }
482 }
483
484 if (Mask & 4)
485 {
486 XPos = State->XPos;
487 YPos = State->YPos;
488
489 if ((TextConsole->State.XPos != XPos) || (TextConsole->State.YPos != YPos))
490 {
491 BlDisplayGetTextCellResolution(&TextWidth, &TextHeight);
492 Status = EfiConOutSetCursorPosition(TextConsole->Protocol,
493 XPos/ TextWidth,
494 YPos / TextHeight);
495
496 if (!NT_SUCCESS(Status))
497 {
498 return Status;
499 }
500
501 TextConsole->State.XPos = XPos;
502 TextConsole->State.YPos = YPos;
503 }
504 }
505
506 if (Mask & 8)
507 {
508 Visible = State->CursorVisible;
509 if (TextConsole->State.CursorVisible != Visible)
510 {
511 if (Visible >= 3)
512 {
513 return STATUS_INVALID_PARAMETER;
514 }
515
516 Status = EfiConOutEnableCursor(TextConsole->Protocol, Visible);
517 if (!NT_SUCCESS(Status))
518 {
519 return Status;
520 }
521
522 TextConsole->State.CursorVisible = Visible;
523 }
524 }
525
526 return Status;
527 }
528
529 NTSTATUS
530 ConsoleEfiTextFindModeFromAllowed (
531 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextProtocol,
532 _In_ PBL_DISPLAY_MODE SupportedModes,
533 _In_ ULONG MaxIndex,
534 _Out_ PULONG SupportedMode
535 )
536 {
537 EFI_SIMPLE_TEXT_OUTPUT_MODE ModeInfo;
538 ULONG MaxMode, MaxQueriedMode, Mode, i, MatchingMode;
539 UINTN HRes, VRes;
540 ULONGLONG ModeListSize;
541 PBL_DISPLAY_MODE ModeEntry, ModeList, SupportedModeEntry;
542 NTSTATUS Status;
543
544 /* Read information on the current mode */
545 EfiConOutReadCurrentMode(TextProtocol, &ModeInfo);
546
547 /* Figure out the max mode, and how many modes we'll have to read */
548 MaxMode = ModeInfo.MaxMode;
549 ModeListSize = sizeof(*ModeEntry) * ModeInfo.MaxMode;
550 if (ModeListSize > MAXULONG)
551 {
552 return STATUS_INTEGER_OVERFLOW;
553 }
554
555 /* Allocate a list for all the supported EFI modes */
556 ModeList = BlMmAllocateHeap(ModeListSize);
557 if (!ModeList)
558 {
559 return STATUS_INSUFFICIENT_RESOURCES;
560 }
561
562 /* Scan all the EFI modes */
563 for (MaxQueriedMode = 0, Mode = 0; Mode < MaxMode; Mode++)
564 {
565 /* Query information on this mode */
566 ModeEntry = &ModeList[MaxQueriedMode];
567 if (NT_SUCCESS(EfiConOutQueryMode(TextProtocol,
568 Mode,
569 &HRes,
570 &VRes)))
571 {
572 /* This mode was succesfully queried. Save the data */
573 ModeEntry->HRes = HRes;
574 ModeEntry->VRes = VRes;
575 ModeEntry->HRes2 = HRes;
576 MaxQueriedMode = Mode;
577 }
578 }
579
580 /* Loop all the supported mode entries */
581 for (i = 0; i < MaxIndex; i++)
582 {
583 /* Loop all the UEFI queried modes */
584 SupportedModeEntry = &SupportedModes[i];
585 for (MatchingMode = 0; MatchingMode < MaxQueriedMode; MatchingMode)
586 {
587 /* Check if the UEFI mode is compatible with our supported mode */
588 ModeEntry = &ModeList[MatchingMode];
589 if ((ModeEntry->HRes == SupportedModeEntry->HRes) &&
590 (ModeEntry->VRes == SupportedModeEntry->VRes))
591 {
592 /* Yep -- free the mode list and return this mode */
593 BlMmFreeHeap(ModeList);
594 *SupportedMode = MatchingMode;
595 return STATUS_SUCCESS;
596 }
597 }
598 }
599
600 /* We can't do anything -- there are no matching modes */
601 Status = STATUS_UNSUCCESSFUL;
602 BlMmFreeHeap(ModeList);
603 return Status;
604 }
605
606 VOID
607 ConsoleFirmwareTextClose (
608 _In_ PBL_TEXT_CONSOLE TextConsole
609 )
610 {
611 ULONG Mode;
612 BL_DISPLAY_STATE DisplayState;
613
614 /* Read the original mode, and see if it's different than the one now */
615 Mode = TextConsole->OldMode.Mode;
616 if (Mode != TextConsole->Mode)
617 {
618 /* Restore to the original mode */
619 EfiConOutSetMode(TextConsole->Protocol, Mode);
620 }
621
622 /* Read the EFI settings for the original mode */
623 ConsoleEfiTextGetStateFromMode(&TextConsole->OldMode, &DisplayState);
624
625 /* Set the original settings */
626 ConsoleFirmwareTextSetState(TextConsole, 0xF, &DisplayState);
627 }
628
629 NTSTATUS
630 ConsoleFirmwareTextOpen (
631 _In_ PBL_TEXT_CONSOLE TextConsole
632 )
633 {
634 BL_DISPLAY_MODE DisplayMode;
635 EFI_SIMPLE_TEXT_OUTPUT_MODE CurrentMode, NewMode;
636 UINTN HRes, VRes;
637 ULONG Mode;
638 NTSTATUS Status;
639
640 /* Read the current mode and its settings */
641 EfiConOutReadCurrentMode(EfiConOut, &CurrentMode);
642 Status = EfiConOutQueryMode(EfiConOut, CurrentMode.Mode, &HRes, &VRes);
643 if (!NT_SUCCESS(Status))
644 {
645 return Status;
646 }
647
648 /* Save the current mode and its settings */
649 NewMode = CurrentMode;
650 DisplayMode.VRes = VRes;
651 DisplayMode.HRes = HRes;
652 DisplayMode.HRes2 = HRes;
653
654 /* Check if the current mode is compatible with one of our modes */
655 if (!ConsolepFindResolution(&DisplayMode, ConsoleTextResolutionList, 1))
656 {
657 /* It isn't -- find a matching EFI mode for what we need */
658 Status = ConsoleEfiTextFindModeFromAllowed(EfiConOut,
659 ConsoleTextResolutionList,
660 1,
661 &Mode);
662 if (!NT_SUCCESS(Status))
663 {
664 return Status;
665 }
666
667 /* Set the new EFI mode */
668 Status = EfiConOutSetMode(EfiConOut, Mode);
669 if (!NT_SUCCESS(Status))
670 {
671 return Status;
672 }
673
674 /* Read the current mode and its settings */
675 EfiConOutReadCurrentMode(EfiConOut, &NewMode);
676 Status = EfiConOutQueryMode(EfiConOut, Mode, &HRes, &VRes);
677 if (!NT_SUCCESS(Status))
678 {
679 EfiConOutSetMode(EfiConOut, CurrentMode.Mode);
680 return Status;
681 }
682
683 /* Save the current mode and its settings */
684 DisplayMode.HRes = HRes;
685 DisplayMode.VRes = VRes;
686 DisplayMode.HRes2 = HRes;
687 }
688
689 /* Capture all the current settings */
690 ConsoleEfiTextGetStateFromMode(&NewMode, &TextConsole->State);
691 TextConsole->Mode = NewMode.Mode;
692 TextConsole->DisplayMode = DisplayMode;
693 TextConsole->Protocol = EfiConOut;
694 TextConsole->OldMode = CurrentMode;
695 return STATUS_SUCCESS;
696 }
697
698 NTSTATUS
699 ConsoleTextLocalDestruct (
700 _In_ struct _BL_TEXT_CONSOLE* Console
701 )
702 {
703 return STATUS_NOT_IMPLEMENTED;
704 }
705
706 NTSTATUS
707 ConsoleTextLocalReinitialize (
708 _In_ struct _BL_TEXT_CONSOLE* Console
709 )
710 {
711 return STATUS_NOT_IMPLEMENTED;
712 }
713
714 NTSTATUS
715 ConsoleTextBaseGetTextState (
716 _In_ struct _BL_TEXT_CONSOLE* Console,
717 _Out_ PBL_DISPLAY_STATE TextState
718 )
719 {
720 return STATUS_NOT_IMPLEMENTED;
721 }
722
723 NTSTATUS
724 ConsoleTextLocalSetTextState (
725 _In_ struct _BL_TEXT_CONSOLE* Console,
726 _In_ ULONG Flags,
727 _In_ PBL_DISPLAY_STATE TextState
728 )
729 {
730 return STATUS_NOT_IMPLEMENTED;
731 }
732
733 NTSTATUS
734 ConsoleTextBaseGetTextResolution (
735 _In_ struct _BL_TEXT_CONSOLE* Console,
736 _Out_ PULONG TextResolution
737 )
738 {
739 return STATUS_NOT_IMPLEMENTED;
740 }
741
742 NTSTATUS
743 ConsoleTextLocalSetTextResolution (
744 _In_ struct _BL_TEXT_CONSOLE* Console,
745 _In_ ULONG NewTextResolution,
746 _Out_ PULONG OldTextResolution
747 )
748 {
749 return STATUS_NOT_IMPLEMENTED;
750 }
751
752 NTSTATUS
753 ConsoleTextLocalClearText (
754 _In_ struct _BL_TEXT_CONSOLE* Console,
755 _In_ ULONG Attribute
756 )
757 {
758 return STATUS_NOT_IMPLEMENTED;
759 }
760
761 NTSTATUS
762 ConsoleTextLocalWriteText (
763 _In_ struct _BL_TEXT_CONSOLE* Console,
764 _In_ PCHAR Text,
765 _In_ ULONG Attribute
766 )
767 {
768 return STATUS_NOT_IMPLEMENTED;
769 }
770
771 BOOLEAN
772 DsppGraphicsDisabledByBcd (
773 VOID
774 )
775 {
776 EarlyPrint(L"Disabling graphics\n");
777 return TRUE;
778 }
779
780 NTSTATUS
781 ConsoleTextLocalConstruct (
782 _In_ PBL_TEXT_CONSOLE TextConsole,
783 _In_ BOOLEAN Activate
784 )
785 {
786 NTSTATUS Status;
787 BL_DISPLAY_STATE TextState;
788
789 /* Set our callbacks */
790 TextConsole->Callbacks = &ConsoleTextLocalVtbl;
791
792 /* Are we activating this console? */
793 if (Activate)
794 {
795 /* Call firmware to activate it */
796 Status = ConsoleFirmwareTextOpen(TextConsole);
797 if (!NT_SUCCESS(Status))
798 {
799 return Status;
800 }
801 }
802
803 /* Set default text state */
804 TextState.BgColor = 0;
805 TextState.XPos = 0;
806 TextState.YPos = 0;
807 TextState.CursorVisible = FALSE;
808 TextState.FgColor = White;
809
810 /* Are we activating? */
811 if (Activate)
812 {
813 /* Call firmware to set it */
814 Status = ConsoleFirmwareTextSetState(TextConsole, 0xF, &TextState);
815 if (!NT_SUCCESS(Status))
816 {
817 /* We failed, back down */
818 ConsoleFirmwareTextClose(TextConsole);
819 return Status;
820 }
821 }
822 else
823 {
824 /* Just save the state for now, someone else can activate later */
825 TextConsole->State = TextState;
826 }
827
828 /* Remember if we activated it */
829 TextConsole->Active = Activate;
830 return STATUS_SUCCESS;
831 }
832
833 NTSTATUS
834 DsppInitialize (
835 _In_ ULONG Flags
836 )
837 {
838 BL_LIBRARY_PARAMETERS LibraryParameters = BlpLibraryParameters;
839 BOOLEAN NoGraphics;// , HighestMode;
840 NTSTATUS Status;
841 PBL_DISPLAY_MODE DisplayMode;
842 //ULONG GraphicsResolution;
843 PVOID GraphicsConsole;
844 // PVOID RemoteConsole;
845 PBL_TEXT_CONSOLE TextConsole;
846
847 /* Initialize font data */
848 BfiCachedStrikeData = 0;
849 InitializeListHead(&BfiDeferredListHead);
850 InitializeListHead(&BfiFontFileListHead);
851
852 /* Allocate the font rectangle */
853 BfiGraphicsRectangle = BlMmAllocateHeap(0x5A);
854 if (!BfiGraphicsRectangle)
855 {
856 return STATUS_NO_MEMORY;
857 }
858
859 /* Display re-initialization not yet handled */
860 if (LibraryParameters.LibraryFlags & BL_LIBRARY_FLAG_REINITIALIZE_ALL)
861 {
862 EarlyPrint(L"Display path not handled\n");
863 return STATUS_NOT_SUPPORTED;
864 }
865
866 /* Check if no graphics console is needed */
867 if ((Flags & BL_LIBRARY_FLAG_NO_GRAPHICS_CONSOLE) ||
868 (DsppGraphicsDisabledByBcd()))
869 {
870 /* Remember this */
871 NoGraphics = TRUE;
872 }
873 else
874 {
875 /* No graphics -- remember this */
876 NoGraphics = FALSE;
877 }
878
879 /* On first load, we always initialize a graphics display */
880 GraphicsConsole = NULL;
881 if (!(Flags & BL_LIBRARY_FLAG_REINITIALIZE_ALL) || !(NoGraphics))
882 {
883 /* Default to mode 0 (1024x768) */
884 DisplayMode = &ConsoleGraphicalResolutionList[0];
885
886 /* Check what resolution to use*/
887 #if 0
888 Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
889 BcdLibraryInteger_GraphicsResolution,
890 &GraphicsResolution);
891 #else
892 //GraphicsResolution = 0;
893 Status = STATUS_NOT_FOUND;
894 #endif
895 if (NT_SUCCESS(Status))
896 {
897 EarlyPrint(L"Display selection not yet handled\n");
898 return STATUS_NOT_IMPLEMENTED;
899 }
900
901 /* Check if the highest mode should be forced */
902 #if 0
903 Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
904 BcdLibraryBoolean_GraphicsForceHighestMode,
905 &HighestMode);
906 #else
907 //HighestMode = 0;
908 Status = STATUS_NOT_FOUND;
909 #endif
910 if (NT_SUCCESS(Status))
911 {
912 ConsoleGraphicalResolutionListFlags |= 2;
913 }
914
915 /* Do we need graphics mode after all? */
916 if (!NoGraphics)
917 {
918 EarlyPrint(L"Display path not handled\n");
919 return STATUS_NOT_SUPPORTED;
920 }
921
922 /* Are we using something else than the default mode? */
923 if (DisplayMode != &ConsoleGraphicalResolutionList[0])
924 {
925 EarlyPrint(L"Display path not handled\n");
926 return STATUS_NOT_SUPPORTED;
927 }
928
929 /* Mask out all the flags now */
930 ConsoleGraphicalResolutionListFlags &= ~3;
931 }
932
933 /* Do we have a graphics console? */
934 TextConsole = NULL;
935 if (!GraphicsConsole)
936 {
937 /* Nope -- go allocate a text console */
938 TextConsole = BlMmAllocateHeap(sizeof(*TextConsole));
939 if (TextConsole)
940 {
941 /* Construct it */
942 Status = ConsoleTextLocalConstruct(TextConsole, TRUE);
943 if (!NT_SUCCESS(Status))
944 {
945 BlMmFreeHeap(TextConsole);
946 TextConsole = NULL;
947 }
948 }
949 }
950
951 /* Initialize all globals to NULL */
952 DspRemoteInputConsole = NULL;
953 DspTextConsole = NULL;
954 DspGraphicalConsole = NULL;
955
956 /* If we don't have a text console, go get a remote console */
957 //RemoteConsole = NULL;
958 if (!TextConsole)
959 {
960 EarlyPrint(L"Display path not handled\n");
961 return STATUS_NOT_SUPPORTED;
962 }
963
964 /* Do we have a remote console? */
965 if (!DspRemoteInputConsole)
966 {
967 /* Nope -- what about a graphical one? */
968 if (GraphicsConsole)
969 {
970 /* Yes, use it for both graphics and text */
971 DspGraphicalConsole = GraphicsConsole;
972 DspTextConsole = GraphicsConsole;
973 }
974 else if (TextConsole)
975 {
976 /* Nope, but we have a text console */
977 DspTextConsole = TextConsole;
978 }
979
980 /* Console has been setup */
981 return STATUS_SUCCESS;
982 }
983
984 /* We have a remote console -- have to figure out how to use it*/
985 EarlyPrint(L"Display path not handled\n");
986 return STATUS_NOT_SUPPORTED;
987 }
988
989 NTSTATUS
990 BlpDisplayInitialize (
991 _In_ ULONG Flags
992 )
993 {
994 NTSTATUS Status;
995
996 /* Are we resetting or initializing? */
997 if (Flags & BL_LIBRARY_FLAG_REINITIALIZE)
998 {
999 /* This is a reset */
1000 Status = STATUS_NOT_IMPLEMENTED;
1001 #if 0
1002 Status = DsppReinitialize(Flags);
1003 if (NT_SUCCESS(Status))
1004 {
1005 Status = BlpDisplayReinitialize();
1006 }
1007 #endif
1008 }
1009 else
1010 {
1011 /* Initialize the display */
1012 Status = DsppInitialize(Flags);
1013 }
1014
1015 /* Return display initailziation state */
1016 return Status;
1017 }
1018
1019 VOID
1020 BlDisplayGetTextCellResolution (
1021 _Out_ PULONG TextWidth,
1022 _Out_ PULONG TextHeight
1023 )
1024 {
1025 NTSTATUS Status;
1026
1027 /* If the caller doesn't want anything, bail out */
1028 if (!(TextWidth) || !(TextHeight))
1029 {
1030 return;
1031 }
1032
1033 /* Do we have a text console? */
1034 Status = STATUS_UNSUCCESSFUL;
1035 if (DspTextConsole)
1036 {
1037 /* Do we have a graphics console? */
1038 if (DspGraphicalConsole)
1039 {
1040 /* Yep -- query it */
1041 EarlyPrint(L"Not supported\n");
1042 Status = STATUS_NOT_IMPLEMENTED;
1043 }
1044 }
1045
1046 /* Check if we failed to get it from the graphics console */
1047 if (!NT_SUCCESS(Status))
1048 {
1049 /* Set default text size */
1050 *TextWidth = 8;
1051 *TextHeight = 8;
1052 }
1053 }