widget/gtk/nsDragService.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial