81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/* $Id$ */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/** @file
1a3b02207c6b6aca1b7bdd50fc2e79defe4e405evboxsync * VBoxDnD.cpp - Windows-specific bits of the drag and drop service.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/*
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync * Copyright (C) 2013-2014 Oracle Corporation
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync *
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * available from http://www.virtualbox.org. This file is free software;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * you can redistribute it and/or modify it under the terms of the GNU
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * General Public License (GPL) as published by the Free Software
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include <windows.h>
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include "VBoxTray.h"
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include "VBoxHelpers.h"
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include "VBoxDnD.h"
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include <VBox/VBoxGuestLib.h>
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include "VBox/HostServices/DragAndDropSvc.h"
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include <iprt/asm.h>
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include <iprt/assert.h>
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include <iprt/err.h>
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include <iprt/ldr.h>
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include <iprt/list.h>
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include <iprt/mem.h>
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include <iprt/cpp/mtlist.h>
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include <iprt/cpp/ministring.h>
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include <iprt/cpp/mtlist.h>
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#include <VBoxGuestInternal.h>
b32e84697b0631a07937ef7aa529e596b09da876vboxsync#ifdef LOG_GROUP
b32e84697b0631a07937ef7aa529e596b09da876vboxsync# undef LOG_GROUP
b32e84697b0631a07937ef7aa529e596b09da876vboxsync#endif
b32e84697b0631a07937ef7aa529e596b09da876vboxsync#define LOG_GROUP LOG_GROUP_GUEST_DND
b32e84697b0631a07937ef7aa529e596b09da876vboxsync#include <VBox/log.h>
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/* Enable this define to see the proxy window(s) when debugging
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * their behavior. Don't have this enabled in release builds! */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifdef DEBUG
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync//# define VBOX_DND_DEBUG_WND
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync/** @todo Merge this with messages from VBoxTray.h. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#define WM_VBOXTRAY_DND_MESSAGE WM_APP + 401
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync/** Function pointer for SendInput(). This only is available starting
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync * at NT4 SP3+. */
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsynctypedef BOOL (WINAPI *PFNSENDINPUT)(UINT, LPINPUT, int);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsynctypedef BOOL (WINAPI* PFNENUMDISPLAYMONITORS)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync/** Static pointer to SendInput() function. */
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsyncstatic PFNSENDINPUT s_pfnSendInput = NULL;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncstatic PFNENUMDISPLAYMONITORS s_pfnEnumDisplayMonitors = NULL;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncstatic LRESULT CALLBACK vboxDnDWndProcInstance(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncstatic LRESULT CALLBACK vboxDnDWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncVBoxDnDWnd::VBoxDnDWnd(void)
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync : hThread(NIL_RTTHREAD),
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync mEventSem(NIL_RTSEMEVENT),
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync hWnd(NULL),
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync uAllActions(DND_IGNORE_ACTION),
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mfMouseButtonDown(false),
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#ifdef VBOX_WITH_DRAG_AND_DROP_GH
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync pDropTarget(NULL),
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mClientID(UINT32_MAX),
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mMode(Unknown),
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mState(Uninitialized)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RT_ZERO(startupInfo);
aa08d96e9f8a68de2d11b24f680757cb02d1f16bvboxsync
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync LogFlowFunc(("Supported formats:\n"));
aa08d96e9f8a68de2d11b24f680757cb02d1f16bvboxsync const RTCString arrEntries[] = { VBOX_DND_FORMATS_DEFAULT };
aa08d96e9f8a68de2d11b24f680757cb02d1f16bvboxsync for (size_t i = 0; i < RT_ELEMENTS(arrEntries); i++)
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync {
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync LogFlowFunc(("\t%s\n", arrEntries[i].c_str()));
aa08d96e9f8a68de2d11b24f680757cb02d1f16bvboxsync this->lstAllowedFormats.append(arrEntries[i]);
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncVBoxDnDWnd::~VBoxDnDWnd(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync Destroy();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Initializes the proxy window with a given DnD context.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param pContext Pointer to context to use.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::Initialize(PVBOXDNDCONTEXT pContext)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtrReturn(pContext, VERR_INVALID_POINTER);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Save the context. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync this->pContext = pContext;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = RTSemEventCreate(&mEventSem);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = RTCritSectInit(&mCritSect);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Message pump thread for our proxy window. */
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync rc = RTThreadCreate(&hThread, VBoxDnDWnd::Thread, this,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync 0, RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync "VBoxTrayDnDWnd");
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync if (RT_SUCCESS(rc))
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync rc = RTThreadUserWait(hThread, 30 * 1000 /* Timeout in ms */);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync if (RT_FAILURE(rc))
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync LogRel(("DnD: Failed to initialize proxy window, rc=%Rrc\n", rc));
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("Returning rc=%Rrc\n", rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Destroys the proxy window and releases all remaining
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * resources again.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsyncvoid VBoxDnDWnd::Destroy(void)
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync{
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync if (hThread != NIL_RTTHREAD)
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync {
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync int rcThread = VERR_WRONG_ORDER;
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync int rc = RTThreadWait(hThread, 60 * 1000 /* Timeout in ms */, &rcThread);
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync LogFlowFunc(("Waiting for thread resulted in %Rrc (thread exited with %Rrc)\n",
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync rc, rcThread));
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync }
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync reset();
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync RTCritSectDelete(&mCritSect);
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync if (mEventSem != NIL_RTSEMEVENT)
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync RTSemEventDestroy(mEventSem);
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync LogFlowFuncLeave();
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync}
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/**
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * Thread for handling the window's message pump.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync *
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param hThread Handle to this thread.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param pvUser Pointer to VBoxDnDWnd instance which
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * is using the thread.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/* static */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::Thread(RTTHREAD hThread, void *pvUser)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VBoxDnDWnd *pThis = (VBoxDnDWnd*)pvUser;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtr(pThis);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync PVBOXDNDCONTEXT pContext = pThis->pContext;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtr(pContext);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtr(pContext->pEnv);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync HINSTANCE hInstance = pContext->pEnv->hInstance;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Assert(hInstance != 0);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Create our proxy window. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync WNDCLASSEX wndClass;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RT_ZERO(wndClass);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync wndClass.cbSize = sizeof(WNDCLASSEX);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync wndClass.lpfnWndProc = vboxDnDWndProc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync wndClass.lpszClassName = "VBoxTrayDnDWnd";
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync wndClass.hInstance = hInstance;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync wndClass.style = CS_NOCLOSE;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifdef VBOX_DND_DEBUG_WND
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync wndClass.style |= CS_HREDRAW | CS_VREDRAW;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync wndClass.hbrBackground = (HBRUSH)(CreateSolidBrush(RGB(255, 0, 0)));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#else
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync wndClass.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync bool fSignalled = false; /* Thread signalled? */
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (!RegisterClassEx(&wndClass))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync DWORD dwErr = GetLastError();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("Unable to register proxy window class, error=%ld\n", dwErr));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = RTErrConvertFromWin32(dwErr);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE;
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync DWORD dwStyle = WS_POPUP;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifdef VBOX_DND_DEBUG_WND
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync dwExStyle &= ~WS_EX_TRANSPARENT; /* Remove transparency bit. */
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync dwStyle |= WS_VISIBLE; /* Make the window visible. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync pThis->hWnd =
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync CreateWindowEx(dwExStyle,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync "VBoxTrayDnDWnd", "VBoxTrayDnDWnd",
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync dwStyle,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifdef VBOX_DND_DEBUG_WND
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, NULL, NULL,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#else
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync -200, -200, 100, 100, NULL, NULL,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync hInstance, pThis /* lParm */);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (!pThis->hWnd)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync DWORD dwErr = GetLastError();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("Unable to create proxy window, error=%ld\n", dwErr));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = RTErrConvertFromWin32(dwErr);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync else
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifndef VBOX_DND_DEBUG_WND
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync SetWindowPos(pThis->hWnd, HWND_TOPMOST, -200, -200, 0, 0,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync SWP_NOACTIVATE | SWP_HIDEWINDOW
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("Proxy window created, hWnd=0x%x\n", pThis->hWnd));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#else
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("Debug proxy window created, hWnd=0x%x\n", pThis->hWnd));
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync /*
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * Install some mouse tracking.
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync */
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync TRACKMOUSEEVENT me;
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync RT_ZERO(me);
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync me.cbSize = sizeof(TRACKMOUSEEVENT);
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync me.dwFlags = TME_HOVER | TME_LEAVE | TME_NONCLIENT;
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync me.hwndTrack = pThis->hWnd;
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync BOOL fRc = TrackMouseEvent(&me);
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync Assert(fRc);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
9725ca270919a5220a25cca2c05f4d85bf0f79e2vboxsync HRESULT hr = OleInitialize(NULL);
9725ca270919a5220a25cca2c05f4d85bf0f79e2vboxsync if (SUCCEEDED(hr))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
9725ca270919a5220a25cca2c05f4d85bf0f79e2vboxsync#ifdef VBOX_WITH_DRAG_AND_DROP_GH
9725ca270919a5220a25cca2c05f4d85bf0f79e2vboxsync rc = pThis->RegisterAsDropTarget();
9725ca270919a5220a25cca2c05f4d85bf0f79e2vboxsync#endif
9725ca270919a5220a25cca2c05f4d85bf0f79e2vboxsync }
9725ca270919a5220a25cca2c05f4d85bf0f79e2vboxsync else
9725ca270919a5220a25cca2c05f4d85bf0f79e2vboxsync {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync LogRel(("DnD: Unable to initialize OLE, hr=%Rhrc\n", hr));
9725ca270919a5220a25cca2c05f4d85bf0f79e2vboxsync rc = VERR_COM_UNEXPECTED;
9725ca270919a5220a25cca2c05f4d85bf0f79e2vboxsync }
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync
9725ca270919a5220a25cca2c05f4d85bf0f79e2vboxsync if (RT_SUCCESS(rc))
9725ca270919a5220a25cca2c05f4d85bf0f79e2vboxsync {
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync rc = RTThreadUserSignal(hThread);
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync fSignalled = RT_SUCCESS(rc);
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync bool fShutdown = false;
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync while (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync MSG uMsg;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync while (GetMessage(&uMsg, 0, 0, 0))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync TranslateMessage(&uMsg);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync DispatchMessage(&uMsg);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (ASMAtomicReadBool(&pContext->fShutdown))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync fShutdown = true;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (fShutdown)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("Cancelling ...\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** @todo Immediately drop on failure? */
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
eec8c0f9948580ef06e396e8b9c34428d0b78cd9vboxsync#ifdef VBOX_WITH_DRAG_AND_DROP_GH
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync int rc2 = pThis->UnregisterAsDropTarget();
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync if (RT_SUCCESS(rc))
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync rc = rc2;
eec8c0f9948580ef06e396e8b9c34428d0b78cd9vboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync OleUninitialize();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync if (!fSignalled)
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync {
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync int rc2 = RTThreadUserSignal(hThread);
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync AssertRC(rc2);
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync }
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFuncLeaveRC(rc);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Monitor enumeration callback for building up a simple bounding
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * box, capable of holding all enumerated monitors.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return BOOL TRUE if enumeration should continue,
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * FALSE if not.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param hMonitor Handle to current monitor being enumerated.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param hdcMonitor The current monitor's DC (device context).
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param lprcMonitor The current monitor's RECT.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param lParam Pointer to a RECT structure holding the
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * bounding box to build.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/* static */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncBOOL CALLBACK VBoxDnDWnd::MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LPRECT lprcMonitor, LPARAM lParam)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LPRECT pRect = (LPRECT)lParam;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtrReturn(pRect, FALSE);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtr(lprcMonitor);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("Monitor is %ld,%ld,%ld,%ld\n",
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync lprcMonitor->left, lprcMonitor->top,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync lprcMonitor->right, lprcMonitor->bottom));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Build up a simple bounding box to hold the entire (virtual) screen. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (pRect->left > lprcMonitor->left)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync pRect->left = lprcMonitor->left;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (pRect->right < lprcMonitor->right)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync pRect->right = lprcMonitor->right;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (pRect->top > lprcMonitor->top)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync pRect->top = lprcMonitor->top;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (pRect->bottom < lprcMonitor->bottom)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync pRect->bottom = lprcMonitor->bottom;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return TRUE;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * The proxy window's WndProc.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncLRESULT CALLBACK VBoxDnDWnd::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync switch (uMsg)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case WM_CREATE:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = OnCreate();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_FAILURE(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return FALSE;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return TRUE;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case WM_CLOSE:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync OnDestroy();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync DestroyWindow(hWnd);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync PostQuitMessage(0);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return 0;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case WM_LBUTTONDOWN:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("WM_LBUTTONDOWN\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mfMouseButtonDown = true;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return 0;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case WM_LBUTTONUP:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("WM_LBUTTONUP\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mfMouseButtonDown = false;
b32e84697b0631a07937ef7aa529e596b09da876vboxsync
b32e84697b0631a07937ef7aa529e596b09da876vboxsync /* As the mouse button was released, Hide the proxy window again.
b32e84697b0631a07937ef7aa529e596b09da876vboxsync * This can happen if
b32e84697b0631a07937ef7aa529e596b09da876vboxsync * - the user bumped a guest window to the screen's edges
b32e84697b0631a07937ef7aa529e596b09da876vboxsync * - there was no drop data from the guest available and the user
b32e84697b0631a07937ef7aa529e596b09da876vboxsync * enters the guest screen again after this unsuccessful operation */
b32e84697b0631a07937ef7aa529e596b09da876vboxsync reset();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return 0;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync case WM_MOUSELEAVE:
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync LogFlowThisFunc(("WM_MOUSELEAVE\n"));
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync return 0;
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Will only be called once; after the first mouse move, this
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * window will be hidden! */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case WM_MOUSEMOVE:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogFlowThisFunc(("WM_MOUSEMOVE: mfMouseButtonDown=%RTbool, mMode=%ld, mState=%ld\n",
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync mfMouseButtonDown, mMode, mState));
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#ifdef DEBUG_andy
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync POINT p;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync GetCursorPos(&p);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogFlowThisFunc(("WM_MOUSEMOVE: curX=%ld, curY=%ld\n", p.x, p.y));
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#endif
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync int rc = VINF_SUCCESS;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (mMode == HG) /* Host to guest. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync /* Dragging not started yet? Kick it off ... */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if ( mfMouseButtonDown
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync && (mState != Dragging))
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync mState = Dragging;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#if 0
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync /* Delay hiding the proxy window a bit when debugging, to see
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync * whether the desired range is covered correctly. */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync RTThreadSleep(5000);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync hide();
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
1a3b02207c6b6aca1b7bdd50fc2e79defe4e405evboxsync LogFlowThisFunc(("Starting drag and drop: uAllActions=0x%x, dwOKEffects=0x%x ...\n",
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync uAllActions, startupInfo.dwOKEffects));
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync AssertPtr(startupInfo.pDataObject);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync AssertPtr(startupInfo.pDropSource);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync DWORD dwEffect;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync HRESULT hr = DoDragDrop(startupInfo.pDataObject, startupInfo.pDropSource,
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync startupInfo.dwOKEffects, &dwEffect);
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync LogFlowThisFunc(("hr=%Rhrc, dwEffect=%RI32\n", hr, dwEffect));
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync switch (hr)
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync case DRAGDROP_S_DROP:
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync mState = Dropped;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync break;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync case DRAGDROP_S_CANCEL:
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync mState = Canceled;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync break;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync default:
1a3b02207c6b6aca1b7bdd50fc2e79defe4e405evboxsync LogFlowThisFunc(("Drag and drop failed with %Rhrc\n", hr));
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync mState = Canceled;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync rc = VERR_GENERAL_FAILURE; /** @todo Find a better status code. */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync break;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync int rc2 = RTCritSectEnter(&mCritSect);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (RT_SUCCESS(rc2))
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync startupInfo.pDropSource->Release();
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync startupInfo.pDataObject->Release();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync RT_ZERO(startupInfo);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync rc2 = RTCritSectLeave(&mCritSect);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (RT_SUCCESS(rc))
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync rc = rc2;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync mMode = Unknown;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync else if (mMode == GH) /* Guest to host. */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync /* Starting here VBoxDnDDropTarget should
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * take over; was instantiated when registering
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * this proxy window as a (valid) drop target. */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync else
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync rc = VERR_NOT_SUPPORTED;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogFlowThisFunc(("WM_MOUSEMOVE: mMode=%ld, mState=%ld, rc=%Rrc\n",
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync mMode, mState, rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return 0;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync case WM_NCMOUSEHOVER:
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync LogFlowThisFunc(("WM_NCMOUSEHOVER\n"));
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync return 0;
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync case WM_NCMOUSELEAVE:
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync LogFlowThisFunc(("WM_NCMOUSELEAVE\n"));
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync return 0;
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case WM_VBOXTRAY_DND_MESSAGE:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VBOXDNDEVENT *pEvent = (PVBOXDNDEVENT)lParam;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (!pEvent)
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync break; /* No event received, bail out. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("Received uType=%RU32, uScreenID=%RU32\n",
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync pEvent->Event.uType, pEvent->Event.uScreenId));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync switch (pEvent->Event.uType)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_HG_EVT_ENTER:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("HOST_DND_HG_EVT_ENTER\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (pEvent->Event.cbFormats)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCList<RTCString> lstFormats =
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCString(pEvent->Event.pszFormats, pEvent->Event.cbFormats - 1).split("\r\n");
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = OnHgEnter(lstFormats, pEvent->Event.u.a.uAllActions);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync else
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertMsgFailed(("cbFormats is 0\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = VERR_INVALID_PARAMETER;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Note: After HOST_DND_HG_EVT_ENTER there immediately is a move
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * event, so fall through is intentional here. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_HG_EVT_MOVE:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("HOST_DND_HG_EVT_MOVE: %d,%d\n",
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync pEvent->Event.u.a.uXpos, pEvent->Event.u.a.uYpos));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync rc = OnHgMove(pEvent->Event.u.a.uXpos, pEvent->Event.u.a.uYpos,
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync pEvent->Event.u.a.uDefAction);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_HG_EVT_LEAVE:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("HOST_DND_HG_EVT_LEAVE\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = OnHgLeave();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_HG_EVT_DROPPED:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("HOST_DND_HG_EVT_DROPPED\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = OnHgDrop();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_HG_SND_DATA:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("HOST_DND_HG_SND_DATA\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync rc = OnHgDataReceived(pEvent->Event.u.b.pvData,
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync pEvent->Event.u.b.cbData);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("HOST_DND_HG_EVT_CANCEL\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = OnHgCancel();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_GH_REQ_PENDING:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("HOST_DND_GH_REQ_PENDING\n"));
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#ifdef VBOX_WITH_DRAG_AND_DROP_GH
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = OnGhIsDnDPending(pEvent->Event.uScreenId);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#else
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync rc = VERR_NOT_SUPPORTED;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_GH_EVT_DROPPED:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("HOST_DND_GH_EVT_DROPPED\n"));
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#ifdef VBOX_WITH_DRAG_AND_DROP_GH
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = OnGhDropped(pEvent->Event.pszFormats,
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync pEvent->Event.cbFormats,
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync pEvent->Event.u.a.uDefAction);
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync#else
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync rc = VERR_NOT_SUPPORTED;
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync#endif
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync break;
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync }
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync default:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = VERR_NOT_SUPPORTED;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Some messages require cleanup. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync switch (pEvent->Event.uType)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_HG_EVT_ENTER:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_HG_EVT_MOVE:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_HG_EVT_DROPPED:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifdef VBOX_WITH_DRAG_AND_DROP_GH
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_GH_EVT_DROPPED:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (pEvent->Event.pszFormats)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTMemFree(pEvent->Event.pszFormats);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_HG_SND_DATA:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (pEvent->Event.pszFormats)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTMemFree(pEvent->Event.pszFormats);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (pEvent->Event.u.b.pvData)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTMemFree(pEvent->Event.u.b.pvData);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync default:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Ignore. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (pEvent)
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync LogFlowThisFunc(("Processing event %RU32 resulted in rc=%Rrc\n",
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync pEvent->Event.uType, rc));
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTMemFree(pEvent);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return 0;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync default:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return DefWindowProc(hWnd, uMsg, wParam, lParam);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#ifdef VBOX_WITH_DRAG_AND_DROP_GH
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync/**
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync * Registers this proxy window as a local drop target.
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync *
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync * @return IPRT status code.
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsyncint VBoxDnDWnd::RegisterAsDropTarget(void)
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync{
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (pDropTarget) /* Already registered as drop target? */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync return VINF_SUCCESS;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync int rc;
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync try
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync pDropTarget = new VBoxDnDDropTarget(this /* pParent */);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync AssertPtr(pDropTarget);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync HRESULT hr = CoLockObjectExternal(pDropTarget, TRUE /* fLock */,
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync FALSE /* fLastUnlockReleases */);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (SUCCEEDED(hr))
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync hr = RegisterDragDrop(hWnd, pDropTarget);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (FAILED(hr))
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync LogRel(("DnD: Creating drop target failed with hr=%Rhrc\n", hr));
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync }
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync else
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync {
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync rc = VINF_SUCCESS;
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync }
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync }
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync catch (std::bad_alloc)
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync {
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync rc = VERR_NO_MEMORY;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogFlowFuncLeaveRC(rc);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync return rc;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync}
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Unregisters this proxy as a drop target.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsyncint VBoxDnDWnd::UnregisterAsDropTarget(void)
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync{
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync LogFlowFuncEnter();
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (!pDropTarget) /* No drop target? Bail out. */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync return VINF_SUCCESS;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync HRESULT hr = RevokeDragDrop(hWnd);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (SUCCEEDED(hr))
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync hr = CoLockObjectExternal(pDropTarget, FALSE /* fLock */,
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync TRUE /* fLastUnlockReleases */);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (SUCCEEDED(hr))
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync {
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync ULONG cRefs = pDropTarget->Release();
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync Assert(cRefs == 0);
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync pDropTarget = NULL;
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync int rc = SUCCEEDED(hr)
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync ? VINF_SUCCESS : VERR_GENERAL_FAILURE; /** @todo Fix this. */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogFlowFuncLeaveRC(rc);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync return rc;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync}
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Handles the creation of a proxy window.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::OnCreate(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = VbglR3DnDConnect(&mClientID);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_FAILURE(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("Connection to host service failed, rc=%Rrc\n", rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogFlowThisFunc(("Client ID=%RU32, rc=%Rrc\n", mClientID, rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Handles the destruction of a proxy window.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncvoid VBoxDnDWnd::OnDestroy(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VbglR3DnDDisconnect(mClientID);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogFlowThisFuncLeave();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Handles actions required when the host cursor enters
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * the guest's screen to initiate a host -> guest DnD operation.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param lstFormats Supported formats offered by the host.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param uAllActions Supported actions offered by the host.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::OnHgEnter(const RTCList<RTCString> &lstFormats, uint32_t uAllActions)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (mMode == GH) /* Wrong mode? Bail out. */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync return VERR_WRONG_ORDER;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifdef DEBUG
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("uActions=0x%x, lstFormats=%zu: ", uAllActions, lstFormats.size()));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync for (size_t i = 0; i < lstFormats.size(); i++)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlow(("'%s' ", lstFormats.at(i).c_str()));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlow(("\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync reset();
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync setMode(HG);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Save all allowed actions. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync this->uAllActions = uAllActions;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /*
aa08d96e9f8a68de2d11b24f680757cb02d1f16bvboxsync * Check if requested formats are compatible with this client.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
aa08d96e9f8a68de2d11b24f680757cb02d1f16bvboxsync LogFlowThisFunc(("Supported formats:\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync for (size_t i = 0; i < lstFormats.size(); i++)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync bool fSupported = false;
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync for (size_t a = 0; a < this->lstAllowedFormats.size(); a++)
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync {
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync LogFlowThisFunc(("\t\"%s\" <=> \"%s\"\n", this->lstAllowedFormats.at(a).c_str(), lstFormats.at(i).c_str()));
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync fSupported = RTStrICmp(this->lstAllowedFormats.at(a).c_str(), lstFormats.at(i).c_str()) == 0;
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync if (fSupported)
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync {
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync this->lstFormats.append(lstFormats.at(i));
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync break;
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync }
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync }
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("\t%s: %RTbool\n", lstFormats.at(i).c_str(), fSupported));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync /*
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync * Warn in the log if this guest does not accept anything.
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync */
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync if (!this->lstFormats.size())
1a3b02207c6b6aca1b7bdd50fc2e79defe4e405evboxsync LogRel(("DnD: Warning: No supported drag and drop formats on the guest found!\n"));
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /*
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * Prepare the startup info for DoDragDrop().
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync try
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync /* Translate our drop actions into allowed Windows drop effects. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync startupInfo.dwOKEffects = DROPEFFECT_NONE;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (uAllActions)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (uAllActions & DND_COPY_ACTION)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync startupInfo.dwOKEffects |= DROPEFFECT_COPY;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (uAllActions & DND_MOVE_ACTION)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync startupInfo.dwOKEffects |= DROPEFFECT_MOVE;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (uAllActions & DND_LINK_ACTION)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync startupInfo.dwOKEffects |= DROPEFFECT_LINK;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync startupInfo.pDropSource = new VBoxDnDDropSource(this);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync startupInfo.pDataObject = new VBoxDnDDataObject();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync catch (std::bad_alloc)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = VERR_NO_MEMORY;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync rc = makeFullscreen();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFuncLeaveRC(rc);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Handles actions required when the host cursor moves inside
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * the guest's screen.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param u32xPos Absolute X position (in pixels) of the host cursor
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * inside the guest.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param u32yPos Absolute Y position (in pixels) of the host cursor
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * inside the guest.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param uAction Action the host wants to perform while moving.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Currently ignored.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::OnHgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t uAction)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync int rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync uint32_t uActionNotify = DND_IGNORE_ACTION;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (mMode == HG)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync LogFlowThisFunc(("u32xPos=%RU32, u32yPos=%RU32, uAction=0x%x\n",
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync u32xPos, u32yPos, uAction));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = mouseMove(u32xPos, u32yPos, MOUSEEVENTF_LEFTDOWN);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (RT_SUCCESS(rc))
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = RTCritSectEnter(&mCritSect);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (RT_SUCCESS(rc))
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if ( (Dragging == mState)
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync && startupInfo.pDropSource)
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync uActionNotify = startupInfo.pDropSource->GetCurrentAction();
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync RTCritSectLeave(&mCritSect);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync else /* Just acknowledge the operation with an ignore action. */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = VbglR3DnDHGAcknowledgeOperation(mClientID, uActionNotify);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_FAILURE(rc))
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync LogFlowThisFunc(("Acknowledging operation failed with rc=%Rrc\n", rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("Returning uActionNotify=0x%x, rc=%Rrc\n", uActionNotify, rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Handles actions required when the host cursor leaves
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * the guest's screen again.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::OnHgLeave(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (mMode == GH) /* Wrong mode? Bail out. */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync return VERR_WRONG_ORDER;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogFlowThisFunc(("mMode=%ld, mState=%RU32\n", mMode, mState));
1a3b02207c6b6aca1b7bdd50fc2e79defe4e405evboxsync LogRel(("DnD: Drag and drop operation aborted\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync reset();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Post ESC to our window to officially abort the
1a3b02207c6b6aca1b7bdd50fc2e79defe4e405evboxsync * drag and drop operation. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync PostMessage(hWnd, WM_KEYDOWN, VK_ESCAPE, 0 /* lParam */);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFuncLeaveRC(rc);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Handles actions required when the host cursor wants to drop
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * and therefore start a "drop" action in the guest.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::OnHgDrop(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (mMode == GH)
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync return VERR_WRONG_ORDER;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogFlowThisFunc(("mMode=%ld, mState=%RU32\n", mMode, mState));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (mState == Dragging)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync if (lstFormats.size() >= 1)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync /** @todo What to do when multiple formats are available? */
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync mFormatRequested = lstFormats.at(0);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync rc = RTCritSectEnter(&mCritSect);
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync if (RT_SUCCESS(rc))
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync {
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync if (startupInfo.pDataObject)
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync startupInfo.pDataObject->SetStatus(VBoxDnDDataObject::Dropping);
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync else
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync rc = VERR_NOT_FOUND;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync RTCritSectLeave(&mCritSect);
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync }
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync if (RT_SUCCESS(rc))
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync {
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync LogRel(("DnD: Requesting data as '%s' ...\n", mFormatRequested.c_str()));
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync rc = VbglR3DnDHGRequestData(mClientID, mFormatRequested.c_str());
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync if (RT_FAILURE(rc))
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync LogFlowThisFunc(("Requesting data failed with rc=%Rrc\n", rc));
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync else /* Should never happen. */
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync LogRel(("DnD: Error: Host did not specify a data format for drop data\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFuncLeaveRC(rc);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Handles actions required when the host has sent over DnD data
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * to the guest after a "drop" event.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param pvData Pointer to raw data received.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param cbData Size of data (in bytes) received.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::OnHgDataReceived(const void *pvData, uint32_t cbData)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("mState=%ld, pvData=%p, cbData=%RU32\n",
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mState, pvData, cbData));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mState = Dropped;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (pvData)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Assert(cbData);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = RTCritSectEnter(&mCritSect);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (startupInfo.pDataObject)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = startupInfo.pDataObject->Signal(mFormatRequested, pvData, cbData);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync else
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = VERR_NOT_FOUND;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCritSectLeave(&mCritSect);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync int rc2 = mouseRelease();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = rc2;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFuncLeaveRC(rc);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Handles actions required when the host wants to cancel an action
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * host -> guest operation.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::OnHgCancel(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = RTCritSectEnter(&mCritSect);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (startupInfo.pDataObject)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync startupInfo.pDataObject->Abort();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCritSectLeave(&mCritSect);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync int rc2 = mouseRelease();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = rc2;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync reset();
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifdef VBOX_WITH_DRAG_AND_DROP_GH
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Handles actions required to start a guest -> host DnD operation.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * This works by letting the host ask whether a DnD operation is pending
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * on the guest. The guest must not know anything about the host's DnD state
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * and/or operations due to security reasons.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * To capture a pending DnD operation on the guest which then can be communicated
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * to the host the proxy window needs to be registered as a drop target. This drop
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * target then will act as a proxy target between the guest OS and the host. In other
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * words, the guest OS will use this proxy target as a regular (invisible) window
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * which can be used by the regular guest OS' DnD mechanisms, independently of the
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * host OS. To make sure this proxy target is able receive an in-progress DnD operation
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * on the guest, it will be shown invisibly across all active guest OS screens. Just
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * think of an opened umbrella across all screens here.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * As soon as the proxy target and its underlying data object receive appropriate
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * DnD messages they'll be hidden again, and the control will be transferred back
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * this class again.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param uScreenID Screen ID the host wants to query a pending operation
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * for. Currently not used/needed here.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsyncint VBoxDnDWnd::OnGhIsDnDPending(uint32_t uScreenID)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogFlowThisFunc(("mMode=%ld, mState=%ld, uScreenID=%RU32\n",
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync mMode, mState, uScreenID));
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (mMode == Unknown)
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync setMode(GH);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (mMode != GH)
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync return VERR_WRONG_ORDER;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (mState == Uninitialized)
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync /* Nothing to do here yet. */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync mState = Initialized;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync int rc;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (mState == Initialized)
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync rc = makeFullscreen();
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (RT_SUCCESS(rc))
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync {
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync /*
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * We have to release the left mouse button to
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * get into our (invisible) proxy window.
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync */
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync mouseRelease();
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync /*
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * Even if we just released the left mouse button
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * we're still in the dragging state to handle our
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * own drop target (for the host).
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync mState = Dragging;
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync else
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync rc = VINF_SUCCESS;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync /**
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * Some notes regarding guest cursor movement:
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * - The host only sends an HOST_DND_GH_REQ_PENDING message to the guest
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * if the mouse cursor is outside the VM's window.
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * - The guest does not know anything about the host's cursor
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * position / state due to security reasons.
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * - The guest *only* knows that the host currently is asking whether a
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync * guest DnD operation is in progress.
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync */
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if ( RT_SUCCESS(rc)
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync && mState == Dragging)
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync /** @todo Put this block into a function! */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync POINT p;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync GetCursorPos(&p);
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync ClientToScreen(hWnd, &p);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#ifdef DEBUG_andy
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync LogFlowThisFunc(("Client to screen curX=%ld, curY=%ld\n", p.x, p.y));
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#endif
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync /** @todo Multi-monitor setups? */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync int iScreenX = GetSystemMetrics(SM_CXSCREEN) - 1;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync int iScreenY = GetSystemMetrics(SM_CYSCREEN) - 1;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync static LONG px = p.x;
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync if (px <= 0)
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync px = 1;
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync static LONG py = p.y;
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync if (py <= 0)
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync py = 1;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync rc = mouseMove(px, py, 0 /* dwMouseInputFlags */);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync if (RT_SUCCESS(rc))
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync {
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync uint32_t uDefAction = DND_IGNORE_ACTION;
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync AssertPtr(pDropTarget);
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync RTCString strFormats = pDropTarget->Formats();
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync if (!strFormats.isEmpty())
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync {
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync uDefAction = DND_COPY_ACTION;
9725ca270919a5220a25cca2c05f4d85bf0f79e2vboxsync
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync LogFlowFunc(("Acknowledging pDropTarget=0x%p, uDefAction=0x%x, uAllActions=0x%x, strFormats=%s\n",
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync pDropTarget, uDefAction, uAllActions, strFormats.c_str()));
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync }
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync else
b32e84697b0631a07937ef7aa529e596b09da876vboxsync {
b32e84697b0631a07937ef7aa529e596b09da876vboxsync strFormats = "unknown"; /* Prevent VERR_IO_GEN_FAILURE for IOCTL. */
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync LogFlowFunc(("No format data available yet\n"));
b32e84697b0631a07937ef7aa529e596b09da876vboxsync }
b32e84697b0631a07937ef7aa529e596b09da876vboxsync
b32e84697b0631a07937ef7aa529e596b09da876vboxsync /** @todo Support more than one action at a time. */
b32e84697b0631a07937ef7aa529e596b09da876vboxsync uAllActions = uDefAction;
b32e84697b0631a07937ef7aa529e596b09da876vboxsync
b32e84697b0631a07937ef7aa529e596b09da876vboxsync rc = VbglR3DnDGHAcknowledgePending(mClientID,
b32e84697b0631a07937ef7aa529e596b09da876vboxsync uDefAction, uAllActions, strFormats.c_str());
b32e84697b0631a07937ef7aa529e596b09da876vboxsync if (RT_FAILURE(rc))
b32e84697b0631a07937ef7aa529e596b09da876vboxsync {
b32e84697b0631a07937ef7aa529e596b09da876vboxsync char szMsg[256]; /* Sizes according to MSDN. */
b32e84697b0631a07937ef7aa529e596b09da876vboxsync char szTitle[64];
b32e84697b0631a07937ef7aa529e596b09da876vboxsync
b32e84697b0631a07937ef7aa529e596b09da876vboxsync /** @todo Add some i18l tr() macros here. */
1a3b02207c6b6aca1b7bdd50fc2e79defe4e405evboxsync RTStrPrintf(szTitle, sizeof(szTitle), "VirtualBox Guest Additions Drag and Drop");
1a3b02207c6b6aca1b7bdd50fc2e79defe4e405evboxsync RTStrPrintf(szMsg, sizeof(szMsg), "Drag and drop to the host either is not supported or disabled. "
1a3b02207c6b6aca1b7bdd50fc2e79defe4e405evboxsync "Please enable Guest to Host or Bidirectional drag and drop mode "
b32e84697b0631a07937ef7aa529e596b09da876vboxsync "or re-install the VirtualBox Guest Additions.");
b32e84697b0631a07937ef7aa529e596b09da876vboxsync switch (rc)
b32e84697b0631a07937ef7aa529e596b09da876vboxsync {
b32e84697b0631a07937ef7aa529e596b09da876vboxsync case VERR_ACCESS_DENIED:
b32e84697b0631a07937ef7aa529e596b09da876vboxsync rc = hlpShowBalloonTip(ghInstance, ghwndToolWindow, ID_TRAYICON,
b32e84697b0631a07937ef7aa529e596b09da876vboxsync szMsg, szTitle,
b32e84697b0631a07937ef7aa529e596b09da876vboxsync 15 * 1000 /* Time to display in msec */, NIIF_INFO);
b32e84697b0631a07937ef7aa529e596b09da876vboxsync AssertRC(rc);
b32e84697b0631a07937ef7aa529e596b09da876vboxsync break;
b32e84697b0631a07937ef7aa529e596b09da876vboxsync
b32e84697b0631a07937ef7aa529e596b09da876vboxsync default:
b32e84697b0631a07937ef7aa529e596b09da876vboxsync break;
b32e84697b0631a07937ef7aa529e596b09da876vboxsync }
b32e84697b0631a07937ef7aa529e596b09da876vboxsync }
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b32e84697b0631a07937ef7aa529e596b09da876vboxsync if (RT_FAILURE(rc))
b32e84697b0631a07937ef7aa529e596b09da876vboxsync reset(); /* Reset state on failure. */
b32e84697b0631a07937ef7aa529e596b09da876vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogFlowFuncLeaveRC(rc);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Handles actions required to let the guest know that the host
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * started a "drop" action on the host. This will tell the guest
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * to send data in a specific format the host requested.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param pszFormat Format the host requests the data in.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param cbFormat Size (in bytes) of format string.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param uDefAction Default action on the host.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsyncint VBoxDnDWnd::OnGhDropped(const char *pszFormat, uint32_t cbFormat,
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync uint32_t uDefAction)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync AssertPtrReturn(pszFormat, VERR_INVALID_POINTER);
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync AssertReturn(cbFormat, VERR_INVALID_PARAMETER);
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync LogFlowThisFunc(("mMode=%ld, mState=%ld, pDropTarget=0x%p, pszFormat=%s, uDefAction=0x%x\n",
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync mMode, mState, pDropTarget, pszFormat, uDefAction));
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync int rc;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (mMode == GH)
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (mState == Dragging)
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync AssertPtr(pDropTarget);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout in ms */);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync reset();
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync }
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync else if (mState == Dropped)
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = VINF_SUCCESS;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync }
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync else
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = VERR_WRONG_ORDER;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync if (RT_SUCCESS(rc))
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync {
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync /** @todo Respect uDefAction. */
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync void *pvData = pDropTarget->DataMutableRaw();
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync AssertPtr(pvData);
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync uint32_t cbData = pDropTarget->DataSize();
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync Assert(cbData);
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = VbglR3DnDGHSendData(mClientID, pszFormat, pvData, cbData);
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync LogFlowFunc(("Sent pvData=0x%p, cbData=%RU32, rc=%Rrc\n",
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync pvData, cbData, rc));
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync else
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync rc = VERR_WRONG_ORDER;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogFlowFuncLeaveRC(rc);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Injects a DnD event in this proxy window's Windows
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * event queue. The (allocated) event will be deleted by
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * this class after processing.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param pEvent Event to inject.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::ProcessEvent(PVBOXDNDEVENT pEvent)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync BOOL fRc = PostMessage(hWnd, WM_VBOXTRAY_DND_MESSAGE,
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync 0 /* wParm */, (LPARAM)pEvent /* lParm */);
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync if (!fRc)
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync {
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync static int s_iBitchedAboutFailedDnDMessages = 0;
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync if (s_iBitchedAboutFailedDnDMessages++ < 10)
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync {
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync DWORD dwErr = GetLastError();
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync LogRel(("DnD: Processing event %p failed with %ld (%Rrc), skpping\n",
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync pEvent, dwErr, RTErrConvertFromWin32(dwErr)));
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync }
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync RTMemFree(pEvent);
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync pEvent = NULL;
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync return VERR_NO_MEMORY;
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Hides the proxy window again.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsyncint VBoxDnDWnd::hide(void)
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync{
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync#ifdef DEBUG_andy
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync LogFlowFunc(("\n"));
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync#endif
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync ShowWindow(hWnd, SW_HIDE);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync return VINF_SUCCESS;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync}
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Shows the (invisible) proxy window in fullscreen,
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * spawned across all active guest monitors.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsyncint VBoxDnDWnd::makeFullscreen(void)
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync{
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync int rc = VINF_SUCCESS;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync RECT r;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync RT_ZERO(r);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync BOOL fRc;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync HDC hDC = GetDC(NULL /* Entire screen */);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (hDC)
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync fRc = s_pfnEnumDisplayMonitors
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* EnumDisplayMonitors is not available on NT4. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync ? s_pfnEnumDisplayMonitors(hDC, NULL, VBoxDnDWnd::MonitorEnumProc, (LPARAM)&r):
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync FALSE;
be2d64b9017ca17cf597a73767a1cf928a7e3f7dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (!fRc)
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync rc = VERR_NOT_FOUND;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync ReleaseDC(NULL, hDC);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync else
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync rc = VERR_ACCESS_DENIED;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (RT_FAILURE(rc))
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync /* If multi-monitor enumeration failed above, try getting at least the
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync * primary monitor as a fallback. */
be2d64b9017ca17cf597a73767a1cf928a7e3f7dvboxsync r.left = 0;
be2d64b9017ca17cf597a73767a1cf928a7e3f7dvboxsync r.top = 0;
be2d64b9017ca17cf597a73767a1cf928a7e3f7dvboxsync r.right = GetSystemMetrics(SM_CXSCREEN);
be2d64b9017ca17cf597a73767a1cf928a7e3f7dvboxsync r.bottom = GetSystemMetrics(SM_CYSCREEN);
be2d64b9017ca17cf597a73767a1cf928a7e3f7dvboxsync rc = VINF_SUCCESS;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (RT_SUCCESS(rc))
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync LONG lStyle = GetWindowLong(hWnd, GWL_STYLE);
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync SetWindowLong(hWnd, GWL_STYLE,
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync lStyle & ~(WS_CAPTION | WS_THICKFRAME));
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync LONG lExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync SetWindowLong(hWnd, GWL_EXSTYLE,
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync lExStyle & ~( WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync fRc = SetWindowPos(hWnd, HWND_TOPMOST,
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync r.left,
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync r.top,
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync r.right - r.left,
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync r.bottom - r.top,
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#ifdef VBOX_DND_DEBUG_WND
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync SWP_SHOWWINDOW | SWP_FRAMECHANGED);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#else
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync SWP_SHOWWINDOW | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOACTIVATE);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync#endif
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync if (fRc)
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync {
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogFlowFunc(("Virtual screen is %ld,%ld,%ld,%ld (%ld x %ld)\n",
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync r.left, r.top, r.right, r.bottom,
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync r.right - r.left, r.bottom - r.top));
440c59bb6f5f678ce4e2569847262f6350c80fabvboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync else
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync DWORD dwErr = GetLastError();
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogRel(("DnD: Failed to set proxy window position, rc=%Rrc\n",
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync RTErrConvertFromWin32(dwErr)));
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync else
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogRel(("DnD: Failed to determine virtual screen size, rc=%Rrc\n", rc));
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync LogFlowFuncLeaveRC(rc);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync return rc;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync}
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Moves the guest mouse cursor to a specific position.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param x X position (in pixels) to move cursor to.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param y Y position (in pixels) to move cursor to.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param dwMouseInputFlags Additional movement flags. @sa MOUSEEVENTF_ flags.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsyncint VBoxDnDWnd::mouseMove(int x, int y, DWORD dwMouseInputFlags)
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync{
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync int iScreenX = GetSystemMetrics(SM_CXSCREEN) - 1;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync int iScreenY = GetSystemMetrics(SM_CYSCREEN) - 1;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync INPUT Input[1] = { 0 };
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync Input[0].type = INPUT_MOUSE;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync Input[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync | dwMouseInputFlags;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync Input[0].mi.dx = x * (65535 / iScreenX);
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync Input[0].mi.dy = y * (65535 / iScreenY);
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync int rc;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync if (s_pfnSendInput(1 /* Number of inputs */,
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync Input, sizeof(INPUT)))
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync {
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync#ifdef DEBUG_andy
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync CURSORINFO ci;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync RT_ZERO(ci);
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync ci.cbSize = sizeof(ci);
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync BOOL fRc = GetCursorInfo(&ci);
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync if (fRc)
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync LogFlowThisFunc(("Cursor shown=%RTbool, cursor=0x%p, x=%d, y=%d\n",
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync (ci.flags & CURSOR_SHOWING) ? true : false,
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync ci.hCursor, ci.ptScreenPos.x, ci.ptScreenPos.y));
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync#endif
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync rc = VINF_SUCCESS;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync }
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync else
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync {
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync DWORD dwErr = GetLastError();
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync rc = RTErrConvertFromWin32(dwErr);
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync LogFlowFunc(("SendInput failed with rc=%Rrc\n", rc));
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync }
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync return rc;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync}
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Releases a previously pressed left guest mouse button.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsyncint VBoxDnDWnd::mouseRelease(void)
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync{
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync#ifdef DEBUG_andy
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync LogFlowFunc(("\n"));
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync#endif
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync int rc;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync /* Release mouse button in the guest to start the "drop"
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync * action at the current mouse cursor position. */
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync INPUT Input[1] = { 0 };
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync Input[0].type = INPUT_MOUSE;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync Input[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync if (!s_pfnSendInput(1, Input, sizeof(INPUT)))
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync {
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync DWORD dwErr = GetLastError();
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync rc = RTErrConvertFromWin32(dwErr);
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync LogFlowFunc(("SendInput failed with rc=%Rrc\n", rc));
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync }
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync else
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync rc = VINF_SUCCESS;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync return rc;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync}
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Resets the proxy window.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncvoid VBoxDnDWnd::reset(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync LogFlowThisFunc(("Resetting, old mMode=%ld, mState=%ld\n",
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync mMode, mState));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync /*
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync * Note: Don't clear this->lstAllowedFormats at the moment, as this value is initialized
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync * on class creation. We might later want to modify the allowed formats in runtime,
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync * so keep this in mind when implementing this.
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync */
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync this->lstFormats.clear();
04f905599c3a63d4349a8584d7ca5b9e0a3c3b98vboxsync this->uAllActions = DND_IGNORE_ACTION;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync int rc2 = setMode(Unknown);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync AssertRC(rc2);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync hide();
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync}
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Sets the current operation mode of this proxy window.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync *
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @return IPRT status code.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * @param enmMode New mode to set.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsyncint VBoxDnDWnd::setMode(Mode enmMode)
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync{
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync LogFlowThisFunc(("Old mode=%ld, new mode=%ld\n",
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync mMode, enmMode));
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync mMode = enmMode;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync mState = Initialized;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync return VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Static helper function for having an own WndProc for proxy
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * window instances.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsyncstatic LRESULT CALLBACK vboxDnDWndProcInstance(HWND hWnd, UINT uMsg,
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync WPARAM wParam, LPARAM lParam)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LONG_PTR pUserData = GetWindowLongPtr(hWnd, GWLP_USERDATA);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtrReturn(pUserData, 0);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VBoxDnDWnd *pWnd = reinterpret_cast<VBoxDnDWnd *>(pUserData);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (pWnd)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return pWnd->WndProc(hWnd, uMsg, wParam, lParam);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return 0;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync/**
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * Static helper function for routing Windows messages to a specific
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync * proxy window instance.
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync */
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsyncstatic LRESULT CALLBACK vboxDnDWndProc(HWND hWnd, UINT uMsg,
fdca3f8441b2cfdf10d1c78011986554948a7753vboxsync WPARAM wParam, LPARAM lParam)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Note: WM_NCCREATE is not the first ever message which arrives, but
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * early enough for us. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (uMsg == WM_NCCREATE)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LPCREATESTRUCT pCS = (LPCREATESTRUCT)lParam;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtr(pCS);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pCS->lpCreateParams);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)vboxDnDWndProcInstance);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return vboxDnDWndProcInstance(hWnd, uMsg, wParam, lParam);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* No window associated yet. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return DefWindowProc(hWnd, uMsg, wParam, lParam);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/**
1a3b02207c6b6aca1b7bdd50fc2e79defe4e405evboxsync * Initializes drag and drop.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync *
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * @return IPRT status code.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * @param pEnv The DnD service's environment.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * @param ppInstance The instance pointer which refer to this object.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * @param pfStartThread Pointer to flag whether the DnD service can be started or not.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** ppInstance not used here. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtrReturn(pfStartThread, VERR_INVALID_POINTER);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFuncEnter();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync *pfStartThread = false;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync PVBOXDNDCONTEXT pCtx = &gCtx;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync bool fSupportedOS = true;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync s_pfnSendInput = (PFNSENDINPUT)
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync RTLdrGetSystemSymbol("User32.dll", "SendInput");
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync fSupportedOS = !RT_BOOL(s_pfnSendInput == NULL);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync s_pfnEnumDisplayMonitors = (PFNENUMDISPLAYMONITORS)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync RTLdrGetSystemSymbol("User32.dll", "EnumDisplayMonitors");
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* g_pfnEnumDisplayMonitors is optional. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync if (!fSupportedOS)
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync {
1a3b02207c6b6aca1b7bdd50fc2e79defe4e405evboxsync LogRel(("DnD: Not supported Windows version, disabling drag and drop support\n"));
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync rc = VERR_NOT_SUPPORTED;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync else
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync rc = VINF_SUCCESS;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
cdfb791447f500ee9c12cc826f49f2668798d07bvboxsync /* Assign service environment to our context. */
cdfb791447f500ee9c12cc826f49f2668798d07bvboxsync pCtx->pEnv = pEnv;
cdfb791447f500ee9c12cc826f49f2668798d07bvboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync /* Create the proxy window. At the moment we
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync * only support one window at a time. */
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync VBoxDnDWnd *pWnd = NULL;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync try
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync {
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync pWnd = new VBoxDnDWnd();
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync rc = pWnd->Initialize(pCtx);
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync /* Add proxy window to our proxy windows list. */
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync if (RT_SUCCESS(rc))
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync pCtx->lstWnd.append(pWnd);
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync }
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync catch (std::bad_alloc)
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync {
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync rc = VERR_NO_MEMORY;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = RTSemEventCreate(&pCtx->hEvtQueueSem);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync *ppInstance = pCtx;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync *pfStartThread = true;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
1a3b02207c6b6aca1b7bdd50fc2e79defe4e405evboxsync LogRel(("DnD: Drag and drop service successfully started\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
1a3b02207c6b6aca1b7bdd50fc2e79defe4e405evboxsync LogRel(("DnD: Initializing drag and drop service failed with rc=%Rrc\n", rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncvoid VBoxDnDStop(const VBOXSERVICEENV *pEnv, void *pInstance)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtrReturnVoid(pEnv);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtrReturnVoid(pInstance);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFunc(("Stopping pInstance=%p\n", pInstance));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync PVBOXDNDCONTEXT pCtx = (PVBOXDNDCONTEXT)pInstance;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtr(pCtx);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Set shutdown indicator. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync ASMAtomicWriteBool(&pCtx->fShutdown, true);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncvoid VBoxDnDDestroy(const VBOXSERVICEENV *pEnv, void *pInstance)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtr(pEnv);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtr(pInstance);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFunc(("Destroying pInstance=%p\n", pInstance));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync PVBOXDNDCONTEXT pCtx = (PVBOXDNDCONTEXT)pInstance;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtr(pCtx);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync /** @todo At the moment we only have one DnD proxy window. */
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync Assert(pCtx->lstWnd.size() == 1);
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync VBoxDnDWnd *pWnd = pCtx->lstWnd.first();
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync if (pWnd)
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync delete pWnd;
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync if (pCtx->hEvtQueueSem != NIL_RTSEMEVENT)
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync RTSemEventDestroy(pCtx->hEvtQueueSem);
e6d5e53bf42a48e3363ce7075cac0cdf83f956b5vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFunc(("Destroyed pInstance=%p, rc=%Rrc\n",
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync pInstance, rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncunsigned __stdcall VBoxDnDThread(void *pInstance)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("pInstance=%p\n", pInstance));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync PVBOXDNDCONTEXT pCtx = (PVBOXDNDCONTEXT)pInstance;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtr(pCtx);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync uint32_t uClientID;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = VbglR3DnDConnect(&uClientID);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_FAILURE(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** @todo At the moment we only have one DnD proxy window. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Assert(pCtx->lstWnd.size() == 1);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VBoxDnDWnd *pWnd = pCtx->lstWnd.first();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtr(pWnd);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync /* Number of invalid messages skipped in a row. */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync int cMsgSkippedInvalid = 0;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync do
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync PVBOXDNDEVENT pEvent = (PVBOXDNDEVENT)RTMemAlloc(sizeof(VBOXDNDEVENT));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (!pEvent)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = VERR_NO_MEMORY;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Note: pEvent will be free'd by the consumer later. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = VbglR3DnDProcessNextMessage(uClientID, &pEvent->Event);
82391de567696f10b21a762fde6a06fe3c266d28vboxsync LogFlowFunc(("VbglR3DnDProcessNextMessage returned uType=%RU32, rc=%Rrc\n",
82391de567696f10b21a762fde6a06fe3c266d28vboxsync pEvent->Event.uType, rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (ASMAtomicReadBool(&pCtx->fShutdown))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync cMsgSkippedInvalid = 0; /* Reset skipped messages count. */
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("Received new event, type=%RU32\n", pEvent->Event.uType));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc2 = pWnd->ProcessEvent(pEvent);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_FAILURE(rc2))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("Processing event failed with rc=%Rrc\n", rc2));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync else if (rc == VERR_CANCELLED)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc2 = pWnd->OnHgCancel();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_FAILURE(rc2))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("Cancelling failed with rc=%Rrc\n", rc2));
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync else
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("Processing next message failed with rc=%Rrc\n", rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync /* Old(er) hosts either are broken regarding DnD support or otherwise
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync * don't support the stuff we do on the guest side, so make sure we
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync * don't process invalid messages forever. */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (cMsgSkippedInvalid++ > 3)
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync LogRel(("DnD: Too many invalid/skipped messages from host, exiting ...\n"));
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync break;
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync }
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync int rc2 = VbglR3DnDGHSendError(uClientID, rc);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync AssertRC(rc2);
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync }
b8e7a8042499abf6f2551c545f6141b36868ab4dvboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (ASMAtomicReadBool(&pCtx->fShutdown))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (RT_FAILURE(rc)) /* Don't hog the CPU on errors. */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync RTThreadSleep(1000 /* ms */);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync } while (true);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("Shutting down ...\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VbglR3DnDDisconnect(uClientID);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFuncLeaveRC(rc);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync