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