| Index: ui/base/x/selection_utils.cc
|
| diff --git a/ui/base/x/selection_utils.cc b/ui/base/x/selection_utils.cc
|
| index 307ce8769a1a51e93a81fc6ee4d5a622219f0e7a..5dd6f681ce129ab01388a4068fcd5154410dffc5 100644
|
| --- a/ui/base/x/selection_utils.cc
|
| +++ b/ui/base/x/selection_utils.cc
|
| @@ -11,6 +11,7 @@
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "ui/base/clipboard/clipboard.h"
|
| #include "ui/base/x/x11_atom_cache.h"
|
| +#include "ui/base/x/x11_util.h"
|
|
|
| namespace ui {
|
|
|
| @@ -75,18 +76,68 @@ SelectionFormatMap::~SelectionFormatMap() {
|
| }
|
|
|
| void SelectionFormatMap::Insert(::Atom atom, char* data, size_t size) {
|
| - DCHECK(data_.find(atom) == data_.end());
|
| + // Views code often inserts the same content multiple times, so we have to
|
| + // free old data. Only call delete when it's the last pointer we have to that
|
| + // data.
|
| + InternalMap::iterator exists_it = data_.find(atom);
|
| + if (exists_it != data_.end()) {
|
| + int count = 0;
|
| + for (InternalMap::iterator it = data_.begin(); it != data_.end(); ++it) {
|
| + if (it->second.first == exists_it->second.first)
|
| + count++;
|
| + }
|
| +
|
| + if (count == 1)
|
| + delete [] exists_it->second.first;
|
| + }
|
| +
|
| data_.insert(std::make_pair(atom, std::make_pair(data, size)));
|
| }
|
|
|
| +ui::SelectionData* SelectionFormatMap::GetFirstOf(
|
| + const std::vector< ::Atom>& requested_types) const {
|
| + for (std::vector< ::Atom>::const_iterator it = requested_types.begin();
|
| + it != requested_types.end(); ++it) {
|
| + const_iterator data_it = data_.find(*it);
|
| + if (data_it != data_.end()) {
|
| + ui::SelectionData* data = new SelectionData;
|
| + data->Set(data_it->first, data_it->second.first, data_it->second.second,
|
| + false);
|
| + return data;
|
| + }
|
| + }
|
| +
|
| + return NULL;
|
| +}
|
| +
|
| +std::vector< ::Atom> SelectionFormatMap::GetTypes() const {
|
| + std::vector< ::Atom> atoms;
|
| + for (const_iterator it = data_.begin(); it != data_.end(); ++it)
|
| + atoms.push_back(it->first);
|
| +
|
| + return atoms;
|
| +}
|
| +
|
| +scoped_ptr<SelectionFormatMap> SelectionFormatMap::Clone() const {
|
| + scoped_ptr<SelectionFormatMap> ret(new SelectionFormatMap);
|
| +
|
| + for (const_iterator it = data_.begin(); it != data_.end(); ++it) {
|
| + char* data_copy = new char[it->second.second];
|
| + memcpy(data_copy, it->second.first, it->second.second);
|
| + ret->Insert(it->first, data_copy, it->second.second);
|
| + }
|
| +
|
| + return ret.Pass();
|
| +}
|
| +
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -SelectionData::SelectionData(Display* x_display)
|
| +SelectionData::SelectionData()
|
| : type_(None),
|
| data_(NULL),
|
| size_(0),
|
| owned_(false),
|
| - atom_cache_(x_display, kSelectionDataAtoms) {
|
| + atom_cache_(ui::GetXDisplay(), kSelectionDataAtoms) {
|
| }
|
|
|
| SelectionData::~SelectionData() {
|
|
|