// @(#)root/gui:$Id$
// Author: Bertrand Bellenot   19/04/07

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TDNDManager
#define ROOT_TDNDManager

#ifndef ROOT_TGFrame
#include "TGFrame.h"
#endif

class TGMainFrame;
class TGDragWindow;
class TTimer;

//----------------------------------------------------------------------

class TGDragWindow : public TGFrame {

protected:
   static Cursor_t fgDefaultCursor; // Default Cursor

protected:
   virtual void DoRedraw();

   Window_t fInput;                 // Input Window
   Pixmap_t fPic, fMask;            // Pixmaps used as Window shape
   UInt_t   fPw, fPh;               // Hot point coordinates (x and y)

public:
   TGDragWindow(const TGWindow *p, Pixmap_t pic, Pixmap_t mask,
                UInt_t options = kChildFrame, Pixel_t back = GetWhitePixel());
   virtual ~TGDragWindow();

   virtual TGDimension GetDefaultSize() const { return TGDimension(fPw, fPh); }

   virtual void MapWindow();
   virtual void UnmapWindow();
   virtual void RaiseWindow();
   virtual void LowerWindow();
   virtual void MapRaised();

   virtual void Layout();

   Window_t GetInputId() const { return fInput; }
   Bool_t HasWindow(Window_t w) const { return (w == fId || w == fInput); }

   ClassDef(TGDragWindow, 0) // Window used for dragging
};

//----------------------------------------------------------------------

//_____________________________________________________________________________
//
// TDNDData
//
// Drag and drop data container.
//_____________________________________________________________________________

class TDNDData : public TObject {
private:
   TDNDData(const TDNDData&);            // Not implemented
   TDNDData& operator=(const TDNDData&); // Not implemented

public:
   TDNDData(Atom_t dt = kNone, void *d = 0, Int_t len = 0, Atom_t act = kNone) :
      fDataType(dt), fAction(act), fData(d), fDataLength(len) {}
   ~TDNDData() {}

   Atom_t    fDataType;       // Data type description
   Atom_t    fAction;         // Action description
   void     *fData;           // Actual data
   Int_t     fDataLength;     // Length of data

   ClassDef(TDNDData, 0) // Drag and drop specific data
};

//----------------------------------------------------------------------

class TGDNDManager : public TObject {

private:
   TGDNDManager(const TGDNDManager&);            // Not implemented
   TGDNDManager& operator=(const TGDNDManager&); // Not implemented

protected:
   TGFrame       *fMain;                         // pointer on TGMainFrame
   Atom_t         fVersion;                      // not really an Atom, but a long
   Atom_t        *fTypelist, *fDraggerTypes;     // lists of DND types
   Atom_t         fDropType;                     // drop type
   Atom_t         fAcceptedAction, fLocalAction; // accepted and local actions

   Bool_t         fDragging;                     // kTRUE while dragging
   Bool_t         fDropAccepted;                 // kTRUE if drop accepted
   Bool_t         fStatusPending;                // kTRUE if status is pending
   Bool_t         fUseVersion;                   // kTRUE if DND version is used
   Bool_t         fProxyOurs;                    // kTRUE if root proxy is ours
   Window_t       fSource, fTarget;              // source and target windows
   Bool_t         fTargetIsDNDAware;             // kTRUE if target is DND aware
   UInt_t         fGrabEventMask;                // pointer grab event mask
   TGFrame       *fLocalSource, *fLocalTarget;   // local source and target

   TTimer        *fDropTimeout;                  // drop timeout
   TGDragWindow  *fDragWin;                      // drag window

   Pixmap_t       fPic, fMask;                   // pixmap used for the drag window
   Int_t          fHotx, fHoty;                  // hot point coordinates
   Cursor_t       fDNDNoDropCursor;              // no drop cursor type

protected:
   static Atom_t  fgDNDAware, fgDNDSelection, fgDNDProxy;
   static Atom_t  fgDNDEnter, fgDNDLeave, fgDNDPosition, fgDNDStatus;
   static Atom_t  fgDNDDrop, fgDNDFinished;
   static Atom_t  fgDNDVersion;
   static Atom_t  fgDNDActionCopy, fgDNDActionMove, fgDNDActionLink;
   static Atom_t  fgDNDActionAsk, fgDNDActionPrivate;
   static Atom_t  fgDNDTypeList, fgDNDActionList, fgDNDActionDescrip;
   static Atom_t  fgXCDNDData;

   static Bool_t  fgInit;
   static Atom_t  fgXAWMState;

protected:
   void           InitAtoms();
   Window_t       GetRootProxy();
   Window_t       FindWindow(Window_t root, Int_t x, Int_t y, Int_t maxd);
   Bool_t         IsDNDAware(Window_t win, Atom_t *typelist = 0);
   Bool_t         IsTopLevel(Window_t win);

   void           SendDNDEnter(Window_t target);
   void           SendDNDLeave(Window_t target);
   void           SendDNDPosition(Window_t target, int x, int y,
                                  Atom_t action, Time_t timestamp);
   void           SendDNDStatus(Window_t target, Atom_t action);
   void           SendDNDDrop(Window_t target);
   void           SendDNDFinished(Window_t src);

   Bool_t         HandleDNDEnter(Window_t src, long vers, Atom_t dataTypes[3]);
   Bool_t         HandleDNDLeave(Window_t src);
   Bool_t         HandleDNDPosition(Window_t src, int x_root, int y_root, Atom_t action, Time_t timestamp);
   Bool_t         HandleDNDStatus(Window_t from, int accepted,
                                  Rectangle_t skip, Atom_t action);
   Bool_t         HandleDNDDrop(Window_t src, Time_t timestamp);
   Bool_t         HandleDNDFinished(Window_t target);

public:
   TGDNDManager(TGFrame *toplevel, Atom_t *typelist);
   virtual ~TGDNDManager();

   Bool_t         HandleClientMessage(Event_t *event);
   Bool_t         HandleSelectionRequest(Event_t *event);
   Bool_t         HandleSelection(Event_t *event);

   Bool_t         HandleTimer(TTimer *t);

  //--- called by widgets

   TGFrame       *GetMainFrame() const { return fMain; }
   void           SetMainFrame(TGFrame *main) { fMain = main; }
   void           SetDragPixmap(Pixmap_t pic, Pixmap_t mask, Int_t hot_x, Int_t hot_y);
   Bool_t         SetRootProxy();
   Bool_t         RemoveRootProxy();

   Bool_t         StartDrag(TGFrame *src, Int_t x_root, Int_t y_root,
                            Window_t grabWin = kNone);
   Bool_t         Drag(Int_t x_root, Int_t y_root, Atom_t action, Time_t timestamp);
   Bool_t         Drop();
   Bool_t         EndDrag();

   Bool_t         IsDragging() const { return fDragging; }
   Window_t       GetSource() const { return fSource; }
   Window_t       GetTarget() const { return fTarget; }
   Atom_t        *GetTypeList() const { return fTypelist; }

   static Atom_t  GetDNDAware();
   static Atom_t  GetDNDSelection();
   static Atom_t  GetDNDProxy();
   static Atom_t  GetDNDEnter();
   static Atom_t  GetDNDLeave();
   static Atom_t  GetDNDPosition();
   static Atom_t  GetDNDStatus();
   static Atom_t  GetDNDDrop();
   static Atom_t  GetDNDFinished();
   static Atom_t  GetDNDVersion();
   static Atom_t  GetDNDActionCopy();
   static Atom_t  GetDNDActionMove();
   static Atom_t  GetDNDActionLink();
   static Atom_t  GetDNDActionAsk();
   static Atom_t  GetDNDActionPrivate();
   static Atom_t  GetDNDTypeList();
   static Atom_t  GetDNDActionList();
   static Atom_t  GetDNDActionDescrip();
   static Atom_t  GetXCDNDData();

   ClassDef(TGDNDManager, 0) // The main Drag and Drop Manager
};

R__EXTERN TGDNDManager *gDNDManager; // global drag and drop manager

#endif  // ROOT_TDNDManager

 TGDNDManager.h:1
 TGDNDManager.h:2
 TGDNDManager.h:3
 TGDNDManager.h:4
 TGDNDManager.h:5
 TGDNDManager.h:6
 TGDNDManager.h:7
 TGDNDManager.h:8
 TGDNDManager.h:9
 TGDNDManager.h:10
 TGDNDManager.h:11
 TGDNDManager.h:12
 TGDNDManager.h:13
 TGDNDManager.h:14
 TGDNDManager.h:15
 TGDNDManager.h:16
 TGDNDManager.h:17
 TGDNDManager.h:18
 TGDNDManager.h:19
 TGDNDManager.h:20
 TGDNDManager.h:21
 TGDNDManager.h:22
 TGDNDManager.h:23
 TGDNDManager.h:24
 TGDNDManager.h:25
 TGDNDManager.h:26
 TGDNDManager.h:27
 TGDNDManager.h:28
 TGDNDManager.h:29
 TGDNDManager.h:30
 TGDNDManager.h:31
 TGDNDManager.h:32
 TGDNDManager.h:33
 TGDNDManager.h:34
 TGDNDManager.h:35
 TGDNDManager.h:36
 TGDNDManager.h:37
 TGDNDManager.h:38
 TGDNDManager.h:39
 TGDNDManager.h:40
 TGDNDManager.h:41
 TGDNDManager.h:42
 TGDNDManager.h:43
 TGDNDManager.h:44
 TGDNDManager.h:45
 TGDNDManager.h:46
 TGDNDManager.h:47
 TGDNDManager.h:48
 TGDNDManager.h:49
 TGDNDManager.h:50
 TGDNDManager.h:51
 TGDNDManager.h:52
 TGDNDManager.h:53
 TGDNDManager.h:54
 TGDNDManager.h:55
 TGDNDManager.h:56
 TGDNDManager.h:57
 TGDNDManager.h:58
 TGDNDManager.h:59
 TGDNDManager.h:60
 TGDNDManager.h:61
 TGDNDManager.h:62
 TGDNDManager.h:63
 TGDNDManager.h:64
 TGDNDManager.h:65
 TGDNDManager.h:66
 TGDNDManager.h:67
 TGDNDManager.h:68
 TGDNDManager.h:69
 TGDNDManager.h:70
 TGDNDManager.h:71
 TGDNDManager.h:72
 TGDNDManager.h:73
 TGDNDManager.h:74
 TGDNDManager.h:75
 TGDNDManager.h:76
 TGDNDManager.h:77
 TGDNDManager.h:78
 TGDNDManager.h:79
 TGDNDManager.h:80
 TGDNDManager.h:81
 TGDNDManager.h:82
 TGDNDManager.h:83
 TGDNDManager.h:84
 TGDNDManager.h:85
 TGDNDManager.h:86
 TGDNDManager.h:87
 TGDNDManager.h:88
 TGDNDManager.h:89
 TGDNDManager.h:90
 TGDNDManager.h:91
 TGDNDManager.h:92
 TGDNDManager.h:93
 TGDNDManager.h:94
 TGDNDManager.h:95
 TGDNDManager.h:96
 TGDNDManager.h:97
 TGDNDManager.h:98
 TGDNDManager.h:99
 TGDNDManager.h:100
 TGDNDManager.h:101
 TGDNDManager.h:102
 TGDNDManager.h:103
 TGDNDManager.h:104
 TGDNDManager.h:105
 TGDNDManager.h:106
 TGDNDManager.h:107
 TGDNDManager.h:108
 TGDNDManager.h:109
 TGDNDManager.h:110
 TGDNDManager.h:111
 TGDNDManager.h:112
 TGDNDManager.h:113
 TGDNDManager.h:114
 TGDNDManager.h:115
 TGDNDManager.h:116
 TGDNDManager.h:117
 TGDNDManager.h:118
 TGDNDManager.h:119
 TGDNDManager.h:120
 TGDNDManager.h:121
 TGDNDManager.h:122
 TGDNDManager.h:123
 TGDNDManager.h:124
 TGDNDManager.h:125
 TGDNDManager.h:126
 TGDNDManager.h:127
 TGDNDManager.h:128
 TGDNDManager.h:129
 TGDNDManager.h:130
 TGDNDManager.h:131
 TGDNDManager.h:132
 TGDNDManager.h:133
 TGDNDManager.h:134
 TGDNDManager.h:135
 TGDNDManager.h:136
 TGDNDManager.h:137
 TGDNDManager.h:138
 TGDNDManager.h:139
 TGDNDManager.h:140
 TGDNDManager.h:141
 TGDNDManager.h:142
 TGDNDManager.h:143
 TGDNDManager.h:144
 TGDNDManager.h:145
 TGDNDManager.h:146
 TGDNDManager.h:147
 TGDNDManager.h:148
 TGDNDManager.h:149
 TGDNDManager.h:150
 TGDNDManager.h:151
 TGDNDManager.h:152
 TGDNDManager.h:153
 TGDNDManager.h:154
 TGDNDManager.h:155
 TGDNDManager.h:156
 TGDNDManager.h:157
 TGDNDManager.h:158
 TGDNDManager.h:159
 TGDNDManager.h:160
 TGDNDManager.h:161
 TGDNDManager.h:162
 TGDNDManager.h:163
 TGDNDManager.h:164
 TGDNDManager.h:165
 TGDNDManager.h:166
 TGDNDManager.h:167
 TGDNDManager.h:168
 TGDNDManager.h:169
 TGDNDManager.h:170
 TGDNDManager.h:171
 TGDNDManager.h:172
 TGDNDManager.h:173
 TGDNDManager.h:174
 TGDNDManager.h:175
 TGDNDManager.h:176
 TGDNDManager.h:177
 TGDNDManager.h:178
 TGDNDManager.h:179
 TGDNDManager.h:180
 TGDNDManager.h:181
 TGDNDManager.h:182
 TGDNDManager.h:183
 TGDNDManager.h:184
 TGDNDManager.h:185
 TGDNDManager.h:186
 TGDNDManager.h:187
 TGDNDManager.h:188
 TGDNDManager.h:189
 TGDNDManager.h:190
 TGDNDManager.h:191
 TGDNDManager.h:192
 TGDNDManager.h:193
 TGDNDManager.h:194
 TGDNDManager.h:195
 TGDNDManager.h:196
 TGDNDManager.h:197
 TGDNDManager.h:198
 TGDNDManager.h:199
 TGDNDManager.h:200
 TGDNDManager.h:201
 TGDNDManager.h:202
 TGDNDManager.h:203
 TGDNDManager.h:204
 TGDNDManager.h:205
 TGDNDManager.h:206
 TGDNDManager.h:207
 TGDNDManager.h:208