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.
diff --git a/windows/clipboard.c b/windows/clipboard.c
index 75a1a1e..031fc08 100644
--- a/windows/clipboard.c
+++ b/windows/clipboard.c
@@ -250,7 +250,7 @@
hWndClipOwner = hWndClipWindow;
- CLIPBOARD_Driver->pEmptyClipboard();
+ CLIPBOARD_Driver->pEmpty();
return TRUE;
}
@@ -293,7 +293,7 @@
if( (hqClipLock != GetFastQueue16()) || !lpFormat ||
(!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
- CLIPBOARD_Driver->pSetClipboardData(wFormat);
+ CLIPBOARD_Driver->pSetData(wFormat);
if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
{
@@ -323,7 +323,7 @@
/**************************************************************************
- * SetClipboardData32 (USER32.470)
+ * SetClipboardData (USER32.470)
*/
HANDLE WINAPI SetClipboardData( UINT wFormat, HANDLE hData )
{
@@ -341,7 +341,7 @@
if( (hqClipLock != GetFastQueue16()) || !lpFormat ||
(!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
- CLIPBOARD_Driver->pSetClipboardData(wFormat);
+ CLIPBOARD_Driver->pSetData(wFormat);
if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
{
@@ -395,6 +395,9 @@
* CLIPBOARD_RenderText
*
* 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)
{
@@ -608,15 +611,13 @@
TRACE(clipboard,"(void)\n");
- /* FIXME: Returns BOOL32 */
- CLIPBOARD_Driver->pRequestSelection();
-
- FormatCount += abs(lpFormat[CF_TEXT-1].wDataPresent -
- lpFormat[CF_OEMTEXT-1].wDataPresent);
-
while(TRUE)
{
if (lpFormat == NULL) break;
+
+ if( lpFormat->wFormatID != CF_TEXT )
+ CLIPBOARD_Driver->pGetData( lpFormat->wFormatID );
+
if (lpFormat->wDataPresent)
{
TRACE(clipboard, "\tdata found for format %i\n", lpFormat->wFormatID);
@@ -625,6 +626,11 @@
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);
return FormatCount;
}
@@ -650,29 +656,30 @@
if( hqClipLock != GetFastQueue16() ) return 0;
- if( (!wFormat || wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
- CLIPBOARD_Driver->pRequestSelection();
+ if( wFormat < CF_OEMTEXT )
+ 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)
- return lpFormat->wFormatID;
- else
- wFormat = lpFormat->wFormatID; /* and CF_TEXT is not available */
+ /* walk up to the specified format record */
+
+ if( !(lpFormat = __lookup_format( lpFormat, wFormat )) )
+ 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)
{
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;
lpFormat = lpFormat->NextFormat;
}
@@ -877,8 +884,7 @@
{
TRACE(clipboard,"(%04X) !\n", wFormat);
- if( (wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
- CLIPBOARD_Driver->pRequestSelection();
+ CLIPBOARD_Driver->pGetData( (wFormat == CF_TEXT) ? CF_OEMTEXT : wFormat );
return CLIPBOARD_IsPresent(wFormat);
}
diff --git a/windows/message.c b/windows/message.c
index acb89ff..f188849 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -502,12 +502,14 @@
qmsg = sysMsgQueue->firstMsg;
-#if 0
/* If the queue is empty, attempt to fill it */
if (!sysMsgQueue->msgCount && THREAD_IsWin16( THREAD_Current() )
&& EVENT_Pending())
- EVENT_WaitNetEvent( FALSE, FALSE );
-#endif
+ {
+ LeaveCriticalSection(&sysMsgQueue->cSection);
+ EVENT_WaitNetEvent( FALSE, TRUE );
+ EnterCriticalSection(&sysMsgQueue->cSection);
+ }
for ( kbd_msg = 0; qmsg; qmsg = nextqmsg)
{
diff --git a/windows/ttydrv/clipboard.c b/windows/ttydrv/clipboard.c
index f6c0c3c..f608b7c 100644
--- a/windows/ttydrv/clipboard.c
+++ b/windows/ttydrv/clipboard.c
@@ -15,7 +15,7 @@
/***********************************************************************
* TTYDRV_CLIPBOARD_EmptyClipboard
*/
-void TTYDRV_CLIPBOARD_EmptyClipboard()
+void TTYDRV_CLIPBOARD_Empty()
{
if(TTYDRV_CLIPBOARD_szSelection)
{
@@ -25,16 +25,16 @@
}
/***********************************************************************
- * 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;
}
diff --git a/windows/ttydrv/init.c b/windows/ttydrv/init.c
index 7f6a15b..f58434c 100644
--- a/windows/ttydrv/init.c
+++ b/windows/ttydrv/init.c
@@ -24,9 +24,9 @@
CLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver =
{
- TTYDRV_CLIPBOARD_EmptyClipboard,
- TTYDRV_CLIPBOARD_SetClipboardData,
- TTYDRV_CLIPBOARD_RequestSelection,
+ TTYDRV_CLIPBOARD_Empty,
+ TTYDRV_CLIPBOARD_SetData,
+ TTYDRV_CLIPBOARD_GetData,
TTYDRV_CLIPBOARD_ResetOwner
};
diff --git a/windows/win.c b/windows/win.c
index 402319d..67c21f0 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -836,10 +836,14 @@
/* 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->flags |= WIN_NEED_SIZE;
+ wndPtr->dwStyle |= WS_CLIPSIBLINGS;
+ if (!(cs->style & WS_POPUP))
+ {
+ wndPtr->dwStyle |= WS_CAPTION;
+ wndPtr->flags |= WIN_NEED_SIZE;
+ }
}
if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
@@ -2701,13 +2705,10 @@
pWnd = WIN_LockWndPtr(wndPtr->child);
while (pWnd)
{
- if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
- if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
- {
+ if( !(pWnd->dwStyle & skipFlags) && !(skipOwned && pWnd->owner) &&
+ (!skipHidden || (pWnd->dwStyle & WS_VISIBLE)) )
count++;
- WIN_UpdateWndPtr(&pWnd,pWnd->next);
- }
-
+ WIN_UpdateWndPtr(&pWnd,pWnd->next);
}
if( count )
diff --git a/windows/winpos.c b/windows/winpos.c
index aadcd07..d98a4d7 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -48,6 +48,8 @@
#define SWP_EX_NOCOPY 0x0001
#define SWP_EX_PAINTSELF 0x0002
+#define MINMAX_NOSWP 0x00010000
+
/* ----- internal variables ----- */
static HWND hwndPrevActive = 0; /* Previously active window */
@@ -1138,9 +1140,9 @@
* This function assumes that 'cmd' is different from the current window
* 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 size = { wndPtr->rectWindow.left, wndPtr->rectWindow.top };
LPINTERNALPOS lpPos = WINPOS_InitInternalPos( wndPtr, size,
@@ -1168,6 +1170,10 @@
wndPtr->flags &= ~WIN_RESTORE_MAX;
wndPtr->dwStyle |= WS_MINIMIZE;
+ if( wndPtr->flags & WIN_NATIVE )
+ if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) )
+ swpFlags |= MINMAX_NOSWP;
+
lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
SetRect16( lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
@@ -1182,6 +1188,10 @@
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 );
wndPtr->dwStyle &= ~WS_MINIMIZE;
}
@@ -1194,8 +1204,13 @@
case SW_RESTORE:
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;
WINPOS_ShowIconTitle( wndPtr, FALSE );
+
if( wndPtr->flags & WIN_RESTORE_MAX)
{
/* Restore to maximized position */
@@ -1253,7 +1268,7 @@
WND* wndPtr = WIN_FindWndPtr( hwnd );
BOOL wasVisible, showFlag;
RECT16 newPos = {0, 0, 0, 0};
- int swp = 0;
+ UINT swp = 0;
if (!wndPtr) return FALSE;
@@ -1335,8 +1350,9 @@
{
/* We can't activate a child window */
if (wndPtr->dwStyle & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
- SetWindowPos( hwnd, HWND_TOP,
- newPos.left, newPos.top, newPos.right, newPos.bottom, swp );
+ if (!(swp & MINMAX_NOSWP))
+ SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
+ newPos.right, newPos.bottom, LOWORD(swp) );
if (!IsWindow( hwnd )) goto END;
else if( wndPtr->dwStyle & WS_MINIMIZE ) WINPOS_ShowIconTitle( wndPtr, TRUE );
}
@@ -1610,8 +1626,8 @@
HQUEUE16 hOldActiveQueue, hNewActiveQueue;
MESSAGEQUEUE *pOldActiveQueue = 0, *pNewActiveQueue = 0;
WORD wIconized = 0;
- HWND hwndActive = 0;
- BOOL bRet = 0;
+ HWND hwndActive = 0;
+ BOOL bRet = 0;
/* Get current active window from the active queue */
if ( hActiveQueue )
@@ -1622,7 +1638,8 @@
}
/* paranoid checks */
- if( hWnd == GetDesktopWindow() || hWnd == hwndActive ) goto CLEANUP;
+ if( hWnd == GetDesktopWindow() || (bRet = (hWnd == hwndActive)) )
+ goto CLEANUP_END;
/* if (wndPtr && (GetFastQueue16() != wndPtr->hmemTaskQ))
* return 0;
@@ -1641,20 +1658,12 @@
/* call CBT hook chain */
if ((cbtStruct = SEGPTR_NEW(CBTACTIVATESTRUCT16)))
{
- LRESULT wRet;
cbtStruct->fMouse = fMouse;
cbtStruct->hWndActive = hwndActive;
- wRet = HOOK_CallHooks16( WH_CBT, HCBT_ACTIVATE, (WPARAM16)hWnd,
- (LPARAM)SEGPTR_GET(cbtStruct) );
+ bRet = (BOOL)HOOK_CallHooks16( WH_CBT, HCBT_ACTIVATE, (WPARAM16)hWnd,
+ (LPARAM)SEGPTR_GET(cbtStruct) );
SEGPTR_FREE(cbtStruct);
- if (wRet)
- {
- /* Unlock the active queue before returning */
- if ( pOldActiveQueue )
- QUEUE_Unlock( pOldActiveQueue );
- WIN_ReleaseWndPtr(wndPtr);
- return wRet;
- }
+ if (bRet) goto CLEANUP_END;
}
/* set prev active wnd to current active wnd and send notification */
@@ -1664,20 +1673,14 @@
if (!SendMessageA( hwndPrevActive, WM_NCACTIVATE, FALSE, 0 ))
{
- if (GetSysModalWindow16() != hWnd) goto CLEANUP;
+ if (GetSysModalWindow16() != hWnd)
+ goto CLEANUP_END;
/* disregard refusal if hWnd is sysmodal */
}
-#if 1
SendMessageA( hwndPrevActive, WM_ACTIVATE,
MAKEWPARAM( WA_INACTIVE, wIconized ),
(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
* (global active queue may have changed)
@@ -1686,7 +1689,7 @@
hwndActive = PERQDATA_GetActiveWnd( pTempActiveQueue->pQData );
QUEUE_Unlock( pTempActiveQueue );
if( hwndPrevActive != hwndActive )
- goto CLEANUP;
+ goto CLEANUP_END;
}
/* Set new active window in the message queue */
@@ -1722,7 +1725,8 @@
if( wndTemp != wndPtr )
SetWindowPos(hWnd, HWND_TOP, 0,0,0,0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
- if (!IsWindow(hWnd)) goto CLEANUP;
+ if (!IsWindow(hWnd))
+ goto CLEANUP;
}
/* Get a handle to the new active queue */
@@ -1780,15 +1784,9 @@
wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
WIN_ReleaseWndPtr(wndTemp);
SendMessageA( hWnd, WM_NCACTIVATE, TRUE, 0 );
-#if 1
SendMessageA( hWnd, WM_ACTIVATE,
MAKEWPARAM( (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE, wIconized),
(LPARAM)hwndPrevActive );
-#else
- SendMessage16(hWnd, WM_ACTIVATE, (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE,
- MAKELPARAM( (HWND16)hwndPrevActive, wIconized) );
-#endif
-
if( !IsWindow(hWnd) ) goto CLEANUP;
}
@@ -1807,17 +1805,20 @@
/* if active wnd is minimized redraw icon title */
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 )
QUEUE_Unlock( pNewActiveQueue );
+
+CLEANUP_END:
+
+ if ( pOldActiveQueue )
+ QUEUE_Unlock( pOldActiveQueue );
+
WIN_ReleaseWndPtr(wndPtr);
- return bRet ? (hWnd == hwndActive) : 0;
+ return bRet;
}
/*******************************************************************
@@ -2231,35 +2232,70 @@
/***********************************************************************
* 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;
+ 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;
- rect.left = pOldClientRect->right - pNewClientRect->left;
- rect.right = pNewClientRect->right - pNewClientRect->left;
- wErase = 1;
- PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
- RDW_ERASENOW | RDW_ALLCHILDREN, RDW_EX_TOPFRAME );
- }
- if( pNewClientRect->bottom > pOldClientRect->bottom ) /* redraw exposed client area on the bottom */
- {
- rect.left = 0; rect.right = ((wErase)? pOldClientRect->right : pNewClientRect->right) - pNewClientRect->left;
- rect.top = pOldClientRect->bottom - pNewClientRect->top;
- rect.bottom = pNewClientRect->bottom - pNewClientRect->top;
- wErase = 1;
- PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
- RDW_ERASENOW | RDW_ALLCHILDREN, RDW_EX_TOPFRAME );
- }
- if( !wErase ) /* IMMEDIATELY update the nonclient area */
- {
- HRGN h;
- if( (h = WIN_UpdateNCRgn(wndPtr, TRUE, TRUE)) > 1) DeleteObject( h );
- }
+ /* FIXME: WVR alignment flags */
+
+ if( wndPtr->rectClient.right > pOldClientRect->right ) /* right edge */
+ {
+ i++;
+ rect.top = 0;
+ rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
+ rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left;
+ if(!(uFlags & SWP_EX_NOCOPY))
+ rect.left = pOldClientRect->right - wndPtr->rectClient.left;
+ else
+ {
+ rect.left = 0;
+ goto redraw;
+ }
+ }
+
+ if( wndPtr->rectClient.bottom > pOldClientRect->bottom ) /* bottom edge */
+ {
+ if( i )
+ hrgn = CreateRectRgnIndirect( &rect );
+ rect.left = 0;
+ rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left;
+ rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
+ if(!(uFlags & SWP_EX_NOCOPY))
+ rect.top = pOldClientRect->bottom - wndPtr->rectClient.top;
+ else
+ rect.top = 0;
+ if( i++ )
+ REGION_UnionRectWithRgn( hrgn, &rect );
+ }
+
+ if( i == 0 && (uFlags & SWP_EX_NOCOPY) ) /* force redraw anyway */
+ {
+ rect = wndPtr->rectWindow;
+ OffsetRect( &rect, wndPtr->rectWindow.left - wndPtr->rectClient.left,
+ wndPtr->rectWindow.top - wndPtr->rectClient.top );
+ i++;
+ }
+ }
+
+ if( i )
+ {
+redraw:
+ PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, hrgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
+ RDW_ERASENOW | RDW_ALLCHILDREN, RDW_EX_TOPFRAME | RDW_EX_USEHRGN );
+ }
+ else
+ hrgn = WIN_UpdateNCRgn(wndPtr, TRUE, TRUE);
+
+ if( hrgn > 1 )
+ DeleteObject( hrgn );
}
/***********************************************************************
@@ -2482,7 +2518,7 @@
/* Common operations */
- SWP_DoNCCalcSize( wndPtr, &winpos, &newWindowRect, &newClientRect, flags );
+ wvrFlags = SWP_DoNCCalcSize( wndPtr, &winpos, &newWindowRect, &newClientRect, flags );
if(!(winpos.flags & SWP_NOZORDER))
{
@@ -2505,6 +2541,23 @@
oldWindowRect = wndPtr->rectWindow;
oldClientRect = wndPtr->rectClient;
+ /* Find out if we have to redraw the whole client rect */
+
+ if( oldClientRect.bottom - oldClientRect.top ==
+ newClientRect.bottom - newClientRect.top ) wvrFlags &= ~WVR_VREDRAW;
+
+ if( oldClientRect.right - oldClientRect.left ==
+ newClientRect.right - newClientRect.left ) wvrFlags &= ~WVR_HREDRAW;
+
+ 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 */
{
BOOL bCallDriver = TRUE;
@@ -2512,9 +2565,6 @@
winpos.hwndInsertAfter = hwndInsertAfter;
- wndPtr->rectWindow = newWindowRect;
- wndPtr->rectClient = newClientRect;
-
if( !(winpos.flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOREDRAW)) )
{
/* This is the only place where we need to force repainting of the contents
@@ -2533,15 +2583,15 @@
winpos.hwndInsertAfter = tempInsertAfter;
bCallDriver = FALSE;
- if( (oldClientRect.left - oldWindowRect.left == newClientRect.left - newWindowRect.left) &&
- (oldClientRect.top - oldWindowRect.top == newClientRect.top - newWindowRect.top) )
- SWP_DoSimpleFrameChanged(wndPtr, &newClientRect, &oldClientRect );
+ if( winpos.flags & SWP_NOCLIENTMOVE )
+ SWP_DoSimpleFrameChanged(wndPtr, &oldClientRect, winpos.flags, uFlags );
else
{
/* client area moved but window extents remained the same, copy valid bits */
visRgn = CreateRectRgn( 0, 0, 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 @@
if( !(winpos.flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOREDRAW)) )
{
if( (oldClientRect.left - oldWindowRect.left == newClientRect.left - newWindowRect.left) &&
- (oldClientRect.top - oldWindowRect.top == newClientRect.top - newWindowRect.top) )
+ (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,
newWindowRect.bottom - newWindowRect.top);
@@ -2606,20 +2661,11 @@
}
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 )
{
wndPtr->dwStyle |= WS_VISIBLE;
uFlags |= SWP_EX_PAINTSELF;
- visRgn = 1;
+ visRgn = 1; /* redraw the whole window */
}
else if( !(winpos.flags & SWP_NOREDRAW) )
{
@@ -2632,16 +2678,15 @@
}
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 )
uFlags = SWP_CopyValidBits(wndPtr, &visRgn, &oldWindowRect,
&oldClientRect, uFlags);
else
{
+ /* nothing moved, redraw frame if needed */
+
if( winpos.flags & SWP_FRAMECHANGED )
- SWP_DoSimpleFrameChanged( wndPtr, &newClientRect, &oldClientRect );
+ SWP_DoSimpleFrameChanged( wndPtr, &oldClientRect, winpos.flags, uFlags );
if( visRgn )
{
DeleteObject( visRgn );
@@ -2669,11 +2714,6 @@
/* ------------------------------------------------------------------------ FINAL */
- /* Activate the window */
-
- if (!(flags & SWP_NOACTIVATE))
- WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE );
-
if (wndPtr->flags & WIN_NATIVE)
EVENT_Synchronize(); /* Synchronize with the host window system */
@@ -2682,7 +2722,11 @@
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 )
{
@@ -2707,6 +2751,9 @@
WIN_ReleaseDesktop();
+ if (!(flags & SWP_NOACTIVATE))
+ WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE );
+
/* And last, send the WM_WINDOWPOSCHANGED message */
TRACE(win,"\tstatus flags = %04x\n", winpos.flags & SWP_AGG_STATUSFLAGS);
diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c
index 9a730c7..92da752 100644
--- a/windows/x11drv/clipboard.c
+++ b/windows/x11drv/clipboard.c
@@ -24,7 +24,6 @@
extern HWND hWndClipWindow;
extern WINE_CLIPFORMAT ClipFormats[];
-static Bool selectionWait = False;
static Bool selectionAcquired = False;
static Window selectionWindow = None;
static Window selectionPrevWindow = None;
@@ -67,15 +66,13 @@
/**************************************************************************
* 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;
LPWINE_CLIPFORMAT lpFormat = ClipFormats;
- TRACE(clipboard,"ReadSelection callback\n");
+ TRACE(clipboard,"Reading X selection...\n");
if(prop != None)
{
@@ -126,19 +123,16 @@
if( hText )
{
- lpFormat = &ClipFormats[CF_TEXT-1];
- if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32)
- CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow));
- lpFormat = &ClipFormats[CF_OEMTEXT-1];
- if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32)
- CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow));
-
- lpFormat->wDataPresent = 1;
- lpFormat->hData32 = hText;
- lpFormat->hData16 = 0;
+ lpFormat = &ClipFormats[CF_TEXT-1];
+ if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32)
+ CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow));
+ lpFormat = &ClipFormats[CF_OEMTEXT-1];
+ if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32)
+ CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow));
+ lpFormat->wDataPresent = 1;
+ lpFormat->hData32 = hText;
+ lpFormat->hData16 = 0;
}
-
- selectionWait=False;
}
/**************************************************************************
@@ -180,27 +174,35 @@
}
/**************************************************************************
- * X11DRV_CLIPBOARD_EmptyClipboard
+ * X11DRV_CLIPBOARD_Empty
*/
-void X11DRV_CLIPBOARD_EmptyClipboard()
+void X11DRV_CLIPBOARD_Empty()
{
- if(selectionAcquired)
+ if( selectionAcquired )
{
- selectionAcquired = False;
- selectionPrevWindow = selectionWindow;
- selectionWindow = None;
+ XEvent xe;
+
+ selectionAcquired = False;
+ selectionPrevWindow = selectionWindow;
+ selectionWindow = None;
- TRACE(clipboard, "\tgiving up selection (spw = %08x)\n",
- (unsigned)selectionPrevWindow);
+ TRACE(clipboard, "\tgiving up selection (spw = %08x)\n",
+ (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;
@@ -226,45 +228,55 @@
}
/**************************************************************************
- * 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();
- WND *tmpWnd = WIN_FindWndPtr(hWnd);
+ WND* wnd = NULL;
- if( selectionAcquired )
- return TRUE;
+ if( wFormat != CF_OEMTEXT ) return FALSE;
- 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
- * CLIPBOARD_ReadSelection() will be invoked
- * from the SelectionNotify event handler */
-
- TSXConvertSelection(display, XA_PRIMARY, XA_STRING,
- TSXInternAtom(display, "PRIMARY_TEXT", False),
- X11DRV_WND_FindXWindow(tmpWnd ),
- CurrentTime);
+ EnterCriticalSection( &X11DRV_CritSection );
+ XConvertSelection(display, XA_PRIMARY, XA_STRING,
+ XInternAtom(display, "PRIMARY_TEXT", False),
+ w, CurrentTime);
- WIN_ReleaseWndPtr(tmpWnd);
+ /* wait until SelectionNotify is received */
- /* wait until SelectionNotify is processed
- *
- * FIXME: Use TSXCheckTypedWindowEvent() instead ( same in the
- * CLIPBOARD_CheckSelection() ).
- */
+ while( TRUE )
+ {
+ if( XCheckTypedWindowEvent(display, w, SelectionNotify, &xe) )
+ if( xe.xselection.selection == XA_PRIMARY )
+ break;
+ }
+ LeaveCriticalSection( &X11DRV_CritSection );
- selectionWait=True;
- while(selectionWait) EVENT_WaitNetEvent( TRUE, FALSE );
+ if (xe.xselection.target != XA_STRING)
+ X11DRV_CLIPBOARD_ReadSelection( 0, None );
+ else
+ X11DRV_CLIPBOARD_ReadSelection( xe.xselection.requestor,
+ xe.xselection.property );
- /* we treat Unix text as CF_OEMTEXT */
- TRACE(clipboard,"\tgot CF_OEMTEXT = %i\n",
- ClipFormats[CF_OEMTEXT-1].wDataPresent);
+ /* treat Unix text as CF_OEMTEXT */
- 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;
}
/**************************************************************************
diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c
index 106903a..876dbfa 100644
--- a/windows/x11drv/event.c
+++ b/windows/x11drv/event.c
@@ -95,10 +95,10 @@
static void EVENT_GraphicsExpose( WND *pWnd, XGraphicsExposeEvent *event );
static void EVENT_ConfigureNotify( WND *pWnd, XConfigureEvent *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_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?
static void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event );
@@ -387,19 +387,22 @@
WND *pWnd;
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.
This check is placed here to avoid getting error messages below,
as X might send some of these even for windows that have already
been deleted ... */
- case UnmapNotify:
case CirculateNotify:
case CreateNotify:
case DestroyNotify:
case GravityNotify:
case ReparentNotify:
return;
- }
+ }
if ( TSXFindContext( display, event->xany.window, winContext,
(char **)&pWnd ) != 0) {
@@ -482,11 +485,6 @@
EVENT_SelectionRequest( pWnd, (XSelectionRequestEvent *)event );
break;
- case SelectionNotify:
- if (!pWnd) return;
- EVENT_SelectionNotify( (XSelectionEvent *)event );
- break;
-
case SelectionClear:
if (!pWnd) return;
EVENT_SelectionClear( pWnd, (XSelectionClearEvent*) event );
@@ -508,9 +506,14 @@
case MapNotify:
if (!pWnd) return;
- EVENT_MapNotify( pWnd->hwndSelf, (XMapEvent *)event );
+ EVENT_MapNotify( pWnd, (XMapEvent *)event );
break;
-
+
+ case UnmapNotify:
+ if (!pWnd) return;
+ EVENT_UnmapNotify( pWnd, (XUnmapEvent *)event );
+ break;
+
default:
WARN(event, "Unprocessed event %s for hwnd %04x\n",
event_names[event->type], pWnd? pWnd->hwndSelf : 0 );
@@ -1037,7 +1040,7 @@
if( oldClientRect.top - oldWindowRect.top != newClientRect.top - newWindowRect.top ||
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 );
SendMessageA( winpos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos );
@@ -1059,22 +1062,26 @@
{
XSelectionEvent result;
Atom rprop = None;
- Window request = event->requestor;
+ Window request = event->requestor;
if(event->target == XA_STRING)
- {
+ {
HANDLE16 hText;
LPSTR text;
int size,i,j;
rprop = event->property;
- if(rprop == None) rprop = event->target;
+ if( rprop == None )
+ rprop = event->target;
- if(event->selection!=XA_PRIMARY) rprop = None;
- else if(!CLIPBOARD_IsPresent(CF_OEMTEXT)) rprop = None;
+ if( event->selection != XA_PRIMARY )
+ rprop = None;
+ else
+ if( !CLIPBOARD_IsPresent(CF_OEMTEXT) )
+ rprop = None;
else
- {
+ {
/* open to make sure that clipboard is available */
BOOL couldOpen = OpenClipboard( pWnd->hwndSelf );
@@ -1088,11 +1095,11 @@
lpstr = (char*)HEAP_xalloc( GetProcessHeap(), 0, size-- );
for(i=0,j=0; i < size && text[i]; i++ )
- {
+ {
if( text[i] == '\r' &&
(text[i+1] == '\n' || text[i+1] == '\0') ) continue;
lpstr[j++] = text[i];
- }
+ }
lpstr[j]='\0';
TSXChangeProperty(display, request, rprop,
@@ -1103,11 +1110,13 @@
/* close only if we opened before */
if(couldOpen) CloseClipboard();
- }
- }
+ }
+ }
- if(rprop == None)
- TRACE(event,"Request for %s ignored\n", TSXGetAtomName(display,event->target));
+ if( rprop == None)
+ TRACE(event,"Request for %s ignored\n", TSXGetAtomName(display,event->target));
+
+ /* reply to sender */
result.type = SelectionNotify;
result.display = display;
@@ -1119,21 +1128,6 @@
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
*/
@@ -1465,18 +1459,36 @@
/**********************************************************************
* EVENT_MapNotify
*/
-void EVENT_MapNotify( HWND hWnd, XMapEvent *event )
+void EVENT_MapNotify( WND* wnd, XMapEvent *event )
{
HWND hwndFocus = GetFocus();
- WND *tmpWnd = WIN_FindWndPtr(hwndFocus);
-
- if (hwndFocus && IsChild( hWnd, hwndFocus ))
- X11DRV_WND_SetFocus(tmpWnd );
- WIN_ReleaseWndPtr(tmpWnd);
+ WND *wndFocus = WIN_FindWndPtr(hwndFocus);
+
+ if (wnd->flags & WIN_MANAGED)
+ wnd->dwStyle &= ~WS_MINIMIZE;
+
+ if (hwndFocus && IsChild( wnd->hwndSelf, hwndFocus ))
+ X11DRV_WND_SetFocus(wndFocus);
+
+ WIN_ReleaseWndPtr(wndFocus);
return;
}
+
+/**********************************************************************
+ * EVENT_MapNotify
+ */
+void EVENT_UnmapNotify( WND* wnd, XUnmapEvent *event )
+{
+ if (wnd->flags & WIN_MANAGED)
+ {
+ EndMenu();
+ wnd->dwStyle |= WS_MINIMIZE;
+ }
+}
+
+
/**********************************************************************
* X11DRV_EVENT_Pending
*/
diff --git a/windows/x11drv/init.c b/windows/x11drv/init.c
index d7a59e1..f3c5f65 100644
--- a/windows/x11drv/init.c
+++ b/windows/x11drv/init.c
@@ -28,9 +28,9 @@
CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver =
{
- X11DRV_CLIPBOARD_EmptyClipboard,
- X11DRV_CLIPBOARD_SetClipboardData,
- X11DRV_CLIPBOARD_RequestSelection,
+ X11DRV_CLIPBOARD_Empty,
+ X11DRV_CLIPBOARD_SetData,
+ X11DRV_CLIPBOARD_GetData,
X11DRV_CLIPBOARD_ResetOwner
};
diff --git a/windows/x11drv/wnd.c b/windows/x11drv/wnd.c
index a877dec..1993d5e 100644
--- a/windows/x11drv/wnd.c
+++ b/windows/x11drv/wnd.c
@@ -16,6 +16,7 @@
#include <stdlib.h>
#include <string.h>
+#include "bitmap.h"
#include "color.h"
#include "debug.h"
#include "display.h"
@@ -27,10 +28,13 @@
#include "windef.h"
#include "class.h"
#include "x11drv.h"
+#include "wine/winuser16.h"
/**********************************************************************/
extern Cursor X11DRV_MOUSE_XCursor; /* Current X cursor */
+extern BOOL X11DRV_CreateBitmap( HBITMAP );
+extern Pixmap X11DRV_BITMAP_Pixmap( HBITMAP );
/**********************************************************************/
@@ -41,6 +45,7 @@
Atom wmDeleteWindow = None;
Atom dndProtocol = None;
Atom dndSelection = None;
+Atom wmChangeState = None;
/***********************************************************************
* X11DRV_WND_GetXWindow
@@ -152,6 +157,8 @@
dndProtocol = TSXInternAtom( display, "DndProtocol" , False );
if( dndSelection == None )
dndSelection = TSXInternAtom( display, "DndSelection" , False );
+ if( wmChangeState == None )
+ wmChangeState = TSXInternAtom (display, "WM_CHANGE_STATE", False);
((X11DRV_WND_DATA *) wndPtr->pDriverData)->window =
X11DRV_WND_GetXRootWindow( wndPtr );
@@ -160,6 +167,7 @@
return TRUE;
}
+
/**********************************************************************
* X11DRV_WND_CreateWindow
*/
@@ -195,13 +203,14 @@
}
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.backing_store = Options.backingstore ? WhenMapped : NotUseful;
win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0);
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 =
TSXCreateWindow( display,
X11DRV_WND_GetXRootWindow(wndPtr),
@@ -216,28 +225,32 @@
if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr)))
return FALSE;
- if (wndPtr->flags & WIN_MANAGED) {
- XClassHint *class_hints = TSXAllocClassHint();
+ if (wndPtr->flags & WIN_MANAGED)
+ {
+ XClassHint *class_hints = TSXAllocClassHint();
- if (class_hints) {
- class_hints->res_name = "wineManaged";
- class_hints->res_class = "Wine";
- TSXSetClassHint( display, ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window, class_hints );
- TSXFree (class_hints);
- }
+ if (class_hints)
+ {
+ class_hints->res_name = "wineManaged";
+ class_hints->res_class = "Wine";
+ TSXSetClassHint( display, ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window, class_hints );
+ TSXFree (class_hints);
+ }
- if (cs->dwExStyle & WS_EX_DLGMODALFRAME) {
- XSizeHints* size_hints = TSXAllocSizeHints();
+ if (cs->dwExStyle & WS_EX_DLGMODALFRAME)
+ {
+ XSizeHints* size_hints = TSXAllocSizeHints();
- 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->flags = (PSize | PMinSize | PMaxSize);
- TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr), size_hints,
- XA_WM_NORMAL_HINTS );
- TSXFree(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->flags = (PSize | PMinSize | PMaxSize);
+ TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr),
+ size_hints, XA_WM_NORMAL_HINTS );
+ TSXFree(size_hints);
+ }
+ }
}
if (cs->hwndParent) /* Get window owner */
@@ -258,12 +271,36 @@
{
wm_hints->flags = InputHint | StateHint | WindowGroupHint;
wm_hints->input = True;
- if( wndPtr->dwStyle & WS_VISIBLE )
- wm_hints->initial_state = (wndPtr->dwStyle & WS_MINIMIZE &&
- wndPtr->flags & WIN_MANAGED ) ?
- IconicState : NormalState;
+
+ if( wndPtr->flags & WIN_MANAGED )
+ {
+ 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
- wm_hints->initial_state = WithdrawnState;
+ wm_hints->initial_state = NormalState;
wm_hints->window_group = wGroupLeader;
TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
@@ -279,14 +316,21 @@
*/
BOOL X11DRV_WND_DestroyWindow(WND *wndPtr)
{
- if (X11DRV_WND_GetXWindow(wndPtr))
- {
+ Window w;
+ if ((w = X11DRV_WND_GetXWindow(wndPtr)))
+ {
XEvent xe;
- TSXDeleteContext( display, X11DRV_WND_GetXWindow(wndPtr), winContext );
- TSXDestroyWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
- while( TSXCheckWindowEvent(display, X11DRV_WND_GetXWindow(wndPtr), NoEventMask, &xe) );
+ TSXDeleteContext( display, w, winContext );
+ TSXDestroyWindow( display, w );
+ while( TSXCheckWindowEvent(display, w, NoEventMask, &xe) );
+
((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None;
- }
+ if( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap )
+ {
+ DeleteObject( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap );
+ ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = 0;
+ }
+ }
return TRUE;
}
@@ -449,7 +493,7 @@
if(bChangePos)
{
- if ( !(winpos->flags & SWP_NOSIZE))
+ if ( !(winpos->flags & SWP_NOSIZE))
{
winChanges.width = (winpos->cx > 0 ) ? winpos->cx : 1;
winChanges.height = (winpos->cy > 0 ) ? winpos->cy : 1;
@@ -476,13 +520,13 @@
}
}
}
- if (!(winpos->flags & SWP_NOMOVE))
+ if (!(winpos->flags & SWP_NOMOVE))
{
winChanges.x = winpos->x;
winChanges.y = winpos->y;
changeMask |= CWX | CWY;
}
- if (!(winpos->flags & SWP_NOZORDER))
+ if (!(winpos->flags & SWP_NOZORDER))
{
winChanges.stack_mode = Below;
changeMask |= CWStackMode;
@@ -504,15 +548,18 @@
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(X11DRV_WND_GetXWindow(wndPtr)) TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
+ if(X11DRV_WND_GetXWindow(wndPtr))
+ TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
}
WIN_ReleaseWndPtr(winposPtr);
}
@@ -668,7 +715,46 @@
}
/***********************************************************************
+ * 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
+ *
+ * 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)
{
@@ -680,7 +766,55 @@
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 )
{
@@ -688,24 +822,12 @@
((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity = value;
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) )
- {
- 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 X11DRV_SetWMHint( display, wnd, InputHint, value );
}
}
return FALSE;