selection_requestor.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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. #ifndef UI_BASE_X_SELECTION_REQUESTOR_H_
  5. #define UI_BASE_X_SELECTION_REQUESTOR_H_
  6. #include <cstddef>
  7. #include <vector>
  8. #include "base/component_export.h"
  9. #include "base/memory/raw_ptr.h"
  10. #include "base/memory/ref_counted_memory.h"
  11. #include "base/time/time.h"
  12. #include "ui/gfx/x/connection.h"
  13. namespace ui {
  14. class SelectionData;
  15. class XClipboardHelper;
  16. // Requests and later receives data from the X11 server through the selection
  17. // system.
  18. //
  19. // X11 uses a system called "selections" to implement clipboards and drag and
  20. // drop. This class interprets messages from the stateful selection request
  21. // API. SelectionRequestor should only deal with the X11 details; it does not
  22. // implement per-component fast-paths.
  23. class COMPONENT_EXPORT(UI_BASE_X) SelectionRequestor {
  24. public:
  25. SelectionRequestor(x11::Window xwindow, XClipboardHelper* helper);
  26. SelectionRequestor(const SelectionRequestor&) = delete;
  27. SelectionRequestor& operator=(const SelectionRequestor&) = delete;
  28. ~SelectionRequestor();
  29. // Does the work of requesting |target| from |selection|, spinning up the
  30. // nested run loop, and reading the resulting data back. The result is
  31. // stored in |out_data|.
  32. // |out_data_items| is the length of |out_data| in |out_type| items.
  33. bool PerformBlockingConvertSelection(x11::Atom selection,
  34. x11::Atom target,
  35. std::vector<uint8_t>* out_data,
  36. x11::Atom* out_type);
  37. // Requests |target| from |selection|, passing |parameter| as a parameter to
  38. // XConvertSelection().
  39. void PerformBlockingConvertSelectionWithParameter(
  40. x11::Atom selection,
  41. x11::Atom target,
  42. const std::vector<x11::Atom>& parameter);
  43. // Returns the first of |types| offered by the current owner of |selection|.
  44. // Returns an empty SelectionData object if none of |types| are available.
  45. SelectionData RequestAndWaitForTypes(x11::Atom selection,
  46. const std::vector<x11::Atom>& types);
  47. // It is our owner's responsibility to plumb X11 SelectionNotify events on
  48. // |xwindow_| to us.
  49. void OnSelectionNotify(const x11::SelectionNotifyEvent& event);
  50. // Returns true if SelectionOwner can process the XChangeProperty event,
  51. // |event|.
  52. bool CanDispatchPropertyEvent(const x11::PropertyNotifyEvent& event);
  53. void OnPropertyEvent(const x11::PropertyNotifyEvent& event);
  54. private:
  55. friend class SelectionRequestorTest;
  56. // A request that has been issued.
  57. struct Request {
  58. Request(x11::Atom selection, x11::Atom target, base::TimeTicks timeout);
  59. ~Request();
  60. // The target and selection requested in the XConvertSelection() request.
  61. // Used for error detection.
  62. x11::Atom selection;
  63. x11::Atom target;
  64. // Whether the result of the XConvertSelection() request is being sent
  65. // incrementally.
  66. bool data_sent_incrementally;
  67. // The result data for the XConvertSelection() request.
  68. std::vector<scoped_refptr<base::RefCountedMemory>> out_data;
  69. x11::Atom out_type;
  70. // Whether the XConvertSelection() request was successful.
  71. bool success;
  72. // The time when the request should be aborted.
  73. base::TimeTicks timeout;
  74. // True if the request is complete.
  75. bool completed;
  76. };
  77. // Aborts requests which have timed out.
  78. void AbortStaleRequests();
  79. // Mark |request| as completed. If the current request is completed, converts
  80. // the selection for the next request.
  81. void CompleteRequest(size_t index, bool success);
  82. // Converts the selection for the request at |current_request_index_|.
  83. void ConvertSelectionForCurrentRequest();
  84. // Blocks till SelectionNotify is received for the target specified in
  85. // |request|.
  86. void BlockTillSelectionNotifyForRequest(Request* request);
  87. // Returns the request at |current_request_index_| or NULL if there isn't any.
  88. Request* GetCurrentRequest();
  89. // Our X11 state.
  90. const x11::Window x_window_;
  91. // Not owned.
  92. const raw_ptr<XClipboardHelper> helper_;
  93. // The property on |x_window_| set by the selection owner with the value of
  94. // the selection.
  95. const x11::Atom x_property_;
  96. // In progress requests. Requests are added to the list at the start of
  97. // PerformBlockingConvertSelection() and are removed and destroyed right
  98. // before the method terminates.
  99. std::vector<Request*> requests_;
  100. // The index of the currently active request in |requests_|. The active
  101. // request is the request for which XConvertSelection() has been
  102. // called and for which we are waiting for a SelectionNotify response.
  103. size_t current_request_index_ = 0u;
  104. };
  105. } // namespace ui
  106. #endif // UI_BASE_X_SELECTION_REQUESTOR_H_