Add scroll region support and refactor framebuffer handling

This commit is contained in:
Aiken Harris 2025-09-03 15:06:25 +02:00
parent 9f5daafad9
commit 227da47bfc
Signed by: harraiken
GPG Key ID: C40F06CB7493C1F5
5 changed files with 321 additions and 56 deletions

View File

@ -366,8 +366,8 @@ typedef struct _CPPORT
UCHAR Ring; UCHAR Ring;
} CPPORT, *PCPPORT; } CPPORT, *PCPPORT;
/* HAL framebuffer data structure */ /* Framebuffer data structure */
typedef struct _HAL_FRAMEBUFFER_DATA typedef struct _HL_FRAMEBUFFER_DATA
{ {
BOOLEAN Initialized; BOOLEAN Initialized;
PVOID Address; PVOID Address;
@ -375,7 +375,6 @@ typedef struct _HAL_FRAMEBUFFER_DATA
UINT Width; UINT Width;
UINT Height; UINT Height;
UINT PixelsPerScanLine; UINT PixelsPerScanLine;
UINT BitsPerPixel;
UINT BytesPerPixel; UINT BytesPerPixel;
UINT Pitch; UINT Pitch;
PVOID Font; PVOID Font;
@ -390,7 +389,22 @@ typedef struct _HAL_FRAMEBUFFER_DATA
USHORT ReservedShift; USHORT ReservedShift;
USHORT ReservedSize; USHORT ReservedSize;
} Pixels; } Pixels;
} HAL_FRAMEBUFFER_DATA, *PHAL_FRAMEBUFFER_DATA; } HL_FRAMEBUFFER_DATA, *PHL_FRAMEBUFFER_DATA;
/* Scroll region data structure */
typedef struct _HL_SCROLL_REGION_DATA
{
ULONG Left;
ULONG Top;
ULONG Right;
ULONG Bottom;
ULONG WidthInChars;
ULONG HeightInChars;
ULONG CursorX;
ULONG CursorY;
ULONG BackgroundColor;
ULONG TextColor;
} HL_SCROLL_REGION_DATA, *PHL_SCROLL_REGION_DATA;
/* Processor identity structure */ /* Processor identity structure */
typedef struct _PROCESSOR_IDENTITY typedef struct _PROCESSOR_IDENTITY

View File

@ -4,6 +4,7 @@
* FILE: xtoskrnl/hl/fbdev.c * FILE: xtoskrnl/hl/fbdev.c
* DESCRIPTION: FrameBuffer support * DESCRIPTION: FrameBuffer support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtos.h> #include <xtos.h>
@ -54,16 +55,84 @@ HlClearScreen(IN ULONG Color)
} }
/** /**
* Draw a pixel on the screen at the given position and color. * Displays a single character at the current cursor position inside the scroll region.
* *
* @param PositionX * @param Character
* Supplies the X coordinate of the pixel. * Supplies the character to be displayed.
* *
* @param PositionY * @return This routine does not return any value.
* Supplies the Y coordinate of the pixel.
* *
* @param Color * @since XT 1.0
* Specifies the color of the pixel in (A)RGB format. */
XTCDECL
XTSTATUS
HlDisplayCharacter(IN WCHAR Character)
{
PSSFN_FONT_HEADER FbFont;
/* Make sure frame buffer is already initialized */
if(HlpFrameBufferData.Initialized == FALSE)
{
/* Unable to operate on non-initialized frame buffer */
return STATUS_DEVICE_NOT_READY;
}
/* Get font information */
FbFont = (PSSFN_FONT_HEADER)HlpFrameBufferData.Font;
/* Handle special characters */
switch(Character)
{
case L'\n':
/* Move cursor to the beginning of the next line */
HlpScrollRegionData.CursorX = HlpScrollRegionData.Left;
HlpScrollRegionData.CursorY += FbFont->Height;
break;
case L'\t':
/* Move cursor to the next tab stop */
HlpScrollRegionData.CursorX += (8 - (HlpScrollRegionData.CursorX - HlpScrollRegionData.Left) / FbFont->Width % 8) * FbFont->Width;
if (HlpScrollRegionData.CursorX >= HlpScrollRegionData.Right)
{
HlpScrollRegionData.CursorX = HlpScrollRegionData.Left;
HlpScrollRegionData.CursorY += FbFont->Height;
}
break;
default:
/* Draw the character */
HlpDrawCharacter(HlpScrollRegionData.CursorX, HlpScrollRegionData.CursorY, HlpScrollRegionData.TextColor, Character);
/* Advance cursor */
HlpScrollRegionData.CursorX += FbFont->Width;
/* Check if cursor reached end of line */
if(HlpScrollRegionData.CursorX >= HlpScrollRegionData.Right)
{
HlpScrollRegionData.CursorX = HlpScrollRegionData.Left;
HlpScrollRegionData.CursorY += FbFont->Height;
}
break;
}
/* Check if cursor reached end of scroll region */
if(HlpScrollRegionData.CursorY >= HlpScrollRegionData.Bottom)
{
/* Scroll one line up */
HlpScrollRegion();
HlpScrollRegionData.CursorY = HlpScrollRegionData.Bottom - FbFont->Height;
}
/* Return success */
return STATUS_SUCCESS;
}
/**
* Returns the current resolution of the frame buffer display.
*
* @param Width
* A pointer to memory area where the screen width will be stored.
*
* @param Height
* A pointer to memory area where the screen height will be stored.
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
@ -71,32 +140,10 @@ HlClearScreen(IN ULONG Color)
*/ */
XTAPI XTAPI
VOID VOID
HlDrawPixel(IN ULONG PositionX, HlGetFrameBufferResolution(OUT PULONG Width, OUT PULONG Height)
IN ULONG PositionY,
IN ULONG Color)
{ {
PCHAR PixelAddress; *Width = HlpFrameBufferData.Width;
*Height = HlpFrameBufferData.Height;
/* Make sure frame buffer is already initialized */
if(HlpFrameBufferData.Initialized == FALSE)
{
/* Unable to operate on non-initialized frame buffer */
return;
}
/* Make sure point is not offscreen */
if(PositionX >= HlpFrameBufferData.Width || PositionY >= HlpFrameBufferData.Height || Color > 0xFFFFFFFF)
{
/* Invalid pixel position or color given */
return;
}
/* Calculate the address of the pixel in the frame buffer memory */
PixelAddress = (PCHAR)HlpFrameBufferData.Address + (PositionY * HlpFrameBufferData.Pitch) +
(PositionX * HlpFrameBufferData.BytesPerPixel);
/* Set the color of the pixel by writing to the corresponding memory location */
*((PULONG)PixelAddress) = HlpRGBColor(Color);
} }
/** /**
@ -155,7 +202,6 @@ HlInitializeFrameBuffer(VOID)
HlpFrameBufferData.Address = FrameBufferResource->Header.VirtualAddress; HlpFrameBufferData.Address = FrameBufferResource->Header.VirtualAddress;
HlpFrameBufferData.Width = FrameBufferResource->Width; HlpFrameBufferData.Width = FrameBufferResource->Width;
HlpFrameBufferData.Height = FrameBufferResource->Height; HlpFrameBufferData.Height = FrameBufferResource->Height;
HlpFrameBufferData.BitsPerPixel = FrameBufferResource->BitsPerPixel;
HlpFrameBufferData.BytesPerPixel = FrameBufferResource->BitsPerPixel / 8; HlpFrameBufferData.BytesPerPixel = FrameBufferResource->BitsPerPixel / 8;
HlpFrameBufferData.PixelsPerScanLine = FrameBufferResource->PixelsPerScanLine; HlpFrameBufferData.PixelsPerScanLine = FrameBufferResource->PixelsPerScanLine;
HlpFrameBufferData.Pitch = FrameBufferResource->Pitch; HlpFrameBufferData.Pitch = FrameBufferResource->Pitch;
@ -177,7 +223,81 @@ HlInitializeFrameBuffer(VOID)
} }
/** /**
* Puts a wide character on the framebuffer at the given position and color using the SSFN font. * Sets the scrollable region of the screen and calculates character dimensions.
*
* @param Left
* Supplies the left pixel coordinate of the scroll region.
*
* @param Top
* Supplies the top pixel coordinate of the scroll region.
*
* @param Right
* Supplies the right pixel coordinate of the scroll region.
*
* @param Bottom
* Supplies the bottom pixel coordinate of the scroll region.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HlInitializeScrollRegion(IN ULONG Left,
IN ULONG Top,
IN ULONG Right,
IN ULONG Bottom,
IN ULONG FontColor)
{
PSSFN_FONT_HEADER FbFont;
PCHAR PixelAddress;
/* Make sure frame buffer is already initialized */
if(HlpFrameBufferData.Initialized == FALSE)
{
/* Unable to operate on non-initialized frame buffer */
return;
}
/* Store pixel coordinates of the scroll region */
HlpScrollRegionData.Left = Left;
HlpScrollRegionData.Top = Top;
HlpScrollRegionData.Right = Right;
HlpScrollRegionData.Bottom = Bottom;
/* Get font information */
FbFont = (PSSFN_FONT_HEADER)HlpFrameBufferData.Font;
/* Validate font information */
if(FbFont && FbFont->Width > 0 && FbFont->Height > 0)
{
/* Calculate character dimensions */
HlpScrollRegionData.WidthInChars = (Right - Left) / FbFont->Width;
HlpScrollRegionData.HeightInChars = (Bottom - Top) / FbFont->Height;
/* Ensure the bottom of the scroll region is an exact multiple of the font height */
HlpScrollRegionData.Bottom = HlpScrollRegionData.Top + (HlpScrollRegionData.HeightInChars * FbFont->Height);
}
else
{
/* Fallback to 0 if font info is not available or invalid */
HlpScrollRegionData.WidthInChars = 0;
HlpScrollRegionData.HeightInChars = 0;
}
/* Initialize cursor position and font color */
HlpScrollRegionData.CursorX = HlpScrollRegionData.Left;
HlpScrollRegionData.CursorY = HlpScrollRegionData.Top;
HlpScrollRegionData.TextColor = FontColor;
/* Get the background color by reading the pixel at the top-left corner of the scroll region */
PixelAddress = (PCHAR)HlpFrameBufferData.Address + (Top * HlpFrameBufferData.Pitch) +
(Left * HlpFrameBufferData.BytesPerPixel);
HlpScrollRegionData.BackgroundColor = *((PULONG)PixelAddress);
}
/**
* Draws a character on the framebuffer at the given position and color using the SSFN font.
* *
* @param PositionX * @param PositionX
* Supplies the X coordinate of the character. * Supplies the X coordinate of the character.
@ -197,7 +317,7 @@ HlInitializeFrameBuffer(VOID)
*/ */
XTAPI XTAPI
VOID VOID
HlPutCharacter(IN ULONG PositionX, HlpDrawCharacter(IN ULONG PositionX,
IN ULONG PositionY, IN ULONG PositionY,
IN ULONG Color, IN ULONG Color,
IN WCHAR WideCharacter) IN WCHAR WideCharacter)
@ -339,6 +459,52 @@ HlPutCharacter(IN ULONG PositionX,
} }
} }
/**
* Draw a pixel on the screen at the given position and color.
*
* @param PositionX
* Supplies the X coordinate of the pixel.
*
* @param PositionY
* Supplies the Y coordinate of the pixel.
*
* @param Color
* Specifies the color of the pixel in (A)RGB format.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HlpDrawPixel(IN ULONG PositionX,
IN ULONG PositionY,
IN ULONG Color)
{
PCHAR PixelAddress;
/* Make sure frame buffer is already initialized */
if(HlpFrameBufferData.Initialized == FALSE)
{
/* Unable to operate on non-initialized frame buffer */
return;
}
/* Make sure point is not offscreen */
if(PositionX >= HlpFrameBufferData.Width || PositionY >= HlpFrameBufferData.Height || Color > 0xFFFFFFFF)
{
/* Invalid pixel position or color given */
return;
}
/* Calculate the address of the pixel in the frame buffer memory */
PixelAddress = (PCHAR)HlpFrameBufferData.Address + (PositionY * HlpFrameBufferData.Pitch) +
(PositionX * HlpFrameBufferData.BytesPerPixel);
/* Set the color of the pixel by writing to the corresponding memory location */
*((PULONG)PixelAddress) = HlpRGBColor(Color);
}
/** /**
* Converts color format from (A)RGB one expected by current FrameBuffer. * Converts color format from (A)RGB one expected by current FrameBuffer.
* *
@ -365,3 +531,62 @@ HlpRGBColor(IN ULONG Color)
return (ULONG)((Blue << HlpFrameBufferData.Pixels.BlueShift) | (Green << HlpFrameBufferData.Pixels.GreenShift) | return (ULONG)((Blue << HlpFrameBufferData.Pixels.BlueShift) | (Green << HlpFrameBufferData.Pixels.GreenShift) |
(Red << HlpFrameBufferData.Pixels.RedShift) | (Reserved << HlpFrameBufferData.Pixels.ReservedShift)); (Red << HlpFrameBufferData.Pixels.RedShift) | (Reserved << HlpFrameBufferData.Pixels.ReservedShift));
} }
/**
* Scrolls the content of the scroll region up by one line.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HlpScrollRegion(VOID)
{
PCHAR Destination, Source;
PSSFN_FONT_HEADER FbFont;
ULONG Line, PositionX;
ULONG LineBytes;
PULONG Pixel;
/* Make sure frame buffer is already initialized */
if(HlpFrameBufferData.Initialized == FALSE)
{
/* Unable to operate on non-initialized frame buffer */
return;
}
/* Get font information */
FbFont = (PSSFN_FONT_HEADER)HlpFrameBufferData.Font;
/* Calculate bytes per line in the scroll region */
LineBytes = (HlpScrollRegionData.Right - HlpScrollRegionData.Left) * HlpFrameBufferData.BytesPerPixel;
/* Scroll up each scan line in the scroll region */
for(Line = HlpScrollRegionData.Top; Line < HlpScrollRegionData.Bottom - FbFont->Height; Line++)
{
Destination = (PCHAR)HlpFrameBufferData.Address + Line * HlpFrameBufferData.Pitch +
HlpScrollRegionData.Left * HlpFrameBufferData.BytesPerPixel;
/* The source is one full text line (FbFont->Height) below the destination */
Source = (PCHAR)HlpFrameBufferData.Address + (Line + FbFont->Height) * HlpFrameBufferData.Pitch +
HlpScrollRegionData.Left * HlpFrameBufferData.BytesPerPixel;
/* Move each scan line in the scroll region up */
RtlMoveMemory(Destination, Source, LineBytes);
}
/* Clear the last text line */
for(Line = HlpScrollRegionData.Bottom - FbFont->Height; Line < HlpScrollRegionData.Bottom; Line++)
{
/* Get pointer to the start of the scan line to clear */
Pixel = (PULONG)((PCHAR)HlpFrameBufferData.Address + Line * HlpFrameBufferData.Pitch +
HlpScrollRegionData.Left * HlpFrameBufferData.BytesPerPixel);
/* Clear each pixel in the scan line with the background color */
for(PositionX = 0; PositionX < (HlpScrollRegionData.Right - HlpScrollRegionData.Left); PositionX++)
{
Pixel[PositionX] = HlpScrollRegionData.BackgroundColor;
}
}
}

View File

@ -25,7 +25,10 @@ KAFFINITY HlpActiveProcessors;
APIC_MODE HlpApicMode; APIC_MODE HlpApicMode;
/* FrameBuffer information */ /* FrameBuffer information */
HAL_FRAMEBUFFER_DATA HlpFrameBufferData; HL_FRAMEBUFFER_DATA HlpFrameBufferData;
/* Scroll region information */
HL_SCROLL_REGION_DATA HlpScrollRegionData;
/* System information */ /* System information */
ACPI_SYSTEM_INFO HlpSystemInfo; ACPI_SYSTEM_INFO HlpSystemInfo;

View File

@ -28,7 +28,10 @@ EXTERN KAFFINITY HlpActiveProcessors;
EXTERN APIC_MODE HlpApicMode; EXTERN APIC_MODE HlpApicMode;
/* FrameBuffer information */ /* FrameBuffer information */
EXTERN HAL_FRAMEBUFFER_DATA HlpFrameBufferData; EXTERN HL_FRAMEBUFFER_DATA HlpFrameBufferData;
/* Scroll region information */
EXTERN HL_SCROLL_REGION_DATA HlpScrollRegionData;
/* System information */ /* System information */
EXTERN ACPI_SYSTEM_INFO HlpSystemInfo; EXTERN ACPI_SYSTEM_INFO HlpSystemInfo;

View File

@ -34,11 +34,9 @@ UCHAR
HlComPortReadLsr(IN PCPPORT Port, HlComPortReadLsr(IN PCPPORT Port,
IN UCHAR Byte); IN UCHAR Byte);
XTAPI XTCDECL
VOID XTSTATUS
HlDrawPixel(IN ULONG PosX, HlDisplayCharacter(IN WCHAR Character);
IN ULONG PosY,
IN ULONG Color);
XTAPI XTAPI
XTSTATUS XTSTATUS
@ -49,6 +47,10 @@ XTSTATUS
HlGetAcpiTable(IN ULONG Signature, HlGetAcpiTable(IN ULONG Signature,
OUT PACPI_DESCRIPTION_HEADER *AcpiTable); OUT PACPI_DESCRIPTION_HEADER *AcpiTable);
XTAPI
VOID
HlGetFrameBufferResolution(OUT PULONG Width, OUT PULONG Height);
XTFASTCALL XTFASTCALL
KRUNLEVEL KRUNLEVEL
HlGetRunLevel(VOID); HlGetRunLevel(VOID);
@ -68,15 +70,16 @@ VOID
HlInitializeProcessor(VOID); HlInitializeProcessor(VOID);
XTAPI XTAPI
XTSTATUS VOID
HlInitializeSystem(VOID); HlInitializeScrollRegion(IN ULONG Left,
IN ULONG Top,
IN ULONG Right,
IN ULONG Bottom,
IN ULONG FontColor);
XTAPI XTAPI
VOID XTSTATUS
HlPutCharacter(IN ULONG PositionX, HlInitializeSystem(VOID);
IN ULONG PositionY,
IN ULONG Color,
IN WCHAR WideCharacter);
XTFASTCALL XTFASTCALL
VOID VOID
@ -86,6 +89,19 @@ XTAPI
VOID VOID
HlpCacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable); HlpCacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable);
XTAPI
VOID
HlpDrawCharacter(IN ULONG PositionX,
IN ULONG PositionY,
IN ULONG Color,
IN WCHAR WideCharacter);
XTAPI
VOID
HlpDrawPixel(IN ULONG PosX,
IN ULONG PosY,
IN ULONG Color);
XTAPI XTAPI
XTSTATUS XTSTATUS
HlpInitializeAcpi(VOID); HlpInitializeAcpi(VOID);
@ -124,6 +140,10 @@ XTAPI
ULONG ULONG
HlpRGBColor(IN ULONG Color); HlpRGBColor(IN ULONG Color);
XTAPI
VOID
HlpScrollRegion(VOID);
XTAPI XTAPI
BOOLEAN BOOLEAN
HlpValidateAcpiTable(IN PVOID Buffer, HlpValidateAcpiTable(IN PVOID Buffer,