diff --git a/dlls/ttydrv/dc.c b/dlls/ttydrv/dc.c index a576532a64e464065a334eef7bcc6e907d25ad26..1dc83d84391f0b5cea0f577dec8ed9ee3ed8c5e1 100644 --- a/dlls/ttydrv/dc.c +++ b/dlls/ttydrv/dc.c @@ -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; diff --git a/dlls/ttydrv/ttydrv.h b/dlls/ttydrv/ttydrv.h index dbb1aa6292de3e52c43ec4e424f7d8d682239d80..3f12f295221390beedcb5fc0ea24ca9b40cbe9c6 100644 --- a/dlls/ttydrv/ttydrv.h +++ b/dlls/ttydrv/ttydrv.h @@ -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) */ diff --git a/dlls/ttydrv/ttydrv.spec b/dlls/ttydrv/ttydrv.spec index aef0ce97adf472fcabb85a50b7cc11d9802f56e5..f5c5b2b954138dbe1c74beb033ccfba02cb7988c 100644 --- a/dlls/ttydrv/ttydrv.spec +++ b/dlls/ttydrv/ttydrv.spec @@ -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 diff --git a/dlls/ttydrv/user.c b/dlls/ttydrv/user.c index 5af69b78dabcf1385f50fea07332454ec08f9c64..b129f0b41497e3fd6c0241bb3acf4635ae415b92 100644 --- a/dlls/ttydrv/user.c +++ b/dlls/ttydrv/user.c @@ -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 */ diff --git a/dlls/ttydrv/wnd.c b/dlls/ttydrv/wnd.c index 3247d65c7420abe96f481d9ddea640956d307b63..743f1a9fbe2d7bd40cb0409ddbd9fcc381208074 100644 --- a/dlls/ttydrv/wnd.c +++ b/dlls/ttydrv/wnd.c @@ -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; -} - -/********************************************************************** - * TTYDRV_WND_Initialize - */ -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; -} +#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_Finalize + * CreateWindow (TTYDRV.@) */ -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) - return TRUE; + /* Only create top-level windows */ + if (wndPtr->dwStyle & WS_CHILD) + { + WIN_ReleaseWndPtr( wndPtr ); + return TRUE; + } - window = subwin(TTYDRV_GetRootWindow(), cs->cy/cellHeight, cs->cx/cellWidth, - cs->y/cellHeight, cs->x/cellWidth); - werase(window); - wrefresh(window); - - 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("(%p, %p, %p, %d): stub\n", wndPtr, cs, bUnicode); - - return TRUE; + FIXME("(%x): stub\n", hwnd); #endif /* defined(WINE_CURSES) */ + return TRUE; } /*********************************************************************** - * TTYDRV_WND_DestroyWindow + * DestroyWindow (TTYDRV.@) */ -BOOL TTYDRV_WND_DestroyWindow(WND *wndPtr) +BOOL TTYDRV_DestroyWindow( HWND hwnd ) { #ifdef WINE_CURSES - WINDOW *window; - - TRACE("(%p)\n", wndPtr); + WND *wndPtr = WIN_FindWndPtr( hwnd ); + WINDOW *window = wndPtr->pDriverData; - window = TTYDRV_WND_GetCursesWindow(wndPtr); - if(window && window != TTYDRV_GetRootWindow()) { - delwin(window); - } + TRACE("(%x)\n", hwnd); - 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 */ @@ -219,54 +127,528 @@ void TTYDRV_WND_ScrollWindow( WND *wndPtr, HDC hdc, INT dx, INT dy, } /*********************************************************************** - * TTYDRV_WND_SetDrawable + * TTYDRV_WND_SetHostAttr */ -void TTYDRV_WND_SetDrawable(WND *wndPtr, HDC hdc, WORD flags, BOOL bSetClipOrigin) +BOOL TTYDRV_WND_SetHostAttr(WND *wndPtr, INT attr, INT value) { - 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; + FIXME("(%p): stub\n", wndPtr); + + return TRUE; +} + + +/*********************************************************************** + * 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_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; } - GDI_ReleaseObj( hdc ); + +fail: + SetRectEmpty( lprect ); + return FALSE; } + /*********************************************************************** - * TTYDRV_WND_SetHostAttr + * 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. */ -BOOL TTYDRV_WND_SetHostAttr(WND *wndPtr, INT attr, INT value) +static BOOL DCE_AddClipRects( WND *pWndStart, WND *pWndEnd, + HRGN hrgnClip, LPRECT lpRect, int x, int y ) { - FIXME("(%p): stub\n", wndPtr); + RECT rect; - return TRUE; + 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); } + /*********************************************************************** - * TTYDRV_WND_IsSelfClipping + * 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. */ -BOOL TTYDRV_WND_IsSelfClipping(WND *wndPtr) +static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags ) { - FIXME("(%p): semistub\n", wndPtr); - - return FALSE; + 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; } + /*********************************************************************** - * TTYDRV_WND_SetWindowRgn + * GetDC (TTYDRV.@) + * + * Set the drawable, origin and dimensions for the DC associated to + * a given window. */ -void TTYDRV_WND_SetWindowRgn(struct tagWND *wndPtr, HRGN hrgnWnd) +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; +} diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c index 5a45a1f80fd4ec999697b9cc50d9dcb61e138904..6e358a37eacdeb4cb039fa95c017d64fb64751ff 100644 --- a/dlls/user/user_main.c +++ b/dlls/user/user_main.c @@ -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; } diff --git a/dlls/x11drv/Makefile.in b/dlls/x11drv/Makefile.in index b1c6ec52866e1c3dc32ad124ae7fee251a36ac8a..10a3f9a6854f9208a3b7b920f426ba824a133fa8 100644 --- a/dlls/x11drv/Makefile.in +++ b/dlls/x11drv/Makefile.in @@ -8,6 +8,8 @@ IMPORTS = user32 gdi32 kernel32 C_SRCS = \ dga2.c \ + window.c \ + winpos.c \ x11ddraw.c \ x11drv_main.c \ xvidmode.c diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c new file mode 100644 index 0000000000000000000000000000000000000000..c5ca2b86adafda106faaaec3368badc730da00d4 --- /dev/null +++ b/dlls/x11drv/window.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; +} diff --git a/dlls/x11drv/winpos.c b/dlls/x11drv/winpos.c new file mode 100644 index 0000000000000000000000000000000000000000..c209ca9701c688b1d1bcdca44c486fd028def72f --- /dev/null +++ b/dlls/x11drv/winpos.c @@ -0,0 +1,1324 @@ +/* + * Window position related functions. + * + * Copyright 1993, 1994, 1995, 2001 Alexandre Julliard + * Copyright 1995, 1996, 1999 Alex Korobka + */ + +#include "config.h" + +#include "ts_xlib.h" +#include "ts_shape.h" + +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" + +#include "x11drv.h" +#include "win.h" +#include "winpos.h" +#include "region.h" +#include "dce.h" + +#include "debugtools.h" + +DEFAULT_DEBUG_CHANNEL(win); + + +#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 SWP_EX_NOCOPY 0x0001 +#define SWP_EX_PAINTSELF 0x0002 +#define SWP_EX_NONCLIENT 0x0004 + + +/*********************************************************************** + * 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_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 (X11DRV_WND_GetXWindow(pWndStart)) return TRUE; /* X 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. + */ +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 (X11DRV.@) + * + * Set the drawable, origin and dimensions for the DC associated to + * a given window. + */ +BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags ) +{ + WND *w, *wndPtr = WIN_FindWndPtr(hwnd); + DC *dc; + X11DRV_PDEVICE *physDev; + INT dcOrgXCopy = 0, dcOrgYCopy = 0; + BOOL offsetClipRgn = FALSE; + BOOL updateVisRgn; + HRGN hrgnVisible = 0; + + if (!wndPtr) return FALSE; + + if (!(dc = DC_GetDCPtr( hdc ))) + { + WIN_ReleaseWndPtr( wndPtr ); + return FALSE; + } + + physDev = (X11DRV_PDEVICE *)dc->physDev; + + /* + * 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; + } + + w = wndPtr; + while (!X11DRV_WND_GetXWindow(w)) + { + w = w->parent; + dc->DCOrgX += w->rectClient.left; + dc->DCOrgY += w->rectClient.top; + } + dc->DCOrgX -= w->rectWindow.left; + dc->DCOrgY -= w->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(w); + +#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 + + 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 + { + if ((hwnd == GetDesktopWindow()) && (root_window != DefaultRootWindow(display))) + hrgnVisible = CreateRectRgn( 0, 0, GetSystemMetrics(SM_CXSCREEN), + GetSystemMetrics(SM_CYSCREEN) ); + 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; +} + + +/*********************************************************************** + * 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; +} + +/*********************************************************************** + * 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 ) ) + { + X11DRV_WND_SurfaceCopy( 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; +} + + +/*********************************************************************** + * SetWindowPos (X11DRV.@) + */ +BOOL X11DRV_SetWindowPos( 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 = 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); + + bChangePos = !(winpos->flags & SWP_WINE_NOHOSTMOVE); + winpos->flags &= ~SWP_WINE_NOHOSTMOVE; + + /* ------------------------------------------------------------------------ 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 */ + + SWP_DoWinPosChanging( wndPtr, winpos, &newWindowRect, &newClientRect ); + + if((winpos->flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER) + { + if( wndPtr->parent == WIN_GetDesktop() ) + winpos->hwndInsertAfter = SWP_DoOwnedPopups( wndPtr->parent, wndPtr, + winpos->hwndInsertAfter, winpos->flags ); + WIN_ReleaseDesktop(); + } + + if(!(wndPtr->flags & WIN_NATIVE) ) + { + 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; + + 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(winpos->hwnd, dflags, 0, 0); + } + } + + /* Common operations */ + + wvrFlags = SWP_DoNCCalcSize( wndPtr, winpos, &newWindowRect, &newClientRect, winpos->flags ); + + if(!(winpos->flags & SWP_NOZORDER) && winpos->hwnd != winpos->hwndInsertAfter) + { + if ( WIN_UnlinkWindow( winpos->hwnd ) ) + WIN_LinkWindow( winpos->hwnd, winpos->hwndInsertAfter ); + } + + /* Reset active DCEs */ + + if( (((winpos->flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) && + wndPtr->dwStyle & WS_VISIBLE) || + (winpos->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 = winpos->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) ) + { + winpos->cx = newWindowRect.right - newWindowRect.left; + winpos->cy = newWindowRect.bottom - newWindowRect.top; + + X11DRV_WND_SetWindowPos(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, winpos->cx, winpos->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; + } + X11DRV_WND_SetGravity(wndPtr, NorthWestGravity ); + } + } + + X11DRV_WND_SetWindowPos(wndPtr, winpos, bChangePos); + X11DRV_WND_SetGravity(wndPtr, ForgetGravity ); + 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 == winpos->hwnd) + { + X11DRV_SetFocus(focus); + 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 (winpos->hwnd == CARET_GetHwnd()) + { + if( winpos->flags & SWP_HIDEWINDOW ) + HideCaret(winpos->hwnd); + else if (winpos->flags & SWP_SHOWWINDOW) + ShowCaret(winpos->hwnd); + } + + /* ------------------------------------------------------------------------ FINAL */ + + if (wndPtr->flags & WIN_NATIVE) + X11DRV_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 ) + { + RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, + RDW_ERASENOW | RDW_NOCHILDREN ); + } + } + if( visRgn != 1 ) + DeleteObject( visRgn ); + } + + WIN_ReleaseDesktop(); + + 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 ( resync || + (((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) && + !(winpos->flags & SWP_NOSENDCHANGING)) ) + { + SendMessageA( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)winpos ); + if (resync) X11DRV_Synchronize(); + } + + retvalue = TRUE; + END: + WIN_ReleaseWndPtr(wndPtr); + return retvalue; +} + + +/*********************************************************************** + * SetWindowRgn (X11DRV.@) + * + * Assign specified region to window (for non-rectangular windows) + */ +BOOL X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw ) +{ + RECT rect; + WND *wndPtr = WIN_FindWndPtr(hwnd); + int ret = FALSE; + + if (!wndPtr) return FALSE; + + if (wndPtr->hrgnWnd == hrgn) + { + ret = TRUE; + goto done; + } + + if (hrgn) /* verify that region really exists */ + { + if (GetRgnBox( hrgn, &rect ) == ERROR) goto done; + } + + if (wndPtr->hrgnWnd) + { + /* delete previous region */ + DeleteObject(wndPtr->hrgnWnd); + wndPtr->hrgnWnd = 0; + } + wndPtr->hrgnWnd = 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 | (redraw ? 0 : SWP_NOREDRAW) ); +#ifdef HAVE_LIBXSHAPE + { + Window win = X11DRV_WND_GetXWindow(wndPtr); + + if (win) + { + if (!hrgn) + { + TSXShapeCombineMask( display, win, ShapeBounding, 0, 0, None, ShapeSet ); + } + else + { + XRectangle *aXRect; + DWORD size; + DWORD dwBufferSize = GetRegionData(hrgn, 0, NULL); + PRGNDATA pRegionData = HeapAlloc(GetProcessHeap(), 0, dwBufferSize); + if (!pRegionData) goto done; + + GetRegionData(hrgn, 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 */ + + ret = TRUE; + + done: + WIN_ReleaseWndPtr(wndPtr); + return ret; +} diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec index d56b457200a10500c1997d5abc62f9f69d98183b..914d5aad4460399395b594980af0eb4e78a5d936 100644 --- a/dlls/x11drv/x11drv.spec +++ b/dlls/x11drv/x11drv.spec @@ -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 diff --git a/include/dce.h b/include/dce.h index 3c386817855fd430746269a6a199e78836a7071c..6e28da7e2178a2d73cd9eb6a647c6215673f4ec8 100644 --- a/include/dce.h +++ b/include/dce.h @@ -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 */ diff --git a/include/message.h b/include/message.h index 2fac450752b7be960db30bff1dbc9e8eaded2e09..5db85092eb4d83207e8884464cbcd3b92f487627 100644 --- a/include/message.h +++ b/include/message.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 ); diff --git a/include/user.h b/include/user.h index a4d16adf36292c84631cc654931e5805396a6dba..df0b9069d61ddcd0fba6bedb1d68e1b5b29d6a90 100644 --- a/include/user.h +++ b/include/user.h @@ -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; diff --git a/include/win.h b/include/win.h index 6cecf6a6f1e12947eb0cc734abf780192b3128e9..8a5b3e1231c9b1589dc539beab3025926e2b7f87 100644 --- a/include/win.h +++ b/include/win.h @@ -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; diff --git a/include/winpos.h b/include/winpos.h index ecadf6df441fcb685c3a9ca20996dd983d1c0976..f43523c74476f03e34fa583e6ed34cf911a8a7bd 100644 --- a/include/winpos.h +++ b/include/winpos.h @@ -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, diff --git a/include/x11drv.h b/include/x11drv.h index 432fb996f98ed8c3ef0571d4c7972ec7409b7041..7b8671eaf9961114ff97cbb9ba568cffddd83d3a 100644 --- a/include/x11drv.h +++ b/include/x11drv.h @@ -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 */ diff --git a/windows/Makefile.in b/windows/Makefile.in index be747ddc3c2cc9f101ed210d81a3fef89805ff01..a971ec6f88d9c0673ee7057c34f27110ca9c7482 100644 --- a/windows/Makefile.in +++ b/windows/Makefile.in @@ -16,7 +16,6 @@ C_SRCS = \ defwnd.c \ dialog.c \ driver.c \ - event.c \ focus.c \ hook.c \ input.c \ diff --git a/windows/dce.c b/windows/dce.c index 6ed390ea8df09eea8dc699ce168f57298cdc23ff..4c697d710c51c20b6fffb0ad39619ba23f9d3095 100644 --- a/windows/dce.c +++ b/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; diff --git a/windows/defwnd.c b/windows/defwnd.c index 3583cf5c889fc26e814f2184f87d6bb5b7de2cbf..855bde36d52d371cc22ab7a4bb9b751b845f54f1 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -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; } diff --git a/windows/event.c b/windows/event.c deleted file mode 100644 index da5041e618f755070c5a26e71553cc8a25f8fd8b..0000000000000000000000000000000000000000 --- a/windows/event.c +++ /dev/null @@ -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(); -} - - - diff --git a/windows/focus.c b/windows/focus.c index d09c278e3cbb4164bd61c2501370b054d65f7bd0..76838dee5e3d71f18f5249ade8fed5e0539b1426 100644 --- a/windows/focus.c +++ b/windows/focus.c @@ -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( !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 } diff --git a/windows/message.c b/windows/message.c index f1ea0cd4b30b73c7acc502f55cfd87c7d81ce6f3..f49d89f4141a6437be2d6694625b452c7d356e6a 100644 --- a/windows/message.c +++ b/windows/message.c @@ -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); diff --git a/windows/painting.c b/windows/painting.c index 072c52a290933bba61fcd32c7dc92804406dddae..86d7b64d7cf5abf88678c3ae27468345b3830a16 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -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 ); } diff --git a/windows/scroll.c b/windows/scroll.c index dc05ffa63312c1a0f3aebdf44cef39a20eec8e9e..71dc90ac0a0b477ddec1fdc0f3d82dd13218ea7b 100644 --- a/windows/scroll.c +++ b/windows/scroll.c @@ -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 ) { diff --git a/windows/win.c b/windows/win.c index 4329e92267e1db5cc7e77d8ee5019dcb2ee3db27..1d2bfefd46c8f3386242fbae510f6cb635bf3efb 100644 --- a/windows/win.c +++ b/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; - if (enable && (wndPtr->dwStyle & WS_DISABLED)) - { - /* Enable window */ - wndPtr->dwStyle &= ~WS_DISABLED; - if( wndPtr->flags & WIN_NATIVE ) - wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ACCEPTFOCUS, TRUE ); + retvalue = ((wndPtr->dwStyle & WS_DISABLED) != 0); - SendMessageA( hwnd, WM_ENABLE, TRUE, 0 ); - retvalue = TRUE; - goto end; + if (enable && (wndPtr->dwStyle & WS_DISABLED)) + { + 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; - - - if(!(wndPtr = WIN_FindWndPtr(hwndChild))) return 0; + WND *wndPtr; + WND *pWndParent; + DWORD dwStyle; + HWND retvalue; - dwStyle = wndPtr->dwStyle; + if (hwnd == GetDesktopWindow()) /* sanity check */ + { + SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return 0; + } - pWndNewParent = hwndNewParent ? WIN_FindWndPtr(hwndNewParent) - : WIN_LockWndPtr(pWndDesktop); + if (USER_Driver.pSetParent) + return USER_Driver.pSetParent( hwnd, parent ); - /* Windows hides the window first, then shows it again - * including the WM_SHOWWINDOW messages and all */ - if (dwStyle & WS_VISIBLE) - ShowWindow( hwndChild, SW_HIDE ); + if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0; - pWndOldParent = WIN_LockWndPtr((*wndPtr->pDriver->pSetParent)(wndPtr, pWndNewParent)); + dwStyle = wndPtr->dwStyle; - /* 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 */ + pWndParent = parent ? WIN_FindWndPtr(parent) : WIN_GetDesktop(); + if (!pWndParent) + { + WIN_ReleaseWndPtr( wndPtr ); + return 0; + } - retvalue = pWndOldParent?pWndOldParent->hwndSelf: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 ); - WIN_ReleaseWndPtr(pWndOldParent); - WIN_ReleaseWndPtr(pWndNewParent); - WIN_ReleaseWndPtr(wndPtr); + retvalue = wndPtr->parent->hwndSelf; /* old parent */ + if (pWndParent != wndPtr->parent) + { + WIN_UnlinkWindow(wndPtr->hwndSelf); + wndPtr->parent = pWndParent; - return retvalue; - + 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 ); + + /* 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); diff --git a/windows/winpos.c b/windows/winpos.c index 45597978109c59f42009bfe473d92069bcfa2a5c..d88161810a41470f67d1f2f515a0913e651a2808 100644 --- a/windows/winpos.c +++ b/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) - { - GetWindowRect(hwnd, &tempRect); - } - else + if (hrgn) /* verify that region really exists */ { - /* 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; diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c index 1c08afbb19cf4e14ee9ab0af70b740d0d21d818d..f07fabd7cbca5dc0fb662e794b569b7db9c98d3b 100644 --- a/windows/x11drv/event.c +++ b/windows/x11drv/event.c @@ -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); diff --git a/windows/x11drv/keyboard.c b/windows/x11drv/keyboard.c index dc51d40bb2b885a03774a65d99cb8b952f57f486..65271ffce7fc894b17e6c3234b6f0c3942deda64 100644 --- a/windows/x11drv/keyboard.c +++ b/windows/x11drv/keyboard.c @@ -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); -} - diff --git a/windows/x11drv/wnd.c b/windows/x11drv/wnd.c index 20e9cdad3d83603c81674947bfdc633c624afdda..9d0cb95c77ea32471a783e4925b7755637db5279 100644 --- a/windows/x11drv/wnd.c +++ b/windows/x11drv/wnd.c @@ -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 */ -}