VirtualBox

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

Last change on this file since 105745 was 98103, checked in by vboxsync, 23 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.9 KB
Line 
1/* $Id: dndmanager.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * Drag and Drop manager: Handling of DnD messages on the host side.
4 */
5
6/*
7 * Copyright (C) 2011-2023 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 {
112 if (i > 0)
113 Log((" - "));
114 DnDMessage const *pMsg = m_queueMsg[i];
115 uint32_t const uType = pMsg->GetType();
116 Log(("%s (%d / %#x) cRefS=%RU32", DnDHostMsgToStr(uType), uType, uType, pMsg->RefCount()));
117 }
118 Log(("\n"));
119}
120#endif /* DEBUG */
121
122/**
123 * Retrieves information about the next message in the queue.
124 *
125 * @returns IPRT status code. VERR_NO_DATA if no next message is available.
126 * @param fAddRef Set to \c true to increase the message's reference count, or \c false if not.
127 * @param puType Where to store the message type.
128 * @param pcParms Where to store the message parameter count.
129 */
130int DnDManager::GetNextMsgInfo(bool fAddRef, uint32_t *puType, uint32_t *pcParms)
131{
132 AssertPtrReturn(puType, VERR_INVALID_POINTER);
133 AssertPtrReturn(pcParms, VERR_INVALID_POINTER);
134
135 int rc;
136
137 if (m_queueMsg.isEmpty())
138 {
139 rc = VERR_NO_DATA;
140 }
141 else
142 {
143 DnDMessage *pMsg = m_queueMsg.first();
144 AssertPtr(pMsg);
145
146 *puType = pMsg->GetType();
147 *pcParms = pMsg->GetParamCount();
148
149 if (fAddRef)
150 pMsg->AddRef();
151
152 rc = VINF_SUCCESS;
153 }
154
155#ifdef DEBUG
156 DumpQueue();
157#endif
158
159 LogFlowFunc(("Returning uMsg=%s (%#x), cParms=%RU32, fAddRef=%RTbool, rc=%Rrc\n",
160 DnDHostMsgToStr(*puType), *puType, *pcParms, fAddRef, rc));
161 return rc;
162}
163
164/**
165 * Retrieves the next queued up message and removes it from the queue on success.
166 *
167 * @returns VBox status code.
168 * @retval VERR_NO_DATA if no next message is available.
169 * @param uMsg Message type to retrieve.
170 * @param cParms Number of parameters the \@a paParms array can store.
171 * @param paParms Where to store the message parameters.
172 */
173int DnDManager::GetNextMsg(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
174{
175 LogFlowFunc(("uMsg=%s (%#x), cParms=%RU32\n", DnDHostMsgToStr(uMsg), uMsg, cParms));
176
177 /* Check for pending messages in our queue. */
178 if (m_queueMsg.isEmpty())
179 return VERR_NO_DATA;
180
181#ifdef DEBUG
182 DumpQueue();
183#endif
184
185 /* Get the current message. */
186 DnDMessage *pMsg = m_queueMsg.first();
187 AssertPtr(pMsg);
188
189 if (pMsg->Release() == 0) /* Not referenced by any client anymore? */
190 m_queueMsg.removeFirst(); /* Remove the current message from the queue. */
191
192 /* Fetch the current message info. */
193 int rc = pMsg->GetData(uMsg, cParms, paParms);
194
195 /*
196 * If there was an error handling the current message or the user has canceled
197 * the operation, we need to cleanup all pending events.
198 */
199 if (RT_FAILURE(rc))
200 {
201 /* Clear any pending messages. */
202 Reset(true /* fForce */);
203 }
204
205 LogFlowFunc(("Message processed with rc=%Rrc\n", rc));
206 return rc;
207}
208
209/**
210 * Resets the manager by clearing the message queue and internal state.
211 *
212 * @param fForce Set to \c true to forcefully also remove still referenced messages, or \c false to only
213 * remove non-referenced messages.
214 */
215void DnDManager::Reset(bool fForce)
216{
217 LogFlowFuncEnter();
218
219#ifdef DEBUG
220 DumpQueue();
221#endif
222
223 for (size_t i = 0; i < m_queueMsg.size(); i++)
224 {
225 if ( fForce
226 || m_queueMsg[i]->RefCount() == 0)
227 {
228 m_queueMsg.removeAt(i);
229 i = i > 0 ? i - 1 : 0;
230 }
231 }
232}
233
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