// 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_REQUESTOR_H_
#define UI_BASE_X_SELECTION_REQUESTOR_H_

#include <vector>

#include "base/basictypes.h"
#include "base/callback.h"
#include "base/event_types.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/gfx/x/x11_atom_cache.h"
#include "ui/gfx/x/x11_types.h"

namespace ui {
class PlatformEventDispatcher;
class SelectionData;

// Requests and later receives data from the X11 server through the selection
// system.
//
// X11 uses a system called "selections" to implement clipboards and drag and
// drop. This class interprets messages from the stateful selection request
// API. SelectionRequestor should only deal with the X11 details; it does not
// implement per-component fast-paths.
class UI_BASE_EXPORT SelectionRequestor {
 public:
  SelectionRequestor(XDisplay* xdisplay,
                     XID xwindow,
                     PlatformEventDispatcher* dispatcher);
  ~SelectionRequestor();

  // Does the work of requesting |target| from |selection|, spinning up the
  // nested message loop, and reading the resulting data back. The result is
  // stored in |out_data|.
  // |out_data_items| is the length of |out_data| in |out_type| items.
  bool PerformBlockingConvertSelection(
      XAtom selection,
      XAtom target,
      scoped_refptr<base::RefCountedMemory>* out_data,
      size_t* out_data_items,
      XAtom* out_type);

  // Requests |target| from |selection|, passing |parameter| as a parameter to
  // XConvertSelection().
  void PerformBlockingConvertSelectionWithParameter(
      XAtom selection,
      XAtom target,
      const std::vector<XAtom>& parameter);

  // Returns the first of |types| offered by the current owner of |selection|.
  // Returns an empty SelectionData object if none of |types| are available.
  SelectionData RequestAndWaitForTypes(XAtom selection,
                                       const std::vector<XAtom>& types);

  // It is our owner's responsibility to plumb X11 SelectionNotify events on
  // |xwindow_| to us.
  void OnSelectionNotify(const XEvent& event);

  // Returns true if SelectionOwner can process the XChangeProperty event,
  // |event|.
  bool CanDispatchPropertyEvent(const XEvent& event);

  void OnPropertyEvent(const XEvent& event);

 private:
  friend class SelectionRequestorTest;

  // A request that has been issued.
  struct Request {
    Request(XAtom selection, XAtom target, base::TimeTicks timeout);
    ~Request();

    // The target and selection requested in the XConvertSelection() request.
    // Used for error detection.
    XAtom selection;
    XAtom target;

    // Whether the result of the XConvertSelection() request is being sent
    // incrementally.
    bool data_sent_incrementally;

    // The result data for the XConvertSelection() request.
    std::vector<scoped_refptr<base::RefCountedMemory> > out_data;
    size_t out_data_items;
    XAtom out_type;

    // Whether the XConvertSelection() request was successful.
    bool success;

    // The time when the request should be aborted.
    base::TimeTicks timeout;

    // Called to terminate the nested message loop.
    base::Closure quit_closure;

    // True if the request is complete.
    bool completed;
  };

  // Aborts requests which have timed out.
  void AbortStaleRequests();

  // Mark |request| as completed. If the current request is completed, converts
  // the selection for the next request.
  void CompleteRequest(size_t index, bool success);

  // Converts the selection for the request at |current_request_index_|.
  void ConvertSelectionForCurrentRequest();

  // Blocks till SelectionNotify is received for the target specified in
  // |request|.
  void BlockTillSelectionNotifyForRequest(Request* request);

  // Returns the request at |current_request_index_| or NULL if there isn't any.
  Request* GetCurrentRequest();

  // Our X11 state.
  XDisplay* x_display_;
  XID x_window_;

  // The property on |x_window_| set by the selection owner with the value of
  // the selection.
  XAtom x_property_;

  // Dispatcher which handles SelectionNotify and SelectionRequest for
  // |selection_name_|. PerformBlockingConvertSelection() calls the
  // dispatcher directly if PerformBlockingConvertSelection() is called after
  // the PlatformEventSource is destroyed.
  // Not owned.
  PlatformEventDispatcher* dispatcher_;

  // In progress requests. Requests are added to the list at the start of
  // PerformBlockingConvertSelection() and are removed and destroyed right
  // before the method terminates.
  std::vector<Request*> requests_;

  // The index of the currently active request in |requests_|. The active
  // request is the request for which XConvertSelection() has been
  // called and for which we are waiting for a SelectionNotify response.
  size_t current_request_index_;

  // Used to abort requests if the selection owner takes too long to respond.
  base::RepeatingTimer<SelectionRequestor> abort_timer_;

  X11AtomCache atom_cache_;

  DISALLOW_COPY_AND_ASSIGN(SelectionRequestor);
};

}  // namespace ui

#endif  // UI_BASE_X_SELECTION_REQUESTOR_H_
