Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: remoting/host/clipboard_linux.cc

Issue 10909133: Implement clipboard for Chromoting Linux hosts. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add initial PumpEvents() Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | remoting/host/event_executor_linux.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/host/clipboard.h" 5 #include "remoting/host/clipboard.h"
6 6
7 #include <X11/Xlib.h>
8
9 #include "base/bind.h"
7 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/message_loop.h"
12 #include "base/message_pump_libevent.h"
13 #include "base/threading/thread.h"
14 #include "remoting/host/x_server_clipboard.h"
15 #include "remoting/proto/event.pb.h"
16 #include "remoting/protocol/clipboard_stub.h"
8 17
9 namespace remoting { 18 namespace remoting {
10 19
11 class ClipboardLinux : public Clipboard { 20 class ClipboardLinux : public Clipboard, base::MessagePumpLibevent::Watcher {
12 public: 21 public:
13 ClipboardLinux(); 22 ClipboardLinux();
23 ~ClipboardLinux();
Sergey Ulanov 2012/09/12 01:00:08 virtual
Lambros 2012/09/12 23:42:32 Done.
14 24
15 // Must be called on the UI thread. 25 // Must be called on the UI thread.
16 virtual void Start( 26 virtual void Start(
17 scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; 27 scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE;
18 virtual void InjectClipboardEvent( 28 virtual void InjectClipboardEvent(
19 const protocol::ClipboardEvent& event) OVERRIDE; 29 const protocol::ClipboardEvent& event) OVERRIDE;
20 virtual void Stop() OVERRIDE; 30 virtual void Stop() OVERRIDE;
21 31
22 private: 32 private:
33 void OnClipboardChanged(const std::string& mime_type,
34 const std::string& data);
35 void PumpEvents();
36
37 // base::MessagePumpLibevent::Watcher interface
38 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
39 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {}
Sergey Ulanov 2012/09/12 01:00:08 Better not to inline implementation of this method
Wez 2012/09/12 04:52:53 NOTREACHED seems overkill for a notification handl
Sergey Ulanov 2012/09/12 18:39:13 heh, really? http://codereview.chromium.org/109070
Lambros 2012/09/12 23:42:32 Done. Chrome has many examples both with and with
40
41 scoped_ptr<protocol::ClipboardStub> client_clipboard_;
42
43 XServerClipboard x_server_clipboard_;
44 Display* display_;
45 base::Thread x11_thread_;
Sergey Ulanov 2012/09/12 01:00:08 Do we really need to create a new thread just for
Lambros 2012/09/12 23:42:32 Sharing the X connection and thread with EventExec
Sergey Ulanov 2012/09/14 00:29:56 main_task_runner that is passed to EventExecutorLi
Lambros 2012/09/14 02:09:18 Done.
46
47 base::MessagePumpLibevent::FileDescriptorWatcher x_connection_watcher_;
48
23 DISALLOW_COPY_AND_ASSIGN(ClipboardLinux); 49 DISALLOW_COPY_AND_ASSIGN(ClipboardLinux);
24 }; 50 };
25 51
52 ClipboardLinux::ClipboardLinux()
53 : display_(NULL),
54 x11_thread_("Clipboard X11 thread") {
55 x11_thread_.StartWithOptions(base::Thread::Options(MessageLoop::TYPE_IO, 0));
56 }
57
58 ClipboardLinux::~ClipboardLinux() {
59 Stop();
60 x11_thread_.Stop();
61 }
62
26 void ClipboardLinux::Start( 63 void ClipboardLinux::Start(
27 scoped_ptr<protocol::ClipboardStub> client_clipboard) { 64 scoped_ptr<protocol::ClipboardStub> client_clipboard) {
28 NOTIMPLEMENTED(); 65 if (!x11_thread_.message_loop_proxy()->BelongsToCurrentThread()) {
66 // base::Unretained is safe, since the clipboard thread is owned by this
67 // object.
68 x11_thread_.message_loop_proxy()->PostTask(
69 FROM_HERE,
70 base::Bind(&ClipboardLinux::Start, base::Unretained(this),
71 base::Passed(client_clipboard.Pass())));
72 return;
73 }
74
75 display_ = XOpenDisplay(NULL);
76 if (!display_) {
77 LOG(ERROR) << "Couldn't open X display";
78 return;
79 }
80 client_clipboard_.swap(client_clipboard);
81
82 // base::Unretained is safe, since the clipboard thread is owned by this
83 // object, and this dtor resets |callback_|, so that no more clipboard
84 // changes are processed while stopping the thread.
85 x_server_clipboard_.Init(display_,
86 base::Bind(&ClipboardLinux::OnClipboardChanged,
87 base::Unretained(this)));
88
89 MessageLoopForIO::current()->WatchFileDescriptor(
90 ConnectionNumber(display_), true, MessageLoopForIO::WATCH_READ,
91 &x_connection_watcher_, this);
92 PumpEvents();
29 } 93 }
30 94
31 void ClipboardLinux::InjectClipboardEvent( 95 void ClipboardLinux::InjectClipboardEvent(
32 const protocol::ClipboardEvent& event) { 96 const protocol::ClipboardEvent& event) {
33 NOTIMPLEMENTED(); 97 if (!x11_thread_.message_loop_proxy()->BelongsToCurrentThread()) {
98 x11_thread_.message_loop_proxy()->PostTask(
99 FROM_HERE,
100 base::Bind(&ClipboardLinux::InjectClipboardEvent,
101 base::Unretained(this),
102 event));
103 return;
104 }
105
106 x_server_clipboard_.SetClipboard(event.mime_type(), event.data());
34 } 107 }
35 108
36 void ClipboardLinux::Stop() { 109 void ClipboardLinux::Stop() {
37 NOTIMPLEMENTED(); 110 if (!x11_thread_.message_loop_proxy()->BelongsToCurrentThread()) {
111 x11_thread_.message_loop_proxy()->PostTask(
112 FROM_HERE,
113 base::Bind(&ClipboardLinux::Stop, base::Unretained(this)));
114 return;
115 }
116
117 client_clipboard_.reset();
118 x_connection_watcher_.StopWatchingFileDescriptor();
119
120 if (display_) {
121 XCloseDisplay(display_);
122 display_ = NULL;
123 }
124 }
125
126 void ClipboardLinux::OnClipboardChanged(const std::string& mime_type,
127 const std::string& data) {
128 protocol::ClipboardEvent event;
129 event.set_mime_type(mime_type);
130 event.set_data(data);
131
132 if (client_clipboard_.get()) {
133 client_clipboard_->InjectClipboardEvent(event);
134 }
135 }
136
137 void ClipboardLinux::PumpEvents() {
138 DCHECK(display_);
139
140 while (XPending(display_)) {
141 XEvent event;
142 XNextEvent(display_, &event);
143 x_server_clipboard_.ProcessXEvent(&event);
144 }
145 }
146
147 void ClipboardLinux::OnFileCanReadWithoutBlocking(int fd) {
148 PumpEvents();
38 } 149 }
39 150
40 scoped_ptr<Clipboard> Clipboard::Create() { 151 scoped_ptr<Clipboard> Clipboard::Create() {
41 return scoped_ptr<Clipboard>(new ClipboardLinux()); 152 return scoped_ptr<Clipboard>(new ClipboardLinux());
42 } 153 }
43 154
44 } // namespace remoting 155 } // namespace remoting
OLDNEW
« no previous file with comments | « no previous file | remoting/host/event_executor_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698