reactos/boot/environ/lib/io/display/guicons.c
Hermès Bélusca-Maïto 9393fc320e
[FORMATTING] Remove trailing whitespace. Addendum to 34593d93.
Excluded: 3rd-party code (incl. wine) and most of the win32ss.
2021-09-13 03:52:22 +02:00

463 lines
11 KiB
C

/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/io/display/guicons.c
* PURPOSE: Boot Library GUI Console Routines
* PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
BL_GRAPHICS_CONSOLE_VTABLE ConsoleGraphicalVtbl =
{
{
(PCONSOLE_DESTRUCT)ConsoleGraphicalDestruct,
(PCONSOLE_REINITIALIZE)ConsoleGraphicalReinitialize,
ConsoleTextBaseGetTextState,
(PCONSOLE_SET_TEXT_STATE)ConsoleGraphicalSetTextState,
NULL, // GetTextResolution
NULL, // SetTextResolution
(PCONSOLE_CLEAR_TEXT)ConsoleGraphicalClearText
},
ConsoleGraphicalIsEnabled,
ConsoleGraphicalEnable,
NULL,
ConsoleGraphicalGetGraphicalResolution,
ConsoleGraphicalGetOriginalResolution,
NULL,
};
/* FUNCTIONS *****************************************************************/
NTSTATUS
ConsoleGraphicalSetTextState (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ ULONG Mask,
_In_ PBL_DISPLAY_STATE TextState
)
{
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* Let it handle that */
return ConsoleFirmwareTextSetState(&Console->TextConsole,
Mask,
TextState);
}
/* Not yet */
EfiPrintf(L"FFX set not implemented\r\n");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
ConsoleGraphicalConstruct (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
NTSTATUS Status;
/* Create a text console */
Status = ConsoleTextLocalConstruct(&GraphicsConsole->TextConsole, FALSE);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"Text failed: %lx\r\n", Status);
return Status;
}
/* But overwrite its callbacks with ours */
GraphicsConsole->TextConsole.Callbacks = &ConsoleGraphicalVtbl.Text;
/* Try to create a GOP console */
Status = ConsoleEfiGraphicalOpenProtocol(GraphicsConsole, BlGopConsole);
if (!NT_SUCCESS(Status))
{
/* That failed, try an older EFI 1.02 UGA console */
EfiPrintf(L"GOP open failed!\r\n", Status);
Status = ConsoleEfiGraphicalOpenProtocol(GraphicsConsole, BlUgaConsole);
if (!NT_SUCCESS(Status))
{
/* That failed too, give up */
EfiPrintf(L"UGA failed!\r\n", Status);
ConsoleTextLocalDestruct(&GraphicsConsole->TextConsole);
return STATUS_UNSUCCESSFUL;
}
}
/* Enable the console */
Status = ConsoleFirmwareGraphicalEnable(GraphicsConsole);
if (!NT_SUCCESS(Status))
{
/* Failed to enable it, undo everything */
EfiPrintf(L"Enable failed\r\n");
ConsoleFirmwareGraphicalClose(GraphicsConsole);
ConsoleTextLocalDestruct(&GraphicsConsole->TextConsole);
return STATUS_UNSUCCESSFUL;
}
/* Save the graphics text color from the text mode text color */
GraphicsConsole->FgColor = GraphicsConsole->TextConsole.State.FgColor;
GraphicsConsole->BgColor = GraphicsConsole->TextConsole.State.BgColor;
return STATUS_SUCCESS;
}
VOID
ConsolepClearBuffer (
_In_ PUCHAR FrameBuffer,
_In_ ULONG Width,
_In_ PUCHAR FillColor,
_In_ ULONG Height,
_In_ ULONG ScanlineWidth,
_In_ ULONG PixelDepth
)
{
PUCHAR Scanline, Current, FrameBufferEnd, LineEnd;
ULONG LineBytes, WidthBytes, BytesPerPixel;
/* Get the BPP */
BytesPerPixel = PixelDepth / 8;
/* Using that, calculate the size of a scan line */
LineBytes = ScanlineWidth * BytesPerPixel;
/* And the size of line we'll have to clear */
WidthBytes = Width * BytesPerPixel;
/* Allocate a scanline */
Scanline = BlMmAllocateHeap(WidthBytes);
if (Scanline)
{
/* For each remaining pixel on the scanline */
Current = Scanline;
while (Width--)
{
/* Copy in the fill color */
RtlCopyMemory(Current, FillColor, BytesPerPixel);
Current += BytesPerPixel;
}
/* For each scanline in the frame buffer */
while (Height--)
{
/* Copy our constructed scanline */
RtlCopyMemory(FrameBuffer, Scanline, WidthBytes);
FrameBuffer += LineBytes;
}
}
else
{
FrameBufferEnd = FrameBuffer + Height * LineBytes;
ScanlineWidth = BytesPerPixel * (ScanlineWidth - Width);
while (FrameBuffer != FrameBufferEnd)
{
if (FrameBuffer != (FrameBuffer + WidthBytes))
{
LineEnd = FrameBuffer + WidthBytes;
do
{
RtlCopyMemory(FrameBuffer, FillColor, BytesPerPixel);
FrameBuffer += BytesPerPixel;
}
while (FrameBuffer != LineEnd);
}
FrameBuffer += ScanlineWidth;
}
}
}
NTSTATUS
ConsolepConvertColorToPixel (
_In_ BL_COLOR Color,
_Out_ PUCHAR Pixel
)
{
NTSTATUS Status;
/* Assume success */
Status = STATUS_SUCCESS;
/* Convert the color to a pixel value */
switch (Color)
{
case Black:
Pixel[1] = 0;
Pixel[2] = 0;
Pixel[0] = 0;
break;
case Blue:
Pixel[1] = 0;
Pixel[2] = 0;
Pixel[0] = 0x7F;
break;
case Green:
Pixel[1] = 0x7F;
Pixel[2] = 0;
Pixel[0] = 0;
break;
case Cyan:
Pixel[1] = 0x7F;
Pixel[2] = 0;
Pixel[0] = 0x7F;
break;
case Red:
Pixel[1] = 0;
Pixel[2] = 0x7F;
Pixel[0] = 0x7F;
break;
case Magenta:
Pixel[1] = 0;
Pixel[2] = 0x7F;
Pixel[0] = 0x7F;
break;
case Brown:
Pixel[1] = 0x3F;
Pixel[2] = 0x7F;
Pixel[0] = 0;
break;
case LtGray:
Pixel[1] = 0xBFu;
Pixel[2] = 0xBFu;
*Pixel = 0xBFu;
break;
case Gray:
Pixel[1] = 0x7F;
Pixel[2] = 0x7F;
Pixel[0] = 0x7F;
break;
case LtBlue:
Pixel[1] = 0;
Pixel[2] = 0;
Pixel[0] = 0xFF;
break;
case LtGreen:
Pixel[1] = 0xFF;
Pixel[2] = 0;
Pixel[0] = 0;
break;
case LtCyan:
Pixel[1] = 0xFF;
Pixel[2] = 0;
Pixel[0] = 0xFF;
break;
case LtRed:
Pixel[1] = 0;
Pixel[2] = 0xFF;
Pixel[0] = 0;
break;
case LtMagenta:
Pixel[1] = 0;
Pixel[2] = 0xFF;
Pixel[0] = 0xFF;
break;
case Yellow:
Pixel[1] = 0xFF;
Pixel[2] = 0xFF;
Pixel[0] = 0;
break;
case White:
Pixel[1] = 0xFF;
Pixel[2] = 0xFF;
Pixel[0] = 0xFF;
break;
default:
Status = STATUS_INVALID_PARAMETER;
break;
}
return Status;
}
NTSTATUS
ConsoleGraphicalClearPixels (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ ULONG Color
)
{
NTSTATUS Status;
/* Check if the text console is active */
if (Console->TextConsole.Active)
{
/* We shouldn't be here */
Status = STATUS_UNSUCCESSFUL;
}
else
{
/* Clear it in graphics mode */
Status = ConsoleFirmwareGraphicalClear(Console, Color);
}
/* All good */
return Status;
}
NTSTATUS
ConsoleGraphicalClearText (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ BOOLEAN LineOnly
)
{
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* Let firmware clear do it */
return ConsoleFirmwareTextClear(&Console->TextConsole, LineOnly);
}
/* Are we clearing a line only? */
if (LineOnly)
{
return BfClearToEndOfLine(Console);
}
/* Nope -- the whole screen */
return BfClearScreen(Console);
}
BOOLEAN
ConsoleGraphicalIsEnabled (
_In_ PBL_GRAPHICS_CONSOLE Console
)
{
/* Is the text console active? If so, the graphics console isn't */
return !Console->TextConsole.Active;
}
VOID
ConsoleGraphicalDestruct (
_In_ PBL_GRAPHICS_CONSOLE Console
)
{
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* Disable it */
ConsoleFirmwareGraphicalDisable(Console);
}
/* Close the firmware protocols */
ConsoleFirmwareGraphicalClose(Console);
/* Destroy the console object */
ConsoleTextLocalDestruct(&Console->TextConsole);
}
NTSTATUS
ConsoleGraphicalReinitialize (
_In_ PBL_GRAPHICS_CONSOLE Console
)
{
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* Reinitialize it */
ConsoleTextLocalReinitialize(&Console->TextConsole);
}
/* Disable the graphics console */
ConsoleFirmwareGraphicalDisable(Console);
/* Then bring it back again */
return ConsoleFirmwareGraphicalEnable(Console);
}
NTSTATUS
ConsoleGraphicalEnable (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ BOOLEAN Enable
)
{
BOOLEAN Active;
NTSTATUS Status;
/* The text mode console state should be the opposite of what we want to do */
Active = Console->TextConsole.Active;
if (Active == Enable)
{
/* Are we trying to enable graphics? */
if (Enable)
{
/* Enable the console */
Status = ConsoleFirmwareGraphicalEnable(Console);
if (NT_SUCCESS(Status))
{
return Status;
}
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* Turn it off */
ConsoleFirmwareTextClose(&Console->TextConsole);
Console->TextConsole.Active = FALSE;
}
/* Preserve the text colors */
Console->FgColor = Console->TextConsole.State.FgColor;
Console->BgColor = Console->TextConsole.State.BgColor;
}
else
{
/* We are turning off graphics -- is the text console active? */
if (Active != TRUE)
{
/* It isn't, so let's turn it on */
Status = ConsoleFirmwareTextOpen(&Console->TextConsole);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Remember that it's on */
Console->TextConsole.Active = TRUE;
}
/* Disable the graphics console */
ConsoleFirmwareGraphicalDisable(Console);
}
}
/* All good */
return STATUS_SUCCESS;
}
NTSTATUS
ConsoleGraphicalGetGraphicalResolution (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ PBL_DISPLAY_MODE DisplayMode
)
{
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* There's no graphics resolution then */
return STATUS_UNSUCCESSFUL;
}
/* Return the current display mode */
*DisplayMode = Console->DisplayMode;
return STATUS_SUCCESS;
}
NTSTATUS
ConsoleGraphicalGetOriginalResolution (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ PBL_DISPLAY_MODE DisplayMode
)
{
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* There's no graphics resolution then */
return STATUS_UNSUCCESSFUL;
}
/* Return the current display mode */
*DisplayMode = Console->OldDisplayMode;
return STATUS_SUCCESS;
}