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.
This commit is contained in:
parent
073e3bc9e5
commit
4f1ac05dea
|
@ -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 */
|
||||
|
|
304
objects/region.c
304
objects/region.c
|
@ -4,6 +4,7 @@
|
|||
*
|
||||
* Copyright 1993, 1994, 1995 Alexandre Julliard
|
||||
* Modifications and additions: Copyright 1998 Huw Davies
|
||||
* 1999 Alex Korobka
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -99,6 +100,7 @@ static void REGION_SubtractRegion(WINEREGION *d, WINEREGION *s1, WINEREGION *s2)
|
|||
static void REGION_XorRegion(WINEREGION *d, WINEREGION *s1, WINEREGION *s2);
|
||||
static void REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn);
|
||||
|
||||
#define RGN_DEFAULT_RECTS 2
|
||||
|
||||
/***********************************************************************
|
||||
* REGION_DumpRegion
|
||||
|
@ -117,47 +119,50 @@ static void REGION_DumpRegion(WINEREGION *pReg)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* REGION_AllocWineRegion
|
||||
* Create a new empty WINEREGION.
|
||||
*/
|
||||
static WINEREGION *REGION_AllocWineRegion( void )
|
||||
static WINEREGION *REGION_AllocWineRegion( INT n )
|
||||
{
|
||||
WINEREGION *pReg;
|
||||
|
||||
if ((pReg = HeapAlloc(SystemHeap, 0, sizeof( WINEREGION ))))
|
||||
{
|
||||
if ((pReg->rects = HeapAlloc(SystemHeap, 0, sizeof( RECT ))))
|
||||
{
|
||||
pReg->size = 1;
|
||||
EMPTY_REGION(pReg);
|
||||
return pReg;
|
||||
}
|
||||
HeapFree(SystemHeap, 0, pReg);
|
||||
if ((pReg->rects = HeapAlloc(SystemHeap, 0, n * sizeof( RECT ))))
|
||||
{
|
||||
pReg->size = n;
|
||||
EMPTY_REGION(pReg);
|
||||
return pReg;
|
||||
}
|
||||
HeapFree(SystemHeap, 0, pReg);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* REGION_CreateRegion
|
||||
* Create a new empty region.
|
||||
*/
|
||||
static HRGN REGION_CreateRegion(void)
|
||||
static HRGN REGION_CreateRegion( INT n )
|
||||
{
|
||||
HRGN hrgn;
|
||||
RGNOBJ *obj;
|
||||
|
||||
|
||||
if(!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC )))
|
||||
return 0;
|
||||
return 0;
|
||||
obj = (RGNOBJ *) GDI_HEAP_LOCK( hrgn );
|
||||
if(!(obj->rgn = REGION_AllocWineRegion())) {
|
||||
GDI_FreeObject( hrgn );
|
||||
return 0;
|
||||
if(!(obj->rgn = REGION_AllocWineRegion(n))) {
|
||||
GDI_FreeObject( hrgn );
|
||||
return 0;
|
||||
}
|
||||
GDI_HEAP_UNLOCK( hrgn );
|
||||
return hrgn;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* REGION_DestroyWineRegion
|
||||
*/
|
||||
|
@ -194,14 +199,14 @@ INT WINAPI OffsetRgn( HRGN hrgn, INT x, INT y )
|
|||
{
|
||||
RGNOBJ * obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
|
||||
|
||||
if (obj)
|
||||
if (obj && (x || y))
|
||||
{
|
||||
INT ret;
|
||||
int nbox = obj->rgn->numRects;
|
||||
RECT *pbox = obj->rgn->rects;
|
||||
|
||||
TRACE(region, " %04x %d,%d\n", hrgn, x, y );
|
||||
if(nbox && (x || y)) {
|
||||
if(nbox) {
|
||||
while(nbox--) {
|
||||
pbox->left += x;
|
||||
pbox->right += x;
|
||||
|
@ -264,7 +269,7 @@ HRGN16 WINAPI CreateRectRgn16(INT16 left, INT16 top, INT16 right, INT16 bottom)
|
|||
{
|
||||
HRGN16 hrgn;
|
||||
|
||||
if (!(hrgn = (HRGN16)REGION_CreateRegion()))
|
||||
if (!(hrgn = (HRGN16)REGION_CreateRegion(RGN_DEFAULT_RECTS)))
|
||||
return 0;
|
||||
TRACE(region, "\n");
|
||||
SetRectRgn16(hrgn, left, top, right, bottom);
|
||||
|
@ -279,7 +284,9 @@ HRGN WINAPI CreateRectRgn(INT left, INT top, INT right, INT bottom)
|
|||
{
|
||||
HRGN hrgn;
|
||||
|
||||
if (!(hrgn = REGION_CreateRegion()))
|
||||
/* Allocate 2 rects by default to reduce the number of reallocs */
|
||||
|
||||
if (!(hrgn = REGION_CreateRegion(RGN_DEFAULT_RECTS)))
|
||||
return 0;
|
||||
TRACE(region, "\n");
|
||||
SetRectRgn(hrgn, left, top, right, bottom);
|
||||
|
@ -399,7 +406,8 @@ HRGN WINAPI CreateRoundRectRgn( INT left, INT top,
|
|||
|
||||
/* Create region */
|
||||
|
||||
if (!(hrgn = REGION_CreateRegion())) return 0;
|
||||
d = (ellipse_height < 128) ? ((3 * ellipse_height) >> 2) : 64;
|
||||
if (!(hrgn = REGION_CreateRegion(d))) return 0;
|
||||
obj = (RGNOBJ *) GDI_HEAP_LOCK( hrgn );
|
||||
TRACE(region,"(%d,%d-%d,%d %dx%d): ret=%04x\n",
|
||||
left, top, right, bottom, ellipse_width, ellipse_height, hrgn );
|
||||
|
@ -574,34 +582,38 @@ DWORD WINAPI GetRegionData16(HRGN16 hrgn, DWORD count, LPRGNDATA rgndata)
|
|||
*/
|
||||
HRGN WINAPI ExtCreateRegion( const XFORM* lpXform, DWORD dwCount, const RGNDATA* rgndata)
|
||||
{
|
||||
HRGN hrgn = CreateRectRgn(0, 0, 0, 0);
|
||||
RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
|
||||
RECT *pCurRect, *pEndRect;
|
||||
HRGN hrgn;
|
||||
|
||||
TRACE(region, " %p %ld %p. Returning %04x\n",
|
||||
lpXform, dwCount, rgndata, hrgn);
|
||||
if(!hrgn)
|
||||
{
|
||||
WARN(region, "Can't create a region!\n");
|
||||
return 0;
|
||||
}
|
||||
if(lpXform)
|
||||
WARN(region, "Xform not implemented - ignoring\n");
|
||||
TRACE(region, " %p %ld %p = ", lpXform, dwCount, rgndata );
|
||||
|
||||
if( lpXform )
|
||||
WARN(region, "(Xform not implemented - ignored) ");
|
||||
|
||||
if(rgndata->rdh.iType != RDH_RECTANGLES)
|
||||
if( rgndata->rdh.iType != RDH_RECTANGLES )
|
||||
{
|
||||
WARN(region, "Type not RDH_RECTANGLES\n");
|
||||
GDI_HEAP_UNLOCK( hrgn );
|
||||
DeleteObject( hrgn );
|
||||
return 0;
|
||||
/* FIXME: We can use CreatePolyPolygonRgn() here
|
||||
* for trapezoidal data */
|
||||
|
||||
WARN(region, "(Unsupported region data) ");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
|
||||
for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
|
||||
REGION_UnionRectWithRegion( pCurRect, obj->rgn );
|
||||
if( (hrgn = REGION_CreateRegion( rgndata->rdh.nCount )) )
|
||||
{
|
||||
RECT *pCurRect, *pEndRect;
|
||||
RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
|
||||
|
||||
GDI_HEAP_UNLOCK( hrgn );
|
||||
return hrgn;
|
||||
pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
|
||||
for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
|
||||
REGION_UnionRectWithRegion( pCurRect, obj->rgn );
|
||||
GDI_HEAP_UNLOCK( hrgn );
|
||||
|
||||
TRACE(region,"%04x\n", hrgn );
|
||||
return hrgn;
|
||||
}
|
||||
fail:
|
||||
WARN(region, "Failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1402,7 +1414,7 @@ static void REGION_RegionOp(
|
|||
* Only do this stuff if the number of rectangles allocated is more than
|
||||
* twice the number of rectangles in the region (a simple optimization...).
|
||||
*/
|
||||
if (newReg->numRects < (newReg->size >> 1))
|
||||
if ((newReg->numRects < (newReg->size >> 1)) && (newReg->numRects > 2))
|
||||
{
|
||||
if (REGION_NOT_EMPTY(newReg))
|
||||
{
|
||||
|
@ -1916,8 +1928,8 @@ static void REGION_XorRegion(WINEREGION *dr, WINEREGION *sra,
|
|||
{
|
||||
WINEREGION *tra, *trb;
|
||||
|
||||
if ((! (tra = REGION_AllocWineRegion())) ||
|
||||
(! (trb = REGION_AllocWineRegion())))
|
||||
if ((! (tra = REGION_AllocWineRegion(sra->numRects + 1))) ||
|
||||
(! (trb = REGION_AllocWineRegion(srb->numRects + 1))))
|
||||
return;
|
||||
REGION_SubtractRegion(tra,sra,srb);
|
||||
REGION_SubtractRegion(trb,srb,sra);
|
||||
|
@ -2357,7 +2369,7 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
|
|||
int numFullPtBlocks = 0;
|
||||
INT poly, total;
|
||||
|
||||
if(!(hrgn = REGION_CreateRegion()))
|
||||
if(!(hrgn = REGION_CreateRegion(nbpolygons)))
|
||||
return 0;
|
||||
obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
|
||||
region = obj->rgn;
|
||||
|
@ -2568,3 +2580,205 @@ HRGN WINAPI GetRandomRgn(DWORD dwArg1, DWORD dwArg2, DWORD dwArg3)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* REGION_CropAndOffsetRegion
|
||||
*/
|
||||
static BOOL REGION_CropAndOffsetRegion(const POINT* off, const RECT *rect, WINEREGION *rgnSrc, WINEREGION* rgnDst)
|
||||
{
|
||||
if( IsRectEmpty(rect) || !EXTENTCHECK(rect, &rgnSrc->extents) )
|
||||
{
|
||||
empty:
|
||||
if( !rgnDst->rects )
|
||||
{
|
||||
rgnDst->rects = HeapAlloc(SystemHeap, 0, sizeof( RECT ));
|
||||
if( rgnDst->rects )
|
||||
rgnDst->size = 1;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE(region,"cropped to empty!\n");
|
||||
EMPTY_REGION(rgnDst);
|
||||
}
|
||||
else /* region box and clipping rect appear to intersect */
|
||||
{
|
||||
RECT *lpr;
|
||||
INT i, j, clipa, clipb;
|
||||
INT left = rgnSrc->extents.right + off->x;
|
||||
INT right = rgnSrc->extents.left + off->x;
|
||||
|
||||
for( clipa = 0; rgnSrc->rects[clipa].bottom <= rect->top; clipa++ )
|
||||
; /* skip bands above the clipping rectangle */
|
||||
|
||||
for( clipb = clipa; clipb < rgnSrc->numRects; clipb++ )
|
||||
if( rgnSrc->rects[clipb].top >= rect->bottom )
|
||||
break; /* and below it */
|
||||
|
||||
/* clipa - index of the first rect in the first intersecting band
|
||||
* clipb - index of the last rect in the last intersecting band
|
||||
*/
|
||||
|
||||
if((rgnDst != rgnSrc) && (rgnDst->size < (i = (clipb - clipa))))
|
||||
{
|
||||
rgnDst->rects = HeapReAlloc( SystemHeap, 0,
|
||||
rgnDst->rects, i * sizeof(RECT));
|
||||
if( !rgnDst->rects ) return FALSE;
|
||||
rgnDst->size = i;
|
||||
}
|
||||
|
||||
if( TRACE_ON(region) )
|
||||
{
|
||||
REGION_DumpRegion( rgnSrc );
|
||||
TRACE(region,"\tclipa = %i, clipb = %i\n", clipa, clipb );
|
||||
}
|
||||
|
||||
for( i = clipa, j = 0; i < clipb ; i++ )
|
||||
{
|
||||
/* i - src index, j - dst index, j is always <= i for obvious reasons */
|
||||
|
||||
lpr = rgnSrc->rects + i;
|
||||
if( lpr->left < rect->right && lpr->right > rect->left )
|
||||
{
|
||||
rgnDst->rects[j].top = lpr->top + off->y;
|
||||
rgnDst->rects[j].bottom = lpr->bottom + off->y;
|
||||
rgnDst->rects[j].left = ((lpr->left > rect->left) ? lpr->left : rect->left) + off->x;
|
||||
rgnDst->rects[j].right = ((lpr->right < rect->right) ? lpr->right : rect->right) + off->x;
|
||||
|
||||
if( rgnDst->rects[j].left < left ) left = rgnDst->rects[j].left;
|
||||
if( rgnDst->rects[j].right > right ) right = rgnDst->rects[j].right;
|
||||
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if( j == 0 ) goto empty;
|
||||
|
||||
rgnDst->extents.left = left;
|
||||
rgnDst->extents.right = right;
|
||||
|
||||
left = rect->top + off->y;
|
||||
right = rect->bottom + off->y;
|
||||
|
||||
rgnDst->numRects = j--;
|
||||
for( i = 0; i <= j; i++ ) /* fixup top band */
|
||||
if( rgnDst->rects[i].top < left )
|
||||
rgnDst->rects[i].top = left;
|
||||
else
|
||||
break;
|
||||
|
||||
for( i = j; i >= 0; i-- ) /* fixup bottom band */
|
||||
if( rgnDst->rects[i].bottom > right )
|
||||
rgnDst->rects[i].bottom = right;
|
||||
else
|
||||
break;
|
||||
|
||||
rgnDst->extents.top = rgnDst->rects[0].top;
|
||||
rgnDst->extents.bottom = rgnDst->rects[j].bottom;
|
||||
|
||||
rgnDst->type = (j >= 1) ? COMPLEXREGION : SIMPLEREGION;
|
||||
|
||||
if( TRACE_ON(region) )
|
||||
{
|
||||
TRACE(region,"result:\n");
|
||||
REGION_DumpRegion( rgnDst );
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* REGION_CropRgn
|
||||
*
|
||||
*
|
||||
* hSrc: Region to crop and offset.
|
||||
* lpRect: Clipping rectangle.
|
||||
* lpPt: Points to offset the cropped region. Can be NULL.
|
||||
*
|
||||
* hDst: Region to hold the result (if 0 a new region is created).
|
||||
* Allowed to be the same region as hSrc (in place, no extra memory needed).
|
||||
*
|
||||
* Returns: hDst if success, 0 otherwise.
|
||||
*/
|
||||
HRGN REGION_CropRgn( HRGN hDst, HRGN hSrc, const RECT *lpRect, const POINT *lpPt )
|
||||
{
|
||||
/* Optimization of the following generic code:
|
||||
|
||||
HRGN h = CreateRectRgn( lpRect->left, lpRect->top, lpRect->right, lpRect->bottom );
|
||||
if( hDst == 0 ) hDst = h;
|
||||
CombineRgn( hDst, hSrc, h, RGN_AND );
|
||||
if( lpPt )
|
||||
OffsetRgn( hDst, lpPt->x, lpPt->y );
|
||||
if( hDst != h )
|
||||
DeleteObject( h );
|
||||
return hDst;
|
||||
|
||||
*/
|
||||
|
||||
RGNOBJ *objSrc = (RGNOBJ *) GDI_HEAP_LOCK( hSrc );
|
||||
|
||||
if(objSrc)
|
||||
{
|
||||
RGNOBJ *objDst;
|
||||
WINEREGION *rgnDst;
|
||||
|
||||
if( hDst )
|
||||
{
|
||||
objDst = (RGNOBJ *) GDI_HEAP_LOCK( hDst );
|
||||
rgnDst = objDst->rgn;
|
||||
}
|
||||
else
|
||||
{
|
||||
rgnDst = HeapAlloc(SystemHeap, 0, sizeof( WINEREGION ));
|
||||
if( rgnDst )
|
||||
{
|
||||
rgnDst->size = rgnDst->numRects = 0;
|
||||
rgnDst->rects = NULL; /* back end will allocate exact number */
|
||||
}
|
||||
}
|
||||
|
||||
if( rgnDst )
|
||||
{
|
||||
POINT pt = { 0, 0 };
|
||||
|
||||
if( !lpPt ) lpPt = &pt;
|
||||
|
||||
TRACE(region, "src %p -> dst %p (%i,%i)-(%i,%i) by (%li,%li)\n", objSrc->rgn, rgnDst,
|
||||
lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, lpPt->x, lpPt->y );
|
||||
|
||||
if( REGION_CropAndOffsetRegion( lpPt, lpRect, objSrc->rgn, rgnDst ) == FALSE )
|
||||
{
|
||||
if( hDst ) /* existing rgn */
|
||||
{
|
||||
GDI_HEAP_UNLOCK(hDst);
|
||||
hDst = 0;
|
||||
goto done;
|
||||
}
|
||||
goto fail;
|
||||
}
|
||||
else if( hDst == 0 )
|
||||
{
|
||||
if(!(hDst = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC )))
|
||||
{
|
||||
fail:
|
||||
if( rgnDst->rects )
|
||||
HeapFree( SystemHeap, 0, rgnDst->rects );
|
||||
HeapFree( SystemHeap, 0, rgnDst );
|
||||
goto done;
|
||||
}
|
||||
|
||||
objDst = (RGNOBJ *) GDI_HEAP_LOCK( hDst );
|
||||
objDst->rgn = rgnDst;
|
||||
}
|
||||
|
||||
GDI_HEAP_UNLOCK(hDst);
|
||||
}
|
||||
else hDst = 0;
|
||||
done:
|
||||
GDI_HEAP_UNLOCK(hSrc);
|
||||
return hDst;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
* Window painting functions
|
||||
*
|
||||
* Copyright 1993, 1994, 1995 Alexandre Julliard
|
||||
* 1999 Alex Korobka
|
||||
*
|
||||
* FIXME: Do not repaint full nonclient area all the time. Instead, compute
|
||||
* intersection with hrgnUpdate (which should be moved from client to
|
||||
* window coords as well, lookup 'the pain' comment in the winpos.c).
|
||||
*/
|
||||
|
||||
#include "region.h"
|
||||
#include "win.h"
|
||||
#include "queue.h"
|
||||
#include "dce.h"
|
||||
|
@ -15,74 +14,98 @@
|
|||
#include "debug.h"
|
||||
#include "wine/winuser16.h"
|
||||
|
||||
/* client rect in window coordinates */
|
||||
|
||||
#define GETCLIENTRECTW( wnd, r ) (r).left = (wnd)->rectClient.left - (wnd)->rectWindow.left; \
|
||||
(r).top = (wnd)->rectClient.top - (wnd)->rectWindow.top; \
|
||||
(r).right = (wnd)->rectClient.right - (wnd)->rectWindow.left; \
|
||||
(r).bottom = (wnd)->rectClient.bottom - (wnd)->rectWindow.top
|
||||
|
||||
/* Last CTLCOLOR id */
|
||||
#define CTLCOLOR_MAX CTLCOLOR_STATIC
|
||||
|
||||
/***********************************************************************
|
||||
* WIN_UpdateNCArea
|
||||
*
|
||||
*/
|
||||
void WIN_UpdateNCArea(WND* wnd, BOOL bUpdate)
|
||||
{
|
||||
POINT16 pt = {0, 0};
|
||||
HRGN hClip = 1;
|
||||
|
||||
TRACE(nonclient,"hwnd %04x, hrgnUpdate %04x\n",
|
||||
wnd->hwndSelf, wnd->hrgnUpdate );
|
||||
/***********************************************************************
|
||||
* WIN_UpdateNCRgn
|
||||
*
|
||||
* NOTE: Caller is responsible for the returned region.
|
||||
*/
|
||||
HRGN WIN_UpdateNCRgn(WND* wnd, BOOL bUpdate, BOOL bForceEntire )
|
||||
{
|
||||
HRGN hClip = 0;
|
||||
|
||||
TRACE(nonclient,"hwnd %04x, hrgnUpdate %04x, ncf %i\n",
|
||||
wnd->hwndSelf, wnd->hrgnUpdate, (wnd->flags & WIN_NEEDS_NCPAINT)!=0 );
|
||||
|
||||
/* desktop window doesn't have nonclient area */
|
||||
if(wnd == WIN_GetDesktop())
|
||||
{
|
||||
wnd->flags &= ~WIN_NEEDS_NCPAINT;
|
||||
WIN_ReleaseDesktop();
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
WIN_ReleaseDesktop();
|
||||
|
||||
if( wnd->hrgnUpdate > 1 )
|
||||
if ((wnd->hwndSelf == GetActiveWindow()) &&
|
||||
!(wnd->flags & WIN_NCACTIVATED) )
|
||||
{
|
||||
ClientToScreen16(wnd->hwndSelf, &pt);
|
||||
|
||||
hClip = CreateRectRgn( 0, 0, 0, 0 );
|
||||
if (!CombineRgn( hClip, wnd->hrgnUpdate, 0, RGN_COPY ))
|
||||
{
|
||||
DeleteObject(hClip);
|
||||
hClip = 1;
|
||||
}
|
||||
else
|
||||
OffsetRgn( hClip, pt.x, pt.y );
|
||||
|
||||
if (bUpdate)
|
||||
{
|
||||
/* exclude non-client area from update region */
|
||||
HRGN hrgn = CreateRectRgn( 0, 0,
|
||||
wnd->rectClient.right - wnd->rectClient.left,
|
||||
wnd->rectClient.bottom - wnd->rectClient.top);
|
||||
|
||||
if (hrgn && (CombineRgn( wnd->hrgnUpdate, wnd->hrgnUpdate,
|
||||
hrgn, RGN_AND) == NULLREGION))
|
||||
{
|
||||
DeleteObject( wnd->hrgnUpdate );
|
||||
wnd->hrgnUpdate = 1;
|
||||
}
|
||||
|
||||
DeleteObject( hrgn );
|
||||
}
|
||||
wnd->flags |= WIN_NCACTIVATED;
|
||||
bForceEntire = TRUE;
|
||||
}
|
||||
|
||||
if( (wnd->flags & WIN_NEEDS_NCPAINT) && wnd->hrgnUpdate )
|
||||
{
|
||||
RECT r, r2, r3;
|
||||
|
||||
GETCLIENTRECTW( wnd, r );
|
||||
|
||||
TRACE(nonclient, "\tclient box (%i,%i-%i,%i)\n", r.left, r.top, r.right, r.bottom );
|
||||
|
||||
if( wnd->hrgnUpdate > 1 )
|
||||
{
|
||||
GetRgnBox( wnd->hrgnUpdate, &r2 );
|
||||
UnionRect( &r3, &r2, &r );
|
||||
if( r3.left != r.left || r3.top != r.top ||
|
||||
r3.right != r.right || r3.bottom != r.bottom )
|
||||
{
|
||||
hClip = CreateRectRgn( 0, 0, 0, 0 );
|
||||
CombineRgn( hClip, wnd->hrgnUpdate, 0, RGN_COPY );
|
||||
}
|
||||
}
|
||||
else
|
||||
hClip = wnd->hrgnUpdate;
|
||||
|
||||
if( wnd->hrgnUpdate > 1 )
|
||||
{
|
||||
REGION_CropRgn( wnd->hrgnUpdate, wnd->hrgnUpdate, &r, NULL );
|
||||
|
||||
if( bUpdate )
|
||||
{
|
||||
GetRgnBox( wnd->hrgnUpdate, &r3 );
|
||||
if( IsRectEmpty( &r3 ) )
|
||||
{
|
||||
/* delete update region since all invalid
|
||||
* parts were in the nonclient area */
|
||||
|
||||
DeleteObject( wnd->hrgnUpdate );
|
||||
wnd->hrgnUpdate = 0;
|
||||
if(!(wnd->flags & WIN_INTERNAL_PAINT))
|
||||
QUEUE_DecPaintCount( wnd->hmemTaskQ );
|
||||
wnd->flags &= ~WIN_NEEDS_ERASEBKGND;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* entire client rect */
|
||||
wnd->hrgnUpdate = CreateRectRgnIndirect( &r );
|
||||
}
|
||||
|
||||
if(!hClip && bForceEntire ) hClip = 1;
|
||||
wnd->flags &= ~WIN_NEEDS_NCPAINT;
|
||||
|
||||
if ((wnd->hwndSelf == GetActiveWindow()) &&
|
||||
!(wnd->flags & WIN_NCACTIVATED))
|
||||
{
|
||||
wnd->flags |= WIN_NCACTIVATED;
|
||||
if( hClip > 1) DeleteObject( hClip );
|
||||
hClip = 1;
|
||||
}
|
||||
if( hClip )
|
||||
SendMessageA( wnd->hwndSelf, WM_NCPAINT, hClip, 0L );
|
||||
|
||||
if (hClip) SendMessage16( wnd->hwndSelf, WM_NCPAINT, hClip, 0L );
|
||||
|
||||
if (hClip > 1) DeleteObject( hClip );
|
||||
return hClip;
|
||||
}
|
||||
|
||||
|
||||
|
@ -100,10 +123,10 @@ HDC16 WINAPI BeginPaint16( HWND16 hwnd, LPPAINTSTRUCT16 lps )
|
|||
|
||||
wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
|
||||
|
||||
if (wndPtr->flags & WIN_NEEDS_NCPAINT) WIN_UpdateNCArea( wndPtr, TRUE );
|
||||
if( (hrgnUpdate = WIN_UpdateNCRgn( wndPtr, FALSE, FALSE )) > 1 )
|
||||
DeleteObject( hrgnUpdate );
|
||||
|
||||
if (((hrgnUpdate = wndPtr->hrgnUpdate) != 0) ||
|
||||
(wndPtr->flags & WIN_INTERNAL_PAINT))
|
||||
if( ((hrgnUpdate = wndPtr->hrgnUpdate) != 0) || (wndPtr->flags & WIN_INTERNAL_PAINT))
|
||||
QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
|
||||
|
||||
wndPtr->hrgnUpdate = 0;
|
||||
|
@ -113,20 +136,19 @@ HDC16 WINAPI BeginPaint16( HWND16 hwnd, LPPAINTSTRUCT16 lps )
|
|||
|
||||
TRACE(win,"hrgnUpdate = %04x, \n", hrgnUpdate);
|
||||
|
||||
/* When bIcon is TRUE hrgnUpdate is automatically in window coordinates
|
||||
* (because rectClient == rectWindow for WS_MINIMIZE windows).
|
||||
*/
|
||||
|
||||
if (wndPtr->class->style & CS_PARENTDC)
|
||||
{
|
||||
/* Don't clip the output to the update region for CS_PARENTDC window */
|
||||
if(hrgnUpdate > 1)
|
||||
if( hrgnUpdate > 1 )
|
||||
DeleteObject(hrgnUpdate);
|
||||
lps->hdc = GetDCEx16( hwnd, 0, DCX_WINDOWPAINT | DCX_USESTYLE |
|
||||
(bIcon ? DCX_WINDOW : 0) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( hrgnUpdate )
|
||||
OffsetRgn( hrgnUpdate, wndPtr->rectWindow.left - wndPtr->rectClient.left,
|
||||
wndPtr->rectWindow.top - wndPtr->rectClient.top );
|
||||
lps->hdc = GetDCEx16(hwnd, hrgnUpdate, DCX_INTERSECTRGN |
|
||||
DCX_WINDOWPAINT | DCX_USESTYLE |
|
||||
(bIcon ? DCX_WINDOW : 0) );
|
||||
|
@ -143,7 +165,7 @@ HDC16 WINAPI BeginPaint16( HWND16 hwnd, LPPAINTSTRUCT16 lps )
|
|||
|
||||
GetClipBox16( lps->hdc, &lps->rcPaint );
|
||||
|
||||
TRACE(win,"box = (%i,%i - %i,%i)\n", lps->rcPaint.left, lps->rcPaint.top,
|
||||
TRACE(win,"box = (%i,%i - %i,%i)\n", lps->rcPaint.left, lps->rcPaint.top,
|
||||
lps->rcPaint.right, lps->rcPaint.bottom );
|
||||
|
||||
if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
|
||||
|
@ -285,14 +307,14 @@ END:
|
|||
* LOWORD(lParam) = hrgnClip
|
||||
* HIWORD(lParam) = hwndSkip (not used; always NULL)
|
||||
*
|
||||
* All in all, a prime candidate for a rewrite.
|
||||
*/
|
||||
BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate,
|
||||
HRGN hrgnUpdate, UINT flags, UINT control )
|
||||
HRGN hrgnUpdate, UINT flags, UINT ex )
|
||||
{
|
||||
BOOL bIcon;
|
||||
HRGN hrgn;
|
||||
RECT rectClient;
|
||||
HRGN hrgn = 0, hrgn2 = 0;
|
||||
RECT r, r2;
|
||||
POINT pt;
|
||||
WND* wndPtr;
|
||||
WND **list, **ppWnd;
|
||||
|
||||
|
@ -307,110 +329,165 @@ BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate,
|
|||
bIcon = (wndPtr->dwStyle & WS_MINIMIZE && wndPtr->class->hIcon);
|
||||
if (rectUpdate)
|
||||
{
|
||||
TRACE(win, "%04x %d,%d-%d,%d %04x flags=%04x\n",
|
||||
hwnd, rectUpdate->left, rectUpdate->top,
|
||||
rectUpdate->right, rectUpdate->bottom, hrgnUpdate, flags );
|
||||
TRACE(win, "%04x (%04x) %d,%d-%d,%d %04x flags=%04x, exflags=%04x\n",
|
||||
hwnd, wndPtr->hrgnUpdate, rectUpdate->left, rectUpdate->top,
|
||||
rectUpdate->right, rectUpdate->bottom, hrgnUpdate, flags, ex );
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE(win, "%04x NULL %04x flags=%04x\n", hwnd, hrgnUpdate, flags);
|
||||
if( hrgnUpdate ) GetRgnBox( hrgnUpdate, &r );
|
||||
else SetRectEmpty( &r );
|
||||
TRACE(win, "%04x (%04x) NULL %04x box (%i,%i-%i,%i) flags=%04x, exflags=%04x\n",
|
||||
hwnd, wndPtr->hrgnUpdate, hrgnUpdate, r.left, r.top, r.right, r.bottom, flags, ex);
|
||||
}
|
||||
|
||||
GetClientRect( hwnd, &rectClient );
|
||||
if( flags & RDW_FRAME )
|
||||
r = wndPtr->rectWindow;
|
||||
else
|
||||
r = wndPtr->rectClient;
|
||||
if( ex & RDW_EX_XYWINDOW )
|
||||
OffsetRect( &r, -wndPtr->rectWindow.left, -wndPtr->rectWindow.top );
|
||||
else
|
||||
OffsetRect( &r, -wndPtr->rectClient.left, -wndPtr->rectClient.top );
|
||||
|
||||
if (flags & RDW_INVALIDATE) /* Invalidate */
|
||||
/* r is the rectangle we crop the supplied update rgn/rect with */
|
||||
|
||||
GETCLIENTRECTW( wndPtr, r2 );
|
||||
pt.x = r2.left; pt.y = r2.top;
|
||||
|
||||
if (flags & RDW_INVALIDATE) /* ------------------------- Invalidate */
|
||||
{
|
||||
int rgnNotEmpty = COMPLEXREGION;
|
||||
BOOL bHasUpdateRgn = (BOOL)wndPtr->hrgnUpdate;
|
||||
|
||||
if (wndPtr->hrgnUpdate > 1) /* Is there already an update region? */
|
||||
{
|
||||
if ((hrgn = hrgnUpdate) == 0)
|
||||
hrgn = CreateRectRgnIndirect( rectUpdate ? rectUpdate :
|
||||
&rectClient );
|
||||
rgnNotEmpty = CombineRgn( wndPtr->hrgnUpdate, wndPtr->hrgnUpdate,
|
||||
hrgn, RGN_OR );
|
||||
if (!hrgnUpdate) DeleteObject( hrgn );
|
||||
}
|
||||
else /* No update region yet */
|
||||
{
|
||||
if (!(wndPtr->flags & WIN_INTERNAL_PAINT))
|
||||
QUEUE_IncPaintCount( wndPtr->hmemTaskQ );
|
||||
if (hrgnUpdate)
|
||||
{
|
||||
wndPtr->hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );
|
||||
rgnNotEmpty = CombineRgn( wndPtr->hrgnUpdate, hrgnUpdate,
|
||||
0, RGN_COPY );
|
||||
}
|
||||
else wndPtr->hrgnUpdate = CreateRectRgnIndirect( rectUpdate ?
|
||||
rectUpdate : &rectClient );
|
||||
}
|
||||
|
||||
if (flags & RDW_FRAME) wndPtr->flags |= WIN_NEEDS_NCPAINT;
|
||||
/* wndPtr->hrgnUpdate is in window coordinates, parameters are
|
||||
* in client coordinates unless RDW_EX_XYWINDOW is set.
|
||||
*/
|
||||
|
||||
/* restrict update region to client area (FIXME: correct?) */
|
||||
if (wndPtr->hrgnUpdate)
|
||||
{
|
||||
HRGN clientRgn = CreateRectRgnIndirect( &rectClient );
|
||||
rgnNotEmpty = CombineRgn( wndPtr->hrgnUpdate, clientRgn,
|
||||
wndPtr->hrgnUpdate, RGN_AND );
|
||||
DeleteObject( clientRgn );
|
||||
}
|
||||
if( hrgnUpdate )
|
||||
{
|
||||
hrgn = REGION_CropRgn( 0, hrgnUpdate, &r, (ex & RDW_EX_XYWINDOW) ? NULL : &pt );
|
||||
GetRgnBox( hrgn, &r2 );
|
||||
if( IsRectEmpty( &r2 ) )
|
||||
goto END;
|
||||
|
||||
/* check for bogus update region */
|
||||
if ( rgnNotEmpty == NULLREGION )
|
||||
{
|
||||
wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
|
||||
DeleteObject( wndPtr->hrgnUpdate );
|
||||
wndPtr->hrgnUpdate=0;
|
||||
if (!(wndPtr->flags & WIN_INTERNAL_PAINT))
|
||||
QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
|
||||
}
|
||||
else
|
||||
if (flags & RDW_ERASE) wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
|
||||
if( wndPtr->hrgnUpdate == 0 )
|
||||
{
|
||||
wndPtr->hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );
|
||||
CombineRgn( wndPtr->hrgnUpdate, hrgn, 0, RGN_COPY );
|
||||
}
|
||||
else
|
||||
if( wndPtr->hrgnUpdate > 1 )
|
||||
CombineRgn( wndPtr->hrgnUpdate, wndPtr->hrgnUpdate, hrgn, RGN_OR );
|
||||
}
|
||||
else if( rectUpdate )
|
||||
{
|
||||
if( !IntersectRect( &r2, &r, rectUpdate ) )
|
||||
goto END;
|
||||
if( !(ex & RDW_EX_XYWINDOW) )
|
||||
OffsetRect( &r2, pt.x, pt.y );
|
||||
|
||||
rect2i: /* r2 contains a rect to add to the update region */
|
||||
|
||||
hrgn = CreateRectRgnIndirect( &r2 );
|
||||
if( wndPtr->hrgnUpdate == 0 )
|
||||
wndPtr->hrgnUpdate = CreateRectRgnIndirect( &r2 );
|
||||
else
|
||||
if( wndPtr->hrgnUpdate > 1 )
|
||||
REGION_UnionRectWithRgn( wndPtr->hrgnUpdate, &r2 );
|
||||
}
|
||||
else /* entire window or client depending on RDW_FRAME */
|
||||
{
|
||||
hrgn = 1;
|
||||
if( flags & RDW_FRAME )
|
||||
{
|
||||
if( wndPtr->hrgnUpdate )
|
||||
DeleteObject( wndPtr->hrgnUpdate );
|
||||
wndPtr->hrgnUpdate = 1;
|
||||
}
|
||||
else /* by default r2 contains client rect in window coordinates */
|
||||
goto rect2i;
|
||||
}
|
||||
|
||||
if( !bHasUpdateRgn && wndPtr->hrgnUpdate && !(wndPtr->flags & WIN_INTERNAL_PAINT))
|
||||
QUEUE_IncPaintCount( wndPtr->hmemTaskQ );
|
||||
|
||||
if (flags & RDW_FRAME) wndPtr->flags |= WIN_NEEDS_NCPAINT;
|
||||
if (flags & RDW_ERASE) wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
|
||||
flags |= RDW_FRAME; /* Force children frame invalidation */
|
||||
}
|
||||
else if (flags & RDW_VALIDATE) /* Validate */
|
||||
else if (flags & RDW_VALIDATE) /* ------------------------- Validate */
|
||||
{
|
||||
/* We need an update region in order to validate anything */
|
||||
if (wndPtr->hrgnUpdate > 1)
|
||||
if (wndPtr->hrgnUpdate) /* need an update region in order to validate anything */
|
||||
{
|
||||
if (!hrgnUpdate && !rectUpdate)
|
||||
if( hrgnUpdate || rectUpdate )
|
||||
{
|
||||
if( hrgnUpdate )
|
||||
{
|
||||
hrgn = REGION_CropRgn( hrgn, hrgnUpdate, &r, (ex & RDW_EX_XYWINDOW) ? NULL : &pt );
|
||||
GetRgnBox( hrgn, &r2 );
|
||||
if( IsRectEmpty( &r2 ) )
|
||||
goto END;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !IntersectRect( &r2, &r, rectUpdate ) )
|
||||
goto END;
|
||||
if( !(ex & RDW_EX_XYWINDOW) )
|
||||
OffsetRect( &r2, pt.x, pt.y );
|
||||
rect2v:
|
||||
hrgn = CreateRectRgnIndirect( &r2 );
|
||||
}
|
||||
|
||||
if( wndPtr->hrgnUpdate == 1 )
|
||||
{
|
||||
wndPtr->hrgnUpdate = CreateRectRgn( 0, 0,
|
||||
wndPtr->rectWindow.right - wndPtr->rectWindow.left,
|
||||
wndPtr->rectWindow.bottom - wndPtr->rectWindow.top );
|
||||
}
|
||||
|
||||
if( CombineRgn( wndPtr->hrgnUpdate,
|
||||
wndPtr->hrgnUpdate, hrgn, RGN_DIFF ) == NULLREGION )
|
||||
{
|
||||
DeleteObject( wndPtr->hrgnUpdate );
|
||||
wndPtr->hrgnUpdate = 0;
|
||||
}
|
||||
}
|
||||
else /* entire window or client depending on RDW_FRAME */
|
||||
{
|
||||
/* Special case: validate everything */
|
||||
DeleteObject( wndPtr->hrgnUpdate );
|
||||
wndPtr->hrgnUpdate = 0;
|
||||
wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
|
||||
|
||||
hrgn = 1;
|
||||
if( flags & RDW_FRAME )
|
||||
{
|
||||
if( wndPtr->hrgnUpdate != 1 )
|
||||
DeleteObject( wndPtr->hrgnUpdate );
|
||||
wndPtr->hrgnUpdate = 0;
|
||||
}
|
||||
else /* by default r2 contains client rect in window coordinates */
|
||||
goto rect2v;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((hrgn = hrgnUpdate) == 0)
|
||||
hrgn = CreateRectRgnIndirect( rectUpdate );
|
||||
if (CombineRgn( wndPtr->hrgnUpdate, wndPtr->hrgnUpdate,
|
||||
hrgn, RGN_DIFF ) == NULLREGION)
|
||||
{
|
||||
DeleteObject( wndPtr->hrgnUpdate );
|
||||
wndPtr->hrgnUpdate = 0;
|
||||
}
|
||||
if (!hrgnUpdate) DeleteObject( hrgn );
|
||||
}
|
||||
if (!wndPtr->hrgnUpdate) /* No more update region */
|
||||
if (!(wndPtr->flags & WIN_INTERNAL_PAINT))
|
||||
|
||||
if (!wndPtr->hrgnUpdate && /* No more update region */
|
||||
!(wndPtr->flags & WIN_INTERNAL_PAINT) )
|
||||
QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
|
||||
}
|
||||
if (flags & RDW_NOFRAME) wndPtr->flags &= ~WIN_NEEDS_NCPAINT;
|
||||
if (flags & RDW_NOERASE) wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
|
||||
}
|
||||
|
||||
/* Set/clear internal paint flag */
|
||||
/* At this point hrgn contains new update region in window coordinates */
|
||||
|
||||
/* Set/clear internal paint flag */
|
||||
|
||||
if (flags & RDW_INTERNALPAINT)
|
||||
{
|
||||
if ( wndPtr->hrgnUpdate <= 1 && !(wndPtr->flags & WIN_INTERNAL_PAINT))
|
||||
if ( !wndPtr->hrgnUpdate && !(wndPtr->flags & WIN_INTERNAL_PAINT))
|
||||
QUEUE_IncPaintCount( wndPtr->hmemTaskQ );
|
||||
wndPtr->flags |= WIN_INTERNAL_PAINT;
|
||||
}
|
||||
else if (flags & RDW_NOINTERNALPAINT)
|
||||
{
|
||||
if ( wndPtr->hrgnUpdate <= 1 && (wndPtr->flags & WIN_INTERNAL_PAINT))
|
||||
if ( !wndPtr->hrgnUpdate && (wndPtr->flags & WIN_INTERNAL_PAINT))
|
||||
QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
|
||||
wndPtr->flags &= ~WIN_INTERNAL_PAINT;
|
||||
}
|
||||
|
@ -422,17 +499,29 @@ BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate,
|
|||
if (wndPtr->hrgnUpdate) /* wm_painticon wparam is 1 */
|
||||
SendMessage16( hwnd, (bIcon) ? WM_PAINTICON : WM_PAINT, bIcon, 0 );
|
||||
}
|
||||
else if (flags & RDW_ERASENOW)
|
||||
else if ((flags & RDW_ERASENOW) || (ex & RDW_EX_TOPFRAME))
|
||||
{
|
||||
if (wndPtr->flags & WIN_NEEDS_NCPAINT)
|
||||
WIN_UpdateNCArea( wndPtr, FALSE);
|
||||
hrgn2 = WIN_UpdateNCRgn( wndPtr, TRUE, (ex & RDW_EX_TOPFRAME) );
|
||||
|
||||
if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
|
||||
if( wndPtr->flags & WIN_NEEDS_ERASEBKGND )
|
||||
{
|
||||
HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
|
||||
DCX_INTERSECTRGN | DCX_USESTYLE |
|
||||
DCX_KEEPCLIPRGN | DCX_WINDOWPAINT |
|
||||
(bIcon ? DCX_WINDOW : 0) );
|
||||
HDC hdc;
|
||||
|
||||
if( hrgn2 > 1 )
|
||||
{
|
||||
OffsetRgn( hrgn2, -pt.x, -pt.y );
|
||||
GetRgnBox( hrgn2, &r2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
hrgn2 = CreateRectRgn( 0, 0, 0, 0 );
|
||||
CombineRgn( hrgn2, wndPtr->hrgnUpdate, 0, RGN_COPY );
|
||||
OffsetRgn( hrgn2, -pt.x, -pt.y );
|
||||
}
|
||||
hdc = GetDCEx( hwnd, hrgn2,
|
||||
DCX_INTERSECTRGN | DCX_USESTYLE |
|
||||
DCX_KEEPCLIPRGN | DCX_WINDOWPAINT |
|
||||
(bIcon ? DCX_WINDOW : 0) );
|
||||
if (hdc)
|
||||
{
|
||||
if (SendMessage16( hwnd, (bIcon) ? WM_ICONERASEBKGND
|
||||
|
@ -456,47 +545,40 @@ BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate,
|
|||
((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) &&
|
||||
!(wndPtr->dwStyle & WS_MINIMIZE) )
|
||||
{
|
||||
if ( hrgnUpdate || rectUpdate )
|
||||
if( hrgnUpdate || rectUpdate )
|
||||
{
|
||||
if (!(hrgn = CreateRectRgn( 0, 0, 0, 0 )))
|
||||
{
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
return TRUE;
|
||||
}
|
||||
if( !hrgnUpdate )
|
||||
{
|
||||
control |= (RDW_C_DELETEHRGN | RDW_C_USEHRGN);
|
||||
if( !(hrgnUpdate = CreateRectRgnIndirect( rectUpdate )) )
|
||||
{
|
||||
DeleteObject( hrgn );
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
if( hrgn2 <= 1 )
|
||||
hrgn2 = (ex & RDW_EX_USEHRGN) ? hrgnUpdate : 0;
|
||||
|
||||
if( (list = WIN_BuildWinArray( wndPtr, 0, NULL )) )
|
||||
{
|
||||
POINT delta = pt;
|
||||
|
||||
for (ppWnd = list; *ppWnd; ppWnd++)
|
||||
{
|
||||
WIN_UpdateWndPtr(&wndPtr,*ppWnd);
|
||||
if (!IsWindow(wndPtr->hwndSelf)) continue;
|
||||
if (wndPtr->dwStyle & WS_VISIBLE)
|
||||
{
|
||||
SetRectRgn( hrgn,
|
||||
wndPtr->rectWindow.left, wndPtr->rectWindow.top,
|
||||
wndPtr->rectWindow.right, wndPtr->rectWindow.bottom );
|
||||
if (CombineRgn( hrgn, hrgn, hrgnUpdate, RGN_AND ))
|
||||
r.left = wndPtr->rectWindow.left + delta.x;
|
||||
r.top = wndPtr->rectWindow.top + delta.y;
|
||||
r.right = wndPtr->rectWindow.right + delta.x;
|
||||
r.bottom = wndPtr->rectWindow.bottom + delta.y;
|
||||
|
||||
pt.x = -r.left; pt.y = -r.top;
|
||||
|
||||
hrgn2 = REGION_CropRgn( hrgn2, hrgn, &r, &pt );
|
||||
|
||||
GetRgnBox( hrgn2, &r2 );
|
||||
if( !IsRectEmpty( &r2 ) )
|
||||
{
|
||||
OffsetRgn( hrgn, -wndPtr->rectClient.left,
|
||||
-wndPtr->rectClient.top );
|
||||
PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, hrgn, flags,
|
||||
RDW_C_USEHRGN );
|
||||
PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, hrgn2, flags,
|
||||
RDW_EX_USEHRGN | RDW_EX_XYWINDOW );
|
||||
}
|
||||
}
|
||||
}
|
||||
WIN_ReleaseWinArray(list);
|
||||
}
|
||||
DeleteObject( hrgn );
|
||||
if (control & RDW_C_DELETEHRGN) DeleteObject( hrgnUpdate );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -513,6 +595,12 @@ BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate,
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
END:
|
||||
if( hrgn2 > 1 && (hrgn2 != hrgnUpdate) )
|
||||
DeleteObject( hrgn2 );
|
||||
if( hrgn > 1 && (hrgn != hrgnUpdate) )
|
||||
DeleteObject( hrgn );
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -680,9 +768,16 @@ BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
|
|||
}
|
||||
}
|
||||
}
|
||||
else SetRectEmpty( rect );
|
||||
else
|
||||
if( wndPtr->hrgnUpdate == 1 )
|
||||
{
|
||||
GetClientRect( hwnd, rect );
|
||||
if (erase) RedrawWindow( hwnd, NULL, 0, RDW_FRAME | RDW_ERASENOW | RDW_NOCHILDREN );
|
||||
}
|
||||
else
|
||||
SetRectEmpty( rect );
|
||||
}
|
||||
retvalue = (wndPtr->hrgnUpdate > 1);
|
||||
retvalue = (wndPtr->hrgnUpdate >= 1);
|
||||
END:
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
return retvalue;
|
||||
|
@ -699,7 +794,7 @@ INT16 WINAPI GetUpdateRgn16( HWND16 hwnd, HRGN16 hrgn, BOOL16 erase )
|
|||
|
||||
|
||||
/***********************************************************************
|
||||
* GetUpdateRgn32 (USER32.298)
|
||||
* GetUpdateRgn (USER32.298)
|
||||
*/
|
||||
INT WINAPI GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
|
||||
{
|
||||
|
@ -707,13 +802,25 @@ INT WINAPI GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
|
|||
WND * wndPtr = WIN_FindWndPtr( hwnd );
|
||||
if (!wndPtr) return ERROR;
|
||||
|
||||
if (wndPtr->hrgnUpdate <= 1)
|
||||
if (wndPtr->hrgnUpdate == 0)
|
||||
{
|
||||
SetRectRgn( hrgn, 0, 0, 0, 0 );
|
||||
retval = NULLREGION;
|
||||
goto END;
|
||||
}
|
||||
retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY );
|
||||
else
|
||||
if (wndPtr->hrgnUpdate == 1)
|
||||
{
|
||||
SetRectRgn( hrgn, 0, 0, wndPtr->rectClient.right - wndPtr->rectClient.left,
|
||||
wndPtr->rectClient.bottom - wndPtr->rectClient.top );
|
||||
retval = SIMPLEREGION;
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY );
|
||||
OffsetRgn( hrgn, wndPtr->rectWindow.left - wndPtr->rectClient.left,
|
||||
wndPtr->rectWindow.top - wndPtr->rectClient.top );
|
||||
}
|
||||
if (erase) RedrawWindow( hwnd, NULL, 0, RDW_ERASENOW | RDW_NOCHILDREN );
|
||||
END:
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
|
@ -745,10 +852,14 @@ INT WINAPI ExcludeUpdateRgn( HDC hdc, HWND hwnd )
|
|||
INT ret;
|
||||
HRGN hrgn = CreateRectRgn(wndPtr->rectWindow.left - wndPtr->rectClient.left,
|
||||
wndPtr->rectWindow.top - wndPtr->rectClient.top,
|
||||
wndPtr->rectClient.right - wndPtr->rectClient.left,
|
||||
wndPtr->rectClient.bottom - wndPtr->rectClient.top);
|
||||
wndPtr->rectWindow.right - wndPtr->rectClient.left,
|
||||
wndPtr->rectWindow.bottom - wndPtr->rectClient.top);
|
||||
if( wndPtr->hrgnUpdate > 1 )
|
||||
{
|
||||
CombineRgn(hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY);
|
||||
OffsetRgn(hrgn, wndPtr->rectWindow.left - wndPtr->rectClient.left,
|
||||
wndPtr->rectWindow.top - wndPtr->rectClient.top );
|
||||
}
|
||||
|
||||
/* do ugly coordinate translations in dce.c */
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -116,6 +116,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
|
||||
*/
|
||||
|
|
|
@ -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 */
|
||||
|
|
1008
windows/winpos.c
1008
windows/winpos.c
File diff suppressed because it is too large
Load Diff
|
@ -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) /* 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();
|
||||
if (bUpdate) /* Make sure exposure events have been processed */
|
||||
EVENT_Synchronize();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -633,6 +664,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
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue