Home | History | Annotate | Download | only in protocol
      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/protocol/input_event_tracker.h"
      6 
      7 #include "base/logging.h"
      8 #include "remoting/proto/event.pb.h"
      9 
     10 namespace remoting {
     11 namespace protocol {
     12 
     13 InputEventTracker::InputEventTracker(InputStub* input_stub)
     14     : input_stub_(input_stub),
     15       mouse_pos_(SkIPoint::Make(0, 0)),
     16       mouse_button_state_(0) {
     17 }
     18 
     19 InputEventTracker::~InputEventTracker() {
     20 }
     21 
     22 bool InputEventTracker::IsKeyPressed(uint32 usb_keycode) const {
     23   return pressed_keys_.find(usb_keycode) != pressed_keys_.end();
     24 }
     25 
     26 int InputEventTracker::PressedKeyCount() const {
     27   return pressed_keys_.size();
     28 }
     29 
     30 void InputEventTracker::ReleaseAll() {
     31   std::set<uint32>::iterator i;
     32   for (i = pressed_keys_.begin(); i != pressed_keys_.end(); ++i) {
     33     KeyEvent event;
     34     event.set_pressed(false);
     35     event.set_usb_keycode(*i);
     36     input_stub_->InjectKeyEvent(event);
     37   }
     38   pressed_keys_.clear();
     39 
     40   for (int i = MouseEvent::BUTTON_UNDEFINED + 1;
     41        i < MouseEvent::BUTTON_MAX; ++i) {
     42     if (mouse_button_state_ & (1 << (i - 1))) {
     43       MouseEvent mouse;
     44 
     45       // TODO(wez): EventInjectors should cope with positionless events by
     46       // using the current cursor position, and we wouldn't set position here.
     47       mouse.set_x(mouse_pos_.x());
     48       mouse.set_y(mouse_pos_.y());
     49 
     50       mouse.set_button((MouseEvent::MouseButton)i);
     51       mouse.set_button_down(false);
     52       input_stub_->InjectMouseEvent(mouse);
     53     }
     54   }
     55   mouse_button_state_ = 0;
     56 }
     57 
     58 void InputEventTracker::InjectKeyEvent(const KeyEvent& event) {
     59   // We don't need to track the keyboard lock states of key down events.
     60   // Pressed keys will be released with |lock_states| set to 0.
     61   // The lock states of auto generated key up events don't matter as long as
     62   // we release all the pressed keys at blurring/disconnection time.
     63   if (event.has_pressed()) {
     64     if (event.has_usb_keycode()) {
     65       if (event.pressed()) {
     66         pressed_keys_.insert(event.usb_keycode());
     67       } else {
     68         pressed_keys_.erase(event.usb_keycode());
     69       }
     70     }
     71   }
     72   input_stub_->InjectKeyEvent(event);
     73 }
     74 
     75 void InputEventTracker::InjectMouseEvent(const MouseEvent& event) {
     76   if (event.has_x() && event.has_y()) {
     77     mouse_pos_ = SkIPoint::Make(event.x(), event.y());
     78   }
     79   if (event.has_button() && event.has_button_down()) {
     80     // Button values are defined in remoting/proto/event.proto.
     81     if (event.button() >= 1 && event.button() < MouseEvent::BUTTON_MAX) {
     82       uint32 button_change = 1 << (event.button() - 1);
     83       if (event.button_down()) {
     84         mouse_button_state_ |= button_change;
     85       } else {
     86         mouse_button_state_ &= ~button_change;
     87       }
     88     }
     89   }
     90   input_stub_->InjectMouseEvent(event);
     91 }
     92 
     93 }  // namespace protocol
     94 }  // namespace remoting
     95