This source file includes following definitions.
- atom_cache_
- PerformBlockingConvertSelection
- RequestAndWaitForTypes
- OnSelectionNotify
- returned
#include "ui/base/x/selection_requestor.h"
#include "base/message_loop/message_pump_x11.h"
#include "base/run_loop.h"
#include "ui/base/x/selection_utils.h"
#include "ui/base/x/x11_util.h"
namespace ui {
namespace {
const char kChromeSelection[] = "CHROME_SELECTION";
const char* kAtomsToCache[] = {
kChromeSelection,
NULL
};
}
SelectionRequestor::SelectionRequestor(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) {
}
SelectionRequestor::~SelectionRequestor() {}
bool SelectionRequestor::PerformBlockingConvertSelection(
Atom target,
scoped_refptr<base::RefCountedMemory>* out_data,
size_t* out_data_bytes,
size_t* out_data_items,
Atom* out_type) {
Atom property_to_set = atom_cache_.GetAtom(kChromeSelection);
XConvertSelection(x_display_,
selection_name_,
target,
property_to_set,
x_window_,
CurrentTime);
base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
base::RunLoop run_loop;
const int kMaxWaitTimeForClipboardResponse = 300;
loop->PostDelayedTask(
FROM_HERE,
run_loop.QuitClosure(),
base::TimeDelta::FromMilliseconds(kMaxWaitTimeForClipboardResponse));
PendingRequest pending_request(target, run_loop.QuitClosure());
pending_requests_.push_back(&pending_request);
run_loop.Run();
DCHECK(!pending_requests_.empty());
DCHECK_EQ(&pending_request, pending_requests_.back());
pending_requests_.pop_back();
if (pending_request.returned_property != property_to_set)
return false;
return ui::GetRawBytesOfProperty(x_window_, pending_request.returned_property,
out_data, out_data_bytes, out_data_items,
out_type);
}
SelectionData SelectionRequestor::RequestAndWaitForTypes(
const std::vector< ::Atom>& types) {
for (std::vector< ::Atom>::const_iterator it = types.begin();
it != types.end(); ++it) {
scoped_refptr<base::RefCountedMemory> data;
size_t data_bytes = 0;
::Atom type = None;
if (PerformBlockingConvertSelection(*it,
&data,
&data_bytes,
NULL,
&type) &&
type == *it) {
return SelectionData(type, data);
}
}
return SelectionData();
}
void SelectionRequestor::OnSelectionNotify(const XSelectionEvent& event) {
PendingRequest* request_notified = NULL;
if (selection_name_ == event.selection) {
for (std::list<PendingRequest*>::iterator iter = pending_requests_.begin();
iter != pending_requests_.end(); ++iter) {
PendingRequest* request = *iter;
if (request->returned)
continue;
if (request->target != event.target)
continue;
request_notified = request;
break;
}
}
if (!request_notified)
return;
request_notified->returned_property = event.property;
request_notified->returned = true;
request_notified->quit_closure.Run();
}
SelectionRequestor::PendingRequest::PendingRequest(Atom target,
base::Closure quit_closure)
: target(target),
quit_closure(quit_closure),
returned_property(None),
returned(false) {
}
SelectionRequestor::PendingRequest::~PendingRequest() {
}
}