Changeset 50265 in vbox for trunk/src/VBox/Main/src-client
- Timestamp:
- Jan 29, 2014 11:12:44 AM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 91898
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/GuestDnDImpl.cpp
r49891 r50265 5 5 6 6 /* 7 * Copyright (C) 2011-201 3Oracle Corporation7 * Copyright (C) 2011-2014 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 167 167 class DnDGuestResponse 168 168 { 169 169 170 public: 171 170 172 DnDGuestResponse(const ComObjPtr<Guest>& pGuest); 171 ~DnDGuestResponse(); 172 173 int notifyAboutGuestResponse(); 174 int waitForGuestResponse(); 173 174 virtual ~DnDGuestResponse(void); 175 176 public: 177 178 int notifyAboutGuestResponse(void); 179 int waitForGuestResponse(RTMSINTERVAL msTimeout = 500); 175 180 176 181 void setDefAction(uint32_t a) { m_defAction = a; } 177 uint32_t defAction( ) const { return m_defAction; }182 uint32_t defAction(void) const { return m_defAction; } 178 183 179 184 void setAllActions(uint32_t a) { m_allActions = a; } … … 181 186 182 187 void setFormat(const Utf8Str &strFormat) { m_strFormat = strFormat; } 183 Utf8Str format( ) const { return m_strFormat; }184 185 int addData(void *pvData, uint32_t cbData, uint32_t *pcbCurSize);186 void reset Data();187 void data(void **ppvData, uint32_t *pcbData) const { *ppvData = m_pvData; *pcbData = m_cbData; }188 bool hasData() const { return m_pvData != NULL; }188 Utf8Str format(void) const { return m_strFormat; } 189 190 int dataAdd(void *pvData, uint32_t cbData, uint32_t *pcbCurSize); 191 void reset(void); 192 const void *data(void) { return m_pvData; } 193 size_t size(void) const { return m_cbData; } 189 194 190 195 int setProgress(unsigned uPercentage, uint32_t uState, int rcOp = VINF_SUCCESS); … … 213 218 , m_pDnDResponse(new DnDGuestResponse(pGuest)) 214 219 {} 215 ~GuestDnDPrivate() { delete m_pDnDResponse; }216 217 DnDGuestResponse *response( ) const { return m_pDnDResponse; }220 virtual ~GuestDnDPrivate(void) { delete m_pDnDResponse; } 221 222 DnDGuestResponse *response(void) const { return m_pDnDResponse; } 218 223 219 224 void adjustCoords(ULONG uScreenId, ULONG *puX, ULONG *puY) const; … … 274 279 DnDGuestResponse::~DnDGuestResponse() 275 280 { 276 reset Data();281 reset(); 277 282 int rc = RTSemEventDestroy(m_EventSem); 278 283 AssertRC(rc); … … 284 289 } 285 290 286 int DnDGuestResponse::waitForGuestResponse( )287 { 288 int vrc = RTSemEventWait(m_EventSem, 300);291 int DnDGuestResponse::waitForGuestResponse(RTMSINTERVAL msTimeout /*= 500 */) 292 { 293 int vrc = RTSemEventWait(m_EventSem, msTimeout); 289 294 #ifdef DEBUG_andy 290 LogFlowFunc((" rc=%Rrc\n", vrc));295 LogFlowFunc(("msTimeout=%RU32, rc=%Rrc\n", msTimeout, vrc)); 291 296 #endif 292 297 return vrc; 293 298 } 294 299 295 int DnDGuestResponse:: addData(void *pvData, uint32_t cbData, uint32_t *pcbCurSize)300 int DnDGuestResponse::dataAdd(void *pvData, uint32_t cbData, uint32_t *pcbCurSize) 296 301 { 297 302 int rc = VINF_SUCCESS; 303 304 /** @todo Make reallocation scheme a bit smarter here. */ 298 305 m_pvData = RTMemRealloc(m_pvData, m_cbData + cbData); 299 306 if (m_pvData) 300 307 { 301 memcpy(&static_cast<uint8_t*>(m_pvData)[m_cbData], pvData, cbData); 302 m_cbData += cbData; 303 *pcbCurSize = m_cbData; 308 memcpy(&static_cast<uint8_t*>(m_pvData)[m_cbData], 309 pvData, cbData); 310 m_cbData += cbData; 311 312 if (pcbCurSize) 313 *pcbCurSize = m_cbData; 304 314 } 305 315 else … … 309 319 } 310 320 311 void DnDGuestResponse::reset Data()321 void DnDGuestResponse::reset(void) 312 322 { 313 323 if (m_pvData) … … 316 326 m_pvData = NULL; 317 327 } 328 318 329 m_cbData = 0; 319 330 } … … 747 758 } 748 759 749 HRESULT GuestDnD::dragHGPutData(ULONG uScreenId, IN_BSTR bstrFormat, ComSafeArrayIn(BYTE, data), IProgress **ppProgress) 760 HRESULT GuestDnD::dragHGPutData(ULONG uScreenId, IN_BSTR bstrFormat, 761 ComSafeArrayIn(BYTE, data), IProgress **ppProgress) 750 762 { 751 763 DPTR(GuestDnD); … … 786 798 } 787 799 788 # ifdef VBOX_WITH_DRAG_AND_DROP_GH 789 HRESULT GuestDnD::dragGHPending(ULONG uScreenId, ComSafeArrayOut(BSTR, formats), ComSafeArrayOut(DragAndDropAction_T, allowedActions), DragAndDropAction_T *pDefaultAction) 800 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 801 HRESULT GuestDnD::dragGHPending(ULONG uScreenId, 802 ComSafeArrayOut(BSTR, formats), 803 ComSafeArrayOut(DragAndDropAction_T, allowedActions), 804 DragAndDropAction_T *pDefaultAction) 790 805 { 791 806 DPTR(GuestDnD); … … 821 836 /* Convert the action bit field to a vector of actions. */ 822 837 d->toMainActions(pDnD->allActions(), ComSafeArrayOutArg(allowedActions)); 838 839 LogFlowFunc(("*pDefaultAction=0x%x\n", *pDefaultAction)); 823 840 } 824 841 catch (HRESULT rc2) … … 830 847 } 831 848 832 HRESULT GuestDnD::dragGHDropped(IN_BSTR bstrFormat, DragAndDropAction_T action, IProgress **ppProgress) 849 HRESULT GuestDnD::dragGHDropped(IN_BSTR bstrFormat, DragAndDropAction_T action, 850 IProgress **ppProgress) 833 851 { 834 852 DPTR(GuestDnD); … … 845 863 try 846 864 { 865 LogFlowFunc(("strFormat=%s, uAction=0x%x\n", strFormat.c_str(), uAction)); 866 847 867 VBOXHGCMSVCPARM paParms[3]; 848 868 int i = 0; … … 853 873 DnDGuestResponse *pDnD = d->response(); 854 874 /* Reset any old data and the progress status. */ 855 pDnD->reset Data();875 pDnD->reset(); 856 876 pDnD->resetProgress(p); 857 877 … … 879 899 880 900 DnDGuestResponse *pDnD = d->response(); 881 /* Is there data at all? */ 882 if (pDnD->hasData()) 883 { 884 /* Copy the data into an safe array of bytes. */ 885 void *pvData = 0; 886 uint32_t cbData = 0; 887 pDnD->data(&pvData, &cbData); 888 com::SafeArray<BYTE> sfaData(cbData); 889 memcpy(sfaData.raw(), pvData, cbData); 901 if (pDnD) 902 { 903 com::SafeArray<BYTE> sfaData; 904 905 uint32_t cbData = pDnD->size(); 906 if (cbData) 907 { 908 /* Copy the data into an safe array of bytes. */ 909 const void *pvData = pDnD->data(); 910 if (sfaData.resize(cbData)) 911 memcpy(sfaData.raw(), pvData, cbData); 912 else 913 rc = E_OUTOFMEMORY; 914 } 915 916 #ifdef DEBUG_andy 917 LogFlowFunc(("Received %RU32 bytes\n", cbData)); 918 #endif 919 /* Detach in any case, regardless of data size. */ 890 920 sfaData.detachTo(ComSafeArrayOutArg(data)); 921 891 922 /* Delete the data. */ 892 pDnD->reset Data();923 pDnD->reset(); 893 924 } 894 925 else … … 897 928 return rc; 898 929 } 899 900 # endif /* VBOX_WITH_DRAG_AND_DROP_GH */ 930 #endif /* VBOX_WITH_DRAG_AND_DROP_GH */ 901 931 902 932 DECLCALLBACK(int) GuestDnD::notifyGuestDragAndDropEvent(void *pvExtension, uint32_t u32Function, void *pvParms, uint32_t cbParms) … … 929 959 break; 930 960 } 961 931 962 case DragAndDropSvc::GUEST_DND_HG_REQ_DATA: 932 963 { … … 939 970 break; 940 971 } 972 941 973 case DragAndDropSvc::GUEST_DND_HG_EVT_PROGRESS: 942 974 { … … 948 980 break; 949 981 } 982 950 983 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 951 984 case DragAndDropSvc::GUEST_DND_GH_ACK_PENDING: … … 961 994 break; 962 995 } 996 963 997 case DragAndDropSvc::GUEST_DND_GH_SND_DATA: 964 998 { … … 967 1001 AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBSNDDATADATA) == cbParms, VERR_INVALID_PARAMETER); 968 1002 AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_SND_DATA == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 1003 969 1004 uint32_t cbCurSize = 0; 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)); 1005 rc = pResp->dataAdd(pCBData->pvData, pCBData->cbData, &cbCurSize); 1006 if (RT_SUCCESS(rc)) 1007 { 1008 uint32_t cbTotalSize = pCBData->cbAllSize; 1009 unsigned int cPercentage; 1010 if (!cbTotalSize) /* Watch out for division by zero. */ 1011 cPercentage = 100; 1012 else 1013 cPercentage = cbCurSize * 100.0 / cbTotalSize; 1014 1015 /** @todo Don't use anonymous enums. */ 1016 uint32_t uState = DragAndDropSvc::DND_PROGRESS_RUNNING; 1017 if ( pCBData->cbAllSize == cbCurSize 1018 /* Empty data? Should not happen, but anyway ... */ 1019 || !pCBData->cbAllSize) 1020 { 1021 uState = DragAndDropSvc::DND_PROGRESS_COMPLETE; 1022 } 1023 1024 rc = pResp->setProgress(cPercentage, uState); 1025 } 972 1026 /* Todo: for now we instantly confirm the cancel. Check if the 973 1027 * guest should first clean up stuff itself and than really confirm … … 977 1031 break; 978 1032 } 1033 979 1034 case DragAndDropSvc::GUEST_DND_GH_EVT_ERROR: 980 1035 { … … 983 1038 AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBEVTERRORDATA) == cbParms, VERR_INVALID_PARAMETER); 984 1039 AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_EVT_ERROR == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 1040 985 1041 /* Cleanup */ 986 pResp->reset Data();1042 pResp->reset(); 987 1043 rc = pResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc); 988 1044 break; … … 990 1046 #endif /* VBOX_WITH_DRAG_AND_DROP_GH */ 991 1047 default: 992 AssertMsgFailedReturn(("Function %RU32 not supported\n", u32Function), VERR_NOT_SUPPORTED);1048 rc = VERR_NOT_SUPPORTED; /* Tell the guest. */ 993 1049 break; 994 1050 }
Note:
See TracChangeset
for help on using the changeset viewer.