widget/gtk/nsDragService.h

changeset 0
6474c204b198
     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 +

mercurial