Reactos

[NTOS:INBV:PO] Consolidate shutdown logo routines where all the boot theming is implemented.

And it's late now, but... Merry Christmas 2023 as well! 🎄
Logo design by contributor 'TheCustomFHD'

"From ReactOS with Love" ;^)

+246 -30
+230 -9
ntoskrnl/inbv/bootanim.c
··· 29 29 // #define REACTOS_SKUS 30 30 31 31 /* 32 + * Enable this define for having fancy features 33 + * in the boot and shutdown screens. 34 + */ 35 + #define REACTOS_FANCY_BOOT 36 + 37 + /* 32 38 * BitBltAligned() alignments 33 39 */ 34 40 typedef enum _BBLT_VERT_ALIGNMENT ··· 86 92 static ROT_BAR_STATUS PltRotBarStatus = 0; 87 93 static UCHAR RotBarBuffer[24 * 9]; 88 94 static UCHAR RotLineBuffer[SCREEN_WIDTH * 6]; 89 - #endif 95 + #endif // INBV_ROTBAR_IMPLEMENTED 90 96 91 97 92 98 /* FADE-IN FUNCTION **********************************************************/ ··· 439 445 PltRotBarStatus = RBS_FADEIN; 440 446 /* Perform other initialization if needed */ 441 447 } 442 - #endif 448 + #endif // INBV_ROTBAR_IMPLEMENTED 443 449 444 450 CODE_SEG("INIT") 445 451 static ··· 467 473 } 468 474 } 469 475 476 + #ifdef REACTOS_FANCY_BOOT 477 + 478 + /* Returns TRUE if this is Christmas time, or FALSE if not */ 479 + static BOOLEAN 480 + IsXmasTime(VOID) 481 + { 482 + LARGE_INTEGER SystemTime; 483 + TIME_FIELDS Time; 484 + 485 + /* Use KeBootTime if it's initialized, otherwise call the HAL */ 486 + SystemTime = KeBootTime; 487 + if ((SystemTime.QuadPart == 0) && HalQueryRealTimeClock(&Time)) 488 + RtlTimeFieldsToTime(&Time, &SystemTime); 489 + 490 + ExSystemTimeToLocalTime(&SystemTime, &SystemTime); 491 + RtlTimeToTimeFields(&SystemTime, &Time); 492 + return ((Time.Month == 12) && (20 <= Time.Day) && (Time.Day <= 31)); 493 + } 494 + 495 + #define SELECT_LOGO_ID(LogoIdDefault, Cond, LogoIdAlt) \ 496 + ((Cond) ? (LogoIdAlt) : (LogoIdDefault)) 497 + 498 + #else 499 + 500 + #define SELECT_LOGO_ID(LogoIdDefault, Cond, LogoIdAlt) (LogoIdDefault) 501 + 502 + #endif // REACTOS_FANCY_BOOT 503 + 470 504 CODE_SEG("INIT") 471 505 VOID 472 506 NTAPI ··· 558 592 } 559 593 else 560 594 { 595 + #ifdef REACTOS_FANCY_BOOT 596 + /* Decide whether this is a good time to change our logo ;^) */ 597 + BOOLEAN IsXmas = IsXmasTime(); 598 + #endif 599 + 561 600 /* Is the boot driver installed? */ 562 601 if (!InbvBootDriverInstalled) return; 563 602 ··· 568 607 MmChangeKernelResourceSectionProtection(MM_READWRITE); 569 608 570 609 /* Load boot screen logo */ 571 - BootLogo = InbvGetResourceAddress(IDB_LOGO_DEFAULT); 610 + BootLogo = InbvGetResourceAddress( 611 + SELECT_LOGO_ID(IDB_LOGO_DEFAULT, IsXmas, IDB_LOGO_XMAS)); 572 612 573 613 #ifdef REACTOS_SKUS 574 614 Text = NULL; ··· 595 635 else 596 636 { 597 637 /* Normal edition */ 598 - Text = InbvGetResourceAddress(IDB_SERVER_LOGO); 638 + Text = InbvGetResourceAddress( 639 + SELECT_LOGO_ID(IDB_SERVER_LOGO, IsXmas, IDB_LOGO_XMAS)); 599 640 } 600 641 601 642 #ifdef INBV_ROTBAR_IMPLEMENTED ··· 603 644 Bar = InbvGetResourceAddress(IDB_BAR_DEFAULT); 604 645 #endif 605 646 } 606 - #else 647 + #else // REACTOS_SKUS 607 648 #ifdef INBV_ROTBAR_IMPLEMENTED 608 649 /* Use default status bar */ 609 650 Bar = InbvGetResourceAddress(IDB_BAR_WKSTA); 610 651 #endif 611 - #endif 652 + #endif // REACTOS_SKUS 612 653 613 654 /* Make sure we have a logo */ 614 655 if (BootLogo) ··· 649 690 /* In setup mode, you haven't selected a SKU yet */ 650 691 if (ExpInTextModeSetup) Text = NULL; 651 692 } 652 - #endif 693 + #endif // REACTOS_SKUS 653 694 } 654 695 655 696 /* Load and draw progress bar bitmap */ ··· 707 748 /* Hide the simple progress bar if not used */ 708 749 ShowProgressBar = FALSE; 709 750 } 710 - #endif 751 + #endif // INBV_ROTBAR_IMPLEMENTED 711 752 712 753 /* Restore the kernel resource section protection to be read-only */ 713 754 MmChangeKernelResourceSectionProtection(MM_READONLY); ··· 733 774 ObCloseHandle(ThreadHandle, KernelMode); 734 775 } 735 776 } 736 - #endif 777 + #endif // INBV_ROTBAR_IMPLEMENTED 737 778 738 779 /* Set filter which will draw text display if needed */ 739 780 InbvInstallDisplayStringFilter(DisplayFilter); ··· 772 813 #endif 773 814 InbvReleaseLock(); 774 815 } 816 + 817 + #ifdef REACTOS_FANCY_BOOT 818 + static PCH 819 + GetFamousQuote(VOID) 820 + { 821 + static const PCH FamousLastWords[] = 822 + { 823 + "So long, and thanks for all the fish.", 824 + "I think you ought to know, I'm feeling very depressed.", 825 + "I'm not getting you down at all am I?", 826 + "I'll be back.", 827 + "It's the same series of signals over and over again!", 828 + "Pie Iesu Domine, dona eis requiem.", 829 + "Wandering stars, for whom it is reserved;\r\n" 830 + "the blackness and darkness forever.", 831 + "Your knees start shakin' and your fingers pop\r\n" 832 + "Like a pinch on the neck from Mr. Spock!", 833 + "It's worse than that ... He's dead, Jim.", 834 + "Don't Panic!", 835 + "Et tu... Brute?", 836 + "Dog of a Saxon! Take thy lance, and prepare for the death thou hast drawn\r\n" 837 + "upon thee!", 838 + "My Precious! O my Precious!", 839 + "Sir, if you'll not be needing me for a while I'll turn down.", 840 + "What are you doing, Dave...?", 841 + "I feel a great disturbance in the Force.", 842 + "Gone fishing.", 843 + "Do you want me to sit in the corner and rust, or just fall apart where I'm\r\n" 844 + "standing?", 845 + "There goes another perfect chance for a new uptime record.", 846 + "The End ..... Try the sequel, hit the reset button right now!", 847 + "God's operating system is going to sleep now, guys, so wait until I will switch\r\n" 848 + "on again!", 849 + "Oh I'm boring, eh?", 850 + "Tell me..., in the future... will I be artificially intelligent enough to\r\n" 851 + "actually feel sad serving you this screen?", 852 + "Thank you for some well deserved rest.", 853 + "It's been great, maybe you can boot me up again some time soon.", 854 + "For what it's worth, I've enjoyed every single CPU cycle.", 855 + "There are many questions when the end is near.\r\n" 856 + "What to expect, what will it be like...what should I look for?", 857 + "I've seen things you people wouldn't believe. Attack ships on fire\r\n" 858 + "off the shoulder of Orion. I watched C-beams glitter in the dark near\r\n" 859 + "the Tannhauser gate. All those moments will be lost in time, like tears\r\n" 860 + "in rain. Time to die.", 861 + "Will I dream?", 862 + "One day, I shall come back. Yes, I shall come back.\r\n" 863 + "Until then, there must be no regrets, no fears, no anxieties.\r\n" 864 + "Just go forward in all your beliefs, and prove to me that I am not mistaken in\r\n" 865 + "mine.", 866 + "Lowest possible energy state reached! Switch off now to achieve a Bose-Einstein\r\n" 867 + "condensate.", 868 + "Hasta la vista, BABY!", 869 + "They live, we sleep!", 870 + "I have come here to chew bubble gum and kick ass,\r\n" 871 + "and I'm all out of bubble gum!", 872 + "That's the way the cookie crumbles ;-)", 873 + "ReactOS is ready to be booted again ;-)", 874 + "NOOOO!! DON'T HIT THE BUTTON! I wouldn't do it to you!", 875 + "Don't abandon your computer, he wouldn't do it to you.", 876 + "Oh, come on. I got a headache. Leave me alone, will ya?", 877 + "Finally, I thought you'd never get over me.", 878 + "No, I didn't like you either.", 879 + "Switching off isn't the end, it is merely the transition to a better reboot.", 880 + "Don't leave me... I need you so badly right now.", 881 + "OK. I'm finished with you, please turn yourself off. I'll go to bed in the\r\n" 882 + "meantime.", 883 + "I'm sleeping now. How about you?", 884 + "Oh Great. Now look what you've done. Who put YOU in charge anyway?", 885 + "Don't look so sad. I'll be back in a very short while.", 886 + "Turn me back on, I'm sure you know how to do it.", 887 + "Oh, switch off! - C3PO", 888 + "Life is no more than a dewdrop balancing on the end of a blade of grass.\r\n" 889 + " - Gautama Buddha", 890 + "Sorrowful is it to be born again and again. - Gautama Buddha", 891 + "Was it as good for you as it was for me?", 892 + "Did you hear that? They've shut down the main reactor. We'll be destroyed\r\n" 893 + "for sure!", 894 + "Now you switch me off!?", 895 + "To shutdown or not to shutdown, That is the question.", 896 + "Preparing to enter ultimate power saving mode... ready!", 897 + "Finally some rest for you ;-)", 898 + "AHA!!! Prospect of sleep!", 899 + "Tired human!!!! No match for me :-D", 900 + "An odd game, the only way to win is not to play. - WOPR (Wargames)", 901 + "Quoth the raven, nevermore.", 902 + "Come blade, my breast imbrue. - William Shakespeare, A Midsummer Nights Dream", 903 + "Buy this place for advertisement purposes.", 904 + "Remember to turn off your computer. (That was a public service message!)", 905 + "You may be a king or poor street sweeper, Sooner or later you'll dance with the\r\n" 906 + "reaper! - Death in Bill and Ted's Bogus Journey", 907 + "Final Surrender", 908 + "If you see this screen...", 909 + "From ReactOS with Love", 910 + // "<Place your Ad here>" 911 + }; 912 + 913 + LARGE_INTEGER Now; 914 + 915 + KeQuerySystemTime(&Now); // KeQueryTickCount(&Now); 916 + Now.LowPart = Now.LowPart >> 8; /* Seems to give a somewhat better "random" number */ 917 + 918 + return FamousLastWords[Now.LowPart % RTL_NUMBER_OF(FamousLastWords)]; 919 + } 920 + #endif // REACTOS_FANCY_BOOT 921 + 922 + VOID 923 + NTAPI 924 + DisplayShutdownBitmap(VOID) 925 + { 926 + PUCHAR Logo1, Logo2; 927 + #ifdef REACTOS_FANCY_BOOT 928 + /* Decide whether this is a good time to change our logo ;^) */ 929 + BOOLEAN IsXmas = IsXmasTime(); 930 + #endif 931 + 932 + #if 0 933 + /* Is the boot driver installed? */ 934 + if (!InbvBootDriverInstalled) 935 + return; 936 + #endif 937 + 938 + /* Yes we do, cleanup for shutdown screen */ 939 + // InbvResetDisplay(); 940 + InbvInstallDisplayStringFilter(NULL); 941 + InbvEnableDisplayString(TRUE); 942 + InbvSolidColorFill(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, BV_COLOR_BLACK); 943 + InbvSetScrollRegion(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1); 944 + 945 + /* Display shutdown logo and message */ 946 + Logo1 = InbvGetResourceAddress(IDB_SHUTDOWN_MSG); 947 + Logo2 = InbvGetResourceAddress( 948 + SELECT_LOGO_ID(IDB_LOGO_DEFAULT, IsXmas, IDB_LOGO_XMAS)); 949 + 950 + if (Logo1 && Logo2) 951 + { 952 + InbvBitBlt(Logo1, VID_SHUTDOWN_MSG_LEFT, VID_SHUTDOWN_MSG_TOP); 953 + #ifndef REACTOS_FANCY_BOOT 954 + InbvBitBlt(Logo2, VID_SHUTDOWN_LOGO_LEFT, VID_SHUTDOWN_LOGO_TOP); 955 + #else 956 + /* Draw the logo at the center of the screen */ 957 + BitBltAligned(Logo2, 958 + FALSE, 959 + AL_HORIZONTAL_CENTER, 960 + AL_VERTICAL_BOTTOM, 961 + 0, 0, 0, SCREEN_HEIGHT - VID_SHUTDOWN_MSG_TOP + 16); 962 + 963 + /* We've got a logo shown, change the scroll region to get 964 + * the rest of the text down below the shutdown message */ 965 + InbvSetScrollRegion(0, 966 + VID_SHUTDOWN_MSG_TOP + ((PBITMAPINFOHEADER)Logo1)->biHeight + 32, 967 + SCREEN_WIDTH - 1, 968 + SCREEN_HEIGHT - 1); 969 + #endif 970 + } 971 + 972 + #ifdef REACTOS_FANCY_BOOT 973 + InbvDisplayString("\r\""); 974 + InbvDisplayString(GetFamousQuote()); 975 + InbvDisplayString("\""); 976 + #endif 977 + } 978 + 979 + VOID 980 + NTAPI 981 + DisplayShutdownText(VOID) 982 + { 983 + ULONG i; 984 + 985 + for (i = 0; i < 25; ++i) InbvDisplayString("\r\n"); 986 + InbvDisplayString(" "); 987 + InbvDisplayString("The system may be powered off now.\r\n"); 988 + 989 + #ifdef REACTOS_FANCY_BOOT 990 + for (i = 0; i < 3; ++i) InbvDisplayString("\r\n"); 991 + InbvDisplayString("\r\""); 992 + InbvDisplayString(GetFamousQuote()); 993 + InbvDisplayString("\""); 994 + #endif 995 + }
+1
ntoskrnl/inbv/bootanim.rc
··· 23 23 IDB_SERVER_FOOTER BITMAP "inbv/resources/fserver.bmp" 24 24 25 25 /* ReactOS additions */ 26 + IDB_LOGO_XMAS BITMAP "inbv/resources/logo_xmas.bmp" 26 27 IDB_ROTATING_LINE BITMAP "inbv/resources/line.bmp" 27 28 IDB_PROGRESS_BAR BITMAP "inbv/resources/progress.bmp" 28 29 IDB_COPYRIGHT BITMAP "inbv/resources/copyright.bmp"
+8
ntoskrnl/inbv/logo.h
··· 72 72 VOID 73 73 NTAPI 74 74 FinalizeBootLogo(VOID); 75 + 76 + VOID 77 + NTAPI 78 + DisplayShutdownBitmap(VOID); 79 + 80 + VOID 81 + NTAPI 82 + DisplayShutdownText(VOID);
ntoskrnl/inbv/resources/logo_xmas.bmp

This is a binary file and will not be displayed.

+4 -3
ntoskrnl/include/resource.h
··· 47 47 #define IDB_STORAGE_SERVER2 18 48 48 49 49 /* ReactOS additions */ 50 - #define IDB_ROTATING_LINE 19 51 - #define IDB_PROGRESS_BAR 20 52 - #define IDB_COPYRIGHT 21 50 + #define IDB_LOGO_XMAS 19 51 + #define IDB_ROTATING_LINE 20 52 + #define IDB_PROGRESS_BAR 21 53 + #define IDB_COPYRIGHT 22 53 54 54 55 #define IDB_MAX_RESOURCES IDB_COPYRIGHT
+3 -18
ntoskrnl/po/poshtdwn.c
··· 149 149 NTAPI 150 150 PopShutdownHandler(VOID) 151 151 { 152 - PUCHAR Logo1, Logo2; 153 - ULONG i; 154 - 155 152 /* Stop all interrupts */ 156 153 KeRaiseIrqlToDpcLevel(); 157 154 _disable(); ··· 162 159 /* Yes we do, cleanup for shutdown screen */ 163 160 if (!InbvCheckDisplayOwnership()) InbvAcquireDisplayOwnership(); 164 161 InbvResetDisplay(); 165 - InbvSolidColorFill(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, BV_COLOR_BLACK); 166 - InbvEnableDisplayString(TRUE); 167 - InbvSetScrollRegion(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1); 168 - 169 - /* Display shutdown logo and message */ 170 - Logo1 = InbvGetResourceAddress(IDB_SHUTDOWN_MSG); 171 - Logo2 = InbvGetResourceAddress(IDB_LOGO_DEFAULT); 172 - if ((Logo1) && (Logo2)) 173 - { 174 - InbvBitBlt(Logo1, VID_SHUTDOWN_MSG_LEFT, VID_SHUTDOWN_MSG_TOP); 175 - InbvBitBlt(Logo2, VID_SHUTDOWN_LOGO_LEFT, VID_SHUTDOWN_LOGO_TOP); 176 - } 162 + // InbvEnableDisplayString(TRUE); 163 + DisplayShutdownBitmap(); 177 164 } 178 165 else 179 166 { 180 167 /* Do it in text-mode */ 181 - for (i = 0; i < 25; i++) InbvDisplayString("\r\n"); 182 - InbvDisplayString(" "); 183 - InbvDisplayString("The system may be powered off now.\r\n"); 168 + DisplayShutdownText(); 184 169 } 185 170 186 171 /* Hang the system */