[CONSOLE][CONSRV]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Wed, 6 Aug 2014 20:49:10 +0000 (20:49 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Wed, 6 Aug 2014 20:49:10 +0000 (20:49 +0000)
- Implement the undocumented WM_SETCONSOLEINFO window message (the equivalent of our PM_APPLY_CONSOLE_INFO), sent
  by the Windows' console control panel applet console.dll, when applying new console settings to the current opened console
  (and its associated data structure CONSOLE_STATE_INFO).
  This is used by the FAR plugin MinCE by Andrew Grechkin (see http://code.google.com/p/andrew-grechkin/source/browse/trunk/MinCE/src/setconsoleinfo.cpp for example)
- Convert GUI_CONSOLE_INFO::FontSize to COORD, as it should be.

See: http://www.catch22.net/sites/default/source/files/setconsoleinfo.c and http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf for more information.

svn path=/branches/condrv_restructure/; revision=63819

dll/cpl/console/console.c
dll/cpl/console/layout.c
win32ss/user/winsrv/consrv/frontends/gui/conwnd.c
win32ss/user/winsrv/consrv/frontends/gui/guisettings.c
win32ss/user/winsrv/consrv/frontends/gui/guisettings.h
win32ss/user/winsrv/consrv/include/settings.h

index e0c4978..d26c23b 100644 (file)
@@ -115,7 +115,8 @@ InitConsoleDefaults(PCONSOLE_PROPS pConInfo)
     wcsncpy(GuiInfo->FaceName, L"VGA", LF_FACESIZE); // HACK: !!
     // GuiInfo->FaceName[0] = L'\0';
     GuiInfo->FontFamily = FF_DONTCARE;
-    GuiInfo->FontSize = 0;
+    GuiInfo->FontSize.X = 0;
+    GuiInfo->FontSize.Y = 0;
     GuiInfo->FontWeight = FW_DONTCARE;
     GuiInfo->UseRasterFonts = TRUE;
 
index 6651bb4..41ebc31 100644 (file)
@@ -120,8 +120,8 @@ PaintText(LPDRAWITEMSTRUCT drawItem,
     hBrush = CreateSolidBrush(nbkColor);
     if (!hBrush) return FALSE;
 
-    Font = CreateFontW(LOWORD(GuiInfo->FontSize),
-                       0, // HIWORD(GuiInfo->FontSize),
+    Font = CreateFontW(GuiInfo->FontSize.X,
+                       0, // GuiInfo->FontSize.Y,
                        0,
                        TA_BASELINE,
                        GuiInfo->FontWeight,
index 68d6579..e401037 100644 (file)
@@ -506,8 +506,8 @@ OnNcCreate(HWND hWnd, LPCREATESTRUCTW Create)
 
     GuiData->hWindow = hWnd;
 
-    GuiData->Font = CreateFontW(LOWORD(GuiData->GuiInfo.FontSize),
-                                0, // HIWORD(GuiData->GuiInfo.FontSize),
+    GuiData->Font = CreateFontW(GuiData->GuiInfo.FontSize.X,
+                                0, // GuiData->GuiInfo.FontSize.Y,
                                 0,
                                 TA_BASELINE,
                                 GuiData->GuiInfo.FontWeight,
@@ -2321,6 +2321,18 @@ ConWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
             break;
         }
 
+        /*
+         * Undocumented message sent by Windows' console.dll for applying 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.
+         */
+        case WM_SETCONSOLEINFO:
+        {
+            GuiApplyWindowsConsoleSettings(GuiData, (HANDLE)wParam);
+            break;
+        }
+
         case PM_CONSOLE_BEEP:
             DPRINT1("Beep !!\n");
             Beep(800, 200);
index ce84523..3220152 100644 (file)
@@ -98,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"))
@@ -159,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;
@@ -200,7 +204,8 @@ GuiConsoleGetDefaultSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
     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;
 
@@ -544,4 +549,180 @@ Quit:
     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 */
index 6681425..ff8a912 100644 (file)
 #ifndef WM_APP
     #define WM_APP 0x8000
 #endif
-#define PM_APPLY_CONSOLE_INFO (WM_APP + 100)
+/* Message sent by ReactOS' console.dll for applying console info */
+#define PM_APPLY_CONSOLE_INFO   (WM_APP + 100)
+
+/*
+ * Undocumented message sent by Windows' console.dll for applying 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.
+ */
+#define WM_SETCONSOLEINFO       (WM_USER + 201)
 
 /* STRUCTURES *****************************************************************/
 
@@ -22,9 +31,9 @@ typedef struct _GUI_CONSOLE_INFO
 {
     // FONTSIGNATURE FontSignature;
     WCHAR FaceName[LF_FACESIZE];
-    UINT  FontFamily;
-    DWORD FontSize;
-    DWORD FontWeight;
+    ULONG FontFamily;
+    COORD FontSize;
+    ULONG FontWeight;
     BOOL  UseRasterFonts;
 
     BOOL  FullScreen;       /* Whether the console is displayed in full-screen or windowed mode */
@@ -35,6 +44,46 @@ typedef struct _GUI_CONSOLE_INFO
     POINT WindowOrigin;
 } GUI_CONSOLE_INFO, *PGUI_CONSOLE_INFO;
 
+/*
+ * Undocumented 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.
+ */
+#pragma pack(push, 1)
+typedef struct _CONSOLE_STATE_INFO
+{
+    ULONG       cbSize;
+    COORD       ScreenBufferSize;
+    COORD       WindowSize;
+    POINT       WindowPosition; // WindowPosX and Y
+
+    COORD       FontSize;
+    ULONG       FontFamily;
+    ULONG       FontWeight;
+    WCHAR       FaceName[LF_FACESIZE];
+
+    ULONG       CursorSize;
+    BOOL        FullScreen;
+    BOOL        QuickEdit;
+    BOOL        AutoPosition;
+    BOOL        InsertMode;
+
+    USHORT      ScreenColors;   // ScreenAttributes
+    USHORT      PopupColors;    // PopupAttributes
+    BOOL        HistoryNoDup;
+    ULONG       HistoryBufferSize;
+    ULONG       NumberOfHistoryBuffers;
+
+    COLORREF    ColorTable[16];
+
+    ULONG       CodePage;
+    HWND        HWnd;
+
+    WCHAR       ConsoleTitle[256];
+} CONSOLE_STATE_INFO, *PCONSOLE_STATE_INFO;
+#pragma pack(pop)
+
 #ifndef CONSOLE_H__ // If we aren't included by console.dll
 
 #include "conwnd.h"
@@ -59,6 +108,9 @@ VOID
 GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
                      HANDLE hClientSection,
                      BOOL SaveSettings);
+VOID
+GuiApplyWindowsConsoleSettings(PGUI_CONSOLE_DATA GuiData,
+                               HANDLE hClientSection);
 
 #endif
 
index f538460..be00e50 100644 (file)
@@ -11,6 +11,8 @@
 
 /* STRUCTURES *****************************************************************/
 
+#pragma pack(push, 1)
+
 /*
  * Structure used to hold terminal-specific information
  */
@@ -69,6 +71,8 @@ typedef struct _CONSOLE_PROPS
     TERMINAL_INFO TerminalInfo; /* Frontend-specific parameters  */
 } CONSOLE_PROPS, *PCONSOLE_PROPS;
 
+#pragma pack(pop)
+
 /* FUNCTIONS ******************************************************************/
 
 #ifndef CONSOLE_H__ // If we aren't included by console.dll