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_vcl.hxx" 26 27 #include <X11/Xatom.h> 28 #include <X11_clipboard.hxx> 29 #include <X11_transferable.hxx> 30 #include <com/sun/star/lang/DisposedException.hpp> 31 #include <com/sun/star/datatransfer/clipboard/RenderingCapabilities.hpp> 32 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 33 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 34 #include <com/sun/star/registry/XRegistryKey.hpp> 35 #include <uno/dispatcher.h> // declaration of generic uno interface 36 #include <uno/mapping.hxx> // mapping stuff 37 #include <cppuhelper/factory.hxx> 38 #include <rtl/tencinfo.h> 39 40 #if OSL_DEBUG_LEVEL > 1 41 #include <stdio.h> 42 #endif 43 44 using namespace com::sun::star::datatransfer; 45 using namespace com::sun::star::datatransfer::clipboard; 46 using namespace com::sun::star::lang; 47 using namespace com::sun::star::uno; 48 using namespace com::sun::star::awt; 49 using namespace cppu; 50 using namespace osl; 51 using namespace rtl; 52 using namespace x11; 53 54 X11Clipboard::X11Clipboard( SelectionManager& rManager, Atom aSelection ) : 55 ::cppu::WeakComponentImplHelper4< 56 ::com::sun::star::datatransfer::clipboard::XClipboardEx, 57 ::com::sun::star::datatransfer::clipboard::XClipboardNotifier, 58 ::com::sun::star::lang::XServiceInfo, 59 ::com::sun::star::lang::XInitialization 60 >( rManager.getMutex() ), 61 62 m_rSelectionManager( rManager ), 63 m_xSelectionManager( & rManager ), 64 m_aSelection( aSelection ) 65 { 66 #if OSL_DEBUG_LEVEL > 1 67 fprintf( stderr, "creating instance of X11Clipboard (this=%p)\n", this ); 68 #endif 69 70 if( m_aSelection != None ) 71 { 72 m_rSelectionManager.registerHandler( m_aSelection, *this ); 73 } 74 else 75 { 76 m_rSelectionManager.registerHandler( XA_PRIMARY, *this ); 77 m_rSelectionManager.registerHandler( m_rSelectionManager.getAtom( OUString::createFromAscii( "CLIPBOARD" ) ), *this ); 78 } 79 } 80 81 // ------------------------------------------------------------------------ 82 83 X11Clipboard::~X11Clipboard() 84 { 85 MutexGuard aGuard( *Mutex::getGlobalMutex() ); 86 87 #if OSL_DEBUG_LEVEL > 1 88 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() ); 89 #endif 90 if( m_aSelection != None ) 91 m_rSelectionManager.deregisterHandler( m_aSelection ); 92 else 93 { 94 m_rSelectionManager.deregisterHandler( XA_PRIMARY ); 95 m_rSelectionManager.deregisterHandler( m_rSelectionManager.getAtom( OUString::createFromAscii( "CLIPBOARD" ) ) ); 96 } 97 } 98 99 100 // ------------------------------------------------------------------------ 101 102 void X11Clipboard::fireChangedContentsEvent() 103 { 104 ClearableMutexGuard aGuard( m_rSelectionManager.getMutex() ); 105 #if OSL_DEBUG_LEVEL > 1 106 fprintf( stderr, "X11Clipboard::fireChangedContentsEvent for %s (%d listeners)\n", 107 OUStringToOString( m_rSelectionManager.getString( m_aSelection ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(), m_aListeners.size() ); 108 #endif 109 ::std::list< Reference< XClipboardListener > > listeners( m_aListeners ); 110 aGuard.clear(); 111 112 ClipboardEvent aEvent( static_cast<OWeakObject*>(this), m_aContents); 113 while( listeners.begin() != listeners.end() ) 114 { 115 if( listeners.front().is() ) 116 listeners.front()->changedContents(aEvent); 117 listeners.pop_front(); 118 } 119 } 120 121 // ------------------------------------------------------------------------ 122 123 void X11Clipboard::clearContents() 124 { 125 ClearableMutexGuard aGuard(m_rSelectionManager.getMutex()); 126 // protect against deletion during outside call 127 Reference< XClipboard > xThis( static_cast<XClipboard*>(this)); 128 // copy member references on stack so they can be called 129 // without having the mutex 130 Reference< XClipboardOwner > xOwner( m_aOwner ); 131 Reference< XTransferable > xTrans( m_aContents ); 132 // clear members 133 m_aOwner.clear(); 134 m_aContents.clear(); 135 136 // release the mutex 137 aGuard.clear(); 138 139 // inform previous owner of lost ownership 140 if ( xOwner.is() ) 141 xOwner->lostOwnership(xThis, m_aContents); 142 } 143 144 // ------------------------------------------------------------------------ 145 146 Reference< XTransferable > SAL_CALL X11Clipboard::getContents() 147 throw(RuntimeException) 148 { 149 MutexGuard aGuard(m_rSelectionManager.getMutex()); 150 151 if( ! m_aContents.is() ) 152 m_aContents = new X11Transferable( SelectionManager::get(), static_cast< OWeakObject* >(this), m_aSelection ); 153 return m_aContents; 154 } 155 156 // ------------------------------------------------------------------------ 157 158 void SAL_CALL X11Clipboard::setContents( 159 const Reference< XTransferable >& xTrans, 160 const Reference< XClipboardOwner >& xClipboardOwner ) 161 throw(RuntimeException) 162 { 163 // remember old values for callbacks before setting the new ones. 164 ClearableMutexGuard aGuard(m_rSelectionManager.getMutex()); 165 166 Reference< XClipboardOwner > oldOwner( m_aOwner ); 167 m_aOwner = xClipboardOwner; 168 169 Reference< XTransferable > oldContents( m_aContents ); 170 m_aContents = xTrans; 171 172 aGuard.clear(); 173 174 // for now request ownership for both selections 175 if( m_aSelection != None ) 176 m_rSelectionManager.requestOwnership( m_aSelection ); 177 else 178 { 179 m_rSelectionManager.requestOwnership( XA_PRIMARY ); 180 m_rSelectionManager.requestOwnership( m_rSelectionManager.getAtom( OUString::createFromAscii( "CLIPBOARD" ) ) ); 181 } 182 183 // notify old owner on loss of ownership 184 if( oldOwner.is() ) 185 oldOwner->lostOwnership(static_cast < XClipboard * > (this), oldContents); 186 187 // notify all listeners on content changes 188 fireChangedContentsEvent(); 189 } 190 191 // ------------------------------------------------------------------------ 192 193 OUString SAL_CALL X11Clipboard::getName() 194 throw(RuntimeException) 195 { 196 return m_rSelectionManager.getString( m_aSelection ); 197 } 198 199 // ------------------------------------------------------------------------ 200 201 sal_Int8 SAL_CALL X11Clipboard::getRenderingCapabilities() 202 throw(RuntimeException) 203 { 204 return RenderingCapabilities::Delayed; 205 } 206 207 208 // ------------------------------------------------------------------------ 209 void SAL_CALL X11Clipboard::addClipboardListener( const Reference< XClipboardListener >& listener ) 210 throw(RuntimeException) 211 { 212 MutexGuard aGuard( m_rSelectionManager.getMutex() ); 213 m_aListeners.push_back( listener ); 214 } 215 216 // ------------------------------------------------------------------------ 217 218 void SAL_CALL X11Clipboard::removeClipboardListener( const Reference< XClipboardListener >& listener ) 219 throw(RuntimeException) 220 { 221 MutexGuard aGuard( m_rSelectionManager.getMutex() ); 222 m_aListeners.remove( listener ); 223 } 224 225 226 // ------------------------------------------------------------------------ 227 228 Reference< XTransferable > X11Clipboard::getTransferable() 229 { 230 return getContents(); 231 } 232 233 // ------------------------------------------------------------------------ 234 235 void X11Clipboard::clearTransferable() 236 { 237 clearContents(); 238 } 239 240 // ------------------------------------------------------------------------ 241 242 void X11Clipboard::fireContentsChanged() 243 { 244 fireChangedContentsEvent(); 245 } 246 247 // ------------------------------------------------------------------------ 248 249 Reference< XInterface > X11Clipboard::getReference() throw() 250 { 251 return Reference< XInterface >( static_cast< OWeakObject* >(this) ); 252 } 253 254 // ------------------------------------------------------------------------ 255 256 OUString SAL_CALL X11Clipboard::getImplementationName( ) 257 throw(RuntimeException) 258 { 259 return OUString::createFromAscii(X11_CLIPBOARD_IMPLEMENTATION_NAME); 260 } 261 262 // ------------------------------------------------------------------------ 263 264 sal_Bool SAL_CALL X11Clipboard::supportsService( const OUString& ServiceName ) 265 throw(RuntimeException) 266 { 267 Sequence < OUString > SupportedServicesNames = X11Clipboard_getSupportedServiceNames(); 268 269 for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; ) 270 if (SupportedServicesNames[n].compareTo(ServiceName) == 0) 271 return sal_True; 272 273 return sal_False; 274 } 275 276 // ------------------------------------------------------------------------ 277 278 void SAL_CALL X11Clipboard::initialize( const Sequence< Any >& ) throw( ::com::sun::star::uno::Exception ) 279 { 280 } 281 282 // ------------------------------------------------------------------------ 283 284 Sequence< OUString > SAL_CALL X11Clipboard::getSupportedServiceNames( ) 285 throw(RuntimeException) 286 { 287 return X11Clipboard_getSupportedServiceNames(); 288 } 289 290