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