Mir

Merge lp:~mir-team/mir/introduce-pointer-event into lp:mir

Proposed by Robert Carr
Status: Merged
Approved by: Andreas Pokorny
Approved revision: no longer in the source branch.
Merged at revision: 2228
Proposed branch: lp:~mir-team/mir/introduce-pointer-event
Merge into: lp:mir
Diff against target: 753 lines (+491/-33)
9 files modified
client-ABI-sha1sums (+2/-1)
common-ABI-sha1sums (+2/-1)
include/common/mir_toolkit/events/input/input_event.h (+12/-1)
include/common/mir_toolkit/events/input/pointer_input_event.h (+120/-0)
platform-ABI-sha1sums (+2/-1)
server-ABI-sha1sums (+2/-1)
src/client/symbols.map (+6/-0)
src/common/input/input_event.cpp (+137/-1)
tests/unit-tests/input/test_input_event.cpp (+208/-27)
To merge this branch: bzr merge lp:~mir-team/mir/introduce-pointer-event
Reviewer Review Type Date Requested Status
Andreas Pokorny (community) Approve
Alan Griffiths Approve
Daniel van Vugt Abstain
Cemil Azizoglu (community) Approve
Chris Halse Rogers Approve
PS Jenkins bot (community) continuous-integration Approve
Kevin DuBois (community) Approve
Review via email: mp+245679@code.launchpad.net

Commit message

Introduce MirPointerEvent

Description of the change

Introduce MirPointerEvents as distinguished from Mir touch events. Recognized via the device class flags provided by android input.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

needs fixing:
Shouldn't we have the new symbol be in its own stanza in the symbols.map for the client library?

needs info:
With MirPointerInputEventButtons, should we provide a flexible number of buttons?

review: Needs Fixing
Revision history for this message
Robert Carr (robertcarr) wrote :

>> Shouldn't we have the new symbol be in its own stanza in the symbols.map for the client library?

Ah...I didn't know about that. How does this work with the global: * catch in the MIR_CLIENT_8 stanza?

Updated anyway :)

>> With MirPointerInputEventButtons, should we provide a flexible number of buttons?

I've been thinking that once the device introspection API is available it will also be possible to obtain the identifiers for more buttons via that, then you can use the introspection API to query their names etc.

MirPointerInputEventButtons is a bit inflexible though so I've changed

MirPointerInputEventButtons mir_pointer_input_event_get_button_state(MirPointerEvent)

To

bool mir_pointer_input_event_get_button_state(MirPointerEvent, MirPointerInputEventButton)

This way the button enum is not using flags and it will be easier to expand/use other values in the future.

This way the pointer button enum doesnt have to be flags and wi to expand as time goes on.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

lgtm then

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

This distinction is confusing:

306 +// Differentiate between MirTouchInputEvents and MirPointerInputEvents based on old device class
307 +MirInputEventType type_from_device_class(int32_t source_class)
308 +{
309 + switch (source_class)
310 + {
311 + case AINPUT_SOURCE_MOUSE:
312 + case AINPUT_SOURCE_TRACKBALL:
313 + case AINPUT_SOURCE_TOUCHPAD:
314 + return mir_input_event_type_pointer;
315 + // Realistically touch events should only come from Stylus and Touchscreen
316 + // device classes...practically its not clear this is a safe assumption.
317 + default:
318 + return mir_input_event_type_touch;
319 + }
320 +}

If "pointer" events don't include the pointiest kind of input (stylus, finger) then we need to clarify the terminology. Perhaps:
   MirAbsoluteInputEvent (stylus, finger)
   MirRelativeInputEvent (mouse, trackball, touchpad)
   MirFocussedInputEvent (keyboard and other buttons)

review: Needs Fixing
Revision history for this message
Robert Carr (robertcarr) wrote :

>> If "pointer" events don't include the pointiest kind of input (stylus, finger)
>> then we need to clarify the terminology

Pointer refers to the system pointer/cursor rather than the "pointiness of the input".

This MP does leave some open questions....e.g. what becomes of joystick events, or how would you get access to raw relative events from a mouse?

This is to be addressed in future MPs through the distinction of raw and synthetic events. For mice, joysticks, etc, the raw event would feature the relative axis. In the case that the relative axis device is controlling the system pointer, a Pointer event will also be generated with a "synthesized_from" member referring to the raw event.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Ah OK. That does kind of clarify another question I had --
Do we mean something that's a physical pointer or something that results in a mouse arrow cursor on screen? I think "pointer" means the latter here.

It sounds like MirRelativeInputEvent might still be more appropriate. At the raw level, they are indeed relative input devices. Only when "cooked" do such devices gain a logical pointing location on screen.

Maybe to avoid confusion over different meanings of pointer, we should say the source of the input is a MirRelativeInputEvent, and that /moves/ a cursor. The ambiguous word "pointer" doesn't need to come into it.

Similarly, a MirAbsoluteInputEvent (digitizer pen) might also move a cursor, in absolute terms (LP: #1396421)

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

133 +/* Relative axis containing the speed of the vertical scroll wheel */
134 + mir_pointer_input_axis_vscroll = 2,
135 +/* Relative axis containing the speed of the horizontal scroll wheel */

speed -> change?

looks good to me otherwise

review: Needs Information
Revision history for this message
Robert Carr (robertcarr) wrote :

>> speed -> change?

Hey! You're back. Happy new years...we have some fun to have on evdev-input-platform ;)

Hmm. I agree its kind of confusing.

I think speed may be correct because change makes it seem like you are talking about change in the axis state over time. Imagine you are scrolling up and receive a +7...then you reverse the direction of your scroll...at one point you will hit +0 which has to be interpreted as a current scroll speed of zero, not a change in the scroll axis state over time (because the change would be zero). Likewise if this entire reveral of speed (say from +7 to -3) happens in a single input frame, -3 is not your change (which would be 10) but rather just your new negative speed.

I have this sinking feeling that I am turning things over wrong in my head though so will continue to think some today.

Revision history for this message
Robert Carr (robertcarr) wrote :

>>
>> It sounds like MirRelativeInputEvent might still be more appropriate. At the raw level, they are
>> indeed relative input devices. Only when "cooked" do such devices gain a logical pointing location
>> on screen.

Yes. Though I am imagining there will only be one MirRawInputEvent type, and the user can introspect whether a given axis is relative or absolute. It seems to be a good strategy to report input in frames which contain snapshots of device state...so it should be easy to mix relative and absolute axis on a single event (e.g. input frame).

>> Maybe to avoid confusion over different meanings of pointer, we should say the source of the input >> is a MirRelativeInputEvent, and that /moves/ a cursor. The ambiguous word "pointer" doesn't need to
>> come into it.

We are close to agreement :). In this model the source is a raw input event with relative axis, and a pointer event is synthesized from it. I don't think pointer is particularly ambiguous and there is a long history of using "pointer" or "cursor" to refer to the onscreen system....pointer/cursor. I don't think this meaning is diluted by the fact that other things have points.

>> Similarly, a MirAbsoluteInputEvent (digitizer pen) might also move a cursor, in absolute terms
>> (LP: #1396421)

Definitely you could enable this via the configuration API. In this case you would get raw absolute axis events, and rather than (in addition to?) a synthetic touch event would receive a synthetic pointer event.

Revision history for this message
Chris Halse Rogers (raof) wrote :

Globally: how difficult would it be to use a 24.8 fixed-point scheme? We do want subpixel motion precision, but we don't need all that much precision.

+ /* Axis values or button state has changed for the pointer */
122 + mir_pointer_input_event_action_change = 4

This appears to be a lie¹? It seems to only be for motion; perhaps it should be mir_pointer_input_event_motion?

I think mir_pointer_input_event_action_up/down might be better as mir_pointer_input_event_action_*button*_up/down? It doesn't make sense for a pointer to be up down.

Additionally, there doesn't seem to be a way to figure out *which* button went up/down? You can get the current state through get_button_state, but unless the client maintains the previous button states it can't work out what button changed.

Likewise, we can get the current axis values but not their changes. It would seem sensible for the client to be able to know which ones have changed?

133 +/* Relative axis containing the speed of the vertical scroll wheel */
134 + mir_pointer_input_axis_vscroll = 2,

Are we really reporting the time-derivative of the scroll axis values? Why? We don't get that from the kernel; we get the values themselves.

input_axis_vscroll and input_axis_hscroll should be relative axes. (Most) scroll wheels aren't joysticks; you can just keep spinning them :).

¹: Relevant bit is:
357 +MirPointerInputEventAction mir_pointer_input_event_get_action(MirPointerInputEvent const* pev)
...
373 + case mir_motion_action_move:
374 + case mir_motion_action_hover_move:
375 + case mir_motion_action_outside:
376 + default:
377 + return mir_pointer_input_event_action_change;

Revision history for this message
Chris Halse Rogers (raof) wrote :

Mark as needs-fixing, so it gets on my review list.

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I think the ease with which I found the word "pointer" confusing suggests I won't be the last one. We have an opportunity to choose less ambiguous terminology now. Probably not so much later.

Chris:
I don't think fixed point is necessarily better than floats for input. If you have fixed 24.8 (32-bit) then to avoid overflows you need to remember to always work with 64-bit numbers. And of course, you need to shift in the end to get to your whole numbers. OK, yes there's a performance advantage in doing lots of ops with ints instead of floats, but not as great as it used to be. Can anyone cite a specific case for input where sub-pixel precision is important?...

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

"Needs Fixing" because I think we should seize the opportunity to avoid introducing confusing wording with "pointer". Less ambiguous alternatives mentioned above.

review: Needs Fixing
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

> >> speed -> change?
>
> Hey! You're back. Happy new years...we have some fun to have on evdev-input-
> platform ;)
>
> Hmm. I agree its kind of confusing.
>
> I think speed may be correct because change makes it seem like you are talking
> about change in the axis state over time. Imagine you are scrolling up and
> receive a +7...then you reverse the direction of your scroll...at one point
> you will hit +0 which has to be interpreted as a current scroll speed of zero,
> not a change in the scroll axis state over time (because the change would be
> zero). Likewise if this entire reveral of speed (say from +7 to -3) happens in
> a single input frame, -3 is not your change (which would be 10) but rather
> just your new negative speed.
>
> I have this sinking feeling that I am turning things over wrong in my head
> though so will continue to think some today.

Yes in the example above I expect to find a change expressed as the value "-10" attached to the event. I believe you are exposing relative changes along the vertical and horizontal axis.
I do not think that you plan to measure the velocity here.. and expect users to integrate speed change events over time diffs, to get to the amount of ticks scrolled.

So I really think that you mean something like a delta expressed in ticks. How about "ticks"?

review: Needs Fixing
Revision history for this message
Robert Carr (robertcarr) wrote :

Fixed vscroll and hscroll comments...I got in to a weird state of confusion imagining spinning scroll balls ;)

Chris other comments:

Updated the actions now button_up and button_down and change...documentation should likewise be more accurate.

Revision history for this message
Robert Carr (robertcarr) wrote :

Chris: With respect to previous button and axis state I agree including it would be useful. Until we change the internal MirEvent representaiton it's difficult though. In the meantime clients will have to track the previous button state (just as they do now). Following the transition, we can add backwards compatible new functions to query the collection of changed axis and buttons.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote :

On Wed, Jan 14, 2015 at 6:35 PM, Daniel van Vugt
<email address hidden> wrote:
> I think the ease with which I found the word "pointer" confusing
> suggests I won't be the last one. We have an opportunity to choose
> less ambiguous terminology now. Probably not so much later.

I don't think we have a better candidate terminology available yet?

The thing is, pointer events *don't* come from any physical input
device; they come from a synthesised virtual pointer.

It shouldn't be called MirRelativeInputEvent because the (the x,y axes
of the event) event is absolute (and the vscroll, hscroll axes are
relative ☺).

And, as you note, absolute devices like the stylus on a tablet *can*
produce MirPointerInputEvents; it would be pretty weird if they
produced RelativeInputEvents.

We *could* have a different model; make everything MirInputDeviceEvent
and then have a special “device 0” virtual pointer device. I'm not
sure if that's any better, though.

>
> Chris:
> I don't think fixed point is necessarily better than floats for
> input. If you have fixed 24.8 (32-bit) then to avoid overflows you
> need to remember to always work with 64-bit numbers. And of course,
> you need to shift in the end to get to your whole numbers. OK, yes
> there's a performance advantage in doing lots of ops with ints
> instead of floats, but not as great as it used to be. Can anyone cite
> a specific case for input where sub-pixel precision is important?...

Sub-pixel precision is important for two cases:

For relative motion events it's flat out necessary - otherwise, it's
possible to move the mouse at a slow but reasonable speed without
generating any non-zero input events.

For absolute events it's necessary if you're doing any sort of
transformation.

Hm. I was suggesting fixed point in part because that's what we get out
of libinput, but it seems that libinput switched to double since I last
looked at it.

Since float will still give us 8bits of subpixel precision all the way
out to 65,000x65,000 pixel outputs that might be enough. The reasons
why we might want doubles include: that's what we get from libinput,
and it gives nested servers some headroom.

If we need to we can double later.

Revision history for this message
Chris Halse Rogers (raof) wrote :

Hm. Rather than “ticks” I think it would be better to describe the scroll axes as measured in pixels. The other axes are measured in pixels, and pixels are a useful unit for scrolling.

Otherwise, ok.

review: Approve
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

LGTM.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Alright, I trust all confusion will be resolved later. When we finish designing the client API ;)

review: Abstain
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

OK

review: Approve
Revision history for this message
Andreas Pokorny (andreas-pokorny) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'client-ABI-sha1sums'
2--- client-ABI-sha1sums 2015-01-14 08:52:38 +0000
3+++ client-ABI-sha1sums 2015-01-14 19:51:52 +0000
4@@ -15,8 +15,9 @@
5 f4d39e9893ce6308bddd83a49b90f0051f565323 include/common/mir_toolkit/event.h
6 2507f2929415aa423f9551d3c595c439fe1c6efd include/common/mir_toolkit/events/event_deprecated.h
7 cb2358a701db2b9c8d9ba1c877f29f834af259a7 include/common/mir_toolkit/events/event.h
8-c591a02a8e9851db342c310cf829d018a1eddb51 include/common/mir_toolkit/events/input/input_event.h
9+caaf95ea6c02570ab733ade70aba2ecea810b3a7 include/common/mir_toolkit/events/input/input_event.h
10 7748a12138474e9be218eeb8f14b372af0fcec7e include/common/mir_toolkit/events/input/key_input_event.h
11+489e8bae7c3e949ac449b09bd3bf554dae0e8986 include/common/mir_toolkit/events/input/pointer_input_event.h
12 de7c23453e6d897296f32e49d9ba952a1baa0200 include/common/mir_toolkit/events/input/touch_input_event.h
13 8642e85a50e2de651589da3ced70e0fc0a915f26 include/common/mir_toolkit/events/orientation_event.h
14 f623dcf3c2ed134c1be20106eb54bcccc84af462 include/common/mir_toolkit/events/prompt_session_event.h
15
16=== modified file 'common-ABI-sha1sums'
17--- common-ABI-sha1sums 2015-01-14 08:52:38 +0000
18+++ common-ABI-sha1sums 2015-01-14 19:51:52 +0000
19@@ -22,8 +22,9 @@
20 f4d39e9893ce6308bddd83a49b90f0051f565323 include/common/mir_toolkit/event.h
21 2507f2929415aa423f9551d3c595c439fe1c6efd include/common/mir_toolkit/events/event_deprecated.h
22 cb2358a701db2b9c8d9ba1c877f29f834af259a7 include/common/mir_toolkit/events/event.h
23-c591a02a8e9851db342c310cf829d018a1eddb51 include/common/mir_toolkit/events/input/input_event.h
24+caaf95ea6c02570ab733ade70aba2ecea810b3a7 include/common/mir_toolkit/events/input/input_event.h
25 7748a12138474e9be218eeb8f14b372af0fcec7e include/common/mir_toolkit/events/input/key_input_event.h
26+489e8bae7c3e949ac449b09bd3bf554dae0e8986 include/common/mir_toolkit/events/input/pointer_input_event.h
27 de7c23453e6d897296f32e49d9ba952a1baa0200 include/common/mir_toolkit/events/input/touch_input_event.h
28 8642e85a50e2de651589da3ced70e0fc0a915f26 include/common/mir_toolkit/events/orientation_event.h
29 f623dcf3c2ed134c1be20106eb54bcccc84af462 include/common/mir_toolkit/events/prompt_session_event.h
30
31=== modified file 'include/common/mir_toolkit/events/input/input_event.h'
32--- include/common/mir_toolkit/events/input/input_event.h 2014-12-17 00:03:09 +0000
33+++ include/common/mir_toolkit/events/input/input_event.h 2015-01-14 19:51:52 +0000
34@@ -35,7 +35,8 @@
35
36 typedef enum {
37 mir_input_event_type_key = 0,
38- mir_input_event_type_touch = 1
39+ mir_input_event_type_touch = 1,
40+ mir_input_event_type_pointer = 2
41 } MirInputEventType;
42
43 /**
44@@ -69,6 +70,7 @@
45
46 #include "mir_toolkit/events/input/touch_input_event.h"
47 #include "mir_toolkit/events/input/key_input_event.h"
48+#include "mir_toolkit/events/input/pointer_input_event.h"
49
50 #ifdef __cplusplus
51 /**
52@@ -120,6 +122,15 @@
53 */
54 MirTouchInputEvent const* mir_input_event_get_touch_input_event(MirInputEvent const* ev);
55
56+/*
57+ * Retrieve the MirPointerInputEvent associated with a given input event.
58+ *
59+ * \param[in] event The input event
60+ * \return The MirPointerInputEvent or NULL if event type is not
61+ * mir_input_event_type_pointer
62+ */
63+MirPointerInputEvent const* mir_input_event_get_pointer_input_event(MirInputEvent const* ev);
64+
65 #ifdef __cplusplus
66 }
67 /**@}*/
68
69=== added file 'include/common/mir_toolkit/events/input/pointer_input_event.h'
70--- include/common/mir_toolkit/events/input/pointer_input_event.h 1970-01-01 00:00:00 +0000
71+++ include/common/mir_toolkit/events/input/pointer_input_event.h 2015-01-14 19:51:52 +0000
72@@ -0,0 +1,120 @@
73+/*
74+ * Copyright © 2015 Canonical Ltd.
75+ *
76+ * This program is free software: you can redistribute it and/or modify it
77+ * under the terms of the GNU Lesser General Public License version 3,
78+ * as published by the Free Software Foundation.
79+ *
80+ * This program is distributed in the hope that it will be useful,
81+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
82+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
83+ * GNU Lesser General Public License for more details.
84+ *
85+ * You should have received a copy of the GNU Lesser General Public License
86+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
87+ *
88+ * Authored by: Robert Carr <robert.carr@canonical.com>
89+ */
90+
91+#ifndef MIR_TOOLKIT_POINTER_INPUT_EVENT_H_
92+#define MIR_TOOLKIT_POINTER_INPUT_EVENT_H_
93+
94+#include <stdbool.h>
95+
96+#ifdef __cplusplus
97+/**
98+ * \addtogroup mir_toolkit
99+ * @{
100+ */
101+extern "C" {
102+#endif
103+
104+/**
105+ * An event type describing a change in pointer device state.
106+ */
107+typedef struct MirPointerInputEvent MirPointerInputEvent;
108+
109+/**
110+ * Possible pointer actions
111+ */
112+typedef enum {
113+ /* A pointer button has come up */
114+ mir_pointer_input_event_action_button_up = 0,
115+ /* A pointer button has gone down */
116+ mir_pointer_input_event_action_button_down = 1,
117+ /* The pointer has entered the surface to which this event was delivered */
118+ mir_pointer_input_event_action_enter = 2,
119+ /* The pointer has left the surface to which this event was delivered */
120+ mir_pointer_input_event_action_leave = 3,
121+ /* Axis values have changed for the pointer */
122+ mir_pointer_input_event_action_motion = 4
123+} MirPointerInputEventAction;
124+
125+/**
126+ * Identifiers for pointer axis
127+ */
128+typedef enum {
129+/* Absolute axis containing the x coordinate of the pointer */
130+ mir_pointer_input_axis_x = 0,
131+/* Absolute axis containing the y coordinate of the pointer */
132+ mir_pointer_input_axis_y = 1,
133+/* Relative axis containing ticks reported by the vertical scroll wheel */
134+ mir_pointer_input_axis_vscroll = 2,
135+/* Relative axis containing ticks reported by the horizontal scroll wheel */
136+ mir_pointer_input_axis_hscroll = 3
137+} MirPointerInputEventAxis;
138+
139+/*
140+ * Identifiers for pointer buttons
141+ */
142+typedef enum {
143+ mir_pointer_input_button_primary = 1,
144+ mir_pointer_input_button_secondary = 2,
145+ mir_pointer_input_button_tertiary = 3,
146+ mir_pointer_input_button_back = 4,
147+ mir_pointer_input_button_forward = 5
148+} MirPointerInputEventButton;
149+
150+/**
151+ * Retrieve the modifier keys pressed when the pointer action occured.
152+ *
153+ * \param [in] event The pointer event
154+ * \return The modifier mask
155+ */
156+MirInputEventModifiers mir_pointer_input_event_get_modifiers(MirPointerInputEvent const* event);
157+
158+/**
159+ * Retrieve the action which occured to generate a given pointer event.
160+ *
161+ * \param [in] event The pointer event
162+ * \return Action performed by the pointer
163+ */
164+MirPointerInputEventAction mir_pointer_input_event_get_action(MirPointerInputEvent const* event);
165+
166+/**
167+ * Retrieve the state of a given pointer button when the action occurred.
168+ *
169+ * \param [in] event The pointer event
170+ * \param [in] button The button to check
171+ *
172+ * \return Whether the given button is depressed
173+ */
174+bool mir_pointer_input_event_get_button_state(MirPointerInputEvent const* event,
175+ MirPointerInputEventButton button);
176+
177+/**
178+ * Retrieve the axis value reported by a given pointer event.
179+ *
180+ * \param [in] event The pointer event
181+ * \param [in] axis The axis to retreive a value from
182+ * \return The value of the given axis
183+ */
184+float mir_pointer_input_event_get_axis_value(MirPointerInputEvent const* event,
185+ MirPointerInputEventAxis axis);
186+
187+#ifdef __cplusplus
188+}
189+/**@}*/
190+#endif
191+
192+#endif /* MIR_TOOLKIT_POINTER_INPUT_EVENT_H_ */
193
194=== modified file 'platform-ABI-sha1sums'
195--- platform-ABI-sha1sums 2015-01-14 08:52:38 +0000
196+++ platform-ABI-sha1sums 2015-01-14 19:51:52 +0000
197@@ -22,8 +22,9 @@
198 f4d39e9893ce6308bddd83a49b90f0051f565323 include/common/mir_toolkit/event.h
199 2507f2929415aa423f9551d3c595c439fe1c6efd include/common/mir_toolkit/events/event_deprecated.h
200 cb2358a701db2b9c8d9ba1c877f29f834af259a7 include/common/mir_toolkit/events/event.h
201-c591a02a8e9851db342c310cf829d018a1eddb51 include/common/mir_toolkit/events/input/input_event.h
202+caaf95ea6c02570ab733ade70aba2ecea810b3a7 include/common/mir_toolkit/events/input/input_event.h
203 7748a12138474e9be218eeb8f14b372af0fcec7e include/common/mir_toolkit/events/input/key_input_event.h
204+489e8bae7c3e949ac449b09bd3bf554dae0e8986 include/common/mir_toolkit/events/input/pointer_input_event.h
205 de7c23453e6d897296f32e49d9ba952a1baa0200 include/common/mir_toolkit/events/input/touch_input_event.h
206 8642e85a50e2de651589da3ced70e0fc0a915f26 include/common/mir_toolkit/events/orientation_event.h
207 f623dcf3c2ed134c1be20106eb54bcccc84af462 include/common/mir_toolkit/events/prompt_session_event.h
208
209=== modified file 'server-ABI-sha1sums'
210--- server-ABI-sha1sums 2015-01-14 08:52:38 +0000
211+++ server-ABI-sha1sums 2015-01-14 19:51:52 +0000
212@@ -22,8 +22,9 @@
213 f4d39e9893ce6308bddd83a49b90f0051f565323 include/common/mir_toolkit/event.h
214 2507f2929415aa423f9551d3c595c439fe1c6efd include/common/mir_toolkit/events/event_deprecated.h
215 cb2358a701db2b9c8d9ba1c877f29f834af259a7 include/common/mir_toolkit/events/event.h
216-c591a02a8e9851db342c310cf829d018a1eddb51 include/common/mir_toolkit/events/input/input_event.h
217+caaf95ea6c02570ab733ade70aba2ecea810b3a7 include/common/mir_toolkit/events/input/input_event.h
218 7748a12138474e9be218eeb8f14b372af0fcec7e include/common/mir_toolkit/events/input/key_input_event.h
219+489e8bae7c3e949ac449b09bd3bf554dae0e8986 include/common/mir_toolkit/events/input/pointer_input_event.h
220 de7c23453e6d897296f32e49d9ba952a1baa0200 include/common/mir_toolkit/events/input/touch_input_event.h
221 8642e85a50e2de651589da3ced70e0fc0a915f26 include/common/mir_toolkit/events/orientation_event.h
222 f623dcf3c2ed134c1be20106eb54bcccc84af462 include/common/mir_toolkit/events/prompt_session_event.h
223
224=== modified file 'src/client/symbols.map'
225--- src/client/symbols.map 2015-01-14 02:35:56 +0000
226+++ src/client/symbols.map 2015-01-14 19:51:52 +0000
227@@ -36,5 +36,11 @@
228 } MIR_CLIENT_8.1;
229
230 MIR_CLIENT_8.3 {
231+ global:
232+ mir_input_event_get_pointer_input_event;
233+ mir_pointer_input_event_get_modifiers;
234+ mir_pointer_input_event_get_action;
235+ mir_pointer_input_event_get_button_state;
236+ mir_pointer_input_event_get_axis_value;
237 mir_connection_create_spec_for_menu_surface;
238 } MIR_CLIENT_8.2;
239\ No newline at end of file
240
241=== modified file 'src/common/input/input_event.cpp'
242--- src/common/input/input_event.cpp 2014-12-17 21:44:45 +0000
243+++ src/common/input/input_event.cpp 2015-01-14 19:51:52 +0000
244@@ -58,22 +58,75 @@
245 }
246 }
247
248+// Never exposed in old event, so lets avoid leaking it in to a header now.
249+enum
250+{
251+ AINPUT_SOURCE_CLASS_MASK = 0x000000ff,
252+
253+ AINPUT_SOURCE_CLASS_BUTTON = 0x00000001,
254+ AINPUT_SOURCE_CLASS_POINTER = 0x00000002,
255+ AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004,
256+ AINPUT_SOURCE_CLASS_POSITION = 0x00000008,
257+ AINPUT_SOURCE_CLASS_JOYSTICK = 0x00000010
258+};
259+enum
260+{
261+ AINPUT_SOURCE_UNKNOWN = 0x00000000,
262+
263+ AINPUT_SOURCE_KEYBOARD = 0x00000100 | AINPUT_SOURCE_CLASS_BUTTON,
264+ AINPUT_SOURCE_DPAD = 0x00000200 | AINPUT_SOURCE_CLASS_BUTTON,
265+ AINPUT_SOURCE_GAMEPAD = 0x00000400 | AINPUT_SOURCE_CLASS_BUTTON,
266+ AINPUT_SOURCE_TOUCHSCREEN = 0x00001000 | AINPUT_SOURCE_CLASS_POINTER,
267+ AINPUT_SOURCE_MOUSE = 0x00002000 | AINPUT_SOURCE_CLASS_POINTER,
268+ AINPUT_SOURCE_STYLUS = 0x00004000 | AINPUT_SOURCE_CLASS_POINTER,
269+ AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION,
270+ AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION,
271+ AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
272+
273+ AINPUT_SOURCE_ANY = 0xffffff00
274+};
275+
276 MirEvent const* old_ev_from_new(MirInputEvent const* ev)
277 {
278 return reinterpret_cast<MirEvent const*>(ev);
279 }
280+
281 MirKeyEvent const& old_kev_from_new(MirKeyInputEvent const* ev)
282 {
283 auto old_ev = reinterpret_cast<MirEvent const*>(ev);
284 expect_old_event_type(old_ev, mir_event_type_key);
285 return old_ev->key;
286 }
287+
288 MirMotionEvent const& old_mev_from_new(MirTouchInputEvent const* ev)
289 {
290 auto old_ev = reinterpret_cast<MirEvent const*>(ev);
291 expect_old_event_type(old_ev, mir_event_type_motion);
292 return old_ev->motion;
293 }
294+
295+MirMotionEvent const& old_mev_from_new(MirPointerInputEvent const* ev)
296+{
297+ auto old_ev = reinterpret_cast<MirEvent const*>(ev);
298+ expect_old_event_type(old_ev, mir_event_type_motion);
299+ return old_ev->motion;
300+}
301+
302+// Differentiate between MirTouchInputEvents and MirPointerInputEvents based on old device class
303+MirInputEventType type_from_device_class(int32_t source_class)
304+{
305+ switch (source_class)
306+ {
307+ case AINPUT_SOURCE_MOUSE:
308+ case AINPUT_SOURCE_TRACKBALL:
309+ case AINPUT_SOURCE_TOUCHPAD:
310+ return mir_input_event_type_pointer;
311+ // Realistically touch events should only come from Stylus and Touchscreen
312+ // device classes...practically its not clear this is a safe assumption.
313+ default:
314+ return mir_input_event_type_touch;
315+ }
316+}
317 }
318
319 MirInputEventType mir_input_event_get_type(MirInputEvent const* ev)
320@@ -91,7 +144,7 @@
321 case mir_event_type_key:
322 return mir_input_event_type_key;
323 case mir_event_type_motion:
324- return mir_input_event_type_touch;
325+ return type_from_device_class(old_ev->motion.source_id);
326 default:
327 abort();
328 }
329@@ -377,3 +430,86 @@
330 return -1;
331 }
332 }
333+
334+/* Pointer event accessors */
335+MirPointerInputEvent const* mir_input_event_get_pointer_input_event(MirInputEvent const* ev)
336+{
337+ if(mir_input_event_get_type(ev) != mir_input_event_type_pointer)
338+ {
339+ mir::log_critical("expected pointer input event but event was of type " +
340+ input_event_type_to_string(mir_input_event_get_type(ev)));
341+ abort();
342+ }
343+
344+ return reinterpret_cast<MirPointerInputEvent const*>(ev);
345+}
346+
347+MirInputEventModifiers mir_pointer_input_event_get_modifiers(MirPointerInputEvent const* pev)
348+{
349+ auto const& old_mev = old_mev_from_new(pev);
350+ return old_modifiers_to_new(static_cast<MirKeyModifier>(old_mev.modifiers));
351+}
352+
353+MirPointerInputEventAction mir_pointer_input_event_get_action(MirPointerInputEvent const* pev)
354+{
355+ auto const& old_mev = old_mev_from_new(pev);
356+ auto masked_action = old_mev.action & MIR_EVENT_ACTION_MASK;
357+ switch (masked_action)
358+ {
359+ case mir_motion_action_up:
360+ case mir_motion_action_pointer_up:
361+ return mir_pointer_input_event_action_button_up;
362+ case mir_motion_action_down:
363+ case mir_motion_action_pointer_down:
364+ return mir_pointer_input_event_action_button_down;
365+ case mir_motion_action_hover_enter:
366+ return mir_pointer_input_event_action_enter;
367+ case mir_motion_action_hover_exit:
368+ return mir_pointer_input_event_action_leave;
369+ case mir_motion_action_move:
370+ case mir_motion_action_hover_move:
371+ case mir_motion_action_outside:
372+ default:
373+ return mir_pointer_input_event_action_motion;
374+ }
375+}
376+
377+bool mir_pointer_input_event_get_button_state(MirPointerInputEvent const* pev,
378+ MirPointerInputEventButton button)
379+{
380+ auto const& old_mev = old_mev_from_new(pev);
381+ switch (button)
382+ {
383+ case mir_pointer_input_button_primary:
384+ return old_mev.button_state & mir_motion_button_primary;
385+ case mir_pointer_input_button_secondary:
386+ return old_mev.button_state & mir_motion_button_secondary;
387+ case mir_pointer_input_button_tertiary:
388+ return old_mev.button_state & mir_motion_button_tertiary;
389+ case mir_pointer_input_button_back:
390+ return old_mev.button_state & mir_motion_button_back;
391+ case mir_pointer_input_button_forward:
392+ return old_mev.button_state & mir_motion_button_forward;
393+ default:
394+ return false;
395+ }
396+}
397+
398+float mir_pointer_input_event_get_axis_value(MirPointerInputEvent const* pev, MirPointerInputEventAxis axis)
399+{
400+ auto const& old_mev = old_mev_from_new(pev);
401+ switch (axis)
402+ {
403+ case mir_pointer_input_axis_x:
404+ return old_mev.pointer_coordinates[0].x;
405+ case mir_pointer_input_axis_y:
406+ return old_mev.pointer_coordinates[0].y;
407+ case mir_pointer_input_axis_vscroll:
408+ return old_mev.pointer_coordinates[0].vscroll;
409+ case mir_pointer_input_axis_hscroll:
410+ return old_mev.pointer_coordinates[0].hscroll;
411+ default:
412+ mir::log_critical("Invalid axis enumeration " + std::to_string(axis));
413+ abort();
414+ }
415+}
416
417=== modified file 'tests/unit-tests/input/test_input_event.cpp'
418--- tests/unit-tests/input/test_input_event.cpp 2014-12-17 00:03:09 +0000
419+++ tests/unit-tests/input/test_input_event.cpp 2015-01-14 19:51:52 +0000
420@@ -24,17 +24,65 @@
421 // See: https://bugs.launchpad.net/mir/+bug/1311699
422 #define MIR_EVENT_ACTION_POINTER_INDEX_MASK 0xff00
423 #define MIR_EVENT_ACTION_POINTER_INDEX_SHIFT 8;
424-
425-TEST(InputEvent, old_style_key_and_motion_events_are_input_events)
426+#define MIR_EVENT_ACTION_MASK 0xff
427+
428+// TODO: Refactor event initializers
429+
430+namespace
431+{
432+// Never exposed in old event, so lets avoid leaking it in to a header now.
433+enum
434+{
435+ AINPUT_SOURCE_CLASS_MASK = 0x000000ff,
436+
437+ AINPUT_SOURCE_CLASS_BUTTON = 0x00000001,
438+ AINPUT_SOURCE_CLASS_POINTER = 0x00000002,
439+ AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004,
440+ AINPUT_SOURCE_CLASS_POSITION = 0x00000008,
441+ AINPUT_SOURCE_CLASS_JOYSTICK = 0x00000010
442+};
443+enum
444+{
445+ AINPUT_SOURCE_UNKNOWN = 0x00000000,
446+
447+ AINPUT_SOURCE_KEYBOARD = 0x00000100 | AINPUT_SOURCE_CLASS_BUTTON,
448+ AINPUT_SOURCE_DPAD = 0x00000200 | AINPUT_SOURCE_CLASS_BUTTON,
449+ AINPUT_SOURCE_GAMEPAD = 0x00000400 | AINPUT_SOURCE_CLASS_BUTTON,
450+ AINPUT_SOURCE_TOUCHSCREEN = 0x00001000 | AINPUT_SOURCE_CLASS_POINTER,
451+ AINPUT_SOURCE_MOUSE = 0x00002000 | AINPUT_SOURCE_CLASS_POINTER,
452+ AINPUT_SOURCE_STYLUS = 0x00004000 | AINPUT_SOURCE_CLASS_POINTER,
453+ AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION,
454+ AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION,
455+ AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
456+
457+ AINPUT_SOURCE_ANY = 0xffffff00
458+};
459+
460+MirEvent a_key_ev()
461 {
462 MirEvent key_ev;
463 key_ev.type = mir_event_type_key;
464+ return key_ev;
465+}
466+
467+MirEvent a_motion_ev(int device_class = AINPUT_SOURCE_UNKNOWN)
468+{
469+ MirEvent motion_ev;
470+ motion_ev.type = mir_event_type_motion;
471+ motion_ev.motion.source_id = device_class;
472+ return motion_ev;
473+}
474+
475+}
476+
477+TEST(InputEvent, old_style_key_and_motion_events_are_input_events)
478+{
479+ auto key_ev = a_key_ev();
480
481 EXPECT_EQ(mir_event_type_input, mir_event_get_type(&key_ev));
482 EXPECT_EQ(mir_input_event_type_key, mir_input_event_get_type(mir_event_get_input_event(&key_ev)));
483
484- MirEvent motion_ev;
485- motion_ev.type = mir_event_type_motion;
486+ auto motion_ev = a_motion_ev();
487
488 EXPECT_EQ(mir_event_type_input, mir_event_get_type(&motion_ev));
489 EXPECT_NE(nullptr, mir_event_get_input_event(&motion_ev));
490@@ -45,7 +93,7 @@
491 TEST(CommonInputEventProperties, device_id_taken_from_old_style_event)
492 {
493 int64_t dev_id_1 = 17, dev_id_2 = 23;
494- MirEvent old_ev;
495+ auto old_ev = a_motion_ev();
496
497 old_ev.type = mir_event_type_motion;
498 old_ev.motion.device_id = dev_id_1;
499@@ -61,9 +109,8 @@
500 TEST(CommonInputEventProperties, event_time_taken_from_old_style_event)
501 {
502 int64_t event_time_1 = 79, event_time_2 = 83;
503- MirEvent old_ev;
504-
505- old_ev.type = mir_event_type_motion;
506+ auto old_ev = a_motion_ev();
507+
508 old_ev.motion.event_time = event_time_1;
509 EXPECT_EQ(event_time_1, mir_input_event_get_event_time(
510 mir_event_get_input_event(&old_ev)));
511@@ -76,8 +123,7 @@
512
513 TEST(KeyInputEventProperties, up_and_down_actions_copied_from_old_style_event)
514 {
515- MirEvent old_ev;
516- old_ev.type = mir_event_type_key;
517+ auto old_ev = a_key_ev();
518
519 old_ev.key.action = mir_key_action_down;
520 old_ev.key.repeat_count = 0;
521@@ -91,8 +137,8 @@
522
523 TEST(KeyInputEventProperties, repeat_action_produced_from_non_zero_repeat_count_in_old_style_event)
524 {
525- MirEvent old_ev;
526- old_ev.type = mir_event_type_key;
527+ auto old_ev = a_key_ev();
528+
529 old_ev.key.action = mir_key_action_down;
530 old_ev.key.repeat_count = 1;
531
532@@ -106,8 +152,7 @@
533 int scan_code = 31;
534 MirKeyModifier old_modifiers = mir_key_modifier_shift;
535
536- MirEvent old_ev;
537- old_ev.type = mir_event_type_key;
538+ auto old_ev = a_key_ev();
539 old_ev.key.key_code = key_code;
540 old_ev.key.scan_code = scan_code;
541 old_ev.key.modifiers = old_modifiers;
542@@ -121,9 +166,8 @@
543 TEST(TouchInputEventProperties, touch_count_taken_from_pointer_count)
544 {
545 unsigned const pointer_count = 3;
546+ auto old_ev = a_motion_ev(AINPUT_SOURCE_TOUCHSCREEN);
547
548- MirEvent old_ev;
549- old_ev.type = mir_event_type_motion;
550 old_ev.motion.action = mir_motion_action_down;
551 old_ev.motion.pointer_count = pointer_count;
552
553@@ -134,8 +178,8 @@
554 TEST(TouchInputEventProperties, touch_id_comes_from_pointer_coordinates)
555 {
556 unsigned const touch_id = 31;
557- MirEvent old_ev;
558- old_ev.type = mir_event_type_motion;
559+ auto old_ev = a_motion_ev(AINPUT_SOURCE_TOUCHSCREEN);
560+
561 old_ev.motion.action = mir_motion_action_down;
562 old_ev.motion.pointer_count = 1;
563 old_ev.motion.pointer_coordinates[0].id = touch_id;
564@@ -147,8 +191,7 @@
565 // mir_motion_action_up/down represent the start of a gesture. pointers only go up/down one at a time
566 TEST(TouchInputEventProperties, down_and_up_actions_are_taken_from_old_event)
567 {
568- MirEvent old_ev;
569- old_ev.type = mir_event_type_motion;
570+ auto old_ev = a_motion_ev(AINPUT_SOURCE_TOUCHSCREEN);
571 old_ev.motion.action = mir_motion_action_down;
572 old_ev.motion.pointer_count = 1;
573
574@@ -156,12 +199,11 @@
575 EXPECT_EQ(mir_touch_input_event_action_down, mir_touch_input_event_get_touch_action(tev, 0));
576 }
577
578-TEST(TouchInputEventProperties, pointer_up_down_applies_only_to_masked_action)
579+TEST(TouchInputEventProperties, touch_up_down_applies_only_to_masked_action)
580 {
581 int const masked_pointer_index = 1;
582
583- MirEvent old_ev;
584- old_ev.type = mir_event_type_motion;
585+ auto old_ev = a_motion_ev(AINPUT_SOURCE_TOUCHSCREEN);
586 old_ev.motion.action = masked_pointer_index << MIR_EVENT_ACTION_POINTER_INDEX_SHIFT;
587 old_ev.motion.action = (old_ev.motion.action & MIR_EVENT_ACTION_POINTER_INDEX_MASK) | mir_motion_action_pointer_up;
588 old_ev.motion.pointer_count = 3;
589@@ -174,8 +216,7 @@
590
591 TEST(TouchInputEventProperties, tool_type_copied_from_old_pc)
592 {
593- MirEvent old_ev;
594- old_ev.type = mir_event_type_motion;
595+ auto old_ev = a_motion_ev(AINPUT_SOURCE_TOUCHSCREEN);
596
597 auto& old_mev = old_ev.motion;
598 old_mev.pointer_count = 4;
599@@ -193,8 +234,7 @@
600 TEST(TouchInputEventProperties, axis_values_used_by_qtmir_copied)
601 {
602 float x_value = 19, y_value = 23, touch_major = .3, touch_minor = .2, pressure = .9, size = 1111;
603- MirEvent old_ev;
604- old_ev.type = mir_event_type_motion;
605+ auto old_ev = a_motion_ev(AINPUT_SOURCE_TOUCHSCREEN);
606 old_ev.motion.pointer_count = 1;
607 auto &old_pc = old_ev.motion.pointer_coordinates[0];
608 old_pc.x = x_value;
609@@ -212,3 +252,144 @@
610 EXPECT_EQ(pressure, mir_touch_input_event_get_touch_axis_value(tev, 0, mir_touch_input_axis_pressure));
611 EXPECT_EQ(size, mir_touch_input_event_get_touch_axis_value(tev, 0, mir_touch_input_axis_size));
612 }
613+
614+/* Pointer and touch event differentiation */
615+
616+namespace
617+{
618+struct DeviceClassTestParameters
619+{
620+ MirInputEventType expected_type;
621+ int32_t device_class;
622+};
623+
624+struct DeviceClassTest : public testing::Test, testing::WithParamInterface<DeviceClassTestParameters>
625+{
626+};
627+}
628+
629+TEST_P(DeviceClassTest, pointer_and_touch_events_differentiated_on_device_class)
630+{
631+ auto const& param = GetParam();
632+ auto old_ev = a_motion_ev(param.device_class);
633+
634+ auto iev = mir_event_get_input_event(&old_ev);
635+ EXPECT_EQ(param.expected_type, mir_input_event_get_type(iev));
636+}
637+
638+INSTANTIATE_TEST_CASE_P(MouseDeviceClassTest,
639+ DeviceClassTest, ::testing::Values(DeviceClassTestParameters{mir_input_event_type_pointer, AINPUT_SOURCE_MOUSE}));
640+
641+INSTANTIATE_TEST_CASE_P(TouchpadDeviceClassTest,
642+ DeviceClassTest, ::testing::Values(DeviceClassTestParameters{mir_input_event_type_pointer, AINPUT_SOURCE_TOUCHPAD}));
643+
644+INSTANTIATE_TEST_CASE_P(TrackballDeviceClassTest,
645+ DeviceClassTest, ::testing::Values(DeviceClassTestParameters{mir_input_event_type_pointer, AINPUT_SOURCE_TRACKBALL}));
646+
647+INSTANTIATE_TEST_CASE_P(TouchscreenDeviceClassTest,
648+ DeviceClassTest, ::testing::Values(DeviceClassTestParameters{mir_input_event_type_touch, AINPUT_SOURCE_TOUCHSCREEN}));
649+
650+INSTANTIATE_TEST_CASE_P(StylusDeviceClassTest,
651+ DeviceClassTest, ::testing::Values(DeviceClassTestParameters{mir_input_event_type_touch, AINPUT_SOURCE_STYLUS}));
652+
653+/* Pointer event property accessors */
654+
655+TEST(PointerInputEventProperties, modifiers_taken_from_old_style_ev)
656+{
657+ auto old_ev = a_motion_ev(AINPUT_SOURCE_MOUSE);
658+ old_ev.motion.modifiers = mir_key_modifier_shift;
659+
660+ auto pointer_event =
661+ mir_input_event_get_pointer_input_event(mir_event_get_input_event(&old_ev));
662+ EXPECT_EQ(mir_input_event_modifier_shift, mir_pointer_input_event_get_modifiers(pointer_event));
663+}
664+
665+namespace
666+{
667+struct ActionTestParameters
668+{
669+ MirMotionAction old_action;
670+ MirPointerInputEventAction new_action;
671+};
672+
673+struct MotionToPointerActionTest : public testing::Test, testing::WithParamInterface<ActionTestParameters>
674+{
675+};
676+}
677+
678+TEST_P(MotionToPointerActionTest, old_style_action_translated_to_new_style)
679+{
680+ auto const& params = GetParam();
681+
682+ auto old_ev = a_motion_ev(AINPUT_SOURCE_MOUSE);
683+
684+ auto shift = 0 << MIR_EVENT_ACTION_POINTER_INDEX_SHIFT;
685+ old_ev.motion.action = (shift & MIR_EVENT_ACTION_POINTER_INDEX_MASK) | params.old_action;
686+ EXPECT_EQ(params.new_action,
687+ mir_pointer_input_event_get_action(mir_input_event_get_pointer_input_event(mir_event_get_input_event(&old_ev))));
688+}
689+
690+INSTANTIATE_TEST_CASE_P(MotionPointerUpTest,
691+ MotionToPointerActionTest, ::testing::Values(
692+ ActionTestParameters{mir_motion_action_pointer_up, mir_pointer_input_event_action_button_up}));
693+
694+INSTANTIATE_TEST_CASE_P(MotionPointerDownTest,
695+ MotionToPointerActionTest, ::testing::Values(
696+ ActionTestParameters{mir_motion_action_pointer_down, mir_pointer_input_event_action_button_down}));
697+
698+INSTANTIATE_TEST_CASE_P(MotionEnterTest,
699+ MotionToPointerActionTest, ::testing::Values(
700+ ActionTestParameters{mir_motion_action_hover_enter, mir_pointer_input_event_action_enter}));
701+
702+INSTANTIATE_TEST_CASE_P(MotionLeaveTest,
703+ MotionToPointerActionTest, ::testing::Values(
704+ ActionTestParameters{mir_motion_action_hover_exit, mir_pointer_input_event_action_leave}));
705+
706+INSTANTIATE_TEST_CASE_P(MotionPointerMoveTest,
707+ MotionToPointerActionTest, ::testing::Values(
708+ ActionTestParameters{mir_motion_action_move, mir_pointer_input_event_action_motion}));
709+
710+INSTANTIATE_TEST_CASE_P(MotionPointerHoverMoveTest,
711+ MotionToPointerActionTest, ::testing::Values(
712+ ActionTestParameters{mir_motion_action_hover_move, mir_pointer_input_event_action_motion}));
713+
714+INSTANTIATE_TEST_CASE_P(MotionPointerOutsideMoveTest,
715+ MotionToPointerActionTest, ::testing::Values(
716+ ActionTestParameters{mir_motion_action_outside, mir_pointer_input_event_action_motion}));
717+
718+TEST(PointerInputEventProperties, button_state_translated)
719+{
720+ auto old_ev = a_motion_ev(AINPUT_SOURCE_MOUSE);
721+
722+ old_ev.motion.button_state = mir_motion_button_primary;
723+ auto pev = mir_input_event_get_pointer_input_event(mir_event_get_input_event(&old_ev));
724+
725+ EXPECT_TRUE(mir_pointer_input_event_get_button_state(pev, mir_pointer_input_button_primary));
726+ EXPECT_FALSE(mir_pointer_input_event_get_button_state(pev, mir_pointer_input_button_secondary));
727+
728+ old_ev.motion.button_state = static_cast<MirMotionButton>(old_ev.motion.button_state | (mir_motion_button_secondary));
729+
730+ EXPECT_TRUE(mir_pointer_input_event_get_button_state(pev, mir_pointer_input_button_primary));
731+ EXPECT_TRUE(mir_pointer_input_event_get_button_state(pev, mir_pointer_input_button_secondary));
732+
733+ EXPECT_FALSE(mir_pointer_input_event_get_button_state(pev, mir_pointer_input_button_tertiary));
734+ EXPECT_FALSE(mir_pointer_input_event_get_button_state(pev, mir_pointer_input_button_back));
735+ EXPECT_FALSE(mir_pointer_input_event_get_button_state(pev, mir_pointer_input_button_forward));
736+}
737+
738+TEST(PointerInputEventProperties, axis_values_copied)
739+{
740+ float x = 7, y = 9.3, hscroll = 13, vscroll = 17;
741+ auto old_ev = a_motion_ev(AINPUT_SOURCE_MOUSE);
742+ old_ev.motion.pointer_count = 0;
743+ old_ev.motion.pointer_coordinates[0].x = x;
744+ old_ev.motion.pointer_coordinates[0].y = y;
745+ old_ev.motion.pointer_coordinates[0].vscroll = vscroll;
746+ old_ev.motion.pointer_coordinates[0].hscroll = hscroll;
747+
748+ auto pev = mir_input_event_get_pointer_input_event(mir_event_get_input_event(&old_ev));
749+ EXPECT_EQ(x, mir_pointer_input_event_get_axis_value(pev, mir_pointer_input_axis_x));
750+ EXPECT_EQ(y, mir_pointer_input_event_get_axis_value(pev, mir_pointer_input_axis_y));
751+ EXPECT_EQ(vscroll, mir_pointer_input_event_get_axis_value(pev, mir_pointer_input_axis_vscroll));
752+ EXPECT_EQ(hscroll, mir_pointer_input_event_get_axis_value(pev, mir_pointer_input_axis_hscroll));
753+}

Subscribers

People subscribed via source and target branches