pepper_input_handler.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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 wheel_ticks_x_(0), 21 wheel_ticks_y_(0) 22{ 23} 24 25PepperInputHandler::~PepperInputHandler() { 26} 27 28// Helper function to get the USB key code using the Dev InputEvent interface. 29uint32_t GetUsbKeyCode(pp::KeyboardInputEvent pp_key_event) { 30 const PPB_KeyboardInputEvent_Dev* key_event_interface = 31 reinterpret_cast<const PPB_KeyboardInputEvent_Dev*>( 32 pp::Module::Get()->GetBrowserInterface( 33 PPB_KEYBOARD_INPUT_EVENT_DEV_INTERFACE)); 34 if (!key_event_interface) 35 return 0; 36 return key_event_interface->GetUsbKeyCode(pp_key_event.pp_resource()); 37} 38 39bool PepperInputHandler::HandleInputEvent(const pp::InputEvent& event) { 40 switch (event.GetType()) { 41 case PP_INPUTEVENT_TYPE_CONTEXTMENU: { 42 // We need to return true here or else we'll get a local (plugin) context 43 // menu instead of the mouseup event for the right click. 44 return true; 45 } 46 47 case PP_INPUTEVENT_TYPE_KEYDOWN: 48 case PP_INPUTEVENT_TYPE_KEYUP: { 49 pp::KeyboardInputEvent pp_key_event(event); 50 protocol::KeyEvent key_event; 51 key_event.set_usb_keycode(GetUsbKeyCode(pp_key_event)); 52 key_event.set_pressed(event.GetType() == PP_INPUTEVENT_TYPE_KEYDOWN); 53 input_stub_->InjectKeyEvent(key_event); 54 return true; 55 } 56 57 case PP_INPUTEVENT_TYPE_MOUSEDOWN: 58 case PP_INPUTEVENT_TYPE_MOUSEUP: { 59 pp::MouseInputEvent pp_mouse_event(event); 60 protocol::MouseEvent mouse_event; 61 switch (pp_mouse_event.GetButton()) { 62 case PP_INPUTEVENT_MOUSEBUTTON_LEFT: 63 mouse_event.set_button(protocol::MouseEvent::BUTTON_LEFT); 64 break; 65 case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE: 66 mouse_event.set_button(protocol::MouseEvent::BUTTON_MIDDLE); 67 break; 68 case PP_INPUTEVENT_MOUSEBUTTON_RIGHT: 69 mouse_event.set_button(protocol::MouseEvent::BUTTON_RIGHT); 70 break; 71 case PP_INPUTEVENT_MOUSEBUTTON_NONE: 72 break; 73 } 74 if (mouse_event.has_button()) { 75 bool is_down = (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN); 76 mouse_event.set_button_down(is_down); 77 mouse_event.set_x(pp_mouse_event.GetPosition().x()); 78 mouse_event.set_y(pp_mouse_event.GetPosition().y()); 79 input_stub_->InjectMouseEvent(mouse_event); 80 } 81 return true; 82 } 83 84 case PP_INPUTEVENT_TYPE_MOUSEMOVE: 85 case PP_INPUTEVENT_TYPE_MOUSEENTER: 86 case PP_INPUTEVENT_TYPE_MOUSELEAVE: { 87 pp::MouseInputEvent pp_mouse_event(event); 88 protocol::MouseEvent mouse_event; 89 mouse_event.set_x(pp_mouse_event.GetPosition().x()); 90 mouse_event.set_y(pp_mouse_event.GetPosition().y()); 91 input_stub_->InjectMouseEvent(mouse_event); 92 return true; 93 } 94 95 case PP_INPUTEVENT_TYPE_WHEEL: { 96 pp::WheelInputEvent pp_wheel_event(event); 97 98 // Don't handle scroll-by-page events, for now. 99 if (pp_wheel_event.GetScrollByPage()) 100 return false; 101 102 // Add this event to our accumulated sub-pixel deltas. 103 pp::FloatPoint delta = pp_wheel_event.GetDelta(); 104 wheel_delta_x_ += delta.x(); 105 wheel_delta_y_ += delta.y(); 106 107 // If there is at least a pixel's movement, emit an event. 108 int delta_x = static_cast<int>(wheel_delta_x_); 109 int delta_y = static_cast<int>(wheel_delta_y_); 110 if (delta_x != 0 || delta_y != 0) { 111 wheel_delta_x_ -= delta_x; 112 wheel_delta_y_ -= delta_y; 113 protocol::MouseEvent mouse_event; 114 mouse_event.set_wheel_delta_x(delta_x); 115 mouse_event.set_wheel_delta_y(delta_y); 116 117 // Add legacy wheel "tick" offsets to the event. 118 // TODO(wez): Remove this once all hosts support the new 119 // fields. See crbug.com/155668. 120#if defined(OS_WIN) 121 // Windows' standard value for WHEEL_DELTA. 122 const float kPixelsPerWheelTick = 120.0f; 123#elif defined(OS_MAC) 124 // From Source/WebKit/chromium/src/mac/WebInputFactory.mm. 125 const float kPixelsPerWheelTick = 40.0f; 126#else // OS_MAC 127 // From Source/WebKit/chromium/src/gtk/WebInputFactory.cc. 128 const float kPixelsPerWheelTick = 160.0f / 3.0f; 129#endif // OS_MAC 130 wheel_ticks_x_ += delta_x / kPixelsPerWheelTick; 131 wheel_ticks_y_ += delta_y / kPixelsPerWheelTick; 132 int ticks_x = static_cast<int>(wheel_ticks_x_); 133 int ticks_y = static_cast<int>(wheel_ticks_y_); 134 wheel_ticks_x_ -= ticks_x; 135 wheel_ticks_y_ -= ticks_y; 136 mouse_event.set_wheel_offset_x(ticks_x); 137 mouse_event.set_wheel_offset_y(ticks_y); 138 139 input_stub_->InjectMouseEvent(mouse_event); 140 } 141 return true; 142 } 143 144 case PP_INPUTEVENT_TYPE_CHAR: 145 // Consume but ignore character input events. 146 return true; 147 148 default: { 149 LOG(INFO) << "Unhandled input event: " << event.GetType(); 150 break; 151 } 152 } 153 154 return false; 155} 156 157} // namespace remoting 158