[CONSOLE][CONSRV]
[reactos.git] / dll / cpl / console / console.c
index 70f688b..d26c23b 100644 (file)
@@ -2,12 +2,16 @@
  * PROJECT:         ReactOS Console Configuration DLL
  * LICENSE:         GPL - See COPYING in the top level directory
  * FILE:            dll/win32/console/console.c
- * PURPOSE:         initialization of DLL
- * PROGRAMMERS:     Johannes Anderwald (johannes.anderwald@student.tugraz.at)
+ * PURPOSE:         Initialization
+ * PROGRAMMERS:     Johannes Anderwald (johannes.anderwald@reactos.org)
+ *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
  */
 
 #include "console.h"
 
+#define NDEBUG
+#include <debug.h>
+
 #define NUM_APPLETS 1
 
 LONG APIENTRY InitApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam);
@@ -56,16 +60,16 @@ const COLORREF s_Colors[16] =
 #define CSR_DEFAULT_CURSOR_SIZE 25
 
 static VOID
-InitPropSheetPage(PROPSHEETPAGE *psp,
+InitPropSheetPage(PROPSHEETPAGEW *psp,
                   WORD idDlg,
                   DLGPROC DlgProc,
                   LPARAM lParam)
 {
-    ZeroMemory(psp, sizeof(PROPSHEETPAGE));
-    psp->dwSize = sizeof(PROPSHEETPAGE);
+    ZeroMemory(psp, sizeof(PROPSHEETPAGEW));
+    psp->dwSize = sizeof(PROPSHEETPAGEW);
     psp->dwFlags = PSP_DEFAULT;
     psp->hInstance = hApplet;
-    psp->pszTemplate = MAKEINTRESOURCE(idDlg);
+    psp->pszTemplate = MAKEINTRESOURCEW(idDlg);
     psp->pfnDlgProc = DlgProc;
     psp->lParam = lParam;
 }
@@ -73,22 +77,30 @@ InitPropSheetPage(PROPSHEETPAGE *psp,
 PCONSOLE_PROPS
 AllocConsoleInfo()
 {
-    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CONSOLE_PROPS));
+    /* Adapted for holding GUI terminal information */
+    return HeapAlloc(GetProcessHeap(),
+                     HEAP_ZERO_MEMORY,
+                     sizeof(CONSOLE_PROPS) + sizeof(GUI_CONSOLE_INFO));
 }
 
 VOID
 InitConsoleDefaults(PCONSOLE_PROPS pConInfo)
 {
+    PGUI_CONSOLE_INFO GuiInfo = NULL;
+
+    /* FIXME: Get also the defaults from the registry */
+
     /* Initialize the default properties */
     pConInfo->ci.HistoryBufferSize = 50;
     pConInfo->ci.NumberOfHistoryBuffers = 4;
     pConInfo->ci.HistoryNoDup = FALSE;
-    pConInfo->ci.FullScreen = FALSE;
     pConInfo->ci.QuickEdit = FALSE;
     pConInfo->ci.InsertMode = TRUE;
     // pConInfo->ci.InputBufferSize;
-    pConInfo->ci.ScreenBufferSize = (COORD){80, 300};
-    pConInfo->ci.ConsoleSize = (COORD){80, 25};
+    pConInfo->ci.ScreenBufferSize.X = 80;
+    pConInfo->ci.ScreenBufferSize.Y = 300;
+    pConInfo->ci.ConsoleSize.X = 80;
+    pConInfo->ci.ConsoleSize.Y = 25;
     pConInfo->ci.CursorBlinkOn = TRUE;
     pConInfo->ci.ForceCursorOff = FALSE;
     pConInfo->ci.CursorSize = CSR_DEFAULT_CURSOR_SIZE;
@@ -97,14 +109,22 @@ InitConsoleDefaults(PCONSOLE_PROPS pConInfo)
     pConInfo->ci.CodePage = 0;
     pConInfo->ci.ConsoleTitle[0] = L'\0';
 
-    pConInfo->ci.u.GuiInfo.FaceName[0] = L'\0';
-    pConInfo->ci.u.GuiInfo.FontFamily = FF_DONTCARE;
-    pConInfo->ci.u.GuiInfo.FontSize = 0;
-    pConInfo->ci.u.GuiInfo.FontWeight = FW_DONTCARE;
-    pConInfo->ci.u.GuiInfo.UseRasterFonts = TRUE;
-
-    pConInfo->ci.u.GuiInfo.AutoPosition = TRUE;
-    pConInfo->ci.u.GuiInfo.WindowOrigin = (POINT){0, 0};
+    /* Adapted for holding GUI terminal information */
+    pConInfo->TerminalInfo.Size = sizeof(GUI_CONSOLE_INFO);
+    GuiInfo = pConInfo->TerminalInfo.TermInfo = (PGUI_CONSOLE_INFO)(pConInfo + 1);
+    wcsncpy(GuiInfo->FaceName, L"VGA", LF_FACESIZE); // HACK: !!
+    // GuiInfo->FaceName[0] = L'\0';
+    GuiInfo->FontFamily = FF_DONTCARE;
+    GuiInfo->FontSize.X = 0;
+    GuiInfo->FontSize.Y = 0;
+    GuiInfo->FontWeight = FW_DONTCARE;
+    GuiInfo->UseRasterFonts = TRUE;
+
+    GuiInfo->FullScreen   = FALSE;
+    GuiInfo->ShowWindow   = SW_SHOWNORMAL;
+    GuiInfo->AutoPosition = TRUE;
+    GuiInfo->WindowOrigin.x = 0;
+    GuiInfo->WindowOrigin.y = 0;
 
     memcpy(pConInfo->ci.Colors, s_Colors, sizeof(s_Colors));
 }
@@ -116,24 +136,20 @@ ApplyProc(HWND hwndDlg,
           WPARAM wParam,
           LPARAM lParam)
 {
-    HWND hDlgCtrl;
-
     UNREFERENCED_PARAMETER(lParam);
 
     switch (uMsg)
     {
         case WM_INITDIALOG:
         {
-            hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_APPLY_CURRENT);
-            SendMessage(hDlgCtrl, BM_SETCHECK, BST_CHECKED, 0);
+            CheckDlgButton(hwndDlg, IDC_RADIO_APPLY_CURRENT, BST_CHECKED);
             return TRUE;
         }
         case WM_COMMAND:
         {
             if (LOWORD(wParam) == IDOK)
             {
-                hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_APPLY_CURRENT);
-                if (SendMessage(hDlgCtrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_APPLY_CURRENT) == BST_CHECKED)
                     EndDialog(hwndDlg, IDC_RADIO_APPLY_CURRENT);
                 else
                     EndDialog(hwndDlg, IDC_RADIO_APPLY_ALL);
@@ -155,37 +171,58 @@ BOOL
 ApplyConsoleInfo(HWND hwndDlg,
                  PCONSOLE_PROPS pConInfo)
 {
-    INT_PTR res = 0;
+    BOOL SetParams  = FALSE;
+    BOOL SaveParams = FALSE;
 
-    res = DialogBox(hApplet, MAKEINTRESOURCE(IDD_APPLYOPTIONS), hwndDlg, ApplyProc);
-    if (res == IDCANCEL)
+    /*
+     * If we are setting the default parameters, just save them,
+     * otherwise display the save-confirmation dialog.
+     */
+    if (pConInfo->ShowDefaultParams)
     {
-        /* Don't destroy when user presses cancel */
-        SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
-        return TRUE;
+        SetParams  = TRUE;
+        SaveParams = TRUE;
     }
-    else if (res == IDC_RADIO_APPLY_ALL || res == IDC_RADIO_APPLY_CURRENT)
+    else
+    {
+        INT_PTR res = DialogBoxW(hApplet, MAKEINTRESOURCEW(IDD_APPLYOPTIONS), hwndDlg, ApplyProc);
+
+        SetParams  = (res != IDCANCEL);
+        SaveParams = (res == IDC_RADIO_APPLY_ALL);
+
+        if (SetParams == FALSE)
+        {
+            /* Don't destroy when user presses cancel */
+            SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
+            // return TRUE;
+        }
+    }
+
+    if (SetParams)
     {
         HANDLE hSection;
         PCONSOLE_PROPS pSharedInfo;
 
-        /* Create a memory section to share with the server, and map it */
-        hSection = CreateFileMapping(INVALID_HANDLE_VALUE,
-                                     NULL,
-                                     PAGE_READWRITE,
-                                     0,
-                                     sizeof(CONSOLE_PROPS),
-                                     NULL);
+        /*
+         * Create a memory section to share with the server, and map it.
+         */
+        /* Holds data for console.dll + console info + terminal-specific info */
+        hSection = CreateFileMappingW(INVALID_HANDLE_VALUE,
+                                      NULL,
+                                      PAGE_READWRITE,
+                                      0,
+                                      sizeof(CONSOLE_PROPS) + sizeof(GUI_CONSOLE_INFO),
+                                      NULL);
         if (!hSection)
         {
-            // DPRINT1("Error when creating file mapping, error = %d\n", GetLastError());
+            DPRINT1("Error when creating file mapping, error = %d\n", GetLastError());
             return FALSE;
         }
 
         pSharedInfo = MapViewOfFile(hSection, FILE_MAP_ALL_ACCESS, 0, 0, 0);
         if (!pSharedInfo)
         {
-            // DPRINT1("Error when mapping view of file, error = %d\n", GetLastError());
+            DPRINT1("Error when mapping view of file, error = %d\n", GetLastError());
             CloseHandle(hSection);
             return FALSE;
         }
@@ -193,8 +230,15 @@ ApplyConsoleInfo(HWND hwndDlg,
         /* We are applying the chosen configuration */
         pConInfo->AppliedConfig = TRUE;
 
-        /* Copy the console info into the section */
-        RtlCopyMemory(pSharedInfo, pConInfo, sizeof(CONSOLE_PROPS));
+        /*
+         * Copy the console information into the section and
+         * offsetize the address of terminal-specific information.
+         * Do not perform the offsetization in pConInfo as it is
+         * likely to be reused later on. Instead, do it in pSharedInfo
+         * after having copied all the data.
+         */
+        RtlCopyMemory(pSharedInfo, pConInfo, sizeof(CONSOLE_PROPS) + sizeof(GUI_CONSOLE_INFO));
+        pSharedInfo->TerminalInfo.TermInfo = (PVOID)((ULONG_PTR)pConInfo->TerminalInfo.TermInfo - (ULONG_PTR)pConInfo);
 
         /* Unmap it */
         UnmapViewOfFile(pSharedInfo);
@@ -204,11 +248,10 @@ ApplyConsoleInfo(HWND hwndDlg,
         SendMessage(pConInfo->hConsoleWindow,
                     PM_APPLY_CONSOLE_INFO,
                     (WPARAM)hSection,
-                    (LPARAM)(res == IDC_RADIO_APPLY_ALL));
+                    (LPARAM)SaveParams);
 
         /* Close the section and return */
         CloseHandle(hSection);
-        return TRUE;
     }
 
     return TRUE;
@@ -219,11 +262,11 @@ LONG APIENTRY
 InitApplet(HWND hWnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
 {
     HANDLE hSection = (HANDLE)wParam;
-    PCONSOLE_PROPS pSharedInfo;
+    PCONSOLE_PROPS pSharedInfo = NULL;
     PCONSOLE_PROPS pConInfo;
     WCHAR szTitle[MAX_PATH + 1];
-    PROPSHEETPAGE psp[4];
-    PROPSHEETHEADER psh;
+    PROPSHEETPAGEW psp[4];
+    PROPSHEETHEADERW psh;
     INT i = 0;
 
     UNREFERENCED_PARAMETER(uMsg);
@@ -239,47 +282,71 @@ InitApplet(HWND hWnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
     pConInfo = AllocConsoleInfo();
     if (!pConInfo) return 0;
 
-    /* Map the shared section */
-    pSharedInfo = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0);
-    if (pSharedInfo == NULL)
+    /* Check whether we were launched from the terminal... */
+    if (hSection != NULL)
     {
-        HeapFree(GetProcessHeap(), 0, pConInfo);
-        return 0;
-    }
+        /* ... yes, map the shared section */
+        pSharedInfo = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0);
+        if (pSharedInfo == NULL)
+        {
+            /* Cleanup */
+            HeapFree(GetProcessHeap(), 0, pConInfo);
+
+            /* Close the section */
+            CloseHandle(hSection);
 
-    // if (IsBadReadPtr((PVOID)pSharedInfo, sizeof(CONSOLE_PROPS)))
-    // {
-    // }
+            return 0;
+        }
 
-    /* Find the console window and whether we must use default parameters */
-    pConInfo->hConsoleWindow    = pSharedInfo->hConsoleWindow;
-    pConInfo->ShowDefaultParams = pSharedInfo->ShowDefaultParams;
+        /* Find the console window and whether we set the default parameters */
+        pConInfo->hConsoleWindow    = pSharedInfo->hConsoleWindow;
+        pConInfo->ShowDefaultParams = pSharedInfo->ShowDefaultParams;
+    }
+    else
+    {
+        /* ... no, we were launched as a CPL. Display the default settings. */
+        pConInfo->ShowDefaultParams = TRUE;
+    }
 
     if (pConInfo->ShowDefaultParams)
     {
         /* Use defaults */
         InitConsoleDefaults(pConInfo);
     }
-    else
+    else if (hSection && pSharedInfo)
     {
-        /* Copy the shared data into our allocated buffer */
-        RtlCopyMemory(pConInfo, pSharedInfo, sizeof(CONSOLE_PROPS));
+        /*
+         * Copy the shared data into our allocated buffer, and
+         * de-offsetize the address of terminal-specific information.
+         */
+
+        /* Check that we are really going to modify GUI terminal information */
+        // FIXME: Do something clever, for example copy the UI-independent part
+        // and init the UI-dependent part to some default values...
+        ASSERT(pSharedInfo->TerminalInfo.Size == sizeof(GUI_CONSOLE_INFO));
+        ASSERT(pSharedInfo->TerminalInfo.TermInfo);
+
+        RtlCopyMemory(pConInfo, pSharedInfo, sizeof(CONSOLE_PROPS) + sizeof(GUI_CONSOLE_INFO));
+        pConInfo->TerminalInfo.TermInfo = (PVOID)((ULONG_PTR)pConInfo + (ULONG_PTR)pConInfo->TerminalInfo.TermInfo);
     }
 
-    /* Close the section */
-    UnmapViewOfFile(pSharedInfo);
-    CloseHandle(hSection);
+    if (hSection && pSharedInfo)
+    {
+        /* Close the section */
+        UnmapViewOfFile(pSharedInfo);
+        CloseHandle(hSection);
+    }
 
     /* Initialize the property sheet structure */
-    ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
-    psh.dwSize = sizeof(PROPSHEETHEADER);
+    ZeroMemory(&psh, sizeof(PROPSHEETHEADERW));
+    psh.dwSize = sizeof(PROPSHEETHEADERW);
     psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | /* PSH_USEHICON */ PSH_USEICONID | PSH_NOAPPLYNOW;
 
     if (pConInfo->ci.ConsoleTitle[0] != L'\0')
     {
-        wcsncpy(szTitle, L"\"", sizeof(szTitle) / sizeof(szTitle[0]));
-        wcsncat(szTitle, pConInfo->ci.ConsoleTitle, sizeof(szTitle) / sizeof(szTitle[0]));
-        wcsncat(szTitle, L"\"", sizeof(szTitle) / sizeof(szTitle[0]));
+        wcsncpy(szTitle, L"\"", MAX_PATH);
+        wcsncat(szTitle, pConInfo->ci.ConsoleTitle, MAX_PATH - wcslen(szTitle));
+        wcsncat(szTitle, L"\"", MAX_PATH - wcslen(szTitle));
     }
     else
     {
@@ -289,18 +356,18 @@ InitApplet(HWND hWnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
 
     psh.hwndParent = pConInfo->hConsoleWindow;
     psh.hInstance = hApplet;
-    // psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON));
-    psh.pszIcon = MAKEINTRESOURCE(IDC_CPLICON);
+    // psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCEW(IDC_CPLICON));
+    psh.pszIcon = MAKEINTRESOURCEW(IDC_CPLICON);
     psh.nPages = 4;
     psh.nStartPage = 0;
     psh.ppsp = psp;
 
     InitPropSheetPage(&psp[i++], IDD_PROPPAGEOPTIONS, (DLGPROC) OptionsProc, (LPARAM)pConInfo);
-    InitPropSheetPage(&psp[i++], IDD_PROPPAGEFONT, (DLGPROC) FontProc, (LPARAM)pConInfo);
-    InitPropSheetPage(&psp[i++], IDD_PROPPAGELAYOUT, (DLGPROC) LayoutProc, (LPARAM)pConInfo);
-    InitPropSheetPage(&psp[i++], IDD_PROPPAGECOLORS, (DLGPROC) ColorsProc, (LPARAM)pConInfo);
+    InitPropSheetPage(&psp[i++], IDD_PROPPAGEFONT   , (DLGPROC) FontProc   , (LPARAM)pConInfo);
+    InitPropSheetPage(&psp[i++], IDD_PROPPAGELAYOUT , (DLGPROC) LayoutProc , (LPARAM)pConInfo);
+    InitPropSheetPage(&psp[i++], IDD_PROPPAGECOLORS , (DLGPROC) ColorsProc , (LPARAM)pConInfo);
 
-    return (PropertySheet(&psh) != -1);
+    return (PropertySheetW(&psh) != -1);
 }
 
 /* Control Panel Callback */
@@ -315,15 +382,19 @@ CPlApplet(HWND hwndCPl,
         case CPL_INIT:
             return TRUE;
 
+        case CPL_EXIT:
+            // TODO: Free allocated memory
+            break;
+
         case CPL_GETCOUNT:
             return NUM_APPLETS;
 
         case CPL_INQUIRE:
         {
             CPLINFO *CPlInfo = (CPLINFO*)lParam2;
-            CPlInfo->idIcon = Applets[0].idIcon;
-            CPlInfo->idName = Applets[0].idName;
-            CPlInfo->idInfo = Applets[0].idDescription;
+            CPlInfo->idIcon  = Applets[0].idIcon;
+            CPlInfo->idName  = Applets[0].idName;
+            CPlInfo->idInfo  = Applets[0].idDescription;
             break;
         }