diff --git a/controls/menu.c b/controls/menu.c index 4a65fd25f7e..ba47fe4667b 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -1177,10 +1177,11 @@ static void MENU_DrawPopupMenu( HWND hwnd, HDC hdc, HMENU hmenu ) GetClientRect( hwnd, &rect ); -/* if(!TWEAK_Win95Look) { */ + if(TWEAK_WineLook == WIN31_LOOK) + { rect.bottom -= POPUP_YSHADE * SYSMETRICS_CYBORDER; rect.right -= POPUP_XSHADE * SYSMETRICS_CXBORDER; -/* } */ + } 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; - width += POPUP_XSHADE * SYSMETRICS_CXBORDER; /* add space for shading */ - height += POPUP_YSHADE * SYSMETRICS_CYBORDER; + if( TWEAK_WineLook == WIN31_LOOK ) + { + width += POPUP_XSHADE * SYSMETRICS_CXBORDER; /* add space for shading */ + height += POPUP_YSHADE * SYSMETRICS_CYBORDER; + } /* NOTE: In Windows, top menu popup is not owned. */ if (!pTopPopupWnd) /* create top level popup menu window */ diff --git a/graphics/x11drv/bitmap.c b/graphics/x11drv/bitmap.c index ea677d0c1a8..1820aa2f8c9 100644 --- a/graphics/x11drv/bitmap.c +++ b/graphics/x11drv/bitmap.c @@ -530,4 +530,15 @@ BOOL X11DRV_BITMAP_DeleteObject( HBITMAP hbitmap, BITMAPOBJ * bmp ) 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) */ diff --git a/include/clipboard.h b/include/clipboard.h index 605e3575fff..16496d3170f 100644 --- a/include/clipboard.h +++ b/include/clipboard.h @@ -19,9 +19,9 @@ typedef struct tagWINE_CLIPFORMAT { typedef struct tagCLIPBOARD_DRIVER { - void (*pEmptyClipboard)(void); - void (*pSetClipboardData)(UINT); - BOOL (*pRequestSelection)(void); + void (*pEmpty)(void); + void (*pSetData)(UINT); + BOOL (*pGetData)(UINT); void (*pResetOwner)(struct tagWND *, BOOL); } CLIPBOARD_DRIVER; diff --git a/include/ts_xlib.h b/include/ts_xlib.h index cf7099c064d..11e985a0392 100644 --- a/include/ts_xlib.h +++ b/include/ts_xlib.h @@ -43,6 +43,7 @@ extern int TSXInitThreads(void); extern int * TSXListDepths(Display*, int, int*); extern int TSXReconfigureWMWindow(Display*, Window, int, unsigned int, XWindowChanges*); extern int TSXSetWMProtocols(Display*, Window, Atom*, int); +extern int TSXIconifyWindow(Display*, Window, int); extern int TSXSetTransientForHint(Display*, Window, Window); extern int TSXActivateScreenSaver(Display*); extern int TSXAllocColor(Display*, Colormap, XColor*); diff --git a/include/ttydrv.h b/include/ttydrv.h index d66997f442b..d8dc61ed4a2 100644 --- a/include/ttydrv.h +++ b/include/ttydrv.h @@ -68,9 +68,9 @@ extern void TTYDRV_USER_EndDebugging(void); extern struct tagCLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver; -extern void TTYDRV_CLIPBOARD_EmptyClipboard(void); -extern void TTYDRV_CLIPBOARD_SetClipboardData(UINT wFormat); -extern BOOL TTYDRV_CLIPBOARD_RequestSelection(void); +extern void TTYDRV_CLIPBOARD_Empty(void); +extern void TTYDRV_CLIPBOARD_SetData(UINT wFormat); +extern BOOL TTYDRV_CLIPBOARD_GetData(UINT wFormat); extern void TTYDRV_CLIPBOARD_ResetOwner(struct tagWND *pWnd, BOOL bFooBar); /* TTY desktop driver */ diff --git a/include/win.h b/include/win.h index 1c37a537162..aa366b91fdd 100644 --- a/include/win.h +++ b/include/win.h @@ -92,6 +92,7 @@ typedef struct tagWND #define HAK_BITGRAVITY 1 #define HAK_ACCEPTFOCUS 2 +#define HAK_ICONICSTATE 3 /* Bit Gravity */ diff --git a/include/winpos.h b/include/winpos.h index 66bbcecbcdf..e07011f6757 100644 --- a/include/winpos.h +++ b/include/winpos.h @@ -31,7 +31,7 @@ extern BOOL WINPOS_ShowIconTitle( WND* pWnd, BOOL bShow ); extern void WINPOS_GetMinMaxInfo( WND* pWnd, POINT *maxSize, POINT *maxPos, POINT *minTrack, 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, BOOL fChangeFocus ); extern BOOL WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); diff --git a/include/x11drv.h b/include/x11drv.h index 4b9a9676d7a..ef778d9725c 100644 --- a/include/x11drv.h +++ b/include/x11drv.h @@ -313,13 +313,11 @@ extern void X11DRV_USER_EndDebugging(void); extern struct tagCLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver; -extern void X11DRV_CLIPBOARD_EmptyClipboard(void); -extern void X11DRV_CLIPBOARD_SetClipboardData(UINT wFormat); -extern BOOL X11DRV_CLIPBOARD_RequestSelection(void); +extern void X11DRV_CLIPBOARD_Empty(void); +extern void X11DRV_CLIPBOARD_SetData(UINT wFormat); +extern BOOL X11DRV_CLIPBOARD_GetData(UINT wFormat); extern void X11DRV_CLIPBOARD_ResetOwner(struct tagWND *pWnd, BOOL bFooBar); - -void X11DRV_CLIPBOARD_ReadSelection(Window w, Atom prop); -void X11DRV_CLIPBOARD_ReleaseSelection(Window w, HWND hwnd); +extern void X11DRV_CLIPBOARD_ReleaseSelection(Window w, HWND hwnd); /* X11 desktop driver */ @@ -415,6 +413,7 @@ extern struct tagWND_DRIVER X11DRV_WND_Driver; typedef struct _X11DRV_WND_DATA { Window window; + HBITMAP hWMIconBitmap; int bit_gravity; } X11DRV_WND_DATA; diff --git a/tsx11/X11_calls b/tsx11/X11_calls index e570e6994d8..4864e33d499 100644 --- a/tsx11/X11_calls +++ b/tsx11/X11_calls @@ -77,6 +77,7 @@ XGetWMSizeHints XGetWindowAttributes XGetWindowProperty XGrabServer +XIconifyWindow XInitThreads XInstallColormap XInternAtom diff --git a/tsx11/ts_xlib.c b/tsx11/ts_xlib.c index 6f3a9f04fe9..d4b6a4819f1 100644 --- a/tsx11/ts_xlib.c +++ b/tsx11/ts_xlib.c @@ -308,6 +308,17 @@ int TSXSetWMProtocols(Display* a0, Window a1, Atom* a2, int a3) 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 r; diff --git a/windows/clipboard.c b/windows/clipboard.c index 75a1a1ebc38..031fc08d72b 100644 --- a/windows/clipboard.c +++ b/windows/clipboard.c @@ -250,7 +250,7 @@ BOOL WINAPI EmptyClipboard(void) hWndClipOwner = hWndClipWindow; - CLIPBOARD_Driver->pEmptyClipboard(); + CLIPBOARD_Driver->pEmpty(); return TRUE; } @@ -293,7 +293,7 @@ HANDLE16 WINAPI SetClipboardData16( UINT16 wFormat, HANDLE16 hData ) 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 @@ HANDLE16 WINAPI SetClipboardData16( UINT16 wFormat, HANDLE16 hData ) /************************************************************************** - * SetClipboardData32 (USER32.470) + * SetClipboardData (USER32.470) */ HANDLE WINAPI SetClipboardData( UINT wFormat, HANDLE hData ) { @@ -341,7 +341,7 @@ HANDLE WINAPI SetClipboardData( UINT wFormat, HANDLE hData ) 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 @@ static BOOL CLIPBOARD_RenderFormat(LPWINE_CLIPFORMAT lpFormat) * 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 @@ INT WINAPI CountClipboardFormats(void) 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 @@ INT WINAPI CountClipboardFormats(void) 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 @@ UINT WINAPI EnumClipboardFormats( UINT wFormat ) 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 @@ BOOL WINAPI IsClipboardFormatAvailable( UINT wFormat ) { 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 acb89ffc6ce..f18884917d2 100644 --- a/windows/message.c +++ b/windows/message.c @@ -502,12 +502,14 @@ static BOOL MSG_PeekHardwareMsg( MSG *msg, HWND hwnd, DWORD first, DWORD last, 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 f6c0c3c1c46..f608b7cf42d 100644 --- a/windows/ttydrv/clipboard.c +++ b/windows/ttydrv/clipboard.c @@ -15,7 +15,7 @@ char *TTYDRV_CLIPBOARD_szSelection = NULL; /*********************************************************************** * TTYDRV_CLIPBOARD_EmptyClipboard */ -void TTYDRV_CLIPBOARD_EmptyClipboard() +void TTYDRV_CLIPBOARD_Empty() { 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; } diff --git a/windows/ttydrv/init.c b/windows/ttydrv/init.c index 7f6a15bd12c..f58434c6f29 100644 --- a/windows/ttydrv/init.c +++ b/windows/ttydrv/init.c @@ -24,9 +24,9 @@ USER_DRIVER TTYDRV_USER_Driver = 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 402319de317..67c21f0e2c0 100644 --- a/windows/win.c +++ b/windows/win.c @@ -836,10 +836,14 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, /* 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 @@ WND **WIN_BuildWinArray( WND *wndPtr, UINT bwaFlags, UINT* pTotal ) 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 aadcd074ade..d98a4d7d028 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 @@ void WINPOS_GetMinMaxInfo( WND *wndPtr, POINT *maxSize, POINT *maxPos, * 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 @@ UINT16 WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect ) wndPtr->flags &= ~WIN_RESTORE_MAX; wndPtr->dwStyle |= WS_MINIMIZE; + if( wndPtr->flags & WIN_NATIVE ) + if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) ) + swpFlags |= MINMAX_NOSWP; + lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos ); 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->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 @@ UINT16 WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect ) 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 @@ BOOL WINAPI ShowWindow( HWND hwnd, INT cmd ) 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 @@ BOOL WINAPI ShowWindow( HWND hwnd, INT cmd ) { /* 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 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus) 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 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus) } /* 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 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus) /* 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 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus) 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 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus) 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 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus) 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 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus) 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 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus) /* 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 @@ nocopy: /*********************************************************************** * 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 @@ Pos: /* ----------------------------------------------------------------------- /* 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 @@ Pos: /* ----------------------------------------------------------------------- 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 @@ Pos: /* ----------------------------------------------------------------------- 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 @@ Pos: /* ----------------------------------------------------------------------- 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 @@ Pos: /* ----------------------------------------------------------------------- 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 @@ Pos: /* ----------------------------------------------------------------------- } 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 @@ Pos: /* ----------------------------------------------------------------------- } 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 @@ Pos: /* ----------------------------------------------------------------------- /* ------------------------------------------------------------------------ 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 @@ Pos: /* ----------------------------------------------------------------------- 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 @@ Pos: /* ----------------------------------------------------------------------- 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 9a730c7199a..92da752681a 100644 --- a/windows/x11drv/clipboard.c +++ b/windows/x11drv/clipboard.c @@ -24,7 +24,6 @@ extern HWND hWndClipOwner; 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 @@ static void X11DRV_CLIPBOARD_CheckSelection(WND* pWnd) /************************************************************************** * 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 @@ void X11DRV_CLIPBOARD_ReadSelection(Window w,Atom prop) 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 @@ 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; - 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 @@ 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(); - 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 106903a710f..876dbfaa9a5 100644 --- a/windows/x11drv/event.c +++ b/windows/x11drv/event.c @@ -95,10 +95,10 @@ static void EVENT_Expose( WND *pWnd, XExposeEvent *event ); 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 @@ static void EVENT_ProcessEvent( XEvent *event ) 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 @@ static void EVENT_ProcessEvent( XEvent *event ) 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 @@ static void EVENT_ProcessEvent( XEvent *event ) 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 @@ TRACE(win, "%04x adjusted to (%i,%i)-(%i,%i)\n", pWnd->hwndSelf, 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 @@ static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event ) { 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 @@ static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event ) 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 @@ static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event ) /* 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 @@ static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event ) 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 @@ void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event ) /********************************************************************** * 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 d7a59e1e6a8..f3c5f65cd9b 100644 --- a/windows/x11drv/init.c +++ b/windows/x11drv/init.c @@ -28,9 +28,9 @@ USER_DRIVER X11DRV_USER_Driver = 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 a877dec0bb5..1993d5e24e8 100644 --- a/windows/x11drv/wnd.c +++ b/windows/x11drv/wnd.c @@ -16,6 +16,7 @@ #include #include +#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 wmProtocols = None; Atom wmDeleteWindow = None; Atom dndProtocol = None; Atom dndSelection = None; +Atom wmChangeState = None; /*********************************************************************** * X11DRV_WND_GetXWindow @@ -152,6 +157,8 @@ BOOL X11DRV_WND_CreateDesktopWindow(WND *wndPtr, CLASS *classPtr, BOOL bUnicode) 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 @@ BOOL X11DRV_WND_CreateDesktopWindow(WND *wndPtr, CLASS *classPtr, BOOL bUnicode) return TRUE; } + /********************************************************************** * X11DRV_WND_CreateWindow */ @@ -195,13 +203,14 @@ BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO } 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 @@ BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO 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 @@ BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO { 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_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO */ 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 @@ void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangeP 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 @@ 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.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 @@ void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangeP 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); } @@ -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 + * + * 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 @@ BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value) 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 @@ BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value) ((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;