X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fsubsystems%2Fwin32%2Fcsrss%2Fwin32csr%2Fguiconsole.c;h=e274872a6eba2ede7c80016015636f8e5e73120d;hp=51eca7c21c73ca5130d928ae3cbf9cf0bc536af5;hb=d27f068a199d9ea217e3ae9145d6e3ccfecde54f;hpb=eb35955f30cbc83d4fbc45c18ead47e39acb0488 diff --git a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c index 51eca7c21c7..e274872a6eb 100644 --- a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c +++ b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c @@ -19,35 +19,33 @@ extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check); typedef struct GUI_CONSOLE_DATA_TAG { - HFONT Font; - unsigned CharWidth; - unsigned CharHeight; - PWCHAR LineBuffer; - BOOL CursorBlinkOn; - BOOL ForceCursorOff; - CRITICAL_SECTION Lock; - RECT Selection; - POINT SelectionStart; - BOOL MouseDown; - HMODULE ConsoleLibrary; - HANDLE hGuiInitEvent; - WCHAR FontName[LF_FACESIZE]; - DWORD FontSize; - DWORD FontWeight; - DWORD HistoryNoDup; - DWORD FullScreen; - DWORD QuickEdit; - DWORD InsertMode; - DWORD NumberOfHistoryBuffers; - DWORD HistoryBufferSize; - DWORD WindowPosition; - DWORD UseRasterFonts; - COLORREF ScreenText; - COLORREF ScreenBackground; - COLORREF PopupBackground; - COLORREF PopupText; - COLORREF Colors[16]; - WCHAR szProcessName[MAX_PATH]; + HFONT Font; + unsigned CharWidth; + unsigned CharHeight; + BOOL CursorBlinkOn; + BOOL ForceCursorOff; + CRITICAL_SECTION Lock; + HMODULE ConsoleLibrary; + HANDLE hGuiInitEvent; + WCHAR FontName[LF_FACESIZE]; + DWORD FontSize; + DWORD FontWeight; + DWORD HistoryNoDup; + DWORD FullScreen; + DWORD QuickEdit; + DWORD InsertMode; + DWORD NumberOfHistoryBuffers; + DWORD HistoryBufferSize; + DWORD WindowPosition; + DWORD UseRasterFonts; + COLORREF ScreenText; + COLORREF ScreenBackground; + COLORREF PopupBackground; + COLORREF PopupText; + COLORREF Colors[16]; + WCHAR szProcessName[MAX_PATH]; + BOOL WindowSizeLock; + POINT OldCursor; } GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA; #ifndef WM_APP @@ -115,7 +113,7 @@ static const COLORREF s_Colors[] = /* FUNCTIONS *****************************************************************/ -static VOID FASTCALL +static VOID GuiConsoleAppendMenuItems(HMENU hMenu, const GUICONSOLE_MENUITEM *Items) { @@ -166,11 +164,11 @@ GuiConsoleAppendMenuItems(HMENU hMenu, 0, NULL); } - i++; - }while(!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0)); + i++; + } while(!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0)); } -static VOID FASTCALL +static VOID GuiConsoleCreateSysMenu(PCSRSS_CONSOLE Console) { HMENU hMenu; @@ -184,209 +182,209 @@ GuiConsoleCreateSysMenu(PCSRSS_CONSOLE Console) } } -static VOID FASTCALL +static VOID GuiConsoleGetDataPointers(HWND hWnd, PCSRSS_CONSOLE *Console, PGUI_CONSOLE_DATA *GuiData) { - *Console = (PCSRSS_CONSOLE) GetWindowLongPtrW(hWnd, GWL_USERDATA); - *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData); + *Console = (PCSRSS_CONSOLE) GetWindowLongPtrW(hWnd, GWL_USERDATA); + *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData); } -static BOOL FASTCALL +static BOOL GuiConsoleOpenUserRegistryPathPerProcessId(DWORD ProcessId, PHANDLE hProcHandle, PHKEY hResult, REGSAM samDesired) { - HANDLE hProcessToken = NULL; - HANDLE hProcess; + HANDLE hProcessToken = NULL; + HANDLE hProcess; - BYTE Buffer[256]; - DWORD Length = 0; - UNICODE_STRING SidName; - LONG res; - PTOKEN_USER TokUser; + 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) + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | READ_CONTROL, FALSE, ProcessId); + if (!hProcess) { - DPRINT("Error: OpenProcess failed(0x%x)\n", GetLastError()); - return FALSE; + DPRINT("Error: OpenProcess failed(0x%x)\n", GetLastError()); + return FALSE; } - if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken)) + if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken)) { - DPRINT("Error: OpenProcessToken failed(0x%x)\n", GetLastError()); - CloseHandle(hProcess); - return FALSE; + DPRINT("Error: OpenProcessToken failed(0x%x)\n", GetLastError()); + CloseHandle(hProcess); + return FALSE; } - if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length)) + if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length)) { - DPRINT("Error: GetTokenInformation failed(0x%x)\n",GetLastError()); - CloseHandle(hProcess); - CloseHandle(hProcessToken); - return FALSE; + DPRINT("Error: GetTokenInformation failed(0x%x)\n",GetLastError()); + CloseHandle(hProcess); + CloseHandle(hProcessToken); + return FALSE; } - TokUser = ((PTOKEN_USER)Buffer)->User.Sid; - if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE))) + TokUser = ((PTOKEN_USER)Buffer)->User.Sid; + if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE))) { - DPRINT("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError()); - return FALSE; + DPRINT("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError()); + return FALSE; } - res = RegOpenKeyExW(HKEY_USERS, SidName.Buffer, 0, samDesired, hResult); - RtlFreeUnicodeString(&SidName); + res = RegOpenKeyExW(HKEY_USERS, SidName.Buffer, 0, samDesired, hResult); + RtlFreeUnicodeString(&SidName); - CloseHandle(hProcessToken); - if (hProcHandle) - *hProcHandle = hProcess; - else - CloseHandle(hProcess); + CloseHandle(hProcessToken); + if (hProcHandle) + *hProcHandle = hProcess; + else + CloseHandle(hProcess); - if (res != ERROR_SUCCESS) - return FALSE; - else - return TRUE; + if (res != ERROR_SUCCESS) + return FALSE; + else + return TRUE; } -static BOOL FASTCALL +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; + 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 - */ + /* + * 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"); + DPRINT("GuiConsoleOpenUserSettings entered\n"); - if (!GuiConsoleOpenUserRegistryPathPerProcessId(ProcessId, &hProcess, &hKey, samDesired)) + if (!GuiConsoleOpenUserRegistryPathPerProcessId(ProcessId, &hProcess, &hKey, samDesired)) { - DPRINT("GuiConsoleOpenUserRegistryPathPerProcessId failed\n"); - return FALSE; + 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); + /* 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); + //DPRINT1("szProcessName3 : %S\n",szProcessName); - if (!fLength) + if (!fLength) { - DPRINT("GetProcessImageFileNameW failed(0x%x)ProcessId %d\n", GetLastError(),hProcess); - return FALSE; + DPRINT("GetProcessImageFileNameW failed(0x%x)ProcessId %d\n", GetLastError(),hProcess); + return FALSE; } - /* - * try the process name as path - */ + /* + * try the process name as path + */ - ptr = wcsrchr(szProcessName, L'\\'); - wcscpy(GuiData->szProcessName, ptr); + ptr = wcsrchr(szProcessName, L'\\'); + wcscpy(GuiData->szProcessName, ptr); - swprintf(szBuffer, L"Console%s",ptr); - DPRINT("#1 Path : %S\n", szBuffer); + swprintf(szBuffer, L"Console%s",ptr); + DPRINT("#1 Path : %S\n", szBuffer); - if (bCreate) + if (bCreate) { - if (RegCreateKeyW(hKey, szBuffer, hSubKey) == ERROR_SUCCESS) + if (RegCreateKeyW(hKey, szBuffer, hSubKey) == ERROR_SUCCESS) { - RegCloseKey(hKey); - return TRUE; + RegCloseKey(hKey); + return TRUE; } - RegCloseKey(hKey); - return FALSE; - } + RegCloseKey(hKey); + return FALSE; + } - if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) + if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) { - RegCloseKey(hKey); - return TRUE; + RegCloseKey(hKey); + return TRUE; } - /* - * try the "Shortcut to processname" as path - * FIXME: detect wheter the process was started as a shortcut - */ + /* + * 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(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; + swprintf(GuiData->szProcessName, L"Shortcut to %S", ptr); + RegCloseKey(hKey); + return TRUE; } - /* - * if the path contains \\Device\\HarddiskVolume1\... remove it - */ + /* + * if the path contains \\Device\\HarddiskVolume1\... remove it + */ - if (szProcessName[0] == L'\\') + if (szProcessName[0] == L'\\') { - dwBitmask = GetLogicalDrives(); - while(dwBitmask) + dwBitmask = GetLogicalDrives(); + while(dwBitmask) { - if (dwBitmask & 0x1) + if (dwBitmask & 0x1) { - dwLength = QueryDosDeviceW(CurDrive, szBuffer, MAX_PATH); - if (dwLength) + dwLength = QueryDosDeviceW(CurDrive, szBuffer, MAX_PATH); + if (dwLength) { - if (!memcmp(szBuffer, szProcessName, (dwLength-2)*sizeof(WCHAR))) + if (!memcmp(szBuffer, szProcessName, (dwLength-2)*sizeof(WCHAR))) { - wcscpy(szProcessName, CurDrive); - RtlMoveMemory(&szProcessName[2], &szProcessName[dwLength-1], fLength - dwLength -1); - break; + wcscpy(szProcessName, CurDrive); + RtlMoveMemory(&szProcessName[2], &szProcessName[dwLength-1], fLength - dwLength -1); + break; } } } - dwBitmask = (dwBitmask >> 1); - CurDrive[0]++; + dwBitmask = (dwBitmask >> 1); + CurDrive[0]++; } } - /* - * last attempt: check whether the file is under %SystemRoot% - * and use path like Console\%SystemRoot%_dir_dir2_file.exe - */ + /* + * 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) + wLength = GetWindowsDirectoryW(szBuffer, MAX_PATH); + if (wLength) { - if (!wcsncmp(szProcessName, szBuffer, wLength)) + if (!wcsncmp(szProcessName, szBuffer, wLength)) { - /* replace slashes by underscores */ - while((ptr = wcschr(szProcessName, L'\\'))) - ptr[0] = L'_'; + /* 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(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; + swprintf(GuiData->szProcessName, L"%%SystemRoot%%%S", &szProcessName[wLength]); + RegCloseKey(hKey); + return TRUE; } } } - RegCloseKey(hKey); - return FALSE; + RegCloseKey(hKey); + return FALSE; } static VOID @@ -396,238 +394,238 @@ GuiConsoleWriteUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData) PCSRSS_PROCESS_DATA ProcessData; if (Console->ProcessList.Flink == &Console->ProcessList) - { + { DPRINT("GuiConsoleWriteUserSettings: No Process!!!\n"); return; - } + } ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry); if (!GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ | KEY_WRITE, TRUE)) - { + { return; - } + } - if (Console->ActiveBuffer->CursorInfo.dwSize <= 1) + if (Console->ActiveBuffer->CursorInfo.dwSize <= 1) { - RegDeleteKeyW(hKey, L"CursorSize"); + RegDeleteKeyW(hKey, L"CursorSize"); } - else + else { - RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD)); + RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD)); } - if (GuiData->NumberOfHistoryBuffers == 5) + if (GuiData->NumberOfHistoryBuffers == 5) { - RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers"); + RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers"); } - else + else { - RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&GuiData->NumberOfHistoryBuffers, sizeof(DWORD)); + RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&GuiData->NumberOfHistoryBuffers, sizeof(DWORD)); } - if (GuiData->HistoryBufferSize == 50) + if (GuiData->HistoryBufferSize == 50) { - RegDeleteKeyW(hKey, L"HistoryBufferSize"); + RegDeleteKeyW(hKey, L"HistoryBufferSize"); } - else + else { - RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryBufferSize, sizeof(DWORD)); + RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryBufferSize, sizeof(DWORD)); } - if (GuiData->FullScreen == FALSE) + if (GuiData->FullScreen == FALSE) { - RegDeleteKeyW(hKey, L"FullScreen"); + RegDeleteKeyW(hKey, L"FullScreen"); } - else + else { - RegSetValueExW(hKey, L"FullScreen", 0, REG_DWORD, (const BYTE *)&GuiData->FullScreen, sizeof(DWORD)); + RegSetValueExW(hKey, L"FullScreen", 0, REG_DWORD, (const BYTE *)&GuiData->FullScreen, sizeof(DWORD)); } - if ( GuiData->QuickEdit == FALSE) + if ( GuiData->QuickEdit == FALSE) { - RegDeleteKeyW(hKey, L"QuickEdit"); + RegDeleteKeyW(hKey, L"QuickEdit"); } else { - RegSetValueExW(hKey, L"QuickEdit", 0, REG_DWORD, (const BYTE *)&GuiData->QuickEdit, sizeof(DWORD)); + RegSetValueExW(hKey, L"QuickEdit", 0, REG_DWORD, (const BYTE *)&GuiData->QuickEdit, sizeof(DWORD)); } - if (GuiData->InsertMode == TRUE) + if (GuiData->InsertMode == TRUE) { - RegDeleteKeyW(hKey, L"InsertMode"); + RegDeleteKeyW(hKey, L"InsertMode"); } - else + else { - RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD)); + RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD)); } - if (GuiData->HistoryNoDup == FALSE) + if (GuiData->HistoryNoDup == FALSE) { - RegDeleteKeyW(hKey, L"HistoryNoDup"); + RegDeleteKeyW(hKey, L"HistoryNoDup"); } - else + else { - RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryNoDup, sizeof(DWORD)); + RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryNoDup, sizeof(DWORD)); } - if (GuiData->ScreenText == RGB(192, 192, 192)) + if (GuiData->ScreenText == RGB(192, 192, 192)) { - /* - * MS uses console attributes instead of real color - */ - RegDeleteKeyW(hKey, L"ScreenText"); + /* + * MS uses console attributes instead of real color + */ + RegDeleteKeyW(hKey, L"ScreenText"); } - else + else { - RegSetValueExW(hKey, L"ScreenText", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenText, sizeof(COLORREF)); + RegSetValueExW(hKey, L"ScreenText", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenText, sizeof(COLORREF)); } - if (GuiData->ScreenBackground == RGB(0, 0, 0)) + if (GuiData->ScreenBackground == RGB(0, 0, 0)) { - RegDeleteKeyW(hKey, L"ScreenBackground"); + RegDeleteKeyW(hKey, L"ScreenBackground"); } - else + else { - RegSetValueExW(hKey, L"ScreenBackground", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenBackground, sizeof(COLORREF)); + RegSetValueExW(hKey, L"ScreenBackground", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenBackground, sizeof(COLORREF)); } - RegCloseKey(hKey); + RegCloseKey(hKey); } -static void FASTCALL +static void GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_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; + 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); + DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys); - for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++) + for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++) { - dwValue = sizeof(Value); - dwValueName = MAX_PATH; + dwValue = sizeof(Value); + dwValueName = MAX_PATH; - if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS) + if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS) { - if (dwType == REG_SZ) + 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; + /* + * 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; + else + break; } - if (!wcscmp(szValueName, L"CursorSize")) + if (!wcscmp(szValueName, L"CursorSize")) { - if (Value == 0x32) + if (Value == 0x32) { - Buffer->CursorInfo.dwSize = Value; + Buffer->CursorInfo.dwSize = Value; } - else if (Value == 0x64) + else if (Value == 0x64) { - Buffer->CursorInfo.dwSize = Value; + Buffer->CursorInfo.dwSize = Value; } } - else if (!wcscmp(szValueName, L"ScreenText")) + else if (!wcscmp(szValueName, L"ScreenText")) { - GuiData->ScreenText = Value; + GuiData->ScreenText = Value; } - else if (!wcscmp(szValueName, L"ScreenBackground")) + else if (!wcscmp(szValueName, L"ScreenBackground")) { - GuiData->ScreenBackground = Value; + GuiData->ScreenBackground = Value; } - else if (!wcscmp(szValueName, L"FaceName")) + else if (!wcscmp(szValueName, L"FaceName")) { - wcscpy(GuiData->FontName, szValue); + wcscpy(GuiData->FontName, szValue); } - else if (!wcscmp(szValueName, L"FontSize")) + else if (!wcscmp(szValueName, L"FontSize")) { - GuiData->FontSize = Value; + GuiData->FontSize = Value; } - else if (!wcscmp(szValueName, L"FontWeight")) + else if (!wcscmp(szValueName, L"FontWeight")) { - GuiData->FontWeight = Value; + GuiData->FontWeight = Value; } - else if (!wcscmp(szValueName, L"HistoryNoDup")) + else if (!wcscmp(szValueName, L"HistoryNoDup")) { - GuiData->HistoryNoDup = Value; + GuiData->HistoryNoDup = Value; } - else if (!wcscmp(szValueName, L"WindowSize")) + else if (!wcscmp(szValueName, L"WindowSize")) { - Console->Size.X = LOWORD(Value); - Console->Size.Y = HIWORD(Value); + Console->Size.X = LOWORD(Value); + Console->Size.Y = HIWORD(Value); } - else if (!wcscmp(szValueName, L"ScreenBufferSize")) + else if (!wcscmp(szValueName, L"ScreenBufferSize")) { if(Buffer) - { + { Buffer->MaxX = LOWORD(Value); Buffer->MaxY = HIWORD(Value); - } + } } - else if (!wcscmp(szValueName, L"FullScreen")) + else if (!wcscmp(szValueName, L"FullScreen")) { - GuiData->FullScreen = Value; + GuiData->FullScreen = Value; } - else if (!wcscmp(szValueName, L"QuickEdit")) + else if (!wcscmp(szValueName, L"QuickEdit")) { - GuiData->QuickEdit = Value; + GuiData->QuickEdit = Value; } - else if (!wcscmp(szValueName, L"InsertMode")) + else if (!wcscmp(szValueName, L"InsertMode")) { - GuiData->InsertMode = Value; + GuiData->InsertMode = Value; } - } + } } -static VOID FASTCALL +static VOID GuiConsoleUseDefaults(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer) { - /* - * init guidata with default properties - */ - - wcscpy(GuiData->FontName, L"DejaVu Sans Mono"); - GuiData->FontSize = 0x0008000C; // font is 8x12 - GuiData->FontWeight = FW_NORMAL; - GuiData->HistoryNoDup = FALSE; - GuiData->FullScreen = FALSE; - GuiData->QuickEdit = FALSE; - GuiData->InsertMode = TRUE; - GuiData->HistoryBufferSize = 50; - GuiData->NumberOfHistoryBuffers = 5; - GuiData->ScreenText = RGB(192, 192, 192); - GuiData->ScreenBackground = RGB(0, 0, 0); - GuiData->PopupText = RGB(128, 0, 128); - GuiData->PopupBackground = RGB(255, 255, 255); - GuiData->WindowPosition = UINT_MAX; - GuiData->UseRasterFonts = TRUE; - memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors)); - - Console->Size.X = 80; - Console->Size.Y = 25; - - if (Buffer) - { - Buffer->MaxX = 80; - Buffer->MaxY = 25; - Buffer->CursorInfo.bVisible = TRUE; - Buffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; + /* + * init guidata with default properties + */ + + wcscpy(GuiData->FontName, L"DejaVu Sans Mono"); + GuiData->FontSize = 0x0008000C; // font is 8x12 + GuiData->FontWeight = FW_NORMAL; + GuiData->HistoryNoDup = FALSE; + GuiData->FullScreen = FALSE; + GuiData->QuickEdit = FALSE; + GuiData->InsertMode = TRUE; + GuiData->HistoryBufferSize = 50; + GuiData->NumberOfHistoryBuffers = 5; + GuiData->ScreenText = RGB(192, 192, 192); + GuiData->ScreenBackground = RGB(0, 0, 0); + GuiData->PopupText = RGB(128, 0, 128); + GuiData->PopupBackground = RGB(255, 255, 255); + GuiData->WindowPosition = UINT_MAX; + GuiData->UseRasterFonts = TRUE; + memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors)); + + Console->Size.X = 80; + Console->Size.Y = 25; + + if (Buffer) + { + Buffer->MaxX = 80; + Buffer->MaxY = 300; + Buffer->CursorInfo.bVisible = TRUE; + Buffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; } } @@ -635,223 +633,233 @@ VOID FASTCALL GuiConsoleInitScrollbar(PCSRSS_CONSOLE Console, HWND hwnd) { - SCROLLINFO sInfo; - PGUI_CONSOLE_DATA GuiData = Console->PrivateData; - - DWORD Width = Console->Size.X * GuiData->CharWidth + 2 * GetSystemMetrics(SM_CXFIXEDFRAME); - DWORD Height = Console->Size.Y * GuiData->CharHeight + 2 * GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION); - - /* set scrollbar sizes */ - sInfo.cbSize = sizeof(SCROLLINFO); - sInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; - sInfo.nMin = 0; - if (Console->ActiveBuffer->MaxY > Console->Size.Y) - { - sInfo.nMax = Console->ActiveBuffer->MaxY - 1; - sInfo.nPage = Console->Size.Y; - sInfo.nPos = Console->ActiveBuffer->ShowY; - SetScrollInfo(hwnd, SB_VERT, &sInfo, TRUE); - Width += GetSystemMetrics(SM_CXVSCROLL); - ShowScrollBar(hwnd, SB_VERT, TRUE); - } - else - { - ShowScrollBar(hwnd, SB_VERT, FALSE); - } - - if (Console->ActiveBuffer->MaxX > Console->Size.X) - { - sInfo.nMax = Console->ActiveBuffer->MaxX - 1; - sInfo.nPage = Console->Size.X; - sInfo.nPos = Console->ActiveBuffer->ShowX; - SetScrollInfo(hwnd, SB_HORZ, &sInfo, TRUE); - Height += GetSystemMetrics(SM_CYHSCROLL); - ShowScrollBar(hwnd, SB_HORZ, TRUE); - } - else - { - ShowScrollBar(hwnd, SB_HORZ, FALSE); - } - - SetWindowPos(hwnd, NULL, 0, 0, Width, Height, - SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); + SCROLLINFO sInfo; + PGUI_CONSOLE_DATA GuiData = Console->PrivateData; + + DWORD Width = Console->Size.X * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); + DWORD Height = Console->Size.Y * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); + + /* set scrollbar sizes */ + sInfo.cbSize = sizeof(SCROLLINFO); + sInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + sInfo.nMin = 0; + if (Console->ActiveBuffer->MaxY > Console->Size.Y) + { + sInfo.nMax = Console->ActiveBuffer->MaxY - 1; + sInfo.nPage = Console->Size.Y; + sInfo.nPos = Console->ActiveBuffer->ShowY; + SetScrollInfo(hwnd, SB_VERT, &sInfo, TRUE); + Width += GetSystemMetrics(SM_CXVSCROLL); + ShowScrollBar(hwnd, SB_VERT, TRUE); + } + else + { + ShowScrollBar(hwnd, SB_VERT, FALSE); + } + + if (Console->ActiveBuffer->MaxX > Console->Size.X) + { + sInfo.nMax = Console->ActiveBuffer->MaxX - 1; + sInfo.nPage = Console->Size.X; + sInfo.nPos = Console->ActiveBuffer->ShowX; + SetScrollInfo(hwnd, SB_HORZ, &sInfo, TRUE); + Height += GetSystemMetrics(SM_CYHSCROLL); + ShowScrollBar(hwnd, SB_HORZ, TRUE); + + } + else + { + ShowScrollBar(hwnd, SB_HORZ, FALSE); + } + + SetWindowPos(hwnd, NULL, 0, 0, Width, Height, + SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); } -static BOOL FASTCALL +static BOOL GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create) { - PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Create->lpCreateParams; - PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->PrivateData; - HDC Dc; - HFONT OldFont; - TEXTMETRICW Metrics; - SIZE CharSize; - PCSRSS_PROCESS_DATA ProcessData; - HKEY hKey; + PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Create->lpCreateParams; + PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->PrivateData; + HDC Dc; + HFONT OldFont; + TEXTMETRICW Metrics; + SIZE CharSize; + PCSRSS_PROCESS_DATA ProcessData; + HKEY hKey; - Console->hWindow = hWnd; + Console->hWindow = hWnd; - if (NULL == GuiData) + if (NULL == GuiData) { - DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n"); - return FALSE; + DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n"); + return FALSE; } - GuiConsoleUseDefaults(Console, GuiData, Console->ActiveBuffer); - if (Console->ProcessList.Flink != &Console->ProcessList) + GuiConsoleUseDefaults(Console, GuiData, Console->ActiveBuffer); + if (Console->ProcessList.Flink != &Console->ProcessList) { - ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry); - if (GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ, FALSE)) + ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry); + if (GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ, FALSE)) { - GuiConsoleReadUserSettings(hKey, Console, GuiData, Console->ActiveBuffer); - RegCloseKey(hKey); + GuiConsoleReadUserSettings(hKey, Console, GuiData, Console->ActiveBuffer); + RegCloseKey(hKey); } } - InitializeCriticalSection(&GuiData->Lock); - - GuiData->LineBuffer = (PWCHAR)HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, - Console->Size.X * sizeof(WCHAR)); - - GuiData->Font = CreateFontW(LOWORD(GuiData->FontSize), - 0, //HIWORD(GuiData->FontSize), - 0, - TA_BASELINE, - GuiData->FontWeight, - FALSE, - FALSE, - FALSE, - OEM_CHARSET, - OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, - NONANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE, - GuiData->FontName); - if (NULL == GuiData->Font) - { - DPRINT1("GuiConsoleNcCreate: CreateFont failed\n"); - DeleteCriticalSection(&GuiData->Lock); - HeapFree(Win32CsrApiHeap, 0, GuiData); - return FALSE; - } - Dc = GetDC(hWnd); - if (NULL == Dc) - { - DPRINT1("GuiConsoleNcCreate: GetDC failed\n"); - DeleteObject(GuiData->Font); - DeleteCriticalSection(&GuiData->Lock); - HeapFree(Win32CsrApiHeap, 0, GuiData); - return FALSE; - } - OldFont = SelectObject(Dc, GuiData->Font); - if (NULL == OldFont) - { - DPRINT1("GuiConsoleNcCreate: SelectObject failed\n"); - ReleaseDC(hWnd, Dc); - DeleteObject(GuiData->Font); - DeleteCriticalSection(&GuiData->Lock); - HeapFree(Win32CsrApiHeap, 0, GuiData); - return FALSE; - } - if (! GetTextMetricsW(Dc, &Metrics)) - { - DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n"); - SelectObject(Dc, OldFont); - ReleaseDC(hWnd, Dc); - DeleteObject(GuiData->Font); - DeleteCriticalSection(&GuiData->Lock); - HeapFree(Win32CsrApiHeap, 0, GuiData); - return FALSE; - } - GuiData->CharWidth = Metrics.tmMaxCharWidth; - GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading; - - /* Measure real char width more precisely if possible. */ - if (GetTextExtentPoint32W(Dc, L"R", 1, &CharSize)) - GuiData->CharWidth = CharSize.cx; - - SelectObject(Dc, OldFont); - - ReleaseDC(hWnd, Dc); - GuiData->CursorBlinkOn = TRUE; - GuiData->ForceCursorOff = FALSE; - - GuiData->Selection.left = -1; - DPRINT("Console %p GuiData %p\n", Console, GuiData); - Console->PrivateData = GuiData; - SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console); - - SetTimer(hWnd, 1, CURSOR_BLINK_TIME, NULL); - GuiConsoleCreateSysMenu(Console); - GuiConsoleInitScrollbar(Console, hWnd); - SetEvent(GuiData->hGuiInitEvent); - - return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create); + InitializeCriticalSection(&GuiData->Lock); + + GuiData->Font = CreateFontW(LOWORD(GuiData->FontSize), + 0, //HIWORD(GuiData->FontSize), + 0, + TA_BASELINE, + GuiData->FontWeight, + FALSE, + FALSE, + FALSE, + OEM_CHARSET, + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + NONANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE, + GuiData->FontName); + if (NULL == GuiData->Font) + { + DPRINT1("GuiConsoleNcCreate: CreateFont failed\n"); + DeleteCriticalSection(&GuiData->Lock); + HeapFree(Win32CsrApiHeap, 0, GuiData); + return FALSE; + } + Dc = GetDC(hWnd); + if (NULL == Dc) + { + DPRINT1("GuiConsoleNcCreate: GetDC failed\n"); + DeleteObject(GuiData->Font); + DeleteCriticalSection(&GuiData->Lock); + HeapFree(Win32CsrApiHeap, 0, GuiData); + return FALSE; + } + OldFont = SelectObject(Dc, GuiData->Font); + if (NULL == OldFont) + { + DPRINT1("GuiConsoleNcCreate: SelectObject failed\n"); + ReleaseDC(hWnd, Dc); + DeleteObject(GuiData->Font); + DeleteCriticalSection(&GuiData->Lock); + HeapFree(Win32CsrApiHeap, 0, GuiData); + return FALSE; + } + if (! GetTextMetricsW(Dc, &Metrics)) + { + DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n"); + SelectObject(Dc, OldFont); + ReleaseDC(hWnd, Dc); + DeleteObject(GuiData->Font); + DeleteCriticalSection(&GuiData->Lock); + HeapFree(Win32CsrApiHeap, 0, GuiData); + return FALSE; + } + GuiData->CharWidth = Metrics.tmMaxCharWidth; + GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading; + + /* Measure real char width more precisely if possible. */ + if (GetTextExtentPoint32W(Dc, L"R", 1, &CharSize)) + GuiData->CharWidth = CharSize.cx; + + SelectObject(Dc, OldFont); + + ReleaseDC(hWnd, Dc); + GuiData->CursorBlinkOn = TRUE; + GuiData->ForceCursorOff = FALSE; + + DPRINT("Console %p GuiData %p\n", Console, GuiData); + Console->PrivateData = GuiData; + SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console); + + SetTimer(hWnd, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL); + GuiConsoleCreateSysMenu(Console); + + GuiData->WindowSizeLock = TRUE; + GuiConsoleInitScrollbar(Console, hWnd); + GuiData->WindowSizeLock = FALSE; + + SetEvent(GuiData->hGuiInitEvent); + + return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create); } -static VOID FASTCALL -GuiConsoleUpdateSelection(HWND hWnd, PRECT rc, PGUI_CONSOLE_DATA GuiData) +static VOID +SmallRectToRect(PCSRSS_CONSOLE Console, PRECT Rect, PSMALL_RECT SmallRect) { - RECT oldRect = GuiData->Selection; - - if(rc != NULL) - { - RECT changeRect = *rc; + PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer; + PGUI_CONSOLE_DATA GuiData = Console->PrivateData; + Rect->left = (SmallRect->Left - Buffer->ShowX) * GuiData->CharWidth; + Rect->top = (SmallRect->Top - Buffer->ShowY) * GuiData->CharHeight; + Rect->right = (SmallRect->Right + 1 - Buffer->ShowX) * GuiData->CharWidth; + Rect->bottom = (SmallRect->Bottom + 1 - Buffer->ShowY) * GuiData->CharHeight; +} - GuiData->Selection = *rc; +static VOID +GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord) +{ + RECT oldRect, newRect; + HWND hWnd = Console->hWindow; - changeRect.left *= GuiData->CharWidth; - changeRect.top *= GuiData->CharHeight; - changeRect.right *= GuiData->CharWidth; - changeRect.bottom *= GuiData->CharHeight; + SmallRectToRect(Console, &oldRect, &Console->Selection.srSelection); - if(rc->left != oldRect.left || - rc->top != oldRect.top || - rc->right != oldRect.right || - rc->bottom != oldRect.bottom) + if(coord != NULL) { - if(oldRect.left != -1) - { - HRGN rgn1, rgn2; + SMALL_RECT rc; + /* exchange left/top with right/bottom if required */ + rc.Left = min(Console->Selection.dwSelectionAnchor.X, coord->X); + rc.Top = min(Console->Selection.dwSelectionAnchor.Y, coord->Y); + rc.Right = max(Console->Selection.dwSelectionAnchor.X, coord->X); + rc.Bottom = max(Console->Selection.dwSelectionAnchor.Y, coord->Y); - oldRect.left *= GuiData->CharWidth; - oldRect.top *= GuiData->CharHeight; - oldRect.right *= GuiData->CharWidth; - oldRect.bottom *= GuiData->CharHeight; + SmallRectToRect(Console, &newRect, &rc); - /* calculate the region that needs to be updated */ - if((rgn1 = CreateRectRgnIndirect(&oldRect))) + if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) { - if((rgn2 = CreateRectRgnIndirect(&changeRect))) - { - if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR) + if (memcmp(&rc, &Console->Selection.srSelection, sizeof(SMALL_RECT)) != 0) { - InvalidateRgn(hWnd, rgn1, FALSE); - } + HRGN rgn1, rgn2; + + /* calculate the region that needs to be updated */ + if((rgn1 = CreateRectRgnIndirect(&oldRect))) + { + if((rgn2 = CreateRectRgnIndirect(&newRect))) + { + if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR) + { + InvalidateRgn(hWnd, rgn1, FALSE); + } - DeleteObject(rgn2); - } - DeleteObject(rgn1); + DeleteObject(rgn2); + } + DeleteObject(rgn1); + } + } + } + else + { + InvalidateRect(hWnd, &newRect, FALSE); + } + Console->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY; + Console->Selection.srSelection = rc; + ConioPause(Console, PAUSED_FROM_SELECTION); + } + else + { + /* clear the selection */ + if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) + { + InvalidateRect(hWnd, &oldRect, FALSE); } - } - else - { - InvalidateRect(hWnd, &changeRect, FALSE); - } - } - } - else if(oldRect.left != -1) - { - /* clear the selection */ - GuiData->Selection.left = -1; - oldRect.left *= GuiData->CharWidth; - oldRect.top *= GuiData->CharHeight; - oldRect.right *= GuiData->CharWidth; - oldRect.bottom *= GuiData->CharHeight; - InvalidateRect(hWnd, &oldRect, FALSE); - } + Console->Selection.dwFlags = CONSOLE_NO_SELECTION; + ConioUnpause(Console, PAUSED_FROM_SELECTION); + } } -static VOID FASTCALL +static VOID GuiConsolePaint(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, HDC hDC, @@ -869,7 +877,7 @@ GuiConsolePaint(PCSRSS_CONSOLE Console, Buff = Console->ActiveBuffer; - EnterCriticalSection(&Buff->Header.Lock); + EnterCriticalSection(&Buff->Header.Console->Lock); TopLine = rc->top / GuiData->CharHeight + Buff->ShowY; BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buff->ShowY; @@ -888,21 +896,22 @@ GuiConsolePaint(PCSRSS_CONSOLE Console, for (Line = TopLine; Line <= BottomLine; Line++) { + WCHAR LineBuffer[80]; From = ConioCoordToPointer(Buff, LeftChar, Line); Start = LeftChar; - To = GuiData->LineBuffer; + To = LineBuffer; for (Char = LeftChar; Char <= RightChar; Char++) { - if (*(From + 1) != LastAttribute) + if (*(From + 1) != LastAttribute || (Char - Start == sizeof(LineBuffer) / sizeof(WCHAR))) { TextOutW(hDC, (Start - Buff->ShowX) * GuiData->CharWidth, (Line - Buff->ShowY) * GuiData->CharHeight, - GuiData->LineBuffer, + LineBuffer, Char - Start); Start = Char; - To = GuiData->LineBuffer; + To = LineBuffer; Attribute = *(From + 1); if (Attribute != LastAttribute) { @@ -925,17 +934,17 @@ GuiConsolePaint(PCSRSS_CONSOLE Console, TextOutW(hDC, (Start - Buff->ShowX) * GuiData->CharWidth, (Line - Buff->ShowY) * GuiData->CharHeight, - GuiData->LineBuffer, + LineBuffer, RightChar - Start + 1); } if (Buff->CursorInfo.bVisible && GuiData->CursorBlinkOn && - !GuiData->ForceCursorOff) + !GuiData->ForceCursorOff) { CursorX = Buff->CurrentX; CursorY = Buff->CurrentY; if (LeftChar <= CursorX && CursorX <= RightChar && - TopLine <= CursorY && CursorY <= BottomLine) + TopLine <= CursorY && CursorY <= BottomLine) { CursorHeight = (GuiData->CharHeight * Buff->CursorInfo.dwSize) / 100; if (CursorHeight < 1) @@ -967,13 +976,13 @@ GuiConsolePaint(PCSRSS_CONSOLE Console, } } - LeaveCriticalSection(&Buff->Header.Lock); + LeaveCriticalSection(&Buff->Header.Console->Lock); SelectObject(hDC, OldFont); } -static VOID FASTCALL +static VOID GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint) { HDC hDC; @@ -983,14 +992,14 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint) hDC = BeginPaint(hWnd, &ps); if (hDC != NULL && - ps.rcPaint.left < ps.rcPaint.right && - ps.rcPaint.top < ps.rcPaint.bottom) + ps.rcPaint.left < ps.rcPaint.right && + ps.rcPaint.top < ps.rcPaint.bottom) { GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); if (Console != NULL && GuiData != NULL && - Console->ActiveBuffer != NULL) + Console->ActiveBuffer != NULL) { if (Console->ActiveBuffer->Buffer != NULL) { @@ -1001,14 +1010,10 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint) hDC, &ps.rcPaint); - if (GuiData->Selection.left != -1) + if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) { - RECT rc = GuiData->Selection; - - rc.left *= GuiData->CharWidth; - rc.top *= GuiData->CharHeight; - rc.right *= GuiData->CharWidth; - rc.bottom *= GuiData->CharHeight; + RECT rc; + SmallRectToRect(Console, &rc, &Console->Selection.srSelection); /* invert the selection */ if (IntersectRect(&rc, @@ -1032,172 +1037,120 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint) EndPaint(hWnd, &ps); } -static VOID FASTCALL +static VOID GuiConsoleHandleKey(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - MSG Message; - - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - Message.hwnd = hWnd; - Message.message = msg; - Message.wParam = wParam; - Message.lParam = lParam; - - if(msg == WM_CHAR || msg == WM_SYSKEYDOWN) - { - /* clear the selection */ - GuiConsoleUpdateSelection(hWnd, NULL, GuiData); - } - - ConioProcessKey(&Message, Console, FALSE); -} + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + MSG Message; -static VOID FASTCALL -GuiIntDrawRegion(PCSRSS_SCREEN_BUFFER Buff, PGUI_CONSOLE_DATA GuiData, HWND Wnd, RECT *Region) -{ - RECT RegionRect; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + Message.hwnd = hWnd; + Message.message = msg; + Message.wParam = wParam; + Message.lParam = lParam; - RegionRect.left = (Region->left - Buff->ShowX) * GuiData->CharWidth; - RegionRect.top = (Region->top - Buff->ShowY) * GuiData->CharHeight; - RegionRect.right = (Region->right + 1 - Buff->ShowX) * GuiData->CharWidth; - RegionRect.bottom = (Region->bottom + 1 - Buff->ShowY) * GuiData->CharHeight; + if(msg == WM_CHAR || msg == WM_SYSKEYDOWN) + { + /* clear the selection */ + GuiConsoleUpdateSelection(Console, NULL); + } - InvalidateRect(Wnd, &RegionRect, FALSE); + ConioProcessKey(&Message, Console, FALSE); } static VOID WINAPI -GuiDrawRegion(PCSRSS_CONSOLE Console, RECT *Region) +GuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region) { - PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData; - - if (NULL != Console->hWindow && NULL != GuiData) - { - GuiIntDrawRegion(Console->ActiveBuffer, GuiData, Console->hWindow, Region); - } + RECT RegionRect; + SmallRectToRect(Console, &RegionRect, Region); + InvalidateRect(Console->hWindow, &RegionRect, FALSE); } -static VOID FASTCALL -GuiInvalidateCell(PCSRSS_SCREEN_BUFFER Buff, PGUI_CONSOLE_DATA GuiData, HWND Wnd, UINT x, UINT y) +static VOID +GuiInvalidateCell(PCSRSS_CONSOLE Console, UINT x, UINT y) { - RECT CellRect; - - CellRect.left = x; - CellRect.top = y; - CellRect.right = x; - CellRect.bottom = y; - - GuiIntDrawRegion(Buff, GuiData, Wnd, &CellRect); + SMALL_RECT CellRect = { x, y, x, y }; + GuiDrawRegion(Console, &CellRect); } static VOID WINAPI -GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG CursorStartY, +GuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LONG CursorStartY, UINT ScrolledLines, CHAR *Buffer, UINT Length) { - PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData; - PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; - LONG CursorEndX, CursorEndY; - RECT ScrollRect; + PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData; + PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; + LONG CursorEndX, CursorEndY; + RECT ScrollRect; - if (NULL == Console->hWindow || NULL == GuiData) + if (NULL == Console->hWindow || NULL == GuiData) { - return; + return; } - if (0 != ScrolledLines) + if (0 != ScrolledLines) { - ScrollRect.left = 0; - ScrollRect.top = 0; - ScrollRect.right = Console->Size.X * GuiData->CharWidth; - ScrollRect.bottom = Region->top * GuiData->CharHeight; + ScrollRect.left = 0; + ScrollRect.top = 0; + ScrollRect.right = Console->Size.X * GuiData->CharWidth; + ScrollRect.bottom = Region->Top * GuiData->CharHeight; - if (GuiData->Selection.left != -1) - { - /* scroll the selection */ - if (GuiData->Selection.top > ScrolledLines) - { - GuiData->Selection.top -= ScrolledLines; - GuiData->Selection.bottom -= ScrolledLines; - } - else if (GuiData->Selection.bottom < ScrolledLines) - { - GuiData->Selection.left = -1; - } - else - { - GuiData->Selection.top = 0; - GuiData->Selection.bottom -= ScrolledLines; - } - } - - ScrollWindowEx(Console->hWindow, - 0, - -(ScrolledLines * GuiData->CharHeight), - &ScrollRect, - NULL, - NULL, - NULL, - SW_INVALIDATE); + ScrollWindowEx(Console->hWindow, + 0, + -(ScrolledLines * GuiData->CharHeight), + &ScrollRect, + NULL, + NULL, + NULL, + SW_INVALIDATE); } - GuiIntDrawRegion(Buff, GuiData, Console->hWindow, Region); + GuiDrawRegion(Console, Region); - if (CursorStartX < Region->left || Region->right < CursorStartX - || CursorStartY < Region->top || Region->bottom < CursorStartY) + if (CursorStartX < Region->Left || Region->Right < CursorStartX + || CursorStartY < Region->Top || Region->Bottom < CursorStartY) { - GuiInvalidateCell(Buff, GuiData, Console->hWindow, CursorStartX, CursorStartY); + GuiInvalidateCell(Console, CursorStartX, CursorStartY); } - CursorEndX = Buff->CurrentX; - CursorEndY = Buff->CurrentY; - if ((CursorEndX < Region->left || Region->right < CursorEndX - || CursorEndY < Region->top || Region->bottom < CursorEndY) - && (CursorEndX != CursorStartX || CursorEndY != CursorStartY)) + CursorEndX = Buff->CurrentX; + CursorEndY = Buff->CurrentY; + if ((CursorEndX < Region->Left || Region->Right < CursorEndX + || CursorEndY < Region->Top || Region->Bottom < CursorEndY) + && (CursorEndX != CursorStartX || CursorEndY != CursorStartY)) { - GuiInvalidateCell(Buff, GuiData, Console->hWindow, CursorEndX, CursorEndY); + GuiInvalidateCell(Console, CursorEndX, CursorEndY); } + + // 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; + SetTimer(Console->hWindow, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL); } static BOOL WINAPI GuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) { - RECT UpdateRect; - - if (Console->ActiveBuffer == Buff) + if (Console->ActiveBuffer == Buff) { - UpdateRect.left = Buff->CurrentX; - UpdateRect.top = Buff->CurrentY; - UpdateRect.right = UpdateRect.left; - UpdateRect.bottom = UpdateRect.top; - ConioDrawRegion(Console, &UpdateRect); + GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); } - return TRUE; + return TRUE; } static BOOL WINAPI GuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY) { - RECT UpdateRect; - - if (Console->ActiveBuffer == Buff) + if (Console->ActiveBuffer == Buff) { - /* Redraw char at old position (removes cursor) */ - UpdateRect.left = OldCursorX; - UpdateRect.top = OldCursorY; - UpdateRect.right = OldCursorX; - UpdateRect.bottom = OldCursorY; - ConioDrawRegion(Console, &UpdateRect); - /* Redraw char at new position (shows cursor) */ - UpdateRect.left = Buff->CurrentX; - UpdateRect.top = Buff->CurrentY; - UpdateRect.right = UpdateRect.left; - UpdateRect.bottom = UpdateRect.top; - ConioDrawRegion(Console, &UpdateRect); + /* Redraw char at old position (removes cursor) */ + GuiInvalidateCell(Console, OldCursorX, OldCursorY); + /* Redraw char at new position (shows cursor) */ + GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); } - return TRUE; + return TRUE; } static BOOL WINAPI @@ -1214,204 +1167,232 @@ GuiUpdateScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) return TRUE; } -static VOID FASTCALL +static VOID GuiConsoleHandleTimer(HWND hWnd) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - RECT CursorRect; - - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn; - - CursorRect.left = Console->ActiveBuffer->CurrentX; - CursorRect.top = Console->ActiveBuffer->CurrentY; - CursorRect.right = CursorRect.left; - CursorRect.bottom = CursorRect.top; - GuiDrawRegion(Console, &CursorRect); + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + PCSRSS_SCREEN_BUFFER Buff; + + SetTimer(hWnd, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL); + + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + + Buff = Console->ActiveBuffer; + GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); + GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn; + + if((GuiData->OldCursor.x != Buff->CurrentX) || (GuiData->OldCursor.y != Buff->CurrentY)) + { + SCROLLINFO xScroll; + int OldScrollX = -1, OldScrollY = -1; + int NewScrollX = -1, NewScrollY = -1; + + xScroll.cbSize = sizeof(SCROLLINFO); + xScroll.fMask = SIF_POS; + // Capture the original position of the scroll bars and save them. + if(GetScrollInfo(hWnd, SB_HORZ, &xScroll))OldScrollX = xScroll.nPos; + if(GetScrollInfo(hWnd, SB_VERT, &xScroll))OldScrollY = xScroll.nPos; + + // 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))) + { + // Handle the horizontal scroll bar + if(Buff->CurrentX >= Console->Size.X) NewScrollX = Buff->CurrentX - Console->Size.X + 1; + else NewScrollX = 0; + } + else + { + NewScrollX = OldScrollX; + } + } + // 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))) + { + // Handle the vertical scroll bar + if(Buff->CurrentY >= Console->Size.Y) NewScrollY = Buff->CurrentY - Console->Size.Y + 1; + else NewScrollY = 0; + } + else + { + NewScrollY = OldScrollY; + } + } + + // Adjust scroll bars and refresh the window if the cursor has moved outside the visible area + // NOTE: OldScroll# and NewScroll# will both be -1 (initial value) if the info for the respective scrollbar + // was not obtained successfully in the previous steps. This means their difference is 0 (no scrolling) + // and their associated scrollbar is left alone. + if((OldScrollX != NewScrollX) || (OldScrollY != NewScrollY)) + { + Buff->ShowX = NewScrollX; + Buff->ShowY = NewScrollY; + ScrollWindowEx(hWnd, + (OldScrollX - NewScrollX) * GuiData->CharWidth, + (OldScrollY - NewScrollY) * GuiData->CharHeight, + NULL, + NULL, + NULL, + NULL, + SW_INVALIDATE); + if(NewScrollX >= 0) + { + xScroll.nPos = NewScrollX; + SetScrollInfo(hWnd, SB_HORZ, &xScroll, TRUE); + } + if(NewScrollY >= 0) + { + xScroll.nPos = NewScrollY; + SetScrollInfo(hWnd, SB_VERT, &xScroll, TRUE); + } + UpdateWindow(hWnd); + GuiData->OldCursor.x = Buff->CurrentX; + GuiData->OldCursor.y = Buff->CurrentY; + } + } } -static VOID FASTCALL +static VOID GuiConsoleHandleClose(HWND hWnd) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - PLIST_ENTRY current_entry; - PCSRSS_PROCESS_DATA current; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + PLIST_ENTRY current_entry; + PCSRSS_PROCESS_DATA current; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - EnterCriticalSection(&Console->Header.Lock); + EnterCriticalSection(&Console->Lock); - current_entry = Console->ProcessList.Flink; - while (current_entry != &Console->ProcessList) + current_entry = Console->ProcessList.Flink; + while (current_entry != &Console->ProcessList) { - current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); - current_entry = current_entry->Flink; + current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); + current_entry = current_entry->Flink; - /* FIXME: Windows will wait up to 5 seconds for the thread to exit. - * We shouldn't wait here, though, since the console lock is entered. - * A copy of the thread list probably needs to be made. */ - ConioConsoleCtrlEvent(CTRL_CLOSE_EVENT, current); + /* FIXME: Windows will wait up to 5 seconds for the thread to exit. + * We shouldn't wait here, though, since the console lock is entered. + * A copy of the thread list probably needs to be made. */ + ConioConsoleCtrlEvent(CTRL_CLOSE_EVENT, current); } - LeaveCriticalSection(&Console->Header.Lock); + LeaveCriticalSection(&Console->Lock); } -static VOID FASTCALL +static VOID GuiConsoleHandleNcDestroy(HWND hWnd) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - KillTimer(hWnd, 1); - Console->PrivateData = NULL; - DeleteCriticalSection(&GuiData->Lock); - GetSystemMenu(hWnd, TRUE); - if (GuiData->ConsoleLibrary) - FreeLibrary(GuiData->ConsoleLibrary); + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + KillTimer(hWnd, 1); + Console->PrivateData = NULL; + DeleteCriticalSection(&GuiData->Lock); + GetSystemMenu(hWnd, TRUE); + if (GuiData->ConsoleLibrary) + FreeLibrary(GuiData->ConsoleLibrary); - HeapFree(Win32CsrApiHeap, 0, GuiData); + HeapFree(Win32CsrApiHeap, 0, GuiData); } -static VOID FASTCALL -GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam) +static COORD +PointToCoord(PCSRSS_CONSOLE Console, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - POINTS pt; - RECT rc; - - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL) return; + PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer; + PGUI_CONSOLE_DATA GuiData = Console->PrivateData; + COORD Coord; + Coord.X = Buffer->ShowX + ((short)LOWORD(lParam) / (int)GuiData->CharWidth); + 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; + return Coord; +} - pt = MAKEPOINTS(lParam); +static VOID +GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam) +{ + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; - rc.left = pt.x / GuiData->CharWidth; - rc.top = pt.y / GuiData->CharHeight; - rc.right = rc.left + 1; - rc.bottom = rc.top + 1; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) return; - GuiData->SelectionStart.x = rc.left; - GuiData->SelectionStart.y = rc.top; + Console->Selection.dwSelectionAnchor = PointToCoord(Console, lParam); - SetCapture(hWnd); + SetCapture(hWnd); - GuiData->MouseDown = TRUE; + Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS | CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN; - GuiConsoleUpdateSelection(hWnd, &rc, GuiData); + GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor); } -static VOID FASTCALL +static VOID GuiConsoleLeftMouseUp(HWND hWnd, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - RECT rc; - POINTS pt; - - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL) return; - if (GuiData->Selection.left == -1 || !GuiData->MouseDown) return; - - pt = MAKEPOINTS(lParam); - - rc.left = GuiData->SelectionStart.x; - rc.top = GuiData->SelectionStart.y; - rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0); - rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0); - - /* exchange left/top with right/bottom if required */ - if(rc.left >= rc.right) - { - LONG tmp; - tmp = rc.left; - rc.left = max(rc.right - 1, 0); - rc.right = tmp + 1; - } - if(rc.top >= rc.bottom) - { - LONG tmp; - tmp = rc.top; - rc.top = max(rc.bottom - 1, 0); - rc.bottom = tmp + 1; - } - - GuiData->MouseDown = FALSE; - - GuiConsoleUpdateSelection(hWnd, &rc, GuiData); - - ReleaseCapture(); + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + COORD c; + + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) return; + if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return; + + c = PointToCoord(Console, lParam); + + Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN; + + GuiConsoleUpdateSelection(Console, &c); + + ReleaseCapture(); } -static VOID FASTCALL +static VOID GuiConsoleMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - RECT rc; - POINTS pt; - - if (!(wParam & MK_LBUTTON)) return; - - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL || !GuiData->MouseDown) return; - - pt = MAKEPOINTS(lParam); - - rc.left = GuiData->SelectionStart.x; - rc.top = GuiData->SelectionStart.y; - rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0); - if (Console->Size.X < rc.right) - { - rc.right = Console->Size.X; - } - rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0); - if (Console->Size.Y < rc.bottom) - { - rc.bottom = Console->Size.Y; - } - - /* exchange left/top with right/bottom if required */ - if(rc.left >= rc.right) - { - LONG tmp; - tmp = rc.left; - rc.left = max(rc.right - 1, 0); - rc.right = tmp + 1; - } - if(rc.top >= rc.bottom) - { - LONG tmp; - tmp = rc.top; - rc.top = max(rc.bottom - 1, 0); - rc.bottom = tmp + 1; - } - - GuiConsoleUpdateSelection(hWnd, &rc, GuiData); + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + COORD c; + + if (!(wParam & MK_LBUTTON)) return; + + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) return; + if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return; + + c = PointToCoord(Console, lParam); /* TODO: Scroll buffer to bring c into view */ + + GuiConsoleUpdateSelection(Console, &c); } -static VOID FASTCALL +static VOID GuiConsoleRightMouseDown(HWND hWnd) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL) return; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) return; - if (GuiData->Selection.left == -1) - { - /* FIXME - paste text from clipboard */ - } - else - { - /* FIXME - copy selection to clipboard */ + if (!(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)) + { + /* FIXME - paste text from clipboard */ + } + else + { + /* FIXME - copy selection to clipboard */ - GuiConsoleUpdateSelection(hWnd, NULL, GuiData); - } + GuiConsoleUpdateSelection(Console, NULL); + } } @@ -1419,517 +1400,606 @@ GuiConsoleRightMouseDown(HWND hWnd) static VOID GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiData) { - PCSRSS_CONSOLE Console; - APPLET_PROC CPLFunc; - TCHAR szBuffer[MAX_PATH]; - ConsoleInfo SharedInfo; + PCSRSS_CONSOLE Console; + APPLET_PROC CPLFunc; + TCHAR szBuffer[MAX_PATH]; + ConsoleInfo SharedInfo; - DPRINT("GuiConsoleShowConsoleProperties entered\n"); + DPRINT("GuiConsoleShowConsoleProperties entered\n"); - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (GuiData == NULL) + if (GuiData == NULL) { - DPRINT("GuiConsoleGetDataPointers failed\n"); - return; + DPRINT("GuiConsoleGetDataPointers failed\n"); + return; } - if (GuiData->ConsoleLibrary == NULL) + if (GuiData->ConsoleLibrary == NULL) { - GetWindowsDirectory(szBuffer,MAX_PATH); - _tcscat(szBuffer, _T("\\system32\\console.dll")); - GuiData->ConsoleLibrary = LoadLibrary(szBuffer); + GetWindowsDirectory(szBuffer,MAX_PATH); + _tcscat(szBuffer, _T("\\system32\\console.dll")); + GuiData->ConsoleLibrary = LoadLibrary(szBuffer); - if (GuiData->ConsoleLibrary == NULL) + if (GuiData->ConsoleLibrary == NULL) { - DPRINT1("failed to load console.dll"); - return; + DPRINT1("failed to load console.dll"); + return; } } - CPLFunc = (APPLET_PROC) GetProcAddress(GuiData->ConsoleLibrary, _T("CPlApplet")); - if (!CPLFunc) + CPLFunc = (APPLET_PROC) GetProcAddress(GuiData->ConsoleLibrary, _T("CPlApplet")); + if (!CPLFunc) { - DPRINT("Error: Console.dll misses CPlApplet export\n"); - return; + DPRINT("Error: Console.dll misses CPlApplet export\n"); + return; } - /* setup struct */ - SharedInfo.InsertMode = GuiData->InsertMode; - SharedInfo.HistoryBufferSize = GuiData->HistoryBufferSize; - SharedInfo.NumberOfHistoryBuffers = GuiData->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 = GuiData->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; + /* setup struct */ + SharedInfo.InsertMode = GuiData->InsertMode; + SharedInfo.HistoryBufferSize = GuiData->HistoryBufferSize; + SharedInfo.NumberOfHistoryBuffers = GuiData->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 = GuiData->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) + if (CPLFunc(hWnd, CPL_GETCOUNT, 0, 0) != 1) { - DPRINT("Error: console.dll returned unexpected CPL count\n"); - return; + DPRINT("Error: console.dll returned unexpected CPL count\n"); + return; } - CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults); + CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults); } -static LRESULT FASTCALL +static LRESULT GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam, PGUI_CONSOLE_DATA GuiData) { LRESULT Ret = TRUE; switch(wParam) { - case ID_SYSTEM_EDIT_MARK: - case ID_SYSTEM_EDIT_COPY: - case ID_SYSTEM_EDIT_PASTE: - case ID_SYSTEM_EDIT_SELECTALL: - case ID_SYSTEM_EDIT_SCROLL: - case ID_SYSTEM_EDIT_FIND: - break; + case ID_SYSTEM_EDIT_MARK: + case ID_SYSTEM_EDIT_COPY: + case ID_SYSTEM_EDIT_PASTE: + case ID_SYSTEM_EDIT_SELECTALL: + case ID_SYSTEM_EDIT_SCROLL: + case ID_SYSTEM_EDIT_FIND: + break; - case ID_SYSTEM_DEFAULTS: - GuiConsoleShowConsoleProperties(hWnd, TRUE, GuiData); - break; + case ID_SYSTEM_DEFAULTS: + GuiConsoleShowConsoleProperties(hWnd, TRUE, GuiData); + break; - case ID_SYSTEM_PROPERTIES: - GuiConsoleShowConsoleProperties(hWnd, FALSE, GuiData); - break; + case ID_SYSTEM_PROPERTIES: + GuiConsoleShowConsoleProperties(hWnd, FALSE, GuiData); + break; - default: - Ret = DefWindowProcW(hWnd, WM_SYSCOMMAND, wParam, lParam); - break; + default: + Ret = DefWindowProcW(hWnd, WM_SYSCOMMAND, wParam, lParam); + break; } return Ret; } -static VOID FASTCALL +static VOID +GuiConsoleGetMinMaxInfo(HWND hWnd, PMINMAXINFO minMaxInfo) +{ + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if((Console == NULL)|| (GuiData == NULL)) return; + + DWORD windx = CONGUI_MIN_WIDTH * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); + DWORD windy = CONGUI_MIN_HEIGHT * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); + + 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); + + 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 + + minMaxInfo->ptMaxTrackSize.x = windx; + minMaxInfo->ptMaxTrackSize.y = windy; +} +static VOID GuiConsoleResize(HWND hWnd, WPARAM wParam, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED) - { - DPRINT1("GuiConsoleResize X %d Y %d\n", LOWORD(lParam), HIWORD(lParam)); - } + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if((Console == NULL) || (GuiData == NULL)) return; + + if ((GuiData->WindowSizeLock == FALSE) && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED)) + { + PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; + + GuiData->WindowSizeLock = TRUE; + + DWORD windx = LOWORD(lParam); + DWORD 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 + + DWORD charx = windx / GuiData->CharWidth; + DWORD chary = windy / GuiData->CharHeight; + + // Character alignment (round size up or down) + if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx; + 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 + + charx = windx / GuiData->CharWidth; + chary = windy / GuiData->CharHeight; + + // Character alignment (round size up or down) + if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx; + if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary; + + // 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; + } + + 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; + InvalidateRect(hWnd, NULL, TRUE); + + GuiData->WindowSizeLock = FALSE; + } } + VOID FASTCALL GuiConsoleHandleScrollbarMenu() { - HMENU hMenu; + HMENU hMenu; - hMenu = CreatePopupMenu(); - if (hMenu == NULL) + hMenu = CreatePopupMenu(); + if (hMenu == NULL) { - DPRINT("CreatePopupMenu failed\n"); - return; + DPRINT("CreatePopupMenu failed\n"); + return; } - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE); - //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM); - //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN); - //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE); + //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM); + //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN); + //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN); } -static VOID FASTCALL -GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsoleInfo pConInfo) +static NTSTATUS WINAPI +GuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD Size) { - DWORD windx, windy; - PCSRSS_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer; - BOOL SizeChanged = FALSE; - - EnterCriticalSection(&ActiveBuffer->Header.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->ScreenBuffer); - windy = HIWORD(pConInfo->ScreenBuffer); + BYTE * Buffer; + DWORD Offset = 0; + BYTE * OldPtr; + USHORT CurrentY; + BYTE * OldBuffer; +#if HAVE_WMEMSET + USHORT value = MAKEWORD(' ', ScreenBuffer->DefaultAttrib); +#endif + DWORD diff; + DWORD i; - if (windx != ActiveBuffer->MaxX || windy != ActiveBuffer->MaxY) - { - BYTE * Buffer = HeapAlloc(Win32CsrApiHeap, 0, windx * windy * 2); + /* Buffer size is not allowed to be smaller than window size */ + if (Size.X < Console->Size.X || Size.Y < Console->Size.Y) + return STATUS_INVALID_PARAMETER; - if (Buffer) - { - DWORD Offset = 0; - BYTE * OldPtr; - USHORT CurrentY; - BYTE * OldBuffer; - USHORT value; - DWORD diff; - DWORD i; + if (Size.X == ScreenBuffer->MaxX && Size.Y == ScreenBuffer->MaxY) + return STATUS_SUCCESS; - value = MAKEWORD(' ', ActiveBuffer->DefaultAttrib); + Buffer = HeapAlloc(Win32CsrApiHeap, 0, Size.X * Size.Y * 2); + if (!Buffer) + return STATUS_NO_MEMORY; - DPRINT("MaxX %d MaxY %d windx %d windy %d value %04x DefaultAttrib %d\n",ActiveBuffer->MaxX, ActiveBuffer->MaxY, windx, windy, value, ActiveBuffer->DefaultAttrib); - OldBuffer = ActiveBuffer->Buffer; + DPRINT1("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->MaxX, ScreenBuffer->MaxY, Size.X, Size.Y); + OldBuffer = ScreenBuffer->Buffer; - for (CurrentY = 0; CurrentY < min(ActiveBuffer->MaxY, windy); CurrentY++) + for (CurrentY = 0; CurrentY < ScreenBuffer->MaxY && CurrentY < Size.Y; CurrentY++) + { + OldPtr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY); + if (Size.X <= ScreenBuffer->MaxX) { - OldPtr = ConioCoordToPointer(ActiveBuffer, 0, CurrentY); - if (windx <= ActiveBuffer->MaxX) - { - /* reduce size */ - RtlCopyMemory(&Buffer[Offset], OldPtr, windx * 2); - Offset += (windx * 2); - } - else - { - /* enlarge size */ - RtlCopyMemory(&Buffer[Offset], OldPtr, ActiveBuffer->MaxX * 2); - Offset += (ActiveBuffer->MaxX * 2); + /* reduce size */ + RtlCopyMemory(&Buffer[Offset], OldPtr, Size.X * 2); + Offset += (Size.X * 2); + } + else + { + /* enlarge size */ + RtlCopyMemory(&Buffer[Offset], OldPtr, ScreenBuffer->MaxX * 2); + Offset += (ScreenBuffer->MaxX * 2); - diff = windx - ActiveBuffer->MaxX; - /* zero new part of it */ + diff = Size.X - ScreenBuffer->MaxX; + /* zero new part of it */ #if HAVE_WMEMSET - wmemset((WCHAR*)&Buffer[Offset], value, diff); + wmemset((WCHAR*)&Buffer[Offset], value, diff); #else - for (i = 0; i < diff; i++) - { - Buffer[Offset++] = ' '; - Buffer[Offset++] = ActiveBuffer->DefaultAttrib; - } -#endif + for (i = 0; i < diff; i++) + { + Buffer[Offset++] = ' '; + Buffer[Offset++] = ScreenBuffer->DefaultAttrib; } +#endif } + } - if (windy > ActiveBuffer->MaxY) - { - diff = windy - ActiveBuffer->MaxY; + if (Size.Y > ScreenBuffer->MaxY) + { + diff = Size.X * (Size.Y - ScreenBuffer->MaxY); #if HAVE_WMEMSET - wmemset((WCHAR*)&Buffer[Offset], value, diff * windx); + wmemset((WCHAR*)&Buffer[Offset], value, diff); #else - for (i = 0; i < diff * windx; i++) - { - Buffer[Offset++] = ' '; - Buffer[Offset++] = ActiveBuffer->DefaultAttrib; - } -#endif + for (i = 0; i < diff; i++) + { + Buffer[Offset++] = ' '; + Buffer[Offset++] = ScreenBuffer->DefaultAttrib; } +#endif + } + + (void)InterlockedExchangePointer((PVOID volatile *)&ScreenBuffer->Buffer, Buffer); + HeapFree(Win32CsrApiHeap, 0, OldBuffer); + ScreenBuffer->MaxX = Size.X; + ScreenBuffer->MaxY = Size.Y; + 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->ShowX > Size.X - Console->Size.X) + ScreenBuffer->ShowX = Size.X - Console->Size.X; + if (ScreenBuffer->ShowY > Size.Y - Console->Size.Y) + ScreenBuffer->ShowY = Size.Y - Console->Size.Y; + + /* TODO: Should update scrollbar, but can't use anything that + * calls SendMessage or it could cause deadlock */ + + return STATUS_SUCCESS; +} + +static VOID +GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsoleInfo pConInfo) +{ + DWORD windx, windy; + PCSRSS_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer; + COORD BufSize; + BOOL SizeChanged = FALSE; + + 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); - (void)InterlockedExchangePointer((PVOID volatile *)&ActiveBuffer->Buffer, Buffer); - HeapFree(Win32CsrApiHeap, 0, OldBuffer); - ActiveBuffer->MaxX = windx; - ActiveBuffer->MaxY = windy; - ActiveBuffer->VirtualY = 0; + if (windx != Console->Size.X || windy != Console->Size.Y) + { + /* resize window */ + Console->Size.X = windx; + Console->Size.Y = windy; SizeChanged = TRUE; - } - else - { - LeaveCriticalSection(&ActiveBuffer->Header.Lock); - return; - } - } - - windx = LOWORD(pConInfo->WindowSize); - windy = HIWORD(pConInfo->WindowSize); - - if (windx > Console->Size.X) - { - PWCHAR LineBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, windx * sizeof(WCHAR)); - if (LineBuffer) - { - HeapFree(Win32CsrApiHeap, 0, GuiData->LineBuffer); - GuiData->LineBuffer = LineBuffer; - } - else - { - LeaveCriticalSection(&ActiveBuffer->Header.Lock); - return; - } - } - - - if (windx != Console->Size.X || windy != Console->Size.Y) - { - /* resize window */ - Console->Size.X = windx; - Console->Size.Y = windy; - SizeChanged = TRUE; - } - - if (SizeChanged) - { - GuiConsoleInitScrollbar(Console, pConInfo->hConsoleWindow); - } - - LeaveCriticalSection(&ActiveBuffer->Header.Lock); - InvalidateRect(pConInfo->hConsoleWindow, NULL, 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; + } + + LeaveCriticalSection(&Console->Lock); + InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE); } static LRESULT GuiConsoleHandleScroll(HWND hwnd, UINT uMsg, WPARAM wParam) { - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - PGUI_CONSOLE_DATA GuiData; - SCROLLINFO sInfo; - int fnBar; - int old_pos, Maximum; - PUSHORT pShowXY; - - GuiConsoleGetDataPointers(hwnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL) - return FALSE; - Buff = Console->ActiveBuffer; - - if (uMsg == WM_HSCROLL) - { - fnBar = SB_HORZ; - Maximum = Buff->MaxX - Console->Size.X; - pShowXY = &Buff->ShowX; - } - else - { - fnBar = SB_VERT; - Maximum = Buff->MaxY - Console->Size.Y; - pShowXY = &Buff->ShowY; - } - - /* set scrollbar sizes */ - sInfo.cbSize = sizeof(SCROLLINFO); - sInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS; - - if (!GetScrollInfo(hwnd, fnBar, &sInfo)) - { - return FALSE; - } - - old_pos = sInfo.nPos; - - switch(LOWORD(wParam)) - { - case SB_LINELEFT: - sInfo.nPos -= 1; - break; - - case SB_LINERIGHT: - sInfo.nPos += 1; - break; - - case SB_PAGELEFT: - sInfo.nPos -= sInfo.nPage; - break; - - case SB_PAGERIGHT: - sInfo.nPos += sInfo.nPage; - break; - - case SB_THUMBTRACK: - sInfo.nPos = sInfo.nTrackPos; - break; - - case SB_TOP: - sInfo.nPos = sInfo.nMin; - break; - - case SB_BOTTOM: - sInfo.nPos = sInfo.nMax; - break; - - default: - break; - } - - sInfo.nPos = max(sInfo.nPos, 0); - sInfo.nPos = min(sInfo.nPos, Maximum); - - if (old_pos != sInfo.nPos) - { - USHORT OldX = Buff->ShowX; - USHORT OldY = Buff->ShowY; - *pShowXY = sInfo.nPos; - - ScrollWindowEx(hwnd, - (OldX - Buff->ShowX) * GuiData->CharWidth, - (OldY - Buff->ShowY) * GuiData->CharHeight, - NULL, - NULL, - NULL, - NULL, - SW_INVALIDATE); - - sInfo.fMask = SIF_POS; - SetScrollInfo(hwnd, fnBar, &sInfo, TRUE); - - UpdateWindow(hwnd); - } - return 0; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + PGUI_CONSOLE_DATA GuiData; + SCROLLINFO sInfo; + int fnBar; + int old_pos, Maximum; + PUSHORT pShowXY; + + GuiConsoleGetDataPointers(hwnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) + return FALSE; + Buff = Console->ActiveBuffer; + + if (uMsg == WM_HSCROLL) + { + fnBar = SB_HORZ; + Maximum = Buff->MaxX - Console->Size.X; + pShowXY = &Buff->ShowX; + } + else + { + fnBar = SB_VERT; + Maximum = Buff->MaxY - Console->Size.Y; + pShowXY = &Buff->ShowY; + } + + /* set scrollbar sizes */ + sInfo.cbSize = sizeof(SCROLLINFO); + sInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS; + + if (!GetScrollInfo(hwnd, fnBar, &sInfo)) + { + return FALSE; + } + + old_pos = sInfo.nPos; + + switch(LOWORD(wParam)) + { + case SB_LINELEFT: + sInfo.nPos -= 1; + break; + + case SB_LINERIGHT: + sInfo.nPos += 1; + break; + + case SB_PAGELEFT: + sInfo.nPos -= sInfo.nPage; + break; + + case SB_PAGERIGHT: + sInfo.nPos += sInfo.nPage; + break; + + case SB_THUMBTRACK: + sInfo.nPos = sInfo.nTrackPos; + ConioPause(Console, PAUSED_FROM_SCROLLBAR); + break; + + case SB_THUMBPOSITION: + ConioUnpause(Console, PAUSED_FROM_SCROLLBAR); + break; + + case SB_TOP: + sInfo.nPos = sInfo.nMin; + break; + + case SB_BOTTOM: + sInfo.nPos = sInfo.nMax; + break; + + default: + break; + } + + sInfo.nPos = max(sInfo.nPos, 0); + sInfo.nPos = min(sInfo.nPos, Maximum); + + if (old_pos != sInfo.nPos) + { + USHORT OldX = Buff->ShowX; + USHORT OldY = Buff->ShowY; + *pShowXY = sInfo.nPos; + + ScrollWindowEx(hwnd, + (OldX - Buff->ShowX) * GuiData->CharWidth, + (OldY - Buff->ShowY) * GuiData->CharHeight, + NULL, + NULL, + NULL, + NULL, + SW_INVALIDATE); + + sInfo.fMask = SIF_POS; + SetScrollInfo(hwnd, fnBar, &sInfo, TRUE); + + UpdateWindow(hwnd); + } + return 0; } static LRESULT CALLBACK GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - LRESULT Result = 0; - PGUI_CONSOLE_DATA GuiData = NULL; - PCSRSS_CONSOLE Console = NULL; + LRESULT Result = 0; + PGUI_CONSOLE_DATA GuiData = NULL; + PCSRSS_CONSOLE Console = NULL; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - switch(msg) + switch(msg) { - case WM_NCCREATE: + case WM_NCCREATE: Result = (LRESULT) GuiConsoleHandleNcCreate(hWnd, (CREATESTRUCTW *) lParam); break; - case WM_PAINT: + case WM_PAINT: GuiConsoleHandlePaint(hWnd, (HDC)wParam); break; - case WM_KEYDOWN: - case WM_KEYUP: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - case WM_CHAR: + case WM_KEYDOWN: + case WM_KEYUP: + case WM_SYSKEYDOWN: + case WM_SYSKEYUP: + case WM_CHAR: GuiConsoleHandleKey(hWnd, msg, wParam, lParam); break; - case WM_TIMER: + case WM_TIMER: GuiConsoleHandleTimer(hWnd); break; - case WM_CLOSE: + case WM_CLOSE: GuiConsoleHandleClose(hWnd); break; - case WM_NCDESTROY: + case WM_NCDESTROY: GuiConsoleHandleNcDestroy(hWnd); break; - case WM_LBUTTONDOWN: - GuiConsoleLeftMouseDown(hWnd, lParam); + case WM_LBUTTONDOWN: + GuiConsoleLeftMouseDown(hWnd, lParam); break; - case WM_LBUTTONUP: - GuiConsoleLeftMouseUp(hWnd, lParam); + case WM_LBUTTONUP: + GuiConsoleLeftMouseUp(hWnd, lParam); break; - case WM_RBUTTONDOWN: - GuiConsoleRightMouseDown(hWnd); + case WM_RBUTTONDOWN: + GuiConsoleRightMouseDown(hWnd); break; - case WM_MOUSEMOVE: - GuiConsoleMouseMove(hWnd, wParam, lParam); + case WM_MOUSEMOVE: + GuiConsoleMouseMove(hWnd, wParam, lParam); break; - case WM_SYSCOMMAND: - Result = GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam, GuiData); - break; - case WM_HSCROLL: - case WM_VSCROLL: - Result = GuiConsoleHandleScroll(hWnd, msg, wParam); - break; - case WM_SIZE: - GuiConsoleResize(hWnd, wParam, lParam); - break; - case PM_APPLY_CONSOLE_INFO: - GuiApplyUserSettings(Console, GuiData, (PConsoleInfo)wParam); - if (lParam) - { - GuiConsoleWriteUserSettings(Console, GuiData); - } - break; - default: + case WM_SYSCOMMAND: + Result = GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam, GuiData); + break; + case WM_HSCROLL: + case WM_VSCROLL: + Result = GuiConsoleHandleScroll(hWnd, msg, wParam); + break; + case WM_GETMINMAXINFO: + GuiConsoleGetMinMaxInfo(hWnd, (PMINMAXINFO)lParam); + break; + case WM_SIZE: + GuiConsoleResize(hWnd, wParam, lParam); + break; + case PM_APPLY_CONSOLE_INFO: + GuiApplyUserSettings(Console, GuiData, (PConsoleInfo)wParam); + if (lParam) + { + GuiConsoleWriteUserSettings(Console, GuiData); + } + break; + default: Result = DefWindowProcW(hWnd, msg, wParam, lParam); break; } - return Result; + return Result; } static LRESULT CALLBACK GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - HWND NewWindow; - LONG WindowCount; - MSG Msg; - PWCHAR Buffer, Title; - PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam; + HWND NewWindow; + LONG WindowCount; + MSG Msg; + PWCHAR Buffer, Title; + PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam; - switch(msg) + switch(msg) { - case WM_CREATE: + case WM_CREATE: SetWindowLongW(hWnd, GWL_USERDATA, 0); return 0; - case PM_CREATE_CONSOLE: + case PM_CREATE_CONSOLE: Buffer = HeapAlloc(Win32CsrApiHeap, 0, Console->Title.Length + sizeof(WCHAR)); if (NULL != Buffer) - { + { memcpy(Buffer, Console->Title.Buffer, Console->Title.Length); Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0'; Title = Buffer; - } + } else - { + { Title = L""; - } - NewWindow = CreateWindowW(L"ConsoleWindowClass", - Title, - WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_HSCROLL | WS_VSCROLL, //WS_OVERLAPPEDWINDOW - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - NULL, - NULL, - (HINSTANCE) GetModuleHandleW(NULL), - (PVOID) Console); + } + NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE, + L"ConsoleWindowClass", + Title, + WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + NULL, + NULL, + (HINSTANCE) GetModuleHandleW(NULL), + (PVOID) Console); if (NULL != Buffer) - { + { HeapFree(Win32CsrApiHeap, 0, Buffer); - } + } if (NULL != NewWindow) - { + { SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1); - ShowWindow(NewWindow, SW_SHOW); - } + if (wParam) + { + ShowWindow(NewWindow, SW_SHOW); + } + } return (LRESULT) NewWindow; - case PM_DESTROY_CONSOLE: + case PM_DESTROY_CONSOLE: /* Window creation is done using a PostMessage(), so it's possible that the * window that we want to destroy doesn't exist yet. So first empty the message * queue */ while(PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE)) - { + { TranslateMessage(&Msg); DispatchMessageW(&Msg); - } + } DestroyWindow(Console->hWindow); Console->hWindow = NULL; WindowCount = GetWindowLongW(hWnd, GWL_USERDATA); WindowCount--; SetWindowLongW(hWnd, GWL_USERDATA, WindowCount); if (0 == WindowCount) - { + { NotifyWnd = NULL; DestroyWindow(hWnd); PrivateCsrssManualGuiCheck(-1); PostQuitMessage(0); - } + } return 0; - default: + default: return DefWindowProcW(hWnd, msg, wParam, lParam); } } @@ -1937,208 +2007,209 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) static DWORD WINAPI GuiConsoleGuiThread(PVOID Data) { - MSG msg; - PHANDLE GraphicsStartupEvent = (PHANDLE) Data; + MSG msg; + PHANDLE GraphicsStartupEvent = (PHANDLE) Data; - NotifyWnd = CreateWindowW(L"Win32CsrCreateNotify", - L"", - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - NULL, - NULL, - (HINSTANCE) GetModuleHandleW(NULL), - NULL); - if (NULL == NotifyWnd) + NotifyWnd = CreateWindowW(L"Win32CsrCreateNotify", + L"", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + NULL, + NULL, + (HINSTANCE) GetModuleHandleW(NULL), + NULL); + if (NULL == NotifyWnd) { - PrivateCsrssManualGuiCheck(-1); - SetEvent(*GraphicsStartupEvent); - return 1; + PrivateCsrssManualGuiCheck(-1); + SetEvent(*GraphicsStartupEvent); + return 1; } - SetEvent(*GraphicsStartupEvent); + SetEvent(*GraphicsStartupEvent); - while(GetMessageW(&msg, NULL, 0, 0)) + while(GetMessageW(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessageW(&msg); + TranslateMessage(&msg); + DispatchMessageW(&msg); } - return 1; + return 1; } -static BOOL FASTCALL +static BOOL GuiInit(VOID) { - WNDCLASSEXW wc; - - if (NULL == NotifyWnd) - { - PrivateCsrssManualGuiCheck(+1); - } - - wc.cbSize = sizeof(WNDCLASSEXW); - wc.lpszClassName = L"Win32CsrCreateNotify"; - wc.lpfnWndProc = GuiConsoleNotifyWndProc; - wc.style = 0; - wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); - wc.hIcon = NULL; - wc.hCursor = NULL; - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hIconSm = NULL; - if (RegisterClassExW(&wc) == 0) - { - DPRINT1("Failed to register notify wndproc\n"); - return FALSE; - } - - wc.cbSize = sizeof(WNDCLASSEXW); - wc.lpszClassName = L"ConsoleWindowClass"; - wc.lpfnWndProc = GuiConsoleWndProc; - wc.style = 0; - wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); - wc.hIcon = LoadIconW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1)); - wc.hCursor = LoadCursorW(NULL, (LPCWSTR) IDC_ARROW); - wc.hbrBackground = CreateSolidBrush(RGB(0,0,0)); - wc.lpszMenuName = NULL; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hIconSm = LoadImageW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1), IMAGE_ICON, - GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), - LR_SHARED); - if (RegisterClassExW(&wc) == 0) - { - DPRINT1("Failed to register console wndproc\n"); - return FALSE; - } - - return TRUE; + WNDCLASSEXW wc; + + if (NULL == NotifyWnd) + { + PrivateCsrssManualGuiCheck(+1); + } + + wc.cbSize = sizeof(WNDCLASSEXW); + wc.lpszClassName = L"Win32CsrCreateNotify"; + wc.lpfnWndProc = GuiConsoleNotifyWndProc; + wc.style = 0; + wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hIconSm = NULL; + if (RegisterClassExW(&wc) == 0) + { + DPRINT1("Failed to register notify wndproc\n"); + return FALSE; + } + + wc.cbSize = sizeof(WNDCLASSEXW); + wc.lpszClassName = L"ConsoleWindowClass"; + wc.lpfnWndProc = GuiConsoleWndProc; + wc.style = 0; + wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); + wc.hIcon = LoadIconW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1)); + wc.hCursor = LoadCursorW(NULL, (LPCWSTR) IDC_ARROW); + wc.hbrBackground = CreateSolidBrush(RGB(0,0,0)); + wc.lpszMenuName = NULL; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hIconSm = LoadImageW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1), IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), + LR_SHARED); + if (RegisterClassExW(&wc) == 0) + { + DPRINT1("Failed to register console wndproc\n"); + return FALSE; + } + + return TRUE; } static VOID WINAPI GuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer) { - Buffer->DefaultAttrib = DEFAULT_ATTRIB; + Buffer->DefaultAttrib = DEFAULT_ATTRIB; } static BOOL WINAPI GuiChangeTitle(PCSRSS_CONSOLE Console) { - PWCHAR Buffer, Title; + PWCHAR Buffer, Title; - Buffer = HeapAlloc(Win32CsrApiHeap, 0, - Console->Title.Length + sizeof(WCHAR)); - if (NULL != Buffer) + Buffer = HeapAlloc(Win32CsrApiHeap, 0, + Console->Title.Length + sizeof(WCHAR)); + if (NULL != Buffer) { - memcpy(Buffer, Console->Title.Buffer, Console->Title.Length); - Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0'; - Title = Buffer; + memcpy(Buffer, Console->Title.Buffer, Console->Title.Length); + Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0'; + Title = Buffer; } - else + else { - Title = L""; + Title = L""; } - SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Title); + SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Title); - if (NULL != Buffer) + if (NULL != Buffer) { - HeapFree(Win32CsrApiHeap, 0, Buffer); + HeapFree(Win32CsrApiHeap, 0, Buffer); } - return TRUE; + return TRUE; } static BOOL WINAPI GuiChangeIcon(PCSRSS_CONSOLE Console, HICON hWindowIcon) { - SendMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)hWindowIcon); - SendMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)hWindowIcon); + SendMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)hWindowIcon); + SendMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)hWindowIcon); - return TRUE; + return TRUE; } static VOID WINAPI GuiCleanupConsole(PCSRSS_CONSOLE Console) { - SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console); + SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console); } static CSRSS_CONSOLE_VTBL GuiVtbl = { - GuiInitScreenBuffer, - GuiWriteStream, - GuiDrawRegion, - GuiSetCursorInfo, - GuiSetScreenInfo, - GuiUpdateScreenInfo, - GuiChangeTitle, - GuiCleanupConsole, - GuiChangeIcon + GuiInitScreenBuffer, + GuiWriteStream, + GuiDrawRegion, + GuiSetCursorInfo, + GuiSetScreenInfo, + GuiUpdateScreenInfo, + GuiChangeTitle, + GuiCleanupConsole, + GuiChangeIcon, + GuiResizeBuffer, }; NTSTATUS FASTCALL -GuiInitConsole(PCSRSS_CONSOLE Console) +GuiInitConsole(PCSRSS_CONSOLE Console, BOOL Visible) { - HANDLE GraphicsStartupEvent; - HANDLE ThreadHandle; - PGUI_CONSOLE_DATA GuiData; + HANDLE GraphicsStartupEvent; + HANDLE ThreadHandle; + PGUI_CONSOLE_DATA GuiData; - if (! ConsInitialized) + if (! ConsInitialized) { - ConsInitialized = TRUE; - if (! GuiInit()) + ConsInitialized = TRUE; + if (! GuiInit()) { - ConsInitialized = FALSE; - return STATUS_UNSUCCESSFUL; + ConsInitialized = FALSE; + return STATUS_UNSUCCESSFUL; } } - Console->Vtbl = &GuiVtbl; - if (NULL == NotifyWnd) + Console->Vtbl = &GuiVtbl; + if (NULL == NotifyWnd) { - GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL); - if (NULL == GraphicsStartupEvent) + GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + if (NULL == GraphicsStartupEvent) { - return STATUS_UNSUCCESSFUL; + return STATUS_UNSUCCESSFUL; } - ThreadHandle = CreateThread(NULL, - 0, - GuiConsoleGuiThread, - (PVOID) &GraphicsStartupEvent, - 0, - NULL); - if (NULL == ThreadHandle) + ThreadHandle = CreateThread(NULL, + 0, + GuiConsoleGuiThread, + (PVOID) &GraphicsStartupEvent, + 0, + NULL); + if (NULL == ThreadHandle) { - NtClose(GraphicsStartupEvent); - DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n"); - return STATUS_UNSUCCESSFUL; + NtClose(GraphicsStartupEvent); + DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n"); + return STATUS_UNSUCCESSFUL; } - SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST); - CloseHandle(ThreadHandle); + SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST); + CloseHandle(ThreadHandle); - WaitForSingleObject(GraphicsStartupEvent, INFINITE); - CloseHandle(GraphicsStartupEvent); + WaitForSingleObject(GraphicsStartupEvent, INFINITE); + CloseHandle(GraphicsStartupEvent); - if (NULL == NotifyWnd) + if (NULL == NotifyWnd) { - DPRINT1("Win32Csr: Failed to create notification window.\n"); - return STATUS_UNSUCCESSFUL; + DPRINT1("Win32Csr: Failed to create notification window.\n"); + return STATUS_UNSUCCESSFUL; } } GuiData = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(GUI_CONSOLE_DATA)); if (!GuiData) - { + { DPRINT1("Win32Csr: Failed to create GUI_CONSOLE_DATA\n"); return STATUS_UNSUCCESSFUL; - } + } Console->PrivateData = (PVOID) GuiData; /* @@ -2150,15 +2221,15 @@ GuiInitConsole(PCSRSS_CONSOLE Console) */ GuiData->hGuiInitEvent = CreateEventW(NULL, FALSE, FALSE, NULL); /* create console */ - PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, 0, (LPARAM) Console); + PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, Visible, (LPARAM) Console); /* wait untill initialization has finished */ WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE); - DPRINT1("received event Console %p GuiData %p X %d Y %d\n", Console, Console->PrivateData, Console->Size.X, Console->Size.Y); + DPRINT("received event Console %p GuiData %p X %d Y %d\n", Console, Console->PrivateData, Console->Size.X, Console->Size.Y); CloseHandle(GuiData->hGuiInitEvent); GuiData->hGuiInitEvent = NULL; - return STATUS_SUCCESS; + return STATUS_SUCCESS; } /* EOF */