15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/web_contents/web_drag_dest_win.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shlobj.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/win_util.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_view_host_impl.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/web_contents/web_drag_utils_win.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_drag_dest_delegate.h"
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/common/drop_data.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/clipboard/clipboard_util_win.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/dragdrop/os_exchange_data.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/dragdrop/os_exchange_data_provider_win.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/window_open_disposition.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/point.h"
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebDragOperationNone;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebDragOperationCopy;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebDragOperationLink;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebDragOperationMove;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebDragOperationGeneric;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned short kHighBitMaskShort = 0x8000;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A helper method for getting the preferred drop effect.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD GetPreferredDropEffect(DWORD effect) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (effect & DROPEFFECT_COPY)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return DROPEFFECT_COPY;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (effect & DROPEFFECT_LINK)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return DROPEFFECT_LINK;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (effect & DROPEFFECT_MOVE)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return DROPEFFECT_MOVE;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return DROPEFFECT_NONE;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetModifierFlags() {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int modifier_state = 0;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::win::IsShiftPressed())
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    modifier_state |= WebKit::WebInputEvent::ShiftKey;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::win::IsCtrlPressed())
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    modifier_state |= WebKit::WebInputEvent::ControlKey;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::win::IsAltPressed())
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    modifier_state |= WebKit::WebInputEvent::AltKey;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (::GetKeyState(VK_LWIN) & kHighBitMaskShort)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    modifier_state |= WebKit::WebInputEvent::MetaKey;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (::GetKeyState(VK_RWIN) & kHighBitMaskShort)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    modifier_state |= WebKit::WebInputEvent::MetaKey;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return modifier_state;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Helper method for converting Window's specific IDataObject to a DropData
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// object.
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid PopulateDropData(IDataObject* data_object, DropData* drop_data) {
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::string16 url_str;
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (ui::ClipboardUtil::GetUrl(
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          data_object, &url_str, &drop_data->url_title, false)) {
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    GURL test_url(url_str);
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (test_url.is_valid())
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      drop_data->url = test_url;
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::vector<base::string16> filenames;
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui::ClipboardUtil::GetFilenames(data_object, &filenames);
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0; i < filenames.size(); ++i)
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    drop_data->filenames.push_back(
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        DropData::FileInfo(filenames[i], base::string16()));
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::string16 text;
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui::ClipboardUtil::GetPlainText(data_object, &text);
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!text.empty()) {
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    drop_data->text = base::NullableString16(text, false);
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::string16 html;
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string html_base_url;
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui::ClipboardUtil::GetHtml(data_object, &html, &html_base_url);
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!html.empty()) {
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    drop_data->html = base::NullableString16(html, false);
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!html_base_url.empty()) {
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    drop_data->html_base_url = GURL(html_base_url);
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui::ClipboardUtil::GetWebCustomData(data_object, &drop_data->custom_data);
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// InterstitialDropTarget is like a ui::DropTargetWin implementation that
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WebDragDest passes through to if an interstitial is showing.  Rather than
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// passing messages on to the renderer, we just check to see if there's a link
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the drop data and handle links as navigations.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class InterstitialDropTarget {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit InterstitialDropTarget(WebContents* web_contents)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : web_contents_(web_contents) {}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD OnDragEnter(IDataObject* data_object, DWORD effect) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ui::ClipboardUtil::HasUrl(data_object) ?
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetPreferredDropEffect(effect) : DROPEFFECT_NONE;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD OnDragOver(IDataObject* data_object, DWORD effect) {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ui::ClipboardUtil::HasUrl(data_object) ?
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetPreferredDropEffect(effect) : DROPEFFECT_NONE;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnDragLeave(IDataObject* data_object) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD OnDrop(IDataObject* data_object, DWORD effect) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ui::ClipboardUtil::HasUrl(data_object))
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return DROPEFFECT_NONE;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::wstring url;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::wstring title;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ClipboardUtil::GetUrl(data_object, &url, &title, true);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OpenURLParams params(GURL(url), Referrer(), CURRENT_TAB,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         PAGE_TRANSITION_AUTO_BOOKMARK, false);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_contents_->OpenURL(params);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetPreferredDropEffect(effect);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebContents* web_contents_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(InterstitialDropTarget);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebDragDest::WebDragDest(HWND source_hwnd, WebContents* web_contents)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : ui::DropTargetWin(source_hwnd),
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_contents_(web_contents),
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_rvh_(NULL),
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      drag_cursor_(WebDragOperationNone),
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      interstitial_drop_target_(new InterstitialDropTarget(web_contents)),
1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      delegate_(NULL),
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      canceled_(false) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebDragDest::~WebDragDest() {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD WebDragDest::OnDragEnter(IDataObject* data_object,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               DWORD key_state,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               POINT cursor_position,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               DWORD effects) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_rvh_ = web_contents_->GetRenderViewHost();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(tc): PopulateDropData can be slow depending on what is in the
1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // IDataObject.  Maybe we can do this in a background thread.
159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<DropData> drop_data;
160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  drop_data.reset(new DropData());
161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PopulateDropData(data_object, drop_data.get());
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (drop_data->url.is_empty())
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ui::OSExchangeDataProviderWin::GetPlainTextURL(data_object,
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                                   &drop_data->url);
1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Give the delegate an opportunity to cancel the drag.
1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  canceled_ = !web_contents_->GetDelegate()->CanDragEnter(
1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      web_contents_,
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      *drop_data,
1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      WinDragOpMaskToWebDragOpMask(effects));
1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (canceled_)
1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return DROPEFFECT_NONE;
1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->DragInitialize(web_contents_);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't pass messages to the renderer if an interstitial page is showing
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because we don't want the interstitial page to navigate.  Instead,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pass the messages on to a separate interstitial DropTarget handler.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents_->ShowingInterstitialPage())
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return interstitial_drop_target_->OnDragEnter(data_object, effects);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  drop_data_.swap(drop_data);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  drag_cursor_ = WebDragOperationNone;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  POINT client_pt = cursor_position;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScreenToClient(GetHWND(), &client_pt);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_contents_->GetRenderViewHost()->DragTargetDragEnter(*drop_data_,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Point(client_pt.x, client_pt.y),
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Point(cursor_position.x, cursor_position.y),
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WinDragOpMaskToWebDragOpMask(effects),
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetModifierFlags());
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->OnDragEnter(data_object);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We lie here and always return a DROPEFFECT because we don't want to
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // wait for the IPC call to return.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return WebDragOpToWinDragOp(drag_cursor_);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD WebDragDest::OnDragOver(IDataObject* data_object,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              DWORD key_state,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              POINT cursor_position,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              DWORD effects) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(current_rvh_);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (current_rvh_ != web_contents_->GetRenderViewHost())
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnDragEnter(data_object, key_state, cursor_position, effects);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (canceled_)
2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return DROPEFFECT_NONE;
2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents_->ShowingInterstitialPage())
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return interstitial_drop_target_->OnDragOver(data_object, effects);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  POINT client_pt = cursor_position;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScreenToClient(GetHWND(), &client_pt);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_contents_->GetRenderViewHost()->DragTargetDragOver(
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Point(client_pt.x, client_pt.y),
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Point(cursor_position.x, cursor_position.y),
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WinDragOpMaskToWebDragOpMask(effects),
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetModifierFlags());
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnDragOver(data_object);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return WebDragOpToWinDragOp(drag_cursor_);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebDragDest::OnDragLeave(IDataObject* data_object) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(current_rvh_);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (current_rvh_ != web_contents_->GetRenderViewHost())
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (canceled_)
2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents_->ShowingInterstitialPage()) {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    interstitial_drop_target_->OnDragLeave(data_object);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_contents_->GetRenderViewHost()->DragTargetDragLeave();
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnDragLeave(data_object);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  drop_data_.reset();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD WebDragDest::OnDrop(IDataObject* data_object,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          DWORD key_state,
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          POINT cursor_position,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          DWORD effect) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(current_rvh_);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (current_rvh_ != web_contents_->GetRenderViewHost())
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnDragEnter(data_object, key_state, cursor_position, effect);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents_->ShowingInterstitialPage())
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    interstitial_drop_target_->OnDragOver(data_object, effect);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents_->ShowingInterstitialPage())
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return interstitial_drop_target_->OnDrop(data_object, effect);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  POINT client_pt = cursor_position;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScreenToClient(GetHWND(), &client_pt);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_contents_->GetRenderViewHost()->DragTargetDrop(
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Point(client_pt.x, client_pt.y),
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Point(cursor_position.x, cursor_position.y),
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetModifierFlags());
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnDrop(data_object);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_rvh_ = NULL;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This isn't always correct, but at least it's a close approximation.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For now, we always map a move to a copy to prevent potential data loss.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD drop_effect = WebDragOpToWinDragOp(drag_cursor_);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD result = drop_effect != DROPEFFECT_MOVE ? drop_effect : DROPEFFECT_COPY;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  drop_data_.reset();
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
287