blob: dc0bd988c5924cd4fda404f4a5559e46368de82d [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>
8
9#include "base/bind.h"
[email protected]6d17db92012-05-11 17:03:1410#include "base/logging.h"
[email protected]f368eeb2013-07-17 23:53:3211#include "base/message_loop/message_loop.h"
[email protected]070ffb72012-09-27 00:24:4912#include "remoting/host/linux/x_server_clipboard.h"
13#include "remoting/proto/event.pb.h"
14#include "remoting/protocol/clipboard_stub.h"
[email protected]6d17db92012-05-11 17:03:1415
16namespace remoting {
17
[email protected]070ffb72012-09-27 00:24:4918// This code is expected to be called on the desktop thread only.
[email protected]c9c94bad2013-04-29 17:45:1219class ClipboardX11 : public Clipboard,
[email protected]faea9d2d2013-04-30 03:18:4420 public base::MessageLoopForIO::Watcher {
[email protected]6d17db92012-05-11 17:03:1421 public:
[email protected]c9c94bad2013-04-29 17:45:1222 ClipboardX11();
dcheng440d8e1c2014-10-28 01:23:1523 ~ClipboardX11() override;
[email protected]6d17db92012-05-11 17:03:1424
[email protected]070ffb72012-09-27 00:24:4925 // Clipboard interface.
dcheng440d8e1c2014-10-28 01:23:1526 void Start(scoped_ptr<protocol::ClipboardStub> client_clipboard) override;
27 void InjectClipboardEvent(const protocol::ClipboardEvent& event) override;
28 void Stop() override;
[email protected]6d17db92012-05-11 17:03:1429
[email protected]070ffb72012-09-27 00:24:4930 // MessageLoopForIO::Watcher interface.
dcheng440d8e1c2014-10-28 01:23:1531 void OnFileCanReadWithoutBlocking(int fd) override;
32 void OnFileCanWriteWithoutBlocking(int fd) override;
[email protected]070ffb72012-09-27 00:24:4933
[email protected]6d17db92012-05-11 17:03:1434 private:
[email protected]070ffb72012-09-27 00:24:4935 void OnClipboardChanged(const std::string& mime_type,
36 const std::string& data);
37 void PumpXEvents();
38
39 scoped_ptr<protocol::ClipboardStub> client_clipboard_;
40
[email protected]e2123b52012-11-17 14:19:4941 // Underlying X11 clipboard implementation.
[email protected]070ffb72012-09-27 00:24:4942 XServerClipboard x_server_clipboard_;
[email protected]e2123b52012-11-17 14:19:4943
44 // Connection to the X server, used by |x_server_clipboard_|. This is created
45 // and owned by this class.
[email protected]070ffb72012-09-27 00:24:4946 Display* display_;
47
[email protected]e2123b52012-11-17 14:19:4948 // Watcher used to handle X11 events from |display_|.
[email protected]faea9d2d2013-04-30 03:18:4449 base::MessageLoopForIO::FileDescriptorWatcher x_connection_watcher_;
[email protected]070ffb72012-09-27 00:24:4950
[email protected]c9c94bad2013-04-29 17:45:1251 DISALLOW_COPY_AND_ASSIGN(ClipboardX11);
[email protected]6d17db92012-05-11 17:03:1452};
53
[email protected]c9c94bad2013-04-29 17:45:1254ClipboardX11::ClipboardX11()
sergeyuc5f104b2015-01-09 19:33:2455 : display_(nullptr) {
[email protected]070ffb72012-09-27 00:24:4956}
57
[email protected]c9c94bad2013-04-29 17:45:1258ClipboardX11::~ClipboardX11() {
[email protected]070ffb72012-09-27 00:24:4959 Stop();
60}
61
[email protected]c9c94bad2013-04-29 17:45:1262void ClipboardX11::Start(
[email protected]7f44ba42012-05-31 20:26:2963 scoped_ptr<protocol::ClipboardStub> client_clipboard) {
[email protected]b0b72f112013-03-24 03:42:4264 // TODO(lambroslambrou): Share the X connection with InputInjector.
sergeyuc5f104b2015-01-09 19:33:2465 display_ = XOpenDisplay(nullptr);
[email protected]070ffb72012-09-27 00:24:4966 if (!display_) {
67 LOG(ERROR) << "Couldn't open X display";
68 return;
69 }
70 client_clipboard_.swap(client_clipboard);
71
72 x_server_clipboard_.Init(display_,
[email protected]c9c94bad2013-04-29 17:45:1273 base::Bind(&ClipboardX11::OnClipboardChanged,
[email protected]070ffb72012-09-27 00:24:4974 base::Unretained(this)));
75
[email protected]faea9d2d2013-04-30 03:18:4476 base::MessageLoopForIO::current()->WatchFileDescriptor(
77 ConnectionNumber(display_),
78 true,
79 base::MessageLoopForIO::WATCH_READ,
80 &x_connection_watcher_,
81 this);
[email protected]070ffb72012-09-27 00:24:4982 PumpXEvents();
[email protected]6d17db92012-05-11 17:03:1483}
84
[email protected]c9c94bad2013-04-29 17:45:1285void ClipboardX11::InjectClipboardEvent(
[email protected]6d17db92012-05-11 17:03:1486 const protocol::ClipboardEvent& event) {
[email protected]070ffb72012-09-27 00:24:4987 x_server_clipboard_.SetClipboard(event.mime_type(), event.data());
[email protected]6d17db92012-05-11 17:03:1488}
89
[email protected]c9c94bad2013-04-29 17:45:1290void ClipboardX11::Stop() {
[email protected]070ffb72012-09-27 00:24:4991 client_clipboard_.reset();
92 x_connection_watcher_.StopWatchingFileDescriptor();
93
94 if (display_) {
95 XCloseDisplay(display_);
sergeyuc5f104b2015-01-09 19:33:2496 display_ = nullptr;
[email protected]070ffb72012-09-27 00:24:4997 }
98}
99
[email protected]c9c94bad2013-04-29 17:45:12100void ClipboardX11::OnFileCanReadWithoutBlocking(int fd) {
[email protected]070ffb72012-09-27 00:24:49101 PumpXEvents();
102}
103
[email protected]c9c94bad2013-04-29 17:45:12104void ClipboardX11::OnFileCanWriteWithoutBlocking(int fd) {
[email protected]070ffb72012-09-27 00:24:49105}
106
[email protected]c9c94bad2013-04-29 17:45:12107void ClipboardX11::OnClipboardChanged(const std::string& mime_type,
108 const std::string& data) {
[email protected]070ffb72012-09-27 00:24:49109 protocol::ClipboardEvent event;
110 event.set_mime_type(mime_type);
111 event.set_data(data);
112
113 if (client_clipboard_.get()) {
114 client_clipboard_->InjectClipboardEvent(event);
115 }
116}
117
[email protected]c9c94bad2013-04-29 17:45:12118void ClipboardX11::PumpXEvents() {
[email protected]070ffb72012-09-27 00:24:49119 DCHECK(display_);
120
121 while (XPending(display_)) {
122 XEvent event;
123 XNextEvent(display_, &event);
124 x_server_clipboard_.ProcessXEvent(&event);
125 }
[email protected]6d17db92012-05-11 17:03:14126}
127
128scoped_ptr<Clipboard> Clipboard::Create() {
sergeyu2d690882014-10-01 02:36:43129 return make_scoped_ptr(new ClipboardX11());
[email protected]6d17db92012-05-11 17:03:14130}
131
132} // namespace remoting