xref: /AOO42X/main/vcl/unx/generic/dtrans/X11_clipboard.cxx (revision ea466eed2d689e648be51acebc1d7041c643cc2f)
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