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 43 using namespace WebCore; 44 45 46 HRESULT 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 54 WebDropSource::WebDropSource(WebView* webView) 55 : m_ref(1) 56 , m_dropped(false) 57 , m_webView(webView) 58 { 59 gClassCount++; 60 gClassNameCount.add("WebDropSource"); 61 } 62 63 WebDropSource::~WebDropSource() 64 { 65 gClassCount--; 66 gClassNameCount.remove("WebDropSource"); 67 } 68 69 STDMETHODIMP 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 83 STDMETHODIMP_(ULONG) WebDropSource::AddRef(void) 84 { 85 return InterlockedIncrement(&m_ref); 86 } 87 88 STDMETHODIMP_(ULONG) WebDropSource::Release(void) 89 { 90 long c = InterlockedDecrement(&m_ref); 91 if (c == 0) 92 delete this; 93 return c; 94 } 95 96 PlatformMouseEvent 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 107 STDMETHODIMP 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 117 STDMETHODIMP 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