1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim: set ts=4 et sw=4 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef nsDragService_h__
8 #define nsDragService_h__
10 #include "nsAutoPtr.h"
11 #include "nsBaseDragService.h"
12 #include "nsIObserver.h"
13 #include "nsAutoRef.h"
24 #ifndef HAVE_NSGOBJECTREFTRAITS
25 #define HAVE_NSGOBJECTREFTRAITS
27 class nsGObjectRefTraits
: public nsPointerRefTraits
<T
> {
29 static void Release(T
*aPtr
) { g_object_unref(aPtr
); }
30 static void AddRef(T
*aPtr
) { g_object_ref(aPtr
); }
34 #ifndef HAVE_NSAUTOREFTRAITS_GTKWIDGET
35 #define HAVE_NSAUTOREFTRAITS_GTKWIDGET
37 class nsAutoRefTraits
<GtkWidget
> : public nsGObjectRefTraits
<GtkWidget
> { };
40 #ifndef HAVE_NSAUTOREFTRAITS_GDKDRAGCONTEXT
41 #define HAVE_NSAUTOREFTRAITS_GDKDRAGCONTEXT
43 class nsAutoRefTraits
<GdkDragContext
> :
44 public nsGObjectRefTraits
<GdkDragContext
> { };
48 * Native GTK DragService wrapper
51 class nsDragService
: public nsBaseDragService
,
57 NS_DECL_ISUPPORTS_INHERITED
62 NS_IMETHOD
InvokeDragSession (nsIDOMNode
*aDOMNode
,
63 nsISupportsArray
* anArrayTransferables
,
64 nsIScriptableRegion
* aRegion
,
65 uint32_t aActionType
);
66 NS_IMETHOD
StartDragSession();
67 NS_IMETHOD
EndDragSession(bool aDoneDrag
);
70 NS_IMETHOD
SetCanDrop (bool aCanDrop
);
71 NS_IMETHOD
GetCanDrop (bool *aCanDrop
);
72 NS_IMETHOD
GetNumDropItems (uint32_t * aNumItems
);
73 NS_IMETHOD
GetData (nsITransferable
* aTransferable
,
75 NS_IMETHOD
IsDataFlavorSupported (const char *aDataFlavor
, bool *_retval
);
77 // Methods called from nsWindow to handle responding to GTK drag
78 // destination signals
80 static nsDragService
* GetInstance();
82 void TargetDataReceived (GtkWidget
*aWidget
,
83 GdkDragContext
*aContext
,
86 GtkSelectionData
*aSelection_data
,
90 gboolean
ScheduleMotionEvent(nsWindow
*aWindow
,
91 GdkDragContext
*aDragContext
,
92 nsIntPoint aWindowPoint
,
94 void ScheduleLeaveEvent();
95 gboolean
ScheduleDropEvent(nsWindow
*aWindow
,
96 GdkDragContext
*aDragContext
,
97 nsIntPoint aWindowPoint
,
100 nsWindow
* GetMostRecentDestWindow()
102 return mScheduledTask
== eDragTaskNone
? mTargetWindow
108 // These methods are public only so that they can be called from functions
109 // with C calling conventions. They are called for drags started with the
111 void SourceEndDragSession(GdkDragContext
*aContext
,
113 void SourceDataGet(GtkWidget
*widget
,
114 GdkDragContext
*context
,
115 GtkSelectionData
*selection_data
,
118 // set the drag icon during drag-begin
119 void SetDragIcon(GdkDragContext
* aContext
);
122 virtual ~nsDragService();
126 // mScheduledTask indicates what signal has been received from GTK and
127 // so what needs to be dispatched when the scheduled task is run. It is
128 // eDragTaskNone when there is no task scheduled (but the
129 // previous task may still not have finished running).
137 DragTask mScheduledTask
;
138 // mTaskSource is the GSource id for the task that is either scheduled
139 // or currently running. It is 0 if no task is scheduled or running.
142 // target/destination side vars
143 // These variables keep track of the state of the current drag.
145 // mPendingWindow, mPendingWindowPoint, mPendingDragContext, and
146 // mPendingTime, carry information from the GTK signal that will be used
147 // when the scheduled task is run. mPendingWindow and mPendingDragContext
148 // will be nullptr if the scheduled task is eDragTaskLeave.
149 nsRefPtr
<nsWindow
> mPendingWindow
;
150 nsIntPoint mPendingWindowPoint
;
151 nsCountedRef
<GdkDragContext
> mPendingDragContext
;
154 // mTargetWindow and mTargetWindowPoint record the position of the last
155 // eDragTaskMotion or eDragTaskDrop task that was run or is still running.
156 // mTargetWindow is cleared once the drag has completed or left.
157 nsRefPtr
<nsWindow
> mTargetWindow
;
158 nsIntPoint mTargetWindowPoint
;
159 // mTargetWidget and mTargetDragContext are set only while dispatching
160 // motion or drop events. mTime records the corresponding timestamp.
161 nsCountedRef
<GtkWidget
> mTargetWidget
;
162 nsCountedRef
<GdkDragContext
> mTargetDragContext
;
165 // is it OK to drop on us?
168 // have we received our drag data?
169 bool mTargetDragDataReceived
;
170 // last data received and its length
171 void *mTargetDragData
;
172 uint32_t mTargetDragDataLen
;
173 // is the current target drag context contain a list?
174 bool IsTargetContextList(void);
175 // this will get the native data from the last target given a
177 void GetTargetDragData(GdkAtom aFlavor
);
178 // this will reset all of the target vars
179 void TargetResetData(void);
183 // the source of our drags
184 GtkWidget
*mHiddenWidget
;
185 // our source data items
186 nsCOMPtr
<nsISupportsArray
> mSourceDataItems
;
188 nsCOMPtr
<nsIScriptableRegion
> mSourceRegion
;
190 // get a list of the sources in gtk's format
191 GtkTargetList
*GetSourceList(void);
193 // attempts to create a semi-transparent drag image. Returns TRUE if
194 // successful, FALSE if not
195 bool SetAlphaPixmap(SourceSurface
*aPixbuf
,
196 GdkDragContext
*aContext
,
199 const nsIntRect
&dragRect
);
201 gboolean
Schedule(DragTask aTask
, nsWindow
*aWindow
,
202 GdkDragContext
*aDragContext
,
203 nsIntPoint aWindowPoint
, guint aTime
);
205 // Callback for g_idle_add_full() to run mScheduledTask.
206 static gboolean
TaskDispatchCallback(gpointer data
);
207 gboolean
RunScheduledTask();
208 void UpdateDragAction();
209 void DispatchMotionEvents();
210 void ReplyToDragMotion();
211 gboolean
DispatchDropEvent();
214 #endif // nsDragService_h__