mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
-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:
parent
417dffd0c4
commit
9cc8d55331
16 changed files with 543 additions and 322 deletions
|
@ -1406,11 +1406,11 @@ NtUserSetObjectInformation(
|
|||
PVOID pvInformation,
|
||||
DWORD nLength);
|
||||
|
||||
DWORD
|
||||
HWND
|
||||
STDCALL
|
||||
NtUserSetParent(
|
||||
DWORD Unknown0,
|
||||
DWORD Unknown1);
|
||||
HWND hWndChild,
|
||||
HWND hWndNewParent);
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
|
|
|
@ -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
|
||||
* PROJECT: ReactOS user32.dll
|
||||
|
@ -1374,8 +1374,7 @@ HWND STDCALL
|
|||
SetParent(HWND hWndChild,
|
||||
HWND hWndNewParent)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return (HWND)0;
|
||||
return NtUserSetParent(hWndChild, hWndNewParent);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ typedef struct _WINSTATION_OBJECT
|
|||
PRTL_ATOM_TABLE AtomTable;
|
||||
PVOID HandleTable;
|
||||
struct _DESKTOP_OBJECT* ActiveDesktop;
|
||||
ERESOURCE Resource;
|
||||
/* FIXME: Clipboard */
|
||||
} WINSTATION_OBJECT, *PWINSTATION_OBJECT;
|
||||
|
||||
|
@ -32,8 +31,6 @@ typedef struct _DESKTOP_OBJECT
|
|||
UNICODE_STRING Name;
|
||||
/* Pointer to the associated window station. */
|
||||
struct _WINSTATION_OBJECT *WindowStation;
|
||||
/* Head of the list of windows in this desktop. */
|
||||
LIST_ENTRY WindowListHead;
|
||||
/* Pointer to the active queue. */
|
||||
PVOID ActiveMessageQueue;
|
||||
/* Handle of the desktop window. */
|
||||
|
|
|
@ -47,8 +47,6 @@ typedef struct _WINDOW_OBJECT
|
|||
LPVOID Parameters;
|
||||
/* Entry in the thread's list of windows. */
|
||||
LIST_ENTRY ListEntry;
|
||||
/* Entry in the global list of windows. */
|
||||
LIST_ENTRY DesktopListEntry;
|
||||
/* Pointer to the extra data associated with the window. */
|
||||
PULONG ExtraData;
|
||||
/* Size of the extra data associated with the window. */
|
||||
|
@ -67,15 +65,10 @@ typedef struct _WINDOW_OBJECT
|
|||
HANDLE UpdateRegion;
|
||||
/* Pointer to the owning thread's message queue. */
|
||||
PUSER_MESSAGE_QUEUE MessageQueue;
|
||||
/* Head of the list of child windows. */
|
||||
LIST_ENTRY ChildrenListHead;
|
||||
struct _WINDOW_OBJECT* FirstChild;
|
||||
struct _WINDOW_OBJECT* LastChild;
|
||||
|
||||
/* Lock for the list of child windows. */
|
||||
FAST_MUTEX ChildrenListLock;
|
||||
/* Entry in the parent's list of child windows. */
|
||||
LIST_ENTRY SiblingListEntry;
|
||||
struct _WINDOW_OBJECT* NextSibling;
|
||||
struct _WINDOW_OBJECT* PrevSibling;
|
||||
/* Entry in the list of thread windows. */
|
||||
|
@ -95,8 +88,8 @@ typedef struct _WINDOW_OBJECT
|
|||
WNDPROC WndProcA;
|
||||
WNDPROC WndProcW;
|
||||
PETHREAD OwnerThread;
|
||||
HWND hWndOwner; /* handle to the owner window (why not use pointer to window? wine doesn't...)*/
|
||||
HWND hWndLastPopup; /* handle to last active popup 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 (wine doesn't use pointer, for unk. reason)*/
|
||||
} WINDOW_OBJECT, *PWINDOW_OBJECT;
|
||||
|
||||
/* Window flags. */
|
||||
|
@ -107,6 +100,10 @@ typedef struct _WINDOW_OBJECT
|
|||
#define WINDOWOBJECT_NEED_INTERNALPAINT (0x00000010)
|
||||
#define WINDOWOBJECT_RESTOREMAX (0x00000020)
|
||||
|
||||
inline BOOL W32kIsDesktopWindow(PWINDOW_OBJECT WindowObject);
|
||||
|
||||
inline BOOL W32kIsBroadcastHwnd( HWND hwnd );
|
||||
|
||||
NTSTATUS FASTCALL
|
||||
InitWindowImpl (VOID);
|
||||
|
||||
|
@ -127,9 +124,6 @@ W32kCreateDesktopWindow (PWINSTATION_OBJECT WindowStation,
|
|||
PWNDCLASS_OBJECT DesktopClass,
|
||||
ULONG Width, ULONG Height);
|
||||
|
||||
BOOL FASTCALL
|
||||
W32kIsDesktopWindow (PWINDOW_OBJECT Window);
|
||||
|
||||
HWND FASTCALL
|
||||
W32kGetActiveWindow (VOID);
|
||||
|
||||
|
@ -169,6 +163,25 @@ W32kGetAncestor(PWINDOW_OBJECT Wnd, UINT Type);
|
|||
PWINDOW_OBJECT FASTCALL
|
||||
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 */
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -7,14 +7,6 @@
|
|||
#include <internal/ps.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() \
|
||||
((HWINSTA)(IoGetCurrentProcess()->Win32WindowStation))
|
||||
|
@ -61,11 +53,6 @@ W32kGetCaptureWindow(VOID);
|
|||
VOID STDCALL
|
||||
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 */
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -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.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
|
||||
*/
|
||||
|
@ -169,6 +169,8 @@ DllMain (
|
|||
NTSTATUS Status;
|
||||
BOOLEAN Result;
|
||||
|
||||
W32kInitializeWinLock();
|
||||
|
||||
/*
|
||||
* Register user mode call interface
|
||||
* (system service table index = 1)
|
||||
|
|
|
@ -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 = ../..
|
||||
|
||||
|
@ -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/winpos.o ntuser/painting.o ntuser/metric.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/color.o objects/coord.o objects/dc.o \
|
||||
|
|
|
@ -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.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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -47,6 +47,7 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* 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 HasChildren = !IsListEmpty(&Window->ChildrenListHead) &&
|
||||
BOOL HasChildren = Window->FirstChild &&
|
||||
!(Flags & RDW_NOCHILDREN) && !(Window->Style & WS_MINIMIZE) &&
|
||||
((Flags & RDW_ALLCHILDREN) || !(Window->Style & WS_CLIPCHILDREN));
|
||||
RECT Rect;
|
||||
|
@ -390,17 +391,14 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
|
|||
POINT PrevOrign = {0, 0};
|
||||
POINT Client;
|
||||
PWINDOW_OBJECT Child;
|
||||
PLIST_ENTRY ChildListEntry;
|
||||
|
||||
Client.x = Window->ClientRect.left - Window->WindowRect.left;
|
||||
Client.y = Window->ClientRect.top - Window->WindowRect.top;
|
||||
|
||||
ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
|
||||
ChildListEntry = Window->ChildrenListHead.Flink;
|
||||
while (ChildListEntry != &Window->ChildrenListHead)
|
||||
Child = Window->FirstChild;
|
||||
while (Child)
|
||||
{
|
||||
Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT,
|
||||
SiblingListEntry);
|
||||
if (0 != (Child->Style & WS_VISIBLE))
|
||||
{
|
||||
POINT Offset;
|
||||
|
@ -424,7 +422,7 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
|
|||
Total.y += Offset.y;
|
||||
}
|
||||
}
|
||||
ChildListEntry = ChildListEntry->Flink;
|
||||
Child = Child->NextSibling;
|
||||
}
|
||||
ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
|
||||
|
||||
|
@ -436,19 +434,16 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
|
|||
if (HasChildren)
|
||||
{
|
||||
PWINDOW_OBJECT Child;
|
||||
PLIST_ENTRY ChildListEntry;
|
||||
|
||||
ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
|
||||
ChildListEntry = Window->ChildrenListHead.Flink;
|
||||
while (ChildListEntry != &Window->ChildrenListHead)
|
||||
Child = Window->FirstChild;
|
||||
while (Child)
|
||||
{
|
||||
Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT,
|
||||
SiblingListEntry);
|
||||
if (Child->Style & WS_VISIBLE)
|
||||
{
|
||||
PaintUpdateRgns(Child, hRgn, Flags, FALSE);
|
||||
}
|
||||
ChildListEntry = ChildListEntry->Flink;
|
||||
Child = Child->NextSibling;
|
||||
}
|
||||
ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
|
||||
}
|
||||
|
@ -682,11 +677,9 @@ PaintingFindWinToRepaint(HWND hWnd, PW32THREAD Thread)
|
|||
}
|
||||
|
||||
ExAcquireFastMutex(&BaseWindow->ChildrenListLock);
|
||||
current_entry = BaseWindow->ChildrenListHead.Flink;
|
||||
while (current_entry != &BaseWindow->ChildrenListHead)
|
||||
Window = BaseWindow->FirstChild;
|
||||
while (Window)
|
||||
{
|
||||
Window = CONTAINING_RECORD(current_entry, WINDOW_OBJECT,
|
||||
SiblingListEntry);
|
||||
if (Window->Style & WS_VISIBLE)
|
||||
{
|
||||
hFoundWnd = PaintingFindWinToRepaint(Window->Self, Thread);
|
||||
|
@ -695,9 +688,10 @@ PaintingFindWinToRepaint(HWND hWnd, PW32THREAD Thread)
|
|||
break;
|
||||
}
|
||||
}
|
||||
current_entry = current_entry->Flink;
|
||||
Window = Window->NextSibling;
|
||||
}
|
||||
ExReleaseFastMutex(&BaseWindow->ChildrenListLock);
|
||||
|
||||
W32kReleaseWindowObject(BaseWindow);
|
||||
return(hFoundWnd);
|
||||
}
|
||||
|
|
|
@ -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: 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -109,11 +109,11 @@ NtUserGetProp(HWND hWnd, ATOM Atom)
|
|||
PPROPERTY Prop;
|
||||
HANDLE Data = NULL;
|
||||
|
||||
W32kAcquireWinStaLockShared();
|
||||
W32kAcquireWinLockShared();
|
||||
|
||||
if (!(WindowObject = W32kGetWindowObject(hWnd)))
|
||||
{
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ NtUserGetProp(HWND hWnd, ATOM Atom)
|
|||
Data = Prop->Data;
|
||||
}
|
||||
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
|
||||
return(Data);
|
||||
}
|
||||
|
@ -155,18 +155,18 @@ NtUserSetProp(HWND hWnd, ATOM Atom, HANDLE Data)
|
|||
PWINDOW_OBJECT Wnd;
|
||||
BOOL ret;
|
||||
|
||||
W32kAcquireWinStaLockExclusive();
|
||||
W32kAcquireWinLockExclusive();
|
||||
|
||||
if (!(Wnd = W32kGetWindowObject(hWnd)))
|
||||
{
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = W32kSetProp(Wnd, Atom, Data);
|
||||
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -1033,16 +1033,6 @@ NtUserSetImeHotKey(
|
|||
return 0;
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
NtUserSetParent(
|
||||
DWORD Unknown0,
|
||||
DWORD Unknown1)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
|
|
|
@ -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.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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -101,21 +101,19 @@ STATIC BOOL FASTCALL
|
|||
VIS_AddClipRects(PWINDOW_OBJECT Parent, PWINDOW_OBJECT End,
|
||||
HRGN ClipRgn, PRECT Rect)
|
||||
{
|
||||
PLIST_ENTRY ChildListEntry;
|
||||
PWINDOW_OBJECT Child;
|
||||
RECT Intersect;
|
||||
|
||||
ExAcquireFastMutexUnsafe(&Parent->ChildrenListLock);
|
||||
ChildListEntry = Parent->ChildrenListHead.Flink;
|
||||
while (ChildListEntry != &Parent->ChildrenListHead)
|
||||
Child = Parent->FirstChild;
|
||||
while (Child)
|
||||
{
|
||||
Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT,
|
||||
SiblingListEntry);
|
||||
if (Child == End)
|
||||
{
|
||||
ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (Child->Style & WS_VISIBLE)
|
||||
{
|
||||
if (W32kIntersectRect(&Intersect, &Child->WindowRect, Rect))
|
||||
|
@ -123,10 +121,12 @@ VIS_AddClipRects(PWINDOW_OBJECT Parent, PWINDOW_OBJECT End,
|
|||
UnsafeW32kUnionRectWithRgn(ClipRgn, &Child->WindowRect);
|
||||
}
|
||||
}
|
||||
ChildListEntry = ChildListEntry->Flink;
|
||||
|
||||
Child = Child->NextSibling;
|
||||
}
|
||||
|
||||
ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -156,8 +156,7 @@ VIS_ComputeVisibleRegion(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
|
|||
|
||||
if (ClipRgn != NULL)
|
||||
{
|
||||
if (ClipChildren &&
|
||||
! IsListEmpty(&Window->ChildrenListHead))
|
||||
if (ClipChildren && Window->FirstChild)
|
||||
{
|
||||
VIS_AddClipRects(Window, NULL, ClipRgn, &Rect);
|
||||
}
|
||||
|
@ -217,18 +216,17 @@ VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
|
|||
{
|
||||
PWINDOW_OBJECT DesktopWindow;
|
||||
PWINDOW_OBJECT Child;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
HRGN Uncovered;
|
||||
HRGN Covered;
|
||||
HRGN Repaint;
|
||||
|
||||
DesktopWindow = W32kGetWindowObject(Desktop->DesktopWindow);
|
||||
Uncovered = UnsafeW32kCreateRectRgnIndirect(&DesktopWindow->WindowRect);
|
||||
|
||||
ExAcquireFastMutexUnsafe(&DesktopWindow->ChildrenListLock);
|
||||
CurrentEntry = DesktopWindow->ChildrenListHead.Flink;
|
||||
while (CurrentEntry != &DesktopWindow->ChildrenListHead)
|
||||
Child = DesktopWindow->FirstChild;
|
||||
while (Child)
|
||||
{
|
||||
Child = CONTAINING_RECORD(CurrentEntry, WINDOW_OBJECT, SiblingListEntry);
|
||||
if (0 != (Child->Style & WS_VISIBLE))
|
||||
{
|
||||
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);
|
||||
W32kDeleteObject(Covered);
|
||||
}
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
Child = Child->NextSibling;
|
||||
}
|
||||
ExReleaseFastMutexUnsafe(&DesktopWindow->ChildrenListLock);
|
||||
|
||||
|
|
|
@ -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.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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -81,7 +81,7 @@ DceGetVisRgn(HWND hWnd, ULONG Flags, HWND hWndChild, ULONG CFlags)
|
|||
Child = W32kGetWindowObject(hWnd);
|
||||
if (NULL != Child)
|
||||
{
|
||||
if (! IsListEmpty(&Child->ChildrenListHead))
|
||||
if (Child->FirstChild)
|
||||
{
|
||||
/* Compute the visible region of the child */
|
||||
VisChild = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
|
||||
|
|
|
@ -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.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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -65,11 +65,22 @@ static LIST_ENTRY RegisteredMessageListHead;
|
|||
#define REGISTERED_MESSAGE_MIN 0xc000
|
||||
#define REGISTERED_MESSAGE_MAX 0xffff
|
||||
|
||||
PWINDOW_OBJECT FASTCALL
|
||||
W32kGetParent(PWINDOW_OBJECT Wnd);
|
||||
|
||||
/* 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
|
||||
W32kGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
|
||||
{
|
||||
|
@ -102,7 +113,7 @@ NtUserGetAncestor(HWND hWnd, UINT Type)
|
|||
PWINDOW_OBJECT Wnd, WndAncestor;
|
||||
HWND hWndAncestor = NULL;
|
||||
|
||||
W32kAcquireWinStaLockShared();
|
||||
W32kAcquireWinLockShared();
|
||||
|
||||
if (!(Wnd = W32kGetWindowObject(hWnd)))
|
||||
{
|
||||
|
@ -113,7 +124,7 @@ NtUserGetAncestor(HWND hWnd, UINT Type)
|
|||
WndAncestor = W32kGetAncestor(Wnd, Type);
|
||||
if (WndAncestor) hWndAncestor = WndAncestor->Self;
|
||||
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
|
||||
return hWndAncestor;
|
||||
}
|
||||
|
@ -140,7 +151,7 @@ NtUserGetParent(HWND hWnd)
|
|||
PWINDOW_OBJECT Wnd, WndParent;
|
||||
HWND hWndParent = NULL;
|
||||
|
||||
W32kAcquireWinStaLockShared();
|
||||
W32kAcquireWinLockShared();
|
||||
|
||||
if (!(Wnd = W32kGetWindowObject(hWnd)))
|
||||
{
|
||||
|
@ -151,7 +162,7 @@ NtUserGetParent(HWND hWnd)
|
|||
WndParent = W32kGetParent(Wnd);
|
||||
if (WndParent) hWndParent = WndParent->Self;
|
||||
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
|
||||
return hWndParent;
|
||||
}
|
||||
|
@ -260,14 +271,6 @@ W32kIsWindowVisible(HWND Wnd)
|
|||
return(Result);
|
||||
}
|
||||
|
||||
BOOL FASTCALL
|
||||
W32kIsDesktopWindow(PWINDOW_OBJECT WindowObject)
|
||||
{
|
||||
BOOL IsDesktop;
|
||||
ASSERT(WindowObject);
|
||||
IsDesktop = WindowObject->Parent == NULL;
|
||||
return(IsDesktop);
|
||||
}
|
||||
|
||||
HWND FASTCALL W32kGetDesktopWindow(VOID)
|
||||
{
|
||||
|
@ -328,16 +331,16 @@ NtUserGetWindowRect(HWND hWnd, LPRECT Rect)
|
|||
PWINDOW_OBJECT Wnd;
|
||||
RECT SafeRect;
|
||||
|
||||
W32kAcquireWinStaLockShared();
|
||||
W32kAcquireWinLockShared();
|
||||
if (!(Wnd = W32kGetWindowObject(hWnd)))
|
||||
{
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SafeRect = Wnd->WindowRect;
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
|
||||
if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
|
||||
{
|
||||
|
@ -360,16 +363,16 @@ NtUserGetClientRect(HWND hWnd, LPRECT Rect)
|
|||
PWINDOW_OBJECT WindowObject;
|
||||
RECT SafeRect;
|
||||
|
||||
W32kAcquireWinStaLockShared();
|
||||
W32kAcquireWinLockShared();
|
||||
if (!(WindowObject = W32kGetWindowObject(hWnd)))
|
||||
{
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
W32kGetClientRect(WindowObject, &SafeRect);
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
|
||||
if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
|
||||
{
|
||||
|
@ -496,8 +499,11 @@ W32kCreateDesktopWindow(PWINSTATION_OBJECT WindowStation,
|
|||
WindowObject->WndProcA = DesktopClass->lpfnWndProcA;
|
||||
WindowObject->WndProcW = DesktopClass->lpfnWndProcW;
|
||||
WindowObject->OwnerThread = PsGetCurrentThread();
|
||||
WindowObject->FirstChild = NULL;
|
||||
WindowObject->LastChild = NULL;
|
||||
WindowObject->PrevSibling = NULL;
|
||||
WindowObject->NextSibling = NULL;
|
||||
|
||||
InitializeListHead(&WindowObject->ChildrenListHead);
|
||||
ExInitializeFastMutex(&WindowObject->ChildrenListLock);
|
||||
|
||||
WindowName = ExAllocatePool(NonPagedPool, sizeof(L"DESKTOP"));
|
||||
|
@ -528,6 +534,49 @@ W32kInitDesktopWindow(ULONG Width, ULONG Height)
|
|||
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
|
||||
NtUserCreateWindowEx(DWORD dwExStyle,
|
||||
PUNICODE_STRING lpClassName,
|
||||
|
@ -566,6 +615,8 @@ NtUserCreateWindowEx(DWORD dwExStyle,
|
|||
return((HWND)0);
|
||||
}
|
||||
|
||||
/* FIXME: parent must belong to the current process */
|
||||
|
||||
if (hWndParent != NULL)
|
||||
{
|
||||
ParentWindow = W32kGetWindowObject(hWndParent);
|
||||
|
@ -646,6 +697,10 @@ NtUserCreateWindowEx(DWORD dwExStyle,
|
|||
WindowObject->WndProcA = ClassObject->lpfnWndProcA;
|
||||
WindowObject->WndProcW = ClassObject->lpfnWndProcW;
|
||||
WindowObject->OwnerThread = PsGetCurrentThread();
|
||||
WindowObject->FirstChild = NULL;
|
||||
WindowObject->LastChild = NULL;
|
||||
WindowObject->PrevSibling = NULL;
|
||||
WindowObject->NextSibling = NULL;
|
||||
|
||||
/* extra window data */
|
||||
if (ClassObject->cbWndExtra != 0)
|
||||
|
@ -660,12 +715,6 @@ NtUserCreateWindowEx(DWORD dwExStyle,
|
|||
WindowObject->ExtraDataSize = 0;
|
||||
}
|
||||
|
||||
ExAcquireFastMutexUnsafe(&ParentWindow->ChildrenListLock);
|
||||
InsertHeadList(&ParentWindow->ChildrenListHead,
|
||||
&WindowObject->SiblingListEntry);
|
||||
ExReleaseFastMutexUnsafe(&ParentWindow->ChildrenListLock);
|
||||
|
||||
InitializeListHead(&WindowObject->ChildrenListHead);
|
||||
InitializeListHead(&WindowObject->PropListHead);
|
||||
ExInitializeFastMutex(&WindowObject->ChildrenListLock);
|
||||
|
||||
|
@ -690,12 +739,6 @@ NtUserCreateWindowEx(DWORD dwExStyle,
|
|||
&WindowObject->ThreadListEntry);
|
||||
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. */
|
||||
if (dwStyle & CS_OWNDC) WindowObject->Dce = DceAllocDCE(WindowObject->Self,DCE_WINDOW_DC);
|
||||
/* FIXME: Handle "CS_CLASSDC" */
|
||||
|
@ -712,6 +755,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
|
|||
*/
|
||||
if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD)))
|
||||
{
|
||||
/* WinPosGetMinMaxInfo sends the WM_GETMINMAXINFO message */
|
||||
WinPosGetMinMaxInfo(WindowObject, &MaxSize, &MaxPos, &MinTrack,
|
||||
&MaxTrack);
|
||||
x = min(MaxSize.x, y);
|
||||
|
@ -761,6 +805,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
|
|||
MaxPos.x = WindowObject->WindowRect.left;
|
||||
MaxPos.y = WindowObject->WindowRect.top;
|
||||
DPRINT("NtUserCreateWindowEx(): About to get non-client size.\n");
|
||||
/* WinPosGetNonClientSize SENDS THE WM_NCCALCSIZE message */
|
||||
Result = WinPosGetNonClientSize(WindowObject->Self,
|
||||
&WindowObject->WindowRect,
|
||||
&WindowObject->ClientRect);
|
||||
|
@ -768,7 +813,22 @@ NtUserCreateWindowEx(DWORD dwExStyle,
|
|||
MaxPos.x - WindowObject->WindowRect.left,
|
||||
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");
|
||||
Result = W32kSendCREATEMessage(WindowObject->Self, &Cs);
|
||||
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)
|
||||
{
|
||||
PLIST_ENTRY Current;
|
||||
unsigned Index;
|
||||
PWINDOW_OBJECT Child;
|
||||
|
||||
*Children = NULL;
|
||||
*NumChildren = 0;
|
||||
|
||||
ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
|
||||
Current = Window->ChildrenListHead.Flink;
|
||||
while (Current != &Window->ChildrenListHead)
|
||||
Child = Window->FirstChild;
|
||||
while (Child)
|
||||
{
|
||||
(*NumChildren)++;
|
||||
Current = Current->Flink;
|
||||
Child = Child->NextSibling;
|
||||
}
|
||||
|
||||
if (0 != *NumChildren)
|
||||
{
|
||||
*Children = ExAllocatePoolWithTag(PagedPool, *NumChildren * sizeof(HWND), TAG_WNAM);
|
||||
if (NULL != *Children)
|
||||
{
|
||||
Current = Window->ChildrenListHead.Flink;
|
||||
Child = Window->FirstChild;
|
||||
Index = 0;
|
||||
while (Current != &Window->ChildrenListHead)
|
||||
while (Child)
|
||||
{
|
||||
Child = CONTAINING_RECORD(Current, WINDOW_OBJECT, SiblingListEntry);
|
||||
(*Children)[Index] = Child->Self;
|
||||
Current = Current->Flink;
|
||||
Child = Child->NextSibling;
|
||||
Index++;
|
||||
}
|
||||
assert(Index == *NumChildren);
|
||||
|
@ -964,6 +1024,7 @@ static BOOL BuildChildWindowArray(PWINDOW_OBJECT Window, HWND **Children, unsign
|
|||
}
|
||||
ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
|
||||
|
||||
|
||||
return 0 == *NumChildren || NULL != *Children;
|
||||
}
|
||||
|
||||
|
@ -1064,11 +1125,9 @@ static LRESULT W32kDestroyWindow(PWINDOW_OBJECT Window,
|
|||
#endif
|
||||
|
||||
ExAcquireFastMutexUnsafe(&Window->Parent->ChildrenListLock);
|
||||
RemoveEntryList(&Window->SiblingListEntry);
|
||||
W32kUnlinkWindow(Window);
|
||||
ExReleaseFastMutexUnsafe(&Window->Parent->ChildrenListLock);
|
||||
|
||||
RemoveEntryList(&Window->DesktopListEntry);
|
||||
|
||||
ExAcquireFastMutexUnsafe (&ThreadData->WindowListLock);
|
||||
RemoveEntryList(&Window->ThreadListEntry);
|
||||
ExReleaseFastMutexUnsafe (&ThreadData->WindowListLock);
|
||||
|
@ -1302,9 +1361,7 @@ NtUserFindWindowEx(HWND hwndParent,
|
|||
{
|
||||
NTSTATUS status;
|
||||
HWND windowHandle;
|
||||
PWINDOW_OBJECT windowObject;
|
||||
PWINDOW_OBJECT ParentWindow;
|
||||
PLIST_ENTRY currentEntry;
|
||||
PWINDOW_OBJECT ParentWindow, WndChildAfter, WndChild;
|
||||
PWNDCLASS_OBJECT classObject;
|
||||
|
||||
// Get a pointer to the class
|
||||
|
@ -1328,39 +1385,35 @@ NtUserFindWindowEx(HWND hwndParent,
|
|||
}
|
||||
|
||||
ExAcquireFastMutexUnsafe (&ParentWindow->ChildrenListLock);
|
||||
currentEntry = ParentWindow->ChildrenListHead.Flink;
|
||||
|
||||
if(hwndChildAfter)
|
||||
{
|
||||
while (currentEntry != &ParentWindow->ChildrenListHead)
|
||||
if (!(WndChildAfter = W32kGetWindowObject(hwndChildAfter)))
|
||||
{
|
||||
windowObject = CONTAINING_RECORD (currentEntry, WINDOW_OBJECT,
|
||||
SiblingListEntry);
|
||||
|
||||
if(windowObject->Self == hwndChildAfter)
|
||||
{
|
||||
/* "The search begins with the _next_ child window in the Z order." */
|
||||
currentEntry = currentEntry->Flink;
|
||||
break;
|
||||
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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:
|
||||
currentEntry=&ParentWindow->ChildrenListHead now so the next
|
||||
block of code will just fall through and the function returns NULL */
|
||||
WndChild = WndChildAfter->NextSibling;
|
||||
}
|
||||
else
|
||||
{
|
||||
WndChild = ParentWindow->FirstChild;
|
||||
}
|
||||
|
||||
while (currentEntry != &ParentWindow->ChildrenListHead)
|
||||
while (WndChild)
|
||||
{
|
||||
windowObject = CONTAINING_RECORD (currentEntry, WINDOW_OBJECT,
|
||||
SiblingListEntry);
|
||||
|
||||
if (classObject == windowObject->Class && (ucWindowName->Buffer==NULL ||
|
||||
RtlCompareUnicodeString (ucWindowName, &windowObject->WindowName, TRUE) == 0))
|
||||
if (classObject == WndChild->Class && (ucWindowName->Buffer==NULL ||
|
||||
RtlCompareUnicodeString (ucWindowName, &WndChild->WindowName, TRUE) == 0))
|
||||
{
|
||||
windowHandle = windowObject->Self;
|
||||
windowHandle = WndChild->Self;
|
||||
|
||||
ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock);
|
||||
W32kReleaseWindowObject(ParentWindow);
|
||||
|
@ -1368,10 +1421,12 @@ NtUserFindWindowEx(HWND hwndParent,
|
|||
|
||||
return windowHandle;
|
||||
}
|
||||
currentEntry = currentEntry->Flink;
|
||||
|
||||
WndChild = WndChild->NextSibling;
|
||||
}
|
||||
|
||||
ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock);
|
||||
|
||||
W32kReleaseWindowObject(ParentWindow);
|
||||
ObmDereferenceObject (classObject);
|
||||
|
||||
|
@ -2064,17 +2119,17 @@ NtUserGetWindowThreadProcessId(HWND hWnd, LPDWORD UnsafePid)
|
|||
PWINDOW_OBJECT Wnd;
|
||||
DWORD tid, pid;
|
||||
|
||||
W32kAcquireWinStaLockShared();
|
||||
W32kAcquireWinLockShared();
|
||||
|
||||
if (!(Wnd = W32kGetWindowObject(hWnd)))
|
||||
{
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tid = W32kGetWindowThreadProcessId(Wnd, &pid);
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
|
||||
if (UnsafePid) MmCopyToCaller(UnsafePid, &pid, sizeof(DWORD));
|
||||
|
||||
|
@ -2107,7 +2162,7 @@ NtUserBuildHwndList(
|
|||
if ( hwndParent )
|
||||
{
|
||||
PWINDOW_OBJECT WindowObject = NULL;
|
||||
PLIST_ENTRY ChildListEntry;
|
||||
PWINDOW_OBJECT Child;
|
||||
|
||||
WindowObject = W32kGetWindowObject ( hwndParent );
|
||||
if ( !WindowObject )
|
||||
|
@ -2118,16 +2173,13 @@ NtUserBuildHwndList(
|
|||
}
|
||||
|
||||
ExAcquireFastMutex ( &WindowObject->ChildrenListLock );
|
||||
ChildListEntry = WindowObject->ChildrenListHead.Flink;
|
||||
while (ChildListEntry != &WindowObject->ChildrenListHead)
|
||||
Child = WindowObject->FirstChild;
|
||||
while (Child)
|
||||
{
|
||||
PWINDOW_OBJECT Child;
|
||||
Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT,
|
||||
SiblingListEntry);
|
||||
if ( pWnd && dwCount < nBufSize )
|
||||
pWnd[dwCount] = Child->Self;
|
||||
dwCount++;
|
||||
ChildListEntry = ChildListEntry->Flink;
|
||||
Child = Child->NextSibling;
|
||||
}
|
||||
ExReleaseFastMutex ( &WindowObject->ChildrenListLock );
|
||||
W32kReleaseWindowObject ( WindowObject );
|
||||
|
@ -2188,7 +2240,7 @@ NtUserBuildHwndList(
|
|||
{
|
||||
PDESKTOP_OBJECT DesktopObject = NULL;
|
||||
KIRQL OldIrql;
|
||||
PLIST_ENTRY WindowListEntry;
|
||||
PWINDOW_OBJECT Child, WndDesktop;
|
||||
|
||||
if ( hDesktop )
|
||||
DesktopObject = W32kGetDesktopObject ( hDesktop );
|
||||
|
@ -2202,16 +2254,15 @@ NtUserBuildHwndList(
|
|||
}
|
||||
|
||||
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 )
|
||||
pWnd[dwCount] = Child->Self;
|
||||
dwCount++;
|
||||
WindowListEntry = WindowListEntry->Flink;
|
||||
Child = Child->NextSibling;
|
||||
}
|
||||
KeReleaseSpinLock ( &DesktopObject->Lock, OldIrql );
|
||||
}
|
||||
|
@ -2248,11 +2299,11 @@ NtUserGetWindow(HWND hWnd, UINT Relationship)
|
|||
PWINDOW_OBJECT Wnd;
|
||||
HWND hWndResult = NULL;
|
||||
|
||||
W32kAcquireWinStaLockShared();
|
||||
W32kAcquireWinLockShared();
|
||||
|
||||
if (!(Wnd = W32kGetWindowObject(hWnd)))
|
||||
{
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2272,19 +2323,22 @@ NtUserGetWindow(HWND hWnd, UINT Relationship)
|
|||
}
|
||||
break;
|
||||
case GW_HWNDNEXT:
|
||||
if (Wnd->NextSibling)
|
||||
if (Wnd->Parent && Wnd->NextSibling)
|
||||
{
|
||||
hWndResult = Wnd->NextSibling->Self;
|
||||
}
|
||||
break;
|
||||
case GW_HWNDPREV:
|
||||
if (Wnd->PrevSibling)
|
||||
if (Wnd->Parent && Wnd->PrevSibling)
|
||||
{
|
||||
hWndResult = Wnd->PrevSibling->Self;
|
||||
}
|
||||
break;
|
||||
case GW_OWNER:
|
||||
if (Wnd->Parent)
|
||||
{
|
||||
hWndResult = Wnd->hWndOwner;
|
||||
}
|
||||
break;
|
||||
case GW_CHILD:
|
||||
if (Wnd->FirstChild)
|
||||
|
@ -2294,7 +2348,7 @@ NtUserGetWindow(HWND hWnd, UINT Relationship)
|
|||
break;
|
||||
}
|
||||
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
|
||||
return hWndResult;
|
||||
}
|
||||
|
@ -2306,23 +2360,128 @@ NtUserGetLastActivePopup(HWND hWnd)
|
|||
PWINDOW_OBJECT Wnd;
|
||||
HWND hWndLastPopup;
|
||||
|
||||
W32kAcquireWinStaLockShared();
|
||||
W32kAcquireWinLockShared();
|
||||
|
||||
if (!(Wnd = W32kGetWindowObject(hWnd)))
|
||||
{
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hWndLastPopup = Wnd->hWndLastPopup;
|
||||
|
||||
W32kReleaseWinStaLock();
|
||||
W32kReleaseWinLock();
|
||||
|
||||
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
|
||||
*/
|
||||
|
|
123
reactos/subsys/win32k/ntuser/winlock.c
Normal file
123
reactos/subsys/win32k/ntuser/winlock.c
Normal 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 */
|
|
@ -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.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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -1112,17 +1112,12 @@ USHORT STATIC STDCALL
|
|||
WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point,
|
||||
PWINDOW_OBJECT* Window)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PWINDOW_OBJECT Current;
|
||||
|
||||
|
||||
ExAcquireFastMutexUnsafe(&ScopeWin->ChildrenListLock);
|
||||
CurrentEntry = ScopeWin->ChildrenListHead.Flink;
|
||||
while (CurrentEntry != &ScopeWin->ChildrenListHead)
|
||||
Current = ScopeWin->FirstChild;
|
||||
while (Current)
|
||||
{
|
||||
Current =
|
||||
CONTAINING_RECORD(CurrentEntry, WINDOW_OBJECT, SiblingListEntry);
|
||||
|
||||
if (Current->Style & WS_VISIBLE &&
|
||||
((!(Current->Style & WS_DISABLED)) ||
|
||||
(Current->Style & (WS_CHILD | WS_POPUP)) != WS_CHILD) &&
|
||||
|
@ -1154,7 +1149,7 @@ WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point,
|
|||
ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock);
|
||||
return(0);
|
||||
}
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
Current = Current->NextSibling;
|
||||
}
|
||||
|
||||
ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock);
|
||||
|
|
|
@ -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: 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -68,41 +68,6 @@ static HDC ScreenDeviceContext = NULL;
|
|||
|
||||
/* 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
|
||||
W32kGetActiveDesktop(VOID)
|
||||
|
@ -376,7 +341,6 @@ NtUserCreateWindowStation(PUNICODE_STRING lpszWindowStationName,
|
|||
return (HWINSTA)0;
|
||||
}
|
||||
|
||||
ExInitializeResourceLite(&WinStaObject->Resource);
|
||||
WinStaObject->HandleTable = ObmCreateHandleTable();
|
||||
if (!WinStaObject->HandleTable)
|
||||
{
|
||||
|
@ -696,7 +660,6 @@ NtUserCreateDesktop(PUNICODE_STRING lpszDesktopName,
|
|||
|
||||
/* Initialize some local (to win32k) desktop state. */
|
||||
DesktopObject->ActiveMessageQueue = NULL;
|
||||
InitializeListHead(&DesktopObject->WindowListHead);
|
||||
DesktopObject->DesktopWindow =
|
||||
W32kCreateDesktopWindow(DesktopObject->WindowStation,
|
||||
DesktopWindowClass,
|
||||
|
|
Loading…
Reference in a new issue