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 POINTL pt; 98 ::GetCursorPos((LPPOINT)&pt); 99 POINTL localpt = pt; 100 HWND viewWindow; 101 if (SUCCEEDED(webView->viewWindow((OLE_HANDLE*)&viewWindow))) 102 ::ScreenToClient(viewWindow, (LPPOINT)&localpt); 103 return PlatformMouseEvent(IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), 104 isDrag ? LeftButton : NoButton, MouseEventMoved, 0, false, false, false, false, currentTime()); 105} 106 107STDMETHODIMP WebDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) 108{ 109 if (fEscapePressed || !(grfKeyState & (MK_LBUTTON|MK_RBUTTON))) { 110 m_dropped = !fEscapePressed; 111 return fEscapePressed? DRAGDROP_S_CANCEL : DRAGDROP_S_DROP; 112 } 113 114 return S_OK; 115} 116 117STDMETHODIMP WebDropSource::GiveFeedback(DWORD dwEffect) 118{ 119 BOOL showCustomCursors; 120 if (FAILED(WebPreferences::sharedStandardPreferences()->customDragCursorsEnabled(&showCustomCursors))) 121 return DRAGDROP_S_USEDEFAULTCURSORS; 122 123 // If we don't want to hide the stop icon, let Windows select the cursor. 124 if (!showCustomCursors) 125 return DRAGDROP_S_USEDEFAULTCURSORS; 126 127 // If we are going to show something other than the not allowed arrow, then let Windows 128 // show the cursor. 129 if (dwEffect != DROPEFFECT_NONE) 130 return DRAGDROP_S_USEDEFAULTCURSORS; 131 132 HWND viewWindow; 133 if (FAILED(m_webView->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow)))) 134 return DRAGDROP_S_USEDEFAULTCURSORS; 135 136 RECT webViewRect; 137 GetWindowRect(viewWindow, &webViewRect); 138 139 POINT cursorPoint; 140 GetCursorPos(&cursorPoint); 141 142 if (!PtInRect(&webViewRect, cursorPoint)) { 143 // If our cursor is outside the bounds of the webView, we want to let Windows select the cursor. 144 return DRAGDROP_S_USEDEFAULTCURSORS; 145 } 146 147 FrameView* view = m_webView->page()->mainFrame()->view(); 148 if (!view) 149 return DRAGDROP_S_USEDEFAULTCURSORS; 150 151 // When dragging inside a WebView and the drag is not allowed, don't show the not allowed icon, 152 // instead, show the pointer cursor. 153 // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and drop (default to pointer). 154 view->setCursor(pointerCursor()); 155 return S_OK; 156} 157