1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <comphelper/lok.hxx>
23 #include <comphelper/processfactory.hxx>
24 #include <o3tl/test_info.hxx>
25 #include <osl/mutex.hxx>
26 #include <tools/debug.hxx>
27 #include <vcl/svapp.hxx>
29 #include <factory.hxx>
31 #include <salinst.hxx>
33 #include <com/sun/star/lang/IllegalArgumentException.hpp>
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 #include <com/sun/star/lang/XServiceInfo.hpp>
36 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
37 #include <com/sun/star/lang/XInitialization.hpp>
38 #include <com/sun/star/datatransfer/XTransferable.hpp>
39 #include <com/sun/star/datatransfer/clipboard/LokClipboard.hpp>
40 #include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp>
41 #include <com/sun/star/datatransfer/clipboard/XSystemClipboard.hpp>
42 #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
43 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
44 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
46 #include <comphelper/compbase.hxx>
47 #include <cppuhelper/supportsservice.hxx>
49 using namespace com::sun::star
;
50 using namespace com::sun::star::uno
;
51 using namespace com::sun::star::lang
;
57 // generic implementation to satisfy SalInstance
58 class GenericClipboard
:
59 public comphelper::WeakComponentImplHelper
<
60 datatransfer::clipboard::XSystemClipboard
,
64 Reference
< css::datatransfer::XTransferable
> m_aContents
;
65 Reference
< css::datatransfer::clipboard::XClipboardOwner
> m_aOwner
;
66 std::vector
< Reference
< css::datatransfer::clipboard::XClipboardListener
> > m_aListeners
;
77 virtual OUString SAL_CALL
getImplementationName() override
;
78 virtual sal_Bool SAL_CALL
supportsService( const OUString
& ServiceName
) override
;
79 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
81 static Sequence
< OUString
> getSupportedServiceNames_static();
87 virtual Reference
< css::datatransfer::XTransferable
> SAL_CALL
getContents() override
;
89 virtual void SAL_CALL
setContents(
90 const Reference
< css::datatransfer::XTransferable
>& xTrans
,
91 const Reference
< css::datatransfer::clipboard::XClipboardOwner
>& xClipboardOwner
) override
;
93 virtual OUString SAL_CALL
getName() override
;
99 virtual sal_Int8 SAL_CALL
getRenderingCapabilities() override
;
104 virtual void SAL_CALL
addClipboardListener(
105 const Reference
< css::datatransfer::clipboard::XClipboardListener
>& listener
) override
;
107 virtual void SAL_CALL
removeClipboardListener(
108 const Reference
< css::datatransfer::clipboard::XClipboardListener
>& listener
) override
;
113 Sequence
< OUString
> GenericClipboard::getSupportedServiceNames_static()
115 Sequence
< OUString
> aRet
{ u
"com.sun.star.datatransfer.clipboard.SystemClipboard"_ustr
};
119 OUString
GenericClipboard::getImplementationName()
121 return u
"com.sun.star.datatransfer.VCLGenericClipboard"_ustr
;
124 Sequence
< OUString
> GenericClipboard::getSupportedServiceNames()
126 return getSupportedServiceNames_static();
129 sal_Bool
GenericClipboard::supportsService( const OUString
& ServiceName
)
131 return cppu::supportsService(this, ServiceName
);
134 Reference
< css::datatransfer::XTransferable
> GenericClipboard::getContents()
136 std::unique_lock
aGuard(m_aMutex
);
140 void GenericClipboard::setContents(
141 const Reference
< css::datatransfer::XTransferable
>& xTrans
,
142 const Reference
< css::datatransfer::clipboard::XClipboardOwner
>& xClipboardOwner
)
144 std::unique_lock
aGuard( m_aMutex
);
145 Reference
< datatransfer::clipboard::XClipboardOwner
> xOldOwner( m_aOwner
);
146 Reference
< datatransfer::XTransferable
> xOldContents( m_aContents
);
147 m_aContents
= xTrans
;
148 m_aOwner
= xClipboardOwner
;
150 std::vector
< Reference
< datatransfer::clipboard::XClipboardListener
> > aListeners( m_aListeners
);
151 datatransfer::clipboard::ClipboardEvent aEv
;
152 aEv
.Contents
= m_aContents
;
156 if( xOldOwner
.is() && xOldOwner
!= xClipboardOwner
)
157 xOldOwner
->lostOwnership( this, xOldContents
);
158 for (auto const& listener
: aListeners
)
160 listener
->changedContents( aEv
);
164 OUString
GenericClipboard::getName()
166 return u
"CLIPBOARD"_ustr
;
169 sal_Int8
GenericClipboard::getRenderingCapabilities()
174 void GenericClipboard::addClipboardListener( const Reference
< datatransfer::clipboard::XClipboardListener
>& listener
)
176 std::unique_lock
aGuard(m_aMutex
);
178 m_aListeners
.push_back( listener
);
181 void GenericClipboard::removeClipboardListener( const Reference
< datatransfer::clipboard::XClipboardListener
>& listener
)
183 std::unique_lock
aGuard(m_aMutex
);
185 std::erase(m_aListeners
, listener
);
190 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
191 vcl_SystemClipboard_get_implementation(
192 css::uno::XComponentContext
* , css::uno::Sequence
<css::uno::Any
> const& args
)
194 SolarMutexGuard aGuard
;
195 auto xClipboard
= ImplGetSVData()->mpDefInst
->CreateClipboard( args
);
197 xClipboard
->acquire();
198 return xClipboard
.get();
204 * generic DragSource dummy
206 class GenericDragSource
: public ::comphelper::WeakComponentImplHelper
<
207 datatransfer::dnd::XDragSource
,
209 css::lang::XServiceInfo
212 css::uno::Reference
<css::datatransfer::XTransferable
> m_xTrans
;
214 GenericDragSource() {}
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
,
223 const Reference
< datatransfer::dnd::XDragSourceListener
>& listener
227 virtual void SAL_CALL
initialize( const Sequence
< Any
>& arguments
) override
;
229 OUString SAL_CALL
getImplementationName() override
230 { return u
"com.sun.star.datatransfer.dnd.VclGenericDragSource"_ustr
; }
232 sal_Bool SAL_CALL
supportsService(OUString
const & ServiceName
) override
233 { return cppu::supportsService(this, ServiceName
); }
235 css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
236 { return getSupportedServiceNames_static(); }
238 static Sequence
< OUString
> getSupportedServiceNames_static()
240 return { u
"com.sun.star.datatransfer.dnd.GenericDragSource"_ustr
};
246 sal_Bool
GenericDragSource::isDragImageSupported()
251 sal_Int32
GenericDragSource::getDefaultCursor( sal_Int8
)
256 void GenericDragSource::startDrag( const datatransfer::dnd::DragGestureEvent
&,
257 sal_Int8
/*sourceActions*/, sal_Int32
/*cursor*/, sal_Int32
/*image*/,
258 const Reference
< datatransfer::XTransferable
>& rTrans
,
259 const Reference
< datatransfer::dnd::XDragSourceListener
>& listener
262 if (comphelper::LibreOfficeKit::isActive()) {
267 datatransfer::dnd::DragSourceDropEvent aEv
;
268 aEv
.DropAction
= datatransfer::dnd::DNDConstants::ACTION_COPY
;
269 aEv
.DropSuccess
= false;
270 listener
->dragDropEnd( aEv
);
273 void GenericDragSource::initialize( const Sequence
< Any
>& )
277 Sequence
< OUString
> DragSource_getSupportedServiceNames()
280 return { "com.sun.star.datatransfer.dnd.OleDragSource" };
282 return { u
"com.sun.star.datatransfer.dnd.X11DragSource"_ustr
};
284 return { "com.sun.star.datatransfer.dnd.VclGenericDragSource" };
288 OUString
DragSource_getImplementationName()
291 return "com.sun.star.comp.datatransfer.dnd.OleDragSource_V1";
293 return u
"com.sun.star.datatransfer.dnd.XdndSupport"_ustr
;
295 return "com.sun.star.datatransfer.dnd.VclGenericDragSource";
299 Reference
< XInterface
> DragSource_createInstance( const Reference
< XMultiServiceFactory
>& )
301 SolarMutexGuard aGuard
;
302 Reference
< XInterface
> xResult
= ImplGetSVData()->mpDefInst
->CreateDragSource();
307 * generic DragSource dummy
312 class GenericDropTarget
: public comphelper::WeakComponentImplHelper
<
313 datatransfer::dnd::XDropTarget
,
315 css::lang::XServiceInfo
319 GenericDropTarget() {}
322 virtual void SAL_CALL
initialize( const Sequence
< Any
>& args
) override
;
325 virtual void SAL_CALL
addDropTargetListener( const Reference
< css::datatransfer::dnd::XDropTargetListener
>& ) override
;
326 virtual void SAL_CALL
removeDropTargetListener( const Reference
< css::datatransfer::dnd::XDropTargetListener
>& ) override
;
327 virtual sal_Bool SAL_CALL
isActive() override
;
328 virtual void SAL_CALL
setActive( sal_Bool active
) override
;
329 virtual sal_Int8 SAL_CALL
getDefaultActions() override
;
330 virtual void SAL_CALL
setDefaultActions( sal_Int8 actions
) override
;
332 OUString SAL_CALL
getImplementationName() override
333 { return u
"com.sun.star.datatransfer.dnd.VclGenericDropTarget"_ustr
; }
335 sal_Bool SAL_CALL
supportsService(OUString
const & ServiceName
) override
336 { return cppu::supportsService(this, ServiceName
); }
338 css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
339 { return getSupportedServiceNames_static(); }
341 static Sequence
< OUString
> getSupportedServiceNames_static()
343 return { u
"com.sun.star.datatransfer.dnd.GenericDropTarget"_ustr
};
349 void GenericDropTarget::initialize( const Sequence
< Any
>& )
353 void GenericDropTarget::addDropTargetListener( const Reference
< css::datatransfer::dnd::XDropTargetListener
>& )
357 void GenericDropTarget::removeDropTargetListener( const Reference
< css::datatransfer::dnd::XDropTargetListener
>& )
361 sal_Bool
GenericDropTarget::isActive()
366 void GenericDropTarget::setActive( sal_Bool
)
370 sal_Int8
GenericDropTarget::getDefaultActions()
375 void GenericDropTarget::setDefaultActions( sal_Int8
)
379 Sequence
< OUString
> DropTarget_getSupportedServiceNames()
382 return { "com.sun.star.datatransfer.dnd.OleDropTarget" };
384 return { u
"com.sun.star.datatransfer.dnd.X11DropTarget"_ustr
};
386 return GenericDropTarget::getSupportedServiceNames_static();
390 OUString
DropTarget_getImplementationName()
394 "com.sun.star.comp.datatransfer.dnd.OleDropTarget_V1"
396 u
"com.sun.star.datatransfer.dnd.XdndDropTarget"_ustr
398 "com.sun.star.datatransfer.dnd.VclGenericDropTarget"
403 Reference
< XInterface
> DropTarget_createInstance( const Reference
< XMultiServiceFactory
>& )
405 SolarMutexGuard aGuard
;
406 Reference
< XInterface
> xResult
= ImplGetSVData()->mpDefInst
->CreateDropTarget();
413 * SalInstance generic
415 Reference
< XInterface
> SalInstance::CreateClipboard( const Sequence
< Any
>& arguments
)
417 if (arguments
.hasElements()) {
418 throw css::lang::IllegalArgumentException(
419 u
"non-empty SalInstance::CreateClipboard arguments"_ustr
, {}, -1);
422 return getXWeak(new vcl::GenericClipboard());
424 if (comphelper::LibreOfficeKit::isActive()) {
425 // In LOK, each document view shall have its own clipboard instance (whereas
426 // in non-LOK below we keep handing out one single instance; see also
427 // <https://lists.freedesktop.org/archives/libreoffice/2020-April/084824.html> "Re: Linux
428 // SAL_USE_VCLPLUGIN=svp and the clipboard"):
429 css::uno::Reference
<css::datatransfer::clipboard::XClipboard
> xClipboard
=
430 css::datatransfer::clipboard::LokClipboard::create(
431 comphelper::getProcessComponentContext());
435 DBG_TESTSOLARMUTEX();
436 if (!m_clipboard
.is()) {
437 m_clipboard
= getXWeak(new vcl::GenericClipboard());
442 uno::Reference
<uno::XInterface
> SalInstance::ImplCreateDragSource(const SystemEnvData
*)
444 return css::uno::Reference
<css::uno::XInterface
>();
447 Reference
< XInterface
> SalInstance::CreateDragSource(const SystemEnvData
* pSysEnv
)
449 // We run unit tests in parallel, which is a problem when touching a shared resource
450 // the system clipboard, so rather use the dummy GenericClipboard.
451 if (Application::IsHeadlessModeEnabled() || o3tl::IsRunningUnitTest() || o3tl::IsRunningUITest())
452 return getXWeak(new vcl::GenericDragSource());
453 return ImplCreateDragSource(pSysEnv
);
456 uno::Reference
<uno::XInterface
> SalInstance::ImplCreateDropTarget(const SystemEnvData
*)
458 return css::uno::Reference
<css::uno::XInterface
>();
461 Reference
< XInterface
> SalInstance::CreateDropTarget(const SystemEnvData
* pSysEnv
)
463 // see SalInstance::CreateDragSource
464 if (Application::IsHeadlessModeEnabled() || o3tl::IsRunningUnitTest() || o3tl::IsRunningUITest())
465 return getXWeak(new vcl::GenericDropTarget());
466 return ImplCreateDropTarget(pSysEnv
);
469 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */