Commit 4f1ac05d authored by Alex Korobka's avatar Alex Korobka Committed by Alexandre Julliard

Moved hrgnUpdate from client to window coordinates, made nonclient

painting depend on the update region, reworked SetWindowPos() and RedrawWindow() to speed up update region calculation, made -desktop work properly, added WM_CANCELMODE here and there, fixed several window activation bugs that crept in since the last time.
parent 073e3bc9
......@@ -3791,6 +3791,10 @@ BOOL WINAPI DrawMenuBar( HWND hWnd )
*/
void WINAPI EndMenu(void)
{
/*
* FIXME: NOT ENOUGH! This has to cancel menu tracking right away.
*/
fEndMenu = TRUE;
}
......
......@@ -378,6 +378,7 @@ typedef struct _ScanLineListBlock {
extern BOOL REGION_DeleteObject( HRGN hrgn, RGNOBJ * obj );
extern BOOL REGION_UnionRectWithRgn( HRGN hrgn, const RECT *lpRect );
extern HRGN REGION_CropRgn( HRGN hDst, HRGN hSrc, const RECT *lpRect, const POINT *lpPt );
extern BOOL REGION_FrameRgn( HRGN dest, HRGN src, INT x, INT y );
extern BOOL REGION_LPTODP( HDC hdc, HRGN hDest, HRGN hSrc );
......
......@@ -16,6 +16,7 @@
#include "windef.h"
#ifdef HAVE_LIBXXF86VM
#define XMD_H
#define INT32 INT
#include <X11/Xlib.h>
#include <X11/extensions/xf86vmode.h>
......
......@@ -38,6 +38,7 @@ extern Region TSXPolygonRegion(XPoint*, int, int);
extern int TSXRectInRegion(Region, int, int, unsigned int, unsigned int);
extern int TSXSaveContext(Display*, XID, XContext, const char*);
extern int TSXSetClassHint(Display*, Window, XClassHint*);
extern int TSXSetWMHints(Display*, Window, XWMHints*);
extern void TSXSetWMProperties(Display*, Window, XTextProperty*, XTextProperty*, char**, int, XSizeHints*, XWMHints*, XClassHint*);
extern void TSXSetWMSizeHints(Display*, Window, XSizeHints*, Atom);
extern int TSXSetRegion(Display*, GC, Region);
......
......@@ -121,6 +121,7 @@ extern void TTYDRV_WND_PreSizeMove(struct tagWND *wndPtr);
extern void TTYDRV_WND_PostSizeMove(struct tagWND *wndPtr);
extern void TTYDRV_WND_ScrollWindow(struct tagWND *wndPtr, struct tagDC *dcPtr, INT dx, INT dy, const RECT *clipRect, BOOL bUpdate);
extern void TTYDRV_WND_SetDrawable(struct tagWND *wndPtr, struct tagDC *dc, WORD flags, BOOL bSetClipOrigin);
extern BOOL TTYDRV_WND_SetHostAttr(struct tagWND *wndPtr, INT haKey, INT value);
extern BOOL TTYDRV_WND_IsSelfClipping(struct tagWND *wndPtr);
#endif /* !defined(__WINE_TTYDRV_H) */
......@@ -44,8 +44,10 @@ typedef enum
} BUILTIN_CLASS32;
/* PAINT_RedrawWindow() control flags */
#define RDW_C_USEHRGN 0x0001
#define RDW_C_DELETEHRGN 0x0002
#define RDW_EX_USEHRGN 0x0001
#define RDW_EX_DELETEHRGN 0x0002
#define RDW_EX_XYWINDOW 0x0004
#define RDW_EX_TOPFRAME 0x0010
struct tagCLASS;
struct tagDCE;
......@@ -86,6 +88,25 @@ typedef struct tagWND
DWORD wExtra[1]; /* Window extra bytes */
} WND;
/* Host attributes */
#define HAK_BITGRAVITY 1
#define HAK_ACCEPTFOCUS 2
/* Bit Gravity */
#define BGForget 0
#define BGNorthWest 1
#define BGNorth 2
#define BGNorthEast 3
#define BGWest 4
#define BGCenter 5
#define BGEast 6
#define BGSouthWest 7
#define BGSouth 8
#define BGSouthEast 9
#define BGStatic 10
typedef struct _WND_DRIVER
{
void (*pInitialize)(WND *);
......@@ -100,8 +121,9 @@ typedef struct _WND_DRIVER
void (*pSetFocus)(WND *);
void (*pPreSizeMove)(WND *);
void (*pPostSizeMove)(WND *);
void (*pScrollWindow)(WND *, struct tagDC *, INT, INT, const RECT *, BOOL);
void (*pSurfaceCopy)(WND *, struct tagDC *, INT, INT, const RECT *, BOOL);
void (*pSetDrawable)(WND *, struct tagDC *, WORD, BOOL);
BOOL (*pSetHostAttr)(WND *, INT haKey, INT value);
BOOL (*pIsSelfClipping)(WND *);
} WND_DRIVER;
......@@ -119,13 +141,12 @@ typedef struct
#define WIN_NEEDS_NCPAINT 0x0004 /* WM_NCPAINT must be sent to window */
#define WIN_RESTORE_MAX 0x0008 /* Maximize when restoring */
#define WIN_INTERNAL_PAINT 0x0010 /* Internal WM_PAINT message pending */
/* Used to have WIN_NO_REDRAW 0x0020 here */
#define WIN_NATIVE 0x0020 /* Directly mapped to the window provided by the driver */
#define WIN_NEED_SIZE 0x0040 /* Internal WM_SIZE is needed */
#define WIN_NCACTIVATED 0x0080 /* last WM_NCACTIVATE was positive */
#define WIN_MANAGED 0x0100 /* Window managed by the X wm */
#define WIN_MANAGED 0x0100 /* Window managed by the window system */
#define WIN_ISDIALOG 0x0200 /* Window is a dialog */
#define WIN_ISWIN32 0x0400 /* Understands Win32 messages */
#define WIN_SAVEUNDER_OVERRIDE 0x0800
/* BuildWinArray() flags */
#define BWA_SKIPDISABLED 0x0001
......@@ -170,7 +191,7 @@ extern void PROPERTY_RemoveWindowProps( WND *pWnd ); /* windows/propert
extern BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate,
HRGN hrgnUpdate, UINT flags,
UINT control ); /* windows/painting.c */
extern void WIN_UpdateNCArea(WND* wnd, BOOL bUpdate);
extern HRGN WIN_UpdateNCRgn(WND* wnd, BOOL bUpdate, BOOL bForce); /* windows/painting.c */
/* controls/widgets.c */
......
......@@ -328,6 +328,7 @@ extern struct _WND_DRIVER X11DRV_WND_Driver;
typedef struct _X11DRV_WND_DATA {
Window window;
int bit_gravity;
} X11DRV_WND_DATA;
extern Window X11DRV_WND_GetXWindow(struct tagWND *wndPtr);
......@@ -347,8 +348,9 @@ extern void X11DRV_WND_SetText(struct tagWND *wndPtr, LPCSTR text);
extern void X11DRV_WND_SetFocus(struct tagWND *wndPtr);
extern void X11DRV_WND_PreSizeMove(struct tagWND *wndPtr);
extern void X11DRV_WND_PostSizeMove(struct tagWND *wndPtr);
extern void X11DRV_WND_ScrollWindow(struct tagWND *wndPtr, struct tagDC *dcPtr, INT dx, INT dy, const RECT *clipRect, BOOL bUpdate);
extern void X11DRV_WND_SurfaceCopy(struct tagWND *wndPtr, struct tagDC *dcPtr, INT dx, INT dy, const RECT *clipRect, BOOL bUpdate);
extern void X11DRV_WND_SetDrawable(struct tagWND *wndPtr, struct tagDC *dc, WORD flags, BOOL bSetClipOrigin);
extern BOOL X11DRV_WND_SetHostAttr(struct tagWND *wndPtr, INT haKey, INT value);
extern BOOL X11DRV_WND_IsSelfClipping(struct tagWND *wndPtr);
#endif /* __WINE_X11DRV_H */
......@@ -69,7 +69,7 @@ foreach $name (@dolist) {
if($name eq "xf86vmode") {
$x11_incl = "#include <X11/Xlib.h>\n";
$extensions_dir = "extensions/";
$pre_file = "#include \"wintypes.h\"\n#ifdef HAVE_LIBXXF86VM\n#define XMD_H\n";
$pre_file = "#include \"windef.h\"\n#ifdef HAVE_LIBXXF86VM\n#define XMD_H\n#define INT32 INT\n";
$post_file = "#endif /* defined(HAVE_LIBXXF86VM) */\n";
}
......
......@@ -131,6 +131,7 @@ XSetSelectionOwner
XSetSubwindowMode
XSetTransientForHint
XSetWindowColormap
XSetWMHints
XSetWMProperties
XSetWMProtocols
XSetWMSizeHints
......
......@@ -11,7 +11,8 @@
#include "windef.h"
#ifdef HAVE_LIBXXF86VM
#define XMD_H
typedef int INT32;
#define INT32 INT
#include <X11/Xlib.h>
#include <X11/extensions/xf86vmode.h>
#include "debug.h"
......
......@@ -235,6 +235,17 @@ int TSXSetClassHint(Display* a0, Window a1, XClassHint* a2)
return r;
}
int TSXSetWMHints(Display* a0, Window a1, XWMHints* a2)
{
int r;
TRACE(x11, "Call XSetWMHints\n");
EnterCriticalSection( &X11DRV_CritSection );
r = XSetWMHints(a0, a1, a2);
LeaveCriticalSection( &X11DRV_CritSection );
TRACE(x11, "Ret XSetWMHints\n");
return r;
}
void TSXSetWMProperties(Display* a0, Window a1, XTextProperty* a2, XTextProperty* a3, char** a4, int a5, XSizeHints* a6, XWMHints* a7, XClassHint* a8)
{
TRACE(x11, "Call XSetWMProperties\n");
......
......@@ -222,8 +222,9 @@ static INT DCE_ReleaseDC( DCE* dce )
* DCE_InvalidateDCE
*
* It is called from SetWindowPos() - we have to mark as dirty all busy
* DCE's for windows that have pWnd->parent as an ansector and whose client
* rect intersects with specified update rectangle.
* DCEs for windows that have pWnd->parent as an ansector and whose client
* rect intersects with specified update rectangle. In addition, pWnd->parent
* DCEs may need to be updated if DCX_CLIPCHILDREN flag is set.
*/
BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate)
{
......@@ -248,17 +249,25 @@ BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate)
{
WND* wndCurrent = WIN_FindWndPtr(dce->hwndCurrent);
if( wndCurrent && wndCurrent != WIN_GetDesktop() )
if( wndCurrent )
{
WND* wnd = NULL;
INT xoffset = 0, yoffset = 0;
if( (wndCurrent == wndScope) && !(dce->DCXflags & DCX_CLIPCHILDREN) )
{
/* child window positions don't bother us */
WIN_ReleaseWndPtr(wndCurrent);
continue;
}
if( !Options.desktopGeometry && wndCurrent == WIN_GetDesktop() )
{
/* don't bother with fake desktop */
WIN_ReleaseDesktop();
continue;
}
/* check if DCE window is within the z-order scope */
for( wnd = WIN_LockWndPtr(wndCurrent); wnd; WIN_UpdateWndPtr(&wnd,wnd->parent))
......@@ -305,7 +314,6 @@ BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate)
}
}
WIN_ReleaseWndPtr(wndCurrent);
WIN_ReleaseDesktop();
}
} /* dce list */
}
......
......@@ -11,6 +11,7 @@
#include "sysmetrics.h"
#include "user.h"
#include "heap.h"
#include "dce.h"
#include "cursoricon.h"
#include "dialog.h"
#include "menu.h"
......@@ -1563,7 +1564,8 @@ void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
TRACE(nonclient, "%04x %d\n", hwnd, active );
if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
wndPtr->rectClient.top-wndPtr->rectWindow.top,
......@@ -1665,7 +1667,7 @@ void NC_DoNCPaint95(
BOOL suppress_menupaint )
{
HDC hdc;
RECT rect;
RECT rfuzz, rect, rectClip;
BOOL active;
HWND hwnd = wndPtr->hwndSelf;
......@@ -1676,7 +1678,15 @@ void NC_DoNCPaint95(
TRACE(nonclient, "%04x %d\n", hwnd, active );
if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
/* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in the call to
* GetDCEx implying that it is allowed not to use it either. However, the suggested
* GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN) will cause clipRgn to be deleted
* after ReleaseDC(). Now, how is the "system" supposed to tell what happened?
*/
if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
wndPtr->rectClient.top-wndPtr->rectWindow.top,
......@@ -1692,6 +1702,14 @@ void NC_DoNCPaint95(
rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
if( clip > 1 )
GetRgnBox( clip, &rectClip );
else
{
clip = 0;
rectClip = rect;
}
SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
if(!(wndPtr->flags & WIN_MANAGED)) {
......@@ -1716,8 +1734,9 @@ void NC_DoNCPaint95(
r.bottom = rect.top + sysMetrics[SM_CYCAPTION];
rect.top += sysMetrics[SM_CYCAPTION];
}
NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
wndPtr->dwExStyle, active);
if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
wndPtr->dwExStyle, active);
}
}
......
......@@ -275,7 +275,7 @@ rc.left, rc.top, rc.right, rc.bottom, (UINT16)flags );
if( (dc = (DC *)GDI_GetObjPtr(hDC, DC_MAGIC)) )
{
if (dc->w.hVisRgn) {
wnd->pDriver->pScrollWindow(wnd,dc,dx,dy,&rc,bUpdate);
wnd->pDriver->pSurfaceCopy(wnd,dc,dx,dy,&rc,bUpdate);
if( bUpdate )
{
......
......@@ -81,6 +81,7 @@ WND_DRIVER TTYDRV_WND_Driver =
TTYDRV_WND_PostSizeMove,
TTYDRV_WND_ScrollWindow,
TTYDRV_WND_SetDrawable,
TTYDRV_WND_SetHostAttr,
TTYDRV_WND_IsSelfClipping
};
......
......@@ -117,6 +117,14 @@ void TTYDRV_WND_SetDrawable(WND *wndPtr, DC *dc, WORD flags, BOOL bSetClipOrigin
}
/***********************************************************************
* TTYDRV_WND_SetHostAttr
*/
BOOL TTYDRV_WND_SetHostAttr(WND *wndPtr, INT attr, INT value)
{
return FALSE;
}
/***********************************************************************
* TTYDRV_WND_IsSelfClipping
*/
BOOL TTYDRV_WND_IsSelfClipping(WND *wndPtr)
......
......@@ -1666,14 +1666,24 @@ BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable )
{
/* Enable window */
wndPtr->dwStyle &= ~WS_DISABLED;
if( wndPtr->flags & WIN_NATIVE )
wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ACCEPTFOCUS, TRUE );
SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
retvalue = TRUE;
goto end;
}
else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
{
SendMessageA( wndPtr->hwndSelf, WM_CANCELMODE, 0, 0);
/* Disable window */
wndPtr->dwStyle |= WS_DISABLED;
if( wndPtr->flags & WIN_NATIVE )
wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ACCEPTFOCUS, FALSE );
if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus() ))
{
SetFocus( 0 ); /* A disabled window can't have the focus */
......
......@@ -520,8 +520,7 @@ static void EVENT_ProcessEvent( XEvent *event )
/***********************************************************************
* EVENT_QueryZOrder
*
* Try to synchronize internal z-order with the window manager's.
* Probably a futile endeavor.
* Synchronize internal z-order with the window manager's.
*/
static BOOL __check_query_condition( WND** pWndA, WND** pWndB )
{
......@@ -540,19 +539,25 @@ static BOOL __check_query_condition( WND** pWndA, WND** pWndB )
static Window __get_common_ancestor( Window A, Window B,
Window** children, unsigned* total )
{
/* find the real root window */
/* find the real root window */
Window root, *childrenB;
unsigned totalB;
Window root, *childrenB;
unsigned totalB;
do
do
{
if( *children ) TSXFree( *children );
TSXQueryTree( display, A, &root, &A, children, total );
TSXQueryTree( display, B, &root, &B, &childrenB, &totalB );
if( childrenB ) TSXFree( childrenB );
if( *children ) TSXFree( *children );
} while( A != B && A && B );
return ( A && B ) ? A : 0 ;
if( A && B )
{
TSXQueryTree( display, A, &root, &B, children, total );
return A;
}
return 0 ;
}
static Window __get_top_decoration( Window w, Window ancestor )
......@@ -573,7 +578,7 @@ static Window __get_top_decoration( Window w, Window ancestor )
static unsigned __td_lookup( Window w, Window* list, unsigned max )
{
unsigned i;
for( i = 0; i < max; i++ ) if( list[i] == w ) break;
for( i = max - 1; i >= 0; i-- ) if( list[i] == w ) break;
return i;
}
......@@ -591,32 +596,42 @@ static BOOL EVENT_QueryZOrder( WND* pWndCheck )
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 );
if( w != children[total - 1] )
{
if( w != children[total-1] ) /* check if at the top */
{
/* X child at index 0 is at the bottom, at index total-1 is at the top */
check = __td_lookup( w, children, total );
best = total;
for( pWnd = pWndZ; pWnd; pWnd = pWnd->next )
{
{
/* go through all windows in Wine z-order... */
if( pWnd != pWndCheck )
{
{
if( !(pWnd->flags & WIN_MANAGED) ||
!(w = __get_top_decoration( X11DRV_WND_GetXWindow(pWnd), parent )) )
continue;
pos = __td_lookup( w, children, total );
if( pos < best && pos > check )
{
{
/* find a nearest Wine window precedes
* pWndCheck in the real z-order... */
best = pos;
hwndInsertAfter = pWnd->hwndSelf;
}
if( check - best == 1 ) break;
}
}
WIN_UnlinkWindow( pWndCheck->hwndSelf );
WIN_LinkWindow( pWndCheck->hwndSelf, hwndInsertAfter);
}
}
}
if( best - check == 1 ) break;
}
}
/* and link pWndCheck right behind it in the local z-order */
}
WIN_UnlinkWindow( pWndCheck->hwndSelf );
WIN_LinkWindow( pWndCheck->hwndSelf, hwndInsertAfter);
}
if( children ) TSXFree( children );
return bRet;
}
......@@ -867,14 +882,17 @@ static void EVENT_FocusIn( WND *pWnd, XFocusChangeEvent *event )
*/
static void EVENT_FocusOut( WND *pWnd, XFocusChangeEvent *event )
{
if (event->detail != NotifyPointer)
if (event->detail != NotifyPointer)
{
HWND hwnd = pWnd->hwndSelf;
if (hwnd == GetActiveWindow())
WINPOS_ChangeActiveWindow( 0, FALSE );
if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus()))
SetFocus( 0 );
HWND hwnd = pWnd->hwndSelf;
if (hwnd == GetActiveWindow())
{
SendMessageA( hwnd, WM_CANCELMODE, 0, 0 );
WINPOS_ChangeActiveWindow( 0, FALSE );
}
if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus()))
SetFocus( 0 );
}
}
......@@ -910,13 +928,13 @@ static void EVENT_GetGeometry( Window win, int *px, int *py,
if (!TSXGetGeometry( display, win, &root, px, py, pwidth, pheight,
&border, &depth )) return;
if (win == X11DRV_GetXRootWindow())
{
{
*px = *py = 0;
return;
}
}
for (;;)
{
{
if (!TSXQueryTree(display, win, &root, &parent, &children, &nb_children))
return;
TSXFree( children );
......@@ -926,7 +944,7 @@ static void EVENT_GetGeometry( Window win, int *px, int *py,
&width, &height, &border, &depth )) return;
*px += xpos;
*py += ypos;
}
}
}
......@@ -940,7 +958,7 @@ static void EVENT_ConfigureNotify( WND *pWnd, XConfigureEvent *event )
{
WINDOWPOS winpos;
RECT newWindowRect, newClientRect;
HRGN hrgnOldPos, hrgnNewPos;
RECT oldWindowRect, oldClientRect;
Window above = event->above;
int x, y;
unsigned int width, height;
......@@ -953,6 +971,9 @@ static void EVENT_ConfigureNotify( WND *pWnd, XConfigureEvent *event )
*/
EVENT_GetGeometry( event->window, &x, &y, &width, &height );
TRACE(win, "%04x adjusted to (%i,%i)-(%i,%i)\n", pWnd->hwndSelf,
x, y, x + width, y + height );
/* Fill WINDOWPOS struct */
winpos.flags = SWP_NOACTIVATE | SWP_NOZORDER;
winpos.hwnd = pWnd->hwndSelf;
......@@ -991,15 +1012,20 @@ static void EVENT_ConfigureNotify( WND *pWnd, XConfigureEvent *event )
if (!IsWindow( winpos.hwnd )) return;
hrgnOldPos = CreateRectRgnIndirect( &pWnd->rectWindow );
hrgnNewPos = CreateRectRgnIndirect( &newWindowRect );
CombineRgn( hrgnOldPos, hrgnOldPos, hrgnNewPos, RGN_DIFF );
DeleteObject(hrgnOldPos);
DeleteObject(hrgnNewPos);
oldWindowRect = pWnd->rectWindow;
oldClientRect = pWnd->rectClient;
/* Set new size and position */
pWnd->rectWindow = newWindowRect;
pWnd->rectClient = newClientRect;
/* FIXME: Copy valid bits */
if( oldClientRect.top - oldWindowRect.top != newClientRect.top - newWindowRect.top ||
oldClientRect.left - oldWindowRect.left != newClientRect.left - newWindowRect.left )
RedrawWindow( winpos.hwnd, 0, NULL, RDW_FRAME | RDW_ALLCHILDREN |
RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW );
SendMessageA( winpos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos );
if (!IsWindow( winpos.hwnd )) return;
......
......@@ -84,8 +84,9 @@ WND_DRIVER X11DRV_WND_Driver =
X11DRV_WND_SetFocus,
X11DRV_WND_PreSizeMove,
X11DRV_WND_PostSizeMove,
X11DRV_WND_ScrollWindow,
X11DRV_WND_SurfaceCopy,
X11DRV_WND_SetDrawable,
X11DRV_WND_SetHostAttr,
X11DRV_WND_IsSelfClipping
};
......
......@@ -170,7 +170,9 @@ BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO
if (!(cs->style & WS_CHILD) &&
(X11DRV_WND_GetXRootWindow(wndPtr) == DefaultRootWindow(display)))
{
{
Window wGroupLeader;
XWMHints* wm_hints;
XSetWindowAttributes win_attr;
if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) ||
......@@ -191,10 +193,15 @@ BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO
FocusChangeMask;
win_attr.override_redirect = TRUE;
}
wndPtr->flags |= WIN_NATIVE;
win_attr.bit_gravity = BGNorthWest;
win_attr.colormap = X11DRV_COLOR_GetColormap();
win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0);
win_attr.cursor = X11DRV_MOUSE_XCursor;
((X11DRV_WND_DATA *) wndPtr->pDriverData)->bit_gravity = BGNorthWest;
((X11DRV_WND_DATA *) wndPtr->pDriverData)->window =
TSXCreateWindow( display,
X11DRV_WND_GetXRootWindow(wndPtr),
......@@ -203,9 +210,10 @@ BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO
InputOutput, CopyFromParent,
CWEventMask | CWOverrideRedirect |
CWColormap | CWCursor | CWSaveUnder |
CWBackingStore, &win_attr );
CWBackingStore | CWBitGravity,
&win_attr );
if(!X11DRV_WND_GetXWindow(wndPtr))
if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr)))
return FALSE;
if (wndPtr->flags & WIN_MANAGED) {
......@@ -233,14 +241,36 @@ BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO
}
if (cs->hwndParent) /* Get window owner */
{
{
Window w;
WND *tmpWnd = WIN_FindWndPtr(cs->hwndParent);
Window win = X11DRV_WND_FindXWindow( tmpWnd );
if (win) TSXSetTransientForHint( display, X11DRV_WND_GetXWindow(wndPtr), win );
w = X11DRV_WND_FindXWindow( tmpWnd );
if (w != None)
{
TSXSetTransientForHint( display, X11DRV_WND_GetXWindow(wndPtr), w );
wGroupLeader = w;
}
WIN_ReleaseWndPtr(tmpWnd);
}
}
wm_hints = TSXAllocWMHints();
{
wm_hints->flags = InputHint | StateHint | WindowGroupHint;
wm_hints->input = True;
if( wndPtr->dwStyle & WS_VISIBLE )
wm_hints->initial_state = (wndPtr->dwStyle & WS_MINIMIZE &&
wndPtr->flags & WIN_MANAGED ) ?
IconicState : NormalState;
else
wm_hints->initial_state = WithdrawnState;
wm_hints->window_group = wGroupLeader;
TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
TSXFree(wm_hints);
}
X11DRV_WND_RegisterWindow( wndPtr );
}
}
return TRUE;
}
......@@ -400,26 +430,26 @@ static Window X11DRV_WND_FindDesktopXWindow( WND *wndPtr )
*
* SetWindowPos() for an X window. Used by the real SetWindowPos().
*/
void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bSMC_SETXPOS)
void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangePos)
{
XWindowChanges winChanges;
int changeMask = 0;
WND *winposPtr = WIN_FindWndPtr( winpos->hwnd );
XWindowChanges winChanges;
int changeMask = 0;
WND *winposPtr = WIN_FindWndPtr( winpos->hwnd );
if(!wndPtr->hwndSelf) wndPtr = NULL; /* FIXME: WND destroyed, shouldn't happend!!! */
if(!wndPtr->hwndSelf) wndPtr = NULL; /* FIXME: WND destroyed, shouldn't happend!!! */
if (!(winpos->flags & SWP_SHOWWINDOW) && (winpos->flags & SWP_HIDEWINDOW))
if (!(winpos->flags & SWP_SHOWWINDOW) && (winpos->flags & SWP_HIDEWINDOW))
{
if(X11DRV_WND_GetXWindow(wndPtr))
TSXUnmapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
}
if(bSMC_SETXPOS)
if(bChangePos)
{
if ( !(winpos->flags & SWP_NOSIZE))
{
winChanges.width = winpos->cx;
winChanges.height = winpos->cy;
winChanges.width = (winpos->cx > 0 ) ? winpos->cx : 1;
winChanges.height = (winpos->cy > 0 ) ? winpos->cy : 1;
changeMask |= CWWidth | CWHeight;
/* Tweak dialog window size hints */
......@@ -477,11 +507,11 @@ void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bSMC_SET
}
}
if ( winpos->flags & SWP_SHOWWINDOW )
if ( winpos->flags & SWP_SHOWWINDOW )
{
if(X11DRV_WND_GetXWindow(wndPtr)) TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
}
WIN_ReleaseWndPtr(winposPtr);
WIN_ReleaseWndPtr(winposPtr);
}
/*****************************************************************
......@@ -555,31 +585,32 @@ void X11DRV_WND_PostSizeMove(WND *wndPtr)
}
/*****************************************************************
* X11DRV_WND_ScrollWindow
* X11DRV_WND_SurfaceCopy
*
* Copies rect to (rect.left + dx, rect.top + dy).
*/
void X11DRV_WND_ScrollWindow(
WND *wndPtr, DC *dcPtr, INT dx, INT dy,
const RECT *rect, BOOL bUpdate)
void X11DRV_WND_SurfaceCopy(WND* wndPtr, DC *dcPtr, INT dx, INT dy,
const RECT *rect, BOOL bUpdate)
{
X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcPtr->physDev;
POINT dst, src;
X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcPtr->physDev;
POINT dst, src;
dst.x = (src.x = dcPtr->w.DCOrgX + rect->left) + dx;
dst.y = (src.y = dcPtr->w.DCOrgY + rect->top) + dy;
dst.x = (src.x = dcPtr->w.DCOrgX + rect->left) + dx;
dst.y = (src.y = dcPtr->w.DCOrgY + rect->top) + 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,
rect->right - rect->left,
rect->bottom - rect->top,
dst.x, dst.y );
if (bUpdate)
TSXSetGraphicsExposures( display, physDev->gc, False );
if (bUpdate) /* Make sure exposure events have been processed */
EVENT_Synchronize();
if (bUpdate) /* handles non-Wine windows hanging over the copied area */
TSXSetGraphicsExposures( display, physDev->gc, True );
TSXSetFunction( display, physDev->gc, GXcopy );
TSXCopyArea( display, physDev->drawable, physDev->drawable,
physDev->gc, src.x, src.y,
rect->right - rect->left,
rect->bottom - rect->top,
dst.x, dst.y );
if (bUpdate)
TSXSetGraphicsExposures( display, physDev->gc, False );
if (bUpdate) /* Make sure exposure events have been processed */
EVENT_Synchronize();
}
/***********************************************************************
......@@ -634,6 +665,50 @@ void X11DRV_WND_SetDrawable(WND *wndPtr, DC *dc, WORD flags, BOOL bSetClipOrigin
}
/***********************************************************************
* X11DRV_WND_SetHostAttr
*/
BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value)
{
Window w;
if( (w = X11DRV_WND_GetXWindow(wnd)) )
{
XSetWindowAttributes win_attr;
switch( ha )
{
case HAK_BITGRAVITY:
if( ((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity != value )
{
win_attr.bit_gravity = value;
((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity = value;
TSXChangeWindowAttributes( display, w, CWBitGravity, &win_attr );
}
return TRUE;
case HAK_ACCEPTFOCUS:
if( (wnd->flags & WIN_MANAGED) )
{
XWMHints* wm_hints = TSXAllocWMHints();
if( wm_hints )
{
wm_hints->flags = InputHint;
wm_hints->input = value;
TSXSetWMHints( display, X11DRV_WND_GetXWindow(wnd), wm_hints );
TSXFree( wm_hints );
return TRUE;
}
}
break;
}
}
return FALSE;
}
/***********************************************************************
* X11DRV_WND_IsSelfClipping
*/
BOOL X11DRV_WND_IsSelfClipping(WND *wndPtr)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment