Author: jmorlan Date: Wed May 12 05:34:02 2010 New Revision: 47165
URL: http://svn.reactos.org/svn/reactos?rev=47165&view=rev Log: [KERNEL32] [WIN32CSR] Implement SetConsoleScreenBufferSize. FAR Manager now works again.
Modified: trunk/reactos/dll/win32/kernel32/misc/console.c trunk/reactos/include/reactos/subsys/csrss/csrss.h trunk/reactos/subsystems/win32/csrss/win32csr/conio.c trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c trunk/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c
Modified: trunk/reactos/dll/win32/kernel32/misc/console.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/con... ============================================================================== --- trunk/reactos/dll/win32/kernel32/misc/console.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/misc/console.c [iso-8859-1] Wed May 12 05:34:02 2010 @@ -3086,16 +3086,29 @@ /*-------------------------------------------------------------- * SetConsoleScreenBufferSize * - * @unimplemented + * @implemented */ BOOL WINAPI SetConsoleScreenBufferSize(HANDLE hConsoleOutput, COORD dwSize) { - DPRINT1("SetConsoleScreenBufferSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, dwSize); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + CSR_API_MESSAGE Request; + ULONG CsrRequest; + NTSTATUS Status; + + CsrRequest = MAKE_CSR_API(SET_SCREEN_BUFFER_SIZE, CSR_CONSOLE); + Request.Data.SetScreenBufferSize.OutputHandle = hConsoleOutput; + Request.Data.SetScreenBufferSize.Size = dwSize; + + Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + return TRUE; }
/*--------------------------------------------------------------
Modified: trunk/reactos/include/reactos/subsys/csrss/csrss.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/subsys/csrs... ============================================================================== --- trunk/reactos/include/reactos/subsys/csrss/csrss.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/subsys/csrss/csrss.h [iso-8859-1] Wed May 12 05:34:02 2010 @@ -472,6 +472,11 @@ DWORD ProcessGroup; } CSRSS_GENERATE_CTRL_EVENT, *PCSRSS_GENERATE_CTRL_EVENT;
+typedef struct +{ + HANDLE OutputHandle; + COORD Size; +} CSRSS_SET_SCREEN_BUFFER_SIZE, *PCSRSS_SET_SCREEN_BUFFER_SIZE;
#define CSR_API_MESSAGE_HEADER_SIZE(Type) (FIELD_OFFSET(CSR_API_MESSAGE, Data) + sizeof(Type)) @@ -551,6 +556,7 @@ #define GET_CONSOLE_ALIASES_EXES_LENGTH (0x3D) #define GENERATE_CTRL_EVENT (0x3E) #define CREATE_THREAD (0x3F) +#define SET_SCREEN_BUFFER_SIZE (0x40)
/* Keep in sync with definition below. */ #define CSRSS_HEADER_SIZE (sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS)) @@ -624,6 +630,7 @@ CSRSS_GET_CONSOLE_ALIASES_EXES GetConsoleAliasesExes; CSRSS_GET_CONSOLE_ALIASES_EXES_LENGTH GetConsoleAliasesExesLength; CSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent; + CSRSS_SET_SCREEN_BUFFER_SIZE SetScreenBufferSize; } Data; } CSR_API_MESSAGE, *PCSR_API_MESSAGE;
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/conio.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/conio.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/conio.c [iso-8859-1] Wed May 12 05:34:02 2010 @@ -3118,4 +3118,33 @@ return Status; }
+CSR_API(CsrSetScreenBufferSize) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferSize.OutputHandle, &Buff, GENERIC_WRITE); + if (!NT_SUCCESS(Status)) + { + ConioUnlockConsole(Console); + return Status; + } + + Status = ConioResizeBuffer(Console, Buff, Request->Data.SetScreenBufferSize.Size); + ConioUnlockScreenBuffer(Buff); + ConioUnlockConsole(Console); + + return Status; +} + /* EOF */
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c [iso-8859-1] Wed May 12 05:34:02 2010 @@ -74,6 +74,7 @@ CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES, CsrGetConsoleAliasesExes), CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES_LENGTH, CsrGetConsoleAliasesExesLength), CSRSS_DEFINE_API(GENERATE_CTRL_EVENT, CsrGenerateCtrlEvent), + CSRSS_DEFINE_API(SET_SCREEN_BUFFER_SIZE, CsrSetScreenBufferSize), { 0, 0, NULL } };
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c [iso-8859-1] Wed May 12 05:34:02 2010 @@ -1708,11 +1708,105 @@
}
+static NTSTATUS WINAPI +GuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD Size) +{ + BYTE * Buffer; + DWORD Offset = 0; + BYTE * OldPtr; + USHORT CurrentY; + BYTE * OldBuffer; +#if HAVE_WMEMSET + USHORT value = MAKEWORD(' ', ScreenBuffer->DefaultAttrib); +#endif + DWORD diff; + DWORD i; + + /* 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 (Size.X == ScreenBuffer->MaxX && Size.Y == ScreenBuffer->MaxY) + return STATUS_SUCCESS; + + Buffer = HeapAlloc(Win32CsrApiHeap, 0, Size.X * Size.Y * 2); + if (!Buffer) + return STATUS_NO_MEMORY; + + DPRINT1("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->MaxX, ScreenBuffer->MaxY, Size.X, Size.Y); + OldBuffer = ScreenBuffer->Buffer; + + for (CurrentY = 0; CurrentY < ScreenBuffer->MaxY && CurrentY < Size.Y; CurrentY++) + { + OldPtr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY); + if (Size.X <= ScreenBuffer->MaxX) + { + /* 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 = Size.X - ScreenBuffer->MaxX; + /* zero new part of it */ +#if HAVE_WMEMSET + wmemset((WCHAR*)&Buffer[Offset], value, diff); +#else + for (i = 0; i < diff; i++) + { + Buffer[Offset++] = ' '; + Buffer[Offset++] = ScreenBuffer->DefaultAttrib; + } +#endif + } + } + + if (Size.Y > ScreenBuffer->MaxY) + { + diff = Size.X * (Size.Y - ScreenBuffer->MaxY); +#if HAVE_WMEMSET + wmemset((WCHAR*)&Buffer[Offset], value, diff); +#else + 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 FASTCALL 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(&ActiveBuffer->Header.Lock); @@ -1723,85 +1817,6 @@
/* apply cursor size */ ActiveBuffer->CursorInfo.dwSize = min(max(pConInfo->CursorSize, 1), 100); - - windx = LOWORD(pConInfo->ScreenBuffer); - windy = HIWORD(pConInfo->ScreenBuffer); - - if (windx != ActiveBuffer->MaxX || windy != ActiveBuffer->MaxY) - { - BYTE * Buffer = HeapAlloc(Win32CsrApiHeap, 0, windx * windy * 2); - - if (Buffer) - { - DWORD Offset = 0; - BYTE * OldPtr; - USHORT CurrentY; - BYTE * OldBuffer; - USHORT value; - DWORD diff; - DWORD i; - - value = MAKEWORD(' ', ActiveBuffer->DefaultAttrib); - - 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; - - for (CurrentY = 0; CurrentY < min(ActiveBuffer->MaxY, windy); CurrentY++) - { - 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); - - diff = windx - ActiveBuffer->MaxX; - /* zero new part of it */ -#if HAVE_WMEMSET - wmemset((WCHAR*)&Buffer[Offset], value, diff); -#else - for (i = 0; i < diff; i++) - { - Buffer[Offset++] = ' '; - Buffer[Offset++] = ActiveBuffer->DefaultAttrib; - } -#endif - } - } - - if (windy > ActiveBuffer->MaxY) - { - diff = windy - ActiveBuffer->MaxY; -#if HAVE_WMEMSET - wmemset((WCHAR*)&Buffer[Offset], value, diff * windx); -#else - for (i = 0; i < diff * windx; i++) - { - Buffer[Offset++] = ' '; - Buffer[Offset++] = ActiveBuffer->DefaultAttrib; - } -#endif - } - - (void)InterlockedExchangePointer((PVOID volatile *)&ActiveBuffer->Buffer, Buffer); - HeapFree(Win32CsrApiHeap, 0, OldBuffer); - ActiveBuffer->MaxX = windx; - ActiveBuffer->MaxY = windy; - ActiveBuffer->VirtualY = 0; - SizeChanged = TRUE; - } - else - { - LeaveCriticalSection(&ActiveBuffer->Header.Lock); - return; - } - }
windx = LOWORD(pConInfo->WindowSize); windy = HIWORD(pConInfo->WindowSize); @@ -1812,6 +1827,14 @@ Console->Size.X = windx; Console->Size.Y = windy; SizeChanged = TRUE; + } + + BufSize.X = LOWORD(pConInfo->ScreenBuffer); + BufSize.Y = HIWORD(pConInfo->ScreenBuffer); + if (BufSize.X != ActiveBuffer->MaxX || BufSize.Y != ActiveBuffer->MaxY) + { + if (NT_SUCCESS(GuiResizeBuffer(Console, ActiveBuffer, BufSize))) + SizeChanged = TRUE; }
if (SizeChanged) @@ -2222,7 +2245,8 @@ GuiUpdateScreenInfo, GuiChangeTitle, GuiCleanupConsole, - GuiChangeIcon + GuiChangeIcon, + GuiResizeBuffer, };
NTSTATUS FASTCALL
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c [iso-8859-1] Wed May 12 05:34:02 2010 @@ -288,6 +288,19 @@ { ConioDrawConsole(ActiveConsole); } +} + +static BOOL WINAPI +TuiChangeIcon(PCSRSS_CONSOLE Console, HICON hWindowIcon) +{ + return TRUE; +} + +static NTSTATUS WINAPI +TuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD Size) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; }
DWORD WINAPI @@ -340,7 +353,8 @@ TuiUpdateScreenInfo, TuiChangeTitle, TuiCleanupConsole, - NULL // ChangeIcon + TuiChangeIcon, + TuiResizeBuffer, };
NTSTATUS FASTCALL