summaryrefslogtreecommitdiffstats
path: root/remoting/client/x11_client.cc
diff options
context:
space:
mode:
authorgarykac@google.com <garykac@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-20 00:34:57 +0000
committergarykac@google.com <garykac@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-20 00:34:57 +0000
commit4d37c874d917cc370e188cfdef05bb629388421a (patch)
tree08f68e3ef47406ae69209f489832fa8f1c76448e /remoting/client/x11_client.cc
parent0af395eb3fa7d33473b4239a7b637fc6a7ce0e98 (diff)
downloadchromium_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.cc259
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;
}