blob: fd88eed607204f6c223ec8ebfc11deb6e1be1453 [file] [log] [blame]
[email protected]6d17db92012-05-11 17:03:141// 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
5#include "remoting/host/clipboard.h"
6
dcheng0765c492016-04-06 22:41:537#include "base/memory/ptr_util.h"
[email protected]070ffb72012-09-27 00:24:498
9#include "base/bind.h"
fdoraycd80c412016-10-03 17:22:4110#include "base/files/file_descriptor_watcher_posix.h"
[email protected]6d17db92012-05-11 17:03:1411#include "base/logging.h"
avic5960f32015-12-22 22:49:4812#include "base/macros.h"
[email protected]070ffb72012-09-27 00:24:4913#include "remoting/host/linux/x_server_clipboard.h"
14#include "remoting/proto/event.pb.h"
15#include "remoting/protocol/clipboard_stub.h"
Daniel Bratellb40fc332017-12-04 10:28:2116#include "ui/gfx/x/x11.h"
[email protected]6d17db92012-05-11 17:03:1417
18namespace remoting {
19
[email protected]070ffb72012-09-27 00:24:4920// This code is expected to be called on the desktop thread only.
fdoraycd80c412016-10-03 17:22:4121class ClipboardX11 : public Clipboard {
[email protected]6d17db92012-05-11 17:03:1422 public:
[email protected]c9c94bad2013-04-29 17:45:1223 ClipboardX11();
dcheng440d8e1c2014-10-28 01:23:1524 ~ClipboardX11() override;
[email protected]6d17db92012-05-11 17:03:1425
[email protected]070ffb72012-09-27 00:24:4926 // Clipboard interface.
dcheng0765c492016-04-06 22:41:5327 void Start(
28 std::unique_ptr<protocol::ClipboardStub> client_clipboard) override;
dcheng440d8e1c2014-10-28 01:23:1529 void InjectClipboardEvent(const protocol::ClipboardEvent& event) override;
[email protected]6d17db92012-05-11 17:03:1430
31 private:
[email protected]070ffb72012-09-27 00:24:4932 void OnClipboardChanged(const std::string& mime_type,
33 const std::string& data);
34 void PumpXEvents();
35
dcheng0765c492016-04-06 22:41:5336 std::unique_ptr<protocol::ClipboardStub> client_clipboard_;
[email protected]070ffb72012-09-27 00:24:4937
[email protected]e2123b52012-11-17 14:19:4938 // Underlying X11 clipboard implementation.
[email protected]070ffb72012-09-27 00:24:4939 XServerClipboard x_server_clipboard_;
[email protected]e2123b52012-11-17 14:19:4940
41 // Connection to the X server, used by |x_server_clipboard_|. This is created
42 // and owned by this class.
[email protected]070ffb72012-09-27 00:24:4943 Display* display_;
44
[email protected]e2123b52012-11-17 14:19:4945 // Watcher used to handle X11 events from |display_|.
fdoraycd80c412016-10-03 17:22:4146 std::unique_ptr<base::FileDescriptorWatcher::Controller>
47 x_connection_watch_controller_;
[email protected]070ffb72012-09-27 00:24:4948
[email protected]c9c94bad2013-04-29 17:45:1249 DISALLOW_COPY_AND_ASSIGN(ClipboardX11);
[email protected]6d17db92012-05-11 17:03:1450};
51
[email protected]c9c94bad2013-04-29 17:45:1252ClipboardX11::ClipboardX11()
sergeyuc5f104b2015-01-09 19:33:2453 : display_(nullptr) {
[email protected]070ffb72012-09-27 00:24:4954}
55
[email protected]c9c94bad2013-04-29 17:45:1256ClipboardX11::~ClipboardX11() {
Wez72c6fc62019-02-08 20:04:4757 x_connection_watch_controller_ = nullptr;
sergeyu45f92d832015-02-19 01:24:1958 if (display_)
59 XCloseDisplay(display_);
[email protected]070ffb72012-09-27 00:24:4960}
61
[email protected]c9c94bad2013-04-29 17:45:1262void ClipboardX11::Start(
dcheng0765c492016-04-06 22:41:5363 std::unique_ptr<protocol::ClipboardStub> client_clipboard) {
[email protected]b0b72f112013-03-24 03:42:4264 // TODO(lambroslambrou): Share the X connection with InputInjector.
fdoraycd80c412016-10-03 17:22:4165 DCHECK(!display_);
sergeyuc5f104b2015-01-09 19:33:2466 display_ = XOpenDisplay(nullptr);
[email protected]070ffb72012-09-27 00:24:4967 if (!display_) {
68 LOG(ERROR) << "Couldn't open X display";
69 return;
70 }
71 client_clipboard_.swap(client_clipboard);
72
73 x_server_clipboard_.Init(display_,
[email protected]c9c94bad2013-04-29 17:45:1274 base::Bind(&ClipboardX11::OnClipboardChanged,
[email protected]070ffb72012-09-27 00:24:4975 base::Unretained(this)));
76
fdoraycd80c412016-10-03 17:22:4177 x_connection_watch_controller_ = base::FileDescriptorWatcher::WatchReadable(
[email protected]faea9d2d2013-04-30 03:18:4478 ConnectionNumber(display_),
fdoraycd80c412016-10-03 17:22:4179 base::Bind(&ClipboardX11::PumpXEvents, base::Unretained(this)));
[email protected]070ffb72012-09-27 00:24:4980 PumpXEvents();
[email protected]6d17db92012-05-11 17:03:1481}
82
[email protected]c9c94bad2013-04-29 17:45:1283void ClipboardX11::InjectClipboardEvent(
[email protected]6d17db92012-05-11 17:03:1484 const protocol::ClipboardEvent& event) {
[email protected]070ffb72012-09-27 00:24:4985 x_server_clipboard_.SetClipboard(event.mime_type(), event.data());
[email protected]6d17db92012-05-11 17:03:1486}
87
[email protected]c9c94bad2013-04-29 17:45:1288void ClipboardX11::OnClipboardChanged(const std::string& mime_type,
89 const std::string& data) {
[email protected]070ffb72012-09-27 00:24:4990 protocol::ClipboardEvent event;
91 event.set_mime_type(mime_type);
92 event.set_data(data);
93
94 if (client_clipboard_.get()) {
95 client_clipboard_->InjectClipboardEvent(event);
96 }
97}
98
[email protected]c9c94bad2013-04-29 17:45:1299void ClipboardX11::PumpXEvents() {
[email protected]070ffb72012-09-27 00:24:49100 DCHECK(display_);
101
102 while (XPending(display_)) {
103 XEvent event;
104 XNextEvent(display_, &event);
105 x_server_clipboard_.ProcessXEvent(&event);
106 }
[email protected]6d17db92012-05-11 17:03:14107}
108
dcheng0765c492016-04-06 22:41:53109std::unique_ptr<Clipboard> Clipboard::Create() {
110 return base::WrapUnique(new ClipboardX11());
[email protected]6d17db92012-05-11 17:03:14111}
112
113} // namespace remoting