Line data Source code
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 : #ifndef INCLUDED_VCL_UNX_GENERIC_DTRANS_X11_SELECTION_HXX
21 : #define INCLUDED_VCL_UNX_GENERIC_DTRANS_X11_SELECTION_HXX
22 :
23 : #include <cppuhelper/compbase3.hxx>
24 : #include <cppuhelper/compbase4.hxx>
25 : #include <com/sun/star/datatransfer/XTransferable.hpp>
26 : #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
27 : #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
28 : #include <com/sun/star/awt/XDisplayConnection.hpp>
29 : #include <com/sun/star/lang/XInitialization.hpp>
30 : #include <com/sun/star/lang/XServiceInfo.hpp>
31 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32 : #include <com/sun/star/frame/XDesktop2.hpp>
33 : #include <osl/thread.h>
34 :
35 : #include <osl/conditn.hxx>
36 :
37 : #include <list>
38 : #include <unordered_map>
39 :
40 : #include <prex.h>
41 : #include <X11/Xlib.h>
42 : #include <postx.h>
43 :
44 : #define XDND_IMPLEMENTATION_NAME "com.sun.star.datatransfer.dnd.XdndSupport"
45 : #define XDND_DROPTARGET_IMPLEMENTATION_NAME "com.sun.star.datatransfer.dnd.XdndDropTarget"
46 :
47 : namespace x11 {
48 :
49 : class PixmapHolder; // in bmp.hxx
50 :
51 : rtl_TextEncoding getTextPlainEncoding( const OUString& rMimeType );
52 :
53 4 : class SelectionAdaptor
54 : {
55 : public:
56 : virtual css::uno::Reference< css::datatransfer::XTransferable > getTransferable() = 0;
57 : virtual void clearTransferable() = 0;
58 : virtual void fireContentsChanged() = 0;
59 : virtual css::uno::Reference< css::uno::XInterface > getReference() = 0;
60 : // returns a reference that will keep the SelectionAdaptor alive until the
61 : // reference is released
62 :
63 : protected:
64 0 : ~SelectionAdaptor() {}
65 : };
66 :
67 : class DropTarget :
68 : public ::cppu::WeakComponentImplHelper3<
69 : css::datatransfer::dnd::XDropTarget,
70 : css::lang::XInitialization,
71 : css::lang::XServiceInfo
72 : >
73 : {
74 : public:
75 : ::osl::Mutex m_aMutex;
76 : bool m_bActive;
77 : sal_Int8 m_nDefaultActions;
78 : ::Window m_aTargetWindow;
79 : class SelectionManager* m_pSelectionManager;
80 : css::uno::Reference< css::datatransfer::dnd::XDragSource >
81 : m_xSelectionManager;
82 : ::std::list< css::uno::Reference< css::datatransfer::dnd::XDropTargetListener > >
83 : m_aListeners;
84 :
85 : DropTarget();
86 : virtual ~DropTarget();
87 :
88 : // convenience functions that loop over listeners
89 : void dragEnter( const css::datatransfer::dnd::DropTargetDragEnterEvent& dtde ) throw();
90 : void dragExit( const css::datatransfer::dnd::DropTargetEvent& dte ) throw();
91 : void dragOver( const css::datatransfer::dnd::DropTargetDragEvent& dtde ) throw();
92 : void drop( const css::datatransfer::dnd::DropTargetDropEvent& dtde ) throw();
93 :
94 : // XInitialization
95 : virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& args ) throw ( css::uno::Exception, std::exception ) SAL_OVERRIDE;
96 :
97 : // XDropTarget
98 : virtual void SAL_CALL addDropTargetListener( const css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >& ) throw(std::exception) SAL_OVERRIDE;
99 : virtual void SAL_CALL removeDropTargetListener( const css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >& ) throw(std::exception) SAL_OVERRIDE;
100 : virtual sal_Bool SAL_CALL isActive() throw(std::exception) SAL_OVERRIDE;
101 : virtual void SAL_CALL setActive( sal_Bool active ) throw(std::exception) SAL_OVERRIDE;
102 : virtual sal_Int8 SAL_CALL getDefaultActions() throw(std::exception) SAL_OVERRIDE;
103 : virtual void SAL_CALL setDefaultActions( sal_Int8 actions ) throw(std::exception) SAL_OVERRIDE;
104 :
105 : // XServiceInfo
106 : virtual OUString SAL_CALL getImplementationName() throw(std::exception) SAL_OVERRIDE;
107 : virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(std::exception) SAL_OVERRIDE;
108 : virtual css::uno::Sequence< OUString >
109 : SAL_CALL getSupportedServiceNames() throw(std::exception) SAL_OVERRIDE;
110 : };
111 :
112 : class SelectionManagerHolder :
113 : public ::cppu::WeakComponentImplHelper3<
114 : css::datatransfer::dnd::XDragSource,
115 : css::lang::XInitialization,
116 : css::lang::XServiceInfo
117 : >
118 : {
119 : ::osl::Mutex m_aMutex;
120 : css::uno::Reference< css::datatransfer::dnd::XDragSource >
121 : m_xRealDragSource;
122 : public:
123 : SelectionManagerHolder();
124 : virtual ~SelectionManagerHolder();
125 :
126 : // XServiceInfo
127 : virtual OUString SAL_CALL getImplementationName() throw(std::exception) SAL_OVERRIDE;
128 : virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(std::exception) SAL_OVERRIDE;
129 : virtual css::uno::Sequence< OUString >
130 : SAL_CALL getSupportedServiceNames() throw(std::exception) SAL_OVERRIDE;
131 :
132 : // XInitialization
133 : virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& arguments ) throw( css::uno::Exception, std::exception ) SAL_OVERRIDE;
134 :
135 : // XDragSource
136 : virtual sal_Bool SAL_CALL isDragImageSupported() throw(std::exception) SAL_OVERRIDE;
137 : virtual sal_Int32 SAL_CALL getDefaultCursor( sal_Int8 dragAction ) throw(std::exception) SAL_OVERRIDE;
138 : virtual void SAL_CALL startDrag(
139 : const css::datatransfer::dnd::DragGestureEvent& trigger,
140 : sal_Int8 sourceActions, sal_Int32 cursor, sal_Int32 image,
141 : const css::uno::Reference< css::datatransfer::XTransferable >& transferable,
142 : const css::uno::Reference< css::datatransfer::dnd::XDragSourceListener >& listener
143 : ) throw(std::exception) SAL_OVERRIDE;
144 :
145 : };
146 :
147 : class SelectionManager :
148 : public ::cppu::WeakImplHelper4<
149 : css::datatransfer::dnd::XDragSource,
150 : css::lang::XInitialization,
151 : css::awt::XEventHandler,
152 : css::frame::XTerminateListener
153 : >,
154 : public SelectionAdaptor
155 : {
156 : static std::unordered_map< OUString, SelectionManager*, OUStringHash >& getInstances();
157 :
158 : // for INCR type selection transfer
159 : // INCR protocol is used if the data cannot
160 : // be transported at once but in parts
161 : // IncrementalTransfer holds the bytes to be transmitted
162 : // as well a the current position
163 : // INCR triggers the delivery of the next part by deleting the
164 : // property used to transfer the data
165 0 : struct IncrementalTransfer
166 : {
167 : css::uno::Sequence< sal_Int8 > m_aData;
168 : int m_nBufferPos;
169 : ::Window m_aRequestor;
170 : Atom m_aProperty;
171 : Atom m_aTarget;
172 : int m_nFormat;
173 : int m_nTransferStartTime;
174 : };
175 : int m_nIncrementalThreshold;
176 :
177 : // a struct to hold the data associated with a selection
178 0 : struct Selection
179 : {
180 : enum State
181 : {
182 : Inactive, WaitingForResponse, WaitingForData, IncrementalTransfer
183 : };
184 :
185 : State m_eState;
186 : SelectionAdaptor* m_pAdaptor;
187 : Atom m_aAtom;
188 : ::osl::Condition m_aDataArrived;
189 : css::uno::Sequence< sal_Int8 > m_aData;
190 : css::uno::Sequence< css::datatransfer::DataFlavor >
191 : m_aTypes;
192 : std::vector< Atom > m_aNativeTypes;
193 : // this is used for caching
194 : // m_aTypes is invalid after 2 seconds
195 : // m_aNativeTypes contains the corresponding original atom
196 : Atom m_aRequestedType;
197 : // m_aRequestedType is only valid while WaitingForResponse and WaitingFotData
198 : int m_nLastTimestamp;
199 : bool m_bHaveUTF16;
200 : Atom m_aUTF8Type;
201 : bool m_bHaveCompound;
202 : bool m_bOwner;
203 : ::Window m_aLastOwner;
204 : PixmapHolder* m_pPixmap;
205 : // m_nOrigTimestamp contains the Timestamp at which the seclection
206 : // was acquired; needed for TimeSTAMP target
207 : Time m_nOrigTimestamp;
208 :
209 4 : Selection() : m_eState( Inactive ),
210 : m_pAdaptor( NULL ),
211 : m_aAtom( None ),
212 : m_aRequestedType( None ),
213 : m_nLastTimestamp( 0 ),
214 : m_bHaveUTF16( false ),
215 : m_aUTF8Type( None ),
216 : m_bHaveCompound( false ),
217 : m_bOwner( false ),
218 : m_aLastOwner( None ),
219 : m_pPixmap( NULL ),
220 4 : m_nOrigTimestamp( CurrentTime )
221 4 : {}
222 : };
223 :
224 : // a struct to hold data associated with a XDropTarget
225 : struct DropTargetEntry
226 : {
227 : DropTarget* m_pTarget;
228 : ::Window m_aRootWindow;
229 :
230 11 : DropTargetEntry() : m_pTarget( NULL ), m_aRootWindow( None ) {}
231 11 : explicit DropTargetEntry( DropTarget* pTarget ) :
232 : m_pTarget( pTarget ),
233 11 : m_aRootWindow( None )
234 11 : {}
235 : DropTargetEntry( const DropTargetEntry& rEntry ) :
236 : m_pTarget( rEntry.m_pTarget ),
237 : m_aRootWindow( rEntry.m_aRootWindow )
238 : {}
239 21 : ~DropTargetEntry() {}
240 :
241 0 : DropTarget* operator->() const { return m_pTarget; }
242 11 : DropTargetEntry& operator=(const DropTargetEntry& rEntry)
243 11 : { m_pTarget = rEntry.m_pTarget; m_aRootWindow = rEntry.m_aRootWindow; return *this; }
244 : };
245 :
246 : // internal data
247 : Display* m_pDisplay;
248 : oslThread m_aThread;
249 : int m_EndThreadPipe[2];
250 : oslThread m_aDragExecuteThread;
251 : ::osl::Condition m_aDragRunning;
252 : ::Window m_aWindow;
253 : css::uno::Reference< css::frame::XDesktop2 > m_xDesktop;
254 : css::uno::Reference< css::awt::XDisplayConnection >
255 : m_xDisplayConnection;
256 : sal_Int32 m_nSelectionTimeout;
257 : Time m_nSelectionTimestamp;
258 :
259 : // members used for Xdnd
260 :
261 : // drop only
262 :
263 : // contains the XdndEnterEvent of a drop action running
264 : // with one of our targets. The data.l[0] member
265 : // (conatining the drag source ::Window) is set
266 : // to None while that is not the case
267 : XClientMessageEvent m_aDropEnterEvent;
268 : // set to false on XdndEnter
269 : // set to true on first XdndPosition or XdndLeave
270 : bool m_bDropEnterSent;
271 : ::Window m_aCurrentDropWindow;
272 : // Time code of XdndDrop
273 : Time m_nDropTime;
274 : sal_Int8 m_nLastDropAction;
275 : // XTransferable for Xdnd with foreign drag source
276 : css::uno::Reference< css::datatransfer::XTransferable >
277 : m_xDropTransferable;
278 : int m_nLastX, m_nLastY;
279 : Time m_nDropTimestamp;
280 : // set to true when calling drop()
281 : // if another XdndEnter is received this shows that
282 : // someone forgot to call dropComplete - we should reset
283 : // and react to the new drop
284 : bool m_bDropWaitingForCompletion;
285 :
286 : // drag only
287 :
288 : // None if no Dnd action is running with us as source
289 : ::Window m_aDropWindow;
290 : // either m_aDropWindow or its XdndProxy
291 : ::Window m_aDropProxy;
292 : ::Window m_aDragSourceWindow;
293 : // XTransferable for Xdnd when we are drag source
294 : css::uno::Reference< css::datatransfer::XTransferable >
295 : m_xDragSourceTransferable;
296 : css::uno::Reference< css::datatransfer::dnd::XDragSourceListener >
297 : m_xDragSourceListener;
298 : // root coordinates
299 : int m_nLastDragX, m_nLastDragY;
300 : css::uno::Sequence< css::datatransfer::DataFlavor >
301 : m_aDragFlavors;
302 : // the rectangle the pointer must leave until a new XdndPosition should
303 : // be sent. empty unless the drop target told to fill
304 : int m_nNoPosX, m_nNoPosY, m_nNoPosWidth, m_nNoPosHeight;
305 : unsigned int m_nDragButton;
306 : sal_Int8 m_nUserDragAction;
307 : sal_Int8 m_nTargetAcceptAction;
308 : sal_Int8 m_nSourceActions;
309 : bool m_bLastDropAccepted;
310 : bool m_bDropSuccess;
311 : bool m_bDropSent;
312 : time_t m_nDropTimeout;
313 : bool m_bWaitingForPrimaryConversion;
314 : Time m_nDragTimestamp;
315 :
316 : // drag cursors
317 : Cursor m_aMoveCursor;
318 : Cursor m_aCopyCursor;
319 : Cursor m_aLinkCursor;
320 : Cursor m_aNoneCursor;
321 : Cursor m_aCurrentCursor;
322 :
323 : // drag and drop
324 :
325 : int m_nCurrentProtocolVersion;
326 : std::unordered_map< ::Window, DropTargetEntry >
327 : m_aDropTargets;
328 :
329 : // some special atoms that are needed often
330 : Atom m_nCLIPBOARDAtom;
331 : Atom m_nTARGETSAtom;
332 : Atom m_nTIMESTAMPAtom;
333 : Atom m_nTEXTAtom;
334 : Atom m_nINCRAtom;
335 : Atom m_nCOMPOUNDAtom;
336 : Atom m_nMULTIPLEAtom;
337 : Atom m_nUTF16Atom;
338 : Atom m_nImageBmpAtom;
339 : Atom m_nXdndAware;
340 : Atom m_nXdndEnter;
341 : Atom m_nXdndLeave;
342 : Atom m_nXdndPosition;
343 : Atom m_nXdndStatus;
344 : Atom m_nXdndDrop;
345 : Atom m_nXdndFinished;
346 : Atom m_nXdndSelection;
347 : Atom m_nXdndTypeList;
348 : Atom m_nXdndProxy;
349 : Atom m_nXdndActionCopy;
350 : Atom m_nXdndActionMove;
351 : Atom m_nXdndActionLink;
352 : Atom m_nXdndActionAsk;
353 : Atom m_nXdndActionPrivate;
354 :
355 : // caching for atoms
356 : std::unordered_map< Atom, OUString >
357 : m_aAtomToString;
358 : std::unordered_map< OUString, Atom, OUStringHash >
359 : m_aStringToAtom;
360 :
361 : // the registered selections
362 : std::unordered_map< Atom, Selection* >
363 : m_aSelections;
364 : // IncrementalTransfers in progress
365 : std::unordered_map< ::Window, std::unordered_map< Atom, IncrementalTransfer > >
366 : m_aIncrementals;
367 :
368 : // do not use X11 multithreading capabilities
369 : // since this leads to deadlocks in different Xlib implentations
370 : // (XFree as well as Xsun) use an own mutex instead
371 : ::osl::Mutex m_aMutex;
372 : bool m_bShutDown;
373 :
374 : SelectionManager();
375 : virtual ~SelectionManager();
376 :
377 : SelectionAdaptor* getAdaptor( Atom selection );
378 : PixmapHolder* getPixmapHolder( Atom selection );
379 :
380 : // handle various events
381 : bool handleSelectionRequest( XSelectionRequestEvent& rRequest );
382 : bool handleSendPropertyNotify( XPropertyEvent& rNotify );
383 : bool handleReceivePropertyNotify( XPropertyEvent& rNotify );
384 : bool handleSelectionNotify( XSelectionEvent& rNotify );
385 : bool handleDragEvent( XEvent& rMessage );
386 : bool handleDropEvent( XClientMessageEvent& rMessage );
387 :
388 : // dnd helpers
389 : void sendDragStatus( Atom nDropAction );
390 : void sendDropPosition( bool bForce, Time eventTime );
391 : bool updateDragAction( int modifierState );
392 : int getXdndVersion( ::Window aXLIB_Window, ::Window& rProxy );
393 : Cursor createCursor( const unsigned char* pPointerData, const unsigned char* pMaskData, int width, int height, int hotX, int hotY );
394 : // coordinates on root ::Window
395 : void updateDragWindow( int nX, int nY, ::Window aRoot );
396 :
397 : bool getPasteData( Atom selection, Atom type, css::uno::Sequence< sal_Int8 >& rData );
398 : // returns true if conversion was successful
399 : bool convertData( const css::uno::Reference< css::datatransfer::XTransferable >& xTransferable,
400 : Atom nType,
401 : Atom nSelection,
402 : int & rFormat,
403 : css::uno::Sequence< sal_Int8 >& rData );
404 : bool sendData( SelectionAdaptor* pAdaptor, ::Window requestor, Atom target, Atom property, Atom selection );
405 :
406 : // thread dispatch loop
407 : public:
408 : // public for extern "C" stub
409 : static void run( void* );
410 : private:
411 : void dispatchEvent( int millisec );
412 : // drag thread dispatch
413 : public:
414 : // public for extern "C" stub
415 : static void runDragExecute( void* );
416 : private:
417 : void dragDoDispatch();
418 : bool handleXEvent( XEvent& rEvent );
419 :
420 : // compound text conversion
421 : OString convertToCompound( const OUString& rText );
422 : OUString convertFromCompound( const char* pText, int nLen = -1 );
423 :
424 : sal_Int8 getUserDragAction() const;
425 : sal_Int32 getSelectionTimeout();
426 : public:
427 : static SelectionManager& get( const OUString& rDisplayName = OUString() );
428 :
429 11 : Display * getDisplay() { return m_pDisplay; };
430 : ::Window getWindow() { return m_aWindow; };
431 :
432 : void registerHandler( Atom selection, SelectionAdaptor& rAdaptor );
433 : void deregisterHandler( Atom selection );
434 : bool requestOwnership( Atom selection );
435 :
436 : // allow for synchronization over one mutex for XClipboard
437 26 : osl::Mutex& getMutex() { return m_aMutex; }
438 :
439 : Atom getAtom( const OUString& rString );
440 : const OUString& getString( Atom nAtom );
441 :
442 : // type conversion
443 : // note: convertTypeToNative does NOT clear the list, so you can append
444 : // multiple types to the same list
445 : void convertTypeToNative( const OUString& rType, Atom selection, int& rFormat, ::std::list< Atom >& rConversions, bool bPushFront = false );
446 : OUString convertTypeFromNative( Atom nType, Atom selection, int& rFormat );
447 : void getNativeTypeList( const css::uno::Sequence< css::datatransfer::DataFlavor >& rTypes, std::list< Atom >& rOutTypeList, Atom targetselection );
448 :
449 : // methods for transferable
450 : bool getPasteDataTypes( Atom selection, css::uno::Sequence< css::datatransfer::DataFlavor >& rTypes );
451 : bool getPasteData( Atom selection, const OUString& rType, css::uno::Sequence< sal_Int8 >& rData );
452 :
453 : // for XDropTarget to register/deregister itself
454 : void registerDropTarget( ::Window aXLIB_Window, DropTarget* pTarget );
455 : void deregisterDropTarget( ::Window aXLIB_Window );
456 :
457 : // for XDropTarget{Drag|Drop}Context
458 : void accept( sal_Int8 dragOperation, ::Window aDropXLIB_Window, Time aTimestamp );
459 : void reject( ::Window aDropXLIB_Window, Time aTimestamp );
460 : void dropComplete( bool success, ::Window aDropXLIB_Window, Time aTimestamp );
461 :
462 : // for XDragSourceContext
463 0 : sal_Int32 getCurrentCursor() { return m_aCurrentCursor;}
464 : void setCursor( sal_Int32 cursor, ::Window aDropXLIB_Window, Time aTimestamp );
465 : void transferablesFlavorsChanged();
466 :
467 : void shutdown() throw();
468 :
469 : // XInitialization
470 : virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& arguments ) throw( css::uno::Exception, std::exception ) SAL_OVERRIDE;
471 :
472 : // XEventHandler
473 : virtual sal_Bool SAL_CALL handleEvent(const css::uno::Any& event)
474 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
475 :
476 : // XDragSource
477 : virtual sal_Bool SAL_CALL isDragImageSupported() throw(std::exception) SAL_OVERRIDE;
478 : virtual sal_Int32 SAL_CALL getDefaultCursor( sal_Int8 dragAction ) throw(std::exception) SAL_OVERRIDE;
479 : virtual void SAL_CALL startDrag(
480 : const css::datatransfer::dnd::DragGestureEvent& trigger,
481 : sal_Int8 sourceActions, sal_Int32 cursor, sal_Int32 image,
482 : const css::uno::Reference< css::datatransfer::XTransferable >& transferable,
483 : const css::uno::Reference< css::datatransfer::dnd::XDragSourceListener >& listener
484 : ) throw(std::exception) SAL_OVERRIDE;
485 :
486 : // SelectionAdaptor for XdndSelection Drag (we are drag source)
487 : virtual css::uno::Reference< css::datatransfer::XTransferable > getTransferable() throw() SAL_OVERRIDE;
488 : virtual void clearTransferable() throw() SAL_OVERRIDE;
489 : virtual void fireContentsChanged() throw() SAL_OVERRIDE;
490 : virtual css::uno::Reference< css::uno::XInterface > getReference() throw() SAL_OVERRIDE;
491 :
492 : // XEventListener
493 : virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
494 :
495 : // XTerminateListener
496 : virtual void SAL_CALL queryTermination( const css::lang::EventObject& aEvent )
497 : throw( css::frame::TerminationVetoException, css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
498 : virtual void SAL_CALL notifyTermination( const css::lang::EventObject& aEvent )
499 : throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
500 : };
501 :
502 : css::uno::Sequence< OUString > SAL_CALL Xdnd_getSupportedServiceNames();
503 : css::uno::Reference< css::uno::XInterface > SAL_CALL Xdnd_createInstance(
504 : const css::uno::Reference< css::lang::XMultiServiceFactory > & xMultiServiceFactory);
505 :
506 : css::uno::Sequence< OUString > SAL_CALL Xdnd_dropTarget_getSupportedServiceNames();
507 : css::uno::Reference< css::uno::XInterface > SAL_CALL Xdnd_dropTarget_createInstance(
508 : const css::uno::Reference< css::lang::XMultiServiceFactory > & xMultiServiceFactory);
509 :
510 : }
511 :
512 : #endif
513 :
514 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|