Index: ui/base/dragdrop/os_exchange_data_provider_aurax11.cc |
diff --git a/ui/base/dragdrop/os_exchange_data_provider_aurax11.cc b/ui/base/dragdrop/os_exchange_data_provider_aurax11.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f6990907fa07b6f6eb7dc3cde285399b8351942a |
--- /dev/null |
+++ b/ui/base/dragdrop/os_exchange_data_provider_aurax11.cc |
@@ -0,0 +1,317 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" |
+ |
+#include "base/logging.h" |
+#include "base/message_pump_aurax11.h" |
+#include "base/string_util.h" |
+#include "base/utf_string_conversions.h" |
+#include "net/base/net_util.h" |
+#include "ui/base/clipboard/clipboard.h" |
+#include "ui/base/clipboard/scoped_clipboard_writer.h" |
+#include "ui/base/dragdrop/desktop_selection_provider_aurax11.h" |
+#include "ui/base/x/selection_utils.h" |
+#include "ui/base/x/x11_util.h" |
+ |
+// Note: the GetBlah() methods are used immediately by the |
+// web_contents_view_aura.cc:PrepareWebDropData(), while the omnibox is a |
+// little more discriminating and calls HasBlah() before trying to get the |
+// information. |
+ |
+namespace ui { |
+ |
+namespace { |
+ |
+const char kDndSelection[] = "XdndSelection"; |
+ |
+const char* kAtomsToCache[] = { |
+ kString, |
+ kText, |
+ kUtf8String, |
+ kDndSelection, |
+ Clipboard::kMimeTypeURIList, |
+ kMimeTypeMozillaURL, |
+ NULL |
+}; |
+ |
+} // namespace |
+ |
+OSExchangeDataProviderAuraX11::OSExchangeDataProviderAuraX11( |
+ ui::DesktopSelectionProviderAuraX11* provider, |
+ ::Window x_window, |
+ const std::vector< ::Atom> targets) |
+ : x_display_(GetXDisplay()), |
+ x_root_window_(DefaultRootWindow(x_display_)), |
+ own_window_(false), |
+ selection_event_provider_(provider), |
+ x_window_(x_window), |
+ atom_cache_(x_display_, kAtomsToCache), |
+ selection_requestor_(x_display_, x_window_, |
+ atom_cache_.GetAtom(kDndSelection)), |
+ selection_owner_(x_display_, x_window_, |
+ atom_cache_.GetAtom(kDndSelection)), |
+ targets_(targets) { |
+ // We don't know all possible MIME types at compile time. |
+ atom_cache_.allow_uncached_atoms(); |
+ |
+ selection_event_provider_->SetDropHandler(this); |
+} |
+ |
+OSExchangeDataProviderAuraX11::OSExchangeDataProviderAuraX11() |
+ : x_display_(GetXDisplay()), |
+ x_root_window_(DefaultRootWindow(x_display_)), |
+ own_window_(true), |
+ selection_event_provider_(NULL), |
+ x_window_(XCreateWindow( |
+ x_display_, |
+ x_root_window_, |
+ -100, -100, 10, 10, // x, y, width, height |
+ 0, // border width |
+ CopyFromParent, // depth |
+ InputOnly, |
+ CopyFromParent, // visual |
+ 0, |
+ NULL)), |
+ atom_cache_(x_display_, kAtomsToCache), |
+ selection_requestor_(x_display_, x_window_, |
+ atom_cache_.GetAtom(kDndSelection)), |
+ selection_owner_(x_display_, x_window_, |
+ atom_cache_.GetAtom(kDndSelection)) { |
+ // We don't know all possible MIME types at compile time. |
+ atom_cache_.allow_uncached_atoms(); |
+ |
+ XStoreName(x_display_, x_window_, "Chromium Drag & Drop Window"); |
+ |
+ base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, x_window_); |
+} |
+ |
+OSExchangeDataProviderAuraX11::~OSExchangeDataProviderAuraX11() { |
+ if (own_window_) { |
+ base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(x_window_); |
+ XDestroyWindow(x_display_, x_window_); |
+ } else { |
+ selection_event_provider_->SetDropHandler(NULL); |
+ } |
+} |
+ |
+void OSExchangeDataProviderAuraX11::OnSelectionNotify( |
+ const XSelectionEvent& event) { |
+ selection_requestor_.OnSelectionNotify(event); |
+} |
+ |
+void OSExchangeDataProviderAuraX11::SetString(const string16& data) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void OSExchangeDataProviderAuraX11::SetURL(const GURL& url, |
+ const string16& title) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void OSExchangeDataProviderAuraX11::SetFilename(const base::FilePath& path) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void OSExchangeDataProviderAuraX11::SetFilenames( |
+ const std::vector<OSExchangeData::FileInfo>& filenames) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void OSExchangeDataProviderAuraX11::SetPickledData( |
+ OSExchangeData::CustomFormat format, |
+ const Pickle& data) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+bool OSExchangeDataProviderAuraX11::GetString(string16* result) const { |
+ std::vector< ::Atom> text_atoms = ui::GetTextAtomsFrom(&atom_cache_); |
+ std::vector< ::Atom> requested_types; |
+ ui::GetAtomIntersection(text_atoms, targets_, &requested_types); |
+ |
+ scoped_ptr<ui::SelectionData> data( |
+ selection_requestor_.RequestAndWaitForTypes(requested_types)); |
+ if (data) { |
+ std::string text = data->GetText(); |
+ *result = UTF8ToUTF16(text); |
+ return true; |
+ } |
+ |
+ return false; |
+} |
+ |
+bool OSExchangeDataProviderAuraX11::GetURLAndTitle(GURL* url, |
+ string16* title) const { |
+ std::vector< ::Atom> url_atoms = ui::GetURLAtomsFrom(&atom_cache_); |
+ std::vector< ::Atom> requested_types; |
+ ui::GetAtomIntersection(url_atoms, targets_, &requested_types); |
+ |
+ scoped_ptr<ui::SelectionData> data( |
+ selection_requestor_.RequestAndWaitForTypes(requested_types)); |
+ if (data) { |
+ // TODO(erg): Technically, both of these forms can accept multiple URLs, |
+ // but that doesn't match the assumptions of the rest of the system which |
+ // expect single types. |
+ |
+ if (data->type() == atom_cache_.GetAtom(kMimeTypeMozillaURL)) { |
+ // Mozilla URLs are (UTF16: URL, newline, title). |
+ string16 unparsed; |
+ data->AssignTo(&unparsed); |
+ |
+ std::vector<string16> tokens; |
+ size_t num_tokens = Tokenize(unparsed, ASCIIToUTF16("\n"), &tokens); |
+ if (num_tokens >= 2) { |
+ *url = GURL(tokens[0]); |
+ *title = tokens[1]; |
+ return true; |
+ } else { |
+ NOTREACHED() << "Data that claimed to be a Mozilla URL has " |
+ << num_tokens << " tokens instead of 2."; |
+ } |
+ } else if (data->type() == atom_cache_.GetAtom( |
+ Clipboard::kMimeTypeURIList)) { |
+ // uri-lists are newline separated file lists in URL encoding. |
+ std::string unparsed; |
+ data->AssignTo(&unparsed); |
+ |
+ std::vector<std::string> tokens; |
+ size_t num_tokens = Tokenize(unparsed, "\n", &tokens); |
+ if (!num_tokens) { |
+ NOTREACHED() << "Empty URI list"; |
+ return false; |
+ } |
+ |
+ *url = GURL(tokens[0]); |
+ *title = string16(); |
+ |
+ return true; |
+ } |
+ } |
+ |
+ return false; |
+} |
+ |
+bool OSExchangeDataProviderAuraX11::GetFilename(base::FilePath* path) const { |
+ // On X11, files are passed by URL and aren't separate. |
+ return false; |
+} |
+ |
+bool OSExchangeDataProviderAuraX11::GetFilenames( |
+ std::vector<OSExchangeData::FileInfo>* filenames) const { |
+ // On X11, files are passed by URL and aren't separate. |
+ return false; |
+} |
+ |
+bool OSExchangeDataProviderAuraX11::GetPickledData( |
+ OSExchangeData::CustomFormat format, |
+ Pickle* data) const { |
+ NOTIMPLEMENTED(); |
+ return false; |
+} |
+ |
+bool OSExchangeDataProviderAuraX11::HasString() const { |
+ std::vector< ::Atom> text_atoms = ui::GetTextAtomsFrom(&atom_cache_); |
+ std::vector< ::Atom> requested_types; |
+ ui::GetAtomIntersection(text_atoms, targets_, &requested_types); |
+ return !requested_types.empty(); |
+} |
+ |
+bool OSExchangeDataProviderAuraX11::HasURL() const { |
+ std::vector< ::Atom> url_atoms = ui::GetURLAtomsFrom(&atom_cache_); |
+ std::vector< ::Atom> requested_types; |
+ ui::GetAtomIntersection(url_atoms, targets_, &requested_types); |
+ return !requested_types.empty(); |
+} |
+ |
+bool OSExchangeDataProviderAuraX11::HasFile() const { |
+ // On X11, files are passed by URL and aren't separate. |
+ return false; |
+} |
+ |
+bool OSExchangeDataProviderAuraX11::HasCustomFormat( |
+ OSExchangeData::CustomFormat format) const { |
+ std::vector< ::Atom> url_atoms; |
+ url_atoms.push_back(atom_cache_.GetAtom(format.ToString().c_str())); |
+ std::vector< ::Atom> requested_types; |
+ ui::GetAtomIntersection(url_atoms, targets_, &requested_types); |
+ |
+ return !requested_types.empty(); |
+} |
+ |
+void OSExchangeDataProviderAuraX11::SetHtml(const string16& html, |
+ const GURL& base_url) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+bool OSExchangeDataProviderAuraX11::GetHtml(string16* html, |
+ GURL* base_url) const { |
+ std::vector< ::Atom> url_atoms; |
+ url_atoms.push_back(atom_cache_.GetAtom(Clipboard::kMimeTypeHTML)); |
+ std::vector< ::Atom> requested_types; |
+ ui::GetAtomIntersection(url_atoms, targets_, &requested_types); |
+ |
+ scoped_ptr<ui::SelectionData> data( |
+ selection_requestor_.RequestAndWaitForTypes(requested_types)); |
+ if (data) { |
+ *html = data->GetHtml(); |
+ *base_url = GURL(); |
+ return true; |
+ } |
+ |
+ return false; |
+} |
+ |
+bool OSExchangeDataProviderAuraX11::HasHtml() const { |
+ std::vector< ::Atom> url_atoms; |
+ url_atoms.push_back(atom_cache_.GetAtom(Clipboard::kMimeTypeHTML)); |
+ std::vector< ::Atom> requested_types; |
+ ui::GetAtomIntersection(url_atoms, targets_, &requested_types); |
+ |
+ return !requested_types.empty(); |
+} |
+ |
+void OSExchangeDataProviderAuraX11::SetDragImage( |
+ const gfx::ImageSkia& image, |
+ const gfx::Vector2d& cursor_offset) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+const gfx::ImageSkia& OSExchangeDataProviderAuraX11::GetDragImage() const { |
+ NOTIMPLEMENTED(); |
+ return drag_image_; |
+} |
+ |
+const gfx::Vector2d& OSExchangeDataProviderAuraX11::GetDragImageOffset() const { |
+ NOTIMPLEMENTED(); |
+ return drag_image_offset_; |
+} |
+ |
+bool OSExchangeDataProviderAuraX11::Dispatch(const base::NativeEvent& event) { |
+ // TODO(erg): Implement this side when we implement sending data. |
+ return false; |
+} |
+ |
+bool OSExchangeDataProviderAuraX11::GetPlainTextURL(GURL* url) const { |
+ NOTIMPLEMENTED(); |
+ return false; |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// OSExchangeData, public: |
+ |
+// static |
+OSExchangeData::Provider* OSExchangeData::CreateProvider() { |
+ return new OSExchangeDataProviderAuraX11(); |
+} |
+ |
+// static |
+OSExchangeData::CustomFormat |
+OSExchangeData::RegisterCustomFormat(const std::string& type) { |
+ // On AuraX11 you probably want to just use the Clipboard::Get*FormatType APIs |
+ // instead. But we can also dynamically generate new CustomFormat objects |
+ // here too if really necessary. |
+ return Clipboard::FormatType::Deserialize(type); |
+} |
+ |
+} // namespace ui |