VirtualBox

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

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

DnD/HostService: More code for host/guest side cancellation handling; simplified.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.8 KB
Line 
1/* $Id: dndmanager.cpp 59832 2016-02-26 10:16:31Z vboxsync $ */
2/** @file
3 * Drag and Drop manager: Handling of DnD messages on the host side.
4 */
5
6/*
7 * Copyright (C) 2011-2016 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;
44
45 try
46 {
47 LogFlowFunc(("uMsg=%RU32, cParms=%RU32, fAppend=%RTbool\n", uMsg, cParms, fAppend));
48
49 DnDMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);
50 if (fAppend)
51 m_dndMessageQueue.append(pMessage);
52 else
53 m_dndMessageQueue.prepend(pMessage);
54
55 rc = VINF_SUCCESS;
56 }
57 catch(std::bad_alloc &)
58 {
59 rc = VERR_NO_MEMORY;
60 }
61
62 LogFlowFuncLeaveRC(rc);
63 return rc;
64}
65
66HGCM::Message* DnDManager::nextHGCMMessage(void)
67{
68 if (m_pCurMsg)
69 return m_pCurMsg->nextHGCMMessage();
70
71 if (m_dndMessageQueue.isEmpty())
72 return NULL;
73
74 return m_dndMessageQueue.first()->nextHGCMMessage();
75}
76
77int DnDManager::nextMessageInfo(uint32_t *puMsg, uint32_t *pcParms)
78{
79 AssertPtrReturn(puMsg, VERR_INVALID_POINTER);
80 AssertPtrReturn(pcParms, VERR_INVALID_POINTER);
81
82 int rc;
83 if (m_pCurMsg)
84 rc = m_pCurMsg->currentMessageInfo(puMsg, pcParms);
85 else
86 {
87 if (m_dndMessageQueue.isEmpty())
88 rc = VERR_NO_DATA;
89 else
90 rc = m_dndMessageQueue.first()->currentMessageInfo(puMsg, pcParms);
91 }
92
93 LogFlowFunc(("Returning puMsg=%RU32, pcParms=%RU32, rc=%Rrc\n", *puMsg, *pcParms, rc));
94 return rc;
95}
96
97int DnDManager::nextMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
98{
99 LogFlowFunc(("uMsg=%RU32, cParms=%RU32\n", uMsg, cParms));
100
101 if (!m_pCurMsg)
102 {
103 /* Check for pending messages in our queue. */
104 if (m_dndMessageQueue.isEmpty())
105 return VERR_NO_DATA;
106
107 m_pCurMsg = m_dndMessageQueue.first();
108 AssertPtr(m_pCurMsg);
109 m_dndMessageQueue.removeFirst();
110 }
111
112 /* Fetch the current message info */
113 int rc = m_pCurMsg->currentMessage(uMsg, cParms, paParms);
114 /* If this message doesn't provide any additional sub messages, clear it. */
115 if (!m_pCurMsg->isMessageWaiting())
116 {
117 delete m_pCurMsg;
118 m_pCurMsg = NULL;
119 }
120
121 /*
122 * If there was an error handling the current message or the user has canceled
123 * the operation, we need to cleanup all pending events and inform the progress
124 * callback about our exit.
125 */
126 if (RT_FAILURE(rc))
127 {
128 /* Clear any pending messages. */
129 clear();
130
131 /* Create a new cancel message to inform the guest + call
132 * the host whether the current transfer was canceled or aborted
133 * due to an error. */
134 try
135 {
136 if (rc == VERR_CANCELLED)
137 LogFlowFunc(("Operation was cancelled\n"));
138
139 Assert(!m_pCurMsg);
140 m_pCurMsg = new DnDHGCancelMessage();
141
142 if (m_pfnProgressCallback)
143 {
144 LogFlowFunc(("Notifying host about aborting operation (%Rrc) ...\n", rc));
145 m_pfnProgressCallback( rc == VERR_CANCELLED
146 ? DragAndDropSvc::DND_PROGRESS_CANCELLED
147 : DragAndDropSvc::DND_PROGRESS_ERROR,
148 100 /* Percent */, rc,
149 m_pvProgressUser);
150 }
151 }
152 catch(std::bad_alloc &)
153 {
154 rc = VERR_NO_MEMORY;
155 }
156 }
157
158 LogFlowFunc(("Message processed with rc=%Rrc\n", rc));
159 return rc;
160}
161
162void DnDManager::clear(void)
163{
164 LogFlowFuncEnter();
165
166 if (m_pCurMsg)
167 {
168 delete m_pCurMsg;
169 m_pCurMsg = NULL;
170 }
171
172 while (!m_dndMessageQueue.isEmpty())
173 {
174 delete m_dndMessageQueue.last();
175 m_dndMessageQueue.removeLast();
176 }
177}
178
179/**
180 * Triggers a rescheduling of the manager's message queue by setting the first
181 * message available in the queue as the current one to process.
182 *
183 * @return IPRT status code. VERR_NO_DATA if not message to process is available at
184 * the time of calling.
185 */
186int DnDManager::doReschedule(void)
187{
188 LogFlowFunc(("Rescheduling ...\n"));
189
190 if (!m_dndMessageQueue.isEmpty())
191 {
192 m_pCurMsg = m_dndMessageQueue.first();
193 m_dndMessageQueue.removeFirst();
194
195 return VINF_SUCCESS;
196 }
197
198 return VERR_NO_DATA;
199}
200
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