diff options
author | garykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-26 23:03:19 +0000 |
---|---|---|
committer | garykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-26 23:03:19 +0000 |
commit | 6730b450fb21fbb7560091b1943ed3be1c757852 (patch) | |
tree | c8c25191d6f5c6adc1a616d8bafb85d7c6094cda /remoting/client | |
parent | 234cd85cf6d9d4dd868c2a21bffe2ec575bb6ffc (diff) | |
download | chromium_src-6730b450fb21fbb7560091b1943ed3be1c757852.zip chromium_src-6730b450fb21fbb7560091b1943ed3be1c757852.tar.gz chromium_src-6730b450fb21fbb7560091b1943ed3be1c757852.tar.bz2 |
Add mouse event support to Chromoting client (Pepper and X11).
BUG=none
TEST=remoting unittests
Review URL: http://codereview.chromium.org/3175028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57598 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/client')
-rw-r--r-- | remoting/client/chromoting_view.cc | 8 | ||||
-rw-r--r-- | remoting/client/chromoting_view.h | 4 | ||||
-rw-r--r-- | remoting/client/host_connection.h | 3 | ||||
-rw-r--r-- | remoting/client/input_handler.cc | 69 | ||||
-rw-r--r-- | remoting/client/input_handler.h | 19 | ||||
-rw-r--r-- | remoting/client/jingle_host_connection.cc | 17 | ||||
-rw-r--r-- | remoting/client/jingle_host_connection.h | 2 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_instance.cc | 10 | ||||
-rw-r--r-- | remoting/client/plugin/pepper_input_handler.cc | 22 | ||||
-rw-r--r-- | remoting/client/plugin/pepper_input_handler.h | 6 | ||||
-rw-r--r-- | remoting/client/x11_input_handler.cc | 52 | ||||
-rw-r--r-- | remoting/client/x11_input_handler.h | 3 | ||||
-rw-r--r-- | remoting/client/x11_view.cc | 8 |
13 files changed, 206 insertions, 17 deletions
diff --git a/remoting/client/chromoting_view.cc b/remoting/client/chromoting_view.cc index f985669..95d2dfa 100644 --- a/remoting/client/chromoting_view.cc +++ b/remoting/client/chromoting_view.cc @@ -14,6 +14,14 @@ ChromotingView::ChromotingView() frame_height_(0) { } + +// TODO(garykac): This assumes a single screen. This will need to be adjusted +// to add support for mulitple monitors. +void ChromotingView::GetScreenSize(int* width, int* height) { + *width = frame_width_; + *height = frame_height_; +} + bool ChromotingView::SetupDecoder(UpdateStreamEncoding encoding) { if (encoding == EncodingInvalid) { LOG(ERROR) << "Cannot create encoder for EncodingInvalid"; diff --git a/remoting/client/chromoting_view.h b/remoting/client/chromoting_view.h index 0f19c09..d785b29 100644 --- a/remoting/client/chromoting_view.h +++ b/remoting/client/chromoting_view.h @@ -18,6 +18,10 @@ class ChromotingView { ChromotingView(); virtual ~ChromotingView() {} + // Get screen dimensions. + // TODO(garykac): This will need to be extended to support multi-monitors. + void GetScreenSize(int* width, int* height); + // Initialize the common structures for the view. virtual bool Initialize() = 0; diff --git a/remoting/client/host_connection.h b/remoting/client/host_connection.h index 8438fb9..7af8de3 100644 --- a/remoting/client/host_connection.h +++ b/remoting/client/host_connection.h @@ -43,6 +43,9 @@ class HostConnection { HostEventCallback* event_callback) = 0; virtual void Disconnect() = 0; + // Send an input event to the host. + virtual void SendEvent(const ChromotingClientMessage& msg) = 0; + protected: HostConnection() {} diff --git a/remoting/client/input_handler.cc b/remoting/client/input_handler.cc new file mode 100644 index 0000000..dd0fd7a --- /dev/null +++ b/remoting/client/input_handler.cc @@ -0,0 +1,69 @@ +// Copyright (c) 2010 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/client/input_handler.h" + +#include "remoting/client/chromoting_view.h" +#include "remoting/client/host_connection.h" + +namespace remoting { + +InputHandler::InputHandler(ClientContext* context, + HostConnection* connection, + ChromotingView* view) + : context_(context), + connection_(connection), + view_(view), + send_absolute_mouse_(true), + mouse_x_(0), + mouse_y_(0) { +} + +void InputHandler::SendMouseMoveEvent(int x, int y) { + ChromotingClientMessage msg; + + if (send_absolute_mouse_) { + MouseSetPositionEvent *event = msg.mutable_mouse_set_position_event(); + event->set_x(x); + event->set_y(y); + + int width, height; + view_->GetScreenSize(&width, &height); + event->set_width(width); + event->set_height(height); + + // TODO(garykac): Fix drift problem with relative mouse events and + // then re-add this line. + //send_absolute_mouse_ = false; + } else { + MouseMoveEvent *event = msg.mutable_mouse_move_event(); + int dx = x - mouse_x_; + int dy = y - mouse_y_; + if (dx == 0 && dy == 0) { + return; + } + event->set_offset_x(dx); + event->set_offset_y(dy); + } + // Record current mouse position. + mouse_x_ = x; + mouse_y_ = y; + + connection_->SendEvent(msg); +} + +void InputHandler::SendMouseButtonEvent(bool button_down, + MouseButton button) { + ChromotingClientMessage msg; + + if (button_down) { + msg.mutable_mouse_down_event()->set_button(button); + } else { + msg.mutable_mouse_up_event()->set_button(button); + } + + connection_->SendEvent(msg); +} + +} // namespace remoting diff --git a/remoting/client/input_handler.h b/remoting/client/input_handler.h index 9cbdd7d..ef9659d 100644 --- a/remoting/client/input_handler.h +++ b/remoting/client/input_handler.h @@ -7,6 +7,7 @@ #include "base/basictypes.h" #include "base/task.h" +#include "remoting/base/protocol/chromotocol.pb.h" namespace remoting { @@ -18,19 +19,29 @@ class InputHandler { public: InputHandler(ClientContext* context, HostConnection* connection, - ChromotingView* view) - : context_(context), - connection_(connection), - view_(view) {} + ChromotingView* view); virtual ~InputHandler() {} virtual void Initialize() = 0; protected: + void SendMouseMoveEvent(int x, int y); + void SendMouseButtonEvent(bool down, MouseButton button); + ClientContext* context_; HostConnection* connection_; ChromotingView* view_; + private: + // True if we should send the next mouse position as an absolute value rather + // than a relative value. After sending a single absolute mouse position, + // it will automatically switch back to sending relative mouse deltas. + bool send_absolute_mouse_; + + // Current (x,y) position of mouse pointer. + // This is the last value that we sent to the host. + int mouse_x_, mouse_y_; + DISALLOW_COPY_AND_ASSIGN(InputHandler); }; diff --git a/remoting/client/jingle_host_connection.cc b/remoting/client/jingle_host_connection.cc index 27de426..4892883 100644 --- a/remoting/client/jingle_host_connection.cc +++ b/remoting/client/jingle_host_connection.cc @@ -4,6 +4,7 @@ #include "base/message_loop.h" #include "remoting/base/constants.h" +#include "remoting/base/protocol_util.h" #include "remoting/client/client_config.h" #include "remoting/client/jingle_host_connection.h" #include "remoting/jingle_glue/jingle_thread.h" @@ -32,6 +33,22 @@ void JingleHostConnection::Disconnect() { NewRunnableMethod(this, &JingleHostConnection::DoDisconnect)); } +void JingleHostConnection::SendEvent(const ChromotingClientMessage& msg) { + if (message_loop() != MessageLoop::current()) { + message_loop()->PostTask( + FROM_HERE, + NewRunnableMethod(this, &JingleHostConnection::SendEvent, msg)); + return; + } + + // Don't send messages if we're disconnected. + if (jingle_channel_ == NULL) { + return; + } + + jingle_channel_->Write(SerializeAndFrameMessage(msg)); +} + void JingleHostConnection::OnStateChange(JingleChannel* channel, JingleChannel::State state) { DCHECK_EQ(message_loop(), MessageLoop::current()); diff --git a/remoting/client/jingle_host_connection.h b/remoting/client/jingle_host_connection.h index 7039a2b..885c63c 100644 --- a/remoting/client/jingle_host_connection.h +++ b/remoting/client/jingle_host_connection.h @@ -46,6 +46,8 @@ class JingleHostConnection : public HostConnection, HostEventCallback* event_callback); virtual void Disconnect(); + virtual void SendEvent(const ChromotingClientMessage& msg); + // JingleChannel::Callback interface. virtual void OnStateChange(JingleChannel* channel, JingleChannel::State state); diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc index 6cbc510..edde1f3 100644 --- a/remoting/client/plugin/chromoting_instance.cc +++ b/remoting/client/plugin/chromoting_instance.cc @@ -115,15 +115,23 @@ bool ChromotingInstance::CurrentlyOnPluginThread() const { bool ChromotingInstance::HandleEvent(const PP_Event& event) { DCHECK(CurrentlyOnPluginThread()); + PepperInputHandler* pih + = static_cast<PepperInputHandler*>(input_handler_.get()); + switch (event.type) { case PP_EVENT_TYPE_MOUSEDOWN: + pih->HandleMouseButtonEvent(true, event.u.mouse); + break; case PP_EVENT_TYPE_MOUSEUP: + pih->HandleMouseButtonEvent(false, event.u.mouse); + break; case PP_EVENT_TYPE_MOUSEMOVE: case PP_EVENT_TYPE_MOUSEENTER: case PP_EVENT_TYPE_MOUSELEAVE: - // client_->handle_mouse_event(npevent); + pih->HandleMouseMoveEvent(event.u.mouse); break; + case PP_EVENT_TYPE_KEYDOWN: case PP_EVENT_TYPE_CHAR: // client_->handle_char_event(npevent); break; diff --git a/remoting/client/plugin/pepper_input_handler.cc b/remoting/client/plugin/pepper_input_handler.cc index 96e8149..40f299e 100644 --- a/remoting/client/plugin/pepper_input_handler.cc +++ b/remoting/client/plugin/pepper_input_handler.cc @@ -16,7 +16,27 @@ PepperInputHandler::~PepperInputHandler() { } void PepperInputHandler::Initialize() { - // TODO(garykac): Implement this. +} + +void PepperInputHandler::HandleMouseMoveEvent(const PP_Event_Mouse& event) { + SendMouseMoveEvent(static_cast<int>(event.x), + static_cast<int>(event.y)); +} + +void PepperInputHandler::HandleMouseButtonEvent(bool button_down, + const PP_Event_Mouse& event) { + MouseButton button = MouseButtonUndefined; + if (event.button == PP_EVENT_MOUSEBUTTON_LEFT) { + button = MouseButtonLeft; + } else if (event.button == PP_EVENT_MOUSEBUTTON_MIDDLE) { + button = MouseButtonMiddle; + } else if (event.button == PP_EVENT_MOUSEBUTTON_RIGHT) { + button = MouseButtonRight; + } + + if (button != MouseButtonUndefined) { + SendMouseButtonEvent(button_down, button); + } } } // namespace remoting diff --git a/remoting/client/plugin/pepper_input_handler.h b/remoting/client/plugin/pepper_input_handler.h index 4db2f87..385cb8a 100644 --- a/remoting/client/plugin/pepper_input_handler.h +++ b/remoting/client/plugin/pepper_input_handler.h @@ -7,6 +7,8 @@ #include "remoting/client/input_handler.h" +#include "third_party/ppapi/c/pp_event.h" + namespace remoting { class PepperInputHandler : public InputHandler { @@ -18,6 +20,10 @@ class PepperInputHandler : public InputHandler { void Initialize(); + void HandleMouseMoveEvent(const PP_Event_Mouse& event); + void HandleMouseButtonEvent(bool button_down, + const PP_Event_Mouse& event); + private: DISALLOW_COPY_AND_ASSIGN(PepperInputHandler); }; diff --git a/remoting/client/x11_input_handler.cc b/remoting/client/x11_input_handler.cc index 900b492..f7900ca 100644 --- a/remoting/client/x11_input_handler.cc +++ b/remoting/client/x11_input_handler.cc @@ -6,7 +6,6 @@ #include "base/message_loop.h" #include "remoting/client/client_context.h" -#include "remoting/client/host_connection.h" #include "remoting/client/x11_view.h" #include "remoting/jingle_glue/jingle_thread.h" @@ -31,19 +30,33 @@ void X11InputHandler::Initialize() { void X11InputHandler::DoProcessX11Events() { DCHECK_EQ(context_->jingle_thread()->message_loop(), MessageLoop::current()); + Display* display = static_cast<X11View*>(view_)->display(); if (XPending(display)) { XEvent e; XNextEvent(display, &e); - if (e.type == Expose) { - // Tell the view to paint again. - view_->Paint(); - } else if (e.type == ButtonPress) { - // TODO(hclam): Implement. - NOTIMPLEMENTED(); - } else { - // TODO(hclam): Implement. - NOTIMPLEMENTED(); + switch (e.type) { + case Expose: + // Tell the view to paint again. + view_->Paint(); + break; + case KeyPress: + case KeyRelease: + // TODO(garykac) Implement. + break; + case ButtonPress: + HandleMouseButtonEvent(true, e.xbutton.button); + HandleMouseMoveEvent(e.xbutton.x, e.xbutton.y); + break; + case ButtonRelease: + HandleMouseButtonEvent(false, e.xbutton.button); + HandleMouseMoveEvent(e.xbutton.x, e.xbutton.y); + break; + case MotionNotify: + SendMouseMoveEvent(e.xmotion.x, e.xmotion.y); + break; + default: + LOG(WARNING) << "Unknown event type: " << e.type; } } @@ -60,4 +73,23 @@ void X11InputHandler::ScheduleX11EventHandler() { kProcessEventsInterval); } +void X11InputHandler::HandleMouseMoveEvent(int x, int y) { + SendMouseMoveEvent(x, y); +} + +void X11InputHandler::HandleMouseButtonEvent(bool button_down, int xbutton_id) { + MouseButton button = MouseButtonUndefined; + if (xbutton_id == 1) { + button = MouseButtonLeft; + } else if (xbutton_id == 2) { + button = MouseButtonMiddle; + } else if (xbutton_id == 3) { + button = MouseButtonRight; + } + + if (button != MouseButtonUndefined) { + SendMouseButtonEvent(button_down, button); + } +} + } // namespace remoting diff --git a/remoting/client/x11_input_handler.h b/remoting/client/x11_input_handler.h index 5d63ca3..eedaf54 100644 --- a/remoting/client/x11_input_handler.h +++ b/remoting/client/x11_input_handler.h @@ -27,6 +27,9 @@ class X11InputHandler : public InputHandler { void ScheduleX11EventHandler(); + void HandleMouseMoveEvent(int x, int y); + void HandleMouseButtonEvent(bool button_down, int xbutton_id); + DISALLOW_COPY_AND_ASSIGN(X11InputHandler); }; diff --git a/remoting/client/x11_view.cc b/remoting/client/x11_view.cc index e40891a..43ecd65 100644 --- a/remoting/client/x11_view.cc +++ b/remoting/client/x11_view.cc @@ -43,7 +43,13 @@ bool X11View::Initialize() { XStoreName(display_, window_, "X11 Remoting"); // Specifies what kind of messages we want to receive. - XSelectInput(display_, window_, ExposureMask | ButtonPressMask); + XSelectInput(display_, + window_, + ExposureMask + | KeyPressMask | KeyReleaseMask + | ButtonPressMask | ButtonReleaseMask + | PointerMotionMask); + XMapWindow(display_, window_); return true; } |