1/* 2 * Copyright (C) 2007 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "WebDropSource.h" 28 29#include "WebKitDLL.h" 30#include "WebView.h" 31 32#include <WebCore/Cursor.h> 33#include <WebCore/DragActions.h> 34#include <WebCore/EventHandler.h> 35#include <WebCore/Frame.h> 36#include <WebCore/FrameView.h> 37#include <WebCore/Page.h> 38#include <WebCore/PlatformMouseEvent.h> 39#include <wtf/CurrentTime.h> 40 41#include <Windows.h> 42 43using namespace WebCore; 44 45 46HRESULT WebDropSource::createInstance(WebView* webView, IDropSource** result) 47{ 48 if (!webView || !result) 49 return E_INVALIDARG; 50 *result = new WebDropSource(webView); 51 return S_OK; 52} 53 54WebDropSource::WebDropSource(WebView* webView) 55: m_ref(1) 56, m_dropped(false) 57, m_webView(webView) 58{ 59 gClassCount++; 60 gClassNameCount.add("WebDropSource"); 61} 62 63WebDropSource::~WebDropSource() 64{ 65 gClassCount--; 66 gClassNameCount.remove("WebDropSource"); 67} 68 69STDMETHODIMP WebDropSource::QueryInterface(REFIID riid, void** ppvObject) 70{ 71 *ppvObject = 0; 72 if (IsEqualIID(riid, IID_IUnknown) || 73 IsEqualIID(riid, IID_IDropSource)) { 74 *ppvObject = this; 75 AddRef(); 76 77 return S_OK; 78 } 79 80 return E_NOINTERFACE; 81} 82 83STDMETHODIMP_(ULONG) WebDropSource::AddRef(void) 84{ 85 return InterlockedIncrement(&m_ref); 86} 87 88STDMETHODIMP_(ULONG) WebDropSource::Release(void) 89{ 90 long c = InterlockedDecrement(&m_ref); 91 if (c == 0) 92 delete this; 93 return c; 94} 95 96PlatformMouseEvent generateMouseEvent(WebView* webView, bool isDrag) 97{ 98 POINTL pt; 99 ::GetCursorPos((LPPOINT)&pt); 100 POINTL localpt = pt; 101 HWND viewWindow; 102 if (SUCCEEDED(webView->viewWindow((OLE_HANDLE*)&viewWindow))) 103 ::ScreenToClient(viewWindow, (LPPOINT)&localpt); 104 return PlatformMouseEvent(IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), 105 isDrag ? LeftButton : NoButton, PlatformEvent::MouseMoved, 0, false, false, false, false, currentTime()); 106} 107 108STDMETHODIMP WebDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) 109{ 110 if (fEscapePressed || !(grfKeyState & (MK_LBUTTON|MK_RBUTTON))) { 111 m_dropped = !fEscapePressed; 112 return fEscapePressed? DRAGDROP_S_CANCEL : DRAGDROP_S_DROP; 113 } 114 115 return S_OK; 116} 117 118STDMETHODIMP WebDropSource::GiveFeedback(DWORD dwEffect) 119{ 120 BOOL showCustomCursors; 121 if (FAILED(WebPreferences::sharedStandardPreferences()->customDragCursorsEnabled(&showCustomCursors))) 122 return DRAGDROP_S_USEDEFAULTCURSORS; 123 124 // If we don't want to hide the stop icon, let Windows select the cursor. 125 if (!showCustomCursors) 126 return DRAGDROP_S_USEDEFAULTCURSORS; 127 128 // If we are going to show something other than the not allowed arrow, then let Windows 129 // show the cursor. 130 if (dwEffect != DROPEFFECT_NONE) 131 return DRAGDROP_S_USEDEFAULTCURSORS; 132 133 HWND viewWindow; 134 if (FAILED(m_webView->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow)))) 135 return DRAGDROP_S_USEDEFAULTCURSORS; 136 137 RECT webViewRect; 138 GetWindowRect(viewWindow, &webViewRect); 139 140 POINT cursorPoint; 141 GetCursorPos(&cursorPoint); 142 143 if (!PtInRect(&webViewRect, cursorPoint)) { 144 // If our cursor is outside the bounds of the webView, we want to let Windows select the cursor. 145 return DRAGDROP_S_USEDEFAULTCURSORS; 146 } 147 148 FrameView* view = m_webView->page()->mainFrame()->view(); 149 if (!view) 150 return DRAGDROP_S_USEDEFAULTCURSORS; 151 152 // When dragging inside a WebView and the drag is not allowed, don't show the not allowed icon, 153 // instead, show the pointer cursor. 154 // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and drop (default to pointer). 155 view->setCursor(pointerCursor()); 156 return S_OK; 157} 158