x_server_clipboard.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright (c) 2012 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. // Don't include this file from any .h files because it pulls in some X headers.
  5. #ifndef REMOTING_HOST_LINUX_X_SERVER_CLIPBOARD_H_
  6. #define REMOTING_HOST_LINUX_X_SERVER_CLIPBOARD_H_
  7. #include <set>
  8. #include <string>
  9. #include "base/callback.h"
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/time/time.h"
  12. #include "ui/gfx/x/event.h"
  13. #include "ui/gfx/x/xfixes.h"
  14. #include "ui/gfx/x/xproto.h"
  15. namespace remoting {
  16. // A class to allow manipulation of the X clipboard, using only X API calls.
  17. // This class is not thread-safe, so all its methods must be called on the
  18. // application's main event-processing thread.
  19. class XServerClipboard {
  20. public:
  21. // Called when new clipboard data has been received from the owner of the X
  22. // selection (primary or clipboard).
  23. // |mime_type| is the MIME type associated with the data. This will be one of
  24. // the types listed in remoting/base/constants.h.
  25. // |data| is the clipboard data from the associated X event, encoded with the
  26. // specified MIME-type.
  27. typedef base::RepeatingCallback<void(const std::string& mime_type,
  28. const std::string& data)>
  29. ClipboardChangedCallback;
  30. XServerClipboard();
  31. XServerClipboard(const XServerClipboard&) = delete;
  32. XServerClipboard& operator=(const XServerClipboard&) = delete;
  33. ~XServerClipboard();
  34. // Start monitoring |connection|'s selections, and invoke |callback| whenever
  35. // their content changes. The caller must ensure |connection| is still valid
  36. // whenever any other methods are called on this object.
  37. void Init(x11::Connection* connection,
  38. const ClipboardChangedCallback& callback);
  39. // Copy data to the X Clipboard. This acquires ownership of the
  40. // PRIMARY and CLIPBOARD selections.
  41. void SetClipboard(const std::string& mime_type, const std::string& data);
  42. // Process |event| if it is an X selection notification. The caller should
  43. // invoke this for every event it receives from |connection|.
  44. void ProcessXEvent(const x11::Event& event);
  45. private:
  46. // Handlers called by ProcessXEvent() for each event type.
  47. void OnSetSelectionOwnerNotify(x11::Atom selection, x11::Time timestamp);
  48. void OnPropertyNotify(const x11::PropertyNotifyEvent& event);
  49. void OnSelectionNotify(const x11::SelectionNotifyEvent& event);
  50. void OnSelectionRequest(const x11::SelectionRequestEvent& event);
  51. void OnSelectionClear(const x11::SelectionClearEvent& event);
  52. // Used by OnSelectionRequest() to respond to requests for details of our
  53. // clipboard content. This is done by changing the property |property| of the
  54. // |requestor| window (these values come from the XSelectionRequestEvent).
  55. // |target| must be a string type (STRING or UTF8_STRING).
  56. void SendTargetsResponse(x11::Window requestor, x11::Atom property);
  57. void SendTimestampResponse(x11::Window requestor, x11::Atom property);
  58. void SendStringResponse(x11::Window requestor,
  59. x11::Atom property,
  60. x11::Atom target);
  61. // Called by OnSelectionNotify() when the selection owner has replied to a
  62. // request for information about a selection.
  63. // |event| is the raw X event from the notification.
  64. // |type|, |format| etc are the results from XGetWindowProperty(), or 0 if
  65. // there is no associated data.
  66. void HandleSelectionNotify(const x11::SelectionNotifyEvent& event,
  67. x11::Atom type,
  68. int format,
  69. int item_count,
  70. const void* data);
  71. // These methods return true if selection processing is complete, false
  72. // otherwise. They are called from HandleSelectionNotify(), and take the same
  73. // arguments.
  74. bool HandleSelectionTargetsEvent(const x11::SelectionNotifyEvent& event,
  75. int format,
  76. int item_count,
  77. const void* data);
  78. bool HandleSelectionStringEvent(const x11::SelectionNotifyEvent& event,
  79. int format,
  80. int item_count,
  81. const void* data);
  82. // Notify the registered callback of new clipboard text.
  83. void NotifyClipboardText(const std::string& text);
  84. // These methods trigger the X server or selection owner to send back an
  85. // event containing the requested information.
  86. void RequestSelectionTargets(x11::Atom selection);
  87. void RequestSelectionString(x11::Atom selection, x11::Atom target);
  88. // Assert ownership of the specified |selection|.
  89. void AssertSelectionOwnership(x11::Atom selection);
  90. bool IsSelectionOwner(x11::Atom selection);
  91. // Stores the connection supplied to Init().
  92. raw_ptr<x11::Connection> connection_ = nullptr;
  93. // Window through which clipboard events are received, or BadValue if the
  94. // window could not be created.
  95. x11::Window clipboard_window_ = x11::Window::None;
  96. // Cached atoms for various strings, initialized during Init().
  97. x11::Atom clipboard_atom_ = x11::Atom::None;
  98. x11::Atom large_selection_atom_ = x11::Atom::None;
  99. x11::Atom selection_string_atom_ = x11::Atom::None;
  100. x11::Atom targets_atom_ = x11::Atom::None;
  101. x11::Atom timestamp_atom_ = x11::Atom::None;
  102. x11::Atom utf8_string_atom_ = x11::Atom::None;
  103. // The set of X selections owned by |clipboard_window_| (can be Primary or
  104. // Clipboard or both).
  105. std::set<x11::Atom> selections_owned_;
  106. // Clipboard content to return to other applications when |clipboard_window_|
  107. // owns a selection.
  108. std::string data_;
  109. // Stores the property to use for large transfers, or None if a large
  110. // transfer is not currently in-progress.
  111. x11::Atom large_selection_property_ = x11::Atom::None;
  112. // Remembers the start time of selection processing, and is set to null when
  113. // processing is complete. This is used to decide whether to begin processing
  114. // a new selection or continue with the current selection.
  115. base::TimeTicks get_selections_time_;
  116. // |callback| argument supplied to Init().
  117. ClipboardChangedCallback callback_;
  118. };
  119. } // namespace remoting
  120. #endif // REMOTING_HOST_LINUX_X_SERVER_CLIPBOARD_H_