Mir

Merge lp:~mir-team/mir/add-keymap-change-support into lp:mir

Proposed by Robert Carr
Status: Merged
Approved by: Alan Griffiths
Approved revision: no longer in the source branch.
Merged at revision: 2336
Proposed branch: lp:~mir-team/mir/add-keymap-change-support
Merge into: lp:mir
Diff against target: 1134 lines (+381/-60)
37 files modified
include/common/mir/events/event_builders.h (+2/-0)
include/common/mir/input/input_platform.h (+3/-1)
include/common/mir_toolkit/events/event.h (+14/-1)
include/common/mir_toolkit/events/event_deprecated.h (+12/-1)
include/common/mir_toolkit/events/keymap_event.h (+48/-0)
include/server/mir/scene/null_surface_observer.h (+1/-0)
include/server/mir/scene/surface.h (+2/-0)
include/server/mir/scene/surface_observer.h (+2/-0)
src/client/mir_surface.cpp (+11/-3)
src/client/mir_surface.h (+2/-0)
src/client/rpc/mir_protobuf_rpc_channel.cpp (+3/-1)
src/common/event.cpp (+14/-0)
src/common/events/event_builders.cpp (+12/-0)
src/common/input/CMakeLists.txt (+1/-1)
src/common/input/android/android_input_platform.cpp (+2/-2)
src/common/input/android/android_input_platform.h (+1/-1)
src/common/input/android/android_input_receiver.cpp (+9/-6)
src/common/input/android/android_input_receiver.h (+3/-2)
src/common/input/xkb_mapper.cpp (+17/-4)
src/common/symbols.map (+7/-0)
src/include/common/mir/input/xkb_mapper.h (+6/-1)
src/include/server/mir/scene/surface_event_source.h (+1/-0)
src/server/input/cursor_controller.cpp (+2/-2)
src/server/scene/basic_surface.cpp (+11/-0)
src/server/scene/basic_surface.h (+3/-0)
src/server/scene/legacy_surface_change_notification.cpp (+5/-0)
src/server/scene/legacy_surface_change_notification.h (+1/-0)
src/server/scene/null_surface_observer.cpp (+1/-0)
src/server/scene/surface_event_source.cpp (+5/-0)
tests/acceptance-tests/throwback/test_client_input.cpp (+80/-0)
tests/include/mir_test/event_matchers.h (+22/-0)
tests/include/mir_test_doubles/stub_scene_surface.h (+2/-0)
tests/integration-tests/test_test_framework.cpp (+40/-12)
tests/unit-tests/client/input/test_android_input_receiver.cpp (+18/-7)
tests/unit-tests/client/input/test_android_input_receiver_thread.cpp (+2/-1)
tests/unit-tests/client/input/test_xkb_mapper.cpp (+12/-10)
tests/unit-tests/client/test_client_mir_surface.cpp (+4/-4)
To merge this branch: bzr merge lp:~mir-team/mir/add-keymap-change-support
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Andreas Pokorny (community) Approve
Kevin DuBois (community) Approve
Chris Halse Rogers Approve
Alan Griffiths Approve
Review via email: mp+248719@code.launchpad.net

Commit message

Introduce ms::Surface::set_keymap

Description of the change

Introduce an API for shells to set the keymap for a surface. Required to implement the keyboard indicator.

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Looks OK.

But it reminds me to wonder what all this input code is doing in libmircommon (as AFAICS it isn't needed by graphics platforms).

review: Approve
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 :

709 +void ms::NullSurfaceObserver::keymap_changed(
710 + xkb_rule_names const& /* names */) {}

Strange carriage return?

Otherwise OK.

review: Needs Fixing
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 :

Whitespace fixed. CI error unrelated timeout (bumped)

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
Robert Carr (robertcarr) wrote :

Its not the timeouts :( its weird behavior due to the FD limit test based leak check test and the movement of where XKB rule files are opened in the surface creation sequence...should get time to check tomorrow

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

Made the test pass via a different method of counting FDs...there are some weird questions...

1. Why did it ever pass? Wasn't there a connection FD too meaning the last surface should have failed to create (due to its input FD being past the limit).
2. Why did the introduction of an additional fd per surface (per keymap) cause the test to fail intermittently in amd64 valgrind and nowhere else? and NOT due to timeouts?

These are the questions of our age. Anyway I believe the test is more robust now...
see "surface_creation_does_not_leak_fds"

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

I just tried my favorite layout us + intl variant, with some of the composed keys. It maps them to dead key key symbols, but does not yield any of the composed symbols. A different part of the xkb API is needed for that, and I guess some more extensions to MirEvent?

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

Looks good to me now.

@Andreas: I think we've decided that dead keys, compose keys, etc are an input method (albeit a very simple one) and will treat them as such.

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
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

okay

review: Approve
Revision history for this message
Andreas Pokorny (andreas-pokorny) :
review: Approve
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)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/common/mir/events/event_builders.h'
2--- include/common/mir/events/event_builders.h 2015-02-13 06:12:34 +0000
3+++ include/common/mir/events/event_builders.h 2015-02-20 18:01:07 +0000
4@@ -46,6 +46,8 @@
5 EventUPtr make_event(frontend::SurfaceId const& surface_id, MirSurfaceAttrib attribute, int value);
6 // Close surface event
7 EventUPtr make_event(frontend::SurfaceId const& surface_id);
8+// Keymap event
9+EventUPtr make_event(frontend::SurfaceId const& surface_id, xkb_rule_names const& names);
10
11 // Key event
12 EventUPtr make_event(MirInputDeviceId device_id, int64_t timestamp,
13
14=== modified file 'include/common/mir/input/input_platform.h'
15--- include/common/mir/input/input_platform.h 2015-01-21 07:34:50 +0000
16+++ include/common/mir/input/input_platform.h 2015-02-20 18:01:07 +0000
17@@ -32,6 +32,7 @@
18 {
19 class InputReceiverThread;
20 class InputReceiverReport;
21+class XKBMapper;
22
23 // Interface for MirSurface to construct input dispatcher threads.
24 class InputPlatform
25@@ -39,7 +40,8 @@
26 public:
27 virtual ~InputPlatform() {};
28
29- virtual std::shared_ptr<InputReceiverThread> create_input_thread(int fd, std::function<void(MirEvent *)> const& callback) = 0;
30+ virtual std::shared_ptr<InputReceiverThread> create_input_thread(
31+ int fd, std::shared_ptr<XKBMapper> const& xkb_mapper, std::function<void(MirEvent *)> const& callback) = 0;
32
33 static std::shared_ptr<InputPlatform> create();
34 static std::shared_ptr<InputPlatform> create(std::shared_ptr<InputReceiverReport> const& report);
35
36=== modified file 'include/common/mir_toolkit/events/event.h'
37--- include/common/mir_toolkit/events/event.h 2015-02-13 06:12:34 +0000
38+++ include/common/mir_toolkit/events/event.h 2015-02-20 18:01:07 +0000
39@@ -42,7 +42,8 @@
40 mir_event_type_close_surface,
41 /* Type for new style input event will be returned from mir_event_get_type
42 when old style event type was mir_event_type_key or mir_event_type_motion */
43- mir_event_type_input
44+ mir_event_type_input,
45+ mir_event_type_keymap
46 } MirEventType;
47
48 typedef struct MirSurfaceEvent MirSurfaceEvent;
49@@ -51,6 +52,7 @@
50 typedef struct MirOrientationEvent MirOrientationEvent;
51 typedef struct MirCloseSurfaceEvent MirCloseSurfaceEvent;
52 typedef struct MirInputEvent MirInputEvent;
53+typedef struct MirKeymapEvent MirKeymapEvent;
54
55 typedef union MirEvent MirEvent;
56
57@@ -73,6 +75,7 @@
58 #include "mir_toolkit/events/surface_event.h"
59 #include "mir_toolkit/events/orientation_event.h"
60 #include "mir_toolkit/events/prompt_session_event.h"
61+#include "mir_toolkit/events/keymap_event.h"
62
63 #ifdef __cplusplus
64 /**
65@@ -153,6 +156,16 @@
66 MirCloseSurfaceEvent const* mir_event_get_close_surface_event(MirEvent const* ev);
67
68 /*
69+ * Retrieve the MirKeymapEvent associated with a MirEvent of
70+ * type mir_event_type_keymap. The event signifies that the keymap
71+ * applied for the relevant surface has changed.
72+ *
73+ * \param [in] event The event
74+ * \return The associated MirKeymapEvent
75+ */
76+MirKeymapEvent const* mir_event_get_keymap_event(MirEvent const* ev);
77+
78+/*
79 *
80 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
81 * _________________________
82
83=== modified file 'include/common/mir_toolkit/events/event_deprecated.h'
84--- include/common/mir_toolkit/events/event_deprecated.h 2014-12-17 21:37:34 +0000
85+++ include/common/mir_toolkit/events/event_deprecated.h 2015-02-20 18:01:07 +0000
86@@ -29,6 +29,8 @@
87 #include <stdint.h>
88 #include "mir_toolkit/common.h"
89
90+#include <xkbcommon/xkbcommon.h>
91+
92 #ifdef __cplusplus
93 /**
94 * \addtogroup mir_toolkit
95@@ -234,9 +236,17 @@
96 int surface_id;
97 };
98
99+struct MirKeymapEvent
100+{
101+ MirEventType type;
102+
103+ int surface_id;
104+ struct xkb_rule_names rules;
105+};
106+
107+// Access to MirEvent is deprecated
108 union MirEvent
109 {
110- // Direct access to the type member is deprecated. Instead use mir_event_get_type.
111 MirEventType type;
112 MirKeyEvent key;
113 MirMotionEvent motion;
114@@ -245,6 +255,7 @@
115 MirPromptSessionEvent prompt_session;
116 MirOrientationEvent orientation;
117 MirCloseSurfaceEvent close_surface;
118+ MirKeymapEvent keymap;
119 };
120
121 #ifdef __cplusplus
122
123=== added file 'include/common/mir_toolkit/events/keymap_event.h'
124--- include/common/mir_toolkit/events/keymap_event.h 1970-01-01 00:00:00 +0000
125+++ include/common/mir_toolkit/events/keymap_event.h 2015-02-20 18:01:07 +0000
126@@ -0,0 +1,48 @@
127+/*
128+ * Copyright © 2014 Canonical Ltd.
129+ *
130+ * This program is free software: you can redistribute it and/or modify it
131+ * under the terms of the GNU Lesser General Public License version 3,
132+ * as published by the Free Software Foundation.
133+ *
134+ * This program is distributed in the hope that it will be useful,
135+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
136+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
137+ * GNU Lesser General Public License for more details.
138+ *
139+ * You should have received a copy of the GNU Lesser General Public License
140+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
141+ *
142+ * Authored by: Robert Carr <robert.carr@canonical.com>
143+ */
144+
145+#ifndef MIR_TOOLKIT_EVENTS_KEYMAP_EVENT_H_
146+#define MIR_TOOLKIT_EVENTS_KEYMAP_EVENT_H_
147+
148+#include <mir_toolkit/events/event.h>
149+
150+#include <xkbcommon/xkbcommon.h>
151+
152+#ifdef __cplusplus
153+/**
154+ * \addtogroup mir_toolkit
155+ * @{
156+ */
157+extern "C" {
158+#endif
159+
160+/*
161+ * Retrieve the new keymap reported by this MirKeymapEvent
162+ *
163+ * \param[in] ev The keymap event
164+ * \param[out] rules XKB rules describing the new keymap.
165+ */
166+void mir_keymap_event_get_rules(MirKeymapEvent const* ev,
167+ struct xkb_rule_names* names);
168+
169+#ifdef __cplusplus
170+}
171+/**@}*/
172+#endif
173+
174+#endif /* MIR_TOOLKIT_KEYMAP_EVENT_H_ */
175
176=== modified file 'include/server/mir/scene/null_surface_observer.h'
177--- include/server/mir/scene/null_surface_observer.h 2015-01-21 07:34:50 +0000
178+++ include/server/mir/scene/null_surface_observer.h 2015-02-20 18:01:07 +0000
179@@ -42,6 +42,7 @@
180 void cursor_image_set_to(graphics::CursorImage const& image) override;
181 void reception_mode_set_to(input::InputReceptionMode mode) override;
182 void client_surface_close_requested() override;
183+ void keymap_changed(xkb_rule_names const& names) override;
184
185 protected:
186 NullSurfaceObserver(NullSurfaceObserver const&) = delete;
187
188=== modified file 'include/server/mir/scene/surface.h'
189--- include/server/mir/scene/surface.h 2015-01-23 03:50:26 +0000
190+++ include/server/mir/scene/surface.h 2015-02-20 18:01:07 +0000
191@@ -105,6 +105,8 @@
192 virtual int configure(MirSurfaceAttrib attrib, int value) = 0;
193 // TODO a legacy of old interactions and needs removing
194 virtual int query(MirSurfaceAttrib attrib) = 0;
195+
196+ virtual void set_keymap(xkb_rule_names const& rules) = 0;
197 };
198 }
199 }
200
201=== modified file 'include/server/mir/scene/surface_observer.h'
202--- include/server/mir/scene/surface_observer.h 2015-01-21 07:34:50 +0000
203+++ include/server/mir/scene/surface_observer.h 2015-02-20 18:01:07 +0000
204@@ -24,6 +24,7 @@
205 #include "mir/input/input_reception_mode.h"
206
207 #include <glm/glm.hpp>
208+#include <xkbcommon/xkbcommon.h>
209
210 namespace mir
211 {
212@@ -53,6 +54,7 @@
213 virtual void reception_mode_set_to(input::InputReceptionMode mode) = 0;
214 virtual void cursor_image_set_to(graphics::CursorImage const& image) = 0;
215 virtual void client_surface_close_requested() = 0;
216+ virtual void keymap_changed(xkb_rule_names const& names) = 0;
217
218 protected:
219 SurfaceObserver() = default;
220
221=== modified file 'src/client/mir_surface.cpp'
222--- src/client/mir_surface.cpp 2015-02-13 06:12:34 +0000
223+++ src/client/mir_surface.cpp 2015-02-20 18:01:07 +0000
224@@ -25,6 +25,7 @@
225 #include "mir_connection.h"
226 #include "mir/input/input_receiver_thread.h"
227 #include "mir/input/input_platform.h"
228+#include "mir/input/xkb_mapper.h"
229
230 #include <cassert>
231 #include <unistd.h>
232@@ -118,7 +119,8 @@
233 name{spec.surface_name.value()},
234 connection(allocating_connection),
235 buffer_stream_factory(buffer_stream_factory),
236- input_platform(input_platform)
237+ input_platform(input_platform),
238+ keymapper(std::make_shared<mircv::XKBMapper>())
239 {
240 for (int i = 0; i < mir_surface_attribs; i++)
241 attrib_cache[i] = -1;
242@@ -433,8 +435,7 @@
243
244 if (surface.fd_size() > 0 && handle_event_callback)
245 {
246- input_thread = input_platform->create_input_thread(surface.fd(0),
247- handle_event_callback);
248+ input_thread = input_platform->create_input_thread(surface.fd(0), keymapper, handle_event_callback);
249 input_thread->start();
250 }
251 }
252@@ -457,6 +458,13 @@
253 case mir_event_type_orientation:
254 orientation = mir_orientation_event_get_direction(mir_event_get_orientation_event(&e));
255 break;
256+ case mir_event_type_keymap:
257+ {
258+ xkb_rule_names names;
259+ mir_keymap_event_get_rules(mir_event_get_keymap_event(&e), &names);
260+ keymapper->set_rules(names);
261+ break;
262+ }
263 default:
264 break;
265 };
266
267=== modified file 'src/client/mir_surface.h'
268--- src/client/mir_surface.h 2015-02-13 06:12:34 +0000
269+++ src/client/mir_surface.h 2015-02-20 18:01:07 +0000
270@@ -43,6 +43,7 @@
271 {
272 class InputPlatform;
273 class InputReceiverThread;
274+class XKBMapper;
275 }
276 }
277 namespace client
278@@ -159,6 +160,7 @@
279 std::shared_ptr<mir::client::ClientBufferStreamFactory> const buffer_stream_factory;
280 std::shared_ptr<mir::client::ClientBufferStream> buffer_stream;
281 std::shared_ptr<mir::input::receiver::InputPlatform> const input_platform;
282+ std::shared_ptr<mir::input::receiver::XKBMapper> const keymapper;
283
284 mir::protobuf::SurfaceSetting configure_result;
285
286
287=== modified file 'src/client/rpc/mir_protobuf_rpc_channel.cpp'
288--- src/client/rpc/mir_protobuf_rpc_channel.cpp 2015-02-13 06:12:34 +0000
289+++ src/client/rpc/mir_protobuf_rpc_channel.cpp 2015-02-20 18:01:07 +0000
290@@ -283,7 +283,9 @@
291 case mir_event_type_close_surface:
292 surface_map->with_surface_do(e.close_surface.surface_id, send_e);
293 break;
294-
295+ case mir_event_type_keymap:
296+ surface_map->with_surface_do(e.keymap.surface_id, send_e);
297+ break;
298 default:
299 event_sink->handle_event(e);
300 }
301
302=== modified file 'src/common/event.cpp'
303--- src/common/event.cpp 2014-12-18 19:11:01 +0000
304+++ src/common/event.cpp 2015-02-20 18:01:07 +0000
305@@ -133,6 +133,13 @@
306 return &ev->close_surface;
307 }
308
309+MirKeymapEvent const* mir_event_get_keymap_event(MirEvent const* ev)
310+{
311+ expect_event_type(ev, mir_event_type_keymap);
312+
313+ return &ev->keymap;
314+}
315+
316 /* Surface event accessors */
317
318 MirSurfaceAttrib mir_surface_event_get_attribute(MirSurfaceEvent const* ev)
319@@ -179,6 +186,13 @@
320 return ev->direction;
321 }
322
323+/* Keymap event accessors */
324+
325+void mir_keymap_event_get_rules(MirKeymapEvent const* ev, xkb_rule_names *out_names)
326+{
327+ expect_event_type(ev, mir_event_type_keymap);
328+ *out_names = ev->rules;
329+}
330
331 // TODO: Until we opaquify the MirEvent structure and add
332 // a ref count ref is implemented as copy.
333
334=== modified file 'src/common/events/event_builders.cpp'
335--- src/common/events/event_builders.cpp 2015-02-13 06:12:34 +0000
336+++ src/common/events/event_builders.cpp 2015-02-20 18:01:07 +0000
337@@ -352,3 +352,15 @@
338
339 return make_event_uptr(e);
340 }
341+
342+mir::EventUPtr mev::make_event(mf::SurfaceId const& surface_id, xkb_rule_names const& rules)
343+{
344+ MirEvent *e = new MirEvent;
345+ memset(e, 0, sizeof (MirEvent));
346+
347+ e->type = mir_event_type_keymap;
348+ e->keymap.surface_id = surface_id.as_value();
349+ e->keymap.rules = rules;
350+
351+ return make_event_uptr(e);
352+}
353
354=== modified file 'src/common/input/CMakeLists.txt'
355--- src/common/input/CMakeLists.txt 2015-01-21 07:34:50 +0000
356+++ src/common/input/CMakeLists.txt 2015-02-20 18:01:07 +0000
357@@ -16,7 +16,6 @@
358
359 set(
360 ANDROID_SHARED_INPUT_SOURCES
361- ${CMAKE_CURRENT_SOURCE_DIR}/xkb_mapper.cpp
362 )
363
364 include_directories(${MIR_3RD_PARTY_INCLUDE_DIRECTORIES})
365@@ -28,6 +27,7 @@
366 ${ANDROID_SHARED_INPUT_SOURCES}
367 udev_wrapper.cpp
368 input_event.cpp
369+ ${CMAKE_CURRENT_SOURCE_DIR}/xkb_mapper.cpp
370 )
371
372 list(APPEND MIR_COMMON_SOURCES
373
374=== modified file 'src/common/input/android/android_input_platform.cpp'
375--- src/common/input/android/android_input_platform.cpp 2014-03-06 06:05:17 +0000
376+++ src/common/input/android/android_input_platform.cpp 2015-02-20 18:01:07 +0000
377@@ -35,9 +35,9 @@
378 }
379
380 std::shared_ptr<mircv::InputReceiverThread> mircva::AndroidInputPlatform::create_input_thread(
381- int fd, std::function<void(MirEvent*)> const& callback)
382+ int fd, std::shared_ptr<mircv::XKBMapper> const& keymaper, std::function<void(MirEvent*)> const& callback)
383 {
384- auto receiver = std::make_shared<mircva::InputReceiver>(fd, report);
385+ auto receiver = std::make_shared<mircva::InputReceiver>(fd, keymaper, report);
386 return std::make_shared<mircva::InputReceiverThread>(receiver, callback);
387 }
388
389
390=== modified file 'src/common/input/android/android_input_platform.h'
391--- src/common/input/android/android_input_platform.h 2014-03-06 06:05:17 +0000
392+++ src/common/input/android/android_input_platform.h 2015-02-20 18:01:07 +0000
393@@ -37,7 +37,7 @@
394 AndroidInputPlatform(std::shared_ptr<InputReceiverReport> const& report);
395 virtual ~AndroidInputPlatform();
396
397- std::shared_ptr<InputReceiverThread> create_input_thread(int fd, std::function<void(MirEvent *)> const& callback);
398+ std::shared_ptr<InputReceiverThread> create_input_thread(int fd, std::shared_ptr<XKBMapper> const& xkb_mapper, std::function<void(MirEvent *)> const& callback);
399
400 protected:
401 AndroidInputPlatform(const AndroidInputPlatform&) = delete;
402
403=== modified file 'src/common/input/android/android_input_receiver.cpp'
404--- src/common/input/android/android_input_receiver.cpp 2015-02-13 06:12:34 +0000
405+++ src/common/input/android/android_input_receiver.cpp 2015-02-20 18:01:07 +0000
406@@ -16,8 +16,6 @@
407 * Authored by: Robert Carr <robert.carr@canonical.com>
408 */
409
410-#define MIR_INCLUDE_DEPRECATED_EVENT_HEADER
411-
412 #include "android_input_receiver.h"
413
414 #include "mir/input/xkb_mapper.h"
415@@ -33,27 +31,29 @@
416 namespace mia = mir::input::android;
417
418 mircva::InputReceiver::InputReceiver(droidinput::sp<droidinput::InputChannel> const& input_channel,
419+ std::shared_ptr<mircv::XKBMapper> const& keymapper,
420 std::shared_ptr<mircv::InputReceiverReport> const& report,
421 AndroidClock clock)
422 : input_channel(input_channel),
423+ xkb_mapper(keymapper),
424 report(report),
425 input_consumer(std::make_shared<droidinput::InputConsumer>(input_channel)),
426 looper(new droidinput::Looper(true)),
427 fd_added(false),
428- xkb_mapper(std::make_shared<mircv::XKBMapper>()),
429 android_clock(clock)
430 {
431 }
432
433 mircva::InputReceiver::InputReceiver(int fd,
434+ std::shared_ptr<mircv::XKBMapper> const& keymapper,
435 std::shared_ptr<mircv::InputReceiverReport> const& report,
436 AndroidClock clock)
437 : input_channel(new droidinput::InputChannel(droidinput::String8(""), fd)),
438+ xkb_mapper(keymapper),
439 report(report),
440 input_consumer(std::make_shared<droidinput::InputConsumer>(input_channel)),
441 looper(new droidinput::Looper(true)),
442 fd_added(false),
443- xkb_mapper(std::make_shared<mircv::XKBMapper>()),
444 android_clock(clock)
445 {
446 }
447@@ -74,10 +74,13 @@
448 {
449 // TODO: As XKBMapper is used to track modifier state we need to use a seperate instance
450 // of XKBMapper per device id (or modify XKBMapper semantics)
451- if (ev.type != mir_event_type_key)
452+ if (mir_event_get_type(&ev) != mir_event_type_input)
453+ return;
454+ if (mir_input_event_get_type(mir_event_get_input_event(&ev)) !=
455+ mir_input_event_type_key)
456 return;
457
458- xkb_mapper->update_state_and_map_event(ev.key);
459+ xkb_mapper->update_state_and_map_event(ev);
460 }
461
462 }
463
464=== modified file 'src/common/input/android/android_input_receiver.h'
465--- src/common/input/android/android_input_receiver.h 2015-02-13 06:12:34 +0000
466+++ src/common/input/android/android_input_receiver.h 2015-02-20 18:01:07 +0000
467@@ -55,9 +55,11 @@
468 typedef std::function<std::chrono::nanoseconds(int)> AndroidClock;
469
470 InputReceiver(droidinput::sp<droidinput::InputChannel> const& input_channel,
471+ std::shared_ptr<XKBMapper> const& keymapper,
472 std::shared_ptr<InputReceiverReport> const& report,
473 AndroidClock clock = systemTime);
474 InputReceiver(int fd,
475+ std::shared_ptr<XKBMapper> const& keymapper,
476 std::shared_ptr<InputReceiverReport> const& report,
477 AndroidClock clock = systemTime);
478
479@@ -78,6 +80,7 @@
480
481 private:
482 droidinput::sp<droidinput::InputChannel> input_channel;
483+ std::shared_ptr<XKBMapper> const xkb_mapper;
484 std::shared_ptr<InputReceiverReport> const report;
485
486 std::shared_ptr<droidinput::InputConsumer> input_consumer;
487@@ -86,8 +89,6 @@
488
489 bool fd_added;
490
491- std::shared_ptr<XKBMapper> xkb_mapper;
492-
493 AndroidClock const android_clock;
494
495 bool try_next_event(MirEvent &ev);
496
497=== modified file 'src/common/input/xkb_mapper.cpp'
498--- src/common/input/xkb_mapper.cpp 2014-03-06 06:05:17 +0000
499+++ src/common/input/xkb_mapper.cpp 2015-02-20 18:01:07 +0000
500@@ -16,6 +16,8 @@
501 * Authored by: Robert Carr <robert.carr@canonical.com>
502 */
503
504+#define MIR_INCLUDE_DEPRECATED_EVENT_HEADER
505+
506 #include "mir/input/xkb_mapper.h"
507
508 #include <string.h>
509@@ -56,9 +58,7 @@
510 names.variant = "";
511 names.options = "";
512
513- context = std::shared_ptr<xkb_context>(xkb_context_new(xkb_context_flags(0)), XKBContextDeleter());
514- map = std::shared_ptr<xkb_keymap>(xkb_map_new_from_names(context.get(), &names, xkb_map_compile_flags(0)), XKBKeymapDeleter());
515- state = std::shared_ptr<xkb_state>(xkb_state_new(map.get()), XKBStateDeleter());
516+ set_rules(names);
517 }
518
519 namespace
520@@ -85,8 +85,12 @@
521
522 }
523
524-void mircv::XKBMapper::update_state_and_map_event(MirKeyEvent &key_ev)
525+void mircv::XKBMapper::update_state_and_map_event(MirEvent &ev)
526 {
527+ std::unique_lock<std::mutex> lg(guard);
528+
529+ auto &key_ev = ev.key;
530+
531 xkb_key_direction direction;
532
533 bool update_state = true;
534@@ -106,3 +110,12 @@
535
536 key_ev.key_code = keysym_for_scan_code(state.get(), xkb_scan_code);
537 }
538+
539+void mircv::XKBMapper::set_rules(xkb_rule_names const& names)
540+{
541+ std::unique_lock<std::mutex> lg(guard);
542+
543+ context = std::shared_ptr<xkb_context>(xkb_context_new(xkb_context_flags(0)), XKBContextDeleter());
544+ map = std::shared_ptr<xkb_keymap>(xkb_map_new_from_names(context.get(), &names, xkb_map_compile_flags(0)), XKBKeymapDeleter());
545+ state = std::shared_ptr<xkb_state>(xkb_state_new(map.get()), XKBStateDeleter());
546+}
547
548=== modified file 'src/common/symbols.map'
549--- src/common/symbols.map 2015-02-18 04:25:26 +0000
550+++ src/common/symbols.map 2015-02-20 18:01:07 +0000
551@@ -222,6 +222,13 @@
552 typeinfo?for?mir::dispatch::SimpleDispatchThread;
553 vtable?for?mir::dispatch::SimpleDispatchThread;
554
555+ mir::events::*;
556+ mir::input::receiver::XKBMapper::XKBMapper*;
557+ mir::input::receiver::XKBMapper::XKBMapper*;
558+ mir::input::receiver::XKBMapper::set_rules*;
559+ typeinfo?for?mir::input::receiver::XKBMapper;
560+ vtable?for?mir::input::receiver::XKBMapper;
561+
562 mir::dispatch::MultiplexingDispatchable::MultiplexingDispatchable*;
563 mir::dispatch::MultiplexingDispatchable::?MultiplexingDispatchable*;
564 mir::dispatch::MultiplexingDispatchable::watch_fd*;
565
566=== modified file 'src/include/common/mir/input/xkb_mapper.h'
567--- src/include/common/mir/input/xkb_mapper.h 2015-02-13 06:12:34 +0000
568+++ src/include/common/mir/input/xkb_mapper.h 2015-02-20 18:01:07 +0000
569@@ -26,6 +26,7 @@
570 #include <xkbcommon/xkbcommon.h>
571
572 #include <memory>
573+#include <mutex>
574
575 namespace mir
576 {
577@@ -40,13 +41,17 @@
578 XKBMapper();
579 virtual ~XKBMapper() = default;
580
581- void update_state_and_map_event(MirKeyEvent& key_ev);
582+ void set_rules(xkb_rule_names const& names);
583+
584+ void update_state_and_map_event(MirEvent& ev);
585
586 protected:
587 XKBMapper(XKBMapper const&) = delete;
588 XKBMapper& operator=(XKBMapper const&) = delete;
589
590 private:
591+ std::mutex guard;
592+
593 std::shared_ptr<xkb_context> context;
594 std::shared_ptr<xkb_keymap> map;
595 std::shared_ptr<xkb_state> state;
596
597=== modified file 'src/include/server/mir/scene/surface_event_source.h'
598--- src/include/server/mir/scene/surface_event_source.h 2015-01-21 07:34:50 +0000
599+++ src/include/server/mir/scene/surface_event_source.h 2015-02-20 18:01:07 +0000
600@@ -40,6 +40,7 @@
601 void resized_to(geometry::Size const& size) override;
602 void orientation_set_to(MirOrientation orientation) override;
603 void client_surface_close_requested() override;
604+ void keymap_changed(xkb_rule_names const& names) override;
605
606 private:
607 frontend::SurfaceId const id;
608
609=== modified file 'src/server/input/cursor_controller.cpp'
610--- src/server/input/cursor_controller.cpp 2015-01-21 07:34:50 +0000
611+++ src/server/input/cursor_controller.cpp 2015-02-20 18:01:07 +0000
612@@ -22,7 +22,7 @@
613 #include "mir/input/surface.h"
614 #include "mir/graphics/cursor.h"
615 #include "mir/scene/observer.h"
616-#include "mir/scene/surface_observer.h"
617+#include "mir/scene/null_surface_observer.h"
618 #include "mir/scene/surface.h"
619
620 #include <functional>
621@@ -39,7 +39,7 @@
622 namespace
623 {
624
625-struct UpdateCursorOnSurfaceChanges : ms::SurfaceObserver
626+struct UpdateCursorOnSurfaceChanges : ms::NullSurfaceObserver
627 {
628 UpdateCursorOnSurfaceChanges(mi::CursorController* cursor_controller)
629 : cursor_controller(cursor_controller)
630
631=== modified file 'src/server/scene/basic_surface.cpp'
632--- src/server/scene/basic_surface.cpp 2015-02-17 11:58:56 +0000
633+++ src/server/scene/basic_surface.cpp 2015-02-20 18:01:07 +0000
634@@ -106,6 +106,12 @@
635 { observer->client_surface_close_requested(); });
636 }
637
638+void ms::SurfaceObservers::keymap_changed(xkb_rule_names const& rules)
639+{
640+ for_each([&rules](std::shared_ptr<SurfaceObserver> const& observer)
641+ { observer->keymap_changed(rules); });
642+}
643+
644
645 ms::BasicSurface::BasicSurface(
646 std::string const& name,
647@@ -742,3 +748,8 @@
648 {
649 input_sender->send_event(event, server_input_channel);
650 }
651+
652+void ms::BasicSurface::set_keymap(xkb_rule_names const& rules)
653+{
654+ observers.keymap_changed(rules);
655+}
656
657=== modified file 'src/server/scene/basic_surface.h'
658--- src/server/scene/basic_surface.h 2015-02-03 15:07:44 +0000
659+++ src/server/scene/basic_surface.h 2015-02-20 18:01:07 +0000
660@@ -72,6 +72,7 @@
661 void reception_mode_set_to(input::InputReceptionMode mode) override;
662 void cursor_image_set_to(graphics::CursorImage const& image) override;
663 void client_surface_close_requested() override;
664+ void keymap_changed(xkb_rule_names const& names) override;
665 };
666
667 class BasicSurface : public Surface
668@@ -162,6 +163,8 @@
669
670 int dpi() const;
671
672+ void set_keymap(xkb_rule_names const& rules) override;
673+
674 private:
675 bool visible(std::unique_lock<std::mutex>&) const;
676 MirSurfaceType set_type(MirSurfaceType t); // Use configure() to make public changes
677
678=== modified file 'src/server/scene/legacy_surface_change_notification.cpp'
679--- src/server/scene/legacy_surface_change_notification.cpp 2015-01-21 07:34:50 +0000
680+++ src/server/scene/legacy_surface_change_notification.cpp 2015-02-20 18:01:07 +0000
681@@ -85,3 +85,8 @@
682 void ms::LegacySurfaceChangeNotification::client_surface_close_requested()
683 {
684 }
685+
686+// A keymap change is not enough to trigger recomposition
687+void ms::LegacySurfaceChangeNotification::keymap_changed(xkb_rule_names const&)
688+{
689+}
690
691=== modified file 'src/server/scene/legacy_surface_change_notification.h'
692--- src/server/scene/legacy_surface_change_notification.h 2015-01-21 07:34:50 +0000
693+++ src/server/scene/legacy_surface_change_notification.h 2015-02-20 18:01:07 +0000
694@@ -48,6 +48,7 @@
695 void reception_mode_set_to(input::InputReceptionMode mode) override;
696 void cursor_image_set_to(graphics::CursorImage const& image) override;
697 void client_surface_close_requested() override;
698+ void keymap_changed(xkb_rule_names const& names) override;
699
700 private:
701 std::function<void()> const notify_scene_change;
702
703=== modified file 'src/server/scene/null_surface_observer.cpp'
704--- src/server/scene/null_surface_observer.cpp 2015-01-21 07:34:50 +0000
705+++ src/server/scene/null_surface_observer.cpp 2015-02-20 18:01:07 +0000
706@@ -32,3 +32,4 @@
707 void ms::NullSurfaceObserver::reception_mode_set_to(input::InputReceptionMode /*mode*/) {}
708 void ms::NullSurfaceObserver::cursor_image_set_to(mg::CursorImage const& /*image*/) {}
709 void ms::NullSurfaceObserver::client_surface_close_requested() {}
710+void ms::NullSurfaceObserver::keymap_changed(xkb_rule_names const& /* names */) {}
711
712=== modified file 'src/server/scene/surface_event_source.cpp'
713--- src/server/scene/surface_event_source.cpp 2015-02-13 06:12:34 +0000
714+++ src/server/scene/surface_event_source.cpp 2015-02-20 18:01:07 +0000
715@@ -56,3 +56,8 @@
716 {
717 event_sink->handle_event(*mev::make_event(id));
718 }
719+
720+void ms::SurfaceEventSource::keymap_changed(xkb_rule_names const& names)
721+{
722+ event_sink->handle_event(*mev::make_event(id, names));
723+}
724
725=== modified file 'tests/acceptance-tests/throwback/test_client_input.cpp'
726--- tests/acceptance-tests/throwback/test_client_input.cpp 2015-02-17 17:49:21 +0000
727+++ tests/acceptance-tests/throwback/test_client_input.cpp 2015-02-20 18:01:07 +0000
728@@ -624,3 +624,83 @@
729 session->default_surface()->consume(key_event);
730 });
731 }
732+
733+TEST_F(TestClientInput, clients_receive_keymap_change_events)
734+{
735+ using namespace testing;
736+
737+ mt::WaitCondition first_event_received;
738+ InputClient client{new_connection(), test_client_name_1};
739+
740+ xkb_rule_names names;
741+ names.rules = "evdev";
742+ names.model = "pc105";
743+ names.layout = "dvorak";
744+ names.variant = "";
745+ names.options = "";
746+
747+ InSequence seq;
748+ EXPECT_CALL(client.handler, handle_input(
749+ mt::KeymapEventWithRules(names)))
750+ .Times(1).WillOnce(mt::WakeUp(&client.all_events_received));
751+
752+ client.start();
753+
754+ server_config().the_session_container()->for_each(
755+ [names] (std::shared_ptr<ms::Session> const& session) -> void
756+ {
757+ session->default_surface()->set_keymap(names);
758+ });
759+}
760+
761+
762+TEST_F(TestClientInput, keymap_changes_change_keycode_received)
763+{
764+ using namespace testing;
765+
766+ xkb_rule_names names;
767+ names.rules = "evdev";
768+ names.model = "pc105";
769+ names.layout = "us";
770+ names.variant = "dvorak";
771+ names.options = "";
772+
773+ mt::WaitCondition first_event_received,
774+ client_sees_keymap_change;
775+ InputClient client{new_connection(), test_client_name_1};
776+
777+ InSequence seq;
778+ EXPECT_CALL(client.handler, handle_input(AllOf(
779+ mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_n)))).Times(1);
780+ EXPECT_CALL(client.handler, handle_input(mt::KeyUpEvent()))
781+ .Times(1).WillOnce(mt::WakeUp(&first_event_received));
782+ EXPECT_CALL(client.handler, handle_input(
783+ mt::KeymapEventWithRules(names)))
784+ .Times(1).WillOnce(mt::WakeUp(&client_sees_keymap_change));
785+ EXPECT_CALL(client.handler, handle_input(AllOf(
786+ mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_b)))).Times(1);
787+ EXPECT_CALL(client.handler, handle_input(mt::KeyUpEvent()))
788+ .Times(1).WillOnce(mt::WakeUp(&client.all_events_received));
789+
790+ client.start();
791+
792+ fake_event_hub()->synthesize_event(
793+ mis::a_key_down_event().of_scancode(KEY_N));
794+ fake_event_hub()->synthesize_event(
795+ mis::a_key_up_event().of_scancode(KEY_N));
796+
797+ first_event_received.wait_for_at_most_seconds(60);
798+
799+ server_config().the_session_container()->for_each(
800+ [&names] (std::shared_ptr<ms::Session> const& session) -> void
801+ {
802+ session->default_surface()->set_keymap(names);
803+ });
804+
805+ client_sees_keymap_change.wait_for_at_most_seconds(60);
806+
807+ fake_event_hub()->synthesize_event(
808+ mis::a_key_down_event().of_scancode(KEY_N));
809+ fake_event_hub()->synthesize_event(
810+ mis::a_key_up_event().of_scancode(KEY_N));
811+}
812
813=== modified file 'tests/include/mir_test/event_matchers.h'
814--- tests/include/mir_test/event_matchers.h 2015-02-13 06:12:34 +0000
815+++ tests/include/mir_test/event_matchers.h 2015-02-20 18:01:07 +0000
816@@ -340,6 +340,28 @@
817 return true;
818 }
819
820+MATCHER_P(KeymapEventWithRules, expected_rules, "")
821+{
822+ auto as_address = to_address(arg);
823+ if (mir_event_get_type(as_address) != mir_event_type_keymap)
824+ return false;
825+ auto kmev = mir_event_get_keymap_event(as_address);
826+ xkb_rule_names received_rules;
827+ mir_keymap_event_get_rules(kmev, &received_rules);
828+
829+ if (strcmp(received_rules.rules, expected_rules.rules) != 0)
830+ return false;
831+ if (strcmp(received_rules.layout, expected_rules.layout) != 0)
832+ return false;
833+ if (strcmp(received_rules.model, expected_rules.model) != 0)
834+ return false;
835+ if (strcmp(received_rules.variant, expected_rules.variant) != 0)
836+ return false;
837+ if (strcmp(received_rules.options, expected_rules.options) != 0)
838+ return false;
839+ return true;
840+}
841+
842 }
843 }
844
845
846=== modified file 'tests/include/mir_test_doubles/stub_scene_surface.h'
847--- tests/include/mir_test_doubles/stub_scene_surface.h 2015-01-22 09:00:14 +0000
848+++ tests/include/mir_test_doubles/stub_scene_surface.h 2015-02-20 18:01:07 +0000
849@@ -104,6 +104,8 @@
850 void with_most_recent_buffer_do(std::function<void(graphics::Buffer&)> const& ) override {}
851
852 std::shared_ptr<mir::scene::Surface> parent() const override { return nullptr; }
853+
854+ void set_keymap(xkb_rule_names const&) {}
855 };
856
857 }
858
859=== modified file 'tests/integration-tests/test_test_framework.cpp'
860--- tests/integration-tests/test_test_framework.cpp 2015-02-13 06:12:34 +0000
861+++ tests/integration-tests/test_test_framework.cpp 2015-02-20 18:01:07 +0000
862@@ -29,7 +29,8 @@
863
864 #include <thread>
865 #include <list>
866-#include <sys/resource.h>
867+#include <sys/types.h>
868+#include <dirent.h>
869
870 namespace mf = mir::frontend;
871
872@@ -93,25 +94,35 @@
873 mir_connection_release(connection);
874 }
875
876+namespace
877+{
878+unsigned count_fds()
879+{
880+ unsigned count = 0;
881+ DIR* dir;
882+ EXPECT_TRUE(dir = opendir("/proc/self/fd/"));
883+ while (readdir(dir) != nullptr)
884+ count++;
885+ closedir(dir);
886+ return count;
887+}
888+}
889+
890 // Regression test for https://bugs.launchpad.net/mir/+bug/1395762
891 TEST_F(DemoInProcessServerWithStubClientPlatform, surface_creation_does_not_leak_fds)
892 {
893 mir::test::Signal connection_released;
894
895+ int fd_count_after_one_surface_lifetime = 0;
896+
897 std::thread{
898 [&]
899 {
900 auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
901 EXPECT_TRUE(mir_connection_is_valid(connection));
902
903- // Use the number of allowed open files to ensure we exercise the system properly
904- struct rlimit rlim;
905- getrlimit(RLIMIT_NOFILE, &rlim);
906- rlim_t fd_limit = rlim.rlim_cur;
907- if (fd_limit == RLIM_INFINITY) fd_limit = 1024;
908-
909- for (rlim_t i = 0; i < fd_limit; ++i)
910- {
911+ for (int i = 0; i < 16; ++i)
912+ {
913 MirSurfaceParameters request_params =
914 {
915 __PRETTY_FUNCTION__,
916@@ -122,13 +133,30 @@
917 };
918
919 auto const surface = mir_connection_create_surface_sync(connection, &request_params);
920+ EXPECT_TRUE(mir_surface_is_valid(surface));
921 mir_surface_release_sync(surface);
922+
923+ if (i == 0)
924+ {
925+ fd_count_after_one_surface_lifetime = count_fds();
926+ }
927 }
928
929 mir_connection_release(connection);
930+
931 connection_released.raise();
932+
933 }}.detach();
934-
935- EXPECT_TRUE(connection_released.wait_for(std::chrono::seconds{60}))
936- << "Client hung, possibly because of fd leaks" << std::endl;
937+
938+
939+ EXPECT_TRUE(connection_released.wait_for(std::chrono::seconds{480}))
940+ << "Client hung" << std::endl;
941+
942+ // Investigation revealed we leak a differing number of fds (3, 0) on Mesa/Android over the
943+ // entire lifetime of the client library. So we verify here only that we don't leak any FDs beyond
944+ // those created up to the lifetime of the first surface.
945+ auto new_fd_count = count_fds();
946+
947+ EXPECT_LE(new_fd_count, fd_count_after_one_surface_lifetime);
948+
949 }
950
951=== modified file 'tests/unit-tests/client/input/test_android_input_receiver.cpp'
952--- tests/unit-tests/client/input/test_android_input_receiver.cpp 2015-02-13 06:12:34 +0000
953+++ tests/unit-tests/client/input/test_android_input_receiver.cpp 2015-02-20 18:01:07 +0000
954@@ -20,6 +20,7 @@
955
956 #include "src/common/input/android/android_input_receiver.h"
957 #include "mir/input/null_input_receiver_report.h"
958+#include "mir/input/xkb_mapper.h"
959 #include "mir_toolkit/event.h"
960
961 #include <androidfw/InputTransport.h>
962@@ -149,14 +150,15 @@
963
964 TEST_F(AndroidInputReceiverSetup, receiever_takes_channel_fd)
965 {
966- mircva::InputReceiver receiver(client_fd, std::make_shared<mircv::NullInputReceiverReport>());
967+ mircva::InputReceiver receiver(client_fd,
968+ std::make_shared<mircv::XKBMapper>(), std::make_shared<mircv::NullInputReceiverReport>());
969
970 EXPECT_EQ(client_fd, receiver.fd());
971 }
972
973 TEST_F(AndroidInputReceiverSetup, receiver_receives_key_events)
974 {
975- mircva::InputReceiver receiver(client_fd, std::make_shared<mircv::NullInputReceiverReport>());
976+ mircva::InputReceiver receiver(client_fd, std::make_shared<mircv::XKBMapper>(), std::make_shared<mircv::NullInputReceiverReport>());
977 TestingInputProducer producer(server_fd);
978
979 producer.produce_a_key_event();
980@@ -172,7 +174,8 @@
981
982 TEST_F(AndroidInputReceiverSetup, receiver_handles_events)
983 {
984- mircva::InputReceiver receiver(client_fd, std::make_shared<mircv::NullInputReceiverReport>());
985+ mircva::InputReceiver receiver(client_fd,
986+ std::make_shared<mircv::XKBMapper>(), std::make_shared<mircv::NullInputReceiverReport>());
987 TestingInputProducer producer(server_fd);
988
989 producer.produce_a_key_event();
990@@ -188,7 +191,9 @@
991
992 TEST_F(AndroidInputReceiverSetup, receiver_consumes_batched_motion_events)
993 {
994- mircva::InputReceiver receiver(client_fd, std::make_shared<mircv::NullInputReceiverReport>());
995+ mircva::InputReceiver receiver(client_fd,
996+ std::make_shared<mircv::XKBMapper>(),
997+ std::make_shared<mircv::NullInputReceiverReport>());
998 TestingInputProducer producer(server_fd);
999
1000 // Produce 3 motion events before client handles any.
1001@@ -213,7 +218,9 @@
1002 std::chrono::nanoseconds t = std::chrono::nanoseconds(0);
1003
1004 mircva::InputReceiver receiver(
1005- client_fd, std::make_shared<mircv::NullInputReceiverReport>(),
1006+ client_fd,
1007+ std::make_shared<mircv::XKBMapper>(),
1008+ std::make_shared<mircv::NullInputReceiverReport>(),
1009 [&t](int) { return t; }
1010 );
1011 TestingInputProducer producer(server_fd);
1012@@ -261,7 +268,9 @@
1013 std::chrono::nanoseconds t;
1014
1015 mircva::InputReceiver receiver(
1016- client_fd, std::make_shared<mircv::NullInputReceiverReport>(),
1017+ client_fd,
1018+ std::make_shared<mircv::XKBMapper>(),
1019+ std::make_shared<mircv::NullInputReceiverReport>(),
1020 [&t](int) { return t; }
1021 );
1022 TestingInputProducer producer(server_fd);
1023@@ -309,7 +318,9 @@
1024 std::chrono::nanoseconds t;
1025
1026 mircva::InputReceiver receiver(
1027- client_fd, std::make_shared<mircv::NullInputReceiverReport>(),
1028+ client_fd,
1029+ std::make_shared<mircv::XKBMapper>(),
1030+ std::make_shared<mircv::NullInputReceiverReport>(),
1031 [&t](int) { return t; }
1032 );
1033 TestingInputProducer producer(server_fd);
1034
1035=== modified file 'tests/unit-tests/client/input/test_android_input_receiver_thread.cpp'
1036--- tests/unit-tests/client/input/test_android_input_receiver_thread.cpp 2015-02-13 06:12:34 +0000
1037+++ tests/unit-tests/client/input/test_android_input_receiver_thread.cpp 2015-02-20 18:01:07 +0000
1038@@ -22,6 +22,7 @@
1039 #include "src/common/input/android/android_input_receiver.h"
1040
1041 #include "mir/input/null_input_receiver_report.h"
1042+#include "mir/input/xkb_mapper.h"
1043
1044 #include "mir_toolkit/mir_client_library.h"
1045
1046@@ -48,7 +49,7 @@
1047 struct MockInputReceiver : public mircva::InputReceiver
1048 {
1049 MockInputReceiver(int fd)
1050- : InputReceiver(fd, std::make_shared<mircv::NullInputReceiverReport>())
1051+ : InputReceiver(fd, std::make_shared<mircv::XKBMapper>(), std::make_shared<mircv::NullInputReceiverReport>())
1052 {
1053 }
1054 MOCK_METHOD1(next_event, bool(MirEvent &));
1055
1056=== modified file 'tests/unit-tests/client/input/test_xkb_mapper.cpp'
1057--- tests/unit-tests/client/input/test_xkb_mapper.cpp 2014-03-06 06:05:17 +0000
1058+++ tests/unit-tests/client/input/test_xkb_mapper.cpp 2015-02-20 18:01:07 +0000
1059@@ -32,24 +32,26 @@
1060
1061 static int map_key(mircv::XKBMapper &mapper, MirKeyAction action, int scan_code)
1062 {
1063- MirKeyEvent ev;
1064- ev.action = action;
1065- ev.scan_code = scan_code;
1066- ev.repeat_count = 0;
1067+ MirEvent ev;
1068+ ev.type = mir_event_type_key;
1069+ ev.key.action = action;
1070+ ev.key.scan_code = scan_code;
1071+ ev.key.repeat_count = 0;
1072
1073 mapper.update_state_and_map_event(ev);
1074- return ev.key_code;
1075+ return ev.key.key_code;
1076 }
1077
1078 static int map_repeated_key(mircv::XKBMapper &mapper, MirKeyAction action, int scan_code)
1079 {
1080- MirKeyEvent ev;
1081- ev.action = action;
1082- ev.scan_code = scan_code;
1083- ev.repeat_count = 1;
1084+ MirEvent ev;
1085+ ev.type = mir_event_type_key;
1086+ ev.key.action = action;
1087+ ev.key.scan_code = scan_code;
1088+ ev.key.repeat_count = 1;
1089
1090 mapper.update_state_and_map_event(ev);
1091- return ev.key_code;
1092+ return ev.key.key_code;
1093 }
1094
1095 }
1096
1097=== modified file 'tests/unit-tests/client/test_client_mir_surface.cpp'
1098--- tests/unit-tests/client/test_client_mir_surface.cpp 2015-02-13 06:12:34 +0000
1099+++ tests/unit-tests/client/test_client_mir_surface.cpp 2015-02-20 18:01:07 +0000
1100@@ -248,7 +248,7 @@
1101
1102 struct StubClientInputPlatform : public mircv::InputPlatform
1103 {
1104- std::shared_ptr<mircv::InputReceiverThread> create_input_thread(int /* fd */, std::function<void(MirEvent*)> const& /* callback */)
1105+ std::shared_ptr<mircv::InputReceiverThread> create_input_thread(int /* fd */, std::shared_ptr<mircv::XKBMapper> const&, std::function<void(MirEvent*)> const& /* callback */)
1106 {
1107 return std::shared_ptr<mircv::InputReceiverThread>();
1108 }
1109@@ -256,7 +256,7 @@
1110
1111 struct MockClientInputPlatform : public mircv::InputPlatform
1112 {
1113- MOCK_METHOD2(create_input_thread, std::shared_ptr<mircv::InputReceiverThread>(int, std::function<void(MirEvent*)> const&));
1114+ MOCK_METHOD3(create_input_thread, std::shared_ptr<mircv::InputReceiverThread>(int, std::shared_ptr<mircv::XKBMapper> const&, std::function<void(MirEvent*)> const&));
1115 };
1116
1117 struct MockInputReceiverThread : public mircv::InputReceiverThread
1118@@ -451,7 +451,7 @@
1119 auto mock_input_thread = std::make_shared<NiceMock<MockInputReceiverThread>>();
1120 MirEventDelegate delegate = {null_event_callback, nullptr};
1121
1122- EXPECT_CALL(*mock_input_platform, create_input_thread(_, _)).Times(1)
1123+ EXPECT_CALL(*mock_input_platform, create_input_thread(_, _, _)).Times(1)
1124 .WillOnce(Return(mock_input_thread));
1125 EXPECT_CALL(*mock_input_thread, start()).Times(1);
1126 EXPECT_CALL(*mock_input_thread, stop()).Times(1);
1127@@ -470,7 +470,7 @@
1128 auto mock_input_platform = std::make_shared<MockClientInputPlatform>();
1129 auto mock_input_thread = std::make_shared<NiceMock<MockInputReceiverThread>>();
1130
1131- EXPECT_CALL(*mock_input_platform, create_input_thread(_, _)).Times(0);
1132+ EXPECT_CALL(*mock_input_platform, create_input_thread(_, _, _)).Times(0);
1133 EXPECT_CALL(*mock_input_thread, start()).Times(0);
1134 EXPECT_CALL(*mock_input_thread, stop()).Times(0);
1135

Subscribers

People subscribed via source and target branches