1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/gtk/nsDragService.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,213 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* vim: set ts=4 et sw=4 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef nsDragService_h__ 1.11 +#define nsDragService_h__ 1.12 + 1.13 +#include "nsAutoPtr.h" 1.14 +#include "nsBaseDragService.h" 1.15 +#include "nsIObserver.h" 1.16 +#include "nsAutoRef.h" 1.17 +#include <gtk/gtk.h> 1.18 + 1.19 +class nsWindow; 1.20 + 1.21 +namespace mozilla { 1.22 +namespace gfx { 1.23 +class SourceSurface; 1.24 +} 1.25 +} 1.26 + 1.27 +#ifndef HAVE_NSGOBJECTREFTRAITS 1.28 +#define HAVE_NSGOBJECTREFTRAITS 1.29 +template <class T> 1.30 +class nsGObjectRefTraits : public nsPointerRefTraits<T> { 1.31 +public: 1.32 + static void Release(T *aPtr) { g_object_unref(aPtr); } 1.33 + static void AddRef(T *aPtr) { g_object_ref(aPtr); } 1.34 +}; 1.35 +#endif 1.36 + 1.37 +#ifndef HAVE_NSAUTOREFTRAITS_GTKWIDGET 1.38 +#define HAVE_NSAUTOREFTRAITS_GTKWIDGET 1.39 +template <> 1.40 +class nsAutoRefTraits<GtkWidget> : public nsGObjectRefTraits<GtkWidget> { }; 1.41 +#endif 1.42 + 1.43 +#ifndef HAVE_NSAUTOREFTRAITS_GDKDRAGCONTEXT 1.44 +#define HAVE_NSAUTOREFTRAITS_GDKDRAGCONTEXT 1.45 +template <> 1.46 +class nsAutoRefTraits<GdkDragContext> : 1.47 + public nsGObjectRefTraits<GdkDragContext> { }; 1.48 +#endif 1.49 + 1.50 +/** 1.51 + * Native GTK DragService wrapper 1.52 + */ 1.53 + 1.54 +class nsDragService : public nsBaseDragService, 1.55 + public nsIObserver 1.56 +{ 1.57 +public: 1.58 + nsDragService(); 1.59 + virtual ~nsDragService(); 1.60 + 1.61 + NS_DECL_ISUPPORTS_INHERITED 1.62 + 1.63 + NS_DECL_NSIOBSERVER 1.64 + 1.65 + // nsIDragService 1.66 + NS_IMETHOD InvokeDragSession (nsIDOMNode *aDOMNode, 1.67 + nsISupportsArray * anArrayTransferables, 1.68 + nsIScriptableRegion * aRegion, 1.69 + uint32_t aActionType); 1.70 + NS_IMETHOD StartDragSession(); 1.71 + NS_IMETHOD EndDragSession(bool aDoneDrag); 1.72 + 1.73 + // nsIDragSession 1.74 + NS_IMETHOD SetCanDrop (bool aCanDrop); 1.75 + NS_IMETHOD GetCanDrop (bool *aCanDrop); 1.76 + NS_IMETHOD GetNumDropItems (uint32_t * aNumItems); 1.77 + NS_IMETHOD GetData (nsITransferable * aTransferable, 1.78 + uint32_t aItemIndex); 1.79 + NS_IMETHOD IsDataFlavorSupported (const char *aDataFlavor, bool *_retval); 1.80 + 1.81 + // Methods called from nsWindow to handle responding to GTK drag 1.82 + // destination signals 1.83 + 1.84 + static nsDragService* GetInstance(); 1.85 + 1.86 + void TargetDataReceived (GtkWidget *aWidget, 1.87 + GdkDragContext *aContext, 1.88 + gint aX, 1.89 + gint aY, 1.90 + GtkSelectionData *aSelection_data, 1.91 + guint aInfo, 1.92 + guint32 aTime); 1.93 + 1.94 + gboolean ScheduleMotionEvent(nsWindow *aWindow, 1.95 + GdkDragContext *aDragContext, 1.96 + nsIntPoint aWindowPoint, 1.97 + guint aTime); 1.98 + void ScheduleLeaveEvent(); 1.99 + gboolean ScheduleDropEvent(nsWindow *aWindow, 1.100 + GdkDragContext *aDragContext, 1.101 + nsIntPoint aWindowPoint, 1.102 + guint aTime); 1.103 + 1.104 + nsWindow* GetMostRecentDestWindow() 1.105 + { 1.106 + return mScheduledTask == eDragTaskNone ? mTargetWindow 1.107 + : mPendingWindow; 1.108 + } 1.109 + 1.110 + // END PUBLIC API 1.111 + 1.112 + // These methods are public only so that they can be called from functions 1.113 + // with C calling conventions. They are called for drags started with the 1.114 + // invisible widget. 1.115 + void SourceEndDragSession(GdkDragContext *aContext, 1.116 + gint aResult); 1.117 + void SourceDataGet(GtkWidget *widget, 1.118 + GdkDragContext *context, 1.119 + GtkSelectionData *selection_data, 1.120 + guint32 aTime); 1.121 + 1.122 + // set the drag icon during drag-begin 1.123 + void SetDragIcon(GdkDragContext* aContext); 1.124 + 1.125 +private: 1.126 + 1.127 + // mScheduledTask indicates what signal has been received from GTK and 1.128 + // so what needs to be dispatched when the scheduled task is run. It is 1.129 + // eDragTaskNone when there is no task scheduled (but the 1.130 + // previous task may still not have finished running). 1.131 + enum DragTask { 1.132 + eDragTaskNone, 1.133 + eDragTaskMotion, 1.134 + eDragTaskLeave, 1.135 + eDragTaskDrop, 1.136 + eDragTaskSourceEnd 1.137 + }; 1.138 + DragTask mScheduledTask; 1.139 + // mTaskSource is the GSource id for the task that is either scheduled 1.140 + // or currently running. It is 0 if no task is scheduled or running. 1.141 + guint mTaskSource; 1.142 + 1.143 + // target/destination side vars 1.144 + // These variables keep track of the state of the current drag. 1.145 + 1.146 + // mPendingWindow, mPendingWindowPoint, mPendingDragContext, and 1.147 + // mPendingTime, carry information from the GTK signal that will be used 1.148 + // when the scheduled task is run. mPendingWindow and mPendingDragContext 1.149 + // will be nullptr if the scheduled task is eDragTaskLeave. 1.150 + nsRefPtr<nsWindow> mPendingWindow; 1.151 + nsIntPoint mPendingWindowPoint; 1.152 + nsCountedRef<GdkDragContext> mPendingDragContext; 1.153 + guint mPendingTime; 1.154 + 1.155 + // mTargetWindow and mTargetWindowPoint record the position of the last 1.156 + // eDragTaskMotion or eDragTaskDrop task that was run or is still running. 1.157 + // mTargetWindow is cleared once the drag has completed or left. 1.158 + nsRefPtr<nsWindow> mTargetWindow; 1.159 + nsIntPoint mTargetWindowPoint; 1.160 + // mTargetWidget and mTargetDragContext are set only while dispatching 1.161 + // motion or drop events. mTime records the corresponding timestamp. 1.162 + nsCountedRef<GtkWidget> mTargetWidget; 1.163 + nsCountedRef<GdkDragContext> mTargetDragContext; 1.164 + guint mTargetTime; 1.165 + 1.166 + // is it OK to drop on us? 1.167 + bool mCanDrop; 1.168 + 1.169 + // have we received our drag data? 1.170 + bool mTargetDragDataReceived; 1.171 + // last data received and its length 1.172 + void *mTargetDragData; 1.173 + uint32_t mTargetDragDataLen; 1.174 + // is the current target drag context contain a list? 1.175 + bool IsTargetContextList(void); 1.176 + // this will get the native data from the last target given a 1.177 + // specific flavor 1.178 + void GetTargetDragData(GdkAtom aFlavor); 1.179 + // this will reset all of the target vars 1.180 + void TargetResetData(void); 1.181 + 1.182 + // source side vars 1.183 + 1.184 + // the source of our drags 1.185 + GtkWidget *mHiddenWidget; 1.186 + // our source data items 1.187 + nsCOMPtr<nsISupportsArray> mSourceDataItems; 1.188 + 1.189 + nsCOMPtr<nsIScriptableRegion> mSourceRegion; 1.190 + 1.191 + // get a list of the sources in gtk's format 1.192 + GtkTargetList *GetSourceList(void); 1.193 + 1.194 + // attempts to create a semi-transparent drag image. Returns TRUE if 1.195 + // successful, FALSE if not 1.196 + bool SetAlphaPixmap(SourceSurface *aPixbuf, 1.197 + GdkDragContext *aContext, 1.198 + int32_t aXOffset, 1.199 + int32_t aYOffset, 1.200 + const nsIntRect &dragRect); 1.201 + 1.202 + gboolean Schedule(DragTask aTask, nsWindow *aWindow, 1.203 + GdkDragContext *aDragContext, 1.204 + nsIntPoint aWindowPoint, guint aTime); 1.205 + 1.206 + // Callback for g_idle_add_full() to run mScheduledTask. 1.207 + static gboolean TaskDispatchCallback(gpointer data); 1.208 + gboolean RunScheduledTask(); 1.209 + void UpdateDragAction(); 1.210 + void DispatchMotionEvents(); 1.211 + void ReplyToDragMotion(); 1.212 + gboolean DispatchDropEvent(); 1.213 +}; 1.214 + 1.215 +#endif // nsDragService_h__ 1.216 +