Use an X context to associated the x11drv private window data to a
window handle instead of accessing the WND structure directly.
diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c
index 35f1333..b34b9f5 100644
--- a/dlls/x11drv/window.c
+++ b/dlls/x11drv/window.c
@@ -50,6 +50,9 @@
/* X context to associate a hwnd to an X window */
XContext winContext = 0;
+/* X context to associate a struct x11drv_win_data to an hwnd */
+static XContext win_data_context;
+
Atom X11DRV_Atoms[NB_XATOMS - FIRST_XATOM];
static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
@@ -743,20 +746,6 @@
}
-/***********************************************************************
- * X11DRV_register_window
- *
- * Associate an X window to a HWND.
- */
-void X11DRV_register_window( Display *display, HWND hwnd, struct x11drv_win_data *data )
-{
- wine_tsx11_lock();
- XSaveContext( display, data->whole_window, winContext, (char *)hwnd );
- XSaveContext( display, data->client_window, winContext, (char *)hwnd );
- wine_tsx11_unlock();
-}
-
-
/**********************************************************************
* create_desktop
*/
@@ -828,6 +817,7 @@
wine_tsx11_unlock();
return 0;
}
+ XSaveContext( display, data->whole_window, winContext, (char *)data->hwnd );
/* non-maximized child must be at bottom of Z order */
if ((style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
@@ -878,6 +868,7 @@
0, screen_depth,
InputOutput, visual,
CWEventMask | CWBitGravity | CWBackingStore, &attr );
+ XSaveContext( display, data->client_window, winContext, (char *)data->hwnd );
if (data->client_window && is_mapped) XMapWindow( display, data->client_window );
wine_tsx11_unlock();
return data->client_window;
@@ -947,9 +938,9 @@
struct x11drv_thread_data *thread_data = x11drv_thread_data();
Display *display = thread_data->display;
WND *wndPtr = WIN_GetPtr( hwnd );
- struct x11drv_win_data *data = wndPtr->pDriverData;
+ struct x11drv_win_data *data;
- if (!data) goto done;
+ if (!(data = X11DRV_get_win_data( hwnd ))) goto done;
if (data->whole_window)
{
@@ -972,8 +963,11 @@
if (data->hWMIconBitmap) DeleteObject( data->hWMIconBitmap );
if (data->hWMIconMask) DeleteObject( data->hWMIconMask);
+ wine_tsx11_lock();
+ XDeleteContext( gdi_display, (XID)hwnd, win_data_context );
+ wine_tsx11_unlock();
HeapFree( GetProcessHeap(), 0, data );
- wndPtr->pDriverData = NULL;
+
done:
WIN_ReleasePtr( wndPtr );
return TRUE;
@@ -988,7 +982,7 @@
Display *display = thread_display();
WND *wndPtr;
struct x11drv_win_data *data;
- HWND insert_after;
+ HWND parent, insert_after;
RECT rect;
DWORD style;
CBT_CREATEWNDA cbtc;
@@ -1024,20 +1018,22 @@
data->hWMIconBitmap = 0;
data->hWMIconMask = 0;
- wndPtr = WIN_GetPtr( hwnd );
- wndPtr->pDriverData = data;
+ /* use gdi_display so that it's available from all threads (FIXME) */
+ wine_tsx11_lock();
+ if (!win_data_context) win_data_context = XUniqueContext();
+ XSaveContext( gdi_display, (XID)hwnd, win_data_context, (char *)data );
+ wine_tsx11_unlock();
/* initialize the dimensions before sending WM_GETMINMAXINFO */
SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
X11DRV_set_window_pos( hwnd, 0, &rect, &rect, SWP_NOZORDER, 0 );
- if (!wndPtr->parent)
+ parent = GetAncestor( hwnd, GA_PARENT );
+ if (!parent)
{
create_desktop( display, data );
- WIN_ReleasePtr( wndPtr );
return TRUE;
}
- WIN_ReleasePtr( wndPtr );
if (!create_whole_window( display, data, cs->style )) goto failed;
if (!create_client_window( display, data )) goto failed;
@@ -1103,7 +1099,6 @@
insert_after = ((wndPtr->dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
X11DRV_set_window_pos( hwnd, insert_after, &wndPtr->rectWindow, &rect, 0, 0 );
- X11DRV_register_window( display, hwnd, data );
TRACE( "win %p window %ld,%ld,%ld,%ld client %ld,%ld,%ld,%ld whole %ld,%ld,%ld,%ld X client %ld,%ld,%ld,%ld xwin %x/%x\n",
hwnd, wndPtr->rectWindow.left, wndPtr->rectWindow.top,
@@ -1179,15 +1174,9 @@
*/
struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd )
{
- struct x11drv_win_data *ret = NULL;
- WND *win = WIN_GetPtr( hwnd );
-
- if (win && win != WND_OTHER_PROCESS)
- {
- ret = win->pDriverData;
- WIN_ReleasePtr( win );
- }
- return ret;
+ char *data;
+ if (XFindContext( gdi_display, (XID)hwnd, win_data_context, &data )) data = NULL;
+ return (struct x11drv_win_data *)data;
}
@@ -1239,27 +1228,27 @@
HWND X11DRV_SetParent( HWND hwnd, HWND parent )
{
Display *display = thread_display();
- WND *wndPtr;
- HWND retvalue;
+ HWND old_parent;
/* Windows hides the window first, then shows it again
* including the WM_SHOWWINDOW messages and all */
BOOL was_visible = ShowWindow( hwnd, SW_HIDE );
if (!IsWindow( parent )) return 0;
- if (!(wndPtr = WIN_GetPtr(hwnd)) || wndPtr == WND_OTHER_PROCESS) return 0;
- retvalue = wndPtr->parent; /* old parent */
- if (parent != retvalue)
+ old_parent = GetAncestor( hwnd, GA_PARENT );
+ if (parent != old_parent)
{
- struct x11drv_win_data *data = wndPtr->pDriverData;
+ struct x11drv_win_data *data;
Window new_parent = X11DRV_get_client_window( parent );
+ if (!(data = X11DRV_get_win_data( hwnd ))) return 0;
+
WIN_LinkWindow( hwnd, parent, HWND_TOP );
if (parent != GetDesktopWindow()) /* a child window */
{
- if (!(wndPtr->dwStyle & WS_CHILD))
+ if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD))
{
HMENU menu = (HMENU)SetWindowLongPtrW( hwnd, GWLP_ID, 0 );
if (menu) DestroyMenu( menu );
@@ -1273,7 +1262,6 @@
data->whole_rect.left, data->whole_rect.top );
wine_tsx11_unlock();
}
- WIN_ReleasePtr( wndPtr );
/* SetParent additionally needs to make hwnd the topmost window
in the x-order and send the expected WM_WINDOWPOSCHANGING and
@@ -1284,7 +1272,7 @@
/* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
* for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
- return retvalue;
+ return old_parent;
}