OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" | 5 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/message_pump_aurax11.h" | 8 #include "base/message_pump_aurax11.h" |
9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
11 #include "net/base/net_util.h" | 11 #include "net/base/net_util.h" |
12 #include "ui/base/clipboard/clipboard.h" | 12 #include "ui/base/clipboard/clipboard.h" |
13 #include "ui/base/clipboard/scoped_clipboard_writer.h" | 13 #include "ui/base/clipboard/scoped_clipboard_writer.h" |
14 #include "ui/base/dragdrop/desktop_selection_provider_aurax11.h" | |
15 #include "ui/base/x/selection_utils.h" | 14 #include "ui/base/x/selection_utils.h" |
16 #include "ui/base/x/x11_util.h" | 15 #include "ui/base/x/x11_util.h" |
17 | 16 |
18 // Note: the GetBlah() methods are used immediately by the | 17 // Note: the GetBlah() methods are used immediately by the |
19 // web_contents_view_aura.cc:PrepareWebDropData(), while the omnibox is a | 18 // web_contents_view_aura.cc:PrepareWebDropData(), while the omnibox is a |
20 // little more discriminating and calls HasBlah() before trying to get the | 19 // little more discriminating and calls HasBlah() before trying to get the |
21 // information. | 20 // information. |
22 | 21 |
23 namespace ui { | 22 namespace ui { |
24 | 23 |
25 namespace { | 24 namespace { |
26 | 25 |
27 const char kDndSelection[] = "XdndSelection"; | 26 const char kDndSelection[] = "XdndSelection"; |
28 | 27 |
29 const char* kAtomsToCache[] = { | 28 const char* kAtomsToCache[] = { |
30 kString, | 29 kString, |
31 kText, | 30 kText, |
32 kUtf8String, | 31 kUtf8String, |
33 kDndSelection, | 32 kDndSelection, |
34 Clipboard::kMimeTypeURIList, | 33 Clipboard::kMimeTypeURIList, |
35 kMimeTypeMozillaURL, | 34 kMimeTypeMozillaURL, |
| 35 Clipboard::kMimeTypeText, |
36 NULL | 36 NULL |
37 }; | 37 }; |
38 | 38 |
39 } // namespace | 39 } // namespace |
40 | 40 |
41 OSExchangeDataProviderAuraX11::OSExchangeDataProviderAuraX11( | 41 OSExchangeDataProviderAuraX11::OSExchangeDataProviderAuraX11( |
42 ui::DesktopSelectionProviderAuraX11* provider, | |
43 ::Window x_window, | 42 ::Window x_window, |
44 const std::vector< ::Atom> targets) | 43 scoped_ptr<SelectionFormatMap> selection) |
45 : x_display_(GetXDisplay()), | 44 : x_display_(GetXDisplay()), |
46 x_root_window_(DefaultRootWindow(x_display_)), | 45 x_root_window_(DefaultRootWindow(x_display_)), |
47 own_window_(false), | 46 own_window_(false), |
48 selection_event_provider_(provider), | |
49 x_window_(x_window), | 47 x_window_(x_window), |
50 atom_cache_(x_display_, kAtomsToCache), | 48 atom_cache_(x_display_, kAtomsToCache), |
51 selection_requestor_(x_display_, x_window_, | 49 format_map_(selection.Pass()), |
52 atom_cache_.GetAtom(kDndSelection)), | |
53 selection_owner_(x_display_, x_window_, | 50 selection_owner_(x_display_, x_window_, |
54 atom_cache_.GetAtom(kDndSelection)), | 51 atom_cache_.GetAtom(kDndSelection)) { |
55 targets_(targets) { | |
56 // We don't know all possible MIME types at compile time. | 52 // We don't know all possible MIME types at compile time. |
57 atom_cache_.allow_uncached_atoms(); | 53 atom_cache_.allow_uncached_atoms(); |
58 | |
59 selection_event_provider_->SetDropHandler(this); | |
60 } | 54 } |
61 | 55 |
62 OSExchangeDataProviderAuraX11::OSExchangeDataProviderAuraX11() | 56 OSExchangeDataProviderAuraX11::OSExchangeDataProviderAuraX11() |
63 : x_display_(GetXDisplay()), | 57 : x_display_(GetXDisplay()), |
64 x_root_window_(DefaultRootWindow(x_display_)), | 58 x_root_window_(DefaultRootWindow(x_display_)), |
65 own_window_(true), | 59 own_window_(true), |
66 selection_event_provider_(NULL), | |
67 x_window_(XCreateWindow( | 60 x_window_(XCreateWindow( |
68 x_display_, | 61 x_display_, |
69 x_root_window_, | 62 x_root_window_, |
70 -100, -100, 10, 10, // x, y, width, height | 63 -100, -100, 10, 10, // x, y, width, height |
71 0, // border width | 64 0, // border width |
72 CopyFromParent, // depth | 65 CopyFromParent, // depth |
73 InputOnly, | 66 InputOnly, |
74 CopyFromParent, // visual | 67 CopyFromParent, // visual |
75 0, | 68 0, |
76 NULL)), | 69 NULL)), |
77 atom_cache_(x_display_, kAtomsToCache), | 70 atom_cache_(x_display_, kAtomsToCache), |
78 selection_requestor_(x_display_, x_window_, | 71 format_map_(new SelectionFormatMap), |
79 atom_cache_.GetAtom(kDndSelection)), | |
80 selection_owner_(x_display_, x_window_, | 72 selection_owner_(x_display_, x_window_, |
81 atom_cache_.GetAtom(kDndSelection)) { | 73 atom_cache_.GetAtom(kDndSelection)) { |
82 // We don't know all possible MIME types at compile time. | 74 // We don't know all possible MIME types at compile time. |
83 atom_cache_.allow_uncached_atoms(); | 75 atom_cache_.allow_uncached_atoms(); |
84 | 76 |
85 XStoreName(x_display_, x_window_, "Chromium Drag & Drop Window"); | 77 XStoreName(x_display_, x_window_, "Chromium Drag & Drop Window"); |
86 | 78 |
87 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, x_window_); | 79 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, x_window_); |
88 } | 80 } |
89 | 81 |
90 OSExchangeDataProviderAuraX11::~OSExchangeDataProviderAuraX11() { | 82 OSExchangeDataProviderAuraX11::~OSExchangeDataProviderAuraX11() { |
91 if (own_window_) { | 83 if (own_window_) { |
92 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(x_window_); | 84 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(x_window_); |
93 XDestroyWindow(x_display_, x_window_); | 85 XDestroyWindow(x_display_, x_window_); |
94 } else { | |
95 selection_event_provider_->SetDropHandler(NULL); | |
96 } | 86 } |
97 } | 87 } |
98 | 88 |
99 void OSExchangeDataProviderAuraX11::OnSelectionNotify( | 89 void OSExchangeDataProviderAuraX11::TakeOwnershipOfSelection() const { |
100 const XSelectionEvent& event) { | 90 selection_owner_.TakeOwnershipOfSelection( |
101 selection_requestor_.OnSelectionNotify(event); | 91 scoped_ptr<SelectionFormatMap>(format_map_->Clone())); |
102 } | 92 } |
103 | 93 |
104 void OSExchangeDataProviderAuraX11::SetString(const string16& data) { | 94 void OSExchangeDataProviderAuraX11::RetrieveTargets( |
105 NOTIMPLEMENTED(); | 95 std::vector<Atom>* targets) const { |
| 96 selection_owner_.RetrieveTargets(targets); |
| 97 } |
| 98 |
| 99 scoped_ptr<SelectionFormatMap> |
| 100 OSExchangeDataProviderAuraX11::CloneFormatMap() const { |
| 101 // We clone the |selection_owner_|'s format map instead of our own in case |
| 102 // ours has been modified since TakeOwnershipOfSelection() was called. |
| 103 return selection_owner_.selection_format_map()->Clone(); |
| 104 } |
| 105 |
| 106 void OSExchangeDataProviderAuraX11::SetString(const string16& text_data) { |
| 107 std::string utf8 = UTF16ToUTF8(text_data); |
| 108 |
| 109 // Ownership of |data| is passed to |format_map_|. |
| 110 size_t text_len = utf8.size(); |
| 111 char* data = new char[text_len]; |
| 112 memcpy(data, utf8.c_str(), text_len); |
| 113 |
| 114 format_map_->Insert( |
| 115 atom_cache_.GetAtom(Clipboard::kMimeTypeText), data, text_len); |
| 116 format_map_->Insert( |
| 117 atom_cache_.GetAtom(kText), data, text_len); |
| 118 format_map_->Insert( |
| 119 atom_cache_.GetAtom(kString), data, text_len); |
| 120 format_map_->Insert( |
| 121 atom_cache_.GetAtom(kUtf8String), data, text_len); |
106 } | 122 } |
107 | 123 |
108 void OSExchangeDataProviderAuraX11::SetURL(const GURL& url, | 124 void OSExchangeDataProviderAuraX11::SetURL(const GURL& url, |
109 const string16& title) { | 125 const string16& title) { |
110 NOTIMPLEMENTED(); | 126 NOTIMPLEMENTED(); |
111 } | 127 } |
112 | 128 |
113 void OSExchangeDataProviderAuraX11::SetFilename(const base::FilePath& path) { | 129 void OSExchangeDataProviderAuraX11::SetFilename(const base::FilePath& path) { |
114 NOTIMPLEMENTED(); | 130 NOTIMPLEMENTED(); |
115 } | 131 } |
116 | 132 |
117 void OSExchangeDataProviderAuraX11::SetFilenames( | 133 void OSExchangeDataProviderAuraX11::SetFilenames( |
118 const std::vector<OSExchangeData::FileInfo>& filenames) { | 134 const std::vector<OSExchangeData::FileInfo>& filenames) { |
119 NOTIMPLEMENTED(); | 135 NOTIMPLEMENTED(); |
120 } | 136 } |
121 | 137 |
122 void OSExchangeDataProviderAuraX11::SetPickledData( | 138 void OSExchangeDataProviderAuraX11::SetPickledData( |
123 const OSExchangeData::CustomFormat& format, | 139 const OSExchangeData::CustomFormat& format, |
124 const Pickle& data) { | 140 const Pickle& data) { |
125 NOTIMPLEMENTED(); | 141 NOTIMPLEMENTED(); |
126 } | 142 } |
127 | 143 |
128 bool OSExchangeDataProviderAuraX11::GetString(string16* result) const { | 144 bool OSExchangeDataProviderAuraX11::GetString(string16* result) const { |
129 std::vector< ::Atom> text_atoms = ui::GetTextAtomsFrom(&atom_cache_); | 145 std::vector< ::Atom> text_atoms = ui::GetTextAtomsFrom(&atom_cache_); |
130 std::vector< ::Atom> requested_types; | 146 std::vector< ::Atom> requested_types; |
131 ui::GetAtomIntersection(text_atoms, targets_, &requested_types); | 147 ui::GetAtomIntersection(text_atoms, GetTargets(), &requested_types); |
132 | 148 |
133 scoped_ptr<ui::SelectionData> data( | 149 scoped_ptr<ui::SelectionData> data(format_map_->GetFirstOf(requested_types)); |
134 selection_requestor_.RequestAndWaitForTypes(requested_types)); | |
135 if (data) { | 150 if (data) { |
136 std::string text = data->GetText(); | 151 std::string text = data->GetText(); |
137 *result = UTF8ToUTF16(text); | 152 *result = UTF8ToUTF16(text); |
138 return true; | 153 return true; |
139 } | 154 } |
140 | 155 |
141 return false; | 156 return false; |
142 } | 157 } |
143 | 158 |
144 bool OSExchangeDataProviderAuraX11::GetURLAndTitle(GURL* url, | 159 bool OSExchangeDataProviderAuraX11::GetURLAndTitle(GURL* url, |
145 string16* title) const { | 160 string16* title) const { |
146 std::vector< ::Atom> url_atoms = ui::GetURLAtomsFrom(&atom_cache_); | 161 std::vector< ::Atom> url_atoms = ui::GetURLAtomsFrom(&atom_cache_); |
147 std::vector< ::Atom> requested_types; | 162 std::vector< ::Atom> requested_types; |
148 ui::GetAtomIntersection(url_atoms, targets_, &requested_types); | 163 ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types); |
149 | 164 |
150 scoped_ptr<ui::SelectionData> data( | 165 scoped_ptr<ui::SelectionData> data(format_map_->GetFirstOf(requested_types)); |
151 selection_requestor_.RequestAndWaitForTypes(requested_types)); | |
152 if (data) { | 166 if (data) { |
153 // TODO(erg): Technically, both of these forms can accept multiple URLs, | 167 // TODO(erg): Technically, both of these forms can accept multiple URLs, |
154 // but that doesn't match the assumptions of the rest of the system which | 168 // but that doesn't match the assumptions of the rest of the system which |
155 // expect single types. | 169 // expect single types. |
156 | 170 |
157 if (data->type() == atom_cache_.GetAtom(kMimeTypeMozillaURL)) { | 171 if (data->type() == atom_cache_.GetAtom(kMimeTypeMozillaURL)) { |
158 // Mozilla URLs are (UTF16: URL, newline, title). | 172 // Mozilla URLs are (UTF16: URL, newline, title). |
159 string16 unparsed; | 173 string16 unparsed; |
160 data->AssignTo(&unparsed); | 174 data->AssignTo(&unparsed); |
161 | 175 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 bool OSExchangeDataProviderAuraX11::GetPickledData( | 220 bool OSExchangeDataProviderAuraX11::GetPickledData( |
207 const OSExchangeData::CustomFormat& format, | 221 const OSExchangeData::CustomFormat& format, |
208 Pickle* data) const { | 222 Pickle* data) const { |
209 NOTIMPLEMENTED(); | 223 NOTIMPLEMENTED(); |
210 return false; | 224 return false; |
211 } | 225 } |
212 | 226 |
213 bool OSExchangeDataProviderAuraX11::HasString() const { | 227 bool OSExchangeDataProviderAuraX11::HasString() const { |
214 std::vector< ::Atom> text_atoms = ui::GetTextAtomsFrom(&atom_cache_); | 228 std::vector< ::Atom> text_atoms = ui::GetTextAtomsFrom(&atom_cache_); |
215 std::vector< ::Atom> requested_types; | 229 std::vector< ::Atom> requested_types; |
216 ui::GetAtomIntersection(text_atoms, targets_, &requested_types); | 230 ui::GetAtomIntersection(text_atoms, GetTargets(), &requested_types); |
217 return !requested_types.empty(); | 231 return !requested_types.empty(); |
218 } | 232 } |
219 | 233 |
220 bool OSExchangeDataProviderAuraX11::HasURL() const { | 234 bool OSExchangeDataProviderAuraX11::HasURL() const { |
221 std::vector< ::Atom> url_atoms = ui::GetURLAtomsFrom(&atom_cache_); | 235 std::vector< ::Atom> url_atoms = ui::GetURLAtomsFrom(&atom_cache_); |
222 std::vector< ::Atom> requested_types; | 236 std::vector< ::Atom> requested_types; |
223 ui::GetAtomIntersection(url_atoms, targets_, &requested_types); | 237 ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types); |
224 return !requested_types.empty(); | 238 return !requested_types.empty(); |
225 } | 239 } |
226 | 240 |
227 bool OSExchangeDataProviderAuraX11::HasFile() const { | 241 bool OSExchangeDataProviderAuraX11::HasFile() const { |
228 // On X11, files are passed by URL and aren't separate. | 242 // On X11, files are passed by URL and aren't separate. |
229 return false; | 243 return false; |
230 } | 244 } |
231 | 245 |
232 bool OSExchangeDataProviderAuraX11::HasCustomFormat( | 246 bool OSExchangeDataProviderAuraX11::HasCustomFormat( |
233 const OSExchangeData::CustomFormat& format) const { | 247 const OSExchangeData::CustomFormat& format) const { |
234 std::vector< ::Atom> url_atoms; | 248 std::vector< ::Atom> url_atoms; |
235 url_atoms.push_back(atom_cache_.GetAtom(format.ToString().c_str())); | 249 url_atoms.push_back(atom_cache_.GetAtom(format.ToString().c_str())); |
236 std::vector< ::Atom> requested_types; | 250 std::vector< ::Atom> requested_types; |
237 ui::GetAtomIntersection(url_atoms, targets_, &requested_types); | 251 ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types); |
238 | 252 |
239 return !requested_types.empty(); | 253 return !requested_types.empty(); |
240 } | 254 } |
241 | 255 |
242 void OSExchangeDataProviderAuraX11::SetHtml(const string16& html, | 256 void OSExchangeDataProviderAuraX11::SetHtml(const string16& html, |
243 const GURL& base_url) { | 257 const GURL& base_url) { |
244 NOTIMPLEMENTED(); | 258 NOTIMPLEMENTED(); |
245 } | 259 } |
246 | 260 |
247 bool OSExchangeDataProviderAuraX11::GetHtml(string16* html, | 261 bool OSExchangeDataProviderAuraX11::GetHtml(string16* html, |
248 GURL* base_url) const { | 262 GURL* base_url) const { |
249 std::vector< ::Atom> url_atoms; | 263 std::vector< ::Atom> url_atoms; |
250 url_atoms.push_back(atom_cache_.GetAtom(Clipboard::kMimeTypeHTML)); | 264 url_atoms.push_back(atom_cache_.GetAtom(Clipboard::kMimeTypeHTML)); |
251 std::vector< ::Atom> requested_types; | 265 std::vector< ::Atom> requested_types; |
252 ui::GetAtomIntersection(url_atoms, targets_, &requested_types); | 266 ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types); |
253 | 267 |
254 scoped_ptr<ui::SelectionData> data( | 268 scoped_ptr<ui::SelectionData> data(format_map_->GetFirstOf(requested_types)); |
255 selection_requestor_.RequestAndWaitForTypes(requested_types)); | |
256 if (data) { | 269 if (data) { |
257 *html = data->GetHtml(); | 270 *html = data->GetHtml(); |
258 *base_url = GURL(); | 271 *base_url = GURL(); |
259 return true; | 272 return true; |
260 } | 273 } |
261 | 274 |
262 return false; | 275 return false; |
263 } | 276 } |
264 | 277 |
265 bool OSExchangeDataProviderAuraX11::HasHtml() const { | 278 bool OSExchangeDataProviderAuraX11::HasHtml() const { |
266 std::vector< ::Atom> url_atoms; | 279 std::vector< ::Atom> url_atoms; |
267 url_atoms.push_back(atom_cache_.GetAtom(Clipboard::kMimeTypeHTML)); | 280 url_atoms.push_back(atom_cache_.GetAtom(Clipboard::kMimeTypeHTML)); |
268 std::vector< ::Atom> requested_types; | 281 std::vector< ::Atom> requested_types; |
269 ui::GetAtomIntersection(url_atoms, targets_, &requested_types); | 282 ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types); |
270 | 283 |
271 return !requested_types.empty(); | 284 return !requested_types.empty(); |
272 } | 285 } |
273 | 286 |
274 void OSExchangeDataProviderAuraX11::SetDragImage( | 287 void OSExchangeDataProviderAuraX11::SetDragImage( |
275 const gfx::ImageSkia& image, | 288 const gfx::ImageSkia& image, |
276 const gfx::Vector2d& cursor_offset) { | 289 const gfx::Vector2d& cursor_offset) { |
277 NOTIMPLEMENTED(); | 290 drag_image_ = image; |
| 291 drag_image_offset_ = cursor_offset; |
278 } | 292 } |
279 | 293 |
280 const gfx::ImageSkia& OSExchangeDataProviderAuraX11::GetDragImage() const { | 294 const gfx::ImageSkia& OSExchangeDataProviderAuraX11::GetDragImage() const { |
281 NOTIMPLEMENTED(); | |
282 return drag_image_; | 295 return drag_image_; |
283 } | 296 } |
284 | 297 |
285 const gfx::Vector2d& OSExchangeDataProviderAuraX11::GetDragImageOffset() const { | 298 const gfx::Vector2d& OSExchangeDataProviderAuraX11::GetDragImageOffset() const { |
286 NOTIMPLEMENTED(); | |
287 return drag_image_offset_; | 299 return drag_image_offset_; |
288 } | 300 } |
289 | 301 |
290 bool OSExchangeDataProviderAuraX11::Dispatch(const base::NativeEvent& event) { | 302 bool OSExchangeDataProviderAuraX11::Dispatch(const base::NativeEvent& event) { |
291 // TODO(erg): Implement this side when we implement sending data. | 303 XEvent* xev = event; |
292 return false; | 304 switch (xev->type) { |
| 305 case SelectionRequest: |
| 306 selection_owner_.OnSelectionRequest(xev->xselectionrequest); |
| 307 break; |
| 308 default: |
| 309 NOTIMPLEMENTED(); |
| 310 } |
| 311 |
| 312 return true; |
293 } | 313 } |
294 | 314 |
295 bool OSExchangeDataProviderAuraX11::GetPlainTextURL(GURL* url) const { | 315 bool OSExchangeDataProviderAuraX11::GetPlainTextURL(GURL* url) const { |
296 NOTIMPLEMENTED(); | 316 NOTIMPLEMENTED(); |
297 return false; | 317 return false; |
298 } | 318 } |
299 | 319 |
| 320 std::vector< ::Atom> OSExchangeDataProviderAuraX11::GetTargets() const { |
| 321 return format_map_->GetTypes(); |
| 322 } |
| 323 |
300 /////////////////////////////////////////////////////////////////////////////// | 324 /////////////////////////////////////////////////////////////////////////////// |
301 // OSExchangeData, public: | 325 // OSExchangeData, public: |
302 | 326 |
303 // static | 327 // static |
304 OSExchangeData::Provider* OSExchangeData::CreateProvider() { | 328 OSExchangeData::Provider* OSExchangeData::CreateProvider() { |
305 return new OSExchangeDataProviderAuraX11(); | 329 return new OSExchangeDataProviderAuraX11(); |
306 } | 330 } |
307 | 331 |
308 } // namespace ui | 332 } // namespace ui |
OLD | NEW |