VBoxDnD.cpp revision 81f46059436c6145937a4cc2c7424023a289fcd8
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/* $Id$ */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/** @file
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * VBoxDnD.cpp - Windows-specific bits of the drag'n drop service.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/*
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * Copyright (C) 2013 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/critsect.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>
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
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#define WM_VBOXTRAY_DND_MESSAGE WM_APP + 401
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
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
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncstruct VBOXDNDCONTEXT;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncclass VBoxDnDWnd;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/*
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * A drag'n drop event from the host.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsynctypedef struct VBOXDNDEVENT
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** The actual event data. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VBGLR3DNDHGCMEVENT Event;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync} VBOXDNDEVENT, *PVBOXDNDEVENT;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/**
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * DnD context data.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsynctypedef struct VBOXDNDCONTEXT
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** Pointer to the service environment. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync const VBOXSERVICEENV *pEnv;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** Shutdown indicator. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync bool fShutdown;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** Thread handle for main event queue
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * processing. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTTHREAD hEvtQueue;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** The DnD main event queue. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCMTList<VBOXDNDEVENT> lstEvtQueue;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** Semaphore for waiting on main event queue
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * events. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTSEMEVENT hEvtQueueSem;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** List of drag'n drop windows. At
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * the moment only one source is supported. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCMTList<VBoxDnDWnd*> lstWnd;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync} VBOXDNDCONTEXT, *PVBOXDNDCONTEXT;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncstatic VBOXDNDCONTEXT gCtx = {0};
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/**
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * Everything which is required to successfully start
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * a drag'n drop operation via DoDragDrop().
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsynctypedef struct VBOXDNDSTARTUPINFO
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** Our DnD data object, holding
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * the raw DnD data. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VBoxDnDDataObject *pDataObject;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** The drop source for sending the
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * DnD request to a IDropTarget. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VBoxDnDDropSource *pDropSource;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** The DnD effects which are wanted / allowed. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync DWORD dwOKEffects;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync} VBOXDNDSTARTUPINFO, *PVBOXDNDSTARTUPINFO;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/**
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * Class for handling a DnD proxy window.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync ** @todo Unify this and VBoxClient's DragInstance!
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncclass VBoxDnDWnd
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync enum State
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Uninitialized,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Initialized,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Dragging,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Dropped,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Canceled
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync };
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync enum Mode
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Unknown,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync HG,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync GH
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync };
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncpublic:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VBoxDnDWnd(void);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync virtual ~VBoxDnDWnd(void);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncpublic:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int Initialize(PVBOXDNDCONTEXT pContext);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncpublic:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** The window's thread for the native message pump and
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * OLE context. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync static int Thread(RTTHREAD hThread, void *pvUser);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncpublic:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM lParam);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** The per-instance wndproc routine. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncpublic:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int DragRelease(void);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int OnCreate(void);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync void OnDestroy(void);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* H->G */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int OnHgEnter(const RTCList<RTCString> &formats, uint32_t uAllActions);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int OnHgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t uAllActions);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int OnHgDrop(void);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int OnHgLeave(void);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int OnHgDataReceived(const void *pvData, uint32_t cData);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int OnHgCancel(void);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifdef VBOX_WITH_DRAG_AND_DROP_GH
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* G->H */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int OnGhIsDnDPending(void);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int OnGhDropped(const RTCString &strFormat, uint32_t action);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int ProcessEvent(PVBOXDNDEVENT pEvent);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncprotected:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync void reset(void);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncpublic: /** @todo Make protected! */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** Pointer to DnD context. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync PVBOXDNDCONTEXT pContext;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCRITSECT mCritSect;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTSEMEVENT mEventSem;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifdef RT_OS_WINDOWS
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** The window's handle. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync HWND hWnd;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** List of allowed MIME types this
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * client can handle. Make this a per-instance
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * property so that we can selectively allow/forbid
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * certain types later on runtime. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCList<RTCString> lstAllowedFormats;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** List of formats for the current
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * drag'n drop operation. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCList<RTCString> lstFormats;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** Flags of all current drag'n drop
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * actions allowed. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync uint32_t uAllActions;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** The startup information required
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * for the actual DoDragDrop() call. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VBOXDNDSTARTUPINFO startupInfo;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync bool mfMouseButtonDown;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#else
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** @todo */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** The window's own HGCM client ID. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync uint32_t mClientID;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Mode mMode;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync State mState;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCString mFormatRequested;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCList<RTCString> mLstFormats;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCList<RTCString> mLstActions;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync};
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncVBoxDnDWnd::VBoxDnDWnd(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync : hWnd(NULL),
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mfMouseButtonDown(false),
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mClientID(UINT32_MAX),
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mMode(Unknown),
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mState(Uninitialized)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RT_ZERO(startupInfo);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncVBoxDnDWnd::~VBoxDnDWnd(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** @todo Shutdown crit sect / event etc! */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync reset();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::DragRelease(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Release mouse button in the guest to start the "drop"
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * action at the current mouse cursor position. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync INPUT Input[1] = { 0 };
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Input[0].type = INPUT_MOUSE;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Input[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync SendInput(1, Input, sizeof(INPUT));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
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. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = RTThreadCreate(&gCtx.hEvtQueue, VBoxDnDWnd::Thread, this,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync 0, RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync "VBoxTrayDnDWnd");
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_FAILURE(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogRel(("DnD: Failed to start proxy window thread, rc=%Rrc\n", rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** @todo Wait for thread to be started! */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("Returning rc=%Rrc\n", rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync/**
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * Thread for handling the window's message pump.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync *
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * @return IPRT status code.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * @param hThread
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * @param pvUser
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
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;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync DWORD dwStyle = WS_POPUPWINDOW;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifdef VBOX_DND_DEBUG_WND
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync dwExStyle &= ~WS_EX_TRANSPARENT;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync dwStyle |= WS_VISIBLE | WS_OVERLAPPEDWINDOW;
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));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync OleInitialize(NULL);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync bool fShutdown = false;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync do
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? */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync } while (RT_SUCCESS(rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync OleUninitialize();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFuncLeaveRC(rc);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
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
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;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return 0;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Will only be called once; after the first mouse move, this
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * window will be hidden! */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case WM_MOUSEMOVE:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("WM_MOUSEMOVE: mfMouseButtonDown=%RTbool, mState=%ld\n",
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mfMouseButtonDown, mState));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Dragging not started yet? Kick it off ... */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if ( mfMouseButtonDown
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync && (mState != Dragging))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mState = Dragging;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifdef VBOX_DND_DEBUG_WND
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Delay hinding the proxy window a bit when debugging, to see
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * whether the desired range is covered correctly. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTThreadSleep(5000);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync ShowWindow(hWnd, SW_HIDE);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("Starting drag'n drop: uAllActions=0x%x, dwOKEffects=0x%x ...\n",
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync uAllActions, startupInfo.dwOKEffects));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtr(startupInfo.pDataObject);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtr(startupInfo.pDropSource);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync DWORD dwEffect;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync HRESULT hr = DoDragDrop(startupInfo.pDataObject, startupInfo.pDropSource,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync startupInfo.dwOKEffects, &dwEffect);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("rc=%Rhrc, dwEffect=%RI32\n", hr, dwEffect));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync switch (hr)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DRAGDROP_S_DROP:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mState = Dropped;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DRAGDROP_S_CANCEL:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mState = Canceled;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync default:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("Drag'n drop failed with %Rhrc\n", hr));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mState = Canceled;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = VERR_GENERAL_FAILURE; /** @todo Find a better status code. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc2 = RTCritSectEnter(&mCritSect);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc2))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync startupInfo.pDropSource->Release();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync startupInfo.pDataObject->Release();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RT_ZERO(startupInfo);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCritSectLeave(&mCritSect);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("Drag'n drop resulted in mState=%ld, rc=%Rrc\n",
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mState, rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return 0;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case WM_VBOXTRAY_DND_MESSAGE:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VBOXDNDEVENT *pEvent = (PVBOXDNDEVENT)lParam;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtr(pEvent);
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",
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync pEvent->Event.u.a.uXpos, pEvent->Event.u.a.uYpos));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = OnHgMove(pEvent->Event.u.a.uXpos, pEvent->Event.u.a.uYpos, 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
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = OnHgDataReceived(pEvent->Event.u.b.pvData, 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#ifdef VBOX_WITH_DRAG_AND_DROP_GH
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_GH_REQ_PENDING:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("HOST_DND_GH_REQ_PENDING\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::HOST_DND_GH_EVT_DROPPED:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("HOST_DND_GH_EVT_DROPPED\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync case DragAndDropSvc::GUEST_DND_GH_EVT_ERROR:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("GUEST_DND_GH_EVT_ERROR\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
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 LogFlowThisFunc(("Processing event %RU32 resulted in rc=%Rrc\n",
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync pEvent->Event.uType, rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (pEvent)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTMemFree(pEvent);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return 0;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync default:
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return DefWindowProc(hWnd, uMsg, wParam, lParam);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
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
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("Client ID=%RU32\n", mClientID));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncvoid VBoxDnDWnd::OnDestroy(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VbglR3DnDDisconnect(mClientID);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::OnHgEnter(const RTCList<RTCString> &lstFormats, uint32_t uAllActions)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync reset();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mState = Initialized;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
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
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Save all allowed actions. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync this->uAllActions = uAllActions;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /*
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * Install our allowed MIME types.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync ** @todo See todo for m_sstrAllowedMimeTypes in GuestDnDImpl.cpp.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync const RTCList<RTCString> lstAllowedMimeTypes = RTCList<RTCString>()
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Uri's */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync << "text/uri-list"
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Text */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync << "text/plain;charset=utf-8"
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync << "UTF8_STRING"
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync << "text/plain"
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync << "COMPOUND_TEXT"
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync << "TEXT"
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync << "STRING"
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* OpenOffice formates */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync << "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\""
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync << "application/x-openoffice-drawing;windows_formatname=\"Drawing Format\"";
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync this->lstAllowedFormats = lstAllowedMimeTypes;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /*
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * Check MIME compatibility with this client.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("Supported MIME types:\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync for (size_t i = 0; i < lstFormats.size(); i++)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync bool fSupported = lstAllowedFormats.contains(lstFormats.at(i));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (fSupported)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync this->lstFormats.append(lstFormats.at(i));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("\t%s: %RTbool\n", lstFormats.at(i).c_str(), fSupported));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /*
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * Prepare the startup info for DoDragDrop().
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync try
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Translate our drop actions into
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * 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 /*
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * Prepare the proxy window.
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RECT r;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RT_ZERO(r);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync HDC hDC = GetDC(NULL);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync BOOL fRc = EnumDisplayMonitors(hDC, NULL, VBoxDnDWnd::MonitorEnumProc, (LPARAM)&r);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (!fRc)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = VERR_NOT_FOUND;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync ReleaseDC(NULL, hDC);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_FAILURE(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* If multi-monitor enumeration failed above, try getting at least the
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * primary monitor as a fallback. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync MONITORINFO monitor_info;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync monitor_info.cbSize = sizeof(monitor_info);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (GetMonitorInfo(MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST),
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync &monitor_info))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync r = monitor_info.rcMonitor;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync SetWindowPos(hWnd, HWND_TOPMOST,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync r.left,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync r.top,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync r.right - r.left,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync r.bottom - r.top,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifdef VBOX_DND_DEBUG_WND
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync SWP_SHOWWINDOW);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#else
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync SWP_SHOWWINDOW | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOACTIVATE);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("Virtual screen is %ld,%ld,%ld,%ld (%ld x %ld)\n",
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync r.left, r.top, r.right, r.bottom,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync r.right - r.left, r.bottom - r.top));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync else
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogRel(("DnD: Failed to determine virtual screen size, rc=%Rrc\n", rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFuncLeaveRC(rc);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::OnHgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t uAction)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("u32xPos=%RU32, u32yPos=%RU32, uAction=0x%x\n",
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync u32xPos, u32yPos, uAction));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** @todo Multi-monitor setups? */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int iScreenX = GetSystemMetrics(SM_CXSCREEN) - 1;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int iScreenY = GetSystemMetrics(SM_CYSCREEN) - 1;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync INPUT Input[1] = { 0 };
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Input[0].type = INPUT_MOUSE;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Input[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Input[0].mi.dx = u32xPos * (65535 / iScreenX);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Input[0].mi.dy = u32yPos * (65535 / iScreenY);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync SendInput(1, Input, sizeof(INPUT));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifdef DEBUG
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync POINT p;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync GetCursorPos(&p);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("curX=%d, cury=%d\n", p.x, p.y));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync uint32_t uActionNotify = DND_IGNORE_ACTION;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = RTCritSectEnter(&mCritSect);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if ( (Dragging == mState)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync && startupInfo.pDropSource)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync uActionNotify = startupInfo.pDropSource->GetCurrentAction();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCritSectLeave(&mCritSect);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = VbglR3DnDHGAcknowledgeOperation(mClientID, uActionNotify);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_FAILURE(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("Acknowleding 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
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::OnHgLeave(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("mMode=%RU32, mState=%RU32\n", mMode, mState));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogRel(("DnD: Drag'n drop operation aborted\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync reset();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Post ESC to our window to officially abort the
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * drag'n drop operation. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync PostMessage(hWnd, WM_KEYDOWN, VK_ESCAPE, 0 /* lParam */);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFuncLeaveRC(rc);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::OnHgDrop(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("mMode=%RU32, mState=%RU32\n", mMode, mState));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc = VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (mState == Dragging)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync Assert(lstFormats.size() >= 1);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /** @todo What to do when multiple formats are available? */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync mFormatRequested = lstFormats.at(0);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = RTCritSectEnter(&mCritSect);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (startupInfo.pDataObject)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync startupInfo.pDataObject->SetStatus(VBoxDnDDataObject::Dropping);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync else
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = VERR_NOT_FOUND;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync RTCritSectLeave(&mCritSect);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogRel(("DnD: Requesting data as '%s' ...\n", mFormatRequested.c_str()));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = VbglR3DnDHGRequestData(mClientID, mFormatRequested.c_str());
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_FAILURE(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("Requesting data failed with rc=%Rrc\n", rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFuncLeaveRC(rc);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
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
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc2 = DragRelease();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = rc2;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFuncLeaveRC(rc);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
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
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync int rc2 = DragRelease();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = rc2;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#ifdef VBOX_WITH_DRAG_AND_DROP_GH
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::OnGhIsDnDPending(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return 0;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::OnGhDropped(const RTCString &strFormat, uint32_t action)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return 0;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncint VBoxDnDWnd::ProcessEvent(PVBOXDNDEVENT pEvent)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync PostMessage(hWnd, WM_VBOXTRAY_DND_MESSAGE,
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync 0 /* wParm */, (LPARAM)pEvent /* lParm */);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncvoid VBoxDnDWnd::reset(void)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync{
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowThisFunc(("mState=%ld\n", mState));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync lstAllowedFormats.clear();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync lstFormats.clear();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync uAllActions = DND_IGNORE_ACTION;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncstatic LRESULT CALLBACK vboxDnDWndProcInstance(HWND hWnd, UINT uMsg, 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
81f46059436c6145937a4cc2c7424023a289fcd8vboxsyncstatic LRESULT CALLBACK vboxDnDWndProc(HWND hWnd, UINT uMsg, 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/**
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * Initializes drag'n 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;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Create the proxy window. At the moment we
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync * only support one window at a time. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VBoxDnDWnd *pWnd = NULL;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync try
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync pWnd = new VBoxDnDWnd();
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = pWnd->Initialize(pCtx);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Add proxy window to our proxy windows list. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync pCtx->lstWnd.append(pWnd);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync catch (std::bad_alloc)
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = VERR_NO_MEMORY;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync rc = RTSemEventCreate(&pCtx->hEvtQueueSem);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync /* Assign service environment to our context. */
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync gCtx.pEnv = pEnv;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync *ppInstance = pCtx;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync *pfStartThread = true;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogRel(("DnD: Drag'n drop service successfully started\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return VINF_SUCCESS;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogRel(("DnD: Initializing drag'n 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 /** @todo Notify / wait for HGCM thread! */
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
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
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);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("VbglR3DnDProcessNextMessage returned rc=%Rrc\n", rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (ASMAtomicReadBool(&pCtx->fShutdown))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (RT_SUCCESS(rc))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync {
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));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync }
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync else
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("Processing next message failed with rc=%Rrc\n", rc));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync if (ASMAtomicReadBool(&pCtx->fShutdown))
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync break;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync } while (true);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFunc(("Shutting down ...\n"));
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync VbglR3DnDDisconnect(uClientID);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync LogFlowFuncLeaveRC(rc);
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync return rc;
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync}
81f46059436c6145937a4cc2c7424023a289fcd8vboxsync