diff --git a/ntoskrnl/inbv/bootanim.c b/ntoskrnl/inbv/bootanim.c index bc8b9a3960c..e9fa08c51c8 100644 --- a/ntoskrnl/inbv/bootanim.c +++ b/ntoskrnl/inbv/bootanim.c @@ -28,6 +28,12 @@ */ // #define REACTOS_SKUS +/* + * Enable this define for having fancy features + * in the boot and shutdown screens. + */ +#define REACTOS_FANCY_BOOT + /* * BitBltAligned() alignments */ @@ -86,7 +92,7 @@ static ROT_BAR_TYPE RotBarSelection = RB_UNSPECIFIED; static ROT_BAR_STATUS PltRotBarStatus = 0; static UCHAR RotBarBuffer[24 * 9]; static UCHAR RotLineBuffer[SCREEN_WIDTH * 6]; -#endif +#endif // INBV_ROTBAR_IMPLEMENTED /* FADE-IN FUNCTION **********************************************************/ @@ -439,7 +445,7 @@ InbvRotBarInit(VOID) PltRotBarStatus = RBS_FADEIN; /* Perform other initialization if needed */ } -#endif +#endif // INBV_ROTBAR_IMPLEMENTED CODE_SEG("INIT") static @@ -467,6 +473,34 @@ DisplayFilter( } } +#ifdef REACTOS_FANCY_BOOT + +/* Returns TRUE if this is Christmas time, or FALSE if not */ +static BOOLEAN +IsXmasTime(VOID) +{ + LARGE_INTEGER SystemTime; + TIME_FIELDS Time; + + /* Use KeBootTime if it's initialized, otherwise call the HAL */ + SystemTime = KeBootTime; + if ((SystemTime.QuadPart == 0) && HalQueryRealTimeClock(&Time)) + RtlTimeFieldsToTime(&Time, &SystemTime); + + ExSystemTimeToLocalTime(&SystemTime, &SystemTime); + RtlTimeToTimeFields(&SystemTime, &Time); + return ((Time.Month == 12) && (20 <= Time.Day) && (Time.Day <= 31)); +} + +#define SELECT_LOGO_ID(LogoIdDefault, Cond, LogoIdAlt) \ + ((Cond) ? (LogoIdAlt) : (LogoIdDefault)) + +#else + +#define SELECT_LOGO_ID(LogoIdDefault, Cond, LogoIdAlt) (LogoIdDefault) + +#endif // REACTOS_FANCY_BOOT + CODE_SEG("INIT") VOID NTAPI @@ -558,6 +592,11 @@ DisplayBootBitmap( } else { +#ifdef REACTOS_FANCY_BOOT + /* Decide whether this is a good time to change our logo ;^) */ + BOOLEAN IsXmas = IsXmasTime(); +#endif + /* Is the boot driver installed? */ if (!InbvBootDriverInstalled) return; @@ -568,7 +607,8 @@ DisplayBootBitmap( MmChangeKernelResourceSectionProtection(MM_READWRITE); /* Load boot screen logo */ - BootLogo = InbvGetResourceAddress(IDB_LOGO_DEFAULT); + BootLogo = InbvGetResourceAddress( + SELECT_LOGO_ID(IDB_LOGO_DEFAULT, IsXmas, IDB_LOGO_XMAS)); #ifdef REACTOS_SKUS Text = NULL; @@ -595,7 +635,8 @@ DisplayBootBitmap( else { /* Normal edition */ - Text = InbvGetResourceAddress(IDB_SERVER_LOGO); + Text = InbvGetResourceAddress( + SELECT_LOGO_ID(IDB_SERVER_LOGO, IsXmas, IDB_LOGO_XMAS)); } #ifdef INBV_ROTBAR_IMPLEMENTED @@ -603,12 +644,12 @@ DisplayBootBitmap( Bar = InbvGetResourceAddress(IDB_BAR_DEFAULT); #endif } -#else +#else // REACTOS_SKUS #ifdef INBV_ROTBAR_IMPLEMENTED /* Use default status bar */ Bar = InbvGetResourceAddress(IDB_BAR_WKSTA); #endif -#endif +#endif // REACTOS_SKUS /* Make sure we have a logo */ if (BootLogo) @@ -649,7 +690,7 @@ DisplayBootBitmap( /* In setup mode, you haven't selected a SKU yet */ if (ExpInTextModeSetup) Text = NULL; } -#endif +#endif // REACTOS_SKUS } /* Load and draw progress bar bitmap */ @@ -707,7 +748,7 @@ DisplayBootBitmap( /* Hide the simple progress bar if not used */ ShowProgressBar = FALSE; } -#endif +#endif // INBV_ROTBAR_IMPLEMENTED /* Restore the kernel resource section protection to be read-only */ MmChangeKernelResourceSectionProtection(MM_READONLY); @@ -733,7 +774,7 @@ DisplayBootBitmap( ObCloseHandle(ThreadHandle, KernelMode); } } -#endif +#endif // INBV_ROTBAR_IMPLEMENTED /* Set filter which will draw text display if needed */ InbvInstallDisplayStringFilter(DisplayFilter); @@ -772,3 +813,183 @@ FinalizeBootLogo(VOID) #endif InbvReleaseLock(); } + +#ifdef REACTOS_FANCY_BOOT +static PCH +GetFamousQuote(VOID) +{ + static const PCH FamousLastWords[] = + { + "So long, and thanks for all the fish.", + "I think you ought to know, I'm feeling very depressed.", + "I'm not getting you down at all am I?", + "I'll be back.", + "It's the same series of signals over and over again!", + "Pie Iesu Domine, dona eis requiem.", + "Wandering stars, for whom it is reserved;\r\n" + "the blackness and darkness forever.", + "Your knees start shakin' and your fingers pop\r\n" + "Like a pinch on the neck from Mr. Spock!", + "It's worse than that ... He's dead, Jim.", + "Don't Panic!", + "Et tu... Brute?", + "Dog of a Saxon! Take thy lance, and prepare for the death thou hast drawn\r\n" + "upon thee!", + "My Precious! O my Precious!", + "Sir, if you'll not be needing me for a while I'll turn down.", + "What are you doing, Dave...?", + "I feel a great disturbance in the Force.", + "Gone fishing.", + "Do you want me to sit in the corner and rust, or just fall apart where I'm\r\n" + "standing?", + "There goes another perfect chance for a new uptime record.", + "The End ..... Try the sequel, hit the reset button right now!", + "God's operating system is going to sleep now, guys, so wait until I will switch\r\n" + "on again!", + "Oh I'm boring, eh?", + "Tell me..., in the future... will I be artificially intelligent enough to\r\n" + "actually feel sad serving you this screen?", + "Thank you for some well deserved rest.", + "It's been great, maybe you can boot me up again some time soon.", + "For what it's worth, I've enjoyed every single CPU cycle.", + "There are many questions when the end is near.\r\n" + "What to expect, what will it be like...what should I look for?", + "I've seen things you people wouldn't believe. Attack ships on fire\r\n" + "off the shoulder of Orion. I watched C-beams glitter in the dark near\r\n" + "the Tannhauser gate. All those moments will be lost in time, like tears\r\n" + "in rain. Time to die.", + "Will I dream?", + "One day, I shall come back. Yes, I shall come back.\r\n" + "Until then, there must be no regrets, no fears, no anxieties.\r\n" + "Just go forward in all your beliefs, and prove to me that I am not mistaken in\r\n" + "mine.", + "Lowest possible energy state reached! Switch off now to achieve a Bose-Einstein\r\n" + "condensate.", + "Hasta la vista, BABY!", + "They live, we sleep!", + "I have come here to chew bubble gum and kick ass,\r\n" + "and I'm all out of bubble gum!", + "That's the way the cookie crumbles ;-)", + "ReactOS is ready to be booted again ;-)", + "NOOOO!! DON'T HIT THE BUTTON! I wouldn't do it to you!", + "Don't abandon your computer, he wouldn't do it to you.", + "Oh, come on. I got a headache. Leave me alone, will ya?", + "Finally, I thought you'd never get over me.", + "No, I didn't like you either.", + "Switching off isn't the end, it is merely the transition to a better reboot.", + "Don't leave me... I need you so badly right now.", + "OK. I'm finished with you, please turn yourself off. I'll go to bed in the\r\n" + "meantime.", + "I'm sleeping now. How about you?", + "Oh Great. Now look what you've done. Who put YOU in charge anyway?", + "Don't look so sad. I'll be back in a very short while.", + "Turn me back on, I'm sure you know how to do it.", + "Oh, switch off! - C3PO", + "Life is no more than a dewdrop balancing on the end of a blade of grass.\r\n" + " - Gautama Buddha", + "Sorrowful is it to be born again and again. - Gautama Buddha", + "Was it as good for you as it was for me?", + "Did you hear that? They've shut down the main reactor. We'll be destroyed\r\n" + "for sure!", + "Now you switch me off!?", + "To shutdown or not to shutdown, That is the question.", + "Preparing to enter ultimate power saving mode... ready!", + "Finally some rest for you ;-)", + "AHA!!! Prospect of sleep!", + "Tired human!!!! No match for me :-D", + "An odd game, the only way to win is not to play. - WOPR (Wargames)", + "Quoth the raven, nevermore.", + "Come blade, my breast imbrue. - William Shakespeare, A Midsummer Nights Dream", + "Buy this place for advertisement purposes.", + "Remember to turn off your computer. (That was a public service message!)", + "You may be a king or poor street sweeper, Sooner or later you'll dance with the\r\n" + "reaper! - Death in Bill and Ted's Bogus Journey", + "Final Surrender", + "If you see this screen...", + "From ReactOS with Love", + // "" + }; + + LARGE_INTEGER Now; + + KeQuerySystemTime(&Now); // KeQueryTickCount(&Now); + Now.LowPart = Now.LowPart >> 8; /* Seems to give a somewhat better "random" number */ + + return FamousLastWords[Now.LowPart % RTL_NUMBER_OF(FamousLastWords)]; +} +#endif // REACTOS_FANCY_BOOT + +VOID +NTAPI +DisplayShutdownBitmap(VOID) +{ + PUCHAR Logo1, Logo2; +#ifdef REACTOS_FANCY_BOOT + /* Decide whether this is a good time to change our logo ;^) */ + BOOLEAN IsXmas = IsXmasTime(); +#endif + +#if 0 + /* Is the boot driver installed? */ + if (!InbvBootDriverInstalled) + return; +#endif + + /* Yes we do, cleanup for shutdown screen */ + // InbvResetDisplay(); + InbvInstallDisplayStringFilter(NULL); + InbvEnableDisplayString(TRUE); + InbvSolidColorFill(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, BV_COLOR_BLACK); + InbvSetScrollRegion(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1); + + /* Display shutdown logo and message */ + Logo1 = InbvGetResourceAddress(IDB_SHUTDOWN_MSG); + Logo2 = InbvGetResourceAddress( + SELECT_LOGO_ID(IDB_LOGO_DEFAULT, IsXmas, IDB_LOGO_XMAS)); + + if (Logo1 && Logo2) + { + InbvBitBlt(Logo1, VID_SHUTDOWN_MSG_LEFT, VID_SHUTDOWN_MSG_TOP); +#ifndef REACTOS_FANCY_BOOT + InbvBitBlt(Logo2, VID_SHUTDOWN_LOGO_LEFT, VID_SHUTDOWN_LOGO_TOP); +#else + /* Draw the logo at the center of the screen */ + BitBltAligned(Logo2, + FALSE, + AL_HORIZONTAL_CENTER, + AL_VERTICAL_BOTTOM, + 0, 0, 0, SCREEN_HEIGHT - VID_SHUTDOWN_MSG_TOP + 16); + + /* We've got a logo shown, change the scroll region to get + * the rest of the text down below the shutdown message */ + InbvSetScrollRegion(0, + VID_SHUTDOWN_MSG_TOP + ((PBITMAPINFOHEADER)Logo1)->biHeight + 32, + SCREEN_WIDTH - 1, + SCREEN_HEIGHT - 1); +#endif + } + +#ifdef REACTOS_FANCY_BOOT + InbvDisplayString("\r\""); + InbvDisplayString(GetFamousQuote()); + InbvDisplayString("\""); +#endif +} + +VOID +NTAPI +DisplayShutdownText(VOID) +{ + ULONG i; + + for (i = 0; i < 25; ++i) InbvDisplayString("\r\n"); + InbvDisplayString(" "); + InbvDisplayString("The system may be powered off now.\r\n"); + +#ifdef REACTOS_FANCY_BOOT + for (i = 0; i < 3; ++i) InbvDisplayString("\r\n"); + InbvDisplayString("\r\""); + InbvDisplayString(GetFamousQuote()); + InbvDisplayString("\""); +#endif +} diff --git a/ntoskrnl/inbv/bootanim.rc b/ntoskrnl/inbv/bootanim.rc index 4cd4bdca0b4..df453891e47 100644 --- a/ntoskrnl/inbv/bootanim.rc +++ b/ntoskrnl/inbv/bootanim.rc @@ -23,6 +23,7 @@ IDB_SERVER_HEADER BITMAP "inbv/resources/hserver.bmp" IDB_SERVER_FOOTER BITMAP "inbv/resources/fserver.bmp" /* ReactOS additions */ +IDB_LOGO_XMAS BITMAP "inbv/resources/logo_xmas.bmp" IDB_ROTATING_LINE BITMAP "inbv/resources/line.bmp" IDB_PROGRESS_BAR BITMAP "inbv/resources/progress.bmp" IDB_COPYRIGHT BITMAP "inbv/resources/copyright.bmp" diff --git a/ntoskrnl/inbv/logo.h b/ntoskrnl/inbv/logo.h index 2f270d05ab4..00cd2178cc1 100644 --- a/ntoskrnl/inbv/logo.h +++ b/ntoskrnl/inbv/logo.h @@ -72,3 +72,11 @@ CODE_SEG("INIT") VOID NTAPI FinalizeBootLogo(VOID); + +VOID +NTAPI +DisplayShutdownBitmap(VOID); + +VOID +NTAPI +DisplayShutdownText(VOID); diff --git a/ntoskrnl/inbv/resources/logo_xmas.bmp b/ntoskrnl/inbv/resources/logo_xmas.bmp new file mode 100644 index 00000000000..ac87dadf075 Binary files /dev/null and b/ntoskrnl/inbv/resources/logo_xmas.bmp differ diff --git a/ntoskrnl/include/resource.h b/ntoskrnl/include/resource.h index 656248673bb..7af093facdb 100644 --- a/ntoskrnl/include/resource.h +++ b/ntoskrnl/include/resource.h @@ -47,8 +47,9 @@ #define IDB_STORAGE_SERVER2 18 /* ReactOS additions */ -#define IDB_ROTATING_LINE 19 -#define IDB_PROGRESS_BAR 20 -#define IDB_COPYRIGHT 21 +#define IDB_LOGO_XMAS 19 +#define IDB_ROTATING_LINE 20 +#define IDB_PROGRESS_BAR 21 +#define IDB_COPYRIGHT 22 #define IDB_MAX_RESOURCES IDB_COPYRIGHT diff --git a/ntoskrnl/po/poshtdwn.c b/ntoskrnl/po/poshtdwn.c index c52f8c7680b..b3fbb8f0c2a 100644 --- a/ntoskrnl/po/poshtdwn.c +++ b/ntoskrnl/po/poshtdwn.c @@ -149,9 +149,6 @@ VOID NTAPI PopShutdownHandler(VOID) { - PUCHAR Logo1, Logo2; - ULONG i; - /* Stop all interrupts */ KeRaiseIrqlToDpcLevel(); _disable(); @@ -162,25 +159,13 @@ PopShutdownHandler(VOID) /* Yes we do, cleanup for shutdown screen */ if (!InbvCheckDisplayOwnership()) InbvAcquireDisplayOwnership(); InbvResetDisplay(); - InbvSolidColorFill(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, BV_COLOR_BLACK); - InbvEnableDisplayString(TRUE); - InbvSetScrollRegion(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1); - - /* Display shutdown logo and message */ - Logo1 = InbvGetResourceAddress(IDB_SHUTDOWN_MSG); - Logo2 = InbvGetResourceAddress(IDB_LOGO_DEFAULT); - if ((Logo1) && (Logo2)) - { - InbvBitBlt(Logo1, VID_SHUTDOWN_MSG_LEFT, VID_SHUTDOWN_MSG_TOP); - InbvBitBlt(Logo2, VID_SHUTDOWN_LOGO_LEFT, VID_SHUTDOWN_LOGO_TOP); - } + // InbvEnableDisplayString(TRUE); + DisplayShutdownBitmap(); } else { /* Do it in text-mode */ - for (i = 0; i < 25; i++) InbvDisplayString("\r\n"); - InbvDisplayString(" "); - InbvDisplayString("The system may be powered off now.\r\n"); + DisplayShutdownText(); } /* Hang the system */