1
/*********************************************************
2
* Copyright (C) 2010 VMware, Inc. All rights reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU Lesser General Public License as published
6
* by the Free Software Foundation version 2.1 and no later version.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
11
* License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17
*********************************************************/
22
* Implementation of common layer GuestDnDDest object for guest.
26
#include "guestDnD.hh"
29
#include "dndClipboard.h"
37
* @param[in] mgr guest DnD manager
40
GuestDnDDest::GuestDnDDest(GuestDnDMgr *mgr)
44
mMgr->GetRpc()->destPrivDragEnterChanged.connect(
45
sigc::mem_fun(this, &GuestDnDDest::OnRpcPrivDragEnter));
46
mMgr->GetRpc()->destPrivDragLeaveChanged.connect(
47
sigc::mem_fun(this, &GuestDnDDest::OnRpcPrivDragLeave));
48
mMgr->GetRpc()->destPrivDropChanged.connect(
49
sigc::mem_fun(this, &GuestDnDDest::OnRpcPrivDrop));
50
mMgr->GetRpc()->destDropChanged.connect(
51
sigc::mem_fun(this, &GuestDnDDest::OnRpcDrop));
52
mMgr->GetRpc()->destCancelChanged.connect(
53
sigc::mem_fun(this, &GuestDnDDest::OnRpcCancel));
55
CPClipboard_Init(&mClipboard);
63
GuestDnDDest::~GuestDnDDest(void)
65
CPClipboard_Destroy(&mClipboard);
70
* Guest UI got dragEnter with valid data. Send dragEnter cmd to controller.
72
* @param[in] clip cross-platform clipboard data.
76
GuestDnDDest::UIDragEnter(const CPClipboard *clip)
78
if (!mMgr->IsDragEnterAllowed()) {
79
Debug("%s: not allowed.\n", __FUNCTION__);
83
Debug("%s: entering.\n", __FUNCTION__);
85
if (GUEST_DND_DEST_DRAGGING == mMgr->GetState() ||
86
GUEST_DND_PRIV_DRAGGING == mMgr->GetState()) {
88
* In GH DnD case, if DnD already happened, user may drag back into guest
89
* VM and drag into the detection window again, and trigger the
90
* DragEnter. In this case, ignore the DragEnter.
92
Debug("%s: already in state %d for GH DnD, ignoring.\n",
93
__FUNCTION__, mMgr->GetState());
97
if (GUEST_DND_SRC_DRAGGING == mMgr->GetState()) {
99
* In HG DnD case, if DnD already happened, user may also drag into the
100
* detection window again. The DragEnter should also be ignored.
102
Debug("%s: already in SRC_DRAGGING state, ignoring\n", __FUNCTION__);
107
* In Unity mode, there is no QueryPendingDrag signal, so may get called
110
if (mMgr->GetState() != GUEST_DND_QUERY_EXITING &&
111
mMgr->GetState() != GUEST_DND_READY) {
112
Debug("%s: Bad state: %d, reset\n", __FUNCTION__, mMgr->GetState());
116
CPClipboard_Clear(&mClipboard);
117
CPClipboard_Copy(&mClipboard, clip);
119
if (!mMgr->GetRpc()->DestDragEnter(mMgr->GetSessionId(), clip)) {
120
Debug("%s: DestDragEnter failed\n", __FUNCTION__);
124
mMgr->SetState(GUEST_DND_DEST_DRAGGING);
125
Debug("%s: state changed to DEST_DRAGGING\n", __FUNCTION__);
134
* User drags back to guest during GH DnD. Change state machine to
135
* PRIV_DRAGGING state.
137
* @param[in] sessionId active session id the controller assigned.
141
GuestDnDDest::OnRpcPrivDragEnter(uint32 sessionId)
143
Debug("%s: entering.\n", __FUNCTION__);
145
if (GUEST_DND_DEST_DRAGGING != mMgr->GetState()) {
146
Debug("%s: Bad state: %d, reset\n", __FUNCTION__, mMgr->GetState());
150
mMgr->SetState(GUEST_DND_PRIV_DRAGGING);
151
Debug("%s: state changed to PRIV_DRAGGING\n", __FUNCTION__);
160
* User drags away from guest during GH DnD. Change state machine to
161
* SRC_DRAGGING state.
163
* @param[in] sessionId active session id the controller assigned.
164
* @param[in] x mouse position x.
165
* @param[in] y mouse position y.
169
GuestDnDDest::OnRpcPrivDragLeave(uint32 sessionId,
173
Debug("%s: entering.\n", __FUNCTION__);
175
if (GUEST_DND_PRIV_DRAGGING != mMgr->GetState()) {
176
Debug("%s: Bad state: %d, reset\n", __FUNCTION__, mMgr->GetState());
180
mMgr->SetState(GUEST_DND_DEST_DRAGGING);
181
mMgr->destMoveDetWndToMousePosChanged.emit();
182
Debug("%s: state changed to DEST_DRAGGING\n", __FUNCTION__);
191
* User drops inside guest during GH DnD. Simulate the mouse drop, hide
192
* detection window, and reset state machine.
194
* @param[in] sessionId active session id the controller assigned.
195
* @param[in] x mouse position x.
196
* @param[in] y mouse position y.
200
GuestDnDDest::OnRpcPrivDrop(uint32 sessionId,
204
mMgr->privDropChanged.emit(x, y);
206
mMgr->SetState(GUEST_DND_READY);
207
Debug("%s: state changed to GUEST_DND_READY, session id changed to 0\n",
213
* User drops outside of guest during GH DnD. Simply cancel the local DnD.
215
* @param[in] sessionId active session id the controller assigned.
216
* @param[in] x mouse position x.
217
* @param[in] y mouse position y.
221
GuestDnDDest::OnRpcDrop(uint32 sessionId,
225
OnRpcCancel(sessionId);
230
* Cancel current GH DnD.
232
* @param[in] sessionId active session id the controller assigned.
236
GuestDnDDest::OnRpcCancel(uint32 sessionId)
238
mMgr->DelayHideDetWnd();
239
mMgr->RemoveUngrabTimeout();
240
mMgr->destCancelChanged.emit();
241
mMgr->SetState(GUEST_DND_READY);
242
Debug("%s: state changed to GUEST_DND_READY, session id changed to 0\n",