Mir

Merge lp:~thomas-voss/mir/explicit-gcc-version into lp:mir/ubuntu

Proposed by Thomas Voß
Status: Superseded
Proposed branch: lp:~thomas-voss/mir/explicit-gcc-version
Merge into: lp:mir/ubuntu
Diff against target: 14184 lines (+6682/-2725) (has conflicts)
192 files modified
3rd_party/android-input/android/frameworks/base/services/input/InputReader.cpp (+10/-20)
3rd_party/android-input/android/frameworks/base/services/input/InputReader.h (+15/-6)
benchmarks/android-input/input_reader_perf.cpp (+6/-0)
debian/changelog (+13/-0)
debian/control (+5/-1)
debian/rules (+7/-0)
examples/eglapp.c (+17/-0)
include/client/mir_toolkit/mir_cursor_configuration.h (+2/-11)
include/client/mir_toolkit/mir_surface.h (+7/-0)
include/platform/mir/graphics/event_handler_register.h (+3/-0)
include/platform/mir/graphics/native_platform.h (+5/-1)
include/platform/mir/graphics/platform.h (+15/-4)
include/server/mir/asio_main_loop.h (+9/-2)
include/server/mir/compositor/compositor_id.h (+32/-0)
include/server/mir/compositor/scene.h (+14/-10)
include/server/mir/compositor/scene_element.h (+52/-0)
include/server/mir/default_server_configuration.h (+6/-0)
include/server/mir/input/android/default_android_input_configuration.h (+0/-1)
include/server/mir/input/input_configuration.h (+0/-2)
include/server/mir/input/input_send_observer.h (+76/-0)
include/server/mir/input/input_sender.h (+48/-0)
include/server/mir/input/input_targets.h (+8/-0)
include/server/mir/input/surface.h (+14/-0)
include/server/mir/scene/null_surface_observer.h (+1/-0)
include/server/mir/scene/surface.h (+2/-1)
include/server/mir/scene/surface_event_source.h (+1/-0)
include/server/mir/scene/surface_observer.h (+1/-0)
include/shared/mir/graphics/android/android_native_buffer.h (+7/-4)
include/shared/mir/graphics/android/native_buffer.h (+11/-2)
include/shared/mir_toolkit/common.h (+20/-1)
include/shared/mir_toolkit/event.h (+11/-1)
include/test/mir_test/client_event_matchers.h (+13/-0)
include/test/mir_test/event_factory.h (+13/-0)
include/test/mir_test/fake_event_hub.h (+9/-3)
include/test/mir_test_doubles/mock_android_native_buffer.h (+2/-2)
include/test/mir_test_doubles/mock_input_send_observer.h (+44/-0)
include/test/mir_test_doubles/mock_input_sender.h (+42/-0)
include/test/mir_test_doubles/mock_input_surface.h (+2/-14)
include/test/mir_test_doubles/mock_main_loop.h (+66/-0)
include/test/mir_test_doubles/mock_scene.h (+5/-3)
include/test/mir_test_doubles/mock_surface.h (+1/-0)
include/test/mir_test_doubles/null_platform.h (+2/-1)
include/test/mir_test_doubles/stub_buffer.h (+37/-16)
include/test/mir_test_doubles/stub_display.h (+69/-0)
include/test/mir_test_doubles/stub_gbm_native_buffer.h (+55/-0)
include/test/mir_test_doubles/stub_input_sender.h (+42/-0)
include/test/mir_test_doubles/stub_input_surface.h (+3/-0)
include/test/mir_test_doubles/stub_input_targets.h (+6/-0)
include/test/mir_test_doubles/stub_renderable.h (+16/-0)
include/test/mir_test_doubles/stub_scene.h (+7/-1)
include/test/mir_test_doubles/stub_scene_element.h (+60/-0)
include/test/mir_test_doubles/stub_scene_surface.h (+3/-1)
include/test/mir_test_doubles/stub_swapping_gl_context.h (+12/-1)
include/test/mir_test_doubles/stub_timer.h (+1/-1)
include/test/mir_test_framework/deferred_in_process_server.h (+41/-0)
include/test/mir_test_framework/in_process_server.h (+0/-10)
include/test/mir_test_framework/input_testing_server_configuration.h (+2/-0)
include/test/mir_test_framework/stubbed_server_configuration.h (+8/-0)
include/test/mir_test_framework/testing_server_configuration.h (+1/-0)
src/client/android/android_client_buffer.cpp (+1/-1)
src/client/cursor_configuration.h (+2/-0)
src/client/mir_cursor_api.cpp (+8/-5)
src/client/mir_surface.cpp (+17/-2)
src/client/mir_surface.h (+2/-0)
src/client/mir_surface_api.cpp (+5/-0)
src/client/rpc/mir_socket_rpc_channel.cpp (+19/-18)
src/platform/graphics/android/android_alloc_adaptor.cpp (+1/-1)
src/platform/graphics/android/android_platform.cpp (+23/-16)
src/platform/graphics/android/android_platform.h (+2/-1)
src/platform/graphics/android/buffer.cpp (+1/-1)
src/platform/graphics/android/fb_device.cpp (+1/-1)
src/platform/graphics/android/hwc_device.cpp (+14/-4)
src/platform/graphics/android/hwc_fallback_gl_renderer.cpp (+6/-1)
src/platform/graphics/android/hwc_fb_device.cpp (+1/-1)
src/platform/graphics/android/hwc_layers.cpp (+13/-2)
src/platform/graphics/android/internal_client_window.cpp (+1/-1)
src/platform/graphics/android/interpreter_cache.cpp (+1/-1)
src/platform/graphics/mesa/display.cpp (+1/-0)
src/platform/graphics/mesa/native_platform.cpp (+18/-13)
src/platform/graphics/mesa/native_platform.h (+2/-1)
src/platform/graphics/mesa/platform.cpp (+17/-13)
src/platform/graphics/mesa/platform.h (+2/-1)
src/server/asio_main_loop.cpp (+136/-47)
src/server/compositor/default_display_buffer_compositor.cpp (+22/-2)
src/server/compositor/default_display_buffer_compositor.h (+1/-0)
src/server/compositor/occlusion.cpp (+20/-6)
src/server/compositor/occlusion.h (+1/-4)
src/server/compositor/timeout_frame_dropping_policy_factory.cpp (+8/-8)
src/server/default_server_configuration.cpp (+0/-24)
src/server/frontend/session_mediator.cpp (+20/-17)
src/server/frontend/session_mediator.h (+6/-2)
src/server/graphics/default_configuration.cpp (+18/-3)
src/server/graphics/nested/nested_platform.cpp (+3/-2)
src/server/graphics/nested/nested_platform.h (+2/-1)
src/server/input/CMakeLists.txt (+2/-0)
src/server/input/android/CMakeLists.txt (+1/-0)
src/server/input/android/android_input_reader_policy.cpp (+13/-1)
src/server/input/android/android_input_reader_policy.h (+5/-2)
src/server/input/android/default_android_input_configuration.cpp (+0/-6)
src/server/input/android/input_send_entry.h (+51/-0)
src/server/input/android/input_sender.cpp (+410/-0)
src/server/input/android/input_sender.h (+146/-0)
src/server/input/cursor_controller.cpp (+244/-0)
src/server/input/cursor_controller.h (+77/-0)
src/server/input/default_configuration.cpp (+45/-4)
src/server/input/nested_input_configuration.cpp (+0/-9)
src/server/input/nested_input_configuration.h (+1/-4)
src/server/input/null_input_channel_factory.cpp (+44/-0)
src/server/input/null_input_channel_factory.h (+38/-0)
src/server/input/null_input_configuration.cpp (+0/-34)
src/server/input/null_input_configuration.h (+0/-1)
src/server/input/null_input_send_observer.h (+47/-0)
src/server/scene/CMakeLists.txt (+1/-0)
src/server/scene/basic_surface.cpp (+46/-2)
src/server/scene/basic_surface.h (+9/-1)
src/server/scene/default_configuration.cpp (+1/-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/prompt_session_manager_impl.cpp (+0/-4)
src/server/scene/rendering_tracker.cpp (+85/-0)
src/server/scene/rendering_tracker.h (+60/-0)
src/server/scene/surface_allocator.cpp (+3/-0)
src/server/scene/surface_allocator.h (+3/-0)
src/server/scene/surface_event_source.cpp (+12/-0)
src/server/scene/surface_stack.cpp (+84/-16)
src/server/scene/surface_stack.h (+12/-21)
src/shared/graphics/android/android_native_buffer.cpp (+9/-3)
src/shared/graphics/android/mir_native_window.cpp (+1/-1)
src/shared/testdraw/android_graphics_region_factory.cpp (+2/-1)
tests/acceptance-tests/CMakeLists.txt (+2/-0)
tests/acceptance-tests/test_client_cursor_api.cpp (+346/-355)
tests/acceptance-tests/test_client_input.cpp (+81/-13)
tests/acceptance-tests/test_client_library.cpp (+0/-67)
tests/acceptance-tests/test_client_surface_events.cpp (+253/-0)
tests/acceptance-tests/test_client_surface_visibility.cpp (+346/-0)
tests/acceptance-tests/test_display_configuration.cpp (+1/-0)
tests/acceptance-tests/test_shell_control_of_surface_configuration.cpp (+8/-4)
tests/acceptance-tests/test_surfaces_with_output_id.cpp (+112/-244)
tests/integration-tests/graphics/android/test_internal_client.cpp (+3/-1)
tests/integration-tests/test_display_server_main_loop_events.cpp (+1/-0)
tests/integration-tests/test_session.cpp (+7/-22)
tests/integration-tests/test_surface_first_frame_sync.cpp (+8/-21)
tests/integration-tests/test_surface_stack_with_compositor.cpp (+4/-1)
tests/integration-tests/test_surfaceloop.cpp (+52/-277)
tests/mir_test_doubles/event_factory.cpp (+25/-0)
tests/mir_test_doubles/fake_event_hub.cpp (+62/-0)
tests/mir_test_framework/input_testing_server_options.cpp (+13/-3)
tests/mir_test_framework/stubbed_server_configuration.cpp (+70/-80)
tests/mir_test_framework/testing_server_options.cpp (+7/-0)
tests/unit-tests/android_input/input_reader.cpp (+12/-5)
tests/unit-tests/client/android/test_android_native_window.cpp (+1/-1)
tests/unit-tests/client/test_client_mir_surface.cpp (+366/-396)
tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp (+132/-26)
tests/unit-tests/compositor/test_multi_threaded_compositor.cpp (+4/-18)
tests/unit-tests/compositor/test_occlusion.cpp (+92/-83)
tests/unit-tests/frontend/stress_protobuf_communicator.cpp (+4/-2)
tests/unit-tests/frontend/test_protobuf_surface_apis.cpp (+6/-4)
tests/unit-tests/frontend/test_published_socket_connector.cpp (+6/-3)
tests/unit-tests/frontend/test_session_mediator.cpp (+32/-8)
tests/unit-tests/graphics/android/CMakeLists.txt (+1/-1)
tests/unit-tests/graphics/android/hwc_struct_helpers.cpp (+1/-0)
tests/unit-tests/graphics/android/hwc_struct_helpers.h (+1/-0)
tests/unit-tests/graphics/android/test_android_platform.cpp (+30/-2)
tests/unit-tests/graphics/android/test_buffer.cpp (+4/-4)
tests/unit-tests/graphics/android/test_buffer_tex_bind.cpp (+1/-1)
tests/unit-tests/graphics/android/test_hwc_device.cpp (+174/-295)
tests/unit-tests/graphics/android/test_hwc_fallback_gl_renderer.cpp (+24/-7)
tests/unit-tests/graphics/android/test_hwc_fb_device.cpp (+1/-0)
tests/unit-tests/graphics/android/test_hwc_layers.cpp (+4/-2)
tests/unit-tests/graphics/android/test_interpreter_buffer_cache.cpp (+2/-2)
tests/unit-tests/graphics/android/test_native_buffer.cpp (+68/-23)
tests/unit-tests/graphics/mesa/test_display.cpp (+6/-3)
tests/unit-tests/graphics/mesa/test_linux_virtual_terminal.cpp (+4/-1)
tests/unit-tests/graphics/mesa/test_native_platform.cpp (+19/-40)
tests/unit-tests/graphics/mesa/test_platform.cpp (+8/-6)
tests/unit-tests/graphics/nested/test_nested_platform.cpp (+2/-1)
tests/unit-tests/input/CMakeLists.txt (+1/-0)
tests/unit-tests/input/android/CMakeLists.txt (+1/-0)
tests/unit-tests/input/android/test_android_input_sender.cpp (+417/-0)
tests/unit-tests/input/android/test_android_input_target_enumerator.cpp (+9/-0)
tests/unit-tests/input/test_cursor_controller.cpp (+391/-0)
tests/unit-tests/scene/CMakeLists.txt (+1/-0)
tests/unit-tests/scene/test_basic_surface.cpp (+97/-150)
tests/unit-tests/scene/test_prompt_session_manager.cpp (+55/-0)
tests/unit-tests/scene/test_rendering_tracker.cpp (+143/-0)
tests/unit-tests/scene/test_session_manager.cpp (+1/-0)
tests/unit-tests/scene/test_surface.cpp (+59/-2)
tests/unit-tests/scene/test_surface_impl.cpp (+15/-0)
tests/unit-tests/scene/test_surface_stack.cpp (+198/-89)
tests/unit-tests/shell/test_graphics_display_layout.cpp (+11/-32)
tests/unit-tests/test_asio_main_loop.cpp (+43/-0)
Text conflict in debian/changelog
To merge this branch: bzr merge lp:~thomas-voss/mir/explicit-gcc-version
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Alan Griffiths Needs Resubmitting
Matthias Klose Pending
Colin Watson Pending
Cemil Azizoglu Pending
Review via email: mp+224773@code.launchpad.net

This proposal has been superseded by a proposal from 2014-06-27.

Commit message

Explicitly select g++-4.9 to prevent from ABI breaks.

Description of the change

Explicitly select g++-4.9 to prevent from ABI breaks.

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

Lots of unrelated change. (Looks like development-branch may be the intended target.)

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '3rd_party/android-input/android/frameworks/base/services/input/InputReader.cpp'
2--- 3rd_party/android-input/android/frameworks/base/services/input/InputReader.cpp 2014-05-21 02:24:48 +0000
3+++ 3rd_party/android-input/android/frameworks/base/services/input/InputReader.cpp 2014-06-27 09:18:41 +0000
4@@ -922,7 +922,7 @@
5 mMappers.add(mapper);
6 }
7
8-void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) {
9+void InputDevice::configure(nsecs_t when, InputReaderConfiguration const* config, uint32_t changes) {
10 mSources = 0;
11
12 if (!isIgnored()) {
13@@ -1760,7 +1760,7 @@
14 void InputMapper::dump(String8& dump) {
15 }
16
17-void InputMapper::configure(nsecs_t when,
18+void InputMapper::configure(nsecs_t when,
19 const InputReaderConfiguration* config, uint32_t changes) {
20 }
21
22@@ -1998,8 +1998,7 @@
23 }
24
25
26-void KeyboardInputMapper::configure(nsecs_t when,
27- const InputReaderConfiguration* config, uint32_t changes) {
28+void KeyboardInputMapper::configure(nsecs_t when, InputReaderConfiguration const* config, uint32_t changes) {
29 InputMapper::configure(when, config, changes);
30
31 if (!changes) { // first time only
32@@ -2284,8 +2283,7 @@
33 appendFormat(dump, INDENT3 "DownTime: %lld\n", mDownTime);
34 }
35
36-void CursorInputMapper::configure(nsecs_t when,
37- const InputReaderConfiguration* config, uint32_t changes) {
38+void CursorInputMapper::configure(nsecs_t when, InputReaderConfiguration const* config, uint32_t changes) {
39 InputMapper::configure(when, config, changes);
40
41 if (!changes) { // first time only
42@@ -2694,8 +2692,8 @@
43 }
44 }
45
46-void TouchInputMapper::configure(nsecs_t when,
47- const InputReaderConfiguration* config, uint32_t changes) {
48+void TouchInputMapper::configure(nsecs_t when, const InputReaderConfiguration* config,
49+ uint32_t changes) {
50 InputMapper::configure(when, config, changes);
51
52 mConfig = *config;
53@@ -2792,16 +2790,9 @@
54 getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
55 mParameters.orientationAware);
56
57- mParameters.associatedDisplayId = -1;
58- mParameters.associatedDisplayIsExternal = false;
59- if (mParameters.orientationAware
60- || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
61- || mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
62- mParameters.associatedDisplayIsExternal =
63- mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
64- && getDevice()->isExternal();
65- mParameters.associatedDisplayId = 0;
66- }
67+ mContext->getPolicy()->getAssociatedDisplayInfo(getDevice()->getIdentifier(),
68+ mParameters.associatedDisplayId, mParameters.associatedDisplayIsExternal);
69+
70 }
71
72 void TouchInputMapper::dumpParameters(String8& dump) {
73@@ -6055,8 +6046,7 @@
74 }
75 }
76
77-void JoystickInputMapper::configure(nsecs_t when,
78- const InputReaderConfiguration* config, uint32_t changes) {
79+void JoystickInputMapper::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) {
80 InputMapper::configure(when, config, changes);
81
82 if (!changes) { // first time only
83
84=== modified file '3rd_party/android-input/android/frameworks/base/services/input/InputReader.h'
85--- 3rd_party/android-input/android/frameworks/base/services/input/InputReader.h 2014-05-21 02:24:48 +0000
86+++ 3rd_party/android-input/android/frameworks/base/services/input/InputReader.h 2014-06-27 09:18:41 +0000
87@@ -240,6 +240,10 @@
88
89 /* Gets a user-supplied alias for a particular input device, or an empty string if none. */
90 virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier) = 0;
91+
92+ /* Retrieve the display association for a given device. */
93+ virtual void getAssociatedDisplayInfo(InputDeviceIdentifier const& identifier,
94+ int& out_associated_display_id, bool& out_associated_display_is_external) = 0;
95 };
96
97
98@@ -472,6 +476,7 @@
99 inline const String8& getName() { return mIdentifier.name; }
100 inline uint32_t getClasses() { return mClasses; }
101 inline uint32_t getSources() { return mSources; }
102+ inline InputDeviceIdentifier const& getIdentifier() { return mIdentifier; }
103
104 inline bool isExternal() { return mIsExternal; }
105 inline void setExternal(bool external) { mIsExternal = external; }
106@@ -480,7 +485,7 @@
107
108 void dump(String8& dump);
109 void addMapper(InputMapper* mapper);
110- void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
111+ void configure(nsecs_t when, InputReaderConfiguration const* config, uint32_t changes);
112 void reset(nsecs_t when);
113 void process(const RawEvent* rawEvents, size_t count);
114 void timeoutExpired(nsecs_t when);
115@@ -892,7 +897,7 @@
116 virtual uint32_t getSources() = 0;
117 virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
118 virtual void dump(String8& dump);
119- virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
120+ virtual void configure(nsecs_t when, InputReaderConfiguration const* config, uint32_t changes);
121 virtual void reset(nsecs_t when);
122 virtual void process(const RawEvent* rawEvent) = 0;
123 virtual void timeoutExpired(nsecs_t when);
124@@ -974,7 +979,8 @@
125 virtual uint32_t getSources();
126 virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
127 virtual void dump(String8& dump);
128- virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
129+ virtual void configure(nsecs_t when,
130+ InputReaderConfiguration const* config, uint32_t changes);
131 virtual void reset(nsecs_t when);
132 virtual void process(const RawEvent* rawEvent);
133
134@@ -1042,7 +1048,8 @@
135 virtual uint32_t getSources();
136 virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
137 virtual void dump(String8& dump);
138- virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
139+ virtual void configure(nsecs_t when,
140+ InputReaderConfiguration const* config, uint32_t changes);
141 virtual void reset(nsecs_t when);
142 virtual void process(const RawEvent* rawEvent);
143
144@@ -1107,7 +1114,8 @@
145 virtual uint32_t getSources();
146 virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
147 virtual void dump(String8& dump);
148- virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
149+ virtual void configure(nsecs_t when,
150+ InputReaderConfiguration const* config, uint32_t changes);
151 virtual void reset(nsecs_t when);
152 virtual void process(const RawEvent* rawEvent);
153
154@@ -1679,7 +1687,8 @@
155 virtual uint32_t getSources();
156 virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
157 virtual void dump(String8& dump);
158- virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
159+ virtual void configure(nsecs_t when,
160+ InputReaderConfiguration const* config, uint32_t changes);
161 virtual void reset(nsecs_t when);
162 virtual void process(const RawEvent* rawEvent);
163
164
165=== modified file 'benchmarks/android-input/input_reader_perf.cpp'
166--- benchmarks/android-input/input_reader_perf.cpp 2014-05-21 02:24:48 +0000
167+++ benchmarks/android-input/input_reader_perf.cpp 2014-06-27 09:18:41 +0000
168@@ -61,6 +61,12 @@
169 return mInputDevices;
170 }
171
172+ void getAssociatedDisplayInfo(InputDeviceIdentifier const& /* identifier */,
173+ int& out_associated_display_id, bool& out_associated_display_is_external) {
174+ out_associated_display_id = 0;
175+ out_associated_display_is_external = false;
176+ }
177+
178 private:
179 virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) {
180 *outConfig = mConfig;
181
182=== modified file 'debian/changelog'
183--- debian/changelog 2014-06-18 17:51:53 +0000
184+++ debian/changelog 2014-06-27 09:18:41 +0000
185@@ -1,3 +1,4 @@
186+<<<<<<< TREE
187 mir (0.3.0+14.10.20140618.1-0ubuntu1) utopic; urgency=medium
188
189 [ Cemil Azizoglu ]
190@@ -48,6 +49,11 @@
191 mir (0.2.0+14.10.20140605-0ubuntu1) utopic; urgency=medium
192
193 [ Daniel van Vugt ]
194+=======
195+mir (0.2.0-0ubuntu2) UNRELEASED; urgency=medium
196+
197+ [ Daniel van Vugt ]
198+>>>>>>> MERGE-SOURCE
199 * New upstream release 0.2.0 (https://launchpad.net/mir/+milestone/0.2.0)
200 - mirclient ABI unchanged, still at 7. Clients do not need rebuilding.
201 - mirserver ABI bumped to 20. Shells need rebuilding.
202@@ -173,7 +179,14 @@
203 [ Ubuntu daily release ]
204 * New rebuild forced
205
206+<<<<<<< TREE
207 -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 05 Jun 2014 14:02:57 +0000
208+=======
209+ [ Thomas Voß ]
210+ * Explicitly select g++-4.9 to prevent from ABI breaks.
211+
212+ -- Thomas Voß <thomas.voss@canonical.com> Fri, 27 Jun 2014 11:16:47 +0200
213+>>>>>>> MERGE-SOURCE
214
215 mir (0.1.9+14.10.20140430.1-0ubuntu1) utopic; urgency=medium
216
217
218=== modified file 'debian/control'
219--- debian/control 2014-06-18 12:50:31 +0000
220+++ debian/control 2014-06-27 09:18:41 +0000
221@@ -10,6 +10,10 @@
222 doxygen,
223 xsltproc,
224 graphviz,
225+# We rely on C++11 features, and to prevent from ABI breaks
226+# in libstdc++ causing us issues, we explicitly select a G++
227+# version.
228+ g++-4.9,
229 libboost-dev,
230 libboost-chrono-dev,
231 libboost-date-time-dev,
232@@ -27,7 +31,7 @@
233 libglm-dev,
234 libprotobuf-dev,
235 pkg-config,
236- android-headers (>=4.2.2) [i386 amd64 armhf],
237+ android-headers (>=4.4.2) [i386 amd64 armhf],
238 libhardware-dev [i386 amd64 armhf],
239 libandroid-properties-dev [i386 amd64 armhf],
240 libgoogle-glog-dev,
241
242=== modified file 'debian/rules'
243--- debian/rules 2014-04-15 17:11:14 +0000
244+++ debian/rules 2014-06-27 09:18:41 +0000
245@@ -6,6 +6,13 @@
246
247 export DPKG_GENSYMBOLS_CHECK_LEVEL = 4
248
249+include /usr/share/dpkg/default.mk
250+
251+# Explicitly selecting a G{CC,++}-version here to avoid accidental
252+# ABI breaks introduced by toolchain updates.
253+export CC=$(DEB_HOST_GNU_TYPE)-gcc-4.9
254+export CXX=$(DEB_HOST_GNU_TYPE)-g++-4.9
255+
256 %:
257 dh $@ --parallel --fail-missing
258
259
260=== modified file 'examples/eglapp.c'
261--- examples/eglapp.c 2014-06-12 15:35:08 +0000
262+++ examples/eglapp.c 2014-06-27 09:18:41 +0000
263@@ -127,6 +127,14 @@
264 */
265 printf("Resized to %dx%d\n", ev->resize.width, ev->resize.height);
266 }
267+ else if (ev->type == mir_event_type_surface &&
268+ ev->surface.attrib == mir_surface_attrib_visibility)
269+ {
270+ if (ev->surface.value == mir_surface_visibility_exposed)
271+ printf("Surface exposed\n");
272+ else if (ev->surface.value == mir_surface_visibility_occluded)
273+ printf("Surface occluded\n");
274+ }
275 }
276
277 static const MirDisplayOutput *find_active_output(
278@@ -179,6 +187,7 @@
279 EGLBoolean ok;
280 EGLint swapinterval = 1;
281 char *mir_socket = NULL;
282+ char const* cursor_name = mir_default_cursor_name;
283
284 if (argc > 1)
285 {
286@@ -263,6 +272,9 @@
287 case 'm':
288 mir_socket = argv[++i];
289 break;
290+ case 'c':
291+ cursor_name = argv[++i];
292+ break;
293 case 'q':
294 {
295 FILE *unused = freopen("/dev/null", "a", stdout);
296@@ -290,6 +302,7 @@
297 " -n Don't sync to vblank\n"
298 " -m socket Mir server socket\n"
299 " -s WIDTHxHEIGHT Force surface size\n"
300+ " -c name Request cursor image by name\n"
301 " -q Quiet mode (no messages output)\n"
302 , argv[0]);
303 return 0;
304@@ -361,6 +374,10 @@
305 CHECK(mir_surface_is_valid(surface), "Can't create a surface");
306
307 mir_surface_set_event_handler(surface, &delegate);
308+
309+ MirCursorConfiguration *conf = mir_cursor_configuration_from_name(cursor_name);
310+ mir_surface_configure_cursor(surface, conf);
311+ mir_cursor_configuration_destroy(conf);
312
313 egldisplay = eglGetDisplay(
314 mir_connection_get_egl_native_display(connection));
315
316=== modified file 'include/client/mir_toolkit/mir_cursor_configuration.h'
317--- include/client/mir_toolkit/mir_cursor_configuration.h 2014-05-14 16:50:03 +0000
318+++ include/client/mir_toolkit/mir_cursor_configuration.h 2014-06-27 09:18:41 +0000
319@@ -18,6 +18,8 @@
320 #ifndef MIR_TOOLKIT_MIR_CURSOR_H_
321 #define MIR_TOOLKIT_MIR_CURSOR_H_
322
323+#include <mir_toolkit/common.h>
324+
325 /**
326 * Opaque structure containing cursor parameterization. Create with mir_cursor* family.
327 * Used with mir_surface_configure_cursor.
328@@ -33,17 +35,6 @@
329 #endif
330
331 /**
332- * A special cursor name for use with mir_cursor_configuration_from_name
333- * representing the system default cursor.
334- */
335-extern char const *const mir_default_cursor_name;
336-/**
337- * A special cursor name for use with mir_cursor_configuration_from_name
338- * representing a disabled cursor image.
339- */
340-extern char const *const mir_disabled_cursor_name;
341-
342-/**
343 * Release resources assosciated with cursor parameters
344 * \param [in] parameters The operand
345 */
346
347=== modified file 'include/client/mir_toolkit/mir_surface.h'
348--- include/client/mir_toolkit/mir_surface.h 2014-06-12 15:35:08 +0000
349+++ include/client/mir_toolkit/mir_surface.h 2014-06-27 09:18:41 +0000
350@@ -266,6 +266,13 @@
351 */
352 MirWaitHandle* mir_surface_configure_cursor(MirSurface *surface, MirCursorConfiguration const* parameters);
353
354+/**
355+ * Get the orientation of a surface.
356+ * \param [in] surface The surface to query
357+ * \return The orientation of the surface
358+ */
359+MirOrientation mir_surface_get_orientation(MirSurface *surface);
360+
361 #ifdef __cplusplus
362 }
363 /**@}*/
364
365=== modified file 'include/platform/mir/graphics/event_handler_register.h'
366--- include/platform/mir/graphics/event_handler_register.h 2013-08-28 03:41:48 +0000
367+++ include/platform/mir/graphics/event_handler_register.h 2014-06-27 09:18:41 +0000
368@@ -37,8 +37,11 @@
369
370 virtual void register_fd_handler(
371 std::initializer_list<int> fds,
372+ void const* owner,
373 std::function<void(int)> const& handler) = 0;
374
375+ virtual void unregister_fd_handler(void const* owner) = 0;
376+
377 protected:
378 EventHandlerRegister() = default;
379 virtual ~EventHandlerRegister() = default;
380
381=== modified file 'include/platform/mir/graphics/native_platform.h'
382--- include/platform/mir/graphics/native_platform.h 2014-03-06 06:05:17 +0000
383+++ include/platform/mir/graphics/native_platform.h 2014-06-27 09:18:41 +0000
384@@ -18,6 +18,7 @@
385 #ifndef MIR_GRAPHICS_NATIVE_PLATFORM_H_
386 #define MIR_GRAPHICS_NATIVE_PLATFORM_H_
387
388+#include "mir/graphics/platform.h"
389 #include <memory>
390 #include <functional>
391
392@@ -52,7 +53,10 @@
393
394 virtual std::shared_ptr<InternalClient> create_internal_client() = 0;
395
396- virtual void fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const = 0;
397+ virtual void fill_buffer_package(
398+ BufferIPCPacker* packer,
399+ Buffer const* buffer,
400+ BufferIpcMsgType msg_type) const = 0;
401
402 virtual ~NativePlatform() = default;
403 NativePlatform(NativePlatform const&) = delete;
404
405=== modified file 'include/platform/mir/graphics/platform.h'
406--- include/platform/mir/graphics/platform.h 2014-06-10 14:40:23 +0000
407+++ include/platform/mir/graphics/platform.h 2014-06-27 09:18:41 +0000
408@@ -54,6 +54,11 @@
409 class GLConfig;
410 class GLProgramFactory;
411
412+enum class BufferIpcMsgType
413+{
414+ full_msg, //pack the full ipc representation of the buffer
415+ update_msg //assume the client has a full representation, and pack only updates to the buffer
416+};
417 /**
418 * \defgroup platform_enablement Mir platform enablement
419 *
420@@ -98,15 +103,21 @@
421 virtual std::shared_ptr<PlatformIPCPackage> get_ipc_package() = 0;
422
423 /**
424- * Fills the IPC package for a buffer.
425+ * Arranges the IPC package for a buffer that is to be sent through
426+ * the frontend. This should be called every time a buffer is to be
427+ * sent cross-process.
428 *
429 * The Buffer IPC package will be sent to clients when receiving a buffer.
430 * The implementation must use the provided packer object to perform the packing.
431 *
432- * \param [in] packer the object providing the packing functionality
433- * \param [in] buffer the buffer to fill the IPC package for
434+ * \param [in] packer the object providing the packing functionality
435+ * \param [in] buffer the buffer to fill the IPC package for
436+ * \param [in] ipc_type what sort of ipc message is needed
437 */
438- virtual void fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const = 0;
439+ virtual void fill_buffer_package(
440+ BufferIPCPacker* packer,
441+ Buffer const* buffer,
442+ BufferIpcMsgType msg_type) const = 0;
443
444 /**
445 * Creates the in-process client support object.
446
447=== modified file 'include/server/mir/asio_main_loop.h'
448--- include/server/mir/asio_main_loop.h 2014-06-12 15:35:08 +0000
449+++ include/server/mir/asio_main_loop.h 2014-06-27 09:18:41 +0000
450@@ -22,8 +22,10 @@
451 #include "mir/main_loop.h"
452
453 #include <boost/asio.hpp>
454+#include <boost/optional.hpp>
455 #include <memory>
456 #include <vector>
457+#include <thread>
458 #include <mutex>
459 #include <utility>
460 #include <deque>
461@@ -52,7 +54,10 @@
462
463 void register_fd_handler(
464 std::initializer_list<int> fd,
465- std::function<void(int)> const& handler);
466+ void const* owner,
467+ std::function<void(int)> const& handler) override;
468+
469+ void unregister_fd_handler(void const* owner) override;
470
471 std::unique_ptr<time::Alarm> notify_in(std::chrono::milliseconds delay,
472 std::function<void()> callback) override;
473@@ -72,8 +77,10 @@
474
475 boost::asio::io_service io;
476 boost::asio::io_service::work work;
477+ boost::optional<std::thread::id> main_loop_thread;
478 std::vector<std::unique_ptr<SignalHandler>> signal_handlers;
479- std::vector<std::unique_ptr<FDHandler>> fd_handlers;
480+ std::vector<std::shared_ptr<FDHandler>> fd_handlers;
481+ std::mutex fd_handlers_mutex;
482 std::mutex server_actions_mutex;
483 std::deque<std::pair<void const*,ServerAction>> server_actions;
484 std::set<void const*> do_not_process;
485
486=== added file 'include/server/mir/compositor/compositor_id.h'
487--- include/server/mir/compositor/compositor_id.h 1970-01-01 00:00:00 +0000
488+++ include/server/mir/compositor/compositor_id.h 2014-06-27 09:18:41 +0000
489@@ -0,0 +1,32 @@
490+/*
491+ * Copyright © 2014 Canonical Ltd.
492+ *
493+ * This program is free software: you can redistribute it and/or modify it
494+ * under the terms of the GNU General Public License version 3,
495+ * as published by the Free Software Foundation.
496+ *
497+ * This program is distributed in the hope that it will be useful,
498+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
499+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
500+ * GNU General Public License for more details.
501+ *
502+ * You should have received a copy of the GNU General Public License
503+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
504+ *
505+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
506+ */
507+
508+#ifndef MIR_COMPOSITOR_COMPOSITOR_ID_H_
509+#define MIR_COMPOSITOR_COMPOSITOR_ID_H_
510+
511+namespace mir
512+{
513+namespace compositor
514+{
515+
516+using CompositorID = void const*;
517+
518+}
519+}
520+
521+#endif
522
523=== modified file 'include/server/mir/compositor/scene.h'
524--- include/server/mir/compositor/scene.h 2014-06-02 17:07:02 +0000
525+++ include/server/mir/compositor/scene.h 2014-06-27 09:18:41 +0000
526@@ -19,11 +19,10 @@
527 #ifndef MIR_COMPOSITOR_SCENE_H_
528 #define MIR_COMPOSITOR_SCENE_H_
529
530-#include "mir/geometry/forward.h"
531-#include "mir/graphics/renderable.h"
532+#include "compositor_id.h"
533
534 #include <memory>
535-#include <functional>
536+#include <vector>
537
538 namespace mir
539 {
540@@ -35,24 +34,29 @@
541 namespace compositor
542 {
543
544+class SceneElement;
545+using SceneElementSequence = std::vector<std::shared_ptr<SceneElement>>;
546+
547 class Scene
548 {
549 public:
550 virtual ~Scene() {}
551
552 /**
553- * Generate a valid list of renderables based on the current state of the Scene.
554+ * Generate a valid sequence of scene elements based on the current state of the Scene.
555 * \param [in] id An arbitrary unique identifier used to distinguish
556- * separate compositors which need to receive a list
557+ * separate compositors which need to receive a sequence
558 * for rendering. Calling with the same id will return
559- * a new (different) list to that user each time. For
560+ * a new (different) sequence to that user each time. For
561 * consistency, all callers need to determine their id
562 * in the same way (e.g. always use "this" pointer).
563- * \returns a list of mg::Renderables for the compositor id. The list is in
564- * stacking order from back to front.
565+ * \returns a sequence of mc::SceneElements for the compositor id. The
566+ * sequence is in stacking order from back to front.
567 */
568- typedef void const* CompositorID;
569- virtual graphics::RenderableList renderable_list_for(CompositorID id) const = 0;
570+ virtual SceneElementSequence scene_elements_for(CompositorID id) = 0;
571+
572+ virtual void register_compositor(CompositorID id) = 0;
573+ virtual void unregister_compositor(CompositorID id) = 0;
574
575 virtual void add_observer(std::shared_ptr<scene::Observer> const& observer) = 0;
576 virtual void remove_observer(std::weak_ptr<scene::Observer> const& observer) = 0;
577
578=== added file 'include/server/mir/compositor/scene_element.h'
579--- include/server/mir/compositor/scene_element.h 1970-01-01 00:00:00 +0000
580+++ include/server/mir/compositor/scene_element.h 2014-06-27 09:18:41 +0000
581@@ -0,0 +1,52 @@
582+/*
583+ * Copyright © 2014 Canonical Ltd.
584+ *
585+ * This program is free software: you can redistribute it and/or modify it
586+ * under the terms of the GNU General Public License version 3,
587+ * as published by the Free Software Foundation.
588+ *
589+ * This program is distributed in the hope that it will be useful,
590+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
591+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
592+ * GNU General Public License for more details.
593+ *
594+ * You should have received a copy of the GNU General Public License
595+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
596+ *
597+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
598+ */
599+
600+#ifndef MIR_COMPOSITOR_SCENE_ELEMENT_H_
601+#define MIR_COMPOSITOR_SCENE_ELEMENT_H_
602+
603+#include "compositor_id.h"
604+#include <memory>
605+
606+namespace mir
607+{
608+namespace graphics
609+{
610+class Renderable;
611+}
612+namespace compositor
613+{
614+
615+class SceneElement
616+{
617+public:
618+ virtual ~SceneElement() = default;
619+
620+ virtual std::shared_ptr<graphics::Renderable> renderable() const = 0;
621+ virtual void rendered_in(CompositorID cid) = 0;
622+ virtual void occluded_in(CompositorID cid) = 0;
623+
624+protected:
625+ SceneElement() = default;
626+ SceneElement(SceneElement const&) = delete;
627+ SceneElement& operator=(SceneElement const&) = delete;
628+};
629+
630+}
631+}
632+
633+#endif // MIR_COMPOSITOR_SCENE_ELEMENT_H_
634
635=== modified file 'include/server/mir/default_server_configuration.h'
636--- include/server/mir/default_server_configuration.h 2014-06-12 15:35:08 +0000
637+++ include/server/mir/default_server_configuration.h 2014-06-27 09:18:41 +0000
638@@ -120,6 +120,8 @@
639 class InputConfiguration;
640 class CursorListener;
641 class InputRegion;
642+class InputSender;
643+class InputSendObserver;
644 class NestedInputRelay;
645 class EventHandler;
646 namespace android
647@@ -164,6 +166,8 @@
648 virtual std::shared_ptr<graphics::Platform> the_graphics_platform();
649 virtual std::shared_ptr<input::InputConfiguration> the_input_configuration();
650 virtual std::shared_ptr<input::InputDispatcher> the_input_dispatcher();
651+ virtual std::shared_ptr<input::InputSender> the_input_sender();
652+ virtual std::shared_ptr<input::InputSendObserver> the_input_send_observer();
653 virtual std::shared_ptr<EmergencyCleanup> the_emergency_cleanup();
654 /** @} */
655
656@@ -321,6 +325,8 @@
657 CachedPtr<input::CompositeEventFilter> composite_event_filter;
658 CachedPtr<input::InputManager> input_manager;
659 CachedPtr<input::InputDispatcher> input_dispatcher;
660+ CachedPtr<input::InputSender> input_sender;
661+ CachedPtr<input::InputSendObserver> input_send_observer;
662 CachedPtr<input::InputRegion> input_region;
663 CachedPtr<shell::InputTargeter> input_targeter;
664 CachedPtr<input::CursorListener> cursor_listener;
665
666=== modified file 'include/server/mir/input/android/default_android_input_configuration.h'
667--- include/server/mir/input/android/default_android_input_configuration.h 2014-06-02 17:07:02 +0000
668+++ include/server/mir/input/android/default_android_input_configuration.h 2014-06-27 09:18:41 +0000
669@@ -56,7 +56,6 @@
670 std::shared_ptr<input::InputReport> const& input_report);
671 virtual ~DefaultInputConfiguration();
672
673- std::shared_ptr<input::InputChannelFactory> the_input_channel_factory() override;
674 std::shared_ptr<input::InputManager> the_input_manager() override;
675
676 protected:
677
678=== modified file 'include/server/mir/input/input_configuration.h'
679--- include/server/mir/input/input_configuration.h 2014-06-02 17:07:02 +0000
680+++ include/server/mir/input/input_configuration.h 2014-06-27 09:18:41 +0000
681@@ -26,14 +26,12 @@
682 namespace input
683 {
684 class InputManager;
685-class InputChannelFactory;
686
687 class InputConfiguration
688 {
689 public:
690 virtual ~InputConfiguration() = default;
691
692- virtual std::shared_ptr<InputChannelFactory> the_input_channel_factory() = 0;
693 virtual std::shared_ptr<InputManager> the_input_manager() = 0;
694
695 protected:
696
697=== added file 'include/server/mir/input/input_send_observer.h'
698--- include/server/mir/input/input_send_observer.h 1970-01-01 00:00:00 +0000
699+++ include/server/mir/input/input_send_observer.h 2014-06-27 09:18:41 +0000
700@@ -0,0 +1,76 @@
701+/*
702+ * Copyright © 2014 Canonical Ltd.
703+ *
704+ * This program is free software: you can redistribute it and/or modify it
705+ * under the terms of the GNU General Public License version 3,
706+ * as published by the Free Software Foundation.
707+ *
708+ * This program is distributed in the hope that it will be useful,
709+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
710+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
711+ * GNU General Public License for more details.
712+ *
713+ * You should have received a copy of the GNU General Public License
714+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
715+ *
716+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
717+ */
718+
719+#ifndef MIR_INPUT_INPUT_SEND_OBSERVER_H_
720+#define MIR_INPUT_INPUT_SEND_OBSERVER_H_
721+
722+#include <mir_toolkit/event.h>
723+
724+#include <memory>
725+
726+namespace mir
727+{
728+namespace input
729+{
730+class Surface;
731+
732+class InputSendObserver
733+{
734+public:
735+ InputSendObserver() = default;
736+ virtual ~InputSendObserver() = default;
737+
738+ enum FailureReason
739+ {
740+ surface_disappeared,
741+ no_response_received,
742+ socket_error
743+ };
744+ /*!
745+ * \brief An attempt to send an input event to a destination failed.
746+ *
747+ * Reasons for failure could be the surface disappearing from the scene, before the response
748+ * was received. Or the client not responding in time.
749+ */
750+ virtual void send_failed(MirEvent const& event, input::Surface* surface, FailureReason reason) = 0;
751+
752+ enum InputResponse
753+ {
754+ consumed,
755+ not_consumed
756+ };
757+ /*!
758+ * \brief Client responded to an input event.
759+ */
760+ virtual void send_suceeded(MirEvent const& event, input::Surface* surface, InputResponse response) = 0;
761+
762+ /*!
763+ * \brief Called when client is temporary blocked because input events are still in
764+ * the queue.
765+ */
766+ virtual void client_blocked(MirEvent const& event, input::Surface* client) = 0;
767+
768+protected:
769+ InputSendObserver& operator=(InputSendObserver const&) = delete;
770+ InputSendObserver(InputSendObserver const&) = delete;
771+};
772+
773+}
774+}
775+
776+#endif
777
778=== added file 'include/server/mir/input/input_sender.h'
779--- include/server/mir/input/input_sender.h 1970-01-01 00:00:00 +0000
780+++ include/server/mir/input/input_sender.h 2014-06-27 09:18:41 +0000
781@@ -0,0 +1,48 @@
782+/*
783+ * Copyright © 2014 Canonical Ltd.
784+ *
785+ * This program is free software: you can redistribute it and/or modify it
786+ * under the terms of the GNU General Public License version 3,
787+ * as published by the Free Software Foundation.
788+ *
789+ * This program is distributed in the hope that it will be useful,
790+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
791+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
792+ * GNU General Public License for more details.
793+ *
794+ * You should have received a copy of the GNU General Public License
795+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
796+ *
797+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
798+ */
799+
800+#ifndef MIR_INPUT_INPUT_SENDER_H_
801+#define MIR_INPUT_INPUT_SENDER_H_
802+
803+#include "mir_toolkit/event.h"
804+
805+#include <memory>
806+
807+namespace mir
808+{
809+namespace input
810+{
811+class InputSendObserver;
812+class Surface;
813+class InputChannel;
814+
815+class InputSender
816+{
817+public:
818+ InputSender() = default;
819+ virtual ~InputSender() = default;
820+ virtual void send_event(MirEvent const& event, std::shared_ptr<InputChannel> const& channel) = 0;
821+protected:
822+ InputSender& operator=(InputSender const&) = delete;
823+ InputSender(InputSender const&) = delete;
824+};
825+
826+}
827+}
828+
829+#endif
830
831=== modified file 'include/server/mir/input/input_targets.h'
832--- include/server/mir/input/input_targets.h 2014-04-24 08:42:12 +0000
833+++ include/server/mir/input/input_targets.h 2014-06-27 09:18:41 +0000
834@@ -26,6 +26,11 @@
835
836 namespace mir
837 {
838+namespace scene
839+{
840+class Observer;
841+}
842+
843 namespace input
844 {
845 class Surface;
846@@ -37,6 +42,9 @@
847
848 virtual void for_each(std::function<void(std::shared_ptr<input::Surface> const&)> const& callback) = 0;
849
850+ virtual void add_observer(std::shared_ptr<scene::Observer> const& observer) = 0;
851+ virtual void remove_observer(std::weak_ptr<scene::Observer> const& observer) = 0;
852+
853 protected:
854 InputTargets() = default;
855 InputTargets(InputTargets const&) = delete;
856
857=== modified file 'include/server/mir/input/surface.h'
858--- include/server/mir/input/surface.h 2014-06-03 11:04:15 +0000
859+++ include/server/mir/input/surface.h 2014-06-27 09:18:41 +0000
860@@ -23,11 +23,23 @@
861 #include "mir/geometry/rectangle.h"
862 #include "mir/input/input_reception_mode.h"
863
864+#include "mir_toolkit/event.h"
865+
866 #include <string>
867 #include <memory>
868
869 namespace mir
870 {
871+namespace graphics
872+{
873+class CursorImage;
874+}
875+
876+namespace scene
877+{
878+class SurfaceObserver;
879+}
880+
881 namespace input
882 {
883 class InputChannel;
884@@ -39,7 +51,9 @@
885 virtual geometry::Rectangle input_bounds() const = 0;
886 virtual bool input_area_contains(geometry::Point const& point) const = 0;
887 virtual std::shared_ptr<input::InputChannel> input_channel() const = 0;
888+ virtual std::shared_ptr<graphics::CursorImage> cursor_image() const = 0;
889 virtual InputReceptionMode reception_mode() const = 0;
890+ virtual void consume(MirEvent const& event) = 0;
891
892 protected:
893 Surface() = default;
894
895=== modified file 'include/server/mir/scene/null_surface_observer.h'
896--- include/server/mir/scene/null_surface_observer.h 2014-06-12 15:35:08 +0000
897+++ include/server/mir/scene/null_surface_observer.h 2014-06-27 09:18:41 +0000
898@@ -37,6 +37,7 @@
899 void hidden_set_to(bool hide);
900 void frame_posted(int frames_available);
901 void alpha_set_to(float alpha);
902+ void orientation_set_to(MirOrientation orientation) override;
903 void transformation_set_to(glm::mat4 const& t);
904 void cursor_image_set_to(graphics::CursorImage const& image);
905 void reception_mode_set_to(input::InputReceptionMode mode);
906
907=== modified file 'include/server/mir/scene/surface.h'
908--- include/server/mir/scene/surface.h 2014-06-05 14:38:50 +0000
909+++ include/server/mir/scene/surface.h 2014-06-27 09:18:41 +0000
910@@ -70,10 +70,11 @@
911 virtual void resize(geometry::Size const& size) = 0;
912 virtual void set_transformation(glm::mat4 const& t) = 0;
913 virtual void set_alpha(float alpha) = 0;
914+ virtual void set_orientation(MirOrientation orientation) = 0;
915 virtual void force_requests_to_complete() = 0;
916
917 virtual void set_cursor_image(std::shared_ptr<graphics::CursorImage> const& image) = 0;
918- virtual std::shared_ptr<graphics::CursorImage> cursor_image() = 0;
919+ virtual std::shared_ptr<graphics::CursorImage> cursor_image() const = 0;
920
921 virtual void add_observer(std::shared_ptr<SurfaceObserver> const& observer) = 0;
922 virtual void remove_observer(std::weak_ptr<SurfaceObserver> const& observer) = 0;
923
924=== modified file 'include/server/mir/scene/surface_event_source.h'
925--- include/server/mir/scene/surface_event_source.h 2014-06-02 17:07:02 +0000
926+++ include/server/mir/scene/surface_event_source.h 2014-06-27 09:18:41 +0000
927@@ -38,6 +38,7 @@
928
929 void attrib_changed(MirSurfaceAttrib attrib, int value) override;
930 void resized_to(geometry::Size const& size) override;
931+ void orientation_set_to(MirOrientation orientation) override;
932
933 private:
934 frontend::SurfaceId const id;
935
936=== modified file 'include/server/mir/scene/surface_observer.h'
937--- include/server/mir/scene/surface_observer.h 2014-06-12 15:35:08 +0000
938+++ include/server/mir/scene/surface_observer.h 2014-06-27 09:18:41 +0000
939@@ -48,6 +48,7 @@
940 virtual void hidden_set_to(bool hide) = 0;
941 virtual void frame_posted(int frames_available) = 0;
942 virtual void alpha_set_to(float alpha) = 0;
943+ virtual void orientation_set_to(MirOrientation orientation) = 0;
944 virtual void transformation_set_to(glm::mat4 const& t) = 0;
945 virtual void reception_mode_set_to(input::InputReceptionMode mode) = 0;
946 virtual void cursor_image_set_to(graphics::CursorImage const& image) = 0;
947
948=== modified file 'include/shared/mir/graphics/android/android_native_buffer.h'
949--- include/shared/mir/graphics/android/android_native_buffer.h 2013-10-11 22:03:04 +0000
950+++ include/shared/mir/graphics/android/android_native_buffer.h 2014-06-27 09:18:41 +0000
951@@ -33,18 +33,21 @@
952
953 struct AndroidNativeBuffer : public graphics::NativeBuffer
954 {
955- AndroidNativeBuffer(std::shared_ptr<ANativeWindowBuffer> const& handle,
956- std::shared_ptr<Fence> const& fence);
957+ AndroidNativeBuffer(
958+ std::shared_ptr<ANativeWindowBuffer> const& handle,
959+ std::shared_ptr<Fence> const& fence,
960+ BufferAccess fence_access);
961
962 ANativeWindowBuffer* anwb() const;
963 buffer_handle_t handle() const;
964 NativeFence copy_fence() const;
965
966- void wait_for_content();
967- void update_fence(NativeFence& merge_fd);
968+ void ensure_available_for(BufferAccess);
969+ void update_usage(NativeFence& merge_fd, BufferAccess);
970
971 private:
972 std::shared_ptr<Fence> fence;
973+ BufferAccess access;
974 std::shared_ptr<ANativeWindowBuffer> native_window_buffer;
975 };
976
977
978=== modified file 'include/shared/mir/graphics/android/native_buffer.h'
979--- include/shared/mir/graphics/android/native_buffer.h 2014-03-06 06:05:17 +0000
980+++ include/shared/mir/graphics/android/native_buffer.h 2014-06-27 09:18:41 +0000
981@@ -27,6 +27,15 @@
982 namespace graphics
983 {
984
985+namespace android
986+{
987+enum class BufferAccess
988+{
989+ read,
990+ write
991+};
992+}
993+
994 class NativeBuffer
995 {
996 public:
997@@ -36,8 +45,8 @@
998 virtual buffer_handle_t handle() const = 0;
999 virtual android::NativeFence copy_fence() const = 0;
1000
1001- virtual void wait_for_content() = 0;
1002- virtual void update_fence(android::NativeFence& fence) = 0;
1003+ virtual void ensure_available_for(android::BufferAccess intent) = 0;
1004+ virtual void update_usage(android::NativeFence& fence, android::BufferAccess current_usage) = 0;
1005
1006 protected:
1007 NativeBuffer() = default;
1008
1009=== modified file 'include/shared/mir_toolkit/common.h'
1010--- include/shared/mir_toolkit/common.h 2014-06-12 15:35:08 +0000
1011+++ include/shared/mir_toolkit/common.h 2014-06-27 09:18:41 +0000
1012@@ -1,7 +1,7 @@
1013 /*
1014 * Simple definitions common to client and server.
1015 *
1016- * Copyright © 2013 Canonical Ltd.
1017+ * Copyright © 2013-2014 Canonical Ltd.
1018 *
1019 * This program is free software: you can redistribute it and/or modify
1020 * it under the terms of the GNU Lesser General Public License version 3 as
1021@@ -38,6 +38,7 @@
1022 mir_surface_attrib_swapinterval,
1023 mir_surface_attrib_focus,
1024 mir_surface_attrib_dpi,
1025+ mir_surface_attrib_visibility,
1026 mir_surface_attribs
1027 } MirSurfaceAttrib;
1028
1029@@ -73,6 +74,12 @@
1030 mir_surface_focused
1031 } MirSurfaceFocusState;
1032
1033+typedef enum MirSurfaceVisibility
1034+{
1035+ mir_surface_visibility_occluded = 0,
1036+ mir_surface_visibility_exposed
1037+} MirSurfaceVisibility;
1038+
1039 typedef enum MirLifecycleState
1040 {
1041 mir_lifecycle_state_will_suspend,
1042@@ -117,6 +124,7 @@
1043 /* This could be improved... https://bugs.launchpad.net/mir/+bug/1236254 */
1044 #define MIR_BYTES_PER_PIXEL(f) (((f) == mir_pixel_format_bgr_888) ? 3 : 4)
1045
1046+/** Direction relative to the "natural" orientation of the display */
1047 typedef enum MirOrientation
1048 {
1049 mir_orientation_normal = 0,
1050@@ -125,6 +133,17 @@
1051 mir_orientation_right = 270
1052 } MirOrientation;
1053
1054+/**
1055+ * A special cursor name for use with mir_cursor_configuration_from_name
1056+ * representing the system default cursor.
1057+ */
1058+extern char const *const mir_default_cursor_name;
1059+/**
1060+ * A special cursor name for use with mir_cursor_configuration_from_name
1061+ * representing a disabled cursor image.
1062+ */
1063+extern char const *const mir_disabled_cursor_name;
1064+
1065 /**@}*/
1066
1067 #endif
1068
1069=== modified file 'include/shared/mir_toolkit/event.h'
1070--- include/shared/mir_toolkit/event.h 2014-06-11 16:11:32 +0000
1071+++ include/shared/mir_toolkit/event.h 2014-06-27 09:18:41 +0000
1072@@ -41,7 +41,8 @@
1073 mir_event_type_motion,
1074 mir_event_type_surface,
1075 mir_event_type_resize,
1076- mir_event_type_prompt_session_state_change
1077+ mir_event_type_prompt_session_state_change,
1078+ mir_event_type_orientation
1079 } MirEventType;
1080
1081 typedef enum {
1082@@ -212,6 +213,14 @@
1083 MirPromptSessionState new_state;
1084 } MirPromptSessionEvent;
1085
1086+typedef struct MirOrientationEvent
1087+{
1088+ MirEventType type;
1089+
1090+ int surface_id;
1091+ MirOrientation direction;
1092+} MirOrientationEvent;
1093+
1094 typedef union
1095 {
1096 MirEventType type;
1097@@ -220,6 +229,7 @@
1098 MirSurfaceEvent surface;
1099 MirResizeEvent resize;
1100 MirPromptSessionEvent prompt_session;
1101+ MirOrientationEvent orientation;
1102 } MirEvent;
1103
1104 #ifdef __cplusplus
1105
1106=== modified file 'include/test/mir_test/client_event_matchers.h'
1107--- include/test/mir_test/client_event_matchers.h 2014-06-02 17:07:02 +0000
1108+++ include/test/mir_test/client_event_matchers.h 2014-06-27 09:18:41 +0000
1109@@ -201,6 +201,19 @@
1110 return true;
1111 }
1112
1113+MATCHER_P2(TouchEvent, x, y, "")
1114+{
1115+ if (to_ref(arg).type != mir_event_type_motion)
1116+ return false;
1117+ if (to_ref(arg).motion.action != mir_motion_action_down)
1118+ return false;
1119+ if (to_ref(arg).motion.pointer_coordinates[0].x != x)
1120+ return false;
1121+ if (to_ref(arg).motion.pointer_coordinates[0].y != y)
1122+ return false;
1123+ return true;
1124+}
1125+
1126 MATCHER_P2(MotionEventWithPosition, x, y, "")
1127 {
1128 if (to_ref(arg).type != mir_event_type_motion)
1129
1130=== modified file 'include/test/mir_test/event_factory.h'
1131--- include/test/mir_test/event_factory.h 2013-04-24 23:59:52 +0000
1132+++ include/test/mir_test/event_factory.h 2014-06-27 09:18:41 +0000
1133@@ -75,6 +75,19 @@
1134 };
1135 MotionParameters a_motion_event();
1136
1137+class TouchParameters
1138+{
1139+public:
1140+ TouchParameters();
1141+ TouchParameters& from_device(int device_id);
1142+ TouchParameters& at_position(int abs_x, int abs_y);
1143+
1144+ int device_id;
1145+ int abs_x;
1146+ int abs_y;
1147+};
1148+TouchParameters a_touch_event();
1149+
1150 }
1151 }
1152 }
1153
1154=== modified file 'include/test/mir_test/fake_event_hub.h'
1155--- include/test/mir_test/fake_event_hub.h 2014-06-02 17:07:02 +0000
1156+++ include/test/mir_test/fake_event_hub.h 2014-06-27 09:18:41 +0000
1157@@ -75,6 +75,10 @@
1158 // special meaning) will do. There is no notion of a builtin
1159 // cursor device in the android input stack.
1160 static const int BuiltInCursorID = droidinput::BUILT_IN_KEYBOARD_ID + 1;
1161+ static const int USBTouchscreenID;
1162+
1163+ static const int TouchScreenMinAxisValue;
1164+ static const int TouchScreenMaxAxisValue;
1165
1166 // From EventHubInterface
1167 uint32_t getDeviceClasses(int32_t deviceId) const override;
1168@@ -114,11 +118,13 @@
1169
1170 void synthesize_builtin_keyboard_added();
1171 void synthesize_builtin_cursor_added();
1172+ void synthesize_usb_touchscreen_added();
1173 void synthesize_device_scan_complete();
1174
1175- void synthesize_event(const synthesis::KeyParameters &parameters);
1176- void synthesize_event(const synthesis::ButtonParameters &parameters);
1177- void synthesize_event(const synthesis::MotionParameters &parameters);
1178+ void synthesize_event(synthesis::KeyParameters const& parameters);
1179+ void synthesize_event(synthesis::ButtonParameters const& parameters);
1180+ void synthesize_event(synthesis::MotionParameters const& parameters);
1181+ void synthesize_event(synthesis::TouchParameters const& parameters);
1182 void synthesize_event(nsecs_t when, int32_t deviceId, int32_t type, int32_t code, int32_t value);
1183
1184 void addDevice(int32_t deviceId, const std::string& name, uint32_t classes);
1185
1186=== modified file 'include/test/mir_test_doubles/mock_android_native_buffer.h'
1187--- include/test/mir_test_doubles/mock_android_native_buffer.h 2014-03-11 13:44:57 +0000
1188+++ include/test/mir_test_doubles/mock_android_native_buffer.h 2014-06-27 09:18:41 +0000
1189@@ -54,8 +54,8 @@
1190 MOCK_CONST_METHOD0(handle, buffer_handle_t());
1191 MOCK_CONST_METHOD0(copy_fence, graphics::android::NativeFence());
1192
1193- MOCK_METHOD0(wait_for_content, void());
1194- MOCK_METHOD1(update_fence, void(graphics::android::NativeFence&));
1195+ MOCK_METHOD1(ensure_available_for, void(graphics::android::BufferAccess));
1196+ MOCK_METHOD2(update_usage, void(graphics::android::NativeFence&, graphics::android::BufferAccess));
1197
1198 ANativeWindowBuffer stub_anwb;
1199 native_handle_t native_handle;
1200
1201=== added file 'include/test/mir_test_doubles/mock_input_send_observer.h'
1202--- include/test/mir_test_doubles/mock_input_send_observer.h 1970-01-01 00:00:00 +0000
1203+++ include/test/mir_test_doubles/mock_input_send_observer.h 2014-06-27 09:18:41 +0000
1204@@ -0,0 +1,44 @@
1205+/*
1206+ * Copyright © 2014 Canonical Ltd.
1207+ *
1208+ * This program is free software: you can redistribute it and/or modify it
1209+ * under the terms of the GNU General Public License version 3,
1210+ * as published by the Free Software Foundation.
1211+ *
1212+ * This program is distributed in the hope that it will be useful,
1213+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1214+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1215+ * GNU General Public License for more details.
1216+ *
1217+ * You should have received a copy of the GNU General Public License
1218+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1219+ *
1220+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
1221+ */
1222+
1223+#ifndef MIR_TEST_DOUBLES_MOCK_INPUT_SEND_OBSERVER_H_
1224+#define MIR_TEST_DOUBLES_MOCK_INPUT_SEND_OBSERVER_H_
1225+
1226+#include "mir/input/input_send_observer.h"
1227+#include <gmock/gmock.h>
1228+
1229+namespace mir
1230+{
1231+namespace test
1232+{
1233+namespace doubles
1234+{
1235+
1236+struct MockInputSendObserver : public mir::input::InputSendObserver
1237+{
1238+ MockInputSendObserver() = default;
1239+ MOCK_METHOD3(send_failed, void(MirEvent const&, mir::input::Surface*, FailureReason));
1240+ MOCK_METHOD3(send_suceeded, void(MirEvent const&, mir::input::Surface*, InputResponse));
1241+ MOCK_METHOD2(client_blocked, void(MirEvent const&, mir::input::Surface*));
1242+};
1243+
1244+}
1245+}
1246+}
1247+
1248+#endif
1249
1250=== added file 'include/test/mir_test_doubles/mock_input_sender.h'
1251--- include/test/mir_test_doubles/mock_input_sender.h 1970-01-01 00:00:00 +0000
1252+++ include/test/mir_test_doubles/mock_input_sender.h 2014-06-27 09:18:41 +0000
1253@@ -0,0 +1,42 @@
1254+/*
1255+ * Copyright © 2014 Canonical Ltd.
1256+ *
1257+ * This program is free software: you can redistribute it and/or modify it
1258+ * under the terms of the GNU General Public License version 3,
1259+ * as published by the Free Software Foundation.
1260+ *
1261+ * This program is distributed in the hope that it will be useful,
1262+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1263+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1264+ * GNU General Public License for more details.
1265+ *
1266+ * You should have received a copy of the GNU General Public License
1267+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1268+ *
1269+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
1270+ */
1271+
1272+#ifndef MIR_TEST_DOUBLES_MOCK_INPUT_SENDER_H_
1273+#define MIR_TEST_DOUBLES_MOCK_INPUT_SENDER_H_
1274+
1275+#include "mir/input/input_sender.h"
1276+#include <gmock/gmock.h>
1277+
1278+namespace mir
1279+{
1280+namespace test
1281+{
1282+namespace doubles
1283+{
1284+
1285+struct MockInputSender : mir::input::InputSender
1286+{
1287+ MOCK_METHOD1(set_send_observer, void(mir::input::InputSendObserver *));
1288+ MOCK_METHOD2(send_event, void(MirEvent const& ev, std::shared_ptr<mir::input::InputChannel> const& channel));
1289+};
1290+
1291+}
1292+}
1293+}
1294+
1295+#endif
1296
1297=== modified file 'include/test/mir_test_doubles/mock_input_surface.h'
1298--- include/test/mir_test_doubles/mock_input_surface.h 2014-06-03 11:04:15 +0000
1299+++ include/test/mir_test_doubles/mock_input_surface.h 2014-06-27 09:18:41 +0000
1300@@ -32,26 +32,14 @@
1301 class MockInputSurface : public input::Surface
1302 {
1303 public:
1304- MockInputSurface()
1305- {
1306- using namespace ::testing;
1307- ON_CALL(*this, input_bounds())
1308- .WillByDefault(Return(geometry::Rectangle()));
1309- static std::string n;
1310- ON_CALL(*this, name())
1311- .WillByDefault(Return(n));
1312- static std::shared_ptr<input::InputChannel> c{nullptr};
1313- ON_CALL(*this, input_channel())
1314- .WillByDefault(Return(c));
1315- ON_CALL(*this, reception_mode())
1316- .WillByDefault(Return(input::InputReceptionMode::normal));
1317- }
1318 ~MockInputSurface() noexcept {}
1319 MOCK_CONST_METHOD0(name, std::string());
1320 MOCK_CONST_METHOD0(input_bounds, geometry::Rectangle());
1321 MOCK_CONST_METHOD1(input_area_contains, bool(geometry::Point const&));
1322 MOCK_CONST_METHOD0(input_channel, std::shared_ptr<input::InputChannel>());
1323+ MOCK_CONST_METHOD0(cursor_image, std::shared_ptr<graphics::CursorImage>());
1324 MOCK_CONST_METHOD0(reception_mode, input::InputReceptionMode());
1325+ MOCK_METHOD1(consume, void(MirEvent const&));
1326 };
1327
1328 }
1329
1330=== added file 'include/test/mir_test_doubles/mock_main_loop.h'
1331--- include/test/mir_test_doubles/mock_main_loop.h 1970-01-01 00:00:00 +0000
1332+++ include/test/mir_test_doubles/mock_main_loop.h 2014-06-27 09:18:41 +0000
1333@@ -0,0 +1,66 @@
1334+/*
1335+ * Copyright © 2014 Canonical Ltd.
1336+ *
1337+ * This program is free software: you can redistribute it and/or modify
1338+ * it under the terms of the GNU General Public License version 3 as
1339+ * published by the Free Software Foundation.
1340+ *
1341+ * This program is distributed in the hope that it will be useful,
1342+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1343+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1344+ * GNU General Public License for more details.
1345+ *
1346+ * You should have received a copy of the GNU General Public License
1347+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1348+ *
1349+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
1350+ */
1351+
1352+#ifndef MIR_TEST_DOUBLES_MOCK_MAIN_LOOP_H_
1353+#define MIR_TEST_DOUBLES_MOCK_MAIN_LOOP_H_
1354+
1355+#include "mir/main_loop.h"
1356+#include "mir_test/gmock_fixes.h"
1357+
1358+#include <gmock/gmock.h>
1359+
1360+namespace mir
1361+{
1362+namespace test
1363+{
1364+namespace doubles
1365+{
1366+class MockMainLoop : public MainLoop
1367+{
1368+public:
1369+ ~MockMainLoop() noexcept {}
1370+
1371+ void run() override {}
1372+ void stop() override {}
1373+
1374+ MOCK_METHOD2(register_signal_handler,
1375+ void(std::initializer_list<int>,
1376+ std::function<void(int)> const&));
1377+
1378+ MOCK_METHOD3(register_fd_handler,
1379+ void(std::initializer_list<int>, void const*,
1380+ std::function<void(int)> const&));
1381+
1382+ MOCK_METHOD1(unregister_fd_handler, void(void const*));
1383+
1384+ MOCK_METHOD2(enqueue, void(void const*, ServerAction const&));
1385+ MOCK_METHOD1(pause_processing_for,void (void const*));
1386+ MOCK_METHOD1(resume_processing_for,void (void const*));
1387+
1388+ MOCK_METHOD2(notify_in, std::unique_ptr<time::Alarm>(std::chrono::milliseconds delay,
1389+ std::function<void(void)> callback));
1390+ MOCK_METHOD2(notify_at, std::unique_ptr<time::Alarm>(time::Timestamp time_point,
1391+ std::function<void(void)> callback));
1392+ MOCK_METHOD1(create_alarm, std::unique_ptr<time::Alarm>(std::function<void ()> callback));
1393+};
1394+
1395+}
1396+}
1397+}
1398+
1399+#endif
1400
1401=== modified file 'include/test/mir_test_doubles/mock_scene.h'
1402--- include/test/mir_test_doubles/mock_scene.h 2014-06-03 11:04:15 +0000
1403+++ include/test/mir_test_doubles/mock_scene.h 2014-06-27 09:18:41 +0000
1404@@ -34,11 +34,13 @@
1405 public:
1406 MockScene()
1407 {
1408- ON_CALL(*this, renderable_list_for(testing::_))
1409- .WillByDefault(testing::Return(graphics::RenderableList{}));
1410+ ON_CALL(*this, scene_elements_for(testing::_))
1411+ .WillByDefault(testing::Return(compositor::SceneElementSequence{}));
1412 }
1413
1414- MOCK_CONST_METHOD1(renderable_list_for, graphics::RenderableList(void const*));
1415+ MOCK_METHOD1(scene_elements_for, compositor::SceneElementSequence(compositor::CompositorID));
1416+ MOCK_METHOD1(register_compositor, void(compositor::CompositorID));
1417+ MOCK_METHOD1(unregister_compositor, void(compositor::CompositorID));
1418
1419 MOCK_METHOD1(add_observer, void(std::shared_ptr<scene::Observer> const&));
1420 MOCK_METHOD1(remove_observer, void(std::weak_ptr<scene::Observer> const&));
1421
1422=== modified file 'include/test/mir_test_doubles/mock_surface.h'
1423--- include/test/mir_test_doubles/mock_surface.h 2014-06-03 16:43:38 +0000
1424+++ include/test/mir_test_doubles/mock_surface.h 2014-06-27 09:18:41 +0000
1425@@ -42,6 +42,7 @@
1426 {},
1427 {},
1428 {},
1429+ {},
1430 mir::report::null_scene_report())
1431 {
1432 }
1433
1434=== modified file 'include/test/mir_test_doubles/null_platform.h'
1435--- include/test/mir_test_doubles/null_platform.h 2014-06-02 17:07:02 +0000
1436+++ include/test/mir_test_doubles/null_platform.h 2014-06-27 09:18:41 +0000
1437@@ -56,7 +56,8 @@
1438 return std::shared_ptr<graphics::InternalClient>();
1439 }
1440
1441- void fill_ipc_package(graphics::BufferIPCPacker*, graphics::Buffer const*) const
1442+ void fill_buffer_package(
1443+ graphics::BufferIPCPacker*, graphics::Buffer const*, graphics::BufferIpcMsgType) const
1444 {
1445 }
1446
1447
1448=== modified file 'include/test/mir_test_doubles/stub_buffer.h'
1449--- include/test/mir_test_doubles/stub_buffer.h 2014-06-06 22:52:52 +0000
1450+++ include/test/mir_test_doubles/stub_buffer.h 2014-06-27 09:18:41 +0000
1451@@ -22,8 +22,7 @@
1452 #ifdef ANDROID
1453 #include "mock_android_native_buffer.h"
1454 #else
1455-#include "src/platform/graphics/mesa/gbm_buffer.h"
1456-#include "mock_gbm.h"
1457+#include "stub_gbm_native_buffer.h"
1458 #endif
1459
1460 #include "mir/graphics/buffer_basic.h"
1461@@ -43,33 +42,46 @@
1462 public:
1463 StubBuffer()
1464 : StubBuffer{
1465+ create_native_buffer(),
1466 graphics::BufferProperties{
1467 geometry::Size{},
1468 mir_pixel_format_abgr_8888,
1469- graphics::BufferUsage::hardware}}
1470-
1471+ graphics::BufferUsage::hardware},
1472+ geometry::Stride{}}
1473+
1474+ {
1475+ }
1476+
1477+ StubBuffer(std::shared_ptr<graphics::NativeBuffer> const& native_buffer, geometry::Size const& size)
1478+ : StubBuffer{
1479+ native_buffer,
1480+ graphics::BufferProperties{
1481+ size,
1482+ mir_pixel_format_abgr_8888,
1483+ graphics::BufferUsage::hardware},
1484+ geometry::Stride{}}
1485+
1486+ {
1487+ }
1488+
1489+ StubBuffer(std::shared_ptr<graphics::NativeBuffer> const& native_buffer)
1490+ : StubBuffer{native_buffer, {}}
1491 {
1492 }
1493
1494 StubBuffer(graphics::BufferProperties const& properties)
1495- : StubBuffer{properties, geometry::Stride{}}
1496+ : StubBuffer{create_native_buffer(), properties, geometry::Stride{}}
1497 {
1498 }
1499
1500- StubBuffer(graphics::BufferProperties const& properties,
1501+ StubBuffer(std::shared_ptr<graphics::NativeBuffer> const& native_buffer,
1502+ graphics::BufferProperties const& properties,
1503 geometry::Stride stride)
1504- : buf_size{properties.size},
1505+ : native_buffer(native_buffer),
1506+ buf_size{properties.size},
1507 buf_pixel_format{properties.format},
1508 buf_stride{stride}
1509 {
1510-#ifndef ANDROID
1511- auto buffer = std::make_shared<graphics::mesa::GBMNativeBuffer>();
1512- int fake_bo{0};
1513- buffer->bo = reinterpret_cast<gbm_bo*>(&fake_bo); //gbm_bo is opaque, so test code shouldn't dereference.
1514- native_buffer = buffer;
1515-#else
1516- native_buffer = std::make_shared<StubAndroidNativeBuffer>();
1517-#endif
1518 }
1519
1520 virtual geometry::Size size() const { return buf_size; }
1521@@ -83,10 +95,19 @@
1522
1523 virtual bool can_bypass() const override { return true; }
1524
1525- std::shared_ptr<graphics::NativeBuffer> native_buffer;
1526+ std::shared_ptr<graphics::NativeBuffer> const native_buffer;
1527 geometry::Size const buf_size;
1528 MirPixelFormat const buf_pixel_format;
1529 geometry::Stride const buf_stride;
1530+
1531+ std::shared_ptr<graphics::NativeBuffer> create_native_buffer()
1532+ {
1533+#ifndef ANDROID
1534+ return std::make_shared<StubGBMNativeBuffer>(geometry::Size{0,0});
1535+#else
1536+ return std::make_shared<StubAndroidNativeBuffer>();
1537+#endif
1538+ }
1539 };
1540 }
1541 }
1542
1543=== added file 'include/test/mir_test_doubles/stub_display.h'
1544--- include/test/mir_test_doubles/stub_display.h 1970-01-01 00:00:00 +0000
1545+++ include/test/mir_test_doubles/stub_display.h 2014-06-27 09:18:41 +0000
1546@@ -0,0 +1,69 @@
1547+/*
1548+ * Copyright © 2014 Canonical Ltd.
1549+ *
1550+ * This program is free software: you can redistribute it and/or modify
1551+ * it under the terms of the GNU General Public License version 3 as
1552+ * published by the Free Software Foundation.
1553+ *
1554+ * This program is distributed in the hope that it will be useful,
1555+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1556+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1557+ * GNU General Public License for more details.
1558+ *
1559+ * You should have received a copy of the GNU General Public License
1560+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1561+ *
1562+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
1563+ */
1564+
1565+#ifndef MIR_TEST_DOUBLES_STUB_DISPLAY_H_
1566+#define MIR_TEST_DOUBLES_STUB_DISPLAY_H_
1567+
1568+#include "null_display.h"
1569+#include "stub_display_buffer.h"
1570+#include "stub_display_configuration.h"
1571+
1572+#include "mir/geometry/rectangle.h"
1573+
1574+#include <vector>
1575+
1576+namespace mir
1577+{
1578+namespace test
1579+{
1580+namespace doubles
1581+{
1582+
1583+class StubDisplay : public NullDisplay
1584+{
1585+public:
1586+ StubDisplay(std::vector<geometry::Rectangle> const& output_rects)
1587+ : output_rects{output_rects}
1588+ {
1589+ for (auto const& output_rect : output_rects)
1590+ display_buffers.emplace_back(output_rect);
1591+ }
1592+
1593+ void for_each_display_buffer(std::function<void(graphics::DisplayBuffer&)> const& f) override
1594+ {
1595+ for (auto& db : display_buffers)
1596+ f(db);
1597+ }
1598+
1599+ std::unique_ptr<graphics::DisplayConfiguration> configuration() const override
1600+ {
1601+ return std::unique_ptr<graphics::DisplayConfiguration>(
1602+ new StubDisplayConfig(output_rects)
1603+ );
1604+ }
1605+
1606+private:
1607+ std::vector<geometry::Rectangle> const output_rects;
1608+ std::vector<StubDisplayBuffer> display_buffers;
1609+};
1610+
1611+}
1612+}
1613+}
1614+
1615+#endif
1616
1617=== added file 'include/test/mir_test_doubles/stub_gbm_native_buffer.h'
1618--- include/test/mir_test_doubles/stub_gbm_native_buffer.h 1970-01-01 00:00:00 +0000
1619+++ include/test/mir_test_doubles/stub_gbm_native_buffer.h 2014-06-27 09:18:41 +0000
1620@@ -0,0 +1,55 @@
1621+/*
1622+ * Copyright © 2014 Canonical Ltd.
1623+ *
1624+ * This program is free software: you can redistribute it and/or modify it
1625+ * under the terms of the GNU General Public License version 3,
1626+ * as published by the Free Software Foundation.
1627+ *
1628+ * This program is distributed in the hope that it will be useful,
1629+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1630+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1631+ * GNU General Public License for more details.
1632+ *
1633+ * You should have received a copy of the GNU General Public License
1634+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1635+ *
1636+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1637+ */
1638+
1639+#ifndef MIR_TEST_DOUBLES_STUB_GBM_NATIVE_BUFFER_H_
1640+#define MIR_TEST_DOUBLES_STUB_GBM_NATIVE_BUFFER_H_
1641+
1642+#include "src/platform/graphics/mesa/gbm_buffer.h"
1643+#include "mir/geometry/size.h"
1644+
1645+namespace mir
1646+{
1647+namespace test
1648+{
1649+namespace doubles
1650+{
1651+
1652+struct StubGBMNativeBuffer : public graphics::mesa::GBMNativeBuffer
1653+{
1654+ StubGBMNativeBuffer(geometry::Size const& size)
1655+ {
1656+ data_items = 4;
1657+ fd_items = 2;
1658+ width = size.width.as_int();
1659+ height = size.height.as_int();
1660+ flags = 0x66;
1661+ stride = 4390;
1662+ bo = reinterpret_cast<gbm_bo*>(&fake_bo); //gbm_bo is opaque, so test code shouldn't dereference.
1663+ for(auto i = 0; i < data_items; i++)
1664+ data[i] = i;
1665+ for(auto i = 0; i < fd_items; i++)
1666+ fd[i] = i;
1667+ }
1668+ int fake_bo{0};
1669+};
1670+
1671+}
1672+}
1673+}
1674+
1675+#endif /* MIR_TEST_DOUBLES_STUB_GBM_NATIVE_BUFFER_H_ */
1676
1677=== added file 'include/test/mir_test_doubles/stub_input_sender.h'
1678--- include/test/mir_test_doubles/stub_input_sender.h 1970-01-01 00:00:00 +0000
1679+++ include/test/mir_test_doubles/stub_input_sender.h 2014-06-27 09:18:41 +0000
1680@@ -0,0 +1,42 @@
1681+/*
1682+ * Copyright © 2014 Canonical Ltd.
1683+ *
1684+ * This program is free software: you can redistribute it and/or modify it
1685+ * under the terms of the GNU General Public License version 3,
1686+ * as published by the Free Software Foundation.
1687+ *
1688+ * This program is distributed in the hope that it will be useful,
1689+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1690+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1691+ * GNU General Public License for more details.
1692+ *
1693+ * You should have received a copy of the GNU General Public License
1694+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1695+ *
1696+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
1697+ */
1698+
1699+#ifndef MIR_TEST_DOUBLES_STUB_INPUT_SENDER_H_
1700+#define MIR_TEST_DOUBLES_STUB_INPUT_SENDER_H_
1701+
1702+#include "mir/input/input_sender.h"
1703+
1704+namespace mir
1705+{
1706+namespace test
1707+{
1708+namespace doubles
1709+{
1710+
1711+struct StubInputSender : mir::input::InputSender
1712+{
1713+ void send_event(MirEvent const& /*event*/, std::shared_ptr<mir::input::InputChannel> const& /*channel*/) override
1714+ {
1715+ }
1716+};
1717+
1718+}
1719+}
1720+}
1721+
1722+#endif
1723
1724=== modified file 'include/test/mir_test_doubles/stub_input_surface.h'
1725--- include/test/mir_test_doubles/stub_input_surface.h 2014-05-14 16:50:03 +0000
1726+++ include/test/mir_test_doubles/stub_input_surface.h 2014-06-27 09:18:41 +0000
1727@@ -47,9 +47,12 @@
1728 }
1729
1730 mir::input::InputReceptionMode reception_mode() const { return mir::input::InputReceptionMode::normal; }
1731+ void consume(MirEvent const&) override {}
1732 std::string name() const { return {}; }
1733 mir::geometry::Rectangle input_bounds() const override { return {{},{}}; }
1734 bool input_area_contains(mir::geometry::Point const&) const { return false; }
1735+
1736+ std::shared_ptr<graphics::CursorImage> cursor_image() const { return nullptr; }
1737
1738 std::shared_ptr<mir::input::InputChannel> const channel;
1739 };
1740
1741=== modified file 'include/test/mir_test_doubles/stub_input_targets.h'
1742--- include/test/mir_test_doubles/stub_input_targets.h 2014-04-01 22:48:55 +0000
1743+++ include/test/mir_test_doubles/stub_input_targets.h 2014-06-27 09:18:41 +0000
1744@@ -33,6 +33,12 @@
1745 void for_each(std::function<void(std::shared_ptr<input::Surface> const&)> const& ) override
1746 {
1747 }
1748+ void add_observer(std::shared_ptr<scene::Observer> const& /* observer */)
1749+ {
1750+ }
1751+ void remove_observer(std::weak_ptr<scene::Observer> const& /* observer */)
1752+ {
1753+ }
1754 };
1755
1756 }
1757
1758=== modified file 'include/test/mir_test_doubles/stub_renderable.h'
1759--- include/test/mir_test_doubles/stub_renderable.h 2014-06-13 23:30:22 +0000
1760+++ include/test/mir_test_doubles/stub_renderable.h 2014-06-27 09:18:41 +0000
1761@@ -43,6 +43,10 @@
1762 stub_buffer(buffer)
1763 {}
1764
1765+ StubRenderable(std::shared_ptr<graphics::Buffer> const& buffer)
1766+ : StubRenderable(buffer, {{},{}})
1767+ {}
1768+
1769 StubRenderable(geometry::Rectangle const& rect)
1770 : StubRenderable(make_stub_buffer(rect), rect)
1771 {}
1772@@ -130,6 +134,18 @@
1773 }
1774 };
1775
1776+struct PlaneAlphaRenderable : public StubRenderable
1777+{
1778+ bool alpha_enabled() const override
1779+ {
1780+ return true;
1781+ }
1782+ float alpha() const override
1783+ {
1784+ //approx 99% alpha
1785+ return 1.0f - ( 3.0f / 1024.0f );
1786+ }
1787+};
1788 }
1789 }
1790 }
1791
1792=== modified file 'include/test/mir_test_doubles/stub_scene.h'
1793--- include/test/mir_test_doubles/stub_scene.h 2014-05-14 16:50:03 +0000
1794+++ include/test/mir_test_doubles/stub_scene.h 2014-06-27 09:18:41 +0000
1795@@ -32,10 +32,16 @@
1796 class StubScene : public compositor::Scene
1797 {
1798 public:
1799- graphics::RenderableList renderable_list_for(void const*) const override
1800+ compositor::SceneElementSequence scene_elements_for(compositor::CompositorID) override
1801 {
1802 return {};
1803 }
1804+ void register_compositor(compositor::CompositorID) override
1805+ {
1806+ }
1807+ void unregister_compositor(compositor::CompositorID) override
1808+ {
1809+ }
1810 void add_observer(std::shared_ptr<scene::Observer> const&) override
1811 {
1812 }
1813
1814=== added file 'include/test/mir_test_doubles/stub_scene_element.h'
1815--- include/test/mir_test_doubles/stub_scene_element.h 1970-01-01 00:00:00 +0000
1816+++ include/test/mir_test_doubles/stub_scene_element.h 2014-06-27 09:18:41 +0000
1817@@ -0,0 +1,60 @@
1818+/*
1819+ * Copyright © 2014 Canonical Ltd.
1820+ *
1821+ * This program is free software: you can redistribute it and/or modify it
1822+ * under the terms of the GNU General Public License version 3,
1823+ * as published by the Free Software Foundation.
1824+ *
1825+ * This program is distributed in the hope that it will be useful,
1826+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1827+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1828+ * GNU General Public License for more details.
1829+ *
1830+ * You should have received a copy of the GNU General Public License
1831+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1832+ *
1833+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
1834+ */
1835+
1836+#ifndef MIR_TEST_DOUBLES_STUB_SCENE_ELEMENT_H_
1837+#define MIR_TEST_DOUBLES_STUB_SCENE_ELEMENT_H_
1838+
1839+#include "mir/compositor/scene_element.h"
1840+
1841+namespace mir
1842+{
1843+namespace test
1844+{
1845+namespace doubles
1846+{
1847+
1848+class StubSceneElement : public compositor::SceneElement
1849+{
1850+public:
1851+ StubSceneElement(std::shared_ptr<graphics::Renderable> const& renderable)
1852+ : renderable_{renderable}
1853+ {
1854+ }
1855+
1856+ std::shared_ptr<graphics::Renderable> renderable() const
1857+ {
1858+ return renderable_;
1859+ }
1860+
1861+ void rendered_in(compositor::CompositorID) override
1862+ {
1863+ }
1864+
1865+ void occluded_in(compositor::CompositorID) override
1866+ {
1867+ }
1868+
1869+private:
1870+ std::shared_ptr<graphics::Renderable> const renderable_;
1871+};
1872+
1873+}
1874+}
1875+}
1876+
1877+#endif
1878
1879=== modified file 'include/test/mir_test_doubles/stub_scene_surface.h'
1880--- include/test/mir_test_doubles/stub_scene_surface.h 2014-06-05 14:38:50 +0000
1881+++ include/test/mir_test_doubles/stub_scene_surface.h 2014-06-27 09:18:41 +0000
1882@@ -77,15 +77,17 @@
1883 void resize(geometry::Size const&) override {}
1884 void set_transformation(glm::mat4 const&) override {}
1885 void set_alpha(float) override {}
1886+ void set_orientation(MirOrientation) {}
1887 void force_requests_to_complete() override {}
1888
1889 void add_observer(std::shared_ptr<scene::SurfaceObserver> const&) override {}
1890 void remove_observer(std::weak_ptr<scene::SurfaceObserver> const&) override {}
1891
1892 void set_reception_mode(input::InputReceptionMode mode) override { input_mode = mode; }
1893+ void consume(MirEvent const&) override {}
1894
1895 void set_cursor_image(std::shared_ptr<graphics::CursorImage> const& /* image */) {}
1896- std::shared_ptr<graphics::CursorImage> cursor_image() { return {}; }
1897+ std::shared_ptr<graphics::CursorImage> cursor_image() const { return {}; }
1898
1899 MirPixelFormat pixel_format() const override { return mir_pixel_format_xrgb_8888; }
1900
1901
1902=== modified file 'include/test/mir_test_doubles/stub_swapping_gl_context.h'
1903--- include/test/mir_test_doubles/stub_swapping_gl_context.h 2014-06-05 18:23:02 +0000
1904+++ include/test/mir_test_doubles/stub_swapping_gl_context.h 2014-06-27 09:18:41 +0000
1905@@ -31,11 +31,22 @@
1906
1907 struct StubSwappingGLContext : public graphics::android::SwappingGLContext
1908 {
1909+ StubSwappingGLContext(std::shared_ptr<graphics::Buffer> const& buffer) :
1910+ buffer(buffer)
1911+ {
1912+ }
1913+
1914+ StubSwappingGLContext() :
1915+ StubSwappingGLContext(std::make_shared<StubBuffer>())
1916+ {
1917+ }
1918 void swap_buffers() const {}
1919 std::shared_ptr<graphics::Buffer> last_rendered_buffer() const
1920 {
1921- return std::make_shared<StubBuffer>();
1922+ return buffer;
1923 }
1924+private:
1925+ std::shared_ptr<graphics::Buffer> const buffer;
1926 };
1927
1928 }
1929
1930=== modified file 'include/test/mir_test_doubles/stub_timer.h'
1931--- include/test/mir_test_doubles/stub_timer.h 2014-04-24 15:07:28 +0000
1932+++ include/test/mir_test_doubles/stub_timer.h 2014-06-27 09:18:41 +0000
1933@@ -37,7 +37,7 @@
1934 }
1935 State state() const override
1936 {
1937- return Cancelled;
1938+ return cancelled;
1939 }
1940 bool reschedule_in(std::chrono::milliseconds) override
1941 {
1942
1943=== added file 'include/test/mir_test_framework/deferred_in_process_server.h'
1944--- include/test/mir_test_framework/deferred_in_process_server.h 1970-01-01 00:00:00 +0000
1945+++ include/test/mir_test_framework/deferred_in_process_server.h 2014-06-27 09:18:41 +0000
1946@@ -0,0 +1,41 @@
1947+/*
1948+ * Copyright © 2014 Canonical Ltd.
1949+ *
1950+ * This program is free software: you can redistribute it and/or modify it
1951+ * under the terms of the GNU General Public License version 3,
1952+ * as published by the Free Software Foundation.
1953+ *
1954+ * This program is distributed in the hope that it will be useful,
1955+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1956+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1957+ * GNU General Public License for more details.
1958+ *
1959+ * You should have received a copy of the GNU General Public License
1960+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1961+ *
1962+ * Authored By: Alan Griffiths <alan@octopull.co.uk>
1963+ */
1964+
1965+#ifndef MIR_TEST_FRAMEWORK_DEFERRED_IN_PROCESS_SERVER_H_
1966+#define MIR_TEST_FRAMEWORK_DEFERRED_IN_PROCESS_SERVER_H_
1967+
1968+#include "mir_test_framework/server_runner.h"
1969+
1970+#include <gtest/gtest.h>
1971+
1972+namespace mir_test_framework
1973+{
1974+/** Fixture for running Mir server in test process.
1975+ * The server startup is deferred until start_server() is called, to allows the
1976+ * test code to initialize the server environment with expectations or stubs.
1977+ */
1978+struct DeferredInProcessServer : testing::Test, private ServerRunner
1979+{
1980+ void TearDown() override { ServerRunner::stop_server(); }
1981+
1982+ using ServerRunner::start_server;
1983+ using ServerRunner::new_connection;
1984+};
1985+}
1986+
1987+#endif /* MIR_TEST_FRAMEWORK_DEFERRED_IN_PROCESS_SERVER_H_ */
1988
1989=== modified file 'include/test/mir_test_framework/in_process_server.h'
1990--- include/test/mir_test_framework/in_process_server.h 2014-06-10 12:28:03 +0000
1991+++ include/test/mir_test_framework/in_process_server.h 2014-06-27 09:18:41 +0000
1992@@ -23,16 +23,6 @@
1993
1994 #include <gtest/gtest.h>
1995
1996-#include <string>
1997-#include <thread>
1998-
1999-namespace mir
2000-{
2001-class DisplayServer;
2002-class DefaultServerConfiguration;
2003-}
2004-
2005-
2006 namespace mir_test_framework
2007 {
2008 /// Fixture for running Mir server in test process
2009
2010=== modified file 'include/test/mir_test_framework/input_testing_server_configuration.h'
2011--- include/test/mir_test_framework/input_testing_server_configuration.h 2014-06-02 17:07:02 +0000
2012+++ include/test/mir_test_framework/input_testing_server_configuration.h 2014-06-27 09:18:41 +0000
2013@@ -56,6 +56,7 @@
2014 {
2015 public:
2016 InputTestingServerConfiguration();
2017+ explicit InputTestingServerConfiguration(std::vector<geometry::Rectangle> const& display_rects);
2018
2019 void exec();
2020 void on_exit();
2021@@ -63,6 +64,7 @@
2022 std::shared_ptr<mir::input::InputConfiguration> the_input_configuration() override;
2023 std::shared_ptr<mir::input::InputDispatcher> the_input_dispatcher() override;
2024 std::shared_ptr<mir::shell::InputTargeter> the_input_targeter() override;
2025+ std::shared_ptr<mir::input::InputSender> the_input_sender() override;
2026
2027 mir::input::android::FakeEventHub* fake_event_hub;
2028
2029
2030=== modified file 'include/test/mir_test_framework/stubbed_server_configuration.h'
2031--- include/test/mir_test_framework/stubbed_server_configuration.h 2014-06-02 17:07:02 +0000
2032+++ include/test/mir_test_framework/stubbed_server_configuration.h 2014-06-27 09:18:41 +0000
2033@@ -20,6 +20,9 @@
2034 #define MIR_TEST_FRAMEWORK_STUBBED_SERVER_CONFIGURATION_H_
2035
2036 #include "mir/default_server_configuration.h"
2037+#include "mir/geometry/rectangle.h"
2038+
2039+#include <vector>
2040
2041 namespace mir_test_framework
2042 {
2043@@ -33,6 +36,7 @@
2044 {
2045 public:
2046 StubbedServerConfiguration();
2047+ explicit StubbedServerConfiguration(std::vector<geometry::Rectangle> const& display_rects);
2048
2049 std::shared_ptr<graphics::Platform> the_graphics_platform() override;
2050 std::shared_ptr<compositor::RendererFactory> the_renderer_factory() override;
2051@@ -42,9 +46,13 @@
2052 std::shared_ptr<input::InputConfiguration> the_input_configuration() override;
2053 std::shared_ptr<input::InputDispatcher> the_input_dispatcher() override;
2054 std::shared_ptr<shell::InputTargeter> the_input_targeter() override;
2055+ std::shared_ptr<input::InputSender> the_input_sender() override;
2056+
2057+ std::shared_ptr<graphics::Cursor> the_cursor() override;
2058
2059 private:
2060 std::shared_ptr<graphics::Platform> graphics_platform;
2061+ std::vector<geometry::Rectangle> const display_rects;
2062 };
2063 }
2064
2065
2066=== modified file 'include/test/mir_test_framework/testing_server_configuration.h'
2067--- include/test/mir_test_framework/testing_server_configuration.h 2014-03-06 06:05:17 +0000
2068+++ include/test/mir_test_framework/testing_server_configuration.h 2014-06-27 09:18:41 +0000
2069@@ -31,6 +31,7 @@
2070 {
2071 public:
2072 TestingServerConfiguration();
2073+ explicit TestingServerConfiguration(std::vector<geometry::Rectangle> const& display_rects);
2074
2075 // Code to run in server process
2076 virtual void exec();
2077
2078=== modified file 'src/client/android/android_client_buffer.cpp'
2079--- src/client/android/android_client_buffer.cpp 2014-03-06 06:05:17 +0000
2080+++ src/client/android/android_client_buffer.cpp 2014-06-27 09:18:41 +0000
2081@@ -52,7 +52,7 @@
2082 anwb->usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER;
2083 anwb->handle = native_handle.get();
2084
2085- native_window_buffer = std::make_shared<mga::AndroidNativeBuffer>(anwb, fence);
2086+ native_window_buffer = std::make_shared<mga::AndroidNativeBuffer>(anwb, fence, mga::BufferAccess::read);
2087 }
2088
2089 mcla::AndroidClientBuffer::~AndroidClientBuffer() noexcept
2090
2091=== modified file 'src/client/cursor_configuration.h'
2092--- src/client/cursor_configuration.h 2014-05-14 16:50:03 +0000
2093+++ src/client/cursor_configuration.h 2014-06-27 09:18:41 +0000
2094@@ -25,6 +25,8 @@
2095 // Will grow to include cursors specified by raw RGBA data, hotspots, etc...
2096 struct MirCursorConfiguration
2097 {
2098+ MirCursorConfiguration(char const* name);
2099+
2100 std::string name;
2101 };
2102
2103
2104=== modified file 'src/client/mir_cursor_api.cpp'
2105--- src/client/mir_cursor_api.cpp 2014-05-14 16:50:03 +0000
2106+++ src/client/mir_cursor_api.cpp 2014-06-27 09:18:41 +0000
2107@@ -19,9 +19,15 @@
2108 #include "mir_toolkit/mir_cursor_configuration.h"
2109 #include "cursor_configuration.h"
2110
2111+#include <memory>
2112+
2113 char const *const mir_default_cursor_name = "default";
2114-char const *const mir_disabled_cursor_name = nullptr;
2115+char const *const mir_disabled_cursor_name = "disabled";
2116
2117+MirCursorConfiguration::MirCursorConfiguration(char const* name) :
2118+ name{name ? name : std::string()}
2119+{
2120+}
2121
2122 void mir_cursor_configuration_destroy(MirCursorConfiguration *cursor)
2123 {
2124@@ -32,10 +38,7 @@
2125 {
2126 try
2127 {
2128- auto c = new MirCursorConfiguration;
2129- c->name = std::string(name);
2130-
2131- return c;
2132+ return new MirCursorConfiguration(name);
2133 }
2134 catch (...)
2135 {
2136
2137=== modified file 'src/client/mir_surface.cpp'
2138--- src/client/mir_surface.cpp 2014-06-16 21:41:08 +0000
2139+++ src/client/mir_surface.cpp 2014-06-27 09:18:41 +0000
2140@@ -326,7 +326,7 @@
2141 {
2142 std::unique_lock<decltype(mutex)> lock(mutex);
2143 setting.mutable_surfaceid()->CopyFrom(surface.id());
2144- if (cursor->name != "")
2145+ if (cursor && cursor->name != mir_disabled_cursor_name)
2146 setting.set_name(cursor->name.c_str());
2147 }
2148
2149@@ -427,12 +427,22 @@
2150 {
2151 std::unique_lock<decltype(mutex)> lock(mutex);
2152
2153- if (e.type == mir_event_type_surface)
2154+ switch (e.type)
2155+ {
2156+ case mir_event_type_surface:
2157 {
2158 MirSurfaceAttrib a = e.surface.attrib;
2159 if (a < mir_surface_attribs)
2160 attrib_cache[a] = e.surface.value;
2161+ break;
2162 }
2163+ case mir_event_type_orientation:
2164+ orientation = e.orientation.direction;
2165+ break;
2166+
2167+ default:
2168+ break;
2169+ };
2170
2171 if (handle_event_callback)
2172 {
2173@@ -459,3 +469,8 @@
2174 {
2175 configure(a, value)->wait_for_all();
2176 }
2177+
2178+MirOrientation MirSurface::get_orientation() const
2179+{
2180+ return orientation;
2181+}
2182
2183=== modified file 'src/client/mir_surface.h'
2184--- src/client/mir_surface.h 2014-06-05 14:38:50 +0000
2185+++ src/client/mir_surface.h 2014-06-27 09:18:41 +0000
2186@@ -87,6 +87,7 @@
2187
2188 MirWaitHandle* configure(MirSurfaceAttrib a, int value);
2189 int attrib(MirSurfaceAttrib a) const;
2190+ MirOrientation get_orientation() const;
2191
2192 MirWaitHandle* configure_cursor(MirCursorConfiguration const* cursor);
2193
2194@@ -131,6 +132,7 @@
2195
2196 // Cache of latest SurfaceSettings returned from the server
2197 int attrib_cache[mir_surface_attribs];
2198+ MirOrientation orientation = mir_orientation_normal;
2199
2200 std::function<void(MirEvent const*)> handle_event_callback;
2201 std::shared_ptr<mir::input::receiver::InputReceiverThread> input_thread;
2202
2203=== modified file 'src/client/mir_surface_api.cpp'
2204--- src/client/mir_surface_api.cpp 2014-06-12 15:35:08 +0000
2205+++ src/client/mir_surface_api.cpp 2014-06-27 09:18:41 +0000
2206@@ -225,6 +225,11 @@
2207 return state;
2208 }
2209
2210+MirOrientation mir_surface_get_orientation(MirSurface *surface)
2211+{
2212+ return surface->get_orientation();
2213+}
2214+
2215 MirWaitHandle* mir_surface_set_swapinterval(MirSurface* surf, int interval)
2216 {
2217 if ((interval < 0) || (interval > 1))
2218
2219=== modified file 'src/client/rpc/mir_socket_rpc_channel.cpp'
2220--- src/client/rpc/mir_socket_rpc_channel.cpp 2014-06-12 15:35:08 +0000
2221+++ src/client/rpc/mir_socket_rpc_channel.cpp 2014-06-27 09:18:41 +0000
2222@@ -418,24 +418,25 @@
2223
2224 rpc_report->event_parsing_succeeded(e);
2225
2226- event_sink->handle_event(e);
2227-
2228- // todo - surfaces should register with the event handler register.
2229- if (e.type == mir_event_type_surface)
2230- {
2231- surface_map->with_surface_do(e.surface.id,
2232- [&e](MirSurface* surface)
2233- {
2234- surface->handle_event(e);
2235- });
2236- }
2237- else if (e.type == mir_event_type_resize)
2238- {
2239- surface_map->with_surface_do(e.resize.surface_id,
2240- [&e](MirSurface* surface)
2241- {
2242- surface->handle_event(e);
2243- });
2244+ auto const send_e = [&e](MirSurface* surface)
2245+ { surface->handle_event(e); };
2246+
2247+ switch (e.type)
2248+ {
2249+ case mir_event_type_surface:
2250+ surface_map->with_surface_do(e.surface.id, send_e);
2251+ break;
2252+
2253+ case mir_event_type_resize:
2254+ surface_map->with_surface_do(e.resize.surface_id, send_e);
2255+ break;
2256+
2257+ case mir_event_type_orientation:
2258+ surface_map->with_surface_do(e.orientation.surface_id, send_e);
2259+ break;
2260+
2261+ default:
2262+ event_sink->handle_event(e);
2263 }
2264 }
2265 else
2266
2267=== modified file 'src/platform/graphics/android/android_alloc_adaptor.cpp'
2268--- src/platform/graphics/android/android_alloc_adaptor.cpp 2014-03-06 06:05:17 +0000
2269+++ src/platform/graphics/android/android_alloc_adaptor.cpp 2014-06-27 09:18:41 +0000
2270@@ -88,7 +88,7 @@
2271 anwb->format = format;
2272 anwb->usage = usage_flag;
2273
2274- return std::make_shared<mga::AndroidNativeBuffer>(anwb, fence);
2275+ return std::make_shared<mga::AndroidNativeBuffer>(anwb, fence, mga::BufferAccess::read);
2276 }
2277
2278 int mga::AndroidAllocAdaptor::convert_to_android_usage(BufferUsage usage)
2279
2280=== modified file 'src/platform/graphics/android/android_platform.cpp'
2281--- src/platform/graphics/android/android_platform.cpp 2014-06-10 14:40:23 +0000
2282+++ src/platform/graphics/android/android_platform.cpp 2014-06-27 09:18:41 +0000
2283@@ -112,24 +112,31 @@
2284 return std::make_shared<mg::PlatformIPCPackage>();
2285 }
2286
2287-void mga::AndroidPlatform::fill_ipc_package(BufferIPCPacker* packer, graphics::Buffer const* buffer) const
2288+void mga::AndroidPlatform::fill_buffer_package(
2289+ BufferIPCPacker* packer, graphics::Buffer const* buffer, BufferIpcMsgType msg_type) const
2290 {
2291 auto native_buffer = buffer->native_buffer_handle();
2292- auto buffer_handle = native_buffer->handle();
2293-
2294- int offset = 0;
2295-
2296- for(auto i=0; i<buffer_handle->numFds; i++)
2297- {
2298- packer->pack_fd(buffer_handle->data[offset++]);
2299- }
2300- for(auto i=0; i<buffer_handle->numInts; i++)
2301- {
2302- packer->pack_data(buffer_handle->data[offset++]);
2303- }
2304-
2305- packer->pack_stride(buffer->stride());
2306- packer->pack_size(buffer->size());
2307+
2308+ /* TODO: instead of waiting, pack the fence fd in the message to the client */
2309+ native_buffer->ensure_available_for(mga::BufferAccess::write);
2310+ if (msg_type == mg::BufferIpcMsgType::full_msg)
2311+ {
2312+ auto buffer_handle = native_buffer->handle();
2313+
2314+ int offset = 0;
2315+
2316+ for(auto i=0; i<buffer_handle->numFds; i++)
2317+ {
2318+ packer->pack_fd(buffer_handle->data[offset++]);
2319+ }
2320+ for(auto i=0; i<buffer_handle->numInts; i++)
2321+ {
2322+ packer->pack_data(buffer_handle->data[offset++]);
2323+ }
2324+
2325+ packer->pack_stride(buffer->stride());
2326+ packer->pack_size(buffer->size());
2327+ }
2328 }
2329
2330 EGLNativeDisplayType mga::AndroidPlatform::egl_native_display() const
2331
2332=== modified file 'src/platform/graphics/android/android_platform.h'
2333--- src/platform/graphics/android/android_platform.h 2014-06-02 17:07:02 +0000
2334+++ src/platform/graphics/android/android_platform.h 2014-06-27 09:18:41 +0000
2335@@ -49,7 +49,8 @@
2336 std::shared_ptr<graphics::GLConfig> const& /*gl_config*/);
2337 std::shared_ptr<PlatformIPCPackage> get_ipc_package();
2338 std::shared_ptr<InternalClient> create_internal_client();
2339- void fill_ipc_package(BufferIPCPacker* packer, graphics::Buffer const* buffer) const;
2340+ void fill_buffer_package(
2341+ BufferIPCPacker* packer, graphics::Buffer const* buffer, BufferIpcMsgType msg_type) const;
2342 EGLNativeDisplayType egl_native_display() const;
2343
2344 private:
2345
2346=== modified file 'src/platform/graphics/android/buffer.cpp'
2347--- src/platform/graphics/android/buffer.cpp 2014-05-01 08:11:50 +0000
2348+++ src/platform/graphics/android/buffer.cpp 2014-06-27 09:18:41 +0000
2349@@ -76,7 +76,7 @@
2350 void mga::Buffer::gl_bind_to_texture()
2351 {
2352 std::unique_lock<std::mutex> lk(content_lock);
2353- native_buffer->wait_for_content();
2354+ native_buffer->ensure_available_for(mga::BufferAccess::read);
2355
2356 DispContextPair current
2357 {
2358
2359=== modified file 'src/platform/graphics/android/fb_device.cpp'
2360--- src/platform/graphics/android/fb_device.cpp 2014-06-16 14:47:14 +0000
2361+++ src/platform/graphics/android/fb_device.cpp 2014-06-27 09:18:41 +0000
2362@@ -49,7 +49,7 @@
2363 context.swap_buffers();
2364 auto const& buffer = context.last_rendered_buffer();
2365 auto native_buffer = buffer->native_buffer_handle();
2366- native_buffer->wait_for_content();
2367+ native_buffer->ensure_available_for(mga::BufferAccess::read);
2368 if (fb_device->post(fb_device.get(), native_buffer->handle()) != 0)
2369 {
2370 BOOST_THROW_EXCEPTION(std::runtime_error("error posting with fb device"));
2371
2372=== modified file 'src/platform/graphics/android/hwc_device.cpp'
2373--- src/platform/graphics/android/hwc_device.cpp 2014-06-16 14:47:14 +0000
2374+++ src/platform/graphics/android/hwc_device.cpp 2014-06-27 09:18:41 +0000
2375@@ -25,6 +25,7 @@
2376 #include "framebuffer_bundle.h"
2377 #include "buffer.h"
2378 #include "hwc_fallback_gl_renderer.h"
2379+#include <limits>
2380
2381 namespace mg = mir::graphics;
2382 namespace mga=mir::graphics::android;
2383@@ -34,6 +35,16 @@
2384 {
2385 static const size_t fbtarget_plus_skip_size = 2;
2386 static const size_t fbtarget_size = 1;
2387+
2388+bool plane_alpha_is_translucent(mg::Renderable const& renderable)
2389+{
2390+ float static const tolerance
2391+ {
2392+ 1.0f/(2.0 * static_cast<float>(std::numeric_limits<decltype(hwc_layer_1_t::planeAlpha)>::max()))
2393+ };
2394+ return renderable.alpha_enabled() && (renderable.alpha() < 1.0f - tolerance);
2395+}
2396+
2397 bool renderable_list_is_hwc_incompatible(mg::RenderableList const& list)
2398 {
2399 if (list.empty())
2400@@ -41,11 +52,10 @@
2401
2402 for(auto const& renderable : list)
2403 {
2404- //TODO: enable alpha, 90 deg rotation
2405+ //TODO: enable planeAlpha for (hwc version >= 1.2), 90 deg rotation
2406 static glm::mat4 const identity;
2407- if (renderable->shaped() ||
2408- renderable->alpha_enabled() ||
2409- (renderable->transformation() != identity))
2410+ if (plane_alpha_is_translucent(*renderable) ||
2411+ (renderable->transformation() != identity))
2412 {
2413 return true;
2414 }
2415
2416=== modified file 'src/platform/graphics/android/hwc_fallback_gl_renderer.cpp'
2417--- src/platform/graphics/android/hwc_fallback_gl_renderer.cpp 2014-06-09 16:01:59 +0000
2418+++ src/platform/graphics/android/hwc_fallback_gl_renderer.cpp 2014-06-27 09:18:41 +0000
2419@@ -105,12 +105,17 @@
2420
2421 glClearColor(0.0, 0.0, 0.0, 1.0);
2422 glClear(GL_COLOR_BUFFER_BIT);
2423-
2424+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2425 glEnableVertexAttribArray(position_attr);
2426 glEnableVertexAttribArray(texcoord_attr);
2427
2428 for(auto const& renderable : renderlist)
2429 {
2430+ if (renderable->alpha_enabled())
2431+ glEnable(GL_BLEND);
2432+ else
2433+ glDisable(GL_BLEND);
2434+
2435 auto const primitive = mg::tessellate_renderable_into_rectangle(*renderable);
2436 glVertexAttribPointer(position_attr, 3, GL_FLOAT, GL_FALSE, sizeof(mg::GLVertex),
2437 &primitive.vertices[0].position);
2438
2439=== modified file 'src/platform/graphics/android/hwc_fb_device.cpp'
2440--- src/platform/graphics/android/hwc_fb_device.cpp 2014-06-16 14:47:14 +0000
2441+++ src/platform/graphics/android/hwc_fb_device.cpp 2014-06-27 09:18:41 +0000
2442@@ -70,7 +70,7 @@
2443
2444 auto const& buffer = context.last_rendered_buffer();
2445 auto native_buffer = buffer->native_buffer_handle();
2446- native_buffer->wait_for_content();
2447+ native_buffer->ensure_available_for(mga::BufferAccess::read);
2448 if (fb_device->post(fb_device.get(), native_buffer->handle()) != 0)
2449 {
2450 BOOST_THROW_EXCEPTION(std::runtime_error("error posting with fb device"));
2451
2452=== modified file 'src/platform/graphics/android/hwc_layers.cpp'
2453--- src/platform/graphics/android/hwc_layers.cpp 2014-06-04 22:41:05 +0000
2454+++ src/platform/graphics/android/hwc_layers.cpp 2014-06-27 09:18:41 +0000
2455@@ -22,6 +22,7 @@
2456 #include "mir/graphics/android/native_buffer.h"
2457 #include "hwc_layerlist.h"
2458
2459+#include <limits>
2460 #include <boost/throw_exception.hpp>
2461 #include <stdexcept>
2462 #include <cstring>
2463@@ -30,6 +31,13 @@
2464 namespace mga=mir::graphics::android;
2465 namespace geom=mir::geometry;
2466
2467+namespace
2468+{
2469+decltype(hwc_layer_1_t::planeAlpha) static const plane_alpha_max{
2470+ std::numeric_limits<decltype(hwc_layer_1_t::planeAlpha)>::max()
2471+};
2472+}
2473+
2474 mga::HWCLayer& mga::HWCLayer::operator=(HWCLayer && other)
2475 {
2476 hwc_layer = other.hwc_layer;
2477@@ -58,6 +66,7 @@
2478 hwc_layer->acquireFenceFd = -1;
2479 hwc_layer->releaseFenceFd = -1;
2480 hwc_layer->blending = HWC_BLENDING_NONE;
2481+ hwc_layer->planeAlpha = plane_alpha_max;
2482
2483 hwc_layer->visibleRegionScreen.numRects=1;
2484 hwc_layer->visibleRegionScreen.rects= &visible_rect;
2485@@ -84,7 +93,7 @@
2486 {
2487 if (hwc_layer->compositionType != HWC_FRAMEBUFFER)
2488 {
2489- associated_buffer->update_fence(hwc_layer->releaseFenceFd);
2490+ associated_buffer->update_usage(hwc_layer->releaseFenceFd, mga::BufferAccess::read);
2491 hwc_layer->releaseFenceFd = -1;
2492 hwc_layer->acquireFenceFd = -1;
2493 associated_buffer.reset();
2494@@ -118,10 +127,12 @@
2495 void mga::HWCLayer::set_render_parameters(geometry::Rectangle position, bool alpha_enabled)
2496 {
2497 if (alpha_enabled)
2498- hwc_layer->blending = HWC_BLENDING_COVERAGE;
2499+ hwc_layer->blending = HWC_BLENDING_PREMULT;
2500 else
2501 hwc_layer->blending = HWC_BLENDING_NONE;
2502
2503+ hwc_layer->planeAlpha = plane_alpha_max;
2504+
2505 /* note, if the sourceCrop and DisplayFrame sizes differ, the output will be linearly scaled */
2506 hwc_layer->displayFrame =
2507 {
2508
2509=== modified file 'src/platform/graphics/android/internal_client_window.cpp'
2510--- src/platform/graphics/android/internal_client_window.cpp 2014-04-15 05:31:19 +0000
2511+++ src/platform/graphics/android/internal_client_window.cpp 2014-06-27 09:18:41 +0000
2512@@ -65,7 +65,7 @@
2513 buffer = it->second.buffer;
2514 lookup.erase(it);
2515
2516- handle->update_fence(fence_fd);
2517+ handle->update_usage(fence_fd, mga::BufferAccess::write);
2518 surface->swap_buffers(buffer);
2519 }
2520
2521
2522=== modified file 'src/platform/graphics/android/interpreter_cache.cpp'
2523--- src/platform/graphics/android/interpreter_cache.cpp 2014-03-06 06:05:17 +0000
2524+++ src/platform/graphics/android/interpreter_cache.cpp 2014-06-27 09:18:41 +0000
2525@@ -58,5 +58,5 @@
2526 }
2527
2528 auto native_buffer = native_it->second;
2529- native_buffer->update_fence(fence);
2530+ native_buffer->update_usage(fence, mga::BufferAccess::write);
2531 }
2532
2533=== modified file 'src/platform/graphics/mesa/display.cpp'
2534--- src/platform/graphics/mesa/display.cpp 2014-06-10 14:40:23 +0000
2535+++ src/platform/graphics/mesa/display.cpp 2014-06-27 09:18:41 +0000
2536@@ -233,6 +233,7 @@
2537 {
2538 handlers.register_fd_handler(
2539 {monitor.fd()},
2540+ this,
2541 [conf_change_handler, this](int)
2542 {
2543 monitor.process_events([conf_change_handler]
2544
2545=== modified file 'src/platform/graphics/mesa/native_platform.cpp'
2546--- src/platform/graphics/mesa/native_platform.cpp 2014-06-02 17:07:02 +0000
2547+++ src/platform/graphics/mesa/native_platform.cpp 2014-06-27 09:18:41 +0000
2548@@ -97,21 +97,26 @@
2549 return std::make_shared<mgm::InternalClient>(nd);
2550 }
2551
2552-void mgm::NativePlatform::fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const
2553+/* TODO : this is just a duplication of mgm::Platform::fill_buffer_package */
2554+void mgm::NativePlatform::fill_buffer_package(
2555+ BufferIPCPacker* packer, Buffer const* buffer, BufferIpcMsgType msg_type) const
2556 {
2557- auto native_handle = buffer->native_buffer_handle();
2558- for(auto i=0; i<native_handle->data_items; i++)
2559- {
2560- packer->pack_data(native_handle->data[i]);
2561- }
2562- for(auto i=0; i<native_handle->fd_items; i++)
2563- {
2564- packer->pack_fd(native_handle->fd[i]);
2565- }
2566+ if (msg_type == mg::BufferIpcMsgType::full_msg)
2567+ {
2568+ auto native_handle = buffer->native_buffer_handle();
2569+ for(auto i=0; i<native_handle->data_items; i++)
2570+ {
2571+ packer->pack_data(native_handle->data[i]);
2572+ }
2573+ for(auto i=0; i<native_handle->fd_items; i++)
2574+ {
2575+ packer->pack_fd(native_handle->fd[i]);
2576+ }
2577
2578- packer->pack_stride(buffer->stride());
2579- packer->pack_flags(native_handle->flags);
2580- packer->pack_size(buffer->size());
2581+ packer->pack_stride(buffer->stride());
2582+ packer->pack_flags(native_handle->flags);
2583+ packer->pack_size(buffer->size());
2584+ }
2585 }
2586
2587 extern "C" std::shared_ptr<mg::NativePlatform> create_native_platform(std::shared_ptr<mg::DisplayReport> const& /*report*/)
2588
2589=== modified file 'src/platform/graphics/mesa/native_platform.h'
2590--- src/platform/graphics/mesa/native_platform.h 2014-03-12 02:46:58 +0000
2591+++ src/platform/graphics/mesa/native_platform.h 2014-06-27 09:18:41 +0000
2592@@ -42,7 +42,8 @@
2593 std::shared_ptr<BufferInitializer> const& buffer_initializer) override;
2594 std::shared_ptr<PlatformIPCPackage> get_ipc_package() override;
2595 std::shared_ptr<InternalClient> create_internal_client() override;
2596- void fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const override;
2597+ void fill_buffer_package(
2598+ BufferIPCPacker* packer, Buffer const* buffer, BufferIpcMsgType msg_type) const override;
2599
2600 static std::shared_ptr<InternalNativeDisplay> internal_native_display();
2601 static bool internal_native_display_in_use();
2602
2603=== modified file 'src/platform/graphics/mesa/platform.cpp'
2604--- src/platform/graphics/mesa/platform.cpp 2014-06-10 14:40:23 +0000
2605+++ src/platform/graphics/mesa/platform.cpp 2014-06-27 09:18:41 +0000
2606@@ -182,21 +182,25 @@
2607 return std::make_shared<MesaPlatformIPCPackage>(drm->get_authenticated_fd());
2608 }
2609
2610-void mgm::Platform::fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const
2611+void mgm::Platform::fill_buffer_package(
2612+ BufferIPCPacker* packer, Buffer const* buffer, BufferIpcMsgType msg_type) const
2613 {
2614- auto native_handle = buffer->native_buffer_handle();
2615- for(auto i=0; i<native_handle->data_items; i++)
2616- {
2617- packer->pack_data(native_handle->data[i]);
2618- }
2619- for(auto i=0; i<native_handle->fd_items; i++)
2620- {
2621- packer->pack_fd(native_handle->fd[i]);
2622- }
2623+ if (msg_type == mg::BufferIpcMsgType::full_msg)
2624+ {
2625+ auto native_handle = buffer->native_buffer_handle();
2626+ for(auto i=0; i<native_handle->data_items; i++)
2627+ {
2628+ packer->pack_data(native_handle->data[i]);
2629+ }
2630+ for(auto i=0; i<native_handle->fd_items; i++)
2631+ {
2632+ packer->pack_fd(native_handle->fd[i]);
2633+ }
2634
2635- packer->pack_stride(buffer->stride());
2636- packer->pack_flags(native_handle->flags);
2637- packer->pack_size(buffer->size());
2638+ packer->pack_stride(buffer->stride());
2639+ packer->pack_flags(native_handle->flags);
2640+ packer->pack_size(buffer->size());
2641+ }
2642 }
2643
2644 void mgm::Platform::drm_auth_magic(unsigned int magic)
2645
2646=== modified file 'src/platform/graphics/mesa/platform.h'
2647--- src/platform/graphics/mesa/platform.h 2014-06-10 14:40:23 +0000
2648+++ src/platform/graphics/mesa/platform.h 2014-06-27 09:18:41 +0000
2649@@ -61,7 +61,8 @@
2650 std::shared_ptr<PlatformIPCPackage> get_ipc_package();
2651 std::shared_ptr<InternalClient> create_internal_client();
2652
2653- void fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const;
2654+ void fill_buffer_package(
2655+ BufferIPCPacker* packer, Buffer const* buffer, BufferIpcMsgType msg_type) const;
2656
2657 EGLNativeDisplayType egl_native_display() const;
2658
2659
2660=== modified file 'src/server/asio_main_loop.cpp'
2661--- src/server/asio_main_loop.cpp 2014-06-12 15:35:08 +0000
2662+++ src/server/asio_main_loop.cpp 2014-06-27 09:18:41 +0000
2663@@ -26,6 +26,37 @@
2664
2665 namespace
2666 {
2667+
2668+void synchronous_server_action(
2669+ mir::ServerActionQueue& queue,
2670+ boost::optional<std::thread::id> queue_thread_id,
2671+ mir::ServerAction const& action)
2672+{
2673+ if (!queue_thread_id || *queue_thread_id == std::this_thread::get_id())
2674+ {
2675+ try { action(); } catch(...) {}
2676+ }
2677+ else
2678+ {
2679+ std::mutex done_mutex;
2680+ bool done{false};
2681+ std::condition_variable done_condition;
2682+
2683+ queue.enqueue(&queue, [&]
2684+ {
2685+ std::lock_guard<std::mutex> lock(done_mutex);
2686+
2687+ try { action(); } catch(...) {}
2688+
2689+ done = true;
2690+ done_condition.notify_one();
2691+ });
2692+
2693+ std::unique_lock<std::mutex> lock(done_mutex);
2694+ done_condition.wait(lock, [&] { return done; });
2695+ }
2696+}
2697+
2698 struct MirClockTimerTraits
2699 {
2700 // TODO the clock used by the main loop is a global setting, this is a restriction
2701@@ -139,8 +170,9 @@
2702 public:
2703 FDHandler(boost::asio::io_service& io,
2704 std::initializer_list<int> fds,
2705+ void const* owner,
2706 std::function<void(int)> const& handler)
2707- : handler{handler}
2708+ : handler{handler}, owner{owner}
2709 {
2710 for (auto fd : fds)
2711 {
2712@@ -150,33 +182,52 @@
2713 }
2714 }
2715
2716- void async_wait()
2717- {
2718- for (auto const& s : stream_descriptors)
2719- {
2720- s->async_read_some(
2721- boost::asio::null_buffers(),
2722- std::bind(&FDHandler::handle, this,
2723- std::placeholders::_1, std::placeholders::_2, s.get()));
2724- }
2725+ bool is_owned_by(void const* possible_owner) const
2726+ {
2727+ return owner == possible_owner;
2728+ }
2729+
2730+ static void async_wait(std::shared_ptr<FDHandler> const& fd_handler, ServerActionQueue& queue)
2731+ {
2732+ for (auto const& s : fd_handler->stream_descriptors)
2733+ read_some(s.get(), fd_handler, queue);
2734 }
2735
2736 private:
2737- void handle(boost::system::error_code err, size_t /*bytes*/,
2738- boost::asio::posix::stream_descriptor* s)
2739+ static void read_some(boost::asio::posix::stream_descriptor* s, std::weak_ptr<FDHandler> const& possible_fd_handler, ServerActionQueue& queue)
2740 {
2741- if (!err)
2742- {
2743- handler(s->native_handle());
2744- s->async_read_some(
2745- boost::asio::null_buffers(),
2746- std::bind(&FDHandler::handle, this,
2747- std::placeholders::_1, std::placeholders::_2, s));
2748- }
2749+ s->async_read_some(
2750+ boost::asio::null_buffers(),
2751+ [possible_fd_handler,s,&queue](boost::system::error_code err, size_t /*bytes*/)
2752+ {
2753+ if (err)
2754+ return;
2755+
2756+ // The actual execution of the fd handler is moved to the action queue.This allows us to synchronously
2757+ // unregister FDHandlers even when they are about to be executed. We do this because of the way Asio
2758+ // copies and executes pending completion handlers.
2759+ // In worst case during the call to unregister the FDHandler, it may still be executed, but not after
2760+ // the unregister call returned.
2761+ queue.enqueue(
2762+ s,
2763+ [possible_fd_handler, s, &queue]()
2764+ {
2765+ auto fd_handler = possible_fd_handler.lock();
2766+ if (!fd_handler)
2767+ return;
2768+
2769+ fd_handler->handler(s->native_handle());
2770+ fd_handler.reset();
2771+
2772+ if (possible_fd_handler.lock())
2773+ read_some(s, possible_fd_handler, queue);
2774+ });
2775+ });
2776 }
2777
2778 std::vector<std::unique_ptr<boost::asio::posix::stream_descriptor>> stream_descriptors;
2779 std::function<void(int)> handler;
2780+ void const* owner;
2781 };
2782
2783 /*
2784@@ -198,12 +249,14 @@
2785
2786 void mir::AsioMainLoop::run()
2787 {
2788+ main_loop_thread = std::this_thread::get_id();
2789 io.run();
2790 }
2791
2792 void mir::AsioMainLoop::stop()
2793 {
2794 io.stop();
2795+ main_loop_thread.reset();
2796 }
2797
2798 void mir::AsioMainLoop::register_signal_handler(
2799@@ -222,18 +275,43 @@
2800
2801 void mir::AsioMainLoop::register_fd_handler(
2802 std::initializer_list<int> fds,
2803+ void const* owner,
2804 std::function<void(int)> const& handler)
2805 {
2806 assert(handler);
2807
2808- auto fd_handler = std::unique_ptr<FDHandler>{
2809- new FDHandler{io, fds, handler}};
2810-
2811- fd_handler->async_wait();
2812-
2813+ auto fd_handler = std::make_shared<FDHandler>(io, fds, owner, handler);
2814+
2815+ FDHandler::async_wait(fd_handler, *this);
2816+
2817+ std::lock_guard<std::mutex> lock(fd_handlers_mutex);
2818 fd_handlers.push_back(std::move(fd_handler));
2819 }
2820
2821+void mir::AsioMainLoop::unregister_fd_handler(void const* owner)
2822+{
2823+ // synchronous_server_action makes sure that with the
2824+ // completion of the method unregister_fd_handler the
2825+ // handler will no longer be called.
2826+ // There is a chance for a fd handler callback to happen before
2827+ // the completion of this method.
2828+ synchronous_server_action(
2829+ *this,
2830+ main_loop_thread,
2831+ [this,owner]()
2832+ {
2833+ std::lock_guard<std::mutex> lock(fd_handlers_mutex);
2834+ auto end_of_valid = remove_if(
2835+ begin(fd_handlers),
2836+ end(fd_handlers),
2837+ [owner](std::shared_ptr<FDHandler> const& item)
2838+ {
2839+ return item->is_owned_by(owner);
2840+ });
2841+ fd_handlers.erase(end_of_valid, end(fd_handlers));
2842+ });
2843+}
2844+
2845 namespace
2846 {
2847 class AlarmImpl : public mir::time::Alarm
2848@@ -266,15 +344,42 @@
2849 {
2850 }
2851
2852- mutable std::mutex m;
2853- std::function<void(void)> callback;
2854+ std::recursive_mutex m;
2855+ std::function<void(void)> const callback;
2856 State state;
2857 };
2858
2859 ::deadline_timer timer;
2860- std::shared_ptr<InternalState> data;
2861+ std::shared_ptr<InternalState> const data;
2862+ std::function<void(boost::system::error_code const& ec)> const handler;
2863+
2864+ friend auto make_handler(std::weak_ptr<InternalState> possible_data)
2865+ -> std::function<void(boost::system::error_code const& ec)>;
2866 };
2867
2868+auto make_handler(std::weak_ptr<AlarmImpl::InternalState> possible_data)
2869+-> std::function<void(boost::system::error_code const& ec)>
2870+{
2871+ // Awkwardly, we can't stop the async_wait handler from being called
2872+ // on a destroyed AlarmImpl. This means we need to wedge a weak_ptr
2873+ // into the async_wait callback.
2874+ return [possible_data](boost::system::error_code const& ec)
2875+ {
2876+ if (!ec)
2877+ {
2878+ if (auto data = possible_data.lock())
2879+ {
2880+ std::unique_lock<decltype(data->m)> lock(data->m);
2881+ if (data->state == mir::time::Alarm::pending)
2882+ {
2883+ data->state = mir::time::Alarm::triggered;
2884+ data->callback();
2885+ }
2886+ }
2887+ }
2888+ };
2889+}
2890+
2891 AlarmImpl::AlarmImpl(boost::asio::io_service& io,
2892 std::chrono::milliseconds delay,
2893 std::function<void ()> callback)
2894@@ -294,7 +399,8 @@
2895 AlarmImpl::AlarmImpl(boost::asio::io_service& io,
2896 std::function<void(void)> callback)
2897 : timer{io},
2898- data{std::make_shared<InternalState>(callback)}
2899+ data{std::make_shared<InternalState>(callback)},
2900+ handler{make_handler(data)}
2901 {
2902 data->state = triggered;
2903 }
2904@@ -338,25 +444,8 @@
2905
2906 void AlarmImpl::update_timer()
2907 {
2908+ timer.async_wait(handler);
2909 std::lock_guard<decltype(data->m)> lock(data->m);
2910- // Awkwardly, we can't stop the async_wait handler from being called
2911- // on a destroyed AlarmImpl. This means we need to wedge a shared_ptr
2912- // into the async_wait callback.
2913- std::weak_ptr<InternalState> possible_data = data;
2914- timer.async_wait([possible_data](boost::system::error_code const& ec)
2915- {
2916- auto data = possible_data.lock();
2917- if (!data)
2918- return;
2919-
2920- std::unique_lock<decltype(data->m)> lock(data->m);
2921- if (!ec && data->state == pending)
2922- {
2923- data->state = triggered;
2924- lock.unlock();
2925- data->callback();
2926- }
2927- });
2928 data->state = pending;
2929 }
2930 }
2931
2932=== modified file 'src/server/compositor/default_display_buffer_compositor.cpp'
2933--- src/server/compositor/default_display_buffer_compositor.cpp 2014-06-10 18:40:05 +0000
2934+++ src/server/compositor/default_display_buffer_compositor.cpp 2014-06-27 09:18:41 +0000
2935@@ -20,6 +20,7 @@
2936 #include "default_display_buffer_compositor.h"
2937
2938 #include "mir/compositor/scene.h"
2939+#include "mir/compositor/scene_element.h"
2940 #include "mir/compositor/renderer.h"
2941 #include "mir/graphics/renderable.h"
2942 #include "mir/graphics/display_buffer.h"
2943@@ -43,6 +44,12 @@
2944 renderer{renderer},
2945 report{report}
2946 {
2947+ scene->register_compositor(this);
2948+}
2949+
2950+mc::DefaultDisplayBufferCompositor::~DefaultDisplayBufferCompositor()
2951+{
2952+ scene->unregister_compositor(this);
2953 }
2954
2955 void mc::DefaultDisplayBufferCompositor::composite()
2956@@ -50,8 +57,21 @@
2957 report->began_frame(this);
2958
2959 auto const& view_area = display_buffer.view_area();
2960- auto renderable_list = scene->renderable_list_for(this);
2961- mc::filter_occlusions_from(renderable_list, view_area);
2962+ auto scene_elements = scene->scene_elements_for(this);
2963+ auto const& occlusions = mc::filter_occlusions_from(scene_elements, view_area);
2964+
2965+ for (auto const& element : occlusions)
2966+ {
2967+ if (element->renderable()->visible())
2968+ element->occluded_in(this);
2969+ }
2970+
2971+ mg::RenderableList renderable_list;
2972+ for (auto const& element : scene_elements)
2973+ {
2974+ element->rendered_in(this);
2975+ renderable_list.push_back(element->renderable());
2976+ }
2977
2978 if (display_buffer.post_renderables_if_optimizable(renderable_list))
2979 {
2980
2981=== modified file 'src/server/compositor/default_display_buffer_compositor.h'
2982--- src/server/compositor/default_display_buffer_compositor.h 2014-06-10 18:40:05 +0000
2983+++ src/server/compositor/default_display_buffer_compositor.h 2014-06-27 09:18:41 +0000
2984@@ -43,6 +43,7 @@
2985 std::shared_ptr<Scene> const& scene,
2986 std::shared_ptr<Renderer> const& renderer,
2987 std::shared_ptr<CompositorReport> const& report);
2988+ ~DefaultDisplayBufferCompositor();
2989
2990 void composite() override;
2991
2992
2993=== modified file 'src/server/compositor/occlusion.cpp'
2994--- src/server/compositor/occlusion.cpp 2014-04-17 01:34:35 +0000
2995+++ src/server/compositor/occlusion.cpp 2014-06-27 09:18:41 +0000
2996@@ -17,11 +17,15 @@
2997 */
2998
2999 #include "mir/geometry/rectangle.h"
3000+#include "mir/compositor/scene_element.h"
3001 #include "mir/graphics/renderable.h"
3002 #include "occlusion.h"
3003
3004+#include <vector>
3005+
3006 using namespace mir::geometry;
3007 using namespace mir::graphics;
3008+using namespace mir::compositor;
3009
3010 namespace
3011 {
3012@@ -62,17 +66,27 @@
3013 }
3014 }
3015
3016-void mir::compositor::filter_occlusions_from(
3017- RenderableList& list,
3018+SceneElementSequence mir::compositor::filter_occlusions_from(
3019+ SceneElementSequence& elements,
3020 Rectangle const& area)
3021 {
3022+ SceneElementSequence occluded;
3023 std::vector<Rectangle> coverage;
3024- auto it = list.rbegin();
3025- while (it != list.rend())
3026+
3027+ auto it = elements.rbegin();
3028+ while (it != elements.rend())
3029 {
3030- if (renderable_is_occluded(**it, area, coverage))
3031- list.erase(std::prev(it.base()));
3032+ auto const renderable = (*it)->renderable();
3033+ if (renderable_is_occluded(*renderable, area, coverage))
3034+ {
3035+ occluded.insert(occluded.begin(), *it);
3036+ it = SceneElementSequence::reverse_iterator(elements.erase(std::prev(it.base())));
3037+ }
3038 else
3039+ {
3040 it++;
3041+ }
3042 }
3043+
3044+ return occluded;
3045 }
3046
3047=== modified file 'src/server/compositor/occlusion.h'
3048--- src/server/compositor/occlusion.h 2014-03-26 16:59:32 +0000
3049+++ src/server/compositor/occlusion.h 2014-06-27 09:18:41 +0000
3050@@ -19,17 +19,14 @@
3051 #ifndef MIR_COMPOSITOR_OCCLUSION_H_
3052 #define MIR_COMPOSITOR_OCCLUSION_H_
3053
3054-#include "mir/graphics/renderable.h"
3055 #include "mir/compositor/scene.h"
3056-#include <vector>
3057-#include <set>
3058
3059 namespace mir
3060 {
3061 namespace compositor
3062 {
3063
3064-void filter_occlusions_from(graphics::RenderableList& list, geometry::Rectangle const& area);
3065+SceneElementSequence filter_occlusions_from(SceneElementSequence& list, geometry::Rectangle const& area);
3066
3067 } // namespace compositor
3068 } // namespace mir
3069
3070=== modified file 'src/server/compositor/timeout_frame_dropping_policy_factory.cpp'
3071--- src/server/compositor/timeout_frame_dropping_policy_factory.cpp 2014-05-22 20:48:20 +0000
3072+++ src/server/compositor/timeout_frame_dropping_policy_factory.cpp 2014-06-27 09:18:41 +0000
3073@@ -41,7 +41,7 @@
3074
3075 private:
3076 std::chrono::milliseconds const timeout;
3077- std::unique_ptr<mir::time::Alarm> alarm;
3078+ std::unique_ptr<mir::time::Alarm> const alarm;
3079 std::atomic<unsigned int> pending_swaps;
3080 };
3081
3082@@ -49,15 +49,15 @@
3083 std::chrono::milliseconds timeout,
3084 std::function<void(void)> drop_frame)
3085 : timeout{timeout},
3086+ alarm{timer->create_alarm([this, drop_frame]
3087+ {
3088+ assert(pending_swaps.load() > 0);
3089+ drop_frame();
3090+ if (--pending_swaps > 0)
3091+ alarm->reschedule_in(this->timeout);
3092+ })},
3093 pending_swaps{0}
3094 {
3095- alarm = timer->create_alarm([this, drop_frame]
3096- {
3097- assert(pending_swaps.load() > 0);
3098- drop_frame();
3099- if (--pending_swaps > 0)
3100- alarm->reschedule_in(this->timeout);
3101- });
3102 }
3103
3104 void TimeoutFrameDroppingPolicy::swap_now_blocking()
3105
3106=== modified file 'src/server/default_server_configuration.cpp'
3107--- src/server/default_server_configuration.cpp 2014-06-11 16:11:32 +0000
3108+++ src/server/default_server_configuration.cpp 2014-06-27 09:18:41 +0000
3109@@ -101,30 +101,6 @@
3110 });
3111 }
3112
3113-std::shared_ptr<mi::CursorListener>
3114-mir::DefaultServerConfiguration::the_cursor_listener()
3115-{
3116- struct DefaultCursorListener : mi::CursorListener
3117- {
3118- DefaultCursorListener(std::shared_ptr<mg::Cursor> const& cursor) :
3119- cursor(cursor)
3120- {
3121- }
3122-
3123- void cursor_moved_to(float abs_x, float abs_y)
3124- {
3125- cursor->move_to(geom::Point{abs_x, abs_y});
3126- }
3127-
3128- std::shared_ptr<mg::Cursor> const cursor;
3129- };
3130- return cursor_listener(
3131- [this]() -> std::shared_ptr<mi::CursorListener>
3132- {
3133- return std::make_shared<DefaultCursorListener>(the_cursor());
3134- });
3135-}
3136-
3137 std::shared_ptr<ms::SurfaceConfigurator> mir::DefaultServerConfiguration::the_surface_configurator()
3138 {
3139 struct DefaultSurfaceConfigurator : public ms::SurfaceConfigurator
3140
3141=== modified file 'src/server/frontend/session_mediator.cpp'
3142--- src/server/frontend/session_mediator.cpp 2014-06-12 10:06:11 +0000
3143+++ src/server/frontend/session_mediator.cpp 2014-06-27 09:18:41 +0000
3144@@ -32,7 +32,6 @@
3145 #include "mir/graphics/cursor_images.h"
3146 #include "mir/compositor/buffer_stream.h"
3147 #include "mir/geometry/dimensions.h"
3148-#include "mir/graphics/platform.h"
3149 #include "mir/frontend/display_changer.h"
3150 #include "mir/graphics/display_configuration.h"
3151 #include "mir/graphics/pixel_format_utils.h"
3152@@ -139,7 +138,7 @@
3153 void mf::SessionMediator::advance_buffer(
3154 SurfaceId surf_id,
3155 Surface& surface,
3156- std::function<void(graphics::Buffer*, bool)> complete)
3157+ std::function<void(graphics::Buffer*, graphics::BufferIpcMsgType)> complete)
3158 {
3159 auto& tracker = client_buffer_tracker[surf_id];
3160 if (!tracker) tracker = std::make_shared<ClientBufferTracker>(client_buffer_cache_size);
3161@@ -148,12 +147,17 @@
3162 surface.swap_buffers(client_buffer,
3163 [&tracker, &client_buffer, complete](mg::Buffer* new_buffer)
3164 {
3165+
3166 client_buffer = new_buffer;
3167 auto id = client_buffer->id();
3168 auto need_full_ipc = !tracker->client_has(id);
3169+
3170 tracker->add(id);
3171
3172- complete(client_buffer, need_full_ipc);
3173+ if (need_full_ipc)
3174+ complete(client_buffer, mg::BufferIpcMsgType::full_msg);
3175+ else
3176+ complete(client_buffer, mg::BufferIpcMsgType::update_msg);
3177 });
3178 }
3179
3180@@ -193,12 +197,13 @@
3181 response->add_fd(surface->client_input_fd());
3182
3183 advance_buffer(surf_id, *surface,
3184- [lock, this, response, done, session](graphics::Buffer* client_buffer, bool need_full_ipc)
3185+ [lock, this, response, done, session]
3186+ (graphics::Buffer* client_buffer, graphics::BufferIpcMsgType msg_type)
3187 {
3188 lock->unlock();
3189
3190 auto buffer = response->mutable_buffer();
3191- pack_protobuf_buffer(*buffer, client_buffer, need_full_ipc);
3192+ pack_protobuf_buffer(*buffer, client_buffer, msg_type);
3193
3194 // TODO: NOTE: We use the ordering here to ensure the shell acts on the surface after the surface ID is sent over the wire.
3195 // This guarantees that notifications such as, gained focus, etc, can be correctly interpreted by the client.
3196@@ -229,11 +234,12 @@
3197 auto surface = session->get_surface(surf_id);
3198
3199 advance_buffer(surf_id, *surface,
3200- [lock, this, response, done, session](graphics::Buffer* client_buffer, bool need_full_ipc)
3201+ [lock, this, response, done, session]
3202+ (graphics::Buffer* client_buffer, graphics::BufferIpcMsgType msg_type)
3203 {
3204 lock->unlock();
3205
3206- pack_protobuf_buffer(*response, client_buffer, need_full_ipc);
3207+ pack_protobuf_buffer(*response, client_buffer, msg_type);
3208
3209 done->Run();
3210 });
3211@@ -373,7 +379,7 @@
3212 mir::protobuf::Screencast* protobuf_screencast,
3213 google::protobuf::Closure* done)
3214 {
3215- static bool const need_full_ipc{true};
3216+ static auto const msg_type = mg::BufferIpcMsgType::full_msg;
3217
3218 geom::Rectangle const region{
3219 {parameters->region().left(), parameters->region().top()},
3220@@ -389,7 +395,7 @@
3221 screencast_session_id.as_value());
3222 pack_protobuf_buffer(*protobuf_screencast->mutable_buffer(),
3223 buffer.get(),
3224- need_full_ipc);
3225+ msg_type);
3226
3227 done->Run();
3228 }
3229@@ -412,7 +418,7 @@
3230 mir::protobuf::Buffer* protobuf_buffer,
3231 google::protobuf::Closure* done)
3232 {
3233- static bool const does_not_need_full_ipc{false};
3234+ static auto const msg_type = mg::BufferIpcMsgType::update_msg;
3235 ScreencastSessionId const screencast_session_id{
3236 protobuf_screencast_id->value()};
3237
3238@@ -420,7 +426,7 @@
3239
3240 pack_protobuf_buffer(*protobuf_buffer,
3241 buffer.get(),
3242- does_not_need_full_ipc);
3243+ msg_type);
3244
3245 done->Run();
3246 }
3247@@ -619,13 +625,10 @@
3248 void mf::SessionMediator::pack_protobuf_buffer(
3249 protobuf::Buffer& protobuf_buffer,
3250 graphics::Buffer* graphics_buffer,
3251- bool need_full_ipc)
3252+ mg::BufferIpcMsgType buffer_msg_type)
3253 {
3254 protobuf_buffer.set_buffer_id(graphics_buffer->id().as_uint32_t());
3255
3256- if (need_full_ipc)
3257- {
3258- mfd::ProtobufBufferPacker packer{&protobuf_buffer};
3259- graphics_platform->fill_ipc_package(&packer, graphics_buffer);
3260- }
3261+ mfd::ProtobufBufferPacker packer{&protobuf_buffer};
3262+ graphics_platform->fill_buffer_package(&packer, graphics_buffer, buffer_msg_type);
3263 }
3264
3265=== modified file 'src/server/frontend/session_mediator.h'
3266--- src/server/frontend/session_mediator.h 2014-06-13 15:20:50 +0000
3267+++ src/server/frontend/session_mediator.h 2014-06-27 09:18:41 +0000
3268@@ -22,6 +22,7 @@
3269 #include "display_server.h"
3270 #include "mir/frontend/connection_context.h"
3271 #include "mir/frontend/surface_id.h"
3272+#include "mir/graphics/platform.h"
3273 #include "mir_toolkit/common.h"
3274
3275 #include <functional>
3276@@ -164,9 +165,12 @@
3277 private:
3278 void pack_protobuf_buffer(protobuf::Buffer& protobuf_buffer,
3279 graphics::Buffer* graphics_buffer,
3280- bool need_full_ipc);
3281+ graphics::BufferIpcMsgType msg_type);
3282
3283- void advance_buffer(SurfaceId surf_id, Surface& surface, std::function<void(graphics::Buffer*, bool)> complete);
3284+ void advance_buffer(
3285+ SurfaceId surf_id,
3286+ Surface& surface,
3287+ std::function<void(graphics::Buffer*, graphics::BufferIpcMsgType)> complete);
3288
3289 virtual std::function<void(std::shared_ptr<Session> const&)> prompt_session_connect_handler() const;
3290
3291
3292=== modified file 'src/server/graphics/default_configuration.cpp'
3293--- src/server/graphics/default_configuration.cpp 2014-06-10 14:40:23 +0000
3294+++ src/server/graphics/default_configuration.cpp 2014-06-27 09:18:41 +0000
3295@@ -27,6 +27,7 @@
3296
3297 #include "mir/graphics/buffer_initializer.h"
3298 #include "mir/graphics/gl_config.h"
3299+#include "mir/graphics/cursor.h"
3300 #include "program_factory.h"
3301
3302 #include "mir/shared_library.h"
3303@@ -34,6 +35,8 @@
3304 #include "mir/abnormal_exit.h"
3305 #include "mir/emergency_cleanup.h"
3306
3307+#include "mir_toolkit/common.h"
3308+
3309 #include <boost/throw_exception.hpp>
3310
3311 #include "builtin_cursor_images.h"
3312@@ -122,11 +125,23 @@
3313 std::shared_ptr<mg::Cursor>
3314 mir::DefaultServerConfiguration::the_cursor()
3315 {
3316+ struct NullCursor : public mg::Cursor
3317+ {
3318+ void show(mg::CursorImage const&) {}
3319+ void hide() {}
3320+ void move_to(geometry::Point) {}
3321+ };
3322 return cursor(
3323 [this]() -> std::shared_ptr<mg::Cursor>
3324 {
3325- // For now we only support a hardware cursor.
3326- return the_display()->create_hardware_cursor(the_default_cursor_image());
3327+ // We try to create a hardware cursor, as we have no software
3328+ // cursor currently, if this fails we need to return
3329+ // a valid cursor object.
3330+ auto hardware_cursor = the_display()->create_hardware_cursor(the_default_cursor_image());
3331+ if (hardware_cursor)
3332+ return hardware_cursor;
3333+ else
3334+ return std::make_shared<NullCursor>();
3335 });
3336 }
3337
3338@@ -138,7 +153,7 @@
3339 return default_cursor_image(
3340 [this]()
3341 {
3342- return the_cursor_images()->image("arrow", default_cursor_size);
3343+ return the_cursor_images()->image(mir_default_cursor_name, default_cursor_size);
3344 });
3345 }
3346
3347
3348=== modified file 'src/server/graphics/nested/nested_platform.cpp'
3349--- src/server/graphics/nested/nested_platform.cpp 2014-06-02 17:07:02 +0000
3350+++ src/server/graphics/nested/nested_platform.cpp 2014-06-27 09:18:41 +0000
3351@@ -99,9 +99,10 @@
3352 return native_platform->create_internal_client();
3353 }
3354
3355-void mgn::NestedPlatform::fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const
3356+void mgn::NestedPlatform::fill_buffer_package(
3357+ BufferIPCPacker* packer, Buffer const* buffer, BufferIpcMsgType msg_type) const
3358 {
3359- native_platform->fill_ipc_package(packer, buffer);
3360+ native_platform->fill_buffer_package(packer, buffer, msg_type);
3361 }
3362
3363 EGLNativeDisplayType mgn::NestedPlatform::egl_native_display() const
3364
3365=== modified file 'src/server/graphics/nested/nested_platform.h'
3366--- src/server/graphics/nested/nested_platform.h 2014-06-02 17:07:02 +0000
3367+++ src/server/graphics/nested/nested_platform.h 2014-06-27 09:18:41 +0000
3368@@ -49,7 +49,8 @@
3369 std::shared_ptr<GLConfig> const& gl_config);
3370 std::shared_ptr<PlatformIPCPackage> get_ipc_package() override;
3371 std::shared_ptr<InternalClient> create_internal_client() override;
3372- void fill_ipc_package(BufferIPCPacker* packer, Buffer const* Buffer) const override;
3373+ void fill_buffer_package(
3374+ BufferIPCPacker* packer, Buffer const* Buffer, BufferIpcMsgType msg_type) const override;
3375 EGLNativeDisplayType egl_native_display() const;
3376
3377 private:
3378
3379=== modified file 'src/server/input/CMakeLists.txt'
3380--- src/server/input/CMakeLists.txt 2014-06-02 17:07:02 +0000
3381+++ src/server/input/CMakeLists.txt 2014-06-27 09:18:41 +0000
3382@@ -5,11 +5,13 @@
3383
3384 event_filter_chain.cpp
3385
3386+ null_input_channel_factory.cpp
3387 null_input_configuration.cpp
3388 null_input_dispatcher.cpp
3389 nested_input_configuration.cpp
3390 display_input_region.cpp
3391 vt_filter.cpp
3392+ cursor_controller.cpp
3393 default_configuration.cpp
3394 )
3395
3396
3397=== modified file 'src/server/input/android/CMakeLists.txt'
3398--- src/server/input/android/CMakeLists.txt 2014-06-02 17:07:02 +0000
3399+++ src/server/input/android/CMakeLists.txt 2014-06-27 09:18:41 +0000
3400@@ -16,6 +16,7 @@
3401 ${CMAKE_CURRENT_SOURCE_DIR}/common_input_thread.cpp
3402 ${CMAKE_CURRENT_SOURCE_DIR}/input_channel_factory.cpp
3403 ${CMAKE_CURRENT_SOURCE_DIR}/input_translator.cpp
3404+ ${CMAKE_CURRENT_SOURCE_DIR}/input_sender.cpp
3405 )
3406
3407 set(
3408
3409=== modified file 'src/server/input/android/android_input_reader_policy.cpp'
3410--- src/server/input/android/android_input_reader_policy.cpp 2014-03-06 06:05:17 +0000
3411+++ src/server/input/android/android_input_reader_policy.cpp 2014-06-27 09:18:41 +0000
3412@@ -26,7 +26,7 @@
3413 namespace mia = mir::input::android;
3414
3415 mia::InputReaderPolicy::InputReaderPolicy(std::shared_ptr<mi::InputRegion> const& input_region,
3416- std::shared_ptr<CursorListener> const& cursor_listener)
3417+ std::shared_ptr<CursorListener> const& cursor_listener)
3418 : input_region(input_region),
3419 pointer_controller(new mia::PointerController(input_region, cursor_listener))
3420 {
3421@@ -56,3 +56,15 @@
3422 {
3423 return pointer_controller;
3424 }
3425+
3426+void mia::InputReaderPolicy::getAssociatedDisplayInfo(droidinput::InputDeviceIdentifier const& /* identifier */,
3427+ int& out_associated_display_id, bool& out_associated_display_is_external)
3428+{
3429+ // This is used primarily for mapping of direct input devices to screen space. Currently we only support one large display
3430+ // bounding all displays (i.e. input_region->bounding_rectangle())
3431+ // the external/internal distinction is mostly a leftover from android configuration nuances.
3432+ // Eventually we will need to use a combination of configuration and heuristic to implement this
3433+ // correctly
3434+ out_associated_display_id = 0;
3435+ out_associated_display_is_external = false;
3436+}
3437
3438=== modified file 'src/server/input/android/android_input_reader_policy.h'
3439--- src/server/input/android/android_input_reader_policy.h 2013-08-28 03:41:48 +0000
3440+++ src/server/input/android/android_input_reader_policy.h 2014-06-27 09:18:41 +0000
3441@@ -39,8 +39,11 @@
3442
3443 virtual ~InputReaderPolicy() {}
3444
3445- virtual droidinput::sp<droidinput::PointerControllerInterface> obtainPointerController(int32_t device_id);
3446- virtual void getReaderConfiguration(droidinput::InputReaderConfiguration* out_config);
3447+ droidinput::sp<droidinput::PointerControllerInterface> obtainPointerController(int32_t device_id) override;
3448+ void getReaderConfiguration(droidinput::InputReaderConfiguration* out_config) override;
3449+
3450+ void getAssociatedDisplayInfo(droidinput::InputDeviceIdentifier const& identifier,
3451+ int& out_associated_display_id, bool& out_associated_display_is_external) override;
3452 private:
3453 std::shared_ptr<InputRegion> const input_region;
3454 droidinput::sp<droidinput::PointerControllerInterface> pointer_controller;
3455
3456=== modified file 'src/server/input/android/default_android_input_configuration.cpp'
3457--- src/server/input/android/default_android_input_configuration.cpp 2014-06-04 15:31:35 +0000
3458+++ src/server/input/android/default_android_input_configuration.cpp 2014-06-27 09:18:41 +0000
3459@@ -26,7 +26,6 @@
3460 #include "android_input_target_enumerator.h"
3461 #include "android_input_manager.h"
3462 #include "input_translator.h"
3463-#include "input_channel_factory.h"
3464 #include "common_input_thread.h"
3465
3466 #include "mir/input/event_filter.h"
3467@@ -65,11 +64,6 @@
3468 {
3469 }
3470
3471-std::shared_ptr<mi::InputChannelFactory> mia::DefaultInputConfiguration::the_input_channel_factory()
3472-{
3473- return std::make_shared<mia::InputChannelFactory>();
3474-}
3475-
3476 std::shared_ptr<droidinput::EventHubInterface> mia::DefaultInputConfiguration::the_event_hub()
3477 {
3478 return event_hub(
3479
3480=== added file 'src/server/input/android/input_send_entry.h'
3481--- src/server/input/android/input_send_entry.h 1970-01-01 00:00:00 +0000
3482+++ src/server/input/android/input_send_entry.h 2014-06-27 09:18:41 +0000
3483@@ -0,0 +1,51 @@
3484+/*
3485+ * Copyright © 2014 Canonical Ltd.
3486+ *
3487+ * This program is free software: you can redistribute it and/or modify it
3488+ * under the terms of the GNU General Public License version 3,
3489+ * as published by the Free Software Foundation.
3490+ *
3491+ * This program is distributed in the hope that it will be useful,
3492+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3493+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3494+ * GNU General Public License for more details.
3495+ *
3496+ * You should have received a copy of the GNU General Public License
3497+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3498+ *
3499+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
3500+ */
3501+
3502+#ifndef MIR_INPUT_ANDROID_INPUT_SEND_ENTRY_H_
3503+#define MIR_INPUT_ANDROID_INPUT_SEND_ENTRY_H_
3504+
3505+#include "mir_toolkit/event.h"
3506+#include <memory>
3507+
3508+namespace mir
3509+{
3510+namespace input
3511+{
3512+class InputChannel;
3513+namespace android
3514+{
3515+
3516+/*!
3517+ * Stores information about an input event to be sent to a client
3518+ */
3519+struct InputSendEntry
3520+{
3521+ uint32_t sequence_id;
3522+ MirEvent event;
3523+ std::shared_ptr<InputChannel> channel;
3524+ InputSendEntry(uint32_t id, MirEvent ev, std::shared_ptr<InputChannel> const& channel)
3525+ : sequence_id(id), event(ev), channel(channel)
3526+ {
3527+ }
3528+};
3529+
3530+}
3531+}
3532+}
3533+
3534+#endif
3535
3536=== added file 'src/server/input/android/input_sender.cpp'
3537--- src/server/input/android/input_sender.cpp 1970-01-01 00:00:00 +0000
3538+++ src/server/input/android/input_sender.cpp 2014-06-27 09:18:41 +0000
3539@@ -0,0 +1,410 @@
3540+/*
3541+ * Copyright © 2014 Canonical Ltd.
3542+ *
3543+ * This program is free software: you can redistribute it and/or modify it
3544+ * under the terms of the GNU General Public License version 3,
3545+ * as published by the Free Software Foundation.
3546+ *
3547+ * This program is distributed in the hope that it will be useful,
3548+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3549+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3550+ * GNU General Public License for more details.
3551+ *
3552+ * You should have received a copy of the GNU General Public License
3553+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3554+ *
3555+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
3556+ */
3557+
3558+#include "input_sender.h"
3559+#include "input_send_entry.h"
3560+
3561+#include "mir/input/input_send_observer.h"
3562+#include "mir/input/input_channel.h"
3563+#include "mir/input/input_report.h"
3564+#include "mir/scene/surface.h"
3565+#include "mir/compositor/scene.h"
3566+#include "mir/main_loop.h"
3567+
3568+#include "androidfw/Input.h"
3569+#include "androidfw/InputTransport.h"
3570+#include "std/Errors.h"
3571+#include "std/String8.h"
3572+
3573+#include <boost/exception/errinfo_errno.hpp>
3574+#include <boost/throw_exception.hpp>
3575+
3576+#include <cstring>
3577+#include <algorithm>
3578+#include <iterator>
3579+
3580+namespace mi = mir::input;
3581+namespace mia = mi::android;
3582+
3583+namespace droidinput = android;
3584+
3585+namespace
3586+{
3587+const std::chrono::seconds input_send_timeout{5};
3588+}
3589+
3590+mia::InputSender::InputSender(std::shared_ptr<mir::compositor::Scene> const& scene,
3591+ std::shared_ptr<mir::MainLoop> const& main_loop,
3592+ std::shared_ptr<mir::input::InputSendObserver> const& observer,
3593+ std::shared_ptr<InputReport> const& report)
3594+ : state{main_loop, observer, report}, scene{scene}
3595+{
3596+ scene->add_observer(std::make_shared<SceneObserver>(state));
3597+}
3598+
3599+mia::InputSender::SceneObserver::SceneObserver(InputSenderState & state)
3600+ : state(state)
3601+{
3602+}
3603+
3604+void mia::InputSender::SceneObserver::surface_added(scene::Surface* surface)
3605+{
3606+ if (surface && surface->input_channel())
3607+ {
3608+ state.add_transfer(surface->input_channel()->server_fd(), surface);
3609+ }
3610+}
3611+
3612+void mia::InputSender::SceneObserver::surface_removed(scene::Surface* surface)
3613+{
3614+ if (surface && surface->input_channel())
3615+ {
3616+ remove_transfer_for(surface);
3617+ }
3618+}
3619+
3620+void mia::InputSender::SceneObserver::surface_exists(scene::Surface* surface)
3621+{
3622+ surface_added(surface);
3623+}
3624+
3625+
3626+void mia::InputSender::SceneObserver::remove_transfer_for(mir::input::Surface * surface)
3627+{
3628+ std::shared_ptr<InputChannel> closed_channel = surface->input_channel();
3629+
3630+ if (!closed_channel)
3631+ return;
3632+
3633+ state.remove_transfer(closed_channel->server_fd());
3634+
3635+}
3636+
3637+mia::InputSender::InputSenderState::InputSenderState(std::shared_ptr<mir::MainLoop> const& main_loop,
3638+ std::shared_ptr<mir::input::InputSendObserver> const& observer,
3639+ std::shared_ptr<InputReport> const& report)
3640+ : main_loop{main_loop}, report{report}, observer{observer}, seq{}
3641+{
3642+}
3643+
3644+void mia::InputSender::send_event(MirEvent const& event, std::shared_ptr<InputChannel> const& channel)
3645+{
3646+ state.send_event(channel, event);
3647+}
3648+
3649+std::shared_ptr<mia::InputSender::ActiveTransfer> mia::InputSender::InputSenderState::get_transfer(int fd)
3650+{
3651+ auto pos = transfers.find(fd);
3652+
3653+ if (pos == transfers.end())
3654+ return nullptr;
3655+
3656+ return pos->second;
3657+}
3658+
3659+void mia::InputSender::InputSenderState::send_event(std::shared_ptr<InputChannel> const& channel, MirEvent const& event)
3660+{
3661+ std::unique_lock<std::mutex> lock(sender_mutex);
3662+ auto transfer = get_transfer(channel->server_fd());
3663+
3664+ if (!transfer)
3665+ BOOST_THROW_EXCEPTION(std::runtime_error("Failure sending input event : Unknown channel provided"));
3666+
3667+ mia::InputSendEntry entry{next_seq(), event, channel};
3668+ lock.unlock();
3669+
3670+ transfer->send(std::move(entry));
3671+}
3672+
3673+void mia::InputSender::InputSenderState::add_transfer(int fd, mir::input::Surface * surface)
3674+{
3675+ std::lock_guard<std::mutex> lock(sender_mutex);
3676+ std::shared_ptr<ActiveTransfer> transfer{get_transfer(fd)};
3677+
3678+ if (transfer && transfer->used_for_surface(surface))
3679+ return;
3680+
3681+ transfers[fd] = std::make_shared<ActiveTransfer>(*this, fd, surface);
3682+}
3683+
3684+void mia::InputSender::InputSenderState::remove_transfer(int fd)
3685+{
3686+ std::unique_lock<std::mutex> lock(sender_mutex);
3687+ auto transfer = get_transfer(fd);
3688+
3689+ if (transfer)
3690+ {
3691+ transfers.erase(fd);
3692+ lock.unlock();
3693+
3694+ transfer->on_surface_disappeared();
3695+ }
3696+}
3697+
3698+uint32_t mia::InputSender::InputSenderState::next_seq()
3699+{
3700+ while(!++seq);
3701+ return seq;
3702+}
3703+
3704+mia::InputSender::ActiveTransfer::ActiveTransfer(InputSenderState & state, int server_fd, mir::input::Surface* surface) :
3705+ state(state),
3706+ publisher{droidinput::sp<droidinput::InputChannel>(
3707+ new droidinput::InputChannel(droidinput::String8(surface->name()), server_fd))},
3708+ surface{surface}
3709+{
3710+}
3711+
3712+void mia::InputSender::ActiveTransfer::send(InputSendEntry && event)
3713+{
3714+ if (event.event.type != mir_event_type_key &&
3715+ event.event.type != mir_event_type_motion)
3716+ return;
3717+
3718+ droidinput::status_t error_status =
3719+ (event.event.type == mir_event_type_key)
3720+ ? send_key_event(event.sequence_id, event.event.key)
3721+ : send_motion_event(event.sequence_id, event.event.motion);
3722+
3723+ if (error_status == droidinput::OK)
3724+ {
3725+ enqueue_entry(std::move(event));
3726+ return;
3727+ }
3728+
3729+ switch(error_status)
3730+ {
3731+ case droidinput::WOULD_BLOCK:
3732+ if (state.observer)
3733+ state.observer->client_blocked(event.event, surface);
3734+ break;
3735+ case droidinput::DEAD_OBJECT:
3736+ if (state.observer)
3737+ state.observer->send_failed(event.event, surface, InputSendObserver::socket_error);
3738+ break;
3739+ default:
3740+ BOOST_THROW_EXCEPTION(boost::enable_error_info(std::runtime_error("Failure sending input event : ")) << boost::errinfo_errno(errno));
3741+ }
3742+}
3743+
3744+mia::InputSender::ActiveTransfer::~ActiveTransfer()
3745+{
3746+ unsubscribe();
3747+}
3748+
3749+void mia::InputSender::ActiveTransfer::unsubscribe()
3750+{
3751+ state.main_loop->unregister_fd_handler(this);
3752+}
3753+
3754+void mia::InputSender::ActiveTransfer::subscribe()
3755+{
3756+ state.main_loop->register_fd_handler({publisher.getChannel()->getFd()},
3757+ this,
3758+ [this](int)
3759+ {
3760+ on_finish_signal();
3761+ });
3762+}
3763+
3764+droidinput::status_t mia::InputSender::ActiveTransfer::send_key_event(uint32_t seq, MirKeyEvent const& event)
3765+{
3766+ return publisher.publishKeyEvent(
3767+ seq,
3768+ event.device_id,
3769+ event.source_id,
3770+ event.action,
3771+ event.flags,
3772+ event.key_code,
3773+ event.scan_code,
3774+ event.modifiers,
3775+ event.repeat_count,
3776+ event.down_time,
3777+ event.event_time
3778+ );
3779+}
3780+
3781+droidinput::status_t mia::InputSender::ActiveTransfer::send_motion_event(uint32_t seq, MirMotionEvent const& event)
3782+{
3783+ droidinput::PointerCoords coords[MIR_INPUT_EVENT_MAX_POINTER_COUNT];
3784+ droidinput::PointerProperties properties[MIR_INPUT_EVENT_MAX_POINTER_COUNT];
3785+ // no default constructor:
3786+ std::memset(coords, 0, sizeof(coords));
3787+ std::memset(properties, 0, sizeof(properties));
3788+
3789+ for (size_t i = 0; i < event.pointer_count; ++i)
3790+ {
3791+ // Note: this assumes that: x == raw_x + x_offset;
3792+ // here x, y is used instead of the raw co-ordinates and offset is set to zero
3793+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_X, event.pointer_coordinates[i].x);
3794+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, event.pointer_coordinates[i].y);
3795+
3796+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, event.pointer_coordinates[i].touch_major);
3797+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, event.pointer_coordinates[i].touch_minor);
3798+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_SIZE, event.pointer_coordinates[i].size);
3799+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, event.pointer_coordinates[i].pressure);
3800+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, event.pointer_coordinates[i].orientation);
3801+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, event.pointer_coordinates[i].vscroll);
3802+ coords[i].setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, event.pointer_coordinates[i].hscroll);
3803+ properties[i].toolType = event.pointer_coordinates[i].tool_type;
3804+ properties[i].id = event.pointer_coordinates[i].id;
3805+ }
3806+
3807+ return publisher.publishMotionEvent(
3808+ seq,
3809+ event.device_id,
3810+ event.source_id,
3811+ event.action,
3812+ static_cast<int32_t>(event.flags),
3813+ event.edge_flags,
3814+ static_cast<int32_t>(event.modifiers),
3815+ static_cast<int32_t>(event.button_state),
3816+ 0.0f, // event.x_offset,
3817+ 0.0f, // event.y_offset,
3818+ event.x_precision,
3819+ event.y_precision,
3820+ event.down_time,
3821+ event.event_time,
3822+ event.pointer_count,
3823+ properties,
3824+ coords
3825+ );
3826+}
3827+
3828+void mia::InputSender::ActiveTransfer::on_surface_disappeared()
3829+{
3830+ std::unique_lock<std::mutex> lock{transfer_mutex};
3831+ std::vector<InputSendEntry> release_pending_responses;
3832+
3833+ swap(release_pending_responses, pending_responses);
3834+
3835+ lock.unlock();
3836+
3837+ auto observer = state.observer;
3838+ if (observer)
3839+ {
3840+ std::for_each(release_pending_responses.rbegin(),
3841+ release_pending_responses.rend(),
3842+ [observer,this](InputSendEntry const& entry)
3843+ {
3844+ observer->send_failed(entry.event, surface, InputSendObserver::surface_disappeared);
3845+ });
3846+ }
3847+}
3848+
3849+void mia::InputSender::ActiveTransfer::on_finish_signal()
3850+{
3851+ uint32_t sequence;
3852+ bool handled;
3853+
3854+ while(true)
3855+ {
3856+ droidinput::status_t status = publisher.receiveFinishedSignal(&sequence, &handled);
3857+
3858+ if (status == droidinput::OK)
3859+ {
3860+ state.report->received_event_finished_signal(publisher.getChannel()->getFd(), sequence);
3861+ InputSendEntry entry = unqueue_entry(sequence);
3862+ auto observer = state.observer;
3863+
3864+ if (entry.sequence_id == sequence && observer)
3865+ observer->send_suceeded(entry.event,
3866+ surface,
3867+ handled ? InputSendObserver::consumed : InputSendObserver::not_consumed);
3868+ }
3869+ else
3870+ {
3871+ return;
3872+ // TODO find a better way to handle communication errors, droidinput::InputDispatcher just ignores them
3873+ }
3874+ }
3875+}
3876+
3877+void mia::InputSender::ActiveTransfer::on_response_timeout()
3878+{
3879+ int top_sequence_id{0};
3880+
3881+ {
3882+ std::lock_guard<std::mutex> lock(transfer_mutex);
3883+ if (pending_responses.empty())
3884+ return;
3885+ top_sequence_id = pending_responses.front().sequence_id;
3886+ }
3887+
3888+ mia::InputSendEntry timedout_entry{unqueue_entry(top_sequence_id)};
3889+
3890+ if (state.observer)
3891+ state.observer->send_failed(timedout_entry.event, surface, InputSendObserver::no_response_received);
3892+}
3893+
3894+void mia::InputSender::ActiveTransfer::enqueue_entry(mia::InputSendEntry && entry)
3895+{
3896+ std::lock_guard<std::mutex> lock(transfer_mutex);
3897+ if (pending_responses.empty())
3898+ {
3899+ subscribe();
3900+ update_timer();
3901+ }
3902+
3903+ pending_responses.push_back(entry);
3904+}
3905+
3906+mia::InputSendEntry mia::InputSender::ActiveTransfer::unqueue_entry(uint32_t sequence_id)
3907+{
3908+ std::lock_guard<std::mutex> lock(transfer_mutex);
3909+ auto pos = std::find_if(pending_responses.begin(),
3910+ pending_responses.end(),
3911+ [sequence_id](mia::InputSendEntry const& entry)
3912+ { return entry.sequence_id == sequence_id; });
3913+
3914+ if (pos == end(pending_responses))
3915+ return {0, MirEvent{}, std::shared_ptr<mi::InputChannel>()};
3916+
3917+ mia::InputSendEntry result = *pos;
3918+ pending_responses.erase(pos);
3919+ if (pending_responses.empty())
3920+ {
3921+ unsubscribe();
3922+ cancel_timer();
3923+ }
3924+ else
3925+ {
3926+ update_timer();
3927+ }
3928+
3929+ return result;
3930+}
3931+
3932+void mia::InputSender::ActiveTransfer::update_timer()
3933+{
3934+ if (send_timer)
3935+ send_timer->reschedule_in(input_send_timeout);
3936+ else
3937+ send_timer = state.main_loop->notify_in(input_send_timeout, [this](){on_response_timeout();});
3938+}
3939+
3940+void mia::InputSender::ActiveTransfer::cancel_timer()
3941+{
3942+ if (send_timer)
3943+ send_timer->cancel();
3944+}
3945+
3946+bool mia::InputSender::ActiveTransfer::used_for_surface(input::Surface const* surface) const
3947+{
3948+ return this->surface == surface;
3949+}
3950
3951=== added file 'src/server/input/android/input_sender.h'
3952--- src/server/input/android/input_sender.h 1970-01-01 00:00:00 +0000
3953+++ src/server/input/android/input_sender.h 2014-06-27 09:18:41 +0000
3954@@ -0,0 +1,146 @@
3955+/*
3956+ * Copyright © 2014 Canonical Ltd.
3957+ *
3958+ * This program is free software: you can redistribute it and/or modify it
3959+ * under the terms of the GNU General Public License version 3,
3960+ * as published by the Free Software Foundation.
3961+ *
3962+ * This program is distributed in the hope that it will be useful,
3963+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3964+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3965+ * GNU General Public License for more details.
3966+ *
3967+ * You should have received a copy of the GNU General Public License
3968+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3969+ *
3970+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
3971+ */
3972+
3973+#ifndef MIR_INPUT_ANDROID_INPUT_SENDER_H_
3974+#define MIR_INPUT_ANDROID_INPUT_SENDER_H_
3975+
3976+#include "mir/input/input_sender.h"
3977+#include "mir/scene/null_observer.h"
3978+
3979+#include "androidfw/InputTransport.h"
3980+
3981+#include <memory>
3982+#include <unordered_map>
3983+#include <mutex>
3984+#include <vector>
3985+
3986+namespace droidinput = android;
3987+
3988+namespace mir
3989+{
3990+class MainLoop;
3991+namespace time
3992+{
3993+class Alarm;
3994+}
3995+namespace compositor
3996+{
3997+class Scene;
3998+}
3999+namespace scene
4000+{
4001+class InputRegistrar;
4002+}
4003+namespace input
4004+{
4005+class InputReport;
4006+namespace android
4007+{
4008+class InputSendEntry;
4009+class Surface;
4010+
4011+class InputSender : public input::InputSender
4012+{
4013+public:
4014+ InputSender(std::shared_ptr<compositor::Scene> const& scene,
4015+ std::shared_ptr<MainLoop> const& main_loop,
4016+ std::shared_ptr<InputSendObserver> const& observer,
4017+ std::shared_ptr<InputReport> const& report);
4018+
4019+ void send_event(MirEvent const& event, std::shared_ptr<InputChannel> const& channel) override;
4020+
4021+private:
4022+ struct InputSenderState;
4023+
4024+ class SceneObserver : public scene::NullObserver
4025+ {
4026+ public:
4027+ explicit SceneObserver(InputSenderState & state);
4028+ private:
4029+ void surface_added(scene::Surface* surface) override;
4030+ void surface_removed(scene::Surface* surface) override;
4031+ void surface_exists(scene::Surface* surface) override;
4032+
4033+ void remove_transfer_for(input::Surface* surface);
4034+ InputSenderState & state;
4035+ };
4036+
4037+ class ActiveTransfer
4038+ {
4039+ public:
4040+ ActiveTransfer(InputSenderState & state, int server_fd, input::Surface* surface);
4041+ ~ActiveTransfer();
4042+ void send(InputSendEntry && item);
4043+ bool used_for_surface(input::Surface const* surface) const;
4044+ void on_surface_disappeared();
4045+
4046+ private:
4047+ void subscribe();
4048+ void unsubscribe();
4049+ void on_finish_signal();
4050+ void on_response_timeout();
4051+ void update_timer();
4052+ void cancel_timer();
4053+ droidinput::status_t send_key_event(uint32_t sequence_id, MirKeyEvent const& event);
4054+ droidinput::status_t send_motion_event(uint32_t sequence_id, MirMotionEvent const& event);
4055+ void process_and_submit_result(std::shared_ptr<InputSendObserver> const& observer, std::shared_ptr<InputReport> const& report);
4056+ InputSendEntry unqueue_entry(uint32_t sequence_id);
4057+ void enqueue_entry(InputSendEntry && entry);
4058+
4059+ InputSenderState & state;
4060+ droidinput::InputPublisher publisher;
4061+ input::Surface * surface;
4062+ std::vector<InputSendEntry> pending_responses;
4063+ std::mutex transfer_mutex;
4064+ std::unique_ptr<time::Alarm> send_timer;
4065+
4066+ ActiveTransfer& operator=(ActiveTransfer const&) = delete;
4067+ ActiveTransfer(ActiveTransfer const&) = delete;
4068+ };
4069+
4070+ struct InputSenderState
4071+ {
4072+ InputSenderState(std::shared_ptr<MainLoop> const& main_loop,
4073+ std::shared_ptr<InputSendObserver> const& observer,
4074+ std::shared_ptr<InputReport> const& report);
4075+ void send_event(std::shared_ptr<InputChannel> const& channel, MirEvent const& event);
4076+ void add_transfer(int fd, input::Surface* surface);
4077+ void remove_transfer(int fd);
4078+
4079+ std::shared_ptr<MainLoop> const main_loop;
4080+ std::shared_ptr<InputReport> const report;
4081+ std::shared_ptr<InputSendObserver> const observer;
4082+
4083+ private:
4084+ std::shared_ptr<ActiveTransfer> get_transfer(int fd);
4085+ uint32_t next_seq();
4086+ uint32_t seq;
4087+
4088+ std::unordered_map<int,std::shared_ptr<ActiveTransfer>> transfers;
4089+ std::mutex sender_mutex;
4090+ };
4091+
4092+ InputSenderState state;
4093+ std::shared_ptr<compositor::Scene> scene;
4094+};
4095+
4096+}
4097+}
4098+}
4099+
4100+#endif
4101
4102=== added file 'src/server/input/cursor_controller.cpp'
4103--- src/server/input/cursor_controller.cpp 1970-01-01 00:00:00 +0000
4104+++ src/server/input/cursor_controller.cpp 2014-06-27 09:18:41 +0000
4105@@ -0,0 +1,244 @@
4106+/*
4107+ * Copyright © 2014 Canonical Ltd.
4108+ *
4109+ * This program is free software: you can redistribute it and/or modify it
4110+ * under the terms of the GNU General Public License version 3,
4111+ * as published by the Free Software Foundation.
4112+ *
4113+ * This program is distributed in the hope that it will be useful,
4114+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4115+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4116+ * GNU General Public License for more details.
4117+ *
4118+ * You should have received a copy of the GNU General Public License
4119+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4120+ *
4121+ * Authored by: Robert Carr <robert.carr@canonical.com>
4122+ */
4123+
4124+#include "cursor_controller.h"
4125+
4126+#include "mir/input/input_targets.h"
4127+#include "mir/input/surface.h"
4128+#include "mir/graphics/cursor.h"
4129+#include "mir/scene/observer.h"
4130+#include "mir/scene/surface_observer.h"
4131+#include "mir/scene/surface.h"
4132+
4133+#include <functional>
4134+#include <mutex>
4135+#include <map>
4136+
4137+#include <assert.h>
4138+
4139+namespace mi = mir::input;
4140+namespace mg = mir::graphics;
4141+namespace ms = mir::scene;
4142+namespace geom = mir::geometry;
4143+
4144+namespace
4145+{
4146+
4147+struct UpdateCursorOnSurfaceChanges : ms::SurfaceObserver
4148+{
4149+ UpdateCursorOnSurfaceChanges(mi::CursorController* cursor_controller)
4150+ : cursor_controller(cursor_controller)
4151+ {
4152+ }
4153+
4154+ void attrib_changed(MirSurfaceAttrib, int) override
4155+ {
4156+ // Attribute changing alone wont trigger a cursor update
4157+ }
4158+ void resized_to(geom::Size const&) override
4159+ {
4160+ cursor_controller->update_cursor_image();
4161+ }
4162+ void moved_to(geom::Point const&) override
4163+ {
4164+ cursor_controller->update_cursor_image();
4165+ }
4166+ void hidden_set_to(bool) override
4167+ {
4168+ cursor_controller->update_cursor_image();
4169+ }
4170+ void frame_posted(int) override
4171+ {
4172+ // Frame posting wont trigger a cursor update
4173+ }
4174+ void alpha_set_to(float) override
4175+ {
4176+ cursor_controller->update_cursor_image();
4177+ }
4178+ void transformation_set_to(glm::mat4 const&) override
4179+ {
4180+ cursor_controller->update_cursor_image();
4181+ }
4182+ void reception_mode_set_to(mi::InputReceptionMode) override
4183+ {
4184+ cursor_controller->update_cursor_image();
4185+ }
4186+ void cursor_image_set_to(mg::CursorImage const&) override
4187+ {
4188+ cursor_controller->update_cursor_image();
4189+ }
4190+ void orientation_set_to(MirOrientation /* orientation */) override
4191+ {
4192+ // No need to update cursor for orientation property change alone.
4193+ }
4194+
4195+ mi::CursorController* const cursor_controller;
4196+};
4197+
4198+struct UpdateCursorOnSceneChanges : ms::Observer
4199+{
4200+ UpdateCursorOnSceneChanges(mi::CursorController* cursor_controller)
4201+ : cursor_controller(cursor_controller)
4202+ {
4203+ }
4204+
4205+ void add_surface_observer(ms::Surface* surface)
4206+ {
4207+ auto const observer = std::make_shared<UpdateCursorOnSurfaceChanges>(cursor_controller);
4208+ surface->add_observer(observer);
4209+
4210+ {
4211+ std::unique_lock<decltype(surface_observers_guard)> lg(surface_observers_guard);
4212+ surface_observers[surface] = observer;
4213+ }
4214+ }
4215+
4216+ void surface_added(ms::Surface *surface)
4217+ {
4218+ add_surface_observer(surface);
4219+ cursor_controller->update_cursor_image();
4220+ }
4221+ void surface_removed(ms::Surface *surface)
4222+ {
4223+ {
4224+ std::unique_lock<decltype(surface_observers_guard)> lg(surface_observers_guard);
4225+ auto it = surface_observers.find(surface);
4226+ if (it != surface_observers.end())
4227+ {
4228+ surface->remove_observer(it->second);
4229+ surface_observers.erase(it);
4230+ }
4231+ }
4232+ cursor_controller->update_cursor_image();
4233+ }
4234+ void surfaces_reordered()
4235+ {
4236+ cursor_controller->update_cursor_image();
4237+ }
4238+
4239+ void surface_exists(ms::Surface *surface)
4240+ {
4241+ add_surface_observer(surface);
4242+ cursor_controller->update_cursor_image();
4243+ }
4244+
4245+ void end_observation()
4246+ {
4247+ std::unique_lock<decltype(surface_observers_guard)> lg(surface_observers_guard);
4248+ for (auto &kv : surface_observers)
4249+ {
4250+ auto surface = kv.first;
4251+ if (surface)
4252+ surface->remove_observer(kv.second);
4253+ }
4254+ surface_observers.clear();
4255+ }
4256+
4257+private:
4258+ mi::CursorController* const cursor_controller;
4259+
4260+ std::mutex surface_observers_guard;
4261+ std::map<ms::Surface*, std::weak_ptr<ms::SurfaceObserver>> surface_observers;
4262+};
4263+
4264+std::shared_ptr<mi::Surface> topmost_surface_containing_point(
4265+ std::shared_ptr<mi::InputTargets> const& targets, geom::Point const& point)
4266+{
4267+ std::shared_ptr<mi::Surface> top_surface_at_point;
4268+ targets->for_each([&top_surface_at_point, &point]
4269+ (std::shared_ptr<mi::Surface> const& surface)
4270+ {
4271+ if (surface->input_area_contains(point))
4272+ top_surface_at_point = surface;
4273+ });
4274+ return top_surface_at_point;
4275+}
4276+
4277+}
4278+
4279+mi::CursorController::CursorController(std::shared_ptr<mi::InputTargets> const& input_targets,
4280+ std::shared_ptr<mg::Cursor> const& cursor,
4281+ std::shared_ptr<mg::CursorImage> const& default_cursor_image) :
4282+ input_targets(input_targets),
4283+ cursor(cursor),
4284+ default_cursor_image(default_cursor_image),
4285+ current_cursor(default_cursor_image)
4286+{
4287+ // TODO: Add observer could return weak_ptr to eliminate this
4288+ // pattern
4289+ auto strong_observer = std::make_shared<UpdateCursorOnSceneChanges>(this);
4290+ input_targets->add_observer(strong_observer);
4291+ observer = strong_observer;
4292+}
4293+
4294+mi::CursorController::~CursorController()
4295+{
4296+ try
4297+ {
4298+ input_targets->remove_observer(observer);
4299+ }
4300+ catch (...)
4301+ {
4302+ std::terminate();
4303+ }
4304+}
4305+
4306+void mi::CursorController::set_cursor_image_locked(std::lock_guard<std::mutex> const&,
4307+ std::shared_ptr<mg::CursorImage> const& image)
4308+{
4309+ if (current_cursor == image)
4310+ {
4311+ return;
4312+ }
4313+
4314+ current_cursor = image;
4315+ if (image)
4316+ cursor->show(*image);
4317+ else
4318+ cursor->hide();
4319+}
4320+
4321+void mi::CursorController::update_cursor_image_locked(std::lock_guard<std::mutex> const& lg)
4322+{
4323+ auto surface = topmost_surface_containing_point(input_targets, cursor_location);
4324+ if (surface)
4325+ {
4326+ set_cursor_image_locked(lg, surface->cursor_image());
4327+ }
4328+ else
4329+ {
4330+ set_cursor_image_locked(lg, default_cursor_image);
4331+ }
4332+}
4333+
4334+void mi::CursorController::update_cursor_image()
4335+{
4336+ std::lock_guard<std::mutex> lg(cursor_state_guard);
4337+ update_cursor_image_locked(lg);
4338+}
4339+
4340+void mi::CursorController::cursor_moved_to(float abs_x, float abs_y)
4341+{
4342+ std::lock_guard<std::mutex> lg(cursor_state_guard);
4343+
4344+ cursor_location = geom::Point{geom::X{abs_x}, geom::Y{abs_y}};
4345+
4346+ update_cursor_image_locked(lg);
4347+
4348+ cursor->move_to(cursor_location);
4349+}
4350
4351=== added file 'src/server/input/cursor_controller.h'
4352--- src/server/input/cursor_controller.h 1970-01-01 00:00:00 +0000
4353+++ src/server/input/cursor_controller.h 2014-06-27 09:18:41 +0000
4354@@ -0,0 +1,77 @@
4355+/*
4356+ * Copyright © 2014 Canonical Ltd.
4357+ *
4358+ * This program is free software: you can redistribute it and/or modify it
4359+ * under the terms of the GNU General Public License version 3,
4360+ * as published by the Free Software Foundation.
4361+ *
4362+ * This program is distributed in the hope that it will be useful,
4363+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4364+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4365+ * GNU General Public License for more details.
4366+ *
4367+ * You should have received a copy of the GNU General Public License
4368+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4369+ *
4370+ * Authored by: Robert Carr <robert.carr@canonical.com>
4371+ */
4372+
4373+#ifndef MIR_INPUT_CURSOR_CONTROLLER_H_
4374+#define MIR_INPUT_CURSOR_CONTROLLER_H_
4375+
4376+#include "mir/input/cursor_listener.h"
4377+#include "mir/geometry/point.h"
4378+
4379+#include <memory>
4380+#include <mutex>
4381+
4382+namespace mir
4383+{
4384+namespace graphics
4385+{
4386+class Cursor;
4387+class CursorImage;
4388+}
4389+namespace scene
4390+{
4391+class Observer;
4392+}
4393+
4394+namespace input
4395+{
4396+class InputTargets;
4397+
4398+class CursorController : public CursorListener
4399+{
4400+public:
4401+ CursorController(std::shared_ptr<InputTargets> const& input_targets,
4402+ std::shared_ptr<graphics::Cursor> const& cursor,
4403+ std::shared_ptr<graphics::CursorImage> const& default_cursor_image);
4404+ virtual ~CursorController();
4405+
4406+ void cursor_moved_to(float abs_x, float abs_y);
4407+
4408+ // Trigger an update of the cursor image without cursor motion, e.g.
4409+ // in response to scene changes.
4410+ void update_cursor_image();
4411+
4412+private:
4413+ std::shared_ptr<InputTargets> const input_targets;
4414+ std::shared_ptr<graphics::Cursor> const cursor;
4415+ std::shared_ptr<graphics::CursorImage> const default_cursor_image;
4416+
4417+ std::mutex cursor_state_guard;
4418+ geometry::Point cursor_location;
4419+ std::shared_ptr<graphics::CursorImage> current_cursor;
4420+
4421+ std::weak_ptr<scene::Observer> observer;
4422+
4423+
4424+ void update_cursor_image_locked(std::lock_guard<std::mutex> const&);
4425+ void set_cursor_image_locked(std::lock_guard<std::mutex> const&, std::shared_ptr<graphics::CursorImage> const& image);
4426+};
4427+
4428+}
4429+}
4430+
4431+#endif // MIR_INPUT_CURSOR_CONTROLLER_H_
4432
4433=== modified file 'src/server/input/default_configuration.cpp'
4434--- src/server/input/default_configuration.cpp 2014-06-06 10:03:54 +0000
4435+++ src/server/input/default_configuration.cpp 2014-06-27 09:18:41 +0000
4436@@ -24,18 +24,24 @@
4437 #include "android/android_input_registrar.h"
4438 #include "android/android_input_target_enumerator.h"
4439 #include "android/event_filter_dispatcher_policy.h"
4440+#include "android/input_sender.h"
4441+#include "android/input_channel_factory.h"
4442 #include "display_input_region.h"
4443 #include "event_filter_chain.h"
4444 #include "nested_input_configuration.h"
4445 #include "null_input_configuration.h"
4446+#include "cursor_controller.h"
4447 #include "null_input_dispatcher.h"
4448 #include "null_input_targeter.h"
4449+#include "null_input_send_observer.h"
4450+#include "null_input_channel_factory.h"
4451
4452 #include "mir/input/android/default_android_input_configuration.h"
4453 #include "mir/options/configuration.h"
4454 #include "mir/options/option.h"
4455 #include "mir/compositor/scene.h"
4456 #include "mir/report/legacy_input_report.h"
4457+#include "mir/main_loop.h"
4458
4459 #include <InputDispatcher.h>
4460
4461@@ -120,6 +126,27 @@
4462 });
4463 }
4464
4465+std::shared_ptr<mi::InputSender>
4466+mir::DefaultServerConfiguration::the_input_sender()
4467+{
4468+ return input_sender(
4469+ [this]()
4470+ {
4471+ return std::make_shared<mia::InputSender>(the_scene(), the_main_loop(), the_input_send_observer(), the_input_report());
4472+ });
4473+}
4474+
4475+std::shared_ptr<mi::InputSendObserver>
4476+mir::DefaultServerConfiguration::the_input_send_observer()
4477+{
4478+ return input_send_observer(
4479+ [this]()
4480+ {
4481+ return std::make_shared<mi::NullInputSendObserver>();
4482+ });
4483+}
4484+
4485+
4486 std::shared_ptr<msh::InputTargeter>
4487 mir::DefaultServerConfiguration::the_input_targeter()
4488 {
4489@@ -190,7 +217,21 @@
4490
4491 std::shared_ptr<mi::InputChannelFactory> mir::DefaultServerConfiguration::the_input_channel_factory()
4492 {
4493- return the_input_configuration()->the_input_channel_factory();
4494-}
4495-
4496-
4497+ auto const options = the_options();
4498+ if (!options->get<bool>(options::enable_input_opt))
4499+ return std::make_shared<mi::NullInputChannelFactory>();
4500+ else
4501+ return std::make_shared<mia::InputChannelFactory>();
4502+}
4503+
4504+std::shared_ptr<mi::CursorListener>
4505+mir::DefaultServerConfiguration::the_cursor_listener()
4506+{
4507+ return cursor_listener(
4508+ [this]() -> std::shared_ptr<mi::CursorListener>
4509+ {
4510+ return std::make_shared<mi::CursorController>(the_input_targets(),
4511+ the_cursor(), the_default_cursor_image());
4512+ });
4513+
4514+}
4515
4516=== modified file 'src/server/input/nested_input_configuration.cpp'
4517--- src/server/input/nested_input_configuration.cpp 2014-06-02 17:07:02 +0000
4518+++ src/server/input/nested_input_configuration.cpp 2014-06-27 09:18:41 +0000
4519@@ -27,15 +27,6 @@
4520 namespace mi = mir::input;
4521 namespace mia = mir::input::android;
4522
4523-mi::NestedInputConfiguration::NestedInputConfiguration()
4524-{
4525-}
4526-
4527-std::shared_ptr<mi::InputChannelFactory> mi::NestedInputConfiguration::the_input_channel_factory()
4528-{
4529- return std::make_shared<mia::InputChannelFactory>();
4530-}
4531-
4532 std::shared_ptr<mi::InputManager> mi::NestedInputConfiguration::the_input_manager()
4533 {
4534 return input_manager(
4535
4536=== modified file 'src/server/input/nested_input_configuration.h'
4537--- src/server/input/nested_input_configuration.h 2014-06-02 17:07:02 +0000
4538+++ src/server/input/nested_input_configuration.h 2014-06-27 09:18:41 +0000
4539@@ -27,14 +27,11 @@
4540 {
4541 namespace input
4542 {
4543-class NestedInputRelay;
4544-
4545 class NestedInputConfiguration : public InputConfiguration
4546 {
4547 public:
4548- NestedInputConfiguration();
4549+ NestedInputConfiguration() = default;
4550 virtual ~NestedInputConfiguration() = default;
4551- std::shared_ptr<InputChannelFactory> the_input_channel_factory() override;
4552 std::shared_ptr<InputManager> the_input_manager() override;
4553
4554 private:
4555
4556=== added file 'src/server/input/null_input_channel_factory.cpp'
4557--- src/server/input/null_input_channel_factory.cpp 1970-01-01 00:00:00 +0000
4558+++ src/server/input/null_input_channel_factory.cpp 2014-06-27 09:18:41 +0000
4559@@ -0,0 +1,44 @@
4560+/*
4561+ * Copyright © 2014 Canonical Ltd.
4562+ *
4563+ * This program is free software: you can redistribute it and/or modify it
4564+ * under the terms of the GNU General Public License version 3,
4565+ * as published by the Free Software Foundation.
4566+ *
4567+ * This program is distributed in the hope that it will be useful,
4568+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4569+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4570+ * GNU General Public License for more details.
4571+ *
4572+ * You should have received a copy of the GNU General Public License
4573+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4574+ *
4575+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
4576+ */
4577+
4578+#include "null_input_channel_factory.h"
4579+
4580+#include "mir/input/input_channel.h"
4581+
4582+namespace mi = mir::input;
4583+
4584+namespace
4585+{
4586+class NullInputChannel : public mi::InputChannel
4587+{
4588+ int client_fd() const override
4589+ {
4590+ return -1;
4591+ }
4592+ int server_fd() const override
4593+ {
4594+ return -1;
4595+ }
4596+};
4597+}
4598+
4599+std::shared_ptr<mi::InputChannel> mi::NullInputChannelFactory::make_input_channel()
4600+{
4601+ return std::make_shared<NullInputChannel>();
4602+}
4603+
4604
4605=== added file 'src/server/input/null_input_channel_factory.h'
4606--- src/server/input/null_input_channel_factory.h 1970-01-01 00:00:00 +0000
4607+++ src/server/input/null_input_channel_factory.h 2014-06-27 09:18:41 +0000
4608@@ -0,0 +1,38 @@
4609+/*
4610+ * Copyright © 2014 Canonical Ltd.
4611+ *
4612+ * This program is free software: you can redistribute it and/or modify it
4613+ * under the terms of the GNU General Public License version 3,
4614+ * as published by the Free Software Foundation.
4615+ *
4616+ * This program is distributed in the hope that it will be useful,
4617+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4618+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4619+ * GNU General Public License for more details.
4620+ *
4621+ * You should have received a copy of the GNU General Public License
4622+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4623+ *
4624+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
4625+ */
4626+
4627+#ifndef MIR_INPUT_NULL_INPUT_CHANNEL_FACTORY_H_
4628+#define MIR_INPUT_NULL_INPUT_CHANNEL_FACTORY_H_
4629+
4630+#include "mir/input/input_channel_factory.h"
4631+
4632+namespace mir
4633+{
4634+namespace input
4635+{
4636+class InputChannel;
4637+
4638+class NullInputChannelFactory : public mir::input::InputChannelFactory
4639+{
4640+ std::shared_ptr<mir::input::InputChannel> make_input_channel() override;
4641+};
4642+
4643+}
4644+}
4645+
4646+#endif
4647
4648=== modified file 'src/server/input/null_input_configuration.cpp'
4649--- src/server/input/null_input_configuration.cpp 2014-06-02 17:07:02 +0000
4650+++ src/server/input/null_input_configuration.cpp 2014-06-27 09:18:41 +0000
4651@@ -19,43 +19,9 @@
4652 #include "null_input_configuration.h"
4653 #include "null_input_manager.h"
4654
4655-#include "mir/input/input_channel_factory.h"
4656-#include "mir/input/input_channel.h"
4657-
4658 namespace mi = mir::input;
4659
4660-namespace
4661-{
4662-
4663-class NullInputChannel : public mi::InputChannel
4664-{
4665- int client_fd() const override
4666- {
4667- return 0;
4668- }
4669- int server_fd() const override
4670- {
4671- return 0;
4672- }
4673-};
4674-
4675-class NullInputChannelFactory : public mi::InputChannelFactory
4676-{
4677- std::shared_ptr<mi::InputChannel> make_input_channel() override
4678- {
4679- return std::make_shared<NullInputChannel>();
4680- }
4681-};
4682-
4683-}
4684-
4685-std::shared_ptr<mi::InputChannelFactory> mi::NullInputConfiguration::the_input_channel_factory()
4686-{
4687- return std::make_shared<NullInputChannelFactory>();
4688-}
4689-
4690 std::shared_ptr<mi::InputManager> mi::NullInputConfiguration::the_input_manager()
4691 {
4692 return std::make_shared<NullInputManager>();
4693 }
4694-
4695
4696=== modified file 'src/server/input/null_input_configuration.h'
4697--- src/server/input/null_input_configuration.h 2014-06-02 17:07:02 +0000
4698+++ src/server/input/null_input_configuration.h 2014-06-27 09:18:41 +0000
4699@@ -33,7 +33,6 @@
4700 NullInputConfiguration() = default;
4701 virtual ~NullInputConfiguration() = default;
4702
4703- std::shared_ptr<input::InputChannelFactory> the_input_channel_factory() override;
4704 std::shared_ptr<input::InputManager> the_input_manager() override;
4705
4706 protected:
4707
4708=== added file 'src/server/input/null_input_send_observer.h'
4709--- src/server/input/null_input_send_observer.h 1970-01-01 00:00:00 +0000
4710+++ src/server/input/null_input_send_observer.h 2014-06-27 09:18:41 +0000
4711@@ -0,0 +1,47 @@
4712+/*
4713+ * Copyright © 2014 Canonical Ltd.
4714+ *
4715+ * This program is free software: you can redistribute it and/or modify it
4716+ * under the terms of the GNU General Public License version 3,
4717+ * as published by the Free Software Foundation.
4718+ *
4719+ * This program is distributed in the hope that it will be useful,
4720+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4721+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4722+ * GNU General Public License for more details.
4723+ *
4724+ * You should have received a copy of the GNU General Public License
4725+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4726+ *
4727+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
4728+ */
4729+
4730+#ifndef MIR_INPUT_NULL_INPUT_SEND_OBSERVER_H_
4731+#define MIR_INPUT_NULL_INPUT_SEND_OBSERVER_H_
4732+
4733+#include "mir/input/input_send_observer.h"
4734+
4735+namespace mir
4736+{
4737+namespace input
4738+{
4739+
4740+class NullInputSendObserver : public InputSendObserver
4741+{
4742+public:
4743+ void send_failed(MirEvent const& /*event*/, input::Surface* /*surface*/, FailureReason /*reason*/) override
4744+ {
4745+ }
4746+
4747+ void send_suceeded(MirEvent const& /*event*/, input::Surface* /*surface*/, InputResponse /*response*/) override
4748+ {
4749+ }
4750+
4751+ void client_blocked(MirEvent const& /*event*/, input::Surface* /*client*/) override
4752+ {
4753+ }
4754+};
4755+
4756+}
4757+}
4758+#endif
4759
4760=== modified file 'src/server/scene/CMakeLists.txt'
4761--- src/server/scene/CMakeLists.txt 2014-06-12 10:24:08 +0000
4762+++ src/server/scene/CMakeLists.txt 2014-06-27 09:18:41 +0000
4763@@ -22,4 +22,5 @@
4764 legacy_surface_change_notification.cpp
4765 prompt_session_container.cpp
4766 prompt_session_manager_impl.cpp
4767+ rendering_tracker.cpp
4768 )
4769
4770=== modified file 'src/server/scene/basic_surface.cpp'
4771--- src/server/scene/basic_surface.cpp 2014-06-12 15:35:08 +0000
4772+++ src/server/scene/basic_surface.cpp 2014-06-27 09:18:41 +0000
4773@@ -23,6 +23,7 @@
4774 #include "mir/frontend/event_sink.h"
4775 #include "mir/input/input_channel.h"
4776 #include "mir/shell/input_targeter.h"
4777+#include "mir/input/input_sender.h"
4778 #include "mir/graphics/buffer.h"
4779
4780 #include "mir/scene/scene_report.h"
4781@@ -88,6 +89,14 @@
4782 p->alpha_set_to(alpha);
4783 }
4784
4785+void ms::SurfaceObservers::orientation_set_to(MirOrientation orientation)
4786+{
4787+ std::unique_lock<decltype(mutex)> lock(mutex);
4788+ // TBD Maybe we should copy observers so we can release the lock?
4789+ for (auto const& p : observers)
4790+ p->orientation_set_to(orientation);
4791+}
4792+
4793 void ms::SurfaceObservers::transformation_set_to(glm::mat4 const& t)
4794 {
4795 std::unique_lock<decltype(mutex)> lock(mutex);
4796@@ -133,6 +142,7 @@
4797 bool nonrectangular,
4798 std::shared_ptr<mc::BufferStream> const& buffer_stream,
4799 std::shared_ptr<mi::InputChannel> const& input_channel,
4800+ std::shared_ptr<input::InputSender> const& input_sender,
4801 std::shared_ptr<SurfaceConfigurator> const& configurator,
4802 std::shared_ptr<mg::CursorImage> const& cursor_image,
4803 std::shared_ptr<SceneReport> const& report) :
4804@@ -146,11 +156,13 @@
4805 input_rectangles{geom::Rectangle{geom::Point{0, 0}, surface_rect.size}},
4806 surface_buffer_stream(buffer_stream),
4807 server_input_channel(input_channel),
4808+ input_sender(input_sender),
4809 configurator(configurator),
4810 cursor_image_(cursor_image),
4811 report(report),
4812 type_value(mir_surface_type_normal),
4813 state_value(mir_surface_state_restored),
4814+ visibility_value(mir_surface_visibility_exposed),
4815 dpi_value(0)
4816 {
4817 report->surface_created(this, surface_name);
4818@@ -340,6 +352,10 @@
4819 observers.alpha_set_to(alpha);
4820 }
4821
4822+void ms::BasicSurface::set_orientation(MirOrientation orientation)
4823+{
4824+ observers.orientation_set_to(orientation);
4825+}
4826
4827 void ms::BasicSurface::set_transformation(glm::mat4 const& t)
4828 {
4829@@ -431,6 +447,7 @@
4830 {
4831 int result = 0;
4832 bool allow_dropping = false;
4833+
4834 /*
4835 * TODO: In future, query the shell implementation for the subset of
4836 * attributes/types it implements.
4837@@ -463,6 +480,10 @@
4838 BOOST_THROW_EXCEPTION(std::logic_error("Invalid DPI value"));
4839 result = dpi();
4840 break;
4841+ case mir_surface_attrib_visibility:
4842+ set_visibility(static_cast<MirSurfaceVisibility>(value));
4843+ result = visibility_value;
4844+ break;
4845 default:
4846 BOOST_THROW_EXCEPTION(std::logic_error("Invalid surface "
4847 "attribute."));
4848@@ -486,13 +507,16 @@
4849
4850 void ms::BasicSurface::set_cursor_image(std::shared_ptr<mg::CursorImage> const& image)
4851 {
4852+ {
4853 std::unique_lock<std::mutex> lock(guard);
4854 cursor_image_ = image;
4855+ }
4856
4857- observers.cursor_image_set_to(*image);
4858+ observers.cursor_image_set_to(*image);
4859 }
4860
4861-std::shared_ptr<mg::CursorImage> ms::BasicSurface::cursor_image()
4862+
4863+std::shared_ptr<mg::CursorImage> ms::BasicSurface::cursor_image() const
4864 {
4865 std::unique_lock<std::mutex> lock(guard);
4866 return cursor_image_;
4867@@ -518,6 +542,21 @@
4868 return valid;
4869 }
4870
4871+void ms::BasicSurface::set_visibility(MirSurfaceVisibility new_visibility)
4872+{
4873+ if (new_visibility != mir_surface_visibility_occluded &&
4874+ new_visibility != mir_surface_visibility_exposed)
4875+ {
4876+ BOOST_THROW_EXCEPTION(std::logic_error("Invalid visibility value"));
4877+ }
4878+
4879+ if (visibility_value != new_visibility)
4880+ {
4881+ visibility_value = new_visibility;
4882+ observers.attrib_changed(mir_surface_attrib_visibility, visibility_value);
4883+ }
4884+}
4885+
4886 void ms::BasicSurface::add_observer(std::shared_ptr<SurfaceObserver> const& observer)
4887 {
4888 observers.add(observer);
4889@@ -626,3 +665,8 @@
4890 nonrectangular,
4891 this));
4892 }
4893+
4894+void ms::BasicSurface::consume(MirEvent const& event)
4895+{
4896+ input_sender->send_event(event, server_input_channel);
4897+}
4898
4899=== modified file 'src/server/scene/basic_surface.h'
4900--- src/server/scene/basic_surface.h 2014-06-12 15:35:08 +0000
4901+++ src/server/scene/basic_surface.h 2014-06-27 09:18:41 +0000
4902@@ -47,6 +47,7 @@
4903 namespace input
4904 {
4905 class InputChannel;
4906+class InputSender;
4907 class Surface;
4908 }
4909 namespace scene
4910@@ -64,6 +65,7 @@
4911 void hidden_set_to(bool hide) override;
4912 void frame_posted(int frames_available) override;
4913 void alpha_set_to(float alpha) override;
4914+ void orientation_set_to(MirOrientation orientation) override;
4915 void transformation_set_to(glm::mat4 const& t) override;
4916 void reception_mode_set_to(input::InputReceptionMode mode) override;
4917 void cursor_image_set_to(graphics::CursorImage const& image) override;
4918@@ -85,6 +87,7 @@
4919 bool nonrectangular,
4920 std::shared_ptr<compositor::BufferStream> const& buffer_stream,
4921 std::shared_ptr<input::InputChannel> const& input_channel,
4922+ std::shared_ptr<input::InputSender> const& sender,
4923 std::shared_ptr<SurfaceConfigurator> const& configurator,
4924 std::shared_ptr<graphics::CursorImage> const& cursor_image,
4925 std::shared_ptr<SceneReport> const& report);
4926@@ -120,7 +123,9 @@
4927 geometry::Point top_left() const override;
4928 geometry::Rectangle input_bounds() const override;
4929 bool input_area_contains(geometry::Point const& point) const override;
4930+ void consume(MirEvent const& event);
4931 void set_alpha(float alpha) override;
4932+ void set_orientation(MirOrientation orientation) override;
4933 void set_transformation(glm::mat4 const&) override;
4934
4935 bool visible() const;
4936@@ -138,7 +143,7 @@
4937 void show() override;
4938
4939 void set_cursor_image(std::shared_ptr<graphics::CursorImage> const& image);
4940- std::shared_ptr<graphics::CursorImage> cursor_image();
4941+ std::shared_ptr<graphics::CursorImage> cursor_image() const;
4942
4943 void add_observer(std::shared_ptr<SurfaceObserver> const& observer) override;
4944 void remove_observer(std::weak_ptr<SurfaceObserver> const& observer) override;
4945@@ -150,6 +155,7 @@
4946 bool set_type(MirSurfaceType t); // Use configure() to make public changes
4947 bool set_state(MirSurfaceState s);
4948 bool set_dpi(int);
4949+ void set_visibility(MirSurfaceVisibility v);
4950
4951 SurfaceObservers observers;
4952 std::mutex mutable guard;
4953@@ -164,12 +170,14 @@
4954 std::vector<geometry::Rectangle> input_rectangles;
4955 std::shared_ptr<compositor::BufferStream> const surface_buffer_stream;
4956 std::shared_ptr<input::InputChannel> const server_input_channel;
4957+ std::shared_ptr<input::InputSender> const input_sender;
4958 std::shared_ptr<SurfaceConfigurator> const configurator;
4959 std::shared_ptr<graphics::CursorImage> cursor_image_;
4960 std::shared_ptr<SceneReport> const report;
4961
4962 MirSurfaceType type_value;
4963 MirSurfaceState state_value;
4964+ MirSurfaceVisibility visibility_value;
4965 int dpi_value;
4966 };
4967
4968
4969=== modified file 'src/server/scene/default_configuration.cpp'
4970--- src/server/scene/default_configuration.cpp 2014-06-11 16:11:32 +0000
4971+++ src/server/scene/default_configuration.cpp 2014-06-27 09:18:41 +0000
4972@@ -72,6 +72,7 @@
4973 return std::make_shared<ms::SurfaceAllocator>(
4974 the_buffer_stream_factory(),
4975 the_input_channel_factory(),
4976+ the_input_sender(),
4977 the_surface_configurator(),
4978 the_default_cursor_image(),
4979 the_scene_report());
4980
4981=== modified file 'src/server/scene/legacy_surface_change_notification.cpp'
4982--- src/server/scene/legacy_surface_change_notification.cpp 2014-06-12 15:35:08 +0000
4983+++ src/server/scene/legacy_surface_change_notification.cpp 2014-06-27 09:18:41 +0000
4984@@ -56,6 +56,11 @@
4985 notify_scene_change();
4986 }
4987
4988+// An orientation change alone is not enough to trigger recomposition.
4989+void ms::LegacySurfaceChangeNotification::orientation_set_to(MirOrientation /*orientation*/)
4990+{
4991+}
4992+
4993 void ms::LegacySurfaceChangeNotification::transformation_set_to(glm::mat4 const& /*t*/)
4994 {
4995 notify_scene_change();
4996
4997=== modified file 'src/server/scene/legacy_surface_change_notification.h'
4998--- src/server/scene/legacy_surface_change_notification.h 2014-06-12 15:35:08 +0000
4999+++ src/server/scene/legacy_surface_change_notification.h 2014-06-27 09:18:41 +0000
5000@@ -42,6 +42,7 @@
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches