172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/tab_contents/web_drop_target_win.h"
6731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <windows.h>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <shlobj.h>
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/bookmarks/bookmark_node_data.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/web_drag_utils_win.h"
12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h"
13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h"
1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/clipboard/clipboard_util_win.h"
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/dragdrop/os_exchange_data.h"
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/dragdrop/os_exchange_data_provider_win.h"
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/point.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/webdropdata.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/window_open_disposition.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebDragOperationNone;
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebDragOperationCopy;
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebDragOperationLink;
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebDragOperationMove;
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebDragOperationGeneric;
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A helper method for getting the preferred drop effect.
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDWORD GetPreferredDropEffect(DWORD effect) {
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (effect & DROPEFFECT_COPY)
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return DROPEFFECT_COPY;
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (effect & DROPEFFECT_LINK)
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return DROPEFFECT_LINK;
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (effect & DROPEFFECT_MOVE)
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return DROPEFFECT_MOVE;
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return DROPEFFECT_NONE;
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}  // namespace
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// InterstitialDropTarget is like a app::win::DropTarget implementation that
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// WebDropTarget passes through to if an interstitial is showing.  Rather than
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// passing messages on to the renderer, we just check to see if there's a link
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// in the drop data and handle links as navigations.
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass InterstitialDropTarget {
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit InterstitialDropTarget(TabContents* tab_contents)
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : tab_contents_(tab_contents) {}
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DWORD OnDragEnter(IDataObject* data_object, DWORD effect) {
5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return ui::ClipboardUtil::HasUrl(data_object) ?
5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        GetPreferredDropEffect(effect) : DROPEFFECT_NONE;
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DWORD OnDragOver(IDataObject* data_object, DWORD effect) {
5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return ui::ClipboardUtil::HasUrl(data_object) ?
6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        GetPreferredDropEffect(effect) : DROPEFFECT_NONE;
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnDragLeave(IDataObject* data_object) {
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DWORD OnDrop(IDataObject* data_object, DWORD effect) {
6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (ui::ClipboardUtil::HasUrl(data_object)) {
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::wstring url;
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::wstring title;
7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      ui::ClipboardUtil::GetUrl(data_object, &url, &title, true);
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab_contents_->OpenURL(GURL(url), GURL(), CURRENT_TAB,
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             PageTransition::AUTO_BOOKMARK);
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return GetPreferredDropEffect(effect);
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return DROPEFFECT_NONE;
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabContents* tab_contents_;
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(InterstitialDropTarget);
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebDropTarget::WebDropTarget(HWND source_hwnd, TabContents* tab_contents)
8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : ui::DropTarget(source_hwnd),
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab_contents_(tab_contents),
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      current_rvh_(NULL),
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      drag_cursor_(WebDragOperationNone),
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      interstitial_drop_target_(new InterstitialDropTarget(tab_contents)) {
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebDropTarget::~WebDropTarget() {
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDWORD WebDropTarget::OnDragEnter(IDataObject* data_object,
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 DWORD key_state,
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 POINT cursor_position,
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 DWORD effects) {
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_rvh_ = tab_contents_->render_view_host();
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't pass messages to the renderer if an interstitial page is showing
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // because we don't want the interstitial page to navigate.  Instead,
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // pass the messages on to a separate interstitial DropTarget handler.
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents_->showing_interstitial_page())
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return interstitial_drop_target_->OnDragEnter(data_object, effects);
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(tc): PopulateWebDropData can be slow depending on what is in the
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // IDataObject.  Maybe we can do this in a background thread.
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WebDropData drop_data;
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebDropData::PopulateWebDropData(data_object, &drop_data);
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (drop_data.url.is_empty())
11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ui::OSExchangeDataProviderWin::GetPlainTextURL(data_object, &drop_data.url);
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  drag_cursor_ = WebDragOperationNone;
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  POINT client_pt = cursor_position;
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScreenToClient(GetHWND(), &client_pt);
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tab_contents_->render_view_host()->DragTargetDragEnter(drop_data,
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      gfx::Point(client_pt.x, client_pt.y),
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      gfx::Point(cursor_position.x, cursor_position.y),
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      web_drag_utils_win::WinDragOpMaskToWebDragOpMask(effects));
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // This is non-null if tab_contents_ is showing an ExtensionWebUI with
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // support for (at the moment experimental) drag and drop extensions.
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents_->GetBookmarkDragDelegate()) {
12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ui::OSExchangeData os_exchange_data(
12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        new ui::OSExchangeDataProviderWin(data_object));
129201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    BookmarkNodeData bookmark_drag_data;
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (bookmark_drag_data.Read(os_exchange_data))
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab_contents_->GetBookmarkDragDelegate()->OnDragEnter(bookmark_drag_data);
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We lie here and always return a DROPEFFECT because we don't want to
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // wait for the IPC call to return.
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return web_drag_utils_win::WebDragOpToWinDragOp(drag_cursor_);
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDWORD WebDropTarget::OnDragOver(IDataObject* data_object,
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                DWORD key_state,
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                POINT cursor_position,
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                DWORD effects) {
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(current_rvh_);
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (current_rvh_ != tab_contents_->render_view_host())
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    OnDragEnter(data_object, key_state, cursor_position, effects);
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents_->showing_interstitial_page())
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return interstitial_drop_target_->OnDragOver(data_object, effects);
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  POINT client_pt = cursor_position;
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScreenToClient(GetHWND(), &client_pt);
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tab_contents_->render_view_host()->DragTargetDragOver(
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      gfx::Point(client_pt.x, client_pt.y),
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      gfx::Point(cursor_position.x, cursor_position.y),
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      web_drag_utils_win::WinDragOpMaskToWebDragOpMask(effects));
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents_->GetBookmarkDragDelegate()) {
15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ui::OSExchangeData os_exchange_data(
15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        new ui::OSExchangeDataProviderWin(data_object));
160201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    BookmarkNodeData bookmark_drag_data;
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (bookmark_drag_data.Read(os_exchange_data))
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab_contents_->GetBookmarkDragDelegate()->OnDragOver(bookmark_drag_data);
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return web_drag_utils_win::WebDragOpToWinDragOp(drag_cursor_);
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebDropTarget::OnDragLeave(IDataObject* data_object) {
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(current_rvh_);
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (current_rvh_ != tab_contents_->render_view_host())
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents_->showing_interstitial_page()) {
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    interstitial_drop_target_->OnDragLeave(data_object);
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tab_contents_->render_view_host()->DragTargetDragLeave();
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents_->GetBookmarkDragDelegate()) {
18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ui::OSExchangeData os_exchange_data(
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        new ui::OSExchangeDataProviderWin(data_object));
182201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    BookmarkNodeData bookmark_drag_data;
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (bookmark_drag_data.Read(os_exchange_data))
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab_contents_->GetBookmarkDragDelegate()->OnDragLeave(bookmark_drag_data);
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDWORD WebDropTarget::OnDrop(IDataObject* data_object,
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            DWORD key_state,
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            POINT cursor_position,
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            DWORD effect) {
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(current_rvh_);
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (current_rvh_ != tab_contents_->render_view_host())
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    OnDragEnter(data_object, key_state, cursor_position, effect);
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents_->showing_interstitial_page())
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    interstitial_drop_target_->OnDragOver(data_object, effect);
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents_->showing_interstitial_page())
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return interstitial_drop_target_->OnDrop(data_object, effect);
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  POINT client_pt = cursor_position;
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScreenToClient(GetHWND(), &client_pt);
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tab_contents_->render_view_host()->DragTargetDrop(
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      gfx::Point(client_pt.x, client_pt.y),
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      gfx::Point(cursor_position.x, cursor_position.y));
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents_->GetBookmarkDragDelegate()) {
20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ui::OSExchangeData os_exchange_data(
21072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        new ui::OSExchangeDataProviderWin(data_object));
211201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    BookmarkNodeData bookmark_drag_data;
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (bookmark_drag_data.Read(os_exchange_data))
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab_contents_->GetBookmarkDragDelegate()->OnDrop(bookmark_drag_data);
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_rvh_ = NULL;
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This isn't always correct, but at least it's a close approximation.
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For now, we always map a move to a copy to prevent potential data loss.
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DWORD drop_effect = web_drag_utils_win::WebDragOpToWinDragOp(drag_cursor_);
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return drop_effect != DROPEFFECT_MOVE ? drop_effect : DROPEFFECT_COPY;
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
223