[BOOTMGFW]
[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, 25, 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 /* Yep -- we got a match */
237 return TRUE;
238
239 }
240
241 /* Try another one*/
242 List++;
243 }
244
245 /* No matches were found */
246 return FALSE;
247 }
248
249 BL_COLOR
250 ConsoleEfiTextGetColorForeground (
251 _In_ UINT32 Attributes
252 )
253 {
254 /* Read the foreground color attribute and convert to CGA color index */
255 switch (Attributes & 0x0F)
256 {
257 case EFI_BLACK:
258 return Black;
259 case EFI_BLUE:
260 return Blue;
261 case EFI_GREEN:
262 return Green;
263 case EFI_RED:
264 return Red;
265 case EFI_CYAN:
266 return Cyan;
267 case EFI_MAGENTA:
268 return Magenta;
269 case EFI_BROWN:
270 return Brown;
271 case EFI_LIGHTGRAY:
272 return LtGray;
273 case EFI_DARKGRAY:
274 return Gray;
275 case EFI_LIGHTBLUE:
276 return LtBlue;
277 case EFI_LIGHTGREEN:
278 return LtGreen;
279 case EFI_LIGHTCYAN:
280 return LtCyan;
281 case EFI_LIGHTRED:
282 return LtRed;
283 case EFI_LIGHTMAGENTA:
284 return LtMagenta;
285 case EFI_YELLOW:
286 return Yellow;
287 case EFI_WHITE:
288 default:
289 return White;
290 }
291 }
292
293 BL_COLOR
294 ConsoleEfiTextGetColorBackground (
295 _In_ UINT32 Attributes
296 )
297 {
298 /* Read the background color attribute and convert to CGA color index */
299 switch (Attributes & 0xF0)
300 {
301 case EFI_BACKGROUND_MAGENTA:
302 return Magenta;
303 case EFI_BACKGROUND_BROWN:
304 return Brown;
305 case EFI_BACKGROUND_LIGHTGRAY:
306 return White;
307 case EFI_BACKGROUND_BLACK:
308 default:
309 return Black;
310 case EFI_BACKGROUND_RED:
311 return Red;
312 case EFI_BACKGROUND_GREEN:
313 return Green;
314 case EFI_BACKGROUND_CYAN:
315 return Cyan;
316 case EFI_BACKGROUND_BLUE:
317 return Blue;
318 }
319 }
320
321 ULONG
322 ConsoleEfiTextGetEfiColorBackground (
323 _In_ BL_COLOR Color
324 )
325 {
326 /* Convert the CGA color index into an EFI background attribute */
327 switch (Color)
328 {
329 case Blue:
330 case LtBlue:
331 return EFI_BACKGROUND_BLUE;
332 case Green:
333 case LtGreen:
334 return EFI_BACKGROUND_GREEN;
335 case Cyan:
336 case LtCyan:
337 return EFI_BACKGROUND_CYAN;
338 case Red:
339 case LtRed:
340 return EFI_BACKGROUND_RED;
341 case Magenta:
342 case LtMagenta:
343 return EFI_BACKGROUND_MAGENTA;
344 case Brown:
345 case Yellow:
346 return EFI_BACKGROUND_BROWN;
347 case LtGray:
348 case White:
349 return EFI_BACKGROUND_LIGHTGRAY;
350 case Black:
351 case Gray:
352 default:
353 return EFI_BACKGROUND_BLACK;
354 }
355 }
356
357 ULONG
358 ConsoleEfiTextGetEfiColorForeground (
359 _In_ BL_COLOR Color
360 )
361 {
362 /* Convert the CGA color index into an EFI foreground attribute */
363 switch (Color)
364 {
365 case Black:
366 return EFI_BLACK;
367 case Blue:
368 return EFI_BLUE;
369 case Green:
370 return EFI_GREEN;
371 case Cyan:
372 return EFI_CYAN;
373 case Red:
374 return EFI_RED;
375 case Magenta:
376 return EFI_MAGENTA;
377 case Brown:
378 return EFI_BROWN;
379 case LtGray:
380 return EFI_LIGHTGRAY;
381 case Gray:
382 return EFI_DARKGRAY;
383 case LtBlue:
384 return EFI_LIGHTBLUE;
385 case LtGreen:
386 return EFI_LIGHTGREEN;
387 case LtCyan:
388 return EFI_LIGHTCYAN;
389 case LtRed:
390 return EFI_LIGHTRED;
391 case LtMagenta:
392 return EFI_LIGHTMAGENTA;
393 case Yellow:
394 return EFI_YELLOW;
395 case White:
396 default:
397 return EFI_WHITE;
398 }
399 }
400
401 ULONG
402 ConsoleEfiTextGetAttribute (
403 BL_COLOR BgColor,
404 BL_COLOR FgColor
405 )
406 {
407 /* Convert each part and OR into a single attribute */
408 return ConsoleEfiTextGetEfiColorBackground(BgColor) |
409 ConsoleEfiTextGetEfiColorForeground(FgColor);
410 }
411
412 VOID
413 ConsoleEfiTextGetStateFromMode (
414 _In_ EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode,
415 _Out_ PBL_DISPLAY_STATE State
416 )
417 {
418
419 ULONG TextWidth, TextHeight;
420
421 /* Get all the EFI data and convert it into our own structure */
422 BlDisplayGetTextCellResolution(&TextWidth, &TextHeight);
423 State->FgColor = ConsoleEfiTextGetColorForeground(Mode->Attribute);
424 State->BgColor = ConsoleEfiTextGetColorBackground(Mode->Attribute);
425 State->XPos = Mode->CursorColumn * TextWidth;
426 State->YPos = Mode->CursorRow * TextHeight;
427 State->CursorVisible = Mode->CursorVisible != FALSE;
428 }
429
430 NTSTATUS
431 ConsoleFirmwareTextSetState (
432 _In_ PBL_TEXT_CONSOLE TextConsole,
433 _In_ UCHAR Mask,
434 _In_ PBL_DISPLAY_STATE State
435 )
436 {
437 NTSTATUS Status;
438 ULONG FgColor, BgColor, Attribute, XPos, YPos, TextHeight, TextWidth;
439 BOOLEAN Visible;
440
441 /* Check if foreground state is being set */
442 if (Mask & 1)
443 {
444 /* Check if there's a difference from current */
445 FgColor = State->FgColor;
446 if (TextConsole->State.FgColor != FgColor)
447 {
448 /* Ignore invalid color */
449 if (FgColor > White)
450 {
451 return STATUS_INVALID_PARAMETER;
452 }
453
454 /* Convert from NT/CGA format to EFI, and then set the attribute */
455 Attribute = ConsoleEfiTextGetAttribute(TextConsole->State.BgColor,
456 FgColor);
457 Status = EfiConOutSetAttribute(TextConsole->Protocol, Attribute);
458 if (!NT_SUCCESS(Status))
459 {
460 return Status;
461 }
462
463 /* Update cached state */
464 TextConsole->State.FgColor = FgColor;
465 }
466 }
467
468 /* Check if background state is being set */
469 if (Mask & 2)
470 {
471 /* Check if there's a difference from current */
472 BgColor = State->BgColor;
473 if (TextConsole->State.BgColor != BgColor)
474 {
475 /* Ignore invalid color */
476 if (BgColor > White)
477 {
478 return STATUS_INVALID_PARAMETER;
479 }
480
481 /* Convert from NT/CGA format to EFI, and then set the attribute */
482 Attribute = ConsoleEfiTextGetAttribute(BgColor,
483 TextConsole->State.FgColor);
484 Status = EfiConOutSetAttribute(TextConsole->Protocol, Attribute);
485
486 if (!NT_SUCCESS(Status))
487 {
488 return Status;
489 }
490
491 /* Update cached state */
492 TextConsole->State.BgColor = BgColor;
493 }
494 }
495
496 /* Check if position state is being set */
497 if (Mask & 4)
498 {
499 /* Check if there's a difference from current */
500 XPos = State->XPos;
501 YPos = State->YPos;
502 if ((TextConsole->State.XPos != XPos) ||
503 (TextConsole->State.YPos != YPos))
504 {
505 /* Set the new cursor position */
506 BlDisplayGetTextCellResolution(&TextWidth, &TextHeight);
507 Status = EfiConOutSetCursorPosition(TextConsole->Protocol,
508 XPos/ TextWidth,
509 YPos / TextHeight);
510 if (!NT_SUCCESS(Status))
511 {
512 return Status;
513 }
514
515 /* Update cached state */
516 TextConsole->State.XPos = XPos;
517 TextConsole->State.YPos = YPos;
518 }
519 }
520
521 /* Check if cursor state is being set */
522 if (Mask & 8)
523 {
524 /* Check if there's a difference from current */
525 Visible = State->CursorVisible;
526 if (TextConsole->State.CursorVisible != Visible)
527 {
528 /* Ignore invalid state */
529 if (Visible >= 3)
530 {
531 return STATUS_INVALID_PARAMETER;
532 }
533
534 /* Set the new cursor state */
535 Status = EfiConOutEnableCursor(TextConsole->Protocol, Visible);
536 if (!NT_SUCCESS(Status))
537 {
538 return Status;
539 }
540
541 /* Update cached status */
542 TextConsole->State.CursorVisible = Visible;
543 }
544 }
545
546 /* Return success */
547 return STATUS_SUCCESS;
548 }
549
550 NTSTATUS
551 ConsoleEfiTextFindModeFromAllowed (
552 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextProtocol,
553 _In_ PBL_DISPLAY_MODE SupportedModes,
554 _In_ ULONG MaxIndex,
555 _Out_ PULONG SupportedMode
556 )
557 {
558 EFI_SIMPLE_TEXT_OUTPUT_MODE ModeInfo;
559 ULONG MaxMode, MaxQueriedMode, Mode, i, MatchingMode;
560 UINTN HRes, VRes;
561 ULONGLONG ModeListSize;
562 PBL_DISPLAY_MODE ModeEntry, ModeList, SupportedModeEntry;
563 NTSTATUS Status;
564
565 /* Read information on the current mode */
566 EfiConOutReadCurrentMode(TextProtocol, &ModeInfo);
567
568 /* Figure out the max mode, and how many modes we'll have to read */
569 MaxMode = ModeInfo.MaxMode;
570 ModeListSize = sizeof(*ModeEntry) * ModeInfo.MaxMode;
571 if (ModeListSize > MAXULONG)
572 {
573 return STATUS_INTEGER_OVERFLOW;
574 }
575
576 /* Allocate a list for all the supported EFI modes */
577 ModeList = BlMmAllocateHeap(ModeListSize);
578 if (!ModeList)
579 {
580 return STATUS_INSUFFICIENT_RESOURCES;
581 }
582
583 /* Scan all the EFI modes */
584 EarlyPrint(L"Scanning through %d modes\n", MaxMode);
585 for (MaxQueriedMode = 0, Mode = 0; Mode < MaxMode; Mode++)
586 {
587 /* Query information on this mode */
588 ModeEntry = &ModeList[MaxQueriedMode];
589 if (NT_SUCCESS(EfiConOutQueryMode(TextProtocol,
590 Mode,
591 &HRes,
592 &VRes)))
593 {
594 /* This mode was succesfully queried. Save the data */
595 EarlyPrint(L"EFI Firmware Supported Mode %d is H: %d V: %d\n", Mode, HRes, VRes);
596 ModeEntry->HRes = HRes;
597 ModeEntry->VRes = VRes;
598 ModeEntry->HRes2 = HRes;
599 MaxQueriedMode = Mode + 1;
600 }
601 }
602
603 /* Loop all the supported mode entries */
604 for (i = 0; i < MaxIndex; i++)
605 {
606 /* Loop all the UEFI queried modes */
607 SupportedModeEntry = &SupportedModes[i];
608 for (MatchingMode = 0; MatchingMode < MaxQueriedMode; MatchingMode++)
609 {
610 /* Check if the UEFI mode is compatible with our supported mode */
611 ModeEntry = &ModeList[MatchingMode];
612 EarlyPrint(L"H1: %d V1: %d - H2: %d - V2: %d\n", ModeEntry->HRes, ModeEntry->VRes, SupportedModeEntry->HRes, SupportedModeEntry->VRes);
613 if ((ModeEntry->HRes == SupportedModeEntry->HRes) &&
614 (ModeEntry->VRes == SupportedModeEntry->VRes))
615 {
616 /* Yep -- free the mode list and return this mode */
617 BlMmFreeHeap(ModeList);
618 *SupportedMode = MatchingMode;
619 return STATUS_SUCCESS;
620 }
621 }
622 }
623
624 /* We can't do anything -- there are no matching modes */
625 Status = STATUS_UNSUCCESSFUL;
626 BlMmFreeHeap(ModeList);
627 return Status;
628 }
629
630 VOID
631 ConsoleFirmwareTextClose (
632 _In_ PBL_TEXT_CONSOLE TextConsole
633 )
634 {
635 ULONG Mode;
636 BL_DISPLAY_STATE DisplayState;
637
638 /* Read the original mode, and see if it's different than the one now */
639 Mode = TextConsole->OldMode.Mode;
640 if (Mode != TextConsole->Mode)
641 {
642 /* Restore to the original mode */
643 EfiConOutSetMode(TextConsole->Protocol, Mode);
644 }
645
646 /* Read the EFI settings for the original mode */
647 ConsoleEfiTextGetStateFromMode(&TextConsole->OldMode, &DisplayState);
648
649 /* Set the original settings */
650 ConsoleFirmwareTextSetState(TextConsole, 0xF, &DisplayState);
651 }
652
653 NTSTATUS
654 ConsoleFirmwareTextOpen (
655 _In_ PBL_TEXT_CONSOLE TextConsole
656 )
657 {
658 BL_DISPLAY_MODE DisplayMode;
659 EFI_SIMPLE_TEXT_OUTPUT_MODE CurrentMode, NewMode;
660 UINTN HRes, VRes;
661 ULONG Mode;
662 NTSTATUS Status;
663
664 /* Read the current mode and its settings */
665 EfiConOutReadCurrentMode(EfiConOut, &CurrentMode);
666 Status = EfiConOutQueryMode(EfiConOut, CurrentMode.Mode, &HRes, &VRes);
667 if (!NT_SUCCESS(Status))
668 {
669 return Status;
670 }
671
672 /* Save the current mode and its settings */
673 NewMode = CurrentMode;
674 DisplayMode.VRes = VRes;
675 DisplayMode.HRes = HRes;
676 DisplayMode.HRes2 = HRes;
677
678 /* Check if the current mode is compatible with one of our modes */
679 if (!ConsolepFindResolution(&DisplayMode, ConsoleTextResolutionList, 1))
680 {
681 /* It isn't -- find a matching EFI mode for what we need */
682 EarlyPrint(L"In incorrect mode, scanning for right one\n");
683 Status = ConsoleEfiTextFindModeFromAllowed(EfiConOut,
684 ConsoleTextResolutionList,
685 1,
686 &Mode);
687 if (!NT_SUCCESS(Status))
688 {
689 EarlyPrint(L"Failed to find mode: %lx\n", Status);
690 return Status;
691 }
692
693 /* Set the new EFI mode */
694 EarlyPrint(L"Setting new mode: %d\n", Mode);
695 Status = EfiConOutSetMode(EfiConOut, Mode);
696 if (!NT_SUCCESS(Status))
697 {
698 return Status;
699 }
700
701 /* Read the current mode and its settings */
702 EfiConOutReadCurrentMode(EfiConOut, &NewMode);
703 Status = EfiConOutQueryMode(EfiConOut, Mode, &HRes, &VRes);
704 if (!NT_SUCCESS(Status))
705 {
706 EfiConOutSetMode(EfiConOut, CurrentMode.Mode);
707 return Status;
708 }
709
710 /* Save the current mode and its settings */
711 DisplayMode.HRes = HRes;
712 DisplayMode.VRes = VRes;
713 DisplayMode.HRes2 = HRes;
714 }
715
716 /* Capture all the current settings */
717 ConsoleEfiTextGetStateFromMode(&NewMode, &TextConsole->State);
718 TextConsole->Mode = NewMode.Mode;
719 TextConsole->DisplayMode = DisplayMode;
720 TextConsole->Protocol = EfiConOut;
721 TextConsole->OldMode = CurrentMode;
722 return STATUS_SUCCESS;
723 }
724
725 NTSTATUS
726 ConsoleTextLocalDestruct (
727 _In_ struct _BL_TEXT_CONSOLE* Console
728 )
729 {
730 return STATUS_NOT_IMPLEMENTED;
731 }
732
733 NTSTATUS
734 ConsoleTextLocalReinitialize (
735 _In_ struct _BL_TEXT_CONSOLE* Console
736 )
737 {
738 return STATUS_NOT_IMPLEMENTED;
739 }
740
741 NTSTATUS
742 ConsoleTextBaseGetTextState (
743 _In_ struct _BL_TEXT_CONSOLE* Console,
744 _Out_ PBL_DISPLAY_STATE TextState
745 )
746 {
747 return STATUS_NOT_IMPLEMENTED;
748 }
749
750 NTSTATUS
751 ConsoleTextLocalSetTextState (
752 _In_ struct _BL_TEXT_CONSOLE* Console,
753 _In_ ULONG Flags,
754 _In_ PBL_DISPLAY_STATE TextState
755 )
756 {
757 return STATUS_NOT_IMPLEMENTED;
758 }
759
760 NTSTATUS
761 ConsoleTextBaseGetTextResolution (
762 _In_ struct _BL_TEXT_CONSOLE* Console,
763 _Out_ PULONG TextResolution
764 )
765 {
766 return STATUS_NOT_IMPLEMENTED;
767 }
768
769 NTSTATUS
770 ConsoleTextLocalSetTextResolution (
771 _In_ struct _BL_TEXT_CONSOLE* Console,
772 _In_ ULONG NewTextResolution,
773 _Out_ PULONG OldTextResolution
774 )
775 {
776 return STATUS_NOT_IMPLEMENTED;
777 }
778
779 NTSTATUS
780 ConsoleTextLocalClearText (
781 _In_ struct _BL_TEXT_CONSOLE* Console,
782 _In_ ULONG Attribute
783 )
784 {
785 return STATUS_NOT_IMPLEMENTED;
786 }
787
788 NTSTATUS
789 ConsoleTextLocalWriteText (
790 _In_ struct _BL_TEXT_CONSOLE* Console,
791 _In_ PCHAR Text,
792 _In_ ULONG Attribute
793 )
794 {
795 return STATUS_NOT_IMPLEMENTED;
796 }
797
798 BOOLEAN
799 DsppGraphicsDisabledByBcd (
800 VOID
801 )
802 {
803 //EarlyPrint(L"Disabling graphics\n");
804 return TRUE;
805 }
806
807 NTSTATUS
808 ConsoleTextLocalConstruct (
809 _In_ PBL_TEXT_CONSOLE TextConsole,
810 _In_ BOOLEAN Activate
811 )
812 {
813 NTSTATUS Status;
814 BL_DISPLAY_STATE TextState;
815
816 /* Set our callbacks */
817 TextConsole->Callbacks = &ConsoleTextLocalVtbl;
818
819 /* Are we activating this console? */
820 if (Activate)
821 {
822 /* Call firmware to activate it */
823 Status = ConsoleFirmwareTextOpen(TextConsole);
824 if (!NT_SUCCESS(Status))
825 {
826 EarlyPrint(L"Failed to activate console: %lx\n", Status);
827 return Status;
828 }
829 }
830
831 /* Set default text state */
832 TextState.BgColor = 0;
833 TextState.XPos = 0;
834 TextState.YPos = 0;
835 TextState.CursorVisible = FALSE;
836 TextState.FgColor = White;
837
838 /* Are we activating? */
839 if (Activate)
840 {
841 /* Call firmware to set it */
842 Status = ConsoleFirmwareTextSetState(TextConsole, 0xF, &TextState);
843 if (!NT_SUCCESS(Status))
844 {
845 /* We failed, back down */
846 EarlyPrint(L"Failed to set console state: %lx\n", Status);
847 ConsoleFirmwareTextClose(TextConsole);
848 return Status;
849 }
850 }
851 else
852 {
853 /* Just save the state for now, someone else can activate later */
854 TextConsole->State = TextState;
855 }
856
857 /* Remember if we activated it */
858 TextConsole->Active = Activate;
859 return STATUS_SUCCESS;
860 }
861
862 NTSTATUS
863 DsppInitialize (
864 _In_ ULONG Flags
865 )
866 {
867 BL_LIBRARY_PARAMETERS LibraryParameters = BlpLibraryParameters;
868 BOOLEAN NoGraphics;// , HighestMode;
869 NTSTATUS Status;
870 PBL_DISPLAY_MODE DisplayMode;
871 //ULONG GraphicsResolution;
872 PVOID GraphicsConsole;
873 // PVOID RemoteConsole;
874 PBL_TEXT_CONSOLE TextConsole;
875
876 /* Initialize font data */
877 BfiCachedStrikeData = 0;
878 InitializeListHead(&BfiDeferredListHead);
879 InitializeListHead(&BfiFontFileListHead);
880
881 /* Allocate the font rectangle */
882 // BfiGraphicsRectangle = BlMmAllocateHeap(0x5A);
883 //if (!BfiGraphicsRectangle)
884 //{
885 //return STATUS_NO_MEMORY;
886 //}
887
888 /* Display re-initialization not yet handled */
889 if (LibraryParameters.LibraryFlags & BL_LIBRARY_FLAG_REINITIALIZE_ALL)
890 {
891 EarlyPrint(L"Display path not handled\n");
892 return STATUS_NOT_SUPPORTED;
893 }
894
895 /* Check if no graphics console is needed */
896 if ((Flags & BL_LIBRARY_FLAG_NO_GRAPHICS_CONSOLE) ||
897 (DsppGraphicsDisabledByBcd()))
898 {
899 /* Remember this */
900 NoGraphics = TRUE;
901 }
902 else
903 {
904 /* No graphics -- remember this */
905 NoGraphics = FALSE;
906 }
907
908 /* On first load, we always initialize a graphics display */
909 GraphicsConsole = NULL;
910 if (!(Flags & BL_LIBRARY_FLAG_REINITIALIZE_ALL) || !(NoGraphics))
911 {
912 /* Default to mode 0 (1024x768) */
913 DisplayMode = &ConsoleGraphicalResolutionList[0];
914
915 /* Check what resolution to use*/
916 #if 0
917 Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
918 BcdLibraryInteger_GraphicsResolution,
919 &GraphicsResolution);
920 #else
921 //GraphicsResolution = 0;
922 Status = STATUS_NOT_FOUND;
923 #endif
924 if (NT_SUCCESS(Status))
925 {
926 EarlyPrint(L"Display selection not yet handled\n");
927 return STATUS_NOT_IMPLEMENTED;
928 }
929
930 /* Check if the highest mode should be forced */
931 #if 0
932 Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
933 BcdLibraryBoolean_GraphicsForceHighestMode,
934 &HighestMode);
935 #else
936 //HighestMode = 0;
937 Status = STATUS_NOT_FOUND;
938 #endif
939 if (NT_SUCCESS(Status))
940 {
941 ConsoleGraphicalResolutionListFlags |= 2;
942 }
943
944 /* Do we need graphics mode after all? */
945 if (!NoGraphics)
946 {
947 EarlyPrint(L"Display path not handled\n");
948 return STATUS_NOT_SUPPORTED;
949 }
950
951 /* Are we using something else than the default mode? */
952 if (DisplayMode != &ConsoleGraphicalResolutionList[0])
953 {
954 EarlyPrint(L"Display path not handled\n");
955 return STATUS_NOT_SUPPORTED;
956 }
957
958 /* Mask out all the flags now */
959 ConsoleGraphicalResolutionListFlags &= ~3;
960 }
961
962 /* Do we have a graphics console? */
963 TextConsole = NULL;
964 if (!GraphicsConsole)
965 {
966 /* Nope -- go allocate a text console */
967 TextConsole = BlMmAllocateHeap(sizeof(*TextConsole));
968 if (TextConsole)
969 {
970 /* Construct it */
971 Status = ConsoleTextLocalConstruct(TextConsole, TRUE);
972 if (!NT_SUCCESS(Status))
973 {
974 BlMmFreeHeap(TextConsole);
975 TextConsole = NULL;
976 }
977 }
978 }
979
980 /* Initialize all globals to NULL */
981 DspRemoteInputConsole = NULL;
982 DspTextConsole = NULL;
983 DspGraphicalConsole = NULL;
984
985 /* If we don't have a text console, go get a remote console */
986 //RemoteConsole = NULL;
987 if (!TextConsole)
988 {
989 EarlyPrint(L"Display path not handled\n");
990 return STATUS_NOT_SUPPORTED;
991 }
992
993 /* Do we have a remote console? */
994 if (!DspRemoteInputConsole)
995 {
996 /* Nope -- what about a graphical one? */
997 if (GraphicsConsole)
998 {
999 /* Yes, use it for both graphics and text */
1000 DspGraphicalConsole = GraphicsConsole;
1001 DspTextConsole = GraphicsConsole;
1002 }
1003 else if (TextConsole)
1004 {
1005 /* Nope, but we have a text console */
1006 DspTextConsole = TextConsole;
1007 }
1008
1009 /* Console has been setup */
1010 return STATUS_SUCCESS;
1011 }
1012
1013 /* We have a remote console -- have to figure out how to use it*/
1014 EarlyPrint(L"Display path not handled\n");
1015 return STATUS_NOT_SUPPORTED;
1016 }
1017
1018 NTSTATUS
1019 BlpDisplayInitialize (
1020 _In_ ULONG Flags
1021 )
1022 {
1023 NTSTATUS Status;
1024
1025 /* Are we resetting or initializing? */
1026 if (Flags & BL_LIBRARY_FLAG_REINITIALIZE)
1027 {
1028 /* This is a reset */
1029 Status = STATUS_NOT_IMPLEMENTED;
1030 #if 0
1031 Status = DsppReinitialize(Flags);
1032 if (NT_SUCCESS(Status))
1033 {
1034 Status = BlpDisplayReinitialize();
1035 }
1036 #endif
1037 }
1038 else
1039 {
1040 /* Initialize the display */
1041 Status = DsppInitialize(Flags);
1042 }
1043
1044 /* Return display initailziation state */
1045 return Status;
1046 }
1047
1048 VOID
1049 BlDisplayGetTextCellResolution (
1050 _Out_ PULONG TextWidth,
1051 _Out_ PULONG TextHeight
1052 )
1053 {
1054 NTSTATUS Status;
1055
1056 /* If the caller doesn't want anything, bail out */
1057 if (!(TextWidth) || !(TextHeight))
1058 {
1059 return;
1060 }
1061
1062 /* Do we have a text console? */
1063 Status = STATUS_UNSUCCESSFUL;
1064 if (DspTextConsole)
1065 {
1066 /* Do we have a graphics console? */
1067 if (DspGraphicalConsole)
1068 {
1069 /* Yep -- query it */
1070 EarlyPrint(L"Not supported\n");
1071 Status = STATUS_NOT_IMPLEMENTED;
1072 }
1073 }
1074
1075 /* Check if we failed to get it from the graphics console */
1076 if (!NT_SUCCESS(Status))
1077 {
1078 /* Set default text size */
1079 *TextWidth = 8;
1080 *TextHeight = 8;
1081 }
1082 }