Limit selection to window border
[reactos.git] / reactos / subsys / csrss / win32csr / guiconsole.c
index b0e1949..933959f 100644 (file)
@@ -360,65 +360,56 @@ GuiConsolePaint(PCSRSS_CONSOLE Console,
 static VOID FASTCALL
 GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint)
 {
 static VOID FASTCALL
 GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint)
 {
-    RECT rcUpdate;
     HDC hDC;
     PAINTSTRUCT ps;
     PCSRSS_CONSOLE Console;
     PGUI_CONSOLE_DATA GuiData;
 
     HDC hDC;
     PAINTSTRUCT ps;
     PCSRSS_CONSOLE Console;
     PGUI_CONSOLE_DATA GuiData;
 
-    if (GetUpdateRect(hWnd,
-                      &rcUpdate,
-                      FALSE))
+    hDC = BeginPaint(hWnd, &ps);
+    if (hDC != NULL &&
+        ps.rcPaint.left < ps.rcPaint.right &&
+        ps.rcPaint.top < ps.rcPaint.bottom)
     {
     {
-        hDC = (hDCPaint != NULL ? hDCPaint : BeginPaint(hWnd,
-                                                        &ps));
-        if (hDC != NULL)
+        GuiConsoleGetDataPointers(hWnd,
+                                  &Console,
+                                  &GuiData);
+        if (Console != NULL && GuiData != NULL &&
+            Console->ActiveBuffer != NULL)
         {
         {
-            GuiConsoleGetDataPointers(hWnd,
-                                      &Console,
-                                      &GuiData);
-            if (Console != NULL && GuiData != NULL &&
-                Console->ActiveBuffer != NULL)
+            EnterCriticalSection(&GuiData->Lock);
+
+            GuiConsolePaint(Console,
+                            GuiData,
+                            hDC,
+                            &ps.rcPaint);
+
+            if (GuiData->Selection.left != -1)
             {
             {
-                EnterCriticalSection(&GuiData->Lock);
+                RECT rc = GuiData->Selection;
 
 
-                GuiConsolePaint(Console,
-                                GuiData,
-                                hDC,
-                                &rcUpdate);
+                rc.left *= GuiData->CharWidth;
+                rc.top *= GuiData->CharHeight;
+                rc.right *= GuiData->CharWidth;
+                rc.bottom *= GuiData->CharHeight;
 
 
-                if (GuiData->Selection.left != -1)
+                /* invert the selection */
+                if (IntersectRect(&rc,
+                                  &ps.rcPaint,
+                                  &rc))
                 {
                 {
-                    RECT rc = GuiData->Selection;
-
-                    rc.left *= GuiData->CharWidth;
-                    rc.top *= GuiData->CharHeight;
-                    rc.right *= GuiData->CharWidth;
-                    rc.bottom *= GuiData->CharHeight;
-
-                    /* invert the selection */
-                    if (IntersectRect(&rc,
-                                      &rcUpdate,
-                                      &rc))
-                    {
-                        PatBlt(hDC,
-                               rc.left,
-                               rc.top,
-                               rc.right - rc.left,
-                               rc.bottom - rc.top,
-                               DSTINVERT);
-                    }
+                    PatBlt(hDC,
+                           rc.left,
+                           rc.top,
+                           rc.right - rc.left,
+                           rc.bottom - rc.top,
+                           DSTINVERT);
                 }
                 }
-
-                LeaveCriticalSection(&GuiData->Lock);
             }
 
             }
 
-            if (hDCPaint == NULL)
-            {
-                EndPaint(hWnd,
-                         &ps);
-            }
+            LeaveCriticalSection(&GuiData->Lock);
         }
         }
+
+        EndPaint(hWnd, &ps);
     }
 }
 
     }
 }
 
@@ -488,7 +479,7 @@ GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG Cur
   PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
   PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
   LONG CursorEndX, CursorEndY;
   PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
   PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
   LONG CursorEndX, CursorEndY;
-  RECT Source, ScrollRect;
+  RECT ScrollRect;
 
   if (NULL == Console->hWindow || NULL == GuiData)
     {
 
   if (NULL == Console->hWindow || NULL == GuiData)
     {
@@ -497,16 +488,38 @@ GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG Cur
 
   if (0 != ScrolledLines)
     {
 
   if (0 != ScrolledLines)
     {
-      Source.left = 0;
-      Source.top = ScrolledLines;
-      Source.right = Console->Size.X - 1;
-      Source.bottom = ScrolledLines + Region->top - 1;
       ScrollRect.left = 0;
       ScrollRect.top = 0;
       ScrollRect.right = Console->Size.X * GuiData->CharWidth;
       ScrollRect.bottom = Region->top * GuiData->CharHeight;
 
       ScrollRect.left = 0;
       ScrollRect.top = 0;
       ScrollRect.right = Console->Size.X * GuiData->CharWidth;
       ScrollRect.bottom = Region->top * GuiData->CharHeight;
 
-      InvalidateRect(Console->hWindow, &ScrollRect, FALSE);
+      if (GuiData->Selection.left != -1)
+      {
+          /* scroll the selection */
+          if (GuiData->Selection.top > ScrolledLines)
+          {
+              GuiData->Selection.top -= ScrolledLines;
+              GuiData->Selection.bottom -= ScrolledLines;
+          }
+          else if (GuiData->Selection.bottom < ScrolledLines)
+          {
+              GuiData->Selection.left = -1;
+          }
+          else
+          {
+              GuiData->Selection.top = 0;
+              GuiData->Selection.bottom -= ScrolledLines;
+          }
+      }
+
+      ScrollWindowEx(Console->hWindow,
+                     0,
+                     -(ScrolledLines * GuiData->CharHeight),
+                     &ScrollRect,
+                     NULL,
+                     NULL,
+                     NULL,
+                     SW_INVALIDATE);
     }
 
   GuiIntDrawRegion(GuiData, Console->hWindow, Region);
     }
 
   GuiIntDrawRegion(GuiData, Console->hWindow, Region);
@@ -712,7 +725,15 @@ GuiConsoleMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
   rc.left = GuiData->SelectionStart.x;
   rc.top = GuiData->SelectionStart.y;
   rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0);
   rc.left = GuiData->SelectionStart.x;
   rc.top = GuiData->SelectionStart.y;
   rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0);
+  if (Console->Size.X < rc.right)
+  {
+    rc.right = Console->Size.X;
+  }
   rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0);
   rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0);
+  if (Console->Size.Y < rc.bottom)
+  {
+    rc.bottom = Console->Size.Y;
+  }
 
   /* exchange left/top with right/bottom if required */
   if(rc.left >= rc.right)
 
   /* exchange left/top with right/bottom if required */
   if(rc.left >= rc.right)