https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dd71fb5ec868c03b08adc52cbfbe3c0cd2e57e86

commit dd71fb5ec868c03b08adc52cbfbe3c0cd2e57e86
Author: Stanislav Motylkov <[email protected]>
AuthorDate: Thu Dec 14 15:49:15 2017 +0300

    [NTOS:INBV] Implement rotation bar for boot screen
    
    CORE-10327 #resolve
---
 ntoskrnl/ex/init.c               |   2 +-
 ntoskrnl/inbv/inbv.c             | 182 +++++++++++++++++++++++++++++++++++++--
 ntoskrnl/inbv/logo/line.bmp      | Bin 0 -> 2038 bytes
 ntoskrnl/include/internal/inbv.h |   9 +-
 ntoskrnl/include/resource.h      |   3 +
 ntoskrnl/ntoskrnl.rc             |   1 +
 6 files changed, 187 insertions(+), 10 deletions(-)

diff --git a/ntoskrnl/ex/init.c b/ntoskrnl/ex/init.c
index 71f27efe60..e4ffdd63bd 100644
--- a/ntoskrnl/ex/init.c
+++ b/ntoskrnl/ex/init.c
@@ -1382,7 +1382,7 @@ Phase1InitializationDiscard(IN PVOID Context)
 
     /* Setup the boot driver */
     InbvEnableBootDriver(!NoGuiBoot);
-    InbvDriverInitialize(LoaderBlock, 18);
+    InbvDriverInitialize(LoaderBlock, IDB_MAX_RESOURCE);
 
     /* Check if GUI boot is enabled */
     if (!NoGuiBoot)
diff --git a/ntoskrnl/inbv/inbv.c b/ntoskrnl/inbv/inbv.c
index 698e8bf380..40e015771c 100644
--- a/ntoskrnl/inbv/inbv.c
+++ b/ntoskrnl/inbv/inbv.c
@@ -27,7 +27,7 @@
 /*
  * Enable this define when Inbv will support rotating progress bar.
  */
-// #define INBV_ROTBAR_IMPLEMENTED
+#define INBV_ROTBAR_IMPLEMENTED
 
 static KSPIN_LOCK BootDriverLock;
 static KIRQL InbvOldIrql;
@@ -41,12 +41,18 @@ static INBV_PROGRESS_STATE InbvProgressState;
 static BT_PROGRESS_INDICATOR InbvProgressIndicator = {0, 25, 0};
 static INBV_RESET_DISPLAY_PARAMETERS InbvResetDisplayParameters = NULL;
 static ULONG ResourceCount = 0;
-static PUCHAR ResourceList[1 + IDB_CLUSTER_SERVER]; // First entry == NULL, 
followed by 'ResourceCount' entries.
+static PUCHAR ResourceList[1 + IDB_MAX_RESOURCE]; // First entry == NULL, 
followed by 'ResourceCount' entries.
 
 #ifdef INBV_ROTBAR_IMPLEMENTED
+/*
+ * Change this to modify progress bar behaviour
+ */
+#define ROT_BAR_DEFAULT_MODE    RB_PROGRESS_BAR
 static BOOLEAN RotBarThreadActive = FALSE;
 static ROT_BAR_TYPE RotBarSelection;
 static ULONG PltRotBarStatus;
+static UCHAR RotBarBuffer[24 * 9];
+static UCHAR RotLineBuffer[640 * 6];
 #endif
 
 
@@ -762,6 +768,108 @@ NtDisplayString(IN PUNICODE_STRING DisplayString)
     return STATUS_SUCCESS;
 }
 
+#ifdef INBV_ROTBAR_IMPLEMENTED
+static
+VOID
+NTAPI
+InbvRotationThread(
+    _In_ PVOID Context)
+{
+    ULONG X, Y, Index, Total;
+    LARGE_INTEGER Delay = {{0}};
+
+    InbvAcquireLock();
+    if (RotBarSelection == RB_SQUARE_CELLS)
+    {
+        Index = 0;
+    }
+    else
+    {
+        Index = 32;
+    }
+    X = ProgressBarLeft + 2;
+    Y = ProgressBarTop + 2;
+    InbvReleaseLock();
+
+    while (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)
+    {
+        /* Wait for a bit */
+        KeDelayExecutionThread(KernelMode, FALSE, &Delay);
+
+        InbvAcquireLock();
+
+        /* Unknown unexpected command */
+        ASSERT(PltRotBarStatus <= 3);
+
+        if (PltRotBarStatus == 3)
+        {
+            /* Stop the thread */
+            InbvReleaseLock();
+            break;
+        }
+
+        if (RotBarSelection == RB_SQUARE_CELLS)
+        {
+            Delay.QuadPart = -800000; // 80 ms
+            Total = 18;
+            Index %= Total;
+
+            if (Index >= 3)
+            {
+                /* Fill previous bar position */
+                VidSolidColorFill(X + ((Index - 3) * 8), Y, (X + ((Index - 3) 
* 8)) + 8 - 1, Y + 9 - 1, 0);
+            }
+            if (Index < Total - 1)
+            {
+                /* Draw the progress bar bit */
+                if (Index < 2)
+                {
+                    /* Appearing from the left */
+                    VidBufferToScreenBlt(RotBarBuffer + 8 * (2 - Index) / 2, 
X, Y, 22 - 8 * (2 - Index), 9, 24);
+                }
+                else if (Index >= Total - 3)
+                {
+                    /* Hiding to the right */
+                    VidBufferToScreenBlt(RotBarBuffer, X + ((Index - 2) * 8), 
Y, 22 - 8 * (4 - (Total - Index)), 9, 24);
+                }
+                else
+                {
+                    VidBufferToScreenBlt(RotBarBuffer, X + ((Index - 2) * 8), 
Y, 22, 9, 24);
+                }
+            }
+            Index++;
+        }
+        else if (RotBarSelection == RB_PROGRESS_BAR)
+        {
+            Delay.QuadPart = -600000; // 60 ms
+            Total = 640;
+            Index %= Total;
+
+            /* Right part */
+            VidBufferToScreenBlt(RotLineBuffer, Index, 474, 640 - Index, 6, 
640);
+            if (Index > 0)
+            {
+                /* Left part */
+                VidBufferToScreenBlt(RotLineBuffer + (640 - Index) / 2, 0, 
474, Index - 2, 6, 640);
+            }
+            Index += 32;
+        }
+
+        InbvReleaseLock();
+    }
+
+    PsTerminateSystemThread(STATUS_SUCCESS);
+}
+
+VOID
+NTAPI
+INIT_FUNCTION
+InbvRotBarInit(VOID)
+{
+    PltRotBarStatus = 1;
+}
+#endif
+
 VOID
 NTAPI
 INIT_FUNCTION
@@ -770,13 +878,15 @@ DisplayBootBitmap(IN BOOLEAN TextMode)
     PVOID Header = NULL, Footer = NULL, Screen = NULL;
 
 #ifdef INBV_ROTBAR_IMPLEMENTED
-    PVOID Bar = NULL;
+    UCHAR Buffer[24 * 9];
+    PVOID Bar = NULL, LineBmp = NULL;
     ROT_BAR_TYPE TempRotBarSelection = RB_UNSPECIFIED;
+    NTSTATUS Status;
+    HANDLE ThreadHandle = NULL;
 #endif
 
 #ifdef REACTOS_SKUS
     PVOID Text = NULL;
-    UCHAR Buffer[64];
 #endif
 
 #ifdef INBV_ROTBAR_IMPLEMENTED
@@ -871,6 +981,9 @@ DisplayBootBitmap(IN BOOLEAN TextMode)
             Bar = InbvGetResourceAddress(IDB_BAR_SERVER);
 #endif
         }
+#else
+        /* Use default status bar */
+        Bar = InbvGetResourceAddress(IDB_BAR_WKSTA);
 #endif
 
         /* Make sure we have a logo */
@@ -893,7 +1006,7 @@ DisplayBootBitmap(IN BOOLEAN TextMode)
 
 #ifdef INBV_ROTBAR_IMPLEMENTED
             /* Choose progress bar */
-            TempRotBarSelection = RB_SQUARE_CELLS;
+            TempRotBarSelection = ROT_BAR_DEFAULT_MODE;
 #endif
 
             /* Set progress bar coordinates and display it */
@@ -920,13 +1033,57 @@ DisplayBootBitmap(IN BOOLEAN TextMode)
 #endif
 
 #ifdef INBV_ROTBAR_IMPLEMENTED
-        /* Draw the progress bar bit */
-        if (Bar) InbvBitBlt(Bar, 0, 0);
+        if (Bar)
+        {
+            /* Save previous screen pixels to buffer */
+            InbvScreenToBufferBlt(Buffer, 0, 0, 22, 9, 24);
+            /* Draw the progress bar bit */
+            InbvBitBlt(Bar, 0, 0);
+            /* Store it in global buffer */
+            InbvScreenToBufferBlt(RotBarBuffer, 0, 0, 22, 9, 24);
+            /* Restore screen pixels */
+            InbvBufferToScreenBlt(Buffer, 0, 0, 22, 9, 24);
+        }
+
+        if (TempRotBarSelection == RB_PROGRESS_BAR)
+        {
+            LineBmp = InbvGetResourceAddress(IDB_ROTATING_LINE);
+            if (LineBmp)
+            {
+                /* Draw the line and store it in global buffer */
+                InbvBitBlt(LineBmp, 0, 474);
+                InbvScreenToBufferBlt(RotLineBuffer, 0, 474, 640, 6, 640);
+            }
+        }
+        else
+        {
+            /* Hide the simple progress bar if not used */
+            ShowProgressBar = FALSE;
+        }
 #endif
 
         /* Display the boot logo and fade it in */
         BootLogoFadeIn();
 
+#ifdef INBV_ROTBAR_IMPLEMENTED
+        if (!RotBarThreadActive && TempRotBarSelection != RB_UNSPECIFIED)
+        {
+            /* Start the animation thread */
+            Status = PsCreateSystemThread(&ThreadHandle,
+                                          0,
+                                          NULL,
+                                          NULL,
+                                          NULL,
+                                          InbvRotationThread,
+                                          NULL);
+            if (NT_SUCCESS(Status))
+            {
+                RotBarThreadActive = TRUE;
+                ObCloseHandle(ThreadHandle, KernelMode);
+            }
+        }
+#endif
+
         /* Set filter which will draw text display if needed */
         InbvInstallDisplayStringFilter(DisplayFilter);
     }
@@ -938,8 +1095,16 @@ DisplayBootBitmap(IN BOOLEAN TextMode)
         /* We do, initialize the progress bar */
         InbvAcquireLock();
         RotBarSelection = TempRotBarSelection;
-        // InbvRotBarInit();
+        InbvRotBarInit();
         InbvReleaseLock();
+
+        // FIXME: This was added to allow animation start before the processor 
hangs
+        if (TempRotBarSelection != RB_UNSPECIFIED)
+        {
+            LARGE_INTEGER Delay;
+            Delay.QuadPart = -3000000; // 300 ms
+            KeDelayExecutionThread(KernelMode, FALSE, &Delay);
+        }
     }
 #endif
 }
@@ -984,6 +1149,7 @@ FinalizeBootLogo(VOID)
     /* Reset progress bar and lock */
 #ifdef INBV_ROTBAR_IMPLEMENTED
     PltRotBarStatus = 3;
+    RotBarThreadActive = FALSE;
 #endif
     InbvReleaseLock();
 }
diff --git a/ntoskrnl/inbv/logo/line.bmp b/ntoskrnl/inbv/logo/line.bmp
new file mode 100644
index 0000000000..d080cad7bb
Binary files /dev/null and b/ntoskrnl/inbv/logo/line.bmp differ
diff --git a/ntoskrnl/include/internal/inbv.h b/ntoskrnl/include/internal/inbv.h
index 84d44ba03a..9293828646 100644
--- a/ntoskrnl/include/internal/inbv.h
+++ b/ntoskrnl/include/internal/inbv.h
@@ -17,7 +17,8 @@ typedef struct _BT_PROGRESS_INDICATOR
 typedef enum _ROT_BAR_TYPE
 {
     RB_UNSPECIFIED,
-    RB_SQUARE_CELLS
+    RB_SQUARE_CELLS,
+    RB_PROGRESS_BAR
 } ROT_BAR_TYPE;
 
 VOID
@@ -26,6 +27,12 @@ InbvUpdateProgressBar(
     IN ULONG Progress
 );
 
+VOID
+NTAPI
+InbvRotBarInit(
+    VOID
+);
+
 BOOLEAN
 NTAPI
 InbvDriverInitialize(
diff --git a/ntoskrnl/include/resource.h b/ntoskrnl/include/resource.h
index d58d7913f9..2f7c22b1cc 100644
--- a/ntoskrnl/include/resource.h
+++ b/ntoskrnl/include/resource.h
@@ -10,6 +10,7 @@
 #define IDB_BAR_SERVER      4
 #define IDB_BAR_WKSTA       8
 #define IDB_BAR_HOME        9
+#define IDB_ROTATING_LINE   19
 
 #define IDB_PROF_TEXT       10
 #define IDB_HOME_TEXT       11
@@ -21,3 +22,5 @@
 #define IDB_SERVER_FOOTER   15
 #define IDB_STORAGE_SERVER  16
 #define IDB_CLUSTER_SERVER  17
+
+#define IDB_MAX_RESOURCE    IDB_ROTATING_LINE
diff --git a/ntoskrnl/ntoskrnl.rc b/ntoskrnl/ntoskrnl.rc
index 93595d0a42..dbe2caccc0 100644
--- a/ntoskrnl/ntoskrnl.rc
+++ b/ntoskrnl/ntoskrnl.rc
@@ -39,3 +39,4 @@ IDB_BAR_WKSTA       BITMAP "inbv/logo/8.bmp"
 IDB_SERVER_LOGO     BITMAP "inbv/logo/5.bmp"
 IDB_SERVER_HEADER   BITMAP "inbv/logo/14.bmp"
 IDB_SERVER_FOOTER   BITMAP "inbv/logo/15.bmp"
+IDB_ROTATING_LINE   BITMAP "inbv/logo/line.bmp"

Reply via email to