VirtualBox

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

Last change on this file since 97731 was 97731, checked in by vboxsync, 2 years ago

DnD/Host service: Added DumpQueue() for debug builds, and also make use of DnDGuestMsgToStr() + DnDHostMsgToStr().

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.2 KB
Line 
1/* $Id: dndmanager.cpp 97731 2022-12-02 15:37:16Z vboxsync $ */
2/** @file
3 * Drag and Drop manager: Handling of DnD messages on the host side.
4 */
5
6/*
7 * Copyright (C) 2011-2022 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32
33#ifdef LOG_GROUP
34 #undef LOG_GROUP
35#endif
36#define LOG_GROUP LOG_GROUP_GUEST_DND
37
38#include "dndmanager.h"
39
40#include <VBox/log.h>
41#include <iprt/file.h>
42#include <iprt/dir.h>
43#include <iprt/path.h>
44#include <iprt/uri.h>
45
46
47/*********************************************************************************************************************************
48* DnDManager *
49*********************************************************************************************************************************/
50
51/**
52 * Adds a DnD message to the manager's queue.
53 *
54 * @returns IPRT status code.
55 * @param pMsg Pointer to DnD message to add. The queue then owns the pointer.
56 * @param fAppend Whether to append or prepend the message to the queue.
57 */
58int DnDManager::AddMsg(DnDMessage *pMsg, bool fAppend /* = true */)
59{
60 AssertPtrReturn(pMsg, VERR_INVALID_POINTER);
61
62 LogFlowFunc(("uMsg=%s (%#x), cParms=%RU32, fAppend=%RTbool\n",
63 DnDHostMsgToStr(pMsg->GetType()), pMsg->GetType(), pMsg->GetParamCount(), fAppend));
64
65 if (fAppend)
66 m_queueMsg.append(pMsg);
67 else
68 m_queueMsg.prepend(pMsg);
69
70#ifdef DEBUG
71 DumpQueue();
72#endif
73
74 /** @todo Catch / handle OOM? */
75
76 return VINF_SUCCESS;
77}
78
79/**
80 * Adds a DnD message to the manager's queue.
81 *
82 * @returns IPRT status code.
83 * @param uMsg Type (function number) of message to add.
84 * @param cParms Number of parameters of message to add.
85 * @param paParms Array of parameters of message to add.
86 * @param fAppend Whether to append or prepend the message to the queue.
87 */
88int DnDManager::AddMsg(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[], bool fAppend /* = true */)
89{
90 int rc;
91
92 try
93 {
94 DnDMessage *pMsg = new DnDGenericMessage(uMsg, cParms, paParms);
95 rc = AddMsg(pMsg, fAppend);
96 }
97 catch(std::bad_alloc &)
98 {
99 rc = VERR_NO_MEMORY;
100 }
101
102 LogFlowFuncLeaveRC(rc);
103 return rc;
104}
105
106#ifdef DEBUG
107void DnDManager::DumpQueue(void)
108{
109 LogFunc(("Current queue (%zu items, FIFO) is: %s", m_queueMsg.size(), m_queueMsg.isEmpty() ? "<Empty>" : ""));
110 for (size_t i = 0; i < m_queueMsg.size(); ++i)
111 Log(("%s ", DnDHostMsgToStr(m_queueMsg[i]->GetType())));
112 Log(("\n"));
113}
114#endif /* DEBUG */
115
116/**
117 * Retrieves information about the next message in the queue.
118 *
119 * @returns IPRT status code. VERR_NO_DATA if no next message is available.
120 * @param puType Where to store the message type.
121 * @param pcParms Where to store the message parameter count.
122 */
123int DnDManager::GetNextMsgInfo(uint32_t *puType, uint32_t *pcParms)
124{
125 AssertPtrReturn(puType, VERR_INVALID_POINTER);
126 AssertPtrReturn(pcParms, VERR_INVALID_POINTER);
127
128 int rc;
129
130#ifdef DEBUG
131 DumpQueue();
132#endif
133
134 if (m_queueMsg.isEmpty())
135 {
136 rc = VERR_NO_DATA;
137 }
138 else
139 {
140 DnDMessage *pMsg = m_queueMsg.first();
141 AssertPtr(pMsg);
142
143 *puType = pMsg->GetType();
144 *pcParms = pMsg->GetParamCount();
145
146 rc = VINF_SUCCESS;
147 }
148
149 LogFlowFunc(("Returning uMsg=%s (%#x), cParms=%RU32, rc=%Rrc\n", DnDHostMsgToStr(*puType), *puType, *pcParms, rc));
150 return rc;
151}
152
153/**
154 * Retrieves the next queued up message and removes it from the queue on success.
155 * Will return VERR_NO_DATA if no next message is available.
156 *
157 * @returns IPRT status code.
158 * @param uMsg Message type to retrieve.
159 * @param cParms Number of parameters the \@a paParms array can store.
160 * @param paParms Where to store the message parameters.
161 */
162int DnDManager::GetNextMsg(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
163{
164 LogFlowFunc(("uMsg=%s (%#x), cParms=%RU32\n", DnDHostMsgToStr(uMsg), uMsg, cParms));
165
166 /* Check for pending messages in our queue. */
167 if (m_queueMsg.isEmpty())
168 return VERR_NO_DATA;
169
170 /* Get the current message. */
171 DnDMessage *pMsg = m_queueMsg.first();
172 AssertPtr(pMsg);
173
174 m_queueMsg.removeFirst(); /* Remove the current message from the queue. */
175
176 /* Fetch the current message info. */
177 int rc = pMsg->GetData(uMsg, cParms, paParms);
178
179 /*
180 * If there was an error handling the current message or the user has canceled
181 * the operation, we need to cleanup all pending events and inform the progress
182 * callback about our exit.
183 */
184 if (RT_FAILURE(rc))
185 {
186 /* Clear any pending messages. */
187 Reset();
188
189 /* Create a new cancel message to inform the guest + call
190 * the host whether the current transfer was canceled or aborted
191 * due to an error. */
192 try
193 {
194 if (rc == VERR_CANCELLED)
195 LogFlowFunc(("Operation was cancelled\n"));
196
197 DnDHGCancelMessage *pMsgCancel = new DnDHGCancelMessage();
198
199 int rc2 = AddMsg(pMsgCancel, false /* Prepend */);
200 AssertRC(rc2);
201
202 if (m_pfnProgressCallback)
203 {
204 LogFlowFunc(("Notifying host about aborting operation (%Rrc) ...\n", rc));
205 m_pfnProgressCallback( rc == VERR_CANCELLED
206 ? DragAndDropSvc::DND_PROGRESS_CANCELLED
207 : DragAndDropSvc::DND_PROGRESS_ERROR,
208 100 /* Percent */, rc,
209 m_pvProgressUser);
210 }
211 }
212 catch(std::bad_alloc &)
213 {
214 rc = VERR_NO_MEMORY;
215 }
216 }
217
218 LogFlowFunc(("Message processed with rc=%Rrc\n", rc));
219 return rc;
220}
221
222/**
223 * Resets the manager by clearing the message queue and internal state.
224 */
225void DnDManager::Reset(void)
226{
227 LogFlowFuncEnter();
228
229 while (!m_queueMsg.isEmpty())
230 {
231 delete m_queueMsg.last();
232 m_queueMsg.removeLast();
233 }
234}
235
Note: See TracBrowser for help on using the repository browser.

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