123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- // Copyright (c) 2013 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/x/selection_utils.h"
- #include <stdint.h>
- #include <set>
- #include "base/containers/contains.h"
- #include "base/i18n/icu_string_conversions.h"
- #include "base/memory/ref_counted_memory.h"
- #include "base/memory/scoped_refptr.h"
- #include "base/notreached.h"
- #include "base/strings/string_split.h"
- #include "base/strings/string_util.h"
- #include "base/strings/utf_string_conversions.h"
- #include "ui/base/clipboard/clipboard_constants.h"
- #include "ui/gfx/x/x11_atom_cache.h"
- namespace ui {
- std::vector<x11::Atom> GetTextAtomsFrom() {
- static const std::vector<x11::Atom> atoms = {
- x11::GetAtom(kMimeTypeLinuxUtf8String),
- x11::GetAtom(kMimeTypeLinuxString), x11::GetAtom(kMimeTypeLinuxText),
- x11::GetAtom(kMimeTypeText), x11::GetAtom(kMimeTypeTextUtf8)};
- return atoms;
- }
- std::vector<x11::Atom> GetURLAtomsFrom() {
- static const std::vector<x11::Atom> atoms = {
- x11::GetAtom(kMimeTypeURIList), x11::GetAtom(kMimeTypeMozillaURL)};
- return atoms;
- }
- std::vector<x11::Atom> GetURIListAtomsFrom() {
- static const std::vector<x11::Atom> atoms = {x11::GetAtom(kMimeTypeURIList)};
- return atoms;
- }
- void GetAtomIntersection(const std::vector<x11::Atom>& desired,
- const std::vector<x11::Atom>& offered,
- std::vector<x11::Atom>* output) {
- for (const auto& desired_atom : desired) {
- if (base::Contains(offered, desired_atom))
- output->push_back(desired_atom);
- }
- }
- void AddString16ToVector(const std::u16string& str,
- std::vector<unsigned char>* bytes) {
- const unsigned char* front =
- reinterpret_cast<const unsigned char*>(str.data());
- bytes->insert(bytes->end(), front, front + (str.size() * 2));
- }
- std::vector<std::string> ParseURIList(const SelectionData& data) {
- // uri-lists are newline separated file lists in URL encoding.
- std::string unparsed;
- data.AssignTo(&unparsed);
- return base::SplitString(unparsed, "\n", base::KEEP_WHITESPACE,
- base::SPLIT_WANT_NONEMPTY);
- }
- std::string RefCountedMemoryToString(
- const scoped_refptr<base::RefCountedMemory>& memory) {
- if (!memory.get()) {
- NOTREACHED();
- return std::string();
- }
- size_t size = memory->size();
- if (!size)
- return std::string();
- const unsigned char* front = memory->front();
- return std::string(reinterpret_cast<const char*>(front), size);
- }
- std::u16string RefCountedMemoryToString16(
- const scoped_refptr<base::RefCountedMemory>& memory) {
- if (!memory.get()) {
- NOTREACHED();
- return std::u16string();
- }
- size_t size = memory->size();
- if (!size)
- return std::u16string();
- const unsigned char* front = memory->front();
- return std::u16string(reinterpret_cast<const char16_t*>(front), size / 2);
- }
- ///////////////////////////////////////////////////////////////////////////////
- SelectionFormatMap::SelectionFormatMap() = default;
- SelectionFormatMap::SelectionFormatMap(const SelectionFormatMap& other) =
- default;
- SelectionFormatMap::~SelectionFormatMap() = default;
- void SelectionFormatMap::Insert(
- x11::Atom atom,
- const scoped_refptr<base::RefCountedMemory>& item) {
- data_.erase(atom);
- data_.emplace(atom, item);
- }
- ui::SelectionData SelectionFormatMap::GetFirstOf(
- const std::vector<x11::Atom>& requested_types) const {
- for (const auto& requested_type : requested_types) {
- auto data_it = data_.find(requested_type);
- if (data_it != data_.end()) {
- return SelectionData(data_it->first, data_it->second);
- }
- }
- return SelectionData();
- }
- std::vector<x11::Atom> SelectionFormatMap::GetTypes() const {
- std::vector<x11::Atom> atoms;
- for (const auto& datum : data_)
- atoms.push_back(datum.first);
- return atoms;
- }
- ///////////////////////////////////////////////////////////////////////////////
- SelectionData::SelectionData() : type_(x11::Atom::None) {}
- SelectionData::SelectionData(
- x11::Atom type,
- const scoped_refptr<base::RefCountedMemory>& memory)
- : type_(type), memory_(memory) {}
- SelectionData::SelectionData(const SelectionData& rhs) = default;
- SelectionData::~SelectionData() = default;
- SelectionData& SelectionData::operator=(const SelectionData& rhs) {
- type_ = rhs.type_;
- memory_ = rhs.memory_;
- // TODO(erg): In some future where we have to support multiple X Displays,
- // the following will also need to deal with the display.
- return *this;
- }
- bool SelectionData::IsValid() const {
- return type_ != x11::Atom::None;
- }
- x11::Atom SelectionData::GetType() const {
- return type_;
- }
- const unsigned char* SelectionData::GetData() const {
- return memory_.get() ? memory_->front() : nullptr;
- }
- size_t SelectionData::GetSize() const {
- return memory_.get() ? memory_->size() : 0;
- }
- std::string SelectionData::GetText() const {
- if (type_ == x11::GetAtom(kMimeTypeLinuxUtf8String) ||
- type_ == x11::GetAtom(kMimeTypeLinuxText) ||
- type_ == x11::GetAtom(kMimeTypeTextUtf8)) {
- return RefCountedMemoryToString(memory_);
- } else if (type_ == x11::GetAtom(kMimeTypeLinuxString) ||
- type_ == x11::GetAtom(kMimeTypeText)) {
- std::string result;
- base::ConvertToUtf8AndNormalize(RefCountedMemoryToString(memory_),
- base::kCodepageLatin1, &result);
- return result;
- } else {
- // BTW, I looked at COMPOUND_TEXT, and there's no way we're going to
- // support that. Yuck.
- NOTREACHED();
- return std::string();
- }
- }
- std::u16string SelectionData::GetHtml() const {
- std::u16string markup;
- if (type_ == x11::GetAtom(kMimeTypeHTML)) {
- const unsigned char* data = GetData();
- size_t size = GetSize();
- // If the data starts with U+FEFF, i.e., Byte Order Mark, assume it is
- // UTF-16, otherwise assume UTF-8.
- if (size >= 2 && reinterpret_cast<const char16_t*>(data)[0] == u'\uFEFF') {
- markup.assign(reinterpret_cast<const char16_t*>(data) + 1,
- (size / 2) - 1);
- } else {
- base::UTF8ToUTF16(reinterpret_cast<const char*>(data), size, &markup);
- }
- // If there is a terminating NULL, drop it.
- if (!markup.empty() && markup.at(markup.length() - 1) == '\0')
- markup.resize(markup.length() - 1);
- return markup;
- } else {
- NOTREACHED();
- return markup;
- }
- }
- void SelectionData::AssignTo(std::string* result) const {
- *result = RefCountedMemoryToString(memory_);
- }
- void SelectionData::AssignTo(std::u16string* result) const {
- *result = RefCountedMemoryToString16(memory_);
- }
- scoped_refptr<base::RefCountedBytes> SelectionData::TakeBytes() {
- if (!memory_.get())
- return nullptr;
- auto* memory = memory_.release();
- return base::MakeRefCounted<base::RefCountedBytes>(memory->data(),
- memory->size());
- }
- } // namespace ui
|