Mir

Merge lp:mir/0.14 into lp:mir/ubuntu

Proposed by Andreas Pokorny
Status: Merged
Approved by: Andreas Pokorny
Approved revision: 2721
Merged at revision: 1235
Proposed branch: lp:mir/0.14
Merge into: lp:mir/ubuntu
Diff against target: 44395 lines (+16262/-13651)
521 files modified
3rd_party/android-input/android/frameworks/base/services/input/InputDevice.cpp (+29/-24)
CMakeLists.txt (+10/-8)
benchmarks/android-input/CMakeLists.txt (+1/-1)
benchmarks/benchmark_multiplexing_dispatchable.cpp (+1/-1)
benchmarks/frame-uniformity/CMakeLists.txt (+5/-1)
cmake/ABICheck.cmake (+5/-5)
cmake/MirCommon.cmake (+97/-129)
cmake/src/mir/CMakeLists.txt (+10/-10)
cmake/src/mir/mir_discover_gtest_tests.cpp (+0/-408)
cmake/src/mir/mir_test_fd_leak.cpp (+6/-0)
cmake/src/mir/mir_test_tmpfile.cpp (+14/-0)
cross-compile-chroot.sh (+1/-1)
debian/changelog (+85/-0)
debian/control (+55/-44)
debian/create_postinst_prerm_scripts.sh (+3/-3)
debian/install_ld_so_conf.sh (+3/-4)
debian/libmirclient9.install (+1/-1)
debian/libmircommon5.install (+1/-1)
debian/libmirplatform8.install (+1/-1)
debian/libmirserver32.install (+1/-1)
debian/mir-demos.install (+2/-1)
debian/mir-platform-graphics-android3.install (+1/-1)
debian/mir-platform-graphics-mesa-kms3.install (+1/-1)
debian/mir-test-tools.install (+2/-0)
debian/mir-utils.install (+1/-0)
debian/rules (+13/-19)
doc/building_source_for_arm.md (+38/-50)
doc/kernel_requirements.md (+1/-1)
examples/CMakeLists.txt (+34/-0)
examples/basic.c (+2/-2)
examples/client_helpers.cpp (+204/-0)
examples/client_helpers.h (+110/-0)
examples/client_touch_validator.cpp (+200/-0)
examples/eglsquare.cpp (+20/-208)
examples/flicker.c (+2/-2)
examples/mir_demo_server_loader.cpp (+46/-0)
examples/render_surfaces.cpp (+16/-9)
examples/server_example_basic_window_manager.h (+7/-0)
examples/server_example_canonical_window_manager.cpp (+425/-161)
examples/server_example_canonical_window_manager.h (+37/-12)
examples/server_example_tiling_window_manager.cpp (+26/-0)
examples/server_example_window_management.cpp (+10/-1)
examples/target.c (+74/-28)
guides/cppguide.xml (+16/-1)
include/client/mir/events/event_builders.h (+9/-5)
include/client/mir_toolkit/client_types.h (+17/-2)
include/client/mir_toolkit/events/event.h (+14/-1)
include/client/mir_toolkit/events/input/pointer_event.h (+15/-5)
include/client/mir_toolkit/events/input_configuration_event.h (+78/-0)
include/client/mir_toolkit/mir_client_library_drm.h (+0/-59)
include/client/mir_toolkit/mir_connection.h (+0/-6)
include/client/mir_toolkit/mir_screencast.h (+0/-7)
include/client/mir_toolkit/mir_surface.h (+140/-135)
include/client/mir_toolkit/version.h (+1/-1)
include/common/mir/dispatch/action_queue.h (+1/-1)
include/common/mir/dispatch/threaded_dispatcher.h (+27/-9)
include/common/mir/optional_value.h (+10/-1)
include/platform/mir/graphics/display_buffer.h (+0/-6)
include/platform/mir/graphics/platform.h (+2/-2)
include/platform/mir/input/device_capability.h (+1/-0)
include/platform/mir/input/input_sink.h (+12/-0)
include/platform/mir/input/platform.h (+13/-0)
include/server/mir/frontend/surface.h (+3/-3)
include/server/mir/input/input_dispatcher.h (+2/-9)
include/server/mir/scene/buffer_stream_factory.h (+2/-0)
include/server/mir/scene/session.h (+3/-0)
include/server/mir/scene/surface.h (+14/-9)
include/server/mir/scene/surface_buffer_access.h (+0/-50)
include/server/mir/scene/surface_coordinator.h (+6/-2)
include/server/mir/scene/surface_factory.h (+4/-1)
include/server/mir/server.h (+8/-0)
include/server/mir/shell/persistent_surface_store.h (+131/-0)
include/server/mir/shell/surface_ready_observer.h (+58/-0)
include/server/mir/shell/surface_specification.h (+17/-5)
include/server/mir/shell/system_compositor_window_manager.h (+99/-0)
include/server/mir/time/alarm.h (+0/-1)
include/test/mir_test/event_matchers.h (+84/-28)
include/test/mir_test_doubles/mock_egl.h (+1/-1)
include/test/mir_test_doubles/mock_input_dispatcher.h (+1/-3)
include/test/mir_test_doubles/nested_mock_egl.h (+44/-0)
include/test/mir_test_doubles/null_display.h (+3/-3)
include/test/mir_test_doubles/null_display_buffer.h (+0/-1)
include/test/mir_test_doubles/null_display_sync_group.h (+2/-2)
include/test/mir_test_doubles/null_platform.h (+2/-2)
include/test/mir_test_doubles/wrap_shell_to_track_latest_surface.h (+50/-0)
include/test/mir_test_framework/fake_input_device.h (+12/-1)
include/test/mir_test_framework/placement_applying_shell.h (+59/-0)
include/test/mir_test_framework/server_runner.h (+4/-1)
playground/demo-shell/CMakeLists.txt (+1/-0)
playground/demo-shell/default_window_manager.cpp (+65/-72)
playground/demo-shell/default_window_manager.h (+13/-13)
playground/demo-shell/demo_compositor.cpp (+0/-10)
playground/demo-shell/demo_renderer.cpp (+1/-3)
playground/demo-shell/demo_renderer.h (+0/-1)
playground/demo-shell/demo_shell.cpp (+30/-8)
playground/demo-shell/window_manager.cpp (+407/-322)
playground/demo-shell/window_manager.h (+3/-0)
playground/server_configuration.cpp (+8/-0)
playground/server_configuration.h (+5/-0)
src/CMakeLists.txt (+1/-1)
src/client/CMakeLists.txt (+2/-2)
src/client/buffer_stream.cpp (+27/-36)
src/client/buffer_stream.h (+7/-4)
src/client/client_buffer_stream_factory.h (+12/-7)
src/client/connection_surface_map.h (+14/-5)
src/client/default_client_buffer_stream_factory.cpp (+23/-15)
src/client/default_client_buffer_stream_factory.h (+11/-7)
src/client/default_connection_configuration.cpp (+0/-19)
src/client/event.cpp (+27/-0)
src/client/events/event_builders.cpp (+56/-191)
src/client/input/android/CMakeLists.txt (+1/-0)
src/client/input/android/android_input_lexicon.cpp (+50/-57)
src/client/input/android/android_input_receiver.cpp (+8/-10)
src/client/input/android/event_conversion_helpers.cpp (+302/-0)
src/client/input/input_event.cpp (+21/-147)
src/client/input/xkb_mapper.cpp (+4/-7)
src/client/mir_buffer_stream_api.cpp (+6/-28)
src/client/mir_connection.cpp (+95/-25)
src/client/mir_connection.h (+23/-5)
src/client/mir_connection_api.cpp (+1/-175)
src/client/mir_prompt_session.cpp (+7/-7)
src/client/mir_screencast.cpp (+14/-10)
src/client/mir_screencast.h (+2/-3)
src/client/mir_screencast_api.cpp (+1/-6)
src/client/mir_surface.cpp (+77/-17)
src/client/mir_surface.h (+19/-3)
src/client/mir_surface_api.cpp (+109/-152)
src/client/rpc/mir_basic_rpc_channel.cpp (+7/-2)
src/client/rpc/mir_basic_rpc_channel.h (+6/-4)
src/client/rpc/mir_protobuf_rpc_channel.cpp (+55/-22)
src/client/rpc/mir_protobuf_rpc_channel.h (+31/-12)
src/client/surface_map.cpp (+61/-12)
src/client/surface_map.h (+6/-1)
src/client/symbols-debug.map (+1/-1)
src/client/symbols.map (+102/-124)
src/common/CMakeLists.txt (+3/-1)
src/common/dispatch/CMakeLists.txt (+1/-2)
src/common/dispatch/action_queue.cpp (+23/-12)
src/common/dispatch/threaded_dispatcher.cpp (+258/-129)
src/common/logging/shared_library_prober_report.cpp (+5/-4)
src/common/sharedlibrary/shared_library.cpp (+1/-1)
src/common/symbols.map (+10/-6)
src/include/common/mir/events/event_private.h (+28/-112)
src/include/common/mir/input/android/android_input_lexicon.h (+2/-1)
src/include/common/mir/input/android/event_conversion_helpers.h (+60/-0)
src/include/common/mir/make_protobuf_object.h (+2/-5)
src/include/common/mir/protobuf/google_protobuf_guard.h (+0/-40)
src/include/platform/mir/graphics/tessellation_helpers.h (+3/-1)
src/include/platform/mir/options/configuration.h (+3/-0)
src/include/platform/mir/options/default_configuration.h (+10/-4)
src/include/server/mir/compositor/buffer_stream.h (+3/-7)
src/include/server/mir/compositor/destination_alpha.h (+0/-36)
src/include/server/mir/compositor/gl_renderer.h (+1/-7)
src/include/server/mir/compositor/renderer_factory.h (+1/-3)
src/include/server/mir/default_server_configuration.h (+14/-17)
src/include/server/mir/frontend/shell.h (+2/-0)
src/include/server/mir/frontend/template_protobuf_message_processor.h (+2/-1)
src/include/server/mir/input/legacy_input_dispatchable.h (+38/-0)
src/include/server/mir/scene/placement_strategy.h (+0/-45)
src/include/server/mir/scene/surface_observers.h (+54/-0)
src/include/server/mir/shell/basic_window_manager.h (+1/-1)
src/include/server/mir/shell/canonical_window_manager.h (+24/-11)
src/platform/CMakeLists.txt (+0/-2)
src/platform/graphics/tessellation_helpers.cpp (+5/-2)
src/platform/options/default_configuration.cpp (+54/-28)
src/platform/symbols.map (+2/-5)
src/platforms/CMakeLists.txt (+3/-3)
src/platforms/android/server/android_alloc_adaptor.cpp (+5/-2)
src/platforms/android/server/configurable_display_buffer.h (+1/-1)
src/platforms/android/server/display.cpp (+15/-4)
src/platforms/android/server/display.h (+1/-0)
src/platforms/android/server/display_buffer.cpp (+9/-10)
src/platforms/android/server/display_buffer.h (+3/-2)
src/platforms/android/server/display_device.h (+2/-0)
src/platforms/android/server/display_group.cpp (+4/-2)
src/platforms/android/server/display_group.h (+2/-1)
src/platforms/android/server/hal_component_factory.cpp (+9/-4)
src/platforms/android/server/hwc_device.cpp (+1/-1)
src/platforms/android/server/hwc_fallback_gl_renderer.cpp (+2/-2)
src/platforms/android/server/hwc_fallback_gl_renderer.h (+3/-2)
src/platforms/android/server/hwc_layerlist.cpp (+10/-5)
src/platforms/android/server/hwc_layerlist.h (+4/-2)
src/platforms/android/server/symbols.map (+1/-1)
src/platforms/mesa/client/client_platform.cpp (+15/-0)
src/platforms/mesa/server/CMakeLists.txt (+5/-0)
src/platforms/mesa/server/common/CMakeLists.txt (+17/-0)
src/platforms/mesa/server/common/buffer_allocator.h (+1/-1)
src/platforms/mesa/server/common/platform_common.h (+38/-0)
src/platforms/mesa/server/kms/CMakeLists.txt (+16/-22)
src/platforms/mesa/server/kms/display_buffer.cpp (+31/-59)
src/platforms/mesa/server/kms/display_buffer.h (+2/-2)
src/platforms/mesa/server/kms/guest_platform.cpp (+0/-1)
src/platforms/mesa/server/kms/platform.cpp (+16/-1)
src/platforms/mesa/server/kms/platform.h (+1/-5)
src/platforms/mesa/server/kms/symbols.map (+1/-1)
src/protobuf/CMakeLists.txt (+1/-1)
src/protobuf/google_protobuf_guard.cpp (+20/-24)
src/protobuf/mir_protobuf.proto (+29/-1)
src/server/CMakeLists.txt (+3/-1)
src/server/compositor/buffer_queue.cpp (+1/-1)
src/server/compositor/buffer_stream_factory.cpp (+17/-6)
src/server/compositor/buffer_stream_factory.h (+6/-3)
src/server/compositor/buffer_stream_surfaces.cpp (+51/-15)
src/server/compositor/buffer_stream_surfaces.h (+16/-5)
src/server/compositor/default_configuration.cpp (+4/-2)
src/server/compositor/default_display_buffer_compositor_factory.cpp (+1/-4)
src/server/compositor/gl_renderer.cpp (+10/-25)
src/server/compositor/gl_renderer_factory.cpp (+2/-3)
src/server/compositor/gl_renderer_factory.h (+1/-2)
src/server/compositor/screencast_display_buffer.cpp (+0/-5)
src/server/compositor/screencast_display_buffer.h (+0/-2)
src/server/display_server.cpp (+21/-22)
src/server/frontend/event_sender.cpp (+19/-18)
src/server/frontend/protobuf_connection_creator.cpp (+0/-1)
src/server/frontend/protobuf_message_processor.cpp (+28/-10)
src/server/frontend/protobuf_responder.cpp (+10/-6)
src/server/frontend/protobuf_responder.h (+1/-1)
src/server/frontend/session_mediator.cpp (+299/-306)
src/server/frontend/session_mediator.h (+33/-3)
src/server/frontend/shell_wrapper.cpp (+5/-0)
src/server/frontend/shell_wrapper.h (+2/-0)
src/server/frontend/socket_connection.cpp (+7/-6)
src/server/graphics/default_configuration.cpp (+5/-6)
src/server/graphics/nested/display_buffer.cpp (+18/-16)
src/server/graphics/nested/display_buffer.h (+0/-2)
src/server/graphics/offscreen/display_buffer.cpp (+0/-5)
src/server/graphics/offscreen/display_buffer.h (+0/-1)
src/server/input/CMakeLists.txt (+4/-1)
src/server/input/android/CMakeLists.txt (+0/-7)
src/server/input/android/android_input_application_handle.cpp (+0/-44)
src/server/input/android/android_input_application_handle.h (+0/-57)
src/server/input/android/android_input_dispatcher.cpp (+0/-150)
src/server/input/android/android_input_dispatcher.h (+0/-64)
src/server/input/android/android_input_registrar.cpp (+0/-129)
src/server/input/android/android_input_registrar.h (+0/-94)
src/server/input/android/android_input_target_enumerator.cpp (+0/-50)
src/server/input/android/android_input_target_enumerator.h (+0/-67)
src/server/input/android/android_input_targeter.cpp (+0/-63)
src/server/input/android/android_input_window_handle.cpp (+0/-102)
src/server/input/android/android_input_window_handle.h (+0/-62)
src/server/input/android/android_window_handle_repository.h (+0/-59)
src/server/input/android/default_dispatcher_policy.h (+5/-8)
src/server/input/android/event_filter_dispatcher_policy.cpp (+0/-100)
src/server/input/android/input_reader_dispatchable.h (+3/-3)
src/server/input/android/input_sender.cpp (+31/-20)
src/server/input/android/input_sender.h (+0/-1)
src/server/input/android/input_translator.cpp (+82/-118)
src/server/input/default_configuration.cpp (+66/-91)
src/server/input/default_input_device_hub.cpp (+79/-9)
src/server/input/default_input_device_hub.h (+22/-3)
src/server/input/default_input_manager.cpp (+20/-9)
src/server/input/default_input_manager.h (+7/-17)
src/server/input/event_filter_chain.cpp (+0/-54)
src/server/input/event_filter_chain.h (+0/-47)
src/server/input/event_filter_chain_dispatcher.cpp (+82/-0)
src/server/input/event_filter_chain_dispatcher.h (+60/-0)
src/server/input/key_repeat_dispatcher.cpp (+147/-0)
src/server/input/key_repeat_dispatcher.h (+75/-0)
src/server/input/null_input_dispatcher.cpp (+3/-11)
src/server/input/null_input_dispatcher.h (+2/-3)
src/server/input/surface_input_dispatcher.cpp (+474/-0)
src/server/input/surface_input_dispatcher.h (+114/-0)
src/server/input/vt_filter.cpp (+3/-3)
src/server/report/logging/input_report.cpp (+80/-2)
src/server/scene/CMakeLists.txt (+0/-1)
src/server/scene/application_session.cpp (+75/-48)
src/server/scene/application_session.h (+7/-2)
src/server/scene/basic_surface.cpp (+61/-76)
src/server/scene/basic_surface.h (+6/-33)
src/server/scene/default_configuration.cpp (+1/-2)
src/server/scene/legacy_scene_change_notification.cpp (+11/-3)
src/server/scene/session_manager.cpp (+8/-6)
src/server/scene/session_manager.h (+3/-0)
src/server/scene/snapshot_strategy.h (+2/-2)
src/server/scene/surface_allocator.cpp (+3/-13)
src/server/scene/surface_allocator.h (+9/-10)
src/server/scene/surface_controller.cpp (+5/-5)
src/server/scene/surface_controller.h (+4/-2)
src/server/scene/surface_stack.cpp (+13/-8)
src/server/scene/surfaceless_buffer_stream.cpp (+0/-84)
src/server/scene/surfaceless_buffer_stream.h (+0/-59)
src/server/scene/threaded_snapshot_strategy.cpp (+6/-9)
src/server/scene/threaded_snapshot_strategy.h (+1/-1)
src/server/server.cpp (+6/-23)
src/server/shell/CMakeLists.txt (+4/-2)
src/server/shell/abstract_shell.cpp (+30/-24)
src/server/shell/canonical_window_manager.cpp (+324/-124)
src/server/shell/default_configuration.cpp (+13/-15)
src/server/shell/default_persistent_surface_store.cpp (+91/-0)
src/server/shell/default_persistent_surface_store.h (+44/-0)
src/server/shell/default_placement_strategy.cpp (+0/-57)
src/server/shell/default_placement_strategy.h (+0/-52)
src/server/shell/frontend_shell.cpp (+15/-1)
src/server/shell/frontend_shell.h (+10/-2)
src/server/shell/persistent_surface_store.cpp (+79/-0)
src/server/shell/surface_ready_observer.cpp (+45/-0)
src/server/shell/system_compositor_window_manager.cpp (+151/-0)
src/server/symbols.map (+70/-10)
src/utils/CMakeLists.txt (+6/-0)
src/utils/backlight.sh (+33/-0)
tests/CMakeLists.txt (+20/-8)
tests/acceptance-tests/CMakeLists.txt (+7/-1)
tests/acceptance-tests/server_configuration_options.cpp (+12/-0)
tests/acceptance-tests/test_buffer_stream_arrangement.cpp (+237/-0)
tests/acceptance-tests/test_client_input.cpp (+582/-47)
tests/acceptance-tests/test_client_library.cpp (+44/-61)
tests/acceptance-tests/test_client_surface_events.cpp (+5/-21)
tests/acceptance-tests/test_custom_input_dispatcher.cpp (+98/-0)
tests/acceptance-tests/test_nested_input.cpp (+174/-0)
tests/acceptance-tests/test_nested_mir.cpp (+55/-52)
tests/acceptance-tests/test_session_mediator_report.cpp (+150/-0)
tests/acceptance-tests/test_shell_control_of_surface_configuration.cpp (+1/-1)
tests/acceptance-tests/test_surface_modifications.cpp (+9/-30)
tests/acceptance-tests/test_surface_morphing.cpp (+396/-0)
tests/acceptance-tests/test_surface_placement.cpp (+214/-26)
tests/acceptance-tests/test_surfaces_with_output_id.cpp (+6/-1)
tests/acceptance-tests/test_system_compositor_window_manager.cpp (+205/-0)
tests/acceptance-tests/throwback/CMakeLists.txt (+1/-3)
tests/acceptance-tests/throwback/clients.cpp (+0/-39)
tests/acceptance-tests/throwback/clients.h (+0/-39)
tests/acceptance-tests/throwback/test_client_cursor_api.cpp (+14/-5)
tests/acceptance-tests/throwback/test_client_input.cpp (+0/-704)
tests/acceptance-tests/throwback/test_custom_input_dispatcher.cpp (+0/-182)
tests/acceptance-tests/throwback/test_focus_selection.cpp (+72/-79)
tests/acceptance-tests/throwback/test_touchspot_visualization.cpp (+44/-64)
tests/client-language/c99.c (+0/-1)
tests/include/mir_test/gmock_fixes.h (+1/-1)
tests/include/mir_test/test_protobuf_client.h (+3/-3)
tests/include/mir_test_doubles/mock_buffer_bundle.h (+5/-4)
tests/include/mir_test_doubles/mock_buffer_stream.h (+18/-2)
tests/include/mir_test_doubles/mock_client_buffer_stream_factory.h (+8/-5)
tests/include/mir_test_doubles/mock_display_buffer.h (+0/-1)
tests/include/mir_test_doubles/mock_event_hub.h (+1/-0)
tests/include/mir_test_doubles/mock_frontend_surface.h (+3/-5)
tests/include/mir_test_doubles/mock_legacy_input_dispatchable.h (+41/-0)
tests/include/mir_test_doubles/mock_renderable_list_compositor.h (+2/-2)
tests/include/mir_test_doubles/mock_scene_session.h (+2/-0)
tests/include/mir_test_doubles/mock_shell.h (+2/-0)
tests/include/mir_test_doubles/mock_surface.h (+12/-1)
tests/include/mir_test_doubles/mock_surface_coordinator.h (+2/-3)
tests/include/mir_test_doubles/mock_virtual_terminal.h (+1/-1)
tests/include/mir_test_doubles/null_display_changer.h (+1/-1)
tests/include/mir_test_doubles/null_snapshot_strategy.h (+1/-1)
tests/include/mir_test_doubles/null_virtual_terminal.h (+1/-1)
tests/include/mir_test_doubles/stub_buffer_stream.h (+16/-21)
tests/include/mir_test_doubles/stub_buffer_stream_factory.h (+5/-2)
tests/include/mir_test_doubles/stub_client_buffer_stream_factory.h (+7/-3)
tests/include/mir_test_doubles/stub_display.h (+4/-4)
tests/include/mir_test_doubles/stub_display_builder.h (+4/-3)
tests/include/mir_test_doubles/stub_gbm_native_buffer.h (+1/-1)
tests/include/mir_test_doubles/stub_legacy_input_dispatchable.h (+52/-0)
tests/include/mir_test_doubles/stub_renderable_list_compositor.h (+4/-1)
tests/include/mir_test_doubles/stub_renderer.h (+3/-0)
tests/include/mir_test_doubles/stub_scene_session.h (+4/-0)
tests/include/mir_test_doubles/stub_scene_surface.h (+4/-8)
tests/include/mir_test_doubles/stub_surface_factory.h (+48/-0)
tests/include/mir_test_framework/client_platform_factory.h (+1/-1)
tests/include/mir_test_framework/declarative_placement_window_manage_policy.h (+18/-22)
tests/include/mir_test_framework/display_server_test_fixture.h (+0/-91)
tests/include/mir_test_framework/fake_event_hub_server_configuration.h (+5/-6)
tests/include/mir_test_framework/input_testing_server_configuration.h (+0/-22)
tests/include/mir_test_framework/stubbed_server_configuration.h (+1/-1)
tests/integration-tests/CMakeLists.txt (+8/-5)
tests/integration-tests/client/test_screencast.cpp (+4/-3)
tests/integration-tests/compositor/test_buffer_stream.cpp (+1/-2)
tests/integration-tests/frontend/CMakeLists.txt (+0/-9)
tests/integration-tests/frontend/test_session_mediator_report.cpp (+0/-538)
tests/integration-tests/graphics/mesa/CMakeLists.txt (+1/-1)
tests/integration-tests/input/CMakeLists.txt (+1/-5)
tests/integration-tests/input/android/CMakeLists.txt (+0/-10)
tests/integration-tests/input/android/test_android_input_manager.cpp (+0/-333)
tests/integration-tests/input/test_configuring_input_manager.cpp (+44/-29)
tests/integration-tests/input/test_cursor_listener.cpp (+21/-30)
tests/integration-tests/input/test_nested_input.cpp (+0/-83)
tests/integration-tests/surface_composition.cpp (+2/-2)
tests/integration-tests/test_default_window_manager.cpp (+0/-181)
tests/integration-tests/test_display_info.cpp (+28/-121)
tests/integration-tests/test_display_server_main_loop_events.cpp (+96/-163)
tests/integration-tests/test_drm_auth_magic.cpp (+0/-152)
tests/integration-tests/test_error_reporting.cpp (+62/-178)
tests/integration-tests/test_exchange_buffer.cpp (+116/-24)
tests/integration-tests/test_server_shutdown.cpp (+132/-278)
tests/integration-tests/test_session.cpp (+6/-3)
tests/integration-tests/test_stale_frames.cpp (+1/-1)
tests/integration-tests/test_surface_first_frame_sync.cpp (+116/-246)
tests/integration-tests/test_surface_stack_with_compositor.cpp (+17/-15)
tests/integration-tests/test_swapinterval.cpp (+127/-192)
tests/integration-tests/test_test_framework.cpp (+0/-38)
tests/loader-tests/CMakeLists.txt (+33/-0)
tests/loader-tests/test_reload.c (+49/-0)
tests/mir_test_doubles/CMakeLists.txt (+8/-2)
tests/mir_test_doubles/nested_mock_egl.cpp (+66/-0)
tests/mir_test_doubles/platform_factory.cpp (+1/-1)
tests/mir_test_doubles/test_protobuf_client.cpp (+2/-2)
tests/mir_test_framework/CMakeLists.txt (+6/-2)
tests/mir_test_framework/async_server_runner.cpp (+1/-1)
tests/mir_test_framework/command_line_server_configuration.cpp (+2/-1)
tests/mir_test_framework/declarative_placement_window_manage_policy.cpp (+14/-12)
tests/mir_test_framework/display_server_test_fixture.cpp (+0/-120)
tests/mir_test_framework/fake_event_hub_server_configuration.cpp (+13/-14)
tests/mir_test_framework/fake_input_device_impl.cpp (+168/-16)
tests/mir_test_framework/fake_input_device_impl.h (+23/-8)
tests/mir_test_framework/headless_test.cpp (+1/-0)
tests/mir_test_framework/input_testing_server_options.cpp (+0/-17)
tests/mir_test_framework/placement_applying_shell.cpp (+59/-0)
tests/mir_test_framework/server_runner.cpp (+6/-3)
tests/mir_test_framework/stubbed_server_configuration.cpp (+12/-11)
tests/mir_test_framework/symbols-server.map (+1/-1)
tests/privileged-tests/CMakeLists.txt (+28/-0)
tests/privileged-tests/README (+2/-0)
tests/privileged-tests/test_input_events.cpp (+290/-0)
tests/privileged-tests/ui_get_sysname_ioctl_override.cpp (+125/-0)
tests/unit-tests/CMakeLists.txt (+19/-3)
tests/unit-tests/android_input/property_map.cpp (+2/-2)
tests/unit-tests/android_input/test_eventhub.cpp (+10/-9)
tests/unit-tests/client/CMakeLists.txt (+2/-1)
tests/unit-tests/client/input/test_android_input_receiver.cpp (+25/-2)
tests/unit-tests/client/input/test_xkb_mapper.cpp (+20/-41)
tests/unit-tests/client/mesa/CMakeLists.txt (+10/-1)
tests/unit-tests/client/test_client_buffer_stream.cpp (+3/-2)
tests/unit-tests/client/test_client_mir_surface.cpp (+1/-1)
tests/unit-tests/client/test_client_platform.cpp (+1/-1)
tests/unit-tests/client/test_connection_resource_map.cpp (+69/-0)
tests/unit-tests/client/test_mir_connection.cpp (+6/-1)
tests/unit-tests/client/test_mir_screencast.cpp (+12/-11)
tests/unit-tests/client/test_probing_client_platform_factory.cpp (+2/-2)
tests/unit-tests/client/test_protobuf_rpc_channel.cpp (+299/-63)
tests/unit-tests/compositor/test_buffer_queue.cpp (+2/-2)
tests/unit-tests/compositor/test_buffer_stream.cpp (+46/-2)
tests/unit-tests/compositor/test_gl_program_family.cpp (+0/-49)
tests/unit-tests/compositor/test_gl_renderer.cpp (+6/-18)
tests/unit-tests/compositor/test_screencast_display_buffer.cpp (+0/-9)
tests/unit-tests/dispatch/CMakeLists.txt (+1/-1)
tests/unit-tests/dispatch/test_action_queue.cpp (+8/-2)
tests/unit-tests/dispatch/test_multiplexing_dispatchable.cpp (+15/-10)
tests/unit-tests/dispatch/test_threaded_dispatcher.cpp (+215/-87)
tests/unit-tests/examples/test_demo_renderer.cpp (+1/-3)
tests/unit-tests/frontend/test_event_sender.cpp (+1/-1)
tests/unit-tests/frontend/test_session_mediator.cpp (+111/-48)
tests/unit-tests/graphics/CMakeLists.txt (+1/-1)
tests/unit-tests/graphics/android/test_android_alloc_adaptor.cpp (+1/-1)
tests/unit-tests/graphics/android/test_display.cpp (+29/-0)
tests/unit-tests/graphics/android/test_display_buffer.cpp (+33/-18)
tests/unit-tests/graphics/android/test_display_group.cpp (+4/-4)
tests/unit-tests/graphics/android/test_display_hotplug.cpp (+2/-1)
tests/unit-tests/graphics/android/test_fb_device.cpp (+2/-2)
tests/unit-tests/graphics/android/test_hwc_device.cpp (+46/-43)
tests/unit-tests/graphics/android/test_hwc_fallback_gl_renderer.cpp (+30/-4)
tests/unit-tests/graphics/android/test_hwc_fb_device.cpp (+2/-2)
tests/unit-tests/graphics/android/test_hwc_layerlist.cpp (+50/-14)
tests/unit-tests/graphics/android/test_hwc_layers.cpp (+54/-0)
tests/unit-tests/graphics/mesa/CMakeLists.txt (+9/-20)
tests/unit-tests/graphics/mesa/common/CMakeLists.txt (+14/-0)
tests/unit-tests/graphics/mesa/common/test_anonymous_shm_file.cpp (+1/-1)
tests/unit-tests/graphics/mesa/common/test_buffer_allocator.cpp (+2/-2)
tests/unit-tests/graphics/mesa/common/test_drm_helper.cpp (+1/-1)
tests/unit-tests/graphics/mesa/common/test_gbm_buffer.cpp (+3/-2)
tests/unit-tests/graphics/mesa/common/test_ipc_operations.cpp (+2/-2)
tests/unit-tests/graphics/mesa/common/test_shm_buffer.cpp (+2/-2)
tests/unit-tests/graphics/mesa/kms/CMakeLists.txt (+21/-0)
tests/unit-tests/graphics/mesa/kms/mock_kms_output.h (+1/-1)
tests/unit-tests/graphics/mesa/kms/test_bypass.cpp (+1/-1)
tests/unit-tests/graphics/mesa/kms/test_cursor.cpp (+4/-4)
tests/unit-tests/graphics/mesa/kms/test_display.cpp (+3/-3)
tests/unit-tests/graphics/mesa/kms/test_display_buffer.cpp (+51/-18)
tests/unit-tests/graphics/mesa/kms/test_display_configuration.cpp (+2/-2)
tests/unit-tests/graphics/mesa/kms/test_guest_platform.cpp (+1/-1)
tests/unit-tests/graphics/mesa/kms/test_kms_page_flipper.cpp (+1/-1)
tests/unit-tests/graphics/mesa/kms/test_linux_virtual_terminal.cpp (+1/-1)
tests/unit-tests/graphics/mesa/kms/test_nested_authentication.cpp (+1/-1)
tests/unit-tests/graphics/mesa/kms/test_platform.cpp (+3/-3)
tests/unit-tests/graphics/mesa/kms/test_real_kms_output.cpp (+2/-2)
tests/unit-tests/graphics/nested/CMakeLists.txt (+0/-1)
tests/unit-tests/graphics/nested/test_nested_display.cpp (+20/-0)
tests/unit-tests/graphics/nested/test_nested_display_buffer.cpp (+0/-87)
tests/unit-tests/graphics/test_platform_prober.cpp (+5/-5)
tests/unit-tests/graphics/test_program_factory.cpp (+0/-1)
tests/unit-tests/input/CMakeLists.txt (+3/-1)
tests/unit-tests/input/android/CMakeLists.txt (+0/-8)
tests/unit-tests/input/android/test_android_input_application_handle.cpp (+0/-51)
tests/unit-tests/input/android/test_android_input_dispatcher.cpp (+0/-272)
tests/unit-tests/input/android/test_android_input_lexicon.cpp (+63/-126)
tests/unit-tests/input/android/test_android_input_registrar.cpp (+0/-118)
tests/unit-tests/input/android/test_android_input_sender.cpp (+101/-56)
tests/unit-tests/input/android/test_android_input_target_enumerator.cpp (+0/-119)
tests/unit-tests/input/android/test_android_input_targeter.cpp (+0/-105)
tests/unit-tests/input/android/test_android_input_window_handle.cpp (+0/-119)
tests/unit-tests/input/android/test_event_filter_input_dispatcher_policy.cpp (+0/-69)
tests/unit-tests/input/android/test_input_dispatcher.cpp (+0/-125)
tests/unit-tests/input/android/test_input_translator.cpp (+66/-144)
tests/unit-tests/input/test_default_input_device_hub.cpp (+162/-22)
tests/unit-tests/input/test_default_input_manager.cpp (+13/-9)
tests/unit-tests/input/test_event_builders.cpp (+53/-4)
tests/unit-tests/input/test_event_filter_chain.cpp (+0/-105)
tests/unit-tests/input/test_event_filter_chain_dispatcher.cpp (+124/-0)
tests/unit-tests/input/test_input_event.cpp (+25/-101)
tests/unit-tests/input/test_key_repeat_dispatcher.cpp (+122/-0)
tests/unit-tests/input/test_surface_input_dispatcher.cpp (+646/-0)
tests/unit-tests/scene/test_abstract_shell.cpp (+19/-10)
tests/unit-tests/scene/test_application_session.cpp (+152/-69)
tests/unit-tests/scene/test_basic_surface.cpp (+271/-65)
tests/unit-tests/scene/test_legacy_scene_change_notification.cpp (+8/-8)
tests/unit-tests/scene/test_session_manager.cpp (+8/-4)
tests/unit-tests/scene/test_surface.cpp (+24/-94)
tests/unit-tests/scene/test_surface_controller.cpp (+8/-11)
tests/unit-tests/scene/test_surface_impl.cpp (+8/-57)
tests/unit-tests/scene/test_surface_stack.cpp (+96/-44)
tests/unit-tests/scene/test_threaded_snapshot_strategy.cpp (+3/-19)
tests/unit-tests/shell/CMakeLists.txt (+2/-2)
tests/unit-tests/shell/test_default_persistent_surface_store.cpp (+124/-0)
tests/unit-tests/shell/test_default_placement_strategy.cpp (+0/-67)
tests/unit-tests/shell/test_default_window_manager.cpp (+0/-213)
tests/unit-tests/shell/test_persistent_surface_store_id.cpp (+88/-0)
tests/unit-tests/test_data/README (+12/-0)
tests/unit-tests/test_glib_main_loop.cpp (+45/-10)
tests/unit-tests/test_shared_library_prober.cpp (+88/-61)
tools/detect_fd_leaks.sh (+65/-0)
tools/discover_gtests.sh (+14/-5)
tools/generate-abi-base-dump.sh (+7/-0)
tools/run_abi_compliance_checker.sh (+3/-8)
tools/update_package_abis.sh (+6/-2)
To merge this branch: bzr merge lp:mir/0.14
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Daniel van Vugt Approve
Review via email: mp+262850@code.launchpad.net

Commit message

Mir 0.14.0 release

Description of the change

Mir 0.14.0 release

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I feel 0.14 isn't big enough to justify investing the time in a release just yet. There's a few branches on the horizon and still up for review that are arguably worth waiting for and getting into 0.14, for the sake of visible performance improvement and stability (yes I mean my branches).

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

Consider getting this one in too:
https://code.launchpad.net/~vanvugt/mir/fix-1391976-0.14/+merge/263068

Because I think we need that fix to be present in two consecutive releases before we can manage its ABI properly.

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

In the end it was r2718 that made it into the wily release...
https://launchpad.net/ubuntu/+source/mir

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/InputDevice.cpp'
2--- 3rd_party/android-input/android/frameworks/base/services/input/InputDevice.cpp 2014-03-06 06:05:17 +0000
3+++ 3rd_party/android-input/android/frameworks/base/services/input/InputDevice.cpp 2015-07-23 14:41:37 +0000
4@@ -86,11 +86,32 @@
5 return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type);
6 }
7
8+String8 getConfigurationFilePathInDirectory(String8 const& directory, String8 const& name, InputDeviceConfigurationFileType type)
9+{
10+ String8 path = directory;
11+ appendInputDeviceConfigurationFileRelativePath(path, name, type);
12+#if DEBUG_PROBE
13+ ALOGD("Probing for input device configuration file: path='%s'", path.c_str());
14+#endif
15+ if (!access(c_str(path), R_OK)) {
16+#if DEBUG_PROBE
17+ ALOGD("Found");
18+#endif
19+ return path;
20+ }
21+
22+ return String8();
23+}
24+
25 String8 getInputDeviceConfigurationFilePathByName(
26 const String8& name, InputDeviceConfigurationFileType type) {
27 // Search system repository.
28 String8 path;
29- // <mir modifications>
30+ setTo(path, "/usr/share/");
31+ auto result = getConfigurationFilePathInDirectory(path, name, type);
32+ if (result.length())
33+ return result;
34+
35 {
36 const char *root_env = getenv("ANDROID_ROOT");
37 if (root_env == NULL) root_env = "";
38@@ -98,38 +119,22 @@
39 }
40 // </mir modifications>
41 path.append("/usr/");
42- appendInputDeviceConfigurationFileRelativePath(path, name, type);
43-#if DEBUG_PROBE
44- ALOGD("Probing for system provided input device configuration file: path='%s'", path.c_str());
45-#endif
46- if (!access(c_str(path), R_OK)) {
47-#if DEBUG_PROBE
48- ALOGD("Found");
49-#endif
50- return path;
51- }
52+ result = getConfigurationFilePathInDirectory(path, name, type);
53+ if (result.length())
54+ return result;
55
56 // Search user repository.
57- // TODO Should only look here if not in safe mode.
58- // <mir modifications>
59+ // TODO Should only look here if not in safe mode. ( ?? ~ racarr)
60 {
61 const char *data_env = getenv("ANDROID_DATA");
62 if (data_env == NULL) data_env = "";
63 setTo(path, data_env);
64 }
65
66- // </mir modifications>
67 path.append("/system/devices/");
68- appendInputDeviceConfigurationFileRelativePath(path, name, type);
69-#if DEBUG_PROBE
70- ALOGD("Probing for system user input device configuration file: path='%s'", path.c_str());
71-#endif
72- if (!access(c_str(path), R_OK)) {
73-#if DEBUG_PROBE
74- ALOGD("Found");
75-#endif
76- return path;
77- }
78+ result = getConfigurationFilePathInDirectory(path, name, type);
79+ if (result.length())
80+ return result;
81
82 // Not found.
83 #if DEBUG_PROBE
84
85=== modified file 'CMakeLists.txt'
86--- CMakeLists.txt 2015-06-10 02:23:59 +0000
87+++ CMakeLists.txt 2015-07-23 14:41:37 +0000
88@@ -27,8 +27,8 @@
89 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
90
91 set(MIR_VERSION_MAJOR 0)
92-set(MIR_VERSION_MINOR 13) # This should change at least with every MIRSERVER_ABI
93-set(MIR_VERSION_PATCH 3)
94+set(MIR_VERSION_MINOR 14) # This should change at least with every MIRSERVER_ABI
95+set(MIR_VERSION_PATCH 0)
96
97 add_definitions(-DMIR_VERSION_MAJOR=${MIR_VERSION_MAJOR})
98 add_definitions(-DMIR_VERSION_MINOR=${MIR_VERSION_MINOR})
99@@ -143,20 +143,20 @@
100
101 add_definitions(-DMESA_EGL_NO_X11_HEADERS)
102
103-# Default to mesa backend, but build all of them
104+# Default to KMS backend, but build all of them
105 set(
106 MIR_PLATFORM
107- mesa;android
108+ mesa-kms;android
109 CACHE
110 STRING
111- "a list of graphics backends to build (options are 'mesa' or 'android')"
112+ "a list of graphics backends to build (options are 'mesa-kms' or 'android')"
113 )
114
115 list(GET MIR_PLATFORM 0 MIR_TEST_PLATFORM)
116
117 foreach(platform IN LISTS MIR_PLATFORM)
118- if (platform STREQUAL "mesa")
119- set(MIR_BUILD_PLATFORM_MESA TRUE)
120+ if (platform STREQUAL "mesa-kms")
121+ set(MIR_BUILD_PLATFORM_MESA_KMS TRUE)
122 endif()
123 if (platform STREQUAL "android")
124 set(MIR_BUILD_PLATFORM_ANDROID TRUE)
125@@ -173,6 +173,7 @@
126 find_package(LTTngUST REQUIRED)
127 pkg_check_modules(UDEV REQUIRED libudev)
128 pkg_check_modules(GLIB REQUIRED glib-2.0)
129+pkg_check_modules(UUID REQUIRED uuid)
130
131 include_directories (${GLESv2_INCLUDE_DIRS})
132 include_directories (${EGL_INCLUDE_DIRS})
133@@ -183,7 +184,7 @@
134 find_package(LibHardware REQUIRED)
135 endif()
136
137-if (MIR_BUILD_PLATFORM_MESA)
138+if (MIR_BUILD_PLATFORM_MESA_KMS)
139 find_package( PkgConfig )
140 pkg_check_modules( GBM REQUIRED gbm>=9.0.0)
141 pkg_check_modules( DRM REQUIRED libdrm )
142@@ -215,6 +216,7 @@
143
144 if (MIR_ENABLE_TESTS)
145 find_package(GtestGmock REQUIRED)
146+ pkg_check_modules(LIBEVDEV REQUIRED libevdev)
147 include_directories(${GMOCK_INCLUDE_DIR} ${GTEST_INCLUDE_DIR})
148 add_subdirectory(tests/)
149
150
151=== modified file 'benchmarks/android-input/CMakeLists.txt'
152--- benchmarks/android-input/CMakeLists.txt 2015-04-17 15:53:50 +0000
153+++ benchmarks/android-input/CMakeLists.txt 2015-07-23 14:41:37 +0000
154@@ -1,7 +1,7 @@
155 project(android-input-perf)
156
157 include_directories(
158- ${Mir_SOURCE_DIR}/tests/include
159+ ${Mir_SOURCE_DIR}/include/test
160 ${Mir_SOURCE_DIR}/include/platform
161 ${MIR_ANDROID_INCLUDE_DIRECTORIES}
162 ${MIR_3RD_PARTY_INCLUDE_DIRECTORIES}
163
164=== modified file 'benchmarks/benchmark_multiplexing_dispatchable.cpp'
165--- benchmarks/benchmark_multiplexing_dispatchable.cpp 2015-04-24 15:36:12 +0000
166+++ benchmarks/benchmark_multiplexing_dispatchable.cpp 2015-07-23 14:41:37 +0000
167@@ -17,12 +17,12 @@
168 */
169
170 #include "mir/dispatch/multiplexing_dispatchable.h"
171-#include "mir/dispatch/simple_dispatch_thread.h"
172
173 #include <iostream>
174 #include <vector>
175 #include <memory>
176 #include <chrono>
177+#include <thread>
178 #include <poll.h>
179 #include <unistd.h>
180
181
182=== modified file 'benchmarks/frame-uniformity/CMakeLists.txt'
183--- benchmarks/frame-uniformity/CMakeLists.txt 2015-04-17 16:26:59 +0000
184+++ benchmarks/frame-uniformity/CMakeLists.txt 2015-07-23 14:41:37 +0000
185@@ -3,12 +3,16 @@
186 ${PROJECT_SOURCE_DIR}/include/platform
187 ${PROJECT_SOURCE_DIR}/include/server
188 ${PROJECT_SOURCE_DIR}/include/client
189- ${PROJECT_SOURCE_DIR}/tests/include/
190+ ${PROJECT_SOURCE_DIR}/include/test
191+
192 ${PROJECT_SOURCE_DIR}/src/include/server
193 ${PROJECT_SOURCE_DIR}/src/include/common
194 ${PROJECT_SOURCE_DIR}
195 ${MIR_ANDROID_INCLUDE_DIRECTORIES}
196 ${MIR_3RD_PARTY_INCLUDE_DIRECTORIES}
197+
198+ # needed for fake_event_hub_server_configuration.h (which relies on private APIs)
199+ ${PROJECT_SOURCE_DIR}/tests/include/
200 )
201
202 mir_add_wrapped_executable(frame_uniformity_test_client NOINSTALL
203
204=== modified file 'cmake/ABICheck.cmake'
205--- cmake/ABICheck.cmake 2015-04-23 17:48:44 +0000
206+++ cmake/ABICheck.cmake 2015-07-23 14:41:37 +0000
207@@ -71,7 +71,7 @@
208 endfunction()
209
210 #These headers are not part of the libmircommon ABI
211-set(mircommon-exclude-headers "${CMAKE_SOURCE_DIR}/src/include/common/mir/graphics/android\n ${CMAKE_SOURCE_DIR}/src/include/common/mir/input")
212+set(mircommon-exclude-headers "${CMAKE_SOURCE_DIR}/src/include/common/mir/graphics/android\n ${CMAKE_SOURCE_DIR}/src/include/common/mir/input\n ${CMAKE_SOURCE_DIR}/src/include/common/mir/events")
213
214 #These headers are not part of the libmirplatform ABI
215 set(mirplatform-exclude-headers "${CMAKE_SOURCE_DIR}/include/platform/mir/input")
216@@ -80,9 +80,9 @@
217 make_lib_descriptor(server)
218 make_lib_descriptor(common INCLUDE_PRIVATE EXCLUDE_HEADERS ${mircommon-exclude-headers})
219 make_lib_descriptor(platform INCLUDE_PRIVATE EXCLUDE_HEADERS ${mirplatform-exclude-headers})
220-if(MIR_BUILD_PLATFORM_MESA)
221+if(MIR_BUILD_PLATFORM_MESA_KMS)
222 make_lib_descriptor(clientplatformmesa LIBRARY_HEADER ${CMAKE_SOURCE_DIR}/src/include/client/mir/client_platform_factory.h)
223-make_lib_descriptor(platformgraphicsmesa LIBRARY_HEADER ${CMAKE_SOURCE_DIR}/include/platform/mir/graphics/platform.h)
224+make_lib_descriptor(platformgraphicsmesakms LIBRARY_HEADER ${CMAKE_SOURCE_DIR}/include/platform/mir/graphics/platform.h)
225 endif()
226 if(MIR_BUILD_PLATFORM_ANDROID)
227 make_lib_descriptor(clientplatformandroid LIBRARY_HEADER ${CMAKE_SOURCE_DIR}/src/include/client/mir/client_platform_factory.h)
228@@ -125,8 +125,8 @@
229 endmacro(_define_abi_check_for)
230
231 set(the_libs mirserver mirclient mircommon mirplatform)
232-if(MIR_BUILD_PLATFORM_MESA)
233- set(the_libs ${the_libs} mirclientplatformmesa mirplatformgraphicsmesa)
234+if(MIR_BUILD_PLATFORM_MESA_KMS)
235+ set(the_libs ${the_libs} mirclientplatformmesa mirplatformgraphicsmesakms)
236 endif()
237 if(MIR_BUILD_PLATFORM_ANDROID)
238 set(the_libs ${the_libs} mirclientplatformandroid mirplatformgraphicsandroid)
239
240=== modified file 'cmake/MirCommon.cmake'
241--- cmake/MirCommon.cmake 2015-04-30 11:36:36 +0000
242+++ cmake/MirCommon.cmake 2015-07-23 14:41:37 +0000
243@@ -5,13 +5,6 @@
244 include(CMakeDependentOption)
245 file(REMOVE ${CMAKE_BINARY_DIR}/discover_all_tests.sh)
246
247-CMAKE_DEPENDENT_OPTION(
248- DISABLE_GTEST_TEST_DISCOVERY
249- "If set to ON, disables fancy test autodiscovery and switches back to classic add_test behavior"
250- OFF
251- "NOT CMAKE_CROSSCOMPILING"
252- ON)
253-
254 option(
255 ENABLE_MEMCHECK_OPTION
256 "If set to ON, enables automatic creation of memcheck targets"
257@@ -30,145 +23,120 @@
258 valgrind)
259
260 if(VALGRIND_EXECUTABLE)
261- set(VALGRIND_ARGS "--error-exitcode=1" "--trace-children=yes" "--leak-check=full" "--show-leak-kinds=definite" "--errors-for-leak-kinds=definite")
262- set(VALGRIND_ARGS ${VALGRIND_ARGS} "--suppressions=${CMAKE_SOURCE_DIR}/tools/valgrind_suppressions_generic")
263- set(VALGRIND_ARGS ${VALGRIND_ARGS} "--suppressions=${CMAKE_SOURCE_DIR}/tools/valgrind_suppressions_glibc_2.21")
264- set(DISCOVER_FLAGS "--enable-memcheck")
265- set(DISCOVER_FLAGS ${DISCOVER_FLAGS} "--suppressions=${CMAKE_SOURCE_DIR}/tools/valgrind_suppressions_generic")
266- set(DISCOVER_FLAGS ${DISCOVER_FLAGS} "--suppressions=${CMAKE_SOURCE_DIR}/tools/valgrind_suppressions_glibc_2.21")
267+ set(VALGRIND_CMD "${VALGRIND_EXECUTABLE}" "--error-exitcode=1" "--trace-children=yes")
268+ set(VALGRIND_CMD ${VALGRIND_CMD} "--leak-check=full" "--show-leak-kinds=definite" "--errors-for-leak-kinds=definite")
269+ set(VALGRIND_CMD ${VALGRIND_CMD} "--track-fds=yes")
270+ set(VALGRIND_CMD ${VALGRIND_CMD} "--suppressions=${CMAKE_SOURCE_DIR}/tools/valgrind_suppressions_generic")
271+ set(VALGRIND_CMD ${VALGRIND_CMD} "--suppressions=${CMAKE_SOURCE_DIR}/tools/valgrind_suppressions_glibc_2.21")
272 if (TARGET_ARCH STREQUAL "arm-linux-gnueabihf")
273- set(VALGRIND_ARGS ${VALGRIND_ARGS} "--suppressions=${CMAKE_SOURCE_DIR}/tools/valgrind_suppressions_armhf")
274- set(DISCOVER_FLAGS ${DISCOVER_FLAGS} "--suppressions=${CMAKE_SOURCE_DIR}/tools/valgrind_suppressions_armhf")
275+ set(VALGRIND_CMD ${VALGRIND_CMD} "--suppressions=${CMAKE_SOURCE_DIR}/tools/valgrind_suppressions_armhf")
276 endif()
277 else(VALGRIND_EXECUTABLE)
278 message("Not enabling memcheck as valgrind is missing on your system")
279 endif(VALGRIND_EXECUTABLE)
280 endif(ENABLE_MEMCHECK_OPTION)
281
282-function (mir_discover_tests EXECUTABLE)
283- if(DISABLE_GTEST_TEST_DISCOVERY)
284- execute_process(
285- COMMAND uname -r
286- OUTPUT_VARIABLE KERNEL_VERSION_FULL
287- OUTPUT_STRIP_TRAILING_WHITESPACE
288- )
289- string(REGEX MATCH "^[0-9]+[.][0-9]+" KERNEL_VERSION ${KERNEL_VERSION_FULL})
290- message(STATUS "Kernel version detected: " ${KERNEL_VERSION})
291- # Some tests expect kernel version 3.11 and up
292- if (${KERNEL_VERSION} VERSION_LESS "3.11")
293- add_test(${EXECUTABLE} ${VALGRIND_EXECUTABLE} ${VALGRIND_ARGS} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${EXECUTABLE}
294- "--gtest_filter=-*DeathTest.*:AnonymousShmFile.*:MesaBufferAllocatorTest.software_buffers_dont_bypass:MesaBufferAllocatorTest.creates_software_rendering_buffer")
295- else()
296- add_test(${EXECUTABLE} ${VALGRIND_EXECUTABLE} ${VALGRIND_ARGS} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${EXECUTABLE}
297- "--gtest_filter=-*DeathTest.*")
298- endif()
299-
300- add_test(${EXECUTABLE}_death_tests ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${EXECUTABLE} "--gtest_filter=*DeathTest.*")
301- if (${ARGC} GREATER 1)
302- set_property(TEST ${EXECUTABLE} PROPERTY ENVIRONMENT ${ARGN})
303- set_property(TEST ${EXECUTABLE}_death_tests PROPERTY ENVIRONMENT ${ARGN})
304- endif()
305- else()
306- set(CHECK_TEST_DISCOVERY_TARGET_NAME "check_discover_tests_in_${EXECUTABLE}")
307- set(TEST_DISCOVERY_TARGET_NAME "discover_tests_in_${EXECUTABLE}")
308- message(STATUS "Defining targets: ${CHECK_TEST_DISCOVERY_TARGET_NAME} and ${TEST_DISCOVERY_TARGET_NAME}")
309-
310- # These targets are always considered out-of-date, and are always run (at least for normal builds, except for make test/install).
311- add_custom_target(
312- ${CHECK_TEST_DISCOVERY_TARGET_NAME} ALL
313- ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${EXECUTABLE} --gtest_list_tests > /dev/null
314- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
315- COMMENT "Check that discovering Tests in ${EXECUTABLE} works")
316-
317- if (MIR_BUILD_PLATFORM_ANDROID)
318- add_dependencies(${CHECK_TEST_DISCOVERY_TARGET_NAME} mirplatformgraphicsandroid)
319- endif()
320-
321- if (MIR_BUILD_PLATFORM_MESA)
322- add_dependencies(${CHECK_TEST_DISCOVERY_TARGET_NAME} mirplatformgraphicsmesa)
323- endif()
324-
325- if (${ARGC} GREATER 1)
326- foreach (env ${ARGN})
327- list(APPEND EXTRA_ENV_FLAGS "--add-environment" "${env}")
328- endforeach()
329- endif()
330-
331- if(cmake_build_type_lower MATCHES "threadsanitizer")
332- find_program(LLVM_SYMBOLIZER llvm-symbolizer-3.6)
333- if (LLVM_SYMBOLIZER)
334- set(TSAN_EXTRA_OPTIONS "external_symbolizer_path=${LLVM_SYMBOLIZER}")
335- endif()
336- list(APPEND EXTRA_ENV_FLAGS "--add-environment" "TSAN_OPTIONS=suppressions=${CMAKE_SOURCE_DIR}/tools/tsan-suppressions second_deadlock_stack=1 halt_on_error=1 history_size=7 ${TSAN_EXTRA_OPTIONS}")
337- # TSan does not support multi-threaded fork
338- # TSan may open fds so "surface_creation_does_not_leak_fds" will not work as written
339- # TSan deadlocks when running StreamTransportTest/0.SendsFullMessagesWhenInterrupted - disable it until understood
340- set(EXCLUDED_TESTS "UnresponsiveClient.does_not_hang_server:DemoInProcessServerWithStubClientPlatform.surface_creation_does_not_leak_fds:StreamTransportTest/0.SendsFullMessagesWhenInterrupted")
341- endif()
342-
343- add_custom_target(
344- ${TEST_DISCOVERY_TARGET_NAME} ALL
345- ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${EXECUTABLE} --gtest_list_tests | ${CMAKE_BINARY_DIR}/mir_gtest/mir_discover_gtest_tests --executable=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${EXECUTABLE} --exclusions=${EXCLUDED_TESTS} ${DISCOVER_FLAGS}
346- ${EXTRA_ENV_FLAGS}
347- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
348- COMMENT "Discovering Tests in ${EXECUTABLE}" VERBATIM)
349-
350- add_dependencies(
351- ${CHECK_TEST_DISCOVERY_TARGET_NAME}
352- ${EXECUTABLE})
353-
354- add_dependencies(
355- ${TEST_DISCOVERY_TARGET_NAME}
356-
357- ${CHECK_TEST_DISCOVERY_TARGET_NAME}
358- ${EXECUTABLE}
359- mir_discover_gtest_tests)
360-
361- endif()
362-
363- foreach (env ${ARGN})
364- set(discover_envs "${discover_envs} --env ${env}")
365+try_run(SYSYEM_SUPPORTS_O_TMPFILE SYSTEM_HEADERS_SUPPORT_O_TMPFILE
366+ ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/cmake/src/mir/mir_test_tmpfile.cpp
367+ )
368+
369+function (list_to_string LIST_VAR PREFIX STR_VAR)
370+ foreach (value ${LIST_VAR})
371+ set(tmp_str "${tmp_str} ${PREFIX} ${value}")
372 endforeach()
373+ set(${STR_VAR} "${tmp_str}" PARENT_SCOPE)
374+endfunction()
375+
376+function (mir_discover_tests_internal EXECUTABLE DETECT_FD_LEAKS)
377+ # Set vars
378+ set(test_cmd_no_memcheck "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${EXECUTABLE}")
379+ set(test_cmd "${test_cmd_no_memcheck}")
380+ set(test_env ${ARGN})
381+ set(test_name ${EXECUTABLE})
382+ set(test_no_memcheck_filter)
383+ set(test_exclusion_filter)
384
385 if(ENABLE_MEMCHECK_OPTION)
386- set(discover_cmd_memcheck "${VALGRIND_EXECUTABLE}")
387- foreach (arg ${VALGRIND_ARGS})
388- set(discover_cmd_memcheck "${discover_cmd_memcheck} ${arg}")
389- endforeach()
390- endif()
391+ set(test_cmd ${VALGRIND_CMD} ${test_cmd_no_memcheck})
392+ set(test_no_memcheck_filter "*DeathTest.*")
393+ endif()
394+
395+ if(cmake_build_type_lower MATCHES "threadsanitizer")
396+ find_program(LLVM_SYMBOLIZER llvm-symbolizer-3.6)
397+ if (LLVM_SYMBOLIZER)
398+ set(TSAN_EXTRA_OPTIONS "external_symbolizer_path=${LLVM_SYMBOLIZER}")
399+ endif()
400+ # Space after ${TSAN_EXTRA_OPTIONS} works around bug in TSAN env. variable parsing
401+ list(APPEND test_env "TSAN_OPTIONS=\"suppressions=${CMAKE_SOURCE_DIR}/tools/tsan-suppressions second_deadlock_stack=1 halt_on_error=1 history_size=7 ${TSAN_EXTRA_OPTIONS} \"")
402+ # TSan does not support multi-threaded fork
403+ # TSan may open fds so "surface_creation_does_not_leak_fds" will not work as written
404+ # TSan deadlocks when running StreamTransportTest/0.SendsFullMessagesWhenInterrupted - disable it until understood
405+ set(test_exclusion_filter "UnresponsiveClient.does_not_hang_server:DemoInProcessServerWithStubClientPlatform.surface_creation_does_not_leak_fds:StreamTransportTest/0.SendsFullMessagesWhenInterrupted")
406+ endif()
407+
408+ if(SYSYEM_SUPPORTS_O_TMPFILE EQUAL 1)
409+ set(test_exclusion_filter "${test_exclusion_filter}:AnonymousShmFile.*:MesaBufferAllocatorTest.software_buffers_dont_bypass:MesaBufferAllocatorTest.creates_software_rendering_buffer")
410+ endif()
411+
412+ # Final commands
413+ set(test_cmd "${test_cmd}" "--gtest_filter=-${test_no_memcheck_filter}:${test_exclusion_filter}")
414+ set(test_cmd_no_memcheck "${test_cmd_no_memcheck}" "--gtest_filter=${test_no_memcheck_filter}:-${test_exclusion_filter}")
415+ if(DETECT_FD_LEAKS)
416+ set(test_cmd ${CMAKE_SOURCE_DIR}/tools/detect_fd_leaks.sh ${test_cmd})
417+ endif()
418+
419+ # Normal
420+ add_test(${test_name} ${test_cmd})
421+ set_property(TEST ${test_name} PROPERTY ENVIRONMENT ${test_env})
422+ if (test_no_memcheck_filter)
423+ add_test(${test_name}_no_memcheck ${test_cmd_no_memcheck})
424+ set_property(TEST ${test_name}_no_memcheck PROPERTY ENVIRONMENT ${test_env})
425+ endif()
426+
427+ # ptest
428+ list_to_string("${test_env}" "--env" discover_env)
429+ list_to_string("${test_cmd}" "" discover_cmd)
430+ list_to_string("${test_cmd_no_memcheck}" "" discover_cmd_no_memcheck)
431
432 file(APPEND ${CMAKE_BINARY_DIR}/discover_all_tests.sh
433- "sh ${CMAKE_SOURCE_DIR}/tools/discover_gtests.sh ${discover_envs} -- ${discover_cmd_memcheck} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${EXECUTABLE}\n")
434+ "sh ${CMAKE_SOURCE_DIR}/tools/discover_gtests.sh ${discover_env} -- ${discover_cmd}\n")
435+ if (test_no_memcheck_filter)
436+ file(APPEND ${CMAKE_BINARY_DIR}/discover_all_tests.sh
437+ "sh ${CMAKE_SOURCE_DIR}/tools/discover_gtests.sh ${discover_env} -- ${discover_cmd_no_memcheck}\n")
438+ endif()
439 endfunction ()
440
441+function (mir_discover_tests EXECUTABLE)
442+ mir_discover_tests_internal(${EXECUTABLE} FALSE ${ARGN})
443+endfunction()
444+
445+function (mir_discover_tests_with_fd_leak_detection EXECUTABLE)
446+ mir_discover_tests_internal(${EXECUTABLE} TRUE ${ARGN})
447+endfunction()
448+
449 function (mir_add_memcheck_test)
450 if (ENABLE_MEMCHECK_OPTION)
451- if(DISABLE_GTEST_TEST_DISCOVERY)
452- add_custom_target(
453- memcheck_test ALL
454- )
455+ add_custom_target(memcheck_test ALL)
456 mir_add_test(NAME "memcheck-test"
457- COMMAND ${CMAKE_BINARY_DIR}/mir_gtest/fail_on_success.sh ${VALGRIND_EXECUTABLE} ${VALGRIND_ARGS} ${CMAKE_BINARY_DIR}/mir_gtest/mir_test_memory_error)
458- add_dependencies(
459- memcheck_test
460-
461- mir_test_memory_error
462- )
463- else()
464- add_custom_target(
465- memcheck_test ALL
466- ${CMAKE_BINARY_DIR}/mir_gtest/mir_discover_gtest_tests --executable=${CMAKE_BINARY_DIR}/mir_gtest/mir_test_memory_error --memcheck-test ${DISCOVER_FLAGS}
467- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
468- COMMENT "Adding memcheck test" VERBATIM)
469-
470- add_dependencies(
471- memcheck_test
472-
473- mir_discover_gtest_tests
474- mir_test_memory_error)
475- endif()
476- endif()
477-endfunction()
478+ COMMAND ${CMAKE_BINARY_DIR}/mir_gtest/fail_on_success.sh ${VALGRIND_CMD} ${CMAKE_BINARY_DIR}/mir_gtest/mir_test_memory_error)
479+ add_dependencies(memcheck_test mir_test_memory_error)
480+ endif()
481+endfunction()
482+
483+function (mir_add_detect_fd_leaks_test)
484+ if (ENABLE_MEMCHECK_OPTION)
485+ add_custom_target(detect_fd_leaks_catches_fd_leak_test ALL)
486+ mir_add_test(NAME "detect-fd-leaks-catches-fd-leak"
487+ COMMAND ${CMAKE_BINARY_DIR}/mir_gtest/fail_on_success.sh ${CMAKE_SOURCE_DIR}/tools/detect_fd_leaks.sh ${VALGRIND_CMD} ${CMAKE_BINARY_DIR}/mir_gtest/mir_test_fd_leak)
488+ add_dependencies(detect_fd_leaks_catches_fd_leak_test mir_test_fd_leak)
489+
490+ add_custom_target(detect_fd_leaks_propagates_test_failure_test ALL)
491+ mir_add_test(NAME "detect-fd-leaks-propagates-test-failure"
492+ COMMAND ${CMAKE_BINARY_DIR}/mir_gtest/fail_on_success.sh ${CMAKE_SOURCE_DIR}/tools/detect_fd_leaks.sh ${VALGRIND_CMD} ${CMAKE_BINARY_DIR}/mir_gtest/mir_test_memory_error)
493+ add_dependencies(detect_fd_leaks_propagates_test_failure_test mir_test_memory_error)
494+ endif()
495+endfunction()
496+
497
498 function (mir_precompiled_header TARGET HEADER)
499 if (MIR_USE_PRECOMPILED_HEADERS)
500
501=== modified file 'cmake/src/mir/CMakeLists.txt'
502--- cmake/src/mir/CMakeLists.txt 2015-01-21 07:34:50 +0000
503+++ cmake/src/mir/CMakeLists.txt 2015-07-23 14:41:37 +0000
504@@ -1,14 +1,4 @@
505 add_executable(
506- mir_discover_gtest_tests
507- EXCLUDE_FROM_ALL
508- ${CMAKE_CURRENT_SOURCE_DIR}/mir_discover_gtest_tests.cpp)
509-
510-set_target_properties(
511- mir_discover_gtest_tests PROPERTIES
512- RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/mir_gtest
513-)
514-
515-add_executable(
516 mir_test_memory_error
517 EXCLUDE_FROM_ALL
518 ${CMAKE_CURRENT_SOURCE_DIR}/mir_test_memory_error.cpp)
519@@ -18,6 +8,16 @@
520 RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/mir_gtest
521 )
522
523+add_executable(
524+ mir_test_fd_leak
525+ EXCLUDE_FROM_ALL
526+ ${CMAKE_CURRENT_SOURCE_DIR}/mir_test_fd_leak.cpp)
527+
528+set_target_properties(
529+ mir_test_fd_leak PROPERTIES
530+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/mir_gtest
531+)
532+
533 file(INSTALL ${CMAKE_CURRENT_SOURCE_DIR}/fail_on_success.sh
534 DESTINATION ${CMAKE_BINARY_DIR}/mir_gtest
535 USE_SOURCE_PERMISSIONS
536
537=== removed file 'cmake/src/mir/mir_discover_gtest_tests.cpp'
538--- cmake/src/mir/mir_discover_gtest_tests.cpp 2015-04-23 10:27:31 +0000
539+++ cmake/src/mir/mir_discover_gtest_tests.cpp 1970-01-01 00:00:00 +0000
540@@ -1,408 +0,0 @@
541-#include <algorithm>
542-#include <cassert>
543-#include <cstring>
544-#include <map>
545-#include <set>
546-#include <string>
547-#include <istream>
548-#include <ostream>
549-#include <fstream>
550-#include <sstream>
551-#include <iterator>
552-#include <iostream>
553-#include <vector>
554-#include <libgen.h>
555-
556-#include <getopt.h>
557-#include <sys/ioctl.h>
558-#include <unistd.h>
559-#ifndef _GNU_SOURCE
560-// Needed for O_TMPFILE
561-#define _GNU_SOURCE
562-#endif
563-#include <fcntl.h>
564-
565-using namespace std;
566-
567-namespace
568-{
569-enum DescriptorType
570-{
571- test_case,
572- test_suite
573-};
574-
575-DescriptorType check_line_for_test_case_or_suite(const string& line)
576-{
577- if (line.find(" ") == 0)
578- return test_case;
579-
580- return test_suite;
581-}
582-
583-int get_output_width()
584-{
585- const int fd_out{fileno(stdout)};
586- const int max_width{65535};
587-
588- int width{max_width};
589-
590- if (isatty(fd_out))
591- {
592- struct winsize w;
593- if (ioctl(fd_out, TIOCGWINSZ, &w) != -1)
594- width = w.ws_col;
595- }
596-
597- // If width is zero we likely don't have a terminal
598- if (width == 0) width = 80;
599-
600- return width;
601-}
602-
603-string ordinary_cmd_line_pattern()
604-{
605- static const char* pattern = "ADD_TEST(\"%s.%s\" \"%s\" \"--gtest_filter=%s:-%s\")\n";
606- return pattern;
607-}
608-
609-vector<string> valgrind_cmd_patterns(vector<string> const& suppressions)
610-{
611- vector<string> patterns{
612- "valgrind",
613- "--error-exitcode=1",
614- "--trace-children=yes"
615- };
616-
617- for (auto const& sup : suppressions)
618- patterns.push_back(std::string("--suppressions=") + sup);
619-
620- vector<string> gtest_patterns{
621- "%s",
622- "--gtest_death_test_use_fork",
623- "--gtest_filter=%s:-%s"
624- };
625-
626- patterns.insert(patterns.end(), gtest_patterns.begin(), gtest_patterns.end());
627-
628- return patterns;
629-}
630-
631-string memcheck_cmd_line_pattern(vector<string> const& suppressions)
632-{
633- stringstream ss;
634-
635- ss << "ADD_TEST(\"memcheck(%s.%s)\"";
636- for (auto& s : valgrind_cmd_patterns(suppressions))
637- ss << " \"" << s << "\"";
638- ss << ")" << endl;
639-
640- return ss.str();
641-}
642-
643-std::string elide_string_left(const std::string& in, std::size_t max_size)
644-{
645- assert(max_size >= 3);
646-
647- if (in.size() <= max_size)
648- return in;
649-
650- std::string result(in.begin() + (in.size() - max_size), in.end());
651-
652- *(result.begin()) = '.';
653- *(result.begin()+1) = '.';
654- *(result.begin()+2) = '.';
655-
656- return result;
657-}
658-
659-struct Configuration
660-{
661- Configuration() : executable(NULL),
662- enable_memcheck(false),
663- memcheck_test(false)
664- {
665- }
666-
667- std::string exclusions_for(string const& test)
668- {
669- if (test.size() < 2)
670- return {};
671-
672- // assuming test name is Foo.*
673- std::string test_name{test.substr(0, test.size() - 2)};
674- if (exclusions.find(test_name) != std::string::npos)
675- return exclusions;
676-
677- return {};
678- }
679-
680- const char* executable;
681- bool enable_memcheck;
682- bool memcheck_test;
683- std::vector<std::pair<std::string, std::string>> extra_environment;
684- std::vector<std::string> suppressions;
685- std::string exclusions;
686-};
687-
688-bool parse_configuration_from_cmd_line(int argc, char** argv, Configuration& config)
689-{
690- static struct option long_options[] = {
691- {"executable", required_argument, 0, 0},
692- {"enable-memcheck", no_argument, 0, 0},
693- {"memcheck-test", no_argument, 0, 0},
694- {"add-environment", required_argument, 0, 0},
695- {"suppressions", required_argument, 0, 0},
696- {"exclusions", required_argument, 0, 0},
697- {0, 0, 0, 0}
698- };
699-
700- while(1)
701- {
702- int option_index = -1;
703- const char *optname = "";
704- int c = getopt_long(
705- argc,
706- argv,
707- "e:m",
708- long_options,
709- &option_index);
710-
711- /* Detect the end of the options. */
712- if (c == -1)
713- break;
714-
715- /* Detect an error in the passed options */
716- if (c == ':' || c == '?')
717- return false;
718-
719- /* Check if we got a long option and get its name */
720- if (option_index != -1)
721- optname = long_options[option_index].name;
722-
723- /* Handle options */
724- if (c == 'e' || !strcmp(optname, "executable"))
725- config.executable = optarg;
726- else if (c == 'm' || !strcmp(optname, "enable-memcheck"))
727- config.enable_memcheck = true;
728- else if (!strcmp(optname, "memcheck-test"))
729- config.memcheck_test = true;
730- else if (!strcmp(optname, "add-environment"))
731- {
732- char const* equal_pos = strchr(optarg, '=');
733- if (!equal_pos)
734- return false;
735- config.extra_environment.push_back(std::make_pair(std::string(optarg, equal_pos - optarg), std::string(equal_pos + 1)));
736- }
737- else if (!strcmp(optname, "suppressions"))
738- {
739- config.suppressions.push_back(std::string(optarg));
740- }
741- else if (!strcmp(optname, "exclusions"))
742- {
743- config.exclusions = optarg;
744- }
745-
746- }
747-
748- return true;
749-}
750-
751-string prepareMemcheckTestLine(string const& exe, vector<string> const& suppressions, std::string const& exclusions)
752-{
753- stringstream ss;
754-
755- ss << "ADD_TEST(\"memcheck-test\" \"sh\" \"-c\" \"";
756- for (auto& s : valgrind_cmd_patterns(suppressions))
757- ss << s << " ";
758- ss << "; if [ $? != 0 ]; then exit 0; else exit 1; fi\")";
759-
760- char cmd_line[1024] = "";
761- snprintf(cmd_line,
762- sizeof(cmd_line),
763- ss.str().c_str(),
764- exe.c_str(),
765- "*",
766- exclusions.c_str()
767- );
768-
769- return cmd_line;
770-}
771-
772-void emitMemcheckTest(string const& exe, vector<string> const& suppressions, std::string const& exclusions)
773-{
774- ifstream CTestTestfile("CTestTestfile.cmake", ifstream::in);
775- bool need_memcheck_test = true;
776- string line;
777-
778- string memcheckTestLine = prepareMemcheckTestLine(exe, suppressions, exclusions);
779-
780- if (CTestTestfile.is_open())
781- {
782- while (CTestTestfile.good())
783- {
784- getline(CTestTestfile, line);
785-
786- if (line == memcheckTestLine)
787- need_memcheck_test = false;
788- }
789-
790- CTestTestfile.close();
791- }
792-
793- if (need_memcheck_test)
794- {
795- ofstream CTestTestfileW ("CTestTestfile.cmake", ofstream::app | ofstream::out);
796-
797- if (CTestTestfileW.is_open())
798- {
799- CTestTestfileW << memcheckTestLine << endl;
800- CTestTestfileW.close();
801- }
802- }
803-}
804-
805-bool is_death_test(string const& test)
806-{
807- // precondition: test will match Foo.*
808- // assumption: death tests will match FooDeathTest.*
809- bool death_test = false;
810- if (test.size() > strlen("DeathTest.*"))
811- death_test = test.substr(test.size() - strlen("DeathTest.*"),
812- strlen("DeathTest")) == "DeathTest";
813-
814- return death_test;
815-}
816-
817-}
818-
819-int main (int argc, char **argv)
820-{
821- int output_width = get_output_width();
822-
823- cin >> noskipws;
824-
825- Configuration config;
826- if (!parse_configuration_from_cmd_line(argc, argv, config) || config.executable == NULL)
827- {
828- cout << "Usage: PATH_TO_TEST_BINARY --gtest_list_tests | " << basename(argv[0])
829- << " --executable PATH_TO_TEST_BINARY [--enable-memcheck]" << std::endl
830- << " or " << std::endl << basename(argv[0])
831- << " --executable PATH_TO_MEMCHECK_BINARY --memcheck-test" << std::endl;
832- return 1;
833- }
834-
835- if (config.memcheck_test)
836- {
837- emitMemcheckTest(config.executable, config.suppressions, config.exclusions);
838- return 0;
839- }
840-
841- set<string> tests;
842- string line;
843- string current_test;
844-
845- while (getline (cin, line))
846- {
847- switch(check_line_for_test_case_or_suite(line))
848- {
849- case test_case:
850- tests.insert(current_test + "*");
851- break;
852- case test_suite:
853- auto suite_end = line.find(' ');
854- if (suite_end != std::string::npos)
855- {
856- line = line.substr(0, suite_end);
857- }
858- current_test = line;
859- break;
860- }
861- }
862-
863- ofstream testfilecmake;
864- char* executable_copy = strdup(config.executable);
865- string test_suite(basename(executable_copy));
866- free(executable_copy);
867-
868- testfilecmake.open(string(test_suite + "_test.cmake").c_str(), ios::out | ios::trunc);
869- if (testfilecmake.is_open())
870- {
871- for (auto& env_pair : config.extra_environment)
872- {
873- testfilecmake << "SET( ENV{"<<env_pair.first<<"} \""<<env_pair.second<<"\" )"<<std::endl;
874- }
875-
876- int ret = open("/dev/shm", O_TMPFILE | O_RDWR | O_EXCL, S_IRWXU);
877- bool kernel_supports_O_TMPFILE = (ret != -1);
878- if (kernel_supports_O_TMPFILE) close(ret);
879-
880- for (auto test = tests.begin(); test != tests.end(); ++ test)
881- {
882- static char cmd_line[1024] = "";
883-
884-
885- if (!kernel_supports_O_TMPFILE)
886- {
887- // Don't run AnonymousShmFile.* tests on older kernels
888- if (*test == "AnonymousShmFile.*")
889- continue;
890- if (*test == "MesaBufferAllocatorTest.*")
891- config.exclusions.append("MesaBufferAllocatorTest.software_buffers_dont_bypass:MesaBufferAllocatorTest.creates_software_rendering_buffer");
892- }
893-
894- snprintf(
895- cmd_line,
896- sizeof(cmd_line),
897- (config.enable_memcheck && !is_death_test(*test)) ?
898- memcheck_cmd_line_pattern(config.suppressions).c_str() :
899- ordinary_cmd_line_pattern().c_str(),
900- test_suite.c_str(),
901- elide_string_left(*test, output_width/2).c_str(),
902- config.executable,
903- test->c_str(),
904- config.exclusions_for(*test).c_str());
905-
906- if (testfilecmake.good())
907- {
908- testfilecmake << cmd_line;
909- }
910- }
911-
912- testfilecmake.close();
913- }
914-
915- ifstream CTestTestfile("CTestTestfile.cmake", ifstream::in);
916- bool need_include = true;
917- line.clear();
918-
919- string includeLine = string ("INCLUDE (") +
920- test_suite +
921- string ("_test.cmake)");
922-
923- if (CTestTestfile.is_open())
924- {
925- while (CTestTestfile.good())
926- {
927- getline(CTestTestfile, line);
928-
929- if (line == includeLine)
930- need_include = false;
931- }
932-
933- CTestTestfile.close();
934- }
935-
936- if (need_include)
937- {
938- ofstream CTestTestfileW ("CTestTestfile.cmake", ofstream::app | ofstream::out);
939-
940- if (CTestTestfileW.is_open())
941- {
942- CTestTestfileW << includeLine << endl;
943- CTestTestfileW.close();
944- }
945- }
946-
947- return 0;
948-}
949
950=== added file 'cmake/src/mir/mir_test_fd_leak.cpp'
951--- cmake/src/mir/mir_test_fd_leak.cpp 1970-01-01 00:00:00 +0000
952+++ cmake/src/mir/mir_test_fd_leak.cpp 2015-07-23 14:41:37 +0000
953@@ -0,0 +1,6 @@
954+#include <fcntl.h>
955+
956+int main()
957+{
958+ open("/dev/zero", O_RDONLY);
959+}
960
961=== added file 'cmake/src/mir/mir_test_tmpfile.cpp'
962--- cmake/src/mir/mir_test_tmpfile.cpp 1970-01-01 00:00:00 +0000
963+++ cmake/src/mir/mir_test_tmpfile.cpp 2015-07-23 14:41:37 +0000
964@@ -0,0 +1,14 @@
965+#include <sys/types.h>
966+#include <sys/stat.h>
967+#include <fcntl.h>
968+#include <unistd.h>
969+
970+int main()
971+{
972+ int ret = open("/dev/shm", O_TMPFILE | O_RDWR | O_EXCL, S_IRWXU);
973+
974+ if (ret == -1)
975+ return 1;
976+ close(ret);
977+ return 0;
978+}
979
980=== modified file 'cross-compile-chroot.sh'
981--- cross-compile-chroot.sh 2015-01-21 07:34:50 +0000
982+++ cross-compile-chroot.sh 2015-07-23 14:41:37 +0000
983@@ -77,7 +77,7 @@
984 echo "Using PKG_CONFIG_EXECUTABLE: $PKG_CONFIG_EXECUTABLE"
985 cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/LinuxCrossCompile.cmake \
986 -DBoost_COMPILER=-gcc \
987- -DMIR_PLATFORM=android\;mesa \
988+ -DMIR_PLATFORM=android\;mesa-kms \
989 ..
990
991 make -j${NUM_JOBS} $@
992
993=== modified file 'debian/changelog'
994--- debian/changelog 2015-06-17 20:02:15 +0000
995+++ debian/changelog 2015-07-23 14:41:37 +0000
996@@ -1,3 +1,88 @@
997+mir (0.14.0+15.10.20150715-0ubuntu2) UNRELEASED; urgency=medium
998+
999+ * Fix missing ABI renaming in Mirplatform
1000+ * Bump Mirserver platform graphics to 3
1001+ * Fix mirprotobuf ABI break
1002+ * Fix g++-5.0 compilation (LP: #1475994)
1003+
1004+ -- Andreas Pokorny <andreas.pokorny@canonical.com> Tue, 21 Jul 2015 10:14:21 +0200
1005+
1006+mir (0.14.0+15.10.20150715-0ubuntu1) wily; urgency=medium
1007+
1008+ [ Andreas Pokorny ]
1009+ * New upstream release 0.14.0 (https://launchpad.net/mir/+milestone/0.14.0)
1010+ - ABI summary: All clients and all servers need building;
1011+ . Mirclient ABI bumped to 9
1012+ . Mirserver ABI bumped to 32
1013+ . Mircommon ABI bumped to 5
1014+ . Mirplatform ABI bumped to 8
1015+ - Enhancements:
1016+ . mir_demo_server: tweaks, features and improvements
1017+ . More MirEvent-2.0 related changes and unifications
1018+ . New SurfaceInputDispatcher to replace the android InputDispatcher
1019+ . New Threaded dispatcher for Dispatchable added
1020+ . Rework of the relationship of surfaces and buffer streams to allow
1021+ attaching multiple buffer streams to a surface.
1022+ . Preparation work for new buffer semantics
1023+ . fd leaks in tests eliminated and leak check activated for unit and
1024+ integration tests
1025+ . Further TSAN reported issues removed
1026+ . Preparation work for mir-on-x: splitting of mesa platform in common
1027+ and KMS parts
1028+ . Further rework of input stack focused on test infrastructure
1029+ . Persistent id request for surfaces added
1030+ . Integration-tests cleaning: switch tests to in-process server
1031+ . A first end-to-end input test added in privileged-tests
1032+ . "mesa" platform renamed to "mesa-kms" (LP: #1381330)
1033+ . [enhancement] Mir servers should allow client connections only after
1034+ server start-up has finished (LP: #1451844)
1035+ . build-dependency on g++-4.9 dropped (LP: #1452320)
1036+ - Bug fixes:
1037+ . Crash because uncaught exception in mir::events::add_touch
1038+ (LP: #1437357)
1039+ . [vegetahd] android buffer allocator does consider hwc alignment
1040+ constraints (LP: #1461314)
1041+ . [regression] Touch input does not work at all any more (LP: #1464174)
1042+ . Mir emits a mir_motion_action_hover_exit event before of a
1043+ mir_motion_action_pointer_down (LP: #1419048)
1044+ . [testsfail] NestedInput.nested_event_filter_receives_keyboard_from_host
1045+ failure in CI (LP: #1462033)
1046+ . [testsfail] InputEvents.reach_nested_client in CI (LP: #1463315)
1047+ . [regression] titlebar in "canonical" example WM + KeyRepeatDispatcher
1048+ causes deadlock (LP: #1464690)
1049+ . CI failure in
1050+ TestClientInput.clients_receive_many_button_events_inside_window
1051+ (LP: #1465231)
1052+ . mir-client-platform-mesa-dev package dependency is incorrect
1053+ (LP: #1465642)
1054+ . Repeat input events keep being emitted even when user switches to
1055+ different VT (LP: #1465669)
1056+ . libmirprotobuf's ABI can be broken when modifying protobuf message
1057+ definitions (LP: #1465883)
1058+ . Spurious Failure in ClientLibrary.highly_threaded_client
1059+ (LP: #1466492)
1060+ . failure in CI in BufferStreamArrangement.arrangements_are_applied
1061+ (LP: #1466594)
1062+ . [arale] software buffers have flickering line artefacts (LP: #1418035)
1063+ . can't load app purchase UI without a U1 account (LP: #1450377)
1064+ . [arale] Software cursor appears slightly corrupt on arale (black
1065+ spots in place of white) (LP: #1451309)
1066+ . [regression] Dragging windows by the titlebar is incredibly slow
1067+ and laggy (LP: #1454128)
1068+ . [regression] Opacity controls (Alt+mousewheel) don't work any more
1069+ (LP: #1454518)
1070+ . [regression] No API for creating freestyle surfaces (LP: #1457987)
1071+ . [vivid-overlay] input-stub.so fails to load on i386 (LP: #1458689)
1072+ . client API version has wrong version (LP: #1461312)
1073+ . abi-dump-base make target is broken (LP: #1461697)
1074+ . Stopping input in a nested server stops VT switching (LP: #1465585)
1075+ . Pointer events are not mapped to correct output by nested Mir
1076+ (LP: #1465692)
1077+ . Loading libmirclient.so twice leads to a segfault in libmirprotobuf.so
1078+ (LP: #1391976)
1079+
1080+ -- CI Train Bot <ci-train-bot@canonical.com> Wed, 15 Jul 2015 12:05:19 +0000
1081+
1082 mir (0.13.3+15.10.20150617-0ubuntu1) wily; urgency=medium
1083
1084 [ Alberto Aguirre ]
1085
1086=== modified file 'debian/control'
1087--- debian/control 2015-06-17 18:28:22 +0000
1088+++ debian/control 2015-07-23 14:41:37 +0000
1089@@ -10,10 +10,6 @@
1090 doxygen,
1091 xsltproc,
1092 graphviz,
1093-# We rely on C++11 features, and to prevent from ABI breaks
1094-# in libstdc++ causing us issues, we explicitly select a G++
1095-# version.
1096- g++-4.9,
1097 libboost-dev,
1098 libboost-date-time-dev,
1099 libboost-program-options-dev,
1100@@ -38,10 +34,13 @@
1101 libudev-dev,
1102 libgtest-dev,
1103 google-mock (>= 1.6.0+svn437),
1104- valgrind [!arm64 !powerpc !ppc64el],
1105+# only enable valgrind once it's been tested to work on each architecture:
1106+ valgrind [amd64 i386 armhf],
1107 libglib2.0-dev,
1108 libfreetype6-dev,
1109+ libevdev-dev,
1110 abi-compliance-checker,
1111+ uuid-dev,
1112 Standards-Version: 3.9.4
1113 Homepage: https://launchpad.net/mir
1114 # If you aren't a member of ~mir-team but need to upload packaging changes,
1115@@ -50,7 +49,7 @@
1116
1117 Package: libmirprotobuf0
1118 Section: libs
1119-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1120+Architecture: linux-any
1121 Multi-Arch: same
1122 Pre-Depends: ${misc:Pre-Depends}
1123 Depends: ${misc:Depends},
1124@@ -64,9 +63,9 @@
1125
1126 #TODO: Packaging infrastructure for better dependency generation,
1127 # ala pkg-xorg's xviddriver:Provides and ABI detection.
1128-Package: libmirserver31
1129+Package: libmirserver32
1130 Section: libs
1131-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1132+Architecture: linux-any
1133 Multi-Arch: same
1134 Pre-Depends: ${misc:Pre-Depends}
1135 Depends: ${misc:Depends},
1136@@ -77,9 +76,9 @@
1137 .
1138 Contains the shared library needed by server applications for Mir.
1139
1140-Package: libmirplatform7
1141+Package: libmirplatform8
1142 Section: libs
1143-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1144+Architecture: linux-any
1145 Multi-Arch: same
1146 Pre-Depends: ${misc:Pre-Depends}
1147 Depends: ${misc:Depends},
1148@@ -93,10 +92,10 @@
1149
1150 Package: libmircommon-dev
1151 Section: libdevel
1152-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1153+Architecture: linux-any
1154 Multi-Arch: same
1155 Pre-Depends: ${misc:Pre-Depends}
1156-Depends: libmircommon4 (= ${binary:Version}),
1157+Depends: libmircommon5 (= ${binary:Version}),
1158 libprotobuf-dev (>= 2.4.1),
1159 libxkbcommon-dev,
1160 ${misc:Depends},
1161@@ -110,10 +109,10 @@
1162
1163 Package: libmirplatform-dev
1164 Section: libdevel
1165-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1166+Architecture: linux-any
1167 Multi-Arch: same
1168 Pre-Depends: ${misc:Pre-Depends}
1169-Depends: libmirplatform7 (= ${binary:Version}),
1170+Depends: libmirplatform8 (= ${binary:Version}),
1171 libmircommon-dev,
1172 libboost-program-options-dev,
1173 ${misc:Depends},
1174@@ -127,10 +126,10 @@
1175
1176 Package: libmirserver-dev
1177 Section: libdevel
1178-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1179+Architecture: linux-any
1180 Multi-Arch: same
1181 Pre-Depends: ${misc:Pre-Depends}
1182-Depends: libmirserver31 (= ${binary:Version}),
1183+Depends: libmirserver32 (= ${binary:Version}),
1184 libmirplatform-dev (= ${binary:Version}),
1185 libmircommon-dev (= ${binary:Version}),
1186 libglm-dev,
1187@@ -141,9 +140,9 @@
1188 .
1189 Contains header files required to build Mir servers.
1190
1191-Package: libmirclient8
1192+Package: libmirclient9
1193 Section: libs
1194-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1195+Architecture: linux-any
1196 Multi-Arch: same
1197 Pre-Depends: ${misc:Pre-Depends}
1198 Depends: ${misc:Depends},
1199@@ -156,10 +155,10 @@
1200
1201 Package: libmirclient-dev
1202 Section: libdevel
1203-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1204+Architecture: linux-any
1205 Multi-Arch: same
1206 Pre-Depends: ${misc:Pre-Depends}
1207-Depends: libmirclient8 (= ${binary:Version}),
1208+Depends: libmirclient9 (= ${binary:Version}),
1209 libmircommon-dev (= ${binary:Version}),
1210 libprotobuf-dev (>= 2.4.1),
1211 ${misc:Depends},
1212@@ -171,7 +170,7 @@
1213
1214 Package: libmirclient-debug-extension1
1215 Section: libs
1216-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1217+Architecture: linux-any
1218 Multi-Arch: same
1219 Pre-Depends: ${misc:Pre-Depends}
1220 Depends: ${misc:Depends},
1221@@ -192,7 +191,7 @@
1222
1223 Package: libmirclient-debug-extension-dev
1224 Section: libdevel
1225-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1226+Architecture: linux-any
1227 Multi-Arch: same
1228 Pre-Depends: ${misc:Pre-Depends}
1229 Depends: libmirclient-debug-extension1 (= ${binary:Version}),
1230@@ -216,7 +215,7 @@
1231 the debug extensions.
1232
1233 Package: mir-demos
1234-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1235+Architecture: linux-any
1236 Depends: ${misc:Depends},
1237 ${shlibs:Depends},
1238 Recommends: fonts-liberation
1239@@ -227,7 +226,7 @@
1240 Contains demo applications (with source) that use the Mir display server
1241
1242 Package: mir-utils
1243-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1244+Architecture: linux-any
1245 Depends: ${misc:Depends},
1246 ${shlibs:Depends},
1247 Description: Display server for Ubuntu - utility programs
1248@@ -244,7 +243,7 @@
1249 This package installs the mir API documentation.
1250
1251 Package: mir-test-tools
1252-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1253+Architecture: linux-any
1254 Multi-Arch: same
1255 Pre-Depends: ${misc:Pre-Depends}
1256 Depends: ${misc:Depends},
1257@@ -256,9 +255,9 @@
1258 .
1259 Contains a tool for stress testing the Mir display server
1260
1261-Package: libmircommon4
1262+Package: libmircommon5
1263 Section: libs
1264-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1265+Architecture: linux-any
1266 Multi-Arch: same
1267 Pre-Depends: ${misc:Pre-Depends}
1268 Depends: ${misc:Depends},
1269@@ -270,21 +269,33 @@
1270 Contains the shared libraries required for the Mir server and client.
1271
1272 # Longer-term these drivers should move out-of-tree
1273+Package: mir-platform-graphics-mesa-kms3
1274+Section: libs
1275+Architecture: linux-any
1276+Multi-Arch: same
1277+Pre-Depends: ${misc:Pre-Depends}
1278+Depends: ${misc:Depends},
1279+ ${shlibs:Depends},
1280+Replaces: mir-platform-graphics-mesa2 (<< 0.14)
1281+Breaks: mir-platform-graphics-mesa2 (<< 0.14)
1282+Description: Display server for Ubuntu - platform library for KMS Mesa
1283+ Mir is a display server running on linux systems, with a focus on efficiency,
1284+ robust operation and a well-defined driver model.
1285+ .
1286+ Contains the shared libraries required for the Mir server to interact with
1287+ the hardware platform using the Mesa drivers.
1288+
1289 Package: mir-platform-graphics-mesa2
1290-Section: libs
1291-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1292-Multi-Arch: same
1293-Pre-Depends: ${misc:Pre-Depends}
1294-Depends: ${misc:Depends},
1295+Section: oldlibs
1296+Architecture: linux-any
1297+Depends: mir-platform-graphics-mesa-kms3,
1298+ ${misc:Depends},
1299 ${shlibs:Depends},
1300-Description: Display server for Ubuntu - platform library for Mesa
1301- Mir is a display server running on linux systems, with a focus on efficiency,
1302- robust operation and a well-defined driver model.
1303- .
1304- Contains the shared libraries required for the Mir server to interact with
1305- the hardware platform using the Mesa drivers.
1306+Description: transitional dummy package
1307+ This is a transitional dummy package created due to package renaming.
1308+ It can safely be removed.
1309
1310-Package: mir-platform-graphics-android2
1311+Package: mir-platform-graphics-android3
1312 Section: libs
1313 Architecture: i386 amd64 armhf
1314 Multi-Arch: same
1315@@ -300,7 +311,7 @@
1316
1317 Package: mir-client-platform-mesa2
1318 Section: libs
1319-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1320+Architecture: linux-any
1321 Multi-Arch: same
1322 Pre-Depends: ${misc:Pre-Depends}
1323 Depends: ${misc:Depends},
1324@@ -314,7 +325,7 @@
1325
1326 Package: mir-client-platform-mesa-dev
1327 Section: libdevel
1328-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1329+Architecture: linux-any
1330 Multi-Arch: same
1331 Pre-Depends: ${misc:Pre-Depends}
1332 Depends: libmirclient-dev,
1333@@ -342,11 +353,11 @@
1334
1335 Package: mir-graphics-drivers-desktop
1336 Section: libs
1337-Architecture: i386 amd64 armhf arm64 powerpc ppc64el
1338+Architecture: linux-any
1339 Multi-Arch: same
1340 Pre-Depends: ${misc:Pre-Depends}
1341 Depends: ${misc:Depends},
1342- mir-platform-graphics-mesa2,
1343+ mir-platform-graphics-mesa-kms3,
1344 mir-client-platform-mesa2,
1345 Description: Display server for Ubuntu - desktop driver metapackage
1346 Mir is a display server running on linux systems, with a focus on efficiency,
1347@@ -361,7 +372,7 @@
1348 Multi-Arch: same
1349 Pre-Depends: ${misc:Pre-Depends}
1350 Depends: ${misc:Depends},
1351- mir-platform-graphics-android2,
1352+ mir-platform-graphics-android3,
1353 mir-client-platform-android2,
1354 Description: Display server for Ubuntu - android driver metapackage
1355 Mir is a display server running on linux systems, with a focus on efficiency,
1356
1357=== modified file 'debian/create_postinst_prerm_scripts.sh'
1358--- debian/create_postinst_prerm_scripts.sh 2015-06-05 17:48:17 +0000
1359+++ debian/create_postinst_prerm_scripts.sh 2015-07-23 14:41:37 +0000
1360@@ -8,11 +8,11 @@
1361
1362 mir_platform_types="${PLATFORM_DRIVER}"
1363 case $deb_host_arch in
1364- arm64|powerpc|ppc64el)
1365- mir_platforms="mesa"
1366+ amd64|i386|armhf)
1367+ mir_platforms="android mesa-kms"
1368 ;;
1369 *)
1370- mir_platforms="android mesa"
1371+ mir_platforms="mesa-kms"
1372 ;;
1373 esac
1374
1375
1376=== modified file 'debian/install_ld_so_conf.sh'
1377--- debian/install_ld_so_conf.sh 2015-06-05 17:48:17 +0000
1378+++ debian/install_ld_so_conf.sh 2015-07-23 14:41:37 +0000
1379@@ -7,12 +7,11 @@
1380
1381 mir_platform_types="${PLATFORM_DRIVER} ${CLIENT_DRIVER}"
1382 case $DEB_HOST_ARCH in
1383- arm64|powerpc|ppc64el)
1384- mir_platforms="mesa"
1385+ amd64|i386|armhf)
1386+ mir_platforms="android mesa-kms"
1387 ;;
1388 *)
1389- mir_platforms="android mesa"
1390- ;;
1391+ mir_platforms="mesa-kms"
1392 esac
1393
1394 for platform_type in $mir_platform_types;
1395
1396=== renamed file 'debian/libmirclient8.install' => 'debian/libmirclient9.install'
1397--- debian/libmirclient8.install 2015-03-31 02:35:42 +0000
1398+++ debian/libmirclient9.install 2015-07-23 14:41:37 +0000
1399@@ -1,1 +1,1 @@
1400-usr/lib/*/libmirclient.so.8
1401+usr/lib/*/libmirclient.so.9
1402
1403=== renamed file 'debian/libmircommon4.install' => 'debian/libmircommon5.install'
1404--- debian/libmircommon4.install 2015-03-31 02:35:42 +0000
1405+++ debian/libmircommon5.install 2015-07-23 14:41:37 +0000
1406@@ -1,1 +1,1 @@
1407-usr/lib/*/libmircommon.so.4
1408+usr/lib/*/libmircommon.so.5
1409
1410=== renamed file 'debian/libmirplatform7.install' => 'debian/libmirplatform8.install'
1411--- debian/libmirplatform7.install 2015-03-31 02:35:42 +0000
1412+++ debian/libmirplatform8.install 2015-07-23 14:41:37 +0000
1413@@ -1,1 +1,1 @@
1414-usr/lib/*/libmirplatform.so.7
1415+usr/lib/*/libmirplatform.so.8
1416
1417=== renamed file 'debian/libmirserver31.install' => 'debian/libmirserver32.install'
1418--- debian/libmirserver31.install 2015-04-30 11:36:36 +0000
1419+++ debian/libmirserver32.install 2015-07-23 14:41:37 +0000
1420@@ -1,1 +1,1 @@
1421-usr/lib/*/libmirserver.so.31
1422+usr/lib/*/libmirserver.so.32
1423
1424=== modified file 'debian/mir-demos.install'
1425--- debian/mir-demos.install 2015-01-21 07:34:50 +0000
1426+++ debian/mir-demos.install 2015-07-23 14:41:37 +0000
1427@@ -1,2 +1,3 @@
1428 usr/bin/mir_demo_*
1429-usr/bin/mir_proving_*
1430\ No newline at end of file
1431+usr/bin/mir_proving_*
1432+usr/lib/*/libmir_demo_*
1433
1434=== renamed file 'debian/mir-platform-graphics-android2.install' => 'debian/mir-platform-graphics-android3.install'
1435--- debian/mir-platform-graphics-android2.install 2015-04-30 11:36:36 +0000
1436+++ debian/mir-platform-graphics-android3.install 2015-07-23 14:41:37 +0000
1437@@ -1,1 +1,1 @@
1438-usr/lib/*/mir/server-platform/graphics-android.so.2
1439+usr/lib/*/mir/server-platform/graphics-android.so.3
1440
1441=== renamed file 'debian/mir-platform-graphics-mesa2.install' => 'debian/mir-platform-graphics-mesa-kms3.install'
1442--- debian/mir-platform-graphics-mesa2.install 2015-04-30 11:36:36 +0000
1443+++ debian/mir-platform-graphics-mesa-kms3.install 2015-07-23 14:41:37 +0000
1444@@ -1,1 +1,1 @@
1445-usr/lib/*/mir/server-platform/graphics-mesa.so.2
1446+usr/lib/*/mir/server-platform/graphics-mesa-kms.so.3
1447
1448=== modified file 'debian/mir-test-tools.install'
1449--- debian/mir-test-tools.install 2015-04-09 06:20:31 +0000
1450+++ debian/mir-test-tools.install 2015-07-23 14:41:37 +0000
1451@@ -3,6 +3,8 @@
1452 usr/bin/mir_acceptance_tests
1453 usr/bin/mir_integration_tests
1454 usr/bin/mir_performance_tests
1455+usr/bin/mir_privileged_tests
1456+usr/bin/mir_test_reload_protobuf
1457 usr/lib/*/mir/tools/libmirclientlttng.so
1458 usr/lib/*/mir/tools/libmirserverlttng.so
1459 usr/lib/*/mir/server-platform/graphics-dummy.so
1460
1461=== modified file 'debian/mir-utils.install'
1462--- debian/mir-utils.install 2014-03-06 06:05:17 +0000
1463+++ debian/mir-utils.install 2015-07-23 14:41:37 +0000
1464@@ -1,3 +1,4 @@
1465 usr/bin/mirping
1466 usr/bin/mirout
1467 usr/bin/mirscreencast
1468+usr/bin/mirbacklight
1469
1470=== modified file 'debian/rules'
1471--- debian/rules 2015-06-05 17:48:17 +0000
1472+++ debian/rules 2015-07-23 14:41:37 +0000
1473@@ -2,27 +2,21 @@
1474
1475 DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
1476 DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
1477+DEB_HOST_ARCH_ENDIAN ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_ENDIAN)
1478 EXACT_PACKAGE_VERSION = $(shell dpkg-parsechangelog | grep Version | cut -d' ' -f 2)
1479
1480 export DPKG_GENSYMBOLS_CHECK_LEVEL = 4
1481
1482-include /usr/share/dpkg/default.mk
1483-
1484-# Explicitly selecting a G{CC,++}-version here to avoid accidental
1485-# ABI breaks introduced by toolchain updates.
1486-export CC=$(DEB_HOST_GNU_TYPE)-gcc-4.9
1487-export CXX=$(DEB_HOST_GNU_TYPE)-g++-4.9
1488-
1489 %:
1490 dh $@ --parallel --fail-missing
1491
1492 # Enable verbose debugging output from the testsuite
1493 export MIR_SERVER_LOGGING = on
1494 override_dh_auto_test:
1495-ifneq ($(DEB_HOST_ARCH),powerpc)
1496+ifeq ($(DEB_HOST_ARCH_ENDIAN),little)
1497 GTEST_OUTPUT=xml:./ dh_auto_test --max-parallel=1 -- ARGS="-V"
1498 else
1499- echo "Testsuite disabled on powerpc due to lack of big-endian support."
1500+ echo "Testsuite disabled on $(DEB_HOST_ARCH) due to lack of big-endian support."
1501 endif
1502
1503 COMMON_CONFIGURE_OPTIONS = \
1504@@ -34,16 +28,16 @@
1505 $(COMMON_CONFIGURE_OPTIONS) \
1506 -DMIR_RUN_ACCEPTANCE_TESTS=OFF \
1507 -DMIR_RUN_INTEGRATION_TESTS=OFF \
1508- -DMIR_PLATFORM=android\;mesa
1509-else
1510-ifneq ($(filter arm64 powerpc ppc64el,$(DEB_HOST_ARCH)),)
1511- dh_auto_configure -- \
1512- $(COMMON_CONFIGURE_OPTIONS) \
1513- -DMIR_PLATFORM=mesa
1514-else
1515- dh_auto_configure -- \
1516- $(COMMON_CONFIGURE_OPTIONS) \
1517- -DMIR_PLATFORM=mesa\;android
1518+ -DMIR_PLATFORM=android\;mesa-kms
1519+else
1520+ifneq ($(filter amd64 i386,$(DEB_HOST_ARCH)),)
1521+ dh_auto_configure -- \
1522+ $(COMMON_CONFIGURE_OPTIONS) \
1523+ -DMIR_PLATFORM=mesa-kms\;android
1524+else
1525+ dh_auto_configure -- \
1526+ $(COMMON_CONFIGURE_OPTIONS) \
1527+ -DMIR_PLATFORM=mesa-kms
1528 endif
1529 endif
1530
1531
1532=== modified file 'doc/building_source_for_arm.md'
1533--- doc/building_source_for_arm.md 2015-01-21 07:34:50 +0000
1534+++ doc/building_source_for_arm.md 2015-07-23 14:41:37 +0000
1535@@ -1,40 +1,55 @@
1536-Building the source for ARM {#building_source_for_arm}
1537+Building the Mir source for ARM {#building_source_for_arm}
1538 ===============================
1539
1540-There are a few ways to compile for a target arm device. Only armhf and arm64
1541-are supported at this time.
1542-
1543-Native Compile
1544---------------
1545-
1546-If you have a target device, you should be able to compile and install directly
1547-on the ARM device. This will be probably be slow, given the relative
1548-desktop/embedded CPU speeds these days. On the armhf or arm64 target device:
1549+There are a few ways to compile Mir for an ARM device. You should only need
1550+to choose one of these approaches...
1551+
1552+Building on the ARM device
1553+--------------------------
1554+
1555+If you have an ARM device you should be able to compile and install directly
1556+on the device. Although this will usually be significantly slower than using a
1557+desktop. On the armhf or arm64 target device just follow these steps:
1558
1559 $ mk-build-deps --install --tool "apt-get -y" --build-dep debian/control
1560 $ cmake .. -DMIR_PLATFORM=android
1561 $ make
1562 $ make install
1563
1564-The build-time flags -DMIR_BUILD_UNIT_TESTS=no -DMIR_BUILD_INTEGRATION_TESTS=no
1565--DMIR_BUILD_ACCEPTANCE_TESTS=no can be used to avoid building the mir test suite
1566-and save build-time.
1567-
1568-Packaging workflow
1569-------------------
1570-
1571-sbuild is recommended to compile mir packages with armhf. Information on setting
1572-sbuild up can be found here:
1573+The addional cmake option -DMIR_ENABLE_TESTS=off can be used to avoid building
1574+the test suite to save time.
1575+
1576+Building for ARM from a PC (cross compiling)
1577+--------------------------------------------
1578+
1579+Using a current Ubuntu (15.04 or later) installation it's very simple to build
1580+binaries for armhf devices. Just follow these steps:
1581+
1582+ $ sudo apt-get install g++-arm-linux-gnueabihf debootstrap
1583+ $ cd mir_source_dir
1584+ $ ./cross-compile-chroot.sh
1585+ $ ls -l build-android-arm/* # binaries to copy to your device as you wish
1586+
1587+To speed up the process for future runs of cross-compile-chroot.sh, some files
1588+are saved in ~/.cache/. To flush the cache and download new armhf packages
1589+just add the -u option to cross-compile-chroot.sh.
1590+
1591+Building armhf deb packages
1592+---------------------------
1593+
1594+"sbuild" is recommended to compile Mir packages with armhf. Information on
1595+setting up sbuild can be found here:
1596
1597 * <a href="https://wiki.debian.org/sbuild"> https://wiki.debian.org/sbuild</a>
1598 * <a href="https://wiki.ubuntu.com/SimpleSbuild">
1599 https://wiki.ubuntu.com/SimpleSbuild</a>
1600
1601-If you do not wish to run the mir test suite during package generation, set
1602- DEB_BUILD_OPTIONS=nocheck to your environment
1603+If you do not wish to run the Mir test suite during package generation, set
1604+DEB_BUILD_OPTIONS=nocheck to your environment
1605
1606 Emulated sbuild package generation
1607 ----------------------------------
1608+
1609 This uses qemu to compile the package. Substitute <version_string> for the .dsc
1610 file name generated by the debuild command.
1611
1612@@ -43,44 +58,17 @@
1613 $ cd ..
1614 $ sbuild -d vivid --arch armhf mir_<version_string>.dsc
1615
1616-Cross compile sbuild package generation
1617+Cross-compile sbuild package generation
1618 ---------------------------------------
1619+
1620 This uses a cross-compile toolchain to compile the package, and generally
1621 should be faster than the emulated sbuild package generation.
1622
1623 Substitute <version_string> for the .dsc file name generated by the debuild
1624 command.
1625
1626-(Nov 2014) We are currently plagued by
1627-<a href="https://bugs.launchpad.net/mir/+bug/1353855">launchpad bug: 1353855</a>
1628-which requires the sed step below as a work-around. If that bug gets resolved,
1629-the sed step can be omitted.
1630-
1631 $ cd mir_source_dir
1632- $ sed -i '/.*g++-4.9.*$/d' debian/control
1633 $ debuild -S -uc -us
1634 $ cd ..
1635 $ sbuild -d vivid --host armhf --build amd64 mir_<version_string>.dsc
1636
1637-Development workflow
1638---------------------
1639-
1640-We have a script that can aid in the development workflow if you do not want to
1641-generate and install a package. The script will download a partial armhf chroot
1642-within the mir_source_dir directory.
1643-
1644-Make sure to have a suitable cross compile toolchain (e.g., the
1645-`g++-arm-linux-gnueabihf` ubuntu package).
1646-
1647- $ sudo apt-get install g++-arm-linux-gnueabihf debootstrap
1648- $ cd mir_source_dir
1649- $ ./cross-compile-chroot.sh
1650- $ ls -l build-android-arm/* # binaries to copy to your device
1651-
1652-To speed up the process for future branches you may wish to cache the files
1653-downloaded by setting environment variable MIR_NDK_PATH to point to a directory
1654-that cross-compile-chroot.sh should reuse each time.
1655-
1656-Copying the produced binaries correctly to the device requires good familiarity
1657-with the Mir codebase. For that reason, installing using the debian packaging is
1658- recommended, and this compile method is mentioned for development purposes.
1659
1660=== modified file 'doc/kernel_requirements.md'
1661--- doc/kernel_requirements.md 2015-04-13 15:57:33 +0000
1662+++ doc/kernel_requirements.md 2015-07-23 14:41:37 +0000
1663@@ -1,7 +1,7 @@
1664 Linux Kernel Requirements for Mir
1665 =================================
1666
1667-To run Mir with the default `mesa` platform you need a linux kernel with at
1668+To run Mir with the default `mesa-kms` platform you need a linux kernel with at
1669 least:
1670
1671 Modules: i915, radeon and nouveau, to support the broadest range of common
1672
1673=== modified file 'examples/CMakeLists.txt'
1674--- examples/CMakeLists.txt 2015-04-23 11:42:34 +0000
1675+++ examples/CMakeLists.txt 2015-07-23 14:41:37 +0000
1676@@ -13,6 +13,7 @@
1677
1678 add_library(eglapp STATIC
1679 eglapp.c
1680+ client_helpers.cpp
1681 )
1682
1683 add_library(exampleserverconfig STATIC
1684@@ -88,6 +89,13 @@
1685 )
1686 target_link_libraries(mir_demo_client_tooltip
1687 eglapp
1688+ )
1689+
1690+mir_add_wrapped_executable(mir_demo_client_touch_validator
1691+ client_touch_validator.cpp
1692+)
1693+target_link_libraries(mir_demo_client_touch_validator
1694+ eglapp
1695 )
1696
1697 mir_add_wrapped_executable(mir_demo_client_basic
1698@@ -185,6 +193,32 @@
1699 ${Boost_LIBRARIES}
1700 )
1701
1702+add_library(mir_demo_server_loadable MODULE
1703+ server_example.cpp
1704+ glog_logger.cpp
1705+ server_example_test_client.cpp
1706+)
1707+
1708+target_link_libraries(mir_demo_server_loadable
1709+ mirserver
1710+ exampleserverconfig
1711+ ${GLog_LIBRARY}
1712+ ${GFlags_LIBRARY}
1713+ ${Boost_LIBRARIES}
1714+)
1715+
1716+install(TARGETS mir_demo_server_loadable
1717+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
1718+)
1719+
1720+mir_add_wrapped_executable(mir_demo_server_loader
1721+ mir_demo_server_loader.cpp
1722+)
1723+
1724+target_link_libraries(mir_demo_server_loader
1725+ dl
1726+)
1727+
1728 mir_add_wrapped_executable(mir_demo_server_minimal server_minimal.cpp)
1729 target_link_libraries(mir_demo_server_minimal mirserver)
1730
1731
1732=== modified file 'examples/basic.c'
1733--- examples/basic.c 2015-03-31 02:35:42 +0000
1734+++ examples/basic.c 2015-07-23 14:41:37 +0000
1735@@ -91,7 +91,7 @@
1736
1737 ///\internal [connect_tag]
1738 // Call mir_connect and wait for callback to complete.
1739- mir_wait_for(mir_connect(server, __PRETTY_FUNCTION__, connection_callback, &mcd));
1740+ mir_wait_for(mir_connect(server, __FILE__, connection_callback, &mcd));
1741 puts("Connected");
1742 ///\internal [connect_tag]
1743
1744@@ -125,7 +125,7 @@
1745 MirSurfaceSpec *spec =
1746 mir_connection_create_spec_for_normal_surface(mcd.connection, 640, 480, pixel_format);
1747 assert(spec != NULL);
1748- mir_surface_spec_set_name(spec, __PRETTY_FUNCTION__);
1749+ mir_surface_spec_set_name(spec, __FILE__);
1750
1751 ///\internal [surface_create_tag]
1752 // ...we create a surface using that format and wait for callback to complete.
1753
1754=== added file 'examples/client_helpers.cpp'
1755--- examples/client_helpers.cpp 1970-01-01 00:00:00 +0000
1756+++ examples/client_helpers.cpp 2015-07-23 14:41:37 +0000
1757@@ -0,0 +1,204 @@
1758+/*
1759+ * Copyright © 2015 Canonical Ltd.
1760+ *
1761+ * This program is free software: you can redistribute it and/or modify
1762+ * it under the terms of the GNU General Public License version 3 as
1763+ * published by the Free Software Foundation.
1764+ *
1765+ * This program is distributed in the hope that it will be useful,
1766+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1767+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1768+ * GNU General Public License for more details.
1769+ *
1770+ * You should have received a copy of the GNU General Public License
1771+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1772+ *
1773+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1774+ */
1775+
1776+#include "client_helpers.h"
1777+#include "mir_toolkit/mir_client_library.h"
1778+#include <thread>
1779+#include <chrono>
1780+#include <iostream>
1781+#include <cstring>
1782+#include <unistd.h>
1783+#include <signal.h>
1784+
1785+namespace me = mir::examples;
1786+
1787+me::Connection::Connection(char const* socket_file) :
1788+ connection(mir_connect_sync(socket_file, __PRETTY_FUNCTION__))
1789+{
1790+ if (!mir_connection_is_valid(connection))
1791+ throw std::runtime_error(std::string("could not connect to server: ") +
1792+ mir_connection_get_error_message(connection));
1793+}
1794+
1795+me::Connection::~Connection()
1796+{
1797+ mir_connection_release(connection);
1798+}
1799+
1800+me::Connection::operator MirConnection*()
1801+{
1802+ return connection;
1803+}
1804+
1805+me::NormalSurface::NormalSurface(me::Connection& connection, unsigned int width, unsigned int height) :
1806+ surface{create_surface(connection, width, height), surface_deleter}
1807+{
1808+}
1809+
1810+me::NormalSurface::operator MirSurface*() const
1811+{
1812+ return surface.get();
1813+}
1814+
1815+MirSurface* me::NormalSurface::create_surface(MirConnection* connection, unsigned int width, unsigned int height)
1816+{
1817+ MirPixelFormat selected_format;
1818+ unsigned int valid_formats{0};
1819+ MirPixelFormat pixel_formats[mir_pixel_formats];
1820+ mir_connection_get_available_surface_formats(connection, pixel_formats, mir_pixel_formats, &valid_formats);
1821+ if (valid_formats == 0)
1822+ throw std::runtime_error("no pixel formats for surface");
1823+ selected_format = pixel_formats[0];
1824+ //select an 8 bit opaque format if we can
1825+ for(auto i = 0u; i < valid_formats; i++)
1826+ {
1827+ if (pixel_formats[i] == mir_pixel_format_xbgr_8888 ||
1828+ pixel_formats[i] == mir_pixel_format_xrgb_8888)
1829+ {
1830+ selected_format = pixel_formats[i];
1831+ break;
1832+ }
1833+ }
1834+
1835+ auto deleter = [](MirSurfaceSpec *spec) { mir_surface_spec_release(spec); };
1836+ std::unique_ptr<MirSurfaceSpec, decltype(deleter)> spec{
1837+ mir_connection_create_spec_for_normal_surface(connection, width, height, selected_format),
1838+ deleter
1839+ };
1840+
1841+ mir_surface_spec_set_name(spec.get(), __PRETTY_FUNCTION__);
1842+ mir_surface_spec_set_buffer_usage(spec.get(), mir_buffer_usage_hardware);
1843+ auto surface = mir_surface_create_sync(spec.get());
1844+ return surface;
1845+}
1846+
1847+me::Context::Context(Connection& connection, MirSurface* surface, int swap_interval) :
1848+ native_display(reinterpret_cast<EGLNativeDisplayType>(
1849+ mir_connection_get_egl_native_display(connection))),
1850+ native_window(reinterpret_cast<EGLNativeWindowType>(
1851+ mir_buffer_stream_get_egl_native_window(mir_surface_get_buffer_stream(surface)))),
1852+ display(native_display),
1853+ config(chooseconfig(display.disp)),
1854+ surface(display.disp, config, native_window),
1855+ context(display.disp, config)
1856+{
1857+ make_current();
1858+ eglSwapInterval(display.disp, swap_interval);
1859+}
1860+
1861+void me::Context::make_current()
1862+{
1863+ if (eglMakeCurrent(display.disp, surface.surface, surface.surface, context.context) == EGL_FALSE)
1864+ throw(std::runtime_error("could not makecurrent"));
1865+}
1866+
1867+void me::Context::release_current()
1868+{
1869+ if (eglMakeCurrent(display.disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_FALSE)
1870+ throw(std::runtime_error("could not makecurrent"));
1871+}
1872+void me::Context::swapbuffers()
1873+{
1874+ if (eglSwapBuffers(display.disp, surface.surface) == EGL_FALSE)
1875+ throw(std::runtime_error("could not swapbuffers"));
1876+}
1877+
1878+EGLConfig me::Context::chooseconfig(EGLDisplay disp)
1879+{
1880+ int n{0};
1881+ EGLConfig egl_config;
1882+ EGLint attribs[] = {
1883+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
1884+ EGL_RED_SIZE, 8,
1885+ EGL_GREEN_SIZE, 8,
1886+ EGL_BLUE_SIZE, 8,
1887+ EGL_ALPHA_SIZE, 8,
1888+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
1889+ EGL_NONE };
1890+ if (eglChooseConfig(disp, attribs, &egl_config, 1, &n) != EGL_TRUE || n != 1)
1891+ throw std::runtime_error("could not find egl config");
1892+ return egl_config;
1893+}
1894+
1895+me::Context::Display::Display(EGLNativeDisplayType native) :
1896+ disp(eglGetDisplay(native))
1897+{
1898+ int major{0}, minor{0};
1899+ if (disp == EGL_NO_DISPLAY)
1900+ throw std::runtime_error("no egl display");
1901+ if (eglInitialize(disp, &major, &minor) != EGL_TRUE || major != 1 || minor != 4)
1902+ throw std::runtime_error("could not init egl");
1903+}
1904+
1905+me::Context::Display::~Display()
1906+{
1907+ eglTerminate(disp);
1908+}
1909+
1910+me::Context::Surface::Surface(EGLDisplay display, EGLConfig config, EGLNativeWindowType native_window) :
1911+ disp(display),
1912+ surface(eglCreateWindowSurface(disp, config, native_window, NULL))
1913+{
1914+ if (surface == EGL_NO_SURFACE)
1915+ throw std::runtime_error("could not create egl surface");
1916+}
1917+
1918+me::Context::Surface::~Surface()
1919+{
1920+ if (eglGetCurrentSurface(EGL_DRAW) == surface)
1921+ eglMakeCurrent(disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
1922+ eglDestroySurface(disp, surface);
1923+}
1924+
1925+me::Context::EglContext::EglContext(EGLDisplay disp, EGLConfig config) :
1926+ disp(disp),
1927+ context(eglCreateContext(disp, config, EGL_NO_CONTEXT, context_attribs))
1928+{
1929+ if (context == EGL_NO_CONTEXT)
1930+ throw std::runtime_error("could not create egl context");
1931+}
1932+
1933+me::Context::EglContext::~EglContext()
1934+{
1935+ eglDestroyContext(disp, context);
1936+}
1937+
1938+me::Shader::Shader(GLchar const* const* src, GLuint type) :
1939+ shader(glCreateShader(type))
1940+{
1941+ glShaderSource(shader, 1, src, 0);
1942+ glCompileShader(shader);
1943+}
1944+
1945+me::Shader::~Shader()
1946+{
1947+ glDeleteShader(shader);
1948+}
1949+
1950+me::Program::Program(Shader& vertex, Shader& fragment) :
1951+ program(glCreateProgram())
1952+{
1953+ glAttachShader(program, vertex.shader);
1954+ glAttachShader(program, fragment.shader);
1955+ glLinkProgram(program);
1956+}
1957+
1958+me::Program::~Program()
1959+{
1960+ glDeleteProgram(program);
1961+}
1962
1963=== added file 'examples/client_helpers.h'
1964--- examples/client_helpers.h 1970-01-01 00:00:00 +0000
1965+++ examples/client_helpers.h 2015-07-23 14:41:37 +0000
1966@@ -0,0 +1,110 @@
1967+/*
1968+ * Copyright © 2015 Canonical Ltd.
1969+ *
1970+ * This program is free software: you can redistribute it and/or modify
1971+ * it under the terms of the GNU General Public License version 3 as
1972+ * published by the Free Software Foundation.
1973+ *
1974+ * This program is distributed in the hope that it will be useful,
1975+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1976+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1977+ * GNU General Public License for more details.
1978+ *
1979+ * You should have received a copy of the GNU General Public License
1980+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1981+ *
1982+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1983+ */
1984+
1985+#ifndef MIR_EXAMLPES_CLIENT_HELPERS_H_
1986+#define MIR_EXAMLPES_CLIENT_HELPERS_H_
1987+
1988+#include "mir_toolkit/mir_client_library.h"
1989+#include <EGL/egl.h>
1990+#include <GLES2/gl2.h>
1991+#include <memory>
1992+
1993+namespace mir
1994+{
1995+namespace examples
1996+{
1997+class Connection
1998+{
1999+public:
2000+ Connection(char const* socket_file);
2001+ ~Connection();
2002+ operator MirConnection*();
2003+ Connection(Connection const&) = delete;
2004+ Connection& operator=(Connection const&) = delete;
2005+private:
2006+ MirConnection* connection;
2007+};
2008+
2009+class NormalSurface
2010+{
2011+public:
2012+ NormalSurface(Connection& connection, unsigned int width, unsigned int height);
2013+ operator MirSurface*() const;
2014+private:
2015+ MirSurface* create_surface(MirConnection* connection, unsigned int width, unsigned int height);
2016+ std::function<void(MirSurface*)> const surface_deleter{
2017+ [](MirSurface* surface) { mir_surface_release_sync(surface); }
2018+ };
2019+ std::unique_ptr<MirSurface, decltype(surface_deleter)> surface;
2020+ NormalSurface(NormalSurface const&) = delete;
2021+ NormalSurface& operator=(NormalSurface const&) = delete;
2022+};
2023+
2024+class Context
2025+{
2026+public:
2027+ Context(Connection& connection, MirSurface* surface, int swap_interval);
2028+ void make_current();
2029+ void release_current();
2030+ void swapbuffers();
2031+ Context(Context const&) = delete;
2032+ Context& operator=(Context const&) = delete;
2033+private:
2034+ EGLConfig chooseconfig(EGLDisplay disp);
2035+ EGLNativeDisplayType native_display;
2036+ EGLNativeWindowType native_window;
2037+ struct Display
2038+ {
2039+ Display(EGLNativeDisplayType native);
2040+ ~Display();
2041+ EGLDisplay disp;
2042+ } display;
2043+ EGLConfig config;
2044+ struct Surface
2045+ {
2046+ Surface(EGLDisplay display, EGLConfig config, EGLNativeWindowType native_window);
2047+ ~Surface();
2048+ EGLDisplay disp;
2049+ EGLSurface surface;
2050+ } surface;
2051+ struct EglContext
2052+ {
2053+ EglContext(EGLDisplay disp, EGLConfig config);
2054+ ~EglContext();
2055+ EGLint context_attribs[3] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
2056+ EGLDisplay disp;
2057+ EGLContext context;
2058+ } context;
2059+};
2060+
2061+struct Shader
2062+{
2063+ Shader(GLchar const* const* src, GLuint type);
2064+ ~Shader();
2065+ GLuint shader;
2066+};
2067+
2068+struct Program
2069+{
2070+ Program(Shader& vertex, Shader& fragment);
2071+ ~Program();
2072+ GLuint program;
2073+};
2074+}
2075+}
2076+#endif /* MIR_EXAMLPES_CLIENT_HELPERS_H_ */
2077
2078=== added file 'examples/client_touch_validator.cpp'
2079--- examples/client_touch_validator.cpp 1970-01-01 00:00:00 +0000
2080+++ examples/client_touch_validator.cpp 2015-07-23 14:41:37 +0000
2081@@ -0,0 +1,200 @@
2082+/*
2083+ * Client which validates incoming touch events.
2084+ *
2085+ * Copyright © 2015 Canonical Ltd.
2086+ *
2087+ * This program is free software: you can redistribute it and/or modify
2088+ * it under the terms of the GNU General Public License version 3 as
2089+ * published by the Free Software Foundation.
2090+ *
2091+ * This program is distributed in the hope that it will be useful,
2092+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2093+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2094+ * GNU General Public License for more details.
2095+ *
2096+ * You should have received a copy of the GNU General Public License
2097+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2098+ *
2099+ * Author: Robert Carr <robert.carr@canonical.com>
2100+ */
2101+
2102+#include "eglapp.h"
2103+
2104+#include <mir_toolkit/mir_client_library.h>
2105+
2106+#include <GLES2/gl2.h>
2107+
2108+#include <set>
2109+
2110+#include <stdio.h>
2111+#include <stdlib.h>
2112+#include <unistd.h>
2113+
2114+namespace
2115+{
2116+// Assumes all touch input comes from a single device.
2117+// Validates:
2118+// 1. All touches which were down stay down unless they were coming up
2119+// 2. All touches which were released do not appear
2120+// 3. Only one touch comes up or down at a time.
2121+
2122+bool validate_events(MirTouchEvent const* last_event, MirTouchEvent const* event)
2123+{
2124+ std::set<MirTouchId> must_be_present;
2125+ std::set<MirTouchId> may_not_be_present;
2126+
2127+ // Here, from the last event, we build a list of points which must be
2128+ // and which must not be present in the next event.
2129+ for (size_t i = 0; i < mir_touch_event_point_count(last_event); i++)
2130+ {
2131+ auto id = mir_touch_event_id(last_event, i);
2132+ auto action = mir_touch_event_action(last_event, i);
2133+ if (action == mir_touch_action_change)
2134+ must_be_present.insert(id);
2135+ else if (action == mir_touch_action_down)
2136+ must_be_present.insert(id);
2137+ else
2138+ may_not_be_present.insert(id);
2139+ }
2140+ if (may_not_be_present.size() > 1)
2141+ {
2142+ printf("More than one touch came up\n");
2143+ return false;
2144+ }
2145+
2146+ bool found_a_up_down = false;
2147+ for (size_t i = 0; i < mir_touch_event_point_count(event); i++)
2148+ {
2149+ auto id = mir_touch_event_id(event, i);
2150+ auto it = may_not_be_present.find(id);
2151+ // Here we validate condition 2, where released touches may not reappear
2152+ if (it != may_not_be_present.end())
2153+ {
2154+ printf("We repeated a touch which was already lifted (%d)\n", static_cast<int>(id));
2155+ return false;
2156+ }
2157+ it = must_be_present.find(id);
2158+ if (it != must_be_present.end())
2159+ {
2160+ must_be_present.erase(it);
2161+ }
2162+ // Here we validate condition 4
2163+ else if (mir_touch_event_action(event, i) == mir_touch_action_down)
2164+ {
2165+ if (found_a_up_down)
2166+ printf("Found too many downs in one event\n");
2167+ found_a_up_down = true;
2168+ }
2169+ if (mir_touch_event_action(event, i) == mir_touch_action_up)
2170+ {
2171+ if (found_a_up_down)
2172+ printf("Found too many ups in one event\n");
2173+ found_a_up_down = true;
2174+ }
2175+ }
2176+
2177+ // Here we validate condition 1
2178+ if (must_be_present.size())
2179+ {
2180+ printf("We received a touch which did not contain all required IDs\n");
2181+ return false;
2182+ }
2183+
2184+ return true;
2185+}
2186+
2187+class TouchState
2188+{
2189+public:
2190+ TouchState() : last_event(nullptr) {}
2191+ ~TouchState() { if (last_event) mir_event_unref(last_event); }
2192+
2193+ void record_event(MirTouchEvent const* event)
2194+ {
2195+ if (!last_event)
2196+ {
2197+ last_event = mir_event_ref(reinterpret_cast<MirEvent const*>(event));
2198+ return;
2199+ }
2200+ if (!validate_events(reinterpret_cast<MirTouchEvent const*>(last_event), event))
2201+ abort();
2202+
2203+ mir_event_unref(last_event);
2204+ last_event = mir_event_ref(reinterpret_cast<MirEvent const*>(event));
2205+ }
2206+private:
2207+ MirEvent const* last_event;
2208+};
2209+
2210+void on_input_event(TouchState *state, MirInputEvent const *event)
2211+{
2212+ if (mir_input_event_get_type(event) != mir_input_event_type_touch)
2213+ return;
2214+ auto tev = mir_input_event_get_touch_event(event);
2215+ state->record_event(tev);
2216+}
2217+
2218+void on_event(MirSurface * /*surface*/, const MirEvent *event, void *context)
2219+{
2220+ TouchState *state = (TouchState*)context;
2221+
2222+ switch (mir_event_get_type(event))
2223+ {
2224+ case mir_event_type_input:
2225+ on_input_event(state, mir_event_get_input_event(event));
2226+ break;
2227+ case mir_event_type_close_surface:
2228+ abort();
2229+ break;
2230+ default:
2231+ break;
2232+ }
2233+}
2234+}
2235+
2236+
2237+typedef struct Color
2238+{
2239+ GLfloat r, g, b, a;
2240+} Color;
2241+
2242+int main(int argc, char *argv[])
2243+{
2244+ unsigned int width = 0, height = 0;
2245+
2246+ if (!mir_eglapp_init(argc, argv, &width, &height))
2247+ return 1;
2248+
2249+ TouchState state;
2250+
2251+ MirSurface *surface = mir_eglapp_native_surface();
2252+ mir_surface_set_event_handler(surface, on_event, &state);
2253+
2254+ float const opacity = mir_eglapp_background_opacity;
2255+ Color red = {opacity, 0.0f, 0.0f, opacity};
2256+ Color green = {0.0f, opacity, 0.0f, opacity};
2257+ Color blue = {0.0f, 0.0f, opacity, opacity};
2258+
2259+ /* This is probably the simplest GL you can do */
2260+ while (mir_eglapp_running())
2261+ {
2262+ glClearColor(red.r, red.g, red.b, red.a);
2263+ glClear(GL_COLOR_BUFFER_BIT);
2264+ mir_eglapp_swap_buffers();
2265+ sleep(1);
2266+
2267+ glClearColor(green.r, green.g, green.b, green.a);
2268+ glClear(GL_COLOR_BUFFER_BIT);
2269+ mir_eglapp_swap_buffers();
2270+ sleep(1);
2271+
2272+ glClearColor(blue.r, blue.g, blue.b, blue.a);
2273+ glClear(GL_COLOR_BUFFER_BIT);
2274+ mir_eglapp_swap_buffers();
2275+ sleep(1);
2276+ }
2277+
2278+ mir_eglapp_shutdown();
2279+
2280+ return 0;
2281+}
2282
2283=== modified file 'examples/eglsquare.cpp'
2284--- examples/eglsquare.cpp 2015-04-24 14:11:07 +0000
2285+++ examples/eglsquare.cpp 2015-07-23 14:41:37 +0000
2286@@ -27,139 +27,16 @@
2287 #include <unistd.h>
2288 #include <signal.h>
2289
2290+#include "client_helpers.h"
2291+
2292+namespace me = mir::examples;
2293+
2294 namespace
2295 {
2296-class Connection
2297-{
2298-public:
2299- Connection(char const* socket_file) :
2300- connection(mir_connect_sync(socket_file, __PRETTY_FUNCTION__))
2301- {
2302- if (!mir_connection_is_valid(connection))
2303- throw std::runtime_error(std::string("could not connect to server: ") +
2304- mir_connection_get_error_message(connection));
2305- }
2306- ~Connection()
2307- {
2308- mir_connection_release(connection);
2309- }
2310- operator MirConnection*() { return connection; }
2311- Connection(Connection const&) = delete;
2312- Connection& operator=(Connection const&) = delete;
2313-private:
2314- MirConnection* connection;
2315-};
2316-
2317-class Context
2318-{
2319-public:
2320- Context(Connection& connection, MirSurface* surface, int swap_interval) :
2321- native_display(reinterpret_cast<EGLNativeDisplayType>(
2322- mir_connection_get_egl_native_display(connection))),
2323- native_window(reinterpret_cast<EGLNativeWindowType>(
2324- mir_buffer_stream_get_egl_native_window(mir_surface_get_buffer_stream(surface)))),
2325- display(native_display),
2326- config(chooseconfig(display.disp)),
2327- surface(display.disp, config, native_window),
2328- context(display.disp, config)
2329- {
2330- make_current();
2331- eglSwapInterval(display.disp, swap_interval);
2332- }
2333- void make_current()
2334- {
2335- if (eglMakeCurrent(display.disp, surface.surface, surface.surface, context.context) == EGL_FALSE)
2336- throw(std::runtime_error("could not makecurrent"));
2337- }
2338- void release_current()
2339- {
2340- if (eglMakeCurrent(display.disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_FALSE)
2341- throw(std::runtime_error("could not makecurrent"));
2342- }
2343- void swapbuffers()
2344- {
2345- if (eglSwapBuffers(display.disp, surface.surface) == EGL_FALSE)
2346- throw(std::runtime_error("could not swapbuffers"));
2347- }
2348- Context(Context const&) = delete;
2349- Context& operator=(Context const&) = delete;
2350-private:
2351- EGLConfig chooseconfig(EGLDisplay disp)
2352- {
2353- int n{0};
2354- EGLConfig egl_config;
2355- EGLint attribs[] = {
2356- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
2357- EGL_RED_SIZE, 8,
2358- EGL_GREEN_SIZE, 8,
2359- EGL_BLUE_SIZE, 8,
2360- EGL_ALPHA_SIZE, 8,
2361- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
2362- EGL_NONE };
2363- if (eglChooseConfig(disp, attribs, &egl_config, 1, &n) != EGL_TRUE || n != 1)
2364- throw std::runtime_error("could not find egl config");
2365- return egl_config;
2366- }
2367- EGLNativeDisplayType native_display;
2368- EGLNativeWindowType native_window;
2369- struct Display
2370- {
2371- Display(EGLNativeDisplayType native) :
2372- disp(eglGetDisplay(native))
2373- {
2374- int major{0}, minor{0};
2375- if (disp == EGL_NO_DISPLAY)
2376- throw std::runtime_error("no egl display");
2377- if (eglInitialize(disp, &major, &minor) != EGL_TRUE || major != 1 || minor != 4)
2378- throw std::runtime_error("could not init egl");
2379- }
2380- ~Display()
2381- {
2382- eglTerminate(disp);
2383- }
2384- EGLDisplay disp;
2385- } display;
2386- EGLConfig config;
2387- struct Surface
2388- {
2389- Surface(EGLDisplay display, EGLConfig config, EGLNativeWindowType native_window) :
2390- disp(display),
2391- surface(eglCreateWindowSurface(disp, config, native_window, NULL))
2392- {
2393- if (surface == EGL_NO_SURFACE)
2394- throw std::runtime_error("could not create egl surface");
2395- }
2396- ~Surface() {
2397- if (eglGetCurrentSurface(EGL_DRAW) == surface)
2398- eglMakeCurrent(disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
2399- eglDestroySurface(disp, surface);
2400- }
2401- EGLDisplay disp;
2402- EGLSurface surface;
2403- } surface;
2404- struct EglContext
2405- {
2406- EglContext(EGLDisplay disp, EGLConfig config) :
2407- disp(disp),
2408- context(eglCreateContext(disp, config, EGL_NO_CONTEXT, context_attribs))
2409- {
2410- if (context == EGL_NO_CONTEXT)
2411- throw std::runtime_error("could not create egl context");
2412- }
2413- ~EglContext()
2414- {
2415- eglDestroyContext(disp, context);
2416- }
2417- EGLint context_attribs[3] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
2418- EGLDisplay disp;
2419- EGLContext context;
2420- } context;
2421-};
2422-
2423 class RenderProgram
2424 {
2425 public:
2426- RenderProgram(Context& context, unsigned int width, unsigned int height) :
2427+ RenderProgram(me::Context& context, unsigned int width, unsigned int height) :
2428 vertex(&vtex_shader_src, GL_VERTEX_SHADER),
2429 fragment(&frag_shader_src, GL_FRAGMENT_SHADER),
2430 program(vertex, fragment)
2431@@ -209,35 +86,9 @@
2432 " gl_Position = vec4(vPosition.xy * scale + pos, 0.0, 1.0);"
2433 "}"
2434 };
2435- struct Shader
2436- {
2437- Shader(GLchar const* const* src, GLuint type) :
2438- shader(glCreateShader(type))
2439- {
2440- glShaderSource(shader, 1, src, 0);
2441- glCompileShader(shader);
2442- }
2443- ~Shader()
2444- {
2445- glDeleteShader(shader);
2446- }
2447- GLuint shader;
2448- } vertex, fragment;
2449- struct Program
2450- {
2451- Program(Shader& vertex, Shader& fragment) :
2452- program(glCreateProgram())
2453- {
2454- glAttachShader(program, vertex.shader);
2455- glAttachShader(program, fragment.shader);
2456- glLinkProgram(program);
2457- }
2458- ~Program()
2459- {
2460- glDeleteProgram(program);
2461- }
2462- GLuint program;
2463- } program;
2464+ me::Shader vertex;
2465+ me::Shader fragment;
2466+ me::Program program;
2467 GLfloat vertex_data[16]
2468 {
2469 -1.0, -1.0f, 0.0f, 1.0f,
2470@@ -249,15 +100,16 @@
2471 GLuint posUniform;
2472 };
2473
2474-class Surface
2475+class SquareRenderingSurface
2476 {
2477 public:
2478- Surface(Connection& connection, int swap_interval) :
2479+ SquareRenderingSurface(me::Connection& connection, int swap_interval) :
2480 dimensions(active_output_dimensions(connection)),
2481- surface{create_surface(connection, dimensions), surface_deleter},
2482- context{connection, surface.get(), swap_interval},
2483+ surface{connection, dimensions.width, dimensions.height},
2484+ context{connection, surface, swap_interval},
2485 program{context, dimensions.width, dimensions.height}
2486 {
2487+ mir_surface_set_event_handler(surface, &on_event, this);
2488 }
2489
2490 void on_event(MirEvent const* ev)
2491@@ -290,8 +142,8 @@
2492 context.swapbuffers();
2493 }
2494
2495- Surface(Surface const&) = delete;
2496- Surface& operator=(Surface const&) = delete;
2497+ SquareRenderingSurface(SquareRenderingSurface const&) = delete;
2498+ SquareRenderingSurface& operator=(SquareRenderingSurface const&) = delete;
2499 private:
2500 struct OutputDimensions
2501 {
2502@@ -299,15 +151,8 @@
2503 unsigned int const height;
2504 } const dimensions;
2505
2506-
2507- std::function<void(MirSurface*)> const surface_deleter{
2508- [](MirSurface* surface)
2509- {
2510- mir_surface_release_sync(surface);
2511- }
2512- };
2513- std::unique_ptr<MirSurface, decltype(surface_deleter)> surface;
2514- Context context;
2515+ me::NormalSurface surface;
2516+ me::Context context;
2517 RenderProgram program;
2518
2519 OutputDimensions active_output_dimensions(MirConnection* connection)
2520@@ -334,45 +179,12 @@
2521 return {width, height};
2522 }
2523
2524- MirSurface* create_surface(MirConnection* connection, OutputDimensions const& dim)
2525- {
2526- MirPixelFormat selected_format;
2527- unsigned int valid_formats{0};
2528- MirPixelFormat pixel_formats[mir_pixel_formats];
2529- mir_connection_get_available_surface_formats(connection, pixel_formats, mir_pixel_formats, &valid_formats);
2530- if (valid_formats == 0)
2531- throw std::runtime_error("no pixel formats for surface");
2532- selected_format = pixel_formats[0];
2533- //select an 8 bit opaque format if we can
2534- for(auto i = 0u; i < valid_formats; i++)
2535- {
2536- if (pixel_formats[i] == mir_pixel_format_xbgr_8888 ||
2537- pixel_formats[i] == mir_pixel_format_xrgb_8888)
2538- {
2539- selected_format = pixel_formats[i];
2540- break;
2541- }
2542- }
2543-
2544- auto deleter = [](MirSurfaceSpec *spec) { mir_surface_spec_release(spec); };
2545- std::unique_ptr<MirSurfaceSpec, decltype(deleter)> spec{
2546- mir_connection_create_spec_for_normal_surface(connection, dim.width, dim.height, selected_format),
2547- deleter
2548- };
2549-
2550- mir_surface_spec_set_name(spec.get(), __PRETTY_FUNCTION__);
2551- mir_surface_spec_set_buffer_usage(spec.get(), mir_buffer_usage_hardware);
2552- auto surface = mir_surface_create_sync(spec.get());
2553- mir_surface_set_event_handler(surface, &on_event, this);
2554- return surface;
2555- }
2556 static void on_event(MirSurface*, const MirEvent *event, void *context)
2557 {
2558- auto surface = reinterpret_cast<Surface*>(context);
2559+ auto surface = reinterpret_cast<SquareRenderingSurface*>(context);
2560 if (surface) surface->on_event(event);
2561 }
2562 };
2563-
2564 }
2565
2566 int main(int argc, char *argv[])
2567@@ -398,8 +210,8 @@
2568 }
2569 }
2570
2571- Connection connection(socket_file);
2572- Surface surface(connection, swap_interval);
2573+ me::Connection connection(socket_file);
2574+ SquareRenderingSurface surface(connection, swap_interval);
2575
2576 sigset_t sigset;
2577 siginfo_t siginfo;
2578
2579=== modified file 'examples/flicker.c'
2580--- examples/flicker.c 2015-03-31 02:35:42 +0000
2581+++ examples/flicker.c 2015-07-23 14:41:37 +0000
2582@@ -129,7 +129,7 @@
2583
2584 puts("Starting");
2585
2586- connection = mir_connect_sync(socket_file, __PRETTY_FUNCTION__);
2587+ connection = mir_connect_sync(socket_file, __FILE__);
2588 assert(connection != NULL);
2589 assert(mir_connection_is_valid(connection));
2590 assert(strcmp(mir_connection_get_error_message(connection), "") == 0);
2591@@ -144,7 +144,7 @@
2592 MirSurfaceSpec *spec =
2593 mir_connection_create_spec_for_normal_surface(connection, 640, 480, pixel_format);
2594 assert(spec != NULL);
2595- mir_surface_spec_set_name(spec, __PRETTY_FUNCTION__);
2596+ mir_surface_spec_set_name(spec, __FILE__);
2597 mir_surface_spec_set_buffer_usage(spec, mir_buffer_usage_software);
2598
2599 surface = mir_surface_create_sync(spec);
2600
2601=== added file 'examples/mir_demo_server_loader.cpp'
2602--- examples/mir_demo_server_loader.cpp 1970-01-01 00:00:00 +0000
2603+++ examples/mir_demo_server_loader.cpp 2015-07-23 14:41:37 +0000
2604@@ -0,0 +1,46 @@
2605+/*
2606+ * Copyright © 2015 Canonical Ltd.
2607+ *
2608+ * This program is free software: you can redistribute it and/or modify
2609+ * it under the terms of the GNU General Public License version 3 as
2610+ * published by the Free Software Foundation.
2611+ *
2612+ * This program is distributed in the hope that it will be useful,
2613+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2614+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2615+ * GNU General Public License for more details.
2616+ *
2617+ * You should have received a copy of the GNU General Public License
2618+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2619+ *
2620+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
2621+ */
2622+
2623+#include <dlfcn.h>
2624+#include <stdexcept>
2625+#include <iostream>
2626+
2627+namespace
2628+{
2629+const char* const library = "libmir_demo_server_loadable.so";
2630+const char* const entry = "main";
2631+}
2632+
2633+int main(int argc, char const* argv[])
2634+try
2635+{
2636+ auto const so = dlopen(library, RTLD_NOW|RTLD_LOCAL);
2637+ if (!so) throw std::runtime_error(dlerror());
2638+
2639+ int (*loaded_main)(int, char const*[]){nullptr};
2640+
2641+ (void*&)loaded_main = dlsym(so, entry);
2642+ if (!loaded_main) throw std::runtime_error(dlerror());
2643+
2644+ return loaded_main(argc, argv);
2645+
2646+}
2647+catch(std::exception const& x)
2648+{
2649+ std::cerr << "Error:" << x.what() << std::endl;
2650+}
2651
2652=== modified file 'examples/render_surfaces.cpp'
2653--- examples/render_surfaces.cpp 2015-04-27 18:42:54 +0000
2654+++ examples/render_surfaces.cpp 2015-07-23 14:41:37 +0000
2655@@ -30,6 +30,8 @@
2656 #include "mir/options/option.h"
2657 #include "mir/scene/surface.h"
2658 #include "mir/scene/surface_coordinator.h"
2659+#include "mir/scene/buffer_stream_factory.h"
2660+#include "mir/scene/surface_factory.h"
2661 #include "mir/server.h"
2662 #include "mir/report_exception.h"
2663
2664@@ -331,6 +333,8 @@
2665 std::cout << "Rendering " << moveables.size() << " surfaces" << std::endl;
2666
2667 auto const display = the_display();
2668+ auto const buffer_stream_factory = the_buffer_stream_factory();
2669+ auto const surface_factory = the_surface_factory();
2670 auto const surface_coordinator = the_surface_coordinator();
2671 auto const gl_context = the_display()->create_gl_context();
2672
2673@@ -355,16 +359,19 @@
2674 int i = 0;
2675 for (auto& m : moveables)
2676 {
2677- auto const s = surface_coordinator->add_surface(
2678- ms::a_surface().of_size(surface_size)
2679- .of_pixel_format(surface_pf)
2680- .of_buffer_usage(mg::BufferUsage::hardware),
2681- nullptr);
2682+ auto params = ms::a_surface()
2683+ .of_size(surface_size)
2684+ .of_pixel_format(surface_pf)
2685+ .of_buffer_usage(mg::BufferUsage::hardware);
2686+ mg::BufferProperties properties{params.size, params.pixel_format, params.buffer_usage};
2687+ auto const stream = buffer_stream_factory->create_buffer_stream(properties);
2688+ auto const surface = surface_factory->create_surface(stream, params);
2689+ surface_coordinator->add_surface(surface, params.depth, params.input_mode, nullptr);
2690
2691 {
2692 mg::Buffer* buffer{nullptr};
2693 auto const complete = [&](mg::Buffer* new_buf){ buffer = new_buf; };
2694- s->swap_buffers(buffer, complete); // Fetch buffer for rendering
2695+ surface->primary_buffer_stream()->swap_buffers(buffer, complete); // Fetch buffer for rendering
2696 {
2697 gl_context->make_current();
2698
2699@@ -377,7 +384,7 @@
2700
2701 gl_context->release_current();
2702 }
2703- s->swap_buffers(buffer, complete); // Post rendered buffer
2704+ surface->primary_buffer_stream()->swap_buffers(buffer, complete); // Post rendered buffer
2705 }
2706
2707 /*
2708@@ -387,8 +394,8 @@
2709 uint32_t const x = w * (0.5 + 0.25 * cos(i * angular_step)) - surface_side / 2.0;
2710 uint32_t const y = h * (0.5 + 0.25 * sin(i * angular_step)) - surface_side / 2.0;
2711
2712- s->move_to({x, y});
2713- m = Moveable(s, display_size,
2714+ surface->move_to({x, y});
2715+ m = Moveable(surface, display_size,
2716 cos(0.1f + i * M_PI / 6.0f) * w / 3.0f,
2717 sin(0.1f + i * M_PI / 6.0f) * h / 3.0f,
2718 glm::vec3{(i % 3 == 0) * 1.0f, (i % 3 == 1) * 1.0f, (i % 3 == 2) * 1.0f},
2719
2720=== modified file 'examples/server_example_basic_window_manager.h'
2721--- examples/server_example_basic_window_manager.h 2015-04-23 07:11:04 +0000
2722+++ examples/server_example_basic_window_manager.h 2015-07-23 14:41:37 +0000
2723@@ -81,6 +81,8 @@
2724
2725 virtual auto active_display() -> geometry::Rectangle const = 0;
2726
2727+ virtual void forget(std::weak_ptr<scene::Surface> const& surface) = 0;
2728+
2729 virtual ~BasicWindowManagerToolsCopy() = default;
2730 BasicWindowManagerToolsCopy() = default;
2731 BasicWindowManagerToolsCopy(BasicWindowManagerToolsCopy const&) = delete;
2732@@ -170,6 +172,11 @@
2733 surface_info.erase(surface);
2734 }
2735
2736+ void forget(std::weak_ptr<scene::Surface> const& surface) override
2737+ {
2738+ surface_info.erase(surface);
2739+ }
2740+
2741 void add_display(geometry::Rectangle const& area) override
2742 {
2743 std::lock_guard<decltype(mutex)> lock(mutex);
2744
2745=== modified file 'examples/server_example_canonical_window_manager.cpp'
2746--- examples/server_example_canonical_window_manager.cpp 2015-04-30 05:09:11 +0000
2747+++ examples/server_example_canonical_window_manager.cpp 2015-07-23 14:41:37 +0000
2748@@ -19,7 +19,7 @@
2749 #include "server_example_canonical_window_manager.h"
2750
2751 #include "mir/scene/surface.h"
2752-#include "mir/scene/null_surface_observer.h"
2753+#include "mir/shell/surface_ready_observer.h"
2754 #include "mir/shell/display_layout.h"
2755 #include "mir/shell/surface_specification.h"
2756 #include "mir/geometry/displacement.h"
2757@@ -28,8 +28,6 @@
2758
2759 #include <linux/input.h>
2760 #include <csignal>
2761-#include <mutex>
2762-#include <condition_variable>
2763 #include <algorithm>
2764
2765 namespace me = mir::examples;
2766@@ -54,20 +52,37 @@
2767 window_position.y - DeltaY(title_bar_height)
2768 };
2769 }
2770+
2771+bool needs_titlebar(MirSurfaceType type)
2772+{
2773+ switch (type)
2774+ {
2775+ case mir_surface_type_freestyle:
2776+ case mir_surface_type_menu:
2777+ case mir_surface_type_inputmethod:
2778+ case mir_surface_type_gloss:
2779+ case mir_surface_type_tip:
2780+ // No decorations for these surface types
2781+ return false;
2782+ default:
2783+ return true;
2784+ }
2785+}
2786 }
2787
2788 me::CanonicalSurfaceInfoCopy::CanonicalSurfaceInfoCopy(
2789 std::shared_ptr<scene::Session> const& session,
2790 std::shared_ptr<scene::Surface> const& surface,
2791 scene::SurfaceCreationParameters const& params) :
2792- state{mir_surface_state_restored},
2793+ type{surface->type()},
2794+ state{surface->state()},
2795 restore_rect{surface->top_left(), surface->size()},
2796 session{session},
2797 parent{params.parent},
2798- min_width{params.min_width},
2799- min_height{params.min_height},
2800- max_width{params.max_width},
2801- max_height{params.max_height},
2802+ min_width{params.min_width.is_set() ? params.min_width.value() : Width{}},
2803+ min_height{params.min_height.is_set() ? params.min_height.value() : Height{}},
2804+ max_width{params.max_width.is_set() ? params.max_width.value() : Width{std::numeric_limits<int>::max()}},
2805+ max_height{params.max_height.is_set() ? params.max_height.value() : Height{std::numeric_limits<int>::max()}},
2806 width_inc{params.width_inc},
2807 height_inc{params.height_inc},
2808 min_aspect{params.min_aspect},
2809@@ -75,6 +90,98 @@
2810 {
2811 }
2812
2813+bool me::CanonicalSurfaceInfoCopy::can_be_active() const
2814+{
2815+ switch (type)
2816+ {
2817+ case mir_surface_type_normal: /**< AKA "regular" */
2818+ case mir_surface_type_utility: /**< AKA "floating" */
2819+ case mir_surface_type_dialog:
2820+ case mir_surface_type_satellite: /**< AKA "toolbox"/"toolbar" */
2821+ case mir_surface_type_freestyle:
2822+ case mir_surface_type_menu:
2823+ case mir_surface_type_inputmethod: /**< AKA "OSK" or handwriting etc. */
2824+ return true;
2825+
2826+ case mir_surface_type_gloss:
2827+ case mir_surface_type_tip: /**< AKA "tooltip" */
2828+ default:
2829+ // Cannot have input focus
2830+ return false;
2831+ }
2832+}
2833+
2834+bool me::CanonicalSurfaceInfoCopy::must_have_parent() const
2835+{
2836+ switch (type)
2837+ {
2838+ case mir_surface_type_overlay:;
2839+ case mir_surface_type_inputmethod:
2840+ case mir_surface_type_satellite:
2841+ case mir_surface_type_tip:
2842+ return true;
2843+
2844+ default:
2845+ return false;
2846+ }
2847+}
2848+
2849+bool me::CanonicalSurfaceInfoCopy::can_morph_to(MirSurfaceType new_type) const
2850+{
2851+ switch (new_type)
2852+ {
2853+ case mir_surface_type_normal:
2854+ case mir_surface_type_utility:
2855+ case mir_surface_type_satellite:
2856+ switch (type)
2857+ {
2858+ case mir_surface_type_normal:
2859+ case mir_surface_type_utility:
2860+ case mir_surface_type_dialog:
2861+ case mir_surface_type_satellite:
2862+ return true;
2863+
2864+ default:
2865+ break;
2866+ }
2867+ break;
2868+
2869+ case mir_surface_type_dialog:
2870+ switch (type)
2871+ {
2872+ case mir_surface_type_normal:
2873+ case mir_surface_type_utility:
2874+ case mir_surface_type_dialog:
2875+ case mir_surface_type_popover:
2876+ case mir_surface_type_satellite:
2877+ return true;
2878+
2879+ default:
2880+ break;
2881+ }
2882+ break;
2883+
2884+ default:
2885+ break;
2886+ }
2887+
2888+ return false;
2889+}
2890+
2891+bool me::CanonicalSurfaceInfoCopy::must_not_have_parent() const
2892+{
2893+ switch (type)
2894+ {
2895+ case mir_surface_type_normal:
2896+ case mir_surface_type_utility:
2897+ return true;
2898+
2899+ default:
2900+ return false;
2901+ }
2902+}
2903+
2904+
2905 me::CanonicalWindowManagerPolicyCopy::CanonicalWindowManagerPolicyCopy(
2906 Tools* const tools,
2907 std::shared_ptr<shell::DisplayLayout> const& display_layout) :
2908@@ -113,7 +220,14 @@
2909 -> ms::SurfaceCreationParameters
2910 {
2911 auto parameters = request_parameters;
2912- parameters.size.height = parameters.size.height + DeltaY{title_bar_height};
2913+ auto surf_type = parameters.type.is_set() ? parameters.type.value() : mir_surface_type_normal;
2914+ bool const needs_titlebar = ::needs_titlebar(surf_type);
2915+
2916+ if (needs_titlebar)
2917+ parameters.size.height = parameters.size.height + DeltaY{title_bar_height};
2918+
2919+ if (!parameters.state.is_set())
2920+ parameters.state = mir_surface_state_restored;
2921
2922 auto const active_display = tools->active_display();
2923
2924@@ -158,7 +272,7 @@
2925 auto const top_right= aux_rect.top_right() -Point{} + parent_top_left;
2926 auto const bot_left = aux_rect.bottom_left()-Point{} + parent_top_left;
2927
2928- if (edge_attachment && mir_edge_attachment_vertical)
2929+ if (edge_attachment & mir_edge_attachment_vertical)
2930 {
2931 if (active_display.contains(top_right + Displacement{width, height}))
2932 {
2933@@ -172,7 +286,7 @@
2934 }
2935 }
2936
2937- if (edge_attachment && mir_edge_attachment_horizontal)
2938+ if (edge_attachment & mir_edge_attachment_horizontal)
2939 {
2940 if (active_display.contains(bot_left + Displacement{width, height}))
2941 {
2942@@ -186,28 +300,119 @@
2943 }
2944 }
2945 }
2946+ else if (parent)
2947+ {
2948+ // o Otherwise, if the dialog is not the same as any previous dialog for the
2949+ // same parent window, and/or it does not have user-customized position:
2950+ // o It should be optically centered relative to its parent, unless this
2951+ // would overlap or cover the title bar of the parent.
2952+ // o Otherwise, it should be cascaded vertically (but not horizontally)
2953+ // relative to its parent, unless, this would cause at least part of
2954+ // it to extend into shell space.
2955+ auto const parent_top_left = parent->top_left();
2956+ auto const centred = parent_top_left
2957+ + 0.5*(as_displacement(parent->size()) - as_displacement(parameters.size))
2958+ - DeltaY{(parent->size().height.as_int()-height)/6};
2959+
2960+ parameters.top_left = centred;
2961+ positioned = true;
2962+ }
2963
2964 if (!positioned)
2965 {
2966- auto centred = active_display.top_left + 0.5*(
2967- as_displacement(active_display.size) - as_displacement(parameters.size));
2968-
2969- parameters.top_left = centred - DeltaY{(active_display.size.height.as_int()-height)/6};
2970+ auto const centred = active_display.top_left
2971+ + 0.5*(as_displacement(active_display.size) - as_displacement(parameters.size))
2972+ - DeltaY{(active_display.size.height.as_int()-height)/6};
2973+
2974+ switch (parameters.state.value())
2975+ {
2976+ case mir_surface_state_fullscreen:
2977+ case mir_surface_state_maximized:
2978+ parameters.top_left = active_display.top_left;
2979+ parameters.size = active_display.size;
2980+ break;
2981+
2982+ case mir_surface_state_vertmaximized:
2983+ parameters.top_left = centred;
2984+ parameters.top_left.y = active_display.top_left.y;
2985+ parameters.size.height = active_display.size.height;
2986+ break;
2987+
2988+ case mir_surface_state_horizmaximized:
2989+ parameters.top_left = centred;
2990+ parameters.top_left.x = active_display.top_left.x;
2991+ parameters.size.width = active_display.size.width;
2992+ break;
2993+
2994+ default:
2995+ parameters.top_left = centred;
2996+ }
2997
2998 if (parameters.top_left.y < display_area.top_left.y)
2999 parameters.top_left.y = display_area.top_left.y;
3000 }
3001
3002- parameters.top_left.y = parameters.top_left.y + DeltaY{title_bar_height};
3003- parameters.size.height = parameters.size.height - DeltaY{title_bar_height};
3004+ if (parameters.state != mir_surface_state_fullscreen && needs_titlebar)
3005+ {
3006+ parameters.top_left.y = parameters.top_left.y + DeltaY{title_bar_height};
3007+ parameters.size.height = parameters.size.height - DeltaY{title_bar_height};
3008+ }
3009+
3010 return parameters;
3011 }
3012
3013+//TODO: provide an easier way for the server to write to a surface!
3014+//TODO: this is painful to use mg::Buffer::write()
3015+struct mir::examples::CanonicalSurfaceInfoCopy::PaintingImpl
3016+{
3017+ PaintingImpl(std::shared_ptr<frontend::BufferStream> const& buffer_stream) :
3018+ buffer_stream{buffer_stream}, buffer{nullptr}
3019+ {
3020+ swap_buffers();
3021+ }
3022+
3023+ void swap_buffers()
3024+ {
3025+ auto const callback = [this](mir::graphics::Buffer* new_buffer)
3026+ {
3027+ buffer.store(new_buffer);
3028+ };
3029+
3030+ buffer_stream->swap_buffers(buffer, callback);
3031+ }
3032+
3033+ std::shared_ptr<frontend::BufferStream> const buffer_stream;
3034+ std::atomic<graphics::Buffer*> buffer;
3035+};
3036+
3037+void mir::examples::CanonicalSurfaceInfoCopy::init_titlebar(std::shared_ptr<scene::Surface> const& surface)
3038+{
3039+ painting_impl = std::make_shared<PaintingImpl>(surface->primary_buffer_stream());
3040+}
3041+
3042+void mir::examples::CanonicalSurfaceInfoCopy::paint_titlebar(int intensity)
3043+{
3044+ if (auto const buf = painting_impl->buffer.load())
3045+ {
3046+ auto const format = painting_impl->buffer_stream->pixel_format();
3047+ auto const sz = buf->size().height.as_int() *
3048+ buf->size().width.as_int() * MIR_BYTES_PER_PIXEL(format);
3049+
3050+ std::vector<unsigned char> pixels(sz, intensity);
3051+ buf->write(pixels.data(), sz);
3052+
3053+ painting_impl->swap_buffers();
3054+ }
3055+}
3056+
3057 void me::CanonicalWindowManagerPolicyCopy::generate_decorations_for(
3058 std::shared_ptr<scene::Session> const& session,
3059 std::shared_ptr<scene::Surface> const& surface,
3060- CanonicalSurfaceInfoMap& surface_info)
3061+ CanonicalSurfaceInfoMap& surface_map)
3062 {
3063+ if (!needs_titlebar(surface->type()))
3064+ return;
3065+
3066 auto format = mir_pixel_format_xrgb_8888;
3067 ms::SurfaceCreationParameters params;
3068 params.of_size(titlebar_size_for_window(surface->size()))
3069@@ -219,116 +424,85 @@
3070 auto id = session->create_surface(params);
3071 auto titlebar = session->surface(id);
3072 titlebar->set_alpha(0.9);
3073- tools->info_for(surface).titlebar = titlebar;
3074- tools->info_for(surface).children.push_back(titlebar);
3075-
3076- //TODO: provide an easier way for the server to write to a surface!
3077- std::mutex mut;
3078- std::condition_variable cv;
3079- mir::graphics::Buffer* written_buffer{nullptr};
3080-
3081- titlebar->swap_buffers(
3082- nullptr,
3083- [&](mir::graphics::Buffer* buffer)
3084- {
3085- //TODO: this is painful to use mg::Buffer::write()
3086- auto const sz = buffer->size().height.as_int() *
3087- buffer->size().width.as_int() * MIR_BYTES_PER_PIXEL(format);
3088- std::vector<unsigned char> pixels(sz, 0xFF);
3089- buffer->write(pixels.data(), sz);
3090- std::unique_lock<decltype(mut)> lk(mut);
3091- written_buffer = buffer;
3092- cv.notify_all();
3093- });
3094- {
3095- std::unique_lock<decltype(mut)> lk(mut);
3096- cv.wait(lk, [&]{return written_buffer;});
3097- }
3098-
3099- titlebar->swap_buffers(written_buffer, [](mir::graphics::Buffer*){});
3100-
3101- CanonicalSurfaceInfoCopy info{session, titlebar, ms::SurfaceCreationParameters{}};
3102- info.is_titlebar = true;
3103- info.parent = surface;
3104-
3105- surface_info.emplace(titlebar, std::move(info));
3106-}
3107-
3108-namespace
3109-{
3110-class SurfaceReadyObserver : public ms::NullSurfaceObserver,
3111- public std::enable_shared_from_this<SurfaceReadyObserver>
3112-{
3113-public:
3114- SurfaceReadyObserver(
3115- me::CanonicalWindowManagerPolicyCopy::Tools* const focus_controller,
3116- std::shared_ptr<ms::Session> const& session,
3117- std::shared_ptr<ms::Surface> const& surface) :
3118- focus_controller{focus_controller},
3119- session{session},
3120- surface{surface}
3121- {
3122- }
3123-
3124-private:
3125- void frame_posted(int) override
3126- {
3127- if (auto const s = surface.lock())
3128- {
3129- focus_controller->set_focus_to(session.lock(), s);
3130- s->remove_observer(shared_from_this());
3131- }
3132- }
3133-
3134- me::CanonicalWindowManagerPolicyCopy::Tools* const focus_controller;
3135- std::weak_ptr<ms::Session> const session;
3136- std::weak_ptr<ms::Surface> const surface;
3137-};
3138+
3139+ auto& surface_info = tools->info_for(surface);
3140+ surface_info.titlebar = titlebar;
3141+ surface_info.titlebar_id = id;
3142+ surface_info.children.push_back(titlebar);
3143+
3144+ CanonicalSurfaceInfoCopy& titlebar_info =
3145+ surface_map.emplace(titlebar, CanonicalSurfaceInfoCopy{session, titlebar, {}}).first->second;
3146+ titlebar_info.is_titlebar = true;
3147+ titlebar_info.parent = surface;
3148+ titlebar_info.init_titlebar(titlebar);
3149 }
3150
3151 void me::CanonicalWindowManagerPolicyCopy::handle_new_surface(std::shared_ptr<ms::Session> const& session, std::shared_ptr<ms::Surface> const& surface)
3152 {
3153- if (auto const parent = surface->parent())
3154+ auto& surface_info = tools->info_for(surface);
3155+ if (auto const parent = surface_info.parent.lock())
3156 {
3157 tools->info_for(parent).children.push_back(surface);
3158 }
3159
3160 tools->info_for(session).surfaces++;
3161
3162- switch (surface->type())
3163+ if (surface_info.can_be_active())
3164 {
3165- case mir_surface_type_normal: /**< AKA "regular" */
3166- case mir_surface_type_utility: /**< AKA "floating" */
3167- case mir_surface_type_dialog:
3168- case mir_surface_type_satellite: /**< AKA "toolbox"/"toolbar" */
3169- case mir_surface_type_freestyle:
3170- case mir_surface_type_menu:
3171- case mir_surface_type_inputmethod: /**< AKA "OSK" or handwriting etc. */
3172- // TODO There's currently no way to insert surfaces into an active (or inactive)
3173- // TODO window tree while keeping the order stable or consistent with spec.
3174- // TODO Nor is there a way to update the "default surface" when appropriate!!
3175- surface->add_observer(std::make_shared<SurfaceReadyObserver>(tools, session, surface));
3176- active_surface_ = surface;
3177- break;
3178-
3179- case mir_surface_type_gloss:
3180- case mir_surface_type_tip: /**< AKA "tooltip" */
3181- default:
3182- // Cannot have input focus
3183- break;
3184+ surface->add_observer(std::make_shared<shell::SurfaceReadyObserver>(
3185+ [this](std::shared_ptr<scene::Session> const& /*session*/,
3186+ std::shared_ptr<scene::Surface> const& surface)
3187+ {
3188+ select_active_surface(surface);
3189+ },
3190+ session,
3191+ surface));
3192 }
3193 }
3194
3195 void me::CanonicalWindowManagerPolicyCopy::handle_modify_surface(
3196- std::shared_ptr<scene::Session> const& /*session*/,
3197+ std::shared_ptr<scene::Session> const& session,
3198 std::shared_ptr<scene::Surface> const& surface,
3199 shell::SurfaceSpecification const& modifications)
3200 {
3201- auto& surface_info = tools->info_for(surface);
3202+ auto& surface_info_old = tools->info_for(surface);
3203+
3204+ auto surface_info = surface_info_old;
3205+
3206+ if (modifications.parent.is_set())
3207+ surface_info.parent = modifications.parent.value();
3208+
3209+ if (modifications.type.is_set() &&
3210+ surface_info.type != modifications.type.value())
3211+ {
3212+ auto const new_type = modifications.type.value();
3213+
3214+ if (!surface_info.can_morph_to(new_type))
3215+ {
3216+ throw std::runtime_error("Unsupported surface type change");
3217+ }
3218+
3219+ surface_info.type = new_type;
3220+
3221+ if (surface_info.must_not_have_parent())
3222+ {
3223+ if (modifications.parent.is_set())
3224+ throw std::runtime_error("Target surface type does not support parent");
3225+
3226+ surface_info.parent.reset();
3227+ }
3228+ else if (surface_info.must_have_parent())
3229+ {
3230+ if (!surface_info.parent.lock())
3231+ throw std::runtime_error("Target surface type requires parent");
3232+ }
3233+
3234+ surface->configure(mir_surface_attrib_type, new_type);
3235+ }
3236
3237 #define COPY_IF_SET(field)\
3238 if (modifications.field.is_set())\
3239- surface_info.field = modifications.field
3240+ surface_info.field = modifications.field.value()
3241
3242 COPY_IF_SET(min_width);
3243 COPY_IF_SET(min_height);
3244@@ -342,9 +516,18 @@
3245
3246 #undef COPY_IF_SET
3247
3248+ std::swap(surface_info, surface_info_old);
3249+
3250 if (modifications.name.is_set())
3251 surface->rename(modifications.name.value());
3252
3253+ if (modifications.streams.is_set())
3254+ {
3255+ auto v = modifications.streams.value();
3256+ std::vector<shell::StreamSpecification> l (v.begin(), v.end());
3257+ session->configure_streams(*surface, l);
3258+ }
3259+
3260 if (modifications.width.is_set() || modifications.height.is_set())
3261 {
3262 auto new_size = surface->size();
3263@@ -355,19 +538,25 @@
3264 if (modifications.height.is_set())
3265 new_size.height = modifications.height.value();
3266
3267- constrained_resize(
3268+ auto top_left = surface->top_left();
3269+
3270+ surface_info.constrain_resize(
3271 surface,
3272- surface->top_left(),
3273+ top_left,
3274 new_size,
3275 false,
3276 false,
3277 display_area);
3278+
3279+ apply_resize(surface, surface_info.titlebar, top_left, new_size);
3280 }
3281 }
3282
3283 void me::CanonicalWindowManagerPolicyCopy::handle_delete_surface(std::shared_ptr<ms::Session> const& session, std::weak_ptr<ms::Surface> const& surface)
3284 {
3285- if (auto const parent = tools->info_for(surface).parent.lock())
3286+ auto& info = tools->info_for(surface);
3287+
3288+ if (auto const parent = info.parent.lock())
3289 {
3290 auto& siblings = tools->info_for(parent).children;
3291
3292@@ -381,8 +570,15 @@
3293 }
3294 }
3295
3296+ if (info.titlebar)
3297+ {
3298+ tools->forget(info.titlebar);
3299+ session->destroy_surface(info.titlebar_id);
3300+ }
3301+
3302 if (!--tools->info_for(session).surfaces && session == tools->focused_session())
3303 {
3304+ active_surface_.reset();
3305 tools->focus_next_session();
3306 select_active_surface(tools->focused_surface());
3307 }
3308@@ -399,6 +595,8 @@
3309 case mir_surface_state_vertmaximized:
3310 case mir_surface_state_horizmaximized:
3311 case mir_surface_state_fullscreen:
3312+ case mir_surface_state_hidden:
3313+ case mir_surface_state_minimized:
3314 break;
3315
3316 default:
3317@@ -423,27 +621,35 @@
3318 case mir_surface_state_restored:
3319 movement = info.restore_rect.top_left - old_pos;
3320 surface->resize(info.restore_rect.size);
3321- info.titlebar->resize(titlebar_size_for_window(info.restore_rect.size));
3322- info.titlebar->show();
3323+ if (info.titlebar)
3324+ {
3325+ info.titlebar->resize(titlebar_size_for_window(info.restore_rect.size));
3326+ info.titlebar->show();
3327+ }
3328 break;
3329
3330 case mir_surface_state_maximized:
3331 movement = display_area.top_left - old_pos;
3332 surface->resize(display_area.size);
3333- info.titlebar->hide();
3334+ if (info.titlebar)
3335+ info.titlebar->hide();
3336 break;
3337
3338 case mir_surface_state_horizmaximized:
3339 movement = Point{display_area.top_left.x, info.restore_rect.top_left.y} - old_pos;
3340 surface->resize({display_area.size.width, info.restore_rect.size.height});
3341- info.titlebar->resize(titlebar_size_for_window({display_area.size.width, info.restore_rect.size.height}));
3342- info.titlebar->show();
3343+ if (info.titlebar)
3344+ {
3345+ info.titlebar->resize(titlebar_size_for_window({display_area.size.width, info.restore_rect.size.height}));
3346+ info.titlebar->show();
3347+ }
3348 break;
3349
3350 case mir_surface_state_vertmaximized:
3351 movement = Point{info.restore_rect.top_left.x, display_area.top_left.y} - old_pos;
3352 surface->resize({info.restore_rect.size.width, display_area.size.height});
3353- info.titlebar->hide();
3354+ if (info.titlebar)
3355+ info.titlebar->hide();
3356 break;
3357
3358 case mir_surface_state_fullscreen:
3359@@ -452,8 +658,16 @@
3360 display_layout->size_to_output(rect);
3361 movement = rect.top_left - old_pos;
3362 surface->resize(rect.size);
3363+ break;
3364 }
3365
3366+ case mir_surface_state_hidden:
3367+ case mir_surface_state_minimized:
3368+ if (info.titlebar)
3369+ info.titlebar->hide();
3370+ surface->hide();
3371+ return info.state = value;
3372+
3373 default:
3374 break;
3375 }
3376@@ -652,35 +866,50 @@
3377
3378 void me::CanonicalWindowManagerPolicyCopy::select_active_surface(std::shared_ptr<ms::Surface> const& surface)
3379 {
3380+ if (surface == active_surface_.lock())
3381+ return;
3382+
3383 if (!surface)
3384 {
3385+ if (auto const active_surface = active_surface_.lock())
3386+ {
3387+ if (auto const titlebar = tools->info_for(active_surface).titlebar)
3388+ {
3389+ tools->info_for(titlebar).paint_titlebar(0x3F);
3390+ }
3391+ }
3392+
3393+ if (active_surface_.lock())
3394+ tools->set_focus_to({}, {});
3395+
3396 active_surface_.reset();
3397 return;
3398 }
3399
3400 auto const& info_for = tools->info_for(surface);
3401
3402- switch (surface->type())
3403+ if (info_for.can_be_active())
3404 {
3405- case mir_surface_type_normal: /**< AKA "regular" */
3406- case mir_surface_type_utility: /**< AKA "floating" */
3407- case mir_surface_type_dialog:
3408- case mir_surface_type_satellite: /**< AKA "toolbox"/"toolbar" */
3409- case mir_surface_type_freestyle:
3410- case mir_surface_type_menu:
3411- case mir_surface_type_inputmethod: /**< AKA "OSK" or handwriting etc. */
3412+ if (auto const active_surface = active_surface_.lock())
3413+ {
3414+ if (auto const titlebar = tools->info_for(active_surface).titlebar)
3415+ {
3416+ tools->info_for(titlebar).paint_titlebar(0x3F);
3417+ }
3418+ }
3419+ if (auto const titlebar = tools->info_for(surface).titlebar)
3420+ {
3421+ tools->info_for(titlebar).paint_titlebar(0xFF);
3422+ }
3423 tools->set_focus_to(info_for.session.lock(), surface);
3424 raise_tree(surface);
3425 active_surface_ = surface;
3426- break;
3427-
3428- case mir_surface_type_gloss:
3429- case mir_surface_type_tip: /**< AKA "tooltip" */
3430- default:
3431+ }
3432+ else
3433+ {
3434 // Cannot have input focus - try the parent
3435 if (auto const parent = info_for.parent.lock())
3436 select_active_surface(parent);
3437- break;
3438 }
3439 }
3440
3441@@ -701,7 +930,7 @@
3442
3443 bool me::CanonicalWindowManagerPolicyCopy::resize(std::shared_ptr<ms::Surface> const& surface, Point cursor, Point old_cursor, Rectangle bounds)
3444 {
3445- if (!surface || !surface->input_area_contains(cursor))
3446+ if (!surface || !surface->input_area_contains(old_cursor))
3447 return false;
3448
3449 auto const top_left = surface->top_left();
3450@@ -732,32 +961,30 @@
3451
3452 Point new_pos = top_left + left_resize*delta.dx + top_resize*delta.dy;
3453
3454- return constrained_resize(surface, new_pos, new_size, left_resize, top_resize, bounds);
3455+
3456+ auto const& surface_info = tools->info_for(surface);
3457+
3458+ surface_info.constrain_resize(surface, new_pos, new_size, left_resize, top_resize, bounds);
3459+
3460+ apply_resize(surface, surface_info.titlebar, new_pos, new_size);
3461+
3462+ return true;
3463 }
3464
3465-bool me::CanonicalWindowManagerPolicyCopy::constrained_resize(
3466+void me::CanonicalSurfaceInfoCopy::constrain_resize(
3467 std::shared_ptr<ms::Surface> const& surface,
3468- Point const& requested_pos,
3469- Size const& requested_size,
3470+ Point& requested_pos,
3471+ Size& requested_size,
3472 bool const left_resize,
3473 bool const top_resize,
3474- Rectangle const& /*bounds*/)
3475+ Rectangle const& /*bounds*/) const
3476 {
3477- auto const& surface_info = tools->info_for(surface);
3478-
3479- auto const min_width = surface_info.min_width.is_set() ? surface_info.min_width.value() : Width{};
3480- auto const min_height = surface_info.min_height.is_set() ? surface_info.min_height.value() : Height{};
3481- auto const max_width = surface_info.max_width.is_set() ?
3482- surface_info.max_width.value() : Width{std::numeric_limits<int>::max()};
3483- auto const max_height = surface_info.max_height.is_set() ?
3484- surface_info.max_height.value() : Height{std::numeric_limits<int>::max()};
3485-
3486 Point new_pos = requested_pos;
3487 Size new_size = requested_size;
3488
3489- if (surface_info.min_aspect.is_set())
3490+ if (min_aspect.is_set())
3491 {
3492- auto const ar = surface_info.min_aspect.value();
3493+ auto const ar = min_aspect.value();
3494
3495 auto const error = new_size.height.as_int()*long(ar.width) - new_size.width.as_int()*long(ar.height);
3496
3497@@ -778,9 +1005,9 @@
3498 }
3499 }
3500
3501- if (surface_info.max_aspect.is_set())
3502+ if (max_aspect.is_set())
3503 {
3504- auto const ar = surface_info.max_aspect.value();
3505+ auto const ar = max_aspect.value();
3506
3507 auto const error = new_size.width.as_int()*long(ar.height) - new_size.height.as_int()*long(ar.width);
3508
3509@@ -813,18 +1040,18 @@
3510 if (max_height < new_size.height)
3511 new_size.height = max_height;
3512
3513- if (surface_info.width_inc.is_set())
3514+ if (width_inc.is_set())
3515 {
3516 auto const width = new_size.width.as_int() - min_width.as_int();
3517- auto inc = surface_info.width_inc.value().as_int();
3518+ auto inc = width_inc.value().as_int();
3519 if (width % inc)
3520 new_size.width = min_width + DeltaX{inc*(((2L*width + inc)/2)/inc)};
3521 }
3522
3523- if (surface_info.height_inc.is_set())
3524+ if (height_inc.is_set())
3525 {
3526 auto const height = new_size.height.as_int() - min_height.as_int();
3527- auto inc = surface_info.height_inc.value().as_int();
3528+ auto inc = height_inc.value().as_int();
3529 if (height % inc)
3530 new_size.height = min_height + DeltaY{inc*(((2L*height + inc)/2)/inc)};
3531 }
3532@@ -837,7 +1064,7 @@
3533
3534 // placeholder - constrain onscreen
3535
3536- switch (surface_info.state)
3537+ switch (state)
3538 {
3539 case mir_surface_state_restored:
3540 break;
3541@@ -861,18 +1088,29 @@
3542 // the left-edge of the surface is anchored to the right-edge of the launcher."
3543 case mir_surface_state_maximized:
3544 default:
3545- return true;
3546+ new_pos.x = surface->top_left().x;
3547+ new_pos.y = surface->top_left().y;
3548+ new_size.width = surface->size().width;
3549+ new_size.height = surface->size().height;
3550+ break;
3551 }
3552
3553- surface_info.titlebar->resize({new_size.width, Height{title_bar_height}});
3554+ requested_pos = new_pos;
3555+ requested_size = new_size;
3556+}
3557+
3558+void me::CanonicalWindowManagerPolicyCopy::apply_resize(
3559+ std::shared_ptr<ms::Surface> const& surface,
3560+ std::shared_ptr<ms::Surface> const& titlebar,
3561+ Point const& new_pos,
3562+ Size const& new_size) const
3563+{
3564+ if (titlebar)
3565+ titlebar->resize({new_size.width, Height{title_bar_height}});
3566+
3567 surface->resize(new_size);
3568
3569- // TODO It is rather simplistic to move a tree WRT the top_left of the root
3570- // TODO when resizing. But for more sophistication we would need to encode
3571- // TODO some sensible layout rules.
3572 move_tree(surface, new_pos-surface->top_left());
3573-
3574- return true;
3575 }
3576
3577 bool me::CanonicalWindowManagerPolicyCopy::drag(std::shared_ptr<ms::Surface> surface, Point to, Point from, Rectangle /*bounds*/)
3578@@ -887,6 +1125,32 @@
3579
3580 // placeholder - constrain onscreen
3581
3582+ switch (tools->info_for(surface).state)
3583+ {
3584+ case mir_surface_state_restored:
3585+ break;
3586+
3587+ // "A vertically maximised surface is anchored to the top and bottom of
3588+ // the available workspace and can have any width."
3589+ case mir_surface_state_vertmaximized:
3590+ movement.dy = DeltaY(0);
3591+ break;
3592+
3593+ // "A horizontally maximised surface is anchored to the left and right of
3594+ // the available workspace and can have any height"
3595+ case mir_surface_state_horizmaximized:
3596+ movement.dx = DeltaX(0);
3597+ break;
3598+
3599+ // "A maximised surface is anchored to the top, bottom, left and right of the
3600+ // available workspace. For example, if the launcher is always-visible then
3601+ // the left-edge of the surface is anchored to the right-edge of the launcher."
3602+ case mir_surface_state_maximized:
3603+ case mir_surface_state_fullscreen:
3604+ default:
3605+ return true;
3606+ }
3607+
3608 move_tree(surface, movement);
3609
3610 return true;
3611
3612=== modified file 'examples/server_example_canonical_window_manager.h'
3613--- examples/server_example_canonical_window_manager.h 2015-04-27 11:53:37 +0000
3614+++ examples/server_example_canonical_window_manager.h 2015-07-23 14:41:37 +0000
3615@@ -23,6 +23,8 @@
3616
3617 #include "mir/geometry/displacement.h"
3618
3619+#include <atomic>
3620+
3621 ///\example server_example_canonical_window_manager.h
3622 // Based on "Mir and Unity: Surfaces, input, and displays (v0.3)"
3623
3624@@ -43,21 +45,46 @@
3625 std::shared_ptr<scene::Surface> const& surface,
3626 scene::SurfaceCreationParameters const& params);
3627
3628+ bool can_be_active() const;
3629+
3630+ bool can_morph_to(MirSurfaceType new_type) const;
3631+ bool must_have_parent() const;
3632+ bool must_not_have_parent() const;
3633+
3634+ void constrain_resize(
3635+ std::shared_ptr<scene::Surface> const& surface,
3636+ geometry::Point& requested_pos,
3637+ geometry::Size& requested_size,
3638+ const bool left_resize,
3639+ const bool top_resize,
3640+ geometry::Rectangle const& bounds) const;
3641+
3642+ MirSurfaceType type;
3643 MirSurfaceState state;
3644 geometry::Rectangle restore_rect;
3645 std::weak_ptr<scene::Session> session;
3646 std::weak_ptr<scene::Surface> parent;
3647 std::vector<std::weak_ptr<scene::Surface>> children;
3648 std::shared_ptr<scene::Surface> titlebar;
3649+ frontend::SurfaceId titlebar_id;
3650 bool is_titlebar = false;
3651- optional_value<geometry::Width> min_width;
3652- optional_value<geometry::Height> min_height;
3653- optional_value<geometry::Width> max_width;
3654- optional_value<geometry::Height> max_height;
3655+ geometry::Width min_width;
3656+ geometry::Height min_height;
3657+ geometry::Width max_width;
3658+ geometry::Height max_height;
3659 mir::optional_value<geometry::DeltaX> width_inc;
3660 mir::optional_value<geometry::DeltaY> height_inc;
3661 mir::optional_value<shell::SurfaceAspectRatio> min_aspect;
3662 mir::optional_value<shell::SurfaceAspectRatio> max_aspect;
3663+
3664+ void init_titlebar(std::shared_ptr<scene::Surface> const& surface);
3665+ void paint_titlebar(int intensity);
3666+
3667+private:
3668+
3669+ struct PaintingImpl;
3670+
3671+ std::shared_ptr<PaintingImpl> painting_impl;
3672 };
3673
3674 // standard window management algorithm:
3675@@ -113,7 +140,7 @@
3676
3677 void generate_decorations_for(
3678 std::shared_ptr<scene::Session> const& session, std::shared_ptr<scene::Surface> const& surface,
3679- CanonicalSurfaceInfoMap& surface_info);
3680+ CanonicalSurfaceInfoMap& surface_map);
3681
3682 private:
3683 static const int modifier_mask =
3684@@ -134,13 +161,11 @@
3685 bool drag(std::shared_ptr<scene::Surface> surface, geometry::Point to, geometry::Point from, geometry::Rectangle bounds);
3686 void move_tree(std::shared_ptr<scene::Surface> const& root, geometry::Displacement movement) const;
3687 void raise_tree(std::shared_ptr<scene::Surface> const& root) const;
3688- bool constrained_resize(
3689- std::shared_ptr<scene::Surface> const& surface,
3690- geometry::Point const& requested_pos,
3691- geometry::Size const& requested_size,
3692- const bool left_resize,
3693- const bool top_resize,
3694- geometry::Rectangle const& bounds);
3695+ void apply_resize(
3696+ std::shared_ptr<mir::scene::Surface> const& surface,
3697+ std::shared_ptr<mir::scene::Surface> const& titlebar,
3698+ geometry::Point const& new_pos,
3699+ geometry::Size const& new_size) const;
3700
3701 Tools* const tools;
3702 std::shared_ptr<shell::DisplayLayout> const display_layout;
3703
3704=== modified file 'examples/server_example_tiling_window_manager.cpp'
3705--- examples/server_example_tiling_window_manager.cpp 2015-04-23 07:11:04 +0000
3706+++ examples/server_example_tiling_window_manager.cpp 2015-07-23 14:41:37 +0000
3707@@ -292,6 +292,32 @@
3708 }
3709 }
3710 }
3711+ else if (action == mir_keyboard_action_down &&
3712+ modifiers == mir_input_event_modifier_alt &&
3713+ scan_code == KEY_TAB)
3714+ {
3715+ tools->focus_next_session();
3716+ if (auto const surface = tools->focused_surface())
3717+ tools->raise({surface});
3718+
3719+ return true;
3720+ }
3721+ else if (action == mir_keyboard_action_down &&
3722+ modifiers == mir_input_event_modifier_alt &&
3723+ scan_code == KEY_GRAVE)
3724+ {
3725+ if (auto const prev = tools->focused_surface())
3726+ {
3727+ if (auto const app = tools->focused_session())
3728+ if (auto const surface = app->surface_after(prev))
3729+ {
3730+ tools->set_focus_to(app, surface);
3731+ tools->raise({surface});
3732+ }
3733+ }
3734+
3735+ return true;
3736+ }
3737
3738 return false;
3739 }
3740
3741=== modified file 'examples/server_example_window_management.cpp'
3742--- examples/server_example_window_management.cpp 2015-04-17 14:31:42 +0000
3743+++ examples/server_example_window_management.cpp 2015-07-23 14:41:37 +0000
3744@@ -27,6 +27,7 @@
3745 #include "mir/input/composite_event_filter.h"
3746 #include "mir/options/option.h"
3747 #include "mir/shell/display_layout.h"
3748+#include "mir/shell/system_compositor_window_manager.h"
3749
3750 namespace me = mir::examples;
3751 namespace mf = mir::frontend;
3752@@ -42,11 +43,12 @@
3753 namespace
3754 {
3755 char const* const wm_option = "window-manager";
3756-char const* const wm_description = "window management strategy [{tiling|fullscreen|canonical}]";
3757+char const* const wm_description = "window management strategy [{tiling|fullscreen|canonical|system-compositor}]";
3758
3759 char const* const wm_tiling = "tiling";
3760 char const* const wm_fullscreen = "fullscreen";
3761 char const* const wm_canonical = "canonical";
3762+char const* const wm_system_compositor = "system-compositor";
3763
3764 struct NullSessionInfo
3765 {
3766@@ -149,6 +151,13 @@
3767 {
3768 return std::make_shared<CanonicalWindowManager>(focus_controller, server.the_shell_display_layout());
3769 }
3770+ else if (selection == wm_system_compositor)
3771+ {
3772+ return std::make_shared<msh::SystemCompositorWindowManager>(
3773+ focus_controller,
3774+ server.the_shell_display_layout(),
3775+ server.the_session_coordinator());
3776+ }
3777
3778 throw mir::AbnormalExit("Unknown window manager: " + selection);
3779 });
3780
3781=== modified file 'examples/target.c'
3782--- examples/target.c 2015-04-02 06:20:31 +0000
3783+++ examples/target.c 2015-07-23 14:41:37 +0000
3784@@ -29,7 +29,8 @@
3785
3786 enum
3787 {
3788- max_touches = 10
3789+ max_fingers = 10,
3790+ max_samples_per_frame = 1000
3791 };
3792
3793 typedef struct
3794@@ -39,8 +40,14 @@
3795
3796 typedef struct
3797 {
3798- int points;
3799- Vec2 point[max_touches];
3800+ int samples;
3801+ Vec2 sample[max_samples_per_frame];
3802+} Finger;
3803+
3804+typedef struct
3805+{
3806+ int fingers;
3807+ Finger finger[max_fingers];
3808 } TouchState;
3809
3810 typedef struct
3811@@ -124,13 +131,18 @@
3812 {
3813 if (mir_input_event_get_type(ievent) == mir_input_event_type_pointer)
3814 {
3815- touch->points = 0;
3816 const MirPointerEvent *pevent =
3817 mir_input_event_get_pointer_event(ievent);
3818- if (mir_pointer_event_action(pevent) != mir_pointer_action_leave)
3819- {
3820- touch->points = 1;
3821- touch->point[0] = (Vec2)
3822+ if (mir_pointer_event_action(pevent) == mir_pointer_action_leave)
3823+ {
3824+ touch->fingers = 0;
3825+ }
3826+ else if (touch->finger[0].samples < max_samples_per_frame)
3827+ {
3828+ if (!touch->fingers)
3829+ touch->finger[0].samples = 0;
3830+ touch->fingers = 1;
3831+ touch->finger[0].sample[touch->finger[0].samples++] = (Vec2)
3832 {
3833 mir_pointer_event_axis_value(pevent, mir_pointer_axis_x),
3834 mir_pointer_event_axis_value(pevent, mir_pointer_axis_y)
3835@@ -141,20 +153,29 @@
3836 {
3837 const MirTouchEvent *tevent = mir_input_event_get_touch_event(ievent);
3838 int n = mir_touch_event_point_count(tevent);
3839- if (n > max_touches)
3840- n = max_touches;
3841- bool all_up = true;
3842- for (int p = 0; p < n; ++p)
3843+ if (n > max_fingers)
3844+ n = max_fingers;
3845+ for (int f = 0; f < n; ++f)
3846 {
3847- if (mir_touch_event_action(tevent, p) != mir_touch_action_up)
3848- all_up = false;
3849- touch->point[p] = (Vec2)
3850- {
3851- mir_touch_event_axis_value(tevent, p, mir_touch_axis_x),
3852- mir_touch_event_axis_value(tevent, p, mir_touch_axis_y)
3853+ Finger *finger = touch->finger + f;
3854+ if (f >= touch->fingers)
3855+ {
3856+ finger->samples = 0;
3857+ touch->fingers = f + 1;
3858+ }
3859+ if (mir_touch_event_action(tevent, f) == mir_touch_action_up)
3860+ {
3861+ finger->samples = 0;
3862+ continue;
3863+ }
3864+ if (finger->samples >= max_samples_per_frame)
3865+ continue;
3866+ finger->sample[finger->samples++] = (Vec2)
3867+ {
3868+ mir_touch_event_axis_value(tevent, f, mir_touch_axis_x),
3869+ mir_touch_event_axis_value(tevent, f, mir_touch_axis_y)
3870 };
3871 }
3872- touch->points = all_up ? 0 : n;
3873 }
3874 }
3875
3876@@ -211,10 +232,13 @@
3877 "precision mediump float;\n"
3878 "varying vec2 v_texcoord;\n"
3879 "uniform sampler2D texture;\n"
3880+ "uniform float opacity;\n"
3881 "\n"
3882 "void main()\n"
3883 "{\n"
3884- " gl_FragColor = texture2D(texture, v_texcoord);\n"
3885+ " vec4 f = texture2D(texture, v_texcoord);\n"
3886+ " f.a *= opacity;\n"
3887+ " gl_FragColor = f;\n"
3888 "}\n";
3889
3890 // Disable Mir's input resampling. We do our own here, in a way that
3891@@ -268,6 +292,9 @@
3892 GLint scale = glGetUniformLocation(prog, "scale");
3893 glUniform1f(scale, 128.0f);
3894
3895+ GLint opacity = glGetUniformLocation(prog, "opacity");
3896+ glUniform1f(opacity, 1.0f);
3897+
3898 GLint translate = glGetUniformLocation(prog, "translate");
3899 glUniform2f(translate, 0.0f, 0.0f);
3900
3901@@ -280,7 +307,7 @@
3902 glViewport(0, 0, width, height);
3903
3904 glEnable(GL_BLEND);
3905- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3906+ glBlendFunc(GL_SRC_ALPHA, GL_ONE); // Behave like an accumulation buffer
3907
3908 State state =
3909 {
3910@@ -288,7 +315,7 @@
3911 PTHREAD_COND_INITIALIZER,
3912 true,
3913 true,
3914- {0, {{0,0}}}
3915+ {0, {{0, {{0.0f, 0.0f}}}}}
3916 };
3917 MirSurface *surface = mir_eglapp_native_surface();
3918 mir_surface_set_event_handler(surface, on_event, &state);
3919@@ -320,12 +347,31 @@
3920
3921 glClear(GL_COLOR_BUFFER_BIT);
3922
3923- for (int p = 0; p < state.touch.points; ++p)
3924- {
3925- // Note the 0.5f to convert from pixel middle to corner (GL)
3926- glUniform2f(translate, state.touch.point[p].x + 0.5f,
3927- state.touch.point[p].y + 0.5f);
3928- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
3929+ for (int f = 0; f < state.touch.fingers; ++f)
3930+ {
3931+ const Finger *finger = state.touch.finger + f;
3932+
3933+ if (!finger->samples)
3934+ continue;
3935+
3936+ glUniform1f(opacity, 1.0f / finger->samples);
3937+
3938+ for (int s = 0; s < finger->samples; ++s)
3939+ {
3940+ // Note the 0.5f to convert from pixel middle to corner (GL)
3941+ glUniform2f(translate, finger->sample[s].x + 0.5f,
3942+ finger->sample[s].y + 0.5f);
3943+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
3944+ }
3945+ }
3946+
3947+ // Just keep the latest sample for the zeroth finger (mouse pointer)
3948+ if (state.touch.fingers)
3949+ {
3950+ state.touch.finger[0].sample[0] =
3951+ state.touch.finger[0].sample[state.touch.finger[0].samples-1];
3952+ state.touch.finger[0].samples = 1;
3953+ state.touch.fingers = 1;
3954 }
3955
3956 // Put the event loop back to sleep:
3957
3958=== modified file 'guides/cppguide.xml'
3959--- guides/cppguide.xml 2014-03-06 06:05:17 +0000
3960+++ guides/cppguide.xml 2015-07-23 14:41:37 +0000
3961@@ -3589,7 +3589,7 @@
3962 </SUMMARY>
3963 <BODY>
3964 <p>
3965- There are two acceptable formats for initializer lists:
3966+ There are three acceptable formats for initializer lists:
3967 </p>
3968 <CODE_SNIPPET>
3969 // When it all fits on one line:
3970@@ -3610,6 +3610,21 @@
3971 ...
3972 }
3973 </CODE_SNIPPET>
3974+ <p>
3975+ or
3976+ </p>
3977+ <CODE_SNIPPET>
3978+ // When it requires multiple lines, indent 4 spaces, putting the colon on
3979+ // the first initializer line and commas at the end of the line.
3980+ MyClass::MyClass(int var)
3981+ : some_var_(var), // 4 space indent
3982+ some_other_var_(var + 1)
3983+ {
3984+ ...
3985+ do_something();
3986+ ...
3987+ }
3988+ </CODE_SNIPPET>
3989 </BODY>
3990 </STYLEPOINT>
3991
3992
3993=== modified file 'include/client/mir/events/event_builders.h'
3994--- include/client/mir/events/event_builders.h 2015-04-01 19:39:19 +0000
3995+++ include/client/mir/events/event_builders.h 2015-07-23 14:41:37 +0000
3996@@ -25,8 +25,8 @@
3997 #include "mir/frontend/surface_id.h"
3998
3999 #include <memory>
4000-#include <vector>
4001 #include <functional>
4002+#include <chrono>
4003
4004 namespace mir
4005 {
4006@@ -48,23 +48,27 @@
4007 EventUPtr make_event(frontend::SurfaceId const& surface_id, xkb_rule_names const& names);
4008
4009 // Key event
4010-EventUPtr make_event(MirInputDeviceId device_id, int64_t timestamp,
4011+EventUPtr make_event(MirInputDeviceId device_id, std::chrono::nanoseconds timestamp,
4012 MirKeyboardAction action, xkb_keysym_t key_code,
4013 int scan_code, MirInputEventModifiers modifiers);
4014
4015 // Touch event
4016-EventUPtr make_event(MirInputDeviceId device_id, int64_t timestamp,
4017+EventUPtr make_event(MirInputDeviceId device_id, std::chrono::nanoseconds timestamp,
4018 MirInputEventModifiers modifiers);
4019 void add_touch(MirEvent &event, MirTouchId touch_id, MirTouchAction action,
4020 MirTouchTooltype tooltype, float x_axis_value, float y_axis_value,
4021 float pressure_value, float touch_major_value, float touch_minor_value, float size_value);
4022
4023 // Pointer event
4024-EventUPtr make_event(MirInputDeviceId device_id, int64_t timestamp,
4025+EventUPtr make_event(MirInputDeviceId device_id, std::chrono::nanoseconds timestamp,
4026 MirInputEventModifiers modifiers, MirPointerAction action,
4027- std::vector<MirPointerButton> const& buttons_pressed,
4028+ MirPointerButtons buttons_pressed,
4029 float x_axis_value, float y_axis_value,
4030 float hscroll_value, float vscroll_value);
4031+
4032+// Input configuration event
4033+EventUPtr make_event(MirInputConfigurationAction action,
4034+ MirInputDeviceId id, std::chrono::nanoseconds time);
4035 }
4036 }
4037
4038
4039=== modified file 'include/client/mir_toolkit/client_types.h'
4040--- include/client/mir_toolkit/client_types.h 2015-03-31 02:35:42 +0000
4041+++ include/client/mir_toolkit/client_types.h 2015-07-23 14:41:37 +0000
4042@@ -43,6 +43,7 @@
4043 typedef struct MirScreencast MirScreencast;
4044 typedef struct MirPromptSession MirPromptSession;
4045 typedef struct MirBufferStream MirBufferStream;
4046+typedef struct MirPersistentId MirPersistentId;
4047
4048 /**
4049 * Returned by asynchronous functions. Must not be free'd by
4050@@ -75,11 +76,11 @@
4051 /**
4052 * Callback to be passed when calling:
4053 * - mir_buffer_stream_* functions requiring a callback.
4054- * \param [in] surface the buffer stream being updated
4055+ * \param [in] stream the buffer stream being updated
4056 * \param [in,out] client_context context provided by client in calling
4057 * mir_connect
4058 */
4059-typedef void (*mir_buffer_stream_callback)(MirBufferStream *surface, void *client_context);
4060+typedef void (*mir_buffer_stream_callback)(MirBufferStream *stream, void *client_context);
4061
4062 /**
4063 * Callback for handling of surface events.
4064@@ -123,6 +124,10 @@
4065 typedef void (*mir_client_fd_callback)(
4066 MirPromptSession *prompt_session, size_t count, int const* fds, void* context);
4067
4068+
4069+typedef void (*mir_surface_id_callback)(
4070+ MirSurface* surface, MirPersistentId* id, void* context);
4071+
4072 /**
4073 * MirBufferUsage specifies how a surface can and will be used. A "hardware"
4074 * surface can be used for OpenGL accelerated rendering. A "software" surface
4075@@ -278,6 +283,16 @@
4076 MirDisplayCard *cards;
4077 } MirDisplayConfiguration;
4078
4079+/**
4080+ * The displacement from the top-left corner of the surface.
4081+ */
4082+typedef struct MirBufferStreamInfo
4083+{
4084+ MirBufferStream* stream;
4085+ int displacement_x;
4086+ int displacement_y;
4087+} MirBufferStreamInfo;
4088+
4089 typedef struct MirRectangle
4090 {
4091 int left;
4092
4093=== modified file 'include/client/mir_toolkit/events/event.h'
4094--- include/client/mir_toolkit/events/event.h 2015-04-01 19:39:19 +0000
4095+++ include/client/mir_toolkit/events/event.h 2015-07-23 14:41:37 +0000
4096@@ -43,7 +43,8 @@
4097 /* Type for new style input event will be returned from mir_event_get_type
4098 when old style event type was mir_event_type_key or mir_event_type_motion */
4099 mir_event_type_input,
4100- mir_event_type_keymap
4101+ mir_event_type_keymap,
4102+ mir_event_type_input_configuration,
4103 } MirEventType;
4104
4105 typedef struct MirSurfaceEvent MirSurfaceEvent;
4106@@ -53,6 +54,7 @@
4107 typedef struct MirCloseSurfaceEvent MirCloseSurfaceEvent;
4108 typedef struct MirInputEvent MirInputEvent;
4109 typedef struct MirKeymapEvent MirKeymapEvent;
4110+typedef struct MirInputConfigurationEvent MirInputConfigurationEvent;
4111
4112 typedef union MirEvent MirEvent;
4113
4114@@ -67,6 +69,7 @@
4115 #include "mir_toolkit/events/orientation_event.h"
4116 #include "mir_toolkit/events/prompt_session_event.h"
4117 #include "mir_toolkit/events/keymap_event.h"
4118+#include "mir_toolkit/events/input_configuration_event.h"
4119
4120 #ifdef __cplusplus
4121 /**
4122@@ -157,6 +160,16 @@
4123 MirKeymapEvent const* mir_event_get_keymap_event(MirEvent const* ev);
4124
4125 /*
4126+ * Retrieve the MirInputConfiguration associated with a MirEvent of
4127+ * type mir_event_type_input_configuration. The event signifies that the
4128+ * input device configuration has changed.
4129+ *
4130+ * \param [in] event The event
4131+ * \return The associated MirInputConfigurationEvent
4132+ */
4133+MirInputConfigurationEvent const* mir_event_get_input_configuration_event(MirEvent const* ev);
4134+
4135+/*
4136 *
4137 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4138 * _________________________
4139
4140=== modified file 'include/client/mir_toolkit/events/input/pointer_event.h'
4141--- include/client/mir_toolkit/events/input/pointer_event.h 2015-03-31 02:35:42 +0000
4142+++ include/client/mir_toolkit/events/input/pointer_event.h 2015-07-23 14:41:37 +0000
4143@@ -68,12 +68,13 @@
4144 * Identifiers for pointer buttons
4145 */
4146 typedef enum {
4147- mir_pointer_button_primary = 1,
4148- mir_pointer_button_secondary = 2,
4149- mir_pointer_button_tertiary = 3,
4150- mir_pointer_button_back = 4,
4151- mir_pointer_button_forward = 5
4152+ mir_pointer_button_primary = 1 << 0,
4153+ mir_pointer_button_secondary = 1 << 1,
4154+ mir_pointer_button_tertiary = 1 << 2,
4155+ mir_pointer_button_back = 1 << 3,
4156+ mir_pointer_button_forward = 1 << 4
4157 } MirPointerButton;
4158+typedef unsigned int MirPointerButtons;
4159
4160 /**
4161 * Retrieve the modifier keys pressed when the pointer action occured.
4162@@ -103,6 +104,15 @@
4163 MirPointerButton button);
4164
4165 /**
4166+ * Retreive the pointer button state as a masked set of values.
4167+ *
4168+ * \param [in] event The pointer event
4169+ *
4170+ * \return The button state
4171+ */
4172+MirPointerButtons mir_pointer_event_buttons(MirPointerEvent const* event);
4173+
4174+/**
4175 * Retrieve the axis value reported by a given pointer event.
4176 *
4177 * \param [in] event The pointer event
4178
4179=== added file 'include/client/mir_toolkit/events/input_configuration_event.h'
4180--- include/client/mir_toolkit/events/input_configuration_event.h 1970-01-01 00:00:00 +0000
4181+++ include/client/mir_toolkit/events/input_configuration_event.h 2015-07-23 14:41:37 +0000
4182@@ -0,0 +1,78 @@
4183+/*
4184+ * Copyright © 2015 Canonical Ltd.
4185+ *
4186+ * This program is free software: you can redistribute it and/or modify it
4187+ * under the terms of the GNU Lesser General Public License version 3,
4188+ * as published by the Free Software Foundation.
4189+ *
4190+ * This program is distributed in the hope that it will be useful,
4191+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4192+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4193+ * GNU Lesser General Public License for more details.
4194+ *
4195+ * You should have received a copy of the GNU Lesser General Public License
4196+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4197+ *
4198+ * Authored by: Robert Carr <robert.carr@canonical.com>
4199+ */
4200+
4201+#ifndef MIR_TOOLKIT_EVENTS_INPUT_CONFIGURATION_EVENT_H_
4202+#define MIR_TOOLKIT_EVENTS_INPUT_CONFIGURATION_EVENT_H_
4203+
4204+#include <mir_toolkit/events/event.h>
4205+
4206+#ifdef __cplusplus
4207+/**
4208+ * \addtogroup mir_toolkit
4209+ * @{
4210+ */
4211+extern "C" {
4212+#endif
4213+
4214+/// MirInputConfigurationEvent indicates a configuration change in the input device subsystem. Eventually
4215+/// it's usage will be required to properly interpret MirInputEvent, for example:
4216+/// If we receive a button down, and then a device reset, we should not expect
4217+/// to receive the button up.
4218+///
4219+/// Another example, the maximum/minimum axis values for a device may have been reconfigured and
4220+/// need to be required.
4221+///
4222+/// Of course as things stand there is no client input-device introspection API so these events
4223+/// are difficult to use.
4224+
4225+typedef enum
4226+{
4227+ mir_input_configuration_action_configuration_changed,
4228+ mir_input_configuration_action_device_reset
4229+} MirInputConfigurationAction;
4230+
4231+/*
4232+ * Retrieve the input configuration action which occurred.
4233+ *
4234+ * \param[in] ev The input configuration event
4235+ * \return The action
4236+ */
4237+MirInputConfigurationAction mir_input_configuration_event_get_action(MirInputConfigurationEvent const* ev);
4238+
4239+/*
4240+ * Retreive the time associated with a MirInputConfiguration event
4241+
4242+ * \param[in] ev The input configuration event
4243+ * \return The time in nanoseconds since epoch
4244+ */
4245+int64_t mir_input_configuration_event_get_time(MirInputConfigurationEvent const* ev);
4246+
4247+/*
4248+ * Retreive the device id associated with a MirInputConfiguration event
4249+
4250+ * \param[in] ev The input configuration event
4251+ * \return The device id or -1 if not applicable to events of this action
4252+ */
4253+MirInputDeviceId mir_input_configuration_event_get_device_id(MirInputConfigurationEvent const* ev);
4254+
4255+#ifdef __cplusplus
4256+}
4257+/**@}*/
4258+#endif
4259+
4260+#endif /* MIR_TOOLKIT_INPUT_CONFIGURATION_EVENT_H_ */
4261
4262=== removed file 'include/client/mir_toolkit/mir_client_library_drm.h'
4263--- include/client/mir_toolkit/mir_client_library_drm.h 2015-04-30 12:37:50 +0000
4264+++ include/client/mir_toolkit/mir_client_library_drm.h 1970-01-01 00:00:00 +0000
4265@@ -1,59 +0,0 @@
4266-/*
4267- * Copyright © 2012 Canonical Ltd.
4268- *
4269- * This program is free software: you can redistribute it and/or modify it
4270- * under the terms of the GNU Lesser General Public License version 3,
4271- * as published by the Free Software Foundation.
4272- *
4273- * This program is distributed in the hope that it will be useful,
4274- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4275- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4276- * GNU Lesser General Public License for more details.
4277- *
4278- * You should have received a copy of the GNU Lesser General Public License
4279- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4280- */
4281-
4282-#ifndef MIR_CLIENT_LIBRARY_DRM_H_
4283-#define MIR_CLIENT_LIBRARY_DRM_H_
4284-
4285-#include "mir_toolkit/mir_client_library.h"
4286-
4287-#ifdef __cplusplus
4288-/**
4289- * \addtogroup mir_toolkit
4290- * @{
4291- */
4292-extern "C" {
4293-#endif
4294-
4295-struct gbm_device;
4296-
4297-typedef void (*mir_drm_auth_magic_callback)(int status, void *context);
4298-
4299-/* Authenticates a DRM magic cookie */
4300-MirWaitHandle *mir_connection_drm_auth_magic(MirConnection *connection,
4301- unsigned int magic,
4302- mir_drm_auth_magic_callback callback,
4303- void *context)
4304- __attribute__((__deprecated__("Use mir_connection_platform_operation() with operations from mir_toolkit/mesa/platform_operation.h")));
4305-
4306-/**
4307- * Set the gbm_device to be used by the EGL implementation.
4308- * This is required if the application needs to create EGLImages from
4309- * gbm buffers objects created on that gbm device.
4310- * \param [in] connection The connection
4311- * \param [in] dev The gbm_device to set
4312- * \return A non-zero value if the operation was successful,
4313- * 0 otherwise
4314- */
4315-int mir_connection_drm_set_gbm_device(MirConnection* connection,
4316- struct gbm_device* dev)
4317- __attribute__((__deprecated__("Use mir_connection_platform_operation() with operations from mir_toolkit/mesa/platform_operation.h")));
4318-
4319-#ifdef __cplusplus
4320-}
4321-/**@}*/
4322-#endif
4323-
4324-#endif /* MIR_CLIENT_LIBRARY_DRM_H_ */
4325
4326=== modified file 'include/client/mir_toolkit/mir_connection.h'
4327--- include/client/mir_toolkit/mir_connection.h 2015-03-31 02:35:42 +0000
4328+++ include/client/mir_toolkit/mir_connection.h 2015-07-23 14:41:37 +0000
4329@@ -104,12 +104,6 @@
4330 mir_lifecycle_event_callback callback, void* context);
4331
4332 /**
4333- * \deprecated Use mir_connection_create_display_config
4334- */
4335-__attribute__((__deprecated__("Use mir_connection_create_display_config()")))
4336-void mir_connection_get_display_info(MirConnection *connection, MirDisplayInfo *display_info);
4337-
4338-/**
4339 * Query the display
4340 * \warning return value must be destroyed via mir_display_config_destroy()
4341 * \warning may return null if connection is invalid
4342
4343=== modified file 'include/client/mir_toolkit/mir_screencast.h'
4344--- include/client/mir_toolkit/mir_screencast.h 2015-03-31 02:35:42 +0000
4345+++ include/client/mir_toolkit/mir_screencast.h 2015-07-23 14:41:37 +0000
4346@@ -56,13 +56,6 @@
4347 */
4348 MirBufferStream* mir_screencast_get_buffer_stream(MirScreencast *screencast);
4349
4350-/**
4351- * Get a window type that can be used by EGL.
4352- * \param [in] screencast The screencast
4353- * \return An EGLNativeWindowType that the client can use
4354- */
4355-MirEGLNativeWindowType mir_screencast_egl_native_window(MirScreencast *screencast) __attribute__((__deprecated__("Use mir_screencast_get_buffer_stream and the corresponding mir_buffer_stream* function")));
4356-
4357 #ifdef __cplusplus
4358 }
4359 /**@}*/
4360
4361=== modified file 'include/client/mir_toolkit/mir_surface.h'
4362--- include/client/mir_toolkit/mir_surface.h 2015-04-30 12:37:50 +0000
4363+++ include/client/mir_toolkit/mir_surface.h 2015-07-23 14:41:37 +0000
4364@@ -168,6 +168,20 @@
4365 MirPixelFormat format);
4366
4367 /**
4368+ * Create a surface specification.
4369+ * This can be used with mir_surface_create() to create a surface or with
4370+ * mir_surface_apply_spec() to change an existing surface.
4371+ * \remark For use with mir_surface_create() at least the type, width, height,
4372+ * format and buffer_usage must be set. (And for types requiring a parent that
4373+ * too must be set.)
4374+ *
4375+ * \param [in] connection a valid mir connection
4376+ * \return A handle that can ultimately be passed to
4377+ * mir_surface_create() or mir_surface_apply_spec()
4378+ */
4379+MirSurfaceSpec* mir_create_surface_spec(MirConnection* connection);
4380+
4381+/**
4382 * Create a surface specification for updating a surface.
4383 *
4384 * This can be applied to one or more target surfaces using
4385@@ -203,6 +217,33 @@
4386 MirSurface* mir_surface_create_sync(MirSurfaceSpec* requested_specification);
4387
4388 /**
4389+ * Set the requested parent.
4390+ *
4391+ * \param [in] spec Specification to mutate
4392+ * \param [in] parent A valid parent surface.
4393+ */
4394+void mir_surface_spec_set_parent(MirSurfaceSpec* spec, MirSurface* parent);
4395+
4396+/**
4397+ * Update a surface specification with a surface type.
4398+ * This can be used with mir_surface_create() to create a surface or with
4399+ * mir_surface_apply_spec() to change an existing surface.
4400+ * \remark For use with mir_surface_apply_spec() the shell need not support
4401+ * arbitrary changes of type and some target types may require the setting of
4402+ * properties such as "parent" that are not already present on the surface.
4403+ * The type transformations the server is required to support are:\n
4404+ * regular => utility, dialog or satellite\n
4405+ * utility => regular, dialog or satellite\n
4406+ * dialog => regular, utility or satellite\n
4407+ * satellite => regular, utility or dialog\n
4408+ * popup => satellite
4409+ *
4410+ * \param [in] spec Specification to mutate
4411+ * \param [in] type the target type of the surface
4412+ */
4413+void mir_surface_spec_set_type(MirSurfaceSpec* spec, MirSurfaceType type);
4414+
4415+/**
4416 * Set the requested name.
4417 *
4418 * The surface name helps the user to distinguish between multiple surfaces
4419@@ -212,31 +253,30 @@
4420 * \param [in] spec Specification to mutate
4421 * \param [in] name Requested name. This must be valid UTF-8.
4422 * Copied into spec; clients can free the buffer passed after this call.
4423- * \return False if name is not a valid attribute of this surface type.
4424 */
4425-bool mir_surface_spec_set_name(MirSurfaceSpec* spec, char const* name);
4426+void mir_surface_spec_set_name(MirSurfaceSpec* spec, char const* name);
4427
4428 /**
4429 * Set the requested width, in pixels
4430 *
4431 * \param [in] spec Specification to mutate
4432 * \param [in] width Requested width.
4433- * \return False if width is invalid for a surface of this type
4434+ *
4435 * \note The requested dimensions are a hint only. The server is not guaranteed to create a
4436 * surface of any specific width or height.
4437 */
4438-bool mir_surface_spec_set_width(MirSurfaceSpec* spec, unsigned width);
4439+void mir_surface_spec_set_width(MirSurfaceSpec* spec, unsigned width);
4440
4441 /**
4442 * Set the requested height, in pixels
4443 *
4444 * \param [in] spec Specification to mutate
4445 * \param [in] height Requested height.
4446- * \return False if height is invalid for a surface of this type
4447+ *
4448 * \note The requested dimensions are a hint only. The server is not guaranteed to create a
4449 * surface of any specific width or height.
4450 */
4451-bool mir_surface_spec_set_height(MirSurfaceSpec* spec, unsigned height);
4452+void mir_surface_spec_set_height(MirSurfaceSpec* spec, unsigned height);
4453
4454 /**
4455 * Set the requested width increment, in pixels.
4456@@ -245,11 +285,11 @@
4457 *
4458 * \param [in] spec Specification to mutate
4459 * \param [in] width_inc Requested width increment.
4460- * \return False if width increment is invalid for a surface of this type
4461+ *
4462 * \note The requested dimensions are a hint only. The server is not guaranteed to
4463 * create a surface of any specific width or height.
4464 */
4465-bool mir_surface_spec_set_width_increment(MirSurfaceSpec *spec, unsigned width_inc);
4466+void mir_surface_spec_set_width_increment(MirSurfaceSpec* spec, unsigned width_inc);
4467
4468 /**
4469 * Set the requested height increment, in pixels
4470@@ -258,54 +298,54 @@
4471 *
4472 * \param [in] spec Specification to mutate
4473 * \param [in] height_inc Requested height increment.
4474- * \return False if height increment is invalid for a surface of this type
4475+ *
4476 * \note The requested dimensions are a hint only. The server is not guaranteed to
4477 * create a surface of any specific width or height.
4478 */
4479-bool mir_surface_spec_set_height_increment(MirSurfaceSpec *spec, unsigned height_inc);
4480+void mir_surface_spec_set_height_increment(MirSurfaceSpec* spec, unsigned height_inc);
4481
4482 /**
4483 * Set the minimum width, in pixels
4484 *
4485 * \param [in] spec Specification to mutate
4486 * \param [in] width Minimum width.
4487- * \return False if minimum width is invalid for a surface of this type
4488+ *
4489 * \note The requested dimensions are a hint only. The server is not guaranteed to create a
4490 * surface of any specific width or height.
4491 */
4492-bool mir_surface_spec_set_min_width(MirSurfaceSpec* spec, unsigned min_width);
4493+void mir_surface_spec_set_min_width(MirSurfaceSpec* spec, unsigned min_width);
4494
4495 /**
4496 * Set the minimum height, in pixels
4497 *
4498 * \param [in] spec Specification to mutate
4499 * \param [in] height Minimum height.
4500- * \return False if minimum height is invalid for a surface of this type
4501+ *
4502 * \note The requested dimensions are a hint only. The server is not guaranteed to create a
4503 * surface of any specific width or height.
4504 */
4505-bool mir_surface_spec_set_min_height(MirSurfaceSpec* spec, unsigned min_height);
4506+void mir_surface_spec_set_min_height(MirSurfaceSpec* spec, unsigned min_height);
4507 /**
4508 * Set the maximum width, in pixels
4509 *
4510 * \param [in] spec Specification to mutate
4511 * \param [in] width Maximum width.
4512- * \return False if maximum width is invalid for a surface of this type
4513+ *
4514 * \note The requested dimensions are a hint only. The server is not guaranteed to create a
4515 * surface of any specific width or height.
4516 */
4517-bool mir_surface_spec_set_max_width(MirSurfaceSpec* spec, unsigned max_width);
4518+void mir_surface_spec_set_max_width(MirSurfaceSpec* spec, unsigned max_width);
4519
4520 /**
4521 * Set the maximum height, in pixels
4522 *
4523 * \param [in] spec Specification to mutate
4524 * \param [in] height Maximum height.
4525- * \return False if maximum height is invalid for a surface of this type
4526+ *
4527 * \note The requested dimensions are a hint only. The server is not guaranteed to create a
4528 * surface of any specific width or height.
4529 */
4530-bool mir_surface_spec_set_max_height(MirSurfaceSpec* spec, unsigned max_height);
4531+void mir_surface_spec_set_max_height(MirSurfaceSpec* spec, unsigned max_height);
4532
4533 /**
4534 * Set the minimum aspect ratio. This is the minimum ratio of surface width to height.
4535@@ -314,11 +354,11 @@
4536 * \param [in] spec Specification to mutate
4537 * \param [in] width numerator
4538 * \param [in] height denominator
4539- * \return False if minimum aspect is invalid for a surface of this type
4540+ *
4541 * \note The requested aspect ratio is a hint only. The server is not guaranteed
4542 * to create a surface of any specific aspect.
4543 */
4544-bool mir_surface_spec_set_min_aspect_ratio(MirSurfaceSpec* spec, unsigned width, unsigned height);
4545+void mir_surface_spec_set_min_aspect_ratio(MirSurfaceSpec* spec, unsigned width, unsigned height);
4546
4547 /**
4548 * Set the maximum aspect ratio. This is the maximum ratio of surface width to height.
4549@@ -327,53 +367,63 @@
4550 * \param [in] spec Specification to mutate
4551 * \param [in] width numerator
4552 * \param [in] height denominator
4553- * \return False if maximum aspect is invalid for a surface of this type
4554+ *
4555 * \note The requested aspect ratio is a hint only. The server is not guaranteed
4556 * to create a surface of any specific aspect.
4557 */
4558-bool mir_surface_spec_set_max_aspect_ratio(MirSurfaceSpec* spec, unsigned width, unsigned height);
4559+void mir_surface_spec_set_max_aspect_ratio(MirSurfaceSpec* spec, unsigned width, unsigned height);
4560
4561 /**
4562 * Set the requested pixel format.
4563 * \param [in] spec Specification to mutate
4564 * \param [in] format Requested pixel format
4565- * \return False if format is not a valid pixel format for this surface type.
4566+ *
4567 * \note If this call returns %true then the server is guaranteed to honour this request.
4568 * If the server is unable to create a surface with this pixel format at
4569 * the point mir_surface_create() is called it will instead return an invalid surface.
4570 */
4571-bool mir_surface_spec_set_pixel_format(MirSurfaceSpec* spec, MirPixelFormat format);
4572+void mir_surface_spec_set_pixel_format(MirSurfaceSpec* spec, MirPixelFormat format);
4573
4574 /**
4575 * Set the requested buffer usage.
4576 * \param [in] spec Specification to mutate
4577 * \param [in] usage Requested buffer usage
4578- * \return False if the requested buffer usage is invalid for this surface.
4579+ *
4580 * \note If this call returns %true then the server is guaranteed to honour this request.
4581 * If the server is unable to create a surface with this buffer usage at
4582 * the point mir_surface_create() is called it will instead return an invalid surface.
4583 */
4584-bool mir_surface_spec_set_buffer_usage(MirSurfaceSpec* spec, MirBufferUsage usage);
4585+void mir_surface_spec_set_buffer_usage(MirSurfaceSpec* spec, MirBufferUsage usage);
4586
4587 /**
4588 * \param [in] spec Specification to mutate
4589 * \param [in] output_id ID of output to place surface on. From MirDisplayOutput.output_id
4590- * \return False if setting surface fullscreen is invalid for this surface.
4591+ *
4592 * \note If this call returns %true then a valid surface returned from mir_surface_create() is
4593 * guaranteed to be fullscreen on the specified output. An invalid surface is returned
4594 * if the server unable to, or policy prevents it from, honouring this request.
4595 */
4596-bool mir_surface_spec_set_fullscreen_on_output(MirSurfaceSpec* spec, uint32_t output_id);
4597+void mir_surface_spec_set_fullscreen_on_output(MirSurfaceSpec* spec, uint32_t output_id);
4598
4599 /**
4600 * Set the requested preferred orientation mode.
4601 * \param [in] spec Specification to mutate
4602 * \param [in] mode Requested preferred orientation
4603- * \return False if the mode is not valid for this surface type.
4604+ *
4605 * \note If the server is unable to create a surface with the preferred orientation at
4606 * the point mir_surface_create() is called it will instead return an invalid surface.
4607 */
4608-bool mir_surface_spec_set_preferred_orientation(MirSurfaceSpec* spec, MirOrientationMode mode);
4609+void mir_surface_spec_set_preferred_orientation(MirSurfaceSpec* spec, MirOrientationMode mode);
4610+
4611+/**
4612+ * Set the requested state.
4613+ * \param [in] spec Specification to mutate
4614+ * \param [in] mode Requested state
4615+ *
4616+ * \note If the server is unable to create a surface with the requested state at
4617+ * the point mir_surface_create() is called it will instead return an invalid surface.
4618+ */
4619+void mir_surface_spec_set_state(MirSurfaceSpec* spec, MirSurfaceState state);
4620
4621 /**
4622 * Release the resources held by a MirSurfaceSpec.
4623@@ -383,40 +433,26 @@
4624 void mir_surface_spec_release(MirSurfaceSpec* spec);
4625
4626 /**
4627- * Request a new Mir surface on the supplied connection with the supplied
4628- * parameters. The returned handle remains valid until the surface has been
4629- * released.
4630- * \warning callback could be called from another thread. You must do any
4631- * locking appropriate to protect your data accessed in the
4632- * callback.
4633- * \note This will soon be deprecated. Use the *_spec_for_* / mir_surface_create()
4634- * two-stage process instead.
4635- * \param [in] connection The connection
4636- * \param [in] surface_parameters Request surface parameters
4637- * \param [in] callback Callback function to be invoked when
4638- * request completes
4639- * \param [in,out] context User data passed to the callback function
4640- * \return A handle that can be passed to
4641- * mir_wait_for
4642- */
4643-MirWaitHandle *mir_connection_create_surface(
4644- MirConnection *connection,
4645- MirSurfaceParameters const *surface_parameters,
4646- mir_surface_callback callback,
4647- void *context) __attribute__((__deprecated__("Use mir_surface_create()")));
4648-
4649-/**
4650- * Create a surface like in mir_connection_create_surface(), but also wait for
4651- * creation to complete and return the resulting surface.
4652- * \note This will soon be deprecated. Use the create_spec_for/mir_surface_create()
4653- * two-stage process instead.
4654- * \param [in] connection The connection
4655- * \param [in] params Parameters describing the desired surface
4656- * \return The resulting surface
4657- */
4658-MirSurface *mir_connection_create_surface_sync(
4659- MirConnection *connection,
4660- MirSurfaceParameters const *params) __attribute__((__deprecated__("Use mir_surface_create_sync()")));
4661+ * Set the streams associated with the spec.
4662+ * streams[0] is the bottom-most stream, and streams[size-1] is the topmost.
4663+ * On application of the spec, a stream that is present in the surface,
4664+ * but is not in the list will be disassociated from the surface.
4665+ * On application of the spec, a stream that is not present in the surface,
4666+ * but is in the list will be associated with the surface.
4667+ * Streams set a displacement from the top-left corner of the surface.
4668+ *
4669+ * \warning disassociating streams from the surface will not release() them.
4670+ * \warning It is wiser to arrange the streams within the bounds of the
4671+ * surface the spec is applied to. Shells can define their own
4672+ * behavior as to what happens to an out-of-bound stream.
4673+ *
4674+ * \param [in] spec The spec to accumulate the request in.
4675+ * \param [in] streams The an array of non-null streams info.
4676+ * \param [in] num_streams The number of elements in the streams array.
4677+ */
4678+void mir_surface_spec_set_streams(MirSurfaceSpec* spec,
4679+ MirBufferStreamInfo* streams,
4680+ unsigned int num_streams);
4681
4682 /**
4683 * Set the event handler to be called when events arrive for a surface.
4684@@ -442,13 +478,6 @@
4685 MirBufferStream* mir_surface_get_buffer_stream(MirSurface *surface);
4686
4687 /**
4688- * Get a window type that can be used for OpenGL ES 2.0 acceleration.
4689- * \param [in] surface The surface
4690- * \return An EGLNativeWindowType that the client can use
4691- */
4692-MirEGLNativeWindowType mir_surface_get_egl_native_window(MirSurface *surface) __attribute__((__deprecated__("Use mir_surface_get_buffer_stream and the corresponding mir_buffer_stream* function")));
4693-
4694-/**
4695 * Test for a valid surface
4696 * \param [in] surface The surface
4697 * \return True if the supplied surface is valid, or
4698@@ -476,58 +505,6 @@
4699 void mir_surface_get_parameters(MirSurface *surface, MirSurfaceParameters *parameters);
4700
4701 /**
4702- * Get the underlying platform type so the buffer obtained in "raw" representation
4703- * in mir_surface_get_current_buffer() can be understood
4704- * \pre The surface is valid
4705- * \param [in] surface The surface
4706- * \return One of mir_platform_type_android or mir_platform_type_gbm
4707- */
4708-MirPlatformType mir_surface_get_platform_type(MirSurface *surface) __attribute__((__deprecated__("Use mir_surface_get_buffer_stream and the corresponding mir_buffer_stream* function")));
4709-
4710-/**
4711- * Get a surface's buffer in "raw" representation.
4712- * \pre The surface is valid
4713- * \param [in] surface The surface
4714- * \param [out] buffer_package Structure to be populated
4715- */
4716-void mir_surface_get_current_buffer(MirSurface *surface, MirNativeBuffer **buffer_package) __attribute__((__deprecated__("Use mir_surface_get_buffer_stream and the corresponding mir_buffer_stream* function")));
4717-
4718-/**
4719- * Get a surface's graphics_region, i.e., map the graphics buffer to main
4720- * memory.
4721- * \pre The surface is valid
4722- * \param [in] surface The surface
4723- * \param [out] graphics_region Structure to be populated
4724- */
4725-void mir_surface_get_graphics_region(
4726- MirSurface *surface,
4727- MirGraphicsRegion *graphics_region) __attribute__((__deprecated__("Use mir_surface_get_buffer_stream and the corresponding mir_buffer_stream* function")));
4728- /**
4729- * Advance a surface's buffer. The returned handle remains valid until the next
4730- * call to mir_surface_swap_buffers, until the surface has been released or the
4731- * connection to the server has been released.
4732- * \warning callback could be called from another thread. You must do any
4733- * locking appropriate to protect your data accessed in the
4734- * callback.
4735- * \param [in] surface The surface
4736- * \param [in] callback Callback function to be invoked when the request
4737- * completes
4738- * \param [in,out] context User data passed to the callback function
4739- * \return A handle that can be passed to mir_wait_for
4740- */
4741-MirWaitHandle *mir_surface_swap_buffers(
4742- MirSurface *surface,
4743- mir_surface_callback callback,
4744- void *context) __attribute__((__deprecated__("Use mir_surface_get_buffer_stream and the corresponding mir_buffer_stream* function")));
4745-
4746-/**
4747- * Advance a surface's buffer as in mir_surface_swap_buffers(), but also wait
4748- * for the operation to complete.
4749- * \param [in] surface The surface whose buffer to advance
4750- */
4751-void mir_surface_swap_buffers_sync(MirSurface *surface) __attribute__((__deprecated__("Use mir_surface_get_buffer_stream and the corresponding mir_buffer_stream* function")));
4752-
4753-/**
4754 * Release the supplied surface and any associated buffer. The returned wait
4755 * handle remains valid until the connection to the server is released.
4756 * \warning callback could be called from another thread. You must do any
4757@@ -552,18 +529,6 @@
4758 void mir_surface_release_sync(MirSurface *surface);
4759
4760 /**
4761- * \deprecated Use mir_debug_surface_id()
4762- */
4763-__attribute__((__deprecated__("Use mir_debug_surface_id()")))
4764-int mir_surface_get_id(MirSurface *surface);
4765-
4766-/**
4767- * \deprecated Use the mir_connection_create_spec_for_xxx family of APIs
4768- */
4769-__attribute__((__deprecated__("Use mir_connection_create_spec_for_xxx()")))
4770-MirWaitHandle* mir_surface_set_type(MirSurface *surface, MirSurfaceType type);
4771-
4772-/**
4773 * Get the type (purpose) of a surface.
4774 * \param [in] surface The surface to query
4775 * \return The type of the surface
4776@@ -689,6 +654,46 @@
4777 */
4778 void mir_surface_apply_spec(MirSurface* surface, MirSurfaceSpec* spec);
4779
4780+/**
4781+ * \brief Request an ID for the surface that can be shared cross-process and
4782+ * across restarts.
4783+ *
4784+ * This call acquires a MirPersistentId for this MirSurface. This MirPersistentId
4785+ * can be serialized to a string, stored or sent to another process, and then
4786+ * later deserialized to refer to the same surface.
4787+ *
4788+ * \param [in] surface The surface to acquire a persistent reference to.
4789+ * \param [in] callback Callback to invoke when the request completes.
4790+ * \param [in,out] context User data passed to completion callback.
4791+ * \return A MirWaitHandle that can be used in mir_wait_for to await completion.
4792+ */
4793+MirWaitHandle* mir_surface_request_persistent_id(MirSurface* surface, mir_surface_id_callback callback, void* context);
4794+
4795+/**
4796+ * \brief Request a persistent ID for a surface and wait for the result
4797+ * \param [in] surface The surface to acquire a persistent ID for.
4798+ * \return A MirPersistentId. This MirPersistentId is owned by the calling code, and must
4799+ * be freed with a call to mir_persistent_id_release()
4800+ */
4801+MirPersistentId* mir_surface_request_persistent_id_sync(MirSurface *surface);
4802+
4803+/**
4804+ * \brief Check the validity of a MirPersistentId
4805+ * \param [in] id The MirPersistentId
4806+ * \return True iff the MirPersistentId contains a valid ID value.
4807+ *
4808+ * \note This does not guarantee that the ID refers to a currently valid object.
4809+ */
4810+bool mir_persistent_id_is_valid(MirPersistentId* id);
4811+
4812+/**
4813+ * \brief Free a MirPersistentId
4814+ * \param [in] id The MirPersistentId to free
4815+ * \note This frees only the client-side representation; it has no effect on the
4816+ * object referred to by \arg id.
4817+ */
4818+void mir_persistent_id_release(MirPersistentId* id);
4819+
4820 #ifdef __cplusplus
4821 }
4822 /**@}*/
4823
4824=== modified file 'include/client/mir_toolkit/version.h'
4825--- include/client/mir_toolkit/version.h 2015-06-02 23:12:34 +0000
4826+++ include/client/mir_toolkit/version.h 2015-07-23 14:41:37 +0000
4827@@ -33,7 +33,7 @@
4828 *
4829 * See also: http://semver.org/
4830 */
4831-#define MIR_CLIENT_MAJOR_VERSION (2)
4832+#define MIR_CLIENT_MAJOR_VERSION (3)
4833
4834 /**
4835 * MIR_CLIENT_MINOR_VERSION
4836
4837=== modified file 'include/common/mir/dispatch/action_queue.h'
4838--- include/common/mir/dispatch/action_queue.h 2015-03-11 07:43:13 +0000
4839+++ include/common/mir/dispatch/action_queue.h 2015-07-23 14:41:37 +0000
4840@@ -41,7 +41,7 @@
4841 bool dispatch(FdEvents events) override;
4842 FdEvents relevant_events() const override;
4843 private:
4844- void consume();
4845+ bool consume();
4846 void wake();
4847 mir::Fd event_fd;
4848 std::mutex list_lock;
4849
4850=== renamed file 'include/common/mir/dispatch/simple_dispatch_thread.h' => 'include/common/mir/dispatch/threaded_dispatcher.h'
4851--- include/common/mir/dispatch/simple_dispatch_thread.h 2015-04-23 18:29:35 +0000
4852+++ include/common/mir/dispatch/threaded_dispatcher.h 2015-07-23 14:41:37 +0000
4853@@ -19,8 +19,14 @@
4854 #ifndef MIR_DISPATCH_SIMPLE_DISPATCH_THREAD_H_
4855 #define MIR_DISPATCH_SIMPLE_DISPATCH_THREAD_H_
4856
4857+#include <string>
4858 #include <memory>
4859 #include <thread>
4860+#include <vector>
4861+#include <mutex>
4862+#include <condition_variable>
4863+
4864+#include "mir/dispatch/multiplexing_dispatchable.h"
4865 #include "mir/fd.h"
4866
4867 namespace mir
4868@@ -29,18 +35,30 @@
4869 {
4870 class Dispatchable;
4871
4872-
4873-class SimpleDispatchThread
4874+class ThreadedDispatcher
4875 {
4876 public:
4877- SimpleDispatchThread(std::shared_ptr<Dispatchable> const& dispatchee);
4878- SimpleDispatchThread(std::shared_ptr<Dispatchable> const& dispatchee,
4879- std::function<void()> const& exception_handler);
4880- ~SimpleDispatchThread() noexcept;
4881-
4882+ ThreadedDispatcher(std::string const& name, std::shared_ptr<Dispatchable> const& dispatchee);
4883+ ThreadedDispatcher(std::string const& name,
4884+ std::shared_ptr<Dispatchable> const& dispatchee,
4885+ std::function<void()> const& exception_handler);
4886+ ~ThreadedDispatcher() noexcept;
4887+
4888+ void add_thread();
4889+ void remove_thread();
4890+
4891+ class ThreadShutdownRequestHandler;
4892 private:
4893- Fd shutdown_fd;
4894- std::thread eventloop;
4895+
4896+ std::string const name_base;
4897+
4898+ std::shared_ptr<ThreadShutdownRequestHandler> thread_exiter;
4899+ std::shared_ptr<MultiplexingDispatchable> dispatcher;
4900+
4901+ std::mutex thread_pool_mutex;
4902+ std::vector<std::thread> threadpool;
4903+
4904+ std::function<void()> const exception_handler;
4905 };
4906
4907 }
4908
4909=== renamed file 'include/platform/mir/fatal.h' => 'include/common/mir/fatal.h'
4910=== modified file 'include/common/mir/optional_value.h'
4911--- include/common/mir/optional_value.h 2015-04-13 14:07:18 +0000
4912+++ include/common/mir/optional_value.h 2015-07-23 14:41:37 +0000
4913@@ -19,6 +19,8 @@
4914 #ifndef MIR_OPTIONAL_VALUE_H_
4915 #define MIR_OPTIONAL_VALUE_H_
4916
4917+#include "mir/fatal.h"
4918+
4919 namespace mir
4920 {
4921 template<typename T>
4922@@ -36,7 +38,14 @@
4923 }
4924
4925 bool is_set() const { return is_set_; }
4926- T value() const { return value_; }
4927+ T value() const
4928+ {
4929+ if (!is_set())
4930+ {
4931+ (*fatal_error)("Accessing value of unset optional");
4932+ }
4933+ return value_;
4934+ }
4935
4936 private:
4937 T value_;
4938
4939=== modified file 'include/platform/mir/graphics/display_buffer.h'
4940--- include/platform/mir/graphics/display_buffer.h 2015-03-31 02:35:42 +0000
4941+++ include/platform/mir/graphics/display_buffer.h 2015-07-23 14:41:37 +0000
4942@@ -81,12 +81,6 @@
4943 */
4944 virtual MirOrientation orientation() const = 0;
4945
4946- /** Returns true if the display buffer has an alpha channel and the alpha
4947- * channel will be read from at some point - in which case the renderer
4948- * must produce valid alpha channel content
4949- */
4950- virtual bool uses_alpha() const = 0;
4951-
4952 protected:
4953 DisplayBuffer() = default;
4954 DisplayBuffer(DisplayBuffer const& c) = delete;
4955
4956=== modified file 'include/platform/mir/graphics/platform.h'
4957--- include/platform/mir/graphics/platform.h 2015-04-09 06:20:31 +0000
4958+++ include/platform/mir/graphics/platform.h 2015-07-23 14:41:37 +0000
4959@@ -146,7 +146,7 @@
4960 std::shared_ptr<NestedContext> const& nested_context);
4961
4962 /**
4963- * Function prototype used to add platform specific options to the platform-independant server options.
4964+ * Function prototype used to add platform specific options to the platform-independent server options.
4965 *
4966 * \param [in] config a boost::program_options that can be appended with new options
4967 *
4968@@ -177,7 +177,7 @@
4969 extern "C" void add_graphics_platform_options(
4970 boost::program_options::options_description& config);
4971
4972-extern "C" mir::graphics::PlatformPriority probe_graphcis_platform();
4973+extern "C" mir::graphics::PlatformPriority probe_graphics_platform();
4974 extern "C" mir::ModuleProperties const* describe_graphics_module();
4975
4976 #endif // MIR_GRAPHICS_PLATFORM_H_
4977
4978=== modified file 'include/platform/mir/input/device_capability.h'
4979--- include/platform/mir/input/device_capability.h 2015-04-09 06:20:31 +0000
4980+++ include/platform/mir/input/device_capability.h 2015-07-23 14:41:37 +0000
4981@@ -42,6 +42,7 @@
4982 alpha_numeric = 1<<9 // enough keys for text entry
4983 };
4984
4985+DeviceCapability mir_enable_enum_bit_operators(DeviceCapability);
4986 using DeviceCapabilities = mir::Flags<DeviceCapability>;
4987
4988 }
4989
4990=== modified file 'include/platform/mir/input/input_sink.h'
4991--- include/platform/mir/input/input_sink.h 2015-04-09 06:20:31 +0000
4992+++ include/platform/mir/input/input_sink.h 2015-07-23 14:41:37 +0000
4993@@ -21,6 +21,8 @@
4994 #define MIR_INPUT_INPUT_SINK_H_
4995
4996 #include "mir_toolkit/event.h"
4997+#include "mir/geometry/rectangle.h"
4998+#include "mir/geometry/displacement.h"
4999
5000 namespace mir
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: