https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dc2eb409c1d838733abcf…
commit dc2eb409c1d838733abcfcb22bbaa90dda434795
Author: Yaroslav Kibysh <yanet.prod(a)gmail.com>
AuthorDate: Tue Jun 11 22:27:25 2019 +0300
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Jul 14 22:23:50 2019 +0200
[NTOS:INBV] Implement BitBltPalette() and BitBltAligned() and use them for aligning
bitmaps. (#1649)
Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
---
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 <debug.h>
#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);