VirtualBox

Ignore:
Timestamp:
Feb 24, 2014 9:07:22 PM (11 years ago)
Author:
vboxsync
Message:

DnD: Update, bugfixes.

Location:
trunk/src/VBox/Additions/WINNT/VBoxTray
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp

    r50508 r50561  
    6060VBoxDnDWnd::VBoxDnDWnd(void)
    6161    : hWnd(NULL),
     62      uAllActions(DND_IGNORE_ACTION),
    6263      mfMouseButtonDown(false),
    6364#ifdef VBOX_WITH_DRAG_AND_DROP_GH
     
    6970{
    7071    RT_ZERO(startupInfo);
    71 
    72     reset();
    7372}
    7473
     
    209208    else
    210209    {
    211         LogRelFunc(("Unable to initialize OLE, hr=%Rhrc\n", hr));
     210        LogRel(("DnD: Unable to initialize OLE, hr=%Rhrc\n", hr));
    212211        rc = VERR_COM_UNEXPECTED;
    213212    }
     
    380379            else if (mMode == GH) /* Guest to host. */
    381380            {
    382                 //hide();
    383 
    384381                /* Starting here VBoxDnDDropTarget should
    385382                 * take over; was instantiated when registering
     
    405402        {
    406403            VBOXDNDEVENT *pEvent = (PVBOXDNDEVENT)lParam;
    407             AssertPtr(pEvent);
     404            if (!pEvent)
     405                break; /* No event received, bail out. */
    408406
    409407            LogFlowThisFunc(("Received uType=%RU32, uScreenID=%RU32\n",
     
    416414                {
    417415                    LogFlowThisFunc(("HOST_DND_HG_EVT_ENTER\n"));
    418 
    419                     reset();
    420 
    421                     mMode = HG;
    422416
    423417                    if (pEvent->Event.cbFormats)
     
    484478                    LogFlowThisFunc(("HOST_DND_GH_REQ_PENDING\n"));
    485479#ifdef VBOX_WITH_DRAG_AND_DROP_GH
    486                     if (   mMode == Unknown
    487                         /* There can be more than one HOST_DND_GH_REQ_PENDING
    488                          * messages coming in. */
    489                         || mMode == GH)
    490                     {
    491                         mMode = GH;
    492                         rc = OnGhIsDnDPending(pEvent->Event.uScreenId);
    493                     }
    494                     else
    495                         rc = VERR_WRONG_ORDER;
     480                    rc = OnGhIsDnDPending(pEvent->Event.uScreenId);
     481
    496482#else
    497483                    rc = VERR_NOT_SUPPORTED;
     
    504490                    LogFlowThisFunc(("HOST_DND_GH_EVT_DROPPED\n"));
    505491#ifdef VBOX_WITH_DRAG_AND_DROP_GH
    506                     if (mMode == GH)
    507                     {
    508                         rc = OnGhDropped(pEvent->Event.pszFormats,
    509                                          pEvent->Event.cbFormats,
    510                                          pEvent->Event.u.a.uDefAction);
    511                     }
    512                     else
    513                         rc = VERR_WRONG_ORDER;
    514 #else
    515                     rc = VERR_NOT_SUPPORTED;
    516 #endif
    517                     break;
    518                 }
    519 
    520                 case DragAndDropSvc::GUEST_DND_GH_EVT_ERROR:
    521                 {
    522                     LogFlowThisFunc(("GUEST_DND_GH_EVT_ERROR\n"));
    523 #ifdef VBOX_WITH_DRAG_AND_DROP_GH
    524                     reset();
    525                     rc = VINF_SUCCESS; /** @todo GUEST_DND_GH_EVT_ERROR */
    526 #else
    527                     rc = VERR_NOT_SUPPORTED;
    528 #endif
    529                     break;
    530                 }
    531 
    532                 case DragAndDropSvc::HOST_DND_GH_RECV_DIR:
    533                 {
    534                     LogFlowThisFunc(("HOST_DND_GH_RECV_DIR\n"));
    535 #ifdef VBOX_WITH_DRAG_AND_DROP_GH
    536                     if (mMode == GH)
    537                     {
    538                         rc = OnGhSendDir(pEvent->Event.pszFormats,
    539                                          pEvent->Event.cbFormats,
    540                                          pEvent->Event.u.a.uDefAction);
    541                     }
    542                     else
    543                         rc = VERR_WRONG_ORDER;
    544 #else
    545                     rc = VERR_NOT_SUPPORTED;
    546 #endif
    547                     break;
    548                 }
    549 
    550                 case DragAndDropSvc::HOST_DND_GH_RECV_FILE:
    551                 {
    552                     LogFlowThisFunc(("HOST_DND_GH_RECV_FILE\n"));
    553 #ifdef VBOX_WITH_DRAG_AND_DROP_GH
    554                     if (mMode == GH)
    555                     {
    556                         rc = OnGhSendFile(pEvent->Event.pszFormats,
    557                                           pEvent->Event.cbFormats,
    558                                           pEvent->Event.u.a.uDefAction);
    559                     }
    560                     else
    561                         rc = VERR_WRONG_ORDER;
     492                    rc = OnGhDropped(pEvent->Event.pszFormats,
     493                                     pEvent->Event.cbFormats,
     494                                     pEvent->Event.u.a.uDefAction);
    562495#else
    563496                    rc = VERR_NOT_SUPPORTED;
     
    600533            }
    601534
    602             LogFlowThisFunc(("Processing event %RU32 resulted in rc=%Rrc\n",
    603                              pEvent->Event.uType, rc));
    604535            if (pEvent)
     536            {
     537                LogFlowThisFunc(("Processing event %RU32 resulted in rc=%Rrc\n",
     538                                 pEvent->Event.uType, rc));
     539
    605540                RTMemFree(pEvent);
     541            }
    606542            return 0;
    607543        }
     
    702638int VBoxDnDWnd::OnHgEnter(const RTCList<RTCString> &lstFormats, uint32_t uAllActions)
    703639{
     640    if (mMode == GH) /* Wrong mode? Bail out. */
     641        return VERR_WRONG_ORDER;
     642
    704643#ifdef DEBUG
    705644    LogFlowThisFunc(("uActions=0x%x, lstFormats=%zu: ", uAllActions, lstFormats.size()));
     
    708647    LogFlow(("\n"));
    709648#endif
     649
     650    reset();
     651    setMode(HG);
    710652
    711653    /* Save all allowed actions. */
     
    779721int VBoxDnDWnd::OnHgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t uAction)
    780722{
    781     LogFlowThisFunc(("u32xPos=%RU32, u32yPos=%RU32, uAction=0x%x\n",
    782                      u32xPos, u32yPos, uAction));
    783 
    784     int rc = mouseMove(u32xPos, u32yPos, MOUSEEVENTF_LEFTDOWN);
     723    int rc;
    785724
    786725    uint32_t uActionNotify = DND_IGNORE_ACTION;
    787     if (RT_SUCCESS(rc))
    788         rc = RTCritSectEnter(&mCritSect);
    789     if (RT_SUCCESS(rc))
    790     {
    791         if (   (Dragging == mState)
    792             && startupInfo.pDropSource)
    793             uActionNotify = startupInfo.pDropSource->GetCurrentAction();
    794 
    795         RTCritSectLeave(&mCritSect);
    796     }
     726    if (mMode == HG)
     727    {
     728        LogFlowThisFunc(("u32xPos=%RU32, u32yPos=%RU32, uAction=0x%x\n",
     729                         u32xPos, u32yPos, uAction));
     730
     731        rc = mouseMove(u32xPos, u32yPos, MOUSEEVENTF_LEFTDOWN);
     732
     733        if (RT_SUCCESS(rc))
     734            rc = RTCritSectEnter(&mCritSect);
     735        if (RT_SUCCESS(rc))
     736        {
     737            if (   (Dragging == mState)
     738                && startupInfo.pDropSource)
     739                uActionNotify = startupInfo.pDropSource->GetCurrentAction();
     740
     741            RTCritSectLeave(&mCritSect);
     742        }
     743    }
     744    else /* Just acknowledge the operation with an ignore action. */
     745        rc = VINF_SUCCESS;
    797746
    798747    if (RT_SUCCESS(rc))
     
    809758int VBoxDnDWnd::OnHgLeave(void)
    810759{
     760    if (mMode == GH) /* Wrong mode? Bail out. */
     761        return VERR_WRONG_ORDER;
     762
    811763    LogFlowThisFunc(("mMode=%ld, mState=%RU32\n", mMode, mState));
    812764    LogRel(("DnD: Drag'n drop operation aborted\n"));
     
    826778int VBoxDnDWnd::OnHgDrop(void)
    827779{
     780    if (mMode == GH)
     781        return VERR_WRONG_ORDER;
     782
    828783    LogFlowThisFunc(("mMode=%ld, mState=%RU32\n", mMode, mState));
    829784
     
    917872                     mMode, mState, uScreenID));
    918873
     874    if (mMode == Unknown)
     875        setMode(GH);
     876
     877    if (mMode != GH)
     878        return VERR_WRONG_ORDER;
     879
    919880    if (mState == Uninitialized)
    920         reset();
     881    {
     882        /* Nothing to do here yet. */
     883        mState = Initialized;
     884    }
    921885
    922886    int rc;
     
    954918
    955919    if (   RT_SUCCESS(rc)
    956         && (mState == Dragging))
     920        && mState == Dragging)
    957921    {
    958922        /** @todo Put this block into a function! */
     
    987951        {
    988952            uDefAction = DND_COPY_ACTION;
     953            /** @todo Support more than one action at a time. */
    989954            uAllActions = uDefAction;
    990955
     
    993958            rc = VbglR3DnDGHAcknowledgePending(mClientID,
    994959                                               uDefAction, uAllActions, strFormats.c_str());
     960            if (RT_FAILURE(rc))
     961            {
     962                char szMsg[256]; /* Sizes according to MSDN. */
     963                char szTitle[64];
     964
     965                /** @todo Add some translation macros here. */
     966                RTStrPrintf(szTitle, sizeof(szTitle), "VirtualBox Guest Additions Drag'n Drop");
     967                RTStrPrintf(szMsg, sizeof(szMsg), "Drag'n drop to the host either is not supported or disabled. "
     968                                                  "Pleas enable Guest to Host or Bidirectional drag'n drop mode "
     969                                                  "or re-install the VirtualBox Guest Additions.");
     970                switch (rc)
     971                {
     972                    case VERR_ACCESS_DENIED:
     973                        rc = hlpShowBalloonTip(ghInstance, ghwndToolWindow, ID_TRAYICON,
     974                                               szMsg, szTitle,
     975                                               15 * 1000 /* Time to display in msec */, NIIF_INFO);
     976                        AssertRC(rc);
     977                        break;
     978
     979                    default:
     980                        break;
     981                }
     982            }
    995983        }
    996984        else
     
    1010998    LogFlowThisFunc(("mMode=%ld, mState=%ld, pDropTarget=0x%p, pszFormat=%s, uDefAction=0x%x\n",
    1011999                     mMode, mState, pDropTarget, pszFormat, uDefAction));
    1012 
    10131000    int rc;
    1014     if (mState == Dragging)
    1015     {
    1016         AssertPtr(pDropTarget);
    1017         rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout in ms */);
     1001    if (mMode == GH)
     1002    {
     1003        if (mState == Dragging)
     1004        {
     1005            AssertPtr(pDropTarget);
     1006            rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout in ms */);
     1007
     1008            reset();
     1009        }
     1010        else if (mState == Dropped)
     1011        {
     1012            rc = VINF_SUCCESS;
     1013        }
     1014        else
     1015            rc = VERR_WRONG_ORDER;
     1016
    10181017        if (RT_SUCCESS(rc))
    10191018        {
     
    10271026            LogFlowFunc(("Sent pvData=0x%p, cbData=%RU32, rc=%Rrc\n",
    10281027                         pvData, cbData, rc));
    1029         }
    1030 
    1031         reset();
     1028
     1029
     1030        }
    10321031    }
    10331032    else
    10341033        rc = VERR_WRONG_ORDER;
    10351034
    1036     LogFlowFuncLeaveRC(rc);
    1037     return rc;
    1038 }
    1039 
    1040 int VBoxDnDWnd::OnGhSendDir(const char *pszFormats, uint32_t cbFormats,
    1041                             uint32_t uDefAction)
    1042 {
    1043     int rc = 0;
    1044     LogFlowFuncLeaveRC(rc);
    1045     return rc;
    1046 }
    1047 
    1048 int VBoxDnDWnd::OnGhSendFile(const char *pszFormats, uint32_t cbFormats,
    1049                              uint32_t uDefAction)
    1050 {
    1051     int rc = 0;
    10521035    LogFlowFuncLeaveRC(rc);
    10531036    return rc;
     
    12131196void VBoxDnDWnd::reset(void)
    12141197{
    1215     LogFlowThisFunc(("Old mState=%ld\n", mState));
     1198    LogFlowThisFunc(("Resetting, old mMode=%ld, mState=%ld\n",
     1199                     mMode, mState));
    12161200
    12171201    lstAllowedFormats.clear();
     
    12191203    uAllActions = DND_IGNORE_ACTION;
    12201204
    1221     mMode = Unknown;
     1205    int rc2 = setMode(Unknown);
     1206    AssertRC(rc2);
     1207
     1208    hide();
     1209}
     1210
     1211int VBoxDnDWnd::setMode(Mode enmMode)
     1212{
     1213    LogFlowThisFunc(("Old mode=%ld, new mode=%ld\n",
     1214                     mMode, enmMode));
     1215
     1216    mMode = enmMode;
    12221217    mState = Initialized;
     1218
     1219    return VINF_SUCCESS;
    12231220}
    12241221
     
    14251422            if (RT_FAILURE(rc2))
    14261423                LogFlowFunc(("Cancelling failed with rc=%Rrc\n", rc2));
     1424            break;
    14271425        }
    14281426        else
     
    14331431             * don't support the stuff we do on the guest side, so make sure we
    14341432             * don't process invalid messages forever. */
    1435             if (rc == VERR_INVALID_PARAMETER)
    1436                 cMsgSkippedInvalid++;
    1437             if (cMsgSkippedInvalid > 3)
     1433            if (cMsgSkippedInvalid++ > 3)
    14381434            {
    1439                 LogFlowFunc(("Too many invalid/skipped messages from host, exiting ...\n"));
     1435                LogRel(("DnD: Too many invalid/skipped messages from host, exiting ...\n"));
    14401436                break;
    14411437            }
     1438
     1439            int rc2 = VbglR3DnDGHSendError(uClientID, rc);
     1440            AssertRC(rc2);
    14421441        }
    14431442
     
    14451444            break;
    14461445
     1446        if (RT_FAILURE(rc)) /* Don't hog the CPU on errors. */
     1447            RTThreadSleep(1000 /* ms */);
     1448
    14471449    } while (true);
    14481450
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h

    r50508 r50561  
    340340    int OnGhIsDnDPending(uint32_t uScreenID);
    341341    int OnGhDropped(const char *pszFormat, uint32_t cbFormats, uint32_t uDefAction);
    342     int OnGhSendDir(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);
    343     int OnGhSendFile(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);
    344342#endif
    345343
     
    353351
    354352    int makeFullscreen(void);
    355     void reset(void);
    356353    int mouseMove(int x, int y, DWORD dwMouseInputFlags);
    357354    int mouseRelease(void);
     355    void reset(void);
     356    int setMode(Mode enmMode);
    358357
    359358public: /** @todo Make protected! */
     
    396395    /** The current state. */
    397396    State                      mState;
     397    bool                       mInFlight;
    398398    RTCString                  mFormatRequested;
    399399    RTCList<RTCString>         mLstFormats;
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDropTarget.cpp

    r50508 r50561  
    120120    else
    121121    {
    122         LogFlowFunc(("CF_HDROP not supported, hr=%Rhrc\n", hr));
     122        LogFlowFunc(("CF_HDROP not wanted, hr=%Rhrc\n", hr));
    123123
    124124        /* So we couldn't retrieve the data in CF_HDROP format; try with
    125          * CF_TEXT format now. Rest stays the same. */
    126         fmtEtc.cfFormat = CF_TEXT;
     125         * CF_UNICODETEXT + CF_TEXT formats now. Rest stays the same. */
     126        fmtEtc.cfFormat = CF_UNICODETEXT;
    127127        hr = pDataObject->QueryGetData(&fmtEtc);
    128         if (hr != S_OK)
     128        if (hr == S_OK)
    129129        {
    130             LogFlowFunc(("CF_TEXT not supported, hr=%Rhrc\n", hr));
    131             fmtEtc.cfFormat = 0; /* Mark it to not supported. */
     130            mFormats = "text/plain;charset=utf-8";
    132131        }
    133132        else
    134133        {
    135             mFormats = "text/plain;charset=utf-8";
     134            LogFlowFunc(("CF_UNICODETEXT not wanted, hr=%Rhrc\n", hr));
     135
     136            fmtEtc.cfFormat = CF_TEXT;
     137            hr = pDataObject->QueryGetData(&fmtEtc);
     138            if (hr == S_OK)
     139            {
     140                mFormats = "text/plain;charset=utf-8";
     141            }
     142            else
     143            {
     144                LogFlowFunc(("CF_TEXT not wanted, hr=%Rhrc\n", hr));
     145                fmtEtc.cfFormat = 0; /* Mark it to not supported. */
     146            }
    136147        }
    137148    }
     
    306317                switch (mFormatEtc.cfFormat)
    307318                {
    308                     /* Handling CF_TEXT means that the system already did some marshalling
    309                      * to convert RTF or unicode text to plain ANSI text. */
     319                    case CF_UNICODETEXT:
     320                    {
     321                        AssertPtr(pvData);
     322                        size_t cbSize = GlobalSize(pvData);
     323                        LogFlowFunc(("CF_UNICODETEXT 0x%p got %zu bytes\n", pvData, cbSize));
     324                        if (cbSize)
     325                        {
     326                            char *pszText = NULL;
     327                            rc = RTUtf16ToUtf8((PCRTUTF16)pvData, &pszText);
     328                            if (RT_SUCCESS(rc))
     329                            {
     330                                mpvData = (void *)pszText;
     331                                mcbData = strlen(pszText) + 1; /* Include termination. */
     332
     333                                /* Note: Don't free data of pszText, mpvData now owns it. */
     334                            }
     335                        }
     336
     337                        break;
     338                    }
     339
    310340                    case CF_TEXT:
    311341                    {
     
    320350                            {
    321351                                mpvData = (void *)pszText;
    322                                 mcbData = strlen(pszText) + 1;
     352                                mcbData = strlen(pszText) + 1; /* Include termination. */
     353
     354                                /* Note: Don't free data of pszText, mpvData now owns it. */
    323355                            }
    324356                        }
     
    412444                            /* Add separation between filenames.
    413445                             * Note: Also do this for the last element of the list. */
    414                             if (i > 0)
    415                             {
    416                                 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */,
    417                                                      "\r\n", 2 /* Bytes */);
    418                                 if (RT_SUCCESS(rc))
    419                                     cchFiles += 2; /* Include \r\n */
    420                             }
     446                            rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */,
     447                                                 "\r\n", 2 /* Bytes */);
     448                            if (RT_SUCCESS(rc))
     449                                cchFiles += 2; /* Include \r\n */
    421450                        }
    422451
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