[CONSOLE][CONSRV]
[reactos.git] / win32ss / user / winsrv / consrv / frontends / gui / guisettings.c
index c579fb5..3220152 100644 (file)
@@ -9,14 +9,13 @@
 
 /* INCLUDES *******************************************************************/
 
-#include "consrv.h"
-#include "include/conio.h"
-#include "include/settings.h"
-#include "guisettings.h"
+#include <consrv.h>
 
 #define NDEBUG
 #include <debug.h>
 
+#include "guiterm.h"
+#include "guisettings.h"
 
 VOID GuiConsoleMoveWindow(PGUI_CONSOLE_DATA GuiData);
 VOID SwitchFullScreen(PGUI_CONSOLE_DATA GuiData, BOOL FullScreen);
@@ -99,7 +98,8 @@ GuiConsoleReadUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
         }
         else if (!wcscmp(szValueName, L"FontSize"))
         {
-            TermInfo->FontSize = Value;
+            TermInfo->FontSize.X = LOWORD(Value);
+            TermInfo->FontSize.Y = HIWORD(Value);
             RetVal = TRUE;
         }
         else if (!wcscmp(szValueName, L"FontWeight"))
@@ -114,7 +114,7 @@ GuiConsoleReadUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
         }
         else if (!wcscmp(szValueName, L"WindowPosition"))
         {
-            TermInfo->AutoPosition = FALSE;
+            TermInfo->AutoPosition   = FALSE;
             TermInfo->WindowOrigin.x = LOWORD(Value);
             TermInfo->WindowOrigin.y = HIWORD(Value);
             RetVal = TRUE;
@@ -160,7 +160,10 @@ do {
 
     SetConsoleSetting(L"FaceName", REG_SZ, (wcslen(TermInfo->FaceName) + 1) * sizeof(WCHAR), TermInfo->FaceName, L'\0'); // wcsnlen
     SetConsoleSetting(L"FontFamily", REG_DWORD, sizeof(DWORD), &TermInfo->FontFamily, FF_DONTCARE);
-    SetConsoleSetting(L"FontSize", REG_DWORD, sizeof(DWORD), &TermInfo->FontSize, 0);
+
+    Storage = MAKELONG(TermInfo->FontSize.X, TermInfo->FontSize.Y);
+    SetConsoleSetting(L"FontSize", REG_DWORD, sizeof(DWORD), &Storage, 0);
+
     SetConsoleSetting(L"FontWeight", REG_DWORD, sizeof(DWORD), &TermInfo->FontWeight, FW_DONTCARE);
 
     Storage = TermInfo->FullScreen;
@@ -198,10 +201,11 @@ GuiConsoleGetDefaultSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
     // TermInfo->FontSize = MAKELONG(16, 16); // font is 16x16
     // TermInfo->FontWeight = FW_NORMAL;
 
-    wcsncpy(TermInfo->FaceName, L"Fixedsys", LF_FACESIZE); // HACK: !!
+    wcsncpy(TermInfo->FaceName, L"VGA", LF_FACESIZE); // HACK: !!
     // TermInfo->FaceName[0] = L'\0';
     TermInfo->FontFamily = FF_DONTCARE;
-    TermInfo->FontSize   = 0;
+    TermInfo->FontSize.X = 0;
+    TermInfo->FontSize.Y = 0;
     TermInfo->FontWeight = FW_DONTCARE;
     TermInfo->UseRasterFonts = TRUE;
 
@@ -239,6 +243,8 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
 
     DPRINT("GuiConsoleShowConsoleProperties entered\n");
 
+    if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
+
     /*
      * Create a memory section to share with the applet, and map it.
      */
@@ -254,7 +260,7 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Error: Impossible to create a shared section ; Status = %lu\n", Status);
-        return;
+        goto Quit;
     }
 
     Status = NtMapViewOfSection(hSection,
@@ -270,8 +276,7 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status);
-        NtClose(hSection);
-        return;
+        goto Quit;
     }
 
 
@@ -330,7 +335,6 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
         GuiInfo->FontWeight = GuiData->GuiInfo.FontWeight;
         GuiInfo->UseRasterFonts = GuiData->GuiInfo.UseRasterFonts;
         GuiInfo->FullScreen = GuiData->GuiInfo.FullScreen;
-        /// GuiInfo->WindowPosition = GuiData->GuiInfo.WindowPosition;
         GuiInfo->AutoPosition = GuiData->GuiInfo.AutoPosition;
         GuiInfo->WindowOrigin = GuiData->GuiInfo.WindowOrigin;
         /* Offsetize */
@@ -358,9 +362,7 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
     NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo);
 
     /* Get the console leader process, our client */
-    ProcessData = CONTAINING_RECORD(Console->ProcessList.Blink,
-                                    CONSOLE_PROCESS_DATA,
-                                    ConsoleLink);
+    ProcessData = ConSrvGetConsoleLeaderProcess(Console);
 
     /* Duplicate the section handle for the client */
     Status = NtDuplicateObject(NtCurrentProcess(),
@@ -412,11 +414,13 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
 
 Quit:
     /* We have finished, close the section handle */
-    NtClose(hSection);
+    if (hSection) NtClose(hSection);
+
+    LeaveCriticalSection(&Console->Lock);
     return;
 }
 
-NTSTATUS
+VOID
 GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
                      HANDLE hClientSection,
                      BOOL SaveSettings)
@@ -431,10 +435,10 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
     PTERMINAL_INFO TermInfo = NULL;
     PGUI_CONSOLE_INFO GuiInfo = NULL;
 
+    if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
+
     /* Get the console leader process, our client */
-    ProcessData = CONTAINING_RECORD(Console->ProcessList.Blink,
-                                    CONSOLE_PROCESS_DATA,
-                                    ConsoleLink);
+    ProcessData = ConSrvGetConsoleLeaderProcess(Console);
 
     /* Duplicate the section handle for ourselves */
     Status = NtDuplicateObject(ProcessData->Process->ProcessHandle,
@@ -445,7 +449,7 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Error when mapping client handle, Status = %lu\n", Status);
-        return Status;
+        goto Quit;
     }
 
     /* Get a view of the shared section */
@@ -458,12 +462,11 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
                                 &ViewSize,
                                 ViewUnmap,
                                 0,
-                                PAGE_READONLY);
+                                PAGE_READWRITE);
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Error when mapping view of file, Status = %lu\n", Status);
-        NtClose(hSection);
-        return Status;
+        goto Quit;
     }
 
     _SEH2_TRY
@@ -536,9 +539,190 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
 
 Quit:
     /* Finally, close the section and return */
-    NtUnmapViewOfSection(NtCurrentProcess(), pConInfo);
-    NtClose(hSection);
-    return Status;
+    if (hSection)
+    {
+        NtUnmapViewOfSection(NtCurrentProcess(), pConInfo);
+        NtClose(hSection);
+    }
+
+    LeaveCriticalSection(&Console->Lock);
+    return;
+}
+
+/*
+ * Function for dealing with the undocumented message and structure used by
+ * Windows' console.dll for setting console info.
+ * See http://www.catch22.net/sites/default/source/files/setconsoleinfo.c
+ * and http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf
+ * for more information.
+ */
+VOID
+GuiApplyWindowsConsoleSettings(PGUI_CONSOLE_DATA GuiData,
+                               HANDLE hClientSection)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    PCONSOLE Console = GuiData->Console;
+    PCONSOLE_PROCESS_DATA ProcessData;
+    HANDLE hSection = NULL;
+    ULONG ViewSize = 0;
+    PCONSOLE_STATE_INFO pConInfo = NULL;
+    CONSOLE_INFO     ConInfo;
+    GUI_CONSOLE_INFO GuiInfo;
+    SIZE_T Length;
+
+    if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
+
+    /* Get the console leader process, our client */
+    ProcessData = ConSrvGetConsoleLeaderProcess(Console);
+
+    /* Duplicate the section handle for ourselves */
+    Status = NtDuplicateObject(ProcessData->Process->ProcessHandle,
+                               hClientSection,
+                               NtCurrentProcess(),
+                               &hSection,
+                               0, 0, DUPLICATE_SAME_ACCESS);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Error when mapping client handle, Status = %lu\n", Status);
+        goto Quit;
+    }
+
+    /* Get a view of the shared section */
+    Status = NtMapViewOfSection(hSection,
+                                NtCurrentProcess(),
+                                (PVOID*)&pConInfo,
+                                0,
+                                0,
+                                NULL,
+                                &ViewSize,
+                                ViewUnmap,
+                                0,
+                                PAGE_READWRITE);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Error when mapping view of file, Status = %lu\n", Status);
+        goto Quit;
+    }
+
+    _SEH2_TRY
+    {
+        /* Check that the section is well-sized */
+        if ( (ViewSize < sizeof(CONSOLE_STATE_INFO)) ||
+             (pConInfo->cbSize != sizeof(CONSOLE_STATE_INFO)) )
+        {
+            DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_STATE_INFO)\n");
+            Status = STATUS_INVALID_VIEW_SIZE;
+            _SEH2_YIELD(goto Quit);
+        }
+
+        // TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow
+
+        /* Retrieve terminal informations */
+
+        // Console information
+        ConInfo.HistoryBufferSize = pConInfo->HistoryBufferSize;
+        ConInfo.NumberOfHistoryBuffers = pConInfo->NumberOfHistoryBuffers;
+        ConInfo.HistoryNoDup = !!pConInfo->HistoryNoDup;
+        ConInfo.QuickEdit = !!pConInfo->QuickEdit;
+        ConInfo.InsertMode = !!pConInfo->InsertMode;
+        ConInfo.ScreenBufferSize = pConInfo->ScreenBufferSize;
+        ConInfo.ConsoleSize = pConInfo->WindowSize;
+        ConInfo.CursorSize = pConInfo->CursorSize;
+        ConInfo.ScreenAttrib = pConInfo->ScreenColors;
+        ConInfo.PopupAttrib = pConInfo->PopupColors;
+        memcpy(&ConInfo.Colors, pConInfo->ColorTable, sizeof(ConInfo.Colors));
+        ConInfo.CodePage = pConInfo->CodePage;
+        /**ConInfo.ConsoleTitle[MAX_PATH + 1] = pConInfo->ConsoleTitle; // FIXME: memcpy**/
+#if 0
+        /* Title of the console, original one corresponding to the one set by the console leader */
+        Length = min(sizeof(pConInfo->ConsoleTitle) / sizeof(pConInfo->ConsoleTitle[0]) - 1,
+               Console->OriginalTitle.Length / sizeof(WCHAR));
+        wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length);
+#endif
+        // ULONG   ConInfo.InputBufferSize = pConInfo->
+        // BOOLEAN ConInfo.CursorBlinkOn = pConInfo->
+        // BOOLEAN ConInfo.ForceCursorOff = pConInfo->
+
+
+        // Terminal information
+        Length = min(wcslen(pConInfo->FaceName) + 1, LF_FACESIZE); // wcsnlen
+        wcsncpy(GuiInfo.FaceName, pConInfo->FaceName, LF_FACESIZE);
+        GuiInfo.FaceName[Length] = L'\0';
+
+        GuiInfo.FontFamily = pConInfo->FontFamily;
+        GuiInfo.FontSize = pConInfo->FontSize;
+        GuiInfo.FontWeight = pConInfo->FontWeight;
+        GuiInfo.FullScreen = !!pConInfo->FullScreen;
+        GuiInfo.AutoPosition = !!pConInfo->AutoPosition;
+        GuiInfo.WindowOrigin = pConInfo->WindowPosition;
+        // BOOL  GuiInfo.UseRasterFonts = pConInfo->
+        // WORD  GuiInfo.ShowWindow = pConInfo->
+
+
+
+        /*
+         * If we don't set the default parameters,
+         * apply them, otherwise just save them.
+         */
+#if 0
+        if (pConInfo->ShowDefaultParams == FALSE)
+#endif
+        {
+            /* Set the console informations */
+            ConSrvApplyUserSettings(Console, &ConInfo);
+
+            /* Set the terminal informations */
+
+            // memcpy(&GuiData->GuiInfo, &GuiInfo, sizeof(GUI_CONSOLE_INFO));
+
+            /* Move the window to the user's values */
+            GuiData->GuiInfo.AutoPosition = GuiInfo.AutoPosition;
+            GuiData->GuiInfo.WindowOrigin = GuiInfo.WindowOrigin;
+            GuiConsoleMoveWindow(GuiData);
+
+            InvalidateRect(GuiData->hWindow, NULL, TRUE);
+
+            /*
+             * Apply full-screen mode.
+             */
+            if (GuiInfo.FullScreen != GuiData->GuiInfo.FullScreen)
+            {
+                SwitchFullScreen(GuiData, GuiInfo.FullScreen);
+            }
+        }
+
+#if 0
+        /*
+         * Save settings if needed
+         */
+        // FIXME: Do it in the console properties applet ??
+        if (SaveSettings)
+        {
+            DWORD ProcessId = HandleToUlong(ProcessData->Process->ClientId.UniqueProcess);
+            ConSrvWriteUserSettings(&ConInfo, ProcessId);
+            GuiConsoleWriteUserSettings(&GuiInfo, ConInfo.ConsoleTitle, ProcessId);
+        }
+#endif
+
+        Status = STATUS_SUCCESS;
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = _SEH2_GetExceptionCode();
+        DPRINT1("GuiApplyUserSettings - Caught an exception, Status = %08X\n", Status);
+    }
+    _SEH2_END;
+
+Quit:
+    /* Finally, close the section and return */
+    if (hSection)
+    {
+        NtUnmapViewOfSection(NtCurrentProcess(), pConInfo);
+        NtClose(hSection);
+    }
+
+    LeaveCriticalSection(&Console->Lock);
+    return;
 }
 
 /* EOF */