clipboard_x11.cc 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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. #include "remoting/host/clipboard.h"
  5. #include <memory>
  6. #include "base/bind.h"
  7. #include "base/logging.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "remoting/host/linux/x_server_clipboard.h"
  10. #include "remoting/proto/event.pb.h"
  11. #include "remoting/protocol/clipboard_stub.h"
  12. #include "ui/gfx/x/connection.h"
  13. #include "ui/gfx/x/xproto_types.h"
  14. namespace remoting {
  15. // This code is expected to be called on the desktop thread only.
  16. class ClipboardX11 : public Clipboard, public x11::EventObserver {
  17. public:
  18. ClipboardX11();
  19. ClipboardX11(const ClipboardX11&) = delete;
  20. ClipboardX11& operator=(const ClipboardX11&) = delete;
  21. ~ClipboardX11() override;
  22. void Init();
  23. // Clipboard interface.
  24. void Start(
  25. std::unique_ptr<protocol::ClipboardStub> client_clipboard) override;
  26. void InjectClipboardEvent(const protocol::ClipboardEvent& event) override;
  27. private:
  28. void OnClipboardChanged(const std::string& mime_type,
  29. const std::string& data);
  30. // x11::EventObserver:
  31. void OnEvent(const x11::Event& event) override;
  32. std::unique_ptr<protocol::ClipboardStub> client_clipboard_;
  33. // Underlying X11 clipboard implementation.
  34. XServerClipboard x_server_clipboard_;
  35. // Connection to the X server, used by |x_server_clipboard_|. This must only
  36. // be accessed on the input thread.
  37. raw_ptr<x11::Connection> connection_;
  38. };
  39. ClipboardX11::ClipboardX11() = default;
  40. ClipboardX11::~ClipboardX11() {
  41. if (connection_) {
  42. connection_->RemoveEventObserver(this);
  43. }
  44. }
  45. void ClipboardX11::Init() {
  46. connection_ = x11::Connection::Get();
  47. connection_->AddEventObserver(this);
  48. x_server_clipboard_.Init(
  49. connection_, base::BindRepeating(&ClipboardX11::OnClipboardChanged,
  50. base::Unretained(this)));
  51. }
  52. void ClipboardX11::Start(
  53. std::unique_ptr<protocol::ClipboardStub> client_clipboard) {
  54. client_clipboard_.swap(client_clipboard);
  55. }
  56. void ClipboardX11::InjectClipboardEvent(const protocol::ClipboardEvent& event) {
  57. x_server_clipboard_.SetClipboard(event.mime_type(), event.data());
  58. }
  59. void ClipboardX11::OnClipboardChanged(const std::string& mime_type,
  60. const std::string& data) {
  61. protocol::ClipboardEvent event;
  62. event.set_mime_type(mime_type);
  63. event.set_data(data);
  64. if (client_clipboard_.get()) {
  65. client_clipboard_->InjectClipboardEvent(event);
  66. }
  67. }
  68. void ClipboardX11::OnEvent(const x11::Event& event) {
  69. x_server_clipboard_.ProcessXEvent(event);
  70. }
  71. std::unique_ptr<Clipboard> Clipboard::Create() {
  72. auto clipboard = std::make_unique<ClipboardX11>();
  73. clipboard->Init();
  74. return clipboard;
  75. }
  76. } // namespace remoting