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 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 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 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 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 176 OUString SAL_CALL CWinClipbImpl::getName( ) throw( RuntimeException ) 177 { 178 return m_itsName; 179 } 180 181 //------------------------------------------------------------------------ 182 // 183 //------------------------------------------------------------------------ 184 185 sal_Int8 SAL_CALL CWinClipbImpl::getRenderingCapabilities( ) throw( RuntimeException ) 186 { 187 return ( Delayed | Persistant ); 188 } 189 190 //------------------------------------------------------------------------ 191 // 192 //------------------------------------------------------------------------ 193 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 215 void SAL_CALL CWinClipbImpl::registerClipboardViewer( ) 216 { 217 m_MtaOleClipboard.registerClipViewer( CWinClipbImpl::onClipboardContentChanged ); 218 } 219 220 //------------------------------------------------------------------------ 221 // 222 //------------------------------------------------------------------------ 223 224 void SAL_CALL CWinClipbImpl::unregisterClipboardViewer( ) 225 { 226 m_MtaOleClipboard.registerClipViewer( NULL ); 227 } 228 229 //------------------------------------------------------------------------ 230 // 231 //------------------------------------------------------------------------ 232 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 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 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