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;