Fixes for ignored WVR_[VH]REDRAW flags, made minimization in managed

mode go through window manager, small bugfixes for menu and window
code, extended clipboard driver model to handle formats other than
text.
This commit is contained in:
Alex Korobka 1999-04-01 12:03:52 +00:00 committed by Alexandre Julliard
parent dc75bd4038
commit 44a1b59cec
20 changed files with 548 additions and 318 deletions

View file

@ -1177,10 +1177,11 @@ static void MENU_DrawPopupMenu( HWND hwnd, HDC hdc, HMENU hmenu )
GetClientRect( hwnd, &rect ); GetClientRect( hwnd, &rect );
/* if(!TWEAK_Win95Look) { */ if(TWEAK_WineLook == WIN31_LOOK)
{
rect.bottom -= POPUP_YSHADE * SYSMETRICS_CYBORDER; rect.bottom -= POPUP_YSHADE * SYSMETRICS_CYBORDER;
rect.right -= POPUP_XSHADE * SYSMETRICS_CXBORDER; rect.right -= POPUP_XSHADE * SYSMETRICS_CXBORDER;
/* } */ }
if((hPrevBrush = SelectObject( hdc, GetSysColorBrush(COLOR_MENU) ))) if((hPrevBrush = SelectObject( hdc, GetSysColorBrush(COLOR_MENU) )))
{ {
@ -1397,8 +1398,11 @@ static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id,
} }
if( y < 0 ) y = 0; if( y < 0 ) y = 0;
width += POPUP_XSHADE * SYSMETRICS_CXBORDER; /* add space for shading */ if( TWEAK_WineLook == WIN31_LOOK )
height += POPUP_YSHADE * SYSMETRICS_CYBORDER; {
width += POPUP_XSHADE * SYSMETRICS_CXBORDER; /* add space for shading */
height += POPUP_YSHADE * SYSMETRICS_CYBORDER;
}
/* NOTE: In Windows, top menu popup is not owned. */ /* NOTE: In Windows, top menu popup is not owned. */
if (!pTopPopupWnd) /* create top level popup menu window */ if (!pTopPopupWnd) /* create top level popup menu window */

View file

@ -530,4 +530,15 @@ BOOL X11DRV_BITMAP_DeleteObject( HBITMAP hbitmap, BITMAPOBJ * bmp )
return TRUE; return TRUE;
} }
/***********************************************************************
* X11DRV_BITMAP_Pixmap
*
* This function exists solely for x11 driver of the window system.
*/
BOOL X11DRV_BITMAP_Pixmap(HBITMAP hbitmap)
{
BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
return ((X11DRV_PHYSBITMAP *)(bmp->DDBitmap->physBitmap))->pixmap;
}
#endif /* !defined(X_DISPLAY_MISSING) */ #endif /* !defined(X_DISPLAY_MISSING) */

View file

@ -19,9 +19,9 @@ typedef struct tagWINE_CLIPFORMAT {
typedef struct tagCLIPBOARD_DRIVER typedef struct tagCLIPBOARD_DRIVER
{ {
void (*pEmptyClipboard)(void); void (*pEmpty)(void);
void (*pSetClipboardData)(UINT); void (*pSetData)(UINT);
BOOL (*pRequestSelection)(void); BOOL (*pGetData)(UINT);
void (*pResetOwner)(struct tagWND *, BOOL); void (*pResetOwner)(struct tagWND *, BOOL);
} CLIPBOARD_DRIVER; } CLIPBOARD_DRIVER;

View file

@ -43,6 +43,7 @@ extern int TSXInitThreads(void);
extern int * TSXListDepths(Display*, int, int*); extern int * TSXListDepths(Display*, int, int*);
extern int TSXReconfigureWMWindow(Display*, Window, int, unsigned int, XWindowChanges*); extern int TSXReconfigureWMWindow(Display*, Window, int, unsigned int, XWindowChanges*);
extern int TSXSetWMProtocols(Display*, Window, Atom*, int); extern int TSXSetWMProtocols(Display*, Window, Atom*, int);
extern int TSXIconifyWindow(Display*, Window, int);
extern int TSXSetTransientForHint(Display*, Window, Window); extern int TSXSetTransientForHint(Display*, Window, Window);
extern int TSXActivateScreenSaver(Display*); extern int TSXActivateScreenSaver(Display*);
extern int TSXAllocColor(Display*, Colormap, XColor*); extern int TSXAllocColor(Display*, Colormap, XColor*);

View file

@ -68,9 +68,9 @@ extern void TTYDRV_USER_EndDebugging(void);
extern struct tagCLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver; extern struct tagCLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver;
extern void TTYDRV_CLIPBOARD_EmptyClipboard(void); extern void TTYDRV_CLIPBOARD_Empty(void);
extern void TTYDRV_CLIPBOARD_SetClipboardData(UINT wFormat); extern void TTYDRV_CLIPBOARD_SetData(UINT wFormat);
extern BOOL TTYDRV_CLIPBOARD_RequestSelection(void); extern BOOL TTYDRV_CLIPBOARD_GetData(UINT wFormat);
extern void TTYDRV_CLIPBOARD_ResetOwner(struct tagWND *pWnd, BOOL bFooBar); extern void TTYDRV_CLIPBOARD_ResetOwner(struct tagWND *pWnd, BOOL bFooBar);
/* TTY desktop driver */ /* TTY desktop driver */

View file

@ -92,6 +92,7 @@ typedef struct tagWND
#define HAK_BITGRAVITY 1 #define HAK_BITGRAVITY 1
#define HAK_ACCEPTFOCUS 2 #define HAK_ACCEPTFOCUS 2
#define HAK_ICONICSTATE 3
/* Bit Gravity */ /* Bit Gravity */

View file

@ -31,7 +31,7 @@ extern BOOL WINPOS_ShowIconTitle( WND* pWnd, BOOL bShow );
extern void WINPOS_GetMinMaxInfo( WND* pWnd, POINT *maxSize, extern void WINPOS_GetMinMaxInfo( WND* pWnd, POINT *maxSize,
POINT *maxPos, POINT *minTrack, POINT *maxPos, POINT *minTrack,
POINT *maxTrack ); POINT *maxTrack );
extern UINT16 WINPOS_MinMaximize( WND* pWnd, UINT16 cmd, LPRECT16 lpPos); extern UINT WINPOS_MinMaximize( WND* pWnd, UINT16 cmd, LPRECT16 lpPos);
extern BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, extern BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse,
BOOL fChangeFocus ); BOOL fChangeFocus );
extern BOOL WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); extern BOOL WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg );

View file

@ -313,13 +313,11 @@ extern void X11DRV_USER_EndDebugging(void);
extern struct tagCLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver; extern struct tagCLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver;
extern void X11DRV_CLIPBOARD_EmptyClipboard(void); extern void X11DRV_CLIPBOARD_Empty(void);
extern void X11DRV_CLIPBOARD_SetClipboardData(UINT wFormat); extern void X11DRV_CLIPBOARD_SetData(UINT wFormat);
extern BOOL X11DRV_CLIPBOARD_RequestSelection(void); extern BOOL X11DRV_CLIPBOARD_GetData(UINT wFormat);
extern void X11DRV_CLIPBOARD_ResetOwner(struct tagWND *pWnd, BOOL bFooBar); extern void X11DRV_CLIPBOARD_ResetOwner(struct tagWND *pWnd, BOOL bFooBar);
extern void X11DRV_CLIPBOARD_ReleaseSelection(Window w, HWND hwnd);
void X11DRV_CLIPBOARD_ReadSelection(Window w, Atom prop);
void X11DRV_CLIPBOARD_ReleaseSelection(Window w, HWND hwnd);
/* X11 desktop driver */ /* X11 desktop driver */
@ -415,6 +413,7 @@ extern struct tagWND_DRIVER X11DRV_WND_Driver;
typedef struct _X11DRV_WND_DATA { typedef struct _X11DRV_WND_DATA {
Window window; Window window;
HBITMAP hWMIconBitmap;
int bit_gravity; int bit_gravity;
} X11DRV_WND_DATA; } X11DRV_WND_DATA;

View file

@ -77,6 +77,7 @@ XGetWMSizeHints
XGetWindowAttributes XGetWindowAttributes
XGetWindowProperty XGetWindowProperty
XGrabServer XGrabServer
XIconifyWindow
XInitThreads XInitThreads
XInstallColormap XInstallColormap
XInternAtom XInternAtom

View file

@ -308,6 +308,17 @@ int TSXSetWMProtocols(Display* a0, Window a1, Atom* a2, int a3)
return r; return r;
} }
int TSXIconifyWindow(Display* a0, Window a1, int a2)
{
int r;
TRACE(x11, "Call XIconifyWindow\n");
EnterCriticalSection( &X11DRV_CritSection );
r = XIconifyWindow(a0, a1, a2);
LeaveCriticalSection( &X11DRV_CritSection );
TRACE(x11, "Ret XIconifyWindow\n");
return r;
}
int TSXSetTransientForHint(Display* a0, Window a1, Window a2) int TSXSetTransientForHint(Display* a0, Window a1, Window a2)
{ {
int r; int r;

View file

@ -250,7 +250,7 @@ BOOL WINAPI EmptyClipboard(void)
hWndClipOwner = hWndClipWindow; hWndClipOwner = hWndClipWindow;
CLIPBOARD_Driver->pEmptyClipboard(); CLIPBOARD_Driver->pEmpty();
return TRUE; return TRUE;
} }
@ -293,7 +293,7 @@ HANDLE16 WINAPI SetClipboardData16( UINT16 wFormat, HANDLE16 hData )
if( (hqClipLock != GetFastQueue16()) || !lpFormat || if( (hqClipLock != GetFastQueue16()) || !lpFormat ||
(!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0; (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
CLIPBOARD_Driver->pSetClipboardData(wFormat); CLIPBOARD_Driver->pSetData(wFormat);
if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 ) if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
{ {
@ -323,7 +323,7 @@ HANDLE16 WINAPI SetClipboardData16( UINT16 wFormat, HANDLE16 hData )
/************************************************************************** /**************************************************************************
* SetClipboardData32 (USER32.470) * SetClipboardData (USER32.470)
*/ */
HANDLE WINAPI SetClipboardData( UINT wFormat, HANDLE hData ) HANDLE WINAPI SetClipboardData( UINT wFormat, HANDLE hData )
{ {
@ -341,7 +341,7 @@ HANDLE WINAPI SetClipboardData( UINT wFormat, HANDLE hData )
if( (hqClipLock != GetFastQueue16()) || !lpFormat || if( (hqClipLock != GetFastQueue16()) || !lpFormat ||
(!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0; (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
CLIPBOARD_Driver->pSetClipboardData(wFormat); CLIPBOARD_Driver->pSetData(wFormat);
if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 ) if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
{ {
@ -395,6 +395,9 @@ static BOOL CLIPBOARD_RenderFormat(LPWINE_CLIPFORMAT lpFormat)
* CLIPBOARD_RenderText * CLIPBOARD_RenderText
* *
* Convert text between UNIX and DOS formats. * Convert text between UNIX and DOS formats.
*
* FIXME: Should be a pair of driver functions that convert between OEM text and Windows.
*
*/ */
static BOOL CLIPBOARD_RenderText(LPWINE_CLIPFORMAT lpTarget, LPWINE_CLIPFORMAT lpSource) static BOOL CLIPBOARD_RenderText(LPWINE_CLIPFORMAT lpTarget, LPWINE_CLIPFORMAT lpSource)
{ {
@ -608,15 +611,13 @@ INT WINAPI CountClipboardFormats(void)
TRACE(clipboard,"(void)\n"); TRACE(clipboard,"(void)\n");
/* FIXME: Returns BOOL32 */
CLIPBOARD_Driver->pRequestSelection();
FormatCount += abs(lpFormat[CF_TEXT-1].wDataPresent -
lpFormat[CF_OEMTEXT-1].wDataPresent);
while(TRUE) while(TRUE)
{ {
if (lpFormat == NULL) break; if (lpFormat == NULL) break;
if( lpFormat->wFormatID != CF_TEXT )
CLIPBOARD_Driver->pGetData( lpFormat->wFormatID );
if (lpFormat->wDataPresent) if (lpFormat->wDataPresent)
{ {
TRACE(clipboard, "\tdata found for format %i\n", lpFormat->wFormatID); TRACE(clipboard, "\tdata found for format %i\n", lpFormat->wFormatID);
@ -625,6 +626,11 @@ INT WINAPI CountClipboardFormats(void)
lpFormat = lpFormat->NextFormat; lpFormat = lpFormat->NextFormat;
} }
/* these two are equivalent, adjust the total */
FormatCount += abs(ClipFormats[CF_TEXT-1].wDataPresent -
ClipFormats[CF_OEMTEXT-1].wDataPresent);
TRACE(clipboard,"\ttotal %d\n", FormatCount); TRACE(clipboard,"\ttotal %d\n", FormatCount);
return FormatCount; return FormatCount;
} }
@ -650,29 +656,30 @@ UINT WINAPI EnumClipboardFormats( UINT wFormat )
if( hqClipLock != GetFastQueue16() ) return 0; if( hqClipLock != GetFastQueue16() ) return 0;
if( (!wFormat || wFormat == CF_TEXT || wFormat == CF_OEMTEXT) ) if( wFormat < CF_OEMTEXT )
CLIPBOARD_Driver->pRequestSelection(); CLIPBOARD_Driver->pGetData( CF_OEMTEXT );
if (wFormat == 0) if (wFormat == 0) /* start from the beginning */
lpFormat = ClipFormats;
else
{ {
if (lpFormat->wDataPresent || ClipFormats[CF_OEMTEXT-1].wDataPresent) /* walk up to the specified format record */
return lpFormat->wFormatID;
else if( !(lpFormat = __lookup_format( lpFormat, wFormat )) )
wFormat = lpFormat->wFormatID; /* and CF_TEXT is not available */ return 0;
lpFormat = lpFormat->NextFormat; /* right */
} }
/* walk up to the specified format record */
if( !(lpFormat = __lookup_format( lpFormat, wFormat )) ) return 0;
/* find next format with available data */
lpFormat = lpFormat->NextFormat;
while(TRUE) while(TRUE)
{ {
if (lpFormat == NULL) return 0; if (lpFormat == NULL) return 0;
if (lpFormat->wDataPresent || (lpFormat->wFormatID == CF_OEMTEXT &&
ClipFormats[CF_TEXT-1].wDataPresent)) if( lpFormat->wFormatID != CF_OEMTEXT && lpFormat->wFormatID != CF_TEXT )
CLIPBOARD_Driver->pGetData( lpFormat->wFormatID );
if (lpFormat->wDataPresent ||
(lpFormat->wFormatID == CF_OEMTEXT && ClipFormats[CF_TEXT-1].wDataPresent) ||
(lpFormat->wFormatID == CF_TEXT && ClipFormats[CF_OEMTEXT-1].wDataPresent) )
break; break;
lpFormat = lpFormat->NextFormat; lpFormat = lpFormat->NextFormat;
} }
@ -877,8 +884,7 @@ BOOL WINAPI IsClipboardFormatAvailable( UINT wFormat )
{ {
TRACE(clipboard,"(%04X) !\n", wFormat); TRACE(clipboard,"(%04X) !\n", wFormat);
if( (wFormat == CF_TEXT || wFormat == CF_OEMTEXT) ) CLIPBOARD_Driver->pGetData( (wFormat == CF_TEXT) ? CF_OEMTEXT : wFormat );
CLIPBOARD_Driver->pRequestSelection();
return CLIPBOARD_IsPresent(wFormat); return CLIPBOARD_IsPresent(wFormat);
} }

View file

@ -502,12 +502,14 @@ static BOOL MSG_PeekHardwareMsg( MSG *msg, HWND hwnd, DWORD first, DWORD last,
qmsg = sysMsgQueue->firstMsg; qmsg = sysMsgQueue->firstMsg;
#if 0
/* If the queue is empty, attempt to fill it */ /* If the queue is empty, attempt to fill it */
if (!sysMsgQueue->msgCount && THREAD_IsWin16( THREAD_Current() ) if (!sysMsgQueue->msgCount && THREAD_IsWin16( THREAD_Current() )
&& EVENT_Pending()) && EVENT_Pending())
EVENT_WaitNetEvent( FALSE, FALSE ); {
#endif LeaveCriticalSection(&sysMsgQueue->cSection);
EVENT_WaitNetEvent( FALSE, TRUE );
EnterCriticalSection(&sysMsgQueue->cSection);
}
for ( kbd_msg = 0; qmsg; qmsg = nextqmsg) for ( kbd_msg = 0; qmsg; qmsg = nextqmsg)
{ {

View file

@ -15,7 +15,7 @@ char *TTYDRV_CLIPBOARD_szSelection = NULL;
/*********************************************************************** /***********************************************************************
* TTYDRV_CLIPBOARD_EmptyClipboard * TTYDRV_CLIPBOARD_EmptyClipboard
*/ */
void TTYDRV_CLIPBOARD_EmptyClipboard() void TTYDRV_CLIPBOARD_Empty()
{ {
if(TTYDRV_CLIPBOARD_szSelection) if(TTYDRV_CLIPBOARD_szSelection)
{ {
@ -25,16 +25,16 @@ void TTYDRV_CLIPBOARD_EmptyClipboard()
} }
/*********************************************************************** /***********************************************************************
* TTYDRV_CLIPBOARD_SetClipboardData * TTYDRV_CLIPBOARD_SetData
*/ */
void TTYDRV_CLIPBOARD_SetClipboardData(UINT wFormat) void TTYDRV_CLIPBOARD_SetData(UINT wFormat)
{ {
} }
/*********************************************************************** /***********************************************************************
* TTYDRV_CLIPBOARD_RequestSelection * TTYDRV_CLIPBOARD_GetData
*/ */
BOOL TTYDRV_CLIPBOARD_RequestSelection() BOOL TTYDRV_CLIPBOARD_GetData(UINT wFormat)
{ {
return FALSE; return FALSE;
} }

View file

@ -24,9 +24,9 @@ USER_DRIVER TTYDRV_USER_Driver =
CLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver = CLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver =
{ {
TTYDRV_CLIPBOARD_EmptyClipboard, TTYDRV_CLIPBOARD_Empty,
TTYDRV_CLIPBOARD_SetClipboardData, TTYDRV_CLIPBOARD_SetData,
TTYDRV_CLIPBOARD_RequestSelection, TTYDRV_CLIPBOARD_GetData,
TTYDRV_CLIPBOARD_ResetOwner TTYDRV_CLIPBOARD_ResetOwner
}; };

View file

@ -836,10 +836,14 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
/* Correct the window style */ /* Correct the window style */
if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */ if (!(cs->style & WS_CHILD))
{ {
wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS; wndPtr->dwStyle |= WS_CLIPSIBLINGS;
wndPtr->flags |= WIN_NEED_SIZE; if (!(cs->style & WS_POPUP))
{
wndPtr->dwStyle |= WS_CAPTION;
wndPtr->flags |= WIN_NEED_SIZE;
}
} }
if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME; if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
@ -2701,13 +2705,10 @@ WND **WIN_BuildWinArray( WND *wndPtr, UINT bwaFlags, UINT* pTotal )
pWnd = WIN_LockWndPtr(wndPtr->child); pWnd = WIN_LockWndPtr(wndPtr->child);
while (pWnd) while (pWnd)
{ {
if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue; if( !(pWnd->dwStyle & skipFlags) && !(skipOwned && pWnd->owner) &&
if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) (!skipHidden || (pWnd->dwStyle & WS_VISIBLE)) )
{
count++; count++;
WIN_UpdateWndPtr(&pWnd,pWnd->next); WIN_UpdateWndPtr(&pWnd,pWnd->next);
}
} }
if( count ) if( count )

View file

@ -48,6 +48,8 @@
#define SWP_EX_NOCOPY 0x0001 #define SWP_EX_NOCOPY 0x0001
#define SWP_EX_PAINTSELF 0x0002 #define SWP_EX_PAINTSELF 0x0002
#define MINMAX_NOSWP 0x00010000
/* ----- internal variables ----- */ /* ----- internal variables ----- */
static HWND hwndPrevActive = 0; /* Previously active window */ static HWND hwndPrevActive = 0; /* Previously active window */
@ -1138,9 +1140,9 @@ void WINPOS_GetMinMaxInfo( WND *wndPtr, POINT *maxSize, POINT *maxPos,
* This function assumes that 'cmd' is different from the current window * This function assumes that 'cmd' is different from the current window
* state. * state.
*/ */
UINT16 WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect ) UINT WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
{ {
UINT16 swpFlags = 0; UINT swpFlags = 0;
POINT pt; POINT pt;
POINT size = { wndPtr->rectWindow.left, wndPtr->rectWindow.top }; POINT size = { wndPtr->rectWindow.left, wndPtr->rectWindow.top };
LPINTERNALPOS lpPos = WINPOS_InitInternalPos( wndPtr, size, LPINTERNALPOS lpPos = WINPOS_InitInternalPos( wndPtr, size,
@ -1168,6 +1170,10 @@ UINT16 WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
wndPtr->flags &= ~WIN_RESTORE_MAX; wndPtr->flags &= ~WIN_RESTORE_MAX;
wndPtr->dwStyle |= WS_MINIMIZE; wndPtr->dwStyle |= WS_MINIMIZE;
if( wndPtr->flags & WIN_NATIVE )
if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) )
swpFlags |= MINMAX_NOSWP;
lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos ); lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
SetRect16( lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y, SetRect16( lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
@ -1182,6 +1188,10 @@ UINT16 WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
if( wndPtr->dwStyle & WS_MINIMIZE ) if( wndPtr->dwStyle & WS_MINIMIZE )
{ {
if( wndPtr->flags & WIN_NATIVE )
if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
swpFlags |= MINMAX_NOSWP;
WINPOS_ShowIconTitle( wndPtr, FALSE ); WINPOS_ShowIconTitle( wndPtr, FALSE );
wndPtr->dwStyle &= ~WS_MINIMIZE; wndPtr->dwStyle &= ~WS_MINIMIZE;
} }
@ -1194,8 +1204,13 @@ UINT16 WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
case SW_RESTORE: case SW_RESTORE:
if( wndPtr->dwStyle & WS_MINIMIZE ) if( wndPtr->dwStyle & WS_MINIMIZE )
{ {
if( wndPtr->flags & WIN_NATIVE )
if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
swpFlags |= MINMAX_NOSWP;
wndPtr->dwStyle &= ~WS_MINIMIZE; wndPtr->dwStyle &= ~WS_MINIMIZE;
WINPOS_ShowIconTitle( wndPtr, FALSE ); WINPOS_ShowIconTitle( wndPtr, FALSE );
if( wndPtr->flags & WIN_RESTORE_MAX) if( wndPtr->flags & WIN_RESTORE_MAX)
{ {
/* Restore to maximized position */ /* Restore to maximized position */
@ -1253,7 +1268,7 @@ BOOL WINAPI ShowWindow( HWND hwnd, INT cmd )
WND* wndPtr = WIN_FindWndPtr( hwnd ); WND* wndPtr = WIN_FindWndPtr( hwnd );
BOOL wasVisible, showFlag; BOOL wasVisible, showFlag;
RECT16 newPos = {0, 0, 0, 0}; RECT16 newPos = {0, 0, 0, 0};
int swp = 0; UINT swp = 0;
if (!wndPtr) return FALSE; if (!wndPtr) return FALSE;
@ -1335,8 +1350,9 @@ BOOL WINAPI ShowWindow( HWND hwnd, INT cmd )
{ {
/* We can't activate a child window */ /* We can't activate a child window */
if (wndPtr->dwStyle & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER; if (wndPtr->dwStyle & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
SetWindowPos( hwnd, HWND_TOP, if (!(swp & MINMAX_NOSWP))
newPos.left, newPos.top, newPos.right, newPos.bottom, swp ); SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
newPos.right, newPos.bottom, LOWORD(swp) );
if (!IsWindow( hwnd )) goto END; if (!IsWindow( hwnd )) goto END;
else if( wndPtr->dwStyle & WS_MINIMIZE ) WINPOS_ShowIconTitle( wndPtr, TRUE ); else if( wndPtr->dwStyle & WS_MINIMIZE ) WINPOS_ShowIconTitle( wndPtr, TRUE );
} }
@ -1610,8 +1626,8 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
HQUEUE16 hOldActiveQueue, hNewActiveQueue; HQUEUE16 hOldActiveQueue, hNewActiveQueue;
MESSAGEQUEUE *pOldActiveQueue = 0, *pNewActiveQueue = 0; MESSAGEQUEUE *pOldActiveQueue = 0, *pNewActiveQueue = 0;
WORD wIconized = 0; WORD wIconized = 0;
HWND hwndActive = 0; HWND hwndActive = 0;
BOOL bRet = 0; BOOL bRet = 0;
/* Get current active window from the active queue */ /* Get current active window from the active queue */
if ( hActiveQueue ) if ( hActiveQueue )
@ -1622,7 +1638,8 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
} }
/* paranoid checks */ /* paranoid checks */
if( hWnd == GetDesktopWindow() || hWnd == hwndActive ) goto CLEANUP; if( hWnd == GetDesktopWindow() || (bRet = (hWnd == hwndActive)) )
goto CLEANUP_END;
/* if (wndPtr && (GetFastQueue16() != wndPtr->hmemTaskQ)) /* if (wndPtr && (GetFastQueue16() != wndPtr->hmemTaskQ))
* return 0; * return 0;
@ -1641,20 +1658,12 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
/* call CBT hook chain */ /* call CBT hook chain */
if ((cbtStruct = SEGPTR_NEW(CBTACTIVATESTRUCT16))) if ((cbtStruct = SEGPTR_NEW(CBTACTIVATESTRUCT16)))
{ {
LRESULT wRet;
cbtStruct->fMouse = fMouse; cbtStruct->fMouse = fMouse;
cbtStruct->hWndActive = hwndActive; cbtStruct->hWndActive = hwndActive;
wRet = HOOK_CallHooks16( WH_CBT, HCBT_ACTIVATE, (WPARAM16)hWnd, bRet = (BOOL)HOOK_CallHooks16( WH_CBT, HCBT_ACTIVATE, (WPARAM16)hWnd,
(LPARAM)SEGPTR_GET(cbtStruct) ); (LPARAM)SEGPTR_GET(cbtStruct) );
SEGPTR_FREE(cbtStruct); SEGPTR_FREE(cbtStruct);
if (wRet) if (bRet) goto CLEANUP_END;
{
/* Unlock the active queue before returning */
if ( pOldActiveQueue )
QUEUE_Unlock( pOldActiveQueue );
WIN_ReleaseWndPtr(wndPtr);
return wRet;
}
} }
/* set prev active wnd to current active wnd and send notification */ /* set prev active wnd to current active wnd and send notification */
@ -1664,20 +1673,14 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
if (!SendMessageA( hwndPrevActive, WM_NCACTIVATE, FALSE, 0 )) if (!SendMessageA( hwndPrevActive, WM_NCACTIVATE, FALSE, 0 ))
{ {
if (GetSysModalWindow16() != hWnd) goto CLEANUP; if (GetSysModalWindow16() != hWnd)
goto CLEANUP_END;
/* disregard refusal if hWnd is sysmodal */ /* disregard refusal if hWnd is sysmodal */
} }
#if 1
SendMessageA( hwndPrevActive, WM_ACTIVATE, SendMessageA( hwndPrevActive, WM_ACTIVATE,
MAKEWPARAM( WA_INACTIVE, wIconized ), MAKEWPARAM( WA_INACTIVE, wIconized ),
(LPARAM)hWnd ); (LPARAM)hWnd );
#else
/* FIXME: must be SendMessage16() because A doesn't do
* intertask at this time */
SendMessage16( hwndPrevActive, WM_ACTIVATE, WA_INACTIVE,
MAKELPARAM( (HWND16)hWnd, wIconized ) );
#endif
/* check if something happened during message processing /* check if something happened during message processing
* (global active queue may have changed) * (global active queue may have changed)
@ -1686,7 +1689,7 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
hwndActive = PERQDATA_GetActiveWnd( pTempActiveQueue->pQData ); hwndActive = PERQDATA_GetActiveWnd( pTempActiveQueue->pQData );
QUEUE_Unlock( pTempActiveQueue ); QUEUE_Unlock( pTempActiveQueue );
if( hwndPrevActive != hwndActive ) if( hwndPrevActive != hwndActive )
goto CLEANUP; goto CLEANUP_END;
} }
/* Set new active window in the message queue */ /* Set new active window in the message queue */
@ -1722,7 +1725,8 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
if( wndTemp != wndPtr ) if( wndTemp != wndPtr )
SetWindowPos(hWnd, HWND_TOP, 0,0,0,0, SetWindowPos(hWnd, HWND_TOP, 0,0,0,0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE ); SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
if (!IsWindow(hWnd)) goto CLEANUP; if (!IsWindow(hWnd))
goto CLEANUP;
} }
/* Get a handle to the new active queue */ /* Get a handle to the new active queue */
@ -1780,15 +1784,9 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE); wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
WIN_ReleaseWndPtr(wndTemp); WIN_ReleaseWndPtr(wndTemp);
SendMessageA( hWnd, WM_NCACTIVATE, TRUE, 0 ); SendMessageA( hWnd, WM_NCACTIVATE, TRUE, 0 );
#if 1
SendMessageA( hWnd, WM_ACTIVATE, SendMessageA( hWnd, WM_ACTIVATE,
MAKEWPARAM( (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE, wIconized), MAKEWPARAM( (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE, wIconized),
(LPARAM)hwndPrevActive ); (LPARAM)hwndPrevActive );
#else
SendMessage16(hWnd, WM_ACTIVATE, (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE,
MAKELPARAM( (HWND16)hwndPrevActive, wIconized) );
#endif
if( !IsWindow(hWnd) ) goto CLEANUP; if( !IsWindow(hWnd) ) goto CLEANUP;
} }
@ -1807,17 +1805,20 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
/* if active wnd is minimized redraw icon title */ /* if active wnd is minimized redraw icon title */
if( IsIconic(hwndActive) ) WINPOS_RedrawIconTitle(hwndActive); if( IsIconic(hwndActive) ) WINPOS_RedrawIconTitle(hwndActive);
bRet = 1; // Success bRet = (hWnd == hwndActive); /* Success? */
CLEANUP: CLEANUP: /* Unlock the message queues before returning */
/* Unlock the message queues before returning */
if ( pOldActiveQueue )
QUEUE_Unlock( pOldActiveQueue );
if ( pNewActiveQueue ) if ( pNewActiveQueue )
QUEUE_Unlock( pNewActiveQueue ); QUEUE_Unlock( pNewActiveQueue );
CLEANUP_END:
if ( pOldActiveQueue )
QUEUE_Unlock( pOldActiveQueue );
WIN_ReleaseWndPtr(wndPtr); WIN_ReleaseWndPtr(wndPtr);
return bRet ? (hWnd == hwndActive) : 0; return bRet;
} }
/******************************************************************* /*******************************************************************
@ -2231,35 +2232,70 @@ nocopy:
/*********************************************************************** /***********************************************************************
* SWP_DoSimpleFrameChanged * SWP_DoSimpleFrameChanged
*
* NOTE: old and new client rect origins are identical, only
* extents may have changed. Window extents are the same.
*/ */
static void SWP_DoSimpleFrameChanged( WND* wndPtr, RECT* pNewClientRect, RECT* pOldClientRect ) static void SWP_DoSimpleFrameChanged( WND* wndPtr, RECT* pOldClientRect, WORD swpFlags, UINT uFlags )
{ {
WORD wErase = 0; INT i = 0;
RECT rect; RECT rect;
HRGN hrgn = 0;
if( pNewClientRect->right > pOldClientRect->right ) /* redraw exposed client area on the right */ if( !(swpFlags & SWP_NOCLIENTSIZE) )
{ {
rect.top = 0; rect.bottom = pNewClientRect->bottom - pNewClientRect->top; /* FIXME: WVR alignment flags */
rect.left = pOldClientRect->right - pNewClientRect->left;
rect.right = pNewClientRect->right - pNewClientRect->left; if( wndPtr->rectClient.right > pOldClientRect->right ) /* right edge */
wErase = 1; {
PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | i++;
RDW_ERASENOW | RDW_ALLCHILDREN, RDW_EX_TOPFRAME ); rect.top = 0;
} rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
if( pNewClientRect->bottom > pOldClientRect->bottom ) /* redraw exposed client area on the bottom */ rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left;
{ if(!(uFlags & SWP_EX_NOCOPY))
rect.left = 0; rect.right = ((wErase)? pOldClientRect->right : pNewClientRect->right) - pNewClientRect->left; rect.left = pOldClientRect->right - wndPtr->rectClient.left;
rect.top = pOldClientRect->bottom - pNewClientRect->top; else
rect.bottom = pNewClientRect->bottom - pNewClientRect->top; {
wErase = 1; rect.left = 0;
PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | goto redraw;
RDW_ERASENOW | RDW_ALLCHILDREN, RDW_EX_TOPFRAME ); }
} }
if( !wErase ) /* IMMEDIATELY update the nonclient area */
{ if( wndPtr->rectClient.bottom > pOldClientRect->bottom ) /* bottom edge */
HRGN h; {
if( (h = WIN_UpdateNCRgn(wndPtr, TRUE, TRUE)) > 1) DeleteObject( h ); if( i )
} hrgn = CreateRectRgnIndirect( &rect );
rect.left = 0;
rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left;
rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
if(!(uFlags & SWP_EX_NOCOPY))
rect.top = pOldClientRect->bottom - wndPtr->rectClient.top;
else
rect.top = 0;
if( i++ )
REGION_UnionRectWithRgn( hrgn, &rect );
}
if( i == 0 && (uFlags & SWP_EX_NOCOPY) ) /* force redraw anyway */
{
rect = wndPtr->rectWindow;
OffsetRect( &rect, wndPtr->rectWindow.left - wndPtr->rectClient.left,
wndPtr->rectWindow.top - wndPtr->rectClient.top );
i++;
}
}
if( i )
{
redraw:
PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, hrgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
RDW_ERASENOW | RDW_ALLCHILDREN, RDW_EX_TOPFRAME | RDW_EX_USEHRGN );
}
else
hrgn = WIN_UpdateNCRgn(wndPtr, TRUE, TRUE);
if( hrgn > 1 )
DeleteObject( hrgn );
} }
/*********************************************************************** /***********************************************************************
@ -2482,7 +2518,7 @@ Pos: /* -----------------------------------------------------------------------
/* Common operations */ /* Common operations */
SWP_DoNCCalcSize( wndPtr, &winpos, &newWindowRect, &newClientRect, flags ); wvrFlags = SWP_DoNCCalcSize( wndPtr, &winpos, &newWindowRect, &newClientRect, flags );
if(!(winpos.flags & SWP_NOZORDER)) if(!(winpos.flags & SWP_NOZORDER))
{ {
@ -2505,6 +2541,23 @@ Pos: /* -----------------------------------------------------------------------
oldWindowRect = wndPtr->rectWindow; oldWindowRect = wndPtr->rectWindow;
oldClientRect = wndPtr->rectClient; oldClientRect = wndPtr->rectClient;
/* Find out if we have to redraw the whole client rect */
if( oldClientRect.bottom - oldClientRect.top ==
newClientRect.bottom - newClientRect.top ) wvrFlags &= ~WVR_VREDRAW;
if( oldClientRect.right - oldClientRect.left ==
newClientRect.right - newClientRect.left ) wvrFlags &= ~WVR_HREDRAW;
uFlags |= ((winpos.flags & SWP_NOCOPYBITS) ||
(!(winpos.flags & SWP_NOCLIENTSIZE) &&
(wvrFlags >= WVR_HREDRAW) && (wvrFlags < WVR_VALIDRECTS))) ? SWP_EX_NOCOPY : 0;
/* FIXME: actually do something with WVR_VALIDRECTS */
wndPtr->rectWindow = newWindowRect;
wndPtr->rectClient = newClientRect;
if (wndPtr->flags & WIN_NATIVE) /* -------------------------------------------- hosted window */ if (wndPtr->flags & WIN_NATIVE) /* -------------------------------------------- hosted window */
{ {
BOOL bCallDriver = TRUE; BOOL bCallDriver = TRUE;
@ -2512,9 +2565,6 @@ Pos: /* -----------------------------------------------------------------------
winpos.hwndInsertAfter = hwndInsertAfter; winpos.hwndInsertAfter = hwndInsertAfter;
wndPtr->rectWindow = newWindowRect;
wndPtr->rectClient = newClientRect;
if( !(winpos.flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOREDRAW)) ) if( !(winpos.flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOREDRAW)) )
{ {
/* This is the only place where we need to force repainting of the contents /* This is the only place where we need to force repainting of the contents
@ -2533,15 +2583,15 @@ Pos: /* -----------------------------------------------------------------------
winpos.hwndInsertAfter = tempInsertAfter; winpos.hwndInsertAfter = tempInsertAfter;
bCallDriver = FALSE; bCallDriver = FALSE;
if( (oldClientRect.left - oldWindowRect.left == newClientRect.left - newWindowRect.left) && if( winpos.flags & SWP_NOCLIENTMOVE )
(oldClientRect.top - oldWindowRect.top == newClientRect.top - newWindowRect.top) ) SWP_DoSimpleFrameChanged(wndPtr, &oldClientRect, winpos.flags, uFlags );
SWP_DoSimpleFrameChanged(wndPtr, &newClientRect, &oldClientRect );
else else
{ {
/* client area moved but window extents remained the same, copy valid bits */ /* client area moved but window extents remained the same, copy valid bits */
visRgn = CreateRectRgn( 0, 0, x, y ); visRgn = CreateRectRgn( 0, 0, x, y );
uFlags = SWP_CopyValidBits(wndPtr, &visRgn, &oldWindowRect, &oldClientRect, SWP_EX_PAINTSELF); uFlags = SWP_CopyValidBits( wndPtr, &visRgn, &oldWindowRect, &oldClientRect,
uFlags | SWP_EX_PAINTSELF );
} }
} }
} }
@ -2552,9 +2602,14 @@ Pos: /* -----------------------------------------------------------------------
if( !(winpos.flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOREDRAW)) ) if( !(winpos.flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOREDRAW)) )
{ {
if( (oldClientRect.left - oldWindowRect.left == newClientRect.left - newWindowRect.left) && if( (oldClientRect.left - oldWindowRect.left == newClientRect.left - newWindowRect.left) &&
(oldClientRect.top - oldWindowRect.top == newClientRect.top - newWindowRect.top) ) (oldClientRect.top - oldWindowRect.top == newClientRect.top - newWindowRect.top) &&
!(uFlags & SWP_EX_NOCOPY) )
{ {
if( !(wndPtr->flags & WIN_MANAGED) ) /* force outer frame redraw */ /* The origin of the client rect didn't move so we can try to repaint
* only the nonclient area by setting bit gravity hint for the host window system.
*/
if( !(wndPtr->flags & WIN_MANAGED) )
{ {
HRGN hrgn = CreateRectRgn( 0, 0, newWindowRect.right - newWindowRect.left, HRGN hrgn = CreateRectRgn( 0, 0, newWindowRect.right - newWindowRect.left,
newWindowRect.bottom - newWindowRect.top); newWindowRect.bottom - newWindowRect.top);
@ -2606,20 +2661,11 @@ Pos: /* -----------------------------------------------------------------------
} }
else /* -------------------------------------------- emulated window */ else /* -------------------------------------------- emulated window */
{ {
wndPtr->rectWindow = newWindowRect;
wndPtr->rectClient = newClientRect;
if( oldClientRect.bottom - oldClientRect.top ==
newClientRect.bottom - newClientRect.top ) wvrFlags &= ~WVR_VREDRAW;
if( oldClientRect.right - oldClientRect.left ==
newClientRect.right - newClientRect.left ) wvrFlags &= ~WVR_HREDRAW;
if( winpos.flags & SWP_SHOWWINDOW ) if( winpos.flags & SWP_SHOWWINDOW )
{ {
wndPtr->dwStyle |= WS_VISIBLE; wndPtr->dwStyle |= WS_VISIBLE;
uFlags |= SWP_EX_PAINTSELF; uFlags |= SWP_EX_PAINTSELF;
visRgn = 1; visRgn = 1; /* redraw the whole window */
} }
else if( !(winpos.flags & SWP_NOREDRAW) ) else if( !(winpos.flags & SWP_NOREDRAW) )
{ {
@ -2632,16 +2678,15 @@ Pos: /* -----------------------------------------------------------------------
} }
else else
{ {
uFlags |= ((winpos.flags & SWP_NOCOPYBITS) ||
(wvrFlags >= WVR_HREDRAW && wvrFlags < WVR_VALIDRECTS)) ? SWP_EX_NOCOPY : 0;
if( (winpos.flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE ) if( (winpos.flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE )
uFlags = SWP_CopyValidBits(wndPtr, &visRgn, &oldWindowRect, uFlags = SWP_CopyValidBits(wndPtr, &visRgn, &oldWindowRect,
&oldClientRect, uFlags); &oldClientRect, uFlags);
else else
{ {
/* nothing moved, redraw frame if needed */
if( winpos.flags & SWP_FRAMECHANGED ) if( winpos.flags & SWP_FRAMECHANGED )
SWP_DoSimpleFrameChanged( wndPtr, &newClientRect, &oldClientRect ); SWP_DoSimpleFrameChanged( wndPtr, &oldClientRect, winpos.flags, uFlags );
if( visRgn ) if( visRgn )
{ {
DeleteObject( visRgn ); DeleteObject( visRgn );
@ -2669,11 +2714,6 @@ Pos: /* -----------------------------------------------------------------------
/* ------------------------------------------------------------------------ FINAL */ /* ------------------------------------------------------------------------ FINAL */
/* Activate the window */
if (!(flags & SWP_NOACTIVATE))
WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE );
if (wndPtr->flags & WIN_NATIVE) if (wndPtr->flags & WIN_NATIVE)
EVENT_Synchronize(); /* Synchronize with the host window system */ EVENT_Synchronize(); /* Synchronize with the host window system */
@ -2682,7 +2722,11 @@ Pos: /* -----------------------------------------------------------------------
wndTemp = WIN_GetDesktop(); wndTemp = WIN_GetDesktop();
/* repaint invalidated region (if any) */ /* repaint invalidated region (if any)
*
* FIXME: if SWP_NOACTIVATE is not set then set invalid regions here without any painting
* and force update after ChangeActiveWindow() to avoid painting frames twice.
*/
if( visRgn ) if( visRgn )
{ {
@ -2707,6 +2751,9 @@ Pos: /* -----------------------------------------------------------------------
WIN_ReleaseDesktop(); WIN_ReleaseDesktop();
if (!(flags & SWP_NOACTIVATE))
WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE );
/* And last, send the WM_WINDOWPOSCHANGED message */ /* And last, send the WM_WINDOWPOSCHANGED message */
TRACE(win,"\tstatus flags = %04x\n", winpos.flags & SWP_AGG_STATUSFLAGS); TRACE(win,"\tstatus flags = %04x\n", winpos.flags & SWP_AGG_STATUSFLAGS);

View file

@ -24,7 +24,6 @@ extern HWND hWndClipOwner;
extern HWND hWndClipWindow; extern HWND hWndClipWindow;
extern WINE_CLIPFORMAT ClipFormats[]; extern WINE_CLIPFORMAT ClipFormats[];
static Bool selectionWait = False;
static Bool selectionAcquired = False; static Bool selectionAcquired = False;
static Window selectionWindow = None; static Window selectionWindow = None;
static Window selectionPrevWindow = None; static Window selectionPrevWindow = None;
@ -67,15 +66,13 @@ static void X11DRV_CLIPBOARD_CheckSelection(WND* pWnd)
/************************************************************************** /**************************************************************************
* X11DRV_CLIPBOARD_ReadSelection * X11DRV_CLIPBOARD_ReadSelection
*
* Called from the SelectionNotify event handler.
*/ */
void X11DRV_CLIPBOARD_ReadSelection(Window w,Atom prop) static void X11DRV_CLIPBOARD_ReadSelection(Window w, Atom prop)
{ {
HANDLE hText = 0; HANDLE hText = 0;
LPWINE_CLIPFORMAT lpFormat = ClipFormats; LPWINE_CLIPFORMAT lpFormat = ClipFormats;
TRACE(clipboard,"ReadSelection callback\n"); TRACE(clipboard,"Reading X selection...\n");
if(prop != None) if(prop != None)
{ {
@ -126,19 +123,16 @@ void X11DRV_CLIPBOARD_ReadSelection(Window w,Atom prop)
if( hText ) if( hText )
{ {
lpFormat = &ClipFormats[CF_TEXT-1]; lpFormat = &ClipFormats[CF_TEXT-1];
if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32) if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32)
CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow)); CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow));
lpFormat = &ClipFormats[CF_OEMTEXT-1]; lpFormat = &ClipFormats[CF_OEMTEXT-1];
if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32) if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32)
CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow)); CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow));
lpFormat->wDataPresent = 1;
lpFormat->wDataPresent = 1; lpFormat->hData32 = hText;
lpFormat->hData32 = hText; lpFormat->hData16 = 0;
lpFormat->hData16 = 0;
} }
selectionWait=False;
} }
/************************************************************************** /**************************************************************************
@ -180,27 +174,35 @@ void X11DRV_CLIPBOARD_ReleaseSelection(Window w, HWND hwnd)
} }
/************************************************************************** /**************************************************************************
* X11DRV_CLIPBOARD_EmptyClipboard * X11DRV_CLIPBOARD_Empty
*/ */
void X11DRV_CLIPBOARD_EmptyClipboard() void X11DRV_CLIPBOARD_Empty()
{ {
if(selectionAcquired) if( selectionAcquired )
{ {
selectionAcquired = False; XEvent xe;
selectionPrevWindow = selectionWindow;
selectionWindow = None; selectionAcquired = False;
selectionPrevWindow = selectionWindow;
selectionWindow = None;
TRACE(clipboard, "\tgiving up selection (spw = %08x)\n", TRACE(clipboard, "\tgiving up selection (spw = %08x)\n",
(unsigned)selectionPrevWindow); (unsigned)selectionPrevWindow);
TSXSetSelectionOwner(display, XA_PRIMARY, None, CurrentTime); EnterCriticalSection(&X11DRV_CritSection);
XSetSelectionOwner(display, XA_PRIMARY, None, CurrentTime);
if( selectionPrevWindow )
while( !XCheckTypedWindowEvent( display, selectionPrevWindow,
SelectionClear, &xe ) );
LeaveCriticalSection(&X11DRV_CritSection);
} }
} }
/************************************************************************** /**************************************************************************
* X11DRV_CLIPBOARD_SetClipboardData * X11DRV_CLIPBOARD_SetData
*/ */
void X11DRV_CLIPBOARD_SetClipboardData(UINT wFormat) void X11DRV_CLIPBOARD_SetData(UINT wFormat)
{ {
Window owner; Window owner;
@ -226,45 +228,55 @@ void X11DRV_CLIPBOARD_SetClipboardData(UINT wFormat)
} }
/************************************************************************** /**************************************************************************
* X11DRV_CLIPBOARD_RequestSelection * X11DRV_CLIPBOARD_GetData
*
* NOTE: Clipboard driver doesn't get requests for CF_TEXT data, only
* for CF_OEMTEXT.
*/ */
BOOL X11DRV_CLIPBOARD_RequestSelection() BOOL X11DRV_CLIPBOARD_GetData(UINT wFormat)
{ {
BOOL bRet = selectionAcquired;
HWND hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow(); HWND hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow();
WND *tmpWnd = WIN_FindWndPtr(hWnd); WND* wnd = NULL;
if( selectionAcquired ) if( wFormat != CF_OEMTEXT ) return FALSE;
return TRUE;
if( !hWnd ) return FALSE; if( !bRet && (wnd = WIN_FindWndPtr(hWnd)) )
{
XEvent xe;
Window w = X11DRV_WND_FindXWindow(wnd);
TRACE(clipboard,"Requesting selection...\n"); TRACE(clipboard, "Requesting XA_STRING selection...\n");
/* request data type XA_STRING, later EnterCriticalSection( &X11DRV_CritSection );
* CLIPBOARD_ReadSelection() will be invoked XConvertSelection(display, XA_PRIMARY, XA_STRING,
* from the SelectionNotify event handler */ XInternAtom(display, "PRIMARY_TEXT", False),
w, CurrentTime);
TSXConvertSelection(display, XA_PRIMARY, XA_STRING,
TSXInternAtom(display, "PRIMARY_TEXT", False),
X11DRV_WND_FindXWindow(tmpWnd ),
CurrentTime);
WIN_ReleaseWndPtr(tmpWnd); /* wait until SelectionNotify is received */
/* wait until SelectionNotify is processed while( TRUE )
* {
* FIXME: Use TSXCheckTypedWindowEvent() instead ( same in the if( XCheckTypedWindowEvent(display, w, SelectionNotify, &xe) )
* CLIPBOARD_CheckSelection() ). if( xe.xselection.selection == XA_PRIMARY )
*/ break;
}
LeaveCriticalSection( &X11DRV_CritSection );
selectionWait=True; if (xe.xselection.target != XA_STRING)
while(selectionWait) EVENT_WaitNetEvent( TRUE, FALSE ); X11DRV_CLIPBOARD_ReadSelection( 0, None );
else
X11DRV_CLIPBOARD_ReadSelection( xe.xselection.requestor,
xe.xselection.property );
/* we treat Unix text as CF_OEMTEXT */ /* treat Unix text as CF_OEMTEXT */
TRACE(clipboard,"\tgot CF_OEMTEXT = %i\n",
ClipFormats[CF_OEMTEXT-1].wDataPresent);
return (BOOL)ClipFormats[CF_OEMTEXT-1].wDataPresent; bRet = (BOOL)ClipFormats[CF_OEMTEXT-1].wDataPresent;
TRACE(clipboard,"\tpresent CF_OEMTEXT = %i\n", bRet );
WIN_ReleaseWndPtr(wnd);
}
return bRet;
} }
/************************************************************************** /**************************************************************************

View file

@ -95,10 +95,10 @@ static void EVENT_Expose( WND *pWnd, XExposeEvent *event );
static void EVENT_GraphicsExpose( WND *pWnd, XGraphicsExposeEvent *event ); static void EVENT_GraphicsExpose( WND *pWnd, XGraphicsExposeEvent *event );
static void EVENT_ConfigureNotify( WND *pWnd, XConfigureEvent *event ); static void EVENT_ConfigureNotify( WND *pWnd, XConfigureEvent *event );
static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event); static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event);
static void EVENT_SelectionNotify( XSelectionEvent *event);
static void EVENT_SelectionClear( WND *pWnd, XSelectionClearEvent *event); static void EVENT_SelectionClear( WND *pWnd, XSelectionClearEvent *event);
static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event ); static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event );
static void EVENT_MapNotify( HWND hwnd, XMapEvent *event ); static void EVENT_MapNotify( WND* wnd, XMapEvent *event );
static void EVENT_UnmapNotify( WND* wnd, XUnmapEvent *event );
/* Usable only with OLVWM - compile option perhaps? /* Usable only with OLVWM - compile option perhaps?
static void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event ); static void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event );
@ -387,19 +387,22 @@ static void EVENT_ProcessEvent( XEvent *event )
WND *pWnd; WND *pWnd;
switch (event->type) switch (event->type)
{ {
case SelectionNotify: /* all of these should be caught by XCheckTypedWindowEvent() */
FIXME(event,"Got SelectionNotify - must not happen!\n");
/* fall through */
/* We get all these because of StructureNotifyMask. /* We get all these because of StructureNotifyMask.
This check is placed here to avoid getting error messages below, This check is placed here to avoid getting error messages below,
as X might send some of these even for windows that have already as X might send some of these even for windows that have already
been deleted ... */ been deleted ... */
case UnmapNotify:
case CirculateNotify: case CirculateNotify:
case CreateNotify: case CreateNotify:
case DestroyNotify: case DestroyNotify:
case GravityNotify: case GravityNotify:
case ReparentNotify: case ReparentNotify:
return; return;
} }
if ( TSXFindContext( display, event->xany.window, winContext, if ( TSXFindContext( display, event->xany.window, winContext,
(char **)&pWnd ) != 0) { (char **)&pWnd ) != 0) {
@ -482,11 +485,6 @@ static void EVENT_ProcessEvent( XEvent *event )
EVENT_SelectionRequest( pWnd, (XSelectionRequestEvent *)event ); EVENT_SelectionRequest( pWnd, (XSelectionRequestEvent *)event );
break; break;
case SelectionNotify:
if (!pWnd) return;
EVENT_SelectionNotify( (XSelectionEvent *)event );
break;
case SelectionClear: case SelectionClear:
if (!pWnd) return; if (!pWnd) return;
EVENT_SelectionClear( pWnd, (XSelectionClearEvent*) event ); EVENT_SelectionClear( pWnd, (XSelectionClearEvent*) event );
@ -508,9 +506,14 @@ static void EVENT_ProcessEvent( XEvent *event )
case MapNotify: case MapNotify:
if (!pWnd) return; if (!pWnd) return;
EVENT_MapNotify( pWnd->hwndSelf, (XMapEvent *)event ); EVENT_MapNotify( pWnd, (XMapEvent *)event );
break; break;
case UnmapNotify:
if (!pWnd) return;
EVENT_UnmapNotify( pWnd, (XUnmapEvent *)event );
break;
default: default:
WARN(event, "Unprocessed event %s for hwnd %04x\n", WARN(event, "Unprocessed event %s for hwnd %04x\n",
event_names[event->type], pWnd? pWnd->hwndSelf : 0 ); event_names[event->type], pWnd? pWnd->hwndSelf : 0 );
@ -1037,7 +1040,7 @@ TRACE(win, "%04x adjusted to (%i,%i)-(%i,%i)\n", pWnd->hwndSelf,
if( oldClientRect.top - oldWindowRect.top != newClientRect.top - newWindowRect.top || if( oldClientRect.top - oldWindowRect.top != newClientRect.top - newWindowRect.top ||
oldClientRect.left - oldWindowRect.left != newClientRect.left - newWindowRect.left ) oldClientRect.left - oldWindowRect.left != newClientRect.left - newWindowRect.left )
RedrawWindow( winpos.hwnd, 0, NULL, RDW_FRAME | RDW_ALLCHILDREN | RedrawWindow( winpos.hwnd, NULL, 0, RDW_FRAME | RDW_ALLCHILDREN |
RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW ); RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW );
SendMessageA( winpos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos ); SendMessageA( winpos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos );
@ -1059,22 +1062,26 @@ static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event )
{ {
XSelectionEvent result; XSelectionEvent result;
Atom rprop = None; Atom rprop = None;
Window request = event->requestor; Window request = event->requestor;
if(event->target == XA_STRING) if(event->target == XA_STRING)
{ {
HANDLE16 hText; HANDLE16 hText;
LPSTR text; LPSTR text;
int size,i,j; int size,i,j;
rprop = event->property; rprop = event->property;
if(rprop == None) rprop = event->target; if( rprop == None )
rprop = event->target;
if(event->selection!=XA_PRIMARY) rprop = None; if( event->selection != XA_PRIMARY )
else if(!CLIPBOARD_IsPresent(CF_OEMTEXT)) rprop = None; rprop = None;
else
if( !CLIPBOARD_IsPresent(CF_OEMTEXT) )
rprop = None;
else else
{ {
/* open to make sure that clipboard is available */ /* open to make sure that clipboard is available */
BOOL couldOpen = OpenClipboard( pWnd->hwndSelf ); BOOL couldOpen = OpenClipboard( pWnd->hwndSelf );
@ -1088,11 +1095,11 @@ static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event )
lpstr = (char*)HEAP_xalloc( GetProcessHeap(), 0, size-- ); lpstr = (char*)HEAP_xalloc( GetProcessHeap(), 0, size-- );
for(i=0,j=0; i < size && text[i]; i++ ) for(i=0,j=0; i < size && text[i]; i++ )
{ {
if( text[i] == '\r' && if( text[i] == '\r' &&
(text[i+1] == '\n' || text[i+1] == '\0') ) continue; (text[i+1] == '\n' || text[i+1] == '\0') ) continue;
lpstr[j++] = text[i]; lpstr[j++] = text[i];
} }
lpstr[j]='\0'; lpstr[j]='\0';
TSXChangeProperty(display, request, rprop, TSXChangeProperty(display, request, rprop,
@ -1103,11 +1110,13 @@ static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event )
/* close only if we opened before */ /* close only if we opened before */
if(couldOpen) CloseClipboard(); if(couldOpen) CloseClipboard();
} }
} }
if(rprop == None) if( rprop == None)
TRACE(event,"Request for %s ignored\n", TSXGetAtomName(display,event->target)); TRACE(event,"Request for %s ignored\n", TSXGetAtomName(display,event->target));
/* reply to sender */
result.type = SelectionNotify; result.type = SelectionNotify;
result.display = display; result.display = display;
@ -1119,21 +1128,6 @@ static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event )
TSXSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result); TSXSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result);
} }
/***********************************************************************
* EVENT_SelectionNotify
*/
static void EVENT_SelectionNotify( XSelectionEvent *event )
{
if (event->selection != XA_PRIMARY) return;
if (event->target != XA_STRING) X11DRV_CLIPBOARD_ReadSelection( 0, None );
else X11DRV_CLIPBOARD_ReadSelection( event->requestor, event->property );
TRACE(event, "\tSelectionNotify done!\n");
}
/*********************************************************************** /***********************************************************************
* EVENT_SelectionClear * EVENT_SelectionClear
*/ */
@ -1465,18 +1459,36 @@ void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event )
/********************************************************************** /**********************************************************************
* EVENT_MapNotify * EVENT_MapNotify
*/ */
void EVENT_MapNotify( HWND hWnd, XMapEvent *event ) void EVENT_MapNotify( WND* wnd, XMapEvent *event )
{ {
HWND hwndFocus = GetFocus(); HWND hwndFocus = GetFocus();
WND *tmpWnd = WIN_FindWndPtr(hwndFocus); WND *wndFocus = WIN_FindWndPtr(hwndFocus);
if (hwndFocus && IsChild( hWnd, hwndFocus )) if (wnd->flags & WIN_MANAGED)
X11DRV_WND_SetFocus(tmpWnd ); wnd->dwStyle &= ~WS_MINIMIZE;
WIN_ReleaseWndPtr(tmpWnd);
if (hwndFocus && IsChild( wnd->hwndSelf, hwndFocus ))
X11DRV_WND_SetFocus(wndFocus);
WIN_ReleaseWndPtr(wndFocus);
return; return;
} }
/**********************************************************************
* EVENT_MapNotify
*/
void EVENT_UnmapNotify( WND* wnd, XUnmapEvent *event )
{
if (wnd->flags & WIN_MANAGED)
{
EndMenu();
wnd->dwStyle |= WS_MINIMIZE;
}
}
/********************************************************************** /**********************************************************************
* X11DRV_EVENT_Pending * X11DRV_EVENT_Pending
*/ */

View file

@ -28,9 +28,9 @@ USER_DRIVER X11DRV_USER_Driver =
CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver = CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver =
{ {
X11DRV_CLIPBOARD_EmptyClipboard, X11DRV_CLIPBOARD_Empty,
X11DRV_CLIPBOARD_SetClipboardData, X11DRV_CLIPBOARD_SetData,
X11DRV_CLIPBOARD_RequestSelection, X11DRV_CLIPBOARD_GetData,
X11DRV_CLIPBOARD_ResetOwner X11DRV_CLIPBOARD_ResetOwner
}; };

View file

@ -16,6 +16,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "bitmap.h"
#include "color.h" #include "color.h"
#include "debug.h" #include "debug.h"
#include "display.h" #include "display.h"
@ -27,10 +28,13 @@
#include "windef.h" #include "windef.h"
#include "class.h" #include "class.h"
#include "x11drv.h" #include "x11drv.h"
#include "wine/winuser16.h"
/**********************************************************************/ /**********************************************************************/
extern Cursor X11DRV_MOUSE_XCursor; /* Current X cursor */ extern Cursor X11DRV_MOUSE_XCursor; /* Current X cursor */
extern BOOL X11DRV_CreateBitmap( HBITMAP );
extern Pixmap X11DRV_BITMAP_Pixmap( HBITMAP );
/**********************************************************************/ /**********************************************************************/
@ -41,6 +45,7 @@ Atom wmProtocols = None;
Atom wmDeleteWindow = None; Atom wmDeleteWindow = None;
Atom dndProtocol = None; Atom dndProtocol = None;
Atom dndSelection = None; Atom dndSelection = None;
Atom wmChangeState = None;
/*********************************************************************** /***********************************************************************
* X11DRV_WND_GetXWindow * X11DRV_WND_GetXWindow
@ -152,6 +157,8 @@ BOOL X11DRV_WND_CreateDesktopWindow(WND *wndPtr, CLASS *classPtr, BOOL bUnicode)
dndProtocol = TSXInternAtom( display, "DndProtocol" , False ); dndProtocol = TSXInternAtom( display, "DndProtocol" , False );
if( dndSelection == None ) if( dndSelection == None )
dndSelection = TSXInternAtom( display, "DndSelection" , False ); dndSelection = TSXInternAtom( display, "DndSelection" , False );
if( wmChangeState == None )
wmChangeState = TSXInternAtom (display, "WM_CHANGE_STATE", False);
((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window =
X11DRV_WND_GetXRootWindow( wndPtr ); X11DRV_WND_GetXRootWindow( wndPtr );
@ -160,6 +167,7 @@ BOOL X11DRV_WND_CreateDesktopWindow(WND *wndPtr, CLASS *classPtr, BOOL bUnicode)
return TRUE; return TRUE;
} }
/********************************************************************** /**********************************************************************
* X11DRV_WND_CreateWindow * X11DRV_WND_CreateWindow
*/ */
@ -195,13 +203,14 @@ BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO
} }
wndPtr->flags |= WIN_NATIVE; wndPtr->flags |= WIN_NATIVE;
win_attr.bit_gravity = BGNorthWest; win_attr.bit_gravity = (classPtr->style & (CS_VREDRAW | CS_HREDRAW)) ? BGForget : BGNorthWest;
win_attr.colormap = X11DRV_PALETTE_PaletteXColormap; win_attr.colormap = X11DRV_PALETTE_PaletteXColormap;
win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful; win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0); win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0);
win_attr.cursor = X11DRV_MOUSE_XCursor; win_attr.cursor = X11DRV_MOUSE_XCursor;
((X11DRV_WND_DATA *) wndPtr->pDriverData)->bit_gravity = BGNorthWest; ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = 0;
((X11DRV_WND_DATA *) wndPtr->pDriverData)->bit_gravity = win_attr.bit_gravity;
((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window =
TSXCreateWindow( display, TSXCreateWindow( display,
X11DRV_WND_GetXRootWindow(wndPtr), X11DRV_WND_GetXRootWindow(wndPtr),
@ -216,28 +225,32 @@ BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO
if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr))) if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr)))
return FALSE; return FALSE;
if (wndPtr->flags & WIN_MANAGED) { if (wndPtr->flags & WIN_MANAGED)
XClassHint *class_hints = TSXAllocClassHint(); {
XClassHint *class_hints = TSXAllocClassHint();
if (class_hints) { if (class_hints)
class_hints->res_name = "wineManaged"; {
class_hints->res_class = "Wine"; class_hints->res_name = "wineManaged";
TSXSetClassHint( display, ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window, class_hints ); class_hints->res_class = "Wine";
TSXFree (class_hints); TSXSetClassHint( display, ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window, class_hints );
} TSXFree (class_hints);
}
if (cs->dwExStyle & WS_EX_DLGMODALFRAME) { if (cs->dwExStyle & WS_EX_DLGMODALFRAME)
XSizeHints* size_hints = TSXAllocSizeHints(); {
XSizeHints* size_hints = TSXAllocSizeHints();
if (size_hints) { if (size_hints)
size_hints->min_width = size_hints->max_width = cs->cx; {
size_hints->min_height = size_hints->max_height = cs->cy; size_hints->min_width = size_hints->max_width = cs->cx;
size_hints->flags = (PSize | PMinSize | PMaxSize); size_hints->min_height = size_hints->max_height = cs->cy;
TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr), size_hints, size_hints->flags = (PSize | PMinSize | PMaxSize);
XA_WM_NORMAL_HINTS ); TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr),
TSXFree(size_hints); size_hints, XA_WM_NORMAL_HINTS );
} TSXFree(size_hints);
} }
}
} }
if (cs->hwndParent) /* Get window owner */ if (cs->hwndParent) /* Get window owner */
@ -258,12 +271,36 @@ BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO
{ {
wm_hints->flags = InputHint | StateHint | WindowGroupHint; wm_hints->flags = InputHint | StateHint | WindowGroupHint;
wm_hints->input = True; wm_hints->input = True;
if( wndPtr->dwStyle & WS_VISIBLE )
wm_hints->initial_state = (wndPtr->dwStyle & WS_MINIMIZE && if( wndPtr->flags & WIN_MANAGED )
wndPtr->flags & WIN_MANAGED ) ? {
IconicState : NormalState; if( wndPtr->class->hIcon )
{
CURSORICONINFO *ptr;
if( (ptr = (CURSORICONINFO *)GlobalLock16( wndPtr->class->hIcon )) )
{
/* This is not entirely correct, may need to create
* an icon window and set the pixmap as a background */
HBITMAP hBitmap = CreateBitmap( ptr->nWidth, ptr->nHeight,
ptr->bPlanes, ptr->bBitsPerPixel, (char *)(ptr + 1) +
ptr->nHeight * BITMAP_GetWidthBytes(ptr->nWidth,1) );
if( hBitmap )
{
((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = hBitmap;
X11DRV_CreateBitmap( hBitmap );
wm_hints->flags |= IconPixmapHint;
wm_hints->icon_pixmap = X11DRV_BITMAP_Pixmap( hBitmap );
}
}
}
wm_hints->initial_state = (wndPtr->dwStyle & WS_MINIMIZE)
? IconicState : NormalState;
}
else else
wm_hints->initial_state = WithdrawnState; wm_hints->initial_state = NormalState;
wm_hints->window_group = wGroupLeader; wm_hints->window_group = wGroupLeader;
TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints ); TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
@ -279,14 +316,21 @@ BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO
*/ */
BOOL X11DRV_WND_DestroyWindow(WND *wndPtr) BOOL X11DRV_WND_DestroyWindow(WND *wndPtr)
{ {
if (X11DRV_WND_GetXWindow(wndPtr)) Window w;
{ if ((w = X11DRV_WND_GetXWindow(wndPtr)))
{
XEvent xe; XEvent xe;
TSXDeleteContext( display, X11DRV_WND_GetXWindow(wndPtr), winContext ); TSXDeleteContext( display, w, winContext );
TSXDestroyWindow( display, X11DRV_WND_GetXWindow(wndPtr) ); TSXDestroyWindow( display, w );
while( TSXCheckWindowEvent(display, X11DRV_WND_GetXWindow(wndPtr), NoEventMask, &xe) ); while( TSXCheckWindowEvent(display, w, NoEventMask, &xe) );
((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None; ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None;
} if( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap )
{
DeleteObject( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap );
((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = 0;
}
}
return TRUE; return TRUE;
} }
@ -449,7 +493,7 @@ void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangeP
if(bChangePos) if(bChangePos)
{ {
if ( !(winpos->flags & SWP_NOSIZE)) if ( !(winpos->flags & SWP_NOSIZE))
{ {
winChanges.width = (winpos->cx > 0 ) ? winpos->cx : 1; winChanges.width = (winpos->cx > 0 ) ? winpos->cx : 1;
winChanges.height = (winpos->cy > 0 ) ? winpos->cy : 1; winChanges.height = (winpos->cy > 0 ) ? winpos->cy : 1;
@ -476,13 +520,13 @@ void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangeP
} }
} }
} }
if (!(winpos->flags & SWP_NOMOVE)) if (!(winpos->flags & SWP_NOMOVE))
{ {
winChanges.x = winpos->x; winChanges.x = winpos->x;
winChanges.y = winpos->y; winChanges.y = winpos->y;
changeMask |= CWX | CWY; changeMask |= CWX | CWY;
} }
if (!(winpos->flags & SWP_NOZORDER)) if (!(winpos->flags & SWP_NOZORDER))
{ {
winChanges.stack_mode = Below; winChanges.stack_mode = Below;
changeMask |= CWStackMode; changeMask |= CWStackMode;
@ -504,15 +548,18 @@ void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangeP
WIN_ReleaseWndPtr(insertPtr); WIN_ReleaseWndPtr(insertPtr);
} }
} }
if (changeMask) if (changeMask)
{ {
TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(winposPtr), 0, changeMask, &winChanges ); TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(winposPtr), 0, changeMask, &winChanges );
if( winposPtr->class->style & (CS_VREDRAW | CS_HREDRAW) )
X11DRV_WND_SetHostAttr( winposPtr, HAK_BITGRAVITY, BGForget );
} }
} }
if ( winpos->flags & SWP_SHOWWINDOW ) if ( winpos->flags & SWP_SHOWWINDOW )
{ {
if(X11DRV_WND_GetXWindow(wndPtr)) TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) ); if(X11DRV_WND_GetXWindow(wndPtr))
TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
} }
WIN_ReleaseWndPtr(winposPtr); WIN_ReleaseWndPtr(winposPtr);
} }
@ -667,8 +714,47 @@ void X11DRV_WND_SetDrawable(WND *wndPtr, DC *dc, WORD flags, BOOL bSetClipOrigin
} }
} }
/***********************************************************************
* X11DRV_SetWMHint
*/
static BOOL X11DRV_SetWMHint(Display* display, WND* wndPtr, int hint, int val)
{
XWMHints* wm_hints = TSXAllocWMHints();
{
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;
}
/*********************************************************************** /***********************************************************************
* X11DRV_WND_SetHostAttr * 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) BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value)
{ {
@ -680,7 +766,55 @@ BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value)
switch( ha ) switch( ha )
{ {
case HAK_BITGRAVITY: case HAK_ICONICSTATE: /* called when a window is minimized/restored */
if( (wnd->flags & WIN_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,
RootWindow( display, XScreenNumberOfScreen(X11DRV_WND_GetXScreen(wnd)) ),
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;
XMapWindow(display, w );
while( !TSXCheckTypedWindowEvent( display, w, MapNotify, &xe) );
}
}
return TRUE;
}
break;
case HAK_BITGRAVITY: /* called when a window is resized */
if( ((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity != value ) if( ((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity != value )
{ {
@ -688,24 +822,12 @@ BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value)
((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity = value; ((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity = value;
TSXChangeWindowAttributes( display, w, CWBitGravity, &win_attr ); TSXChangeWindowAttributes( display, w, CWBitGravity, &win_attr );
} }
return TRUE; return TRUE;
case HAK_ACCEPTFOCUS: case HAK_ACCEPTFOCUS: /* called when a window is disabled/enabled */
if( (wnd->flags & WIN_MANAGED) ) if( (wnd->flags & WIN_MANAGED) )
{ return X11DRV_SetWMHint( display, wnd, InputHint, value );
XWMHints* wm_hints = TSXAllocWMHints();
if( wm_hints )
{
wm_hints->flags = InputHint;
wm_hints->input = value;
TSXSetWMHints( display, X11DRV_WND_GetXWindow(wnd), wm_hints );
TSXFree( wm_hints );
return TRUE;
}
}
break;
} }
} }
return FALSE; return FALSE;