#ifndef UI_BASE_X_SELECTION_OWNER_H_
#define UI_BASE_X_SELECTION_OWNER_H_
#include <stddef.h>
#include <vector>
#include "base/component_export.h"
#include "base/memory/ref_counted_memory.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "ui/base/x/selection_utils.h"
#include "ui/gfx/x/connection.h"
#include "ui/gfx/x/event.h"
namespace x11 {
class ScopedEventSelector;
}
namespace ui {
COMPONENT_EXPORT(UI_BASE_X) extern const char kIncr[];
COMPONENT_EXPORT(UI_BASE_X) extern const char kSaveTargets[];
COMPONENT_EXPORT(UI_BASE_X) extern const char kTargets[];
class COMPONENT_EXPORT(UI_BASE_X) SelectionOwner {
public:
SelectionOwner(x11::Connection& connection,
x11::Window xwindow,
x11::Atom selection_name);
SelectionOwner(const SelectionOwner&) = delete;
SelectionOwner& operator=(const SelectionOwner&) = delete;
~SelectionOwner();
const SelectionFormatMap& selection_format_map() { return format_map_; }
void RetrieveTargets(std::vector<x11::Atom>* targets);
void TakeOwnershipOfSelection(const SelectionFormatMap& data);
void ClearSelectionOwner();
void OnSelectionRequest(const x11::SelectionRequestEvent& event);
void OnSelectionClear(const x11::SelectionClearEvent& event);
bool CanDispatchPropertyEvent(const x11::PropertyNotifyEvent& event);
void OnPropertyEvent(const x11::PropertyNotifyEvent& event);
private:
struct IncrementalTransfer {
IncrementalTransfer(x11::Window window,
x11::Atom target,
x11::Atom property,
x11::ScopedEventSelector event_selector,
const scoped_refptr<base::RefCountedMemory>& data,
int offset,
base::TimeTicks timeout);
IncrementalTransfer(const IncrementalTransfer&) = delete;
IncrementalTransfer& operator=(const IncrementalTransfer&) = delete;
~IncrementalTransfer();
IncrementalTransfer(IncrementalTransfer&&);
IncrementalTransfer& operator=(IncrementalTransfer&&);
x11::Window window;
x11::Atom target;
x11::Atom property;
x11::ScopedEventSelector event_selector;
scoped_refptr<base::RefCountedMemory> data;
size_t offset;
base::TimeTicks timeout;
};
bool ProcessTarget(x11::Atom target,
x11::Window requestor,
x11::Atom property);
void ProcessIncrementalTransfer(IncrementalTransfer* transfer);
void AbortStaleIncrementalTransfers();
void CompleteIncrementalTransfer(
std::vector<IncrementalTransfer>::iterator it);
std::vector<IncrementalTransfer>::iterator FindIncrementalTransferForEvent(
const x11::PropertyNotifyEvent& event);
raw_ref<x11::Connection> connection_;
x11::Window x_window_;
x11::Atom selection_name_;
x11::Time acquired_selection_timestamp_;
SelectionFormatMap format_map_;
std::vector<IncrementalTransfer> incremental_transfers_;
base::RepeatingTimer incremental_transfer_abort_timer_;
};
}
#endif