From 2e6eddbc97c225baaa0ad5db1c75418ea1e4320f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Tue, 18 Oct 2016 23:51:59 +0000 Subject: [PATCH] [CONSRV] - Call TermGetLargestConsoleWindowSize to obtain the largest console window size allowed on the system, and use it for GetConsoleScreenBufferInfo and for SetConsoleWindowInfo too, where it is used to check if the given user window size is not too large. - Improve GuiGetLargestConsoleWindowSize for multi-monitor situations. - Remove the redundant definition of GetScreenBufferSizeUnits in guiterm.c (it already exists in conwnd.c). svn path=/trunk/; revision=72993 --- .../user/winsrv/consrv/condrv/dummyterm.c | 4 + .../win32ss/user/winsrv/consrv/condrv/text.c | 36 ++++++-- .../win32ss/user/winsrv/consrv/frontendctl.c | 6 ++ .../user/winsrv/consrv/frontends/gui/conwnd.c | 4 +- .../winsrv/consrv/frontends/gui/guiterm.c | 92 +++++++++---------- reactos/win32ss/user/winsrv/consrv/settings.c | 3 + 6 files changed, 87 insertions(+), 58 deletions(-) diff --git a/reactos/win32ss/user/winsrv/consrv/condrv/dummyterm.c b/reactos/win32ss/user/winsrv/consrv/condrv/dummyterm.c index fa87462ae01..7261994f6c9 100644 --- a/reactos/win32ss/user/winsrv/consrv/condrv/dummyterm.c +++ b/reactos/win32ss/user/winsrv/consrv/condrv/dummyterm.c @@ -112,6 +112,10 @@ static VOID NTAPI DummyGetLargestConsoleWindowSize(IN OUT PTERMINAL This, PCOORD pSize) { + /* Return a standard size */ + if (!pSize) return; + pSize->X = 80; + pSize->Y = 25; } static BOOL NTAPI diff --git a/reactos/win32ss/user/winsrv/consrv/condrv/text.c b/reactos/win32ss/user/winsrv/consrv/condrv/text.c index d54d8207508..5b4d415b297 100644 --- a/reactos/win32ss/user/winsrv/consrv/condrv/text.c +++ b/reactos/win32ss/user/winsrv/consrv/condrv/text.c @@ -1065,6 +1065,8 @@ ConDrvGetConsoleScreenBufferInfo(IN PCONSOLE Console, OUT PCOORD MaximumViewSize, OUT PWORD Attributes) { + COORD LargestWindowSize; + if (Console == NULL || Buffer == NULL || ScreenBufferSize == NULL || CursorPosition == NULL || ViewOrigin == NULL || ViewSize == NULL || MaximumViewSize == NULL || Attributes == NULL) @@ -1081,8 +1083,14 @@ ConDrvGetConsoleScreenBufferInfo(IN PCONSOLE Console, *ViewSize = Buffer->ViewSize; *Attributes = Buffer->ScreenDefaultAttrib; - // FIXME: Refine the computation - *MaximumViewSize = Buffer->ScreenBufferSize; + /* + * Retrieve the largest possible console window size, taking + * into account the size of the console screen buffer. + */ + TermGetLargestConsoleWindowSize(Console, &LargestWindowSize); + LargestWindowSize.X = min(LargestWindowSize.X, Buffer->ScreenBufferSize.X); + LargestWindowSize.Y = min(LargestWindowSize.Y, Buffer->ScreenBufferSize.Y); + *MaximumViewSize = LargestWindowSize; return STATUS_SUCCESS; } @@ -1216,6 +1224,7 @@ ConDrvSetConsoleWindowInfo(IN PCONSOLE Console, IN PSMALL_RECT WindowRect) { SMALL_RECT CapturedWindowRect; + COORD LargestWindowSize; if (Console == NULL || Buffer == NULL || WindowRect == NULL) return STATUS_INVALID_PARAMETER; @@ -1227,7 +1236,7 @@ ConDrvSetConsoleWindowInfo(IN PCONSOLE Console, if (!Absolute) { - /* Relative positions given. Transform them to absolute ones */ + /* Relative positions are given, transform them to absolute ones */ CapturedWindowRect.Left += Buffer->ViewOrigin.X; CapturedWindowRect.Top += Buffer->ViewOrigin.Y; CapturedWindowRect.Right += Buffer->ViewOrigin.X + Buffer->ViewSize.X - 1; @@ -1248,6 +1257,19 @@ ConDrvSetConsoleWindowInfo(IN PCONSOLE Console, return STATUS_INVALID_PARAMETER; } + /* + * Forbid window sizes larger than the largest allowed console window size, + * taking into account the size of the console screen buffer. + */ + TermGetLargestConsoleWindowSize(Console, &LargestWindowSize); + LargestWindowSize.X = min(LargestWindowSize.X, Buffer->ScreenBufferSize.X); + LargestWindowSize.Y = min(LargestWindowSize.Y, Buffer->ScreenBufferSize.Y); + if ((CapturedWindowRect.Right - CapturedWindowRect.Left + 1 > LargestWindowSize.X) || + (CapturedWindowRect.Bottom - CapturedWindowRect.Top + 1 > LargestWindowSize.Y)) + { + return STATUS_INVALID_PARAMETER; + } + /* Shift the window rectangle coordinates if 'Left' or 'Top' are negative */ if (CapturedWindowRect.Left < 0) { @@ -1260,11 +1282,9 @@ ConDrvSetConsoleWindowInfo(IN PCONSOLE Console, CapturedWindowRect.Top = 0; } - if ((CapturedWindowRect.Right >= Buffer->ScreenBufferSize.X) || - (CapturedWindowRect.Bottom >= Buffer->ScreenBufferSize.Y)) - { - return STATUS_INVALID_PARAMETER; - } + /* Clip the window rectangle to the screen buffer */ + CapturedWindowRect.Right = min(CapturedWindowRect.Right , Buffer->ScreenBufferSize.X); + CapturedWindowRect.Bottom = min(CapturedWindowRect.Bottom, Buffer->ScreenBufferSize.Y); Buffer->ViewOrigin.X = CapturedWindowRect.Left; Buffer->ViewOrigin.Y = CapturedWindowRect.Top; diff --git a/reactos/win32ss/user/winsrv/consrv/frontendctl.c b/reactos/win32ss/user/winsrv/consrv/frontendctl.c index 7d4cd84b131..9ea1fe99616 100644 --- a/reactos/win32ss/user/winsrv/consrv/frontendctl.c +++ b/reactos/win32ss/user/winsrv/consrv/frontendctl.c @@ -174,6 +174,12 @@ CSR_API(SrvGetLargestConsoleWindowSize) if (!NT_SUCCESS(Status)) return Status; Console = Buff->Header.Console; + + /* + * Retrieve the largest possible console window size, without + * taking into account the size of the console screen buffer + * (thus differs from ConDrvGetConsoleScreenBufferInfo). + */ TermGetLargestConsoleWindowSize(Console, &GetLargestWindowSizeRequest->Size); ConSrvReleaseScreenBuffer(Buff, TRUE); diff --git a/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c b/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c index 1a9806b28ce..3966670799a 100644 --- a/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c +++ b/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c @@ -172,8 +172,8 @@ UnRegisterConWndClass(HINSTANCE hInstance) } - -static VOID +/* NOTE: Also used in guiterm.c */ +/* static */ VOID GetScreenBufferSizeUnits(IN PCONSOLE_SCREEN_BUFFER Buffer, IN PGUI_CONSOLE_DATA GuiData, OUT PUINT WidthUnit, diff --git a/reactos/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c b/reactos/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c index 61f4ade07d9..d479a5a31ee 100644 --- a/reactos/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c +++ b/reactos/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c @@ -56,29 +56,12 @@ UnRegisterConWndClass(HINSTANCE hInstance); /* FUNCTIONS ******************************************************************/ -static VOID +/* NOTE: Defined in conwnd.c */ +VOID GetScreenBufferSizeUnits(IN PCONSOLE_SCREEN_BUFFER Buffer, IN PGUI_CONSOLE_DATA GuiData, OUT PUINT WidthUnit, - OUT PUINT HeightUnit) -{ - if (Buffer == NULL || GuiData == NULL || - WidthUnit == NULL || HeightUnit == NULL) - { - return; - } - - if (GetType(Buffer) == TEXTMODE_BUFFER) - { - *WidthUnit = GuiData->CharWidth ; - *HeightUnit = GuiData->CharHeight; - } - else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */ - { - *WidthUnit = 1; - *HeightUnit = 1; - } -} + OUT PUINT HeightUnit); VOID GuiConsoleMoveWindow(PGUI_CONSOLE_DATA GuiData) @@ -817,13 +800,9 @@ GuiSetActiveScreenBuffer(IN OUT PFRONTEND This) /* Change the current palette */ if (ActiveBuffer->PaletteHandle == NULL) - { hPalette = GuiData->hSysPalette; - } else - { hPalette = ActiveBuffer->PaletteHandle; - } DPRINT("GuiSetActiveScreenBuffer using palette 0x%p\n", hPalette); @@ -937,9 +916,7 @@ GuiChangeIcon(IN OUT PFRONTEND This, } if (hIcon == NULL) - { return FALSE; - } if (hIcon != GuiData->hIcon) { @@ -976,41 +953,60 @@ GuiGetLargestConsoleWindowSize(IN OUT PFRONTEND This, { PGUI_CONSOLE_DATA GuiData = This->Context; PCONSOLE_SCREEN_BUFFER ActiveBuffer; - RECT WorkArea; - LONG width, height; + HMONITOR hMonitor; + MONITORINFO MonitorInfo; + LONG Width, Height; UINT WidthUnit, HeightUnit; if (!pSize) return; - if (!SystemParametersInfoW(SPI_GETWORKAREA, 0, &WorkArea, 0)) + /* + * Retrieve the monitor that is mostly covered by the current console window; + * default to primary monitor otherwise. + */ + MonitorInfo.cbSize = sizeof(MonitorInfo); + hMonitor = MonitorFromWindow(GuiData->hWindow, MONITOR_DEFAULTTOPRIMARY); + if (hMonitor && GetMonitorInfoW(hMonitor, &MonitorInfo)) { - DPRINT1("SystemParametersInfoW failed - What to do ??\n"); - return; - } - - ActiveBuffer = GuiData->ActiveBuffer; - if (ActiveBuffer) - { - GetScreenBufferSizeUnits(ActiveBuffer, GuiData, &WidthUnit, &HeightUnit); + /* Retrieve the width and height of the client area of this monitor */ + Width = MonitorInfo.rcWork.right - MonitorInfo.rcWork.left; + Height = MonitorInfo.rcWork.bottom - MonitorInfo.rcWork.top; } else { - /* Default: text mode */ - WidthUnit = GuiData->CharWidth ; - HeightUnit = GuiData->CharHeight; + /* + * Retrieve the width and height of the client area for a full-screen + * window on the primary display monitor. + */ + Width = GetSystemMetrics(SM_CXFULLSCREEN); + Height = GetSystemMetrics(SM_CYFULLSCREEN); + + // RECT WorkArea; + // SystemParametersInfoW(SPI_GETWORKAREA, 0, &WorkArea, 0); + // Width = WorkArea.right; + // Height = WorkArea.bottom; } - width = WorkArea.right; - height = WorkArea.bottom; + ActiveBuffer = GuiData->ActiveBuffer; +#if 0 + // NOTE: This would be surprising if we wouldn't have an associated buffer... + if (ActiveBuffer) +#endif + GetScreenBufferSizeUnits(ActiveBuffer, GuiData, &WidthUnit, &HeightUnit); +#if 0 + else + /* Default: graphics mode */ + WidthUnit = HeightUnit = 1; +#endif - width -= (2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE))); - height -= (2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION)); + Width -= (2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE))); + Height -= (2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION)); - if (width < 0) width = 0; - if (height < 0) height = 0; + if (Width < 0) Width = 0; + if (Height < 0) Height = 0; - pSize->X = (SHORT)(width / (int)WidthUnit ) /* HACK */ + 2; - pSize->Y = (SHORT)(height / (int)HeightUnit) /* HACK */ + 1; + pSize->X = (SHORT)(Width / (int)WidthUnit ) /* HACK */ + 2; + pSize->Y = (SHORT)(Height / (int)HeightUnit) /* HACK */ + 1; } static BOOL NTAPI diff --git a/reactos/win32ss/user/winsrv/consrv/settings.c b/reactos/win32ss/user/winsrv/consrv/settings.c index 5b0d46531e8..f700c95a62f 100644 --- a/reactos/win32ss/user/winsrv/consrv/settings.c +++ b/reactos/win32ss/user/winsrv/consrv/settings.c @@ -52,6 +52,9 @@ ConSrvApplyUserSettings(IN PCONSOLE Console, ActiveBuffer->CursorInfo.bVisible = (ConsoleInfo->CursorSize != 0); ActiveBuffer->CursorInfo.dwSize = min(max(ConsoleInfo->CursorSize, 0), 100); + // FIXME: Check ConsoleInfo->WindowSize with respect to + // TermGetLargestConsoleWindowSize(...). + if (GetType(ActiveBuffer) == TEXTMODE_BUFFER) { PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer;