2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Server DLL
4 * FILE: consrv/frontends/gui/guisettings.c
5 * PURPOSE: GUI Terminal Front-End Settings Management
6 * PROGRAMMERS: Johannes Anderwald
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
10 /* INCLUDES *******************************************************************/
18 #include "guisettings.h"
20 /* FUNCTIONS ******************************************************************/
23 GuiConsoleReadUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo
)
30 GuiConsoleWriteUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo
)
37 GuiConsoleGetDefaultSettings(IN OUT PGUI_CONSOLE_INFO TermInfo
)
43 GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData
,
47 PCONSRV_CONSOLE Console
= GuiData
->Console
;
48 PCONSOLE_PROCESS_DATA ProcessData
;
49 HANDLE hSection
= NULL
, hClientSection
= NULL
;
50 PVOID ThreadParameter
= NULL
; // Is either hClientSection or the console window handle,
51 // depending on whether we display the default settings or
52 // the settings of a particular console.
54 DPRINT("GuiConsoleShowConsoleProperties entered\n");
56 if (!ConDrvValidateConsoleUnsafe((PCONSOLE
)Console
, CONSOLE_RUNNING
, TRUE
)) return;
58 /* Get the console leader process, our client */
59 ProcessData
= ConSrvGetConsoleLeaderProcess(Console
);
62 * Be sure we effectively have a properties dialog routine (that launches
63 * the console control panel applet). It resides in kernel32.dll (client).
65 if (ProcessData
->PropRoutine
== NULL
) goto Quit
;
68 * Create a memory section to be shared with the console control panel applet
69 * in the case we are displaying the settings of a particular console.
70 * In that case the ThreadParameter is the hClientSection handle.
71 * In the case we display the default console parameters, we don't need to
72 * create a memory section. We just need to open the applet, and in this case
73 * the ThreadParameter is the parent window handle of the applet's window,
74 * that is, the console window.
78 PCONSOLE_SCREEN_BUFFER ActiveBuffer
= GuiData
->ActiveBuffer
;
79 LARGE_INTEGER SectionSize
;
81 PCONSOLE_STATE_INFO pSharedInfo
= NULL
;
84 * Create a memory section to share with the applet, and map it.
86 SectionSize
.QuadPart
= sizeof(CONSOLE_STATE_INFO
); // Standard size
87 SectionSize
.QuadPart
+= Console
->OriginalTitle
.Length
; // Add the length in bytes of the console title string
89 Status
= NtCreateSection(&hSection
,
96 if (!NT_SUCCESS(Status
))
98 DPRINT1("Error: Impossible to create a shared section, Status = 0x%08lx\n", Status
);
102 Status
= NtMapViewOfSection(hSection
,
104 (PVOID
*)&pSharedInfo
,
112 if (!NT_SUCCESS(Status
))
114 DPRINT1("Error: Impossible to map the shared section, Status = 0x%08lx\n", Status
);
120 * Setup the shared console properties structure.
123 /* Store the real size of the structure */
124 pSharedInfo
->cbSize
= SectionSize
.QuadPart
;
127 * When we setup the settings of a particular console, the parent window
128 * of the applet's window is the console window, and it is given via the
129 * hWnd member of the shared console info structure.
131 pSharedInfo
->hWnd
= GuiData
->hWindow
;
133 /* Console information */
134 pSharedInfo
->HistoryBufferSize
= Console
->HistoryBufferSize
;
135 pSharedInfo
->NumberOfHistoryBuffers
= Console
->NumberOfHistoryBuffers
;
136 pSharedInfo
->HistoryNoDup
= Console
->HistoryNoDup
;
137 pSharedInfo
->QuickEdit
= Console
->QuickEdit
;
138 pSharedInfo
->InsertMode
= Console
->InsertMode
;
139 /// pSharedInfo->InputBufferSize = 0;
140 pSharedInfo
->ScreenBufferSize
= ActiveBuffer
->ScreenBufferSize
;
141 pSharedInfo
->WindowSize
= ActiveBuffer
->ViewSize
;
142 pSharedInfo
->CursorSize
= ActiveBuffer
->CursorInfo
.dwSize
;
143 if (GetType(ActiveBuffer
) == TEXTMODE_BUFFER
)
145 PTEXTMODE_SCREEN_BUFFER Buffer
= (PTEXTMODE_SCREEN_BUFFER
)ActiveBuffer
;
147 pSharedInfo
->ScreenAttributes
= Buffer
->ScreenDefaultAttrib
;
148 pSharedInfo
->PopupAttributes
= Buffer
->PopupDefaultAttrib
;
150 else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
152 // PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)ActiveBuffer;
153 DPRINT1("GuiConsoleShowConsoleProperties - Graphics buffer\n");
155 // FIXME: Gather defaults from the registry ?
156 pSharedInfo
->ScreenAttributes
= DEFAULT_SCREEN_ATTRIB
;
157 pSharedInfo
->PopupAttributes
= DEFAULT_POPUP_ATTRIB
;
159 /// pSharedInfo->CodePage;
161 /* GUI Information */
162 wcsncpy(pSharedInfo
->FaceName
, GuiData
->GuiInfo
.FaceName
, LF_FACESIZE
);
163 pSharedInfo
->FaceName
[LF_FACESIZE
- 1] = UNICODE_NULL
;
164 pSharedInfo
->FontFamily
= GuiData
->GuiInfo
.FontFamily
;
165 pSharedInfo
->FontSize
= GuiData
->GuiInfo
.FontSize
;
166 pSharedInfo
->FontWeight
= GuiData
->GuiInfo
.FontWeight
;
167 pSharedInfo
->FullScreen
= GuiData
->GuiInfo
.FullScreen
;
168 pSharedInfo
->AutoPosition
= GuiData
->GuiInfo
.AutoPosition
;
169 pSharedInfo
->WindowPosition
= GuiData
->GuiInfo
.WindowOrigin
;
172 RtlCopyMemory(pSharedInfo
->ColorTable
,
173 Console
->Colors
, sizeof(Console
->Colors
));
175 /* Copy the original title of the console and null-terminate it */
176 RtlCopyMemory(pSharedInfo
->ConsoleTitle
,
177 Console
->OriginalTitle
.Buffer
,
178 Console
->OriginalTitle
.Length
);
180 pSharedInfo
->ConsoleTitle
[Console
->OriginalTitle
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
184 NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo
);
186 /* Duplicate the section handle for the client */
187 Status
= NtDuplicateObject(NtCurrentProcess(),
189 ProcessData
->Process
->ProcessHandle
,
191 0, 0, DUPLICATE_SAME_ACCESS
);
192 if (!NT_SUCCESS(Status
))
194 DPRINT1("Error: Impossible to duplicate section handle for client, Status = 0x%08lx\n", Status
);
198 /* For the settings of a particular console, use the shared client section handle as the thread parameter */
199 ThreadParameter
= (PVOID
)hClientSection
;
203 /* For the default settings, use the console window handle as the thread parameter */
204 ThreadParameter
= (PVOID
)GuiData
->hWindow
;
207 /* Start the console control panel applet */
210 HANDLE Thread
= NULL
;
214 Thread
= CreateRemoteThread(ProcessData
->Process
->ProcessHandle
, NULL
, 0,
215 ProcessData
->PropRoutine
,
216 ThreadParameter
, 0, NULL
);
219 DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
223 DPRINT("ProcessData->PropRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
224 ProcessData
->Process
->ClientId
.UniqueProcess
, ProcessData
->Process
);
233 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
235 Status
= _SEH2_GetExceptionCode();
236 DPRINT1("GuiConsoleShowConsoleProperties - Caught an exception, Status = 0x%08lx\n", Status
);
241 /* We have finished, close the section handle if any */
242 if (hSection
) NtClose(hSection
);
244 LeaveCriticalSection(&Console
->Lock
);
249 * Function for dealing with the undocumented message and structure used by
250 * Windows' console.dll for setting console info.
251 * See http://www.catch22.net/sites/default/source/files/setconsoleinfo.c
252 * and http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf
253 * for more information.
256 GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData
,
257 HANDLE hClientSection
)
259 NTSTATUS Status
= STATUS_SUCCESS
;
260 PCONSRV_CONSOLE Console
= GuiData
->Console
;
261 PCONSOLE_PROCESS_DATA ProcessData
;
262 HANDLE hSection
= NULL
;
264 PCONSOLE_STATE_INFO pConInfo
= NULL
;
266 if (!ConDrvValidateConsoleUnsafe((PCONSOLE
)Console
, CONSOLE_RUNNING
, TRUE
)) return;
268 /* Get the console leader process, our client */
269 ProcessData
= ConSrvGetConsoleLeaderProcess(Console
);
271 /* Duplicate the section handle for ourselves */
272 Status
= NtDuplicateObject(ProcessData
->Process
->ProcessHandle
,
276 0, 0, DUPLICATE_SAME_ACCESS
);
277 if (!NT_SUCCESS(Status
))
279 DPRINT1("Error when mapping client handle, Status = 0x%08lx\n", Status
);
283 /* Get a view of the shared section */
284 Status
= NtMapViewOfSection(hSection
,
294 if (!NT_SUCCESS(Status
))
296 DPRINT1("Error when mapping view of file, Status = 0x%08lx\n", Status
);
302 /* Check that the section is well-sized */
303 if ( (ViewSize
< sizeof(CONSOLE_STATE_INFO
)) ||
304 (pConInfo
->cbSize
< sizeof(CONSOLE_STATE_INFO
)) )
306 DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_STATE_INFO)\n");
307 Status
= STATUS_INVALID_VIEW_SIZE
;
308 _SEH2_YIELD(goto Quit
);
311 // TODO: Check that GuiData->hWindow == pConInfo->hWnd
313 /* Retrieve terminal informations */
315 /* Console information */
316 #if 0 // FIXME: Things not set
317 ConInfo
.HistoryBufferSize
= pConInfo
->HistoryBufferSize
;
318 ConInfo
.NumberOfHistoryBuffers
= pConInfo
->NumberOfHistoryBuffers
;
319 ConInfo
.HistoryNoDup
= !!pConInfo
->HistoryNoDup
;
320 ConInfo
.CodePage
= pConInfo
->CodePage
;
327 /* Set the console informations */
328 ConSrvApplyUserSettings(Console
, pConInfo
);
330 /* Set the terminal informations */
332 /* Change the font */
335 pConInfo
->FontFamily
,
337 pConInfo
->FontWeight
);
338 // HACK, needed because changing font may change the size of the window
339 /**/TermResizeTerminal(Console
);/**/
341 /* Move the window to the user's values */
342 GuiData
->GuiInfo
.AutoPosition
= !!pConInfo
->AutoPosition
;
343 GuiData
->GuiInfo
.WindowOrigin
= pConInfo
->WindowPosition
;
344 GuiConsoleMoveWindow(GuiData
);
346 InvalidateRect(GuiData
->hWindow
, NULL
, TRUE
);
349 * Apply full-screen mode.
351 if (!!pConInfo
->FullScreen
!= GuiData
->GuiInfo
.FullScreen
)
353 SwitchFullScreen(GuiData
, !!pConInfo
->FullScreen
);
357 * The settings are saved in the registry by console.dll itself, if needed.
361 // GuiConsoleWriteUserSettings(GuiInfo);
364 Status
= STATUS_SUCCESS
;
366 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
368 Status
= _SEH2_GetExceptionCode();
369 DPRINT1("GuiApplyUserSettings - Caught an exception, Status = 0x%08lx\n", Status
);
374 /* Finally, close the section and return */
377 NtUnmapViewOfSection(NtCurrentProcess(), pConInfo
);
381 LeaveCriticalSection(&Console
->Lock
);