This source file includes following definitions.
- atom_cache_
- RetrieveTargets
- TakeOwnershipOfSelection
- ClearSelectionOwner
- OnSelectionRequest
- OnSelectionClear
#include "ui/base/x/selection_owner.h"
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include "base/logging.h"
#include "ui/base/x/selection_utils.h"
namespace ui {
namespace {
const char kMultiple[] = "MULTIPLE";
const char kTargets[] = "TARGETS";
const char* kAtomsToCache[] = {
kMultiple,
kTargets,
NULL
};
}
SelectionOwner::SelectionOwner(Display* x_display,
Window x_window,
Atom selection_name)
: x_display_(x_display),
x_window_(x_window),
selection_name_(selection_name),
atom_cache_(x_display_, kAtomsToCache) {
}
SelectionOwner::~SelectionOwner() {
if (XGetSelectionOwner(x_display_, selection_name_) == x_window_)
XSetSelectionOwner(x_display_, selection_name_, None, CurrentTime);
}
void SelectionOwner::RetrieveTargets(std::vector<Atom>* targets) {
for (SelectionFormatMap::const_iterator it = format_map_.begin();
it != format_map_.end(); ++it) {
targets->push_back(it->first);
}
}
void SelectionOwner::TakeOwnershipOfSelection(
const SelectionFormatMap& data) {
XSetSelectionOwner(x_display_, selection_name_, x_window_, CurrentTime);
if (XGetSelectionOwner(x_display_, selection_name_) == x_window_) {
format_map_ = data;
}
}
void SelectionOwner::ClearSelectionOwner() {
XSetSelectionOwner(x_display_, selection_name_, None, CurrentTime);
format_map_ = SelectionFormatMap();
}
void SelectionOwner::OnSelectionRequest(const XSelectionRequestEvent& event) {
XEvent reply;
reply.xselection.type = SelectionNotify;
reply.xselection.requestor = event.requestor;
reply.xselection.selection = event.selection;
reply.xselection.target = event.target;
reply.xselection.property = None;
reply.xselection.time = event.time;
Atom targets_atom = atom_cache_.GetAtom(kTargets);
if (event.target == targets_atom) {
std::vector<Atom> targets;
targets.push_back(targets_atom);
RetrieveTargets(&targets);
XChangeProperty(x_display_, event.requestor, event.property, XA_ATOM, 32,
PropModeReplace,
reinterpret_cast<unsigned char*>(&targets.front()),
targets.size());
reply.xselection.property = event.property;
} else if (event.target == atom_cache_.GetAtom(kMultiple)) {
NOTIMPLEMENTED();
} else {
SelectionFormatMap::const_iterator it =
format_map_.find(event.target);
if (it != format_map_.end()) {
XChangeProperty(x_display_, event.requestor, event.property,
event.target, 8,
PropModeReplace,
const_cast<unsigned char*>(
reinterpret_cast<const unsigned char*>(
it->second->front())),
it->second->size());
reply.xselection.property = event.property;
}
}
XSendEvent(x_display_, event.requestor, False, 0, &reply);
}
void SelectionOwner::OnSelectionClear(const XSelectionClearEvent& event) {
DLOG(ERROR) << "SelectionClear";
}
}