selection_owner.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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_OWNER_H_
  5. #define UI_BASE_X_SELECTION_OWNER_H_
  6. #include <stddef.h>
  7. #include <vector>
  8. #include "base/callback.h"
  9. #include "base/component_export.h"
  10. #include "base/memory/ref_counted_memory.h"
  11. #include "base/time/time.h"
  12. #include "base/timer/timer.h"
  13. #include "ui/base/x/selection_utils.h"
  14. #include "ui/gfx/x/event.h"
  15. namespace x11 {
  16. class XScopedEventSelector;
  17. }
  18. namespace ui {
  19. COMPONENT_EXPORT(UI_BASE_X) extern const char kIncr[];
  20. COMPONENT_EXPORT(UI_BASE_X) extern const char kSaveTargets[];
  21. COMPONENT_EXPORT(UI_BASE_X) extern const char kTargets[];
  22. // Owns a specific X11 selection on an X window.
  23. //
  24. // The selection owner object keeps track of which xwindow is the current
  25. // owner, and when its |xwindow_|, offers different data types to other
  26. // processes.
  27. class COMPONENT_EXPORT(UI_BASE_X) SelectionOwner {
  28. public:
  29. SelectionOwner(x11::Connection* connection,
  30. x11::Window xwindow,
  31. x11::Atom selection_name);
  32. SelectionOwner(const SelectionOwner&) = delete;
  33. SelectionOwner& operator=(const SelectionOwner&) = delete;
  34. ~SelectionOwner();
  35. // Returns the current selection data. Useful for fast paths.
  36. const SelectionFormatMap& selection_format_map() { return format_map_; }
  37. // Appends a list of types we're offering to |targets|.
  38. void RetrieveTargets(std::vector<x11::Atom>* targets);
  39. // Attempts to take ownership of the selection. If we're successful, present
  40. // |data| to other windows.
  41. void TakeOwnershipOfSelection(const SelectionFormatMap& data);
  42. // Clears our internal format map and clears the selection owner, whether we
  43. // own the selection or not.
  44. void ClearSelectionOwner();
  45. // It is our owner's responsibility to plumb X11 events on |xwindow_| to us.
  46. void OnSelectionRequest(const x11::SelectionRequestEvent& event);
  47. void OnSelectionClear(const x11::SelectionClearEvent& event);
  48. // Returns true if SelectionOwner can process the XPropertyEvent event,
  49. // |event|.
  50. bool CanDispatchPropertyEvent(const x11::PropertyNotifyEvent& event);
  51. void OnPropertyEvent(const x11::PropertyNotifyEvent& event);
  52. private:
  53. // Holds state related to an incremental data transfer.
  54. struct IncrementalTransfer {
  55. IncrementalTransfer(
  56. x11::Window window,
  57. x11::Atom target,
  58. x11::Atom property,
  59. std::unique_ptr<x11::XScopedEventSelector> event_selector,
  60. const scoped_refptr<base::RefCountedMemory>& data,
  61. int offset,
  62. base::TimeTicks timeout);
  63. IncrementalTransfer(const IncrementalTransfer&) = delete;
  64. IncrementalTransfer& operator=(const IncrementalTransfer&) = delete;
  65. ~IncrementalTransfer();
  66. // Move-only class.
  67. IncrementalTransfer(IncrementalTransfer&&);
  68. IncrementalTransfer& operator=(IncrementalTransfer&&);
  69. // Parameters from the XSelectionRequest. The data is transferred over
  70. // |property| on |window|.
  71. x11::Window window;
  72. x11::Atom target;
  73. x11::Atom property;
  74. // Selects events on |window|.
  75. std::unique_ptr<x11::XScopedEventSelector> event_selector;
  76. // The data to be transferred.
  77. scoped_refptr<base::RefCountedMemory> data;
  78. // The offset from the beginning of |data| of the first byte to be
  79. // transferred in the next chunk.
  80. size_t offset;
  81. // Time when the transfer should be aborted because the selection requestor
  82. // is taking too long to notify us that we can send the next chunk.
  83. base::TimeTicks timeout;
  84. };
  85. // Attempts to convert the selection to |target|. If the conversion is
  86. // successful, true is returned and the result is stored in the |property|
  87. // of |requestor|.
  88. bool ProcessTarget(x11::Atom target,
  89. x11::Window requestor,
  90. x11::Atom property);
  91. // Sends the next chunk of data for given the incremental data transfer.
  92. void ProcessIncrementalTransfer(IncrementalTransfer* transfer);
  93. // Aborts any incremental data transfers which have timed out.
  94. void AbortStaleIncrementalTransfers();
  95. // Called when the transfer at |it| has completed to do cleanup.
  96. void CompleteIncrementalTransfer(
  97. std::vector<IncrementalTransfer>::iterator it);
  98. // Returns the incremental data transfer, if any, which was waiting for
  99. // |event|.
  100. std::vector<IncrementalTransfer>::iterator FindIncrementalTransferForEvent(
  101. const x11::PropertyNotifyEvent& event);
  102. // Our X11 state.
  103. x11::Window x_window_;
  104. // The X11 selection that this instance communicates on.
  105. x11::Atom selection_name_;
  106. // The time that this instance took ownership of its selection.
  107. x11::Time acquired_selection_timestamp_;
  108. // The data we are currently serving.
  109. SelectionFormatMap format_map_;
  110. std::vector<IncrementalTransfer> incremental_transfers_;
  111. // Used to abort stale incremental data transfers.
  112. base::RepeatingTimer incremental_transfer_abort_timer_;
  113. };
  114. } // namespace ui
  115. #endif // UI_BASE_X_SELECTION_OWNER_H_