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