VirtualBox

Changeset 49891 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Dec 12, 2013 8:09:20 PM (11 years ago)
Author:
vboxsync
Message:

Merged private draganddrop branch into trunk.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/VBox

  • trunk/src/VBox/Main/src-client/GuestDnDImpl.cpp

    r45367 r49891  
    55
    66/*
    7  * Copyright (C) 2011-2012 Oracle Corporation
     7 * Copyright (C) 2011-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2929# include <VBox/HostServices/DragAndDropSvc.h>
    3030
     31# ifdef LOG_GROUP
     32 # undef LOG_GROUP
     33# endif
     34# define LOG_GROUP LOG_GROUP_GUEST_DND
     35# include <VBox/log.h>
     36
    3137# include <iprt/stream.h>
    3238# include <iprt/semaphore.h>
     
    4854 *    of it to the Main IGuest interface (see UIDnDHandler.cpp).
    4955 * 2. Main: Public interface for doing Drag and Drop. Also manage the IProgress
    50  *    interfaces for blocking the caller by showing a progress dialog. (see
    51  *    this file)
     56 *    interfaces for blocking the caller by showing a progress dialog (see
     57 *    this file).
    5258 * 3. HGCM service: Handle all messages from the host to the guest at once and
    53  *    encapsulate the internal communication details. (see dndmanager.cpp and
    54  *    friends)
     59 *    encapsulate the internal communication details (see dndmanager.cpp and
     60 *    friends).
    5561 * 4. Guest additions: Split into the platform neutral part (see
    5662 *    VBoxGuestR3LibDragAndDrop.cpp) and the guest OS specific parts.
    5763 *    Receive/send message from/to the HGCM service and does all guest specific
    58  *    operations. Currently only X11 is supported. (see draganddrop.cpp within
    59  *    VBoxClient)
    60  *
    61  * Host  -> Guest:
     64 *    operations. Currently only X11 is supported (see draganddrop.cpp within
     65 *    VBoxClient).
     66 *
     67 * Host -> Guest:
    6268 * 1. There are DnD Enter, Move, Leave events which are send exactly like this
    6369 *    to the guest. The info includes the pos, mimetypes and allowed actions.
     
    8692 * Dropping of a directory, means recursively transferring _all_ the content.
    8793 *
    88  * Directories and files are placed into a public visible user directory on the
    89  * guest (~/Documents/VirtualBox Dropped Files). We can't delete them after the
     94 * Directories and files are placed into the user's temporary directory on the
     95 * guest (e.g. /tmp/VirtualBox Dropped Files). We can't delete them after the
    9096 * DnD operation, because we didn't know what the DnD target does with it. E.g.
    9197 * it could just be opened in place. This could lead ofc to filling up the disk
     
    111117 * Cancel is supported in both directions and cleans up all previous steps
    112118 * (thats is: deleting already transfered dirs/files).
    113  *
    114  * There are a lot of DO (debug output) calls in the code. This could be
    115  * disabled, but should be removed (or replaced by Log calls) when this is
    116  * nearly finished.
    117  *
    118  * For Windows guests there could be different communication become necessary.
    119  * So the current interface isn't set in stone and should be made public only,
    120  * after someone had deeply looked into the Win guest support. See
    121  * http://www.catch22.net/tuts/dragdrop for a start.
    122  *
    123  * How to test:
    124  * First set VBOX_WITH_DRAG_AND_DROP=1 in LocalConfig.kmk. The best is if the
    125  * host match the guest OS arch. Just build the tree and point a shared folder
    126  * within the guest to the additions subfolder in bin. Start the guest and
    127  * execute ./VBoxClient --dragandrop --nodaemon within this shared folder. You
    128  * should now be able of dragging text or files to the guest. I used a 64bit
    129  * Linux for both the host and the guest. If the archs don't match, you need to
    130  * first setup a build environment in the guest ofc.
    131119 *
    132120 * In general I propose the following changes in the VBox HGCM infrastructure
     
    152140 * Todo:
    153141 * - Dragging out of the guest (partly done)
    154  *   - ESC doesn't really work
     142 *   - ESC doesn't really work (on Windows guests it's already implemented)
    155143 *   - transfer of URIs (that is the files and patching of the data)
    156144 *   - testing in a multi monitor setup
     
    230218
    231219    void adjustCoords(ULONG uScreenId, ULONG *puX, ULONG *puY) const;
    232     void hostCall(const char* psczFunction, uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const;
     220    void hostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const;
    233221
    234222    /* Static helper */
     
    254242/* What mime-types are supported by VirtualBox.
    255243 * Note: If you add something here, make sure you test it with all guest OS's!
     244 ** @todo Make this MIME list configurable / extendable (by extra data?). Currently
     245 *        this is done hardcoded on every guest platform (POSIX/Windows).
    256246 */
    257247/* static */
     
    296286int DnDGuestResponse::waitForGuestResponse()
    297287{
    298     return RTSemEventWait(m_EventSem, 300);
     288    int vrc = RTSemEventWait(m_EventSem, 300);
     289#ifdef DEBUG_andy
     290    LogFlowFunc(("rc=%Rrc\n", vrc));
     291#endif
     292    return vrc;
    299293}
    300294
     
    340334int DnDGuestResponse::setProgress(unsigned uPercentage, uint32_t uState, int rcOp /* = VINF_SUCCESS */)
    341335{
     336    LogFlowFunc(("uPercentage=%RU32, uState=%ld, rcOp=%Rrc\n", uPercentage, uState, rcOp));
     337
    342338    int vrc = VINF_SUCCESS;
    343     HRESULT rc;
    344339    if (!m_progress.isNull())
    345340    {
    346341        BOOL fCompleted;
    347         rc = m_progress->COMGETTER(Completed)(&fCompleted);
     342        HRESULT rc = m_progress->COMGETTER(Completed)(&fCompleted);
    348343        if (!fCompleted)
    349344        {
    350345            if (uState == DragAndDropSvc::DND_PROGRESS_ERROR)
     346            {
    351347                rc = m_progress->notifyComplete(E_FAIL,
    352348                                                COM_IIDOF(IGuest),
    353349                                                m_parent->getComponentName(),
    354350                                                m_parent->tr("Guest error (%Rrc)"), rcOp);
     351            }
    355352            else if (uState == DragAndDropSvc::DND_PROGRESS_CANCELLED)
    356                 rc = m_progress->notifyComplete(S_OK);
    357             else
     353            {
     354                rc = m_progress->Cancel();
     355                vrc = VERR_CANCELLED;
     356            }
     357            else /* uState == DragAndDropSvc::DND_PROGRESS_RUNNING */
    358358            {
    359359                rc = m_progress->SetCurrentOperationProgress(uPercentage);
     360#ifndef DEBUG_andy
     361                Assert(SUCCEEDED(rc));
     362#endif
    360363                if (   uState      == DragAndDropSvc::DND_PROGRESS_COMPLETE
    361364                    || uPercentage >= 100)
    362365                    rc = m_progress->notifyComplete(S_OK);
    363366            }
     367#ifndef DEBUG_andy
     368            Assert(SUCCEEDED(rc));
     369#endif
    364370        }
    365         BOOL fCanceled = FALSE;
    366         rc = m_progress->COMGETTER(Canceled)(&fCanceled);
    367         if (fCanceled)
    368             vrc = VERR_CANCELLED;
    369     }
     371    }
     372
    370373    return vrc;
    371374}
     
    391394}
    392395
    393 void GuestDnDPrivate::hostCall(const char* psczFunction, uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const
    394 {
    395     VMMDev *vmmDev = 0;
     396void GuestDnDPrivate::hostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const
     397{
     398    VMMDev *vmmDev = NULL;
    396399    {
    397400        /* Make sure mParent is valid, so set the read lock while using.
     
    409412                          p->tr("VMM device is not available (is the VM running?)"));
    410413
    411     LogFlowFunc(("hgcmHostCall msg=%s; numParms=%u\n", psczFunction, u32Function));
     414    LogFlowFunc(("hgcmHostCall msg=%RU32, numParms=%RU32\n", u32Function, cParms));
    412415    int vrc = vmmDev->hgcmHostCall("VBoxDragAndDropSvc",
    413416                                   u32Function,
     
    576579        paParms[i++].setUInt32(strFormats.length() + 1);
    577580
    578         d->hostCall("HOST_DND_HG_EVT_ENTER",
    579                     DragAndDropSvc::HOST_DND_HG_EVT_ENTER,
     581        d->hostCall(DragAndDropSvc::HOST_DND_HG_EVT_ENTER,
    580582                    i,
    581583                    paParms);
     
    588590        /* Copy the response info */
    589591        *pResultAction = d->toMainAction(pDnD->defAction());
     592        LogFlowFunc(("*pResultAction=%ld\n", *pResultAction));
    590593    }
    591594    catch (HRESULT rc2)
     
    636639        paParms[i++].setUInt32(strFormats.length() + 1);
    637640
    638         d->hostCall("HOST_DND_HG_EVT_MOVE",
    639                     DragAndDropSvc::HOST_DND_HG_EVT_MOVE,
     641        d->hostCall(DragAndDropSvc::HOST_DND_HG_EVT_MOVE,
    640642                    i,
    641643                    paParms);
     
    648650        /* Copy the response info */
    649651        *pResultAction = d->toMainAction(pDnD->defAction());
     652        LogFlowFunc(("*pResultAction=%ld\n", *pResultAction));
    650653    }
    651654    catch (HRESULT rc2)
     
    666669    try
    667670    {
    668         d->hostCall("HOST_DND_HG_EVT_LEAVE",
    669                     DragAndDropSvc::HOST_DND_HG_EVT_LEAVE,
     671        d->hostCall(DragAndDropSvc::HOST_DND_HG_EVT_LEAVE,
    670672                    0,
    671673                    NULL);
     
    722724        paParms[i++].setUInt32(strFormats.length() + 1);
    723725
    724         d->hostCall("HOST_DND_HG_EVT_DROPPED",
    725                     DragAndDropSvc::HOST_DND_HG_EVT_DROPPED,
     726        d->hostCall(DragAndDropSvc::HOST_DND_HG_EVT_DROPPED,
    726727                    i,
    727728                    paParms);
     
    735736        *pResultAction = d->toMainAction(pDnD->defAction());
    736737        Bstr(pDnD->format()).cloneTo(pstrFormat);
     738
     739        LogFlowFunc(("*pResultAction=%ld\n", *pResultAction));
    737740    }
    738741    catch (HRESULT rc2)
     
    768771        pDnD->resetProgress(p);
    769772
    770         d->hostCall("HOST_DND_HG_SND_DATA",
    771                     DragAndDropSvc::HOST_DND_HG_SND_DATA,
     773        d->hostCall(DragAndDropSvc::HOST_DND_HG_SND_DATA,
    772774                    i,
    773775                    paParms);
     
    801803        paParms[i++].setUInt32(uScreenId);
    802804
    803         d->hostCall("HOST_DND_GH_REQ_PENDING",
    804                     DragAndDropSvc::HOST_DND_GH_REQ_PENDING,
     805        d->hostCall(DragAndDropSvc::HOST_DND_GH_REQ_PENDING,
    805806                    i,
    806807                    paParms);
     
    855856        pDnD->resetProgress(p);
    856857
    857         d->hostCall("HOST_DND_GH_EVT_DROPPED",
    858                     DragAndDropSvc::HOST_DND_GH_EVT_DROPPED,
     858        d->hostCall(DragAndDropSvc::HOST_DND_GH_EVT_DROPPED,
    859859                    i,
    860860                    paParms);
     
    902902DECLCALLBACK(int) GuestDnD::notifyGuestDragAndDropEvent(void *pvExtension, uint32_t u32Function, void *pvParms, uint32_t cbParms)
    903903{
     904    LogFlowFunc(("pvExtension=%p, u32Function=%RU32, pvParms=%p, cbParms=%RU32\n",
     905                 pvExtension, u32Function, pvParms, cbParms));
     906
    904907    ComObjPtr<Guest> pGuest = reinterpret_cast<Guest*>(pvExtension);
    905908    if (!pGuest->m_pGuestDnD)
     
    909912    const ComObjPtr<Guest> &p = d->p;
    910913
    911     DnDGuestResponse *pDnD = d->response();
    912     if (pDnD == NULL)
     914    DnDGuestResponse *pResp = d->response();
     915    if (pResp == NULL)
    913916        return VERR_INVALID_PARAMETER;
    914917
     
    922925            AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBHGACKOPDATA) == cbParms, VERR_INVALID_PARAMETER);
    923926            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_HG_ACK_OP == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    924             pDnD->setDefAction(pCBData->uAction);
    925             rc = pDnD->notifyAboutGuestResponse();
     927            pResp->setDefAction(pCBData->uAction);
     928            rc = pResp->notifyAboutGuestResponse();
    926929            break;
    927930        }
     
    932935            AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBHGREQDATADATA) == cbParms, VERR_INVALID_PARAMETER);
    933936            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_HG_REQ_DATA == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    934             pDnD->setFormat(pCBData->pszFormat);
    935             rc = pDnD->notifyAboutGuestResponse();
     937            pResp->setFormat(pCBData->pszFormat);
     938            rc = pResp->notifyAboutGuestResponse();
    936939            break;
    937940        }
     
    942945            AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBHGEVTPROGRESSDATA) == cbParms, VERR_INVALID_PARAMETER);
    943946            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_HG_EVT_PROGRESS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    944             rc = pDnD->setProgress(pCBData->uPercentage, pCBData->uState);
     947            rc = pResp->setProgress(pCBData->uPercentage, pCBData->uState, pCBData->rc);
    945948            break;
    946949        }
     
    952955            AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBGHACKPENDINGDATA) == cbParms, VERR_INVALID_PARAMETER);
    953956            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_ACK_PENDING == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    954             pDnD->setFormat(pCBData->pszFormat);
    955             pDnD->setDefAction(pCBData->uDefAction);
    956             pDnD->setAllActions(pCBData->uAllActions);
    957             rc = pDnD->notifyAboutGuestResponse();
     957            pResp->setFormat(pCBData->pszFormat);
     958            pResp->setDefAction(pCBData->uDefAction);
     959            pResp->setAllActions(pCBData->uAllActions);
     960            rc = pResp->notifyAboutGuestResponse();
    958961            break;
    959962        }
     
    965968            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_SND_DATA == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    966969            uint32_t cbCurSize = 0;
    967             pDnD->addData(pCBData->pvData, pCBData->cbData, &cbCurSize);
    968             rc = pDnD->setProgress(100.0 / pCBData->cbAllSize * cbCurSize, (pCBData->cbAllSize == cbCurSize ? DragAndDropSvc::DND_PROGRESS_COMPLETE : DragAndDropSvc::DND_PROGRESS_RUNNING));
     970            pResp->addData(pCBData->pvData, pCBData->cbData, &cbCurSize);
     971            rc = pResp->setProgress(100.0 / pCBData->cbAllSize * cbCurSize, (pCBData->cbAllSize == cbCurSize ? DragAndDropSvc::DND_PROGRESS_COMPLETE : DragAndDropSvc::DND_PROGRESS_RUNNING));
    969972            /* Todo: for now we instantly confirm the cancel. Check if the
    970973             * guest should first clean up stuff itself and than really confirm
    971974             * the cancel request by an extra message. */
    972975            if (rc == VERR_CANCELLED)
    973                 pDnD->setProgress(100, DragAndDropSvc::DND_PROGRESS_CANCELLED);
     976                pResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_CANCELLED);
    974977            break;
    975978        }
     
    981984            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_EVT_ERROR == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    982985            /* Cleanup */
    983             pDnD->resetData();
    984             rc = pDnD->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc);
     986            pResp->resetData();
     987            rc = pResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc);
    985988            break;
    986989        }
    987990#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
    988         default: AssertMsgFailedReturn(("Function %u not recognized!\n", u32Function), VERR_INVALID_PARAMETER); break;
    989     }
    990 
     991        default:
     992            AssertMsgFailedReturn(("Function %RU32 not supported\n", u32Function), VERR_NOT_SUPPORTED);
     993            break;
     994    }
     995
     996    LogFlowFunc(("Returning rc=%Rrc\n", rc));
    991997    return rc;
    992998}
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