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