diff --git a/controls/desktop.c b/controls/desktop.c index 2b3f8365123f8dd213f9d2e7553be831bb7a12cc..01e1706cacfe3d7d32a4cc72a14ea9c59dbc1cfe 100644 --- a/controls/desktop.c +++ b/controls/desktop.c @@ -97,121 +97,25 @@ static HBITMAP DESKTOP_LoadBitmap( HDC hdc, const char *filename ) } -/*********************************************************************** - * 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. + * DesktopWndProc */ -static inline LRESULT WINAPI DesktopWndProc_locked( WND *wndPtr, UINT message, - WPARAM wParam, LPARAM lParam ) +static LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { + LRESULT retvalue = 0; + WND *wndPtr = WIN_FindWndPtr( hwnd ); DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra; - HWND hwnd = wndPtr->hwndSelf; - - /* Most messages are ignored (we DON'T call DefWindowProc) */ - switch(message) + if (message == WM_NCCREATE) { - /* 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 ) ); + desktopPtr->hbrushPattern = 0; + desktopPtr->hbitmapWallPaper = 0; + SetDeskPattern(); + SetDeskWallPaper( (LPSTR)-1 ); + retvalue = 1; } - - 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 ) -{ - WND *wndPtr = WIN_FindWndPtr( hwnd ); - LRESULT retvalue = DesktopWndProc_locked(wndPtr,message,wParam,lParam); + /* all other messages are ignored */ WIN_ReleaseWndPtr(wndPtr); return retvalue; @@ -223,14 +127,61 @@ static LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LP */ 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 55ad8bcdbc342e4fc9e86e47201590dec30259e8..ffcdc9f88fa3f3213de2d2c7a48682247ea3b0b7 100644 --- a/dlls/ttydrv/ttydrv.spec +++ b/dlls/ttydrv/ttydrv.spec @@ -11,7 +11,6 @@ debug_channels (ttydrv) # 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 @@ debug_channels (ttydrv) @ 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 ca7a3c5d9dd542c2309e3a70e2b6885a95c2d7bd..6d65162068b0c342bc38009c6857a18b5fd06400 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 @@ -169,14 +162,6 @@ HANDLE TTYDRV_LoadOEMResource(WORD resid, WORD type) return 0; } -/*********************************************************************** - * TTYDRV_IsSingleWindow - */ -BOOL TTYDRV_IsSingleWindow(void) -{ - return TRUE; -} - /*********************************************************************** * TTYDRV_AcquireClipboard */ diff --git a/dlls/user/display.c b/dlls/user/display.c index 822174a13f3860443fedb531d5b0d1f0f7a685f7..e132285c58691524d7567afb1deeedf4fbd74da8 100644 --- a/dlls/user/display.c +++ b/dlls/user/display.c @@ -76,6 +76,6 @@ DWORD WINAPI DISPLAY_GetDriverResourceID( WORD wQueriedResID, LPSTR lpsResName ) */ 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 2690e8daa16db50ee1e7497e1372e75db7d8e8f6..341c5f45ff2c644205e70c76836f19697299e64d 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 @@ static BOOL load_driver(void) return FALSE; } - GET_USER_FUNC(UserRepaintDisable); GET_USER_FUNC(InitKeyboard); GET_USER_FUNC(VkKeyScan); GET_USER_FUNC(MapVirtualKey); @@ -75,7 +76,6 @@ static BOOL load_driver(void) 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 @@ static BOOL load_driver(void) 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 @@ static void tweak_init(void) /*********************************************************************** * 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 @@ BOOL WINAPI USER_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) /* 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 10a3f9a6854f9208a3b7b920f426ba824a133fa8..e98cdd571a823619f2815f556589b587fb7f3dd2 100644 --- a/dlls/x11drv/Makefile.in +++ b/dlls/x11drv/Makefile.in @@ -7,6 +7,7 @@ EXTRALIBS = $(LIBTSX11) $(X_LIBS) $(XLIB) 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 0000000000000000000000000000000000000000..1376899d844bc1ebf00864b8b1e54528ec3db579 --- /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 939cb6a15f5108f6c5d5cf9515126f931b3651cc..bf9fc0a32b0bef90ace1b816a4532e7063f0cc3e 100644 --- a/dlls/x11drv/dga2.c +++ b/dlls/x11drv/dga2.c @@ -51,7 +51,7 @@ void X11DRV_XF86DGA2_Init(void) 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 4508b99cb8beabe6917b84931c2c7acc14db8836..ed3e9664833e31ed3c72d6a901c7e24c93e57363 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 @@ Atom _kde_net_wm_system_tray_window_for = None; /* KDE 2 Final */ /*********************************************************************** - * 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 @@ static void register_window( HWND hwnd, Window win ) * * 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 @@ static void set_wm_hint( Window win, int hint, int val ) * * 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 @@ static void set_icon_hints( WND *wndPtr, XWMHints *hints ) * * 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 @@ inline static void dock_window( Window win ) /********************************************************************** * 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 @@ static void create_desktop(WND *wndPtr) _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 @@ static void create_desktop(WND *wndPtr) */ 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 @@ BOOL X11DRV_CreateWindow( HWND hwnd ) if (!wndPtr->parent) { - create_desktop( wndPtr ); + create_desktop( display, wndPtr ); WIN_ReleaseWndPtr( wndPtr ); return TRUE; } @@ -246,11 +249,13 @@ BOOL X11DRV_CreateWindow( HWND hwnd ) } 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 @@ BOOL X11DRV_CreateWindow( HWND hwnd ) 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 @@ BOOL X11DRV_CreateWindow( HWND hwnd ) 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 @@ BOOL X11DRV_CreateWindow( HWND hwnd ) } /* 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 @@ BOOL X11DRV_CreateWindow( HWND hwnd ) 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 @@ BOOL X11DRV_CreateWindow( HWND hwnd ) 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_CreateWindow( HWND hwnd ) */ 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 @@ BOOL X11DRV_DestroyWindow( HWND hwnd ) 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 @@ BOOL X11DRV_DestroyWindow( HWND hwnd ) */ HWND X11DRV_SetParent( HWND hwnd, HWND parent ) { + Display *display = thread_display(); WND *wndPtr; WND *pWndParent; DWORD dwStyle; @@ -464,6 +478,7 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent ) */ BOOL X11DRV_EnableWindow( HWND hwnd, BOOL enable ) { + Display *display = thread_display(); WND *wndPtr; BOOL retvalue; Window w; @@ -478,7 +493,7 @@ BOOL X11DRV_EnableWindow( HWND hwnd, BOOL enable ) 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 @@ BOOL X11DRV_EnableWindow( HWND hwnd, BOOL enable ) 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 @@ BOOL X11DRV_EnableWindow( HWND hwnd, BOOL enable ) */ void X11DRV_SetFocus( HWND hwnd ) { + Display *display = thread_display(); XWindowAttributes win_attr; Window win; WND *wndPtr = WIN_FindWndPtr( hwnd ); @@ -558,6 +574,7 @@ void X11DRV_SetFocus( HWND hwnd ) */ 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 @@ BOOL X11DRV_SetWindowText( HWND hwnd, LPCWSTR text ) */ 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 @@ HICON X11DRV_SetWindowIcon( HWND hwnd, HICON icon, BOOL small ) 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 1f110a5b2c80a758c561bae8e005934e7deee69e..721bd7b8a8cf0a6dc92875e7c8eb25da045d0114 100644 --- a/dlls/x11drv/winpos.c +++ b/dlls/x11drv/winpos.c @@ -405,7 +405,7 @@ BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags ) } 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 @@ BOOL X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw ) 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 @@ void X11DRV_SysCommandSizeMove( HWND hwnd, WPARAM wParam ) 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 @@ void X11DRV_SysCommandSizeMove( HWND hwnd, WPARAM wParam ) 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 @@ void X11DRV_SysCommandSizeMove( HWND hwnd, WPARAM wParam ) 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 378cdbd041e14ee2687614f20a880f81267a5659..a867222248285d9f6c29ac03641752a21dc6f1a0 100644 --- a/dlls/x11drv/x11ddraw.c +++ b/dlls/x11drv/x11ddraw.c @@ -48,6 +48,7 @@ static void SetPrimaryDIB(HBITMAP hBmp) 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 abfdac3db61953a95e5f2345269fb49dc1f2d9c2..ac91214d4740c3a87991e2a4cc67e1996bec981a 100644 --- a/dlls/x11drv/x11drv.spec +++ b/dlls/x11drv/x11drv.spec @@ -11,7 +11,6 @@ debug_channels (bitblt bitmap clipboard cursor dinput event font gdi graphics # 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 @@ debug_channels (bitblt bitmap clipboard cursor dinput event font gdi graphics @ 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 @@ debug_channels (bitblt bitmap clipboard cursor dinput event font gdi graphics @ 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 a788543b08533f58a1755d0dab3c9d05c6728a7e..50b0ac2eefa36d38ad4415e0a363d6a42943808e 100644 --- a/dlls/x11drv/x11drv_main.c +++ b/dlls/x11drv/x11drv_main.c @@ -33,6 +33,7 @@ static int *ph_errno = &h_errno; #include "debugtools.h" #include "gdi.h" +#include "file.h" #include "options.h" #include "user.h" #include "win.h" @@ -48,7 +49,6 @@ static void (*old_tsx11_unlock)(void); static CRITICAL_SECTION X11DRV_CritSection = CRITICAL_SECTION_INIT; -Display *display; Screen *screen; Visual *visual; unsigned int screen_width; @@ -61,6 +61,7 @@ unsigned int X11DRV_server_startticks; 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 @@ static void setup_options(void) * 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; @@ -256,89 +256,14 @@ static void setup_opengl_visual( void ) } #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 @@ static void process_attach(void) /* 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 @@ static void process_attach(void) 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 @@ static void process_attach(void) ExitProcess(1); } - /* initialize event handling */ - X11DRV_EVENT_Init(); - #ifdef HAVE_LIBXXF86VM /* initialize XVidMode */ X11DRV_XF86VM_Init(); @@ -440,6 +362,24 @@ static void process_attach(void) } +/*********************************************************************** + * 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 */ @@ -458,12 +398,11 @@ static void process_detach(void) 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; @@ -476,6 +415,36 @@ static void process_detach(void) } +/*********************************************************************** + * 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 */ @@ -486,6 +455,9 @@ BOOL WINAPI X11DRV_Init( HINSTANCE hinst, DWORD reason, LPVOID reserved ) 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 @@ void X11DRV_SetScreenSaveTimeout(int nTimeout) 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 264c2fb1304e2dcb2a9d85a28c61c28f4125737b..6f46457aab75b64caf3a571abd35e0de1883c5fa 100644 --- a/include/thread.h +++ b/include/thread.h @@ -101,10 +101,11 @@ typedef struct _TEB 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 683798957239c2fffd9abb80f3c30309d42b8e76..8e1b92e8523222ed6fc45023205518d6c09cceb5 100644 --- a/include/user.h +++ b/include/user.h @@ -38,8 +38,6 @@ typedef VOID CALLBACK (*LPMOUSE_EVENT_PROC)(DWORD,DWORD,DWORD,DWORD,DWORD); struct tagWND; typedef struct tagUSER_DRIVER { - /* event functions */ - void (*pUserRepaintDisable)(BOOL); /* keyboard functions */ void (*pInitKeyboard)(void); WORD (*pVkKeyScan)(CHAR); @@ -75,6 +73,7 @@ typedef struct tagUSER_DRIVER { 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 @@ typedef struct tagUSER_DRIVER { 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 0006cef0ebc91355976908ec9c60834d1a51a0f4..ea8c479b5a816014388a8c9c8e69a6785c92f8e6 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 @@ extern BOOL X11DRV_PALETTE_IsDark(int pixel); * 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 BOOL X11DRV_GetClipboardData(UINT wFormat); 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 void X11DRV_WND_SetGravity(struct tagWND* wndPtr, int value ); 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 5a22e675caa793febd0c1096d5705681d9836198..5648db3d3fc4832f97c34e27a3c9dc87fa02138a 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 @@ static DWORD MSG_TranslateMouseMsg( HWND hTopWnd, DWORD first, DWORD last, /* 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 @@ static DWORD MSG_TranslateKbdMsg( HWND hTopWnd, DWORD first, DWORD last, 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 @@ static BOOL MSG_PeekMessage( int type, LPMSG msg_out, HWND hwnd, #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 @@ static LRESULT MSG_SendMessage( HWND hwnd, UINT msg, WPARAM wParam, 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 @@ DWORD WINAPI MsgWaitForMultipleObjects( DWORD nCount, HANDLE *pHandles, /* 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 14a55ce808bc80723d72ff1646a308560c1dd9e7..b66c53ba588d6e25824ee5d9d2252424abab68ca 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 @@ int QUEUE_WaitBits( WORD bits, DWORD timeout ) } 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 @@ void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, QMSG *qmsg ) } +#if 0 /*********************************************************************** * QUEUE_WakeSomeone * @@ -1161,6 +1167,7 @@ static void QUEUE_WakeSomeone( UINT message ) WARN_(msg)("couldn't find queue\n"); } +#endif /*********************************************************************** @@ -1174,6 +1181,7 @@ void hardware_event( UINT message, WPARAM wParam, LPARAM lParam, { MSG *msg; QMSG *qmsg; + MESSAGEQUEUE *queue; int mergeMsg = 0; if (!sysMsgQueue) return; @@ -1237,10 +1245,19 @@ void hardware_event( UINT message, WPARAM wParam, LPARAM lParam, 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 f012e91c950d872fbbba3f25ad94e8112614c316..7dba9aeb830ea7d50cdfdc9d37b9a23c33e5c84c 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 @@ static void USER_ModuleUnload( HMODULE16 hModule ) 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 @@ WORD WINAPI UserSignalProc( UINT uCode, DWORD dwThreadOrProcessID, 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 f16ff60b78679b5dbc61f09baa927bcc44602fd5..a31f7567cb7246b5a06cb362e453cf3e4e95ad8c 100644 --- a/windows/win.c +++ b/windows/win.c @@ -359,6 +359,7 @@ HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE16 hQueue ) * 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 @@ BOOL WIN_CreateDesktopWindow(void) 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 ce533d1c645fbfb5151d8b7cf6089dd1713fc5ae..500391b0789937105cce32d1665dbec35328e0f2 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -1987,13 +1987,7 @@ BOOL WINPOS_ActivateOtherWindow(WND* pWnd) 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_ActivateOtherWindow(WND* pWnd) */ BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg ) { - WND *wndPtr, *wndTemp; + WND *wndPtr; BOOL retvalue; HWND hwndActive = 0; @@ -2045,12 +2039,6 @@ BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg ) 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 aece6ca0d1b408762c3bb466ad7e39b5a32e9022..b0b7f131a810449b3bb9ea3dc3f9bc335b7cb0b9 100644 --- a/windows/x11drv/clipboard.c +++ b/windows/x11drv/clipboard.c @@ -176,7 +176,7 @@ Atom X11DRV_CLIPBOARD_MapFormatToProperty(UINT wFormat) 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 @@ Atom X11DRV_CLIPBOARD_MapFormatToProperty(UINT wFormat) */ 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_IsNativeProperty(Atom prop) 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 @@ BOOL X11DRV_CLIPBOARD_LaunchServer() 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 @@ BOOL X11DRV_CLIPBOARD_LaunchServer() /* 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 @@ BOOL X11DRV_CLIPBOARD_LaunchServer() 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 @@ BOOL X11DRV_CLIPBOARD_LaunchServer() 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 @@ BOOL X11DRV_CLIPBOARD_LaunchServer() */ int X11DRV_CLIPBOARD_CacheDataFormats( Atom SelectionName ) { + Display *display = thread_display(); HWND hWnd = 0; HWND hWndClipWindow = GetOpenClipboardWindow(); WND* wnd = NULL; @@ -458,6 +451,7 @@ int X11DRV_CLIPBOARD_CacheDataFormats( Atom SelectionName ) */ 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 @@ END: */ 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_CLIPBOARD_ReleaseSelection(Atom selType, Window w, HWND hwnd) */ void X11DRV_ReleaseClipboard(void) { + Display *display = thread_display(); if( selectionAcquired ) { XEvent xe; @@ -847,6 +843,7 @@ void X11DRV_ReleaseClipboard(void) */ void X11DRV_AcquireClipboard(void) { + Display *display = thread_display(); Window owner; HWND hWndClipWindow = GetOpenClipboardWindow(); @@ -900,6 +897,7 @@ void X11DRV_AcquireClipboard(void) */ 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_IsClipboardFormatAvailable(UINT wFormat) */ BOOL X11DRV_RegisterClipboardFormat( LPCSTR FormatName ) { + Display *display = thread_display(); Atom prop = None; char str[256]; @@ -1009,6 +1008,7 @@ void X11DRV_SetClipboardData(UINT wFormat) */ BOOL X11DRV_GetClipboardData(UINT wFormat) { + Display *display = thread_display(); BOOL bRet = selectionAcquired; HWND hWndClipWindow = GetOpenClipboardWindow(); HWND hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow(); @@ -1087,6 +1087,7 @@ BOOL X11DRV_GetClipboardData(UINT wFormat) */ 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 ef1c597720499c8b0a2eb9f64cd249e152953934..743f89452a5dbcc73cf2b06baa3e3da4dc25352f 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 const char * const event_names[] = }; -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_DGAButtonReleaseEvent( XDGAButtonEvent *event ); 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 - */ -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 + * process_events */ -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 @@ static void CALLBACK EVENT_ProcessAllEvents( ULONG_PTR arg ) } /*********************************************************************** - * 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 @@ void X11DRV_UserRepaintDisable( BOOL bDisabled ) static void EVENT_ProcessEvent( XEvent *event ) { HWND hWnd; + Display *display = event->xany.display; TRACE( "called.\n" ); @@ -302,7 +283,7 @@ static void EVENT_ProcessEvent( XEvent *event ) 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 @@ static void EVENT_ProcessEvent( XEvent *event ) } } - 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 @@ static void EVENT_ProcessEvent( XEvent *event ) BOOL bIsDisabled; XFocusChangeEvent *xfocChange = (XFocusChangeEvent*)event; - if (!hWnd || bUserRepaintDisabled) return; + if (!hWnd) return; bIsDisabled = GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED; @@ -393,34 +374,32 @@ static void EVENT_ProcessEvent( XEvent *event ) /* 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 @@ static void EVENT_ProcessEvent( XEvent *event ) break; case ClientMessage: - if (!hWnd || bUserRepaintDisabled) return; + if (!hWnd) return; EVENT_ClientMessage( hWnd, (XClientMessageEvent *) event ); break; @@ -443,12 +422,12 @@ static void EVENT_ProcessEvent( XEvent *event ) 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 @@ static BOOL __check_query_condition( WND** pWndA, WND** pWndB ) 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 @@ static Window __get_common_ancestor( Window A, Window B, 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 @@ static unsigned __td_lookup( Window w, Window* list, unsigned max ) 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 @@ static HWND EVENT_QueryZOrder( HWND hWndCheck) 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 @@ static HWND EVENT_QueryZOrder( HWND hWndCheck) 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 void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event ) */ static BOOL X11DRV_CheckFocus(void) { + Display *display = thread_display(); HWND hWnd; Window xW; int state; @@ -873,7 +853,7 @@ static BOOL X11DRV_CheckFocus(void) * 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 @@ static void EVENT_ConfigureNotify( HWND hWnd, XConfigureEvent *event ) /* 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 @@ static void EVENT_ConfigureNotify( HWND hWnd, XConfigureEvent *event ) * 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 @@ static Atom EVENT_SelectionRequest_TARGETS( Window requestor, Atom target, Atom * 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 @@ static Atom EVENT_SelectionRequest_STRING( Window requestor, Atom target, Atom r * 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 @@ END: * 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_WCF( Window requestor, Atom target, Atom rpro */ static Atom EVENT_SelectionRequest_MULTIPLE( HWND hWnd, XSelectionRequestEvent *pevent ) { + Display *display = pevent->display; Atom rprop; Atom atype=AnyPropertyType; int aformat; @@ -1375,6 +1360,7 @@ END: */ 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 @@ static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BO 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 @@ END: */ 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 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event ) 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 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event ) 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 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event ) } 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 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event ) } 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 @@ static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event ) 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 @@ static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event ) #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 9bc5242b4984510adb1c5a85e723e1a643110a6e..3fc1e1f9266c17bbb0884400dc8a0c2e1e628cad 100644 --- a/windows/x11drv/keyboard.c +++ b/windows/x11drv/keyboard.c @@ -691,7 +691,7 @@ void X11DRV_KEYBOARD_UpdateState ( void ) 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 @@ void X11DRV_KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event ) 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 @@ void X11DRV_InitKeyboard(void) #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 @@ void X11DRV_InitKeyboard(void) */ WORD X11DRV_VkKeyScan(CHAR cChar) { + Display *display = thread_display(); KeyCode keycode; KeySym keysym; int i,index; @@ -1212,6 +1215,8 @@ WORD X11DRV_VkKeyScan(CHAR cChar) */ 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 @@ INT16 X11DRV_GetKeyNameText(LONG lParam, LPSTR lpBuffer, INT16 nSize) 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 @@ static char KEYBOARD_MapDeadKeysym(KeySym keysym) 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 @@ INT X11DRV_ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState, */ void X11DRV_Beep(void) { - TSXBell(display, 0); + TSXBell(thread_display(), 0); } /*********************************************************************** diff --git a/windows/x11drv/mouse.c b/windows/x11drv/mouse.c index 0c68c0bdb097d30caa126d898d9c40e18bf67c57..255972a8105c46ccaca0c3fe9e19f2dd6be88113 100644 --- a/windows/x11drv/mouse.c +++ b/windows/x11drv/mouse.c @@ -20,15 +20,13 @@ DEFAULT_DEBUG_CHANNEL(cursor); /**********************************************************************/ -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 BOOL X11DRV_MOUSE_DoSetCursor( CURSORICONINFO *ptr ) 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 @@ static BOOL X11DRV_MOUSE_DoSetCursor( CURSORICONINFO *ptr ) 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 @@ static BOOL X11DRV_MOUSE_DoSetCursor( CURSORICONINFO *ptr ) * 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 @@ static BOOL X11DRV_MOUSE_DoSetCursor( CURSORICONINFO *ptr ) * 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 @@ static BOOL X11DRV_MOUSE_DoSetCursor( CURSORICONINFO *ptr ) 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 @@ static BOOL X11DRV_MOUSE_DoSetCursor( CURSORICONINFO *ptr ) */ void X11DRV_SetCursor( CURSORICONINFO *lpCursor ) { - BOOL success; - - wine_tsx11_lock(); - success = X11DRV_MOUSE_DoSetCursor( lpCursor ); - wine_tsx11_unlock(); - if ( !success ) return; + Cursor cursor; - 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 ); + wine_tsx11_lock(); + cursor = X11DRV_GetCursor( gdi_display, lpCursor ); + if (cursor) + { + XDefineCursor( gdi_display, root_window, cursor ); + XFreeCursor( gdi_display, cursor ); + } + wine_tsx11_unlock(); } - else + else /* set the same cursor for all top-level windows of the current thread */ { - /* Else, set the same cursor for all top-level windows */ + Display *display = thread_display(); - /* 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( display, lpCursor ); + wine_tsx11_unlock(); + 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); +/* EnumThreadWindows( GetCurrentThreadId(), set_win_cursor, (LPARAM)cursor );*/ + EnumWindows( set_win_cursor, (LPARAM)cursor ); + TSXFreeCursor( display, cursor ); } } } @@ -205,7 +206,7 @@ void X11DRV_SetCursor( CURSORICONINFO *lpCursor ) 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 @@ void X11DRV_MoveCursor(WORD wAbsX, WORD wAbsY) * 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 @@ void X11DRV_MoveCursor(WORD wAbsX, WORD wAbsY) 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 @@ void X11DRV_InitMouse( LPMOUSE_EVENT_PROC proc ) 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 263a9f4f916be586bbd6ea4412fe091968765e97..901a13b7bd0d0e197253f5c480e7ccb18b3384ec 100644 --- a/windows/x11drv/wnd.c +++ b/windows/x11drv/wnd.c @@ -115,7 +115,7 @@ void X11DRV_WND_ForceWindowRaise(WND *wndPtr) 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 @@ static Window X11DRV_WND_FindDesktopXWindow( WND *wndPtr ) 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 @@ static Window X11DRV_WND_FindDesktopXWindow( WND *wndPtr ) 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 @@ void X11DRV_WND_SetGravity( WND* wnd, int value ) 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 @@ BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value) 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 @@ BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value) 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;