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