Reactos
at master 173 lines 4.9 kB view raw
1/* 2 * PROJECT: ReactOS Boot Video Driver 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Platform-independent console functionality 5 * COPYRIGHT: Copyright 2010 Gregor Schneider <gregor.schneider@reactos.org> 6 * Copyright 2011 Rafal Harabien <rafalh@reactos.org> 7 * Copyright 2020 Stanislav Motylkov <x86corez@gmail.com> 8 */ 9 10#include "precomp.h" 11 12/* GLOBALS ********************************************************************/ 13 14UCHAR VidpTextColor = BV_COLOR_WHITE; 15ULONG VidpCurrentX = 0; 16ULONG VidpCurrentY = 0; 17URECT VidpScrollRegion = {0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1}; 18 19static BOOLEAN ClearRow = FALSE; 20 21/* PUBLIC FUNCTIONS ***********************************************************/ 22 23VOID 24NTAPI 25VidResetDisplay( 26 _In_ BOOLEAN SetMode) 27{ 28 /* Clear the current position */ 29 VidpCurrentX = 0; 30 VidpCurrentY = 0; 31 32 /* Invoke the hardware-specific routine */ 33 ResetDisplay(SetMode); 34} 35 36ULONG 37NTAPI 38VidSetTextColor( 39 _In_ ULONG Color) 40{ 41 ULONG OldColor; 42 43 /* Save the old color and set the new one */ 44 OldColor = VidpTextColor; 45 VidpTextColor = Color; 46 return OldColor; 47} 48 49VOID 50NTAPI 51VidSetScrollRegion( 52 _In_ ULONG Left, 53 _In_ ULONG Top, 54 _In_ ULONG Right, 55 _In_ ULONG Bottom) 56{ 57 /* Assert alignment */ 58 ASSERT((Left % BOOTCHAR_WIDTH) == 0); 59 ASSERT((Right % BOOTCHAR_WIDTH) == BOOTCHAR_WIDTH - 1); 60 61 /* Set the scroll region */ 62 VidpScrollRegion.Left = Left; 63 VidpScrollRegion.Top = Top; 64 VidpScrollRegion.Right = Right; 65 VidpScrollRegion.Bottom = Bottom; 66 67 /* Set the current X and Y */ 68 VidpCurrentX = Left; 69 VidpCurrentY = Top; 70} 71 72VOID 73NTAPI 74VidDisplayStringXY( 75 _In_ PCSTR String, 76 _In_ ULONG Left, 77 _In_ ULONG Top, 78 _In_ BOOLEAN Transparent) 79{ 80 ULONG BackColor; 81 82 /* 83 * If the caller wanted transparent, then send the special value (16), 84 * else use our default and call the helper routine. 85 */ 86 BackColor = Transparent ? BV_COLOR_NONE : BV_COLOR_LIGHT_CYAN; 87 88 /* Loop every character and adjust the position */ 89 for (; *String; ++String, Left += BOOTCHAR_WIDTH) 90 { 91 /* Display a character */ 92 DisplayCharacter(*String, Left, Top, BV_COLOR_LIGHT_BLUE, BackColor); 93 } 94} 95 96VOID 97NTAPI 98VidDisplayString( 99 _In_ PCSTR String) 100{ 101 /* Start looping the string */ 102 for (; *String; ++String) 103 { 104 /* Treat new-line separately */ 105 if (*String == '\n') 106 { 107 /* Modify Y position */ 108 VidpCurrentY += BOOTCHAR_HEIGHT + 1; 109 if (VidpCurrentY + BOOTCHAR_HEIGHT > VidpScrollRegion.Bottom) 110 { 111 /* Scroll the view and clear the current row */ 112 DoScroll(BOOTCHAR_HEIGHT + 1); 113 VidpCurrentY -= BOOTCHAR_HEIGHT + 1; 114 PreserveRow(VidpCurrentY, BOOTCHAR_HEIGHT + 1, TRUE); 115 } 116 else 117 { 118 /* Preserve the current row */ 119 PreserveRow(VidpCurrentY, BOOTCHAR_HEIGHT + 1, FALSE); 120 } 121 122 /* Update current X */ 123 VidpCurrentX = VidpScrollRegion.Left; 124 125 /* No need to clear this row */ 126 ClearRow = FALSE; 127 } 128 else if (*String == '\r') 129 { 130 /* Update current X */ 131 VidpCurrentX = VidpScrollRegion.Left; 132 133 /* If a new-line does not follow we will clear the current row */ 134 if (String[1] != '\n') 135 ClearRow = TRUE; 136 } 137 else 138 { 139 /* Clear the current row if we had a return-carriage without a new-line */ 140 if (ClearRow) 141 { 142 PreserveRow(VidpCurrentY, BOOTCHAR_HEIGHT + 1, TRUE); 143 ClearRow = FALSE; 144 } 145 146 /* Display this character */ 147 DisplayCharacter(*String, VidpCurrentX, VidpCurrentY, VidpTextColor, BV_COLOR_NONE); 148 VidpCurrentX += BOOTCHAR_WIDTH; 149 150 /* Check if we should scroll */ 151 if (VidpCurrentX + BOOTCHAR_WIDTH - 1 > VidpScrollRegion.Right) 152 { 153 /* Update Y position and check if we should scroll it */ 154 VidpCurrentY += BOOTCHAR_HEIGHT + 1; 155 if (VidpCurrentY + BOOTCHAR_HEIGHT > VidpScrollRegion.Bottom) 156 { 157 /* Scroll the view and clear the current row */ 158 DoScroll(BOOTCHAR_HEIGHT + 1); 159 VidpCurrentY -= BOOTCHAR_HEIGHT + 1; 160 PreserveRow(VidpCurrentY, BOOTCHAR_HEIGHT + 1, TRUE); 161 } 162 else 163 { 164 /* Preserve the current row */ 165 PreserveRow(VidpCurrentY, BOOTCHAR_HEIGHT + 1, FALSE); 166 } 167 168 /* Update current X */ 169 VidpCurrentX = VidpScrollRegion.Left; 170 } 171 } 172 } 173}