[CONSRV]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 15 Mar 2014 17:15:23 +0000 (17:15 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 15 Mar 2014 17:15:23 +0000 (17:15 +0000)
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

reactos/win32ss/user/winsrv/consrv/condrv/text.c
reactos/win32ss/user/winsrv/consrv/settings.c

index 5c1ab10..afe3afe 100644 (file)
@@ -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);
     }
index f765e85..1775d1d 100644 (file)
@@ -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)
     {