xref: /AOO41X/main/dtrans/source/win32/clipb/WinClipbImpl.cxx (revision 48123e16153c92857455f9e7a0d17cc19307983f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dtrans.hxx"
26 
27 //------------------------------------------------------------------------
28 // includes
29 //------------------------------------------------------------------------
30 #include <osl/diagnose.h>
31 #include "WinClipbImpl.hxx"
32 
33 #include <systools/win32/comtools.hxx>
34 #include "..\..\inc\DtObjFactory.hxx"
35 #include "..\dtobj\APNDataObject.hxx"
36 #include "WinClipboard.hxx"
37 #include <com/sun/star/datatransfer/clipboard/RenderingCapabilities.hpp>
38 #include "..\dtobj\XNotifyingDataObject.hxx"
39 
40 #if defined _MSC_VER
41 #pragma warning(push,1)
42 #endif
43 #include <windows.h>
44 #include <ole2.h>
45 #include <objidl.h>
46 #if defined _MSC_VER
47 #pragma warning(pop)
48 #endif
49 
50 //------------------------------------------------------------------------
51 // namespace directives
52 //------------------------------------------------------------------------
53 
54 using namespace rtl;
55 using namespace osl;
56 using namespace std;
57 using namespace cppu;
58 
59 using namespace com::sun::star::uno;
60 using namespace com::sun::star::datatransfer;
61 using namespace com::sun::star::datatransfer::clipboard;
62 using namespace com::sun::star::datatransfer::clipboard::RenderingCapabilities;
63 
64 //------------------------------------------------------------------------
65 // deklarations
66 //------------------------------------------------------------------------
67 
68 // definition of static members
69 CWinClipbImpl* CWinClipbImpl::s_pCWinClipbImpl = NULL;
70 osl::Mutex     CWinClipbImpl::s_aMutex;
71 
72 //------------------------------------------------------------------------
73 //
74 //------------------------------------------------------------------------
75 
CWinClipbImpl(const OUString & aClipboardName,CWinClipboard * theWinClipboard)76 CWinClipbImpl::CWinClipbImpl( const OUString& aClipboardName, CWinClipboard* theWinClipboard ) :
77     m_itsName( aClipboardName ),
78     m_pWinClipboard( theWinClipboard ),
79     m_pCurrentClipContent( NULL )
80 {
81     OSL_ASSERT( NULL != m_pWinClipboard );
82 
83     // necessary to reassociate from
84     // the static callback function
85     s_pCWinClipbImpl = this;
86     registerClipboardViewer( );
87 }
88 
89 //------------------------------------------------------------------------
90 //
91 //------------------------------------------------------------------------
92 
~CWinClipbImpl()93 CWinClipbImpl::~CWinClipbImpl( )
94 {
95     ClearableMutexGuard aGuard( s_aMutex );
96     s_pCWinClipbImpl = NULL;
97     aGuard.clear( );
98 
99     unregisterClipboardViewer( );
100 }
101 
102 //------------------------------------------------------------------------
103 // getContent
104 //------------------------------------------------------------------------
105 
getContents()106 Reference< XTransferable > SAL_CALL CWinClipbImpl::getContents( ) throw( RuntimeException )
107 {
108     // use the shotcut or create a transferable from
109     // system clipboard
110     ClearableMutexGuard aGuard( m_ClipContentMutex );
111 
112     if ( NULL != m_pCurrentClipContent )
113     {
114         return m_pCurrentClipContent->m_XTransferable;
115     }
116 
117     // release the mutex, so that the variable may be
118     // changed by other threads
119     aGuard.clear( );
120 
121     Reference< XTransferable > rClipContent;
122 
123     // get the current dataobject from clipboard
124     IDataObjectPtr pIDataObject;
125     HRESULT hr = m_MtaOleClipboard.getClipboard( &pIDataObject );
126 
127     if ( SUCCEEDED( hr ) )
128     {
129         // create an apartment neutral dataobject and initialize it with a
130         // com smart pointer to the IDataObject from clipboard
131         IDataObjectPtr pIDo( new CAPNDataObject( pIDataObject ) );
132 
133         CDTransObjFactory objFactory;
134 
135         // remeber pIDo destroys itself due to the smart pointer
136         rClipContent = objFactory.createTransferableFromDataObj( m_pWinClipboard->m_SrvMgr, pIDo );
137     }
138 
139     return rClipContent;
140 }
141 
142 //------------------------------------------------------------------------
143 // setContent
144 //------------------------------------------------------------------------
145 
setContents(const Reference<XTransferable> & xTransferable,const Reference<XClipboardOwner> & xClipboardOwner)146 void SAL_CALL CWinClipbImpl::setContents(
147     const Reference< XTransferable >& xTransferable,
148     const Reference< XClipboardOwner >& xClipboardOwner )
149     throw( RuntimeException )
150 {
151     CDTransObjFactory objFactory;
152     IDataObjectPtr    pIDataObj;
153 
154     if ( xTransferable.is( ) )
155     {
156         ClearableMutexGuard aGuard( m_ClipContentMutex );
157 
158         m_pCurrentClipContent = new CXNotifyingDataObject(
159             objFactory.createDataObjFromTransferable( m_pWinClipboard->m_SrvMgr , xTransferable ),
160             xTransferable,
161             xClipboardOwner,
162             this );
163 
164         aGuard.clear( );
165 
166         pIDataObj = IDataObjectPtr( m_pCurrentClipContent );
167     }
168 
169     m_MtaOleClipboard.setClipboard(pIDataObj.get());
170 }
171 
172 //------------------------------------------------------------------------
173 //
174 //------------------------------------------------------------------------
175 
getName()176 OUString SAL_CALL CWinClipbImpl::getName(  ) throw( RuntimeException )
177 {
178     return m_itsName;
179 }
180 
181 //------------------------------------------------------------------------
182 //
183 //------------------------------------------------------------------------
184 
getRenderingCapabilities()185 sal_Int8 SAL_CALL CWinClipbImpl::getRenderingCapabilities(  ) throw( RuntimeException )
186 {
187     return ( Delayed | Persistant );
188 }
189 
190 //------------------------------------------------------------------------
191 //
192 //------------------------------------------------------------------------
193 
flushClipboard()194 void SAL_CALL CWinClipbImpl::flushClipboard( ) throw( RuntimeException )
195 {
196     // sollte eigentlich hier stehen: ClearableMutexGuard aGuard( m_ClipContentMutex );
197     // geht aber nicht, da FlushClipboard zur�ckruft und das DataObject
198     // freigibt und damit w�rde es einen Deadlock in onReleaseDataObject geben
199     // FlushClipboard mu� synchron sein, damit das runterfahren ggf. erst weitergeht,
200     // wenn alle Clipboard-Formate gerendert wurden
201     // die Abfrage ist n�tig, damit nur geflusht wird, wenn wir wirklich Clipboardowner
202     // sind (ich weiss nicht genau was passiert, wenn man flusht und nicht Clipboard
203     // owner ist).
204     // eventuell kann man aber die Abfrage in den Clipboard STA Thread verlagern, indem
205     // man sich dort das DataObject merkt und vor dem flushen OleIsCurrentClipboard ruft
206 
207     if ( NULL != m_pCurrentClipContent )
208         m_MtaOleClipboard.flushClipboard( );
209 }
210 
211 //------------------------------------------------------------------------
212 //
213 //------------------------------------------------------------------------
214 
registerClipboardViewer()215 void SAL_CALL CWinClipbImpl::registerClipboardViewer( )
216 {
217     m_MtaOleClipboard.registerClipViewer( CWinClipbImpl::onClipboardContentChanged );
218 }
219 
220 //------------------------------------------------------------------------
221 //
222 //------------------------------------------------------------------------
223 
unregisterClipboardViewer()224 void SAL_CALL CWinClipbImpl::unregisterClipboardViewer( )
225 {
226     m_MtaOleClipboard.registerClipViewer( NULL );
227 }
228 
229 //------------------------------------------------------------------------
230 //
231 //------------------------------------------------------------------------
232 
dispose()233 void SAL_CALL CWinClipbImpl::dispose() throw( RuntimeException )
234 {
235     OSL_ENSURE( !m_pCurrentClipContent, "Clipboard was not flushed before shutdown!" );
236 }
237 
238 //------------------------------------------------------------------------
239 //
240 //------------------------------------------------------------------------
241 
onClipboardContentChanged(void)242 void WINAPI CWinClipbImpl::onClipboardContentChanged( void )
243 {
244     MutexGuard aGuard( s_aMutex );
245 
246     // reassocition to instance through static member
247     if ( NULL != s_pCWinClipbImpl )
248         s_pCWinClipbImpl->m_pWinClipboard->notifyAllClipboardListener( );
249 }
250 
251 //------------------------------------------------------------------------
252 //
253 //------------------------------------------------------------------------
254 
onReleaseDataObject(CXNotifyingDataObject * theCaller)255 void SAL_CALL CWinClipbImpl::onReleaseDataObject( CXNotifyingDataObject* theCaller )
256 {
257     OSL_ASSERT( NULL != theCaller );
258 
259     if ( theCaller )
260         theCaller->lostOwnership( );
261 
262     // if the current caller is the one we currently
263     // hold, then set it to NULL because an external
264     // source must be the clipboardowner now
265     MutexGuard aGuard( m_ClipContentMutex );
266 
267     if ( m_pCurrentClipContent == theCaller )
268         m_pCurrentClipContent = NULL;
269 }
270