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
This commit is contained in:
Thomas Bluemel 2004-02-24 01:30:58 +00:00
parent d8b7c0ee97
commit b13d239f87
13 changed files with 639 additions and 743 deletions

View file

@ -7,6 +7,7 @@ typedef struct _WINDOW_OBJECT *PWINDOW_OBJECT;
#include <windows.h>
#include <ddk/ntddk.h>
#include <include/object.h>
#include <include/class.h>
#include <include/msgqueue.h>
#include <include/winsta.h>
@ -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);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: 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)

View file

@ -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 \

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: 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 <ddk/ntddk.h>
#include <include/object.h>
#include <include/window.h>
#define NDEBUG
#include <debug.h>
@ -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;

View file

@ -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 <win32k/win32k.h>
#include <include/object.h>
#include <include/window.h>
#include <include/desktop.h>
#include <include/focus.h>
@ -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);
}
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: 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

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: 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))

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: 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)
{

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: 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);
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: windc.c,v 1.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)

File diff suppressed because it is too large Load diff

View file

@ -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 <ddk/ntddk.h>
#include <win32k/win32k.h>
#include <include/object.h>
#include <include/guicheck.h>
#include <include/window.h>
#include <include/class.h>
#include <include/error.h>
#include <include/winsta.h>
#include <include/winpos.h>
#include <include/callback.h>
#include <include/msgqueue.h>
#include <include/rect.h>
#define NDEBUG
#include <win32k/debug1.h>
#include <debug.h>
/* 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 */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: 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;
}