From ef4ace3cd7ef00174769731509c84c4a65a515e2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=A9=20van=20Geldorp?= Date: Thu, 17 Jul 2003 07:49:15 +0000 Subject: [PATCH] Changes for multiple window support svn path=/trunk/; revision=5147 --- reactos/apps/tests/multiwin/multiwin.c | 134 ++++++++++--- reactos/include/win32k/region.h | 11 +- reactos/subsys/win32k/include/painting.h | 1 + reactos/subsys/win32k/include/vis.h | 29 +++ reactos/subsys/win32k/makefile | 4 +- reactos/subsys/win32k/ntuser/vis.c | 243 +++++++++++++++++++++++ reactos/subsys/win32k/ntuser/windc.c | 238 ++++------------------ reactos/subsys/win32k/ntuser/window.c | 45 +++-- reactos/subsys/win32k/objects/dc.c | 11 +- reactos/subsys/win32k/objects/region.c | 143 +++++++------ 10 files changed, 546 insertions(+), 313 deletions(-) create mode 100644 reactos/subsys/win32k/include/vis.h create mode 100644 reactos/subsys/win32k/ntuser/vis.c diff --git a/reactos/apps/tests/multiwin/multiwin.c b/reactos/apps/tests/multiwin/multiwin.c index b30021923be..63d95a90069 100644 --- a/reactos/apps/tests/multiwin/multiwin.c +++ b/reactos/apps/tests/multiwin/multiwin.c @@ -1,8 +1,9 @@ #include #include -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; } diff --git a/reactos/include/win32k/region.h b/reactos/include/win32k/region.h index 88da34c0c9f..9673e6d6153 100644 --- a/reactos/include/win32k/region.h +++ b/reactos/include/win32k/region.h @@ -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 diff --git a/reactos/subsys/win32k/include/painting.h b/reactos/subsys/win32k/include/painting.h index 84ff34401fd..177471d9dc6 100644 --- a/reactos/subsys/win32k/include/painting.h +++ b/reactos/subsys/win32k/include/painting.h @@ -5,6 +5,7 @@ #include #include #include +#include /* 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 index 00000000000..6113afca0bd --- /dev/null +++ b/reactos/subsys/win32k/include/vis.h @@ -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 +#include + +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 */ + diff --git a/reactos/subsys/win32k/makefile b/reactos/subsys/win32k/makefile index 440f2afff19..7998e9f3b58 100644 --- a/reactos/subsys/win32k/makefile +++ b/reactos/subsys/win32k/makefile @@ -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 index 00000000000..8c704a68e57 --- /dev/null +++ b/reactos/subsys/win32k/ntuser/vis.c @@ -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 +#include +#include +#include + + +#define NDEBUG +#include +#include + +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 */ diff --git a/reactos/subsys/win32k/ntuser/windc.c b/reactos/subsys/win32k/ntuser/windc.c index 8904fc18247..61b8275cfc2 100644 --- a/reactos/subsys/win32k/ntuser/windc.c +++ b/reactos/subsys/win32k/ntuser/windc.c @@ -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 #include +#include #define NDEBUG #include @@ -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); } } diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index e546dcf2219..2d88f8cf409 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.c @@ -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 #include +#include #define NDEBUG #include @@ -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, diff --git a/reactos/subsys/win32k/objects/dc.c b/reactos/subsys/win32k/objects/dc.c index db9a40ced57..5acab80f959 100644 --- a/reactos/subsys/win32k/objects/dc.c +++ b/reactos/subsys/win32k/objects/dc.c @@ -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; diff --git a/reactos/subsys/win32k/objects/region.c b/reactos/subsys/win32k/objects/region.c index e59fd22e2d8..51a16499ae8 100644 --- a/reactos/subsys/win32k/objects/region.c +++ b/reactos/subsys/win32k/objects/region.c @@ -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 #include @@ -30,7 +30,7 @@ #include #include #include - +#include #define NDEBUG #include @@ -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); } /*! -- 2.17.1