1 /* 2 * LICENSE: GPL - See COPYING in the top level directory 3 * PROJECT: ReactOS Console Server DLL 4 * FILE: win32ss/user/winsrv/consrv/popup.c 5 * PURPOSE: Console popup windows 6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) 7 * 8 * NOTE: Strongly inspired by the DrawBox function 9 * from base/setup/usetup/interface/usetup.c, written by: 10 * Eric Kohl (revision 3753) 11 * Herv� Poussineau (revision 24718) 12 * and *UiDisplayMenu from FreeLdr. 13 */ 14 15 /* INCLUDES *******************************************************************/ 16 17 #include "consrv.h" 18 #include "popup.h" 19 20 #define NDEBUG 21 #include <debug.h> 22 23 24 /* PRIVATE FUNCTIONS **********************************************************/ 25 26 NTSTATUS NTAPI 27 ConDrvFillConsoleOutput(IN PCONSOLE Console, 28 IN PTEXTMODE_SCREEN_BUFFER Buffer, 29 IN CODE_TYPE CodeType, 30 IN CODE_ELEMENT Code, 31 IN ULONG NumCodesToWrite, 32 IN PCOORD WriteCoord, 33 OUT PULONG NumCodesWritten OPTIONAL); 34 NTSTATUS NTAPI 35 ConDrvReadConsoleOutput(IN PCONSOLE Console, 36 IN PTEXTMODE_SCREEN_BUFFER Buffer, 37 IN BOOLEAN Unicode, 38 OUT PCHAR_INFO CharInfo/*Buffer*/, 39 IN OUT PSMALL_RECT ReadRegion); 40 NTSTATUS NTAPI 41 ConDrvWriteConsoleOutput(IN PCONSOLE Console, 42 IN PTEXTMODE_SCREEN_BUFFER Buffer, 43 IN BOOLEAN Unicode, 44 IN PCHAR_INFO CharInfo/*Buffer*/, 45 IN OUT PSMALL_RECT WriteRegion); 46 47 48 static VOID 49 DrawBox(PTEXTMODE_SCREEN_BUFFER Buffer, 50 IN SHORT xLeft, 51 IN SHORT yTop, 52 IN SHORT Width, 53 IN SHORT Height) 54 { 55 COORD coPos; 56 DWORD Written; 57 CODE_ELEMENT Code; 58 59 /* Set screen attributes */ 60 coPos.X = xLeft; 61 Code.Attribute = Buffer->PopupDefaultAttrib; 62 for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++) 63 { 64 ConDrvFillConsoleOutput(Buffer->Header.Console, 65 Buffer, 66 CODE_ATTRIBUTE, 67 Code, 68 Width, 69 &coPos, 70 &Written); 71 } 72 73 /* draw upper left corner */ 74 coPos.X = xLeft; 75 coPos.Y = yTop; 76 Code.AsciiChar = 0xDA; // '+' 77 ConDrvFillConsoleOutput(Buffer->Header.Console, 78 Buffer, 79 CODE_ASCII, 80 Code, 81 1, 82 &coPos, 83 &Written); 84 85 /* draw upper edge */ 86 coPos.X = xLeft + 1; 87 coPos.Y = yTop; 88 Code.AsciiChar = 0xC4; // '-' 89 ConDrvFillConsoleOutput(Buffer->Header.Console, 90 Buffer, 91 CODE_ASCII, 92 Code, 93 Width - 2, 94 &coPos, 95 &Written); 96 97 /* draw upper right corner */ 98 coPos.X = xLeft + Width - 1; 99 coPos.Y = yTop; 100 Code.AsciiChar = 0xBF; // '+' 101 ConDrvFillConsoleOutput(Buffer->Header.Console, 102 Buffer, 103 CODE_ASCII, 104 Code, 105 1, 106 &coPos, 107 &Written); 108 109 /* Draw right edge, inner space and left edge */ 110 for (coPos.Y = yTop + 1; coPos.Y < yTop + Height - 1; coPos.Y++) 111 { 112 coPos.X = xLeft; 113 Code.AsciiChar = 0xB3; // '|' 114 ConDrvFillConsoleOutput(Buffer->Header.Console, 115 Buffer, 116 CODE_ASCII, 117 Code, 118 1, 119 &coPos, 120 &Written); 121 122 coPos.X = xLeft + 1; 123 Code.AsciiChar = ' '; 124 ConDrvFillConsoleOutput(Buffer->Header.Console, 125 Buffer, 126 CODE_ASCII, 127 Code, 128 Width - 2, 129 &coPos, 130 &Written); 131 132 coPos.X = xLeft + Width - 1; 133 Code.AsciiChar = 0xB3; // '|' 134 ConDrvFillConsoleOutput(Buffer->Header.Console, 135 Buffer, 136 CODE_ASCII, 137 Code, 138 1, 139 &coPos, 140 &Written); 141 } 142 143 /* draw lower left corner */ 144 coPos.X = xLeft; 145 coPos.Y = yTop + Height - 1; 146 Code.AsciiChar = 0xC0; // '+' 147 ConDrvFillConsoleOutput(Buffer->Header.Console, 148 Buffer, 149 CODE_ASCII, 150 Code, 151 1, 152 &coPos, 153 &Written); 154 155 /* draw lower edge */ 156 coPos.X = xLeft + 1; 157 coPos.Y = yTop + Height - 1; 158 Code.AsciiChar = 0xC4; // '-' 159 ConDrvFillConsoleOutput(Buffer->Header.Console, 160 Buffer, 161 CODE_ASCII, 162 Code, 163 Width - 2, 164 &coPos, 165 &Written); 166 167 /* draw lower right corner */ 168 coPos.X = xLeft + Width - 1; 169 coPos.Y = yTop + Height - 1; 170 Code.AsciiChar = 0xD9; // '+' 171 ConDrvFillConsoleOutput(Buffer->Header.Console, 172 Buffer, 173 CODE_ASCII, 174 Code, 175 1, 176 &coPos, 177 &Written); 178 } 179 180 181 /* PUBLIC FUNCTIONS ***********************************************************/ 182 183 PPOPUP_WINDOW 184 CreatePopupWindow( 185 IN PCONSRV_CONSOLE Console, 186 IN PCONSOLE_SCREEN_BUFFER ScreenBuffer, 187 IN SHORT xLeft, 188 IN SHORT yTop, 189 IN SHORT Width, 190 IN SHORT Height) 191 { 192 PTEXTMODE_SCREEN_BUFFER Buffer; 193 PPOPUP_WINDOW Popup; 194 SMALL_RECT Region; 195 196 ASSERT((PCONSOLE)Console == ScreenBuffer->Header.Console); 197 198 if (GetType(ScreenBuffer) != TEXTMODE_BUFFER) 199 return NULL; 200 201 Buffer = (PTEXTMODE_SCREEN_BUFFER)ScreenBuffer; 202 203 /* Create the popup window */ 204 Popup = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(*Popup)); 205 if (Popup == NULL) return NULL; 206 207 Popup->ScreenBuffer = Buffer; 208 Popup->Origin.X = xLeft; 209 Popup->Origin.Y = yTop; 210 Popup->Size.X = Width; 211 Popup->Size.Y = Height; 212 213 /* Save old contents */ 214 Popup->OldContents = ConsoleAllocHeap(HEAP_ZERO_MEMORY, 215 Popup->Size.X * Popup->Size.Y * 216 sizeof(*Popup->OldContents)); 217 if (Popup->OldContents == NULL) 218 { 219 ConsoleFreeHeap(Popup); 220 return NULL; 221 } 222 Region.Left = Popup->Origin.X; 223 Region.Top = Popup->Origin.Y; 224 Region.Right = Popup->Origin.X + Popup->Size.X - 1; 225 Region.Bottom = Popup->Origin.Y + Popup->Size.Y - 1; 226 ConDrvReadConsoleOutput(Buffer->Header.Console, 227 Buffer, 228 TRUE, 229 Popup->OldContents, 230 &Region); 231 232 /* Draw it */ 233 DrawBox(Buffer, 234 xLeft, yTop, 235 Width, Height); 236 237 /* Add it into the list of popups */ 238 InsertTailList(&Console->PopupWindows, &Popup->ListEntry); 239 240 return Popup; 241 } 242 243 VOID 244 DestroyPopupWindow( 245 IN PPOPUP_WINDOW Popup) 246 { 247 SMALL_RECT Region; 248 249 if (Popup == NULL) return; 250 251 /* Remove it from the list of popups */ 252 RemoveEntryList(&Popup->ListEntry); 253 254 /* Restore the old screen-buffer contents */ 255 Region.Left = Popup->Origin.X; 256 Region.Top = Popup->Origin.Y; 257 Region.Right = Popup->Origin.X + Popup->Size.X - 1; 258 Region.Bottom = Popup->Origin.Y + Popup->Size.Y - 1; 259 ConDrvWriteConsoleOutput(Popup->ScreenBuffer->Header.Console, 260 Popup->ScreenBuffer, 261 TRUE, 262 Popup->OldContents, 263 &Region); 264 265 /* Free memory */ 266 ConsoleFreeHeap(Popup->OldContents); 267 ConsoleFreeHeap(Popup); 268 } 269 270 /* EOF */ 271