OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
TextOutputSystem.c
Go to the documentation of this file.
1
16
18#include <Protocol/GraphicsOutput.h>
19#include <Protocol/SimpleTextOut.h>
20
21#include <Library/BaseMemoryLib.h>
22#include <Library/BaseLib.h>
23#include <Library/DebugLib.h>
24#include <Library/MemoryAllocationLib.h>
26#include <Library/OcMiscLib.h>
27#include <Library/BaseOverflowLib.h>
28#include <Library/UefiBootServicesTableLib.h>
29
30//
31// Current reported console mode.
32//
33STATIC
36
37//
38// Disable text output in graphics mode.
39//
40STATIC
41BOOLEAN
43
44//
45// Clear screen when switching from graphics mode to text mode.
46//
47STATIC
48BOOLEAN
50
51//
52// Replace tab character with a space in output.
53//
54STATIC
55BOOLEAN
57
58//
59// Original text output function.
60//
61STATIC
62EFI_TEXT_STRING
64
65//
66// Original clear screen function.
67//
68STATIC
69EFI_TEXT_CLEAR_SCREEN
71
72//
73// Original console control protocol functions.
74//
75STATIC
78
79//
80// EFI background colours.
81//
82STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiBackgroundColors[8] = {
83 //
84 // B G R reserved
85 //
86 { 0x00, 0x00, 0x00, 0x00 }, // BLACK
87 { 0x98, 0x00, 0x00, 0x00 }, // LIGHTBLUE
88 { 0x00, 0x98, 0x00, 0x00 }, // LIGHGREEN
89 { 0x98, 0x98, 0x00, 0x00 }, // LIGHCYAN
90 { 0x00, 0x00, 0x98, 0x00 }, // LIGHRED
91 { 0x98, 0x00, 0x98, 0x00 }, // MAGENTA
92 { 0x00, 0x98, 0x98, 0x00 }, // BROWN
93 { 0x98, 0x98, 0x98, 0x00 }, // LIGHTGRAY
94};
95
96STATIC
97EFI_STATUS
98EFIAPI
100 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
101 IN CHAR16 *String
102 )
103{
104 UINTN Index;
105 UINTN Size;
106 CHAR16 *StringCopy;
107 EFI_STATUS Status;
108
111 Size = StrSize (String);
112
113 StringCopy = AllocatePool (Size);
114 if (StringCopy == NULL) {
115 return mOriginalOutputString (This, String);
116 }
117
118 Size /= sizeof (CHAR16);
119 for (Index = 0; Index < Size; Index++) {
120 if (String[Index] == L'\t') {
121 StringCopy[Index] = L' ';
122 } else {
123 StringCopy[Index] = String[Index];
124 }
125 }
126
127 Status = mOriginalOutputString (This, StringCopy);
128 FreePool (StringCopy);
129 return Status;
130 }
131
132 return mOriginalOutputString (This, String);
133 }
134
135 return EFI_UNSUPPORTED;
136}
137
138STATIC
139EFI_STATUS
140EFIAPI
142 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
143 )
144{
145 EFI_STATUS Status;
146 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
147 UINT32 Width;
148 UINT32 Height;
149 UINTN SizeOfInfo;
150 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
151
152 Status = OcHandleProtocolFallback (
153 gST->ConsoleOutHandle,
155 (VOID **)&GraphicsOutput
156 );
157
158 if (!EFI_ERROR (Status)) {
159 Status = GraphicsOutput->QueryMode (
160 GraphicsOutput,
161 GraphicsOutput->Mode->Mode,
162 &SizeOfInfo,
163 &Info
164 );
165 if (!EFI_ERROR (Status)) {
166 Width = Info->HorizontalResolution;
167 Height = Info->VerticalResolution;
168 FreePool (Info);
169 } else {
170 GraphicsOutput = NULL;
171 }
172 } else {
173 GraphicsOutput = NULL;
174 }
175
176 //
177 // On APTIO V with large resolution (e.g. 2K or 4K) ClearScreen
178 // invocation resets resolution to 1024x768. To avoid the glitches
179 // we clear the screen manually, doing with other methods results
180 // in screen flashes and other problems.
181 //
182
183 if (GraphicsOutput != NULL) {
184 Status = GraphicsOutput->Blt (
185 GraphicsOutput,
186 &mEfiBackgroundColors[BitFieldRead32 ((UINT32)This->Mode->Attribute, 4, 6)],
187 EfiBltVideoFill,
188 0,
189 0,
190 0,
191 0,
192 Width,
193 Height,
194 0
195 );
196
197 This->SetCursorPosition (This, 0, 0);
198 } else {
199 Status = mOriginalClearScreen (This);
200 }
201
202 return Status;
203}
204
205STATIC
206EFI_STATUS
207EFIAPI
211 OUT BOOLEAN *GopUgaExists OPTIONAL,
212 OUT BOOLEAN *StdInLocked OPTIONAL
213 )
214{
215 EFI_STATUS Status;
216
219 This,
220 Mode,
221 GopUgaExists,
222 StdInLocked
223 );
224
225 if (!EFI_ERROR (Status)) {
226 mConsoleMode = *Mode;
227 }
228
229 return Status;
230 }
231
232 *Mode = mConsoleMode;
233
234 if (GopUgaExists != NULL) {
235 *GopUgaExists = TRUE;
236 }
237
238 if (StdInLocked != NULL) {
239 *StdInLocked = FALSE;
240 }
241
242 return EFI_SUCCESS;
243}
244
245STATIC
246EFI_STATUS
247EFIAPI
251 )
252{
253 EFI_STATUS Status;
254 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
255
256 DEBUG ((DEBUG_INFO, "OCC: Setting cc mode %d -> %d\n", mConsoleMode, Mode));
257
258 mConsoleMode = Mode;
259
261 Status = OcHandleProtocolFallback (
262 gST->ConsoleOutHandle,
264 (VOID **)&GraphicsOutput
265 );
266
267 if (!EFI_ERROR (Status)) {
268 GraphicsOutput->Blt (
269 GraphicsOutput,
270 &mEfiBackgroundColors[BitFieldRead32 ((UINT32)gST->ConOut->Mode->Attribute, 4, 6)],
271 EfiBltVideoFill,
272 0,
273 0,
274 0,
275 0,
276 GraphicsOutput->Mode->Info->HorizontalResolution,
277 GraphicsOutput->Mode->Info->VerticalResolution,
278 0
279 );
280 }
281 }
282
285 This,
286 Mode
287 );
288 }
289
290 //
291 // Disable and hide flashing cursor when switching to graphics from text.
292 // This may be the case when we formerly handled text input or output.
293 //
295 gST->ConOut->EnableCursor (gST->ConOut, FALSE);
296 gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0);
297 }
298
299 return EFI_SUCCESS;
300}
301
302STATIC
303EFI_STATUS
304EFIAPI
307 IN CHAR16 *Password
308 )
309{
312 This,
313 Password
314 );
315 }
316
317 return EFI_DEVICE_ERROR;
318}
319
320STATIC
327
328EFI_STATUS
330 IN EFI_CONSOLE_CONTROL_SCREEN_MODE InitialMode,
331 IN OC_CONSOLE_RENDERER Renderer,
332 IN BOOLEAN IgnoreTextOutput,
333 IN BOOLEAN SanitiseClearScreen,
334 IN BOOLEAN ClearScreenOnModeSwitch,
335 IN BOOLEAN ReplaceTabWithSpace
336 )
337{
338 DEBUG ((
339 DEBUG_INFO,
340 "OCC: Configuring system console ignore %d san clear %d clear switch %d replace tab %d\n",
341 IgnoreTextOutput,
342 SanitiseClearScreen,
343 ClearScreenOnModeSwitch,
344 ReplaceTabWithSpace
345 ));
346
347 mConsoleMode = InitialMode;
348
349 if (Renderer == OcConsoleRendererSystemGraphics) {
352 } else if (Renderer == OcConsoleRendererSystemText) {
355 } else {
357 OcConsoleControlSetMode (InitialMode);
359 }
360
361 mIgnoreTextInGraphics = IgnoreTextOutput;
362 mClearScreenOnModeSwitch = ClearScreenOnModeSwitch;
363 mReplaceTabWithSpace = ReplaceTabWithSpace;
364
365 if (IgnoreTextOutput || ReplaceTabWithSpace) {
366 mOriginalOutputString = gST->ConOut->OutputString;
367 gST->ConOut->OutputString = ControlledOutputString;
368 }
369
370 if (SanitiseClearScreen) {
371 mOriginalClearScreen = gST->ConOut->ClearScreen;
372 gST->ConOut->ClearScreen = ControlledClearScreen;
373 }
374
375 return EFI_SUCCESS;
376}
EFI_STATUS OcConsoleControlInstallProtocol(IN EFI_CONSOLE_CONTROL_PROTOCOL *NewProtocol, OUT EFI_CONSOLE_CONTROL_PROTOCOL *OldProtocol OPTIONAL, IN OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *OldMode OPTIONAL)
EFI_CONSOLE_CONTROL_SCREEN_MODE
@ EfiConsoleControlScreenGraphics
@ EfiConsoleControlScreenText
DMG_SIZE_DEVICE_PATH Size
EFI_SYSTEM_TABLE * gST
EFI_CONSOLE_CONTROL_SCREEN_MODE OcConsoleControlSetMode(IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode)
OC_CONSOLE_RENDERER
@ OcConsoleRendererSystemGraphics
@ OcConsoleRendererSystemGeneric
@ OcConsoleRendererSystemText
EFI_STATUS OcHandleProtocolFallback(IN EFI_HANDLE Handle, IN EFI_GUID *Protocol, OUT VOID **Interface)
EFI_STATUS OcUseSystemTextOutput(IN EFI_CONSOLE_CONTROL_SCREEN_MODE InitialMode, IN OC_CONSOLE_RENDERER Renderer, IN BOOLEAN IgnoreTextOutput, IN BOOLEAN SanitiseClearScreen, IN BOOLEAN ClearScreenOnModeSwitch, IN BOOLEAN ReplaceTabWithSpace)
STATIC EFI_STATUS EFIAPI ConsoleControlSetMode(IN EFI_CONSOLE_CONTROL_PROTOCOL *This, IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode)
STATIC EFI_STATUS EFIAPI ControlledOutputString(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *String)
STATIC EFI_TEXT_STRING mOriginalOutputString
STATIC EFI_CONSOLE_CONTROL_SCREEN_MODE mConsoleMode
STATIC BOOLEAN mIgnoreTextInGraphics
STATIC BOOLEAN mReplaceTabWithSpace
STATIC EFI_STATUS EFIAPI ControlledClearScreen(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This)
STATIC EFI_STATUS EFIAPI ConsoleControlLockStdIn(IN EFI_CONSOLE_CONTROL_PROTOCOL *This, IN CHAR16 *Password)
STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiBackgroundColors[8]
STATIC BOOLEAN mClearScreenOnModeSwitch
STATIC EFI_CONSOLE_CONTROL_PROTOCOL mOriginalConsoleControlProtocol
STATIC EFI_CONSOLE_CONTROL_PROTOCOL mConsoleControlProtocol
STATIC EFI_TEXT_CLEAR_SCREEN mOriginalClearScreen
STATIC EFI_STATUS EFIAPI ConsoleControlGetMode(IN EFI_CONSOLE_CONTROL_PROTOCOL *This, OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode, OUT BOOLEAN *GopUgaExists OPTIONAL, OUT BOOLEAN *StdInLocked OPTIONAL)
EFI_GUID gEfiGraphicsOutputProtocolGuid
#define ASSERT(x)
Definition coder.h:55
EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn
EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE GetMode
EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE SetMode