summaryrefslogtreecommitdiffstats
path: root/remoting/client
diff options
context:
space:
mode:
authorgarykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-26 23:03:19 +0000
committergarykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-26 23:03:19 +0000
commit6730b450fb21fbb7560091b1943ed3be1c757852 (patch)
treec8c25191d6f5c6adc1a616d8bafb85d7c6094cda /remoting/client
parent234cd85cf6d9d4dd868c2a21bffe2ec575bb6ffc (diff)
downloadchromium_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.cc8
-rw-r--r--remoting/client/chromoting_view.h4
-rw-r--r--remoting/client/host_connection.h3
-rw-r--r--remoting/client/input_handler.cc69
-rw-r--r--remoting/client/input_handler.h19
-rw-r--r--remoting/client/jingle_host_connection.cc17
-rw-r--r--remoting/client/jingle_host_connection.h2
-rw-r--r--remoting/client/plugin/chromoting_instance.cc10
-rw-r--r--remoting/client/plugin/pepper_input_handler.cc22
-rw-r--r--remoting/client/plugin/pepper_input_handler.h6
-rw-r--r--remoting/client/x11_input_handler.cc52
-rw-r--r--remoting/client/x11_input_handler.h3
-rw-r--r--remoting/client/x11_view.cc8
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;
}