VirtualBox

Ignore:
Timestamp:
Oct 13, 2015 11:49:33 AM (9 years ago)
Author:
vboxsync
Message:

DnD: Updates.

  • Introduced protocol changelog in DragAndDropSvc.h.
  • Implemented protocol v3 with HOST_DND_HG_SND_DATA_HDR message for doing proper object accounting, among other parameters like checksumming and compression flags.
  • Encapsulated a lot of functionality in class hierarchies.
  • Renamed a lot of functions to make the usage more clear.
  • Various other bugfixes.
Location:
trunk/src/VBox/Frontends/VirtualBox/src/runtime
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDataObject_win.cpp

    r58069 r58212  
    4242UIDnDDataObject::UIDnDDataObject(UIDnDHandler *pDnDHandler, const QStringList &lstFormats)
    4343    : m_pDnDHandler(pDnDHandler)
    44     , mStatus(Uninitialized)
    45     , mRefCount(1)
    46     , mcFormats(0)
    47     , mpFormatEtc(NULL)
    48     , mpStgMedium(NULL)
    49     , mSemEvent(NIL_RTSEMEVENT)
    50     , mpvData(NULL)
    51     , mcbData(0)
     44    , m_enmStatus(DnDDataObjectStatus_Uninitialized)
     45    , m_cRefs(1)
     46    , m_cFormats(0)
     47    , m_pFormatEtc(NULL)
     48    , m_pStgMedium(NULL)
     49    , m_SemEvent(NIL_RTSEMEVENT)
     50    , m_fDataRetrieved(false)
     51    , m_pvData(NULL)
     52    , m_cbData(0)
    5253{
    5354    HRESULT hr;
     
    5859    try
    5960    {
    60         mpFormatEtc = new FORMATETC[cMaxFormats];
    61         RT_BZERO(mpFormatEtc, sizeof(FORMATETC) * cMaxFormats);
    62         mpStgMedium = new STGMEDIUM[cMaxFormats];
    63         RT_BZERO(mpStgMedium, sizeof(STGMEDIUM) * cMaxFormats);
     61        m_pFormatEtc = new FORMATETC[cMaxFormats];
     62        RT_BZERO(m_pFormatEtc, sizeof(FORMATETC) * cMaxFormats);
     63        m_pStgMedium = new STGMEDIUM[cMaxFormats];
     64        RT_BZERO(m_pStgMedium, sizeof(STGMEDIUM) * cMaxFormats);
    6465
    6566        for (int i = 0;
     
    6869        {
    6970            const QString &strFormat = lstFormats.at(i);
    70             if (mlstFormats.contains(strFormat))
     71            if (m_lstFormats.contains(strFormat))
    7172                continue;
    7273
     
    7475            if (strFormat.contains("text/uri-list", Qt::CaseInsensitive))
    7576            {
    76                 RegisterFormat(&mpFormatEtc[cRegisteredFormats], CF_TEXT);
    77                 mpStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;
    78                 RegisterFormat(&mpFormatEtc[cRegisteredFormats], CF_UNICODETEXT);
    79                 mpStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;
    80                 RegisterFormat(&mpFormatEtc[cRegisteredFormats], CF_HDROP);
    81                 mpStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;
    82 
    83                 mlstFormats << strFormat;
     77                RegisterFormat(&m_pFormatEtc[cRegisteredFormats], CF_TEXT);
     78                m_pStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;
     79                RegisterFormat(&m_pFormatEtc[cRegisteredFormats], CF_UNICODETEXT);
     80                m_pStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;
     81                RegisterFormat(&m_pFormatEtc[cRegisteredFormats], CF_HDROP);
     82                m_pStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;
     83
     84                m_lstFormats << strFormat;
    8485            }
    8586            /* Plain text ("text/plain"). */
    8687            if (strFormat.contains("text/plain", Qt::CaseInsensitive))
    8788            {
    88                 RegisterFormat(&mpFormatEtc[cRegisteredFormats], CF_TEXT);
    89                 mpStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;
    90                 RegisterFormat(&mpFormatEtc[cRegisteredFormats], CF_UNICODETEXT);
    91                 mpStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;
    92 
    93                 mlstFormats << strFormat;
     89                RegisterFormat(&m_pFormatEtc[cRegisteredFormats], CF_TEXT);
     90                m_pStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;
     91                RegisterFormat(&m_pFormatEtc[cRegisteredFormats], CF_UNICODETEXT);
     92                m_pStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;
     93
     94                m_lstFormats << strFormat;
    9495            }
    9596        }
     
    106107    if (SUCCEEDED(hr))
    107108    {
    108         int rc2 = RTSemEventCreate(&mSemEvent);
     109        int rc2 = RTSemEventCreate(&m_SemEvent);
    109110        AssertRC(rc2);
    110111
     
    130131                       RegisterClipboardFormat(CFSTR_SHELLIDLISTOFFSET));
    131132#endif
    132         mcFormats = cRegisteredFormats;
    133         mStatus   = Dropped;
     133        m_cFormats = cRegisteredFormats;
     134        m_enmStatus = DnDDataObjectStatus_Dropping;
    134135    }
    135136
     
    139140UIDnDDataObject::~UIDnDDataObject(void)
    140141{
    141     if (mpFormatEtc)
    142         delete[] mpFormatEtc;
    143 
    144     if (mpStgMedium)
    145         delete[] mpStgMedium;
    146 
    147     if (mpvData)
    148         RTMemFree(mpvData);
    149 
    150     if (mSemEvent != NIL_RTSEMEVENT)
    151         RTSemEventDestroy(mSemEvent);
    152 
    153     LogFlowFunc(("mRefCount=%RI32\n", mRefCount));
     142    if (m_pFormatEtc)
     143        delete[] m_pFormatEtc;
     144
     145    if (m_pStgMedium)
     146        delete[] m_pStgMedium;
     147
     148    if (m_pvData)
     149        RTMemFree(m_pvData);
     150
     151    if (m_SemEvent != NIL_RTSEMEVENT)
     152        RTSemEventDestroy(m_SemEvent);
     153
     154    LogFlowFunc(("mRefCount=%RI32\n", m_cRefs));
    154155}
    155156
     
    160161STDMETHODIMP_(ULONG) UIDnDDataObject::AddRef(void)
    161162{
    162     return InterlockedIncrement(&mRefCount);
     163    return InterlockedIncrement(&m_cRefs);
    163164}
    164165
    165166STDMETHODIMP_(ULONG) UIDnDDataObject::Release(void)
    166167{
    167     LONG lCount = InterlockedDecrement(&mRefCount);
     168    LONG lCount = InterlockedDecrement(&m_cRefs);
    168169    if (lCount == 0)
    169170    {
     
    210211    LPSTGMEDIUM pThisMedium = NULL;
    211212
     213    LogFlowThisFunc(("\n"));
     214
    212215    /* Format supported? */
    213216    ULONG lIndex;
    214217    if (   LookupFormatEtc(pFormatEtc, &lIndex)
    215         && lIndex < mcFormats) /* Paranoia. */
    216     {
    217         pThisMedium = &mpStgMedium[lIndex];
     218        && lIndex < m_cFormats) /* Paranoia. */
     219    {
     220        pThisMedium = &m_pStgMedium[lIndex];
    218221        AssertPtr(pThisMedium);
    219         pThisFormat = &mpFormatEtc[lIndex];
     222        pThisFormat = &m_pFormatEtc[lIndex];
    220223        AssertPtr(pThisFormat);
    221224
    222         LogFlowFunc(("pThisMedium=%p, pThisFormat=%p\n", pThisMedium, pThisFormat));
    223         LogFlowFunc(("mStatus=%ld\n", mStatus));
    224         switch (mStatus)
     225        LogFlowThisFunc(("pThisMedium=%p, pThisFormat=%p\n", pThisMedium, pThisFormat));
     226        LogFlowThisFunc(("mStatus=%RU32\n", m_enmStatus));
     227        switch (m_enmStatus)
    225228        {
    226             case Dropping:
     229            case DnDDataObjectStatus_Dropping:
    227230            {
    228                     LogRel3(("DnD: Dropping\n"));
    229                     LogFlowFunc(("Waiting for event ...\n"));
    230                     int rc2 = RTSemEventWait(mSemEvent, RT_INDEFINITE_WAIT);
    231                     LogFlowFunc(("rc=%Rrc, mStatus=%ld\n", rc2, mStatus));
     231#if 0
     232                LogRel3(("DnD: Dropping\n"));
     233                LogFlowFunc(("Waiting for event ...\n"));
     234                int rc2 = RTSemEventWait(m_SemEvent, RT_INDEFINITE_WAIT);
     235                LogFlowFunc(("rc=%Rrc, mStatus=%RU32\n", rc2, m_enmStatus));
     236#endif
     237                break;
    232238            }
    233239
    234             case Dropped:
     240            case DnDDataObjectStatus_Dropped:
    235241            {
    236242                LogRel3(("DnD: Dropped\n"));
     
    239245                         pThisFormat->tymed, pThisFormat->dwAspect));
    240246                LogRel3(("DnD: Got strFormat=%s, pvData=%p, cbData=%RU32\n",
    241                          mstrFormat.toAscii().constData(), mpvData, mcbData));
     247                         m_strFormat.toAscii().constData(), m_pvData, m_cbData));
    242248
    243249                QVariant::Type vaType;
     
    288294
    289295                int rc;
    290                 if (!mVaData.isValid())
     296
     297                if (!m_fDataRetrieved)
    291298                {
    292                     /* Note:  We're usig Qt::MoveAction because this speeds up the whole operation
    293                      *        significantly: Instead of copying the data from the temporary location to
    294                      *        the final destination we just move it.
    295                      *
    296                      * Note2: The Qt::MoveAction *only* affects the behavior on the host! The desired
    297                      *        action for the guest (e.g. moving a file from guest to host) is not affected
    298                      *        by this setting. */
    299                     rc = m_pDnDHandler->retrieveData(Qt::MoveAction,
    300                                                      strMIMEType, vaType, mVaData);
     299                    if (m_pDnDHandler)
     300                    {
     301                        rc = m_pDnDHandler->retrieveData(Qt::CopyAction,
     302                                                         strMIMEType, vaType, m_vaData);
     303                    }
     304                    else
     305                        rc = VERR_NOT_FOUND;
     306
     307                    m_fDataRetrieved = true;
     308                    LogFlowFunc(("Retrieving data ended with %Rrc\n", rc));
    301309                }
    302                 else
    303                     rc = VINF_SUCCESS; /* Data already retrieved. */
    304 
    305                 if (RT_SUCCESS(rc))
     310                else /* Data already been retrieved. */
     311                    rc = VINF_SUCCESS;
     312
     313                if (   RT_SUCCESS(rc)
     314                    && m_vaData.isValid())
    306315                {
    307316                    if (   strMIMEType.startsWith("text/uri-list")
    308317                               /* One item. */
    309                         && (   mVaData.canConvert(QVariant::String)
     318                        && (   m_vaData.canConvert(QVariant::String)
    310319                               /* Multiple items. */
    311                             || mVaData.canConvert(QVariant::StringList))
     320                            || m_vaData.canConvert(QVariant::StringList))
    312321                       )
    313322                    {
    314                         QStringList lstFilesURI = mVaData.toStringList();
     323                        QStringList lstFilesURI = m_vaData.toStringList();
    315324                        QStringList lstFiles;
    316325                        for (size_t i = 0; i < lstFilesURI.size(); i++)
     
    331340
    332341                        size_t cFiles = lstFiles.size();
     342                        LogFlowThisFunc(("Files (%zu)\n", cFiles));
    333343                        if (   RT_SUCCESS(rc)
    334344                            && cFiles)
    335345                        {
    336 #ifdef DEBUG
    337                             LogFlowFunc(("Files (%zu)\n", cFiles));
    338                             for (size_t i = 0; i < cFiles; i++)
    339                                 LogFlowFunc(("\tFile: %s\n", lstFiles.at(i).toAscii().constData()));
    340 #endif
    341                             size_t cchFiles = 0; /* Number of ASCII characters. */
     346                            size_t cchFiles = 0; /* Number of characters. */
    342347                            for (size_t i = 0; i < cFiles; i++)
    343348                            {
    344                                 cchFiles += strlen(lstFiles.at(i).toAscii().constData());
     349                                const char *pszFile = lstFiles.at(i).toAscii().constData();
     350                                cchFiles += strlen(pszFile);
    345351                                cchFiles += 1; /* Terminating '\0'. */
     352                                LogFlowThisFunc(("\tFile: %s (cchFiles=%zu)\n", pszFile, cchFiles));
    346353                            }
    347354
    348                             size_t cbBuf = sizeof(DROPFILES) + ((cchFiles + 1) * sizeof(RTUTF16));
     355                            /* List termination with '\0'. */
     356                            cchFiles++;
     357
     358                            size_t cbBuf = sizeof(DROPFILES) + (cchFiles * sizeof(RTUTF16));
    349359                            DROPFILES *pDropFiles = (DROPFILES *)RTMemAllocZ(cbBuf);
    350360                            if (pDropFiles)
    351361                            {
    352                                 pDropFiles->pFiles = sizeof(DROPFILES);
    353                                 pDropFiles->fWide = 1; /* We use unicode. Always. */
     362                                /* Put the files list right after our DROPFILES structure. */
     363                                pDropFiles->pFiles = sizeof(DROPFILES); /* Offset to file list. */
     364                                pDropFiles->fWide  = 1;                 /* We use Unicode. Always. */
    354365
    355366                                uint8_t *pCurFile = (uint8_t *)pDropFiles + pDropFiles->pFiles;
    356367                                AssertPtr(pCurFile);
    357368
     369                                LogFlowThisFunc(("Encoded:\n"));
    358370                                for (size_t i = 0; i < cFiles; i++)
    359371                                {
     372                                    const char *pszFile = lstFiles.at(i).toUtf8().constData();
     373                                    Assert(strlen(pszFile));
     374
    360375                                    size_t cchCurFile;
    361376                                    PRTUTF16 pwszFile;
    362                                     rc = RTStrToUtf16(lstFiles.at(i).toAscii().constData(), &pwszFile);
     377                                    rc = RTStrToUtf16(pszFile, &pwszFile);
    363378                                    if (RT_SUCCESS(rc))
    364379                                    {
     
    376391                                    *pCurFile = L'\0';
    377392                                    pCurFile += sizeof(RTUTF16);
     393
     394                                    LogFlowThisFunc(("\t#%zu: cchCurFile=%zu\n", i, cchCurFile));
    378395                                }
    379396
     
    382399                                    *pCurFile = L'\0'; /* Final list terminator. */
    383400
    384                                     pMedium->tymed = TYMED_HGLOBAL;
     401                                    /*
     402                                     * Fill out the medium structure we're going to report back.
     403                                     */
     404                                    pMedium->tymed          = TYMED_HGLOBAL;
    385405                                    pMedium->pUnkForRelease = NULL;
    386                                     pMedium->hGlobal = GlobalAlloc(  GMEM_ZEROINIT
    387                                                                    | GMEM_MOVEABLE
    388                                                                    | GMEM_DDESHARE, cbBuf);
     406                                    pMedium->hGlobal        = GlobalAlloc(  GMEM_ZEROINIT
     407                                                                          | GMEM_MOVEABLE
     408                                                                          | GMEM_DDESHARE, cbBuf);
    389409                                    if (pMedium->hGlobal)
    390410                                    {
     
    402422                                    else
    403423                                        rc = VERR_NO_MEMORY;
     424
     425                                    LogFlowThisFunc(("Copying to TYMED_HGLOBAL (%zu bytes): %Rrc\n", cbBuf, rc));
    404426                                }
    405427
    406428                                RTMemFree(pDropFiles);
    407429                            }
     430                            else
     431                                rc = VERR_NO_MEMORY;
     432
     433                            if (RT_FAILURE(rc))
     434                                LogFlowThisFunc(("Failed with %Rrc\n", rc));
    408435                        }
    409436                    }
    410437                    else if (   strMIMEType.startsWith("text/plain")
    411                              && mVaData.canConvert(QVariant::String))
     438                             && m_vaData.canConvert(QVariant::String))
    412439                    {
    413                         bool fUnicode = pFormatEtc->cfFormat == CF_UNICODETEXT;
    414                         int cbCh = fUnicode
    415                                  ? sizeof(WCHAR) : sizeof(char);
    416 
    417                         QString strText = mVaData.toString();
     440                        const bool fUnicode = pFormatEtc->cfFormat == CF_UNICODETEXT;
     441                        const size_t cbCh  = fUnicode
     442                                            ? sizeof(WCHAR) : sizeof(char);
     443
     444                        QString strText = m_vaData.toString();
    418445                        size_t cbSrc = strText.length() * cbCh;
    419446                        Assert(cbSrc);
     
    423450                        AssertPtr(pvSrc);
    424451
    425                         LogFlowFunc(("pvSrc=0x%p, cbSrc=%zu, cbch=%d, fUnicode=%RTbool\n",
     452                        LogFlowFunc(("pvSrc=0x%p, cbSrc=%zu, cbCh=%zu, fUnicode=%RTbool\n",
    426453                                     pvSrc, cbSrc, cbCh, fUnicode));
    427454
    428                         pMedium->tymed = TYMED_HGLOBAL;
     455                        pMedium->tymed          = TYMED_HGLOBAL;
    429456                        pMedium->pUnkForRelease = NULL;
    430                         pMedium->hGlobal = GlobalAlloc(  GMEM_ZEROINIT
    431                                                        | GMEM_MOVEABLE
    432                                                        | GMEM_DDESHARE,
    433                                                        cbSrc);
     457                        pMedium->hGlobal        = GlobalAlloc(GHND | GMEM_SHARE, cbSrc);
    434458                        if (pMedium->hGlobal)
    435459                        {
     
    449473                    }
    450474                    else
    451                         LogFlowFunc(("MIME type=%s not supported\n",
    452                                      strMIMEType.toAscii().constData()));
    453 
    454                     LogFlowFunc(("Handling formats ended with rc=%Rrc\n", rc));
     475                        LogRel2(("DnD: MIME type '%s' not supported\n", strMIMEType.toAscii().constData()));
     476
     477                    LogFlowThisFunc(("Handling formats ended with rc=%Rrc\n", rc));
    455478                }
     479
     480                break;
    456481            }
    457482
     
    488513    }
    489514
    490     LogFlowFunc(("Returning hr=%Rhrc\n", hr));
     515    LogFlowThisFunc(("Returning hr=%Rhrc\n", hr));
    491516    return hr;
    492517}
     
    535560{
    536561    LogFlowFunc(("dwDirection=%RI32, mcFormats=%RI32, mpFormatEtc=%p\n",
    537                  dwDirection, mcFormats, mpFormatEtc));
     562                 dwDirection, m_cFormats, m_pFormatEtc));
    538563
    539564    HRESULT hr;
    540565    if (dwDirection == DATADIR_GET)
    541566    {
    542         hr = UIDnDEnumFormatEtc::CreateEnumFormatEtc(mcFormats, mpFormatEtc, ppEnumFormatEtc);
     567        hr = UIDnDEnumFormatEtc::CreateEnumFormatEtc(m_cFormats, m_pFormatEtc, ppEnumFormatEtc);
    543568    }
    544569    else
     
    571596{
    572597    LogFlowFunc(("Aborting ...\n"));
    573     mStatus = Aborted;
    574     return RTSemEventSignal(mSemEvent);
     598    m_enmStatus = DnDDataObjectStatus_Aborted;
     599    return RTSemEventSignal(m_SemEvent);
    575600}
    576601
     
    661686    /* puIndex is optional. */
    662687
    663     for (ULONG i = 0; i < mcFormats; i++)
    664     {
    665         if(    (pFormatEtc->tymed & mpFormatEtc[i].tymed)
    666             && pFormatEtc->cfFormat == mpFormatEtc[i].cfFormat
    667             && pFormatEtc->dwAspect == mpFormatEtc[i].dwAspect)
     688    for (ULONG i = 0; i < m_cFormats; i++)
     689    {
     690        if(    (pFormatEtc->tymed & m_pFormatEtc[i].tymed)
     691            && pFormatEtc->cfFormat == m_pFormatEtc[i].cfFormat
     692            && pFormatEtc->dwAspect == m_pFormatEtc[i].dwAspect)
    668693        {
    669694            LogRel3(("DnD: Format found: tyMed=%RI32, cfFormat=%RI16, sFormats=%s, dwAspect=%RI32, ulIndex=%RU32\n",
    670                      pFormatEtc->tymed, pFormatEtc->cfFormat, UIDnDDataObject::ClipboardFormatToString(mpFormatEtc[i].cfFormat),
     695                     pFormatEtc->tymed, pFormatEtc->cfFormat, UIDnDDataObject::ClipboardFormatToString(m_pFormatEtc[i].cfFormat),
    671696                     pFormatEtc->dwAspect, i));
    672697
     
    677702    }
    678703
     704#if 0
    679705    LogRel3(("DnD: Format NOT found: tyMed=%RI32, cfFormat=%RI16, sFormats=%s, dwAspect=%RI32\n",
    680706             pFormatEtc->tymed, pFormatEtc->cfFormat, UIDnDDataObject::ClipboardFormatToString(pFormatEtc->cfFormat),
    681707             pFormatEtc->dwAspect));
     708#endif
    682709
    683710    return false;
    684 }
    685 
    686 /* static */
    687 HGLOBAL UIDnDDataObject::MemDup(HGLOBAL hMemSource)
    688 {
    689     DWORD dwLen    = GlobalSize(hMemSource);
    690     AssertReturn(dwLen, NULL);
    691     PVOID pvSource = GlobalLock(hMemSource);
    692     if (pvSource)
    693     {
    694         PVOID pvDest = GlobalAlloc(GMEM_FIXED, dwLen);
    695         if (pvDest)
    696             memcpy(pvDest, pvSource, dwLen);
    697 
    698         GlobalUnlock(hMemSource);
    699         return pvDest;
    700     }
    701 
    702     return NULL;
    703711}
    704712
     
    719727}
    720728
    721 void UIDnDDataObject::SetStatus(Status status)
    722 {
    723     LogFlowFunc(("Setting status to %ld\n", status));
    724     mStatus = status;
     729void UIDnDDataObject::SetStatus(DnDDataObjectStatus enmStatus)
     730{
     731    LogFlowFunc(("Setting status to %RU32\n", enmStatus));
     732    m_enmStatus = enmStatus;
     733}
     734
     735void UIDnDDataObject::Signal(void)
     736{
     737    SetStatus(DnDDataObjectStatus_Dropped);
    725738}
    726739
     
    732745    int rc;
    733746
    734     SetStatus(Dropped);
    735 
    736     mstrFormat = strFormat;
    737747    if (cbData)
    738748    {
    739         mpvData = RTMemAlloc(cbData);
    740         if (mpvData)
     749        m_pvData = RTMemAlloc(cbData);
     750        if (m_pvData)
    741751        {
    742             memcpy(mpvData, pvData, cbData);
    743             mcbData = cbData;
     752            memcpy(m_pvData, pvData, cbData);
     753            m_cbData = cbData;
    744754            rc = VINF_SUCCESS;
    745755        }
     
    750760        rc = VINF_SUCCESS;
    751761
    752     if (RT_FAILURE(rc))
    753         mStatus = Aborted;
     762    if (RT_SUCCESS(rc))
     763    {
     764        m_strFormat = strFormat;
     765        SetStatus(DnDDataObjectStatus_Dropped);
     766    }
     767    else
     768        SetStatus(DnDDataObjectStatus_Aborted);
    754769
    755770    /* Signal in any case. */
    756     int rc2 = RTSemEventSignal(mSemEvent);
     771    int rc2 = RTSemEventSignal(m_SemEvent);
    757772    if (RT_SUCCESS(rc))
    758773        rc = rc2;
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDataObject_win.h

    r56780 r58212  
    3737public:
    3838
    39     enum Status
     39    enum DnDDataObjectStatus
    4040    {
    41         Uninitialized = 0,
    42         Initialized,
    43         Dropping,
    44         Dropped,
    45         Aborted
     41        DnDDataObjectStatus_Uninitialized = 0,
     42        DnDDataObjectStatus_Initialized,
     43        DnDDataObjectStatus_Dropping,
     44        DnDDataObjectStatus_Dropped,
     45        DnDDataObjectStatus_Aborted,
     46        DnDDataObjectStatus_32Bit_Hack = 0x7fffffff
    4647    };
    4748
     
    7172public:
    7273
    73     static const char* ClipboardFormatToString(CLIPFORMAT fmt);
     74    static const char *ClipboardFormatToString(CLIPFORMAT fmt);
    7475
    7576    int Abort(void);
    76     void SetStatus(Status status);
     77    void Signal(void);
    7778    int Signal(const QString &strFormat, const void *pvData, uint32_t cbData);
    7879
    7980protected:
    8081
     82    void SetStatus(DnDDataObjectStatus enmStatus);
     83
    8184    bool LookupFormatEtc(LPFORMATETC pFormatEtc, ULONG *puIndex);
    82     static HGLOBAL MemDup(HGLOBAL hMemSource);
    8385    void RegisterFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat, TYMED tyMed = TYMED_HGLOBAL,
    8486                        LONG lindex = -1, DWORD dwAspect = DVASPECT_CONTENT, DVTARGETDEVICE *pTargetDevice = NULL);
    8587
    86     UIDnDHandler   *m_pDnDHandler;
    87 
    88     Status          mStatus;
    89     LONG            mRefCount;
     88    /** Pointe rto drag and drop handler. */
     89    UIDnDHandler           *m_pDnDHandler;
     90    /** Current drag and drop status. */
     91    DnDDataObjectStatus     m_enmStatus;
     92    /** Internal reference count of this object. */
     93    LONG                    m_cRefs;
    9094    /** Number of native formats registered. This can be a different number than supplied with mlstFormats. */
    91     ULONG           mcFormats;
    92     FORMATETC      *mpFormatEtc;
    93     STGMEDIUM      *mpStgMedium;
    94     RTSEMEVENT      mSemEvent;
    95     QStringList     mlstFormats;
    96     QString         mstrFormat;
     95    ULONG                   m_cFormats;
     96    FORMATETC              *m_pFormatEtc;
     97    STGMEDIUM              *m_pStgMedium;
     98    RTSEMEVENT              m_SemEvent;
     99    QStringList             m_lstFormats;
     100    QString                 m_strFormat;
    97101    /** The retrieved data as a QVariant. Needed for buffering in case a second format needs the same data,
    98102     *  e.g. CF_TEXT and CF_UNICODETEXT. */
    99     QVariant        mVaData;
     103    QVariant                m_vaData;
     104    /** Whether the data already was retrieved or not. */
     105    bool                    m_fDataRetrieved;
    100106    /** The retrieved data as a raw buffer. */
    101     void           *mpvData;
     107    void                   *m_pvData;
    102108    /** Raw buffer size (in bytes). */
    103     uint32_t        mcbData;
     109    uint32_t                m_cbData;
    104110};
    105111
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDropSource_win.cpp

    r56780 r58212  
    2424#include <iprt/thread.h>
    2525
     26/* Qt includes: */
     27#include <QApplication>
     28
     29/* Windows includes: */
     30#include <QApplication>
    2631#include <windows.h>
    2732#include <new> /* For bad_alloc. */
    2833
    2934#include "UIDnDDropSource_win.h"
     35#include "UIDnDDataObject_win.h"
    3036
    31 
    32 
    33 UIDnDDropSource::UIDnDDropSource(QWidget *pParent)
    34     : mRefCount(1),
    35       mpParent(pParent),
    36       mdwCurEffect(0),
    37       muCurAction(Qt::IgnoreAction)
     37UIDnDDropSource::UIDnDDropSource(QWidget *pParent, UIDnDDataObject *pDataObject)
     38    : m_cRefCount(1)
     39    , m_pParent(pParent)
     40    , m_pDataObject(pDataObject)
     41    , m_dwCurEffect(DROPEFFECT_NONE)
     42    , m_uCurAction(Qt::IgnoreAction)
    3843{
    39     LogFlowFunc(("pParent=0x%p\n", mpParent));
     44    LogFlowFunc(("pParent=0x%p\n", m_pParent));
    4045}
    4146
    4247UIDnDDropSource::~UIDnDDropSource(void)
    4348{
    44     LogFlowFunc(("mRefCount=%RI32\n", mRefCount));
     49    LogFlowFunc(("mRefCount=%RU32\n", m_cRefCount));
    4550}
    4651
     
    5156STDMETHODIMP_(ULONG) UIDnDDropSource::AddRef(void)
    5257{
    53     return InterlockedIncrement(&mRefCount);
     58    LogFlowFunc(("mRefCount=%RU32\n", m_cRefCount + 1));
     59    return (ULONG)InterlockedIncrement(&m_cRefCount);
    5460}
    5561
    5662STDMETHODIMP_(ULONG) UIDnDDropSource::Release(void)
    5763{
    58     LONG lCount = InterlockedDecrement(&mRefCount);
    59     if (lCount == 0)
     64    Assert(m_cRefCount > 0);
     65    LogFlowFunc(("mRefCount=%RU32\n", m_cRefCount - 1));
     66    LONG lCount = InterlockedDecrement(&m_cRefCount);
     67    if (lCount <= 0)
    6068    {
    6169        delete this;
     
    6371    }
    6472
    65     return lCount;
     73    return (ULONG)lCount;
    6674}
    6775
     
    94102STDMETHODIMP UIDnDDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD dwKeyState)
    95103{
    96 #ifndef DEBUG_andy
    97     LogFlowFunc(("fEscapePressed=%RTbool, dwKeyState=0x%x, mdwCurEffect=%RI32, muCurAction=%RU32\n",
    98                  fEscapePressed, dwKeyState, mdwCurEffect, muCurAction));
    99 #endif
     104    LogFlowFunc(("fEscapePressed=%RTbool, dwKeyState=0x%x, m_dwCurEffect=%RI32, m_uCurAction=%RU32\n",
     105                 RT_BOOL(fEscapePressed), dwKeyState, m_dwCurEffect, m_uCurAction));
    100106
    101107    /* ESC pressed? Bail out. */
    102108    if (fEscapePressed)
    103109    {
    104         mdwCurEffect = 0;
    105         muCurAction = Qt::IgnoreAction;
     110        m_dwCurEffect = DROPEFFECT_NONE;
     111        m_uCurAction = Qt::IgnoreAction;
    106112
    107113        LogRel2(("DnD: User cancelled dropping data to the host\n"));
     
    118124    if (fDropContent)
    119125    {
     126        if (m_pDataObject)
     127            m_pDataObject->Signal();
     128
    120129        LogRel2(("DnD: User dropped data to the host\n"));
    121130        return DRAGDROP_S_DROP;
    122131    }
     132
     133    QApplication::processEvents();
    123134
    124135    /* No change, just continue. */
     
    134145STDMETHODIMP UIDnDDropSource::GiveFeedback(DWORD dwEffect)
    135146{
    136      Qt::DropActions dropActions = Qt::IgnoreAction;
     147    Qt::DropActions dropActions = Qt::IgnoreAction;
    137148
    138 #ifndef DEBUG_andy
    139149    LogFlowFunc(("dwEffect=0x%x\n", dwEffect));
    140 #endif
    141150    if (dwEffect)
    142151    {
     
    147156        if (dwEffect & DROPEFFECT_LINK)
    148157            dropActions |= Qt::LinkAction;
     158
     159        m_dwCurEffect = dwEffect;
    149160    }
    150161
    151     mdwCurEffect = dwEffect;
    152     muCurAction = dropActions;
     162    m_uCurAction  = dropActions;
    153163
    154164    return DRAGDROP_S_USEDEFAULTCURSORS;
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDropSource_win.h

    r55821 r58212  
    2222#include "COMEnums.h"
    2323
     24class UIDnDDataObject;
     25
     26/**
     27 * Implementation of IDropSource for drag and drop on the host.
     28 */
    2429class UIDnDDropSource : public IDropSource
    2530{
    2631public:
    2732
    28     UIDnDDropSource(QWidget *pParent);
     33    UIDnDDropSource(QWidget *pParent, UIDnDDataObject *pDataObject);
    2934    virtual ~UIDnDDropSource(void);
    3035
    3136public:
    3237
    33     uint32_t GetCurrentAction(void) { return muCurAction; }
     38    uint32_t GetCurrentAction(void) const { return m_uCurAction; }
    3439
    3540public: /* IUnknown methods. */
     
    4651protected:
    4752
    48     LONG             mRefCount;
    49     QWidget         *mpParent;
    50     DWORD            mdwCurEffect;
    51     Qt::DropActions  muCurAction;
     53    /** Pointer to parent widget. */
     54    QWidget         *m_pParent;
     55    UIDnDDataObject *m_pDataObject;
     56    /** The current reference count. */
     57    LONG             m_cRefCount;
     58    /** Current (last) drop effect issued. */
     59    DWORD            m_dwCurEffect;
     60    /** Current drop action to perform in case of a successful drop. */
     61    Qt::DropActions  m_uCurAction;
    5262};
    5363
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDHandler.cpp

    r57292 r58212  
    335335
    336336# ifdef RT_OS_WINDOWS
    337 
    338     UIDnDDropSource *pDropSource = new UIDnDDropSource(m_pParent);
    339     if (!pDropSource)
    340         return VERR_NO_MEMORY;
    341337    UIDnDDataObject *pDataObject = new UIDnDDataObject(this, lstFormats);
    342338    if (!pDataObject)
     339        return VERR_NO_MEMORY;
     340    UIDnDDropSource *pDropSource = new UIDnDDropSource(m_pParent, pDataObject);
     341    if (!pDropSource)
    343342        return VERR_NO_MEMORY;
    344343
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDMIMEData.cpp

    r57288 r58212  
    109109
    110110    /* Let the user know. */
    111     LogRel(("Drag and drop support for OS X is disabled in this version."));
     111    LogRel(("DnD: Drag and drop support for OS X is not available in this version\n"));
    112112# endif /* VBOX_WITH_DRAG_AND_DROP_PROMISES */
    113113#else /* !RT_OS_DARWIN */
     
    120120    {
    121121        LogFlowFunc(("Current drop action is 0x%x, so can't drop yet\n", m_curAction));
    122         rc = VERR_WRONG_ORDER;
     122        rc = VERR_NOT_FOUND;
    123123    }
    124124#endif
     
    172172
    173173    if (RT_FAILURE(rc))
    174         LogRel(("DnD: Retrieving data failed with %Rrc\n", rc));
     174        LogRel2(("DnD: Retrieving data failed with %Rrc\n", rc));
    175175
    176176    return QVariant(QVariant::Invalid);
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp

    r58011 r58212  
    101101
    102102
    103 #ifdef DEBUG_andy
     103#ifdef DEBUG
     104# ifdef DEBUG_andy
    104105/* Macro for debugging drag and drop actions which usually would
    105106 * go to Main's logging group. */
    106 # define DNDDEBUG(x) LogRel(x)
    107 #else
    108 # define DNDDEBUG(x)
     107#  define DNDDEBUG(x) LogFlowFunc(x)
     108# else
     109#  define DNDDEBUG(x)
     110# endif
    109111#endif
    110112
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