From b13d239f87305a052ad0bdceb07dfd5c8b99a6c3 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Tue, 24 Feb 2004 01:30:58 +0000 Subject: [PATCH] 1. get rid of winlock.c 2. changed the Parent and Object field of the WINDOW_OBJECT structure to HANDLE for easier maintainance and serialize any access to them svn path=/trunk/; revision=8346 --- reactos/subsys/win32k/include/window.h | 77 +-- reactos/subsys/win32k/main/dllmain.c | 4 +- reactos/subsys/win32k/makefile | 5 +- reactos/subsys/win32k/misc/object.c | 17 +- reactos/subsys/win32k/ntuser/focus.c | 33 +- reactos/subsys/win32k/ntuser/message.c | 12 +- reactos/subsys/win32k/ntuser/msgqueue.c | 15 +- reactos/subsys/win32k/ntuser/painting.c | 40 +- reactos/subsys/win32k/ntuser/vis.c | 28 +- reactos/subsys/win32k/ntuser/windc.c | 24 +- reactos/subsys/win32k/ntuser/window.c | 708 +++++++++++------------- reactos/subsys/win32k/ntuser/winlock.c | 126 ----- reactos/subsys/win32k/ntuser/winpos.c | 293 ++++++---- 13 files changed, 639 insertions(+), 743 deletions(-) delete mode 100644 reactos/subsys/win32k/ntuser/winlock.c diff --git a/reactos/subsys/win32k/include/window.h b/reactos/subsys/win32k/include/window.h index bcc22d276c6..09d3a851310 100644 --- a/reactos/subsys/win32k/include/window.h +++ b/reactos/subsys/win32k/include/window.h @@ -7,6 +7,7 @@ typedef struct _WINDOW_OBJECT *PWINDOW_OBJECT; #include #include +#include #include #include #include @@ -63,18 +64,18 @@ typedef struct _WINDOW_OBJECT FAST_MUTEX UpdateLock; /* Pointer to the owning thread's message queue. */ PUSER_MESSAGE_QUEUE MessageQueue; + /* Lock for the list of child windows. */ + FAST_MUTEX RelativesLock; struct _WINDOW_OBJECT* FirstChild; struct _WINDOW_OBJECT* LastChild; - /* Lock for the list of child windows. */ - FAST_MUTEX ChildrenListLock; struct _WINDOW_OBJECT* NextSibling; struct _WINDOW_OBJECT* PrevSibling; /* Entry in the list of thread windows. */ LIST_ENTRY ThreadListEntry; /* Pointer to the parent window. */ - struct _WINDOW_OBJECT* Parent; + HANDLE Parent; /* Pointer to the owner window. */ - struct _WINDOW_OBJECT* Owner; + HANDLE Owner; /* DC Entries (DCE) */ PDCE Dce; /* Property list head.*/ @@ -101,9 +102,40 @@ typedef struct _WINDOW_OBJECT #define WINDOWOBJECT_NEED_INTERNALPAINT (0x00000008) #define WINDOWOBJECT_RESTOREMAX (0x00000020) -inline BOOL IntIsDesktopWindow(PWINDOW_OBJECT WindowObject); +#define IntIsDesktopWindow(WndObj) \ + (WndObj->Parent == NULL) -inline BOOL IntIsBroadcastHwnd(HWND hwnd); +#define IntIsBroadcastHwnd(hWnd) \ + (hWnd == HWND_BROADCAST || hWnd == HWND_TOPMOST) + +#define IntGetWindowObject(hWnd) \ + IntGetProcessWindowObject(PsGetWin32Process(), hWnd) + +#define IntReferenceWindowObject(WndObj) \ + ObmReferenceObjectByPointer(WndObj, otWindow) + +#define IntReleaseWindowObject(WndObj) \ + ObmDereferenceObject(WndObj) + +#define IntWndBelongsToThread(WndObj, W32Thread) \ + (((WndObj->OwnerThread && WndObj->OwnerThread->Win32Thread)) && \ + (WndObj->OwnerThread->Win32Thread == W32Thread)) + +#define IntGetWndThreadId(WndObj) \ + WndObj->OwnerThread->Cid.UniqueThread + +#define IntGetWndProcessId(WndObj) \ + WndObj->OwnerThread->ThreadsProcess->UniqueProcessId + +#define IntLockRelatives(WndObj) \ + ExAcquireFastMutexUnsafe(&WndObj->RelativesLock) + +#define IntUnLockRelatives(WndObj) \ + ExReleaseFastMutexUnsafe(&WndObj->RelativesLock) + + +PWINDOW_OBJECT FASTCALL +IntGetProcessWindowObject(PW32PROCESS ProcessData, HWND hWnd); BOOL FASTCALL IntIsWindow(HWND hWnd); @@ -111,9 +143,6 @@ IntIsWindow(HWND hWnd); HWND* FASTCALL IntWinListChildren(PWINDOW_OBJECT Window); -BOOLEAN FASTCALL -IntWndBelongsToThread(PWINDOW_OBJECT Window, PW32THREAD ThreadData); - NTSTATUS FASTCALL InitWindowImpl (VOID); @@ -123,17 +152,11 @@ CleanupWindowImpl (VOID); VOID FASTCALL IntGetClientRect (PWINDOW_OBJECT WindowObject, PRECT Rect); -PWINDOW_OBJECT FASTCALL -IntGetWindowObject (HWND hWnd); - -VOID FASTCALL -IntReleaseWindowObject (PWINDOW_OBJECT Window); - HWND FASTCALL IntGetActiveWindow (VOID); BOOL FASTCALL -IntIsWindowVisible (HWND Wnd); +IntIsWindowVisible (HWND hWnd); BOOL FASTCALL IntIsChildWindow (HWND Parent, HWND Child); @@ -144,9 +167,6 @@ IntSetProp(PWINDOW_OBJECT Wnd, ATOM Atom, HANDLE Data); PPROPERTY FASTCALL IntGetProp(PWINDOW_OBJECT WindowObject, ATOM Atom); -DWORD FASTCALL -IntGetWindowThreadProcessId(PWINDOW_OBJECT Wnd, PDWORD pid); - VOID FASTCALL IntUnlinkWindow(PWINDOW_OBJECT Wnd); @@ -159,24 +179,9 @@ IntGetAncestor(PWINDOW_OBJECT Wnd, UINT Type); PWINDOW_OBJECT FASTCALL IntGetParent(PWINDOW_OBJECT Wnd); -typedef enum _WINLOCK_TYPE -{ - None, - Any, - Shared, - Exclusive -} WINLOCK_TYPE; +PWINDOW_OBJECT FASTCALL +IntGetParentObject(PWINDOW_OBJECT Wnd); -#define ASSERT_WINLOCK(a) assert(IntVerifyWinLock(a)) - -inline VOID IntAcquireWinLockShared(); -inline VOID IntAcquireWinLockExclusive(); -inline VOID IntReleaseWinLock(); -BOOL FASTCALL IntVerifyWinLock(WINLOCK_TYPE Type); -WINLOCK_TYPE FASTCALL IntSuspendWinLock(); -VOID FASTCALL IntRestoreWinLock(WINLOCK_TYPE Type); -inline BOOL IntInitializeWinLock(); -inline VOID IntDeleteWinLock(); DWORD IntRemoveWndProcHandle(WNDPROC Handle); DWORD IntRemoveProcessWndProcHandles(HANDLE ProcessID); DWORD IntAddWndProcHandle(WNDPROC WindowProc, BOOL IsUnicode); diff --git a/reactos/subsys/win32k/main/dllmain.c b/reactos/subsys/win32k/main/dllmain.c index 95ab484902c..13d37e615bf 100644 --- a/reactos/subsys/win32k/main/dllmain.c +++ b/reactos/subsys/win32k/main/dllmain.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: dllmain.c,v 1.66 2004/02/05 20:09:10 gvg Exp $ +/* $Id: dllmain.c,v 1.67 2004/02/24 01:30:57 weiden Exp $ * * Entry Point for win32k.sys */ @@ -194,8 +194,6 @@ DllMain ( NTSTATUS Status; BOOLEAN Result; - IntInitializeWinLock(); - /* * Register user mode call interface * (system service table index = 1) diff --git a/reactos/subsys/win32k/makefile b/reactos/subsys/win32k/makefile index a99cbc05316..1a52e0eddfe 100644 --- a/reactos/subsys/win32k/makefile +++ b/reactos/subsys/win32k/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.93 2004/02/19 06:59:50 arty Exp $ +# $Id: makefile,v 1.94 2004/02/24 01:30:57 weiden Exp $ PATH_TO_TOP = ../.. @@ -56,8 +56,7 @@ NTUSER_OBJECTS = ntuser/accelerator.o ntuser/callback.o ntuser/caret.o ntuser/cl ntuser/menu.o ntuser/message.o ntuser/metric.o ntuser/misc.o \ ntuser/msgqueue.o ntuser/painting.o ntuser/prop.o ntuser/scrollbar.o \ ntuser/stubs.o ntuser/timer.o ntuser/useratom.o ntuser/vis.o \ - ntuser/windc.o ntuser/window.o ntuser/winlock.o ntuser/winpos.o \ - ntuser/winsta.o + ntuser/windc.o ntuser/window.o ntuser/winpos.o ntuser/winsta.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/misc/object.c b/reactos/subsys/win32k/misc/object.c index 95b36e9dcf7..35b093aea82 100644 --- a/reactos/subsys/win32k/misc/object.c +++ b/reactos/subsys/win32k/misc/object.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: object.c,v 1.8 2003/12/17 19:56:13 weiden Exp $ +/* $Id: object.c,v 1.9 2004/02/24 01:30:57 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -31,6 +31,7 @@ #include #include +#include #define NDEBUG #include @@ -113,7 +114,7 @@ ObmpGetObjectByHandle(PUSER_HANDLE_TABLE HandleTable, Current = Current->Flink; if (Current == &(HandleTable->ListHead)) { - DPRINT1("Invalid handle 0x%x\n", Handle); + DPRINT1("Invalid handle 0x%x\n", Handle); return NULL; } } @@ -275,6 +276,7 @@ ObmReferenceObject(PVOID ObjectBody) if (!ObjectBody) { + DPRINT1("Cannot Reference NULL!\n"); return; } @@ -298,13 +300,17 @@ ObmDereferenceObject(PVOID ObjectBody) if (!ObjectBody) { + DPRINT1("Cannot Dereference NULL!\n"); return; } ObjectHeader = BODY_TO_HEADER(ObjectBody); ObjectHeader->RefCount--; - + #if 0 + if(ObjectHeader->Type == otWindow) + DbgPrint("Dereference 0x%x: %d\n", ((PWINDOW_OBJECT)ObjectBody)->Self, ObjectHeader->RefCount); + #endif ObmpPerformRetentionChecks(ObjectHeader); } @@ -327,7 +333,10 @@ ObmReferenceObjectByPointer(PVOID ObjectBody, { return STATUS_INVALID_PARAMETER; } - + #if 0 + if(ObjectType == otWindow) + DbgPrint("Reference 0x%x: %d\n", ((PWINDOW_OBJECT)ObjectBody)->Self, ObjectHeader->RefCount); + #endif ObjectHeader->RefCount++; return STATUS_SUCCESS; diff --git a/reactos/subsys/win32k/ntuser/focus.c b/reactos/subsys/win32k/ntuser/focus.c index 0a933f1f833..2efd2840c46 100644 --- a/reactos/subsys/win32k/ntuser/focus.c +++ b/reactos/subsys/win32k/ntuser/focus.c @@ -16,10 +16,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: focus.c,v 1.17 2004/02/23 12:39:37 gvg Exp $ + * $Id: focus.c,v 1.18 2004/02/24 01:30:57 weiden Exp $ */ #include +#include #include #include #include @@ -112,20 +113,28 @@ HWND FASTCALL IntFindChildWindowToOwner(PWINDOW_OBJECT Root, PWINDOW_OBJECT Owner) { HWND Ret; - PWINDOW_OBJECT Child; - ExAcquireFastMutexUnsafe(&Root->ChildrenListLock); + PWINDOW_OBJECT Child, OwnerWnd; + IntLockRelatives(Root); for(Child = Root->FirstChild; Child; Child = Child->NextSibling) { - if(Child->Owner == Owner) + IntLockRelatives(Child); + OwnerWnd = IntGetWindowObject(Child->Owner); + IntUnLockRelatives(Child); + if(!OwnerWnd) + continue; + + if(OwnerWnd == Owner) { + IntUnLockRelatives(Root); Ret = Child->Self; - ExReleaseFastMutexUnsafe(&Root->ChildrenListLock); + IntReleaseWindowObject(OwnerWnd); return Ret; } + IntReleaseWindowObject(OwnerWnd); } - ExReleaseFastMutexUnsafe(&Root->ChildrenListLock); + IntUnLockRelatives(Root); return NULL; } @@ -186,7 +195,7 @@ IntSetForegroundAndFocusWindow(PWINDOW_OBJECT Window, PWINDOW_OBJECT FocusWindow } IntSendSetFocusMessages(hWndFocusPrev, hWndFocus); IntSendActivateMessages(hWndPrev, hWnd, MouseActivate); - + return TRUE; } @@ -210,8 +219,7 @@ IntMouseActivateWindow(PWINDOW_OBJECT Window) if(DesktopWindow) { Top = IntFindChildWindowToOwner(DesktopWindow, Window); - TopWnd = IntGetWindowObject(Top); - if(TopWnd) + if((TopWnd = IntGetWindowObject(Top))) { Ret = IntMouseActivateWindow(TopWnd); IntReleaseWindowObject(TopWnd); @@ -283,9 +291,8 @@ IntSetActiveWindow(PWINDOW_OBJECT Window) } HWND FASTCALL -IntSetFocusWindow(PWINDOW_OBJECT Window) +IntSetFocusWindow(HWND hWnd) { - HWND hWnd = Window != 0 ? Window->Self : 0; HWND hWndPrev = 0; PUSER_MESSAGE_QUEUE ThreadQueue; @@ -453,14 +460,14 @@ NtUserSetFocus(HWND hWnd) NtUserSetActiveWindow(hWndTop); } - hWndPrev = IntSetFocusWindow(Window); + hWndPrev = IntSetFocusWindow(hWnd); IntReleaseWindowObject(Window); return hWndPrev; } else { - return IntSetFocusWindow(0); + return IntSetFocusWindow(NULL); } } diff --git a/reactos/subsys/win32k/ntuser/message.c b/reactos/subsys/win32k/ntuser/message.c index 8d518c87202..de41ee99cba 100644 --- a/reactos/subsys/win32k/ntuser/message.c +++ b/reactos/subsys/win32k/ntuser/message.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: message.c,v 1.50 2004/02/19 21:12:09 weiden Exp $ +/* $Id: message.c,v 1.51 2004/02/24 01:30:57 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -776,13 +776,11 @@ IntSendMessage(HWND hWnd, IntReleaseWindowObject(Window); return Result; } - else - { - Result = MsqSendMessage(Window->MessageQueue, hWnd, Msg, wParam, lParam); + + Result = MsqSendMessage(Window->MessageQueue, hWnd, Msg, wParam, lParam); - IntReleaseWindowObject(Window); - return Result; - } + IntReleaseWindowObject(Window); + return Result; } static NTSTATUS FASTCALL diff --git a/reactos/subsys/win32k/ntuser/msgqueue.c b/reactos/subsys/win32k/ntuser/msgqueue.c index 2a3483d3139..d83d2726e10 100644 --- a/reactos/subsys/win32k/ntuser/msgqueue.c +++ b/reactos/subsys/win32k/ntuser/msgqueue.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: msgqueue.c,v 1.69 2004/02/23 20:08:35 gvg Exp $ +/* $Id: msgqueue.c,v 1.70 2004/02/24 01:30:57 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -258,11 +258,13 @@ MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh, /* **Make sure that we have a window that is not already in focus */ - if (0 != Window && Window->Self != IntGetFocusWindow()) + if (Window) { + if(Window->Self != IntGetFocusWindow()) + { SpareLParam = MAKELONG(Hit, Msg); - if(Window && (Hit != (USHORT)HTTRANSPARENT)) + if(Hit != (USHORT)HTTRANSPARENT) { Result = IntSendMessage(Window->Self, WM_MOUSEACTIVATE, (WPARAM)NtUserGetParent(Window->Self), (LPARAM)SpareLParam); @@ -285,16 +287,16 @@ MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh, IntMouseActivateWindow(Window); break; } - IntReleaseWindowObject(Window); } else { - if(Window) - IntReleaseWindowObject(Window); + IntReleaseWindowObject(Window); ExFreePool(Message); *Freed = TRUE; return(FALSE); } + } + IntReleaseWindowObject(Window); } } @@ -577,6 +579,7 @@ MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, } } } + IntReleaseWindowObject(DesktopWindow); /* Check if the system message queue is now empty. */ KeAcquireSpinLock(&SystemMessageQueueLock, &OldIrql); if (SystemMessageQueueCount == 0 && IsListEmpty(&HardwareMessageQueueHead)) diff --git a/reactos/subsys/win32k/ntuser/painting.c b/reactos/subsys/win32k/ntuser/painting.c index cf5067c8334..0111b82f37f 100644 --- a/reactos/subsys/win32k/ntuser/painting.c +++ b/reactos/subsys/win32k/ntuser/painting.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: painting.c,v 1.72 2004/02/22 16:56:14 navaraf Exp $ + * $Id: painting.c,v 1.73 2004/02/24 01:30:57 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -59,14 +59,11 @@ VOID FASTCALL IntValidateParent(PWINDOW_OBJECT Child, HRGN ValidRegion) { - HWND Parent; - PWINDOW_OBJECT ParentWindow; + PWINDOW_OBJECT ParentWindow = IntGetParentObject(Child), OldWindow; - Parent = NtUserGetAncestor(Child->Self, GA_PARENT); - while (Parent) + while (ParentWindow) { - ParentWindow = IntGetWindowObject(Parent); - if (ParentWindow && !(ParentWindow->Style & WS_CLIPCHILDREN)) + if (!(ParentWindow->Style & WS_CLIPCHILDREN)) { ExAcquireFastMutex(&ParentWindow->UpdateLock); if (ParentWindow->UpdateRegion != 0) @@ -87,15 +84,9 @@ IntValidateParent(PWINDOW_OBJECT Child, HRGN ValidRegion) } ExReleaseFastMutex(&ParentWindow->UpdateLock); } - if (ParentWindow) - { - IntReleaseWindowObject(ParentWindow); - Parent = NtUserGetAncestor(Parent, GA_PARENT); - } - else - { - return; - } + OldWindow = ParentWindow; + ParentWindow = IntGetParentObject(ParentWindow); + IntReleaseWindowObject(OldWindow); } } @@ -422,14 +413,21 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags) BOOL FASTCALL IntIsWindowDrawable(PWINDOW_OBJECT Window) { - PWINDOW_OBJECT Wnd = Window; + PWINDOW_OBJECT Old, Wnd = Window; - for (; Wnd; Wnd = Wnd->Parent) + IntReferenceWindowObject(Wnd); + do { if (!(Wnd->Style & WS_VISIBLE) || ((Wnd->Style & WS_MINIMIZE) && (Wnd != Window))) + { + IntReleaseWindowObject(Wnd); return FALSE; - } + } + Old = Wnd; + Wnd = IntGetParentObject(Wnd); + IntReleaseWindowObject(Old); + } while(Wnd); return TRUE; } @@ -559,7 +557,7 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread) return hWnd; } - ExAcquireFastMutex(&Window->ChildrenListLock); + IntLockRelatives(Window); for (Child = Window->FirstChild; Child; Child = Child->NextSibling) { if (IntIsWindowDirty(Child) && @@ -569,7 +567,7 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread) break; } } - ExReleaseFastMutex(&Window->ChildrenListLock); + IntUnLockRelatives(Window); if (hFoundWnd == NULL) { diff --git a/reactos/subsys/win32k/ntuser/vis.c b/reactos/subsys/win32k/ntuser/vis.c index c5e600a2df2..9335da8c4e8 100644 --- a/reactos/subsys/win32k/ntuser/vis.c +++ b/reactos/subsys/win32k/ntuser/vis.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: vis.c,v 1.19 2004/02/22 16:56:14 navaraf Exp $ + * $Id: vis.c,v 1.20 2004/02/24 01:30:57 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -70,7 +70,7 @@ VIS_ComputeVisibleRegion( */ PreviousWindow = Window; - CurrentWindow = Window->Parent; + CurrentWindow = IntGetParentObject(Window); while (CurrentWindow) { if (!(CurrentWindow->Style & WS_VISIBLE)) @@ -85,7 +85,7 @@ VIS_ComputeVisibleRegion( if ((CurrentWindow->Style & WS_CLIPSIBLINGS) || (PreviousWindow == Window && ClipSiblings)) { - ExAcquireFastMutexUnsafe(&CurrentWindow->ChildrenListLock); + IntLockRelatives(CurrentWindow); CurrentSibling = CurrentWindow->FirstChild; while (CurrentSibling != PreviousWindow) { @@ -97,16 +97,17 @@ VIS_ComputeVisibleRegion( } CurrentSibling = CurrentSibling->NextSibling; } - ExReleaseFastMutexUnsafe(&CurrentWindow->ChildrenListLock); + IntUnLockRelatives(CurrentWindow); } PreviousWindow = CurrentWindow; - CurrentWindow = CurrentWindow->Parent; + CurrentWindow = IntGetParentObject(CurrentWindow); + IntReleaseWindowObject(PreviousWindow); } if (ClipChildren) { - ExAcquireFastMutexUnsafe(&Window->ChildrenListLock); + IntLockRelatives(Window); CurrentWindow = Window->FirstChild; while (CurrentWindow) { @@ -118,7 +119,7 @@ VIS_ComputeVisibleRegion( } CurrentWindow = CurrentWindow->NextSibling; } - ExReleaseFastMutexUnsafe(&Window->ChildrenListLock); + IntUnLockRelatives(Window); } NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset); @@ -132,18 +133,23 @@ VIS_WindowLayoutChanged( HRGN NewlyExposed) { HRGN Temp; + PWINDOW_OBJECT Parent; Temp = NtGdiCreateRectRgn(0, 0, 0, 0); NtGdiCombineRgn(Temp, NewlyExposed, NULL, RGN_COPY); - if (Window->Parent != NULL) + + Parent = IntGetParentObject(Window); + if(Parent) { NtGdiOffsetRgn(Temp, - Window->WindowRect.left - Window->Parent->ClientRect.left, - Window->WindowRect.top - Window->Parent->ClientRect.top); + Window->WindowRect.left - Parent->ClientRect.left, + Window->WindowRect.top - Parent->ClientRect.top); } - IntRedrawWindow(Window->Parent, NULL, Temp, + IntRedrawWindow(Parent, NULL, Temp, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN); + if(Parent) + IntReleaseWindowObject(Parent); NtGdiDeleteObject(Temp); } diff --git a/reactos/subsys/win32k/ntuser/windc.c b/reactos/subsys/win32k/ntuser/windc.c index 3b37cc15765..684f99796cf 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.58 2004/02/22 12:25:35 navaraf Exp $ +/* $Id: windc.c,v 1.59 2004/02/24 01:30:57 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -238,7 +238,13 @@ DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags) { PWINDOW_OBJECT Parent; - Parent = Window->Parent; + Parent = IntGetParentObject(Window); + if(!Parent) + { + hRgnVisible = NULL; + goto noparent; + } + if (Parent->Style & WS_CLIPSIBLINGS) { DcxFlags = DCX_CLIPSIBLINGS | @@ -289,6 +295,7 @@ DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags) hRgnVisible = DceGetVisRgn(Window->Self, Flags, 0, 0); } +noparent: if (Flags & DCX_INTERSECTRGN) { NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_AND); @@ -311,7 +318,7 @@ DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags) HDC STDCALL NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags) { - PWINDOW_OBJECT Window; + PWINDOW_OBJECT Window, Parent; ULONG DcxFlags; DCE* Dce; BOOL UpdateVisRgn = TRUE; @@ -372,7 +379,9 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags) Flags = (Flags & ~DCX_CLIPCHILDREN) | DCX_CACHE; } - if (NULL == Window || !(Window->Style & WS_CHILD) || NULL == Window->Parent) + Parent = (Window ? IntGetParentObject(Window) : NULL); + + if (NULL == Window || !(Window->Style & WS_CHILD) || NULL == Parent) { Flags &= ~DCX_PARENTCLIP; } @@ -380,16 +389,19 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags) { Flags |= DCX_CACHE; if ((Window->Style & WS_VISIBLE) && - (Window->Parent->Style & WS_VISIBLE)) + (Parent->Style & WS_VISIBLE)) { Flags &= ~DCX_CLIPCHILDREN; - if (Window->Parent->Style & WS_CLIPSIBLINGS) + if (Parent->Style & WS_CLIPSIBLINGS) { Flags |= DCX_CLIPSIBLINGS; } } } + if(Parent) + IntReleaseWindowObject(Parent); + DcxFlags = Flags & DCX_CACHECOMPAREMASK; if (Flags & DCX_CACHE) diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 5f58d6ea6c9..2a38cc60621 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.190 2004/02/22 23:40:58 gvg Exp $ +/* $Id: window.c,v 1.191 2004/02/24 01:30:57 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -97,36 +97,6 @@ CleanupWindowImpl(VOID) /* HELPER FUNCTIONS ***********************************************************/ -/* - * IntIsBroadcastHwnd - * - * Check if window is a broadcast. - * - * Return Value - * TRUE if window is broadcast, FALSE otherwise. - */ - -inline BOOL -IntIsBroadcastHwnd(HWND hWnd) -{ - return (hWnd == HWND_BROADCAST || hWnd == HWND_TOPMOST); -} - -/* - * IntIsDesktopWindow - * - * Check if window is a desktop. Desktop windows has no parent. - * - * Return Value - * TRUE if window is desktop, FALSE otherwise. - */ - -inline BOOL -IntIsDesktopWindow(PWINDOW_OBJECT Wnd) -{ - return Wnd->Parent == NULL; -} - /* * IntIsWindow * @@ -150,9 +120,8 @@ IntIsWindow(HWND hWnd) if (!(Window = IntGetWindowObject(hWnd))) return FALSE; - else - IntReleaseWindowObject(Window); - + + IntReleaseWindowObject(Window); return TRUE; } @@ -177,29 +146,40 @@ IntGetProcessWindowObject(PW32PROCESS ProcessData, HWND hWnd) return WindowObject; } -/* - * IntGetWindowObject - * - * Get window object from handle of current process. - */ PWINDOW_OBJECT FASTCALL -IntGetWindowObject(HWND hWnd) +IntGetParent(PWINDOW_OBJECT Wnd) { - return IntGetProcessWindowObject(PsGetWin32Process(), hWnd); + HWND hWnd; + + if (Wnd->Style & WS_POPUP) + { + IntLockRelatives(Wnd); + hWnd = Wnd->Owner; + IntUnLockRelatives(Wnd); + return IntGetWindowObject(hWnd); + } + else if (Wnd->Style & WS_CHILD) + { + IntLockRelatives(Wnd); + hWnd = Wnd->Parent; + IntUnLockRelatives(Wnd); + return IntGetWindowObject(hWnd); + } + + return NULL; } -/* - * IntReleaseWindowObject - * - * Release window object returned by IntGetWindowObject or - * IntGetProcessWindowObject. - */ -VOID FASTCALL -IntReleaseWindowObject(PWINDOW_OBJECT Window) +PWINDOW_OBJECT FASTCALL +IntGetParentObject(PWINDOW_OBJECT Wnd) { - ObmDereferenceObject(Window); + HWND hParent; + + IntLockRelatives(Wnd); + hParent = Wnd->Parent; + IntUnLockRelatives(Wnd); + return IntGetWindowObject(hParent); } /* @@ -219,7 +199,7 @@ IntWinListChildren(PWINDOW_OBJECT Window) HWND *List; UINT Index, NumChildren = 0; - ExAcquireFastMutexUnsafe(&Window->ChildrenListLock); + IntLockRelatives(Window); for (Child = Window->FirstChild; Child; Child = Child->NextSibling) ++NumChildren; @@ -227,21 +207,20 @@ IntWinListChildren(PWINDOW_OBJECT Window) if (NumChildren != 0) { List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), TAG_WINLIST); - if (List != NULL) + if(!List) { - for (Child = Window->FirstChild, Index = 0; - Child != NULL; - Child = Child->NextSibling, ++Index) - List[Index] = Child->Self; - List[Index] = NULL; - } - else - { - DPRINT1("Failed to allocate memory for children array\n"); + DPRINT1("Failed to allocate memory for children array\n"); + IntUnLockRelatives(Window); + return NULL; } + for (Child = Window->FirstChild, Index = 0; + Child != NULL; + Child = Child->NextSibling, ++Index) + List[Index] = Child->Self; + List[Index] = NULL; } - ExReleaseFastMutexUnsafe(&Window->ChildrenListLock); + IntUnLockRelatives(Window); return (NumChildren > 0) ? List : NULL; } @@ -328,8 +307,7 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window, { for (ChildHandle = Children; *ChildHandle; ++ChildHandle) { - Child = IntGetProcessWindowObject(ProcessData, *ChildHandle); - if (NULL != Child) + if ((Child = IntGetWindowObject(*ChildHandle))) { if(IntWndBelongsToThread(Child, ThreadData)) { @@ -409,14 +387,8 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window, WINPROC_FreeProc(Window->winproc, WIN_PROC_WINDOW); CLASS_RemoveWindow(Window->Class); #endif - - if (Window->Parent) - { - PWINDOW_OBJECT Parent = Window->Parent; - ExAcquireFastMutexUnsafe(&Parent->ChildrenListLock); - IntUnlinkWindow(Window); - ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock); - } + + IntUnlinkWindow(Window); ExAcquireFastMutexUnsafe (&ThreadData->WindowListLock); RemoveEntryList(&Window->ThreadListEntry); @@ -545,8 +517,7 @@ IntGetClientRect(PWINDOW_OBJECT WindowObject, PRECT Rect) Rect->left = Rect->top = 0; Rect->right = WindowObject->ClientRect.right - WindowObject->ClientRect.left; - Rect->bottom = - WindowObject->ClientRect.bottom - WindowObject->ClientRect.top; + Rect->bottom = WindowObject->ClientRect.bottom - WindowObject->ClientRect.top; } @@ -569,23 +540,6 @@ IntGetFocusWindow(VOID) } #endif -PWINDOW_OBJECT FASTCALL -IntGetParent(PWINDOW_OBJECT Wnd) -{ - if (Wnd->Style & WS_POPUP) - { - return Wnd->Owner; - } - else if (Wnd->Style & WS_CHILD) - { - return Wnd->Parent; - } - - return NULL; -} - - - PMENU_OBJECT FASTCALL IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu) { @@ -698,51 +652,54 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu) } - -DWORD FASTCALL -IntGetWindowThreadProcessId(PWINDOW_OBJECT Wnd, PDWORD pid) -{ - if (pid) *pid = (DWORD) Wnd->OwnerThread->ThreadsProcess->UniqueProcessId; - return (DWORD) Wnd->OwnerThread->Cid.UniqueThread; -} - BOOL FASTCALL IntIsChildWindow(HWND Parent, HWND Child) { PWINDOW_OBJECT BaseWindow = IntGetWindowObject(Child); PWINDOW_OBJECT Window = BaseWindow; + while (Window != NULL && Window->Style & WS_CHILD) + { + if (Window->Self == Parent) { - if (Window->Self == Parent) - { - IntReleaseWindowObject(BaseWindow); - return(TRUE); - } - Window = Window->Parent; + if(Window != BaseWindow) + IntReleaseWindowObject(Window); + IntReleaseWindowObject(BaseWindow); + return(TRUE); } + if(Window != BaseWindow) + IntReleaseWindowObject(Window); + Window = IntGetParentObject(Window); + } + IntReleaseWindowObject(BaseWindow); return(FALSE); } BOOL FASTCALL -IntIsWindowVisible(HWND Wnd) +IntIsWindowVisible(HWND hWnd) { - PWINDOW_OBJECT BaseWindow = IntGetWindowObject(Wnd); + PWINDOW_OBJECT BaseWindow = IntGetWindowObject(hWnd); PWINDOW_OBJECT Window = BaseWindow; BOOLEAN Result = FALSE; + while (Window != NULL && Window->Style & WS_CHILD) - { - if (!(Window->Style & WS_VISIBLE)) + { + if (!(Window->Style & WS_VISIBLE)) { + if(Window != BaseWindow) + IntReleaseWindowObject(Window); IntReleaseWindowObject(BaseWindow); return(FALSE); } - Window = Window->Parent; - } + if(Window != BaseWindow) + IntReleaseWindowObject(Window); + Window = IntGetParentObject(Window); + } if (Window != NULL && Window->Style & WS_VISIBLE) - { - Result = TRUE; - } + { + Result = TRUE; + } IntReleaseWindowObject(BaseWindow); return(Result); } @@ -756,33 +713,64 @@ IntLinkWindow( PWINDOW_OBJECT WndPrevSibling /* set to NULL if top sibling */ ) { - Wnd->Parent = WndParent; - + PWINDOW_OBJECT Parent; + + IntLockRelatives(Wnd); + Wnd->Parent = WndParent->Self; if ((Wnd->PrevSibling = WndPrevSibling)) { /* link after WndPrevSibling */ - if ((Wnd->NextSibling = WndPrevSibling->NextSibling)) Wnd->NextSibling->PrevSibling = Wnd; - else if (Wnd->Parent->LastChild == WndPrevSibling) Wnd->Parent->LastChild = Wnd; + if ((Wnd->NextSibling = WndPrevSibling->NextSibling)) + Wnd->NextSibling->PrevSibling = Wnd; + else if ((Parent = IntGetWindowObject(Wnd->Parent))) + { + IntLockRelatives(Parent); + if(Parent->LastChild == WndPrevSibling) + Parent->LastChild = Wnd; + IntUnLockRelatives(Parent); + IntReleaseWindowObject(Parent); + } Wnd->PrevSibling->NextSibling = Wnd; } else { /* link at top */ - if ((Wnd->NextSibling = WndParent->FirstChild)) Wnd->NextSibling->PrevSibling = Wnd; - else Wnd->Parent->LastChild = Wnd; - WndParent->FirstChild = Wnd; + Parent = IntGetWindowObject(Wnd->Parent); + if ((Wnd->NextSibling = WndParent->FirstChild)) + Wnd->NextSibling->PrevSibling = Wnd; + else if (Parent) + { + IntLockRelatives(Parent); + Parent->LastChild = Wnd; + Parent->FirstChild = Wnd; + IntUnLockRelatives(Parent); + IntReleaseWindowObject(Parent); + IntUnLockRelatives(Wnd); + return; + } + if(Parent) + { + IntLockRelatives(Parent); + Parent->FirstChild = Wnd; + IntUnLockRelatives(Parent); + IntReleaseWindowObject(Parent); + } } - + IntUnLockRelatives(Wnd); } HWND FASTCALL IntSetOwner(HWND hWnd, HWND hWndNewOwner) { - PWINDOW_OBJECT Wnd, WndOldOwner; + PWINDOW_OBJECT Wnd, WndOldOwner, WndNewOwner; HWND ret; Wnd = IntGetWindowObject(hWnd); - WndOldOwner = Wnd->Owner; + if(!Wnd) + return NULL; + + IntLockRelatives(Wnd); + WndOldOwner = IntGetWindowObject(Wnd->Owner); if (WndOldOwner) { ret = WndOldOwner->Self; @@ -792,7 +780,16 @@ IntSetOwner(HWND hWnd, HWND hWndNewOwner) { ret = 0; } - Wnd->Owner = IntGetWindowObject(hWndNewOwner); + + if((WndNewOwner = IntGetWindowObject(hWndNewOwner))) + { + Wnd->Owner = hWndNewOwner; + IntReleaseWindowObject(WndNewOwner); + } + else + Wnd->Owner = NULL; + + IntUnLockRelatives(Wnd); IntReleaseWindowObject(Wnd); return ret; } @@ -822,17 +819,13 @@ IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent) if (Wnd->OwnerThread->ThreadsProcess != PsGetCurrentProcess()) return NULL; - WndOldParent = Wnd->Parent; - hWndOldParent = WndOldParent->Self; + WndOldParent = IntGetParentObject(Wnd); + hWndOldParent = (WndOldParent ? WndOldParent->Self : NULL); if (WndNewParent != WndOldParent) { - ExAcquireFastMutexUnsafe(&WndOldParent->ChildrenListLock); IntUnlinkWindow(Wnd); - ExReleaseFastMutexUnsafe(&WndOldParent->ChildrenListLock); - ExAcquireFastMutexUnsafe(&WndNewParent->ChildrenListLock); IntLinkWindow(Wnd, WndNewParent, NULL /*prev sibling*/); - ExReleaseFastMutexUnsafe(&WndNewParent->ChildrenListLock); if (WndNewParent->Self != IntGetDesktopWindow()) /* a child window */ { @@ -843,7 +836,9 @@ IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent) } } } - + + if(WndOldParent) + IntReleaseWindowObject(WndOldParent); /* * SetParent additionally needs to make hwnd the topmost window * in the x-order and send the expected WM_WINDOWPOSCHANGING and @@ -895,29 +890,29 @@ IntSetSystemMenu(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject) VOID FASTCALL IntUnlinkWindow(PWINDOW_OBJECT Wnd) { - PWINDOW_OBJECT WndParent = Wnd->Parent; - + PWINDOW_OBJECT WndParent; + + IntLockRelatives(Wnd); + if((WndParent = IntGetWindowObject(Wnd->Parent))) + { + IntLockRelatives(WndParent); + } + if (Wnd->NextSibling) Wnd->NextSibling->PrevSibling = Wnd->PrevSibling; - else if (WndParent->LastChild == Wnd) WndParent->LastChild = Wnd->PrevSibling; + else if (WndParent && WndParent->LastChild == Wnd) WndParent->LastChild = Wnd->PrevSibling; if (Wnd->PrevSibling) Wnd->PrevSibling->NextSibling = Wnd->NextSibling; - else if (WndParent->FirstChild == Wnd) WndParent->FirstChild = Wnd->NextSibling; + else if (WndParent && WndParent->FirstChild == Wnd) WndParent->FirstChild = Wnd->NextSibling; //else if (parent->first_unlinked == win) parent->first_unlinked = Wnd->NextSibling; -} - - -BOOLEAN FASTCALL -IntWndBelongsToThread(PWINDOW_OBJECT Window, PW32THREAD ThreadData) -{ - if (Window->OwnerThread && Window->OwnerThread->Win32Thread) + if(WndParent) { - return (Window->OwnerThread->Win32Thread == ThreadData); + IntUnLockRelatives(WndParent); + IntReleaseWindowObject(WndParent); } - - return FALSE; + Wnd->PrevSibling = Wnd->NextSibling = Wnd->Parent = NULL; + IntUnLockRelatives(Wnd); } - /* FUNCTIONS *****************************************************************/ /* @@ -972,7 +967,7 @@ NtUserBuildHwndList( return 0; } - ExAcquireFastMutex ( &WindowObject->ChildrenListLock ); + IntLockRelatives(WindowObject ); Child = WindowObject->FirstChild; while (Child) { @@ -981,7 +976,7 @@ NtUserBuildHwndList( dwCount++; Child = Child->NextSibling; } - ExReleaseFastMutex ( &WindowObject->ChildrenListLock ); + IntUnLockRelatives(WindowObject); IntReleaseWindowObject ( WindowObject ); } else if ( dwThreadId ) @@ -1028,7 +1023,7 @@ NtUserBuildHwndList( if ( pWnd && dwCount < nBufSize ) { pWnd[dwCount] = - (HWND)ObmReferenceObjectByPointer ( ObjectBody, otWindow ); + (HWND)IntReferenceWindowObject(ObjectBody); } dwCount++; } @@ -1078,13 +1073,15 @@ NtUserBuildHwndList( /* * @implemented */ + + /* FIXME - NEEDS TO BE FIXED - UNSAFE !!! */ HWND STDCALL NtUserChildWindowFromPointEx(HWND hwndParent, LONG x, LONG y, UINT uiFlags) { - PWINDOW_OBJECT pParent, pCurrent, pLast; + PWINDOW_OBJECT pParent, pCurrent, pLast, pPar; POINT p = {x,y}; RECT rc; BOOL bFirstRun = TRUE; @@ -1094,7 +1091,7 @@ NtUserChildWindowFromPointEx(HWND hwndParent, pParent = IntGetWindowObject(hwndParent); if(pParent) { - ExAcquireFastMutexUnsafe (&pParent->ChildrenListLock); + IntLockRelatives(pParent); pLast = IntGetWindowObject(pParent->LastChild->Self); pCurrent = IntGetWindowObject(pParent->FirstChild->Self); @@ -1109,13 +1106,21 @@ NtUserChildWindowFromPointEx(HWND hwndParent, else bFirstRun = FALSE; if(!pCurrent) + { + IntUnLockRelatives(pParent); return (HWND)NULL; - - rc.left = pCurrent->WindowRect.left - pCurrent->Parent->ClientRect.left; - rc.top = pCurrent->WindowRect.top - pCurrent->Parent->ClientRect.top; + } + if(!(pPar = IntGetWindowObject(pCurrent->Parent))) + { + IntUnLockRelatives(pParent); + return (HWND)NULL; + } + rc.left = pCurrent->WindowRect.left - pPar->ClientRect.left; + rc.top = pCurrent->WindowRect.top - pPar->ClientRect.top; rc.right = rc.left + (pCurrent->WindowRect.right - pCurrent->WindowRect.left); rc.bottom = rc.top + (pCurrent->WindowRect.bottom - pCurrent->WindowRect.top); DbgPrint("Rect: %i,%i,%i,%i\n",rc.left, rc.top, rc.right, rc.bottom); + IntReleaseWindowObject(pPar); if (POINT_IN_RECT(p,rc)) /* Found a match */ { if ( (uiFlags & CWP_SKIPDISABLED) && (pCurrent->Style & WS_DISABLED) ) @@ -1125,13 +1130,13 @@ NtUserChildWindowFromPointEx(HWND hwndParent, if( (uiFlags & CWP_SKIPINVISIBLE) && !(pCurrent->Style & WS_VISIBLE) ) continue; - ExReleaseFastMutexUnsafe(&pParent->ChildrenListLock); + IntUnLockRelatives(pParent); return pCurrent->Self; } } while(pCurrent != pLast); - ExReleaseFastMutexUnsafe(&pParent->ChildrenListLock); + IntUnLockRelatives(pParent); return (HWND)NULL; } SetLastWin32Error(ERROR_INVALID_PARAMETER); @@ -1163,7 +1168,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, PWINSTATION_OBJECT WinStaObject; PWNDCLASS_OBJECT ClassObject; PWINDOW_OBJECT WindowObject; - PWINDOW_OBJECT ParentWindow; + PWINDOW_OBJECT ParentWindow, OwnerWindow; HWND ParentWindowHandle; HWND OwnerWindowHandle; PMENU_OBJECT SystemMenu; @@ -1306,8 +1311,14 @@ NtUserCreateWindowEx(DWORD dwExStyle, IntSetMenu(WindowObject, hMenu, &MenuChanged); } WindowObject->MessageQueue = PsGetWin32Thread()->MessageQueue; - WindowObject->Parent = ParentWindow; - WindowObject->Owner = IntGetWindowObject(OwnerWindowHandle); + WindowObject->Parent = (ParentWindow ? ParentWindow->Self : NULL); + if((OwnerWindow = IntGetWindowObject(OwnerWindowHandle))) + { + WindowObject->Owner = OwnerWindowHandle; + IntReleaseWindowObject(OwnerWindow); + } + else + WindowObject->Owner = NULL; WindowObject->UserData = 0; if ((((DWORD)ClassObject->lpfnWndProcA & 0xFFFF0000) != 0xFFFF0000) && (((DWORD)ClassObject->lpfnWndProcW & 0xFFFF0000) != 0xFFFF0000)) @@ -1341,7 +1352,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, InitializeListHead(&WindowObject->PropListHead); ExInitializeFastMutex(&WindowObject->PropListLock); - ExInitializeFastMutex(&WindowObject->ChildrenListLock); + ExInitializeFastMutex(&WindowObject->RelativesLock); ExInitializeFastMutex(&WindowObject->UpdateLock); RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer); @@ -1389,10 +1400,10 @@ NtUserCreateWindowEx(DWORD dwExStyle, WindowObject->WindowRect.top = y; WindowObject->WindowRect.right = x + nWidth; WindowObject->WindowRect.bottom = y + nHeight; - if (0 != (WindowObject->Style & WS_CHILD)) + if (0 != (WindowObject->Style & WS_CHILD) && ParentWindow) { - NtGdiOffsetRect(&(WindowObject->WindowRect), WindowObject->Parent->ClientRect.left, - WindowObject->Parent->ClientRect.top); + NtGdiOffsetRect(&(WindowObject->WindowRect), ParentWindow->ClientRect.left, + ParentWindow->ClientRect.top); } WindowObject->ClientRect = WindowObject->WindowRect; @@ -1442,10 +1453,10 @@ NtUserCreateWindowEx(DWORD dwExStyle, WindowObject->WindowRect.top = y; WindowObject->WindowRect.right = x + nWidth; WindowObject->WindowRect.bottom = y + nHeight; - if (0 != (WindowObject->Style & WS_CHILD)) + if (0 != (WindowObject->Style & WS_CHILD) && ParentWindow) { - NtGdiOffsetRect(&(WindowObject->WindowRect), WindowObject->Parent->ClientRect.left, - WindowObject->Parent->ClientRect.top); + NtGdiOffsetRect(&(WindowObject->WindowRect), ParentWindow->ClientRect.left, + ParentWindow->ClientRect.top); } WindowObject->ClientRect = WindowObject->WindowRect; @@ -1499,7 +1510,6 @@ NtUserCreateWindowEx(DWORD dwExStyle, if (NULL != ParentWindow) { /* link the window into the parent's child list */ - ExAcquireFastMutexUnsafe(&ParentWindow->ChildrenListLock); if ((dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD) { /* link window as bottom sibling */ @@ -1510,7 +1520,6 @@ NtUserCreateWindowEx(DWORD dwExStyle, /* link window as top sibling */ IntLinkWindow(WindowObject, ParentWindow, NULL /*prev sibling*/); } - ExReleaseFastMutexUnsafe(&ParentWindow->ChildrenListLock); } /* Send the WM_CREATE message. */ @@ -1547,10 +1556,10 @@ NtUserCreateWindowEx(DWORD dwExStyle, DPRINT("NtUserCreateWindow(): About to send WM_MOVE\n"); - if (0 != (WindowObject->Style & WS_CHILD)) + if (0 != (WindowObject->Style & WS_CHILD) && ParentWindow) { - lParam = MAKE_LONG(WindowObject->ClientRect.left - WindowObject->Parent->ClientRect.left, - WindowObject->ClientRect.top - WindowObject->Parent->ClientRect.top); + lParam = MAKE_LONG(WindowObject->ClientRect.left - ParentWindow->ClientRect.left, + WindowObject->ClientRect.top - ParentWindow->ClientRect.top); } else { @@ -1581,15 +1590,20 @@ NtUserCreateWindowEx(DWORD dwExStyle, /* Notify the parent window of a new child. */ if ((WindowObject->Style & WS_CHILD) && - (!(WindowObject->ExStyle & WS_EX_NOPARENTNOTIFY))) + (!(WindowObject->ExStyle & WS_EX_NOPARENTNOTIFY)) && ParentWindow) { DPRINT("NtUserCreateWindow(): About to notify parent\n"); - IntSendMessage(WindowObject->Parent->Self, + IntSendMessage(ParentWindow->Self, WM_PARENTNOTIFY, MAKEWPARAM(WM_CREATE, WindowObject->IDMenu), (LPARAM)WindowObject->Self); } + if (NULL != ParentWindow) + { + IntReleaseWindowObject(ParentWindow); + } + if (dwStyle & WS_VISIBLE) { DPRINT("NtUserCreateWindow(): About to show window\n"); @@ -1627,7 +1641,7 @@ NtUserDeferWindowPos(HDWP WinPosInfo, BOOLEAN STDCALL NtUserDestroyWindow(HWND Wnd) { - PWINDOW_OBJECT Window, Parent; + PWINDOW_OBJECT Window; BOOLEAN isChild; Window = IntGetWindowObject(Wnd); @@ -1720,7 +1734,7 @@ NtUserDestroyWindow(HWND Wnd) { continue; } - if (Child->Parent != Window) + if (Child->Parent != Window->Self) { IntReleaseWindowObject(Child); continue; @@ -1734,7 +1748,6 @@ NtUserDestroyWindow(HWND Wnd) } if (Child->Owner != NULL) { - IntReleaseWindowObject(Child->Owner); Child->Owner = NULL; } IntReleaseWindowObject(Child); @@ -1754,11 +1767,7 @@ NtUserDestroyWindow(HWND Wnd) } /* Unlink now so we won't bother with the children later on */ - Parent = Window->Parent; - ExAcquireFastMutexUnsafe(&Parent->ChildrenListLock); IntUnlinkWindow(Window); - Window->Parent = NULL; - ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock); /* Destroy the window storage */ IntDestroyWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE); @@ -1872,7 +1881,7 @@ NtUserFindWindowEx(HWND hwndParent, return NULL; } - ExAcquireFastMutexUnsafe (&ParentWindow->ChildrenListLock); + IntLockRelatives(ParentWindow); if(hwndChildAfter) { @@ -1883,11 +1892,14 @@ NtUserFindWindowEx(HWND hwndParent, } /* must be a direct child (not a decendant child)*/ - if (WndChildAfter->Parent != ParentWindow) + IntLockRelatives(WndChildAfter); + if (WndChildAfter->Parent != ParentWindow->Self) { + IntUnLockRelatives(WndChildAfter); SetLastWin32Error(ERROR_INVALID_PARAMETER); return NULL; } + IntUnLockRelatives(WndChildAfter); WndChild = WndChildAfter->NextSibling; } @@ -1903,7 +1915,7 @@ NtUserFindWindowEx(HWND hwndParent, { windowHandle = WndChild->Self; - ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock); + IntUnLockRelatives(ParentWindow); IntReleaseWindowObject(ParentWindow); ObmDereferenceObject (classObject); @@ -1913,7 +1925,7 @@ NtUserFindWindowEx(HWND hwndParent, WndChild = WndChild->NextSibling; } - ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock); + IntUnLockRelatives(ParentWindow); IntReleaseWindowObject(ParentWindow); ObmDereferenceObject (classObject); @@ -1940,19 +1952,16 @@ NtUserFlashWindowEx(DWORD Unknown0) HWND STDCALL NtUserGetAncestor(HWND hWnd, UINT Type) { - PWINDOW_OBJECT Wnd, WndAncestor; - HWND hWndAncestor = NULL; + PWINDOW_OBJECT Wnd, WndAncestor, Parent; + HWND hWndAncestor; if (hWnd == IntGetDesktopWindow()) { return NULL; } - IntAcquireWinLockShared(); - if (!(Wnd = IntGetWindowObject(hWnd))) { - IntReleaseWinLock(); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); return NULL; } @@ -1960,36 +1969,71 @@ NtUserGetAncestor(HWND hWnd, UINT Type) switch (Type) { case GA_PARENT: - WndAncestor = Wnd->Parent; + WndAncestor = IntGetParentObject(Wnd); break; case GA_ROOT: WndAncestor = Wnd; - while (!IntIsDesktopWindow(WndAncestor->Parent)) - WndAncestor = WndAncestor->Parent; + Parent = NULL; +#if 0 + while (0 != (WndAncestor->Style & WS_CHILD)) + { + Parent = IntGetParentObject(WndAncestor); + if (WndAncestor != Wnd) + { + IntReleaseWindowObject(WndAncestor); + } + WndAncestor = Parent; + } +#else + for(;;) + { + if(Parent) + { + IntReleaseWindowObject(Parent); + } + if(!(Parent = IntGetParentObject(WndAncestor)) || + !IntIsDesktopWindow(WndAncestor)) + { + break; + } + WndAncestor = Parent; + } +#endif break; case GA_ROOTOWNER: WndAncestor = Wnd; + IntReferenceWindowObject(WndAncestor); for (;;) { - PWINDOW_OBJECT Parent = IntGetParent(WndAncestor); - if (!Parent) break; + PWINDOW_OBJECT Old; + Old = WndAncestor; + Parent = IntGetParent(WndAncestor); + IntReleaseWindowObject(Old); + if (!Parent) + { + break; + } WndAncestor = Parent; } break; default: - WndAncestor = NULL; + IntReleaseWindowObject(Wnd); + return NULL; } - - if (WndAncestor) - { - hWndAncestor = WndAncestor->Self; - } - + IntReleaseWindowObject(Wnd); - IntReleaseWinLock(); + + if(!WndAncestor) + { + return NULL; + } + + hWndAncestor = WndAncestor->Self; + if(WndAncestor != Wnd) + IntReleaseWindowObject(WndAncestor); return hWndAncestor; } @@ -2011,16 +2055,13 @@ NtUserGetClientRect(HWND hWnd, LPRECT Rect) PWINDOW_OBJECT WindowObject; RECT SafeRect; - IntAcquireWinLockShared(); if (!(WindowObject = IntGetWindowObject(hWnd))) { - IntReleaseWinLock(); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); return FALSE; } IntGetClientRect(WindowObject, &SafeRect); - IntReleaseWinLock(); if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT)))) { @@ -2109,11 +2150,8 @@ NtUserGetParent(HWND hWnd) PWINDOW_OBJECT Wnd, WndParent; HWND hWndParent = NULL; - IntAcquireWinLockShared(); - if (!(Wnd = IntGetWindowObject(hWnd))) { - IntReleaseWinLock(); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); return NULL; } @@ -2122,10 +2160,10 @@ NtUserGetParent(HWND hWnd) if (WndParent) { hWndParent = WndParent->Self; + IntReleaseWindowObject(WndParent); } IntReleaseWindowObject(Wnd); - IntReleaseWinLock(); return hWndParent; } @@ -2165,12 +2203,10 @@ NtUserSetParent(HWND hWndChild, HWND hWndNewParent) return NULL; } - IntAcquireWinLockExclusive(); if (hWndNewParent) { if (!(WndParent = IntGetWindowObject(hWndNewParent))) { - IntReleaseWinLock(); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); return NULL; } @@ -2179,7 +2215,6 @@ NtUserSetParent(HWND hWndChild, HWND hWndNewParent) { if (!(WndParent = IntGetWindowObject(IntGetDesktopWindow()))) { - IntReleaseWinLock(); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); return NULL; } @@ -2187,7 +2222,6 @@ NtUserSetParent(HWND hWndChild, HWND hWndNewParent) if (!(Wnd = IntGetWindowObject(hWndChild))) { - IntReleaseWinLock(); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); return NULL; } @@ -2201,7 +2235,6 @@ NtUserSetParent(HWND hWndChild, HWND hWndNewParent) IntReleaseWindowObject(Wnd); IntReleaseWindowObject(WndParent); - IntReleaseWinLock(); return hWndOldParent; } @@ -2417,28 +2450,38 @@ NtUserSetSystemMenu(HWND hWnd, HMENU hMenu) HWND STDCALL NtUserGetWindow(HWND hWnd, UINT Relationship) { - PWINDOW_OBJECT WindowObject; + PWINDOW_OBJECT WindowObject, Parent; HWND hWndResult = NULL; - IntAcquireWinLockShared(); - if (!(WindowObject = IntGetWindowObject(hWnd))) { - IntReleaseWinLock(); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); return NULL; } + IntLockRelatives(WindowObject); switch (Relationship) { case GW_HWNDFIRST: - if (WindowObject->Parent && WindowObject->Parent->FirstChild) - hWndResult = WindowObject->Parent->FirstChild->Self; + if((Parent = IntGetParentObject(WindowObject))) + { + IntLockRelatives(Parent); + if (Parent->FirstChild) + hWndResult = Parent->FirstChild->Self; + IntUnLockRelatives(Parent); + IntReleaseWindowObject(Parent); + } break; case GW_HWNDLAST: - if (WindowObject->Parent && WindowObject->Parent->LastChild) - hWndResult = WindowObject->Parent->LastChild->Self; + if((Parent = IntGetParentObject(WindowObject))) + { + IntLockRelatives(Parent); + if (Parent->LastChild) + hWndResult = Parent->LastChild->Self; + IntUnLockRelatives(Parent); + IntReleaseWindowObject(Parent); + } break; case GW_HWNDNEXT: @@ -2452,17 +2495,20 @@ NtUserGetWindow(HWND hWnd, UINT Relationship) break; case GW_OWNER: - if (WindowObject->Owner) - hWndResult = WindowObject->Owner->Self; + if((Parent = IntGetWindowObject(WindowObject->Owner))) + { + hWndResult = Parent->Self; + IntReleaseWindowObject(Parent); + } break; case GW_CHILD: if (WindowObject->FirstChild) hWndResult = WindowObject->FirstChild->Self; break; } + IntUnLockRelatives(WindowObject); IntReleaseWindowObject(WindowObject); - IntReleaseWinLock(); return hWndResult; } @@ -2500,7 +2546,7 @@ NtUserGetWindowDC(HWND hWnd) LONG STDCALL NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi) { - PWINDOW_OBJECT WindowObject; + PWINDOW_OBJECT WindowObject, Parent; LONG Result; DPRINT("NtUserGetWindowLong(%x,%d,%d)\n", hWnd, (INT)Index, Ansi); @@ -2555,10 +2601,17 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi) break; case GWL_HWNDPARENT: - if (WindowObject->Parent->Self == IntGetDesktopWindow()) - Result = (LONG) NtUserGetWindow(WindowObject->Self, GW_OWNER); - else - Result = (LONG) NtUserGetAncestor(WindowObject->Self, GA_PARENT); + IntLockRelatives(WindowObject); + Parent = IntGetWindowObject(WindowObject->Parent); + IntUnLockRelatives(WindowObject); + if(Parent) + { + if (Parent && Parent->Self == IntGetDesktopWindow()) + Result = (LONG) NtUserGetWindow(WindowObject->Self, GW_OWNER); + else + Result = (LONG) Parent->Self; + IntReleaseWindowObject(Parent); + } break; case GWL_ID: @@ -2596,7 +2649,7 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi) LONG STDCALL NtUserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi) { - PWINDOW_OBJECT WindowObject; + PWINDOW_OBJECT WindowObject, Parent; PW32PROCESS Process; PWINSTATION_OBJECT WindowStation; LONG OldValue; @@ -2684,10 +2737,13 @@ NtUserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi) break; case GWL_HWNDPARENT: - if (WindowObject->Parent->Self == IntGetDesktopWindow()) + Parent = IntGetParentObject(WindowObject); + if (Parent && (Parent->Self == IntGetDesktopWindow())) OldValue = (LONG) IntSetOwner(WindowObject->Self, (HWND) NewValue); else OldValue = (LONG) NtUserSetParent(WindowObject->Self, (HWND) NewValue); + if(Parent) + IntReleaseWindowObject(Parent); break; case GWL_ID: @@ -2841,24 +2897,22 @@ BOOL STDCALL NtUserGetWindowRect(HWND hWnd, LPRECT Rect) { PWINDOW_OBJECT Wnd; - RECT SafeRect; + NTSTATUS Status; - IntAcquireWinLockShared(); if (!(Wnd = IntGetWindowObject(hWnd))) { - IntReleaseWinLock(); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); return FALSE; } - - SafeRect = Wnd->WindowRect; - IntReleaseWinLock(); - - if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT)))) + Status = MmCopyToCaller(Rect, &Wnd->WindowRect, sizeof(RECT)); + if (!NT_SUCCESS(Status)) { + IntReleaseWindowObject(Wnd); + SetLastNtError(Status); return FALSE; } - + + IntReleaseWindowObject(Wnd); return TRUE; } @@ -2871,18 +2925,15 @@ NtUserGetWindowThreadProcessId(HWND hWnd, LPDWORD UnsafePid) { PWINDOW_OBJECT Wnd; DWORD tid, pid; - - IntAcquireWinLockShared(); - + if (!(Wnd = IntGetWindowObject(hWnd))) { - IntReleaseWinLock(); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); return 0; } - tid = IntGetWindowThreadProcessId(Wnd, &pid); - IntReleaseWinLock(); + tid = (DWORD)IntGetWndThreadId(Wnd); + pid = (DWORD)IntGetWndProcessId(Wnd); if (UnsafePid) MmCopyToCaller(UnsafePid, &pid, sizeof(DWORD)); @@ -2914,11 +2965,9 @@ NtUserMoveWindow( int nHeight, BOOL bRepaint) { - UINT flags = SWP_NOZORDER | SWP_NOACTIVATE; - - if(!bRepaint) - flags |= SWP_NOREDRAW; - return NtUserSetWindowPos(hWnd, 0, X, Y, nWidth, nHeight, flags); + return NtUserSetWindowPos(hWnd, 0, X, Y, nWidth, nHeight, + (bRepaint ? SWP_NOZORDER | SWP_NOACTIVATE : + SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW)); } /* @@ -2951,11 +3000,11 @@ NtUserQueryWindow(HWND hWnd, DWORD Index) switch(Index) { case 0x00: - Result = (DWORD)Window->OwnerThread->ThreadsProcess->UniqueProcessId; + Result = (DWORD)IntGetWndProcessId(Window); break; case 0x01: - Result = (DWORD)Window->OwnerThread->Cid.UniqueThread; + Result = (DWORD)IntGetWndThreadId(Window); break; default: @@ -3306,153 +3355,38 @@ NtUserValidateRect(HWND hWnd, const RECT* Rect) return (VOID)NtUserRedrawWindow(hWnd, Rect, 0, RDW_VALIDATE | RDW_NOCHILDREN); } -static BOOL IsStaticClass(PWINDOW_OBJECT Window) -{ - BOOL rc = FALSE; - - ASSERT(0 != Window->Class); - ASSERT(0 != Window->Class->Atom); - - DbgPrint("FIXME: Update IsStatic to really check if a window is a static\n"); - /* - if (0 == wcscmp((LPWSTR)Window->Class->lpszClassName, L"Static")) - rc = TRUE; - */ - return rc; -} - -static BOOL IsDisabled(PWINDOW_OBJECT Window) -{ - BOOL rc = FALSE; - ASSERT(0 != Window); - - rc = (Window->Style & WS_DISABLED); - - return rc; -} - -static PWINDOW_OBJECT RestrictiveSearchChildWindows(PWINDOW_OBJECT Window, POINT p) -{ - PWINDOW_OBJECT ChildWindow = 0; - PWINDOW_OBJECT rc = Window; - ASSERT(0 != Window); - - /* - **Aquire a mutex to the Child list. - */ - ExAcquireFastMutexUnsafe(&Window->ChildrenListLock); - - /* - **Now Find the first non-static window. - */ - ChildWindow = Window->FirstChild; - - while (0 != ChildWindow) - { - /* - **Test Restrictions on the window. - */ - if (!IsStaticClass(ChildWindow) && - !IsDisabled(ChildWindow) && - IntIsWindowVisible(ChildWindow->Self)) - { - /* - **Now find the deepest child window - */ - if (POINT_IN_RECT(p, ChildWindow->WindowRect)) - { - rc = RestrictiveSearchChildWindows(ChildWindow, p); - break; - } - } - ChildWindow = ChildWindow->NextSibling; - } - - /* - **Release mutex. - */ - ExReleaseFastMutexUnsafe(&Window->ChildrenListLock); - - return rc; -} /* - * NtUserWindowFromPoint - * - * Return Value - * The return value is a handle to the window that contains the point. - * If no window exists at the given point, the return value is NULL. - * If the point is over a static text control, the return value is a handle - * to the window under the static text control. - * - * Remarks - * The WindowFromPoint function does not retrieve a handle to a hidden or - * disabled window, even if the point is within the window. An application - * should use the ChildWindowFromPoint function for a nonrestrictive search. - * - * Author - * Mark Tempel - * - * Status * @implemented */ - HWND STDCALL NtUserWindowFromPoint(LONG X, LONG Y) { - HWND hWnd = 0; - PWINDOW_OBJECT DesktopWindow = 0; - PWINDOW_OBJECT TopWindow = 0; - PWINDOW_OBJECT ChildWindow = 0; POINT pt; + HWND Ret; + PWINDOW_OBJECT DesktopWindow, Window = NULL; - DesktopWindow = IntGetWindowObject(IntGetDesktopWindow()); - - pt.x = X; - pt.y = Y; - - if (DesktopWindow != NULL) + if ((DesktopWindow = IntGetWindowObject(IntGetDesktopWindow()))) { - /* - * Aquire the mutex to the child window list. (All the topmost windows) - */ - ExAcquireFastMutexUnsafe(&DesktopWindow->ChildrenListLock); - - /* - * Spin through the windows looking for the window that contains the - * point. The child windows are in Z-order. - */ - TopWindow = DesktopWindow->FirstChild; - while (TopWindow != NULL) + USHORT Hit; + + pt.x = X; + pt.y = Y; + + Hit = WinPosWindowFromPoint(DesktopWindow, pt, &Window); + + if(Window) { - if (POINT_IN_RECT(pt, TopWindow->WindowRect)) - { - break; - } - TopWindow = TopWindow->NextSibling; + Ret = Window->Self; + IntReleaseWindowObject(Window); + IntReleaseWindowObject(DesktopWindow); + return Ret; } - /* - * Search for the child window that contains the point. - */ - if (TopWindow != NULL) - { - ChildWindow = RestrictiveSearchChildWindows(TopWindow, pt); - if (ChildWindow != NULL) - { - hWnd = ChildWindow->Self; - } - } - - /* - * Release mutex. - */ - ExReleaseFastMutexUnsafe(&DesktopWindow->ChildrenListLock); + IntReleaseWindowObject(DesktopWindow); } - - IntReleaseWindowObject(DesktopWindow); - return hWnd; + return NULL; } diff --git a/reactos/subsys/win32k/ntuser/winlock.c b/reactos/subsys/win32k/ntuser/winlock.c deleted file mode 100644 index 3b1bb1d921f..00000000000 --- a/reactos/subsys/win32k/ntuser/winlock.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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. - */ -/* - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * PURPOSE: Windows++ locking - * FILE: subsys/win32k/ntuser/winlock.c - * PROGRAMER: Gunnar - * REVISION HISTORY: - * - */ -/* INCLUDES ******************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NDEBUG -#include -#include - -/* GLOBALS *****************************************************************/ - -static ERESOURCE WinLock; - -/* FUNCTIONS *****************************************************************/ - -BOOL FASTCALL IntVerifyWinLock(WINLOCK_TYPE Type) -{ - switch (Type) - { - case None: - return !ExIsResourceAcquiredSharedLite(&WinLock); - case Shared: /* NOTE: an exclusive lock is also a shared lock */ - case Any: - return ExIsResourceAcquiredSharedLite(&WinLock); - case Exclusive: - return ExIsResourceAcquiredExclusiveLite(&WinLock); - } - - KEBUGCHECK(0); - return FALSE; -} - -WINLOCK_TYPE FASTCALL IntSuspendWinLock() -{ - ASSERT_WINLOCK(Any); - - if (ExIsResourceAcquiredExclusiveLite(&WinLock)) return Exclusive; - - return Shared; -} - -VOID FASTCALL IntRestoreWinLock(WINLOCK_TYPE Type) -{ - switch (Type) - { - case Exclusive: - return IntAcquireWinLockExclusive(&WinLock); - case Shared: - return IntAcquireWinLockShared(&WinLock); - /* silence warnings */ - case None: - case Any: - break; - } - - KEBUGCHECK(0); -} - -inline VOID IntAcquireWinLockShared() -{ - KeEnterCriticalRegion(); - ExAcquireResourceSharedLite(&WinLock, TRUE /*Wait*/ ); -} - -inline VOID IntAcquireWinLockExclusive() -{ - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(&WinLock, TRUE /*Wait*/ ); -} - -inline VOID IntReleaseWinLock() -{ - ExReleaseResourceLite(&WinLock ); - KeLeaveCriticalRegion(); -} - -inline BOOL IntInitializeWinLock() -{ - ExInitializeResourceLite(&WinLock ); - return TRUE; -} - -inline VOID IntDeleteWinLock() -{ - ExDeleteResourceLite(&WinLock ); -} - -/* EOF */ diff --git a/reactos/subsys/win32k/ntuser/winpos.c b/reactos/subsys/win32k/ntuser/winpos.c index aa24ea7ca31..7e0c759d1cf 100644 --- a/reactos/subsys/win32k/ntuser/winpos.c +++ b/reactos/subsys/win32k/ntuser/winpos.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: winpos.c,v 1.97 2004/02/22 14:26:35 navaraf Exp $ +/* $Id: winpos.c,v 1.98 2004/02/24 01:30:58 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -122,34 +122,53 @@ NtUserGetClientOrigin(HWND hWnd, LPPOINT Point) VOID FASTCALL WinPosActivateOtherWindow(PWINDOW_OBJECT Window) { - PWINDOW_OBJECT Child; - PWINDOW_OBJECT TabooWindow = Window; + PWINDOW_OBJECT Child, Wnd = Window; + HWND *List, *phWnd; - for (;;) + if (!Window || IntIsDesktopWindow(Window)) + { + IntSetFocusMessageQueue(NULL); + return; + } + + for(;;) + { + Wnd = IntGetParentObject(Wnd); + if(!Wnd) { - if (NULL == Window || IntIsDesktopWindow(Window)) - { - IntSetFocusMessageQueue(NULL); - return; - } - Window = Window->Parent; - ExAcquireFastMutex(&(Window->ChildrenListLock)); - Child = Window->FirstChild; - while (NULL != Child) - { - if (Child != TabooWindow) - { - ExReleaseFastMutex(&(Window->ChildrenListLock)); - if (IntSetForegroundWindow(Child)) - { - return; - } - ExAcquireFastMutex(&(Window->ChildrenListLock)); - } - Child = Child->NextSibling; - } - ExReleaseFastMutex(&(Window->ChildrenListLock)); + IntSetFocusMessageQueue(NULL); + return; } + if(IntIsDesktopWindow(Wnd)) + { + IntReleaseWindowObject(Wnd); + IntSetFocusMessageQueue(NULL); + return; + } + if((List = IntWinListChildren(Window))) + { + for(phWnd = List; *phWnd; ++phWnd) + { + if(*phWnd == Window->Self) + { + continue; + } + + Child = IntGetWindowObject(*phWnd); + if(Child) + { + if(IntSetForegroundWindow(Child)) + { + IntReleaseWindowObject(Child); + ExFreePool(List); + return; + } + IntReleaseWindowObject(Child); + } + } + ExFreePool(List); + } + } } VOID STATIC FASTCALL @@ -161,6 +180,7 @@ WinPosFindIconPos(HWND hWnd, POINT *Pos) PINTERNALPOS FASTCALL WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect) { + PWINDOW_OBJECT Parent; INT XInc, YInc; if (WindowObject->InternalPos == NULL) @@ -168,10 +188,17 @@ WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect) RECT WorkArea; PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop; /* Or rather get it from the window? */ - if(IntIsDesktopWindow(WindowObject->Parent)) - WorkArea = *IntGetDesktopWorkArea(Desktop); + Parent = IntGetParentObject(WindowObject); + if(Parent) + { + if(IntIsDesktopWindow(Parent)) + WorkArea = *IntGetDesktopWorkArea(Desktop); + else + WorkArea = Parent->ClientRect; + IntReleaseWindowObject(Parent); + } else - WorkArea = WindowObject->Parent->ClientRect; + WorkArea = *IntGetDesktopWorkArea(Desktop); WindowObject->InternalPos = ExAllocatePoolWithTag(NonPagedPool, sizeof(INTERNALPOS), TAG_WININTLIST); if(!WindowObject->InternalPos) @@ -402,6 +429,7 @@ LONG STATIC FASTCALL WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos, RECT* WindowRect, RECT* ClientRect) { + PWINDOW_OBJECT Parent; UINT wvrFlags = 0; /* Send WM_NCCALCSIZE message to get new client area */ @@ -413,14 +441,15 @@ WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos, params.rgrc[0] = *WindowRect; params.rgrc[1] = Window->WindowRect; params.rgrc[2] = Window->ClientRect; - if (0 != (Window->Style & WS_CHILD)) + Parent = IntGetParentObject(Window); + if (0 != (Window->Style & WS_CHILD) && Parent) { - NtGdiOffsetRect(&(params.rgrc[0]), - Window->Parent->ClientRect.left, - - Window->Parent->ClientRect.top); - NtGdiOffsetRect(&(params.rgrc[1]), - Window->Parent->ClientRect.left, - - Window->Parent->ClientRect.top); - NtGdiOffsetRect(&(params.rgrc[2]), - Window->Parent->ClientRect.left, - - Window->Parent->ClientRect.top); + NtGdiOffsetRect(&(params.rgrc[0]), - Parent->ClientRect.left, + - Parent->ClientRect.top); + NtGdiOffsetRect(&(params.rgrc[1]), - Parent->ClientRect.left, + - Parent->ClientRect.top); + NtGdiOffsetRect(&(params.rgrc[2]), - Parent->ClientRect.left, + - Parent->ClientRect.top); } params.lppos = &winposCopy; winposCopy = *WinPos; @@ -432,10 +461,10 @@ WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos, params.rgrc[0].top <= params.rgrc[0].bottom) { *ClientRect = params.rgrc[0]; - if (Window->Style & WS_CHILD) + if ((Window->Style & WS_CHILD) && Parent) { - NtGdiOffsetRect(ClientRect, Window->Parent->ClientRect.left, - Window->Parent->ClientRect.top); + NtGdiOffsetRect(ClientRect, Parent->ClientRect.left, + Parent->ClientRect.top); } } @@ -454,6 +483,8 @@ WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos, { WinPos->flags &= ~SWP_NOCLIENTSIZE; } + if(Parent) + IntReleaseWindowObject(Parent); } else { @@ -492,13 +523,17 @@ WinPosDoWinPosChanging(PWINDOW_OBJECT WindowObject, if (!(WinPos->flags & SWP_NOMOVE)) { + PWINDOW_OBJECT Parent; X = WinPos->x; Y = WinPos->y; - if (0 != (WindowObject->Style & WS_CHILD)) + Parent = IntGetParentObject(WindowObject); + if ((0 != (WindowObject->Style & WS_CHILD)) && Parent) { - X += WindowObject->Parent->ClientRect.left; - Y += WindowObject->Parent->ClientRect.top; + X += Parent->ClientRect.left; + Y += Parent->ClientRect.top; } + if(Parent) + IntReleaseWindowObject(Parent); WindowRect->left = X; WindowRect->top = Y; WindowRect->right += X - WindowObject->WindowRect.left; @@ -588,8 +623,7 @@ WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter) VOID STATIC FASTCALL WinPosInternalMoveWindow(PWINDOW_OBJECT Window, INT MoveX, INT MoveY) { - HWND *Children; - UINT Count; + PWINDOW_OBJECT Child; Window->WindowRect.left += MoveX; Window->WindowRect.right += MoveX; @@ -600,18 +634,13 @@ WinPosInternalMoveWindow(PWINDOW_OBJECT Window, INT MoveX, INT MoveY) Window->ClientRect.right += MoveX; Window->ClientRect.top += MoveY; Window->ClientRect.bottom += MoveY; - - Children = IntWinListChildren(Window); - if (Children) + + IntLockRelatives(Window); + for(Child = Window->FirstChild; Child; Child = Child->NextSibling) { - for (Count = 0; Children[Count] != NULL; Count++) - { - Window = IntGetWindowObject(Children[Count]); - WinPosInternalMoveWindow(Window, MoveX, MoveY); - IntReleaseWindowObject(Window); - } - ExFreePool(Children); + WinPosInternalMoveWindow(Child, MoveX, MoveY); } + IntUnLockRelatives(Window); } /* @@ -691,13 +720,18 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window) if ((WinPos->hwndInsertAfter != HWND_TOP) && (WinPos->hwndInsertAfter != HWND_BOTTOM)) { + PWINDOW_OBJECT Parent = IntGetParentObject(Window); if (NtUserGetAncestor(WinPos->hwndInsertAfter, GA_PARENT) != - Window->Parent->Self) + (Parent ? Parent->Self : NULL)) { + if(Parent) + IntReleaseWindowObject(Parent); return FALSE; } else { + if(Parent) + IntReleaseWindowObject(Parent); /* * We don't need to change the Z order of hwnd if it's already * inserted after hwndInsertAfter or when inserting hwnd after @@ -812,26 +846,35 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx, PWINDOW_OBJECT ParentWindow; PWINDOW_OBJECT InsertAfterWindow; - ParentWindow = Window->Parent; - if (ParentWindow) + if ((ParentWindow = IntGetParentObject(Window))) { if (WinPos.hwndInsertAfter == HWND_TOP) InsertAfterWindow = NULL; else if (WinPos.hwndInsertAfter == HWND_BOTTOM) - InsertAfterWindow = IntGetWindowObject(ParentWindow->LastChild->Self); + { + IntLockRelatives(ParentWindow); + if(ParentWindow->LastChild) + { + IntReferenceWindowObject(ParentWindow->LastChild); + InsertAfterWindow = ParentWindow->LastChild; + } + else + InsertAfterWindow = NULL; + IntUnLockRelatives(ParentWindow); + } else InsertAfterWindow = IntGetWindowObject(WinPos.hwndInsertAfter); /* Do nothing if hwndInsertAfter is HWND_BOTTOM and Window is already the last window */ if (InsertAfterWindow != Window) { - ExAcquireFastMutexUnsafe(&ParentWindow->ChildrenListLock); IntUnlinkWindow(Window); IntLinkWindow(Window, ParentWindow, InsertAfterWindow); - ExReleaseFastMutexUnsafe(&ParentWindow->ChildrenListLock); } if (InsertAfterWindow != NULL) IntReleaseWindowObject(InsertAfterWindow); + + IntReleaseWindowObject(ParentWindow); } } @@ -1191,7 +1234,7 @@ WinPosShowWindow(HWND Wnd, INT Cmd) if (Wnd == IntGetThreadFocusWindow() || IntIsChildWindow(Wnd, IntGetThreadFocusWindow())) { - NtUserSetFocus(Window->Parent->Self); + NtUserSetFocus(Window->Parent); } } @@ -1238,71 +1281,78 @@ WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT *Point, PWINDOW_OBJECT* Window, USHORT *HitTest) { PWINDOW_OBJECT Current; + HWND *List, *phWnd; - ExAcquireFastMutexUnsafe(&ScopeWin->ChildrenListLock); - Current = ScopeWin->FirstChild; - while (Current) + if((List = IntWinListChildren(ScopeWin))) + { + for(phWnd = List; *phWnd; ++phWnd) { + if(!(Current = IntGetWindowObject(*phWnd))) + { + continue; + } + if (Current->Style & WS_VISIBLE && - ((!(Current->Style & WS_DISABLED)) || - (Current->Style & (WS_CHILD | WS_POPUP)) != WS_CHILD) && - (Point->x >= Current->WindowRect.left && + ((!(Current->Style & WS_DISABLED)) || + (Current->Style & (WS_CHILD | WS_POPUP)) != WS_CHILD) && + (Point->x >= Current->WindowRect.left && Point->x < Current->WindowRect.right && Point->y >= Current->WindowRect.top && Point->y < Current->WindowRect.bottom)) /* FIXME - check if Point is in window region */ - { - if(*Window) { - ObmDereferenceObject(*Window); - } - ObmReferenceObjectByPointer(Current, otWindow); - *Window = Current; - - if (Current->Style & WS_DISABLED) + if(*Window) { - ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock); - *HitTest = HTERROR; - return TRUE; + IntReleaseWindowObject(*Window); } - if(Current->MessageQueue == PsGetWin32Thread()->MessageQueue) - { - *HitTest = IntSendMessage(Current->Self, WM_NCHITTEST, 0, - MAKELONG(Point->x, Point->y)); - if((*HitTest) == (USHORT)HTTRANSPARENT) - { - Current = Current->NextSibling; - continue; - } - } - else - { - *HitTest = HTCLIENT; - } - - if (Point->x >= Current->ClientRect.left && - Point->x < Current->ClientRect.right && - Point->y >= Current->ClientRect.top && - Point->y < Current->ClientRect.bottom) - { - USHORT ChildHitTest; - if(WinPosSearchChildren(Current, Point, Window, &ChildHitTest)) - { - ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock); - *HitTest = ChildHitTest; - return TRUE; - } - } - - ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock); - return TRUE; - } - Current = Current->NextSibling; + *Window = Current; + + if(Current->Style & WS_DISABLED) + { + *HitTest = HTERROR; + ExFreePool(List); + return TRUE; + } + + if(Current->MessageQueue == PsGetWin32Thread()->MessageQueue) + { + *HitTest = IntSendMessage(Current->Self, WM_NCHITTEST, 0, + MAKELONG(Point->x, Point->y)); + if((*HitTest) == (USHORT)HTTRANSPARENT) + { + continue; + } + } + else + { + *HitTest = HTCLIENT; + } + + if(Point->x >= Current->ClientRect.left && + Point->x < Current->ClientRect.right && + Point->y >= Current->ClientRect.top && + Point->y < Current->ClientRect.bottom) + { + USHORT ChildHitTest; + if(WinPosSearchChildren(Current, Point, Window, &ChildHitTest)) + { + *HitTest = ChildHitTest; + ExFreePool(List); + return TRUE; + } + } + + ExFreePool(List); + return TRUE; + } + IntReleaseWindowObject(Current); } - - ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock); - if(*Window == NULL) - *HitTest = HTNOWHERE; + ExFreePool(List); + } + + if((*Window) == NULL) + HitTest = HTNOWHERE; + return FALSE; } @@ -1330,15 +1380,18 @@ WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, POINT WinPoint, /* Translate the point to the space of the scope window. */ DesktopWindowHandle = IntGetDesktopWindow(); - DesktopWindow = IntGetWindowObject(DesktopWindowHandle); - Point.x += ScopeWin->ClientRect.left - DesktopWindow->ClientRect.left; - Point.y += ScopeWin->ClientRect.top - DesktopWindow->ClientRect.top; - IntReleaseWindowObject(DesktopWindow); - + if((DesktopWindow = IntGetWindowObject(DesktopWindowHandle))) + { + Point.x += ScopeWin->ClientRect.left - DesktopWindow->ClientRect.left; + Point.y += ScopeWin->ClientRect.top - DesktopWindow->ClientRect.top; + IntReleaseWindowObject(DesktopWindow); + } + if(WinPosSearchChildren(ScopeWin, &Point, Window, &HitTest)) { return HitTest; } + return HTNOWHERE; }