VirtualBox

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

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

scm copyright and license note update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1/* $Id: dndmanager.cpp 96407 2022-08-22 17:43:14Z 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=%RU32, cParms=%RU32, fAppend=%RTbool\n", pMsg->GetType(), pMsg->GetParamCount(), fAppend));
63
64 if (fAppend)
65 m_queueMsg.append(pMsg);
66 else
67 m_queueMsg.prepend(pMsg);
68
69 /** @todo Catch / handle OOM? */
70
71 return VINF_SUCCESS;
72}
73
74/**
75 * Adds a DnD message to the manager's queue.
76 *
77 * @returns IPRT status code.
78 * @param uMsg Type (function number) of message to add.
79 * @param cParms Number of parameters of message to add.
80 * @param paParms Array of parameters of message to add.
81 * @param fAppend Whether to append or prepend the message to the queue.
82 */
83int DnDManager::AddMsg(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[], bool fAppend /* = true */)
84{
85 int rc;
86
87 try
88 {
89 DnDMessage *pMsg = new DnDGenericMessage(uMsg, cParms, paParms);
90 rc = AddMsg(pMsg, fAppend);
91 }
92 catch(std::bad_alloc &)
93 {
94 rc = VERR_NO_MEMORY;
95 }
96
97 LogFlowFuncLeaveRC(rc);
98 return rc;
99}
100
101/**
102 * Retrieves information about the next message in the queue.
103 *
104 * @returns IPRT status code. VERR_NO_DATA if no next message is available.
105 * @param puType Where to store the message type.
106 * @param pcParms Where to store the message parameter count.
107 */
108int DnDManager::GetNextMsgInfo(uint32_t *puType, uint32_t *pcParms)
109{
110 AssertPtrReturn(puType, VERR_INVALID_POINTER);
111 AssertPtrReturn(pcParms, VERR_INVALID_POINTER);
112
113 int rc;
114
115 if (m_queueMsg.isEmpty())
116 {
117 rc = VERR_NO_DATA;
118 }
119 else
120 {
121 DnDMessage *pMsg = m_queueMsg.first();
122 AssertPtr(pMsg);
123
124 *puType = pMsg->GetType();
125 *pcParms = pMsg->GetParamCount();
126
127 rc = VINF_SUCCESS;
128 }
129
130 LogFlowFunc(("Returning puMsg=%RU32, pcParms=%RU32, rc=%Rrc\n", *puType, *pcParms, rc));
131 return rc;
132}
133
134/**
135 * Retrieves the next queued up message and removes it from the queue on success.
136 * Will return VERR_NO_DATA if no next message is available.
137 *
138 * @returns IPRT status code.
139 * @param uMsg Message type to retrieve.
140 * @param cParms Number of parameters the \@a paParms array can store.
141 * @param paParms Where to store the message parameters.
142 */
143int DnDManager::GetNextMsg(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
144{
145 LogFlowFunc(("uMsg=%RU32, cParms=%RU32\n", uMsg, cParms));
146
147 /* Check for pending messages in our queue. */
148 if (m_queueMsg.isEmpty())
149 return VERR_NO_DATA;
150
151 /* Get the current message. */
152 DnDMessage *pMsg = m_queueMsg.first();
153 AssertPtr(pMsg);
154
155 m_queueMsg.removeFirst(); /* Remove the current message from the queue. */
156
157 /* Fetch the current message info. */
158 int rc = pMsg->GetData(uMsg, cParms, paParms);
159
160 /*
161 * If there was an error handling the current message or the user has canceled
162 * the operation, we need to cleanup all pending events and inform the progress
163 * callback about our exit.
164 */
165 if (RT_FAILURE(rc))
166 {
167 /* Clear any pending messages. */
168 Reset();
169
170 /* Create a new cancel message to inform the guest + call
171 * the host whether the current transfer was canceled or aborted
172 * due to an error. */
173 try
174 {
175 if (rc == VERR_CANCELLED)
176 LogFlowFunc(("Operation was cancelled\n"));
177
178 DnDHGCancelMessage *pMsgCancel = new DnDHGCancelMessage();
179
180 int rc2 = AddMsg(pMsgCancel, false /* Prepend */);
181 AssertRC(rc2);
182
183 if (m_pfnProgressCallback)
184 {
185 LogFlowFunc(("Notifying host about aborting operation (%Rrc) ...\n", rc));
186 m_pfnProgressCallback( rc == VERR_CANCELLED
187 ? DragAndDropSvc::DND_PROGRESS_CANCELLED
188 : DragAndDropSvc::DND_PROGRESS_ERROR,
189 100 /* Percent */, rc,
190 m_pvProgressUser);
191 }
192 }
193 catch(std::bad_alloc &)
194 {
195 rc = VERR_NO_MEMORY;
196 }
197 }
198
199 LogFlowFunc(("Message processed with rc=%Rrc\n", rc));
200 return rc;
201}
202
203/**
204 * Resets the manager by clearing the message queue and internal state.
205 */
206void DnDManager::Reset(void)
207{
208 LogFlowFuncEnter();
209
210 while (!m_queueMsg.isEmpty())
211 {
212 delete m_queueMsg.last();
213 m_queueMsg.removeLast();
214 }
215}
216
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