Moved more things to the X11 driver.
diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c
index 39c1f47..7d98737 100644
--- a/windows/x11drv/clipboard.c
+++ b/windows/x11drv/clipboard.c
@@ -38,19 +38,21 @@
*/
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 @@
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 @@
* 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 @@
*
* 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 @@
/* 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 0a47590..fc4b0b7 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 @@
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 @@
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 @@
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 cdae2aa..734b8a5 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 @@
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 @@
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 ed87b98..6015636 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 cf5ae7b..2575e38 100644
--- a/windows/x11drv/wnd.c
+++ b/windows/x11drv/wnd.c
@@ -17,12 +17,14 @@
#include <stdlib.h>
#include <string.h>
#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 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 @@
*/
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 @@
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 @@
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 @@
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 @@
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 @@
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_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 @@
{
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 @@
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 @@
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 @@
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 @@
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 @@
{
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 @@
}
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_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 @@
/* 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 @@
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) */