https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dd71fb5ec868c03b08adc5...
commit dd71fb5ec868c03b08adc52cbfbe3c0cd2e57e86 Author: Stanislav Motylkov x86corez@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"