- Fixed few more bugs reported by Wine user32 window test. 4/373 tests fails now. The rest is caused propably by incomplete NtUserDestroyWindow.

- Fixed locking of DCs in NtGdiBitBlt when hDCSrc == hDCDest.

svn path=/trunk/; revision=6457
This commit is contained in:
Filip Navara 2003-10-29 16:25:00 +00:00
parent ac96511aae
commit 4a4b64e0e7
4 changed files with 93 additions and 53 deletions

View file

@ -78,6 +78,8 @@ typedef struct _WINDOW_OBJECT
LIST_ENTRY ThreadListEntry;
/* Pointer to the parent window. */
struct _WINDOW_OBJECT* Parent;
/* Pointer to the owner window. */
struct _WINDOW_OBJECT* Owner;
/* DC Entries (DCE) */
PDCE Dce;
/* Property list head.*/
@ -91,7 +93,6 @@ typedef struct _WINDOW_OBJECT
WNDPROC WndProcA;
WNDPROC WndProcW;
PETHREAD OwnerThread;
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 already declared at top of file */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: window.c,v 1.125 2003/10/29 10:04:55 navaraf Exp $
/* $Id: window.c,v 1.126 2003/10/29 16:24:59 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -101,6 +101,17 @@ inline BOOL IntIsDesktopWindow(PWINDOW_OBJECT Wnd)
}
BOOL IntIsWindow(HWND hWnd)
{
PWINDOW_OBJECT Window;
if (!(Window = IntGetWindowObject(hWnd)))
return FALSE;
else
IntReleaseWindowObject(Window);
return TRUE;
}
static PWINDOW_OBJECT FASTCALL
IntGetProcessWindowObject(PW32PROCESS ProcessData, HWND hWnd)
{
@ -160,7 +171,7 @@ static BOOL BuildChildWindowArray(PWINDOW_OBJECT Window, HWND **Children, unsign
ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
return 0 == *NumChildren || NULL != *Children;
return 0 != *NumChildren && NULL != *Children;
}
@ -186,18 +197,20 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
}
/* free child windows */
if (! BuildChildWindowArray(Window, &Children, &NumChildren))
if (BuildChildWindowArray(Window, &Children, &NumChildren))
{
return 0;
}
for (Index = NumChildren; 0 < Index; Index--)
{
Child = IntGetProcessWindowObject(ProcessData, Children[Index - 1]);
if (NULL != Child)
DbgPrint("NumChildren: %d\n", NumChildren);
for (Index = NumChildren; 0 < Index; Index--)
{
Child = IntGetProcessWindowObject(ProcessData, Children[Index - 1]);
DbgPrint("Child %d: %x\n", Index - 1, Child);
if (NULL != Child)
{
if (IntWndBelongsToThread(Child, ThreadData))
{
DbgPrint("Destroying\n");
IntDestroyWindow(Child, ProcessData, ThreadData, SendMessages);
DbgPrint("End Destroying\n");
}
#if 0 /* FIXME */
else
@ -206,10 +219,11 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
}
#endif
}
}
if (0 != NumChildren)
{
ExFreePool(Children);
}
if (0 != NumChildren)
{
ExFreePool(Children);
}
}
if (SendMessages)
@ -353,7 +367,7 @@ IntCreateDesktopWindow(PWINSTATION_OBJECT WindowStation,
WindowObject->Height = Height;
WindowObject->ParentHandle = NULL;
WindowObject->Parent = NULL;
WindowObject->hWndOwner = NULL;
WindowObject->Owner = NULL;
WindowObject->IDMenu = 0;
WindowObject->Instance = NULL;
WindowObject->Parameters = NULL;
@ -488,7 +502,7 @@ IntGetParent(PWINDOW_OBJECT Wnd)
* I don't understand this either, but I trust Wine test suite.
* -- Filip, 28/oct/2003
*/
return IntGetWindowObject(Wnd->hWndOwner);
return Wnd->Owner;
}
else if (Wnd->Style & WS_CHILD)
{
@ -722,9 +736,7 @@ set_focus_window(HWND New, PWINDOW_OBJECT Window, HWND Previous)
}
}
#if 0 /* FIXME */
if (IsWindow(New))
#endif
if (IntIsWindow(New))
{
NtUserSendMessage(New, WM_SETFOCUS, (WPARAM) Previous, 0);
}
@ -856,12 +868,21 @@ IntSetFocusWindow(HWND hWnd)
HWND FASTCALL
IntSetOwner(HWND hWnd, HWND hWndNewOwner)
{
PWINDOW_OBJECT Wnd;
PWINDOW_OBJECT Wnd, WndOldOwner;
HWND ret;
Wnd = IntGetWindowObject(hWnd);
ret = Wnd->hWndOwner;
Wnd->hWndOwner = hWndNewOwner;
WndOldOwner = Wnd->Owner;
if (WndOldOwner)
{
ret = WndOldOwner->Self;
IntReleaseWindowObject(WndOldOwner);
}
else
{
ret = 0;
}
Wnd->Owner = IntGetWindowObject(hWndNewOwner);
IntReleaseWindowObject(Wnd);
return ret;
}
@ -1388,13 +1409,13 @@ NtUserCreateWindowEx(DWORD dwExStyle,
WindowObject->Height = nHeight;
WindowObject->ContextHelpId = 0;
WindowObject->ParentHandle = ParentWindowHandle;
WindowObject->hWndOwner = OwnerWindowHandle;
WindowObject->IDMenu = (UINT)hMenu;
WindowObject->Instance = hInstance;
WindowObject->Parameters = lpParam;
WindowObject->Self = Handle;
WindowObject->MessageQueue = PsGetWin32Thread()->MessageQueue;
WindowObject->Parent = ParentWindow;
WindowObject->Owner = IntGetWindowObject(OwnerWindowHandle);
WindowObject->UserData = 0;
WindowObject->Unicode = ClassObject->Unicode;
WindowObject->WndProcA = ClassObject->lpfnWndProcA;
@ -1678,8 +1699,8 @@ NtUserDestroyWindow(HWND Wnd)
return FALSE;
}
/* Check for desktop window (has NULL parent) */
if (NULL == Window->Parent)
/* Check for desktop window */
if (IntIsDesktopWindow(Window))
{
IntReleaseWindowObject(Window);
SetLastWin32Error(ERROR_ACCESS_DENIED);
@ -1758,24 +1779,35 @@ NtUserDestroyWindow(HWND Wnd)
{
int i;
BOOL GotOne = FALSE;
HWND *list = WIN_ListChildren(GetDesktopWindow());
if (list)
HWND *list;
UINT NumChildren;
PWINDOW_OBJECT Child;
if (BuildChildWindowArray(IntGetWindowObject(IntGetDesktopWindow()),
&list, &NumChildren))
{
for (i = 0; list[i]; i++)
for (i = 0; i < NumChildren; i++)
{
if (GetWindow(list[i], GW_OWNER) != Wnd)
Child = IntGetWindowObject(list[i]);
if (Child->Owner != Window)
{
continue;
}
if (WIN_IsCurrentThread(list[i]))
if (IntWndBelongsToThread(Child, PsGetWin32Thread()))
{
DestroyWindow(list[i]);
GotOne = TRUE;
IntReleaseWindowObject(Child);
NtUserDestroyWindow(list[i]);
GotOne = TRUE;
continue;
}
WIN_SetOwner(list[i], NULL);
if (Child->Owner != NULL)
{
IntReleaseWindowObject(Child->Owner);
Child->Owner = NULL;
}
IntReleaseWindowObject(Child);
}
HeapFree(GetProcessHeap(), 0, list);
ExFreePool(list);
}
if (! GotOne)
{
@ -2258,7 +2290,10 @@ NtUserGetWindow(HWND hWnd, UINT Relationship)
}
break;
case GW_OWNER:
hWndResult = Wnd->hWndOwner;
if (Wnd->Owner)
{
hWndResult = Wnd->Owner->Self;
}
break;
case GW_CHILD:
if (Wnd->FirstChild)
@ -2350,12 +2385,10 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
if (WindowObject->ParentHandle == IntGetDesktopWindow())
{
Result = (LONG) NtUserGetWindow(WindowObject->Self, GW_OWNER);
/*WindowObject->hWndOwner*/
}
else
{
Result = (LONG) NtUserGetAncestor(WindowObject->Self, GA_PARENT);
/*WindowObject->ParentHandle*/
}
break;
@ -2931,7 +2964,7 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
/* move shell window into background */
if (hwndListView && hwndListView!=hwndShell)
{
WinPosSetWindowPos(hwndListView, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
/* WinPosSetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);*/
if (NtUserGetWindowLong(hwndListView, GWL_EXSTYLE, FALSE) & WS_EX_TOPMOST)
return FALSE;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: winpos.c,v 1.39 2003/10/29 10:04:55 navaraf Exp $
/* $Id: winpos.c,v 1.40 2003/10/29 16:24:59 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -772,7 +772,7 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
PWINDOW_OBJECT ParentWindow;
PWINDOW_OBJECT InsertAfterWindow;
ParentWindow = IntGetWindowObject(Window->ParentHandle);
ParentWindow = Window->Parent;
if (ParentWindow)
{
if (WndInsertAfter == HWND_TOP)
@ -785,7 +785,6 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
IntUnlinkWindow(Window);
IntLinkWindow(Window, ParentWindow, InsertAfterWindow);
ExReleaseFastMutexUnsafe(&ParentWindow->ChildrenListLock);
IntReleaseWindowObject(ParentWindow);
if (InsertAfterWindow != NULL)
IntReleaseWindowObject(InsertAfterWindow);
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: bitmaps.c,v 1.43 2003/10/29 08:38:55 gvg Exp $ */
/* $Id: bitmaps.c,v 1.44 2003/10/29 16:25:00 navaraf Exp $ */
#undef WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
@ -70,13 +70,20 @@ BOOL STDCALL NtGdiBitBlt(HDC hDCDest,
if (UsesSource)
{
DCSrc = DC_LockDc(hDCSrc);
if (NULL == DCSrc)
if (hDCSrc != hDCDest)
{
DC_UnlockDc(hDCDest);
DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
DCSrc = DC_LockDc(hDCSrc);
if (NULL == DCSrc)
{
DC_UnlockDc(hDCDest);
DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
}
else
{
DCSrc = DCDest;
}
}
else
@ -120,7 +127,7 @@ BOOL STDCALL NtGdiBitBlt(HDC hDCDest,
BrushObj = BRUSHOBJ_LockBrush(DCDest->w.hBrush);
if (NULL == BrushObj)
{
if (UsesSource)
if (UsesSource && hDCSrc != hDCDest)
{
DC_UnlockDc(hDCSrc);
}
@ -155,7 +162,7 @@ BOOL STDCALL NtGdiBitBlt(HDC hDCDest,
PalSourceGDI = PALETTE_LockPalette(SourcePalette);
if (NULL == PalSourceGDI)
{
if (UsesSource)
if (UsesSource && hDCSrc != hDCDest)
{
DC_UnlockDc(hDCSrc);
}
@ -175,7 +182,7 @@ BOOL STDCALL NtGdiBitBlt(HDC hDCDest,
PalDestGDI = PALETTE_LockPalette(DestPalette);
if (NULL == PalDestGDI)
{
if (UsesSource)
if (UsesSource && hDCSrc != hDCDest)
{
DC_UnlockDc(hDCSrc);
}
@ -190,7 +197,7 @@ BOOL STDCALL NtGdiBitBlt(HDC hDCDest,
XlateObj = (PXLATEOBJ)IntEngCreateXlate(DestMode, SourceMode, DestPalette, SourcePalette);
if (NULL == XlateObj)
{
if (UsesSource)
if (UsesSource && hDCSrc != hDCDest)
{
DC_UnlockDc(hDCSrc);
}
@ -208,7 +215,7 @@ BOOL STDCALL NtGdiBitBlt(HDC hDCDest,
{
BRUSHOBJ_UnlockBrush(DCDest->w.hBrush);
}
if (UsesSource)
if (UsesSource && hDCSrc != hDCDest)
{
DC_UnlockDc(hDCSrc);
}