Chromium Code Reviews| 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 |