From 5d937b84a8245ff525cba4dcddeb7f88bc796360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sat, 15 Mar 2014 17:15:23 +0000 Subject: [PATCH] [CONSRV] Fix changing foreground and background console colors via console properties dialog. Fully developed and tested in ReactOS 8^D CORE-4901 #resolve #comment Fixed in revision 62505. svn path=/trunk/; revision=62505 --- .../win32ss/user/winsrv/consrv/condrv/text.c | 76 ++++++++++++++++++- reactos/win32ss/user/winsrv/consrv/settings.c | 30 +++----- 2 files changed, 86 insertions(+), 20 deletions(-) diff --git a/reactos/win32ss/user/winsrv/consrv/condrv/text.c b/reactos/win32ss/user/winsrv/consrv/condrv/text.c index 5c1ab108d7e..afe3afe661b 100644 --- a/reactos/win32ss/user/winsrv/consrv/condrv/text.c +++ b/reactos/win32ss/user/winsrv/consrv/condrv/text.c @@ -585,6 +585,78 @@ ConioWriteConsole(PCONSOLE Console, return STATUS_SUCCESS; } +NTSTATUS NTAPI +ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN USHORT NewScreenAttrib, + IN USHORT NewPopupAttrib) +{ + DWORD X, Y, Length; + PCHAR_INFO Ptr; + + COORD TopLeft = {0}; + ULONG NumCodesToWrite = Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y; + USHORT OldScreenAttrib = Buffer->ScreenDefaultAttrib; + + if (Console == NULL || Buffer == NULL) + { + return STATUS_INVALID_PARAMETER; + } + + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); + + X = TopLeft.X; + Y = (TopLeft.Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; + Length = NumCodesToWrite; + // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work + // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work + + while (Length--) + { + // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either + Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; + + /* + * Change the current colors only if they are the old ones. + */ + + /* Foreground color */ + if ((Ptr->Attributes & 0x0F) == (OldScreenAttrib & 0x0F)) + Ptr->Attributes = (Ptr->Attributes & 0xFFF0) | (NewScreenAttrib & 0x0F); + + /* Background color */ + if ((Ptr->Attributes & 0xF0) == (OldScreenAttrib & 0xF0)) + Ptr->Attributes = (Ptr->Attributes & 0xFF0F) | (NewScreenAttrib & 0xF0); + + // ++Ptr; + + if (++X == Buffer->ScreenBufferSize.X) + { + X = 0; + + if (++Y == Buffer->ScreenBufferSize.Y) + { + Y = 0; + } + } + } + + /* Save foreground and background colors for both screen and popup */ + Buffer->ScreenDefaultAttrib = (NewScreenAttrib & 0x00FF); + Buffer->PopupDefaultAttrib = (NewPopupAttrib & 0x00FF); + + /* Refresh the display if needed */ + if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer) + { + SMALL_RECT UpdateRect; + ConioComputeUpdateRect(Buffer, &UpdateRect, &TopLeft, NumCodesToWrite); + TermDrawRegion(Console, &UpdateRect); + } + + return STATUS_SUCCESS; +} + /* PUBLIC DRIVER APIS *********************************************************/ @@ -947,7 +1019,6 @@ ConDrvWriteConsoleOutputString(IN PCONSOLE Console, PWCHAR tmpString = NULL; DWORD X, Y, Length; // , Written = 0; ULONG CodeSize; - SMALL_RECT UpdateRect; PCHAR_INFO Ptr; if (Console == NULL || Buffer == NULL || @@ -1046,6 +1117,7 @@ ConDrvWriteConsoleOutputString(IN PCONSOLE Console, if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer) { + SMALL_RECT UpdateRect; ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite); TermDrawRegion(Console, &UpdateRect); } @@ -1071,7 +1143,6 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console, { DWORD X, Y, Length; // , Written = 0; PCHAR_INFO Ptr; - SMALL_RECT UpdateRect; if (Console == NULL || Buffer == NULL || Code == NULL || WriteCoord == NULL /* || CodesWritten == NULL */) @@ -1144,6 +1215,7 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console, if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer) { + SMALL_RECT UpdateRect; ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite); TermDrawRegion(Console, &UpdateRect); } diff --git a/reactos/win32ss/user/winsrv/consrv/settings.c b/reactos/win32ss/user/winsrv/consrv/settings.c index f765e853d19..1775d1d3e79 100644 --- a/reactos/win32ss/user/winsrv/consrv/settings.c +++ b/reactos/win32ss/user/winsrv/consrv/settings.c @@ -436,7 +436,11 @@ ConSrvGetDefaultSettings(IN OUT PCONSOLE_INFO ConsoleInfo, } } - +NTSTATUS NTAPI +ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN USHORT NewScreenAttrib, + IN USHORT NewPopupAttrib); /* * NOTE: This function explicitely references Console->ActiveBuffer. * It is possible that it should go into some frontend... @@ -455,26 +459,10 @@ ConSrvApplyUserSettings(IN PCONSOLE Console, Console->QuickEdit = ConsoleInfo->QuickEdit; Console->InsertMode = ConsoleInfo->InsertMode; - /* - * Apply foreground and background colors for both screen and popup - * and copy the new palette. - */ - if (GetType(ActiveBuffer) == TEXTMODE_BUFFER) - { - PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer; - - Buffer->ScreenDefaultAttrib = ConsoleInfo->ScreenAttrib; - Buffer->PopupDefaultAttrib = ConsoleInfo->PopupAttrib; - } - else // if (Console->ActiveBuffer->Header.Type == GRAPHICS_BUFFER) - { - } - + /* Copy the new console palette */ // FIXME: Possible buffer overflow if s_colors is bigger than pConInfo->Colors. memcpy(Console->Colors, ConsoleInfo->Colors, sizeof(s_Colors)); - // TODO: Really update the screen attributes as FillConsoleOutputAttribute does. - /* Apply cursor size */ ActiveBuffer->CursorInfo.bVisible = (ConsoleInfo->CursorSize != 0); ActiveBuffer->CursorInfo.dwSize = min(max(ConsoleInfo->CursorSize, 0), 100); @@ -537,6 +525,12 @@ ConSrvApplyUserSettings(IN PCONSOLE Console, if (SizeChanged) TermResizeTerminal(Console); } + + /* Apply foreground and background colors for both screen and popup */ + ConDrvChangeScreenBufferAttributes(Console, + Buffer, + ConsoleInfo->ScreenAttrib, + ConsoleInfo->PopupAttrib); } else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) {