This source file includes following definitions.
- wheel_ticks_y_
- GetUsbKeyCode
- HandleInputEvent
- AllowMouseLock
- DidChangeFocus
- SetMouseCursor
- MouseLockLost
- RequestMouseLock
- CancelMouseLock
- UpdateMouseCursor
- OnMouseLocked
#include "remoting/client/plugin/pepper_input_handler.h"
#include "base/logging.h"
#include "ppapi/cpp/image_data.h"
#include "ppapi/cpp/input_event.h"
#include "ppapi/cpp/module_impl.h"
#include "ppapi/cpp/mouse_cursor.h"
#include "ppapi/cpp/point.h"
#include "ppapi/cpp/var.h"
#include "remoting/proto/event.pb.h"
#include "ui/events/keycodes/dom4/keycode_converter.h"
namespace remoting {
PepperInputHandler::PepperInputHandler(
    pp::Instance* instance,
    protocol::InputStub* input_stub)
    : pp::MouseLock(instance),
      instance_(instance),
      input_stub_(input_stub),
      callback_factory_(this),
      has_focus_(false),
      mouse_lock_state_(MouseLockDisallowed),
      wheel_delta_x_(0),
      wheel_delta_y_(0),
      wheel_ticks_x_(0),
      wheel_ticks_y_(0) {
}
PepperInputHandler::~PepperInputHandler() {
}
uint32_t GetUsbKeyCode(pp::KeyboardInputEvent pp_key_event) {
  
  std::string codestr = pp_key_event.GetCode().AsString();
  
  ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance();
  return key_converter->CodeToUsbKeycode(codestr.c_str());
}
bool PepperInputHandler::HandleInputEvent(const pp::InputEvent& event) {
  switch (event.GetType()) {
    case PP_INPUTEVENT_TYPE_CONTEXTMENU: {
      
      
      return true;
    }
    case PP_INPUTEVENT_TYPE_KEYDOWN:
    case PP_INPUTEVENT_TYPE_KEYUP: {
      pp::KeyboardInputEvent pp_key_event(event);
      uint32_t modifiers = event.GetModifiers();
      uint32_t lock_states = 0;
      if (modifiers & PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY)
        lock_states |= protocol::KeyEvent::LOCK_STATES_CAPSLOCK;
      if (modifiers & PP_INPUTEVENT_MODIFIER_NUMLOCKKEY)
        lock_states |= protocol::KeyEvent::LOCK_STATES_NUMLOCK;
      protocol::KeyEvent key_event;
      key_event.set_usb_keycode(GetUsbKeyCode(pp_key_event));
      key_event.set_pressed(event.GetType() == PP_INPUTEVENT_TYPE_KEYDOWN);
      key_event.set_lock_states(lock_states);
      input_stub_->InjectKeyEvent(key_event);
      return true;
    }
    case PP_INPUTEVENT_TYPE_MOUSEDOWN:
    case PP_INPUTEVENT_TYPE_MOUSEUP: {
      pp::MouseInputEvent pp_mouse_event(event);
      protocol::MouseEvent mouse_event;
      switch (pp_mouse_event.GetButton()) {
        case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
          mouse_event.set_button(protocol::MouseEvent::BUTTON_LEFT);
          break;
        case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE:
          mouse_event.set_button(protocol::MouseEvent::BUTTON_MIDDLE);
          break;
        case PP_INPUTEVENT_MOUSEBUTTON_RIGHT:
          mouse_event.set_button(protocol::MouseEvent::BUTTON_RIGHT);
          break;
        case PP_INPUTEVENT_MOUSEBUTTON_NONE:
          break;
      }
      if (mouse_event.has_button()) {
        bool is_down = (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN);
        mouse_event.set_button_down(is_down);
        mouse_event.set_x(pp_mouse_event.GetPosition().x());
        mouse_event.set_y(pp_mouse_event.GetPosition().y());
        
        if (mouse_lock_state_ == MouseLockOn) {
          pp::Point delta = pp_mouse_event.GetMovement();
          mouse_event.set_delta_x(delta.x());
          mouse_event.set_delta_y(delta.y());
        }
        input_stub_->InjectMouseEvent(mouse_event);
      }
      return true;
    }
    case PP_INPUTEVENT_TYPE_MOUSEMOVE:
    case PP_INPUTEVENT_TYPE_MOUSEENTER:
    case PP_INPUTEVENT_TYPE_MOUSELEAVE: {
      pp::MouseInputEvent pp_mouse_event(event);
      protocol::MouseEvent mouse_event;
      mouse_event.set_x(pp_mouse_event.GetPosition().x());
      mouse_event.set_y(pp_mouse_event.GetPosition().y());
      
      if (mouse_lock_state_ == MouseLockOn) {
        pp::Point delta = pp_mouse_event.GetMovement();
        mouse_event.set_delta_x(delta.x());
        mouse_event.set_delta_y(delta.y());
      }
      input_stub_->InjectMouseEvent(mouse_event);
      return true;
    }
    case PP_INPUTEVENT_TYPE_WHEEL: {
      pp::WheelInputEvent pp_wheel_event(event);
      
      if (pp_wheel_event.GetScrollByPage())
        return false;
      
      pp::FloatPoint delta = pp_wheel_event.GetDelta();
      wheel_delta_x_ += delta.x();
      wheel_delta_y_ += delta.y();
      pp::FloatPoint ticks = pp_wheel_event.GetTicks();
      wheel_ticks_x_ += ticks.x();
      wheel_ticks_y_ += ticks.y();
      
      
      
      int delta_x = static_cast<int>(wheel_delta_x_);
      int delta_y = static_cast<int>(wheel_delta_y_);
      if (delta_x != 0 || delta_y != 0) {
        wheel_delta_x_ -= delta_x;
        wheel_delta_y_ -= delta_y;
        protocol::MouseEvent mouse_event;
        mouse_event.set_wheel_delta_x(delta_x);
        mouse_event.set_wheel_delta_y(delta_y);
        
        
        
        
        
        int ticks_x = static_cast<int>(wheel_ticks_x_);
        int ticks_y = static_cast<int>(wheel_ticks_y_);
        wheel_ticks_x_ -= ticks_x;
        wheel_ticks_y_ -= ticks_y;
        mouse_event.set_wheel_ticks_x(ticks_x);
        mouse_event.set_wheel_ticks_y(ticks_y);
        input_stub_->InjectMouseEvent(mouse_event);
      }
      return true;
    }
    case PP_INPUTEVENT_TYPE_CHAR:
      
      return true;
    default: {
      VLOG(0) << "Unhandled input event: " << event.GetType();
      break;
    }
  }
  return false;
}
void PepperInputHandler::AllowMouseLock() {
  DCHECK_EQ(mouse_lock_state_, MouseLockDisallowed);
  mouse_lock_state_ = MouseLockOff;
}
void PepperInputHandler::DidChangeFocus(bool has_focus) {
  has_focus_ = has_focus;
  if (has_focus_)
    RequestMouseLock();
}
void PepperInputHandler::SetMouseCursor(scoped_ptr<pp::ImageData> image,
                                        const pp::Point& hotspot) {
  cursor_image_ = image.Pass();
  cursor_hotspot_ = hotspot;
  if (mouse_lock_state_ != MouseLockDisallowed && !cursor_image_) {
    RequestMouseLock();
  } else {
    CancelMouseLock();
  }
}
void PepperInputHandler::MouseLockLost() {
  DCHECK(mouse_lock_state_ == MouseLockOn ||
         mouse_lock_state_ == MouseLockCancelling);
  mouse_lock_state_ = MouseLockOff;
  UpdateMouseCursor();
}
void PepperInputHandler::RequestMouseLock() {
  
  
  if (has_focus_ && !cursor_image_ && mouse_lock_state_ == MouseLockOff) {
    pp::CompletionCallback callback =
        callback_factory_.NewCallback(&PepperInputHandler::OnMouseLocked);
    int result = pp::MouseLock::LockMouse(callback);
    DCHECK_EQ(result, PP_OK_COMPLETIONPENDING);
    
    pp::MouseCursor::SetCursor(instance_, PP_MOUSECURSOR_TYPE_NONE);
    mouse_lock_state_ = MouseLockRequestPending;
  }
}
void PepperInputHandler::CancelMouseLock() {
  switch (mouse_lock_state_) {
    case MouseLockDisallowed:
    case MouseLockOff:
      UpdateMouseCursor();
      break;
    case MouseLockCancelling:
      break;
    case MouseLockRequestPending:
      
      
      mouse_lock_state_ = MouseLockCancelling;
      break;
    case MouseLockOn:
      pp::MouseLock::UnlockMouse();
      
      
      mouse_lock_state_ = MouseLockCancelling;
      break;
    default:
      NOTREACHED();
  }
}
void PepperInputHandler::UpdateMouseCursor() {
  DCHECK(mouse_lock_state_ == MouseLockDisallowed ||
         mouse_lock_state_ == MouseLockOff);
  if (cursor_image_) {
    pp::MouseCursor::SetCursor(instance_, PP_MOUSECURSOR_TYPE_CUSTOM,
                               *cursor_image_,
                               cursor_hotspot_);
  } else {
    
    
    
    pp::MouseCursor::SetCursor(instance_, PP_MOUSECURSOR_TYPE_POINTER);
  }
}
void PepperInputHandler::OnMouseLocked(int error) {
  DCHECK(mouse_lock_state_ == MouseLockRequestPending ||
         mouse_lock_state_ == MouseLockCancelling);
  bool should_cancel = (mouse_lock_state_ == MouseLockCancelling);
  
  if (error == PP_OK) {
    mouse_lock_state_ = MouseLockOn;
  } else {
    mouse_lock_state_ = MouseLockOff;
    UpdateMouseCursor();
  }
  
  if (should_cancel)
    CancelMouseLock();
}
}