1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_vcl.hxx" 30 31 #include <X11/Xatom.h> 32 #include <X11_clipboard.hxx> 33 #include <X11_transferable.hxx> 34 #include <com/sun/star/lang/DisposedException.hpp> 35 #include <com/sun/star/datatransfer/clipboard/RenderingCapabilities.hpp> 36 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 37 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 38 #include <com/sun/star/registry/XRegistryKey.hpp> 39 #include <uno/dispatcher.h> // declaration of generic uno interface 40 #include <uno/mapping.hxx> // mapping stuff 41 #include <cppuhelper/factory.hxx> 42 #include <rtl/tencinfo.h> 43 44 #if OSL_DEBUG_LEVEL > 1 45 #include <stdio.h> 46 #endif 47 48 using namespace com::sun::star::datatransfer; 49 using namespace com::sun::star::datatransfer::clipboard; 50 using namespace com::sun::star::lang; 51 using namespace com::sun::star::uno; 52 using namespace com::sun::star::awt; 53 using namespace cppu; 54 using namespace osl; 55 using namespace rtl; 56 using namespace x11; 57 58 X11Clipboard::X11Clipboard( SelectionManager& rManager, Atom aSelection ) : 59 ::cppu::WeakComponentImplHelper4< 60 ::com::sun::star::datatransfer::clipboard::XClipboardEx, 61 ::com::sun::star::datatransfer::clipboard::XClipboardNotifier, 62 ::com::sun::star::lang::XServiceInfo, 63 ::com::sun::star::lang::XInitialization 64 >( rManager.getMutex() ), 65 66 m_rSelectionManager( rManager ), 67 m_xSelectionManager( & rManager ), 68 m_aSelection( aSelection ) 69 { 70 #if OSL_DEBUG_LEVEL > 1 71 fprintf( stderr, "creating instance of X11Clipboard (this=%p)\n", this ); 72 #endif 73 74 if( m_aSelection != None ) 75 { 76 m_rSelectionManager.registerHandler( m_aSelection, *this ); 77 } 78 else 79 { 80 m_rSelectionManager.registerHandler( XA_PRIMARY, *this ); 81 m_rSelectionManager.registerHandler( m_rSelectionManager.getAtom( OUString::createFromAscii( "CLIPBOARD" ) ), *this ); 82 } 83 } 84 85 // ------------------------------------------------------------------------ 86 87 X11Clipboard::~X11Clipboard() 88 { 89 MutexGuard aGuard( *Mutex::getGlobalMutex() ); 90 91 #if OSL_DEBUG_LEVEL > 1 92 fprintf( stderr, "shutting down instance of X11Clipboard (this=%p, Selecttion=\"%s\")\n", this, OUStringToOString( m_rSelectionManager.getString( m_aSelection ), RTL_TEXTENCODING_ISO_8859_1 ).getStr() ); 93 #endif 94 if( m_aSelection != None ) 95 m_rSelectionManager.deregisterHandler( m_aSelection ); 96 else 97 { 98 m_rSelectionManager.deregisterHandler( XA_PRIMARY ); 99 m_rSelectionManager.deregisterHandler( m_rSelectionManager.getAtom( OUString::createFromAscii( "CLIPBOARD" ) ) ); 100 } 101 } 102 103 104 // ------------------------------------------------------------------------ 105 106 void X11Clipboard::fireChangedContentsEvent() 107 { 108 ClearableMutexGuard aGuard( m_rSelectionManager.getMutex() ); 109 #if OSL_DEBUG_LEVEL > 1 110 fprintf( stderr, "X11Clipboard::fireChangedContentsEvent for %s (%d listeners)\n", 111 OUStringToOString( m_rSelectionManager.getString( m_aSelection ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(), m_aListeners.size() ); 112 #endif 113 ::std::list< Reference< XClipboardListener > > listeners( m_aListeners ); 114 aGuard.clear(); 115 116 ClipboardEvent aEvent( static_cast<OWeakObject*>(this), m_aContents); 117 while( listeners.begin() != listeners.end() ) 118 { 119 if( listeners.front().is() ) 120 listeners.front()->changedContents(aEvent); 121 listeners.pop_front(); 122 } 123 } 124 125 // ------------------------------------------------------------------------ 126 127 void X11Clipboard::clearContents() 128 { 129 ClearableMutexGuard aGuard(m_rSelectionManager.getMutex()); 130 // protect against deletion during outside call 131 Reference< XClipboard > xThis( static_cast<XClipboard*>(this)); 132 // copy member references on stack so they can be called 133 // without having the mutex 134 Reference< XClipboardOwner > xOwner( m_aOwner ); 135 Reference< XTransferable > xTrans( m_aContents ); 136 // clear members 137 m_aOwner.clear(); 138 m_aContents.clear(); 139 140 // release the mutex 141 aGuard.clear(); 142 143 // inform previous owner of lost ownership 144 if ( xOwner.is() ) 145 xOwner->lostOwnership(xThis, m_aContents); 146 } 147 148 // ------------------------------------------------------------------------ 149 150 Reference< XTransferable > SAL_CALL X11Clipboard::getContents() 151 throw(RuntimeException) 152 { 153 MutexGuard aGuard(m_rSelectionManager.getMutex()); 154 155 if( ! m_aContents.is() ) 156 m_aContents = new X11Transferable( SelectionManager::get(), static_cast< OWeakObject* >(this), m_aSelection ); 157 return m_aContents; 158 } 159 160 // ------------------------------------------------------------------------ 161 162 void SAL_CALL X11Clipboard::setContents( 163 const Reference< XTransferable >& xTrans, 164 const Reference< XClipboardOwner >& xClipboardOwner ) 165 throw(RuntimeException) 166 { 167 // remember old values for callbacks before setting the new ones. 168 ClearableMutexGuard aGuard(m_rSelectionManager.getMutex()); 169 170 Reference< XClipboardOwner > oldOwner( m_aOwner ); 171 m_aOwner = xClipboardOwner; 172 173 Reference< XTransferable > oldContents( m_aContents ); 174 m_aContents = xTrans; 175 176 aGuard.clear(); 177 178 // for now request ownership for both selections 179 if( m_aSelection != None ) 180 m_rSelectionManager.requestOwnership( m_aSelection ); 181 else 182 { 183 m_rSelectionManager.requestOwnership( XA_PRIMARY ); 184 m_rSelectionManager.requestOwnership( m_rSelectionManager.getAtom( OUString::createFromAscii( "CLIPBOARD" ) ) ); 185 } 186 187 // notify old owner on loss of ownership 188 if( oldOwner.is() ) 189 oldOwner->lostOwnership(static_cast < XClipboard * > (this), oldContents); 190 191 // notify all listeners on content changes 192 fireChangedContentsEvent(); 193 } 194 195 // ------------------------------------------------------------------------ 196 197 OUString SAL_CALL X11Clipboard::getName() 198 throw(RuntimeException) 199 { 200 return m_rSelectionManager.getString( m_aSelection ); 201 } 202 203 // ------------------------------------------------------------------------ 204 205 sal_Int8 SAL_CALL X11Clipboard::getRenderingCapabilities() 206 throw(RuntimeException) 207 { 208 return RenderingCapabilities::Delayed; 209 } 210 211 212 // ------------------------------------------------------------------------ 213 void SAL_CALL X11Clipboard::addClipboardListener( const Reference< XClipboardListener >& listener ) 214 throw(RuntimeException) 215 { 216 MutexGuard aGuard( m_rSelectionManager.getMutex() ); 217 m_aListeners.push_back( listener ); 218 } 219 220 // ------------------------------------------------------------------------ 221 222 void SAL_CALL X11Clipboard::removeClipboardListener( const Reference< XClipboardListener >& listener ) 223 throw(RuntimeException) 224 { 225 MutexGuard aGuard( m_rSelectionManager.getMutex() ); 226 m_aListeners.remove( listener ); 227 } 228 229 230 // ------------------------------------------------------------------------ 231 232 Reference< XTransferable > X11Clipboard::getTransferable() 233 { 234 return getContents(); 235 } 236 237 // ------------------------------------------------------------------------ 238 239 void X11Clipboard::clearTransferable() 240 { 241 clearContents(); 242 } 243 244 // ------------------------------------------------------------------------ 245 246 void X11Clipboard::fireContentsChanged() 247 { 248 fireChangedContentsEvent(); 249 } 250 251 // ------------------------------------------------------------------------ 252 253 Reference< XInterface > X11Clipboard::getReference() throw() 254 { 255 return Reference< XInterface >( static_cast< OWeakObject* >(this) ); 256 } 257 258 // ------------------------------------------------------------------------ 259 260 OUString SAL_CALL X11Clipboard::getImplementationName( ) 261 throw(RuntimeException) 262 { 263 return OUString::createFromAscii(X11_CLIPBOARD_IMPLEMENTATION_NAME); 264 } 265 266 // ------------------------------------------------------------------------ 267 268 sal_Bool SAL_CALL X11Clipboard::supportsService( const OUString& ServiceName ) 269 throw(RuntimeException) 270 { 271 Sequence < OUString > SupportedServicesNames = X11Clipboard_getSupportedServiceNames(); 272 273 for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; ) 274 if (SupportedServicesNames[n].compareTo(ServiceName) == 0) 275 return sal_True; 276 277 return sal_False; 278 } 279 280 // ------------------------------------------------------------------------ 281 282 void SAL_CALL X11Clipboard::initialize( const Sequence< Any >& ) throw( ::com::sun::star::uno::Exception ) 283 { 284 } 285 286 // ------------------------------------------------------------------------ 287 288 Sequence< OUString > SAL_CALL X11Clipboard::getSupportedServiceNames( ) 289 throw(RuntimeException) 290 { 291 return X11Clipboard_getSupportedServiceNames(); 292 } 293 294