diff options
author | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-29 17:45:12 +0000 |
---|---|---|
committer | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-29 17:45:12 +0000 |
commit | c9c94badff01963c313e77604ee838254e11240f (patch) | |
tree | b9ed6bd582b7ea4124741fe1011f4237f6659643 /remoting/host/clipboard_x11.cc | |
parent | 49e293a1ac5d94c0cbac0b49acb85a22dfea6c20 (diff) | |
download | chromium_src-c9c94badff01963c313e77604ee838254e11240f.zip chromium_src-c9c94badff01963c313e77604ee838254e11240f.tar.gz chromium_src-c9c94badff01963c313e77604ee838254e11240f.tar.bz2 |
Rationalize linux vs x11 in remoting
BUG=236170
TEST=None
R=ben@chromium.org
Review URL: https://codereview.chromium.org/14104006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@197073 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/host/clipboard_x11.cc')
-rw-r--r-- | remoting/host/clipboard_x11.cc | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/remoting/host/clipboard_x11.cc b/remoting/host/clipboard_x11.cc new file mode 100644 index 0000000..eb952c1 --- /dev/null +++ b/remoting/host/clipboard_x11.cc @@ -0,0 +1,131 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/host/clipboard.h" + +#include <X11/Xlib.h> + +#include "base/bind.h" +#include "base/logging.h" +#include "base/message_loop.h" +#include "remoting/host/linux/x_server_clipboard.h" +#include "remoting/proto/event.pb.h" +#include "remoting/protocol/clipboard_stub.h" + +namespace remoting { + +// This code is expected to be called on the desktop thread only. +class ClipboardX11 : public Clipboard, + public MessageLoopForIO::Watcher { + public: + ClipboardX11(); + virtual ~ClipboardX11(); + + // Clipboard interface. + virtual void Start( + scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; + virtual void InjectClipboardEvent( + const protocol::ClipboardEvent& event) OVERRIDE; + virtual void Stop() OVERRIDE; + + // MessageLoopForIO::Watcher interface. + virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; + virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE; + + private: + void OnClipboardChanged(const std::string& mime_type, + const std::string& data); + void PumpXEvents(); + + scoped_ptr<protocol::ClipboardStub> client_clipboard_; + + // Underlying X11 clipboard implementation. + XServerClipboard x_server_clipboard_; + + // Connection to the X server, used by |x_server_clipboard_|. This is created + // and owned by this class. + Display* display_; + + // Watcher used to handle X11 events from |display_|. + MessageLoopForIO::FileDescriptorWatcher x_connection_watcher_; + + DISALLOW_COPY_AND_ASSIGN(ClipboardX11); +}; + +ClipboardX11::ClipboardX11() + : display_(NULL) { +} + +ClipboardX11::~ClipboardX11() { + Stop(); +} + +void ClipboardX11::Start( + scoped_ptr<protocol::ClipboardStub> client_clipboard) { + // TODO(lambroslambrou): Share the X connection with InputInjector. + display_ = XOpenDisplay(NULL); + if (!display_) { + LOG(ERROR) << "Couldn't open X display"; + return; + } + client_clipboard_.swap(client_clipboard); + + x_server_clipboard_.Init(display_, + base::Bind(&ClipboardX11::OnClipboardChanged, + base::Unretained(this))); + + MessageLoopForIO::current()->WatchFileDescriptor( + ConnectionNumber(display_), true, MessageLoopForIO::WATCH_READ, + &x_connection_watcher_, this); + PumpXEvents(); +} + +void ClipboardX11::InjectClipboardEvent( + const protocol::ClipboardEvent& event) { + x_server_clipboard_.SetClipboard(event.mime_type(), event.data()); +} + +void ClipboardX11::Stop() { + client_clipboard_.reset(); + x_connection_watcher_.StopWatchingFileDescriptor(); + + if (display_) { + XCloseDisplay(display_); + display_ = NULL; + } +} + +void ClipboardX11::OnFileCanReadWithoutBlocking(int fd) { + PumpXEvents(); +} + +void ClipboardX11::OnFileCanWriteWithoutBlocking(int fd) { +} + +void ClipboardX11::OnClipboardChanged(const std::string& mime_type, + const std::string& data) { + protocol::ClipboardEvent event; + event.set_mime_type(mime_type); + event.set_data(data); + + if (client_clipboard_.get()) { + client_clipboard_->InjectClipboardEvent(event); + } +} + +void ClipboardX11::PumpXEvents() { + DCHECK(display_); + + while (XPending(display_)) { + XEvent event; + XNextEvent(display_, &event); + x_server_clipboard_.ProcessXEvent(&event); + } +} + +scoped_ptr<Clipboard> Clipboard::Create() { + return scoped_ptr<Clipboard>(new ClipboardX11()); +} + +} // namespace remoting |