File: selection_owner.h

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (137 lines) | stat: -rw-r--r-- 4,540 bytes parent folder | download
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_