Mir

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

Proposed by Robert Carr
Status: Merged
Approved by: Robert Carr
Approved revision: no longer in the source branch.
Merged at revision: 2129
Proposed branch: lp:~mir-team/mir/introduce-mir-event-2.0
Merge into: lp:mir
Diff against target: 1174 lines (+963/-22)
14 files modified
client-ABI-sha1sums (+4/-1)
common-ABI-sha1sums (+4/-1)
examples/fingerpaint.c (+23/-16)
include/common/mir_toolkit/event.h (+22/-1)
include/common/mir_toolkit/input/input_event.h (+101/-0)
include/common/mir_toolkit/input/key_input_event.h (+113/-0)
include/common/mir_toolkit/input/touch_input_event.h (+141/-0)
platform-ABI-sha1sums (+4/-1)
server-ABI-sha1sums (+4/-1)
src/common/input/CMakeLists.txt (+1/-0)
src/common/input/input_event.cpp (+330/-0)
src/common/symbols.map (+1/-1)
tests/unit-tests/input/CMakeLists.txt (+1/-0)
tests/unit-tests/input/test_input_event.cpp (+214/-0)
To merge this branch: bzr merge lp:~mir-team/mir/introduce-mir-event-2.0
Reviewer Review Type Date Requested Status
Chris Halse Rogers Approve
Alberto Aguirre (community) Needs Information
PS Jenkins bot (community) continuous-integration Approve
Alexandros Frantzis (community) Approve
Andreas Pokorny (community) Approve
Cemil Azizoglu (community) Approve
Review via email: mp+242443@code.launchpad.net

Commit message

Introduce a transition path to MirEvent 2.0, henceforth MirInputEvent.

Direct access to MirEvent::type is deprecated, and a new method mir_event_get_type is encouraged. For what was mir_event_type_key/motion a new type mir_event_type_input will be returned. Client code may call mir_event_get_input_event(...) to retreive a "MirInputEvent*" a.k.a. MirEvent 2.0.

Description of the change

Introduce an API/ABI preserving transition path to MirEvent 2.0, henceforth MirInputEvent.

Direct access to MirEvent::type is deprecated, and a new method mir_event_get_type is encouraged. For what was mir_event_type_key/motion a new type mir_event_type_input will be returned. Client code may call mir_event_get_input_event(...) to retreive a "MirInputEvent*" a.k.a. MirEvent 2.0.

The MirInputEvent API is of course incomplete, but I believe what is in this proposal has at least these two qualities:
1. Contains everything needed by current down streams.
2. Is ABI/API compatible with the 'final form' of MirInputEvent.

I'd like to transition as follows:
1. Iterate on names, documentation, etc, then land this branch.
2. Port downstream and internal MirEvent usage
3. Remove MirMotionEvent and MirKeyEvent

A quick guide to the branch contents:
include/common/mir_toolkit/input/* : New InputEvent API
tests/unit-tests/input/test_input_event.cpp : Test of translations from MirEvent to MirInputEvent, I would say the only surprising one involves the pointer action masking.
src/common/input/input_event.cpp: Impl of API
examples/fingerpaint.cpp: Port fingerpaint to new API
include/mir_toolkit/event.h: Add pointer action masks (ala https://bugs.launchpad.net/mir/+bug/1311699) to support the MirInputEvent translation.
src/common/symbols.map : Export the C symbols

Thanks!
Robert

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
Chris Halse Rogers (raof) wrote :

179 +MirInputEvent* mir_event_get_input_event(MirEvent* ev);

Const? Why is the MirEvent and MirInputEvent mutable?

---

229 +typedef struct _MirInputEvent MirInputEvent;
344 +typedef struct _MirKeyInputEvent MirKeyInputEvent;
460 +typedef struct _MirTouchInputEvent MirTouchInputEvent;

We've traditionally not used the typedef struct _Foo Foo idiom. Any particular reason to not make this “typedef struct Mir*InputEvent Mir*InputEvent”?

---

271 +MirInputEventTime mir_input_event_get_event_time(MirInputEvent const* ev);

Is there any particular reason to typedef int64_t to MirInputEventTime here? We're documenting it's nanoseconds-since-the-epoch, and this is not really useful if the type is opaque.

---

467 +typedef int64_t MirTouchInputEventTouchId;

We'll probably not have a full 2^63 touch ids at any point; int32_t maybe? :)

---

479 + /* This touch point was cancelled, an down should have been
480 + received but an up will never come. */
481 + mir_touch_input_event_action_cancel = 3,

Comment seems a bit off, and not just the an/down mismatch :)
Should mention that this is opt-in behaviour, “a down should have been received” is a bit wishy-washy.

“This touch point was cancelled. Any actions taken in response to this touch should be undone. No further events will be delivered for this touch point.

A cancelled event will only be sent to a client that has explicitly enabled cancellation, via mir_input_break_me_harder()”

Maybe?

---

482 + /* This touch point is unchanged but is reported as part of
483 + a full state update. */
484 + mir_touch_input_event_action_none = 4

Why do we have this? Is there an ability to request a full-state update?

---

518 +// Touch is made with a mouse through touch emulation
519 + mir_touch_input_tool_type_mouse = 3,

Are we going to do this?

---

549 +MirTouchInputEventTouchAction mir_touch_input_event_get_touch_action(MirTouchInputEvent const* event, size_t touch_index);

Hm. Would it be nice for clients if instead of get_touch_id(..., index) and get_*(..., index) we just had.
get_*(MirTouchInputEvent const* event, MirTouchInputEventTouchId id)?

That would seem be a more natural API to me, but we'd need toolkit input as to whether or not that's better.

---

655 + default:
656 + return MirInputEventType();

I'm a fan of abort() when faced with egregious client API abuse. Likewise for the DeviceId just afterwards.

---

761 +MirTouchInputEventTouchAction mir_touch_input_event_get_touch_action(MirTouchInputEvent const* event, size_t touch_index)

Oooh, ugh. Maybe we need an actual MirTouchInputEvent to pass in here, so that we can maintain the state that lets us implement this properly?

review: Needs Fixing
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
Alexandros Frantzis (afrantzis) wrote :

10 +da39a3ee5e6b4b0d3255bfef95601890afd80709 include/common/mir_toolkit/input/event.h~

A script gone awry?

130 +#define MIR_EVENT_ACTION_MASK 0xff
131 +#define MIR_EVENT_ACTION_POINTER_INDEX_MASK 0xff00
132 +#define MIR_EVENT_ACTION_POINTER_INDEX_SHIFT 8;

Given that we propose a new API that hides all the details, and these weren't previously expose, do we need to expose these now?

365 + * Retreive
... and other function docs

Typo "Retrieve"

677 + assert(mir_event_get_type(ev) == mir_event_type_input);

Since all users of our library would use the release builds, these asserts would just protect us from problematic tests and example code, which I don't think is a significant gain. We should decide (at an API-wide level) how to react in such cases: abort, ignore, return null/error object (and if so what to do when this null/error value is passed to other functions).

Needs fixing/information

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

165 +// and the mir_input_event* family of function.s
"functions."
-----------
other spelling errors : search for all instances of "Retreive", "assosciated", "occured"
-----------
233 + * \param [in] event The input event
"The event"
-----------
241 + * \param [in] event The event
"The input event"
-----------
Inconsistencies in terms of arg, or return type, e.g. sometimes we refer to a structure, as in "MirInputEvent", other times "the input event"
-----------
269 +MirKeyInputEvent const* mir_input_event_get_key_input_event(MirInputEvent const* ev);
Better if this was in include/common/mir_toolkit/input/key_input_event.h?
-----------
278 +MirTouchInputEvent const* mir_input_event_get_touch_input_event(MirInputEvent const* ev);
Better if this was in include/common/mir_toolkit/input/touch_input_event.h?
-----------
460 + /* This touch point was cancelled, an down should have been
"a down"
-----------
536 + * \param [in] touch_index The touch index. Must be less than touch_count.
"touch_count-1"
-----------
521 +MirTouchInputEventTouchId mir_touch_input_event_get_touch_id(MirTouchInputEvent const* event, size_t touch_index);
530 +MirTouchInputEventTouchAction mir_touch_input_event_get_touch_action(MirTouchInputEvent const* event, size_t touch_index);
Lines too long, wanna break like others?
-----------
570 +da39a3ee5e6b4b0d3255bfef95601890afd80709 include/common/mir_toolkit/input/event.h~
accidental commit (there are others)
-----------
130 +#define MIR_EVENT_ACTION_MASK 0xff
131 +#define MIR_EVENT_ACTION_POINTER_INDEX_MASK 0xff00
132 +#define MIR_EVENT_ACTION_POINTER_INDEX_SHIFT 8;

Better to move these to src/common/input/input_event.cpp, as they are only used there.
-----------
Too hungry to continue. :-)

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

Hi guys! Thanks. Will reply to reviews 1 by 1

>> 179 +MirInputEvent* mir_event_get_input_event(MirEvent* ev);
>>
>> Const? Why is the MirEvent and MirInputEvent mutable?

Fixed!

>> We've traditionally not used the typedef struct _Foo Foo idiom. Any particular reason to not make >> this “typedef struct Mir*InputEvent Mir*InputEvent”?

Old habit

>> Is there any particular reason to typedef int64_t to MirInputEventTime here? We're documenting
>> it's nanoseconds-since-the-epoch, and this is not really useful if the type is opaque.

I was kind of imagining mir_input_event_time_to_nsecs or something but there probably is no point...updated to use int64_t.

---

>> We'll probably not have a full 2^63 touch ids at any point; int32_t maybe? :)

Ubuntu: Linux for trillion fingered hindu gods.

...:p changed.

---

>> 479 + /* This touch point was cancelled, an down should have been
>> 480 + received but an up will never come. */
>> 481 + mir_touch_input_event_action_cancel = 3,
>> 482 + /* This touch point is unchanged but is reported as part of
>> 483 + a full state update. */
>> 484 + mir_touch_input_event_action_none = 4
>>
>> Why do we have this? Is there an ability to request a full-state update?
You are right cancel is wishy washy....I will remove it for now since there is no "mir_input_break_me_harder" to refer to. I've removed it for now since it can be added later. Likewise I've removed none for now as with the current impl change is always used. None was added because the API is always a full state update (mirroring the hardware frames).

>> 518 +// Touch is made with a mouse through touch emulation
>> 519 + mir_touch_input_tool_type_mouse = 3,
>>
>> Are we going to do this?

Probably not and we can add it later...removed.

---

>>655 + default:
>> 656 + return MirInputEventType();

>> I'm a fan of abort() when faced with egregious client API abuse. Likewise for the DeviceId just >> afterwards.

Not confident here we have a consensus so lets discuss on monday?

---

761 +MirTouchInputEventTouchAction mir_touch_input_event_get_touch_action(MirTouchInputEvent const* event, size_t touch_index)

>> Oooh, ugh. Maybe we need an actual MirTouchInputEvent to pass in here, so that we can maintain
>> the state that lets us implement this properly?

I think the proposed implementation is correct. From android input only one pointer can go up or down per event, and this lets us always determine the correct touch to assign the up/down action to and rest get the change action.

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

Alexandros:

>> A script gone awry?
Yes MP to fix the script incoming next.

>> 130 +#define MIR_EVENT_ACTION_MASK 0xff
>> 131 +#define MIR_EVENT_ACTION_POINTER_INDEX_MASK 0xff00
>> 132 +#define MIR_EVENT_ACTION_POINTER_INDEX_SHIFT 8;
>>
>> Given that we propose a new API that hides all the details, and these weren't previously expose, >> do we need to expose these now?

Good point I guess.

>> Typo "Retrieve"

Whoops.

>> 677 + assert(mir_event_get_type(ev) == mir_event_type_input);

Lets discuss a strategy on monday

Needs fixing/information

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
Daniel d'Andrada (dandrader) wrote :

I have shell rotation to get done ASAP, so I won't really have time to take a close look at it until then.

From my side, what I would like to ensure is that touch ids are kept unique for some time after they've ended (ie, you don't recycle IDs ASAP but keep incrementing the nextIdNumber until it loops over a certain high-enough upper bound). As long as you keep this, I'm happy. This is important for the touch point ownership and cancellation scheme I've in place in unity8.

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

Hey daniel. The old touch ids are being copied over 1-1 so we shouldn't have any problem there.

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

Did some self review and ended up with three changes:

1. Use abort in case of obvious programmer error, i.e. passing touch index > mir_touch_input_event_get_touch_count.
2. Remove mir_touch_input_tool_type_eraser, I think stylus/finger/unknown is the right level here and eraser is probably some sort of state on stylus events. If eraser, why not airbrush :p
3. A few comment tweaks.

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
Alexandros Frantzis (afrantzis) wrote :

Looks good overall. Some remaining nits/questions:

325 + mir_key_input_event_modifier_alt = 0x02,
326 + mir_key_input_event_modifier_alt_left = 0x10,
327 + mir_key_input_event_modifier_alt_right = 0x20,

The bit flags associated with the modifiers seem somewhat arbitrary (which may be OK since they are just flags). I wonder, though, if we could arrange them in a way that made more sense? Are we following some kind of external mapping?

Formatting nits:

124 +// Type for new style input event. Will be returned from mir_event_get_type for old style
125 +// key and motion events.

446 +/* Axis representing the x coordinate for the touch */
447 + mir_touch_input_axis_x = 0,

... and others

Comments are usually indented at the same level as the symbol they refers to.

633 + case mir_event_type_key:
634 + case mir_event_type_motion:
... and others

'case' should be indented at the same level as 'switch' (according to our guide).

Needs fixing + information for the modifier bit flags.

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

Fixed formatting nits.

Modifier flags are per android, compatibility is not required though...updated to use less question provoking values :)

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

Needs fixing :

216 +MirEventType mir_event_get_type(MirEvent const* ev);

This function is not input specific so it should be elsewhere (not in input_event.h). E.g. it 'd be odd to have to include input_event.h in your app if you were looking for, say, 'mir_event_type_prompt_session_state_change'.
_______________________

637 +MirEventType mir_event_get_type(MirEvent const* ev)

This one also looks out of place as it's not input specific, yet it's defined in input_event.cpp.
_______________________

Nits :

Do we want some masks for MirKeyInputEventModifiers. E.g. mir_key_input_event_modifier_alt_mask = mir_key_input_event_modifier_alt |mir_key_input_event_modifier_alt_left | mir_key_input_event_modifier_alt_right;

_______________________

old_modifiers_to_new could be made more efficient by using masks.

_________________________

883 + case mir_motion_tool_type_mouse:

Not sure why 'mouse' should return 'unknown'.

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

Thanks :D

>> This function is not input specific so it should be elsewhere (not in input_event.h). E.g. it >> be odd to have to include input_event.h in your app if you were looking for, say,
>> 'mir_event_type_prompt_session_state_change'.

Indeed. Fixed.

>> 637 +MirEventType mir_event_get_type(MirEvent const* ev)

>> This one also looks out of place as it's not input specific, yet it's defined in
>> input_event.cpp.

Yes but I dont think its worth creating event.cpp until there is other stuff in there.

Nits :

>> Do we want some masks for MirKeyInputEventModifiers.

I don't think so, as I mentioned in standup, I think in the future we will move to using opaque modifier masks from strings anyway.
_________________________

>> 883 + case mir_motion_tool_type_mouse:
>> Not sure why 'mouse' should return 'unknown'.

Because mir_motion_tool_type_mouse does not have an equivalent in the MirEvent 2.0 world. Or rather at least, mouse is not a touch tool, and will generate a separate pointer event category (not defined in this mp).This at least doesn't regress pointer support anywhere though (though already its quite flakey...)

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

No more to add. LGTM.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Robert Carr (robertcarr) wrote :

Weird failure retrying.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

Looks reasonable. +1 on sanitizing the touch tools..

review: Approve
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks good.

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

abort seems unfriendly, if there's an invalid argument. Other than that looks okay by me

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

Thanks for looking :) I think I've placed aborts only where the client can (and is required to have) detected incorrect use of the API...e.g.

mir_event_get_type != mir_event_type_input but passed to mir_event_get_input_event

I think in cases like this it's always an error in client code and the abort is helpful to developers.

Revision history for this message
Alberto Aguirre (albaguirre) wrote :

Why are all apis under common? Is the server going to use those APIs?

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

Definitely. QtMir will use it as opposed to direct access to MirEvent. Likewise other shells could consume it via mi::InputFilter etc. It's not infeasible USC would use it to implement some keybindings, etc.

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

LGTM now.

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 2014-11-27 03:48:20 +0000
3+++ client-ABI-sha1sums 2014-12-02 23:48:29 +0000
4@@ -11,6 +11,9 @@
5 1863a7fe3a382061f2752c0236cc971e7e68f93f include/common/mir_toolkit/client_types.h
6 2100c0674d9d882c1845550847357f6a5de5af66 include/common/mir_toolkit/common.h
7 fce4c1a9e0d037244f7e9e96ea2d8eaab4fc404c include/common/mir_toolkit/cursors.h
8-bccde9cdbc2f0d07e186c2950ef88d3a7d5f0d3b include/common/mir_toolkit/event.h
9+d71dddf6c4275ee423d3e0fa204e3b77b4d87401 include/common/mir_toolkit/event.h
10+49403c824f69fa1cc1f58bf5fe635639148765eb include/common/mir_toolkit/input/input_event.h
11+f531c6a49883884a6c694393d5614f9942fe2703 include/common/mir_toolkit/input/key_input_event.h
12+fd6d86becfa5ffa367480fd2654180f6ffcbf059 include/common/mir_toolkit/input/touch_input_event.h
13 4975998aa1056ed0d39dcc538127453e516ad8e9 include/common/mir_toolkit/mesa/native_display.h
14 101017c17714a57db57d79b7b5e7df40a3568236 include/common/mir_toolkit/mir_native_buffer.h
15
16=== modified file 'common-ABI-sha1sums'
17--- common-ABI-sha1sums 2014-11-27 03:48:20 +0000
18+++ common-ABI-sha1sums 2014-12-02 23:48:29 +0000
19@@ -17,6 +17,9 @@
20 1863a7fe3a382061f2752c0236cc971e7e68f93f include/common/mir_toolkit/client_types.h
21 2100c0674d9d882c1845550847357f6a5de5af66 include/common/mir_toolkit/common.h
22 fce4c1a9e0d037244f7e9e96ea2d8eaab4fc404c include/common/mir_toolkit/cursors.h
23-bccde9cdbc2f0d07e186c2950ef88d3a7d5f0d3b include/common/mir_toolkit/event.h
24+d71dddf6c4275ee423d3e0fa204e3b77b4d87401 include/common/mir_toolkit/event.h
25+49403c824f69fa1cc1f58bf5fe635639148765eb include/common/mir_toolkit/input/input_event.h
26+f531c6a49883884a6c694393d5614f9942fe2703 include/common/mir_toolkit/input/key_input_event.h
27+fd6d86becfa5ffa367480fd2654180f6ffcbf059 include/common/mir_toolkit/input/touch_input_event.h
28 4975998aa1056ed0d39dcc538127453e516ad8e9 include/common/mir_toolkit/mesa/native_display.h
29 101017c17714a57db57d79b7b5e7df40a3568236 include/common/mir_toolkit/mir_native_buffer.h
30
31=== modified file 'examples/fingerpaint.c'
32--- examples/fingerpaint.c 2014-11-24 02:16:00 +0000
33+++ examples/fingerpaint.c 2014-12-02 23:48:29 +0000
34@@ -17,6 +17,8 @@
35 */
36
37 #include "mir_toolkit/mir_client_library.h"
38+#include "mir_toolkit/input/input_event.h"
39+
40 #include <stdio.h>
41 #include <signal.h>
42 #include <stdint.h>
43@@ -200,41 +202,46 @@
44 {0x00, 0xff, 0x00, 0xff},
45 {0x00, 0x00, 0xff, 0xff},
46 };
47+
48+ MirEventType event_type = mir_event_get_type(event);
49
50- if (event->type == mir_event_type_motion)
51+ if (event_type == mir_event_type_input)
52 {
53 static size_t base_color = 0;
54 static size_t max_fingers = 0;
55 static float max_pressure = 1.0f;
56+
57+ MirInputEvent const* input_event = mir_event_get_input_event(event);
58+ if (mir_input_event_get_type(input_event) != mir_input_event_type_touch)
59+ return;
60+ MirTouchInputEvent const* tev = mir_input_event_get_touch_input_event(input_event);
61+ unsigned touch_count = mir_touch_input_event_get_touch_count(tev);
62
63- // FIXME: https://bugs.launchpad.net/mir/+bug/1311699
64- MirMotionAction masked_action = event->motion.action & ~0xff00;
65-
66- if (masked_action == mir_motion_action_up)
67+ if (touch_count == 1 && mir_touch_input_event_get_touch_action(tev, 0) == mir_touch_input_event_action_up)
68 {
69 base_color = (base_color + max_fingers) %
70 (sizeof(color)/sizeof(color[0]));
71 max_fingers = 0;
72 }
73-
74- if (masked_action == mir_motion_action_move ||
75- masked_action == mir_motion_action_down)
76+ else
77 {
78 size_t p;
79
80- if (event->motion.pointer_count > max_fingers)
81- max_fingers = event->motion.pointer_count;
82+ if (touch_count > max_fingers)
83+ max_fingers = touch_count;
84
85- for (p = 0; p < event->motion.pointer_count; p++)
86+ for (p = 0; p < touch_count; p++)
87 {
88- int x = event->motion.pointer_coordinates[p].x;
89- int y = event->motion.pointer_coordinates[p].y;
90- int radius = event->motion.pointer_coordinates[p].size * 50.0f
91+ int x = mir_touch_input_event_get_touch_axis_value(tev, p, mir_touch_input_axis_x);
92+ int y = mir_touch_input_event_get_touch_axis_value(tev, p, mir_touch_input_axis_y);
93+ float size = mir_touch_input_event_get_touch_axis_value(tev, p, mir_touch_input_axis_size);
94+ float pressure = mir_touch_input_event_get_touch_axis_value(tev, p, mir_touch_input_axis_pressure);
95+
96+ int radius = size * 50.0f
97 + 1.0f;
98 size_t c = (base_color + p) %
99 (sizeof(color)/sizeof(color[0]));
100 Color tone = color[c];
101- float pressure = event->motion.pointer_coordinates[p].pressure;
102
103 if (pressure > max_pressure)
104 max_pressure = pressure;
105@@ -247,7 +254,7 @@
106 redraw(surface, canvas);
107 }
108 }
109- else if (event->type == mir_event_type_resize)
110+ else if (event_type == mir_event_type_resize)
111 {
112 /* FIXME: https://bugs.launchpad.net/mir/+bug/1194384
113 * mir_event_type_resize will arrive in a different thread to that of
114
115=== modified file 'include/common/mir_toolkit/event.h'
116--- include/common/mir_toolkit/event.h 2014-11-27 03:48:20 +0000
117+++ include/common/mir_toolkit/event.h 2014-12-02 23:48:29 +0000
118@@ -43,7 +43,10 @@
119 mir_event_type_resize,
120 mir_event_type_prompt_session_state_change,
121 mir_event_type_orientation,
122- mir_event_type_close_surface
123+ mir_event_type_close_surface,
124+ /* Type for new style input event will be returned from mir_event_get_type
125+ when old style event type was mir_event_type_key or mir_event_type_motion */
126+ mir_event_type_input
127 } MirEventType;
128
129 typedef enum {
130@@ -121,6 +124,9 @@
131 mir_motion_tool_type_eraser = 4
132 } MirMotionToolType;
133
134+// DEPRECATED
135+// Direct access to MirKeyEvent is deprecated. Please use mir_event_get_input_event
136+// and the mir_input_event* family of functions.
137 typedef struct
138 {
139 MirEventType type;
140@@ -135,6 +141,7 @@
141 int32_t scan_code;
142 int32_t repeat_count;
143 nsecs_t down_time;
144+
145 nsecs_t event_time;
146 int is_system_key;
147 } MirKeyEvent;
148@@ -157,6 +164,9 @@
149 int unused3;
150 } MirMotionPointer;
151
152+// DEPRECATED
153+// Direct access to MirMotionEvent is deprecated. Please use mir_event_get_input_event
154+// and the mir_input_event* family of functions.
155 typedef struct
156 {
157 MirEventType type;
158@@ -234,6 +244,7 @@
159
160 typedef union
161 {
162+ // Direct access to the type member is deprecated. Instead use mir_event_get_type.
163 MirEventType type;
164 MirKeyEvent key;
165 MirMotionEvent motion;
166@@ -244,6 +255,16 @@
167 MirCloseSurfaceEvent close_surface;
168 } MirEvent;
169
170+/*
171+ * Retrieves the type of a MirEvent. Now preferred over direct access to ev->type.
172+ * In particular ev->type will never be mir_event_type_input and mir_event_get_type
173+ * is the only way to ensure mir_event_get_input_event will succeed.
174+ *
175+ * \param [in] event The event
176+ * \return The event type
177+ */
178+MirEventType mir_event_get_type(MirEvent const* ev);
179+
180 #ifdef __cplusplus
181 }
182 /**@}*/
183
184=== added directory 'include/common/mir_toolkit/input'
185=== added file 'include/common/mir_toolkit/input/input_event.h'
186--- include/common/mir_toolkit/input/input_event.h 1970-01-01 00:00:00 +0000
187+++ include/common/mir_toolkit/input/input_event.h 2014-12-02 23:48:29 +0000
188@@ -0,0 +1,101 @@
189+/*
190+ * Copyright © 2014 Canonical Ltd.
191+ *
192+ * This program is free software: you can redistribute it and/or modify it
193+ * under the terms of the GNU Lesser General Public License version 3,
194+ * as published by the Free Software Foundation.
195+ *
196+ * This program is distributed in the hope that it will be useful,
197+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
198+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
199+ * GNU Lesser General Public License for more details.
200+ *
201+ * You should have received a copy of the GNU Lesser General Public License
202+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
203+ *
204+ * Authored by: Robert Carr <robert.carr@canonical.com>
205+ */
206+
207+#ifndef MIR_TOOLKIT_INPUT_EVENT_H_
208+#define MIR_TOOLKIT_INPUT_EVENT_H_
209+
210+#include "mir_toolkit/event.h"
211+#include "mir_toolkit/input/key_input_event.h"
212+#include "mir_toolkit/input/touch_input_event.h"
213+
214+#include <stdint.h>
215+
216+#ifdef __cplusplus
217+/**
218+ * \addtogroup mir_toolkit
219+ * @{
220+ */
221+extern "C" {
222+#endif
223+
224+typedef struct MirInputEvent MirInputEvent;
225+
226+typedef int64_t MirInputDeviceId;
227+
228+typedef enum {
229+ mir_input_event_type_key = 0,
230+ mir_input_event_type_touch = 1
231+} MirInputEventType;
232+
233+/*
234+ * Retrieve the MirInputEvent associated with a MirEvent of
235+ * type mir_event_type_input.
236+ *
237+ * \param [in] event The event
238+ * \return The associated MirInputEvent
239+ */
240+MirInputEvent const* mir_event_get_input_event(MirEvent const* ev);
241+
242+/*
243+ * Retrieves the device id responsible for generating an input event.
244+ *
245+ * \param [in] event The input event
246+ * \return The id of the generating device
247+ */
248+MirInputDeviceId mir_input_event_get_device_id(MirInputEvent const* ev);
249+
250+/*
251+ * Retrieve the time at which an input event occured.
252+ *
253+ * \param [in] event The input event
254+ * \return A timestamp in nanoseconds-since-epoch
255+ */
256+int64_t mir_input_event_get_event_time(MirInputEvent const* ev);
257+
258+/*
259+ * Retrieve the type of an input event (e.g. key, touch...)
260+ *
261+ * \param [in] event The input event
262+ * \return The input event type
263+ */
264+MirInputEventType mir_input_event_get_type(MirInputEvent const* ev);
265+
266+/*
267+ * Retrieve the MirKeyInputEvent associated with a given input event.
268+ *
269+ * \param[in] event The input event
270+ * \return The MirKeyInputEvent or NULL if event type is not
271+ * mir_input_event_type_key
272+ */
273+MirKeyInputEvent const* mir_input_event_get_key_input_event(MirInputEvent const* ev);
274+
275+/*
276+ * Retrieve the MirTouchInputEvent associated with a given input event.
277+ *
278+ * \param[in] event The input event
279+ * \return The MirTouchInputEvent or NULL if event type is not
280+ * mir_input_event_type_touch
281+ */
282+MirTouchInputEvent const* mir_input_event_get_touch_input_event(MirInputEvent const* ev);
283+
284+#ifdef __cplusplus
285+}
286+/**@}*/
287+#endif
288+
289+#endif // MIR_TOOLKIT_INPUT_EVENT_H_
290
291=== added file 'include/common/mir_toolkit/input/key_input_event.h'
292--- include/common/mir_toolkit/input/key_input_event.h 1970-01-01 00:00:00 +0000
293+++ include/common/mir_toolkit/input/key_input_event.h 2014-12-02 23:48:29 +0000
294@@ -0,0 +1,113 @@
295+/*
296+ * Copyright © 2014 Canonical Ltd.
297+ *
298+ * This program is free software: you can redistribute it and/or modify it
299+ * under the terms of the GNU Lesser General Public License version 3,
300+ * as published by the Free Software Foundation.
301+ *
302+ * This program is distributed in the hope that it will be useful,
303+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
304+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
305+ * GNU Lesser General Public License for more details.
306+ *
307+ * You should have received a copy of the GNU Lesser General Public License
308+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
309+ *
310+ * Authored by: Robert Carr <robert.carr@canonical.com>
311+ */
312+
313+#ifndef MIR_TOOLKIT_KEY_INPUT_EVENT_H_
314+#define MIR_TOOLKIT_KEY_INPUT_EVENT_H_
315+
316+#include <xkbcommon/xkbcommon.h>
317+
318+#ifdef __cplusplus
319+/**
320+ * \addtogroup mir_toolkit
321+ * @{
322+ */
323+extern "C" {
324+#endif
325+
326+/**
327+ * An event type describing a change in keyboard state
328+ */
329+typedef struct MirKeyInputEvent MirKeyInputEvent;
330+
331+/**
332+ * Possible actions for changing key state
333+ */
334+typedef enum {
335+ /* A key has gone down */
336+ mir_key_input_event_action_up,
337+ /* A key has come up */
338+ mir_key_input_event_action_down,
339+ /* System policy has triggered a key repeat on a key
340+ which was already down */
341+ mir_key_input_event_action_repeat
342+} MirKeyInputEventAction;
343+
344+/**
345+ * Description of key modifier state.
346+ */
347+typedef enum {
348+ mir_key_input_event_modifier_none = 1 << 0,
349+ mir_key_input_event_modifier_alt = 1 << 1,
350+ mir_key_input_event_modifier_alt_left = 1 << 2,
351+ mir_key_input_event_modifier_alt_right = 1 << 3,
352+ mir_key_input_event_modifier_shift = 1 << 4,
353+ mir_key_input_event_modifier_shift_left = 1 << 5,
354+ mir_key_input_event_modifier_shift_right = 1 << 6,
355+ mir_key_input_event_modifier_sym = 1 << 7,
356+ mir_key_input_event_modifier_function = 1 << 8,
357+ mir_key_input_event_modifier_ctrl = 1 << 9,
358+ mir_key_input_event_modifier_ctrl_left = 1 << 10,
359+ mir_key_input_event_modifier_ctrl_right = 1 << 11,
360+ mir_key_input_event_modifier_meta = 1 << 12,
361+ mir_key_input_event_modifier_meta_left = 1 << 13,
362+ mir_key_input_event_modifier_meta_right = 1 << 14,
363+ mir_key_input_event_modifier_caps_lock = 1 << 15,
364+ mir_key_input_event_modifier_num_lock = 1 << 16,
365+ mir_key_input_event_modifier_scroll_lock = 1 << 17
366+} MirKeyInputEventModifiers;
367+
368+/**
369+ * Retrieve the action which triggered a given key event.
370+ *
371+ * \param [in] event The key event
372+ * \return The associated action
373+ */
374+MirKeyInputEventAction mir_key_input_event_get_action(MirKeyInputEvent const* event);
375+
376+/**
377+ * Retrieve the xkb mapped keycode associated with the key acted on.. May
378+ * be interpreted as per <xkbcommon/xkb-keysyms.h>
379+ *
380+ * \param [in] event The key event
381+ * \return The xkb_keysym
382+ */
383+xkb_keysym_t mir_key_input_event_get_key_code(MirKeyInputEvent const* event);
384+
385+/**
386+ * Retrieve the raw hardware scan code associated with the key acted on. May
387+ * be interpreted as per <linux/input.h>
388+ *
389+ * \param [in] event The key event
390+ * \return The scancode
391+ */
392+int mir_key_input_event_get_scan_code(MirKeyInputEvent const* event);
393+
394+/**
395+ * Retrieve the modifier keys pressed when the key action occured.
396+ *
397+ * \param [in] event The key event
398+ * \return The modifier mask
399+ */
400+MirKeyInputEventModifiers mir_key_input_event_get_modifiers(MirKeyInputEvent const* event);
401+
402+#ifdef __cplusplus
403+}
404+/**@}*/
405+#endif
406+
407+#endif /* MIR_TOOLKIT_KEY_INPUT_EVENT_H_ */
408
409=== added file 'include/common/mir_toolkit/input/touch_input_event.h'
410--- include/common/mir_toolkit/input/touch_input_event.h 1970-01-01 00:00:00 +0000
411+++ include/common/mir_toolkit/input/touch_input_event.h 2014-12-02 23:48:29 +0000
412@@ -0,0 +1,141 @@
413+/*
414+ * Copyright © 2014 Canonical Ltd.
415+ *
416+ * This program is free software: you can redistribute it and/or modify it
417+ * under the terms of the GNU Lesser General Public License version 3,
418+ * as published by the Free Software Foundation.
419+ *
420+ * This program is distributed in the hope that it will be useful,
421+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
422+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
423+ * GNU Lesser General Public License for more details.
424+ *
425+ * You should have received a copy of the GNU Lesser General Public License
426+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
427+ *
428+ * Authored by: Robert Carr <robert.carr@canonical.com>
429+ */
430+
431+#ifndef MIR_TOOLKIT_TOUCH_INPUT_EVENT_H_
432+#define MIR_TOOLKIT_TOUCH_INPUT_EVENT_H_
433+
434+#ifdef __cplusplus
435+/**
436+ * \addtogroup mir_toolkit
437+ * @{
438+ */
439+extern "C" {
440+#endif
441+
442+/**
443+ * An event type describing a change in touch device state.
444+ */
445+typedef struct MirTouchInputEvent MirTouchInputEvent;
446+
447+/**
448+ * An identifier for a touch-point. TouchId's are unique per-gesture.
449+ * That is to say, once a touch has gone down at time T, no other touch will
450+ * use that touch's ID until all touches at time T have come up.
451+ */
452+typedef int32_t MirTouchInputEventTouchId;
453+
454+/**
455+ * Possible per touch actions for state changing
456+ */
457+typedef enum {
458+ /* This touch point is going up */
459+ mir_touch_input_event_action_up = 0,
460+ /* This touch point is going down */
461+ mir_touch_input_event_action_down = 1,
462+ /* Axis values have changed on this touch point */
463+ mir_touch_input_event_action_change = 2
464+} MirTouchInputEventTouchAction;
465+
466+/**
467+ * Identifiers for touch axis
468+ */
469+typedef enum {
470+/* Axis representing the x coordinate for the touch */
471+ mir_touch_input_axis_x = 0,
472+/* Axis representing the y coordinate for the touch */
473+ mir_touch_input_axis_y = 1,
474+/* Axis representing pressure of the touch */
475+ mir_touch_input_axis_pressure = 2,
476+/* Axis representing the length of the major axis of an ellipse
477+ centered at the touch point */
478+ mir_touch_input_axis_touch_major = 3,
479+/* Axis representing the length of the minor axis of an ellipse
480+ centered at the touch point */
481+ mir_touch_input_axis_touch_minor = 4,
482+/* Axis representing the diameter of a circle centered on the touch
483+ point */
484+ mir_touch_input_axis_size = 5
485+} MirTouchInputEventTouchAxis;
486+
487+/**
488+ * Identifiers for per-touch tool types
489+ */
490+typedef enum {
491+// Tool type could not be determined
492+ mir_touch_input_tool_type_unknown = 0,
493+// Touch is made with a finger
494+ mir_touch_input_tool_type_finger = 1,
495+// Touch is made with a stylus
496+ mir_touch_input_tool_type_stylus = 2
497+} MirTouchInputEventTouchTooltype;
498+
499+/**
500+ * Retrieve the number of touches reported for a given touch event. Each touch
501+ * is said to be index in the event and may be accessed by index 0, 1, ... , (touch_count - 1)
502+ *
503+ * \param [in] event The touch event
504+ * \return The number of touches
505+ */
506+unsigned int mir_touch_input_event_get_touch_count(MirTouchInputEvent const* event);
507+
508+/**
509+ * Retrieve the TouchID for a touch at given index.
510+ *
511+ * \param [in] event The touch event
512+ * \param [in] touch_index The touch index. Must be less than (touch_count - 1).
513+ * \return ID of the touch at index
514+ */
515+MirTouchInputEventTouchId mir_touch_input_event_get_touch_id(MirTouchInputEvent const* event, size_t touch_index);
516+
517+/**
518+ * Retrieve the action which occured for a touch at given index.
519+ *
520+ * \param [in] event The touch event
521+ * \param [in] touch_index The touch index. Must be less than (touch_count - 1).
522+ * \return Action performed for the touch at index.
523+ */
524+MirTouchInputEventTouchAction mir_touch_input_event_get_touch_action(MirTouchInputEvent const* event, size_t touch_index);
525+
526+/**
527+ * Retrieve the tooltype for touch at given index.
528+ *
529+ * \param [in] event The touch event
530+ * \param [in] touch_index The touch index. Must be less than (touch_count - 1).
531+ * \return Tooltype used for the touch at index
532+ */
533+MirTouchInputEventTouchTooltype mir_touch_input_event_get_touch_tooltype(MirTouchInputEvent const* event,
534+ size_t touch_index);
535+
536+
537+/**
538+ * Retrieve the axis value for a given axis on an indexed touch.
539+ *
540+ * \param [in] event The touch event
541+ * \param [in] touch_index The touch index. Must be less than (touch_count - 1).
542+ * \param [in] axis The axis to retreive a value from
543+ * \return The value of the given axis
544+ */
545+float mir_touch_input_event_get_touch_axis_value(MirTouchInputEvent const* event,
546+ size_t touch_index, MirTouchInputEventTouchAxis axis);
547+
548+#ifdef __cplusplus
549+}
550+/**@}*/
551+#endif
552+
553+#endif /* MIR_TOOLKIT_TOUCH_INPUT_EVENT_H_ */
554
555=== modified file 'platform-ABI-sha1sums'
556--- platform-ABI-sha1sums 2014-11-27 03:48:20 +0000
557+++ platform-ABI-sha1sums 2014-12-02 23:48:29 +0000
558@@ -17,7 +17,10 @@
559 1863a7fe3a382061f2752c0236cc971e7e68f93f include/common/mir_toolkit/client_types.h
560 2100c0674d9d882c1845550847357f6a5de5af66 include/common/mir_toolkit/common.h
561 fce4c1a9e0d037244f7e9e96ea2d8eaab4fc404c include/common/mir_toolkit/cursors.h
562-bccde9cdbc2f0d07e186c2950ef88d3a7d5f0d3b include/common/mir_toolkit/event.h
563+d71dddf6c4275ee423d3e0fa204e3b77b4d87401 include/common/mir_toolkit/event.h
564+49403c824f69fa1cc1f58bf5fe635639148765eb include/common/mir_toolkit/input/input_event.h
565+f531c6a49883884a6c694393d5614f9942fe2703 include/common/mir_toolkit/input/key_input_event.h
566+fd6d86becfa5ffa367480fd2654180f6ffcbf059 include/common/mir_toolkit/input/touch_input_event.h
567 4975998aa1056ed0d39dcc538127453e516ad8e9 include/common/mir_toolkit/mesa/native_display.h
568 101017c17714a57db57d79b7b5e7df40a3568236 include/common/mir_toolkit/mir_native_buffer.h
569 871e609c0fed0d566ddbaaa8ac2d7cd5c06dd09a include/platform/mir/abnormal_exit.h
570
571=== modified file 'server-ABI-sha1sums'
572--- server-ABI-sha1sums 2014-11-27 03:48:20 +0000
573+++ server-ABI-sha1sums 2014-12-02 23:48:29 +0000
574@@ -17,7 +17,10 @@
575 1863a7fe3a382061f2752c0236cc971e7e68f93f include/common/mir_toolkit/client_types.h
576 2100c0674d9d882c1845550847357f6a5de5af66 include/common/mir_toolkit/common.h
577 fce4c1a9e0d037244f7e9e96ea2d8eaab4fc404c include/common/mir_toolkit/cursors.h
578-bccde9cdbc2f0d07e186c2950ef88d3a7d5f0d3b include/common/mir_toolkit/event.h
579+d71dddf6c4275ee423d3e0fa204e3b77b4d87401 include/common/mir_toolkit/event.h
580+49403c824f69fa1cc1f58bf5fe635639148765eb include/common/mir_toolkit/input/input_event.h
581+f531c6a49883884a6c694393d5614f9942fe2703 include/common/mir_toolkit/input/key_input_event.h
582+fd6d86becfa5ffa367480fd2654180f6ffcbf059 include/common/mir_toolkit/input/touch_input_event.h
583 4975998aa1056ed0d39dcc538127453e516ad8e9 include/common/mir_toolkit/mesa/native_display.h
584 101017c17714a57db57d79b7b5e7df40a3568236 include/common/mir_toolkit/mir_native_buffer.h
585 871e609c0fed0d566ddbaaa8ac2d7cd5c06dd09a include/platform/mir/abnormal_exit.h
586
587=== modified file 'src/common/input/CMakeLists.txt'
588--- src/common/input/CMakeLists.txt 2014-11-24 02:16:00 +0000
589+++ src/common/input/CMakeLists.txt 2014-12-02 23:48:29 +0000
590@@ -27,6 +27,7 @@
591 add_library(mirsharedinput OBJECT
592 ${ANDROID_SHARED_INPUT_SOURCES}
593 udev_wrapper.cpp
594+ input_event.cpp
595 )
596
597 list(APPEND MIR_COMMON_SOURCES
598
599=== added file 'src/common/input/input_event.cpp'
600--- src/common/input/input_event.cpp 1970-01-01 00:00:00 +0000
601+++ src/common/input/input_event.cpp 2014-12-02 23:48:29 +0000
602@@ -0,0 +1,330 @@
603+/*
604+ * Copyright © 2014 Canonical Ltd.
605+ *
606+ * This program is free software: you can redistribute it and/or modify it
607+ * under the terms of the GNU Lesser General Public License version 3,
608+ * as published by the Free Software Foundation.
609+ *
610+ * This program is distributed in the hope that it will be useful,
611+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
612+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
613+ * GNU Lesser General Public License for more details.
614+ *
615+ * You should have received a copy of the GNU Lesser General Public License
616+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
617+ *
618+ * Authored by: Robert Carr <robert.carr@canonical.com>
619+ */
620+
621+#include "mir_toolkit/input/input_event.h"
622+
623+#include <assert.h>
624+#include <stdlib.h>
625+
626+// See: https://bugs.launchpad.net/mir/+bug/1311699
627+#define MIR_EVENT_ACTION_MASK 0xff
628+#define MIR_EVENT_ACTION_POINTER_INDEX_MASK 0xff00
629+#define MIR_EVENT_ACTION_POINTER_INDEX_SHIFT 8;
630+
631+namespace
632+{
633+MirEvent const* old_ev_from_new(MirInputEvent const* ev)
634+{
635+ return reinterpret_cast<MirEvent const*>(ev);
636+}
637+MirKeyEvent const& old_kev_from_new(MirKeyInputEvent const* ev)
638+{
639+ auto old_ev = reinterpret_cast<MirEvent const*>(ev);
640+ if (old_ev->type != mir_event_type_key)
641+ abort();
642+ return old_ev->key;
643+}
644+MirMotionEvent const& old_mev_from_new(MirTouchInputEvent const* ev)
645+{
646+ auto old_ev = reinterpret_cast<MirEvent const*>(ev);
647+ if (old_ev->type != mir_event_type_motion)
648+ abort();
649+ return old_ev->motion;
650+}
651+}
652+
653+MirEventType mir_event_get_type(MirEvent const* ev)
654+{
655+ switch (ev->type)
656+ {
657+ case mir_event_type_key:
658+ case mir_event_type_motion:
659+ return mir_event_type_input;
660+ default:
661+ return ev->type;
662+ }
663+}
664+
665+MirInputEvent const* mir_event_get_input_event(MirEvent const* ev)
666+{
667+ if(mir_event_get_type(ev) != mir_event_type_input)
668+ abort();
669+
670+ return reinterpret_cast<MirInputEvent const*>(ev);
671+}
672+
673+MirInputEventType mir_input_event_get_type(MirInputEvent const* ev)
674+{
675+ auto old_ev = old_ev_from_new(ev);
676+ assert(old_ev->type == mir_event_type_key || old_ev->type == mir_event_type_motion);
677+
678+ switch (old_ev->type)
679+ {
680+ case mir_event_type_key:
681+ return mir_input_event_type_key;
682+ case mir_event_type_motion:
683+ return mir_input_event_type_touch;
684+ default:
685+ abort();
686+ }
687+}
688+
689+MirInputDeviceId mir_input_event_get_device_id(MirInputEvent const* ev)
690+{
691+ auto old_ev = old_ev_from_new(ev);
692+ assert(mir_event_get_type(old_ev) == mir_event_type_input);
693+
694+ switch (old_ev->type)
695+ {
696+ case mir_event_type_motion:
697+ return old_ev->motion.device_id;
698+ case mir_event_type_key:
699+ return old_ev->key.device_id;
700+ default:
701+ abort();
702+ }
703+}
704+
705+int64_t mir_input_event_get_event_time(MirInputEvent const* ev)
706+{
707+ auto old_ev = old_ev_from_new(ev);
708+ assert(mir_event_get_type(old_ev) == mir_event_type_input);
709+
710+ switch (old_ev->type)
711+ {
712+ case mir_event_type_motion:
713+ return old_ev->motion.event_time;
714+ case mir_event_type_key:
715+ return old_ev->key.event_time;
716+ default:
717+ abort();
718+ }
719+}
720+
721+/* Key event accessors */
722+
723+MirKeyInputEvent const* mir_input_event_get_key_input_event(MirInputEvent const* ev)
724+{
725+ if (mir_input_event_get_type(ev) != mir_input_event_type_key)
726+ abort();
727+
728+ return reinterpret_cast<MirKeyInputEvent const*>(ev);
729+}
730+
731+MirKeyInputEventAction mir_key_input_event_get_action(MirKeyInputEvent const* kev)
732+{
733+ auto const& old_kev = old_kev_from_new(kev);
734+
735+ switch (old_kev.action)
736+ {
737+ case mir_key_action_down:
738+ if (old_kev.repeat_count != 0)
739+ return mir_key_input_event_action_repeat;
740+ else
741+ return mir_key_input_event_action_down;
742+ case mir_key_action_up:
743+ return mir_key_input_event_action_up;
744+ default:
745+ // TODO:? This means we got key_action_multiple which I dont think is
746+ // actually emitted yet (and never will be as in the future it would fall under text
747+ // event in the new model).
748+ return mir_key_input_event_action_down;
749+ }
750+}
751+
752+xkb_keysym_t mir_key_input_event_get_key_code(MirKeyInputEvent const* kev)
753+{
754+ auto const& old_kev = old_kev_from_new(kev);
755+ return old_kev.key_code;
756+}
757+
758+int mir_key_input_event_get_scan_code(MirKeyInputEvent const* kev)
759+{
760+ auto const& old_kev = old_kev_from_new(kev);
761+ return old_kev.scan_code;
762+}
763+
764+namespace
765+{
766+MirKeyInputEventModifiers old_modifiers_to_new(MirKeyModifier old_modifier)
767+{
768+ unsigned modifier = 0;
769+
770+ if (old_modifier & mir_key_modifier_none)
771+ modifier |= mir_key_input_event_modifier_none;
772+ if (old_modifier & mir_key_modifier_alt)
773+ modifier |= mir_key_input_event_modifier_alt;
774+ if (old_modifier & mir_key_modifier_alt_left)
775+ modifier |= mir_key_input_event_modifier_alt_left;
776+ if (old_modifier & mir_key_modifier_alt_right)
777+ modifier |= mir_key_input_event_modifier_alt_right;
778+ if (old_modifier & mir_key_modifier_shift)
779+ modifier |= mir_key_input_event_modifier_shift;
780+ if (old_modifier & mir_key_modifier_shift_left)
781+ modifier |= mir_key_input_event_modifier_shift_left;
782+ if (old_modifier & mir_key_modifier_shift_right)
783+ modifier |= mir_key_input_event_modifier_shift_right;
784+ if (old_modifier & mir_key_modifier_sym)
785+ modifier |= mir_key_input_event_modifier_sym;
786+ if (old_modifier & mir_key_modifier_function)
787+ modifier |= mir_key_input_event_modifier_function;
788+ if (old_modifier & mir_key_modifier_ctrl)
789+ modifier |= mir_key_input_event_modifier_ctrl;
790+ if (old_modifier & mir_key_modifier_ctrl_left)
791+ modifier |= mir_key_input_event_modifier_ctrl_left;
792+ if (old_modifier & mir_key_modifier_ctrl_right)
793+ modifier |= mir_key_input_event_modifier_ctrl_right;
794+ if (old_modifier & mir_key_modifier_meta)
795+ modifier |= mir_key_input_event_modifier_meta;
796+ if (old_modifier & mir_key_modifier_meta_left)
797+ modifier |= mir_key_input_event_modifier_meta_left;
798+ if (old_modifier & mir_key_modifier_meta_right)
799+ modifier |= mir_key_input_event_modifier_meta_right;
800+ if (old_modifier & mir_key_modifier_caps_lock)
801+ modifier |= mir_key_input_event_modifier_caps_lock;
802+ if (old_modifier & mir_key_modifier_num_lock)
803+ modifier |= mir_key_input_event_modifier_num_lock;
804+ if (old_modifier & mir_key_modifier_scroll_lock)
805+ modifier |= mir_key_input_event_modifier_scroll_lock;
806+ return static_cast<MirKeyInputEventModifiers>(modifier);
807+}
808+}
809+MirKeyInputEventModifiers mir_key_input_event_get_modifiers(MirKeyInputEvent const* kev)
810+{ auto const& old_kev = old_kev_from_new(kev);
811+ return old_modifiers_to_new(static_cast<MirKeyModifier>(old_kev.modifiers));
812+}
813+/* Touch event accessors */
814+
815+MirTouchInputEvent const* mir_input_event_get_touch_input_event(MirInputEvent const* ev)
816+{
817+ if(mir_input_event_get_type(ev) != mir_input_event_type_touch)
818+ abort();
819+
820+ return reinterpret_cast<MirTouchInputEvent const*>(ev);
821+}
822+
823+unsigned int mir_touch_input_event_get_touch_count(MirTouchInputEvent const* event)
824+{
825+ auto const& old_mev = reinterpret_cast<MirEvent const*>(event)->motion;
826+ return old_mev.pointer_count;
827+}
828+
829+MirTouchInputEventTouchId mir_touch_input_event_get_touch_id(MirTouchInputEvent const* event, size_t touch_index)
830+{
831+ auto const& old_mev = old_mev_from_new(event);
832+
833+ if (touch_index >= old_mev.pointer_count)
834+ abort();
835+
836+ return old_mev.pointer_coordinates[touch_index].id;
837+}
838+
839+MirTouchInputEventTouchAction mir_touch_input_event_get_touch_action(MirTouchInputEvent const* event, size_t touch_index)
840+{
841+ auto const& old_mev = old_mev_from_new(event);
842+
843+ if(touch_index > old_mev.pointer_count)
844+ abort();
845+
846+ auto masked_action = old_mev.action & MIR_EVENT_ACTION_MASK;
847+ size_t masked_index = (old_mev.action & MIR_EVENT_ACTION_POINTER_INDEX_MASK) >> MIR_EVENT_ACTION_POINTER_INDEX_SHIFT;
848+
849+ switch (masked_action)
850+ {
851+ // For the next two cases we could assert pc=1...because a gesture must
852+ // be starting or ending.
853+ case mir_motion_action_down:
854+ return mir_touch_input_event_action_down;
855+ case mir_motion_action_up:
856+ return mir_touch_input_event_action_up;
857+ // We can't tell which touches have actually moved without tracking state
858+ // so we report all touchpoints as changed.
859+ case mir_motion_action_move:
860+ case mir_motion_action_hover_move:
861+ return mir_touch_input_event_action_change;
862+ // All touch points are handled at once so we don't know the index
863+ case mir_motion_action_pointer_down:
864+ if (touch_index == masked_index)
865+ return mir_touch_input_event_action_down;
866+ else
867+ return mir_touch_input_event_action_change;
868+ case mir_motion_action_pointer_up:
869+ if (touch_index == masked_index)
870+ return mir_touch_input_event_action_up;
871+ else
872+ return mir_touch_input_event_action_change;
873+ // TODO: How to deal with these?
874+ case mir_motion_action_cancel:
875+ case mir_motion_action_outside:
876+ case mir_motion_action_scroll:
877+ case mir_motion_action_hover_enter:
878+ case mir_motion_action_hover_exit:
879+ default:
880+ return mir_touch_input_event_action_change;
881+ }
882+}
883+
884+MirTouchInputEventTouchTooltype mir_touch_input_event_get_touch_tooltype(MirTouchInputEvent const* event,
885+ size_t touch_index)
886+{
887+ auto const& old_mev = old_mev_from_new(event);
888+
889+ if(touch_index > old_mev.pointer_count)
890+ abort();
891+
892+ switch (old_mev.pointer_coordinates[touch_index].tool_type)
893+ {
894+ case mir_motion_tool_type_finger:
895+ return mir_touch_input_tool_type_finger;
896+ case mir_motion_tool_type_stylus:
897+ case mir_motion_tool_type_eraser:
898+ return mir_touch_input_tool_type_stylus;
899+ case mir_motion_tool_type_mouse:
900+ case mir_motion_tool_type_unknown:
901+ default:
902+ return mir_touch_input_tool_type_unknown;
903+ }
904+}
905+
906+float mir_touch_input_event_get_touch_axis_value(MirTouchInputEvent const* event,
907+ size_t touch_index, MirTouchInputEventTouchAxis axis)
908+{
909+ auto const& old_mev = old_mev_from_new(event);
910+
911+ if(touch_index > old_mev.pointer_count)
912+ abort();
913+
914+ auto const& old_pc = old_mev.pointer_coordinates[touch_index];
915+ switch (axis)
916+ {
917+ case mir_touch_input_axis_x:
918+ return old_pc.x;
919+ case mir_touch_input_axis_y:
920+ return old_pc.y;
921+ case mir_touch_input_axis_pressure:
922+ return old_pc.pressure;
923+ case mir_touch_input_axis_touch_major:
924+ return old_pc.touch_major;
925+ case mir_touch_input_axis_touch_minor:
926+ return old_pc.touch_minor;
927+ case mir_touch_input_axis_size:
928+ return old_pc.size;
929+ default:
930+ return -1;
931+ }
932+}
933
934=== modified file 'src/common/symbols.map'
935--- src/common/symbols.map 2014-11-24 02:16:00 +0000
936+++ src/common/symbols.map 2014-12-02 23:48:29 +0000
937@@ -1,5 +1,5 @@
938 MIR_COMMON_3 {
939- global:
940+ global: mir_*;
941 extern "C++" {
942 # The following symbols come from running a script over the generated docs. Vis:
943 # ../tools/process_doxygen_xml.py doc/xml/*.xml | grep "^mircommon public" | sed "s/mircommon public: / /" | sort
944
945=== modified file 'tests/unit-tests/input/CMakeLists.txt'
946--- tests/unit-tests/input/CMakeLists.txt 2014-11-24 02:16:00 +0000
947+++ tests/unit-tests/input/CMakeLists.txt 2014-12-02 23:48:29 +0000
948@@ -6,6 +6,7 @@
949 ${CMAKE_CURRENT_SOURCE_DIR}/test_cursor_controller.cpp
950 ${CMAKE_CURRENT_SOURCE_DIR}/test_xcursor_loader.cpp
951 ${CMAKE_CURRENT_SOURCE_DIR}/test_touchspot_controller.cpp
952+ ${CMAKE_CURRENT_SOURCE_DIR}/test_input_event.cpp
953 )
954
955 set(
956
957=== added file 'tests/unit-tests/input/test_input_event.cpp'
958--- tests/unit-tests/input/test_input_event.cpp 1970-01-01 00:00:00 +0000
959+++ tests/unit-tests/input/test_input_event.cpp 2014-12-02 23:48:29 +0000
960@@ -0,0 +1,214 @@
961+/*
962+ * Copyright © 2014 Canonical Ltd.
963+ *
964+ * This program is free software: you can redistribute it and/or modify
965+ * it under the terms of the GNU General Public License version 3 as
966+ * published by the Free Software Foundation.
967+ *
968+ * This program is distributed in the hope that it will be useful,
969+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
970+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
971+ * GNU General Public License for more details.
972+ *
973+ * You should have received a copy of the GNU General Public License
974+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
975+ *
976+ * Authored by: Robert Carr <robert.carr@canonical.com>
977+ */
978+
979+#include <gtest/gtest.h>
980+
981+#include "mir_toolkit/event.h"
982+#include "mir_toolkit/input/input_event.h"
983+
984+// See: https://bugs.launchpad.net/mir/+bug/1311699
985+#define MIR_EVENT_ACTION_POINTER_INDEX_MASK 0xff00
986+#define MIR_EVENT_ACTION_POINTER_INDEX_SHIFT 8;
987+
988+TEST(InputEvent, old_style_key_and_motion_events_are_input_events)
989+{
990+ MirEvent key_ev;
991+ key_ev.type = mir_event_type_key;
992+
993+ EXPECT_EQ(mir_event_type_input, mir_event_get_type(&key_ev));
994+ EXPECT_EQ(mir_input_event_type_key, mir_input_event_get_type(mir_event_get_input_event(&key_ev)));
995+
996+ MirEvent motion_ev;
997+ motion_ev.type = mir_event_type_motion;
998+
999+ EXPECT_EQ(mir_event_type_input, mir_event_get_type(&motion_ev));
1000+ EXPECT_NE(nullptr, mir_event_get_input_event(&motion_ev));
1001+}
1002+
1003+// MirInputEvent properties common to all events.
1004+
1005+TEST(CommonInputEventProperties, device_id_taken_from_old_style_event)
1006+{
1007+ int64_t dev_id_1 = 17, dev_id_2 = 23;
1008+ MirEvent old_ev;
1009+
1010+ old_ev.type = mir_event_type_motion;
1011+ old_ev.motion.device_id = dev_id_1;
1012+ EXPECT_EQ(dev_id_1, mir_input_event_get_device_id(
1013+ mir_event_get_input_event(&old_ev)));
1014+
1015+ old_ev.type = mir_event_type_key;
1016+ old_ev.motion.device_id = dev_id_2;
1017+ EXPECT_EQ(dev_id_2, mir_input_event_get_device_id(
1018+ mir_event_get_input_event(&old_ev)));
1019+}
1020+
1021+TEST(CommonInputEventProperties, event_time_taken_from_old_style_event)
1022+{
1023+ int64_t event_time_1 = 79, event_time_2 = 83;
1024+ MirEvent old_ev;
1025+
1026+ old_ev.type = mir_event_type_motion;
1027+ old_ev.motion.event_time = event_time_1;
1028+ EXPECT_EQ(event_time_1, mir_input_event_get_event_time(
1029+ mir_event_get_input_event(&old_ev)));
1030+
1031+ old_ev.type = mir_event_type_key;
1032+ old_ev.key.event_time = event_time_2;
1033+ EXPECT_EQ(event_time_2, mir_input_event_get_event_time(
1034+ mir_event_get_input_event(&old_ev)));
1035+}
1036+
1037+TEST(KeyInputEventProperties, up_and_down_actions_copied_from_old_style_event)
1038+{
1039+ MirEvent old_ev;
1040+ old_ev.type = mir_event_type_key;
1041+
1042+ old_ev.key.action = mir_key_action_down;
1043+ old_ev.key.repeat_count = 0;
1044+
1045+ auto new_kev = mir_input_event_get_key_input_event(mir_event_get_input_event(&old_ev));
1046+ EXPECT_EQ(mir_key_input_event_action_down, mir_key_input_event_get_action(new_kev));
1047+
1048+ old_ev.key.action = mir_key_action_up;
1049+ EXPECT_EQ(mir_key_input_event_action_up, mir_key_input_event_get_action(new_kev));
1050+}
1051+
1052+TEST(KeyInputEventProperties, repeat_action_produced_from_non_zero_repeat_count_in_old_style_event)
1053+{
1054+ MirEvent old_ev;
1055+ old_ev.type = mir_event_type_key;
1056+ old_ev.key.action = mir_key_action_down;
1057+ old_ev.key.repeat_count = 1;
1058+
1059+ auto new_kev = mir_input_event_get_key_input_event(mir_event_get_input_event(&old_ev));
1060+ EXPECT_EQ(mir_key_input_event_action_repeat, mir_key_input_event_get_action(new_kev));
1061+}
1062+
1063+TEST(KeyInputEventProperties, keycode_scancode_and_modifiers_taken_from_old_style_event)
1064+{
1065+ xkb_keysym_t key_code = 171;
1066+ int scan_code = 31;
1067+ MirKeyModifier old_modifiers = mir_key_modifier_shift;
1068+
1069+ MirEvent old_ev;
1070+ old_ev.type = mir_event_type_key;
1071+ old_ev.key.key_code = key_code;
1072+ old_ev.key.scan_code = scan_code;
1073+ old_ev.key.modifiers = old_modifiers;
1074+
1075+ auto new_kev = mir_input_event_get_key_input_event(mir_event_get_input_event(&old_ev));
1076+ EXPECT_EQ(key_code, mir_key_input_event_get_key_code(new_kev));
1077+ EXPECT_EQ(scan_code, mir_key_input_event_get_scan_code(new_kev));
1078+ EXPECT_EQ(mir_key_input_event_modifier_shift, mir_key_input_event_get_modifiers(new_kev));
1079+}
1080+
1081+TEST(TouchInputEventProperties, touch_count_taken_from_pointer_count)
1082+{
1083+ unsigned const pointer_count = 3;
1084+
1085+ MirEvent old_ev;
1086+ old_ev.type = mir_event_type_motion;
1087+ old_ev.motion.action = mir_motion_action_down;
1088+ old_ev.motion.pointer_count = pointer_count;
1089+
1090+ auto tev = mir_input_event_get_touch_input_event(mir_event_get_input_event(&old_ev));
1091+ EXPECT_EQ(pointer_count, mir_touch_input_event_get_touch_count(tev));
1092+}
1093+
1094+TEST(TouchInputEventProperties, touch_id_comes_from_pointer_coordinates)
1095+{
1096+ unsigned const touch_id = 31;
1097+ MirEvent old_ev;
1098+ old_ev.type = mir_event_type_motion;
1099+ old_ev.motion.action = mir_motion_action_down;
1100+ old_ev.motion.pointer_count = 1;
1101+ old_ev.motion.pointer_coordinates[0].id = touch_id;
1102+
1103+ auto tev = mir_input_event_get_touch_input_event(mir_event_get_input_event(&old_ev));
1104+ EXPECT_EQ(touch_id, mir_touch_input_event_get_touch_id(tev, 0));
1105+}
1106+
1107+// mir_motion_action_up/down represent the start of a gesture. pointers only go up/down one at a time
1108+TEST(TouchInputEventProperties, down_and_up_actions_are_taken_from_old_event)
1109+{
1110+ MirEvent old_ev;
1111+ old_ev.type = mir_event_type_motion;
1112+ old_ev.motion.action = mir_motion_action_down;
1113+ old_ev.motion.pointer_count = 1;
1114+
1115+ auto tev = mir_input_event_get_touch_input_event(mir_event_get_input_event(&old_ev));
1116+ EXPECT_EQ(mir_touch_input_event_action_down, mir_touch_input_event_get_touch_action(tev, 0));
1117+}
1118+
1119+TEST(TouchInputEventProperties, pointer_up_down_applies_only_to_masked_action)
1120+{
1121+ int const masked_pointer_index = 1;
1122+
1123+ MirEvent old_ev;
1124+ old_ev.type = mir_event_type_motion;
1125+ old_ev.motion.action = masked_pointer_index << MIR_EVENT_ACTION_POINTER_INDEX_SHIFT;
1126+ old_ev.motion.action = (old_ev.motion.action & MIR_EVENT_ACTION_POINTER_INDEX_MASK) | mir_motion_action_pointer_up;
1127+ old_ev.motion.pointer_count = 3;
1128+
1129+ auto tev = mir_input_event_get_touch_input_event(mir_event_get_input_event(&old_ev));
1130+ EXPECT_EQ(mir_touch_input_event_action_change, mir_touch_input_event_get_touch_action(tev, 0));
1131+ EXPECT_EQ(mir_touch_input_event_action_up, mir_touch_input_event_get_touch_action(tev, 1));
1132+ EXPECT_EQ(mir_touch_input_event_action_change, mir_touch_input_event_get_touch_action(tev, 2));
1133+}
1134+
1135+TEST(TouchInputEventProperties, tool_type_copied_from_old_pc)
1136+{
1137+ MirEvent old_ev;
1138+ old_ev.type = mir_event_type_motion;
1139+
1140+ auto& old_mev = old_ev.motion;
1141+ old_mev.pointer_count = 4;
1142+ old_mev.pointer_coordinates[0].tool_type = mir_motion_tool_type_unknown;
1143+ old_mev.pointer_coordinates[1].tool_type = mir_motion_tool_type_finger;
1144+ old_mev.pointer_coordinates[2].tool_type = mir_motion_tool_type_stylus;
1145+ old_mev.pointer_coordinates[3].tool_type = mir_motion_tool_type_mouse;
1146+
1147+ auto tev = mir_input_event_get_touch_input_event(mir_event_get_input_event(&old_ev));
1148+ EXPECT_EQ(mir_touch_input_tool_type_unknown, mir_touch_input_event_get_touch_tooltype(tev, 0));
1149+ EXPECT_EQ(mir_touch_input_tool_type_finger, mir_touch_input_event_get_touch_tooltype(tev, 1));
1150+ EXPECT_EQ(mir_touch_input_tool_type_stylus, mir_touch_input_event_get_touch_tooltype(tev, 2));
1151+}
1152+
1153+TEST(TouchInputEventProperties, axis_values_used_by_qtmir_copied)
1154+{
1155+ float x_value = 19, y_value = 23, touch_major = .3, touch_minor = .2, pressure = .9, size = 1111;
1156+ MirEvent old_ev;
1157+ old_ev.type = mir_event_type_motion;
1158+ old_ev.motion.pointer_count = 1;
1159+ auto &old_pc = old_ev.motion.pointer_coordinates[0];
1160+ old_pc.x = x_value;
1161+ old_pc.y = y_value;
1162+ old_pc.touch_major = touch_major;
1163+ old_pc.touch_minor = touch_minor;
1164+ old_pc.pressure = pressure;
1165+ old_pc.size = size;
1166+
1167+ auto tev = mir_input_event_get_touch_input_event(mir_event_get_input_event(&old_ev));
1168+ EXPECT_EQ(x_value, mir_touch_input_event_get_touch_axis_value(tev, 0, mir_touch_input_axis_x));
1169+ EXPECT_EQ(y_value, mir_touch_input_event_get_touch_axis_value(tev, 0, mir_touch_input_axis_y));
1170+ EXPECT_EQ(touch_major, mir_touch_input_event_get_touch_axis_value(tev, 0, mir_touch_input_axis_touch_major));
1171+ EXPECT_EQ(touch_minor, mir_touch_input_event_get_touch_axis_value(tev, 0, mir_touch_input_axis_touch_minor));
1172+ EXPECT_EQ(pressure, mir_touch_input_event_get_touch_axis_value(tev, 0, mir_touch_input_axis_pressure));
1173+ EXPECT_EQ(size, mir_touch_input_event_get_touch_axis_value(tev, 0, mir_touch_input_axis_size));
1174+}

Subscribers

People subscribed via source and target branches