VirtualBox

Ignore:
Timestamp:
Jun 20, 2014 10:17:20 AM (11 years ago)
Author:
vboxsync
Message:

DnD/VBoxTray: Cleanup, documentation.

File:
1 edited

Legend:

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

    r51556 r51675  
    6464
    6565VBoxDnDWnd::VBoxDnDWnd(void)
    66     : hWnd(NULL),
     66    : hThread(NIL_RTTHREAD),
     67      mEventSem(NIL_RTSEMEVENT),
     68      hWnd(NULL),
    6769      uAllActions(DND_IGNORE_ACTION),
    6870      mfMouseButtonDown(false),
     
    8385VBoxDnDWnd::~VBoxDnDWnd(void)
    8486{
    85     /** @todo Shutdown crit sect / event etc! */
    86 
    87     reset();
    88 }
    89 
     87    Destroy();
     88}
     89
     90/**
     91 * Initializes the proxy window with a given DnD context.
     92 *
     93 * @return  IPRT status code.
     94 * @param   pContext                Pointer to context to use.
     95 */
    9096int VBoxDnDWnd::Initialize(PVBOXDNDCONTEXT pContext)
    9197{
     
    102108    {
    103109        /* Message pump thread for our proxy window. */
    104         rc = RTThreadCreate(&gCtx.hEvtQueue, VBoxDnDWnd::Thread, this,
     110        rc = RTThreadCreate(&hThread, VBoxDnDWnd::Thread, this,
    105111                            0, RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE,
    106112                            "VBoxTrayDnDWnd");
    107         if (RT_FAILURE(rc))
    108             LogRel(("DnD: Failed to start proxy window thread, rc=%Rrc\n", rc));
    109         /** @todo Wait for thread to be started! */
    110     }
     113        if (RT_SUCCESS(rc))
     114            rc = RTThreadUserWait(hThread, 30 * 1000 /* Timeout in ms */);
     115    }
     116
     117    if (RT_FAILURE(rc))
     118        LogRel(("DnD: Failed to initialize proxy window, rc=%Rrc\n", rc));
    111119
    112120    LogFlowThisFunc(("Returning rc=%Rrc\n", rc));
     
    115123
    116124/**
     125 * Destroys the proxy window and releases all remaining
     126 * resources again.
     127 *
     128 */
     129void VBoxDnDWnd::Destroy(void)
     130{
     131    if (hThread != NIL_RTTHREAD)
     132    {
     133        int rcThread = VERR_WRONG_ORDER;
     134        int rc = RTThreadWait(hThread, 60 * 1000 /* Timeout in ms */, &rcThread);
     135        LogFlowFunc(("Waiting for thread resulted in %Rrc (thread exited with %Rrc)\n",
     136                     rc, rcThread));
     137    }
     138
     139    reset();
     140
     141    RTCritSectDelete(&mCritSect);
     142    if (mEventSem != NIL_RTSEMEVENT)
     143        RTSemEventDestroy(mEventSem);
     144
     145    LogFlowFuncLeave();
     146}
     147
     148/**
    117149 * Thread for handling the window's message pump.
    118150 *
    119151 * @return  IPRT status code.
    120  * @param   hThread
    121  * @param   pvUser
     152 * @param   hThread                 Handle to this thread.
     153 * @param   pvUser                  Pointer to VBoxDnDWnd instance which
     154 *                                  is using the thread.
    122155 */
    123156/* static */
     
    152185#endif
    153186
     187    bool fSignalled = false; /* Thread signalled? */
     188
    154189    int rc = VINF_SUCCESS;
    155190    if (!RegisterClassEx(&wndClass))
     
    223258    if (RT_SUCCESS(rc))
    224259    {
     260        rc = RTThreadUserSignal(hThread);
     261        fSignalled = RT_SUCCESS(rc);
     262
    225263        bool fShutdown = false;
    226         do
     264        while (RT_SUCCESS(rc))
    227265        {
    228266            MSG uMsg;
     
    243281
    244282            /** @todo Immediately drop on failure? */
    245 
    246         } while (RT_SUCCESS(rc));
     283        }
    247284
    248285#ifdef VBOX_WITH_DRAG_AND_DROP_GH
     
    254291    }
    255292
     293    if (!fSignalled)
     294    {
     295        int rc2 = RTThreadUserSignal(hThread);
     296        AssertRC(rc2);
     297    }
     298
    256299    LogFlowFuncLeaveRC(rc);
    257300    return rc;
    258301}
    259302
     303/**
     304 * Monitor enumeration callback for building up a simple bounding
     305 * box, capable of holding all enumerated monitors.
     306 *
     307 * @return  BOOL                    TRUE if enumeration should continue,
     308 *                                  FALSE if not.
     309 * @param   hMonitor                Handle to current monitor being enumerated.
     310 * @param   hdcMonitor              The current monitor's DC (device context).
     311 * @param   lprcMonitor             The current monitor's RECT.
     312 * @param   lParam                  Pointer to a RECT structure holding the
     313 *                                  bounding box to build.
     314 */
    260315/* static */
    261316BOOL CALLBACK VBoxDnDWnd::MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor,
     
    283338}
    284339
     340/**
     341 * The proxy window's WndProc.
     342 */
    285343LRESULT CALLBACK VBoxDnDWnd::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    286344{
     
    606664}
    607665
     666/**
     667 * Unregisters this proxy as a drop target.
     668 *
     669 * @return  IPRT status code.
     670 */
    608671int VBoxDnDWnd::UnregisterAsDropTarget(void)
    609672{
     
    633696#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
    634697
     698/**
     699 * Handles the creation of a proxy window.
     700 *
     701 * @return  IPRT status code.
     702 */
    635703int VBoxDnDWnd::OnCreate(void)
    636704{
     
    646714}
    647715
     716/**
     717 * Handles the destruction of a proxy window.
     718 */
    648719void VBoxDnDWnd::OnDestroy(void)
    649720{
     
    652723}
    653724
     725/**
     726 * Handles actions required when the host cursor enters
     727 * the guest's screen to initiate a host -> guest DnD operation.
     728 *
     729 * @return  IPRT status code.
     730 * @param   lstFormats              Supported formats offered by the host.
     731 * @param   uAllActions             Supported actions offered by the host.
     732 */
    654733int VBoxDnDWnd::OnHgEnter(const RTCList<RTCString> &lstFormats, uint32_t uAllActions)
    655734{
     
    716795}
    717796
     797/**
     798 * Handles actions required when the host cursor moves inside
     799 * the guest's screen.
     800 *
     801 * @return  IPRT status code.
     802 * @param   u32xPos                 Absolute X position (in pixels) of the host cursor
     803 *                                  inside the guest.
     804 * @param   u32yPos                 Absolute Y position (in pixels) of the host cursor
     805 *                                  inside the guest.
     806 * @param   uAction                 Action the host wants to perform while moving.
     807 *                                  Currently ignored.
     808 */
    718809int VBoxDnDWnd::OnHgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t uAction)
    719810{
     
    753844}
    754845
     846/**
     847 * Handles actions required when the host cursor leaves
     848 * the guest's screen again.
     849 *
     850 * @return  IPRT status code.
     851 */
    755852int VBoxDnDWnd::OnHgLeave(void)
    756853{
     
    773870}
    774871
     872/**
     873 * Handles actions required when the host cursor wants to drop
     874 * and therefore start a "drop" action in the guest.
     875 *
     876 * @return  IPRT status code.
     877 */
    775878int VBoxDnDWnd::OnHgDrop(void)
    776879{
     
    812915}
    813916
     917/**
     918 * Handles actions required when the host has sent over DnD data
     919 * to the guest after a "drop" event.
     920 *
     921 * @return  IPRT status code.
     922 * @param   pvData                  Pointer to raw data received.
     923 * @param   cbData                  Size of data (in bytes) received.
     924 */
    814925int VBoxDnDWnd::OnHgDataReceived(const void *pvData, uint32_t cbData)
    815926{
     
    843954}
    844955
     956/**
     957 * Handles actions required when the host wants to cancel an action
     958 * host -> guest operation.
     959 *
     960 * @return  IPRT status code.
     961 */
    845962int VBoxDnDWnd::OnHgCancel(void)
    846963{
     
    864981
    865982#ifdef VBOX_WITH_DRAG_AND_DROP_GH
     983/**
     984 * Handles actions required to start a guest -> host DnD operation.
     985 * This works by letting the host ask whether a DnD operation is pending
     986 * on the guest. The guest must not know anything about the host's DnD state
     987 * and/or operations due to security reasons.
     988 *
     989 * To capture a pending DnD operation on the guest which then can be communicated
     990 * to the host the proxy window needs to be registered as a drop target. This drop
     991 * target then will act as a proxy target between the guest OS and the host. In other
     992 * words, the guest OS will use this proxy target as a regular (invisible) window
     993 * which can be used by the regular guest OS' DnD mechanisms, independently of the
     994 * host OS. To make sure this proxy target is able receive an in-progress DnD operation
     995 * on the guest, it will be shown invisibly across all active guest OS screens. Just
     996 * think of an opened umbrella across all screens here.
     997 *
     998 * As soon as the proxy target and its underlying data object receive appropriate
     999 * DnD messages they'll be hidden again, and the control will be transferred back
     1000 * this class again.
     1001 *
     1002 * @return  IPRT status code.
     1003 * @param   uScreenID               Screen ID the host wants to query a pending operation
     1004 *                                  for. Currently not used/needed here.
     1005 */
    8661006int VBoxDnDWnd::OnGhIsDnDPending(uint32_t uScreenID)
    8671007{
     
    9951135}
    9961136
    997 int VBoxDnDWnd::OnGhDropped(const char *pszFormat, uint32_t cbFormats,
     1137/**
     1138 * Handles actions required to let the guest know that the host
     1139 * started a "drop" action on the host. This will tell the guest
     1140 * to send data in a specific format the host requested.
     1141 *
     1142 * @return  IPRT status code.
     1143 * @param   pszFormat               Format the host requests the data in.
     1144 * @param   cbFormat                Size (in bytes) of format string.
     1145 * @param   uDefAction              Default action on the host.
     1146 */
     1147int VBoxDnDWnd::OnGhDropped(const char *pszFormat, uint32_t cbFormat,
    9981148                            uint32_t uDefAction)
    9991149{
    10001150    AssertPtrReturn(pszFormat, VERR_INVALID_POINTER);
    1001     AssertReturn(cbFormats, VERR_INVALID_PARAMETER);
     1151    AssertReturn(cbFormat, VERR_INVALID_PARAMETER);
    10021152
    10031153    LogFlowThisFunc(("mMode=%ld, mState=%ld, pDropTarget=0x%p, pszFormat=%s, uDefAction=0x%x\n",
     
    10431193#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
    10441194
     1195/**
     1196 * Injects a DnD event in this proxy window's Windows
     1197 * event queue. The (allocated) event will be deleted by
     1198 * this class after processing.
     1199 *
     1200 * @return  IPRT status code.
     1201 * @param   pEvent                  Event to inject.
     1202 */
    10451203int VBoxDnDWnd::ProcessEvent(PVBOXDNDEVENT pEvent)
    10461204{
    10471205    AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
    10481206
    1049     PostMessage(hWnd, WM_VBOXTRAY_DND_MESSAGE,
    1050                 0 /* wParm */, (LPARAM)pEvent /* lParm */);
     1207    BOOL fRc = PostMessage(hWnd, WM_VBOXTRAY_DND_MESSAGE,
     1208                           0 /* wParm */, (LPARAM)pEvent /* lParm */);
     1209    if (!fRc)
     1210    {
     1211        static int s_iBitchedAboutFailedDnDMessages = 0;
     1212        if (s_iBitchedAboutFailedDnDMessages++ < 10)
     1213        {
     1214            DWORD dwErr = GetLastError();
     1215            LogRel(("DnD: Processing event %p failed with %ld (%Rrc), skpping\n",
     1216                    pEvent, dwErr, RTErrConvertFromWin32(dwErr)));
     1217        }
     1218
     1219        RTMemFree(pEvent);
     1220        pEvent = NULL;
     1221
     1222        return VERR_NO_MEMORY;
     1223    }
    10511224
    10521225    return VINF_SUCCESS;
    10531226}
    10541227
     1228/**
     1229 * Hides the proxy window again.
     1230 *
     1231 * @return  IPRT status code.
     1232 */
    10551233int VBoxDnDWnd::hide(void)
    10561234{
     
    10631241}
    10641242
     1243/**
     1244 * Shows the (invisible) proxy window in fullscreen,
     1245 * spawned across all active guest monitors.
     1246 *
     1247 * @return  IPRT status code.
     1248 */
    10651249int VBoxDnDWnd::makeFullscreen(void)
    10661250{
     
    11371321}
    11381322
     1323/**
     1324 * Moves the guest mouse cursor to a specific position.
     1325 *
     1326 * @return  IPRT status code.
     1327 * @param   x                       X position (in pixels) to move cursor to.
     1328 * @param   y                       Y position (in pixels) to move cursor to.
     1329 * @param   dwMouseInputFlags       Additional movement flags. @sa MOUSEEVENTF_ flags.
     1330 */
    11391331int VBoxDnDWnd::mouseMove(int x, int y, DWORD dwMouseInputFlags)
    11401332{
     
    11751367}
    11761368
     1369/**
     1370 * Releases a previously pressed left guest mouse button.
     1371 *
     1372 * @return  IPRT status code.
     1373 */
    11771374int VBoxDnDWnd::mouseRelease(void)
    11781375{
     
    11991396}
    12001397
     1398/**
     1399 * Resets the proxy window.
     1400 */
    12011401void VBoxDnDWnd::reset(void)
    12021402{
     
    12141414}
    12151415
     1416/**
     1417 * Sets the current operation mode of this proxy window.
     1418 *
     1419 * @return  IPRT status code.
     1420 * @param   enmMode                 New mode to set.
     1421 */
    12161422int VBoxDnDWnd::setMode(Mode enmMode)
    12171423{
     
    12251431}
    12261432
    1227 static LRESULT CALLBACK vboxDnDWndProcInstance(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
     1433/**
     1434 * Static helper function for having an own WndProc for proxy
     1435 * window instances.
     1436 */
     1437static LRESULT CALLBACK vboxDnDWndProcInstance(HWND hWnd, UINT uMsg,
     1438                                               WPARAM wParam, LPARAM lParam)
    12281439{
    12291440    LONG_PTR pUserData = GetWindowLongPtr(hWnd, GWLP_USERDATA);
     
    12371448}
    12381449
    1239 static LRESULT CALLBACK vboxDnDWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
     1450/**
     1451 * Static helper function for routing Windows messages to a specific
     1452 * proxy window instance.
     1453 */
     1454static LRESULT CALLBACK vboxDnDWndProc(HWND hWnd, UINT uMsg,
     1455                                       WPARAM wParam, LPARAM lParam)
    12401456{
    12411457    /* Note: WM_NCCREATE is not the first ever message which arrives, but
     
    13461562    /* Set shutdown indicator. */
    13471563    ASMAtomicWriteBool(&pCtx->fShutdown, true);
    1348 
    1349     /** @todo Notify / wait for HGCM thread! */
    13501564}
    13511565
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