Moved most of the implementation of SetWindowPos and SetDrawable into
the user driver, and the corresponding code into the dlls/x11drv directory. Moved a few functions out of the window driver into the user driver. Plus a few related cleanups.
This commit is contained in:
parent
56a45b2049
commit
9ae0fe54b0
|
@ -239,7 +239,7 @@ BOOL TTYDRV_DC_CreateDC(DC *dc, LPCSTR driver, LPCSTR device,
|
|||
|
||||
GDI_ReleaseObj( dc->hBitmap );
|
||||
} else {
|
||||
physDev->window = TTYDRV_GetRootWindow();
|
||||
physDev->window = root_window;
|
||||
physDev->cellWidth = cell_width;
|
||||
physDev->cellHeight = cell_height;
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ struct tagWND;
|
|||
struct tagCURSORICONINFO;
|
||||
struct tagCREATESTRUCTA;
|
||||
struct tagWINDOWPOS;
|
||||
struct tagKEYBOARD_CONFIG;
|
||||
struct DIDEVICEOBJECTDATA;
|
||||
|
||||
#if defined(HAVE_LIBCURSES) || defined(HAVE_LIBNCURSES)
|
||||
|
@ -127,36 +126,17 @@ extern int cell_height;
|
|||
extern int screen_rows;
|
||||
extern int screen_cols;
|
||||
extern WINDOW *root_window;
|
||||
static inline WINDOW *TTYDRV_GetRootWindow(void) { return root_window; }
|
||||
|
||||
/* TTY windows driver */
|
||||
|
||||
extern struct tagWND_DRIVER TTYDRV_WND_Driver;
|
||||
|
||||
typedef struct tagTTYDRV_WND_DATA {
|
||||
WINDOW *window;
|
||||
} TTYDRV_WND_DATA;
|
||||
|
||||
WINDOW *TTYDRV_WND_GetCursesWindow(struct tagWND *wndPtr);
|
||||
|
||||
extern HANDLE TTYDRV_LoadOEMResource(WORD resid, WORD type);
|
||||
|
||||
extern void TTYDRV_WND_Initialize(struct tagWND *wndPtr);
|
||||
extern void TTYDRV_WND_Finalize(struct tagWND *wndPtr);
|
||||
extern BOOL TTYDRV_WND_CreateDesktopWindow(struct tagWND *wndPtr);
|
||||
extern BOOL TTYDRV_WND_CreateWindow(struct tagWND *wndPtr, struct tagCREATESTRUCTA *cs, BOOL bUnicode);
|
||||
extern BOOL TTYDRV_WND_DestroyWindow(struct tagWND *pWnd);
|
||||
extern struct tagWND *TTYDRV_WND_SetParent(struct tagWND *wndPtr, struct tagWND *pWndParent);
|
||||
extern void TTYDRV_WND_ForceWindowRaise(struct tagWND *pWnd);
|
||||
extern void TTYDRV_WND_SetWindowPos(struct tagWND *wndPtr, const struct tagWINDOWPOS *winpos, BOOL bSMC_SETXPOS);
|
||||
extern void TTYDRV_WND_SetText(struct tagWND *wndPtr, LPCWSTR text);
|
||||
extern void TTYDRV_WND_SetFocus(struct tagWND *wndPtr);
|
||||
extern void TTYDRV_WND_PreSizeMove(struct tagWND *wndPtr);
|
||||
extern void TTYDRV_WND_PostSizeMove(struct tagWND *wndPtr);
|
||||
extern void TTYDRV_WND_ScrollWindow(struct tagWND *wndPtr, HDC hdc, INT dx, INT dy, const RECT *clipRect, BOOL bUpdate);
|
||||
extern void TTYDRV_WND_SetDrawable(struct tagWND *wndPtr, HDC hdc, WORD flags, BOOL bSetClipOrigin);
|
||||
extern BOOL TTYDRV_WND_SetHostAttr(struct tagWND *wndPtr, INT haKey, INT value);
|
||||
extern BOOL TTYDRV_WND_IsSelfClipping(struct tagWND *wndPtr);
|
||||
extern void TTYDRV_WND_SetWindowRgn(struct tagWND *wndPtr, HRGN hrgnWnd);
|
||||
|
||||
#endif /* !defined(__WINE_TTYDRV_H) */
|
||||
|
|
|
@ -11,8 +11,6 @@ debug_channels (ttydrv)
|
|||
|
||||
# USER driver
|
||||
|
||||
@ cdecl Synchronize() TTYDRV_Synchronize
|
||||
@ cdecl CheckFocus() TTYDRV_CheckFocus
|
||||
@ cdecl UserRepaintDisable(long) TTYDRV_UserRepaintDisable
|
||||
@ cdecl InitKeyboard() TTYDRV_InitKeyboard
|
||||
@ cdecl VkKeyScan(long) TTYDRV_VkKeyScan
|
||||
|
@ -24,8 +22,6 @@ debug_channels (ttydrv)
|
|||
@ cdecl Beep() TTYDRV_Beep
|
||||
@ cdecl GetDIState(long ptr) TTYDRV_GetDIState
|
||||
@ cdecl GetDIData(ptr long ptr ptr long) TTYDRV_GetDIData
|
||||
@ cdecl GetKeyboardConfig(ptr) TTYDRV_GetKeyboardConfig
|
||||
@ cdecl SetKeyboardConfig(ptr long) TTYDRV_SetKeyboardConfig
|
||||
@ cdecl InitMouse(ptr) TTYDRV_InitMouse
|
||||
@ cdecl SetCursor(ptr) TTYDRV_SetCursor
|
||||
@ cdecl MoveCursor(long long) TTYDRV_MoveCursor
|
||||
|
@ -34,6 +30,10 @@ debug_channels (ttydrv)
|
|||
@ cdecl GetScreenSaveTimeout() TTYDRV_GetScreenSaveTimeout
|
||||
@ cdecl SetScreenSaveTimeout(long) TTYDRV_SetScreenSaveTimeout
|
||||
@ cdecl LoadOEMResource(long long) TTYDRV_LoadOEMResource
|
||||
@ cdecl CreateWindow(long) TTYDRV_CreateWindow
|
||||
@ cdecl DestroyWindow(long) TTYDRV_DestroyWindow
|
||||
@ cdecl GetDC(long long long long) TTYDRV_GetDC
|
||||
@ cdecl SetWindowPos(ptr) TTYDRV_SetWindowPos
|
||||
@ cdecl IsSingleWindow() TTYDRV_IsSingleWindow
|
||||
@ cdecl AcquireClipboard() TTYDRV_AcquireClipboard
|
||||
@ cdecl ReleaseClipboard() TTYDRV_ReleaseClipboard
|
||||
|
|
|
@ -11,21 +11,6 @@
|
|||
|
||||
DEFAULT_DEBUG_CHANNEL(ttydrv);
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_Synchronize
|
||||
*/
|
||||
void TTYDRV_Synchronize( void )
|
||||
{
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_CheckFocus
|
||||
*/
|
||||
BOOL TTYDRV_CheckFocus(void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_UserRepaintDisable
|
||||
*/
|
||||
|
@ -117,20 +102,6 @@ BOOL TTYDRV_GetDIData( BYTE *keystate, DWORD dodsize, LPDIDEVICEOBJECTDATA dod,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_GetKeyboardConfig
|
||||
*/
|
||||
void TTYDRV_GetKeyboardConfig(KEYBOARD_CONFIG *cfg)
|
||||
{
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_SetKeyboardConfig
|
||||
*/
|
||||
extern void TTYDRV_SetKeyboardConfig(KEYBOARD_CONFIG *cfg, DWORD mask)
|
||||
{
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_InitMouse
|
||||
*/
|
||||
|
|
|
@ -8,156 +8,88 @@
|
|||
|
||||
#include "gdi.h"
|
||||
#include "ttydrv.h"
|
||||
#include "region.h"
|
||||
#include "win.h"
|
||||
#include "winpos.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(ttydrv);
|
||||
|
||||
WND_DRIVER TTYDRV_WND_Driver =
|
||||
{
|
||||
TTYDRV_WND_Initialize,
|
||||
TTYDRV_WND_Finalize,
|
||||
TTYDRV_WND_CreateDesktopWindow,
|
||||
TTYDRV_WND_CreateWindow,
|
||||
TTYDRV_WND_DestroyWindow,
|
||||
TTYDRV_WND_SetParent,
|
||||
TTYDRV_WND_ForceWindowRaise,
|
||||
TTYDRV_WND_SetWindowPos,
|
||||
TTYDRV_WND_SetText,
|
||||
TTYDRV_WND_SetFocus,
|
||||
TTYDRV_WND_PreSizeMove,
|
||||
TTYDRV_WND_PostSizeMove,
|
||||
TTYDRV_WND_ScrollWindow,
|
||||
TTYDRV_WND_SetDrawable,
|
||||
TTYDRV_WND_SetHostAttr,
|
||||
TTYDRV_WND_IsSelfClipping,
|
||||
TTYDRV_WND_SetWindowRgn
|
||||
TTYDRV_WND_SetHostAttr
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_WND_GetCursesWindow
|
||||
*
|
||||
* Return the Curses window associated to a window.
|
||||
*/
|
||||
WINDOW *TTYDRV_WND_GetCursesWindow(WND *wndPtr)
|
||||
{
|
||||
return wndPtr && wndPtr->pDriverData ?
|
||||
((TTYDRV_WND_DATA *) wndPtr->pDriverData)->window : 0;
|
||||
}
|
||||
#define SWP_AGG_NOGEOMETRYCHANGE \
|
||||
(SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
|
||||
#define SWP_AGG_NOPOSCHANGE \
|
||||
(SWP_AGG_NOGEOMETRYCHANGE | SWP_NOZORDER)
|
||||
#define SWP_AGG_STATUSFLAGS \
|
||||
(SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
|
||||
|
||||
/**********************************************************************
|
||||
* TTYDRV_WND_Initialize
|
||||
* CreateWindow (TTYDRV.@)
|
||||
*/
|
||||
void TTYDRV_WND_Initialize(WND *wndPtr)
|
||||
{
|
||||
TTYDRV_WND_DATA *pWndDriverData = HeapAlloc(GetProcessHeap(), 0, sizeof(TTYDRV_WND_DATA));
|
||||
|
||||
TRACE("(%p)\n", wndPtr);
|
||||
|
||||
wndPtr->pDriverData = (void *) pWndDriverData;
|
||||
|
||||
pWndDriverData->window = NULL;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* TTYDRV_WND_Finalize
|
||||
*/
|
||||
void TTYDRV_WND_Finalize(WND *wndPtr)
|
||||
{
|
||||
TTYDRV_WND_DATA *pWndDriverData =
|
||||
(TTYDRV_WND_DATA *) wndPtr->pDriverData;
|
||||
|
||||
TRACE("(%p)\n", wndPtr);
|
||||
|
||||
if(!pWndDriverData) {
|
||||
ERR("WND already destroyed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(pWndDriverData->window) {
|
||||
ERR("WND destroyed without destroying the associated Curses Windows");
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pWndDriverData);
|
||||
wndPtr->pDriverData = NULL;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* TTYDRV_WND_CreateDesktopWindow
|
||||
*/
|
||||
BOOL TTYDRV_WND_CreateDesktopWindow(WND *wndPtr)
|
||||
{
|
||||
TTYDRV_WND_DATA *pWndDriverData =
|
||||
(TTYDRV_WND_DATA *) wndPtr->pDriverData;
|
||||
|
||||
TRACE("(%p)\n", wndPtr);
|
||||
|
||||
if(!pWndDriverData) { ERR("WND never initialized\n"); return FALSE; }
|
||||
|
||||
pWndDriverData->window = TTYDRV_GetRootWindow();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* TTYDRV_WND_CreateWindow
|
||||
*/
|
||||
BOOL TTYDRV_WND_CreateWindow(WND *wndPtr, CREATESTRUCTA *cs, BOOL bUnicode)
|
||||
BOOL TTYDRV_CreateWindow( HWND hwnd )
|
||||
{
|
||||
#ifdef WINE_CURSES
|
||||
WINDOW *window;
|
||||
INT cellWidth=8, cellHeight=8; /* FIXME: Hardcoded */
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
WINDOW *window;
|
||||
INT cellWidth=8, cellHeight=8; /* FIXME: Hardcoded */
|
||||
|
||||
TRACE("(%p, %p, %d)\n", wndPtr, cs, bUnicode);
|
||||
TRACE("(%x)\n", hwnd);
|
||||
|
||||
/* Only create top-level windows */
|
||||
if(cs->style & WS_CHILD)
|
||||
/* Only create top-level windows */
|
||||
if (wndPtr->dwStyle & WS_CHILD)
|
||||
{
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!wndPtr->parent) /* desktop */
|
||||
window = root_window;
|
||||
else
|
||||
{
|
||||
int x = wndPtr->rectWindow.left;
|
||||
int y = wndPtr->rectWindow.top;
|
||||
int cx = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
|
||||
int cy = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
|
||||
|
||||
window = subwin( root_window, cy/cellHeight, cx/cellWidth,
|
||||
y/cellHeight, x/cellWidth);
|
||||
werase(window);
|
||||
wrefresh(window);
|
||||
}
|
||||
wndPtr->pDriverData = window;
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
#else /* defined(WINE_CURSES) */
|
||||
FIXME("(%x): stub\n", hwnd);
|
||||
#endif /* defined(WINE_CURSES) */
|
||||
return TRUE;
|
||||
|
||||
window = subwin(TTYDRV_GetRootWindow(), cs->cy/cellHeight, cs->cx/cellWidth,
|
||||
cs->y/cellHeight, cs->x/cellWidth);
|
||||
werase(window);
|
||||
wrefresh(window);
|
||||
|
||||
return TRUE;
|
||||
#else /* defined(WINE_CURSES) */
|
||||
FIXME("(%p, %p, %p, %d): stub\n", wndPtr, cs, bUnicode);
|
||||
|
||||
return TRUE;
|
||||
#endif /* defined(WINE_CURSES) */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_WND_DestroyWindow
|
||||
* DestroyWindow (TTYDRV.@)
|
||||
*/
|
||||
BOOL TTYDRV_WND_DestroyWindow(WND *wndPtr)
|
||||
BOOL TTYDRV_DestroyWindow( HWND hwnd )
|
||||
{
|
||||
#ifdef WINE_CURSES
|
||||
WINDOW *window;
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
WINDOW *window = wndPtr->pDriverData;
|
||||
|
||||
TRACE("(%p)\n", wndPtr);
|
||||
TRACE("(%x)\n", hwnd);
|
||||
|
||||
window = TTYDRV_WND_GetCursesWindow(wndPtr);
|
||||
if(window && window != TTYDRV_GetRootWindow()) {
|
||||
delwin(window);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
if (window && window != root_window) delwin(window);
|
||||
wndPtr->pDriverData = NULL;
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
#else /* defined(WINE_CURSES) */
|
||||
FIXME("(%p): stub\n", wndPtr);
|
||||
|
||||
return TRUE;
|
||||
FIXME("(%x): stub\n", hwnd);
|
||||
#endif /* defined(WINE_CURSES) */
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* TTYDRV_WND_SetParent
|
||||
*/
|
||||
WND *TTYDRV_WND_SetParent(WND *wndPtr, WND *pWndParent)
|
||||
{
|
||||
FIXME("(%p, %p): stub\n", wndPtr, pWndParent);
|
||||
|
||||
return NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -168,30 +100,6 @@ void TTYDRV_WND_ForceWindowRaise(WND *wndPtr)
|
|||
FIXME("(%p): stub\n", wndPtr);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_WINPOS_SetWindowPos
|
||||
*/
|
||||
void TTYDRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bSMC_SETXPOS)
|
||||
{
|
||||
FIXME("(%p, %p, %d): stub\n", wndPtr, winpos, bSMC_SETXPOS);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* TTYDRV_WND_SetText
|
||||
*/
|
||||
void TTYDRV_WND_SetText(WND *wndPtr, LPCWSTR text)
|
||||
{
|
||||
FIXME("(%p, %s): stub\n", wndPtr, debugstr_w(text));
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* TTYDRV_WND_SetFocus
|
||||
*/
|
||||
void TTYDRV_WND_SetFocus(WND *wndPtr)
|
||||
{
|
||||
FIXME("(%p): stub\n", wndPtr);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* TTYDRV_WND_PreSizeMove
|
||||
*/
|
||||
|
@ -218,31 +126,6 @@ void TTYDRV_WND_ScrollWindow( WND *wndPtr, HDC hdc, INT dx, INT dy,
|
|||
wndPtr, hdc, dx, dy, clipRect, bUpdate);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_WND_SetDrawable
|
||||
*/
|
||||
void TTYDRV_WND_SetDrawable(WND *wndPtr, HDC hdc, WORD flags, BOOL bSetClipOrigin)
|
||||
{
|
||||
DC *dc = DC_GetDCPtr( hdc );
|
||||
if (!dc) return;
|
||||
TRACE("(%p, %p, %d, %d)\n", wndPtr, dc, flags, bSetClipOrigin);
|
||||
|
||||
/* FIXME: Should be done in the common code instead */
|
||||
if(!wndPtr) {
|
||||
dc->DCOrgX = 0;
|
||||
dc->DCOrgY = 0;
|
||||
} else {
|
||||
if(flags & DCX_WINDOW) {
|
||||
dc->DCOrgX = wndPtr->rectWindow.left;
|
||||
dc->DCOrgY = wndPtr->rectWindow.top;
|
||||
} else {
|
||||
dc->DCOrgX = wndPtr->rectClient.left;
|
||||
dc->DCOrgY = wndPtr->rectClient.top;
|
||||
}
|
||||
}
|
||||
GDI_ReleaseObj( hdc );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_WND_SetHostAttr
|
||||
*/
|
||||
|
@ -253,20 +136,519 @@ BOOL TTYDRV_WND_SetHostAttr(WND *wndPtr, INT attr, INT value)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_WND_IsSelfClipping
|
||||
*/
|
||||
BOOL TTYDRV_WND_IsSelfClipping(WND *wndPtr)
|
||||
{
|
||||
FIXME("(%p): semistub\n", wndPtr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TTYDRV_WND_SetWindowRgn
|
||||
* DCE_OffsetVisRgn
|
||||
*
|
||||
* Change region from DC-origin relative coordinates to screen coords.
|
||||
*/
|
||||
void TTYDRV_WND_SetWindowRgn(struct tagWND *wndPtr, HRGN hrgnWnd)
|
||||
|
||||
static void DCE_OffsetVisRgn( HDC hDC, HRGN hVisRgn )
|
||||
{
|
||||
DC *dc;
|
||||
if (!(dc = DC_GetDCPtr( hDC ))) return;
|
||||
|
||||
OffsetRgn( hVisRgn, dc->DCOrgX, dc->DCOrgY );
|
||||
|
||||
GDI_ReleaseObj( hDC );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DCE_GetVisRect
|
||||
*
|
||||
* Calculate the visible rectangle of a window (i.e. the client or
|
||||
* window area clipped by the client area of all ancestors) in the
|
||||
* corresponding coordinates. Return FALSE if the visible region is empty.
|
||||
*/
|
||||
static BOOL DCE_GetVisRect( WND *wndPtr, BOOL clientArea, RECT *lprect )
|
||||
{
|
||||
*lprect = clientArea ? wndPtr->rectClient : wndPtr->rectWindow;
|
||||
|
||||
if (wndPtr->dwStyle & WS_VISIBLE)
|
||||
{
|
||||
INT xoffset = lprect->left;
|
||||
INT yoffset = lprect->top;
|
||||
|
||||
while ((wndPtr = WIN_LockWndPtr(wndPtr->parent)))
|
||||
{
|
||||
if ( (wndPtr->dwStyle & (WS_ICONIC | WS_VISIBLE)) != WS_VISIBLE )
|
||||
{
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
xoffset += wndPtr->rectClient.left;
|
||||
yoffset += wndPtr->rectClient.top;
|
||||
OffsetRect( lprect, wndPtr->rectClient.left,
|
||||
wndPtr->rectClient.top );
|
||||
|
||||
if( (wndPtr->rectClient.left >= wndPtr->rectClient.right) ||
|
||||
(wndPtr->rectClient.top >= wndPtr->rectClient.bottom) ||
|
||||
(lprect->left >= wndPtr->rectClient.right) ||
|
||||
(lprect->right <= wndPtr->rectClient.left) ||
|
||||
(lprect->top >= wndPtr->rectClient.bottom) ||
|
||||
(lprect->bottom <= wndPtr->rectClient.top) )
|
||||
{
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
lprect->left = max( lprect->left, wndPtr->rectClient.left );
|
||||
lprect->right = min( lprect->right, wndPtr->rectClient.right );
|
||||
lprect->top = max( lprect->top, wndPtr->rectClient.top );
|
||||
lprect->bottom = min( lprect->bottom, wndPtr->rectClient.bottom );
|
||||
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
}
|
||||
OffsetRect( lprect, -xoffset, -yoffset );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
fail:
|
||||
SetRectEmpty( lprect );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DCE_AddClipRects
|
||||
*
|
||||
* Go through the linked list of windows from pWndStart to pWndEnd,
|
||||
* adding to the clip region the intersection of the target rectangle
|
||||
* with an offset window rectangle.
|
||||
*/
|
||||
static BOOL DCE_AddClipRects( WND *pWndStart, WND *pWndEnd,
|
||||
HRGN hrgnClip, LPRECT lpRect, int x, int y )
|
||||
{
|
||||
RECT rect;
|
||||
|
||||
for (WIN_LockWndPtr(pWndStart); (pWndStart && (pWndStart != pWndEnd)); WIN_UpdateWndPtr(&pWndStart,pWndStart->next))
|
||||
{
|
||||
if( !(pWndStart->dwStyle & WS_VISIBLE) ) continue;
|
||||
|
||||
rect.left = pWndStart->rectWindow.left + x;
|
||||
rect.top = pWndStart->rectWindow.top + y;
|
||||
rect.right = pWndStart->rectWindow.right + x;
|
||||
rect.bottom = pWndStart->rectWindow.bottom + y;
|
||||
|
||||
if( IntersectRect( &rect, &rect, lpRect ))
|
||||
{
|
||||
if(!REGION_UnionRectWithRgn( hrgnClip, &rect )) break;
|
||||
}
|
||||
}
|
||||
WIN_ReleaseWndPtr(pWndStart);
|
||||
return (pWndStart == pWndEnd);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DCE_GetVisRgn
|
||||
*
|
||||
* Return the visible region of a window, i.e. the client or window area
|
||||
* clipped by the client area of all ancestors, and then optionally
|
||||
* by siblings and children.
|
||||
*/
|
||||
static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
|
||||
{
|
||||
HRGN hrgnVis = 0;
|
||||
RECT rect;
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
WND *childWnd = WIN_FindWndPtr( hwndChild );
|
||||
|
||||
/* Get visible rectangle and create a region with it. */
|
||||
|
||||
if (wndPtr && DCE_GetVisRect(wndPtr, !(flags & DCX_WINDOW), &rect))
|
||||
{
|
||||
if((hrgnVis = CreateRectRgnIndirect( &rect )))
|
||||
{
|
||||
HRGN hrgnClip = CreateRectRgn( 0, 0, 0, 0 );
|
||||
INT xoffset, yoffset;
|
||||
|
||||
if( hrgnClip )
|
||||
{
|
||||
/* Compute obscured region for the visible rectangle by
|
||||
* clipping children, siblings, and ancestors. Note that
|
||||
* DCE_GetVisRect() returns a rectangle either in client
|
||||
* or in window coordinates (for DCX_WINDOW request). */
|
||||
|
||||
if( (flags & DCX_CLIPCHILDREN) && wndPtr->child )
|
||||
{
|
||||
if( flags & DCX_WINDOW )
|
||||
{
|
||||
/* adjust offsets since child window rectangles are
|
||||
* in client coordinates */
|
||||
|
||||
xoffset = wndPtr->rectClient.left - wndPtr->rectWindow.left;
|
||||
yoffset = wndPtr->rectClient.top - wndPtr->rectWindow.top;
|
||||
}
|
||||
else
|
||||
xoffset = yoffset = 0;
|
||||
|
||||
DCE_AddClipRects( wndPtr->child, NULL, hrgnClip, &rect, xoffset, yoffset );
|
||||
}
|
||||
|
||||
/* We may need to clip children of child window, if a window with PARENTDC
|
||||
* class style and CLIPCHILDREN window style (like in Free Agent 16
|
||||
* preference dialogs) gets here, we take the region for the parent window
|
||||
* but apparently still need to clip the children of the child window... */
|
||||
|
||||
if( (cflags & DCX_CLIPCHILDREN) && childWnd && childWnd->child )
|
||||
{
|
||||
if( flags & DCX_WINDOW )
|
||||
{
|
||||
/* adjust offsets since child window rectangles are
|
||||
* in client coordinates */
|
||||
|
||||
xoffset = wndPtr->rectClient.left - wndPtr->rectWindow.left;
|
||||
yoffset = wndPtr->rectClient.top - wndPtr->rectWindow.top;
|
||||
}
|
||||
else
|
||||
xoffset = yoffset = 0;
|
||||
|
||||
/* client coordinates of child window */
|
||||
xoffset += childWnd->rectClient.left;
|
||||
yoffset += childWnd->rectClient.top;
|
||||
|
||||
DCE_AddClipRects( childWnd->child, NULL, hrgnClip,
|
||||
&rect, xoffset, yoffset );
|
||||
}
|
||||
|
||||
/* sibling window rectangles are in client
|
||||
* coordinates of the parent window */
|
||||
|
||||
if (flags & DCX_WINDOW)
|
||||
{
|
||||
xoffset = -wndPtr->rectWindow.left;
|
||||
yoffset = -wndPtr->rectWindow.top;
|
||||
}
|
||||
else
|
||||
{
|
||||
xoffset = -wndPtr->rectClient.left;
|
||||
yoffset = -wndPtr->rectClient.top;
|
||||
}
|
||||
|
||||
if (flags & DCX_CLIPSIBLINGS && wndPtr->parent )
|
||||
DCE_AddClipRects( wndPtr->parent->child,
|
||||
wndPtr, hrgnClip, &rect, xoffset, yoffset );
|
||||
|
||||
/* Clip siblings of all ancestors that have the
|
||||
* WS_CLIPSIBLINGS style
|
||||
*/
|
||||
|
||||
while (wndPtr->parent)
|
||||
{
|
||||
WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
|
||||
xoffset -= wndPtr->rectClient.left;
|
||||
yoffset -= wndPtr->rectClient.top;
|
||||
if(wndPtr->dwStyle & WS_CLIPSIBLINGS && wndPtr->parent)
|
||||
{
|
||||
DCE_AddClipRects( wndPtr->parent->child, wndPtr,
|
||||
hrgnClip, &rect, xoffset, yoffset );
|
||||
}
|
||||
}
|
||||
|
||||
/* Now once we've got a jumbo clip region we have
|
||||
* to substract it from the visible rectangle.
|
||||
*/
|
||||
CombineRgn( hrgnVis, hrgnVis, hrgnClip, RGN_DIFF );
|
||||
DeleteObject( hrgnClip );
|
||||
}
|
||||
else
|
||||
{
|
||||
DeleteObject( hrgnVis );
|
||||
hrgnVis = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
hrgnVis = CreateRectRgn(0, 0, 0, 0); /* empty */
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
WIN_ReleaseWndPtr(childWnd);
|
||||
return hrgnVis;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetDC (TTYDRV.@)
|
||||
*
|
||||
* Set the drawable, origin and dimensions for the DC associated to
|
||||
* a given window.
|
||||
*/
|
||||
BOOL TTYDRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
|
||||
{
|
||||
WND *wndPtr = WIN_FindWndPtr(hwnd);
|
||||
DC *dc;
|
||||
BOOL updateVisRgn;
|
||||
HRGN hrgnVisible = 0;
|
||||
|
||||
if (!wndPtr) return FALSE;
|
||||
|
||||
if (!(dc = DC_GetDCPtr( hdc )))
|
||||
{
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(flags & DCX_WINDOW)
|
||||
{
|
||||
dc->DCOrgX = wndPtr->rectWindow.left;
|
||||
dc->DCOrgY = wndPtr->rectWindow.top;
|
||||
}
|
||||
else
|
||||
{
|
||||
dc->DCOrgX = wndPtr->rectClient.left;
|
||||
dc->DCOrgY = wndPtr->rectClient.top;
|
||||
}
|
||||
updateVisRgn = (dc->flags & DC_DIRTY) != 0;
|
||||
GDI_ReleaseObj( hdc );
|
||||
|
||||
if (updateVisRgn)
|
||||
{
|
||||
if (flags & DCX_PARENTCLIP)
|
||||
{
|
||||
WND *parentPtr = WIN_LockWndPtr(wndPtr->parent);
|
||||
|
||||
if( wndPtr->dwStyle & WS_VISIBLE && !(parentPtr->dwStyle & WS_MINIMIZE) )
|
||||
{
|
||||
DWORD dcxFlags;
|
||||
|
||||
if( parentPtr->dwStyle & WS_CLIPSIBLINGS )
|
||||
dcxFlags = DCX_CLIPSIBLINGS | (flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW));
|
||||
else
|
||||
dcxFlags = flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW);
|
||||
|
||||
hrgnVisible = DCE_GetVisRgn( parentPtr->hwndSelf, dcxFlags,
|
||||
wndPtr->hwndSelf, flags );
|
||||
if( flags & DCX_WINDOW )
|
||||
OffsetRgn( hrgnVisible, -wndPtr->rectWindow.left,
|
||||
-wndPtr->rectWindow.top );
|
||||
else
|
||||
OffsetRgn( hrgnVisible, -wndPtr->rectClient.left,
|
||||
-wndPtr->rectClient.top );
|
||||
DCE_OffsetVisRgn( hdc, hrgnVisible );
|
||||
}
|
||||
else
|
||||
hrgnVisible = CreateRectRgn( 0, 0, 0, 0 );
|
||||
WIN_ReleaseWndPtr(parentPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
hrgnVisible = DCE_GetVisRgn( hwnd, flags, 0, 0 );
|
||||
DCE_OffsetVisRgn( hdc, hrgnVisible );
|
||||
}
|
||||
SelectVisRgn16( hdc, hrgnVisible );
|
||||
}
|
||||
|
||||
/* apply additional region operation (if any) */
|
||||
|
||||
if( flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN) )
|
||||
{
|
||||
if( !hrgnVisible ) hrgnVisible = CreateRectRgn( 0, 0, 0, 0 );
|
||||
|
||||
TRACE("\tsaved VisRgn, clipRgn = %04x\n", hrgn);
|
||||
|
||||
SaveVisRgn16( hdc );
|
||||
CombineRgn( hrgnVisible, hrgn, 0, RGN_COPY );
|
||||
DCE_OffsetVisRgn( hdc, hrgnVisible );
|
||||
CombineRgn( hrgnVisible, InquireVisRgn16( hdc ), hrgnVisible,
|
||||
(flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
|
||||
SelectVisRgn16( hdc, hrgnVisible );
|
||||
}
|
||||
|
||||
if (hrgnVisible) DeleteObject( hrgnVisible );
|
||||
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetWindowPos (TTYDRV.@)
|
||||
*/
|
||||
BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos )
|
||||
{
|
||||
WND *wndPtr;
|
||||
RECT newWindowRect, newClientRect;
|
||||
BOOL retvalue;
|
||||
HWND hwndActive = GetForegroundWindow();
|
||||
|
||||
TRACE( "hwnd %04x, swp (%i,%i)-(%i,%i) flags %08x\n",
|
||||
winpos->hwnd, winpos->x, winpos->y,
|
||||
winpos->x + winpos->cx, winpos->y + winpos->cy, winpos->flags);
|
||||
|
||||
/* ------------------------------------------------------------------------ CHECKS */
|
||||
|
||||
/* Check window handle */
|
||||
|
||||
if (winpos->hwnd == GetDesktopWindow()) return FALSE;
|
||||
if (!(wndPtr = WIN_FindWndPtr( winpos->hwnd ))) return FALSE;
|
||||
|
||||
TRACE("\tcurrent (%i,%i)-(%i,%i), style %08x\n",
|
||||
wndPtr->rectWindow.left, wndPtr->rectWindow.top,
|
||||
wndPtr->rectWindow.right, wndPtr->rectWindow.bottom, (unsigned)wndPtr->dwStyle );
|
||||
|
||||
/* Fix redundant flags */
|
||||
|
||||
if(wndPtr->dwStyle & WS_VISIBLE)
|
||||
winpos->flags &= ~SWP_SHOWWINDOW;
|
||||
else
|
||||
{
|
||||
if (!(winpos->flags & SWP_SHOWWINDOW)) winpos->flags |= SWP_NOREDRAW;
|
||||
winpos->flags &= ~SWP_HIDEWINDOW;
|
||||
}
|
||||
|
||||
if ( winpos->cx < 0 ) winpos->cx = 0;
|
||||
if ( winpos->cy < 0 ) winpos->cy = 0;
|
||||
|
||||
if ((wndPtr->rectWindow.right - wndPtr->rectWindow.left == winpos->cx) &&
|
||||
(wndPtr->rectWindow.bottom - wndPtr->rectWindow.top == winpos->cy))
|
||||
winpos->flags |= SWP_NOSIZE; /* Already the right size */
|
||||
|
||||
if ((wndPtr->rectWindow.left == winpos->x) && (wndPtr->rectWindow.top == winpos->y))
|
||||
winpos->flags |= SWP_NOMOVE; /* Already the right position */
|
||||
|
||||
if (winpos->hwnd == hwndActive)
|
||||
winpos->flags |= SWP_NOACTIVATE; /* Already active */
|
||||
else if ( (wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD )
|
||||
{
|
||||
if(!(winpos->flags & SWP_NOACTIVATE)) /* Bring to the top when activating */
|
||||
{
|
||||
winpos->flags &= ~SWP_NOZORDER;
|
||||
winpos->hwndInsertAfter = HWND_TOP;
|
||||
goto Pos;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check hwndInsertAfter */
|
||||
|
||||
/* FIXME: TOPMOST not supported yet */
|
||||
if ((winpos->hwndInsertAfter == HWND_TOPMOST) ||
|
||||
(winpos->hwndInsertAfter == HWND_NOTOPMOST)) winpos->hwndInsertAfter = HWND_TOP;
|
||||
|
||||
/* hwndInsertAfter must be a sibling of the window */
|
||||
if ((winpos->hwndInsertAfter != HWND_TOP) && (winpos->hwndInsertAfter != HWND_BOTTOM))
|
||||
{
|
||||
WND* wnd = WIN_FindWndPtr(winpos->hwndInsertAfter);
|
||||
|
||||
if( wnd ) {
|
||||
if( wnd->parent != wndPtr->parent )
|
||||
{
|
||||
retvalue = FALSE;
|
||||
WIN_ReleaseWndPtr(wnd);
|
||||
goto END;
|
||||
}
|
||||
/* don't need to change the Zorder of hwnd if it's already inserted
|
||||
* after hwndInsertAfter or when inserting hwnd after itself.
|
||||
*/
|
||||
if(( wnd->next == wndPtr ) || (winpos->hwnd == winpos->hwndInsertAfter))
|
||||
winpos->flags |= SWP_NOZORDER;
|
||||
}
|
||||
WIN_ReleaseWndPtr(wnd);
|
||||
}
|
||||
|
||||
Pos: /* ------------------------------------------------------------------------ MAIN part */
|
||||
|
||||
/* Send WM_WINDOWPOSCHANGING message */
|
||||
|
||||
if (!(winpos->flags & SWP_NOSENDCHANGING))
|
||||
SendMessageA( wndPtr->hwndSelf, WM_WINDOWPOSCHANGING, 0, (LPARAM)winpos );
|
||||
|
||||
/* Calculate new position and size */
|
||||
|
||||
newWindowRect = wndPtr->rectWindow;
|
||||
newClientRect = (wndPtr->dwStyle & WS_MINIMIZE) ? wndPtr->rectWindow
|
||||
: wndPtr->rectClient;
|
||||
|
||||
if (!(winpos->flags & SWP_NOSIZE))
|
||||
{
|
||||
newWindowRect.right = newWindowRect.left + winpos->cx;
|
||||
newWindowRect.bottom = newWindowRect.top + winpos->cy;
|
||||
}
|
||||
if (!(winpos->flags & SWP_NOMOVE))
|
||||
{
|
||||
newWindowRect.left = winpos->x;
|
||||
newWindowRect.top = winpos->y;
|
||||
newWindowRect.right += winpos->x - wndPtr->rectWindow.left;
|
||||
newWindowRect.bottom += winpos->y - wndPtr->rectWindow.top;
|
||||
|
||||
OffsetRect( &newClientRect, winpos->x - wndPtr->rectWindow.left,
|
||||
winpos->y - wndPtr->rectWindow.top );
|
||||
}
|
||||
|
||||
if( winpos->hwndInsertAfter == HWND_TOP )
|
||||
winpos->flags |= ( wndPtr->parent->child == wndPtr)? SWP_NOZORDER: 0;
|
||||
else
|
||||
if( winpos->hwndInsertAfter == HWND_BOTTOM )
|
||||
winpos->flags |= ( wndPtr->next )? 0: SWP_NOZORDER;
|
||||
else
|
||||
if( !(winpos->flags & SWP_NOZORDER) )
|
||||
if( GetWindow(winpos->hwndInsertAfter, GW_HWNDNEXT) == wndPtr->hwndSelf )
|
||||
winpos->flags |= SWP_NOZORDER;
|
||||
|
||||
/* Common operations */
|
||||
|
||||
/* Send WM_NCCALCSIZE message to get new client area */
|
||||
if( (winpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
|
||||
{
|
||||
WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect,
|
||||
&wndPtr->rectWindow, &wndPtr->rectClient,
|
||||
winpos, &newClientRect );
|
||||
}
|
||||
|
||||
if(!(winpos->flags & SWP_NOZORDER) && winpos->hwnd != winpos->hwndInsertAfter)
|
||||
{
|
||||
if ( WIN_UnlinkWindow( winpos->hwnd ) )
|
||||
WIN_LinkWindow( winpos->hwnd, winpos->hwndInsertAfter );
|
||||
}
|
||||
|
||||
/* FIXME: actually do something with WVR_VALIDRECTS */
|
||||
|
||||
wndPtr->rectWindow = newWindowRect;
|
||||
wndPtr->rectClient = newClientRect;
|
||||
|
||||
if( winpos->flags & SWP_SHOWWINDOW )
|
||||
{
|
||||
wndPtr->dwStyle |= WS_VISIBLE;
|
||||
}
|
||||
else if( winpos->flags & SWP_HIDEWINDOW )
|
||||
{
|
||||
wndPtr->dwStyle &= ~WS_VISIBLE;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ FINAL */
|
||||
|
||||
/* repaint invalidated region (if any)
|
||||
*
|
||||
* FIXME: if SWP_NOACTIVATE is not set then set invalid regions here without any painting
|
||||
* and force update after ChangeActiveWindow() to avoid painting frames twice.
|
||||
*/
|
||||
|
||||
if( !(winpos->flags & SWP_NOREDRAW) )
|
||||
{
|
||||
RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0,
|
||||
RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN );
|
||||
if (wndPtr->parent->hwndSelf == GetDesktopWindow() ||
|
||||
wndPtr->parent->parent->hwndSelf == GetDesktopWindow())
|
||||
{
|
||||
RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0,
|
||||
RDW_ERASENOW | RDW_NOCHILDREN );
|
||||
}
|
||||
}
|
||||
|
||||
if (!(winpos->flags & SWP_NOACTIVATE))
|
||||
WINPOS_ChangeActiveWindow( winpos->hwnd, FALSE );
|
||||
|
||||
/* And last, send the WM_WINDOWPOSCHANGED message */
|
||||
|
||||
TRACE("\tstatus flags = %04x\n", winpos->flags & SWP_AGG_STATUSFLAGS);
|
||||
|
||||
if ((((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) &&
|
||||
!(winpos->flags & SWP_NOSENDCHANGING)) )
|
||||
SendMessageA( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)winpos );
|
||||
|
||||
retvalue = TRUE;
|
||||
END:
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
return retvalue;
|
||||
}
|
||||
|
|
|
@ -58,8 +58,6 @@ static BOOL load_driver(void)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
GET_USER_FUNC(Synchronize);
|
||||
GET_USER_FUNC(CheckFocus);
|
||||
GET_USER_FUNC(UserRepaintDisable);
|
||||
GET_USER_FUNC(InitKeyboard);
|
||||
GET_USER_FUNC(VkKeyScan);
|
||||
|
@ -71,8 +69,6 @@ static BOOL load_driver(void)
|
|||
GET_USER_FUNC(Beep);
|
||||
GET_USER_FUNC(GetDIState);
|
||||
GET_USER_FUNC(GetDIData);
|
||||
GET_USER_FUNC(GetKeyboardConfig);
|
||||
GET_USER_FUNC(SetKeyboardConfig);
|
||||
GET_USER_FUNC(InitMouse);
|
||||
GET_USER_FUNC(SetCursor);
|
||||
GET_USER_FUNC(MoveCursor);
|
||||
|
@ -90,6 +86,16 @@ static BOOL load_driver(void)
|
|||
GET_USER_FUNC(RegisterClipboardFormat);
|
||||
GET_USER_FUNC(IsSelectionOwner);
|
||||
GET_USER_FUNC(ResetSelectionOwner);
|
||||
GET_USER_FUNC(CreateWindow);
|
||||
GET_USER_FUNC(DestroyWindow);
|
||||
GET_USER_FUNC(GetDC);
|
||||
GET_USER_FUNC(EnableWindow);
|
||||
GET_USER_FUNC(SetFocus);
|
||||
GET_USER_FUNC(SetParent);
|
||||
GET_USER_FUNC(SetWindowPos);
|
||||
GET_USER_FUNC(SetWindowRgn);
|
||||
GET_USER_FUNC(SetWindowIcon);
|
||||
GET_USER_FUNC(SetWindowText);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ IMPORTS = user32 gdi32 kernel32
|
|||
|
||||
C_SRCS = \
|
||||
dga2.c \
|
||||
window.c \
|
||||
winpos.c \
|
||||
x11ddraw.c \
|
||||
x11drv_main.c \
|
||||
xvidmode.c
|
||||
|
|
|
@ -0,0 +1,633 @@
|
|||
/*
|
||||
* Window related functions
|
||||
*
|
||||
* Copyright 1993, 1994, 1995, 1996, 2001 Alexandre Julliard
|
||||
* Copyright 1993 David Metcalfe
|
||||
* Copyright 1995, 1996 Alex Korobka
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "ts_xlib.h"
|
||||
#include "ts_xutil.h"
|
||||
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
|
||||
#include "debugtools.h"
|
||||
#include "x11drv.h"
|
||||
#include "win.h"
|
||||
#include "options.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(win);
|
||||
|
||||
extern Cursor X11DRV_MOUSE_XCursor; /* current X cursor */
|
||||
extern Pixmap X11DRV_BITMAP_Pixmap( HBITMAP );
|
||||
|
||||
#define HAS_DLGFRAME(style,exStyle) \
|
||||
((!((style) & WS_THICKFRAME)) && (((style) & WS_DLGFRAME) || ((exStyle) & WS_EX_DLGMODALFRAME)))
|
||||
|
||||
/* X context to associate a hwnd to an X window */
|
||||
XContext winContext = 0;
|
||||
|
||||
Atom wmProtocols = None;
|
||||
Atom wmDeleteWindow = None;
|
||||
Atom dndProtocol = None;
|
||||
Atom dndSelection = None;
|
||||
Atom wmChangeState = None;
|
||||
Atom kwmDockWindow = None;
|
||||
Atom _kde_net_wm_system_tray_window_for = None; /* KDE 2 Final */
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* register_window
|
||||
*
|
||||
* Associate an X window to a HWND.
|
||||
*/
|
||||
static void register_window( HWND hwnd, Window win )
|
||||
{
|
||||
if (!winContext) winContext = TSXUniqueContext();
|
||||
TSXSaveContext( display, win, winContext, (char *)hwnd );
|
||||
TSXSetWMProtocols( display, win, &wmDeleteWindow, 1 );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* set_wm_hint
|
||||
*
|
||||
* Set a window manager hint.
|
||||
*/
|
||||
static void set_wm_hint( Window win, int hint, int val )
|
||||
{
|
||||
XWMHints* wm_hints = TSXGetWMHints( display, win );
|
||||
if (!wm_hints) wm_hints = TSXAllocWMHints();
|
||||
if (wm_hints)
|
||||
{
|
||||
wm_hints->flags = hint;
|
||||
switch( hint )
|
||||
{
|
||||
case InputHint:
|
||||
wm_hints->input = val;
|
||||
break;
|
||||
|
||||
case StateHint:
|
||||
wm_hints->initial_state = val;
|
||||
break;
|
||||
|
||||
case IconPixmapHint:
|
||||
wm_hints->icon_pixmap = (Pixmap)val;
|
||||
break;
|
||||
|
||||
case IconWindowHint:
|
||||
wm_hints->icon_window = (Window)val;
|
||||
break;
|
||||
}
|
||||
TSXSetWMHints( display, win, wm_hints );
|
||||
TSXFree(wm_hints);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* set_icon_hints
|
||||
*
|
||||
* Set the icon wm hints
|
||||
*/
|
||||
static void set_icon_hints( WND *wndPtr, XWMHints *hints )
|
||||
{
|
||||
X11DRV_WND_DATA *data = wndPtr->pDriverData;
|
||||
HICON hIcon = GetClassLongA( wndPtr->hwndSelf, GCL_HICON );
|
||||
|
||||
if (data->hWMIconBitmap) DeleteObject( data->hWMIconBitmap );
|
||||
if (data->hWMIconMask) DeleteObject( data->hWMIconMask);
|
||||
|
||||
if (!hIcon)
|
||||
{
|
||||
data->hWMIconBitmap = 0;
|
||||
data->hWMIconMask = 0;
|
||||
hints->flags &= ~(IconPixmapHint | IconMaskHint);
|
||||
}
|
||||
else
|
||||
{
|
||||
HBITMAP hbmOrig;
|
||||
RECT rcMask;
|
||||
BITMAP bmMask;
|
||||
ICONINFO ii;
|
||||
HDC hDC;
|
||||
|
||||
GetIconInfo(hIcon, &ii);
|
||||
|
||||
X11DRV_CreateBitmap(ii.hbmMask);
|
||||
X11DRV_CreateBitmap(ii.hbmColor);
|
||||
|
||||
GetObjectA(ii.hbmMask, sizeof(bmMask), &bmMask);
|
||||
rcMask.top = 0;
|
||||
rcMask.left = 0;
|
||||
rcMask.right = bmMask.bmWidth;
|
||||
rcMask.bottom = bmMask.bmHeight;
|
||||
|
||||
hDC = CreateCompatibleDC(0);
|
||||
hbmOrig = SelectObject(hDC, ii.hbmMask);
|
||||
InvertRect(hDC, &rcMask);
|
||||
SelectObject(hDC, hbmOrig);
|
||||
DeleteDC(hDC);
|
||||
|
||||
data->hWMIconBitmap = ii.hbmColor;
|
||||
data->hWMIconMask = ii.hbmMask;
|
||||
|
||||
hints->icon_pixmap = X11DRV_BITMAP_Pixmap(data->hWMIconBitmap);
|
||||
hints->icon_mask = X11DRV_BITMAP_Pixmap(data->hWMIconMask);
|
||||
hints->flags |= IconPixmapHint | IconMaskHint;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* dock_window
|
||||
*
|
||||
* Set the X Property of the window that tells the windowmanager we really
|
||||
* want to be in the systray
|
||||
*
|
||||
* KDE: set "KWM_DOCKWINDOW", type "KWM_DOCKWINDOW" to 1 before a window is
|
||||
* mapped.
|
||||
*
|
||||
* all others: to be added ;)
|
||||
*/
|
||||
inline static void dock_window( Window win )
|
||||
{
|
||||
int data = 1;
|
||||
if (kwmDockWindow != None)
|
||||
TSXChangeProperty( display, win, kwmDockWindow, kwmDockWindow,
|
||||
32, PropModeReplace, (char*)&data, 1 );
|
||||
if (_kde_net_wm_system_tray_window_for != None)
|
||||
TSXChangeProperty( display, win, _kde_net_wm_system_tray_window_for, XA_WINDOW,
|
||||
32, PropModeReplace, (char*)&win, 1 );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* create_desktop
|
||||
*/
|
||||
static void create_desktop(WND *wndPtr)
|
||||
{
|
||||
X11DRV_WND_DATA *data = wndPtr->pDriverData;
|
||||
|
||||
wmProtocols = TSXInternAtom( display, "WM_PROTOCOLS", True );
|
||||
wmDeleteWindow = TSXInternAtom( display, "WM_DELETE_WINDOW", True );
|
||||
dndProtocol = TSXInternAtom( display, "DndProtocol" , False );
|
||||
dndSelection = TSXInternAtom( display, "DndSelection" , False );
|
||||
wmChangeState = TSXInternAtom (display, "WM_CHANGE_STATE", False);
|
||||
kwmDockWindow = TSXInternAtom( display, "KWM_DOCKWINDOW", False );
|
||||
_kde_net_wm_system_tray_window_for = TSXInternAtom( display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False );
|
||||
|
||||
data->window = root_window;
|
||||
if (root_window != DefaultRootWindow(display)) wndPtr->flags |= WIN_NATIVE;
|
||||
register_window( wndPtr->hwndSelf, root_window );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* CreateWindow (X11DRV.@)
|
||||
*/
|
||||
BOOL X11DRV_CreateWindow( HWND hwnd )
|
||||
{
|
||||
X11DRV_WND_DATA *data;
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
int x = wndPtr->rectWindow.left;
|
||||
int y = wndPtr->rectWindow.top;
|
||||
int cx = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
|
||||
int cy = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
|
||||
|
||||
if (!(data = HeapAlloc(GetProcessHeap(), 0, sizeof(X11DRV_WND_DATA))))
|
||||
{
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return FALSE;
|
||||
}
|
||||
data->window = 0;
|
||||
wndPtr->pDriverData = data;
|
||||
|
||||
if (!wndPtr->parent)
|
||||
{
|
||||
create_desktop( wndPtr );
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Create the X window (only for top-level windows, and then only */
|
||||
/* when there's no desktop window) */
|
||||
|
||||
if ((root_window == DefaultRootWindow(display))
|
||||
&& (wndPtr->parent->hwndSelf == GetDesktopWindow()))
|
||||
{
|
||||
Window wGroupLeader;
|
||||
XWMHints* wm_hints;
|
||||
XSetWindowAttributes win_attr;
|
||||
|
||||
/* Create "managed" windows only if a title bar or resizable */
|
||||
/* frame is required. */
|
||||
if (WIN_WindowNeedsWMBorder(wndPtr->dwStyle, wndPtr->dwExStyle))
|
||||
{
|
||||
win_attr.event_mask = ExposureMask | KeyPressMask |
|
||||
KeyReleaseMask | PointerMotionMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
FocusChangeMask | StructureNotifyMask;
|
||||
win_attr.override_redirect = FALSE;
|
||||
wndPtr->dwExStyle |= WS_EX_MANAGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
win_attr.event_mask = ExposureMask | KeyPressMask |
|
||||
KeyReleaseMask | PointerMotionMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
FocusChangeMask;
|
||||
win_attr.override_redirect = TRUE;
|
||||
}
|
||||
wndPtr->flags |= WIN_NATIVE;
|
||||
|
||||
win_attr.bit_gravity = (wndPtr->clsStyle & (CS_VREDRAW | CS_HREDRAW)) ? ForgetGravity : NorthWestGravity;
|
||||
win_attr.colormap = X11DRV_PALETTE_PaletteXColormap;
|
||||
win_attr.backing_store = NotUseful;
|
||||
win_attr.save_under = ((wndPtr->clsStyle & CS_SAVEBITS) != 0);
|
||||
win_attr.cursor = X11DRV_MOUSE_XCursor;
|
||||
|
||||
data->hWMIconBitmap = 0;
|
||||
data->hWMIconMask = 0;
|
||||
data->bit_gravity = win_attr.bit_gravity;
|
||||
|
||||
/* Zero-size X11 window hack. X doesn't like them, and will crash */
|
||||
/* with a BadValue unless we do something ugly like this. */
|
||||
/* Zero size window won't be mapped */
|
||||
if (cx <= 0) cx = 1;
|
||||
if (cy <= 0) cy = 1;
|
||||
|
||||
data->window = TSXCreateWindow( display, root_window,
|
||||
x, y, cx, cy,
|
||||
0, screen_depth,
|
||||
InputOutput, visual,
|
||||
CWEventMask | CWOverrideRedirect |
|
||||
CWColormap | CWCursor | CWSaveUnder |
|
||||
CWBackingStore | CWBitGravity,
|
||||
&win_attr );
|
||||
|
||||
if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr)))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If we are the systray, we need to be managed to be noticed by KWM */
|
||||
if (wndPtr->dwExStyle & WS_EX_TRAYWINDOW) dock_window( data->window );
|
||||
|
||||
if (wndPtr->dwExStyle & WS_EX_MANAGED)
|
||||
{
|
||||
XClassHint *class_hints = TSXAllocClassHint();
|
||||
XSizeHints* size_hints = TSXAllocSizeHints();
|
||||
|
||||
if (class_hints)
|
||||
{
|
||||
class_hints->res_name = "wineManaged";
|
||||
class_hints->res_class = "Wine";
|
||||
TSXSetClassHint( display, data->window, class_hints );
|
||||
TSXFree (class_hints);
|
||||
}
|
||||
|
||||
if (size_hints)
|
||||
{
|
||||
size_hints->win_gravity = StaticGravity;
|
||||
size_hints->x = x;
|
||||
size_hints->y = y;
|
||||
size_hints->flags = PWinGravity|PPosition;
|
||||
|
||||
if (HAS_DLGFRAME(wndPtr->dwStyle,wndPtr->dwExStyle))
|
||||
{
|
||||
size_hints->min_width = size_hints->max_width = cx;
|
||||
size_hints->min_height = size_hints->max_height = cy;
|
||||
size_hints->flags |= PMinSize | PMaxSize;
|
||||
}
|
||||
|
||||
TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr),
|
||||
size_hints, XA_WM_NORMAL_HINTS );
|
||||
TSXFree(size_hints);
|
||||
}
|
||||
}
|
||||
|
||||
if (wndPtr->owner) /* Get window owner */
|
||||
{
|
||||
Window w = X11DRV_WND_FindXWindow( wndPtr->owner );
|
||||
if (w != None)
|
||||
{
|
||||
TSXSetTransientForHint( display, X11DRV_WND_GetXWindow(wndPtr), w );
|
||||
wGroupLeader = w;
|
||||
}
|
||||
}
|
||||
|
||||
if ((wm_hints = TSXAllocWMHints()))
|
||||
{
|
||||
wm_hints->flags = InputHint | StateHint | WindowGroupHint;
|
||||
wm_hints->input = True;
|
||||
|
||||
if (wndPtr->dwExStyle & WS_EX_MANAGED)
|
||||
{
|
||||
set_icon_hints( wndPtr, wm_hints );
|
||||
wm_hints->initial_state = (wndPtr->dwStyle & WS_MINIMIZE)
|
||||
? IconicState : NormalState;
|
||||
}
|
||||
else
|
||||
wm_hints->initial_state = NormalState;
|
||||
wm_hints->window_group = wGroupLeader;
|
||||
|
||||
TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
|
||||
TSXFree(wm_hints);
|
||||
}
|
||||
register_window( hwnd, data->window );
|
||||
}
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DestroyWindow (X11DRV.@)
|
||||
*/
|
||||
BOOL X11DRV_DestroyWindow( HWND hwnd )
|
||||
{
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
X11DRV_WND_DATA *data = wndPtr->pDriverData;
|
||||
Window w;
|
||||
|
||||
if (data && (w = data->window))
|
||||
{
|
||||
XEvent xe;
|
||||
TSXDeleteContext( display, w, winContext );
|
||||
TSXDestroyWindow( display, w );
|
||||
while( TSXCheckWindowEvent(display, w, NoEventMask, &xe) );
|
||||
|
||||
data->window = None;
|
||||
if( data->hWMIconBitmap )
|
||||
{
|
||||
DeleteObject( data->hWMIconBitmap );
|
||||
data->hWMIconBitmap = 0;
|
||||
}
|
||||
if( data->hWMIconMask )
|
||||
{
|
||||
DeleteObject( data->hWMIconMask);
|
||||
data->hWMIconMask= 0;
|
||||
}
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
wndPtr->pDriverData = NULL;
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
* SetParent (X11DRV.@)
|
||||
*/
|
||||
HWND X11DRV_SetParent( HWND hwnd, HWND parent )
|
||||
{
|
||||
WND *wndPtr;
|
||||
WND *pWndParent;
|
||||
DWORD dwStyle;
|
||||
HWND retvalue;
|
||||
|
||||
if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
|
||||
|
||||
dwStyle = wndPtr->dwStyle;
|
||||
|
||||
pWndParent = parent ? WIN_FindWndPtr(parent) : WIN_GetDesktop();
|
||||
if (!pWndParent)
|
||||
{
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Windows hides the window first, then shows it again
|
||||
* including the WM_SHOWWINDOW messages and all */
|
||||
if (dwStyle & WS_VISIBLE) ShowWindow( hwnd, SW_HIDE );
|
||||
|
||||
retvalue = wndPtr->parent->hwndSelf; /* old parent */
|
||||
if (pWndParent != wndPtr->parent)
|
||||
{
|
||||
if ( X11DRV_WND_GetXWindow(wndPtr) )
|
||||
{
|
||||
/* Toplevel window needs to be reparented. Used by Tk 8.0 */
|
||||
TSXDestroyWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
|
||||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None;
|
||||
}
|
||||
WIN_UnlinkWindow(wndPtr->hwndSelf);
|
||||
wndPtr->parent = pWndParent;
|
||||
|
||||
/* Create an X counterpart for reparented top-level windows
|
||||
* when not in the desktop mode. */
|
||||
if (parent == GetDesktopWindow())
|
||||
{
|
||||
if(root_window == DefaultRootWindow(display))
|
||||
X11DRV_CreateWindow(wndPtr->hwndSelf);
|
||||
}
|
||||
else /* a child window */
|
||||
{
|
||||
if( !( wndPtr->dwStyle & WS_CHILD ) )
|
||||
{
|
||||
if( wndPtr->wIDmenu != 0)
|
||||
{
|
||||
DestroyMenu( (HMENU) wndPtr->wIDmenu );
|
||||
wndPtr->wIDmenu = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP);
|
||||
}
|
||||
WIN_ReleaseWndPtr( pWndParent );
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
|
||||
/* SetParent additionally needs to make hwnd the topmost window
|
||||
in the x-order and send the expected WM_WINDOWPOSCHANGING and
|
||||
WM_WINDOWPOSCHANGED notification messages.
|
||||
*/
|
||||
SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0,
|
||||
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|
|
||||
((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0));
|
||||
/* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
|
||||
* for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
|
||||
|
||||
return retvalue;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* EnableWindow (X11DRV.@)
|
||||
*/
|
||||
BOOL X11DRV_EnableWindow( HWND hwnd, BOOL enable )
|
||||
{
|
||||
WND *wndPtr;
|
||||
BOOL retvalue;
|
||||
Window w;
|
||||
|
||||
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
|
||||
|
||||
retvalue = ((wndPtr->dwStyle & WS_DISABLED) != 0);
|
||||
|
||||
if (enable && (wndPtr->dwStyle & WS_DISABLED))
|
||||
{
|
||||
/* Enable window */
|
||||
wndPtr->dwStyle &= ~WS_DISABLED;
|
||||
|
||||
if ((wndPtr->dwExStyle & WS_EX_MANAGED) && (w = X11DRV_WND_GetXWindow( wndPtr )))
|
||||
set_wm_hint( w, InputHint, TRUE );
|
||||
|
||||
SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
|
||||
}
|
||||
else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
|
||||
{
|
||||
SendMessageA( wndPtr->hwndSelf, WM_CANCELMODE, 0, 0 );
|
||||
|
||||
/* Disable window */
|
||||
wndPtr->dwStyle |= WS_DISABLED;
|
||||
|
||||
if ((wndPtr->dwExStyle & WS_EX_MANAGED) && (w = X11DRV_WND_GetXWindow( wndPtr )))
|
||||
set_wm_hint( w, InputHint, FALSE );
|
||||
|
||||
if (hwnd == GetFocus())
|
||||
SetFocus( 0 ); /* A disabled window can't have the focus */
|
||||
|
||||
if (hwnd == GetCapture())
|
||||
ReleaseCapture(); /* A disabled window can't capture the mouse */
|
||||
|
||||
SendMessageA( hwnd, WM_ENABLE, FALSE, 0 );
|
||||
}
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
return retvalue;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
* SetFocus (X11DRV.@)
|
||||
*
|
||||
* Set the X focus.
|
||||
* Explicit colormap management seems to work only with OLVWM.
|
||||
*/
|
||||
void X11DRV_SetFocus( HWND hwnd )
|
||||
{
|
||||
XWindowAttributes win_attr;
|
||||
Window win;
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
WND *w = wndPtr;
|
||||
|
||||
if (!wndPtr) return;
|
||||
|
||||
/* Only mess with the X focus if there's */
|
||||
/* no desktop window and if the window is not managed by the WM. */
|
||||
if (root_window != DefaultRootWindow(display)) goto done;
|
||||
|
||||
while (w && !((X11DRV_WND_DATA *) w->pDriverData)->window)
|
||||
w = w->parent;
|
||||
if (!w) w = wndPtr;
|
||||
if (w->dwExStyle & WS_EX_MANAGED) goto done;
|
||||
|
||||
if (!hwnd) /* If setting the focus to 0, uninstall the colormap */
|
||||
{
|
||||
if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
|
||||
TSXUninstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
|
||||
}
|
||||
else if ((win = X11DRV_WND_FindXWindow(wndPtr)))
|
||||
{
|
||||
/* Set X focus and install colormap */
|
||||
if (TSXGetWindowAttributes( display, win, &win_attr ) &&
|
||||
(win_attr.map_state == IsViewable))
|
||||
{
|
||||
/* If window is not viewable, don't change anything */
|
||||
TSXSetInputFocus( display, win, RevertToParent, CurrentTime );
|
||||
if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
|
||||
TSXInstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
|
||||
X11DRV_Synchronize();
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
* SetWindowText (X11DRV.@)
|
||||
*/
|
||||
BOOL X11DRV_SetWindowText( HWND hwnd, LPCWSTR text )
|
||||
{
|
||||
UINT count;
|
||||
char *buffer;
|
||||
static UINT text_cp = (UINT)-1;
|
||||
Window win;
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
|
||||
if (!wndPtr) return FALSE;
|
||||
if ((win = X11DRV_WND_GetXWindow(wndPtr)))
|
||||
{
|
||||
if (text_cp == (UINT)-1)
|
||||
{
|
||||
text_cp = PROFILE_GetWineIniInt("x11drv", "TextCP", CP_ACP);
|
||||
TRACE("text_cp = %u\n", text_cp);
|
||||
}
|
||||
|
||||
/* allocate new buffer for window text */
|
||||
count = WideCharToMultiByte(text_cp, 0, text, -1, NULL, 0, NULL, NULL);
|
||||
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, count * sizeof(WCHAR) )))
|
||||
{
|
||||
ERR("Not enough memory for window text\n");
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return FALSE;
|
||||
}
|
||||
WideCharToMultiByte(text_cp, 0, text, -1, buffer, count, NULL, NULL);
|
||||
|
||||
TSXStoreName( display, win, buffer );
|
||||
TSXSetIconName( display, win, buffer );
|
||||
HeapFree( GetProcessHeap(), 0, buffer );
|
||||
}
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* X11DRV_SetWindowIcon
|
||||
*
|
||||
* hIcon or hIconSm has changed (or is being initialised for the
|
||||
* first time). Complete the X11 driver-specific initialisation
|
||||
* and set the window hints.
|
||||
*
|
||||
* This is not entirely correct, may need to create
|
||||
* an icon window and set the pixmap as a background
|
||||
*/
|
||||
HICON X11DRV_SetWindowIcon( HWND hwnd, HICON icon, BOOL small )
|
||||
{
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
int index = small ? GCL_HICONSM : GCL_HICON;
|
||||
HICON old;
|
||||
|
||||
if (!wndPtr) return 0;
|
||||
|
||||
old = GetClassLongW( hwnd, index );
|
||||
SetClassLongW( hwnd, index, icon );
|
||||
|
||||
SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE |
|
||||
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
|
||||
|
||||
if (wndPtr->dwExStyle & WS_EX_MANAGED)
|
||||
{
|
||||
Window win = X11DRV_WND_GetXWindow(wndPtr);
|
||||
XWMHints* wm_hints = TSXGetWMHints( display, win );
|
||||
|
||||
if (!wm_hints) wm_hints = TSXAllocWMHints();
|
||||
if (wm_hints)
|
||||
{
|
||||
set_icon_hints( wndPtr, wm_hints );
|
||||
TSXSetWMHints( display, win, wm_hints );
|
||||
TSXFree( wm_hints );
|
||||
}
|
||||
}
|
||||
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return old;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -11,8 +11,6 @@ debug_channels (bitblt bitmap clipboard cursor dinput event font gdi graphics
|
|||
|
||||
# USER driver
|
||||
|
||||
@ cdecl Synchronize() X11DRV_Synchronize
|
||||
@ cdecl CheckFocus() X11DRV_CheckFocus
|
||||
@ cdecl UserRepaintDisable(long) X11DRV_UserRepaintDisable
|
||||
@ cdecl InitKeyboard() X11DRV_InitKeyboard
|
||||
@ cdecl VkKeyScan(long) X11DRV_VkKeyScan
|
||||
|
@ -24,8 +22,6 @@ debug_channels (bitblt bitmap clipboard cursor dinput event font gdi graphics
|
|||
@ cdecl Beep() X11DRV_Beep
|
||||
@ cdecl GetDIState(long ptr) X11DRV_GetDIState
|
||||
@ cdecl GetDIData(ptr long ptr ptr long) X11DRV_GetDIData
|
||||
@ cdecl GetKeyboardConfig(ptr) X11DRV_GetKeyboardConfig
|
||||
@ cdecl SetKeyboardConfig(ptr long) X11DRV_SetKeyboardConfig
|
||||
@ cdecl InitMouse(ptr) X11DRV_InitMouse
|
||||
@ cdecl SetCursor(ptr) X11DRV_SetCursor
|
||||
@ cdecl MoveCursor(long long) X11DRV_MoveCursor
|
||||
|
@ -34,6 +30,16 @@ debug_channels (bitblt bitmap clipboard cursor dinput event font gdi graphics
|
|||
@ cdecl GetScreenSaveTimeout() X11DRV_GetScreenSaveTimeout
|
||||
@ cdecl SetScreenSaveTimeout(long) X11DRV_SetScreenSaveTimeout
|
||||
@ cdecl LoadOEMResource(long long) X11DRV_LoadOEMResource
|
||||
@ cdecl CreateWindow(long) X11DRV_CreateWindow
|
||||
@ cdecl DestroyWindow(long) X11DRV_DestroyWindow
|
||||
@ cdecl GetDC(long long long long) X11DRV_GetDC
|
||||
@ cdecl EnableWindow(long long) X11DRV_EnableWindow
|
||||
@ cdecl SetFocus(long) X11DRV_SetFocus
|
||||
@ cdecl SetParent(long long) X11DRV_SetParent
|
||||
@ cdecl SetWindowPos(ptr) X11DRV_SetWindowPos
|
||||
@ cdecl SetWindowRgn(long long) X11DRV_SetWindowRgn
|
||||
@ cdecl SetWindowIcon(long long long) X11DRV_SetWindowIcon
|
||||
@ cdecl SetWindowText(long wstr) X11DRV_SetWindowText
|
||||
@ cdecl IsSingleWindow() X11DRV_IsSingleWindow
|
||||
@ cdecl AcquireClipboard() X11DRV_AcquireClipboard
|
||||
@ cdecl ReleaseClipboard() X11DRV_ReleaseClipboard
|
||||
|
|
|
@ -42,7 +42,6 @@ extern DCE* DCE_AllocDCE( HWND hWnd, DCE_TYPE type );
|
|||
extern DCE* DCE_FreeDCE( DCE *dce );
|
||||
extern void DCE_FreeWindowDCE( struct tagWND* );
|
||||
extern INT DCE_ExcludeRgn( HDC, struct tagWND*, HRGN );
|
||||
extern HRGN DCE_GetVisRgn( HWND, WORD, HWND, WORD );
|
||||
extern BOOL DCE_InvalidateDCE( struct tagWND*, const RECT* );
|
||||
|
||||
#endif /* __WINE_DCE_H */
|
||||
|
|
|
@ -25,10 +25,6 @@ extern BOOL TIMER_GetTimerMsg( struct tagMSG *msg, HWND hwnd,
|
|||
HQUEUE16 hQueue, BOOL remove );
|
||||
extern BOOL TIMER_IsTimerValid( HWND hwnd, UINT id, HWINDOWPROC hProc );
|
||||
|
||||
/* event.c */
|
||||
extern void EVENT_Synchronize( void );
|
||||
extern BOOL EVENT_CheckFocus( void );
|
||||
|
||||
/* input.c */
|
||||
|
||||
extern HWND EVENT_Capture( HWND, INT16 );
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
#ifndef __WINE_USER_H
|
||||
#define __WINE_USER_H
|
||||
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
|
||||
#include "local.h"
|
||||
|
||||
extern WORD USER_HeapSel;
|
||||
|
@ -29,19 +33,12 @@ extern WORD USER_HeapSel;
|
|||
struct tagCURSORICONINFO;
|
||||
struct DIDEVICEOBJECTDATA;
|
||||
|
||||
#define WINE_KEYBOARD_CONFIG_AUTO_REPEAT 0x00000001
|
||||
typedef struct tagKEYBOARD_CONFIG {
|
||||
BOOL auto_repeat;
|
||||
} KEYBOARD_CONFIG;
|
||||
|
||||
typedef VOID CALLBACK (*LPMOUSE_EVENT_PROC)(DWORD,DWORD,DWORD,DWORD,DWORD);
|
||||
|
||||
struct tagWND;
|
||||
|
||||
typedef struct tagUSER_DRIVER {
|
||||
/* event functions */
|
||||
void (*pSynchronize)(void);
|
||||
BOOL (*pCheckFocus)(void);
|
||||
void (*pUserRepaintDisable)(BOOL);
|
||||
/* keyboard functions */
|
||||
void (*pInitKeyboard)(void);
|
||||
|
@ -54,8 +51,6 @@ typedef struct tagUSER_DRIVER {
|
|||
void (*pBeep)(void);
|
||||
BOOL (*pGetDIState)(DWORD, LPVOID);
|
||||
BOOL (*pGetDIData)(BYTE *, DWORD, struct DIDEVICEOBJECTDATA *, LPDWORD, DWORD);
|
||||
void (*pGetKeyboardConfig)(KEYBOARD_CONFIG *);
|
||||
void (*pSetKeyboardConfig)(KEYBOARD_CONFIG *, DWORD);
|
||||
/* mouse functions */
|
||||
void (*pInitMouse)(LPMOUSE_EVENT_PROC);
|
||||
void (*pSetCursor)(struct tagCURSORICONINFO *);
|
||||
|
@ -67,8 +62,6 @@ typedef struct tagUSER_DRIVER {
|
|||
void (*pSetScreenSaveTimeout)(int);
|
||||
/* resource functions */
|
||||
HANDLE (*pLoadOEMResource)(WORD,WORD);
|
||||
/* windowing functions */
|
||||
BOOL (*pIsSingleWindow)(void);
|
||||
/* clipboard functions */
|
||||
void (*pAcquireClipboard)(void); /* Acquire selection */
|
||||
void (*pReleaseClipboard)(void); /* Release selection */
|
||||
|
@ -78,6 +71,19 @@ typedef struct tagUSER_DRIVER {
|
|||
BOOL (*pRegisterClipboardFormat)(LPCSTR); /* Register a clipboard format */
|
||||
BOOL (*pIsSelectionOwner)(void); /* Check if we own the selection */
|
||||
void (*pResetSelectionOwner)(struct tagWND *, BOOL);
|
||||
|
||||
/* windowing functions */
|
||||
BOOL (*pCreateWindow)(HWND);
|
||||
BOOL (*pDestroyWindow)(HWND);
|
||||
BOOL (*pGetDC)(HWND,HDC,HRGN,DWORD);
|
||||
BOOL (*pEnableWindow)(HWND,BOOL);
|
||||
void (*pSetFocus)(HWND);
|
||||
HWND (*pSetParent)(HWND,HWND);
|
||||
BOOL (*pSetWindowPos)(WINDOWPOS *);
|
||||
BOOL (*pSetWindowRgn)(HWND,HRGN,BOOL);
|
||||
HICON (*pSetWindowIcon)(HWND,HICON,BOOL);
|
||||
BOOL (*pSetWindowText)(HWND,LPCWSTR);
|
||||
BOOL (*pIsSingleWindow)(void);
|
||||
} USER_DRIVER;
|
||||
|
||||
extern USER_DRIVER USER_Driver;
|
||||
|
|
|
@ -66,45 +66,15 @@ typedef struct tagWND
|
|||
} WND;
|
||||
|
||||
/* Host attributes */
|
||||
|
||||
#define HAK_BITGRAVITY 1
|
||||
#define HAK_ACCEPTFOCUS 2
|
||||
#define HAK_ICONICSTATE 3
|
||||
#define HAK_ICONS 4
|
||||
|
||||
/* 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 tagWND_DRIVER
|
||||
{
|
||||
void (*pInitialize)(WND *);
|
||||
void (*pFinalize)(WND *);
|
||||
BOOL (*pCreateDesktopWindow)(WND *);
|
||||
BOOL (*pCreateWindow)(WND *, CREATESTRUCTA *, BOOL);
|
||||
BOOL (*pDestroyWindow)(WND *);
|
||||
WND* (*pSetParent)(WND *, WND *);
|
||||
void (*pForceWindowRaise)(WND *);
|
||||
void (*pSetWindowPos)(WND *, const WINDOWPOS *, BOOL);
|
||||
void (*pSetText)(WND *, LPCWSTR);
|
||||
void (*pSetFocus)(WND *);
|
||||
void (*pPreSizeMove)(WND *);
|
||||
void (*pPostSizeMove)(WND *);
|
||||
void (*pSurfaceCopy)(WND *, HDC, INT, INT, const RECT *, BOOL);
|
||||
void (*pSetDrawable)(WND *, HDC, WORD, BOOL);
|
||||
BOOL (*pSetHostAttr)(WND *, INT haKey, INT value);
|
||||
BOOL (*pIsSelfClipping)(WND *);
|
||||
void (*pSetWindowRgn)(WND *, const HRGN);
|
||||
} WND_DRIVER;
|
||||
|
||||
extern WND_DRIVER *WND_Driver;
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
struct tagWND;
|
||||
|
||||
#define DWP_MAGIC ((INT)('W' | ('P' << 8) | ('O' << 16) | ('S' << 24)))
|
||||
|
||||
/* undocumented SWP flags - from SDK 3.1 */
|
||||
#define SWP_NOCLIENTSIZE 0x0800
|
||||
#define SWP_NOCLIENTMOVE 0x1000
|
||||
|
@ -25,16 +23,6 @@ struct tagWND;
|
|||
|
||||
struct tagWINDOWPOS16;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT actualCount;
|
||||
INT suggestedCount;
|
||||
BOOL valid;
|
||||
INT wMagic;
|
||||
HWND hwndParent;
|
||||
WINDOWPOS winPos[1];
|
||||
} DWP;
|
||||
|
||||
extern BOOL WINPOS_RedrawIconTitle( HWND hWnd );
|
||||
extern BOOL WINPOS_ShowIconTitle( struct tagWND* pWnd, BOOL bShow );
|
||||
extern void WINPOS_GetMinMaxInfo( struct tagWND* pWnd, POINT *maxSize,
|
||||
|
|
|
@ -31,7 +31,6 @@ struct tagDeviceCaps;
|
|||
struct tagPALETTEOBJ;
|
||||
struct tagWND;
|
||||
struct tagWINDOWPOS;
|
||||
struct tagKEYBOARD_CONFIG;
|
||||
struct DIDEVICEOBJECTDATA;
|
||||
|
||||
/* X physical pen */
|
||||
|
@ -364,8 +363,6 @@ extern UINT16 X11DRV_MapVirtualKey(UINT16 wCode, UINT16 wMapType);
|
|||
extern INT16 X11DRV_GetKeyNameText(LONG lParam, LPSTR lpBuffer, INT16 nSize);
|
||||
extern BOOL X11DRV_GetDIState(DWORD len, LPVOID ptr);
|
||||
extern BOOL X11DRV_GetDIData(BYTE *keystate, DWORD dodsize, struct DIDEVICEOBJECTDATA *dod, LPDWORD entries, DWORD flags);
|
||||
extern void X11DRV_GetKeyboardConfig(struct tagKEYBOARD_CONFIG *cfg);
|
||||
extern void X11DRV_SetKeyboardConfig(struct tagKEYBOARD_CONFIG *cfg, DWORD mask);
|
||||
|
||||
extern void X11DRV_HandleEvent(struct tagWND *pWnd, XKeyEvent *event);
|
||||
|
||||
|
@ -391,28 +388,20 @@ typedef struct _X11DRV_WND_DATA {
|
|||
extern Window X11DRV_WND_GetXWindow(struct tagWND *wndPtr);
|
||||
extern Window X11DRV_WND_FindXWindow(struct tagWND *wndPtr);
|
||||
|
||||
extern void X11DRV_WND_Initialize(struct tagWND *wndPtr);
|
||||
extern void X11DRV_WND_Finalize(struct tagWND *wndPtr);
|
||||
extern BOOL X11DRV_WND_CreateDesktopWindow(struct tagWND *wndPtr);
|
||||
extern BOOL X11DRV_WND_CreateWindow(struct tagWND *wndPtr, struct tagCREATESTRUCTA *cs, BOOL bUnicode);
|
||||
extern BOOL X11DRV_WND_DestroyWindow(struct tagWND *pWnd);
|
||||
extern struct tagWND *X11DRV_WND_SetParent(struct tagWND *wndPtr, struct tagWND *pWndParent);
|
||||
extern void X11DRV_WND_ForceWindowRaise(struct tagWND *pWnd);
|
||||
extern void X11DRV_WND_SetWindowPos(struct tagWND *wndPtr, const struct tagWINDOWPOS *winpos, BOOL bSMC_SETXPOS);
|
||||
extern void X11DRV_WND_SetText(struct tagWND *wndPtr, LPCWSTR 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_SurfaceCopy(struct tagWND *wndPtr, HDC hdc, INT dx, INT dy, const RECT *clipRect, BOOL bUpdate);
|
||||
extern void X11DRV_WND_SetDrawable(struct tagWND *wndPtr, HDC hdc, WORD flags, BOOL bSetClipOrigin);
|
||||
extern void X11DRV_WND_SetGravity(struct tagWND* wndPtr, int value );
|
||||
extern BOOL X11DRV_WND_SetHostAttr(struct tagWND *wndPtr, INT haKey, INT value);
|
||||
extern BOOL X11DRV_WND_IsSelfClipping(struct tagWND *wndPtr);
|
||||
extern void X11DRV_WND_DockWindow(struct tagWND *wndPtr);
|
||||
extern void X11DRV_WND_SetWindowRgn(struct tagWND *wndPtr, HRGN hrgnWnd);
|
||||
|
||||
extern int X11DRV_EVENT_PrepareShmCompletion( Drawable dw );
|
||||
extern void X11DRV_EVENT_WaitShmCompletion( int compl );
|
||||
extern void X11DRV_EVENT_WaitShmCompletions( Drawable dw );
|
||||
extern void X11DRV_EVENT_WaitReplaceShmCompletion( int *compl, Drawable dw );
|
||||
|
||||
extern void X11DRV_SetFocus( HWND hwnd );
|
||||
|
||||
#endif /* __WINE_X11DRV_H */
|
||||
|
|
|
@ -16,7 +16,6 @@ C_SRCS = \
|
|||
defwnd.c \
|
||||
dialog.c \
|
||||
driver.c \
|
||||
event.c \
|
||||
focus.c \
|
||||
hook.c \
|
||||
input.c \
|
||||
|
|
362
windows/dce.c
362
windows/dce.c
|
@ -356,242 +356,6 @@ BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate)
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DCE_GetVisRect
|
||||
*
|
||||
* Calculate the visible rectangle of a window (i.e. the client or
|
||||
* window area clipped by the client area of all ancestors) in the
|
||||
* corresponding coordinates. Return FALSE if the visible region is empty.
|
||||
*/
|
||||
static BOOL DCE_GetVisRect( WND *wndPtr, BOOL clientArea, RECT *lprect )
|
||||
{
|
||||
*lprect = clientArea ? wndPtr->rectClient : wndPtr->rectWindow;
|
||||
|
||||
if (wndPtr->dwStyle & WS_VISIBLE)
|
||||
{
|
||||
INT xoffset = lprect->left;
|
||||
INT yoffset = lprect->top;
|
||||
|
||||
while( !(wndPtr->flags & WIN_NATIVE) &&
|
||||
( wndPtr = WIN_LockWndPtr(wndPtr->parent)) )
|
||||
{
|
||||
if ( (wndPtr->dwStyle & (WS_ICONIC | WS_VISIBLE)) != WS_VISIBLE )
|
||||
{
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
xoffset += wndPtr->rectClient.left;
|
||||
yoffset += wndPtr->rectClient.top;
|
||||
OffsetRect( lprect, wndPtr->rectClient.left,
|
||||
wndPtr->rectClient.top );
|
||||
|
||||
if( (wndPtr->rectClient.left >= wndPtr->rectClient.right) ||
|
||||
(wndPtr->rectClient.top >= wndPtr->rectClient.bottom) ||
|
||||
(lprect->left >= wndPtr->rectClient.right) ||
|
||||
(lprect->right <= wndPtr->rectClient.left) ||
|
||||
(lprect->top >= wndPtr->rectClient.bottom) ||
|
||||
(lprect->bottom <= wndPtr->rectClient.top) )
|
||||
{
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
lprect->left = max( lprect->left, wndPtr->rectClient.left );
|
||||
lprect->right = min( lprect->right, wndPtr->rectClient.right );
|
||||
lprect->top = max( lprect->top, wndPtr->rectClient.top );
|
||||
lprect->bottom = min( lprect->bottom, wndPtr->rectClient.bottom );
|
||||
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
}
|
||||
OffsetRect( lprect, -xoffset, -yoffset );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
fail:
|
||||
SetRectEmpty( lprect );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DCE_AddClipRects
|
||||
*
|
||||
* Go through the linked list of windows from pWndStart to pWndEnd,
|
||||
* adding to the clip region the intersection of the target rectangle
|
||||
* with an offset window rectangle.
|
||||
*/
|
||||
static BOOL DCE_AddClipRects( WND *pWndStart, WND *pWndEnd,
|
||||
HRGN hrgnClip, LPRECT lpRect, int x, int y )
|
||||
{
|
||||
RECT rect;
|
||||
|
||||
if( pWndStart->pDriver->pIsSelfClipping( pWndStart ) )
|
||||
return TRUE; /* The driver itself will do the clipping */
|
||||
|
||||
for (WIN_LockWndPtr(pWndStart); (pWndStart && (pWndStart != pWndEnd)); WIN_UpdateWndPtr(&pWndStart,pWndStart->next))
|
||||
{
|
||||
if( !(pWndStart->dwStyle & WS_VISIBLE) ) continue;
|
||||
|
||||
rect.left = pWndStart->rectWindow.left + x;
|
||||
rect.top = pWndStart->rectWindow.top + y;
|
||||
rect.right = pWndStart->rectWindow.right + x;
|
||||
rect.bottom = pWndStart->rectWindow.bottom + y;
|
||||
|
||||
if( IntersectRect( &rect, &rect, lpRect ))
|
||||
{
|
||||
if(!REGION_UnionRectWithRgn( hrgnClip, &rect )) break;
|
||||
}
|
||||
}
|
||||
WIN_ReleaseWndPtr(pWndStart);
|
||||
return (pWndStart == pWndEnd);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DCE_GetVisRgn
|
||||
*
|
||||
* Return the visible region of a window, i.e. the client or window area
|
||||
* clipped by the client area of all ancestors, and then optionally
|
||||
* by siblings and children.
|
||||
*/
|
||||
HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
|
||||
{
|
||||
HRGN hrgnVis = 0;
|
||||
RECT rect;
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
WND *childWnd = WIN_FindWndPtr( hwndChild );
|
||||
|
||||
/* Get visible rectangle and create a region with it. */
|
||||
|
||||
if (wndPtr && DCE_GetVisRect(wndPtr, !(flags & DCX_WINDOW), &rect))
|
||||
{
|
||||
if((hrgnVis = CreateRectRgnIndirect( &rect )))
|
||||
{
|
||||
HRGN hrgnClip = CreateRectRgn( 0, 0, 0, 0 );
|
||||
INT xoffset, yoffset;
|
||||
|
||||
if( hrgnClip )
|
||||
{
|
||||
/* Compute obscured region for the visible rectangle by
|
||||
* clipping children, siblings, and ancestors. Note that
|
||||
* DCE_GetVisRect() returns a rectangle either in client
|
||||
* or in window coordinates (for DCX_WINDOW request). */
|
||||
|
||||
if( (flags & DCX_CLIPCHILDREN) && wndPtr->child )
|
||||
{
|
||||
if( flags & DCX_WINDOW )
|
||||
{
|
||||
/* adjust offsets since child window rectangles are
|
||||
* in client coordinates */
|
||||
|
||||
xoffset = wndPtr->rectClient.left - wndPtr->rectWindow.left;
|
||||
yoffset = wndPtr->rectClient.top - wndPtr->rectWindow.top;
|
||||
}
|
||||
else
|
||||
xoffset = yoffset = 0;
|
||||
|
||||
DCE_AddClipRects( wndPtr->child, NULL, hrgnClip,
|
||||
&rect, xoffset, yoffset );
|
||||
}
|
||||
|
||||
/* We may need to clip children of child window, if a window with PARENTDC
|
||||
* class style and CLIPCHILDREN window style (like in Free Agent 16
|
||||
* preference dialogs) gets here, we take the region for the parent window
|
||||
* but apparently still need to clip the children of the child window... */
|
||||
|
||||
if( (cflags & DCX_CLIPCHILDREN) && childWnd && childWnd->child )
|
||||
{
|
||||
if( flags & DCX_WINDOW )
|
||||
{
|
||||
/* adjust offsets since child window rectangles are
|
||||
* in client coordinates */
|
||||
|
||||
xoffset = wndPtr->rectClient.left - wndPtr->rectWindow.left;
|
||||
yoffset = wndPtr->rectClient.top - wndPtr->rectWindow.top;
|
||||
}
|
||||
else
|
||||
xoffset = yoffset = 0;
|
||||
|
||||
/* client coordinates of child window */
|
||||
xoffset += childWnd->rectClient.left;
|
||||
yoffset += childWnd->rectClient.top;
|
||||
|
||||
DCE_AddClipRects( childWnd->child, NULL, hrgnClip,
|
||||
&rect, xoffset, yoffset );
|
||||
}
|
||||
|
||||
/* sibling window rectangles are in client
|
||||
* coordinates of the parent window */
|
||||
|
||||
if (flags & DCX_WINDOW)
|
||||
{
|
||||
xoffset = -wndPtr->rectWindow.left;
|
||||
yoffset = -wndPtr->rectWindow.top;
|
||||
}
|
||||
else
|
||||
{
|
||||
xoffset = -wndPtr->rectClient.left;
|
||||
yoffset = -wndPtr->rectClient.top;
|
||||
}
|
||||
|
||||
if (flags & DCX_CLIPSIBLINGS && wndPtr->parent )
|
||||
DCE_AddClipRects( wndPtr->parent->child,
|
||||
wndPtr, hrgnClip, &rect, xoffset, yoffset );
|
||||
|
||||
/* Clip siblings of all ancestors that have the
|
||||
* WS_CLIPSIBLINGS style
|
||||
*/
|
||||
|
||||
while (wndPtr->parent)
|
||||
{
|
||||
WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
|
||||
xoffset -= wndPtr->rectClient.left;
|
||||
yoffset -= wndPtr->rectClient.top;
|
||||
if(wndPtr->dwStyle & WS_CLIPSIBLINGS && wndPtr->parent)
|
||||
{
|
||||
DCE_AddClipRects( wndPtr->parent->child, wndPtr,
|
||||
hrgnClip, &rect, xoffset, yoffset );
|
||||
}
|
||||
}
|
||||
|
||||
/* Now once we've got a jumbo clip region we have
|
||||
* to substract it from the visible rectangle.
|
||||
*/
|
||||
|
||||
CombineRgn( hrgnVis, hrgnVis, hrgnClip, RGN_DIFF );
|
||||
DeleteObject( hrgnClip );
|
||||
}
|
||||
else
|
||||
{
|
||||
DeleteObject( hrgnVis );
|
||||
hrgnVis = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
hrgnVis = CreateRectRgn(0, 0, 0, 0); /* empty */
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
WIN_ReleaseWndPtr(childWnd);
|
||||
return hrgnVis;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DCE_OffsetVisRgn
|
||||
*
|
||||
* Change region from DC-origin relative coordinates to screen coords.
|
||||
*/
|
||||
|
||||
static void DCE_OffsetVisRgn( HDC hDC, HRGN hVisRgn )
|
||||
{
|
||||
DC *dc;
|
||||
if (!(dc = DC_GetDCPtr( hDC ))) return;
|
||||
|
||||
OffsetRgn( hVisRgn, dc->DCOrgX, dc->DCOrgY );
|
||||
|
||||
GDI_ReleaseObj( hDC );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DCE_ExcludeRgn
|
||||
*
|
||||
|
@ -640,10 +404,8 @@ HDC16 WINAPI GetDCEx16( HWND16 hwnd, HRGN16 hrgnClip, DWORD flags )
|
|||
*/
|
||||
HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
|
||||
{
|
||||
HRGN hrgnVisible = 0;
|
||||
HDC hdc = 0;
|
||||
DCE * dce;
|
||||
DC * dc;
|
||||
WND * wndPtr;
|
||||
DWORD dcxFlags = 0;
|
||||
BOOL bUpdateVisRgn = TRUE;
|
||||
|
@ -779,90 +541,21 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
|
|||
goto END;
|
||||
}
|
||||
|
||||
if (!(flags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN))) hrgnClip = 0;
|
||||
dce->hwndCurrent = hwnd;
|
||||
dce->hClipRgn = 0;
|
||||
dce->DCXflags = dcxFlags | (flags & DCX_WINDOWPAINT) | DCX_DCEBUSY;
|
||||
dce->hClipRgn = hrgnClip;
|
||||
dce->DCXflags = flags & (DCX_PARENTCLIP | DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN |
|
||||
DCX_CACHE | DCX_WINDOW | DCX_WINDOWPAINT |
|
||||
DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_EXCLUDERGN);
|
||||
dce->DCXflags |= DCX_DCEBUSY;
|
||||
dce->DCXflags &= ~DCX_DCEDIRTY;
|
||||
hdc = dce->hDC;
|
||||
|
||||
if (!(dc = DC_GetDCPtr( hdc )))
|
||||
{
|
||||
hdc = 0;
|
||||
goto END;
|
||||
}
|
||||
bUpdateVisRgn = bUpdateVisRgn || (dc->flags & DC_DIRTY);
|
||||
|
||||
/* recompute visible region */
|
||||
wndPtr->pDriver->pSetDrawable( wndPtr, hdc, flags, bUpdateClipOrigin );
|
||||
dc->flags &= ~DC_DIRTY;
|
||||
GDI_ReleaseObj( hdc );
|
||||
if (bUpdateVisRgn) SetHookFlags16( hdc, DCHF_INVALIDATEVISRGN ); /* force update */
|
||||
|
||||
if( bUpdateVisRgn )
|
||||
{
|
||||
TRACE("updating visrgn for %08x dce, hwnd [%04x]\n", (unsigned)dce, hwnd);
|
||||
if (!USER_Driver.pGetDC( hwnd, hdc, hrgnClip, flags )) hdc = 0;
|
||||
|
||||
if (flags & DCX_PARENTCLIP)
|
||||
{
|
||||
WND *parentPtr = WIN_LockWndPtr(wndPtr->parent);
|
||||
|
||||
if( wndPtr->dwStyle & WS_VISIBLE && !(parentPtr->dwStyle & WS_MINIMIZE) )
|
||||
{
|
||||
if( parentPtr->dwStyle & WS_CLIPSIBLINGS )
|
||||
dcxFlags = DCX_CLIPSIBLINGS | (flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW));
|
||||
else
|
||||
dcxFlags = flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW);
|
||||
|
||||
hrgnVisible = DCE_GetVisRgn( parentPtr->hwndSelf, dcxFlags,
|
||||
wndPtr->hwndSelf, flags );
|
||||
if( flags & DCX_WINDOW )
|
||||
OffsetRgn( hrgnVisible, -wndPtr->rectWindow.left,
|
||||
-wndPtr->rectWindow.top );
|
||||
else
|
||||
OffsetRgn( hrgnVisible, -wndPtr->rectClient.left,
|
||||
-wndPtr->rectClient.top );
|
||||
DCE_OffsetVisRgn( hdc, hrgnVisible );
|
||||
}
|
||||
else
|
||||
hrgnVisible = CreateRectRgn( 0, 0, 0, 0 );
|
||||
WIN_ReleaseWndPtr(parentPtr);
|
||||
}
|
||||
else
|
||||
if ((hwnd == GetDesktopWindow()) && !USER_Driver.pIsSingleWindow())
|
||||
hrgnVisible = CreateRectRgn( 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN) );
|
||||
else
|
||||
{
|
||||
hrgnVisible = DCE_GetVisRgn( hwnd, flags, 0, 0 );
|
||||
DCE_OffsetVisRgn( hdc, hrgnVisible );
|
||||
}
|
||||
|
||||
dce->DCXflags &= ~DCX_DCEDIRTY;
|
||||
SelectVisRgn16( hdc, hrgnVisible );
|
||||
}
|
||||
else
|
||||
TRACE("no visrgn update %08x dce, hwnd [%04x]\n", (unsigned)dce, hwnd);
|
||||
|
||||
/* apply additional region operation (if any) */
|
||||
|
||||
if( flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN) )
|
||||
{
|
||||
if( !hrgnVisible ) hrgnVisible = CreateRectRgn( 0, 0, 0, 0 );
|
||||
|
||||
dce->DCXflags |= flags & (DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_EXCLUDERGN);
|
||||
dce->hClipRgn = hrgnClip;
|
||||
|
||||
TRACE("\tsaved VisRgn, clipRgn = %04x\n", hrgnClip);
|
||||
|
||||
SaveVisRgn16( hdc );
|
||||
CombineRgn( hrgnVisible, hrgnClip, 0, RGN_COPY );
|
||||
DCE_OffsetVisRgn( hdc, hrgnVisible );
|
||||
CombineRgn( hrgnVisible, InquireVisRgn16( hdc ), hrgnVisible,
|
||||
(flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
|
||||
SelectVisRgn16( hdc, hrgnVisible );
|
||||
}
|
||||
|
||||
if( hrgnVisible ) DeleteObject( hrgnVisible );
|
||||
|
||||
TRACE("(%04x,%04x,0x%lx): returning %04x\n",
|
||||
hwnd, hrgnClip, flags, hdc);
|
||||
TRACE("(%04x,%04x,0x%lx): returning %04x\n", hwnd, hrgnClip, flags, hdc);
|
||||
END:
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
return hdc;
|
||||
|
@ -960,9 +653,7 @@ INT WINAPI ReleaseDC(
|
|||
BOOL16 WINAPI DCHook16( HDC16 hDC, WORD code, DWORD data, LPARAM lParam )
|
||||
{
|
||||
BOOL retv = TRUE;
|
||||
HRGN hVisRgn;
|
||||
DCE *dce = (DCE *)data;
|
||||
WND *wndPtr;
|
||||
|
||||
TRACE("hDC = %04x, %i\n", hDC, code);
|
||||
|
||||
|
@ -975,43 +666,12 @@ BOOL16 WINAPI DCHook16( HDC16 hDC, WORD code, DWORD data, LPARAM lParam )
|
|||
switch( code )
|
||||
{
|
||||
case DCHC_INVALIDVISRGN:
|
||||
|
||||
/* GDI code calls this when it detects that the
|
||||
* DC is dirty (usually after SetHookFlags()). This
|
||||
* means that we have to recompute the visible region.
|
||||
*/
|
||||
|
||||
if( dce->DCXflags & DCX_DCEBUSY )
|
||||
{
|
||||
|
||||
/* Update stale DC in DCX */
|
||||
wndPtr = WIN_FindWndPtr( dce->hwndCurrent);
|
||||
if (wndPtr) wndPtr->pDriver->pSetDrawable( wndPtr, dce->hDC, dce->DCXflags, TRUE);
|
||||
|
||||
SetHookFlags16(hDC, DCHF_VALIDATEVISRGN);
|
||||
hVisRgn = DCE_GetVisRgn(dce->hwndCurrent, dce->DCXflags, 0, 0);
|
||||
|
||||
TRACE("\tapplying saved clipRgn\n");
|
||||
|
||||
/* clip this region with saved clipping region */
|
||||
|
||||
if ( (dce->DCXflags & DCX_INTERSECTRGN && dce->hClipRgn != 1) ||
|
||||
( dce->DCXflags & DCX_EXCLUDERGN && dce->hClipRgn) )
|
||||
{
|
||||
|
||||
if( (!dce->hClipRgn && dce->DCXflags & DCX_INTERSECTRGN) ||
|
||||
(dce->hClipRgn == 1 && dce->DCXflags & DCX_EXCLUDERGN) )
|
||||
SetRectRgn(hVisRgn,0,0,0,0);
|
||||
else
|
||||
CombineRgn(hVisRgn, hVisRgn, dce->hClipRgn,
|
||||
(dce->DCXflags & DCX_EXCLUDERGN)? RGN_DIFF:RGN_AND);
|
||||
}
|
||||
dce->DCXflags &= ~DCX_DCEDIRTY;
|
||||
DCE_OffsetVisRgn( hDC, hVisRgn );
|
||||
SelectVisRgn16(hDC, hVisRgn);
|
||||
DeleteObject( hVisRgn );
|
||||
WIN_ReleaseWndPtr( wndPtr ); /* Release WIN_FindWndPtr lock */
|
||||
}
|
||||
USER_Driver.pGetDC( dce->hwndCurrent, dce->hDC, dce->hClipRgn, dce->DCXflags );
|
||||
else /* non-fatal but shouldn't happen */
|
||||
WARN("DC is not in use!\n");
|
||||
break;
|
||||
|
|
|
@ -72,7 +72,8 @@ void DEFWND_SetTextA( WND *wndPtr, LPCSTR text )
|
|||
else
|
||||
ERR("Not enough memory for window text");
|
||||
|
||||
wndPtr->pDriver->pSetText(wndPtr, wndPtr->text);
|
||||
if (USER_Driver.pSetWindowText)
|
||||
USER_Driver.pSetWindowText(wndPtr->hwndSelf, wndPtr->text);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -94,7 +95,8 @@ void DEFWND_SetTextW( WND *wndPtr, LPCWSTR text )
|
|||
else
|
||||
ERR("Not enough memory for window text");
|
||||
|
||||
wndPtr->pDriver->pSetText(wndPtr, wndPtr->text);
|
||||
if (USER_Driver.pSetWindowText)
|
||||
USER_Driver.pSetWindowText(wndPtr->hwndSelf, wndPtr->text);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -165,7 +167,7 @@ static void DEFWND_SetRedraw( WND* wndPtr, WPARAM wParam )
|
|||
if( wndPtr->dwStyle & WS_MINIMIZE ) wParam = RDW_VALIDATE;
|
||||
else wParam = RDW_ALLCHILDREN | RDW_VALIDATE;
|
||||
|
||||
PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, wParam, 0 );
|
||||
RedrawWindow( wndPtr->hwndSelf, NULL, 0, wParam );
|
||||
DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
|
||||
wndPtr->dwStyle &= ~WS_VISIBLE;
|
||||
}
|
||||
|
@ -623,6 +625,9 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT msg, WPARAM wParam,
|
|||
return 1;
|
||||
|
||||
case WM_SETICON:
|
||||
if (USER_Driver.pSetWindowIcon)
|
||||
return USER_Driver.pSetWindowIcon( wndPtr->hwndSelf, lParam, (wParam != ICON_SMALL) );
|
||||
else
|
||||
{
|
||||
int index = (wParam != ICON_SMALL) ? GCL_HICON : GCL_HICONSM;
|
||||
HICON hOldIcon = GetClassLongW(wndPtr->hwndSelf, index);
|
||||
|
@ -631,10 +636,6 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT msg, WPARAM wParam,
|
|||
SetWindowPos(wndPtr->hwndSelf, 0, 0, 0, 0, 0, SWP_FRAMECHANGED
|
||||
| SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE
|
||||
| SWP_NOZORDER);
|
||||
|
||||
if( wndPtr->flags & WIN_NATIVE )
|
||||
wndPtr->pDriver->pSetHostAttr(wndPtr, HAK_ICONS, 0);
|
||||
|
||||
return hOldIcon;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* X events handling functions
|
||||
*
|
||||
* Copyright 1993 Alexandre Julliard
|
||||
*
|
||||
*/
|
||||
|
||||
#include "message.h"
|
||||
#include "user.h"
|
||||
#include "win.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
DECLARE_DEBUG_CHANNEL(event);
|
||||
|
||||
/***********************************************************************
|
||||
* EVENT_Synchronize
|
||||
*
|
||||
* Synchronize with the X server. Should not be used too often.
|
||||
*/
|
||||
void EVENT_Synchronize( void )
|
||||
{
|
||||
int iWndsLocks = WIN_SuspendWndsLock();
|
||||
USER_Driver.pSynchronize();
|
||||
WIN_RestoreWndsLock(iWndsLocks);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* EVENT_CheckFocus
|
||||
*/
|
||||
BOOL EVENT_CheckFocus(void)
|
||||
{
|
||||
return USER_Driver.pCheckFocus();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
#include "hook.h"
|
||||
#include "message.h"
|
||||
#include "queue.h"
|
||||
#include "user.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(win);
|
||||
|
@ -26,35 +27,20 @@ DEFAULT_DEBUG_CHANNEL(win);
|
|||
*/
|
||||
void FOCUS_SwitchFocus( MESSAGEQUEUE *pMsgQ, HWND hFocusFrom, HWND hFocusTo )
|
||||
{
|
||||
WND *pFocusTo = WIN_FindWndPtr( hFocusTo );
|
||||
|
||||
PERQDATA_SetFocusWnd( pMsgQ->pQData, hFocusTo );
|
||||
|
||||
#if 0
|
||||
if (hFocusFrom) SendMessageA( hFocusFrom, WM_KILLFOCUS, hFocusTo, 0 );
|
||||
#else
|
||||
/* FIXME: must be SendMessage16() because 32A doesn't do
|
||||
* intertask at this time */
|
||||
if (hFocusFrom) SendMessage16( hFocusFrom, WM_KILLFOCUS, hFocusTo, 0 );
|
||||
#endif
|
||||
|
||||
if( !pFocusTo || hFocusTo != PERQDATA_GetFocusWnd( pMsgQ->pQData ) )
|
||||
if (hFocusFrom) SendMessageA( hFocusFrom, WM_KILLFOCUS, hFocusTo, 0 );
|
||||
|
||||
if( !hFocusTo || hFocusTo != PERQDATA_GetFocusWnd( pMsgQ->pQData ) )
|
||||
{
|
||||
WIN_ReleaseWndPtr(pFocusTo);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
/* According to API docs, the WM_SETFOCUS message is sent AFTER the window
|
||||
has received the keyboard focus. */
|
||||
if (USER_Driver.pSetFocus) USER_Driver.pSetFocus(hFocusTo);
|
||||
|
||||
pFocusTo->pDriver->pSetFocus(pFocusTo);
|
||||
|
||||
WIN_ReleaseWndPtr(pFocusTo);
|
||||
#if 0
|
||||
SendMessageA( hFocusTo, WM_SETFOCUS, hFocusFrom, 0 );
|
||||
#else
|
||||
SendMessage16( hFocusTo, WM_SETFOCUS, hFocusFrom, 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2458,8 +2458,8 @@ LONG WINAPI DispatchMessageA( const MSG* msg )
|
|||
msg->hwnd);
|
||||
wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
|
||||
/* Validate the update region to avoid infinite WM_PAINT loop */
|
||||
PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0,
|
||||
RDW_FRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT, 0 );
|
||||
RedrawWindow( wndPtr->hwndSelf, NULL, 0,
|
||||
RDW_FRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT );
|
||||
}
|
||||
END:
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
|
|
|
@ -988,8 +988,7 @@ BOOL16 WINAPI RedrawWindow16( HWND16 hwnd, const RECT16 *rectUpdate,
|
|||
CONV_RECT16TO32( rectUpdate, &r );
|
||||
return (BOOL16)RedrawWindow( (HWND)hwnd, &r, hrgnUpdate, flags );
|
||||
}
|
||||
return (BOOL16)PAINT_RedrawWindow( (HWND)hwnd, NULL,
|
||||
(HRGN)hrgnUpdate, flags, 0 );
|
||||
return RedrawWindow( hwnd, NULL, hrgnUpdate, flags );
|
||||
}
|
||||
|
||||
|
||||
|
@ -998,7 +997,7 @@ BOOL16 WINAPI RedrawWindow16( HWND16 hwnd, const RECT16 *rectUpdate,
|
|||
*/
|
||||
void WINAPI UpdateWindow16( HWND16 hwnd )
|
||||
{
|
||||
PAINT_RedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN, 0 );
|
||||
RedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1006,7 +1005,7 @@ void WINAPI UpdateWindow16( HWND16 hwnd )
|
|||
*/
|
||||
void WINAPI UpdateWindow( HWND hwnd )
|
||||
{
|
||||
PAINT_RedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN, 0 );
|
||||
RedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1014,8 +1013,7 @@ void WINAPI UpdateWindow( HWND hwnd )
|
|||
*/
|
||||
void WINAPI InvalidateRgn16( HWND16 hwnd, HRGN16 hrgn, BOOL16 erase )
|
||||
{
|
||||
PAINT_RedrawWindow((HWND)hwnd, NULL, (HRGN)hrgn,
|
||||
RDW_INVALIDATE | (erase ? RDW_ERASE : 0), 0 );
|
||||
RedrawWindow((HWND)hwnd, NULL, (HRGN)hrgn, RDW_INVALIDATE | (erase ? RDW_ERASE : 0) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1024,7 +1022,7 @@ void WINAPI InvalidateRgn16( HWND16 hwnd, HRGN16 hrgn, BOOL16 erase )
|
|||
*/
|
||||
BOOL WINAPI InvalidateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
|
||||
{
|
||||
return PAINT_RedrawWindow(hwnd, NULL, hrgn, RDW_INVALIDATE | (erase ? RDW_ERASE : 0), 0 );
|
||||
return RedrawWindow(hwnd, NULL, hrgn, RDW_INVALIDATE | (erase ? RDW_ERASE : 0) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1042,8 +1040,7 @@ void WINAPI InvalidateRect16( HWND16 hwnd, const RECT16 *rect, BOOL16 erase )
|
|||
*/
|
||||
BOOL WINAPI InvalidateRect( HWND hwnd, const RECT *rect, BOOL erase )
|
||||
{
|
||||
return PAINT_RedrawWindow( hwnd, rect, 0,
|
||||
RDW_INVALIDATE | (erase ? RDW_ERASE : 0), 0 );
|
||||
return RedrawWindow( hwnd, rect, 0, RDW_INVALIDATE | (erase ? RDW_ERASE : 0) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1052,8 +1049,7 @@ BOOL WINAPI InvalidateRect( HWND hwnd, const RECT *rect, BOOL erase )
|
|||
*/
|
||||
void WINAPI ValidateRgn16( HWND16 hwnd, HRGN16 hrgn )
|
||||
{
|
||||
PAINT_RedrawWindow( (HWND)hwnd, NULL, (HRGN)hrgn,
|
||||
RDW_VALIDATE | RDW_NOCHILDREN, 0 );
|
||||
RedrawWindow( (HWND)hwnd, NULL, (HRGN)hrgn, RDW_VALIDATE | RDW_NOCHILDREN );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1062,7 +1058,7 @@ void WINAPI ValidateRgn16( HWND16 hwnd, HRGN16 hrgn )
|
|||
*/
|
||||
void WINAPI ValidateRgn( HWND hwnd, HRGN hrgn )
|
||||
{
|
||||
PAINT_RedrawWindow( hwnd, NULL, hrgn, RDW_VALIDATE | RDW_NOCHILDREN, 0 );
|
||||
RedrawWindow( hwnd, NULL, hrgn, RDW_VALIDATE | RDW_NOCHILDREN );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1080,7 +1076,7 @@ void WINAPI ValidateRect16( HWND16 hwnd, const RECT16 *rect )
|
|||
*/
|
||||
void WINAPI ValidateRect( HWND hwnd, const RECT *rect )
|
||||
{
|
||||
PAINT_RedrawWindow( hwnd, rect, 0, RDW_VALIDATE | RDW_NOCHILDREN, 0 );
|
||||
RedrawWindow( hwnd, rect, 0, RDW_VALIDATE | RDW_NOCHILDREN );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -336,8 +336,9 @@ rc.left, rc.top, rc.right, rc.bottom, (UINT16)flags );
|
|||
}
|
||||
|
||||
if( flags & (SW_INVALIDATE | SW_ERASE) )
|
||||
PAINT_RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE |
|
||||
((flags & SW_ERASE) ? RDW_ERASENOW : 0) | ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ), 0 );
|
||||
RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE |
|
||||
((flags & SW_ERASE) ? RDW_ERASENOW : 0) |
|
||||
((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) );
|
||||
|
||||
if( bCaret )
|
||||
{
|
||||
|
|
156
windows/win.c
156
windows/win.c
|
@ -455,8 +455,6 @@ static WND* WIN_DestroyWindow( WND* wndPtr )
|
|||
TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
|
||||
PROPERTY_RemoveWindowProps( wndPtr );
|
||||
|
||||
wndPtr->dwMagic = 0; /* Mark it as invalid */
|
||||
|
||||
/* toss stale messages from the queue */
|
||||
|
||||
if( wndPtr->hmemTaskQ )
|
||||
|
@ -494,16 +492,15 @@ static WND* WIN_DestroyWindow( WND* wndPtr )
|
|||
DestroyMenu( wndPtr->hSysMenu );
|
||||
wndPtr->hSysMenu = 0;
|
||||
}
|
||||
wndPtr->pDriver->pDestroyWindow( wndPtr );
|
||||
USER_Driver.pDestroyWindow( wndPtr->hwndSelf );
|
||||
DCE_FreeWindowDCE( wndPtr ); /* Always do this to catch orphaned DCs */
|
||||
WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
|
||||
CLASS_RemoveWindow( wndPtr->class );
|
||||
wndPtr->class = NULL;
|
||||
wndPtr->dwMagic = 0; /* Mark it as invalid */
|
||||
|
||||
WIN_UpdateWndPtr(&pWnd,wndPtr->next);
|
||||
|
||||
wndPtr->pDriver->pFinalize(wndPtr);
|
||||
|
||||
return pWnd;
|
||||
}
|
||||
|
||||
|
@ -590,8 +587,6 @@ BOOL WIN_CreateDesktopWindow(void)
|
|||
pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
|
||||
|
||||
pWndDesktop->pDriver = WND_Driver;
|
||||
pWndDesktop->pDriver->pInitialize(pWndDesktop);
|
||||
|
||||
pWndDesktop->next = NULL;
|
||||
pWndDesktop->child = NULL;
|
||||
pWndDesktop->parent = NULL;
|
||||
|
@ -626,7 +621,7 @@ BOOL WIN_CreateDesktopWindow(void)
|
|||
pWndDesktop->cbWndExtra = wndExtra;
|
||||
pWndDesktop->irefCount = 0;
|
||||
|
||||
if(!pWndDesktop->pDriver->pCreateDesktopWindow(pWndDesktop)) return FALSE;
|
||||
if (!USER_Driver.pCreateWindow( hwndDesktop )) return FALSE;
|
||||
|
||||
SendMessageW( hwndDesktop, WM_NCCREATE, 0, 0 );
|
||||
pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
|
||||
|
@ -789,7 +784,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
|
|||
|
||||
|
||||
wndPtr->pDriver = wndPtr->parent->pDriver;
|
||||
wndPtr->pDriver->pInitialize(wndPtr);
|
||||
|
||||
wndPtr->class = classPtr;
|
||||
wndPtr->winproc = winproc;
|
||||
|
@ -835,7 +829,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
|
|||
if (ret)
|
||||
{
|
||||
TRACE("CBT-hook returned 0\n");
|
||||
wndPtr->pDriver->pFinalize(wndPtr);
|
||||
USER_HEAP_FREE( hwnd );
|
||||
CLASS_RemoveWindow( classPtr );
|
||||
retvalue = 0;
|
||||
|
@ -889,7 +882,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
|
|||
wndPtr->rectWindow.bottom = cs->y + cs->cy;
|
||||
wndPtr->rectClient = wndPtr->rectWindow;
|
||||
|
||||
if(!wndPtr->pDriver->pCreateWindow(wndPtr, cs, type == WIN_PROC_32W))
|
||||
if (!USER_Driver.pCreateWindow(wndPtr->hwndSelf))
|
||||
{
|
||||
retvalue = FALSE;
|
||||
goto end;
|
||||
|
@ -1374,9 +1367,7 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
|
|||
|
||||
if (wndPtr->dwStyle & WS_VISIBLE)
|
||||
{
|
||||
SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
|
||||
SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
|
||||
((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
|
||||
ShowWindow( hwnd, SW_HIDE );
|
||||
if (!IsWindow(hwnd))
|
||||
{
|
||||
retvalue = TRUE;
|
||||
|
@ -1413,8 +1404,7 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
|
|||
else break;
|
||||
}
|
||||
|
||||
if( !Options.managed || EVENT_CheckFocus() )
|
||||
WINPOS_ActivateOtherWindow(wndPtr);
|
||||
WINPOS_ActivateOtherWindow(wndPtr);
|
||||
|
||||
if( wndPtr->owner &&
|
||||
wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
|
||||
|
@ -1725,45 +1715,34 @@ BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable )
|
|||
WND *wndPtr;
|
||||
BOOL retvalue;
|
||||
|
||||
TRACE("EnableWindow32: ( %x, %d )\n", hwnd, enable);
|
||||
|
||||
TRACE("( %x, %d )\n", hwnd, enable);
|
||||
|
||||
if (USER_Driver.pEnableWindow)
|
||||
return USER_Driver.pEnableWindow( hwnd, enable );
|
||||
|
||||
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
|
||||
|
||||
retvalue = ((wndPtr->dwStyle & WS_DISABLED) != 0);
|
||||
|
||||
if (enable && (wndPtr->dwStyle & WS_DISABLED))
|
||||
{
|
||||
/* 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;
|
||||
wndPtr->dwStyle &= ~WS_DISABLED; /* Enable window */
|
||||
SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
|
||||
}
|
||||
else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
|
||||
{
|
||||
SendMessageA( wndPtr->hwndSelf, WM_CANCELMODE, 0, 0);
|
||||
SendMessageA( wndPtr->hwndSelf, WM_CANCELMODE, 0, 0);
|
||||
|
||||
/* Disable window */
|
||||
wndPtr->dwStyle |= WS_DISABLED;
|
||||
wndPtr->dwStyle |= WS_DISABLED; /* Disable window */
|
||||
|
||||
if( wndPtr->flags & WIN_NATIVE )
|
||||
wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ACCEPTFOCUS, FALSE );
|
||||
if (hwnd == GetFocus())
|
||||
SetFocus( 0 ); /* A disabled window can't have the focus */
|
||||
|
||||
if (hwnd == GetFocus())
|
||||
{
|
||||
SetFocus( 0 ); /* A disabled window can't have the focus */
|
||||
}
|
||||
if (hwnd == GetCapture())
|
||||
{
|
||||
ReleaseCapture(); /* A disabled window can't capture the mouse */
|
||||
}
|
||||
SendMessageA( hwnd, WM_ENABLE, FALSE, 0 );
|
||||
retvalue = FALSE;
|
||||
goto end;
|
||||
if (hwnd == GetCapture())
|
||||
ReleaseCapture(); /* A disabled window can't capture the mouse */
|
||||
|
||||
SendMessageA( hwnd, WM_ENABLE, FALSE, 0 );
|
||||
}
|
||||
retvalue = ((wndPtr->dwStyle & WS_DISABLED) != 0);
|
||||
end:
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
return retvalue;
|
||||
}
|
||||
|
@ -2392,48 +2371,72 @@ HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
|
|||
/*****************************************************************
|
||||
* SetParent (USER32.@)
|
||||
*/
|
||||
HWND WINAPI SetParent( HWND hwndChild, HWND hwndNewParent )
|
||||
HWND WINAPI SetParent( HWND hwnd, HWND parent )
|
||||
{
|
||||
WND *wndPtr;
|
||||
DWORD dwStyle;
|
||||
WND *pWndNewParent;
|
||||
WND *pWndOldParent;
|
||||
HWND retvalue;
|
||||
WND *wndPtr;
|
||||
WND *pWndParent;
|
||||
DWORD dwStyle;
|
||||
HWND retvalue;
|
||||
|
||||
if (hwnd == GetDesktopWindow()) /* sanity check */
|
||||
{
|
||||
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!(wndPtr = WIN_FindWndPtr(hwndChild))) return 0;
|
||||
if (USER_Driver.pSetParent)
|
||||
return USER_Driver.pSetParent( hwnd, parent );
|
||||
|
||||
dwStyle = wndPtr->dwStyle;
|
||||
if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
|
||||
|
||||
pWndNewParent = hwndNewParent ? WIN_FindWndPtr(hwndNewParent)
|
||||
: WIN_LockWndPtr(pWndDesktop);
|
||||
dwStyle = wndPtr->dwStyle;
|
||||
|
||||
/* Windows hides the window first, then shows it again
|
||||
* including the WM_SHOWWINDOW messages and all */
|
||||
if (dwStyle & WS_VISIBLE)
|
||||
ShowWindow( hwndChild, SW_HIDE );
|
||||
pWndParent = parent ? WIN_FindWndPtr(parent) : WIN_GetDesktop();
|
||||
if (!pWndParent)
|
||||
{
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return 0;
|
||||
}
|
||||
|
||||
pWndOldParent = WIN_LockWndPtr((*wndPtr->pDriver->pSetParent)(wndPtr, pWndNewParent));
|
||||
/* Windows hides the window first, then shows it again
|
||||
* including the WM_SHOWWINDOW messages and all */
|
||||
if (dwStyle & WS_VISIBLE) ShowWindow( hwnd, SW_HIDE );
|
||||
|
||||
/* SetParent additionally needs to make hwndChild the topmost window
|
||||
in the x-order and send the expected WM_WINDOWPOSCHANGING and
|
||||
WM_WINDOWPOSCHANGED notification messages.
|
||||
*/
|
||||
SetWindowPos( hwndChild, HWND_TOPMOST, 0, 0, 0, 0,
|
||||
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0));
|
||||
/* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
|
||||
* for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
|
||||
retvalue = wndPtr->parent->hwndSelf; /* old parent */
|
||||
if (pWndParent != wndPtr->parent)
|
||||
{
|
||||
WIN_UnlinkWindow(wndPtr->hwndSelf);
|
||||
wndPtr->parent = pWndParent;
|
||||
|
||||
retvalue = pWndOldParent?pWndOldParent->hwndSelf:0;
|
||||
if (parent != GetDesktopWindow()) /* a child window */
|
||||
{
|
||||
if( !( wndPtr->dwStyle & WS_CHILD ) )
|
||||
{
|
||||
if( wndPtr->wIDmenu != 0)
|
||||
{
|
||||
DestroyMenu( (HMENU) wndPtr->wIDmenu );
|
||||
wndPtr->wIDmenu = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP);
|
||||
}
|
||||
WIN_ReleaseWndPtr( pWndParent );
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
|
||||
WIN_ReleaseWndPtr(pWndOldParent);
|
||||
WIN_ReleaseWndPtr(pWndNewParent);
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
|
||||
return retvalue;
|
||||
|
||||
/* SetParent additionally needs to make hwnd the topmost window
|
||||
in the x-order and send the expected WM_WINDOWPOSCHANGING and
|
||||
WM_WINDOWPOSCHANGED notification messages.
|
||||
*/
|
||||
SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0,
|
||||
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|
|
||||
((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0));
|
||||
/* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
|
||||
* for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
|
||||
return retvalue;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* IsChild (USER.48)
|
||||
*/
|
||||
|
@ -3071,8 +3074,7 @@ BOOL WINAPI FlashWindow( HWND hWnd, BOOL bInvert )
|
|||
}
|
||||
else
|
||||
{
|
||||
PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
|
||||
RDW_UPDATENOW | RDW_FRAME, 0 );
|
||||
RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_FRAME );
|
||||
wndPtr->flags &= ~WIN_NCACTIVATED;
|
||||
}
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
|
|
902
windows/winpos.c
902
windows/winpos.c
|
@ -36,25 +36,27 @@ DEFAULT_DEBUG_CHANNEL(win);
|
|||
(((style) & WS_THICKFRAME) && \
|
||||
!(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
|
||||
|
||||
#define SWP_AGG_NOGEOMETRYCHANGE \
|
||||
(SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
|
||||
#define SWP_AGG_NOPOSCHANGE \
|
||||
(SWP_AGG_NOGEOMETRYCHANGE | SWP_NOZORDER)
|
||||
#define SWP_AGG_STATUSFLAGS \
|
||||
(SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
|
||||
|
||||
#define EMPTYPOINT(pt) ((*(LONG*)&(pt)) == -1)
|
||||
|
||||
#define PLACE_MIN 0x0001
|
||||
#define PLACE_MAX 0x0002
|
||||
#define PLACE_RECT 0x0004
|
||||
|
||||
#define SWP_EX_NOCOPY 0x0001
|
||||
#define SWP_EX_PAINTSELF 0x0002
|
||||
#define SWP_EX_NONCLIENT 0x0004
|
||||
|
||||
#define MINMAX_NOSWP 0x00010000
|
||||
|
||||
|
||||
#define DWP_MAGIC ((INT)('W' | ('P' << 8) | ('O' << 16) | ('S' << 24)))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT actualCount;
|
||||
INT suggestedCount;
|
||||
BOOL valid;
|
||||
INT wMagic;
|
||||
HWND hwndParent;
|
||||
WINDOWPOS winPos[1];
|
||||
} DWP;
|
||||
|
||||
/* ----- internal variables ----- */
|
||||
|
||||
static HWND hwndPrevActive = 0; /* Previously active window */
|
||||
|
@ -288,65 +290,39 @@ int WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
|
|||
*/
|
||||
int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw )
|
||||
{
|
||||
RECT rect;
|
||||
WND *wndPtr;
|
||||
int ret = FALSE;
|
||||
RECT tempRect;
|
||||
|
||||
WND *wndPtr = WIN_FindWndPtr(hwnd);
|
||||
if (USER_Driver.pSetWindowRgn)
|
||||
return USER_Driver.pSetWindowRgn( hwnd, hrgn, bRedraw );
|
||||
|
||||
if (!wndPtr) return FALSE;
|
||||
if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
|
||||
|
||||
/* a region exists for this window */
|
||||
if (hrgn != 0 && hrgn == wndPtr->hrgnWnd)
|
||||
if (wndPtr->hrgnWnd == hrgn)
|
||||
{
|
||||
/* can't replace actual region with same region
|
||||
since we're now owner of that region
|
||||
*/
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
ret = TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
/* we'd like to set it back to 0 */
|
||||
if (hrgn == 0)
|
||||
if (hrgn) /* verify that region really exists */
|
||||
{
|
||||
GetWindowRect(hwnd, &tempRect);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* verify that region really exists */
|
||||
if (GetRgnBox(hrgn, &tempRect) == ERROR) goto done;
|
||||
if (GetRgnBox( hrgn, &rect ) == ERROR) goto done;
|
||||
}
|
||||
|
||||
|
||||
/* Size the window to the rectangle of the new region
|
||||
(if it isn't NULL) */
|
||||
/* James: Added SWP_NOACTIVATE because SetWindowRgn in Windows doesn't activate the
|
||||
window (and this was REALLY screwing up my app) */
|
||||
SetWindowPos( hwnd, 0, tempRect.left, tempRect.top,
|
||||
tempRect.right - tempRect.left, tempRect.bottom - tempRect.top,
|
||||
SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE |
|
||||
SWP_NOZORDER | (bRedraw ? 0 : SWP_NOREDRAW) );
|
||||
|
||||
|
||||
if (wndPtr->hrgnWnd)
|
||||
{
|
||||
/* delete previous region */
|
||||
DeleteObject(wndPtr->hrgnWnd);
|
||||
wndPtr->hrgnWnd = 0;
|
||||
}
|
||||
else if (!hrgn)
|
||||
{
|
||||
/* if there was no previous region (stored in wndPtr->hrgnWnd) and
|
||||
the region to be set is also NULL, there is nothing more to do
|
||||
*/
|
||||
ret = TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* valid region handle */
|
||||
wndPtr->hrgnWnd = hrgn;
|
||||
wndPtr->pDriver->pSetWindowRgn(wndPtr, hrgn);
|
||||
|
||||
/* Size the window to the rectangle of the new region (if it isn't NULL) */
|
||||
if (hrgn) SetWindowPos( hwnd, 0, rect.left, rect.top,
|
||||
rect.right - rect.left, rect.bottom - rect.top,
|
||||
SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE |
|
||||
SWP_NOZORDER | (bRedraw ? 0 : SWP_NOREDRAW) );
|
||||
ret = TRUE;
|
||||
|
||||
done:
|
||||
|
@ -1271,9 +1247,8 @@ UINT WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
|
|||
wndPtr->flags &= ~WIN_RESTORE_MAX;
|
||||
wndPtr->dwStyle |= WS_MINIMIZE;
|
||||
|
||||
if( wndPtr->flags & WIN_NATIVE )
|
||||
if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) )
|
||||
swpFlags |= MINMAX_NOSWP;
|
||||
if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) )
|
||||
swpFlags |= MINMAX_NOSWP;
|
||||
|
||||
lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
|
||||
|
||||
|
@ -1289,8 +1264,7 @@ UINT WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
|
|||
|
||||
if( wndPtr->dwStyle & WS_MINIMIZE )
|
||||
{
|
||||
if( wndPtr->flags & WIN_NATIVE )
|
||||
wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE );
|
||||
wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE );
|
||||
|
||||
WINPOS_ShowIconTitle( wndPtr, FALSE );
|
||||
wndPtr->dwStyle &= ~WS_MINIMIZE;
|
||||
|
@ -1304,8 +1278,7 @@ UINT WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
|
|||
case SW_RESTORE:
|
||||
if( wndPtr->dwStyle & WS_MINIMIZE )
|
||||
{
|
||||
if( wndPtr->flags & WIN_NATIVE )
|
||||
wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE );
|
||||
wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE );
|
||||
|
||||
wndPtr->dwStyle &= ~WS_MINIMIZE;
|
||||
WINPOS_ShowIconTitle( wndPtr, FALSE );
|
||||
|
@ -2176,411 +2149,6 @@ LONG WINPOS_HandleWindowPosChanging( WND *wndPtr, WINDOWPOS *winpos )
|
|||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SWP_DoOwnedPopups
|
||||
*
|
||||
* fix Z order taking into account owned popups -
|
||||
* basically we need to maintain them above the window that owns them
|
||||
*
|
||||
* FIXME: hide/show owned popups when owner visibility changes.
|
||||
*/
|
||||
static HWND SWP_DoOwnedPopups(WND* pDesktop, WND* wndPtr, HWND hwndInsertAfter, WORD flags)
|
||||
{
|
||||
WND* w = WIN_LockWndPtr(pDesktop->child);
|
||||
|
||||
WARN("(%04x) hInsertAfter = %04x\n", wndPtr->hwndSelf, hwndInsertAfter );
|
||||
|
||||
if( (wndPtr->dwStyle & WS_POPUP) && wndPtr->owner )
|
||||
{
|
||||
/* make sure this popup stays above the owner */
|
||||
|
||||
HWND hwndLocalPrev = HWND_TOP;
|
||||
|
||||
if( hwndInsertAfter != HWND_TOP )
|
||||
{
|
||||
while( w && w != wndPtr->owner )
|
||||
{
|
||||
if (w != wndPtr) hwndLocalPrev = w->hwndSelf;
|
||||
if( hwndLocalPrev == hwndInsertAfter ) break;
|
||||
WIN_UpdateWndPtr(&w,w->next);
|
||||
}
|
||||
hwndInsertAfter = hwndLocalPrev;
|
||||
}
|
||||
}
|
||||
else if( wndPtr->dwStyle & WS_CHILD )
|
||||
goto END;
|
||||
|
||||
WIN_UpdateWndPtr(&w, pDesktop->child);
|
||||
|
||||
while( w )
|
||||
{
|
||||
if( w == wndPtr ) break;
|
||||
|
||||
if( (w->dwStyle & WS_POPUP) && w->owner == wndPtr )
|
||||
{
|
||||
SetWindowPos(w->hwndSelf, hwndInsertAfter, 0, 0, 0, 0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_DEFERERASE);
|
||||
hwndInsertAfter = w->hwndSelf;
|
||||
}
|
||||
WIN_UpdateWndPtr(&w, w->next);
|
||||
}
|
||||
|
||||
END:
|
||||
WIN_ReleaseWndPtr(w);
|
||||
return hwndInsertAfter;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SWP_CopyValidBits
|
||||
*
|
||||
* Make window look nice without excessive repainting
|
||||
*
|
||||
* visible and update regions are in window coordinates
|
||||
* client and window rectangles are in parent client coordinates
|
||||
*
|
||||
* Returns: uFlags and a dirty region in *pVisRgn.
|
||||
*/
|
||||
static UINT SWP_CopyValidBits( WND* Wnd, HRGN* pVisRgn,
|
||||
LPRECT lpOldWndRect,
|
||||
LPRECT lpOldClientRect, UINT uFlags )
|
||||
{
|
||||
RECT r;
|
||||
HRGN newVisRgn, dirtyRgn;
|
||||
INT my = COMPLEXREGION;
|
||||
DWORD dflags;
|
||||
|
||||
TRACE("\tnew wnd=(%i %i-%i %i) old wnd=(%i %i-%i %i), %04x\n",
|
||||
Wnd->rectWindow.left, Wnd->rectWindow.top,
|
||||
Wnd->rectWindow.right, Wnd->rectWindow.bottom,
|
||||
lpOldWndRect->left, lpOldWndRect->top,
|
||||
lpOldWndRect->right, lpOldWndRect->bottom, *pVisRgn);
|
||||
TRACE("\tnew client=(%i %i-%i %i) old client=(%i %i-%i %i)\n",
|
||||
Wnd->rectClient.left, Wnd->rectClient.top,
|
||||
Wnd->rectClient.right, Wnd->rectClient.bottom,
|
||||
lpOldClientRect->left, lpOldClientRect->top,
|
||||
lpOldClientRect->right,lpOldClientRect->bottom );
|
||||
|
||||
if( Wnd->hrgnUpdate == 1 )
|
||||
uFlags |= SWP_EX_NOCOPY; /* whole window is invalid, nothing to copy */
|
||||
|
||||
dflags = DCX_WINDOW;
|
||||
if(Wnd->dwStyle & WS_CLIPSIBLINGS)
|
||||
dflags |= DCX_CLIPSIBLINGS;
|
||||
newVisRgn = DCE_GetVisRgn( Wnd->hwndSelf, dflags, 0, 0);
|
||||
|
||||
dirtyRgn = CreateRectRgn( 0, 0, 0, 0 );
|
||||
|
||||
if( !(uFlags & SWP_EX_NOCOPY) ) /* make sure dst region covers only valid bits */
|
||||
my = CombineRgn( dirtyRgn, newVisRgn, *pVisRgn, RGN_AND );
|
||||
|
||||
if( (my == NULLREGION) || (uFlags & SWP_EX_NOCOPY) )
|
||||
{
|
||||
nocopy:
|
||||
|
||||
TRACE("\twon't copy anything!\n");
|
||||
|
||||
/* set dirtyRgn to the sum of old and new visible regions
|
||||
* in parent client coordinates */
|
||||
|
||||
OffsetRgn( newVisRgn, Wnd->rectWindow.left, Wnd->rectWindow.top );
|
||||
OffsetRgn( *pVisRgn, lpOldWndRect->left, lpOldWndRect->top );
|
||||
|
||||
CombineRgn(*pVisRgn, *pVisRgn, newVisRgn, RGN_OR );
|
||||
}
|
||||
else /* copy valid bits to a new location */
|
||||
{
|
||||
INT dx, dy, ow, oh, nw, nh, ocw, ncw, och, nch;
|
||||
HRGN hrgnValid = dirtyRgn; /* non-empty intersection of old and new visible rgns */
|
||||
|
||||
/* subtract already invalid region inside Wnd from the dst region */
|
||||
|
||||
if( Wnd->hrgnUpdate )
|
||||
if( CombineRgn( hrgnValid, hrgnValid, Wnd->hrgnUpdate, RGN_DIFF) == NULLREGION )
|
||||
goto nocopy;
|
||||
|
||||
/* check if entire window can be copied */
|
||||
|
||||
ow = lpOldWndRect->right - lpOldWndRect->left;
|
||||
oh = lpOldWndRect->bottom - lpOldWndRect->top;
|
||||
nw = Wnd->rectWindow.right - Wnd->rectWindow.left;
|
||||
nh = Wnd->rectWindow.bottom - Wnd->rectWindow.top;
|
||||
|
||||
ocw = lpOldClientRect->right - lpOldClientRect->left;
|
||||
och = lpOldClientRect->bottom - lpOldClientRect->top;
|
||||
ncw = Wnd->rectClient.right - Wnd->rectClient.left;
|
||||
nch = Wnd->rectClient.bottom - Wnd->rectClient.top;
|
||||
|
||||
if( (ocw != ncw) || (och != nch) ||
|
||||
( ow != nw) || ( oh != nh) ||
|
||||
((lpOldClientRect->top - lpOldWndRect->top) !=
|
||||
(Wnd->rectClient.top - Wnd->rectWindow.top)) ||
|
||||
((lpOldClientRect->left - lpOldWndRect->left) !=
|
||||
(Wnd->rectClient.left - Wnd->rectWindow.left)) )
|
||||
{
|
||||
if(uFlags & SWP_EX_PAINTSELF)
|
||||
{
|
||||
/* movement relative to the window itself */
|
||||
dx = (Wnd->rectClient.left - Wnd->rectWindow.left) -
|
||||
(lpOldClientRect->left - lpOldWndRect->left) ;
|
||||
dy = (Wnd->rectClient.top - Wnd->rectWindow.top) -
|
||||
(lpOldClientRect->top - lpOldWndRect->top) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* movement relative to the parent's client area */
|
||||
dx = Wnd->rectClient.left - lpOldClientRect->left;
|
||||
dy = Wnd->rectClient.top - lpOldClientRect->top;
|
||||
}
|
||||
|
||||
/* restrict valid bits to the common client rect */
|
||||
|
||||
r.left = Wnd->rectClient.left - Wnd->rectWindow.left;
|
||||
r.top = Wnd->rectClient.top - Wnd->rectWindow.top;
|
||||
r.right = r.left + min( ocw, ncw );
|
||||
r.bottom = r.top + min( och, nch );
|
||||
|
||||
REGION_CropRgn( hrgnValid, hrgnValid, &r,
|
||||
(uFlags & SWP_EX_PAINTSELF) ? NULL : (POINT*)&(Wnd->rectWindow));
|
||||
GetRgnBox( hrgnValid, &r );
|
||||
if( IsRectEmpty( &r ) )
|
||||
goto nocopy;
|
||||
r = *lpOldClientRect;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(uFlags & SWP_EX_PAINTSELF) {
|
||||
/*
|
||||
* with SWP_EX_PAINTSELF, the window repaints itself. Since a window can't move
|
||||
* relative to itself, only the client area can change.
|
||||
* if the client rect didn't change, there's nothing to do.
|
||||
*/
|
||||
dx = 0;
|
||||
dy = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dx = Wnd->rectWindow.left - lpOldWndRect->left;
|
||||
dy = Wnd->rectWindow.top - lpOldWndRect->top;
|
||||
OffsetRgn( hrgnValid, Wnd->rectWindow.left, Wnd->rectWindow.top );
|
||||
}
|
||||
r = *lpOldWndRect;
|
||||
}
|
||||
|
||||
if( !(uFlags & SWP_EX_PAINTSELF) )
|
||||
{
|
||||
/* Move remaining regions to parent coordinates */
|
||||
OffsetRgn( newVisRgn, Wnd->rectWindow.left, Wnd->rectWindow.top );
|
||||
OffsetRgn( *pVisRgn, lpOldWndRect->left, lpOldWndRect->top );
|
||||
}
|
||||
else
|
||||
OffsetRect( &r, -lpOldWndRect->left, -lpOldWndRect->top );
|
||||
|
||||
TRACE("\tcomputing dirty region!\n");
|
||||
|
||||
/* Compute combined dirty region (old + new - valid) */
|
||||
CombineRgn( *pVisRgn, *pVisRgn, newVisRgn, RGN_OR);
|
||||
CombineRgn( *pVisRgn, *pVisRgn, hrgnValid, RGN_DIFF);
|
||||
|
||||
/* Blt valid bits, r is the rect to copy */
|
||||
|
||||
if( dx || dy )
|
||||
{
|
||||
RECT rClip;
|
||||
HDC hDC;
|
||||
|
||||
/* get DC and clip rect with drawable rect to avoid superfluous expose events
|
||||
from copying clipped areas */
|
||||
|
||||
if( uFlags & SWP_EX_PAINTSELF )
|
||||
{
|
||||
hDC = GetDCEx( Wnd->hwndSelf, hrgnValid, DCX_WINDOW | DCX_CACHE |
|
||||
DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CLIPSIBLINGS );
|
||||
rClip.right = nw; rClip.bottom = nh;
|
||||
}
|
||||
else
|
||||
{
|
||||
hDC = GetDCEx( Wnd->parent->hwndSelf, hrgnValid, DCX_CACHE |
|
||||
DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CLIPSIBLINGS );
|
||||
rClip.right = Wnd->parent->rectClient.right - Wnd->parent->rectClient.left;
|
||||
rClip.bottom = Wnd->parent->rectClient.bottom - Wnd->parent->rectClient.top;
|
||||
}
|
||||
rClip.left = rClip.top = 0;
|
||||
|
||||
if( oh > nh ) r.bottom = r.top + nh;
|
||||
if( ow < nw ) r.right = r.left + nw;
|
||||
|
||||
if( IntersectRect( &r, &r, &rClip ) )
|
||||
{
|
||||
Wnd->pDriver->pSurfaceCopy( Wnd->parent, hDC, dx, dy, &r, TRUE );
|
||||
|
||||
/* When you copy the bits without repainting, parent doesn't
|
||||
get validated appropriately. Therefore, we have to validate
|
||||
the parent with the windows' updated region when the
|
||||
parent's update region is not empty. */
|
||||
|
||||
if (Wnd->parent->hrgnUpdate != 0 && !(Wnd->parent->dwStyle & WS_CLIPCHILDREN))
|
||||
{
|
||||
OffsetRect(&r, dx, dy);
|
||||
ValidateRect(Wnd->parent->hwndSelf, &r);
|
||||
}
|
||||
}
|
||||
ReleaseDC( (uFlags & SWP_EX_PAINTSELF) ?
|
||||
Wnd->hwndSelf : Wnd->parent->hwndSelf, hDC);
|
||||
}
|
||||
}
|
||||
|
||||
/* *pVisRgn now points to the invalidated region */
|
||||
|
||||
DeleteObject(newVisRgn);
|
||||
DeleteObject(dirtyRgn);
|
||||
return uFlags;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SWP_DoSimpleFrameChanged
|
||||
*
|
||||
* NOTE: old and new client rect origins are identical, only
|
||||
* extents may have changed. Window extents are the same.
|
||||
*/
|
||||
static void SWP_DoSimpleFrameChanged( WND* wndPtr, RECT* pOldClientRect, WORD swpFlags, UINT uFlags )
|
||||
{
|
||||
INT i = 0;
|
||||
RECT rect;
|
||||
HRGN hrgn = 0;
|
||||
|
||||
if( !(swpFlags & SWP_NOCLIENTSIZE) )
|
||||
{
|
||||
/* Client rect changed its position/size, most likely a scrollar
|
||||
* was added/removed.
|
||||
*
|
||||
* FIXME: WVR alignment flags
|
||||
*/
|
||||
|
||||
if( wndPtr->rectClient.right > pOldClientRect->right ) /* right edge */
|
||||
{
|
||||
i++;
|
||||
rect.top = 0;
|
||||
rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
|
||||
rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left;
|
||||
if(!(uFlags & SWP_EX_NOCOPY))
|
||||
rect.left = pOldClientRect->right - wndPtr->rectClient.left;
|
||||
else
|
||||
{
|
||||
rect.left = 0;
|
||||
goto redraw;
|
||||
}
|
||||
}
|
||||
|
||||
if( wndPtr->rectClient.bottom > pOldClientRect->bottom ) /* bottom edge */
|
||||
{
|
||||
if( i )
|
||||
hrgn = CreateRectRgnIndirect( &rect );
|
||||
rect.left = 0;
|
||||
rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left;
|
||||
rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
|
||||
if(!(uFlags & SWP_EX_NOCOPY))
|
||||
rect.top = pOldClientRect->bottom - wndPtr->rectClient.top;
|
||||
else
|
||||
rect.top = 0;
|
||||
if( i++ )
|
||||
REGION_UnionRectWithRgn( hrgn, &rect );
|
||||
}
|
||||
|
||||
if( i == 0 && (uFlags & SWP_EX_NOCOPY) ) /* force redraw anyway */
|
||||
{
|
||||
rect = wndPtr->rectWindow;
|
||||
OffsetRect( &rect, wndPtr->rectWindow.left - wndPtr->rectClient.left,
|
||||
wndPtr->rectWindow.top - wndPtr->rectClient.top );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if( i )
|
||||
{
|
||||
redraw:
|
||||
PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, hrgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
|
||||
RDW_ERASENOW | RDW_ALLCHILDREN, RDW_EX_TOPFRAME | RDW_EX_USEHRGN );
|
||||
}
|
||||
else
|
||||
{
|
||||
WIN_UpdateNCRgn(wndPtr, 0, UNC_UPDATE | UNC_ENTIRE);
|
||||
}
|
||||
|
||||
if( hrgn > 1 )
|
||||
DeleteObject( hrgn );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SWP_DoWinPosChanging
|
||||
*/
|
||||
static BOOL SWP_DoWinPosChanging( WND* wndPtr, WINDOWPOS* pWinpos,
|
||||
RECT* pNewWindowRect, RECT* pNewClientRect )
|
||||
{
|
||||
/* Send WM_WINDOWPOSCHANGING message */
|
||||
|
||||
if (!(pWinpos->flags & SWP_NOSENDCHANGING))
|
||||
SendMessageA( wndPtr->hwndSelf, WM_WINDOWPOSCHANGING, 0, (LPARAM)pWinpos );
|
||||
|
||||
/* Calculate new position and size */
|
||||
|
||||
*pNewWindowRect = wndPtr->rectWindow;
|
||||
*pNewClientRect = (wndPtr->dwStyle & WS_MINIMIZE) ? wndPtr->rectWindow
|
||||
: wndPtr->rectClient;
|
||||
|
||||
if (!(pWinpos->flags & SWP_NOSIZE))
|
||||
{
|
||||
pNewWindowRect->right = pNewWindowRect->left + pWinpos->cx;
|
||||
pNewWindowRect->bottom = pNewWindowRect->top + pWinpos->cy;
|
||||
}
|
||||
if (!(pWinpos->flags & SWP_NOMOVE))
|
||||
{
|
||||
pNewWindowRect->left = pWinpos->x;
|
||||
pNewWindowRect->top = pWinpos->y;
|
||||
pNewWindowRect->right += pWinpos->x - wndPtr->rectWindow.left;
|
||||
pNewWindowRect->bottom += pWinpos->y - wndPtr->rectWindow.top;
|
||||
|
||||
OffsetRect( pNewClientRect, pWinpos->x - wndPtr->rectWindow.left,
|
||||
pWinpos->y - wndPtr->rectWindow.top );
|
||||
}
|
||||
|
||||
pWinpos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SWP_DoNCCalcSize
|
||||
*/
|
||||
static UINT SWP_DoNCCalcSize( WND* wndPtr, WINDOWPOS* pWinpos,
|
||||
RECT* pNewWindowRect, RECT* pNewClientRect, WORD f)
|
||||
{
|
||||
UINT wvrFlags = 0;
|
||||
|
||||
/* Send WM_NCCALCSIZE message to get new client area */
|
||||
if( (pWinpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
|
||||
{
|
||||
wvrFlags = WINPOS_SendNCCalcSize( pWinpos->hwnd, TRUE, pNewWindowRect,
|
||||
&wndPtr->rectWindow, &wndPtr->rectClient,
|
||||
pWinpos, pNewClientRect );
|
||||
|
||||
/* FIXME: WVR_ALIGNxxx */
|
||||
|
||||
if( pNewClientRect->left != wndPtr->rectClient.left ||
|
||||
pNewClientRect->top != wndPtr->rectClient.top )
|
||||
pWinpos->flags &= ~SWP_NOCLIENTMOVE;
|
||||
|
||||
if( (pNewClientRect->right - pNewClientRect->left !=
|
||||
wndPtr->rectClient.right - wndPtr->rectClient.left) ||
|
||||
(pNewClientRect->bottom - pNewClientRect->top !=
|
||||
wndPtr->rectClient.bottom - wndPtr->rectClient.top) )
|
||||
pWinpos->flags &= ~SWP_NOCLIENTSIZE;
|
||||
}
|
||||
else
|
||||
if( !(f & SWP_NOMOVE) && (pNewClientRect->left != wndPtr->rectClient.left ||
|
||||
pNewClientRect->top != wndPtr->rectClient.top) )
|
||||
pWinpos->flags &= ~SWP_NOCLIENTMOVE;
|
||||
return wvrFlags;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetWindowPos (USER.232)
|
||||
*/
|
||||
|
@ -2596,104 +2164,7 @@ BOOL16 WINAPI SetWindowPos16( HWND16 hwnd, HWND16 hwndInsertAfter,
|
|||
BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter,
|
||||
INT x, INT y, INT cx, INT cy, UINT flags )
|
||||
{
|
||||
WINDOWPOS winpos;
|
||||
WND * wndPtr,*wndTemp;
|
||||
RECT newWindowRect, newClientRect;
|
||||
RECT oldWindowRect, oldClientRect;
|
||||
HRGN visRgn = 0;
|
||||
UINT wvrFlags = 0, uFlags = 0;
|
||||
BOOL retvalue, resync = FALSE, bChangePos;
|
||||
HWND hwndActive = 0;
|
||||
|
||||
/* Get current active window from the active queue */
|
||||
if ( hActiveQueue )
|
||||
{
|
||||
MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
|
||||
if ( pActiveQueue )
|
||||
{
|
||||
hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
|
||||
QUEUE_Unlock( pActiveQueue );
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("hwnd %04x, swp (%i,%i)-(%i,%i) flags %08x\n",
|
||||
hwnd, x, y, x+cx, y+cy, flags);
|
||||
|
||||
bChangePos = !(flags & SWP_WINE_NOHOSTMOVE);
|
||||
flags &= ~SWP_WINE_NOHOSTMOVE;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ CHECKS */
|
||||
|
||||
/* Check window handle */
|
||||
|
||||
if (hwnd == GetDesktopWindow()) return FALSE;
|
||||
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
|
||||
|
||||
TRACE("\tcurrent (%i,%i)-(%i,%i), style %08x\n", wndPtr->rectWindow.left, wndPtr->rectWindow.top,
|
||||
wndPtr->rectWindow.right, wndPtr->rectWindow.bottom, (unsigned)wndPtr->dwStyle );
|
||||
|
||||
/* Fix redundant flags */
|
||||
|
||||
if(wndPtr->dwStyle & WS_VISIBLE)
|
||||
flags &= ~SWP_SHOWWINDOW;
|
||||
else
|
||||
{
|
||||
if (!(flags & SWP_SHOWWINDOW))
|
||||
flags |= SWP_NOREDRAW;
|
||||
flags &= ~SWP_HIDEWINDOW;
|
||||
}
|
||||
|
||||
if ( cx < 0 ) cx = 0; if( cy < 0 ) cy = 0;
|
||||
|
||||
if ((wndPtr->rectWindow.right - wndPtr->rectWindow.left == cx) &&
|
||||
(wndPtr->rectWindow.bottom - wndPtr->rectWindow.top == cy))
|
||||
flags |= SWP_NOSIZE; /* Already the right size */
|
||||
|
||||
if ((wndPtr->rectWindow.left == x) && (wndPtr->rectWindow.top == y))
|
||||
flags |= SWP_NOMOVE; /* Already the right position */
|
||||
|
||||
if (hwnd == hwndActive)
|
||||
flags |= SWP_NOACTIVATE; /* Already active */
|
||||
else if ( (wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD )
|
||||
{
|
||||
if(!(flags & SWP_NOACTIVATE)) /* Bring to the top when activating */
|
||||
{
|
||||
flags &= ~SWP_NOZORDER;
|
||||
hwndInsertAfter = HWND_TOP;
|
||||
goto Pos;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check hwndInsertAfter */
|
||||
|
||||
/* FIXME: TOPMOST not supported yet */
|
||||
if ((hwndInsertAfter == HWND_TOPMOST) ||
|
||||
(hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP;
|
||||
|
||||
/* hwndInsertAfter must be a sibling of the window */
|
||||
if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
|
||||
{
|
||||
WND* wnd = WIN_FindWndPtr(hwndInsertAfter);
|
||||
|
||||
if( wnd ) {
|
||||
if( wnd->parent != wndPtr->parent )
|
||||
{
|
||||
retvalue = FALSE;
|
||||
WIN_ReleaseWndPtr(wnd);
|
||||
goto END;
|
||||
}
|
||||
/* don't need to change the Zorder of hwnd if it's already inserted
|
||||
* after hwndInsertAfter or when inserting hwnd after itself.
|
||||
*/
|
||||
if(( wnd->next == wndPtr ) || (hwnd == hwndInsertAfter)) flags |= SWP_NOZORDER;
|
||||
}
|
||||
WIN_ReleaseWndPtr(wnd);
|
||||
}
|
||||
|
||||
Pos: /* ------------------------------------------------------------------------ MAIN part */
|
||||
|
||||
/* Fill the WINDOWPOS structure */
|
||||
WINDOWPOS winpos;
|
||||
|
||||
winpos.hwnd = hwnd;
|
||||
winpos.hwndInsertAfter = hwndInsertAfter;
|
||||
|
@ -2702,311 +2173,10 @@ Pos: /* -----------------------------------------------------------------------
|
|||
winpos.cx = cx;
|
||||
winpos.cy = cy;
|
||||
winpos.flags = flags;
|
||||
|
||||
SWP_DoWinPosChanging( wndPtr, &winpos, &newWindowRect, &newClientRect );
|
||||
|
||||
if((winpos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER)
|
||||
{
|
||||
if( wndPtr->parent == WIN_GetDesktop() )
|
||||
hwndInsertAfter = SWP_DoOwnedPopups( wndPtr->parent, wndPtr,
|
||||
hwndInsertAfter, winpos.flags );
|
||||
WIN_ReleaseDesktop();
|
||||
}
|
||||
|
||||
if(!(wndPtr->flags & WIN_NATIVE) )
|
||||
{
|
||||
if( hwndInsertAfter == HWND_TOP )
|
||||
winpos.flags |= ( wndPtr->parent->child == wndPtr)? SWP_NOZORDER: 0;
|
||||
else
|
||||
if( hwndInsertAfter == HWND_BOTTOM )
|
||||
winpos.flags |= ( wndPtr->next )? 0: SWP_NOZORDER;
|
||||
else
|
||||
if( !(winpos.flags & SWP_NOZORDER) )
|
||||
if( GetWindow(hwndInsertAfter, GW_HWNDNEXT) == wndPtr->hwndSelf )
|
||||
winpos.flags |= SWP_NOZORDER;
|
||||
|
||||
if( !(winpos.flags & (SWP_NOREDRAW | SWP_SHOWWINDOW)) &&
|
||||
((winpos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_HIDEWINDOW | SWP_FRAMECHANGED))
|
||||
!= (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER)) )
|
||||
{
|
||||
/* get a previous visible region for SWP_CopyValidBits() */
|
||||
DWORD dflags = DCX_WINDOW;
|
||||
|
||||
if (wndPtr->dwStyle & WS_CLIPSIBLINGS)
|
||||
dflags |= DCX_CLIPSIBLINGS;
|
||||
|
||||
visRgn = DCE_GetVisRgn(hwnd, dflags, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Common operations */
|
||||
|
||||
wvrFlags = SWP_DoNCCalcSize( wndPtr, &winpos, &newWindowRect, &newClientRect, flags );
|
||||
|
||||
if(!(winpos.flags & SWP_NOZORDER) && winpos.hwnd != hwndInsertAfter)
|
||||
{
|
||||
if ( WIN_UnlinkWindow( winpos.hwnd ) )
|
||||
WIN_LinkWindow( winpos.hwnd, hwndInsertAfter );
|
||||
}
|
||||
|
||||
/* Reset active DCEs */
|
||||
|
||||
if( (((winpos.flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) &&
|
||||
wndPtr->dwStyle & WS_VISIBLE) ||
|
||||
(flags & (SWP_HIDEWINDOW | SWP_SHOWWINDOW)) )
|
||||
{
|
||||
RECT rect;
|
||||
|
||||
UnionRect(&rect, &newWindowRect, &wndPtr->rectWindow);
|
||||
DCE_InvalidateDCE(wndPtr, &rect);
|
||||
}
|
||||
|
||||
oldWindowRect = wndPtr->rectWindow;
|
||||
oldClientRect = wndPtr->rectClient;
|
||||
|
||||
/* Find out if we have to redraw the whole client rect */
|
||||
|
||||
if( oldClientRect.bottom - oldClientRect.top ==
|
||||
newClientRect.bottom - newClientRect.top ) wvrFlags &= ~WVR_VREDRAW;
|
||||
|
||||
if( oldClientRect.right - oldClientRect.left ==
|
||||
newClientRect.right - newClientRect.left ) wvrFlags &= ~WVR_HREDRAW;
|
||||
|
||||
if( (winpos.flags & SWP_NOCOPYBITS) || (!(winpos.flags & SWP_NOCLIENTSIZE) &&
|
||||
(wvrFlags >= WVR_HREDRAW) && (wvrFlags < WVR_VALIDRECTS)) )
|
||||
{
|
||||
uFlags |= SWP_EX_NOCOPY;
|
||||
}
|
||||
/*
|
||||
* Use this later in CopyValidBits()
|
||||
*
|
||||
else if( 0 )
|
||||
uFlags |= SWP_EX_NONCLIENT;
|
||||
*/
|
||||
|
||||
/* FIXME: actually do something with WVR_VALIDRECTS */
|
||||
|
||||
wndPtr->rectWindow = newWindowRect;
|
||||
wndPtr->rectClient = newClientRect;
|
||||
|
||||
if (wndPtr->flags & WIN_NATIVE) /* -------------------------------------------- hosted window */
|
||||
{
|
||||
BOOL bCallDriver = TRUE;
|
||||
HWND tempInsertAfter = winpos.hwndInsertAfter;
|
||||
|
||||
winpos.hwndInsertAfter = hwndInsertAfter;
|
||||
|
||||
if( !(winpos.flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOREDRAW)) )
|
||||
{
|
||||
/* This is the only place where we need to force repainting of the contents
|
||||
of windows created by the host window system, all other cases go through the
|
||||
expose event handling */
|
||||
|
||||
if( (winpos.flags & (SWP_NOSIZE | SWP_FRAMECHANGED)) == (SWP_NOSIZE | SWP_FRAMECHANGED) )
|
||||
{
|
||||
cx = newWindowRect.right - newWindowRect.left;
|
||||
cy = newWindowRect.bottom - newWindowRect.top;
|
||||
|
||||
wndPtr->pDriver->pSetWindowPos(wndPtr, &winpos, bChangePos);
|
||||
winpos.hwndInsertAfter = tempInsertAfter;
|
||||
bCallDriver = FALSE;
|
||||
|
||||
if( winpos.flags & SWP_NOCLIENTMOVE )
|
||||
SWP_DoSimpleFrameChanged(wndPtr, &oldClientRect, winpos.flags, uFlags );
|
||||
else
|
||||
{
|
||||
/* client area moved but window extents remained the same, copy valid bits */
|
||||
|
||||
visRgn = CreateRectRgn( 0, 0, cx, cy );
|
||||
uFlags = SWP_CopyValidBits( wndPtr, &visRgn, &oldWindowRect, &oldClientRect,
|
||||
uFlags | SWP_EX_PAINTSELF );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( bCallDriver )
|
||||
{
|
||||
if( !(winpos.flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOREDRAW)) )
|
||||
{
|
||||
if( (oldClientRect.left - oldWindowRect.left == newClientRect.left - newWindowRect.left) &&
|
||||
(oldClientRect.top - oldWindowRect.top == newClientRect.top - newWindowRect.top) &&
|
||||
!(uFlags & SWP_EX_NOCOPY) )
|
||||
{
|
||||
/* The origin of the client rect didn't move so we can try to repaint
|
||||
* only the nonclient area by setting bit gravity hint for the host window system.
|
||||
*/
|
||||
|
||||
if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
|
||||
{
|
||||
HRGN hrgn = CreateRectRgn( 0, 0, newWindowRect.right - newWindowRect.left,
|
||||
newWindowRect.bottom - newWindowRect.top);
|
||||
RECT rcn = newClientRect;
|
||||
RECT rco = oldClientRect;
|
||||
|
||||
OffsetRect( &rcn, -newWindowRect.left, -newWindowRect.top );
|
||||
OffsetRect( &rco, -oldWindowRect.left, -oldWindowRect.top );
|
||||
IntersectRect( &rcn, &rcn, &rco );
|
||||
visRgn = CreateRectRgnIndirect( &rcn );
|
||||
CombineRgn( visRgn, hrgn, visRgn, RGN_DIFF );
|
||||
DeleteObject( hrgn );
|
||||
uFlags = SWP_EX_PAINTSELF;
|
||||
}
|
||||
wndPtr->pDriver->pSetHostAttr(wndPtr, HAK_BITGRAVITY, BGNorthWest );
|
||||
}
|
||||
}
|
||||
|
||||
wndPtr->pDriver->pSetWindowPos(wndPtr, &winpos, bChangePos);
|
||||
wndPtr->pDriver->pSetHostAttr(wndPtr, HAK_BITGRAVITY, BGForget );
|
||||
winpos.hwndInsertAfter = tempInsertAfter;
|
||||
}
|
||||
|
||||
if( winpos.flags & SWP_SHOWWINDOW )
|
||||
{
|
||||
HWND focus, curr;
|
||||
|
||||
wndPtr->dwStyle |= WS_VISIBLE;
|
||||
|
||||
if (wndPtr->dwExStyle & WS_EX_MANAGED) resync = TRUE;
|
||||
|
||||
/* focus was set to unmapped window, reset host focus
|
||||
* since the window is now visible */
|
||||
|
||||
focus = curr = GetFocus();
|
||||
while (curr)
|
||||
{
|
||||
if (curr == hwnd)
|
||||
{
|
||||
WND *pFocus = WIN_FindWndPtr( focus );
|
||||
if (pFocus)
|
||||
pFocus->pDriver->pSetFocus(pFocus);
|
||||
WIN_ReleaseWndPtr(pFocus);
|
||||
break;
|
||||
}
|
||||
curr = GetParent(curr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* -------------------------------------------- emulated window */
|
||||
{
|
||||
if( winpos.flags & SWP_SHOWWINDOW )
|
||||
{
|
||||
wndPtr->dwStyle |= WS_VISIBLE;
|
||||
uFlags |= SWP_EX_PAINTSELF;
|
||||
visRgn = 1; /* redraw the whole window */
|
||||
}
|
||||
else if( !(winpos.flags & SWP_NOREDRAW) )
|
||||
{
|
||||
if( winpos.flags & SWP_HIDEWINDOW )
|
||||
{
|
||||
if( visRgn > 1 ) /* map to parent */
|
||||
OffsetRgn( visRgn, oldWindowRect.left, oldWindowRect.top );
|
||||
else
|
||||
visRgn = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (winpos.flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE )
|
||||
uFlags = SWP_CopyValidBits(wndPtr, &visRgn, &oldWindowRect,
|
||||
&oldClientRect, uFlags);
|
||||
else
|
||||
{
|
||||
/* nothing moved, redraw frame if needed */
|
||||
|
||||
if( winpos.flags & SWP_FRAMECHANGED )
|
||||
SWP_DoSimpleFrameChanged( wndPtr, &oldClientRect, winpos.flags, uFlags );
|
||||
if( visRgn )
|
||||
{
|
||||
DeleteObject( visRgn );
|
||||
visRgn = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( winpos.flags & SWP_HIDEWINDOW )
|
||||
{
|
||||
wndPtr->dwStyle &= ~WS_VISIBLE;
|
||||
}
|
||||
|
||||
if (hwnd == CARET_GetHwnd())
|
||||
{
|
||||
if( winpos.flags & SWP_HIDEWINDOW )
|
||||
HideCaret(hwnd);
|
||||
else if (winpos.flags & SWP_SHOWWINDOW)
|
||||
ShowCaret(hwnd);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ FINAL */
|
||||
|
||||
if (wndPtr->flags & WIN_NATIVE)
|
||||
EVENT_Synchronize(); /* Synchronize with the host window system */
|
||||
|
||||
wndTemp = WIN_GetDesktop();
|
||||
|
||||
/* repaint invalidated region (if any)
|
||||
*
|
||||
* FIXME: if SWP_NOACTIVATE is not set then set invalid regions here without any painting
|
||||
* and force update after ChangeActiveWindow() to avoid painting frames twice.
|
||||
*/
|
||||
|
||||
if( visRgn )
|
||||
{
|
||||
if( !(winpos.flags & SWP_NOREDRAW) )
|
||||
{
|
||||
|
||||
/* Use PAINT_RedrawWindow to explicitly force an invalidation of the window,
|
||||
its parent and sibling and so on, and then erase the parent window
|
||||
background if the parent is either a top-level window or its parent's parent
|
||||
is top-level window. Rely on the system to repaint other affected
|
||||
windows later on. */
|
||||
if( uFlags & SWP_EX_PAINTSELF )
|
||||
{
|
||||
PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, (visRgn == 1) ? 0 : visRgn,
|
||||
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN,
|
||||
RDW_EX_XYWINDOW | RDW_EX_USEHRGN );
|
||||
}
|
||||
else
|
||||
{
|
||||
PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, (visRgn == 1) ? 0 : visRgn,
|
||||
RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN,
|
||||
RDW_EX_USEHRGN );
|
||||
}
|
||||
|
||||
if(wndPtr -> parent == wndTemp || wndPtr->parent->parent == wndTemp )
|
||||
{
|
||||
PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0,
|
||||
RDW_ERASENOW | RDW_NOCHILDREN, 0 );
|
||||
}
|
||||
}
|
||||
if( visRgn != 1 )
|
||||
DeleteObject( visRgn );
|
||||
}
|
||||
|
||||
WIN_ReleaseDesktop();
|
||||
|
||||
if (!(flags & SWP_NOACTIVATE))
|
||||
WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE );
|
||||
|
||||
/* And last, send the WM_WINDOWPOSCHANGED message */
|
||||
|
||||
TRACE("\tstatus flags = %04x\n", winpos.flags & SWP_AGG_STATUSFLAGS);
|
||||
|
||||
if ( resync ||
|
||||
(((winpos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) &&
|
||||
!(winpos.flags & SWP_NOSENDCHANGING)) )
|
||||
{
|
||||
SendMessageA( winpos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos );
|
||||
if (resync) EVENT_Synchronize();
|
||||
}
|
||||
|
||||
retvalue = TRUE;
|
||||
END:
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
return retvalue;
|
||||
return USER_Driver.pSetWindowPos( &winpos );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* BeginDeferWindowPos (USER.259)
|
||||
*/
|
||||
|
@ -3173,9 +2343,7 @@ BOOL WINAPI EndDeferWindowPos( HDWP hdwp )
|
|||
if (!pDWP) return FALSE;
|
||||
for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++)
|
||||
{
|
||||
if (!(res = SetWindowPos( winpos->hwnd, winpos->hwndInsertAfter,
|
||||
winpos->x, winpos->y, winpos->cx,
|
||||
winpos->cy, winpos->flags ))) break;
|
||||
if (!(res = USER_Driver.pSetWindowPos( winpos ))) break;
|
||||
}
|
||||
USER_HEAP_FREE( hdwp );
|
||||
return res;
|
||||
|
|
|
@ -93,7 +93,7 @@ static const char * const event_names[] =
|
|||
static void CALLBACK EVENT_Flush( ULONG_PTR arg );
|
||||
static void CALLBACK EVENT_ProcessAllEvents( ULONG_PTR arg );
|
||||
static void EVENT_ProcessEvent( XEvent *event );
|
||||
BOOL X11DRV_CheckFocus(void);
|
||||
static BOOL X11DRV_CheckFocus(void);
|
||||
|
||||
/* Event handlers */
|
||||
static void EVENT_Key( HWND hWnd, XKeyEvent *event );
|
||||
|
@ -401,8 +401,8 @@ static void EVENT_ProcessEvent( XEvent *event )
|
|||
(win_attr.map_state == IsViewable) )
|
||||
{
|
||||
TSXSetInputFocus( xfocChange->display, glastXFocusWin, RevertToParent, CurrentTime );
|
||||
EVENT_Synchronize();
|
||||
break;
|
||||
X11DRV_Synchronize();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -877,7 +877,7 @@ static void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event )
|
|||
/**********************************************************************
|
||||
* CheckFocus (X11DRV.@)
|
||||
*/
|
||||
BOOL X11DRV_CheckFocus(void)
|
||||
static BOOL X11DRV_CheckFocus(void)
|
||||
{
|
||||
HWND hWnd;
|
||||
Window xW;
|
||||
|
@ -1850,7 +1850,7 @@ void EVENT_MapNotify( HWND hWnd, XMapEvent *event )
|
|||
WIN_ReleaseWndPtr(pWnd);
|
||||
|
||||
if (hwndFocus && IsChild( hWnd, hwndFocus ))
|
||||
X11DRV_WND_SetFocus(wndFocus);
|
||||
X11DRV_SetFocus(hwndFocus);
|
||||
|
||||
WIN_ReleaseWndPtr(wndFocus);
|
||||
|
||||
|
|
|
@ -1726,30 +1726,3 @@ BOOL X11DRV_GetDIData(
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetKeyboardConfig (X11DRV.@)
|
||||
*/
|
||||
void X11DRV_GetKeyboardConfig(KEYBOARD_CONFIG *cfg) {
|
||||
XKeyboardState xks;
|
||||
|
||||
/* For the moment, only get the auto-repeat mode */
|
||||
TSXGetKeyboardControl(display, &xks);
|
||||
cfg->auto_repeat = xks.global_auto_repeat;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetKeyboardConfig (X11DRV.@)
|
||||
*/
|
||||
void X11DRV_SetKeyboardConfig(KEYBOARD_CONFIG *cfg, DWORD mask) {
|
||||
XKeyboardControl xkc;
|
||||
unsigned long X_mask = 0;
|
||||
|
||||
if (mask & WINE_KEYBOARD_CONFIG_AUTO_REPEAT) {
|
||||
X_mask |= KBAutoRepeatMode;
|
||||
xkc.auto_repeat_mode = cfg->auto_repeat;
|
||||
}
|
||||
if (X_mask)
|
||||
TSXChangeKeyboardControl(display, X_mask, &xkc);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,53 +31,23 @@
|
|||
|
||||
DEFAULT_DEBUG_CHANNEL(win);
|
||||
|
||||
/* Some useful macros */
|
||||
extern Atom wmChangeState;
|
||||
|
||||
#define HAS_DLGFRAME(style,exStyle) \
|
||||
((!((style) & WS_THICKFRAME)) && (((style) & WS_DLGFRAME) || ((exStyle) & WS_EX_DLGMODALFRAME)))
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
extern Cursor X11DRV_MOUSE_XCursor; /* Current X cursor */
|
||||
extern BOOL X11DRV_CreateBitmap( HBITMAP );
|
||||
extern Pixmap X11DRV_BITMAP_Pixmap( HBITMAP );
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
WND_DRIVER X11DRV_WND_Driver =
|
||||
{
|
||||
X11DRV_WND_Initialize,
|
||||
X11DRV_WND_Finalize,
|
||||
X11DRV_WND_CreateDesktopWindow,
|
||||
X11DRV_WND_CreateWindow,
|
||||
X11DRV_WND_DestroyWindow,
|
||||
X11DRV_WND_SetParent,
|
||||
X11DRV_WND_ForceWindowRaise,
|
||||
X11DRV_WND_SetWindowPos,
|
||||
X11DRV_WND_SetText,
|
||||
X11DRV_WND_SetFocus,
|
||||
X11DRV_WND_PreSizeMove,
|
||||
X11DRV_WND_PostSizeMove,
|
||||
X11DRV_WND_SurfaceCopy,
|
||||
X11DRV_WND_SetDrawable,
|
||||
X11DRV_WND_SetHostAttr,
|
||||
X11DRV_WND_IsSelfClipping,
|
||||
X11DRV_WND_SetWindowRgn
|
||||
X11DRV_WND_SetHostAttr
|
||||
};
|
||||
|
||||
|
||||
/* X context to associate a hwnd to an X window */
|
||||
XContext winContext = 0;
|
||||
|
||||
Atom wmProtocols = None;
|
||||
Atom wmDeleteWindow = None;
|
||||
Atom dndProtocol = None;
|
||||
Atom dndSelection = None;
|
||||
Atom wmChangeState = None;
|
||||
|
||||
Atom kwmDockWindow = None;
|
||||
Atom _net_kde_system_tray_window_for = None; /* KDE 2 Beta */
|
||||
Atom _kde_net_wm_system_tray_window_for = None; /* KDE 2 Final */
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_WND_GetXWindow
|
||||
*
|
||||
|
@ -103,20 +73,6 @@ Window X11DRV_WND_FindXWindow(WND *wndPtr)
|
|||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->window : 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_WND_RegisterWindow
|
||||
*
|
||||
* Associate an X window to a HWND.
|
||||
*/
|
||||
static void X11DRV_WND_RegisterWindow(WND *wndPtr)
|
||||
{
|
||||
TSXSetWMProtocols( display, X11DRV_WND_GetXWindow(wndPtr), &wmDeleteWindow, 1 );
|
||||
|
||||
if (!winContext) winContext = TSXUniqueContext();
|
||||
TSXSaveContext( display, X11DRV_WND_GetXWindow(wndPtr),
|
||||
winContext, (char *) wndPtr->hwndSelf );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_WND_IsZeroSizeWnd
|
||||
*
|
||||
|
@ -131,414 +87,6 @@ static BOOL X11DRV_WND_IsZeroSizeWnd(WND *wndPtr)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* X11DRV_WND_Initialize
|
||||
*/
|
||||
void X11DRV_WND_Initialize(WND *wndPtr)
|
||||
{
|
||||
X11DRV_WND_DATA *pWndDriverData = HeapAlloc(GetProcessHeap(), 0, sizeof(X11DRV_WND_DATA));
|
||||
|
||||
wndPtr->pDriverData = (void *) pWndDriverData;
|
||||
|
||||
pWndDriverData->window = 0;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* X11DRV_WND_Finalize
|
||||
*/
|
||||
void X11DRV_WND_Finalize(WND *wndPtr)
|
||||
{
|
||||
X11DRV_WND_DATA *pWndDriverData =
|
||||
(X11DRV_WND_DATA *) wndPtr->pDriverData;
|
||||
|
||||
if (!wndPtr->pDriverData) {
|
||||
ERR("Trying to destroy window again. Not good.\n");
|
||||
return;
|
||||
}
|
||||
if(pWndDriverData->window)
|
||||
{
|
||||
ERR(
|
||||
"WND destroyed without destroying "
|
||||
"the associated X Window (%ld)\n",
|
||||
pWndDriverData->window
|
||||
);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, wndPtr->pDriverData);
|
||||
wndPtr->pDriverData = NULL;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* X11DRV_WND_CreateDesktopWindow
|
||||
*/
|
||||
BOOL X11DRV_WND_CreateDesktopWindow(WND *wndPtr)
|
||||
{
|
||||
if (wmProtocols == None)
|
||||
wmProtocols = TSXInternAtom( display, "WM_PROTOCOLS", True );
|
||||
if (wmDeleteWindow == None)
|
||||
wmDeleteWindow = TSXInternAtom( display, "WM_DELETE_WINDOW", True );
|
||||
if( dndProtocol == None )
|
||||
dndProtocol = TSXInternAtom( display, "DndProtocol" , False );
|
||||
if( dndSelection == None )
|
||||
dndSelection = TSXInternAtom( display, "DndSelection" , False );
|
||||
if( wmChangeState == None )
|
||||
wmChangeState = TSXInternAtom (display, "WM_CHANGE_STATE", False);
|
||||
if (kwmDockWindow == None)
|
||||
kwmDockWindow = TSXInternAtom( display, "KWM_DOCKWINDOW", False );
|
||||
if (_kde_net_wm_system_tray_window_for == None)
|
||||
_kde_net_wm_system_tray_window_for = TSXInternAtom( display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False );
|
||||
if (_net_kde_system_tray_window_for == None)
|
||||
_net_kde_system_tray_window_for = TSXInternAtom( display, "_NET_KDE_SYSTEM_TRAY_WINDOW_FOR", False );
|
||||
|
||||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = X11DRV_GetXRootWindow();
|
||||
if (X11DRV_GetXRootWindow() != DefaultRootWindow(display)) wndPtr->flags |= WIN_NATIVE;
|
||||
X11DRV_WND_RegisterWindow( wndPtr );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* X11DRV_WND_IconChanged
|
||||
*
|
||||
* hIcon or hIconSm has changed (or is being initialised for the
|
||||
* first time). Complete the X11 driver-specific initialisation.
|
||||
*
|
||||
* This is not entirely correct, may need to create
|
||||
* an icon window and set the pixmap as a background
|
||||
*/
|
||||
static void X11DRV_WND_IconChanged(WND *wndPtr)
|
||||
{
|
||||
|
||||
HICON16 hIcon = NC_IconForWindow(wndPtr);
|
||||
|
||||
if( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap )
|
||||
DeleteObject( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap );
|
||||
|
||||
if( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconMask )
|
||||
DeleteObject( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconMask);
|
||||
|
||||
if (!hIcon)
|
||||
{
|
||||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap= 0;
|
||||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconMask= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
HBITMAP hbmOrig;
|
||||
RECT rcMask;
|
||||
BITMAP bmMask;
|
||||
ICONINFO ii;
|
||||
HDC hDC;
|
||||
|
||||
GetIconInfo(hIcon, &ii);
|
||||
|
||||
X11DRV_CreateBitmap(ii.hbmMask);
|
||||
X11DRV_CreateBitmap(ii.hbmColor);
|
||||
|
||||
GetObjectA(ii.hbmMask, sizeof(bmMask), &bmMask);
|
||||
rcMask.top = 0;
|
||||
rcMask.left = 0;
|
||||
rcMask.right = bmMask.bmWidth;
|
||||
rcMask.bottom = bmMask.bmHeight;
|
||||
|
||||
hDC = CreateCompatibleDC(0);
|
||||
hbmOrig = SelectObject(hDC, ii.hbmMask);
|
||||
InvertRect(hDC, &rcMask);
|
||||
SelectObject(hDC, hbmOrig);
|
||||
DeleteDC(hDC);
|
||||
|
||||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = ii.hbmColor;
|
||||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconMask= ii.hbmMask;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void X11DRV_WND_SetIconHints(WND *wndPtr, XWMHints *hints)
|
||||
{
|
||||
if (((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap)
|
||||
{
|
||||
hints->icon_pixmap
|
||||
= X11DRV_BITMAP_Pixmap(((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap);
|
||||
hints->flags |= IconPixmapHint;
|
||||
}
|
||||
else
|
||||
hints->flags &= ~IconPixmapHint;
|
||||
|
||||
if (((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconMask)
|
||||
{
|
||||
hints->icon_mask
|
||||
= X11DRV_BITMAP_Pixmap(((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconMask);
|
||||
hints->flags |= IconMaskHint;
|
||||
}
|
||||
else
|
||||
hints->flags &= ~IconMaskHint;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* X11DRV_WND_UpdateIconHints
|
||||
*
|
||||
* hIcon or hIconSm has changed (or is being initialised for the
|
||||
* first time). Complete the X11 driver-specific initialisation
|
||||
* and set the window hints.
|
||||
*
|
||||
* This is not entirely correct, may need to create
|
||||
* an icon window and set the pixmap as a background
|
||||
*/
|
||||
static void X11DRV_WND_UpdateIconHints(WND *wndPtr)
|
||||
{
|
||||
XWMHints* wm_hints;
|
||||
|
||||
X11DRV_WND_IconChanged(wndPtr);
|
||||
|
||||
wm_hints = TSXGetWMHints( display, X11DRV_WND_GetXWindow(wndPtr) );
|
||||
if (!wm_hints) wm_hints = TSXAllocWMHints();
|
||||
if (wm_hints)
|
||||
{
|
||||
X11DRV_WND_SetIconHints(wndPtr, wm_hints);
|
||||
TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
|
||||
TSXFree( wm_hints );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* X11DRV_WND_CreateWindow
|
||||
*/
|
||||
BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CREATESTRUCTA *cs, BOOL bUnicode)
|
||||
{
|
||||
/* Create the X window (only for top-level windows, and then only */
|
||||
/* when there's no desktop window) */
|
||||
|
||||
if ((X11DRV_GetXRootWindow() == DefaultRootWindow(display))
|
||||
&& (wndPtr->parent->hwndSelf == GetDesktopWindow()))
|
||||
{
|
||||
Window wGroupLeader;
|
||||
XWMHints* wm_hints;
|
||||
XSetWindowAttributes win_attr;
|
||||
|
||||
/* Create "managed" windows only if a title bar or resizable */
|
||||
/* frame is required. */
|
||||
if (WIN_WindowNeedsWMBorder(cs->style, cs->dwExStyle)) {
|
||||
win_attr.event_mask = ExposureMask | KeyPressMask |
|
||||
KeyReleaseMask | PointerMotionMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
FocusChangeMask | StructureNotifyMask;
|
||||
win_attr.override_redirect = FALSE;
|
||||
wndPtr->dwExStyle |= WS_EX_MANAGED;
|
||||
} else {
|
||||
win_attr.event_mask = ExposureMask | KeyPressMask |
|
||||
KeyReleaseMask | PointerMotionMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
FocusChangeMask;
|
||||
win_attr.override_redirect = TRUE;
|
||||
}
|
||||
wndPtr->flags |= WIN_NATIVE;
|
||||
|
||||
win_attr.bit_gravity = (wndPtr->clsStyle & (CS_VREDRAW | CS_HREDRAW)) ? BGForget : BGNorthWest;
|
||||
win_attr.colormap = X11DRV_PALETTE_PaletteXColormap;
|
||||
win_attr.backing_store = NotUseful;
|
||||
win_attr.save_under = ((wndPtr->clsStyle & CS_SAVEBITS) != 0);
|
||||
win_attr.cursor = X11DRV_MOUSE_XCursor;
|
||||
|
||||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = 0;
|
||||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconMask = 0;
|
||||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->bit_gravity = win_attr.bit_gravity;
|
||||
|
||||
/* Zero-size X11 window hack. X doesn't like them, and will crash */
|
||||
/* with a BadValue unless we do something ugly like this. */
|
||||
/* Zero size window won't be mapped */
|
||||
if (cs->cx <= 0) cs->cx = 1;
|
||||
if (cs->cy <= 0) cs->cy = 1;
|
||||
|
||||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->window =
|
||||
TSXCreateWindow( display, X11DRV_GetXRootWindow(),
|
||||
cs->x, cs->y, cs->cx, cs->cy,
|
||||
0, screen_depth,
|
||||
InputOutput, visual,
|
||||
CWEventMask | CWOverrideRedirect |
|
||||
CWColormap | CWCursor | CWSaveUnder |
|
||||
CWBackingStore | CWBitGravity,
|
||||
&win_attr );
|
||||
|
||||
if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr)))
|
||||
return FALSE;
|
||||
|
||||
/* If we are the systray, we need to be managed to be noticed by KWM */
|
||||
|
||||
if (wndPtr->dwExStyle & WS_EX_TRAYWINDOW)
|
||||
X11DRV_WND_DockWindow(wndPtr);
|
||||
|
||||
if (wndPtr->dwExStyle & WS_EX_MANAGED)
|
||||
{
|
||||
XClassHint *class_hints = TSXAllocClassHint();
|
||||
XSizeHints* size_hints = TSXAllocSizeHints();
|
||||
|
||||
if (class_hints)
|
||||
{
|
||||
class_hints->res_name = "wineManaged";
|
||||
class_hints->res_class = "Wine";
|
||||
TSXSetClassHint( display, ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window, class_hints );
|
||||
TSXFree (class_hints);
|
||||
}
|
||||
|
||||
if (size_hints)
|
||||
{
|
||||
size_hints->win_gravity = StaticGravity;
|
||||
size_hints->x = cs->x;
|
||||
size_hints->y = cs->y;
|
||||
size_hints->flags = PWinGravity|PPosition;
|
||||
|
||||
if (HAS_DLGFRAME(cs->style,cs->dwExStyle))
|
||||
{
|
||||
size_hints->min_width = size_hints->max_width = cs->cx;
|
||||
size_hints->min_height = size_hints->max_height = cs->cy;
|
||||
size_hints->flags |= PMinSize | PMaxSize;
|
||||
}
|
||||
|
||||
TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr),
|
||||
size_hints, XA_WM_NORMAL_HINTS );
|
||||
TSXFree(size_hints);
|
||||
}
|
||||
}
|
||||
|
||||
if (cs->hwndParent) /* Get window owner */
|
||||
{
|
||||
Window w;
|
||||
WND *tmpWnd = WIN_FindWndPtr(cs->hwndParent);
|
||||
|
||||
w = X11DRV_WND_FindXWindow( tmpWnd );
|
||||
if (w != None)
|
||||
{
|
||||
TSXSetTransientForHint( display, X11DRV_WND_GetXWindow(wndPtr), w );
|
||||
wGroupLeader = w;
|
||||
}
|
||||
WIN_ReleaseWndPtr(tmpWnd);
|
||||
}
|
||||
|
||||
if ((wm_hints = TSXAllocWMHints()))
|
||||
{
|
||||
wm_hints->flags = InputHint | StateHint | WindowGroupHint;
|
||||
wm_hints->input = True;
|
||||
|
||||
if (wndPtr->dwExStyle & WS_EX_MANAGED)
|
||||
{
|
||||
X11DRV_WND_IconChanged(wndPtr);
|
||||
X11DRV_WND_SetIconHints(wndPtr, wm_hints);
|
||||
|
||||
wm_hints->initial_state = (wndPtr->dwStyle & WS_MINIMIZE)
|
||||
? IconicState : NormalState;
|
||||
}
|
||||
else
|
||||
wm_hints->initial_state = NormalState;
|
||||
wm_hints->window_group = wGroupLeader;
|
||||
|
||||
TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
|
||||
TSXFree(wm_hints);
|
||||
}
|
||||
X11DRV_WND_RegisterWindow( wndPtr );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_WND_DestroyWindow
|
||||
*/
|
||||
BOOL X11DRV_WND_DestroyWindow(WND *wndPtr)
|
||||
{
|
||||
Window w;
|
||||
if ((w = X11DRV_WND_GetXWindow(wndPtr)))
|
||||
{
|
||||
XEvent xe;
|
||||
TSXDeleteContext( display, w, winContext );
|
||||
TSXDestroyWindow( display, w );
|
||||
while( TSXCheckWindowEvent(display, w, NoEventMask, &xe) );
|
||||
|
||||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None;
|
||||
if( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap )
|
||||
{
|
||||
DeleteObject( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap );
|
||||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = 0;
|
||||
}
|
||||
if( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconMask )
|
||||
{
|
||||
DeleteObject( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconMask);
|
||||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconMask= 0;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* X11DRV_WND_SetParent
|
||||
*/
|
||||
WND *X11DRV_WND_SetParent(WND *wndPtr, WND *pWndParent)
|
||||
{
|
||||
WND *pDesktop = WIN_GetDesktop();
|
||||
|
||||
if( wndPtr && pWndParent && (wndPtr != pDesktop) )
|
||||
{
|
||||
WND* pWndPrev = wndPtr->parent;
|
||||
|
||||
if( pWndParent != pWndPrev )
|
||||
{
|
||||
if ( X11DRV_WND_GetXWindow(wndPtr) )
|
||||
{
|
||||
/* Toplevel window needs to be reparented. Used by Tk 8.0 */
|
||||
|
||||
TSXDestroyWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
|
||||
((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None;
|
||||
}
|
||||
|
||||
WIN_UnlinkWindow(wndPtr->hwndSelf);
|
||||
wndPtr->parent = pWndParent;
|
||||
|
||||
/* Create an X counterpart for reparented top-level windows
|
||||
* when not in the desktop mode. */
|
||||
|
||||
if( pWndParent == pDesktop )
|
||||
{
|
||||
if( X11DRV_GetXRootWindow() == DefaultRootWindow(display) )
|
||||
{
|
||||
CREATESTRUCTA cs;
|
||||
cs.lpCreateParams = NULL;
|
||||
cs.hInstance = 0; /* not used in following call */
|
||||
cs.hMenu = 0; /* not used in following call */
|
||||
cs.hwndParent = pWndParent->hwndSelf;
|
||||
cs.cy = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
|
||||
if (!cs.cy)
|
||||
cs.cy = 1;
|
||||
cs.cx = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
|
||||
if (!cs.cx)
|
||||
cs.cx = 1;
|
||||
cs.y = wndPtr->rectWindow.top;
|
||||
cs.x = wndPtr->rectWindow.left;
|
||||
cs.style = wndPtr->dwStyle;
|
||||
cs.lpszName = 0; /* not used in following call */
|
||||
cs.lpszClass = 0; /*not used in following call */
|
||||
cs.dwExStyle = wndPtr->dwExStyle;
|
||||
X11DRV_WND_CreateWindow(wndPtr, &cs, FALSE);
|
||||
}
|
||||
}
|
||||
else /* a child window */
|
||||
{
|
||||
if( !( wndPtr->dwStyle & WS_CHILD ) )
|
||||
{
|
||||
if( wndPtr->wIDmenu != 0)
|
||||
{
|
||||
DestroyMenu( (HMENU) wndPtr->wIDmenu );
|
||||
wndPtr->wIDmenu = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP);
|
||||
}
|
||||
WIN_ReleaseDesktop();
|
||||
return pWndPrev;
|
||||
} /* failure */
|
||||
WIN_ReleaseDesktop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_WND_ForceWindowRaise
|
||||
*
|
||||
|
@ -755,7 +303,7 @@ void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangeP
|
|||
{
|
||||
TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(winposPtr), 0, changeMask, &winChanges );
|
||||
if( winposPtr->clsStyle & (CS_VREDRAW | CS_HREDRAW) )
|
||||
X11DRV_WND_SetHostAttr( winposPtr, HAK_BITGRAVITY, BGForget );
|
||||
X11DRV_WND_SetGravity( winposPtr, ForgetGravity );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -768,83 +316,6 @@ void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangeP
|
|||
WIN_ReleaseWndPtr(winposPtr);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* X11DRV_WND_SetText
|
||||
*/
|
||||
void X11DRV_WND_SetText(WND *wndPtr, LPCWSTR text)
|
||||
{
|
||||
UINT count;
|
||||
char *buffer;
|
||||
static UINT text_cp = (UINT)-1;
|
||||
Window win;
|
||||
|
||||
if (!(win = X11DRV_WND_GetXWindow(wndPtr))) return;
|
||||
|
||||
if(text_cp == (UINT)-1)
|
||||
{
|
||||
text_cp = PROFILE_GetWineIniInt("x11drv", "TextCP", CP_ACP);
|
||||
TRACE("text_cp = %u\n", text_cp);
|
||||
}
|
||||
|
||||
/* allocate new buffer for window text */
|
||||
count = WideCharToMultiByte(text_cp, 0, text, -1, NULL, 0, NULL, NULL);
|
||||
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, count * sizeof(WCHAR) )))
|
||||
{
|
||||
ERR("Not enough memory for window text\n");
|
||||
return;
|
||||
}
|
||||
WideCharToMultiByte(text_cp, 0, text, -1, buffer, count, NULL, NULL);
|
||||
|
||||
TSXStoreName( display, win, buffer );
|
||||
TSXSetIconName( display, win, buffer );
|
||||
HeapFree( GetProcessHeap(), 0, buffer );
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* X11DRV_WND_SetFocus
|
||||
*
|
||||
* Set the X focus.
|
||||
* Explicit colormap management seems to work only with OLVWM.
|
||||
*/
|
||||
void X11DRV_WND_SetFocus(WND *wndPtr)
|
||||
{
|
||||
HWND hwnd = wndPtr->hwndSelf;
|
||||
XWindowAttributes win_attr;
|
||||
Window win;
|
||||
WND *w = wndPtr;
|
||||
|
||||
if (X11DRV_WND_IsZeroSizeWnd(wndPtr))
|
||||
return;
|
||||
|
||||
/* Only mess with the X focus if there's */
|
||||
/* no desktop window and if the window is not managed by the WM. */
|
||||
if ((X11DRV_GetXRootWindow() != DefaultRootWindow(display))) return;
|
||||
while (w && !((X11DRV_WND_DATA *) w->pDriverData)->window)
|
||||
w = w->parent;
|
||||
if (!w) w = wndPtr;
|
||||
if (w->dwExStyle & WS_EX_MANAGED) return;
|
||||
|
||||
if (!hwnd) /* If setting the focus to 0, uninstall the colormap */
|
||||
{
|
||||
if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
|
||||
TSXUninstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set X focus and install colormap */
|
||||
|
||||
if (!(win = X11DRV_WND_FindXWindow(wndPtr))) return;
|
||||
if (!TSXGetWindowAttributes( display, win, &win_attr ) ||
|
||||
(win_attr.map_state != IsViewable))
|
||||
return; /* If window is not viewable, don't change anything */
|
||||
|
||||
TSXSetInputFocus( display, win, RevertToParent, CurrentTime );
|
||||
if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
|
||||
TSXInstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
|
||||
|
||||
EVENT_Synchronize();
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* X11DRV_WND_PreSizeMove
|
||||
*/
|
||||
|
@ -896,89 +367,7 @@ void X11DRV_WND_SurfaceCopy(WND* wndPtr, HDC hdc, INT dx, INT dy,
|
|||
GDI_ReleaseObj( hdc );
|
||||
|
||||
if (bUpdate) /* Make sure exposure events have been processed */
|
||||
EVENT_Synchronize();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_WND_SetDrawable
|
||||
*
|
||||
* Set the drawable, origin and dimensions for the DC associated to
|
||||
* a given window.
|
||||
*/
|
||||
void X11DRV_WND_SetDrawable(WND *wndPtr, HDC hdc, WORD flags, BOOL bSetClipOrigin)
|
||||
{
|
||||
DC *dc = DC_GetDCPtr( hdc );
|
||||
X11DRV_PDEVICE *physDev;
|
||||
INT dcOrgXCopy = 0, dcOrgYCopy = 0;
|
||||
BOOL offsetClipRgn = FALSE;
|
||||
|
||||
if (!dc) return;
|
||||
physDev = (X11DRV_PDEVICE *)dc->physDev;
|
||||
if (!wndPtr) /* Get a DC for the whole screen */
|
||||
{
|
||||
dc->DCOrgX = 0;
|
||||
dc->DCOrgY = 0;
|
||||
physDev->drawable = X11DRV_GetXRootWindow();
|
||||
TSXSetSubwindowMode( display, physDev->gc, IncludeInferiors );
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* This function change the coordinate system (DCOrgX,DCOrgY)
|
||||
* values. When it moves the origin, other data like the current clipping
|
||||
* region will not be moved to that new origin. In the case of DCs that are class
|
||||
* or window DCs that clipping region might be a valid value from a previous use
|
||||
* of the DC and changing the origin of the DC without moving the clip region
|
||||
* results in a clip region that is not placed properly in the DC.
|
||||
* This code will save the dc origin, let the SetDrawable
|
||||
* modify the origin and reset the clipping. When the clipping is set,
|
||||
* it is moved according to the new DC origin.
|
||||
*/
|
||||
if ( (wndPtr->clsStyle & (CS_OWNDC | CS_CLASSDC)) && (dc->hClipRgn > 0))
|
||||
{
|
||||
dcOrgXCopy = dc->DCOrgX;
|
||||
dcOrgYCopy = dc->DCOrgY;
|
||||
offsetClipRgn = TRUE;
|
||||
}
|
||||
|
||||
if (flags & DCX_WINDOW)
|
||||
{
|
||||
dc->DCOrgX = wndPtr->rectWindow.left;
|
||||
dc->DCOrgY = wndPtr->rectWindow.top;
|
||||
}
|
||||
else
|
||||
{
|
||||
dc->DCOrgX = wndPtr->rectClient.left;
|
||||
dc->DCOrgY = wndPtr->rectClient.top;
|
||||
}
|
||||
while (!X11DRV_WND_GetXWindow(wndPtr))
|
||||
{
|
||||
wndPtr = wndPtr->parent;
|
||||
dc->DCOrgX += wndPtr->rectClient.left;
|
||||
dc->DCOrgY += wndPtr->rectClient.top;
|
||||
}
|
||||
dc->DCOrgX -= wndPtr->rectWindow.left;
|
||||
dc->DCOrgY -= wndPtr->rectWindow.top;
|
||||
|
||||
/* reset the clip region, according to the new origin */
|
||||
if ( offsetClipRgn )
|
||||
{
|
||||
OffsetRgn(dc->hClipRgn, dc->DCOrgX - dcOrgXCopy,dc->DCOrgY - dcOrgYCopy);
|
||||
}
|
||||
|
||||
physDev->drawable = X11DRV_WND_GetXWindow(wndPtr);
|
||||
|
||||
#if 0
|
||||
/* This is needed when we reuse a cached DC because
|
||||
* SetDCState() called by ReleaseDC() screws up DC
|
||||
* origins for child windows.
|
||||
*/
|
||||
|
||||
if( bSetClipOrigin )
|
||||
TSXSetClipOrigin( display, physDev->gc, dc->DCOrgX, dc->DCOrgY );
|
||||
#endif
|
||||
}
|
||||
GDI_ReleaseObj( hdc );
|
||||
X11DRV_Synchronize();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1018,6 +407,20 @@ static BOOL X11DRV_SetWMHint(Display* display, WND* wndPtr, int hint, int val)
|
|||
}
|
||||
|
||||
|
||||
void X11DRV_WND_SetGravity( WND* wnd, int value )
|
||||
{
|
||||
X11DRV_WND_DATA *data = wnd->pDriverData;
|
||||
|
||||
if (data->window && data->bit_gravity != value )
|
||||
{
|
||||
XSetWindowAttributes win_attr;
|
||||
win_attr.bit_gravity = value;
|
||||
data->bit_gravity = value;
|
||||
TSXChangeWindowAttributes( display, data->window, CWBitGravity, &win_attr );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_WND_SetHostAttr
|
||||
*
|
||||
|
@ -1031,8 +434,6 @@ BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value)
|
|||
|
||||
if( (w = X11DRV_WND_GetXWindow(wnd)) )
|
||||
{
|
||||
XSetWindowAttributes win_attr;
|
||||
|
||||
switch( ha )
|
||||
{
|
||||
case HAK_ICONICSTATE: /* called when a window is minimized/restored */
|
||||
|
@ -1086,142 +487,7 @@ BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value)
|
|||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case HAK_BITGRAVITY: /* called when a window is resized */
|
||||
|
||||
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_ICONS: /* called when the icons change */
|
||||
if ( (wnd->dwExStyle & WS_EX_MANAGED) )
|
||||
X11DRV_WND_UpdateIconHints(wnd);
|
||||
return TRUE;
|
||||
|
||||
case HAK_ACCEPTFOCUS: /* called when a window is disabled/enabled */
|
||||
|
||||
if( (wnd->dwExStyle & WS_EX_MANAGED) )
|
||||
return X11DRV_SetWMHint( display, wnd, InputHint, value );
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_WND_IsSelfClipping
|
||||
*/
|
||||
BOOL X11DRV_WND_IsSelfClipping(WND *wndPtr)
|
||||
{
|
||||
return X11DRV_WND_GetXWindow(wndPtr) != None;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_WND_DockWindow
|
||||
*
|
||||
* Set the X Property of the window that tells the windowmanager we really
|
||||
* want to be in the systray
|
||||
*
|
||||
* KDE: set "KWM_DOCKWINDOW", type "KWM_DOCKWINDOW" to 1 before a window is
|
||||
* mapped.
|
||||
*
|
||||
* all others: to be added ;)
|
||||
*/
|
||||
void X11DRV_WND_DockWindow(WND *wndPtr)
|
||||
{
|
||||
int data = 1;
|
||||
Window win = X11DRV_WND_GetXWindow(wndPtr);
|
||||
if (kwmDockWindow != None) {
|
||||
TSXChangeProperty(
|
||||
display,win,kwmDockWindow,kwmDockWindow,32,PropModeReplace,(char*)&data,1
|
||||
);
|
||||
}
|
||||
if (_kde_net_wm_system_tray_window_for != None) {
|
||||
TSXChangeProperty(
|
||||
display,
|
||||
win,
|
||||
_kde_net_wm_system_tray_window_for,
|
||||
XA_WINDOW,
|
||||
32,
|
||||
PropModeReplace,
|
||||
(char*)&win,
|
||||
1
|
||||
);
|
||||
}
|
||||
if (_net_kde_system_tray_window_for != None) {
|
||||
TSXChangeProperty(
|
||||
display,
|
||||
win,
|
||||
_net_kde_system_tray_window_for,
|
||||
XA_WINDOW,
|
||||
32,
|
||||
PropModeReplace,
|
||||
(char*)&win,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_WND_SetWindowRgn
|
||||
*
|
||||
* Assign specified region to window (for non-rectangular windows)
|
||||
*/
|
||||
void X11DRV_WND_SetWindowRgn(WND *wndPtr, HRGN hrgnWnd)
|
||||
{
|
||||
#ifdef HAVE_LIBXSHAPE
|
||||
Window win = X11DRV_WND_GetXWindow(wndPtr);
|
||||
|
||||
if (!win) return;
|
||||
|
||||
if (!hrgnWnd)
|
||||
{
|
||||
TSXShapeCombineMask( display, win, ShapeBounding, 0, 0, None, ShapeSet );
|
||||
}
|
||||
else
|
||||
{
|
||||
XRectangle *aXRect;
|
||||
DWORD size;
|
||||
DWORD dwBufferSize = GetRegionData(hrgnWnd, 0, NULL);
|
||||
PRGNDATA pRegionData = HeapAlloc(GetProcessHeap(), 0, dwBufferSize);
|
||||
if (!pRegionData) return;
|
||||
|
||||
GetRegionData(hrgnWnd, dwBufferSize, pRegionData);
|
||||
size = pRegionData->rdh.nCount;
|
||||
/* convert region's "Windows rectangles" to XRectangles */
|
||||
aXRect = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*aXRect) );
|
||||
if (aXRect)
|
||||
{
|
||||
XRectangle* pCurrRect = aXRect;
|
||||
RECT *pRect = (RECT*) pRegionData->Buffer;
|
||||
for (; pRect < ((RECT*) pRegionData->Buffer) + size ; ++pRect, ++pCurrRect)
|
||||
{
|
||||
pCurrRect->x = pRect->left;
|
||||
pCurrRect->y = pRect->top;
|
||||
pCurrRect->height = pRect->bottom - pRect->top;
|
||||
pCurrRect->width = pRect->right - pRect->left;
|
||||
|
||||
TRACE("Rectangle %04d of %04ld data: X=%04d, Y=%04d, Height=%04d, Width=%04d.\n",
|
||||
pRect - (RECT*) pRegionData->Buffer,
|
||||
size,
|
||||
pCurrRect->x,
|
||||
pCurrRect->y,
|
||||
pCurrRect->height,
|
||||
pCurrRect->width);
|
||||
}
|
||||
|
||||
/* shape = non-rectangular windows (X11/extensions) */
|
||||
TSXShapeCombineRectangles( display, win, ShapeBounding,
|
||||
0, 0, aXRect,
|
||||
pCurrRect - aXRect, ShapeSet, YXBanded );
|
||||
HeapFree(GetProcessHeap(), 0, aXRect );
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, pRegionData);
|
||||
}
|
||||
#endif /* HAVE_LIBXSHAPE */
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue