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