pepper_input_handler.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Use of this source code is governed by a BSD-style license that can be
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// found in the LICENSE file.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "remoting/client/plugin/pepper_input_handler.h"
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/logging.h"
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ppapi/c/dev/ppb_keyboard_input_event_dev.h"
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ppapi/cpp/input_event.h"
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ppapi/cpp/module_impl.h"
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ppapi/cpp/point.h"
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "remoting/proto/event.pb.h"
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace remoting {
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgPepperInputHandler::PepperInputHandler(protocol::InputStub* input_stub)
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    : input_stub_(input_stub),
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      wheel_delta_x_(0),
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      wheel_delta_y_(0) {
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgPepperInputHandler::~PepperInputHandler() {
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Helper function to get the USB key code using the Dev InputEvent interface.
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orguint32_t GetUsbKeyCode(pp::KeyboardInputEvent pp_key_event) {
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const PPB_KeyboardInputEvent_Dev* key_event_interface =
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      reinterpret_cast<const PPB_KeyboardInputEvent_Dev*>(
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          pp::Module::Get()->GetBrowserInterface(
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              PPB_KEYBOARD_INPUT_EVENT_DEV_INTERFACE));
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!key_event_interface)
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return key_event_interface->GetUsbKeyCode(pp_key_event.pp_resource());
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool PepperInputHandler::HandleInputEvent(const pp::InputEvent& event) {
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  switch (event.GetType()) {
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case PP_INPUTEVENT_TYPE_CONTEXTMENU: {
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // We need to return true here or else we'll get a local (plugin) context
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // menu instead of the mouseup event for the right click.
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case PP_INPUTEVENT_TYPE_KEYDOWN:
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case PP_INPUTEVENT_TYPE_KEYUP: {
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pp::KeyboardInputEvent pp_key_event(event);
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      protocol::KeyEvent key_event;
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      key_event.set_usb_keycode(GetUsbKeyCode(pp_key_event));
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      key_event.set_pressed(event.GetType() == PP_INPUTEVENT_TYPE_KEYDOWN);
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      input_stub_->InjectKeyEvent(key_event);
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case PP_INPUTEVENT_TYPE_MOUSEDOWN:
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case PP_INPUTEVENT_TYPE_MOUSEUP: {
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pp::MouseInputEvent pp_mouse_event(event);
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      protocol::MouseEvent mouse_event;
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (pp_mouse_event.GetButton()) {
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          mouse_event.set_button(protocol::MouseEvent::BUTTON_LEFT);
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          break;
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE:
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          mouse_event.set_button(protocol::MouseEvent::BUTTON_MIDDLE);
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          break;
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        case PP_INPUTEVENT_MOUSEBUTTON_RIGHT:
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          mouse_event.set_button(protocol::MouseEvent::BUTTON_RIGHT);
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          break;
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        case PP_INPUTEVENT_MOUSEBUTTON_NONE:
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          break;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mouse_event.has_button()) {
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        bool is_down = (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN);
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        mouse_event.set_button_down(is_down);
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        mouse_event.set_x(pp_mouse_event.GetPosition().x());
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        mouse_event.set_y(pp_mouse_event.GetPosition().y());
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        input_stub_->InjectMouseEvent(mouse_event);
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case PP_INPUTEVENT_TYPE_MOUSEMOVE:
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case PP_INPUTEVENT_TYPE_MOUSEENTER:
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case PP_INPUTEVENT_TYPE_MOUSELEAVE: {
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pp::MouseInputEvent pp_mouse_event(event);
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      protocol::MouseEvent mouse_event;
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mouse_event.set_x(pp_mouse_event.GetPosition().x());
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mouse_event.set_y(pp_mouse_event.GetPosition().y());
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      input_stub_->InjectMouseEvent(mouse_event);
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case PP_INPUTEVENT_TYPE_WHEEL: {
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pp::WheelInputEvent pp_wheel_event(event);
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Don't handle scroll-by-page events, for now.
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (pp_wheel_event.GetScrollByPage())
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return false;
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Add this event to our accumulated sub-pixel deltas.
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pp::FloatPoint delta = pp_wheel_event.GetDelta();
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      wheel_delta_x_ += delta.x();
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      wheel_delta_y_ += delta.y();
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // If there is at least a pixel's movement, emit an event.
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int delta_x = static_cast<int>(wheel_delta_x_);
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int delta_y = static_cast<int>(wheel_delta_y_);
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (delta_x != 0 || delta_y != 0) {
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        wheel_delta_x_ -= delta_x;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        wheel_delta_y_ -= delta_y;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        protocol::MouseEvent mouse_event;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        mouse_event.set_wheel_delta_x(delta_x);
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        mouse_event.set_wheel_delta_y(delta_y);
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        input_stub_->InjectMouseEvent(mouse_event);
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case PP_INPUTEVENT_TYPE_CHAR:
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Consume but ignore character input events.
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default: {
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LOG(INFO) << "Unhandled input event: " << event.GetType();
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return false;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}  // namespace remoting
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org