https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dd71fb5ec868c03b08adc…
commit dd71fb5ec868c03b08adc52cbfbe3c0cd2e57e86
Author: Stanislav Motylkov <x86corez(a)gmail.com>
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"