Infer appropriate GNU_STACK alignment for a shared library.
[chromium-blink-merge.git] / remoting / host / clipboard_x11.cc
blobdc0bd988c5924cd4fda404f4a5559e46368de82d
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.
5 #include "remoting/host/clipboard.h"
7 #include <X11/Xlib.h>
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/message_loop/message_loop.h"
12 #include "remoting/host/linux/x_server_clipboard.h"
13 #include "remoting/proto/event.pb.h"
14 #include "remoting/protocol/clipboard_stub.h"
16 namespace remoting {
18 // This code is expected to be called on the desktop thread only.
19 class ClipboardX11 : public Clipboard,
20 public base::MessageLoopForIO::Watcher {
21 public:
22 ClipboardX11();
23 ~ClipboardX11() override;
25 // Clipboard interface.
26 void Start(scoped_ptr<protocol::ClipboardStub> client_clipboard) override;
27 void InjectClipboardEvent(const protocol::ClipboardEvent& event) override;
28 void Stop() override;
30 // MessageLoopForIO::Watcher interface.
31 void OnFileCanReadWithoutBlocking(int fd) override;
32 void OnFileCanWriteWithoutBlocking(int fd) override;
34 private:
35 void OnClipboardChanged(const std::string& mime_type,
36 const std::string& data);
37 void PumpXEvents();
39 scoped_ptr<protocol::ClipboardStub> client_clipboard_;
41 // Underlying X11 clipboard implementation.
42 XServerClipboard x_server_clipboard_;
44 // Connection to the X server, used by |x_server_clipboard_|. This is created
45 // and owned by this class.
46 Display* display_;
48 // Watcher used to handle X11 events from |display_|.
49 base::MessageLoopForIO::FileDescriptorWatcher x_connection_watcher_;
51 DISALLOW_COPY_AND_ASSIGN(ClipboardX11);
54 ClipboardX11::ClipboardX11()
55 : display_(nullptr) {
58 ClipboardX11::~ClipboardX11() {
59 Stop();
62 void ClipboardX11::Start(
63 scoped_ptr<protocol::ClipboardStub> client_clipboard) {
64 // TODO(lambroslambrou): Share the X connection with InputInjector.
65 display_ = XOpenDisplay(nullptr);
66 if (!display_) {
67 LOG(ERROR) << "Couldn't open X display";
68 return;
70 client_clipboard_.swap(client_clipboard);
72 x_server_clipboard_.Init(display_,
73 base::Bind(&ClipboardX11::OnClipboardChanged,
74 base::Unretained(this)));
76 base::MessageLoopForIO::current()->WatchFileDescriptor(
77 ConnectionNumber(display_),
78 true,
79 base::MessageLoopForIO::WATCH_READ,
80 &x_connection_watcher_,
81 this);
82 PumpXEvents();
85 void ClipboardX11::InjectClipboardEvent(
86 const protocol::ClipboardEvent& event) {
87 x_server_clipboard_.SetClipboard(event.mime_type(), event.data());
90 void ClipboardX11::Stop() {
91 client_clipboard_.reset();
92 x_connection_watcher_.StopWatchingFileDescriptor();
94 if (display_) {
95 XCloseDisplay(display_);
96 display_ = nullptr;
100 void ClipboardX11::OnFileCanReadWithoutBlocking(int fd) {
101 PumpXEvents();
104 void ClipboardX11::OnFileCanWriteWithoutBlocking(int fd) {
107 void ClipboardX11::OnClipboardChanged(const std::string& mime_type,
108 const std::string& data) {
109 protocol::ClipboardEvent event;
110 event.set_mime_type(mime_type);
111 event.set_data(data);
113 if (client_clipboard_.get()) {
114 client_clipboard_->InjectClipboardEvent(event);
118 void ClipboardX11::PumpXEvents() {
119 DCHECK(display_);
121 while (XPending(display_)) {
122 XEvent event;
123 XNextEvent(display_, &event);
124 x_server_clipboard_.ProcessXEvent(&event);
128 scoped_ptr<Clipboard> Clipboard::Create() {
129 return make_scoped_ptr(new ClipboardX11());
132 } // namespace remoting