18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebDragClient.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebDropSource.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebKitGraphics.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebView.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <shlobj.h> 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/ClipboardWin.h> 35231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <WebCore/DragController.h> 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/DragData.h> 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/FrameView.h> 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/GraphicsContext.h> 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/Page.h> 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WebCore; 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic DWORD draggingSourceOperationMaskToDragCursors(DragOperation op) 44231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 45231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block DWORD result = DROPEFFECT_NONE; 46231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (op == DragOperationEvery) 47231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return DROPEFFECT_COPY | DROPEFFECT_LINK | DROPEFFECT_MOVE; 48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (op & DragOperationCopy) 49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block result |= DROPEFFECT_COPY; 50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (op & DragOperationLink) 51231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block result |= DROPEFFECT_LINK; 52231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (op & DragOperationMove) 53231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block result |= DROPEFFECT_MOVE; 54231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (op & DragOperationGeneric) 55231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block result |= DROPEFFECT_MOVE; 56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return result; 57231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 58231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectWebDragClient::WebDragClient(WebView* webView) 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project : m_webView(webView) 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(webView); 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectDragDestinationAction WebDragClient::actionMaskForDrag(DragData* dragData) 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project COMPtr<IWebUIDelegate> delegateRef = 0; 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project //Default behaviour (eg. no delegate, or callback not implemented) is to allow 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project //any action 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebDragDestinationAction mask = WebDragDestinationActionAny; 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (SUCCEEDED(m_webView->uiDelegate(&delegateRef))) 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delegateRef->dragDestinationActionMaskForDraggingInfo(m_webView, dragData->platformData(), &mask); 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (DragDestinationAction)mask; 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebDragClient::willPerformDragDestinationAction(DragDestinationAction action, DragData* dragData) 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project //Default delegate for willPerformDragDestinationAction has no side effects 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project //so we just call the delegate, and don't worry about whether it's implemented 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project COMPtr<IWebUIDelegate> delegateRef = 0; 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (SUCCEEDED(m_webView->uiDelegate(&delegateRef))) 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delegateRef->willPerformDragDestinationAction(m_webView, (WebDragDestinationAction)action, dragData->platformData()); 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectDragSourceAction WebDragClient::dragSourceActionMaskForPoint(const IntPoint& windowPoint) 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project COMPtr<IWebUIDelegate> delegateRef = 0; 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebDragSourceAction action = WebDragSourceActionAny; 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project POINT localpt = core(m_webView)->mainFrame()->view()->windowToContents(windowPoint); 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (SUCCEEDED(m_webView->uiDelegate(&delegateRef))) 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delegateRef->dragSourceActionMaskForPoint(m_webView, &localpt, &action); 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (DragSourceAction)action; 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid WebDragClient::willPerformDragSourceAction(DragSourceAction action, const IntPoint& intPoint, Clipboard* clipboard) 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch COMPtr<IWebUIDelegate> uiDelegate; 990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!SUCCEEDED(m_webView->uiDelegate(&uiDelegate))) 1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return; 1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch POINT point = intPoint; 1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch COMPtr<IDataObject> dataObject = static_cast<ClipboardWin*>(clipboard)->dataObject(); 1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch COMPtr<IDataObject> newDataObject; 1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch HRESULT result = uiDelegate->willPerformDragSourceAction(m_webView, static_cast<WebDragSourceAction>(action), &point, dataObject.get(), &newDataObject); 1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (result == S_OK && newDataObject != dataObject) 1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static_cast<ClipboardWin*>(clipboard)->setExternalDataObject(newDataObject.get()); 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebDragClient::startDrag(DragImageRef image, const IntPoint& imageOrigin, const IntPoint& dragPoint, Clipboard* clipboard, Frame* frame, bool isLink) 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project //FIXME: Allow UIDelegate to override behaviour <rdar://problem/5015953> 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project //We liberally protect everything, to protect against a load occurring mid-drag 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<Frame> frameProtector = frame; 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project COMPtr<IDragSourceHelper> helper; 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project COMPtr<IDataObject> dataObject; 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project COMPtr<WebView> viewProtector = m_webView; 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project COMPtr<IDropSource> source; 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(WebDropSource::createInstance(m_webView, &source))) 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dataObject = static_cast<ClipboardWin*>(clipboard)->dataObject(); 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (source && (image || dataObject)) { 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (image) { 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if(SUCCEEDED(CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IID_IDragSourceHelper,(LPVOID*)&helper))) { 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project BITMAP b; 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project GetObject(image, sizeof(BITMAP), &b); 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SHDRAGIMAGE sdi; 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sdi.sizeDragImage.cx = b.bmWidth; 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sdi.sizeDragImage.cy = b.bmHeight; 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sdi.crColorKey = 0xffffffff; 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sdi.hbmpDragImage = image; 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sdi.ptOffset.x = dragPoint.x() - imageOrigin.x(); 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sdi.ptOffset.y = dragPoint.y() - imageOrigin.y(); 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isLink) 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sdi.ptOffset.y = b.bmHeight - sdi.ptOffset.y; 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project helper->InitializeFromBitmap(&sdi, dataObject.get()); 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 145231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block DWORD okEffect = draggingSourceOperationMaskToDragCursors(m_webView->page()->dragController()->sourceDragOperation()); 146cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block DWORD effect = DROPEFFECT_NONE; 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project COMPtr<IWebUIDelegate> ui; 148cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block HRESULT hr = E_NOTIMPL; 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (SUCCEEDED(m_webView->uiDelegate(&ui))) { 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project COMPtr<IWebUIDelegatePrivate> uiPrivate; 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegatePrivate, (void**)&uiPrivate))) 152cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block hr = uiPrivate->doDragDrop(m_webView, dataObject.get(), source.get(), okEffect, &effect); 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 154cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (hr == E_NOTIMPL) 155cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block hr = DoDragDrop(dataObject.get(), source.get(), okEffect, &effect); 156cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 157cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block DragOperation operation = DragOperationNone; 158cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (hr == DRAGDROP_S_DROP) { 159cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (effect & DROPEFFECT_COPY) 160cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block operation = DragOperationCopy; 161cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block else if (effect & DROPEFFECT_LINK) 162cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block operation = DragOperationLink; 163cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block else if (effect & DROPEFFECT_MOVE) 164cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block operation = DragOperationMove; 165cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 166cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block frame->eventHandler()->dragSourceEndedAt(generateMouseEvent(m_webView, false), operation); 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebDragClient::dragControllerDestroyed() 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete this; 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 174