fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / dtrans / source / win32 / dtobj / APNDataObject.cxx
blob4de3f3e579c7cbbd546b950196f74703e26bce21
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "APNDataObject.hxx"
21 #include <osl/diagnose.h>
23 #include <systools/win32/comtools.hxx>
24 #ifdef __MINGW32__
25 #if defined __uuidof
26 #undef __uuidof
27 #endif
28 #define __uuidof(I) IID_##I
29 #endif
31 #define FREE_HGLOB_ON_RELEASE TRUE
32 #define KEEP_HGLOB_ON_RELEASE FALSE
34 // ctor
36 CAPNDataObject::CAPNDataObject( IDataObjectPtr rIDataObject ) :
37 m_rIDataObjectOrg( rIDataObject ),
38 m_hGlobal( NULL ),
39 m_nRefCnt( 0 )
42 OSL_ENSURE( m_rIDataObjectOrg.get( ), "constructing CAPNDataObject with empty data object" );
44 // we marshal the IDataObject interface pointer here so
45 // that it can be unmarshaled multiple times when this
46 // class will be used from another apartment
47 IStreamPtr pStm;
48 HRESULT hr = CreateStreamOnHGlobal( 0, KEEP_HGLOB_ON_RELEASE, &pStm );
50 OSL_ENSURE( E_INVALIDARG != hr, "invalid args passed to CreateStreamOnHGlobal" );
52 if ( SUCCEEDED( hr ) )
54 HRESULT hr_marshal = CoMarshalInterface(
55 pStm.get(),
56 __uuidof(IDataObject),
57 static_cast<LPUNKNOWN>(m_rIDataObjectOrg.get()),
58 MSHCTX_LOCAL,
59 NULL,
60 MSHLFLAGS_TABLEWEAK );
62 OSL_ENSURE( CO_E_NOTINITIALIZED != hr_marshal, "COM is not initialized" );
64 // marshalling may fail if COM is not initialized
65 // for the calling thread which is a program time
66 // error or because of stream errors which are runtime
67 // errors for instance E_OUTOFMEMORY etc.
69 hr = GetHGlobalFromStream(pStm.get(), &m_hGlobal );
71 OSL_ENSURE( E_INVALIDARG != hr, "invalid stream passed to GetHGlobalFromStream" );
73 // if the marshalling failed we free the
74 // global memory again and set m_hGlobal
75 // to a defined value
76 if (FAILED(hr_marshal))
78 OSL_FAIL("marshalling failed");
80 #if OSL_DEBUG_LEVEL > 0
81 HGLOBAL hGlobal =
82 #endif
83 GlobalFree(m_hGlobal);
84 OSL_ENSURE(NULL == hGlobal, "GlobalFree failed");
85 m_hGlobal = NULL;
90 CAPNDataObject::~CAPNDataObject( )
92 if (m_hGlobal)
94 IStreamPtr pStm;
95 HRESULT hr = CreateStreamOnHGlobal(m_hGlobal, FREE_HGLOB_ON_RELEASE, &pStm);
97 OSL_ENSURE( E_INVALIDARG != hr, "invalid args passed to CreateStreamOnHGlobal" );
99 if (SUCCEEDED(hr))
101 hr = CoReleaseMarshalData(pStm.get());
102 OSL_ENSURE(SUCCEEDED(hr), "CoReleaseMarshalData failed");
107 // IUnknown->QueryInterface
109 STDMETHODIMP CAPNDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
111 OSL_ASSERT( NULL != ppvObject );
113 if ( NULL == ppvObject )
114 return E_INVALIDARG;
116 HRESULT hr = E_NOINTERFACE;
117 *ppvObject = NULL;
119 if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) )
121 *ppvObject = static_cast< IUnknown* >( this );
122 ( (LPUNKNOWN)*ppvObject )->AddRef( );
123 hr = S_OK;
126 return hr;
129 // IUnknown->AddRef
131 STDMETHODIMP_(ULONG) CAPNDataObject::AddRef( )
133 return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
136 // IUnknown->Release
138 STDMETHODIMP_(ULONG) CAPNDataObject::Release( )
140 // we need a helper variable because it's not allowed to access
141 // a member variable after an object is destroyed
142 ULONG nRefCnt = static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
144 if ( 0 == nRefCnt )
145 delete this;
147 return nRefCnt;
150 // IDataObject->GetData
152 STDMETHODIMP CAPNDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
154 HRESULT hr = m_rIDataObjectOrg->GetData( pFormatetc, pmedium );
156 if (RPC_E_WRONG_THREAD == hr)
158 IDataObjectPtr pIDOTmp;
159 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
161 if (SUCCEEDED(hr))
162 hr = pIDOTmp->GetData(pFormatetc, pmedium);
164 return hr;
167 // IDataObject->EnumFormatEtc
169 STDMETHODIMP CAPNDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
171 HRESULT hr = m_rIDataObjectOrg->EnumFormatEtc(dwDirection, ppenumFormatetc);
173 if (RPC_E_WRONG_THREAD == hr)
175 IDataObjectPtr pIDOTmp;
176 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
178 if (SUCCEEDED(hr))
179 hr = pIDOTmp->EnumFormatEtc(dwDirection, ppenumFormatetc);
181 return hr;
184 // IDataObject->QueryGetData
186 STDMETHODIMP CAPNDataObject::QueryGetData( LPFORMATETC pFormatetc )
188 HRESULT hr = m_rIDataObjectOrg->QueryGetData( pFormatetc );
190 if (RPC_E_WRONG_THREAD == hr)
192 IDataObjectPtr pIDOTmp;
193 hr = MarshalIDataObjectIntoCurrentApartment( &pIDOTmp );
195 if (SUCCEEDED(hr))
196 hr = pIDOTmp->QueryGetData(pFormatetc);
198 return hr;
201 // IDataObject->GetDataHere
203 STDMETHODIMP CAPNDataObject::GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
205 HRESULT hr = m_rIDataObjectOrg->GetDataHere(pFormatetc, pmedium);
207 if (RPC_E_WRONG_THREAD == hr)
209 IDataObjectPtr pIDOTmp;
210 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
212 if (SUCCEEDED(hr))
213 hr = pIDOTmp->GetDataHere(pFormatetc, pmedium);
215 return hr;
218 // IDataObject->GetCanonicalFormatEtc
220 STDMETHODIMP CAPNDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut)
222 HRESULT hr = m_rIDataObjectOrg->GetCanonicalFormatEtc( pFormatectIn, pFormatetcOut );
224 if (RPC_E_WRONG_THREAD == hr)
226 IDataObjectPtr pIDOTmp;
227 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
229 if (SUCCEEDED(hr))
230 hr = pIDOTmp->GetCanonicalFormatEtc(pFormatectIn, pFormatetcOut);
232 return hr;
235 // IDataObject->SetData
237 STDMETHODIMP CAPNDataObject::SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease )
239 HRESULT hr = m_rIDataObjectOrg->SetData( pFormatetc, pmedium, fRelease );
241 if (RPC_E_WRONG_THREAD == hr)
243 IDataObjectPtr pIDOTmp;
244 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
246 if (SUCCEEDED(hr))
247 hr = pIDOTmp->SetData(pFormatetc, pmedium, fRelease);
249 return hr;
252 // IDataObject->DAdvise
254 STDMETHODIMP CAPNDataObject::DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD * pdwConnection )
256 HRESULT hr = m_rIDataObjectOrg->DAdvise(pFormatetc, advf, pAdvSink, pdwConnection);
258 if (RPC_E_WRONG_THREAD == hr)
260 IDataObjectPtr pIDOTmp;
261 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
263 if (SUCCEEDED(hr))
264 hr = pIDOTmp->DAdvise(pFormatetc, advf, pAdvSink, pdwConnection);
266 return hr;
269 // IDataObject->DUnadvise
271 STDMETHODIMP CAPNDataObject::DUnadvise( DWORD dwConnection )
273 HRESULT hr = m_rIDataObjectOrg->DUnadvise( dwConnection );
275 if (RPC_E_WRONG_THREAD == hr)
277 IDataObjectPtr pIDOTmp;
278 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
280 if (SUCCEEDED(hr))
281 hr = pIDOTmp->DUnadvise(dwConnection);
283 return hr;
286 // IDataObject->EnumDAdvise
288 STDMETHODIMP CAPNDataObject::EnumDAdvise( LPENUMSTATDATA * ppenumAdvise )
290 HRESULT hr = m_rIDataObjectOrg->EnumDAdvise(ppenumAdvise);
292 if (RPC_E_WRONG_THREAD == hr)
294 IDataObjectPtr pIDOTmp;
295 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
297 if (SUCCEEDED(hr))
298 hr = pIDOTmp->EnumDAdvise(ppenumAdvise);
300 return hr;
303 // for our convenience
305 CAPNDataObject::operator IDataObject*( )
307 return static_cast< IDataObject* >( this );
310 // helper function
312 HRESULT CAPNDataObject::MarshalIDataObjectIntoCurrentApartment( IDataObject** ppIDataObj )
314 OSL_ASSERT(NULL != ppIDataObj);
316 *ppIDataObj = NULL;
317 HRESULT hr = E_FAIL;
319 if (m_hGlobal)
321 IStreamPtr pStm;
322 hr = CreateStreamOnHGlobal(m_hGlobal, KEEP_HGLOB_ON_RELEASE, &pStm);
324 OSL_ENSURE(E_INVALIDARG != hr, "CreateStreamOnHGlobal with invalid args called");
326 if (SUCCEEDED(hr))
328 hr = CoUnmarshalInterface(pStm.get(), __uuidof(IDataObject), (void**)ppIDataObj);
329 OSL_ENSURE(CO_E_NOTINITIALIZED != hr, "COM is not initialized");
332 return hr;
335 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */