blob: ec9b93ec0812d0ec158d12b8ad251935b787422c [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
[email protected]070ffb72012-09-27 00:24:497#include <X11/Xlib.h>
dcheng0765c492016-04-06 22:41:538
9#include "base/memory/ptr_util.h"
pkastingdea81dc32015-08-17 20:30:5710#undef Status // Xlib.h #defines this, which breaks protobuf headers.
[email protected]070ffb72012-09-27 00:24:4911
12#include "base/bind.h"
[email protected]6d17db92012-05-11 17:03:1413#include "base/logging.h"
avic5960f32015-12-22 22:49:4814#include "base/macros.h"
[email protected]f368eeb2013-07-17 23:53:3215#include "base/message_loop/message_loop.h"
[email protected]070ffb72012-09-27 00:24:4916#include "remoting/host/linux/x_server_clipboard.h"
17#include "remoting/proto/event.pb.h"
18#include "remoting/protocol/clipboard_stub.h"
[email protected]6d17db92012-05-11 17:03:1419
20namespace remoting {
21
[email protected]070ffb72012-09-27 00:24:4922// This code is expected to be called on the desktop thread only.
[email protected]c9c94bad2013-04-29 17:45:1223class ClipboardX11 : public Clipboard,
[email protected]faea9d2d2013-04-30 03:18:4424 public base::MessageLoopForIO::Watcher {
[email protected]6d17db92012-05-11 17:03:1425 public:
[email protected]c9c94bad2013-04-29 17:45:1226 ClipboardX11();
dcheng440d8e1c2014-10-28 01:23:1527 ~ClipboardX11() override;
[email protected]6d17db92012-05-11 17:03:1428
[email protected]070ffb72012-09-27 00:24:4929 // Clipboard interface.
dcheng0765c492016-04-06 22:41:5330 void Start(
31 std::unique_ptr<protocol::ClipboardStub> client_clipboard) override;
dcheng440d8e1c2014-10-28 01:23:1532 void InjectClipboardEvent(const protocol::ClipboardEvent& event) override;
[email protected]6d17db92012-05-11 17:03:1433
[email protected]070ffb72012-09-27 00:24:4934 // MessageLoopForIO::Watcher interface.
dcheng440d8e1c2014-10-28 01:23:1535 void OnFileCanReadWithoutBlocking(int fd) override;
36 void OnFileCanWriteWithoutBlocking(int fd) override;
[email protected]070ffb72012-09-27 00:24:4937
[email protected]6d17db92012-05-11 17:03:1438 private:
[email protected]070ffb72012-09-27 00:24:4939 void OnClipboardChanged(const std::string& mime_type,
40 const std::string& data);
41 void PumpXEvents();
42
dcheng0765c492016-04-06 22:41:5343 std::unique_ptr<protocol::ClipboardStub> client_clipboard_;
[email protected]070ffb72012-09-27 00:24:4944
[email protected]e2123b52012-11-17 14:19:4945 // Underlying X11 clipboard implementation.
[email protected]070ffb72012-09-27 00:24:4946 XServerClipboard x_server_clipboard_;
[email protected]e2123b52012-11-17 14:19:4947
48 // Connection to the X server, used by |x_server_clipboard_|. This is created
49 // and owned by this class.
[email protected]070ffb72012-09-27 00:24:4950 Display* display_;
51
[email protected]e2123b52012-11-17 14:19:4952 // Watcher used to handle X11 events from |display_|.
[email protected]faea9d2d2013-04-30 03:18:4453 base::MessageLoopForIO::FileDescriptorWatcher x_connection_watcher_;
[email protected]070ffb72012-09-27 00:24:4954
[email protected]c9c94bad2013-04-29 17:45:1255 DISALLOW_COPY_AND_ASSIGN(ClipboardX11);
[email protected]6d17db92012-05-11 17:03:1456};
57
[email protected]c9c94bad2013-04-29 17:45:1258ClipboardX11::ClipboardX11()
sergeyuc5f104b2015-01-09 19:33:2459 : display_(nullptr) {
[email protected]070ffb72012-09-27 00:24:4960}
61
[email protected]c9c94bad2013-04-29 17:45:1262ClipboardX11::~ClipboardX11() {
sergeyu45f92d832015-02-19 01:24:1963 if (display_)
64 XCloseDisplay(display_);
[email protected]070ffb72012-09-27 00:24:4965}
66
[email protected]c9c94bad2013-04-29 17:45:1267void ClipboardX11::Start(
dcheng0765c492016-04-06 22:41:5368 std::unique_ptr<protocol::ClipboardStub> client_clipboard) {
[email protected]b0b72f112013-03-24 03:42:4269 // TODO(lambroslambrou): Share the X connection with InputInjector.
sergeyuc5f104b2015-01-09 19:33:2470 display_ = XOpenDisplay(nullptr);
[email protected]070ffb72012-09-27 00:24:4971 if (!display_) {
72 LOG(ERROR) << "Couldn't open X display";
73 return;
74 }
75 client_clipboard_.swap(client_clipboard);
76
77 x_server_clipboard_.Init(display_,
[email protected]c9c94bad2013-04-29 17:45:1278 base::Bind(&ClipboardX11::OnClipboardChanged,
[email protected]070ffb72012-09-27 00:24:4979 base::Unretained(this)));
80
[email protected]faea9d2d2013-04-30 03:18:4481 base::MessageLoopForIO::current()->WatchFileDescriptor(
82 ConnectionNumber(display_),
83 true,
84 base::MessageLoopForIO::WATCH_READ,
85 &x_connection_watcher_,
86 this);
[email protected]070ffb72012-09-27 00:24:4987 PumpXEvents();
[email protected]6d17db92012-05-11 17:03:1488}
89
[email protected]c9c94bad2013-04-29 17:45:1290void ClipboardX11::InjectClipboardEvent(
[email protected]6d17db92012-05-11 17:03:1491 const protocol::ClipboardEvent& event) {
[email protected]070ffb72012-09-27 00:24:4992 x_server_clipboard_.SetClipboard(event.mime_type(), event.data());
[email protected]6d17db92012-05-11 17:03:1493}
94
[email protected]c9c94bad2013-04-29 17:45:1295void ClipboardX11::OnFileCanReadWithoutBlocking(int fd) {
[email protected]070ffb72012-09-27 00:24:4996 PumpXEvents();
97}
98
[email protected]c9c94bad2013-04-29 17:45:1299void ClipboardX11::OnFileCanWriteWithoutBlocking(int fd) {
[email protected]070ffb72012-09-27 00:24:49100}
101
[email protected]c9c94bad2013-04-29 17:45:12102void ClipboardX11::OnClipboardChanged(const std::string& mime_type,
103 const std::string& data) {
[email protected]070ffb72012-09-27 00:24:49104 protocol::ClipboardEvent event;
105 event.set_mime_type(mime_type);
106 event.set_data(data);
107
108 if (client_clipboard_.get()) {
109 client_clipboard_->InjectClipboardEvent(event);
110 }
111}
112
[email protected]c9c94bad2013-04-29 17:45:12113void ClipboardX11::PumpXEvents() {
[email protected]070ffb72012-09-27 00:24:49114 DCHECK(display_);
115
116 while (XPending(display_)) {
117 XEvent event;
118 XNextEvent(display_, &event);
119 x_server_clipboard_.ProcessXEvent(&event);
120 }
[email protected]6d17db92012-05-11 17:03:14121}
122
dcheng0765c492016-04-06 22:41:53123std::unique_ptr<Clipboard> Clipboard::Create() {
124 return base::WrapUnique(new ClipboardX11());
[email protected]6d17db92012-05-11 17:03:14125}
126
127} // namespace remoting