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_
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"
21 class PlatformEventDispatcher
;
24 // Requests and later receives data from the X11 server through the selection
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
{
33 SelectionRequestor(XDisplay
* xdisplay
,
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(
45 scoped_refptr
<base::RefCountedMemory
>* out_data
,
46 size_t* out_data_items
,
49 // Requests |target| from |selection|, passing |parameter| as a parameter to
50 // XConvertSelection().
51 void PerformBlockingConvertSelectionWithParameter(
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
63 void OnSelectionNotify(const XEvent
& event
);
65 // Returns true if SelectionOwner can process the XChangeProperty event,
67 bool CanDispatchPropertyEvent(const XEvent
& event
);
69 void OnPropertyEvent(const XEvent
& event
);
72 friend class SelectionRequestorTest
;
74 // A request that has been issued.
76 Request(XAtom selection
, XAtom target
, base::TimeTicks timeout
);
79 // The target and selection requested in the XConvertSelection() request.
80 // Used for error detection.
84 // Whether the result of the XConvertSelection() request is being sent
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
;
93 // Whether the XConvertSelection() request was successful.
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.
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
118 void BlockTillSelectionNotifyForRequest(Request
* request
);
120 // Returns the request at |current_request_index_| or NULL if there isn't any.
121 Request
* GetCurrentRequest();
124 XDisplay
* x_display_
;
127 // The property on |x_window_| set by the selection owner with the value of
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.
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
);
158 #endif // UI_BASE_X_SELECTION_REQUESTOR_H_