Changeset 97740 in vbox for trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
- Timestamp:
- Dec 5, 2022 9:00:05 AM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
r97739 r97740 821 821 m_cFailedPendingAttempts = 0; 822 822 823 m_eventQueueList.clear();824 825 823 /* Reset the selection request buffer. */ 826 824 if (m_pvSelReqData) … … 831 829 Assert(m_cbSelReqData); 832 830 m_cbSelReqData = 0; 831 } 832 833 rc2 = RTCritSectEnter(&m_eventQueueCS); 834 if (RT_SUCCESS(rc2)) 835 { 836 m_eventQueueList.clear(); 837 838 rc2 = RTCritSectLeave(&m_eventQueueCS); 839 AssertRC(rc2); 833 840 } 834 841 … … 2830 2837 XFlush(m_pDisplay); 2831 2838 2832 m_eventQueueList.clear();2833 2834 2839 return VINF_SUCCESS; /** @todo Add error checking. */ 2835 2840 } … … 3319 3324 RT_ZERO(e); 3320 3325 3321 LogFlowFunc(("Waiting for new event ...\n"));3326 LogFlowFunc(("Waiting for new events ...\n")); 3322 3327 rc = RTSemEventWait(m_hEventSem, RT_INDEFINITE_WAIT); 3323 3328 if (RT_FAILURE(rc)) 3324 3329 break; 3325 3330 3326 AssertMsg(m_eventQueue.size(), ("Event queue is empty when it shouldn't\n")); 3327 3328 e = m_eventQueue.first(); 3329 m_eventQueue.removeFirst(); 3330 3331 if (e.enmType == DNDEVENT::DnDEventType_HGCM) 3331 size_t cEvents = 0; 3332 3333 int rc2 = RTCritSectEnter(&m_eventQueueCS); 3334 if (RT_SUCCESS(rc2)) 3332 3335 { 3333 PVBGLR3DNDEVENT pVbglR3Event = e.hgcm; 3334 AssertPtrBreak(pVbglR3Event); 3335 3336 LogFlowThisFunc(("HGCM event, enmType=%RU32\n", pVbglR3Event->enmType)); 3337 switch (pVbglR3Event->enmType) 3336 cEvents = m_eventQueue.size(); 3337 3338 rc2 = RTCritSectLeave(&m_eventQueueCS); 3339 AssertRC(rc2); 3340 } 3341 3342 while (cEvents) 3343 { 3344 rc2 = RTCritSectEnter(&m_eventQueueCS); 3345 if (RT_SUCCESS(rc2)) 3338 3346 { 3339 case VBGLR3DNDEVENTTYPE_HG_ENTER:3347 if (m_eventQueue.isEmpty()) 3340 3348 { 3341 if (pVbglR3Event->u.HG_Enter.cbFormats) 3349 rc2 = RTCritSectLeave(&m_eventQueueCS); 3350 AssertRC(rc2); 3351 break; 3352 } 3353 3354 e = m_eventQueue.first(); 3355 m_eventQueue.removeFirst(); 3356 3357 rc2 = RTCritSectLeave(&m_eventQueueCS); 3358 AssertRC(rc2); 3359 } 3360 3361 if (e.enmType == DNDEVENT::DnDEventType_HGCM) 3362 { 3363 PVBGLR3DNDEVENT pVbglR3Event = e.hgcm; 3364 AssertPtrBreak(pVbglR3Event); 3365 3366 LogFlowThisFunc(("HGCM event enmType=%RU32\n", pVbglR3Event->enmType)); 3367 switch (pVbglR3Event->enmType) 3368 { 3369 case VBGLR3DNDEVENTTYPE_HG_ENTER: 3342 3370 { 3343 RTCList<RTCString> lstFormats = 3344 RTCString(pVbglR3Event->u.HG_Enter.pszFormats, pVbglR3Event->u.HG_Enter.cbFormats - 1).split("\r\n"); 3345 rc = m_pCurDnD->hgEnter(lstFormats, pVbglR3Event->u.HG_Enter.dndLstActionsAllowed); 3346 if (RT_FAILURE(rc)) 3371 if (pVbglR3Event->u.HG_Enter.cbFormats) 3372 { 3373 RTCList<RTCString> lstFormats = 3374 RTCString(pVbglR3Event->u.HG_Enter.pszFormats, pVbglR3Event->u.HG_Enter.cbFormats - 1).split("\r\n"); 3375 rc = m_pCurDnD->hgEnter(lstFormats, pVbglR3Event->u.HG_Enter.dndLstActionsAllowed); 3376 if (RT_FAILURE(rc)) 3377 break; 3378 /* Enter is always followed by a move event. */ 3379 } 3380 else 3381 { 3382 AssertMsgFailed(("cbFormats is 0\n")); 3383 rc = VERR_INVALID_PARAMETER; 3347 3384 break; 3348 /* Enter is always followed by a move event. */ 3385 } 3386 3387 /* Note: After HOST_DND_FN_HG_EVT_ENTER there immediately is a move 3388 * event, so fall through is intentional here. */ 3389 RT_FALL_THROUGH(); 3349 3390 } 3350 else 3391 3392 case VBGLR3DNDEVENTTYPE_HG_MOVE: 3351 3393 { 3352 AssertMsgFailed(("cbFormats is 0\n"));3353 rc = VERR_INVALID_PARAMETER;3394 rc = m_pCurDnD->hgMove(pVbglR3Event->u.HG_Move.uXpos, pVbglR3Event->u.HG_Move.uYpos, 3395 pVbglR3Event->u.HG_Move.dndActionDefault); 3354 3396 break; 3355 3397 } 3356 3398 3357 /* Note: After HOST_DND_FN_HG_EVT_ENTER there immediately is a move 3358 * event, so fall through is intentional here. */ 3359 RT_FALL_THROUGH(); 3399 case VBGLR3DNDEVENTTYPE_HG_LEAVE: 3400 { 3401 rc = m_pCurDnD->hgLeave(); 3402 break; 3403 } 3404 3405 case VBGLR3DNDEVENTTYPE_HG_DROP: 3406 { 3407 rc = m_pCurDnD->hgDrop(pVbglR3Event->u.HG_Drop.uXpos, pVbglR3Event->u.HG_Drop.uYpos, 3408 pVbglR3Event->u.HG_Drop.dndActionDefault); 3409 break; 3410 } 3411 3412 /* Note: VbglR3DnDRecvNextMsg() will return HOST_DND_FN_HG_SND_DATA_HDR when 3413 * the host has finished copying over all the data to the guest. 3414 * 3415 * The actual data transfer (and message processing for it) will be done 3416 * internally by VbglR3DnDRecvNextMsg() to not duplicate any code for different 3417 * platforms. 3418 * 3419 * The data header now will contain all the (meta) data the guest needs in 3420 * order to complete the DnD operation. */ 3421 case VBGLR3DNDEVENTTYPE_HG_RECEIVE: 3422 { 3423 rc = m_pCurDnD->hgDataReceive(&pVbglR3Event->u.HG_Received.Meta); 3424 break; 3425 } 3426 3427 case VBGLR3DNDEVENTTYPE_HG_CANCEL: 3428 { 3429 m_pCurDnD->reset(); /** @todo Test this! */ 3430 break; 3431 } 3432 3433 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 3434 case VBGLR3DNDEVENTTYPE_GH_ERROR: 3435 { 3436 m_pCurDnD->reset(); 3437 break; 3438 } 3439 3440 case VBGLR3DNDEVENTTYPE_GH_REQ_PENDING: 3441 { 3442 rc = m_pCurDnD->ghIsDnDPending(); 3443 break; 3444 } 3445 3446 case VBGLR3DNDEVENTTYPE_GH_DROP: 3447 { 3448 rc = m_pCurDnD->ghDropped(pVbglR3Event->u.GH_Drop.pszFormat, pVbglR3Event->u.GH_Drop.dndActionRequested); 3449 break; 3450 } 3451 #endif 3452 case VBGLR3DNDEVENTTYPE_QUIT: 3453 { 3454 rc = VINF_SUCCESS; 3455 break; 3456 } 3457 3458 default: 3459 { 3460 VBClLogError("Received unsupported message type %RU32\n", pVbglR3Event->enmType); 3461 rc = VERR_NOT_SUPPORTED; 3462 break; 3463 } 3360 3464 } 3361 3465 3362 case VBGLR3DNDEVENTTYPE_HG_MOVE: 3466 LogFlowFunc(("Message %RU32 processed with %Rrc\n", pVbglR3Event->enmType, rc)); 3467 if (RT_FAILURE(rc)) 3363 3468 { 3364 rc = m_pCurDnD->hgMove(pVbglR3Event->u.HG_Move.uXpos, pVbglR3Event->u.HG_Move.uYpos, 3365 pVbglR3Event->u.HG_Move.dndActionDefault); 3469 /* Tell the user. */ 3470 VBClLogError("Processing message %RU32 failed with %Rrc\n", pVbglR3Event->enmType, rc); 3471 3472 /* If anything went wrong, do a reset and start over. */ 3473 reset(); 3474 } 3475 3476 const bool fQuit = pVbglR3Event->enmType == VBGLR3DNDEVENTTYPE_QUIT; 3477 3478 VbglR3DnDEventFree(e.hgcm); 3479 e.hgcm = NULL; 3480 3481 if (fQuit) 3366 3482 break; 3367 }3368 3369 case VBGLR3DNDEVENTTYPE_HG_LEAVE:3370 {3371 rc = m_pCurDnD->hgLeave();3372 break;3373 }3374 3375 case VBGLR3DNDEVENTTYPE_HG_DROP:3376 {3377 rc = m_pCurDnD->hgDrop(pVbglR3Event->u.HG_Drop.uXpos, pVbglR3Event->u.HG_Drop.uYpos,3378 pVbglR3Event->u.HG_Drop.dndActionDefault);3379 break;3380 }3381 3382 /* Note: VbglR3DnDRecvNextMsg() will return HOST_DND_FN_HG_SND_DATA_HDR when3383 * the host has finished copying over all the data to the guest.3384 *3385 * The actual data transfer (and message processing for it) will be done3386 * internally by VbglR3DnDRecvNextMsg() to not duplicate any code for different3387 * platforms.3388 *3389 * The data header now will contain all the (meta) data the guest needs in3390 * order to complete the DnD operation. */3391 case VBGLR3DNDEVENTTYPE_HG_RECEIVE:3392 {3393 rc = m_pCurDnD->hgDataReceive(&pVbglR3Event->u.HG_Received.Meta);3394 break;3395 }3396 3397 case VBGLR3DNDEVENTTYPE_HG_CANCEL:3398 {3399 m_pCurDnD->reset(); /** @todo Test this! */3400 break;3401 }3402 3403 #ifdef VBOX_WITH_DRAG_AND_DROP_GH3404 case VBGLR3DNDEVENTTYPE_GH_ERROR:3405 {3406 m_pCurDnD->reset();3407 break;3408 }3409 3410 case VBGLR3DNDEVENTTYPE_GH_REQ_PENDING:3411 {3412 rc = m_pCurDnD->ghIsDnDPending();3413 break;3414 }3415 3416 case VBGLR3DNDEVENTTYPE_GH_DROP:3417 {3418 rc = m_pCurDnD->ghDropped(pVbglR3Event->u.GH_Drop.pszFormat, pVbglR3Event->u.GH_Drop.dndActionRequested);3419 break;3420 }3421 #endif3422 case VBGLR3DNDEVENTTYPE_QUIT:3423 {3424 rc = VINF_SUCCESS;3425 break;3426 }3427 3428 default:3429 {3430 VBClLogError("Received unsupported message type %RU32\n", pVbglR3Event->enmType);3431 rc = VERR_NOT_SUPPORTED;3432 break;3433 }3434 3483 } 3435 3436 LogFlowFunc(("Message %RU32 processed with %Rrc\n", pVbglR3Event->enmType, rc)); 3437 if (RT_FAILURE(rc)) 3484 else if (e.enmType == DNDEVENT::DnDEventType_X11) 3438 3485 { 3439 /* Tell the user. */ 3440 VBClLogError("Processing message %RU32 failed with %Rrc\n", pVbglR3Event->enmType, rc); 3441 3442 /* If anything went wrong, do a reset and start over. */ 3443 m_pCurDnD->reset(); 3486 LogFlowThisFunc(("X11 event (type %#x)\n", e.x11.type)); 3487 m_pCurDnD->onX11Event(e.x11); 3444 3488 } 3445 3446 const bool fQuit = pVbglR3Event->enmType == VBGLR3DNDEVENTTYPE_QUIT; 3447 3448 VbglR3DnDEventFree(e.hgcm); 3449 e.hgcm = NULL; 3450 3451 if (fQuit) 3452 break; 3453 } 3454 else if (e.enmType == DNDEVENT::DnDEventType_X11) 3455 { 3456 m_pCurDnD->onX11Event(e.x11); 3457 } 3458 else 3459 AssertMsgFailed(("Unknown event queue type %RU32\n", e.enmType)); 3489 else 3490 AssertMsgFailed(("Unknown event queue type %RU32\n", e.enmType)); 3491 3492 --cEvents; 3493 3494 } /* for */ 3460 3495 3461 3496 /* … … 3638 3673 { 3639 3674 cMsgSkippedInvalid = 0; /* Reset skipped messages count. */ 3640 pThis->m_eventQueue.append(e); 3675 3676 int rc2 = RTCritSectEnter(&pThis->m_eventQueueCS); 3677 if (RT_SUCCESS(rc2)) 3678 { 3679 VBClLogVerbose(2, "Received new HGCM message (type %#x)\n", e.hgcm->enmType); 3680 3681 pThis->m_eventQueue.append(e); 3682 3683 rc2 = RTCritSectLeave(&pThis->m_eventQueueCS); 3684 AssertRC(rc2); 3685 } 3641 3686 3642 3687 rc = RTSemEventSignal(pThis->m_hEventSem); … … 3693 3738 3694 3739 DNDEVENT e; 3740 RT_ZERO(e); 3741 e.enmType = DNDEVENT::DnDEventType_X11; 3742 3695 3743 do 3696 3744 { … … 3702 3750 * of time. 3703 3751 */ 3704 if (XEventsQueued(pThis->m_pDisplay, QueuedAfterFlush) > 0) 3705 { 3706 RT_ZERO(e); 3707 e.enmType = DNDEVENT::DnDEventType_X11; 3708 3752 unsigned cNewEvents = 0; 3753 unsigned cQueued = XEventsQueued(pThis->m_pDisplay, QueuedAfterFlush); 3754 while (cQueued) 3755 { 3709 3756 /* XNextEvent will block until a new X event becomes available. */ 3710 3757 XNextEvent(pThis->m_pDisplay, &e.x11); 3711 3758 { 3712 /* At the moment we only have one drag instance. */ 3713 DragInstance *pInstance = pThis->m_pCurDnD; 3714 AssertPtr(pInstance); 3715 3716 pInstance->onX11Event(e.x11); 3759 rc2 = RTCritSectEnter(&pThis->m_eventQueueCS); 3760 if (RT_SUCCESS(rc2)) 3761 { 3762 LogFlowFunc(("Added new X11 event, type=%d\n", e.x11.type)); 3763 3764 pThis->m_eventQueue.append(e); 3765 cNewEvents++; 3766 3767 rc2 = RTCritSectLeave(&pThis->m_eventQueueCS); 3768 AssertRC(rc2); 3769 } 3717 3770 } 3718 } 3719 else 3720 RTThreadSleep(25 /* ms */); 3771 3772 cQueued--; 3773 } 3774 3775 if (cNewEvents) 3776 { 3777 rc = RTSemEventSignal(pThis->m_hEventSem); 3778 if (RT_FAILURE(rc)) 3779 break; 3780 3781 continue; 3782 } 3783 3784 /* No new events; wait a bit. */ 3785 RTThreadSleep(25 /* ms */); 3721 3786 3722 3787 } while (!ASMAtomicReadBool(&pThis->m_fStop));
Note:
See TracChangeset
for help on using the changeset viewer.