Commit in reactos/subsys/csrss/win32csr on MAIN
guiconsole.c+109-631.10 -> 1.11
guiconsole.h+2-21.2 -> 1.3
+111-65
2 modified files
- Implemented double buffering for a console windows. Currently the second buffer 
  is a memory bitmap. All screen buffer updates does also write to the bitmap and 
  the screen is updated by invalidating the update region. The previous version 
  has released the screen buffer lock while scrolling up. It is not possible to 
  release the lock while a write to the screen buffer is in progress. If the text 
  output routines are faster, we should change the second buffer from a bitmap 
  to character array.

reactos/subsys/csrss/win32csr
guiconsole.c 1.10 -> 1.11
diff -u -r1.10 -r1.11
--- guiconsole.c	4 Feb 2004 00:05:46 -0000	1.10
+++ guiconsole.c	7 Mar 2004 21:00:11 -0000	1.11
@@ -1,4 +1,4 @@
-/* $Id: guiconsole.c,v 1.10 2004/02/04 00:05:46 gvg Exp $
+/* $Id: guiconsole.c,v 1.11 2004/03/07 21:00:11 hbirr Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -29,6 +29,9 @@
   PWCHAR LineBuffer;
   BOOL CursorBlinkOn;
   BOOL ForceCursorOff;
+  CRITICAL_SECTION Lock;
+  HDC MemoryDC;
+  HBITMAP MemoryBitmap;
 } GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA;
 
 #ifndef WM_APP
@@ -37,8 +40,6 @@
 #define PM_CREATE_CONSOLE  (WM_APP + 1)
 #define PM_DESTROY_CONSOLE (WM_APP + 2)
 
-#define PM_COPY_REGION     (WM_APP + 100)
-
 #define CURSOR_BLINK_TIME 500
 
 static BOOL Initialized = FALSE;
@@ -62,8 +63,9 @@
   HDC Dc;
   HFONT OldFont;
   TEXTMETRICW Metrics;
+  NTSTATUS Status;
 
-  GuiData = HeapAlloc(Win32CsrApiHeap, 0,
+  GuiData = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY,
                       sizeof(GUI_CONSOLE_DATA) +
                       (Console->Size.X + 1) * sizeof(WCHAR));
   if (NULL == GuiData)
@@ -71,6 +73,15 @@
       DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n");
       return FALSE;
     }
+
+  Status = RtlInitializeCriticalSection(&GuiData->Lock);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT1("RtlInitializeCriticalSection failed, Status=%x\n", Status);
+      HeapFree(Win32CsrApiHeap, 0, GuiData);
+      return FALSE;
+    }
+
   GuiData->LineBuffer = (PWCHAR)(GuiData + 1);
 
   GuiData->Font = CreateFontW(12, 0, 0, TA_BASELINE, FW_NORMAL,
@@ -81,6 +92,7 @@
   if (NULL == GuiData->Font)
     {
       DPRINT1("GuiConsoleNcCreate: CreateFont failed\n");
+      RtlDeleteCriticalSection(&GuiData->Lock);
       HeapFree(Win32CsrApiHeap, 0, GuiData);
       return FALSE;
     }
@@ -88,6 +100,8 @@
   if (NULL == Dc)
     {
       DPRINT1("GuiConsoleNcCreate: GetDC failed\n");
+      DeleteObject(GuiData->Font);
+      RtlDeleteCriticalSection(&GuiData->Lock);
       HeapFree(Win32CsrApiHeap, 0, GuiData);
       return FALSE;
     }
@@ -96,6 +110,8 @@
     {
       DPRINT1("GuiConsoleNcCreate: SelectObject failed\n");
       ReleaseDC(hWnd, Dc);
+      DeleteObject(GuiData->Font);
+      RtlDeleteCriticalSection(&GuiData->Lock);
       HeapFree(Win32CsrApiHeap, 0, GuiData);
       return FALSE;
     }
@@ -104,12 +120,23 @@
       DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n");
       SelectObject(Dc, OldFont);
       ReleaseDC(hWnd, Dc);
+      DeleteObject(GuiData->Font);
+      RtlDeleteCriticalSection(&GuiData->Lock);
       HeapFree(Win32CsrApiHeap, 0, GuiData);
       return FALSE;
     }
   GuiData->CharWidth = Metrics.tmMaxCharWidth;
   GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading;
   SelectObject(Dc, OldFont);
+
+  GuiData->MemoryDC = CreateCompatibleDC(Dc);
+  GuiData->MemoryBitmap = CreateCompatibleBitmap(Dc, 
+                                                 Console->Size.X * GuiData->CharWidth, 
+						 Console->Size.Y * GuiData->CharHeight);
+  DeleteObject(SelectObject(GuiData->MemoryDC, GuiData->MemoryBitmap));
+  DeleteObject(SelectObject(GuiData->MemoryDC, GuiData->Font));
+
+
   ReleaseDC(hWnd, Dc);
   GuiData->CursorBlinkOn = TRUE;
   GuiData->ForceCursorOff = FALSE;
@@ -161,17 +188,15 @@
     }
 }
 
-static VOID FASTCALL
-GuiConsoleHandlePaint(HWND hWnd)
+VOID FASTCALL
+GuiConsoleUpdateBitmap(HWND hWnd, RECT rc)
 {
-  PAINTSTRUCT Ps;
-  HDC Dc;
   PCSRSS_CONSOLE Console;
   PGUI_CONSOLE_DATA GuiData;
   PCSRSS_SCREEN_BUFFER Buff;
-  unsigned TopLine, BottomLine, LeftChar, RightChar;
-  unsigned Line, Char, Start;
-  HFONT OldFont;
+  HDC Dc;
+  ULONG TopLine, BottomLine, LeftChar, RightChar;
+  ULONG Line, Char, Start;
   PBYTE From;
   PWCHAR To;
   BYTE LastAttribute, Attribute;
@@ -182,23 +207,24 @@
   if (NULL != Console && NULL != GuiData && NULL != Console->ActiveBuffer)
     {
       Buff = Console->ActiveBuffer;
-      EnterCriticalSection(&(Buff->Header.Lock));
-
-      Dc = BeginPaint(hWnd, &Ps);
-      if (Ps.rcPaint.right <= Ps.rcPaint.left || Ps.rcPaint.bottom <= Ps.rcPaint.top)
+      EnterCriticalSection(&Buff->Header.Lock);
+      Dc = GetDC(hWnd);
+      if (rc.right <= rc.left || rc.bottom <= rc.top)
         {
-          EndPaint(hWnd, &Ps);
-          LeaveCriticalSection(&(Buff->Header.Lock));
+          ReleaseDC(hWnd, Dc);
+          LeaveCriticalSection(&Buff->Header.Lock);
           return;
         }
-      OldFont = SelectObject(Dc, GuiData->Font);
 
-      TopLine = Ps.rcPaint.top / GuiData->CharHeight;
-      BottomLine = (Ps.rcPaint.bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1;
-      LeftChar = Ps.rcPaint.left / GuiData->CharWidth;
-      RightChar = (Ps.rcPaint.right + (GuiData->CharWidth - 1)) / GuiData->CharWidth - 1;
+      EnterCriticalSection(&GuiData->Lock);
+
+      TopLine = rc.top / GuiData->CharHeight;
+      BottomLine = (rc.bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1;
+      LeftChar = rc.left / GuiData->CharWidth;
+      RightChar = (rc.right + (GuiData->CharWidth - 1)) / GuiData->CharWidth - 1;
       LastAttribute = Buff->Buffer[(TopLine * Buff->MaxX + LeftChar) * 2 + 1];
-      GuiConsoleSetTextColors(Dc, LastAttribute);
+      GuiConsoleSetTextColors(GuiData->MemoryDC, LastAttribute);
+
       for (Line = TopLine; Line <= BottomLine; Line++)
         {
           if (Line + Buff->ShowY < Buff->MaxY)
@@ -217,14 +243,14 @@
             {
               if (*(From + 1) != Attribute)
                 {
-                  TextOutW(Dc, Start * GuiData->CharWidth, Line * GuiData->CharHeight,
+                  TextOutW(GuiData->MemoryDC, Start * GuiData->CharWidth, Line * GuiData->CharHeight,
                            GuiData->LineBuffer, Char - Start);
                   Start = Char;
                   To = GuiData->LineBuffer;
                   Attribute = *(From + 1);
                   if (Attribute != LastAttribute)
                     {
-                      GuiConsoleSetTextColors(Dc, Attribute);
+                      GuiConsoleSetTextColors(GuiData->MemoryDC, Attribute);
                       LastAttribute = Attribute;
                     }
                 }  
@@ -233,12 +259,10 @@
               To++;
               From += 2;
             }
-          TextOutW(Dc, Start * GuiData->CharWidth, Line * GuiData->CharHeight,
+          TextOutW(GuiData->MemoryDC, Start * GuiData->CharWidth, Line * GuiData->CharHeight,
                    GuiData->LineBuffer, RightChar - Start + 1);
         }
 
-      SelectObject(Dc, OldFont);
-
       if (Buff->CursorInfo.bVisible && GuiData->CursorBlinkOn
           &&! GuiData->ForceCursorOff)
         {
@@ -253,22 +277,47 @@
                 }
               From = Buff->Buffer + (Buff->CurrentY * Buff->MaxX + Buff->CurrentX) * 2 + 1;
               CursorBrush = CreateSolidBrush(GuiConsoleRGBFromAttribute(*From));
-              OldBrush = SelectObject(Dc, CursorBrush);
-              PatBlt(Dc, CursorX * GuiData->CharWidth,
+              OldBrush = SelectObject(GuiData->MemoryDC, CursorBrush);
+              PatBlt(GuiData->MemoryDC, CursorX * GuiData->CharWidth,
                      CursorY * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight),
                      GuiData->CharWidth, CursorHeight, PATCOPY);
-              SelectObject(Dc, OldBrush);
+              SelectObject(GuiData->MemoryDC, OldBrush);
               DeleteObject(CursorBrush);
             }
         }
-      EndPaint(hWnd, &Ps);
 
-      LeaveCriticalSection(&(Buff->Header.Lock));
+      LeaveCriticalSection(&GuiData->Lock);
+      ReleaseDC(hWnd, Dc);
+      LeaveCriticalSection(&Buff->Header.Lock);
+      InvalidateRect(hWnd, &rc, FALSE);
+   }
+
+}
+
+VOID FASTCALL
+GuiConsoleHandlePaint(HWND hWnd)
+{
+  PAINTSTRUCT Ps;
+  HDC Dc;
+  PCSRSS_CONSOLE Console;
+  PGUI_CONSOLE_DATA GuiData;
+
+  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+  if (NULL != Console && NULL != GuiData)
+    {
+      EnterCriticalSection(&GuiData->Lock);
+      Dc = BeginPaint (hWnd, &Ps);
+      BitBlt(Dc, Ps.rcPaint.left, Ps.rcPaint.top,
+             Ps.rcPaint.right - Ps.rcPaint.left + 1,
+             Ps.rcPaint.bottom - Ps.rcPaint.top + 1, GuiData->MemoryDC,
+             Ps.rcPaint.left, Ps.rcPaint.top, SRCCOPY);
+      EndPaint (hWnd, &Ps);
+      LeaveCriticalSection(&GuiData->Lock);
     }
   else
     {
-      Dc = BeginPaint(hWnd, &Ps);
-      EndPaint(hWnd, &Ps);
+      Dc = BeginPaint (hWnd, &Ps);
+      EndPaint (hWnd, &Ps);
     }
 }
 
@@ -289,25 +338,6 @@
 }
 
 static VOID FASTCALL
-GuiConsoleHandleCopyRegion(HWND hWnd, PRECT Source, PRECT Dest)
-{
-  RECT ClientRect, ScrollRect;
-  PGUI_CONSOLE_DATA GuiData;
-  PCSRSS_CONSOLE Console;
-
-  GetClientRect(hWnd, &ClientRect);
-  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
-  ScrollRect.left = min(Source->left, Dest->left) * GuiData->CharWidth;
-  ScrollRect.top = min(Source->top, Dest->top) * GuiData->CharHeight;
-  ScrollRect.right = max(Source->right, Dest->right) * GuiData->CharWidth;
-  ScrollRect.bottom = max(Source->bottom, Dest->bottom) * GuiData->CharHeight;
-  ScrollWindow(hWnd,
-    (Dest->left - Source->left) * GuiData->CharWidth,
-    (Dest->top - Source->top) * GuiData->CharHeight,
-    &ScrollRect, &ClientRect);
-}
-
-static VOID FASTCALL
 GuiIntDrawRegion(PGUI_CONSOLE_DATA GuiData, HWND Wnd, RECT *Region)
 {
   RECT RegionRect;
@@ -317,7 +347,7 @@
   RegionRect.right = (Region->right + 1) * GuiData->CharWidth;
   RegionRect.bottom = (Region->bottom + 1) * GuiData->CharHeight;
 
-  InvalidateRect(Wnd, &RegionRect, FALSE);
+  GuiConsoleUpdateBitmap(Wnd, RegionRect);
 }
 
 static VOID STDCALL
@@ -371,7 +401,7 @@
       Dest.right = Console->Size.X - 1;
       Dest.bottom = Region->top - 1;
 
-      GuiConsoleCopyRegion(Console, &Source, &Dest);
+      GuiConsoleCopyRegion(Console->hWindow, &Source, &Dest);
     }
 
   GuiIntDrawRegion(GuiData, Console->hWindow, Region);
@@ -467,6 +497,8 @@
   GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
   KillTimer(hWnd, 1);
   Console->PrivateData = NULL;
+  DeleteDC(GuiData->MemoryDC);
+  RtlDeleteCriticalSection(&GuiData->Lock);
   HeapFree(Win32CsrApiHeap, 0, GuiData);
 }
 
@@ -496,9 +528,6 @@
         GuiConsoleHandleTimer(hWnd);
         Result = 0;
         break;
-      case PM_COPY_REGION:
-        GuiConsoleHandleCopyRegion(hWnd, (PRECT) wParam, (PRECT) lParam);
-        break;
       case WM_CLOSE:
         GuiConsoleHandleClose(hWnd);
         Result = 0;
@@ -744,6 +773,7 @@
           DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n");
           return STATUS_UNSUCCESSFUL;
         }
+      SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST);
       CloseHandle(ThreadHandle);
 
       WaitForSingleObject(GraphicsStartupEvent, INFINITE);
@@ -762,13 +792,29 @@
 }
 
 VOID STDCALL
-GuiConsoleCopyRegion(PCSRSS_CONSOLE Console,
+GuiConsoleCopyRegion(HWND hWnd,
                      RECT *Source,
                      RECT *Dest)
 {
-  LeaveCriticalSection(&(Console->ActiveBuffer->Header.Lock));
-  SendMessageW(Console->hWindow, PM_COPY_REGION, (WPARAM) Source, (LPARAM) Dest);
-  EnterCriticalSection(&(Console->ActiveBuffer->Header.Lock));
+  RECT ScrollRect;
+  PGUI_CONSOLE_DATA GuiData;
+  PCSRSS_CONSOLE Console;
+
+
+  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+
+  ScrollRect.left = Dest->left * GuiData->CharWidth;
+  ScrollRect.right = (Dest->right + 1) * GuiData->CharWidth;
+  ScrollRect.top = Dest->top * GuiData->CharHeight;
+  ScrollRect.bottom = (Dest->bottom + 1) * GuiData->CharHeight;
+  EnterCriticalSection(&GuiData->Lock);
+  BitBlt(GuiData->MemoryDC, ScrollRect.left, ScrollRect.top, 
+         ScrollRect.right - ScrollRect.left, ScrollRect.bottom - ScrollRect.top,
+	 GuiData->MemoryDC, Source->left * GuiData->CharWidth, Source->top * GuiData->CharHeight, SRCCOPY);
+
+  LeaveCriticalSection(&GuiData->Lock);
+
+  InvalidateRect(hWnd, &ScrollRect, FALSE);
 }
 
 /* EOF */

reactos/subsys/csrss/win32csr
guiconsole.h 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- guiconsole.h	11 Jan 2004 17:31:16 -0000	1.2
+++ guiconsole.h	7 Mar 2004 21:00:11 -0000	1.3
@@ -1,4 +1,4 @@
-/* $Id: guiconsole.h,v 1.2 2004/01/11 17:31:16 gvg Exp $
+/* $Id: guiconsole.h,v 1.3 2004/03/07 21:00:11 hbirr Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -10,7 +10,7 @@
 
 extern NTSTATUS FASTCALL GuiInitConsole(PCSRSS_CONSOLE Console);
 extern VOID STDCALL GuiConsoleDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT Region);
-extern VOID STDCALL GuiConsoleCopyRegion(PCSRSS_CONSOLE Console,
+extern VOID STDCALL GuiConsoleCopyRegion(HWND hWnd,
                                          RECT *Source,
                                          RECT *Dest);
 extern VOID STDCALL GuiConsoleChangeTitle(PCSRSS_CONSOLE Console);
CVSspam 0.2.8