Mir

Merge lp:~andreas-pokorny/mir/combine-modifier-state-accross-devices into lp:mir

Proposed by Andreas Pokorny
Status: Superseded
Proposed branch: lp:~andreas-pokorny/mir/combine-modifier-state-accross-devices
Merge into: lp:mir
Diff against target: 1479 lines (+586/-279)
24 files modified
include/client/mir/events/event_builders.h (+2/-0)
include/platform/mir/input/event_builder.h (+5/-7)
include/test/mir/test/event_matchers.h (+8/-0)
src/client/events/event_builders.cpp (+22/-0)
src/client/symbols.map (+8/-0)
src/platforms/evdev/CMakeLists.txt (+2/-3)
src/platforms/evdev/button_utils.cpp (+37/-0)
src/platforms/evdev/button_utils.h (+35/-0)
src/platforms/evdev/libinput_device.cpp (+12/-34)
src/platforms/evdev/libinput_device.h (+0/-1)
src/platforms/mesa/server/x11/input/input_platform.cpp (+5/-37)
src/server/input/CMakeLists.txt (+2/-0)
src/server/input/default_event_builder.cpp (+12/-14)
src/server/input/default_event_builder.h (+5/-7)
src/server/input/default_input_device_hub.cpp (+22/-58)
src/server/input/default_input_device_hub.h (+6/-10)
src/server/input/input_modifier_utils.cpp (+4/-18)
src/server/input/input_modifier_utils.h (+2/-6)
src/server/input/seat.cpp (+153/-0)
src/server/input/seat.h (+72/-0)
tests/mir_test_framework/fake_input_device_impl.cpp (+3/-14)
tests/mir_test_framework/fake_input_device_impl.h (+0/-1)
tests/unit-tests/input/evdev/test_libinput_device.cpp (+23/-55)
tests/unit-tests/input/test_default_input_device_hub.cpp (+146/-14)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/combine-modifier-state-accross-devices
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Mir development team Pending
Review via email: mp+274372@code.launchpad.net

This proposal has been superseded by a proposal from 2015-10-14.

Commit message

Rework Modifier tracking to combine modifiers within

The platform is no longer in charge of the modifier. Instead the new input stack tracks it when the events are received. To reduce the complexity of InputDeviceHub this behavior and similar parts are moved to mir::input::Seat which represents a group of input devices that belong to a user session. (Currently all of them).

Collateral changes:
- allow changing the modifier of MirEvent after creation -> additional symbols to 'hidden' C++ client API
- reduction of EventBuilder interface
- moving of modifier utils to server

Description of the change

This fixes the problem that caused the revert of the input platform probing mp..

To post a comment you must log in.
3018. By Andreas Pokorny on 2015-10-14

diff reduction

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
3019. By Andreas Pokorny on 2015-10-14

remove unused modifier state

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
3020. By Andreas Pokorny on 2015-10-14

rename stanza

3021. By Andreas Pokorny on 2015-10-19

refine modifier tracking

Modifiers for Keyboard Events are local, while Modifiers for all the others are global.

3022. By Andreas Pokorny on 2015-10-20

merge lp:mir

3023. By Andreas Pokorny on 2015-10-26

merge lp:mir

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/client/mir/events/event_builders.h'
--- include/client/mir/events/event_builders.h 2015-10-02 04:27:33 +0000
+++ include/client/mir/events/event_builders.h 2015-10-14 12:41:48 +0000
@@ -58,6 +58,8 @@
58 uint64_t mac, MirKeyboardAction action, xkb_keysym_t key_code,58 uint64_t mac, MirKeyboardAction action, xkb_keysym_t key_code,
59 int scan_code, MirInputEventModifiers modifiers);59 int scan_code, MirInputEventModifiers modifiers);
6060
61void set_modifier(MirEvent& event, MirInputEventModifiers modifiers);
62
61// Deprecated version without mac63// Deprecated version without mac
62EventUPtr make_event(MirInputDeviceId device_id, std::chrono::nanoseconds timestamp,64EventUPtr make_event(MirInputDeviceId device_id, std::chrono::nanoseconds timestamp,
63 MirKeyboardAction action, xkb_keysym_t key_code,65 MirKeyboardAction action, xkb_keysym_t key_code,
6466
=== modified file 'include/platform/mir/input/event_builder.h'
--- include/platform/mir/input/event_builder.h 2015-08-24 23:25:00 +0000
+++ include/platform/mir/input/event_builder.h 2015-10-14 12:41:48 +0000
@@ -38,18 +38,16 @@
38 virtual ~EventBuilder() = default;38 virtual ~EventBuilder() = default;
39 using Timestamp = std::chrono::nanoseconds;39 using Timestamp = std::chrono::nanoseconds;
4040
41 virtual EventUPtr key_event(Timestamp timestamp, MirKeyboardAction action, xkb_keysym_t key_code, int scan_code,41 virtual EventUPtr key_event(Timestamp timestamp, MirKeyboardAction action, xkb_keysym_t key_code, int scan_code) = 0;
42 MirInputEventModifiers modifiers) = 0;
4342
44 virtual EventUPtr touch_event(Timestamp timestamp, MirInputEventModifiers modifiers) = 0;43 virtual EventUPtr touch_event(Timestamp timestamp) = 0;
45 virtual void add_touch(MirEvent& event, MirTouchId touch_id, MirTouchAction action, MirTouchTooltype tooltype,44 virtual void add_touch(MirEvent& event, MirTouchId touch_id, MirTouchAction action, MirTouchTooltype tooltype,
46 float x_axis_value, float y_axis_value, float pressure_value, float touch_major_value,45 float x_axis_value, float y_axis_value, float pressure_value, float touch_major_value,
47 float touch_minor_value, float size_value) = 0;46 float touch_minor_value, float size_value) = 0;
4847
49 virtual EventUPtr pointer_event(Timestamp timestamp, MirInputEventModifiers modifiers, MirPointerAction action,48 virtual EventUPtr pointer_event(Timestamp timestamp, MirPointerAction action, MirPointerButtons buttons_pressed,
50 MirPointerButtons buttons_pressed, float x_axis_value, float y_axis_value,49 float x_axis_value, float y_axis_value, float hscroll_value, float vscroll_value,
51 float hscroll_value, float vscroll_value, float relative_x_value,50 float relative_x_value, float relative_y_value) = 0;
52 float relative_y_value) = 0;
5351
54 virtual EventUPtr configuration_event(Timestamp timestamp, MirInputConfigurationAction action) = 0;52 virtual EventUPtr configuration_event(Timestamp timestamp, MirInputConfigurationAction action) = 0;
5553
5654
=== modified file 'include/test/mir/test/event_matchers.h'
--- include/test/mir/test/event_matchers.h 2015-10-13 16:25:36 +0000
+++ include/test/mir/test/event_matchers.h 2015-10-14 12:41:48 +0000
@@ -353,6 +353,14 @@
353 return true;353 return true;
354}354}
355355
356MATCHER_P(PointerEventWithModifiers, modifiers, "")
357{
358 auto pev = maybe_pointer_event(to_address(arg));
359 if (pev && mir_pointer_event_modifiers(pev) == modifiers)
360 return true;
361 return false;
362}
363
356MATCHER_P2(PointerEventWithDiff, dx, dy, "")364MATCHER_P2(PointerEventWithDiff, dx, dy, "")
357{365{
358 auto pev = maybe_pointer_event(to_address(arg));366 auto pev = maybe_pointer_event(to_address(arg));
359367
=== modified file 'src/client/events/event_builders.cpp'
--- src/client/events/event_builders.cpp 2015-10-07 12:07:00 +0000
+++ src/client/events/event_builders.cpp 2015-10-14 12:41:48 +0000
@@ -165,6 +165,28 @@
165 return make_event_uptr(e);165 return make_event_uptr(e);
166}166}
167167
168
169void mev::set_modifier(MirEvent& event, MirInputEventModifiers modifiers)
170{
171 switch(event.type)
172 {
173 case mir_event_type_key:
174 {
175 auto& kev = event.key;
176 kev.modifiers = modifiers;
177 break;
178 }
179 case mir_event_type_motion:
180 {
181 auto& mev = event.motion;
182 mev.modifiers = modifiers;
183 break;
184 }
185 default:
186 BOOST_THROW_EXCEPTION(std::invalid_argument("Input event modifiers are only valid for pointer, key and touch events."));
187 }
188}
189
168// Deprecated version without mac190// Deprecated version without mac
169mir::EventUPtr mev::make_event(MirInputDeviceId device_id, std::chrono::nanoseconds timestamp,191mir::EventUPtr mev::make_event(MirInputDeviceId device_id, std::chrono::nanoseconds timestamp,
170 MirKeyboardAction action, xkb_keysym_t key_code,192 MirKeyboardAction action, xkb_keysym_t key_code,
171193
=== modified file 'src/client/symbols.map'
--- src/client/symbols.map 2015-10-08 21:11:44 +0000
+++ src/client/symbols.map 2015-10-14 12:41:48 +0000
@@ -243,3 +243,11 @@
243 mir::operator???std::ostream???Mir*243 mir::operator???std::ostream???Mir*
244 }; 244 };
245};245};
246
247MIR_CLIENT_DETAIL_v0.18.0 {
248 global:
249 extern "C++" {
250 mir::events::set_modifier*;
251 };
252} MIR_CLIENT_DETAIL_9;
253
246254
=== modified file 'src/platforms/evdev/CMakeLists.txt'
--- src/platforms/evdev/CMakeLists.txt 2015-10-05 20:17:26 +0000
+++ src/platforms/evdev/CMakeLists.txt 2015-10-14 12:41:48 +0000
@@ -8,7 +8,7 @@
88
9add_library(mirevdevutilsobjects OBJECT9add_library(mirevdevutilsobjects OBJECT
10 evdev_device_detection.cpp10 evdev_device_detection.cpp
11 input_modifier_utils.cpp11 button_utils.cpp
12 )12 )
1313
14add_library(mirplatforminputevdevobjects OBJECT14add_library(mirplatforminputevdevobjects OBJECT
@@ -34,8 +34,7 @@
34)34)
3535
36target_link_libraries(mirplatforminputevdev36target_link_libraries(mirplatforminputevdev
37 mirplatform37 mirplatform # udev wrapper
38 mirclient
39 ${Boost_PROGRAM_OPTIONS_LIBRARY}38 ${Boost_PROGRAM_OPTIONS_LIBRARY}
40 ${LIBINPUT_LDFLAGS} ${LIBINPUT_LIBRARIES}39 ${LIBINPUT_LDFLAGS} ${LIBINPUT_LIBRARIES}
41)40)
4241
=== added file 'src/platforms/evdev/button_utils.cpp'
--- src/platforms/evdev/button_utils.cpp 1970-01-01 00:00:00 +0000
+++ src/platforms/evdev/button_utils.cpp 2015-10-14 12:41:48 +0000
@@ -0,0 +1,37 @@
1/*
2 * Copyright © 2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
17 */
18
19#include "button_utils.h"
20#include "boost/throw_exception.hpp"
21
22#include "linux/input.h"
23
24#include <stdexcept>
25
26MirPointerButton mir::input::evdev::to_pointer_button(int button)
27{
28 switch(button)
29 {
30 case BTN_LEFT: return mir_pointer_button_primary;
31 case BTN_RIGHT: return mir_pointer_button_secondary;
32 case BTN_MIDDLE: return mir_pointer_button_tertiary;
33 case BTN_BACK: return mir_pointer_button_back;
34 case BTN_FORWARD: return mir_pointer_button_forward;
35 }
36 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid mouse button"));
37}
038
=== added file 'src/platforms/evdev/button_utils.h'
--- src/platforms/evdev/button_utils.h 1970-01-01 00:00:00 +0000
+++ src/platforms/evdev/button_utils.h 2015-10-14 12:41:48 +0000
@@ -0,0 +1,35 @@
1/*
2 * Copyright © 2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
17 */
18
19#ifndef MIR_INPUT_EVDEV_BUTTON_UTILS_H_
20#define MIR_INPUT_EVDEV_BUTTON_UTILS_H_
21
22#include "mir_toolkit/event.h"
23
24namespace mir
25{
26namespace input
27{
28namespace evdev
29{
30MirPointerButton to_pointer_button(int button);
31}
32}
33}
34
35#endif
036
=== modified file 'src/platforms/evdev/libinput_device.cpp'
--- src/platforms/evdev/libinput_device.cpp 2015-10-07 15:32:10 +0000
+++ src/platforms/evdev/libinput_device.cpp 2015-10-14 12:41:48 +0000
@@ -19,8 +19,8 @@
19#include "libinput_device.h"19#include "libinput_device.h"
20#include "libinput_ptr.h"20#include "libinput_ptr.h"
21#include "libinput_device_ptr.h"21#include "libinput_device_ptr.h"
22#include "input_modifier_utils.h"
23#include "evdev_device_detection.h"22#include "evdev_device_detection.h"
23#include "button_utils.h"
2424
25#include "mir/input/input_sink.h"25#include "mir/input/input_sink.h"
26#include "mir/input/input_report.h"26#include "mir/input/input_report.h"
@@ -53,8 +53,7 @@
5353
54mie::LibInputDevice::LibInputDevice(std::shared_ptr<mi::InputReport> const& report, char const* path,54mie::LibInputDevice::LibInputDevice(std::shared_ptr<mi::InputReport> const& report, char const* path,
55 LibInputDevicePtr dev)55 LibInputDevicePtr dev)
56 : report{report}, accumulated_touch_event{nullptr, null_deleter}, pointer_pos{0, 0}, modifier_state{0},56 : report{report}, accumulated_touch_event{nullptr, null_deleter}, pointer_pos{0, 0}, button_state{0}
57 button_state{0}
58{57{
59 add_device_of_group(path, std::move(dev));58 add_device_of_group(path, std::move(dev));
60}59}
@@ -138,18 +137,7 @@
138 auto const code = libinput_event_keyboard_get_key(keyboard);137 auto const code = libinput_event_keyboard_get_key(keyboard);
139 report->received_event_from_kernel(time.count(), EV_KEY, code, action);138 report->received_event_from_kernel(time.count(), EV_KEY, code, action);
140139
141 auto event = builder->key_event(time,140 return builder->key_event(time, action, xkb_keysym_t{0}, code);
142 action,
143 xkb_keysym_t{0},
144 code,
145 mie::expand_modifiers(modifier_state));
146
147 if (action == mir_keyboard_action_down)
148 modifier_state |= mie::to_modifiers(code);
149 else
150 modifier_state &= ~mie::to_modifiers(code);
151
152 return event;
153}141}
154142
155mir::EventUPtr mie::LibInputDevice::convert_button_event(libinput_event_pointer* pointer)143mir::EventUPtr mie::LibInputDevice::convert_button_event(libinput_event_pointer* pointer)
@@ -172,11 +160,8 @@
172 else160 else
173 button_state = MirPointerButton(button_state & ~uint32_t(pointer_button));161 button_state = MirPointerButton(button_state & ~uint32_t(pointer_button));
174162
175 auto event = builder->pointer_event(time, mie::expand_modifiers(modifier_state), action, button_state,163 return builder->pointer_event(time, action, button_state, pointer_pos.x.as_float(), pointer_pos.y.as_float(),
176 pointer_pos.x.as_float(), pointer_pos.y.as_float(), hscroll_value,164 hscroll_value, vscroll_value, relative_x_value, relative_y_value);
177 vscroll_value, relative_x_value, relative_y_value);
178
179 return event;
180}165}
181166
182mir::EventUPtr mie::LibInputDevice::convert_motion_event(libinput_event_pointer* pointer)167mir::EventUPtr mie::LibInputDevice::convert_motion_event(libinput_event_pointer* pointer)
@@ -195,11 +180,8 @@
195180
196 sink->confine_pointer(pointer_pos);181 sink->confine_pointer(pointer_pos);
197182
198 auto event = builder->pointer_event(time, mie::expand_modifiers(modifier_state), action, button_state,183 return builder->pointer_event(time, action, button_state, pointer_pos.x.as_float(), pointer_pos.y.as_float(),
199 pointer_pos.x.as_float(), pointer_pos.y.as_float(), hscroll_value,184 hscroll_value, vscroll_value, movement.dx.as_float(), movement.dy.as_float());
200 vscroll_value, movement.dx.as_float(), movement.dy.as_float());
201
202 return event;
203}185}
204186
205mir::EventUPtr mie::LibInputDevice::convert_absolute_motion_event(libinput_event_pointer* pointer)187mir::EventUPtr mie::LibInputDevice::convert_absolute_motion_event(libinput_event_pointer* pointer)
@@ -219,10 +201,8 @@
219201
220 sink->confine_pointer(pointer_pos);202 sink->confine_pointer(pointer_pos);
221203
222 auto event = builder->pointer_event(time, mie::expand_modifiers(modifier_state), action, button_state,204 return builder->pointer_event(time, action, button_state, pointer_pos.x.as_float(), pointer_pos.y.as_float(),
223 pointer_pos.x.as_float(), pointer_pos.y.as_float(), hscroll_value,205 hscroll_value, vscroll_value, movement.dx.as_float(), movement.dy.as_float());
224 vscroll_value, movement.dx.as_float(), movement.dy.as_float());
225 return event;
226}206}
227207
228mir::EventUPtr mie::LibInputDevice::convert_axis_event(libinput_event_pointer* pointer)208mir::EventUPtr mie::LibInputDevice::convert_axis_event(libinput_event_pointer* pointer)
@@ -239,10 +219,8 @@
239 : 0.0f;219 : 0.0f;
240220
241 report->received_event_from_kernel(time.count(), EV_REL, 0, 0);221 report->received_event_from_kernel(time.count(), EV_REL, 0, 0);
242 auto event = builder->pointer_event(time, mie::expand_modifiers(modifier_state), action, button_state,222 return builder->pointer_event(time, action, button_state, pointer_pos.x.as_float(), pointer_pos.y.as_float(),
243 pointer_pos.x.as_float(), pointer_pos.y.as_float(), hscroll_value,223 hscroll_value, vscroll_value, relative_x_value, relative_y_value);
244 vscroll_value, relative_x_value, relative_y_value);
245 return event;
246}224}
247225
248MirEvent& mie::LibInputDevice::get_accumulated_touch_event(std::chrono::nanoseconds timestamp)226MirEvent& mie::LibInputDevice::get_accumulated_touch_event(std::chrono::nanoseconds timestamp)
@@ -250,7 +228,7 @@
250 if (!accumulated_touch_event)228 if (!accumulated_touch_event)
251 {229 {
252 report->received_event_from_kernel(timestamp.count(), EV_SYN, 0, 0);230 report->received_event_from_kernel(timestamp.count(), EV_SYN, 0, 0);
253 accumulated_touch_event = builder->touch_event(timestamp, mie::expand_modifiers(modifier_state));231 accumulated_touch_event = builder->touch_event(timestamp);
254 }232 }
255233
256 return *accumulated_touch_event;234 return *accumulated_touch_event;
257235
=== modified file 'src/platforms/evdev/libinput_device.h'
--- src/platforms/evdev/libinput_device.h 2015-10-07 15:32:10 +0000
+++ src/platforms/evdev/libinput_device.h 2015-10-14 12:41:48 +0000
@@ -84,7 +84,6 @@
8484
85 InputDeviceInfo info;85 InputDeviceInfo info;
86 mir::geometry::Point pointer_pos;86 mir::geometry::Point pointer_pos;
87 MirInputEventModifiers modifier_state;
88 MirPointerButtons button_state;87 MirPointerButtons button_state;
8988
90 struct ContactData89 struct ContactData
9190
=== modified file 'src/platforms/mesa/server/x11/input/input_platform.cpp'
--- src/platforms/mesa/server/x11/input/input_platform.cpp 2015-10-13 16:25:36 +0000
+++ src/platforms/mesa/server/x11/input/input_platform.cpp 2015-10-14 12:41:48 +0000
@@ -127,16 +127,6 @@
127#endif127#endif
128 XLookupString(&xkev, str, STRMAX, &keysym, NULL);128 XLookupString(&xkev, str, STRMAX, &keysym, NULL);
129129
130 MirInputEventModifiers modifiers = mir_input_event_modifier_none;
131 if (xkev.state & ShiftMask)
132 modifiers |= mir_input_event_modifier_shift;
133 if (xkev.state & ControlMask)
134 modifiers |= mir_input_event_modifier_ctrl;
135 if (xkev.state & Mod1Mask)
136 modifiers |= mir_input_event_modifier_alt;
137 if (xkev.state & Mod4Mask)
138 modifiers |= mir_input_event_modifier_meta;
139
140 auto event_time =130 auto event_time =
141 std::chrono::duration_cast<std::chrono::nanoseconds>(131 std::chrono::duration_cast<std::chrono::nanoseconds>(
142 std::chrono::milliseconds{xkev.time});132 std::chrono::milliseconds{xkev.time});
@@ -155,8 +145,7 @@
155 mir_keyboard_action_down :145 mir_keyboard_action_down :
156 mir_keyboard_action_up,146 mir_keyboard_action_up,
157 keysym,147 keysym,
158 xkev.keycode-8,148 xkev.keycode-8
159 modifiers
160 )149 )
161 );150 );
162 break;151 break;
@@ -177,16 +166,6 @@
177 xbev.subwindow, xbev.time, xbev.x, xbev.y, xbev.x_root,166 xbev.subwindow, xbev.time, xbev.x, xbev.y, xbev.x_root,
178 xbev.y_root, xbev.state, xbev.button, xbev.same_screen);167 xbev.y_root, xbev.state, xbev.button, xbev.same_screen);
179#endif168#endif
180 MirInputEventModifiers modifiers = mir_input_event_modifier_none;
181 if (xbev.state & ShiftMask)
182 modifiers |= mir_input_event_modifier_shift;
183 if (xbev.state & ControlMask)
184 modifiers |= mir_input_event_modifier_ctrl;
185 if (xbev.state & Mod1Mask)
186 modifiers |= mir_input_event_modifier_alt;
187 if (xbev.state & Mod4Mask)
188 modifiers |= mir_input_event_modifier_meta;
189
190 auto event_time =169 auto event_time =
191 std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds{xbev.time});170 std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds{xbev.time});
192171
@@ -207,13 +186,12 @@
207186
208#ifdef MIR_ON_X11_INPUT_VERBOSE187#ifdef MIR_ON_X11_INPUT_VERBOSE
209 mir::log_info("Mir button event : x=%d, y=%d, "188 mir::log_info("Mir button event : x=%d, y=%d, "
210 "buttons_pressed=0x%0X, modifiers=0x%0X, event_time=%" PRId64,189 "buttons_pressed=0x%0X, event_time=%" PRId64,
211 xbev.x, xbev.y, buttons_pressed, modifiers, event_time);190 xbev.x, xbev.y, buttons_pressed, event_time);
212#endif191#endif
213 core_pointer->sink->handle_input(192 core_pointer->sink->handle_input(
214 *core_pointer->builder->pointer_event(193 *core_pointer->builder->pointer_event(
215 event_time,194 event_time,
216 modifiers,
217 xbev.type == ButtonPress ?195 xbev.type == ButtonPress ?
218 mir_pointer_action_button_down :196 mir_pointer_action_button_down :
219 mir_pointer_action_button_up,197 mir_pointer_action_button_up,
@@ -242,15 +220,6 @@
242 xmev.root, xmev.subwindow, xmev.time, xmev.x, xmev.y, xmev.x_root,220 xmev.root, xmev.subwindow, xmev.time, xmev.x, xmev.y, xmev.x_root,
243 xmev.y_root, xmev.state, xmev.is_hint == NotifyNormal ? "no" : "yes", xmev.same_screen);221 xmev.y_root, xmev.state, xmev.is_hint == NotifyNormal ? "no" : "yes", xmev.same_screen);
244#endif222#endif
245 MirInputEventModifiers modifiers = mir_input_event_modifier_none;
246 if (xmev.state & ShiftMask)
247 modifiers |= mir_input_event_modifier_shift;
248 if (xmev.state & ControlMask)
249 modifiers |= mir_input_event_modifier_ctrl;
250 if (xmev.state & Mod1Mask)
251 modifiers |= mir_input_event_modifier_alt;
252 if (xmev.state & Mod4Mask)
253 modifiers |= mir_input_event_modifier_meta;
254223
255 auto event_time =224 auto event_time =
256 std::chrono::duration_cast<std::chrono::nanoseconds>(225 std::chrono::duration_cast<std::chrono::nanoseconds>(
@@ -270,13 +239,12 @@
270239
271#ifdef MIR_ON_X11_INPUT_VERBOSE240#ifdef MIR_ON_X11_INPUT_VERBOSE
272 mir::log_info("Mir pointer event : "241 mir::log_info("Mir pointer event : "
273 "x=%d, y=%d, buttons_pressed=0x%0X, modifiers=0x%0X, event_time=%" PRId64,242 "x=%d, y=%d, buttons_pressed=0x%0X, event_time=%" PRId64,
274 xmev.x, xmev.y, buttons_pressed, modifiers, event_time);243 xmev.x, xmev.y, buttons_pressed, event_time);
275#endif244#endif
276 core_pointer->sink->handle_input(245 core_pointer->sink->handle_input(
277 *core_pointer->builder->pointer_event(246 *core_pointer->builder->pointer_event(
278 event_time,247 event_time,
279 modifiers,
280 mir_pointer_action_motion,248 mir_pointer_action_motion,
281 buttons_pressed,249 buttons_pressed,
282 xmev.x,250 xmev.x,
283251
=== modified file 'src/server/input/CMakeLists.txt'
--- src/server/input/CMakeLists.txt 2015-10-12 19:30:14 +0000
+++ src/server/input/CMakeLists.txt 2015-10-14 12:41:48 +0000
@@ -8,6 +8,8 @@
8 default_event_builder.cpp8 default_event_builder.cpp
9 default_input_manager.cpp9 default_input_manager.cpp
10 default_input_device_hub.cpp10 default_input_device_hub.cpp
11 input_modifier_utils.cpp
12 seat.cpp
1113
12 surface_input_dispatcher.cpp14 surface_input_dispatcher.cpp
13 event_filter_chain_dispatcher.cpp15 event_filter_chain_dispatcher.cpp
1416
=== modified file 'src/server/input/default_event_builder.cpp'
--- src/server/input/default_event_builder.cpp 2015-10-09 00:15:44 +0000
+++ src/server/input/default_event_builder.cpp 2015-10-14 12:41:48 +0000
@@ -33,21 +33,21 @@
33}33}
3434
35mir::EventUPtr mi::DefaultEventBuilder::key_event(Timestamp timestamp, MirKeyboardAction action, xkb_keysym_t key_code,35mir::EventUPtr mi::DefaultEventBuilder::key_event(Timestamp timestamp, MirKeyboardAction action, xkb_keysym_t key_code,
36 int scan_code, MirInputEventModifiers modifiers)36 int scan_code)
37{37{
38 uint64_t mac = cookie_factory->timestamp_to_cookie(timestamp.count()).mac;38 uint64_t mac = cookie_factory->timestamp_to_cookie(timestamp.count()).mac;
39 return me::make_event(device_id, timestamp, mac, action, key_code, scan_code, modifiers);39 return me::make_event(device_id, timestamp, mac, action, key_code, scan_code, mir_input_event_modifier_none);
40}40}
4141
42mir::EventUPtr mi::DefaultEventBuilder::touch_event(Timestamp timestamp, MirInputEventModifiers modifiers)42mir::EventUPtr mi::DefaultEventBuilder::touch_event(Timestamp timestamp)
43{43{
44 return me::make_event(device_id, timestamp, 0, modifiers);44 return me::make_event(device_id, timestamp, 0, mir_input_event_modifier_none);
45}45}
4646
47void mi::DefaultEventBuilder::add_touch(MirEvent& event, MirTouchId touch_id, MirTouchAction action,47void mi::DefaultEventBuilder::add_touch(MirEvent& event, MirTouchId touch_id, MirTouchAction action,
48 MirTouchTooltype tooltype, float x_axis_value, float y_axis_value,48 MirTouchTooltype tooltype, float x_axis_value, float y_axis_value,
49 float pressure_value, float touch_major_value,49 float pressure_value, float touch_major_value, float touch_minor_value,
50 float touch_minor_value, float size_value)50 float size_value)
51{51{
52 if (action == mir_touch_action_up || action == mir_touch_action_down)52 if (action == mir_touch_action_up || action == mir_touch_action_down)
53 {53 {
@@ -59,17 +59,15 @@
59 touch_minor_value, size_value);59 touch_minor_value, size_value);
60}60}
6161
62mir::EventUPtr mi::DefaultEventBuilder::pointer_event(Timestamp timestamp, MirInputEventModifiers modifiers,62mir::EventUPtr mi::DefaultEventBuilder::pointer_event(Timestamp timestamp, MirPointerAction action,
63 MirPointerAction action, MirPointerButtons buttons_pressed,63 MirPointerButtons buttons_pressed, float x_axis_value,
64 float x_axis_value, float y_axis_value, float hscroll_value,64 float y_axis_value, float hscroll_value, float vscroll_value,
65 float vscroll_value, float relative_x_value,65 float relative_x_value, float relative_y_value)
66 float relative_y_value)
67{66{
68 uint64_t mac = 0;67 uint64_t mac = 0;
69 if (action == mir_pointer_action_button_up || action == mir_pointer_action_button_down)68 if (action == mir_pointer_action_button_up || action == mir_pointer_action_button_down)
70 mac = cookie_factory->timestamp_to_cookie(timestamp.count()).mac;69 mac = cookie_factory->timestamp_to_cookie(timestamp.count()).mac;
7170 return me::make_event(device_id, timestamp, mac, mir_input_event_modifier_none, action, buttons_pressed, x_axis_value, y_axis_value,
72 return me::make_event(device_id, timestamp, mac, modifiers, action, buttons_pressed, x_axis_value, y_axis_value,
73 hscroll_value, vscroll_value, relative_x_value, relative_y_value);71 hscroll_value, vscroll_value, relative_x_value, relative_y_value);
74}72}
7573
7674
=== modified file 'src/server/input/default_event_builder.h'
--- src/server/input/default_event_builder.h 2015-10-08 00:23:43 +0000
+++ src/server/input/default_event_builder.h 2015-10-14 12:41:48 +0000
@@ -37,18 +37,16 @@
37 explicit DefaultEventBuilder(MirInputDeviceId device_id,37 explicit DefaultEventBuilder(MirInputDeviceId device_id,
38 std::shared_ptr<cookie::CookieFactory> const& cookie_factory);38 std::shared_ptr<cookie::CookieFactory> const& cookie_factory);
3939
40 EventUPtr key_event(Timestamp timestamp, MirKeyboardAction action, xkb_keysym_t key_code, int scan_code,40 EventUPtr key_event(Timestamp timestamp, MirKeyboardAction action, xkb_keysym_t key_code, int scan_code) override;
41 MirInputEventModifiers modifiers) override;
4241
43 EventUPtr touch_event(Timestamp timestamp, MirInputEventModifiers modifiers) override;42 EventUPtr touch_event(Timestamp timestamp) override;
44 void add_touch(MirEvent& event, MirTouchId touch_id, MirTouchAction action, MirTouchTooltype tooltype,43 void add_touch(MirEvent& event, MirTouchId touch_id, MirTouchAction action, MirTouchTooltype tooltype,
45 float x_axis_value, float y_axis_value, float pressure_value, float touch_major_value,44 float x_axis_value, float y_axis_value, float pressure_value, float touch_major_value,
46 float touch_minor_value, float size_value) override;45 float touch_minor_value, float size_value) override;
4746
48 EventUPtr pointer_event(Timestamp timestamp, MirInputEventModifiers modifiers, MirPointerAction action,47 EventUPtr pointer_event(Timestamp timestamp, MirPointerAction action, MirPointerButtons buttons_pressed,
49 MirPointerButtons buttons_pressed, float x_axis_value, float y_axis_value,48 float x_axis_value, float y_axis_value, float hscroll_value, float vscroll_value,
50 float hscroll_value, float vscroll_value, float relative_x_value,49 float relative_x_value, float relative_y_value) override;
51 float relative_y_value) override;
5250
53 EventUPtr configuration_event(Timestamp timestamp, MirInputConfigurationAction action) override;51 EventUPtr configuration_event(Timestamp timestamp, MirInputConfigurationAction action) override;
5452
5553
=== modified file 'src/server/input/default_input_device_hub.cpp'
--- src/server/input/default_input_device_hub.cpp 2015-10-08 00:23:43 +0000
+++ src/server/input/default_input_device_hub.cpp 2015-10-14 12:41:48 +0000
@@ -19,11 +19,13 @@
19#include "default_input_device_hub.h"19#include "default_input_device_hub.h"
20#include "device_handle.h"20#include "device_handle.h"
2121
22#include "seat.h"
22#include "mir/input/input_dispatcher.h"23#include "mir/input/input_dispatcher.h"
23#include "mir/input/input_device.h"24#include "mir/input/input_device.h"
24#include "mir/input/input_device_observer.h"25#include "mir/input/input_device_observer.h"
25#include "mir/input/cursor_listener.h"
26#include "mir/input/input_region.h"26#include "mir/input/input_region.h"
27#include "mir/geometry/point.h"
28#include "mir/events/event_builders.h"
27#include "mir/dispatch/multiplexing_dispatchable.h"29#include "mir/dispatch/multiplexing_dispatchable.h"
28#include "mir/server_action_queue.h"30#include "mir/server_action_queue.h"
29#include "mir/cookie_factory.h"31#include "mir/cookie_factory.h"
@@ -36,6 +38,8 @@
36#include <atomic>38#include <atomic>
3739
38namespace mi = mir::input;40namespace mi = mir::input;
41namespace geom = mir::geometry;
42namespace mev = mir::events;
3943
40mi::DefaultInputDeviceHub::DefaultInputDeviceHub(44mi::DefaultInputDeviceHub::DefaultInputDeviceHub(
41 std::shared_ptr<mi::InputDispatcher> const& input_dispatcher,45 std::shared_ptr<mi::InputDispatcher> const& input_dispatcher,
@@ -45,9 +49,13 @@
45 std::shared_ptr<CursorListener> const& cursor_listener,49 std::shared_ptr<CursorListener> const& cursor_listener,
46 std::shared_ptr<InputRegion> const& input_region,50 std::shared_ptr<InputRegion> const& input_region,
47 std::shared_ptr<mir::cookie::CookieFactory> const& cookie_factory)51 std::shared_ptr<mir::cookie::CookieFactory> const& cookie_factory)
48 : input_dispatcher(input_dispatcher), input_dispatchable{input_multiplexer}, observer_queue(observer_queue),52 : input_dispatcher(input_dispatcher),
49 touch_visualizer(touch_visualizer), cursor_listener(cursor_listener), input_region(input_region),53 input_dispatchable{input_multiplexer},
50 cookie_factory(cookie_factory), device_id_generator{0}54 observer_queue(observer_queue),
55 input_region(input_region),
56 cookie_factory(cookie_factory),
57 seat(touch_visualizer, cursor_listener),
58 device_id_generator{0}
51{59{
52}60}
5361
@@ -67,9 +75,10 @@
67 {75 {
68 // send input device info to observer loop..76 // send input device info to observer loop..
69 devices.push_back(std::make_unique<RegisteredDevice>(77 devices.push_back(std::make_unique<RegisteredDevice>(
70 device, create_new_device_id(), input_dispatcher, input_dispatchable, cookie_factory, this));78 device, create_new_device_id(), input_dispatcher, input_dispatchable, cookie_factory, this, &seat));
7179
72 auto const& dev = devices.back();80 auto const& dev = devices.back();
81 seat.add_device(dev->id());
7382
74 auto handle = std::make_shared<DefaultDevice>(83 auto handle = std::make_shared<DefaultDevice>(
75 dev->id(), device->get_device_info());84 dev->id(), device->get_device_info());
@@ -104,6 +113,7 @@
104 if (item->device_matches(device))113 if (item->device_matches(device))
105 {114 {
106 item->stop();115 item->stop();
116 seat.remove_device(item->id());
107117
108 // send input device info to observer queue..118 // send input device info to observer queue..
109 observer_queue->enqueue(119 observer_queue->enqueue(
@@ -131,9 +141,10 @@
131 std::shared_ptr<InputDispatcher> const& dispatcher,141 std::shared_ptr<InputDispatcher> const& dispatcher,
132 std::shared_ptr<dispatch::MultiplexingDispatchable> const& multiplexer,142 std::shared_ptr<dispatch::MultiplexingDispatchable> const& multiplexer,
133 std::shared_ptr<mir::cookie::CookieFactory> const& cookie_factory,143 std::shared_ptr<mir::cookie::CookieFactory> const& cookie_factory,
134 DefaultInputDeviceHub* hub)144 DefaultInputDeviceHub* hub,
145 Seat* seat)
135 : device_id(device_id), builder(device_id, cookie_factory), device(dev), dispatcher(dispatcher),146 : device_id(device_id), builder(device_id, cookie_factory), device(dev), dispatcher(dispatcher),
136 multiplexer(multiplexer), hub(hub)147 multiplexer(multiplexer), hub(hub), seat(seat)
137{148{
138}149}
139150
@@ -154,50 +165,13 @@
154 if (type != mir_event_type_input)165 if (type != mir_event_type_input)
155 BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid input event receivd from device"));166 BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid input event receivd from device"));
156167
157 update_spots(mir_event_get_input_event(&event));168 seat->update_seat_properties(mir_event_get_input_event(&event));
158 notify_cursor_listener(mir_event_get_input_event(&event));169
170 mev::set_modifier(event, seat->event_modifier());
171
159 dispatcher->dispatch(event);172 dispatcher->dispatch(event);
160}173}
161174
162void mi::DefaultInputDeviceHub::RegisteredDevice::notify_cursor_listener(MirInputEvent const* event)
163{
164 if (mir_input_event_get_type(event) != mir_input_event_type_pointer)
165 return;
166
167 auto pointer_ev = mir_input_event_get_pointer_event(event);
168 hub->cursor_listener->cursor_moved_to(
169 mir_pointer_event_axis_value(pointer_ev, mir_pointer_axis_x),
170 mir_pointer_event_axis_value(pointer_ev, mir_pointer_axis_y)
171 );
172}
173
174void mi::DefaultInputDeviceHub::RegisteredDevice::update_spots(MirInputEvent const* event)
175{
176 if (mir_input_event_get_type(event) != mir_input_event_type_touch)
177 return;
178
179 auto const* touch_event = mir_input_event_get_touch_event(event);
180 auto count = mir_touch_event_point_count(touch_event);
181 touch_spots.reserve(count);
182 touch_spots.clear();
183 for (decltype(count) i = 0; i != count; ++i)
184 {
185 if (mir_touch_event_action(touch_event, i) == mir_touch_action_up)
186 continue;
187 touch_spots.push_back(mi::TouchVisualizer::Spot{
188 {mir_touch_event_axis_value(touch_event, i, mir_touch_axis_x),
189 mir_touch_event_axis_value(touch_event, i, mir_touch_axis_y)},
190 mir_touch_event_axis_value(touch_event, i, mir_touch_axis_pressure)});
191 }
192
193 hub->update_spots();
194}
195
196std::vector<mir::input::TouchVisualizer::Spot> const& mi::DefaultInputDeviceHub::RegisteredDevice::spots() const
197{
198 return touch_spots;
199}
200
201bool mi::DefaultInputDeviceHub::RegisteredDevice::device_matches(std::shared_ptr<InputDevice> const& dev) const175bool mi::DefaultInputDeviceHub::RegisteredDevice::device_matches(std::shared_ptr<InputDevice> const& dev) const
202{176{
203 return dev == device;177 return dev == device;
@@ -278,13 +252,3 @@
278252
279 handles.erase(handle_it, end(handles));253 handles.erase(handle_it, end(handles));
280}254}
281
282void mi::DefaultInputDeviceHub::update_spots()
283{
284 std::vector<TouchVisualizer::Spot> spots;
285
286 for (auto const& dev : devices)
287 spots.insert(end(spots), begin(dev->spots()), end(dev->spots()));
288
289 touch_visualizer->visualize_touches(spots);
290}
291255
=== modified file 'src/server/input/default_input_device_hub.h'
--- src/server/input/default_input_device_hub.h 2015-10-08 00:23:43 +0000
+++ src/server/input/default_input_device_hub.h 2015-10-14 12:41:48 +0000
@@ -20,12 +20,12 @@
20#define MIR_INPUT_DEFAULT_INPUT_DEVICE_HUB_H_20#define MIR_INPUT_DEFAULT_INPUT_DEVICE_HUB_H_
2121
22#include "default_event_builder.h"22#include "default_event_builder.h"
23#include "seat.h"
2324
24#include "mir/input/input_device_registry.h"25#include "mir/input/input_device_registry.h"
25#include "mir/input/input_sink.h"26#include "mir/input/input_sink.h"
26#include "mir/input/input_device_hub.h"27#include "mir/input/input_device_hub.h"
27#include "mir/input/input_device_info.h"28#include "mir/input/input_device_info.h"
28#include "mir/input/touch_visualizer.h"
2929
30#include "mir_toolkit/event.h"30#include "mir_toolkit/event.h"
3131
@@ -82,10 +82,9 @@
82 std::shared_ptr<InputDispatcher> const input_dispatcher;82 std::shared_ptr<InputDispatcher> const input_dispatcher;
83 std::shared_ptr<dispatch::MultiplexingDispatchable> const input_dispatchable;83 std::shared_ptr<dispatch::MultiplexingDispatchable> const input_dispatchable;
84 std::shared_ptr<ServerActionQueue> const observer_queue;84 std::shared_ptr<ServerActionQueue> const observer_queue;
85 std::shared_ptr<TouchVisualizer> const touch_visualizer;
86 std::shared_ptr<CursorListener> const cursor_listener;
87 std::shared_ptr<InputRegion> const input_region;85 std::shared_ptr<InputRegion> const input_region;
88 std::shared_ptr<cookie::CookieFactory> const cookie_factory;86 std::shared_ptr<cookie::CookieFactory> const cookie_factory;
87 Seat seat;
8988
90 struct RegisteredDevice : public InputSink89 struct RegisteredDevice : public InputSink
91 {90 {
@@ -95,8 +94,8 @@
95 std::shared_ptr<InputDispatcher> const& dispatcher,94 std::shared_ptr<InputDispatcher> const& dispatcher,
96 std::shared_ptr<dispatch::MultiplexingDispatchable> const& multiplexer,95 std::shared_ptr<dispatch::MultiplexingDispatchable> const& multiplexer,
97 std::shared_ptr<cookie::CookieFactory> const& cookie_factory,96 std::shared_ptr<cookie::CookieFactory> const& cookie_factory,
98 DefaultInputDeviceHub* hub);97 DefaultInputDeviceHub* hub,
9998 Seat* seat);
100 void handle_input(MirEvent& event) override;99 void handle_input(MirEvent& event) override;
101 void confine_pointer(mir::geometry::Point& position) override;100 void confine_pointer(mir::geometry::Point& position) override;
102 mir::geometry::Rectangle bounding_rectangle() const override;101 mir::geometry::Rectangle bounding_rectangle() const override;
@@ -104,24 +103,21 @@
104 void start();103 void start();
105 void stop();104 void stop();
106 MirInputDeviceId id();105 MirInputDeviceId id();
107 std::vector<TouchVisualizer::Spot> const& spots() const;
108 private:106 private:
109 void update_spots(MirInputEvent const* event);
110 void notify_cursor_listener(MirInputEvent const* event);
111 MirInputDeviceId device_id;107 MirInputDeviceId device_id;
112 DefaultEventBuilder builder;108 DefaultEventBuilder builder;
113 std::shared_ptr<InputDevice> const device;109 std::shared_ptr<InputDevice> const device;
114 std::shared_ptr<InputDispatcher> const dispatcher;110 std::shared_ptr<InputDispatcher> const dispatcher;
115 std::shared_ptr<dispatch::MultiplexingDispatchable> const multiplexer;111 std::shared_ptr<dispatch::MultiplexingDispatchable> const multiplexer;
116 DefaultInputDeviceHub* hub;112 DefaultInputDeviceHub* hub;
117 std::vector<TouchVisualizer::Spot> touch_spots;113 Seat* seat;
118 friend class DefaultInputDeviceHub;114 friend class DefaultInputDeviceHub;
119 };115 };
120116
121 std::vector<std::shared_ptr<DefaultDevice>> handles;117 std::vector<std::shared_ptr<DefaultDevice>> handles;
122 std::vector<std::unique_ptr<RegisteredDevice>> devices;118 std::vector<std::unique_ptr<RegisteredDevice>> devices;
123 std::vector<std::shared_ptr<InputDeviceObserver>> observers;119 std::vector<std::shared_ptr<InputDeviceObserver>> observers;
124 120
125 MirInputDeviceId device_id_generator;121 MirInputDeviceId device_id_generator;
126};122};
127123
128124
=== renamed file 'src/platforms/evdev/input_modifier_utils.cpp' => 'src/server/input/input_modifier_utils.cpp'
--- src/platforms/evdev/input_modifier_utils.cpp 2015-09-17 06:40:14 +0000
+++ src/server/input/input_modifier_utils.cpp 2015-10-14 12:41:48 +0000
@@ -25,22 +25,9 @@
2525
26#include <stdexcept>26#include <stdexcept>
2727
28namespace mie = mir::input::evdev;28namespace mi = mir::input;
2929
30MirPointerButton mie::to_pointer_button(int button)30MirInputEventModifiers mi::to_modifiers(int32_t scan_code)
31{
32 switch(button)
33 {
34 case BTN_LEFT: return mir_pointer_button_primary;
35 case BTN_RIGHT: return mir_pointer_button_secondary;
36 case BTN_MIDDLE: return mir_pointer_button_tertiary;
37 case BTN_BACK: return mir_pointer_button_back;
38 case BTN_FORWARD: return mir_pointer_button_forward;
39 }
40 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid mouse button"));
41}
42
43MirInputEventModifiers mie::to_modifiers(int32_t scan_code)
44{31{
45 switch(scan_code)32 switch(scan_code)
46 {33 {
@@ -71,7 +58,7 @@
71 }58 }
72}59}
7360
74MirInputEventModifiers mie::expand_modifiers(MirInputEventModifiers modifiers)61MirInputEventModifiers mi::expand_modifiers(MirInputEventModifiers modifiers)
75{62{
76 if (modifiers == 0)63 if (modifiers == 0)
77 return mir_input_event_modifier_none;64 return mir_input_event_modifier_none;
@@ -91,4 +78,3 @@
91 return modifiers;78 return modifiers;
92}79}
9380
94
9581
=== renamed file 'src/platforms/evdev/input_modifier_utils.h' => 'src/server/input/input_modifier_utils.h'
--- src/platforms/evdev/input_modifier_utils.h 2015-09-17 06:40:14 +0000
+++ src/server/input/input_modifier_utils.h 2015-10-14 12:41:48 +0000
@@ -16,8 +16,8 @@
16 * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>16 * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
17 */17 */
1818
19#ifndef MIR_INPUT_EVDEV_INPUT_MODIFIER_UTILS_H_19#ifndef MIR_INPUT_INPUT_MODIFIER_UTILS_H_
20#define MIR_INPUT_EVDEV_INPUT_MODIFIER_UTILS_H_20#define MIR_INPUT_INPUT_MODIFIER_UTILS_H_
2121
22#include "mir_toolkit/event.h"22#include "mir_toolkit/event.h"
2323
@@ -25,13 +25,9 @@
25{25{
26namespace input26namespace input
27{27{
28namespace evdev
29{
30MirPointerButton to_pointer_button(int button);
31MirInputEventModifiers to_modifiers(int32_t scan_code);28MirInputEventModifiers to_modifiers(int32_t scan_code);
32MirInputEventModifiers expand_modifiers(MirInputEventModifiers modifiers);29MirInputEventModifiers expand_modifiers(MirInputEventModifiers modifiers);
33}30}
34}31}
35}
3632
37#endif33#endif
3834
=== added file 'src/server/input/seat.cpp'
--- src/server/input/seat.cpp 1970-01-01 00:00:00 +0000
+++ src/server/input/seat.cpp 2015-10-14 12:41:48 +0000
@@ -0,0 +1,153 @@
1/*
2 * Copyright © 2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by:
17 * Andreas Pokorny <andreas.pokorny@canonical.com>
18 */
19
20#include "seat.h"
21#include "mir/input/device.h"
22#include "mir/input/cursor_listener.h"
23
24#include "input_modifier_utils.h"
25
26#include <boost/throw_exception.hpp>
27
28#include <stdexcept>
29#include <algorithm>
30
31namespace mi = mir::input;
32
33mi::Seat::Seat(std::shared_ptr<TouchVisualizer> const& touch_visualizer,
34 std::shared_ptr<CursorListener> const& cursor_listener)
35 : touch_visualizer{touch_visualizer}, cursor_listener{cursor_listener}, modifier{0}
36{
37}
38
39void mi::Seat::add_device(MirInputDeviceId id)
40{
41 device_data[id];
42}
43
44void mi::Seat::remove_device(MirInputDeviceId id)
45{
46 auto stored_data = device_data.find(id);
47
48 if (stored_data == end(device_data))
49 BOOST_THROW_EXCEPTION(std::logic_error("Modifier for unknown device changed"));
50
51 bool mod_update_needed = stored_data->second.mod != mir_input_event_modifier_none;
52 bool spot_update_needed = !stored_data->second.spots.empty();
53
54 device_data.erase(stored_data);
55
56 if (mod_update_needed)
57 update_modifier();
58 if (spot_update_needed)
59 update_spots();
60}
61
62MirInputEventModifiers mi::Seat::event_modifier() const
63{
64 return expand_modifiers(modifier);
65}
66
67void mi::Seat::update_seat_properties(MirInputEvent const* event)
68{
69 auto id = mir_input_event_get_device_id(event);
70
71 auto stored_data = device_data.find(id);
72
73 if (stored_data == end(device_data))
74 BOOST_THROW_EXCEPTION(std::logic_error("Modifier for unknown device changed"));
75
76 switch(mir_input_event_get_type(event))
77 {
78 case mir_input_event_type_key:
79 {
80 auto const* key = mir_input_event_get_keyboard_event(event);
81 if (stored_data->second.update_modifier(mir_keyboard_event_action(key),
82 mir_keyboard_event_scan_code(key)))
83 update_modifier();
84 break;
85 }
86 case mir_input_event_type_touch:
87 if (stored_data->second.update_spots(mir_input_event_get_touch_event(event)))
88 update_spots();
89 break;
90 case mir_input_event_type_pointer:
91 update_cursor(mir_input_event_get_pointer_event(event));
92 break;
93 default:
94 break;
95 }
96}
97
98bool mi::Seat::DeviceData::update_modifier(MirKeyboardAction key_action, int scan_code)
99{
100 auto mod_change = to_modifiers(scan_code);
101
102 if (mod_change == 0 || key_action == mir_keyboard_action_repeat)
103 return false;
104
105 if (key_action == mir_keyboard_action_down)
106 mod |= mod_change;
107 else if (key_action == mir_keyboard_action_up)
108 mod &= ~mod_change;
109
110 return true;
111}
112
113bool mi::Seat::DeviceData::update_spots(MirTouchEvent const* event)
114{
115 auto count = mir_touch_event_point_count(event);
116 spots.clear();
117 for (decltype(count) i = 0; i != count; ++i)
118 {
119 if (mir_touch_event_action(event, i) == mir_touch_action_up)
120 continue;
121 spots.push_back({{mir_touch_event_axis_value(event, i, mir_touch_axis_x),
122 mir_touch_event_axis_value(event, i, mir_touch_axis_y)},
123 mir_touch_event_axis_value(event, i, mir_touch_axis_pressure)});
124 }
125 return true;
126}
127
128void mi::Seat::update_spots()
129{
130 spots.clear();
131 for (auto const& dev : device_data)
132 spots.insert(end(spots), begin(dev.second.spots), end(dev.second.spots));
133
134 touch_visualizer->visualize_touches(spots);
135}
136
137void mi::Seat::update_modifier()
138{
139 modifier = std::accumulate(begin(device_data),
140 end(device_data),
141 MirInputEventModifiers{0},
142 [](auto const& acc, auto const& item)
143 {
144 return acc | item.second.mod;
145 });
146}
147
148void mi::Seat::update_cursor(MirPointerEvent const* event)
149{
150 cursor_listener->cursor_moved_to(mir_pointer_event_axis_value(event, mir_pointer_axis_x),
151 mir_pointer_event_axis_value(event, mir_pointer_axis_y));
152}
153
0154
=== added file 'src/server/input/seat.h'
--- src/server/input/seat.h 1970-01-01 00:00:00 +0000
+++ src/server/input/seat.h 2015-10-14 12:41:48 +0000
@@ -0,0 +1,72 @@
1/*
2 * Copyright © 2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by:
17 * Andreas Pokorny <andreas.pokorny@canonical.com>
18 */
19
20#ifndef MIR_INPUT_DEFAULT_SEAT_H_
21#define MIR_INPUT_DEFAULT_SEAT_H_
22
23#include "mir/input/touch_visualizer.h"
24#include "mir_toolkit/event.h"
25#include <unordered_map>
26#include <memory>
27
28namespace mir
29{
30namespace input
31{
32class CursorListener;
33
34/*
35 * The seat bundles a group of devices. A cursor position, input event modifiers and the visible touch spots are properties
36 * controlled by this grouping of input devices.
37 */
38struct Seat
39{
40 Seat(std::shared_ptr<TouchVisualizer> const& touch_visualizer, std::shared_ptr<CursorListener> const& cursor_listener);
41 void add_device(MirInputDeviceId);
42 void remove_device(MirInputDeviceId);
43
44 MirInputEventModifiers event_modifier() const;
45 void update_seat_properties(MirInputEvent const* event);
46private:
47 void update_cursor(MirPointerEvent const* event);
48 void update_spots();
49 void update_modifier();
50
51 std::shared_ptr<TouchVisualizer> const touch_visualizer;
52 std::shared_ptr<CursorListener> const cursor_listener;
53
54 struct DeviceData
55 {
56 DeviceData() {}
57 bool update_modifier(MirKeyboardAction action, int scan_code);
58 bool update_spots(MirTouchEvent const* event);
59
60 MirInputEventModifiers mod{0};
61 std::vector<TouchVisualizer::Spot> spots;
62 };
63
64 MirInputEventModifiers modifier;
65 std::unordered_map<MirInputDeviceId, DeviceData> device_data;
66 std::vector<TouchVisualizer::Spot> spots;
67};
68
69}
70}
71
72#endif
073
=== modified file 'tests/mir_test_framework/fake_input_device_impl.cpp'
--- tests/mir_test_framework/fake_input_device_impl.cpp 2015-10-12 08:08:58 +0000
+++ tests/mir_test_framework/fake_input_device_impl.cpp 2015-10-14 12:41:48 +0000
@@ -25,7 +25,7 @@
25#include "mir/input/event_builder.h"25#include "mir/input/event_builder.h"
26#include "mir/dispatch/action_queue.h"26#include "mir/dispatch/action_queue.h"
27#include "mir/geometry/displacement.h"27#include "mir/geometry/displacement.h"
28#include "src/platforms/evdev/input_modifier_utils.h"28#include "src/platforms/evdev/button_utils.h"
2929
30#include "boost/throw_exception.hpp"30#include "boost/throw_exception.hpp"
3131
@@ -100,13 +100,7 @@
100 auto input_action =100 auto input_action =
101 (key_params.action == synthesis::EventAction::Down) ? mir_keyboard_action_down : mir_keyboard_action_up;101 (key_params.action == synthesis::EventAction::Down) ? mir_keyboard_action_down : mir_keyboard_action_up;
102102
103 auto event_modifiers = mie::expand_modifiers(modifiers);103 auto key_event = builder->key_event(event_time, input_action, key_code, key_params.scancode);
104 auto key_event = builder->key_event(event_time, input_action, key_code, key_params.scancode, event_modifiers);
105
106 if (key_params.action == synthesis::EventAction::Down)
107 modifiers |= mie::to_modifiers(key_params.scancode);
108 else
109 modifiers &= ~mie::to_modifiers(key_params.scancode);
110104
111 if (!sink)105 if (!sink)
112 BOOST_THROW_EXCEPTION(std::runtime_error("Device is not started."));106 BOOST_THROW_EXCEPTION(std::runtime_error("Device is not started."));
@@ -118,9 +112,7 @@
118 auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(112 auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(
119 std::chrono::system_clock::now().time_since_epoch());113 std::chrono::system_clock::now().time_since_epoch());
120 auto action = update_buttons(button.action, mie::to_pointer_button(button.button));114 auto action = update_buttons(button.action, mie::to_pointer_button(button.button));
121 auto event_modifiers = mie::expand_modifiers(modifiers);
122 auto button_event = builder->pointer_event(event_time,115 auto button_event = builder->pointer_event(event_time,
123 event_modifiers,
124 action,116 action,
125 buttons,117 buttons,
126 pos.x.as_float(),118 pos.x.as_float(),
@@ -156,10 +148,8 @@
156148
157 auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(149 auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(
158 std::chrono::system_clock::now().time_since_epoch());150 std::chrono::system_clock::now().time_since_epoch());
159 auto event_modifiers = mie::expand_modifiers(modifiers);
160 update_position(pointer.rel_x, pointer.rel_y);151 update_position(pointer.rel_x, pointer.rel_y);
161 auto pointer_event = builder->pointer_event(event_time,152 auto pointer_event = builder->pointer_event(event_time,
162 event_modifiers,
163 mir_pointer_action_motion,153 mir_pointer_action_motion,
164 buttons,154 buttons,
165 pos.x.as_float(),155 pos.x.as_float(),
@@ -185,9 +175,8 @@
185175
186 auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(176 auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(
187 std::chrono::system_clock::now().time_since_epoch());177 std::chrono::system_clock::now().time_since_epoch());
188 auto event_modifiers = mie::expand_modifiers(modifiers);
189178
190 auto touch_event = builder->touch_event(event_time, event_modifiers);179 auto touch_event = builder->touch_event(event_time);
191180
192 auto touch_action = mir_touch_action_up;181 auto touch_action = mir_touch_action_up;
193 if (touch.action == synthesis::TouchParameters::Action::Tap)182 if (touch.action == synthesis::TouchParameters::Action::Tap)
194183
=== modified file 'tests/mir_test_framework/fake_input_device_impl.h'
--- tests/mir_test_framework/fake_input_device_impl.h 2015-09-01 07:41:29 +0000
+++ tests/mir_test_framework/fake_input_device_impl.h 2015-10-14 12:41:48 +0000
@@ -73,7 +73,6 @@
73 mir::input::EventBuilder* builder{nullptr};73 mir::input::EventBuilder* builder{nullptr};
74 mir::input::InputDeviceInfo info;74 mir::input::InputDeviceInfo info;
75 std::shared_ptr<mir::dispatch::Dispatchable> const queue;75 std::shared_ptr<mir::dispatch::Dispatchable> const queue;
76 uint32_t modifiers{0};
77 mir::geometry::Point pos, scroll;76 mir::geometry::Point pos, scroll;
78 MirPointerButtons buttons;77 MirPointerButtons buttons;
79 };78 };
8079
=== modified file 'tests/unit-tests/input/evdev/test_libinput_device.cpp'
--- tests/unit-tests/input/evdev/test_libinput_device.cpp 2015-10-07 16:41:50 +0000
+++ tests/unit-tests/input/evdev/test_libinput_device.cpp 2015-10-14 12:41:48 +0000
@@ -73,16 +73,15 @@
73 mi::DefaultEventBuilder builder{MirInputDeviceId{3}, cookie_factory};73 mi::DefaultEventBuilder builder{MirInputDeviceId{3}, cookie_factory};
74 MockEventBuilder()74 MockEventBuilder()
75 {75 {
76 ON_CALL(*this, key_event(_,_,_,_,_))76 ON_CALL(*this, key_event(_,_,_,_))
77 .WillByDefault(Invoke([this](Timestamp time, MirKeyboardAction action, xkb_keysym_t key, int scan_code,77 .WillByDefault(Invoke([this](Timestamp time, MirKeyboardAction action, xkb_keysym_t key, int scan_code)
78 MirInputEventModifiers modifier)
79 {78 {
80 return builder.key_event(time, action, key, scan_code, modifier);79 return builder.key_event(time, action, key, scan_code);
81 }));80 }));
82 ON_CALL(*this, touch_event(_,_))81 ON_CALL(*this, touch_event(_))
83 .WillByDefault(Invoke([this](Timestamp time, MirInputEventModifiers modifier)82 .WillByDefault(Invoke([this](Timestamp time)
84 {83 {
85 return builder.touch_event(time, modifier);84 return builder.touch_event(time);
86 }));85 }));
87 ON_CALL(*this, add_touch(_,_,_,_,_,_,_,_,_,_))86 ON_CALL(*this, add_touch(_,_,_,_,_,_,_,_,_,_))
88 .WillByDefault(Invoke([this](MirEvent& event, MirTouchId id, MirTouchAction action,87 .WillByDefault(Invoke([this](MirEvent& event, MirTouchId id, MirTouchAction action,
@@ -92,13 +91,12 @@
92 return builder.add_touch(event, id, action, tooltype, x, y, major, minor,91 return builder.add_touch(event, id, action, tooltype, x, y, major, minor,
93 pressure, size);92 pressure, size);
94 }));93 }));
95 ON_CALL(*this, pointer_event(_,_,_,_,_,_,_,_,_,_))94 ON_CALL(*this, pointer_event(_, _, _, _, _, _, _, _, _))
96 .WillByDefault(Invoke([this](Timestamp time, MirInputEventModifiers modifier, MirPointerAction action,95 .WillByDefault(Invoke([this](Timestamp time, MirPointerAction action, MirPointerButtons buttons, float x,
97 MirPointerButtons buttons, float x, float y, float hscroll, float vscroll,96 float y, float hscroll, float vscroll, float relative_x, float relative_y)
98 float relative_x, float relative_y)
99 {97 {
100 return builder.pointer_event(time, modifier, action, buttons, x, y, hscroll,98 return builder.pointer_event(time, action, buttons, x, y, hscroll, vscroll,
101 vscroll, relative_x, relative_y);99 relative_x, relative_y);
102 }));100 }));
103 ON_CALL(*this, configuration_event(_,_))101 ON_CALL(*this, configuration_event(_,_))
104 .WillByDefault(Invoke([this](Timestamp time, MirInputConfigurationAction action)102 .WillByDefault(Invoke([this](Timestamp time, MirInputConfigurationAction action)
@@ -107,14 +105,14 @@
107 }));105 }));
108 }106 }
109 using EventBuilder::Timestamp;107 using EventBuilder::Timestamp;
110 MOCK_METHOD5(key_event, mir::EventUPtr(Timestamp, MirKeyboardAction, xkb_keysym_t, int, MirInputEventModifiers));108 MOCK_METHOD4(key_event, mir::EventUPtr(Timestamp, MirKeyboardAction, xkb_keysym_t, int));
111109
112 MOCK_METHOD2(touch_event, mir::EventUPtr(Timestamp, MirInputEventModifiers));110 MOCK_METHOD1(touch_event, mir::EventUPtr(Timestamp));
113 MOCK_METHOD10(add_touch, void(MirEvent&, MirTouchId, MirTouchAction, MirTouchTooltype, float, float, float, float,111 MOCK_METHOD10(add_touch, void(MirEvent&, MirTouchId, MirTouchAction, MirTouchTooltype, float, float, float, float,
114 float, float));112 float, float));
115113
116 MOCK_METHOD10(pointer_event, mir::EventUPtr(Timestamp, MirInputEventModifiers, MirPointerAction, MirPointerButtons,114 MOCK_METHOD9(pointer_event, mir::EventUPtr(Timestamp, MirPointerAction, MirPointerButtons, float, float, float,
117 float, float, float, float, float, float));115 float, float, float));
118 MOCK_METHOD2(configuration_event, mir::EventUPtr(Timestamp, MirInputConfigurationAction));116 MOCK_METHOD2(configuration_event, mir::EventUPtr(Timestamp, MirInputConfigurationAction));
119};117};
120118
@@ -374,9 +372,9 @@
374 setup_key_event(fake_event_1, event_time_1, KEY_A, LIBINPUT_KEY_STATE_PRESSED);372 setup_key_event(fake_event_1, event_time_1, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
375 setup_key_event(fake_event_2, event_time_2, KEY_A, LIBINPUT_KEY_STATE_RELEASED);373 setup_key_event(fake_event_2, event_time_2, KEY_A, LIBINPUT_KEY_STATE_RELEASED);
376374
377 EXPECT_CALL(mock_builder, key_event(time_stamp_1, mir_keyboard_action_down, _, KEY_A, mir_input_event_modifier_none));375 EXPECT_CALL(mock_builder, key_event(time_stamp_1, mir_keyboard_action_down, _, KEY_A));
378 EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_A),mt::KeyDownEvent())));376 EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_A),mt::KeyDownEvent())));
379 EXPECT_CALL(mock_builder, key_event(time_stamp_2, mir_keyboard_action_up, _, KEY_A, mir_input_event_modifier_none));377 EXPECT_CALL(mock_builder, key_event(time_stamp_2, mir_keyboard_action_up, _, KEY_A));
380 EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_A),mt::KeyUpEvent())));378 EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_A),mt::KeyUpEvent())));
381379
382 dev.start(&mock_sink, &mock_builder);380 dev.start(&mock_sink, &mock_builder);
@@ -384,36 +382,6 @@
384 dev.process_event(fake_event_2);382 dev.process_event(fake_event_2);
385}383}
386384
387TEST_F(LibInputDevice, process_event_accumulates_key_state)
388{
389 std::shared_ptr<libinput> lib = mie::make_libinput();
390 mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
391
392
393 setup_key_event(fake_event_1, event_time_1, KEY_C, LIBINPUT_KEY_STATE_PRESSED);
394 setup_key_event(fake_event_2, event_time_2, KEY_LEFTALT, LIBINPUT_KEY_STATE_PRESSED);
395 setup_key_event(fake_event_3, event_time_3, KEY_C, LIBINPUT_KEY_STATE_RELEASED);
396
397 InSequence seq;
398 EXPECT_CALL(mock_builder, key_event(time_stamp_1, mir_keyboard_action_down, _, KEY_C, mir_input_event_modifier_none));
399 EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_C),mt::KeyDownEvent())));
400 EXPECT_CALL(mock_builder, key_event(time_stamp_2, mir_keyboard_action_down, _, KEY_LEFTALT, mir_input_event_modifier_none));
401 EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_LEFTALT),mt::KeyDownEvent())));
402 EXPECT_CALL(mock_builder, key_event(time_stamp_3, mir_keyboard_action_up, _, KEY_C, mir_input_event_modifier_alt|mir_input_event_modifier_alt_left));
403 EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_C),
404 mt::KeyWithModifiers(
405 MirInputEventModifiers{
406 mir_input_event_modifier_alt|
407 mir_input_event_modifier_alt_left
408 }),
409 mt::KeyUpEvent())));
410
411 dev.start(&mock_sink, &mock_builder);
412 dev.process_event(fake_event_1);
413 dev.process_event(fake_event_2);
414 dev.process_event(fake_event_3);
415}
416
417TEST_F(LibInputDevice, process_event_converts_pointer_event)385TEST_F(LibInputDevice, process_event_converts_pointer_event)
418{386{
419 std::shared_ptr<libinput> lib = mie::make_libinput();387 std::shared_ptr<libinput> lib = mie::make_libinput();
@@ -499,9 +467,9 @@
499467
500 InSequence seq;468 InSequence seq;
501 // expect two scroll events..469 // expect two scroll events..
502 EXPECT_CALL(mock_builder, pointer_event(time_stamp_1, mir_input_event_modifier_none, mir_pointer_action_motion, 0, 0.0f, 0.0f, 0.0f, 20.0f, 0.0f, 0.0f));470 EXPECT_CALL(mock_builder, pointer_event(time_stamp_1, mir_pointer_action_motion, 0, 0.0f, 0.0f, 0.0f, 20.0f, 0.0f, 0.0f));
503 EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_vscroll, 20.0f)));471 EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_vscroll, 20.0f)));
504 EXPECT_CALL(mock_builder, pointer_event(time_stamp_2, mir_input_event_modifier_none, mir_pointer_action_motion, 0, 0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f));472 EXPECT_CALL(mock_builder, pointer_event(time_stamp_2, mir_pointer_action_motion, 0, 0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f));
505 EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_hscroll, 5.0f)));473 EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_hscroll, 5.0f)));
506474
507 dev.start(&mock_sink, &mock_builder);475 dev.start(&mock_sink, &mock_builder);
@@ -525,7 +493,7 @@
525 setup_touch_frame(fake_event_2);493 setup_touch_frame(fake_event_2);
526494
527 InSequence seq;495 InSequence seq;
528 EXPECT_CALL(mock_builder, touch_event(time_stamp_1, mir_input_event_modifier_none));496 EXPECT_CALL(mock_builder, touch_event(time_stamp_1));
529 EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{0}, mir_touch_action_down, mir_touch_tooltype_finger, x, y,497 EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{0}, mir_touch_action_down, mir_touch_tooltype_finger, x, y,
530 pressure, major, minor, major));498 pressure, major, minor, major));
531 EXPECT_CALL(mock_sink, handle_input(mt::TouchEvent(x,y)));499 EXPECT_CALL(mock_sink, handle_input(mt::TouchEvent(x,y)));
@@ -551,7 +519,7 @@
551 setup_touch_frame(fake_event_2);519 setup_touch_frame(fake_event_2);
552520
553 InSequence seq;521 InSequence seq;
554 EXPECT_CALL(mock_builder, touch_event(time_stamp_1, mir_input_event_modifier_none));522 EXPECT_CALL(mock_builder, touch_event(time_stamp_1));
555 EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{0}, mir_touch_action_change, mir_touch_tooltype_finger, x, y,523 EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{0}, mir_touch_action_change, mir_touch_tooltype_finger, x, y,
556 pressure, major, minor, major));524 pressure, major, minor, major));
557 EXPECT_CALL(mock_sink, handle_input(mt::TouchMovementEvent()));525 EXPECT_CALL(mock_sink, handle_input(mt::TouchMovementEvent()));
@@ -579,12 +547,12 @@
579 setup_touch_frame(fake_event_4);547 setup_touch_frame(fake_event_4);
580548
581 InSequence seq;549 InSequence seq;
582 EXPECT_CALL(mock_builder, touch_event(time_stamp_1, mir_input_event_modifier_none));550 EXPECT_CALL(mock_builder, touch_event(time_stamp_1));
583 EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{slot}, mir_touch_action_down, mir_touch_tooltype_finger, x, y,551 EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{slot}, mir_touch_action_down, mir_touch_tooltype_finger, x, y,
584 pressure, major, minor, major));552 pressure, major, minor, major));
585 EXPECT_CALL(mock_sink, handle_input(mt::TouchEvent(x,y)));553 EXPECT_CALL(mock_sink, handle_input(mt::TouchEvent(x,y)));
586554
587 EXPECT_CALL(mock_builder, touch_event(time_stamp_2, mir_input_event_modifier_none));555 EXPECT_CALL(mock_builder, touch_event(time_stamp_2));
588 EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{slot}, mir_touch_action_up, mir_touch_tooltype_finger, x, y,556 EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{slot}, mir_touch_action_up, mir_touch_tooltype_finger, x, y,
589 pressure, major, minor, major));557 pressure, major, minor, major));
590 EXPECT_CALL(mock_sink, handle_input(mt::TouchUpEvent(x,y)));558 EXPECT_CALL(mock_sink, handle_input(mt::TouchUpEvent(x,y)));
591559
=== modified file 'tests/unit-tests/input/test_default_input_device_hub.cpp'
--- tests/unit-tests/input/test_default_input_device_hub.cpp 2015-10-07 16:41:50 +0000
+++ tests/unit-tests/input/test_default_input_device_hub.cpp 2015-10-14 12:41:48 +0000
@@ -268,7 +268,7 @@
268 observer_loop.trigger_server_actions();268 observer_loop.trigger_server_actions();
269269
270 auto event = builder->key_event(arbitrary_timestamp, mir_keyboard_action_down, 0,270 auto event = builder->key_event(arbitrary_timestamp, mir_keyboard_action_down, 0,
271 KEY_A, mir_input_event_modifier_none);271 KEY_A);
272272
273 EXPECT_CALL(mock_dispatcher, dispatch(AllOf(mt::InputDeviceIdMatches(handle->id()), mt::MirKeyEventMatches(event.get()))));273 EXPECT_CALL(mock_dispatcher, dispatch(AllOf(mt::InputDeviceIdMatches(handle->id()), mt::MirKeyEventMatches(event.get()))));
274274
@@ -287,23 +287,23 @@
287287
288 observer_loop.trigger_server_actions();288 observer_loop.trigger_server_actions();
289289
290 auto touch_event_1 = builder->touch_event(arbitrary_timestamp, mir_input_event_modifier_none);290 auto touch_event_1 = builder->touch_event(arbitrary_timestamp);
291 builder->add_touch(*touch_event_1, 0, mir_touch_action_down, mir_touch_tooltype_finger, 21.0f, 34.0f, 50.0f, 15.0f,291 builder->add_touch(*touch_event_1, 0, mir_touch_action_down, mir_touch_tooltype_finger, 21.0f, 34.0f, 50.0f, 15.0f,
292 5.0f, 4.0f);292 5.0f, 4.0f);
293293
294 auto touch_event_2 = builder->touch_event(arbitrary_timestamp, mir_input_event_modifier_none);294 auto touch_event_2 = builder->touch_event(arbitrary_timestamp);
295 builder->add_touch(*touch_event_2, 0, mir_touch_action_change, mir_touch_tooltype_finger, 24.0f, 34.0f, 50.0f,295 builder->add_touch(*touch_event_2, 0, mir_touch_action_change, mir_touch_tooltype_finger, 24.0f, 34.0f, 50.0f,
296 15.0f, 5.0f, 4.0f);296 15.0f, 5.0f, 4.0f);
297 builder->add_touch(*touch_event_2, 1, mir_touch_action_down, mir_touch_tooltype_finger, 60.0f, 34.0f, 50.0f, 15.0f,297 builder->add_touch(*touch_event_2, 1, mir_touch_action_down, mir_touch_tooltype_finger, 60.0f, 34.0f, 50.0f, 15.0f,
298 5.0f, 4.0f);298 5.0f, 4.0f);
299299
300 auto touch_event_3 = builder->touch_event(arbitrary_timestamp, mir_input_event_modifier_none);300 auto touch_event_3 = builder->touch_event(arbitrary_timestamp);
301 builder->add_touch(*touch_event_3, 0, mir_touch_action_up, mir_touch_tooltype_finger, 24.0f, 34.0f, 50.0f, 15.0f,301 builder->add_touch(*touch_event_3, 0, mir_touch_action_up, mir_touch_tooltype_finger, 24.0f, 34.0f, 50.0f, 15.0f,
302 5.0f, 4.0f);302 5.0f, 4.0f);
303 builder->add_touch(*touch_event_3, 1, mir_touch_action_change, mir_touch_tooltype_finger, 70.0f, 30.0f, 50.0f,303 builder->add_touch(*touch_event_3, 1, mir_touch_action_change, mir_touch_tooltype_finger, 70.0f, 30.0f, 50.0f,
304 15.0f, 5.0f, 4.0f);304 15.0f, 5.0f, 4.0f);
305305
306 auto touch_event_4 = builder->touch_event(arbitrary_timestamp, mir_input_event_modifier_none);306 auto touch_event_4 = builder->touch_event(arbitrary_timestamp);
307 builder->add_touch(*touch_event_4, 1, mir_touch_action_up, mir_touch_tooltype_finger, 70.0f, 35.0f, 50.0f, 15.0f,307 builder->add_touch(*touch_event_4, 1, mir_touch_action_up, mir_touch_tooltype_finger, 70.0f, 35.0f, 50.0f, 15.0f,
308 5.0f, 4.0f);308 5.0f, 4.0f);
309309
@@ -372,17 +372,149 @@
372 using namespace ::testing;372 using namespace ::testing;
373373
374 auto x = 12.2f, y = 14.3f;374 auto x = 12.2f, y = 14.3f;
375 auto const mac = 0;375
376376 mi::InputSink* sink;
377 auto event = mir::events::make_event(0, 0ns, mac, mir_input_event_modifier_none, mir_pointer_action_motion, 0,377 mi::EventBuilder* builder;
378 x, y, 0.0f, 0.0f, 0.0f, 0.0f);378 capture_input_sink(device, sink, builder);
379 hub.add_device(mt::fake_shared(device));
380
381 auto event = builder->pointer_event(0ns, mir_pointer_action_motion, 0, x, y, 0.0f, 0.0f, 0.0f, 0.0f);
379382
380 EXPECT_CALL(mock_cursor_listener, cursor_moved_to(x, y)).Times(1);383 EXPECT_CALL(mock_cursor_listener, cursor_moved_to(x, y)).Times(1);
381384
382 mi::InputSink* sink;
383 mi::EventBuilder* builder;
384 capture_input_sink(device, sink, builder);
385 hub.add_device(mt::fake_shared(device));
386
387 sink->handle_input(*event);385 sink->handle_input(*event);
388}386}
387
388TEST_F(InputDeviceHubTest, input_sink_tracks_modifier)
389{
390 using namespace ::testing;
391
392 mi::InputSink* key_board_sink;
393 mi::EventBuilder* key_event_builder;
394 std::shared_ptr<mi::Device> key_handle;
395
396 capture_input_sink(device, key_board_sink, key_event_builder);
397
398 InSequence seq;
399 EXPECT_CALL(mock_observer,device_added(_))
400 .WillOnce(SaveArg<0>(&key_handle));
401
402 hub.add_observer(mt::fake_shared(mock_observer));
403 hub.add_device(mt::fake_shared(device));
404
405 observer_loop.trigger_server_actions();
406
407 const MirInputEventModifiers shift_left = mir_input_event_modifier_shift_left | mir_input_event_modifier_shift;
408 auto shift_down =
409 key_event_builder->key_event(arbitrary_timestamp, mir_keyboard_action_down, 0, KEY_LEFTSHIFT);
410 auto shift_up =
411 key_event_builder->key_event(arbitrary_timestamp, mir_keyboard_action_up, 0, KEY_LEFTSHIFT);
412
413 EXPECT_CALL(mock_dispatcher, dispatch(mt::KeyWithModifiers(shift_left)));
414 EXPECT_CALL(mock_dispatcher, dispatch(mt::KeyWithModifiers(mir_input_event_modifier_none)));
415
416 key_board_sink->handle_input(*shift_down);
417 key_board_sink->handle_input(*shift_up);
418}
419
420TEST_F(InputDeviceHubTest, input_sink_unifies_modifier_state_accross_devices)
421{
422 using namespace ::testing;
423
424 mi::InputSink* mouse_sink;
425 mi::EventBuilder* mouse_event_builder;
426 mi::InputSink* key_board_sink;
427 mi::EventBuilder* key_event_builder;
428 std::shared_ptr<mi::Device> mouse_handle;
429 std::shared_ptr<mi::Device> key_handle;
430
431 capture_input_sink(device, mouse_sink, mouse_event_builder);
432 capture_input_sink(another_device, key_board_sink, key_event_builder);
433
434 InSequence seq;
435 EXPECT_CALL(mock_observer,device_added(_))
436 .WillOnce(SaveArg<0>(&mouse_handle));
437 EXPECT_CALL(mock_observer,device_added(_))
438 .WillOnce(SaveArg<0>(&key_handle));
439
440 hub.add_observer(mt::fake_shared(mock_observer));
441 hub.add_device(mt::fake_shared(device));
442 hub.add_device(mt::fake_shared(another_device));
443
444 observer_loop.trigger_server_actions();
445
446 const MirInputEventModifiers r_alt_modifier = mir_input_event_modifier_alt_right | mir_input_event_modifier_alt;
447 auto key =
448 key_event_builder->key_event(arbitrary_timestamp, mir_keyboard_action_down, 0, KEY_RIGHTALT);
449 auto motion =
450 mouse_event_builder->pointer_event(arbitrary_timestamp, mir_pointer_action_motion, 0, 12, 40, 0, 0, 12, 40);
451
452 EXPECT_CALL(mock_dispatcher, dispatch(mt::KeyWithModifiers(r_alt_modifier)));
453 EXPECT_CALL(mock_dispatcher, dispatch(mt::PointerEventWithModifiers(r_alt_modifier)));
454
455 key_board_sink->handle_input(*key);
456 mouse_sink->handle_input(*motion);
457
458 EXPECT_THAT(key_handle->id(), Ne(mouse_handle->id()));
459}
460
461TEST_F(InputDeviceHubTest, input_sink_reduces_modifier_state_accross_devices)
462{
463 using namespace ::testing;
464
465 mi::InputSink* mouse_sink;
466 mi::EventBuilder* mouse_event_builder;
467 mi::InputSink* key_board_sink_1;
468 mi::EventBuilder* key_event_builder_1;
469 mi::InputSink* key_board_sink_2;
470 mi::EventBuilder* key_event_builder_2;
471 std::shared_ptr<mi::Device> mouse_handle;
472 std::shared_ptr<mi::Device> key_handle_1;
473 std::shared_ptr<mi::Device> key_handle_2;
474
475 capture_input_sink(device, mouse_sink, mouse_event_builder);
476 capture_input_sink(another_device, key_board_sink_1, key_event_builder_1);
477 capture_input_sink(third_device, key_board_sink_2, key_event_builder_2);
478
479 InSequence seq;
480 EXPECT_CALL(mock_observer, device_added(_))
481 .WillOnce(SaveArg<0>(&mouse_handle));
482 EXPECT_CALL(mock_observer, device_added(_))
483 .WillOnce(SaveArg<0>(&key_handle_1));
484 EXPECT_CALL(mock_observer, device_added(_))
485 .WillOnce(SaveArg<0>(&key_handle_2));
486
487 hub.add_observer(mt::fake_shared(mock_observer));
488 hub.add_device(mt::fake_shared(device));
489 hub.add_device(mt::fake_shared(another_device));
490 hub.add_device(mt::fake_shared(third_device));
491
492 const MirInputEventModifiers r_alt_modifier = mir_input_event_modifier_alt_right | mir_input_event_modifier_alt;
493 const MirInputEventModifiers l_ctrl_modifier = mir_input_event_modifier_ctrl_left | mir_input_event_modifier_ctrl;
494 const MirInputEventModifiers combined_modifier = r_alt_modifier | l_ctrl_modifier;
495
496 observer_loop.trigger_server_actions();
497
498 auto alt_down = key_event_builder_1->key_event(arbitrary_timestamp, mir_keyboard_action_down, 0, KEY_RIGHTALT);
499 auto ctrl_down = key_event_builder_2->key_event(arbitrary_timestamp, mir_keyboard_action_down, 0, KEY_LEFTCTRL);
500 auto ctrl_up = key_event_builder_2->key_event(arbitrary_timestamp, mir_keyboard_action_up, 0, KEY_LEFTCTRL);
501
502 auto motion_1 =
503 mouse_event_builder->pointer_event(arbitrary_timestamp, mir_pointer_action_motion, 0, 12, 40, 0, 0, 12, 40);
504 auto motion_2 =
505 mouse_event_builder->pointer_event(arbitrary_timestamp, mir_pointer_action_motion, 0, 30, 50, 0, 0, 18, 10);
506
507 EXPECT_CALL(mock_dispatcher, dispatch(mt::KeyWithModifiers(r_alt_modifier)));
508 EXPECT_CALL(mock_dispatcher, dispatch(mt::KeyWithModifiers(combined_modifier)));
509 EXPECT_CALL(mock_dispatcher, dispatch(mt::PointerEventWithModifiers(combined_modifier)));
510 EXPECT_CALL(mock_dispatcher, dispatch(mt::KeyWithModifiers(r_alt_modifier)));
511 EXPECT_CALL(mock_dispatcher, dispatch(mt::PointerEventWithModifiers(r_alt_modifier)));
512
513 key_board_sink_1->handle_input(*alt_down);
514 key_board_sink_2->handle_input(*ctrl_down);
515 mouse_sink->handle_input(*motion_1);
516 key_board_sink_2->handle_input(*ctrl_up);
517 mouse_sink->handle_input(*motion_2);
518
519 EXPECT_THAT(key_handle_1->id(), Ne(key_handle_2->id()));
520}

Subscribers

People subscribed via source and target branches