From 28842d99ad7a915a791247f2a4dd7a712c714b28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 3 Mar 2013 15:35:12 +0000 Subject: [PATCH] [CONSOLE.DLL-KERNEL32-CONSRV] Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...) Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator). [CONSOLE.DLL] Fix retriving / setting colors.c and other things. [CONSRV.DLL] - Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog. - Few DPRINTs removed. svn path=/branches/ros-csrss/; revision=58415 --- dll/cpl/console/CMakeLists.txt | 1 + dll/cpl/console/colors.c | 299 +++-- dll/cpl/console/console.c | 510 ++++---- dll/cpl/console/console.h | 52 +- dll/cpl/console/font.c | 74 +- dll/cpl/console/lang/fr-FR.rc | 4 +- dll/cpl/console/layout.c | 110 +- dll/cpl/console/options.c | 75 +- dll/win32/kernel32/client/console/console.c | 12 +- dll/win32/kernel32/client/console/init.c | 123 +- dll/win32/kernel32/include/console.h | 8 +- include/reactos/subsys/win/conmsg.h | 17 +- win32ss/user/consrv/CMakeLists.txt | 4 +- win32ss/user/consrv/coninput.c | 67 +- win32ss/user/consrv/conio.h | 59 +- win32ss/user/consrv/conoutput.c | 298 ++--- win32ss/user/consrv/console.c | 292 +++-- win32ss/user/consrv/consrv.h | 7 +- win32ss/user/consrv/guiconsole.c | 1276 +++++++------------ win32ss/user/consrv/guiconsole.h | 4 +- win32ss/user/consrv/handle.c | 64 +- win32ss/user/consrv/init.c | 104 +- win32ss/user/consrv/lineinput.c | 16 +- win32ss/user/consrv/settings.c | 498 ++++++++ win32ss/user/consrv/settings.h | 91 ++ win32ss/user/consrv/tuiconsole.c | 742 +++++------ win32ss/user/consrv/tuiconsole.h | 6 +- 27 files changed, 2701 insertions(+), 2112 deletions(-) create mode 100644 win32ss/user/consrv/settings.c create mode 100644 win32ss/user/consrv/settings.h diff --git a/dll/cpl/console/CMakeLists.txt b/dll/cpl/console/CMakeLists.txt index 69fb3bb3d62..68331e8eead 100644 --- a/dll/cpl/console/CMakeLists.txt +++ b/dll/cpl/console/CMakeLists.txt @@ -1,4 +1,5 @@ +include_directories(${REACTOS_SOURCE_DIR}/win32ss/user/consrv) spec2def(console.dll console.spec) diff --git a/dll/cpl/console/colors.c b/dll/cpl/console/colors.c index 75b2ce502f6..ca964d6a139 100644 --- a/dll/cpl/console/colors.c +++ b/dll/cpl/console/colors.c @@ -8,64 +8,64 @@ #include "console.h" -static -BOOL -PaintStaticControls(HWND hwndDlg, PConsoleInfo pConInfo, LPDRAWITEMSTRUCT drawItem) +static BOOL +PaintStaticControls(HWND hwndDlg, + PCONSOLE_PROPS pConInfo, + LPDRAWITEMSTRUCT drawItem) { - HBRUSH hBrush; - DWORD index; + HBRUSH hBrush; + DWORD index; - index = drawItem->CtlID - IDC_STATIC_COLOR1; - hBrush = CreateSolidBrush(pConInfo->Colors[index]); - if (!hBrush) - { - return FALSE; - } + index = min(drawItem->CtlID - IDC_STATIC_COLOR1, + sizeof(pConInfo->ci.Colors) / sizeof(pConInfo->ci.Colors[0]) - 1); + hBrush = CreateSolidBrush(pConInfo->ci.Colors[index]); + if (!hBrush) + { + return FALSE; + } - FillRect(drawItem->hDC, &drawItem->rcItem, hBrush); + FillRect(drawItem->hDC, &drawItem->rcItem, hBrush); DeleteObject((HGDIOBJ)hBrush); - if (pConInfo->ActiveStaticControl == index) - { - DrawFocusRect(drawItem->hDC, &drawItem->rcItem); - } - return TRUE; + if (pConInfo->ActiveStaticControl == index) + { + DrawFocusRect(drawItem->hDC, &drawItem->rcItem); + } + + return TRUE; } -INT_PTR -CALLBACK -ColorsProc( - HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam -) +INT_PTR CALLBACK +ColorsProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { - PConsoleInfo pConInfo; - LPNMUPDOWN lpnmud; - LPPSHNOTIFY lppsn; + PCONSOLE_PROPS pConInfo; LPDRAWITEMSTRUCT drawItem; - DWORD red = MAXDWORD; - DWORD green = MAXDWORD; - DWORD blue = MAXDWORD; + DWORD colorIndex; + COLORREF color; - pConInfo = (PConsoleInfo) GetWindowLongPtr(hwndDlg, DWLP_USER); + pConInfo = (PCONSOLE_PROPS)GetWindowLongPtr(hwndDlg, DWLP_USER); - switch(uMsg) + switch (uMsg) { case WM_INITDIALOG: { - pConInfo = (PConsoleInfo) ((LPPROPSHEETPAGE)lParam)->lParam; + pConInfo = (PCONSOLE_PROPS)((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pConInfo); - SendMessage(GetDlgItem(hwndDlg, IDC_RADIO_SCREEN_BACKGROUND), BM_SETCHECK, BST_CHECKED, 0); + + /* Set the valid range of the colour indicators */ SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_COLOR_RED), UDM_SETRANGE, 0, (LPARAM)MAKELONG(255, 0)); SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_COLOR_GREEN), UDM_SETRANGE, 0, (LPARAM)MAKELONG(255, 0)); SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_COLOR_BLUE), UDM_SETRANGE, 0, (LPARAM)MAKELONG(255, 0)); - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(pConInfo->ScreenBackground), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(pConInfo->ScreenBackground), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(pConInfo->ScreenBackground), FALSE); + + /* Select by default the screen background option */ CheckRadioButton(hwndDlg, IDC_RADIO_SCREEN_TEXT, IDC_RADIO_POPUP_BACKGROUND, IDC_RADIO_SCREEN_BACKGROUND); + SendMessage(hwndDlg, WM_COMMAND, IDC_RADIO_SCREEN_BACKGROUND, 0); + return TRUE; } + case WM_DRAWITEM: { drawItem = (LPDRAWITEMSTRUCT)lParam; @@ -78,159 +78,198 @@ ColorsProc( PaintText(drawItem, pConInfo); return TRUE; } + break; } + case WM_NOTIFY: { - lpnmud = (LPNMUPDOWN) lParam; - lppsn = (LPPSHNOTIFY) lParam; + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + { + // LPPSHNOTIFY lppsn; + if (!pConInfo->AppliedConfig) + { + return ApplyConsoleInfo(hwndDlg, pConInfo); + } + else + { + /* Options have already been applied */ + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); + return TRUE; + } + break; + } - if (lppsn->hdr.code == PSN_APPLY) - { - if (!pConInfo->AppliedConfig) - { - ApplyConsoleInfo(hwndDlg, pConInfo); - } - else - { - /* Options have already been applied */ - SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR); - return TRUE; - } - return TRUE; - } + case UDN_DELTAPOS: + { + LPNMUPDOWN lpnmud = (LPNMUPDOWN)lParam; - if (lpnmud->hdr.idFrom == IDC_UPDOWN_COLOR_RED) - { - red = lpnmud->iPos; - } - else if (lpnmud->hdr.idFrom == IDC_UPDOWN_COLOR_GREEN) - { - green = lpnmud->iPos; - } - else if (lpnmud->hdr.idFrom == IDC_UPDOWN_COLOR_BLUE) - { - blue = lpnmud->iPos; - } - else - { - break; - } + /* Get the current color */ + colorIndex = pConInfo->ActiveStaticControl; + color = pConInfo->ci.Colors[colorIndex]; - if (red == MAXDWORD) - { - red = SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_COLOR_RED), UDM_GETPOS, 0, 0); - if (HIWORD(red)) - { - // TODO: Handle error - break; - } - red = LOBYTE(red); - } + if (lpnmud->hdr.idFrom == IDC_UPDOWN_COLOR_RED) + { + if (lpnmud->iPos < 0) lpnmud->iPos = 0; + else if (lpnmud->iPos > 255) lpnmud->iPos = 255; - if (green == MAXDWORD) - { - green = SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_COLOR_GREEN), UDM_GETPOS, 0, 0); - if (HIWORD(green)) - { - // TODO: Handle error - break; - } - green = LOBYTE(green); - } + color = RGB(lpnmud->iPos, GetGValue(color), GetBValue(color)); + } + else if (lpnmud->hdr.idFrom == IDC_UPDOWN_COLOR_GREEN) + { + if (lpnmud->iPos < 0) lpnmud->iPos = 0; + else if (lpnmud->iPos > 255) lpnmud->iPos = 255; + + color = RGB(GetRValue(color), lpnmud->iPos, GetBValue(color)); + } + else if (lpnmud->hdr.idFrom == IDC_UPDOWN_COLOR_BLUE) + { + if (lpnmud->iPos < 0) lpnmud->iPos = 0; + else if (lpnmud->iPos > 255) lpnmud->iPos = 255; + + color = RGB(GetRValue(color), GetGValue(color), lpnmud->iPos); + } + else + { + break; + } + + pConInfo->ci.Colors[colorIndex] = color; + InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + colorIndex), NULL, TRUE); + InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SCREEN_COLOR), NULL, TRUE); + InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_POPUP_COLOR), NULL, TRUE); + + PropSheet_Changed(GetParent(hwndDlg), hwndDlg); + break; + } + } - if (blue == MAXDWORD) - { - blue = SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_COLOR_BLUE), UDM_GETPOS, 0, 0); - if (HIWORD(blue)) - { - // TODO: Handle error - break; - } - blue = LOBYTE(blue); - } - pConInfo->Colors[pConInfo->ActiveStaticControl] = RGB(red, green, blue); - InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE); - InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SCREEN_COLOR), NULL, TRUE); - InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_POPUP_COLOR), NULL, TRUE); break; } + case WM_COMMAND: { - switch(LOWORD(wParam)) + switch (LOWORD(wParam)) { case IDC_RADIO_SCREEN_TEXT: { - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(pConInfo->ScreenText), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(pConInfo->ScreenText), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(pConInfo->ScreenText), FALSE); + /* Get the color of the screen foreground */ + colorIndex = TextAttribFromAttrib(pConInfo->ci.ScreenAttrib); + color = pConInfo->ci.Colors[colorIndex]; + + /* Set the values of the colour indicators */ + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(color), FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(color), FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(color), FALSE); + + InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE); + pConInfo->ActiveStaticControl = colorIndex; + InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE); InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SCREEN_COLOR), NULL, TRUE); InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_POPUP_COLOR), NULL, TRUE); break; } + case IDC_RADIO_SCREEN_BACKGROUND: { - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(pConInfo->ScreenBackground), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(pConInfo->ScreenBackground), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(pConInfo->ScreenBackground), FALSE); + /* Get the color of the screen background */ + colorIndex = BkgdAttribFromAttrib(pConInfo->ci.ScreenAttrib); + color = pConInfo->ci.Colors[colorIndex]; + + /* Set the values of the colour indicators */ + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(color), FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(color), FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(color), FALSE); + + InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE); + pConInfo->ActiveStaticControl = colorIndex; + InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE); InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SCREEN_COLOR), NULL, TRUE); InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_POPUP_COLOR), NULL, TRUE); break; } + case IDC_RADIO_POPUP_TEXT: { - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(pConInfo->PopupText), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(pConInfo->PopupText), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(pConInfo->PopupText), FALSE); + /* Get the color of the popup foreground */ + colorIndex = TextAttribFromAttrib(pConInfo->ci.PopupAttrib); + color = pConInfo->ci.Colors[colorIndex]; + + /* Set the values of the colour indicators */ + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(color), FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(color), FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(color), FALSE); + + InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE); + pConInfo->ActiveStaticControl = colorIndex; + InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE); InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SCREEN_COLOR), NULL, TRUE); InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_POPUP_COLOR), NULL, TRUE); break; } + case IDC_RADIO_POPUP_BACKGROUND: { - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(pConInfo->PopupBackground), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(pConInfo->PopupBackground), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(pConInfo->PopupBackground), FALSE); + /* Get the color of the popup background */ + colorIndex = BkgdAttribFromAttrib(pConInfo->ci.PopupAttrib); + color = pConInfo->ci.Colors[colorIndex]; + + /* Set the values of the colour indicators */ + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(color), FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(color), FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(color), FALSE); + + InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE); + pConInfo->ActiveStaticControl = colorIndex; + InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE); InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SCREEN_COLOR), NULL, TRUE); InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_POPUP_COLOR), NULL, TRUE); break; } } - if (HIWORD(wParam) == STN_CLICKED && LOWORD(wParam) >= IDC_STATIC_COLOR1 && LOWORD(wParam) <= IDC_STATIC_COLOR16) - { - DWORD index = LOWORD(wParam) - IDC_STATIC_COLOR1; - if (index == pConInfo->ActiveStaticControl) + if ( HIWORD(wParam) == STN_CLICKED && + IDC_STATIC_COLOR1 <= LOWORD(wParam) && LOWORD(wParam) <= IDC_STATIC_COLOR16 ) + { + colorIndex = LOWORD(wParam) - IDC_STATIC_COLOR1; + + if (colorIndex == pConInfo->ActiveStaticControl) { /* Same static control was re-clicked */ break; } - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(pConInfo->Colors[index]), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(pConInfo->Colors[index]), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(pConInfo->Colors[index]), FALSE); + color = pConInfo->ci.Colors[colorIndex]; + + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(color), FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(color), FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(color), FALSE); /* Update global struct */ if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_SCREEN_TEXT)) { - pConInfo->ScreenText = pConInfo->Colors[index]; + pConInfo->ci.ScreenAttrib = MakeAttrib(colorIndex, BkgdAttribFromAttrib(pConInfo->ci.ScreenAttrib)); } else if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_SCREEN_BACKGROUND)) { - pConInfo->ScreenBackground = pConInfo->Colors[index]; + pConInfo->ci.ScreenAttrib = MakeAttrib(TextAttribFromAttrib(pConInfo->ci.ScreenAttrib), colorIndex); } else if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_POPUP_TEXT)) { - pConInfo->PopupText = pConInfo->Colors[index]; + pConInfo->ci.PopupAttrib = MakeAttrib(colorIndex, BkgdAttribFromAttrib(pConInfo->ci.PopupAttrib)); } else if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_POPUP_BACKGROUND)) { - pConInfo->PopupBackground = pConInfo->Colors[index]; + pConInfo->ci.PopupAttrib = MakeAttrib(TextAttribFromAttrib(pConInfo->ci.PopupAttrib), colorIndex); } + + InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE); + pConInfo->ActiveStaticControl = colorIndex; InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE); - InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + index), NULL, TRUE); InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SCREEN_COLOR), NULL, TRUE); InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_POPUP_COLOR), NULL, TRUE); - pConInfo->ActiveStaticControl = index; + PropSheet_Changed(GetParent(hwndDlg), hwndDlg); break; } diff --git a/dll/cpl/console/console.c b/dll/cpl/console/console.c index c75a63dc0ca..83072c55430 100644 --- a/dll/cpl/console/console.c +++ b/dll/cpl/console/console.c @@ -8,9 +8,7 @@ #include "console.h" -#define NUM_APPLETS (1) -#define WM_SETCONSOLE (WM_USER+10) - +#define NUM_APPLETS 1 LONG APIENTRY InitApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam); INT_PTR CALLBACK OptionsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); @@ -23,286 +21,334 @@ HINSTANCE hApplet = 0; /* Applets */ APPLET Applets[NUM_APPLETS] = { - {IDC_CPLICON, IDS_CPLNAME, IDS_CPLDESCRIPTION, InitApplet} + {IDC_CPLICON, IDS_CPLNAME, IDS_CPLDESCRIPTION, InitApplet} }; -static COLORREF s_Colors[] = +/* + * Default 16-color palette for foreground and background + * (corresponding flags in comments). + */ +const COLORREF s_Colors[16] = { - RGB(0, 0, 0), - RGB(0, 0, 128), - RGB(0, 128, 0), - RGB(0, 128, 128), - RGB(128, 0, 0), - RGB(128, 0, 128), - RGB(128, 128, 0), - RGB(192, 192, 192), - RGB(128, 128, 128), - RGB(0, 0, 255), - RGB(0, 255, 0), - RGB(0, 255, 255), - RGB(255, 0, 0), - RGB(255, 0, 255), - RGB(255, 255, 0), - RGB(255, 255, 255) -}; + RGB(0, 0, 0), // (Black) + RGB(0, 0, 128), // BLUE + RGB(0, 128, 0), // GREEN + RGB(0, 128, 128), // BLUE | GREEN + RGB(128, 0, 0), // RED + RGB(128, 0, 128), // BLUE | RED + RGB(128, 128, 0), // GREEN | RED + RGB(192, 192, 192), // BLUE | GREEN | RED -static void -InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc, LPARAM lParam) + RGB(128, 128, 128), // (Grey) INTENSITY + RGB(0, 0, 255), // BLUE | INTENSITY + RGB(0, 255, 0), // GREEN | INTENSITY + RGB(0, 255, 255), // BLUE | GREEN | INTENSITY + RGB(255, 0, 0), // RED | INTENSITY + RGB(255, 0, 255), // BLUE | RED | INTENSITY + RGB(255, 255, 0), // GREEN | RED | INTENSITY + RGB(255, 255, 255) // BLUE | GREEN | RED | INTENSITY +}; +/* Default attributes */ +#define DEFAULT_SCREEN_ATTRIB (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED) +#define DEFAULT_POPUP_ATTRIB (FOREGROUND_BLUE | FOREGROUND_RED | \ + BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY) + +static VOID +InitPropSheetPage(PROPSHEETPAGE *psp, + WORD idDlg, + DLGPROC DlgProc, + LPARAM lParam) { - ZeroMemory(psp, sizeof(PROPSHEETPAGE)); - psp->dwSize = sizeof(PROPSHEETPAGE); - psp->dwFlags = PSP_DEFAULT; - psp->hInstance = hApplet; - psp->pszTemplate = MAKEINTRESOURCE(idDlg); - psp->pfnDlgProc = DlgProc; - psp->lParam = lParam; + ZeroMemory(psp, sizeof(PROPSHEETPAGE)); + psp->dwSize = sizeof(PROPSHEETPAGE); + psp->dwFlags = PSP_DEFAULT; + psp->hInstance = hApplet; + psp->pszTemplate = MAKEINTRESOURCE(idDlg); + psp->pfnDlgProc = DlgProc; + psp->lParam = lParam; } -PConsoleInfo +PCONSOLE_PROPS AllocConsoleInfo() { - PConsoleInfo pConInfo; - - pConInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ConsoleInfo)); - - return pConInfo; + return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CONSOLE_PROPS)); } -void -InitConsoleDefaults(PConsoleInfo pConInfo) +VOID +InitConsoleDefaults(PCONSOLE_PROPS pConInfo) { - /* Initialize struct */ - pConInfo->InsertMode = TRUE; - pConInfo->HistoryBufferSize = 50; - pConInfo->NumberOfHistoryBuffers = 5; - pConInfo->ScreenText = RGB(192, 192, 192); - pConInfo->ScreenBackground = RGB(0, 0, 0); - pConInfo->PopupText = RGB(128, 0, 128); - pConInfo->PopupBackground = RGB(255, 255, 255); - pConInfo->WindowSize = (DWORD)MAKELONG(80, 25); - pConInfo->WindowPosition = UINT_MAX; - pConInfo->ScreenBuffer = MAKELONG(80, 300); - pConInfo->UseRasterFonts = TRUE; - pConInfo->FontSize = (DWORD)MAKELONG(8, 12); - pConInfo->FontWeight = FW_NORMAL; - memcpy(pConInfo->Colors, s_Colors, sizeof(s_Colors)); -} + /* 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.CursorBlinkOn = TRUE; + pConInfo->ci.ForceCursorOff = FALSE; + pConInfo->ci.CursorSize = 0; + pConInfo->ci.ScreenAttrib = DEFAULT_SCREEN_ATTRIB; + pConInfo->ci.PopupAttrib = DEFAULT_POPUP_ATTRIB; + 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}; + + memcpy(pConInfo->ci.Colors, s_Colors, sizeof(s_Colors)); +} INT_PTR CALLBACK -ApplyProc( - HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam -) +ApplyProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { - HWND hDlgCtrl; + HWND hDlgCtrl; - UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(lParam); - switch(uMsg) - { - case WM_INITDIALOG: - { - hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_APPLY_CURRENT); - SendMessage(hDlgCtrl, BM_SETCHECK, BST_CHECKED, 0); - 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 ) - EndDialog(hwndDlg, IDC_RADIO_APPLY_CURRENT); - else - EndDialog(hwndDlg, IDC_RADIO_APPLY_ALL); - } - else if (LOWORD(wParam) == IDCANCEL) - { - EndDialog(hwndDlg, IDCANCEL); - } - break; - } - default: - break; - } - return FALSE; + switch (uMsg) + { + case WM_INITDIALOG: + { + hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_APPLY_CURRENT); + SendMessage(hDlgCtrl, BM_SETCHECK, BST_CHECKED, 0); + 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) + EndDialog(hwndDlg, IDC_RADIO_APPLY_CURRENT); + else + EndDialog(hwndDlg, IDC_RADIO_APPLY_ALL); + } + else if (LOWORD(wParam) == IDCANCEL) + { + EndDialog(hwndDlg, IDCANCEL); + } + break; + } + default: + break; + } + return FALSE; } -void -ApplyConsoleInfo(HWND hwndDlg, PConsoleInfo pConInfo) +BOOL +ApplyConsoleInfo(HWND hwndDlg, + PCONSOLE_PROPS pConInfo) { - INT_PTR res = 0; + INT_PTR res = 0; - res = DialogBox(hApplet, MAKEINTRESOURCE(IDD_APPLYOPTIONS), hwndDlg, ApplyProc); + res = DialogBox(hApplet, MAKEINTRESOURCE(IDD_APPLYOPTIONS), hwndDlg, ApplyProc); + if (res == IDCANCEL) + { + /* Don't destroy when user presses cancel */ + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); + return TRUE; + } + else if (res == IDC_RADIO_APPLY_ALL || res == IDC_RADIO_APPLY_CURRENT) + { + HANDLE hSection; + PCONSOLE_PROPS pSharedInfo; - if (res == IDCANCEL) - { - /* Don't destroy when user presses cancel */ - SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); - } - else if ( res == IDC_RADIO_APPLY_ALL ) - { - pConInfo->AppliedConfig = TRUE; - SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR); - SendMessage(pConInfo->hConsoleWindow, PM_APPLY_CONSOLE_INFO, (WPARAM)pConInfo, (LPARAM)TRUE); - } - else if ( res == IDC_RADIO_APPLY_CURRENT ) - { - pConInfo->AppliedConfig = TRUE; - SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR); - SendMessage(pConInfo->hConsoleWindow, PM_APPLY_CONSOLE_INFO, (WPARAM)pConInfo, (LPARAM)TRUE); - } + /* 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); + if (!hSection) + { + // 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()); + CloseHandle(hSection); + return FALSE; + } + + /* We are applying the chosen configuration */ + pConInfo->AppliedConfig = TRUE; + + /* Copy the console info into the section */ + RtlCopyMemory(pSharedInfo, pConInfo, sizeof(CONSOLE_PROPS)); + + /* Unmap it */ + UnmapViewOfFile(pSharedInfo); + + /* Signal to the console server that it can apply the new configuration */ + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); + SendMessage(pConInfo->hConsoleWindow, + PM_APPLY_CONSOLE_INFO, + (WPARAM)hSection, + (LPARAM)(res == IDC_RADIO_APPLY_ALL)); + + /* Close the section and return */ + CloseHandle(hSection); + return TRUE; + } + + return TRUE; } /* First Applet */ LONG APIENTRY -InitApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam) +InitApplet(HWND hWnd, UINT uMsg, LPARAM wParam, LPARAM lParam) { - PROPSHEETPAGE psp[4]; - PROPSHEETHEADER psh; - INT i=0; - PConsoleInfo pConInfo; - WCHAR szTitle[100]; - PConsoleInfo pSharedInfo = (PConsoleInfo)wParam; + HANDLE hSection = (HANDLE)wParam; + PCONSOLE_PROPS pSharedInfo; + PCONSOLE_PROPS pConInfo; + WCHAR szTitle[MAX_PATH + 1]; + PROPSHEETPAGE psp[4]; + PROPSHEETHEADER psh; + INT i = 0; - UNREFERENCED_PARAMETER(uMsg); + UNREFERENCED_PARAMETER(uMsg); - /* - * console.dll shares information with win32csr with wParam, lParam - * - * wParam is a pointer to a ConsoleInfo struct - * lParam is a boolean parameter which specifies whether defaults should be shown - */ + /* + * CONSOLE.DLL shares information with CONSRV with wParam: + * wParam is a handle to a shared section holding a CONSOLE_PROPS struct. + * + * NOTE: lParam is not used. + */ - pConInfo = AllocConsoleInfo(); - if (!pConInfo) - { - return 0; - } + /* Allocate a local buffer to hold console information */ + pConInfo = AllocConsoleInfo(); + if (!pConInfo) return 0; - if (lParam) - { - /* Use defaults */ - InitConsoleDefaults(pConInfo); - } - else - { - if (IsBadReadPtr((const void *)pSharedInfo, sizeof(ConsoleInfo))) - { - /* Use defaults */ - InitConsoleDefaults(pConInfo); - } - else - { - pConInfo->InsertMode = pSharedInfo->InsertMode; - pConInfo->HistoryBufferSize = pSharedInfo->HistoryBufferSize; - pConInfo->NumberOfHistoryBuffers = pSharedInfo->NumberOfHistoryBuffers; - pConInfo->ScreenText = pSharedInfo->ScreenText; - pConInfo->ScreenBackground = pSharedInfo->ScreenBackground; - pConInfo->PopupText = pSharedInfo->PopupText; - pConInfo->PopupBackground = pSharedInfo->PopupBackground; - pConInfo->WindowSize = pSharedInfo->WindowSize; - pConInfo->WindowPosition = pSharedInfo->WindowPosition; - pConInfo->ScreenBuffer = pSharedInfo->ScreenBuffer; - pConInfo->UseRasterFonts = pSharedInfo->UseRasterFonts; - pConInfo->FontSize = pSharedInfo->FontSize; - pConInfo->FontWeight = pSharedInfo->FontWeight; - memcpy(pConInfo->Colors, pSharedInfo->Colors, sizeof(s_Colors)); - } - } + /* Map the shared section */ + pSharedInfo = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0); + if (pSharedInfo == NULL) + { + HeapFree(GetProcessHeap(), 0, pConInfo); + return 0; + } - /* console window -> is notified on a property change event */ - pConInfo->hConsoleWindow = hwnd; + // if (IsBadReadPtr((PVOID)pSharedInfo, sizeof(CONSOLE_PROPS))) + // { + // } - ZeroMemory(&psh, sizeof(PROPSHEETHEADER)); - psh.dwSize = sizeof(PROPSHEETHEADER); - psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW; - if(_tcslen(pConInfo->szProcessName)) - { - psh.dwFlags |= PSH_PROPTITLE; - psh.pszCaption = pConInfo->szProcessName; - } - else - { - if (!GetConsoleTitleW(szTitle, sizeof(szTitle)/sizeof(WCHAR))) - { - _tcscpy(szTitle, _T("cmd.exe")); - } - szTitle[(sizeof(szTitle)/sizeof(WCHAR))-1] = _T('\0'); - psh.pszCaption = szTitle; - } + /* Find the console window and whether we must use default parameters */ + pConInfo->hConsoleWindow = pSharedInfo->hConsoleWindow; + pConInfo->ShowDefaultParams = pSharedInfo->ShowDefaultParams; - psh.hwndParent = hwnd; - psh.hInstance = hApplet; - psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON)); - psh.nPages = 4; - psh.nStartPage = 0; - psh.ppsp = psp; + if (pConInfo->ShowDefaultParams) + { + /* Use defaults */ + InitConsoleDefaults(pConInfo); + } + else + { + /* Copy the shared data into our allocated buffer */ + RtlCopyMemory(pConInfo, pSharedInfo, sizeof(CONSOLE_PROPS)); + } - 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); + /* Close the section */ + UnmapViewOfFile(pSharedInfo); + CloseHandle(hSection); - return (PropertySheet(&psh) != -1); + /* Initialize the property sheet structure */ + ZeroMemory(&psh, sizeof(PROPSHEETHEADER)); + psh.dwSize = sizeof(PROPSHEETHEADER); + 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])); + } + else + { + wcscpy(szTitle, L"ReactOS Console"); + } + psh.pszCaption = szTitle; + + psh.hwndParent = pConInfo->hConsoleWindow; + psh.hInstance = hApplet; + // psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON)); + psh.pszIcon = MAKEINTRESOURCE(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); + + return (PropertySheet(&psh) != -1); } /* Control Panel Callback */ LONG CALLBACK -CPlApplet( - HWND hwndCPl, - UINT uMsg, - LPARAM lParam1, - LPARAM lParam2) +CPlApplet(HWND hwndCPl, + UINT uMsg, + LPARAM lParam1, + LPARAM lParam2) { - switch(uMsg) - { - case CPL_INIT: + switch (uMsg) { - return TRUE; + case CPL_INIT: + return TRUE; + + 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; + break; + } + + case CPL_DBLCLK: + InitApplet(hwndCPl, uMsg, lParam1, lParam2); + 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; - break; - } - case CPL_DBLCLK: - { - InitApplet(hwndCPl, uMsg, lParam1, lParam2); - break; - } - } - return FALSE; + + return FALSE; } INT WINAPI -DllMain( - HINSTANCE hinstDLL, - DWORD dwReason, - LPVOID lpvReserved) +DllMain(HINSTANCE hinstDLL, + DWORD dwReason, + LPVOID lpvReserved) { - UNREFERENCED_PARAMETER(lpvReserved); + UNREFERENCED_PARAMETER(lpvReserved); - switch(dwReason) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - hApplet = hinstDLL; - break; - } - return TRUE; + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + hApplet = hinstDLL; + break; + } + + return TRUE; } diff --git a/dll/cpl/console/console.h b/dll/cpl/console/console.h index 1d86befd070..87584f4458f 100644 --- a/dll/cpl/console/console.h +++ b/dll/cpl/console/console.h @@ -2,7 +2,9 @@ #define CONSOLE_H__ #define WIN32_NO_STATUS -#include +#include // just for UINT_MAX in layout.c +#include + #include #include #include @@ -10,51 +12,23 @@ #include #include #include -#include -#include #include "resource.h" +/* Shared header with consrv.dll */ +#include "settings.h" + typedef struct { - int idIcon; - int idName; - int idDescription; - APPLET_PROC AppletProc; + int idIcon; + int idName; + int idDescription; + APPLET_PROC AppletProc; } APPLET, *PAPPLET; -typedef struct TAGConsoleInfo -{ - HWND hConsoleWindow; - WCHAR szProcessName[MAX_PATH]; - BOOLEAN AppliedConfig; - DWORD UseRasterFonts; - DWORD FontSize; - DWORD FontWeight; - FONTSIGNATURE FontSignature; - DWORD CursorSize; - DWORD NumberOfHistoryBuffers; - DWORD HistoryBufferSize; - DWORD HistoryNoDup; - DWORD FullScreen; - DWORD QuickEdit; - DWORD InsertMode; - DWORD ScreenBuffer; - DWORD WindowSize; - DWORD WindowPosition; - DWORD ActiveStaticControl; - COLORREF ScreenText; - COLORREF ScreenBackground; - COLORREF PopupText; - COLORREF PopupBackground; - COLORREF Colors[16]; -} ConsoleInfo, *PConsoleInfo; - -void ApplyConsoleInfo(HWND hwndDlg, PConsoleInfo pConInfo); -void PaintConsole(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo); -void PaintText(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo); - -#define PM_APPLY_CONSOLE_INFO (WM_APP + 100) +BOOL ApplyConsoleInfo(HWND hwndDlg, PCONSOLE_PROPS pConInfo); +VOID PaintConsole(LPDRAWITEMSTRUCT drawItem, PCONSOLE_PROPS pConInfo); +VOID PaintText(LPDRAWITEMSTRUCT drawItem, PCONSOLE_PROPS pConInfo); // Globals extern HINSTANCE hApplet; diff --git a/dll/cpl/console/font.c b/dll/cpl/console/font.c index 8145a081421..c86f8301bc0 100644 --- a/dll/cpl/console/font.c +++ b/dll/cpl/console/font.c @@ -6,51 +6,47 @@ * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@student.tugraz.at) */ - #include "console.h" INT_PTR CALLBACK -FontProc( - HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam -) +FontProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { - LPDRAWITEMSTRUCT drawItem; - PConsoleInfo pConInfo = (PConsoleInfo)GetWindowLongPtr(hwndDlg, DWLP_USER); + LPDRAWITEMSTRUCT drawItem; + PCONSOLE_PROPS pConInfo = (PCONSOLE_PROPS)GetWindowLongPtr(hwndDlg, DWLP_USER); - UNREFERENCED_PARAMETER(hwndDlg); - UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(hwndDlg); + UNREFERENCED_PARAMETER(wParam); + switch (uMsg) + { + case WM_INITDIALOG: + { + pConInfo = (PCONSOLE_PROPS)((LPPROPSHEETPAGE)lParam)->lParam; + SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pConInfo); + return TRUE; + } + case WM_DRAWITEM: + { + drawItem = (LPDRAWITEMSTRUCT)lParam; + if (drawItem->CtlID == IDC_STATIC_FONT_WINDOW_PREVIEW) + { + PaintConsole(drawItem, pConInfo); + } + else if (drawItem->CtlID == IDC_STATIC_SELECT_FONT_PREVIEW) + { + PaintText(drawItem, pConInfo); + } + return TRUE; + } + default: + { + break; + } + } - switch(uMsg) - { - case WM_INITDIALOG: - { - pConInfo = (PConsoleInfo) ((LPPROPSHEETPAGE)lParam)->lParam; - SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pConInfo); - return TRUE; - } - case WM_DRAWITEM: - { - drawItem = (LPDRAWITEMSTRUCT)lParam; - if (drawItem->CtlID == IDC_STATIC_FONT_WINDOW_PREVIEW) - { - PaintConsole(drawItem, pConInfo); - } - else if (drawItem->CtlID == IDC_STATIC_SELECT_FONT_PREVIEW) - { - PaintText(drawItem, pConInfo); - } - return TRUE; - } - default: - { - break; - } - } - - return FALSE; + return FALSE; } diff --git a/dll/cpl/console/lang/fr-FR.rc b/dll/cpl/console/lang/fr-FR.rc index bcbd6727ea3..9235e95796f 100644 --- a/dll/cpl/console/lang/fr-FR.rc +++ b/dll/cpl/console/lang/fr-FR.rc @@ -70,8 +70,8 @@ BEGIN EDITTEXT IDC_EDIT_SCREEN_BUFFER_HEIGHT, 203, 42, 35, 14, ES_RIGHT | ES_NUMBER | WS_GROUP CONTROL "", IDC_UPDOWN_SCREEN_BUFFER_HEIGHT, UPDOWN_CLASS, UDS_NOTHOUSANDS | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_GROUP, 238, 42, 13, 14 GROUPBOX "Taille de la fenĂȘtre", -1, 130, 65, 115, 47 - LTEXT "&L&argeur :", -1, 140, 78, 39, 10 - LTEXT "&H&auteur :", -1, 140, 95, 37, 10 + LTEXT "L&argeur :", -1, 140, 78, 39, 10 + LTEXT "Ha&uteur :", -1, 140, 95, 37, 10 EDITTEXT IDC_EDIT_WINDOW_SIZE_WIDTH, 203, 75, 35, 14, ES_RIGHT | ES_NUMBER | WS_GROUP CONTROL "", IDC_UPDOWN_WINDOW_SIZE_WIDTH, UPDOWN_CLASS, UDS_NOTHOUSANDS | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_GROUP, 238, 75, 13, 14 EDITTEXT IDC_EDIT_WINDOW_SIZE_HEIGHT, 203, 92, 35, 14, ES_RIGHT | ES_NUMBER | WS_GROUP diff --git a/dll/cpl/console/layout.c b/dll/cpl/console/layout.c index 86a37b917eb..72e4a5be2a1 100644 --- a/dll/cpl/console/layout.c +++ b/dll/cpl/console/layout.c @@ -8,8 +8,36 @@ #include "console.h" +// TODO: Use ReactOS output +const TCHAR szPreviewText[] = \ + _T("C:\\ReactOS> dir \n") \ + _T("SYSTEM 10-01-99 5:00a\n") \ + _T("SYSTEM32 10-01-99 5:00a\n") \ + _T("README TXT 26926 10-01-99 5:00a\n") \ + _T("WINDOWS BMP 46080 10-01-99 5:00a\n") \ + _T("NOTEPAD EXE 337232 10-01-99 5:00a\n") \ + _T("CLOCK AVI 39594 10-01-99 5:00p\n") \ + _T("WIN INI 7005 10-01-99 5:00a\n"); +/* +const TCHAR szPreviewText[] = \ + _T("C:\\ReactOS> dir \n") \ + _T("02-18-13 05:00a system \n") \ + _T("02-18-13 05:00a system32 \n") \ + _T("02-18-13 05:00a 26926 readme.txt \n") \ + _T("02-18-13 05:00a 3321856 explorer.exe\n") \ + _T("02-18-13 05:00a 256 setuplog. \n") \ + _T("02-18-13 05:00a 18736 vgafonts.cab\n") \ + _T("02-18-13 05:00a 256 win.ini \n") \ + _T("README TXT 26926 10-01-99 5:00a\n") \ + _T("CLOCK AVI 39594 10-01-99 5:00p\n") \ + _T("WIN INI 7005 10-01-99 5:00a\n"); +*/ +// IDS_SCREEN_TEXT "C:\\ReactOS> dir\nSYSTEM 10-01-99 5:00\nSYSTEM32 10-01-99 5:00" -void PaintConsole(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo) + +VOID +PaintConsole(LPDRAWITEMSTRUCT drawItem, + PCONSOLE_PROPS pConInfo) { HBRUSH hBrush; RECT cRect, fRect; @@ -22,7 +50,8 @@ void PaintConsole(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo) sizex = drawItem->rcItem.right - drawItem->rcItem.left; sizey = drawItem->rcItem.bottom - drawItem->rcItem.top; - if (pConInfo->WindowPosition == UINT_MAX) + if ( pConInfo->ci.u.GuiInfo.WindowOrigin.x == MAXDWORD && + pConInfo->ci.u.GuiInfo.WindowOrigin.y == MAXDWORD ) { startx = sizex / 3; starty = sizey / 3; @@ -69,33 +98,30 @@ void PaintConsole(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo) FillRect(drawItem->hDC, &fRect, GetSysColorBrush(COLOR_SCROLLBAR)); /* Draw console background */ - hBrush = CreateSolidBrush(pConInfo->ScreenBackground); + hBrush = CreateSolidBrush(pConInfo->ci.Colors[BkgdAttribFromAttrib(pConInfo->ci.ScreenAttrib)]); SetRect(&fRect, startx + 3, starty + 6, cRect.right - 6, cRect.bottom - 3); FillRect(drawItem->hDC, &fRect, hBrush); DeleteObject((HGDIOBJ)hBrush); } -void PaintText(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo) +VOID PaintText(LPDRAWITEMSTRUCT drawItem, + PCONSOLE_PROPS pConInfo) { COLORREF pbkColor, ptColor; COLORREF nbkColor, ntColor; HBRUSH hBrush = NULL; - TCHAR szText[1024]; - - ZeroMemory(szText, sizeof(szText)); - LoadString(hApplet, IDS_SCREEN_TEXT, szText, sizeof(szText) / sizeof(TCHAR)); if (drawItem->CtlID == IDC_STATIC_SCREEN_COLOR) { - nbkColor = pConInfo->ScreenBackground; + nbkColor = pConInfo->ci.Colors[BkgdAttribFromAttrib(pConInfo->ci.ScreenAttrib)]; hBrush = CreateSolidBrush(nbkColor); - ntColor = pConInfo->ScreenText; + ntColor = pConInfo->ci.Colors[TextAttribFromAttrib(pConInfo->ci.ScreenAttrib)]; } else if (drawItem->CtlID == IDC_STATIC_POPUP_COLOR) { - nbkColor = pConInfo->PopupBackground; + nbkColor = pConInfo->ci.Colors[BkgdAttribFromAttrib(pConInfo->ci.PopupAttrib)]; hBrush = CreateSolidBrush(nbkColor); - ntColor = pConInfo->PopupText; + ntColor = pConInfo->ci.Colors[TextAttribFromAttrib(pConInfo->ci.PopupAttrib)]; } if (!hBrush) @@ -104,15 +130,10 @@ void PaintText(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo) } FillRect(drawItem->hDC, &drawItem->rcItem, hBrush); - if (ntColor == nbkColor) - { - /* Text has same color -> invisible */ - return; - } ptColor = SetTextColor(drawItem->hDC, ntColor); pbkColor = SetBkColor(drawItem->hDC, nbkColor); - DrawText(drawItem->hDC, szText, _tcslen(szText), &drawItem->rcItem, 0); + DrawText(drawItem->hDC, szPreviewText, _tcslen(szPreviewText), &drawItem->rcItem, 0); SetTextColor(drawItem->hDC, ptColor); SetBkColor(drawItem->hDC, pbkColor); DeleteObject((HGDIOBJ)hBrush); @@ -121,47 +142,48 @@ void PaintText(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo) INT_PTR CALLBACK -LayoutProc( - HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam -) +LayoutProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { LPNMUPDOWN lpnmud; LPPSHNOTIFY lppsn; - PConsoleInfo pConInfo = (PConsoleInfo)GetWindowLongPtr(hwndDlg, DWLP_USER); + PCONSOLE_PROPS pConInfo = (PCONSOLE_PROPS)GetWindowLongPtr(hwndDlg, DWLP_USER); UNREFERENCED_PARAMETER(hwndDlg); UNREFERENCED_PARAMETER(wParam); - switch(uMsg) + switch (uMsg) { case WM_INITDIALOG: { DWORD xres, yres; HDC hDC; - pConInfo = (PConsoleInfo) ((LPPROPSHEETPAGE)lParam)->lParam; + pConInfo = (PCONSOLE_PROPS)((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pConInfo); - SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, HIWORD(pConInfo->ScreenBuffer), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, LOWORD(pConInfo->ScreenBuffer), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, HIWORD(pConInfo->WindowSize), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, LOWORD(pConInfo->WindowSize), FALSE); + SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_HEIGHT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1)); SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_WIDTH), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1)); SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_HEIGHT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1)); SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_WIDTH), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1)); + SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, pConInfo->ci.ScreenBufferSize.Y, FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, pConInfo->ci.ScreenBufferSize.X, FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, pConInfo->ci.ConsoleSize.Y, FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, pConInfo->ci.ConsoleSize.X, FALSE); + hDC = GetDC(NULL); xres = GetDeviceCaps(hDC, HORZRES); yres = GetDeviceCaps(hDC, VERTRES); SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(xres, 0)); SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP), UDM_SETRANGE, 0, (LPARAM)MAKELONG(yres, 0)); - if (pConInfo->WindowPosition != MAXDWORD) + if ( pConInfo->ci.u.GuiInfo.WindowOrigin.x != MAXDWORD && + pConInfo->ci.u.GuiInfo.WindowOrigin.y != MAXDWORD ) { - SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, LOWORD(pConInfo->WindowPosition), FALSE); - SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, HIWORD(pConInfo->WindowPosition), FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, pConInfo->ci.u.GuiInfo.WindowOrigin.x, FALSE); + SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, pConInfo->ci.u.GuiInfo.WindowOrigin.y, FALSE); } else { @@ -281,16 +303,16 @@ LayoutProc( } } - pConInfo->ScreenBuffer = MAKELONG(swidth, sheight); - pConInfo->WindowSize = MAKELONG(wwidth, wheight); - pConInfo->WindowPosition = MAKELONG(left, top); + pConInfo->ci.ScreenBufferSize = (COORD){swidth, sheight}; + pConInfo->ci.ConsoleSize = (COORD){wwidth, wheight}; + pConInfo->ci.u.GuiInfo.WindowOrigin = (POINT){left, top}; PropSheet_Changed(GetParent(hwndDlg), hwndDlg); } break; } case WM_COMMAND: { - switch(LOWORD(wParam)) + switch (LOWORD(wParam)) { case IDC_EDIT_SCREEN_BUFFER_WIDTH: case IDC_EDIT_SCREEN_BUFFER_HEIGHT: @@ -328,11 +350,9 @@ LayoutProc( wheight = sheight; } - - pConInfo->ScreenBuffer = MAKELONG(swidth, sheight); - pConInfo->WindowSize = MAKELONG(wwidth, wheight); - pConInfo->WindowPosition = MAKELONG(left, top); - + pConInfo->ci.ScreenBufferSize = (COORD){swidth, sheight}; + pConInfo->ci.ConsoleSize = (COORD){wwidth, wheight}; + pConInfo->ci.u.GuiInfo.WindowOrigin = (POINT){left, top}; PropSheet_Changed(GetParent(hwndDlg), hwndDlg); } break; @@ -347,7 +367,7 @@ LayoutProc( left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, FALSE); top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, FALSE); - pConInfo->WindowPosition = MAKELONG(left, top); + pConInfo->ci.u.GuiInfo.WindowOrigin = (POINT){left, top}; SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP), TRUE); @@ -356,7 +376,7 @@ LayoutProc( } else if (res == BST_UNCHECKED) { - pConInfo->WindowPosition = UINT_MAX; + pConInfo->ci.u.GuiInfo.WindowOrigin = (POINT){UINT_MAX, UINT_MAX}; SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP), FALSE); diff --git a/dll/cpl/console/options.c b/dll/cpl/console/options.c index ace6599509c..c17439608bf 100644 --- a/dll/cpl/console/options.c +++ b/dll/cpl/console/options.c @@ -10,29 +10,27 @@ static void -UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo); +UpdateDialogElements(HWND hwndDlg, PCONSOLE_PROPS pConInfo); INT_PTR CALLBACK -OptionsProc( - HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam -) +OptionsProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { - PConsoleInfo pConInfo; + PCONSOLE_PROPS pConInfo; LRESULT lResult; HWND hDlgCtrl; LPPSHNOTIFY lppsn; - pConInfo = (PConsoleInfo) GetWindowLongPtr(hwndDlg, DWLP_USER); + pConInfo = (PCONSOLE_PROPS)GetWindowLongPtr(hwndDlg, DWLP_USER); - switch(uMsg) + switch (uMsg) { case WM_INITDIALOG: { - pConInfo = (PConsoleInfo) ((LPPROPSHEETPAGE)lParam)->lParam; + pConInfo = (PCONSOLE_PROPS)((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pConInfo); UpdateDialogElements(hwndDlg, pConInfo); return TRUE; @@ -47,25 +45,24 @@ OptionsProc( if (lppsn->hdr.code == UDN_DELTAPOS) { hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_BUFFER_SIZE); - pConInfo->HistoryBufferSize = LOWORD(SendMessage(hDlgCtrl, UDM_GETPOS, 0, 0)); + pConInfo->ci.HistoryBufferSize = LOWORD(SendMessage(hDlgCtrl, UDM_GETPOS, 0, 0)); hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_NUM_BUFFER); - pConInfo->NumberOfHistoryBuffers = LOWORD(SendMessage(hDlgCtrl, UDM_GETPOS, 0, 0)); + pConInfo->ci.NumberOfHistoryBuffers = LOWORD(SendMessage(hDlgCtrl, UDM_GETPOS, 0, 0)); PropSheet_Changed(GetParent(hwndDlg), hwndDlg); } else if (lppsn->hdr.code == PSN_APPLY) { if (!pConInfo->AppliedConfig) { - ApplyConsoleInfo(hwndDlg, pConInfo); + return ApplyConsoleInfo(hwndDlg, pConInfo); } else { /* Options have already been applied */ - SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); return TRUE; } - return TRUE; } break; } @@ -75,35 +72,35 @@ OptionsProc( { break; } - switch(LOWORD(wParam)) + switch (LOWORD(wParam)) { case IDC_RADIO_SMALL_CURSOR: { - pConInfo->CursorSize = 0x0; + pConInfo->ci.CursorSize = 0; PropSheet_Changed(GetParent(hwndDlg), hwndDlg); break; } case IDC_RADIO_MEDIUM_CURSOR: { - pConInfo->CursorSize = 0x32; + pConInfo->ci.CursorSize = 50; PropSheet_Changed(GetParent(hwndDlg), hwndDlg); break; } case IDC_RADIO_LARGE_CURSOR: { - pConInfo->CursorSize = 0x64; + pConInfo->ci.CursorSize = 100; PropSheet_Changed(GetParent(hwndDlg), hwndDlg); break; } case IDC_RADIO_DISPLAY_WINDOW: { - pConInfo->FullScreen = FALSE; + pConInfo->ci.FullScreen = FALSE; PropSheet_Changed(GetParent(hwndDlg), hwndDlg); break; } case IDC_RADIO_DISPLAY_FULL: { - pConInfo->FullScreen = TRUE; + pConInfo->ci.FullScreen = TRUE; PropSheet_Changed(GetParent(hwndDlg), hwndDlg); break; } @@ -112,12 +109,12 @@ OptionsProc( lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0); if (lResult == BST_CHECKED) { - pConInfo->QuickEdit = FALSE; + pConInfo->ci.QuickEdit = FALSE; SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); } else if (lResult == BST_UNCHECKED) { - pConInfo->QuickEdit = TRUE; + pConInfo->ci.QuickEdit = TRUE; SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); } PropSheet_Changed(GetParent(hwndDlg), hwndDlg); @@ -128,12 +125,12 @@ OptionsProc( lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0); if (lResult == BST_CHECKED) { - pConInfo->InsertMode = FALSE; + pConInfo->ci.InsertMode = FALSE; SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); } else if (lResult == BST_UNCHECKED) { - pConInfo->InsertMode = TRUE; + pConInfo->ci.InsertMode = TRUE; SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); } PropSheet_Changed(GetParent(hwndDlg), hwndDlg); @@ -144,12 +141,12 @@ OptionsProc( lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0); if (lResult == BST_CHECKED) { - pConInfo->HistoryNoDup = FALSE; + pConInfo->ci.HistoryNoDup = FALSE; SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); } else if (lResult == BST_UNCHECKED) { - pConInfo->HistoryNoDup = TRUE; + pConInfo->ci.HistoryNoDup = TRUE; SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); } PropSheet_Changed(GetParent(hwndDlg), hwndDlg); @@ -169,13 +166,13 @@ OptionsProc( static void -UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo) +UpdateDialogElements(HWND hwndDlg, PCONSOLE_PROPS pConInfo) { HWND hDlgCtrl; TCHAR szBuffer[MAX_PATH]; /* Update cursor size */ - if ( pConInfo->CursorSize == 0) + if (pConInfo->ci.CursorSize == 0) { /* Small cursor */ hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_SMALL_CURSOR); @@ -186,7 +183,7 @@ UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo) hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_LARGE_CURSOR); SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); } - else if ( pConInfo->CursorSize == 0x32 ) + else if (pConInfo->ci.CursorSize == 50) { hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_MEDIUM_CURSOR); SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); @@ -196,7 +193,7 @@ UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo) hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_LARGE_CURSOR); SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); } - else if ( pConInfo->CursorSize == 0x64 ) + else if (pConInfo->ci.CursorSize == 100) { hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_LARGE_CURSOR); SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); @@ -211,27 +208,25 @@ UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo) hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_NUM_BUFFER); SendMessage(hDlgCtrl, UDM_SETRANGE, 0, MAKELONG((short)999, (short)1)); hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_NUM_BUFFER); - _stprintf(szBuffer, _T("%d"), pConInfo->NumberOfHistoryBuffers); + _stprintf(szBuffer, _T("%d"), pConInfo->ci.NumberOfHistoryBuffers); SendMessage(hDlgCtrl, WM_SETTEXT, 0, (LPARAM)szBuffer); /* Update buffer size */ hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_BUFFER_SIZE); SendMessage(hDlgCtrl, UDM_SETRANGE, 0, MAKELONG((short)999, (short)1)); hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_BUFFER_SIZE); - _stprintf(szBuffer, _T("%d"), pConInfo->HistoryBufferSize); + _stprintf(szBuffer, _T("%d"), pConInfo->ci.HistoryBufferSize); SendMessage(hDlgCtrl, WM_SETTEXT, 0, (LPARAM)szBuffer); - - /* Update discard duplicates */ hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_DISCARD_DUPLICATES); - if ( pConInfo->HistoryNoDup ) + if (pConInfo->ci.HistoryNoDup) SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); else SendMessage(hDlgCtrl, BM_SETCHECK, (LPARAM)BST_UNCHECKED, 0); /* Update full/window screen */ - if ( pConInfo->FullScreen ) + if (pConInfo->ci.FullScreen) { hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_DISPLAY_FULL); SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); @@ -250,14 +245,14 @@ UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo) /* Update quick edit */ hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_QUICK_EDIT); - if ( pConInfo->QuickEdit ) + if (pConInfo->ci.QuickEdit) SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); else SendMessage(hDlgCtrl, BM_SETCHECK, (LPARAM)BST_UNCHECKED, 0); /* Update insert mode */ hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_INSERT_MODE); - if ( pConInfo->InsertMode ) + if (pConInfo->ci.InsertMode) SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); else SendMessage(hDlgCtrl, BM_SETCHECK, (LPARAM)BST_UNCHECKED, 0); diff --git a/dll/win32/kernel32/client/console/console.c b/dll/win32/kernel32/client/console/console.c index 46f09e8c7bf..ccba7af0e67 100644 --- a/dll/win32/kernel32/client/console/console.c +++ b/dll/win32/kernel32/client/console/console.c @@ -849,7 +849,7 @@ AllocConsole(VOID) return FALSE; } - CaptureBuffer = CsrAllocateCaptureBuffer(2, sizeof(CONSOLE_PROPS) + + CaptureBuffer = CsrAllocateCaptureBuffer(2, sizeof(CONSOLE_START_INFO) + (MAX_PATH + 1) * sizeof(WCHAR)); if (CaptureBuffer == NULL) { @@ -859,23 +859,24 @@ AllocConsole(VOID) } CsrAllocateMessagePointer(CaptureBuffer, - sizeof(CONSOLE_PROPS), - (PVOID*)&AllocConsoleRequest->ConsoleProps); + sizeof(CONSOLE_START_INFO), + (PVOID*)&AllocConsoleRequest->ConsoleStartInfo); CsrAllocateMessagePointer(CaptureBuffer, (MAX_PATH + 1) * sizeof(WCHAR), (PVOID*)&AllocConsoleRequest->AppPath); /** Copied from BasepInitConsole **********************************************/ - InitConsoleProps(AllocConsoleRequest->ConsoleProps); + InitConsoleInfo(AllocConsoleRequest->ConsoleStartInfo); - Length = min(MAX_PATH + 1, Parameters->ImagePathName.Length / sizeof(WCHAR)); + Length = min(MAX_PATH, Parameters->ImagePathName.Length / sizeof(WCHAR)); wcsncpy(AllocConsoleRequest->AppPath, Parameters->ImagePathName.Buffer, Length); AllocConsoleRequest->AppPath[Length] = L'\0'; /******************************************************************************/ AllocConsoleRequest->Console = NULL; AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher; + AllocConsoleRequest->PropDispatcher = PropDialogHandler; Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, CaptureBuffer, @@ -2004,6 +2005,7 @@ AttachConsole(DWORD dwProcessId) AttachConsoleRequest->ProcessId = dwProcessId; AttachConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher; + AttachConsoleRequest->PropDispatcher = PropDialogHandler; Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, diff --git a/dll/win32/kernel32/client/console/init.c b/dll/win32/kernel32/client/console/init.c index 6e5bb531eeb..cdcdd6f700c 100644 --- a/dll/win32/kernel32/client/console/init.c +++ b/dll/win32/kernel32/client/console/init.c @@ -10,6 +10,9 @@ #include +// For Control Panel Applet +#include + #define NDEBUG #include @@ -19,54 +22,133 @@ RTL_CRITICAL_SECTION ConsoleLock; BOOL ConsoleInitialized = FALSE; -extern DWORD WINAPI ConsoleControlDispatcher(IN LPVOID lpThreadParameter); extern HANDLE InputWaitHandle; +static HMODULE ConsoleLibrary = NULL; +static BOOL AlreadyDisplayingProps = FALSE; + #define WIN_OBJ_DIR L"\\Windows" #define SESSION_DIR L"\\Sessions" /* FUNCTIONS ******************************************************************/ +DWORD +WINAPI +PropDialogHandler(IN LPVOID lpThreadParameter) +{ + // NOTE: lpThreadParameter corresponds to the client shared section handle. + + APPLET_PROC CPLFunc; + + /* + * Do not launch more than once the console property dialog applet, + * or (albeit less probable), if we are not initialized. + */ + if (!ConsoleInitialized || AlreadyDisplayingProps) + { + /* Close the associated client shared section handle if needed */ + if (lpThreadParameter) + { + CloseHandle((HANDLE)lpThreadParameter); + } + return STATUS_UNSUCCESSFUL; + } + + AlreadyDisplayingProps = TRUE; + + /* Load the Control Applet if needed */ + if (ConsoleLibrary == NULL) + { + WCHAR szBuffer[MAX_PATH]; + + GetWindowsDirectoryW(szBuffer, MAX_PATH); + wcscat(szBuffer, L"\\system32\\console.dll"); + ConsoleLibrary = LoadLibraryW(szBuffer); + + if (ConsoleLibrary == NULL) + { + DPRINT1("Failed to load console.dll"); + AlreadyDisplayingProps = FALSE; + return STATUS_UNSUCCESSFUL; + } + } + + /* Load its main function */ + CPLFunc = (APPLET_PROC)GetProcAddress(ConsoleLibrary, "CPlApplet"); + if (CPLFunc == NULL) + { + DPRINT("Error: Console.dll misses CPlApplet export\n"); + AlreadyDisplayingProps = FALSE; + return STATUS_UNSUCCESSFUL; + } + + if (CPLFunc(NULL, CPL_INIT, 0, 0) == FALSE) + { + DPRINT("Error: failed to initialize console.dll\n"); + AlreadyDisplayingProps = FALSE; + return STATUS_UNSUCCESSFUL; + } + + if (CPLFunc(NULL, CPL_GETCOUNT, 0, 0) != 1) + { + DPRINT("Error: console.dll returned unexpected CPL count\n"); + AlreadyDisplayingProps = FALSE; + return STATUS_UNSUCCESSFUL; + } + + CPLFunc(NULL, CPL_DBLCLK, (LPARAM)lpThreadParameter, 0); + CPLFunc(NULL, CPL_EXIT , 0, 0); + + AlreadyDisplayingProps = FALSE; + return STATUS_SUCCESS; +} + + VOID -InitConsoleProps(IN OUT PCONSOLE_PROPS ConsoleProps) +InitConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo) { STARTUPINFOW si; GetStartupInfoW(&si); - ConsoleProps->dwStartupFlags = si.dwFlags; + ConsoleStartInfo->dwStartupFlags = si.dwFlags; if (si.dwFlags & STARTF_USEFILLATTRIBUTE) { - ConsoleProps->FillAttribute = si.dwFillAttribute; + ConsoleStartInfo->FillAttribute = si.dwFillAttribute; } if (si.dwFlags & STARTF_USECOUNTCHARS) { - ConsoleProps->ScreenBufferSize.X = (SHORT)(si.dwXCountChars); - ConsoleProps->ScreenBufferSize.Y = (SHORT)(si.dwYCountChars); + ConsoleStartInfo->ScreenBufferSize.X = (SHORT)(si.dwXCountChars); + ConsoleStartInfo->ScreenBufferSize.Y = (SHORT)(si.dwYCountChars); } if (si.dwFlags & STARTF_USESHOWWINDOW) { - ConsoleProps->ShowWindow = si.wShowWindow; + ConsoleStartInfo->ShowWindow = si.wShowWindow; } if (si.dwFlags & STARTF_USEPOSITION) { - ConsoleProps->ConsoleWindowOrigin.x = (LONG)(si.dwX); - ConsoleProps->ConsoleWindowOrigin.y = (LONG)(si.dwY); + ConsoleStartInfo->ConsoleWindowOrigin.x = (LONG)(si.dwX); + ConsoleStartInfo->ConsoleWindowOrigin.y = (LONG)(si.dwY); } if (si.dwFlags & STARTF_USESIZE) { - ConsoleProps->ConsoleWindowSize.cx = (LONG)(si.dwXSize); - ConsoleProps->ConsoleWindowSize.cy = (LONG)(si.dwYSize); + ConsoleStartInfo->ConsoleWindowSize.cx = (LONG)(si.dwXSize); + ConsoleStartInfo->ConsoleWindowSize.cy = (LONG)(si.dwYSize); } + /* + if (si.dwFlags & STARTF_RUNFULLSCREEN) + { + } + */ if (si.lpTitle) { - wcsncpy(ConsoleProps->ConsoleTitle, si.lpTitle, MAX_PATH + 1); + wcsncpy(ConsoleStartInfo->ConsoleTitle, si.lpTitle, MAX_PATH + 1); } else { - ConsoleProps->ConsoleTitle[0] = L'\0'; + ConsoleStartInfo->ConsoleTitle[0] = L'\0'; } } @@ -102,7 +184,7 @@ BasepInitConsole(VOID) Parameters->ConsoleHandle = NULL; ConnectInfo.ConsoleNeeded = FALSE; // ConsoleNeeded is used for knowing whether or not this is a CUI app. - ConnectInfo.ConsoleProps.ConsoleTitle[0] = L'\0'; + ConnectInfo.ConsoleStartInfo.ConsoleTitle[0] = L'\0'; ConnectInfo.AppPath[0] = L'\0'; } else @@ -110,9 +192,9 @@ BasepInitConsole(VOID) SIZE_T Length = 0; LPCWSTR ExeName; - InitConsoleProps(&ConnectInfo.ConsoleProps); + InitConsoleInfo(&ConnectInfo.ConsoleStartInfo); - Length = min(sizeof(ConnectInfo.AppPath) / sizeof(ConnectInfo.AppPath[0]), + Length = min(sizeof(ConnectInfo.AppPath) / sizeof(ConnectInfo.AppPath[0]) - 1, Parameters->ImagePathName.Length / sizeof(WCHAR)); wcsncpy(ConnectInfo.AppPath, Parameters->ImagePathName.Buffer, Length); ConnectInfo.AppPath[Length] = L'\0'; @@ -143,7 +225,7 @@ BasepInitConsole(VOID) /* We'll get the real one soon */ DPRINT("Creating new invisible console\n"); Parameters->ConsoleHandle = NULL; - ConnectInfo.ConsoleProps.ShowWindow = SW_HIDE; + ConnectInfo.ConsoleStartInfo.ShowWindow = SW_HIDE; } else { @@ -158,10 +240,13 @@ BasepInitConsole(VOID) /* Now use the proper console handle */ ConnectInfo.Console = Parameters->ConsoleHandle; - /* Initialize Console Ctrl Handler */ + /* Initialize the Console Ctrl Handler */ InitConsoleCtrlHandling(); ConnectInfo.CtrlDispatcher = ConsoleControlDispatcher; + /* Initialize the Property Dialog Handler */ + ConnectInfo.PropDispatcher = PropDialogHandler; + /* Setup the right Object Directory path */ if (!SessionId) { @@ -233,6 +318,8 @@ BasepUninitConsole(VOID) /* Delete our critical section if we were initialized */ if (ConsoleInitialized == TRUE) { + if (ConsoleLibrary) FreeLibrary(ConsoleLibrary); + ConsoleInitialized = FALSE; RtlDeleteCriticalSection(&ConsoleLock); } diff --git a/dll/win32/kernel32/include/console.h b/dll/win32/kernel32/include/console.h index bbb6f991544..1ea2c612d6e 100644 --- a/dll/win32/kernel32/include/console.h +++ b/dll/win32/kernel32/include/console.h @@ -26,6 +26,12 @@ BasepUninitConsole(VOID); VOID WINAPI InitConsoleCtrlHandling(VOID); +DWORD WINAPI +ConsoleControlDispatcher(IN LPVOID lpThreadParameter); + +DWORD WINAPI +PropDialogHandler(IN LPVOID lpThreadParameter); + HANDLE WINAPI DuplicateConsoleHandle(HANDLE hConsole, DWORD dwDesiredAccess, @@ -45,7 +51,7 @@ HANDLE FASTCALL TranslateStdHandle(HANDLE hHandle); VOID -InitConsoleProps(IN OUT PCONSOLE_PROPS ConsoleProps); +InitConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo); LPCWSTR IntCheckForConsoleFileName(IN LPCWSTR pszName, diff --git a/include/reactos/subsys/win/conmsg.h b/include/reactos/subsys/win/conmsg.h index 65ba39a93b6..0d092fb4d76 100644 --- a/include/reactos/subsys/win/conmsg.h +++ b/include/reactos/subsys/win/conmsg.h @@ -112,7 +112,7 @@ typedef enum _CONSRV_API_NUMBER } CONSRV_API_NUMBER, *PCONSRV_API_NUMBER; -typedef struct _CONSOLE_PROPS +typedef struct _CONSOLE_START_INFO { DWORD dwStartupFlags; DWORD FillAttribute; @@ -122,14 +122,14 @@ typedef struct _CONSOLE_PROPS SIZE ConsoleWindowSize; // UNICODE_STRING ConsoleTitle; WCHAR ConsoleTitle[MAX_PATH + 1]; -} CONSOLE_PROPS, *PCONSOLE_PROPS; +} CONSOLE_START_INFO, *PCONSOLE_START_INFO; typedef struct _CONSOLE_CONNECTION_INFO { BOOL ConsoleNeeded; // Used for GUI apps only. /* Adapted from CONSOLE_ALLOCCONSOLE */ - CONSOLE_PROPS ConsoleProps; + CONSOLE_START_INFO ConsoleStartInfo; WCHAR AppPath[MAX_PATH + 1]; HANDLE Console; // ConsoleHandle // In fact, it is a PCSRSS_CONSOLE <-- correct that !! @@ -138,13 +138,10 @@ typedef struct _CONSOLE_CONNECTION_INFO HANDLE ErrorHandle; HANDLE InputWaitHandle; LPTHREAD_START_ROUTINE CtrlDispatcher; + LPTHREAD_START_ROUTINE PropDispatcher; } CONSOLE_CONNECTION_INFO, *PCONSOLE_CONNECTION_INFO; -#define CONSOLE_INPUT_MODE_VALID 0x0f -#define CONSOLE_OUTPUT_MODE_VALID 0x03 - - typedef struct { USHORT nMaxIds; @@ -182,8 +179,8 @@ typedef struct typedef struct { - PCONSOLE_PROPS ConsoleProps; - LPWSTR AppPath; + PCONSOLE_START_INFO ConsoleStartInfo; + LPWSTR AppPath; // Length: MAX_PATH + 1 HANDLE Console; // ConsoleHandle // In fact, it is a PCSRSS_CONSOLE <-- correct that !! HANDLE InputHandle; @@ -191,6 +188,7 @@ typedef struct HANDLE ErrorHandle; HANDLE InputWaitHandle; LPTHREAD_START_ROUTINE CtrlDispatcher; + LPTHREAD_START_ROUTINE PropDispatcher; } CONSOLE_ALLOCCONSOLE, *PCONSOLE_ALLOCCONSOLE; typedef struct @@ -202,6 +200,7 @@ typedef struct HANDLE ErrorHandle; HANDLE InputWaitHandle; LPTHREAD_START_ROUTINE CtrlDispatcher; + LPTHREAD_START_ROUTINE PropDispatcher; } CONSOLE_ATTACHCONSOLE, *PCONSOLE_ATTACHCONSOLE; typedef struct diff --git a/win32ss/user/consrv/CMakeLists.txt b/win32ss/user/consrv/CMakeLists.txt index 5de0ebf2861..336083a619a 100644 --- a/win32ss/user/consrv/CMakeLists.txt +++ b/win32ss/user/consrv/CMakeLists.txt @@ -1,8 +1,7 @@ include_directories( ${REACTOS_SOURCE_DIR}/include/reactos/subsys - ${REACTOS_SOURCE_DIR}/win32ss/include - ${REACTOS_SOURCE_DIR}/dll/cpl/console) + ${REACTOS_SOURCE_DIR}/win32ss/include) spec2def(consrv.dll consrv.spec) @@ -15,6 +14,7 @@ list(APPEND SOURCE handle.c init.c lineinput.c + settings.c tuiconsole.c consrv.rc ${CMAKE_CURRENT_BINARY_DIR}/consrv.def) diff --git a/win32ss/user/consrv/coninput.c b/win32ss/user/consrv/coninput.c index ce15cf261d6..708943b2727 100644 --- a/win32ss/user/consrv/coninput.c +++ b/win32ss/user/consrv/coninput.c @@ -10,7 +10,6 @@ #include "consrv.h" #include "conio.h" -#include "tuiconsole.h" #define NDEBUG #include @@ -132,7 +131,7 @@ ConioGetShiftState(PBYTE KeyState) } VOID WINAPI -ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode) +ConioProcessKey(PCONSOLE Console, MSG* msg) { static BYTE KeyState[256] = { 0 }; /* MSDN mentions that you should use the last virtual key code received @@ -149,6 +148,12 @@ ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode) BOOLEAN Fake; // synthesized, not a real event BOOLEAN NotChar; // message should not be used to return a character + if (NULL == Console) + { + DPRINT1("No Active Console!\n"); + return; + } + RepeatCount = 1; VirtualScanCode = (msg->lParam >> 16) & 0xff; Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR || @@ -186,39 +191,13 @@ ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode) er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode; er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode; - if (TextMode) + if (ConioProcessKeyCallback(Console, + msg, + KeyState[VK_MENU], + ShiftState, + VirtualKeyCode, + Down)) { - if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) - && VK_TAB == VirtualKeyCode) - { - if (Down) - { - TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1); - } - - return; - } - else if (VK_MENU == VirtualKeyCode && ! Down) - { - if (TuiSwapConsole(0)) - { - return; - } - } - } - else - { - if ((ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED) || KeyState[VK_MENU] & 0x80) && - (VirtualKeyCode == VK_ESCAPE || VirtualKeyCode == VK_TAB || VirtualKeyCode == VK_SPACE)) - { - DefWindowProcW(msg->hwnd, msg->message, msg->wParam, msg->lParam); - return; - } - } - - if (NULL == Console) - { - DPRINT1("No Active Console!\n"); return; } @@ -226,8 +205,7 @@ ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode) (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); - if (NotChar) - LastVirtualKey = msg->wParam; + if (NotChar) LastVirtualKey = msg->wParam; DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n", Down ? "down" : "up ", @@ -240,8 +218,7 @@ ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode) (UnicodeChar >= L' ') ? UnicodeChar : L'.', ShiftState); - if (Fake) - return; + if (Fake) return; /* process Ctrl-C and Ctrl-Break */ if (Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT && @@ -282,22 +259,22 @@ ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode) if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode) { /* only scroll up if there is room to scroll up into */ - if (Console->ActiveBuffer->CurrentY != Console->ActiveBuffer->MaxY - 1) + if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1) { Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + - Console->ActiveBuffer->MaxY - 1) % - Console->ActiveBuffer->MaxY; - Console->ActiveBuffer->CurrentY++; + Console->ActiveBuffer->ScreenBufferSize.Y - 1) % + Console->ActiveBuffer->ScreenBufferSize.Y; + Console->ActiveBuffer->CursorPosition.Y++; } } else { /* only scroll down if there is room to scroll down into */ - if (Console->ActiveBuffer->CurrentY != 0) + if (Console->ActiveBuffer->CursorPosition.Y != 0) { Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) % - Console->ActiveBuffer->MaxY; - Console->ActiveBuffer->CurrentY--; + Console->ActiveBuffer->ScreenBufferSize.Y; + Console->ActiveBuffer->CursorPosition.Y--; } } ConioDrawConsole(Console); diff --git a/win32ss/user/consrv/conio.h b/win32ss/user/consrv/conio.h index 282fc909da2..84578186d9e 100644 --- a/win32ss/user/consrv/conio.h +++ b/win32ss/user/consrv/conio.h @@ -10,7 +10,11 @@ #define CSR_DEFAULT_CURSOR_SIZE 25 #define CURSOR_BLINK_TIME 500 -#define DEFAULT_ATTRIB (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED) + +/* Default attributes */ +#define DEFAULT_SCREEN_ATTRIB (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED) +#define DEFAULT_POPUP_ATTRIB (FOREGROUND_BLUE | FOREGROUND_RED | \ + BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY) #ifndef WM_APP #define WM_APP 0x8000 @@ -42,14 +46,21 @@ typedef struct _CONSOLE_SCREEN_BUFFER Object_t Header; /* Object header */ LIST_ENTRY ListEntry; /* Entry in console's list of buffers */ - BYTE *Buffer; /* Pointer to screen buffer */ - USHORT MaxX, MaxY; /* Size of the entire scrollback buffer */ + BYTE *Buffer; /* CHAR_INFO */ /* Pointer to screen buffer */ + + COORD ScreenBufferSize; /* Size of this screen buffer */ + COORD CursorPosition; /* Current cursor position */ + USHORT ShowX, ShowY; /* Beginning offset for the actual display area */ - ULONG CurrentX; /* Current X cursor position */ - ULONG CurrentY; /* Current Y cursor position */ - WORD DefaultAttrib; /* Default char attribute */ USHORT VirtualY; /* Top row of buffer being displayed, reported to callers */ - CONSOLE_CURSOR_INFO CursorInfo; + + BOOLEAN CursorBlinkOn; + BOOLEAN ForceCursorOff; + ULONG CursorSize; + CONSOLE_CURSOR_INFO CursorInfo; // FIXME: Keep this member or not ?? + + WORD ScreenDefaultAttrib; /* Default screen char attribute */ + WORD PopupDefaultAttrib; /* Default popup char attribute */ USHORT Mode; } CONSOLE_SCREEN_BUFFER, *PCONSOLE_SCREEN_BUFFER; @@ -57,10 +68,12 @@ typedef struct _CONSOLE_INPUT_BUFFER { Object_t Header; /* Object header */ + ULONG InputBufferSize; /* Size of this input buffer */ LIST_ENTRY InputEvents; /* List head for input event queue */ HANDLE ActiveEvent; /* Event set when an input event is added in its queue */ LIST_ENTRY ReadWaitQueue; /* List head for the queue of read wait blocks */ - WORD Mode; /* Console Input Buffer mode flags */ + + USHORT Mode; /* Console Input Buffer mode flags */ } CONSOLE_INPUT_BUFFER, *PCONSOLE_INPUT_BUFFER; typedef struct ConsoleInput_t @@ -92,6 +105,8 @@ typedef struct _CONSOLE BOOLEAN LineInsertToggle; /* Replace character over cursor instead of inserting */ ULONG LineWakeupMask; /* Bitmap of which control characters will end line input */ + BOOLEAN QuickEdit; + BOOLEAN InsertMode; UINT CodePage; UINT OutputCodePage; @@ -105,21 +120,27 @@ typedef struct _CONSOLE LIST_ENTRY WriteWaitQueue; /* List head for the queue of write wait blocks */ DWORD HardwareState; /* _GDI_MANAGED, _DIRECT */ +/* BOOLEAN */ ULONG FullScreen; // Give the type of console: GUI (windowed) or TUI (fullscreen) /**************************** Aliases and Histories ***************************/ struct _ALIAS_HEADER *Aliases; LIST_ENTRY HistoryBuffers; - UINT HistoryBufferSize; /* Size for newly created history buffers */ - UINT NumberOfHistoryBuffers; /* Maximum number of history buffers allowed */ + ULONG HistoryBufferSize; /* Size for newly created history buffers */ + ULONG NumberOfHistoryBuffers; /* Maximum number of history buffers allowed */ BOOLEAN HistoryNoDup; /* Remove old duplicate history entries */ -/****************************** GUI-related data ******************************/ +/******************************* Common UI data *******************************/ + UNICODE_STRING OriginalTitle; /* Original title of console, the one when the console leader is launched. It is always NULL-terminated */ UNICODE_STRING Title; /* Title of console. It is always NULL-terminated */ + + COORD Size; /* Size of the console (different of the size of the screen buffer */ + COLORREF Colors[16]; /* Colour palette */ + +/****************************** GUI-related data ******************************/ HWND hWindow; /* Handle to the console's window */ HICON hIcon; /* Handle to its icon (used when freeing) */ HICON hIconSm; - COORD Size; - PVOID GuiData; + PVOID GuiData; /* PGUI_CONSOLE_DATA */ } CONSOLE, *PCONSOLE; @@ -149,6 +170,7 @@ typedef struct _CONSOLE_VTBL VOID (WINAPI *CleanupConsole)(PCONSOLE Console); BOOL (WINAPI *ChangeIcon)(PCONSOLE Console, HICON hWindowIcon); NTSTATUS (WINAPI *ResizeBuffer)(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Size); + BOOL (WINAPI *ProcessKeyCallback)(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD ShiftState, UINT VirtualKeyCode, BOOL Down); } CONSOLE_VTBL, *PCONSOLE_VTBL; /* CONSOLE_SELECTION_INFO dwFlags values */ @@ -178,13 +200,14 @@ typedef struct _CONSOLE_VTBL #define ConioCleanupConsole(Console) (Console)->Vtbl->CleanupConsole(Console) #define ConioChangeIcon(Console, hWindowIcon) (Console)->Vtbl->ChangeIcon((Console), (hWindowIcon)) #define ConioResizeBuffer(Console, Buff, Size) (Console)->Vtbl->ResizeBuffer((Console), (Buff), (Size)) +#define ConioProcessKeyCallback(Console, Msg, KeyStateMenu, ShiftState, VirtualKeyCode, Down) (Console)->Vtbl->ProcessKeyCallback((Console), (Msg), (KeyStateMenu), (ShiftState), (VirtualKeyCode), (Down)) /* console.c */ VOID WINAPI ConSrvDeleteConsole(PCONSOLE Console); VOID WINAPI ConSrvInitConsoleSupport(VOID); NTSTATUS WINAPI ConSrvInitConsole(OUT PCONSOLE* NewConsole, IN LPCWSTR AppPath, - IN OUT PCONSOLE_PROPS ConsoleProps, + IN OUT PCONSOLE_START_INFO ConsoleStartInfo, IN PCSR_PROCESS ConsoleLeaderProcess); VOID FASTCALL ConioPause(PCONSOLE Console, UINT Flags); VOID FASTCALL ConioUnpause(PCONSOLE Console, UINT Flags); @@ -202,7 +225,7 @@ VOID FASTCALL ConSrvConsoleCtrlEventTimeout(DWORD Event, (Access), (LockConsole), CONIO_INPUT_BUFFER_MAGIC) #define ConSrvReleaseInputBuffer(Buff, IsConsoleLocked) \ ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked)) -void WINAPI ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode); +VOID WINAPI ConioProcessKey(PCONSOLE Console, MSG* msg); /* conoutput.c */ #define ConioRectHeight(Rect) \ @@ -221,7 +244,11 @@ PBYTE FASTCALL ConioCoordToPointer(PCONSOLE_SCREEN_BUFFER Buf, ULONG X, ULONG Y) VOID FASTCALL ConioDrawConsole(PCONSOLE Console); NTSTATUS FASTCALL ConioWriteConsole(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, CHAR *Buffer, DWORD Length, BOOL Attrib); -NTSTATUS FASTCALL ConSrvInitConsoleScreenBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buffer); +NTSTATUS FASTCALL ConSrvCreateScreenBuffer(IN OUT PCONSOLE Console, + OUT PCONSOLE_SCREEN_BUFFER* Buffer, + IN COORD ScreenBufferSize, + IN USHORT ScreenAttrib, + IN USHORT PopupAttrib); VOID WINAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer); DWORD FASTCALL ConioEffectiveCursorSize(PCONSOLE Console, DWORD Scale); diff --git a/win32ss/user/consrv/conoutput.c b/win32ss/user/consrv/conoutput.c index 0594808ffe4..74914dae19f 100644 --- a/win32ss/user/consrv/conoutput.c +++ b/win32ss/user/consrv/conoutput.c @@ -42,52 +42,72 @@ do { \ PBYTE FASTCALL ConioCoordToPointer(PCONSOLE_SCREEN_BUFFER Buff, ULONG X, ULONG Y) { - return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->MaxY) * Buff->MaxX + X)]; + return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y) * Buff->ScreenBufferSize.X + X)]; } static VOID FASTCALL ClearLineBuffer(PCONSOLE_SCREEN_BUFFER Buff) { - PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CurrentY); + PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CursorPosition.Y); UINT Pos; - for (Pos = 0; Pos < Buff->MaxX; Pos++) + for (Pos = 0; Pos < Buff->ScreenBufferSize.X; Pos++) { /* Fill the cell */ *Ptr++ = ' '; - *Ptr++ = Buff->DefaultAttrib; + *Ptr++ = Buff->ScreenDefaultAttrib; } } NTSTATUS FASTCALL -ConSrvInitConsoleScreenBuffer(PCONSOLE Console, - PCONSOLE_SCREEN_BUFFER Buffer) +ConSrvCreateScreenBuffer(IN OUT PCONSOLE Console, + OUT PCONSOLE_SCREEN_BUFFER* Buffer, + IN COORD ScreenBufferSize, + IN USHORT ScreenAttrib, + IN USHORT PopupAttrib) { - DPRINT1("ConSrvInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY); + DPRINT("ConSrvCreateScreenBuffer\n"); - Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC; - Buffer->Header.Console = Console; - Buffer->Header.HandleCount = 0; - Buffer->ShowX = 0; - Buffer->ShowY = 0; - Buffer->VirtualY = 0; - Buffer->Buffer = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, Buffer->MaxX * Buffer->MaxY * 2); - if (NULL == Buffer->Buffer) + if (Console == NULL || Buffer == NULL) + return STATUS_INVALID_PARAMETER; + + *Buffer = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CONSOLE_SCREEN_BUFFER)); + if (NULL == *Buffer) { - DPRINT1("ConSrvInitConsoleScreenBuffer - D'oh!\n"); return STATUS_INSUFFICIENT_RESOURCES; } - Buffer->DefaultAttrib = DEFAULT_ATTRIB; - /* initialize buffer to be empty with default attributes */ - for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++) - { - ClearLineBuffer(Buffer); - } - Buffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; - Buffer->CurrentX = 0; - Buffer->CurrentY = 0; - InsertHeadList(&Console->BufferList, &Buffer->ListEntry); + (*Buffer)->Header.Type = CONIO_SCREEN_BUFFER_MAGIC; + (*Buffer)->Header.Console = Console; + (*Buffer)->Header.HandleCount = 0; + (*Buffer)->ScreenBufferSize = ScreenBufferSize; + + (*Buffer)->Buffer = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, (*Buffer)->ScreenBufferSize.X * (*Buffer)->ScreenBufferSize.Y * 2); + if (NULL == (*Buffer)->Buffer) + { + RtlFreeHeap(ConSrvHeap, 0, *Buffer); + return STATUS_INSUFFICIENT_RESOURCES; + } + + (*Buffer)->ShowX = 0; + (*Buffer)->ShowY = 0; + (*Buffer)->VirtualY = 0; + + // FIXME: !! + (*Buffer)->CursorInfo.bVisible = TRUE; + // (*Buffer)->CursorInfo.dwSize = ConsoleInfo->CursorSize; + + (*Buffer)->ScreenDefaultAttrib = ScreenAttrib; + (*Buffer)->PopupDefaultAttrib = PopupAttrib; + /* initialize buffer to be empty with default attributes */ + for ((*Buffer)->CursorPosition.Y = 0 ; (*Buffer)->CursorPosition.Y < (*Buffer)->ScreenBufferSize.Y; (*Buffer)->CursorPosition.Y++) + { + ClearLineBuffer(*Buffer); + } + (*Buffer)->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; + (*Buffer)->CursorPosition = (COORD){0, 0}; + + InsertHeadList(&Console->BufferList, &(*Buffer)->ListEntry); return STATUS_SUCCESS; } @@ -95,10 +115,10 @@ static VOID FASTCALL ConioNextLine(PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, UINT *ScrolledLines) { /* If we hit bottom, slide the viewable screen */ - if (++Buff->CurrentY == Buff->MaxY) + if (++Buff->CursorPosition.Y == Buff->ScreenBufferSize.Y) { - Buff->CurrentY--; - if (++Buff->VirtualY == Buff->MaxY) + Buff->CursorPosition.Y--; + if (++Buff->VirtualY == Buff->ScreenBufferSize.Y) { Buff->VirtualY = 0; } @@ -110,8 +130,8 @@ ConioNextLine(PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, UINT *Scrolle } } UpdateRect->Left = 0; - UpdateRect->Right = Buff->MaxX - 1; - UpdateRect->Bottom = Buff->CurrentY; + UpdateRect->Right = Buff->ScreenBufferSize.X - 1; + UpdateRect->Bottom = Buff->CursorPosition.Y; } NTSTATUS FASTCALL @@ -124,12 +144,12 @@ ConioWriteConsole(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, LONG CursorStartX, CursorStartY; UINT ScrolledLines; - CursorStartX = Buff->CurrentX; - CursorStartY = Buff->CurrentY; - UpdateRect.Left = Buff->MaxX; - UpdateRect.Top = Buff->CurrentY; + CursorStartX = Buff->CursorPosition.X; + CursorStartY = Buff->CursorPosition.Y; + UpdateRect.Left = Buff->ScreenBufferSize.X; + UpdateRect.Top = Buff->CursorPosition.Y; UpdateRect.Right = -1; - UpdateRect.Bottom = Buff->CurrentY; + UpdateRect.Bottom = Buff->CursorPosition.Y; ScrolledLines = 0; for (i = 0; i < Length; i++) @@ -143,15 +163,15 @@ ConioWriteConsole(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, /* --- CR --- */ if (Buffer[i] == '\r') { - Buff->CurrentX = 0; - UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); - UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CurrentX); + Buff->CursorPosition.X = 0; + UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CursorPosition.X); + UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CursorPosition.X); continue; } /* --- LF --- */ else if (Buffer[i] == '\n') { - Buff->CurrentX = 0; + Buff->CursorPosition.X = 0; ConioNextLine(Buff, &UpdateRect, &ScrolledLines); continue; } @@ -159,24 +179,24 @@ ConioWriteConsole(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, else if (Buffer[i] == '\b') { /* Only handle BS if we're not on the first pos of the first line */ - if (0 != Buff->CurrentX || 0 != Buff->CurrentY) + if (0 != Buff->CursorPosition.X || 0 != Buff->CursorPosition.Y) { - if (0 == Buff->CurrentX) + if (0 == Buff->CursorPosition.X) { /* slide virtual position up */ - Buff->CurrentX = Buff->MaxX - 1; - Buff->CurrentY--; - UpdateRect.Top = min(UpdateRect.Top, (LONG)Buff->CurrentY); + Buff->CursorPosition.X = Buff->ScreenBufferSize.X - 1; + Buff->CursorPosition.Y--; + UpdateRect.Top = min(UpdateRect.Top, (LONG)Buff->CursorPosition.Y); } else { - Buff->CurrentX--; + Buff->CursorPosition.X--; } - Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); + Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); Ptr[0] = ' '; - Ptr[1] = Buff->DefaultAttrib; - UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); - UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CurrentX); + Ptr[1] = Buff->ScreenDefaultAttrib; + UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CursorPosition.X); + UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CursorPosition.X); } continue; } @@ -185,27 +205,27 @@ ConioWriteConsole(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, { UINT EndX; - UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); - EndX = (Buff->CurrentX + TAB_WIDTH) & ~(TAB_WIDTH - 1); - EndX = min(EndX, Buff->MaxX); - Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); - while (Buff->CurrentX < EndX) + UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CursorPosition.X); + EndX = (Buff->CursorPosition.X + TAB_WIDTH) & ~(TAB_WIDTH - 1); + EndX = min(EndX, Buff->ScreenBufferSize.X); + Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); + while (Buff->CursorPosition.X < EndX) { *Ptr++ = ' '; - *Ptr++ = Buff->DefaultAttrib; - Buff->CurrentX++; + *Ptr++ = Buff->ScreenDefaultAttrib; + Buff->CursorPosition.X++; } - UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CurrentX - 1); - if (Buff->CurrentX == Buff->MaxX) + UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CursorPosition.X - 1); + if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X) { if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) { - Buff->CurrentX = 0; + Buff->CursorPosition.X = 0; ConioNextLine(Buff, &UpdateRect, &ScrolledLines); } else { - Buff->CurrentX--; + Buff->CursorPosition.X--; } } continue; @@ -218,25 +238,25 @@ ConioWriteConsole(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, continue; } } - UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); - UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CurrentX); - Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); + UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CursorPosition.X); + UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CursorPosition.X); + Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); Ptr[0] = Buffer[i]; if (Attrib) { - Ptr[1] = Buff->DefaultAttrib; + Ptr[1] = Buff->ScreenDefaultAttrib; } - Buff->CurrentX++; - if (Buff->CurrentX == Buff->MaxX) + Buff->CursorPosition.X++; + if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X) { if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) { - Buff->CurrentX = 0; + Buff->CursorPosition.X = 0; ConioNextLine(Buff, &UpdateRect, &ScrolledLines); } else { - Buff->CurrentX = CursorStartX; + Buff->CursorPosition.X = CursorStartX; } } } @@ -377,7 +397,6 @@ VOID WINAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer) { PCONSOLE Console = Buffer->Header.Console; - DPRINT1("ConioDeleteScreenBuffer(Buffer = 0x%p, Buffer->Buffer = 0x%p) ; Console = 0x%p\n", Buffer, Buffer->Buffer, Console); RemoveEntryList(&Buffer->ListEntry); if (Buffer == Console->ActiveBuffer) @@ -386,7 +405,6 @@ ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer) Console->ActiveBuffer = NULL; if (!IsListEmpty(&Console->BufferList)) { - DPRINT1("ConioDeleteScreenBuffer - Bang !!!!!!!!\n"); Console->ActiveBuffer = CONTAINING_RECORD(Console->BufferList.Flink, CONSOLE_SCREEN_BUFFER, ListEntry); ConioDrawConsole(Console); } @@ -402,14 +420,13 @@ ConioDrawConsole(PCONSOLE Console) SMALL_RECT Region; ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1); - ConioDrawRegion(Console, &Region); } static VOID FASTCALL ConioComputeUpdateRect(PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, PCOORD Start, UINT Length) { - if (Buff->MaxX <= Start->X + Length) + if (Buff->ScreenBufferSize.X <= Start->X + Length) { UpdateRect->Left = 0; } @@ -417,19 +434,19 @@ ConioComputeUpdateRect(PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, PCOO { UpdateRect->Left = Start->X; } - if (Buff->MaxX <= Start->X + Length) + if (Buff->ScreenBufferSize.X <= Start->X + Length) { - UpdateRect->Right = Buff->MaxX - 1; + UpdateRect->Right = Buff->ScreenBufferSize.X - 1; } else { UpdateRect->Right = Start->X + Length - 1; } UpdateRect->Top = Start->Y; - UpdateRect->Bottom = Start->Y + (Start->X + Length - 1) / Buff->MaxX; - if (Buff->MaxY <= UpdateRect->Bottom) + UpdateRect->Bottom = Start->Y + (Start->X + Length - 1) / Buff->ScreenBufferSize.X; + if (Buff->ScreenBufferSize.Y <= UpdateRect->Bottom) { - UpdateRect->Bottom = Buff->MaxY - 1; + UpdateRect->Bottom = Buff->ScreenBufferSize.Y - 1; } } @@ -622,7 +639,7 @@ CSR_API(SrvReadConsoleOutput) ReadRegion.Bottom = ReadRegion.Top + SizeY; ReadRegion.Right = ReadRegion.Left + SizeX; - ConioInitRect(&ScreenRect, 0, 0, Buff->MaxY, Buff->MaxX); + ConioInitRect(&ScreenRect, 0, 0, Buff->ScreenBufferSize.Y, Buff->ScreenBufferSize.X); if (!ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion)) { ConSrvReleaseScreenBuffer(Buff, TRUE); @@ -734,7 +751,7 @@ CSR_API(SrvWriteConsoleOutput) WriteRegion.Right = WriteRegion.Left + SizeX - 1; /* Make sure WriteRegion is inside the screen buffer */ - ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); + ConioInitRect(&ScreenBuffer, 0, 0, Buff->ScreenBufferSize.Y - 1, Buff->ScreenBufferSize.X - 1); if (!ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion)) { ConSrvReleaseScreenBuffer(Buff, TRUE); @@ -826,7 +843,7 @@ CSR_API(SrvReadConsoleOutputString) ReadBuffer = ReadOutputCodeRequest->pCode.pCode; Xpos = ReadOutputCodeRequest->ReadCoord.X; - Ypos = (ReadOutputCodeRequest->ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; + Ypos = (ReadOutputCodeRequest->ReadCoord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y; /* * MSDN (ReadConsoleOutputAttribute and ReadConsoleOutputCharacter) : @@ -843,7 +860,7 @@ CSR_API(SrvReadConsoleOutputString) */ for (i = 0; i < ReadOutputCodeRequest->NumCodesToRead; ++i) { - Code = Buff->Buffer[2 * (Xpos + Ypos * Buff->MaxX) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)]; + Code = Buff->Buffer[2 * (Xpos + Ypos * Buff->ScreenBufferSize.X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)]; switch (CodeType) { @@ -863,12 +880,12 @@ CSR_API(SrvReadConsoleOutputString) Xpos++; - if (Xpos == Buff->MaxX) + if (Xpos == Buff->ScreenBufferSize.X) { Xpos = 0; Ypos++; - if (Ypos == Buff->MaxY) + if (Ypos == Buff->ScreenBufferSize.Y) { Ypos = 0; } @@ -891,7 +908,7 @@ CSR_API(SrvReadConsoleOutputString) // } ReadOutputCodeRequest->EndCoord.X = Xpos; - ReadOutputCodeRequest->EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY; + ReadOutputCodeRequest->EndCoord.Y = (Ypos - Buff->VirtualY + Buff->ScreenBufferSize.Y) % Buff->ScreenBufferSize.Y; ConSrvReleaseScreenBuffer(Buff, TRUE); @@ -990,9 +1007,9 @@ CSR_API(SrvWriteConsoleOutputString) if (String && NT_SUCCESS(Status)) { X = WriteOutputCodeRequest->Coord.X; - Y = (WriteOutputCodeRequest->Coord.Y + Buff->VirtualY) % Buff->MaxY; + Y = (WriteOutputCodeRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y; Length = WriteOutputCodeRequest->Length; - Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)]; + Buffer = &Buff->Buffer[2 * (Y * Buff->ScreenBufferSize.X + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)]; while (Length--) { @@ -1001,9 +1018,9 @@ CSR_API(SrvWriteConsoleOutputString) String = (PCHAR)((ULONG_PTR)String + CodeSize); // Written++; Buffer += 2; - if (++X == Buff->MaxX) + if (++X == Buff->ScreenBufferSize.X) { - if (++Y == Buff->MaxY) + if (++Y == Buff->ScreenBufferSize.Y) { Y = 0; Buffer = Buff->Buffer + (CodeType == CODE_ATTRIBUTE ? 1 : 0); @@ -1020,7 +1037,7 @@ CSR_API(SrvWriteConsoleOutputString) } WriteOutputCodeRequest->EndCoord.X = X; - WriteOutputCodeRequest->EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; + WriteOutputCodeRequest->EndCoord.Y = (Y + Buff->ScreenBufferSize.Y - Buff->VirtualY) % Buff->ScreenBufferSize.Y; } if (tmpString) @@ -1056,9 +1073,9 @@ CSR_API(SrvFillConsoleOutput) CodeType = FillOutputRequest->CodeType; X = FillOutputRequest->Coord.X; - Y = (FillOutputRequest->Coord.Y + Buff->VirtualY) % Buff->MaxY; + Y = (FillOutputRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y; Length = FillOutputRequest->Length; - Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)]; + Buffer = &Buff->Buffer[2 * (Y * Buff->ScreenBufferSize.X + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)]; switch (CodeType) { @@ -1084,9 +1101,9 @@ CSR_API(SrvFillConsoleOutput) *Buffer = Code; Buffer += 2; // Written++; - if (++X == Buff->MaxX) + if (++X == Buff->ScreenBufferSize.X) { - if (++Y == Buff->MaxY) + if (++Y == Buff->ScreenBufferSize.Y) { Y = 0; Buffer = Buff->Buffer + (CodeType == CODE_ATTRIBUTE ? 1 : 0); @@ -1192,16 +1209,16 @@ CSR_API(SrvSetConsoleCursorPosition) NewCursorX = SetCursorPositionRequest->Position.X; NewCursorY = SetCursorPositionRequest->Position.Y; - if ( NewCursorX < 0 || NewCursorX >= Buff->MaxX || - NewCursorY < 0 || NewCursorY >= Buff->MaxY ) + if ( NewCursorX < 0 || NewCursorX >= Buff->ScreenBufferSize.X || + NewCursorY < 0 || NewCursorY >= Buff->ScreenBufferSize.Y ) { ConSrvReleaseScreenBuffer(Buff, TRUE); return STATUS_INVALID_PARAMETER; } - OldCursorX = Buff->CurrentX; - OldCursorY = Buff->CurrentY; - Buff->CurrentX = NewCursorX; - Buff->CurrentY = NewCursorY; + OldCursorX = Buff->CursorPosition.X; + OldCursorY = Buff->CursorPosition.Y; + Buff->CursorPosition.X = NewCursorX; + Buff->CursorPosition.Y = NewCursorY; if (Buff == Console->ActiveBuffer) { if (!ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY)) @@ -1230,7 +1247,7 @@ CSR_API(SrvSetConsoleTextAttribute) Console = Buff->Header.Console; - Buff->DefaultAttrib = SetTextAttribRequest->Attrib; + Buff->ScreenDefaultAttrib = SetTextAttribRequest->Attrib; if (Buff == Console->ActiveBuffer) { if (!ConioUpdateScreenInfo(Console, Buff)) @@ -1253,6 +1270,10 @@ CSR_API(SrvCreateConsoleScreenBuffer) PCONSOLE Console; PCONSOLE_SCREEN_BUFFER Buff; + COORD ScreenBufferSize = (COORD){80, 25}; + USHORT ScreenAttrib = DEFAULT_SCREEN_ATTRIB; + USHORT PopupAttrib = DEFAULT_POPUP_ATTRIB; + DPRINT("SrvCreateConsoleScreenBuffer\n"); RtlEnterCriticalSection(&ProcessData->HandleTableLock); @@ -1264,46 +1285,36 @@ CSR_API(SrvCreateConsoleScreenBuffer) return Status; } - Buff = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CONSOLE_SCREEN_BUFFER)); - if (Buff != NULL) + if (Console->ActiveBuffer) { - if (Console->ActiveBuffer) - { - Buff->MaxX = Console->ActiveBuffer->MaxX; - Buff->MaxY = Console->ActiveBuffer->MaxY; - Buff->CursorInfo.bVisible = Console->ActiveBuffer->CursorInfo.bVisible; - Buff->CursorInfo.dwSize = Console->ActiveBuffer->CursorInfo.dwSize; - } - else - { - Buff->CursorInfo.bVisible = TRUE; - Buff->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; - } + ScreenBufferSize = Console->ActiveBuffer->ScreenBufferSize; + if (ScreenBufferSize.X == 0) ScreenBufferSize.X = 80; + if (ScreenBufferSize.Y == 0) ScreenBufferSize.Y = 25; - if (Buff->MaxX == 0) - { - Buff->MaxX = 80; - } - - if (Buff->MaxY == 0) - { - Buff->MaxY = 25; - } - - Status = ConSrvInitConsoleScreenBuffer(Console, Buff); - if (NT_SUCCESS(Status)) - { - Status = ConSrvInsertObject(ProcessData, - &CreateScreenBufferRequest->OutputHandle, - &Buff->Header, - CreateScreenBufferRequest->Access, - CreateScreenBufferRequest->Inheritable, - CreateScreenBufferRequest->ShareMode); - } + ScreenAttrib = Console->ActiveBuffer->ScreenDefaultAttrib; + PopupAttrib = Console->ActiveBuffer->PopupDefaultAttrib; + // Buff->CursorInfo.bVisible = Console->ActiveBuffer->CursorInfo.bVisible; + // Buff->CursorInfo.dwSize = Console->ActiveBuffer->CursorInfo.dwSize; } - else + // else + // { + // Buff->CursorInfo.bVisible = TRUE; + // Buff->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; + // } + + Status = ConSrvCreateScreenBuffer(Console, + &Buff, + ScreenBufferSize, + ScreenAttrib, + PopupAttrib); + if (NT_SUCCESS(Status)) { - Status = STATUS_INSUFFICIENT_RESOURCES; + Status = ConSrvInsertObject(ProcessData, + &CreateScreenBufferRequest->OutputHandle, + &Buff->Header, + CreateScreenBufferRequest->Access, + CreateScreenBufferRequest->Inheritable, + CreateScreenBufferRequest->ShareMode); } ConSrvReleaseConsole(Console, TRUE); @@ -1328,17 +1339,14 @@ CSR_API(SrvGetConsoleScreenBufferInfo) Console = Buff->Header.Console; - pInfo->dwSize.X = Buff->MaxX; - pInfo->dwSize.Y = Buff->MaxY; - pInfo->dwCursorPosition.X = Buff->CurrentX; - pInfo->dwCursorPosition.Y = Buff->CurrentY; - pInfo->wAttributes = Buff->DefaultAttrib; + pInfo->dwSize = Buff->ScreenBufferSize; + pInfo->dwCursorPosition = Buff->CursorPosition; + pInfo->wAttributes = Buff->ScreenDefaultAttrib; pInfo->srWindow.Left = Buff->ShowX; pInfo->srWindow.Right = Buff->ShowX + Console->Size.X - 1; pInfo->srWindow.Top = Buff->ShowY; pInfo->srWindow.Bottom = Buff->ShowY + Console->Size.Y - 1; - pInfo->dwMaximumWindowSize.X = Buff->MaxX; - pInfo->dwMaximumWindowSize.Y = Buff->MaxY; + pInfo->dwMaximumWindowSize = Buff->ScreenBufferSize; ConSrvReleaseScreenBuffer(Buff, TRUE); @@ -1415,7 +1423,7 @@ CSR_API(SrvScrollConsoleScreenBuffer) ScrollRectangle = ScrollScreenBufferRequest->ScrollRectangle; /* Make sure source rectangle is inside the screen buffer */ - ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); + ConioInitRect(&ScreenBuffer, 0, 0, Buff->ScreenBufferSize.Y - 1, Buff->ScreenBufferSize.X - 1); if (!ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle)) { ConSrvReleaseScreenBuffer(Buff, TRUE); diff --git a/win32ss/user/consrv/console.c b/win32ss/user/consrv/console.c index 4b78c9ea001..6d28fa7035e 100644 --- a/win32ss/user/consrv/console.c +++ b/win32ss/user/consrv/console.c @@ -12,6 +12,7 @@ #define NONAMELESSUNION #include "consrv.h" +#include "settings.h" #include "guiconsole.h" #include "tuiconsole.h" @@ -102,17 +103,19 @@ ConioUnpause(PCONSOLE Console, UINT Flags) } static BOOL -LoadShellLinkInfo(IN OUT PCONSOLE_PROPS ConsoleProps, - OUT LPWSTR IconPath, - IN SIZE_T IconPathLength, - OUT PINT piIcon) +LoadShellLinkConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo, + OUT PCONSOLE_INFO ConsoleInfo, + OUT LPWSTR IconPath, + IN SIZE_T IconPathLength, + OUT PINT piIcon) { #define PATH_SEPARATOR L'\\' + BOOL RetVal = FALSE; LPWSTR LinkName = NULL; SIZE_T Length = 0; - if ((ConsoleProps->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0) + if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0) return FALSE; if (IconPath == NULL || piIcon == NULL) @@ -122,10 +125,10 @@ LoadShellLinkInfo(IN OUT PCONSOLE_PROPS ConsoleProps, *piIcon = 0; /* 1- Find the last path separator if any */ - LinkName = wcsrchr(ConsoleProps->ConsoleTitle, PATH_SEPARATOR); + LinkName = wcsrchr(ConsoleStartInfo->ConsoleTitle, PATH_SEPARATOR); if (LinkName == NULL) { - LinkName = ConsoleProps->ConsoleTitle; + LinkName = ConsoleStartInfo->ConsoleTitle; } else { @@ -142,7 +145,7 @@ LoadShellLinkInfo(IN OUT PCONSOLE_PROPS ConsoleProps, HRESULT hRes = CoInitialize(NULL); if (SUCCEEDED(hRes)) { - // Get a pointer to the IShellLink interface. + /* Get a pointer to the IShellLink interface */ IShellLinkW* pshl = NULL; hRes = CoCreateInstance(&CLSID_ShellLink, NULL, @@ -151,13 +154,13 @@ LoadShellLinkInfo(IN OUT PCONSOLE_PROPS ConsoleProps, (LPVOID*)&pshl); if (SUCCEEDED(hRes)) { - // Get a pointer to the IPersistFile interface. + /* Get a pointer to the IPersistFile interface */ IPersistFile* ppf = NULL; hRes = IPersistFile_QueryInterface(pshl, &IID_IPersistFile, (LPVOID*)&ppf); if (SUCCEEDED(hRes)) { - // Load the shortcut. - hRes = IPersistFile_Load(ppf, ConsoleProps->ConsoleTitle, STGM_READ); + /* Load the shortcut */ + hRes = IPersistFile_Load(ppf, ConsoleStartInfo->ConsoleTitle, STGM_READ); if (SUCCEEDED(hRes)) { /* @@ -167,26 +170,36 @@ LoadShellLinkInfo(IN OUT PCONSOLE_PROPS ConsoleProps, INT ShowCmd = 0; // WORD HotKey = 0; - // Get the name of the shortcut. + /* Get the name of the shortcut */ Length = min(Length - 4, - sizeof(ConsoleProps->ConsoleTitle) / sizeof(ConsoleProps->ConsoleTitle[0])); - wcsncpy(ConsoleProps->ConsoleTitle, LinkName, Length); - ConsoleProps->ConsoleTitle[Length] = L'\0'; + sizeof(ConsoleStartInfo->ConsoleTitle) / sizeof(ConsoleStartInfo->ConsoleTitle[0]) - 1); + wcsncpy(ConsoleStartInfo->ConsoleTitle, LinkName, Length); + ConsoleStartInfo->ConsoleTitle[Length] = L'\0'; - // Get the window showing command. + // HACK: Copy also the name of the shortcut + Length = min(Length, + sizeof(ConsoleInfo->ConsoleTitle) / sizeof(ConsoleInfo->ConsoleTitle[0]) - 1); + wcsncpy(ConsoleInfo->ConsoleTitle, LinkName, Length); + ConsoleInfo->ConsoleTitle[Length] = L'\0'; + + /* Get the window showing command */ hRes = IShellLinkW_GetShowCmd(pshl, &ShowCmd); - if (SUCCEEDED(hRes)) ConsoleProps->ShowWindow = (WORD)ShowCmd; + if (SUCCEEDED(hRes)) ConsoleStartInfo->ShowWindow = (WORD)ShowCmd; - // Get the hotkey. + /* Get the hotkey */ // hRes = pshl->GetHotkey(&ShowCmd); - // if (SUCCEEDED(hRes)) ConsoleProps->HotKey = HotKey; + // if (SUCCEEDED(hRes)) ConsoleStartInfo->HotKey = HotKey; - // Get the icon location, if any. + /* Get the icon location, if any */ hRes = IShellLinkW_GetIconLocation(pshl, IconPath, IconPathLength, piIcon); if (!SUCCEEDED(hRes)) { IconPath[0] = L'\0'; } + + // FIXME: Since we still don't load console properties from the shortcut, + // return false. When this will be done, we will return true instead. + RetVal = FALSE; } IPersistFile_Release(ppf); } @@ -195,17 +208,20 @@ LoadShellLinkInfo(IN OUT PCONSOLE_PROPS ConsoleProps, } CoUninitialize(); - return TRUE; + return RetVal; } NTSTATUS WINAPI ConSrvInitConsole(OUT PCONSOLE* NewConsole, IN LPCWSTR AppPath, - IN OUT PCONSOLE_PROPS ConsoleProps, + IN OUT PCONSOLE_START_INFO ConsoleStartInfo, IN PCSR_PROCESS ConsoleLeaderProcess) { NTSTATUS Status; SECURITY_ATTRIBUTES SecurityAttributes; + CONSOLE_INFO ConsoleInfo; + SIZE_T Length = 0; + DWORD ProcessId = HandleToUlong(ConsoleLeaderProcess->ClientId.UniqueProcess); PCONSOLE Console; PCONSOLE_SCREEN_BUFFER NewBuffer; BOOL GuiMode; @@ -214,10 +230,11 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole, INT iIcon = 0; if (NewConsole == NULL) return STATUS_INVALID_PARAMETER; - *NewConsole = NULL; - /* Allocate a console structure */ + /* + * Allocate a console structure + */ Console = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CONSOLE)); if (NULL == Console) { @@ -226,46 +243,101 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole, } /* - * Check whether the process creating the console - * was launched via a shell-link. + * Load the console settings */ - if (ConsoleProps->dwStartupFlags & STARTF_TITLEISLINKNAME) - { - LoadShellLinkInfo(ConsoleProps, - IconPath, - MAX_PATH, - &iIcon); - ConsoleProps->dwStartupFlags &= ~STARTF_TITLEISLINKNAME; + /* 1. Load the default settings */ + ConSrvGetDefaultSettings(&ConsoleInfo, ProcessId); + + /* 2. Get the title of the console (initialize ConsoleInfo.ConsoleTitle) */ + Length = min(wcslen(ConsoleStartInfo->ConsoleTitle), + sizeof(ConsoleInfo.ConsoleTitle) / sizeof(ConsoleInfo.ConsoleTitle[0]) - 1); + wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleStartInfo->ConsoleTitle, Length); + ConsoleInfo.ConsoleTitle[Length] = L'\0'; + + /* + * 3. Check whether the process creating the + * console was launched via a shell-link + * (ConsoleInfo.ConsoleTitle may be updated). + */ + if (ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) + { + if (!LoadShellLinkConsoleInfo(ConsoleStartInfo, + &ConsoleInfo, + IconPath, + MAX_PATH, + &iIcon)) + { + ConsoleStartInfo->dwStartupFlags &= ~STARTF_TITLEISLINKNAME; + } } - /* Initialize the console */ + /* + * 4. Load the remaining console settings via the registry. + */ + if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0) + { + /* + * Either we weren't created by an app launched via a shell-link, + * or we failed to load shell-link console properties. + * Therefore, load the console infos for the application from the registry. + */ + ConSrvReadUserSettings(&ConsoleInfo, ProcessId); + + /* + * Now, update them with the properties the user might gave to us + * via the STARTUPINFO structure before calling CreateProcess + * (and which was transmitted via the ConsoleStartInfo structure). + */ + if (ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE) + { + ConsoleInfo.ScreenAttrib = ConsoleStartInfo->FillAttribute; + } + if (ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS) + { + ConsoleInfo.ScreenBufferSize = ConsoleStartInfo->ScreenBufferSize; + } + if (ConsoleStartInfo->dwStartupFlags & STARTF_USESHOWWINDOW) + { + ConsoleInfo.u.GuiInfo.ShowWindow = ConsoleStartInfo->ShowWindow; + } + if (ConsoleStartInfo->dwStartupFlags & STARTF_USEPOSITION) + { + ConsoleInfo.u.GuiInfo.AutoPosition = FALSE; + ConsoleInfo.u.GuiInfo.WindowOrigin = ConsoleStartInfo->ConsoleWindowOrigin; + } + if (ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE) + { + // ConsoleInfo.ConsoleSize = ConsoleStartInfo->ConsoleWindowSize; + ConsoleInfo.ConsoleSize.X = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cx; + ConsoleInfo.ConsoleSize.Y = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cy; + } + /* + if (ConsoleStartInfo->dwStartupFlags & STARTF_RUNFULLSCREEN) + { + } + */ + } + + /* + * Initialize the console + */ InitializeCriticalSection(&Console->Lock); Console->ReferenceCount = 0; - Console->LineBuffer = NULL; Console->ConsoleLeaderCID = ConsoleLeaderProcess->ClientId; InitializeListHead(&Console->ProcessList); - InitializeListHead(&Console->BufferList); - Console->ActiveBuffer = NULL; + memcpy(Console->Colors, ConsoleInfo.Colors, sizeof(ConsoleInfo.Colors)); + Console->Size = ConsoleInfo.ConsoleSize; - /* Initialize the input buffer */ + /* + * Initialize the input buffer + */ Console->InputBuffer.Header.Type = CONIO_INPUT_BUFFER_MAGIC; Console->InputBuffer.Header.Console = Console; - Console->InputBuffer.Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT; - InitializeListHead(&Console->InputBuffer.ReadWaitQueue); - InitializeListHead(&Console->InputBuffer.InputEvents); - - InitializeListHead(&Console->WriteWaitQueue); - InitializeListHead(&Console->HistoryBuffers); - Console->CodePage = GetOEMCP(); - Console->OutputCodePage = GetOEMCP(); - Console->GuiData = NULL; - Console->hIcon = Console->hIconSm = NULL; SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); SecurityAttributes.lpSecurityDescriptor = NULL; SecurityAttributes.bInheritHandle = TRUE; - Console->InputBuffer.ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL); if (NULL == Console->InputBuffer.ActiveEvent) { @@ -274,39 +346,52 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole, return STATUS_UNSUCCESSFUL; } - /* Allocate console screen buffer */ - NewBuffer = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CONSOLE_SCREEN_BUFFER)); - if (NULL == NewBuffer) - { - DeleteCriticalSection(&Console->Lock); - CloseHandle(Console->InputBuffer.ActiveEvent); - RtlFreeHeap(ConSrvHeap, 0, Console); - return STATUS_INSUFFICIENT_RESOURCES; - } - /* Init screen buffer with defaults */ - NewBuffer->CursorInfo.bVisible = TRUE; - NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; - /* Make console active, and insert into console list */ - Console->ActiveBuffer = NewBuffer; - /** Finish to initialize the screen buffer ** - ** Fix problems with MaxX == 0 and MaxY == 0 - ** - Status = ConSrvInitConsoleScreenBuffer(Console, NewBuffer); + // TODO: Use the values from ConsoleInfo. + Console->InputBuffer.Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | + ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT; + Console->QuickEdit = ConsoleInfo.QuickEdit; + Console->InsertMode = ConsoleInfo.InsertMode; + InitializeListHead(&Console->InputBuffer.ReadWaitQueue); + InitializeListHead(&Console->InputBuffer.InputEvents); + Console->LineBuffer = NULL; + Console->CodePage = GetOEMCP(); + Console->OutputCodePage = GetOEMCP(); + + /* Initialize a new screen buffer with default settings */ + InitializeListHead(&Console->BufferList); + Status = ConSrvCreateScreenBuffer(Console, + &NewBuffer, + ConsoleInfo.ScreenBufferSize, + ConsoleInfo.ScreenAttrib, + ConsoleInfo.PopupAttrib); if (!NT_SUCCESS(Status)) { - DPRINT1("ConSrvInitConsoleScreenBuffer: failed\n"); - RtlFreeHeap(ConSrvHeap, 0, NewBuffer); - DeleteCriticalSection(&Console->Lock); + DPRINT1("ConSrvCreateScreenBuffer: failed, Status = 0x%08lx\n", Status); CloseHandle(Console->InputBuffer.ActiveEvent); + DeleteCriticalSection(&Console->Lock); RtlFreeHeap(ConSrvHeap, 0, Console); return Status; } - **/ + /* Make the new screen buffer active */ + Console->ActiveBuffer = NewBuffer; + Console->FullScreen = ConsoleInfo.FullScreen; + InitializeListHead(&Console->WriteWaitQueue); + + /* + * Initialize the history buffers + */ + InitializeListHead(&Console->HistoryBuffers); + Console->HistoryBufferSize = ConsoleInfo.HistoryBufferSize; + Console->NumberOfHistoryBuffers = ConsoleInfo.NumberOfHistoryBuffers; + Console->HistoryNoDup = ConsoleInfo.HistoryNoDup; + + /* Finish initialization */ + Console->GuiData = NULL; + Console->hIcon = Console->hIconSm = NULL; /* Initialize the console title */ - Console->Title.MaximumLength = Console->Title.Length = 0; - Console->Title.Buffer = NULL; - if (ConsoleProps->ConsoleTitle[0] == L'\0') + RtlCreateUnicodeString(&Console->OriginalTitle, ConsoleStartInfo->ConsoleTitle); + if (ConsoleStartInfo->ConsoleTitle[0] == L'\0') { if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, Title, sizeof(Title) / sizeof(Title[0]))) { @@ -319,7 +404,7 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole, } else { - RtlCreateUnicodeString(&Console->Title, ConsoleProps->ConsoleTitle); + RtlCreateUnicodeString(&Console->Title, ConsoleStartInfo->ConsoleTitle); } /* @@ -331,7 +416,7 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole, if (!GuiMode) { DPRINT1("CONSRV: Opening text-mode console\n"); - Status = TuiInitConsole(Console); + Status = TuiInitConsole(Console, &ConsoleInfo); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to open text-mode console, switching to gui-mode, Status = 0x%08lx\n", Status); @@ -354,41 +439,27 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole, DPRINT1("CONSRV: Opening GUI-mode console\n"); Status = GuiInitConsole(Console, AppPath, - ConsoleProps->ShowWindow, + &ConsoleInfo, IconPath, iIcon); if (!NT_SUCCESS(Status)) { DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status); RtlFreeUnicodeString(&Console->Title); - DeleteCriticalSection(&Console->Lock); + RtlFreeUnicodeString(&Console->OriginalTitle); + ConioDeleteScreenBuffer(NewBuffer); CloseHandle(Console->InputBuffer.ActiveEvent); - RtlFreeHeap(ConSrvHeap, 0, NewBuffer); - /// ConioDeleteScreenBuffer(NewBuffer); + DeleteCriticalSection(&Console->Lock); RtlFreeHeap(ConSrvHeap, 0, Console); return Status; } } - // TODO: Move this call before initializing Tui/Gui console. But before fix freeing Buffer->Buffer !! - Status = ConSrvInitConsoleScreenBuffer(Console, NewBuffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ConSrvInitConsoleScreenBuffer: failed\n"); - ConioCleanupConsole(Console); - RtlFreeUnicodeString(&Console->Title); - DeleteCriticalSection(&Console->Lock); - CloseHandle(Console->InputBuffer.ActiveEvent); - RtlFreeHeap(ConSrvHeap, 0, NewBuffer); - RtlFreeHeap(ConSrvHeap, 0, Console); - return Status; - } - /* Copy buffer contents to screen */ ConioDrawConsole(Console); + /* Return the newly created console to the caller and a success code too */ *NewConsole = Console; - return STATUS_SUCCESS; } @@ -432,6 +503,7 @@ ConSrvDeleteConsole(PCONSOLE Console) if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent); DeleteCriticalSection(&Console->Lock); + RtlFreeUnicodeString(&Console->OriginalTitle); RtlFreeUnicodeString(&Console->Title); IntDeleteAllAliases(Console->Aliases); RtlFreeHeap(ConSrvHeap, 0, Console); @@ -484,11 +556,11 @@ CSR_API(SrvOpenConsole) else { Status = ConSrvInsertObject(ProcessData, - &OpenConsoleRequest->ConsoleHandle, - Object, - DesiredAccess, - OpenConsoleRequest->Inheritable, - ShareMode); + &OpenConsoleRequest->ConsoleHandle, + Object, + DesiredAccess, + OpenConsoleRequest->Inheritable, + ShareMode); } LeaveCriticalSection(&Console->Lock); @@ -515,9 +587,9 @@ CSR_API(SrvAllocConsole) } if ( !CsrValidateMessageBuffer(ApiMessage, - (PVOID*)&AllocConsoleRequest->ConsoleProps, + (PVOID*)&AllocConsoleRequest->ConsoleStartInfo, 1, - sizeof(CONSOLE_PROPS)) || + sizeof(CONSOLE_START_INFO)) || !CsrValidateMessageBuffer(ApiMessage, (PVOID*)&AllocConsoleRequest->AppPath, MAX_PATH + 1, @@ -545,7 +617,7 @@ CSR_API(SrvAllocConsole) &AllocConsoleRequest->InputHandle, &AllocConsoleRequest->OutputHandle, &AllocConsoleRequest->ErrorHandle, - AllocConsoleRequest->ConsoleProps); + AllocConsoleRequest->ConsoleStartInfo); if (!NT_SUCCESS(Status)) { DPRINT1("Console allocation failed\n"); @@ -558,6 +630,10 @@ CSR_API(SrvAllocConsole) /* Input Wait Handle */ AllocConsoleRequest->InputWaitHandle = ProcessData->ConsoleEvent; + /* Set the Property Dialog Handler */ + ProcessData->PropDispatcher = AllocConsoleRequest->PropDispatcher; + DPRINT("CONSRV: PropDispatcher address: %x\n", ProcessData->PropDispatcher); + /* Set the Ctrl Dispatcher */ ProcessData->CtrlDispatcher = AllocConsoleRequest->CtrlDispatcher; DPRINT("CONSRV: CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher); @@ -656,6 +732,10 @@ CSR_API(SrvAttachConsole) /* Input Wait Handle */ AttachConsoleRequest->InputWaitHandle = TargetProcessData->ConsoleEvent; + /* Set the Property Dialog Handler */ + TargetProcessData->PropDispatcher = AttachConsoleRequest->PropDispatcher; + DPRINT("CONSRV: PropDispatcher address: %x\n", TargetProcessData->PropDispatcher); + /* Set the Ctrl Dispatcher */ TargetProcessData->CtrlDispatcher = AttachConsoleRequest->CtrlDispatcher; DPRINT("CONSRV: CtrlDispatcher address: %x\n", TargetProcessData->CtrlDispatcher); @@ -677,6 +757,12 @@ CSR_API(SrvFreeConsole) CSR_API(SrvSetConsoleMode) { +#define CONSOLE_INPUT_MODE_VALID ( ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | \ + ENABLE_ECHO_INPUT | ENABLE_WINDOW_INPUT | \ + ENABLE_MOUSE_INPUT | \ + ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS ) +#define CONSOLE_OUTPUT_MODE_VALID ( ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT ) + NTSTATUS Status; PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest; Object_t* Object = NULL; diff --git a/win32ss/user/consrv/consrv.h b/win32ss/user/consrv/consrv.h index b8cb53f61cb..41f0b1fd0db 100644 --- a/win32ss/user/consrv/consrv.h +++ b/win32ss/user/consrv/consrv.h @@ -25,6 +25,7 @@ #include #define NTOS_MODE_USER #include +#include #include #include #include @@ -42,9 +43,6 @@ #include "resource.h" -/* Shared header with console.dll */ -#include "console.h" - extern HINSTANCE ConSrvDllInstance; extern HANDLE ConSrvHeap; @@ -93,6 +91,7 @@ typedef struct _CONSOLE_PROCESS_DATA PCONSOLE_IO_HANDLE HandleTable; // Length-varying table LPTHREAD_START_ROUTINE CtrlDispatcher; + LPTHREAD_START_ROUTINE PropDispatcher; // We hold the property dialog handler there, till all the GUI thingie moves out from CSRSS. } CONSOLE_PROCESS_DATA, *PCONSOLE_PROCESS_DATA; @@ -182,7 +181,7 @@ NTSTATUS FASTCALL ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData, PHANDLE pInputHandle, PHANDLE pOutputHandle, PHANDLE pErrorHandle, - PCONSOLE_PROPS ConsoleProps); + PCONSOLE_START_INFO ConsoleStartInfo); NTSTATUS FASTCALL ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData, struct _CONSOLE* Console, BOOL CreateNewHandlesTable, diff --git a/win32ss/user/consrv/guiconsole.c b/win32ss/user/consrv/guiconsole.c index 3f894761723..7c963e04b7e 100644 --- a/win32ss/user/consrv/guiconsole.c +++ b/win32ss/user/consrv/guiconsole.c @@ -2,15 +2,15 @@ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL * FILE: win32ss/user/consrv/guiconsole.c - * PURPOSE: Implementation of gui-mode consoles + * PURPOSE: Implementation of GUI-mode consoles * PROGRAMMERS: */ -/* INCLUDES ******************************************************************/ +/* INCLUDES *******************************************************************/ #include "consrv.h" +#include "settings.h" #include "guiconsole.h" -#include #define NDEBUG #include @@ -35,36 +35,24 @@ PrivateCsrssManualGuiCheck(LONG Check) NtUserCallOneParam(Check, ONEPARAM_ROUTINE_CSRSS_GUICHECK); } -/* GLOBALS *******************************************************************/ +/* GLOBALS ********************************************************************/ typedef struct _GUI_CONSOLE_DATA { -/* GUI-specific */ HFONT Font; -/* GUI-specific */ WCHAR FontName[LF_FACESIZE]; -/* GUI-specific */ DWORD FontSize; -/* GUI-specific */ DWORD FontWeight; -/* GUI-specific */ UINT CharWidth; -/* GUI-specific */ UINT CharHeight; -/* non-specific */ BOOL CursorBlinkOn; -/* non-specific */ BOOL ForceCursorOff; - CRITICAL_SECTION Lock; - HMODULE ConsoleLibrary; HANDLE hGuiInitEvent; - -/* GUI-specific */ DWORD FullScreen; -/* non-specific */ DWORD QuickEdit; -/* non-specific */ DWORD InsertMode; -/* GUI-specific */ DWORD WindowPosition; -/* GUI-specific */ DWORD UseRasterFonts; -/* non-specific */ COLORREF ScreenText; -/* non-specific */ COLORREF ScreenBackground; -/* non-specific */ COLORREF PopupBackground; -/* non-specific */ COLORREF PopupText; -/* non-specific */ COLORREF Colors[16]; - WCHAR szProcessName[MAX_PATH]; BOOL WindowSizeLock; POINT OldCursor; + + // HWND hWindow; + // HICON hIcon; + // HICON hIconSm; + + HFONT Font; + UINT CharWidth; + UINT CharHeight; + + GUI_CONSOLE_INFO GuiInfo; } GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA; static BOOL ConsInitialized = FALSE; @@ -94,7 +82,6 @@ static const GUICONSOLE_MENUITEM GuiConsoleEditMenuItems[] = static const GUICONSOLE_MENUITEM GuiConsoleMainMenuItems[] = { - { (UINT)-1, NULL, 0 }, /* Separator */ { IDS_EDIT, GuiConsoleEditMenuItems, 0 }, { IDS_DEFAULTS, NULL, ID_SYSTEM_DEFAULTS }, { IDS_PROPERTIES, NULL, ID_SYSTEM_PROPERTIES }, @@ -102,29 +89,32 @@ static const GUICONSOLE_MENUITEM GuiConsoleMainMenuItems[] = { 0, NULL, 0 } /* End of list */ }; -static const COLORREF s_Colors[] = +/* + * Default 16-color palette for foreground and background + * (corresponding flags in comments). + */ +const COLORREF s_Colors[16] = { - RGB(0, 0, 0), - RGB(0, 0, 128), - RGB(0, 128, 0), - RGB(0, 128, 128), - RGB(128, 0, 0), - RGB(128, 0, 128), - RGB(128, 128, 0), - RGB(192, 192, 192), - RGB(128, 128, 128), - RGB(0, 0, 255), - RGB(0, 255, 0), - RGB(0, 255, 255), - RGB(255, 0, 0), - RGB(255, 0, 255), - RGB(255, 255, 0), - RGB(255, 255, 255) + RGB(0, 0, 0), // (Black) + RGB(0, 0, 128), // BLUE + RGB(0, 128, 0), // GREEN + RGB(0, 128, 128), // BLUE | GREEN + RGB(128, 0, 0), // RED + RGB(128, 0, 128), // BLUE | RED + RGB(128, 128, 0), // GREEN | RED + RGB(192, 192, 192), // BLUE | GREEN | RED + + RGB(128, 128, 128), // (Grey) INTENSITY + RGB(0, 0, 255), // BLUE | INTENSITY + RGB(0, 255, 0), // GREEN | INTENSITY + RGB(0, 255, 255), // BLUE | GREEN | INTENSITY + RGB(255, 0, 0), // RED | INTENSITY + RGB(255, 0, 255), // BLUE | RED | INTENSITY + RGB(255, 255, 0), // GREEN | RED | INTENSITY + RGB(255, 255, 255) // BLUE | GREEN | RED | INTENSITY }; -#define GuiConsoleRGBFromAttribute(GuiData, Attribute) ((GuiData)->Colors[(Attribute) & 0xF]) - -/* FUNCTIONS *****************************************************************/ +/* FUNCTIONS ******************************************************************/ static VOID GuiConsoleAppendMenuItems(HMENU hMenu, @@ -194,472 +184,328 @@ GuiConsoleCreateSysMenu(PCONSOLE Console) } } + +static VOID +GuiConsoleCopy(HWND hWnd, PCONSOLE Console); +static VOID +GuiConsolePaste(HWND hWnd, PCONSOLE Console); +static VOID +GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord); +static VOID +GuiConsoleShowConsoleProperties(PCONSOLE Console, + HWND hWnd, + BOOL Defaults); + +static LRESULT +GuiConsoleHandleSysMenuCommand(PCONSOLE Console, + HWND hWnd, + WPARAM wParam, LPARAM lParam) +{ + LRESULT Ret = TRUE; + COORD bottomRight = { 0, 0 }; + + switch (wParam) + { + case ID_SYSTEM_EDIT_MARK: + DPRINT1("Marking not handled yet\n"); + break; + + case ID_SYSTEM_EDIT_COPY: + GuiConsoleCopy(hWnd, Console); + break; + + case ID_SYSTEM_EDIT_PASTE: + GuiConsolePaste(hWnd, Console); + break; + + case ID_SYSTEM_EDIT_SELECTALL: + bottomRight.X = Console->Size.X - 1; + bottomRight.Y = Console->Size.Y - 1; + GuiConsoleUpdateSelection(Console, &bottomRight); + break; + + case ID_SYSTEM_EDIT_SCROLL: + DPRINT1("Scrolling is not handled yet\n"); + break; + + case ID_SYSTEM_EDIT_FIND: + DPRINT1("Finding is not handled yet\n"); + break; + + case ID_SYSTEM_DEFAULTS: + GuiConsoleShowConsoleProperties(Console, hWnd, TRUE); + break; + + case ID_SYSTEM_PROPERTIES: + GuiConsoleShowConsoleProperties(Console, hWnd, FALSE); + break; + + default: + Ret = DefWindowProcW(hWnd, WM_SYSCOMMAND, wParam, lParam); + break; + } + return Ret; +} + +static VOID +GuiConsoleShowConsoleProperties(PCONSOLE Console, + HWND hWnd, + BOOL Defaults) +{ + NTSTATUS Status; + PGUI_CONSOLE_DATA GuiData = Console->GuiData; + PCONSOLE_PROCESS_DATA ProcessData; + HANDLE hSection = NULL, hClientSection = NULL; + LARGE_INTEGER SectionSize; + ULONG ViewSize = 0; + SIZE_T Length = 0; + PCONSOLE_PROPS pSharedInfo = NULL; + + DPRINT("GuiConsoleShowConsoleProperties entered\n"); + + if (GuiData == NULL) return; + + /* Create a memory section to share with the applet, and map it */ + SectionSize.QuadPart = sizeof(CONSOLE_PROPS); + Status = NtCreateSection(&hSection, + SECTION_ALL_ACCESS, + NULL, + &SectionSize, + PAGE_READWRITE, + SEC_COMMIT, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Error: Impossible to create a shared section ; Status = %lu\n", Status); + return; + } + + Status = NtMapViewOfSection(hSection, + NtCurrentProcess(), + (PVOID*)&pSharedInfo, + 0, + 0, + NULL, + &ViewSize, + ViewUnmap, + 0, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status); + NtClose(hSection); + return; + } + + /* + * Setup the shared console properties structure. + */ + /* Header */ + pSharedInfo->hConsoleWindow = hWnd; // Console->hWindow; + pSharedInfo->ShowDefaultParams = Defaults; + /* Console information */ + pSharedInfo->ci.HistoryBufferSize = Console->HistoryBufferSize; + pSharedInfo->ci.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers; + pSharedInfo->ci.HistoryNoDup = Console->HistoryNoDup; + pSharedInfo->ci.FullScreen = Console->FullScreen; + pSharedInfo->ci.QuickEdit = Console->QuickEdit; + pSharedInfo->ci.InsertMode = Console->InsertMode; + pSharedInfo->ci.InputBufferSize = 0; + pSharedInfo->ci.ScreenBufferSize = Console->ActiveBuffer->ScreenBufferSize; + pSharedInfo->ci.ConsoleSize = Console->Size; + pSharedInfo->ci.CursorBlinkOn; + pSharedInfo->ci.ForceCursorOff; + pSharedInfo->ci.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize; + pSharedInfo->ci.ScreenAttrib = Console->ActiveBuffer->ScreenDefaultAttrib; + pSharedInfo->ci.PopupAttrib = Console->ActiveBuffer->PopupDefaultAttrib; + pSharedInfo->ci.CodePage; + /* GUI Information */ + wcsncpy(pSharedInfo->ci.u.GuiInfo.FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE); + pSharedInfo->ci.u.GuiInfo.FontSize = (DWORD)GuiData->GuiInfo.FontSize; + pSharedInfo->ci.u.GuiInfo.FontWeight = GuiData->GuiInfo.FontWeight; + pSharedInfo->ci.u.GuiInfo.UseRasterFonts = GuiData->GuiInfo.UseRasterFonts; + /// pSharedInfo->ci.u.GuiInfo.WindowPosition = GuiData->GuiInfo.WindowPosition; + pSharedInfo->ci.u.GuiInfo.AutoPosition = GuiData->GuiInfo.AutoPosition; + pSharedInfo->ci.u.GuiInfo.WindowOrigin = GuiData->GuiInfo.WindowOrigin; + /* Palette */ + memcpy(pSharedInfo->ci.Colors, Console->Colors, sizeof(s_Colors)); // FIXME: Possible buffer overflow if s_colors is bigger than pSharedInfo->Colors. + /* Title of the console, original one corresponding to the one set by the console leader */ + Length = min(sizeof(pSharedInfo->ci.ConsoleTitle) / sizeof(pSharedInfo->ci.ConsoleTitle[0]) - 1, + Console->OriginalTitle.Length / sizeof(WCHAR)); + wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length); + pSharedInfo->ci.ConsoleTitle[Length] = L'\0'; + + /* Unmap the view */ + NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo); + + /* Get the console leader process, our client */ + ProcessData = CONTAINING_RECORD(Console->ProcessList.Blink, + CONSOLE_PROCESS_DATA, + ConsoleLink); + + /* Duplicate the section handle for the client */ + Status = NtDuplicateObject(NtCurrentProcess(), + hSection, + ProcessData->Process->ProcessHandle, + &hClientSection, + 0, 0, DUPLICATE_SAME_ACCESS); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Error: Impossible to duplicate section handle for client ; Status = %lu\n", Status); + NtClose(hSection); + return; + } + + /* Start the properties dialog */ + if (ProcessData->PropDispatcher) + { + HANDLE Thread; + + Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0, + ProcessData->PropDispatcher, + (PVOID)hClientSection, 0, NULL); + if (NULL == Thread) + { + DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError()); + return; + } + + DPRINT1("We succeeded at creating ProcessData->PropDispatcher remote thread, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process); + /// WaitForSingleObject(Thread, INFINITE); + CloseHandle(Thread); + } + + /* We have finished, close the section handle */ + NtClose(hSection); + return; +} + + +static NTSTATUS WINAPI +GuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Size); +VOID FASTCALL +GuiConsoleInitScrollbar(PCONSOLE Console, HWND hwnd); + +static VOID +GuiApplyUserSettings(PCONSOLE Console, + HANDLE hClientSection, + BOOL SaveSettings) +{ + NTSTATUS Status; + PCONSOLE_PROCESS_DATA ProcessData; + HANDLE hSection = NULL; + ULONG ViewSize = 0; + PCONSOLE_PROPS pConInfo = NULL; + PCONSOLE_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer; + COORD BufSize; + BOOL SizeChanged = FALSE; + + /// LOCK /// EnterCriticalSection(&Console->Lock); + + /* Get the console leader process, our client */ + ProcessData = CONTAINING_RECORD(Console->ProcessList.Blink, + CONSOLE_PROCESS_DATA, + ConsoleLink); + + /* 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); + return; + } + + /* Get a view of the shared section */ + Status = NtMapViewOfSection(hSection, + NtCurrentProcess(), + (PVOID*)&pConInfo, + 0, + 0, + NULL, + &ViewSize, + ViewUnmap, + 0, + PAGE_READONLY); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Error when mapping view of file, Status = %lu\n", Status); + NtClose(hSection); + return; + } + + /* Check that the section is well-sized */ + if (ViewSize < sizeof(CONSOLE_PROPS)) + { + DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_PROPS)\n"); + NtUnmapViewOfSection(NtCurrentProcess(), pConInfo); + NtClose(hSection); + return; + } + + /* + * Apply foreground and background colors for both screen and popup. + * Copy the new palette. + * TODO: Really update the screen attributes as FillConsoleOutputAttribute does. + */ + ActiveBuffer->ScreenDefaultAttrib = pConInfo->ci.ScreenAttrib; + ActiveBuffer->PopupDefaultAttrib = pConInfo->ci.PopupAttrib; + memcpy(Console->Colors, pConInfo->ci.Colors, sizeof(s_Colors)); // FIXME: Possible buffer overflow if s_colors is bigger than pConInfo->Colors. + + /* Apply cursor size */ + ActiveBuffer->CursorInfo.dwSize = min(max(pConInfo->ci.CursorSize, 1), 100); + + if (pConInfo->ci.ConsoleSize.X != Console->Size.X || + pConInfo->ci.ConsoleSize.Y != Console->Size.Y) + { + /* Resize window */ + Console->Size = pConInfo->ci.ConsoleSize; + SizeChanged = TRUE; + } + + BufSize = pConInfo->ci.ScreenBufferSize; + if (BufSize.X != ActiveBuffer->ScreenBufferSize.X || BufSize.Y != ActiveBuffer->ScreenBufferSize.Y) + { + if (NT_SUCCESS(GuiResizeBuffer(Console, ActiveBuffer, BufSize))) + SizeChanged = TRUE; + } + + if (SizeChanged) + { + PGUI_CONSOLE_DATA GuiData = Console->GuiData; + if (GuiData) + { + GuiData->WindowSizeLock = TRUE; + GuiConsoleInitScrollbar(Console, pConInfo->hConsoleWindow); + GuiData->WindowSizeLock = FALSE; + } + } + + /// LOCK /// LeaveCriticalSection(&Console->Lock); + InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE); + + /* Save settings if needed */ + // FIXME: Do it in the console properties applet ?? + if (SaveSettings) + { + DWORD ProcessId = HandleToUlong(ProcessData->Process->ClientId.UniqueProcess); + ConSrvWriteUserSettings(&pConInfo->ci, ProcessId); + } + + /* Finally, close the section */ + NtUnmapViewOfSection(NtCurrentProcess(), pConInfo); + NtClose(hSection); +} + static PCONSOLE GuiGetWindowConsole(HWND hWnd) { return (PCONSOLE)GetWindowLongPtrW(hWnd, GWLP_USERDATA); } - - -/******************************************************************************* - ** The following functions may be available for both GUI and CUI - ******************************************************************************/ - -static BOOL -GuiConsoleOpenUserRegistryPathPerProcessId(DWORD ProcessId, PHANDLE hProcHandle, PHKEY hResult, REGSAM samDesired) -{ - HANDLE hProcessToken = NULL; - HANDLE hProcess; - - BYTE Buffer[256]; - DWORD Length = 0; - UNICODE_STRING SidName; - LONG res; - PTOKEN_USER TokUser; - - hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | READ_CONTROL, FALSE, ProcessId); - if (!hProcess) - { - DPRINT("Error: OpenProcess failed(0x%x)\n", GetLastError()); - return FALSE; - } - - if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken)) - { - DPRINT("Error: OpenProcessToken failed(0x%x)\n", GetLastError()); - CloseHandle(hProcess); - return FALSE; - } - - if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length)) - { - DPRINT("Error: GetTokenInformation failed(0x%x)\n",GetLastError()); - CloseHandle(hProcessToken); - CloseHandle(hProcess); - return FALSE; - } - - TokUser = ((PTOKEN_USER)Buffer)->User.Sid; - if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE))) - { - DPRINT("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError()); - CloseHandle(hProcessToken); - CloseHandle(hProcess); - return FALSE; - } - - res = RegOpenKeyExW(HKEY_USERS, SidName.Buffer, 0, samDesired, hResult); - RtlFreeUnicodeString(&SidName); - - CloseHandle(hProcessToken); - if (res != ERROR_SUCCESS) - { - CloseHandle(hProcess); - return FALSE; - } - - if (hProcHandle) - *hProcHandle = hProcess; - else - CloseHandle(hProcess); - - return TRUE; -} - -static BOOL -GuiConsoleOpenUserSettings(PGUI_CONSOLE_DATA GuiData, DWORD ProcessId, PHKEY hSubKey, REGSAM samDesired, BOOL bCreate) -{ - WCHAR szProcessName[MAX_PATH]; - WCHAR szBuffer[MAX_PATH]; - UINT fLength, wLength; - DWORD dwBitmask, dwLength; - WCHAR CurDrive[] = { 'A',':', 0 }; - HANDLE hProcess; - HKEY hKey; - WCHAR * ptr; - - /* - * console properties are stored under - * HKCU\Console\* - * - * There are 3 ways to store console properties - * - * 1. use console title as subkey name - * i.e. cmd.exe - * - * 2. use application name as subkey name - * - * 3. use unexpanded path to console application. - * i.e. %SystemRoot%_system32_cmd.exe - */ - - DPRINT("GuiConsoleOpenUserSettings entered\n"); - - if (!GuiConsoleOpenUserRegistryPathPerProcessId(ProcessId, &hProcess, &hKey, samDesired)) - { - DPRINT("GuiConsoleOpenUserRegistryPathPerProcessId failed\n"); - return FALSE; - } - - /* FIXME we do not getting the process name so no menu will be loading, why ?*/ - fLength = GetProcessImageFileNameW(hProcess, szProcessName, sizeof(GuiData->szProcessName) / sizeof(WCHAR)); - CloseHandle(hProcess); - - //DPRINT1("szProcessName3 : %S\n",szProcessName); - - if (!fLength) - { - DPRINT("GetProcessImageFileNameW failed(0x%x)ProcessId %d\n", GetLastError(), ProcessId); - return FALSE; - } - /* - * try the process name as path - */ - - ptr = wcsrchr(szProcessName, L'\\'); - wcscpy(GuiData->szProcessName, ptr); - - swprintf(szBuffer, L"Console%s",ptr); - DPRINT("#1 Path : %S\n", szBuffer); - - if (bCreate) - { - if (RegCreateKeyW(hKey, szBuffer, hSubKey) == ERROR_SUCCESS) - { - RegCloseKey(hKey); - return TRUE; - } - RegCloseKey(hKey); - return FALSE; - } - - if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) - { - RegCloseKey(hKey); - return TRUE; - } - - /* - * try the "Shortcut to processname" as path - * FIXME: detect wheter the process was started as a shortcut - */ - - swprintf(szBuffer, L"Console\\Shortcut to %S", ptr); - DPRINT("#2 Path : %S\n", szBuffer); - if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) - { - swprintf(GuiData->szProcessName, L"Shortcut to %S", ptr); - RegCloseKey(hKey); - return TRUE; - } - - /* - * if the path contains \\Device\\HarddiskVolume1\... remove it - */ - - if (szProcessName[0] == L'\\') - { - dwBitmask = GetLogicalDrives(); - while(dwBitmask) - { - if (dwBitmask & 0x1) - { - dwLength = QueryDosDeviceW(CurDrive, szBuffer, MAX_PATH); - if (dwLength) - { - if (!memcmp(szBuffer, szProcessName, (dwLength-2)*sizeof(WCHAR))) - { - wcscpy(szProcessName, CurDrive); - RtlMoveMemory(&szProcessName[2], &szProcessName[dwLength-1], fLength - dwLength -1); - break; - } - } - } - dwBitmask = (dwBitmask >> 1); - CurDrive[0]++; - } - } - - /* - * last attempt: check whether the file is under %SystemRoot% - * and use path like Console\%SystemRoot%_dir_dir2_file.exe - */ - - wLength = GetWindowsDirectoryW(szBuffer, MAX_PATH); - if (wLength) - { - if (!wcsncmp(szProcessName, szBuffer, wLength)) - { - /* replace slashes by underscores */ - while((ptr = wcschr(szProcessName, L'\\'))) - ptr[0] = L'_'; - - swprintf(szBuffer, L"Console\\%%SystemRoot%%%S", &szProcessName[wLength]); - DPRINT("#3 Path : %S\n", szBuffer); - if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) - { - swprintf(GuiData->szProcessName, L"%%SystemRoot%%%S", &szProcessName[wLength]); - RegCloseKey(hKey); - return TRUE; - } - } - } - RegCloseKey(hKey); - return FALSE; -} - -static VOID -GuiConsoleWriteUserSettings(PCONSOLE Console) -{ - PGUI_CONSOLE_DATA GuiData = Console->GuiData; - HKEY hKey; - PCONSOLE_PROCESS_DATA ProcessData; - - if (Console->ProcessList.Flink == &Console->ProcessList) - { - DPRINT("GuiConsoleWriteUserSettings: No Process!!!\n"); - return; - } - - ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CONSOLE_PROCESS_DATA, ConsoleLink); - if (!GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->Process->ClientId.UniqueProcess), &hKey, KEY_READ | KEY_WRITE, TRUE)) - { - return; - } - - if (Console->ActiveBuffer->CursorInfo.dwSize <= 1) - { - RegDeleteKeyW(hKey, L"CursorSize"); - } - else - { - RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD)); - } - - if (Console->NumberOfHistoryBuffers == 5) - { - RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers"); - } - else - { - RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&Console->NumberOfHistoryBuffers, sizeof(DWORD)); - } - - if (Console->HistoryBufferSize == 50) - { - RegDeleteKeyW(hKey, L"HistoryBufferSize"); - } - else - { - RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&Console->HistoryBufferSize, sizeof(DWORD)); - } - - if (GuiData->FullScreen == FALSE) - { - RegDeleteKeyW(hKey, L"FullScreen"); - } - else - { - RegSetValueExW(hKey, L"FullScreen", 0, REG_DWORD, (const BYTE *)&GuiData->FullScreen, sizeof(DWORD)); - } - - if (GuiData->QuickEdit == FALSE) - { - RegDeleteKeyW(hKey, L"QuickEdit"); - } - else - { - RegSetValueExW(hKey, L"QuickEdit", 0, REG_DWORD, (const BYTE *)&GuiData->QuickEdit, sizeof(DWORD)); - } - - if (GuiData->InsertMode == TRUE) - { - RegDeleteKeyW(hKey, L"InsertMode"); - } - else - { - RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD)); - } - - if (Console->HistoryNoDup == FALSE) - { - RegDeleteKeyW(hKey, L"HistoryNoDup"); - } - else - { - DWORD Temp = Console->HistoryNoDup; - RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD)); - } - - if (GuiData->ScreenText == RGB(192, 192, 192)) - { - /* - * MS uses console attributes instead of real color - */ - RegDeleteKeyW(hKey, L"ScreenText"); - } - else - { - RegSetValueExW(hKey, L"ScreenText", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenText, sizeof(COLORREF)); - } - - if (GuiData->ScreenBackground == RGB(0, 0, 0)) - { - RegDeleteKeyW(hKey, L"ScreenBackground"); - } - else - { - RegSetValueExW(hKey, L"ScreenBackground", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenBackground, sizeof(COLORREF)); - } - - RegCloseKey(hKey); -} - -static void -GuiConsoleReadUserSettings(HKEY hKey, PCONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCONSOLE_SCREEN_BUFFER Buffer) -{ - DWORD dwNumSubKeys = 0; - DWORD dwIndex; - DWORD dwValueName; - DWORD dwValue; - DWORD dwType; - WCHAR szValueName[MAX_PATH]; - WCHAR szValue[LF_FACESIZE] = L"\0"; - DWORD Value; - - if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) - { - DPRINT("GuiConsoleReadUserSettings: RegQueryInfoKey failed\n"); - return; - } - - DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys); - - for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++) - { - dwValue = sizeof(Value); - dwValueName = MAX_PATH; - - if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS) - { - if (dwType == REG_SZ) - { - /* - * retry in case of string value - */ - dwValue = sizeof(szValue); - dwValueName = LF_FACESIZE; - if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS) - break; - } - else - break; - } - if (!wcscmp(szValueName, L"CursorSize")) - { - if (Value == 0x32) - { - Buffer->CursorInfo.dwSize = Value; - } - else if (Value == 0x64) - { - Buffer->CursorInfo.dwSize = Value; - } - } - else if (!wcscmp(szValueName, L"ScreenText")) - { - GuiData->ScreenText = Value; - } - else if (!wcscmp(szValueName, L"ScreenBackground")) - { - GuiData->ScreenBackground = Value; - } - else if (!wcscmp(szValueName, L"FaceName")) - { - wcscpy(GuiData->FontName, szValue); - } - else if (!wcscmp(szValueName, L"FontSize")) - { - GuiData->FontSize = Value; - } - else if (!wcscmp(szValueName, L"FontWeight")) - { - GuiData->FontWeight = Value; - } - else if (!wcscmp(szValueName, L"HistoryNoDup")) - { - Console->HistoryNoDup = Value; - } - else if (!wcscmp(szValueName, L"WindowSize")) - { - Console->Size.X = LOWORD(Value); - Console->Size.Y = HIWORD(Value); - } - else if (!wcscmp(szValueName, L"ScreenBufferSize")) - { - if(Buffer) - { - Buffer->MaxX = LOWORD(Value); - Buffer->MaxY = HIWORD(Value); - } - } - else if (!wcscmp(szValueName, L"FullScreen")) - { - GuiData->FullScreen = Value; - } - else if (!wcscmp(szValueName, L"QuickEdit")) - { - GuiData->QuickEdit = Value; - } - else if (!wcscmp(szValueName, L"InsertMode")) - { - GuiData->InsertMode = Value; - } - } -} - -static VOID -GuiConsoleUseDefaults(PCONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCONSOLE_SCREEN_BUFFER Buffer) -{ - /* - * init guidata with default properties - */ - -/* GUI-specific */ wcscpy(GuiData->FontName, L"DejaVu Sans Mono"); -/* GUI-specific */ GuiData->FontSize = 0x0008000C; // font is 8x12 -/* GUI-specific */ GuiData->FontWeight = FW_NORMAL; -/* GUI-specific */ GuiData->FullScreen = FALSE; -/* non-specific */ GuiData->QuickEdit = FALSE; -/* non-specific */ GuiData->InsertMode = TRUE; -/* non-specific */ GuiData->ScreenText = RGB(192, 192, 192); -/* non-specific */ GuiData->ScreenBackground = RGB(0, 0, 0); -/* non-specific */ GuiData->PopupText = RGB(128, 0, 128); -/* non-specific */ GuiData->PopupBackground = RGB(255, 255, 255); - GuiData->WindowPosition = UINT_MAX; -/* GUI-specific */ GuiData->UseRasterFonts = TRUE; -/* non-specific */ memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors)); - -/* non-specific */ Console->HistoryBufferSize = 50; -/* non-specific */ Console->NumberOfHistoryBuffers = 5; -/* non-specific */ Console->HistoryNoDup = FALSE; -/* XUI-specific */ Console->Size.X = 80; -/* XUI-specific */ Console->Size.Y = 25; - - if (Buffer) - { -/* XUI-specific */ Buffer->MaxX = 80; -/* XUI-specific */ Buffer->MaxY = 300; -/* XUI-specific */ Buffer->CursorInfo.bVisible = TRUE; -/* XUI-specific */ Buffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; - } -} - -/******************************************************************************* - ******************************************************************************/ - - - VOID FASTCALL GuiConsoleInitScrollbar(PCONSOLE Console, HWND hwnd) @@ -674,9 +520,9 @@ GuiConsoleInitScrollbar(PCONSOLE Console, HWND hwnd) sInfo.cbSize = sizeof(SCROLLINFO); sInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; sInfo.nMin = 0; - if (Console->ActiveBuffer->MaxY > Console->Size.Y) + if (Console->ActiveBuffer->ScreenBufferSize.Y > Console->Size.Y) { - sInfo.nMax = Console->ActiveBuffer->MaxY - 1; + sInfo.nMax = Console->ActiveBuffer->ScreenBufferSize.Y - 1; sInfo.nPage = Console->Size.Y; sInfo.nPos = Console->ActiveBuffer->ShowY; SetScrollInfo(hwnd, SB_VERT, &sInfo, TRUE); @@ -688,9 +534,9 @@ GuiConsoleInitScrollbar(PCONSOLE Console, HWND hwnd) ShowScrollBar(hwnd, SB_VERT, FALSE); } - if (Console->ActiveBuffer->MaxX > Console->Size.X) + if (Console->ActiveBuffer->ScreenBufferSize.X > Console->Size.X) { - sInfo.nMax = Console->ActiveBuffer->MaxX - 1; + sInfo.nMax = Console->ActiveBuffer->ScreenBufferSize.X - 1; sInfo.nPage = Console->Size.X; sInfo.nPos = Console->ActiveBuffer->ShowX; SetScrollInfo(hwnd, SB_HORZ, &sInfo, TRUE); @@ -711,13 +557,11 @@ static BOOL GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create) { PCONSOLE Console = (PCONSOLE)Create->lpCreateParams; - PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->GuiData; + PGUI_CONSOLE_DATA GuiData = Console->GuiData; HDC Dc; HFONT OldFont; TEXTMETRICW Metrics; SIZE CharSize; - PCONSOLE_PROCESS_DATA ProcessData; - HKEY hKey; Console->hWindow = hWnd; @@ -727,31 +571,22 @@ GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create) return FALSE; } - GuiConsoleUseDefaults(Console, GuiData, Console->ActiveBuffer); - if (Console->ProcessList.Flink != &Console->ProcessList) - { - ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CONSOLE_PROCESS_DATA, ConsoleLink); - if (GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->Process->ClientId.UniqueProcess), &hKey, KEY_READ, FALSE)) - { - GuiConsoleReadUserSettings(hKey, Console, GuiData, Console->ActiveBuffer); - RegCloseKey(hKey); - } - } - InitializeCriticalSection(&GuiData->Lock); - GuiData->Font = CreateFontW(LOWORD(GuiData->FontSize), - 0, //HIWORD(GuiData->FontSize), + GuiData->Font = CreateFontW(LOWORD(GuiData->GuiInfo.FontSize), + 0, // HIWORD(GuiData->GuiInfo.FontSize), 0, TA_BASELINE, - GuiData->FontWeight, + GuiData->GuiInfo.FontWeight, FALSE, FALSE, FALSE, OEM_CHARSET, - OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, - NONANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE, - GuiData->FontName); + OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, + NONANTIALIASED_QUALITY, + FIXED_PITCH | GuiData->GuiInfo.FontFamily /* FF_DONTCARE */, + GuiData->GuiInfo.FaceName); if (NULL == GuiData->Font) { DPRINT1("GuiConsoleNcCreate: CreateFont failed\n"); @@ -798,11 +633,13 @@ GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create) SelectObject(Dc, OldFont); ReleaseDC(hWnd, Dc); - GuiData->CursorBlinkOn = TRUE; - GuiData->ForceCursorOff = FALSE; + + // FIXME: Keep these instructions here ? /////////////////////////////////// + Console->ActiveBuffer->CursorBlinkOn = TRUE; + Console->ActiveBuffer->ForceCursorOff = FALSE; + //////////////////////////////////////////////////////////////////////////// DPRINT("Console %p GuiData %p\n", Console, GuiData); - Console->GuiData = GuiData; SetWindowLongPtrW(hWnd, GWLP_USERDATA, (DWORD_PTR)Console); SetTimer(hWnd, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL); @@ -915,11 +752,11 @@ GuiConsolePaint(PCONSOLE Console, RightChar = (rc->right + (GuiData->CharWidth - 1)) / GuiData->CharWidth - 1 + Buff->ShowX; LastAttribute = ConioCoordToPointer(Buff, LeftChar, TopLine)[1]; - SetTextColor(hDC, GuiConsoleRGBFromAttribute(GuiData, LastAttribute)); - SetBkColor(hDC, GuiConsoleRGBFromAttribute(GuiData, LastAttribute >> 4)); + SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute))); + SetBkColor(hDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute))); - if (BottomLine >= Buff->MaxY) BottomLine = Buff->MaxY - 1; - if (RightChar >= Buff->MaxX) RightChar = Buff->MaxX - 1; + if (BottomLine >= Buff->ScreenBufferSize.Y) BottomLine = Buff->ScreenBufferSize.Y - 1; + if (RightChar >= Buff->ScreenBufferSize.X) RightChar = Buff->ScreenBufferSize.X - 1; OldFont = SelectObject(hDC, GuiData->Font); @@ -945,8 +782,8 @@ GuiConsolePaint(PCONSOLE Console, Attribute = *(From + 1); if (Attribute != LastAttribute) { - SetTextColor(hDC, GuiConsoleRGBFromAttribute(GuiData, Attribute)); - SetBkColor(hDC, GuiConsoleRGBFromAttribute(GuiData, Attribute >> 4)); + SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(Attribute))); + SetBkColor(hDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(Attribute))); LastAttribute = Attribute; } } @@ -968,24 +805,24 @@ GuiConsolePaint(PCONSOLE Console, RightChar - Start + 1); } - if (Buff->CursorInfo.bVisible && GuiData->CursorBlinkOn && - !GuiData->ForceCursorOff) + if (Buff->CursorInfo.bVisible && Buff->CursorBlinkOn && + !Buff->ForceCursorOff) { - CursorX = Buff->CurrentX; - CursorY = Buff->CurrentY; + CursorX = Buff->CursorPosition.X; + CursorY = Buff->CursorPosition.Y; if (LeftChar <= CursorX && CursorX <= RightChar && TopLine <= CursorY && CursorY <= BottomLine) { CursorHeight = ConioEffectiveCursorSize(Console, GuiData->CharHeight); - From = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY) + 1; + From = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y) + 1; - if (*From != DEFAULT_ATTRIB) + if (*From != DEFAULT_SCREEN_ATTRIB) { - CursorBrush = CreateSolidBrush(GuiConsoleRGBFromAttribute(GuiData, *From)); + CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, *From)); } else { - CursorBrush = CreateSolidBrush(GuiData->ScreenText); + CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, Buff->ScreenDefaultAttrib)); } OldBrush = SelectObject(hDC, @@ -1076,7 +913,20 @@ GuiConsoleHandleKey(PCONSOLE Console, HWND hWnd, GuiConsoleUpdateSelection(Console, NULL); } - ConioProcessKey(&Message, Console, FALSE); + ConioProcessKey(Console, &Message); +} + +static BOOL WINAPI +GuiProcessKeyCallback(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD ShiftState, UINT VirtualKeyCode, BOOL Down) +{ + if ((ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED) || KeyStateMenu & 0x80) && + (VirtualKeyCode == VK_ESCAPE || VirtualKeyCode == VK_TAB || VirtualKeyCode == VK_SPACE)) + { + DefWindowProcW(msg->hwnd, msg->message, msg->wParam, msg->lParam); + return TRUE; + } + + return FALSE; } static VOID WINAPI @@ -1098,7 +948,7 @@ static VOID WINAPI GuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, LONG CursorStartX, LONG CursorStartY, UINT ScrolledLines, CHAR *Buffer, UINT Length) { - PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->GuiData; + PGUI_CONSOLE_DATA GuiData = Console->GuiData; PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; LONG CursorEndX, CursorEndY; RECT ScrollRect; @@ -1133,8 +983,8 @@ GuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, LONG CursorStartX, LONG Cur GuiInvalidateCell(Console, CursorStartX, CursorStartY); } - CursorEndX = Buff->CurrentX; - CursorEndY = Buff->CurrentY; + CursorEndX = Buff->CursorPosition.X; + CursorEndY = Buff->CursorPosition.Y; if ((CursorEndX < Region->Left || Region->Right < CursorEndX || CursorEndY < Region->Top || Region->Bottom < CursorEndY) && (CursorEndX != CursorStartX || CursorEndY != CursorStartY)) @@ -1144,7 +994,7 @@ GuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, LONG CursorStartX, LONG Cur // Set up the update timer (very short interval) - this is a "hack" for getting the OS to // repaint the window without having it just freeze up and stay on the screen permanently. - GuiData->CursorBlinkOn = TRUE; + Buff->CursorBlinkOn = TRUE; SetTimer(Console->hWindow, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL); } @@ -1153,7 +1003,7 @@ GuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff) { if (Console->ActiveBuffer == Buff) { - GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); + GuiInvalidateCell(Console, Buff->CursorPosition.X, Buff->CursorPosition.Y); } return TRUE; @@ -1167,7 +1017,7 @@ GuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, UINT OldCursorX, /* Redraw char at old position (removes cursor) */ GuiInvalidateCell(Console, OldCursorX, OldCursorY); /* Redraw char at new position (shows cursor) */ - GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); + GuiInvalidateCell(Console, Buff->CursorPosition.X, Buff->CursorPosition.Y); } return TRUE; @@ -1176,14 +1026,6 @@ GuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, UINT OldCursorX, static BOOL WINAPI GuiUpdateScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff) { - PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->GuiData; - - if (Console->ActiveBuffer == Buff) - { - GuiData->ScreenText = GuiConsoleRGBFromAttribute(GuiData, Buff->DefaultAttrib); - GuiData->ScreenBackground = GuiConsoleRGBFromAttribute(GuiData, Buff->DefaultAttrib >> 4); - } - return TRUE; } @@ -1198,10 +1040,10 @@ GuiConsoleHandleTimer(PCONSOLE Console, HWND hWnd) SetTimer(hWnd, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL); Buff = Console->ActiveBuffer; - GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); - GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn; + GuiInvalidateCell(Console, Buff->CursorPosition.X, Buff->CursorPosition.Y); + Buff->CursorBlinkOn = !Buff->CursorBlinkOn; - if((GuiData->OldCursor.x != Buff->CurrentX) || (GuiData->OldCursor.y != Buff->CurrentY)) + if((GuiData->OldCursor.x != Buff->CursorPosition.X) || (GuiData->OldCursor.y != Buff->CursorPosition.Y)) { SCROLLINFO xScroll; int OldScrollX = -1, OldScrollY = -1; @@ -1216,10 +1058,10 @@ GuiConsoleHandleTimer(PCONSOLE Console, HWND hWnd) // If we successfully got the info for the horizontal scrollbar if(OldScrollX >= 0) { - if((Buff->CurrentX < Buff->ShowX)||(Buff->CurrentX >= (Buff->ShowX + Console->Size.X))) + if((Buff->CursorPosition.X < Buff->ShowX)||(Buff->CursorPosition.X >= (Buff->ShowX + Console->Size.X))) { // Handle the horizontal scroll bar - if(Buff->CurrentX >= Console->Size.X) NewScrollX = Buff->CurrentX - Console->Size.X + 1; + if(Buff->CursorPosition.X >= Console->Size.X) NewScrollX = Buff->CursorPosition.X - Console->Size.X + 1; else NewScrollX = 0; } else @@ -1230,10 +1072,10 @@ GuiConsoleHandleTimer(PCONSOLE Console, HWND hWnd) // If we successfully got the info for the vertical scrollbar if(OldScrollY >= 0) { - if((Buff->CurrentY < Buff->ShowY) || (Buff->CurrentY >= (Buff->ShowY + Console->Size.Y))) + if((Buff->CursorPosition.Y < Buff->ShowY) || (Buff->CursorPosition.Y >= (Buff->ShowY + Console->Size.Y))) { // Handle the vertical scroll bar - if(Buff->CurrentY >= Console->Size.Y) NewScrollY = Buff->CurrentY - Console->Size.Y + 1; + if(Buff->CursorPosition.Y >= Console->Size.Y) NewScrollY = Buff->CursorPosition.Y - Console->Size.Y + 1; else NewScrollY = 0; } else @@ -1269,8 +1111,8 @@ GuiConsoleHandleTimer(PCONSOLE Console, HWND hWnd) SetScrollInfo(hWnd, SB_VERT, &xScroll, TRUE); } UpdateWindow(hWnd); - GuiData->OldCursor.x = Buff->CurrentX; - GuiData->OldCursor.y = Buff->CurrentY; + GuiData->OldCursor.x = Buff->CursorPosition.X; + GuiData->OldCursor.y = Buff->CursorPosition.Y; } } } @@ -1283,6 +1125,13 @@ GuiConsoleHandleClose(PCONSOLE Console, HWND hWnd) /// LOCK /// EnterCriticalSection(&Console->Lock); + /* + * Loop through the process list, from the most recent process + * (the active one) to the oldest one (the first created, + * i.e. the console leader process), and for each, send a + * CTRL-CLOSE event (new processes are inserted at the head + * of the console process list). + */ current_entry = Console->ProcessList.Flink; while (current_entry != &Console->ProcessList) { @@ -1307,8 +1156,6 @@ GuiConsoleHandleNcDestroy(PCONSOLE Console, HWND hWnd) Console->GuiData = NULL; DeleteCriticalSection(&GuiData->Lock); GetSystemMenu(hWnd, TRUE); - if (GuiData->ConsoleLibrary) - FreeLibrary(GuiData->ConsoleLibrary); RtlFreeHeap(ConSrvHeap, 0, GuiData); } @@ -1324,10 +1171,15 @@ PointToCoord(PCONSOLE Console, LPARAM lParam) Coord.Y = Buffer->ShowY + ((short)HIWORD(lParam) / (int)GuiData->CharHeight); /* Clip coordinate to ensure it's inside buffer */ - if (Coord.X < 0) Coord.X = 0; - else if (Coord.X >= Buffer->MaxX) Coord.X = Buffer->MaxX - 1; - if (Coord.Y < 0) Coord.Y = 0; - else if (Coord.Y >= Buffer->MaxY) Coord.Y = Buffer->MaxY - 1; + if (Coord.X < 0) + Coord.X = 0; + else if (Coord.X >= Buffer->ScreenBufferSize.X) + Coord.X = Buffer->ScreenBufferSize.X - 1; + + if (Coord.Y < 0) + Coord.Y = 0; + else if (Coord.Y >= Buffer->ScreenBufferSize.Y) + Coord.Y = Buffer->ScreenBufferSize.Y - 1; return Coord; } @@ -1473,6 +1325,7 @@ GuiConsolePaste(HWND hWnd, PCONSOLE Console) DPRINT("Got data <%s> from clipboard\n", str); len = strlen(str); + // TODO: Push the text into the input buffer. ConioWriteConsole(Console, Console->ActiveBuffer, str, len, TRUE); GlobalUnlock(hData); @@ -1496,127 +1349,6 @@ GuiConsoleRightMouseDown(PCONSOLE Console, HWND hWnd) } } -static VOID -GuiConsoleShowConsoleProperties(PCONSOLE Console, - HWND hWnd, - BOOL Defaults) -{ - PGUI_CONSOLE_DATA GuiData = Console->GuiData; - APPLET_PROC CPLFunc; - WCHAR szBuffer[MAX_PATH]; - ConsoleInfo SharedInfo; - - DPRINT("GuiConsoleShowConsoleProperties entered\n"); - - if (GuiData == NULL) return; - - if (GuiData->ConsoleLibrary == NULL) - { - GetWindowsDirectoryW(szBuffer, MAX_PATH); - wcscat(szBuffer, L"\\system32\\console.dll"); - GuiData->ConsoleLibrary = LoadLibraryW(szBuffer); - - if (GuiData->ConsoleLibrary == NULL) - { - DPRINT1("failed to load console.dll"); - return; - } - } - - CPLFunc = (APPLET_PROC)GetProcAddress(GuiData->ConsoleLibrary, "CPlApplet"); - if (!CPLFunc) - { - DPRINT("Error: Console.dll misses CPlApplet export\n"); - return; - } - - /* setup struct */ - SharedInfo.InsertMode = GuiData->InsertMode; - SharedInfo.HistoryBufferSize = Console->HistoryBufferSize; - SharedInfo.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers; - SharedInfo.ScreenText = GuiData->ScreenText; - SharedInfo.ScreenBackground = GuiData->ScreenBackground; - SharedInfo.PopupText = GuiData->PopupText; - SharedInfo.PopupBackground = GuiData->PopupBackground; - SharedInfo.WindowSize = (DWORD)MAKELONG(Console->Size.X, Console->Size.Y); - SharedInfo.WindowPosition = GuiData->WindowPosition; - SharedInfo.ScreenBuffer = (DWORD)MAKELONG(Console->ActiveBuffer->MaxX, Console->ActiveBuffer->MaxY); - SharedInfo.UseRasterFonts = GuiData->UseRasterFonts; - SharedInfo.FontSize = (DWORD)GuiData->FontSize; - SharedInfo.FontWeight = GuiData->FontWeight; - SharedInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize; - SharedInfo.HistoryNoDup = Console->HistoryNoDup; - SharedInfo.FullScreen = GuiData->FullScreen; - SharedInfo.QuickEdit = GuiData->QuickEdit; - memcpy(&SharedInfo.Colors[0], GuiData->Colors, sizeof(s_Colors)); - - if (!CPLFunc(hWnd, CPL_INIT, 0, 0)) - { - DPRINT("Error: failed to initialize console.dll\n"); - return; - } - - if (CPLFunc(hWnd, CPL_GETCOUNT, 0, 0) != 1) - { - DPRINT("Error: console.dll returned unexpected CPL count\n"); - return; - } - - CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults); - CPLFunc(hWnd, CPL_EXIT , 0, 0); -} - -static LRESULT -GuiConsoleHandleSysMenuCommand(PCONSOLE Console, - HWND hWnd, - WPARAM wParam, LPARAM lParam) -{ - LRESULT Ret = TRUE; - COORD bottomRight = { 0, 0 }; - - switch (wParam) - { - case ID_SYSTEM_EDIT_MARK: - DPRINT1("Marking not handled yet\n"); - break; - - case ID_SYSTEM_EDIT_COPY: - GuiConsoleCopy(hWnd, Console); - break; - - case ID_SYSTEM_EDIT_PASTE: - GuiConsolePaste(hWnd, Console); - break; - - case ID_SYSTEM_EDIT_SELECTALL: - bottomRight.X = Console->Size.X - 1; - bottomRight.Y = Console->Size.Y - 1; - GuiConsoleUpdateSelection(Console, &bottomRight); - break; - - case ID_SYSTEM_EDIT_SCROLL: - DPRINT1("Scrolling is not handled yet\n"); - break; - - case ID_SYSTEM_EDIT_FIND: - DPRINT1("Finding is not handled yet\n"); - break; - - case ID_SYSTEM_DEFAULTS: - GuiConsoleShowConsoleProperties(Console, hWnd, TRUE); - break; - - case ID_SYSTEM_PROPERTIES: - GuiConsoleShowConsoleProperties(Console, hWnd, FALSE); - break; - - default: - Ret = DefWindowProcW(hWnd, WM_SYSCOMMAND, wParam, lParam); - break; - } - return Ret; -} - static VOID GuiConsoleGetMinMaxInfo(PCONSOLE Console, HWND hWnd, @@ -1633,11 +1365,11 @@ GuiConsoleGetMinMaxInfo(PCONSOLE Console, minMaxInfo->ptMinTrackSize.x = windx; minMaxInfo->ptMinTrackSize.y = windy; - windx = (Console->ActiveBuffer->MaxX) * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); - windy = (Console->ActiveBuffer->MaxY) * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); + windx = (Console->ActiveBuffer->ScreenBufferSize.X) * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); + windy = (Console->ActiveBuffer->ScreenBufferSize.Y) * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); - if(Console->Size.X < Console->ActiveBuffer->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar - if(Console->Size.Y < Console->ActiveBuffer->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar + if(Console->Size.X < Console->ActiveBuffer->ScreenBufferSize.X) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar + if(Console->Size.Y < Console->ActiveBuffer->ScreenBufferSize.Y) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar minMaxInfo->ptMaxTrackSize.x = windx; minMaxInfo->ptMaxTrackSize.y = windy; @@ -1663,8 +1395,8 @@ GuiConsoleResize(PCONSOLE Console, windy = HIWORD(lParam); // Compensate for existing scroll bars (because lParam values do not accommodate scroll bar) - if(Console->Size.X < Buff->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar - if(Console->Size.Y < Buff->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar + if(Console->Size.X < Buff->ScreenBufferSize.X) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar + if(Console->Size.Y < Buff->ScreenBufferSize.Y) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar charx = windx / GuiData->CharWidth; chary = windy / GuiData->CharHeight; @@ -1674,8 +1406,8 @@ GuiConsoleResize(PCONSOLE Console, if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary; // Compensate for added scroll bars in new window - if(charx < Buff->MaxX)windy -= GetSystemMetrics(SM_CYHSCROLL); // new window will have a horizontal scroll bar - if(chary < Buff->MaxY)windx -= GetSystemMetrics(SM_CXVSCROLL); // new window will have a vertical scroll bar + if(charx < Buff->ScreenBufferSize.X)windy -= GetSystemMetrics(SM_CYHSCROLL); // new window will have a horizontal scroll bar + if(chary < Buff->ScreenBufferSize.Y)windx -= GetSystemMetrics(SM_CXVSCROLL); // new window will have a vertical scroll bar charx = windx / GuiData->CharWidth; chary = windy / GuiData->CharHeight; @@ -1687,15 +1419,15 @@ GuiConsoleResize(PCONSOLE Console, // Resize window if((charx != Console->Size.X) || (chary != Console->Size.Y)) { - Console->Size.X = (charx <= Buff->MaxX) ? charx : Buff->MaxX; - Console->Size.Y = (chary <= Buff->MaxY) ? chary : Buff->MaxY; + Console->Size.X = (charx <= Buff->ScreenBufferSize.X) ? charx : Buff->ScreenBufferSize.X; + Console->Size.Y = (chary <= Buff->ScreenBufferSize.Y) ? chary : Buff->ScreenBufferSize.Y; } GuiConsoleInitScrollbar(Console, hWnd); // Adjust the start of the visible area if we are attempting to show nonexistent areas - if((Buff->MaxX - Buff->ShowX) < Console->Size.X) Buff->ShowX = Buff->MaxX - Console->Size.X; - if((Buff->MaxY - Buff->ShowY) < Console->Size.Y) Buff->ShowY = Buff->MaxY - Console->Size.Y; + if((Buff->ScreenBufferSize.X - Buff->ShowX) < Console->Size.X) Buff->ShowX = Buff->ScreenBufferSize.X - Console->Size.X; + if((Buff->ScreenBufferSize.Y - Buff->ShowY) < Console->Size.Y) Buff->ShowY = Buff->ScreenBufferSize.Y - Console->Size.Y; InvalidateRect(hWnd, NULL, TRUE); GuiData->WindowSizeLock = FALSE; @@ -1736,7 +1468,7 @@ GuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Siz USHORT CurrentY; BYTE * OldBuffer; #ifdef HAVE_WMEMSET - USHORT value = MAKEWORD(' ', ScreenBuffer->DefaultAttrib); + USHORT value = MAKEWORD(' ', ScreenBuffer->ScreenDefaultAttrib); #else DWORD i; #endif @@ -1746,20 +1478,20 @@ GuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Siz if (Size.X < Console->Size.X || Size.Y < Console->Size.Y) return STATUS_INVALID_PARAMETER; - if (Size.X == ScreenBuffer->MaxX && Size.Y == ScreenBuffer->MaxY) + if (Size.X == ScreenBuffer->ScreenBufferSize.X && Size.Y == ScreenBuffer->ScreenBufferSize.Y) return STATUS_SUCCESS; Buffer = RtlAllocateHeap(ConSrvHeap, 0, Size.X * Size.Y * 2); if (!Buffer) return STATUS_NO_MEMORY; - DPRINT1("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->MaxX, ScreenBuffer->MaxY, Size.X, Size.Y); + DPRINT1("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->ScreenBufferSize.X, ScreenBuffer->ScreenBufferSize.Y, Size.X, Size.Y); OldBuffer = ScreenBuffer->Buffer; - for (CurrentY = 0; CurrentY < ScreenBuffer->MaxY && CurrentY < Size.Y; CurrentY++) + for (CurrentY = 0; CurrentY < ScreenBuffer->ScreenBufferSize.Y && CurrentY < Size.Y; CurrentY++) { OldPtr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY); - if (Size.X <= ScreenBuffer->MaxX) + if (Size.X <= ScreenBuffer->ScreenBufferSize.X) { /* reduce size */ RtlCopyMemory(&Buffer[Offset], OldPtr, Size.X * 2); @@ -1768,10 +1500,10 @@ GuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Siz else { /* enlarge size */ - RtlCopyMemory(&Buffer[Offset], OldPtr, ScreenBuffer->MaxX * 2); - Offset += (ScreenBuffer->MaxX * 2); + RtlCopyMemory(&Buffer[Offset], OldPtr, ScreenBuffer->ScreenBufferSize.X * 2); + Offset += (ScreenBuffer->ScreenBufferSize.X * 2); - diff = Size.X - ScreenBuffer->MaxX; + diff = Size.X - ScreenBuffer->ScreenBufferSize.X; /* zero new part of it */ #ifdef HAVE_WMEMSET wmemset((PWCHAR)&Buffer[Offset], value, diff); @@ -1779,37 +1511,36 @@ GuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Siz for (i = 0; i < diff; i++) { Buffer[Offset++] = ' '; - Buffer[Offset++] = ScreenBuffer->DefaultAttrib; + Buffer[Offset++] = ScreenBuffer->ScreenDefaultAttrib; } #endif } } - if (Size.Y > ScreenBuffer->MaxY) + if (Size.Y > ScreenBuffer->ScreenBufferSize.Y) { - diff = Size.X * (Size.Y - ScreenBuffer->MaxY); + diff = Size.X * (Size.Y - ScreenBuffer->ScreenBufferSize.Y); #ifdef HAVE_WMEMSET wmemset((PWCHAR)&Buffer[Offset], value, diff); #else for (i = 0; i < diff; i++) { Buffer[Offset++] = ' '; - Buffer[Offset++] = ScreenBuffer->DefaultAttrib; + Buffer[Offset++] = ScreenBuffer->ScreenDefaultAttrib; } #endif } (void)InterlockedExchangePointer((PVOID volatile*)&ScreenBuffer->Buffer, Buffer); RtlFreeHeap(ConSrvHeap, 0, OldBuffer); - ScreenBuffer->MaxX = Size.X; - ScreenBuffer->MaxY = Size.Y; + ScreenBuffer->ScreenBufferSize = Size; ScreenBuffer->VirtualY = 0; /* Ensure cursor and window are within buffer */ - if (ScreenBuffer->CurrentX >= Size.X) - ScreenBuffer->CurrentX = Size.X - 1; - if (ScreenBuffer->CurrentY >= Size.Y) - ScreenBuffer->CurrentY = Size.Y - 1; + if (ScreenBuffer->CursorPosition.X >= Size.X) + ScreenBuffer->CursorPosition.X = Size.X - 1; + if (ScreenBuffer->CursorPosition.Y >= Size.Y) + ScreenBuffer->CursorPosition.Y = Size.Y - 1; if (ScreenBuffer->ShowX > Size.X - Console->Size.X) ScreenBuffer->ShowX = Size.X - Console->Size.X; if (ScreenBuffer->ShowY > Size.Y - Console->Size.Y) @@ -1821,55 +1552,6 @@ GuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Siz return STATUS_SUCCESS; } -static VOID -GuiApplyUserSettings(PCONSOLE Console, - PConsoleInfo pConInfo) -{ - PGUI_CONSOLE_DATA GuiData = Console->GuiData; - DWORD windx, windy; - PCONSOLE_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer; - COORD BufSize; - BOOL SizeChanged = FALSE; - - /// LOCK /// EnterCriticalSection(&Console->Lock); - - /* apply text / background color */ - GuiData->ScreenText = pConInfo->ScreenText; - GuiData->ScreenBackground = pConInfo->ScreenBackground; - - /* apply cursor size */ - ActiveBuffer->CursorInfo.dwSize = min(max(pConInfo->CursorSize, 1), 100); - - windx = LOWORD(pConInfo->WindowSize); - windy = HIWORD(pConInfo->WindowSize); - - if (windx != Console->Size.X || windy != Console->Size.Y) - { - /* resize window */ - Console->Size.X = windx; - Console->Size.Y = windy; - SizeChanged = TRUE; - } - - BufSize.X = LOWORD(pConInfo->ScreenBuffer); - BufSize.Y = HIWORD(pConInfo->ScreenBuffer); - if (BufSize.X != ActiveBuffer->MaxX || BufSize.Y != ActiveBuffer->MaxY) - { - if (NT_SUCCESS(GuiResizeBuffer(Console, ActiveBuffer, BufSize))) - SizeChanged = TRUE; - } - - if (SizeChanged) - { - GuiData->WindowSizeLock = TRUE; - GuiConsoleInitScrollbar(Console, pConInfo->hConsoleWindow); - GuiData->WindowSizeLock = FALSE; - } - - /// LOCK /// LeaveCriticalSection(&Console->Lock); - InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE); -} - static LRESULT GuiConsoleHandleScroll(PCONSOLE Console, @@ -1891,13 +1573,13 @@ GuiConsoleHandleScroll(PCONSOLE Console, if (uMsg == WM_HSCROLL) { fnBar = SB_HORZ; - Maximum = Buff->MaxX - Console->Size.X; + Maximum = Buff->ScreenBufferSize.X - Console->Size.X; pShowXY = &Buff->ShowX; } else { fnBar = SB_VERT; - Maximum = Buff->MaxY - Console->Size.Y; + Maximum = Buff->ScreenBufferSize.Y - Console->Size.Y; pShowXY = &Buff->ShowY; } @@ -2001,6 +1683,8 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) Console = GuiGetWindowConsole(hWnd); if (Console == NULL) return 0; + // TODO: If the console is about to be destroyed, leave the loop. + /* Lock the console */ EnterCriticalSection(&Console->Lock); @@ -2065,11 +1749,7 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) break; case PM_APPLY_CONSOLE_INFO: - GuiApplyUserSettings(Console, (PConsoleInfo)wParam); - if (lParam) - { - GuiConsoleWriteUserSettings(Console); - } + GuiApplyUserSettings(Console, (HANDLE)wParam, (BOOL)lParam); break; case PM_CONSOLE_BEEP: @@ -2250,7 +1930,7 @@ GuiInit(VOID) wc.hIcon = ghDefaultIcon; wc.hIconSm = ghDefaultIconSm; wc.hCursor = ghDefaultCursor; - wc.hbrBackground = CreateSolidBrush(RGB(0,0,0)); + wc.hbrBackground = CreateSolidBrush(RGB(0,0,0)); // FIXME: Use defaults from registry. wc.lpszMenuName = NULL; wc.cbClsExtra = 0; wc.cbWndExtra = GWLP_CONSOLEWND_ALLOC; @@ -2348,12 +2028,13 @@ static CONSOLE_VTBL GuiVtbl = GuiCleanupConsole, GuiChangeIcon, GuiResizeBuffer, + GuiProcessKeyCallback }; NTSTATUS FASTCALL GuiInitConsole(PCONSOLE Console, LPCWSTR AppPath, - WORD ShowWindow, + PCONSOLE_INFO ConsoleInfo, LPCWSTR IconPath, INT IconIndex) { @@ -2418,6 +2099,25 @@ GuiInitConsole(PCONSOLE Console, } Console->GuiData = (PVOID)GuiData; + if (ConsoleInfo) + { + wcsncpy(GuiData->GuiInfo.FaceName, ConsoleInfo->u.GuiInfo.FaceName, LF_FACESIZE); + GuiData->GuiInfo.FontFamily = ConsoleInfo->u.GuiInfo.FontFamily; + GuiData->GuiInfo.FontSize = ConsoleInfo->u.GuiInfo.FontSize; + GuiData->GuiInfo.FontWeight = ConsoleInfo->u.GuiInfo.FontWeight; + GuiData->GuiInfo.UseRasterFonts = ConsoleInfo->u.GuiInfo.UseRasterFonts; + + GuiData->GuiInfo.ShowWindow = ConsoleInfo->u.GuiInfo.ShowWindow; + GuiData->GuiInfo.AutoPosition = ConsoleInfo->u.GuiInfo.AutoPosition; + GuiData->GuiInfo.WindowOrigin = ConsoleInfo->u.GuiInfo.WindowOrigin; + } + /* + else + { + // TODO: What could be the defaults ? + } + */ + /* Initialize the icon handles to their default values */ Console->hIcon = ghDefaultIcon; Console->hIconSm = ghDefaultIconSm; @@ -2456,7 +2156,7 @@ GuiInitConsole(PCONSOLE Console, GuiData->hGuiInitEvent = CreateEventW(NULL, FALSE, FALSE, NULL); /* Create the GUI console */ - PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, ShowWindow, (LPARAM)Console); + PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, GuiData->GuiInfo.ShowWindow, (LPARAM)Console); /* Wait until initialization has finished */ WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE); diff --git a/win32ss/user/consrv/guiconsole.h b/win32ss/user/consrv/guiconsole.h index 5908c52a89d..462d11d8e47 100644 --- a/win32ss/user/consrv/guiconsole.h +++ b/win32ss/user/consrv/guiconsole.h @@ -2,7 +2,7 @@ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL * FILE: win32ss/user/consrv/guiconsole.h - * PURPOSE: Interface to gui-mode consoles + * PURPOSE: Interface to GUI-mode consoles * PROGRAMMERS: */ @@ -15,7 +15,7 @@ NTSTATUS FASTCALL GuiInitConsole(PCONSOLE Console, LPCWSTR AppPath, - WORD ShowWindow, + PCONSOLE_INFO ConsoleInfo, LPCWSTR IconPath, INT IconIndex); VOID FASTCALL GuiConsoleHandleScrollbarMenu(VOID); diff --git a/win32ss/user/consrv/handle.c b/win32ss/user/consrv/handle.c index cdef4452a8f..28b8d4d3698 100644 --- a/win32ss/user/consrv/handle.c +++ b/win32ss/user/consrv/handle.c @@ -129,11 +129,11 @@ ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData, /* Insert the Input handle */ Status = ConSrvInsertObject(ProcessData, - &InputHandle, - &ProcessData->Console->InputBuffer.Header, - GENERIC_READ | GENERIC_WRITE, - TRUE, - FILE_SHARE_READ | FILE_SHARE_WRITE); + &InputHandle, + &ProcessData->Console->InputBuffer.Header, + GENERIC_READ | GENERIC_WRITE, + TRUE, + FILE_SHARE_READ | FILE_SHARE_WRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to insert the input handle\n"); @@ -144,11 +144,11 @@ ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData, /* Insert the Output handle */ Status = ConSrvInsertObject(ProcessData, - &OutputHandle, - &ProcessData->Console->ActiveBuffer->Header, - GENERIC_READ | GENERIC_WRITE, - TRUE, - FILE_SHARE_READ | FILE_SHARE_WRITE); + &OutputHandle, + &ProcessData->Console->ActiveBuffer->Header, + GENERIC_READ | GENERIC_WRITE, + TRUE, + FILE_SHARE_READ | FILE_SHARE_WRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to insert the output handle\n"); @@ -159,11 +159,11 @@ ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData, /* Insert the Error handle */ Status = ConSrvInsertObject(ProcessData, - &ErrorHandle, - &ProcessData->Console->ActiveBuffer->Header, - GENERIC_READ | GENERIC_WRITE, - TRUE, - FILE_SHARE_READ | FILE_SHARE_WRITE); + &ErrorHandle, + &ProcessData->Console->ActiveBuffer->Header, + GENERIC_READ | GENERIC_WRITE, + TRUE, + FILE_SHARE_READ | FILE_SHARE_WRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to insert the error handle\n"); @@ -405,12 +405,12 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData, PHANDLE pInputHandle, PHANDLE pOutputHandle, PHANDLE pErrorHandle, - PCONSOLE_PROPS ConsoleProps) + PCONSOLE_START_INFO ConsoleStartInfo) { NTSTATUS Status = STATUS_SUCCESS; /* Initialize a new Console owned by this process */ - Status = ConSrvInitConsole(&ProcessData->Console, AppPath, ConsoleProps, ProcessData->Process); + Status = ConSrvInitConsole(&ProcessData->Console, AppPath, ConsoleStartInfo, ProcessData->Process); if (!NT_SUCCESS(Status)) { DPRINT1("Console initialization failed\n"); @@ -511,6 +511,7 @@ FASTCALL ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData) { PCONSOLE Console; + PCONSOLE_PROCESS_DATA NewProcessData; DPRINT1("ConSrvRemoveConsole\n"); @@ -523,9 +524,21 @@ ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData) { DPRINT1("ConSrvRemoveConsole - Console->ReferenceCount = %lu - We are going to decrement it !\n", Console->ReferenceCount); ProcessData->Console = NULL; + EnterCriticalSection(&Console->Lock); DPRINT1("ConSrvRemoveConsole - Locking OK\n"); + + /* Remove ourselves from the console's list of processes */ RemoveEntryList(&ProcessData->ConsoleLink); + + /* Update the console leader process */ + NewProcessData = CONTAINING_RECORD(Console->ProcessList.Blink, + CONSOLE_PROCESS_DATA, + ConsoleLink); + Console->ConsoleLeaderCID = NewProcessData->Process->ClientId; + SetConsoleWndConsoleLeaderCID(Console); + + /* Release the console */ ConSrvReleaseConsole(Console, TRUE); //CloseHandle(ProcessData->ConsoleEvent); //ProcessData->ConsoleEvent = NULL; @@ -613,7 +626,6 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess, TargetProcessData->HandleTableSize = 0; TargetProcessData->HandleTable = NULL; - /**** HACK !!!! ****/ RtlZeroMemory(&TargetProcessData->HandleTableLock, sizeof(RTL_CRITICAL_SECTION)); RtlInitializeCriticalSection(&TargetProcessData->HandleTableLock); /* Do nothing if the source process is NULL */ @@ -700,7 +712,7 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess, &ConnectInfo->InputHandle, &ConnectInfo->OutputHandle, &ConnectInfo->ErrorHandle, - &ConnectInfo->ConsoleProps); + &ConnectInfo->ConsoleStartInfo); if (!NT_SUCCESS(Status)) { DPRINT1("Console allocation failed\n"); @@ -731,6 +743,10 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess, /* Input Wait Handle */ ConnectInfo->InputWaitHandle = ProcessData->ConsoleEvent; + /* Set the Property Dialog Handler */ + ProcessData->PropDispatcher = ConnectInfo->PropDispatcher; + DPRINT("CONSRV: PropDispatcher address: %x\n", ProcessData->PropDispatcher); + /* Set the Ctrl Dispatcher */ ProcessData->CtrlDispatcher = ConnectInfo->CtrlDispatcher; DPRINT("CONSRV: CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher); @@ -831,11 +847,11 @@ CSR_API(SrvDuplicateHandle) } ApiMessage->Status = ConSrvInsertObject(ProcessData, - &DuplicateHandleRequest->ConsoleHandle, // Use the new handle value! - Entry->Object, - DesiredAccess, - DuplicateHandleRequest->Inheritable, - Entry->ShareMode); + &DuplicateHandleRequest->ConsoleHandle, // Use the new handle value! + Entry->Object, + DesiredAccess, + DuplicateHandleRequest->Inheritable, + Entry->ShareMode); if (NT_SUCCESS(ApiMessage->Status) && DuplicateHandleRequest->Options & DUPLICATE_CLOSE_SOURCE) { diff --git a/win32ss/user/consrv/init.c b/win32ss/user/consrv/init.c index 6a281c44e6a..f3bec2c66f2 100644 --- a/win32ss/user/consrv/init.c +++ b/win32ss/user/consrv/init.c @@ -116,47 +116,47 @@ PCSR_API_ROUTINE ConsoleServerApiDispatchTable[ConsolepMaxApiNumber] = BOOLEAN ConsoleServerApiServerValidTable[ConsolepMaxApiNumber] = { - TRUE /* FALSE */, // SrvOpenConsole, - TRUE /* FALSE */, // SrvGetConsoleInput, - TRUE /* FALSE */, // SrvWriteConsoleInput, - TRUE /* FALSE */, // SrvReadConsoleOutput, - TRUE /* FALSE */, // SrvWriteConsoleOutput, - TRUE /* FALSE */, // SrvReadConsoleOutputString, - TRUE /* FALSE */, // SrvWriteConsoleOutputString, - TRUE /* FALSE */, // SrvFillConsoleOutput, - TRUE /* FALSE */, // SrvGetConsoleMode, + FALSE, // SrvOpenConsole, + FALSE, // SrvGetConsoleInput, + FALSE, // SrvWriteConsoleInput, + FALSE, // SrvReadConsoleOutput, + FALSE, // SrvWriteConsoleOutput, + FALSE, // SrvReadConsoleOutputString, + FALSE, // SrvWriteConsoleOutputString, + FALSE, // SrvFillConsoleOutput, + FALSE, // SrvGetConsoleMode, // FALSE, // SrvGetConsoleNumberOfFonts, - TRUE /* FALSE */, // SrvGetConsoleNumberOfInputEvents, - TRUE /* FALSE */, // SrvGetConsoleScreenBufferInfo, - TRUE /* FALSE */, // SrvGetConsoleCursorInfo, + FALSE, // SrvGetConsoleNumberOfInputEvents, + FALSE, // SrvGetConsoleScreenBufferInfo, + FALSE, // SrvGetConsoleCursorInfo, // FALSE, // SrvGetConsoleMouseInfo, // FALSE, // SrvGetConsoleFontInfo, // FALSE, // SrvGetConsoleFontSize, // FALSE, // SrvGetConsoleCurrentFont, - TRUE /* FALSE */, // SrvSetConsoleMode, - TRUE /* FALSE */, // SrvSetConsoleActiveScreenBuffer, - TRUE /* FALSE */, // SrvFlushConsoleInputBuffer, + FALSE, // SrvSetConsoleMode, + FALSE, // SrvSetConsoleActiveScreenBuffer, + FALSE, // SrvFlushConsoleInputBuffer, // FALSE, // SrvGetLargestConsoleWindowSize, - TRUE /* FALSE */, // SrvSetConsoleScreenBufferSize, - TRUE /* FALSE */, // SrvSetConsoleCursorPosition, - TRUE /* FALSE */, // SrvSetConsoleCursorInfo, + FALSE, // SrvSetConsoleScreenBufferSize, + FALSE, // SrvSetConsoleCursorPosition, + FALSE, // SrvSetConsoleCursorInfo, // FALSE, // SrvSetConsoleWindowInfo, - TRUE /* FALSE */, // SrvScrollConsoleScreenBuffer, - TRUE /* FALSE */, // SrvSetConsoleTextAttribute, + FALSE, // SrvScrollConsoleScreenBuffer, + FALSE, // SrvSetConsoleTextAttribute, // FALSE, // SrvSetConsoleFont, - TRUE /* FALSE */, // SrvSetConsoleIcon, - TRUE /* FALSE */, // SrvReadConsole, - TRUE /* FALSE */, // SrvWriteConsole, - TRUE /* FALSE */, // SrvDuplicateHandle, + FALSE, // SrvSetConsoleIcon, + FALSE, // SrvReadConsole, + FALSE, // SrvWriteConsole, + FALSE, // SrvDuplicateHandle, // FALSE, // SrvGetHandleInformation, // FALSE, // SrvSetHandleInformation, - TRUE /* FALSE */, // SrvCloseHandle, - TRUE /* FALSE */, // SrvVerifyConsoleIoHandle, - TRUE /* FALSE */, // SrvAllocConsole, - TRUE /* FALSE */, // SrvFreeConsole, - TRUE /* FALSE */, // SrvGetConsoleTitle, - TRUE /* FALSE */, // SrvSetConsoleTitle, - TRUE /* FALSE */, // SrvCreateConsoleScreenBuffer, + FALSE, // SrvCloseHandle, + FALSE, // SrvVerifyConsoleIoHandle, + FALSE, // SrvAllocConsole, + FALSE, // SrvFreeConsole, + FALSE, // SrvGetConsoleTitle, + FALSE, // SrvSetConsoleTitle, + FALSE, // SrvCreateConsoleScreenBuffer, // FALSE, // SrvInvalidateBitMapRect, // FALSE, // SrvVDMConsoleOperation, // FALSE, // SrvSetConsoleCursor, @@ -165,28 +165,28 @@ BOOLEAN ConsoleServerApiServerValidTable[ConsolepMaxApiNumber] = // FALSE, // SrvSetConsolePalette, // FALSE, // SrvSetConsoleDisplayMode, // FALSE, // SrvRegisterConsoleVDM, - TRUE /* FALSE */, // SrvGetConsoleHardwareState, - TRUE /* FALSE */, // SrvSetConsoleHardwareState, + FALSE, // SrvGetConsoleHardwareState, + FALSE, // SrvSetConsoleHardwareState, // TRUE, // SrvGetConsoleDisplayMode, - TRUE /* FALSE */, // SrvAddConsoleAlias, - TRUE /* FALSE */, // SrvGetConsoleAlias, - TRUE /* FALSE */, // SrvGetConsoleAliasesLength, - TRUE /* FALSE */, // SrvGetConsoleAliasExesLength, - TRUE /* FALSE */, // SrvGetConsoleAliases, - TRUE /* FALSE */, // SrvGetConsoleAliasExes, - TRUE /* FALSE */, // SrvExpungeConsoleCommandHistory, - TRUE /* FALSE */, // SrvSetConsoleNumberOfCommands, - TRUE /* FALSE */, // SrvGetConsoleCommandHistoryLength, - TRUE /* FALSE */, // SrvGetConsoleCommandHistory, + FALSE, // SrvAddConsoleAlias, + FALSE, // SrvGetConsoleAlias, + FALSE, // SrvGetConsoleAliasesLength, + FALSE, // SrvGetConsoleAliasExesLength, + FALSE, // SrvGetConsoleAliases, + FALSE, // SrvGetConsoleAliasExes, + FALSE, // SrvExpungeConsoleCommandHistory, + FALSE, // SrvSetConsoleNumberOfCommands, + FALSE, // SrvGetConsoleCommandHistoryLength, + FALSE, // SrvGetConsoleCommandHistory, // FALSE, // SrvSetConsoleCommandHistoryMode, - TRUE /* FALSE */, // SrvGetConsoleCP, - TRUE /* FALSE */, // SrvSetConsoleCP, + FALSE, // SrvGetConsoleCP, + FALSE, // SrvSetConsoleCP, // FALSE, // SrvSetConsoleKeyShortcuts, // FALSE, // SrvSetConsoleMenuClose, // FALSE, // SrvConsoleNotifyLastClose, - TRUE /* FALSE */, // SrvGenerateConsoleCtrlEvent, + FALSE, // SrvGenerateConsoleCtrlEvent, // FALSE, // SrvGetConsoleKeyboardLayoutName, - TRUE /* FALSE */, // SrvGetConsoleWindow, + FALSE, // SrvGetConsoleWindow, // FALSE, // SrvGetConsoleCharType, // FALSE, // SrvSetConsoleLocalEUDC, // FALSE, // SrvSetConsoleCursorMode, @@ -198,11 +198,11 @@ BOOLEAN ConsoleServerApiServerValidTable[ConsolepMaxApiNumber] = // FALSE, // SrvRegisterConsoleIME, // FALSE, // SrvUnregisterConsoleIME, // FALSE, // SrvGetConsoleLangId, - TRUE /* FALSE */, // SrvAttachConsole, - TRUE /* FALSE */, // SrvGetConsoleSelectionInfo, - TRUE /* FALSE */, // SrvGetConsoleProcessList, - TRUE /* FALSE */, // SrvGetConsoleHistory, - TRUE /* FALSE */, // SrvSetConsoleHistory + FALSE, // SrvAttachConsole, + FALSE, // SrvGetConsoleSelectionInfo, + FALSE, // SrvGetConsoleProcessList, + FALSE, // SrvGetConsoleHistory, + FALSE, // SrvSetConsoleHistory // FALSE }; diff --git a/win32ss/user/consrv/lineinput.c b/win32ss/user/consrv/lineinput.c index 602dbb989f0..1ce643858c4 100644 --- a/win32ss/user/consrv/lineinput.c +++ b/win32ss/user/consrv/lineinput.c @@ -1,7 +1,7 @@ /* * LICENSE: GPL - See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/tuiconsole.c + * FILE: win32ss/user/consrv/lineinput.c * PURPOSE: Console line input functions * PROGRAMMERS: Jeffrey Morlan */ @@ -343,18 +343,18 @@ LineInputSetPos(PCONSOLE Console, UINT Pos) if (Pos != Console->LinePos && Console->InputBuffer.Mode & ENABLE_ECHO_INPUT) { PCONSOLE_SCREEN_BUFFER Buffer = Console->ActiveBuffer; - UINT OldCursorX = Buffer->CurrentX; - UINT OldCursorY = Buffer->CurrentY; - INT XY = OldCursorY * Buffer->MaxX + OldCursorX; + UINT OldCursorX = Buffer->CursorPosition.X; + UINT OldCursorY = Buffer->CursorPosition.Y; + INT XY = OldCursorY * Buffer->ScreenBufferSize.X + OldCursorX; XY += (Pos - Console->LinePos); if (XY < 0) XY = 0; - else if (XY >= Buffer->MaxY * Buffer->MaxX) - XY = Buffer->MaxY * Buffer->MaxX - 1; + else if (XY >= Buffer->ScreenBufferSize.Y * Buffer->ScreenBufferSize.X) + XY = Buffer->ScreenBufferSize.Y * Buffer->ScreenBufferSize.X - 1; - Buffer->CurrentX = XY % Buffer->MaxX; - Buffer->CurrentY = XY / Buffer->MaxX; + Buffer->CursorPosition.X = XY % Buffer->ScreenBufferSize.X; + Buffer->CursorPosition.Y = XY / Buffer->ScreenBufferSize.X; ConioSetScreenInfo(Console, Buffer, OldCursorX, OldCursorY); } diff --git a/win32ss/user/consrv/settings.c b/win32ss/user/consrv/settings.c new file mode 100644 index 00000000000..766a690f685 --- /dev/null +++ b/win32ss/user/consrv/settings.c @@ -0,0 +1,498 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Server DLL + * FILE: win32ss/user/consrv/settings.c + * PURPOSE: Consoles settings management + * PROGRAMMERS: Hermes Belusca - Maito + * + * NOTE: Adapted from existing code. + */ + +/* INCLUDES *******************************************************************/ + +#include "consrv.h" +#include "conio.h" +#include "settings.h" + +#include // for swprintf + +#define NDEBUG +#include + + +/* GLOBALS ********************************************************************/ + +extern const COLORREF s_Colors[16]; + + +/* FUNCTIONS ******************************************************************/ + +static VOID +TranslateConsoleName(OUT LPWSTR DestString, + IN LPCWSTR ConsoleName, + IN UINT MaxStrLen) +{ +#define PATH_SEPARATOR L'\\' + + UINT wLength; + + if ( DestString == NULL || ConsoleName == NULL || + *ConsoleName == L'\0' || MaxStrLen == 0 ) + { + return; + } + + wLength = GetWindowsDirectoryW(DestString, MaxStrLen); + if ((wLength > 0) && (_wcsnicmp(ConsoleName, DestString, wLength) == 0)) + { + wcsncpy(DestString, L"%SystemRoot%", MaxStrLen); + // FIXME: Fix possible buffer overflows there !!!!! + wcsncat(DestString, ConsoleName + wLength, MaxStrLen); + } + else + { + wcsncpy(DestString, ConsoleName, MaxStrLen); + } + + /* Replace path separators (backslashes) by underscores */ + while ((DestString = wcschr(DestString, PATH_SEPARATOR))) *DestString = L'_'; +} + +static BOOL +OpenUserRegistryPathPerProcessId(DWORD ProcessId, + PHKEY hResult, + REGSAM samDesired) +{ + BOOL bRet = TRUE; + HANDLE hProcessToken = NULL; + HANDLE hProcess; + BYTE Buffer[256]; + DWORD Length = 0; + UNICODE_STRING SidName; + PTOKEN_USER TokUser; + + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | READ_CONTROL, FALSE, ProcessId); + if (!hProcess) + { + DPRINT("Error: OpenProcess failed(0x%x)\n", GetLastError()); + return FALSE; + } + + if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken)) + { + DPRINT("Error: OpenProcessToken failed(0x%x)\n", GetLastError()); + CloseHandle(hProcess); + return FALSE; + } + + if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length)) + { + DPRINT("Error: GetTokenInformation failed(0x%x)\n",GetLastError()); + CloseHandle(hProcessToken); + CloseHandle(hProcess); + return FALSE; + } + + TokUser = ((PTOKEN_USER)Buffer)->User.Sid; + if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE))) + { + DPRINT("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError()); + CloseHandle(hProcessToken); + CloseHandle(hProcess); + return FALSE; + } + + bRet = (RegOpenKeyExW(HKEY_USERS, + SidName.Buffer, + 0, + samDesired, + hResult) == ERROR_SUCCESS); + + RtlFreeUnicodeString(&SidName); + + CloseHandle(hProcessToken); + CloseHandle(hProcess); + + return bRet; +} + +BOOL +ConSrvOpenUserSettings(DWORD ProcessId, + LPCWSTR ConsoleTitle, + PHKEY hSubKey, + REGSAM samDesired, + BOOL bCreate) +{ + BOOL bRet = TRUE; + WCHAR szBuffer[MAX_PATH] = L"Console\\"; + WCHAR szBuffer2[MAX_PATH] = L""; + HKEY hKey; + + /* + * Console properties are stored under the HKCU\Console\* key. + * + * We use the original console title as the subkey name for storing + * console properties. We need to distinguish whether we were launched + * via the console application directly or via a shortcut. + * + * If the title of the console corresponds to a path (more precisely, + * if the title is of the form: C:\ReactOS\\), + * then use the corresponding unexpanded path and with the backslashes + * replaced by underscores, to make the registry happy, + * i.e. %SystemRoot%__ + */ + + DPRINT1("ConSrvOpenUserSettings entered\n"); + + /* Open the registry key where we saved the console properties */ + if (!OpenUserRegistryPathPerProcessId(ProcessId, &hKey, samDesired)) + { + DPRINT1("OpenUserRegistryPathPerProcessId failed\n"); + return FALSE; + } + + /* + * Try to open properties via the console title: + * to make the registry happy, replace all the + * backslashes by underscores. + */ + TranslateConsoleName(szBuffer2, ConsoleTitle, MAX_PATH); + + /* Create the registry path */ + wcsncat(szBuffer, szBuffer2, MAX_PATH); + + /* Create or open the registry key */ + if (bCreate) + { + /* Create the key */ + bRet = (RegCreateKeyExW(hKey, + szBuffer, + 0, NULL, + REG_OPTION_NON_VOLATILE, + samDesired, + NULL, + hSubKey, + NULL) == ERROR_SUCCESS); + } + else + { + /* Open the key */ + bRet = (RegOpenKeyExW(hKey, + szBuffer, + 0, + samDesired, + hSubKey) == ERROR_SUCCESS); + } + + /* Close the parent key and return success or not */ + RegCloseKey(hKey); + return bRet; +} + +BOOL +ConSrvReadUserSettings(IN OUT PCONSOLE_INFO ConsoleInfo, + IN DWORD ProcessId) +{ + HKEY hKey; + DWORD dwNumSubKeys = 0; + DWORD dwIndex; + DWORD dwValueName; + DWORD dwValue; + DWORD dwColorIndex = 0; + DWORD dwType; + WCHAR szValueName[MAX_PATH]; + WCHAR szValue[LF_FACESIZE] = L"\0"; + DWORD Value; + + if (!ConSrvOpenUserSettings(ProcessId, + ConsoleInfo->ConsoleTitle, + &hKey, KEY_READ, + FALSE)) + { + DPRINT1("ConSrvOpenUserSettings failed\n"); + return FALSE; + } + + if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, + &dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + { + DPRINT("ConSrvReadUserSettings: RegQueryInfoKey failed\n"); + RegCloseKey(hKey); + return FALSE; + } + + DPRINT("ConSrvReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys); + + for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++) + { + dwValue = sizeof(Value); + dwValueName = MAX_PATH; + + if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS) + { + if (dwType == REG_SZ) + { + /* + * Retry in case of string value + */ + dwValue = sizeof(szValue); + dwValueName = LF_FACESIZE; + if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS) + break; + } + else + { + break; + } + } + + if (!wcsncmp(szValueName, L"ColorTable", wcslen(L"ColorTable"))) + { + dwColorIndex = 0; + swscanf(szValueName, L"ColorTable%2d", &dwColorIndex); + if (dwColorIndex < sizeof(ConsoleInfo->Colors)/sizeof(ConsoleInfo->Colors[0])) + { + ConsoleInfo->Colors[dwColorIndex] = Value; + } + } + else if (!wcscmp(szValueName, L"HistoryBufferSize")) + { + ConsoleInfo->HistoryBufferSize = Value; + } + else if (!wcscmp(szValueName, L"NumberOfHistoryBuffers")) + { + ConsoleInfo->NumberOfHistoryBuffers = Value; + } + else if (!wcscmp(szValueName, L"HistoryNoDup")) + { + ConsoleInfo->HistoryNoDup = Value; + } + else if (!wcscmp(szValueName, L"FullScreen")) + { + ConsoleInfo->FullScreen = Value; + } + else if (!wcscmp(szValueName, L"QuickEdit")) + { + ConsoleInfo->QuickEdit = Value; + } + else if (!wcscmp(szValueName, L"InsertMode")) + { + ConsoleInfo->InsertMode = Value; + } + else if (!wcscmp(szValueName, L"ScreenBufferSize")) + { + ConsoleInfo->ScreenBufferSize.X = LOWORD(Value); + ConsoleInfo->ScreenBufferSize.Y = HIWORD(Value); + } + else if (!wcscmp(szValueName, L"WindowSize")) + { + ConsoleInfo->ConsoleSize.X = LOWORD(Value); + ConsoleInfo->ConsoleSize.Y = HIWORD(Value); + } + else if (!wcscmp(szValueName, L"CursorSize")) + { + if ( (Value == 0) || (Value == 50) || (Value == 100) ) + { + ConsoleInfo->CursorSize = Value; + } + } + else if (!wcscmp(szValueName, L"ScreenColors")) + { + ConsoleInfo->ScreenAttrib = Value; + } + else if (!wcscmp(szValueName, L"PopupColors")) + { + ConsoleInfo->PopupAttrib = Value; + } + else if (!wcscmp(szValueName, L"FaceName")) + { + wcsncpy(ConsoleInfo->u.GuiInfo.FaceName, szValue, LF_FACESIZE); + } + else if (!wcscmp(szValueName, L"FontFamily")) + { + ConsoleInfo->u.GuiInfo.FontFamily = Value; + } + else if (!wcscmp(szValueName, L"FontSize")) + { + ConsoleInfo->u.GuiInfo.FontSize = Value; + } + else if (!wcscmp(szValueName, L"FontWeight")) + { + ConsoleInfo->u.GuiInfo.FontWeight = Value; + } + else if (!wcscmp(szValueName, L"WindowPosition")) + { + ConsoleInfo->u.GuiInfo.AutoPosition = FALSE; + ConsoleInfo->u.GuiInfo.WindowOrigin.x = LOWORD(Value); + ConsoleInfo->u.GuiInfo.WindowOrigin.y = HIWORD(Value); + } + } + + RegCloseKey(hKey); + return TRUE; +} + +BOOL +ConSrvWriteUserSettings(IN PCONSOLE_INFO ConsoleInfo, + IN DWORD ProcessId) +{ + BOOL GlobalSettings = (ConsoleInfo->ConsoleTitle[0] == L'\0'); + HKEY hKey; + DWORD Storage = 0; + +#define SetConsoleSetting(SettingName, SettingType, SettingSize, Setting, DefaultValue) \ +do { \ + if (GlobalSettings || (!GlobalSettings && (*(Setting) != (DefaultValue)))) \ + { \ + RegSetValueExW(hKey, (SettingName), 0, (SettingType), (PBYTE)(Setting), (SettingSize)); \ + } \ + else \ + { \ + RegDeleteValue(hKey, (SettingName)); \ + } \ +} while (0) + + WCHAR szValueName[15]; + UINT i; + + if (!ConSrvOpenUserSettings(ProcessId, + ConsoleInfo->ConsoleTitle, + &hKey, KEY_WRITE, + TRUE)) + { + return FALSE; + } + + for (i = 0 ; i < sizeof(ConsoleInfo->Colors)/sizeof(ConsoleInfo->Colors[0]) ; ++i) + { + /* + * Write only the new value if we are saving the global settings + * or we are saving settings for a particular console, which differs + * from the default ones. + */ + swprintf(szValueName, L"ColorTable%02d", i); + SetConsoleSetting(szValueName, REG_DWORD, sizeof(DWORD), &ConsoleInfo->Colors[i], s_Colors[i]); + } + + SetConsoleSetting(L"HistoryBufferSize", REG_DWORD, sizeof(DWORD), &ConsoleInfo->HistoryBufferSize, 50); + SetConsoleSetting(L"NumberOfHistoryBuffers", REG_DWORD, sizeof(DWORD), &ConsoleInfo->NumberOfHistoryBuffers, 4); + + Storage = ConsoleInfo->HistoryNoDup; + SetConsoleSetting(L"HistoryNoDup", REG_DWORD, sizeof(DWORD), &Storage, FALSE); + + Storage = ConsoleInfo->FullScreen; + SetConsoleSetting(L"FullScreen", REG_DWORD, sizeof(DWORD), &Storage, FALSE); + + Storage = ConsoleInfo->QuickEdit; + SetConsoleSetting(L"QuickEdit", REG_DWORD, sizeof(DWORD), &Storage, FALSE); + + Storage = ConsoleInfo->InsertMode; + SetConsoleSetting(L"InsertMode", REG_DWORD, sizeof(DWORD), &Storage, TRUE); + + Storage = MAKELONG(ConsoleInfo->ScreenBufferSize.X, ConsoleInfo->ScreenBufferSize.Y); + SetConsoleSetting(L"ScreenBufferSize", REG_DWORD, sizeof(DWORD), &Storage, MAKELONG(80, 300)); + + Storage = MAKELONG(ConsoleInfo->ConsoleSize.X, ConsoleInfo->ConsoleSize.Y); + SetConsoleSetting(L"WindowSize", REG_DWORD, sizeof(DWORD), &Storage, MAKELONG(80, 25)); + + SetConsoleSetting(L"CursorSize", REG_DWORD, sizeof(DWORD), &ConsoleInfo->CursorSize, CSR_DEFAULT_CURSOR_SIZE); + + Storage = ConsoleInfo->ScreenAttrib; + SetConsoleSetting(L"ScreenColors", REG_DWORD, sizeof(DWORD), &Storage, DEFAULT_SCREEN_ATTRIB); + + Storage = ConsoleInfo->PopupAttrib; + SetConsoleSetting(L"PopupColors", REG_DWORD, sizeof(DWORD), &Storage, DEFAULT_POPUP_ATTRIB); + + SetConsoleSetting(L"FaceName", REG_SZ, (wcslen(ConsoleInfo->u.GuiInfo.FaceName) + 1) * sizeof(WCHAR), ConsoleInfo->u.GuiInfo.FaceName, L'\0'); + SetConsoleSetting(L"FontFamily", REG_DWORD, sizeof(DWORD), &ConsoleInfo->u.GuiInfo.FontFamily, FF_DONTCARE); + SetConsoleSetting(L"FontSize", REG_DWORD, sizeof(DWORD), &ConsoleInfo->u.GuiInfo.FontSize, 0); + SetConsoleSetting(L"FontWeight", REG_DWORD, sizeof(DWORD), &ConsoleInfo->u.GuiInfo.FontWeight, FW_DONTCARE); + + if (ConsoleInfo->u.GuiInfo.AutoPosition == FALSE) + { + Storage = MAKELONG(ConsoleInfo->u.GuiInfo.WindowOrigin.x, ConsoleInfo->u.GuiInfo.WindowOrigin.y); + RegSetValueExW(hKey, L"WindowPosition", 0, REG_DWORD, (PBYTE)&ConsoleInfo->u.GuiInfo.WindowOrigin, sizeof(DWORD)); + } + else + { + RegDeleteValue(hKey, L"WindowPosition"); + } + + RegCloseKey(hKey); + return TRUE; +} + +VOID +ConSrvGetDefaultSettings(IN OUT PCONSOLE_INFO ConsoleInfo, + IN DWORD ProcessId) +{ + DPRINT1("ConSrvGetDefaultSettings(0x%p)\n", ConsoleInfo); + + if (ConsoleInfo == NULL) return; + +/// HKCU,"Console","LoadConIme",0x00010003,1 + + /* + * 1. Load the default values + */ +// #define DEFAULT_HISTORY_COMMANDS_NUMBER 50 +// #define DEFAULT_HISTORY_BUFFERS_NUMBER 4 + ConsoleInfo->HistoryBufferSize = 50; + ConsoleInfo->NumberOfHistoryBuffers = 4; + ConsoleInfo->HistoryNoDup = FALSE; + + ConsoleInfo->FullScreen = FALSE; + ConsoleInfo->QuickEdit = FALSE; + ConsoleInfo->InsertMode = TRUE; + // ConsoleInfo->InputBufferSize; + ConsoleInfo->ScreenBufferSize = (COORD){80, 300}; + ConsoleInfo->ConsoleSize = (COORD){80, 25 }; + + ConsoleInfo->CursorBlinkOn; + ConsoleInfo->ForceCursorOff; + ConsoleInfo->CursorSize = CSR_DEFAULT_CURSOR_SIZE; // 0; #define SMALL_SIZE 25 // large enough to be one pixel on a six pixel font + + ConsoleInfo->ScreenAttrib = DEFAULT_SCREEN_ATTRIB; + ConsoleInfo->PopupAttrib = DEFAULT_POPUP_ATTRIB; + + memcpy(ConsoleInfo->Colors, s_Colors, sizeof(s_Colors)); + + // ConsoleInfo->CodePage; + + ConsoleInfo->ConsoleTitle[0] = L'\0'; + + // wcsncpy(ConsoleInfo->u.GuiInfo.FaceName, L"DejaVu Sans Mono", LF_FACESIZE); + // ConsoleInfo->u.GuiInfo.FontSize = MAKELONG(12, 8); // 0x0008000C; // font is 8x12 + // ConsoleInfo->u.GuiInfo.FontSize = MAKELONG(16, 16); // font is 16x16 + // ConsoleInfo->u.GuiInfo.FontWeight = FW_NORMAL; + + wcsncpy(ConsoleInfo->u.GuiInfo.FaceName, L"Fixedsys", LF_FACESIZE); // HACK: !! + // ConsoleInfo->u.GuiInfo.FaceName[0] = L'\0'; + ConsoleInfo->u.GuiInfo.FontFamily = FF_DONTCARE; + ConsoleInfo->u.GuiInfo.FontSize = 0; + ConsoleInfo->u.GuiInfo.FontWeight = FW_DONTCARE; + ConsoleInfo->u.GuiInfo.UseRasterFonts = TRUE; + + ConsoleInfo->u.GuiInfo.ShowWindow = SW_SHOWNORMAL; + ConsoleInfo->u.GuiInfo.AutoPosition = TRUE; + ConsoleInfo->u.GuiInfo.WindowOrigin = (POINT){0, 0}; + + // if (Console->ActiveBuffer) + // { + // Console->ActiveBuffer->ScreenBufferSize.X = 80; + // Console->ActiveBuffer->ScreenBufferSize.Y = 300; + // Console->ActiveBuffer->CursorInfo.bVisible = TRUE; + // } + + /* + * 2. Overwrite them with the ones stored in HKCU\Console. + * If the HKCU\Console key doesn't exist, create it + * and store the default values inside. + */ + if (!ConSrvReadUserSettings(ConsoleInfo, ProcessId)) + { + ConSrvWriteUserSettings(ConsoleInfo, ProcessId); + } +} + +/* EOF */ diff --git a/win32ss/user/consrv/settings.h b/win32ss/user/consrv/settings.h new file mode 100644 index 00000000000..4c0aaf36f86 --- /dev/null +++ b/win32ss/user/consrv/settings.h @@ -0,0 +1,91 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Server DLL + * FILE: win32ss/user/consrv/settings.h + * PURPOSE: Consoles settings management + * PROGRAMMERS: Hermes Belusca - Maito + * + * NOTE: Adapted from existing code. + */ + +#define PM_APPLY_CONSOLE_INFO (WM_APP + 100) + +/* STRUCTURES *****************************************************************/ + +typedef struct _GUI_CONSOLE_INFO +{ + // FONTSIGNATURE FontSignature; + WCHAR FaceName[LF_FACESIZE]; + UINT FontFamily; + DWORD FontSize; + DWORD FontWeight; + BOOL UseRasterFonts; + + WORD ShowWindow; + BOOL AutoPosition; + POINT WindowOrigin; +} GUI_CONSOLE_INFO, *PGUI_CONSOLE_INFO; + +typedef struct _CONSOLE_INFO +{ + ULONG HistoryBufferSize; + ULONG NumberOfHistoryBuffers; + BOOLEAN HistoryNoDup; + +/* BOOLEAN */ ULONG FullScreen; // Give the type of console: GUI (windowed) or TUI (fullscreen) + BOOLEAN QuickEdit; + BOOLEAN InsertMode; + ULONG InputBufferSize; + COORD ScreenBufferSize; + +/* SIZE */ COORD ConsoleSize; // This is really the size of the console at screen. + + BOOLEAN CursorBlinkOn; + BOOLEAN ForceCursorOff; + ULONG CursorSize; + + USHORT ScreenAttrib; // CHAR_INFO ScreenFillAttrib + USHORT PopupAttrib; + + // Color palette + COLORREF Colors[16]; + + ULONG CodePage; + + WCHAR ConsoleTitle[MAX_PATH + 1]; + + union + { + GUI_CONSOLE_INFO GuiInfo; + // TUI_CONSOLE_INFO TuiInfo; + } u; +} CONSOLE_INFO, *PCONSOLE_INFO; + +#define RGBFromAttrib(Console, Attribute) ((Console)->Colors[(Attribute) & 0xF]) +#define TextAttribFromAttrib(Attribute) ((Attribute) & 0xF) +#define BkgdAttribFromAttrib(Attribute) (((Attribute) >> 4) & 0xF) +#define MakeAttrib(TextAttrib, BkgdAttrib) (DWORD)((((BkgdAttrib) & 0xF) << 4) | ((TextAttrib) & 0xF)) + + +/* Used to communicate with console.dll */ +typedef struct _CONSOLE_PROPS +{ + HWND hConsoleWindow; + BOOL ShowDefaultParams; + + BOOLEAN AppliedConfig; + DWORD ActiveStaticControl; + + CONSOLE_INFO ci; +} CONSOLE_PROPS, *PCONSOLE_PROPS; + +/* FUNCTIONS ******************************************************************/ + +BOOL ConSrvReadUserSettings(IN OUT PCONSOLE_INFO ConsoleInfo, + IN DWORD ProcessId); +BOOL ConSrvWriteUserSettings(IN PCONSOLE_INFO ConsoleInfo, + IN DWORD ProcessId); +VOID ConSrvGetDefaultSettings(IN OUT PCONSOLE_INFO ConsoleInfo, + IN DWORD ProcessId); + +/* EOF */ diff --git a/win32ss/user/consrv/tuiconsole.c b/win32ss/user/consrv/tuiconsole.c index 08d98cce587..f5c5c2fd72f 100644 --- a/win32ss/user/consrv/tuiconsole.c +++ b/win32ss/user/consrv/tuiconsole.c @@ -7,6 +7,7 @@ */ #include "consrv.h" +#include "settings.h" #include "tuiconsole.h" #include @@ -150,366 +151,6 @@ TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) } static BOOL FASTCALL -TuiInit(DWORD OemCP) -{ - CONSOLE_SCREEN_BUFFER_INFO ScrInfo; - DWORD BytesReturned; - WNDCLASSEXW wc; - ATOM ConsoleClassAtom; - USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; - - ScmLoadDriver(L"Blue"); - - ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen", FILE_ALL_ACCESS, 0, NULL, - OPEN_EXISTING, 0, NULL); - if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle) - { - DPRINT1("Failed to open BlueScreen.\n"); - return FALSE; - } - - if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT, - &OemCP, sizeof(OemCP), NULL, 0, - &BytesReturned, NULL)) - { - DPRINT1("Failed to load the font for codepage %d\n", OemCP); - /* Let's suppose the font is good enough to continue */ - } - - if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE, - &TextAttribute, sizeof(TextAttribute), NULL, 0, - &BytesReturned, NULL)) - { - DPRINT1("Failed to set text attribute\n"); - } - - ActiveConsole = NULL; - InitializeCriticalSection(&ActiveConsoleLock); - if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO, - NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL)) - { - DPRINT1("Failed to get console info\n"); - return FALSE; - } - PhysicalConsoleSize = ScrInfo.dwSize; - - RtlZeroMemory(&wc, sizeof(WNDCLASSEXW)); - wc.cbSize = sizeof(WNDCLASSEXW); - wc.lpszClassName = TUI_CONSOLE_WINDOW_CLASS; - wc.lpfnWndProc = TuiConsoleWndProc; - wc.cbWndExtra = GWLP_CONSOLEWND_ALLOC; - wc.hInstance = ConSrvDllInstance; - - ConsoleClassAtom = RegisterClassExW(&wc); - if (ConsoleClassAtom == 0) - { - DPRINT1("Failed to register TUI console wndproc\n"); - return FALSE; - } - else - { - NtUserConsoleControl(TuiConsoleWndClassAtom, &ConsoleClassAtom, sizeof(ATOM)); - } - - return TRUE; -} - -static void FASTCALL -TuiCopyRect(char *Dest, PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* Region) -{ - UINT SrcDelta, DestDelta; - LONG i; - PBYTE Src, SrcEnd; - - Src = ConioCoordToPointer(Buff, Region->Left, Region->Top); - SrcDelta = Buff->MaxX * 2; - SrcEnd = Buff->Buffer + Buff->MaxY * Buff->MaxX * 2; - DestDelta = ConioRectWidth(Region) * 2; - for (i = Region->Top; i <= Region->Bottom; i++) - { - memcpy(Dest, Src, DestDelta); - Src += SrcDelta; - if (SrcEnd <= Src) - { - Src -= Buff->MaxY * Buff->MaxX * 2; - } - Dest += DestDelta; - } -} - -static VOID WINAPI -TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region) -{ - DWORD BytesReturned; - PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; - PCONSOLE_DRAW ConsoleDraw; - UINT ConsoleDrawSize; - - if (ActiveConsole != Console) - { - return; - } - - ConsoleDrawSize = sizeof(CONSOLE_DRAW) + - (ConioRectWidth(Region) * ConioRectHeight(Region)) * 2; - ConsoleDraw = RtlAllocateHeap(ConSrvHeap, 0, ConsoleDrawSize); - if (NULL == ConsoleDraw) - { - DPRINT1("RtlAllocateHeap failed\n"); - return; - } - ConsoleDraw->X = Region->Left; - ConsoleDraw->Y = Region->Top; - ConsoleDraw->SizeX = ConioRectWidth(Region); - ConsoleDraw->SizeY = ConioRectHeight(Region); - ConsoleDraw->CursorX = Buff->CurrentX; - ConsoleDraw->CursorY = Buff->CurrentY; - - TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region); - - if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW, - NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL)) - { - DPRINT1("Failed to draw console\n"); - RtlFreeHeap(ConSrvHeap, 0, ConsoleDraw); - return; - } - - RtlFreeHeap(ConSrvHeap, 0, ConsoleDraw); -} - -static VOID WINAPI -TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, LONG CursorStartX, LONG CursorStartY, - UINT ScrolledLines, CHAR *Buffer, UINT Length) -{ - DWORD BytesWritten; - PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; - - if (ActiveConsole->ActiveBuffer != Buff) - { - return; - } - - if (!WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL)) - { - DPRINT1("Error writing to BlueScreen\n"); - } -} - -static BOOL WINAPI -TuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff) -{ - CONSOLE_CURSOR_INFO Info; - DWORD BytesReturned; - - if (ActiveConsole->ActiveBuffer != Buff) - { - return TRUE; - } - - Info.dwSize = ConioEffectiveCursorSize(Console, 100); - Info.bVisible = Buff->CursorInfo.bVisible; - - if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO, - &Info, sizeof(Info), NULL, 0, &BytesReturned, NULL)) - { - DPRINT1( "Failed to set cursor info\n" ); - return FALSE; - } - - return TRUE; -} - -static BOOL WINAPI -TuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY) -{ - CONSOLE_SCREEN_BUFFER_INFO Info; - DWORD BytesReturned; - - if (ActiveConsole->ActiveBuffer != Buff) - { - return TRUE; - } - - Info.dwCursorPosition.X = Buff->CurrentX; - Info.dwCursorPosition.Y = Buff->CurrentY; - Info.wAttributes = Buff->DefaultAttrib; - - if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, - &Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0, - &BytesReturned, NULL)) - { - DPRINT1( "Failed to set cursor position\n" ); - return FALSE; - } - - return TRUE; -} - -static BOOL WINAPI -TuiUpdateScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff) -{ - return TRUE; -} - -static VOID WINAPI -TuiChangeTitle(PCONSOLE Console) -{ -} - -static VOID WINAPI -TuiCleanupConsole(PCONSOLE Console) -{ - DestroyWindow(Console->hWindow); - - EnterCriticalSection(&ActiveConsoleLock); - - /* Switch to next console */ - if (ActiveConsole == Console) - { - ActiveConsole = Console->Next != Console ? Console->Next : NULL; - } - - if (Console->Next != Console) - { - Console->Prev->Next = Console->Next; - Console->Next->Prev = Console->Prev; - } - LeaveCriticalSection(&ActiveConsoleLock); - - if (NULL != ActiveConsole) - { - ConioDrawConsole(ActiveConsole); - } -} - -static BOOL WINAPI -TuiChangeIcon(PCONSOLE Console, HICON hWindowIcon) -{ - return TRUE; -} - -static NTSTATUS WINAPI -TuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Size) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -DWORD WINAPI -TuiConsoleThread(PVOID Data) -{ - PCONSOLE Console = (PCONSOLE) Data; - HWND NewWindow; - MSG msg; - - NewWindow = CreateWindowW(TUI_CONSOLE_WINDOW_CLASS, - Console->Title.Buffer, - 0, - -32000, -32000, 0, 0, - NULL, NULL, - ConSrvDllInstance, - (PVOID)Console); - if (NULL == NewWindow) - { - DPRINT1("CONSRV: Unable to create console window\n"); - return 1; - } - Console->hWindow = NewWindow; - SetConsoleWndConsoleLeaderCID(Console); - - SetForegroundWindow(Console->hWindow); - - while (TRUE) - { - GetMessageW(&msg, 0, 0, 0); - DispatchMessage(&msg); - TranslateMessage(&msg); - - if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR || - msg.message == WM_KEYDOWN || msg.message == WM_KEYUP || - msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP) - { - ConioProcessKey(&msg, Console, TRUE); - } - } - - return 0; -} - -static CONSOLE_VTBL TuiVtbl = -{ - TuiWriteStream, - TuiDrawRegion, - TuiSetCursorInfo, - TuiSetScreenInfo, - TuiUpdateScreenInfo, - TuiChangeTitle, - TuiCleanupConsole, - TuiChangeIcon, - TuiResizeBuffer, -}; - -NTSTATUS FASTCALL -TuiInitConsole(PCONSOLE Console) -{ - HANDLE ThreadHandle; - - if (!ConsInitialized) - { - ConsInitialized = TRUE; - if (!TuiInit(Console->CodePage)) - { - ConsInitialized = FALSE; - return STATUS_UNSUCCESSFUL; - } - } - - Console->Vtbl = &TuiVtbl; - Console->hWindow = NULL; - Console->Size = PhysicalConsoleSize; - Console->ActiveBuffer->MaxX = PhysicalConsoleSize.X; - Console->ActiveBuffer->MaxY = PhysicalConsoleSize.Y; - - ThreadHandle = CreateThread(NULL, - 0, - TuiConsoleThread, - (PVOID)Console, - 0, - NULL); - if (NULL == ThreadHandle) - { - DPRINT1("CONSRV: Unable to create console thread\n"); - return STATUS_UNSUCCESSFUL; - } - CloseHandle(ThreadHandle); - - EnterCriticalSection(&ActiveConsoleLock); - if (NULL != ActiveConsole) - { - Console->Prev = ActiveConsole; - Console->Next = ActiveConsole->Next; - ActiveConsole->Next->Prev = Console; - ActiveConsole->Next = Console; - } - else - { - Console->Prev = Console; - Console->Next = Console; - } - ActiveConsole = Console; - LeaveCriticalSection(&ActiveConsoleLock); - - return STATUS_SUCCESS; -} - -PCONSOLE FASTCALL -TuiGetFocusConsole(VOID) -{ - return ActiveConsole; -} - -BOOL FASTCALL TuiSwapConsole(INT Next) { static PCONSOLE SwapConsole = NULL; /* console we are thinking about swapping with */ @@ -579,4 +220,385 @@ TuiSwapConsole(INT Next) } } +static BOOL WINAPI +TuiProcessKeyCallback(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD ShiftState, UINT VirtualKeyCode, BOOL Down) +{ + if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) && + VK_TAB == VirtualKeyCode) + { + if (Down) + { + TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1); + } + + return TRUE; + } + else if (VK_MENU == VirtualKeyCode && !Down) + { + return TuiSwapConsole(0); + } + + return FALSE; +} + +static BOOL FASTCALL +TuiInit(DWORD OemCP) +{ + CONSOLE_SCREEN_BUFFER_INFO ScrInfo; + DWORD BytesReturned; + WNDCLASSEXW wc; + ATOM ConsoleClassAtom; + USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + + ScmLoadDriver(L"Blue"); + + ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen", FILE_ALL_ACCESS, 0, NULL, + OPEN_EXISTING, 0, NULL); + if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle) + { + DPRINT1("Failed to open BlueScreen.\n"); + return FALSE; + } + + if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT, + &OemCP, sizeof(OemCP), NULL, 0, + &BytesReturned, NULL)) + { + DPRINT1("Failed to load the font for codepage %d\n", OemCP); + /* Let's suppose the font is good enough to continue */ + } + + if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE, + &TextAttribute, sizeof(TextAttribute), NULL, 0, + &BytesReturned, NULL)) + { + DPRINT1("Failed to set text attribute\n"); + } + + ActiveConsole = NULL; + InitializeCriticalSection(&ActiveConsoleLock); + if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO, + NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL)) + { + DPRINT1("Failed to get console info\n"); + return FALSE; + } + PhysicalConsoleSize = ScrInfo.dwSize; + + RtlZeroMemory(&wc, sizeof(WNDCLASSEXW)); + wc.cbSize = sizeof(WNDCLASSEXW); + wc.lpszClassName = TUI_CONSOLE_WINDOW_CLASS; + wc.lpfnWndProc = TuiConsoleWndProc; + wc.cbWndExtra = GWLP_CONSOLEWND_ALLOC; + wc.hInstance = ConSrvDllInstance; + + ConsoleClassAtom = RegisterClassExW(&wc); + if (ConsoleClassAtom == 0) + { + DPRINT1("Failed to register TUI console wndproc\n"); + return FALSE; + } + else + { + NtUserConsoleControl(TuiConsoleWndClassAtom, &ConsoleClassAtom, sizeof(ATOM)); + } + + return TRUE; +} + +static VOID FASTCALL +TuiCopyRect(char *Dest, PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* Region) +{ + UINT SrcDelta, DestDelta; + LONG i; + PBYTE Src, SrcEnd; + + Src = ConioCoordToPointer(Buff, Region->Left, Region->Top); + SrcDelta = Buff->ScreenBufferSize.X * 2; + SrcEnd = Buff->Buffer + Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * 2; + DestDelta = ConioRectWidth(Region) * 2; + for (i = Region->Top; i <= Region->Bottom; i++) + { + memcpy(Dest, Src, DestDelta); + Src += SrcDelta; + if (SrcEnd <= Src) + { + Src -= Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * 2; + } + Dest += DestDelta; + } +} + +static VOID WINAPI +TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region) +{ + DWORD BytesReturned; + PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; + PCONSOLE_DRAW ConsoleDraw; + UINT ConsoleDrawSize; + + if (ActiveConsole != Console) + { + return; + } + + ConsoleDrawSize = sizeof(CONSOLE_DRAW) + + (ConioRectWidth(Region) * ConioRectHeight(Region)) * 2; + ConsoleDraw = RtlAllocateHeap(ConSrvHeap, 0, ConsoleDrawSize); + if (NULL == ConsoleDraw) + { + DPRINT1("RtlAllocateHeap failed\n"); + return; + } + ConsoleDraw->X = Region->Left; + ConsoleDraw->Y = Region->Top; + ConsoleDraw->SizeX = ConioRectWidth(Region); + ConsoleDraw->SizeY = ConioRectHeight(Region); + ConsoleDraw->CursorX = Buff->CursorPosition.X; + ConsoleDraw->CursorY = Buff->CursorPosition.Y; + + TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region); + + if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW, + NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL)) + { + DPRINT1("Failed to draw console\n"); + RtlFreeHeap(ConSrvHeap, 0, ConsoleDraw); + return; + } + + RtlFreeHeap(ConSrvHeap, 0, ConsoleDraw); +} + +static VOID WINAPI +TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, LONG CursorStartX, LONG CursorStartY, + UINT ScrolledLines, CHAR *Buffer, UINT Length) +{ + DWORD BytesWritten; + PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; + + if (ActiveConsole->ActiveBuffer != Buff) + { + return; + } + + if (!WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL)) + { + DPRINT1("Error writing to BlueScreen\n"); + } +} + +static BOOL WINAPI +TuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff) +{ + CONSOLE_CURSOR_INFO Info; + DWORD BytesReturned; + + if (ActiveConsole->ActiveBuffer != Buff) + { + return TRUE; + } + + Info.dwSize = ConioEffectiveCursorSize(Console, 100); + Info.bVisible = Buff->CursorInfo.bVisible; + + if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO, + &Info, sizeof(Info), NULL, 0, &BytesReturned, NULL)) + { + DPRINT1( "Failed to set cursor info\n" ); + return FALSE; + } + + return TRUE; +} + +static BOOL WINAPI +TuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY) +{ + CONSOLE_SCREEN_BUFFER_INFO Info; + DWORD BytesReturned; + + if (ActiveConsole->ActiveBuffer != Buff) + { + return TRUE; + } + + Info.dwCursorPosition = Buff->CursorPosition; + Info.wAttributes = Buff->ScreenDefaultAttrib; + + if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, + &Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0, + &BytesReturned, NULL)) + { + DPRINT1( "Failed to set cursor position\n" ); + return FALSE; + } + + return TRUE; +} + +static BOOL WINAPI +TuiUpdateScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff) +{ + return TRUE; +} + +static VOID WINAPI +TuiChangeTitle(PCONSOLE Console) +{ +} + +static VOID WINAPI +TuiCleanupConsole(PCONSOLE Console) +{ + DestroyWindow(Console->hWindow); + + EnterCriticalSection(&ActiveConsoleLock); + + /* Switch to next console */ + if (ActiveConsole == Console) + { + ActiveConsole = Console->Next != Console ? Console->Next : NULL; + } + + if (Console->Next != Console) + { + Console->Prev->Next = Console->Next; + Console->Next->Prev = Console->Prev; + } + LeaveCriticalSection(&ActiveConsoleLock); + + if (NULL != ActiveConsole) + { + ConioDrawConsole(ActiveConsole); + } +} + +static BOOL WINAPI +TuiChangeIcon(PCONSOLE Console, HICON hWindowIcon) +{ + return TRUE; +} + +static NTSTATUS WINAPI +TuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Size) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +static DWORD WINAPI +TuiConsoleThread(PVOID Data) +{ + PCONSOLE Console = (PCONSOLE) Data; + HWND NewWindow; + MSG msg; + + NewWindow = CreateWindowW(TUI_CONSOLE_WINDOW_CLASS, + Console->Title.Buffer, + 0, + -32000, -32000, 0, 0, + NULL, NULL, + ConSrvDllInstance, + (PVOID)Console); + if (NULL == NewWindow) + { + DPRINT1("CONSRV: Unable to create console window\n"); + return 1; + } + Console->hWindow = NewWindow; + SetConsoleWndConsoleLeaderCID(Console); + + SetForegroundWindow(Console->hWindow); + + while (TRUE) + { + GetMessageW(&msg, 0, 0, 0); + DispatchMessage(&msg); + TranslateMessage(&msg); + + if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR || + msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN || + msg.message == WM_KEYUP || msg.message == WM_SYSKEYUP) + { + ConioProcessKey(Console, &msg); + } + } + + return 0; +} + +static CONSOLE_VTBL TuiVtbl = +{ + TuiWriteStream, + TuiDrawRegion, + TuiSetCursorInfo, + TuiSetScreenInfo, + TuiUpdateScreenInfo, + TuiChangeTitle, + TuiCleanupConsole, + TuiChangeIcon, + TuiResizeBuffer, + TuiProcessKeyCallback +}; + +NTSTATUS FASTCALL +TuiInitConsole(PCONSOLE Console, + PCONSOLE_INFO ConsoleInfo) +{ + HANDLE ThreadHandle; + + if (!ConsInitialized) + { + ConsInitialized = TRUE; + if (!TuiInit(Console->CodePage)) + { + ConsInitialized = FALSE; + return STATUS_UNSUCCESSFUL; + } + } + + Console->Vtbl = &TuiVtbl; + Console->hWindow = NULL; + Console->Size = PhysicalConsoleSize; + Console->ActiveBuffer->ScreenBufferSize = PhysicalConsoleSize; + + ThreadHandle = CreateThread(NULL, + 0, + TuiConsoleThread, + (PVOID)Console, + 0, + NULL); + if (NULL == ThreadHandle) + { + DPRINT1("CONSRV: Unable to create console thread\n"); + return STATUS_UNSUCCESSFUL; + } + CloseHandle(ThreadHandle); + + EnterCriticalSection(&ActiveConsoleLock); + if (NULL != ActiveConsole) + { + Console->Prev = ActiveConsole; + Console->Next = ActiveConsole->Next; + ActiveConsole->Next->Prev = Console; + ActiveConsole->Next = Console; + } + else + { + Console->Prev = Console; + Console->Next = Console; + } + ActiveConsole = Console; + LeaveCriticalSection(&ActiveConsoleLock); + + return STATUS_SUCCESS; +} + +PCONSOLE FASTCALL +TuiGetFocusConsole(VOID) +{ + return ActiveConsole; +} + /* EOF */ diff --git a/win32ss/user/consrv/tuiconsole.h b/win32ss/user/consrv/tuiconsole.h index b9a5fe382bd..f38cc1c383a 100644 --- a/win32ss/user/consrv/tuiconsole.h +++ b/win32ss/user/consrv/tuiconsole.h @@ -8,8 +8,8 @@ #include "conio.h" -extern NTSTATUS FASTCALL TuiInitConsole(PCONSOLE Console); -extern PCONSOLE FASTCALL TuiGetFocusConsole(VOID); -extern BOOL FASTCALL TuiSwapConsole(INT Next); +NTSTATUS FASTCALL TuiInitConsole(PCONSOLE Console, + PCONSOLE_INFO ConsoleInfo); +PCONSOLE FASTCALL TuiGetFocusConsole(VOID); /* EOF */