Add ICU message format support
[chromium-blink-merge.git] / ui / base / x / selection_requestor.h
blob5455ff781fbda822b7e4ba612b2682f1a2e82a00
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef UI_BASE_X_SELECTION_REQUESTOR_H_
6 #define UI_BASE_X_SELECTION_REQUESTOR_H_
8 #include <vector>
10 #include "base/basictypes.h"
11 #include "base/callback.h"
12 #include "base/event_types.h"
13 #include "base/memory/ref_counted_memory.h"
14 #include "base/time/time.h"
15 #include "base/timer/timer.h"
16 #include "ui/base/ui_base_export.h"
17 #include "ui/gfx/x/x11_atom_cache.h"
18 #include "ui/gfx/x/x11_types.h"
20 namespace ui {
21 class PlatformEventDispatcher;
22 class SelectionData;
24 // Requests and later receives data from the X11 server through the selection
25 // system.
27 // X11 uses a system called "selections" to implement clipboards and drag and
28 // drop. This class interprets messages from the stateful selection request
29 // API. SelectionRequestor should only deal with the X11 details; it does not
30 // implement per-component fast-paths.
31 class UI_BASE_EXPORT SelectionRequestor {
32 public:
33 SelectionRequestor(XDisplay* xdisplay,
34 XID xwindow,
35 PlatformEventDispatcher* dispatcher);
36 ~SelectionRequestor();
38 // Does the work of requesting |target| from |selection|, spinning up the
39 // nested message loop, and reading the resulting data back. The result is
40 // stored in |out_data|.
41 // |out_data_items| is the length of |out_data| in |out_type| items.
42 bool PerformBlockingConvertSelection(
43 XAtom selection,
44 XAtom target,
45 scoped_refptr<base::RefCountedMemory>* out_data,
46 size_t* out_data_items,
47 XAtom* out_type);
49 // Requests |target| from |selection|, passing |parameter| as a parameter to
50 // XConvertSelection().
51 void PerformBlockingConvertSelectionWithParameter(
52 XAtom selection,
53 XAtom target,
54 const std::vector<XAtom>& parameter);
56 // Returns the first of |types| offered by the current owner of |selection|.
57 // Returns an empty SelectionData object if none of |types| are available.
58 SelectionData RequestAndWaitForTypes(XAtom selection,
59 const std::vector<XAtom>& types);
61 // It is our owner's responsibility to plumb X11 SelectionNotify events on
62 // |xwindow_| to us.
63 void OnSelectionNotify(const XEvent& event);
65 // Returns true if SelectionOwner can process the XChangeProperty event,
66 // |event|.
67 bool CanDispatchPropertyEvent(const XEvent& event);
69 void OnPropertyEvent(const XEvent& event);
71 private:
72 friend class SelectionRequestorTest;
74 // A request that has been issued.
75 struct Request {
76 Request(XAtom selection, XAtom target, base::TimeTicks timeout);
77 ~Request();
79 // The target and selection requested in the XConvertSelection() request.
80 // Used for error detection.
81 XAtom selection;
82 XAtom target;
84 // Whether the result of the XConvertSelection() request is being sent
85 // incrementally.
86 bool data_sent_incrementally;
88 // The result data for the XConvertSelection() request.
89 std::vector<scoped_refptr<base::RefCountedMemory> > out_data;
90 size_t out_data_items;
91 XAtom out_type;
93 // Whether the XConvertSelection() request was successful.
94 bool success;
96 // The time when the request should be aborted.
97 base::TimeTicks timeout;
99 // Called to terminate the nested message loop.
100 base::Closure quit_closure;
102 // True if the request is complete.
103 bool completed;
106 // Aborts requests which have timed out.
107 void AbortStaleRequests();
109 // Mark |request| as completed. If the current request is completed, converts
110 // the selection for the next request.
111 void CompleteRequest(size_t index, bool success);
113 // Converts the selection for the request at |current_request_index_|.
114 void ConvertSelectionForCurrentRequest();
116 // Blocks till SelectionNotify is received for the target specified in
117 // |request|.
118 void BlockTillSelectionNotifyForRequest(Request* request);
120 // Returns the request at |current_request_index_| or NULL if there isn't any.
121 Request* GetCurrentRequest();
123 // Our X11 state.
124 XDisplay* x_display_;
125 XID x_window_;
127 // The property on |x_window_| set by the selection owner with the value of
128 // the selection.
129 XAtom x_property_;
131 // Dispatcher which handles SelectionNotify and SelectionRequest for
132 // |selection_name_|. PerformBlockingConvertSelection() calls the
133 // dispatcher directly if PerformBlockingConvertSelection() is called after
134 // the PlatformEventSource is destroyed.
135 // Not owned.
136 PlatformEventDispatcher* dispatcher_;
138 // In progress requests. Requests are added to the list at the start of
139 // PerformBlockingConvertSelection() and are removed and destroyed right
140 // before the method terminates.
141 std::vector<Request*> requests_;
143 // The index of the currently active request in |requests_|. The active
144 // request is the request for which XConvertSelection() has been
145 // called and for which we are waiting for a SelectionNotify response.
146 size_t current_request_index_;
148 // Used to abort requests if the selection owner takes too long to respond.
149 base::RepeatingTimer<SelectionRequestor> abort_timer_;
151 X11AtomCache atom_cache_;
153 DISALLOW_COPY_AND_ASSIGN(SelectionRequestor);
156 } // namespace ui
158 #endif // UI_BASE_X_SELECTION_REQUESTOR_H_