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