From 151170c437425cdf2a0f2a7e156e5b585361e243 Mon Sep 17 00:00:00 2001 From: Patrik Stridvall Date: Sat, 26 Dec 1998 12:00:43 +0000 Subject: [PATCH] Moved more things to the X11 driver. --- debugger/dbg.y | 2 + graphics/ddraw.c | 5 +- graphics/x11drv/bitblt.c | 5 +- graphics/x11drv/brush.c | 2 + graphics/x11drv/clipping.c | 2 + graphics/x11drv/init.c | 2 + include/clipboard.h | 2 +- include/ddraw.h | 10 +- include/display.h | 5 + include/ttydrv.h | 2 +- include/win.h | 9 ++ include/x11drv.h | 32 +++-- objects/palette.c | 2 - windows/dce.c | 57 +-------- windows/dinput.c | 2 - windows/display.c | 208 ++------------------------------ windows/input.c | 10 +- windows/message.c | 2 - windows/scroll.c | 25 +--- windows/ttydrv/clipboard.c | 2 +- windows/ttydrv/event.c | 2 + windows/ttydrv/init.c | 2 + windows/win.c | 15 ++- windows/winpos.c | 16 +-- windows/x11drv/clipboard.c | 31 +++-- windows/x11drv/event.c | 11 +- windows/x11drv/init.c | 15 +-- windows/x11drv/mouse.c | 206 +++++++++++++++++++++++++++++++- windows/x11drv/wnd.c | 236 ++++++++++++++++++++++++++++++------- 29 files changed, 537 insertions(+), 383 deletions(-) diff --git a/debugger/dbg.y b/debugger/dbg.y index 5cbe3571a6b..03073429afc 100644 --- a/debugger/dbg.y +++ b/debugger/dbg.y @@ -6,6 +6,8 @@ * Copyright 1995 Morten Welinder */ +#include "ts_xlib.h" + #include #include #include diff --git a/graphics/ddraw.c b/graphics/ddraw.c index b3511fa37a4..474d2b050f1 100644 --- a/graphics/ddraw.c +++ b/graphics/ddraw.c @@ -17,6 +17,7 @@ #include #include #include "ts_xlib.h" +#include "ts_xutil.h" #include #include #include @@ -2249,10 +2250,10 @@ static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode( _common_IDirectDraw_SetDisplayMode(this); this->e.xlib.paintable = 1; - this->e.xlib.drawable = WIN_FindWndPtr(this->d.window)->window; + this->e.xlib.drawable = ((X11DRV_WND_DATA *) WIN_FindWndPtr(this->d.window)->pDriverData)->window; /* We don't have a context for this window. Host off the desktop */ if( !this->e.xlib.drawable ) - this->e.xlib.drawable = WIN_GetDesktop()->window; + this->e.xlib.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window; return DD_OK; } diff --git a/graphics/x11drv/bitblt.c b/graphics/x11drv/bitblt.c index 7d43a658abd..f2028eb776c 100644 --- a/graphics/x11drv/bitblt.c +++ b/graphics/x11drv/bitblt.c @@ -4,11 +4,12 @@ * Copyright 1993, 1994 Alexandre Julliard */ +#include "ts_xlib.h" +#include + #include #include #include -#include -#include #include "bitmap.h" #include "callback.h" #include "color.h" diff --git a/graphics/x11drv/brush.c b/graphics/x11drv/brush.c index 379857eb162..b280233280a 100644 --- a/graphics/x11drv/brush.c +++ b/graphics/x11drv/brush.c @@ -4,6 +4,8 @@ * Copyright 1993, 1994 Alexandre Julliard */ +#include "ts_xlib.h" + #include #include "brush.h" #include "bitmap.h" diff --git a/graphics/x11drv/clipping.c b/graphics/x11drv/clipping.c index 8af6eaf5aba..feb18d9c990 100644 --- a/graphics/x11drv/clipping.c +++ b/graphics/x11drv/clipping.c @@ -4,6 +4,8 @@ * Copyright 1998 Huw Davies */ +#include "ts_xlib.h" + #include #include "dc.h" #include "x11drv.h" diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c index 38d789c51d4..42e03ecdc20 100644 --- a/graphics/x11drv/init.c +++ b/graphics/x11drv/init.c @@ -4,6 +4,8 @@ * Copyright 1996 Alexandre Julliard */ +#include "ts_xlib.h" + #include #include "x11drv.h" #include "color.h" diff --git a/include/clipboard.h b/include/clipboard.h index 4bda6641b6c..4bfd7242ff8 100644 --- a/include/clipboard.h +++ b/include/clipboard.h @@ -21,7 +21,7 @@ typedef struct _CLIPBOARD_DRIVER void (*pEmptyClipboard)(); void (*pSetClipboardData)(UINT32); BOOL32 (*pRequestSelection)(); - void (*pResetOwner)(WND *); + void (*pResetOwner)(WND *, BOOL32); } CLIPBOARD_DRIVER; CLIPBOARD_DRIVER *CLIPBOARD_GetDriver(); diff --git a/include/ddraw.h b/include/ddraw.h index de048f41d19..4b5e917132e 100644 --- a/include/ddraw.h +++ b/include/ddraw.h @@ -1,10 +1,14 @@ #ifndef __WINE_DDRAW_H #define __WINE_DDRAW_H -#include "ts_xlib.h" +#include "config.h" + +#ifndef X_DISPLAY_MISSING +#include #ifdef HAVE_LIBXXSHM -#include "ts_xshm.h" -#endif +#include +#endif /* defined(HAVE_LIBXXSHM) */ +#endif /* !defined(X_DISPLAY_MISSING) */ #ifndef DIRECTDRAW_VERSION #define DIRECTDRAW_VERSION 0x0500 diff --git a/include/display.h b/include/display.h index f45db62ac44..d7a713ea3cf 100644 --- a/include/display.h +++ b/include/display.h @@ -17,6 +17,11 @@ typedef struct _CURSORINFO } CURSORINFO, *LPCURSORINFO; #pragma pack(4) +typedef struct _MOUSE_DRIVER { + VOID (*pSetCursor)(CURSORICONINFO *); + VOID (*pMoveCursor)(WORD, WORD); +} MOUSE_DRIVER; + WORD WINAPI DISPLAY_Inquire(LPCURSORINFO lpCursorInfo); VOID WINAPI DISPLAY_SetCursor( CURSORICONINFO *lpCursor ); VOID WINAPI DISPLAY_MoveCursor( WORD wAbsX, WORD wAbsY ); diff --git a/include/ttydrv.h b/include/ttydrv.h index 99d9828e487..86cbee84872 100644 --- a/include/ttydrv.h +++ b/include/ttydrv.h @@ -16,7 +16,7 @@ extern CLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver; extern void TTYDRV_CLIPBOARD_EmptyClipboard(); extern void TTYDRV_CLIPBOARD_SetClipboardData(UINT32 wFormat); extern BOOL32 TTYDRV_CLIPBOARD_RequestSelection(); -extern void TTYDRV_CLIPBOARD_ResetOwner(WND *pWnd); +extern void TTYDRV_CLIPBOARD_ResetOwner(WND *pWnd, BOOL32 bFooBar); /* TTY event driver */ diff --git a/include/win.h b/include/win.h index db015a0ea78..c575a3228ae 100644 --- a/include/win.h +++ b/include/win.h @@ -55,6 +55,7 @@ typedef enum #define RDW_C_DELETEHRGN 0x0002 struct tagDCE; +struct tagDC; struct _WND_DRIVER; typedef struct tagWND @@ -83,15 +84,20 @@ typedef struct tagWND UINT32 wIDmenu; /* ID or hmenu (from CreateWindow) */ DWORD helpContext; /* Help context ID */ WORD flags; /* Misc. flags (see below) */ +#if 0 Window window; /* X window (only for top-level windows) */ +#endif HMENU16 hSysMenu; /* window's copy of System Menu */ DWORD userdata; /* User private data */ struct _WND_DRIVER *pDriver; /* Window driver */ + void *pDriverData; /* Window driver data */ DWORD wExtra[1]; /* Window extra bytes */ } WND; typedef struct _WND_DRIVER { + void (*pInitialize)(WND *); + void (*pFinalize)(WND *); BOOL32 (*pCreateDesktopWindow)(WND *, CLASS *, BOOL32); BOOL32 (*pCreateWindow)(WND *, CLASS *, CREATESTRUCT32A *, BOOL32); BOOL32 (*pDestroyWindow)(WND *); @@ -102,6 +108,9 @@ typedef struct _WND_DRIVER void (*pSetFocus)(WND *); void (*pPreSizeMove)(WND *); void (*pPostSizeMove)(WND *); + void (*pScrollWindow)(WND *, struct tagDC *, INT32, INT32, const RECT32 *, BOOL32); + void (*pSetDrawable)(WND *, struct tagDC *, WORD, BOOL32); + BOOL32 (*pIsSelfClipping)(WND *); } WND_DRIVER; typedef struct diff --git a/include/x11drv.h b/include/x11drv.h index 61f43b28260..01dfb7ad78d 100644 --- a/include/x11drv.h +++ b/include/x11drv.h @@ -6,11 +6,17 @@ #define __WINE_X11DRV_H #include "config.h" -#include "ts_xlib.h" -#include "ts_xutil.h" + +#ifndef X_DISPLAY_MISSING +#include +#include +#include +#include +#endif /* !defined(X_DISPLAY_MISSING) */ #include "winbase.h" -#include "windows.h" +#include "wintypes.h" +#include "display.h" #include "gdi.h" #include "xmalloc.h" /* for XCREATEIMAGE macro */ #include "clipboard.h" @@ -219,10 +225,18 @@ extern int *X11DRV_DIB_BuildColorMap( struct tagDC *dc, WORD coloruse, int *nColors ); /* X11 windows driver */ + extern WND_DRIVER X11DRV_WND_Driver; -extern Window X11DRV_WND_GetXWindow(HWND32 hwnd); +typedef struct _X11DRV_WND_DATA { + Window window; +} X11DRV_WND_DATA; +extern Window X11DRV_WND_GetXWindow(WND *wndPtr); +extern Window X11DRV_WND_FindXWindow(WND *wndPtr); + +extern void X11DRV_WND_Initialize(WND *wndPtr); +extern void X11DRV_WND_Finalize(WND *wndPtr); extern BOOL32 X11DRV_WND_CreateDesktopWindow(WND *wndPtr, CLASS *classPtr, BOOL32 bUnicode); extern BOOL32 X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCT32A *cs, BOOL32 bUnicode); extern BOOL32 X11DRV_WND_DestroyWindow(WND *pWnd); @@ -233,6 +247,9 @@ extern void X11DRV_WND_SetText(WND *wndPtr, LPCSTR text); extern void X11DRV_WND_SetFocus(WND *wndPtr); extern void X11DRV_WND_PreSizeMove(WND *wndPtr); extern void X11DRV_WND_PostSizeMove(WND *wndPtr); +extern void X11DRV_WND_ScrollWindow(WND *wndPtr, DC *dcPtr, INT32 dx, INT32 dy, const RECT32 *clipRect, BOOL32 bUpdate); +extern void X11DRV_WND_SetDrawable(WND *wndPtr, DC *dc, WORD flags, BOOL32 bSetClipOrigin); +extern BOOL32 X11DRV_WND_IsSelfClipping(WND *wndPtr); /* X11 clipboard driver */ @@ -241,7 +258,7 @@ extern CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver; extern void X11DRV_CLIPBOARD_EmptyClipboard(); extern void X11DRV_CLIPBOARD_SetClipboardData(UINT32 wFormat); extern BOOL32 X11DRV_CLIPBOARD_RequestSelection(); -extern void X11DRV_CLIPBOARD_ResetOwner(WND *pWnd); +extern void X11DRV_CLIPBOARD_ResetOwner(WND *pWnd, BOOL32 bFooBar); void X11DRV_CLIPBOARD_ReadSelection(Window w, Atom prop); void X11DRV_CLIPBOARD_ReleaseSelection(Window w, HWND32 hwnd); @@ -258,9 +275,10 @@ extern INT16 X11DRV_KEYBOARD_ToAscii(UINT16 virtKey, UINT16 scanCode, LPBYTE lpK /* X11 mouse driver */ -#if 0 extern MOUSE_DRIVER X11DRV_MOUSE_Driver; -#endif + +extern void X11DRV_MOUSE_SetCursor(CURSORICONINFO *lpCursor); +extern void X11DRV_MOUSE_MoveCursor(WORD wAbsX, WORD wAbsY); /* X11 event driver */ diff --git a/objects/palette.c b/objects/palette.c index b6179a73717..e50038d75e8 100644 --- a/objects/palette.c +++ b/objects/palette.c @@ -10,8 +10,6 @@ #include #include -#include "ts_xlib.h" - #include "gdi.h" #include "color.h" #include "palette.h" diff --git a/windows/dce.c b/windows/dce.c index 0dc1d1bc485..8b7b4cc31ea 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -26,7 +26,6 @@ #include "heap.h" #include "sysmetrics.h" #include "debug.h" -#include "x11drv.h" #define NB_DCE 5 /* Number of DCEs created at startup */ @@ -380,7 +379,8 @@ static BOOL32 DCE_AddClipRects( WND *pWndStart, WND *pWndEnd, { RECT32 rect; - if (pWndStart->window) return TRUE; /* X itself will do the clipping */ + if( pWndStart->pDriver->pIsSelfClipping( pWndStart ) ) + return TRUE; /* The driver itself will do the clipping */ for (; pWndStart != pWndEnd; pWndStart = pWndStart->next) { @@ -514,57 +514,6 @@ static void DCE_OffsetVisRgn( HDC32 hDC, HRGN32 hVisRgn ) GDI_HEAP_UNLOCK( hDC ); } - -/*********************************************************************** - * DCE_SetDrawable - * - * Set the drawable, origin and dimensions for the DC associated to - * a given window. - */ -static void DCE_SetDrawable( WND *wndPtr, DC *dc, WORD flags, BOOL32 bSetClipOrigin ) -{ - X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev; - - if (!wndPtr) /* Get a DC for the whole screen */ - { - dc->w.DCOrgX = 0; - dc->w.DCOrgY = 0; - physDev->drawable = rootWindow; - TSXSetSubwindowMode( display, physDev->gc, IncludeInferiors ); - } - else - { - if (flags & DCX_WINDOW) - { - dc->w.DCOrgX = wndPtr->rectWindow.left; - dc->w.DCOrgY = wndPtr->rectWindow.top; - } - else - { - dc->w.DCOrgX = wndPtr->rectClient.left; - dc->w.DCOrgY = wndPtr->rectClient.top; - } - while (!wndPtr->window) - { - wndPtr = wndPtr->parent; - dc->w.DCOrgX += wndPtr->rectClient.left; - dc->w.DCOrgY += wndPtr->rectClient.top; - } - dc->w.DCOrgX -= wndPtr->rectWindow.left; - dc->w.DCOrgY -= wndPtr->rectWindow.top; - physDev->drawable = wndPtr->window; - -#if 0 - /* This is needed when we reuse a cached DC because - * SetDCState() called by ReleaseDC() screws up DC - * origins for child windows. - */ - - if( bSetClipOrigin ) - TSXSetClipOrigin( display, physDev->gc, dc->w.DCOrgX, dc->w.DCOrgY ); -#endif - } -} /*********************************************************************** * DCE_ExcludeRgn * @@ -745,7 +694,7 @@ HDC32 WINAPI GetDCEx32( HWND32 hwnd, HRGN32 hrgnClip, DWORD flags ) /* recompute visible region */ - DCE_SetDrawable( wndPtr, dc, flags, bUpdateClipOrigin ); + wndPtr->pDriver->pSetDrawable( wndPtr, dc, flags, bUpdateClipOrigin ); if( bUpdateVisRgn ) { TRACE(dc,"updating visrgn for %08x dce, hwnd [%04x]\n", (unsigned)dce, hwnd); diff --git a/windows/dinput.c b/windows/dinput.c index 1679ccb5057..85b2246538c 100644 --- a/windows/dinput.c +++ b/windows/dinput.c @@ -18,8 +18,6 @@ * an utter mess.) */ -#include "ts_xlib.h" - #include "config.h" #include #include diff --git a/windows/display.c b/windows/display.c index 8282cccb418..f9d748905d4 100644 --- a/windows/display.c +++ b/windows/display.c @@ -5,27 +5,19 @@ * */ -#include "ts_xlib.h" -#include "ts_xresource.h" -#include "ts_xutil.h" - -#include -#include -#include -#include "windows.h" -#include "win.h" -#include "gdi.h" -#include "display.h" -#include "callback.h" -#include "heap.h" #include "debug.h" -#include "debugtools.h" -#include "x11drv.h" +#include "display.h" +#include "wintypes.h" -Cursor DISPLAY_XCursor = None; /* Current X cursor */ - -BOOL32 DISPLAY_DisableWarpPointer = FALSE; /* hack; see DISPLAY_MoveCursor */ +extern MOUSE_DRIVER X11DRV_MOUSE_Driver; +/*********************************************************************** + * MOUSE_GetDriver() + */ +MOUSE_DRIVER *MOUSE_GetDriver() +{ + return &X11DRV_MOUSE_Driver; +} /*********************************************************************** * DISPLAY_Inquire (DISPLAY.101) @@ -38,154 +30,12 @@ WORD WINAPI DISPLAY_Inquire(LPCURSORINFO lpCursorInfo) return sizeof(CURSORINFO); } -/*********************************************************************** - * DISPLAY_DoSetCursor - */ -static BOOL32 DISPLAY_DoSetCursor( CURSORICONINFO *ptr ) -{ - Pixmap pixmapBits, pixmapMask, pixmapAll; - XColor fg, bg; - Cursor cursor = None; - - if (!ptr) /* Create an empty cursor */ - { - static const char data[] = { 0 }; - - bg.red = bg.green = bg.blue = 0x0000; - pixmapBits = XCreateBitmapFromData( display, rootWindow, data, 1, 1 ); - if (pixmapBits) - { - cursor = XCreatePixmapCursor( display, pixmapBits, pixmapBits, - &bg, &bg, 0, 0 ); - XFreePixmap( display, pixmapBits ); - } - } - else /* Create the X cursor from the bits */ - { - XImage *image; - - if (ptr->bPlanes * ptr->bBitsPerPixel != 1) - { - WARN(cursor, "Cursor has more than 1 bpp!\n" ); - return FALSE; - } - - /* Create a pixmap and transfer all the bits to it */ - - /* NOTE: Following hack works, but only because XFree depth - * 1 images really use 1 bit/pixel (and so the same layout - * as the Windows cursor data). Perhaps use a more generic - * algorithm here. - */ - pixmapAll = XCreatePixmap( display, rootWindow, - ptr->nWidth, ptr->nHeight * 2, 1 ); - image = XCreateImage( display, DefaultVisualOfScreen(screen), - 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 ); - } - - /* Now create the 2 pixmaps for bits and mask */ - - pixmapBits = XCreatePixmap( display, rootWindow, - ptr->nWidth, ptr->nHeight, 1 ); - pixmapMask = XCreatePixmap( display, rootWindow, - ptr->nWidth, ptr->nHeight, 1 ); - - /* Make sure everything went OK so far */ - - if (pixmapBits && pixmapMask && pixmapAll) - { - /* We have to do some magic here, as cursors are not fully - * compatible between Windows and X11. Under X11, there - * are only 3 possible color cursor: black, white and - * masked. So we map the 4th Windows color (invert the - * bits on the screen) to black. This require some boolean - * arithmetic: - * - * Windows | X11 - * Xor And Result | Bits Mask Result - * 0 0 black | 0 1 background - * 0 1 no change | X 0 no change - * 1 0 white | 1 1 foreground - * 1 1 inverted | 0 1 background - * - * which gives: - * Bits = 'Xor' and not 'And' - * Mask = 'Xor' or not 'And' - * - * FIXME: apparently some servers do support 'inverted' color. - * I don't know if it's correct per the X spec, but maybe - * we ought to take advantage of it. -- AJ - */ - XCopyArea( display, pixmapAll, pixmapBits, BITMAP_monoGC, - 0, 0, ptr->nWidth, ptr->nHeight, 0, 0 ); - XCopyArea( display, pixmapAll, pixmapMask, BITMAP_monoGC, - 0, 0, ptr->nWidth, ptr->nHeight, 0, 0 ); - XSetFunction( display, BITMAP_monoGC, GXandReverse ); - XCopyArea( display, pixmapAll, pixmapBits, BITMAP_monoGC, - 0, ptr->nHeight, ptr->nWidth, ptr->nHeight, 0, 0 ); - XSetFunction( display, BITMAP_monoGC, GXorReverse ); - XCopyArea( display, pixmapAll, pixmapMask, BITMAP_monoGC, - 0, ptr->nHeight, ptr->nWidth, ptr->nHeight, 0, 0 ); - XSetFunction( display, BITMAP_monoGC, GXcopy ); - fg.red = fg.green = fg.blue = 0xffff; - bg.red = bg.green = bg.blue = 0x0000; - cursor = XCreatePixmapCursor( display, pixmapBits, pixmapMask, - &fg, &bg, ptr->ptHotSpot.x, ptr->ptHotSpot.y ); - } - - /* Now free everything */ - - if (pixmapAll) XFreePixmap( display, pixmapAll ); - if (pixmapBits) XFreePixmap( display, pixmapBits ); - if (pixmapMask) XFreePixmap( display, pixmapMask ); - } - - if (cursor == None) return FALSE; - if (DISPLAY_XCursor != None) XFreeCursor( display, DISPLAY_XCursor ); - DISPLAY_XCursor = cursor; - - if (rootWindow != DefaultRootWindow(display) || !WIN_GetDesktop()) - { - /* Set the cursor on the desktop window */ - XDefineCursor( display, rootWindow, cursor ); - } - else - { - /* FIXME: this won't work correctly with native USER !*/ - - /* Set the same cursor for all top-level windows */ - HWND32 hwnd = GetWindow32( GetDesktopWindow32(), GW_CHILD ); - while(hwnd) - { - Window win = X11DRV_WND_GetXWindow( hwnd ); - if (win && win!=DefaultRootWindow(display)) - XDefineCursor( display, win, cursor ); - hwnd = GetWindow32( hwnd, GW_HWNDNEXT ); - } - } - return TRUE; -} - /*********************************************************************** * DISPLAY_SetCursor (DISPLAY.102) */ VOID WINAPI DISPLAY_SetCursor( CURSORICONINFO *lpCursor ) { - EnterCriticalSection( &X11DRV_CritSection ); - CALL_LARGE_STACK( DISPLAY_DoSetCursor, lpCursor ); - LeaveCriticalSection( &X11DRV_CritSection ); + MOUSE_GetDriver()->pSetCursor(lpCursor); } /*********************************************************************** @@ -193,40 +43,7 @@ VOID WINAPI DISPLAY_SetCursor( CURSORICONINFO *lpCursor ) */ VOID WINAPI DISPLAY_MoveCursor( WORD wAbsX, WORD wAbsY ) { - /* - * We do not want the to create MotionNotify events here, - * otherwise we will get an endless recursion: - * XMotionEvent -> MOUSEEVENTF_MOVE -> mouse_event -> DisplayMoveCursor - * -> XWarpPointer -> XMotionEvent -> ... - * - * Unfortunately, the XWarpPointer call does create a MotionNotify - * event. So, we use a hack: before MOUSE_SendEvent calls the mouse event - * procedure, it sets a global flag. If this flag is set, we skip the - * XWarpPointer call. If we are *not* called from within MOUSE_SendEvent, - * we will call XWarpPointer, which will create a MotionNotify event. - * Strictly speaking, this is also wrong, but that should normally not - * have any negative effects ... - * - * 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. - */ - - Window root, child; - int rootX, rootY, winX, winY; - unsigned int xstate; - - if (DISPLAY_DisableWarpPointer) return; - - if (!TSXQueryPointer( display, rootWindow, &root, &child, - &rootX, &rootY, &winX, &winY, &xstate )) - return; - - if ( winX == wAbsX && winY == wAbsY ) - return; - - TRACE( cursor, "(%d,%d): moving from (%d,%d)\n", wAbsX, wAbsY, winX, winY ); - - TSXWarpPointer( display, rootWindow, rootWindow, 0, 0, 0, 0, wAbsX, wAbsY ); + MOUSE_GetDriver()->pMoveCursor(wAbsX, wAbsY); } /*********************************************************************** @@ -244,4 +61,3 @@ VOID WINAPI UserRepaintDisable( BOOL16 disable ) { TRACE( cursor, "(%d): stub\n", disable ); } - diff --git a/windows/input.c b/windows/input.c index f82585bcff7..eafecf05fb0 100644 --- a/windows/input.c +++ b/windows/input.c @@ -22,11 +22,11 @@ #include "keyboard.h" #include "mouse.h" #include "message.h" +#include "sysmetrics.h" #include "debug.h" #include "debugtools.h" #include "struct32.h" #include "winerror.h" -#include "x11drv.h" static INT16 captureHT = HTCLIENT; static HWND32 captureWnd = 0; @@ -162,8 +162,8 @@ void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy, extra = (DWORD)wme->hWnd; assert( dwFlags & MOUSEEVENTF_ABSOLUTE ); - posX = (dx * screenWidth) >> 16; - posY = (dy * screenHeight) >> 16; + posX = (dx * SYSMETRICS_CXSCREEN) >> 16; + posY = (dy * SYSMETRICS_CYSCREEN) >> 16; } else { @@ -177,8 +177,8 @@ void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy, { if ( dwFlags & MOUSEEVENTF_ABSOLUTE ) { - posX = (dx * screenWidth) >> 16; - posY = (dy * screenHeight) >> 16; + posX = (dx * SYSMETRICS_CXSCREEN) >> 16; + posY = (dy * SYSMETRICS_CYSCREEN) >> 16; } else { diff --git a/windows/message.c b/windows/message.c index 5da24fdde6e..300ae1b2c2f 100644 --- a/windows/message.c +++ b/windows/message.c @@ -4,8 +4,6 @@ * Copyright 1993, 1994 Alexandre Julliard */ -#include "ts_xlib.h" - #include #include #include diff --git a/windows/scroll.c b/windows/scroll.c index 2db40ff23a7..3da5e8ada18 100644 --- a/windows/scroll.c +++ b/windows/scroll.c @@ -17,7 +17,6 @@ #include "region.h" #include "sysmetrics.h" #include "debug.h" -#include "x11drv.h" /************************************************************************* * ScrollWindow16 (USER.61) @@ -345,29 +344,7 @@ rect?rect->left:0, rect?rect->top:0, rect ?rect->right:0, rect ?rect->bottom:0, ((flags & SW_SCROLLCHILDREN) ? DCX_NOCLIPCHILDREN : 0) ); if( (dc = (DC *)GDI_GetObjPtr(hDC, DC_MAGIC)) ) { - X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev; - POINT32 dst, src; - - if( dx > 0 ) dst.x = (src.x = dc->w.DCOrgX + cliprc.left) + dx; - else src.x = (dst.x = dc->w.DCOrgX + cliprc.left) - dx; - - if( dy > 0 ) dst.y = (src.y = dc->w.DCOrgY + cliprc.top) + dy; - else src.y = (dst.y = dc->w.DCOrgY + cliprc.top) - dy; - - if ((cliprc.right - cliprc.left > abs(dx)) && - (cliprc.bottom - cliprc.top > abs(dy))) - { - if (bUpdate) /* handles non-Wine windows hanging over the scrolled area */ - TSXSetGraphicsExposures( display, physDev->gc, True ); - TSXSetFunction( display, physDev->gc, GXcopy ); - TSXCopyArea( display, physDev->drawable, physDev->drawable, - physDev->gc, src.x, src.y, - cliprc.right - cliprc.left - abs(dx), - cliprc.bottom - cliprc.top - abs(dy), - dst.x, dst.y ); - if (bUpdate) - TSXSetGraphicsExposures( display, physDev->gc, False ); - } + wnd->pDriver->pScrollWindow(wnd,dc,dx,dy,&cliprc,bUpdate); if( dc->w.hVisRgn && bUpdate ) { diff --git a/windows/ttydrv/clipboard.c b/windows/ttydrv/clipboard.c index 48dbd6fd3d9..58701ffa616 100644 --- a/windows/ttydrv/clipboard.c +++ b/windows/ttydrv/clipboard.c @@ -43,6 +43,6 @@ BOOL32 TTYDRV_CLIPBOARD_RequestSelection() /*********************************************************************** * TTYDRV_CLIPBOARD_ResetOwner */ -void TTYDRV_CLIPBOARD_ResetOwner(WND *pWnd) +void TTYDRV_CLIPBOARD_ResetOwner(WND *pWnd, BOOL32 bFooBar) { } diff --git a/windows/ttydrv/event.c b/windows/ttydrv/event.c index 9c92afac04c..2ac93cdaf10 100644 --- a/windows/ttydrv/event.c +++ b/windows/ttydrv/event.c @@ -66,6 +66,8 @@ BOOL32 TTYDRV_EVENT_QueryPointer(DWORD *posX, DWORD *posY, DWORD *state) if(state) *state = 0; + + return TRUE; } /*********************************************************************** diff --git a/windows/ttydrv/init.c b/windows/ttydrv/init.c index 99139bfffea..d6f6734a21a 100644 --- a/windows/ttydrv/init.c +++ b/windows/ttydrv/init.c @@ -11,6 +11,8 @@ #if 0 WND_DRIVER TTYDRV_WND_Driver = { + TTYDRV_WND_Initialize, + TTYDRV_WND_Finalize, TTYDRV_WND_CreateDesktopWindow, TTYDRV_WND_CreateWindow, TTYDRV_WND_DestroyWindow, diff --git a/windows/win.c b/windows/win.c index 1551a373dcf..10b1612369c 100644 --- a/windows/win.c +++ b/windows/win.c @@ -322,6 +322,7 @@ static WND* WIN_DestroyWindow( WND* wndPtr ) wndPtr->class = NULL; pWnd = wndPtr->next; + wndPtr->pDriver->pFinalize(wndPtr); USER_HEAP_FREE( hwnd ); return pWnd; } @@ -395,6 +396,9 @@ BOOL32 WIN_CreateDesktopWindow(void) if (!hwndDesktop) return FALSE; pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop ); + pWndDesktop->pDriver = &X11DRV_WND_Driver; + pWndDesktop->pDriver->pInitialize(pWndDesktop); + pWndDesktop->next = NULL; pWndDesktop->child = NULL; pWndDesktop->parent = NULL; @@ -424,7 +428,6 @@ BOOL32 WIN_CreateDesktopWindow(void) pWndDesktop->flags = 0; pWndDesktop->hSysMenu = 0; pWndDesktop->userdata = 0; - pWndDesktop->pDriver = &X11DRV_WND_Driver; pWndDesktop->winproc = (WNDPROC16)class->winproc; /* FIXME: How do we know if it should be Unicode or not */ @@ -543,8 +546,9 @@ static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom, wndPtr->owner = WIN_GetTopParentPtr(WIN_FindWndPtr(cs->hwndParent)); } - wndPtr->pDriver = &X11DRV_WND_Driver; - wndPtr->window = 0; + wndPtr->pDriver = wndPtr->parent->pDriver; + wndPtr->pDriver->pInitialize(wndPtr); + wndPtr->class = classPtr; wndPtr->winproc = classPtr->winproc; wndPtr->dwMagic = WND_MAGIC; @@ -585,6 +589,7 @@ static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom, if (ret) { TRACE(win, "CBT-hook returned 0\n"); + wndPtr->pDriver->pFinalize(wndPtr); USER_HEAP_FREE( hwnd ); return 0; } @@ -916,7 +921,7 @@ static void WIN_SendDestroyMsg( WND* pWnd ) WIN_CheckFocus(pWnd); if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32(); - if( !pWnd->window ) CLIPBOARD_GetDriver()->pResetOwner( pWnd ); + CLIPBOARD_GetDriver()->pResetOwner( pWnd, TRUE ); SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0); @@ -978,7 +983,7 @@ BOOL32 WINAPI DestroyWindow32( HWND32 hwnd ) if( !IsWindow32(hwnd) ) return TRUE; } - if( wndPtr->window ) CLIPBOARD_GetDriver()->pResetOwner( wndPtr ); /* before the window is unmapped */ + CLIPBOARD_GetDriver()->pResetOwner( wndPtr, FALSE ); /* before the window is unmapped */ /* Hide the window */ diff --git a/windows/winpos.c b/windows/winpos.c index b9abdfb5dff..a5fba131c7d 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -20,6 +20,7 @@ #include "dce.h" #include "nonclient.h" #include "debug.h" +#include "x11drv.h" #define HAS_DLGFRAME(style,exStyle) \ (((exStyle) & WS_EX_DLGMODALFRAME) || \ @@ -2108,7 +2109,7 @@ BOOL32 WINAPI SetWindowPos32( HWND32 hwnd, HWND32 hwndInsertAfter, if( wnd->next == wndPtr ) flags |= SWP_NOZORDER; } } - else if (!(wndPtr->window)) + else if (!((X11DRV_WND_DATA *) wndPtr->pDriverData)->window) { /* FIXME: the following optimization is no good for "X-ed" windows */ if (hwndInsertAfter == HWND_TOP) @@ -2166,7 +2167,7 @@ BOOL32 WINAPI SetWindowPos32( HWND32 hwnd, HWND32 hwndInsertAfter, hwndInsertAfter = WINPOS_ReorderOwnedPopups( hwndInsertAfter, wndPtr, winpos.flags ); - if (wndPtr->window) + if (((X11DRV_WND_DATA *) wndPtr->pDriverData)->window) { WIN_UnlinkWindow( winpos.hwnd ); WIN_LinkWindow( winpos.hwnd, hwndInsertAfter ); @@ -2174,7 +2175,7 @@ BOOL32 WINAPI SetWindowPos32( HWND32 hwnd, HWND32 hwndInsertAfter, else WINPOS_MoveWindowZOrder( winpos.hwnd, hwndInsertAfter ); } - if ( !wndPtr->window && !(winpos.flags & SWP_NOREDRAW) && + if ( !((X11DRV_WND_DATA *) wndPtr->pDriverData)->window && !(winpos.flags & SWP_NOREDRAW) && ((winpos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED)) != (SWP_NOMOVE | SWP_NOSIZE)) ) visRgn = DCE_GetVisRgn(hwnd, DCX_WINDOW | DCX_CLIPSIBLINGS); @@ -2222,7 +2223,7 @@ BOOL32 WINAPI SetWindowPos32( HWND32 hwnd, HWND32 hwndInsertAfter, oldWindowRect = wndPtr->rectWindow; - if (wndPtr->window) + if (((X11DRV_WND_DATA *) wndPtr->pDriverData)->window) { RECT32 oldClientRect = wndPtr->rectClient; @@ -2325,7 +2326,7 @@ BOOL32 WINAPI SetWindowPos32( HWND32 hwnd, HWND32 hwndInsertAfter, if (flags & SWP_SHOWWINDOW) { wndPtr->dwStyle |= WS_VISIBLE; - if (wndPtr->window) + if (((X11DRV_WND_DATA *) wndPtr->pDriverData)->window) { HWND32 focus, curr; @@ -2360,7 +2361,7 @@ BOOL32 WINAPI SetWindowPos32( HWND32 hwnd, HWND32 hwndInsertAfter, { wndPtr->dwStyle &= ~WS_VISIBLE; - if (wndPtr->window) + if (((X11DRV_WND_DATA *) wndPtr->pDriverData)->window) { wndPtr->pDriver->pSetWindowPos(wndPtr, &winpos, uFlags & SMC_SETXPOS ); if( uFlags & SMC_SETXPOS ) @@ -2396,7 +2397,8 @@ BOOL32 WINAPI SetWindowPos32( HWND32 hwnd, HWND32 hwndInsertAfter, /* Repaint the window */ - if (wndPtr->window) EVENT_Synchronize(); /* Wait for all expose events */ + if (((X11DRV_WND_DATA *) wndPtr->pDriverData)->window) + EVENT_Synchronize(); /* Wait for all expose events */ if (!GetCapture32()) EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */ diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c index 39c1f47cd24..7d987378c42 100644 --- a/windows/x11drv/clipboard.c +++ b/windows/x11drv/clipboard.c @@ -38,19 +38,21 @@ static Window selectionPrevWindow = None; */ static void X11DRV_CLIPBOARD_CheckSelection(WND* pWnd) { - TRACE(clipboard,"\tchecking %08x\n", (unsigned)pWnd->window); + TRACE(clipboard,"\tchecking %08x\n", + (unsigned) X11DRV_WND_GetXWindow(pWnd) + ); if( selectionAcquired && selectionWindow != None && - pWnd->window == selectionWindow ) + X11DRV_WND_GetXWindow(pWnd) == selectionWindow ) { selectionPrevWindow = selectionWindow; selectionWindow = None; if( pWnd->next ) - selectionWindow = pWnd->next->window; + selectionWindow = X11DRV_WND_GetXWindow(pWnd->next); else if( pWnd->parent ) if( pWnd->parent->child != pWnd ) - selectionWindow = pWnd->parent->child->window; + selectionWindow = X11DRV_WND_GetXWindow(pWnd->parent->child); TRACE(clipboard,"\tswitching selection from %08x to %08x\n", (unsigned)selectionPrevWindow, (unsigned)selectionWindow); @@ -208,7 +210,9 @@ void X11DRV_CLIPBOARD_SetClipboardData(UINT32 wFormat) if( !selectionAcquired && (wFormat == CF_TEXT || wFormat == CF_OEMTEXT) ) { - owner = X11DRV_WND_GetXWindow( hWndClipWindow ? hWndClipWindow : AnyPopup32() ); + owner = X11DRV_WND_FindXWindow( + WIN_FindWndPtr( hWndClipWindow ? hWndClipWindow : AnyPopup32() ) + ); TSXSetSelectionOwner(display,XA_PRIMARY, owner, CurrentTime); if( TSXGetSelectionOwner(display,XA_PRIMARY) == owner ) @@ -240,9 +244,10 @@ BOOL32 X11DRV_CLIPBOARD_RequestSelection() * CLIPBOARD_ReadSelection() will be invoked * from the SelectionNotify event handler */ - TSXConvertSelection(display,XA_PRIMARY,XA_STRING, - TSXInternAtom(display,"PRIMARY_TEXT",False), - X11DRV_WND_GetXWindow(hWnd),CurrentTime); + TSXConvertSelection(display, XA_PRIMARY, XA_STRING, + TSXInternAtom(display, "PRIMARY_TEXT", False), + X11DRV_WND_FindXWindow( WIN_FindWndPtr( hWnd ) ), + CurrentTime); /* wait until SelectionNotify is processed * @@ -265,10 +270,16 @@ BOOL32 X11DRV_CLIPBOARD_RequestSelection() * * Called from DestroyWindow(). */ -void X11DRV_CLIPBOARD_ResetOwner(WND *pWnd) +void X11DRV_CLIPBOARD_ResetOwner(WND *pWnd, BOOL32 bFooBar) { LPCLIPFORMAT lpFormat = ClipFormats; + if(bFooBar && X11DRV_WND_GetXWindow(pWnd)) + return; + + if(!bFooBar && !X11DRV_WND_GetXWindow(pWnd)) + return; + TRACE(clipboard,"clipboard owner = %04x, selection = %08x\n", hWndClipOwner, (unsigned)selectionWindow); @@ -293,7 +304,7 @@ void X11DRV_CLIPBOARD_ResetOwner(WND *pWnd) /* now try to salvage current selection from being destroyed by X */ - if( pWnd->window ) X11DRV_CLIPBOARD_CheckSelection(pWnd); + if( X11DRV_WND_GetXWindow(pWnd) ) X11DRV_CLIPBOARD_CheckSelection(pWnd); } #endif /* !defined(X_DISPLAY_MISSING) */ diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c index 0a47590ddff..fc4b0b7f10a 100644 --- a/windows/x11drv/event.c +++ b/windows/x11drv/event.c @@ -1,5 +1,5 @@ /* - * X11 windows driver + * X11 event driver * * Copyright 1993 Alexandre Julliard */ @@ -526,11 +526,12 @@ static BOOL32 EVENT_QueryZOrder( WND* pWndCheck ) if( !__check_query_condition(&pWndZ, &pWnd) ) return TRUE; - parent = __get_common_ancestor( pWndZ->window, pWnd->window, + parent = __get_common_ancestor( X11DRV_WND_GetXWindow(pWndZ), + X11DRV_WND_GetXWindow(pWnd), &children, &total ); if( parent && children ) { - w = __get_top_decoration( pWndCheck->window, parent ); + w = __get_top_decoration( X11DRV_WND_GetXWindow(pWndCheck), parent ); if( w != children[total - 1] ) { check = __td_lookup( w, children, total ); @@ -540,7 +541,7 @@ static BOOL32 EVENT_QueryZOrder( WND* pWndCheck ) if( pWnd != pWndCheck ) { if( !(pWnd->flags & WIN_MANAGED) || - !(w = __get_top_decoration( pWnd->window, parent )) ) + !(w = __get_top_decoration( X11DRV_WND_GetXWindow(pWnd), parent )) ) continue; pos = __td_lookup( w, children, total ); if( pos < best && pos > check ) @@ -1029,7 +1030,7 @@ static void EVENT_DropFromOffiX( WND *pWnd, XClientMessageEvent *event ) if( !lpDragInfo || !spDragInfo ) return; - TSXQueryPointer( display, pWnd->window, &w_aux_root, &w_aux_child, + TSXQueryPointer( display, X11DRV_WND_GetXWindow(pWnd), &w_aux_root, &w_aux_child, &x, &y, &u.pt_aux.x, &u.pt_aux.y, (unsigned int*)&aux_long); lpDragInfo->hScope = pWnd->hwndSelf; diff --git a/windows/x11drv/init.c b/windows/x11drv/init.c index cdae2aad8b1..734b8a53719 100644 --- a/windows/x11drv/init.c +++ b/windows/x11drv/init.c @@ -12,6 +12,8 @@ WND_DRIVER X11DRV_WND_Driver = { + X11DRV_WND_Initialize, + X11DRV_WND_Finalize, X11DRV_WND_CreateDesktopWindow, X11DRV_WND_CreateWindow, X11DRV_WND_DestroyWindow, @@ -21,7 +23,10 @@ WND_DRIVER X11DRV_WND_Driver = X11DRV_WND_SetText, X11DRV_WND_SetFocus, X11DRV_WND_PreSizeMove, - X11DRV_WND_PostSizeMove + X11DRV_WND_PostSizeMove, + X11DRV_WND_ScrollWindow, + X11DRV_WND_SetDrawable, + X11DRV_WND_IsSelfClipping }; CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver = @@ -55,16 +60,12 @@ EVENT_DRIVER X11DRV_EVENT_Driver = X11DRV_EVENT_IsUserIdle }; -#if 0 MOUSE_DRIVER X11DRV_MOUSE_Driver = { + X11DRV_MOUSE_SetCursor, + X11DRV_MOUSE_MoveCursor }; -#endif #endif /* !defined(X_DISPLAY_MISSING) */ - - - - diff --git a/windows/x11drv/mouse.c b/windows/x11drv/mouse.c index ed87b981f1e..6015636c1f8 100644 --- a/windows/x11drv/mouse.c +++ b/windows/x11drv/mouse.c @@ -1,13 +1,215 @@ /* - * X11 windows driver + * X11 mouse driver * - * Copyright 1998 Patrik Stridvall + * Copyright 1998 Ulrich Weigand */ #include "config.h" #ifndef X_DISPLAY_MISSING +#include "ts_xlib.h" + +#include "debug.h" +#include "callback.h" +#include "wintypes.h" #include "x11drv.h" +/**********************************************************************/ + +Cursor DISPLAY_XCursor = None; /* Current X cursor */ + +BOOL32 DISPLAY_DisableWarpPointer = FALSE; /* hack; see DISPLAY_MoveCursor */ + +/*********************************************************************** + * X11DRV_MOUSE_DoSetCursor + */ +static BOOL32 X11DRV_MOUSE_DoSetCursor( CURSORICONINFO *ptr ) +{ + Pixmap pixmapBits, pixmapMask, pixmapAll; + XColor fg, bg; + Cursor cursor = None; + + if (!ptr) /* Create an empty cursor */ + { + static const char data[] = { 0 }; + + bg.red = bg.green = bg.blue = 0x0000; + pixmapBits = XCreateBitmapFromData( display, rootWindow, data, 1, 1 ); + if (pixmapBits) + { + cursor = XCreatePixmapCursor( display, pixmapBits, pixmapBits, + &bg, &bg, 0, 0 ); + XFreePixmap( display, pixmapBits ); + } + } + else /* Create the X cursor from the bits */ + { + XImage *image; + + if (ptr->bPlanes * ptr->bBitsPerPixel != 1) + { + WARN(cursor, "Cursor has more than 1 bpp!\n" ); + return FALSE; + } + + /* Create a pixmap and transfer all the bits to it */ + + /* NOTE: Following hack works, but only because XFree depth + * 1 images really use 1 bit/pixel (and so the same layout + * as the Windows cursor data). Perhaps use a more generic + * algorithm here. + */ + pixmapAll = XCreatePixmap( display, rootWindow, + ptr->nWidth, ptr->nHeight * 2, 1 ); + image = XCreateImage( display, DefaultVisualOfScreen(screen), + 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 ); + } + + /* Now create the 2 pixmaps for bits and mask */ + + pixmapBits = XCreatePixmap( display, rootWindow, + ptr->nWidth, ptr->nHeight, 1 ); + pixmapMask = XCreatePixmap( display, rootWindow, + ptr->nWidth, ptr->nHeight, 1 ); + + /* Make sure everything went OK so far */ + + if (pixmapBits && pixmapMask && pixmapAll) + { + /* We have to do some magic here, as cursors are not fully + * compatible between Windows and X11. Under X11, there + * are only 3 possible color cursor: black, white and + * masked. So we map the 4th Windows color (invert the + * bits on the screen) to black. This require some boolean + * arithmetic: + * + * Windows | X11 + * Xor And Result | Bits Mask Result + * 0 0 black | 0 1 background + * 0 1 no change | X 0 no change + * 1 0 white | 1 1 foreground + * 1 1 inverted | 0 1 background + * + * which gives: + * Bits = 'Xor' and not 'And' + * Mask = 'Xor' or not 'And' + * + * FIXME: apparently some servers do support 'inverted' color. + * I don't know if it's correct per the X spec, but maybe + * we ought to take advantage of it. -- AJ + */ + XCopyArea( display, pixmapAll, pixmapBits, BITMAP_monoGC, + 0, 0, ptr->nWidth, ptr->nHeight, 0, 0 ); + XCopyArea( display, pixmapAll, pixmapMask, BITMAP_monoGC, + 0, 0, ptr->nWidth, ptr->nHeight, 0, 0 ); + XSetFunction( display, BITMAP_monoGC, GXandReverse ); + XCopyArea( display, pixmapAll, pixmapBits, BITMAP_monoGC, + 0, ptr->nHeight, ptr->nWidth, ptr->nHeight, 0, 0 ); + XSetFunction( display, BITMAP_monoGC, GXorReverse ); + XCopyArea( display, pixmapAll, pixmapMask, BITMAP_monoGC, + 0, ptr->nHeight, ptr->nWidth, ptr->nHeight, 0, 0 ); + XSetFunction( display, BITMAP_monoGC, GXcopy ); + fg.red = fg.green = fg.blue = 0xffff; + bg.red = bg.green = bg.blue = 0x0000; + cursor = XCreatePixmapCursor( display, pixmapBits, pixmapMask, + &fg, &bg, ptr->ptHotSpot.x, ptr->ptHotSpot.y ); + } + + /* Now free everything */ + + if (pixmapAll) XFreePixmap( display, pixmapAll ); + if (pixmapBits) XFreePixmap( display, pixmapBits ); + if (pixmapMask) XFreePixmap( display, pixmapMask ); + } + + if (cursor == None) return FALSE; + if (DISPLAY_XCursor != None) XFreeCursor( display, DISPLAY_XCursor ); + DISPLAY_XCursor = cursor; + + if (rootWindow != DefaultRootWindow(display) || !WIN_GetDesktop()) + { + /* Set the cursor on the desktop window */ + XDefineCursor( display, rootWindow, cursor ); + } + else + { + /* FIXME: this won't work correctly with native USER !*/ + + /* Set the same cursor for all top-level windows */ + HWND32 hwnd = GetWindow32( GetDesktopWindow32(), GW_CHILD ); + while(hwnd) + { + Window win = X11DRV_WND_FindXWindow( WIN_FindWndPtr( hwnd ) ); + if (win && win!=DefaultRootWindow(display)) + XDefineCursor( display, win, cursor ); + hwnd = GetWindow32( hwnd, GW_HWNDNEXT ); + } + } + return TRUE; +} + +/*********************************************************************** + * X11DRV_MOUSE_SetCursor + */ +void X11DRV_MOUSE_SetCursor( CURSORICONINFO *lpCursor ) +{ + EnterCriticalSection( &X11DRV_CritSection ); + CALL_LARGE_STACK( X11DRV_MOUSE_DoSetCursor, lpCursor ); + LeaveCriticalSection( &X11DRV_CritSection ); +} + +/*********************************************************************** + * X11DRV_MOUSE_MoveCursor + */ +void X11DRV_MOUSE_MoveCursor(WORD wAbsX, WORD wAbsY) +{ + /* + * We do not want the to create MotionNotify events here, + * otherwise we will get an endless recursion: + * XMotionEvent -> MOUSEEVENTF_MOVE -> mouse_event -> DisplayMoveCursor + * -> XWarpPointer -> XMotionEvent -> ... + * + * Unfortunately, the XWarpPointer call does create a MotionNotify + * event. So, we use a hack: before MOUSE_SendEvent calls the mouse event + * procedure, it sets a global flag. If this flag is set, we skip the + * XWarpPointer call. If we are *not* called from within MOUSE_SendEvent, + * we will call XWarpPointer, which will create a MotionNotify event. + * Strictly speaking, this is also wrong, but that should normally not + * have any negative effects ... + * + * 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. + */ + + Window root, child; + int rootX, rootY, winX, winY; + unsigned int xstate; + + if (DISPLAY_DisableWarpPointer) return; + + if (!TSXQueryPointer( display, rootWindow, &root, &child, + &rootX, &rootY, &winX, &winY, &xstate )) + return; + + if ( winX == wAbsX && winY == wAbsY ) + return; + + TRACE( cursor, "(%d,%d): moving from (%d,%d)\n", wAbsX, wAbsY, winX, winY ); + + TSXWarpPointer( display, rootWindow, rootWindow, 0, 0, 0, 0, wAbsX, wAbsY ); +} + #endif /* !defined(X_DISPLAY_MISSING) */ diff --git a/windows/x11drv/wnd.c b/windows/x11drv/wnd.c index cf5ae7b4bda..2575e381f4d 100644 --- a/windows/x11drv/wnd.c +++ b/windows/x11drv/wnd.c @@ -17,12 +17,14 @@ #include #include #include "color.h" +#include "debug.h" #include "display.h" #include "dce.h" #include "options.h" #include "message.h" +#include "heap.h" #include "win.h" -#include "windows.h" +#include "wintypes.h" #include "x11drv.h" /**********************************************************************/ @@ -40,15 +42,28 @@ Atom dndProtocol = None; Atom dndSelection = None; /*********************************************************************** - * X11DRV_WND_GetXWindow + * X11DRV_WND_GetXWindow * * Return the X window associated to a window. */ -Window X11DRV_WND_GetXWindow(HWND32 hwnd) +Window X11DRV_WND_GetXWindow(WND *wndPtr) { - WND *wndPtr = WIN_FindWndPtr( hwnd ); - while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent; - return wndPtr ? wndPtr->window : 0; + return wndPtr ? + ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window : 0; +} + +/*********************************************************************** + * X11DRV_WND_FindXWindow + * + * Return the the first X window associated to a window chain. + */ +Window X11DRV_WND_FindXWindow(WND *wndPtr) +{ + while (wndPtr && + !((X11DRV_WND_DATA *) wndPtr->pDriverData)->window) + wndPtr = wndPtr->parent; + return wndPtr ? + ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window : 0; } /*********************************************************************** @@ -58,10 +73,42 @@ Window X11DRV_WND_GetXWindow(HWND32 hwnd) */ static void X11DRV_WND_RegisterWindow(WND *pWnd) { - TSXSetWMProtocols( display, pWnd->window, &wmDeleteWindow, 1 ); + TSXSetWMProtocols( display, X11DRV_WND_GetXWindow(pWnd), &wmDeleteWindow, 1 ); if (!winContext) winContext = TSXUniqueContext(); - TSXSaveContext( display, pWnd->window, winContext, (char *)pWnd ); + TSXSaveContext( display, X11DRV_WND_GetXWindow(pWnd), winContext, (char *)pWnd ); +} + +/********************************************************************** + * X11DRV_WND_Initialize + */ +void X11DRV_WND_Initialize(WND *wndPtr) +{ + X11DRV_WND_DATA *pWndDriverData = + (X11DRV_WND_DATA *) HeapAlloc(SystemHeap, 0, sizeof(X11DRV_WND_DATA)); + + wndPtr->pDriverData = (void *) pWndDriverData; + + pWndDriverData->window = 0; +} + +/********************************************************************** + * X11DRV_WND_Finalize + */ +void X11DRV_WND_Finalize(WND *wndPtr) +{ + X11DRV_WND_DATA *pWndDriverData = + (X11DRV_WND_DATA *) wndPtr->pDriverData; + + if(pWndDriverData->window) + { + ERR(win, + "WND destroyed without destroying " + "the associated X Window (%ld)\n", + pWndDriverData->window + ); + } + HeapFree(SystemHeap, 0, wndPtr->pDriverData); } /********************************************************************** @@ -78,7 +125,7 @@ BOOL32 X11DRV_WND_CreateDesktopWindow(WND *wndPtr, CLASS *classPtr, BOOL32 bUnic if( dndSelection == None ) dndSelection = TSXInternAtom( display, "DndSelection" , False ); - wndPtr->window = rootWindow; + ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = rootWindow; X11DRV_WND_RegisterWindow( wndPtr ); return TRUE; @@ -118,14 +165,15 @@ BOOL32 X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCT32A *cs win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful; win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0); win_attr.cursor = DISPLAY_XCursor; - wndPtr->window = TSXCreateWindow( display, rootWindow, cs->x, cs->y, - cs->cx, cs->cy, 0, CopyFromParent, - InputOutput, CopyFromParent, - CWEventMask | CWOverrideRedirect | - CWColormap | CWCursor | CWSaveUnder | - CWBackingStore, &win_attr ); - - if(!wndPtr->window) + ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = + TSXCreateWindow( display, rootWindow, cs->x, cs->y, + cs->cx, cs->cy, 0, CopyFromParent, + InputOutput, CopyFromParent, + CWEventMask | CWOverrideRedirect | + CWColormap | CWCursor | CWSaveUnder | + CWBackingStore, &win_attr ); + + if(!X11DRV_WND_GetXWindow(wndPtr)) return FALSE; if (wndPtr->flags & WIN_MANAGED) { @@ -134,7 +182,7 @@ BOOL32 X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCT32A *cs if (class_hints) { class_hints->res_name = "wineManaged"; class_hints->res_class = "Wine"; - TSXSetClassHint( display, wndPtr->window, class_hints ); + TSXSetClassHint( display, ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window, class_hints ); TSXFree (class_hints); } @@ -145,7 +193,7 @@ BOOL32 X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCT32A *cs size_hints->min_width = size_hints->max_width = cs->cx; size_hints->min_height = size_hints->max_height = cs->cy; size_hints->flags = (PSize | PMinSize | PMaxSize); - TSXSetWMSizeHints( display, wndPtr->window, size_hints, + TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr), size_hints, XA_WM_NORMAL_HINTS ); TSXFree(size_hints); } @@ -154,8 +202,8 @@ BOOL32 X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCT32A *cs if (cs->hwndParent) /* Get window owner */ { - Window win = X11DRV_WND_GetXWindow( cs->hwndParent ); - if (win) TSXSetTransientForHint( display, wndPtr->window, win ); + Window win = X11DRV_WND_FindXWindow( WIN_FindWndPtr( cs->hwndParent ) ); + if (win) TSXSetTransientForHint( display, X11DRV_WND_GetXWindow(wndPtr), win ); } X11DRV_WND_RegisterWindow( wndPtr ); } @@ -167,13 +215,13 @@ BOOL32 X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCT32A *cs */ BOOL32 X11DRV_WND_DestroyWindow(WND *pWnd) { - if (pWnd->window) + if (X11DRV_WND_GetXWindow(pWnd)) { XEvent xe; - TSXDeleteContext( display, pWnd->window, winContext ); - TSXDestroyWindow( display, pWnd->window ); - while( TSXCheckWindowEvent(display, pWnd->window, NoEventMask, &xe) ); - pWnd->window = None; + TSXDeleteContext( display, X11DRV_WND_GetXWindow(pWnd), winContext ); + TSXDestroyWindow( display, X11DRV_WND_GetXWindow(pWnd) ); + while( TSXCheckWindowEvent(display, X11DRV_WND_GetXWindow(pWnd), NoEventMask, &xe) ); + ((X11DRV_WND_DATA *) pWnd->pDriverData)->window = None; } return TRUE; @@ -192,12 +240,12 @@ WND *X11DRV_WND_SetParent(WND *wndPtr, WND *pWndParent) { BOOL32 bFixupDCE = IsWindowVisible32(wndPtr->hwndSelf); - if ( wndPtr->window ) + if ( X11DRV_WND_GetXWindow(wndPtr) ) { /* Toplevel window needs to be reparented. Used by Tk 8.0 */ - TSXDestroyWindow( display, wndPtr->window ); - wndPtr->window = None; + TSXDestroyWindow( display, X11DRV_WND_GetXWindow(wndPtr) ); + ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None; } else if( bFixupDCE ) DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow ); @@ -233,7 +281,7 @@ void X11DRV_WND_ForceWindowRaise(WND *pWnd) XWindowChanges winChanges; WND *wndPrev; - if( !pWnd || !pWnd->window || (pWnd->flags & WIN_MANAGED) ) + if( !pWnd || !X11DRV_WND_GetXWindow(pWnd) || (pWnd->flags & WIN_MANAGED) ) return; /* Raise all windows up to pWnd according to their Z order. @@ -243,8 +291,9 @@ void X11DRV_WND_ForceWindowRaise(WND *pWnd) winChanges.stack_mode = Above; while (pWnd) { - if (pWnd->window) TSXReconfigureWMWindow( display, pWnd->window, 0, - CWStackMode, &winChanges ); + if (X11DRV_WND_GetXWindow(pWnd)) + TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(pWnd), 0, + CWStackMode, &winChanges ); wndPrev = WIN_GetDesktop()->child; if (wndPrev == pWnd) break; while (wndPrev && (wndPrev->next != pWnd)) wndPrev = wndPrev->next; @@ -261,12 +310,12 @@ void X11DRV_WND_ForceWindowRaise(WND *pWnd) static Window X11DRV_WND_FindDesktopXWindow( WND *wndPtr ) { if (!(wndPtr->flags & WIN_MANAGED)) - return wndPtr->window; + return X11DRV_WND_GetXWindow(wndPtr); else { Window window, root, parent, *children; int nchildren; - window = wndPtr->window; + window = X11DRV_WND_GetXWindow(wndPtr); for (;;) { TSXQueryTree( display, window, &root, &parent, @@ -292,7 +341,8 @@ void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS32 *winpos, BOOL32 bSMC if (!(winpos->flags & SWP_SHOWWINDOW) && (winpos->flags & SWP_HIDEWINDOW)) { - if(wndPtr && wndPtr->window) TSXUnmapWindow( display, wndPtr->window ); + if(X11DRV_WND_GetXWindow(wndPtr)) + TSXUnmapWindow( display, X11DRV_WND_GetXWindow(wndPtr) ); } if(bSMC_SETXPOS) @@ -314,11 +364,11 @@ void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS32 *winpos, BOOL32 bSMC { long supplied_return; - TSXGetWMSizeHints( display, winposPtr->window, size_hints, + TSXGetWMSizeHints( display, X11DRV_WND_GetXWindow(winposPtr), size_hints, &supplied_return, XA_WM_NORMAL_HINTS); size_hints->min_width = size_hints->max_width = winpos->cx; size_hints->min_height = size_hints->max_height = winpos->cy; - TSXSetWMSizeHints( display, winposPtr->window, size_hints, + TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(winposPtr), size_hints, XA_WM_NORMAL_HINTS ); TSXFree(size_hints); } @@ -352,13 +402,13 @@ void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS32 *winpos, BOOL32 bSMC } if (changeMask) { - TSXReconfigureWMWindow( display, winposPtr->window, 0, changeMask, &winChanges ); + TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(winposPtr), 0, changeMask, &winChanges ); } } if ( winpos->flags & SWP_SHOWWINDOW ) { - if(wndPtr && wndPtr->window) TSXMapWindow( display, wndPtr->window ); + if(X11DRV_WND_GetXWindow(wndPtr)) TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) ); } } @@ -367,11 +417,11 @@ void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS32 *winpos, BOOL32 bSMC */ void X11DRV_WND_SetText(WND *wndPtr, LPCSTR text) { - if (!wndPtr->window) + if (!X11DRV_WND_GetXWindow(wndPtr)) return; - TSXStoreName( display, wndPtr->window, text ); - TSXSetIconName( display, wndPtr->window, text ); + TSXStoreName( display, X11DRV_WND_GetXWindow(wndPtr), text ); + TSXSetIconName( display, X11DRV_WND_GetXWindow(wndPtr), text ); } /***************************************************************** @@ -398,13 +448,13 @@ void X11DRV_WND_SetFocus(WND *wndPtr) /* Set X focus and install colormap */ - if (!wndPtr->window) return; + if (!X11DRV_WND_GetXWindow(wndPtr)) return; - if (!TSXGetWindowAttributes( display, wndPtr->window, &win_attr ) || + if (!TSXGetWindowAttributes( display, X11DRV_WND_GetXWindow(wndPtr), &win_attr ) || (win_attr.map_state != IsViewable)) return; /* If window is not viewable, don't change anything */ - TSXSetInputFocus( display,wndPtr->window, RevertToParent, CurrentTime ); + TSXSetInputFocus( display, X11DRV_WND_GetXWindow(wndPtr), RevertToParent, CurrentTime ); if (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE) TSXInstallColormap( display, COLOR_GetColormap() ); @@ -429,4 +479,100 @@ void X11DRV_WND_PostSizeMove(WND *wndPtr) TSXUngrabServer( display ); } + +/***************************************************************** + * X11DRV_WND_ScrollWindow + */ +void X11DRV_WND_ScrollWindow( + WND *wndPtr, DC *dcPtr, INT32 dx, INT32 dy, + const RECT32 *clipRect, BOOL32 bUpdate) +{ + X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcPtr->physDev; + POINT32 dst, src; + + if( dx > 0 ) dst.x = (src.x = dcPtr->w.DCOrgX + clipRect->left) + dx; + else src.x = (dst.x = dcPtr->w.DCOrgX + clipRect->left) - dx; + + if( dy > 0 ) dst.y = (src.y = dcPtr->w.DCOrgY + clipRect->top) + dy; + else src.y = (dst.y = dcPtr->w.DCOrgY + clipRect->top) - dy; + + + if ((clipRect->right - clipRect->left > abs(dx)) && + (clipRect->bottom - clipRect->top > abs(dy))) + { + if (bUpdate) /* handles non-Wine windows hanging over the scrolled area */ + TSXSetGraphicsExposures( display, physDev->gc, True ); + TSXSetFunction( display, physDev->gc, GXcopy ); + TSXCopyArea( display, physDev->drawable, physDev->drawable, + physDev->gc, src.x, src.y, + clipRect->right - clipRect->left - abs(dx), + clipRect->bottom - clipRect->top - abs(dy), + dst.x, dst.y ); + if (bUpdate) + TSXSetGraphicsExposures( display, physDev->gc, False ); + } +} + +/*********************************************************************** + * X11DRV_WND_SetDrawable + * + * Set the drawable, origin and dimensions for the DC associated to + * a given window. + */ +void X11DRV_WND_SetDrawable(WND *wndPtr, DC *dc, WORD flags, BOOL32 bSetClipOrigin) +{ + X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev; + + if (!wndPtr) /* Get a DC for the whole screen */ + { + dc->w.DCOrgX = 0; + dc->w.DCOrgY = 0; + physDev->drawable = rootWindow; + TSXSetSubwindowMode( display, physDev->gc, IncludeInferiors ); + } + else + { + if (flags & DCX_WINDOW) + { + dc->w.DCOrgX = wndPtr->rectWindow.left; + dc->w.DCOrgY = wndPtr->rectWindow.top; + } + else + { + dc->w.DCOrgX = wndPtr->rectClient.left; + dc->w.DCOrgY = wndPtr->rectClient.top; + } + while (!X11DRV_WND_GetXWindow(wndPtr)) + { + wndPtr = wndPtr->parent; + dc->w.DCOrgX += wndPtr->rectClient.left; + dc->w.DCOrgY += wndPtr->rectClient.top; + } + dc->w.DCOrgX -= wndPtr->rectWindow.left; + dc->w.DCOrgY -= wndPtr->rectWindow.top; + physDev->drawable = X11DRV_WND_GetXWindow(wndPtr); + +#if 0 + /* This is needed when we reuse a cached DC because + * SetDCState() called by ReleaseDC() screws up DC + * origins for child windows. + */ + + if( bSetClipOrigin ) + TSXSetClipOrigin( display, physDev->gc, dc->w.DCOrgX, dc->w.DCOrgY ); +#endif + } +} + +/*********************************************************************** + * X11DRV_WND_IsSelfClipping + */ +BOOL32 X11DRV_WND_IsSelfClipping(WND *wndPtr) +{ + if( X11DRV_WND_GetXWindow(wndPtr) ) + return TRUE; /* X itself will do the clipping */ + + return FALSE; +} + #endif /* !defined(X_DISPLAY_MISSING) */