VirtualBox

Ignore:
Timestamp:
Aug 6, 2015 7:19:19 PM (9 years ago)
Author:
vboxsync
Message:

DnD: Added support for "drag promises" on OS X for guest to host transfers, cleaned up MIME type conversion/handling, bugfixes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp

    r56909 r57221  
    177177}
    178178
    179 HRESULT GuestDnDTarget::getFormats(std::vector<com::Utf8Str> &aFormats)
     179HRESULT GuestDnDTarget::getFormats(GuestDnDMIMEList &aFormats)
    180180{
    181181#if !defined(VBOX_WITH_DRAG_AND_DROP)
     
    192192}
    193193
    194 HRESULT GuestDnDTarget::addFormats(const std::vector<com::Utf8Str> &aFormats)
     194HRESULT GuestDnDTarget::addFormats(const GuestDnDMIMEList &aFormats)
    195195{
    196196#if !defined(VBOX_WITH_DRAG_AND_DROP)
     
    207207}
    208208
    209 HRESULT GuestDnDTarget::removeFormats(const std::vector<com::Utf8Str> &aFormats)
     209HRESULT GuestDnDTarget::removeFormats(const GuestDnDMIMEList &aFormats)
    210210{
    211211#if !defined(VBOX_WITH_DRAG_AND_DROP)
     
    243243                              DnDAction_T                      aDefaultAction,
    244244                              const std::vector<DnDAction_T>  &aAllowedActions,
    245                               const std::vector<com::Utf8Str> &aFormats,
     245                              const GuestDnDMIMEList          &aFormats,
    246246                              DnDAction_T                     *aResultAction)
    247247{
     
    276276        return S_OK;
    277277
    278     /* Make a flat data string out of the supported format list. */
    279     Utf8Str strFormats = GuestDnD::toFormatString(m_vecFmtSup, aFormats);
    280 
    281     /* If there is no valid supported format, ignore this request. */
     278    /*
     279     * Make a flat data string out of the supported format list.
     280     * In the GuestDnDTarget case the source formats are from the host,
     281     * as GuestDnDTarget acts as a source for the guest.
     282     */
     283    Utf8Str strFormats = GuestDnD::toFormatString(GuestDnD::toFilteredFormatList(m_lstFmtSupported, aFormats));
    282284    if (strFormats.isEmpty())
    283         return setError(E_INVALIDARG, tr("Specified format(s) not supported"));
     285        return setError(E_INVALIDARG, tr("No or not supported format(s) specified"));
    284286
    285287    LogRel2(("DnD: Offered formats to guest:\n"));
     
    290292    /* Save the formats offered to the guest. This is needed to later
    291293     * decide what to do with the data when sending stuff to the guest. */
    292     m_vecFmtOff = aFormats;
    293     Assert(m_vecFmtOff.size());
     294    m_lstFmtOffered = aFormats;
     295    Assert(m_lstFmtOffered.size());
    294296
    295297    HRESULT hr = S_OK;
     
    335337                             DnDAction_T                      aDefaultAction,
    336338                             const std::vector<DnDAction_T>  &aAllowedActions,
    337                              const std::vector<com::Utf8Str> &aFormats,
     339                             const GuestDnDMIMEList          &aFormats,
    338340                             DnDAction_T                     *aResultAction)
    339341{
     
    359361        return S_OK;
    360362
    361     /* Make a flat data string out of the supported format list. */
    362     RTCString strFormats = GuestDnD::toFormatString(m_vecFmtSup, aFormats);
    363     /* If there is no valid supported format, ignore this request. */
     363    /*
     364     * Make a flat data string out of the supported format list.
     365     * In the GuestDnDTarget case the source formats are from the host,
     366     * as GuestDnDTarget acts as a source for the guest.
     367     */
     368    Utf8Str strFormats = GuestDnD::toFormatString(GuestDnD::toFilteredFormatList(m_lstFmtSupported, aFormats));
    364369    if (strFormats.isEmpty())
    365         return setError(E_INVALIDARG, tr("Specified format(s) not supported"));
     370        return setError(E_INVALIDARG, tr("No or not supported format(s) specified"));
    366371
    367372    HRESULT hr = S_OK;
     
    433438                             DnDAction_T                      aDefaultAction,
    434439                             const std::vector<DnDAction_T>  &aAllowedActions,
    435                              const std::vector<com::Utf8Str> &aFormats,
     440                             const GuestDnDMIMEList          &aFormats,
    436441                             com::Utf8Str                    &aFormat,
    437442                             DnDAction_T                     *aResultAction)
     
    441446#else /* VBOX_WITH_DRAG_AND_DROP */
    442447
    443     /* Input validation. */
    444 
    445     /* Everything else is optional. */
     448    if (aDefaultAction == DnDAction_Ignore)
     449        return setError(E_INVALIDARG, tr("Invalid default action specified"));
     450    if (!aAllowedActions.size())
     451        return setError(E_INVALIDARG, tr("Invalid allowed actions specified"));
     452    if (!aFormats.size())
     453        return setError(E_INVALIDARG, tr("No drop format(s) specified"));
     454    /* aResultAction is optional. */
    446455
    447456    AutoCaller autoCaller(this);
     
    449458
    450459    /* Default action is ignoring. */
    451     DnDAction_T resAction = DnDAction_Ignore;
    452 
    453     /* Check & convert the drag & drop actions. */
    454     uint32_t uDefAction      = 0;
     460    DnDAction_T resAction    = DnDAction_Ignore;
     461
     462    /* Check & convert the drag & drop actions to HGCM codes. */
     463    uint32_t uDefAction      = DND_IGNORE_ACTION;
    455464    uint32_t uAllowedActions = 0;
    456     GuestDnD::toHGCMActions(aDefaultAction, &uDefAction,
     465    GuestDnD::toHGCMActions(aDefaultAction,  &uDefAction,
    457466                            aAllowedActions, &uAllowedActions);
    458467    /* If there is no usable action, ignore this request. */
     
    465474    }
    466475
    467     /* Make a flat data string out of the supported format list. */
    468     Utf8Str strFormats = GuestDnD::toFormatString(m_vecFmtSup, aFormats);
    469     /* If there is no valid supported format, ignore this request. */
     476    /*
     477     * Make a flat data string out of the supported format list.
     478     * In the GuestDnDTarget case the source formats are from the host,
     479     * as GuestDnDTarget acts as a source for the guest.
     480     */
     481    Utf8Str strFormats = GuestDnD::toFormatString(GuestDnD::toFilteredFormatList(m_lstFmtSupported, aFormats));
    470482    if (strFormats.isEmpty())
    471         return setError(E_INVALIDARG, tr("Specified format(s) not supported"));
    472 
    473     HRESULT hr = S_OK;
     483        return setError(E_INVALIDARG, tr("No or not supported format(s) specified"));
    474484
    475485    /* Adjust the coordinates in a multi-monitor setup. */
    476     int rc = GuestDnDInst()->adjustScreenCoordinates(aScreenId, &aX, &aY);
    477     if (RT_SUCCESS(rc))
     486    HRESULT hr = GuestDnDInst()->adjustScreenCoordinates(aScreenId, &aX, &aY);
     487    if (SUCCEEDED(hr))
    478488    {
    479489        GuestDnDMsg Msg;
     
    487497        Msg.setNextUInt32(strFormats.length() + 1);
    488498
    489         rc = GuestDnDInst()->hostCall(Msg.getType(), Msg.getCount(), Msg.getParms());
     499        int rc = GuestDnDInst()->hostCall(Msg.getType(), Msg.getCount(), Msg.getParms());
    490500        if (RT_SUCCESS(rc))
    491501        {
    492502            GuestDnDResponse *pResp = GuestDnDInst()->response();
    493             if (pResp && RT_SUCCESS(pResp->waitForGuestResponse()))
     503            AssertPtr(pResp);
     504
     505            rc = pResp->waitForGuestResponse();
     506            if (RT_SUCCESS(rc))
    494507            {
    495508                resAction = GuestDnD::toMainAction(pResp->defAction());
    496                 aFormat = pResp->fmtReq();
    497 
    498                 LogFlowFunc(("resFormat=%s, resAction=%RU32\n",
    499                              pResp->fmtReq().c_str(), pResp->defAction()));
     509
     510                GuestDnDMIMEList lstFormats = pResp->formats();
     511                if (lstFormats.size() == 1) /* Exactly one format to use specified? */
     512                {
     513                    aFormat = lstFormats.at(0);
     514                    LogFlowFunc(("resFormat=%s, resAction=%RU32\n", aFormat.c_str(), pResp->defAction()));
     515                }
     516                else
     517                    hr = setError(VBOX_E_IPRT_ERROR, tr("Guest returned invalid drop formats (%zu formats)"), lstFormats.size());
    500518            }
    501         }
    502     }
    503 
    504     if (RT_FAILURE(rc))
    505         hr = VBOX_E_IPRT_ERROR;
     519            else
     520                hr = setError(VBOX_E_IPRT_ERROR, tr("Waiting for response of dropped event failed (%Rrc)"), rc);
     521        }
     522        else
     523            hr = setError(VBOX_E_IPRT_ERROR, tr("Sending dropped event to guest failed (%Rrc)"), rc);
     524    }
     525    else
     526        hr = setError(hr, tr("Retrieving drop coordinates failed"));
    506527
    507528    if (SUCCEEDED(hr))
     
    737758     *
    738759     ** @todo Support more than one format; add a format<->function handler concept. Later. */
    739     bool fHasURIList = std::find(m_vecFmtOff.begin(),
    740                                  m_vecFmtOff.end(), "text/uri-list") != m_vecFmtOff.end();
     760    bool fHasURIList = std::find(m_lstFmtOffered.begin(),
     761                                 m_lstFmtOffered.end(), "text/uri-list") != m_lstFmtOffered.end();
    741762    if (fHasURIList)
    742763    {
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