Changeset 74380 in vbox for trunk/src/VBox/Additions/common
- Timestamp:
- Sep 20, 2018 10:02:42 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibDragAndDrop.cpp
r74333 r74380 97 97 * @param pCtx DnD context to use. 98 98 * @param uMsg Which kind of message to receive. 99 * @param puScreenID Where to store the host screen ID the message is bound to. 100 * @param puX Where to store the absolute X coordinates. 101 * @param puY Where to store the absolute Y coordinates. 102 * @param puDefAction Where to store the default action to perform. 103 * @param puAllActions Where to store the available actions. 104 * @param ppszFormats Where to store List of formats. 105 * @param pcbFormats Size (in bytes) of where to store the list of formats. 99 * @param puScreenID Where to store the host screen ID the message is bound to. Optional. 100 * @param puX Where to store the absolute X coordinates. Optional. 101 * @param puY Where to store the absolute Y coordinates. Optional. 102 * @param puDefAction Where to store the default action to perform. Optional. 103 * @param puAllActions Where to store the available actions. Optional. 104 * @param ppszFormats Where to store List of formats. Optional. 105 * @param pcbFormats Size (in bytes) of where to store the list of formats. Optional. 106 106 * 107 107 * @todo r=andy Get rid of this function as soon as we resolved the protocol TODO #1. … … 109 109 */ 110 110 static int vbglR3DnDHGRecvAction(PVBGLR3GUESTDNDCMDCTX pCtx, 111 uint32_t uMsg, 112 uint32_t *puScreenId, 113 uint32_t *puX, 114 uint32_t *puY, 115 uint32_t *puDefAction, 116 uint32_t *puAllActions, 117 char *pszFormats, 118 uint32_t cbFormats, 119 uint32_t *pcbFormatsRecv) 120 { 121 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 122 AssertPtrReturn(puScreenId, VERR_INVALID_POINTER); 123 AssertPtrReturn(puX, VERR_INVALID_POINTER); 124 AssertPtrReturn(puY, VERR_INVALID_POINTER); 125 AssertPtrReturn(puDefAction, VERR_INVALID_POINTER); 126 AssertPtrReturn(puAllActions, VERR_INVALID_POINTER); 127 AssertPtrReturn(pszFormats, VERR_INVALID_POINTER); 128 AssertReturn(cbFormats, VERR_INVALID_PARAMETER); 129 AssertPtrReturn(pcbFormatsRecv, VERR_INVALID_POINTER); 111 uint32_t uMsg, 112 uint32_t *puScreenID, 113 uint32_t *puX, 114 uint32_t *puY, 115 uint32_t *puDefAction, 116 uint32_t *puAllActions, 117 char **ppszFormats, 118 uint32_t *pcbFormats) 119 { 120 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 121 /* The rest is optional. */ 122 123 const uint32_t cbFormatsTmp = pCtx->cbMaxChunkSize; 124 125 char *pszFormatsTmp = static_cast<char *>(RTMemAlloc(cbFormatsTmp)); 126 if (!pszFormatsTmp) 127 return VERR_NO_MEMORY; 130 128 131 129 VBOXDNDHGACTIONMSG Msg; … … 139 137 Msg.u.v1.uDefAction.SetUInt32(0); 140 138 Msg.u.v1.uAllActions.SetUInt32(0); 141 Msg.u.v1.pvFormats.SetPtr(pszFormats , cbFormats);139 Msg.u.v1.pvFormats.SetPtr(pszFormatsTmp, cbFormatsTmp); 142 140 Msg.u.v1.cbFormats.SetUInt32(0); 143 141 } … … 151 149 Msg.u.v3.uDefAction.SetUInt32(0); 152 150 Msg.u.v3.uAllActions.SetUInt32(0); 153 Msg.u.v3.pvFormats.SetPtr(pszFormats , cbFormats);151 Msg.u.v3.pvFormats.SetPtr(pszFormatsTmp, cbFormatsTmp); 154 152 Msg.u.v3.cbFormats.SetUInt32(0); 155 153 } … … 160 158 if (pCtx->uProtocol < 3) 161 159 { 162 rc = Msg.u.v1.uScreenId.GetUInt32(puScreenId); AssertRC(rc); 163 rc = Msg.u.v1.uX.GetUInt32(puX); AssertRC(rc); 164 rc = Msg.u.v1.uY.GetUInt32(puY); AssertRC(rc); 165 rc = Msg.u.v1.uDefAction.GetUInt32(puDefAction); AssertRC(rc); 166 rc = Msg.u.v1.uAllActions.GetUInt32(puAllActions); AssertRC(rc); 167 rc = Msg.u.v1.cbFormats.GetUInt32(pcbFormatsRecv); AssertRC(rc); 160 if (puScreenID) 161 rc = Msg.u.v1.uScreenId.GetUInt32(puScreenID); 162 if (RT_SUCCESS(rc) && puX) 163 rc = Msg.u.v1.uX.GetUInt32(puX); 164 if (RT_SUCCESS(rc) && puY) 165 rc = Msg.u.v1.uY.GetUInt32(puY); 166 if (RT_SUCCESS(rc) && puDefAction) 167 rc = Msg.u.v1.uDefAction.GetUInt32(puDefAction); 168 if (RT_SUCCESS(rc) && puAllActions) 169 rc = Msg.u.v1.uAllActions.GetUInt32(puAllActions); 170 if (RT_SUCCESS(rc) && pcbFormats) 171 rc = Msg.u.v1.cbFormats.GetUInt32(pcbFormats); 168 172 } 169 173 else 170 174 { 171 175 /** @todo Context ID not used yet. */ 172 rc = Msg.u.v3.uScreenId.GetUInt32(puScreenId); AssertRC(rc); 173 rc = Msg.u.v3.uX.GetUInt32(puX); AssertRC(rc); 174 rc = Msg.u.v3.uY.GetUInt32(puY); AssertRC(rc); 175 rc = Msg.u.v3.uDefAction.GetUInt32(puDefAction); AssertRC(rc); 176 rc = Msg.u.v3.uAllActions.GetUInt32(puAllActions); AssertRC(rc); 177 rc = Msg.u.v3.cbFormats.GetUInt32(pcbFormatsRecv); AssertRC(rc); 178 } 179 180 AssertReturn(cbFormats >= *pcbFormatsRecv, VERR_TOO_MUCH_DATA); 181 } 176 if (RT_SUCCESS(rc) && puScreenID) 177 rc = Msg.u.v3.uScreenId.GetUInt32(puScreenID); 178 if (RT_SUCCESS(rc) && puX) 179 rc = Msg.u.v3.uX.GetUInt32(puX); 180 if (RT_SUCCESS(rc) && puY) 181 rc = Msg.u.v3.uY.GetUInt32(puY); 182 if (RT_SUCCESS(rc) && puDefAction) 183 rc = Msg.u.v3.uDefAction.GetUInt32(puDefAction); 184 if (RT_SUCCESS(rc) && puAllActions) 185 rc = Msg.u.v3.uAllActions.GetUInt32(puAllActions); 186 if (RT_SUCCESS(rc) && pcbFormats) 187 rc = Msg.u.v3.cbFormats.GetUInt32(pcbFormats); 188 } 189 190 if (RT_SUCCESS(rc)) 191 { 192 if (ppszFormats) 193 { 194 *ppszFormats = RTStrDup(pszFormatsTmp); 195 if (!*ppszFormats) 196 rc = VERR_NO_MEMORY; 197 } 198 } 199 } 200 201 RTStrFree(pszFormatsTmp); 182 202 183 203 return rc; … … 1083 1103 if (RT_SUCCESS(rc)) 1084 1104 { 1085 LogFlowFunc(("cbTotal=%RU64, cbMeta=%RU32 \n", pDataHdr->cbTotal, pDataHdr->cbMeta));1105 LogFlowFunc(("cbTotal=%RU64, cbMeta=%RU32, cObjects=%RU32\n", pDataHdr->cbTotal, pDataHdr->cbMeta, pDataHdr->cObjects)); 1086 1106 if (pDataHdr->cbMeta) 1087 1107 { … … 1141 1161 * @returns IPRT status code. 1142 1162 * @param pCtx DnD context to use. 1143 * @param pEnmType Where to store the meta data type. 1144 * @param ppvData Returns the received meta data. Needs to be free'd by the caller. 1145 * @param pcbData Where to store the size (in bytes) of the received meta data. 1146 */ 1147 static int vbglR3DnDHGRecvDataMain(PVBGLR3GUESTDNDCMDCTX pCtx, 1148 uint32_t *puScreenId, 1149 char **ppszFormat, 1150 uint32_t *pcbFormat, 1151 void **ppvData, 1152 uint32_t *pcbData) 1153 { 1154 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1155 AssertPtrReturn(puScreenId, VERR_INVALID_POINTER); 1156 AssertPtrReturn(ppszFormat, VERR_INVALID_POINTER); 1157 AssertPtrReturn(pcbFormat, VERR_INVALID_POINTER); 1158 AssertPtrReturn(ppvData, VERR_INVALID_POINTER); 1159 AssertPtrReturn(pcbData, VERR_INVALID_POINTER); 1160 1161 VBOXDNDDATAHDR dataHdr; /** @todo See todo above. */ 1163 * @param pEnmType Where to store the meta data type. Optional. 1164 * @param ppvData Returns the received meta data. Needs to be free'd by the caller. Optional. 1165 * @param pcbData Where to store the size (in bytes) of the received meta data. Optional. 1166 */ 1167 static int vbglR3DnDHGRecvDataMainEx(PVBGLR3GUESTDNDCMDCTX pCtx, 1168 VBGLR3GUESTDNDMETADATATYPE *pEnmType, 1169 void **ppvData, 1170 uint32_t *pcbData) 1171 { 1172 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1173 /* The rest is optional. */ 1174 1175 VBOXDNDDATAHDR dataHdr; 1162 1176 RT_ZERO(dataHdr); 1163 1177 1164 dataHdr.cbMetaFmt = _64K; /** @todo Make this configurable? */ 1178 AssertMsg(pCtx->cbMaxChunkSize, ("Maximum chunk size must not be 0\n")); 1179 1180 dataHdr.cbMetaFmt = pCtx->cbMaxChunkSize; 1165 1181 dataHdr.pvMetaFmt = RTMemAlloc(dataHdr.cbMetaFmt); 1166 1182 if (!dataHdr.pvMetaFmt) … … 1170 1186 DnDDroppedFiles droppedFiles; 1171 1187 1172 void *pvData; /** @todo See todo above. */1173 uint64_t cbData ; /** @todo See todo above. */1188 void *pvData = NULL; 1189 uint64_t cbData = 0; 1174 1190 1175 1191 int rc = vbglR3DnDHGRecvDataLoop(pCtx, &dataHdr, &pvData, &cbData); … … 1186 1202 Assert(dataHdr.cbMetaFmt); 1187 1203 AssertPtr(dataHdr.pvMetaFmt); 1188 if (DnDMIMEHasFileURLs((char *)dataHdr.pvMetaFmt, dataHdr.cbMetaFmt)) 1204 if (DnDMIMEHasFileURLs((char *)dataHdr.pvMetaFmt, dataHdr.cbMetaFmt)) /* URI data. */ 1189 1205 { 1190 1206 AssertPtr(pvData); 1191 1207 Assert(cbData); 1208 1192 1209 rc = lstURI.RootFromURIData(pvData, cbData, 0 /* fFlags */); 1193 1210 if (RT_SUCCESS(rc)) … … 1213 1230 { 1214 1231 memcpy(pvData, strData.c_str(), cbData); 1232 1233 if (pEnmType) 1234 *pEnmType = VBGLR3GUESTDNDMETADATATYPE_URI_LIST; 1215 1235 } 1216 1236 else … … 1220 1240 else /* Raw data. */ 1221 1241 { 1222 const uint32_t cbDataRaw = dataHdr.cbMetaFmt; 1223 if (cbData >= cbDataRaw) 1224 { 1225 if (cbDataRaw) 1226 memcpy(pvData, dataHdr.pvMetaFmt, cbDataRaw); 1227 cbData = cbDataRaw; 1228 } 1242 if (pEnmType) 1243 *pEnmType = VBGLR3GUESTDNDMETADATATYPE_RAW; 1244 } 1245 } 1246 1247 if (dataHdr.pvMetaFmt) 1248 RTMemFree(dataHdr.pvMetaFmt); 1249 1250 if (RT_SUCCESS(rc)) 1251 { 1252 if ( pvData 1253 && cbData) 1254 { 1255 if (pcbData) 1256 *pcbData = cbData; 1257 if (ppvData) 1258 *ppvData = pvData; 1229 1259 else 1230 rc = VERR_BUFFER_OVERFLOW; 1231 } 1232 } 1233 1234 if ( RT_FAILURE(rc) 1235 && rc != VERR_CANCELLED) 1236 { 1237 if (dataHdr.pvMetaFmt) 1238 RTMemFree(dataHdr.pvMetaFmt); 1260 RTMemFree(pvData); 1261 } 1262 } 1263 else if ( RT_FAILURE(rc) 1264 && rc != VERR_CANCELLED) 1265 { 1239 1266 if (pvData) 1240 1267 RTMemFree(pvData); … … 1244 1271 LogFlowFunc(("Unable to send progress error %Rrc to host: %Rrc\n", rc, rc2)); 1245 1272 } 1246 else if (RT_SUCCESS(rc))1247 {1248 *ppszFormat = (char *)dataHdr.pvMetaFmt;1249 *pcbFormat = dataHdr.cbMetaFmt;1250 *ppvData = pvData;1251 *pcbData = cbData;1252 }1253 1273 1254 1274 LogFlowFuncLeaveRC(rc); … … 1256 1276 } 1257 1277 1278 /** 1279 * Host -> Guest 1280 * Main function for receiving the actual DnD data from the host. 1281 * 1282 * @returns IPRT status code. 1283 * @param pCtx DnD context to use. 1284 * @param pMeta Where to store the actual meta data received from the host. 1285 */ 1286 static int vbglR3DnDHGRecvDataMain(PVBGLR3GUESTDNDCMDCTX pCtx, 1287 PVBGLR3GUESTDNDMETADATA pMeta) 1288 { 1289 AssertPtrReturn(pMeta, VERR_INVALID_POINTER); 1290 1291 int rc = vbglR3DnDHGRecvDataMainEx(pCtx, 1292 &pMeta->enmType, 1293 &pMeta->pvMeta, 1294 &pMeta->cbMeta); 1295 return rc; 1296 } 1297 1258 1298 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 1259 1299 /** … … 1263 1303 * @returns IPRT status code. 1264 1304 * @param pCtx DnD context to use. 1265 * @param puScreenI d For which screen on the host the request is for.1266 */ 1267 static int vbglR3DnDGHRecvPending(PVBGLR3GUESTDNDCMDCTX pCtx, uint32_t *puScreenI d)1268 { 1269 AssertPtrReturn(pCtx, 1270 AssertPtrReturn(puScreenId, VERR_INVALID_POINTER);1305 * @param puScreenID For which screen on the host the request is for. Optional. 1306 */ 1307 static int vbglR3DnDGHRecvPending(PVBGLR3GUESTDNDCMDCTX pCtx, uint32_t *puScreenID) 1308 { 1309 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1310 /* pScreenID is optional. */ 1271 1311 1272 1312 VBOXDNDGHREQPENDINGMSG Msg; … … 1290 1330 if (pCtx->uProtocol < 3) 1291 1331 { 1292 rc = Msg.u.v1.uScreenId.GetUInt32(puScreenId); AssertRC(rc); 1332 if (puScreenID) 1333 rc = Msg.u.v1.uScreenId.GetUInt32(puScreenID); 1293 1334 } 1294 1335 else 1295 1336 { 1296 1337 /** @todo Context ID not used yet. */ 1297 rc = Msg.u.v3.uContext.GetUInt32(puScreenId); AssertRC(rc); 1338 if (puScreenID) 1339 rc = Msg.u.v3.uContext.GetUInt32(puScreenID); 1298 1340 } 1299 1341 } … … 1308 1350 * @returns IPRT status code. 1309 1351 * @param pCtx DnD context to use. 1310 * @param pszFormat Requested data format from the host. 1311 * @param cbFormat Size of requested data format (in bytes). 1312 * @param pcbFormatRecv Actual size of requested data format (in bytes). 1313 * @param puAction Requested action from the host. 1352 * @param ppszFormat Requested data format from the host. Optional. 1353 * @param pcbFormat Size of requested data format (in bytes). Optional. 1354 * @param puAction Requested action from the host. Optional. 1314 1355 */ 1315 1356 static int vbglR3DnDGHRecvDropped(PVBGLR3GUESTDNDCMDCTX pCtx, 1316 char *pszFormat, 1317 uint32_t cbFormat, 1318 uint32_t *pcbFormatRecv, 1319 uint32_t *puAction) 1320 { 1321 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1322 AssertPtrReturn(pszFormat, VERR_INVALID_POINTER); 1323 AssertReturn(cbFormat, VERR_INVALID_PARAMETER); 1324 AssertPtrReturn(pcbFormatRecv, VERR_INVALID_POINTER); 1325 AssertPtrReturn(puAction, VERR_INVALID_POINTER); 1357 char **ppszFormat, 1358 uint32_t *pcbFormat, 1359 uint32_t *puAction) 1360 { 1361 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1362 /* The rest is optional. */ 1363 1364 const uint32_t cbFormatTmp = pCtx->cbMaxChunkSize; 1365 1366 char *pszFormatTmp = static_cast<char *>(RTMemAlloc(cbFormatTmp)); 1367 if (!pszFormatTmp) 1368 return VERR_NO_MEMORY; 1326 1369 1327 1370 VBOXDNDGHDROPPEDMSG Msg; … … 1330 1373 { 1331 1374 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_GH_EVT_DROPPED, 3); 1332 Msg.u.v1.pvFormat.SetPtr(pszFormat , cbFormat);1375 Msg.u.v1.pvFormat.SetPtr(pszFormatTmp, cbFormatTmp); 1333 1376 Msg.u.v1.cbFormat.SetUInt32(0); 1334 1377 Msg.u.v1.uAction.SetUInt32(0); … … 1338 1381 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_GH_EVT_DROPPED, 4); 1339 1382 Msg.u.v3.uContext.SetUInt32(0); 1340 Msg.u.v3.pvFormat.SetPtr(pszFormat , cbFormat);1383 Msg.u.v3.pvFormat.SetPtr(pszFormatTmp, cbFormatTmp); 1341 1384 Msg.u.v3.cbFormat.SetUInt32(0); 1342 1385 Msg.u.v3.uAction.SetUInt32(0); … … 1348 1391 if (pCtx->uProtocol < 3) 1349 1392 { 1350 rc = Msg.u.v1.cbFormat.GetUInt32(pcbFormatRecv); AssertRC(rc); 1351 rc = Msg.u.v1.uAction.GetUInt32(puAction); AssertRC(rc); 1393 if (pcbFormat) 1394 rc = Msg.u.v1.cbFormat.GetUInt32(pcbFormat); 1395 if (RT_SUCCESS(rc) && puAction) 1396 rc = Msg.u.v1.uAction.GetUInt32(puAction); 1352 1397 } 1353 1398 else 1354 1399 { 1355 1400 /** @todo Context ID not used yet. */ 1356 rc = Msg.u.v3.cbFormat.GetUInt32(pcbFormatRecv); AssertRC(rc); 1357 rc = Msg.u.v3.uAction.GetUInt32(puAction); AssertRC(rc); 1358 } 1359 1360 AssertReturn(cbFormat >= *pcbFormatRecv, VERR_TOO_MUCH_DATA); 1361 } 1401 if (pcbFormat) 1402 rc = Msg.u.v3.cbFormat.GetUInt32(pcbFormat); 1403 if (RT_SUCCESS(rc) && puAction) 1404 rc = Msg.u.v3.uAction.GetUInt32(puAction); 1405 } 1406 1407 if (RT_SUCCESS(rc)) 1408 { 1409 *ppszFormat = RTStrDup(pszFormatTmp); 1410 if (!*ppszFormat) 1411 rc = VERR_NO_MEMORY; 1412 } 1413 } 1414 1415 RTMemFree(pszFormatTmp); 1362 1416 1363 1417 return rc; … … 1469 1523 * 1470 1524 * @returns IPRT status code. 1471 * @param pCtx DnD context to use.1525 * @param pCtx DnD context to disconnect. 1472 1526 * The context is invalid afterwards on successful disconnection. 1473 1527 */ … … 1482 1536 1483 1537 /** 1484 * Receives the next upcoming event for a given DnD context. 1485 * 1486 * @returns IPRT status code. 1487 * @param pCtx DnD context to use. 1488 * @param pEvent Where to return the received DnD event on success. 1489 */ 1490 VBGLR3DECL(int) VbglR3DnDRecvNextMsg(PVBGLR3GUESTDNDCMDCTX pCtx, CPVBGLR3DNDHGCMEVENT pEvent) 1491 { 1492 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1493 AssertPtrReturn(pEvent, VERR_INVALID_POINTER); 1494 1495 const uint32_t cbFormatMax = pCtx->cbMaxChunkSize; 1496 1497 uint32_t uMsg = 0; 1498 uint32_t cParms = 0; 1538 * Receives the next upcoming DnD event. 1539 * 1540 * This is the main function DnD clients call in order to implement any DnD functionality. 1541 * The purpose of it is to abstract the actual DnD protocol handling as much as possible from 1542 * the clients -- those only need to react to certain events, regardless of how the underlying 1543 * protocol actually is working. 1544 * 1545 * @returns IPRT status code. 1546 * @param pCtx DnD context to work with. 1547 * @param ppEvent Next DnD event received on success; needs to be free'd by the client calling 1548 * VbglR3DnDEventFree() when done. 1549 */ 1550 VBGLR3DECL(int) VbglR3DnDEventGetNext(PVBGLR3GUESTDNDCMDCTX pCtx, PVBGLR3DNDEVENT *ppEvent) 1551 { 1552 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1553 AssertPtrReturn(ppEvent, VERR_INVALID_POINTER); 1554 1555 PVBGLR3DNDEVENT pEvent = (PVBGLR3DNDEVENT)RTMemAllocZ(sizeof(VBGLR3DNDEVENT)); 1556 if (!pEvent) 1557 return VERR_NO_MEMORY; 1558 1559 uint32_t uMsg = 0; 1560 uint32_t cParms = 0; 1499 1561 int rc = vbglR3DnDGetNextMsgType(pCtx, &uMsg, &cParms, true /* fWait */); 1500 1562 if (RT_SUCCESS(rc)) … … 1520 1582 if (RT_SUCCESS(rc)) 1521 1583 { 1522 pEvent->uType = uMsg;1584 LogFunc(("Handling uMsg=%RU32\n", uMsg)); 1523 1585 1524 1586 switch(uMsg) 1525 1587 { 1526 1588 case HOST_DND_HG_EVT_ENTER: 1589 { 1590 rc = vbglR3DnDHGRecvAction(pCtx, 1591 uMsg, 1592 &pEvent->u.HG_Enter.uScreenID, 1593 NULL /* puXPos */, 1594 NULL /* puYPos */, 1595 NULL /* uDefAction */, 1596 &pEvent->u.HG_Enter.uAllActions, 1597 &pEvent->u.HG_Enter.pszFormats, 1598 &pEvent->u.HG_Enter.cbFormats); 1599 if (RT_SUCCESS(rc)) 1600 pEvent->enmType = VBGLR3DNDEVENTTYPE_HG_ENTER; 1601 break; 1602 } 1527 1603 case HOST_DND_HG_EVT_MOVE: 1604 { 1605 rc = vbglR3DnDHGRecvAction(pCtx, 1606 uMsg, 1607 NULL /* puScreenId */, 1608 &pEvent->u.HG_Move.uXpos, 1609 &pEvent->u.HG_Move.uYpos, 1610 &pEvent->u.HG_Move.uDefAction, 1611 NULL /* puAllActions */, 1612 NULL /* pszFormats */, 1613 NULL /* pcbFormats */); 1614 if (RT_SUCCESS(rc)) 1615 pEvent->enmType = VBGLR3DNDEVENTTYPE_HG_MOVE; 1616 break; 1617 } 1528 1618 case HOST_DND_HG_EVT_DROPPED: 1529 1619 { 1530 pEvent->pszFormats = static_cast<char*>(RTMemAlloc(cbFormatMax)); 1531 if (!pEvent->pszFormats) 1532 rc = VERR_NO_MEMORY; 1533 1620 rc = vbglR3DnDHGRecvAction(pCtx, 1621 uMsg, 1622 NULL /* puScreenId */, 1623 &pEvent->u.HG_Drop.uXpos, 1624 &pEvent->u.HG_Drop.uYpos, 1625 &pEvent->u.HG_Drop.uDefAction, 1626 NULL /* puAllActions */, 1627 NULL /* pszFormats */, 1628 NULL /* pcbFormats */); 1534 1629 if (RT_SUCCESS(rc)) 1535 rc = vbglR3DnDHGRecvAction(pCtx, 1536 uMsg, 1537 &pEvent->uScreenId, 1538 &pEvent->u.a.uXpos, 1539 &pEvent->u.a.uYpos, 1540 &pEvent->u.a.uDefAction, 1541 &pEvent->u.a.uAllActions, 1542 pEvent->pszFormats, 1543 cbFormatMax, 1544 &pEvent->cbFormats); 1630 pEvent->enmType = VBGLR3DNDEVENTTYPE_HG_DROP; 1545 1631 break; 1546 1632 } … … 1548 1634 { 1549 1635 rc = vbglR3DnDHGRecvLeave(pCtx); 1636 if (RT_SUCCESS(rc)) 1637 pEvent->enmType = VBGLR3DNDEVENTTYPE_HG_LEAVE; 1550 1638 break; 1551 1639 } 1552 1640 case HOST_DND_HG_SND_DATA: 1553 /* Protocol v1 + v2: Also contains the header data. 1554 * Note: Fall through is intentional. */1641 /* Protocol v1 + v2: Also contains the header data. */ 1642 RT_FALL_THROUGH(); 1555 1643 case HOST_DND_HG_SND_DATA_HDR: 1556 1644 { 1557 rc = vbglR3DnDHGRecvDataMain(pCtx, 1558 /* Screen ID */ 1559 &pEvent->uScreenId, 1560 /* Format */ 1561 &pEvent->pszFormats, 1562 &pEvent->cbFormats, 1563 /* Data */ 1564 &pEvent->u.b.pvData, 1565 &pEvent->u.b.cbData); 1645 rc = vbglR3DnDHGRecvDataMain(pCtx, &pEvent->u.HG_Received.Meta); 1646 if (RT_SUCCESS(rc)) 1647 pEvent->enmType = VBGLR3DNDEVENTTYPE_HG_RECEIVE; 1566 1648 break; 1567 1649 } 1568 case HOST_DND_HG_SND_MORE_DATA: 1650 case HOST_DND_HG_SND_MORE_DATA: /* Deprecated; kept for backwards compatibility. */ 1651 RT_FALL_THROUGH(); 1569 1652 case HOST_DND_HG_SND_DIR: 1653 RT_FALL_THROUGH(); 1570 1654 case HOST_DND_HG_SND_FILE_DATA: 1571 1655 { … … 1573 1657 * All messages in this case are handled internally 1574 1658 * by vbglR3DnDHGRecvDataMain() and must be specified 1575 * by a preceding HOST_DND_HG_SND_DATA or HOST_DND_HG_SND_DATA_HDR 1576 * calls. 1659 * by preceeding HOST_DND_HG_SND_DATA or HOST_DND_HG_SND_DATA_HDR calls. 1577 1660 */ 1578 1661 rc = VERR_WRONG_ORDER; … … 1582 1665 { 1583 1666 rc = vbglR3DnDHGRecvCancel(pCtx); 1667 if (RT_SUCCESS(rc)) 1668 pEvent->enmType = VBGLR3DNDEVENTTYPE_HG_CANCEL; 1584 1669 break; 1585 1670 } … … 1587 1672 case HOST_DND_GH_REQ_PENDING: 1588 1673 { 1589 rc = vbglR3DnDGHRecvPending(pCtx, &pEvent->uScreenId); 1674 rc = vbglR3DnDGHRecvPending(pCtx, &pEvent->u.GH_IsPending.uScreenID); 1675 if (RT_SUCCESS(rc)) 1676 pEvent->enmType = VBGLR3DNDEVENTTYPE_GH_REQ_PENDING; 1590 1677 break; 1591 1678 } 1592 1679 case HOST_DND_GH_EVT_DROPPED: 1593 1680 { 1594 pEvent->pszFormats = static_cast<char*>(RTMemAlloc(cbFormatMax));1595 if (!pEvent->pszFormats)1596 rc = VERR_NO_MEMORY;1597 1681 rc = vbglR3DnDGHRecvDropped(pCtx, 1682 &pEvent->u.GH_Drop.pszFormat, 1683 &pEvent->u.GH_Drop.cbFormat, 1684 &pEvent->u.GH_Drop.uAction); 1598 1685 if (RT_SUCCESS(rc)) 1599 rc = vbglR3DnDGHRecvDropped(pCtx, 1600 pEvent->pszFormats, 1601 cbFormatMax, 1602 &pEvent->cbFormats, 1603 &pEvent->u.a.uDefAction); 1686 pEvent->enmType = VBGLR3DNDEVENTTYPE_GH_DROP; 1604 1687 break; 1605 1688 } … … 1614 1697 1615 1698 if (RT_FAILURE(rc)) 1616 LogFlowFunc(("Returning error %Rrc\n", rc)); 1699 { 1700 VbglR3DnDEventFree(pEvent); 1701 LogFlowFunc(("Failed with %Rrc\n", rc)); 1702 } 1703 else 1704 *ppEvent = pEvent; 1705 1617 1706 return rc; 1618 1707 } 1619 1708 1620 1709 /** 1621 * Host -> Guest 1622 * Acknowledges that a pending DnD operation from the host can be dropped 1623 * on the currently selected area on the guest. 1624 * 1625 * @returns IPRT status code. 1626 * @param pCtx DnD context to use. 1627 * @param uAction Action to acknowledge. 1628 */ 1710 * Frees (destroys) a formerly allocated DnD event. 1711 * 1712 * @returns IPRT status code. 1713 * @param pEvent Event to free (destroy). 1714 */ 1715 VBGLR3DECL(void) VbglR3DnDEventFree(PVBGLR3DNDEVENT pEvent) 1716 { 1717 if (!pEvent) 1718 return; 1719 1720 /* Some messages require additional cleanup. */ 1721 switch (pEvent->enmType) 1722 { 1723 case VBGLR3DNDEVENTTYPE_HG_ENTER: 1724 { 1725 if (pEvent->u.HG_Enter.pszFormats) 1726 RTStrFree(pEvent->u.HG_Enter.pszFormats); 1727 break; 1728 } 1729 1730 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 1731 case VBGLR3DNDEVENTTYPE_GH_DROP: 1732 { 1733 if (pEvent->u.GH_Drop.pszFormat) 1734 RTStrFree(pEvent->u.GH_Drop.pszFormat); 1735 break; 1736 } 1737 #endif 1738 case VBGLR3DNDEVENTTYPE_HG_RECEIVE: 1739 { 1740 PVBGLR3GUESTDNDMETADATA pMeta = &pEvent->u.HG_Received.Meta; 1741 if (pMeta->pvMeta) 1742 { 1743 Assert(pMeta->cbMeta); 1744 RTMemFree(pMeta->pvMeta); 1745 pMeta->cbMeta = 0; 1746 } 1747 break; 1748 } 1749 1750 default: 1751 break; 1752 } 1753 1754 RTMemFree(pEvent); 1755 pEvent = NULL; 1756 } 1757 1629 1758 VBGLR3DECL(int) VbglR3DnDHGSendAckOp(PVBGLR3GUESTDNDCMDCTX pCtx, uint32_t uAction) 1630 1759 {
Note:
See TracChangeset
for help on using the changeset viewer.