xref: /trunk/main/vcl/unx/generic/dtrans/X11_clipboard.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 {
146     MutexGuard aGuard(m_rSelectionManager.getMutex());
147 
148     if( ! m_aContents.is() )
149         m_aContents = new X11Transferable( SelectionManager::get(), static_cast< OWeakObject* >(this), m_aSelection );
150     return m_aContents;
151 }
152 
153 // ------------------------------------------------------------------------
154 
setContents(const Reference<XTransferable> & xTrans,const Reference<XClipboardOwner> & xClipboardOwner)155 void SAL_CALL X11Clipboard::setContents(
156     const Reference< XTransferable >& xTrans,
157     const Reference< XClipboardOwner >& xClipboardOwner )
158 {
159     // remember old values for callbacks before setting the new ones.
160     ClearableMutexGuard aGuard(m_rSelectionManager.getMutex());
161 
162     Reference< XClipboardOwner > oldOwner( m_aOwner );
163     m_aOwner = xClipboardOwner;
164 
165     Reference< XTransferable > oldContents( m_aContents );
166     m_aContents = xTrans;
167 
168     aGuard.clear();
169 
170     // for now request ownership for both selections
171     if( m_aSelection != None )
172         m_rSelectionManager.requestOwnership( m_aSelection );
173     else
174     {
175         m_rSelectionManager.requestOwnership( XA_PRIMARY );
176         m_rSelectionManager.requestOwnership( m_rSelectionManager.getAtom( OUString::createFromAscii( "CLIPBOARD" ) ) );
177     }
178 
179     // notify old owner on loss of ownership
180     if( oldOwner.is() )
181         oldOwner->lostOwnership(static_cast < XClipboard * > (this), oldContents);
182 
183     // notify all listeners on content changes
184     fireChangedContentsEvent();
185 }
186 
187 // ------------------------------------------------------------------------
188 
getName()189 OUString SAL_CALL X11Clipboard::getName()
190 {
191     return m_rSelectionManager.getString( m_aSelection );
192 }
193 
194 // ------------------------------------------------------------------------
195 
getRenderingCapabilities()196 sal_Int8 SAL_CALL X11Clipboard::getRenderingCapabilities()
197 {
198     return RenderingCapabilities::Delayed;
199 }
200 
201 
202 // ------------------------------------------------------------------------
addClipboardListener(const Reference<XClipboardListener> & listener)203 void SAL_CALL X11Clipboard::addClipboardListener( const Reference< XClipboardListener >& listener )
204 {
205     MutexGuard aGuard( m_rSelectionManager.getMutex() );
206     m_aListeners.push_back( listener );
207 }
208 
209 // ------------------------------------------------------------------------
210 
removeClipboardListener(const Reference<XClipboardListener> & listener)211 void SAL_CALL X11Clipboard::removeClipboardListener( const Reference< XClipboardListener >& listener )
212 {
213     MutexGuard aGuard( m_rSelectionManager.getMutex() );
214     m_aListeners.remove( listener );
215 }
216 
217 
218 // ------------------------------------------------------------------------
219 
getTransferable()220 Reference< XTransferable > X11Clipboard::getTransferable()
221 {
222     return getContents();
223 }
224 
225 // ------------------------------------------------------------------------
226 
clearTransferable()227 void X11Clipboard::clearTransferable()
228 {
229     clearContents();
230 }
231 
232 // ------------------------------------------------------------------------
233 
fireContentsChanged()234 void X11Clipboard::fireContentsChanged()
235 {
236     fireChangedContentsEvent();
237 }
238 
239 // ------------------------------------------------------------------------
240 
getReference()241 Reference< XInterface > X11Clipboard::getReference() throw()
242 {
243     return Reference< XInterface >( static_cast< OWeakObject* >(this) );
244 }
245 
246 // ------------------------------------------------------------------------
247 
getImplementationName()248 OUString SAL_CALL X11Clipboard::getImplementationName(  )
249 {
250     return OUString::createFromAscii(X11_CLIPBOARD_IMPLEMENTATION_NAME);
251 }
252 
253 // ------------------------------------------------------------------------
254 
supportsService(const OUString & ServiceName)255 sal_Bool SAL_CALL X11Clipboard::supportsService( const OUString& ServiceName )
256 {
257     Sequence < OUString > SupportedServicesNames = X11Clipboard_getSupportedServiceNames();
258 
259     for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; )
260         if (SupportedServicesNames[n].compareTo(ServiceName) == 0)
261             return sal_True;
262 
263     return sal_False;
264 }
265 
266 // ------------------------------------------------------------------------
267 
initialize(const Sequence<Any> &)268 void SAL_CALL X11Clipboard::initialize( const Sequence< Any >& )
269 {
270 }
271 
272 // ------------------------------------------------------------------------
273 
getSupportedServiceNames()274 Sequence< OUString > SAL_CALL X11Clipboard::getSupportedServiceNames(    )
275 {
276     return X11Clipboard_getSupportedServiceNames();
277 }
278 
279 /* vim: set noet sw=4 ts=4: */
280