[CONSRV]
[reactos.git] / reactos / win32ss / user / winsrv / consrv / popup.c
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 for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++)
62 {
63 Code.Attribute = Buffer->PopupDefaultAttrib;
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(PCONSRV_CONSOLE Console,
185 PTEXTMODE_SCREEN_BUFFER Buffer,
186 SHORT xLeft,
187 SHORT yTop,
188 SHORT Width,
189 SHORT Height)
190 {
191 PPOPUP_WINDOW Popup;
192 SMALL_RECT Region;
193
194 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
195
196 /* Create the popup window */
197 Popup = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(*Popup));
198 if (Popup == NULL) return NULL;
199
200 Popup->ScreenBuffer = Buffer;
201 Popup->Origin.X = xLeft;
202 Popup->Origin.Y = yTop;
203 Popup->Size.X = Width;
204 Popup->Size.Y = Height;
205
206 /* Save old contents */
207 Popup->OldContents = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
208 Popup->Size.X * Popup->Size.Y *
209 sizeof(*Popup->OldContents));
210 if (Popup->OldContents == NULL)
211 {
212 ConsoleFreeHeap(Popup);
213 return NULL;
214 }
215 Region.Left = Popup->Origin.X;
216 Region.Top = Popup->Origin.Y;
217 Region.Right = Popup->Origin.X + Popup->Size.X - 1;
218 Region.Bottom = Popup->Origin.Y + Popup->Size.Y - 1;
219 ConDrvReadConsoleOutput(Buffer->Header.Console,
220 Buffer,
221 TRUE,
222 Popup->OldContents,
223 &Region);
224
225 /* Draw it */
226 DrawBox(Buffer,
227 xLeft, yTop,
228 Width, Height);
229
230 /* Add it into the list of popups */
231 InsertTailList(&Console->PopupWindows, &Popup->ListEntry);
232
233 return Popup;
234 }
235
236 VOID
237 DestroyPopupWindow(PPOPUP_WINDOW Popup)
238 {
239 SMALL_RECT Region;
240
241 if (Popup == NULL) return;
242
243 /* Remove it from the list of popups */
244 RemoveEntryList(&Popup->ListEntry);
245
246 /* Restore the old screen-buffer contents */
247 Region.Left = Popup->Origin.X;
248 Region.Top = Popup->Origin.Y;
249 Region.Right = Popup->Origin.X + Popup->Size.X - 1;
250 Region.Bottom = Popup->Origin.Y + Popup->Size.Y - 1;
251 ConDrvWriteConsoleOutput(Popup->ScreenBuffer->Header.Console,
252 Popup->ScreenBuffer,
253 TRUE,
254 Popup->OldContents,
255 &Region);
256
257 /* Free memory */
258 ConsoleFreeHeap(Popup->OldContents);
259 ConsoleFreeHeap(Popup);
260 }
261
262 /* EOF */