Commit 0801ffc5 authored by Alexandre Julliard's avatar Alexandre Julliard

Implemented GetAncestor and removed WIN_GetTopParent.

Removed a few more accesses to the WND structure.
parent 8af0eda7
...@@ -655,6 +655,7 @@ debug_channels (accel caret class clipboard combo cursor dc dde ddeml dialog dri ...@@ -655,6 +655,7 @@ debug_channels (accel caret class clipboard combo cursor dc dde ddeml dialog dri
# win98/win2k # win98/win2k
@ stdcall AllowSetForegroundWindow (long) AllowSetForegroundWindow @ stdcall AllowSetForegroundWindow (long) AllowSetForegroundWindow
@ stdcall AnimateWindow(long long long) AnimateWindow @ stdcall AnimateWindow(long long long) AnimateWindow
@ stdcall GetAncestor(long long) GetAncestor
@ stdcall DrawMenuBarTemp(long long) DrawMenuBarTemp @ stdcall DrawMenuBarTemp(long long) DrawMenuBarTemp
@ stdcall EnumDisplaySettingsExA(str long ptr long) EnumDisplaySettingsExA @ stdcall EnumDisplaySettingsExA(str long ptr long) EnumDisplaySettingsExA
@ stdcall EnumDisplaySettingsExW(wstr long ptr long) EnumDisplaySettingsExW @ stdcall EnumDisplaySettingsExW(wstr long ptr long) EnumDisplaySettingsExW
......
...@@ -488,23 +488,18 @@ int X11DRV_sync_whole_window_position( Display *display, WND *win, int zorder ) ...@@ -488,23 +488,18 @@ int X11DRV_sync_whole_window_position( Display *display, WND *win, int zorder )
if (zorder) if (zorder)
{ {
/* find window that this one must be after */ /* find window that this one must be after */
WND *prev = win->parent->child; HWND prev = GetWindow( win->hwndSelf, GW_HWNDPREV );
if (prev == win) /* top child */ if (!prev) /* top child */
{ {
changes.stack_mode = Above; changes.stack_mode = Above;
mask |= CWStackMode; mask |= CWStackMode;
} }
else else
{ {
while (prev && prev->next != win) prev = prev->next;
if (prev)
{
changes.stack_mode = Below; changes.stack_mode = Below;
changes.sibling = get_whole_window(prev); changes.sibling = X11DRV_get_whole_window(prev);
mask |= CWStackMode | CWSibling; mask |= CWStackMode | CWSibling;
} }
else ERR( "previous window not found for %x, list corrupted?\n", win->hwndSelf );
}
} }
data->whole_rect = whole_rect; data->whole_rect = whole_rect;
...@@ -970,27 +965,6 @@ Window X11DRV_get_whole_window( HWND hwnd ) ...@@ -970,27 +965,6 @@ Window X11DRV_get_whole_window( HWND hwnd )
} }
/***********************************************************************
* X11DRV_get_top_window
*
* Return the X window associated with the top-level parent of a window
*/
Window X11DRV_get_top_window( HWND hwnd )
{
Window ret = 0;
WND *win = WIN_FindWndPtr( hwnd );
while (win && win->parent->hwndSelf != GetDesktopWindow())
WIN_UpdateWndPtr( &win, win->parent );
if (win)
{
struct x11drv_win_data *data = win->pDriverData;
ret = data->whole_window;
WIN_ReleaseWndPtr( win );
}
return ret;
}
/***************************************************************** /*****************************************************************
* SetParent (X11DRV.@) * SetParent (X11DRV.@)
*/ */
...@@ -1142,26 +1116,22 @@ void X11DRV_SetFocus( HWND hwnd ) ...@@ -1142,26 +1116,22 @@ void X11DRV_SetFocus( HWND hwnd )
Display *display = thread_display(); Display *display = thread_display();
XWindowAttributes win_attr; XWindowAttributes win_attr;
Window win; Window win;
WND *wndPtr = WIN_FindWndPtr( hwnd );
WND *w = wndPtr;
if (!wndPtr) return;
/* Only mess with the X focus if there's */ /* Only mess with the X focus if there's */
/* no desktop window and if the window is not managed by the WM. */ /* no desktop window and if the window is not managed by the WM. */
if (root_window != DefaultRootWindow(display)) goto done; if (root_window != DefaultRootWindow(display)) return;
while (w && !get_whole_window(w)) w = w->parent;
if (!w) goto done;
if (w->dwExStyle & WS_EX_MANAGED) goto done;
if (!hwnd) /* If setting the focus to 0, uninstall the colormap */ if (!hwnd) /* If setting the focus to 0, uninstall the colormap */
{ {
if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE) if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
TSXUninstallColormap( display, X11DRV_PALETTE_PaletteXColormap ); TSXUninstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
return;
} }
else if ((win = get_whole_window(w)))
{ hwnd = GetAncestor( hwnd, GA_ROOT );
if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_MANAGED) return;
if (!(win = X11DRV_get_whole_window( hwnd ))) return;
/* Set X focus and install colormap */ /* Set X focus and install colormap */
wine_tsx11_lock(); wine_tsx11_lock();
if (XGetWindowAttributes( display, win, &win_attr ) && if (XGetWindowAttributes( display, win, &win_attr ) &&
...@@ -1177,10 +1147,6 @@ void X11DRV_SetFocus( HWND hwnd ) ...@@ -1177,10 +1147,6 @@ void X11DRV_SetFocus( HWND hwnd )
XInstallColormap( display, X11DRV_PALETTE_PaletteXColormap ); XInstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
} }
wine_tsx11_unlock(); wine_tsx11_unlock();
}
done:
WIN_ReleaseWndPtr( wndPtr );
} }
......
...@@ -557,13 +557,15 @@ static UINT SWP_DoNCCalcSize( WND* wndPtr, WINDOWPOS* pWinpos, ...@@ -557,13 +557,15 @@ static UINT SWP_DoNCCalcSize( WND* wndPtr, WINDOWPOS* pWinpos,
* *
* FIXME: hide/show owned popups when owner visibility changes. * FIXME: hide/show owned popups when owner visibility changes.
*/ */
static HWND SWP_DoOwnedPopups(WND* pDesktop, WND* wndPtr, HWND hwndInsertAfter, WORD flags) static HWND SWP_DoOwnedPopups(HWND hwnd, HWND hwndInsertAfter)
{ {
WND *w = WIN_LockWndPtr(pDesktop->child); HWND *list = NULL;
HWND owner = GetWindow( hwnd, GW_OWNER );
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
WARN("(%04x) hInsertAfter = %04x\n", wndPtr->hwndSelf, hwndInsertAfter ); WARN("(%04x) hInsertAfter = %04x\n", hwnd, hwndInsertAfter );
if( (wndPtr->dwStyle & WS_POPUP) && wndPtr->owner ) if ((style & WS_POPUP) && owner)
{ {
/* make sure this popup stays above the owner */ /* make sure this popup stays above the owner */
...@@ -571,35 +573,40 @@ static HWND SWP_DoOwnedPopups(WND* pDesktop, WND* wndPtr, HWND hwndInsertAfter, ...@@ -571,35 +573,40 @@ static HWND SWP_DoOwnedPopups(WND* pDesktop, WND* wndPtr, HWND hwndInsertAfter,
if( hwndInsertAfter != HWND_TOP ) if( hwndInsertAfter != HWND_TOP )
{ {
while( w && w != wndPtr->owner ) if ((list = WIN_BuildWinArray( GetDesktopWindow() )))
{ {
if (w != wndPtr) hwndLocalPrev = w->hwndSelf; int i;
if( hwndLocalPrev == hwndInsertAfter ) break; for (i = 0; list[i]; i++)
WIN_UpdateWndPtr(&w,w->next); {
if (list[i] == owner) break;
if (list[i] != hwnd) hwndLocalPrev = list[i];
if (hwndLocalPrev == hwndInsertAfter) break;
} }
hwndInsertAfter = hwndLocalPrev; hwndInsertAfter = hwndLocalPrev;
} }
} }
else if( wndPtr->dwStyle & WS_CHILD ) }
goto END; else if (style & WS_CHILD) return hwndInsertAfter;
WIN_UpdateWndPtr(&w, pDesktop->child);
while( w ) if (!list) list = WIN_BuildWinArray( GetDesktopWindow() );
if (list)
{ {
if( w == wndPtr ) break; int i;
for (i = 0; list[i]; i++)
if( (w->dwStyle & WS_POPUP) && w->owner == wndPtr )
{ {
SetWindowPos(w->hwndSelf, hwndInsertAfter, 0, 0, 0, 0, if (list[i] == hwnd) break;
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_DEFERERASE); if ((GetWindowLongW( list[i], GWL_STYLE ) & WS_POPUP) &&
hwndInsertAfter = w->hwndSelf; GetWindow( list[i], GW_OWNER ) == hwnd)
{
SetWindowPos( list[i], hwndInsertAfter, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE |
SWP_NOSENDCHANGING | SWP_DEFERERASE );
hwndInsertAfter = list[i];
}
} }
WIN_UpdateWndPtr(&w, w->next); WIN_ReleaseWinArray( list );
} }
END:
WIN_ReleaseWndPtr(w);
return hwndInsertAfter; return hwndInsertAfter;
} }
...@@ -705,9 +712,8 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos ) ...@@ -705,9 +712,8 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
if((winpos->flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER) if((winpos->flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER)
{ {
if( wndPtr->parent->hwndSelf == GetDesktopWindow() ) if (GetAncestor( winpos->hwnd, GA_PARENT ) == GetDesktopWindow())
winpos->hwndInsertAfter = SWP_DoOwnedPopups( wndPtr->parent, wndPtr, winpos->hwndInsertAfter = SWP_DoOwnedPopups( winpos->hwnd, winpos->hwndInsertAfter );
winpos->hwndInsertAfter, winpos->flags );
} }
/* Common operations */ /* Common operations */
...@@ -729,7 +735,7 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos ) ...@@ -729,7 +735,7 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
RECT rect; RECT rect;
UnionRect(&rect, &newWindowRect, &wndPtr->rectWindow); UnionRect(&rect, &newWindowRect, &wndPtr->rectWindow);
DCE_InvalidateDCE(wndPtr, &rect); DCE_InvalidateDCE(wndPtr->hwndSelf, &rect);
} }
oldWindowRect = wndPtr->rectWindow; oldWindowRect = wndPtr->rectWindow;
...@@ -1152,7 +1158,7 @@ void X11DRV_MapNotify( HWND hwnd, XMapEvent *event ) ...@@ -1152,7 +1158,7 @@ void X11DRV_MapNotify( HWND hwnd, XMapEvent *event )
Window root, top; Window root, top;
RECT rect; RECT rect;
DCE_InvalidateDCE( win, &win->rectWindow ); DCE_InvalidateDCE( hwnd, &win->rectWindow );
win->dwStyle &= ~WS_MINIMIZE; win->dwStyle &= ~WS_MINIMIZE;
win->dwStyle |= WS_VISIBLE; win->dwStyle |= WS_VISIBLE;
WIN_InternalShowOwnedPopups( hwnd, TRUE, TRUE ); WIN_InternalShowOwnedPopups( hwnd, TRUE, TRUE );
......
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
#include "windef.h" #include "windef.h"
struct tagWND;
/* internal DCX flags */ /* internal DCX flags */
#define DCX_DCEEMPTY 0x00000800 #define DCX_DCEEMPTY 0x00000800
#define DCX_DCEBUSY 0x00001000 #define DCX_DCEBUSY 0x00001000
...@@ -40,8 +38,8 @@ typedef struct tagDCE ...@@ -40,8 +38,8 @@ typedef struct tagDCE
extern DCE* DCE_AllocDCE( HWND hWnd, DCE_TYPE type ); extern DCE* DCE_AllocDCE( HWND hWnd, DCE_TYPE type );
extern DCE* DCE_FreeDCE( DCE *dce ); extern DCE* DCE_FreeDCE( DCE *dce );
extern void DCE_FreeWindowDCE( struct tagWND* ); extern void DCE_FreeWindowDCE( HWND );
extern INT DCE_ExcludeRgn( HDC, struct tagWND*, HRGN ); extern INT DCE_ExcludeRgn( HDC, HWND, HRGN );
extern BOOL DCE_InvalidateDCE( struct tagWND*, const RECT* ); extern BOOL DCE_InvalidateDCE( HWND, const RECT* );
#endif /* __WINE_DCE_H */ #endif /* __WINE_DCE_H */
...@@ -89,10 +89,8 @@ extern void WIN_WalkWindows( HWND hwnd, int indent ); ...@@ -89,10 +89,8 @@ extern void WIN_WalkWindows( HWND hwnd, int indent );
extern BOOL WIN_UnlinkWindow( HWND hwnd ); extern BOOL WIN_UnlinkWindow( HWND hwnd );
extern BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter ); extern BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter );
extern HWND WIN_FindWinToRepaint( HWND hwnd ); extern HWND WIN_FindWinToRepaint( HWND hwnd );
extern BOOL WIN_DestroyThreadWindows( HWND hwnd ); extern void WIN_DestroyThreadWindows( HWND hwnd );
extern BOOL WIN_CreateDesktopWindow(void); extern BOOL WIN_CreateDesktopWindow(void);
extern HWND WIN_GetTopParent( HWND hwnd );
extern WND* WIN_GetTopParentPtr( WND* pWnd );
extern BOOL WIN_IsWindowDrawable(WND*, BOOL ); extern BOOL WIN_IsWindowDrawable(WND*, BOOL );
extern HWND *WIN_BuildWinArray( HWND hwnd ); extern HWND *WIN_BuildWinArray( HWND hwnd );
extern void WIN_ReleaseWinArray( HWND *wndArray ); extern void WIN_ReleaseWinArray( HWND *wndArray );
......
...@@ -1089,6 +1089,11 @@ typedef struct { ...@@ -1089,6 +1089,11 @@ typedef struct {
#define GW_OWNER 4 #define GW_OWNER 4
#define GW_CHILD 5 #define GW_CHILD 5
/* GetAncestor() constants */
#define GA_PARENT 1
#define GA_ROOT 2
#define GA_ROOTOWNER 3
/* WM_GETMINMAXINFO struct */ /* WM_GETMINMAXINFO struct */
typedef struct typedef struct
{ {
...@@ -3540,6 +3545,7 @@ HWND WINAPI FindWindowExW(HWND,HWND,LPCWSTR,LPCWSTR); ...@@ -3540,6 +3545,7 @@ HWND WINAPI FindWindowExW(HWND,HWND,LPCWSTR,LPCWSTR);
BOOL WINAPI FlashWindow(HWND,BOOL); BOOL WINAPI FlashWindow(HWND,BOOL);
INT WINAPI FrameRect(HDC,const RECT*,HBRUSH); INT WINAPI FrameRect(HDC,const RECT*,HBRUSH);
HWND WINAPI GetActiveWindow(void); HWND WINAPI GetActiveWindow(void);
HWND WINAPI GetAncestor(HWND,UINT);
DWORD WINAPI GetAppCompatFlags(HTASK); DWORD WINAPI GetAppCompatFlags(HTASK);
WORD WINAPI GetAsyncKeyState(INT); WORD WINAPI GetAsyncKeyState(INT);
HWND WINAPI GetCapture(void); HWND WINAPI GetCapture(void);
......
...@@ -395,7 +395,6 @@ typedef struct x11drv_win_data X11DRV_WND_DATA; ...@@ -395,7 +395,6 @@ typedef struct x11drv_win_data X11DRV_WND_DATA;
extern Window X11DRV_get_client_window( HWND hwnd ); extern Window X11DRV_get_client_window( HWND hwnd );
extern Window X11DRV_get_whole_window( HWND hwnd ); extern Window X11DRV_get_whole_window( HWND hwnd );
extern Window X11DRV_get_top_window( HWND hwnd );
inline static Window get_client_window( WND *wnd ) inline static Window get_client_window( WND *wnd )
{ {
......
...@@ -143,7 +143,7 @@ DCE* DCE_FreeDCE( DCE *dce ) ...@@ -143,7 +143,7 @@ DCE* DCE_FreeDCE( DCE *dce )
* *
* Remove owned DCE and reset unreleased cache DCEs. * Remove owned DCE and reset unreleased cache DCEs.
*/ */
void DCE_FreeWindowDCE( WND* pWnd ) void DCE_FreeWindowDCE( HWND hwnd )
{ {
DCE *pDCE; DCE *pDCE;
...@@ -152,14 +152,16 @@ void DCE_FreeWindowDCE( WND* pWnd ) ...@@ -152,14 +152,16 @@ void DCE_FreeWindowDCE( WND* pWnd )
while( pDCE ) while( pDCE )
{ {
if( pDCE->hwndCurrent == pWnd->hwndSelf ) if( pDCE->hwndCurrent == hwnd )
{ {
WND *pWnd = WIN_FindWndPtr( hwnd );
if( pDCE == pWnd->dce ) /* owned or Class DCE*/ if( pDCE == pWnd->dce ) /* owned or Class DCE*/
{ {
if (pWnd->clsStyle & CS_OWNDC) /* owned DCE*/ if (pWnd->clsStyle & CS_OWNDC) /* owned DCE*/
{ {
pDCE = DCE_FreeDCE( pDCE ); pDCE = DCE_FreeDCE( pDCE );
pWnd->dce = NULL; pWnd->dce = NULL;
WIN_ReleaseWndPtr( pWnd );
continue; continue;
} }
else if( pDCE->DCXflags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN) ) /* Class DCE*/ else if( pDCE->DCXflags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN) ) /* Class DCE*/
...@@ -188,6 +190,7 @@ void DCE_FreeWindowDCE( WND* pWnd ) ...@@ -188,6 +190,7 @@ void DCE_FreeWindowDCE( WND* pWnd )
pDCE->DCXflags |= DCX_DCEEMPTY; pDCE->DCXflags |= DCX_DCEEMPTY;
pDCE->hwndCurrent = 0; pDCE->hwndCurrent = 0;
} }
WIN_ReleaseWndPtr( pWnd );
} }
pDCE = pDCE->next; pDCE = pDCE->next;
} }
...@@ -257,17 +260,17 @@ static INT DCE_ReleaseDC( DCE* dce ) ...@@ -257,17 +260,17 @@ static INT DCE_ReleaseDC( DCE* dce )
* an ancestor and whose client rect intersects with specified update * an ancestor and whose client rect intersects with specified update
* rectangle. In addition, pWnd->parent DCEs may need to be updated if * rectangle. In addition, pWnd->parent DCEs may need to be updated if
* DCX_CLIPCHILDREN flag is set. */ * DCX_CLIPCHILDREN flag is set. */
BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate) BOOL DCE_InvalidateDCE(HWND hwnd, const RECT* pRectUpdate)
{ {
WND* wndScope = WIN_LockWndPtr(pWnd->parent); HWND hwndScope = GetAncestor( hwnd, GA_PARENT );
BOOL bRet = FALSE; BOOL bRet = FALSE;
if( wndScope ) if( hwndScope )
{ {
DCE *dce; DCE *dce;
TRACE("scope hwnd = %04x, (%i,%i - %i,%i)\n", TRACE("scope hwnd = %04x, (%i,%i - %i,%i)\n",
wndScope->hwndSelf, pRectUpdate->left,pRectUpdate->top, hwndScope, pRectUpdate->left,pRectUpdate->top,
pRectUpdate->right,pRectUpdate->bottom); pRectUpdate->right,pRectUpdate->bottom);
if(TRACE_ON(dc)) if(TRACE_ON(dc))
DCE_DumpCache(); DCE_DumpCache();
...@@ -276,27 +279,20 @@ BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate) ...@@ -276,27 +279,20 @@ BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate)
for (dce = firstDCE; (dce); dce = dce->next) for (dce = firstDCE; (dce); dce = dce->next)
{ {
if( !(dce->DCXflags & DCX_DCEEMPTY) ) WND* wndCurrent;
{ HWND tmp;
WND* wndCurrent = WIN_FindWndPtr(dce->hwndCurrent);
if( wndCurrent )
{
WND* wnd = NULL;
INT xoffset = 0, yoffset = 0; INT xoffset = 0, yoffset = 0;
if( (wndCurrent == wndScope) && !(dce->DCXflags & DCX_CLIPCHILDREN) ) if (dce->DCXflags & DCX_DCEEMPTY) continue;
{ if ((dce->hwndCurrent == hwndScope) && !(dce->DCXflags & DCX_CLIPCHILDREN))
/* child window positions don't bother us */ continue; /* child window positions don't bother us */
WIN_ReleaseWndPtr(wndCurrent); if (!(wndCurrent = WIN_FindWndPtr(dce->hwndCurrent))) continue;
continue;
}
/* check if DCE window is within the z-order scope */ /* check if DCE window is within the z-order scope */
for( wnd = WIN_LockWndPtr(wndCurrent); wnd; WIN_UpdateWndPtr(&wnd,wnd->parent)) for (tmp = dce->hwndCurrent; tmp; tmp = GetAncestor( tmp, GA_PARENT ))
{ {
if( wnd == wndScope ) if (tmp == hwndScope )
{ {
RECT wndRect; RECT wndRect;
...@@ -305,7 +301,7 @@ BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate) ...@@ -305,7 +301,7 @@ BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate)
OffsetRect( &wndRect, xoffset - wndCurrent->rectClient.left, OffsetRect( &wndRect, xoffset - wndCurrent->rectClient.left,
yoffset - wndCurrent->rectClient.top); yoffset - wndCurrent->rectClient.top);
if (pWnd == wndCurrent || if (hwnd == wndCurrent->hwndSelf ||
IntersectRect( &wndRect, &wndRect, pRectUpdate )) IntersectRect( &wndRect, &wndRect, pRectUpdate ))
{ {
if( !(dce->DCXflags & DCX_DCEBUSY) ) if( !(dce->DCXflags & DCX_DCEBUSY) )
...@@ -331,17 +327,18 @@ BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate) ...@@ -331,17 +327,18 @@ BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate)
bRet = TRUE; bRet = TRUE;
} }
} }
WIN_ReleaseWndPtr(wnd);
break; break;
} }
else
{
WND* wnd = WIN_FindWndPtr( tmp );
xoffset += wnd->rectClient.left; xoffset += wnd->rectClient.left;
yoffset += wnd->rectClient.top; yoffset += wnd->rectClient.top;
WIN_ReleaseWndPtr( wnd );
} }
} }
WIN_ReleaseWndPtr(wndCurrent); WIN_ReleaseWndPtr(wndCurrent);
}
} /* dce list */ } /* dce list */
WIN_ReleaseWndPtr(wndScope);
} }
return bRet; return bRet;
} }
...@@ -353,24 +350,22 @@ BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate) ...@@ -353,24 +350,22 @@ BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate)
* Translate given region from the wnd client to the DC coordinates * Translate given region from the wnd client to the DC coordinates
* and add it to the clipping region. * and add it to the clipping region.
*/ */
INT DCE_ExcludeRgn( HDC hDC, WND* wnd, HRGN hRgn ) INT DCE_ExcludeRgn( HDC hDC, HWND hwnd, HRGN hRgn )
{ {
POINT pt = {0, 0}; POINT pt = {0, 0};
DCE *dce = firstDCE; DCE *dce = firstDCE;
while (dce && (dce->hDC != hDC)) dce = dce->next; while (dce && (dce->hDC != hDC)) dce = dce->next;
if( dce ) if (!dce) return ERROR;
{
MapWindowPoints( wnd->hwndSelf, dce->hwndCurrent, &pt, 1); MapWindowPoints( hwnd, dce->hwndCurrent, &pt, 1);
if( dce->DCXflags & DCX_WINDOW ) if( dce->DCXflags & DCX_WINDOW )
{ {
wnd = WIN_FindWndPtr(dce->hwndCurrent); WND *wnd = WIN_FindWndPtr(dce->hwndCurrent);
pt.x += wnd->rectClient.left - wnd->rectWindow.left; pt.x += wnd->rectClient.left - wnd->rectWindow.left;
pt.y += wnd->rectClient.top - wnd->rectWindow.top; pt.y += wnd->rectClient.top - wnd->rectWindow.top;
WIN_ReleaseWndPtr(wnd); WIN_ReleaseWndPtr(wnd);
} }
}
else return ERROR;
OffsetRgn(hRgn, pt.x, pt.y); OffsetRgn(hRgn, pt.x, pt.y);
return ExtSelectClipRgn( hDC, hRgn, RGN_DIFF ); return ExtSelectClipRgn( hDC, hRgn, RGN_DIFF );
...@@ -401,6 +396,7 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) ...@@ -401,6 +396,7 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
DWORD dcxFlags = 0; DWORD dcxFlags = 0;
BOOL bUpdateVisRgn = TRUE; BOOL bUpdateVisRgn = TRUE;
BOOL bUpdateClipOrigin = FALSE; BOOL bUpdateClipOrigin = FALSE;
HWND parent;
TRACE("hwnd %04x, hrgnClip %04x, flags %08x\n", TRACE("hwnd %04x, hrgnClip %04x, flags %08x\n",
hwnd, hrgnClip, (unsigned)flags); hwnd, hrgnClip, (unsigned)flags);
...@@ -431,7 +427,8 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) ...@@ -431,7 +427,8 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
if (flags & DCX_WINDOW) flags &= ~DCX_CLIPCHILDREN; if (flags & DCX_WINDOW) flags &= ~DCX_CLIPCHILDREN;
if (!wndPtr->parent || (wndPtr->parent->hwndSelf == GetDesktopWindow())) parent = GetAncestor( hwnd, GA_PARENT );
if (!parent || (parent == GetDesktopWindow()))
flags = (flags & ~DCX_PARENTCLIP) | DCX_CLIPSIBLINGS; flags = (flags & ~DCX_PARENTCLIP) | DCX_CLIPSIBLINGS;
/* it seems parent clip is ignored when clipping siblings or children */ /* it seems parent clip is ignored when clipping siblings or children */
...@@ -439,11 +436,11 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) ...@@ -439,11 +436,11 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
if( flags & DCX_PARENTCLIP ) if( flags & DCX_PARENTCLIP )
{ {
if( (wndPtr->dwStyle & WS_VISIBLE) && (wndPtr->parent->dwStyle & WS_VISIBLE) ) LONG parent_style = GetWindowLongW( parent, GWL_STYLE );
if( (wndPtr->dwStyle & WS_VISIBLE) && (parent_style & WS_VISIBLE) )
{ {
flags &= ~DCX_CLIPCHILDREN; flags &= ~DCX_CLIPCHILDREN;
if( wndPtr->parent->dwStyle & WS_CLIPSIBLINGS ) if (parent_style & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS;
flags |= DCX_CLIPSIBLINGS;
} }
} }
......
...@@ -162,14 +162,14 @@ static void DEFWND_SetRedraw( HWND hwnd, WPARAM wParam ) ...@@ -162,14 +162,14 @@ static void DEFWND_SetRedraw( HWND hwnd, WPARAM wParam )
WND *wndPtr = WIN_FindWndPtr( hwnd ); WND *wndPtr = WIN_FindWndPtr( hwnd );
BOOL bVisible = wndPtr->dwStyle & WS_VISIBLE; BOOL bVisible = wndPtr->dwStyle & WS_VISIBLE;
TRACE("%04x %i\n", wndPtr->hwndSelf, (wParam!=0) ); TRACE("%04x %i\n", hwnd, (wParam!=0) );
if( wParam ) if( wParam )
{ {
if( !bVisible ) if( !bVisible )
{ {
wndPtr->dwStyle |= WS_VISIBLE; wndPtr->dwStyle |= WS_VISIBLE;
DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow ); DCE_InvalidateDCE( hwnd, &wndPtr->rectWindow );
} }
} }
else if( bVisible ) else if( bVisible )
...@@ -177,8 +177,8 @@ static void DEFWND_SetRedraw( HWND hwnd, WPARAM wParam ) ...@@ -177,8 +177,8 @@ static void DEFWND_SetRedraw( HWND hwnd, WPARAM wParam )
if( wndPtr->dwStyle & WS_MINIMIZE ) wParam = RDW_VALIDATE; if( wndPtr->dwStyle & WS_MINIMIZE ) wParam = RDW_VALIDATE;
else wParam = RDW_ALLCHILDREN | RDW_VALIDATE; else wParam = RDW_ALLCHILDREN | RDW_VALIDATE;
RedrawWindow( wndPtr->hwndSelf, NULL, 0, wParam ); RedrawWindow( hwnd, NULL, 0, wParam );
DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow ); DCE_InvalidateDCE( hwnd, &wndPtr->rectWindow );
wndPtr->dwStyle &= ~WS_VISIBLE; wndPtr->dwStyle &= ~WS_VISIBLE;
} }
WIN_ReleaseWndPtr( wndPtr ); WIN_ReleaseWndPtr( wndPtr );
...@@ -520,7 +520,7 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa ...@@ -520,7 +520,7 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
if( wParam == VK_F4 ) /* try to close the window */ if( wParam == VK_F4 ) /* try to close the window */
{ {
HWND top = WIN_GetTopParent( hwnd ); HWND top = GetAncestor( hwnd, GA_ROOT );
if (!(GetClassLongW( top, GCL_STYLE ) & CS_NOCLOSE)) if (!(GetClassLongW( top, GCL_STYLE ) & CS_NOCLOSE))
PostMessageW( top, WM_SYSCOMMAND, SC_CLOSE, 0 ); PostMessageW( top, WM_SYSCOMMAND, SC_CLOSE, 0 );
} }
...@@ -537,7 +537,7 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa ...@@ -537,7 +537,7 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
/* Press and release F10 or ALT */ /* Press and release F10 or ALT */
if (((wParam == VK_MENU) && iMenuSysKey) || if (((wParam == VK_MENU) && iMenuSysKey) ||
((wParam == VK_F10) && iF10Key)) ((wParam == VK_F10) && iF10Key))
SendMessageW( WIN_GetTopParent(hwnd), WM_SYSCOMMAND, SC_KEYMENU, 0L ); SendMessageW( GetAncestor( hwnd, GA_ROOT ), WM_SYSCOMMAND, SC_KEYMENU, 0L );
iMenuSysKey = iF10Key = 0; iMenuSysKey = iF10Key = 0;
break; break;
......
...@@ -59,39 +59,40 @@ HWND16 WINAPI SetFocus16( HWND16 hwnd ) ...@@ -59,39 +59,40 @@ HWND16 WINAPI SetFocus16( HWND16 hwnd )
HWND WINAPI SetFocus( HWND hwnd ) HWND WINAPI SetFocus( HWND hwnd )
{ {
HWND hWndFocus = 0, hwndTop = hwnd; HWND hWndFocus = 0, hwndTop = hwnd;
WND *wndPtr = WIN_FindWndPtr( hwnd );
MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0; MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
BOOL16 bRet = 0; BOOL bRet = 0;
/* Get the messageQ for the current thread */ /* Get the messageQ for the current thread */
if (!(pCurMsgQ = QUEUE_Current())) if (!(pCurMsgQ = QUEUE_Current()))
{ {
WARN("\tCurrent message queue not found. Exiting!\n" ); WARN("\tCurrent message queue not found. Exiting!\n" );
goto CLEANUP; return 0;
} }
if (wndPtr) if (hwnd)
{ {
/* Check if we can set the focus to this window */ /* Check if we can set the focus to this window */
WND *wndPtr;
while ( (wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD ) for (;;)
{ {
if ( wndPtr->dwStyle & ( WS_MINIMIZE | WS_DISABLED) ) HWND parent;
goto CLEANUP; LONG style = GetWindowLongW( hwndTop, GWL_STYLE );
WIN_UpdateWndPtr(&wndPtr,wndPtr->parent); if (style & (WS_MINIMIZE | WS_DISABLED)) return 0;
if (!wndPtr) goto CLEANUP; parent = GetAncestor( hwndTop, GA_PARENT );
hwndTop = wndPtr->hwndSelf; if (!parent || parent == GetDesktopWindow()) break;
hwndTop = parent;
} }
/* definitely at the top window now */ if (!(wndPtr = WIN_FindWndPtr( hwndTop ))) return 0;
if ( wndPtr->dwStyle & ( WS_MINIMIZE | WS_DISABLED) ) goto CLEANUP;
/* Retrieve the message queue associated with this window */ /* Retrieve the message queue associated with this window */
pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ ); pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
WIN_ReleaseWndPtr( wndPtr );
if ( !pMsgQ ) if ( !pMsgQ )
{ {
WARN("\tMessage queue not found. Exiting!\n" ); WARN("\tMessage queue not found. Exiting!\n" );
goto CLEANUP; return 0;
} }
/* Make sure that message queue for the window we are setting focus to /* Make sure that message queue for the window we are setting focus to
...@@ -133,7 +134,7 @@ HWND WINAPI SetFocus( HWND hwnd ) ...@@ -133,7 +134,7 @@ HWND WINAPI SetFocus( HWND hwnd )
else /* NULL hwnd passed in */ else /* NULL hwnd passed in */
{ {
if( HOOK_CallHooksA( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)hWndFocus ) ) if( HOOK_CallHooksA( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)hWndFocus ) )
goto CLEANUP; return 0;
/* Get the current focus from the perQ data of the current message Q */ /* Get the current focus from the perQ data of the current message Q */
hWndFocus = PERQDATA_GetFocusWnd( pCurMsgQ->pQData ); hWndFocus = PERQDATA_GetFocusWnd( pCurMsgQ->pQData );
...@@ -150,7 +151,6 @@ CLEANUP: ...@@ -150,7 +151,6 @@ CLEANUP:
if ( pMsgQ ) if ( pMsgQ )
QUEUE_Unlock( pMsgQ ); QUEUE_Unlock( pMsgQ );
WIN_ReleaseWndPtr(wndPtr);
return bRet ? hWndFocus : 0; return bRet ? hWndFocus : 0;
} }
......
...@@ -433,7 +433,7 @@ static BOOL process_cooked_mouse_message( MSG *msg, BOOL remove ) ...@@ -433,7 +433,7 @@ static BOOL process_cooked_mouse_message( MSG *msg, BOOL remove )
(raw_message == WM_RBUTTONDOWN) || (raw_message == WM_RBUTTONDOWN) ||
(raw_message == WM_MBUTTONDOWN)) (raw_message == WM_MBUTTONDOWN))
{ {
HWND hwndTop = WIN_GetTopParent( msg->hwnd ); HWND hwndTop = GetAncestor( msg->hwnd, GA_ROOT );
/* Send the WM_PARENTNOTIFY, /* Send the WM_PARENTNOTIFY,
* note that even for double/nonclient clicks * note that even for double/nonclient clicks
......
...@@ -1787,7 +1787,7 @@ void NC_GetSysPopupPos( HWND hwnd, RECT* rect ) ...@@ -1787,7 +1787,7 @@ void NC_GetSysPopupPos( HWND hwnd, RECT* rect )
NC_GetInsideRect( hwnd, rect ); NC_GetInsideRect( hwnd, rect );
OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top); OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
if (wndPtr->dwStyle & WS_CHILD) if (wndPtr->dwStyle & WS_CHILD)
ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect ); ClientToScreen( GetParent(hwnd), (POINT *)rect );
if (TWEAK_WineLook == WIN31_LOOK) { if (TWEAK_WineLook == WIN31_LOOK) {
rect->right = rect->left + GetSystemMetrics(SM_CXSIZE); rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE); rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
...@@ -2065,7 +2065,7 @@ LONG NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) ...@@ -2065,7 +2065,7 @@ LONG NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam )
{ {
case HTCAPTION: case HTCAPTION:
{ {
HWND top = WIN_GetTopParent(hwnd); HWND top = GetAncestor( hwnd, GA_ROOT );
if( WINPOS_SetActiveWindow(top, TRUE, TRUE) || (GetActiveWindow() == top) ) if( WINPOS_SetActiveWindow(top, TRUE, TRUE) || (GetActiveWindow() == top) )
SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam ); SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
...@@ -2187,8 +2187,11 @@ LONG NC_HandleSysCommand( HWND hwnd, WPARAM wParam, POINT pt ) ...@@ -2187,8 +2187,11 @@ LONG NC_HandleSysCommand( HWND hwnd, WPARAM wParam, POINT pt )
TRACE("Handling WM_SYSCOMMAND %x %ld,%ld\n", wParam, pt.x, pt.y ); TRACE("Handling WM_SYSCOMMAND %x %ld,%ld\n", wParam, pt.x, pt.y );
if (wndPtr->parent && (uCommand != SC_KEYMENU)) if (uCommand != SC_KEYMENU)
ScreenToClient( wndPtr->parent->hwndSelf, &pt ); {
HWND parent = GetAncestor( hwnd, GA_PARENT );
if (parent != GetDesktopWindow()) ScreenToClient( parent, &pt );
}
switch (uCommand) switch (uCommand)
{ {
......
...@@ -96,12 +96,8 @@ static void add_paint_count( HWND hwnd, int incr ) ...@@ -96,12 +96,8 @@ static void add_paint_count( HWND hwnd, int incr )
* RDW_Paint() method. * RDW_Paint() method.
* *
*/ */
static BOOL WIN_HaveToDelayNCPAINT( static BOOL WIN_HaveToDelayNCPAINT( HWND hwnd, UINT uncFlags)
WND* wndPtr,
UINT uncFlags)
{ {
WND* parentWnd = NULL;
/* /*
* Test the shortcut first. (duh) * Test the shortcut first. (duh)
*/ */
...@@ -122,22 +118,16 @@ static BOOL WIN_HaveToDelayNCPAINT( ...@@ -122,22 +118,16 @@ static BOOL WIN_HaveToDelayNCPAINT(
* that doesn't have the WS_CLIPCHILDREN style and that * that doesn't have the WS_CLIPCHILDREN style and that
* has an invalid region. * has an invalid region.
*/ */
parentWnd = WIN_LockWndPtr(wndPtr->parent); while ((hwnd = GetAncestor( hwnd, GA_PARENT )))
while (parentWnd!=NULL)
{ {
if ( ((parentWnd->dwStyle & WS_CLIPCHILDREN) == 0) && WND* parentWnd = WIN_FindWndPtr( hwnd );
(parentWnd->hrgnUpdate != 0) ) if (!(parentWnd->dwStyle & WS_CLIPCHILDREN) && parentWnd->hrgnUpdate)
{ {
WIN_ReleaseWndPtr(parentWnd); WIN_ReleaseWndPtr( parentWnd );
return TRUE; return TRUE;
} }
WIN_ReleaseWndPtr( parentWnd );
WIN_UpdateWndPtr(&parentWnd, parentWnd->parent);
} }
WIN_ReleaseWndPtr(parentWnd);
return FALSE; return FALSE;
} }
...@@ -188,7 +178,7 @@ static HRGN WIN_UpdateNCRgn(WND* wnd, HRGN hRgn, UINT uncFlags ) ...@@ -188,7 +178,7 @@ static HRGN WIN_UpdateNCRgn(WND* wnd, HRGN hRgn, UINT uncFlags )
* If the window's non-client area needs to be painted, * If the window's non-client area needs to be painted,
*/ */
if ( ( wnd->flags & WIN_NEEDS_NCPAINT ) && if ( ( wnd->flags & WIN_NEEDS_NCPAINT ) &&
!WIN_HaveToDelayNCPAINT(wnd, uncFlags) ) !WIN_HaveToDelayNCPAINT(wnd->hwndSelf, uncFlags) )
{ {
RECT r2, r3; RECT r2, r3;
...@@ -495,7 +485,7 @@ HBRUSH16 WINAPI GetControlBrush16( HWND16 hwnd, HDC16 hdc, UINT16 ctlType ) ...@@ -495,7 +485,7 @@ HBRUSH16 WINAPI GetControlBrush16( HWND16 hwnd, HDC16 hdc, UINT16 ctlType )
*/ */
static void RDW_ValidateParent(WND *wndChild) static void RDW_ValidateParent(WND *wndChild)
{ {
WND *wndParent = WIN_LockWndPtr(wndChild->parent); HWND parent;
HRGN hrg; HRGN hrg;
if (wndChild->hrgnUpdate == 1 ) { if (wndChild->hrgnUpdate == 1 ) {
...@@ -508,7 +498,10 @@ static void RDW_ValidateParent(WND *wndChild) ...@@ -508,7 +498,10 @@ static void RDW_ValidateParent(WND *wndChild)
} else } else
hrg = wndChild->hrgnUpdate; hrg = wndChild->hrgnUpdate;
while ((wndParent) && (wndParent->hwndSelf != GetDesktopWindow()) ) { parent = GetAncestor( wndChild->hwndSelf, GA_PARENT );
while (parent && parent != GetDesktopWindow())
{
WND *wndParent = WIN_FindWndPtr( parent );
if (!(wndParent->dwStyle & WS_CLIPCHILDREN)) if (!(wndParent->dwStyle & WS_CLIPCHILDREN))
{ {
if (wndParent->hrgnUpdate != 0) if (wndParent->hrgnUpdate != 0)
...@@ -536,10 +529,10 @@ static void RDW_ValidateParent(WND *wndChild) ...@@ -536,10 +529,10 @@ static void RDW_ValidateParent(WND *wndChild)
OffsetRgn( hrg, -ptOffset.x, -ptOffset.y ); OffsetRgn( hrg, -ptOffset.x, -ptOffset.y );
} }
} }
WIN_UpdateWndPtr(&wndParent, wndParent->parent); WIN_ReleaseWndPtr( wndParent );
parent = GetAncestor( parent, GA_PARENT );
} }
if (hrg != wndChild->hrgnUpdate) DeleteObject( hrg ); if (hrg != wndChild->hrgnUpdate) DeleteObject( hrg );
WIN_ReleaseWndPtr(wndParent);
} }
/*********************************************************************** /***********************************************************************
...@@ -559,8 +552,8 @@ static void RDW_UpdateRgns( WND* wndPtr, HRGN hRgn, UINT flags, BOOL firstRecurs ...@@ -559,8 +552,8 @@ static void RDW_UpdateRgns( WND* wndPtr, HRGN hRgn, UINT flags, BOOL firstRecurs
*/ */
BOOL bHadOne = wndPtr->hrgnUpdate && hRgn; BOOL bHadOne = wndPtr->hrgnUpdate && hRgn;
BOOL bChildren = ( wndPtr->child && !(flags & RDW_NOCHILDREN) && !(wndPtr->dwStyle & WS_MINIMIZE) BOOL bChildren = (!(flags & RDW_NOCHILDREN) && !(wndPtr->dwStyle & WS_MINIMIZE) &&
&& ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) ); ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) );
RECT r; RECT r;
r.left = 0; r.left = 0;
...@@ -657,17 +650,20 @@ static void RDW_UpdateRgns( WND* wndPtr, HRGN hRgn, UINT flags, BOOL firstRecurs ...@@ -657,17 +650,20 @@ static void RDW_UpdateRgns( WND* wndPtr, HRGN hRgn, UINT flags, BOOL firstRecurs
if( flags & (RDW_INVALIDATE | RDW_VALIDATE) ) if( flags & (RDW_INVALIDATE | RDW_VALIDATE) )
{ {
if( hRgn > 1 && bChildren ) HWND *list;
if( hRgn > 1 && bChildren && (list = WIN_BuildWinArray( wndPtr->hwndSelf )))
{ {
WND* wnd = wndPtr->child;
POINT ptTotal, prevOrigin = {0,0}; POINT ptTotal, prevOrigin = {0,0};
POINT ptClient; POINT ptClient;
INT i;
ptClient.x = wndPtr->rectClient.left - wndPtr->rectWindow.left; ptClient.x = wndPtr->rectClient.left - wndPtr->rectWindow.left;
ptClient.y = wndPtr->rectClient.top - wndPtr->rectWindow.top; ptClient.y = wndPtr->rectClient.top - wndPtr->rectWindow.top;
for( ptTotal.x = ptTotal.y = 0; wnd; wnd = wnd->next ) for(i = ptTotal.x = ptTotal.y = 0; list[i]; i++)
{ {
WND *wnd = WIN_FindWndPtr( list[i] );
if (!wnd) continue;
if( wnd->dwStyle & WS_VISIBLE ) if( wnd->dwStyle & WS_VISIBLE )
{ {
POINT ptOffset; POINT ptOffset;
...@@ -691,7 +687,9 @@ static void RDW_UpdateRgns( WND* wndPtr, HRGN hRgn, UINT flags, BOOL firstRecurs ...@@ -691,7 +687,9 @@ static void RDW_UpdateRgns( WND* wndPtr, HRGN hRgn, UINT flags, BOOL firstRecurs
ptTotal.y += ptOffset.y; ptTotal.y += ptOffset.y;
} }
} }
WIN_ReleaseWndPtr( wnd );
} }
WIN_ReleaseWinArray( list );
OffsetRgn( hRgn, ptTotal.x, ptTotal.y ); OffsetRgn( hRgn, ptTotal.x, ptTotal.y );
bChildren = 0; bChildren = 0;
} }
...@@ -701,10 +699,20 @@ static void RDW_UpdateRgns( WND* wndPtr, HRGN hRgn, UINT flags, BOOL firstRecurs ...@@ -701,10 +699,20 @@ static void RDW_UpdateRgns( WND* wndPtr, HRGN hRgn, UINT flags, BOOL firstRecurs
if( bChildren ) if( bChildren )
{ {
WND* wnd; HWND *list;
for( wnd = wndPtr->child; wnd; wnd = wnd->next ) if ((list = WIN_BuildWinArray( wndPtr->hwndSelf )))
{
INT i;
for (i = 0; list[i]; i++)
{
WND *wnd = WIN_FindWndPtr( list[i] );
if (!wnd) continue;
if( wnd->dwStyle & WS_VISIBLE ) if( wnd->dwStyle & WS_VISIBLE )
RDW_UpdateRgns( wnd, hRgn, flags, FALSE ); RDW_UpdateRgns( wnd, hRgn, flags, FALSE );
WIN_ReleaseWndPtr( wnd );
}
WIN_ReleaseWinArray( list );
}
} }
end: end:
...@@ -762,7 +770,7 @@ static HRGN RDW_Paint( WND* wndPtr, HRGN hrgn, UINT flags, UINT ex ) ...@@ -762,7 +770,7 @@ static HRGN RDW_Paint( WND* wndPtr, HRGN hrgn, UINT flags, UINT ex )
* Check if this window should delay it's processing of WM_NCPAINT. * Check if this window should delay it's processing of WM_NCPAINT.
* See WIN_HaveToDelayNCPAINT for a description of the mechanism * See WIN_HaveToDelayNCPAINT for a description of the mechanism
*/ */
if ((ex & RDW_EX_DELAY_NCPAINT) || WIN_HaveToDelayNCPAINT(wndPtr, 0) ) if ((ex & RDW_EX_DELAY_NCPAINT) || WIN_HaveToDelayNCPAINT(wndPtr->hwndSelf, 0) )
ex |= RDW_EX_DELAY_NCPAINT; ex |= RDW_EX_DELAY_NCPAINT;
if (flags & RDW_UPDATENOW) if (flags & RDW_UPDATENOW)
...@@ -807,8 +815,8 @@ static HRGN RDW_Paint( WND* wndPtr, HRGN hrgn, UINT flags, UINT ex ) ...@@ -807,8 +815,8 @@ static HRGN RDW_Paint( WND* wndPtr, HRGN hrgn, UINT flags, UINT ex )
/* ... and its child windows */ /* ... and its child windows */
if( wndPtr->child && !(flags & RDW_NOCHILDREN) && !(wndPtr->dwStyle & WS_MINIMIZE) if(!(flags & RDW_NOCHILDREN) && !(wndPtr->dwStyle & WS_MINIMIZE) &&
&& ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) ) ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) )
{ {
HWND *list, *phwnd; HWND *list, *phwnd;
...@@ -1209,7 +1217,7 @@ INT WINAPI ExcludeUpdateRgn( HDC hdc, HWND hwnd ) ...@@ -1209,7 +1217,7 @@ INT WINAPI ExcludeUpdateRgn( HDC hdc, HWND hwnd )
/* do ugly coordinate translations in dce.c */ /* do ugly coordinate translations in dce.c */
ret = DCE_ExcludeRgn( hdc, wndPtr, hrgn ); ret = DCE_ExcludeRgn( hdc, hwnd, hrgn );
DeleteObject( hrgn ); DeleteObject( hrgn );
WIN_ReleaseWndPtr(wndPtr); WIN_ReleaseWndPtr(wndPtr);
return ret; return ret;
......
...@@ -187,13 +187,13 @@ void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore ) ...@@ -187,13 +187,13 @@ void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
*/ */
void WINAPI GetWindowRect16( HWND16 hwnd, LPRECT16 rect ) void WINAPI GetWindowRect16( HWND16 hwnd, LPRECT16 rect )
{ {
WND * wndPtr = WIN_FindWndPtr( hwnd ); RECT rect32;
if (!wndPtr) return;
CONV_RECT32TO16( &wndPtr->rectWindow, rect ); GetWindowRect( hwnd, &rect32 );
if (wndPtr->parent) rect->left = rect32.left;
MapWindowPoints16( wndPtr->parent->hwndSelf, 0, (POINT16 *)rect, 2 ); rect->top = rect32.top;
WIN_ReleaseWndPtr(wndPtr); rect->right = rect32.right;
rect->bottom = rect32.bottom;
} }
...@@ -204,11 +204,9 @@ BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect ) ...@@ -204,11 +204,9 @@ BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
{ {
WND * wndPtr = WIN_FindWndPtr( hwnd ); WND * wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return FALSE; if (!wndPtr) return FALSE;
*rect = wndPtr->rectWindow; *rect = wndPtr->rectWindow;
if (wndPtr->parent)
MapWindowPoints( wndPtr->parent->hwndSelf, 0, (POINT *)rect, 2 );
WIN_ReleaseWndPtr(wndPtr); WIN_ReleaseWndPtr(wndPtr);
MapWindowPoints( GetAncestor( hwnd, GA_PARENT ), 0, (POINT *)rect, 2 );
TRACE("hwnd %04x (%d,%d)-(%d,%d)\n", TRACE("hwnd %04x (%d,%d)-(%d,%d)\n",
hwnd, rect->left, rect->top, rect->right, rect->bottom); hwnd, rect->left, rect->top, rect->right, rect->bottom);
return TRUE; return TRUE;
...@@ -528,38 +526,7 @@ HWND16 WINAPI ChildWindowFromPoint16( HWND16 hwndParent, POINT16 pt ) ...@@ -528,38 +526,7 @@ HWND16 WINAPI ChildWindowFromPoint16( HWND16 hwndParent, POINT16 pt )
*/ */
HWND WINAPI ChildWindowFromPoint( HWND hwndParent, POINT pt ) HWND WINAPI ChildWindowFromPoint( HWND hwndParent, POINT pt )
{ {
/* pt is in the client coordinates */ return ChildWindowFromPointEx( hwndParent, pt, CWP_ALL );
WND* wnd = WIN_FindWndPtr(hwndParent);
RECT rect;
HWND retvalue;
if( !wnd ) return 0;
/* get client rect fast */
rect.top = rect.left = 0;
rect.right = wnd->rectClient.right - wnd->rectClient.left;
rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top;
if (!PtInRect( &rect, pt ))
{
retvalue = 0;
goto end;
}
WIN_UpdateWndPtr(&wnd,wnd->child);
while ( wnd )
{
if (PtInRect( &wnd->rectWindow, pt ))
{
retvalue = wnd->hwndSelf;
goto end;
}
WIN_UpdateWndPtr(&wnd,wnd->next);
}
retvalue = hwndParent;
end:
WIN_ReleaseWndPtr(wnd);
return retvalue;
} }
/******************************************************************* /*******************************************************************
...@@ -576,50 +543,36 @@ HWND16 WINAPI ChildWindowFromPointEx16( HWND16 hwndParent, POINT16 pt, UINT16 uF ...@@ -576,50 +543,36 @@ HWND16 WINAPI ChildWindowFromPointEx16( HWND16 hwndParent, POINT16 pt, UINT16 uF
/******************************************************************* /*******************************************************************
* ChildWindowFromPointEx (USER32.@) * ChildWindowFromPointEx (USER32.@)
*/ */
HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt, HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt, UINT uFlags)
UINT uFlags)
{ {
/* pt is in the client coordinates */ /* pt is in the client coordinates */
HWND *list;
WND* wnd = WIN_FindWndPtr(hwndParent); int i;
RECT rect; RECT rect;
HWND retvalue; HWND retvalue = 0;
if( !wnd ) return 0;
/* get client rect fast */ GetClientRect( hwndParent, &rect );
rect.top = rect.left = 0; if (!PtInRect( &rect, pt )) return 0;
rect.right = wnd->rectClient.right - wnd->rectClient.left; if (!(list = WIN_BuildWinArray( hwndParent ))) return 0;
rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top;
if (!PtInRect( &rect, pt )) for (i = 0; list[i] && !retvalue; i++)
{ {
retvalue = 0; WND *wnd = WIN_FindWndPtr( list[i] );
goto end; if (!wnd) continue;
} if (PtInRect( &wnd->rectWindow, pt ))
WIN_UpdateWndPtr(&wnd,wnd->child);
while ( wnd )
{ {
if (PtInRect( &wnd->rectWindow, pt )) {
if ( (uFlags & CWP_SKIPINVISIBLE) && if ( (uFlags & CWP_SKIPINVISIBLE) &&
!(wnd->dwStyle & WS_VISIBLE) ); !(wnd->dwStyle & WS_VISIBLE) );
else if ( (uFlags & CWP_SKIPDISABLED) && else if ( (uFlags & CWP_SKIPDISABLED) &&
(wnd->dwStyle & WS_DISABLED) ); (wnd->dwStyle & WS_DISABLED) );
else if ( (uFlags & CWP_SKIPTRANSPARENT) && else if ( (uFlags & CWP_SKIPTRANSPARENT) &&
(wnd->dwExStyle & WS_EX_TRANSPARENT) ); (wnd->dwExStyle & WS_EX_TRANSPARENT) );
else else retvalue = list[i];
{
retvalue = wnd->hwndSelf;
goto end;
}
} }
WIN_UpdateWndPtr(&wnd,wnd->next); WIN_ReleaseWndPtr( wnd );
} }
retvalue = hwndParent; WIN_ReleaseWinArray( list );
end: if (!retvalue) retvalue = hwndParent;
WIN_ReleaseWndPtr(wnd);
return retvalue; return retvalue;
} }
...@@ -787,11 +740,10 @@ HWND WINAPI GetActiveWindow(void) ...@@ -787,11 +740,10 @@ HWND WINAPI GetActiveWindow(void)
/******************************************************************* /*******************************************************************
* WINPOS_CanActivate * WINPOS_CanActivate
*/ */
static BOOL WINPOS_CanActivate(WND* pWnd) static BOOL WINPOS_CanActivate(HWND hwnd)
{ {
if( pWnd && ( (pWnd->dwStyle & (WS_DISABLED | WS_VISIBLE | WS_CHILD)) if (!hwnd) return FALSE;
== WS_VISIBLE ) ) return TRUE; return ((GetWindowLongW( hwnd, GWL_STYLE ) & (WS_DISABLED|WS_VISIBLE|WS_CHILD)) == WS_VISIBLE);
return FALSE;
} }
...@@ -1601,11 +1553,8 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus) ...@@ -1601,11 +1553,8 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
if (hWnd) if (hWnd)
{ {
/* walk up to the first unowned window */ /* walk up to the first unowned window */
wndTemp = WIN_LockWndPtr(wndPtr); HWND tmp = GetAncestor( hWnd, GA_ROOTOWNER );
while (wndTemp->owner) wndTemp = WIN_FindWndPtr( tmp );
{
WIN_UpdateWndPtr(&wndTemp,wndTemp->owner);
}
/* and set last active owned popup */ /* and set last active owned popup */
wndTemp->hwndLastActive = hWnd; wndTemp->hwndLastActive = hWnd;
...@@ -1625,7 +1574,7 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus) ...@@ -1625,7 +1574,7 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
{ {
HWND hOldFocus = PERQDATA_GetFocusWnd( pNewActiveQueue->pQData ); HWND hOldFocus = PERQDATA_GetFocusWnd( pNewActiveQueue->pQData );
if ( hOldFocus && WIN_GetTopParent( hOldFocus ) != hwndActive ) if ( hOldFocus && GetAncestor( hOldFocus, GA_ROOT ) != hwndActive )
FOCUS_SwitchFocus( pNewActiveQueue, hOldFocus, FOCUS_SwitchFocus( pNewActiveQueue, hOldFocus,
(wndPtr && (wndPtr->dwStyle & WS_MINIMIZE))? (wndPtr && (wndPtr->dwStyle & WS_MINIMIZE))?
0 : hwndActive ); 0 : hwndActive );
...@@ -1673,8 +1622,9 @@ CLEANUP_END: ...@@ -1673,8 +1622,9 @@ CLEANUP_END:
BOOL WINPOS_ActivateOtherWindow(HWND hwnd) BOOL WINPOS_ActivateOtherWindow(HWND hwnd)
{ {
BOOL bRet = 0; BOOL bRet = 0;
WND *pWnd, *pWndTo = NULL; WND *pWnd;
HWND hwndActive = 0; HWND hwndActive = 0;
HWND hwndTo = 0;
/* Get current active window from the active queue */ /* Get current active window from the active queue */
if ( hActiveQueue ) if ( hActiveQueue )
...@@ -1699,27 +1649,21 @@ BOOL WINPOS_ActivateOtherWindow(HWND hwnd) ...@@ -1699,27 +1649,21 @@ BOOL WINPOS_ActivateOtherWindow(HWND hwnd)
} }
if( !(pWnd->dwStyle & WS_POPUP) || !(pWnd->owner) || if( !(pWnd->dwStyle & WS_POPUP) || !(pWnd->owner) ||
!WINPOS_CanActivate((pWndTo = WIN_GetTopParentPtr(pWnd->owner))) ) !WINPOS_CanActivate((hwndTo = GetAncestor( pWnd->owner->hwndSelf, GA_ROOT ))) )
{ {
WND* pWndPtr = WIN_GetTopParentPtr(pWnd); HWND tmp = GetAncestor( pWnd->hwndSelf, GA_ROOT );
hwndTo = hwndPrevActive;
WIN_ReleaseWndPtr(pWndTo); while( !WINPOS_CanActivate(hwndTo) )
pWndTo = WIN_FindWndPtr(hwndPrevActive);
while( !WINPOS_CanActivate(pWndTo) )
{ {
/* by now owned windows should've been taken care of */ /* by now owned windows should've been taken care of */
WIN_UpdateWndPtr(&pWndTo,pWndPtr->next); tmp = hwndTo = GetWindow( tmp, GW_HWNDNEXT );
WIN_UpdateWndPtr(&pWndPtr,pWndTo); if( !hwndTo ) break;
if( !pWndTo ) break;
} }
WIN_ReleaseWndPtr(pWndPtr);
} }
WIN_ReleaseWndPtr( pWnd ); WIN_ReleaseWndPtr( pWnd );
bRet = WINPOS_SetActiveWindow( pWndTo ? pWndTo->hwndSelf : 0, FALSE, TRUE ); bRet = WINPOS_SetActiveWindow( hwndTo, FALSE, TRUE );
if( pWndTo ) WIN_ReleaseWndPtr(pWndTo);
hwndPrevActive = 0; hwndPrevActive = 0;
return bRet; return bRet;
......
...@@ -353,7 +353,7 @@ int X11DRV_CLIPBOARD_CacheDataFormats( Atom SelectionName ) ...@@ -353,7 +353,7 @@ int X11DRV_CLIPBOARD_CacheDataFormats( Atom SelectionName )
/* /*
* Query the selection owner for the TARGETS property * Query the selection owner for the TARGETS property
*/ */
w = X11DRV_get_top_window(hWnd); w = X11DRV_get_whole_window( GetAncestor(hWnd,GA_ROOT) );
aTargets = TSXInternAtom(display, "TARGETS", False); aTargets = TSXInternAtom(display, "TARGETS", False);
...@@ -892,7 +892,8 @@ void X11DRV_AcquireClipboard(void) ...@@ -892,7 +892,8 @@ void X11DRV_AcquireClipboard(void)
if ( !(selectionAcquired == (S_PRIMARY | S_CLIPBOARD)) ) if ( !(selectionAcquired == (S_PRIMARY | S_CLIPBOARD)) )
{ {
Atom xaClipboard = TSXInternAtom(display, _CLIPBOARD, False); Atom xaClipboard = TSXInternAtom(display, _CLIPBOARD, False);
owner = X11DRV_get_top_window( hWndClipWindow ? hWndClipWindow : AnyPopup() ); owner = X11DRV_get_whole_window( GetAncestor( hWndClipWindow ? hWndClipWindow : AnyPopup(),
GA_ROOT ) );
/* Grab PRIMARY selection if not owned */ /* Grab PRIMARY selection if not owned */
if ( !(selectionAcquired & S_PRIMARY) ) if ( !(selectionAcquired & S_PRIMARY) )
...@@ -1047,7 +1048,7 @@ BOOL X11DRV_GetClipboardData(UINT wFormat) ...@@ -1047,7 +1048,7 @@ BOOL X11DRV_GetClipboardData(UINT wFormat)
{ {
XEvent xe; XEvent xe;
Atom propRequest; Atom propRequest;
Window w = X11DRV_get_top_window(hWnd); Window w = X11DRV_get_whole_window( GetAncestor( hWnd, GA_ROOT ));
/* Map the format ID requested to an X selection property. /* Map the format ID requested to an X selection property.
* If the format is in the cache, use the atom associated * If the format is in the cache, use the atom associated
......
...@@ -386,16 +386,15 @@ static void get_coords( HWND *hwnd, Window window, int x, int y, POINT *pt ) ...@@ -386,16 +386,15 @@ static void get_coords( HWND *hwnd, Window window, int x, int y, POINT *pt )
x -= data->client_rect.left; x -= data->client_rect.left;
y -= data->client_rect.top; y -= data->client_rect.top;
} }
while (win->parent && win->parent->hwndSelf != GetDesktopWindow()) WIN_ReleaseWndPtr( win );
pt->x = x;
pt->y = y;
if (*hwnd != GetDesktopWindow())
{ {
x += win->rectClient.left; ClientToScreen( *hwnd, pt );
y += win->rectClient.top; *hwnd = GetAncestor( *hwnd, GA_ROOT );
WIN_UpdateWndPtr( &win, win->parent );
} }
pt->x = x + win->rectClient.left;
pt->y = y + win->rectClient.top;
*hwnd = win->hwndSelf;
WIN_ReleaseWndPtr( win );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment