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
X11Clipboard(SelectionManager & rManager,Atom aSelection)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
~X11Clipboard()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
fireChangedContentsEvent()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
clearContents()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
getContents()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
setContents(const Reference<XTransferable> & xTrans,const Reference<XClipboardOwner> & xClipboardOwner)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
getName()193 OUString SAL_CALL X11Clipboard::getName()
194 throw(RuntimeException)
195 {
196 return m_rSelectionManager.getString( m_aSelection );
197 }
198
199 // ------------------------------------------------------------------------
200
getRenderingCapabilities()201 sal_Int8 SAL_CALL X11Clipboard::getRenderingCapabilities()
202 throw(RuntimeException)
203 {
204 return RenderingCapabilities::Delayed;
205 }
206
207
208 // ------------------------------------------------------------------------
addClipboardListener(const Reference<XClipboardListener> & listener)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
removeClipboardListener(const Reference<XClipboardListener> & listener)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
getTransferable()228 Reference< XTransferable > X11Clipboard::getTransferable()
229 {
230 return getContents();
231 }
232
233 // ------------------------------------------------------------------------
234
clearTransferable()235 void X11Clipboard::clearTransferable()
236 {
237 clearContents();
238 }
239
240 // ------------------------------------------------------------------------
241
fireContentsChanged()242 void X11Clipboard::fireContentsChanged()
243 {
244 fireChangedContentsEvent();
245 }
246
247 // ------------------------------------------------------------------------
248
getReference()249 Reference< XInterface > X11Clipboard::getReference() throw()
250 {
251 return Reference< XInterface >( static_cast< OWeakObject* >(this) );
252 }
253
254 // ------------------------------------------------------------------------
255
getImplementationName()256 OUString SAL_CALL X11Clipboard::getImplementationName( )
257 throw(RuntimeException)
258 {
259 return OUString::createFromAscii(X11_CLIPBOARD_IMPLEMENTATION_NAME);
260 }
261
262 // ------------------------------------------------------------------------
263
supportsService(const OUString & ServiceName)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
initialize(const Sequence<Any> &)278 void SAL_CALL X11Clipboard::initialize( const Sequence< Any >& ) throw( ::com::sun::star::uno::Exception )
279 {
280 }
281
282 // ------------------------------------------------------------------------
283
getSupportedServiceNames()284 Sequence< OUString > SAL_CALL X11Clipboard::getSupportedServiceNames( )
285 throw(RuntimeException)
286 {
287 return X11Clipboard_getSupportedServiceNames();
288 }
289
290