1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <osl/diagnose.h>
21 #include <comphelper/diagnose_ex.hxx>
22 #include "XNotifyingDataObject.hxx"
23 #include "WinClipboard.hxx"
25 using namespace com::sun::star::datatransfer
;
26 using namespace com::sun::star::datatransfer::clipboard
;
27 using com::sun::star::uno::RuntimeException
;
28 using com::sun::star::uno::Reference
;
30 CXNotifyingDataObject::CXNotifyingDataObject(
31 const IDataObjectPtr
& aIDataObject
,
32 const Reference
< XTransferable
>& aXTransferable
,
33 const Reference
< XClipboardOwner
>& aXClipOwner
,
34 CWinClipboard
* const theWinClipoard
) :
36 m_aIDataObject( aIDataObject
),
37 m_XTransferable( aXTransferable
),
38 m_XClipboardOwner( aXClipOwner
),
39 m_pWinClipImpl( theWinClipoard
)
43 CXNotifyingDataObject::~CXNotifyingDataObject()
45 if (auto pWinClipImpl
= m_pWinClipImpl
.get())
46 pWinClipImpl
->onReleaseDataObject(*this);
49 STDMETHODIMP
CXNotifyingDataObject::QueryInterface( REFIID iid
, void** ppvObject
)
51 if ( nullptr == ppvObject
)
54 HRESULT hr
= E_NOINTERFACE
;
57 if ( ( __uuidof( IUnknown
) == iid
) ||
58 ( __uuidof( IDataObject
) == iid
) )
60 *ppvObject
= static_cast< IUnknown
* >( this );
61 static_cast<LPUNKNOWN
>(*ppvObject
)->AddRef( );
68 STDMETHODIMP_(ULONG
) CXNotifyingDataObject::AddRef( )
70 return static_cast< ULONG
>( InterlockedIncrement( &m_nRefCnt
) );
75 // delete CXNotifyingDataObject is a dedicated thread. It calls CWinClipboard::onReleaseDataObject,
76 // which may lock solar mutex, and if called in CMtaOleClipboard::run() thread, may deadlock.
77 unsigned __stdcall
releaseAsyncProc(void* p
)
79 delete static_cast<CXNotifyingDataObject
*>(p
);
84 STDMETHODIMP_(ULONG
) CXNotifyingDataObject::Release( )
87 static_cast< ULONG
>( InterlockedDecrement( &m_nRefCnt
) );
91 auto handle
= _beginthreadex(nullptr, 0, releaseAsyncProc
, this, 0, nullptr);
93 CloseHandle(reinterpret_cast<HANDLE
>(handle
));
99 STDMETHODIMP
CXNotifyingDataObject::GetData( FORMATETC
* pFormatetc
, STGMEDIUM
* pmedium
)
101 return m_aIDataObject
->GetData(pFormatetc
, pmedium
);
104 STDMETHODIMP
CXNotifyingDataObject::EnumFormatEtc(
105 DWORD dwDirection
, IEnumFORMATETC
** ppenumFormatetc
)
107 return m_aIDataObject
->EnumFormatEtc(dwDirection
, ppenumFormatetc
);
110 STDMETHODIMP
CXNotifyingDataObject::QueryGetData( FORMATETC
* pFormatetc
)
112 return m_aIDataObject
->QueryGetData(pFormatetc
);
115 STDMETHODIMP
CXNotifyingDataObject::GetDataHere( FORMATETC
* lpFetc
, STGMEDIUM
* lpStgMedium
)
117 return m_aIDataObject
->GetDataHere(lpFetc
, lpStgMedium
);
120 STDMETHODIMP
CXNotifyingDataObject::GetCanonicalFormatEtc( FORMATETC
* lpFetc
, FORMATETC
* lpCanonicalFetc
)
122 return m_aIDataObject
->GetCanonicalFormatEtc(lpFetc
, lpCanonicalFetc
);
125 STDMETHODIMP
CXNotifyingDataObject::SetData( FORMATETC
* lpFetc
, STGMEDIUM
* lpStgMedium
, BOOL bRelease
)
127 return m_aIDataObject
->SetData( lpFetc
, lpStgMedium
, bRelease
);
130 STDMETHODIMP
CXNotifyingDataObject::DAdvise(
131 FORMATETC
* lpFetc
, DWORD advf
, IAdviseSink
* lpAdvSink
, DWORD
* pdwConnection
)
133 return m_aIDataObject
->DAdvise( lpFetc
, advf
, lpAdvSink
, pdwConnection
);
136 STDMETHODIMP
CXNotifyingDataObject::DUnadvise( DWORD dwConnection
)
138 return m_aIDataObject
->DUnadvise( dwConnection
);
141 STDMETHODIMP
CXNotifyingDataObject::EnumDAdvise( IEnumSTATDATA
** ppenumAdvise
)
143 return m_aIDataObject
->EnumDAdvise( ppenumAdvise
);
146 CXNotifyingDataObject::operator IDataObject
*( )
148 return static_cast< IDataObject
* >( this );
151 void CXNotifyingDataObject::lostOwnership( )
155 if (m_XClipboardOwner
.is())
156 m_XClipboardOwner
->lostOwnership(m_pWinClipImpl
.get(), m_XTransferable
);
158 catch(RuntimeException
&)
160 TOOLS_WARN_EXCEPTION( "vcl", "" );
164 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */