summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/inc/win/salframe.h6
-rw-r--r--vcl/win/window/salframe.cxx302
2 files changed, 147 insertions, 161 deletions
diff --git a/vcl/inc/win/salframe.h b/vcl/inc/win/salframe.h
index 002b6731c72b..77902a40034e 100644
--- a/vcl/inc/win/salframe.h
+++ b/vcl/inc/win/salframe.h
@@ -82,6 +82,12 @@ public:
bool mbPropertiesStored; // has values stored in the window property store
void updateScreenNumber();
+
+private:
+ void ImplSetParentFrame( HWND hNewParentWnd, bool bAsChild );
+ bool InitFrameGraphicsDC( WinSalGraphics *pGraphics, HDC hDC, HWND hWnd );
+ bool ReleaseFrameGraphicsDC( WinSalGraphics* pGraphics );
+
public:
WinSalFrame();
virtual ~WinSalFrame() override;
diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx
index 74fb14120c6c..75784736c4e8 100644
--- a/vcl/win/window/salframe.cxx
+++ b/vcl/win/window/salframe.cxx
@@ -907,6 +907,34 @@ void WinSalFrame::updateScreenNumber()
}
}
+bool WinSalFrame::ReleaseFrameGraphicsDC( WinSalGraphics* pGraphics )
+{
+ assert( pGraphics );
+ SalData* pSalData = GetSalData();
+ HDC hDC = pGraphics->getHDC();
+ if ( !hDC )
+ return FALSE;
+ if ( pGraphics->getDefPal() )
+ SelectPalette( hDC, pGraphics->getDefPal(), TRUE );
+ pGraphics->DeInitGraphics();
+ // we don't want to run the WinProc in the main thread directly
+ // so we don't hit the mbNoYieldLock assert
+ if ( !pSalData->mpInstance->IsMainThread() )
+ {
+ assert( pGraphics == mpThreadGraphics );
+ SendMessageW( pSalData->mpInstance->mhComWnd, SAL_MSG_RELEASEDC,
+ reinterpret_cast<WPARAM>(mhWnd), reinterpret_cast<LPARAM>(hDC) );
+ pSalData->mnCacheDCInUse--;
+ }
+ else
+ {
+ assert( pGraphics == mpLocalGraphics );
+ ReleaseDC( mhWnd, hDC );
+ }
+ pGraphics->setHDC(nullptr);
+ return TRUE;
+}
+
WinSalFrame::~WinSalFrame()
{
SalData* pSalData = GetSalData();
@@ -921,18 +949,18 @@ WinSalFrame::~WinSalFrame()
*ppFrame = mpNextFrame;
mpNextFrame = nullptr;
- // Release Cache DC
- if ( mpThreadGraphics &&
- mpThreadGraphics->getHDC() )
- ReleaseGraphics( mpThreadGraphics );
+ // destroy the thread SalGraphics
+ if ( mpThreadGraphics )
+ {
+ ReleaseFrameGraphicsDC( mpThreadGraphics );
+ delete mpThreadGraphics;
+ mpThreadGraphics = nullptr;
+ }
- // destroy saved DC
+ // destroy the local SalGraphics
if ( mpLocalGraphics )
{
- if ( mpLocalGraphics->getDefPal() )
- SelectPalette( mpLocalGraphics->getHDC(), mpLocalGraphics->getDefPal(), TRUE );
- mpLocalGraphics->DeInitGraphics();
- ReleaseDC( mhWnd, mpLocalGraphics->getHDC() );
+ ReleaseFrameGraphicsDC( mpLocalGraphics );
delete mpLocalGraphics;
mpLocalGraphics = nullptr;
}
@@ -962,16 +990,50 @@ WinSalFrame::~WinSalFrame()
}
}
+bool WinSalFrame::InitFrameGraphicsDC( WinSalGraphics *pGraphics, HDC hDC, HWND hWnd )
+{
+ SalData* pSalData = GetSalData();
+ assert( pGraphics );
+ if ( !pSalData->mpInstance->IsMainThread() )
+ assert( pGraphics == mpThreadGraphics );
+ else
+ assert( pGraphics == mpLocalGraphics );
+ pGraphics->setHWND( hWnd );
+
+ HDC hCurrentDC = pGraphics->getHDC();
+ assert( !hCurrentDC || (hCurrentDC == hDC) );
+ if ( hCurrentDC )
+ return TRUE;
+ pGraphics->setHDC( hDC );
+
+ if ( !hDC )
+ return FALSE;
+
+ if ( pSalData->mhDitherPal )
+ {
+ pGraphics->setDefPal(SelectPalette( hDC, pSalData->mhDitherPal, TRUE ));
+ RealizePalette( hDC );
+ }
+ pGraphics->InitGraphics();
+
+ if ( pGraphics == mpThreadGraphics )
+ pSalData->mnCacheDCInUse++;
+ return TRUE;
+}
+
SalGraphics* WinSalFrame::AcquireGraphics()
{
- if ( mbGraphics )
+ if ( mbGraphics || !mhWnd )
return nullptr;
+ SalData* pSalData = GetSalData();
+ WinSalGraphics *pGraphics = nullptr;
+ HDC hDC = 0;
+
// Other threads get an own DC, because Windows modify in the
// other case our DC (changing clip region), when they send a
// WM_ERASEBACKGROUND message
- SalData* pSalData = GetSalData();
- if ( pSalData->mnAppThreadId != GetCurrentThreadId() )
+ if ( !pSalData->mpInstance->IsMainThread() )
{
// We use only three CacheDC's for all threads, because W9x is limited
// to max. 5 Cache DC's per thread
@@ -979,80 +1041,30 @@ SalGraphics* WinSalFrame::AcquireGraphics()
return nullptr;
if ( !mpThreadGraphics )
- {
mpThreadGraphics = new WinSalGraphics(WinSalGraphics::WINDOW, true, mhWnd, this);
- mpThreadGraphics->setHDC(nullptr);
- }
-
- HDC hDC = reinterpret_cast<HDC>(static_cast<sal_IntPtr>(SendMessageW( pSalData->mpInstance->mhComWnd,
- SAL_MSG_GETDC,
- reinterpret_cast<WPARAM>(mhWnd), 0 )));
- if ( hDC )
- {
- mpThreadGraphics->setHDC(hDC);
- if ( pSalData->mhDitherPal )
- {
- mpThreadGraphics->setDefPal(SelectPalette( hDC, pSalData->mhDitherPal, TRUE ));
- RealizePalette( hDC );
- }
- mpThreadGraphics->InitGraphics();
- mbGraphics = TRUE;
-
- pSalData->mnCacheDCInUse++;
- return mpThreadGraphics;
- }
- else
- return nullptr;
+ pGraphics = mpThreadGraphics;
+ assert( !pGraphics->getHDC() );
+ hDC = reinterpret_cast<HDC>(static_cast<sal_IntPtr>(SendMessageW( pSalData->mpInstance->mhComWnd,
+ SAL_MSG_GETDC, reinterpret_cast<WPARAM>(mhWnd), 0 )));
}
else
{
if ( !mpLocalGraphics )
- {
- HDC hDC = GetDC( mhWnd );
- if ( hDC )
- {
- mpLocalGraphics = new WinSalGraphics(WinSalGraphics::WINDOW, true, mhWnd, this);
- mpLocalGraphics->setHDC(hDC);
- if ( pSalData->mhDitherPal )
- {
- mpLocalGraphics->setDefPal(SelectPalette( hDC, pSalData->mhDitherPal, TRUE ));
- RealizePalette( hDC );
- }
- mpLocalGraphics->InitGraphics();
- mbGraphics = TRUE;
- }
- }
- else
- mbGraphics = TRUE;
-
- return mpLocalGraphics;
+ mpLocalGraphics = new WinSalGraphics(WinSalGraphics::WINDOW, true, mhWnd, this);
+ pGraphics = mpLocalGraphics;
+ hDC = pGraphics->getHDC();
+ if ( !hDC )
+ hDC = GetDC( mhWnd );
}
+
+ mbGraphics = InitFrameGraphicsDC( pGraphics, hDC, mhWnd );
+ return mbGraphics ? pGraphics : nullptr;
}
void WinSalFrame::ReleaseGraphics( SalGraphics* pGraphics )
{
if ( mpThreadGraphics == pGraphics )
- {
- if ( mpThreadGraphics->getHDC() )
- {
- SalData* pSalData = GetSalData();
- if ( mpThreadGraphics->getDefPal() )
- SelectPalette( mpThreadGraphics->getHDC(), mpThreadGraphics->getDefPal(), TRUE );
- mpThreadGraphics->DeInitGraphics();
- // we don't want to run the WinProc in the main thread directly
- // so we don't hit the mbNoYieldLock assert
- if ( !pSalData->mpInstance->IsMainThread() )
- SendMessageW( pSalData->mpInstance->mhComWnd,
- SAL_MSG_RELEASEDC,
- reinterpret_cast<WPARAM>(mhWnd),
- reinterpret_cast<LPARAM>(mpThreadGraphics->getHDC()) );
- else
- ReleaseDC( mhWnd, mpThreadGraphics->getHDC() );
- mpThreadGraphics->setHDC(nullptr);
- pSalData->mnCacheDCInUse--;
- }
- }
-
+ ReleaseFrameGraphicsDC( mpThreadGraphics );
mbGraphics = FALSE;
}
@@ -1436,10 +1448,10 @@ void WinSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight,
CallCallback( nEvent, nullptr );
}
-static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, bool bAsChild )
+void WinSalFrame::ImplSetParentFrame( HWND hNewParentWnd, bool bAsChild )
{
// save hwnd, will be overwritten in WM_CREATE during createwindow
- HWND hWndOld = pThis->mhWnd;
+ HWND hWndOld = mhWnd;
HWND hWndOldParent = ::GetParent( hWndOld );
SalData* pSalData = GetSalData();
@@ -1454,7 +1466,7 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, bool bAs
while( pFrame )
{
HWND hWndParent = ::GetParent( pFrame->mhWnd );
- if( pThis->mhWnd == hWndParent )
+ if( mhWnd == hWndParent )
children.push_back( pFrame );
pFrame = pFrame->mpNextFrame;
}
@@ -1464,13 +1476,13 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, bool bAs
while( pObject )
{
HWND hWndParent = ::GetParent( pObject->mhWnd );
- if( pThis->mhWnd == hWndParent )
+ if( mhWnd == hWndParent )
systemChildren.push_back( pObject );
pObject = pObject->mpNextObject;
}
- bool bNeedGraphics = pThis->mbGraphics;
- bool bNeedCacheDC = FALSE;
+ // to recreate the DCs, if they were destroyed
+ bool bHadLocalGraphics = FALSE, bHadThreadGraphics = FALSE;
HFONT hFont = nullptr;
HPEN hPen = nullptr;
@@ -1478,100 +1490,67 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, bool bAs
int oldCount = pSalData->mnCacheDCInUse;
- // Release Cache DC
- if ( pThis->mpThreadGraphics &&
- pThis->mpThreadGraphics->getHDC() )
+ // release the thread DC
+ if ( mpThreadGraphics )
{
// save current gdi objects before hdc is gone
- hFont = static_cast<HFONT>(GetCurrentObject( pThis->mpThreadGraphics->getHDC(), OBJ_FONT));
- hPen = static_cast<HPEN>(GetCurrentObject( pThis->mpThreadGraphics->getHDC(), OBJ_PEN));
- hBrush = static_cast<HBRUSH>(GetCurrentObject( pThis->mpThreadGraphics->getHDC(), OBJ_BRUSH));
- pThis->ReleaseGraphics( pThis->mpThreadGraphics );
+ HDC hDC = mpThreadGraphics->getHDC();
+ if ( hDC )
+ {
+ hFont = static_cast<HFONT>(GetCurrentObject( hDC, OBJ_FONT ));
+ hPen = static_cast<HPEN>(GetCurrentObject( hDC, OBJ_PEN ));
+ hBrush = static_cast<HBRUSH>(GetCurrentObject( hDC, OBJ_BRUSH ));
+ }
- // recreate cache dc only if it was destroyed
- bNeedCacheDC = TRUE;
+ bHadThreadGraphics = ReleaseFrameGraphicsDC( mpThreadGraphics );
+ assert( (bHadThreadGraphics && hDC) || (!bHadThreadGraphics && !hDC) );
}
- // destroy saved DC
- if ( pThis->mpLocalGraphics )
- {
- if ( pThis->mpLocalGraphics->getDefPal() )
- SelectPalette( pThis->mpLocalGraphics->getHDC(), pThis->mpLocalGraphics->getDefPal(), TRUE );
- pThis->mpLocalGraphics->DeInitGraphics();
- ReleaseDC( pThis->mhWnd, pThis->mpLocalGraphics->getHDC() );
- }
+ // release the local DC
+ if ( mpLocalGraphics )
+ bHadLocalGraphics = ReleaseFrameGraphicsDC( mpLocalGraphics );
// create a new hwnd with the same styles
HWND hWndParent = hNewParentWnd;
// forward to main thread
HWND hWnd = reinterpret_cast<HWND>(static_cast<sal_IntPtr>(SendMessageW( pSalData->mpInstance->mhComWnd,
bAsChild ? SAL_MSG_RECREATECHILDHWND : SAL_MSG_RECREATEHWND,
- reinterpret_cast<WPARAM>(hWndParent), reinterpret_cast<LPARAM>(pThis->mhWnd) )));
+ reinterpret_cast<WPARAM>(hWndParent), reinterpret_cast<LPARAM>(mhWnd) )));
// succeeded ?
SAL_WARN_IF( !IsWindow( hWnd ), "vcl", "WinSalFrame::SetParent not successful");
- // recreate DCs
- if( bNeedGraphics )
+ // re-create thread DC
+ if( bHadThreadGraphics )
{
- if( pThis->mpThreadGraphics )
- {
- pThis->mpThreadGraphics->setHWND(hWnd);
-
- if( bNeedCacheDC )
- {
- // re-create cached DC
- HDC hDC = reinterpret_cast<HDC>(static_cast<sal_IntPtr>(SendMessageW( pSalData->mpInstance->mhComWnd,
- SAL_MSG_GETDC,
- reinterpret_cast<WPARAM>(hWnd), 0 )));
- if ( hDC )
- {
- pThis->mpThreadGraphics->setHDC(hDC);
- if ( pSalData->mhDitherPal )
- {
- pThis->mpThreadGraphics->setDefPal(SelectPalette( hDC, pSalData->mhDitherPal, TRUE ));
- RealizePalette( hDC );
- }
- pThis->mpThreadGraphics->InitGraphics();
-
- // re-select saved gdi objects
- if( hFont )
- SelectObject( hDC, hFont );
- if( hPen )
- SelectObject( hDC, hPen );
- if( hBrush )
- SelectObject( hDC, hBrush );
-
- pThis->mbGraphics = TRUE;
-
- pSalData->mnCacheDCInUse++;
-
- SAL_WARN_IF( oldCount != pSalData->mnCacheDCInUse, "vcl", "WinSalFrame::SetParent() hDC count corrupted");
- }
- }
- }
-
- if( pThis->mpLocalGraphics )
+ HDC hDC = reinterpret_cast<HDC>(static_cast<sal_IntPtr>(
+ SendMessageW( pSalData->mpInstance->mhComWnd,
+ SAL_MSG_GETDC, reinterpret_cast<WPARAM>(hWnd), 0 )));
+ InitFrameGraphicsDC( mpThreadGraphics, hDC, hWnd );
+ if ( hDC )
{
- // re-create DC
- pThis->mpLocalGraphics->setHWND(hWnd);
- pThis->mpLocalGraphics->setHDC( GetDC( hWnd ) );
- if ( GetSalData()->mhDitherPal )
- {
- pThis->mpLocalGraphics->setDefPal(SelectPalette( pThis->mpLocalGraphics->getHDC(), GetSalData()->mhDitherPal, TRUE ));
- RealizePalette( pThis->mpLocalGraphics->getHDC() );
- }
- pThis->mpLocalGraphics->InitGraphics();
- pThis->mbGraphics = TRUE;
+ // re-select saved gdi objects
+ if( hFont )
+ SelectObject( hDC, hFont );
+ if( hPen )
+ SelectObject( hDC, hPen );
+ if( hBrush )
+ SelectObject( hDC, hBrush );
+
+ SAL_WARN_IF( oldCount != pSalData->mnCacheDCInUse, "vcl", "WinSalFrame::SetParent() hDC count corrupted");
}
}
+ // re-create local DC
+ if( bHadLocalGraphics )
+ InitFrameGraphicsDC( mpLocalGraphics, GetDC( hWnd ), hWnd );
+
// TODO: add SetParent() call for SalObjects
SAL_WARN_IF( !systemChildren.empty(), "vcl", "WinSalFrame::SetParent() parent of living system child window will be destroyed!");
// reparent children before old parent is destroyed
for (auto & child : children)
- ImplSetParentFrame( child, hWnd, false );
+ child->ImplSetParentFrame( hWnd, false );
children.clear();
systemChildren.clear();
@@ -1584,7 +1563,7 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, bool bAs
void WinSalFrame::SetParent( SalFrame* pNewParent )
{
WinSalFrame::mbInReparent = TRUE;
- ImplSetParentFrame( this, static_cast<WinSalFrame*>(pNewParent)->mhWnd, false );
+ ImplSetParentFrame( static_cast<WinSalFrame*>(pNewParent)->mhWnd, false );
WinSalFrame::mbInReparent = FALSE;
}
@@ -1596,7 +1575,7 @@ bool WinSalFrame::SetPluginParent( SystemParentData* pNewParent )
}
WinSalFrame::mbInReparent = TRUE;
- ImplSetParentFrame( this, pNewParent->hWnd, true );
+ ImplSetParentFrame( pNewParent->hWnd, true );
WinSalFrame::mbInReparent = FALSE;
return true;
}
@@ -3774,9 +3753,11 @@ static bool ImplHandlePaintMsg( HWND hWnd )
{
// clip region must be set, as we don't get a proper
// bounding rectangle otherwise
- bool bHasClipRegion = pFrame->mpLocalGraphics && pFrame->mpLocalGraphics->getRegion();
+ WinSalGraphics *pGraphics = pFrame->mpLocalGraphics;
+ bool bHasClipRegion = pGraphics &&
+ pGraphics->getHDC() && pGraphics->getRegion();
if ( bHasClipRegion )
- SelectClipRgn( pFrame->mpLocalGraphics->getHDC(), nullptr );
+ SelectClipRgn( pGraphics->getHDC(), nullptr );
// according to Windows documentation one shall check first if
// there really is a paint-region
@@ -3793,8 +3774,7 @@ static bool ImplHandlePaintMsg( HWND hWnd )
// reset clip region
if ( bHasClipRegion )
- SelectClipRgn( pFrame->mpLocalGraphics->getHDC(),
- pFrame->mpLocalGraphics->getRegion() );
+ SelectClipRgn( pGraphics->getHDC(), pGraphics->getRegion() );
// try painting
if ( bHasPaintRegion )
@@ -4098,7 +4078,7 @@ static void ImplHandleForcePalette( HWND hWnd )
if ( hPal )
{
WinSalFrame* pFrame = ProcessOrDeferMessage( hWnd, SAL_MSG_FORCEPALETTE );
- if ( pFrame && pFrame->mpLocalGraphics )
+ if ( pFrame && pFrame->mpLocalGraphics && pFrame->mpLocalGraphics->getHDC() )
{
WinSalGraphics* pGraphics = pFrame->mpLocalGraphics;
if ( pGraphics && pGraphics->getDefPal() )
@@ -4182,7 +4162,7 @@ static LRESULT ImplHandlePalette( bool bFrame, HWND hWnd, UINT nMsg,
while ( pTempFrame )
{
pGraphics = pTempFrame->mpLocalGraphics;
- if ( pGraphics && pGraphics->getDefPal() )
+ if ( pGraphics && pGraphics->getHDC() && pGraphics->getDefPal() )
{
SelectPalette( pGraphics->getHDC(),
pGraphics->getDefPal(),
@@ -4195,7 +4175,7 @@ static LRESULT ImplHandlePalette( bool bFrame, HWND hWnd, UINT nMsg,
WinSalFrame* pFrame = nullptr;
if ( bFrame )
pFrame = GetWindowPtr( hWnd );
- if ( pFrame && pFrame->mpLocalGraphics )
+ if ( pFrame && pFrame->mpLocalGraphics && pFrame->mpLocalGraphics->getHDC() )
{
hDC = pFrame->mpLocalGraphics->getHDC();
bStdDC = TRUE;
@@ -4233,7 +4213,7 @@ static LRESULT ImplHandlePalette( bool bFrame, HWND hWnd, UINT nMsg,
if ( pTempFrame != pFrame )
{
pGraphics = pTempFrame->mpLocalGraphics;
- if ( pGraphics && pGraphics->getDefPal() )
+ if ( pGraphics && pGraphics->getHDC() && pGraphics->getDefPal() )
{
SelectPalette( pGraphics->getHDC(), hPal, TRUE );
if ( RealizePalette( pGraphics->getHDC() ) )
@@ -4250,7 +4230,7 @@ static LRESULT ImplHandlePalette( bool bFrame, HWND hWnd, UINT nMsg,
while ( pTempFrame )
{
pGraphics = pTempFrame->mpLocalGraphics;
- if ( pGraphics && pGraphics->getDefPal() )
+ if ( pGraphics && pGraphics->getHDC() && pGraphics->getDefPal() )
{
InvalidateRect( pTempFrame->mhWnd, nullptr, FALSE );
UpdateWindow( pTempFrame->mhWnd );