Sync with trunk for console graphics palettes.
[reactos.git] / dll / cpl / console / layout.c
1 /*
2 * PROJECT: ReactOS Console Configuration DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/console/layout.c
5 * PURPOSE: displays layout dialog
6 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
7 */
8
9 #include "console.h"
10
11 #define NDEBUG
12 #include <debug.h>
13
14 const TCHAR szPreviewText[] =
15 _T("C:\\ReactOS> dir \n") \
16 _T("SYSTEM <DIR> 13-04-15 5:00a\n") \
17 _T("SYSTEM32 <DIR> 13-04-15 5:00a\n") \
18 _T("readme txt 1739 13-04-15 5:00a\n") \
19 _T("explorer exe 3329536 13-04-15 5:00a\n") \
20 _T("vgafonts cab 18736 13-04-15 5:00a\n") \
21 _T("setuplog txt 313 13-04-15 5:00a\n") \
22 _T("win ini 7005 13-04-15 5:00a\n");
23
24
25 VOID
26 PaintConsole(LPDRAWITEMSTRUCT drawItem,
27 PCONSOLE_PROPS pConInfo)
28 {
29 PGUI_CONSOLE_INFO GuiInfo = pConInfo->TerminalInfo.TermInfo;
30 HBRUSH hBrush;
31 RECT cRect, fRect;
32 DWORD startx, starty;
33 DWORD endx, endy;
34 DWORD sizex, sizey;
35
36 FillRect(drawItem->hDC, &drawItem->rcItem, GetSysColorBrush(COLOR_BACKGROUND));
37
38 sizex = drawItem->rcItem.right - drawItem->rcItem.left;
39 sizey = drawItem->rcItem.bottom - drawItem->rcItem.top;
40
41 if ( GuiInfo->WindowOrigin.x == MAXDWORD &&
42 GuiInfo->WindowOrigin.y == MAXDWORD )
43 {
44 startx = sizex / 3;
45 starty = sizey / 3;
46 }
47 else
48 {
49 // TODO:
50 // Calculate pos correctly when console centered
51 startx = sizex / 3;
52 starty = sizey / 3;
53 }
54
55 // TODO:
56 // Strech console when bold fonts are selected
57 endx = drawItem->rcItem.right - startx + 15;
58 endy = starty + sizey / 3;
59
60 /* Draw console size */
61 SetRect(&cRect, startx, starty, endx, endy);
62 FillRect(drawItem->hDC, &cRect, GetSysColorBrush(COLOR_WINDOWFRAME));
63
64 /* Draw console border */
65 SetRect(&fRect, startx + 1, starty + 1, cRect.right - 1, cRect.bottom - 1);
66 FrameRect(drawItem->hDC, &fRect, GetSysColorBrush(COLOR_ACTIVEBORDER));
67
68 /* Draw left box */
69 SetRect(&fRect, startx + 3, starty + 3, startx + 5, starty + 5);
70 FillRect(drawItem->hDC, &fRect, GetSysColorBrush(COLOR_ACTIVEBORDER));
71
72 /* Draw window title */
73 SetRect(&fRect, startx + 7, starty + 3, cRect.right - 9, starty + 5);
74 FillRect(drawItem->hDC, &fRect, GetSysColorBrush(COLOR_ACTIVECAPTION));
75
76 /* Draw first right box */
77 SetRect(&fRect, fRect.right + 1, starty + 3, fRect.right + 3, starty + 5);
78 FillRect(drawItem->hDC, &fRect, GetSysColorBrush(COLOR_ACTIVEBORDER));
79
80 /* Draw second right box */
81 SetRect(&fRect, fRect.right + 1, starty + 3, fRect.right + 3, starty + 5);
82 FillRect(drawItem->hDC, &fRect, GetSysColorBrush(COLOR_ACTIVEBORDER));
83
84 /* Draw scrollbar */
85 SetRect(&fRect, cRect.right - 5, fRect.bottom + 1, cRect.right - 3, cRect.bottom - 3);
86 FillRect(drawItem->hDC, &fRect, GetSysColorBrush(COLOR_SCROLLBAR));
87
88 /* Draw console background */
89 hBrush = CreateSolidBrush(pConInfo->ci.Colors[BkgdAttribFromAttrib(pConInfo->ci.ScreenAttrib)]);
90 SetRect(&fRect, startx + 3, starty + 6, cRect.right - 6, cRect.bottom - 3);
91 FillRect(drawItem->hDC, &fRect, hBrush);
92 DeleteObject((HGDIOBJ)hBrush);
93 }
94
95 VOID PaintText(LPDRAWITEMSTRUCT drawItem,
96 PCONSOLE_PROPS pConInfo)
97 {
98 COLORREF pbkColor, ptColor;
99 COLORREF nbkColor, ntColor;
100 HBRUSH hBrush = NULL;
101
102 if (drawItem->CtlID == IDC_STATIC_SCREEN_COLOR)
103 {
104 nbkColor = pConInfo->ci.Colors[BkgdAttribFromAttrib(pConInfo->ci.ScreenAttrib)];
105 hBrush = CreateSolidBrush(nbkColor);
106 ntColor = pConInfo->ci.Colors[TextAttribFromAttrib(pConInfo->ci.ScreenAttrib)];
107 }
108 else if (drawItem->CtlID == IDC_STATIC_POPUP_COLOR)
109 {
110 nbkColor = pConInfo->ci.Colors[BkgdAttribFromAttrib(pConInfo->ci.PopupAttrib)];
111 hBrush = CreateSolidBrush(nbkColor);
112 ntColor = pConInfo->ci.Colors[TextAttribFromAttrib(pConInfo->ci.PopupAttrib)];
113 }
114
115 if (!hBrush)
116 {
117 return;
118 }
119
120 FillRect(drawItem->hDC, &drawItem->rcItem, hBrush);
121
122 ptColor = SetTextColor(drawItem->hDC, ntColor);
123 pbkColor = SetBkColor(drawItem->hDC, nbkColor);
124 DrawText(drawItem->hDC, szPreviewText, _tcslen(szPreviewText), &drawItem->rcItem, 0);
125 SetTextColor(drawItem->hDC, ptColor);
126 SetBkColor(drawItem->hDC, pbkColor);
127 DeleteObject((HGDIOBJ)hBrush);
128 }
129
130 INT_PTR
131 CALLBACK
132 LayoutProc(HWND hwndDlg,
133 UINT uMsg,
134 WPARAM wParam,
135 LPARAM lParam)
136 {
137 LPNMUPDOWN lpnmud;
138 LPPSHNOTIFY lppsn;
139 PCONSOLE_PROPS pConInfo = (PCONSOLE_PROPS)GetWindowLongPtr(hwndDlg, DWLP_USER);
140 PGUI_CONSOLE_INFO GuiInfo = (pConInfo ? pConInfo->TerminalInfo.TermInfo : NULL);
141
142 UNREFERENCED_PARAMETER(hwndDlg);
143 UNREFERENCED_PARAMETER(wParam);
144
145 switch (uMsg)
146 {
147 case WM_INITDIALOG:
148 {
149 DWORD xres, yres;
150 HDC hDC;
151 pConInfo = (PCONSOLE_PROPS)((LPPROPSHEETPAGE)lParam)->lParam;
152 GuiInfo = pConInfo->TerminalInfo.TermInfo;
153 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pConInfo);
154
155 SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_HEIGHT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
156 SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_WIDTH), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
157 SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_HEIGHT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
158 SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_WIDTH), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
159
160 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, pConInfo->ci.ScreenBufferSize.Y, FALSE);
161 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, pConInfo->ci.ScreenBufferSize.X, FALSE);
162 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, pConInfo->ci.ConsoleSize.Y, FALSE);
163 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, pConInfo->ci.ConsoleSize.X, FALSE);
164
165 hDC = GetDC(NULL);
166 xres = GetDeviceCaps(hDC, HORZRES);
167 yres = GetDeviceCaps(hDC, VERTRES);
168 SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(xres, 0));
169 SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP), UDM_SETRANGE, 0, (LPARAM)MAKELONG(yres, 0));
170
171 if ( GuiInfo->WindowOrigin.x != MAXDWORD &&
172 GuiInfo->WindowOrigin.y != MAXDWORD )
173 {
174 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, GuiInfo->WindowOrigin.x, FALSE);
175 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, GuiInfo->WindowOrigin.y, FALSE);
176 }
177 else
178 {
179 // FIXME: Calculate window pos from xres, yres
180 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, 88, FALSE);
181 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, 88, FALSE);
182 EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT), FALSE);
183 EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP), FALSE);
184 EnableWindow(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT), FALSE);
185 EnableWindow(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP), FALSE);
186 SendMessage(GetDlgItem(hwndDlg, IDC_CHECK_SYSTEM_POS_WINDOW), BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
187 }
188
189 return TRUE;
190 }
191 case WM_DRAWITEM:
192 {
193 PaintConsole((LPDRAWITEMSTRUCT)lParam, pConInfo);
194 return TRUE;
195 }
196 case WM_NOTIFY:
197 {
198 lpnmud = (LPNMUPDOWN) lParam;
199 lppsn = (LPPSHNOTIFY) lParam;
200
201 if (lppsn->hdr.code == UDN_DELTAPOS)
202 {
203 DWORD wheight, wwidth;
204 DWORD sheight, swidth;
205 DWORD left, top;
206
207 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_WIDTH)
208 {
209 wwidth = lpnmud->iPos + lpnmud->iDelta;
210 }
211 else
212 {
213 wwidth = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, NULL, FALSE);
214 }
215
216 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_HEIGHT)
217 {
218 wheight = lpnmud->iPos + lpnmud->iDelta;
219 }
220 else
221 {
222 wheight = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, NULL, FALSE);
223 }
224
225 if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_WIDTH)
226 {
227 swidth = lpnmud->iPos + lpnmud->iDelta;
228 }
229 else
230 {
231 swidth = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
232 }
233
234 if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_HEIGHT)
235 {
236 sheight = lpnmud->iPos + lpnmud->iDelta;
237 }
238 else
239 {
240 sheight = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
241 }
242
243 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_POS_LEFT)
244 {
245 left = lpnmud->iPos + lpnmud->iDelta;
246 }
247 else
248 {
249 left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, FALSE);
250 }
251
252 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_POS_TOP)
253 {
254 top = lpnmud->iPos + lpnmud->iDelta;
255 }
256 else
257 {
258 top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, FALSE);
259 }
260
261 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_HEIGHT)
262 {
263 /* Automatically adjust screen buffer size when window size enlarges */
264 if (wwidth >= swidth)
265 {
266 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, wwidth, TRUE);
267 swidth = wwidth;
268 }
269
270 if (wheight >= sheight)
271 {
272 SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, wheight, TRUE);
273 sheight = wheight;
274 }
275 }
276 swidth = min(max(swidth , 1), 0xFFFF);
277 sheight = min(max(sheight, 1), 0xFFFF);
278
279 if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_HEIGHT)
280 {
281 /* Automatically adjust window size when screen buffer decreases */
282 if (wwidth > swidth)
283 {
284 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, swidth, TRUE);
285 wwidth = swidth;
286 }
287
288 if (wheight > sheight)
289 {
290 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, sheight, TRUE);
291 wheight = sheight;
292 }
293 }
294
295 pConInfo->ci.ScreenBufferSize.X = (SHORT)swidth;
296 pConInfo->ci.ScreenBufferSize.Y = (SHORT)sheight;
297 pConInfo->ci.ConsoleSize.X = (SHORT)wwidth;
298 pConInfo->ci.ConsoleSize.Y = (SHORT)wheight;
299 GuiInfo->WindowOrigin.x = left;
300 GuiInfo->WindowOrigin.y = top;
301 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
302 }
303 break;
304 }
305 case WM_COMMAND:
306 {
307 switch (LOWORD(wParam))
308 {
309 case IDC_EDIT_SCREEN_BUFFER_WIDTH:
310 case IDC_EDIT_SCREEN_BUFFER_HEIGHT:
311 case IDC_EDIT_WINDOW_SIZE_WIDTH:
312 case IDC_UPDOWN_WINDOW_SIZE_HEIGHT:
313 case IDC_EDIT_WINDOW_POS_LEFT:
314 case IDC_EDIT_WINDOW_POS_TOP:
315 {
316 if (HIWORD(wParam) == EN_KILLFOCUS)
317 {
318 DWORD wheight, wwidth;
319 DWORD sheight, swidth;
320 DWORD left, top;
321
322 wwidth = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, NULL, FALSE);
323 wheight = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, NULL, FALSE);
324 swidth = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
325 sheight = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
326 left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, FALSE);
327 top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, FALSE);
328
329 swidth = min(max(swidth , 1), 0xFFFF);
330 sheight = min(max(sheight, 1), 0xFFFF);
331
332 /* Automatically adjust window size when screen buffer decreases */
333 if (wwidth > swidth)
334 {
335 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, swidth, TRUE);
336 wwidth = swidth;
337 }
338
339 if (wheight > sheight)
340 {
341 SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, sheight, TRUE);
342 wheight = sheight;
343 }
344
345 pConInfo->ci.ScreenBufferSize.X = (SHORT)swidth;
346 pConInfo->ci.ScreenBufferSize.Y = (SHORT)sheight;
347 pConInfo->ci.ConsoleSize.X = (SHORT)wwidth;
348 pConInfo->ci.ConsoleSize.Y = (SHORT)wheight;
349 GuiInfo->WindowOrigin.x = left;
350 GuiInfo->WindowOrigin.y = top;
351 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
352 }
353 break;
354 }
355
356 case IDC_CHECK_SYSTEM_POS_WINDOW:
357 {
358 LONG res = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0);
359 if (res == BST_CHECKED)
360 {
361 ULONG left, top;
362
363 left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, FALSE);
364 top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, FALSE);
365 GuiInfo->WindowOrigin.x = left;
366 GuiInfo->WindowOrigin.y = top;
367 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
368 EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT), TRUE);
369 EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP), TRUE);
370 EnableWindow(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT), TRUE);
371 EnableWindow(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP), TRUE);
372 }
373 else if (res == BST_UNCHECKED)
374 {
375 GuiInfo->WindowOrigin.x = UINT_MAX;
376 GuiInfo->WindowOrigin.y = UINT_MAX;
377 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
378 EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT), FALSE);
379 EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP), FALSE);
380 EnableWindow(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT), FALSE);
381 EnableWindow(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP), FALSE);
382 }
383 }
384 }
385 }
386 default:
387 break;
388 }
389
390 return FALSE;
391 }