0

client-side wheel mouse support

BUG=none
TEST=manual


Review URL: http://codereview.chromium.org/6697024

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@105774 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
garykac@chromium.org
2011-10-17 06:37:25 +00:00
parent 867fd923c9
commit cd00992102
8 changed files with 73 additions and 16 deletions

@ -62,6 +62,16 @@ void InputHandler::SendMouseButtonEvent(bool button_down,
} }
} }
void InputHandler::SendMouseWheelEvent(int dx, int dy) {
protocol::InputStub* stub = connection_->input_stub();
if (stub) {
MouseEvent event;
event.set_wheel_offset_x(dx);
event.set_wheel_offset_y(dy);
stub->InjectMouseEvent(event);
}
}
void InputHandler::ReleaseAllKeys() { void InputHandler::ReleaseAllKeys() {
std::set<int> pressed_keys_copy = pressed_keys_; std::set<int> pressed_keys_copy = pressed_keys_;
std::set<int>::iterator i; std::set<int>::iterator i;

@ -36,6 +36,7 @@ class InputHandler {
void SendMouseMoveEvent(int x, int y); void SendMouseMoveEvent(int x, int y);
void SendMouseButtonEvent(bool down, void SendMouseButtonEvent(bool down,
protocol::MouseEvent::MouseButton button); protocol::MouseEvent::MouseButton button);
void SendMouseWheelEvent(int dx, int dy);
ClientContext* context_; ClientContext* context_;
protocol::ConnectionToHost* connection_; protocol::ConnectionToHost* connection_;

@ -258,6 +258,11 @@ bool ChromotingInstance::HandleInputEvent(const pp::InputEvent& event) {
return true; return true;
} }
case PP_INPUTEVENT_TYPE_WHEEL: {
pih->HandleMouseWheelEvent(pp::WheelInputEvent(event));
return true;
}
case PP_INPUTEVENT_TYPE_CONTEXTMENU: { case PP_INPUTEVENT_TYPE_CONTEXTMENU: {
// We need to return true here or else we'll get a local (plugin) context // We need to return true here or else we'll get a local (plugin) context
// menu instead of the mouseup event for the right click. // menu instead of the mouseup event for the right click.

@ -10,16 +10,15 @@
namespace remoting { namespace remoting {
using pp::KeyboardInputEvent;
using pp::MouseInputEvent;
using protocol::KeyEvent;
using protocol::MouseEvent; using protocol::MouseEvent;
PepperInputHandler::PepperInputHandler(ClientContext* context, PepperInputHandler::PepperInputHandler(ClientContext* context,
protocol::ConnectionToHost* connection, protocol::ConnectionToHost* connection,
PepperViewProxy* view) PepperViewProxy* view)
: InputHandler(context, connection, view), : InputHandler(context, connection, view),
pepper_view_(view) { pepper_view_(view),
wheel_ticks_x_(0),
wheel_ticks_y_(0) {
} }
PepperInputHandler::~PepperInputHandler() { PepperInputHandler::~PepperInputHandler() {
@ -78,4 +77,18 @@ void PepperInputHandler::HandleMouseButtonEvent(
} }
} }
void PepperInputHandler::HandleMouseWheelEvent(
const pp::WheelInputEvent& event) {
pp::FloatPoint ticks = event.GetTicks();
wheel_ticks_x_ += ticks.x();
wheel_ticks_y_ += ticks.y();
int ticks_x = static_cast<int>(wheel_ticks_x_);
int ticks_y = static_cast<int>(wheel_ticks_y_);
if (ticks_x != 0 || ticks_y != 0) {
wheel_ticks_x_ -= ticks_x;
wheel_ticks_y_ -= ticks_y;
SendMouseWheelEvent(ticks_x, ticks_y);
}
}
} // namespace remoting } // namespace remoting

@ -13,11 +13,6 @@ class MouseInputEvent;
class WheelInputEvent; class WheelInputEvent;
} }
namespace pp {
class KeyboardInputEvent;
class MouseInputEvent;
} // namespace pp
namespace remoting { namespace remoting {
class PepperViewProxy; class PepperViewProxy;
@ -37,10 +32,14 @@ class PepperInputHandler : public InputHandler {
void HandleMouseMoveEvent(const pp::MouseInputEvent& event); void HandleMouseMoveEvent(const pp::MouseInputEvent& event);
void HandleMouseButtonEvent(bool button_down, void HandleMouseButtonEvent(bool button_down,
const pp::MouseInputEvent& event); const pp::MouseInputEvent& event);
void HandleMouseWheelEvent(const pp::WheelInputEvent& event);
private: private:
PepperViewProxy* pepper_view_; PepperViewProxy* pepper_view_;
float wheel_ticks_x_;
float wheel_ticks_y_;
DISALLOW_COPY_AND_ASSIGN(PepperInputHandler); DISALLOW_COPY_AND_ASSIGN(PepperInputHandler);
}; };

@ -36,6 +36,8 @@ class EventExecutorLinux : public EventExecutor {
virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE;
private: private:
void InjectScrollWheelClicks(int button, int count);
MessageLoop* message_loop_; MessageLoop* message_loop_;
Capturer* capturer_; Capturer* capturer_;
@ -68,6 +70,16 @@ int MouseButtonToX11ButtonNumber(MouseEvent::MouseButton button) {
} }
} }
int ScrollWheelToX11ButtonNumber(int dx, int dy) {
// Horizontal scroll wheel.
if (dx != 0)
return (dx > 0 ? 6 : 7);
// Positive y-values are wheel scroll-up events (button 4), negative y-values
// are wheel scroll-down events (button 5).
return (dy > 0 ? 4 : 5);
}
// Hard-coded mapping from Virtual Key codes to X11 KeySyms. // Hard-coded mapping from Virtual Key codes to X11 KeySyms.
// This mapping is only valid if both client and host are using a // This mapping is only valid if both client and host are using a
// US English keyboard layout. // US English keyboard layout.
@ -309,6 +321,15 @@ void EventExecutorLinux::InjectKeyEvent(const KeyEvent& event) {
XFlush(display_); XFlush(display_);
} }
void EventExecutorLinux::InjectScrollWheelClicks(int button, int count) {
for (int i = 0; i < count; i++) {
// Generate a button-down and a button-up to simulate a wheel click.
XTestFakeButtonEvent(display_, button, true, CurrentTime);
XTestFakeButtonEvent(display_, button, false, CurrentTime);
}
XFlush(display_);
}
void EventExecutorLinux::InjectMouseEvent(const MouseEvent& event) { void EventExecutorLinux::InjectMouseEvent(const MouseEvent& event) {
if (MessageLoop::current() != message_loop_) { if (MessageLoop::current() != message_loop_) {
message_loop_->PostTask( message_loop_->PostTask(
@ -339,8 +360,7 @@ void EventExecutorLinux::InjectMouseEvent(const MouseEvent& event) {
int button_number = MouseButtonToX11ButtonNumber(event.button()); int button_number = MouseButtonToX11ButtonNumber(event.button());
if (button_number < 0) { if (button_number < 0) {
LOG(WARNING) << "Ignoring unknown button type: " LOG(WARNING) << "Ignoring unknown button type: " << event.button();
<< event.button();
return; return;
} }
@ -353,8 +373,15 @@ void EventExecutorLinux::InjectMouseEvent(const MouseEvent& event) {
XFlush(display_); XFlush(display_);
} }
if (event.has_wheel_offset_x() && event.has_wheel_offset_y()) { if (event.has_wheel_offset_y() && event.wheel_offset_y() != 0) {
NOTIMPLEMENTED() << "No scroll wheel support yet."; int dy = event.wheel_offset_y();
InjectScrollWheelClicks(ScrollWheelToX11ButtonNumber(0, dy),
(dy > 0) ? dy : -dy);
}
if (event.has_wheel_offset_x() && event.wheel_offset_x() != 0) {
int dx = event.wheel_offset_x();
InjectScrollWheelClicks(ScrollWheelToX11ButtonNumber(dx, 0),
(dx > 0) ? dx : -dx);
} }
} }

@ -127,12 +127,12 @@ void EventExecutorWin::HandleMouse(const MouseEvent& event) {
int dy = event.wheel_offset_y(); int dy = event.wheel_offset_y();
if (dx != 0) { if (dx != 0) {
wheel.mi.mouseData = dx; wheel.mi.mouseData = dx * WHEEL_DELTA;
wheel.mi.dwFlags = MOUSEEVENTF_HWHEEL; wheel.mi.dwFlags = MOUSEEVENTF_HWHEEL;
SendInput(1, &wheel, sizeof(INPUT)); SendInput(1, &wheel, sizeof(INPUT));
} }
if (dy != 0) { if (dy != 0) {
wheel.mi.mouseData = dy; wheel.mi.mouseData = dy * WHEEL_DELTA;
wheel.mi.dwFlags = MOUSEEVENTF_WHEEL; wheel.mi.dwFlags = MOUSEEVENTF_WHEEL;
SendInput(1, &wheel, sizeof(INPUT)); SendInput(1, &wheel, sizeof(INPUT));
} }

@ -11,7 +11,6 @@ option optimize_for = LITE_RUNTIME;
package remoting.protocol; package remoting.protocol;
// Defines a keyboard event. // Defines a keyboard event.
// NEXT ID: 3
message KeyEvent { message KeyEvent {
// The POSIX key code. // The POSIX key code.
required int32 keycode = 1; required int32 keycode = 1;
@ -34,6 +33,9 @@ message MouseEvent {
optional int32 y = 2; optional int32 y = 2;
// Mouse wheel information. // Mouse wheel information.
// These values encode the number of wheel 'ticks' (sometimes called
// 'clicks' although 'ticks' is the most common cross-platform term).
// Additional fields may be added later to support high-resolution devices.
optional int32 wheel_offset_x = 3; optional int32 wheel_offset_x = 3;
optional int32 wheel_offset_y = 4; optional int32 wheel_offset_y = 4;