VirtualBox

Changeset 74380 in vbox for trunk/src/VBox/Additions/common


Ignore:
Timestamp:
Sep 20, 2018 10:02:42 AM (6 years ago)
Author:
vboxsync
Message:

DnD: Added VBGLR3DNDEVENTTYPE to abstract the DnD protocol from the actual DnD events more; that way the client don't need to know exactly how the actual protocol works, but only react on events they care for.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibDragAndDrop.cpp

    r74333 r74380  
    9797 * @param   pCtx                DnD context to use.
    9898 * @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.
    106106 *
    107107 * @todo r=andy Get rid of this function as soon as we resolved the protocol TODO #1.
     
    109109 */
    110110static 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;
    130128
    131129    VBOXDNDHGACTIONMSG Msg;
     
    139137        Msg.u.v1.uDefAction.SetUInt32(0);
    140138        Msg.u.v1.uAllActions.SetUInt32(0);
    141         Msg.u.v1.pvFormats.SetPtr(pszFormats, cbFormats);
     139        Msg.u.v1.pvFormats.SetPtr(pszFormatsTmp, cbFormatsTmp);
    142140        Msg.u.v1.cbFormats.SetUInt32(0);
    143141    }
     
    151149        Msg.u.v3.uDefAction.SetUInt32(0);
    152150        Msg.u.v3.uAllActions.SetUInt32(0);
    153         Msg.u.v3.pvFormats.SetPtr(pszFormats, cbFormats);
     151        Msg.u.v3.pvFormats.SetPtr(pszFormatsTmp, cbFormatsTmp);
    154152        Msg.u.v3.cbFormats.SetUInt32(0);
    155153    }
     
    160158        if (pCtx->uProtocol < 3)
    161159        {
    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);
    168172        }
    169173        else
    170174        {
    171175            /** @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);
    182202
    183203    return rc;
     
    10831103        if (RT_SUCCESS(rc))
    10841104        {
    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));
    10861106            if (pDataHdr->cbMeta)
    10871107            {
     
    11411161 * @returns IPRT status code.
    11421162 * @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 */
     1167static 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;
    11621176    RT_ZERO(dataHdr);
    11631177
    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;
    11651181    dataHdr.pvMetaFmt = RTMemAlloc(dataHdr.cbMetaFmt);
    11661182    if (!dataHdr.pvMetaFmt)
     
    11701186    DnDDroppedFiles droppedFiles;
    11711187
    1172     void *pvData;    /** @todo See todo above. */
    1173     uint64_t cbData; /** @todo See todo above. */
     1188    void    *pvData = NULL;
     1189    uint64_t cbData = 0;
    11741190
    11751191    int rc = vbglR3DnDHGRecvDataLoop(pCtx, &dataHdr, &pvData, &cbData);
     
    11861202        Assert(dataHdr.cbMetaFmt);
    11871203        AssertPtr(dataHdr.pvMetaFmt);
    1188         if (DnDMIMEHasFileURLs((char *)dataHdr.pvMetaFmt, dataHdr.cbMetaFmt))
     1204        if (DnDMIMEHasFileURLs((char *)dataHdr.pvMetaFmt, dataHdr.cbMetaFmt)) /* URI data. */
    11891205        {
    11901206            AssertPtr(pvData);
    11911207            Assert(cbData);
     1208
    11921209            rc = lstURI.RootFromURIData(pvData, cbData, 0 /* fFlags */);
    11931210            if (RT_SUCCESS(rc))
     
    12131230                {
    12141231                    memcpy(pvData, strData.c_str(), cbData);
     1232
     1233                    if (pEnmType)
     1234                        *pEnmType = VBGLR3GUESTDNDMETADATATYPE_URI_LIST;
    12151235                }
    12161236                else
     
    12201240        else /* Raw data. */
    12211241        {
    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;
    12291259            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    {
    12391266        if (pvData)
    12401267            RTMemFree(pvData);
     
    12441271            LogFlowFunc(("Unable to send progress error %Rrc to host: %Rrc\n", rc, rc2));
    12451272    }
    1246     else if (RT_SUCCESS(rc))
    1247     {
    1248         *ppszFormat = (char *)dataHdr.pvMetaFmt;
    1249         *pcbFormat  =         dataHdr.cbMetaFmt;
    1250         *ppvData    = pvData;
    1251         *pcbData    = cbData;
    1252     }
    12531273
    12541274    LogFlowFuncLeaveRC(rc);
     
    12561276}
    12571277
     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 */
     1286static 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
    12581298#ifdef VBOX_WITH_DRAG_AND_DROP_GH
    12591299/**
     
    12631303 * @returns IPRT status code.
    12641304 * @param   pCtx                DnD context to use.
    1265  * @param   puScreenId          For which screen on the host the request is for.
    1266  */
    1267 static int vbglR3DnDGHRecvPending(PVBGLR3GUESTDNDCMDCTX pCtx, uint32_t *puScreenId)
    1268 {
    1269     AssertPtrReturn(pCtx,       VERR_INVALID_POINTER);
    1270     AssertPtrReturn(puScreenId, VERR_INVALID_POINTER);
     1305 * @param   puScreenID          For which screen on the host the request is for. Optional.
     1306 */
     1307static int vbglR3DnDGHRecvPending(PVBGLR3GUESTDNDCMDCTX pCtx, uint32_t *puScreenID)
     1308{
     1309    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     1310   /* pScreenID is optional. */
    12711311
    12721312    VBOXDNDGHREQPENDINGMSG Msg;
     
    12901330        if (pCtx->uProtocol < 3)
    12911331        {
    1292             rc = Msg.u.v1.uScreenId.GetUInt32(puScreenId); AssertRC(rc);
     1332            if (puScreenID)
     1333                 rc = Msg.u.v1.uScreenId.GetUInt32(puScreenID);
    12931334        }
    12941335        else
    12951336        {
    12961337            /** @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);
    12981340        }
    12991341    }
     
    13081350 * @returns IPRT status code.
    13091351 * @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.
    13141355 */
    13151356static 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;
    13261369
    13271370    VBOXDNDGHDROPPEDMSG Msg;
     
    13301373    {
    13311374        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);
    13331376        Msg.u.v1.cbFormat.SetUInt32(0);
    13341377        Msg.u.v1.uAction.SetUInt32(0);
     
    13381381        VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_GH_EVT_DROPPED, 4);
    13391382        Msg.u.v3.uContext.SetUInt32(0);
    1340         Msg.u.v3.pvFormat.SetPtr(pszFormat, cbFormat);
     1383        Msg.u.v3.pvFormat.SetPtr(pszFormatTmp, cbFormatTmp);
    13411384        Msg.u.v3.cbFormat.SetUInt32(0);
    13421385        Msg.u.v3.uAction.SetUInt32(0);
     
    13481391        if (pCtx->uProtocol < 3)
    13491392        {
    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);
    13521397        }
    13531398        else
    13541399        {
    13551400            /** @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);
    13621416
    13631417    return rc;
     
    14691523 *
    14701524 * @returns IPRT status code.
    1471  * @param   pCtx                DnD context to use.
     1525 * @param   pCtx                DnD context to disconnect.
    14721526 *                              The context is invalid afterwards on successful disconnection.
    14731527 */
     
    14821536
    14831537/**
    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 */
     1550VBGLR3DECL(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;
    14991561    int rc = vbglR3DnDGetNextMsgType(pCtx, &uMsg, &cParms, true /* fWait */);
    15001562    if (RT_SUCCESS(rc))
     
    15201582    if (RT_SUCCESS(rc))
    15211583    {
    1522         pEvent->uType = uMsg;
     1584        LogFunc(("Handling uMsg=%RU32\n", uMsg));
    15231585
    15241586        switch(uMsg)
    15251587        {
    15261588            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            }
    15271603            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            }
    15281618            case HOST_DND_HG_EVT_DROPPED:
    15291619            {
    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 */);
    15341629                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;
    15451631                break;
    15461632            }
     
    15481634            {
    15491635                rc = vbglR3DnDHGRecvLeave(pCtx);
     1636                if (RT_SUCCESS(rc))
     1637                    pEvent->enmType = VBGLR3DNDEVENTTYPE_HG_LEAVE;
    15501638                break;
    15511639            }
    15521640            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();
    15551643            case HOST_DND_HG_SND_DATA_HDR:
    15561644            {
    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;
    15661648                break;
    15671649            }
    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();
    15691652            case HOST_DND_HG_SND_DIR:
     1653                RT_FALL_THROUGH();
    15701654            case HOST_DND_HG_SND_FILE_DATA:
    15711655            {
     
    15731657                 * All messages in this case are handled internally
    15741658                 * 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.
    15771660                 */
    15781661                rc = VERR_WRONG_ORDER;
     
    15821665            {
    15831666                rc = vbglR3DnDHGRecvCancel(pCtx);
     1667                if (RT_SUCCESS(rc))
     1668                    pEvent->enmType = VBGLR3DNDEVENTTYPE_HG_CANCEL;
    15841669                break;
    15851670            }
     
    15871672            case HOST_DND_GH_REQ_PENDING:
    15881673            {
    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;
    15901677                break;
    15911678            }
    15921679            case HOST_DND_GH_EVT_DROPPED:
    15931680            {
    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);
    15981685                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;
    16041687                break;
    16051688            }
     
    16141697
    16151698    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
    16171706    return rc;
    16181707}
    16191708
    16201709/**
    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 */
     1715VBGLR3DECL(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
    16291758VBGLR3DECL(int) VbglR3DnDHGSendAckOp(PVBGLR3GUESTDNDCMDCTX pCtx, uint32_t uAction)
    16301759{
Note: See TracChangeset for help on using the changeset viewer.

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