widget/gtk/nsDragService.h

branch
TOR_BUG_9701
changeset 10
ac0c01689b40
equal deleted inserted replaced
-1:000000000000 0:a993ef82c21f
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/. */
6
7 #ifndef nsDragService_h__
8 #define nsDragService_h__
9
10 #include "nsAutoPtr.h"
11 #include "nsBaseDragService.h"
12 #include "nsIObserver.h"
13 #include "nsAutoRef.h"
14 #include <gtk/gtk.h>
15
16 class nsWindow;
17
18 namespace mozilla {
19 namespace gfx {
20 class SourceSurface;
21 }
22 }
23
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); }
31 };
32 #endif
33
34 #ifndef HAVE_NSAUTOREFTRAITS_GTKWIDGET
35 #define HAVE_NSAUTOREFTRAITS_GTKWIDGET
36 template <>
37 class nsAutoRefTraits<GtkWidget> : public nsGObjectRefTraits<GtkWidget> { };
38 #endif
39
40 #ifndef HAVE_NSAUTOREFTRAITS_GDKDRAGCONTEXT
41 #define HAVE_NSAUTOREFTRAITS_GDKDRAGCONTEXT
42 template <>
43 class nsAutoRefTraits<GdkDragContext> :
44 public nsGObjectRefTraits<GdkDragContext> { };
45 #endif
46
47 /**
48 * Native GTK DragService wrapper
49 */
50
51 class nsDragService : public nsBaseDragService,
52 public nsIObserver
53 {
54 public:
55 nsDragService();
56 virtual ~nsDragService();
57
58 NS_DECL_ISUPPORTS_INHERITED
59
60 NS_DECL_NSIOBSERVER
61
62 // nsIDragService
63 NS_IMETHOD InvokeDragSession (nsIDOMNode *aDOMNode,
64 nsISupportsArray * anArrayTransferables,
65 nsIScriptableRegion * aRegion,
66 uint32_t aActionType);
67 NS_IMETHOD StartDragSession();
68 NS_IMETHOD EndDragSession(bool aDoneDrag);
69
70 // nsIDragSession
71 NS_IMETHOD SetCanDrop (bool aCanDrop);
72 NS_IMETHOD GetCanDrop (bool *aCanDrop);
73 NS_IMETHOD GetNumDropItems (uint32_t * aNumItems);
74 NS_IMETHOD GetData (nsITransferable * aTransferable,
75 uint32_t aItemIndex);
76 NS_IMETHOD IsDataFlavorSupported (const char *aDataFlavor, bool *_retval);
77
78 // Methods called from nsWindow to handle responding to GTK drag
79 // destination signals
80
81 static nsDragService* GetInstance();
82
83 void TargetDataReceived (GtkWidget *aWidget,
84 GdkDragContext *aContext,
85 gint aX,
86 gint aY,
87 GtkSelectionData *aSelection_data,
88 guint aInfo,
89 guint32 aTime);
90
91 gboolean ScheduleMotionEvent(nsWindow *aWindow,
92 GdkDragContext *aDragContext,
93 nsIntPoint aWindowPoint,
94 guint aTime);
95 void ScheduleLeaveEvent();
96 gboolean ScheduleDropEvent(nsWindow *aWindow,
97 GdkDragContext *aDragContext,
98 nsIntPoint aWindowPoint,
99 guint aTime);
100
101 nsWindow* GetMostRecentDestWindow()
102 {
103 return mScheduledTask == eDragTaskNone ? mTargetWindow
104 : mPendingWindow;
105 }
106
107 // END PUBLIC API
108
109 // These methods are public only so that they can be called from functions
110 // with C calling conventions. They are called for drags started with the
111 // invisible widget.
112 void SourceEndDragSession(GdkDragContext *aContext,
113 gint aResult);
114 void SourceDataGet(GtkWidget *widget,
115 GdkDragContext *context,
116 GtkSelectionData *selection_data,
117 guint32 aTime);
118
119 // set the drag icon during drag-begin
120 void SetDragIcon(GdkDragContext* aContext);
121
122 private:
123
124 // mScheduledTask indicates what signal has been received from GTK and
125 // so what needs to be dispatched when the scheduled task is run. It is
126 // eDragTaskNone when there is no task scheduled (but the
127 // previous task may still not have finished running).
128 enum DragTask {
129 eDragTaskNone,
130 eDragTaskMotion,
131 eDragTaskLeave,
132 eDragTaskDrop,
133 eDragTaskSourceEnd
134 };
135 DragTask mScheduledTask;
136 // mTaskSource is the GSource id for the task that is either scheduled
137 // or currently running. It is 0 if no task is scheduled or running.
138 guint mTaskSource;
139
140 // target/destination side vars
141 // These variables keep track of the state of the current drag.
142
143 // mPendingWindow, mPendingWindowPoint, mPendingDragContext, and
144 // mPendingTime, carry information from the GTK signal that will be used
145 // when the scheduled task is run. mPendingWindow and mPendingDragContext
146 // will be nullptr if the scheduled task is eDragTaskLeave.
147 nsRefPtr<nsWindow> mPendingWindow;
148 nsIntPoint mPendingWindowPoint;
149 nsCountedRef<GdkDragContext> mPendingDragContext;
150 guint mPendingTime;
151
152 // mTargetWindow and mTargetWindowPoint record the position of the last
153 // eDragTaskMotion or eDragTaskDrop task that was run or is still running.
154 // mTargetWindow is cleared once the drag has completed or left.
155 nsRefPtr<nsWindow> mTargetWindow;
156 nsIntPoint mTargetWindowPoint;
157 // mTargetWidget and mTargetDragContext are set only while dispatching
158 // motion or drop events. mTime records the corresponding timestamp.
159 nsCountedRef<GtkWidget> mTargetWidget;
160 nsCountedRef<GdkDragContext> mTargetDragContext;
161 guint mTargetTime;
162
163 // is it OK to drop on us?
164 bool mCanDrop;
165
166 // have we received our drag data?
167 bool mTargetDragDataReceived;
168 // last data received and its length
169 void *mTargetDragData;
170 uint32_t mTargetDragDataLen;
171 // is the current target drag context contain a list?
172 bool IsTargetContextList(void);
173 // this will get the native data from the last target given a
174 // specific flavor
175 void GetTargetDragData(GdkAtom aFlavor);
176 // this will reset all of the target vars
177 void TargetResetData(void);
178
179 // source side vars
180
181 // the source of our drags
182 GtkWidget *mHiddenWidget;
183 // our source data items
184 nsCOMPtr<nsISupportsArray> mSourceDataItems;
185
186 nsCOMPtr<nsIScriptableRegion> mSourceRegion;
187
188 // get a list of the sources in gtk's format
189 GtkTargetList *GetSourceList(void);
190
191 // attempts to create a semi-transparent drag image. Returns TRUE if
192 // successful, FALSE if not
193 bool SetAlphaPixmap(SourceSurface *aPixbuf,
194 GdkDragContext *aContext,
195 int32_t aXOffset,
196 int32_t aYOffset,
197 const nsIntRect &dragRect);
198
199 gboolean Schedule(DragTask aTask, nsWindow *aWindow,
200 GdkDragContext *aDragContext,
201 nsIntPoint aWindowPoint, guint aTime);
202
203 // Callback for g_idle_add_full() to run mScheduledTask.
204 static gboolean TaskDispatchCallback(gpointer data);
205 gboolean RunScheduledTask();
206 void UpdateDragAction();
207 void DispatchMotionEvents();
208 void ReplyToDragMotion();
209 gboolean DispatchDropEvent();
210 };
211
212 #endif // nsDragService_h__
213

mercurial