1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
// 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.
#ifndef UI_BASE_X_SELECTION_OWNER_H_
#define UI_BASE_X_SELECTION_OWNER_H_
#include <vector>
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/ref_counted_memory.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "ui/base/ui_base_export.h"
#include "ui/base/x/selection_utils.h"
#include "ui/gfx/x/x11_atom_cache.h"
#include "ui/gfx/x/x11_types.h"
namespace ui {
// Owns a specific X11 selection on an X window.
//
// The selection owner object keeps track of which xwindow is the current
// owner, and when its |xwindow_|, offers different data types to other
// processes.
class UI_BASE_EXPORT SelectionOwner {
public:
SelectionOwner(XDisplay* xdisplay,
XID xwindow,
XAtom selection_name);
~SelectionOwner();
// Returns the current selection data. Useful for fast paths.
const SelectionFormatMap& selection_format_map() { return format_map_; }
// Appends a list of types we're offering to |targets|.
void RetrieveTargets(std::vector<XAtom>* targets);
// Attempts to take ownership of the selection. If we're successful, present
// |data| to other windows.
void TakeOwnershipOfSelection(const SelectionFormatMap& data);
// Clears our internal format map and clears the selection owner, whether we
// own the selection or not.
void ClearSelectionOwner();
// It is our owner's responsibility to plumb X11 events on |xwindow_| to us.
void OnSelectionRequest(const XEvent& event);
void OnSelectionClear(const XEvent& event);
// Returns true if SelectionOwner can process the XPropertyEvent event,
// |event|.
bool CanDispatchPropertyEvent(const XEvent& event);
void OnPropertyEvent(const XEvent& event);
private:
// Holds state related to an incremental data transfer.
struct IncrementalTransfer {
IncrementalTransfer(XID window,
XAtom target,
XAtom property,
const scoped_refptr<base::RefCountedMemory>& data,
int offset,
base::TimeTicks timeout,
int foreign_window_manager_id);
~IncrementalTransfer();
// Parameters from the XSelectionRequest. The data is transferred over
// |property| on |window|.
XID window;
XAtom target;
XAtom property;
// The data to be transferred.
scoped_refptr<base::RefCountedMemory> data;
// The offset from the beginning of |data| of the first byte to be
// transferred in the next chunk.
size_t offset;
// Time when the transfer should be aborted because the selection requestor
// is taking too long to notify us that we can send the next chunk.
base::TimeTicks timeout;
// Used to unselect PropertyChangeMask on |window| when we are done with
// the data transfer.
int foreign_window_manager_id;
};
// Attempts to convert the selection to |target|. If the conversion is
// successful, true is returned and the result is stored in the |property|
// of |requestor|.
bool ProcessTarget(XAtom target, XID requestor, XAtom property);
// Sends the next chunk of data for given the incremental data transfer.
void ProcessIncrementalTransfer(IncrementalTransfer* transfer);
// Aborts any incremental data transfers which have timed out.
void AbortStaleIncrementalTransfers();
// Called when the transfer at |it| has completed to do cleanup.
void CompleteIncrementalTransfer(
std::vector<IncrementalTransfer>::iterator it);
// Returns the incremental data transfer, if any, which was waiting for
// |event|.
std::vector<IncrementalTransfer>::iterator FindIncrementalTransferForEvent(
const XEvent& event);
// Our X11 state.
XDisplay* x_display_;
XID x_window_;
// The X11 selection that this instance communicates on.
XAtom selection_name_;
// The maximum size of data we can put in XChangeProperty().
size_t max_request_size_;
// The data we are currently serving.
SelectionFormatMap format_map_;
std::vector<IncrementalTransfer> incremental_transfers_;
// Used to abort stale incremental data transfers.
base::RepeatingTimer<SelectionOwner> incremental_transfer_abort_timer_;
X11AtomCache atom_cache_;
DISALLOW_COPY_AND_ASSIGN(SelectionOwner);
};
} // namespace ui
#endif // UI_BASE_X_SELECTION_OWNER_H_
|