OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/message_pump_aurax11.h" | |
9 #include "base/string_util.h" | |
10 #include "base/utf_string_conversions.h" | |
11 #include "net/base/net_util.h" | |
12 #include "ui/base/clipboard/clipboard.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" | |
16 #include "ui/base/x/x11_util.h" | |
17 | |
18 // Note: the GetBlah() methods are used immediately by the | |
19 // web_contents_view_aura.cc:PrepareWebDropData(), while the omnibox is a | |
20 // little more discriminating and calls HasBlah() before trying to get the | |
21 // information. | |
22 | |
23 namespace ui { | |
24 | |
25 namespace { | |
26 | |
27 const char kDndSelection[] = "XdndSelection"; | |
28 | |
29 const char* kAtomsToCache[] = { | |
30 kString, | |
31 kText, | |
32 kUtf8String, | |
33 kDndSelection, | |
34 Clipboard::kMimeTypeURIList, | |
35 kMimeTypeMozillaURL, | |
36 NULL | |
37 }; | |
38 | |
39 } // namespace | |
40 | |
41 OSExchangeDataProviderAuraX11::OSExchangeDataProviderAuraX11( | |
42 ui::DesktopSelectionProviderAuraX11* provider, | |
43 ::Window x_window, | |
44 const std::vector< ::Atom> targets) | |
45 : x_display_(GetXDisplay()), | |
46 x_root_window_(DefaultRootWindow(x_display_)), | |
47 own_window_(false), | |
48 selection_event_provider_(provider), | |
49 x_window_(x_window), | |
50 atom_cache_(x_display_, kAtomsToCache), | |
51 selection_requestor_(x_display_, x_window_, | |
52 atom_cache_.GetAtom("XdndSelection")), | |
Daniel Erat
2013/04/13 02:15:00
nit: use kDndSelection here
| |
53 selection_owner_(x_display_, x_window_, | |
54 atom_cache_.GetAtom("XdndSelection")), | |
Daniel Erat
2013/04/13 02:15:00
nit: use kDndSelection here
| |
55 targets_(targets) { | |
56 // We don't know all possible MIME types at compile time. | |
57 atom_cache_.allow_uncached_atoms(); | |
58 | |
59 selection_event_provider_->SetDropHandler(this); | |
60 } | |
61 | |
62 OSExchangeDataProviderAuraX11::OSExchangeDataProviderAuraX11() | |
63 : x_display_(GetXDisplay()), | |
64 x_root_window_(DefaultRootWindow(x_display_)), | |
65 own_window_(true), | |
66 selection_event_provider_(NULL), | |
67 x_window_(XCreateWindow( | |
68 x_display_, | |
69 x_root_window_, | |
70 -100, -100, 10, 10, // x, y, width, height | |
71 0, // border width | |
72 CopyFromParent, // depth | |
73 InputOnly, | |
74 CopyFromParent, // visual | |
75 0, | |
76 NULL)), | |
77 atom_cache_(x_display_, kAtomsToCache), | |
78 selection_requestor_(x_display_, x_window_, | |
79 atom_cache_.GetAtom("XdndSelection")), | |
Daniel Erat
2013/04/13 02:15:00
and here
| |
80 selection_owner_(x_display_, x_window_, | |
81 atom_cache_.GetAtom("XdndSelection")) { | |
Daniel Erat
2013/04/13 02:15:00
and here
| |
82 // We don't know all possible MIME types at compile time. | |
83 atom_cache_.allow_uncached_atoms(); | |
84 | |
85 XStoreName(x_display_, x_window_, "Chromium Drag & Drop Window"); | |
86 | |
87 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, x_window_); | |
88 } | |
89 | |
90 OSExchangeDataProviderAuraX11::~OSExchangeDataProviderAuraX11() { | |
91 if (own_window_) { | |
92 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(x_window_); | |
93 XDestroyWindow(x_display_, x_window_); | |
94 } else { | |
95 selection_event_provider_->SetDropHandler(NULL); | |
96 } | |
97 } | |
98 | |
99 void OSExchangeDataProviderAuraX11::OnSelectionNotify( | |
100 const XSelectionEvent& event) { | |
101 selection_requestor_.OnSelectionNotify(event); | |
102 } | |
103 | |
104 void OSExchangeDataProviderAuraX11::SetString(const string16& data) { | |
105 NOTIMPLEMENTED(); | |
106 } | |
107 | |
108 void OSExchangeDataProviderAuraX11::SetURL(const GURL& url, | |
109 const string16& title) { | |
110 NOTIMPLEMENTED(); | |
111 } | |
112 | |
113 void OSExchangeDataProviderAuraX11::SetFilename(const base::FilePath& path) { | |
114 NOTIMPLEMENTED(); | |
115 } | |
116 | |
117 void OSExchangeDataProviderAuraX11::SetFilenames( | |
118 const std::vector<OSExchangeData::FileInfo>& filenames) { | |
119 NOTIMPLEMENTED(); | |
120 } | |
121 | |
122 void OSExchangeDataProviderAuraX11::SetPickledData( | |
123 OSExchangeData::CustomFormat format, | |
124 const Pickle& data) { | |
125 NOTIMPLEMENTED(); | |
126 } | |
127 | |
128 bool OSExchangeDataProviderAuraX11::GetString(string16* result) const { | |
129 std::vector< ::Atom> text_atoms = ui::GetTextAtomsFrom(&atom_cache_); | |
130 std::vector< ::Atom> requested_types; | |
131 ui::GetAtomIntersection(text_atoms, targets_, &requested_types); | |
132 | |
133 scoped_ptr<ui::SelectionData> data( | |
134 selection_requestor_.RequestAndWaitForTypes(requested_types)); | |
135 if (data.get()) { | |
Daniel Erat
2013/04/13 02:15:00
nit: think you can just use "if (data)" now
| |
136 std::string text = data->GetText(); | |
137 *result = UTF8ToUTF16(text); | |
138 return true; | |
139 } | |
140 | |
141 return false; | |
142 } | |
143 | |
144 bool OSExchangeDataProviderAuraX11::GetURLAndTitle(GURL* url, | |
145 string16* title) const { | |
146 std::vector< ::Atom> url_atoms = ui::GetURLAtomsFrom(&atom_cache_); | |
147 std::vector< ::Atom> requested_types; | |
148 ui::GetAtomIntersection(url_atoms, targets_, &requested_types); | |
149 | |
150 scoped_ptr<ui::SelectionData> data( | |
151 selection_requestor_.RequestAndWaitForTypes(requested_types)); | |
152 if (data.get()) { | |
Daniel Erat
2013/04/13 02:15:00
same here
| |
153 // 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 | |
155 // expect single types. | |
156 | |
157 if (data->type() == atom_cache_.GetAtom(kMimeTypeMozillaURL)) { | |
158 // Mozilla URLs are (UTF16: URL, newline, title). | |
159 string16 unparsed; | |
160 data->AssignTo(&unparsed); | |
161 | |
162 std::vector<string16> tokens; | |
163 size_t num_tokens = Tokenize(unparsed, ASCIIToUTF16("\n"), &tokens); | |
164 if (num_tokens >= 2) { | |
165 *url = GURL(tokens[0]); | |
166 *title = tokens[1]; | |
167 return true; | |
168 } else { | |
169 NOTREACHED() << "Data that claimed to be a Mozilla URL has " | |
170 << num_tokens << " tokens instead of 2."; | |
171 } | |
172 } else if (data->type() == atom_cache_.GetAtom( | |
173 Clipboard::kMimeTypeURIList)) { | |
174 // uri-lists are newline separated file lists in URL encoding. | |
175 std::string unparsed; | |
176 data->AssignTo(&unparsed); | |
177 | |
178 std::vector<std::string> tokens; | |
179 size_t num_tokens = Tokenize(unparsed, "\n", &tokens); | |
180 if (!num_tokens) { | |
181 NOTREACHED() << "Empty URI list"; | |
182 return false; | |
183 } | |
184 | |
185 *url = GURL(tokens[0]); | |
186 *title = string16(); | |
187 | |
188 return true; | |
189 } | |
190 } | |
191 | |
192 return false; | |
193 } | |
194 | |
195 bool OSExchangeDataProviderAuraX11::GetFilename(base::FilePath* path) const { | |
196 // On X11, files are passed by URL and aren't separate. | |
197 return false; | |
198 } | |
199 | |
200 bool OSExchangeDataProviderAuraX11::GetFilenames( | |
201 std::vector<OSExchangeData::FileInfo>* filenames) const { | |
202 // On X11, files are passed by URL and aren't separate. | |
203 return false; | |
204 } | |
205 | |
206 bool OSExchangeDataProviderAuraX11::GetPickledData( | |
207 OSExchangeData::CustomFormat format, | |
208 Pickle* data) const { | |
209 NOTIMPLEMENTED(); | |
210 return false; | |
211 } | |
212 | |
213 bool OSExchangeDataProviderAuraX11::HasString() const { | |
214 std::vector< ::Atom> text_atoms = ui::GetTextAtomsFrom(&atom_cache_); | |
215 std::vector< ::Atom> requested_types; | |
216 ui::GetAtomIntersection(text_atoms, targets_, &requested_types); | |
217 return !requested_types.empty(); | |
218 } | |
219 | |
220 bool OSExchangeDataProviderAuraX11::HasURL() const { | |
221 std::vector< ::Atom> url_atoms = ui::GetURLAtomsFrom(&atom_cache_); | |
222 std::vector< ::Atom> requested_types; | |
223 ui::GetAtomIntersection(url_atoms, targets_, &requested_types); | |
224 return !requested_types.empty(); | |
225 } | |
226 | |
227 bool OSExchangeDataProviderAuraX11::HasFile() const { | |
228 // On X11, files are passed by URL and aren't separate. | |
229 return false; | |
230 } | |
231 | |
232 bool OSExchangeDataProviderAuraX11::HasCustomFormat( | |
233 OSExchangeData::CustomFormat format) const { | |
234 std::vector< ::Atom> url_atoms; | |
235 url_atoms.push_back(atom_cache_.GetAtom(format.ToString().c_str())); | |
236 std::vector< ::Atom> requested_types; | |
237 ui::GetAtomIntersection(url_atoms, targets_, &requested_types); | |
238 | |
239 return !requested_types.empty(); | |
240 } | |
241 | |
242 void OSExchangeDataProviderAuraX11::SetHtml(const string16& html, | |
243 const GURL& base_url) { | |
244 NOTIMPLEMENTED(); | |
245 } | |
246 | |
247 bool OSExchangeDataProviderAuraX11::GetHtml(string16* html, | |
248 GURL* base_url) const { | |
249 std::vector< ::Atom> url_atoms; | |
250 url_atoms.push_back(atom_cache_.GetAtom(Clipboard::kMimeTypeHTML)); | |
251 std::vector< ::Atom> requested_types; | |
252 ui::GetAtomIntersection(url_atoms, targets_, &requested_types); | |
253 | |
254 scoped_ptr<ui::SelectionData> data( | |
255 selection_requestor_.RequestAndWaitForTypes(requested_types)); | |
256 if (data.get()) { | |
257 *html = data->GetHtml(); | |
258 *base_url = GURL(); | |
259 return true; | |
260 } | |
261 | |
262 return false; | |
263 } | |
264 | |
265 bool OSExchangeDataProviderAuraX11::HasHtml() const { | |
266 std::vector< ::Atom> url_atoms; | |
267 url_atoms.push_back(atom_cache_.GetAtom(Clipboard::kMimeTypeHTML)); | |
268 std::vector< ::Atom> requested_types; | |
269 ui::GetAtomIntersection(url_atoms, targets_, &requested_types); | |
270 | |
271 return !requested_types.empty(); | |
272 } | |
273 | |
274 void OSExchangeDataProviderAuraX11::SetDragImage( | |
275 const gfx::ImageSkia& image, | |
276 const gfx::Vector2d& cursor_offset) { | |
277 NOTIMPLEMENTED(); | |
278 } | |
279 | |
280 const gfx::ImageSkia& OSExchangeDataProviderAuraX11::GetDragImage() const { | |
281 NOTIMPLEMENTED(); | |
282 return drag_image_; | |
283 } | |
284 | |
285 const gfx::Vector2d& OSExchangeDataProviderAuraX11::GetDragImageOffset() const { | |
286 NOTIMPLEMENTED(); | |
287 return drag_image_offset_; | |
288 } | |
289 | |
290 bool OSExchangeDataProviderAuraX11::Dispatch(const base::NativeEvent& event) { | |
291 // TODO(erg): Implement this side when we implement sending data. | |
292 return false; | |
293 } | |
294 | |
295 bool OSExchangeDataProviderAuraX11::GetPlainTextURL(GURL* url) const { | |
296 NOTIMPLEMENTED(); | |
297 return false; | |
298 } | |
299 | |
300 /////////////////////////////////////////////////////////////////////////////// | |
301 // OSExchangeData, public: | |
302 | |
303 // static | |
304 OSExchangeData::Provider* OSExchangeData::CreateProvider() { | |
305 return new OSExchangeDataProviderAuraX11(); | |
306 } | |
307 | |
308 // static | |
309 OSExchangeData::CustomFormat | |
310 OSExchangeData::RegisterCustomFormat(const std::string& type) { | |
311 // On AuraX11 you probably want to just use the Clipboard::Get*FormatType APIs | |
312 // instead. But we can also dynamically generate new CustomFormat objects | |
313 // here too if really necessary. | |
314 return Clipboard::FormatType::Deserialize(type); | |
315 } | |
316 | |
317 } // namespace ui | |
OLD | NEW |