xref: /trunk/main/dtrans/source/win32/clipb/WinClipbImpl.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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( )
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         // remember 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 {
150     CDTransObjFactory objFactory;
151     IDataObjectPtr    pIDataObj;
152 
153     if ( xTransferable.is( ) )
154     {
155         ClearableMutexGuard aGuard( m_ClipContentMutex );
156 
157         m_pCurrentClipContent = new CXNotifyingDataObject(
158             objFactory.createDataObjFromTransferable( m_pWinClipboard->m_SrvMgr , xTransferable ),
159             xTransferable,
160             xClipboardOwner,
161             this );
162 
163         aGuard.clear( );
164 
165         pIDataObj = IDataObjectPtr( m_pCurrentClipContent );
166     }
167 
168     m_MtaOleClipboard.setClipboard(pIDataObj.get());
169 }
170 
171 //------------------------------------------------------------------------
172 //
173 //------------------------------------------------------------------------
174 
getName()175 OUString SAL_CALL CWinClipbImpl::getName(  )
176 {
177     return m_itsName;
178 }
179 
180 //------------------------------------------------------------------------
181 //
182 //------------------------------------------------------------------------
183 
getRenderingCapabilities()184 sal_Int8 SAL_CALL CWinClipbImpl::getRenderingCapabilities(  )
185 {
186     return ( Delayed | Persistant );
187 }
188 
189 //------------------------------------------------------------------------
190 //
191 //------------------------------------------------------------------------
192 
flushClipboard()193 void SAL_CALL CWinClipbImpl::flushClipboard( )
194 {
195     // sollte eigentlich hier stehen: ClearableMutexGuard aGuard( m_ClipContentMutex );
196     // geht aber nicht, da FlushClipboard zur�ckruft und das DataObject
197     // freigibt und damit w�rde es einen Deadlock in onReleaseDataObject geben
198     // FlushClipboard mu� synchron sein, damit das runterfahren ggf. erst weitergeht,
199     // wenn alle Clipboard-Formate gerendert wurden
200     // die Abfrage ist n�tig, damit nur geflusht wird, wenn wir wirklich Clipboardowner
201     // sind (ich weiss nicht genau was passiert, wenn man flusht und nicht Clipboard
202     // owner ist).
203     // eventuell kann man aber die Abfrage in den Clipboard STA Thread verlagern, indem
204     // man sich dort das DataObject merkt und vor dem flushen OleIsCurrentClipboard ruft
205 
206     if ( NULL != m_pCurrentClipContent )
207         m_MtaOleClipboard.flushClipboard( );
208 }
209 
210 //------------------------------------------------------------------------
211 //
212 //------------------------------------------------------------------------
213 
registerClipboardViewer()214 void SAL_CALL CWinClipbImpl::registerClipboardViewer( )
215 {
216     m_MtaOleClipboard.registerClipViewer( CWinClipbImpl::onClipboardContentChanged );
217 }
218 
219 //------------------------------------------------------------------------
220 //
221 //------------------------------------------------------------------------
222 
unregisterClipboardViewer()223 void SAL_CALL CWinClipbImpl::unregisterClipboardViewer( )
224 {
225     m_MtaOleClipboard.registerClipViewer( NULL );
226 }
227 
228 //------------------------------------------------------------------------
229 //
230 //------------------------------------------------------------------------
231 
dispose()232 void SAL_CALL CWinClipbImpl::dispose()
233 {
234     OSL_ENSURE( !m_pCurrentClipContent, "Clipboard was not flushed before shutdown!" );
235 }
236 
237 //------------------------------------------------------------------------
238 //
239 //------------------------------------------------------------------------
240 
onClipboardContentChanged(void)241 void WINAPI CWinClipbImpl::onClipboardContentChanged( void )
242 {
243     MutexGuard aGuard( s_aMutex );
244 
245     // reassocition to instance through static member
246     if ( NULL != s_pCWinClipbImpl )
247         s_pCWinClipbImpl->m_pWinClipboard->notifyAllClipboardListener( );
248 }
249 
250 //------------------------------------------------------------------------
251 //
252 //------------------------------------------------------------------------
253 
onReleaseDataObject(CXNotifyingDataObject * theCaller)254 void SAL_CALL CWinClipbImpl::onReleaseDataObject( CXNotifyingDataObject* theCaller )
255 {
256     OSL_ASSERT( NULL != theCaller );
257 
258     if ( theCaller )
259         theCaller->lostOwnership( );
260 
261     // if the current caller is the one we currently
262     // hold, then set it to NULL because an external
263     // source must be the clipboardowner now
264     MutexGuard aGuard( m_ClipContentMutex );
265 
266     if ( m_pCurrentClipContent == theCaller )
267         m_pCurrentClipContent = NULL;
268 }
269