Bumping manifests a=b2g-bump
[gecko.git] / widget / gtk / nsDragService.h
blob2ef0c288b811aef65ec49b709562de5758681553
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"
14 #include <gtk/gtk.h>
16 class nsWindow;
18 namespace mozilla {
19 namespace gfx {
20 class SourceSurface;
24 #ifndef HAVE_NSGOBJECTREFTRAITS
25 #define HAVE_NSGOBJECTREFTRAITS
26 template <class T>
27 class nsGObjectRefTraits : public nsPointerRefTraits<T> {
28 public:
29 static void Release(T *aPtr) { g_object_unref(aPtr); }
30 static void AddRef(T *aPtr) { g_object_ref(aPtr); }
32 #endif
34 #ifndef HAVE_NSAUTOREFTRAITS_GTKWIDGET
35 #define HAVE_NSAUTOREFTRAITS_GTKWIDGET
36 template <>
37 class nsAutoRefTraits<GtkWidget> : public nsGObjectRefTraits<GtkWidget> { };
38 #endif
40 #ifndef HAVE_NSAUTOREFTRAITS_GDKDRAGCONTEXT
41 #define HAVE_NSAUTOREFTRAITS_GDKDRAGCONTEXT
42 template <>
43 class nsAutoRefTraits<GdkDragContext> :
44 public nsGObjectRefTraits<GdkDragContext> { };
45 #endif
47 /**
48 * Native GTK DragService wrapper
51 class nsDragService : public nsBaseDragService,
52 public nsIObserver
54 public:
55 nsDragService();
57 NS_DECL_ISUPPORTS_INHERITED
59 NS_DECL_NSIOBSERVER
61 // nsIDragService
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);
69 // nsIDragSession
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,
74 uint32_t aItemIndex);
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,
84 gint aX,
85 gint aY,
86 GtkSelectionData *aSelection_data,
87 guint aInfo,
88 guint32 aTime);
90 gboolean ScheduleMotionEvent(nsWindow *aWindow,
91 GdkDragContext *aDragContext,
92 nsIntPoint aWindowPoint,
93 guint aTime);
94 void ScheduleLeaveEvent();
95 gboolean ScheduleDropEvent(nsWindow *aWindow,
96 GdkDragContext *aDragContext,
97 nsIntPoint aWindowPoint,
98 guint aTime);
100 nsWindow* GetMostRecentDestWindow()
102 return mScheduledTask == eDragTaskNone ? mTargetWindow
103 : mPendingWindow;
106 // END PUBLIC API
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
110 // invisible widget.
111 void SourceEndDragSession(GdkDragContext *aContext,
112 gint aResult);
113 void SourceDataGet(GtkWidget *widget,
114 GdkDragContext *context,
115 GtkSelectionData *selection_data,
116 guint32 aTime);
118 // set the drag icon during drag-begin
119 void SetDragIcon(GdkDragContext* aContext);
121 protected:
122 virtual ~nsDragService();
124 private:
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).
130 enum DragTask {
131 eDragTaskNone,
132 eDragTaskMotion,
133 eDragTaskLeave,
134 eDragTaskDrop,
135 eDragTaskSourceEnd
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.
140 guint mTaskSource;
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;
152 guint mPendingTime;
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;
163 guint mTargetTime;
165 // is it OK to drop on us?
166 bool mCanDrop;
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
176 // specific flavor
177 void GetTargetDragData(GdkAtom aFlavor);
178 // this will reset all of the target vars
179 void TargetResetData(void);
181 // source side vars
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,
197 int32_t aXOffset,
198 int32_t aYOffset,
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__