LibreOffice Module vcl (master)  1
dtranscomp.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <comphelper/lok.hxx>
23 #include <osl/mutex.hxx>
24 #include <tools/debug.hxx>
25 #include <vcl/svapp.hxx>
26 
27 #include <factory.hxx>
28 #include <svdata.hxx>
29 #include <salinst.hxx>
30 
31 #include <com/sun/star/lang/IllegalArgumentException.hpp>
32 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
35 #include <com/sun/star/lang/XInitialization.hpp>
36 #include <com/sun/star/datatransfer/XTransferable.hpp>
37 #include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp>
38 #include <com/sun/star/datatransfer/clipboard/XSystemClipboard.hpp>
39 #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
40 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
41 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
42 
43 #include <cppuhelper/compbase.hxx>
45 
46 using namespace com::sun::star;
47 using namespace com::sun::star::uno;
48 using namespace com::sun::star::lang;
49 
50 namespace vcl
51 {
52 namespace {
53 
54 // generic implementation to satisfy SalInstance
55 class GenericClipboard :
56  public cppu::WeakComponentImplHelper<
57  datatransfer::clipboard::XSystemClipboard,
58  XServiceInfo
59  >
60 {
61  osl::Mutex m_aMutex;
64  std::vector< Reference< css::datatransfer::clipboard::XClipboardListener > > m_aListeners;
65 
66 public:
67 
68  GenericClipboard() : cppu::WeakComponentImplHelper<
69  datatransfer::clipboard::XSystemClipboard,
70  XServiceInfo
71  >( m_aMutex )
72  {}
73 
74  /*
75  * XServiceInfo
76  */
77 
78  virtual OUString SAL_CALL getImplementationName() override;
79  virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
80  virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
81 
82  static Sequence< OUString > getSupportedServiceNames_static();
83 
84  /*
85  * XClipboard
86  */
87 
88  virtual Reference< css::datatransfer::XTransferable > SAL_CALL getContents() override;
89 
90  virtual void SAL_CALL setContents(
92  const Reference< css::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner ) override;
93 
94  virtual OUString SAL_CALL getName() override;
95 
96  /*
97  * XClipboardEx
98  */
99 
100  virtual sal_Int8 SAL_CALL getRenderingCapabilities() override;
101 
102  /*
103  * XClipboardNotifier
104  */
105  virtual void SAL_CALL addClipboardListener(
107 
108  virtual void SAL_CALL removeClipboardListener(
110 };
111 
112 }
113 
114 Sequence< OUString > GenericClipboard::getSupportedServiceNames_static()
115 {
116  Sequence< OUString > aRet { "com.sun.star.datatransfer.clipboard.SystemClipboard" };
117  return aRet;
118 }
119 
120 OUString GenericClipboard::getImplementationName()
121 {
122  return "com.sun.star.datatransfer.VCLGenericClipboard";
123 }
124 
125 Sequence< OUString > GenericClipboard::getSupportedServiceNames()
126 {
127  return getSupportedServiceNames_static();
128 }
129 
130 sal_Bool GenericClipboard::supportsService( const OUString& ServiceName )
131 {
132  return cppu::supportsService(this, ServiceName);
133 }
134 
135 Reference< css::datatransfer::XTransferable > GenericClipboard::getContents()
136 {
137  return m_aContents;
138 }
139 
140 void GenericClipboard::setContents(
143 {
144  osl::ClearableMutexGuard aGuard( m_aMutex );
147  m_aContents = xTrans;
148  m_aOwner = xClipboardOwner;
149 
150  std::vector< Reference< datatransfer::clipboard::XClipboardListener > > aListeners( m_aListeners );
151  datatransfer::clipboard::ClipboardEvent aEv;
152  aEv.Contents = m_aContents;
153 
154  aGuard.clear();
155 
156  if( xOldOwner.is() && xOldOwner != xClipboardOwner )
157  xOldOwner->lostOwnership( this, xOldContents );
158  for (auto const& listener : aListeners)
159  {
160  listener->changedContents( aEv );
161  }
162 }
163 
164 OUString GenericClipboard::getName()
165 {
166  return "CLIPBOARD";
167 }
168 
169 sal_Int8 GenericClipboard::getRenderingCapabilities()
170 {
171  return 0;
172 }
173 
174 void GenericClipboard::addClipboardListener( const Reference< datatransfer::clipboard::XClipboardListener >& listener )
175 {
176  osl::MutexGuard aGuard(m_aMutex);
177 
178  m_aListeners.push_back( listener );
179 }
180 
181 void GenericClipboard::removeClipboardListener( const Reference< datatransfer::clipboard::XClipboardListener >& listener )
182 {
183  osl::MutexGuard aGuard(m_aMutex);
184 
185  m_aListeners.erase(std::remove(m_aListeners.begin(), m_aListeners.end(), listener), m_aListeners.end());
186 }
187 
188 
189 
190 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
192  css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const& args)
193 {
194  SolarMutexGuard aGuard;
195  auto xClipboard = ImplGetSVData()->mpDefInst->CreateClipboard( args );
196  if (xClipboard.is())
197  xClipboard->acquire();
198  return xClipboard.get();
199 }
200 
201 namespace {
202 
203 /*
204 * generic DragSource dummy
205 */
206 class GenericDragSource : public cppu::WeakComponentImplHelper<
207  datatransfer::dnd::XDragSource,
208  XInitialization,
209  css::lang::XServiceInfo
210  >
211 {
212  osl::Mutex m_aMutex;
213 public:
214  GenericDragSource() : WeakComponentImplHelper( m_aMutex ) {}
215 
216  // XDragSource
217  virtual sal_Bool SAL_CALL isDragImageSupported() override;
218  virtual sal_Int32 SAL_CALL getDefaultCursor( sal_Int8 dragAction ) override;
219  virtual void SAL_CALL startDrag(
220  const datatransfer::dnd::DragGestureEvent& trigger,
221  sal_Int8 sourceActions, sal_Int32 cursor, sal_Int32 image,
222  const Reference< datatransfer::XTransferable >& transferable,
224  ) override;
225 
226  // XInitialization
227  virtual void SAL_CALL initialize( const Sequence< Any >& arguments ) override;
228 
229  OUString SAL_CALL getImplementationName() override
230  { return "com.sun.star.datatransfer.dnd.VclGenericDragSource"; }
231 
232  sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
233  { return cppu::supportsService(this, ServiceName); }
234 
235  css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
236  { return getSupportedServiceNames_static(); }
237 
238  static Sequence< OUString > getSupportedServiceNames_static()
239  {
240  return { "com.sun.star.datatransfer.dnd.GenericDragSource" };
241  }
242 };
243 
244 }
245 
246 sal_Bool GenericDragSource::isDragImageSupported()
247 {
248  return false;
249 }
250 
251 sal_Int32 GenericDragSource::getDefaultCursor( sal_Int8 )
252 {
253  return 0;
254 }
255 
256 void GenericDragSource::startDrag( const datatransfer::dnd::DragGestureEvent&,
257  sal_Int8 /*sourceActions*/, sal_Int32 /*cursor*/, sal_Int32 /*image*/,
260  )
261 {
262  datatransfer::dnd::DragSourceDropEvent aEv;
263  aEv.DropAction = datatransfer::dnd::DNDConstants::ACTION_COPY;
264  aEv.DropSuccess = false;
265  listener->dragDropEnd( aEv );
266 }
267 
268 void GenericDragSource::initialize( const Sequence< Any >& )
269 {
270 }
271 
273 {
274 #if defined MACOSX
275  return { "com.sun.star.datatransfer.dnd.OleDragSource" };
276 #elif defined UNX
277  return { "com.sun.star.datatransfer.dnd.X11DragSource" };
278 #else
279  return { "com.sun.star.datatransfer.dnd.VclGenericDragSource" };
280 #endif
281 }
282 
284 {
285 #if defined MACOSX
286  return "com.sun.star.comp.datatransfer.dnd.OleDragSource_V1";
287 #elif defined UNX
288  return "com.sun.star.datatransfer.dnd.XdndSupport";
289 #else
290  return "com.sun.star.datatransfer.dnd.VclGenericDragSource";
291 #endif
292 }
293 
295 {
296  SolarMutexGuard aGuard;
298  return xResult;
299 }
300 
301 /*
302 * generic DragSource dummy
303 */
304 
305 namespace {
306 
307 class GenericDropTarget : public cppu::WeakComponentImplHelper<
308  datatransfer::dnd::XDropTarget,
309  XInitialization,
310  css::lang::XServiceInfo
311  >
312 {
313  osl::Mutex m_aMutex;
314 public:
315  GenericDropTarget() : WeakComponentImplHelper( m_aMutex )
316  {}
317 
318  // XInitialization
319  virtual void SAL_CALL initialize( const Sequence< Any >& args ) override;
320 
321  // XDropTarget
322  virtual void SAL_CALL addDropTargetListener( const Reference< css::datatransfer::dnd::XDropTargetListener >& ) override;
323  virtual void SAL_CALL removeDropTargetListener( const Reference< css::datatransfer::dnd::XDropTargetListener >& ) override;
324  virtual sal_Bool SAL_CALL isActive() override;
325  virtual void SAL_CALL setActive( sal_Bool active ) override;
326  virtual sal_Int8 SAL_CALL getDefaultActions() override;
327  virtual void SAL_CALL setDefaultActions( sal_Int8 actions ) override;
328 
329  OUString SAL_CALL getImplementationName() override
330  { return "com.sun.star.datatransfer.dnd.VclGenericDropTarget"; }
331 
332  sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
333  { return cppu::supportsService(this, ServiceName); }
334 
335  css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
336  { return getSupportedServiceNames_static(); }
337 
338  static Sequence< OUString > getSupportedServiceNames_static()
339  {
340  return { "com.sun.star.datatransfer.dnd.GenericDropTarget" };
341  }
342 };
343 
344 }
345 
346 void GenericDropTarget::initialize( const Sequence< Any >& )
347 {
348 }
349 
350 void GenericDropTarget::addDropTargetListener( const Reference< css::datatransfer::dnd::XDropTargetListener >& )
351 {
352 }
353 
354 void GenericDropTarget::removeDropTargetListener( const Reference< css::datatransfer::dnd::XDropTargetListener >& )
355 {
356 }
357 
358 sal_Bool GenericDropTarget::isActive()
359 {
360  return false;
361 }
362 
363 void GenericDropTarget::setActive( sal_Bool )
364 {
365 }
366 
367 sal_Int8 GenericDropTarget::getDefaultActions()
368 {
369  return 0;
370 }
371 
372 void GenericDropTarget::setDefaultActions( sal_Int8)
373 {
374 }
375 
377 {
378 #if defined MACOSX
379  return { "com.sun.star.datatransfer.dnd.OleDropTarget" };
380 #elif defined UNX
381  return { "com.sun.star.datatransfer.dnd.X11DropTarget" };
382 #else
383  return GenericDropTarget::getSupportedServiceNames_static();
384 #endif
385 }
386 
388 {
389  return
390  #if defined MACOSX
391  "com.sun.star.comp.datatransfer.dnd.OleDropTarget_V1"
392  #elif defined UNX
393  "com.sun.star.datatransfer.dnd.XdndDropTarget"
394  #else
395  "com.sun.star.datatransfer.dnd.VclGenericDropTarget"
396  #endif
397  ;
398 }
399 
401 {
402  SolarMutexGuard aGuard;
404  return xResult;
405 }
406 
407 } // namespace vcl
408 
409 /*
410 * SalInstance generic
411 */
413 {
414  if (arguments.hasElements()) {
415  throw css::lang::IllegalArgumentException(
416  "non-empty SalInstance::CreateClipboard arguments", {}, -1);
417  }
419  // In LOK, each document view shall have its own clipboard instance, and the way that
420  // (happens to?) work is that apparently this function is called at most once for each such
421  // document view, so it is OK if we hand out a fresh instance on each call in LOK (whereas
422  // in non-LOK below we keep handing out one single instance; see also
423  // <https://lists.freedesktop.org/archives/libreoffice/2020-April/084824.html> "Re: Linux
424  // SAL_USE_VCLPLUGIN=svp and the clipboard"):
425  return Reference< XInterface >( static_cast<cppu::OWeakObject *>(new vcl::GenericClipboard()) );
426  }
428  if (!m_clipboard.is()) {
429  m_clipboard = static_cast<cppu::OWeakObject *>(new vcl::GenericClipboard());
430  }
431  return m_clipboard;
432 }
433 
435 {
436  return Reference< XInterface >( static_cast<cppu::OWeakObject *>(new vcl::GenericDragSource()) );
437 }
438 
440 {
441  return Reference< XInterface >( static_cast<cppu::OWeakObject *>(new vcl::GenericDropTarget()) );
442 }
443 
444 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
exports com.sun.star.datatransfer. clipboard
virtual css::uno::Reference< css::uno::XInterface > CreateDropTarget()
Definition: dtranscomp.cxx:439
virtual css::uno::Reference< css::uno::XInterface > CreateClipboard(const css::uno::Sequence< css::uno::Any > &i_rArguments)
Definition: dtranscomp.cxx:412
signed char sal_Int8
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
OUString DragSource_getImplementationName()
Definition: dtranscomp.cxx:283
std::vector< Reference< css::datatransfer::clipboard::XClipboardListener > > m_aListeners
Definition: dtranscomp.cxx:64
virtual css::uno::Reference< css::uno::XInterface > CreateDragSource()
Definition: dtranscomp.cxx:434
Reference< css::datatransfer::XTransferable > m_aContents
Definition: dtranscomp.cxx:62
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Listeners aListeners
exports com.sun.star. datatransfer
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:73
Sequence< OUString > DropTarget_getSupportedServiceNames()
Definition: dtranscomp.cxx:376
Reference< XInterface > DragSource_createInstance(const Reference< XMultiServiceFactory > &)
Definition: dtranscomp.cxx:294
unsigned char sal_Bool
Sequence< OUString > DragSource_getSupportedServiceNames()
Definition: dtranscomp.cxx:272
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * vcl_SystemClipboard_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &args)
Definition: dtranscomp.cxx:191
OUString DropTarget_getImplementationName()
Definition: dtranscomp.cxx:387
bool isActive()
void setActive(bool bActive)
#define DBG_TESTSOLARMUTEX()
osl::Mutex m_aMutex
Definition: dtranscomp.cxx:61
Reference< XInterface > DropTarget_createInstance(const Reference< XMultiServiceFactory > &)
Definition: dtranscomp.cxx:400
SalInstance * mpDefInst
Definition: svdata.hxx:383
Reference< css::datatransfer::clipboard::XClipboardOwner > m_aOwner
Definition: dtranscomp.cxx:63