From dc2eb409c1d838733abcfcb22bbaa90dda434795 Mon Sep 17 00:00:00 2001 From: Yaroslav Kibysh Date: Tue, 11 Jun 2019 22:27:25 +0300 Subject: [PATCH] [NTOS:INBV] Implement BitBltPalette() and BitBltAligned() and use them for aligning bitmaps. (#1649) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Co-authored-by: Hermès Bélusca-Maïto --- ntoskrnl/inbv/inbv.c | 170 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 153 insertions(+), 17 deletions(-) diff --git a/ntoskrnl/inbv/inbv.c b/ntoskrnl/inbv/inbv.c index 295ffac0142..d0d382e8e68 100644 --- a/ntoskrnl/inbv/inbv.c +++ b/ntoskrnl/inbv/inbv.c @@ -5,6 +5,10 @@ #include #include "bootvid/bootvid.h" +/* See also mm/ARM3/miarm.h */ +#define MM_READONLY 1 // PAGE_READONLY +#define MM_READWRITE 4 // PAGE_WRITECOPY + #ifndef TAG_OSTR #define TAG_OSTR 'RTSO' #endif @@ -28,6 +32,29 @@ */ // #define REACTOS_SKUS +/* + * Screen resolution (for default VGA) + */ +#define SCREEN_WIDTH 640 +#define SCREEN_HEIGHT 480 + +/* + * BitBltAligned() alignments + */ +typedef enum _BBLT_VERT_ALIGNMENT +{ + AL_VERTICAL_TOP = 0, + AL_VERTICAL_CENTER, + AL_VERTICAL_BOTTOM +} BBLT_VERT_ALIGNMENT; + +typedef enum _BBLT_HORZ_ALIGNMENT +{ + AL_HORIZONTAL_LEFT = 0, + AL_HORIZONTAL_CENTER, + AL_HORIZONTAL_RIGHT +} BBLT_HORZ_ALIGNMENT; + /* * Enable this define when Inbv will support rotating progress bar. */ @@ -210,6 +237,96 @@ BootLogoFadeIn(VOID) } } +static VOID +BitBltPalette( + IN PVOID Image, + IN BOOLEAN NoPalette, + IN ULONG X, + IN ULONG Y) +{ + LPRGBQUAD Palette; + RGBQUAD OrigPalette[RTL_NUMBER_OF(MainPalette)]; + + /* If requested, remove the palette from the image */ + if (NoPalette) + { + /* Get bitmap header and palette */ + PBITMAPINFOHEADER BitmapInfoHeader = Image; + Palette = (LPRGBQUAD)((PUCHAR)Image + BitmapInfoHeader->biSize); + + /* Save the image original palette and remove palette information */ + RtlCopyMemory(OrigPalette, Palette, sizeof(OrigPalette)); + RtlZeroMemory(Palette, sizeof(OrigPalette)); + } + + /* Draw the image */ + InbvBitBlt(Image, X, Y); + + /* Restore the image original palette */ + if (NoPalette) + { + RtlCopyMemory(Palette, OrigPalette, sizeof(OrigPalette)); + } +} + +static VOID +BitBltAligned( + IN PVOID Image, + IN BOOLEAN NoPalette, + IN BBLT_HORZ_ALIGNMENT HorizontalAlignment, + IN BBLT_VERT_ALIGNMENT VerticalAlignment, + IN ULONG MarginLeft, + IN ULONG MarginTop, + IN ULONG MarginRight, + IN ULONG MarginBottom) +{ + PBITMAPINFOHEADER BitmapInfoHeader = Image; + ULONG X, Y; + + /* Calculate X */ + switch (HorizontalAlignment) + { + case AL_HORIZONTAL_LEFT: + X = MarginLeft - MarginRight; + break; + + case AL_HORIZONTAL_CENTER: + X = MarginLeft - MarginRight + (SCREEN_WIDTH - BitmapInfoHeader->biWidth + 1) / 2; + break; + + case AL_HORIZONTAL_RIGHT: + X = MarginLeft - MarginRight + SCREEN_WIDTH - BitmapInfoHeader->biWidth; + break; + + default: + /* Unknown */ + return; + } + + /* Calculate Y */ + switch (VerticalAlignment) + { + case AL_VERTICAL_TOP: + Y = MarginTop - MarginBottom; + break; + + case AL_VERTICAL_CENTER: + Y = MarginTop - MarginBottom + (SCREEN_HEIGHT - BitmapInfoHeader->biHeight + 1) / 2; + break; + + case AL_VERTICAL_BOTTOM: + Y = MarginTop - MarginBottom + SCREEN_HEIGHT - BitmapInfoHeader->biHeight; + break; + + default: + /* Unknown */ + return; + } + + /* Finally draw the image */ + BitBltPalette(Image, NoPalette, X, Y); +} + /* FUNCTIONS *****************************************************************/ INIT_FUNCTION @@ -975,6 +1092,12 @@ DisplayBootBitmap(IN BOOLEAN TextMode) /* Check if this is text mode */ if (TextMode) { + /* + * Make the kernel resource section temporarily writable, + * as we are going to change the bitmaps' palette in place. + */ + MmChangeKernelResourceSectionProtection(MM_READWRITE); + /* Check the type of the OS: workstation or server */ if (SharedUserData->NtProductType == NtProductWinNt) { @@ -1006,15 +1129,32 @@ DisplayBootBitmap(IN BOOLEAN TextMode) if (Header && Footer) { /* BitBlt them on the screen */ - InbvBitBlt(Footer, 0, 419); - InbvBitBlt(Header, 0, 0); + BitBltAligned(Footer, + TRUE, + AL_HORIZONTAL_CENTER, + AL_VERTICAL_BOTTOM, + 0, 0, 0, 59); + BitBltAligned(Header, + FALSE, + AL_HORIZONTAL_CENTER, + AL_VERTICAL_TOP, + 0, 0, 0, 0); } + + /* Restore the kernel resource section protection to be read-only */ + MmChangeKernelResourceSectionProtection(MM_READONLY); } else { /* Is the boot driver installed? */ if (!InbvBootDriverInstalled) return; + /* + * Make the kernel resource section temporarily writable, + * as we are going to change the bitmaps' palette in place. + */ + MmChangeKernelResourceSectionProtection(MM_READWRITE); + /* Load the standard boot screen */ Screen = InbvGetResourceAddress(IDB_BOOT_SCREEN); @@ -1059,20 +1199,13 @@ DisplayBootBitmap(IN BOOLEAN TextMode) /* Make sure we have a logo */ if (Screen) { - PBITMAPINFOHEADER BitmapInfoHeader; - LPRGBQUAD Palette; - - /* - * Save the main image palette and replace it with black palette, - * so that we can do fade-in effect later. - */ - BitmapInfoHeader = (PBITMAPINFOHEADER)Screen; - Palette = (LPRGBQUAD)((PUCHAR)Screen + BitmapInfoHeader->biSize); + /* Save the main image palette for implementing the fade-in effect */ + PBITMAPINFOHEADER BitmapInfoHeader = Screen; + LPRGBQUAD Palette = (LPRGBQUAD)((PUCHAR)Screen + BitmapInfoHeader->biSize); RtlCopyMemory(MainPalette, Palette, sizeof(MainPalette)); - RtlZeroMemory(Palette, sizeof(MainPalette)); /* Blit the background */ - InbvBitBlt(Screen, 0, 0); + BitBltPalette(Screen, TRUE, 0, 0); #ifdef INBV_ROTBAR_IMPLEMENTED /* Choose progress bar */ @@ -1099,7 +1232,7 @@ DisplayBootBitmap(IN BOOLEAN TextMode) #ifdef REACTOS_SKUS /* Draw the SKU text if it exits */ - if (Text) InbvBitBlt(Text, 180, 121); + if (Text) BitBltPalette(Text, TRUE, 180, 121); #endif #ifdef INBV_ROTBAR_IMPLEMENTED @@ -1126,7 +1259,7 @@ DisplayBootBitmap(IN BOOLEAN TextMode) if (LineBmp) { /* Draw the line and store it in global buffer */ - InbvBitBlt(LineBmp, 0, 474); + BitBltPalette(LineBmp, TRUE, 0, 474); InbvScreenToBufferBlt(RotLineBuffer, 0, 474, 640, 6, 640); } } @@ -1137,6 +1270,9 @@ DisplayBootBitmap(IN BOOLEAN TextMode) } #endif + /* Restore the kernel resource section protection to be read-only */ + MmChangeKernelResourceSectionProtection(MM_READONLY); + /* Display the boot logo and fade it in */ BootLogoFadeIn(); @@ -1194,10 +1330,10 @@ DisplayFilter(PCHAR *String) static BOOLEAN DotHack = TRUE; /* If "." is given set *String to empty string */ - if(DotHack && strcmp(*String, ".") == 0) + if (DotHack && strcmp(*String, ".") == 0) *String = ""; - if(**String) + if (**String) { /* Remove the filter */ InbvInstallDisplayStringFilter(NULL); -- 2.17.1