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. 4 5#ifndef UI_BASE_X_SELECTION_REQUESTOR_H_ 6#define UI_BASE_X_SELECTION_REQUESTOR_H_ 7 8#include <X11/Xlib.h> 9 10// Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class. 11#undef RootWindow 12 13#include <list> 14#include <vector> 15 16#include "base/basictypes.h" 17#include "base/callback.h" 18#include "base/memory/ref_counted_memory.h" 19#include "ui/base/ui_export.h" 20#include "ui/gfx/x/x11_atom_cache.h" 21 22namespace ui { 23class SelectionData; 24 25// Requests and later receives data from the X11 server through the selection 26// system. 27// 28// X11 uses a system called "selections" to implement clipboards and drag and 29// drop. This class interprets messages from the statefull selection request 30// API. SelectionRequestor should only deal with the X11 details; it does not 31// implement per-component fast-paths. 32class UI_EXPORT SelectionRequestor { 33 public: 34 SelectionRequestor(Display* xdisplay, 35 ::Window xwindow, 36 ::Atom selection_name); 37 ~SelectionRequestor(); 38 39 // Does the work of requesting |target| from the selection we handle, 40 // spinning up the nested message loop, and reading the resulting data 41 // back. |out_data| is allocated with the X allocator and must be freed with 42 // XFree(). |out_data_bytes| is the length in machine chars, while 43 // |out_data_items| is the length in |out_type| items. 44 bool PerformBlockingConvertSelection( 45 ::Atom target, 46 scoped_refptr<base::RefCountedMemory>* out_data, 47 size_t* out_data_bytes, 48 size_t* out_data_items, 49 ::Atom* out_type); 50 51 // Returns the first of |types| offered by the current selection holder, or 52 // returns NULL if none of those types are available. 53 SelectionData RequestAndWaitForTypes(const std::vector< ::Atom>& types); 54 55 // It is our owner's responsibility to plumb X11 SelectionNotify events on 56 // |xwindow_| to us. 57 void OnSelectionNotify(const XSelectionEvent& event); 58 59 private: 60 // Our X11 state. 61 Display* x_display_; 62 ::Window x_window_; 63 64 // The X11 selection that this instance communicates on. 65 ::Atom selection_name_; 66 67 // A request that has been issued and we are waiting for a response to. 68 struct PendingRequest { 69 PendingRequest(Atom target, base::Closure quit_closure); 70 ~PendingRequest(); 71 72 // Data to the current XConvertSelection request. Used for error detection; 73 // we verify it on the return message. 74 ::Atom target; 75 76 // Called to terminate the nested message loop. 77 base::Closure quit_closure; 78 79 // The property in the returning SelectNotify message is used to signal 80 // success. If None, our request failed somehow. If equal to the property 81 // atom that we sent in the XConvertSelection call, we can read that 82 // property on |x_window_| for the requested data. 83 ::Atom returned_property; 84 85 // Set to true when return_property is populated. 86 bool returned; 87 }; 88 89 // A list of requests for which we are waiting for responses. 90 std::list<PendingRequest*> pending_requests_; 91 92 X11AtomCache atom_cache_; 93 94 DISALLOW_COPY_AND_ASSIGN(SelectionRequestor); 95}; 96 97} // namespace ui 98 99#endif // UI_BASE_X_SELECTION_REQUESTOR_H_ 100