15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/client/plugin/pepper_input_handler.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ppapi/cpp/image_data.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/input_event.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module_impl.h" 1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ppapi/cpp/mouse_cursor.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/point.h" 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/cpp/var.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/proto/event.pb.h" 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/events/keycodes/dom4/keycode_converter.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)PepperInputHandler::PepperInputHandler( 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) pp::Instance* instance) 2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : pp::MouseLock(instance), 2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) instance_(instance), 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) input_stub_(NULL), 2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) callback_factory_(this), 2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) has_focus_(false), 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) send_mouse_input_when_unfocused_(false), 2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) mouse_lock_state_(MouseLockDisallowed), 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wheel_delta_x_(0), 29558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch wheel_delta_y_(0), 30558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch wheel_ticks_x_(0), 31558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch wheel_ticks_y_(0) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PepperInputHandler::~PepperInputHandler() {} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper function to get the USB key code using the Dev InputEvent interface. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t GetUsbKeyCode(pp::KeyboardInputEvent pp_key_event) { 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Get the DOM3 |code| as a string. 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string codestr = pp_key_event.GetCode().AsString(); 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Convert the |code| string into a USB keycode. 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return ui::KeycodeConverter::CodeToUsbKeycode(codestr.c_str()); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PepperInputHandler::HandleInputEvent(const pp::InputEvent& event) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (event.GetType()) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_INPUTEVENT_TYPE_CONTEXTMENU: { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to return true here or else we'll get a local (plugin) context 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // menu instead of the mouseup event for the right click. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_INPUTEVENT_TYPE_KEYDOWN: 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_INPUTEVENT_TYPE_KEYUP: { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::KeyboardInputEvent pp_key_event(event); 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint32_t modifiers = event.GetModifiers(); 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint32_t lock_states = 0; 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (modifiers & PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY) 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch lock_states |= protocol::KeyEvent::LOCK_STATES_CAPSLOCK; 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (modifiers & PP_INPUTEVENT_MODIFIER_NUMLOCKKEY) 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch lock_states |= protocol::KeyEvent::LOCK_STATES_NUMLOCK; 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol::KeyEvent key_event; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_event.set_usb_keycode(GetUsbKeyCode(pp_key_event)); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_event.set_pressed(event.GetType() == PP_INPUTEVENT_TYPE_KEYDOWN); 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch key_event.set_lock_states(lock_states); 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (input_stub_) 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) input_stub_->InjectKeyEvent(key_event); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_INPUTEVENT_TYPE_MOUSEDOWN: 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_INPUTEVENT_TYPE_MOUSEUP: { 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!has_focus_ && !send_mouse_input_when_unfocused_) 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::MouseInputEvent pp_mouse_event(event); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol::MouseEvent mouse_event; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (pp_mouse_event.GetButton()) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_INPUTEVENT_MOUSEBUTTON_LEFT: 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mouse_event.set_button(protocol::MouseEvent::BUTTON_LEFT); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mouse_event.set_button(protocol::MouseEvent::BUTTON_MIDDLE); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_INPUTEVENT_MOUSEBUTTON_RIGHT: 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mouse_event.set_button(protocol::MouseEvent::BUTTON_RIGHT); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_INPUTEVENT_MOUSEBUTTON_NONE: 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mouse_event.has_button()) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_down = (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mouse_event.set_button_down(is_down); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mouse_event.set_x(pp_mouse_event.GetPosition().x()); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mouse_event.set_y(pp_mouse_event.GetPosition().y()); 10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Add relative movement if the mouse is locked. 10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (mouse_lock_state_ == MouseLockOn) { 10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pp::Point delta = pp_mouse_event.GetMovement(); 10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) mouse_event.set_delta_x(delta.x()); 10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) mouse_event.set_delta_y(delta.y()); 10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (input_stub_) 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) input_stub_->InjectMouseEvent(mouse_event); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_INPUTEVENT_TYPE_MOUSEMOVE: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_INPUTEVENT_TYPE_MOUSEENTER: 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_INPUTEVENT_TYPE_MOUSELEAVE: { 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!has_focus_ && !send_mouse_input_when_unfocused_) 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pp::MouseInputEvent pp_mouse_event(event); 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) protocol::MouseEvent mouse_event; 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) mouse_event.set_x(pp_mouse_event.GetPosition().x()); 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) mouse_event.set_y(pp_mouse_event.GetPosition().y()); 12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Add relative movement if the mouse is locked. 12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (mouse_lock_state_ == MouseLockOn) { 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) pp::Point delta = pp_mouse_event.GetMovement(); 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) mouse_event.set_delta_x(delta.x()); 12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) mouse_event.set_delta_y(delta.y()); 13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (input_stub_) 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) input_stub_->InjectMouseEvent(mouse_event); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_INPUTEVENT_TYPE_WHEEL: { 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!has_focus_ && !send_mouse_input_when_unfocused_) 139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pp::WheelInputEvent pp_wheel_event(event); 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Don't handle scroll-by-page events, for now. 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pp_wheel_event.GetScrollByPage()) 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 147558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Add this event to our accumulated sub-pixel deltas and clicks. 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pp::FloatPoint delta = pp_wheel_event.GetDelta(); 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) wheel_delta_x_ += delta.x(); 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) wheel_delta_y_ += delta.y(); 151558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch pp::FloatPoint ticks = pp_wheel_event.GetTicks(); 152558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch wheel_ticks_x_ += ticks.x(); 153558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch wheel_ticks_y_ += ticks.y(); 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 155558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // If there is at least a pixel's movement, emit an event. We don't 156558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // ever expect to accumulate one tick's worth of scrolling without 157558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // accumulating a pixel's worth at the same time, so this is safe. 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int delta_x = static_cast<int>(wheel_delta_x_); 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int delta_y = static_cast<int>(wheel_delta_y_); 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (delta_x != 0 || delta_y != 0) { 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) wheel_delta_x_ -= delta_x; 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) wheel_delta_y_ -= delta_y; 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) protocol::MouseEvent mouse_event; 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) mouse_event.set_wheel_delta_x(delta_x); 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) mouse_event.set_wheel_delta_y(delta_y); 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 167558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Always include the ticks in the event, even if insufficient pixel 168558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // scrolling has accumulated for a single tick. This informs hosts 169558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // that can't inject pixel-based scroll events that the client will 170558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // accumulate them into tick-based scrolling, which gives a better 171558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // overall experience than trying to do this host-side. 172558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch int ticks_x = static_cast<int>(wheel_ticks_x_); 173558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch int ticks_y = static_cast<int>(wheel_ticks_y_); 174558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch wheel_ticks_x_ -= ticks_x; 175558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch wheel_ticks_y_ -= ticks_y; 176558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch mouse_event.set_wheel_ticks_x(ticks_x); 177558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch mouse_event.set_wheel_ticks_y(ticks_y); 178558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (input_stub_) 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) input_stub_->InjectMouseEvent(mouse_event); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_INPUTEVENT_TYPE_CHAR: 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consume but ignore character input events. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: { 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) VLOG(0) << "Unhandled input event: " << event.GetType(); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PepperInputHandler::AllowMouseLock() { 19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK_EQ(mouse_lock_state_, MouseLockDisallowed); 20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) mouse_lock_state_ = MouseLockOff; 20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PepperInputHandler::DidChangeFocus(bool has_focus) { 20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) has_focus_ = has_focus; 20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (has_focus_) 20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RequestMouseLock(); 20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PepperInputHandler::SetMouseCursor(scoped_ptr<pp::ImageData> image, 21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const pp::Point& hotspot) { 21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) cursor_image_ = image.Pass(); 21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) cursor_hotspot_ = hotspot; 21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (mouse_lock_state_ != MouseLockDisallowed && !cursor_image_) { 21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RequestMouseLock(); 21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CancelMouseLock(); 21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PepperInputHandler::MouseLockLost() { 22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(mouse_lock_state_ == MouseLockOn || 22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) mouse_lock_state_ == MouseLockCancelling); 22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) mouse_lock_state_ = MouseLockOff; 22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) UpdateMouseCursor(); 22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PepperInputHandler::RequestMouseLock() { 23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Request mouse lock only if the plugin is focused, the host-supplied cursor 23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // is empty and no callback is pending. 23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (has_focus_ && !cursor_image_ && mouse_lock_state_ == MouseLockOff) { 23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) pp::CompletionCallback callback = 23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) callback_factory_.NewCallback(&PepperInputHandler::OnMouseLocked); 23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int result = pp::MouseLock::LockMouse(callback); 23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); 23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Hide cursor to avoid it becoming a black square (see crbug.com/285809). 23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) pp::MouseCursor::SetCursor(instance_, PP_MOUSECURSOR_TYPE_NONE); 24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) mouse_lock_state_ = MouseLockRequestPending; 24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PepperInputHandler::CancelMouseLock() { 24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) switch (mouse_lock_state_) { 24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case MouseLockDisallowed: 24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case MouseLockOff: 24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) UpdateMouseCursor(); 25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) break; 25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case MouseLockCancelling: 25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) break; 25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case MouseLockRequestPending: 25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The mouse lock request is pending. Delay UnlockMouse() call until 25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // the callback is called. 25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) mouse_lock_state_ = MouseLockCancelling; 25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) break; 26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case MouseLockOn: 26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) pp::MouseLock::UnlockMouse(); 26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Note that mouse-lock has been cancelled. We will continue to receive 26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // locked events until MouseLockLost() is called back. 26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) mouse_lock_state_ = MouseLockCancelling; 26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) break; 26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) default: 27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) NOTREACHED(); 27158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 27258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PepperInputHandler::UpdateMouseCursor() { 27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(mouse_lock_state_ == MouseLockDisallowed || 27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) mouse_lock_state_ == MouseLockOff); 27758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (cursor_image_) { 27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) pp::MouseCursor::SetCursor(instance_, PP_MOUSECURSOR_TYPE_CUSTOM, 28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *cursor_image_, 28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) cursor_hotspot_); 28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // If there is no cursor shape stored, either because the host never 28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // supplied one, or we were previously in mouse-lock mode, then use 28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // a standard arrow pointer. 28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) pp::MouseCursor::SetCursor(instance_, PP_MOUSECURSOR_TYPE_POINTER); 28758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PepperInputHandler::OnMouseLocked(int error) { 29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(mouse_lock_state_ == MouseLockRequestPending || 29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) mouse_lock_state_ == MouseLockCancelling); 29358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool should_cancel = (mouse_lock_state_ == MouseLockCancelling); 29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // See if the operation succeeded. 29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (error == PP_OK) { 29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) mouse_lock_state_ = MouseLockOn; 29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 30058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) mouse_lock_state_ = MouseLockOff; 30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) UpdateMouseCursor(); 30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Cancel as needed. 30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (should_cancel) 30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CancelMouseLock(); 30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 310