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

     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;
    21 }
    22 }
    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
    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
    49  */
    51 class nsDragService : public nsBaseDragService,
    52                       public nsIObserver
    53 {
    54 public:
    55     nsDragService();
    56     virtual ~nsDragService();
    58     NS_DECL_ISUPPORTS_INHERITED
    60     NS_DECL_NSIOBSERVER
    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);
    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);
    78     // Methods called from nsWindow to handle responding to GTK drag
    79     // destination signals
    81     static nsDragService* GetInstance();
    83     void TargetDataReceived          (GtkWidget         *aWidget,
    84                                       GdkDragContext    *aContext,
    85                                       gint               aX,
    86                                       gint               aY,
    87                                       GtkSelectionData  *aSelection_data,
    88                                       guint              aInfo,
    89                                       guint32            aTime);
    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);
   101     nsWindow* GetMostRecentDestWindow()
   102     {
   103         return mScheduledTask == eDragTaskNone ? mTargetWindow
   104             : mPendingWindow;
   105     }
   107     //  END PUBLIC API
   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);
   119     // set the drag icon during drag-begin
   120     void SetDragIcon(GdkDragContext* aContext);
   122 private:
   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;
   140     // target/destination side vars
   141     // These variables keep track of the state of the current drag.
   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;
   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;
   163     // is it OK to drop on us?
   164     bool            mCanDrop;
   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);
   179     // source side vars
   181     // the source of our drags
   182     GtkWidget     *mHiddenWidget;
   183     // our source data items
   184     nsCOMPtr<nsISupportsArray> mSourceDataItems;
   186     nsCOMPtr<nsIScriptableRegion> mSourceRegion;
   188     // get a list of the sources in gtk's format
   189     GtkTargetList *GetSourceList(void);
   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);
   199     gboolean Schedule(DragTask aTask, nsWindow *aWindow,
   200                       GdkDragContext *aDragContext,
   201                       nsIntPoint aWindowPoint, guint aTime);
   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 };
   212 #endif // nsDragService_h__

mercurial