diff options
author | garykac@google.com <garykac@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-20 00:34:57 +0000 |
---|---|---|
committer | garykac@google.com <garykac@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-20 00:34:57 +0000 |
commit | 4d37c874d917cc370e188cfdef05bb629388421a (patch) | |
tree | 08f68e3ef47406ae69209f489832fa8f1c76448e /remoting/client/x11_client.cc | |
parent | 0af395eb3fa7d33473b4239a7b637fc6a7ce0e98 (diff) | |
download | chromium_src-4d37c874d917cc370e188cfdef05bb629388421a.zip chromium_src-4d37c874d917cc370e188cfdef05bb629388421a.tar.gz chromium_src-4d37c874d917cc370e188cfdef05bb629388421a.tar.bz2 |
Refactor the client code for the X11 version.
Make ChromotingViews responsible for initializing themselves.
Move all x11-related code into X11View.
Create InputCapturer class manage client input capture.
BUG=none
TEST=ran Win host + X11 client
Review URL: http://codereview.chromium.org/2861047
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52973 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/client/x11_client.cc')
-rw-r--r-- | remoting/client/x11_client.cc | 259 |
1 files changed, 23 insertions, 236 deletions
diff --git a/remoting/client/x11_client.cc b/remoting/client/x11_client.cc index eeda70d..8d79f92 100644 --- a/remoting/client/x11_client.cc +++ b/remoting/client/x11_client.cc @@ -2,259 +2,46 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// This file implements a X11 chromoting client. +// This file implements a simple X11 chromoting client. #include <iostream> #include "base/at_exit.h" -#include "base/message_loop.h" -#include "base/stl_util-inl.h" -#include "base/task.h" -#include "base/waitable_event.h" +#include "remoting/client/chromoting_client.h" +#include "remoting/client/client_config.h" #include "remoting/client/client_util.h" -#include "remoting/client/host_connection.h" #include "remoting/client/jingle_host_connection.h" -#include "remoting/jingle_glue/jingle_thread.h" - -// Include Xlib at the end because it clashes with ClientMessage defined in -// the protocol buffer. -// x11_view.h also includes Xlib.h so put it behind all other headers but -// before Xlib.h #include "remoting/client/x11_view.h" -#include <X11/Xlib.h> - -using remoting::JingleHostConnection; -using remoting::JingleThread; - -namespace remoting { - -class X11Client : public HostConnection::HostEventCallback { - public: - X11Client(MessageLoop* loop, base::WaitableEvent* client_done) - : message_loop_(loop), - client_done_(client_done), - display_(NULL), - window_(0), - width_(0), - height_(0) { - } - - virtual ~X11Client() { - DCHECK(!display_); - DCHECK(!window_); - } - - //////////////////////////////////////////////////////////////////////////// - // HostConnection::EventHandler implementations. - virtual void HandleMessages(HostConnection* conn, - remoting::HostMessageList* messages) { - for (size_t i = 0; i < messages->size(); ++i) { - HostMessage* msg = (*messages)[i]; - if (msg->has_init_client()) { - message_loop_->PostTask( - FROM_HERE, NewRunnableMethod(this, &X11Client::DoInitClient, msg)); - } else if (msg->has_begin_update_stream()) { - message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, &X11Client::DoBeginUpdate, msg)); - } else if (msg->has_update_stream_packet()) { - message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, &X11Client::DoHandleUpdate, msg)); - } else if (msg->has_end_update_stream()) { - message_loop_->PostTask( - FROM_HERE, NewRunnableMethod(this, &X11Client::DoEndUpdate, msg)); - } else { - NOTREACHED() << "Unknown message received"; - } - } - // Assume we have processed all the messages. - messages->clear(); - } - - virtual void OnConnectionOpened(HostConnection* conn) { - std::cout << "Connection established." << std::endl; - } - - virtual void OnConnectionClosed(HostConnection* conn) { - std::cout << "Connection closed." << std::endl; - client_done_->Signal(); - } - - virtual void OnConnectionFailed(HostConnection* conn) { - std::cout << "Conection failed." << std::endl; - client_done_->Signal(); - } - - void InitX11() { - message_loop_->PostTask(FROM_HERE, - NewRunnableMethod(this, &X11Client::DoInitX11)); - } - - void DoInitX11() { - display_ = XOpenDisplay(NULL); - if (!display_) { - std::cout << "Error - cannot open display" << std::endl; - client_done_->Signal(); - return; - } - - // Get properties of the screen. - int screen = DefaultScreen(display_); - int root_window = RootWindow(display_, screen); - - // Creates the window. - window_ = XCreateSimpleWindow(display_, root_window, 1, 1, 640, 480, 0, - BlackPixel(display_, screen), - BlackPixel(display_, screen)); - DCHECK(window_); - XStoreName(display_, window_, "X11 Remoting"); - - // Specifies what kind of messages we want to receive. - XSelectInput(display_, window_, ExposureMask | ButtonPressMask); - XMapWindow(display_, window_); - } - - void DestroyX11() { - message_loop_->PostTask(FROM_HERE, - NewRunnableMethod(this, &X11Client::DoDestroyX11)); - } - - void DoDestroyX11() { - if (display_ && window_) { - // Shutdown the window system. - XDestroyWindow(display_, window_); - XCloseDisplay(display_); - display_ = NULL; - window_ = 0; - } - } - - private: - // This method is executed on the main loop. - void DoInitClient(HostMessage* msg) { - DCHECK_EQ(message_loop_, MessageLoop::current()); - DCHECK(msg->has_init_client()); - scoped_ptr<HostMessage> deleter(msg); - - // Saves the dimension and resize the window. - width_ = msg->init_client().width(); - height_ = msg->init_client().height(); - LOG(INFO) << "Init client received: " << width_ << "x" << height_; - XResizeWindow(display_, window_, width_, height_); +#include "remoting/client/x11_input_handler.h" - // Now construct the X11View that renders the remote desktop. - view_.reset(new X11View(display_, window_, width_, height_)); - - // Schedule the event handler to process the event queue of X11. - ScheduleX11EventHandler(); - } - - // The following methods are executed on the same thread as libjingle. - void DoBeginUpdate(HostMessage* msg) { - DCHECK_EQ(message_loop_, MessageLoop::current()); - DCHECK(msg->has_begin_update_stream()); - - view_->HandleBeginUpdateStream(msg); - } - - void DoHandleUpdate(HostMessage* msg) { - DCHECK_EQ(message_loop_, MessageLoop::current()); - DCHECK(msg->has_update_stream_packet()); - - view_->HandleUpdateStreamPacket(msg); - } - - void DoEndUpdate(HostMessage* msg) { - DCHECK_EQ(message_loop_, MessageLoop::current()); - DCHECK(msg->has_end_update_stream()); - - view_->HandleEndUpdateStream(msg); - } - - void DoProcessX11Events() { - DCHECK_EQ(message_loop_, MessageLoop::current()); - if (XPending(display_)) { - XEvent e; - XNextEvent(display_, &e); - if (e.type == Expose) { - // Tell the ChromotingView to paint again. - view_->Paint(); - } else if (e.type == ButtonPress) { - // TODO(hclam): Implement. - NOTIMPLEMENTED(); - } else { - // TODO(hclam): Implement. - NOTIMPLEMENTED(); - } - } - - // Schedule the next event handler. - ScheduleX11EventHandler(); - } - - void ScheduleX11EventHandler() { - // Schedule a delayed task to process X11 events in 10ms. - static const int kProcessEventsInterval = 10; - message_loop_->PostDelayedTask( - FROM_HERE, - NewRunnableMethod(this, &X11Client::DoProcessX11Events), - kProcessEventsInterval); - } - - MessageLoop* message_loop_; - base::WaitableEvent* client_done_; - - // Members used for display. - Display* display_; - Window window_; - - // Dimension of the window. They are initialized when InitClient message is - // received. - int width_; - int height_; - - scoped_ptr<ChromotingView> view_; - - DISALLOW_COPY_AND_ASSIGN(X11Client); -}; - -} // namespace remoting - -DISABLE_RUNNABLE_METHOD_REFCOUNT(remoting::X11Client); +void ClientQuit(MessageLoop* loop) { + loop->PostTask(FROM_HERE, new MessageLoop::QuitTask()); +} int main(int argc, char** argv) { base::AtExitManager at_exit; - std::string host_jid; - std::string username; - std::string auth_token; - if (!remoting::GetLoginInfo(argc, argv, &host_jid, &username, &auth_token)) { - std::cout << "Cannot obtain login info" << std::endl; + remoting::ClientConfig config; + if (!remoting::GetLoginInfoFromArgs(argc, argv, &config)) { + std::cout << "Unable to obtain login info" << std::endl; return 1; } - JingleThread network_thread; - network_thread.Start(); - - base::WaitableEvent client_done(false, false); - remoting::X11Client client(network_thread.message_loop(), &client_done); - JingleHostConnection connection(&network_thread); - connection.Connect(username, auth_token, host_jid, &client); - - client.InitX11(); - - // Wait until the main loop is done. - client_done.Wait(); - - connection.Disconnect(); + MessageLoop ui_loop; + remoting::ClientContext context; + remoting::JingleHostConnection connection(&context); + remoting::X11View view; + remoting::X11InputHandler input_handler(&context, &view); + remoting::ChromotingClient client(&config, &context, &connection, &view, + &input_handler, NewRunnableFunction(&ClientQuit, &ui_loop)); - client.DestroyX11(); + // Run the client on a new MessageLoop until + context.Start(); + client.Start(); + ui_loop.Run(); - // Quit the current message loop. - network_thread.message_loop()->PostTask(FROM_HERE, - new MessageLoop::QuitTask()); - network_thread.Stop(); + client.Stop(); + context.Stop(); return 0; } |