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