Changes for multiple window support
authorGé van Geldorp <ge@gse.nl>
Thu, 17 Jul 2003 07:49:15 +0000 (07:49 +0000)
committerGé van Geldorp <ge@gse.nl>
Thu, 17 Jul 2003 07:49:15 +0000 (07:49 +0000)
svn path=/trunk/; revision=5147

reactos/apps/tests/multiwin/multiwin.c
reactos/include/win32k/region.h
reactos/subsys/win32k/include/painting.h
reactos/subsys/win32k/include/vis.h [new file with mode: 0644]
reactos/subsys/win32k/makefile
reactos/subsys/win32k/ntuser/vis.c [new file with mode: 0644]
reactos/subsys/win32k/ntuser/windc.c
reactos/subsys/win32k/ntuser/window.c
reactos/subsys/win32k/objects/dc.c
reactos/subsys/win32k/objects/region.c

index b300219..63d95a9 100644 (file)
@@ -1,8 +1,9 @@
 #include <windows.h>
 #include <stdio.h>
 
-HFONT tf;
-LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM);
+static UINT WindowCount;
+LRESULT WINAPI TopLevelWndProc(HWND, UINT, WPARAM, LPARAM);
+LRESULT WINAPI ChildWndProc(HWND, UINT, WPARAM, LPARAM);
 
 int WINAPI 
 WinMain(HINSTANCE hInstance,
@@ -12,11 +13,12 @@ WinMain(HINSTANCE hInstance,
 {
   WNDCLASS wc;
   MSG msg;
-  HWND hWnd;
+  HWND hWnd1;
   HWND hWnd2;
+  HWND hWndChild;
 
-  wc.lpszClassName = "MultiWinClass";
-  wc.lpfnWndProc = MainWndProc;
+  wc.lpszClassName = "TopLevelClass";
+  wc.lpfnWndProc = TopLevelWndProc;
   wc.style = CS_VREDRAW | CS_HREDRAW;
   wc.hInstance = hInstance;
   wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
@@ -32,9 +34,26 @@ WinMain(HINSTANCE hInstance,
       return(1);
     }
 
-  hWnd = CreateWindow("MultiWinClass",
-                     "Window1",
-                     WS_OVERLAPPEDWINDOW|WS_VISIBLE,
+  wc.lpszClassName = "ChildClass";
+  wc.lpfnWndProc = ChildWndProc;
+  wc.style = CS_VREDRAW | CS_HREDRAW;
+  wc.hInstance = hInstance;
+  wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+  wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+  wc.lpszMenuName = NULL;
+  wc.cbClsExtra = 0;
+  wc.cbWndExtra = 0;
+  if (RegisterClass(&wc) == 0)
+    {
+      fprintf(stderr, "RegisterClass failed (last error 0x%X)\n",
+             GetLastError());
+      return(1);
+    }
+
+  hWnd1 = CreateWindow("TopLevelClass",
+                     "TopLevel1",
+                     WS_OVERLAPPEDWINDOW,
                      0,
                      0,
                      320,
@@ -44,9 +63,22 @@ WinMain(HINSTANCE hInstance,
                      hInstance,
                      NULL);
   
-  hWnd2 =   hWnd = CreateWindow("MultiWinClass",
-                     "Window2",
-                     WS_CAPTION|WS_SYSMENU|WS_VISIBLE,
+  hWndChild = CreateWindow("ChildClass",
+                     "Child1 of TopLevel1",
+                     WS_CHILD | WS_BORDER | WS_CAPTION | WS_VISIBLE | WS_SYSMENU,
+                     20,
+                     120,
+                     200,
+                     200,
+                     hWnd1,
+                     NULL,
+                     hInstance,
+                     NULL);
+  
+#ifdef TODO
+  hWnd2 = CreateWindow("TopLevelClass",
+                     "TopLevel2",
+                     WS_OVERLAPPEDWINDOW,
                      400,
                      0,
                      160,
@@ -55,14 +87,29 @@ WinMain(HINSTANCE hInstance,
                      NULL,
                      hInstance,
                      NULL);
+#else
+  hWnd2 = CreateWindow("TopLevelClass",
+                     "TopLevel2",
+                     WS_OVERLAPPEDWINDOW,
+                     400,
+                     0,
+                     160,
+                     490,
+                     NULL,
+                     NULL,
+                     hInstance,
+                     NULL);
+#endif
 
-  if (!hWnd || !hWnd2)
+  if (! hWnd1 || ! hWnd2 || ! hWndChild)
     {
       fprintf(stderr, "CreateWindow failed (last error 0x%X)\n",
              GetLastError());
       return(1);
     }
-  ShowWindow(hWnd, nCmdShow);
+  WindowCount = 2;
+  ShowWindow(hWnd1, SW_NORMAL);
+  ShowWindow(hWnd2, SW_NORMAL);
 
   while(GetMessage(&msg, NULL, 0, 0))
   {
@@ -72,24 +119,47 @@ WinMain(HINSTANCE hInstance,
   return msg.wParam;
 }
 
-LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+LRESULT CALLBACK TopLevelWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+  PAINTSTRUCT ps;
+  HDC hDC;
+
+  switch(msg)
+    {
+      case WM_PAINT:
+       hDC = BeginPaint(hWnd, &ps);
+       EndPaint(hWnd, &ps);
+       break;
+
+      case WM_DESTROY:
+       if (0 == --WindowCount)
+         {
+           PostQuitMessage(0);
+         }
+       break;
+
+      default:
+       return DefWindowProc(hWnd, msg, wParam, lParam);
+    }
+
+  return 0;
+}
+
+LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-       PAINTSTRUCT ps;
-       HDC hDC;
-
-       switch(msg)
-       {
-       case WM_PAINT:
-         hDC = BeginPaint(hWnd, &ps);
-         EndPaint(hWnd, &ps);
-         break;
-
-       case WM_DESTROY:
-         PostQuitMessage(0);
-         break;
-
-       default:
-         return DefWindowProc(hWnd, msg, wParam, lParam);
-       }
-       return 0;
+  PAINTSTRUCT ps;
+  HDC hDC;
+
+  switch(msg)
+    {
+      case WM_PAINT:
+       hDC = BeginPaint(hWnd, &ps);
+       EndPaint(hWnd, &ps);
+       break;
+
+      default:
+       return DefWindowProc(hWnd, msg, wParam, lParam);
+    }
+
+  return 0;
 }
index 88da34c..9673e6d 100644 (file)
@@ -20,7 +20,7 @@ BOOL FASTCALL RGNDATA_InternalDelete( PROSRGNDATA Obj );
 
 /*  User entry points */
 HRGN STDCALL
-W32kUnionRectWithRgn(HRGN hDest, const RECT* Rect);
+W32kUnionRectWithRgn(HRGN hDest, CONST PRECT Rect);
 
 INT
 STDCALL
@@ -150,10 +150,9 @@ W32kGetRegionData(HRGN hrgn,
                                                LPRGNDATA rgndata);
 
 HRGN STDCALL REGION_CropRgn(HRGN hDst, HRGN hSrc, const PRECT lpRect, PPOINT lpPt);
-HRGN STDCALL
-UnsafeW32kCreateRectRgnIndirect(CONST PRECT rc);
-INT STDCALL
-UnsafeW32kGetRgnBox(HRGN  hRgn,
-                   LPRECT  pRect);
+
+HRGN STDCALL UnsafeW32kCreateRectRgnIndirect(CONST PRECT rc);
+INT STDCALL UnsafeW32kGetRgnBox(HRGN  hRgn, LPRECT pRect);
+HRGN FASTCALL UnsafeW32kUnionRectWithRgn(HRGN hDest, CONST PRECT Rect);
 #endif
 
index 84ff344..177471d 100644 (file)
@@ -5,6 +5,7 @@
 #include <ddk/ntddk.h>
 #include <include/class.h>
 #include <include/msgqueue.h>
+#include <include/window.h>
 
 /* PaintRedrawWindow() control flags */
 #define RDW_EX_USEHRGN         0x0001
diff --git a/reactos/subsys/win32k/include/vis.h b/reactos/subsys/win32k/include/vis.h
new file mode 100644 (file)
index 0000000..6113afc
--- /dev/null
@@ -0,0 +1,29 @@
+/* $Id: vis.h,v 1.1 2003/07/17 07:49:15 gvg Exp $
+ *
+ * COPYRIGHT:        See COPYING in the top level directory
+ * PROJECT:          ReactOS Win32k subsystem
+ * PURPOSE:          Visibility computations interface definition
+ * FILE:             include/win32k/vis.h
+ * PROGRAMMER:       Ge van Geldorp (ge@gse.nl)
+ *
+ */
+
+#ifndef _WIN32K_VIS_H
+#define _WIN32K_VIS_H
+
+#include <internal/ex.h>
+#include <include/window.h>
+
+HRGN FASTCALL
+VIS_ComputeVisibleRegion(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
+                         BOOLEAN ClientArea, BOOLEAN ClipChildren,
+                         BOOLEAN ClipSiblings);
+
+VOID FASTCALL
+VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
+                        HRGN UncoveredRgn);
+
+#endif /* ! defined(_WIN32K_VIS_H) */
+
+/* EOF */
+
index 440f2af..7998e9f 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.69 2003/07/12 12:45:29 gvg Exp $
+# $Id: makefile,v 1.70 2003/07/17 07:49:15 gvg Exp $
 
 PATH_TO_TOP = ../..
 
@@ -51,7 +51,7 @@ NTUSER_OBJECTS = ntuser/class.o ntuser/guicheck.o ntuser/hook.o \
                 ntuser/input.o ntuser/keyboard.o ntuser/callback.o \
                 ntuser/winpos.o ntuser/painting.o ntuser/metric.o \
                 ntuser/windc.o ntuser/prop.o ntuser/scrollbar.o \
-                ntuser/timer.o ntuser/misc.o
+                ntuser/timer.o ntuser/misc.o ntuser/vis.o
 
 OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o  \
                   objects/color.o objects/coord.o objects/dc.o  \
diff --git a/reactos/subsys/win32k/ntuser/vis.c b/reactos/subsys/win32k/ntuser/vis.c
new file mode 100644 (file)
index 0000000..8c704a6
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ *  ReactOS W32 Subsystem
+ *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: vis.c,v 1.1 2003/07/17 07:49:15 gvg Exp $
+ *
+ * COPYRIGHT:        See COPYING in the top level directory
+ * PROJECT:          ReactOS kernel
+ * PURPOSE:          Visibility computations
+ * FILE:             subsys/win32k/ntuser/vis.c
+ * PROGRAMMER:       Ge van Geldorp (ge@gse.nl)
+ */
+
+#include <win32k/win32k.h>
+#include <include/painting.h>
+#include <include/rect.h>
+#include <include/vis.h>
+
+
+#define NDEBUG
+#include <win32k/debug1.h>
+#include <debug.h>
+
+BOOL STATIC FASTCALL
+VIS_GetVisRect(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
+               BOOLEAN ClientArea, RECT* Rect)
+{
+  PWINDOW_OBJECT DesktopWindow;
+
+  if (ClientArea)
+    {
+      *Rect = Window->ClientRect;
+    }
+  else
+    {
+      *Rect = Window->WindowRect;
+    }
+
+  if (0 == (Window->Style & WS_VISIBLE))
+    {
+      W32kSetEmptyRect(Rect);
+
+      return FALSE;
+    }
+
+  if (Window->Self == Desktop->DesktopWindow)
+    {
+      return TRUE;
+    }
+
+  if (0 != (Window->Style & WS_CHILD))
+    {
+      do
+       {
+         Window = Window->Parent;
+         if (WS_VISIBLE != (Window->Style & (WS_ICONIC | WS_VISIBLE)))
+           {
+             W32kSetEmptyRect(Rect);
+             return FALSE;
+           }
+         if (! W32kIntersectRect(Rect, Rect, &(Window->ClientRect)))
+           {
+             return FALSE;
+           }
+       }
+      while (0 != (Window->Style & WS_CHILD));
+    }
+
+  DesktopWindow = W32kGetWindowObject(Desktop->DesktopWindow);
+  if (NULL == DesktopWindow)
+    {
+      ASSERT(FALSE);
+      return FALSE;
+    }
+
+  if (! W32kIntersectRect(Rect, Rect, &(DesktopWindow->ClientRect)))
+    {
+      W32kReleaseWindowObject(DesktopWindow);
+      return FALSE;
+    }
+  W32kReleaseWindowObject(DesktopWindow);
+
+  return TRUE;
+}
+
+STATIC BOOL FASTCALL
+VIS_AddClipRects(PWINDOW_OBJECT Parent, PWINDOW_OBJECT End, 
+                HRGN ClipRgn, PRECT Rect)
+{
+  PLIST_ENTRY ChildListEntry;
+  PWINDOW_OBJECT Child;
+  RECT Intersect;
+
+  ExAcquireFastMutexUnsafe(&Parent->ChildrenListLock);
+  ChildListEntry = Parent->ChildrenListHead.Flink;
+  while (ChildListEntry != &Parent->ChildrenListHead)
+    {
+      Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT, 
+                               SiblingListEntry);
+      if (Child == End)
+       {
+         ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock);
+         return TRUE;
+       }
+      if (Child->Style & WS_VISIBLE)
+       {
+         if (W32kIntersectRect(&Intersect, &Child->WindowRect, Rect))
+           {
+             UnsafeW32kUnionRectWithRgn(ClipRgn, &Child->WindowRect);
+           }
+       }
+      ChildListEntry = ChildListEntry->Flink;
+    }
+
+  ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock);
+  return FALSE;
+}
+
+HRGN FASTCALL
+VIS_ComputeVisibleRegion(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
+                         BOOLEAN ClientArea, BOOLEAN ClipChildren,
+                         BOOLEAN ClipSiblings)
+{
+  HRGN VisRgn;
+  RECT Rect;
+  HRGN ClipRgn;
+  PWINDOW_OBJECT DesktopWindow;
+
+  DesktopWindow = W32kGetWindowObject(Desktop->DesktopWindow);
+  if (NULL == DesktopWindow)
+    {
+      ASSERT(FALSE);
+      return NULL;
+    }
+
+  if (VIS_GetVisRect(Desktop, Window, ClientArea, &Rect))
+    {
+      VisRgn = UnsafeW32kCreateRectRgnIndirect(&Rect);
+      if (NULL != VisRgn)
+       {
+         ClipRgn = W32kCreateRectRgn(0, 0, 0, 0);
+
+         if (ClipRgn != NULL)
+           {
+             if (ClipChildren && 
+                 ! IsListEmpty(&Window->ChildrenListHead))
+               {
+                 VIS_AddClipRects(Window, NULL, ClipRgn, &Rect);
+               }
+
+             if (ClipSiblings && 0 != (Window->Style & WS_CHILD))
+               {
+                 VIS_AddClipRects(Window->Parent, Window, ClipRgn, &Rect);
+               }
+             
+             while (0 != (Window->Style & WS_CHILD))
+               {
+                 if (0 != (Window->Style & WS_CLIPSIBLINGS))
+                   {
+                     VIS_AddClipRects(Window->Parent, Window, ClipRgn, &Rect);
+                   }
+                 Window = Window->Parent;
+               }
+
+             VIS_AddClipRects(DesktopWindow, Window, ClipRgn, &Rect);
+
+             W32kCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF);
+             W32kDeleteObject(ClipRgn);
+           }
+         else
+           {
+             W32kDeleteObject(VisRgn);
+             VisRgn = NULL;
+           }
+       }
+    }
+  else
+    {
+      VisRgn = W32kCreateRectRgn(0, 0, 0, 0);
+    }
+
+  W32kReleaseWindowObject(DesktopWindow);
+
+  return VisRgn;
+}
+
+VOID STATIC FASTCALL
+VIS_RepaintDesktop(HWND Desktop, HRGN RepaintRgn)
+{
+  HDC dc = NtUserGetDC(Desktop);
+  HBRUSH DesktopBrush = W32kCreateSolidBrush(RGB(58, 110, 165));
+  W32kFillRgn(dc, RepaintRgn, DesktopBrush);
+  W32kDeleteObject(DesktopBrush);
+  NtUserReleaseDC(Desktop, dc);
+}
+
+
+VOID FASTCALL
+VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
+                        HRGN UncoveredRgn)
+{
+  PWINDOW_OBJECT DesktopWindow;
+  PWINDOW_OBJECT Child;
+  PLIST_ENTRY CurrentEntry;
+  HRGN Uncovered;
+  HRGN Covered;
+
+  DesktopWindow = W32kGetWindowObject(Desktop->DesktopWindow);
+  Uncovered = UnsafeW32kCreateRectRgnIndirect(&DesktopWindow->WindowRect);
+  ExAcquireFastMutexUnsafe(&DesktopWindow->ChildrenListLock);
+  CurrentEntry = DesktopWindow->ChildrenListHead.Flink;
+  while (CurrentEntry != &DesktopWindow->ChildrenListHead)
+    {
+      Child = CONTAINING_RECORD(CurrentEntry, WINDOW_OBJECT, SiblingListEntry);
+      if (0 != (Child->Style & WS_VISIBLE))
+       {
+         Covered = UnsafeW32kCreateRectRgnIndirect(&Child->WindowRect);
+         W32kCombineRgn(Uncovered, Uncovered, Covered, RGN_DIFF);
+         PaintRedrawWindow(Child->Self, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE, 0);
+         W32kDeleteObject(Covered);
+       }
+      CurrentEntry = CurrentEntry->Flink;
+    }
+  ExReleaseFastMutexUnsafe(&DesktopWindow->ChildrenListLock);
+  VIS_RepaintDesktop(DesktopWindow->Self, Uncovered);
+  W32kDeleteObject(Uncovered);
+}
+
+/* EOF */
index 8904fc1..61b8275 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: windc.c,v 1.14 2003/07/11 17:08:44 chorns Exp $
+/* $Id: windc.c,v 1.15 2003/07/17 07:49:15 gvg Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -40,6 +40,7 @@
 #include <include/window.h>
 #include <include/rect.h>
 #include <include/dce.h>
+#include <include/vis.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -53,219 +54,70 @@ static PDCE FirstDce = NULL;
 
 /* FUNCTIONS *****************************************************************/
 
-VOID STATIC FASTCALL
-DceOffsetVisRgn(HDC hDC, HRGN hVisRgn)
-{
-  DC *dc = DC_HandleToPtr(hDC);
-  if (dc == NULL)
-    {
-      return;
-    }
-  W32kOffsetRgn(hVisRgn, dc->w.DCOrgX, dc->w.DCOrgY);
-  DC_ReleasePtr(hDC);
-}
-
-BOOL STATIC STDCALL
-DceGetVisRect(PWINDOW_OBJECT Window, BOOL ClientArea, RECT* Rect)
-{
-  if (ClientArea)
-    {
-      *Rect = Window->ClientRect;
-    }
-  else
-    {
-      *Rect = Window->WindowRect;
-    }
-
-  if (Window->Style & WS_VISIBLE)
-    {
-      INT XOffset = Rect->left;
-      INT YOffset = Rect->top;
-
-      while ((Window = Window->Parent) != NULL)
-       {
-         if ((Window->Style & (WS_ICONIC | WS_VISIBLE)) != WS_VISIBLE)
-           {
-             W32kSetEmptyRect(Rect);
-             return(FALSE);
-           }
-         XOffset += Window->ClientRect.left;
-         YOffset += Window->ClientRect.top;
-         W32kOffsetRect(Rect, Window->ClientRect.left, 
-                        Window->ClientRect.top);
-         if (Window->ClientRect.left >= Window->ClientRect.right ||
-             Window->ClientRect.top >= Window->ClientRect.bottom ||
-             Rect->left >= Window->ClientRect.right ||
-             Rect->right <= Window->ClientRect.left ||
-             Rect->top >= Window->ClientRect.bottom ||
-             Rect->bottom <= Window->ClientRect.top)
-           {
-             W32kSetEmptyRect(Rect);
-             return(FALSE);
-           }
-         Rect->left = max(Rect->left, Window->ClientRect.left);
-         Rect->right = min(Rect->right, Window->ClientRect.right);
-         Rect->top = max(Rect->top, Window->ClientRect.top);
-         Rect->bottom = min(Rect->bottom, Window->ClientRect.bottom);
-       }
-      W32kOffsetRect(Rect, -XOffset, -YOffset);
-      return(TRUE);
-    }
-  W32kSetEmptyRect(Rect);
-  return(FALSE);
-}
-
-BOOL STDCALL
-DceAddClipRects(PWINDOW_OBJECT Parent, PWINDOW_OBJECT End, 
-               HRGN ClipRgn, PRECT Rect, INT XOffset, INT YOffset)
-{
-  PLIST_ENTRY ChildListEntry;
-  PWINDOW_OBJECT Child;
-  RECT Rect1;
-
-
-  ExAcquireFastMutexUnsafe(&Parent->ChildrenListLock);
-  ChildListEntry = Parent->ChildrenListHead.Flink;
-  while (ChildListEntry != &Parent->ChildrenListHead)
-    {
-      Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT, 
-                               SiblingListEntry);
-      if (Child == End)
-       {
-         ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock);
-         return(TRUE);
-       }
-      if (Child->Style & WS_VISIBLE)
-       {
-         Rect1.left = Child->WindowRect.left + XOffset;
-         Rect1.top = Child->WindowRect.top + YOffset;
-         Rect1.right = Child->WindowRect.right + XOffset;
-         Rect1.bottom = Child->WindowRect.bottom + YOffset;
-
-         if (W32kIntersectRect(&Rect1, &Rect1, Rect))
-           {
-             W32kUnionRectWithRgn(ClipRgn, &Rect1);
-           }
-       }
-      ChildListEntry = ChildListEntry->Flink;
-    }
-  ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock);
-  return(FALSE);
-}
-
 HRGN STDCALL
 DceGetVisRgn(HWND hWnd, ULONG Flags, HWND hWndChild, ULONG CFlags)
 {
   PWINDOW_OBJECT Window;
   PWINDOW_OBJECT Child;
   HRGN VisRgn;
-  RECT Rect;
+  HRGN VisChild;
+  HRGN ChildRect;
+  HRGN ParentRect;
 
   Window = W32kGetWindowObject(hWnd);
-  Child = W32kGetWindowObject(hWndChild);
 
-  if (Window != NULL && DceGetVisRect(Window, !(Flags & DCX_WINDOW), &Rect))
+  if (NULL == Window)
     {
-      if ((VisRgn = UnsafeW32kCreateRectRgnIndirect(&Rect)) != NULL)
-       {
-         HRGN ClipRgn = W32kCreateRectRgn(0, 0, 0, 0);
-         INT XOffset, YOffset;
+      return NULL;
+    }
 
-         if (ClipRgn != NULL)
+  VisRgn = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop, Window,
+                                    0 == (Flags & DCX_WINDOW),
+                                    0 != (Flags & DCX_CLIPCHILDREN),
+                                    0 != (Flags & DCX_CLIPSIBLINGS));
+  if (NULL != hWndChild && 0 != (CFlags & DCX_CLIPCHILDREN))
+    {
+      /* We need to filter out the child windows of hWndChild */
+      Child = W32kGetWindowObject(hWnd);
+      if (NULL != Child)
+       {
+         if (! IsListEmpty(&Child->ChildrenListHead))
            {
-             if (Flags & DCX_CLIPCHILDREN && 
-                 !IsListEmpty(&Window->ChildrenListHead))
+             /* Compute the visible region of the child */
+             VisChild = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
+                                                 Child, FALSE, TRUE, FALSE);
+             /* If the child doesn't obscure the whole window, we need to
+                 extend it. First compute the difference between window and child */
+             ChildRect = UnsafeW32kCreateRectRgnIndirect(&(Child->ClientRect));
+             if (0 == (Flags & DCX_WINDOW))
                {
-                 if (Flags & DCX_WINDOW)
-                   {
-                     XOffset = Window->ClientRect.left -
-                       Window->WindowRect.left;
-                     YOffset = Window->ClientRect.top -
-                       Window->WindowRect.top;
-                   }           
-                 else
-                   {
-                     XOffset = YOffset = 0;
-                   }
-                 DceAddClipRects(Window, NULL, ClipRgn, &Rect,
-                                 XOffset, YOffset);
-               }
-
-             if (CFlags & DCX_CLIPCHILDREN && Child &&
-                 !IsListEmpty(&Child->ChildrenListHead))
-               {
-                 if (Flags & DCX_WINDOW)
-                   {
-                     XOffset = Window->ClientRect.left -
-                       Window->WindowRect.left;
-                     YOffset = Window->ClientRect.top -
-                       Window->WindowRect.top;
-                   }
-                 else
-                   {
-                     XOffset = YOffset = 0;
-                   }
-
-                 XOffset += Child->ClientRect.left;
-                 YOffset += Child->ClientRect.top;
-
-                 DceAddClipRects(Child, NULL, ClipRgn, &Rect,
-                                 XOffset, YOffset);
-               }
-
-             if (Flags & DCX_WINDOW)
-               {
-                 XOffset = -Window->WindowRect.left;
-                 YOffset = -Window->WindowRect.top;
+                 ParentRect = UnsafeW32kCreateRectRgnIndirect(&(Window->ClientRect));
                }
              else
                {
-                 XOffset = -Window->ClientRect.left;
-                 YOffset = -Window->ClientRect.top;
+                 ParentRect = UnsafeW32kCreateRectRgnIndirect(&(Window->WindowRect));
                }
+             W32kCombineRgn(ChildRect, ParentRect, ChildRect, RGN_DIFF);
 
-             if (Flags & DCX_CLIPSIBLINGS && Window->Parent != NULL)
-               {
-                 DceAddClipRects(Window->Parent, Window, ClipRgn,
-                                 &Rect, XOffset, YOffset);
-               }
-             
-             while (Window->Style & WS_CHILD)
-               {
-                 Window = Window->Parent;
-                 XOffset -= Window->ClientRect.left;
-                 YOffset -= Window->ClientRect.top;
-                 if (Window->Style & WS_CLIPSIBLINGS && 
-                     Window->Parent != NULL)
-                   {
-                     DceAddClipRects(Window->Parent, Window, ClipRgn,
-                                     &Rect, XOffset, YOffset);
-                   }
-               }
+             /* Now actually extend the child by adding the difference */
+             W32kCombineRgn(VisChild, VisChild, ChildRect, RGN_OR);
 
-             W32kCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF);
-             W32kDeleteObject(ClipRgn);
-           }
-         else
-           {
-             W32kDeleteObject(VisRgn);
-             VisRgn = 0;
+             /* Clip the childs children */
+             W32kCombineRgn(VisRgn, VisRgn, VisChild, RGN_AND);
            }
+         W32kReleaseWindowObject(Child);
        }
     }
-  else
-    {
-      VisRgn = W32kCreateRectRgn(0, 0, 0, 0);
-    }
+
   W32kReleaseWindowObject(Window);
-  W32kReleaseWindowObject(Child);
-  return(VisRgn);
+
+  return VisRgn;
 }
 
 INT STDCALL
 NtUserReleaseDC(HWND hWnd, HDC hDc)
 {
-  
+  return 1;  
 }
 
 HDC STDCALL
@@ -505,19 +357,6 @@ NtUserGetDCEx(HWND hWnd, HANDLE hRegion, ULONG Flags)
                }
              hRgnVisible = DceGetVisRgn(Parent->Self, DcxFlags, 
                                         Window->Self, Flags);
-             if (Flags & DCX_WINDOW)
-               {
-                 W32kOffsetRgn(hRgnVisible,
-                               Parent->WindowRect.left - Window->WindowRect.left,
-                               Parent->WindowRect.top - Window->WindowRect.top);
-               }
-             else
-               {
-                 W32kOffsetRgn(hRgnVisible,
-                               Parent->ClientRect.left - Window->ClientRect.left,
-                               Parent->ClientRect.top - Window->ClientRect.top);
-               }
-             DceOffsetVisRgn(Dce->hDC, hRgnVisible);
            }
          else
            {
@@ -536,7 +375,6 @@ NtUserGetDCEx(HWND hWnd, HANDLE hRegion, ULONG Flags)
          else
            {
              hRgnVisible = DceGetVisRgn(hWnd, Flags, 0, 0);
-             DceOffsetVisRgn(Dce->hDC, hRgnVisible);
            }
        }
 
index e546dcf..2d88f8c 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: window.c,v 1.63 2003/07/11 17:08:44 chorns Exp $
+/* $Id: window.c,v 1.64 2003/07/17 07:49:15 gvg Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -45,6 +45,7 @@
 #include <include/paint.h>
 #include <include/painting.h>
 #include <include/scroll.h>
+#include <include/vis.h>
 
 #define NDEBUG
 #include <win32k/debug1.h>
@@ -298,20 +299,17 @@ W32kGetWindowRect(HWND hWnd, LPRECT Rect)
 {
   PWINDOW_OBJECT WindowObject;
 
-  ASSERT( Rect );
+  ASSERT(NULL != Rect);
 
   WindowObject = W32kGetWindowObject(hWnd);
   if (WindowObject == NULL)
     {
-      return(FALSE);
+      return FALSE;
     }
   *Rect = WindowObject->WindowRect;
-  if (WindowObject->Style & WS_CHILD)
-    {
-      DbgBreakPoint();
-    }
   W32kReleaseWindowObject(WindowObject);
-  return(TRUE);
+
+  return TRUE;
 }
 
 /*!
@@ -326,10 +324,12 @@ NtUserGetWindowRect(HWND hWnd, LPRECT Rect)
   BOOL bRet;
 
   bRet = W32kGetWindowRect(hWnd, &SafeRect);
-  if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT)))){
-    return(FALSE);
-  }
-  return( bRet );
+  if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
+    {
+      return FALSE;
+    }
+
+  return bRet;
 }
 
 /*!
@@ -501,6 +501,27 @@ W32kCreateDesktopWindow(PWINSTATION_OBJECT WindowStation,
   return(Handle);
 }
 
+VOID FASTCALL
+W32kInitDesktopWindow(ULONG Width, ULONG Height)
+{
+  PWINDOW_OBJECT DesktopWindow;
+  HRGN DesktopRgn;
+  
+  DesktopWindow = W32kGetWindowObject(PsGetWin32Thread()->Desktop->DesktopWindow);
+  if (NULL == DesktopWindow)
+    {
+      return;
+    }
+  DesktopWindow->WindowRect.right = Width;
+  DesktopWindow->WindowRect.bottom = Height;
+  DesktopWindow->ClientRect = DesktopWindow->WindowRect;
+
+  DesktopRgn = UnsafeW32kCreateRectRgnIndirect(&(DesktopWindow->WindowRect));
+  VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, DesktopWindow, DesktopRgn);
+  W32kDeleteObject(DesktopRgn);
+  W32kReleaseWindowObject(DesktopWindow);
+}
+
 HWND STDCALL
 NtUserCreateWindowEx(DWORD dwExStyle,
                     PUNICODE_STRING lpClassName,
index db9a40c..5acab80 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: dc.c,v 1.63 2003/07/14 17:36:59 gvg Exp $
+/* $Id: dc.c,v 1.64 2003/07/17 07:49:15 gvg Exp $
  *
  * DC.C - Device context functions
  *
@@ -258,9 +258,11 @@ BOOL STDCALL W32kCreatePrimarySurface(LPCWSTR Driver,
   PGD_ENABLEDRIVER GDEnableDriver;
   DRVENABLEDATA DED;
   PSURFOBJ SurfObj;
+  PSURFGDI SurfGDI;
   UNICODE_STRING DriverFileNames;
   PWSTR CurrentName;
   BOOL GotDriver;
+  extern void FASTCALL W32kInitDesktopWindow(ULONG Width, ULONG Height);
 
   /*  Open the miniport driver  */
   if ((PrimarySurface.DisplayDevice = DRIVER_FindMPDriver(Driver)) == NULL)
@@ -381,6 +383,8 @@ BOOL STDCALL W32kCreatePrimarySurface(LPCWSTR Driver,
 
   SurfObj = (PSURFOBJ)AccessUserObject((ULONG) PrimarySurface.Handle);
   SurfObj->dhpdev = PrimarySurface.PDev;
+  SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) PrimarySurface.Handle);
+  W32kInitDesktopWindow(SurfGDI->SurfObj.sizlBitmap.cx, SurfGDI->SurfObj.sizlBitmap.cy);
 
   return TRUE;
 }
@@ -414,16 +418,17 @@ HDC STDCALL  W32kCreateDC(LPCWSTR  Driver,
   NewDC = DC_HandleToPtr( hNewDC );
   ASSERT( NewDC );
 
-  if (!PrimarySurfaceCreated)
+  if (! PrimarySurfaceCreated)
     {
+      PrimarySurfaceCreated = TRUE;
       if (!W32kCreatePrimarySurface(Driver, Device))
        {
+         PrimarySurfaceCreated = FALSE;
          DC_ReleasePtr( hNewDC );
          DC_FreeDC(hNewDC);
          return  NULL;
        }
     }
-  PrimarySurfaceCreated = TRUE;
   NewDC->DMW = PrimarySurface.DMW;
   NewDC->DevInfo = &PrimarySurface.DevInfo;
   NewDC->GDIInfo = &PrimarySurface.GDIInfo;
index e59fd22..51a1649 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: region.c,v 1.28 2003/07/15 08:55:52 gvg Exp $ */
+/* $Id: region.c,v 1.29 2003/07/17 07:49:15 gvg Exp $ */
 #undef WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <ddk/ntddk.h>
@@ -30,7 +30,7 @@
 #include <include/rect.h>
 #include <include/object.h>
 #include <include/inteng.h>
-
+#include <include/error.h>
 
 #define NDEBUG
 #include <win32k/debug1.h>
@@ -347,7 +347,7 @@ HRGN STDCALL REGION_CropRgn(HRGN hDst, HRGN hSrc, const PRECT lpRect, PPOINT lpP
          Lock[0].hObj = hNewDst;
   }
 
-  GDIOBJ_LockMultipleObj( Lock, 2 );
+  GDIOBJ_LockMultipleObj(Lock, 2);
   rgnDst = Lock[0].pObj;
   objSrc = Lock[1].pObj;
 
@@ -369,7 +369,7 @@ HRGN STDCALL REGION_CropRgn(HRGN hDst, HRGN hSrc, const PRECT lpRect, PPOINT lpP
          }
     }
   }
-  GDIOBJ_UnlockMultipleObj( Lock, 2 );
+  GDIOBJ_UnlockMultipleObj(Lock, 2);
   return hRet;
 }
 
@@ -1011,62 +1011,74 @@ static void FASTCALL REGION_UnionO (ROSRGNDATA *pReg, RECT *r1, RECT *r1End,
 static void FASTCALL REGION_UnionRegion(ROSRGNDATA *newReg, ROSRGNDATA *reg1,
                               ROSRGNDATA *reg2)
 {
-    /*  checks all the simple cases */
-
-    /*
-     * Region 1 and 2 are the same or region 1 is empty
-     */
-    if ( (reg1 == reg2) || (!(reg1->rdh.nCount)) )
+  /*  checks all the simple cases */
+
+  /*
+   * Region 1 and 2 are the same or region 1 is empty
+   */
+  if (reg1 == reg2 || 0 == reg1->rdh.nCount ||
+      reg1->rdh.rcBound.right <= reg1->rdh.rcBound.left ||
+      reg1->rdh.rcBound.bottom <= reg1->rdh.rcBound.top)
     {
-               if (newReg != reg2)
-                   REGION_CopyRegion(newReg, reg2);
-               return;
+      if (newReg != reg2)
+       {
+         REGION_CopyRegion(newReg, reg2);
+       }
+      return;
     }
 
     /*
      * if nothing to union (region 2 empty)
      */
-    if (!(reg2->rdh.nCount))
+  if (0 == reg2->rdh.nCount ||
+      reg2->rdh.rcBound.right <= reg2->rdh.rcBound.left ||
+      reg2->rdh.rcBound.bottom <= reg2->rdh.rcBound.top)
     {
-               if (newReg != reg1)
-                   REGION_CopyRegion(newReg, reg1);
-               return;
+      if (newReg != reg1)
+       {
+         REGION_CopyRegion(newReg, reg1);
+       }
+      return;
     }
 
-    /*
-     * Region 1 completely subsumes region 2
-     */
-    if ((reg1->rdh.nCount == 1) &&
-               (reg1->rdh.rcBound.left <= reg2->rdh.rcBound.left) &&
-               (reg1->rdh.rcBound.top <= reg2->rdh.rcBound.top) &&
-               (reg1->rdh.rcBound.right >= reg2->rdh.rcBound.right) &&
-               (reg1->rdh.rcBound.bottom >= reg2->rdh.rcBound.bottom))
+  /*
+   * Region 1 completely subsumes region 2
+   */
+  if (1 == reg1->rdh.nCount &&
+      reg1->rdh.rcBound.left <= reg2->rdh.rcBound.left &&
+      reg1->rdh.rcBound.top <= reg2->rdh.rcBound.top &&
+      reg2->rdh.rcBound.right <= reg1->rdh.rcBound.right &&
+      reg2->rdh.rcBound.bottom <= reg1->rdh.rcBound.bottom)
     {
-               if (newReg != reg1)
-                   REGION_CopyRegion(newReg, reg1);
-               return;
+      if (newReg != reg1)
+       {
+         REGION_CopyRegion(newReg, reg1);
+       }
+      return;
     }
 
-    /*
-     * Region 2 completely subsumes region 1
-     */
-    if ((reg2->rdh.nCount == 1) &&
-               (reg2->rdh.rcBound.left <= reg1->rdh.rcBound.left) &&
-               (reg2->rdh.rcBound.top <= reg1->rdh.rcBound.top) &&
-               (reg2->rdh.rcBound.right >= reg1->rdh.rcBound.right) &&
-               (reg2->rdh.rcBound.bottom >= reg1->rdh.rcBound.bottom))
+  /*
+   * Region 2 completely subsumes region 1
+   */
+  if (1 == reg2->rdh.nCount &&
+      reg2->rdh.rcBound.left <= reg1->rdh.rcBound.left &&
+      reg2->rdh.rcBound.top <= reg1->rdh.rcBound.top &&
+      reg1->rdh.rcBound.right <= reg2->rdh.rcBound.right &&
+      reg1->rdh.rcBound.bottom <= reg2->rdh.rcBound.bottom)
     {
-               if (newReg != reg2)
-                   REGION_CopyRegion(newReg, reg2);
-               return;
+      if (newReg != reg2)
+       {
+         REGION_CopyRegion(newReg, reg2);
+       }
+      return;
     }
 
-    REGION_RegionOp (newReg, reg1, reg2, REGION_UnionO,
-               REGION_UnionNonO, REGION_UnionNonO);
-    newReg->rdh.rcBound.left = min(reg1->rdh.rcBound.left, reg2->rdh.rcBound.left);
-    newReg->rdh.rcBound.top = min(reg1->rdh.rcBound.top, reg2->rdh.rcBound.top);
-    newReg->rdh.rcBound.right = max(reg1->rdh.rcBound.right, reg2->rdh.rcBound.right);
-    newReg->rdh.rcBound.bottom = max(reg1->rdh.rcBound.bottom, reg2->rdh.rcBound.bottom);
+  REGION_RegionOp(newReg, reg1, reg2, REGION_UnionO,
+                 REGION_UnionNonO, REGION_UnionNonO);
+  newReg->rdh.rcBound.left = min(reg1->rdh.rcBound.left, reg2->rdh.rcBound.left);
+  newReg->rdh.rcBound.top = min(reg1->rdh.rcBound.top, reg2->rdh.rcBound.top);
+  newReg->rdh.rcBound.right = max(reg1->rdh.rcBound.right, reg2->rdh.rcBound.right);
+  newReg->rdh.rcBound.bottom = max(reg1->rdh.rcBound.bottom, reg2->rdh.rcBound.bottom);
 }
 
 /***********************************************************************
@@ -1427,7 +1439,7 @@ W32kCombineRgn(HRGN  hDest,
   GDIMULTILOCK Lock[3] = {{hDest, 0, GO_REGION_MAGIC}, {hSrc1, 0, GO_REGION_MAGIC}, {hSrc2, 0, GO_REGION_MAGIC}};
   PROSRGNDATA destRgn, src1Rgn, src2Rgn;
 
-  GDIOBJ_LockMultipleObj( &Lock, 3 );
+  GDIOBJ_LockMultipleObj(Lock, 3);
 
   destRgn = (PROSRGNDATA) Lock[0].pObj;
   src1Rgn = (PROSRGNDATA) Lock[1].pObj;
@@ -1468,7 +1480,7 @@ W32kCombineRgn(HRGN  hDest,
       DPRINT("W32kCombineRgn: hDest unavailable\n");
          result = ERROR;
   }
-  GDIOBJ_UnlockMultipleObj( &Lock, 3 );
+  GDIOBJ_UnlockMultipleObj(Lock, 3);
   return result;
 }
 
@@ -1923,21 +1935,36 @@ W32kSetRectRgn(HRGN  hRgn,
   return TRUE;
 }
 
-HRGN STDCALL
-W32kUnionRectWithRgn(HRGN hDest, const RECT* unsafeRect)
+HRGN FASTCALL
+UnsafeW32kUnionRectWithRgn(HRGN hDest, CONST PRECT Rect)
 {
-       PRECT pRect;
-       PROSRGNDATA pRgn;
+  PROSRGNDATA pRgn;
+
+  pRgn = RGNDATA_LockRgn(hDest);
+  if (NULL == pRgn)
+    {
+      SetLastWin32Error(ERROR_INVALID_HANDLE);
+      return NULL;
+    }
 
-       if( !NT_SUCCESS( MmCopyFromCaller( pRect, (PRECT)unsafeRect, sizeof( RECT ) ) ) )
-               return NULL;
+  REGION_UnionRectWithRegion(Rect, pRgn);
+  RGNDATA_UnlockRgn(hDest);
 
-       if( !(pRgn = RGNDATA_LockRgn( hDest ) ) )
-               return NULL;
+  return hDest;
+}
+
+HRGN STDCALL
+W32kUnionRectWithRgn(HRGN hDest, CONST PRECT UnsafeRect)
+{
+  RECT SafeRect;
+
+  if (! NT_SUCCESS(MmCopyFromCaller(&SafeRect, UnsafeRect, sizeof(RECT))))
+    {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      return NULL;
+    }
 
-       REGION_UnionRectWithRegion( pRect, pRgn );
-       RGNDATA_UnlockRgn( hDest );
-       return hDest;
+  return UnsafeW32kUnionRectWithRgn(hDest, &SafeRect);
 }
 
 /*!