[CONSOLE.DLL-CONSRV]
[reactos.git] / dll / cpl / console / console.c
1 /*
2 * PROJECT: ReactOS Console Configuration DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/console/console.c
5 * PURPOSE: initialization of DLL
6 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@student.tugraz.at)
7 */
8
9 #include "console.h"
10
11 #define NUM_APPLETS 1
12
13 LONG APIENTRY InitApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam);
14 INT_PTR CALLBACK OptionsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
15 INT_PTR CALLBACK FontProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
16 INT_PTR CALLBACK LayoutProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
17 INT_PTR CALLBACK ColorsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
18
19 HINSTANCE hApplet = 0;
20
21 /* Applets */
22 APPLET Applets[NUM_APPLETS] =
23 {
24 {IDC_CPLICON, IDS_CPLNAME, IDS_CPLDESCRIPTION, InitApplet}
25 };
26
27 /*
28 * Default 16-color palette for foreground and background
29 * (corresponding flags in comments).
30 */
31 const COLORREF s_Colors[16] =
32 {
33 RGB(0, 0, 0), // (Black)
34 RGB(0, 0, 128), // BLUE
35 RGB(0, 128, 0), // GREEN
36 RGB(0, 128, 128), // BLUE | GREEN
37 RGB(128, 0, 0), // RED
38 RGB(128, 0, 128), // BLUE | RED
39 RGB(128, 128, 0), // GREEN | RED
40 RGB(192, 192, 192), // BLUE | GREEN | RED
41
42 RGB(128, 128, 128), // (Grey) INTENSITY
43 RGB(0, 0, 255), // BLUE | INTENSITY
44 RGB(0, 255, 0), // GREEN | INTENSITY
45 RGB(0, 255, 255), // BLUE | GREEN | INTENSITY
46 RGB(255, 0, 0), // RED | INTENSITY
47 RGB(255, 0, 255), // BLUE | RED | INTENSITY
48 RGB(255, 255, 0), // GREEN | RED | INTENSITY
49 RGB(255, 255, 255) // BLUE | GREEN | RED | INTENSITY
50 };
51 /* Default attributes */
52 #define DEFAULT_SCREEN_ATTRIB (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
53 #define DEFAULT_POPUP_ATTRIB (FOREGROUND_BLUE | FOREGROUND_RED | \
54 BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY)
55 /* Cursor size */
56 #define CSR_DEFAULT_CURSOR_SIZE 25
57
58 static VOID
59 InitPropSheetPage(PROPSHEETPAGE *psp,
60 WORD idDlg,
61 DLGPROC DlgProc,
62 LPARAM lParam)
63 {
64 ZeroMemory(psp, sizeof(PROPSHEETPAGE));
65 psp->dwSize = sizeof(PROPSHEETPAGE);
66 psp->dwFlags = PSP_DEFAULT;
67 psp->hInstance = hApplet;
68 psp->pszTemplate = MAKEINTRESOURCE(idDlg);
69 psp->pfnDlgProc = DlgProc;
70 psp->lParam = lParam;
71 }
72
73 PCONSOLE_PROPS
74 AllocConsoleInfo()
75 {
76 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CONSOLE_PROPS));
77 }
78
79 VOID
80 InitConsoleDefaults(PCONSOLE_PROPS pConInfo)
81 {
82 /* Initialize the default properties */
83 pConInfo->ci.HistoryBufferSize = 50;
84 pConInfo->ci.NumberOfHistoryBuffers = 4;
85 pConInfo->ci.HistoryNoDup = FALSE;
86 pConInfo->ci.FullScreen = FALSE;
87 pConInfo->ci.QuickEdit = FALSE;
88 pConInfo->ci.InsertMode = TRUE;
89 // pConInfo->ci.InputBufferSize;
90 pConInfo->ci.ScreenBufferSize = (COORD){80, 300};
91 pConInfo->ci.ConsoleSize = (COORD){80, 25};
92 pConInfo->ci.CursorBlinkOn = TRUE;
93 pConInfo->ci.ForceCursorOff = FALSE;
94 pConInfo->ci.CursorSize = CSR_DEFAULT_CURSOR_SIZE;
95 pConInfo->ci.ScreenAttrib = DEFAULT_SCREEN_ATTRIB;
96 pConInfo->ci.PopupAttrib = DEFAULT_POPUP_ATTRIB;
97 pConInfo->ci.CodePage = 0;
98 pConInfo->ci.ConsoleTitle[0] = L'\0';
99
100 pConInfo->ci.u.GuiInfo.FaceName[0] = L'\0';
101 pConInfo->ci.u.GuiInfo.FontFamily = FF_DONTCARE;
102 pConInfo->ci.u.GuiInfo.FontSize = 0;
103 pConInfo->ci.u.GuiInfo.FontWeight = FW_DONTCARE;
104 pConInfo->ci.u.GuiInfo.UseRasterFonts = TRUE;
105
106 pConInfo->ci.u.GuiInfo.AutoPosition = TRUE;
107 pConInfo->ci.u.GuiInfo.WindowOrigin = (POINT){0, 0};
108
109 memcpy(pConInfo->ci.Colors, s_Colors, sizeof(s_Colors));
110 }
111
112 INT_PTR
113 CALLBACK
114 ApplyProc(HWND hwndDlg,
115 UINT uMsg,
116 WPARAM wParam,
117 LPARAM lParam)
118 {
119 HWND hDlgCtrl;
120
121 UNREFERENCED_PARAMETER(lParam);
122
123 switch (uMsg)
124 {
125 case WM_INITDIALOG:
126 {
127 hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_APPLY_CURRENT);
128 SendMessage(hDlgCtrl, BM_SETCHECK, BST_CHECKED, 0);
129 return TRUE;
130 }
131 case WM_COMMAND:
132 {
133 if (LOWORD(wParam) == IDOK)
134 {
135 hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_APPLY_CURRENT);
136 if (SendMessage(hDlgCtrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
137 EndDialog(hwndDlg, IDC_RADIO_APPLY_CURRENT);
138 else
139 EndDialog(hwndDlg, IDC_RADIO_APPLY_ALL);
140 }
141 else if (LOWORD(wParam) == IDCANCEL)
142 {
143 EndDialog(hwndDlg, IDCANCEL);
144 }
145 break;
146 }
147 default:
148 break;
149 }
150
151 return FALSE;
152 }
153
154 BOOL
155 ApplyConsoleInfo(HWND hwndDlg,
156 PCONSOLE_PROPS pConInfo)
157 {
158 INT_PTR res = 0;
159
160 res = DialogBox(hApplet, MAKEINTRESOURCE(IDD_APPLYOPTIONS), hwndDlg, ApplyProc);
161 if (res == IDCANCEL)
162 {
163 /* Don't destroy when user presses cancel */
164 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
165 return TRUE;
166 }
167 else if (res == IDC_RADIO_APPLY_ALL || res == IDC_RADIO_APPLY_CURRENT)
168 {
169 HANDLE hSection;
170 PCONSOLE_PROPS pSharedInfo;
171
172 /* Create a memory section to share with the server, and map it */
173 hSection = CreateFileMapping(INVALID_HANDLE_VALUE,
174 NULL,
175 PAGE_READWRITE,
176 0,
177 sizeof(CONSOLE_PROPS),
178 NULL);
179 if (!hSection)
180 {
181 // DPRINT1("Error when creating file mapping, error = %d\n", GetLastError());
182 return FALSE;
183 }
184
185 pSharedInfo = MapViewOfFile(hSection, FILE_MAP_ALL_ACCESS, 0, 0, 0);
186 if (!pSharedInfo)
187 {
188 // DPRINT1("Error when mapping view of file, error = %d\n", GetLastError());
189 CloseHandle(hSection);
190 return FALSE;
191 }
192
193 /* We are applying the chosen configuration */
194 pConInfo->AppliedConfig = TRUE;
195
196 /* Copy the console info into the section */
197 RtlCopyMemory(pSharedInfo, pConInfo, sizeof(CONSOLE_PROPS));
198
199 /* Unmap it */
200 UnmapViewOfFile(pSharedInfo);
201
202 /* Signal to the console server that it can apply the new configuration */
203 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
204 SendMessage(pConInfo->hConsoleWindow,
205 PM_APPLY_CONSOLE_INFO,
206 (WPARAM)hSection,
207 (LPARAM)(res == IDC_RADIO_APPLY_ALL));
208
209 /* Close the section and return */
210 CloseHandle(hSection);
211 return TRUE;
212 }
213
214 return TRUE;
215 }
216
217 /* First Applet */
218 LONG APIENTRY
219 InitApplet(HWND hWnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
220 {
221 HANDLE hSection = (HANDLE)wParam;
222 PCONSOLE_PROPS pSharedInfo;
223 PCONSOLE_PROPS pConInfo;
224 WCHAR szTitle[MAX_PATH + 1];
225 PROPSHEETPAGE psp[4];
226 PROPSHEETHEADER psh;
227 INT i = 0;
228
229 UNREFERENCED_PARAMETER(uMsg);
230
231 /*
232 * CONSOLE.DLL shares information with CONSRV with wParam:
233 * wParam is a handle to a shared section holding a CONSOLE_PROPS struct.
234 *
235 * NOTE: lParam is not used.
236 */
237
238 /* Allocate a local buffer to hold console information */
239 pConInfo = AllocConsoleInfo();
240 if (!pConInfo) return 0;
241
242 /* Map the shared section */
243 pSharedInfo = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0);
244 if (pSharedInfo == NULL)
245 {
246 HeapFree(GetProcessHeap(), 0, pConInfo);
247 return 0;
248 }
249
250 // if (IsBadReadPtr((PVOID)pSharedInfo, sizeof(CONSOLE_PROPS)))
251 // {
252 // }
253
254 /* Find the console window and whether we must use default parameters */
255 pConInfo->hConsoleWindow = pSharedInfo->hConsoleWindow;
256 pConInfo->ShowDefaultParams = pSharedInfo->ShowDefaultParams;
257
258 if (pConInfo->ShowDefaultParams)
259 {
260 /* Use defaults */
261 InitConsoleDefaults(pConInfo);
262 }
263 else
264 {
265 /* Copy the shared data into our allocated buffer */
266 RtlCopyMemory(pConInfo, pSharedInfo, sizeof(CONSOLE_PROPS));
267 }
268
269 /* Close the section */
270 UnmapViewOfFile(pSharedInfo);
271 CloseHandle(hSection);
272
273 /* Initialize the property sheet structure */
274 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
275 psh.dwSize = sizeof(PROPSHEETHEADER);
276 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | /* PSH_USEHICON */ PSH_USEICONID | PSH_NOAPPLYNOW;
277
278 if (pConInfo->ci.ConsoleTitle[0] != L'\0')
279 {
280 wcsncpy(szTitle, L"\"", sizeof(szTitle) / sizeof(szTitle[0]));
281 wcsncat(szTitle, pConInfo->ci.ConsoleTitle, sizeof(szTitle) / sizeof(szTitle[0]));
282 wcsncat(szTitle, L"\"", sizeof(szTitle) / sizeof(szTitle[0]));
283 }
284 else
285 {
286 wcscpy(szTitle, L"ReactOS Console");
287 }
288 psh.pszCaption = szTitle;
289
290 psh.hwndParent = pConInfo->hConsoleWindow;
291 psh.hInstance = hApplet;
292 // psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON));
293 psh.pszIcon = MAKEINTRESOURCE(IDC_CPLICON);
294 psh.nPages = 4;
295 psh.nStartPage = 0;
296 psh.ppsp = psp;
297
298 InitPropSheetPage(&psp[i++], IDD_PROPPAGEOPTIONS, (DLGPROC) OptionsProc, (LPARAM)pConInfo);
299 InitPropSheetPage(&psp[i++], IDD_PROPPAGEFONT, (DLGPROC) FontProc, (LPARAM)pConInfo);
300 InitPropSheetPage(&psp[i++], IDD_PROPPAGELAYOUT, (DLGPROC) LayoutProc, (LPARAM)pConInfo);
301 InitPropSheetPage(&psp[i++], IDD_PROPPAGECOLORS, (DLGPROC) ColorsProc, (LPARAM)pConInfo);
302
303 return (PropertySheet(&psh) != -1);
304 }
305
306 /* Control Panel Callback */
307 LONG CALLBACK
308 CPlApplet(HWND hwndCPl,
309 UINT uMsg,
310 LPARAM lParam1,
311 LPARAM lParam2)
312 {
313 switch (uMsg)
314 {
315 case CPL_INIT:
316 return TRUE;
317
318 case CPL_GETCOUNT:
319 return NUM_APPLETS;
320
321 case CPL_INQUIRE:
322 {
323 CPLINFO *CPlInfo = (CPLINFO*)lParam2;
324 CPlInfo->idIcon = Applets[0].idIcon;
325 CPlInfo->idName = Applets[0].idName;
326 CPlInfo->idInfo = Applets[0].idDescription;
327 break;
328 }
329
330 case CPL_DBLCLK:
331 InitApplet(hwndCPl, uMsg, lParam1, lParam2);
332 break;
333 }
334
335 return FALSE;
336 }
337
338
339 INT
340 WINAPI
341 DllMain(HINSTANCE hinstDLL,
342 DWORD dwReason,
343 LPVOID lpvReserved)
344 {
345 UNREFERENCED_PARAMETER(lpvReserved);
346
347 switch (dwReason)
348 {
349 case DLL_PROCESS_ATTACH:
350 case DLL_THREAD_ATTACH:
351 hApplet = hinstDLL;
352 break;
353 }
354
355 return TRUE;
356 }