VirtualBox

source: vbox/trunk/src/VBox/HostServices/DragAndDrop/dndmanager.cpp@ 58212

Last change on this file since 58212 was 58212, checked in by vboxsync, 9 years ago

DnD: Updates.

  • Introduced protocol changelog in DragAndDropSvc.h.
  • Implemented protocol v3 with HOST_DND_HG_SND_DATA_HDR message for doing proper object accounting, among other parameters like checksumming and compression flags.
  • Encapsulated a lot of functionality in class hierarchies.
  • Renamed a lot of functions to make the usage more clear.
  • Various other bugfixes.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 KB
Line 
1/* $Id: dndmanager.cpp 58212 2015-10-13 11:49:33Z vboxsync $ */
2/** @file
3 * Drag and Drop manager: Handling of DnD messages on the host side.
4 */
5
6/*
7 * Copyright (C) 2011-2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22
23#ifdef LOG_GROUP
24 #undef LOG_GROUP
25#endif
26#define LOG_GROUP LOG_GROUP_GUEST_DND
27
28#include "dndmanager.h"
29
30#include <VBox/log.h>
31#include <iprt/file.h>
32#include <iprt/dir.h>
33#include <iprt/path.h>
34#include <iprt/uri.h>
35
36
37/*********************************************************************************************************************************
38* DnDManager *
39*********************************************************************************************************************************/
40
41int DnDManager::addMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[], bool fAppend /* = true */)
42{
43 int rc = VINF_SUCCESS;
44
45 LogFlowFunc(("uMsg=%RU32, cParms=%RU32, fAppend=%RTbool\n", uMsg, cParms, fAppend));
46
47 try
48 {
49 DnDMessage *pMessage = NULL;
50
51 switch (uMsg)
52 {
53 case DragAndDropSvc::HOST_DND_HG_EVT_ENTER:
54 {
55 clear();
56 LogFlowFunc(("HOST_DND_HG_EVT_ENTER\n"));
57 break;
58 }
59
60 case DragAndDropSvc::HOST_DND_HG_EVT_MOVE:
61 {
62 LogFlowFunc(("HOST_DND_HG_EVT_MOVE\n"));
63 break;
64 }
65
66 case DragAndDropSvc::HOST_DND_HG_EVT_LEAVE:
67 {
68 LogFlowFunc(("HOST_DND_HG_EVT_LEAVE\n"));
69 break;
70 }
71
72 case DragAndDropSvc::HOST_DND_HG_EVT_DROPPED:
73 {
74 LogFlowFunc(("HOST_DND_HG_EVT_DROPPED\n"));
75 break;
76 }
77
78 case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL:
79 {
80 LogFlowFunc(("HOST_DND_HG_EVT_CANCEL\n"));
81
82 pMessage = new DnDHGCancelMessage();
83 break;
84 }
85
86 case DragAndDropSvc::HOST_DND_HG_SND_DATA_HDR:
87 {
88 LogFlowFunc(("HOST_DND_HG_SND_DATA_HDR\n"));
89 break;
90 }
91
92 case DragAndDropSvc::HOST_DND_HG_SND_DATA:
93 {
94 LogFlowFunc(("HOST_DND_HG_SND_DATA\n"));
95 break;
96 }
97
98 case DragAndDropSvc::HOST_DND_HG_SND_DIR:
99 {
100 LogFlowFunc(("HOST_DND_HG_SND_DIR\n"));
101 break;
102 }
103
104 /* New since protocol version 2 (VBox 5.0). */
105 case DragAndDropSvc::HOST_DND_HG_SND_FILE_HDR:
106 {
107 LogFlowFunc(("HOST_DND_HG_SND_FILE_HDR\n"));
108 break;
109 }
110
111 case DragAndDropSvc::HOST_DND_HG_SND_FILE_DATA:
112 {
113 LogFlowFunc(("HOST_DND_HG_SND_FILE\n"));
114
115 /* No parameter verification here as, depending on the protocol version
116 * being used, the parameter count + types might change. */
117 break;
118 }
119
120#ifdef VBOX_WITH_DRAG_AND_DROP_GH
121 case DragAndDropSvc::HOST_DND_GH_REQ_PENDING:
122 {
123 LogFlowFunc(("HOST_DND_GH_REQ_PENDING\n"));
124 break;
125 }
126
127 case DragAndDropSvc::HOST_DND_GH_EVT_DROPPED:
128 {
129 LogFlowFunc(("HOST_DND_GH_EVT_DROPPED\n"));
130 break;
131 }
132#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
133
134 default:
135 rc = VERR_NOT_IMPLEMENTED;
136 break;
137 }
138
139 if (RT_SUCCESS(rc))
140 {
141 if (!pMessage) /* Generic message needed? */
142 pMessage = new DnDGenericMessage(uMsg, cParms, paParms);
143
144 if (fAppend)
145 m_dndMessageQueue.append(pMessage);
146 else
147 m_dndMessageQueue.prepend(pMessage);
148 }
149 }
150 catch(std::bad_alloc &)
151 {
152 rc = VERR_NO_MEMORY;
153 }
154
155 return rc;
156}
157
158HGCM::Message* DnDManager::nextHGCMMessage(void)
159{
160 if (m_pCurMsg)
161 return m_pCurMsg->nextHGCMMessage();
162
163 if (m_dndMessageQueue.isEmpty())
164 return NULL;
165
166 return m_dndMessageQueue.first()->nextHGCMMessage();
167}
168
169int DnDManager::nextMessageInfo(uint32_t *puMsg, uint32_t *pcParms)
170{
171 AssertPtrReturn(puMsg, VERR_INVALID_POINTER);
172 AssertPtrReturn(pcParms, VERR_INVALID_POINTER);
173
174 int rc;
175 if (m_pCurMsg)
176 rc = m_pCurMsg->currentMessageInfo(puMsg, pcParms);
177 else
178 {
179 if (m_dndMessageQueue.isEmpty())
180 rc = VERR_NO_DATA;
181 else
182 rc = m_dndMessageQueue.first()->currentMessageInfo(puMsg, pcParms);
183 }
184
185 LogFlowFunc(("Returning puMsg=%RU32, pcParms=%RU32, rc=%Rrc\n", *puMsg, *pcParms, rc));
186 return rc;
187}
188
189int DnDManager::nextMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
190{
191 LogFlowFunc(("uMsg=%RU32, cParms=%RU32\n", uMsg, cParms));
192
193 if (!m_pCurMsg)
194 {
195 /* Check for pending messages in our queue. */
196 if (m_dndMessageQueue.isEmpty())
197 return VERR_NO_DATA;
198
199 m_pCurMsg = m_dndMessageQueue.first();
200 AssertPtr(m_pCurMsg);
201 m_dndMessageQueue.removeFirst();
202 }
203
204 /* Fetch the current message info */
205 int rc = m_pCurMsg->currentMessage(uMsg, cParms, paParms);
206 /* If this message doesn't provide any additional sub messages, clear it. */
207 if (!m_pCurMsg->isMessageWaiting())
208 {
209 delete m_pCurMsg;
210 m_pCurMsg = NULL;
211 }
212
213 /*
214 * If there was an error handling the current message or the user has canceled
215 * the operation, we need to cleanup all pending events and inform the progress
216 * callback about our exit.
217 */
218 if (RT_FAILURE(rc))
219 {
220 /* Clear any pending messages. */
221 clear();
222
223 /* Create a new cancel message to inform the guest + call
224 * the host whether the current transfer was canceled or aborted
225 * due to an error. */
226 try
227 {
228 if (rc == VERR_CANCELLED)
229 LogFlowFunc(("Operation was cancelled\n"));
230
231 Assert(!m_pCurMsg);
232 m_pCurMsg = new DnDHGCancelMessage();
233
234 if (m_pfnProgressCallback)
235 {
236 LogFlowFunc(("Notifying host about aborting operation (%Rrc) ...\n", rc));
237 m_pfnProgressCallback( rc == VERR_CANCELLED
238 ? DragAndDropSvc::DND_PROGRESS_CANCELLED
239 : DragAndDropSvc::DND_PROGRESS_ERROR,
240 100 /* Percent */, rc,
241 m_pvProgressUser);
242 }
243 }
244 catch(std::bad_alloc &)
245 {
246 rc = VERR_NO_MEMORY;
247 }
248 }
249
250 LogFlowFunc(("Message processed with rc=%Rrc\n", rc));
251 return rc;
252}
253
254void DnDManager::clear(void)
255{
256 if (m_pCurMsg)
257 {
258 delete m_pCurMsg;
259 m_pCurMsg = NULL;
260 }
261
262 while (!m_dndMessageQueue.isEmpty())
263 {
264 delete m_dndMessageQueue.last();
265 m_dndMessageQueue.removeLast();
266 }
267}
268
269/**
270 * Triggers a rescheduling of the manager's message queue by setting the first
271 * message available in the queue as the current one to process.
272 *
273 * @return IPRT status code. VERR_NO_DATA if not message to process is available at
274 * the time of calling.
275 */
276int DnDManager::doReschedule(void)
277{
278 LogFlowFunc(("Rescheduling ...\n"));
279
280 if (!m_dndMessageQueue.isEmpty())
281 {
282 m_pCurMsg = m_dndMessageQueue.first();
283 m_dndMessageQueue.removeFirst();
284
285 return VINF_SUCCESS;
286 }
287
288 return VERR_NO_DATA;
289}
290
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette