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.
This commit is contained in:
Alexandre Julliard 2001-06-04 21:55:17 +00:00
parent d7c69a5d5f
commit dc4fe7735b
29 changed files with 2806 additions and 3450 deletions

View File

@ -27,7 +27,7 @@ debug_channels (ttydrv)
@ 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

View File

@ -17,8 +17,7 @@ DEFAULT_DEBUG_CHANNEL(ttydrv);
WND_DRIVER TTYDRV_WND_Driver =
{
TTYDRV_WND_ForceWindowRaise,
TTYDRV_WND_SetHostAttr
TTYDRV_WND_ForceWindowRaise
};
#define SWP_AGG_NOGEOMETRYCHANGE \
@ -31,8 +30,10 @@ WND_DRIVER TTYDRV_WND_Driver =
/**********************************************************************
* 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 @@ BOOL TTYDRV_CreateWindow( HWND hwnd )
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 @@ void TTYDRV_WND_ForceWindowRaise(WND *wndPtr)
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

View File

@ -89,6 +89,7 @@ static BOOL load_driver(void)
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 @@ static BOOL load_driver(void)
GET_USER_FUNC(SetWindowRgn);
GET_USER_FUNC(SetWindowIcon);
GET_USER_FUNC(SetWindowText);
GET_USER_FUNC(ShowWindow);
GET_USER_FUNC(SysCommandSizeMove);
return TRUE;

View File

@ -9,6 +9,7 @@ IMPORTS = user32 gdi32 kernel32
C_SRCS = \
desktop.c \
dga2.c \
scroll.c \
window.c \
winpos.c \
x11ddraw.c \

View File

@ -55,11 +55,14 @@ static DWORD CALLBACK desktop_thread( LPVOID driver_data )
/* 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;

234
dlls/x11drv/scroll.c Normal file
View File

@ -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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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 @@ static void GrabPointer(HWND hWnd)
{
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);
}

View File

@ -27,11 +27,12 @@ debug_channels (bitblt bitmap clipboard cursor dinput event font gdi graphics
@ cdecl GetScreenSaveTimeout() X11DRV_GetScreenSaveTimeout
@ cdecl SetScreenSaveTimeout(long) X11DRV_SetScreenSaveTimeout
@ cdecl LoadOEMResource(long long) X11DRV_LoadOEMResource
@ cdecl CreateWindow(long) X11DRV_CreateWindow
@ cdecl 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 @@ debug_channels (bitblt bitmap clipboard cursor dinput event font gdi graphics
@ 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

View File

@ -1306,28 +1306,22 @@ static BOOL BITBLT_InternalStretchBlt( DC *dcDst, INT xDst, INT yDst,
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 @@ static BOOL BITBLT_InternalStretchBlt( DC *dcDst, INT xDst, INT yDst,
}
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 );

View File

@ -41,6 +41,7 @@ BOOL X11DRV_BITMAP_Init(void)
{
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 @@ BOOL X11DRV_BITMAP_Init(void)
{
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 @@ HBITMAP X11DRV_BITMAP_SelectObject( DC * dc, HBITMAP hbitmap,
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 );

View File

@ -72,3 +72,102 @@ void X11DRV_SetDeviceClipping( DC * dc )
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 );
}
}

View File

@ -69,11 +69,12 @@ typedef struct tagUSER_DRIVER {
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 @@ typedef struct tagUSER_DRIVER {
BOOL (*pSetWindowRgn)(HWND,HRGN,BOOL);
HICON (*pSetWindowIcon)(HWND,HICON,BOOL);
BOOL (*pSetWindowText)(HWND,LPCWSTR);
BOOL (*pShowWindow)(HWND,INT);
void (*pSysCommandSizeMove)(HWND,WPARAM);
} USER_DRIVER;

View File

@ -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 @@ typedef struct tagWND
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 @@ typedef struct
#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 WND** WIN_BuildWinArray( WND *wndPtr, UINT bwa, UINT* pnum );
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 HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType ); /* windows/defwnd.c
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 @@ extern void CLASS_FreeModuleClasses( HMODULE16 hModule );
/* 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 */

View File

@ -28,7 +28,6 @@ extern BOOL WINPOS_ShowIconTitle( struct tagWND* pWnd, BOOL bShow );
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 );

View File

@ -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 HBITMAP X11DRV_BITMAP_CreateBitmapFromPixmap(Pixmap pixmap, BOOL bDeleteP
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 @@ struct x11drv_thread_data
{
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_width;
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 BOOL X11DRV_GetClipboardData(UINT wFormat);
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 void X11DRV_SendEvent( DWORD mouseStatus, DWORD posX, DWORD posY,
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 */

View File

@ -211,9 +211,9 @@ static void DCE_DeleteClipRgn( DCE* dce )
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 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
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 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
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 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
{
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 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
}
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 @@ HDC WINAPI GetDC(
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 @@ HDC WINAPI GetDC(
*/
HDC16 WINAPI GetWindowDC16( HWND16 hwnd )
{
if (!hwnd) hwnd = GetDesktopWindow16();
return GetDCEx16( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
}
@ -601,7 +584,6 @@ HDC16 WINAPI GetWindowDC16( HWND16 hwnd )
*/
HDC WINAPI GetWindowDC( HWND hwnd )
{
if (!hwnd) hwnd = GetDesktopWindow();
return GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
}

View File

@ -415,11 +415,7 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT msg, WPARAM wParam,
}
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:

View File

@ -75,24 +75,6 @@ static const BYTE lpGrayMask[] = { 0xAA, 0xA0,
#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 @@ static void NC_AdjustRect( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle )
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 @@ NC_AdjustRectOuter95 (LPRECT rect, DWORD style, BOOL menu, DWORD exStyle)
{
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 @@ NC_AdjustRectInner95 (LPRECT rect, DWORD style, DWORD exStyle)
}
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 @@ DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
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 @@ void NC_GetInsideRect( HWND hwnd, RECT *rect )
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 @@ static LONG NC_DoNCHitTest (WND *wndPtr, POINT pt )
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 @@ static LONG NC_DoNCHitTest95 (WND *wndPtr, POINT pt )
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 @@ void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
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 @@ void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
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_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
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 @@ static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
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 @@ NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
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_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
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_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
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 @@ static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
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 @@ static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
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 @@ static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
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 @@ static void NC_DrawCaption95(
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 @@ static void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
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 @@ static void NC_DoNCPaint95(
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 @@ BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
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;
}

View File

@ -28,6 +28,17 @@ DECLARE_DEBUG_CHANNEL(nonclient);
(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 @@ static BOOL WIN_HaveToDelayNCPAINT(
* 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 @@ HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps )
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 @@ HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps )
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 @@ END:
* 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 @@ static void RDW_UpdateRgns( WND* wndPtr, HRGN hRgn, UINT flags, BOOL firstRecurs
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 @@ static HRGN RDW_Paint( WND* wndPtr, HRGN hrgn, UINT flags, UINT ex )
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 @@ static HRGN RDW_Paint( WND* wndPtr, HRGN hrgn, UINT flags, UINT ex )
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 @@ static HRGN RDW_Paint( WND* wndPtr, HRGN hrgn, UINT flags, UINT ex )
}
if( !IsWindow(hWnd) ) return hrgn;
ex &= ~RDW_EX_TOPFRAME;
/* ... and its child windows */
@ -820,12 +828,12 @@ static HRGN RDW_Paint( WND* wndPtr, HRGN hrgn, UINT flags, UINT ex )
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 @@ BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate,
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 @@ BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate,
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 @@ BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate,
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 @@ rect2i:
{
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 @@ rect2v:
else
{
GETCLIENTRECTW( wndPtr, r2 );
goto rect2v;
hRgn = CreateRectRgnIndirect( &r2 );
}
}
}
@ -956,7 +955,7 @@ rect2v:
/* 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) )
@ -966,16 +965,6 @@ END:
}
/***********************************************************************
* 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)
*/

View File

@ -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 @@ BOOL WINAPI ScrollDC( HDC hdc, INT dx, INT dy, const RECT *rc,
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;
}

View File

@ -553,6 +553,7 @@ BOOL WIN_CreateDesktopWindow(void)
DWORD clsStyle;
WNDPROC winproc;
DCE *dce;
CREATESTRUCTA cs;
TRACE("Creating desktop window\n");
@ -601,9 +602,21 @@ BOOL WIN_CreateDesktopWindow(void)
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;
if (!USER_Driver.pCreateWindow( hwndDesktop, &cs )) return FALSE;
SendMessageW( hwndDesktop, WM_NCCREATE, 0, 0 );
pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
return TRUE;
}
@ -685,14 +698,12 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
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 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
TRACE("CBT-hook returned 0\n");
USER_HEAP_FREE( hwnd );
CLASS_RemoveWindow( classPtr );
retvalue = 0;
hwnd = 0;
goto end;
}
}
@ -862,12 +873,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
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 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
}
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 GetWindowTextA( HWND hwnd, LPSTR lpString, INT nMaxCount )
*/
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);
}

View File

@ -42,8 +42,6 @@ DEFAULT_DEBUG_CHANNEL(win);
#define PLACE_MAX 0x0002
#define PLACE_RECT 0x0004
#define MINMAX_NOSWP 0x00010000
#define DWP_MAGIC ((INT)('W' | ('P' << 8) | ('O' << 16) | ('S' << 24)))
@ -118,58 +116,6 @@ void WINPOS_CheckInternalPos( WND* wndPtr )
return;
}
/***********************************************************************
* 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)
*/
@ -440,7 +386,8 @@ INT16 WINPOS_WindowFromPoint( WND* wndScope, POINT pt, WND **ppWnd )
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 @@ void WINPOS_GetMinMaxInfo( WND *wndPtr, POINT *maxSize, POINT *maxPos,
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);
@ -1206,107 +1152,6 @@ void WINPOS_GetMinMaxInfo( WND *wndPtr, POINT *maxSize, POINT *maxPos,
if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
}
/***********************************************************************
* 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.@)
*
@ -1332,140 +1177,9 @@ BOOL16 WINAPI ShowWindow16( HWND16 hwnd, INT16 cmd )
/***********************************************************************
* 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 );
}

View File

@ -315,7 +315,6 @@ int X11DRV_CLIPBOARD_CacheDataFormats( Atom SelectionName )
Display *display = thread_display();
HWND hWnd = 0;
HWND hWndClipWindow = GetOpenClipboardWindow();
WND* wnd = NULL;
XEvent xe;
Atom aTargets;
Atom atype=AnyPropertyType;
@ -343,10 +342,7 @@ int X11DRV_CLIPBOARD_CacheDataFormats( Atom SelectionName )
/*
* 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 @@ void X11DRV_AcquireClipboard(void)
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 X11DRV_GetClipboardData(UINT wFormat)
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 @@ void X11DRV_ResetSelectionOwner(WND *pWnd, BOOL bFooBar)
{
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 @@ void X11DRV_ResetSelectionOwner(WND *pWnd, BOOL bFooBar)
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 )
{

View File

@ -51,7 +51,7 @@ extern Atom dndProtocol;
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_MotionNotify( HWND hWnd, XMotionEvent *event );
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_DGAButtonPressEvent( XDGAButtonEvent *event );
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 @@ static BOOL in_transition = FALSE; /* This is not used as for today */
/***********************************************************************
* 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 @@ DWORD X11DRV_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
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 @@ static void EVENT_ProcessEvent( XEvent *event )
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 @@ static void EVENT_ProcessEvent( XEvent *event )
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 @@ static void EVENT_ProcessEvent( XEvent *event )
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:
@ -445,136 +369,6 @@ static void EVENT_ProcessEvent( XEvent *event )
TRACE( "returns.\n" );
}
/***********************************************************************
* 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
*
@ -593,62 +387,74 @@ WORD X11DRV_EVENT_XStateToKeyState( int state )
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_GraphicsExpose( HWND hWnd, XGraphicsExposeEvent *event )
*/
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_Key( HWND hWnd, XKeyEvent *event )
*/
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_MotionNotify( HWND hWnd, XMotionEvent *event )
*/
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_ButtonPress( HWND hWnd, XButtonEvent *event )
*/
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_ButtonRelease( HWND hWnd, XButtonEvent *event )
*/
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_FocusIn( HWND hWnd, XFocusChangeEvent *event )
*/
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 @@ static BOOL X11DRV_CheckFocus(void)
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 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event )
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 @@ static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event )
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)
{
/* 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 ( 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 0
/* enable this if you want to see the message */
@ -1782,65 +1516,6 @@ static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event )
}
}
/**********************************************************************
* 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

View File

@ -708,7 +708,7 @@ void X11DRV_KEYBOARD_UpdateState ( void )
*
* 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 @@ void X11DRV_KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event )
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 @@ void X11DRV_KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event )
{
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 @@ void X11DRV_KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event )
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 @@ void X11DRV_KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event )
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 @@ void X11DRV_KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event )
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 );
}
}
}

View File

@ -154,13 +154,8 @@ Cursor X11DRV_GetCursor( Display *display, CURSORICONINFO *ptr )
/* 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;
}

View File

@ -40,36 +40,10 @@ extern Atom wmChangeState;
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
*
@ -101,7 +75,7 @@ void X11DRV_WND_ForceWindowRaise(WND *wndPtr)
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 @@ void X11DRV_WND_ForceWindowRaise(WND *wndPtr)
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 @@ void X11DRV_WND_ForceWindowRaise(WND *wndPtr)
}
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;
}