blob: ff7c1dfb9a9e636752b0383169d93f4cfff03707 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/protocol/input_event_tracker.h"
#include "base/logging.h"
#include "remoting/proto/event.pb.h"
namespace remoting {
namespace protocol {
InputEventTracker::InputEventTracker(InputStub* input_stub)
: input_stub_(input_stub),
mouse_button_state_(0) {
}
InputEventTracker::~InputEventTracker() {}
bool InputEventTracker::IsKeyPressed(uint32 usb_keycode) const {
return pressed_keys_.find(usb_keycode) != pressed_keys_.end();
}
int InputEventTracker::PressedKeyCount() const {
return pressed_keys_.size();
}
void InputEventTracker::ReleaseAll() {
// Release all pressed keys.
for (uint32 keycode : pressed_keys_) {
KeyEvent event;
event.set_pressed(false);
event.set_usb_keycode(keycode);
input_stub_->InjectKeyEvent(event);
}
pressed_keys_.clear();
// Release all mouse buttons.
for (int i = MouseEvent::BUTTON_UNDEFINED + 1;
i < MouseEvent::BUTTON_MAX; ++i) {
if (mouse_button_state_ & (1 << (i - 1))) {
MouseEvent mouse;
// TODO(wez): EventInjectors should cope with positionless events by
// using the current cursor position, and we wouldn't set position here.
mouse.set_x(mouse_pos_.x());
mouse.set_y(mouse_pos_.y());
mouse.set_button((MouseEvent::MouseButton)i);
mouse.set_button_down(false);
input_stub_->InjectMouseEvent(mouse);
}
}
mouse_button_state_ = 0;
// Cancel all active touch points.
if (!touch_point_ids_.empty()) {
TouchEvent cancel_all_touch_event;
cancel_all_touch_event.set_event_type(TouchEvent::TOUCH_POINT_CANCEL);
for (uint32 touch_point_id : touch_point_ids_) {
TouchEventPoint* point = cancel_all_touch_event.add_touch_points();
point->set_id(touch_point_id);
}
input_stub_->InjectTouchEvent(cancel_all_touch_event);
touch_point_ids_.clear();
}
DCHECK(touch_point_ids_.empty());
}
void InputEventTracker::InjectKeyEvent(const KeyEvent& event) {
// We don't need to track the keyboard lock states of key down events.
// Pressed keys will be released with |lock_states| set to 0.
// The lock states of auto generated key up events don't matter as long as
// we release all the pressed keys at blurring/disconnection time.
if (event.has_pressed()) {
if (event.has_usb_keycode()) {
if (event.pressed()) {
pressed_keys_.insert(event.usb_keycode());
} else {
pressed_keys_.erase(event.usb_keycode());
}
}
}
input_stub_->InjectKeyEvent(event);
}
void InputEventTracker::InjectTextEvent(const TextEvent& event) {
input_stub_->InjectTextEvent(event);
}
void InputEventTracker::InjectMouseEvent(const MouseEvent& event) {
if (event.has_x() && event.has_y()) {
mouse_pos_ = webrtc::DesktopVector(event.x(), event.y());
}
if (event.has_button() && event.has_button_down()) {
// Button values are defined in remoting/proto/event.proto.
if (event.button() >= 1 && event.button() < MouseEvent::BUTTON_MAX) {
uint32 button_change = 1 << (event.button() - 1);
if (event.button_down()) {
mouse_button_state_ |= button_change;
} else {
mouse_button_state_ &= ~button_change;
}
}
}
input_stub_->InjectMouseEvent(event);
}
void InputEventTracker::InjectTouchEvent(const TouchEvent& event) {
// We only need the IDs to cancel all touch points in ReleaseAll(). Other
// fields do not have to be tracked here as long as the host keeps track of
// them.
switch (event.event_type()) {
case TouchEvent::TOUCH_POINT_START:
for (const TouchEventPoint& touch_point : event.touch_points()) {
DCHECK(touch_point_ids_.find(touch_point.id()) ==
touch_point_ids_.end());
touch_point_ids_.insert(touch_point.id());
}
break;
case TouchEvent::TOUCH_POINT_END:
case TouchEvent::TOUCH_POINT_CANCEL:
for (const TouchEventPoint& touch_point : event.touch_points()) {
DCHECK(touch_point_ids_.find(touch_point.id()) !=
touch_point_ids_.end());
touch_point_ids_.erase(touch_point.id());
}
break;
default:
break;
}
input_stub_->InjectTouchEvent(event);
}
} // namespace protocol
} // namespace remoting
|