Changeset 49891 in vbox for trunk/src/VBox/Main
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/VBox-4.1 merged: 85944-85947,85949-85950,85953,86701,86728,87009 /branches/andy/draganddrop (added) merged: 90781-91268
- Property svn:mergeinfo changed
-
trunk/src/VBox
- Property svn:mergeinfo changed
/branches/andy/draganddrop/src/VBox (added) merged: 90781-91268
- Property svn:mergeinfo changed
-
trunk/src/VBox/Main/src-client/GuestDnDImpl.cpp
r45367 r49891 5 5 6 6 /* 7 * Copyright (C) 2011-201 2Oracle Corporation7 * Copyright (C) 2011-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 29 29 # include <VBox/HostServices/DragAndDropSvc.h> 30 30 31 # ifdef LOG_GROUP 32 # undef LOG_GROUP 33 # endif 34 # define LOG_GROUP LOG_GROUP_GUEST_DND 35 # include <VBox/log.h> 36 31 37 # include <iprt/stream.h> 32 38 # include <iprt/semaphore.h> … … 48 54 * of it to the Main IGuest interface (see UIDnDHandler.cpp). 49 55 * 2. Main: Public interface for doing Drag and Drop. Also manage the IProgress 50 * interfaces for blocking the caller by showing a progress dialog .(see51 * this file) 56 * interfaces for blocking the caller by showing a progress dialog (see 57 * this file). 52 58 * 3. HGCM service: Handle all messages from the host to the guest at once and 53 * encapsulate the internal communication details .(see dndmanager.cpp and54 * friends) 59 * encapsulate the internal communication details (see dndmanager.cpp and 60 * friends). 55 61 * 4. Guest additions: Split into the platform neutral part (see 56 62 * VBoxGuestR3LibDragAndDrop.cpp) and the guest OS specific parts. 57 63 * Receive/send message from/to the HGCM service and does all guest specific 58 * operations. Currently only X11 is supported .(see draganddrop.cpp within59 * VBoxClient) 60 * 61 * Host 64 * operations. Currently only X11 is supported (see draganddrop.cpp within 65 * VBoxClient). 66 * 67 * Host -> Guest: 62 68 * 1. There are DnD Enter, Move, Leave events which are send exactly like this 63 69 * to the guest. The info includes the pos, mimetypes and allowed actions. … … 86 92 * Dropping of a directory, means recursively transferring _all_ the content. 87 93 * 88 * Directories and files are placed into a public visible userdirectory on the89 * guest ( ~/Documents/VirtualBox Dropped Files). We can't delete them after the94 * 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 90 96 * DnD operation, because we didn't know what the DnD target does with it. E.g. 91 97 * it could just be opened in place. This could lead ofc to filling up the disk … … 111 117 * Cancel is supported in both directions and cleans up all previous steps 112 118 * (thats is: deleting already transfered dirs/files). 113 *114 * There are a lot of DO (debug output) calls in the code. This could be115 * disabled, but should be removed (or replaced by Log calls) when this is116 * 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. See121 * 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 the125 * host match the guest OS arch. Just build the tree and point a shared folder126 * within the guest to the additions subfolder in bin. Start the guest and127 * execute ./VBoxClient --dragandrop --nodaemon within this shared folder. You128 * should now be able of dragging text or files to the guest. I used a 64bit129 * Linux for both the host and the guest. If the archs don't match, you need to130 * first setup a build environment in the guest ofc.131 119 * 132 120 * In general I propose the following changes in the VBox HGCM infrastructure … … 152 140 * Todo: 153 141 * - 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) 155 143 * - transfer of URIs (that is the files and patching of the data) 156 144 * - testing in a multi monitor setup … … 230 218 231 219 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; 233 221 234 222 /* Static helper */ … … 254 242 /* What mime-types are supported by VirtualBox. 255 243 * 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). 256 246 */ 257 247 /* static */ … … 296 286 int DnDGuestResponse::waitForGuestResponse() 297 287 { 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; 299 293 } 300 294 … … 340 334 int DnDGuestResponse::setProgress(unsigned uPercentage, uint32_t uState, int rcOp /* = VINF_SUCCESS */) 341 335 { 336 LogFlowFunc(("uPercentage=%RU32, uState=%ld, rcOp=%Rrc\n", uPercentage, uState, rcOp)); 337 342 338 int vrc = VINF_SUCCESS; 343 HRESULT rc;344 339 if (!m_progress.isNull()) 345 340 { 346 341 BOOL fCompleted; 347 rc = m_progress->COMGETTER(Completed)(&fCompleted);342 HRESULT rc = m_progress->COMGETTER(Completed)(&fCompleted); 348 343 if (!fCompleted) 349 344 { 350 345 if (uState == DragAndDropSvc::DND_PROGRESS_ERROR) 346 { 351 347 rc = m_progress->notifyComplete(E_FAIL, 352 348 COM_IIDOF(IGuest), 353 349 m_parent->getComponentName(), 354 350 m_parent->tr("Guest error (%Rrc)"), rcOp); 351 } 355 352 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 */ 358 358 { 359 359 rc = m_progress->SetCurrentOperationProgress(uPercentage); 360 #ifndef DEBUG_andy 361 Assert(SUCCEEDED(rc)); 362 #endif 360 363 if ( uState == DragAndDropSvc::DND_PROGRESS_COMPLETE 361 364 || uPercentage >= 100) 362 365 rc = m_progress->notifyComplete(S_OK); 363 366 } 367 #ifndef DEBUG_andy 368 Assert(SUCCEEDED(rc)); 369 #endif 364 370 } 365 BOOL fCanceled = FALSE; 366 rc = m_progress->COMGETTER(Canceled)(&fCanceled); 367 if (fCanceled) 368 vrc = VERR_CANCELLED; 369 } 371 } 372 370 373 return vrc; 371 374 } … … 391 394 } 392 395 393 void GuestDnDPrivate::hostCall( const char* psczFunction,uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const394 { 395 VMMDev *vmmDev = 0;396 void GuestDnDPrivate::hostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const 397 { 398 VMMDev *vmmDev = NULL; 396 399 { 397 400 /* Make sure mParent is valid, so set the read lock while using. … … 409 412 p->tr("VMM device is not available (is the VM running?)")); 410 413 411 LogFlowFunc(("hgcmHostCall msg=% s; numParms=%u\n", psczFunction, u32Function));414 LogFlowFunc(("hgcmHostCall msg=%RU32, numParms=%RU32\n", u32Function, cParms)); 412 415 int vrc = vmmDev->hgcmHostCall("VBoxDragAndDropSvc", 413 416 u32Function, … … 576 579 paParms[i++].setUInt32(strFormats.length() + 1); 577 580 578 d->hostCall("HOST_DND_HG_EVT_ENTER", 579 DragAndDropSvc::HOST_DND_HG_EVT_ENTER, 581 d->hostCall(DragAndDropSvc::HOST_DND_HG_EVT_ENTER, 580 582 i, 581 583 paParms); … … 588 590 /* Copy the response info */ 589 591 *pResultAction = d->toMainAction(pDnD->defAction()); 592 LogFlowFunc(("*pResultAction=%ld\n", *pResultAction)); 590 593 } 591 594 catch (HRESULT rc2) … … 636 639 paParms[i++].setUInt32(strFormats.length() + 1); 637 640 638 d->hostCall("HOST_DND_HG_EVT_MOVE", 639 DragAndDropSvc::HOST_DND_HG_EVT_MOVE, 641 d->hostCall(DragAndDropSvc::HOST_DND_HG_EVT_MOVE, 640 642 i, 641 643 paParms); … … 648 650 /* Copy the response info */ 649 651 *pResultAction = d->toMainAction(pDnD->defAction()); 652 LogFlowFunc(("*pResultAction=%ld\n", *pResultAction)); 650 653 } 651 654 catch (HRESULT rc2) … … 666 669 try 667 670 { 668 d->hostCall("HOST_DND_HG_EVT_LEAVE", 669 DragAndDropSvc::HOST_DND_HG_EVT_LEAVE, 671 d->hostCall(DragAndDropSvc::HOST_DND_HG_EVT_LEAVE, 670 672 0, 671 673 NULL); … … 722 724 paParms[i++].setUInt32(strFormats.length() + 1); 723 725 724 d->hostCall("HOST_DND_HG_EVT_DROPPED", 725 DragAndDropSvc::HOST_DND_HG_EVT_DROPPED, 726 d->hostCall(DragAndDropSvc::HOST_DND_HG_EVT_DROPPED, 726 727 i, 727 728 paParms); … … 735 736 *pResultAction = d->toMainAction(pDnD->defAction()); 736 737 Bstr(pDnD->format()).cloneTo(pstrFormat); 738 739 LogFlowFunc(("*pResultAction=%ld\n", *pResultAction)); 737 740 } 738 741 catch (HRESULT rc2) … … 768 771 pDnD->resetProgress(p); 769 772 770 d->hostCall("HOST_DND_HG_SND_DATA", 771 DragAndDropSvc::HOST_DND_HG_SND_DATA, 773 d->hostCall(DragAndDropSvc::HOST_DND_HG_SND_DATA, 772 774 i, 773 775 paParms); … … 801 803 paParms[i++].setUInt32(uScreenId); 802 804 803 d->hostCall("HOST_DND_GH_REQ_PENDING", 804 DragAndDropSvc::HOST_DND_GH_REQ_PENDING, 805 d->hostCall(DragAndDropSvc::HOST_DND_GH_REQ_PENDING, 805 806 i, 806 807 paParms); … … 855 856 pDnD->resetProgress(p); 856 857 857 d->hostCall("HOST_DND_GH_EVT_DROPPED", 858 DragAndDropSvc::HOST_DND_GH_EVT_DROPPED, 858 d->hostCall(DragAndDropSvc::HOST_DND_GH_EVT_DROPPED, 859 859 i, 860 860 paParms); … … 902 902 DECLCALLBACK(int) GuestDnD::notifyGuestDragAndDropEvent(void *pvExtension, uint32_t u32Function, void *pvParms, uint32_t cbParms) 903 903 { 904 LogFlowFunc(("pvExtension=%p, u32Function=%RU32, pvParms=%p, cbParms=%RU32\n", 905 pvExtension, u32Function, pvParms, cbParms)); 906 904 907 ComObjPtr<Guest> pGuest = reinterpret_cast<Guest*>(pvExtension); 905 908 if (!pGuest->m_pGuestDnD) … … 909 912 const ComObjPtr<Guest> &p = d->p; 910 913 911 DnDGuestResponse *p DnD= d->response();912 if (p DnD== NULL)914 DnDGuestResponse *pResp = d->response(); 915 if (pResp == NULL) 913 916 return VERR_INVALID_PARAMETER; 914 917 … … 922 925 AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBHGACKOPDATA) == cbParms, VERR_INVALID_PARAMETER); 923 926 AssertReturn(DragAndDropSvc::CB_MAGIC_DND_HG_ACK_OP == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 924 p DnD->setDefAction(pCBData->uAction);925 rc = p DnD->notifyAboutGuestResponse();927 pResp->setDefAction(pCBData->uAction); 928 rc = pResp->notifyAboutGuestResponse(); 926 929 break; 927 930 } … … 932 935 AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBHGREQDATADATA) == cbParms, VERR_INVALID_PARAMETER); 933 936 AssertReturn(DragAndDropSvc::CB_MAGIC_DND_HG_REQ_DATA == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 934 p DnD->setFormat(pCBData->pszFormat);935 rc = p DnD->notifyAboutGuestResponse();937 pResp->setFormat(pCBData->pszFormat); 938 rc = pResp->notifyAboutGuestResponse(); 936 939 break; 937 940 } … … 942 945 AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBHGEVTPROGRESSDATA) == cbParms, VERR_INVALID_PARAMETER); 943 946 AssertReturn(DragAndDropSvc::CB_MAGIC_DND_HG_EVT_PROGRESS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 944 rc = p DnD->setProgress(pCBData->uPercentage, pCBData->uState);947 rc = pResp->setProgress(pCBData->uPercentage, pCBData->uState, pCBData->rc); 945 948 break; 946 949 } … … 952 955 AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBGHACKPENDINGDATA) == cbParms, VERR_INVALID_PARAMETER); 953 956 AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_ACK_PENDING == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 954 p DnD->setFormat(pCBData->pszFormat);955 p DnD->setDefAction(pCBData->uDefAction);956 p DnD->setAllActions(pCBData->uAllActions);957 rc = p DnD->notifyAboutGuestResponse();957 pResp->setFormat(pCBData->pszFormat); 958 pResp->setDefAction(pCBData->uDefAction); 959 pResp->setAllActions(pCBData->uAllActions); 960 rc = pResp->notifyAboutGuestResponse(); 958 961 break; 959 962 } … … 965 968 AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_SND_DATA == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 966 969 uint32_t cbCurSize = 0; 967 p DnD->addData(pCBData->pvData, pCBData->cbData, &cbCurSize);968 rc = p DnD->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)); 969 972 /* Todo: for now we instantly confirm the cancel. Check if the 970 973 * guest should first clean up stuff itself and than really confirm 971 974 * the cancel request by an extra message. */ 972 975 if (rc == VERR_CANCELLED) 973 p DnD->setProgress(100, DragAndDropSvc::DND_PROGRESS_CANCELLED);976 pResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_CANCELLED); 974 977 break; 975 978 } … … 981 984 AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_EVT_ERROR == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 982 985 /* Cleanup */ 983 p DnD->resetData();984 rc = p DnD->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc);986 pResp->resetData(); 987 rc = pResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc); 985 988 break; 986 989 } 987 990 #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)); 991 997 return rc; 992 998 }
Note:
See TracChangeset
for help on using the changeset viewer.