1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h"
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/memory/ref_counted_memory.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_aurax11.h"
105e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/net_util.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/clipboard/clipboard.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/clipboard/scoped_clipboard_writer.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/x/selection_utils.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/x/x11_util.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Note: the GetBlah() methods are used immediately by the
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// web_contents_view_aura.cc:PrepareDropData(), while the omnibox is a
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// little more discriminating and calls HasBlah() before trying to get the
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// information.
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace ui {
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kDndSelection[] = "XdndSelection";
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char* kAtomsToCache[] = {
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kString,
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kText,
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kUtf8String,
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kDndSelection,
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Clipboard::kMimeTypeURIList,
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kMimeTypeMozillaURL,
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Clipboard::kMimeTypeText,
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NULL
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)OSExchangeDataProviderAuraX11::OSExchangeDataProviderAuraX11(
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ::Window x_window,
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const SelectionFormatMap& selection)
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : x_display_(GetXDisplay()),
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      x_root_window_(DefaultRootWindow(x_display_)),
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      own_window_(false),
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      x_window_(x_window),
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      atom_cache_(x_display_, kAtomsToCache),
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      format_map_(selection),
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      selection_owner_(x_display_, x_window_,
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       atom_cache_.GetAtom(kDndSelection)) {
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We don't know all possible MIME types at compile time.
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  atom_cache_.allow_uncached_atoms();
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)OSExchangeDataProviderAuraX11::OSExchangeDataProviderAuraX11()
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : x_display_(GetXDisplay()),
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      x_root_window_(DefaultRootWindow(x_display_)),
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      own_window_(true),
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      x_window_(XCreateWindow(
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          x_display_,
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          x_root_window_,
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          -100, -100, 10, 10,  // x, y, width, height
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          0,                   // border width
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          CopyFromParent,      // depth
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          InputOnly,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          CopyFromParent,      // visual
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          0,
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          NULL)),
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      atom_cache_(x_display_, kAtomsToCache),
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      format_map_(),
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      selection_owner_(x_display_, x_window_,
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       atom_cache_.GetAtom(kDndSelection)) {
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We don't know all possible MIME types at compile time.
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  atom_cache_.allow_uncached_atoms();
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  XStoreName(x_display_, x_window_, "Chromium Drag & Drop Window");
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, x_window_);
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)OSExchangeDataProviderAuraX11::~OSExchangeDataProviderAuraX11() {
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (own_window_) {
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(x_window_);
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    XDestroyWindow(x_display_, x_window_);
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid OSExchangeDataProviderAuraX11::TakeOwnershipOfSelection() const {
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  selection_owner_.TakeOwnershipOfSelection(format_map_);
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid OSExchangeDataProviderAuraX11::RetrieveTargets(
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::vector<Atom>* targets) const {
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  selection_owner_.RetrieveTargets(targets);
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSelectionFormatMap OSExchangeDataProviderAuraX11::GetFormatMap() const {
100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We return the |selection_owner_|'s format map instead of our own in case
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // ours has been modified since TakeOwnershipOfSelection() was called.
102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return selection_owner_.selection_format_map();
103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochOSExchangeData::Provider* OSExchangeDataProviderAuraX11::Clone() const {
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  OSExchangeDataProviderAuraX11* ret = new OSExchangeDataProviderAuraX11();
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ret->format_map_ = format_map_;
108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return ret;
109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid OSExchangeDataProviderAuraX11::SetString(const base::string16& text_data) {
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string utf8 = UTF16ToUTF8(text_data);
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<base::RefCountedMemory> mem(
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::RefCountedString::TakeString(&utf8));
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  format_map_.Insert(atom_cache_.GetAtom(Clipboard::kMimeTypeText), mem);
117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  format_map_.Insert(atom_cache_.GetAtom(kText), mem);
118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  format_map_.Insert(atom_cache_.GetAtom(kString), mem);
119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  format_map_.Insert(atom_cache_.GetAtom(kUtf8String), mem);
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void OSExchangeDataProviderAuraX11::SetURL(const GURL& url,
123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                           const base::string16& title) {
124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Mozilla's URL format: (UTF16: URL, newline, title)
125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (url.is_valid()) {
126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    string16 spec = UTF8ToUTF16(url.spec());
127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::vector<unsigned char> data;
129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ui::AddString16ToVector(spec, &data);
130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ui::AddString16ToVector(ASCIIToUTF16("\n"), &data);
131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ui::AddString16ToVector(title, &data);
132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_refptr<base::RefCountedMemory> mem(
133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::RefCountedBytes::TakeVector(&data));
134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    format_map_.Insert(atom_cache_.GetAtom(kMimeTypeMozillaURL), mem);
136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SetString(spec);
138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void OSExchangeDataProviderAuraX11::SetFilename(const base::FilePath& path) {
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NOTIMPLEMENTED();
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void OSExchangeDataProviderAuraX11::SetFilenames(
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::vector<OSExchangeData::FileInfo>& filenames) {
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NOTIMPLEMENTED();
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void OSExchangeDataProviderAuraX11::SetPickledData(
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const OSExchangeData::CustomFormat& format,
152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const Pickle& pickle) {
153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const unsigned char* data =
154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      reinterpret_cast<const unsigned char*>(pickle.data());
155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::vector<unsigned char> bytes;
157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bytes.insert(bytes.end(), data, data + pickle.size());
158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<base::RefCountedMemory> mem(
159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::RefCountedBytes::TakeVector(&bytes));
160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  format_map_.Insert(atom_cache_.GetAtom(format.ToString().c_str()), mem);
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool OSExchangeDataProviderAuraX11::GetString(base::string16* result) const {
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> text_atoms = ui::GetTextAtomsFrom(&atom_cache_);
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> requested_types;
167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ui::GetAtomIntersection(text_atoms, GetTargets(), &requested_types);
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ui::SelectionData data(format_map_.GetFirstOf(requested_types));
170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (data.IsValid()) {
171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::string text = data.GetText();
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *result = UTF8ToUTF16(text);
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool OSExchangeDataProviderAuraX11::GetURLAndTitle(
180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    GURL* url,
181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::string16* title) const {
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> url_atoms = ui::GetURLAtomsFrom(&atom_cache_);
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> requested_types;
184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ui::SelectionData data(format_map_.GetFirstOf(requested_types));
187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (data.IsValid()) {
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // TODO(erg): Technically, both of these forms can accept multiple URLs,
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // but that doesn't match the assumptions of the rest of the system which
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // expect single types.
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (data.GetType() == atom_cache_.GetAtom(kMimeTypeMozillaURL)) {
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Mozilla URLs are (UTF16: URL, newline, title).
194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::string16 unparsed;
195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      data.AssignTo(&unparsed);
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      std::vector<base::string16> tokens;
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      size_t num_tokens = Tokenize(unparsed, ASCIIToUTF16("\n"), &tokens);
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (num_tokens >= 2) {
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        *url = GURL(tokens[0]);
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        *title = tokens[1];
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return true;
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        NOTREACHED() << "Data that claimed to be a Mozilla URL has "
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                     << num_tokens << " tokens instead of 2.";
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else if (data.GetType() == atom_cache_.GetAtom(
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   Clipboard::kMimeTypeURIList)) {
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // uri-lists are newline separated file lists in URL encoding.
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string unparsed;
211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      data.AssignTo(&unparsed);
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::vector<std::string> tokens;
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      size_t num_tokens = Tokenize(unparsed, "\n", &tokens);
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (!num_tokens) {
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        NOTREACHED() << "Empty URI list";
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return false;
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *url = GURL(tokens[0]);
221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      *title = base::string16();
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return true;
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OSExchangeDataProviderAuraX11::GetFilename(base::FilePath* path) const {
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // On X11, files are passed by URL and aren't separate.
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OSExchangeDataProviderAuraX11::GetFilenames(
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::vector<OSExchangeData::FileInfo>* filenames) const {
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // On X11, files are passed by URL and aren't separate.
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OSExchangeDataProviderAuraX11::GetPickledData(
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const OSExchangeData::CustomFormat& format,
243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Pickle* pickle) const {
244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::vector< ::Atom> requested_types;
245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  requested_types.push_back(atom_cache_.GetAtom(format.ToString().c_str()));
246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ui::SelectionData data(format_map_.GetFirstOf(requested_types));
248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (data.IsValid()) {
249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Note that the pickle object on the right hand side of the assignment
250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // only refers to the bytes in |data|. The assignment copies the data.
251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    *pickle = Pickle(reinterpret_cast<const char*>(data.GetData()),
252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     static_cast<int>(data.GetSize()));
253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return true;
254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OSExchangeDataProviderAuraX11::HasString() const {
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> text_atoms = ui::GetTextAtomsFrom(&atom_cache_);
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> requested_types;
262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ui::GetAtomIntersection(text_atoms, GetTargets(), &requested_types);
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !requested_types.empty();
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OSExchangeDataProviderAuraX11::HasURL() const {
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> url_atoms = ui::GetURLAtomsFrom(&atom_cache_);
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> requested_types;
269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !requested_types.empty();
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OSExchangeDataProviderAuraX11::HasFile() const {
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // On X11, files are passed by URL and aren't separate.
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OSExchangeDataProviderAuraX11::HasCustomFormat(
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const OSExchangeData::CustomFormat& format) const {
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> url_atoms;
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  url_atoms.push_back(atom_cache_.GetAtom(format.ToString().c_str()));
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> requested_types;
283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !requested_types.empty();
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid OSExchangeDataProviderAuraX11::SetHtml(const base::string16& html,
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                            const GURL& base_url) {
290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::vector<unsigned char> bytes;
291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Manually jam a UTF16 BOM into bytes because otherwise, other programs will
292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // assume UTF-8.
293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bytes.push_back(0xFF);
294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bytes.push_back(0xFE);
295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ui::AddString16ToVector(html, &bytes);
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<base::RefCountedMemory> mem(
297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::RefCountedBytes::TakeVector(&bytes));
298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  format_map_.Insert(atom_cache_.GetAtom(Clipboard::kMimeTypeHTML), mem);
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool OSExchangeDataProviderAuraX11::GetHtml(base::string16* html,
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                            GURL* base_url) const {
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> url_atoms;
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  url_atoms.push_back(atom_cache_.GetAtom(Clipboard::kMimeTypeHTML));
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> requested_types;
307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ui::SelectionData data(format_map_.GetFirstOf(requested_types));
310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (data.IsValid()) {
311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    *html = data.GetHtml();
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *base_url = GURL();
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OSExchangeDataProviderAuraX11::HasHtml() const {
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> url_atoms;
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  url_atoms.push_back(atom_cache_.GetAtom(Clipboard::kMimeTypeHTML));
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> requested_types;
323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !requested_types.empty();
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void OSExchangeDataProviderAuraX11::SetDragImage(
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const gfx::ImageSkia& image,
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const gfx::Vector2d& cursor_offset) {
331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  drag_image_ = image;
332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  drag_image_offset_ = cursor_offset;
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const gfx::ImageSkia& OSExchangeDataProviderAuraX11::GetDragImage() const {
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return drag_image_;
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const gfx::Vector2d& OSExchangeDataProviderAuraX11::GetDragImageOffset() const {
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return drag_image_offset_;
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OSExchangeDataProviderAuraX11::Dispatch(const base::NativeEvent& event) {
344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  XEvent* xev = event;
345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  switch (xev->type) {
346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case SelectionRequest:
347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      selection_owner_.OnSelectionRequest(xev->xselectionrequest);
348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    default:
350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      NOTIMPLEMENTED();
351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return true;
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OSExchangeDataProviderAuraX11::GetPlainTextURL(GURL* url) const {
357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  string16 text;
358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetString(&text)) {
359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    GURL test_url(text);
360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (test_url.is_valid()) {
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      *url = test_url;
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return true;
363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::vector< ::Atom> OSExchangeDataProviderAuraX11::GetTargets() const {
370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return format_map_.GetTypes();
371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// OSExchangeData, public:
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)OSExchangeData::Provider* OSExchangeData::CreateProvider() {
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return new OSExchangeDataProviderAuraX11();
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace ui
382