Create an X connection for each thread, and process X events in the
thread that created the corresponding X window.
Spawn a separate thread to run the desktop message loop in desktop
mode.
diff --git a/controls/desktop.c b/controls/desktop.c
index 2b3f836..01e1706 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -97,121 +97,25 @@
}
-/***********************************************************************
- * DESKTOP_DoEraseBkgnd
- *
- * Handle the WM_ERASEBKGND message.
- */
-static LRESULT DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc,
- DESKTOP *desktopPtr )
-{
- RECT rect;
- WND* Wnd = WIN_FindWndPtr( hwnd );
-
- if (Wnd->hrgnUpdate > 1) DeleteObject( Wnd->hrgnUpdate );
- Wnd->hrgnUpdate = 0;
-
- WIN_ReleaseWndPtr(Wnd);
-
- GetClientRect( hwnd, &rect );
-
- /* Paint desktop pattern (only if wall paper does not cover everything) */
-
- if (!desktopPtr->hbitmapWallPaper ||
- (!desktopPtr->fTileWallPaper && ((desktopPtr->bitmapSize.cx < rect.right) ||
- (desktopPtr->bitmapSize.cy < rect.bottom))))
- {
- HBRUSH brush = desktopPtr->hbrushPattern;
- if (!brush) brush = GetClassLongA( hwnd, GCL_HBRBACKGROUND );
- /* Set colors in case pattern is a monochrome bitmap */
- SetBkColor( hdc, RGB(0,0,0) );
- SetTextColor( hdc, GetSysColor(COLOR_BACKGROUND) );
- FillRect( hdc, &rect, brush );
- }
-
- /* Paint wall paper */
-
- if (desktopPtr->hbitmapWallPaper)
- {
- INT x, y;
- HDC hMemDC = CreateCompatibleDC( hdc );
-
- SelectObject( hMemDC, desktopPtr->hbitmapWallPaper );
-
- if (desktopPtr->fTileWallPaper)
- {
- for (y = 0; y < rect.bottom; y += desktopPtr->bitmapSize.cy)
- for (x = 0; x < rect.right; x += desktopPtr->bitmapSize.cx)
- BitBlt( hdc, x, y, desktopPtr->bitmapSize.cx,
- desktopPtr->bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
- }
- else
- {
- x = (rect.left + rect.right - desktopPtr->bitmapSize.cx) / 2;
- y = (rect.top + rect.bottom - desktopPtr->bitmapSize.cy) / 2;
- if (x < 0) x = 0;
- if (y < 0) y = 0;
- BitBlt( hdc, x, y, desktopPtr->bitmapSize.cx,
- desktopPtr->bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
- }
- DeleteDC( hMemDC );
- }
-
- return 1;
-}
-
-
-/***********************************************************************
- * DesktopWndProc_locked
- *
- * Window procedure for the desktop window.
- */
-static inline LRESULT WINAPI DesktopWndProc_locked( WND *wndPtr, UINT message,
- WPARAM wParam, LPARAM lParam )
-{
- DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
- HWND hwnd = wndPtr->hwndSelf;
-
- /* Most messages are ignored (we DON'T call DefWindowProc) */
-
- switch(message)
- {
- /* Warning: this message is sent directly by */
- /* WIN_CreateDesktopWindow() and does not contain a valid lParam */
- case WM_NCCREATE:
- desktopPtr->hbrushPattern = 0;
- desktopPtr->hbitmapWallPaper = 0;
- SetDeskPattern();
- SetDeskWallPaper( (LPSTR)-1 );
- return 1;
-
- case WM_ERASEBKGND:
- if(!USER_Driver.pIsSingleWindow())
- return 1;
- return DESKTOP_DoEraseBkgnd( hwnd, (HDC)wParam, desktopPtr );
-
- case WM_SYSCOMMAND:
- if ((wParam & 0xfff0) != SC_CLOSE)
- return 0;
- ExitWindows16( 0, 0 );
-
- case WM_SETCURSOR:
- return (LRESULT)SetCursor( LoadCursorA( 0, IDC_ARROWA ) );
- }
-
- return 0;
-}
/***********************************************************************
* DesktopWndProc
- *
- * This is just a wrapper for the DesktopWndProc which does windows
- * locking and unlocking.
*/
static LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
+ LRESULT retvalue = 0;
WND *wndPtr = WIN_FindWndPtr( hwnd );
- LRESULT retvalue = DesktopWndProc_locked(wndPtr,message,wParam,lParam);
+ DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
+
+ if (message == WM_NCCREATE)
+ {
+ desktopPtr->hbrushPattern = 0;
+ desktopPtr->hbitmapWallPaper = 0;
+ SetDeskPattern();
+ SetDeskWallPaper( (LPSTR)-1 );
+ retvalue = 1;
+ }
+ /* all other messages are ignored */
WIN_ReleaseWndPtr(wndPtr);
return retvalue;
@@ -223,14 +127,61 @@
*/
BOOL WINAPI PaintDesktop(HDC hdc)
{
- BOOL retvalue;
HWND hwnd = GetDesktopWindow();
WND *wndPtr = WIN_FindWndPtr( hwnd );
DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
- retvalue = DESKTOP_DoEraseBkgnd( hwnd, hdc, desktopPtr );
- WIN_ReleaseWndPtr(wndPtr);
- return retvalue;
+ /* check for a queue; otherwise don't paint anything (non-desktop mode) */
+ if (wndPtr->hmemTaskQ)
+ {
+ RECT rect;
+
+ GetClientRect( hwnd, &rect );
+
+ /* Paint desktop pattern (only if wall paper does not cover everything) */
+
+ if (!desktopPtr->hbitmapWallPaper ||
+ (!desktopPtr->fTileWallPaper && ((desktopPtr->bitmapSize.cx < rect.right) ||
+ (desktopPtr->bitmapSize.cy < rect.bottom))))
+ {
+ HBRUSH brush = desktopPtr->hbrushPattern;
+ if (!brush) brush = GetClassLongA( hwnd, GCL_HBRBACKGROUND );
+ /* Set colors in case pattern is a monochrome bitmap */
+ SetBkColor( hdc, RGB(0,0,0) );
+ SetTextColor( hdc, GetSysColor(COLOR_BACKGROUND) );
+ FillRect( hdc, &rect, brush );
+ }
+
+ /* Paint wall paper */
+
+ if (desktopPtr->hbitmapWallPaper)
+ {
+ INT x, y;
+ HDC hMemDC = CreateCompatibleDC( hdc );
+
+ SelectObject( hMemDC, desktopPtr->hbitmapWallPaper );
+
+ if (desktopPtr->fTileWallPaper)
+ {
+ for (y = 0; y < rect.bottom; y += desktopPtr->bitmapSize.cy)
+ for (x = 0; x < rect.right; x += desktopPtr->bitmapSize.cx)
+ BitBlt( hdc, x, y, desktopPtr->bitmapSize.cx,
+ desktopPtr->bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
+ }
+ else
+ {
+ x = (rect.left + rect.right - desktopPtr->bitmapSize.cx) / 2;
+ y = (rect.top + rect.bottom - desktopPtr->bitmapSize.cy) / 2;
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ BitBlt( hdc, x, y, desktopPtr->bitmapSize.cx,
+ desktopPtr->bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
+ }
+ DeleteDC( hMemDC );
+ }
+ }
+ WIN_ReleaseWndPtr(wndPtr);
+ return TRUE;
}
/***********************************************************************
diff --git a/dlls/ttydrv/ttydrv.spec b/dlls/ttydrv/ttydrv.spec
index 55ad8bc..ffcdc9f 100644
--- a/dlls/ttydrv/ttydrv.spec
+++ b/dlls/ttydrv/ttydrv.spec
@@ -11,7 +11,6 @@
# USER driver
-@ cdecl UserRepaintDisable(long) TTYDRV_UserRepaintDisable
@ cdecl InitKeyboard() TTYDRV_InitKeyboard
@ cdecl VkKeyScan(long) TTYDRV_VkKeyScan
@ cdecl MapVirtualKey(long long) TTYDRV_MapVirtualKey
@@ -32,7 +31,6 @@
@ cdecl DestroyWindow(long) TTYDRV_DestroyWindow
@ cdecl GetDC(long long long long) TTYDRV_GetDC
@ cdecl SetWindowPos(ptr) TTYDRV_SetWindowPos
-@ cdecl IsSingleWindow() TTYDRV_IsSingleWindow
@ cdecl AcquireClipboard() TTYDRV_AcquireClipboard
@ cdecl ReleaseClipboard() TTYDRV_ReleaseClipboard
@ cdecl SetClipboardData(long) TTYDRV_SetClipboardData
diff --git a/dlls/ttydrv/user.c b/dlls/ttydrv/user.c
index ca7a3c5..6d65162 100644
--- a/dlls/ttydrv/user.c
+++ b/dlls/ttydrv/user.c
@@ -11,13 +11,6 @@
DEFAULT_DEBUG_CHANNEL(ttydrv);
-/***********************************************************************
- * TTYDRV_UserRepaintDisable
- */
-void TTYDRV_UserRepaintDisable( BOOL bDisable )
-{
-}
-
/***********************************************************************
* TTYDRV_InitKeyboard
@@ -170,14 +163,6 @@
}
/***********************************************************************
- * TTYDRV_IsSingleWindow
- */
-BOOL TTYDRV_IsSingleWindow(void)
-{
- return TRUE;
-}
-
-/***********************************************************************
* TTYDRV_AcquireClipboard
*/
void TTYDRV_AcquireClipboard(void)
diff --git a/dlls/user/display.c b/dlls/user/display.c
index 822174a..e132285 100644
--- a/dlls/user/display.c
+++ b/dlls/user/display.c
@@ -76,6 +76,6 @@
*/
VOID WINAPI UserRepaintDisable16( BOOL16 disable )
{
- USER_Driver.pUserRepaintDisable( disable );
+ FIXME("stub\n");
}
diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c
index 2690e8d..341c5f4 100644
--- a/dlls/user/user_main.c
+++ b/dlls/user/user_main.c
@@ -12,8 +12,10 @@
#include "wine/winuser16.h"
#include "controls.h"
+#include "cursoricon.h"
#include "global.h"
#include "input.h"
+#include "hook.h"
#include "keyboard.h"
#include "message.h"
#include "queue.h"
@@ -58,7 +60,6 @@
return FALSE;
}
- GET_USER_FUNC(UserRepaintDisable);
GET_USER_FUNC(InitKeyboard);
GET_USER_FUNC(VkKeyScan);
GET_USER_FUNC(MapVirtualKey);
@@ -75,7 +76,6 @@
GET_USER_FUNC(GetScreenSaveTimeout);
GET_USER_FUNC(SetScreenSaveTimeout);
GET_USER_FUNC(LoadOEMResource);
- GET_USER_FUNC(IsSingleWindow);
GET_USER_FUNC(AcquireClipboard);
GET_USER_FUNC(ReleaseClipboard);
GET_USER_FUNC(SetClipboardData);
@@ -88,6 +88,7 @@
GET_USER_FUNC(DestroyWindow);
GET_USER_FUNC(GetDC);
GET_USER_FUNC(EnableWindow);
+ GET_USER_FUNC(MsgWaitForMultipleObjects);
GET_USER_FUNC(ScrollWindowEx);
GET_USER_FUNC(SetFocus);
GET_USER_FUNC(SetParent);
@@ -191,13 +192,11 @@
/***********************************************************************
* USER initialisation routine
*/
-BOOL WINAPI USER_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+static BOOL process_attach(void)
{
HINSTANCE16 instance;
int queueSize;
- if ( USER_HeapSel ) return TRUE;
-
/* Create USER heap */
if ((instance = LoadLibrary16( "USER.EXE" )) < 32) return FALSE;
USER_HeapSel = instance | 7;
@@ -250,8 +249,66 @@
/* Initialize mouse driver */
MOUSE_Enable( mouse_event );
- /* Start processing X events */
- USER_Driver.pUserRepaintDisable( FALSE );
-
return TRUE;
}
+
+
+/**********************************************************************
+ * thread
+ */
+static void thread_detach(void)
+{
+ HQUEUE16 hQueue = GetThreadQueue16( 0 );
+
+ if (hQueue)
+ {
+ WND* desktop = WIN_GetDesktop();
+
+ TIMER_RemoveQueueTimers( hQueue );
+
+ HOOK_FreeQueueHooks( hQueue );
+
+ QUEUE_SetExitingQueue( hQueue );
+ WIN_ResetQueueWindows( desktop, hQueue, 0 );
+ QUEUE_SetExitingQueue( 0 );
+ QUEUE_DeleteMsgQueue( hQueue );
+
+ WIN_ReleaseDesktop();
+ SetThreadQueue16( 0, 0 );
+ }
+
+ if (!(NtCurrentTeb()->tibflags & TEBF_WIN32))
+ {
+ HMODULE16 hModule = GetExePtr( MapHModuleLS(0) );
+
+ /* FIXME: maybe destroy menus (Windows only complains about them
+ * but does nothing);
+ */
+ if (GetModuleUsage16( hModule ) <= 1)
+ {
+ /* ModuleUnload() in "Internals" */
+ HOOK_FreeModuleHooks( hModule );
+ CLASS_FreeModuleClasses( hModule );
+ CURSORICON_FreeModuleIcons( hModule );
+ }
+ }
+}
+
+
+/***********************************************************************
+ * USER initialisation routine
+ */
+BOOL WINAPI USER_Init( HINSTANCE inst, DWORD reason, LPVOID reserved )
+{
+ BOOL ret = TRUE;
+ switch(reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ ret = process_attach();
+ break;
+ case DLL_THREAD_DETACH:
+ thread_detach();
+ break;
+ }
+ return ret;
+}
diff --git a/dlls/x11drv/Makefile.in b/dlls/x11drv/Makefile.in
index 10a3f9a..e98cdd5 100644
--- a/dlls/x11drv/Makefile.in
+++ b/dlls/x11drv/Makefile.in
@@ -7,6 +7,7 @@
IMPORTS = user32 gdi32 kernel32
C_SRCS = \
+ desktop.c \
dga2.c \
window.c \
winpos.c \
diff --git a/dlls/x11drv/desktop.c b/dlls/x11drv/desktop.c
new file mode 100644
index 0000000..1376899
--- /dev/null
+++ b/dlls/x11drv/desktop.c
@@ -0,0 +1,158 @@
+/*
+ * X11DRV desktop window handling
+ *
+ * Copyright 2001 Alexandre Julliard
+ */
+
+#include "config.h"
+#include <X11/cursorfont.h>
+
+#include "ts_xlib.h"
+
+#include "win.h"
+#include "x11drv.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(x11drv);
+
+
+/* desktop window procedure */
+static LRESULT WINAPI desktop_winproc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
+{
+ switch(message)
+ {
+ case WM_ERASEBKGND:
+ PaintDesktop( (HDC)wParam );
+ ValidateRect( hwnd, NULL );
+ break;
+
+ case WM_SYSCOMMAND:
+ if ((wParam & 0xfff0) == SC_CLOSE) ExitWindows( 0, 0 );
+ break;
+
+ case WM_SETCURSOR:
+ return SetCursor( LoadCursorA( 0, IDC_ARROWA ) );
+
+ case WM_NCHITTEST:
+ return HTCLIENT;
+ }
+ return 0;
+}
+
+
+/* desktop window manager thread */
+static DWORD CALLBACK desktop_thread( LPVOID driver_data )
+{
+ Display *display;
+ MSG msg;
+ HWND hwnd;
+ WND *win;
+
+ NtCurrentTeb()->driver_data = driver_data;
+ display = thread_display();
+ hwnd = GetDesktopWindow();
+
+ /* patch the desktop window queue to point to our queue */
+ win = WIN_FindWndPtr( hwnd );
+ win->hmemTaskQ = GetFastQueue16();
+ WIN_ReleaseWndPtr( win );
+
+ SetWindowLongW( hwnd, GWL_WNDPROC, (LONG)desktop_winproc );
+ X11DRV_register_window( display, hwnd, root_window );
+ TSXMapWindow( display, root_window );
+
+ while (GetMessageW( &msg, hwnd, 0, 0 )) DispatchMessageW( &msg );
+ return 0;
+}
+
+
+/***********************************************************************
+ * X11DRV_create_desktop_thread
+ *
+ * Create the thread that manages the desktop window
+ */
+void X11DRV_create_desktop_thread(void)
+{
+ HANDLE handle = CreateThread( NULL, 0, desktop_thread, NtCurrentTeb()->driver_data, 0, NULL );
+ if (!handle)
+ {
+ MESSAGE( "Could not create desktop thread\n" );
+ ExitProcess(1);
+ }
+ /* we transferred our driver data to the new thread */
+ NtCurrentTeb()->driver_data = NULL;
+ CloseHandle( handle );
+}
+
+
+/***********************************************************************
+ * X11DRV_create_desktop
+ *
+ * Create the X11 desktop window for the desktop mode.
+ */
+Window X11DRV_create_desktop( XVisualInfo *desktop_vi, const char *geometry )
+{
+ int x = 0, y = 0, flags;
+ unsigned int width = 640, height = 480; /* Default size = 640x480 */
+ char *name = "Wine desktop";
+ XSizeHints *size_hints;
+ XWMHints *wm_hints;
+ XClassHint *class_hints;
+ XSetWindowAttributes win_attr;
+ XTextProperty window_name;
+ Window win;
+ Display *display = thread_display();
+
+ wine_tsx11_lock();
+ flags = XParseGeometry( geometry, &x, &y, &width, &height );
+ screen_width = width;
+ screen_height = height;
+
+ /* Create window */
+ win_attr.background_pixel = BlackPixel(display, 0);
+ win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
+ win_attr.cursor = XCreateFontCursor( display, XC_top_left_arrow );
+
+ if (desktop_vi)
+ win_attr.colormap = XCreateColormap( display, DefaultRootWindow(display),
+ visual, AllocNone );
+ else
+ win_attr.colormap = None;
+
+ win = XCreateWindow( display, DefaultRootWindow(display),
+ x, y, width, height, 0, screen_depth, InputOutput, visual,
+ CWBackPixel | CWEventMask | CWCursor | CWColormap, &win_attr );
+
+ /* Set window manager properties */
+ size_hints = XAllocSizeHints();
+ wm_hints = XAllocWMHints();
+ class_hints = XAllocClassHint();
+ if (!size_hints || !wm_hints || !class_hints)
+ {
+ MESSAGE("Not enough memory for window manager hints.\n" );
+ ExitProcess(1);
+ }
+ size_hints->min_width = size_hints->max_width = width;
+ size_hints->min_height = size_hints->max_height = height;
+ size_hints->flags = PMinSize | PMaxSize;
+ if (flags & (XValue | YValue)) size_hints->flags |= USPosition;
+ if (flags & (WidthValue | HeightValue)) size_hints->flags |= USSize;
+ else size_hints->flags |= PSize;
+
+ wm_hints->flags = InputHint | StateHint;
+ wm_hints->input = True;
+ wm_hints->initial_state = NormalState;
+ class_hints->res_name = "wine";
+ class_hints->res_class = "Wine";
+
+ XStringListToTextProperty( &name, 1, &window_name );
+ XSetWMProperties( display, win, &window_name, &window_name,
+ NULL, 0, size_hints, wm_hints, class_hints );
+ XFree( size_hints );
+ XFree( wm_hints );
+ XFree( class_hints );
+ XFlush( display );
+ wine_tsx11_unlock();
+ return win;
+}
diff --git a/dlls/x11drv/dga2.c b/dlls/x11drv/dga2.c
index 939cb6a..bf9fc0a 100644
--- a/dlls/x11drv/dga2.c
+++ b/dlls/x11drv/dga2.c
@@ -51,7 +51,7 @@
if (xf86dga2_modes) return; /* already initialized? */
/* if in desktop mode, don't use DGA */
- if (X11DRV_GetXRootWindow() != DefaultRootWindow(display)) return;
+ if (root_window != DefaultRootWindow(display)) return;
if (!usedga) return;
diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c
index 4508b99..ed3e966 100644
--- a/dlls/x11drv/window.c
+++ b/dlls/x11drv/window.c
@@ -23,7 +23,6 @@
DEFAULT_DEBUG_CHANNEL(win);
-extern Cursor X11DRV_MOUSE_XCursor; /* current X cursor */
extern Pixmap X11DRV_BITMAP_Pixmap( HBITMAP );
#define HAS_DLGFRAME(style,exStyle) \
@@ -42,11 +41,11 @@
/***********************************************************************
- * register_window
+ * X11DRV_register_window
*
* Associate an X window to a HWND.
*/
-static void register_window( HWND hwnd, Window win )
+void X11DRV_register_window( Display *display, HWND hwnd, Window win )
{
if (!winContext) winContext = TSXUniqueContext();
TSXSaveContext( display, win, winContext, (char *)hwnd );
@@ -59,7 +58,7 @@
*
* Set a window manager hint.
*/
-static void set_wm_hint( Window win, int hint, int val )
+static void set_wm_hint( Display *display, Window win, int hint, int val )
{
XWMHints* wm_hints = TSXGetWMHints( display, win );
if (!wm_hints) wm_hints = TSXAllocWMHints();
@@ -95,7 +94,7 @@
*
* Set the icon wm hints
*/
-static void set_icon_hints( WND *wndPtr, XWMHints *hints )
+static void set_icon_hints( Display *display, WND *wndPtr, XWMHints *hints )
{
X11DRV_WND_DATA *data = wndPtr->pDriverData;
HICON hIcon = GetClassLongA( wndPtr->hwndSelf, GCL_HICON );
@@ -155,7 +154,7 @@
*
* all others: to be added ;)
*/
-inline static void dock_window( Window win )
+inline static void dock_window( Display *display, Window win )
{
int data = 1;
if (kwmDockWindow != None)
@@ -170,7 +169,7 @@
/**********************************************************************
* create_desktop
*/
-static void create_desktop(WND *wndPtr)
+static void create_desktop( Display *display, WND *wndPtr )
{
X11DRV_WND_DATA *data = wndPtr->pDriverData;
@@ -183,8 +182,11 @@
_kde_net_wm_system_tray_window_for = TSXInternAtom( display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False );
data->window = root_window;
- if (root_window != DefaultRootWindow(display)) wndPtr->flags |= WIN_NATIVE;
- register_window( wndPtr->hwndSelf, root_window );
+ if (root_window != DefaultRootWindow(display))
+ {
+ wndPtr->flags |= WIN_NATIVE;
+ X11DRV_create_desktop_thread();
+ }
}
@@ -193,6 +195,7 @@
*/
BOOL X11DRV_CreateWindow( HWND hwnd )
{
+ Display *display = thread_display();
X11DRV_WND_DATA *data;
WND *wndPtr = WIN_FindWndPtr( hwnd );
int x = wndPtr->rectWindow.left;
@@ -210,7 +213,7 @@
if (!wndPtr->parent)
{
- create_desktop( wndPtr );
+ create_desktop( display, wndPtr );
WIN_ReleaseWndPtr( wndPtr );
return TRUE;
}
@@ -246,11 +249,13 @@
}
wndPtr->flags |= WIN_NATIVE;
+ wine_tsx11_lock();
+
win_attr.bit_gravity = (wndPtr->clsStyle & (CS_VREDRAW | CS_HREDRAW)) ? ForgetGravity : NorthWestGravity;
win_attr.colormap = X11DRV_PALETTE_PaletteXColormap;
win_attr.backing_store = NotUseful;
win_attr.save_under = ((wndPtr->clsStyle & CS_SAVEBITS) != 0);
- win_attr.cursor = X11DRV_MOUSE_XCursor;
+ win_attr.cursor = X11DRV_GetCursor( display, GlobalLock16(GetCursor()) );
data->hWMIconBitmap = 0;
data->hWMIconMask = 0;
@@ -262,7 +267,7 @@
if (cx <= 0) cx = 1;
if (cy <= 0) cy = 1;
- data->window = TSXCreateWindow( display, root_window,
+ data->window = XCreateWindow( display, root_window,
x, y, cx, cy,
0, screen_depth,
InputOutput, visual,
@@ -271,7 +276,10 @@
CWBackingStore | CWBitGravity,
&win_attr );
- if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr)))
+ if (win_attr.cursor) XFreeCursor( display, win_attr.cursor );
+ wine_tsx11_unlock();
+
+ if(!(wGroupLeader = data->window))
{
HeapFree( GetProcessHeap(), 0, data );
WIN_ReleaseWndPtr( wndPtr );
@@ -279,7 +287,7 @@
}
/* If we are the systray, we need to be managed to be noticed by KWM */
- if (wndPtr->dwExStyle & WS_EX_TRAYWINDOW) dock_window( data->window );
+ if (wndPtr->dwExStyle & WS_EX_TRAYWINDOW) dock_window( display, data->window );
if (wndPtr->dwExStyle & WS_EX_MANAGED)
{
@@ -331,7 +339,7 @@
if (wndPtr->dwExStyle & WS_EX_MANAGED)
{
- set_icon_hints( wndPtr, wm_hints );
+ set_icon_hints( display, wndPtr, wm_hints );
wm_hints->initial_state = (wndPtr->dwStyle & WS_MINIMIZE)
? IconicState : NormalState;
}
@@ -342,7 +350,8 @@
TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
TSXFree(wm_hints);
}
- register_window( hwnd, data->window );
+ X11DRV_register_window( display, hwnd, data->window );
+ TSXFlush( display );
}
WIN_ReleaseWndPtr( wndPtr );
return TRUE;
@@ -354,6 +363,7 @@
*/
BOOL X11DRV_DestroyWindow( HWND hwnd )
{
+ Display *display = thread_display();
WND *wndPtr = WIN_FindWndPtr( hwnd );
X11DRV_WND_DATA *data = wndPtr->pDriverData;
Window w;
@@ -361,9 +371,12 @@
if (data && (w = data->window))
{
XEvent xe;
- TSXDeleteContext( display, w, winContext );
- TSXDestroyWindow( display, w );
- while( TSXCheckWindowEvent(display, w, NoEventMask, &xe) );
+ wine_tsx11_lock();
+ XSync( gdi_display, False ); /* flush any reference to this drawable in GDI queue */
+ XDeleteContext( display, w, winContext );
+ XDestroyWindow( display, w );
+ while( XCheckWindowEvent(display, w, NoEventMask, &xe) );
+ wine_tsx11_unlock();
data->window = None;
if( data->hWMIconBitmap )
@@ -389,6 +402,7 @@
*/
HWND X11DRV_SetParent( HWND hwnd, HWND parent )
{
+ Display *display = thread_display();
WND *wndPtr;
WND *pWndParent;
DWORD dwStyle;
@@ -464,6 +478,7 @@
*/
BOOL X11DRV_EnableWindow( HWND hwnd, BOOL enable )
{
+ Display *display = thread_display();
WND *wndPtr;
BOOL retvalue;
Window w;
@@ -478,7 +493,7 @@
wndPtr->dwStyle &= ~WS_DISABLED;
if ((wndPtr->dwExStyle & WS_EX_MANAGED) && (w = X11DRV_WND_GetXWindow( wndPtr )))
- set_wm_hint( w, InputHint, TRUE );
+ set_wm_hint( display, w, InputHint, TRUE );
SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
}
@@ -490,7 +505,7 @@
wndPtr->dwStyle |= WS_DISABLED;
if ((wndPtr->dwExStyle & WS_EX_MANAGED) && (w = X11DRV_WND_GetXWindow( wndPtr )))
- set_wm_hint( w, InputHint, FALSE );
+ set_wm_hint( display, w, InputHint, FALSE );
if (hwnd == GetFocus())
SetFocus( 0 ); /* A disabled window can't have the focus */
@@ -513,6 +528,7 @@
*/
void X11DRV_SetFocus( HWND hwnd )
{
+ Display *display = thread_display();
XWindowAttributes win_attr;
Window win;
WND *wndPtr = WIN_FindWndPtr( hwnd );
@@ -558,6 +574,7 @@
*/
BOOL X11DRV_SetWindowText( HWND hwnd, LPCWSTR text )
{
+ Display *display = thread_display();
UINT count;
char *buffer;
static UINT text_cp = (UINT)-1;
@@ -604,6 +621,7 @@
*/
HICON X11DRV_SetWindowIcon( HWND hwnd, HICON icon, BOOL small )
{
+ Display *display = thread_display();
WND *wndPtr = WIN_FindWndPtr( hwnd );
int index = small ? GCL_HICONSM : GCL_HICON;
HICON old;
@@ -624,7 +642,7 @@
if (!wm_hints) wm_hints = TSXAllocWMHints();
if (wm_hints)
{
- set_icon_hints( wndPtr, wm_hints );
+ set_icon_hints( display, wndPtr, wm_hints );
TSXSetWMHints( display, win, wm_hints );
TSXFree( wm_hints );
}
diff --git a/dlls/x11drv/winpos.c b/dlls/x11drv/winpos.c
index 1f110a5..721bd7b 100644
--- a/dlls/x11drv/winpos.c
+++ b/dlls/x11drv/winpos.c
@@ -405,7 +405,7 @@
}
else
{
- if ((hwnd == GetDesktopWindow()) && (root_window != DefaultRootWindow(display)))
+ if ((hwnd == GetDesktopWindow()) && (root_window != DefaultRootWindow(thread_display())))
hrgnVisible = CreateRectRgn( 0, 0, GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN) );
else
@@ -1280,6 +1280,7 @@
SWP_NOZORDER | (redraw ? 0 : SWP_NOREDRAW) );
#ifdef HAVE_LIBXSHAPE
{
+ Display *display = thread_display();
Window win = X11DRV_WND_GetXWindow(wndPtr);
if (win)
@@ -1474,7 +1475,10 @@
BOOL moved = FALSE;
DWORD dwPoint = GetMessagePos ();
BOOL DragFullWindows = FALSE;
+ BOOL grab;
int iWndsLocks;
+ Display *old_gdi_display = NULL;
+ Display *display = thread_display();
SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
@@ -1563,9 +1567,18 @@
RedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN );
/* grab the server only when moving top-level windows without desktop */
- if ((root_window == DefaultRootWindow(display)) &&
- (wndPtr->parent->hwndSelf == GetDesktopWindow()))
- TSXGrabServer( display );
+ grab = (!DragFullWindows && (root_window == DefaultRootWindow(gdi_display)) &&
+ (wndPtr->parent->hwndSelf == GetDesktopWindow()));
+ if (grab)
+ {
+ wine_tsx11_lock();
+ XSync( gdi_display, False );
+ XGrabServer( display );
+ /* switch gdi display to the thread display, since the server is grabbed */
+ old_gdi_display = gdi_display;
+ gdi_display = display;
+ wine_tsx11_unlock();
+ }
while(1)
{
@@ -1673,9 +1686,14 @@
else
ReleaseDC( 0, hdc );
- if ((root_window == DefaultRootWindow(display)) &&
- (wndPtr->parent->hwndSelf == GetDesktopWindow()))
- TSXUngrabServer( display );
+ if (grab)
+ {
+ wine_tsx11_lock();
+ XSync( display, False );
+ XUngrabServer( display );
+ gdi_display = old_gdi_display;
+ wine_tsx11_unlock();
+ }
if (HOOK_CallHooksA( WH_CBT, HCBT_MOVESIZE, hwnd, (LPARAM)&sizingRect ))
sizingRect = wndPtr->rectWindow;
diff --git a/dlls/x11drv/x11ddraw.c b/dlls/x11drv/x11ddraw.c
index 378cdbd..a867222 100644
--- a/dlls/x11drv/x11ddraw.c
+++ b/dlls/x11drv/x11ddraw.c
@@ -48,6 +48,7 @@
static void GrabPointer(HWND hWnd)
{
+ Display *display = thread_display();
if (hWnd) {
WND *tmpWnd;
Window win;
diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec
index abfdac3..ac91214 100644
--- a/dlls/x11drv/x11drv.spec
+++ b/dlls/x11drv/x11drv.spec
@@ -11,7 +11,6 @@
# USER driver
-@ cdecl UserRepaintDisable(long) X11DRV_UserRepaintDisable
@ cdecl InitKeyboard() X11DRV_InitKeyboard
@ cdecl VkKeyScan(long) X11DRV_VkKeyScan
@ cdecl MapVirtualKey(long long) X11DRV_MapVirtualKey
@@ -32,6 +31,7 @@
@ cdecl DestroyWindow(long) X11DRV_DestroyWindow
@ cdecl GetDC(long long long long) X11DRV_GetDC
@ cdecl EnableWindow(long long) X11DRV_EnableWindow
+@ cdecl MsgWaitForMultipleObjects(long ptr long long) X11DRV_MsgWaitForMultipleObjects
@ cdecl ScrollWindowEx(long long long ptr ptr long ptr long) X11DRV_ScrollWindowEx
@ cdecl SetFocus(long) X11DRV_SetFocus
@ cdecl SetParent(long long) X11DRV_SetParent
@@ -40,7 +40,6 @@
@ cdecl SetWindowIcon(long long long) X11DRV_SetWindowIcon
@ cdecl SetWindowText(long wstr) X11DRV_SetWindowText
@ cdecl SysCommandSizeMove(long long) X11DRV_SysCommandSizeMove
-@ cdecl IsSingleWindow() X11DRV_IsSingleWindow
@ cdecl AcquireClipboard() X11DRV_AcquireClipboard
@ cdecl ReleaseClipboard() X11DRV_ReleaseClipboard
@ cdecl SetClipboardData(long) X11DRV_SetClipboardData
diff --git a/dlls/x11drv/x11drv_main.c b/dlls/x11drv/x11drv_main.c
index a788543..50b0ac2 100644
--- a/dlls/x11drv/x11drv_main.c
+++ b/dlls/x11drv/x11drv_main.c
@@ -33,6 +33,7 @@
#include "debugtools.h"
#include "gdi.h"
+#include "file.h"
#include "options.h"
#include "user.h"
#include "win.h"
@@ -48,7 +49,6 @@
static CRITICAL_SECTION X11DRV_CritSection = CRITICAL_SECTION_INIT;
-Display *display;
Screen *screen;
Visual *visual;
unsigned int screen_width;
@@ -61,6 +61,7 @@
static BOOL synchronous; /* run in synchronous mode? */
static char *desktop_geometry;
+static XVisualInfo *desktop_vi;
#ifdef NO_REENTRANT_X11
static int* (*old_errno_location)(void);
@@ -232,9 +233,8 @@
* window (if it exists). If OpenGL isn't available, the visual is simply
* set to the default visual for the display
*/
-XVisualInfo *desktop_vi = NULL;
#ifdef HAVE_OPENGL
-static void setup_opengl_visual( void )
+static void setup_opengl_visual( Display *display )
{
int err_base, evt_base;
@@ -257,88 +257,13 @@
#endif /* HAVE_OPENGL */
/***********************************************************************
- * create_desktop
- *
- * Create the desktop window for the --desktop mode.
- */
-static void create_desktop( const char *geometry )
-{
- int x = 0, y = 0, flags;
- unsigned int width = 640, height = 480; /* Default size = 640x480 */
- char *name = "Wine desktop";
- XSizeHints *size_hints;
- XWMHints *wm_hints;
- XClassHint *class_hints;
- XSetWindowAttributes win_attr;
- XTextProperty window_name;
- Atom XA_WM_DELETE_WINDOW;
-
- flags = TSXParseGeometry( geometry, &x, &y, &width, &height );
- screen_width = width;
- screen_height = height;
-
- /* Create window */
- win_attr.background_pixel = BlackPixel(display, 0);
- win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
- PointerMotionMask | ButtonPressMask |
- ButtonReleaseMask | EnterWindowMask;
- win_attr.cursor = TSXCreateFontCursor( display, XC_top_left_arrow );
-
- if (desktop_vi != NULL) {
- win_attr.colormap = XCreateColormap(display, RootWindow(display,desktop_vi->screen),
- desktop_vi->visual, AllocNone);
- }
- root_window = TSXCreateWindow( display,
- (desktop_vi == NULL ? DefaultRootWindow(display) : RootWindow(display, desktop_vi->screen)),
- x, y, width, height, 0,
- (desktop_vi == NULL ? CopyFromParent : desktop_vi->depth),
- InputOutput,
- (desktop_vi == NULL ? CopyFromParent : desktop_vi->visual),
- CWBackPixel | CWEventMask | CWCursor | (desktop_vi == NULL ? 0 : CWColormap),
- &win_attr );
-
- /* Set window manager properties */
- size_hints = TSXAllocSizeHints();
- wm_hints = TSXAllocWMHints();
- class_hints = TSXAllocClassHint();
- if (!size_hints || !wm_hints || !class_hints)
- {
- MESSAGE("Not enough memory for window manager hints.\n" );
- ExitProcess(1);
- }
- size_hints->min_width = size_hints->max_width = width;
- size_hints->min_height = size_hints->max_height = height;
- size_hints->flags = PMinSize | PMaxSize;
- if (flags & (XValue | YValue)) size_hints->flags |= USPosition;
- if (flags & (WidthValue | HeightValue)) size_hints->flags |= USSize;
- else size_hints->flags |= PSize;
-
- wm_hints->flags = InputHint | StateHint;
- wm_hints->input = True;
- wm_hints->initial_state = NormalState;
- class_hints->res_name = "wine";
- class_hints->res_class = "Wine";
-
- TSXStringListToTextProperty( &name, 1, &window_name );
- TSXSetWMProperties( display, root_window, &window_name, &window_name,
- NULL, 0, size_hints, wm_hints, class_hints );
- XA_WM_DELETE_WINDOW = TSXInternAtom( display, "WM_DELETE_WINDOW", False );
- TSXSetWMProtocols( display, root_window, &XA_WM_DELETE_WINDOW, 1 );
- TSXFree( size_hints );
- TSXFree( wm_hints );
- TSXFree( class_hints );
-
- /* Map window */
- TSXMapWindow( display, root_window );
-}
-
-
-/***********************************************************************
* X11DRV process initialisation routine
*/
static void process_attach(void)
{
- WND_Driver = &X11DRV_WND_Driver;
+ Display *display;
+
+ WND_Driver = &X11DRV_WND_Driver;
get_server_startup();
setup_options();
@@ -386,7 +311,7 @@
/* If OpenGL is available, change the default visual, etc as necessary */
#ifdef HAVE_OPENGL
- setup_opengl_visual();
+ setup_opengl_visual( display );
#endif /* HAVE_OPENGL */
/* tell the libX11 that we will do input method handling ourselves
@@ -409,7 +334,7 @@
if (desktop_geometry)
{
Options.managed = FALSE;
- create_desktop( desktop_geometry );
+ root_window = X11DRV_create_desktop( desktop_vi, desktop_geometry );
}
/* initialize GDI */
@@ -419,9 +344,6 @@
ExitProcess(1);
}
- /* initialize event handling */
- X11DRV_EVENT_Init();
-
#ifdef HAVE_LIBXXF86VM
/* initialize XVidMode */
X11DRV_XF86VM_Init();
@@ -441,6 +363,24 @@
/***********************************************************************
+ * X11DRV thread termination routine
+ */
+static void thread_detach(void)
+{
+ struct x11drv_thread_data *data = NtCurrentTeb()->driver_data;
+
+ if (data)
+ {
+ CloseHandle( data->display_fd );
+ wine_tsx11_lock();
+ XCloseDisplay( data->display );
+ wine_tsx11_unlock();
+ HeapFree( GetProcessHeap(), 0, data );
+ }
+}
+
+
+/***********************************************************************
* X11DRV process termination routine
*/
static void process_detach(void)
@@ -458,12 +398,11 @@
X11DRV_XF86VM_Cleanup();
#endif
- /* cleanup event handling */
- X11DRV_EVENT_Cleanup();
+ /* FIXME: should detach all threads */
+ thread_detach();
/* cleanup GDI */
X11DRV_GDI_Finalize();
- display = NULL;
/* restore TSX11 locking */
wine_tsx11_lock = old_tsx11_lock;
@@ -477,6 +416,36 @@
/***********************************************************************
+ * X11DRV thread initialisation routine
+ */
+struct x11drv_thread_data *x11drv_init_thread_data(void)
+{
+ struct x11drv_thread_data *data;
+
+ if (!(data = HeapAlloc( GetProcessHeap(), 0, sizeof(*data) )))
+ {
+ ERR( "could not create data\n" );
+ ExitProcess(1);
+ }
+ wine_tsx11_lock();
+ if (!(data->display = XOpenDisplay(NULL)))
+ {
+ wine_tsx11_unlock();
+ MESSAGE( "x11drv: Can't open display: %s\n", XDisplayName(NULL) );
+ ExitProcess(1);
+ }
+ fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
+ if (synchronous) XSynchronize( data->display, True );
+ wine_tsx11_unlock();
+ data->display_fd = FILE_DupUnixHandle( ConnectionNumber(data->display),
+ GENERIC_READ | SYNCHRONIZE );
+ data->process_event_count = 0;
+ NtCurrentTeb()->driver_data = data;
+ return data;
+}
+
+
+/***********************************************************************
* X11DRV initialisation routine
*/
BOOL WINAPI X11DRV_Init( HINSTANCE hinst, DWORD reason, LPVOID reserved )
@@ -486,6 +455,9 @@
case DLL_PROCESS_ATTACH:
process_attach();
break;
+ case DLL_THREAD_DETACH:
+ thread_detach();
+ break;
case DLL_PROCESS_DETACH:
process_detach();
break;
@@ -542,11 +514,3 @@
if (nTimeout>32767) nTimeout = 32767;
TSXSetScreenSaver(gdi_display, nTimeout, 60, DefaultBlanking, DefaultExposures);
}
-
-/***********************************************************************
- * X11DRV_IsSingleWindow
- */
-BOOL X11DRV_IsSingleWindow(void)
-{
- return (root_window != DefaultRootWindow(gdi_display));
-}
diff --git a/include/thread.h b/include/thread.h
index 264c2fb..6f46457 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -101,10 +101,11 @@
void *debug_info; /* --3 21c Info for debugstr functions */
void *pthread_data; /* --3 220 Data for pthread emulation */
struct async_private *pending_list; /* --3 224 list of pending async operations */
+ void *driver_data; /* --3 228 Graphics driver private data */
/* here is plenty space for wine specific fields (don't forget to change pad6!!) */
/* the following are nt specific fields */
- DWORD pad6[628]; /* --n 228 */
+ DWORD pad6[627]; /* --n 22c */
UNICODE_STRING StaticUnicodeString; /* -2- bf8 used by advapi32 */
USHORT StaticUnicodeBuffer[261]; /* -2- c00 used by advapi32 */
DWORD pad7; /* --n e0c */
diff --git a/include/user.h b/include/user.h
index 6837989..8e1b92e 100644
--- a/include/user.h
+++ b/include/user.h
@@ -38,8 +38,6 @@
struct tagWND;
typedef struct tagUSER_DRIVER {
- /* event functions */
- void (*pUserRepaintDisable)(BOOL);
/* keyboard functions */
void (*pInitKeyboard)(void);
WORD (*pVkKeyScan)(CHAR);
@@ -75,6 +73,7 @@
BOOL (*pDestroyWindow)(HWND);
BOOL (*pGetDC)(HWND,HDC,HRGN,DWORD);
BOOL (*pEnableWindow)(HWND,BOOL);
+ DWORD (*pMsgWaitForMultipleObjects)(DWORD,HANDLE*,BOOL,DWORD);
INT (*pScrollWindowEx)(HWND,INT,INT,const RECT*,const RECT*,HRGN,LPRECT,UINT);
void (*pSetFocus)(HWND);
HWND (*pSetParent)(HWND,HWND);
@@ -83,7 +82,6 @@
HICON (*pSetWindowIcon)(HWND,HICON,BOOL);
BOOL (*pSetWindowText)(HWND,LPCWSTR);
void (*pSysCommandSizeMove)(HWND,WPARAM);
- BOOL (*pIsSingleWindow)(void);
} USER_DRIVER;
extern USER_DRIVER USER_Driver;
diff --git a/include/x11drv.h b/include/x11drv.h
index 0006cef..ea8c479 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -19,12 +19,11 @@
#include "winbase.h"
#include "gdi.h"
#include "user.h"
+#include "thread.h"
#define MAX_PIXELFORMATS 8
struct tagBITMAPOBJ;
-struct tagCLASS;
-struct tagCREATESTRUCTA;
struct tagCURSORICONINFO;
struct tagDC;
struct tagDeviceCaps;
@@ -304,18 +303,32 @@
* X11 USER driver
*/
-extern Display *display;
-extern Screen *screen;
+struct x11drv_thread_data
+{
+ Display *display;
+ HANDLE display_fd;
+ int process_event_count;
+};
+
+extern struct x11drv_thread_data *x11drv_init_thread_data(void);
+
+inline static struct x11drv_thread_data *x11drv_thread_data(void)
+{
+ struct x11drv_thread_data *data = NtCurrentTeb()->driver_data;
+ if (!data) data = x11drv_init_thread_data();
+ return data;
+}
+
+inline static Display *thread_display(void) { return x11drv_thread_data()->display; }
+
extern Visual *visual;
extern Window root_window;
extern unsigned int screen_width;
extern unsigned int screen_height;
extern unsigned int screen_depth;
-static inline Screen *X11DRV_GetXScreen(void) { return screen; }
static inline Visual *X11DRV_GetVisual(void) { return visual; }
static inline Window X11DRV_GetXRootWindow(void) { return root_window; }
-static inline unsigned int X11DRV_GetDepth(void) { return screen_depth; }
/* X11 clipboard driver */
@@ -332,8 +345,6 @@
extern WORD X11DRV_EVENT_XStateToKeyState( int state ) ;
-extern void X11DRV_EVENT_Init(void);
-extern void X11DRV_EVENT_Cleanup(void);
extern void X11DRV_Synchronize( void );
typedef enum {
@@ -388,5 +399,10 @@
extern BOOL X11DRV_WND_SetHostAttr(struct tagWND *wndPtr, INT haKey, INT value);
extern void X11DRV_SetFocus( HWND hwnd );
+extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr );
+
+extern void X11DRV_register_window( Display *display, HWND hwnd, Window win );
+extern void X11DRV_create_desktop_thread(void);
+extern Window X11DRV_create_desktop( XVisualInfo *desktop_vi, const char *geometry );
#endif /* __WINE_X11DRV_H */
diff --git a/windows/message.c b/windows/message.c
index 5a22e67..5648db3 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -22,6 +22,7 @@
#include "dde.h"
#include "queue.h"
#include "winproc.h"
+#include "user.h"
#include "thread.h"
#include "options.h"
#include "controls.h"
@@ -147,7 +148,7 @@
/* stop if not the right queue */
- if (pWnd->hmemTaskQ != hQ)
+ if (pWnd->hmemTaskQ && pWnd->hmemTaskQ != hQ)
{
/* Not for the current task */
if (queue) QUEUE_ClearWakeBit( queue, QS_MOUSE );
@@ -377,7 +378,7 @@
if ( !hWnd ) return SYSQ_MSG_ABANDON;
pWnd = WIN_FindWndPtr( hWnd );
- if (pWnd && (pWnd->hmemTaskQ != GetFastQueue16()))
+ if (pWnd && pWnd->hmemTaskQ && (pWnd->hmemTaskQ != GetFastQueue16()))
{
/* Not for the current task */
MESSAGEQUEUE *queue = QUEUE_Lock( GetFastQueue16() );
@@ -1252,6 +1253,10 @@
#if 0 /* FIXME */
if (!(flags & PM_NOYIELD)) UserYield16();
#endif
+ /* check for graphics events */
+ if (USER_Driver.pMsgWaitForMultipleObjects)
+ USER_Driver.pMsgWaitForMultipleObjects( 0, NULL, FALSE, 0 );
+
QUEUE_Unlock( msgQueue );
WIN_RestoreWndsLock(iWndsLocks);
return FALSE;
@@ -1860,7 +1865,7 @@
else
SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wParam, lParam );
- if (wndPtr->hmemTaskQ != GetFastQueue16())
+ if (wndPtr->hmemTaskQ && wndPtr->hmemTaskQ != GetFastQueue16())
ret = MSG_SendMessageInterThread( wndPtr->hmemTaskQ, hwnd, msg,
wParam, lParam, timeout, flags, pRes );
else
@@ -2064,7 +2069,13 @@
/* Add the thread event to the handle list */
for (i = 0; i < nCount; i++) handles[i] = pHandles[i];
handles[nCount] = msgQueue->server_queue;
- ret = WaitForMultipleObjects( nCount+1, handles, fWaitAll, dwMilliseconds );
+ if (USER_Driver.pMsgWaitForMultipleObjects)
+ {
+ ret = USER_Driver.pMsgWaitForMultipleObjects(nCount+1, handles, fWaitAll, dwMilliseconds);
+ if (ret == nCount+1) ret = nCount; /* pretend the msg queue is ready */
+ }
+ else
+ ret = WaitForMultipleObjects( nCount+1, handles, fWaitAll, dwMilliseconds );
QUEUE_Unlock( msgQueue );
return ret;
diff --git a/windows/queue.c b/windows/queue.c
index 14a55ce..b66c53b 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -13,6 +13,7 @@
#include "wine/winuser16.h"
#include "queue.h"
#include "win.h"
+#include "user.h"
#include "hook.h"
#include "thread.h"
#include "debugtools.h"
@@ -731,12 +732,16 @@
}
queue->wakeMask = bits | QS_SENDMESSAGE;
- TRACE_(msg)("%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask);
+ TRACE_(msg)("%04x: wakeMask is %04x, waiting\n", queue->self, queue->wakeMask);
LeaveCriticalSection( &queue->cSection );
ReleaseThunkLock( &dwlc );
if (dwlc) TRACE_(msg)("had win16 lock\n");
- WaitForSingleObject( queue->server_queue, timeout );
+
+ if (USER_Driver.pMsgWaitForMultipleObjects)
+ USER_Driver.pMsgWaitForMultipleObjects( 1, &queue->server_queue, FALSE, timeout );
+ else
+ WaitForSingleObject( queue->server_queue, timeout );
if (dwlc) RestoreThunkLock( dwlc );
}
}
@@ -1095,6 +1100,7 @@
}
+#if 0
/***********************************************************************
* QUEUE_WakeSomeone
*
@@ -1161,6 +1167,7 @@
WARN_(msg)("couldn't find queue\n");
}
+#endif
/***********************************************************************
@@ -1174,6 +1181,7 @@
{
MSG *msg;
QMSG *qmsg;
+ MESSAGEQUEUE *queue;
int mergeMsg = 0;
if (!sysMsgQueue) return;
@@ -1237,10 +1245,19 @@
LeaveCriticalSection( &sysMsgQueue->cSection );
- QUEUE_WakeSomeone( message );
+ if ((queue = QUEUE_Lock( GetFastQueue16() )))
+ {
+ WORD wakeBit;
+
+ if ((message >= WM_KEYFIRST) && (message <= WM_KEYLAST)) wakeBit = QS_KEY;
+ else wakeBit = (message == WM_MOUSEMOVE) ? QS_MOUSEMOVE : QS_MOUSEBUTTON;
+
+ QUEUE_SetWakeBit( queue, wakeBit );
+ QUEUE_Unlock( queue );
+ }
}
-
+
/***********************************************************************
* QUEUE_GetQueueTask
*/
diff --git a/windows/user.c b/windows/user.c
index f012e91..7dba9ae 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -13,7 +13,6 @@
#include "winuser.h"
#include "heap.h"
#include "user.h"
-#include "task.h"
#include "queue.h"
#include "win.h"
#include "controls.h"
@@ -101,56 +100,6 @@
CURSORICON_FreeModuleIcons( hModule );
}
-/**********************************************************************
- * USER_QueueCleanup
- */
-static void USER_QueueCleanup( HQUEUE16 hQueue )
-{
- if ( hQueue )
- {
- WND* desktop = WIN_GetDesktop();
-
- /* Patch desktop window */
- if ( desktop->hmemTaskQ == hQueue )
- {
- HTASK16 nextTask = TASK_GetNextTask( GetCurrentTask() );
- desktop->hmemTaskQ = GetTaskQueue16( nextTask );
- }
-
- TIMER_RemoveQueueTimers( hQueue );
-
- HOOK_FreeQueueHooks( hQueue );
-
- QUEUE_SetExitingQueue( hQueue );
- WIN_ResetQueueWindows( desktop, hQueue, (HQUEUE16)0);
- QUEUE_SetExitingQueue( 0 );
-
- /* Free the message queue */
- QUEUE_DeleteMsgQueue( hQueue );
-
- WIN_ReleaseDesktop();
- }
-}
-
-/**********************************************************************
- * USER_AppExit
- */
-static void USER_AppExit(void)
-{
- HINSTANCE16 hInstance = MapHModuleLS(0);
-
- /* FIXME: maybe destroy menus (Windows only complains about them
- * but does nothing);
- */
-
- /* ModuleUnload() in "Internals" */
-
- hInstance = GetExePtr( hInstance );
- if( GetModuleUsage16( hInstance ) <= 1 )
- USER_ModuleUnload( hInstance );
-}
-
-
/***********************************************************************
* SignalProc (USER.314)
*/
@@ -190,34 +139,16 @@
break;
case USIG_DLL_UNLOAD_ORPHANS:
- break;
-
case USIG_FAULT_DIALOG_PUSH:
case USIG_FAULT_DIALOG_POP:
- break;
-
case USIG_THREAD_INIT:
- break;
-
case USIG_THREAD_EXIT:
- USER_QueueCleanup( GetThreadQueue16( dwThreadOrProcessID ) );
- SetThreadQueue16( dwThreadOrProcessID, 0 );
- break;
-
case USIG_PROCESS_CREATE:
- break;
-
case USIG_PROCESS_INIT:
case USIG_PROCESS_LOADED:
- break;
case USIG_PROCESS_RUNNING:
- break;
-
case USIG_PROCESS_EXIT:
- break;
-
case USIG_PROCESS_DESTROY:
- USER_AppExit();
break;
default:
diff --git a/windows/win.c b/windows/win.c
index f16ff60..a31f756 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -359,6 +359,7 @@
* The real reason why is because Windows DesktopWndProc
* does ValidateRgn inside WM_ERASEBKGND handler.
*/
+ if (hwnd == GetDesktopWindow()) hwnd = 0;
pWnd = hwnd ? WIN_FindWndPtr(hwnd) : WIN_LockWndPtr(pWndDesktop->child);
@@ -601,7 +602,7 @@
pWndDesktop->rectWindow.bottom = GetSystemMetrics(SM_CYSCREEN);
pWndDesktop->rectClient = pWndDesktop->rectWindow;
pWndDesktop->text = NULL;
- pWndDesktop->hmemTaskQ = GetFastQueue16();
+ pWndDesktop->hmemTaskQ = 0;
pWndDesktop->hrgnUpdate = 0;
pWndDesktop->hwndLastActive = hwndDesktop;
pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
diff --git a/windows/winpos.c b/windows/winpos.c
index ce533d1..500391b 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -1987,13 +1987,7 @@
bRet = WINPOS_SetActiveWindow( pWndTo ? pWndTo->hwndSelf : 0, FALSE, TRUE );
- /* switch desktop queue to current active */
- if( pWndTo )
- {
- WIN_GetDesktop()->hmemTaskQ = pWndTo->hmemTaskQ;
- WIN_ReleaseWndPtr(pWndTo);
- WIN_ReleaseDesktop();
- }
+ if( pWndTo ) WIN_ReleaseWndPtr(pWndTo);
hwndPrevActive = 0;
return bRet;
@@ -2005,7 +1999,7 @@
*/
BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg )
{
- WND *wndPtr, *wndTemp;
+ WND *wndPtr;
BOOL retvalue;
HWND hwndActive = 0;
@@ -2045,12 +2039,6 @@
goto end;
}
- /* switch desktop queue to current active */
- wndTemp = WIN_GetDesktop();
- if( wndPtr->parent == wndTemp)
- wndTemp->hmemTaskQ = wndPtr->hmemTaskQ;
- WIN_ReleaseDesktop();
-
retvalue = TRUE;
end:
WIN_ReleaseWndPtr(wndPtr);
diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c
index aece6ca..b0b7f13 100644
--- a/windows/x11drv/clipboard.c
+++ b/windows/x11drv/clipboard.c
@@ -176,7 +176,7 @@
if (fmtName)
{
strncat(str, fmtName, sizeof(str) - strlen(FMT_PREFIX));
- prop = TSXInternAtom(display, str, False);
+ prop = TSXInternAtom(thread_display(), str, False);
}
break;
}
@@ -196,7 +196,7 @@
*/
BOOL X11DRV_CLIPBOARD_IsNativeProperty(Atom prop)
{
- char *itemFmtName = TSXGetAtomName(display, prop);
+ char *itemFmtName = TSXGetAtomName(thread_display(), prop);
BOOL bRet = FALSE;
if ( 0 == strncmp(itemFmtName, FMT_PREFIX, strlen(FMT_PREFIX)) )
@@ -217,6 +217,7 @@
BOOL X11DRV_CLIPBOARD_LaunchServer()
{
int iWndsLocks;
+ char clearSelection[8];
/* If persistant selection has been disabled in the .winerc Clipboard section,
* don't launch the server
@@ -224,6 +225,9 @@
if ( !PROFILE_GetWineIniInt("Clipboard", "PersistentSelection", 1) )
return FALSE;
+ /* Get the clear selection preference */
+ sprintf(clearSelection, "%d", PROFILE_GetWineIniInt("Clipboard", "ClearAllSelections", 0));
+
/* Start up persistant WINE X clipboard server process which will
* take ownership of the X selection and continue to service selection
* requests from other apps.
@@ -234,16 +238,8 @@
/* NOTE: This code only executes in the context of the child process
* Do note make any Wine specific calls here.
*/
-
int dbgClasses = 0;
- char selMask[8], dbgClassMask[8], clearSelection[8];
- int i;
-
- /* Don't inherit wine's X sockets to the wineclipsrv, otherwise
- * windows stay around when you have to kill a hanging wine...
- */
- for (i = 3; i < 256; ++i)
- fcntl(i, F_SETFD, 1);
+ char selMask[8], dbgClassMask[8];
sprintf(selMask, "%d", selectionAcquired);
@@ -256,10 +252,6 @@
dbgClasses |= TRACE_ON(clipboard) ? 8 : 0;
sprintf(dbgClassMask, "%d", dbgClasses);
- /* Get the clear selection preference */
- sprintf(clearSelection, "%d",
- PROFILE_GetWineIniInt("Clipboard", "ClearAllSelections", 0));
-
/* Exec the clipboard server passing it the selection and debug class masks */
execl( BINDIR "/wineclipsrv", "wineclipsrv",
selMask, dbgClassMask, clearSelection, NULL );
@@ -295,7 +287,7 @@
TRACE("Waiting for clipboard server to acquire selection\n");
- if ( WaitForSingleObject( selectionClearEvent, 60000 ) != WAIT_OBJECT_0 )
+ if ( MsgWaitForMultipleObjects( 1, &selectionClearEvent, FALSE, 60000, QS_ALLINPUT ) != WAIT_OBJECT_0 )
TRACE("Server could not acquire selection, or a timeout occurred!\n");
else
TRACE("Server successfully acquired selection\n");
@@ -320,6 +312,7 @@
*/
int X11DRV_CLIPBOARD_CacheDataFormats( Atom SelectionName )
{
+ Display *display = thread_display();
HWND hWnd = 0;
HWND hWndClipWindow = GetOpenClipboardWindow();
WND* wnd = NULL;
@@ -458,6 +451,7 @@
*/
static BOOL X11DRV_CLIPBOARD_ReadSelection(UINT wFormat, Window w, Atom prop, Atom reqType)
{
+ Display *display = thread_display();
Atom atype=AnyPropertyType;
int aformat;
unsigned long total,nitems,remain,itemSize,val_cnt;
@@ -685,6 +679,7 @@
*/
void X11DRV_CLIPBOARD_ReleaseSelection(Atom selType, Window w, HWND hwnd)
{
+ Display *display = thread_display();
Atom xaClipboard = TSXInternAtom(display, "CLIPBOARD", False);
int clearAllSelections = PROFILE_GetWineIniInt("Clipboard", "ClearAllSelections", 0);
@@ -797,6 +792,7 @@
*/
void X11DRV_ReleaseClipboard(void)
{
+ Display *display = thread_display();
if( selectionAcquired )
{
XEvent xe;
@@ -847,6 +843,7 @@
*/
void X11DRV_AcquireClipboard(void)
{
+ Display *display = thread_display();
Window owner;
HWND hWndClipWindow = GetOpenClipboardWindow();
@@ -900,6 +897,7 @@
*/
BOOL X11DRV_IsClipboardFormatAvailable(UINT wFormat)
{
+ Display *display = thread_display();
Atom xaClipboard = TSXInternAtom(display, _CLIPBOARD, False);
Window ownerPrimary = TSXGetSelectionOwner(display,XA_PRIMARY);
Window ownerClipboard = TSXGetSelectionOwner(display,xaClipboard);
@@ -957,6 +955,7 @@
*/
BOOL X11DRV_RegisterClipboardFormat( LPCSTR FormatName )
{
+ Display *display = thread_display();
Atom prop = None;
char str[256];
@@ -1009,6 +1008,7 @@
*/
BOOL X11DRV_GetClipboardData(UINT wFormat)
{
+ Display *display = thread_display();
BOOL bRet = selectionAcquired;
HWND hWndClipWindow = GetOpenClipboardWindow();
HWND hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow();
@@ -1087,6 +1087,7 @@
*/
void X11DRV_ResetSelectionOwner(WND *pWnd, BOOL bFooBar)
{
+ Display *display = thread_display();
HWND hWndClipOwner = 0;
Window XWnd = X11DRV_WND_GetXWindow(pWnd);
Atom xaClipboard;
diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c
index ef1c597..743f894 100644
--- a/windows/x11drv/event.c
+++ b/windows/x11drv/event.c
@@ -34,7 +34,6 @@
#include "queue.h"
#include "win.h"
#include "winpos.h"
-#include "services.h"
#include "file.h"
#include "windef.h"
#include "x11drv.h"
@@ -87,8 +86,6 @@
};
-static void CALLBACK EVENT_Flush( ULONG_PTR arg );
-static void CALLBACK EVENT_ProcessAllEvents( ULONG_PTR arg );
static void EVENT_ProcessEvent( XEvent *event );
static BOOL X11DRV_CheckFocus(void);
@@ -129,60 +126,21 @@
static void EVENT_EnterNotify( HWND hWnd, XCrossingEvent *event );
*/
-static void EVENT_GetGeometry( Window win, int *px, int *py,
+static void EVENT_GetGeometry( Display *display, Window win, int *px, int *py,
unsigned int *pwidth, unsigned int *pheight );
-static BOOL bUserRepaintDisabled = TRUE;
-
/* Static used for the current input method */
static INPUT_TYPE current_input_type = X11DRV_INPUT_ABSOLUTE;
static BOOL in_transition = FALSE; /* This is not used as for today */
-static HANDLE service_object, service_timer;
/***********************************************************************
- * EVENT_Init
+ * process_events
*/
-void X11DRV_EVENT_Init(void)
-{
- /* Install the X event processing callback */
- if ((service_object = SERVICE_AddObject( FILE_DupUnixHandle( ConnectionNumber(display), GENERIC_READ|SYNCHRONIZE ),
- EVENT_ProcessAllEvents, 0 )) == INVALID_HANDLE_VALUE)
- {
- ERR("cannot add service object\n");
- ExitProcess(1);
- }
-
- /* Install the XFlush timer callback */
- service_timer = SERVICE_AddTimer( 200, EVENT_Flush, 0 );
-}
-
-/***********************************************************************
- * X11DRV_EVENT_Cleanup
- */
-void X11DRV_EVENT_Cleanup(void)
-{
- SERVICE_Delete( service_timer );
- SERVICE_Delete( service_object );
-}
-
-/***********************************************************************
- * EVENT_Flush
- */
-static void CALLBACK EVENT_Flush( ULONG_PTR arg )
-{
- TSXFlush( display );
-}
-
-/***********************************************************************
- * EVENT_ProcessAllEvents
- */
-static void CALLBACK EVENT_ProcessAllEvents( ULONG_PTR arg )
+static void process_events( Display *display )
{
XEvent event;
-
- TRACE( "called (thread %lx).\n", GetCurrentThreadId() );
wine_tsx11_lock();
while ( XPending( display ) )
@@ -196,24 +154,46 @@
}
/***********************************************************************
- * Synchronize (X11DRV.@)
+ * X11DRV_Synchronize
*
* Synchronize with the X server. Should not be used too often.
*/
void X11DRV_Synchronize( void )
{
+ Display *display = thread_display();
TSXSync( display, False );
- EVENT_ProcessAllEvents( 0 );
+ process_events( display );
}
+
/***********************************************************************
- * UserRepaintDisable (X11DRV.@)
+ * MsgWaitForMultipleObjects (X11DRV.@)
*/
-void X11DRV_UserRepaintDisable( BOOL bDisabled )
+DWORD X11DRV_MsgWaitForMultipleObjects( DWORD count, HANDLE *handles,
+ BOOL wait_all, DWORD timeout )
{
- bUserRepaintDisabled = bDisabled;
+ HANDLE new_handles[MAXIMUM_WAIT_OBJECTS+1]; /* FIXME! */
+ DWORD i, ret;
+ struct x11drv_thread_data *data = NtCurrentTeb()->driver_data;
+
+ if (!data || data->process_event_count)
+ return WaitForMultipleObjects( count, handles, wait_all, timeout );
+
+ for (i = 0; i < count; i++) new_handles[i] = handles[i];
+ new_handles[count] = data->display_fd;
+
+ data->process_event_count++;
+ wine_tsx11_lock();
+ XFlush( gdi_display );
+ XFlush( data->display );
+ wine_tsx11_unlock();
+ ret = WaitForMultipleObjects( count+1, new_handles, wait_all, timeout );
+ if (ret == count) process_events( data->display );
+ data->process_event_count--;
+ return ret;
}
+
/***********************************************************************
* EVENT_ProcessEvent
*
@@ -222,6 +202,7 @@
static void EVENT_ProcessEvent( XEvent *event )
{
HWND hWnd;
+ Display *display = event->xany.display;
TRACE( "called.\n" );
@@ -302,7 +283,7 @@
Window root, child;
int root_x, root_y, child_x, child_y;
unsigned u;
- TSXQueryPointer( display, X11DRV_GetXRootWindow(), &root, &child,
+ TSXQueryPointer( display, root_window, &root, &child,
&root_x, &root_y, &child_x, &child_y, &u);
if (TSXFindContext( display, child, winContext, (char **)&hWnd ) != 0)
return;
@@ -311,7 +292,7 @@
}
}
- if ( !hWnd && event->xany.window != X11DRV_GetXRootWindow()
+ if ( !hWnd && event->xany.window != root_window
&& event->type != PropertyNotify
&& event->type != MappingNotify)
ERR("Got event %s for unknown Window %08lx\n",
@@ -359,7 +340,7 @@
BOOL bIsDisabled;
XFocusChangeEvent *xfocChange = (XFocusChangeEvent*)event;
- if (!hWnd || bUserRepaintDisabled) return;
+ if (!hWnd) return;
bIsDisabled = GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED;
@@ -393,34 +374,32 @@
/* Save the last window which had the focus */
XFocusChangeEvent *xfocChange = (XFocusChangeEvent*)event;
glastXFocusWin = xfocChange->window;
- if (!hWnd || bUserRepaintDisabled) return;
+ if (!hWnd) return;
if (GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED) glastXFocusWin = 0;
EVENT_FocusOut( hWnd, (XFocusChangeEvent*)event );
break;
}
case Expose:
- if (bUserRepaintDisabled) return;
EVENT_Expose( hWnd, (XExposeEvent *)event );
break;
case GraphicsExpose:
- if (bUserRepaintDisabled) return;
EVENT_GraphicsExpose( hWnd, (XGraphicsExposeEvent *)event );
break;
case ConfigureNotify:
- if (!hWnd || bUserRepaintDisabled) return;
+ if (!hWnd) return;
EVENT_ConfigureNotify( hWnd, (XConfigureEvent*)event );
break;
case SelectionRequest:
- if (!hWnd || bUserRepaintDisabled) return;
+ if (!hWnd) return;
EVENT_SelectionRequest( hWnd, (XSelectionRequestEvent *)event, FALSE );
break;
case SelectionClear:
- if (!hWnd || bUserRepaintDisabled) return;
+ if (!hWnd) return;
EVENT_SelectionClear( hWnd, (XSelectionClearEvent*) event );
break;
@@ -429,7 +408,7 @@
break;
case ClientMessage:
- if (!hWnd || bUserRepaintDisabled) return;
+ if (!hWnd) return;
EVENT_ClientMessage( hWnd, (XClientMessageEvent *) event );
break;
@@ -443,12 +422,12 @@
break;
case MapNotify:
- if (!hWnd || bUserRepaintDisabled) return;
+ if (!hWnd) return;
EVENT_MapNotify( hWnd, (XMapEvent *)event );
break;
case UnmapNotify:
- if (!hWnd || bUserRepaintDisabled) return;
+ if (!hWnd) return;
EVENT_UnmapNotify( hWnd, (XUnmapEvent *)event );
break;
@@ -483,7 +462,7 @@
return ((*pWndB) != NULL);
}
-static Window __get_common_ancestor( Window A, Window B,
+static Window __get_common_ancestor( Display *display, Window A, Window B,
Window** children, unsigned* total )
{
/* find the real root window */
@@ -507,7 +486,7 @@
return 0 ;
}
-static Window __get_top_decoration( Window w, Window ancestor )
+static Window __get_top_decoration( Display *display, Window w, Window ancestor )
{
Window* children, root, prev = w, parent = w;
unsigned total;
@@ -529,7 +508,7 @@
return i;
}
-static HWND EVENT_QueryZOrder( HWND hWndCheck)
+static HWND EVENT_QueryZOrder( Display *display, HWND hWndCheck)
{
HWND hwndInsertAfter = HWND_TOP;
WND *pWndCheck = WIN_FindWndPtr(hWndCheck);
@@ -550,14 +529,14 @@
WIN_ReleaseWndPtr(pDesktop->child);
WIN_ReleaseDesktop();
- parent = __get_common_ancestor( X11DRV_WND_GetXWindow(pWndZ),
+ parent = __get_common_ancestor( display, X11DRV_WND_GetXWindow(pWndZ),
X11DRV_WND_GetXWindow(pWnd),
&children, &total );
if( parent && children )
{
/* w is the ancestor if pWndCheck that is a direct descendant of 'parent' */
- w = __get_top_decoration( X11DRV_WND_GetXWindow(pWndCheck), parent );
+ w = __get_top_decoration( display, X11DRV_WND_GetXWindow(pWndCheck), parent );
if( w != children[total-1] ) /* check if at the top */
{
@@ -572,7 +551,7 @@
if( pWnd != pWndCheck )
{
if( !(pWnd->dwExStyle & WS_EX_MANAGED) ||
- !(w = __get_top_decoration( X11DRV_WND_GetXWindow(pWnd), parent )) )
+ !(w = __get_top_decoration( display, X11DRV_WND_GetXWindow(pWnd), parent )) )
continue;
pos = __td_lookup( w, children, total );
if( pos < best && pos > check )
@@ -856,6 +835,7 @@
*/
static BOOL X11DRV_CheckFocus(void)
{
+ Display *display = thread_display();
HWND hWnd;
Window xW;
int state;
@@ -873,7 +853,7 @@
* Helper function for ConfigureNotify handling.
* Get the new geometry of a window relative to the root window.
*/
-static void EVENT_GetGeometry( Window win, int *px, int *py,
+static void EVENT_GetGeometry( Display *display, Window win, int *px, int *py,
unsigned int *pwidth, unsigned int *pheight )
{
Window root, top;
@@ -911,8 +891,8 @@
/* Get geometry and Z-order according to X */
- EVENT_GetGeometry( event->window, &x, &y, &width, &height );
- newInsertAfter = EVENT_QueryZOrder( hWnd );
+ EVENT_GetGeometry( event->display, event->window, &x, &y, &width, &height );
+ newInsertAfter = EVENT_QueryZOrder( event->display, hWnd );
/* Get geometry and Z-order according to Wine */
@@ -966,7 +946,8 @@
* EVENT_SelectionRequest_TARGETS
* Service a TARGETS selection request event
*/
-static Atom EVENT_SelectionRequest_TARGETS( Window requestor, Atom target, Atom rprop )
+static Atom EVENT_SelectionRequest_TARGETS( Display *display, Window requestor,
+ Atom target, Atom rprop )
{
Atom xaTargets = TSXInternAtom(display, "TARGETS", False);
Atom* targets;
@@ -1057,7 +1038,8 @@
* EVENT_SelectionRequest_STRING
* Service a STRING selection request event
*/
-static Atom EVENT_SelectionRequest_STRING( Window requestor, Atom target, Atom rprop )
+static Atom EVENT_SelectionRequest_STRING( Display *display, Window requestor,
+ Atom target, Atom rprop )
{
static UINT text_cp = (UINT)-1;
HANDLE hUnicodeText;
@@ -1123,7 +1105,8 @@
* EVENT_SelectionRequest_PIXMAP
* Service a PIXMAP selection request event
*/
-static Atom EVENT_SelectionRequest_PIXMAP( Window requestor, Atom target, Atom rprop )
+static Atom EVENT_SelectionRequest_PIXMAP( Display *display, Window requestor,
+ Atom target, Atom rprop )
{
HANDLE hClipData = 0;
Pixmap pixmap = 0;
@@ -1222,7 +1205,8 @@
* Service a Wine Clipboard Format selection request event.
* For <WCF>* data types we simply copy the data to X without conversion.
*/
-static Atom EVENT_SelectionRequest_WCF( Window requestor, Atom target, Atom rprop )
+static Atom EVENT_SelectionRequest_WCF( Display *display, Window requestor,
+ Atom target, Atom rprop )
{
HANDLE hClipData = 0;
void* lpClipData;
@@ -1281,6 +1265,7 @@
*/
static Atom EVENT_SelectionRequest_MULTIPLE( HWND hWnd, XSelectionRequestEvent *pevent )
{
+ Display *display = pevent->display;
Atom rprop;
Atom atype=AnyPropertyType;
int aformat;
@@ -1375,6 +1360,7 @@
*/
static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple )
{
+ Display *display = event->display;
XSelectionEvent result;
Atom rprop = None;
Window request = event->requestor;
@@ -1406,32 +1392,32 @@
if(event->target == xaTargets) /* Return a list of all supported targets */
{
/* TARGETS selection request */
- rprop = EVENT_SelectionRequest_TARGETS( request, event->target, rprop );
+ rprop = EVENT_SelectionRequest_TARGETS( display, request, event->target, rprop );
}
else if(event->target == xaMultiple) /* rprop contains a list of (target, property) atom pairs */
{
/* MULTIPLE selection request */
- rprop = EVENT_SelectionRequest_MULTIPLE( hWnd, event );
+ rprop = EVENT_SelectionRequest_MULTIPLE( hWnd, event );
}
else if(event->target == XA_STRING) /* treat CF_TEXT as Unix text */
{
/* XA_STRING selection request */
- rprop = EVENT_SelectionRequest_STRING( request, event->target, rprop );
+ rprop = EVENT_SelectionRequest_STRING( display, request, event->target, rprop );
}
else if(event->target == XA_PIXMAP) /* Convert DIB's to Pixmaps */
{
/* XA_PIXMAP selection request */
- rprop = EVENT_SelectionRequest_PIXMAP( request, event->target, rprop );
+ rprop = EVENT_SelectionRequest_PIXMAP( display, request, event->target, rprop );
}
else if(event->target == XA_BITMAP) /* Convert DIB's to 1-bit Pixmaps */
{
/* XA_BITMAP selection request - TODO: create a monochrome Pixmap */
- rprop = EVENT_SelectionRequest_PIXMAP( request, XA_PIXMAP, rprop );
+ rprop = EVENT_SelectionRequest_PIXMAP( display, request, XA_PIXMAP, rprop );
}
else if(X11DRV_CLIPBOARD_IsNativeProperty(event->target)) /* <WCF>* */
{
/* All <WCF> selection requests */
- rprop = EVENT_SelectionRequest_WCF( request, event->target, rprop );
+ rprop = EVENT_SelectionRequest_WCF( display, request, event->target, rprop );
}
else
rprop = None; /* Don't support this format */
@@ -1465,7 +1451,7 @@
*/
static void EVENT_SelectionClear( HWND hWnd, XSelectionClearEvent *event )
{
- Atom xaClipboard = TSXInternAtom(display, "CLIPBOARD", False);
+ Atom xaClipboard = TSXInternAtom(event->display, "CLIPBOARD", False);
if (event->selection == XA_PRIMARY || event->selection == xaClipboard)
X11DRV_CLIPBOARD_ReleaseSelection( event->selection, event->window, hWnd );
@@ -1536,7 +1522,7 @@
pWnd = WIN_FindWndPtr(hWnd);
- TSXQueryPointer( display, X11DRV_WND_GetXWindow(pWnd), &w_aux_root, &w_aux_child,
+ TSXQueryPointer( event->display, X11DRV_WND_GetXWindow(pWnd), &w_aux_root, &w_aux_child,
&x, &y, (int *) &u.pt_aux.x, (int *) &u.pt_aux.y,
(unsigned int*)&aux_long);
@@ -1560,7 +1546,7 @@
if( bAccept )
{
- TSXGetWindowProperty( display, DefaultRootWindow(display),
+ TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
dndSelection, 0, 65535, FALSE,
AnyPropertyType, &u.atom_aux, (int *) &u.pt_aux.y,
&data_length, &aux_long, &p_data);
@@ -1660,7 +1646,7 @@
}
WIN_ReleaseWndPtr(pWnd);
- TSXGetWindowProperty( display, DefaultRootWindow(display),
+ TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
dndSelection, 0, 65535, FALSE,
AnyPropertyType, &u.atom_aux, &u.i,
&data_length, &aux_long, &p_data);
@@ -1688,7 +1674,7 @@
}
if( drop_len && drop_len < 65535 ) {
- TSXQueryPointer( display, X11DRV_GetXRootWindow(), &u.w_aux, &u.w_aux,
+ TSXQueryPointer( event->display, root_window, &u.w_aux, &u.w_aux,
&x, &y, &u.i, &u.i, &u.i);
pDropWnd = WIN_FindWndPtr( hWnd );
@@ -1780,7 +1766,7 @@
int i;
Atom atom;
} u; /* unused */
- TSXGetWindowProperty( display, DefaultRootWindow(display),
+ TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
dndSelection, 0, 65535, FALSE,
AnyPropertyType, &u.atom, &u.i,
&u.l, &u.l, &p_data);
@@ -1803,9 +1789,9 @@
#if 0
void EVENT_EnterNotify( HWND hWnd, XCrossingEvent *event )
{
- if( !Options.managed && X11DRV_GetXRootWindow() == DefaultRootWindow(display) &&
+ if( !Options.managed && root_window == DefaultRootWindow(event->display) &&
(COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE) && GetFocus() )
- TSXInstallColormap( display, X11DRV_PALETTE_GetColormap() );
+ TSXInstallColormap( event->display, X11DRV_PALETTE_GetColormap() );
}
#endif
diff --git a/windows/x11drv/keyboard.c b/windows/x11drv/keyboard.c
index 9bc5242..3fc1e1f 100644
--- a/windows/x11drv/keyboard.c
+++ b/windows/x11drv/keyboard.c
@@ -691,7 +691,7 @@
char keys_return[32];
TRACE("called\n");
- if (!TSXQueryKeymap(display, keys_return)) {
+ if (!TSXQueryKeymap(thread_display(), keys_return)) {
ERR("Error getting keymap !\n");
return;
}
@@ -839,6 +839,7 @@
static void
X11DRV_KEYBOARD_DetectLayout (void)
{
+ Display *display = thread_display();
unsigned current, match, mismatch, seq;
int score, keyc, i, key, pkey, ok, syms;
KeySym keysym;
@@ -937,6 +938,7 @@
#ifdef HAVE_XKB
int xkb_major = XkbMajorVersion, xkb_minor = XkbMinorVersion;
#endif
+ Display *display = thread_display();
KeySym *ksp;
XModifierKeymap *mmp;
KeySym keysym;
@@ -1164,6 +1166,7 @@
*/
WORD X11DRV_VkKeyScan(CHAR cChar)
{
+ Display *display = thread_display();
KeyCode keycode;
KeySym keysym;
int i,index;
@@ -1212,6 +1215,8 @@
*/
UINT16 X11DRV_MapVirtualKey(UINT16 wCode, UINT16 wMapType)
{
+ Display *display = thread_display();
+
#define returnMVK(value) { TRACE("returning 0x%x.\n",value); return value; }
TRACE("MapVirtualKey wCode=0x%x wMapType=%d ... \n", wCode,wMapType);
@@ -1366,7 +1371,7 @@
break;
if (keyc <= max_keycode)
{
- keys = TSXKeycodeToKeysym(display, keyc, 0);
+ keys = TSXKeycodeToKeysym(thread_display(), keyc, 0);
name = TSXKeysymToString(keys);
TRACE("found scan=%04x keyc=%04x keysym=%04x string=%s\n",
scanCode, keyc, (int)keys, name);
@@ -1484,6 +1489,7 @@
INT X11DRV_ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
LPWSTR bufW, int bufW_size, UINT flags)
{
+ Display *display = thread_display();
XKeyEvent e;
KeySym keysym;
INT ret;
@@ -1628,7 +1634,7 @@
*/
void X11DRV_Beep(void)
{
- TSXBell(display, 0);
+ TSXBell(thread_display(), 0);
}
/***********************************************************************
diff --git a/windows/x11drv/mouse.c b/windows/x11drv/mouse.c
index 0c68c0b..255972a 100644
--- a/windows/x11drv/mouse.c
+++ b/windows/x11drv/mouse.c
@@ -20,15 +20,13 @@
/**********************************************************************/
-Cursor X11DRV_MOUSE_XCursor = None; /* Current X cursor */
-
static LONG X11DRV_MOUSE_WarpPointer = 0; /* hack; see DISPLAY_MoveCursor */
static LPMOUSE_EVENT_PROC DefMouseEventProc = NULL;
/***********************************************************************
- * X11DRV_MOUSE_DoSetCursor
+ * X11DRV_GetCursor
*/
-static BOOL X11DRV_MOUSE_DoSetCursor( CURSORICONINFO *ptr )
+Cursor X11DRV_GetCursor( Display *display, CURSORICONINFO *ptr )
{
Pixmap pixmapBits, pixmapMask, pixmapMaskInv, pixmapAll;
XColor fg, bg;
@@ -39,7 +37,7 @@
static const char data[] = { 0 };
bg.red = bg.green = bg.blue = 0x0000;
- pixmapBits = XCreateBitmapFromData( display, X11DRV_GetXRootWindow(), data, 1, 1 );
+ pixmapBits = XCreateBitmapFromData( display, root_window, data, 1, 1 );
if (pixmapBits)
{
cursor = XCreatePixmapCursor( display, pixmapBits, pixmapBits,
@@ -50,11 +48,12 @@
else /* Create the X cursor from the bits */
{
XImage *image;
+ GC gc;
if (ptr->bPlanes * ptr->bBitsPerPixel != 1)
{
WARN("Cursor has more than 1 bpp!\n" );
- return FALSE;
+ return 0;
}
/* Create a pixmap and transfer all the bits to it */
@@ -64,36 +63,31 @@
* as the Windows cursor data). Perhaps use a more generic
* algorithm here.
*/
- pixmapAll = XCreatePixmap( display, X11DRV_GetXRootWindow(),
- ptr->nWidth, ptr->nHeight * 2, 1 );
- image = XCreateImage( display, X11DRV_GetVisual(),
- 1, ZPixmap, 0, (char *)(ptr + 1), ptr->nWidth,
- ptr->nHeight * 2, 16, ptr->nWidthBytes);
- if (image)
- {
- image->byte_order = MSBFirst;
- image->bitmap_bit_order = MSBFirst;
- image->bitmap_unit = 16;
- _XInitImageFuncPtrs(image);
- if (pixmapAll)
- XPutImage( display, pixmapAll, BITMAP_monoGC, image,
- 0, 0, 0, 0, ptr->nWidth, ptr->nHeight * 2 );
- image->data = NULL;
- XDestroyImage( image );
- }
+ if (!(pixmapAll = XCreatePixmap( display, root_window,
+ ptr->nWidth, ptr->nHeight * 2, 1 ))) return 0;
+ if (!(image = XCreateImage( display, visual,
+ 1, ZPixmap, 0, (char *)(ptr + 1), ptr->nWidth,
+ ptr->nHeight * 2, 16, ptr->nWidthBytes))) return 0;
+ gc = XCreateGC( display, pixmapAll, 0, NULL );
+ XSetGraphicsExposures( display, gc, False );
+ image->byte_order = MSBFirst;
+ image->bitmap_bit_order = MSBFirst;
+ image->bitmap_unit = 16;
+ _XInitImageFuncPtrs(image);
+ XPutImage( display, pixmapAll, gc, image,
+ 0, 0, 0, 0, ptr->nWidth, ptr->nHeight * 2 );
+ image->data = NULL;
+ XDestroyImage( image );
/* Now create the 2 pixmaps for bits and mask */
- pixmapBits = XCreatePixmap( display, X11DRV_GetXRootWindow(),
- ptr->nWidth, ptr->nHeight, 1 );
- pixmapMask = XCreatePixmap( display, X11DRV_GetXRootWindow(),
- ptr->nWidth, ptr->nHeight, 1 );
- pixmapMaskInv = XCreatePixmap( display, X11DRV_GetXRootWindow(),
- ptr->nWidth, ptr->nHeight, 1 );
+ pixmapBits = XCreatePixmap( display, root_window, ptr->nWidth, ptr->nHeight, 1 );
+ pixmapMask = XCreatePixmap( display, root_window, ptr->nWidth, ptr->nHeight, 1 );
+ pixmapMaskInv = XCreatePixmap( display, root_window, ptr->nWidth, ptr->nHeight, 1 );
/* Make sure everything went OK so far */
- if (pixmapBits && pixmapMask && pixmapAll)
+ if (pixmapBits && pixmapMask && pixmapMaskInv)
{
/* We have to do some magic here, as cursors are not fully
* compatible between Windows and X11. Under X11, there
@@ -117,29 +111,29 @@
* I don't know if it's correct per the X spec, but maybe
* we ought to take advantage of it. -- AJ
*/
- XSetFunction( display, BITMAP_monoGC, GXcopy );
- XCopyArea( display, pixmapAll, pixmapBits, BITMAP_monoGC,
+ XSetFunction( display, gc, GXcopy );
+ XCopyArea( display, pixmapAll, pixmapBits, gc,
0, 0, ptr->nWidth, ptr->nHeight, 0, 0 );
- XCopyArea( display, pixmapAll, pixmapMask, BITMAP_monoGC,
+ XCopyArea( display, pixmapAll, pixmapMask, gc,
0, 0, ptr->nWidth, ptr->nHeight, 0, 0 );
- XCopyArea( display, pixmapAll, pixmapMaskInv, BITMAP_monoGC,
+ XCopyArea( display, pixmapAll, pixmapMaskInv, gc,
0, 0, ptr->nWidth, ptr->nHeight, 0, 0 );
- XSetFunction( display, BITMAP_monoGC, GXand );
- XCopyArea( display, pixmapAll, pixmapMaskInv, BITMAP_monoGC,
+ XSetFunction( display, gc, GXand );
+ XCopyArea( display, pixmapAll, pixmapMaskInv, gc,
0, ptr->nHeight, ptr->nWidth, ptr->nHeight, 0, 0 );
- XSetFunction( display, BITMAP_monoGC, GXandReverse );
- XCopyArea( display, pixmapAll, pixmapBits, BITMAP_monoGC,
+ XSetFunction( display, gc, GXandReverse );
+ XCopyArea( display, pixmapAll, pixmapBits, gc,
0, ptr->nHeight, ptr->nWidth, ptr->nHeight, 0, 0 );
- XSetFunction( display, BITMAP_monoGC, GXorReverse );
- XCopyArea( display, pixmapAll, pixmapMask, BITMAP_monoGC,
+ XSetFunction( display, gc, GXorReverse );
+ XCopyArea( display, pixmapAll, pixmapMask, gc,
0, ptr->nHeight, ptr->nWidth, ptr->nHeight, 0, 0 );
/* Additional white */
- XSetFunction( display, BITMAP_monoGC, GXor );
- XCopyArea( display, pixmapMaskInv, pixmapMask, BITMAP_monoGC,
+ XSetFunction( display, gc, GXor );
+ XCopyArea( display, pixmapMaskInv, pixmapMask, gc,
0, 0, ptr->nWidth, ptr->nHeight, 1, 1 );
- XCopyArea( display, pixmapMaskInv, pixmapBits, BITMAP_monoGC,
+ XCopyArea( display, pixmapMaskInv, pixmapBits, gc,
0, 0, ptr->nWidth, ptr->nHeight, 1, 1 );
- XSetFunction( display, BITMAP_monoGC, GXcopy );
+ XSetFunction( display, gc, GXcopy );
fg.red = fg.green = fg.blue = 0xffff;
bg.red = bg.green = bg.blue = 0x0000;
cursor = XCreatePixmapCursor( display, pixmapBits, pixmapMask,
@@ -152,12 +146,21 @@
if (pixmapBits) XFreePixmap( display, pixmapBits );
if (pixmapMask) XFreePixmap( display, pixmapMask );
if (pixmapMaskInv) XFreePixmap( display, pixmapMaskInv );
+ XFreeGC( display, gc );
}
+ return cursor;
+}
- if (cursor == None) return FALSE;
- if (X11DRV_MOUSE_XCursor != None) XFreeCursor( display, X11DRV_MOUSE_XCursor );
- X11DRV_MOUSE_XCursor = cursor;
-
+/* set the cursor of a window; helper for X11DRV_SetCursor */
+static BOOL CALLBACK set_win_cursor( HWND hwnd, LPARAM cursor )
+{
+ WND *wndPtr = WIN_FindWndPtr(hwnd);
+ if (wndPtr)
+ {
+ Window win = X11DRV_WND_GetXWindow(wndPtr);
+ if (win) TSXDefineCursor( thread_display(), win, (Cursor)cursor );
+ }
+ WIN_ReleaseWndPtr( wndPtr );
return TRUE;
}
@@ -166,35 +169,33 @@
*/
void X11DRV_SetCursor( CURSORICONINFO *lpCursor )
{
- BOOL success;
+ Cursor cursor;
- wine_tsx11_lock();
- success = X11DRV_MOUSE_DoSetCursor( lpCursor );
- wine_tsx11_unlock();
- if ( !success ) return;
-
- if (X11DRV_GetXRootWindow() != DefaultRootWindow(display))
+ if (root_window != DefaultRootWindow(gdi_display))
{
/* If in desktop mode, set the cursor on the desktop window */
- TSXDefineCursor( display, X11DRV_GetXRootWindow(), X11DRV_MOUSE_XCursor );
- }
- else
- {
- /* Else, set the same cursor for all top-level windows */
-
- /* FIXME: we should not reference USER internals here, but native USER
- works only in desktop mode anyway, so this should not matter */
-
- HWND hwnd = GetWindow( GetDesktopWindow(), GW_CHILD );
- while(hwnd)
+ wine_tsx11_lock();
+ cursor = X11DRV_GetCursor( gdi_display, lpCursor );
+ if (cursor)
{
- WND *tmpWnd = WIN_FindWndPtr(hwnd);
- Window win = X11DRV_WND_FindXWindow(tmpWnd );
- if (win && win!=DefaultRootWindow(display))
- TSXDefineCursor( display, win, X11DRV_MOUSE_XCursor );
- hwnd = GetWindow( hwnd, GW_HWNDNEXT );
- WIN_ReleaseWndPtr(tmpWnd);
+ XDefineCursor( gdi_display, root_window, cursor );
+ XFreeCursor( gdi_display, cursor );
+ }
+ wine_tsx11_unlock();
+ }
+ else /* set the same cursor for all top-level windows of the current thread */
+ {
+ Display *display = thread_display();
+
+ wine_tsx11_lock();
+ cursor = X11DRV_GetCursor( display, lpCursor );
+ wine_tsx11_unlock();
+ if (cursor)
+ {
+/* EnumThreadWindows( GetCurrentThreadId(), set_win_cursor, (LPARAM)cursor );*/
+ EnumWindows( set_win_cursor, (LPARAM)cursor );
+ TSXFreeCursor( display, cursor );
}
}
}
@@ -205,7 +206,7 @@
void X11DRV_MoveCursor(WORD wAbsX, WORD wAbsY)
{
/*
- * We do not want the to create MotionNotify events here,
+ * We do not want to create MotionNotify events here,
* otherwise we will get an endless recursion:
* XMotionEvent -> MOUSEEVENTF_MOVE -> mouse_event -> DisplayMoveCursor
* -> XWarpPointer -> XMotionEvent -> ...
@@ -221,14 +222,15 @@
* But first of all, we check whether we already are at the position
* are supposed to move to; if so, we don't need to do anything.
*/
-
+
+ Display *display = thread_display();
Window root, child;
int rootX, rootY, winX, winY;
unsigned int xstate;
if (X11DRV_MOUSE_WarpPointer < 0) return;
- if (!TSXQueryPointer( display, X11DRV_GetXRootWindow(), &root, &child,
+ if (!TSXQueryPointer( display, root_window, &root, &child,
&rootX, &rootY, &winX, &winY, &xstate ))
return;
@@ -237,8 +239,7 @@
TRACE("(%d,%d): moving from (%d,%d)\n", wAbsX, wAbsY, winX, winY );
- TSXWarpPointer( display, X11DRV_GetXRootWindow(), X11DRV_GetXRootWindow(),
- 0, 0, 0, 0, wAbsX, wAbsY );
+ TSXWarpPointer( display, root_window, root_window, 0, 0, 0, 0, wAbsX, wAbsY );
}
/***********************************************************************
@@ -259,7 +260,7 @@
init_done = 1;
/* Get the current mouse position and simulate an absolute mouse
movement to initialize the mouse global variables */
- TSXQueryPointer( display, X11DRV_GetXRootWindow(), &root, &child,
+ TSXQueryPointer( thread_display(), root_window, &root, &child,
&root_x, &root_y, &child_x, &child_y, &KeyState);
X11DRV_SendEvent(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
root_x, root_y, X11DRV_EVENT_XStateToKeyState(KeyState),
diff --git a/windows/x11drv/wnd.c b/windows/x11drv/wnd.c
index 263a9f4..901a13b 100644
--- a/windows/x11drv/wnd.c
+++ b/windows/x11drv/wnd.c
@@ -115,7 +115,7 @@
while (wndPtr)
{
if ( !X11DRV_WND_IsZeroSizeWnd(wndPtr) && X11DRV_WND_GetXWindow(wndPtr) )
- TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(wndPtr), 0,
+ TSXReconfigureWMWindow( thread_display(), X11DRV_WND_GetXWindow(wndPtr), 0,
CWStackMode, &winChanges );
wndPrev = pDesktop->child;
@@ -144,7 +144,7 @@
window = X11DRV_WND_GetXWindow(wndPtr);
for (;;)
{
- TSXQueryTree( display, window, &root, &parent,
+ TSXQueryTree( thread_display(), window, &root, &parent,
&children, &nchildren );
TSXFree( children );
if (parent == root)
@@ -162,6 +162,7 @@
void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangePos)
{
XWindowChanges winChanges;
+ Display *display = thread_display();
int changeMask = 0;
BOOL isZeroSizeWnd = FALSE;
BOOL forceMapWindow = FALSE;
@@ -392,7 +393,7 @@
XSetWindowAttributes win_attr;
win_attr.bit_gravity = value;
data->bit_gravity = value;
- TSXChangeWindowAttributes( display, data->window, CWBitGravity, &win_attr );
+ TSXChangeWindowAttributes( thread_display(), data->window, CWBitGravity, &win_attr );
}
}
@@ -410,6 +411,7 @@
if( (w = X11DRV_WND_GetXWindow(wnd)) )
{
+ Display *display = thread_display();
switch( ha )
{
case HAK_ICONICSTATE: /* called when a window is minimized/restored */
@@ -435,8 +437,7 @@
ev.data.l[0] = IconicState;
ev.window = w;
- if( TSXSendEvent (display,
- RootWindow( display, XScreenNumberOfScreen(X11DRV_GetXScreen()) ),
+ if( TSXSendEvent (display, DefaultRootWindow(display),
True, (SubstructureRedirectMask | SubstructureNotifyMask), (XEvent*)&ev))
{
XEvent xe;