[CONSRV] Fix setting the default screenbuffer and console view sizes when creating a new screenbuffer.

For more information, see:
https://docs.microsoft.com/en-us/windows/console/createconsolescreenbuffer#remarks
This commit is contained in:
Hermès Bélusca-Maïto 2020-02-23 21:45:55 +01:00
parent 309f7e9443
commit 1d3fb3e370
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
5 changed files with 59 additions and 43 deletions

View file

@ -82,7 +82,7 @@ ConDrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
IN ULONG BufferType, IN ULONG BufferType,
IN PVOID ScreenBufferInfo) IN PVOID ScreenBufferInfo)
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_UNSUCCESSFUL;
if ( Console == NULL || Buffer == NULL || if ( Console == NULL || Buffer == NULL ||
(BufferType != CONSOLE_TEXTMODE_BUFFER && BufferType != CONSOLE_GRAPHICS_BUFFER) ) (BufferType != CONSOLE_TEXTMODE_BUFFER && BufferType != CONSOLE_GRAPHICS_BUFFER) )

View file

@ -185,9 +185,11 @@ ConDrvInitConsole(OUT PCONSOLE* NewConsole,
} }
/* /*
* Fix the screen buffer size if needed. The rule is: * Set and fix the screen buffer size if needed.
* ScreenBufferSize >= ConsoleSize * The rule is: ScreenBufferSize >= ConsoleSize
*/ */
if (ConsoleInfo->ScreenBufferSize.X == 0) ConsoleInfo->ScreenBufferSize.X = 1;
if (ConsoleInfo->ScreenBufferSize.Y == 0) ConsoleInfo->ScreenBufferSize.Y = 1;
if (ConsoleInfo->ScreenBufferSize.X < ConsoleInfo->ConsoleSize.X) if (ConsoleInfo->ScreenBufferSize.X < ConsoleInfo->ConsoleSize.X)
ConsoleInfo->ScreenBufferSize.X = ConsoleInfo->ConsoleSize.X; ConsoleInfo->ScreenBufferSize.X = ConsoleInfo->ConsoleSize.X;
if (ConsoleInfo->ScreenBufferSize.Y < ConsoleInfo->ConsoleSize.Y) if (ConsoleInfo->ScreenBufferSize.Y < ConsoleInfo->ConsoleSize.Y)
@ -224,10 +226,11 @@ ConDrvInitConsole(OUT PCONSOLE* NewConsole,
/* Initialize a new text-mode screen buffer with default settings */ /* Initialize a new text-mode screen buffer with default settings */
ScreenBufferInfo.ScreenBufferSize = ConsoleInfo->ScreenBufferSize; ScreenBufferInfo.ScreenBufferSize = ConsoleInfo->ScreenBufferSize;
ScreenBufferInfo.ViewSize = ConsoleInfo->ConsoleSize;
ScreenBufferInfo.ScreenAttrib = ConsoleInfo->ScreenAttrib; ScreenBufferInfo.ScreenAttrib = ConsoleInfo->ScreenAttrib;
ScreenBufferInfo.PopupAttrib = ConsoleInfo->PopupAttrib; ScreenBufferInfo.PopupAttrib = ConsoleInfo->PopupAttrib;
ScreenBufferInfo.IsCursorVisible = TRUE;
ScreenBufferInfo.CursorSize = ConsoleInfo->CursorSize; ScreenBufferInfo.CursorSize = ConsoleInfo->CursorSize;
ScreenBufferInfo.IsCursorVisible = TRUE;
InitializeListHead(&Console->BufferList); InitializeListHead(&Console->BufferList);
Status = ConDrvCreateScreenBuffer(&NewBuffer, Status = ConDrvCreateScreenBuffer(&NewBuffer,

View file

@ -76,6 +76,12 @@ TEXTMODE_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
if (Console == NULL || Buffer == NULL || TextModeInfo == NULL) if (Console == NULL || Buffer == NULL || TextModeInfo == NULL)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
if ((TextModeInfo->ScreenBufferSize.X == 0) ||
(TextModeInfo->ScreenBufferSize.Y == 0))
{
return STATUS_INVALID_PARAMETER;
}
*Buffer = NULL; *Buffer = NULL;
Status = CONSOLE_SCREEN_BUFFER_Initialize((PCONSOLE_SCREEN_BUFFER*)&NewBuffer, Status = CONSOLE_SCREEN_BUFFER_Initialize((PCONSOLE_SCREEN_BUFFER*)&NewBuffer,
@ -95,10 +101,16 @@ TEXTMODE_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
NewBuffer->ScreenBufferSize = NewBuffer->OldScreenBufferSize NewBuffer->ScreenBufferSize = TextModeInfo->ScreenBufferSize;
= TextModeInfo->ScreenBufferSize; NewBuffer->OldScreenBufferSize = NewBuffer->ScreenBufferSize;
NewBuffer->ViewSize = NewBuffer->OldViewSize
= Console->ConsoleSize; /*
* Set and fix the view size if needed.
* The rule is: ScreenBufferSize >= ViewSize (== ConsoleSize)
*/
NewBuffer->ViewSize.X = min(max(TextModeInfo->ViewSize.X, 1), NewBuffer->ScreenBufferSize.X);
NewBuffer->ViewSize.Y = min(max(TextModeInfo->ViewSize.Y, 1), NewBuffer->ScreenBufferSize.Y);
NewBuffer->OldViewSize = NewBuffer->ViewSize;
NewBuffer->ViewOrigin.X = NewBuffer->ViewOrigin.Y = 0; NewBuffer->ViewOrigin.X = NewBuffer->ViewOrigin.Y = 0;
NewBuffer->VirtualY = 0; NewBuffer->VirtualY = 0;
@ -465,15 +477,11 @@ ConioResizeBuffer(PCONSOLE Console,
ScreenBuffer->ScreenBufferSize = ScreenBuffer->OldScreenBufferSize = Size; ScreenBuffer->ScreenBufferSize = ScreenBuffer->OldScreenBufferSize = Size;
ScreenBuffer->VirtualY = 0; ScreenBuffer->VirtualY = 0;
/* Ensure cursor and window are within buffer */ /* Ensure the cursor and the view are within the buffer */
if (ScreenBuffer->CursorPosition.X >= Size.X) ScreenBuffer->CursorPosition.X = min(ScreenBuffer->CursorPosition.X, Size.X - 1);
ScreenBuffer->CursorPosition.X = Size.X - 1; ScreenBuffer->CursorPosition.Y = min(ScreenBuffer->CursorPosition.Y, Size.Y - 1);
if (ScreenBuffer->CursorPosition.Y >= Size.Y) ScreenBuffer->ViewOrigin.X = min(ScreenBuffer->ViewOrigin.X, Size.X - ScreenBuffer->ViewSize.X);
ScreenBuffer->CursorPosition.Y = Size.Y - 1; ScreenBuffer->ViewOrigin.Y = min(ScreenBuffer->ViewOrigin.Y, Size.Y - ScreenBuffer->ViewSize.Y);
if (ScreenBuffer->ViewOrigin.X > Size.X - ScreenBuffer->ViewSize.X)
ScreenBuffer->ViewOrigin.X = Size.X - ScreenBuffer->ViewSize.X;
if (ScreenBuffer->ViewOrigin.Y > Size.Y - ScreenBuffer->ViewSize.Y)
ScreenBuffer->ViewOrigin.Y = Size.Y - ScreenBuffer->ViewSize.Y;
/* /*
* Trigger a buffer resize event * Trigger a buffer resize event

View file

@ -204,6 +204,7 @@ CSR_API(SrvCreateConsoleScreenBuffer)
PVOID ScreenBufferInfo = NULL; PVOID ScreenBufferInfo = NULL;
TEXTMODE_BUFFER_INFO TextModeInfo = {{80, 25}, TEXTMODE_BUFFER_INFO TextModeInfo = {{80, 25},
{80, 25},
DEFAULT_SCREEN_ATTRIB, DEFAULT_SCREEN_ATTRIB,
DEFAULT_POPUP_ATTRIB , DEFAULT_POPUP_ATTRIB ,
TRUE, TRUE,
@ -221,29 +222,18 @@ CSR_API(SrvCreateConsoleScreenBuffer)
ScreenBufferInfo = &TextModeInfo; ScreenBufferInfo = &TextModeInfo;
/* /*
if (Console->ActiveBuffer) * This is Windows behaviour, as described by MSDN and verified manually:
{ *
TextModeInfo.ScreenBufferSize = Console->ActiveBuffer->ScreenBufferSize; * The newly created screen buffer will copy some properties from the
if (TextModeInfo.ScreenBufferSize.X == 0) TextModeInfo.ScreenBufferSize.X = 80; * active screen buffer at the time that this function is called.
if (TextModeInfo.ScreenBufferSize.Y == 0) TextModeInfo.ScreenBufferSize.Y = 25; * The behavior is as follows:
* Font - copied from active screen buffer.
TextModeInfo.ScreenAttrib = Console->ActiveBuffer->ScreenBuffer.TextBuffer.ScreenDefaultAttrib; * Display Window Size - copied from active screen buffer.
TextModeInfo.PopupAttrib = Console->ActiveBuffer->ScreenBuffer.TextBuffer.PopupDefaultAttrib; * Buffer Size - matched to Display Window Size (NOT copied).
* Default Attributes (colors) - copied from active screen buffer.
TextModeInfo.IsCursorVisible = Console->ActiveBuffer->CursorInfo.bVisible; * Default Popup Attributes (colors) - copied from active screen buffer.
TextModeInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
}
*/
/*
* This is Windows behaviour.
*/ */
/* Use the current console size. Normalize it if needed */
TextModeInfo.ScreenBufferSize = Console->ConsoleSize;
if (TextModeInfo.ScreenBufferSize.X == 0) TextModeInfo.ScreenBufferSize.X = 1;
if (TextModeInfo.ScreenBufferSize.Y == 0) TextModeInfo.ScreenBufferSize.Y = 1;
/* If we have an active screen buffer, use its attributes as the new ones */ /* If we have an active screen buffer, use its attributes as the new ones */
if (Console->ActiveBuffer && GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER) if (Console->ActiveBuffer && GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
{ {
@ -252,9 +242,23 @@ CSR_API(SrvCreateConsoleScreenBuffer)
TextModeInfo.ScreenAttrib = Buffer->ScreenDefaultAttrib; TextModeInfo.ScreenAttrib = Buffer->ScreenDefaultAttrib;
TextModeInfo.PopupAttrib = Buffer->PopupDefaultAttrib; TextModeInfo.PopupAttrib = Buffer->PopupDefaultAttrib;
TextModeInfo.IsCursorVisible = Buffer->CursorInfo.bVisible;
TextModeInfo.CursorSize = Buffer->CursorInfo.dwSize; TextModeInfo.CursorSize = Buffer->CursorInfo.dwSize;
TextModeInfo.IsCursorVisible = Buffer->CursorInfo.bVisible;
/* Use the current view size */
TextModeInfo.ScreenBufferSize = Buffer->ViewSize;
TextModeInfo.ViewSize = Buffer->ViewSize;
} }
else
{
/* Use the current console size */
TextModeInfo.ScreenBufferSize = Console->ConsoleSize;
TextModeInfo.ViewSize = Console->ConsoleSize;
}
/* Normalize the screen buffer size if needed */
if (TextModeInfo.ScreenBufferSize.X == 0) TextModeInfo.ScreenBufferSize.X = 1;
if (TextModeInfo.ScreenBufferSize.Y == 0) TextModeInfo.ScreenBufferSize.Y = 1;
} }
else if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_GRAPHICS_BUFFER) else if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_GRAPHICS_BUFFER)
{ {

View file

@ -105,8 +105,8 @@ struct _CONSOLE_SCREEN_BUFFER
HPALETTE PaletteHandle; /* Handle to the color palette associated to this buffer */ HPALETTE PaletteHandle; /* Handle to the color palette associated to this buffer */
UINT PaletteUsage; /* The new use of the system palette. See SetSystemPaletteUse 'uUsage' parameter */ UINT PaletteUsage; /* The new use of the system palette. See SetSystemPaletteUse 'uUsage' parameter */
// WORD ScreenDefaultAttrib; /* Default screen char attribute */ // USHORT ScreenDefaultAttrib; /* Default screen char attribute */
// WORD PopupDefaultAttrib; /* Default popup char attribute */ // USHORT PopupDefaultAttrib; /* Default popup char attribute */
USHORT Mode; /* Output buffer modes */ USHORT Mode; /* Output buffer modes */
}; };
@ -141,6 +141,7 @@ struct _CONSOLE_SCREEN_BUFFER
typedef struct _TEXTMODE_BUFFER_INFO typedef struct _TEXTMODE_BUFFER_INFO
{ {
COORD ScreenBufferSize; COORD ScreenBufferSize;
COORD ViewSize;
USHORT ScreenAttrib; USHORT ScreenAttrib;
USHORT PopupAttrib; USHORT PopupAttrib;
ULONG CursorSize; ULONG CursorSize;
@ -153,8 +154,8 @@ typedef struct _TEXTMODE_SCREEN_BUFFER
PCHAR_INFO Buffer; /* Pointer to UNICODE screen buffer (Buffer->Char.UnicodeChar only is valid, not Char.AsciiChar) */ PCHAR_INFO Buffer; /* Pointer to UNICODE screen buffer (Buffer->Char.UnicodeChar only is valid, not Char.AsciiChar) */
WORD ScreenDefaultAttrib; /* Default screen char attribute */ USHORT ScreenDefaultAttrib; /* Default screen char attribute */
WORD PopupDefaultAttrib; /* Default popup char attribute */ USHORT PopupDefaultAttrib; /* Default popup char attribute */
} TEXTMODE_SCREEN_BUFFER, *PTEXTMODE_SCREEN_BUFFER; } TEXTMODE_SCREEN_BUFFER, *PTEXTMODE_SCREEN_BUFFER;