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