Create an X window for every window, including children.
Fixed non-client rectangle calculations in managed mode.
Added support for icon window in managed mode.
diff --git a/dlls/ttydrv/ttydrv.spec b/dlls/ttydrv/ttydrv.spec
index ffcdc9f..8a14613 100644
--- a/dlls/ttydrv/ttydrv.spec
+++ b/dlls/ttydrv/ttydrv.spec
@@ -27,7 +27,7 @@
@ cdecl GetScreenSaveTimeout() TTYDRV_GetScreenSaveTimeout
@ cdecl SetScreenSaveTimeout(long) TTYDRV_SetScreenSaveTimeout
@ cdecl LoadOEMResource(long long) TTYDRV_LoadOEMResource
-@ cdecl CreateWindow(long) TTYDRV_CreateWindow
+@ cdecl CreateWindow(long ptr) TTYDRV_CreateWindow
@ cdecl DestroyWindow(long) TTYDRV_DestroyWindow
@ cdecl GetDC(long long long long) TTYDRV_GetDC
@ cdecl SetWindowPos(ptr) TTYDRV_SetWindowPos
diff --git a/dlls/ttydrv/wnd.c b/dlls/ttydrv/wnd.c
index bb10699..b0ae7e1 100644
--- a/dlls/ttydrv/wnd.c
+++ b/dlls/ttydrv/wnd.c
@@ -17,8 +17,7 @@
WND_DRIVER TTYDRV_WND_Driver =
{
- TTYDRV_WND_ForceWindowRaise,
- TTYDRV_WND_SetHostAttr
+ TTYDRV_WND_ForceWindowRaise
};
#define SWP_AGG_NOGEOMETRYCHANGE \
@@ -31,8 +30,10 @@
/**********************************************************************
* CreateWindow (TTYDRV.@)
*/
-BOOL TTYDRV_CreateWindow( HWND hwnd )
+BOOL TTYDRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs )
{
+ BOOL ret;
+
#ifdef WINE_CURSES
WND *wndPtr = WIN_FindWndPtr( hwnd );
WINDOW *window;
@@ -41,32 +42,40 @@
TRACE("(%x)\n", hwnd);
/* Only create top-level windows */
- if (wndPtr->dwStyle & WS_CHILD)
+ if (!(wndPtr->dwStyle & WS_CHILD))
{
- WIN_ReleaseWndPtr( wndPtr );
- return TRUE;
- }
+ if (!wndPtr->parent) /* desktop */
+ window = root_window;
+ else
+ {
+ int x = wndPtr->rectWindow.left;
+ int y = wndPtr->rectWindow.top;
+ int cx = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
+ int cy = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
- 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);
+ window = subwin( root_window, cy/cellHeight, cx/cellWidth,
+ y/cellHeight, x/cellWidth);
+ werase(window);
+ wrefresh(window);
+ }
+ wndPtr->pDriverData = window;
}
- wndPtr->pDriverData = window;
WIN_ReleaseWndPtr( wndPtr );
#else /* defined(WINE_CURSES) */
FIXME("(%x): stub\n", hwnd);
#endif /* defined(WINE_CURSES) */
- return TRUE;
+
+ if (IsWindowUnicode( hwnd ))
+ {
+ ret = SendMessageW( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
+ if (ret) ret = (SendMessageW( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
+ }
+ else
+ {
+ ret = SendMessageA( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
+ if (ret) ret = (SendMessageA( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
+ }
+ return ret;
}
/***********************************************************************
@@ -97,16 +106,6 @@
FIXME("(%p): stub\n", wndPtr);
}
-/***********************************************************************
- * TTYDRV_WND_SetHostAttr
- */
-BOOL TTYDRV_WND_SetHostAttr(WND *wndPtr, INT attr, INT value)
-{
- FIXME("(%p): stub\n", wndPtr);
-
- return TRUE;
-}
-
/***********************************************************************
* DCE_OffsetVisRgn
diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c
index 63dbfb9..cdd1ff2 100644
--- a/dlls/user/user_main.c
+++ b/dlls/user/user_main.c
@@ -89,6 +89,7 @@
GET_USER_FUNC(GetDC);
GET_USER_FUNC(EnableWindow);
GET_USER_FUNC(MsgWaitForMultipleObjectsEx);
+ GET_USER_FUNC(ScrollDC);
GET_USER_FUNC(ScrollWindowEx);
GET_USER_FUNC(SetFocus);
GET_USER_FUNC(SetParent);
@@ -96,6 +97,7 @@
GET_USER_FUNC(SetWindowRgn);
GET_USER_FUNC(SetWindowIcon);
GET_USER_FUNC(SetWindowText);
+ GET_USER_FUNC(ShowWindow);
GET_USER_FUNC(SysCommandSizeMove);
return TRUE;
diff --git a/dlls/x11drv/Makefile.in b/dlls/x11drv/Makefile.in
index e98cdd5..9ad31aa 100644
--- a/dlls/x11drv/Makefile.in
+++ b/dlls/x11drv/Makefile.in
@@ -9,6 +9,7 @@
C_SRCS = \
desktop.c \
dga2.c \
+ scroll.c \
window.c \
winpos.c \
x11ddraw.c \
diff --git a/dlls/x11drv/desktop.c b/dlls/x11drv/desktop.c
index 1376899..ff57b37 100644
--- a/dlls/x11drv/desktop.c
+++ b/dlls/x11drv/desktop.c
@@ -55,11 +55,14 @@
/* patch the desktop window queue to point to our queue */
win = WIN_FindWndPtr( hwnd );
win->hmemTaskQ = GetFastQueue16();
+ X11DRV_register_window( display, hwnd, win->pDriverData );
WIN_ReleaseWndPtr( win );
SetWindowLongW( hwnd, GWL_WNDPROC, (LONG)desktop_winproc );
- X11DRV_register_window( display, hwnd, root_window );
- TSXMapWindow( display, root_window );
+ wine_tsx11_lock();
+ XSetWMProtocols( display, root_window, &wmDeleteWindow, 1 );
+ XMapWindow( display, root_window );
+ wine_tsx11_unlock();
while (GetMessageW( &msg, hwnd, 0, 0 )) DispatchMessageW( &msg );
return 0;
diff --git a/dlls/x11drv/scroll.c b/dlls/x11drv/scroll.c
new file mode 100644
index 0000000..c6b4520
--- /dev/null
+++ b/dlls/x11drv/scroll.c
@@ -0,0 +1,234 @@
+/*
+ * Scroll windows and DCs
+ *
+ * Copyright 1993 David W. Metcalfe
+ * Copyright 1995, 1996 Alex Korobka
+ * Copyright 2001 Alexandre Julliard
+ */
+
+#include "config.h"
+
+#include "ts_xlib.h"
+#include "ts_xutil.h"
+
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+
+#include "x11drv.h"
+#include "win.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(x11drv);
+
+
+/*************************************************************************
+ * fix_caret
+ */
+static BOOL fix_caret(HWND hWnd, LPRECT lprc, UINT flags)
+{
+ HWND hCaret = CARET_GetHwnd();
+
+ if( hCaret )
+ {
+ RECT rc;
+ CARET_GetRect( &rc );
+ if( hCaret == hWnd ||
+ (flags & SW_SCROLLCHILDREN && IsChild(hWnd, hCaret)) )
+ {
+ POINT pt;
+ pt.x = rc.left;
+ pt.y = rc.top;
+ MapWindowPoints( hCaret, hWnd, (LPPOINT)&rc, 2 );
+ if( IntersectRect(lprc, lprc, &rc) )
+ {
+ HideCaret(0);
+ lprc->left = pt.x;
+ lprc->top = pt.y;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+/*************************************************************************
+ * ScrollDC (X11DRV.@)
+ *
+ * Only the hrgnUpdate is returned in device coordinates.
+ * rcUpdate must be returned in logical coordinates to comply with win API.
+ * FIXME: the doc explicitly states the opposite, to be checked
+ */
+BOOL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *rc,
+ const RECT *clipRect, HRGN hrgnUpdate, LPRECT rcUpdate )
+{
+ RECT rect, rClip, rSrc;
+
+ TRACE( "%04x %d,%d hrgnUpdate=%04x rcUpdate = %p\n", hdc, dx, dy, hrgnUpdate, rcUpdate );
+ if (clipRect) TRACE( "cliprc = (%d,%d,%d,%d)\n",
+ clipRect->left, clipRect->top, clipRect->right, clipRect->bottom );
+ if (rc) TRACE( "rc = (%d,%d,%d,%d)\n", rc->left, rc->top, rc->right, rc->bottom );
+
+ /* compute device clipping region (in device coordinates) */
+
+ if (rc) rect = *rc;
+ else GetClipBox( hdc, &rect );
+
+ if (clipRect)
+ {
+ rClip = *clipRect;
+ IntersectRect( &rClip, &rect, &rClip );
+ }
+ else rClip = rect;
+
+ rSrc = rClip;
+ OffsetRect( &rSrc, -dx, -dy );
+ IntersectRect( &rSrc, &rSrc, &rect );
+
+ if (!IsRectEmpty(&rSrc))
+ {
+ /* copy bits */
+ if (!BitBlt( hdc, rSrc.left + dx, rSrc.top + dy,
+ rSrc.right - rSrc.left, rSrc.bottom - rSrc.top,
+ hdc, rSrc.left, rSrc.top, SRCCOPY))
+ return FALSE;
+ }
+
+ /* compute update areas */
+
+ if (hrgnUpdate || rcUpdate)
+ {
+ HRGN hrgn = hrgnUpdate, hrgn2;
+ POINT pt;
+
+ /* map everything to device coordinates */
+ pt.x = rect.left + dx;
+ pt.y = rect.top + dy;
+ LPtoDP( hdc, &pt, 1 );
+ LPtoDP( hdc, (LPPOINT)&rect, 2 );
+ LPtoDP( hdc, (LPPOINT)&rClip, 2 );
+ dx = pt.x - rect.left;
+ dy = pt.y - rect.top;
+
+ hrgn2 = CreateRectRgnIndirect( &rect );
+ if (hrgn) SetRectRgn( hrgn, rClip.left, rClip.top, rClip.right, rClip.bottom );
+ else hrgn = CreateRectRgn( rClip.left, rClip.top, rClip.right, rClip.bottom );
+ CombineRgn( hrgn, hrgn, hrgn2, RGN_AND );
+ OffsetRgn( hrgn2, dx, dy );
+ CombineRgn( hrgn, hrgn, hrgn2, RGN_DIFF );
+
+ if( rcUpdate )
+ {
+ GetRgnBox( hrgn, rcUpdate );
+
+ /* Put the rcUpdate in logical coordinate */
+ DPtoLP( hdc, (LPPOINT)rcUpdate, 2 );
+ }
+ if (!hrgnUpdate) DeleteObject( hrgn );
+ DeleteObject( hrgn2 );
+ }
+ return TRUE;
+}
+
+
+/*************************************************************************
+ * ScrollWindowEx (X11DRV.@)
+ */
+INT X11DRV_ScrollWindowEx( HWND hwnd, INT dx, INT dy,
+ const RECT *rect, const RECT *clipRect,
+ HRGN hrgnUpdate, LPRECT rcUpdate, UINT flags )
+{
+ INT retVal = NULLREGION;
+ BOOL bCaret = FALSE, bOwnRgn = TRUE;
+ RECT rc, cliprc;
+ WND* wnd = WIN_FindWndPtr( hwnd );
+
+ if( !wnd || !WIN_IsWindowDrawable( wnd, TRUE ))
+ {
+ retVal = ERROR;
+ goto END;
+ }
+
+ GetClientRect(hwnd, &rc);
+ if (rect) IntersectRect(&rc, &rc, rect);
+
+ if (clipRect) IntersectRect(&cliprc,&rc,clipRect);
+ else cliprc = rc;
+
+ if (!IsRectEmpty(&cliprc) && (dx || dy))
+ {
+ HDC hDC;
+ BOOL bUpdate = (rcUpdate || hrgnUpdate || flags & (SW_INVALIDATE | SW_ERASE));
+ HRGN hrgnClip = CreateRectRgnIndirect(&cliprc);
+ HRGN hrgnTemp;
+ RECT caretrc;
+
+ TRACE( "%04x, %d,%d hrgnUpdate=%04x rcUpdate = %p rc=(%d,%d-%d,%d) %04x\n",
+ hwnd, dx, dy, hrgnUpdate, rcUpdate,
+ rc.left, rc.top, rc.right, rc.bottom, flags );
+ if (clipRect) TRACE( "cliprc = (%d,%d,%d,%d)\n",
+ clipRect->left, clipRect->top,
+ clipRect->right, clipRect->bottom );
+
+ caretrc = rc;
+ bCaret = fix_caret(hwnd, &caretrc, flags);
+
+ if( hrgnUpdate ) bOwnRgn = FALSE;
+ else if( bUpdate ) hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );
+
+ hDC = GetDCEx( hwnd, 0, DCX_CACHE | DCX_USESTYLE );
+ if (hDC)
+ {
+ HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
+ X11DRV_StartGraphicsExposures( hDC );
+ X11DRV_ScrollDC( hDC, dx, dy, &rc, &cliprc, hrgnUpdate, rcUpdate );
+ X11DRV_EndGraphicsExposures( hDC, hrgn );
+ ReleaseDC( hwnd, hDC );
+ if (bUpdate) CombineRgn( hrgnUpdate, hrgnUpdate, hrgn, RGN_OR );
+ else RedrawWindow( hwnd, NULL, hrgn, RDW_INVALIDATE | RDW_ERASE );
+ }
+
+ /* Take into account the fact that some damages may have occured during the scroll */
+ hrgnTemp = CreateRectRgn( 0, 0, 0, 0 );
+ if (GetUpdateRgn( hwnd, hrgnTemp, FALSE ) != NULLREGION)
+ {
+ OffsetRgn( hrgnTemp, dx, dy );
+ CombineRgn( hrgnTemp, hrgnTemp, hrgnClip, RGN_AND );
+ RedrawWindow( hwnd, NULL, hrgnTemp, RDW_INVALIDATE | RDW_ERASE );
+ }
+ DeleteObject( hrgnTemp );
+
+ if( flags & SW_SCROLLCHILDREN )
+ {
+ RECT r;
+ WND *w;
+ for( w =WIN_LockWndPtr(wnd->child); w; WIN_UpdateWndPtr(&w, w->next))
+ {
+ r = w->rectWindow;
+ if( !rect || IntersectRect(&r, &r, &rc) )
+ SetWindowPos(w->hwndSelf, 0, w->rectWindow.left + dx,
+ w->rectWindow.top + dy, 0,0, SWP_NOZORDER |
+ SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW |
+ SWP_DEFERERASE );
+ }
+ }
+
+ if( flags & (SW_INVALIDATE | SW_ERASE) )
+ RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE |
+ ((flags & SW_ERASE) ? RDW_ERASENOW : 0) |
+ ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) );
+
+ if( bCaret )
+ {
+ SetCaretPos( caretrc.left + dx, caretrc.top + dy );
+ ShowCaret(0);
+ }
+
+ if( bOwnRgn && hrgnUpdate ) DeleteObject( hrgnUpdate );
+ DeleteObject( hrgnClip );
+ }
+END:
+ WIN_ReleaseWndPtr(wnd);
+ return retVal;
+}
diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c
index ed3e966..2b54382 100644
--- a/dlls/x11drv/window.c
+++ b/dlls/x11drv/window.c
@@ -21,18 +21,27 @@
#include "dce.h"
#include "options.h"
-DEFAULT_DEBUG_CHANNEL(win);
+DEFAULT_DEBUG_CHANNEL(x11drv);
extern Pixmap X11DRV_BITMAP_Pixmap( HBITMAP );
#define HAS_DLGFRAME(style,exStyle) \
-((!((style) & WS_THICKFRAME)) && (((style) & WS_DLGFRAME) || ((exStyle) & WS_EX_DLGMODALFRAME)))
+ (((exStyle) & WS_EX_DLGMODALFRAME) || \
+ (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
+
+#define HAS_THICKFRAME(style,exStyle) \
+ (((style) & WS_THICKFRAME) && \
+ !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
+
+#define HAS_THINFRAME(style) \
+ (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
/* X context to associate a hwnd to an X window */
XContext winContext = 0;
Atom wmProtocols = None;
Atom wmDeleteWindow = None;
+Atom wmTakeFocus = None;
Atom dndProtocol = None;
Atom dndSelection = None;
Atom wmChangeState = None;
@@ -41,51 +50,137 @@
/***********************************************************************
- * X11DRV_register_window
+ * is_window_managed
*
- * Associate an X window to a HWND.
+ * Check if a given window should be managed
*/
-void X11DRV_register_window( Display *display, HWND hwnd, Window win )
+inline static BOOL is_window_managed( WND *win )
{
- if (!winContext) winContext = TSXUniqueContext();
- TSXSaveContext( display, win, winContext, (char *)hwnd );
- TSXSetWMProtocols( display, win, &wmDeleteWindow, 1 );
+ if (!Options.managed) return FALSE;
+
+ /* tray window is always managed */
+ if (win->dwExStyle & WS_EX_TRAYWINDOW) return TRUE;
+ /* child windows are not managed */
+ if (win->dwStyle & WS_CHILD) return FALSE;
+ /* tool windows are not managed */
+ if (win->dwExStyle & WS_EX_TOOLWINDOW) return FALSE;
+ /* windows with caption or thick frame are managed */
+ if ((win->dwStyle & WS_CAPTION) == WS_CAPTION) return TRUE;
+ if (win->dwStyle & WS_THICKFRAME) return TRUE;
+ /* default: not managed */
+ return FALSE;
}
/***********************************************************************
- * set_wm_hint
+ * is_window_top_level
*
- * Set a window manager hint.
+ * Check if a given window is a top level X11 window
*/
-static void set_wm_hint( Display *display, Window win, int hint, int val )
+inline static BOOL is_window_top_level( WND *win )
{
- XWMHints* wm_hints = TSXGetWMHints( display, win );
- if (!wm_hints) wm_hints = TSXAllocWMHints();
- if (wm_hints)
+ return (root_window == DefaultRootWindow(gdi_display) &&
+ win->parent->hwndSelf == GetDesktopWindow());
+}
+
+
+/***********************************************************************
+ * get_window_attributes
+ *
+ * Fill the window attributes structure for an X window
+ */
+static int get_window_attributes( WND *win, XSetWindowAttributes *attr )
+{
+ BOOL is_top_level = is_window_top_level( win );
+ BOOL managed = is_top_level && is_window_managed( win );
+
+ if (managed) win->dwExStyle |= WS_EX_MANAGED;
+ else win->dwExStyle &= ~WS_EX_MANAGED;
+
+ attr->override_redirect = !managed;
+ attr->bit_gravity = ForgetGravity;
+ attr->win_gravity = NorthWestGravity;
+ attr->colormap = X11DRV_PALETTE_PaletteXColormap;
+ attr->backing_store = NotUseful/*WhenMapped*/;
+ attr->save_under = ((win->clsStyle & CS_SAVEBITS) != 0);
+ attr->cursor = None;
+ attr->event_mask = (ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
+ ButtonPressMask | ButtonReleaseMask);
+ if (is_window_top_level( win )) attr->event_mask |= StructureNotifyMask | FocusChangeMask;
+
+ return (CWBitGravity | CWWinGravity | CWBackingStore | CWOverrideRedirect |
+ CWSaveUnder | CWEventMask | CWColormap | CWCursor);
+}
+
+
+/***********************************************************************
+ * get_window_changes
+ *
+ * fill the window changes structure
+ */
+static int get_window_changes( XWindowChanges *changes, const RECT *old, const RECT *new )
+{
+ int mask = 0;
+
+ if (old->right - old->left != new->right - new->left )
{
- 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);
+ if (!(changes->width = new->right - new->left)) changes->width = 1;
+ mask |= CWWidth;
}
+ if (old->bottom - old->top != new->bottom - new->top)
+ {
+ if (!(changes->height = new->bottom - new->top)) changes->height = 1;
+ mask |= CWHeight;
+ }
+ if (old->left != new->left)
+ {
+ changes->x = new->left;
+ mask |= CWX;
+ }
+ if (old->top != new->top)
+ {
+ changes->y = new->top;
+ mask |= CWY;
+ }
+ return mask;
+}
+
+
+/***********************************************************************
+ * create_icon_window
+ */
+static Window create_icon_window( Display *display, WND *win )
+{
+ struct x11drv_win_data *data = win->pDriverData;
+ XSetWindowAttributes attr;
+
+ attr.event_mask = (ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
+ ButtonPressMask | ButtonReleaseMask);
+ attr.bit_gravity = NorthWestGravity;
+ attr.backing_store = NotUseful/*WhenMapped*/;
+
+ data->icon_window = TSXCreateWindow( display, root_window, 0, 0,
+ GetSystemMetrics( SM_CXICON ),
+ GetSystemMetrics( SM_CYICON ),
+ 0, screen_depth,
+ InputOutput, visual,
+ CWEventMask | CWBitGravity | CWBackingStore, &attr );
+ XSaveContext( display, data->icon_window, winContext, (char *)win->hwndSelf );
+ TRACE( "created %lx\n", data->icon_window );
+ return data->icon_window;
+}
+
+
+
+/***********************************************************************
+ * destroy_icon_window
+ */
+inline static void destroy_icon_window( Display *display, struct x11drv_win_data *data )
+{
+ if (!data->icon_window) return;
+ XDeleteContext( display, data->icon_window, winContext );
+ XDestroyWindow( display, data->icon_window );
+ data->icon_window = 0;
}
@@ -106,7 +201,9 @@
{
data->hWMIconBitmap = 0;
data->hWMIconMask = 0;
- hints->flags &= ~(IconPixmapHint | IconMaskHint);
+ if (!data->icon_window) create_icon_window( display, wndPtr );
+ hints->icon_window = data->icon_window;
+ hints->flags = (hints->flags & ~(IconPixmapHint | IconMaskHint)) | IconWindowHint;
}
else
{
@@ -138,31 +235,338 @@
hints->icon_pixmap = X11DRV_BITMAP_Pixmap(data->hWMIconBitmap);
hints->icon_mask = X11DRV_BITMAP_Pixmap(data->hWMIconMask);
- hints->flags |= IconPixmapHint | IconMaskHint;
+ destroy_icon_window( display, data );
+ hints->flags = (hints->flags & ~IconWindowHint) | IconPixmapHint | IconMaskHint;
}
}
/***********************************************************************
- * dock_window
+ * set_size_hints
*
- * 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 ;)
+ * set the window size hints
*/
-inline static void dock_window( Display *display, Window win )
+static void set_size_hints( Display *display, WND *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 );
+ XSizeHints* size_hints;
+ struct x11drv_win_data *data = win->pDriverData;
+
+ if ((size_hints = XAllocSizeHints()))
+ {
+ size_hints->win_gravity = StaticGravity;
+ size_hints->x = data->whole_rect.left;
+ size_hints->y = data->whole_rect.top;
+ size_hints->flags = PWinGravity | PPosition;
+
+ if (HAS_DLGFRAME( win->dwStyle, win->dwExStyle ))
+ {
+ size_hints->max_width = data->whole_rect.right - data->whole_rect.left;
+ size_hints->max_height = data->whole_rect.bottom - data->whole_rect.top;
+ size_hints->min_width = size_hints->max_width;
+ size_hints->min_height = size_hints->max_height;
+ size_hints->flags |= PMinSize | PMaxSize;
+ }
+ XSetWMNormalHints( display, data->whole_window, size_hints );
+ XFree( size_hints );
+ }
+}
+
+
+/***********************************************************************
+ * set_wm_hints
+ *
+ * Set the window manager hints for a newly-created window
+ */
+inline static void set_wm_hints( Display *display, WND *win )
+{
+ struct x11drv_win_data *data = win->pDriverData;
+ Window group_leader;
+ XClassHint *class_hints;
+ XWMHints* wm_hints;
+ Atom protocols[2];
+ int i;
+
+ wine_tsx11_lock();
+
+ /* wm protocols */
+ i = 0;
+ protocols[i++] = wmDeleteWindow;
+ if (wmTakeFocus) protocols[i++] = wmTakeFocus;
+ XSetWMProtocols( display, data->whole_window, protocols, i );
+
+ /* class hints */
+ if ((class_hints = XAllocClassHint()))
+ {
+ class_hints->res_name = "wine";
+ class_hints->res_class = "Wine";
+ XSetClassHint( display, data->whole_window, class_hints );
+ XFree( class_hints );
+ }
+
+ /* transient for hint */
+ if (win->owner)
+ {
+ struct x11drv_win_data *owner_data = win->owner->pDriverData;
+ XSetTransientForHint( display, data->whole_window, owner_data->whole_window );
+ group_leader = owner_data->whole_window;
+ }
+ else group_leader = data->whole_window;
+
+ /* wm hints */
+ if ((wm_hints = XAllocWMHints()))
+ {
+ wm_hints->flags = InputHint | StateHint | WindowGroupHint;
+ /* use globally active model if take focus is supported,
+ * passive model otherwise (cf. ICCCM) */
+ wm_hints->input = !wmTakeFocus;
+
+ set_icon_hints( display, win, wm_hints );
+
+ wm_hints->initial_state = (win->dwStyle & WS_MINIMIZE) ? IconicState : NormalState;
+ wm_hints->window_group = group_leader;
+
+ XSetWMHints( display, data->whole_window, wm_hints );
+ XFree(wm_hints);
+ }
+
+ /* size hints */
+ set_size_hints( display, win );
+
+ /* systray properties (KDE only for now) */
+ if (win->dwExStyle & WS_EX_TRAYWINDOW)
+ {
+ int val = 1;
+ if (kwmDockWindow != None)
+ TSXChangeProperty( display, data->whole_window, kwmDockWindow, kwmDockWindow,
+ 32, PropModeReplace, (char*)&val, 1 );
+ if (_kde_net_wm_system_tray_window_for != None)
+ TSXChangeProperty( display, data->whole_window, _kde_net_wm_system_tray_window_for,
+ XA_WINDOW, 32, PropModeReplace, (char*)&data->whole_window, 1 );
+ }
+
+ wine_tsx11_unlock();
+}
+
+
+/***********************************************************************
+ * X11DRV_set_iconic_state
+ *
+ * Set the X11 iconic state according to the window style.
+ */
+void X11DRV_set_iconic_state( WND *win )
+{
+ Display *display = thread_display();
+ struct x11drv_win_data *data = win->pDriverData;
+ XWMHints* wm_hints;
+ BOOL iconic = IsIconic( win->hwndSelf );
+
+ if (!(win->dwExStyle & WS_EX_MANAGED))
+ {
+ if (iconic) TSXUnmapWindow( display, data->client_window );
+ else TSXMapWindow( display, data->client_window );
+ }
+
+ wine_tsx11_lock();
+
+ if (!(wm_hints = XGetWMHints( display, data->whole_window ))) wm_hints = XAllocWMHints();
+ wm_hints->flags |= StateHint | IconPositionHint;
+ wm_hints->initial_state = iconic ? IconicState : NormalState;
+ wm_hints->icon_x = win->rectWindow.left;
+ wm_hints->icon_y = win->rectWindow.top;
+ XSetWMHints( display, data->whole_window, wm_hints );
+
+ if (win->dwStyle & WS_VISIBLE)
+ {
+ if (iconic)
+ XIconifyWindow( display, data->whole_window, DefaultScreen(display) );
+ else
+ if (!IsRectEmpty( &win->rectWindow )) XMapWindow( display, data->whole_window );
+ }
+
+ XFree(wm_hints);
+ wine_tsx11_unlock();
+}
+
+
+/***********************************************************************
+ * X11DRV_window_to_X_rect
+ *
+ * Convert a rect from client to X window coordinates
+ */
+void X11DRV_window_to_X_rect( WND *win, RECT *rect )
+{
+ if (!(win->dwExStyle & WS_EX_MANAGED)) return;
+ if (win->dwStyle & WS_ICONIC) return;
+ if (IsRectEmpty( rect )) return;
+
+ if (HAS_THICKFRAME( win->dwStyle, win->dwExStyle ))
+ InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
+ else if (HAS_DLGFRAME( win->dwStyle, win->dwExStyle ))
+ InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME) );
+ else if (HAS_THINFRAME( win->dwStyle ))
+ InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
+
+ if ((win->dwStyle & WS_CAPTION) == WS_CAPTION)
+ {
+ if (win->dwExStyle & WS_EX_TOOLWINDOW)
+ rect->top += GetSystemMetrics(SM_CYSMCAPTION);
+ else
+ rect->top += GetSystemMetrics(SM_CYCAPTION);
+ }
+
+ if (win->dwExStyle & WS_EX_CLIENTEDGE)
+ InflateRect( rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE) );
+ if (win->dwExStyle & WS_EX_STATICEDGE)
+ InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
+
+ if (rect->top >= rect->bottom) rect->bottom = rect->top + 1;
+ if (rect->left >= rect->right) rect->right = rect->left + 1;
+}
+
+
+/***********************************************************************
+ * X11DRV_X_to_window_rect
+ *
+ * Opposite of X11DRV_window_to_X_rect
+ */
+void X11DRV_X_to_window_rect( WND *win, RECT *rect )
+{
+ if (!(win->dwExStyle & WS_EX_MANAGED)) return;
+ if (win->dwStyle & WS_ICONIC) return;
+ if (IsRectEmpty( rect )) return;
+
+ if (HAS_THICKFRAME( win->dwStyle, win->dwExStyle ))
+ InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
+ else if (HAS_DLGFRAME( win->dwStyle, win->dwExStyle ))
+ InflateRect( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
+ else if (HAS_THINFRAME( win->dwStyle ))
+ InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER) );
+
+ if ((win->dwStyle & WS_CAPTION) == WS_CAPTION)
+ {
+ if (win->dwExStyle & WS_EX_TOOLWINDOW)
+ rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
+ else
+ rect->top -= GetSystemMetrics(SM_CYCAPTION);
+ }
+
+ if (win->dwExStyle & WS_EX_CLIENTEDGE)
+ InflateRect( rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE) );
+ if (win->dwExStyle & WS_EX_STATICEDGE)
+ InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER) );
+
+ if (rect->top >= rect->bottom) rect->bottom = rect->top + 1;
+ if (rect->left >= rect->right) rect->right = rect->left + 1;
+}
+
+
+/***********************************************************************
+ * X11DRV_sync_whole_window_position
+ *
+ * Synchronize the X whole window position with the Windows one
+ */
+int X11DRV_sync_whole_window_position( Display *display, WND *win, int zorder )
+{
+ XWindowChanges changes;
+ int mask;
+ struct x11drv_win_data *data = win->pDriverData;
+ RECT whole_rect = win->rectWindow;
+
+ X11DRV_window_to_X_rect( win, &whole_rect );
+ mask = get_window_changes( &changes, &data->whole_rect, &whole_rect );
+
+ if (zorder)
+ {
+ /* find window that this one must be after */
+ WND *prev = win->parent->child;
+ if (prev == win) /* top child */
+ {
+ changes.stack_mode = Above;
+ mask |= CWStackMode;
+ }
+ else
+ {
+ while (prev && prev->next != win) prev = prev->next;
+ if (prev)
+ {
+ changes.stack_mode = Below;
+ changes.sibling = get_whole_window(prev);
+ mask |= CWStackMode | CWSibling;
+ }
+ else ERR( "previous window not found for %x, list corrupted?\n", win->hwndSelf );
+ }
+ }
+
+ data->whole_rect = whole_rect;
+
+ if (mask)
+ {
+ TRACE( "setting win %lx pos %d,%d,%dx%d after %lx changes=%x\n",
+ data->whole_window, whole_rect.left, whole_rect.top,
+ whole_rect.right - whole_rect.left, whole_rect.bottom - whole_rect.top,
+ changes.sibling, mask );
+ wine_tsx11_lock();
+ XSync( gdi_display, False ); /* flush graphics operations before moving the window */
+ if (is_window_top_level( win ))
+ {
+ if (mask & (CWWidth|CWHeight)) set_size_hints( display, win );
+ XReconfigureWMWindow( display, data->whole_window,
+ DefaultScreen(display), mask, &changes );
+ }
+ else XConfigureWindow( display, data->whole_window, mask, &changes );
+ wine_tsx11_unlock();
+ }
+ return mask;
+}
+
+
+/***********************************************************************
+ * X11DRV_sync_client_window_position
+ *
+ * Synchronize the X client window position with the Windows one
+ */
+int X11DRV_sync_client_window_position( Display *display, WND *win )
+{
+ XWindowChanges changes;
+ int mask;
+ struct x11drv_win_data *data = win->pDriverData;
+ RECT client_rect = win->rectClient;
+
+ OffsetRect( &client_rect, -data->whole_rect.left, -data->whole_rect.top );
+ /* client rect cannot be empty */
+ if (client_rect.top >= client_rect.bottom) client_rect.bottom = client_rect.top + 1;
+ if (client_rect.left >= client_rect.right) client_rect.right = client_rect.left + 1;
+
+ if ((mask = get_window_changes( &changes, &data->client_rect, &client_rect )))
+ {
+ TRACE( "setting win %lx pos %d,%d,%dx%d (was %d,%d,%dx%d) after %lx changes=%x\n",
+ data->client_window, client_rect.left, client_rect.top,
+ client_rect.right - client_rect.left, client_rect.bottom - client_rect.top,
+ data->client_rect.left, data->client_rect.top,
+ data->client_rect.right - data->client_rect.left,
+ data->client_rect.bottom - data->client_rect.top,
+ changes.sibling, mask );
+ data->client_rect = client_rect;
+ wine_tsx11_lock();
+ XSync( gdi_display, False ); /* flush graphics operations before moving the window */
+ XConfigureWindow( display, data->client_window, mask, &changes );
+ wine_tsx11_unlock();
+ }
+ return mask;
+}
+
+
+/***********************************************************************
+ * X11DRV_register_window
+ *
+ * Associate an X window to a HWND.
+ */
+void X11DRV_register_window( Display *display, HWND hwnd, struct x11drv_win_data *data )
+{
+ wine_tsx11_lock();
+ XSaveContext( display, data->whole_window, winContext, (char *)hwnd );
+ XSaveContext( display, data->client_window, winContext, (char *)hwnd );
+ wine_tsx11_unlock();
}
@@ -173,15 +577,20 @@
{
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 );
+ wine_tsx11_lock();
+ winContext = XUniqueContext();
+ wmProtocols = XInternAtom( display, "WM_PROTOCOLS", False );
+ wmDeleteWindow = XInternAtom( display, "WM_DELETE_WINDOW", False );
+/* wmTakeFocus = XInternAtom( display, "WM_TAKE_FOCUS", False );*/
+ wmTakeFocus = 0; /* not yet */
+ dndProtocol = XInternAtom( display, "DndProtocol" , False );
+ dndSelection = XInternAtom( display, "DndSelection" , False );
+ wmChangeState = XInternAtom (display, "WM_CHANGE_STATE", False);
+ kwmDockWindow = XInternAtom( display, "KWM_DOCKWINDOW", False );
+ _kde_net_wm_system_tray_window_for = XInternAtom( display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False );
+ wine_tsx11_unlock();
- data->window = root_window;
+ data->whole_window = data->client_window = root_window;
if (root_window != DefaultRootWindow(display))
{
wndPtr->flags |= WIN_NATIVE;
@@ -191,167 +600,133 @@
/**********************************************************************
- * CreateWindow (X11DRV.@)
+ * create_whole_window
+ *
+ * Create the whole X window for a given window
*/
-BOOL X11DRV_CreateWindow( HWND hwnd )
+static Window create_whole_window( Display *display, WND *win )
+{
+ struct x11drv_win_data *data = win->pDriverData;
+ int cx, cy, mask;
+ XSetWindowAttributes attr;
+ Window parent;
+ RECT rect;
+ BOOL is_top_level = is_window_top_level( win );
+
+ mask = get_window_attributes( win, &attr );
+
+ rect = win->rectWindow;
+ X11DRV_window_to_X_rect( win, &rect );
+
+ if (!(cx = rect.right - rect.left)) cx = 1;
+ if (!(cy = rect.bottom - rect.top)) cy = 1;
+
+ parent = get_client_window( win->parent );
+
+ wine_tsx11_lock();
+
+ if (is_top_level) attr.cursor = X11DRV_GetCursor( display, GlobalLock16(GetCursor()) );
+ data->whole_rect = rect;
+ data->whole_window = XCreateWindow( display, parent, rect.left, rect.top, cx, cy,
+ 0, screen_depth, InputOutput, visual,
+ mask, &attr );
+ if (attr.cursor) XFreeCursor( display, attr.cursor );
+
+ if (!data->whole_window) goto done;
+
+ /* non-maximized child must be at bottom of Z order */
+ if ((win->dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
+ {
+ XWindowChanges changes;
+ changes.stack_mode = Below;
+ XConfigureWindow( display, data->whole_window, CWStackMode, &changes );
+ }
+
+ if (is_top_level && !attr.override_redirect) set_wm_hints( display, win );
+
+ done:
+ wine_tsx11_unlock();
+ return data->whole_window;
+}
+
+
+/**********************************************************************
+ * create_client_window
+ *
+ * Create the client window for a given window
+ */
+static Window create_client_window( Display *display, WND *win )
+{
+ struct x11drv_win_data *data = win->pDriverData;
+ RECT rect;
+ XSetWindowAttributes attr;
+
+ rect = win->rectWindow;
+ SendMessageW( win->hwndSelf, WM_NCCALCSIZE, FALSE, (LPARAM)&rect );
+
+ if (rect.left > rect.right || rect.top > rect.bottom) rect = win->rectWindow;
+ if (rect.top >= rect.bottom) rect.bottom = rect.top + 1;
+ if (rect.left >= rect.right) rect.right = rect.left + 1;
+
+ win->rectClient = rect;
+ OffsetRect( &rect, -data->whole_rect.left, -data->whole_rect.top );
+ data->client_rect = rect;
+
+ attr.event_mask = (ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
+ ButtonPressMask | ButtonReleaseMask);
+ attr.bit_gravity = (win->clsStyle & (CS_VREDRAW | CS_HREDRAW)) ?
+ ForgetGravity : NorthWestGravity;
+ attr.backing_store = NotUseful/*WhenMapped*/;
+
+ data->client_window = TSXCreateWindow( display, data->whole_window,
+ rect.left, rect.top,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ 0, screen_depth,
+ InputOutput, visual,
+ CWEventMask | CWBitGravity | CWBackingStore, &attr );
+ if (data->client_window) TSXMapWindow( display, data->client_window );
+ return data->client_window;
+}
+
+
+/*****************************************************************
+ * SetWindowText (X11DRV.@)
+ */
+BOOL X11DRV_SetWindowText( HWND hwnd, LPCWSTR text )
{
Display *display = thread_display();
- X11DRV_WND_DATA *data;
+ UINT count;
+ char *buffer;
+ static UINT text_cp = (UINT)-1;
+ Window win;
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))))
+ if (!wndPtr) return FALSE;
+ if ((win = get_whole_window(wndPtr)))
{
- WIN_ReleaseWndPtr( wndPtr );
- return FALSE;
- }
- data->window = 0;
- wndPtr->pDriverData = data;
-
- if (!wndPtr->parent)
- {
- create_desktop( display, 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))
+ if (text_cp == (UINT)-1)
{
- win_attr.event_mask = ExposureMask | KeyPressMask |
- KeyReleaseMask | PointerMotionMask |
- ButtonPressMask | ButtonReleaseMask |
- FocusChangeMask | StructureNotifyMask;
- win_attr.override_redirect = FALSE;
- wndPtr->dwExStyle |= WS_EX_MANAGED;
+ text_cp = PROFILE_GetWineIniInt("x11drv", "TextCP", CP_ACP);
+ TRACE("text_cp = %u\n", text_cp);
}
- else
+
+ /* 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) )))
{
- win_attr.event_mask = ExposureMask | KeyPressMask |
- KeyReleaseMask | PointerMotionMask |
- ButtonPressMask | ButtonReleaseMask |
- FocusChangeMask;
- win_attr.override_redirect = TRUE;
- }
- wndPtr->flags |= WIN_NATIVE;
-
- wine_tsx11_lock();
-
- 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_GetCursor( display, GlobalLock16(GetCursor()) );
-
- 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 = XCreateWindow( display, root_window,
- x, y, cx, cy,
- 0, screen_depth,
- InputOutput, visual,
- CWEventMask | CWOverrideRedirect |
- CWColormap | CWCursor | CWSaveUnder |
- CWBackingStore | CWBitGravity,
- &win_attr );
-
- if (win_attr.cursor) XFreeCursor( display, win_attr.cursor );
- wine_tsx11_unlock();
-
- if(!(wGroupLeader = data->window))
- {
- HeapFree( GetProcessHeap(), 0, data );
+ ERR("Not enough memory for window text\n");
WIN_ReleaseWndPtr( wndPtr );
return FALSE;
}
+ WideCharToMultiByte(text_cp, 0, text, -1, buffer, count, NULL, NULL);
- /* If we are the systray, we need to be managed to be noticed by KWM */
- if (wndPtr->dwExStyle & WS_EX_TRAYWINDOW) dock_window( display, data->window );
+ wine_tsx11_lock();
+ XStoreName( display, win, buffer );
+ XSetIconName( display, win, buffer );
+ wine_tsx11_unlock();
- 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( display, 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_register_window( display, hwnd, data->window );
- TSXFlush( display );
+ HeapFree( GetProcessHeap(), 0, buffer );
}
WIN_ReleaseWndPtr( wndPtr );
return TRUE;
@@ -366,37 +741,209 @@
Display *display = thread_display();
WND *wndPtr = WIN_FindWndPtr( hwnd );
X11DRV_WND_DATA *data = wndPtr->pDriverData;
- Window w;
- if (data && (w = data->window))
+ if (!data) goto done;
+
+ if (data->whole_window)
{
- XEvent xe;
+ TRACE( "win %x xwin %lx/%lx\n", hwnd, data->whole_window, data->client_window );
wine_tsx11_lock();
XSync( gdi_display, False ); /* flush any reference to this drawable in GDI queue */
- XDeleteContext( display, w, winContext );
- XDestroyWindow( display, w );
- while( XCheckWindowEvent(display, w, NoEventMask, &xe) );
+ XDeleteContext( display, data->whole_window, winContext );
+ XDeleteContext( display, data->client_window, winContext );
+ XDestroyWindow( display, data->whole_window ); /* this destroys client too */
+ destroy_icon_window( display, data );
wine_tsx11_unlock();
-
- data->window = None;
- if( data->hWMIconBitmap )
- {
- DeleteObject( data->hWMIconBitmap );
- data->hWMIconBitmap = 0;
- }
- if( data->hWMIconMask )
- {
- DeleteObject( data->hWMIconMask);
- data->hWMIconMask= 0;
- }
}
+
+ if (data->hWMIconBitmap) DeleteObject( data->hWMIconBitmap );
+ if (data->hWMIconMask) DeleteObject( data->hWMIconMask);
HeapFree( GetProcessHeap(), 0, data );
wndPtr->pDriverData = NULL;
+ done:
WIN_ReleaseWndPtr( wndPtr );
return TRUE;
}
+/**********************************************************************
+ * CreateWindow (X11DRV.@)
+ */
+BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs )
+{
+ Display *display = thread_display();
+ WND *wndPtr;
+ struct x11drv_win_data *data;
+ BOOL ret = FALSE;
+
+ if (!(data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data)))) return FALSE;
+ data->whole_window = 0;
+ data->client_window = 0;
+ data->icon_window = 0;
+ data->hWMIconBitmap = 0;
+ data->hWMIconMask = 0;
+
+ wndPtr = WIN_FindWndPtr( hwnd );
+ wndPtr->pDriverData = data;
+ wndPtr->flags |= WIN_NATIVE;
+ WIN_ReleaseWndPtr( wndPtr );
+
+ if (IsWindowUnicode( hwnd ))
+ ret = SendMessageW( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
+ else
+ ret = SendMessageA( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
+
+ if (!ret) goto failed;
+
+ TRACE( "hwnd %x cs %d,%d %dx%d\n", hwnd, cs->x, cs->y, cs->cx, cs->cy );
+
+ if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
+
+ if (!wndPtr->parent)
+ {
+ create_desktop( display, wndPtr );
+ WIN_ReleaseWndPtr( wndPtr );
+ return TRUE;
+ }
+
+ if (!create_whole_window( display, wndPtr )) goto failed;
+ if (!create_client_window( display, wndPtr )) goto failed;
+ TSXSync( display, False );
+
+ TRACE( "win %x window %d,%d,%d,%d client %d,%d,%d,%d whole %d,%d,%d,%d X client %d,%d,%d,%d xwin %x/%x\n",
+ hwnd, wndPtr->rectWindow.left, wndPtr->rectWindow.top,
+ wndPtr->rectWindow.right, wndPtr->rectWindow.bottom,
+ wndPtr->rectClient.left, wndPtr->rectClient.top,
+ wndPtr->rectClient.right, wndPtr->rectClient.bottom,
+ data->whole_rect.left, data->whole_rect.top,
+ data->whole_rect.right, data->whole_rect.bottom,
+ data->client_rect.left, data->client_rect.top,
+ data->client_rect.right, data->client_rect.bottom,
+ (unsigned int)data->whole_window, (unsigned int)data->client_window );
+
+ if ((wndPtr->dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
+ WIN_LinkWindow( hwnd, HWND_BOTTOM );
+ else
+ WIN_LinkWindow( hwnd, HWND_TOP );
+
+ if (wndPtr->text) X11DRV_SetWindowText( hwnd, wndPtr->text );
+ X11DRV_register_window( display, hwnd, data );
+ WIN_ReleaseWndPtr( wndPtr );
+
+ if (IsWindowUnicode( hwnd ))
+ ret = (SendMessageW( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
+ else
+ ret = (SendMessageA( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
+
+ if (!ret)
+ {
+ WIN_UnlinkWindow( hwnd );
+ goto failed;
+ }
+
+ /* Send the size messages */
+
+ if (!(wndPtr->flags & WIN_NEED_SIZE))
+ {
+ /* send it anyway */
+ if (((wndPtr->rectClient.right-wndPtr->rectClient.left) <0)
+ ||((wndPtr->rectClient.bottom-wndPtr->rectClient.top)<0))
+ WARN("sending bogus WM_SIZE message 0x%08lx\n",
+ MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
+ wndPtr->rectClient.bottom-wndPtr->rectClient.top));
+ SendMessageW( hwnd, WM_SIZE, SIZE_RESTORED,
+ MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
+ wndPtr->rectClient.bottom-wndPtr->rectClient.top));
+ SendMessageW( hwnd, WM_MOVE, 0,
+ MAKELONG( wndPtr->rectClient.left, wndPtr->rectClient.top ) );
+ }
+
+ /* Show the window, maximizing or minimizing if needed */
+
+ if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
+ {
+ extern UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ); /*FIXME*/
+
+ RECT newPos;
+ UINT swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
+ wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
+ WINPOS_MinMaximize( hwnd, swFlag, &newPos );
+ swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow())
+ ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
+ : SWP_NOZORDER | SWP_FRAMECHANGED;
+ SetWindowPos( hwnd, 0, newPos.left, newPos.top,
+ newPos.right, newPos.bottom, swFlag );
+ }
+
+ return TRUE;
+
+
+ failed:
+ X11DRV_DestroyWindow( wndPtr->hwndSelf );
+ WIN_ReleaseWndPtr( wndPtr );
+ return FALSE;
+}
+
+
+/***********************************************************************
+ * X11DRV_get_client_window
+ *
+ * Return the X window associated with the client area of a window
+ */
+Window X11DRV_get_client_window( HWND hwnd )
+{
+ Window ret = 0;
+ WND *win = WIN_FindWndPtr( hwnd );
+ if (win)
+ {
+ struct x11drv_win_data *data = win->pDriverData;
+ ret = data->client_window;
+ WIN_ReleaseWndPtr( win );
+ }
+ return ret;
+}
+
+
+/***********************************************************************
+ * X11DRV_get_whole_window
+ *
+ * Return the X window associated with the full area of a window
+ */
+Window X11DRV_get_whole_window( HWND hwnd )
+{
+ Window ret = 0;
+ WND *win = WIN_FindWndPtr( hwnd );
+ if (win)
+ {
+ struct x11drv_win_data *data = win->pDriverData;
+ ret = data->whole_window;
+ WIN_ReleaseWndPtr( win );
+ }
+ return ret;
+}
+
+
+/***********************************************************************
+ * X11DRV_get_top_window
+ *
+ * Return the X window associated with the top-level parent of a window
+ */
+Window X11DRV_get_top_window( HWND hwnd )
+{
+ Window ret = 0;
+ WND *win = WIN_FindWndPtr( hwnd );
+ while (win && win->parent->hwndSelf != GetDesktopWindow())
+ WIN_UpdateWndPtr( &win, win->parent );
+ if (win)
+ {
+ struct x11drv_win_data *data = win->pDriverData;
+ ret = data->whole_window;
+ WIN_ReleaseWndPtr( win );
+ }
+ return ret;
+}
+
+
/*****************************************************************
* SetParent (X11DRV.@)
*/
@@ -427,34 +974,32 @@
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;
- }
+ struct x11drv_win_data *data = wndPtr->pDriverData;
+ int mask;
+ XSetWindowAttributes attr;
+
WIN_UnlinkWindow(wndPtr->hwndSelf);
wndPtr->parent = pWndParent;
+ WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP);
- /* Create an X counterpart for reparented top-level windows
- * when not in the desktop mode. */
- if (parent == GetDesktopWindow())
+ mask = get_window_attributes( wndPtr, &attr );
+ if (is_window_top_level( wndPtr ) && !attr.override_redirect)
+ set_wm_hints( display, wndPtr );
+
+ if (parent != GetDesktopWindow()) /* a child window */
{
- if(root_window == DefaultRootWindow(display))
- X11DRV_CreateWindow(wndPtr->hwndSelf);
- }
- else /* a child window */
- {
- if( !( wndPtr->dwStyle & WS_CHILD ) )
+ if (!(wndPtr->dwStyle & WS_CHILD) && wndPtr->wIDmenu)
{
- if( wndPtr->wIDmenu != 0)
- {
- DestroyMenu( (HMENU) wndPtr->wIDmenu );
- wndPtr->wIDmenu = 0;
- }
+ DestroyMenu( (HMENU)wndPtr->wIDmenu );
+ wndPtr->wIDmenu = 0;
}
}
- WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP);
+
+ wine_tsx11_lock();
+ XChangeWindowAttributes( display, data->whole_window, mask, &attr );
+ XReparentWindow( display, data->whole_window, get_client_window(pWndParent),
+ data->whole_rect.left, data->whole_rect.top );
+ wine_tsx11_unlock();
}
WIN_ReleaseWndPtr( pWndParent );
WIN_ReleaseWndPtr( wndPtr );
@@ -479,9 +1024,9 @@
BOOL X11DRV_EnableWindow( HWND hwnd, BOOL enable )
{
Display *display = thread_display();
+ XWMHints *wm_hints;
WND *wndPtr;
BOOL retvalue;
- Window w;
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
@@ -492,8 +1037,20 @@
/* Enable window */
wndPtr->dwStyle &= ~WS_DISABLED;
- if ((wndPtr->dwExStyle & WS_EX_MANAGED) && (w = X11DRV_WND_GetXWindow( wndPtr )))
- set_wm_hint( display, w, InputHint, TRUE );
+ if (wndPtr->dwExStyle & WS_EX_MANAGED)
+ {
+ wine_tsx11_lock();
+ if (!(wm_hints = XGetWMHints( display, get_whole_window(wndPtr) )))
+ wm_hints = XAllocWMHints();
+ if (wm_hints)
+ {
+ wm_hints->flags |= InputHint;
+ wm_hints->input = TRUE;
+ XSetWMHints( display, get_whole_window(wndPtr), wm_hints );
+ XFree(wm_hints);
+ }
+ wine_tsx11_unlock();
+ }
SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
}
@@ -504,8 +1061,20 @@
/* Disable window */
wndPtr->dwStyle |= WS_DISABLED;
- if ((wndPtr->dwExStyle & WS_EX_MANAGED) && (w = X11DRV_WND_GetXWindow( wndPtr )))
- set_wm_hint( display, w, InputHint, FALSE );
+ if (wndPtr->dwExStyle & WS_EX_MANAGED)
+ {
+ wine_tsx11_lock();
+ if (!(wm_hints = XGetWMHints( display, get_whole_window(wndPtr) )))
+ wm_hints = XAllocWMHints();
+ if (wm_hints)
+ {
+ wm_hints->flags |= InputHint;
+ wm_hints->input = FALSE;
+ XSetWMHints( display, get_whole_window(wndPtr), wm_hints );
+ XFree(wm_hints);
+ }
+ wine_tsx11_unlock();
+ }
if (hwnd == GetFocus())
SetFocus( 0 ); /* A disabled window can't have the focus */
@@ -540,9 +1109,8 @@
/* 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;
+ while (w && !get_whole_window(w)) w = w->parent;
+ if (!w) goto done;
if (w->dwExStyle & WS_EX_MANAGED) goto done;
if (!hwnd) /* If setting the focus to 0, uninstall the colormap */
@@ -550,18 +1118,23 @@
if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
TSXUninstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
}
- else if ((win = X11DRV_WND_FindXWindow(wndPtr)))
+ else if ((win = get_whole_window(w)))
{
/* Set X focus and install colormap */
- if (TSXGetWindowAttributes( display, win, &win_attr ) &&
+ wine_tsx11_lock();
+ if (XGetWindowAttributes( display, win, &win_attr ) &&
(win_attr.map_state == IsViewable))
{
/* If window is not viewable, don't change anything */
- TSXSetInputFocus( display, win, RevertToParent, CurrentTime );
+
+ /* we must not use CurrentTime (ICCCM), so try to use last message time instead */
+ /* FIXME: this is not entirely correct */
+ XSetInputFocus( display, win, RevertToParent,
+ /*CurrentTime*/ GetMessageTime() + X11DRV_server_startticks );
if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
- TSXInstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
- X11DRV_Synchronize();
+ XInstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
}
+ wine_tsx11_unlock();
}
done:
@@ -569,46 +1142,6 @@
}
-/*****************************************************************
- * SetWindowText (X11DRV.@)
- */
-BOOL X11DRV_SetWindowText( HWND hwnd, LPCWSTR text )
-{
- Display *display = thread_display();
- 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
*
@@ -636,7 +1169,7 @@
if (wndPtr->dwExStyle & WS_EX_MANAGED)
{
- Window win = X11DRV_WND_GetXWindow(wndPtr);
+ Window win = get_whole_window(wndPtr);
XWMHints* wm_hints = TSXGetWMHints( display, win );
if (!wm_hints) wm_hints = TSXAllocWMHints();
@@ -651,154 +1184,3 @@
WIN_ReleaseWndPtr( wndPtr );
return old;
}
-
-
-/*************************************************************************
- * fix_caret
- */
-static BOOL fix_caret(HWND hWnd, LPRECT lprc, UINT flags)
-{
- HWND hCaret = CARET_GetHwnd();
-
- if( hCaret )
- {
- RECT rc;
- CARET_GetRect( &rc );
- if( hCaret == hWnd ||
- (flags & SW_SCROLLCHILDREN && IsChild(hWnd, hCaret)) )
- {
- POINT pt;
- pt.x = rc.left;
- pt.y = rc.top;
- MapWindowPoints( hCaret, hWnd, (LPPOINT)&rc, 2 );
- if( IntersectRect(lprc, lprc, &rc) )
- {
- HideCaret(0);
- lprc->left = pt.x;
- lprc->top = pt.y;
- return TRUE;
- }
- }
- }
- return FALSE;
-}
-
-
-/*************************************************************************
- * ScrollWindowEx (X11DRV.@)
- */
-INT X11DRV_ScrollWindowEx( HWND hwnd, INT dx, INT dy,
- const RECT *rect, const RECT *clipRect,
- HRGN hrgnUpdate, LPRECT rcUpdate, UINT flags )
-{
- INT retVal = NULLREGION;
- BOOL bCaret = FALSE, bOwnRgn = TRUE;
- RECT rc, cliprc;
- WND* wnd = WIN_FindWndPtr( hwnd );
-
- if( !wnd || !WIN_IsWindowDrawable( wnd, TRUE ))
- {
- retVal = ERROR;
- goto END;
- }
-
- GetClientRect(hwnd, &rc);
- if (rect) IntersectRect(&rc, &rc, rect);
-
- if (clipRect) IntersectRect(&cliprc,&rc,clipRect);
- else cliprc = rc;
-
- if (!IsRectEmpty(&cliprc) && (dx || dy))
- {
- HDC hDC;
- BOOL bUpdate = (rcUpdate || hrgnUpdate || flags & (SW_INVALIDATE | SW_ERASE));
- HRGN hrgnClip = CreateRectRgnIndirect(&cliprc);
- HRGN hrgnTemp = CreateRectRgnIndirect(&rc);
- RECT caretrc;
-
- TRACE("%04x, %d,%d hrgnUpdate=%04x rcUpdate = %p cliprc = (%d,%d-%d,%d), rc=(%d,%d-%d,%d) %04x\n",
- (HWND16)hwnd, dx, dy, hrgnUpdate, rcUpdate,
- clipRect?clipRect->left:0, clipRect?clipRect->top:0,
- clipRect?clipRect->right:0, clipRect?clipRect->bottom:0,
- rc.left, rc.top, rc.right, rc.bottom, (UINT16)flags );
-
- caretrc = rc;
- bCaret = fix_caret(hwnd, &caretrc, flags);
-
- if( hrgnUpdate ) bOwnRgn = FALSE;
- else if( bUpdate ) hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );
-
- hDC = GetDCEx( hwnd, hrgnClip, DCX_CACHE | DCX_USESTYLE |
- DCX_KEEPCLIPRGN | DCX_INTERSECTRGN |
- ((flags & SW_SCROLLCHILDREN) ? DCX_NOCLIPCHILDREN : 0) );
- if (hDC)
- {
- X11DRV_WND_SurfaceCopy(wnd,hDC,dx,dy,&rc,bUpdate);
- if( bUpdate )
- {
- DC* dc;
-
- if( (dc = DC_GetDCPtr(hDC)) )
- {
- OffsetRgn( hrgnTemp, dc->DCOrgX, dc->DCOrgY );
- CombineRgn( hrgnTemp, hrgnTemp, dc->hVisRgn,
- RGN_AND );
- OffsetRgn( hrgnTemp, -dc->DCOrgX, -dc->DCOrgY );
- CombineRgn( hrgnUpdate, hrgnTemp, hrgnClip,
- RGN_AND );
- OffsetRgn( hrgnTemp, dx, dy );
- retVal =
- CombineRgn( hrgnUpdate, hrgnUpdate, hrgnTemp,
- RGN_DIFF );
-
- if( rcUpdate ) GetRgnBox( hrgnUpdate, rcUpdate );
- GDI_ReleaseObj( hDC );
- }
- }
- ReleaseDC(hwnd, hDC);
- }
-
- if( wnd->hrgnUpdate > 1 )
- {
- /* Takes into account the fact that some damages may have
- occured during the scroll. */
- CombineRgn( hrgnTemp, wnd->hrgnUpdate, 0, RGN_COPY );
- OffsetRgn( hrgnTemp, dx, dy );
- CombineRgn( hrgnTemp, hrgnTemp, hrgnClip, RGN_AND );
- CombineRgn( wnd->hrgnUpdate, wnd->hrgnUpdate, hrgnTemp, RGN_OR );
- }
-
- if( flags & SW_SCROLLCHILDREN )
- {
- RECT r;
- WND *w;
- for( w =WIN_LockWndPtr(wnd->child); w; WIN_UpdateWndPtr(&w, w->next))
- {
- r = w->rectWindow;
- if( !rect || IntersectRect(&r, &r, &rc) )
- SetWindowPos(w->hwndSelf, 0, w->rectWindow.left + dx,
- w->rectWindow.top + dy, 0,0, SWP_NOZORDER |
- SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW |
- SWP_DEFERERASE );
- }
- }
-
- if( flags & (SW_INVALIDATE | SW_ERASE) )
- RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE |
- ((flags & SW_ERASE) ? RDW_ERASENOW : 0) |
- ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) );
-
- if( bCaret )
- {
- SetCaretPos( caretrc.left + dx, caretrc.top + dy );
- ShowCaret(0);
- }
-
- if( bOwnRgn && hrgnUpdate ) DeleteObject( hrgnUpdate );
- DeleteObject( hrgnClip );
- DeleteObject( hrgnTemp );
- }
-END:
- WIN_ReleaseWndPtr(wnd);
- return retVal;
-}
diff --git a/dlls/x11drv/winpos.c b/dlls/x11drv/winpos.c
index 721bd7b..5fdd44e 100644
--- a/dlls/x11drv/winpos.c
+++ b/dlls/x11drv/winpos.c
@@ -8,6 +8,7 @@
#include "config.h"
#include "ts_xlib.h"
+#include "ts_xutil.h"
#include "ts_shape.h"
#include "winbase.h"
@@ -26,8 +27,7 @@
#include "debugtools.h"
-DEFAULT_DEBUG_CHANNEL(win);
-
+DEFAULT_DEBUG_CHANNEL(x11drv);
#define SWP_AGG_NOGEOMETRYCHANGE \
(SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
@@ -53,480 +53,187 @@
#define ON_BOTTOM_BORDER(hit) \
(((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
-/***********************************************************************
- * 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
+ * clip_children
*
- * 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.
+ * Clip all children of a given window out of the visible region
*/
-static BOOL DCE_GetVisRect( WND *wndPtr, BOOL clientArea, RECT *lprect )
+static void clip_children( WND *win, HRGN hrgn, int whole_window )
{
- *lprect = clientArea ? wndPtr->rectClient : wndPtr->rectWindow;
+ WND *ptr;
+ HRGN rectRgn;
+ int x, y;
- if (wndPtr->dwStyle & WS_VISIBLE)
+ /* first check if we have anything to do */
+ for (ptr = win->child; ptr; ptr = ptr->next)
+ if (ptr->dwStyle & WS_VISIBLE) break;
+ if (!ptr) return; /* no children to clip */
+
+ if (whole_window)
{
- 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;
+ x = win->rectWindow.left - win->rectClient.left;
+ y = win->rectWindow.top - win->rectClient.top;
}
+ else x = y = 0;
-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))
+ rectRgn = CreateRectRgn( 0, 0, 0, 0 );
+ while (ptr)
{
- 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 (ptr->dwStyle & WS_VISIBLE)
{
- if(!REGION_UnionRectWithRgn( hrgnClip, &rect )) break;
+ SetRectRgn( rectRgn, ptr->rectWindow.left + x, ptr->rectWindow.top + y,
+ ptr->rectWindow.right + x, ptr->rectWindow.bottom + y );
+ if (CombineRgn( hrgn, hrgn, rectRgn, RGN_DIFF ) == NULLREGION)
+ break; /* no need to go on, region is empty */
}
+ ptr = ptr->next;
}
- WIN_ReleaseWndPtr(pWndStart);
- return (pWndStart == pWndEnd);
+ DeleteObject( rectRgn );
}
/***********************************************************************
- * DCE_GetVisRgn
+ * get_visible_region
*
- * 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.
+ * Compute the visible region of a window
*/
-static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
+static HRGN get_visible_region( WND *win, UINT flags )
{
- HRGN hrgnVis = 0;
+ HRGN rgn;
RECT rect;
- WND *wndPtr = WIN_FindWndPtr( hwnd );
- WND *childWnd = WIN_FindWndPtr( hwndChild );
+ int xoffset, yoffset;
+ X11DRV_WND_DATA *data = win->pDriverData;
- /* Get visible rectangle and create a region with it. */
-
- if (wndPtr && DCE_GetVisRect(wndPtr, !(flags & DCX_WINDOW), &rect))
+ if (flags & DCX_WINDOW)
{
- 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;
- }
- }
+ xoffset = win->rectWindow.left;
+ yoffset = win->rectWindow.top;
}
else
- hrgnVis = CreateRectRgn(0, 0, 0, 0); /* empty */
- WIN_ReleaseWndPtr(wndPtr);
- WIN_ReleaseWndPtr(childWnd);
- return hrgnVis;
+ {
+ xoffset = win->rectClient.left;
+ yoffset = win->rectClient.top;
+ }
+
+ if (flags & DCX_PARENTCLIP)
+ GetClientRect( win->parent->hwndSelf, &rect );
+ else if (flags & DCX_WINDOW)
+ rect = data->whole_rect;
+ else
+ rect = win->rectClient;
+
+ /* vis region is relative to the start of the client/window area */
+ OffsetRect( &rect, -xoffset, -yoffset );
+
+ if (!(rgn = CreateRectRgn( rect.left, rect.top, rect.right, rect.bottom ))) return 0;
+
+ if (flags & DCX_CLIPCHILDREN)
+ {
+ /* if we are clipping siblings and using the client area,
+ * X will do the clipping for us; otherwise, we need to
+ * clip children by hand here
+ */
+ if ((flags & DCX_WINDOW) || !(flags & DCX_CLIPSIBLINGS))
+ clip_children( win, rgn, (flags & DCX_WINDOW) );
+ }
+ return rgn;
}
/***********************************************************************
- * GetDC (X11DRV.@)
+ * X11DRV_GetDC
*
* 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;
+ WND *win = WIN_FindWndPtr( hwnd );
+ X11DRV_WND_DATA *data = win->pDriverData;
+ Drawable drawable;
+ int org_x, org_y, mode = IncludeInferiors;
- if (!wndPtr) return FALSE;
+ /* don't clip siblings if using parent clip region */
+ if (flags & DCX_PARENTCLIP) flags &= ~DCX_CLIPSIBLINGS;
- if (!(dc = DC_GetDCPtr( hdc )))
+ if (flags & DCX_CLIPSIBLINGS)
{
- 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)
+ if (IsIconic( hwnd ))
{
- 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);
+ drawable = data->icon_window ? data->icon_window : data->whole_window;
+ org_x = 0;
+ org_y = 0;
+ }
+ else if (flags & DCX_WINDOW)
+ {
+ drawable = data->whole_window;
+ org_x = win->rectWindow.left - data->whole_rect.left;
+ org_y = win->rectWindow.top - data->whole_rect.top;
}
else
{
- if ((hwnd == GetDesktopWindow()) && (root_window != DefaultRootWindow(thread_display())))
- hrgnVisible = CreateRectRgn( 0, 0, GetSystemMetrics(SM_CXSCREEN),
- GetSystemMetrics(SM_CYSCREEN) );
- else
- {
- hrgnVisible = DCE_GetVisRgn( hwnd, flags, 0, 0 );
- DCE_OffsetVisRgn( hdc, hrgnVisible );
- }
+ drawable = data->client_window;
+ org_x = 0;
+ org_y = 0;
+ if (flags & DCX_CLIPCHILDREN) mode = ClipByChildren; /* can use X11 clipping */
}
- SelectVisRgn16( hdc, hrgnVisible );
}
-
- /* apply additional region operation (if any) */
-
- if( flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN) )
+ else
{
- 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 );
+ /* not clipping siblings -> have to use parent client drawable */
+ if (win->parent) drawable = get_client_window( win->parent );
+ else drawable = root_window;
+ if (flags & DCX_WINDOW)
+ {
+ org_x = win->rectWindow.left;
+ org_y = win->rectWindow.top;
+ }
+ else
+ {
+ org_x = win->rectClient.left;
+ org_y = win->rectClient.top;
+ }
}
- if (hrgnVisible) DeleteObject( hrgnVisible );
+ X11DRV_SetDrawable( hdc, drawable, mode, org_x, org_y );
- WIN_ReleaseWndPtr( wndPtr );
+ if (flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN) ||
+ SetHookFlags16( hdc, DCHF_VALIDATEVISRGN )) /* DC was dirty */
+ {
+ /* need to recompute the visible region */
+ HRGN visRgn = get_visible_region( win, flags );
+
+ if (flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN))
+ CombineRgn( visRgn, visRgn, hrgn, (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
+
+ /* make it relative to the drawable origin */
+ OffsetRgn( visRgn, org_x, org_y );
+ SelectVisRgn16( hdc, visRgn );
+ DeleteObject( visRgn );
+ }
+
+ WIN_ReleaseWndPtr( win );
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 )
+static BOOL SWP_DoWinPosChanging( WINDOWPOS* pWinpos, RECT* pNewWindowRect, RECT* pNewClientRect )
{
- /* Send WM_WINDOWPOSCHANGING message */
+ WND *wndPtr;
+
+ /* Send WM_WINDOWPOSCHANGING message */
if (!(pWinpos->flags & SWP_NOSENDCHANGING))
- SendMessageA( wndPtr->hwndSelf, WM_WINDOWPOSCHANGING, 0, (LPARAM)pWinpos );
+ SendMessageA( pWinpos->hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)pWinpos );
- /* Calculate new position and size */
+ if (!(wndPtr = WIN_FindWndPtr( pWinpos->hwnd ))) return FALSE;
+
+ /* Calculate new position and size */
*pNewWindowRect = wndPtr->rectWindow;
*pNewClientRect = (wndPtr->dwStyle & WS_MINIMIZE) ? wndPtr->rectWindow
@@ -547,8 +254,8 @@
OffsetRect( pNewClientRect, pWinpos->x - wndPtr->rectWindow.left,
pWinpos->y - wndPtr->rectWindow.top );
}
-
pWinpos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
+ WIN_ReleaseWndPtr( wndPtr );
return TRUE;
}
@@ -556,7 +263,7 @@
* SWP_DoNCCalcSize
*/
static UINT SWP_DoNCCalcSize( WND* wndPtr, WINDOWPOS* pWinpos,
- RECT* pNewWindowRect, RECT* pNewClientRect, WORD f)
+ RECT* pNewWindowRect, RECT* pNewClientRect )
{
UINT wvrFlags = 0;
@@ -566,7 +273,6 @@
wvrFlags = WINPOS_SendNCCalcSize( pWinpos->hwnd, TRUE, pNewWindowRect,
&wndPtr->rectWindow, &wndPtr->rectClient,
pWinpos, pNewClientRect );
-
/* FIXME: WVR_ALIGNxxx */
if( pNewClientRect->left != wndPtr->rectClient.left ||
@@ -580,8 +286,8 @@
pWinpos->flags &= ~SWP_NOCLIENTSIZE;
}
else
- if( !(f & SWP_NOMOVE) && (pNewClientRect->left != wndPtr->rectClient.left ||
- pNewClientRect->top != wndPtr->rectClient.top) )
+ if( !(pWinpos->flags & SWP_NOMOVE) && (pNewClientRect->left != wndPtr->rectClient.left ||
+ pNewClientRect->top != wndPtr->rectClient.top) )
pWinpos->flags &= ~SWP_NOCLIENTMOVE;
return wvrFlags;
}
@@ -640,256 +346,24 @@
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 )
+
+/* fix redundant flags and values in the WINDOWPOS structure */
+static BOOL fixup_flags( WINDOWPOS *winpos )
{
- RECT r;
- HRGN newVisRgn, dirtyRgn;
- INT my = COMPLEXREGION;
- DWORD dflags;
+ WND *wndPtr = WIN_FindWndPtr( winpos->hwnd );
+ BOOL ret = TRUE;
- 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 (!wndPtr) return FALSE;
- 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;
+ 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->flags & SWP_SHOWWINDOW)) winpos->flags |= SWP_NOREDRAW;
}
- if ( winpos->cx < 0 ) winpos->cx = 0;
- if ( winpos->cy < 0 ) winpos->cy = 0;
+ 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))
@@ -898,15 +372,15 @@
if ((wndPtr->rectWindow.left == winpos->x) && (wndPtr->rectWindow.top == winpos->y))
winpos->flags |= SWP_NOMOVE; /* Already the right position */
- if (winpos->hwnd == hwndActive)
+ if (winpos->hwnd == GetForegroundWindow())
winpos->flags |= SWP_NOACTIVATE; /* Already active */
- else if ( (wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD )
+ else if ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD)
{
- if(!(winpos->flags & SWP_NOACTIVATE)) /* Bring to the top when activating */
+ if (!(winpos->flags & SWP_NOACTIVATE)) /* Bring to the top when activating */
{
winpos->flags &= ~SWP_NOZORDER;
winpos->hwndInsertAfter = HWND_TOP;
- goto Pos;
+ goto done;
}
}
@@ -920,64 +394,68 @@
if ((winpos->hwndInsertAfter != HWND_TOP) && (winpos->hwndInsertAfter != HWND_BOTTOM))
{
WND* wnd = WIN_FindWndPtr(winpos->hwndInsertAfter);
-
- if( wnd ) {
- if( wnd->parent != wndPtr->parent )
+ if (wnd)
+ {
+ if (wnd->parent != wndPtr->parent) ret = FALSE;
+ else
{
- 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;
}
- /* 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);
}
- WIN_ReleaseWndPtr(wnd);
}
+ done:
+ WIN_ReleaseWndPtr(wndPtr);
+ return ret;
+}
- Pos: /* ------------------------------------------------------------------------ MAIN part */
- SWP_DoWinPosChanging( wndPtr, winpos, &newWindowRect, &newClientRect );
+/***********************************************************************
+ * SetWindowPos (X11DRV.@)
+ */
+BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
+{
+ WND *wndPtr;
+ RECT newWindowRect, newClientRect;
+ RECT oldWindowRect, oldClientRect;
+ UINT wvrFlags = 0;
+ BOOL bChangePos;
+
+ 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;
+
+ /* Check window handle */
+ if (winpos->hwnd == GetDesktopWindow()) return FALSE;
+
+ /* Fix redundant flags */
+ if (!fixup_flags( winpos )) return FALSE;
+
+ SWP_DoWinPosChanging( winpos, &newWindowRect, &newClientRect );
+
+ 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 );
if((winpos->flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER)
{
- if( wndPtr->parent == WIN_GetDesktop() )
+ if( wndPtr->parent->hwndSelf == GetDesktopWindow() )
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 );
+ wvrFlags = SWP_DoNCCalcSize( wndPtr, winpos, &newWindowRect, &newClientRect );
if(!(winpos->flags & SWP_NOZORDER) && winpos->hwnd != winpos->hwndInsertAfter)
{
@@ -1008,161 +486,81 @@
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 */
+ if (winpos->flags & SWP_SHOWWINDOW) wndPtr->dwStyle |= WS_VISIBLE;
+ else if (winpos->flags & SWP_HIDEWINDOW)
{
- 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 )
- {
+ /* clear the update region */
+ RedrawWindow( winpos->hwnd, NULL, 0, RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE |
+ RDW_NOINTERNALPAINT | RDW_ALLCHILDREN );
wndPtr->dwStyle &= ~WS_VISIBLE;
}
+ if (get_whole_window(wndPtr)) /* don't do anything if X window not created yet */
+ {
+ Display *display = thread_display();
+
+ wine_tsx11_lock();
+ if (!(winpos->flags & SWP_SHOWWINDOW) && (winpos->flags & SWP_HIDEWINDOW))
+ {
+ if (!IsRectEmpty( &oldWindowRect ))
+ {
+ XUnmapWindow( display, get_whole_window(wndPtr) );
+ TRACE( "unmapping win %x\n", winpos->hwnd );
+ }
+ else TRACE( "not unmapping zero size win %x\n", winpos->hwnd );
+ }
+ else if ((wndPtr->dwStyle & WS_VISIBLE) &&
+ !IsRectEmpty( &oldWindowRect ) && IsRectEmpty( &newWindowRect ))
+ {
+ /* resizing to zero size -> unmap */
+ TRACE( "unmapping zero size win %x\n", winpos->hwnd );
+ XUnmapWindow( display, get_whole_window(wndPtr) );
+ }
+
+ if (bChangePos)
+ X11DRV_sync_whole_window_position( display, wndPtr, !(winpos->flags & SWP_NOZORDER) );
+ else
+ {
+ struct x11drv_win_data *data = wndPtr->pDriverData;
+ data->whole_rect = wndPtr->rectWindow;
+ X11DRV_window_to_X_rect( wndPtr, &data->whole_rect );
+ }
+
+ if (X11DRV_sync_client_window_position( display, wndPtr ) ||
+ (winpos->flags & SWP_FRAMECHANGED))
+ {
+ /* if we moved the client area, repaint the whole non-client window */
+ XClearArea( display, get_whole_window(wndPtr), 0, 0, 0, 0, True );
+ }
+ if (winpos->flags & SWP_SHOWWINDOW)
+ {
+ if (!IsRectEmpty( &newWindowRect ))
+ {
+ XMapWindow( display, get_whole_window(wndPtr) );
+ TRACE( "mapping win %x\n", winpos->hwnd );
+ }
+ else TRACE( "not mapping win %x, size is zero\n", winpos->hwnd );
+ }
+ else if ((wndPtr->dwStyle & WS_VISIBLE) &&
+ IsRectEmpty( &oldWindowRect ) && !IsRectEmpty( &newWindowRect ))
+ {
+ /* resizing from zero size to non-zero -> map */
+ TRACE( "mapping non zero size win %x\n", winpos->hwnd );
+ XMapWindow( display, get_whole_window(wndPtr) );
+ }
+ XFlush( display ); /* FIXME: should not be necessary */
+ wine_tsx11_unlock();
+ }
+
+ WIN_ReleaseWndPtr(wndPtr);
+
+ if (wvrFlags & WVR_REDRAW) RedrawWindow( winpos->hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE );
+
if (winpos->hwnd == CARET_GetHwnd())
{
if( winpos->flags & SWP_HIDEWINDOW )
@@ -1171,54 +569,6 @@
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 );
@@ -1226,18 +576,593 @@
TRACE("\tstatus flags = %04x\n", winpos->flags & SWP_AGG_STATUSFLAGS);
- if ( resync ||
- (((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) &&
- !(winpos->flags & SWP_NOSENDCHANGING)) )
- {
+ if (((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) &&
+ !(winpos->flags & SWP_NOSENDCHANGING))
SendMessageA( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)winpos );
- if (resync) X11DRV_Synchronize();
+
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * WINPOS_FindIconPos
+ *
+ * Find a suitable place for an iconic window.
+ */
+static POINT WINPOS_FindIconPos( WND* wndPtr, POINT pt )
+{
+ RECT rectParent;
+ short x, y, xspacing, yspacing;
+
+ GetClientRect( wndPtr->parent->hwndSelf, &rectParent );
+ if ((pt.x >= rectParent.left) && (pt.x + GetSystemMetrics(SM_CXICON) < rectParent.right) &&
+ (pt.y >= rectParent.top) && (pt.y + GetSystemMetrics(SM_CYICON) < rectParent.bottom))
+ return pt; /* The icon already has a suitable position */
+
+ xspacing = GetSystemMetrics(SM_CXICONSPACING);
+ yspacing = GetSystemMetrics(SM_CYICONSPACING);
+
+ y = rectParent.bottom;
+ for (;;)
+ {
+ x = rectParent.left;
+ do
+ {
+ /* Check if another icon already occupies this spot */
+ WND *childPtr = WIN_LockWndPtr(wndPtr->parent->child);
+ while (childPtr)
+ {
+ if ((childPtr->dwStyle & WS_MINIMIZE) && (childPtr != wndPtr))
+ {
+ if ((childPtr->rectWindow.left < x + xspacing) &&
+ (childPtr->rectWindow.right >= x) &&
+ (childPtr->rectWindow.top <= y) &&
+ (childPtr->rectWindow.bottom > y - yspacing))
+ break; /* There's a window in there */
+ }
+ WIN_UpdateWndPtr(&childPtr,childPtr->next);
+ }
+ WIN_ReleaseWndPtr(childPtr);
+ if (!childPtr) /* No window was found, so it's OK for us */
+ {
+ pt.x = x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2;
+ pt.y = y - (yspacing + GetSystemMetrics(SM_CYICON)) / 2;
+ return pt;
+ }
+ x += xspacing;
+ } while(x <= rectParent.right-xspacing);
+ y -= yspacing;
+ }
+}
+
+
+
+
+
+UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
+{
+ WND *wndPtr = WIN_FindWndPtr( hwnd );
+ UINT swpFlags = 0;
+ POINT size;
+ WINDOWPLACEMENT wpl;
+
+ TRACE("0x%04x %u\n", hwnd, cmd );
+
+ wpl.length = sizeof(wpl);
+ GetWindowPlacement( hwnd, &wpl );
+
+ size.x = wndPtr->rectWindow.left;
+ size.y = wndPtr->rectWindow.top;
+
+ if (!HOOK_CallHooksA(WH_CBT, HCBT_MINMAX, wndPtr->hwndSelf, cmd))
+ {
+ if( wndPtr->dwStyle & WS_MINIMIZE )
+ {
+ if( !SendMessageA( wndPtr->hwndSelf, WM_QUERYOPEN, 0, 0L ) )
+ {
+ swpFlags = SWP_NOSIZE | SWP_NOMOVE;
+ goto done;
+ }
+ swpFlags |= SWP_NOCOPYBITS;
+ }
+ switch( cmd )
+ {
+ case SW_MINIMIZE:
+ if( wndPtr->dwStyle & WS_MAXIMIZE)
+ {
+ wndPtr->flags |= WIN_RESTORE_MAX;
+ wndPtr->dwStyle &= ~WS_MAXIMIZE;
+ }
+ else
+ wndPtr->flags &= ~WIN_RESTORE_MAX;
+ wndPtr->dwStyle |= WS_MINIMIZE;
+
+ X11DRV_set_iconic_state( wndPtr );
+
+ wpl.ptMinPosition = WINPOS_FindIconPos( wndPtr, wpl.ptMinPosition );
+
+ SetRect( rect, wpl.ptMinPosition.x, wpl.ptMinPosition.y,
+ GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
+ swpFlags |= SWP_NOCOPYBITS;
+ break;
+
+ case SW_MAXIMIZE:
+ WINPOS_GetMinMaxInfo( wndPtr, &size, &wpl.ptMaxPosition, NULL, NULL );
+
+ if( wndPtr->dwStyle & WS_MINIMIZE )
+ {
+ wndPtr->dwStyle &= ~WS_MINIMIZE;
+ WINPOS_ShowIconTitle( wndPtr, FALSE );
+ X11DRV_set_iconic_state( wndPtr );
+ }
+ wndPtr->dwStyle |= WS_MAXIMIZE;
+
+ SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
+ break;
+
+ case SW_RESTORE:
+ if( wndPtr->dwStyle & WS_MINIMIZE )
+ {
+ wndPtr->dwStyle &= ~WS_MINIMIZE;
+ WINPOS_ShowIconTitle( wndPtr, FALSE );
+ X11DRV_set_iconic_state( wndPtr );
+
+ if( wndPtr->flags & WIN_RESTORE_MAX)
+ {
+ /* Restore to maximized position */
+ WINPOS_GetMinMaxInfo( wndPtr, &size, &wpl.ptMaxPosition, NULL, NULL);
+ wndPtr->dwStyle |= WS_MAXIMIZE;
+ SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
+ break;
+ }
+ }
+ else
+ if( !(wndPtr->dwStyle & WS_MAXIMIZE) )
+ {
+ swpFlags = (UINT16)(-1);
+ goto done;
+ }
+ else wndPtr->dwStyle &= ~WS_MAXIMIZE;
+
+ /* Restore to normal position */
+
+ *rect = wpl.rcNormalPosition;
+ rect->right -= rect->left;
+ rect->bottom -= rect->top;
+
+ break;
+ }
+ } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
+
+ done:
+ WIN_ReleaseWndPtr( wndPtr );
+ return swpFlags;
+}
+
+
+/***********************************************************************
+ * X11DRV_ShowWindow (X11DRV.@)
+ */
+BOOL X11DRV_ShowWindow( HWND hwnd, INT cmd )
+{
+ WND* wndPtr = WIN_FindWndPtr( hwnd );
+ BOOL wasVisible, showFlag;
+ RECT newPos = {0, 0, 0, 0};
+ UINT swp = 0;
+
+ if (!wndPtr) return FALSE;
+
+ TRACE("hwnd=%04x, cmd=%d\n", hwnd, cmd);
+
+ wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
+
+ switch(cmd)
+ {
+ case SW_HIDE:
+ if (!wasVisible) goto END;;
+ swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
+ SWP_NOACTIVATE | SWP_NOZORDER;
+ break;
+
+ case SW_SHOWMINNOACTIVE:
+ swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+ /* fall through */
+ case SW_SHOWMINIMIZED:
+ swp |= SWP_SHOWWINDOW;
+ /* fall through */
+ case SW_MINIMIZE:
+ swp |= SWP_FRAMECHANGED;
+ if( !(wndPtr->dwStyle & WS_MINIMIZE) )
+ swp |= WINPOS_MinMaximize( hwnd, SW_MINIMIZE, &newPos );
+ else swp |= SWP_NOSIZE | SWP_NOMOVE;
+ break;
+
+ case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
+ swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
+ if( !(wndPtr->dwStyle & WS_MAXIMIZE) )
+ swp |= WINPOS_MinMaximize( hwnd, SW_MAXIMIZE, &newPos );
+ else swp |= SWP_NOSIZE | SWP_NOMOVE;
+ break;
+
+ case SW_SHOWNA:
+ swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+ /* fall through */
+ case SW_SHOW:
+ swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+
+ /*
+ * ShowWindow has a little peculiar behavior that if the
+ * window is already the topmost window, it will not
+ * activate it.
+ */
+ if (GetTopWindow((HWND)0)==hwnd && (wasVisible || GetActiveWindow() == hwnd))
+ swp |= SWP_NOACTIVATE;
+
+ break;
+
+ case SW_SHOWNOACTIVATE:
+ swp |= SWP_NOZORDER;
+ if (GetActiveWindow()) swp |= SWP_NOACTIVATE;
+ /* fall through */
+ case SW_SHOWNORMAL: /* same as SW_NORMAL: */
+ case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
+ case SW_RESTORE:
+ swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
+
+ if( wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE) )
+ swp |= WINPOS_MinMaximize( hwnd, SW_RESTORE, &newPos );
+ else swp |= SWP_NOSIZE | SWP_NOMOVE;
+ break;
}
- retvalue = TRUE;
- END:
+ showFlag = (cmd != SW_HIDE);
+ if (showFlag != wasVisible)
+ {
+ SendMessageA( hwnd, WM_SHOWWINDOW, showFlag, 0 );
+ if (!IsWindow( hwnd )) goto END;
+ }
+
+ /* We can't activate a child window */
+ if ((wndPtr->dwStyle & WS_CHILD) &&
+ !(wndPtr->dwExStyle & WS_EX_MDICHILD))
+ swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+
+ SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
+ newPos.right, newPos.bottom, LOWORD(swp) );
+ if (cmd == SW_HIDE)
+ {
+ /* FIXME: This will cause the window to be activated irrespective
+ * of whether it is owned by the same thread. Has to be done
+ * asynchronously.
+ */
+
+ if (hwnd == GetActiveWindow())
+ WINPOS_ActivateOtherWindow(wndPtr);
+
+ /* Revert focus to parent */
+ if (hwnd == GetFocus() || IsChild(hwnd, GetFocus()))
+ SetFocus( GetParent(hwnd) );
+ }
+ if (!IsWindow( hwnd )) goto END;
+ else if( wndPtr->dwStyle & WS_MINIMIZE ) WINPOS_ShowIconTitle( wndPtr, TRUE );
+
+ if (wndPtr->flags & WIN_NEED_SIZE)
+ {
+ /* should happen only in CreateWindowEx() */
+ int wParam = SIZE_RESTORED;
+
+ wndPtr->flags &= ~WIN_NEED_SIZE;
+ if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
+ else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
+ SendMessageA( hwnd, WM_SIZE, wParam,
+ MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
+ wndPtr->rectClient.bottom-wndPtr->rectClient.top));
+ SendMessageA( hwnd, WM_MOVE, 0,
+ MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
+ }
+
+END:
WIN_ReleaseWndPtr(wndPtr);
- return retvalue;
+ return wasVisible;
+}
+
+
+/**********************************************************************
+ * X11DRV_MapNotify
+ */
+void X11DRV_MapNotify( HWND hwnd, XMapEvent *event )
+{
+ HWND hwndFocus = GetFocus();
+ WND *win;
+
+ if (!(win = WIN_FindWndPtr( hwnd ))) return;
+
+ if ((win->dwStyle & WS_VISIBLE) &&
+ (win->dwStyle & WS_MINIMIZE) &&
+ (win->dwExStyle & WS_EX_MANAGED))
+ {
+ int x, y;
+ unsigned int width, height, border, depth;
+ Window root, top;
+ RECT rect;
+
+ DCE_InvalidateDCE( win, &win->rectWindow );
+ win->dwStyle &= ~WS_MINIMIZE;
+ win->dwStyle |= WS_VISIBLE;
+ WIN_InternalShowOwnedPopups( hwnd, TRUE, TRUE );
+
+ if (win->flags & WIN_RESTORE_MAX)
+ win->dwStyle |= WS_MAXIMIZE;
+ else
+ win->dwStyle &= ~WS_MAXIMIZE;
+
+ /* FIXME: hack */
+ wine_tsx11_lock();
+ XGetGeometry( event->display, get_whole_window(win), &root, &x, &y, &width, &height,
+ &border, &depth );
+ XTranslateCoordinates( event->display, get_whole_window(win), root, 0, 0, &x, &y, &top );
+ wine_tsx11_unlock();
+ rect.left = x;
+ rect.top = y;
+ rect.right = x + width;
+ rect.bottom = y + height;
+ X11DRV_X_to_window_rect( win, &rect );
+
+ SendMessageA( hwnd, WM_SHOWWINDOW, SW_RESTORE, 0 );
+ SetWindowPos( hwnd, 0, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
+ SWP_NOZORDER | SWP_WINE_NOHOSTMOVE );
+ }
+ if (hwndFocus && IsChild( hwnd, hwndFocus )) X11DRV_SetFocus(hwndFocus); /* FIXME */
+ WIN_ReleaseWndPtr( win );
+}
+
+
+/**********************************************************************
+ * X11DRV_UnmapNotify
+ */
+void X11DRV_UnmapNotify( HWND hwnd, XUnmapEvent *event )
+{
+ WND *win;
+
+ if (!(win = WIN_FindWndPtr( hwnd ))) return;
+
+ if ((win->dwStyle & WS_VISIBLE) && (win->dwExStyle & WS_EX_MANAGED))
+ {
+ EndMenu();
+ SendMessageA( hwnd, WM_SHOWWINDOW, SW_MINIMIZE, 0 );
+
+ win->flags &= ~WIN_RESTORE_MAX;
+ win->dwStyle |= WS_MINIMIZE;
+
+ if (win->dwStyle & WS_MAXIMIZE)
+ {
+ win->flags |= WIN_RESTORE_MAX;
+ win->dwStyle &= ~WS_MAXIMIZE;
+ }
+
+ SetWindowPos( hwnd, 0, 0, 0, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON),
+ SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_WINE_NOHOSTMOVE );
+
+ WIN_InternalShowOwnedPopups( hwnd, FALSE, TRUE );
+ }
+ WIN_ReleaseWndPtr( win );
+}
+
+
+/***********************************************************************
+ * query_zorder
+ *
+ * Synchronize internal z-order with the window manager's.
+ */
+static BOOL __check_query_condition( WND** pWndA, WND** pWndB )
+{
+ /* return TRUE if we have at least two managed windows */
+
+ for( *pWndB = NULL; *pWndA; *pWndA = (*pWndA)->next )
+ if( ((*pWndA)->dwExStyle & WS_EX_MANAGED) &&
+ ((*pWndA)->dwStyle & WS_VISIBLE )) break;
+ if( *pWndA )
+ for( *pWndB = (*pWndA)->next; *pWndB; *pWndB = (*pWndB)->next )
+ if( ((*pWndB)->dwExStyle & WS_EX_MANAGED) &&
+ ((*pWndB)->dwStyle & WS_VISIBLE )) break;
+ return ((*pWndB) != NULL);
+}
+
+static Window __get_common_ancestor( Display *display, Window A, Window B,
+ Window** children, unsigned* total )
+{
+ /* find the real root window */
+
+ Window root, *childrenB;
+ unsigned totalB;
+
+ while( A != B && A && B )
+ {
+ TSXQueryTree( display, A, &root, &A, children, total );
+ TSXQueryTree( display, B, &root, &B, &childrenB, &totalB );
+ if( childrenB ) TSXFree( childrenB );
+ if( *children ) TSXFree( *children ), *children = NULL;
+ }
+
+ if( A && B )
+ {
+ TSXQueryTree( display, A, &root, &B, children, total );
+ return A;
+ }
+ return 0 ;
+}
+
+static Window __get_top_decoration( Display *display, Window w, Window ancestor )
+{
+ Window* children, root, prev = w, parent = w;
+ unsigned total;
+
+ do
+ {
+ w = parent;
+ TSXQueryTree( display, w, &root, &parent, &children, &total );
+ if( children ) TSXFree( children );
+ } while( parent && parent != ancestor );
+ TRACE("\t%08x -> %08x\n", (unsigned)prev, (unsigned)w );
+ return ( parent ) ? w : 0 ;
+}
+
+static unsigned __td_lookup( Window w, Window* list, unsigned max )
+{
+ unsigned i;
+ for( i = max - 1; i >= 0; i-- ) if( list[i] == w ) break;
+ return i;
+}
+
+static HWND query_zorder( Display *display, HWND hWndCheck)
+{
+ HWND hwndInsertAfter = HWND_TOP;
+ WND *pWndCheck = WIN_FindWndPtr(hWndCheck);
+ WND *pDesktop = WIN_GetDesktop();
+ WND *pWnd, *pWndZ = WIN_LockWndPtr(pDesktop->child);
+ Window w, parent, *children = NULL;
+ unsigned total, check, pos, best;
+
+ if( !__check_query_condition(&pWndZ, &pWnd) )
+ {
+ WIN_ReleaseWndPtr(pWndCheck);
+ WIN_ReleaseWndPtr(pDesktop->child);
+ WIN_ReleaseDesktop();
+ return hwndInsertAfter;
+ }
+ WIN_LockWndPtr(pWndZ);
+ WIN_LockWndPtr(pWnd);
+ WIN_ReleaseWndPtr(pDesktop->child);
+ WIN_ReleaseDesktop();
+
+ parent = __get_common_ancestor( display, get_whole_window(pWndZ),
+ get_whole_window(pWnd), &children, &total );
+ if( parent && children )
+ {
+ /* w is the ancestor if pWndCheck that is a direct descendant of 'parent' */
+
+ w = __get_top_decoration( display, get_whole_window(pWndCheck), parent );
+
+ if( w != children[total-1] ) /* check if at the top */
+ {
+ /* X child at index 0 is at the bottom, at index total-1 is at the top */
+ check = __td_lookup( w, children, total );
+ best = total;
+
+ for( WIN_UpdateWndPtr(&pWnd,pWndZ); pWnd;WIN_UpdateWndPtr(&pWnd,pWnd->next))
+ {
+ /* go through all windows in Wine z-order... */
+
+ if( pWnd != pWndCheck )
+ {
+ if( !(pWnd->dwExStyle & WS_EX_MANAGED) ||
+ !(w = __get_top_decoration( display, get_whole_window(pWnd), parent )) )
+ continue;
+ pos = __td_lookup( w, children, total );
+ if( pos < best && pos > check )
+ {
+ /* find a nearest Wine window precedes
+ * pWndCheck in the real z-order... */
+ best = pos;
+ hwndInsertAfter = pWnd->hwndSelf;
+ }
+ if( best - check == 1 ) break;
+ }
+ }
+ }
+ }
+ if( children ) TSXFree( children );
+ WIN_ReleaseWndPtr(pWnd);
+ WIN_ReleaseWndPtr(pWndZ);
+ WIN_ReleaseWndPtr(pWndCheck);
+ return hwndInsertAfter;
+}
+
+
+/***********************************************************************
+ * X11DRV_ConfigureNotify
+ */
+void X11DRV_ConfigureNotify( HWND hwnd, XConfigureEvent *event )
+{
+ HWND oldInsertAfter;
+ struct x11drv_win_data *data;
+ WND *win;
+ RECT rect;
+ WINDOWPOS winpos;
+ int x = event->x, y = event->y;
+
+ if (!(win = WIN_FindWndPtr( hwnd ))) return;
+ data = win->pDriverData;
+
+ /* Get geometry */
+
+ if (!event->send_event) /* normal event, need to map coordinates to the root */
+ {
+ Window child;
+ wine_tsx11_lock();
+ XTranslateCoordinates( event->display, data->whole_window, root_window,
+ 0, 0, &x, &y, &child );
+ wine_tsx11_unlock();
+ }
+ rect.left = x;
+ rect.top = y;
+ rect.right = x + event->width;
+ rect.bottom = y + event->height;
+ TRACE( "win %x new X rect %d,%d,%dx%d (event %d,%d,%dx%d)\n",
+ hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
+ event->x, event->y, event->width, event->height );
+ X11DRV_X_to_window_rect( win, &rect );
+ WIN_ReleaseWndPtr( win );
+
+ winpos.hwnd = hwnd;
+ winpos.x = rect.left;
+ winpos.y = rect.top;
+ winpos.cx = rect.right - rect.left;
+ winpos.cy = rect.bottom - rect.top;
+ winpos.flags = SWP_NOACTIVATE;
+
+ /* Get Z-order (FIXME) */
+
+ winpos.hwndInsertAfter = query_zorder( event->display, hwnd );
+
+ /* needs to find the first Visible Window above the current one */
+ oldInsertAfter = hwnd;
+ for (;;)
+ {
+ oldInsertAfter = GetWindow( oldInsertAfter, GW_HWNDPREV );
+ if (!oldInsertAfter)
+ {
+ oldInsertAfter = HWND_TOP;
+ break;
+ }
+ if (GetWindowLongA( oldInsertAfter, GWL_STYLE ) & WS_VISIBLE) break;
+ }
+
+ /* Compare what has changed */
+
+ GetWindowRect( hwnd, &rect );
+ if (rect.left == winpos.x && rect.top == winpos.y) winpos.flags |= SWP_NOMOVE;
+ else
+ TRACE( "%04x moving from (%d,%d) to (%d,%d)\n",
+ hwnd, rect.left, rect.top, winpos.x, winpos.y );
+
+ if (rect.right - rect.left == winpos.cx &&
+ rect.bottom - rect.top == winpos.cy) winpos.flags |= SWP_NOSIZE;
+ else
+ TRACE( "%04x resizing from (%dx%d) to (%dx%d)\n",
+ hwnd, rect.right - rect.left, rect.bottom - rect.top,
+ winpos.cx, winpos.cy );
+
+ if (winpos.hwndInsertAfter == oldInsertAfter) winpos.flags |= SWP_NOZORDER;
+ else
+ TRACE( "%04x restacking from after %04x to after %04x\n",
+ hwnd, oldInsertAfter, winpos.hwndInsertAfter );
+
+ /* if nothing changed, don't do anything */
+ if (winpos.flags == (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE)) return;
+
+ SetWindowPos( hwnd, winpos.hwndInsertAfter, winpos.x, winpos.y,
+ winpos.cx, winpos.cy, winpos.flags | SWP_WINE_NOHOSTMOVE );
}
@@ -1281,17 +1206,19 @@
#ifdef HAVE_LIBXSHAPE
{
Display *display = thread_display();
- Window win = X11DRV_WND_GetXWindow(wndPtr);
+ X11DRV_WND_DATA *data = wndPtr->pDriverData;
- if (win)
+ if (data->whole_window)
{
if (!hrgn)
{
- TSXShapeCombineMask( display, win, ShapeBounding, 0, 0, None, ShapeSet );
+ TSXShapeCombineMask( display, data->whole_window,
+ ShapeBounding, 0, 0, None, ShapeSet );
}
else
{
XRectangle *aXRect;
+ int x_offset, y_offset;
DWORD size;
DWORD dwBufferSize = GetRegionData(hrgn, 0, NULL);
PRGNDATA pRegionData = HeapAlloc(GetProcessHeap(), 0, dwBufferSize);
@@ -1299,6 +1226,8 @@
GetRegionData(hrgn, dwBufferSize, pRegionData);
size = pRegionData->rdh.nCount;
+ x_offset = wndPtr->rectWindow.left - data->whole_rect.left;
+ y_offset = wndPtr->rectWindow.top - data->whole_rect.top;
/* convert region's "Windows rectangles" to XRectangles */
aXRect = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*aXRect) );
if (aXRect)
@@ -1307,8 +1236,8 @@
RECT *pRect = (RECT*) pRegionData->Buffer;
for (; pRect < ((RECT*) pRegionData->Buffer) + size ; ++pRect, ++pCurrRect)
{
- pCurrRect->x = pRect->left;
- pCurrRect->y = pRect->top;
+ pCurrRect->x = pRect->left + x_offset;
+ pCurrRect->y = pRect->top + y_offset;
pCurrRect->height = pRect->bottom - pRect->top;
pCurrRect->width = pRect->right - pRect->left;
@@ -1322,7 +1251,7 @@
}
/* shape = non-rectangular windows (X11/extensions) */
- TSXShapeCombineRectangles( display, win, ShapeBounding,
+ TSXShapeCombineRectangles( display, data->whole_window, ShapeBounding,
0, 0, aXRect,
pCurrRect - aXRect, ShapeSet, YXBanded );
HeapFree(GetProcessHeap(), 0, aXRect );
@@ -1543,17 +1472,9 @@
{
MapWindowPoints( wndPtr->parent->hwndSelf, 0, (LPPOINT)&mouseRect, 2 );
}
- SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
- if (GetCapture() != hwnd) SetCapture( hwnd );
-
- if (wndPtr->parent && (wndPtr->parent->hwndSelf != GetDesktopWindow()))
- {
- /* Retrieve a default cache DC (without using the window style) */
- hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
- }
- else
- hdc = GetDC( 0 );
+ /* Retrieve a default cache DC (without using the window style) */
+ hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
if( iconic ) /* create a cursor for dragging */
{
@@ -1566,19 +1487,28 @@
/* repaint the window before moving it around */
RedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN );
+ SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
+ SetCapture( hwnd );
+
/* grab the server only when moving top-level windows without desktop */
grab = (!DragFullWindows && (root_window == DefaultRootWindow(gdi_display)) &&
(wndPtr->parent->hwndSelf == GetDesktopWindow()));
+
+ wine_tsx11_lock();
if (grab)
{
- wine_tsx11_lock();
XSync( gdi_display, False );
XGrabServer( display );
+ XSync( display, False );
/* switch gdi display to the thread display, since the server is grabbed */
old_gdi_display = gdi_display;
gdi_display = display;
- wine_tsx11_unlock();
}
+ XGrabPointer( display, get_whole_window(wndPtr), False,
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
+ GrabModeAsync, GrabModeAsync, get_client_window(wndPtr->parent),
+ None, CurrentTime );
+ wine_tsx11_unlock();
while(1)
{
@@ -1681,19 +1611,18 @@
else if (moved && !DragFullWindows)
draw_moving_frame( hdc, &sizingRect, thickframe );
- if (wndPtr->parent && (wndPtr->parent->hwndSelf != GetDesktopWindow()))
- ReleaseDC( wndPtr->parent->hwndSelf, hdc );
- else
- ReleaseDC( 0, hdc );
+ ReleaseDC( wndPtr->parent->hwndSelf, hdc );
+ wine_tsx11_lock();
+ XUngrabPointer( display, CurrentTime );
if (grab)
{
- wine_tsx11_lock();
XSync( display, False );
XUngrabServer( display );
+ XSync( display, False );
gdi_display = old_gdi_display;
- wine_tsx11_unlock();
}
+ wine_tsx11_unlock();
if (HOOK_CallHooksA( WH_CBT, HCBT_MOVESIZE, hwnd, (LPARAM)&sizingRect ))
sizingRect = wndPtr->rectWindow;
diff --git a/dlls/x11drv/x11ddraw.c b/dlls/x11drv/x11ddraw.c
index a867222..76ec411 100644
--- a/dlls/x11drv/x11ddraw.c
+++ b/dlls/x11drv/x11ddraw.c
@@ -18,7 +18,6 @@
#include "wingdi.h"
#include "ddrawi.h"
#include "bitmap.h"
-#include "win.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(x11drv);
@@ -50,19 +49,12 @@
{
Display *display = thread_display();
if (hWnd) {
- WND *tmpWnd;
- Window win;
/* find the X11 window that ddraw uses */
- tmpWnd = WIN_FindWndPtr(hWnd);
- win = X11DRV_WND_GetXWindow(tmpWnd);
- TRACE("WND: %p win: %ld\n", tmpWnd, win);
- WIN_ReleaseWndPtr(tmpWnd);
+ Window win = X11DRV_get_whole_window(hWnd);
+ TRACE("WND: %x win: %ld\n", hWnd, win);
if (!win) {
TRACE("host off desktop\n");
- tmpWnd = WIN_FindWndPtr(GetDesktopWindow());
- win = X11DRV_WND_GetXWindow(tmpWnd);
- TRACE("Owner WND: %p win: %ld\n", tmpWnd, win);
- WIN_ReleaseWndPtr(tmpWnd);
+ win = root_window;
}
TSXGrabPointer(display, win, True, 0, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
}
diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec
index 118e318..70d3aa3 100644
--- a/dlls/x11drv/x11drv.spec
+++ b/dlls/x11drv/x11drv.spec
@@ -27,11 +27,12 @@
@ cdecl GetScreenSaveTimeout() X11DRV_GetScreenSaveTimeout
@ cdecl SetScreenSaveTimeout(long) X11DRV_SetScreenSaveTimeout
@ cdecl LoadOEMResource(long long) X11DRV_LoadOEMResource
-@ cdecl CreateWindow(long) X11DRV_CreateWindow
+@ cdecl CreateWindow(long ptr) X11DRV_CreateWindow
@ cdecl DestroyWindow(long) X11DRV_DestroyWindow
@ cdecl GetDC(long long long long) X11DRV_GetDC
@ cdecl EnableWindow(long long) X11DRV_EnableWindow
@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) X11DRV_MsgWaitForMultipleObjectsEx
+@ cdecl ScrollDC(long long long ptr ptr long ptr) X11DRV_ScrollDC
@ cdecl ScrollWindowEx(long long long ptr ptr long ptr long) X11DRV_ScrollWindowEx
@ cdecl SetFocus(long) X11DRV_SetFocus
@ cdecl SetParent(long long) X11DRV_SetParent
@@ -39,6 +40,7 @@
@ cdecl SetWindowRgn(long long long) X11DRV_SetWindowRgn
@ cdecl SetWindowIcon(long long long) X11DRV_SetWindowIcon
@ cdecl SetWindowText(long wstr) X11DRV_SetWindowText
+@ cdecl ShowWindow(long long) X11DRV_ShowWindow
@ cdecl SysCommandSizeMove(long long) X11DRV_SysCommandSizeMove
@ cdecl AcquireClipboard() X11DRV_AcquireClipboard
@ cdecl ReleaseClipboard() X11DRV_ReleaseClipboard
diff --git a/graphics/x11drv/bitblt.c b/graphics/x11drv/bitblt.c
index 17a0b9d..d0c8b86 100644
--- a/graphics/x11drv/bitblt.c
+++ b/graphics/x11drv/bitblt.c
@@ -1306,28 +1306,22 @@
case SRCCOPY: /* 0xcc */
if (dcSrc->bitsPerPixel == dcDst->bitsPerPixel)
{
- BOOL expose = !(dcSrc->flags & DC_MEMORY) && !(dcDst->flags & DC_MEMORY);
- if ( expose ) XSetGraphicsExposures( gdi_display, physDevDst->gc, True );
XSetFunction( gdi_display, physDevDst->gc, GXcopy );
XCopyArea( gdi_display, physDevSrc->drawable,
physDevDst->drawable, physDevDst->gc,
visRectSrc.left, visRectSrc.top,
width, height, visRectDst.left, visRectDst.top );
- if ( expose ) XSetGraphicsExposures( gdi_display, physDevDst->gc, False );
return TRUE;
}
if (dcSrc->bitsPerPixel == 1)
{
- BOOL expose = !(dcSrc->flags & DC_MEMORY) && !(dcDst->flags & DC_MEMORY);
XSetBackground( gdi_display, physDevDst->gc, physDevDst->textPixel );
XSetForeground( gdi_display, physDevDst->gc, physDevDst->backgroundPixel );
XSetFunction( gdi_display, physDevDst->gc, GXcopy );
- if ( expose ) XSetGraphicsExposures( gdi_display, physDevDst->gc, True );
XCopyPlane( gdi_display, physDevSrc->drawable,
physDevDst->drawable, physDevDst->gc,
visRectSrc.left, visRectSrc.top,
width, height, visRectDst.left, visRectDst.top, 1 );
- if ( expose ) XSetGraphicsExposures( gdi_display, physDevDst->gc, False );
return TRUE;
}
break;
@@ -1355,6 +1349,7 @@
}
tmpGC = XCreateGC( gdi_display, physDevDst->drawable, 0, NULL );
+ XSetSubwindowMode( gdi_display, tmpGC, IncludeInferiors );
XSetGraphicsExposures( gdi_display, tmpGC, False );
pixmaps[DST] = XCreatePixmap( gdi_display, root_window, width, height,
dcDst->bitsPerPixel );
diff --git a/graphics/x11drv/bitmap.c b/graphics/x11drv/bitmap.c
index 343323e..26e06c6 100644
--- a/graphics/x11drv/bitmap.c
+++ b/graphics/x11drv/bitmap.c
@@ -41,6 +41,7 @@
{
BITMAP_monoGC = XCreateGC( gdi_display, tmpPixmap, 0, NULL );
XSetGraphicsExposures( gdi_display, BITMAP_monoGC, False );
+ XSetSubwindowMode( gdi_display, BITMAP_monoGC, IncludeInferiors );
XFreePixmap( gdi_display, tmpPixmap );
}
@@ -50,6 +51,7 @@
{
BITMAP_colorGC = XCreateGC( gdi_display, tmpPixmap, 0, NULL );
XSetGraphicsExposures( gdi_display, BITMAP_colorGC, False );
+ XSetSubwindowMode( gdi_display, BITMAP_colorGC, IncludeInferiors );
XFreePixmap( gdi_display, tmpPixmap );
}
}
@@ -101,6 +103,8 @@
XFreeGC( gdi_display, physDev->gc );
physDev->gc = XCreateGC( gdi_display, physDev->drawable, 0, NULL );
XSetGraphicsExposures( gdi_display, physDev->gc, False );
+ XSetSubwindowMode( gdi_display, physDev->gc, IncludeInferiors );
+ XFlush( gdi_display );
wine_tsx11_unlock();
dc->bitsPerPixel = bmp->bitmap.bmBitsPixel;
DC_InitDC( dc );
diff --git a/graphics/x11drv/clipping.c b/graphics/x11drv/clipping.c
index e1090e8..384561e 100644
--- a/graphics/x11drv/clipping.c
+++ b/graphics/x11drv/clipping.c
@@ -72,3 +72,102 @@
GDI_ReleaseObj( dc->hGCClipRgn );
}
+
+/***********************************************************************
+ * X11DRV_SetDrawable
+ *
+ * Set the drawable, clipping mode and origin for a DC.
+ */
+void X11DRV_SetDrawable( HDC hdc, Drawable drawable, int mode, int org_x, int org_y )
+{
+ DC *dc = DC_GetDCPtr( hdc );
+ if (dc)
+ {
+ X11DRV_PDEVICE *physDev = 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 (dc->hClipRgn) OffsetRgn( dc->hClipRgn, org_x - dc->DCOrgX, org_y - dc->DCOrgY );
+ dc->DCOrgX = org_x;
+ dc->DCOrgY = org_y;
+ physDev->drawable = drawable;
+ TSXSetSubwindowMode( gdi_display, physDev->gc, mode );
+ GDI_ReleaseObj( hdc );
+ }
+}
+
+
+/***********************************************************************
+ * X11DRV_StartGraphicsExposures
+ *
+ * Set the DC in graphics exposures mode
+ */
+void X11DRV_StartGraphicsExposures( HDC hdc )
+{
+ DC *dc = DC_GetDCPtr( hdc );
+ if (dc)
+ {
+ X11DRV_PDEVICE *physDev = dc->physDev;
+ TSXSetGraphicsExposures( gdi_display, physDev->gc, True );
+ GDI_ReleaseObj( hdc );
+ }
+}
+
+
+/***********************************************************************
+ * X11DRV_EndGraphicsExposures
+ *
+ * End the graphics exposures mode and process the events
+ */
+void X11DRV_EndGraphicsExposures( HDC hdc, HRGN hrgn )
+{
+ HRGN tmp = 0;
+ DC *dc = DC_GetDCPtr( hdc );
+
+ if (dc)
+ {
+ XEvent event;
+ X11DRV_PDEVICE *physDev = dc->physDev;
+
+ SetRectRgn( hrgn, 0, 0, 0, 0 );
+ wine_tsx11_lock();
+ XSetGraphicsExposures( gdi_display, physDev->gc, False );
+ XSync( gdi_display, False );
+ for (;;)
+ {
+ XWindowEvent( gdi_display, physDev->drawable, ~0, &event );
+ if (event.type == NoExpose) break;
+ if (event.type == GraphicsExpose)
+ {
+ TRACE( "got %d,%d %dx%d count %d\n",
+ event.xgraphicsexpose.x, event.xgraphicsexpose.y,
+ event.xgraphicsexpose.width, event.xgraphicsexpose.height,
+ event.xgraphicsexpose.count );
+
+ if (!tmp) tmp = CreateRectRgn( 0, 0, 0, 0 );
+ SetRectRgn( tmp, event.xgraphicsexpose.x, event.xgraphicsexpose.y,
+ event.xgraphicsexpose.x + event.xgraphicsexpose.width,
+ event.xgraphicsexpose.y + event.xgraphicsexpose.height );
+ CombineRgn( hrgn, hrgn, tmp, RGN_OR );
+ if (!event.xgraphicsexpose.count) break;
+ }
+ else
+ {
+ ERR( "got unexpected event %d\n", event.type );
+ break;
+ }
+ if (tmp) DeleteObject( tmp );
+ }
+ wine_tsx11_unlock();
+ GDI_ReleaseObj( hdc );
+ }
+}
+
diff --git a/include/user.h b/include/user.h
index a69feb0..51d45ac 100644
--- a/include/user.h
+++ b/include/user.h
@@ -69,11 +69,12 @@
void (*pResetSelectionOwner)(struct tagWND *, BOOL);
/* windowing functions */
- BOOL (*pCreateWindow)(HWND);
+ BOOL (*pCreateWindow)(HWND,CREATESTRUCTA*);
BOOL (*pDestroyWindow)(HWND);
BOOL (*pGetDC)(HWND,HDC,HRGN,DWORD);
BOOL (*pEnableWindow)(HWND,BOOL);
DWORD (*pMsgWaitForMultipleObjectsEx)(DWORD,const HANDLE*,DWORD,DWORD,DWORD);
+ BOOL (*pScrollDC)(HDC,INT,INT,const RECT*,const RECT*,HRGN,LPRECT);
INT (*pScrollWindowEx)(HWND,INT,INT,const RECT*,const RECT*,HRGN,LPRECT,UINT);
void (*pSetFocus)(HWND);
HWND (*pSetParent)(HWND,HWND);
@@ -81,6 +82,7 @@
BOOL (*pSetWindowRgn)(HWND,HRGN,BOOL);
HICON (*pSetWindowIcon)(HWND,HICON,BOOL);
BOOL (*pSetWindowText)(HWND,LPCWSTR);
+ BOOL (*pShowWindow)(HWND,INT);
void (*pSysCommandSizeMove)(HWND,WPARAM);
} USER_DRIVER;
diff --git a/include/win.h b/include/win.h
index 2ccf79d..4fda6b2 100644
--- a/include/win.h
+++ b/include/win.h
@@ -16,13 +16,6 @@
#define WND_MAGIC 0x444e4957 /* 'WIND' */
- /* PAINT_RedrawWindow() control flags */
-#define RDW_EX_USEHRGN 0x0001
-#define RDW_EX_DELETEHRGN 0x0002
-#define RDW_EX_XYWINDOW 0x0004
-#define RDW_EX_TOPFRAME 0x0010
-#define RDW_EX_DELAY_NCPAINT 0x0020
-
struct tagCLASS;
struct tagDCE;
struct tagMESSAGEQUEUE;
@@ -65,13 +58,9 @@
DWORD wExtra[1]; /* Window extra bytes */
} WND;
-/* Host attributes */
-#define HAK_ICONICSTATE 3
-
typedef struct tagWND_DRIVER
{
void (*pForceWindowRaise)(WND *);
- BOOL (*pSetHostAttr)(WND *, INT haKey, INT value);
} WND_DRIVER;
extern WND_DRIVER *WND_Driver;
@@ -104,14 +93,6 @@
#define BWA_SKIPOWNED 0x0004
#define BWA_SKIPICONIC 0x0008
- /* WIN_UpdateNCRgn() flags */
-#define UNC_CHECK 0x0001
-#define UNC_ENTIRE 0x0002
-#define UNC_REGION 0x0004
-#define UNC_UPDATE 0x0008
-#define UNC_DELAY_NCPAINT 0x0010
-#define UNC_IN_BEGINPAINT 0x0020
-
/* Window functions */
extern void WIN_LockWnds( void );
extern void WIN_UnlockWnds( void );
@@ -137,8 +118,6 @@
extern void WIN_ReleaseWinArray(WND **wndArray);
extern BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly );
-extern HICON16 NC_IconForWindow( WND *wndPtr );
-
extern HWND CARET_GetHwnd(void);
extern void CARET_GetRect(LPRECT lprc); /* windows/caret.c */
@@ -149,11 +128,6 @@
extern void PROPERTY_RemoveWindowProps( WND *pWnd ); /* windows/property.c */
-extern BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate,
- HRGN hrgnUpdate, UINT flags,
- UINT control ); /* windows/painting.c */
-extern HRGN WIN_UpdateNCRgn(WND* wnd, HRGN hRgn, UINT flags); /* windows/painting.c */
-
/* Classes functions */
struct tagCLASS; /* opaque structure */
struct builtin_class_descr;
@@ -167,8 +141,4 @@
/* windows/focus.c */
extern void FOCUS_SwitchFocus( struct tagMESSAGEQUEUE *pMsgQ, HWND , HWND );
-/* generic method that returns TRUE if the window properties ask for a
- window manager type of border */
-extern BOOL WIN_WindowNeedsWMBorder( DWORD style, DWORD exStyle );
-
#endif /* __WINE_WIN_H */
diff --git a/include/winpos.h b/include/winpos.h
index 3a89fb1..59f76de 100644
--- a/include/winpos.h
+++ b/include/winpos.h
@@ -28,7 +28,6 @@
extern void WINPOS_GetMinMaxInfo( struct tagWND* pWnd, POINT *maxSize,
POINT *maxPos, POINT *minTrack,
POINT *maxTrack );
-extern UINT WINPOS_MinMaximize( struct tagWND* pWnd, UINT16 cmd, LPRECT16 lpPos);
extern BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse,
BOOL fChangeFocus );
extern BOOL WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg );
diff --git a/include/x11drv.h b/include/x11drv.h
index ea8c479..c288d92 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -19,6 +19,7 @@
#include "winbase.h"
#include "gdi.h"
#include "user.h"
+#include "win.h"
#include "thread.h"
#define MAX_PIXELFORMATS 8
@@ -181,8 +182,11 @@
extern Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc );
extern Pixmap X11DRV_BITMAP_CreatePixmapFromBitmap( HBITMAP hBmp, HDC hdc );
-extern BOOL X11DRV_SetupGCForPatBlt( struct tagDC *dc, GC gc,
- BOOL fMapColors );
+extern void X11DRV_SetDrawable( HDC hdc, Drawable drawable, int mode, int org_x, int org_y );
+extern void X11DRV_StartGraphicsExposures( HDC hdc );
+extern void X11DRV_EndGraphicsExposures( HDC hdc, HRGN hrgn );
+
+extern BOOL X11DRV_SetupGCForPatBlt( struct tagDC *dc, GC gc, BOOL fMapColors );
extern BOOL X11DRV_SetupGCForBrush( struct tagDC *dc );
extern BOOL X11DRV_SetupGCForPen( struct tagDC *dc );
extern BOOL X11DRV_SetupGCForText( struct tagDC *dc );
@@ -307,7 +311,7 @@
{
Display *display;
HANDLE display_fd;
- int process_event_count;
+ int process_event_count; /* recursion count for event processing */
};
extern struct x11drv_thread_data *x11drv_init_thread_data(void);
@@ -327,6 +331,15 @@
extern unsigned int screen_height;
extern unsigned int screen_depth;
+extern Atom wmProtocols;
+extern Atom wmDeleteWindow;
+extern Atom wmTakeFocus;
+extern Atom dndProtocol;
+extern Atom dndSelection;
+extern Atom wmChangeState;
+extern Atom kwmDockWindow;
+extern Atom _kde_net_wm_system_tray_window_for;
+
static inline Visual *X11DRV_GetVisual(void) { return visual; }
static inline Window X11DRV_GetXRootWindow(void) { return root_window; }
@@ -345,8 +358,6 @@
extern WORD X11DRV_EVENT_XStateToKeyState( int state ) ;
-extern void X11DRV_Synchronize( void );
-
typedef enum {
X11DRV_INPUT_RELATIVE,
X11DRV_INPUT_ABSOLUTE
@@ -381,28 +392,50 @@
extern struct tagWND_DRIVER X11DRV_WND_Driver;
-typedef struct _X11DRV_WND_DATA {
- Window window;
- HBITMAP hWMIconBitmap;
- HBITMAP hWMIconMask;
- int bit_gravity;
-} X11DRV_WND_DATA;
+/* x11drv private window data */
+struct x11drv_win_data
+{
+ Window whole_window; /* X window for the complete window */
+ Window client_window; /* X window for the client area */
+ Window icon_window; /* X window for the icon */
+ RECT whole_rect; /* X window rectangle for the whole window relative to parent */
+ RECT client_rect; /* client area relative to whole window */
+ HBITMAP hWMIconBitmap;
+ HBITMAP hWMIconMask;
+};
-extern Window X11DRV_WND_GetXWindow(struct tagWND *wndPtr);
-extern Window X11DRV_WND_FindXWindow(struct tagWND *wndPtr);
+typedef struct x11drv_win_data X11DRV_WND_DATA;
+
+extern Window X11DRV_get_client_window( HWND hwnd );
+extern Window X11DRV_get_whole_window( HWND hwnd );
+extern Window X11DRV_get_top_window( HWND hwnd );
+
+inline static Window get_client_window( WND *wnd )
+{
+ struct x11drv_win_data *data = wnd->pDriverData;
+ return data->client_window;
+}
+
+inline static Window get_whole_window( WND *wnd )
+{
+ struct x11drv_win_data *data = wnd->pDriverData;
+ return data->whole_window;
+}
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_SurfaceCopy(struct tagWND *wndPtr, HDC hdc, INT dx, INT dy, const RECT *clipRect, BOOL bUpdate);
-extern void X11DRV_WND_SetGravity(struct tagWND* wndPtr, int value );
-extern BOOL X11DRV_WND_SetHostAttr(struct tagWND *wndPtr, INT haKey, INT value);
extern void X11DRV_SetFocus( HWND hwnd );
extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr );
-extern void X11DRV_register_window( Display *display, HWND hwnd, Window win );
+extern void X11DRV_expect_error( unsigned char request, unsigned char error, XID id );
+extern int X11DRV_check_error(void);
+extern void X11DRV_register_window( Display *display, HWND hwnd, struct x11drv_win_data *data );
+extern void X11DRV_set_iconic_state( WND *win );
+extern void X11DRV_window_to_X_rect( WND *win, RECT *rect );
+extern void X11DRV_X_to_window_rect( WND *win, RECT *rect );
extern void X11DRV_create_desktop_thread(void);
extern Window X11DRV_create_desktop( XVisualInfo *desktop_vi, const char *geometry );
+extern int X11DRV_sync_whole_window_position( Display *display, WND *win, int zorder );
+extern int X11DRV_sync_client_window_position( Display *display, WND *win );
#endif /* __WINE_X11DRV_H */
diff --git a/windows/dce.c b/windows/dce.c
index 400231a..3a143ae 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -211,9 +211,9 @@
dce->hClipRgn = 0;
- TRACE("\trestoring VisRgn\n");
-
- RestoreVisRgn16(dce->hDC);
+ /* make it dirty so that the vis rgn gets recomputed next time */
+ dce->DCXflags |= DCX_DCEDIRTY;
+ SetHookFlags16( dce->hDC, DCHF_INVALIDATEVISRGN );
}
@@ -412,8 +412,9 @@
BOOL bUpdateClipOrigin = FALSE;
TRACE("hwnd %04x, hrgnClip %04x, flags %08x\n",
- hwnd, hrgnClip, (unsigned)flags);
-
+ hwnd, hrgnClip, (unsigned)flags);
+
+ if (!hwnd) hwnd = GetDesktopWindow();
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
/* fixup flags */
@@ -437,17 +438,11 @@
else flags |= DCX_CACHE;
}
- if( flags & DCX_NOCLIPCHILDREN )
- {
- flags |= DCX_CACHE;
- flags &= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN);
- }
-
if (flags & DCX_WINDOW)
flags = (flags & ~DCX_CLIPCHILDREN) | DCX_CACHE;
- if (!(wndPtr->dwStyle & WS_CHILD) || !wndPtr->parent )
- flags &= ~DCX_PARENTCLIP;
+ if (!wndPtr->parent || (wndPtr->parent->hwndSelf == GetDesktopWindow()))
+ flags = (flags & ~DCX_PARENTCLIP) | DCX_CLIPSIBLINGS;
else if( flags & DCX_PARENTCLIP )
{
flags |= DCX_CACHE;
@@ -514,25 +509,6 @@
{
TRACE("\tskipping hVisRgn update\n");
bUpdateVisRgn = FALSE; /* updated automatically, via DCHook() */
-
- /* Abey - 16Jul99. to take care of the nested GetDC. first one
- with DCX_EXCLUDERGN or DCX_INTERSECTRGN flags and the next
- one with or without these flags. */
-
- if(dce->DCXflags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN))
- {
- /* This is likely to be a nested BeginPaint().
- or a BeginPaint() followed by a GetDC()*/
-
- if( dce->hClipRgn != hrgnClip )
- {
- FIXME("new hrgnClip[%04x] smashes the previous[%04x]\n",
- hrgnClip, dce->hClipRgn );
- DCE_DeleteClipRgn( dce );
- }
- else
- RestoreVisRgn16(dce->hDC);
- }
}
}
if (!dce)
@@ -542,6 +518,14 @@
}
if (!(flags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN))) hrgnClip = 0;
+
+ if (((flags ^ dce->DCXflags) & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) &&
+ (dce->hClipRgn != hrgnClip))
+ {
+ /* if the extra clip region has changed, get rid of the old one */
+ DCE_DeleteClipRgn( dce );
+ }
+
dce->hwndCurrent = hwnd;
dce->hClipRgn = hrgnClip;
dce->DCXflags = flags & (DCX_PARENTCLIP | DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN |
@@ -581,7 +565,7 @@
HWND hwnd /* [in] handle of window */
) {
if (!hwnd)
- return GetDCEx( GetDesktopWindow(), 0, DCX_CACHE | DCX_WINDOW );
+ return GetDCEx( 0, 0, DCX_CACHE | DCX_WINDOW );
return GetDCEx( hwnd, 0, DCX_USESTYLE );
}
@@ -591,7 +575,6 @@
*/
HDC16 WINAPI GetWindowDC16( HWND16 hwnd )
{
- if (!hwnd) hwnd = GetDesktopWindow16();
return GetDCEx16( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
}
@@ -601,7 +584,6 @@
*/
HDC WINAPI GetWindowDC( HWND hwnd )
{
- if (!hwnd) hwnd = GetDesktopWindow();
return GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
}
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 7a2b647..3c5e537 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -415,11 +415,7 @@
}
case WM_SYNCPAINT:
- if (wndPtr->hrgnUpdate)
- {
- RedrawWindow ( wndPtr->hwndSelf, 0, wndPtr->hrgnUpdate,
- RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN );
- }
+ RedrawWindow ( wndPtr->hwndSelf, NULL, 0, RDW_ERASENOW | RDW_ERASE | RDW_ALLCHILDREN );
return 0;
case WM_SETREDRAW:
diff --git a/windows/nonclient.c b/windows/nonclient.c
index cc47c45..b25049c 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -75,24 +75,6 @@
#define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
-/***********************************************************************
- * WIN_WindowNeedsWMBorder
- *
- * This method defines the rules for a window to have a WM border,
- * caption... It is used for consistency purposes.
- */
-BOOL WIN_WindowNeedsWMBorder( DWORD style, DWORD exStyle )
-{
- if (!(style & WS_CHILD) &&
- Options.managed &&
- !(exStyle & WS_EX_TOOLWINDOW) &&
- ( ((style & WS_CAPTION) == WS_CAPTION) ||
- (style & WS_THICKFRAME)))
- return TRUE;
- if (exStyle & WS_EX_TRAYWINDOW)
- return TRUE;
- return FALSE;
-}
/***********************************************************************
* NC_AdjustRect
@@ -106,21 +88,17 @@
ERR("Called in Win95 mode. Aiee! Please report this.\n" );
if(style & WS_ICONIC) return;
- /* Decide if the window will be managed (see CreateWindowEx) */
- if (!WIN_WindowNeedsWMBorder(style, exStyle))
- {
- if (HAS_THICKFRAME( style, exStyle ))
- InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
- else
- if (HAS_DLGFRAME( style, exStyle ))
- InflateRect( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
- else
- if (HAS_THINFRAME( style ))
- InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
- if ((style & WS_CAPTION) == WS_CAPTION)
- rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
- }
+ if (HAS_THICKFRAME( style, exStyle ))
+ InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
+ else if (HAS_DLGFRAME( style, exStyle ))
+ InflateRect( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
+ else if (HAS_THINFRAME( style ))
+ InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
+
+ if ((style & WS_CAPTION) == WS_CAPTION)
+ rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
+
if (menu) rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
if (style & WS_VSCROLL) {
@@ -172,29 +150,21 @@
{
if(style & WS_ICONIC) return;
- /* Decide if the window will be managed (see CreateWindowEx) */
- if (!WIN_WindowNeedsWMBorder(style, exStyle))
+ if (HAS_THICKFRAME( style, exStyle ))
+ InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
+ else if (HAS_DLGFRAME( style, exStyle ))
+ InflateRect(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
+ else if (HAS_THINFRAME( style ))
+ InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
+
+ if ((style & WS_CAPTION) == WS_CAPTION)
{
- if (HAS_THICKFRAME( style, exStyle ))
- InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
+ if (exStyle & WS_EX_TOOLWINDOW)
+ rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
else
- if (HAS_DLGFRAME( style, exStyle ))
- InflateRect(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
- else
- if (HAS_THINFRAME( style ))
- InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
-
- if ((style & WS_CAPTION) == WS_CAPTION)
- {
- if (exStyle & WS_EX_TOOLWINDOW)
- rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
- else
- rect->top -= GetSystemMetrics(SM_CYCAPTION);
- }
+ rect->top -= GetSystemMetrics(SM_CYCAPTION);
}
-
- if (menu)
- rect->top -= GetSystemMetrics(SM_CYMENU);
+ if (menu) rect->top -= GetSystemMetrics(SM_CYMENU);
}
@@ -240,6 +210,20 @@
}
+
+static HICON NC_IconForWindow( HWND hwnd )
+{
+ HICON hIcon = (HICON) GetClassLongA( hwnd, GCL_HICONSM );
+ if (!hIcon) hIcon = (HICON) GetClassLongA( hwnd, GCL_HICON );
+
+ /* If there is no hIcon specified and this is a modal dialog,
+ * get the default one.
+ */
+ if (!hIcon && (GetWindowLongA( hwnd, GWL_STYLE ) & DS_MODALFRAME))
+ hIcon = LoadImageA(0, IDI_WINLOGOA, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
+ return hIcon;
+}
+
/***********************************************************************
* DrawCaption (USER.660) Draws a caption bar
*
@@ -355,18 +339,9 @@
pt.x = rc.left + 2;
pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
- if (hIcon) {
- DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
- GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
- }
- else {
- WND* wndPtr = WIN_FindWndPtr(hwnd);
- HICON hAppIcon = (HICON) NC_IconForWindow(wndPtr);
- DrawIconEx (hdc, pt.x, pt.y, hAppIcon, GetSystemMetrics(SM_CXSMICON),
- GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
- WIN_ReleaseWndPtr(wndPtr);
- }
-
+ if (!hIcon) hIcon = NC_IconForWindow(hwnd);
+ DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
+ GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
rc.left += (rc.bottom - rc.top);
}
@@ -574,7 +549,7 @@
rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
- if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->dwExStyle & WS_EX_MANAGED)) goto END;
+ if (wndPtr->dwStyle & WS_ICONIC) goto END;
/* Remove frame from rectangle */
if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
@@ -630,76 +605,73 @@
if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
- if (!(wndPtr->dwExStyle & WS_EX_MANAGED))
+ /* Check borders */
+ if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
{
- /* Check borders */
- if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+ InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
+ if (!PtInRect( &rect, pt ))
{
- InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
- if (!PtInRect( &rect, pt ))
+ /* Check top sizing border */
+ if (pt.y < rect.top)
{
- /* Check top sizing border */
- if (pt.y < rect.top)
- {
- if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
- if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
- return HTTOP;
- }
- /* Check bottom sizing border */
- if (pt.y >= rect.bottom)
- {
- if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
- if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
- return HTBOTTOM;
- }
- /* Check left sizing border */
- if (pt.x < rect.left)
- {
- if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
- if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
- return HTLEFT;
- }
- /* Check right sizing border */
- if (pt.x >= rect.right)
- {
- if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
- if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
- return HTRIGHT;
- }
+ if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
+ if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
+ return HTTOP;
+ }
+ /* Check bottom sizing border */
+ if (pt.y >= rect.bottom)
+ {
+ if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
+ if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
+ return HTBOTTOM;
+ }
+ /* Check left sizing border */
+ if (pt.x < rect.left)
+ {
+ if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
+ if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
+ return HTLEFT;
+ }
+ /* Check right sizing border */
+ if (pt.x >= rect.right)
+ {
+ if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
+ if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
+ return HTRIGHT;
}
}
- else /* No thick frame */
+ }
+ else /* No thick frame */
+ {
+ if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+ InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
+ else if (HAS_THINFRAME( wndPtr->dwStyle ))
+ InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
+ if (!PtInRect( &rect, pt )) return HTBORDER;
+ }
+
+ /* Check caption */
+
+ if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+ {
+ rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
+ if (!PtInRect( &rect, pt ))
{
- if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
- InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
- else if (HAS_THINFRAME( wndPtr->dwStyle ))
- InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
- if (!PtInRect( &rect, pt )) return HTBORDER;
- }
+ /* Check system menu */
+ if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
+ rect.left += GetSystemMetrics(SM_CXSIZE);
+ if (pt.x <= rect.left) return HTSYSMENU;
- /* Check caption */
+ /* Check maximize box */
+ if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
+ rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
- if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
- {
- rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
- if (!PtInRect( &rect, pt ))
- {
- /* Check system menu */
- if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
- rect.left += GetSystemMetrics(SM_CXSIZE);
- if (pt.x <= rect.left) return HTSYSMENU;
-
- /* Check maximize box */
- if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
- rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
-
- if (pt.x >= rect.right) return HTMAXBUTTON;
- /* Check minimize box */
- if (wndPtr->dwStyle & WS_MINIMIZEBOX)
- rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
- if (pt.x >= rect.right) return HTMINBUTTON;
- return HTCAPTION;
- }
+ if (pt.x >= rect.right) return HTMAXBUTTON;
+ /* Check minimize box */
+ if (wndPtr->dwStyle & WS_MINIMIZEBOX)
+ rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+ if (pt.x >= rect.right) return HTMINBUTTON;
+ return HTCAPTION;
}
}
@@ -765,90 +737,87 @@
if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
- if (!(wndPtr->dwExStyle & WS_EX_MANAGED))
+ /* Check borders */
+ if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
{
- /* Check borders */
- if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+ InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
+ if (!PtInRect( &rect, pt ))
{
- InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
- if (!PtInRect( &rect, pt ))
+ /* Check top sizing border */
+ if (pt.y < rect.top)
{
- /* Check top sizing border */
- if (pt.y < rect.top)
- {
- if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
- if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
- return HTTOP;
- }
- /* Check bottom sizing border */
- if (pt.y >= rect.bottom)
- {
- if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
- if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
- return HTBOTTOM;
- }
- /* Check left sizing border */
- if (pt.x < rect.left)
- {
- if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
- if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
- return HTLEFT;
- }
- /* Check right sizing border */
- if (pt.x >= rect.right)
- {
- if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
- if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
- return HTRIGHT;
- }
+ if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
+ if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
+ return HTTOP;
+ }
+ /* Check bottom sizing border */
+ if (pt.y >= rect.bottom)
+ {
+ if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
+ if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
+ return HTBOTTOM;
+ }
+ /* Check left sizing border */
+ if (pt.x < rect.left)
+ {
+ if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
+ if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
+ return HTLEFT;
+ }
+ /* Check right sizing border */
+ if (pt.x >= rect.right)
+ {
+ if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
+ if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
+ return HTRIGHT;
}
}
- else /* No thick frame */
- {
- if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
- InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
- else if (HAS_THINFRAME( wndPtr->dwStyle ))
- InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
- if (!PtInRect( &rect, pt )) return HTBORDER;
- }
+ }
+ else /* No thick frame */
+ {
+ if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+ InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
+ else if (HAS_THINFRAME( wndPtr->dwStyle ))
+ InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
+ if (!PtInRect( &rect, pt )) return HTBORDER;
+ }
- /* Check caption */
+ /* Check caption */
- if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+ if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+ {
+ if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
+ rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
+ else
+ rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
+ if (!PtInRect( &rect, pt ))
{
- if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
- rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
- else
- rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
- if (!PtInRect( &rect, pt ))
+ /* Check system menu */
+ if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
{
- /* Check system menu */
- if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
- {
- if (NC_IconForWindow(wndPtr))
- rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
- }
- if (pt.x < rect.left) return HTSYSMENU;
-
- /* Check close button */
- if (wndPtr->dwStyle & WS_SYSMENU)
- rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
- if (pt.x > rect.right) return HTCLOSE;
-
- /* Check maximize box */
- /* In win95 there is automatically a Maximize button when there is a minimize one*/
- if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
- rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
- if (pt.x > rect.right) return HTMAXBUTTON;
-
- /* Check minimize box */
- /* In win95 there is automatically a Maximize button when there is a Maximize one*/
- if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
- rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
-
- if (pt.x > rect.right) return HTMINBUTTON;
- return HTCAPTION;
+ if (NC_IconForWindow(wndPtr->hwndSelf))
+ rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
}
+ if (pt.x < rect.left) return HTSYSMENU;
+
+ /* Check close button */
+ if (wndPtr->dwStyle & WS_SYSMENU)
+ rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
+ if (pt.x > rect.right) return HTCLOSE;
+
+ /* Check maximize box */
+ /* In win95 there is automatically a Maximize button when there is a minimize one*/
+ if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
+ rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+ if (pt.x > rect.right) return HTMAXBUTTON;
+
+ /* Check minimize box */
+ /* In win95 there is automatically a Maximize button when there is a Maximize one*/
+ if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
+ rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+
+ if (pt.x > rect.right) return HTMINBUTTON;
+ return HTCAPTION;
}
}
@@ -925,20 +894,15 @@
RECT rect;
HDC hdcMem;
HBITMAP hbitmap;
- WND *wndPtr = WIN_FindWndPtr( hwnd );
- if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
- {
- NC_GetInsideRect( hwnd, &rect );
- hdcMem = CreateCompatibleDC( hdc );
- hbitmap = SelectObject( hdcMem, hbitmapClose );
- BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
- hdcMem, (wndPtr->dwStyle & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
- down ? NOTSRCCOPY : SRCCOPY );
- SelectObject( hdcMem, hbitmap );
- DeleteDC( hdcMem );
- }
- WIN_ReleaseWndPtr(wndPtr);
+ NC_GetInsideRect( hwnd, &rect );
+ hdcMem = CreateCompatibleDC( hdc );
+ hbitmap = SelectObject( hdcMem, hbitmapClose );
+ BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
+ hdcMem, (GetWindowLongA(hwnd,GWL_STYLE) & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
+ down ? NOTSRCCOPY : SRCCOPY );
+ SelectObject( hdcMem, hbitmap );
+ DeleteDC( hdcMem );
}
@@ -948,22 +912,17 @@
static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
{
RECT rect;
- WND *wndPtr = WIN_FindWndPtr( hwnd );
HDC hdcMem;
- if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
- {
- NC_GetInsideRect( hwnd, &rect );
- hdcMem = CreateCompatibleDC( hdc );
- SelectObject( hdcMem, (IsZoomed(hwnd)
- ? (down ? hbitmapRestoreD : hbitmapRestore)
- : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
- BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
- GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
- SRCCOPY );
- DeleteDC( hdcMem );
- }
- WIN_ReleaseWndPtr(wndPtr);
+ NC_GetInsideRect( hwnd, &rect );
+ hdcMem = CreateCompatibleDC( hdc );
+ SelectObject( hdcMem, (IsZoomed(hwnd)
+ ? (down ? hbitmapRestoreD : hbitmapRestore)
+ : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
+ BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
+ GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
+ SRCCOPY );
+ DeleteDC( hdcMem );
}
@@ -974,21 +933,17 @@
static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
{
RECT rect;
- WND *wndPtr = WIN_FindWndPtr( hwnd );
HDC hdcMem;
- if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
- {
- NC_GetInsideRect( hwnd, &rect );
- hdcMem = CreateCompatibleDC( hdc );
- SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
- if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
- BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
- GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
- SRCCOPY );
- DeleteDC( hdcMem );
- }
- WIN_ReleaseWndPtr(wndPtr);
+ NC_GetInsideRect( hwnd, &rect );
+ hdcMem = CreateCompatibleDC( hdc );
+ SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
+ if (GetWindowLongA(hwnd,GWL_STYLE) & WS_MAXIMIZEBOX)
+ rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
+ BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
+ GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
+ SRCCOPY );
+ DeleteDC( hdcMem );
}
@@ -1012,28 +967,17 @@
BOOL
NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
{
- WND *wndPtr = WIN_FindWndPtr( hwnd );
+ HICON hIcon = NC_IconForWindow( hwnd );
- if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
+ if (hIcon)
{
- HICON hIcon;
- RECT rect;
-
- NC_GetInsideRect( hwnd, &rect );
-
- hIcon = NC_IconForWindow( wndPtr );
-
- if (hIcon)
- DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
- GetSystemMetrics(SM_CXSMICON),
- GetSystemMetrics(SM_CYSMICON),
- 0, 0, DI_NORMAL);
-
- WIN_ReleaseWndPtr(wndPtr);
- return (hIcon != 0);
+ RECT rect;
+ NC_GetInsideRect( hwnd, &rect );
+ DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
+ GetSystemMetrics(SM_CXSMICON),
+ GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
}
- WIN_ReleaseWndPtr(wndPtr);
- return FALSE;
+ return (hIcon != 0);
}
@@ -1058,37 +1002,32 @@
static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
{
RECT rect;
- WND *wndPtr = WIN_FindWndPtr( hwnd );
- if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
+ NC_GetInsideRect( hwnd, &rect );
+
+ /* A tool window has a smaller Close button */
+ if (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW)
{
- NC_GetInsideRect( hwnd, &rect );
+ INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
+ INT iBmpWidth = 11; /* it uses 11x11 for the close button in tool window */
+ INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
- /* A tool window has a smaller Close button */
- if(wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
- {
- INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
- INT iBmpWidth = 11; /* it uses 11x11 for the close button in tool window */
- INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
-
- rect.top = rect.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
- rect.left = rect.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
- rect.bottom = rect.top + iBmpHeight;
- rect.right = rect.left + iBmpWidth;
- }
- else
- {
- rect.left = rect.right - GetSystemMetrics(SM_CXSIZE) - 1;
- rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
- rect.top += 2;
- rect.right -= 2;
- }
- DrawFrameControl( hdc, &rect, DFC_CAPTION,
- (DFCS_CAPTIONCLOSE |
- (down ? DFCS_PUSHED : 0) |
- (bGrayed ? DFCS_INACTIVE : 0)) );
+ rect.top = rect.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
+ rect.left = rect.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
+ rect.bottom = rect.top + iBmpHeight;
+ rect.right = rect.left + iBmpWidth;
}
- WIN_ReleaseWndPtr(wndPtr);
+ else
+ {
+ rect.left = rect.right - GetSystemMetrics(SM_CXSIZE) - 1;
+ rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
+ rect.top += 2;
+ rect.right -= 2;
+ }
+ DrawFrameControl( hdc, &rect, DFC_CAPTION,
+ (DFCS_CAPTIONCLOSE |
+ (down ? DFCS_PUSHED : 0) |
+ (bGrayed ? DFCS_INACTIVE : 0)) );
}
/******************************************************************************
@@ -1100,23 +1039,18 @@
static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
{
RECT rect;
- WND *wndPtr = WIN_FindWndPtr( hwnd );
+ UINT flags = IsZoomed(hwnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX;
- if( !(wndPtr->dwExStyle & WS_EX_MANAGED))
- {
- UINT flags = IsZoomed(hwnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX;
- NC_GetInsideRect( hwnd, &rect );
- if (wndPtr->dwStyle & WS_SYSMENU)
- rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
- rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
- rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
- rect.top += 2;
- rect.right -= 2;
- if (down) flags |= DFCS_PUSHED;
- if (bGrayed) flags |= DFCS_INACTIVE;
- DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
- }
- WIN_ReleaseWndPtr(wndPtr);
+ NC_GetInsideRect( hwnd, &rect );
+ if (GetWindowLongA( hwnd, GWL_STYLE) & WS_SYSMENU)
+ rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+ rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
+ rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
+ rect.top += 2;
+ rect.right -= 2;
+ if (down) flags |= DFCS_PUSHED;
+ if (bGrayed) flags |= DFCS_INACTIVE;
+ DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
}
/******************************************************************************
@@ -1128,25 +1062,21 @@
static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
{
RECT rect;
- WND *wndPtr = WIN_FindWndPtr( hwnd );
+ UINT flags = DFCS_CAPTIONMIN;
+ DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
- if( !(wndPtr->dwExStyle & WS_EX_MANAGED))
- {
- UINT flags = DFCS_CAPTIONMIN;
- NC_GetInsideRect( hwnd, &rect );
- if (wndPtr->dwStyle & WS_SYSMENU)
- rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
- if (wndPtr->dwStyle & (WS_MAXIMIZEBOX|WS_MINIMIZEBOX))
- rect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
- rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
- rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
- rect.top += 2;
- rect.right -= 2;
- if (down) flags |= DFCS_PUSHED;
- if (bGrayed) flags |= DFCS_INACTIVE;
- DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
- }
- WIN_ReleaseWndPtr(wndPtr);
+ NC_GetInsideRect( hwnd, &rect );
+ if (style & WS_SYSMENU)
+ rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+ if (style & (WS_MAXIMIZEBOX|WS_MINIMIZEBOX))
+ rect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
+ rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
+ rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
+ rect.top += 2;
+ rect.right -= 2;
+ if (down) flags |= DFCS_PUSHED;
+ if (bGrayed) flags |= DFCS_INACTIVE;
+ DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
}
/***********************************************************************
@@ -1306,22 +1236,11 @@
DWORD style, BOOL active )
{
RECT r = *rect;
- WND * wndPtr = WIN_FindWndPtr( hwnd );
char buffer[256];
- if (wndPtr->dwExStyle & WS_EX_MANAGED)
- {
- WIN_ReleaseWndPtr(wndPtr);
- return;
- }
-
if (!hbitmapClose)
{
- if (!(hbitmapClose = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSE) )))
- {
- WIN_ReleaseWndPtr(wndPtr);
- return;
- }
+ if (!(hbitmapClose = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSE) ))) return;
hbitmapMinimize = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCE) );
hbitmapMinimizeD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCED) );
hbitmapMaximize = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOM) );
@@ -1330,7 +1249,7 @@
hbitmapRestoreD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORED) );
}
- if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
+ if (GetWindowLongA( hwnd, GWL_EXSTYLE) & WS_EX_DLGMODALFRAME)
{
HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
@@ -1340,7 +1259,6 @@
r.right--;
SelectObject( hdc, hbrushOld );
}
- WIN_ReleaseWndPtr(wndPtr);
MoveToEx( hdc, r.left, r.bottom, NULL );
LineTo( hdc, r.right, r.bottom );
@@ -1409,18 +1327,10 @@
BOOL active )
{
RECT r = *rect;
- WND *wndPtr = WIN_FindWndPtr( hwnd );
char buffer[256];
HPEN hPrevPen;
HMENU hSysMenu;
- if (wndPtr->dwExStyle & WS_EX_MANAGED)
- {
- WIN_ReleaseWndPtr(wndPtr);
- return;
- }
- WIN_ReleaseWndPtr(wndPtr);
-
hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
MoveToEx( hdc, r.left, r.bottom - 1, NULL );
LineTo( hdc, r.right, r.bottom - 1 );
@@ -1521,27 +1431,24 @@
SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
- if (!(wndPtr->dwExStyle & WS_EX_MANAGED))
+ if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
{
- if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
- {
- SelectObject( hdc, GetStockObject(NULL_BRUSH) );
- Rectangle( hdc, 0, 0, rect.right, rect.bottom );
- InflateRect( &rect, -1, -1 );
- }
+ SelectObject( hdc, GetStockObject(NULL_BRUSH) );
+ Rectangle( hdc, 0, 0, rect.right, rect.bottom );
+ InflateRect( &rect, -1, -1 );
+ }
- if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
- NC_DrawFrame(hdc, &rect, FALSE, active );
- else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
- NC_DrawFrame( hdc, &rect, TRUE, active );
+ if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+ NC_DrawFrame(hdc, &rect, FALSE, active );
+ else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+ NC_DrawFrame( hdc, &rect, TRUE, active );
- if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
- {
- RECT r = rect;
- r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
- rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
- NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
- }
+ if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+ {
+ RECT r = rect;
+ r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
+ rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
+ NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
}
if (HAS_MENU(wndPtr))
@@ -1652,34 +1559,32 @@
SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
- if(!(wndPtr->dwExStyle & WS_EX_MANAGED)) {
- if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
- DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
- }
- if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
- NC_DrawFrame95(hdc, &rect, FALSE, active );
- else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
- NC_DrawFrame95( hdc, &rect, TRUE, active );
- else if (HAS_THINFRAME( wndPtr->dwStyle )) {
- SelectObject( hdc, GetStockObject(NULL_BRUSH) );
- Rectangle( hdc, 0, 0, rect.right, rect.bottom );
- }
+ if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
+ DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
+ }
+ if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+ NC_DrawFrame95(hdc, &rect, FALSE, active );
+ else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+ NC_DrawFrame95( hdc, &rect, TRUE, active );
+ else if (HAS_THINFRAME( wndPtr->dwStyle )) {
+ SelectObject( hdc, GetStockObject(NULL_BRUSH) );
+ Rectangle( hdc, 0, 0, rect.right, rect.bottom );
+ }
- if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
- {
- RECT r = rect;
- if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
- r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
- rect.top += GetSystemMetrics(SM_CYSMCAPTION);
- }
- else {
- r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
- rect.top += GetSystemMetrics(SM_CYCAPTION);
- }
- if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
- NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
- wndPtr->dwExStyle, active);
+ if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+ {
+ RECT r = rect;
+ if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
+ r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
+ rect.top += GetSystemMetrics(SM_CYSMCAPTION);
}
+ else {
+ r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
+ rect.top += GetSystemMetrics(SM_CYCAPTION);
+ }
+ if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
+ NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
+ wndPtr->dwExStyle, active);
}
if (HAS_MENU(wndPtr))
@@ -2351,16 +2256,3 @@
return TRUE;
}
-
-HICON16 NC_IconForWindow(WND *wndPtr)
-{
- HICON16 hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM);
- if(!hIcon) hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON);
-
- /* If there is no hIcon specified and this is a modal dialog, */
- /* get the default one. */
- if (!hIcon && (wndPtr->dwStyle & DS_MODALFRAME))
- hIcon = LoadImageA(0, IDI_WINLOGOA, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
-
- return hIcon;
-}
diff --git a/windows/painting.c b/windows/painting.c
index 86d7b64..898d9d8 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -28,6 +28,17 @@
(r).right = (wnd)->rectClient.right - (wnd)->rectWindow.left; \
(r).bottom = (wnd)->rectClient.bottom - (wnd)->rectWindow.top
+ /* PAINT_RedrawWindow() control flags */
+#define RDW_EX_DELAY_NCPAINT 0x0020
+
+ /* WIN_UpdateNCRgn() flags */
+#define UNC_CHECK 0x0001
+#define UNC_ENTIRE 0x0002
+#define UNC_REGION 0x0004
+#define UNC_UPDATE 0x0008
+#define UNC_DELAY_NCPAINT 0x0010
+#define UNC_IN_BEGINPAINT 0x0020
+
/* Last COLOR id */
#define COLOR_MAX COLOR_GRADIENTINACTIVECAPTION
@@ -127,7 +138,7 @@
* is 1 then the hRgn is preserved and RDW_Paint() will have to get
* a DC without extra clipping region.
*/
-HRGN WIN_UpdateNCRgn(WND* wnd, HRGN hRgn, UINT uncFlags )
+static HRGN WIN_UpdateNCRgn(WND* wnd, HRGN hRgn, UINT uncFlags )
{
RECT r;
HRGN hClip = 0;
@@ -323,7 +334,7 @@
TRACE("hrgnUpdate = %04x, \n", hrgnUpdate);
- if (GetClassWord16(wndPtr->hwndSelf, GCW_STYLE) & CS_PARENTDC)
+ if (GetClassLongA(wndPtr->hwndSelf, GCL_STYLE) & CS_PARENTDC)
{
/* Don't clip the output to the update region for CS_PARENTDC window */
if( hrgnUpdate )
@@ -336,7 +347,7 @@
if( hrgnUpdate ) /* convert to client coordinates */
OffsetRgn( hrgnUpdate, wndPtr->rectWindow.left - wndPtr->rectClient.left,
wndPtr->rectWindow.top - wndPtr->rectClient.top );
- lps->hdc = GetDCEx(hwnd, hrgnUpdate, DCX_INTERSECTRGN |
+ lps->hdc = GetDCEx(hwnd, hrgnUpdate, DCX_INTERSECTRGN |
DCX_WINDOWPAINT | DCX_USESTYLE | (bIcon ? DCX_WINDOW : 0) );
/* ReleaseDC() in EndPaint() will delete the region */
}
@@ -477,7 +488,7 @@
* Validate the portions of parents that are covered by a validated child
* wndPtr = child
*/
-void RDW_ValidateParent(WND *wndChild)
+static void RDW_ValidateParent(WND *wndChild)
{
WND *wndParent = WIN_LockWndPtr(wndChild->parent);
WND *wndDesktop = WIN_GetDesktop();
@@ -611,15 +622,14 @@
if( CombineRgn( wndPtr->hrgnUpdate, wndPtr->hrgnUpdate, hRgn, RGN_DIFF )
== NULLREGION )
- goto EMPTY;
+ {
+ DeleteObject( wndPtr->hrgnUpdate );
+ wndPtr->hrgnUpdate = 0;
+ }
}
else /* validate everything */
{
- if( wndPtr->hrgnUpdate > 1 )
- {
-EMPTY:
- DeleteObject( wndPtr->hrgnUpdate );
- }
+ if( wndPtr->hrgnUpdate > 1 ) DeleteObject( wndPtr->hrgnUpdate );
wndPtr->hrgnUpdate = 0;
}
@@ -757,7 +767,7 @@
if (wndPtr->hrgnUpdate) /* wm_painticon wparam is 1 */
SendMessage16( hWnd, (bIcon) ? WM_PAINTICON : WM_PAINT, bIcon, 0 );
}
- else if ((flags & RDW_ERASENOW) || (ex & RDW_EX_TOPFRAME))
+ else if (flags & RDW_ERASENOW)
{
UINT dcx = DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN | DCX_WINDOWPAINT | DCX_CACHE;
HRGN hrgnRet;
@@ -765,7 +775,6 @@
hrgnRet = WIN_UpdateNCRgn(wndPtr,
hrgn,
UNC_REGION | UNC_CHECK |
- ((ex & RDW_EX_TOPFRAME) ? UNC_ENTIRE : 0) |
((ex & RDW_EX_DELAY_NCPAINT) ? UNC_DELAY_NCPAINT : 0) );
if( hrgnRet )
@@ -792,7 +801,6 @@
}
if( !IsWindow(hWnd) ) return hrgn;
- ex &= ~RDW_EX_TOPFRAME;
/* ... and its child windows */
@@ -820,12 +828,12 @@
return hrgn;
}
+
/***********************************************************************
- * PAINT_RedrawWindow
- *
+ * RedrawWindow (USER32.@)
*/
-BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate,
- HRGN hrgnUpdate, UINT flags, UINT ex )
+BOOL WINAPI RedrawWindow( HWND hwnd, const RECT *rectUpdate,
+ HRGN hrgnUpdate, UINT flags )
{
HRGN hRgn = 0;
RECT r, r2;
@@ -848,8 +856,8 @@
if( hrgnUpdate )
{
GetRgnBox( hrgnUpdate, &r );
- TRACE( "%04x (%04x) NULL %04x box (%i,%i-%i,%i) flags=%04x, exflags=%04x\n",
- hwnd, wndPtr->hrgnUpdate, hrgnUpdate, r.left, r.top, r.right, r.bottom, flags, ex);
+ TRACE( "%04x (%04x) NULL %04x box (%i,%i-%i,%i) flags=%04x\n",
+ hwnd, wndPtr->hrgnUpdate, hrgnUpdate, r.left, r.top, r.right, r.bottom, flags );
}
else
{
@@ -857,9 +865,9 @@
r = *rectUpdate;
else
SetRectEmpty( &r );
- TRACE( "%04x (%04x) %s %d,%d-%d,%d %04x flags=%04x, exflags=%04x\n",
+ TRACE( "%04x (%04x) %s %d,%d-%d,%d %04x flags=%04x\n",
hwnd, wndPtr->hrgnUpdate, rectUpdate ? "rect" : "NULL", r.left,
- r.top, r.right, r.bottom, hrgnUpdate, flags, ex );
+ r.top, r.right, r.bottom, hrgnUpdate, flags );
}
}
@@ -870,17 +878,9 @@
else
r = wndPtr->rectClient;
- if( ex & RDW_EX_XYWINDOW )
- {
- pt.x = pt.y = 0;
- OffsetRect( &r, -wndPtr->rectWindow.left, -wndPtr->rectWindow.top );
- }
- else
- {
- pt.x = wndPtr->rectClient.left - wndPtr->rectWindow.left;
- pt.y = wndPtr->rectClient.top - wndPtr->rectWindow.top;
- OffsetRect( &r, -wndPtr->rectClient.left, -wndPtr->rectClient.top );
- }
+ pt.x = wndPtr->rectClient.left - wndPtr->rectWindow.left;
+ pt.y = wndPtr->rectClient.top - wndPtr->rectWindow.top;
+ OffsetRect( &r, -wndPtr->rectClient.left, -wndPtr->rectClient.top );
if (flags & RDW_INVALIDATE) /* ------------------------- Invalidate */
{
@@ -935,7 +935,6 @@
{
if( !IntersectRect( &r2, &r, rectUpdate ) ) goto END;
OffsetRect( &r2, pt.x, pt.y );
-rect2v:
hRgn = CreateRectRgnIndirect( &r2 );
}
else /* entire window or client depending on RDW_FRAME */
@@ -945,7 +944,7 @@
else
{
GETCLIENTRECTW( wndPtr, r2 );
- goto rect2v;
+ hRgn = CreateRectRgnIndirect( &r2 );
}
}
}
@@ -956,7 +955,7 @@
/* Erase/update windows, from now on hRgn is a scratch region */
- hRgn = RDW_Paint( wndPtr, (hRgn == 1) ? 0 : hRgn, flags, ex );
+ hRgn = RDW_Paint( wndPtr, (hRgn == 1) ? 0 : hRgn, flags, 0 );
END:
if( hRgn > 1 && (hRgn != hrgnUpdate) )
@@ -967,16 +966,6 @@
/***********************************************************************
- * RedrawWindow (USER32.@)
- */
-BOOL WINAPI RedrawWindow( HWND hwnd, const RECT *rectUpdate,
- HRGN hrgnUpdate, UINT flags )
-{
- return PAINT_RedrawWindow( hwnd, rectUpdate, hrgnUpdate, flags, 0 );
-}
-
-
-/***********************************************************************
* RedrawWindow (USER.290)
*/
BOOL16 WINAPI RedrawWindow16( HWND16 hwnd, const RECT16 *rectUpdate,
diff --git a/windows/scroll.c b/windows/scroll.c
index dba6111..bf094eb 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -13,10 +13,6 @@
#include "wingdi.h"
#include "wine/winuser16.h"
#include "winuser.h"
-#include "win.h"
-#include "gdi.h"
-#include "dce.h"
-#include "region.h"
#include "user.h"
#include "debugtools.h"
@@ -79,109 +75,9 @@
const RECT *prLClip, HRGN hrgnUpdate,
LPRECT rcUpdate )
{
- RECT rect, rClip, rSrc;
- POINT src, dest;
- DC *dc = DC_GetDCUpdate( hdc );
-
- TRACE("%04x %d,%d hrgnUpdate=%04x rcUpdate = %p cliprc = (%d,%d-%d,%d), rc=(%d,%d-%d,%d)\n",
- (HDC16)hdc, dx, dy, hrgnUpdate, rcUpdate,
- prLClip ? prLClip->left : 0, prLClip ? prLClip->top : 0, prLClip ? prLClip->right : 0, prLClip ? prLClip->bottom : 0,
- rc ? rc->left : 0, rc ? rc->top : 0, rc ? rc->right : 0, rc ? rc->bottom : 0 );
-
- if ( !dc || !hdc ) return FALSE;
-
-/*
- TRACE(scroll,"\t[wndOrgX=%i, wndExtX=%i, vportOrgX=%i, vportExtX=%i]\n",
- dc->wndOrgX, dc->wndExtX, dc->vportOrgX, dc->vportExtX );
- TRACE(scroll,"\t[wndOrgY=%i, wndExtY=%i, vportOrgY=%i, vportExtY=%i]\n",
- dc->wndOrgY, dc->wndExtY, dc->vportOrgY, dc->vportExtY );
-*/
-
- /* compute device clipping region (in device coordinates) */
-
- if ( rc )
- rect = *rc;
- else /* maybe we should just return FALSE? */
- GetClipBox( hdc, &rect );
-
- LPtoDP( hdc, (LPPOINT)&rect, 2 );
-
- if (prLClip)
- {
- rClip = *prLClip;
- LPtoDP( hdc, (LPPOINT)&rClip, 2 );
- IntersectRect( &rClip, &rect, &rClip );
- }
- else
- rClip = rect;
-
- dx = XLPTODP ( dc, rect.left + dx ) - XLPTODP ( dc, rect.left );
- dy = YLPTODP ( dc, rect.top + dy ) - YLPTODP ( dc, rect.top );
-
- rSrc = rClip;
- OffsetRect( &rSrc, -dx, -dy );
- IntersectRect( &rSrc, &rSrc, &rect );
-
- if(dc->hVisRgn)
- {
- if (!IsRectEmpty(&rSrc))
- {
- dest.x = (src.x = rSrc.left) + dx;
- dest.y = (src.y = rSrc.top) + dy;
-
- /* copy bits */
-
- DPtoLP( hdc, (LPPOINT)&rSrc, 2 );
- DPtoLP( hdc, &src, 1 );
- DPtoLP( hdc, &dest, 1 );
-
- if (!BitBlt( hdc, dest.x, dest.y,
- rSrc.right - rSrc.left, rSrc.bottom - rSrc.top,
- hdc, src.x, src.y, SRCCOPY))
- {
- GDI_ReleaseObj( hdc );
- return FALSE;
- }
- }
-
- /* compute update areas */
-
- if (hrgnUpdate || rcUpdate)
- {
- HRGN hrgn =
- (hrgnUpdate) ? hrgnUpdate : CreateRectRgn( 0,0,0,0 );
- HRGN hrgn2;
-
- hrgn2 = CreateRectRgnIndirect( &rect );
- OffsetRgn( hrgn2, dc->DCOrgX, dc->DCOrgY );
- CombineRgn( hrgn2, hrgn2, dc->hVisRgn, RGN_AND );
- OffsetRgn( hrgn2, -dc->DCOrgX, -dc->DCOrgY );
- SetRectRgn( hrgn, rClip.left, rClip.top,
- rClip.right, rClip.bottom );
- CombineRgn( hrgn, hrgn, hrgn2, RGN_AND );
- OffsetRgn( hrgn2, dx, dy );
- CombineRgn( hrgn, hrgn, hrgn2, RGN_DIFF );
-
- if( rcUpdate )
- {
- GetRgnBox( hrgn, rcUpdate );
-
- /* Put the rcUpdate in logical coordinate */
- DPtoLP( hdc, (LPPOINT)rcUpdate, 2 );
- }
- if (!hrgnUpdate) DeleteObject( hrgn );
- DeleteObject( hrgn2 );
-
- }
- }
- else
- {
- if (hrgnUpdate) SetRectRgn(hrgnUpdate, 0, 0, 0, 0);
- if (rcUpdate) SetRectEmpty(rcUpdate);
- }
-
- GDI_ReleaseObj( hdc );
- return TRUE;
+ if (USER_Driver.pScrollDC)
+ return USER_Driver.pScrollDC( hdc, dx, dy, rc, prLClip, hrgnUpdate, rcUpdate );
+ return FALSE;
}
diff --git a/windows/win.c b/windows/win.c
index 77a73c6..0ad24dc 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -553,6 +553,7 @@
DWORD clsStyle;
WNDPROC winproc;
DCE *dce;
+ CREATESTRUCTA cs;
TRACE("Creating desktop window\n");
@@ -601,9 +602,21 @@
pWndDesktop->cbWndExtra = wndExtra;
pWndDesktop->irefCount = 0;
- if (!USER_Driver.pCreateWindow( hwndDesktop )) return FALSE;
+ cs.lpCreateParams = NULL;
+ cs.hInstance = 0;
+ cs.hMenu = 0;
+ cs.hwndParent = 0;
+ cs.x = 0;
+ cs.y = 0;
+ cs.cx = pWndDesktop->rectWindow.right;
+ cs.cy = pWndDesktop->rectWindow.bottom;
+ cs.style = pWndDesktop->dwStyle;
+ cs.dwExStyle = pWndDesktop->dwExStyle;
+ cs.lpszName = NULL;
+ cs.lpszClass = DESKTOP_CLASS_ATOM;
- SendMessageW( hwndDesktop, WM_NCCREATE, 0, 0 );
+ if (!USER_Driver.pCreateWindow( hwndDesktop, &cs )) return FALSE;
+
pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
return TRUE;
}
@@ -685,14 +698,12 @@
INT sw = SW_SHOW;
struct tagCLASS *classPtr;
WND *wndPtr;
- HWND retvalue;
- HWND16 hwnd, hwndLinkAfter;
+ HWND hwnd, hwndLinkAfter;
POINT maxSize, maxPos, minTrack, maxTrack;
INT wndExtra;
DWORD clsStyle;
WNDPROC winproc;
DCE *dce;
- LRESULT CALLBACK (*localSend32)(HWND, UINT, WPARAM, LPARAM);
TRACE("%s %s %08lx %08lx %d,%d %dx%d %04x %04x %08x %p\n",
(type == WIN_PROC_32W) ? debugres_w((LPWSTR)cs->lpszName) : debugres_a(cs->lpszName),
@@ -811,7 +822,7 @@
TRACE("CBT-hook returned 0\n");
USER_HEAP_FREE( hwnd );
CLASS_RemoveWindow( classPtr );
- retvalue = 0;
+ hwnd = 0;
goto end;
}
}
@@ -862,12 +873,6 @@
wndPtr->rectWindow.bottom = cs->y + cs->cy;
wndPtr->rectClient = wndPtr->rectWindow;
- if (!USER_Driver.pCreateWindow(wndPtr->hwndSelf))
- {
- retvalue = FALSE;
- goto end;
- }
-
/* Set the window menu */
if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
@@ -889,96 +894,44 @@
}
else wndPtr->wIDmenu = (UINT)cs->hMenu;
- /* Send the WM_CREATE message
- * Perhaps we shouldn't allow width/height changes as well.
- * See p327 in "Internals".
- */
-
- maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
-
- localSend32 = (type == WIN_PROC_32W) ? SendMessageW : SendMessageA;
- if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
+ if (!USER_Driver.pCreateWindow( wndPtr->hwndSelf, cs ))
{
- /* Insert the window in the linked list */
-
- WIN_LinkWindow( hwnd, hwndLinkAfter );
-
- WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
- NULL, NULL, 0, &wndPtr->rectClient );
- OffsetRect(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
- maxPos.y - wndPtr->rectWindow.top);
- if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
- {
- /* Send the size messages */
-
- if (!(wndPtr->flags & WIN_NEED_SIZE))
- {
- /* send it anyway */
- if (((wndPtr->rectClient.right-wndPtr->rectClient.left) <0)
- ||((wndPtr->rectClient.bottom-wndPtr->rectClient.top)<0))
- WARN("sending bogus WM_SIZE message 0x%08lx\n",
- MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
- wndPtr->rectClient.bottom-wndPtr->rectClient.top));
- (*localSend32)( hwnd, WM_SIZE, SIZE_RESTORED,
- MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
- wndPtr->rectClient.bottom-wndPtr->rectClient.top));
- (*localSend32)( hwnd, WM_MOVE, 0,
- MAKELONG( wndPtr->rectClient.left,
- wndPtr->rectClient.top ) );
- }
-
- /* Show the window, maximizing or minimizing if needed */
-
- if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
- {
- RECT16 newPos;
- UINT16 swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
- wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
- WINPOS_MinMaximize( wndPtr, swFlag, &newPos );
- swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow())
- ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
- : SWP_NOZORDER | SWP_FRAMECHANGED;
- SetWindowPos( hwnd, 0, newPos.left, newPos.top,
- newPos.right, newPos.bottom, swFlag );
- }
-
- if( (wndPtr->dwStyle & WS_CHILD) && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
- {
- /* Notify the parent window only */
-
- SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
- MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
- if( !IsWindow(hwnd) )
- {
- retvalue = 0;
- goto end;
- }
- }
-
- if (cs->style & WS_VISIBLE) ShowWindow( hwnd, sw );
-
- /* Call WH_SHELL hook */
-
- if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
- HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
-
- TRACE("created window %04x\n", hwnd);
- retvalue = hwnd;
- goto end;
- }
- WIN_UnlinkWindow( hwnd );
+ WARN("aborted by WM_xxCREATE!\n");
+ WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
+ CLASS_RemoveWindow( classPtr );
+ WIN_ReleaseWndPtr(wndPtr);
+ return 0;
}
- /* Abort window creation */
+ if( (wndPtr->dwStyle & WS_CHILD) && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
+ {
+ /* Notify the parent window only */
- WARN("aborted by WM_xxCREATE!\n");
- WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
- CLASS_RemoveWindow( classPtr );
- retvalue = 0;
-end:
+ SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
+ MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
+ if( !IsWindow(hwnd) )
+ {
+ hwnd = 0;
+ goto end;
+ }
+ }
+
+ if (cs->style & WS_VISIBLE)
+ {
+ /* in case WS_VISIBLE got set in the meantime */
+ wndPtr->dwStyle &= ~WS_VISIBLE;
+ ShowWindow( hwnd, sw );
+ }
+
+ /* Call WH_SHELL hook */
+
+ if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
+ HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
+
+ TRACE("created window %04x\n", hwnd);
+ end:
WIN_ReleaseWndPtr(wndPtr);
-
- return retvalue;
+ return hwnd;
}
@@ -2176,8 +2129,12 @@
*/
INT WINAPI InternalGetWindowText(HWND hwnd,LPWSTR lpString,INT nMaxCount )
{
- FIXME("(0x%08x,%p,0x%x),stub!\n",hwnd,lpString,nMaxCount);
- return GetWindowTextW(hwnd,lpString,nMaxCount);
+ WND *win = WIN_FindWndPtr( hwnd );
+ if (!win) return 0;
+ if (win->text) lstrcpynW( lpString, win->text, nMaxCount );
+ else lpString[0] = 0;
+ WIN_ReleaseWndPtr( win );
+ return strlenW(lpString);
}
diff --git a/windows/winpos.c b/windows/winpos.c
index ae3e946..42e87c3 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -42,8 +42,6 @@
#define PLACE_MAX 0x0002
#define PLACE_RECT 0x0004
-#define MINMAX_NOSWP 0x00010000
-
#define DWP_MAGIC ((INT)('W' | ('P' << 8) | ('O' << 16) | ('S' << 24)))
@@ -119,58 +117,6 @@
}
/***********************************************************************
- * WINPOS_FindIconPos
- *
- * Find a suitable place for an iconic window.
- */
-static POINT16 WINPOS_FindIconPos( WND* wndPtr, POINT16 pt )
-{
- RECT16 rectParent;
- short x, y, xspacing, yspacing;
-
- GetClientRect16( wndPtr->parent->hwndSelf, &rectParent );
- if ((pt.x >= rectParent.left) && (pt.x + GetSystemMetrics(SM_CXICON) < rectParent.right) &&
- (pt.y >= rectParent.top) && (pt.y + GetSystemMetrics(SM_CYICON) < rectParent.bottom))
- return pt; /* The icon already has a suitable position */
-
- xspacing = GetSystemMetrics(SM_CXICONSPACING);
- yspacing = GetSystemMetrics(SM_CYICONSPACING);
-
- y = rectParent.bottom;
- for (;;)
- {
- x = rectParent.left;
- do
- {
- /* Check if another icon already occupies this spot */
- WND *childPtr = WIN_LockWndPtr(wndPtr->parent->child);
- while (childPtr)
- {
- if ((childPtr->dwStyle & WS_MINIMIZE) && (childPtr != wndPtr))
- {
- if ((childPtr->rectWindow.left < x + xspacing) &&
- (childPtr->rectWindow.right >= x) &&
- (childPtr->rectWindow.top <= y) &&
- (childPtr->rectWindow.bottom > y - yspacing))
- break; /* There's a window in there */
- }
- WIN_UpdateWndPtr(&childPtr,childPtr->next);
- }
- WIN_ReleaseWndPtr(childPtr);
- if (!childPtr) /* No window was found, so it's OK for us */
- {
- pt.x = x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2;
- pt.y = y - (yspacing + GetSystemMetrics(SM_CYICON)) / 2;
- return pt;
- }
- x += xspacing;
- } while(x <= rectParent.right-xspacing);
- y -= yspacing;
- }
-}
-
-
-/***********************************************************************
* ArrangeIconicWindows (USER.170)
*/
UINT16 WINAPI ArrangeIconicWindows16( HWND16 parent)
@@ -440,7 +386,8 @@
MapWindowPoints( GetDesktopWindow(), wndScope->parent->hwndSelf, &xy, 1 );
if (xy.x < wndScope->rectClient.left || pt.x >= wndScope->rectClient.right ||
- xy.y < wndScope->rectClient.top || pt.y >= wndScope->rectClient.bottom)
+ xy.y < wndScope->rectClient.top || pt.y >= wndScope->rectClient.bottom ||
+ wndScope->dwStyle & WS_MINIMIZE)
goto hittest;
xy.x -= wndScope->rectClient.left;
@@ -1154,8 +1101,7 @@
MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN);
MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN);
- if (wndPtr->dwExStyle & WS_EX_MANAGED) xinc = yinc = 0;
- else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+ if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
{
xinc = GetSystemMetrics(SM_CXDLGFRAME);
yinc = GetSystemMetrics(SM_CYDLGFRAME);
@@ -1207,107 +1153,6 @@
}
/***********************************************************************
- * WINPOS_MinMaximize
- *
- * Fill in lpRect and return additional flags to be used with SetWindowPos().
- * This function assumes that 'cmd' is different from the current window
- * state.
- */
-UINT WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
-{
- UINT swpFlags = 0;
- POINT pt, size;
- LPINTERNALPOS lpPos;
-
- TRACE("0x%04x %u\n", wndPtr->hwndSelf, cmd );
-
- size.x = wndPtr->rectWindow.left; size.y = wndPtr->rectWindow.top;
- lpPos = WINPOS_InitInternalPos( wndPtr, size, &wndPtr->rectWindow );
-
- if (lpPos && !HOOK_CallHooksA(WH_CBT, HCBT_MINMAX, wndPtr->hwndSelf, cmd))
- {
- if( wndPtr->dwStyle & WS_MINIMIZE )
- {
- if( !SendMessageA( wndPtr->hwndSelf, WM_QUERYOPEN, 0, 0L ) )
- return (SWP_NOSIZE | SWP_NOMOVE);
- swpFlags |= SWP_NOCOPYBITS;
- }
- switch( cmd )
- {
- case SW_MINIMIZE:
- if( wndPtr->dwStyle & WS_MAXIMIZE)
- {
- wndPtr->flags |= WIN_RESTORE_MAX;
- wndPtr->dwStyle &= ~WS_MAXIMIZE;
- }
- else
- wndPtr->flags &= ~WIN_RESTORE_MAX;
- wndPtr->dwStyle |= WS_MINIMIZE;
-
- if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) )
- swpFlags |= MINMAX_NOSWP;
-
- lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
-
- SetRect16( lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
- GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
- swpFlags |= SWP_NOCOPYBITS;
- break;
-
- case SW_MAXIMIZE:
- CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
- WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL );
- CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
-
- if( wndPtr->dwStyle & WS_MINIMIZE )
- {
- wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE );
-
- WINPOS_ShowIconTitle( wndPtr, FALSE );
- wndPtr->dwStyle &= ~WS_MINIMIZE;
- }
- wndPtr->dwStyle |= WS_MAXIMIZE;
-
- SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
- size.x, size.y );
- break;
-
- case SW_RESTORE:
- if( wndPtr->dwStyle & WS_MINIMIZE )
- {
- wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE );
-
- wndPtr->dwStyle &= ~WS_MINIMIZE;
- WINPOS_ShowIconTitle( wndPtr, FALSE );
-
- if( wndPtr->flags & WIN_RESTORE_MAX)
- {
- /* Restore to maximized position */
- CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
- WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL);
- CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
- wndPtr->dwStyle |= WS_MAXIMIZE;
- SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y, size.x, size.y );
- break;
- }
- }
- else
- if( !(wndPtr->dwStyle & WS_MAXIMIZE) ) return (UINT16)(-1);
- else wndPtr->dwStyle &= ~WS_MAXIMIZE;
-
- /* Restore to normal position */
-
- *lpRect = lpPos->rectNormal;
- lpRect->right -= lpRect->left;
- lpRect->bottom -= lpRect->top;
-
- break;
- }
- } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
- return swpFlags;
-}
-
-/***********************************************************************
* ShowWindowAsync (USER32.@)
*
* doesn't wait; returns immediately.
@@ -1332,140 +1177,9 @@
/***********************************************************************
* ShowWindow (USER32.@)
*/
-BOOL WINAPI ShowWindow( HWND hwnd, INT cmd )
-{
- WND* wndPtr = WIN_FindWndPtr( hwnd );
- BOOL wasVisible, showFlag;
- RECT16 newPos = {0, 0, 0, 0};
- UINT swp = 0;
-
- if (!wndPtr) return FALSE;
-
- TRACE("hwnd=%04x, cmd=%d\n", hwnd, cmd);
-
- wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
-
- switch(cmd)
- {
- case SW_HIDE:
- if (!wasVisible) goto END;;
- swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
- SWP_NOACTIVATE | SWP_NOZORDER;
- break;
-
- case SW_SHOWMINNOACTIVE:
- swp |= SWP_NOACTIVATE | SWP_NOZORDER;
- /* fall through */
- case SW_SHOWMINIMIZED:
- swp |= SWP_SHOWWINDOW;
- /* fall through */
- case SW_MINIMIZE:
- swp |= SWP_FRAMECHANGED;
- if( !(wndPtr->dwStyle & WS_MINIMIZE) )
- swp |= WINPOS_MinMaximize( wndPtr, SW_MINIMIZE, &newPos );
- else swp |= SWP_NOSIZE | SWP_NOMOVE;
- break;
-
- case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
- swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
- if( !(wndPtr->dwStyle & WS_MAXIMIZE) )
- swp |= WINPOS_MinMaximize( wndPtr, SW_MAXIMIZE, &newPos );
- else swp |= SWP_NOSIZE | SWP_NOMOVE;
- break;
-
- case SW_SHOWNA:
- swp |= SWP_NOACTIVATE | SWP_NOZORDER;
- /* fall through */
- case SW_SHOW:
- swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
-
- /*
- * ShowWindow has a little peculiar behavior that if the
- * window is already the topmost window, it will not
- * activate it.
- */
- if (GetTopWindow((HWND)0)==hwnd && (wasVisible || GetActiveWindow() == hwnd))
- swp |= SWP_NOACTIVATE;
-
- break;
-
- case SW_SHOWNOACTIVATE:
- swp |= SWP_NOZORDER;
- if (GetActiveWindow()) swp |= SWP_NOACTIVATE;
- /* fall through */
- case SW_SHOWNORMAL: /* same as SW_NORMAL: */
- case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
- case SW_RESTORE:
- swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
-
- if( wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE) )
- swp |= WINPOS_MinMaximize( wndPtr, SW_RESTORE, &newPos );
- else swp |= SWP_NOSIZE | SWP_NOMOVE;
- break;
- }
-
- showFlag = (cmd != SW_HIDE);
- if (showFlag != wasVisible)
- {
- SendMessageA( hwnd, WM_SHOWWINDOW, showFlag, 0 );
- if (!IsWindow( hwnd )) goto END;
- }
-
- if ((wndPtr->dwStyle & WS_CHILD) &&
- !IsWindowVisible( wndPtr->parent->hwndSelf ) &&
- (swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE) )
- {
- /* Don't call SetWindowPos() on invisible child windows */
- if (cmd == SW_HIDE) wndPtr->dwStyle &= ~WS_VISIBLE;
- else wndPtr->dwStyle |= WS_VISIBLE;
- }
- else
- {
- /* We can't activate a child window */
- if ((wndPtr->dwStyle & WS_CHILD) &&
- !(wndPtr->dwExStyle & WS_EX_MDICHILD))
- swp |= SWP_NOACTIVATE | SWP_NOZORDER;
- if (!(swp & MINMAX_NOSWP))
- {
- SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
- newPos.right, newPos.bottom, LOWORD(swp) );
- if (cmd == SW_HIDE)
- {
- /* FIXME: This will cause the window to be activated irrespective
- * of whether it is owned by the same thread. Has to be done
- * asynchronously.
- */
-
- if (hwnd == GetActiveWindow())
- WINPOS_ActivateOtherWindow(wndPtr);
-
- /* Revert focus to parent */
- if (hwnd == GetFocus() || IsChild(hwnd, GetFocus()))
- SetFocus( GetParent(hwnd) );
- }
- }
- if (!IsWindow( hwnd )) goto END;
- else if( wndPtr->dwStyle & WS_MINIMIZE ) WINPOS_ShowIconTitle( wndPtr, TRUE );
- }
-
- if (wndPtr->flags & WIN_NEED_SIZE)
- {
- /* should happen only in CreateWindowEx() */
- int wParam = SIZE_RESTORED;
-
- wndPtr->flags &= ~WIN_NEED_SIZE;
- if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
- else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
- SendMessageA( hwnd, WM_SIZE, wParam,
- MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
- wndPtr->rectClient.bottom-wndPtr->rectClient.top));
- SendMessageA( hwnd, WM_MOVE, 0,
- MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
- }
-
-END:
- WIN_ReleaseWndPtr(wndPtr);
- return wasVisible;
+BOOL WINAPI ShowWindow( HWND hwnd, INT cmd )
+{
+ return USER_Driver.pShowWindow( hwnd, cmd );
}
diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c
index 9de7f5f..b115853 100644
--- a/windows/x11drv/clipboard.c
+++ b/windows/x11drv/clipboard.c
@@ -315,7 +315,6 @@
Display *display = thread_display();
HWND hWnd = 0;
HWND hWndClipWindow = GetOpenClipboardWindow();
- WND* wnd = NULL;
XEvent xe;
Atom aTargets;
Atom atype=AnyPropertyType;
@@ -343,10 +342,7 @@
/*
* Query the selection owner for the TARGETS property
*/
- wnd = WIN_FindWndPtr(hWnd);
- w = X11DRV_WND_FindXWindow(wnd);
- WIN_ReleaseWndPtr(wnd);
- wnd = NULL;
+ w = X11DRV_get_top_window(hWnd);
aTargets = TSXInternAtom(display, "TARGETS", False);
@@ -863,9 +859,7 @@
if ( !(selectionAcquired == (S_PRIMARY | S_CLIPBOARD)) )
{
Atom xaClipboard = TSXInternAtom(display, _CLIPBOARD, False);
- WND *tmpWnd = WIN_FindWndPtr( hWndClipWindow ? hWndClipWindow : AnyPopup() );
- owner = X11DRV_WND_FindXWindow(tmpWnd );
- WIN_ReleaseWndPtr(tmpWnd);
+ owner = X11DRV_get_top_window( hWndClipWindow ? hWndClipWindow : AnyPopup() );
/* Grab PRIMARY selection if not owned */
if ( !(selectionAcquired & S_PRIMARY) )
@@ -1012,18 +1006,15 @@
BOOL bRet = selectionAcquired;
HWND hWndClipWindow = GetOpenClipboardWindow();
HWND hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow();
- WND* wnd = NULL;
LPWINE_CLIPFORMAT lpFormat;
TRACE("%d\n", wFormat);
- if( !selectionAcquired && (wnd = WIN_FindWndPtr(hWnd)) )
+ if (!selectionAcquired)
{
XEvent xe;
Atom propRequest;
- Window w = X11DRV_WND_FindXWindow(wnd);
- WIN_ReleaseWndPtr(wnd);
- wnd = NULL;
+ Window w = X11DRV_get_top_window(hWnd);
/* Map the format ID requested to an X selection property.
* If the format is in the cache, use the atom associated
@@ -1089,7 +1080,7 @@
{
Display *display = thread_display();
HWND hWndClipOwner = 0;
- Window XWnd = X11DRV_WND_GetXWindow(pWnd);
+ Window XWnd = get_whole_window(pWnd);
Atom xaClipboard;
BOOL bLostSelection = FALSE;
@@ -1118,10 +1109,10 @@
selectionWindow = None;
if( pWnd->next )
- selectionWindow = X11DRV_WND_GetXWindow(pWnd->next);
+ selectionWindow = get_whole_window(pWnd->next);
else if( pWnd->parent )
if( pWnd->parent->child != pWnd )
- selectionWindow = X11DRV_WND_GetXWindow(pWnd->parent->child);
+ selectionWindow = get_whole_window(pWnd->parent->child);
if( selectionWindow != None )
{
diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c
index 9757619..5ac098a 100644
--- a/windows/x11drv/event.c
+++ b/windows/x11drv/event.c
@@ -51,7 +51,7 @@
extern Atom dndSelection;
extern void X11DRV_KEYBOARD_UpdateState(void);
-extern void X11DRV_KEYBOARD_HandleEvent(WND *pWnd, XKeyEvent *event);
+extern void X11DRV_KEYBOARD_HandleEvent( XKeyEvent *event, int x, int y );
#define NB_BUTTONS 5 /* Windows can handle 3 buttons and the wheel too */
@@ -97,16 +97,16 @@
static void EVENT_FocusIn( HWND hWnd, XFocusChangeEvent *event );
static void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event );
static void EVENT_Expose( HWND hWnd, XExposeEvent *event );
-static void EVENT_GraphicsExpose( HWND hWnd, XGraphicsExposeEvent *event );
-static void EVENT_ConfigureNotify( HWND hWnd, XConfigureEvent *event );
static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple );
static void EVENT_SelectionClear( HWND hWnd, XSelectionClearEvent *event);
static void EVENT_PropertyNotify( XPropertyEvent *event );
static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event );
-static void EVENT_MapNotify( HWND pWnd, XMapEvent *event );
-static void EVENT_UnmapNotify( HWND pWnd, XUnmapEvent *event );
static void EVENT_MappingNotify( XMappingEvent *event );
+extern void X11DRV_MapNotify( HWND hwnd, XMapEvent *event );
+extern void X11DRV_UnmapNotify( HWND hwnd, XUnmapEvent *event );
+extern void X11DRV_ConfigureNotify( HWND hwnd, XConfigureEvent *event );
+
#ifdef HAVE_LIBXXF86DGA2
static int DGAMotionEventType;
static int DGAButtonPressEventType;
@@ -122,14 +122,6 @@
static void EVENT_DGAButtonReleaseEvent( XDGAButtonEvent *event );
#endif
-/* Usable only with OLVWM - compile option perhaps?
-static void EVENT_EnterNotify( HWND hWnd, XCrossingEvent *event );
-*/
-
-static void EVENT_GetGeometry( Display *display, Window win, int *px, int *py,
- unsigned int *pwidth, unsigned int *pheight );
-
-
/* Static used for the current input method */
static INPUT_TYPE current_input_type = X11DRV_INPUT_ABSOLUTE;
static BOOL in_transition = FALSE; /* This is not used as for today */
@@ -138,31 +130,22 @@
/***********************************************************************
* process_events
*/
-static void process_events( Display *display )
+static int process_events( struct x11drv_thread_data *data )
{
XEvent event;
+ int count = 0;
wine_tsx11_lock();
- while ( XPending( display ) )
+ while ( XPending( data->display ) )
{
- XNextEvent( display, &event );
+ XNextEvent( data->display, &event );
wine_tsx11_unlock();
EVENT_ProcessEvent( &event );
+ count++;
wine_tsx11_lock();
}
wine_tsx11_unlock();
-}
-
-/***********************************************************************
- * X11DRV_Synchronize
- *
- * Synchronize with the X server. Should not be used too often.
- */
-void X11DRV_Synchronize( void )
-{
- Display *display = thread_display();
- TSXSync( display, False );
- process_events( display );
+ return count;
}
@@ -183,14 +166,19 @@
for (i = 0; i < count; i++) new_handles[i] = handles[i];
new_handles[count] = data->display_fd;
- data->process_event_count++;
wine_tsx11_lock();
XFlush( gdi_display );
XFlush( data->display );
wine_tsx11_unlock();
- ret = WaitForMultipleObjectsEx( count+1, new_handles, flags & MWMO_WAITALL,
- timeout, flags & MWMO_ALERTABLE );
- if (ret == count) process_events( data->display );
+
+ data->process_event_count++;
+ if (process_events( data )) ret = count;
+ else
+ {
+ ret = WaitForMultipleObjectsEx( count+1, new_handles, flags & MWMO_WAITALL,
+ timeout, flags & MWMO_ALERTABLE );
+ if (ret == count) process_events( data );
+ }
data->process_event_count--;
return ret;
}
@@ -272,33 +260,20 @@
ke.keycode = evt->keycode;
ke.same_screen = TRUE;
- X11DRV_KEYBOARD_HandleEvent(NULL, &ke);
+ X11DRV_KEYBOARD_HandleEvent(&ke,pt.x,pt.y);
return;
}
}
#endif
-
- if ( TSXFindContext( display, event->xany.window, winContext,
- (char **)&hWnd ) != 0) {
- if ( event->type == ClientMessage) {
- /* query window (drag&drop event contains only drag window) */
- Window root, child;
- int root_x, root_y, child_x, child_y;
- unsigned u;
- TSXQueryPointer( display, root_window, &root, &child,
- &root_x, &root_y, &child_x, &child_y, &u);
- if (TSXFindContext( display, child, winContext, (char **)&hWnd ) != 0)
- return;
- } else {
+
+ if (TSXFindContext( display, event->xany.window, winContext, (char **)&hWnd ) != 0)
hWnd = 0; /* Not for a registered window */
- }
- }
if ( !hWnd && event->xany.window != root_window
&& event->type != PropertyNotify
&& event->type != MappingNotify)
- ERR("Got event %s for unknown Window %08lx\n",
- event_names[event->type], event->xany.window );
+ WARN( "Got event %s for unknown Window %08lx\n",
+ event_names[event->type], event->xany.window );
else
TRACE("Got event %s for hwnd %04x\n",
event_names[event->type], hWnd );
@@ -334,65 +309,22 @@
MotionNotify, event));
EVENT_MotionNotify( hWnd, (XMotionEvent*)event );
break;
-
+
case FocusIn:
- {
- WND *pWndLastFocus = 0;
- XWindowAttributes win_attr;
- BOOL bIsDisabled;
- XFocusChangeEvent *xfocChange = (XFocusChangeEvent*)event;
-
- if (!hWnd) return;
-
- bIsDisabled = GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED;
-
- /* If the window has been disabled and we are in managed mode,
- * revert the X focus back to the last focus window. This is to disallow
- * the window manager from switching focus away while the app is
- * in a modal state.
- */
- if ( Options.managed && bIsDisabled && glastXFocusWin)
- {
- /* Change focus only if saved focus window is registered and viewable */
- if ( TSXFindContext( xfocChange->display, glastXFocusWin, winContext,
- (char **)&pWndLastFocus ) == 0 )
- {
- if ( TSXGetWindowAttributes( display, glastXFocusWin, &win_attr ) &&
- (win_attr.map_state == IsViewable) )
- {
- TSXSetInputFocus( xfocChange->display, glastXFocusWin, RevertToParent, CurrentTime );
- X11DRV_Synchronize();
- break;
- }
- }
- }
-
- EVENT_FocusIn( hWnd, xfocChange );
+ EVENT_FocusIn( hWnd, (XFocusChangeEvent*)event );
break;
- }
-
+
case FocusOut:
- {
- /* Save the last window which had the focus */
- XFocusChangeEvent *xfocChange = (XFocusChangeEvent*)event;
- glastXFocusWin = xfocChange->window;
- if (!hWnd) return;
- if (GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED) glastXFocusWin = 0;
EVENT_FocusOut( hWnd, (XFocusChangeEvent*)event );
break;
- }
-
+
case Expose:
- EVENT_Expose( hWnd, (XExposeEvent *)event );
+ EVENT_Expose( hWnd, &event->xexpose );
break;
-
- case GraphicsExpose:
- EVENT_GraphicsExpose( hWnd, (XGraphicsExposeEvent *)event );
- break;
-
+
case ConfigureNotify:
if (!hWnd) return;
- EVENT_ConfigureNotify( hWnd, (XConfigureEvent*)event );
+ X11DRV_ConfigureNotify( hWnd, &event->xconfigure );
break;
case SelectionRequest:
@@ -414,23 +346,15 @@
EVENT_ClientMessage( hWnd, (XClientMessageEvent *) event );
break;
-#if 0
- case EnterNotify:
- EVENT_EnterNotify( hWnd, (XCrossingEvent *) event );
- break;
-#endif
-
case NoExpose:
break;
-
+
case MapNotify:
- if (!hWnd) return;
- EVENT_MapNotify( hWnd, (XMapEvent *)event );
+ X11DRV_MapNotify( hWnd, (XMapEvent *)event );
break;
case UnmapNotify:
- if (!hWnd) return;
- EVENT_UnmapNotify( hWnd, (XUnmapEvent *)event );
+ X11DRV_UnmapNotify( hWnd, (XUnmapEvent *)event );
break;
case MappingNotify:
@@ -446,136 +370,6 @@
}
/***********************************************************************
- * EVENT_QueryZOrder
- *
- * Synchronize internal z-order with the window manager's.
- */
-static BOOL __check_query_condition( WND** pWndA, WND** pWndB )
-{
- /* return TRUE if we have at least two managed windows */
-
- for( *pWndB = NULL; *pWndA; *pWndA = (*pWndA)->next )
- if( ((*pWndA)->dwExStyle & WS_EX_MANAGED) &&
- ((*pWndA)->dwStyle & WS_VISIBLE )) break;
- if( *pWndA )
- for( *pWndB = (*pWndA)->next; *pWndB; *pWndB = (*pWndB)->next )
- if( ((*pWndB)->dwExStyle & WS_EX_MANAGED) &&
- ((*pWndB)->dwStyle & WS_VISIBLE )) break;
- return ((*pWndB) != NULL);
-}
-
-static Window __get_common_ancestor( Display *display, Window A, Window B,
- Window** children, unsigned* total )
-{
- /* find the real root window */
-
- Window root, *childrenB;
- unsigned totalB;
-
- while( A != B && A && B )
- {
- TSXQueryTree( display, A, &root, &A, children, total );
- TSXQueryTree( display, B, &root, &B, &childrenB, &totalB );
- if( childrenB ) TSXFree( childrenB );
- if( *children ) TSXFree( *children ), *children = NULL;
- }
-
- if( A && B )
- {
- TSXQueryTree( display, A, &root, &B, children, total );
- return A;
- }
- return 0 ;
-}
-
-static Window __get_top_decoration( Display *display, Window w, Window ancestor )
-{
- Window* children, root, prev = w, parent = w;
- unsigned total;
-
- do
- {
- w = parent;
- TSXQueryTree( display, w, &root, &parent, &children, &total );
- if( children ) TSXFree( children );
- } while( parent && parent != ancestor );
- TRACE("\t%08x -> %08x\n", (unsigned)prev, (unsigned)w );
- return ( parent ) ? w : 0 ;
-}
-
-static unsigned __td_lookup( Window w, Window* list, unsigned max )
-{
- unsigned i;
- for( i = max - 1; i >= 0; i-- ) if( list[i] == w ) break;
- return i;
-}
-
-static HWND EVENT_QueryZOrder( Display *display, HWND hWndCheck)
-{
- HWND hwndInsertAfter = HWND_TOP;
- WND *pWndCheck = WIN_FindWndPtr(hWndCheck);
- WND *pDesktop = WIN_GetDesktop();
- WND *pWnd, *pWndZ = WIN_LockWndPtr(pDesktop->child);
- Window w, parent, *children = NULL;
- unsigned total, check, pos, best;
-
- if( !__check_query_condition(&pWndZ, &pWnd) )
- {
- WIN_ReleaseWndPtr(pWndCheck);
- WIN_ReleaseWndPtr(pDesktop->child);
- WIN_ReleaseDesktop();
- return hwndInsertAfter;
- }
- WIN_LockWndPtr(pWndZ);
- WIN_LockWndPtr(pWnd);
- WIN_ReleaseWndPtr(pDesktop->child);
- WIN_ReleaseDesktop();
-
- parent = __get_common_ancestor( display, X11DRV_WND_GetXWindow(pWndZ),
- X11DRV_WND_GetXWindow(pWnd),
- &children, &total );
- if( parent && children )
- {
- /* w is the ancestor if pWndCheck that is a direct descendant of 'parent' */
-
- w = __get_top_decoration( display, X11DRV_WND_GetXWindow(pWndCheck), parent );
-
- if( w != children[total-1] ) /* check if at the top */
- {
- /* X child at index 0 is at the bottom, at index total-1 is at the top */
- check = __td_lookup( w, children, total );
- best = total;
-
- for( WIN_UpdateWndPtr(&pWnd,pWndZ); pWnd;WIN_UpdateWndPtr(&pWnd,pWnd->next))
- {
- /* go through all windows in Wine z-order... */
-
- if( pWnd != pWndCheck )
- {
- if( !(pWnd->dwExStyle & WS_EX_MANAGED) ||
- !(w = __get_top_decoration( display, X11DRV_WND_GetXWindow(pWnd), parent )) )
- continue;
- pos = __td_lookup( w, children, total );
- if( pos < best && pos > check )
- {
- /* find a nearest Wine window precedes
- * pWndCheck in the real z-order... */
- best = pos;
- hwndInsertAfter = pWnd->hwndSelf;
- }
- if( best - check == 1 ) break;
- }
- }
- }
- }
- if( children ) TSXFree( children );
- WIN_ReleaseWndPtr(pWnd);
- WIN_ReleaseWndPtr(pWndZ);
- WIN_ReleaseWndPtr(pWndCheck);
- return hwndInsertAfter;
-}
-
-/***********************************************************************
* X11DRV_EVENT_XStateToKeyState
*
* Translate a X event state (Button1Mask, ShiftMask, etc...) to
@@ -593,62 +387,74 @@
return kstate;
}
+
/***********************************************************************
* EVENT_Expose
*/
-static void EVENT_Expose( HWND hWnd, XExposeEvent *event )
+static void EVENT_Expose( HWND hwnd, XExposeEvent *event )
{
- RECT rect;
- int offx = 0,offy = 0;
+ RECT rect;
+ struct x11drv_win_data *data;
+ int flags = RDW_INVALIDATE | RDW_ERASE;
+ WND *win;
- WND *pWnd = WIN_FindWndPtr(hWnd);
- /* Make position relative to client area instead of window */
- offx = (pWnd? (pWnd->rectClient.left - pWnd->rectWindow.left) : 0);
- offy = (pWnd? (pWnd->rectClient.top - pWnd->rectWindow.top) : 0);
+ TRACE( "win %x (%lx) %d,%d %dx%d\n",
+ hwnd, event->window, event->x, event->y, event->width, event->height );
- rect.left = event->x - offx;
- rect.top = event->y - offy;
+ rect.left = event->x;
+ rect.top = event->y;
+ rect.right = rect.left + event->width;
+ rect.bottom = rect.top + event->height;
- rect.right = rect.left + event->width;
- rect.bottom = rect.top + event->height;
+ if (!(win = WIN_FindWndPtr(hwnd))) return;
+ data = win->pDriverData;
- WIN_ReleaseWndPtr(pWnd);
+ if (event->window != data->client_window) /* whole window or icon window */
+ {
+ flags |= RDW_FRAME;
+ /* make position relative to client area instead of window */
+ OffsetRect( &rect, -data->client_rect.left, -data->client_rect.top );
+ }
- RedrawWindow( hWnd, &rect, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE );
-
- if (event->count == 0)
- SendNotifyMessageA(hWnd,WM_SYNCPAINT, 0, 0);
+ /* find the top level parent that doesn't clip children and invalidate the area */
+ /* on the parent (which will invalidate all the children too) */
+ while (win->parent && win->parent->hwndSelf != GetDesktopWindow() &&
+ !(win->parent->dwStyle & WS_CLIPCHILDREN))
+ {
+ OffsetRect( &rect, win->rectClient.left, win->rectClient.top );
+ WIN_UpdateWndPtr( &win, win->parent );
+ flags &= ~RDW_FRAME; /* parent will invalidate children frame anyway */
+ }
+ hwnd = win->hwndSelf;
+ WIN_ReleaseWndPtr(win);
+ RedrawWindow( hwnd, &rect, 0, flags );
}
-/***********************************************************************
- * EVENT_GraphicsExpose
- *
- * This is needed when scrolling area is partially obscured
- * by non-Wine X window.
- */
-static void EVENT_GraphicsExpose( HWND hWnd, XGraphicsExposeEvent *event )
+/* get the coordinates of a mouse event */
+static void get_coords( HWND *hwnd, Window window, int x, int y, POINT *pt )
{
- RECT rect;
- int offx = 0,offy = 0;
+ struct x11drv_win_data *data;
+ WND *win;
- WND *pWnd = WIN_FindWndPtr(hWnd);
- /* Make position relative to client area instead of window */
- offx = (pWnd? (pWnd->rectClient.left - pWnd->rectWindow.left) : 0);
- offy = (pWnd? (pWnd->rectClient.top - pWnd->rectWindow.top) : 0);
+ if (!(win = WIN_FindWndPtr( *hwnd ))) return;
+ data = win->pDriverData;
- rect.left = event->x - offx;
- rect.top = event->y - offy;
-
- rect.right = rect.left + event->width;
- rect.bottom = rect.top + event->height;
-
- WIN_ReleaseWndPtr(pWnd);
-
- RedrawWindow( hWnd, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE );
-
- if (event->count == 0)
- SendNotifyMessageA(hWnd,WM_SYNCPAINT, 0, 0);
+ if (window == data->whole_window)
+ {
+ x -= data->client_rect.left;
+ y -= data->client_rect.top;
+ }
+ while (win->parent && win->parent->hwndSelf != GetDesktopWindow())
+ {
+ x += win->rectClient.left;
+ y += win->rectClient.top;
+ WIN_UpdateWndPtr( &win, win->parent );
+ }
+ pt->x = x + win->rectClient.left;
+ pt->y = y + win->rectClient.top;
+ *hwnd = win->hwndSelf;
+ WIN_ReleaseWndPtr( win );
}
@@ -659,10 +465,9 @@
*/
static void EVENT_Key( HWND hWnd, XKeyEvent *event )
{
- WND *pWnd = WIN_FindWndPtr(hWnd);
- X11DRV_KEYBOARD_HandleEvent( pWnd, event );
- WIN_ReleaseWndPtr(pWnd);
-
+ POINT pt;
+ get_coords( &hWnd, event->window, event->x, event->y, &pt );
+ X11DRV_KEYBOARD_HandleEvent( event, pt.x, pt.y );
}
@@ -671,22 +476,22 @@
*/
static void EVENT_MotionNotify( HWND hWnd, XMotionEvent *event )
{
- if (current_input_type == X11DRV_INPUT_ABSOLUTE) {
- WND *pWnd = WIN_FindWndPtr(hWnd);
- int xOffset = pWnd? pWnd->rectWindow.left : 0;
- int yOffset = pWnd? pWnd->rectWindow.top : 0;
- WIN_ReleaseWndPtr(pWnd);
-
- X11DRV_SendEvent( MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
- xOffset + event->x, yOffset + event->y,
- X11DRV_EVENT_XStateToKeyState( event->state ),
- event->time - X11DRV_server_startticks, hWnd);
- } else {
- X11DRV_SendEvent( MOUSEEVENTF_MOVE,
- event->x_root, event->y_root,
- X11DRV_EVENT_XStateToKeyState( event->state ),
- event->time - X11DRV_server_startticks, hWnd);
- }
+ POINT pt;
+
+ if (current_input_type == X11DRV_INPUT_ABSOLUTE)
+ {
+ get_coords( &hWnd, event->window, event->x, event->y, &pt );
+ X11DRV_SendEvent( MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, pt.x, pt.y,
+ X11DRV_EVENT_XStateToKeyState( event->state ),
+ event->time - X11DRV_server_startticks, hWnd);
+ }
+ else
+ {
+ X11DRV_SendEvent( MOUSEEVENTF_MOVE,
+ event->x_root, event->y_root,
+ X11DRV_EVENT_XStateToKeyState( event->state ),
+ event->time - X11DRV_server_startticks, hWnd);
+ }
}
@@ -695,51 +500,46 @@
*/
static void EVENT_ButtonPress( HWND hWnd, XButtonEvent *event )
{
- static WORD statusCodes[NB_BUTTONS] =
- { MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_WHEEL, MOUSEEVENTF_WHEEL};
- int buttonNum = event->button - 1;
-
- WND *pWnd = WIN_FindWndPtr(hWnd);
- int xOffset = pWnd? pWnd->rectWindow.left : 0;
- int yOffset = pWnd? pWnd->rectWindow.top : 0;
- WORD keystate,wData = 0;
-
- WIN_ReleaseWndPtr(pWnd);
+ static const WORD statusCodes[NB_BUTTONS] = { MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_MIDDLEDOWN,
+ MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_WHEEL,
+ MOUSEEVENTF_WHEEL};
+ int buttonNum = event->button - 1;
+ WORD keystate, wData = 0;
+ POINT pt;
- if (buttonNum >= NB_BUTTONS) return;
+ if (buttonNum >= NB_BUTTONS) return;
- /*
- * Get the compatible keystate
- */
- keystate = X11DRV_EVENT_XStateToKeyState( event->state );
-
- /*
- * Make sure that the state of the button that was just
- * pressed is "down".
- */
- switch (buttonNum)
- {
+ get_coords( &hWnd, event->window, event->x, event->y, &pt );
+
+ /* Get the compatible keystate */
+ keystate = X11DRV_EVENT_XStateToKeyState( event->state );
+
+ /*
+ * Make sure that the state of the button that was just
+ * pressed is "down".
+ */
+ switch (buttonNum)
+ {
case 0:
- keystate |= MK_LBUTTON;
- break;
+ keystate |= MK_LBUTTON;
+ break;
case 1:
- keystate |= MK_MBUTTON;
- break;
+ keystate |= MK_MBUTTON;
+ break;
case 2:
- keystate |= MK_RBUTTON;
- break;
+ keystate |= MK_RBUTTON;
+ break;
case 3:
wData = WHEEL_DELTA;
break;
case 4:
wData = -WHEEL_DELTA;
break;
- }
-
- X11DRV_SendEvent( statusCodes[buttonNum],
- xOffset + event->x, yOffset + event->y,
- MAKEWPARAM(keystate,wData),
- event->time - X11DRV_server_startticks, hWnd);
+ }
+
+ X11DRV_SendEvent( statusCodes[buttonNum], pt.x, pt.y,
+ MAKEWPARAM(keystate,wData),
+ event->time - X11DRV_server_startticks, hWnd);
}
@@ -748,45 +548,39 @@
*/
static void EVENT_ButtonRelease( HWND hWnd, XButtonEvent *event )
{
- static WORD statusCodes[NB_BUTTONS] =
- { MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_RIGHTUP };
- int buttonNum = event->button - 1;
- WND *pWnd = WIN_FindWndPtr(hWnd);
- int xOffset = pWnd? pWnd->rectWindow.left : 0;
- int yOffset = pWnd? pWnd->rectWindow.top : 0;
- WORD keystate;
-
- WIN_ReleaseWndPtr(pWnd);
-
- if (buttonNum >= NB_BUTTONS) return;
-
- /*
- * Get the compatible keystate
- */
- keystate = X11DRV_EVENT_XStateToKeyState( event->state );
+ static const WORD statusCodes[NB_BUTTONS] = { MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEUP,
+ MOUSEEVENTF_RIGHTUP, 0, 0 };
+ int buttonNum = event->button - 1;
+ WORD keystate;
+ POINT pt;
- /*
- * Make sure that the state of the button that was just
- * released is "up".
- */
- switch (buttonNum)
- {
+ if (buttonNum >= NB_BUTTONS) return;
+
+ get_coords( &hWnd, event->window, event->x, event->y, &pt );
+
+ /* Get the compatible keystate */
+ keystate = X11DRV_EVENT_XStateToKeyState( event->state );
+
+ /*
+ * Make sure that the state of the button that was just
+ * released is "up".
+ */
+ switch (buttonNum)
+ {
case 0:
- keystate &= ~MK_LBUTTON;
- break;
+ keystate &= ~MK_LBUTTON;
+ break;
case 1:
- keystate &= ~MK_MBUTTON;
- break;
+ keystate &= ~MK_MBUTTON;
+ break;
case 2:
- keystate &= ~MK_RBUTTON;
- break;
- default:
- return;
- }
-
- X11DRV_SendEvent( statusCodes[buttonNum],
- xOffset + event->x, yOffset + event->y,
- keystate, event->time - X11DRV_server_startticks, hWnd);
+ keystate &= ~MK_RBUTTON;
+ break;
+ default:
+ return;
+ }
+ X11DRV_SendEvent( statusCodes[buttonNum], pt.x, pt.y,
+ keystate, event->time - X11DRV_server_startticks, hWnd);
}
@@ -795,12 +589,42 @@
*/
static void EVENT_FocusIn( HWND hWnd, XFocusChangeEvent *event )
{
- if (event->detail != NotifyPointer)
- if (hWnd != GetForegroundWindow())
+ WND *pWndLastFocus;
+ XWindowAttributes win_attr;
+ BOOL bIsDisabled;
+
+ if (!hWnd) return;
+
+ bIsDisabled = GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED;
+
+ /* If the window has been disabled and we are in managed mode,
+ * revert the X focus back to the last focus window. This is to disallow
+ * the window manager from switching focus away while the app is
+ * in a modal state.
+ */
+ if ( Options.managed && bIsDisabled && glastXFocusWin)
+ {
+ /* Change focus only if saved focus window is registered and viewable */
+ wine_tsx11_lock();
+ if (XFindContext( event->display, glastXFocusWin, winContext,
+ (char **)&pWndLastFocus ) == 0 )
{
- SetForegroundWindow( hWnd );
- X11DRV_KEYBOARD_UpdateState();
+ if (XGetWindowAttributes( event->display, glastXFocusWin, &win_attr ) &&
+ (win_attr.map_state == IsViewable) )
+ {
+ XSetInputFocus( event->display, glastXFocusWin, RevertToParent, CurrentTime );
+ wine_tsx11_unlock();
+ return;
+ }
}
+ wine_tsx11_unlock();
+ }
+
+ if (event->detail != NotifyPointer && hWnd != GetForegroundWindow())
+ {
+ SetForegroundWindow( hWnd );
+ X11DRV_KEYBOARD_UpdateState();
+ }
}
@@ -811,25 +635,27 @@
*/
static void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event )
{
- if (event->detail != NotifyPointer)
- if (hWnd == GetForegroundWindow())
- {
- SendMessageA( hWnd, WM_CANCELMODE, 0, 0 );
+ /* Save the last window which had the focus */
+ glastXFocusWin = event->window;
+ if (!hWnd) return;
+ if (GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED) glastXFocusWin = 0;
-
- /* don't reset the foreground window, if the window who's
+ if (event->detail != NotifyPointer && hWnd == GetForegroundWindow())
+ {
+ /* don't reset the foreground window, if the window which is
getting the focus is a Wine window */
- if (!X11DRV_CheckFocus())
- {
- /* Abey : 6-Oct-99. Check again if the focus out window is the
- Foreground window, because in most cases the messages sent
- above must have already changed the foreground window, in which
- case we don't have to change the foreground window to 0 */
+ if (!X11DRV_CheckFocus())
+ {
+ SendMessageA( hWnd, WM_CANCELMODE, 0, 0 );
+ /* Abey : 6-Oct-99. Check again if the focus out window is the
+ Foreground window, because in most cases the messages sent
+ above must have already changed the foreground window, in which
+ case we don't have to change the foreground window to 0 */
- if (hWnd == GetForegroundWindow())
- SetForegroundWindow( 0 );
- }
- }
+ if (hWnd == GetForegroundWindow())
+ SetForegroundWindow( 0 );
+ }
+ }
}
/**********************************************************************
@@ -849,100 +675,6 @@
return TRUE;
}
-/**********************************************************************
- * EVENT_GetGeometry
- *
- * Helper function for ConfigureNotify handling.
- * Get the new geometry of a window relative to the root window.
- */
-static void EVENT_GetGeometry( Display *display, Window win, int *px, int *py,
- unsigned int *pwidth, unsigned int *pheight )
-{
- Window root, top;
- int x, y, width, height, border, depth;
-
- wine_tsx11_lock();
-
- /* Get the geometry of the window */
- XGetGeometry( display, win, &root, &x, &y, &width, &height,
- &border, &depth );
-
- /* Translate the window origin to root coordinates */
- XTranslateCoordinates( display, win, root, 0, 0, &x, &y, &top );
-
- wine_tsx11_unlock();
-
- *px = x;
- *py = y;
- *pwidth = width;
- *pheight = height;
-}
-
-/**********************************************************************
- * EVENT_ConfigureNotify
- *
- * The ConfigureNotify event is only selected on top-level windows
- * when the -managed flag is used.
- */
-static void EVENT_ConfigureNotify( HWND hWnd, XConfigureEvent *event )
-{
- RECT rectWindow;
- int x, y, flags = 0;
- unsigned int width, height;
- HWND newInsertAfter, oldInsertAfter;
-
- /* Get geometry and Z-order according to X */
-
- EVENT_GetGeometry( event->display, event->window, &x, &y, &width, &height );
- newInsertAfter = EVENT_QueryZOrder( event->display, hWnd );
-
- /* Get geometry and Z-order according to Wine */
-
- /*
- * Needs to find the first Visible Window above the current one
- */
- oldInsertAfter = hWnd;
- for (;;)
- {
- oldInsertAfter = GetWindow( oldInsertAfter, GW_HWNDPREV );
- if (!oldInsertAfter)
- {
- oldInsertAfter = HWND_TOP;
- break;
- }
- if (GetWindowLongA( oldInsertAfter, GWL_STYLE ) & WS_VISIBLE) break;
- }
-
- /* Compare what has changed */
-
- GetWindowRect( hWnd, &rectWindow );
- if ( rectWindow.left == x && rectWindow.top == y )
- flags |= SWP_NOMOVE;
- else
- TRACE_(win)( "%04x moving from (%d,%d) to (%d,%d)\n", hWnd,
- rectWindow.left, rectWindow.top, x, y );
-
- if ( rectWindow.right - rectWindow.left == width
- && rectWindow.bottom - rectWindow.top == height )
- flags |= SWP_NOSIZE;
- else
- TRACE_(win)( "%04x resizing from (%d,%d) to (%d,%d)\n", hWnd,
- rectWindow.right - rectWindow.left,
- rectWindow.bottom - rectWindow.top, width, height );
-
- if ( newInsertAfter == oldInsertAfter )
- flags |= SWP_NOZORDER;
- else
- TRACE_(win)( "%04x restacking from after %04x to after %04x\n", hWnd,
- oldInsertAfter, newInsertAfter );
-
- /* If anything changed, call SetWindowPos */
-
- if ( flags != (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER) )
- SetWindowPos( hWnd, newInsertAfter, x, y, width, height,
- flags | SWP_NOACTIVATE | SWP_WINE_NOHOSTMOVE );
-}
-
/***********************************************************************
* EVENT_SelectionRequest_TARGETS
@@ -1524,7 +1256,7 @@
pWnd = WIN_FindWndPtr(hWnd);
- TSXQueryPointer( event->display, X11DRV_WND_GetXWindow(pWnd), &w_aux_root, &w_aux_child,
+ TSXQueryPointer( event->display, get_whole_window(pWnd), &w_aux_root, &w_aux_child,
&x, &y, (int *) &u.pt_aux.x, (int *) &u.pt_aux.y,
(unsigned int*)&aux_long);
@@ -1743,22 +1475,24 @@
if ((event->message_type == wmProtocols) &&
(((Atom) event->data.l[0]) == wmDeleteWindow))
{
- /* Ignore the delete window request if the window has been disabled
- * and we are in managed mode. This is to disallow applications from
- * being closed by the window manager while in a modal state.
- */
- BOOL bIsDisabled;
- bIsDisabled = GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED;
-
- if ( !Options.managed || !bIsDisabled )
- PostMessage16( hWnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
+ /* Ignore the delete window request if the window has been disabled */
+ if (!(GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED))
+ PostMessageA( hWnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
}
- else if ( event->message_type == dndProtocol &&
- (event->data.l[0] == DndFile || event->data.l[0] == DndFiles) )
- EVENT_DropFromOffiX(hWnd, event);
- else if ( event->message_type == dndProtocol &&
- event->data.l[0] == DndURL )
- EVENT_DropURLs(hWnd, event);
+ else if (event->message_type == dndProtocol)
+ {
+ /* query window (drag&drop event contains only drag window) */
+ Window root, child;
+ int root_x, root_y, child_x, child_y;
+ unsigned int u;
+ TSXQueryPointer( event->display, root_window, &root, &child,
+ &root_x, &root_y, &child_x, &child_y, &u);
+ if (TSXFindContext( event->display, child, winContext, (char **)&hWnd ) != 0) return;
+ if (event->data.l[0] == DndFile || event->data.l[0] == DndFiles)
+ EVENT_DropFromOffiX(hWnd, event);
+ else if (event->data.l[0] == DndURL)
+ EVENT_DropURLs(hWnd, event);
+ }
else {
#if 0
/* enable this if you want to see the message */
@@ -1782,65 +1516,6 @@
}
}
-/**********************************************************************
- * EVENT_EnterNotify
- *
- * Install colormap when Wine window is focused in
- * self-managed mode with private colormap
- */
-#if 0
-void EVENT_EnterNotify( HWND hWnd, XCrossingEvent *event )
-{
- if( !Options.managed && root_window == DefaultRootWindow(event->display) &&
- (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE) && GetFocus() )
- TSXInstallColormap( event->display, X11DRV_PALETTE_GetColormap() );
-}
-#endif
-
-/**********************************************************************
- * EVENT_MapNotify
- */
-void EVENT_MapNotify( HWND hWnd, XMapEvent *event )
-{
- HWND hwndFocus = GetFocus();
- WND *wndFocus = WIN_FindWndPtr(hwndFocus);
- WND *pWnd = WIN_FindWndPtr(hWnd);
- if (pWnd && (pWnd->dwExStyle & WS_EX_MANAGED))
- {
- DCE_InvalidateDCE( pWnd, &pWnd->rectWindow );
- pWnd->dwStyle &= ~WS_MINIMIZE;
- pWnd->dwStyle |= WS_VISIBLE;
- WIN_InternalShowOwnedPopups(hWnd,TRUE,TRUE);
- }
- WIN_ReleaseWndPtr(pWnd);
-
- if (hwndFocus && IsChild( hWnd, hwndFocus ))
- X11DRV_SetFocus(hwndFocus);
-
- WIN_ReleaseWndPtr(wndFocus);
-
- return;
-}
-
-
-/**********************************************************************
- * EVENT_UnmapNotify
- */
-void EVENT_UnmapNotify( HWND hWnd, XUnmapEvent *event )
-{
- WND *pWnd = WIN_FindWndPtr(hWnd);
- if (pWnd && (pWnd->dwExStyle & WS_EX_MANAGED))
- {
- EndMenu();
- if( pWnd->dwStyle & WS_VISIBLE )
- {
- pWnd->dwStyle |= WS_MINIMIZE;
- pWnd->dwStyle &= ~WS_VISIBLE;
- WIN_InternalShowOwnedPopups(hWnd,FALSE,TRUE);
- }
- }
- WIN_ReleaseWndPtr(pWnd);
-}
/***********************************************************************
* EVENT_MappingNotify
diff --git a/windows/x11drv/keyboard.c b/windows/x11drv/keyboard.c
index 3fc1e1f..78ff6aa 100644
--- a/windows/x11drv/keyboard.c
+++ b/windows/x11drv/keyboard.c
@@ -708,7 +708,7 @@
*
* Handle a X key event
*/
-void X11DRV_KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event )
+void X11DRV_KEYBOARD_HandleEvent( XKeyEvent *event, int x, int y )
{
char Str[24];
KeySym keysym;
@@ -717,8 +717,6 @@
static BOOL force_extended = FALSE; /* hack for AltGr translation */
int ascii_chars;
- INT event_x = (pWnd? pWnd->rectWindow.left : 0) + event->x;
- INT event_y = (pWnd? pWnd->rectWindow.top : 0) + event->y;
DWORD event_time = event->time - X11DRV_server_startticks;
/* this allows support for dead keys */
@@ -745,11 +743,11 @@
{
TRACE_(key)("Alt Gr key event received\n");
event->keycode = kcControl; /* Simulate Control */
- X11DRV_KEYBOARD_HandleEvent( pWnd, event );
+ X11DRV_KEYBOARD_HandleEvent( event, x, y );
event->keycode = kcAlt; /* Simulate Alt */
force_extended = TRUE;
- X11DRV_KEYBOARD_HandleEvent( pWnd, event );
+ X11DRV_KEYBOARD_HandleEvent( event, x, y );
force_extended = FALSE;
/* Here we save the pressed/released state of the AltGr key, to be able to
@@ -783,13 +781,11 @@
switch (vkey & 0xff)
{
case VK_NUMLOCK:
- KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, event->type, event_x, event_y,
- event_time );
+ KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, event->type, x, y, event_time );
break;
case VK_CAPITAL:
TRACE("Caps Lock event. (type %d). State before : %#.2x\n",event->type,pKeyStateTable[vkey]);
- KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, event->type, event_x, event_y,
- event_time );
+ KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, event->type, x, y, event_time );
TRACE("State after : %#.2x\n",pKeyStateTable[vkey]);
break;
default:
@@ -797,19 +793,15 @@
if (!(pKeyStateTable[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask))
{
TRACE("Adjusting NumLock state. \n");
- KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyPress, event_x, event_y,
- event_time );
- KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyRelease, event_x, event_y,
- event_time );
+ KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyPress, x, y, event_time );
+ KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyRelease, x, y, event_time );
}
/* Adjust the CAPSLOCK state if it has been changed outside wine */
if (!(pKeyStateTable[VK_CAPITAL] & 0x01) != !(event->state & LockMask))
{
TRACE("Adjusting Caps Lock state.\n");
- KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyPress, event_x, event_y,
- event_time );
- KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyRelease, event_x, event_y,
- event_time );
+ KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyPress, x, y, event_time );
+ KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyRelease, x, y, event_time );
}
/* Not Num nor Caps : end of intermediary states for both. */
NumState = FALSE;
@@ -823,8 +815,7 @@
if ( vkey & 0x100 ) dwFlags |= KEYEVENTF_EXTENDEDKEY;
if ( force_extended ) dwFlags |= KEYEVENTF_WINE_FORCEEXTENDED;
- KEYBOARD_SendEvent( vkey & 0xff, bScan, dwFlags,
- event_x, event_y, event_time );
+ KEYBOARD_SendEvent( vkey & 0xff, bScan, dwFlags, x, y, event_time );
}
}
}
diff --git a/windows/x11drv/mouse.c b/windows/x11drv/mouse.c
index 255972a..03f68a1 100644
--- a/windows/x11drv/mouse.c
+++ b/windows/x11drv/mouse.c
@@ -154,13 +154,8 @@
/* set the cursor of a window; helper for X11DRV_SetCursor */
static BOOL CALLBACK set_win_cursor( HWND hwnd, LPARAM cursor )
{
- WND *wndPtr = WIN_FindWndPtr(hwnd);
- if (wndPtr)
- {
- Window win = X11DRV_WND_GetXWindow(wndPtr);
- if (win) TSXDefineCursor( thread_display(), win, (Cursor)cursor );
- }
- WIN_ReleaseWndPtr( wndPtr );
+ Window win = X11DRV_get_whole_window( hwnd );
+ if (win) TSXDefineCursor( thread_display(), win, (Cursor)cursor );
return TRUE;
}
diff --git a/windows/x11drv/wnd.c b/windows/x11drv/wnd.c
index 901a13b..601219e 100644
--- a/windows/x11drv/wnd.c
+++ b/windows/x11drv/wnd.c
@@ -40,37 +40,11 @@
WND_DRIVER X11DRV_WND_Driver =
{
- X11DRV_WND_ForceWindowRaise,
- X11DRV_WND_SetHostAttr
+ X11DRV_WND_ForceWindowRaise
};
/***********************************************************************
- * X11DRV_WND_GetXWindow
- *
- * Return the X window associated to a window.
- */
-Window X11DRV_WND_GetXWindow(WND *wndPtr)
-{
- return wndPtr && wndPtr->pDriverData ?
- ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window : 0;
-}
-
-/***********************************************************************
- * X11DRV_WND_FindXWindow
- *
- * Return the the first X window associated to a window chain.
- */
-Window X11DRV_WND_FindXWindow(WND *wndPtr)
-{
- while (wndPtr &&
- !((X11DRV_WND_DATA *) wndPtr->pDriverData)->window)
- wndPtr = wndPtr->parent;
- return wndPtr ?
- ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window : 0;
-}
-
-/***********************************************************************
* X11DRV_WND_IsZeroSizeWnd
*
* Return TRUE if the window has a height or widht less or equal to 0
@@ -101,7 +75,7 @@
return;
}
- if( !wndPtr || !X11DRV_WND_GetXWindow(wndPtr) || (wndPtr->dwExStyle & WS_EX_MANAGED) )
+ if( !wndPtr || !get_whole_window(wndPtr) || (wndPtr->dwExStyle & WS_EX_MANAGED) )
{
WIN_ReleaseDesktop();
return;
@@ -114,9 +88,9 @@
winChanges.stack_mode = Above;
while (wndPtr)
{
- if ( !X11DRV_WND_IsZeroSizeWnd(wndPtr) && X11DRV_WND_GetXWindow(wndPtr) )
- TSXReconfigureWMWindow( thread_display(), X11DRV_WND_GetXWindow(wndPtr), 0,
- CWStackMode, &winChanges );
+ if ( !X11DRV_WND_IsZeroSizeWnd(wndPtr) && get_whole_window(wndPtr) )
+ TSXReconfigureWMWindow( thread_display(), get_whole_window(wndPtr), 0,
+ CWStackMode, &winChanges );
wndPrev = pDesktop->child;
if (wndPrev == wndPtr) break;
@@ -126,345 +100,3 @@
}
WIN_ReleaseDesktop();
}
-
-/***********************************************************************
- * X11DRV_WND_FindDesktopXWindow [Internal]
- *
- * Find the actual X window which needs be restacked.
- * Used by X11DRV_WND_SetWindowPos().
- */
-static Window X11DRV_WND_FindDesktopXWindow( WND *wndPtr )
-{
- if (!(wndPtr->dwExStyle & WS_EX_MANAGED))
- return X11DRV_WND_GetXWindow(wndPtr);
- else
- {
- Window window, root, parent, *children;
- int nchildren;
- window = X11DRV_WND_GetXWindow(wndPtr);
- for (;;)
- {
- TSXQueryTree( thread_display(), window, &root, &parent,
- &children, &nchildren );
- TSXFree( children );
- if (parent == root)
- return window;
- window = parent;
- }
- }
-}
-
-/***********************************************************************
- * WINPOS_SetXWindowPos
- *
- * SetWindowPos() for an X window. Used by the real SetWindowPos().
- */
-void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangePos)
-{
- XWindowChanges winChanges;
- Display *display = thread_display();
- int changeMask = 0;
- BOOL isZeroSizeWnd = FALSE;
- BOOL forceMapWindow = FALSE;
- WND *winposPtr = WIN_FindWndPtr( winpos->hwnd );
- if ( !winposPtr ) return;
-
- /* find out if after this function we will end out with a zero-size window */
- if (X11DRV_WND_IsZeroSizeWnd(winposPtr))
- {
- /* if current size is 0, and no resizing */
- if (winpos->flags & SWP_NOSIZE)
- isZeroSizeWnd = TRUE;
- else if ((winpos->cx > 0) && (winpos->cy > 0))
- {
- /* if this function is setting a new size > 0 for the window, we
- should map the window if WS_VISIBLE is set */
- if ((winposPtr->dwStyle & WS_VISIBLE) && !(winpos->flags & SWP_HIDEWINDOW))
- forceMapWindow = TRUE;
- }
- }
- /* if resizing to 0 */
- if ( !(winpos->flags & SWP_NOSIZE) && ((winpos->cx <= 0) || (winpos->cy <= 0)) )
- isZeroSizeWnd = TRUE;
-
- if(!wndPtr->hwndSelf) wndPtr = NULL; /* FIXME: WND destroyed, shouldn't happen!!! */
-
- if (!(winpos->flags & SWP_SHOWWINDOW) && (winpos->flags & SWP_HIDEWINDOW))
- {
- if(X11DRV_WND_GetXWindow(wndPtr))
- TSXUnmapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
- }
-
- if(bChangePos)
- {
- if ( !(winpos->flags & SWP_NOSIZE))
- {
- winChanges.width = (winpos->cx > 0 ) ? winpos->cx : 1;
- winChanges.height = (winpos->cy > 0 ) ? winpos->cy : 1;
- changeMask |= CWWidth | CWHeight;
-
- /* Tweak dialog window size hints */
-
- if ((winposPtr->dwExStyle & WS_EX_MANAGED) &&
- HAS_DLGFRAME(winposPtr->dwStyle,winposPtr->dwExStyle))
- {
- XSizeHints *size_hints = TSXAllocSizeHints();
-
- if (size_hints)
- {
- long supplied_return;
-
- TSXGetWMSizeHints( display, X11DRV_WND_GetXWindow(winposPtr), size_hints,
- &supplied_return, XA_WM_NORMAL_HINTS);
- size_hints->min_width = size_hints->max_width = winpos->cx;
- size_hints->min_height = size_hints->max_height = winpos->cy;
- TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(winposPtr), size_hints,
- XA_WM_NORMAL_HINTS );
- TSXFree(size_hints);
- }
- }
- }
- if (!(winpos->flags & SWP_NOMOVE))
- {
- winChanges.x = winpos->x;
- winChanges.y = winpos->y;
- changeMask |= CWX | CWY;
- }
- if (!(winpos->flags & SWP_NOZORDER) && !isZeroSizeWnd)
- {
- winChanges.stack_mode = Below;
- changeMask |= CWStackMode;
-
- if (winpos->hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above;
- else if (winpos->hwndInsertAfter != HWND_BOTTOM)
- {
- WND* insertPtr = WIN_FindWndPtr( winpos->hwndInsertAfter );
- Window stack[2];
-
- /* If the window where we should do the insert is zero-sized (not mapped)
- don't used this window since it will possibly crash the X server,
- use the "non zero-sized" window above */
- if (X11DRV_WND_IsZeroSizeWnd(insertPtr))
- {
- /* find the window on top of the zero sized window */
- WND *pDesktop = WIN_GetDesktop();
- WND *wndPrev = pDesktop->child;
- WND *wndZeroSized = insertPtr;
-
- while (1)
- {
- if (wndPrev == wndZeroSized)
- break; /* zero-sized window is on top */
-
- while (wndPrev && (wndPrev->next != wndZeroSized))
- wndPrev = wndPrev->next;
-
- /* check if the window found is not zero-sized */
- if (X11DRV_WND_IsZeroSizeWnd(wndPrev))
- {
- wndZeroSized = wndPrev; /* restart the search */
- wndPrev = pDesktop->child;
- }
- else
- break; /* "above" window is found */
- }
- WIN_ReleaseDesktop();
-
- if (wndPrev == wndZeroSized)
- {
- /* the zero-sized window is on top */
- /* so set the window on top */
- winChanges.stack_mode = Above;
- }
- else
- {
- stack[0] = X11DRV_WND_FindDesktopXWindow( wndPrev );
- stack[1] = X11DRV_WND_FindDesktopXWindow( winposPtr );
-
- TSXRestackWindows(display, stack, 2);
- changeMask &= ~CWStackMode;
- }
- }
- else /* Normal behavior, windows are not zero-sized */
- {
- stack[0] = X11DRV_WND_FindDesktopXWindow( insertPtr );
- stack[1] = X11DRV_WND_FindDesktopXWindow( winposPtr );
-
- TSXRestackWindows(display, stack, 2);
- changeMask &= ~CWStackMode;
- }
-
- WIN_ReleaseWndPtr(insertPtr);
- }
- }
- if (changeMask && X11DRV_WND_GetXWindow(winposPtr))
- {
- TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(winposPtr), 0, changeMask, &winChanges );
- if( winposPtr->clsStyle & (CS_VREDRAW | CS_HREDRAW) )
- X11DRV_WND_SetGravity( winposPtr, ForgetGravity );
- }
- }
-
- /* don't map the window if it's a zero size window */
- if ( ((winpos->flags & SWP_SHOWWINDOW) && !isZeroSizeWnd) || forceMapWindow )
- {
- if(X11DRV_WND_GetXWindow(wndPtr))
- TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
- }
- WIN_ReleaseWndPtr(winposPtr);
-}
-
-/*****************************************************************
- * X11DRV_WND_SurfaceCopy
- *
- * Copies rect to (rect.left + dx, rect.top + dy).
- */
-void X11DRV_WND_SurfaceCopy(WND* wndPtr, HDC hdc, INT dx, INT dy,
- const RECT *rect, BOOL bUpdate)
-{
- X11DRV_PDEVICE *physDev;
- POINT dst, src;
- DC *dcPtr = DC_GetDCPtr( hdc );
-
- if (!dcPtr) return;
- physDev = (X11DRV_PDEVICE *)dcPtr->physDev;
- dst.x = (src.x = dcPtr->DCOrgX + rect->left) + dx;
- dst.y = (src.y = dcPtr->DCOrgY + rect->top) + dy;
-
- wine_tsx11_lock();
- if (bUpdate) /* handles non-Wine windows hanging over the copied area */
- XSetGraphicsExposures( gdi_display, physDev->gc, True );
- XSetFunction( gdi_display, physDev->gc, GXcopy );
- XCopyArea( gdi_display, physDev->drawable, physDev->drawable, physDev->gc,
- src.x, src.y, rect->right - rect->left, rect->bottom - rect->top,
- dst.x, dst.y );
- if (bUpdate)
- XSetGraphicsExposures( gdi_display, physDev->gc, False );
- wine_tsx11_unlock();
- GDI_ReleaseObj( hdc );
-
- if (bUpdate) /* Make sure exposure events have been processed */
- X11DRV_Synchronize();
-}
-
-/***********************************************************************
- * X11DRV_SetWMHint
- */
-static BOOL X11DRV_SetWMHint(Display* display, WND* wndPtr, int hint, int val)
-{
- XWMHints* wm_hints = TSXGetWMHints( display, X11DRV_WND_GetXWindow(wndPtr) );
- 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, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
- TSXFree(wm_hints);
- return TRUE;
- }
- return FALSE;
-}
-
-
-void X11DRV_WND_SetGravity( WND* wnd, int value )
-{
- X11DRV_WND_DATA *data = wnd->pDriverData;
-
- if (data && data->window && data->bit_gravity != value )
- {
- XSetWindowAttributes win_attr;
- win_attr.bit_gravity = value;
- data->bit_gravity = value;
- TSXChangeWindowAttributes( thread_display(), data->window, CWBitGravity, &win_attr );
- }
-}
-
-
-/***********************************************************************
- * X11DRV_WND_SetHostAttr
- *
- * This function returns TRUE if the attribute is supported and the
- * action was successful. Otherwise it should return FALSE and Wine will try
- * to get by without the functionality provided by the host window system.
- */
-BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value)
-{
- Window w;
-
- if( (w = X11DRV_WND_GetXWindow(wnd)) )
- {
- Display *display = thread_display();
- switch( ha )
- {
- case HAK_ICONICSTATE: /* called when a window is minimized/restored */
-
- /* don't do anything if it'a zero size window */
- if (X11DRV_WND_IsZeroSizeWnd(wnd))
- return TRUE;
-
- if( (wnd->dwExStyle & WS_EX_MANAGED) )
- {
- if( value )
- {
- if( wnd->dwStyle & WS_VISIBLE )
- {
- XClientMessageEvent ev;
-
- /* FIXME: set proper icon */
-
- ev.type = ClientMessage;
- ev.display = display;
- ev.message_type = wmChangeState;
- ev.format = 32;
- ev.data.l[0] = IconicState;
- ev.window = w;
-
- if( TSXSendEvent (display, DefaultRootWindow(display),
- True, (SubstructureRedirectMask | SubstructureNotifyMask), (XEvent*)&ev))
- {
- XEvent xe;
- TSXFlush (display);
- while( !TSXCheckTypedWindowEvent( display, w, UnmapNotify, &xe) );
- }
- else
- break;
- }
- else
- X11DRV_SetWMHint( display, wnd, StateHint, IconicState );
- }
- else
- {
- if( !(wnd->flags & WS_VISIBLE) )
- X11DRV_SetWMHint( display, wnd, StateHint, NormalState );
- else
- {
- XEvent xe;
- TSXMapWindow(display, w );
- while( !TSXCheckTypedWindowEvent( display, w, MapNotify, &xe) );
- }
- }
- return TRUE;
- }
- break;
- }
- }
- return FALSE;
-}