-WinStaLock is now WinLock & made global

-removed desktop window list
-fixed/reworked window linking
-SetParent/NtUserSetParent somewhat implemented
-misc

svn path=/trunk/; revision=5532
This commit is contained in:
Gunnar Dalsnes 2003-08-11 19:14:16 +00:00
parent 417dffd0c4
commit 9cc8d55331
16 changed files with 543 additions and 322 deletions

View file

@ -1406,11 +1406,11 @@ NtUserSetObjectInformation(
PVOID pvInformation, PVOID pvInformation,
DWORD nLength); DWORD nLength);
DWORD HWND
STDCALL STDCALL
NtUserSetParent( NtUserSetParent(
DWORD Unknown0, HWND hWndChild,
DWORD Unknown1); HWND hWndNewParent);
BOOL BOOL
STDCALL STDCALL

View file

@ -1,4 +1,4 @@
/* $Id: window.c,v 1.55 2003/08/11 10:30:19 gvg Exp $ /* $Id: window.c,v 1.56 2003/08/11 19:09:53 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll * PROJECT: ReactOS user32.dll
@ -1374,8 +1374,7 @@ HWND STDCALL
SetParent(HWND hWndChild, SetParent(HWND hWndChild,
HWND hWndNewParent) HWND hWndNewParent)
{ {
UNIMPLEMENTED; return NtUserSetParent(hWndChild, hWndNewParent);
return (HWND)0;
} }

View file

@ -19,7 +19,6 @@ typedef struct _WINSTATION_OBJECT
PRTL_ATOM_TABLE AtomTable; PRTL_ATOM_TABLE AtomTable;
PVOID HandleTable; PVOID HandleTable;
struct _DESKTOP_OBJECT* ActiveDesktop; struct _DESKTOP_OBJECT* ActiveDesktop;
ERESOURCE Resource;
/* FIXME: Clipboard */ /* FIXME: Clipboard */
} WINSTATION_OBJECT, *PWINSTATION_OBJECT; } WINSTATION_OBJECT, *PWINSTATION_OBJECT;
@ -32,8 +31,6 @@ typedef struct _DESKTOP_OBJECT
UNICODE_STRING Name; UNICODE_STRING Name;
/* Pointer to the associated window station. */ /* Pointer to the associated window station. */
struct _WINSTATION_OBJECT *WindowStation; struct _WINSTATION_OBJECT *WindowStation;
/* Head of the list of windows in this desktop. */
LIST_ENTRY WindowListHead;
/* Pointer to the active queue. */ /* Pointer to the active queue. */
PVOID ActiveMessageQueue; PVOID ActiveMessageQueue;
/* Handle of the desktop window. */ /* Handle of the desktop window. */

View file

@ -47,8 +47,6 @@ typedef struct _WINDOW_OBJECT
LPVOID Parameters; LPVOID Parameters;
/* Entry in the thread's list of windows. */ /* Entry in the thread's list of windows. */
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
/* Entry in the global list of windows. */
LIST_ENTRY DesktopListEntry;
/* Pointer to the extra data associated with the window. */ /* Pointer to the extra data associated with the window. */
PULONG ExtraData; PULONG ExtraData;
/* Size of the extra data associated with the window. */ /* Size of the extra data associated with the window. */
@ -67,15 +65,10 @@ typedef struct _WINDOW_OBJECT
HANDLE UpdateRegion; HANDLE UpdateRegion;
/* Pointer to the owning thread's message queue. */ /* Pointer to the owning thread's message queue. */
PUSER_MESSAGE_QUEUE MessageQueue; PUSER_MESSAGE_QUEUE MessageQueue;
/* Head of the list of child windows. */
LIST_ENTRY ChildrenListHead;
struct _WINDOW_OBJECT* FirstChild; struct _WINDOW_OBJECT* FirstChild;
struct _WINDOW_OBJECT* LastChild; struct _WINDOW_OBJECT* LastChild;
/* Lock for the list of child windows. */ /* Lock for the list of child windows. */
FAST_MUTEX ChildrenListLock; FAST_MUTEX ChildrenListLock;
/* Entry in the parent's list of child windows. */
LIST_ENTRY SiblingListEntry;
struct _WINDOW_OBJECT* NextSibling; struct _WINDOW_OBJECT* NextSibling;
struct _WINDOW_OBJECT* PrevSibling; struct _WINDOW_OBJECT* PrevSibling;
/* Entry in the list of thread windows. */ /* Entry in the list of thread windows. */
@ -95,8 +88,8 @@ typedef struct _WINDOW_OBJECT
WNDPROC WndProcA; WNDPROC WndProcA;
WNDPROC WndProcW; WNDPROC WndProcW;
PETHREAD OwnerThread; PETHREAD OwnerThread;
HWND hWndOwner; /* handle to the owner window (why not use pointer to window? wine doesn't...)*/ HWND hWndOwner; /* handle to the owner window (wine doesn't use pointer, for unk. reason)*/
HWND hWndLastPopup; /* handle to last active popup window (why not use pointer to window? wine doesn't...)*/ HWND hWndLastPopup; /* handle to last active popup window (wine doesn't use pointer, for unk. reason)*/
} WINDOW_OBJECT, *PWINDOW_OBJECT; } WINDOW_OBJECT, *PWINDOW_OBJECT;
/* Window flags. */ /* Window flags. */
@ -107,6 +100,10 @@ typedef struct _WINDOW_OBJECT
#define WINDOWOBJECT_NEED_INTERNALPAINT (0x00000010) #define WINDOWOBJECT_NEED_INTERNALPAINT (0x00000010)
#define WINDOWOBJECT_RESTOREMAX (0x00000020) #define WINDOWOBJECT_RESTOREMAX (0x00000020)
inline BOOL W32kIsDesktopWindow(PWINDOW_OBJECT WindowObject);
inline BOOL W32kIsBroadcastHwnd( HWND hwnd );
NTSTATUS FASTCALL NTSTATUS FASTCALL
InitWindowImpl (VOID); InitWindowImpl (VOID);
@ -127,9 +124,6 @@ W32kCreateDesktopWindow (PWINSTATION_OBJECT WindowStation,
PWNDCLASS_OBJECT DesktopClass, PWNDCLASS_OBJECT DesktopClass,
ULONG Width, ULONG Height); ULONG Width, ULONG Height);
BOOL FASTCALL
W32kIsDesktopWindow (PWINDOW_OBJECT Window);
HWND FASTCALL HWND FASTCALL
W32kGetActiveWindow (VOID); W32kGetActiveWindow (VOID);
@ -169,6 +163,25 @@ W32kGetAncestor(PWINDOW_OBJECT Wnd, UINT Type);
PWINDOW_OBJECT FASTCALL PWINDOW_OBJECT FASTCALL
W32kGetParent(PWINDOW_OBJECT Wnd); W32kGetParent(PWINDOW_OBJECT Wnd);
typedef enum _WINLOCK_TYPE
{
None,
Any,
Shared,
Exclusive
} WINLOCK_TYPE;
#define ASSERT_WINLOCK(a) assert(W32kVerifyWinLock(a))
inline VOID W32kAcquireWinLockShared();
inline VOID W32kAcquireWinLockExclusive();
inline VOID W32kReleaseWinLock();
BOOL FASTCALL W32kVerifyWinLock(WINLOCK_TYPE Type);
WINLOCK_TYPE FASTCALL W32kSuspendWinLock();
VOID FASTCALL W32kRestoreWinLock(WINLOCK_TYPE Type);
inline BOOL W32kInitializeWinLock();
inline VOID W32kDeleteWinLock();
#endif /* __WIN32K_WINDOW_H */ #endif /* __WIN32K_WINDOW_H */
/* EOF */ /* EOF */

View file

@ -7,14 +7,6 @@
#include <internal/ps.h> #include <internal/ps.h>
#include "msgqueue.h" #include "msgqueue.h"
typedef enum _WINSTA_LOCK_TYPE
{
None,
Any,
Exclusive
} WINSTA_LOCK_TYPE;
#define ASSERT_WINSTA_LOCK(a) (ASSERT(W32kVerifyWinStaLock(a)))
#define PROCESS_WINDOW_STATION() \ #define PROCESS_WINDOW_STATION() \
((HWINSTA)(IoGetCurrentProcess()->Win32WindowStation)) ((HWINSTA)(IoGetCurrentProcess()->Win32WindowStation))
@ -61,11 +53,6 @@ W32kGetCaptureWindow(VOID);
VOID STDCALL VOID STDCALL
W32kSetCaptureWindow(struct _WINDOW_OBJECT* Window); W32kSetCaptureWindow(struct _WINDOW_OBJECT* Window);
inline VOID W32kAcquireWinStaLockShared();
inline VOID W32kAcquireWinStaLockExclusive();
inline VOID W32kReleaseWinStaLock();
BOOL FASTCALL W32kVerifyWinStaLock(WINSTA_LOCK_TYPE Type);
#endif /* __WIN32K_WINSTA_H */ #endif /* __WIN32K_WINSTA_H */
/* EOF */ /* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: dllmain.c,v 1.41 2003/07/31 23:11:38 weiden Exp $ /* $Id: dllmain.c,v 1.42 2003/08/11 19:06:25 gdalsnes Exp $
* *
* Entry Point for win32k.sys * Entry Point for win32k.sys
*/ */
@ -169,6 +169,8 @@ DllMain (
NTSTATUS Status; NTSTATUS Status;
BOOLEAN Result; BOOLEAN Result;
W32kInitializeWinLock();
/* /*
* Register user mode call interface * Register user mode call interface
* (system service table index = 1) * (system service table index = 1)

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.72 2003/08/07 04:03:25 royce Exp $ # $Id: makefile,v 1.73 2003/08/11 19:08:40 gdalsnes Exp $
PATH_TO_TOP = ../.. PATH_TO_TOP = ../..
@ -54,7 +54,8 @@ NTUSER_OBJECTS = ntuser/class.o ntuser/guicheck.o ntuser/hook.o \
ntuser/input.o ntuser/keyboard.o ntuser/callback.o \ ntuser/input.o ntuser/keyboard.o ntuser/callback.o \
ntuser/winpos.o ntuser/painting.o ntuser/metric.o \ ntuser/winpos.o ntuser/painting.o ntuser/metric.o \
ntuser/windc.o ntuser/prop.o ntuser/scrollbar.o \ ntuser/windc.o ntuser/prop.o ntuser/scrollbar.o \
ntuser/timer.o ntuser/misc.o ntuser/vis.o ntuser/timer.o ntuser/misc.o ntuser/vis.o \
ntuser/winlock.o
OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \ OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \
objects/color.o objects/coord.o objects/dc.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 * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: painting.c,v 1.24 2003/08/06 15:27:27 dwelch Exp $ /* $Id: painting.c,v 1.25 2003/08/11 19:05:27 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -47,6 +47,7 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
/* client rect in window coordinates */ /* client rect in window coordinates */
@ -251,7 +252,7 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
*/ */
BOOL HadOne = NULL != Window->UpdateRegion && NULL != hRgn; BOOL HadOne = NULL != Window->UpdateRegion && NULL != hRgn;
BOOL HasChildren = !IsListEmpty(&Window->ChildrenListHead) && BOOL HasChildren = Window->FirstChild &&
!(Flags & RDW_NOCHILDREN) && !(Window->Style & WS_MINIMIZE) && !(Flags & RDW_NOCHILDREN) && !(Window->Style & WS_MINIMIZE) &&
((Flags & RDW_ALLCHILDREN) || !(Window->Style & WS_CLIPCHILDREN)); ((Flags & RDW_ALLCHILDREN) || !(Window->Style & WS_CLIPCHILDREN));
RECT Rect; RECT Rect;
@ -390,17 +391,14 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
POINT PrevOrign = {0, 0}; POINT PrevOrign = {0, 0};
POINT Client; POINT Client;
PWINDOW_OBJECT Child; PWINDOW_OBJECT Child;
PLIST_ENTRY ChildListEntry;
Client.x = Window->ClientRect.left - Window->WindowRect.left; Client.x = Window->ClientRect.left - Window->WindowRect.left;
Client.y = Window->ClientRect.top - Window->WindowRect.top; Client.y = Window->ClientRect.top - Window->WindowRect.top;
ExAcquireFastMutexUnsafe(&Window->ChildrenListLock); ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
ChildListEntry = Window->ChildrenListHead.Flink; Child = Window->FirstChild;
while (ChildListEntry != &Window->ChildrenListHead) while (Child)
{ {
Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT,
SiblingListEntry);
if (0 != (Child->Style & WS_VISIBLE)) if (0 != (Child->Style & WS_VISIBLE))
{ {
POINT Offset; POINT Offset;
@ -424,7 +422,7 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
Total.y += Offset.y; Total.y += Offset.y;
} }
} }
ChildListEntry = ChildListEntry->Flink; Child = Child->NextSibling;
} }
ExReleaseFastMutexUnsafe(&Window->ChildrenListLock); ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
@ -436,19 +434,16 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
if (HasChildren) if (HasChildren)
{ {
PWINDOW_OBJECT Child; PWINDOW_OBJECT Child;
PLIST_ENTRY ChildListEntry;
ExAcquireFastMutexUnsafe(&Window->ChildrenListLock); ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
ChildListEntry = Window->ChildrenListHead.Flink; Child = Window->FirstChild;
while (ChildListEntry != &Window->ChildrenListHead) while (Child)
{ {
Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT,
SiblingListEntry);
if (Child->Style & WS_VISIBLE) if (Child->Style & WS_VISIBLE)
{ {
PaintUpdateRgns(Child, hRgn, Flags, FALSE); PaintUpdateRgns(Child, hRgn, Flags, FALSE);
} }
ChildListEntry = ChildListEntry->Flink; Child = Child->NextSibling;
} }
ExReleaseFastMutexUnsafe(&Window->ChildrenListLock); ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
} }
@ -682,11 +677,9 @@ PaintingFindWinToRepaint(HWND hWnd, PW32THREAD Thread)
} }
ExAcquireFastMutex(&BaseWindow->ChildrenListLock); ExAcquireFastMutex(&BaseWindow->ChildrenListLock);
current_entry = BaseWindow->ChildrenListHead.Flink; Window = BaseWindow->FirstChild;
while (current_entry != &BaseWindow->ChildrenListHead) while (Window)
{ {
Window = CONTAINING_RECORD(current_entry, WINDOW_OBJECT,
SiblingListEntry);
if (Window->Style & WS_VISIBLE) if (Window->Style & WS_VISIBLE)
{ {
hFoundWnd = PaintingFindWinToRepaint(Window->Self, Thread); hFoundWnd = PaintingFindWinToRepaint(Window->Self, Thread);
@ -695,9 +688,10 @@ PaintingFindWinToRepaint(HWND hWnd, PW32THREAD Thread)
break; break;
} }
} }
current_entry = current_entry->Flink; Window = Window->NextSibling;
} }
ExReleaseFastMutex(&BaseWindow->ChildrenListLock); ExReleaseFastMutex(&BaseWindow->ChildrenListLock);
W32kReleaseWindowObject(BaseWindow); W32kReleaseWindowObject(BaseWindow);
return(hFoundWnd); return(hFoundWnd);
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: prop.c,v 1.3 2003/08/02 16:32:18 gdalsnes Exp $ /* $Id: prop.c,v 1.4 2003/08/11 19:05:27 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -109,11 +109,11 @@ NtUserGetProp(HWND hWnd, ATOM Atom)
PPROPERTY Prop; PPROPERTY Prop;
HANDLE Data = NULL; HANDLE Data = NULL;
W32kAcquireWinStaLockShared(); W32kAcquireWinLockShared();
if (!(WindowObject = W32kGetWindowObject(hWnd))) if (!(WindowObject = W32kGetWindowObject(hWnd)))
{ {
W32kReleaseWinStaLock(); W32kReleaseWinLock();
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return FALSE; return FALSE;
} }
@ -124,7 +124,7 @@ NtUserGetProp(HWND hWnd, ATOM Atom)
Data = Prop->Data; Data = Prop->Data;
} }
W32kReleaseWinStaLock(); W32kReleaseWinLock();
return(Data); return(Data);
} }
@ -155,18 +155,18 @@ NtUserSetProp(HWND hWnd, ATOM Atom, HANDLE Data)
PWINDOW_OBJECT Wnd; PWINDOW_OBJECT Wnd;
BOOL ret; BOOL ret;
W32kAcquireWinStaLockExclusive(); W32kAcquireWinLockExclusive();
if (!(Wnd = W32kGetWindowObject(hWnd))) if (!(Wnd = W32kGetWindowObject(hWnd)))
{ {
W32kReleaseWinStaLock(); W32kReleaseWinLock();
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return FALSE; return FALSE;
} }
ret = W32kSetProp(Wnd, Atom, Data); ret = W32kSetProp(Wnd, Atom, Data);
W32kReleaseWinStaLock(); W32kReleaseWinLock();
return ret; return ret;
} }

View file

@ -1,4 +1,4 @@
/* $Id: stubs.c,v 1.24 2003/08/06 13:17:44 weiden Exp $ /* $Id: stubs.c,v 1.25 2003/08/11 19:05:27 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -1033,16 +1033,6 @@ NtUserSetImeHotKey(
return 0; return 0;
} }
DWORD
STDCALL
NtUserSetParent(
DWORD Unknown0,
DWORD Unknown1)
{
UNIMPLEMENTED
return 0;
}
DWORD DWORD
STDCALL STDCALL

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* $Id: vis.c,v 1.4 2003/08/04 16:54:54 gdalsnes Exp $ * $Id: vis.c,v 1.5 2003/08/11 19:05:27 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -101,21 +101,19 @@ STATIC BOOL FASTCALL
VIS_AddClipRects(PWINDOW_OBJECT Parent, PWINDOW_OBJECT End, VIS_AddClipRects(PWINDOW_OBJECT Parent, PWINDOW_OBJECT End,
HRGN ClipRgn, PRECT Rect) HRGN ClipRgn, PRECT Rect)
{ {
PLIST_ENTRY ChildListEntry;
PWINDOW_OBJECT Child; PWINDOW_OBJECT Child;
RECT Intersect; RECT Intersect;
ExAcquireFastMutexUnsafe(&Parent->ChildrenListLock); ExAcquireFastMutexUnsafe(&Parent->ChildrenListLock);
ChildListEntry = Parent->ChildrenListHead.Flink; Child = Parent->FirstChild;
while (ChildListEntry != &Parent->ChildrenListHead) while (Child)
{ {
Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT,
SiblingListEntry);
if (Child == End) if (Child == End)
{ {
ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock); ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock);
return TRUE; return TRUE;
} }
if (Child->Style & WS_VISIBLE) if (Child->Style & WS_VISIBLE)
{ {
if (W32kIntersectRect(&Intersect, &Child->WindowRect, Rect)) if (W32kIntersectRect(&Intersect, &Child->WindowRect, Rect))
@ -123,10 +121,12 @@ VIS_AddClipRects(PWINDOW_OBJECT Parent, PWINDOW_OBJECT End,
UnsafeW32kUnionRectWithRgn(ClipRgn, &Child->WindowRect); UnsafeW32kUnionRectWithRgn(ClipRgn, &Child->WindowRect);
} }
} }
ChildListEntry = ChildListEntry->Flink;
Child = Child->NextSibling;
} }
ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock); ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock);
return FALSE; return FALSE;
} }
@ -156,8 +156,7 @@ VIS_ComputeVisibleRegion(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
if (ClipRgn != NULL) if (ClipRgn != NULL)
{ {
if (ClipChildren && if (ClipChildren && Window->FirstChild)
! IsListEmpty(&Window->ChildrenListHead))
{ {
VIS_AddClipRects(Window, NULL, ClipRgn, &Rect); VIS_AddClipRects(Window, NULL, ClipRgn, &Rect);
} }
@ -217,18 +216,17 @@ VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
{ {
PWINDOW_OBJECT DesktopWindow; PWINDOW_OBJECT DesktopWindow;
PWINDOW_OBJECT Child; PWINDOW_OBJECT Child;
PLIST_ENTRY CurrentEntry;
HRGN Uncovered; HRGN Uncovered;
HRGN Covered; HRGN Covered;
HRGN Repaint; HRGN Repaint;
DesktopWindow = W32kGetWindowObject(Desktop->DesktopWindow); DesktopWindow = W32kGetWindowObject(Desktop->DesktopWindow);
Uncovered = UnsafeW32kCreateRectRgnIndirect(&DesktopWindow->WindowRect); Uncovered = UnsafeW32kCreateRectRgnIndirect(&DesktopWindow->WindowRect);
ExAcquireFastMutexUnsafe(&DesktopWindow->ChildrenListLock); ExAcquireFastMutexUnsafe(&DesktopWindow->ChildrenListLock);
CurrentEntry = DesktopWindow->ChildrenListHead.Flink; Child = DesktopWindow->FirstChild;
while (CurrentEntry != &DesktopWindow->ChildrenListHead) while (Child)
{ {
Child = CONTAINING_RECORD(CurrentEntry, WINDOW_OBJECT, SiblingListEntry);
if (0 != (Child->Style & WS_VISIBLE)) if (0 != (Child->Style & WS_VISIBLE))
{ {
Covered = UnsafeW32kCreateRectRgnIndirect(&Child->WindowRect); Covered = UnsafeW32kCreateRectRgnIndirect(&Child->WindowRect);
@ -236,7 +234,7 @@ VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
PaintRedrawWindow(Child, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE, 0); PaintRedrawWindow(Child, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE, 0);
W32kDeleteObject(Covered); W32kDeleteObject(Covered);
} }
CurrentEntry = CurrentEntry->Flink; Child = Child->NextSibling;
} }
ExReleaseFastMutexUnsafe(&DesktopWindow->ChildrenListLock); ExReleaseFastMutexUnsafe(&DesktopWindow->ChildrenListLock);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: windc.c,v 1.18 2003/08/06 16:47:35 weiden Exp $ /* $Id: windc.c,v 1.19 2003/08/11 19:05:26 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -81,7 +81,7 @@ DceGetVisRgn(HWND hWnd, ULONG Flags, HWND hWndChild, ULONG CFlags)
Child = W32kGetWindowObject(hWnd); Child = W32kGetWindowObject(hWnd);
if (NULL != Child) if (NULL != Child)
{ {
if (! IsListEmpty(&Child->ChildrenListHead)) if (Child->FirstChild)
{ {
/* Compute the visible region of the child */ /* Compute the visible region of the child */
VisChild = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop, VisChild = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: window.c,v 1.85 2003/08/11 10:30:19 gvg Exp $ /* $Id: window.c,v 1.86 2003/08/11 19:05:26 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -65,11 +65,22 @@ static LIST_ENTRY RegisteredMessageListHead;
#define REGISTERED_MESSAGE_MIN 0xc000 #define REGISTERED_MESSAGE_MIN 0xc000
#define REGISTERED_MESSAGE_MAX 0xffff #define REGISTERED_MESSAGE_MAX 0xffff
PWINDOW_OBJECT FASTCALL
W32kGetParent(PWINDOW_OBJECT Wnd);
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
/* check if hwnd is a broadcast magic handle */
inline BOOL W32kIsBroadcastHwnd( HWND hwnd )
{
return (hwnd == HWND_BROADCAST || hwnd == HWND_TOPMOST);
}
inline BOOL W32kIsDesktopWindow(PWINDOW_OBJECT Wnd)
{
return Wnd->Parent == NULL;
}
PWINDOW_OBJECT FASTCALL PWINDOW_OBJECT FASTCALL
W32kGetAncestor(PWINDOW_OBJECT Wnd, UINT Type) W32kGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
{ {
@ -102,7 +113,7 @@ NtUserGetAncestor(HWND hWnd, UINT Type)
PWINDOW_OBJECT Wnd, WndAncestor; PWINDOW_OBJECT Wnd, WndAncestor;
HWND hWndAncestor = NULL; HWND hWndAncestor = NULL;
W32kAcquireWinStaLockShared(); W32kAcquireWinLockShared();
if (!(Wnd = W32kGetWindowObject(hWnd))) if (!(Wnd = W32kGetWindowObject(hWnd)))
{ {
@ -113,7 +124,7 @@ NtUserGetAncestor(HWND hWnd, UINT Type)
WndAncestor = W32kGetAncestor(Wnd, Type); WndAncestor = W32kGetAncestor(Wnd, Type);
if (WndAncestor) hWndAncestor = WndAncestor->Self; if (WndAncestor) hWndAncestor = WndAncestor->Self;
W32kReleaseWinStaLock(); W32kReleaseWinLock();
return hWndAncestor; return hWndAncestor;
} }
@ -140,7 +151,7 @@ NtUserGetParent(HWND hWnd)
PWINDOW_OBJECT Wnd, WndParent; PWINDOW_OBJECT Wnd, WndParent;
HWND hWndParent = NULL; HWND hWndParent = NULL;
W32kAcquireWinStaLockShared(); W32kAcquireWinLockShared();
if (!(Wnd = W32kGetWindowObject(hWnd))) if (!(Wnd = W32kGetWindowObject(hWnd)))
{ {
@ -151,7 +162,7 @@ NtUserGetParent(HWND hWnd)
WndParent = W32kGetParent(Wnd); WndParent = W32kGetParent(Wnd);
if (WndParent) hWndParent = WndParent->Self; if (WndParent) hWndParent = WndParent->Self;
W32kReleaseWinStaLock(); W32kReleaseWinLock();
return hWndParent; return hWndParent;
} }
@ -260,14 +271,6 @@ W32kIsWindowVisible(HWND Wnd)
return(Result); return(Result);
} }
BOOL FASTCALL
W32kIsDesktopWindow(PWINDOW_OBJECT WindowObject)
{
BOOL IsDesktop;
ASSERT(WindowObject);
IsDesktop = WindowObject->Parent == NULL;
return(IsDesktop);
}
HWND FASTCALL W32kGetDesktopWindow(VOID) HWND FASTCALL W32kGetDesktopWindow(VOID)
{ {
@ -328,16 +331,16 @@ NtUserGetWindowRect(HWND hWnd, LPRECT Rect)
PWINDOW_OBJECT Wnd; PWINDOW_OBJECT Wnd;
RECT SafeRect; RECT SafeRect;
W32kAcquireWinStaLockShared(); W32kAcquireWinLockShared();
if (!(Wnd = W32kGetWindowObject(hWnd))) if (!(Wnd = W32kGetWindowObject(hWnd)))
{ {
W32kReleaseWinStaLock(); W32kReleaseWinLock();
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return FALSE; return FALSE;
} }
SafeRect = Wnd->WindowRect; SafeRect = Wnd->WindowRect;
W32kReleaseWinStaLock(); W32kReleaseWinLock();
if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT)))) if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
{ {
@ -360,16 +363,16 @@ NtUserGetClientRect(HWND hWnd, LPRECT Rect)
PWINDOW_OBJECT WindowObject; PWINDOW_OBJECT WindowObject;
RECT SafeRect; RECT SafeRect;
W32kAcquireWinStaLockShared(); W32kAcquireWinLockShared();
if (!(WindowObject = W32kGetWindowObject(hWnd))) if (!(WindowObject = W32kGetWindowObject(hWnd)))
{ {
W32kReleaseWinStaLock(); W32kReleaseWinLock();
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return FALSE; return FALSE;
} }
W32kGetClientRect(WindowObject, &SafeRect); W32kGetClientRect(WindowObject, &SafeRect);
W32kReleaseWinStaLock(); W32kReleaseWinLock();
if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT)))) if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
{ {
@ -496,8 +499,11 @@ W32kCreateDesktopWindow(PWINSTATION_OBJECT WindowStation,
WindowObject->WndProcA = DesktopClass->lpfnWndProcA; WindowObject->WndProcA = DesktopClass->lpfnWndProcA;
WindowObject->WndProcW = DesktopClass->lpfnWndProcW; WindowObject->WndProcW = DesktopClass->lpfnWndProcW;
WindowObject->OwnerThread = PsGetCurrentThread(); WindowObject->OwnerThread = PsGetCurrentThread();
WindowObject->FirstChild = NULL;
WindowObject->LastChild = NULL;
WindowObject->PrevSibling = NULL;
WindowObject->NextSibling = NULL;
InitializeListHead(&WindowObject->ChildrenListHead);
ExInitializeFastMutex(&WindowObject->ChildrenListLock); ExInitializeFastMutex(&WindowObject->ChildrenListLock);
WindowName = ExAllocatePool(NonPagedPool, sizeof(L"DESKTOP")); WindowName = ExAllocatePool(NonPagedPool, sizeof(L"DESKTOP"));
@ -528,6 +534,49 @@ W32kInitDesktopWindow(ULONG Width, ULONG Height)
W32kReleaseWindowObject(DesktopWindow); W32kReleaseWindowObject(DesktopWindow);
} }
/* link the window into siblings and parent. children are kept in place. */
VOID FASTCALL
W32kLinkWindow(
PWINDOW_OBJECT Wnd,
PWINDOW_OBJECT WndParent,
PWINDOW_OBJECT WndPrevSibling /* set to NULL if top sibling */
)
{
Wnd->Parent = WndParent;
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;
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;
}
}
/* unlink the window from siblings and parent. children are kept in place. */
VOID FASTCALL
W32kUnlinkWindow(PWINDOW_OBJECT Wnd)
{
PWINDOW_OBJECT WndParent = Wnd->Parent;
if (Wnd->NextSibling) Wnd->NextSibling->PrevSibling = Wnd->PrevSibling;
else if (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 (parent->first_unlinked == win) parent->first_unlinked = Wnd->NextSibling;
}
HWND STDCALL HWND STDCALL
NtUserCreateWindowEx(DWORD dwExStyle, NtUserCreateWindowEx(DWORD dwExStyle,
PUNICODE_STRING lpClassName, PUNICODE_STRING lpClassName,
@ -566,6 +615,8 @@ NtUserCreateWindowEx(DWORD dwExStyle,
return((HWND)0); return((HWND)0);
} }
/* FIXME: parent must belong to the current process */
if (hWndParent != NULL) if (hWndParent != NULL)
{ {
ParentWindow = W32kGetWindowObject(hWndParent); ParentWindow = W32kGetWindowObject(hWndParent);
@ -646,6 +697,10 @@ NtUserCreateWindowEx(DWORD dwExStyle,
WindowObject->WndProcA = ClassObject->lpfnWndProcA; WindowObject->WndProcA = ClassObject->lpfnWndProcA;
WindowObject->WndProcW = ClassObject->lpfnWndProcW; WindowObject->WndProcW = ClassObject->lpfnWndProcW;
WindowObject->OwnerThread = PsGetCurrentThread(); WindowObject->OwnerThread = PsGetCurrentThread();
WindowObject->FirstChild = NULL;
WindowObject->LastChild = NULL;
WindowObject->PrevSibling = NULL;
WindowObject->NextSibling = NULL;
/* extra window data */ /* extra window data */
if (ClassObject->cbWndExtra != 0) if (ClassObject->cbWndExtra != 0)
@ -660,12 +715,6 @@ NtUserCreateWindowEx(DWORD dwExStyle,
WindowObject->ExtraDataSize = 0; WindowObject->ExtraDataSize = 0;
} }
ExAcquireFastMutexUnsafe(&ParentWindow->ChildrenListLock);
InsertHeadList(&ParentWindow->ChildrenListHead,
&WindowObject->SiblingListEntry);
ExReleaseFastMutexUnsafe(&ParentWindow->ChildrenListLock);
InitializeListHead(&WindowObject->ChildrenListHead);
InitializeListHead(&WindowObject->PropListHead); InitializeListHead(&WindowObject->PropListHead);
ExInitializeFastMutex(&WindowObject->ChildrenListLock); ExInitializeFastMutex(&WindowObject->ChildrenListLock);
@ -690,12 +739,6 @@ NtUserCreateWindowEx(DWORD dwExStyle,
&WindowObject->ThreadListEntry); &WindowObject->ThreadListEntry);
ExReleaseFastMutexUnsafe (&PsGetWin32Thread()->WindowListLock); ExReleaseFastMutexUnsafe (&PsGetWin32Thread()->WindowListLock);
/*
* Insert the window into the list of windows associated with the thread's
* desktop.
*/
InsertTailList(&PsGetWin32Thread()->Desktop->WindowListHead,
&WindowObject->DesktopListEntry);
/* Allocate a DCE for this window. */ /* Allocate a DCE for this window. */
if (dwStyle & CS_OWNDC) WindowObject->Dce = DceAllocDCE(WindowObject->Self,DCE_WINDOW_DC); if (dwStyle & CS_OWNDC) WindowObject->Dce = DceAllocDCE(WindowObject->Self,DCE_WINDOW_DC);
/* FIXME: Handle "CS_CLASSDC" */ /* FIXME: Handle "CS_CLASSDC" */
@ -712,6 +755,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
*/ */
if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD))) if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD)))
{ {
/* WinPosGetMinMaxInfo sends the WM_GETMINMAXINFO message */
WinPosGetMinMaxInfo(WindowObject, &MaxSize, &MaxPos, &MinTrack, WinPosGetMinMaxInfo(WindowObject, &MaxSize, &MaxPos, &MinTrack,
&MaxTrack); &MaxTrack);
x = min(MaxSize.x, y); x = min(MaxSize.x, y);
@ -761,6 +805,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
MaxPos.x = WindowObject->WindowRect.left; MaxPos.x = WindowObject->WindowRect.left;
MaxPos.y = WindowObject->WindowRect.top; MaxPos.y = WindowObject->WindowRect.top;
DPRINT("NtUserCreateWindowEx(): About to get non-client size.\n"); DPRINT("NtUserCreateWindowEx(): About to get non-client size.\n");
/* WinPosGetNonClientSize SENDS THE WM_NCCALCSIZE message */
Result = WinPosGetNonClientSize(WindowObject->Self, Result = WinPosGetNonClientSize(WindowObject->Self,
&WindowObject->WindowRect, &WindowObject->WindowRect,
&WindowObject->ClientRect); &WindowObject->ClientRect);
@ -768,7 +813,22 @@ NtUserCreateWindowEx(DWORD dwExStyle,
MaxPos.x - WindowObject->WindowRect.left, MaxPos.x - WindowObject->WindowRect.left,
MaxPos.y - WindowObject->WindowRect.top); MaxPos.y - WindowObject->WindowRect.top);
/* Send the CREATE message. */
/* 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 */
W32kLinkWindow(WindowObject, ParentWindow, ParentWindow->LastChild /*prev sibling*/);
}
else
{
/* link window as top sibling */
W32kLinkWindow(WindowObject, ParentWindow, NULL /*prev sibling*/);
}
ExReleaseFastMutexUnsafe(&ParentWindow->ChildrenListLock);
/* Send the WM_CREATE message. */
DPRINT("NtUserCreateWindowEx(): about to send CREATE message.\n"); DPRINT("NtUserCreateWindowEx(): about to send CREATE message.\n");
Result = W32kSendCREATEMessage(WindowObject->Self, &Cs); Result = W32kSendCREATEMessage(WindowObject->Self, &Cs);
if (Result == (LRESULT)-1) if (Result == (LRESULT)-1)
@ -928,31 +988,31 @@ static BOOLEAN W32kWndBelongsToThread(PWINDOW_OBJECT Window, PW32THREAD ThreadDa
static BOOL BuildChildWindowArray(PWINDOW_OBJECT Window, HWND **Children, unsigned *NumChildren) static BOOL BuildChildWindowArray(PWINDOW_OBJECT Window, HWND **Children, unsigned *NumChildren)
{ {
PLIST_ENTRY Current;
unsigned Index; unsigned Index;
PWINDOW_OBJECT Child; PWINDOW_OBJECT Child;
*Children = NULL; *Children = NULL;
*NumChildren = 0; *NumChildren = 0;
ExAcquireFastMutexUnsafe(&Window->ChildrenListLock); ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
Current = Window->ChildrenListHead.Flink; Child = Window->FirstChild;
while (Current != &Window->ChildrenListHead) while (Child)
{ {
(*NumChildren)++; (*NumChildren)++;
Current = Current->Flink; Child = Child->NextSibling;
} }
if (0 != *NumChildren) if (0 != *NumChildren)
{ {
*Children = ExAllocatePoolWithTag(PagedPool, *NumChildren * sizeof(HWND), TAG_WNAM); *Children = ExAllocatePoolWithTag(PagedPool, *NumChildren * sizeof(HWND), TAG_WNAM);
if (NULL != *Children) if (NULL != *Children)
{ {
Current = Window->ChildrenListHead.Flink; Child = Window->FirstChild;
Index = 0; Index = 0;
while (Current != &Window->ChildrenListHead) while (Child)
{ {
Child = CONTAINING_RECORD(Current, WINDOW_OBJECT, SiblingListEntry);
(*Children)[Index] = Child->Self; (*Children)[Index] = Child->Self;
Current = Current->Flink; Child = Child->NextSibling;
Index++; Index++;
} }
assert(Index == *NumChildren); assert(Index == *NumChildren);
@ -964,6 +1024,7 @@ static BOOL BuildChildWindowArray(PWINDOW_OBJECT Window, HWND **Children, unsign
} }
ExReleaseFastMutexUnsafe(&Window->ChildrenListLock); ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
return 0 == *NumChildren || NULL != *Children; return 0 == *NumChildren || NULL != *Children;
} }
@ -1064,11 +1125,9 @@ static LRESULT W32kDestroyWindow(PWINDOW_OBJECT Window,
#endif #endif
ExAcquireFastMutexUnsafe(&Window->Parent->ChildrenListLock); ExAcquireFastMutexUnsafe(&Window->Parent->ChildrenListLock);
RemoveEntryList(&Window->SiblingListEntry); W32kUnlinkWindow(Window);
ExReleaseFastMutexUnsafe(&Window->Parent->ChildrenListLock); ExReleaseFastMutexUnsafe(&Window->Parent->ChildrenListLock);
RemoveEntryList(&Window->DesktopListEntry);
ExAcquireFastMutexUnsafe (&ThreadData->WindowListLock); ExAcquireFastMutexUnsafe (&ThreadData->WindowListLock);
RemoveEntryList(&Window->ThreadListEntry); RemoveEntryList(&Window->ThreadListEntry);
ExReleaseFastMutexUnsafe (&ThreadData->WindowListLock); ExReleaseFastMutexUnsafe (&ThreadData->WindowListLock);
@ -1302,9 +1361,7 @@ NtUserFindWindowEx(HWND hwndParent,
{ {
NTSTATUS status; NTSTATUS status;
HWND windowHandle; HWND windowHandle;
PWINDOW_OBJECT windowObject; PWINDOW_OBJECT ParentWindow, WndChildAfter, WndChild;
PWINDOW_OBJECT ParentWindow;
PLIST_ENTRY currentEntry;
PWNDCLASS_OBJECT classObject; PWNDCLASS_OBJECT classObject;
// Get a pointer to the class // Get a pointer to the class
@ -1328,39 +1385,35 @@ NtUserFindWindowEx(HWND hwndParent,
} }
ExAcquireFastMutexUnsafe (&ParentWindow->ChildrenListLock); ExAcquireFastMutexUnsafe (&ParentWindow->ChildrenListLock);
currentEntry = ParentWindow->ChildrenListHead.Flink;
if(hwndChildAfter) if(hwndChildAfter)
{ {
while (currentEntry != &ParentWindow->ChildrenListHead) if (!(WndChildAfter = W32kGetWindowObject(hwndChildAfter)))
{ {
windowObject = CONTAINING_RECORD (currentEntry, WINDOW_OBJECT, SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
SiblingListEntry); return NULL;
if(windowObject->Self == hwndChildAfter)
{
/* "The search begins with the _next_ child window in the Z order." */
currentEntry = currentEntry->Flink;
break;
} }
currentEntry = currentEntry->Flink; /* must be a direct child (not a decendant child)*/
if (WndChildAfter->Parent != ParentWindow)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return NULL;
} }
/* If the child hwndChildAfter was not found: WndChild = WndChildAfter->NextSibling;
currentEntry=&ParentWindow->ChildrenListHead now so the next }
block of code will just fall through and the function returns NULL */ else
{
WndChild = ParentWindow->FirstChild;
} }
while (currentEntry != &ParentWindow->ChildrenListHead) while (WndChild)
{ {
windowObject = CONTAINING_RECORD (currentEntry, WINDOW_OBJECT, if (classObject == WndChild->Class && (ucWindowName->Buffer==NULL ||
SiblingListEntry); RtlCompareUnicodeString (ucWindowName, &WndChild->WindowName, TRUE) == 0))
if (classObject == windowObject->Class && (ucWindowName->Buffer==NULL ||
RtlCompareUnicodeString (ucWindowName, &windowObject->WindowName, TRUE) == 0))
{ {
windowHandle = windowObject->Self; windowHandle = WndChild->Self;
ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock); ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock);
W32kReleaseWindowObject(ParentWindow); W32kReleaseWindowObject(ParentWindow);
@ -1368,10 +1421,12 @@ NtUserFindWindowEx(HWND hwndParent,
return windowHandle; return windowHandle;
} }
currentEntry = currentEntry->Flink;
WndChild = WndChild->NextSibling;
} }
ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock); ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock);
W32kReleaseWindowObject(ParentWindow); W32kReleaseWindowObject(ParentWindow);
ObmDereferenceObject (classObject); ObmDereferenceObject (classObject);
@ -2064,17 +2119,17 @@ NtUserGetWindowThreadProcessId(HWND hWnd, LPDWORD UnsafePid)
PWINDOW_OBJECT Wnd; PWINDOW_OBJECT Wnd;
DWORD tid, pid; DWORD tid, pid;
W32kAcquireWinStaLockShared(); W32kAcquireWinLockShared();
if (!(Wnd = W32kGetWindowObject(hWnd))) if (!(Wnd = W32kGetWindowObject(hWnd)))
{ {
W32kReleaseWinStaLock(); W32kReleaseWinLock();
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return 0; return 0;
} }
tid = W32kGetWindowThreadProcessId(Wnd, &pid); tid = W32kGetWindowThreadProcessId(Wnd, &pid);
W32kReleaseWinStaLock(); W32kReleaseWinLock();
if (UnsafePid) MmCopyToCaller(UnsafePid, &pid, sizeof(DWORD)); if (UnsafePid) MmCopyToCaller(UnsafePid, &pid, sizeof(DWORD));
@ -2107,7 +2162,7 @@ NtUserBuildHwndList(
if ( hwndParent ) if ( hwndParent )
{ {
PWINDOW_OBJECT WindowObject = NULL; PWINDOW_OBJECT WindowObject = NULL;
PLIST_ENTRY ChildListEntry; PWINDOW_OBJECT Child;
WindowObject = W32kGetWindowObject ( hwndParent ); WindowObject = W32kGetWindowObject ( hwndParent );
if ( !WindowObject ) if ( !WindowObject )
@ -2118,16 +2173,13 @@ NtUserBuildHwndList(
} }
ExAcquireFastMutex ( &WindowObject->ChildrenListLock ); ExAcquireFastMutex ( &WindowObject->ChildrenListLock );
ChildListEntry = WindowObject->ChildrenListHead.Flink; Child = WindowObject->FirstChild;
while (ChildListEntry != &WindowObject->ChildrenListHead) while (Child)
{ {
PWINDOW_OBJECT Child;
Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT,
SiblingListEntry);
if ( pWnd && dwCount < nBufSize ) if ( pWnd && dwCount < nBufSize )
pWnd[dwCount] = Child->Self; pWnd[dwCount] = Child->Self;
dwCount++; dwCount++;
ChildListEntry = ChildListEntry->Flink; Child = Child->NextSibling;
} }
ExReleaseFastMutex ( &WindowObject->ChildrenListLock ); ExReleaseFastMutex ( &WindowObject->ChildrenListLock );
W32kReleaseWindowObject ( WindowObject ); W32kReleaseWindowObject ( WindowObject );
@ -2188,7 +2240,7 @@ NtUserBuildHwndList(
{ {
PDESKTOP_OBJECT DesktopObject = NULL; PDESKTOP_OBJECT DesktopObject = NULL;
KIRQL OldIrql; KIRQL OldIrql;
PLIST_ENTRY WindowListEntry; PWINDOW_OBJECT Child, WndDesktop;
if ( hDesktop ) if ( hDesktop )
DesktopObject = W32kGetDesktopObject ( hDesktop ); DesktopObject = W32kGetDesktopObject ( hDesktop );
@ -2202,16 +2254,15 @@ NtUserBuildHwndList(
} }
KeAcquireSpinLock ( &DesktopObject->Lock, &OldIrql ); KeAcquireSpinLock ( &DesktopObject->Lock, &OldIrql );
WindowListEntry = DesktopObject->WindowListHead.Flink;
while ( WindowListEntry != &DesktopObject->WindowListHead ) WndDesktop = W32kGetWindowObject(DesktopObject->DesktopWindow);
Child = (WndDesktop ? WndDesktop->FirstChild : NULL);
while (Child)
{ {
PWINDOW_OBJECT Child;
Child = CONTAINING_RECORD(WindowListEntry, WINDOW_OBJECT,
SiblingListEntry);
if ( pWnd && dwCount < nBufSize ) if ( pWnd && dwCount < nBufSize )
pWnd[dwCount] = Child->Self; pWnd[dwCount] = Child->Self;
dwCount++; dwCount++;
WindowListEntry = WindowListEntry->Flink; Child = Child->NextSibling;
} }
KeReleaseSpinLock ( &DesktopObject->Lock, OldIrql ); KeReleaseSpinLock ( &DesktopObject->Lock, OldIrql );
} }
@ -2248,11 +2299,11 @@ NtUserGetWindow(HWND hWnd, UINT Relationship)
PWINDOW_OBJECT Wnd; PWINDOW_OBJECT Wnd;
HWND hWndResult = NULL; HWND hWndResult = NULL;
W32kAcquireWinStaLockShared(); W32kAcquireWinLockShared();
if (!(Wnd = W32kGetWindowObject(hWnd))) if (!(Wnd = W32kGetWindowObject(hWnd)))
{ {
W32kReleaseWinStaLock(); W32kReleaseWinLock();
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return NULL; return NULL;
} }
@ -2272,19 +2323,22 @@ NtUserGetWindow(HWND hWnd, UINT Relationship)
} }
break; break;
case GW_HWNDNEXT: case GW_HWNDNEXT:
if (Wnd->NextSibling) if (Wnd->Parent && Wnd->NextSibling)
{ {
hWndResult = Wnd->NextSibling->Self; hWndResult = Wnd->NextSibling->Self;
} }
break; break;
case GW_HWNDPREV: case GW_HWNDPREV:
if (Wnd->PrevSibling) if (Wnd->Parent && Wnd->PrevSibling)
{ {
hWndResult = Wnd->PrevSibling->Self; hWndResult = Wnd->PrevSibling->Self;
} }
break; break;
case GW_OWNER: case GW_OWNER:
if (Wnd->Parent)
{
hWndResult = Wnd->hWndOwner; hWndResult = Wnd->hWndOwner;
}
break; break;
case GW_CHILD: case GW_CHILD:
if (Wnd->FirstChild) if (Wnd->FirstChild)
@ -2294,7 +2348,7 @@ NtUserGetWindow(HWND hWnd, UINT Relationship)
break; break;
} }
W32kReleaseWinStaLock(); W32kReleaseWinLock();
return hWndResult; return hWndResult;
} }
@ -2306,23 +2360,128 @@ NtUserGetLastActivePopup(HWND hWnd)
PWINDOW_OBJECT Wnd; PWINDOW_OBJECT Wnd;
HWND hWndLastPopup; HWND hWndLastPopup;
W32kAcquireWinStaLockShared(); W32kAcquireWinLockShared();
if (!(Wnd = W32kGetWindowObject(hWnd))) if (!(Wnd = W32kGetWindowObject(hWnd)))
{ {
W32kReleaseWinStaLock(); W32kReleaseWinLock();
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return NULL; return NULL;
} }
hWndLastPopup = Wnd->hWndLastPopup; hWndLastPopup = Wnd->hWndLastPopup;
W32kReleaseWinStaLock(); W32kReleaseWinLock();
return hWndLastPopup; return hWndLastPopup;
} }
PWINDOW_OBJECT FASTCALL
W32kSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
{
PWINDOW_OBJECT WndOldParent;
BOOL was_visible;
HWND hWnd, hWndNewParent, hWndOldParent;
if (!WndNewParent) WndNewParent = W32kGetWindowObject(W32kGetDesktopWindow());
hWnd = Wnd;
hWndNewParent = WndNewParent;
#if 0
if (!(full_handle = WIN_IsCurrentThread( hwnd )))
return (HWND)SendMessageW( hwnd, WM_WINE_SETPARENT, (WPARAM)parent, 0 );
if (USER_Driver.pSetParent)
return USER_Driver.pSetParent( hwnd, parent );
#endif
/* Windows hides the window first, then shows it again
* including the WM_SHOWWINDOW messages and all */
was_visible = WinPosShowWindow( hWnd, SW_HIDE );
/* validate that window and parent still exist */
if (!W32kGetWindowObject(hWnd) || !W32kGetWindowObject(hWndNewParent)) return NULL;
/* window must belong to current process */
if (Wnd->OwnerThread->ThreadsProcess != PsGetCurrentProcess()) return NULL;
WndOldParent = Wnd->Parent;
hWndOldParent = WndOldParent->Self;
if (WndNewParent != WndOldParent)
{
W32kUnlinkWindow(Wnd);
W32kLinkWindow(Wnd, WndNewParent, NULL /*prev sibling*/);
if (WndNewParent->Self != W32kGetDesktopWindow()) /* a child window */
{
if (!(Wnd->Style & WS_CHILD))
{
HMENU Menu = Wnd->Menu;
Wnd->Menu = NULL;
//if (Menu) DestroyMenu( menu );
}
}
}
/* SetParent additionally needs to make hwnd the topmost window
in the x-order and send the expected WM_WINDOWPOSCHANGING and
WM_WINDOWPOSCHANGED notification messages.
*/
WinPosSetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | (was_visible ? SWP_SHOWWINDOW : 0) );
/* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
* for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
/* validate that the old parent still exist, since it migth have been destroyed
during the last callbacks to user-mode
*/
return (W32kGetWindowObject(hWndOldParent) ? WndOldParent : NULL);
}
HWND
STDCALL
NtUserSetParent(HWND hWndChild, HWND hWndNewParent)
{
PWINDOW_OBJECT Wnd = NULL, WndParent = NULL, WndOldParent;
HWND hWndOldParent;
if (W32kIsBroadcastHwnd(hWndChild) || W32kIsBroadcastHwnd(hWndNewParent))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return NULL;
}
W32kAcquireWinLockExclusive();
if (hWndNewParent)
{
if (!(WndParent = W32kGetWindowObject(hWndNewParent)))
{
W32kReleaseWinLock();
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return NULL;
}
}
if (!(Wnd = W32kGetWindowObject(hWndNewParent)))
{
W32kReleaseWinLock();
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return NULL;
}
WndOldParent = W32kSetParent(Wnd, WndParent);
if (WndOldParent) hWndOldParent = WndOldParent->Self;
W32kReleaseWinLock();
return hWndOldParent;
}
/* /*
* @implemented * @implemented
*/ */

View file

@ -0,0 +1,123 @@
/*
* 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 W32kVerifyWinLock(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 W32kSuspendWinLock()
{
ASSERT_WINLOCK(Any);
if (ExIsResourceAcquiredExclusiveLite(&WinLock)) return Exclusive;
return Shared;
}
VOID FASTCALL W32kRestoreWinLock(WINLOCK_TYPE Type)
{
switch (Type)
{
case Exclusive:
return W32kAcquireWinLockExclusive(&WinLock);
case Shared:
return W32kAcquireWinLockShared(&WinLock);
/* silence warnings */
case None:
case Any:
break;
}
KEBUGCHECK(0);
}
inline VOID W32kAcquireWinLockShared()
{
ExAcquireResourceExclusiveLite(&WinLock, TRUE /*Wait*/ );
}
inline VOID W32kAcquireWinLockExclusive()
{
ExAcquireResourceSharedLite(&WinLock, TRUE /*Wait*/ );
}
inline VOID W32kReleaseWinLock()
{
ExReleaseResourceLite(&WinLock );
}
inline BOOL W32kInitializeWinLock()
{
ExInitializeResourceLite(&WinLock );
return TRUE;
}
inline VOID W32kDeleteWinLock()
{
ExDeleteResourceLite(&WinLock );
}
/* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: winpos.c,v 1.21 2003/08/04 16:54:54 gdalsnes Exp $ /* $Id: winpos.c,v 1.22 2003/08/11 19:05:26 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -1112,17 +1112,12 @@ USHORT STATIC STDCALL
WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point, WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point,
PWINDOW_OBJECT* Window) PWINDOW_OBJECT* Window)
{ {
PLIST_ENTRY CurrentEntry;
PWINDOW_OBJECT Current; PWINDOW_OBJECT Current;
ExAcquireFastMutexUnsafe(&ScopeWin->ChildrenListLock); ExAcquireFastMutexUnsafe(&ScopeWin->ChildrenListLock);
CurrentEntry = ScopeWin->ChildrenListHead.Flink; Current = ScopeWin->FirstChild;
while (CurrentEntry != &ScopeWin->ChildrenListHead) while (Current)
{ {
Current =
CONTAINING_RECORD(CurrentEntry, WINDOW_OBJECT, SiblingListEntry);
if (Current->Style & WS_VISIBLE && if (Current->Style & WS_VISIBLE &&
((!(Current->Style & WS_DISABLED)) || ((!(Current->Style & WS_DISABLED)) ||
(Current->Style & (WS_CHILD | WS_POPUP)) != WS_CHILD) && (Current->Style & (WS_CHILD | WS_POPUP)) != WS_CHILD) &&
@ -1154,7 +1149,7 @@ WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point,
ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock); ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock);
return(0); return(0);
} }
CurrentEntry = CurrentEntry->Flink; Current = Current->NextSibling;
} }
ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock); ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: winsta.c,v 1.24 2003/08/06 16:47:35 weiden Exp $ /* $Id: winsta.c,v 1.25 2003/08/11 19:05:26 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -68,41 +68,6 @@ static HDC ScreenDeviceContext = NULL;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
BOOL FASTCALL W32kVerifyWinStaLock(WINSTA_LOCK_TYPE Type)
{
switch (Type)
{
case None:
return !ExIsResourceAcquiredSharedLite(&(PsGetWin32Process()->WindowStation->Resource));
case Any: /* exclusive lock is subset of shared lock */
return ExIsResourceAcquiredSharedLite(&(PsGetWin32Process()->WindowStation->Resource));
case Exclusive:
return ExIsResourceAcquiredExclusiveLite(&(PsGetWin32Process()->WindowStation->Resource));
}
return FALSE;
}
inline VOID W32kAcquireWinStaLockShared()
{
ExAcquireResourceExclusiveLite(&(PsGetWin32Process()->WindowStation->Resource),
TRUE /*Wait*/
);
}
inline VOID W32kAcquireWinStaLockExclusive()
{
ExAcquireResourceSharedLite(&(PsGetWin32Process()->WindowStation->Resource),
TRUE /*Wait*/
);
}
inline VOID W32kReleaseWinStaLock()
{
ExReleaseResourceLite( &(PsGetWin32Process()->WindowStation->Resource) );
}
PDESKTOP_OBJECT FASTCALL PDESKTOP_OBJECT FASTCALL
W32kGetActiveDesktop(VOID) W32kGetActiveDesktop(VOID)
@ -376,7 +341,6 @@ NtUserCreateWindowStation(PUNICODE_STRING lpszWindowStationName,
return (HWINSTA)0; return (HWINSTA)0;
} }
ExInitializeResourceLite(&WinStaObject->Resource);
WinStaObject->HandleTable = ObmCreateHandleTable(); WinStaObject->HandleTable = ObmCreateHandleTable();
if (!WinStaObject->HandleTable) if (!WinStaObject->HandleTable)
{ {
@ -696,7 +660,6 @@ NtUserCreateDesktop(PUNICODE_STRING lpszDesktopName,
/* Initialize some local (to win32k) desktop state. */ /* Initialize some local (to win32k) desktop state. */
DesktopObject->ActiveMessageQueue = NULL; DesktopObject->ActiveMessageQueue = NULL;
InitializeListHead(&DesktopObject->WindowListHead);
DesktopObject->DesktopWindow = DesktopObject->DesktopWindow =
W32kCreateDesktopWindow(DesktopObject->WindowStation, W32kCreateDesktopWindow(DesktopObject->WindowStation,
DesktopWindowClass, DesktopWindowClass,