Store window parent as an HWND instead of a pointer.
This commit is contained in:
parent
9e1fc62651
commit
556607a147
|
@ -127,7 +127,7 @@ static BOOL DCE_GetVisRect( WND *wndPtr, BOOL clientArea, RECT *lprect )
|
|||
INT xoffset = lprect->left;
|
||||
INT yoffset = lprect->top;
|
||||
|
||||
while ((wndPtr = WIN_LockWndPtr(wndPtr->parent)))
|
||||
while ((wndPtr = WIN_FindWndPtr( GetAncestor(wndPtr->hwndSelf,GA_PARENT) )))
|
||||
{
|
||||
if ( (wndPtr->dwStyle & (WS_ICONIC | WS_VISIBLE)) != WS_VISIBLE )
|
||||
{
|
||||
|
@ -175,27 +175,28 @@ fail:
|
|||
* adding to the clip region the intersection of the target rectangle
|
||||
* with an offset window rectangle.
|
||||
*/
|
||||
static BOOL DCE_AddClipRects( WND *pWndStart, WND *pWndEnd,
|
||||
HRGN hrgnClip, LPRECT lpRect, int x, int y )
|
||||
static BOOL DCE_AddClipRects( HWND start, HWND end, HRGN hrgnClip, LPRECT lpRect, int x, int y )
|
||||
{
|
||||
RECT rect;
|
||||
WND *pWnd;
|
||||
|
||||
for (WIN_LockWndPtr(pWndStart); (pWndStart && (pWndStart != pWndEnd)); WIN_UpdateWndPtr(&pWndStart,pWndStart->next))
|
||||
for (pWnd = WIN_FindWndPtr(start); (pWnd && (pWnd->hwndSelf != end)); WIN_UpdateWndPtr(&pWnd,pWnd->next))
|
||||
{
|
||||
if( !(pWndStart->dwStyle & WS_VISIBLE) ) continue;
|
||||
if( !(pWnd->dwStyle & WS_VISIBLE) ) continue;
|
||||
|
||||
rect.left = pWndStart->rectWindow.left + x;
|
||||
rect.top = pWndStart->rectWindow.top + y;
|
||||
rect.right = pWndStart->rectWindow.right + x;
|
||||
rect.bottom = pWndStart->rectWindow.bottom + y;
|
||||
rect.left = pWnd->rectWindow.left + x;
|
||||
rect.top = pWnd->rectWindow.top + y;
|
||||
rect.right = pWnd->rectWindow.right + x;
|
||||
rect.bottom = pWnd->rectWindow.bottom + y;
|
||||
|
||||
if( IntersectRect( &rect, &rect, lpRect ))
|
||||
{
|
||||
if(!REGION_UnionRectWithRgn( hrgnClip, &rect )) break;
|
||||
}
|
||||
}
|
||||
WIN_ReleaseWndPtr(pWndStart);
|
||||
return (pWndStart == pWndEnd);
|
||||
start = pWnd->hwndSelf;
|
||||
WIN_ReleaseWndPtr(pWnd);
|
||||
return (start == end);
|
||||
}
|
||||
|
||||
|
||||
|
@ -242,7 +243,7 @@ static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
|
|||
else
|
||||
xoffset = yoffset = 0;
|
||||
|
||||
DCE_AddClipRects( wndPtr->child, NULL, hrgnClip, &rect, xoffset, yoffset );
|
||||
DCE_AddClipRects( wndPtr->child->hwndSelf, 0, hrgnClip, &rect, xoffset, yoffset );
|
||||
}
|
||||
|
||||
/* We may need to clip children of child window, if a window with PARENTDC
|
||||
|
@ -267,7 +268,7 @@ static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
|
|||
xoffset += childWnd->rectClient.left;
|
||||
yoffset += childWnd->rectClient.top;
|
||||
|
||||
DCE_AddClipRects( childWnd->child, NULL, hrgnClip,
|
||||
DCE_AddClipRects( childWnd->child->hwndSelf, 0, hrgnClip,
|
||||
&rect, xoffset, yoffset );
|
||||
}
|
||||
|
||||
|
@ -286,8 +287,8 @@ static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
|
|||
}
|
||||
|
||||
if (flags & DCX_CLIPSIBLINGS && wndPtr->parent )
|
||||
DCE_AddClipRects( wndPtr->parent->child,
|
||||
wndPtr, hrgnClip, &rect, xoffset, yoffset );
|
||||
DCE_AddClipRects( GetWindow( wndPtr->hwndSelf, GW_HWNDFIRST ),
|
||||
wndPtr->hwndSelf, hrgnClip, &rect, xoffset, yoffset );
|
||||
|
||||
/* Clip siblings of all ancestors that have the
|
||||
* WS_CLIPSIBLINGS style
|
||||
|
@ -295,13 +296,15 @@ static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
|
|||
|
||||
while (wndPtr->parent)
|
||||
{
|
||||
WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
|
||||
WND *ptr = WIN_FindWndPtr( wndPtr->parent );
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
wndPtr = ptr;
|
||||
xoffset -= wndPtr->rectClient.left;
|
||||
yoffset -= wndPtr->rectClient.top;
|
||||
if(wndPtr->dwStyle & WS_CLIPSIBLINGS && wndPtr->parent)
|
||||
{
|
||||
DCE_AddClipRects( wndPtr->parent->child, wndPtr,
|
||||
hrgnClip, &rect, xoffset, yoffset );
|
||||
DCE_AddClipRects( GetWindow( wndPtr->hwndSelf, GW_HWNDFIRST ),
|
||||
wndPtr->hwndSelf, hrgnClip, &rect, xoffset, yoffset );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -364,7 +367,7 @@ BOOL TTYDRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
|
|||
{
|
||||
if (flags & DCX_PARENTCLIP)
|
||||
{
|
||||
WND *parentPtr = WIN_LockWndPtr(wndPtr->parent);
|
||||
WND *parentPtr = WIN_FindWndPtr( wndPtr->parent );
|
||||
|
||||
if( wndPtr->dwStyle & WS_VISIBLE && !(parentPtr->dwStyle & WS_MINIMIZE) )
|
||||
{
|
||||
|
@ -534,7 +537,10 @@ BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos )
|
|||
}
|
||||
|
||||
if( winpos->hwndInsertAfter == HWND_TOP )
|
||||
winpos->flags |= ( wndPtr->parent->child == wndPtr)? SWP_NOZORDER: 0;
|
||||
{
|
||||
if (GetWindow( wndPtr->hwndSelf, GW_HWNDFIRST ) == wndPtr->hwndSelf)
|
||||
winpos->flags |= SWP_NOZORDER;
|
||||
}
|
||||
else
|
||||
if( winpos->hwndInsertAfter == HWND_BOTTOM )
|
||||
winpos->flags |= ( wndPtr->next )? 0: SWP_NOZORDER;
|
||||
|
@ -583,14 +589,11 @@ BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos )
|
|||
|
||||
if( !(winpos->flags & SWP_NOREDRAW) )
|
||||
{
|
||||
RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0,
|
||||
RedrawWindow( wndPtr->parent, NULL, 0,
|
||||
RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN );
|
||||
if (wndPtr->parent->hwndSelf == GetDesktopWindow() ||
|
||||
wndPtr->parent->parent->hwndSelf == GetDesktopWindow())
|
||||
{
|
||||
RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0,
|
||||
if (wndPtr->parent == GetDesktopWindow())
|
||||
RedrawWindow( wndPtr->parent, NULL, 0,
|
||||
RDW_ERASENOW | RDW_NOCHILDREN );
|
||||
}
|
||||
}
|
||||
|
||||
if (!(winpos->flags & SWP_NOACTIVATE))
|
||||
|
|
|
@ -76,8 +76,7 @@ inline static BOOL is_window_managed( WND *win )
|
|||
*/
|
||||
inline static BOOL is_window_top_level( WND *win )
|
||||
{
|
||||
return (root_window == DefaultRootWindow(gdi_display) &&
|
||||
win->parent->hwndSelf == GetDesktopWindow());
|
||||
return (root_window == DefaultRootWindow(gdi_display) && win->parent == GetDesktopWindow());
|
||||
}
|
||||
|
||||
|
||||
|
@ -633,7 +632,7 @@ static Window create_whole_window( Display *display, WND *win )
|
|||
if (!(cx = rect.right - rect.left)) cx = 1;
|
||||
if (!(cy = rect.bottom - rect.top)) cy = 1;
|
||||
|
||||
parent = get_client_window( win->parent );
|
||||
parent = X11DRV_get_client_window( win->parent );
|
||||
|
||||
wine_tsx11_lock();
|
||||
|
||||
|
@ -887,9 +886,9 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
|
|||
(unsigned int)data->whole_window, (unsigned int)data->client_window );
|
||||
|
||||
if ((wndPtr->dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
|
||||
WIN_LinkWindow( hwnd, wndPtr->parent->hwndSelf, HWND_BOTTOM );
|
||||
WIN_LinkWindow( hwnd, wndPtr->parent, HWND_BOTTOM );
|
||||
else
|
||||
WIN_LinkWindow( hwnd, wndPtr->parent->hwndSelf, HWND_TOP );
|
||||
WIN_LinkWindow( hwnd, wndPtr->parent, HWND_TOP );
|
||||
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
|
||||
|
@ -1009,7 +1008,7 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent )
|
|||
* including the WM_SHOWWINDOW messages and all */
|
||||
if (dwStyle & WS_VISIBLE) ShowWindow( hwnd, SW_HIDE );
|
||||
|
||||
retvalue = wndPtr->parent->hwndSelf; /* old parent */
|
||||
retvalue = wndPtr->parent; /* old parent */
|
||||
if (parent != retvalue)
|
||||
{
|
||||
struct x11drv_win_data *data = wndPtr->pDriverData;
|
||||
|
|
|
@ -59,37 +59,48 @@ DEFAULT_DEBUG_CHANNEL(x11drv);
|
|||
*
|
||||
* Clip all children of a given window out of the visible region
|
||||
*/
|
||||
static int clip_children( WND *win, WND *last, HRGN hrgn, int whole_window )
|
||||
static int clip_children( HWND parent, HWND last, HRGN hrgn, int whole_window )
|
||||
{
|
||||
HWND *list;
|
||||
WND *ptr;
|
||||
HRGN rectRgn;
|
||||
int x, y, ret = SIMPLEREGION;
|
||||
int i, x, y, ret = SIMPLEREGION;
|
||||
|
||||
/* first check if we have anything to do */
|
||||
for (ptr = win->child; ptr && ptr != last; ptr = ptr->next)
|
||||
if (ptr->dwStyle & WS_VISIBLE) break;
|
||||
if (!ptr || ptr == last) return ret; /* no children to clip */
|
||||
if (!(list = WIN_ListChildren( parent ))) return ret;
|
||||
for (i = 0; list[i] && list[i] != last; i++)
|
||||
if (GetWindowLongW( list[i], GWL_STYLE ) & WS_VISIBLE) break;
|
||||
if (!list[i] || list[i] == last) goto done; /* no children to clip */
|
||||
|
||||
if (whole_window)
|
||||
{
|
||||
WND *win = WIN_FindWndPtr( parent );
|
||||
x = win->rectWindow.left - win->rectClient.left;
|
||||
y = win->rectWindow.top - win->rectClient.top;
|
||||
WIN_ReleaseWndPtr( win );
|
||||
}
|
||||
else x = y = 0;
|
||||
|
||||
rectRgn = CreateRectRgn( 0, 0, 0, 0 );
|
||||
while (ptr && ptr != last)
|
||||
|
||||
for ( ; list[i] && list[i] != last; i++)
|
||||
{
|
||||
if (!(ptr = WIN_FindWndPtr( list[i] ))) continue;
|
||||
if (ptr->dwStyle & WS_VISIBLE)
|
||||
{
|
||||
SetRectRgn( rectRgn, ptr->rectWindow.left + x, ptr->rectWindow.top + y,
|
||||
ptr->rectWindow.right + x, ptr->rectWindow.bottom + y );
|
||||
if ((ret = CombineRgn( hrgn, hrgn, rectRgn, RGN_DIFF )) == NULLREGION)
|
||||
{
|
||||
WIN_ReleaseWndPtr( ptr );
|
||||
break; /* no need to go on, region is empty */
|
||||
}
|
||||
}
|
||||
ptr = ptr->next;
|
||||
WIN_ReleaseWndPtr( ptr );
|
||||
}
|
||||
DeleteObject( rectRgn );
|
||||
done:
|
||||
HeapFree( GetProcessHeap(), 0, list );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -99,7 +110,7 @@ static int clip_children( WND *win, WND *last, HRGN hrgn, int whole_window )
|
|||
*
|
||||
* Compute the visible region of a window
|
||||
*/
|
||||
static HRGN get_visible_region( WND *win, WND *top, UINT flags, int mode )
|
||||
static HRGN get_visible_region( WND *win, HWND top, UINT flags, int mode )
|
||||
{
|
||||
HRGN rgn;
|
||||
RECT rect;
|
||||
|
@ -118,7 +129,7 @@ static HRGN get_visible_region( WND *win, WND *top, UINT flags, int mode )
|
|||
}
|
||||
|
||||
if (flags & DCX_PARENTCLIP)
|
||||
GetClientRect( win->parent->hwndSelf, &rect );
|
||||
GetClientRect( win->parent, &rect );
|
||||
else if (flags & DCX_WINDOW)
|
||||
rect = data->whole_rect;
|
||||
else
|
||||
|
@ -132,12 +143,12 @@ static HRGN get_visible_region( WND *win, WND *top, UINT flags, int mode )
|
|||
if ((flags & DCX_CLIPCHILDREN) && (mode != ClipByChildren))
|
||||
{
|
||||
/* we need to clip children by hand */
|
||||
if (clip_children( win, NULL, rgn, (flags & DCX_WINDOW) ) == NULLREGION) return rgn;
|
||||
if (clip_children( win->hwndSelf, 0, rgn, (flags & DCX_WINDOW) ) == NULLREGION) return rgn;
|
||||
}
|
||||
|
||||
if (top && top != win) /* need to clip siblings of ancestors */
|
||||
if (top && top != win->hwndSelf) /* need to clip siblings of ancestors */
|
||||
{
|
||||
WND *ptr = win;
|
||||
WND *parent, *ptr = WIN_LockWndPtr( win );
|
||||
HRGN tmp = 0;
|
||||
|
||||
OffsetRgn( rgn, xoffset, yoffset );
|
||||
|
@ -145,10 +156,12 @@ static HRGN get_visible_region( WND *win, WND *top, UINT flags, int mode )
|
|||
{
|
||||
if (ptr->dwStyle & WS_CLIPSIBLINGS)
|
||||
{
|
||||
if (clip_children( ptr->parent, ptr, rgn, FALSE ) == NULLREGION) break;
|
||||
if (clip_children( ptr->parent, ptr->hwndSelf, rgn, FALSE ) == NULLREGION) break;
|
||||
}
|
||||
if (ptr == top) break;
|
||||
ptr = ptr->parent;
|
||||
if (ptr->hwndSelf == top) break;
|
||||
if (!(parent = WIN_FindWndPtr( ptr->parent ))) break;
|
||||
WIN_ReleaseWndPtr( ptr );
|
||||
ptr = parent;
|
||||
/* clip to parent client area */
|
||||
if (tmp) SetRectRgn( tmp, 0, 0, ptr->rectClient.right - ptr->rectClient.left,
|
||||
ptr->rectClient.bottom - ptr->rectClient.top );
|
||||
|
@ -159,6 +172,7 @@ static HRGN get_visible_region( WND *win, WND *top, UINT flags, int mode )
|
|||
xoffset += ptr->rectClient.left;
|
||||
yoffset += ptr->rectClient.top;
|
||||
}
|
||||
WIN_ReleaseWndPtr( ptr );
|
||||
/* make it relative to the target window again */
|
||||
OffsetRgn( rgn, -xoffset, -yoffset );
|
||||
if (tmp) DeleteObject( tmp );
|
||||
|
@ -180,7 +194,7 @@ static int get_covered_region( WND *win, HRGN rgn )
|
|||
{
|
||||
HRGN tmp;
|
||||
int ret;
|
||||
WND *ptr = win;
|
||||
WND *parent, *ptr = WIN_LockWndPtr( win );
|
||||
int xoffset = 0, yoffset = 0;
|
||||
|
||||
tmp = CreateRectRgn( 0, 0, 0, 0 );
|
||||
|
@ -193,13 +207,16 @@ static int get_covered_region( WND *win, HRGN rgn )
|
|||
{
|
||||
if (!(ptr->dwStyle & WS_CLIPSIBLINGS))
|
||||
{
|
||||
if (clip_children( ptr->parent, ptr, tmp, FALSE ) == NULLREGION) break;
|
||||
if (clip_children( ptr->parent, ptr->hwndSelf, tmp, FALSE ) == NULLREGION) break;
|
||||
}
|
||||
if (!(ptr = ptr->parent)) break;
|
||||
if (!(parent = WIN_FindWndPtr( ptr->parent ))) break;
|
||||
WIN_ReleaseWndPtr( ptr );
|
||||
ptr = parent;
|
||||
OffsetRgn( tmp, ptr->rectClient.left, ptr->rectClient.top );
|
||||
xoffset += ptr->rectClient.left;
|
||||
yoffset += ptr->rectClient.top;
|
||||
}
|
||||
WIN_ReleaseWndPtr( ptr );
|
||||
/* make it relative to the target window again */
|
||||
OffsetRgn( tmp, -xoffset, -yoffset );
|
||||
|
||||
|
@ -215,44 +232,58 @@ static int get_covered_region( WND *win, HRGN rgn )
|
|||
*
|
||||
* Expose a region of a given window.
|
||||
*/
|
||||
static void expose_window( WND *win, RECT *rect, HRGN rgn, int flags )
|
||||
static void expose_window( HWND hwnd, RECT *rect, HRGN rgn, int flags )
|
||||
{
|
||||
WND *ptr, *top;
|
||||
int xoffset = 0, yoffset = 0;
|
||||
POINT offset;
|
||||
HWND top = 0;
|
||||
HWND *list;
|
||||
int i;
|
||||
|
||||
/* find the top most parent that doesn't clip children or siblings and
|
||||
* invalidate the area on its parent, including all children */
|
||||
top = NULL;
|
||||
for (ptr = win; ptr && ptr->parent; ptr = ptr->parent)
|
||||
if ((list = WIN_ListParents( hwnd )))
|
||||
{
|
||||
if (!(ptr->dwStyle & WS_CLIPSIBLINGS)) top = ptr;
|
||||
if (!(ptr->parent->dwStyle & WS_CLIPCHILDREN)) top = ptr;
|
||||
HWND current = hwnd;
|
||||
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
||||
for (i = 0; list[i] && list[i] != GetDesktopWindow(); i++)
|
||||
{
|
||||
if (!(style & WS_CLIPSIBLINGS)) top = current;
|
||||
style = GetWindowLongW( list[i], GWL_STYLE );
|
||||
if (!(style & WS_CLIPCHILDREN)) top = current;
|
||||
current = list[i];
|
||||
}
|
||||
|
||||
if (top)
|
||||
{
|
||||
/* find the parent of the top window, reusing the parent list */
|
||||
if (top == hwnd) i = 0;
|
||||
else
|
||||
{
|
||||
for (i = 0; list[i]; i++) if (list[i] == top) break;
|
||||
if (list[i] && list[i+1]) i++;
|
||||
}
|
||||
if (list[i] != GetDesktopWindow()) top = list[i];
|
||||
flags &= ~RDW_FRAME; /* parent will invalidate children frame anyway */
|
||||
flags |= RDW_ALLCHILDREN;
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, list );
|
||||
}
|
||||
|
||||
if (top)
|
||||
{
|
||||
if (top->parent && top->parent->hwndSelf != GetDesktopWindow()) top = top->parent;
|
||||
flags &= ~RDW_FRAME; /* parent will invalidate children frame anyway */
|
||||
flags |= RDW_ALLCHILDREN;
|
||||
}
|
||||
else top = win;
|
||||
if (!top) top = hwnd;
|
||||
|
||||
/* make coords relative to top */
|
||||
for (ptr = win; ptr != top; ptr = ptr->parent)
|
||||
{
|
||||
xoffset += ptr->rectClient.left;
|
||||
yoffset += ptr->rectClient.top;
|
||||
}
|
||||
offset.x = offset.y = 0;
|
||||
MapWindowPoints( hwnd, top, &offset, 1 );
|
||||
|
||||
if (rect)
|
||||
{
|
||||
OffsetRect( rect, xoffset, yoffset );
|
||||
RedrawWindow( top->hwndSelf, rect, 0, flags );
|
||||
OffsetRect( rect, offset.x, offset.y );
|
||||
RedrawWindow( top, rect, 0, flags );
|
||||
}
|
||||
else
|
||||
{
|
||||
OffsetRgn( rgn, xoffset, yoffset );
|
||||
RedrawWindow( top->hwndSelf, NULL, rgn, flags );
|
||||
OffsetRgn( rgn, offset.x, offset.y );
|
||||
RedrawWindow( top, NULL, rgn, flags );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,7 +358,7 @@ static void expose_covered_window_area( WND *win, const RECT *old_client_rect, B
|
|||
if (ret != NULLREGION)
|
||||
{
|
||||
if (get_covered_region( win, hrgn ) != NULLREGION)
|
||||
expose_window( win, NULL, hrgn,
|
||||
expose_window( win->hwndSelf, NULL, hrgn,
|
||||
RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN );
|
||||
}
|
||||
|
||||
|
@ -362,9 +393,9 @@ void X11DRV_Expose( HWND hwnd, XExposeEvent *event )
|
|||
/* make position relative to client area instead of window */
|
||||
OffsetRect( &rect, -data->client_rect.left, -data->client_rect.top );
|
||||
}
|
||||
|
||||
expose_window( win, &rect, 0, flags );
|
||||
WIN_ReleaseWndPtr( win );
|
||||
|
||||
expose_window( hwnd, &rect, 0, flags );
|
||||
}
|
||||
|
||||
|
||||
|
@ -377,49 +408,53 @@ void X11DRV_Expose( HWND hwnd, XExposeEvent *event )
|
|||
BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
|
||||
{
|
||||
WND *win = WIN_FindWndPtr( hwnd );
|
||||
WND *ptr, *top;
|
||||
HWND top = 0;
|
||||
X11DRV_WND_DATA *data = win->pDriverData;
|
||||
Drawable drawable;
|
||||
BOOL visible;
|
||||
int org_x, org_y, mode = IncludeInferiors;
|
||||
POINT org;
|
||||
int mode = IncludeInferiors;
|
||||
|
||||
/* don't clip siblings if using parent clip region */
|
||||
if (flags & DCX_PARENTCLIP) flags &= ~DCX_CLIPSIBLINGS;
|
||||
|
||||
/* find the top parent in the hierarchy that isn't clipping siblings */
|
||||
top = NULL;
|
||||
visible = (win->dwStyle & WS_VISIBLE) != 0;
|
||||
|
||||
if (visible)
|
||||
{
|
||||
for (ptr = win->parent; ptr && ptr->parent; ptr = ptr->parent)
|
||||
HWND *list = WIN_ListParents( hwnd );
|
||||
if (list)
|
||||
{
|
||||
if (!(ptr->dwStyle & WS_VISIBLE))
|
||||
int i;
|
||||
for (i = 0; list[i] != GetDesktopWindow(); i++)
|
||||
{
|
||||
visible = FALSE;
|
||||
top = NULL;
|
||||
break;
|
||||
LONG style = GetWindowLongW( list[i], GWL_STYLE );
|
||||
if (!(style & WS_VISIBLE))
|
||||
{
|
||||
visible = FALSE;
|
||||
top = 0;
|
||||
break;
|
||||
}
|
||||
if (!(style & WS_CLIPSIBLINGS)) top = list[i];
|
||||
}
|
||||
if (!(ptr->dwStyle & WS_CLIPSIBLINGS)) top = ptr;
|
||||
HeapFree( GetProcessHeap(), 0, list );
|
||||
}
|
||||
if (!top && visible && !(flags & DCX_CLIPSIBLINGS)) top = win;
|
||||
if (!top && visible && !(flags & DCX_CLIPSIBLINGS)) top = hwnd;
|
||||
}
|
||||
|
||||
if (top)
|
||||
{
|
||||
org_x = org_y = 0;
|
||||
HWND parent = GetAncestor( top, GA_PARENT );
|
||||
org.x = org.y = 0;
|
||||
if (flags & DCX_WINDOW)
|
||||
{
|
||||
org_x = win->rectWindow.left - win->rectClient.left;
|
||||
org_y = win->rectWindow.top - win->rectClient.top;
|
||||
}
|
||||
for (ptr = win; ptr != top->parent; ptr = ptr->parent)
|
||||
{
|
||||
org_x += ptr->rectClient.left;
|
||||
org_y += ptr->rectClient.top;
|
||||
org.x = win->rectWindow.left - win->rectClient.left;
|
||||
org.y = win->rectWindow.top - win->rectClient.top;
|
||||
}
|
||||
MapWindowPoints( hwnd, parent, &org, 1 );
|
||||
/* have to use the parent so that we include siblings */
|
||||
if (top->parent) drawable = get_client_window( top->parent );
|
||||
if (parent) drawable = X11DRV_get_client_window( parent );
|
||||
else drawable = root_window;
|
||||
}
|
||||
else
|
||||
|
@ -427,25 +462,25 @@ BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
|
|||
if (IsIconic( hwnd ))
|
||||
{
|
||||
drawable = data->icon_window ? data->icon_window : data->whole_window;
|
||||
org_x = 0;
|
||||
org_y = 0;
|
||||
org.x = 0;
|
||||
org.y = 0;
|
||||
}
|
||||
else if (flags & DCX_WINDOW)
|
||||
{
|
||||
drawable = data->whole_window;
|
||||
org_x = win->rectWindow.left - data->whole_rect.left;
|
||||
org_y = win->rectWindow.top - data->whole_rect.top;
|
||||
org.x = win->rectWindow.left - data->whole_rect.left;
|
||||
org.y = win->rectWindow.top - data->whole_rect.top;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawable = data->client_window;
|
||||
org_x = 0;
|
||||
org_y = 0;
|
||||
org.x = 0;
|
||||
org.y = 0;
|
||||
if (flags & DCX_CLIPCHILDREN) mode = ClipByChildren; /* can use X11 clipping */
|
||||
}
|
||||
}
|
||||
|
||||
X11DRV_SetDrawable( hdc, drawable, mode, org_x, org_y );
|
||||
X11DRV_SetDrawable( hdc, drawable, mode, org.x, org.y );
|
||||
|
||||
if (flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN) ||
|
||||
SetHookFlags16( hdc, DCHF_VALIDATEVISRGN )) /* DC was dirty */
|
||||
|
@ -462,7 +497,7 @@ BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
|
|||
(flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
|
||||
|
||||
/* make it relative to the drawable origin */
|
||||
OffsetRgn( visRgn, org_x, org_y );
|
||||
OffsetRgn( visRgn, org.x, org.y );
|
||||
}
|
||||
else visRgn = CreateRectRgn( 0, 0, 0, 0 );
|
||||
|
||||
|
@ -893,9 +928,10 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
|
|||
static POINT WINPOS_FindIconPos( WND* wndPtr, POINT pt )
|
||||
{
|
||||
RECT rectParent;
|
||||
HWND *list;
|
||||
short x, y, xspacing, yspacing;
|
||||
|
||||
GetClientRect( wndPtr->parent->hwndSelf, &rectParent );
|
||||
GetClientRect( wndPtr->parent, &rectParent );
|
||||
if ((pt.x >= rectParent.left) && (pt.x + GetSystemMetrics(SM_CXICON) < rectParent.right) &&
|
||||
(pt.y >= rectParent.top) && (pt.y + GetSystemMetrics(SM_CYICON) < rectParent.bottom))
|
||||
return pt; /* The icon already has a suitable position */
|
||||
|
@ -903,34 +939,48 @@ static POINT WINPOS_FindIconPos( WND* wndPtr, POINT pt )
|
|||
xspacing = GetSystemMetrics(SM_CXICONSPACING);
|
||||
yspacing = GetSystemMetrics(SM_CYICONSPACING);
|
||||
|
||||
list = WIN_ListChildren( wndPtr->parent );
|
||||
y = rectParent.bottom;
|
||||
for (;;)
|
||||
{
|
||||
x = rectParent.left;
|
||||
do
|
||||
{
|
||||
/* Check if another icon already occupies this spot */
|
||||
WND *childPtr = WIN_LockWndPtr(wndPtr->parent->child);
|
||||
while (childPtr)
|
||||
/* Check if another icon already occupies this spot */
|
||||
/* FIXME: this is completely inefficient */
|
||||
if (list)
|
||||
{
|
||||
if ((childPtr->dwStyle & WS_MINIMIZE) && (childPtr != wndPtr))
|
||||
int i;
|
||||
WND *childPtr;
|
||||
|
||||
for (i = 0; list[i]; i++)
|
||||
{
|
||||
if (list[i] == wndPtr->hwndSelf) continue;
|
||||
if (!IsIconic( list[i] )) continue;
|
||||
if (!(childPtr = WIN_FindWndPtr( list[i] ))) continue;
|
||||
if ((childPtr->rectWindow.left < x + xspacing) &&
|
||||
(childPtr->rectWindow.right >= x) &&
|
||||
(childPtr->rectWindow.top <= y) &&
|
||||
(childPtr->rectWindow.bottom > y - yspacing))
|
||||
{
|
||||
WIN_ReleaseWndPtr( childPtr );
|
||||
break; /* There's a window in there */
|
||||
}
|
||||
WIN_ReleaseWndPtr( childPtr );
|
||||
}
|
||||
if (list[i])
|
||||
{
|
||||
/* found something here, try next spot */
|
||||
x += xspacing;
|
||||
continue;
|
||||
}
|
||||
WIN_UpdateWndPtr(&childPtr,childPtr->next);
|
||||
}
|
||||
WIN_ReleaseWndPtr(childPtr);
|
||||
if (!childPtr) /* No window was found, so it's OK for us */
|
||||
{
|
||||
pt.x = x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2;
|
||||
pt.y = y - (yspacing + GetSystemMetrics(SM_CYICON)) / 2;
|
||||
return pt;
|
||||
}
|
||||
x += xspacing;
|
||||
|
||||
/* No window was found, so it's OK for us */
|
||||
pt.x = x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2;
|
||||
pt.y = y - (yspacing + GetSystemMetrics(SM_CYICON)) / 2;
|
||||
return pt;
|
||||
|
||||
} while(x <= rectParent.right-xspacing);
|
||||
y -= yspacing;
|
||||
}
|
||||
|
@ -1990,35 +2040,42 @@ void X11DRV_SysCommandSizeMove( HWND hwnd, WPARAM wParam )
|
|||
*/
|
||||
void X11DRV_ForceWindowRaise( HWND hwnd )
|
||||
{
|
||||
int i = 0;
|
||||
HWND *list;
|
||||
XWindowChanges winChanges;
|
||||
Display *display = thread_display();
|
||||
WND *wndPrev, *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
|
||||
if (!wndPtr) return;
|
||||
|
||||
if ((wndPtr->dwExStyle & WS_EX_MANAGED) ||
|
||||
wndPtr->parent->hwndSelf != GetDesktopWindow() ||
|
||||
wndPtr->parent != GetDesktopWindow() ||
|
||||
IsRectEmpty( &wndPtr->rectWindow ) ||
|
||||
!get_whole_window(wndPtr))
|
||||
{
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return;
|
||||
}
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
|
||||
/* Raise all windows up to wndPtr according to their Z order.
|
||||
* (it would be easier with sibling-related Below but it doesn't
|
||||
* work very well with SGI mwm for instance)
|
||||
*/
|
||||
winChanges.stack_mode = Above;
|
||||
while (wndPtr)
|
||||
if (!(list = WIN_ListChildren( GetDesktopWindow() ))) return;
|
||||
while (list[i] && list[i] != hwnd) i++;
|
||||
if (list[i])
|
||||
{
|
||||
if (!IsRectEmpty( &wndPtr->rectWindow ) && get_whole_window(wndPtr))
|
||||
TSXReconfigureWMWindow( display, get_whole_window(wndPtr), 0,
|
||||
CWStackMode, &winChanges );
|
||||
wndPrev = wndPtr->parent->child;
|
||||
if (wndPrev == wndPtr) break;
|
||||
while (wndPrev && (wndPrev->next != wndPtr)) wndPrev = wndPrev->next;
|
||||
WIN_UpdateWndPtr( &wndPtr, wndPrev );
|
||||
for ( ; i >= 0; i--)
|
||||
{
|
||||
WND *ptr = WIN_FindWndPtr( list[i] );
|
||||
if (!ptr) continue;
|
||||
if (!IsRectEmpty( &ptr->rectWindow ) && get_whole_window(ptr))
|
||||
TSXReconfigureWMWindow( display, get_whole_window(ptr), 0,
|
||||
CWStackMode, &winChanges );
|
||||
WIN_ReleaseWndPtr( ptr );
|
||||
}
|
||||
}
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
HeapFree( GetProcessHeap(), 0, list );
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ typedef struct tagWND
|
|||
{
|
||||
struct tagWND *next; /* Next sibling */
|
||||
struct tagWND *child; /* First child */
|
||||
struct tagWND *parent; /* Window parent (from CreateWindow) */
|
||||
HWND parent; /* Window parent */
|
||||
HWND owner; /* Window owner */
|
||||
struct tagCLASS *class; /* Window class */
|
||||
HWINDOWPROC winproc; /* Window procedure */
|
||||
|
|
|
@ -406,14 +406,16 @@ void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
|
|||
/* first unlink it if it is linked */
|
||||
if (wndPtr->parent)
|
||||
{
|
||||
ppWnd = &wndPtr->parent->child;
|
||||
WND *ptr = WIN_FindWndPtr( wndPtr->parent );
|
||||
ppWnd = &ptr->child;
|
||||
while (*ppWnd && *ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
|
||||
if (*ppWnd) *ppWnd = wndPtr->next;
|
||||
WIN_ReleaseWndPtr( ptr );
|
||||
}
|
||||
|
||||
if (parentPtr)
|
||||
{
|
||||
wndPtr->parent = parentPtr;
|
||||
wndPtr->parent = parentPtr->hwndSelf;
|
||||
if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
|
||||
{
|
||||
ppWnd = &parentPtr->child; /* Point to first sibling hwnd */
|
||||
|
@ -622,7 +624,7 @@ BOOL WIN_CreateDesktopWindow(void)
|
|||
pWndDesktop->tid = 0; /* nobody owns the desktop */
|
||||
pWndDesktop->next = NULL;
|
||||
pWndDesktop->child = NULL;
|
||||
pWndDesktop->parent = NULL;
|
||||
pWndDesktop->parent = 0;
|
||||
pWndDesktop->owner = 0;
|
||||
pWndDesktop->class = class;
|
||||
pWndDesktop->hInstance = 0;
|
||||
|
@ -777,7 +779,16 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
|
|||
WARN("Bad parent %04x\n", cs->hwndParent );
|
||||
return 0;
|
||||
}
|
||||
if (cs->style & WS_CHILD) parent = cs->hwndParent;
|
||||
if (cs->style & WS_CHILD)
|
||||
{
|
||||
parent = WIN_GetFullHandle(cs->hwndParent);
|
||||
if (!WIN_IsCurrentProcess(parent))
|
||||
{
|
||||
FIXME( "creating child window of %x in other process not supported yet\n",
|
||||
parent );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else owner = GetAncestor( cs->hwndParent, GA_ROOT );
|
||||
}
|
||||
else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP))
|
||||
|
@ -831,9 +842,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
|
|||
wndPtr->next = NULL;
|
||||
wndPtr->child = NULL;
|
||||
wndPtr->owner = owner;
|
||||
wndPtr->parent = WIN_FindWndPtr( parent );
|
||||
WIN_ReleaseWndPtr(wndPtr->parent);
|
||||
|
||||
wndPtr->parent = parent;
|
||||
wndPtr->class = classPtr;
|
||||
wndPtr->winproc = winproc;
|
||||
wndPtr->hInstance = cs->hInstance;
|
||||
|
@ -964,7 +973,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
|
|||
{
|
||||
/* Notify the parent window only */
|
||||
|
||||
SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
|
||||
SendMessageA( wndPtr->parent, WM_PARENTNOTIFY,
|
||||
MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
|
||||
if( !IsWindow(hwnd) )
|
||||
{
|
||||
|
@ -1262,8 +1271,8 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
|
|||
if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
|
||||
{
|
||||
/* Notify the parent window only */
|
||||
SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
|
||||
MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
|
||||
SendMessageA( wndPtr->parent, WM_PARENTNOTIFY,
|
||||
MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
|
||||
if( !IsWindow(hwnd) )
|
||||
{
|
||||
retvalue = TRUE;
|
||||
|
@ -1292,7 +1301,7 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
|
|||
for (;;)
|
||||
{
|
||||
int i, got_one = 0;
|
||||
HWND *list = WIN_ListChildren( wndPtr->parent->hwndSelf );
|
||||
HWND *list = WIN_ListChildren( wndPtr->parent );
|
||||
if (list)
|
||||
{
|
||||
for (i = 0; list[i]; i++)
|
||||
|
@ -2092,7 +2101,7 @@ HWND WINAPI GetParent( HWND hwnd )
|
|||
if ((wndPtr = WIN_FindWndPtr(hwnd)))
|
||||
{
|
||||
if (wndPtr->dwStyle & WS_CHILD)
|
||||
retvalue = wndPtr->parent->hwndSelf;
|
||||
retvalue = wndPtr->parent;
|
||||
else if (wndPtr->dwStyle & WS_POPUP)
|
||||
retvalue = wndPtr->owner;
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
|
@ -2107,34 +2116,42 @@ HWND WINAPI GetParent( HWND hwnd )
|
|||
HWND WINAPI GetAncestor( HWND hwnd, UINT type )
|
||||
{
|
||||
HWND ret = 0;
|
||||
WND *wndPtr;
|
||||
size_t size = (type == GA_PARENT) ? sizeof(user_handle_t) : REQUEST_MAX_VAR_SIZE;
|
||||
|
||||
if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
|
||||
if (wndPtr->hwndSelf == GetDesktopWindow()) goto done;
|
||||
|
||||
switch(type)
|
||||
SERVER_START_VAR_REQ( get_window_parents, size )
|
||||
{
|
||||
case GA_PARENT:
|
||||
WIN_UpdateWndPtr( &wndPtr, wndPtr->parent );
|
||||
break;
|
||||
case GA_ROOT:
|
||||
while (wndPtr->parent->hwndSelf != GetDesktopWindow())
|
||||
WIN_UpdateWndPtr( &wndPtr, wndPtr->parent );
|
||||
break;
|
||||
case GA_ROOTOWNER:
|
||||
while (wndPtr->parent->hwndSelf != GetDesktopWindow())
|
||||
WIN_UpdateWndPtr( &wndPtr, wndPtr->parent );
|
||||
while (wndPtr && wndPtr->owner)
|
||||
req->handle = hwnd;
|
||||
if (!SERVER_CALL())
|
||||
{
|
||||
WND *ptr = WIN_FindWndPtr( wndPtr->owner );
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
wndPtr = ptr;
|
||||
user_handle_t *data = server_data_ptr(req);
|
||||
int count = server_data_size(req) / sizeof(*data);
|
||||
if (count)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case GA_PARENT:
|
||||
ret = data[0];
|
||||
break;
|
||||
case GA_ROOT:
|
||||
case GA_ROOTOWNER:
|
||||
if (count > 1) ret = data[count - 2]; /* get the one before the desktop */
|
||||
else ret = WIN_GetFullHandle( hwnd );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SERVER_END_VAR_REQ;
|
||||
|
||||
if (ret && type == GA_ROOTOWNER)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
HWND owner = GetWindow( ret, GW_OWNER );
|
||||
if (!owner) break;
|
||||
ret = owner;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ret = wndPtr ? wndPtr->hwndSelf : 0;
|
||||
done:
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2169,7 +2186,7 @@ HWND WINAPI SetParent( HWND hwnd, HWND parent )
|
|||
* including the WM_SHOWWINDOW messages and all */
|
||||
if (dwStyle & WS_VISIBLE) ShowWindow( hwnd, SW_HIDE );
|
||||
|
||||
retvalue = wndPtr->parent->hwndSelf; /* old parent */
|
||||
retvalue = wndPtr->parent; /* old parent */
|
||||
if (parent != retvalue)
|
||||
{
|
||||
WIN_LinkWindow( hwnd, parent, HWND_TOP );
|
||||
|
|
|
@ -309,7 +309,7 @@ HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest )
|
|||
}
|
||||
|
||||
if (wndScope->parent)
|
||||
MapWindowPoints( GetDesktopWindow(), wndScope->parent->hwndSelf, &xy, 1 );
|
||||
MapWindowPoints( GetDesktopWindow(), wndScope->parent, &xy, 1 );
|
||||
|
||||
if (xy.x < wndScope->rectClient.left || pt.x >= wndScope->rectClient.right ||
|
||||
xy.y < wndScope->rectClient.top || pt.y >= wndScope->rectClient.bottom ||
|
||||
|
@ -401,7 +401,7 @@ hittest:
|
|||
|
||||
/* Restart the search from the next sibling */
|
||||
WIN_UpdateWndPtr(&wndPtr,wndTmp->next);
|
||||
hwnd_ret = wndTmp->parent ? wndTmp->parent->hwndSelf : 0;
|
||||
hwnd_ret = wndTmp->parent;
|
||||
WIN_ReleaseWndPtr( wndTmp );
|
||||
}
|
||||
|
||||
|
@ -477,6 +477,8 @@ static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo,
|
|||
POINT *offset )
|
||||
{
|
||||
WND * wndPtr = 0;
|
||||
HWND *list;
|
||||
int i;
|
||||
|
||||
offset->x = offset->y = 0;
|
||||
if (hwndFrom == hwndTo ) return;
|
||||
|
@ -489,11 +491,16 @@ static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo,
|
|||
ERR("bad hwndFrom = %04x\n",hwndFrom);
|
||||
return;
|
||||
}
|
||||
while (wndPtr->parent)
|
||||
if ((list = WIN_ListParents( hwndFrom )))
|
||||
{
|
||||
offset->x += wndPtr->rectClient.left;
|
||||
offset->y += wndPtr->rectClient.top;
|
||||
WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
|
||||
for (i = 0; list[i]; i++)
|
||||
{
|
||||
offset->x += wndPtr->rectClient.left;
|
||||
offset->y += wndPtr->rectClient.top;
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
if (!(wndPtr = WIN_FindWndPtr( list[i] ))) break;
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, list );
|
||||
}
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
}
|
||||
|
@ -506,12 +513,17 @@ static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo,
|
|||
ERR("bad hwndTo = %04x\n", hwndTo );
|
||||
return;
|
||||
}
|
||||
while (wndPtr->parent)
|
||||
if ((list = WIN_ListParents( hwndTo )))
|
||||
{
|
||||
offset->x -= wndPtr->rectClient.left;
|
||||
offset->y -= wndPtr->rectClient.top;
|
||||
WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
|
||||
}
|
||||
for (i = 0; list[i]; i++)
|
||||
{
|
||||
offset->x -= wndPtr->rectClient.left;
|
||||
offset->y -= wndPtr->rectClient.top;
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
if (!(wndPtr = WIN_FindWndPtr( list[i] ))) break;
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, list );
|
||||
}
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue