summaryrefslogtreecommitdiff
path: root/open-vm-tools/services/plugins/dndcp/dndUIX11.h
blob: 6a98def38298bd6d9a776f76de977c29ea0f248e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*********************************************************
 * Copyright (C) 2009 VMware, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation version 2.1 and no later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
 *
 *********************************************************/

/**
 * @file dndUIX11.h
 *
 *    Implement the methods that allow DnD between host and guest for
 *    protocols V3 or greater.
 *
 */

#ifndef __DND_UI_X11_H__
#define __DND_UI_X11_H__

#include "stringxx/string.hh"

extern "C" {
#include "debug.h"
#include "dnd.h"
#include "str.h"
#include "util.h"
#include "vmblock.h"
#include "dndClipboard.h"
#include "dynbuf.h"
#include "../dnd/dndFileContentsUtil.h"
#include "dynxdr.h"
#include "cpNameUtil.h"
#include "posix.h"
#include "vmware/tools/guestrpc.h"
#include "vmware/tools/plugin.h"
}

#include "guestDnD.hh"
#include "dndFileList.hh"
#include "dragDetWndX11.h"

struct DblLnkLst_Links;

/**
 * The DnDUI class implements the UI portion of DnD V3 and greater
 * versions of the protocol.
 */
class DnDUIX11
   : public sigc::trackable
{
public:
   DnDUIX11(ToolsAppCtx *ctx);
   ~DnDUIX11();
   bool Init();
   void VmxDnDVersionChanged(RpcChannel *chan, uint32 version);
   void SetDnDAllowed(bool isDnDAllowed)
      {ASSERT(mDnD); mDnD->SetDnDAllowed(isDnDAllowed);}
   void SetBlockControl(DnDBlockControl *blockCtrl);
   void SetUnityMode(Bool mode)
      {mUnityMode = mode;};

   DragDetWnd *GetFullDetWnd() {return mDetWnd;}
   GtkWidget *GetDetWndAsWidget();

private:
   /*
    * Blocking FS Helper Functions.
    */
   void AddBlock();
   void RemoveBlock();

   bool TryXTestFakeDeviceButtonEvent();

   /*
    * Callbacks from Common DnD layer.
    */
   void ResetUI();
   void OnMoveMouse(int32 x, int32 y);

   /*
    * Source functions for HG DnD.
    */
   void OnSrcDragBegin(const CPClipboard *clip, std::string stagingDir);
   void OnSrcDrop();

   /*
    * Called when HG Dnd is completed.
    */
   void OnSrcCancel();

   /*
    * Called when GH DnD is completed.
    */
   void OnPrivateDrop(int32 x, int32 y);
   void OnDestCancel();

   /*
    * Source functions for file transfer.
    */
   void OnGetFilesDone(bool success);

   /*
    * Callbacks for showing/hiding detection window.
    */
   void OnUpdateDetWnd(bool bShow, int32 x, int32 y);
   void OnUpdateUnityDetWnd(bool bShow, uint32 unityWndId, bool bottom);
   void OnDestMoveDetWndToMousePos();

   /*
    * Gtk+ Callbacks: Drag Destination.
    */
   void OnGtkDragDataReceived(const Glib::RefPtr<Gdk::DragContext> &dc,
                              int x, int y, const Gtk::SelectionData &sd,
                              guint info, guint time);
   bool OnGtkDragDrop(const Glib::RefPtr<Gdk::DragContext> &dc, int x, int y,
                      guint time);
   void OnGtkDragLeave(const Glib::RefPtr<Gdk::DragContext> &dc, guint time);
   bool OnGtkDragMotion(const Glib::RefPtr<Gdk::DragContext> &dc, int x,
                        int y, guint time);

   /*
    * Gtk+ Callbacks: Drag Source.
    */
   void OnGtkDragBegin(const Glib::RefPtr<Gdk::DragContext>& context);
   void OnGtkDragDataGet(const Glib::RefPtr<Gdk::DragContext>& context,
                         Gtk::SelectionData& selection_data, guint info,
                         guint time);
   void OnGtkDragEnd(const Glib::RefPtr<Gdk::DragContext>& context);
   /*
    * Source functions for HG DnD. Makes calls to common layer.
    */
   void SourceDragStartDone();
   void SourceUpdateFeedback(DND_DROPEFFECT effect);

   /*
    * Target function for GH DnD. Makes call to common layer.
    */
   void TargetDragEnter();

   /*
    * Other signal handlers for tracing.
    */

   bool GtkEnterEventCB(GdkEventCrossing *event);
   bool GtkLeaveEventCB(GdkEventCrossing *event);
   bool GtkMapEventCB(GdkEventAny *event);
   bool GtkUnmapEventCB(GdkEventAny *event);
   void GtkRealizeEventCB();
   void GtkUnrealizeEventCB();
   bool GtkMotionNotifyEventCB(GdkEventMotion *event);
   bool GtkConfigureEventCB(GdkEventConfigure *event);
   bool GtkButtonPressEventCB(GdkEventButton *event);
   bool GtkButtonReleaseEventCB(GdkEventButton *event);

   /*
    * Misc methods.
    */
   void InitGtk();

   bool SetCPClipboardFromGtk(const Gtk::SelectionData& sd);
   bool RequestData(const Glib::RefPtr<Gdk::DragContext> &dc,
                    guint timeValue);
   std::string GetLastDirName(const std::string &str);
   utf::utf8string GetNextPath(utf::utf8string &str, size_t& index);

   static DND_DROPEFFECT ToDropEffect(const Gdk::DragAction action);
   static unsigned long GetTimeInMillis();

   bool SendFakeXEvents(const bool showWidget, const bool buttonEvent,
                        const bool buttonPress, const bool moveWindow,
                        const bool coordsProvided,
                        const int xCoord, const int yCoord);
   bool SendFakeMouseMove(const int x, const int y);
   bool WriteFileContentsToStagingDir();

   static inline bool TargetIsPlainText(const utf::string& target) {
      return    target == TARGET_NAME_STRING
             || target == TARGET_NAME_TEXT_PLAIN
             || target == TARGET_NAME_UTF8_STRING
             || target == TARGET_NAME_COMPOUND_TEXT;
   }

   static inline bool TargetIsRichText(const utf::string& target) {
      return    target == TARGET_NAME_APPLICATION_RTF
             || target == TARGET_NAME_TEXT_RICHTEXT;
   }

   void OnWorkAreaChanged(Glib::RefPtr<Gdk::Screen> screen);

   ToolsAppCtx *mCtx;
   GuestDnDMgr *mDnD;
   std::string mHGStagingDir;
   utf::string mHGFileContentsUriList;
   DragDetWnd *mDetWnd;
   CPClipboard mClipboard;
   DnDBlockControl *mBlockCtrl;
   DND_FILE_TRANSFER_STATUS mHGGetFileStatus;
   int mHGEffect;
   bool mBlockAdded;

   /* State to determine if drag motion is a drag enter. */
   bool mGHDnDInProgress;
   /* Icon updates from the guest. */
   /* Only update mouse when we have clipboard contents from the host. */
   bool mGHDnDDataReceived;
   bool mGHDnDDropOccurred;
   bool mUnityMode;
   bool mInHGDrag;
   DND_DROPEFFECT mEffect;
   int32 mMousePosX;
   int32 mMousePosY;
   GdkDragContext *mDragCtx;
   int mNumPendingRequest;
   unsigned long mDestDropTime;
   uint64 mTotalFileSize;

   /*
    * Upper left corner of our work area, a safe place for us to place
    * our detection window without clashing with a windows parented to the
    * composite overlay window.
    */
   Gdk::Point mOrigin;
};

#endif // __DND_UI_X11_H__