Mir

Merge lp:~alan-griffiths/mir/spike-nested-input into lp:~mir-team/mir/trunk

Proposed by Alan Griffiths
Status: Merged
Approved by: Alan Griffiths
Approved revision: no longer in the source branch.
Merged at revision: 1059
Proposed branch: lp:~alan-griffiths/mir/spike-nested-input
Merge into: lp:~mir-team/mir/trunk
Prerequisite: lp:~alan-griffiths/mir/spike-more-nested-input
Diff against target: 612 lines (+285/-59)
13 files modified
include/server/mir/default_server_configuration.h (+3/-0)
include/server/mir/graphics/nested/nested_platform.h (+7/-3)
include/server/mir/input/nested_input_configuration.h (+5/-18)
include/server/mir/input/nested_input_relay.h (+49/-0)
src/server/default_server_configuration.cpp (+13/-2)
src/server/graphics/nested/nested_display.cpp (+10/-2)
src/server/graphics/nested/nested_display.h (+3/-0)
src/server/graphics/nested/nested_output.cpp (+38/-1)
src/server/graphics/nested/nested_output.h (+7/-3)
src/server/graphics/nested/nested_platform.cpp (+3/-1)
src/server/input/CMakeLists.txt (+1/-0)
src/server/input/nested_input_configuration.cpp (+4/-29)
src/server/input/nested_input_relay.cpp (+142/-0)
To merge this branch: bzr merge lp:~alan-griffiths/mir/spike-nested-input
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Alexandros Frantzis (community) Approve
Kevin DuBois (community) Approve
Review via email: mp+184351@code.launchpad.net

Commit message

graphics: Hook up nested surfaces events to input

Description of the change

graphics: Hook up nested surfaces events to 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: Approve (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 :

291 + std::shared_ptr<input::EventFilter> const& event_handler) :
event_filter vs. event_handler (pre-existing, and is common naming problem in the code elsewhere)

517 + // TODO can reviewers look carefully at these?
my best guess is security reasons, although i'm not very sure either

all in all, looks good

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

1. I'm concerned about this:
337 + case mir_event_type_surface:
338 + // TODO Surface attributes shouldn't be changing. So what do we do if they do?
339 + break;
Not sure of the context though. Seems strange and dangerous to drop a whole family of event types. And if it's only that we want to translate motion events, why do we handle mir_event_type_key still?

2. mi::NestedInputRelay::handle() has a scary degree of coupling. Can we not copy the event data more atomically?

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

> 2. mi::NestedInputRelay::handle() has a scary degree of coupling. Can we not
> copy the event data more atomically?

I wish! The types we adopted from the android input stack are difficult to work with (there's similar code doing the converse transformation) - hopefully we can do some refactoring once we are feature complete.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

524 + static auto const policy_flags = ::android::POLICY_FLAG_INJECTED || ::android::POLICY_FLAG_TRUSTED;

We should be using bitwise OR (|).

::android::POLICY_FLAG_INJECTED is automatically added by injectInputEvent(), so there is no need to add it.

::android::POLICY_FLAG_TRUSTED is also added by injectInputEvent() because uid == 0, but I guess it's better to be explicit about it.

I am not sure if we also need to use ::android::POLICY_FLAG_PASS_TO_USER.

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

> 524 + static auto const policy_flags = ::android::POLICY_FLAG_INJECTED ||
> ::android::POLICY_FLAG_TRUSTED;
>
> We should be using bitwise OR (|).

Good catch, thanks!

> I am not sure if we also need to use ::android::POLICY_FLAG_PASS_TO_USER.

I think that is correctly done by mia::EventFilterDispatcherPolicy

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
Alan Griffiths (alan-griffiths) wrote :

Top approving.

This code can't be tested on GBM at the moment. (We end up crashing egl when we try for a nested configuration - Alexandros is working on it.)

On android, it doesn't work (but doesn't crash). I'm continuing to work on this.

But I think the code is better off living on trunk while these problems are resolved.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/server/mir/default_server_configuration.h'
2--- include/server/mir/default_server_configuration.h 2013-08-30 09:01:48 +0000
3+++ include/server/mir/default_server_configuration.h 2013-09-10 11:30:39 +0000
4@@ -102,6 +102,7 @@
5 class InputConfiguration;
6 class CursorListener;
7 class InputRegion;
8+class NestedInputRelay;
9 }
10
11 namespace logging
12@@ -134,6 +135,7 @@
13 virtual std::shared_ptr<compositor::RendererFactory> the_renderer_factory();
14 virtual std::shared_ptr<graphics::DisplayConfigurationPolicy> the_display_configuration_policy();
15 virtual std::shared_ptr<graphics::nested::HostConnection> the_host_connection();
16+ virtual std::shared_ptr<input::NestedInputRelay> the_nested_input_relay();
17 /** @} */
18
19 /** @name graphics configuration - dependencies
20@@ -285,6 +287,7 @@
21 CachedPtr<MainLoop> main_loop;
22 CachedPtr<graphics::DisplayConfigurationPolicy> display_configuration_policy;
23 CachedPtr<graphics::nested::HostConnection> host_connection;
24+ CachedPtr<input::NestedInputRelay> nested_input_relay;
25 CachedPtr<shell::MediatingDisplayChanger> mediating_display_changer;
26 CachedPtr<shell::BroadcastingSessionEventSink> broadcasting_session_event_sink;
27
28
29=== modified file 'include/server/mir/graphics/nested/nested_platform.h'
30--- include/server/mir/graphics/nested/nested_platform.h 2013-08-30 09:01:48 +0000
31+++ include/server/mir/graphics/nested/nested_platform.h 2013-09-10 11:30:39 +0000
32@@ -25,6 +25,7 @@
33
34 namespace mir
35 {
36+namespace input { class EventFilter; }
37 namespace graphics
38 {
39 namespace nested
40@@ -33,9 +34,11 @@
41 class NestedPlatform : public Platform
42 {
43 public:
44- NestedPlatform(std::shared_ptr<HostConnection> const& connection,
45- std::shared_ptr<DisplayReport> const& display_report,
46- std::shared_ptr<NativePlatform> const& native_platform);
47+ NestedPlatform(
48+ std::shared_ptr<HostConnection> const& connection,
49+ std::shared_ptr<input::EventFilter> const& event_handler,
50+ std::shared_ptr<DisplayReport> const& display_report,
51+ std::shared_ptr<NativePlatform> const& native_platform);
52
53 ~NestedPlatform() noexcept;
54 std::shared_ptr<GraphicBufferAllocator> create_buffer_allocator(
55@@ -49,6 +52,7 @@
56
57 private:
58 std::shared_ptr<NativePlatform> const native_platform;
59+ std::shared_ptr<input::EventFilter> const event_handler;
60 std::shared_ptr<DisplayReport> const display_report;
61 std::shared_ptr<HostConnection> const connection;
62 };
63
64=== modified file 'include/server/mir/input/nested_input_configuration.h'
65--- include/server/mir/input/nested_input_configuration.h 2013-08-29 16:18:41 +0000
66+++ include/server/mir/input/nested_input_configuration.h 2013-09-10 11:30:39 +0000
67@@ -19,40 +19,27 @@
68 #ifndef MIR_INPUT_NESTED_INPUT_CONFIGURATION_H_
69 #define MIR_INPUT_NESTED_INPUT_CONFIGURATION_H_
70
71-#include "mir/input/input_configuration.h"
72+#include "mir/input/android/dispatcher_input_configuration.h"
73
74 namespace mir
75 {
76-namespace graphics { namespace nested { class HostConnection; }}
77 namespace input
78 {
79-class EventFilter;
80-class CursorListener;
81-class InputReport;
82-class InputRegion;
83+class NestedInputRelay;
84
85-class NestedInputConfiguration : public InputConfiguration
86+class NestedInputConfiguration : public android::DispatcherInputConfiguration
87 {
88 public:
89 NestedInputConfiguration(
90- std::shared_ptr<graphics::nested::HostConnection> const& connection,
91+ std::shared_ptr<NestedInputRelay> const& input_relay,
92 std::shared_ptr<EventFilter> const& event_filter,
93 std::shared_ptr<InputRegion> const& input_region,
94 std::shared_ptr<CursorListener> const& cursor_listener,
95 std::shared_ptr<InputReport> const& input_report);
96 virtual ~NestedInputConfiguration();
97
98- std::shared_ptr<surfaces::InputRegistrar> the_input_registrar();
99- std::shared_ptr<shell::InputTargeter> the_input_targeter();
100- std::shared_ptr<InputManager> the_input_manager();
101- void set_input_targets(std::shared_ptr<InputTargets> const& targets);
102-
103 private:
104- std::shared_ptr<graphics::nested::HostConnection> const connection;
105- std::shared_ptr<EventFilter> const event_filter;
106- std::shared_ptr<InputRegion> const input_region;
107- std::shared_ptr<CursorListener> const cursor_listener;
108- std::shared_ptr<InputReport> const input_report;
109+ std::shared_ptr<NestedInputRelay> const input_relay;
110 };
111 }
112 }
113
114=== added file 'include/server/mir/input/nested_input_relay.h'
115--- include/server/mir/input/nested_input_relay.h 1970-01-01 00:00:00 +0000
116+++ include/server/mir/input/nested_input_relay.h 2013-09-10 11:30:39 +0000
117@@ -0,0 +1,49 @@
118+/*
119+ * Copyright © 2013 Canonical Ltd.
120+ *
121+ * This program is free software: you can redistribute it and/or modify it
122+ * under the terms of the GNU General Public License version 3,
123+ * as published by the Free Software Foundation.
124+ *
125+ * This program is distributed in the hope that it will be useful,
126+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
127+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
128+ * GNU General Public License for more details.
129+ *
130+ * You should have received a copy of the GNU General Public License
131+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
132+ *
133+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
134+ */
135+
136+#ifndef MIR_INPUT_NESTED_INPUT_RELAY_H_
137+#define MIR_INPUT_NESTED_INPUT_RELAY_H_
138+
139+#include "mir/input/event_filter.h"
140+
141+#include <utils/StrongPointer.h>
142+
143+namespace android { class InputDispatcher; }
144+
145+namespace mir
146+{
147+namespace input
148+{
149+class NestedInputRelay : public EventFilter
150+{
151+public:
152+ NestedInputRelay();
153+ ~NestedInputRelay() noexcept;
154+
155+ void set_dispatcher(::android::sp<::android::InputDispatcher> const& dispatcher);
156+
157+private:
158+ bool handle(MirEvent const& event);
159+
160+ ::android::sp<::android::InputDispatcher> dispatcher;
161+};
162+}
163+}
164+
165+
166+#endif /* MIR_INPUT_NESTED_INPUT_RELAY_H_ */
167
168=== modified file 'src/server/default_server_configuration.cpp'
169--- src/server/default_server_configuration.cpp 2013-08-30 10:04:48 +0000
170+++ src/server/default_server_configuration.cpp 2013-09-10 11:30:39 +0000
171@@ -63,6 +63,7 @@
172 #include "mir/input/null_input_report.h"
173 #include "mir/input/display_input_region.h"
174 #include "mir/input/event_filter_chain.h"
175+#include "mir/input/nested_input_relay.h"
176 #include "mir/input/vt_filter.h"
177 #include "mir/input/android/default_android_input_configuration.h"
178 #include "mir/input/input_manager.h"
179@@ -345,7 +346,11 @@
180
181 auto create_native_platform = graphics_lib->load_function<mg::CreateNativePlatform>("create_native_platform");
182
183- return std::make_shared<mir::graphics::nested::NestedPlatform>(the_host_connection(), the_display_report(), create_native_platform());
184+ return std::make_shared<mir::graphics::nested::NestedPlatform>(
185+ the_host_connection(),
186+ the_nested_input_relay(),
187+ the_display_report(),
188+ create_native_platform());
189 });
190 }
191
192@@ -593,7 +598,7 @@
193 else if (options->is_set(nested_mode_opt))
194 {
195 return std::make_shared<mi::NestedInputConfiguration>(
196- the_host_connection(),
197+ the_nested_input_relay(),
198 the_composite_event_filter(),
199 the_input_region(),
200 the_cursor_listener(),
201@@ -959,6 +964,12 @@
202 });
203 }
204
205+auto mir::DefaultServerConfiguration::the_nested_input_relay()
206+-> std::shared_ptr<mi::NestedInputRelay>
207+{
208+ return nested_input_relay([]{ return std::make_shared<mi::NestedInputRelay>(); });
209+}
210+
211
212 std::shared_ptr<msh::BroadcastingSessionEventSink>
213 mir::DefaultServerConfiguration::the_broadcasting_session_event_sink()
214
215=== modified file 'src/server/graphics/nested/nested_display.cpp'
216--- src/server/graphics/nested/nested_display.cpp 2013-09-09 19:06:30 +0000
217+++ src/server/graphics/nested/nested_display.cpp 2013-09-10 11:30:39 +0000
218@@ -94,8 +94,12 @@
219 eglTerminate(egl_display);
220 }
221
222-mgn::NestedDisplay::NestedDisplay(std::shared_ptr<HostConnection> const& connection, std::shared_ptr<mg::DisplayReport> const& display_report) :
223+mgn::NestedDisplay::NestedDisplay(
224+ std::shared_ptr<HostConnection> const& connection,
225+ std::shared_ptr<input::EventFilter> const& event_handler,
226+ std::shared_ptr<mg::DisplayReport> const& display_report) :
227 connection{connection},
228+ event_handler{event_handler},
229 display_report{display_report},
230 egl_display{*connection},
231 outputs{}
232@@ -151,7 +155,11 @@
233 if (!mir_surface_is_valid(mir_surface))
234 BOOST_THROW_EXCEPTION(std::runtime_error(mir_surface_get_error_message(mir_surface)));
235
236- result[output.id] = std::make_shared<mgn::detail::NestedOutput>(egl_display, mir_surface, area);
237+ result[output.id] = std::make_shared<mgn::detail::NestedOutput>(
238+ egl_display,
239+ mir_surface,
240+ area,
241+ event_handler);
242 }
243 });
244
245
246=== modified file 'src/server/graphics/nested/nested_display.h'
247--- src/server/graphics/nested/nested_display.h 2013-09-09 19:06:30 +0000
248+++ src/server/graphics/nested/nested_display.h 2013-09-10 11:30:39 +0000
249@@ -32,6 +32,7 @@
250
251 namespace mir
252 {
253+namespace input { class EventFilter; }
254 namespace geometry
255 {
256 struct Rectangle;
257@@ -88,6 +89,7 @@
258 public:
259 NestedDisplay(
260 std::shared_ptr<HostConnection> const& connection,
261+ std::shared_ptr<input::EventFilter> const& event_handler,
262 std::shared_ptr<DisplayReport> const& display_report);
263
264 ~NestedDisplay() noexcept;
265@@ -114,6 +116,7 @@
266
267 private:
268 std::shared_ptr<HostConnection> const connection;
269+ std::shared_ptr<input::EventFilter> const event_handler;
270 std::shared_ptr<DisplayReport> const display_report;
271 detail::EGLDisplayHandle const egl_display;
272
273
274=== modified file 'src/server/graphics/nested/nested_output.cpp'
275--- src/server/graphics/nested/nested_output.cpp 2013-09-09 19:06:30 +0000
276+++ src/server/graphics/nested/nested_output.cpp 2013-09-10 11:30:39 +0000
277@@ -17,6 +17,7 @@
278 */
279
280 #include "nested_output.h"
281+#include "mir/input/event_filter.h"
282
283 #include "mir_toolkit/mir_client_library.h"
284
285@@ -54,14 +55,18 @@
286 mgn::detail::NestedOutput::NestedOutput(
287 EGLDisplayHandle const& egl_display,
288 MirSurface* mir_surface,
289- geometry::Rectangle const& area) :
290+ geometry::Rectangle const& area,
291+ std::shared_ptr<input::EventFilter> const& event_handler) :
292 egl_display(egl_display),
293 mir_surface{mir_surface},
294 egl_config{egl_display.choose_config(egl_attribs)},
295 egl_context{egl_display, eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, egl_context_attribs)},
296 area{area.top_left, area.size},
297+ event_handler{event_handler},
298 display_egl_surface{egl_display.create_egl_surface(egl_config, mir_surface)}
299 {
300+ MirEventDelegate ed = {event_thunk, this};
301+ mir_surface_set_event_handler(mir_surface, &ed);
302 }
303
304 geom::Rectangle mgn::detail::NestedOutput::view_area() const
305@@ -90,3 +95,35 @@
306 // TODO we really should return "true" - but we need to support bypass properly then
307 return false;
308 }
309+
310+mgn::detail::NestedOutput::~NestedOutput() noexcept
311+{
312+}
313+
314+void mgn::detail::NestedOutput::event_thunk(
315+ MirSurface* /*surface*/,
316+ MirEvent const* event,
317+ void* context)
318+try
319+{
320+ static_cast<mgn::detail::NestedOutput*>(context)->mir_event(*event);
321+}
322+catch (std::exception const&)
323+{
324+ // Just in case: do not allow exceptions to propagate.
325+}
326+
327+void mgn::detail::NestedOutput::mir_event(MirEvent const& event)
328+{
329+ if (event.type == mir_event_type_motion)
330+ {
331+ auto my_event = event;
332+ my_event.motion.x_offset += area.top_left.x.as_float();
333+ my_event.motion.y_offset += area.top_left.y.as_float();
334+ event_handler->handle(my_event);
335+ }
336+ else
337+ {
338+ event_handler->handle(event);
339+ }
340+}
341
342=== modified file 'src/server/graphics/nested/nested_output.h'
343--- src/server/graphics/nested/nested_output.h 2013-09-09 18:47:13 +0000
344+++ src/server/graphics/nested/nested_output.h 2013-09-10 11:30:39 +0000
345@@ -53,9 +53,10 @@
346 NestedOutput(
347 EGLDisplayHandle const& egl_display,
348 MirSurface* mir_surface,
349- geometry::Rectangle const& area);
350+ geometry::Rectangle const& area,
351+ std::shared_ptr<input::EventFilter> const& event_handler);
352
353- ~NestedOutput() = default;
354+ ~NestedOutput() noexcept;
355
356 geometry::Rectangle view_area() const override;
357 void make_current() override;
358@@ -71,8 +72,11 @@
359 EGLConfig const egl_config;
360 EGLContextStore const egl_context;
361 geometry::Rectangle const area;
362-
363+ std::shared_ptr<input::EventFilter> const event_handler;
364 std::shared_ptr<EGLSurfaceHandle> const display_egl_surface;
365+
366+ static void event_thunk(MirSurface* surface, MirEvent const* event, void* context);
367+ void mir_event(MirEvent const& event);
368 };
369
370 extern EGLint const egl_attribs[];
371
372=== modified file 'src/server/graphics/nested/nested_platform.cpp'
373--- src/server/graphics/nested/nested_platform.cpp 2013-09-03 09:00:53 +0000
374+++ src/server/graphics/nested/nested_platform.cpp 2013-09-10 11:30:39 +0000
375@@ -31,9 +31,11 @@
376
377 mgn::NestedPlatform::NestedPlatform(
378 std::shared_ptr<HostConnection> const& connection,
379+ std::shared_ptr<input::EventFilter> const& event_handler,
380 std::shared_ptr<mg::DisplayReport> const& display_report,
381 std::shared_ptr<mg::NativePlatform> const& native_platform) :
382 native_platform{native_platform},
383+event_handler{event_handler},
384 display_report{display_report},
385 connection{connection}
386 {
387@@ -59,7 +61,7 @@
388
389 std::shared_ptr<mg::Display> mgn::NestedPlatform::create_display(std::shared_ptr<mg::DisplayConfigurationPolicy> const& /*initial_conf_policy*/)
390 {
391- return std::make_shared<mgn::NestedDisplay>(connection, display_report);
392+ return std::make_shared<mgn::NestedDisplay>(connection, event_handler, display_report);
393 }
394
395 std::shared_ptr<mg::PlatformIPCPackage> mgn::NestedPlatform::get_ipc_package()
396
397=== modified file 'src/server/input/CMakeLists.txt'
398--- src/server/input/CMakeLists.txt 2013-08-30 07:47:16 +0000
399+++ src/server/input/CMakeLists.txt 2013-09-10 11:30:39 +0000
400@@ -6,6 +6,7 @@
401 null_input_configuration.cpp
402 null_input_report.cpp
403 nested_input_configuration.cpp
404+ nested_input_relay.cpp
405 display_input_region.cpp
406 vt_filter.cpp
407 )
408
409=== modified file 'src/server/input/nested_input_configuration.cpp'
410--- src/server/input/nested_input_configuration.cpp 2013-08-29 16:18:41 +0000
411+++ src/server/input/nested_input_configuration.cpp 2013-09-10 11:30:39 +0000
412@@ -17,6 +17,7 @@
413 */
414
415 #include "mir/input/nested_input_configuration.h"
416+#include "mir/input/nested_input_relay.h"
417
418 #include <boost/exception/all.hpp>
419 #include <stdexcept>
420@@ -24,42 +25,16 @@
421 namespace mi = mir::input;
422
423 mi::NestedInputConfiguration::NestedInputConfiguration(
424- std::shared_ptr<graphics::nested::HostConnection> const& connection,
425+ std::shared_ptr<NestedInputRelay> const& input_relay,
426 std::shared_ptr<EventFilter> const& event_filter,
427 std::shared_ptr<InputRegion> const& input_region,
428 std::shared_ptr<CursorListener> const& cursor_listener,
429 std::shared_ptr<InputReport> const& input_report) :
430-connection(connection),
431-event_filter(event_filter),
432-input_region(input_region),
433-cursor_listener(cursor_listener),
434-input_report(input_report)
435+ android::DispatcherInputConfiguration(event_filter, input_region, cursor_listener, input_report),
436+ input_relay(input_relay)
437 {
438 }
439
440 mi::NestedInputConfiguration::~NestedInputConfiguration()
441 {
442 }
443-
444-auto mi::NestedInputConfiguration::the_input_registrar()
445--> std::shared_ptr<surfaces::InputRegistrar>
446-{
447- BOOST_THROW_EXCEPTION(std::runtime_error("Nested mode input not implemented"));
448-}
449-
450-auto mi::NestedInputConfiguration::the_input_targeter()
451--> std::shared_ptr<shell::InputTargeter>
452-{
453- BOOST_THROW_EXCEPTION(std::runtime_error("Nested mode input not implemented"));
454-}
455-
456-auto mi::NestedInputConfiguration::the_input_manager()
457--> std::shared_ptr<InputManager>
458-{
459- BOOST_THROW_EXCEPTION(std::runtime_error("Nested mode input not implemented"));
460-}
461-
462-void mi::NestedInputConfiguration::set_input_targets(std::shared_ptr<InputTargets> const& /*targets*/)
463-{
464- BOOST_THROW_EXCEPTION(std::runtime_error("Nested mode input not implemented"));
465-}
466
467=== added file 'src/server/input/nested_input_relay.cpp'
468--- src/server/input/nested_input_relay.cpp 1970-01-01 00:00:00 +0000
469+++ src/server/input/nested_input_relay.cpp 2013-09-10 11:30:39 +0000
470@@ -0,0 +1,142 @@
471+/*
472+ * Copyright © 2013 Canonical Ltd.
473+ *
474+ * This program is free software: you can redistribute it and/or modify it
475+ * under the terms of the GNU General Public License version 3,
476+ * as published by the Free Software Foundation.
477+ *
478+ * This program is distributed in the hope that it will be useful,
479+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
480+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
481+ * GNU General Public License for more details.
482+ *
483+ * You should have received a copy of the GNU General Public License
484+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
485+ *
486+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
487+ */
488+
489+#include "mir/input/nested_input_relay.h"
490+
491+#include <InputDispatcher.h>
492+
493+#include <boost/exception/all.hpp>
494+#include <stdexcept>
495+
496+namespace mi = mir::input;
497+
498+mi::NestedInputRelay::NestedInputRelay()
499+{
500+}
501+
502+mi::NestedInputRelay::~NestedInputRelay() noexcept
503+{
504+}
505+
506+void mi::NestedInputRelay::set_dispatcher(::android::sp<::android::InputDispatcher> const& dispatcher)
507+{
508+ this->dispatcher = dispatcher;
509+}
510+
511+bool mi::NestedInputRelay::handle(MirEvent const& event)
512+{
513+ if (dispatcher == nullptr)
514+ {
515+ return false;
516+ }
517+
518+ // TODO it isn't obvious what to pass to injectInputEvent()
519+ // TODO can reviewers look carefully at these?
520+ static auto const injector_pid = 0;
521+ static auto const injector_uid = 0;
522+ static auto const sync_mode = ::android::INPUT_EVENT_INJECTION_SYNC_NONE;
523+ static auto const timeout_millis = 0;
524+ static auto const policy_flags = ::android::POLICY_FLAG_INJECTED | ::android::POLICY_FLAG_TRUSTED;
525+
526+ switch (event.type)
527+ {
528+ case mir_event_type_key:
529+ {
530+ ::android::KeyEvent input_event;
531+
532+ input_event.initialize(
533+ event.key.device_id, //int32_t deviceId,
534+ event.key.source_id, //int32_t source,
535+ event.key.action, //int32_t action,
536+ event.key.flags, //int32_t flags,
537+ event.key.key_code, //int32_t keyCode,
538+ event.key.scan_code, //int32_t scanCode,
539+ event.key.modifiers, //int32_t metaState,
540+ event.key.repeat_count, //int32_t repeatCount,
541+ event.key.down_time, //nsecs_t downTime,
542+ event.key.event_time); //nsecs_t eventTime
543+
544+ dispatcher->injectInputEvent(
545+ &input_event, //const InputEvent* event,
546+ injector_pid, //int32_t injectorPid,
547+ injector_uid, //int32_t injectorUid,
548+ sync_mode, //int32_t syncMode,
549+ timeout_millis, //int32_t timeoutMillis,
550+ policy_flags); //uint32_t policyFlags
551+ break;
552+ }
553+
554+ case mir_event_type_motion:
555+ {
556+ ::android::MotionEvent input_event;
557+
558+ std::vector<::android::PointerProperties> pointer_properties(event.motion.pointer_count);
559+ std::vector<::android::PointerCoords> pointer_coords(event.motion.pointer_count);
560+
561+ for(auto i = 0U; i != event.motion.pointer_count; ++i)
562+ {
563+ pointer_properties[i].id = event.motion.pointer_coordinates[i].id;
564+ pointer_properties[i].toolType = 0;
565+
566+ pointer_coords[i].setAxisValue(AMOTION_EVENT_AXIS_X, event.motion.pointer_coordinates[i].x);
567+ pointer_coords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, event.motion.pointer_coordinates[i].y);
568+ pointer_coords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, event.motion.pointer_coordinates[i].pressure);
569+ pointer_coords[i].setAxisValue(AMOTION_EVENT_AXIS_SIZE, event.motion.pointer_coordinates[i].size);
570+ pointer_coords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, event.motion.pointer_coordinates[i].touch_major);
571+ pointer_coords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, event.motion.pointer_coordinates[i].touch_minor);
572+ pointer_coords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, event.motion.pointer_coordinates[i].orientation);
573+ }
574+
575+ input_event.initialize(
576+ event.motion.device_id, //int32_t deviceId,
577+ event.motion.source_id, //int32_t source,
578+ event.motion.action, //int32_t action,
579+ event.motion.flags, //int32_t flags,
580+ event.motion.edge_flags, //int32_t edgeFlags,
581+ event.motion.modifiers, //int32_t metaState,
582+ event.motion.button_state, //int32_t buttonState,
583+ event.motion.x_offset, //float xOffset,
584+ event.motion.y_offset, //float yOffset,
585+ event.motion.x_precision, //float xPrecision,
586+ event.motion.y_precision, //float yPrecision,
587+ event.motion.down_time, //nsecs_t downTime,
588+ event.motion.event_time, //nsecs_t eventTime,
589+ event.motion.pointer_count, //size_t pointerCount,
590+ pointer_properties.data(), //const PointerProperties* pointerProperties,
591+ pointer_coords.data()); //const PointerCoords* pointerCoords);
592+
593+ dispatcher->injectInputEvent(
594+ &input_event, //const InputEvent* event,
595+ injector_pid, //int32_t injectorPid,
596+ injector_uid, //int32_t injectorUid,
597+ sync_mode, //int32_t syncMode,
598+ timeout_millis, //int32_t timeoutMillis,
599+ policy_flags); //uint32_t policyFlags
600+ break;
601+ }
602+
603+ case mir_event_type_surface:
604+ // Just ignore these events: it doesn't make sense to pass them on.
605+ break;
606+
607+ default:
608+ BOOST_THROW_EXCEPTION(std::logic_error("Unhandled event type"));
609+ }
610+
611+ return true;
612+}

Subscribers

People subscribed via source and target branches