2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Server DLL
4 * FILE: win32ss/user/consrv/guisettings.c
5 * PURPOSE: GUI terminal emulator settings management
6 * PROGRAMMERS: Hermes Belusca - Maito
9 /* INCLUDES *******************************************************************/
14 #include "guiconsole.h"
15 #include "guisettings.h"
21 VOID
GuiConsoleMoveWindow(PGUI_CONSOLE_DATA GuiData
);
23 /* FUNCTIONS ******************************************************************/
26 GuiConsoleReadUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo
,
27 IN LPCWSTR ConsoleTitle
,
30 /*****************************************************
31 * Adapted from ConSrvReadUserSettings in settings.c *
32 *****************************************************/
36 DWORD dwNumSubKeys
= 0;
39 WCHAR szValueName
[MAX_PATH
];
41 WCHAR szValue
[LF_FACESIZE
] = L
"\0";
45 if (!ConSrvOpenUserSettings(ProcessId
,
50 DPRINT("ConSrvOpenUserSettings failed\n");
54 if (RegQueryInfoKey(hKey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
55 &dwNumSubKeys
, NULL
, NULL
, NULL
, NULL
) != ERROR_SUCCESS
)
57 DPRINT("GuiConsoleReadUserSettings: RegQueryInfoKey failed\n");
62 DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys
);
64 for (dwIndex
= 0; dwIndex
< dwNumSubKeys
; dwIndex
++)
66 dwValue
= sizeof(Value
);
67 dwValueName
= MAX_PATH
; // sizeof(szValueName)/sizeof(szValueName[0])
69 if (RegEnumValueW(hKey
, dwIndex
, szValueName
, &dwValueName
, NULL
, &dwType
, (BYTE
*)&Value
, &dwValue
) != ERROR_SUCCESS
)
74 * Retry in case of string value
76 dwValue
= sizeof(szValue
);
77 dwValueName
= MAX_PATH
; // sizeof(szValueName)/sizeof(szValueName[0])
78 if (RegEnumValueW(hKey
, dwIndex
, szValueName
, &dwValueName
, NULL
, NULL
, (BYTE
*)szValue
, &dwValue
) != ERROR_SUCCESS
)
87 if (!wcscmp(szValueName
, L
"FaceName"))
89 wcsncpy(TermInfo
->FaceName
, szValue
, LF_FACESIZE
);
92 else if (!wcscmp(szValueName
, L
"FontFamily"))
94 TermInfo
->FontFamily
= Value
;
97 else if (!wcscmp(szValueName
, L
"FontSize"))
99 TermInfo
->FontSize
= Value
;
102 else if (!wcscmp(szValueName
, L
"FontWeight"))
104 TermInfo
->FontWeight
= Value
;
107 else if (!wcscmp(szValueName
, L
"WindowPosition"))
109 TermInfo
->AutoPosition
= FALSE
;
110 TermInfo
->WindowOrigin
.x
= LOWORD(Value
);
111 TermInfo
->WindowOrigin
.y
= HIWORD(Value
);
121 GuiConsoleWriteUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo
,
122 IN LPCWSTR ConsoleTitle
,
125 /******************************************************
126 * Adapted from ConSrvWriteUserSettings in settings.c *
127 ******************************************************/
129 BOOL GlobalSettings
= (ConsoleTitle
[0] == L
'\0');
133 #define SetConsoleSetting(SettingName, SettingType, SettingSize, Setting, DefaultValue) \
135 if (GlobalSettings || (!GlobalSettings && (*(Setting) != (DefaultValue)))) \
137 RegSetValueExW(hKey, (SettingName), 0, (SettingType), (PBYTE)(Setting), (SettingSize)); \
141 RegDeleteValue(hKey, (SettingName)); \
145 if (!ConSrvOpenUserSettings(ProcessId
,
153 SetConsoleSetting(L
"FaceName", REG_SZ
, (wcslen(TermInfo
->FaceName
) + 1) * sizeof(WCHAR
), TermInfo
->FaceName
, L
'\0');
154 SetConsoleSetting(L
"FontFamily", REG_DWORD
, sizeof(DWORD
), &TermInfo
->FontFamily
, FF_DONTCARE
);
155 SetConsoleSetting(L
"FontSize", REG_DWORD
, sizeof(DWORD
), &TermInfo
->FontSize
, 0);
156 SetConsoleSetting(L
"FontWeight", REG_DWORD
, sizeof(DWORD
), &TermInfo
->FontWeight
, FW_DONTCARE
);
158 if (TermInfo
->AutoPosition
== FALSE
)
160 Storage
= MAKELONG(TermInfo
->WindowOrigin
.x
, TermInfo
->WindowOrigin
.y
);
161 RegSetValueExW(hKey
, L
"WindowPosition", 0, REG_DWORD
, (PBYTE
)&Storage
, sizeof(DWORD
));
165 RegDeleteValue(hKey
, L
"WindowPosition");
173 GuiConsoleGetDefaultSettings(IN OUT PGUI_CONSOLE_INFO TermInfo
,
176 /*******************************************************
177 * Adapted from ConSrvGetDefaultSettings in settings.c *
178 *******************************************************/
180 if (TermInfo
== NULL
) return;
183 * 1. Load the default values
185 // wcsncpy(TermInfo->FaceName, L"DejaVu Sans Mono", LF_FACESIZE);
186 // TermInfo->FontSize = MAKELONG(12, 8); // 0x0008000C; // font is 8x12
187 // TermInfo->FontSize = MAKELONG(16, 16); // font is 16x16
188 // TermInfo->FontWeight = FW_NORMAL;
190 wcsncpy(TermInfo
->FaceName
, L
"Fixedsys", LF_FACESIZE
); // HACK: !!
191 // TermInfo->FaceName[0] = L'\0';
192 TermInfo
->FontFamily
= FF_DONTCARE
;
193 TermInfo
->FontSize
= 0;
194 TermInfo
->FontWeight
= FW_DONTCARE
;
195 TermInfo
->UseRasterFonts
= TRUE
;
197 TermInfo
->ShowWindow
= SW_SHOWNORMAL
;
198 TermInfo
->AutoPosition
= TRUE
;
199 TermInfo
->WindowOrigin
= (POINT
){0, 0};
202 * 2. Overwrite them with the ones stored in HKCU\Console.
203 * If the HKCU\Console key doesn't exist, create it
204 * and store the default values inside.
206 if (!GuiConsoleReadUserSettings(TermInfo
, L
"", ProcessId
))
208 GuiConsoleWriteUserSettings(TermInfo
, L
"", ProcessId
);
213 GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData
,
217 PCONSOLE Console
= GuiData
->Console
;
218 PCONSOLE_PROCESS_DATA ProcessData
;
219 HANDLE hSection
= NULL
, hClientSection
= NULL
;
220 LARGE_INTEGER SectionSize
;
223 PCONSOLE_PROPS pSharedInfo
= NULL
;
224 PGUI_CONSOLE_INFO GuiInfo
= NULL
;
226 DPRINT("GuiConsoleShowConsoleProperties entered\n");
229 * Create a memory section to share with the applet, and map it.
231 /* Holds data for console.dll + console info + terminal-specific info */
232 SectionSize
.QuadPart
= sizeof(CONSOLE_PROPS
) + sizeof(GUI_CONSOLE_INFO
);
233 Status
= NtCreateSection(&hSection
,
240 if (!NT_SUCCESS(Status
))
242 DPRINT1("Error: Impossible to create a shared section ; Status = %lu\n", Status
);
246 Status
= NtMapViewOfSection(hSection
,
248 (PVOID
*)&pSharedInfo
,
256 if (!NT_SUCCESS(Status
))
258 DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status
);
265 * Setup the shared console properties structure.
269 pSharedInfo
->hConsoleWindow
= GuiData
->hWindow
;
270 pSharedInfo
->ShowDefaultParams
= Defaults
;
272 /* Console information */
273 pSharedInfo
->ci
.HistoryBufferSize
= Console
->HistoryBufferSize
;
274 pSharedInfo
->ci
.NumberOfHistoryBuffers
= Console
->NumberOfHistoryBuffers
;
275 pSharedInfo
->ci
.HistoryNoDup
= Console
->HistoryNoDup
;
276 pSharedInfo
->ci
.FullScreen
= Console
->FullScreen
;
277 pSharedInfo
->ci
.QuickEdit
= Console
->QuickEdit
;
278 pSharedInfo
->ci
.InsertMode
= Console
->InsertMode
;
279 pSharedInfo
->ci
.InputBufferSize
= 0;
280 pSharedInfo
->ci
.ScreenBufferSize
= Console
->ActiveBuffer
->ScreenBufferSize
;
281 pSharedInfo
->ci
.ConsoleSize
= Console
->ConsoleSize
;
282 pSharedInfo
->ci
.CursorBlinkOn
;
283 pSharedInfo
->ci
.ForceCursorOff
;
284 pSharedInfo
->ci
.CursorSize
= Console
->ActiveBuffer
->CursorInfo
.dwSize
;
285 pSharedInfo
->ci
.ScreenAttrib
= Console
->ActiveBuffer
->ScreenDefaultAttrib
;
286 pSharedInfo
->ci
.PopupAttrib
= Console
->ActiveBuffer
->PopupDefaultAttrib
;
287 pSharedInfo
->ci
.CodePage
;
289 /* GUI Information */
290 pSharedInfo
->TerminalInfo
.Size
= sizeof(GUI_CONSOLE_INFO
);
291 GuiInfo
= pSharedInfo
->TerminalInfo
.TermInfo
= (PGUI_CONSOLE_INFO
)(pSharedInfo
+ 1);
292 wcsncpy(GuiInfo
->FaceName
, GuiData
->GuiInfo
.FaceName
, LF_FACESIZE
);
293 GuiInfo
->FontSize
= (DWORD
)GuiData
->GuiInfo
.FontSize
;
294 GuiInfo
->FontWeight
= GuiData
->GuiInfo
.FontWeight
;
295 GuiInfo
->UseRasterFonts
= GuiData
->GuiInfo
.UseRasterFonts
;
296 /// GuiInfo->WindowPosition = GuiData->GuiInfo.WindowPosition;
297 GuiInfo
->AutoPosition
= GuiData
->GuiInfo
.AutoPosition
;
298 GuiInfo
->WindowOrigin
= GuiData
->GuiInfo
.WindowOrigin
;
300 pSharedInfo
->TerminalInfo
.TermInfo
= (PVOID
)((ULONG_PTR
)GuiInfo
- (ULONG_PTR
)pSharedInfo
);
303 memcpy(pSharedInfo
->ci
.Colors
, Console
->Colors
, sizeof(Console
->Colors
));
305 /* Title of the console, original one corresponding to the one set by the console leader */
306 Length
= min(sizeof(pSharedInfo
->ci
.ConsoleTitle
) / sizeof(pSharedInfo
->ci
.ConsoleTitle
[0]) - 1,
307 Console
->OriginalTitle
.Length
/ sizeof(WCHAR
));
308 wcsncpy(pSharedInfo
->ci
.ConsoleTitle
, Console
->OriginalTitle
.Buffer
, Length
);
309 pSharedInfo
->ci
.ConsoleTitle
[Length
] = L
'\0';
313 NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo
);
315 /* Get the console leader process, our client */
316 ProcessData
= CONTAINING_RECORD(Console
->ProcessList
.Blink
,
317 CONSOLE_PROCESS_DATA
,
320 /* Duplicate the section handle for the client */
321 Status
= NtDuplicateObject(NtCurrentProcess(),
323 ProcessData
->Process
->ProcessHandle
,
325 0, 0, DUPLICATE_SAME_ACCESS
);
326 if (!NT_SUCCESS(Status
))
328 DPRINT1("Error: Impossible to duplicate section handle for client ; Status = %lu\n", Status
);
333 /* Start the properties dialog */
334 if (ProcessData
->PropDispatcher
)
338 Thread
= CreateRemoteThread(ProcessData
->Process
->ProcessHandle
, NULL
, 0,
339 ProcessData
->PropDispatcher
,
340 (PVOID
)hClientSection
, 0, NULL
);
343 DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
347 DPRINT1("We succeeded at creating ProcessData->PropDispatcher remote thread, ProcessId = %x, Process = 0x%p\n", ProcessData
->Process
->ClientId
.UniqueProcess
, ProcessData
->Process
);
348 /// WaitForSingleObject(Thread, INFINITE);
352 /* We have finished, close the section handle */
358 GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData
,
359 HANDLE hClientSection
,
362 NTSTATUS Status
= STATUS_SUCCESS
;
363 PCONSOLE Console
= GuiData
->Console
;
364 PCONSOLE_PROCESS_DATA ProcessData
;
365 HANDLE hSection
= NULL
;
367 PCONSOLE_PROPS pConInfo
= NULL
;
368 PCONSOLE_INFO ConInfo
= NULL
;
369 PTERMINAL_INFO TermInfo
= NULL
;
370 PGUI_CONSOLE_INFO GuiInfo
= NULL
;
372 /// LOCK /// EnterCriticalSection(&Console->Lock);
374 /* Get the console leader process, our client */
375 ProcessData
= CONTAINING_RECORD(Console
->ProcessList
.Blink
,
376 CONSOLE_PROCESS_DATA
,
379 /* Duplicate the section handle for ourselves */
380 Status
= NtDuplicateObject(ProcessData
->Process
->ProcessHandle
,
384 0, 0, DUPLICATE_SAME_ACCESS
);
385 if (!NT_SUCCESS(Status
))
387 DPRINT1("Error when mapping client handle, Status = %lu\n", Status
);
391 /* Get a view of the shared section */
392 Status
= NtMapViewOfSection(hSection
,
402 if (!NT_SUCCESS(Status
))
404 DPRINT1("Error when mapping view of file, Status = %lu\n", Status
);
409 /* Check that the section is well-sized */
410 if ( (ViewSize
< sizeof(CONSOLE_PROPS
)) ||
411 (pConInfo
->TerminalInfo
.Size
!= sizeof(GUI_CONSOLE_INFO
)) ||
412 (ViewSize
< sizeof(CONSOLE_PROPS
) + pConInfo
->TerminalInfo
.Size
) )
414 DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_PROPS) + sizeof(Terminal_specific_info)\n");
415 Status
= STATUS_INVALID_VIEW_SIZE
;
419 // TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow
421 /* Set the console informations */
422 ConInfo
= &pConInfo
->ci
;
423 ConSrvApplyUserSettings(Console
, ConInfo
);
425 /* Set the terminal informations - De-offsetization of the pointer */
426 TermInfo
= &pConInfo
->TerminalInfo
;
427 GuiInfo
= TermInfo
->TermInfo
= (PVOID
)((ULONG_PTR
)pConInfo
+ (ULONG_PTR
)TermInfo
->TermInfo
);
429 // memcpy(&GuiData->GuiInfo, GuiInfo, sizeof(GUI_CONSOLE_INFO));
431 /* Move the window to the user's values */
432 GuiData
->GuiInfo
.AutoPosition
= GuiInfo
->AutoPosition
;
433 GuiData
->GuiInfo
.WindowOrigin
= GuiInfo
->WindowOrigin
;
434 GuiConsoleMoveWindow(GuiData
);
436 InvalidateRect(GuiData
->hWindow
, NULL
, TRUE
);
440 * Save settings if needed
443 // FIXME: Do it in the console properties applet ??
446 DWORD ProcessId
= HandleToUlong(ProcessData
->Process
->ClientId
.UniqueProcess
);
447 ConSrvWriteUserSettings(ConInfo
, ProcessId
);
448 GuiConsoleWriteUserSettings(GuiInfo
, ConInfo
->ConsoleTitle
, ProcessId
);
451 Status
= STATUS_SUCCESS
;
453 /// LOCK /// LeaveCriticalSection(&Console->Lock);
456 /* Finally, close the section and return */
457 NtUnmapViewOfSection(NtCurrentProcess(), pConInfo
);