[NTOS:INBV] Implement BitBltPalette() and BitBltAligned() and use them for aligning...
authorYaroslav Kibysh <yanet.prod@gmail.com>
Tue, 11 Jun 2019 19:27:25 +0000 (22:27 +0300)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 14 Jul 2019 20:23:50 +0000 (22:23 +0200)
Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
ntoskrnl/inbv/inbv.c

index 295ffac..d0d382e 100644 (file)
@@ -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
  */
 // #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);