Mir

Merge lp:~mir-team/mir/v0.1.2 into lp:mir/0.1

Proposed by kevin gunn
Status: Merged
Approved by: Timo Jyrinki
Approved revision: no longer in the source branch.
Merged at revision: 1167
Proposed branch: lp:~mir-team/mir/v0.1.2
Merge into: lp:mir/0.1
Diff against target: 28153 lines (+9779/-6877)
377 files modified
3rd_party/android-input/android/CMakeLists.txt (+1/-0)
3rd_party/android-input/android/frameworks/base/include/androidfw/Input.h (+5/-2)
3rd_party/android-input/android/frameworks/base/include/androidfw/InputTransport.h (+10/-7)
3rd_party/android-input/android/frameworks/base/include/androidfw/IntSet.h (+104/-0)
3rd_party/android-input/android/frameworks/base/include/androidfw/VelocityControl.h (+2/-0)
3rd_party/android-input/android/frameworks/base/include/androidfw/VelocityTracker.h (+24/-22)
3rd_party/android-input/android/frameworks/base/services/input/InputDevice.cpp (+6/-3)
3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp (+40/-33)
3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.h (+6/-6)
3rd_party/android-input/android/frameworks/base/services/input/InputEventPrinter.h (+138/-0)
3rd_party/android-input/android/frameworks/base/services/input/InputListener.h (+1/-1)
3rd_party/android-input/android/frameworks/base/services/input/InputReader.cpp (+409/-354)
3rd_party/android-input/android/frameworks/base/services/input/InputReader.h (+68/-40)
3rd_party/android-input/android/frameworks/base/services/input/InputTransport.cpp (+8/-8)
3rd_party/android-input/android/frameworks/base/services/input/IntSet.cpp (+123/-0)
3rd_party/android-input/android/frameworks/base/services/input/PointerController.cpp (+5/-8)
3rd_party/android-input/android/frameworks/base/services/input/PointerController.h (+2/-5)
3rd_party/android-input/android/frameworks/base/services/input/VelocityControl.cpp (+2/-2)
3rd_party/android-input/android/frameworks/base/services/input/VelocityTracker.cpp (+80/-83)
CMakeLists.txt (+1/-1)
debian/changelog (+93/-0)
debian/control (+2/-2)
debian/libmirserver11.install (+1/-1)
doc/Doxyfile.in (+192/-82)
doc/component_reports.md (+2/-1)
doc/installing_prebuilt_on_pc.md (+6/-1)
doc/using_mir_on_pc.md (+8/-6)
examples/CMakeLists.txt (+1/-0)
examples/buffer_render_target.cpp (+3/-1)
examples/buffer_render_target.h (+1/-0)
examples/demo-inprocess-surface-client/inprocess_egl_client.cpp (+1/-2)
examples/demo-shell/demo_shell.cpp (+0/-1)
examples/demo-shell/window_manager.cpp (+102/-14)
examples/demo-shell/window_manager.h (+6/-2)
examples/demo_input_filter.cpp (+25/-3)
examples/eglapp.c (+16/-8)
examples/progressbar.c (+9/-4)
examples/render_surfaces.cpp (+20/-18)
include/client/mir_toolkit/mir_client_library.h (+1/-1)
include/platform/mir/graphics/basic_platform.h (+45/-0)
include/platform/mir/graphics/buffer_ipc_packer.h (+2/-0)
include/platform/mir/graphics/egl_resources.h (+10/-4)
include/platform/mir/graphics/native_platform.h (+1/-1)
include/platform/mir/graphics/platform.h (+4/-3)
include/server/mir/compositor/buffer_stream.h (+1/-0)
include/server/mir/compositor/scene.h (+1/-1)
include/server/mir/default_configuration_options.h (+2/-1)
include/server/mir/default_server_configuration.h (+57/-62)
include/server/mir/frontend/shell.h (+2/-2)
include/server/mir/frontend/surface.h (+4/-21)
include/server/mir/input/android/dispatcher_input_configuration.h (+1/-1)
include/server/mir/input/input_configuration.h (+2/-2)
include/server/mir/scene/buffer_stream_factory.h (+4/-4)
include/server/mir/scene/depth_id.h (+4/-4)
include/server/mir/scene/input_registrar.h (+4/-4)
include/server/mir/scene/scene_report.h (+19/-19)
include/server/mir/shell/snapshot.h (+3/-3)
include/server/mir/shell/surface.h (+21/-68)
include/server/mir/shell/surface_controller.h (+3/-3)
include/server/mir/shell/surface_creation_parameters.h (+3/-3)
include/shared/mir/geometry/dimensions.h (+1/-0)
include/shared/mir/geometry/displacement.h (+2/-6)
include/shared/mir/geometry/point.h (+2/-7)
include/shared/mir/geometry/rectangle.h (+2/-7)
include/shared/mir/geometry/size.h (+2/-7)
include/shared/mir/graphics/android/mir_native_window.h (+2/-0)
include/shared/mir/input/input_platform.h (+3/-1)
include/shared/mir/input/input_receiver_report.h (+48/-0)
include/shared/mir/input/null_input_receiver_report.h (+46/-0)
include/shared/mir_toolkit/client_types.h (+2/-1)
include/shared/mir_toolkit/common.h (+4/-5)
include/shared/mir_toolkit/event.h (+9/-1)
include/shared/mir_toolkit/mir_native_buffer.h (+6/-2)
include/test/mir_test/client_event_matchers.h (+119/-0)
include/test/mir_test/draw/draw_pattern_checkered-inl.h (+10/-5)
include/test/mir_test_doubles/mock_buffer_packer.h (+1/-0)
include/test/mir_test_doubles/mock_buffer_stream.h (+1/-0)
include/test/mir_test_doubles/mock_display_device.h (+4/-6)
include/test/mir_test_doubles/mock_egl.h (+17/-0)
include/test/mir_test_doubles/mock_fb_hal_device.h (+5/-5)
include/test/mir_test_doubles/mock_framebuffer_bundle.h (+51/-0)
include/test/mir_test_doubles/mock_frontend_surface.h (+1/-1)
include/test/mir_test_doubles/mock_gl.h (+2/-0)
include/test/mir_test_doubles/mock_hwc_composer_device_1.h (+28/-4)
include/test/mir_test_doubles/mock_input_registrar.h (+2/-2)
include/test/mir_test_doubles/mock_surface.h (+4/-4)
include/test/mir_test_doubles/mock_surface_controller.h (+1/-1)
include/test/mir_test_doubles/mock_surface_state.h (+3/-2)
include/test/mir_test_doubles/null_platform.h (+7/-3)
include/test/mir_test_doubles/null_session_event_sink.h (+2/-2)
include/test/mir_test_doubles/null_snapshot_strategy.h (+2/-2)
include/test/mir_test_doubles/stub_buffer_stream.h (+4/-0)
include/test/mir_test_doubles/stub_display_builder.h (+80/-0)
include/test/mir_test_doubles/stub_display_configuration.h (+11/-4)
include/test/mir_test_doubles/stub_display_device.h (+12/-16)
include/test/mir_test_doubles/stub_input_registrar.h (+2/-2)
include/test/mir_test_doubles/stub_surface.h (+1/-1)
include/test/mir_test_doubles/stub_surface_builder.h (+9/-9)
include/test/mir_test_doubles/stub_surface_controller.h (+1/-1)
include/test/mir_test_framework/input_testing_server_configuration.h (+2/-10)
include/test/mir_test_framework/udev_environment.h (+12/-1)
src/client/CMakeLists.txt (+1/-0)
src/client/android/android_client_buffer.cpp (+2/-0)
src/client/android/android_client_buffer_factory.cpp (+7/-1)
src/client/android/client_surface_interpreter.cpp (+1/-1)
src/client/default_connection_configuration.cpp (+20/-2)
src/client/default_connection_configuration.h (+9/-0)
src/client/gbm/gbm_client_buffer_factory.cpp (+6/-1)
src/client/logging/input_receiver_report.cpp (+125/-0)
src/client/logging/input_receiver_report.h (+54/-0)
src/client/lttng/rpc_report_tp.h (+14/-0)
src/client/mir_client_library.cpp (+1/-1)
src/client/mir_connection.cpp (+6/-8)
src/client/mir_connection.h (+2/-2)
src/client/mir_surface.cpp (+16/-5)
src/client/mir_surface.h (+1/-1)
src/platform/graphics/egl_resources.cpp (+30/-6)
src/server/CMakeLists.txt (+7/-5)
src/server/compositor/buffer_stream_factory.cpp (+1/-1)
src/server/compositor/buffer_stream_factory.h (+2/-2)
src/server/compositor/buffer_stream_surfaces.cpp (+5/-0)
src/server/compositor/buffer_stream_surfaces.h (+4/-3)
src/server/compositor/default_configuration.cpp (+1/-1)
src/server/default_configuration_options.cpp (+6/-3)
src/server/default_server_configuration.cpp (+1/-1)
src/server/frontend/CMakeLists.txt (+0/-1)
src/server/frontend/default_configuration.cpp (+6/-26)
src/server/frontend/protobuf_buffer_packer.cpp (+6/-0)
src/server/frontend/protobuf_buffer_packer.h (+1/-0)
src/server/frontend/published_socket_connector.cpp (+5/-5)
src/server/frontend/published_socket_connector.h (+3/-3)
src/server/frontend/session_mediator.cpp (+59/-34)
src/server/frontend/session_mediator.h (+8/-4)
src/server/frontend/surface.cpp (+1/-16)
src/server/graphics/CMakeLists.txt (+1/-0)
src/server/graphics/android/CMakeLists.txt (+4/-2)
src/server/graphics/android/android_buffer_allocator.cpp (+1/-1)
src/server/graphics/android/android_display.cpp (+9/-145)
src/server/graphics/android/android_display.h (+9/-17)
src/server/graphics/android/android_graphic_buffer_allocator.h (+1/-1)
src/server/graphics/android/android_platform.cpp (+25/-51)
src/server/graphics/android/android_platform.h (+5/-5)
src/server/graphics/android/display_buffer.cpp (+69/-0)
src/server/graphics/android/display_buffer.h (+61/-0)
src/server/graphics/android/display_builder.h (+15/-18)
src/server/graphics/android/display_device.h (+4/-12)
src/server/graphics/android/display_resource_factory.h (+3/-14)
src/server/graphics/android/fb_device.cpp (+19/-45)
src/server/graphics/android/fb_device.h (+5/-10)
src/server/graphics/android/framebuffer_bundle.h (+17/-11)
src/server/graphics/android/framebuffers.cpp (+120/-9)
src/server/graphics/android/framebuffers.h (+19/-13)
src/server/graphics/android/gl_context.cpp (+155/-0)
src/server/graphics/android/gl_context.h (+78/-0)
src/server/graphics/android/graphic_buffer_allocator.h (+2/-2)
src/server/graphics/android/hwc10_device.cpp (+37/-54)
src/server/graphics/android/hwc10_device.h (+10/-11)
src/server/graphics/android/hwc11_device.cpp (+34/-62)
src/server/graphics/android/hwc11_device.h (+11/-13)
src/server/graphics/android/hwc_common_device.cpp (+1/-8)
src/server/graphics/android/hwc_common_device.h (+1/-0)
src/server/graphics/android/hwc_layerlist.cpp (+89/-102)
src/server/graphics/android/hwc_layerlist.h (+38/-59)
src/server/graphics/android/output_builder.cpp (+78/-97)
src/server/graphics/android/output_builder.h (+32/-10)
src/server/graphics/android/resource_factory.cpp (+8/-32)
src/server/graphics/android/resource_factory.h (+2/-20)
src/server/graphics/android/server_render_window.cpp (+11/-15)
src/server/graphics/android/server_render_window.h (+3/-7)
src/server/graphics/default_configuration.cpp (+14/-3)
src/server/graphics/gbm/CMakeLists.txt (+1/-1)
src/server/graphics/gbm/gbm_buffer.cpp (+4/-0)
src/server/graphics/gbm/gbm_display.cpp (+14/-6)
src/server/graphics/gbm/gbm_display.h (+1/-3)
src/server/graphics/gbm/gbm_display_helpers.cpp (+26/-76)
src/server/graphics/gbm/gbm_display_helpers.h (+4/-20)
src/server/graphics/gbm/gbm_platform.cpp (+9/-5)
src/server/graphics/gbm/gbm_platform.h (+4/-3)
src/server/graphics/gbm/linux_virtual_terminal.cpp (+11/-1)
src/server/graphics/gbm/native_gbm_platform.cpp (+1/-3)
src/server/graphics/gbm/native_gbm_platform.h (+1/-1)
src/server/graphics/gbm/udev_video_devices.cpp (+0/-58)
src/server/graphics/gbm/udev_video_devices.h (+0/-50)
src/server/graphics/gbm/udev_wrapper.cpp (+275/-0)
src/server/graphics/gbm/udev_wrapper.h (+149/-0)
src/server/graphics/gbm/video_devices.h (+0/-52)
src/server/graphics/nested/nested_display.cpp (+25/-3)
src/server/graphics/nested/nested_platform.cpp (+7/-2)
src/server/graphics/nested/nested_platform.h (+2/-2)
src/server/graphics/offscreen/CMakeLists.txt (+13/-0)
src/server/graphics/offscreen/display.cpp (+197/-0)
src/server/graphics/offscreen/display.h (+105/-0)
src/server/graphics/offscreen/display_buffer.cpp (+156/-0)
src/server/graphics/offscreen/display_buffer.h (+82/-0)
src/server/graphics/offscreen/display_configuration.cpp (+72/-0)
src/server/graphics/offscreen/display_configuration.h (+51/-0)
src/server/graphics/offscreen/gl_extensions_base.cpp (+51/-0)
src/server/graphics/offscreen/gl_extensions_base.h (+47/-0)
src/server/graphics/offscreen/surfaceless_egl_context.cpp (+132/-0)
src/server/graphics/offscreen/surfaceless_egl_context.h (+59/-0)
src/server/input/android/android_input_registrar.cpp (+1/-1)
src/server/input/android/android_input_registrar.h (+2/-2)
src/server/input/android/android_input_target_enumerator.h (+1/-1)
src/server/input/android/android_input_targeter.cpp (+1/-1)
src/server/input/android/default_android_input_configuration.cpp (+1/-1)
src/server/input/android/dispatcher_input_configuration.cpp (+1/-1)
src/server/input/android/dummy_android_pointer_controller.h (+2/-4)
src/server/input/default_configuration.cpp (+1/-1)
src/server/input/null_input_configuration.cpp (+2/-2)
src/server/input/null_input_configuration.h (+1/-1)
src/server/logging/CMakeLists.txt (+0/-1)
src/server/logging/default_configuration.cpp (+1/-25)
src/server/logging/display_report.cpp (+3/-2)
src/server/logging/surfaces_report.cpp (+0/-119)
src/server/lttng/input_report_tp.h (+13/-0)
src/server/lttng/message_processor_report_tp.h (+14/-0)
src/server/scene/CMakeLists.txt (+12/-2)
src/server/scene/application_session.cpp (+19/-18)
src/server/scene/application_session.h (+16/-15)
src/server/scene/basic_surface.h (+39/-51)
src/server/scene/broadcasting_session_event_sink.cpp (+13/-12)
src/server/scene/broadcasting_session_event_sink.h (+10/-13)
src/server/scene/default_configuration.cpp (+190/-10)
src/server/scene/default_session_container.cpp (+27/-4)
src/server/scene/default_session_container.h (+11/-11)
src/server/scene/gl_pixel_buffer.cpp (+9/-9)
src/server/scene/gl_pixel_buffer.h (+4/-4)
src/server/scene/global_event_sender.cpp (+6/-6)
src/server/scene/global_event_sender.h (+8/-10)
src/server/scene/mediating_display_changer.cpp (+13/-12)
src/server/scene/mediating_display_changer.h (+6/-8)
src/server/scene/mutable_surface_state.h (+5/-4)
src/server/scene/pixel_buffer.h (+4/-5)
src/server/scene/scene_report.cpp (+108/-9)
src/server/scene/scene_report.h (+11/-11)
src/server/scene/session_container.h (+14/-11)
src/server/scene/session_event_handler_register.h (+8/-9)
src/server/scene/session_event_sink.h (+8/-9)
src/server/scene/session_manager.cpp (+26/-30)
src/server/scene/session_manager.h (+22/-32)
src/server/scene/snapshot_strategy.h (+8/-6)
src/server/scene/surface.cpp (+25/-5)
src/server/scene/surface.h (+81/-0)
src/server/scene/surface_allocator.cpp (+7/-7)
src/server/scene/surface_allocator.h (+8/-8)
src/server/scene/surface_builder.h (+11/-8)
src/server/scene/surface_controller.cpp (+5/-5)
src/server/scene/surface_controller.h (+9/-9)
src/server/scene/surface_data.cpp (+11/-1)
src/server/scene/surface_data.h (+5/-4)
src/server/scene/surface_factory.h (+6/-6)
src/server/scene/surface_impl.cpp (+50/-32)
src/server/scene/surface_impl.h (+114/-0)
src/server/scene/surface_source.cpp (+6/-9)
src/server/scene/surface_source.h (+13/-9)
src/server/scene/surface_stack.cpp (+17/-12)
src/server/scene/surface_stack.h (+13/-14)
src/server/scene/surface_stack_model.h (+9/-9)
src/server/scene/surface_state.h (+4/-4)
src/server/scene/threaded_snapshot_strategy.cpp (+10/-9)
src/server/scene/threaded_snapshot_strategy.h (+6/-7)
src/server/shell/CMakeLists.txt (+0/-10)
src/server/shell/default_configuration.cpp (+3/-135)
src/server/shell/focus_sequence.h (+0/-51)
src/server/shell/registration_order_focus_sequence.cpp (+0/-120)
src/server/shell/registration_order_focus_sequence.h (+0/-52)
src/server/shell/surface_creation_parameters.cpp (+1/-1)
src/shared/geometry/CMakeLists.txt (+1/-0)
src/shared/geometry/ostream.cpp (+60/-0)
src/shared/geometry/rectangles.cpp (+0/-9)
src/shared/graphics/android/mir_native_window.cpp (+22/-9)
src/shared/input/android/android_input_lexicon.cpp (+3/-0)
src/shared/input/android/android_input_platform.cpp (+11/-3)
src/shared/input/android/android_input_platform.h (+4/-1)
src/shared/input/android/android_input_receiver.cpp (+9/-2)
src/shared/input/android/android_input_receiver.h (+7/-2)
src/shared/protobuf/mir_protobuf.proto (+8/-32)
tests/acceptance-tests/test_client_authorization.cpp (+9/-57)
tests/acceptance-tests/test_client_focus_notification.cpp (+14/-47)
tests/acceptance-tests/test_client_input.cpp (+387/-622)
tests/acceptance-tests/test_client_library.cpp (+75/-0)
tests/acceptance-tests/test_display_configuration.cpp (+3/-17)
tests/acceptance-tests/test_focus_selection.cpp (+9/-54)
tests/acceptance-tests/test_server_shutdown.cpp (+3/-3)
tests/acceptance-tests/test_surfaceloop.cpp (+0/-1)
tests/acceptance-tests/test_surfaces_with_output_id.cpp (+1/-1)
tests/draw/android_graphics.cpp (+2/-1)
tests/draw/patterns.cpp (+12/-10)
tests/integration-tests/CMakeLists.txt (+2/-0)
tests/integration-tests/client/test_client_render.cpp (+76/-37)
tests/integration-tests/compositor/test_buffer_stream.cpp (+73/-0)
tests/integration-tests/graphics/android/test_display_integration.cpp (+47/-95)
tests/integration-tests/graphics/android/test_internal_client.cpp (+17/-12)
tests/integration-tests/graphics/gbm/test_buffer_integration.cpp (+5/-9)
tests/integration-tests/input/android/test_android_input_manager.cpp (+1/-1)
tests/integration-tests/shell/CMakeLists.txt (+0/-2)
tests/integration-tests/shell/test_session_lifecycle_event.cpp (+4/-3)
tests/integration-tests/test_display_info.cpp (+14/-18)
tests/integration-tests/test_drm_auth_magic.cpp (+2/-17)
tests/integration-tests/test_session.cpp (+11/-21)
tests/integration-tests/test_session_manager.cpp (+7/-11)
tests/integration-tests/test_surface_first_frame_sync.cpp (+1/-1)
tests/integration-tests/test_surfaceloop.cpp (+9/-20)
tests/integration-tests/test_swapinterval.cpp (+3/-2)
tests/mir_test_doubles/mock_egl.cpp (+1/-1)
tests/mir_test_doubles/mock_gl.cpp (+12/-0)
tests/mir_test_framework/input_testing_server_options.cpp (+1/-113)
tests/mir_test_framework/testing_server_options.cpp (+21/-21)
tests/mir_test_framework/udev_environment.cpp (+45/-0)
tests/unit-tests/CMakeLists.txt (+1/-1)
tests/unit-tests/android_input/CMakeLists.txt (+1/-0)
tests/unit-tests/android_input/input_reader.cpp (+156/-98)
tests/unit-tests/android_input/int_set.cpp (+133/-0)
tests/unit-tests/client/android/test_android_native_window.cpp (+21/-3)
tests/unit-tests/client/android/test_client_surface_interpreter.cpp (+16/-0)
tests/unit-tests/client/gbm/test_gbm_client_buffer.cpp (+21/-0)
tests/unit-tests/client/input/test_android_input_receiver.cpp (+8/-5)
tests/unit-tests/client/input/test_android_input_receiver_thread.cpp (+5/-2)
tests/unit-tests/client/test_android_client_buffer_factory.cpp (+5/-5)
tests/unit-tests/client/test_client_mir_surface.cpp (+47/-0)
tests/unit-tests/client/test_mir_connection.cpp (+15/-4)
tests/unit-tests/compositor/test_buffer_stream.cpp (+12/-0)
tests/unit-tests/compositor/test_gl_renderer.cpp (+1/-4)
tests/unit-tests/draw/test_draw_patterns.cpp (+10/-11)
tests/unit-tests/frontend/CMakeLists.txt (+0/-1)
tests/unit-tests/frontend/test_protobuf_buffer_packer.cpp (+3/-0)
tests/unit-tests/frontend/test_session_mediator.cpp (+17/-24)
tests/unit-tests/frontend/test_session_mediator_android.cpp (+5/-19)
tests/unit-tests/frontend/test_session_mediator_gbm.cpp (+5/-20)
tests/unit-tests/graphics/CMakeLists.txt (+1/-0)
tests/unit-tests/graphics/android/CMakeLists.txt (+1/-0)
tests/unit-tests/graphics/android/test_android_fb.cpp (+163/-573)
tests/unit-tests/graphics/android/test_android_platform.cpp (+31/-213)
tests/unit-tests/graphics/android/test_fb_device.cpp (+28/-68)
tests/unit-tests/graphics/android/test_fb_simple_swapper.cpp (+179/-106)
tests/unit-tests/graphics/android/test_hwc10_device.cpp (+37/-94)
tests/unit-tests/graphics/android/test_hwc11_device.cpp (+67/-158)
tests/unit-tests/graphics/android/test_hwc_device.cpp (+39/-77)
tests/unit-tests/graphics/android/test_hwc_display.cpp (+132/-97)
tests/unit-tests/graphics/android/test_hwc_layerlist.cpp (+118/-136)
tests/unit-tests/graphics/android/test_output_builder.cpp (+241/-0)
tests/unit-tests/graphics/android/test_resource_factory.cpp (+3/-79)
tests/unit-tests/graphics/android/test_server_interpreter.cpp (+19/-36)
tests/unit-tests/graphics/gbm/CMakeLists.txt (+1/-1)
tests/unit-tests/graphics/gbm/test_gbm_display.cpp (+57/-20)
tests/unit-tests/graphics/gbm/test_gbm_platform.cpp (+20/-10)
tests/unit-tests/graphics/gbm/test_linux_virtual_terminal.cpp (+58/-5)
tests/unit-tests/graphics/gbm/test_udev_helper.cpp (+467/-0)
tests/unit-tests/graphics/gbm/test_udev_video_devices.cpp (+0/-76)
tests/unit-tests/graphics/nested/CMakeLists.txt (+1/-0)
tests/unit-tests/graphics/nested/test_nested_platform.cpp (+27/-0)
tests/unit-tests/graphics/offscreen/CMakeLists.txt (+6/-0)
tests/unit-tests/graphics/offscreen/test_offscreen_display.cpp (+147/-0)
tests/unit-tests/graphics/test_display.cpp (+11/-15)
tests/unit-tests/input/android/test_android_communication_package.cpp (+2/-2)
tests/unit-tests/input/android/test_android_input_lexicon.cpp (+9/-0)
tests/unit-tests/input/android/test_android_input_manager.cpp (+2/-2)
tests/unit-tests/input/android/test_android_input_registrar.cpp (+1/-1)
tests/unit-tests/logging/test_display_report.cpp (+2/-1)
tests/unit-tests/scene/CMakeLists.txt (+10/-0)
tests/unit-tests/scene/test_application_session.cpp (+12/-12)
tests/unit-tests/scene/test_broadcasting_session_event_sink.cpp (+5/-4)
tests/unit-tests/scene/test_default_focus_mechanism.cpp (+3/-4)
tests/unit-tests/scene/test_gl_pixel_buffer.cpp (+5/-5)
tests/unit-tests/scene/test_global_event_sender.cpp (+6/-5)
tests/unit-tests/scene/test_session_manager.cpp (+23/-35)
tests/unit-tests/scene/test_surface.cpp (+53/-4)
tests/unit-tests/scene/test_surface_allocator.cpp (+1/-1)
tests/unit-tests/scene/test_surface_controller.cpp (+8/-8)
tests/unit-tests/scene/test_surface_data.cpp (+20/-2)
tests/unit-tests/scene/test_surface_impl.cpp (+38/-38)
tests/unit-tests/scene/test_surface_stack.cpp (+9/-9)
tests/unit-tests/scene/test_the_session_container_implementation.cpp (+40/-41)
tests/unit-tests/scene/test_threaded_snapshot_strategy.cpp (+5/-4)
tests/unit-tests/shell/CMakeLists.txt (+0/-9)
tests/unit-tests/shell/test_mediating_display_changer.cpp (+1/-1)
tests/unit-tests/shell/test_registration_order_focus_sequence.cpp (+0/-159)
To merge this branch: bzr merge lp:~mir-team/mir/v0.1.2
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Daniel van Vugt Approve
Robert Carr (community) Approve
Kevin DuBois (community) Approve
Review via email: mp+196359@code.launchpad.net

Commit message

Merge v0.1.2 from development-branch r1248

    - graphics: android: improve interface for mga::DisplayDevice so its
      just concerned with rendering and posting.
    - surfaces: rename "surfaces" component to "scene".
    - surfaces, shell: Migrate Session data model from shell to surfaces.
    - graphics: change fill_ipc_package() to use real pointers.
    - mir_client_library.h: Fix typo "do and locking" should be "do any
      locking".
    - API enumerations cleanup: Remove slightly misleading *_enum_max_
      values, and replace them with more accurate plural forms.
    - test_android_communication_package: Do not expect opened fd to be >0,
      we may have closed stdin making this a valid value (LP: #1247718).
    - Update docs about running Mir on the desktop to mention new package
      ubuntu-desktop-mir.
    - offscreen: Add a display that renders its output to offscreen buffers
    - graphics: android: fix regression for hwc1.0 devices introduced in r1228
      (LP: #1252433).
    - OffscreenPlatform provides the services that the offscreen display
      needs from the Platform.
    - graphics: android: consolidate the GLContexts classes in use.
    - Fix uninitialized variable causing random drm_auth_magic test
      failures. (LP: #1252144).
    - Add a fullyish functional Udev wrapper. This currently sits in
      graphics/gbm, but will be moved to the top-level when input device
      detection migrates.
    - Add resizing support to example code; demo-shell and clients.
    - eglapp: Clarify messages about pixel formats (LP: #1168304).
    - Adds support to the MirMotionEvent under pointer_coordinates called
      tool_type. This will allow clients to tell what type of tool is
      being used, from mouse/finger/etc. (LP: #1252498)
    - client,frontend: Report the real available surface pixel formats to
      clients. (LP: #1240833)
    - graphics: android: 1) change hwc1.1 to make use of sync fences during
      the compositor's gl renderloop. Note that we no longer wait for the
      render to complete, we pass this responsibility to the driver and the
      kernel. 2) support nexus 10. (LP: #1252173) (LP: #1203268)
    - shell: don't publish SurfacesContainer - it can be private to shell.
    - gbm: Don't mess up the VT mode on setup failure Only restore the
      previous VT mode during shutdown if it was VT_AUTO.
    - Fix a crash due to a failed eglMakeCurrent() call when in nested mode.
    - shell: unity-mir uses shell::FocusSetter - make the header public again
    - Add resize support to client surfaces (mir::client::MirSurface).
    - graphics: android: support 'old aka 2012' nexus 7 hwc (nvidia tegra3
      SoC) better. (LP: #1231917)
    - Add resize support to *ClientBuffer classes. Now always get dimensions
      from the latest buffer package.
    - android: support driver hooks for the Mali T604 (present in nexus 10)
    - Add width and height to the protocol Buffer messages, in preparation
      for resizable surfaces.
    - surfaces, shell, logging, tests: don't publish headers
      that can be private to surfaces. surfaces/basic_surface.h,
      surfaces/surface_controller.h and shell/surface_builder.h
    - examples: Restore GL framebuffer binding when destroying the render
      target
    - examples, surfaces, shell: remove render_surfaces dependency on
      BasicSurface
    - geometry: remove implementation of streaming operators from headers
      (LP: #1247820)
    - Eliminate the registration order focus sequence, folding it's
      functionality in to the session container.
    - Ensure the session mediator releases acquired buffer resources before
      attempting to acquire a new buffer on behalf of the client. This fixes
      performance regression (LP: #1249210).
    - Some cleanups to test_client_input.cpp.
    - Factor out a bunch of "ClientConfigCommon".
    - Small cleanup to session container test to increase encapsulation.
    - shell, surfaces: Another step in "fixing" the surfaces hierarchies -
      only publish interfaces and putting the data model into surfaces.
    - graphics: android: HWC1.1 use EGL to get further information about
      the framebuffer pixel format.
    - Fix FTBS using use_debflags=ON (building for android-armhf).
      (LP: #1248014)
    - Add a client input receiver report.
    - doc: doxygen 1.8.4 complains about an obsolete config so ran "doxygen
      u Doxyfile.in".
    - Implement resize() for the server-side Surface classes.
    - android: clean up mga::DisplayBuffer and mga::DisplayBufferFactory
    - Add resize() support to BufferStream, in preparation for resizable
      surfaces.
    - Merge metadata changes from the newly reconstructed lp:mir
    - tests: Deduplicate mg::GraphicBufferAllocator stubs.
    - examples: Remove spurious use of mir/shell/surface.h.
    - frontend: remove ClientTrackingSurface from the Surface class
      hierarchy
    - Bumping ABI on server to libmirserver11.
    - Don't mention "Renderable". That interface hasn't existed for quite
      some time now.
    - android-input: Assign more unique touch ids

To post a comment you must log in.
Revision history for this message
Kevin DuBois (kdub) wrote :

looks okay to me

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

+1

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

The debian/changelog is missing stuff that is correctly mentioned in the commit message. Also, we need to use the official format "(LP: #NNNNNNN)" to keep the automation accurate.

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '3rd_party/android-input/android/CMakeLists.txt'
2--- 3rd_party/android-input/android/CMakeLists.txt 2013-10-15 08:53:10 +0000
3+++ 3rd_party/android-input/android/CMakeLists.txt 2013-11-25 03:07:43 +0000
4@@ -33,6 +33,7 @@
5 frameworks/base/services/input/InputReader.cpp
6 frameworks/base/services/input/InputTransport.cpp
7 frameworks/base/services/input/InputWindow.cpp
8+ frameworks/base/services/input/IntSet.cpp
9 frameworks/base/services/input/PointerController.cpp
10 # Keyboard/keymap handling
11 frameworks/base/services/input/GenericKeyMap.cpp
12
13=== modified file '3rd_party/android-input/android/frameworks/base/include/androidfw/Input.h'
14--- 3rd_party/android-input/android/frameworks/base/include/androidfw/Input.h 2013-05-03 16:38:07 +0000
15+++ 3rd_party/android-input/android/frameworks/base/include/androidfw/Input.h 2013-11-25 03:07:43 +0000
16@@ -77,9 +77,12 @@
17 /*
18 * Maximum pointer id value supported in a motion event.
19 * Smallest pointer id is 0.
20- * (This is limited by our use of BitSet32 to track pointer assignments.)
21+ * Any reasonably large value that fits in a int32_t is fine.
22+ * A "reasonably large" number is one that guarantees uniqueness of a touch id for some 30 seconds
23+ * after its corresponding touch point has physically ended, under very heavy usage (many
24+ * simultaneous taps ongoing).
25 */
26-#define MAX_POINTER_ID 31
27+#define MAX_POINTER_ID 100000000
28
29 /*
30 * Declare a concrete type for the NDK's input event forward declaration.
31
32=== modified file '3rd_party/android-input/android/frameworks/base/include/androidfw/InputTransport.h'
33--- 3rd_party/android-input/android/frameworks/base/include/androidfw/InputTransport.h 2013-05-31 16:06:07 +0000
34+++ 3rd_party/android-input/android/frameworks/base/include/androidfw/InputTransport.h 2013-11-25 03:07:43 +0000
35@@ -29,12 +29,15 @@
36 */
37
38 #include <androidfw/Input.h>
39+#include <androidfw/IntSet.h>
40 #include <std/Errors.h>
41 #include <std/Timers.h>
42 #include <std/RefBase.h>
43 #include <std/String8.h>
44 #include <std/Vector.h>
45-#include <std/BitSet.h>
46+
47+// C++ std lib
48+#include <unordered_map>
49
50 namespace android {
51
52@@ -352,23 +355,23 @@
53 // Touch state per device and source, only for sources of class pointer.
54 struct History {
55 nsecs_t eventTime;
56- BitSet32 idBits;
57- int32_t idToIndex[MAX_POINTER_ID + 1];
58+ IntSet ids;
59+ std::unordered_map<int32_t, size_t> idToIndex;
60 PointerCoords pointers[MAX_POINTERS];
61
62 void initializeFrom(const InputMessage* msg) {
63 eventTime = msg->body.motion.eventTime;
64- idBits.clear();
65+ ids.clear();
66 for (size_t i = 0; i < msg->body.motion.pointerCount; i++) {
67 uint32_t id = msg->body.motion.pointers[i].properties.id;
68- idBits.markBit(id);
69+ ids.insert(id);
70 idToIndex[id] = i;
71 pointers[i].copyFrom(msg->body.motion.pointers[i].coords);
72 }
73 }
74
75 const PointerCoords& getPointerById(uint32_t id) const {
76- return pointers[idToIndex[id]];
77+ return pointers[idToIndex.at(id)];
78 }
79 };
80 struct TouchState {
81@@ -385,7 +388,7 @@
82 historyCurrent = 0;
83 historySize = 0;
84 lastResample.eventTime = 0;
85- lastResample.idBits.clear();
86+ lastResample.ids.clear();
87 }
88
89 void addHistory(const InputMessage* msg) {
90
91=== added file '3rd_party/android-input/android/frameworks/base/include/androidfw/IntSet.h'
92--- 3rd_party/android-input/android/frameworks/base/include/androidfw/IntSet.h 1970-01-01 00:00:00 +0000
93+++ 3rd_party/android-input/android/frameworks/base/include/androidfw/IntSet.h 2013-11-25 03:07:43 +0000
94@@ -0,0 +1,104 @@
95+/*
96+ * Copyright © 2013 Canonical Ltd.
97+ *
98+ * This program is free software: you can redistribute it and/or modify it
99+ * under the terms of the GNU Lesser General Public License version 3,
100+ * as published by the Free Software Foundation.
101+ *
102+ * This program is distributed in the hope that it will be useful,
103+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
104+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
105+ * GNU Lesser General Public License for more details.
106+ *
107+ * You should have received a copy of the GNU Lesser General Public License
108+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
109+ *
110+ * Author: Daniel d'Andrada <daniel.dandrada@canonical.com>
111+ */
112+
113+#ifndef ANDROID_INTSET_H
114+#define ANDROID_INTSET_H
115+
116+#include <assert.h>
117+
118+// C++ std lib
119+#include <algorithm>
120+#include <sstream>
121+#include <set>
122+
123+#ifdef ANDROID_INPUT_INTSET_TEST
124+namespace test {
125+#endif
126+
127+namespace android {
128+
129+/*
130+ A set of integers
131+
132+ It serves two purposes:
133+ - Provide a convenience wrapper for std::set<int32_t>. Because the std API is cumbersome.
134+ - Provide an API similar to the BitSet32 class that it's replacing.
135+ */
136+class IntSet {
137+public:
138+
139+#ifdef ANDROID_INPUT_INTSET_TEST
140+ static int constructionCount;
141+ static int destructionCount;
142+#endif
143+
144+ IntSet();
145+ IntSet(std::initializer_list<int32_t> list);
146+ virtual ~IntSet();
147+
148+ IntSet operator -(const IntSet &other) const;
149+ IntSet operator &(const IntSet &other) const;
150+ bool operator ==(const IntSet &other) const;
151+
152+ std::set<int32_t>::iterator begin() { return stdSet.begin(); }
153+ std::set<int32_t>::const_iterator begin() const { return stdSet.begin(); }
154+ std::set<int32_t>::iterator end() { return stdSet.end(); }
155+ std::set<int32_t>::const_iterator end() const { return stdSet.end(); }
156+ std::set<int32_t>::const_iterator cbegin() const { return stdSet.cbegin(); }
157+ std::set<int32_t>::const_iterator cend() const { return stdSet.cend(); }
158+
159+ void clear() { stdSet.clear(); }
160+ void insert(int32_t value) { stdSet.insert(value); }
161+
162+ template<typename Func>
163+ void forEach(Func func) { std::for_each(stdSet.begin(), stdSet.end(), func); }
164+
165+ template<typename Func>
166+ void forEach(Func func) const { std::for_each(stdSet.begin(), stdSet.end(), func); }
167+
168+ void remove(int32_t value) { stdSet.erase(value); }
169+ void remove(const IntSet &values);
170+
171+ size_t size() const { return stdSet.size(); }
172+ size_t count() const { return stdSet.size(); }
173+
174+ bool isEmpty() const { return stdSet.empty(); }
175+
176+ bool contains(int32_t value) const;
177+
178+ int32_t first() const { return *stdSet.cbegin(); }
179+
180+ // It's assumed that the given value does exist in the set
181+ size_t indexOf(int32_t value) const;
182+
183+ std::string toString() const;
184+
185+private:
186+ void remove(std::set<int32_t>::iterator selfIterator,
187+ std::set<int32_t>::const_iterator otherIterator,
188+ std::set<int32_t>::const_iterator otherEnd);
189+ std::set<int32_t> stdSet;
190+};
191+
192+} // namespace android
193+
194+#ifdef ANDROID_INPUT_INTSET_TEST
195+} // namespace test
196+#endif
197+
198+#endif
199
200=== modified file '3rd_party/android-input/android/frameworks/base/include/androidfw/VelocityControl.h'
201--- 3rd_party/android-input/android/frameworks/base/include/androidfw/VelocityControl.h 2013-05-03 16:38:07 +0000
202+++ 3rd_party/android-input/android/frameworks/base/include/androidfw/VelocityControl.h 2013-11-25 03:07:43 +0000
203@@ -19,6 +19,7 @@
204
205
206 #include <androidfw/Input.h>
207+#include <androidfw/IntSet.h>
208 #include <androidfw/VelocityTracker.h>
209 #include <std/Timers.h>
210
211@@ -101,6 +102,7 @@
212 nsecs_t mLastMovementTime;
213 VelocityTracker::Position mRawPosition;
214 VelocityTracker mVelocityTracker;
215+ IntSet mIds;
216 };
217
218 } // namespace android
219
220=== modified file '3rd_party/android-input/android/frameworks/base/include/androidfw/VelocityTracker.h'
221--- 3rd_party/android-input/android/frameworks/base/include/androidfw/VelocityTracker.h 2013-05-03 16:38:07 +0000
222+++ 3rd_party/android-input/android/frameworks/base/include/androidfw/VelocityTracker.h 2013-11-25 03:07:43 +0000
223@@ -17,10 +17,12 @@
224 #ifndef _ANDROIDFW_VELOCITY_TRACKER_H
225 #define _ANDROIDFW_VELOCITY_TRACKER_H
226
227-
228 #include <androidfw/Input.h>
229+#include <androidfw/IntSet.h>
230 #include <std/Timers.h>
231-#include <std/BitSet.h>
232+
233+// C++ std lib
234+#include <unordered_map>
235
236 namespace android {
237
238@@ -74,14 +76,14 @@
239 // Resets the velocity tracker state for specific pointers.
240 // Call this method when some pointers have changed and may be reusing
241 // an id that was assigned to a different pointer earlier.
242- void clearPointers(BitSet32 idBits);
243+ void clearPointers(const IntSet &ids);
244
245 // Adds movement information for a set of pointers.
246- // The idBits bitfield specifies the pointer ids of the pointers whose positions
247+ // The ids set specifies the pointer ids of the pointers whose positions
248 // are included in the movement.
249 // The positions array contains position information for each pointer in order by
250- // increasing id. Its size should be equal to the number of one bits in idBits.
251- void addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions);
252+ // increasing id. Its size should be equal to the size of ids.
253+ void addMovement(nsecs_t eventTime, const IntSet &ids, const Position* positions);
254
255 // Adds movement information for all pointers in a MotionEvent, including historical samples.
256 void addMovement(const MotionEvent* event);
257@@ -100,13 +102,13 @@
258 inline int32_t getActivePointerId() const { return mActivePointerId; }
259
260 // Gets a bitset containing all pointer ids from the most recent movement.
261- inline BitSet32 getCurrentPointerIdBits() const { return mCurrentPointerIdBits; }
262+ inline const IntSet &getCurrentPointerIds() const { return mCurrentPointerIds; }
263
264 private:
265 static const char* DEFAULT_STRATEGY;
266
267 nsecs_t mLastEventTime;
268- BitSet32 mCurrentPointerIdBits;
269+ IntSet mCurrentPointerIds;
270 int32_t mActivePointerId;
271 VelocityTrackerStrategy* mStrategy;
272
273@@ -127,8 +129,8 @@
274 virtual ~VelocityTrackerStrategy() { }
275
276 virtual void clear() = 0;
277- virtual void clearPointers(BitSet32 idBits) = 0;
278- virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
279+ virtual void clearPointers(const IntSet &ids) = 0;
280+ virtual void addMovement(nsecs_t eventTime, const IntSet &ids,
281 const VelocityTracker::Position* positions) = 0;
282 virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const = 0;
283 };
284@@ -159,8 +161,8 @@
285 virtual ~LeastSquaresVelocityTrackerStrategy();
286
287 virtual void clear();
288- virtual void clearPointers(BitSet32 idBits);
289- virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
290+ virtual void clearPointers(const IntSet &ids);
291+ virtual void addMovement(nsecs_t eventTime, const IntSet &ids,
292 const VelocityTracker::Position* positions);
293 virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
294
295@@ -175,11 +177,11 @@
296
297 struct Movement {
298 nsecs_t eventTime;
299- BitSet32 idBits;
300+ IntSet ids;
301 VelocityTracker::Position positions[MAX_POINTERS];
302
303 inline const VelocityTracker::Position& getPosition(uint32_t id) const {
304- return positions[idBits.getIndexOfBit(id)];
305+ return positions[ids.indexOf(id)];
306 }
307 };
308
309@@ -202,8 +204,8 @@
310 ~IntegratingVelocityTrackerStrategy();
311
312 virtual void clear();
313- virtual void clearPointers(BitSet32 idBits);
314- virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
315+ virtual void clearPointers(const IntSet &ids);
316+ virtual void addMovement(nsecs_t eventTime, const IntSet &ids,
317 const VelocityTracker::Position* positions);
318 virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
319
320@@ -218,8 +220,8 @@
321 };
322
323 const uint32_t mDegree;
324- BitSet32 mPointerIdBits;
325- State mPointerState[MAX_POINTER_ID + 1];
326+ IntSet mPointerIds;
327+ std::unordered_map<int32_t, State> mPointerState; // maps the id of a pointer to its state
328
329 void initState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
330 void updateState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
331@@ -236,8 +238,8 @@
332 virtual ~LegacyVelocityTrackerStrategy();
333
334 virtual void clear();
335- virtual void clearPointers(BitSet32 idBits);
336- virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
337+ virtual void clearPointers(const IntSet &ids);
338+ virtual void addMovement(nsecs_t eventTime, const IntSet &ids,
339 const VelocityTracker::Position* positions);
340 virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
341
342@@ -253,11 +255,11 @@
343
344 struct Movement {
345 nsecs_t eventTime;
346- BitSet32 idBits;
347+ IntSet ids;
348 VelocityTracker::Position positions[MAX_POINTERS];
349
350 inline const VelocityTracker::Position& getPosition(uint32_t id) const {
351- return positions[idBits.getIndexOfBit(id)];
352+ return positions[ids.indexOf(id)];
353 }
354 };
355
356
357=== modified file '3rd_party/android-input/android/frameworks/base/services/input/InputDevice.cpp'
358--- 3rd_party/android-input/android/frameworks/base/services/input/InputDevice.cpp 2013-02-05 17:19:57 +0000
359+++ 3rd_party/android-input/android/frameworks/base/services/input/InputDevice.cpp 2013-11-25 03:07:43 +0000
360@@ -16,6 +16,9 @@
361
362 #define LOG_TAG "InputDevice"
363
364+#include <cutils/log.h>
365+#define DEBUG_PROBE 0
366+
367 #include <stdlib.h>
368 #include <unistd.h>
369 #include <ctype.h>
370@@ -97,7 +100,7 @@
371 path.append("/usr/");
372 appendInputDeviceConfigurationFileRelativePath(path, name, type);
373 #if DEBUG_PROBE
374- ALOGD("Probing for system provided input device configuration file: path='%s'", path.string());
375+ ALOGD("Probing for system provided input device configuration file: path='%s'", path.c_str());
376 #endif
377 if (!access(c_str(path), R_OK)) {
378 #if DEBUG_PROBE
379@@ -119,7 +122,7 @@
380 path.append("/system/devices/");
381 appendInputDeviceConfigurationFileRelativePath(path, name, type);
382 #if DEBUG_PROBE
383- ALOGD("Probing for system user input device configuration file: path='%s'", path.string());
384+ ALOGD("Probing for system user input device configuration file: path='%s'", path.c_str());
385 #endif
386 if (!access(c_str(path), R_OK)) {
387 #if DEBUG_PROBE
388@@ -131,7 +134,7 @@
389 // Not found.
390 #if DEBUG_PROBE
391 ALOGD("Probe failed to find input device configuration file: name='%s', type=%d",
392- name.string(), type);
393+ name.c_str(), type);
394 #endif
395 return String8();
396 }
397
398=== modified file '3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp'
399--- 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp 2013-08-28 03:41:48 +0000
400+++ 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp 2013-11-25 03:07:43 +0000
401@@ -152,7 +152,7 @@
402 pointerCount, MAX_POINTERS);
403 return false;
404 }
405- BitSet32 pointerIdBits;
406+ IntSet pointerIds;
407 for (size_t i = 0; i < pointerCount; i++) {
408 int32_t id = pointerProperties[i].id;
409 if (id < 0 || id > MAX_POINTER_ID) {
410@@ -160,11 +160,11 @@
411 id, MAX_POINTER_ID);
412 return false;
413 }
414- if (pointerIdBits.hasBit(id)) {
415+ if (pointerIds.contains(id)) {
416 ALOGE("Motion event has duplicate pointer id %d", id);
417 return false;
418 }
419- pointerIdBits.markBit(id);
420+ pointerIds.insert(id);
421 }
422 return true;
423 }
424@@ -1043,7 +1043,7 @@
425 // Success! Output targets.
426 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
427 addWindowTargetLocked(mFocusedWindowHandle,
428- InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
429+ InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, IntSet(),
430 inputTargets);
431
432 // Done.
433@@ -1181,7 +1181,7 @@
434 }
435
436 mTempTouchState.addOrUpdateWindow(
437- windowHandle, outsideTargetFlags, BitSet32(0));
438+ windowHandle, outsideTargetFlags, IntSet());
439 }
440 }
441 });
442@@ -1250,10 +1250,10 @@
443 }
444
445 // Update the temporary touch state.
446- BitSet32 pointerIds;
447+ IntSet pointerIds;
448 if (isSplit) {
449- uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
450- pointerIds.markBit(pointerId);
451+ int32_t pointerId = entry->pointerProperties[pointerIndex].id;
452+ pointerIds.insert(pointerId);
453 }
454 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
455 } else {
456@@ -1288,7 +1288,7 @@
457 #endif
458 // Make a slippery exit from the old window.
459 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
460- InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
461+ InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, IntSet());
462
463 // Make a slippery entrance into the new window.
464 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
465@@ -1304,9 +1304,9 @@
466 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
467 }
468
469- BitSet32 pointerIds;
470+ IntSet pointerIds;
471 if (isSplit) {
472- pointerIds.markBit(entry->pointerProperties[0].id);
473+ pointerIds.insert(entry->pointerProperties[0].id);
474 }
475 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
476 }
477@@ -1321,7 +1321,7 @@
478 c_str(mLastHoverWindowHandle->getName()));
479 #endif
480 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
481- InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
482+ InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, IntSet());
483 }
484
485 // Let the new window know that the hover sequence is starting.
486@@ -1331,7 +1331,7 @@
487 c_str(newHoverWindowHandle->getName()));
488 #endif
489 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
490- InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
491+ InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, IntSet());
492 }
493 }
494
495@@ -1375,7 +1375,7 @@
496 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
497 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
498 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
499- InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
500+ InputTarget::FLAG_ZERO_COORDS, IntSet());
501 }
502 }
503 }
504@@ -1421,7 +1421,7 @@
505 mTempTouchState.addOrUpdateWindow(windowHandle,
506 InputTarget::FLAG_WINDOW_IS_OBSCURED
507 | InputTarget::FLAG_DISPATCH_AS_IS,
508- BitSet32(0));
509+ IntSet());
510 }
511 });
512 }
513@@ -1491,12 +1491,12 @@
514 // One pointer went up.
515 if (isSplit) {
516 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
517- uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
518+ int32_t pointerId = entry->pointerProperties[pointerIndex].id;
519
520 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
521 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
522 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
523- touchedWindow.pointerIds.clearBit(pointerId);
524+ touchedWindow.pointerIds.remove(pointerId);
525 if (touchedWindow.pointerIds.isEmpty()) {
526 mTempTouchState.windows.removeAt(i);
527 continue;
528@@ -1538,7 +1538,7 @@
529 }
530
531 void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
532- int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) {
533+ int32_t targetFlags, const IntSet &pointerIds, Vector<InputTarget>& inputTargets) {
534 inputTargets.push();
535
536 const InputWindowInfo* windowInfo = windowHandle->getInfo();
537@@ -1693,12 +1693,13 @@
538 void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
539 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
540 #if DEBUG_DISPATCH_CYCLE
541+ std::string pointerIdsString = inputTarget->pointerIds.toString();
542 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
543 "xOffset=%f, yOffset=%f, scaleFactor=%f, "
544- "pointerIds=0x%x",
545+ "pointerIds=%s",
546 connection->getInputChannelName(), inputTarget->flags,
547 inputTarget->xOffset, inputTarget->yOffset,
548- inputTarget->scaleFactor, inputTarget->pointerIds.value);
549+ inputTarget->scaleFactor, pointerIdsString.c_str());
550 #endif
551
552 // Skip this event if the connection status is not normal.
553@@ -2163,8 +2164,8 @@
554 }
555
556 InputDispatcher::MotionEntry*
557-InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
558- ALOG_ASSERT(pointerIds.value != 0);
559+InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, const IntSet &pointerIds) {
560+ ALOG_ASSERT(!pointerIds.isEmpty());
561
562 uint32_t splitPointerIndexMap[MAX_POINTERS];
563 PointerProperties splitPointerProperties[MAX_POINTERS];
564@@ -2178,7 +2179,7 @@
565 const PointerProperties& pointerProperties =
566 originalMotionEntry->pointerProperties[originalPointerIndex];
567 uint32_t pointerId = uint32_t(pointerProperties.id);
568- if (pointerIds.hasBit(pointerId)) {
569+ if (pointerIds.contains(pointerId)) {
570 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
571 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
572 splitPointerCoords[splitPointerCount].copyFrom(
573@@ -2207,8 +2208,8 @@
574 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
575 const PointerProperties& pointerProperties =
576 originalMotionEntry->pointerProperties[originalPointerIndex];
577- uint32_t pointerId = uint32_t(pointerProperties.id);
578- if (pointerIds.hasBit(pointerId)) {
579+ int32_t pointerId = pointerProperties.id;
580+ if (pointerIds.contains(pointerId)) {
581 if (pointerIds.count() == 1) {
582 // The first/last pointer went down/up.
583 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
584@@ -2216,7 +2217,7 @@
585 } else {
586 // A secondary pointer went down/up.
587 uint32_t splitPointerIndex = 0;
588- while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
589+ while (pointerId != splitPointerProperties[splitPointerIndex].id) {
590 splitPointerIndex += 1;
591 }
592 action = maskedAction | (splitPointerIndex
593@@ -2901,7 +2902,7 @@
594 const TouchedWindow& touchedWindow = mTouchState.windows[i];
595 if (touchedWindow.windowHandle == fromWindowHandle) {
596 int32_t oldTargetFlags = touchedWindow.targetFlags;
597- BitSet32 pointerIds = touchedWindow.pointerIds;
598+ IntSet pointerIds = touchedWindow.pointerIds;
599
600 mTouchState.windows.removeAt(i);
601
602@@ -3000,10 +3001,14 @@
603 dump.append(INDENT "TouchedWindows:\n");
604 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
605 const TouchedWindow& touchedWindow = mTouchState.windows[i];
606- appendFormat(dump, INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
607- i, c_str(touchedWindow.windowHandle->getName()),
608- touchedWindow.pointerIds.value,
609- touchedWindow.targetFlags);
610+ appendFormat(dump, INDENT2 "%d: name='%s'",
611+ i, c_str(touchedWindow.windowHandle->getName()));
612+
613+ dump.append(", pointerIds=(");
614+ touchedWindow.pointerIds.forEach([&](int32_t id) {appendFormat(dump, ", %d", id);});
615+ dump.append(")");
616+
617+ appendFormat(dump, ", targetFlags=0x%x\n", touchedWindow.targetFlags);
618 }
619 } else {
620 dump.append(INDENT "TouchedWindows: <none>\n");
621@@ -4191,7 +4196,7 @@
622 }
623
624 void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
625- int32_t targetFlags, BitSet32 pointerIds) {
626+ int32_t targetFlags, const IntSet &pointerIds) {
627 if (targetFlags & InputTarget::FLAG_SPLIT) {
628 split = true;
629 }
630@@ -4203,7 +4208,9 @@
631 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
632 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
633 }
634- touchedWindow.pointerIds.value |= pointerIds.value;
635+ pointerIds.forEach([&](int32_t id) {
636+ touchedWindow.pointerIds.insert(id);
637+ });
638 return;
639 }
640 }
641
642=== modified file '3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.h'
643--- 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.h 2013-05-30 19:24:29 +0000
644+++ 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.h 2013-11-25 03:07:43 +0000
645@@ -19,13 +19,13 @@
646
647 #include <androidfw/Input.h>
648 #include <androidfw/InputTransport.h>
649+#include <androidfw/IntSet.h>
650 #include <std/KeyedVector.h>
651 #include <std/Vector.h>
652 #include <std/Timers.h>
653 #include <std/RefBase.h>
654 #include <std/String8.h>
655 #include <std/Looper.h>
656-#include <std/BitSet.h>
657 #include <std/atomic.h>
658 #include <std/Condition.h>
659 #include <std/Thread.h>
660@@ -169,7 +169,7 @@
661
662 // The subset of pointer ids to include in motion events dispatched to this input target
663 // if FLAG_SPLIT is set.
664- BitSet32 pointerIds;
665+ IntSet pointerIds;
666 };
667
668
669@@ -953,7 +953,7 @@
670 struct TouchedWindow {
671 sp<InputWindowHandle> windowHandle;
672 int32_t targetFlags;
673- BitSet32 pointerIds; // zero unless target flag FLAG_SPLIT is set
674+ IntSet pointerIds; // empty unless target flag FLAG_SPLIT is set
675 };
676 struct TouchState {
677 bool down;
678@@ -967,7 +967,7 @@
679 void reset();
680 void copyFrom(const TouchState& other);
681 void addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
682- int32_t targetFlags, BitSet32 pointerIds);
683+ int32_t targetFlags, const IntSet &pointerIds);
684 void removeWindow(const sp<InputWindowHandle>& windowHandle);
685 void filterNonAsIsTouchWindows();
686 sp<InputWindowHandle> getFirstForegroundWindowHandle() const;
687@@ -1033,7 +1033,7 @@
688 bool* outConflictingPointerActions);
689
690 void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
691- int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets);
692+ int32_t targetFlags, const IntSet &pointerIds, Vector<InputTarget>& inputTargets);
693 void addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets);
694
695 bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
696@@ -1072,7 +1072,7 @@
697 const CancelationOptions& options);
698
699 // Splitting motion events across windows.
700- MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds);
701+ MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, const IntSet &pointerIds);
702
703 // Reset and drop everything the dispatcher is doing.
704 void resetAndDropEverythingLocked(const char* reason);
705
706=== added file '3rd_party/android-input/android/frameworks/base/services/input/InputEventPrinter.h'
707--- 3rd_party/android-input/android/frameworks/base/services/input/InputEventPrinter.h 1970-01-01 00:00:00 +0000
708+++ 3rd_party/android-input/android/frameworks/base/services/input/InputEventPrinter.h 2013-11-25 03:07:43 +0000
709@@ -0,0 +1,138 @@
710+/*
711+ * Copyright © 2013 Canonical Ltd.
712+ *
713+ * This program is free software: you can redistribute it and/or modify it
714+ * under the terms of the GNU Lesser General Public License version 3,
715+ * as published by the Free Software Foundation.
716+ *
717+ * This program is distributed in the hope that it will be useful,
718+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
719+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
720+ * GNU Lesser General Public License for more details.
721+ *
722+ * You should have received a copy of the GNU Lesser General Public License
723+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
724+ *
725+ * Author: Daniel d'Andrada <daniel.dandrada@canonical.com>
726+ */
727+
728+#ifndef INPUT_EVENT_PRINTER_H
729+#define INPUT_EVENT_PRINTER_H
730+
731+#include <stdio.h>
732+
733+void synEvCodeToStr(char *codeStr, int code) {
734+ switch(code) {
735+ case SYN_REPORT:
736+ sprintf(codeStr, "SYN_REPORT");
737+ break;
738+ case SYN_CONFIG:
739+ sprintf(codeStr, "SYN_CONFIG");
740+ break;
741+ case SYN_MT_REPORT:
742+ sprintf(codeStr, "SYN_MT_REPORT");
743+ break;
744+ case SYN_DROPPED:
745+ sprintf(codeStr, "SYN_DROPPED");
746+ break;
747+ default:
748+ sprintf(codeStr, "0x%08x", code);
749+ break;
750+ }
751+}
752+
753+void absEvCodeToStr(char *codeStr, int code) {
754+ switch(code) {
755+ case ABS_X:
756+ sprintf(codeStr, "ABS_X");
757+ break;
758+ case ABS_Y:
759+ sprintf(codeStr, "ABS_Y");
760+ break;
761+ case ABS_MT_TOUCH_MAJOR:
762+ sprintf(codeStr, "ABS_MT_TOUCH_MAJOR");
763+ break;
764+ case ABS_MT_TOUCH_MINOR:
765+ sprintf(codeStr, "ABS_MT_TOUCH_MINOR");
766+ break;
767+ case ABS_MT_ORIENTATION:
768+ sprintf(codeStr, "ABS_MT_ORIENTATION");
769+ break;
770+ case ABS_MT_POSITION_X:
771+ sprintf(codeStr, "ABS_MT_POSITION_X");
772+ break;
773+ case ABS_MT_POSITION_Y:
774+ sprintf(codeStr, "ABS_MT_POSITION_Y");
775+ break;
776+ case ABS_MT_TOOL_TYPE:
777+ sprintf(codeStr, "ABS_MT_TOOL_TYPE");
778+ break;
779+ default:
780+ sprintf(codeStr, "0x%08x", code);
781+ break;
782+ }
783+}
784+
785+void keyEvCodeToStr(char *codeStr, int code) {
786+ switch(code) {
787+ case BTN_TOUCH:
788+ sprintf(codeStr, "BTN_TOUCH");
789+ break;
790+ case BTN_STYLUS:
791+ sprintf(codeStr, "BTN_STYLUS");
792+ break;
793+ default:
794+ sprintf(codeStr, "0x%08x", code);
795+ break;
796+ }
797+}
798+
799+void inputEvToStr(char *buffer, int type, int code, int value) {
800+ char codeStr[100];
801+ switch (type) {
802+ case EV_SYN:
803+ synEvCodeToStr(codeStr, code);
804+ sprintf(buffer, "EV_SYN, %s, 0x%08x", codeStr, value);
805+ break;
806+ case EV_KEY:
807+ keyEvCodeToStr(codeStr, code);
808+ sprintf(buffer, "EV_KEY, %s, 0x%08x", codeStr, value);
809+ break;
810+ case EV_REL:
811+ sprintf(buffer, "EV_REL, 0x%08x, 0x%08x", code, value);
812+ break;
813+ case EV_ABS:
814+ absEvCodeToStr(codeStr, code);
815+ sprintf(buffer, "EV_ABS, %s, 0x%08x", codeStr, value);
816+ break;
817+ case EV_MSC:
818+ sprintf(buffer, "EV_MSC, 0x%08x, 0x%08x", code, value);
819+ break;
820+ case EV_SW:
821+ sprintf(buffer, "EV_SW, 0x%08x, 0x%08x", code, value);
822+ break;
823+ case EV_LED:
824+ sprintf(buffer, "EV_LED, 0x%08x, 0x%08x", code, value);
825+ break;
826+ case EV_SND:
827+ sprintf(buffer, "EV_SND, 0x%08x, 0x%08x", code, value);
828+ break;
829+ case EV_REP:
830+ sprintf(buffer, "EV_REP, 0x%08x, 0x%08x", code, value);
831+ break;
832+ case EV_FF:
833+ sprintf(buffer, "EV_FF, 0x%08x, 0x%08x", code, value);
834+ break;
835+ case EV_PWR:
836+ sprintf(buffer, "EV_PWR, 0x%08x, 0x%08x", code, value);
837+ break;
838+ case EV_FF_STATUS:
839+ sprintf(buffer, "EV_FF_STATUS, 0x%08x, 0x%08x", code, value);
840+ break;
841+ default:
842+ sprintf(buffer, "0x%08x, 0x%08x, 0x%08x", type, code, value);
843+ break;
844+ }
845+}
846+
847+#endif // INPUT_EVENT_PRINTER_H
848
849=== modified file '3rd_party/android-input/android/frameworks/base/services/input/InputListener.h'
850--- 3rd_party/android-input/android/frameworks/base/services/input/InputListener.h 2013-05-03 16:38:07 +0000
851+++ 3rd_party/android-input/android/frameworks/base/services/input/InputListener.h 2013-11-25 03:07:43 +0000
852@@ -38,7 +38,7 @@
853 struct NotifyConfigurationChangedArgs : public NotifyArgs {
854 nsecs_t eventTime;
855
856- inline NotifyConfigurationChangedArgs() { }
857+ inline NotifyConfigurationChangedArgs() : eventTime{0} { }
858
859 NotifyConfigurationChangedArgs(nsecs_t eventTime);
860
861
862=== modified file '3rd_party/android-input/android/frameworks/base/services/input/InputReader.cpp'
863--- 3rd_party/android-input/android/frameworks/base/services/input/InputReader.cpp 2013-10-15 08:53:10 +0000
864+++ 3rd_party/android-input/android/frameworks/base/services/input/InputReader.cpp 2013-11-25 03:07:43 +0000
865@@ -47,6 +47,8 @@
866
867 #include <android/keycodes.h>
868
869+#include <std/BitSet.h>
870+
871 #include <stddef.h>
872 #include <stdlib.h>
873 #include <unistd.h>
874@@ -54,6 +56,10 @@
875 #include <limits.h>
876 #include <math.h>
877
878+#if DEBUG_RAW_EVENTS
879+#include "InputEventPrinter.h"
880+#endif
881+
882 #define INDENT " "
883 #define INDENT2 " "
884 #define INDENT3 " "
885@@ -339,7 +345,7 @@
886 batchSize += 1;
887 }
888 #if DEBUG_RAW_EVENTS
889- ALOGD("BatchSize: %d Count: %d", batchSize, count);
890+ ALOGD("BatchSize: %zu Count: %zu", batchSize, count);
891 #endif
892 processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
893 } else {
894@@ -974,8 +980,9 @@
895 size_t numMappers = mMappers.size();
896 for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
897 #if DEBUG_RAW_EVENTS
898- ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x",
899- rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value);
900+ char inputStr[200];
901+ inputEvToStr(inputStr, rawEvent->type, rawEvent->code, rawEvent->value);
902+ ALOGD("Input event: device=%d %s", rawEvent->deviceId, inputStr);
903 #endif
904
905 if (mDropUntilNextSync) {
906@@ -1434,32 +1441,31 @@
907
908 void RawPointerData::clear() {
909 pointerCount = 0;
910- clearIdBits();
911+ clearIds();
912 }
913
914 void RawPointerData::copyFrom(const RawPointerData& other) {
915 pointerCount = other.pointerCount;
916- hoveringIdBits = other.hoveringIdBits;
917- touchingIdBits = other.touchingIdBits;
918+ hoveringIds = other.hoveringIds;
919+ touchingIds = other.touchingIds;
920
921 for (uint32_t i = 0; i < pointerCount; i++) {
922 pointers[i] = other.pointers[i];
923
924 int id = pointers[i].id;
925- idToIndex[id] = other.idToIndex[id];
926 }
927 }
928
929 void RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const {
930 float x = 0, y = 0;
931- uint32_t count = touchingIdBits.count();
932+
933+ uint32_t count = touchingIds.count();
934 if (count) {
935- for (BitSet32 idBits(touchingIdBits); !idBits.isEmpty(); ) {
936- uint32_t id = idBits.clearFirstMarkedBit();
937+ touchingIds.forEach([&](int32_t id) {
938 const Pointer& pointer = pointerForId(id);
939 x += pointer.x;
940 y += pointer.y;
941- }
942+ });
943 x /= count;
944 y /= count;
945 }
946@@ -1476,21 +1482,18 @@
947
948 void CookedPointerData::clear() {
949 pointerCount = 0;
950- hoveringIdBits.clear();
951- touchingIdBits.clear();
952+ hoveringIds.clear();
953+ touchingIds.clear();
954 }
955
956 void CookedPointerData::copyFrom(const CookedPointerData& other) {
957 pointerCount = other.pointerCount;
958- hoveringIdBits = other.hoveringIdBits;
959- touchingIdBits = other.touchingIdBits;
960+ hoveringIds = other.hoveringIds;
961+ touchingIds = other.touchingIds;
962
963 for (uint32_t i = 0; i < pointerCount; i++) {
964 pointerProperties[i].copyFrom(other.pointerProperties[i]);
965 pointerCoords[i].copyFrom(other.pointerCoords[i]);
966-
967- int id = pointerProperties[i].id;
968- idToIndex[id] = other.idToIndex[id];
969 }
970 }
971
972@@ -2554,7 +2557,8 @@
973 InputMapper(device),
974 mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
975 mSurfaceOrientation(-1), mSurfaceWidth(-1), mSurfaceHeight(-1),
976- mPointerUsage(POINTER_USAGE_NONE) {
977+ mPointerUsage(POINTER_USAGE_NONE),
978+ mNextNewPointerId(0) {
979 }
980
981 TouchInputMapper::~TouchInputMapper() {
982@@ -3499,12 +3503,12 @@
983 mLastButtonState = 0;
984 mCurrentRawVScroll = 0;
985 mCurrentRawHScroll = 0;
986- mCurrentFingerIdBits.clear();
987- mLastFingerIdBits.clear();
988- mCurrentStylusIdBits.clear();
989- mLastStylusIdBits.clear();
990- mCurrentMouseIdBits.clear();
991- mLastMouseIdBits.clear();
992+ mCurrentFingerIds.clear();
993+ mLastFingerIds.clear();
994+ mCurrentStylusIds.clear();
995+ mLastStylusIds.clear();
996+ mCurrentMouseIds.clear();
997+ mLastMouseIds.clear();
998 mPointerUsage = POINTER_USAGE_NONE;
999 mSentHoverEnter = false;
1000 mDownTime = 0;
1001@@ -3553,21 +3557,25 @@
1002 mLastRawPointerData.pointerCount,
1003 mCurrentRawPointerData.pointerCount);
1004 } else {
1005- ALOGD("syncTouch: pointerCount %d -> %d, touching ids 0x%08x -> 0x%08x, "
1006- "hovering ids 0x%08x -> 0x%08x",
1007+ std::string lastTouchingIdsString = mLastRawPointerData.touchingIds.toString();
1008+ std::string currentTouchingIdsString = mCurrentRawPointerData.touchingIds.toString();
1009+ std::string lastHoveringIdsString = mLastRawPointerData.hoveringIds.toString();
1010+ std::string currentHoveringIdsString = mCurrentRawPointerData.hoveringIds.toString();
1011+ ALOGD("syncTouch: pointerCount %u -> %u, touching ids (%s) -> (%s), "
1012+ "hovering ids (%s) -> (%s)",
1013 mLastRawPointerData.pointerCount,
1014 mCurrentRawPointerData.pointerCount,
1015- mLastRawPointerData.touchingIdBits.value,
1016- mCurrentRawPointerData.touchingIdBits.value,
1017- mLastRawPointerData.hoveringIdBits.value,
1018- mCurrentRawPointerData.hoveringIdBits.value);
1019+ lastTouchingIdsString.c_str(),
1020+ currentTouchingIdsString.c_str(),
1021+ lastHoveringIdsString.c_str(),
1022+ currentHoveringIdsString.c_str());
1023 }
1024 #endif
1025
1026 // Reset state that we will compute below.
1027- mCurrentFingerIdBits.clear();
1028- mCurrentStylusIdBits.clear();
1029- mCurrentMouseIdBits.clear();
1030+ mCurrentFingerIds.clear();
1031+ mCurrentStylusIds.clear();
1032+ mCurrentMouseIds.clear();
1033 mCurrentCookedPointerData.clear();
1034
1035 if (mDeviceMode == DEVICE_MODE_DISABLED) {
1036@@ -3617,38 +3625,36 @@
1037
1038 // Dispatch the touches either directly or by translation through a pointer on screen.
1039 if (mDeviceMode == DEVICE_MODE_POINTER) {
1040- for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); ) {
1041- uint32_t id = idBits.clearFirstMarkedBit();
1042- const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
1043+ for (uint32_t i = 0; i < mCurrentRawPointerData.pointerCount; ++i) {
1044+ const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointers[i];
1045 if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
1046 || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
1047- mCurrentStylusIdBits.markBit(id);
1048+ mCurrentStylusIds.insert(pointer.id);
1049 } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
1050 || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
1051- mCurrentFingerIdBits.markBit(id);
1052+ mCurrentFingerIds.insert(pointer.id);
1053 } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_MOUSE) {
1054- mCurrentMouseIdBits.markBit(id);
1055+ mCurrentMouseIds.insert(pointer.id);
1056 }
1057 }
1058- for (BitSet32 idBits(mCurrentRawPointerData.hoveringIdBits); !idBits.isEmpty(); ) {
1059- uint32_t id = idBits.clearFirstMarkedBit();
1060+ mCurrentRawPointerData.hoveringIds.forEach([&](int32_t id) {
1061 const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
1062 if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
1063 || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
1064- mCurrentStylusIdBits.markBit(id);
1065+ mCurrentStylusIds.insert(id);
1066 }
1067- }
1068+ });
1069
1070 // Stylus takes precedence over all tools, then mouse, then finger.
1071 PointerUsage pointerUsage = mPointerUsage;
1072- if (!mCurrentStylusIdBits.isEmpty()) {
1073- mCurrentMouseIdBits.clear();
1074- mCurrentFingerIdBits.clear();
1075+ if (!mCurrentStylusIds.isEmpty()) {
1076+ mCurrentMouseIds.clear();
1077+ mCurrentFingerIds.clear();
1078 pointerUsage = POINTER_USAGE_STYLUS;
1079- } else if (!mCurrentMouseIdBits.isEmpty()) {
1080- mCurrentFingerIdBits.clear();
1081+ } else if (!mCurrentMouseIds.isEmpty()) {
1082+ mCurrentFingerIds.clear();
1083 pointerUsage = POINTER_USAGE_MOUSE;
1084- } else if (!mCurrentFingerIdBits.isEmpty() || isPointerDown(mCurrentButtonState)) {
1085+ } else if (!mCurrentFingerIds.isEmpty() || isPointerDown(mCurrentButtonState)) {
1086 pointerUsage = POINTER_USAGE_GESTURES;
1087 }
1088
1089@@ -3661,8 +3667,7 @@
1090
1091 mPointerController->setButtonState(mCurrentButtonState);
1092 mPointerController->setSpots(mCurrentCookedPointerData.pointerCoords,
1093- mCurrentCookedPointerData.idToIndex,
1094- mCurrentCookedPointerData.touchingIdBits);
1095+ mCurrentCookedPointerData.pointerCount);
1096 }
1097
1098 dispatchHoverExit(when, policyFlags);
1099@@ -3679,9 +3684,9 @@
1100 mLastRawPointerData.copyFrom(mCurrentRawPointerData);
1101 mLastCookedPointerData.copyFrom(mCurrentCookedPointerData);
1102 mLastButtonState = mCurrentButtonState;
1103- mLastFingerIdBits = mCurrentFingerIdBits;
1104- mLastStylusIdBits = mCurrentStylusIdBits;
1105- mLastMouseIdBits = mCurrentMouseIdBits;
1106+ mLastFingerIds = mCurrentFingerIds;
1107+ mLastStylusIds = mCurrentStylusIds;
1108+ mLastMouseIds = mCurrentMouseIds;
1109
1110 // Clear some transient state.
1111 mCurrentRawVScroll = 0;
1112@@ -3699,7 +3704,7 @@
1113 bool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
1114 // Check for release of a virtual key.
1115 if (mCurrentVirtualKey.down) {
1116- if (mCurrentRawPointerData.touchingIdBits.isEmpty()) {
1117+ if (mCurrentRawPointerData.touchingIds.isEmpty()) {
1118 // Pointer went up while virtual key was down.
1119 mCurrentVirtualKey.down = false;
1120 if (!mCurrentVirtualKey.ignored) {
1121@@ -3714,8 +3719,8 @@
1122 return true;
1123 }
1124
1125- if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
1126- uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
1127+ if (mCurrentRawPointerData.touchingIds.count() == 1) {
1128+ int32_t id = mCurrentRawPointerData.touchingIds.first();
1129 const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
1130 const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
1131 if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
1132@@ -3741,15 +3746,15 @@
1133 }
1134 }
1135
1136- if (mLastRawPointerData.touchingIdBits.isEmpty()
1137- && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
1138+ if (mLastRawPointerData.touchingIds.isEmpty()
1139+ && !mCurrentRawPointerData.touchingIds.isEmpty()) {
1140 // Pointer just went down. Check for virtual key press or off-screen touches.
1141- uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
1142+ int32_t id = mCurrentRawPointerData.touchingIds.first();
1143 const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
1144 if (!isPointInsideSurface(pointer.x, pointer.y)) {
1145 // If exactly one pointer went down, check for virtual key hit.
1146 // Otherwise we will drop the entire stroke.
1147- if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
1148+ if (mCurrentRawPointerData.touchingIds.count() == 1) {
1149 const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
1150 if (virtualKey) {
1151 mCurrentVirtualKey.down = true;
1152@@ -3789,7 +3794,7 @@
1153 // area and accidentally triggers a virtual key. This often happens when virtual keys
1154 // are layed out below the screen near to where the on screen keyboard's space bar
1155 // is displayed.
1156- if (mConfig.virtualKeyQuietTime > 0 && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
1157+ if (mConfig.virtualKeyQuietTime > 0 && !mCurrentRawPointerData.touchingIds.isEmpty()) {
1158 mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
1159 }
1160 return false;
1161@@ -3809,13 +3814,13 @@
1162 }
1163
1164 void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
1165- BitSet32 currentIdBits = mCurrentCookedPointerData.touchingIdBits;
1166- BitSet32 lastIdBits = mLastCookedPointerData.touchingIdBits;
1167+ IntSet &currentIds = mCurrentCookedPointerData.touchingIds;
1168+ IntSet &lastIds = mLastCookedPointerData.touchingIds;
1169 int32_t metaState = getContext()->getGlobalMetaState();
1170 int32_t buttonState = mCurrentButtonState;
1171
1172- if (currentIdBits == lastIdBits) {
1173- if (!currentIdBits.isEmpty()) {
1174+ if (currentIds == lastIds) {
1175+ if (!currentIds.isEmpty()) {
1176 // No pointer id changes so this is a move event.
1177 // The listener takes care of batching moves so we don't have to deal with that here.
1178 dispatchMotion(when, policyFlags, mSource,
1179@@ -3823,66 +3828,63 @@
1180 AMOTION_EVENT_EDGE_FLAG_NONE,
1181 mCurrentCookedPointerData.pointerProperties,
1182 mCurrentCookedPointerData.pointerCoords,
1183- mCurrentCookedPointerData.idToIndex,
1184- currentIdBits, -1,
1185+ mCurrentCookedPointerData.pointerCount,
1186+ currentIds, -1,
1187 mOrientedXPrecision, mOrientedYPrecision, mDownTime);
1188 }
1189 } else {
1190 // There may be pointers going up and pointers going down and pointers moving
1191 // all at the same time.
1192- BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value);
1193- BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
1194- BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
1195- BitSet32 dispatchedIdBits(lastIdBits.value);
1196+ IntSet upIds = lastIds - currentIds;
1197+ IntSet downIds = currentIds - lastIds;
1198+ IntSet moveIds = lastIds & currentIds;
1199+ IntSet dispatchedIds = lastIds;
1200
1201 // Update last coordinates of pointers that have moved so that we observe the new
1202 // pointer positions at the same time as other pointers that have just gone up.
1203 bool moveNeeded = updateMovedPointers(
1204 mCurrentCookedPointerData.pointerProperties,
1205 mCurrentCookedPointerData.pointerCoords,
1206- mCurrentCookedPointerData.idToIndex,
1207+ mCurrentCookedPointerData.pointerCount,
1208 mLastCookedPointerData.pointerProperties,
1209 mLastCookedPointerData.pointerCoords,
1210- mLastCookedPointerData.idToIndex,
1211- moveIdBits);
1212+ mLastCookedPointerData.pointerCount,
1213+ moveIds);
1214 if (buttonState != mLastButtonState) {
1215 moveNeeded = true;
1216 }
1217
1218 // Dispatch pointer up events.
1219- while (!upIdBits.isEmpty()) {
1220- uint32_t upId = upIdBits.clearFirstMarkedBit();
1221-
1222+ upIds.forEach([&](int32_t upId) {
1223 dispatchMotion(when, policyFlags, mSource,
1224 AMOTION_EVENT_ACTION_POINTER_UP, 0, metaState, buttonState, 0,
1225 mLastCookedPointerData.pointerProperties,
1226 mLastCookedPointerData.pointerCoords,
1227- mLastCookedPointerData.idToIndex,
1228- dispatchedIdBits, upId,
1229+ mLastCookedPointerData.pointerCount,
1230+ dispatchedIds, upId,
1231 mOrientedXPrecision, mOrientedYPrecision, mDownTime);
1232- dispatchedIdBits.clearBit(upId);
1233- }
1234+ dispatchedIds.remove(upId);
1235+ });
1236
1237 // Dispatch move events if any of the remaining pointers moved from their old locations.
1238 // Although applications receive new locations as part of individual pointer up
1239 // events, they do not generally handle them except when presented in a move event.
1240 if (moveNeeded) {
1241- ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
1242+ ALOG_ASSERT(moveIds == dispatchedIds);
1243 dispatchMotion(when, policyFlags, mSource,
1244 AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0,
1245 mCurrentCookedPointerData.pointerProperties,
1246 mCurrentCookedPointerData.pointerCoords,
1247- mCurrentCookedPointerData.idToIndex,
1248- dispatchedIdBits, -1,
1249+ mCurrentCookedPointerData.pointerCount,
1250+ dispatchedIds, -1,
1251 mOrientedXPrecision, mOrientedYPrecision, mDownTime);
1252 }
1253
1254 // Dispatch pointer down events using the new pointer locations.
1255- while (!downIdBits.isEmpty()) {
1256- uint32_t downId = downIdBits.clearFirstMarkedBit();
1257- dispatchedIdBits.markBit(downId);
1258+ downIds.forEach([&](int32_t downId) {
1259+ dispatchedIds.insert(downId);
1260
1261- if (dispatchedIdBits.count() == 1) {
1262+ if (dispatchedIds.count() == 1) {
1263 // First pointer is going down. Set down time.
1264 mDownTime = when;
1265 }
1266@@ -3891,40 +3893,40 @@
1267 AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
1268 mCurrentCookedPointerData.pointerProperties,
1269 mCurrentCookedPointerData.pointerCoords,
1270- mCurrentCookedPointerData.idToIndex,
1271- dispatchedIdBits, downId,
1272+ mCurrentCookedPointerData.pointerCount,
1273+ dispatchedIds, downId,
1274 mOrientedXPrecision, mOrientedYPrecision, mDownTime);
1275- }
1276+ });
1277 }
1278 }
1279
1280 void TouchInputMapper::dispatchHoverExit(nsecs_t when, uint32_t policyFlags) {
1281 if (mSentHoverEnter &&
1282- (mCurrentCookedPointerData.hoveringIdBits.isEmpty()
1283- || !mCurrentCookedPointerData.touchingIdBits.isEmpty())) {
1284+ (mCurrentCookedPointerData.hoveringIds.isEmpty()
1285+ || !mCurrentCookedPointerData.touchingIds.isEmpty())) {
1286 int32_t metaState = getContext()->getGlobalMetaState();
1287 dispatchMotion(when, policyFlags, mSource,
1288 AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
1289 mLastCookedPointerData.pointerProperties,
1290 mLastCookedPointerData.pointerCoords,
1291- mLastCookedPointerData.idToIndex,
1292- mLastCookedPointerData.hoveringIdBits, -1,
1293+ mLastCookedPointerData.pointerCount,
1294+ mLastCookedPointerData.hoveringIds, -1,
1295 mOrientedXPrecision, mOrientedYPrecision, mDownTime);
1296 mSentHoverEnter = false;
1297 }
1298 }
1299
1300 void TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags) {
1301- if (mCurrentCookedPointerData.touchingIdBits.isEmpty()
1302- && !mCurrentCookedPointerData.hoveringIdBits.isEmpty()) {
1303+ if (mCurrentCookedPointerData.touchingIds.isEmpty()
1304+ && !mCurrentCookedPointerData.hoveringIds.isEmpty()) {
1305 int32_t metaState = getContext()->getGlobalMetaState();
1306 if (!mSentHoverEnter) {
1307 dispatchMotion(when, policyFlags, mSource,
1308 AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
1309 mCurrentCookedPointerData.pointerProperties,
1310 mCurrentCookedPointerData.pointerCoords,
1311- mCurrentCookedPointerData.idToIndex,
1312- mCurrentCookedPointerData.hoveringIdBits, -1,
1313+ mCurrentCookedPointerData.pointerCount,
1314+ mCurrentCookedPointerData.hoveringIds, -1,
1315 mOrientedXPrecision, mOrientedYPrecision, mDownTime);
1316 mSentHoverEnter = true;
1317 }
1318@@ -3933,8 +3935,8 @@
1319 AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
1320 mCurrentCookedPointerData.pointerProperties,
1321 mCurrentCookedPointerData.pointerCoords,
1322- mCurrentCookedPointerData.idToIndex,
1323- mCurrentCookedPointerData.hoveringIdBits, -1,
1324+ mCurrentCookedPointerData.pointerCount,
1325+ mCurrentCookedPointerData.hoveringIds, -1,
1326 mOrientedXPrecision, mOrientedYPrecision, mDownTime);
1327 }
1328 }
1329@@ -3944,8 +3946,8 @@
1330
1331 mCurrentCookedPointerData.clear();
1332 mCurrentCookedPointerData.pointerCount = currentPointerCount;
1333- mCurrentCookedPointerData.hoveringIdBits = mCurrentRawPointerData.hoveringIdBits;
1334- mCurrentCookedPointerData.touchingIdBits = mCurrentRawPointerData.touchingIdBits;
1335+ mCurrentCookedPointerData.hoveringIds = mCurrentRawPointerData.hoveringIds;
1336+ mCurrentCookedPointerData.touchingIds = mCurrentRawPointerData.touchingIds;
1337
1338 // Walk through the the active pointers and map device coordinates onto
1339 // surface coordinates and adjust for display orientation.
1340@@ -3988,7 +3990,7 @@
1341 }
1342
1343 if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) {
1344- uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count();
1345+ uint32_t touchingCount = mCurrentRawPointerData.touchingIds.count();
1346 if (touchingCount > 1) {
1347 touchMajor /= touchingCount;
1348 touchMinor /= touchingCount;
1349@@ -4137,9 +4139,6 @@
1350 properties.clear();
1351 properties.id = id;
1352 properties.toolType = in.toolType;
1353-
1354- // Write id index.
1355- mCurrentCookedPointerData.idToIndex[id] = i;
1356 }
1357 }
1358
1359@@ -4203,8 +4202,7 @@
1360 mPointerController->clearSpots();
1361 }
1362 mPointerController->setSpots(mPointerGesture.currentGestureCoords,
1363- mPointerGesture.currentGestureIdToIndex,
1364- mPointerGesture.currentGestureIdBits);
1365+ mPointerGesture.currentGestureIds.count());
1366 } else {
1367 mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
1368 }
1369@@ -4255,54 +4253,52 @@
1370 || mPointerGesture.currentGestureMode == PointerGesture::FREEFORM;
1371 bool moveNeeded = false;
1372 if (down && !cancelPreviousGesture && !finishPreviousGesture
1373- && !mPointerGesture.lastGestureIdBits.isEmpty()
1374- && !mPointerGesture.currentGestureIdBits.isEmpty()) {
1375- BitSet32 movedGestureIdBits(mPointerGesture.currentGestureIdBits.value
1376- & mPointerGesture.lastGestureIdBits.value);
1377+ && !(mPointerGesture.lastGestureIds.isEmpty())
1378+ && !(mPointerGesture.currentGestureIds.isEmpty())) {
1379+ IntSet movedGestureIds = mPointerGesture.currentGestureIds & mPointerGesture.lastGestureIds;
1380 moveNeeded = updateMovedPointers(mPointerGesture.currentGestureProperties,
1381- mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
1382+ mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIds.count(),
1383 mPointerGesture.lastGestureProperties,
1384- mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
1385- movedGestureIdBits);
1386+ mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIds.count(),
1387+ movedGestureIds);
1388 if (buttonState != mLastButtonState) {
1389 moveNeeded = true;
1390 }
1391 }
1392
1393 // Send motion events for all pointers that went up or were canceled.
1394- BitSet32 dispatchedGestureIdBits(mPointerGesture.lastGestureIdBits);
1395- if (!dispatchedGestureIdBits.isEmpty()) {
1396+ IntSet dispatchedGestureIds = mPointerGesture.lastGestureIds;
1397+ if (!dispatchedGestureIds.isEmpty()) {
1398 if (cancelPreviousGesture) {
1399 dispatchMotion(when, policyFlags, mSource,
1400 AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
1401 AMOTION_EVENT_EDGE_FLAG_NONE,
1402 mPointerGesture.lastGestureProperties,
1403- mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
1404- dispatchedGestureIdBits, -1,
1405+ mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIds.count(),
1406+ dispatchedGestureIds, -1,
1407 0, 0, mPointerGesture.downTime);
1408
1409- dispatchedGestureIdBits.clear();
1410+ dispatchedGestureIds.clear();
1411 } else {
1412- BitSet32 upGestureIdBits;
1413+ IntSet upGestureIds;
1414 if (finishPreviousGesture) {
1415- upGestureIdBits = dispatchedGestureIdBits;
1416+ upGestureIds = dispatchedGestureIds;
1417 } else {
1418- upGestureIdBits.value = dispatchedGestureIdBits.value
1419- & ~mPointerGesture.currentGestureIdBits.value;
1420+ upGestureIds = dispatchedGestureIds - mPointerGesture.currentGestureIds;
1421 }
1422- while (!upGestureIdBits.isEmpty()) {
1423- uint32_t id = upGestureIdBits.clearFirstMarkedBit();
1424+
1425+ upGestureIds.forEach([&](int32_t upId) {
1426
1427 dispatchMotion(when, policyFlags, mSource,
1428 AMOTION_EVENT_ACTION_POINTER_UP, 0,
1429 metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
1430 mPointerGesture.lastGestureProperties,
1431- mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
1432- dispatchedGestureIdBits, id,
1433+ mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIds.count(),
1434+ dispatchedGestureIds, upId,
1435 0, 0, mPointerGesture.downTime);
1436
1437- dispatchedGestureIdBits.clearBit(id);
1438- }
1439+ dispatchedGestureIds.remove(upId);
1440+ });
1441 }
1442 }
1443
1444@@ -4311,30 +4307,29 @@
1445 dispatchMotion(when, policyFlags, mSource,
1446 AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
1447 mPointerGesture.currentGestureProperties,
1448- mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
1449- dispatchedGestureIdBits, -1,
1450+ mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIds.count(),
1451+ dispatchedGestureIds, -1,
1452 0, 0, mPointerGesture.downTime);
1453 }
1454
1455 // Send motion events for all pointers that went down.
1456 if (down) {
1457- BitSet32 downGestureIdBits(mPointerGesture.currentGestureIdBits.value
1458- & ~dispatchedGestureIdBits.value);
1459- while (!downGestureIdBits.isEmpty()) {
1460- uint32_t id = downGestureIdBits.clearFirstMarkedBit();
1461- dispatchedGestureIdBits.markBit(id);
1462-
1463- if (dispatchedGestureIdBits.count() == 1) {
1464+ IntSet downGestureIds = mPointerGesture.currentGestureIds - dispatchedGestureIds;
1465+
1466+ downGestureIds.forEach([&](int32_t downId) {
1467+ dispatchedGestureIds.insert(downId);
1468+
1469+ if (dispatchedGestureIds.size() == 1) {
1470 mPointerGesture.downTime = when;
1471 }
1472
1473 dispatchMotion(when, policyFlags, mSource,
1474 AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
1475 mPointerGesture.currentGestureProperties,
1476- mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
1477- dispatchedGestureIdBits, id,
1478+ mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIds.count(),
1479+ dispatchedGestureIds, downId,
1480 0, 0, mPointerGesture.downTime);
1481- }
1482+ });
1483 }
1484
1485 // Send motion events for hover.
1486@@ -4343,11 +4338,11 @@
1487 AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
1488 metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
1489 mPointerGesture.currentGestureProperties,
1490- mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
1491- mPointerGesture.currentGestureIdBits, -1,
1492+ mPointerGesture.currentGestureCoords,
1493+ mPointerGesture.currentGestureIds.count(), -1,
1494 0, 0, mPointerGesture.downTime);
1495- } else if (dispatchedGestureIdBits.isEmpty()
1496- && !mPointerGesture.lastGestureIdBits.isEmpty()) {
1497+ } else if (dispatchedGestureIds.isEmpty()
1498+ && !mPointerGesture.lastGestureIds.isEmpty()) {
1499 // Synthesize a hover move event after all pointers go up to indicate that
1500 // the pointer is hovering again even if the user is not currently touching
1501 // the touch pad. This ensures that a view will receive a fresh hover enter
1502@@ -4375,32 +4370,29 @@
1503 // Update state.
1504 mPointerGesture.lastGestureMode = mPointerGesture.currentGestureMode;
1505 if (!down) {
1506- mPointerGesture.lastGestureIdBits.clear();
1507+ mPointerGesture.lastGestureIds.clear();
1508 } else {
1509- mPointerGesture.lastGestureIdBits = mPointerGesture.currentGestureIdBits;
1510- for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) {
1511- uint32_t id = idBits.clearFirstMarkedBit();
1512- uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
1513+ mPointerGesture.lastGestureIds = mPointerGesture.currentGestureIds;
1514+ mPointerGesture.lastGestureIdToIndex = mPointerGesture.currentGestureIdToIndex;
1515+ for (uint32_t index = 0; index < mPointerGesture.currentGestureIds.count(); ++index) {
1516 mPointerGesture.lastGestureProperties[index].copyFrom(
1517 mPointerGesture.currentGestureProperties[index]);
1518 mPointerGesture.lastGestureCoords[index].copyFrom(
1519 mPointerGesture.currentGestureCoords[index]);
1520- mPointerGesture.lastGestureIdToIndex[id] = index;
1521 }
1522 }
1523 }
1524
1525 void TouchInputMapper::abortPointerGestures(nsecs_t when, uint32_t policyFlags) {
1526 // Cancel previously dispatches pointers.
1527- if (!mPointerGesture.lastGestureIdBits.isEmpty()) {
1528+ if (!mPointerGesture.lastGestureIds.isEmpty()) {
1529 int32_t metaState = getContext()->getGlobalMetaState();
1530 int32_t buttonState = mCurrentButtonState;
1531 dispatchMotion(when, policyFlags, mSource,
1532 AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
1533 AMOTION_EVENT_EDGE_FLAG_NONE,
1534 mPointerGesture.lastGestureProperties,
1535- mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
1536- mPointerGesture.lastGestureIdBits, -1,
1537+ mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIds.count(), -1,
1538 0, 0, mPointerGesture.downTime);
1539 }
1540
1541@@ -4440,7 +4432,7 @@
1542
1543 mPointerGesture.activeGestureId = -1;
1544 mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
1545- mPointerGesture.currentGestureIdBits.clear();
1546+ mPointerGesture.currentGestureIds.clear();
1547
1548 mPointerVelocityControl.reset();
1549 return true;
1550@@ -4451,21 +4443,20 @@
1551 return false;
1552 }
1553
1554- const uint32_t currentFingerCount = mCurrentFingerIdBits.count();
1555- const uint32_t lastFingerCount = mLastFingerIdBits.count();
1556+ const uint32_t currentFingerCount = mCurrentFingerIds.size();
1557+ const uint32_t lastFingerCount = mLastFingerIds.size();
1558
1559 // Update the velocity tracker.
1560 {
1561 VelocityTracker::Position positions[MAX_POINTERS];
1562 uint32_t count = 0;
1563- for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); count++) {
1564- uint32_t id = idBits.clearFirstMarkedBit();
1565+ mCurrentFingerIds.forEach([&](int32_t id) {
1566 const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
1567 positions[count].x = pointer.x * mPointerXMovementScale;
1568 positions[count].y = pointer.y * mPointerYMovementScale;
1569- }
1570- mPointerGesture.velocityTracker.addMovement(when,
1571- mCurrentFingerIdBits, positions);
1572+ count++;
1573+ });
1574+ mPointerGesture.velocityTracker.addMovement(when, mCurrentFingerIds, positions);
1575 }
1576
1577 // Pick a new active touch id if needed.
1578@@ -4477,17 +4468,17 @@
1579 int32_t lastActiveTouchId = mPointerGesture.activeTouchId;
1580 int32_t activeTouchId = lastActiveTouchId;
1581 if (activeTouchId < 0) {
1582- if (!mCurrentFingerIdBits.isEmpty()) {
1583+ if (!mCurrentFingerIds.isEmpty()) {
1584 activeTouchChanged = true;
1585 activeTouchId = mPointerGesture.activeTouchId =
1586- mCurrentFingerIdBits.firstMarkedBit();
1587+ mCurrentFingerIds.first();
1588 mPointerGesture.firstTouchTime = when;
1589 }
1590- } else if (!mCurrentFingerIdBits.hasBit(activeTouchId)) {
1591+ } else if (!mCurrentFingerIds.contains(activeTouchId)) {
1592 activeTouchChanged = true;
1593- if (!mCurrentFingerIdBits.isEmpty()) {
1594+ if (!mCurrentFingerIds.isEmpty()) {
1595 activeTouchId = mPointerGesture.activeTouchId =
1596- mCurrentFingerIdBits.firstMarkedBit();
1597+ mCurrentFingerIds.first();
1598 } else {
1599 activeTouchId = mPointerGesture.activeTouchId = -1;
1600 }
1601@@ -4535,7 +4526,7 @@
1602
1603 mPointerGesture.activeGestureId = -1;
1604 mPointerGesture.currentGestureMode = PointerGesture::QUIET;
1605- mPointerGesture.currentGestureIdBits.clear();
1606+ mPointerGesture.currentGestureIds.clear();
1607
1608 mPointerVelocityControl.reset();
1609 } else if (isPointerDown(mCurrentButtonState)) {
1610@@ -4567,8 +4558,7 @@
1611 if (activeTouchId >= 0 && currentFingerCount > 1) {
1612 int32_t bestId = -1;
1613 float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed;
1614- for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); ) {
1615- uint32_t id = idBits.clearFirstMarkedBit();
1616+ mCurrentFingerIds.forEach([&](int32_t id) {
1617 float vx, vy;
1618 if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
1619 float speed = hypotf(vx, vy);
1620@@ -4577,7 +4567,7 @@
1621 bestSpeed = speed;
1622 }
1623 }
1624- }
1625+ });
1626 if (bestId >= 0 && bestId != activeTouchId) {
1627 mPointerGesture.activeTouchId = activeTouchId = bestId;
1628 activeTouchChanged = true;
1629@@ -4588,7 +4578,7 @@
1630 }
1631 }
1632
1633- if (activeTouchId >= 0 && mLastFingerIdBits.hasBit(activeTouchId)) {
1634+ if (activeTouchId >= 0 && mLastFingerIds.contains(activeTouchId)) {
1635 const RawPointerData::Pointer& currentPointer =
1636 mCurrentRawPointerData.pointerForId(activeTouchId);
1637 const RawPointerData::Pointer& lastPointer =
1638@@ -4611,9 +4601,8 @@
1639 mPointerController->getPosition(&x, &y);
1640
1641 mPointerGesture.currentGestureMode = PointerGesture::BUTTON_CLICK_OR_DRAG;
1642- mPointerGesture.currentGestureIdBits.clear();
1643- mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
1644- mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
1645+ mPointerGesture.currentGestureIds.clear();
1646+ mPointerGesture.currentGestureIds.insert(mPointerGesture.activeGestureId);
1647 mPointerGesture.currentGestureProperties[0].clear();
1648 mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
1649 mPointerGesture.currentGestureProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
1650@@ -4648,11 +4637,9 @@
1651
1652 mPointerGesture.activeGestureId = 0;
1653 mPointerGesture.currentGestureMode = PointerGesture::TAP;
1654- mPointerGesture.currentGestureIdBits.clear();
1655- mPointerGesture.currentGestureIdBits.markBit(
1656+ mPointerGesture.currentGestureIds.clear();
1657+ mPointerGesture.currentGestureIds.insert(
1658 mPointerGesture.activeGestureId);
1659- mPointerGesture.currentGestureIdToIndex[
1660- mPointerGesture.activeGestureId] = 0;
1661 mPointerGesture.currentGestureProperties[0].clear();
1662 mPointerGesture.currentGestureProperties[0].id =
1663 mPointerGesture.activeGestureId;
1664@@ -4690,7 +4677,7 @@
1665 #endif
1666 mPointerGesture.activeGestureId = -1;
1667 mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
1668- mPointerGesture.currentGestureIdBits.clear();
1669+ mPointerGesture.currentGestureIds.clear();
1670 }
1671 } else if (currentFingerCount == 1) {
1672 // Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
1673@@ -4724,7 +4711,7 @@
1674 mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
1675 }
1676
1677- if (mLastFingerIdBits.hasBit(activeTouchId)) {
1678+ if (mLastFingerIds.contains(activeTouchId)) {
1679 const RawPointerData::Pointer& currentPointer =
1680 mCurrentRawPointerData.pointerForId(activeTouchId);
1681 const RawPointerData::Pointer& lastPointer =
1682@@ -4764,9 +4751,8 @@
1683 float x, y;
1684 mPointerController->getPosition(&x, &y);
1685
1686- mPointerGesture.currentGestureIdBits.clear();
1687- mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
1688- mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
1689+ mPointerGesture.currentGestureIds.clear();
1690+ mPointerGesture.currentGestureIds.insert(mPointerGesture.activeGestureId);
1691 mPointerGesture.currentGestureProperties[0].clear();
1692 mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
1693 mPointerGesture.currentGestureProperties[0].toolType =
1694@@ -4823,7 +4809,7 @@
1695 if (*outFinishPreviousGesture || *outCancelPreviousGesture) {
1696 mPointerGesture.currentGestureMode = PointerGesture::PRESS;
1697 mPointerGesture.activeGestureId = 0;
1698- mPointerGesture.referenceIdBits.clear();
1699+ mPointerGesture.referenceIds.clear();
1700 mPointerVelocityControl.reset();
1701
1702 // Use the centroid and pointer location as the reference points for the gesture.
1703@@ -4841,21 +4827,18 @@
1704 }
1705
1706 // Clear the reference deltas for fingers not yet included in the reference calculation.
1707- for (BitSet32 idBits(mCurrentFingerIdBits.value
1708- & ~mPointerGesture.referenceIdBits.value); !idBits.isEmpty(); ) {
1709- uint32_t id = idBits.clearFirstMarkedBit();
1710+ (mCurrentFingerIds - mPointerGesture.referenceIds).forEach([&](int32_t id) {
1711 mPointerGesture.referenceDeltas[id].dx = 0;
1712 mPointerGesture.referenceDeltas[id].dy = 0;
1713- }
1714- mPointerGesture.referenceIdBits = mCurrentFingerIdBits;
1715+ });
1716+ mPointerGesture.referenceIds = mCurrentFingerIds;
1717
1718 // Add delta for all fingers and calculate a common movement delta.
1719 float commonDeltaX = 0, commonDeltaY = 0;
1720- BitSet32 commonIdBits(mLastFingerIdBits.value
1721- & mCurrentFingerIdBits.value);
1722- for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
1723- bool first = (idBits == commonIdBits);
1724- uint32_t id = idBits.clearFirstMarkedBit();
1725+ IntSet commonIds = mLastFingerIds & mCurrentFingerIds;
1726+
1727+ bool first = true;
1728+ commonIds.forEach([&](int32_t id) {
1729 const RawPointerData::Pointer& cpd = mCurrentRawPointerData.pointerForId(id);
1730 const RawPointerData::Pointer& lpd = mLastRawPointerData.pointerForId(id);
1731 PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
1732@@ -4865,25 +4848,25 @@
1733 if (first) {
1734 commonDeltaX = delta.dx;
1735 commonDeltaY = delta.dy;
1736+ first = false;
1737 } else {
1738 commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx);
1739 commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy);
1740 }
1741- }
1742+ });
1743
1744 // Consider transitions from PRESS to SWIPE or MULTITOUCH.
1745 if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) {
1746- float dist[MAX_POINTER_ID + 1];
1747+ std::unordered_map<int32_t, float> dist;
1748 int32_t distOverThreshold = 0;
1749- for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
1750- uint32_t id = idBits.clearFirstMarkedBit();
1751+ mPointerGesture.referenceIds.forEach([&](int32_t id) {
1752 PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
1753 dist[id] = hypotf(delta.dx * mPointerXZoomScale,
1754 delta.dy * mPointerYZoomScale);
1755 if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) {
1756 distOverThreshold += 1;
1757 }
1758- }
1759+ });
1760
1761 // Only transition when at least two pointers have moved further than
1762 // the minimum distance threshold.
1763@@ -4898,9 +4881,14 @@
1764 mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
1765 } else {
1766 // There are exactly two pointers.
1767- BitSet32 idBits(mCurrentFingerIdBits);
1768- uint32_t id1 = idBits.clearFirstMarkedBit();
1769- uint32_t id2 = idBits.firstMarkedBit();
1770+ int32_t id1;
1771+ int32_t id2;
1772+ {
1773+ auto currentFingerIdsIt = mCurrentFingerIds.cbegin();
1774+ id1 = *currentFingerIdsIt;
1775+ ++currentFingerIdsIt;
1776+ id2 = *currentFingerIdsIt;
1777+ }
1778 const RawPointerData::Pointer& p1 = mCurrentRawPointerData.pointerForId(id1);
1779 const RawPointerData::Pointer& p2 = mCurrentRawPointerData.pointerForId(id2);
1780 float mutualDistance = distance(p1.x, p1.y, p2.x, p2.y);
1781@@ -4977,12 +4965,11 @@
1782 // except in PRESS mode while waiting for a transition to occur.
1783 if (mPointerGesture.currentGestureMode != PointerGesture::PRESS
1784 && (commonDeltaX || commonDeltaY)) {
1785- for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
1786- uint32_t id = idBits.clearFirstMarkedBit();
1787+ mPointerGesture.referenceIds.forEach([&](int32_t id) {
1788 PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
1789 delta.dx = 0;
1790 delta.dy = 0;
1791- }
1792+ });
1793
1794 mPointerGesture.referenceTouchX += commonDeltaX;
1795 mPointerGesture.referenceTouchY += commonDeltaY;
1796@@ -5008,9 +4995,8 @@
1797 #endif
1798 ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
1799
1800- mPointerGesture.currentGestureIdBits.clear();
1801- mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
1802- mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
1803+ mPointerGesture.currentGestureIds.clear();
1804+ mPointerGesture.currentGestureIds.insert(mPointerGesture.activeGestureId);
1805 mPointerGesture.currentGestureProperties[0].clear();
1806 mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
1807 mPointerGesture.currentGestureProperties[0].toolType =
1808@@ -5030,16 +5016,16 @@
1809 #endif
1810 ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
1811
1812- mPointerGesture.currentGestureIdBits.clear();
1813+ mPointerGesture.currentGestureIds.clear();
1814
1815- BitSet32 mappedTouchIdBits;
1816- BitSet32 usedGestureIdBits;
1817+ IntSet mappedTouchIds;
1818+ IntSet usedGestureIds;
1819 if (mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
1820 // Initially, assign the active gesture id to the active touch point
1821 // if there is one. No other touch id bits are mapped yet.
1822 if (!*outCancelPreviousGesture) {
1823- mappedTouchIdBits.markBit(activeTouchId);
1824- usedGestureIdBits.markBit(mPointerGesture.activeGestureId);
1825+ mappedTouchIds.insert(activeTouchId);
1826+ usedGestureIds.insert(mPointerGesture.activeGestureId);
1827 mPointerGesture.freeformTouchToGestureIdMap[activeTouchId] =
1828 mPointerGesture.activeGestureId;
1829 } else {
1830@@ -5048,38 +5034,41 @@
1831 } else {
1832 // Otherwise, assume we mapped all touches from the previous frame.
1833 // Reuse all mappings that are still applicable.
1834- mappedTouchIdBits.value = mLastFingerIdBits.value
1835- & mCurrentFingerIdBits.value;
1836- usedGestureIdBits = mPointerGesture.lastGestureIdBits;
1837+ mappedTouchIds = mLastFingerIds & mCurrentFingerIds;
1838+ usedGestureIds = mPointerGesture.lastGestureIds;
1839
1840 // Check whether we need to choose a new active gesture id because the
1841 // current went went up.
1842- for (BitSet32 upTouchIdBits(mLastFingerIdBits.value
1843- & ~mCurrentFingerIdBits.value);
1844- !upTouchIdBits.isEmpty(); ) {
1845- uint32_t upTouchId = upTouchIdBits.clearFirstMarkedBit();
1846- uint32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[upTouchId];
1847- if (upGestureId == uint32_t(mPointerGesture.activeGestureId)) {
1848- mPointerGesture.activeGestureId = -1;
1849- break;
1850+ auto it = mLastFingerIds.cbegin();
1851+ while (it != mLastFingerIds.cend()) {
1852+ int32_t id = *it;
1853+ if (!mCurrentFingerIds.contains(id)) {
1854+ int32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[id];
1855+ if (upGestureId == mPointerGesture.activeGestureId) {
1856+ mPointerGesture.activeGestureId = -1;
1857+ break;
1858+ }
1859 }
1860+ it++;
1861 }
1862 }
1863
1864 #if DEBUG_GESTURES
1865- ALOGD("Gestures: FREEFORM follow up "
1866- "mappedTouchIdBits=0x%08x, usedGestureIdBits=0x%08x, "
1867- "activeGestureId=%d",
1868- mappedTouchIdBits.value, usedGestureIdBits.value,
1869- mPointerGesture.activeGestureId);
1870+ {
1871+ std::string mappedTouchIdsString = mappedTouchIdBits.toString();
1872+ std::string usedGestureIdsString = usedGestureIdBits.toString();
1873+ ALOGD("Gestures: FREEFORM follow up "
1874+ "mappedTouchIds=%s, usedGestureIds=%s, "
1875+ "activeGestureId=%d",
1876+ mappedTouchIdsString.c_str(), usedGestureIdsString.c_str(),
1877+ mPointerGesture.activeGestureId);
1878+ }
1879 #endif
1880-
1881- BitSet32 idBits(mCurrentFingerIdBits);
1882- for (uint32_t i = 0; i < currentFingerCount; i++) {
1883- uint32_t touchId = idBits.clearFirstMarkedBit();
1884- uint32_t gestureId;
1885- if (!mappedTouchIdBits.hasBit(touchId)) {
1886- gestureId = usedGestureIdBits.markFirstUnmarkedBit();
1887+ uint32_t i = 0;
1888+ mCurrentFingerIds.forEach([&](int32_t touchId) {
1889+ int32_t gestureId;
1890+ if (mappedTouchIds.contains(touchId)) {
1891+ gestureId = usedGestureIds.first();
1892 mPointerGesture.freeformTouchToGestureIdMap[touchId] = gestureId;
1893 #if DEBUG_GESTURES
1894 ALOGD("Gestures: FREEFORM "
1895@@ -5094,8 +5083,7 @@
1896 touchId, gestureId);
1897 #endif
1898 }
1899- mPointerGesture.currentGestureIdBits.markBit(gestureId);
1900- mPointerGesture.currentGestureIdToIndex[gestureId] = i;
1901+ mPointerGesture.currentGestureIds.insert(gestureId);
1902
1903 const RawPointerData::Pointer& pointer =
1904 mCurrentRawPointerData.pointerForId(touchId);
1905@@ -5116,11 +5104,12 @@
1906 AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY + deltaY);
1907 mPointerGesture.currentGestureCoords[i].setAxisValue(
1908 AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
1909- }
1910+
1911+ ++i;
1912+ });
1913
1914 if (mPointerGesture.activeGestureId < 0) {
1915- mPointerGesture.activeGestureId =
1916- mPointerGesture.currentGestureIdBits.firstMarkedBit();
1917+ mPointerGesture.activeGestureId = mPointerGesture.currentGestureIds.first();
1918 #if DEBUG_GESTURES
1919 ALOGD("Gestures: FREEFORM new "
1920 "activeGestureId=%d", mPointerGesture.activeGestureId);
1921@@ -5132,35 +5121,35 @@
1922 mPointerController->setButtonState(mCurrentButtonState);
1923
1924 #if DEBUG_GESTURES
1925- ALOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
1926- "currentGestureMode=%d, currentGestureIdBits=0x%08x, "
1927- "lastGestureMode=%d, lastGestureIdBits=0x%08x",
1928- toString(*outFinishPreviousGesture), toString(*outCancelPreviousGesture),
1929- mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIdBits.value,
1930- mPointerGesture.lastGestureMode, mPointerGesture.lastGestureIdBits.value);
1931- for (BitSet32 idBits = mPointerGesture.currentGestureIdBits; !idBits.isEmpty(); ) {
1932- uint32_t id = idBits.clearFirstMarkedBit();
1933- uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
1934- const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
1935- const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
1936- ALOGD(" currentGesture[%d]: index=%d, toolType=%d, "
1937- "x=%0.3f, y=%0.3f, pressure=%0.3f",
1938- id, index, properties.toolType,
1939- coords.getAxisValue(AMOTION_EVENT_AXIS_X),
1940- coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
1941- coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
1942- }
1943- for (BitSet32 idBits = mPointerGesture.lastGestureIdBits; !idBits.isEmpty(); ) {
1944- uint32_t id = idBits.clearFirstMarkedBit();
1945- uint32_t index = mPointerGesture.lastGestureIdToIndex[id];
1946- const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
1947- const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
1948- ALOGD(" lastGesture[%d]: index=%d, toolType=%d, "
1949- "x=%0.3f, y=%0.3f, pressure=%0.3f",
1950- id, index, properties.toolType,
1951- coords.getAxisValue(AMOTION_EVENT_AXIS_X),
1952- coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
1953- coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
1954+ {
1955+ std::string lastGestureIdsString = mPointerGesture.lastGestureIds.toString();
1956+
1957+ ALOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
1958+ "currentGestureMode=%d, currentGestureIds.count()=%u, "
1959+ "lastGestureMode=%d, lastGestureIds=%s",
1960+ toString(*outFinishPreviousGesture), toString(*outCancelPreviousGesture),
1961+ mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIds.count(),
1962+ mPointerGesture.lastGestureMode, lastGestureIdsString.c_str());
1963+ for (uint32_t index = 0; index < mPointerGesture.currentGestureIds.count(); ++index) {
1964+ const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
1965+ const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
1966+ ALOGD(" currentGesture[%d]: index=%d, toolType=%d, "
1967+ "x=%0.3f, y=%0.3f, pressure=%0.3f",
1968+ id, index, properties.toolType,
1969+ coords.getAxisValue(AMOTION_EVENT_AXIS_X),
1970+ coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
1971+ coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
1972+ }
1973+ for (uint32_t index = 0; index < mPointerGesture.lastGestureIds.count(); ++index) {
1974+ const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
1975+ const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
1976+ ALOGD(" lastGesture[%d]: index=%d, toolType=%d, "
1977+ "x=%0.3f, y=%0.3f, pressure=%0.3f",
1978+ id, index, properties.toolType,
1979+ coords.getAxisValue(AMOTION_EVENT_AXIS_X),
1980+ coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
1981+ coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
1982+ }
1983 }
1984 #endif
1985 return true;
1986@@ -5171,14 +5160,14 @@
1987 mPointerSimple.currentProperties.clear();
1988
1989 bool down, hovering;
1990- if (!mCurrentStylusIdBits.isEmpty()) {
1991- uint32_t id = mCurrentStylusIdBits.firstMarkedBit();
1992- uint32_t index = mCurrentCookedPointerData.idToIndex[id];
1993+ if (!mCurrentStylusIds.isEmpty()) {
1994+ int32_t id = mCurrentStylusIds.first();
1995+ uint32_t index = mCurrentCookedPointerData.idToIndex(id);
1996 float x = mCurrentCookedPointerData.pointerCoords[index].getX();
1997 float y = mCurrentCookedPointerData.pointerCoords[index].getY();
1998 mPointerController->setPosition(x, y);
1999
2000- hovering = mCurrentCookedPointerData.hoveringIdBits.hasBit(id);
2001+ hovering = mCurrentCookedPointerData.hoveringIds.contains(id);
2002 down = !hovering;
2003
2004 mPointerController->getPosition(&x, &y);
2005@@ -5205,11 +5194,11 @@
2006 mPointerSimple.currentProperties.clear();
2007
2008 bool down, hovering;
2009- if (!mCurrentMouseIdBits.isEmpty()) {
2010- uint32_t id = mCurrentMouseIdBits.firstMarkedBit();
2011- uint32_t currentIndex = mCurrentRawPointerData.idToIndex[id];
2012- if (mLastMouseIdBits.hasBit(id)) {
2013- uint32_t lastIndex = mCurrentRawPointerData.idToIndex[id];
2014+ if (!mCurrentMouseIds.isEmpty()) {
2015+ uint32_t id = mCurrentMouseIds.first();
2016+ uint32_t currentIndex = mCurrentRawPointerData.idToIndex(id);
2017+ if (mLastMouseIds.contains(id)) {
2018+ uint32_t lastIndex = mCurrentRawPointerData.idToIndex(id);
2019 float deltaX = (mCurrentRawPointerData.pointers[currentIndex].x
2020 - mLastRawPointerData.pointers[lastIndex].x)
2021 * mPointerXMovementScale;
2022@@ -5377,19 +5366,17 @@
2023
2024 void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
2025 int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
2026- const PointerProperties* properties, const PointerCoords* coords,
2027- const uint32_t* idToIndex, BitSet32 idBits,
2028+ const PointerProperties* properties, const PointerCoords* coords, uint32_t inPointerCount,
2029 int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime) {
2030 PointerCoords pointerCoords[MAX_POINTERS];
2031 PointerProperties pointerProperties[MAX_POINTERS];
2032 uint32_t pointerCount = 0;
2033- while (!idBits.isEmpty()) {
2034- uint32_t id = idBits.clearFirstMarkedBit();
2035- uint32_t index = idToIndex[id];
2036- pointerProperties[pointerCount].copyFrom(properties[index]);
2037- pointerCoords[pointerCount].copyFrom(coords[index]);
2038-
2039- if (changedId >= 0 && id == uint32_t(changedId)) {
2040+
2041+ while (pointerCount < inPointerCount) {
2042+ pointerProperties[pointerCount].copyFrom(properties[pointerCount]);
2043+ pointerCoords[pointerCount].copyFrom(coords[pointerCount]);
2044+
2045+ if (changedId >= 0 && properties[pointerCount].id == uint32_t(changedId)) {
2046 action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
2047 }
2048
2049@@ -5418,31 +5405,94 @@
2050 getListener()->notifyMotion(&args);
2051 }
2052
2053+void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
2054+ int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
2055+ const PointerProperties* properties, const PointerCoords* coords,
2056+ uint32_t inPointerCount, const IntSet &idsToDispatch,
2057+ int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime) {
2058+ PointerCoords pointerCoords[MAX_POINTERS];
2059+ PointerProperties pointerProperties[MAX_POINTERS];
2060+ uint32_t pointerCount = 0;
2061+
2062+ for (uint32_t i = 0; i < inPointerCount && pointerCount < idsToDispatch.size(); ++i) {
2063+ if (!idsToDispatch.contains(properties[i].id))
2064+ continue;
2065+
2066+ pointerProperties[pointerCount].copyFrom(properties[i]);
2067+ pointerCoords[pointerCount].copyFrom(coords[i]);
2068+
2069+ if (changedId >= 0 && properties[i].id == uint32_t(changedId)) {
2070+ action |= i << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
2071+ }
2072+
2073+ pointerCount += 1;
2074+ }
2075+
2076+ ALOG_ASSERT(pointerCount != 0);
2077+
2078+ if (changedId >= 0 && pointerCount == 1) {
2079+ // Remove the poiter index part
2080+ int actionPart = action & AMOTION_EVENT_ACTION_MASK;
2081+
2082+ // Replace initial down and final up action.
2083+ // We can compare the action without masking off the changed pointer index
2084+ // because we know the index is 0.
2085+ if (actionPart == AMOTION_EVENT_ACTION_POINTER_DOWN) {
2086+ actionPart = AMOTION_EVENT_ACTION_DOWN;
2087+ } else if (actionPart & AMOTION_EVENT_ACTION_POINTER_UP) {
2088+ actionPart = AMOTION_EVENT_ACTION_UP;
2089+ } else {
2090+ // Can't happen.
2091+ ALOG_ASSERT(false);
2092+ }
2093+
2094+ // And put it back into the action integer
2095+ action = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) | actionPart;
2096+ }
2097+
2098+ NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
2099+ action, flags, metaState, buttonState, edgeFlags,
2100+ pointerCount, pointerProperties, pointerCoords, xPrecision, yPrecision, downTime);
2101+ getListener()->notifyMotion(&args);
2102+}
2103+
2104 bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties,
2105- const PointerCoords* inCoords, const uint32_t* inIdToIndex,
2106- PointerProperties* outProperties, PointerCoords* outCoords, const uint32_t* outIdToIndex,
2107- BitSet32 idBits) const {
2108+ const PointerCoords* inCoords, uint32_t inPointerCount,
2109+ PointerProperties* outProperties, PointerCoords* outCoords, uint32_t outPointerCount,
2110+ const IntSet &commonTouchingIds) const {
2111 bool changed = false;
2112- while (!idBits.isEmpty()) {
2113- uint32_t id = idBits.clearFirstMarkedBit();
2114- uint32_t inIndex = inIdToIndex[id];
2115- uint32_t outIndex = outIdToIndex[id];
2116-
2117- const PointerProperties& curInProperties = inProperties[inIndex];
2118- const PointerCoords& curInCoords = inCoords[inIndex];
2119- PointerProperties& curOutProperties = outProperties[outIndex];
2120- PointerCoords& curOutCoords = outCoords[outIndex];
2121-
2122- if (curInProperties != curOutProperties) {
2123- curOutProperties.copyFrom(curInProperties);
2124- changed = true;
2125- }
2126-
2127- if (curInCoords != curOutCoords) {
2128- curOutCoords.copyFrom(curInCoords);
2129- changed = true;
2130- }
2131- }
2132+
2133+ if (commonTouchingIds.isEmpty()) {
2134+ return changed;
2135+ }
2136+
2137+ for (uint32_t inIndex = 0; inIndex < inPointerCount; ++inIndex) {
2138+ int32_t inId = inProperties[inIndex].id;
2139+ if (!commonTouchingIds.contains(inId)) {
2140+ continue;
2141+ }
2142+ for (uint32_t outIndex = 0; outIndex < outPointerCount; ++outIndex) {
2143+ int32_t outId = outProperties[outIndex].id;
2144+ if (inId == outId) {
2145+ // The pointer is present in both sets. Let's see if it has moved.
2146+ const PointerProperties& curInProperties = inProperties[inIndex];
2147+ const PointerCoords& curInCoords = inCoords[inIndex];
2148+ PointerProperties& curOutProperties = outProperties[outIndex];
2149+ PointerCoords& curOutCoords = outCoords[outIndex];
2150+
2151+ if (curInProperties != curOutProperties) {
2152+ curOutProperties.copyFrom(curInProperties);
2153+ changed = true;
2154+ }
2155+
2156+ if (curInCoords != curOutCoords) {
2157+ curOutCoords.copyFrom(curInCoords);
2158+ changed = true;
2159+ }
2160+ }
2161+ }
2162+ }
2163+
2164 return changed;
2165 }
2166
2167@@ -5484,7 +5534,7 @@
2168 uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
2169 uint32_t lastPointerCount = mLastRawPointerData.pointerCount;
2170
2171- mCurrentRawPointerData.clearIdBits();
2172+ mCurrentRawPointerData.clearIds();
2173
2174 if (currentPointerCount == 0) {
2175 // No pointers to assign.
2176@@ -5494,10 +5544,9 @@
2177 if (lastPointerCount == 0) {
2178 // All pointers are new.
2179 for (uint32_t i = 0; i < currentPointerCount; i++) {
2180- uint32_t id = i;
2181+ int32_t id = fetchNewPointerId();
2182 mCurrentRawPointerData.pointers[i].id = id;
2183- mCurrentRawPointerData.idToIndex[id] = i;
2184- mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(i));
2185+ mCurrentRawPointerData.insertId(id, mCurrentRawPointerData.isHovering(i));
2186 }
2187 return;
2188 }
2189@@ -5506,10 +5555,9 @@
2190 && mCurrentRawPointerData.pointers[0].toolType
2191 == mLastRawPointerData.pointers[0].toolType) {
2192 // Only one pointer and no change in count so it must have the same id as before.
2193- uint32_t id = mLastRawPointerData.pointers[0].id;
2194+ int32_t id = mLastRawPointerData.pointers[0].id;
2195 mCurrentRawPointerData.pointers[0].id = id;
2196- mCurrentRawPointerData.idToIndex[id] = 0;
2197- mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(0));
2198+ mCurrentRawPointerData.insertId(id, mCurrentRawPointerData.isHovering(0));
2199 return;
2200 }
2201
2202@@ -5569,9 +5617,9 @@
2203 }
2204
2205 #if DEBUG_POINTER_ASSIGNMENT
2206- ALOGD("assignPointerIds - initial distance min-heap: size=%d", heapSize);
2207+ ALOGD("assignPointerIds - initial distance min-heap: size=%u", heapSize);
2208 for (size_t i = 0; i < heapSize; i++) {
2209- ALOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
2210+ ALOGD(" heap[%d]: cur=%u, last=%u, distance=%llu",
2211 i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
2212 heap[i].distance);
2213 }
2214@@ -5580,10 +5628,8 @@
2215 // Pull matches out by increasing order of distance.
2216 // To avoid reassigning pointers that have already been matched, the loop keeps track
2217 // of which last and current pointers have been matched using the matchedXXXBits variables.
2218- // It also tracks the used pointer id bits.
2219 BitSet32 matchedLastBits(0);
2220 BitSet32 matchedCurrentBits(0);
2221- BitSet32 usedIdBits(0);
2222 bool first = true;
2223 for (uint32_t i = min(currentPointerCount, lastPointerCount); heapSize > 0 && i > 0; i--) {
2224 while (heapSize > 0) {
2225@@ -5635,12 +5681,9 @@
2226 matchedCurrentBits.markBit(currentPointerIndex);
2227 matchedLastBits.markBit(lastPointerIndex);
2228
2229- uint32_t id = mLastRawPointerData.pointers[lastPointerIndex].id;
2230+ int32_t id = mLastRawPointerData.pointers[lastPointerIndex].id;
2231 mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
2232- mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
2233- mCurrentRawPointerData.markIdBit(id,
2234- mCurrentRawPointerData.isHovering(currentPointerIndex));
2235- usedIdBits.markBit(id);
2236+ mCurrentRawPointerData.insertId(id, mCurrentRawPointerData.isHovering(currentPointerIndex));
2237
2238 #if DEBUG_POINTER_ASSIGNMENT
2239 ALOGD("assignPointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
2240@@ -5653,11 +5696,10 @@
2241 // Assign fresh ids to pointers that were not matched in the process.
2242 for (uint32_t i = currentPointerCount - matchedCurrentBits.count(); i != 0; i--) {
2243 uint32_t currentPointerIndex = matchedCurrentBits.markFirstUnmarkedBit();
2244- uint32_t id = usedIdBits.markFirstUnmarkedBit();
2245+ int32_t id = fetchNewPointerId();
2246
2247 mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
2248- mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
2249- mCurrentRawPointerData.markIdBit(id,
2250+ mCurrentRawPointerData.insertId(id,
2251 mCurrentRawPointerData.isHovering(currentPointerIndex));
2252
2253 #if DEBUG_POINTER_ASSIGNMENT
2254@@ -5667,6 +5709,14 @@
2255 }
2256 }
2257
2258+int32_t TouchInputMapper::fetchNewPointerId() {
2259+ int32_t id = mNextNewPointerId++;
2260+ if (mNextNewPointerId > MAX_POINTER_ID) {
2261+ mNextNewPointerId = 0;
2262+ }
2263+ return id;
2264+}
2265+
2266 int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
2267 if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
2268 return AKEY_STATE_VIRTUAL;
2269@@ -5740,16 +5790,21 @@
2270 void SingleTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
2271 if (mTouchButtonAccumulator.isToolActive()) {
2272 mCurrentRawPointerData.pointerCount = 1;
2273- mCurrentRawPointerData.idToIndex[0] = 0;
2274
2275 bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
2276 && (mTouchButtonAccumulator.isHovering()
2277 || (mRawPointerAxes.pressure.valid
2278 && mSingleTouchMotionAccumulator.getAbsolutePressure() <= 0));
2279- mCurrentRawPointerData.markIdBit(0, isHovering);
2280
2281 RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[0];
2282- outPointer.id = 0;
2283+
2284+ if (mLastRawPointerData.pointerCount == 1) {
2285+ outPointer.id = mLastRawPointerData.pointers[0].id;
2286+ mCurrentRawPointerData.insertId(outPointer.id, isHovering);
2287+ } else {
2288+ outPointer.id = -1;
2289+ *outHavePointerIds = false;
2290+ }
2291 outPointer.x = mSingleTouchMotionAccumulator.getAbsoluteX();
2292 outPointer.y = mSingleTouchMotionAccumulator.getAbsoluteY();
2293 outPointer.pressure = mSingleTouchMotionAccumulator.getAbsolutePressure();
2294@@ -5766,6 +5821,7 @@
2295 outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
2296 }
2297 outPointer.isHovering = isHovering;
2298+
2299 }
2300 }
2301
2302@@ -5798,7 +5854,7 @@
2303 void MultiTouchInputMapper::reset(nsecs_t when) {
2304 mMultiTouchMotionAccumulator.reset(getDevice());
2305
2306- mPointerIdBits.clear();
2307+ mPointerIds.clear();
2308
2309 TouchInputMapper::reset(when);
2310 }
2311@@ -5812,7 +5868,7 @@
2312 void MultiTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
2313 size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
2314 size_t outCount = 0;
2315- BitSet32 newPointerIdBits;
2316+ IntSet newPointerIds;
2317
2318 for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
2319 const MultiTouchMotionAccumulator::Slot* inSlot =
2320@@ -5861,27 +5917,26 @@
2321 int32_t trackingId = inSlot->getTrackingId();
2322 int32_t id = -1;
2323 if (trackingId >= 0) {
2324- for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
2325- uint32_t n = idBits.clearFirstMarkedBit();
2326+ mPointerIds.forEach([&](int32_t n) {
2327 if (mPointerTrackingIdMap[n] == trackingId) {
2328 id = n;
2329 }
2330- }
2331+ });
2332
2333- if (id < 0 && !mPointerIdBits.isFull()) {
2334- id = mPointerIdBits.markFirstUnmarkedBit();
2335+ if (id < 0) {
2336+ id = fetchNewPointerId();
2337+ mPointerIds.insert(id);
2338 mPointerTrackingIdMap[id] = trackingId;
2339 }
2340 }
2341 if (id < 0) {
2342 *outHavePointerIds = false;
2343- mCurrentRawPointerData.clearIdBits();
2344- newPointerIdBits.clear();
2345+ mCurrentRawPointerData.clearIds();
2346+ newPointerIds.clear();
2347 } else {
2348 outPointer.id = id;
2349- mCurrentRawPointerData.idToIndex[id] = outCount;
2350- mCurrentRawPointerData.markIdBit(id, isHovering);
2351- newPointerIdBits.markBit(id);
2352+ mCurrentRawPointerData.insertId(id, isHovering);
2353+ newPointerIds.insert(id);
2354 }
2355 }
2356
2357@@ -5889,7 +5944,7 @@
2358 }
2359
2360 mCurrentRawPointerData.pointerCount = outCount;
2361- mPointerIdBits = newPointerIdBits;
2362+ mPointerIds = newPointerIds;
2363
2364 mMultiTouchMotionAccumulator.finishSync();
2365 }
2366@@ -5914,8 +5969,8 @@
2367 && mRawPointerAxes.slot.minValue == 0 && mRawPointerAxes.slot.maxValue > 0) {
2368 size_t slotCount = mRawPointerAxes.slot.maxValue + 1;
2369 if (slotCount > MAX_SLOTS) {
2370- ALOGW("MultiTouch Device %s reported %d slots but the framework "
2371- "only supports a maximum of %d slots at this time.",
2372+ ALOGW("MultiTouch Device %s reported %lu slots but the framework "
2373+ "only supports a maximum of %lu slots at this time.",
2374 c_str(getDeviceName()), slotCount, MAX_SLOTS);
2375 slotCount = MAX_SLOTS;
2376 }
2377@@ -6057,7 +6112,7 @@
2378 // If there are too many axes, start dropping them.
2379 // Prefer to keep explicitly mapped axes.
2380 if (mAxes.size() > PointerCoords::MAX_AXES) {
2381- ALOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.",
2382+ ALOGI("Joystick '%s' has %lu axes but the framework only supports a maximum of %d.",
2383 c_str(getDeviceName()), mAxes.size(), PointerCoords::MAX_AXES);
2384 pruneAxes(true);
2385 pruneAxes(false);
2386
2387=== modified file '3rd_party/android-input/android/frameworks/base/services/input/InputReader.h'
2388--- 3rd_party/android-input/android/frameworks/base/services/input/InputReader.h 2013-09-20 12:18:12 +0000
2389+++ 3rd_party/android-input/android/frameworks/base/services/input/InputReader.h 2013-11-25 03:07:43 +0000
2390@@ -22,6 +22,7 @@
2391 #include "InputListener.h"
2392
2393 #include <androidfw/Input.h>
2394+#include <androidfw/IntSet.h>
2395 #include <androidfw/VelocityControl.h>
2396 #include <androidfw/VelocityTracker.h>
2397 #include <std/KeyedVector.h>
2398@@ -30,12 +31,14 @@
2399 #include <std/Timers.h>
2400 #include <std/RefBase.h>
2401 #include <std/String8.h>
2402-#include <std/BitSet.h>
2403
2404 #include <limits.h>
2405 #include <stddef.h>
2406 #include <unistd.h>
2407
2408+// C++ std lib
2409+#include <unordered_map>
2410+
2411 // Maximum supported size of a vibration pattern.
2412 // Must be at least 2.
2413 #define MAX_VIBRATE_PATTERN_SIZE 100
2414@@ -678,7 +681,7 @@
2415 /* Raw data for a collection of pointers including a pointer id mapping table. */
2416 struct RawPointerData {
2417 struct Pointer {
2418- uint32_t id;
2419+ int32_t id;
2420 int32_t x;
2421 int32_t y;
2422 int32_t pressure;
2423@@ -696,29 +699,40 @@
2424
2425 uint32_t pointerCount;
2426 Pointer pointers[MAX_POINTERS];
2427- BitSet32 hoveringIdBits, touchingIdBits;
2428- uint32_t idToIndex[MAX_POINTER_ID + 1];
2429+ IntSet hoveringIds, touchingIds;
2430+
2431+ uint32_t idToIndex(int32_t id) const {
2432+ uint32_t i = 0;
2433+
2434+ while (pointers[i].id != id && i < pointerCount) {
2435+ ++i;
2436+ }
2437+
2438+ assert(pointers[i].id == id);
2439+ return i;
2440+ }
2441+
2442
2443 RawPointerData();
2444 void clear();
2445 void copyFrom(const RawPointerData& other);
2446 void getCentroidOfTouchingPointers(float* outX, float* outY) const;
2447
2448- inline void markIdBit(uint32_t id, bool isHovering) {
2449+ inline void insertId(int32_t id, bool isHovering) {
2450 if (isHovering) {
2451- hoveringIdBits.markBit(id);
2452+ hoveringIds.insert(id);
2453 } else {
2454- touchingIdBits.markBit(id);
2455+ touchingIds.insert(id);
2456 }
2457 }
2458
2459- inline void clearIdBits() {
2460- hoveringIdBits.clear();
2461- touchingIdBits.clear();
2462+ inline void clearIds() {
2463+ hoveringIds.clear();
2464+ touchingIds.clear();
2465 }
2466
2467- inline const Pointer& pointerForId(uint32_t id) const {
2468- return pointers[idToIndex[id]];
2469+ inline const Pointer& pointerForId(int32_t id) const {
2470+ return pointers[idToIndex(id)];
2471 }
2472
2473 inline bool isHovering(uint32_t pointerIndex) {
2474@@ -732,15 +746,22 @@
2475 uint32_t pointerCount;
2476 PointerProperties pointerProperties[MAX_POINTERS];
2477 PointerCoords pointerCoords[MAX_POINTERS];
2478- BitSet32 hoveringIdBits, touchingIdBits;
2479- uint32_t idToIndex[MAX_POINTER_ID + 1];
2480+ IntSet hoveringIds, touchingIds;
2481+ uint32_t idToIndex(int32_t id) const {
2482+ uint32_t i = 0;
2483+
2484+ while (pointerProperties[i].id != id && i < pointerCount) { ++i; }
2485+
2486+ assert(pointerProperties[i].id == id);
2487+ return i;
2488+ }
2489
2490 CookedPointerData();
2491 void clear();
2492 void copyFrom(const CookedPointerData& other);
2493
2494 inline bool isHovering(uint32_t pointerIndex) {
2495- return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
2496+ return hoveringIds.contains(pointerProperties[pointerIndex].id);
2497 }
2498 };
2499
2500@@ -1233,13 +1254,13 @@
2501 int32_t mCurrentRawVScroll;
2502 int32_t mCurrentRawHScroll;
2503
2504- // Id bits used to differentiate fingers, stylus and mouse tools.
2505- BitSet32 mCurrentFingerIdBits; // finger or unknown
2506- BitSet32 mLastFingerIdBits;
2507- BitSet32 mCurrentStylusIdBits; // stylus or eraser
2508- BitSet32 mLastStylusIdBits;
2509- BitSet32 mCurrentMouseIdBits; // mouse or lens
2510- BitSet32 mLastMouseIdBits;
2511+ // Id sets used to differentiate fingers, stylus and mouse tools.
2512+ IntSet mCurrentFingerIds; // finger or unknown
2513+ IntSet mLastFingerIds;
2514+ IntSet mCurrentStylusIds; // stylus or eraser
2515+ IntSet mLastStylusIds;
2516+ IntSet mCurrentMouseIds; // mouse or lens
2517+ IntSet mLastMouseIds;
2518
2519 // True if we sent a HOVER_ENTER event.
2520 bool mSentHoverEnter;
2521@@ -1266,6 +1287,7 @@
2522 virtual bool hasStylus() const = 0;
2523
2524 virtual void syncTouch(nsecs_t when, bool* outHavePointerIds) = 0;
2525+ int32_t fetchNewPointerId();
2526
2527 private:
2528 // The surface orientation and width and height set by configureSurface().
2529@@ -1445,14 +1467,14 @@
2530
2531 // Pointer coords and ids for the current and previous pointer gesture.
2532 Mode currentGestureMode;
2533- BitSet32 currentGestureIdBits;
2534- uint32_t currentGestureIdToIndex[MAX_POINTER_ID + 1];
2535+ IntSet currentGestureIds;
2536+ std::unordered_map<int32_t, uint32_t> currentGestureIdToIndex;
2537 PointerProperties currentGestureProperties[MAX_POINTERS];
2538 PointerCoords currentGestureCoords[MAX_POINTERS];
2539
2540 Mode lastGestureMode;
2541- BitSet32 lastGestureIdBits;
2542- uint32_t lastGestureIdToIndex[MAX_POINTER_ID + 1];
2543+ IntSet lastGestureIds;
2544+ std::unordered_map<int32_t, uint32_t> lastGestureIdToIndex;
2545 PointerProperties lastGestureProperties[MAX_POINTERS];
2546 PointerCoords lastGestureCoords[MAX_POINTERS];
2547
2548@@ -1479,14 +1501,14 @@
2549
2550 // Distance that each pointer has traveled which has not yet been
2551 // subsumed into the reference gesture position.
2552- BitSet32 referenceIdBits;
2553+ IntSet referenceIds;
2554 struct Delta {
2555 float dx, dy;
2556 };
2557- Delta referenceDeltas[MAX_POINTER_ID + 1];
2558+ std::unordered_map<int32_t, Delta> referenceDeltas;
2559
2560 // Describes how touch ids are mapped to gesture ids for freeform gestures.
2561- uint32_t freeformTouchToGestureIdMap[MAX_POINTER_ID + 1];
2562+ std::unordered_map<int32_t, int32_t> freeformTouchToGestureIdMap;
2563
2564 // A velocity tracker for determining whether to switch active pointers during drags.
2565 VelocityTracker velocityTracker;
2566@@ -1496,9 +1518,9 @@
2567 activeTouchId = -1;
2568 activeGestureId = -1;
2569 currentGestureMode = NEUTRAL;
2570- currentGestureIdBits.clear();
2571+ currentGestureIds.clear();
2572 lastGestureMode = NEUTRAL;
2573- lastGestureIdBits.clear();
2574+ lastGestureIds.clear();
2575 downTime = 0;
2576 velocityTracker.clear();
2577 resetTap();
2578@@ -1584,20 +1606,26 @@
2579 int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
2580 int32_t edgeFlags,
2581 const PointerProperties* properties, const PointerCoords* coords,
2582- const uint32_t* idToIndex, BitSet32 idBits,
2583+ uint32_t inPointerCount,
2584+ int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime);
2585+ void dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
2586+ int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
2587+ int32_t edgeFlags,
2588+ const PointerProperties* properties, const PointerCoords* coords,
2589+ uint32_t inPointerCount, const IntSet &idsToDispatch,
2590 int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime);
2591
2592- // Updates pointer coords and properties for pointers with specified ids that have moved.
2593+ // Updates pointer coords and properties for pointers that have moved.
2594 // Returns true if any of them changed.
2595- bool updateMovedPointers(const PointerProperties* inProperties,
2596- const PointerCoords* inCoords, const uint32_t* inIdToIndex,
2597- PointerProperties* outProperties, PointerCoords* outCoords,
2598- const uint32_t* outIdToIndex, BitSet32 idBits) const;
2599+ bool updateMovedPointers(const PointerProperties* inProperties, const PointerCoords* inCoords,
2600+ uint32_t inPointerCount, PointerProperties* outProperties, PointerCoords* outCoords,
2601+ uint32_t outPointerCount, const IntSet &commonTouchingIds) const;
2602
2603 bool isPointInsideSurface(int32_t x, int32_t y);
2604 const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
2605
2606 void assignPointerIds();
2607+ int32_t mNextNewPointerId;
2608 };
2609
2610
2611@@ -1635,9 +1663,9 @@
2612 private:
2613 MultiTouchMotionAccumulator mMultiTouchMotionAccumulator;
2614
2615- // Specifies the pointer id bits that are in use, and their associated tracking id.
2616- BitSet32 mPointerIdBits;
2617- int32_t mPointerTrackingIdMap[MAX_POINTER_ID + 1];
2618+ // Specifies the pointer ids that are in use, and their associated tracking id.
2619+ IntSet mPointerIds;
2620+ std::unordered_map<int32_t, int32_t> mPointerTrackingIdMap;
2621 };
2622
2623
2624
2625=== modified file '3rd_party/android-input/android/frameworks/base/services/input/InputTransport.cpp'
2626--- 3rd_party/android-input/android/frameworks/base/services/input/InputTransport.cpp 2013-05-31 16:06:07 +0000
2627+++ 3rd_party/android-input/android/frameworks/base/services/input/InputTransport.cpp 2013-11-25 03:07:43 +0000
2628@@ -593,7 +593,7 @@
2629 if (eventTime < touchState.lastResample.eventTime) {
2630 rewriteMessage(touchState, msg);
2631 } else {
2632- touchState.lastResample.idBits.clear();
2633+ touchState.lastResample.ids.clear();
2634 }
2635 }
2636 break;
2637@@ -603,7 +603,7 @@
2638 ssize_t index = findTouchState(deviceId, source);
2639 if (index >= 0) {
2640 TouchState& touchState = mTouchStates.editItemAt(index);
2641- touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
2642+ touchState.lastResample.ids.remove(msg->body.motion.getActionId());
2643 rewriteMessage(touchState, msg);
2644 }
2645 break;
2646@@ -614,7 +614,7 @@
2647 if (index >= 0) {
2648 TouchState& touchState = mTouchStates.editItemAt(index);
2649 rewriteMessage(touchState, msg);
2650- touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
2651+ touchState.lastResample.ids.remove(msg->body.motion.getActionId());
2652 }
2653 break;
2654 }
2655@@ -644,7 +644,7 @@
2656 void InputConsumer::rewriteMessage(const TouchState& state, InputMessage* msg) {
2657 for (size_t i = 0; i < msg->body.motion.pointerCount; i++) {
2658 uint32_t id = msg->body.motion.pointers[i].properties.id;
2659- if (state.lastResample.idBits.hasBit(id)) {
2660+ if (state.lastResample.ids.contains(id)) {
2661 PointerCoords& msgCoords = msg->body.motion.pointers[i].coords;
2662 const PointerCoords& resampleCoords = state.lastResample.getPointerById(id);
2663 #if DEBUG_RESAMPLING
2664@@ -689,7 +689,7 @@
2665 size_t pointerCount = event->getPointerCount();
2666 for (size_t i = 0; i < pointerCount; i++) {
2667 uint32_t id = event->getPointerId(i);
2668- if (!current->idBits.hasBit(id)) {
2669+ if (!current->ids.contains(id)) {
2670 #if DEBUG_RESAMPLING
2671 ALOGD("Not resampled, missing id %d", id);
2672 #endif
2673@@ -744,14 +744,14 @@
2674
2675 // Resample touch coordinates.
2676 touchState.lastResample.eventTime = sampleTime;
2677- touchState.lastResample.idBits.clear();
2678+ touchState.lastResample.ids.clear();
2679 for (size_t i = 0; i < pointerCount; i++) {
2680 uint32_t id = event->getPointerId(i);
2681 touchState.lastResample.idToIndex[id] = i;
2682- touchState.lastResample.idBits.markBit(id);
2683+ touchState.lastResample.ids.insert(id);
2684 PointerCoords& resampledCoords = touchState.lastResample.pointers[i];
2685 const PointerCoords& currentCoords = current->getPointerById(id);
2686- if (other->idBits.hasBit(id)
2687+ if (other->ids.contains(id)
2688 && shouldResampleTool(event->getToolType(i))) {
2689 const PointerCoords& otherCoords = other->getPointerById(id);
2690 resampledCoords.copyFrom(currentCoords);
2691
2692=== added file '3rd_party/android-input/android/frameworks/base/services/input/IntSet.cpp'
2693--- 3rd_party/android-input/android/frameworks/base/services/input/IntSet.cpp 1970-01-01 00:00:00 +0000
2694+++ 3rd_party/android-input/android/frameworks/base/services/input/IntSet.cpp 2013-11-25 03:07:43 +0000
2695@@ -0,0 +1,123 @@
2696+/*
2697+ * Copyright © 2013 Canonical Ltd.
2698+ *
2699+ * This program is free software: you can redistribute it and/or modify it
2700+ * under the terms of the GNU Lesser General Public License version 3,
2701+ * as published by the Free Software Foundation.
2702+ *
2703+ * This program is distributed in the hope that it will be useful,
2704+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2705+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2706+ * GNU Lesser General Public License for more details.
2707+ *
2708+ * You should have received a copy of the GNU Lesser General Public License
2709+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2710+ *
2711+ * Author: Daniel d'Andrada <daniel.dandrada@canonical.com>
2712+ */
2713+
2714+#include <androidfw/IntSet.h>
2715+
2716+#ifdef ANDROID_INPUT_INTSET_TEST
2717+using namespace test::android;
2718+#else
2719+using namespace android;
2720+#endif
2721+
2722+IntSet::IntSet() {
2723+#ifdef ANDROID_INPUT_INTSET_TEST
2724+ ++constructionCount;
2725+#endif
2726+}
2727+
2728+IntSet::IntSet(std::initializer_list<int32_t> list)
2729+ : stdSet(list) {
2730+#ifdef ANDROID_INPUT_INTSET_TEST
2731+ ++constructionCount;
2732+#endif
2733+}
2734+
2735+IntSet::~IntSet() {
2736+#ifdef ANDROID_INPUT_INTSET_TEST
2737+ ++destructionCount;
2738+#endif
2739+}
2740+
2741+IntSet IntSet::operator -(const IntSet &other) const {
2742+ IntSet result;
2743+
2744+ std::set_difference(stdSet.cbegin(), stdSet.cend(),
2745+ other.stdSet.cbegin(), other.stdSet.cend(),
2746+ std::inserter(result.stdSet, result.stdSet.begin()));
2747+
2748+ return result;
2749+}
2750+
2751+IntSet IntSet::operator &(const IntSet &other) const {
2752+ IntSet result;
2753+
2754+ std::set_intersection(stdSet.cbegin(), stdSet.cend(),
2755+ other.stdSet.cbegin(), other.stdSet.cend(),
2756+ std::inserter(result.stdSet, result.stdSet.begin()));
2757+
2758+ return result;
2759+}
2760+
2761+bool IntSet::operator ==(const IntSet &other) const {
2762+ return stdSet == other.stdSet;
2763+}
2764+
2765+void IntSet::remove(const IntSet &values) {
2766+ remove(stdSet.begin(), values.stdSet.begin(), values.stdSet.end());
2767+}
2768+
2769+bool IntSet::contains(int32_t value) const {
2770+ return stdSet.find(value) != stdSet.end();
2771+}
2772+
2773+size_t IntSet::indexOf(int32_t value) const {
2774+ auto it = stdSet.begin();
2775+ size_t index = 0;
2776+ while (it != stdSet.end() && *it != value) {
2777+ it++;
2778+ ++index;
2779+ }
2780+ assert(it != stdSet.end());
2781+ return index;
2782+}
2783+
2784+std::string IntSet::toString() const {
2785+ std::ostringstream stream;
2786+
2787+ bool isFirst = true;
2788+ forEach([&](int32_t value) {
2789+ if (isFirst) {
2790+ isFirst = false;
2791+ } else {
2792+ stream << ", ";
2793+ }
2794+ stream << value;
2795+ });
2796+
2797+ return stream.str();
2798+}
2799+
2800+void IntSet::remove(std::set<int32_t>::iterator selfIterator,
2801+ std::set<int32_t>::const_iterator otherIterator,
2802+ std::set<int32_t>::const_iterator otherEnd) {
2803+
2804+ if (selfIterator == stdSet.end() || otherIterator == otherEnd)
2805+ return;
2806+
2807+ if (*selfIterator < *otherIterator) {
2808+ selfIterator++;
2809+ remove(selfIterator, otherIterator, otherEnd);
2810+ } else if (*selfIterator == *otherIterator) {
2811+ selfIterator = stdSet.erase(selfIterator);
2812+ otherIterator++;
2813+ remove(selfIterator, otherIterator, otherEnd);
2814+ } else /* *selfIterator > *otherIterator */ {
2815+ otherIterator++;
2816+ remove(selfIterator, otherIterator, otherEnd);
2817+ }
2818+}
2819
2820=== modified file '3rd_party/android-input/android/frameworks/base/services/input/PointerController.cpp'
2821--- 3rd_party/android-input/android/frameworks/base/services/input/PointerController.cpp 2012-11-06 18:05:11 +0000
2822+++ 3rd_party/android-input/android/frameworks/base/services/input/PointerController.cpp 2013-11-25 03:07:43 +0000
2823@@ -167,15 +167,12 @@
2824 }
2825 }
2826
2827-void PointerController::setSpots(const PointerCoords* spotCoords,
2828- const uint32_t* spotIdToIndex, BitSet32 spotIdBits) {
2829+void PointerController::setSpots(const PointerCoords* spotCoords, uint32_t spotCount) {
2830 #if DEBUG_POINTER_UPDATES
2831- ALOGD("setSpots: idBits=%08x", spotIdBits.value);
2832- for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
2833- uint32_t id = idBits.firstMarkedBit();
2834- idBits.clearBit(id);
2835- const PointerCoords& c = spotCoords[spotIdToIndex[id]];
2836- ALOGD(" spot %d: position=(%0.3f, %0.3f), pressure=%0.3f", id,
2837+ ALOGD("setSpots: spotCount=%d", spotCount);
2838+ for (size_t i = 0; i < spotCount; ++i) {
2839+ const PointerCoords& c = spotCoords[i];
2840+ ALOGD(" spot %d: position=(%0.3f, %0.3f), pressure=%0.3f", i,
2841 c.getAxisValue(AMOTION_EVENT_AXIS_X),
2842 c.getAxisValue(AMOTION_EVENT_AXIS_Y),
2843 c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
2844
2845=== modified file '3rd_party/android-input/android/frameworks/base/services/input/PointerController.h'
2846--- 3rd_party/android-input/android/frameworks/base/services/input/PointerController.h 2013-05-03 16:38:07 +0000
2847+++ 3rd_party/android-input/android/frameworks/base/services/input/PointerController.h 2013-11-25 03:07:43 +0000
2848@@ -18,7 +18,6 @@
2849 #define _UI_POINTER_CONTROLLER_H
2850
2851 #include <androidfw/Input.h>
2852-#include <std/BitSet.h>
2853 #include <std/Mutex.h>
2854 #include <std/RefBase.h>
2855 #include <std/String8.h>
2856@@ -104,8 +103,7 @@
2857 * For spotCoords, pressure != 0 indicates that the spot's location is being
2858 * pressed (not hovering).
2859 */
2860- virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
2861- BitSet32 spotIdBits) = 0;
2862+ virtual void setSpots(const PointerCoords* spotCoords, uint32_t spotCount) = 0;
2863
2864 /* Removes all spots. */
2865 virtual void clearSpots() = 0;
2866@@ -139,8 +137,7 @@
2867 virtual void unfade(Transition transition);
2868
2869 virtual void setPresentation(Presentation presentation);
2870- virtual void setSpots(const PointerCoords* spotCoords,
2871- const uint32_t* spotIdToIndex, BitSet32 spotIdBits);
2872+ virtual void setSpots(const PointerCoords* spotCoords, uint32_t spotCount);
2873 virtual void clearSpots();
2874
2875 void setDisplaySize(int32_t width, int32_t height);
2876
2877=== modified file '3rd_party/android-input/android/frameworks/base/services/input/VelocityControl.cpp'
2878--- 3rd_party/android-input/android/frameworks/base/services/input/VelocityControl.cpp 2013-05-03 16:38:07 +0000
2879+++ 3rd_party/android-input/android/frameworks/base/services/input/VelocityControl.cpp 2013-11-25 03:07:43 +0000
2880@@ -24,7 +24,6 @@
2881 #include <limits.h>
2882
2883 #include <androidfw/VelocityControl.h>
2884-#include <std/BitSet.h>
2885 #include <std/Timers.h>
2886
2887 namespace android {
2888@@ -35,6 +34,7 @@
2889
2890 VelocityControl::VelocityControl() {
2891 reset();
2892+ mIds.insert(1);
2893 }
2894
2895 void VelocityControl::setParameters(const VelocityControlParameters& parameters) {
2896@@ -66,7 +66,7 @@
2897 if (deltaY) {
2898 mRawPosition.y += *deltaY;
2899 }
2900- mVelocityTracker.addMovement(eventTime, BitSet32(BitSet32::valueForBit(0)), &mRawPosition);
2901+ mVelocityTracker.addMovement(eventTime, mIds, &mRawPosition);
2902
2903 float vx, vy;
2904 float scale = mParameters.scale;
2905
2906=== modified file '3rd_party/android-input/android/frameworks/base/services/input/VelocityTracker.cpp'
2907--- 3rd_party/android-input/android/frameworks/base/services/input/VelocityTracker.cpp 2013-05-03 16:38:07 +0000
2908+++ 3rd_party/android-input/android/frameworks/base/services/input/VelocityTracker.cpp 2013-11-25 03:07:43 +0000
2909@@ -27,7 +27,7 @@
2910 #include <limits.h>
2911
2912 #include <androidfw/VelocityTracker.h>
2913-#include <std/BitSet.h>
2914+#include <androidfw/IntSet.h>
2915 #include <std/String8.h>
2916 #include <std/Timers.h>
2917 #include <std/Log.h>
2918@@ -109,7 +109,7 @@
2919 const char* VelocityTracker::DEFAULT_STRATEGY = "lsq2";
2920
2921 VelocityTracker::VelocityTracker(const char* strategy) :
2922- mLastEventTime(0), mCurrentPointerIdBits(0), mActivePointerId(-1) {
2923+ mLastEventTime(0), mActivePointerId(-1) {
2924 char value[PROPERTY_VALUE_MAX];
2925
2926 // Allow the default strategy to be overridden using a system property for debugging.
2927@@ -202,29 +202,24 @@
2928 }
2929
2930 void VelocityTracker::clear() {
2931- mCurrentPointerIdBits.clear();
2932+ mCurrentPointerIds.clear();
2933 mActivePointerId = -1;
2934
2935 mStrategy->clear();
2936 }
2937
2938-void VelocityTracker::clearPointers(BitSet32 idBits) {
2939- BitSet32 remainingIdBits(mCurrentPointerIdBits.value & ~idBits.value);
2940- mCurrentPointerIdBits = remainingIdBits;
2941+void VelocityTracker::clearPointers(const IntSet &ids) {
2942+ mCurrentPointerIds.remove(ids);
2943
2944- if (mActivePointerId >= 0 && idBits.hasBit(mActivePointerId)) {
2945- mActivePointerId = !remainingIdBits.isEmpty() ? remainingIdBits.firstMarkedBit() : -1;
2946+ if (mActivePointerId >= 0 && ids.contains(mActivePointerId)) {
2947+ mActivePointerId = !mCurrentPointerIds.isEmpty() ? mCurrentPointerIds.first() : -1;
2948 }
2949
2950- mStrategy->clearPointers(idBits);
2951+ mStrategy->clearPointers(ids);
2952 }
2953
2954-void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions) {
2955- while (idBits.count() > MAX_POINTERS) {
2956- idBits.clearLastMarkedBit();
2957- }
2958-
2959- if ((mCurrentPointerIdBits.value & idBits.value)
2960+void VelocityTracker::addMovement(nsecs_t eventTime, const IntSet &ids, const Position* positions) {
2961+ if (!(mCurrentPointerIds & ids).isEmpty()
2962 && eventTime >= mLastEventTime + ASSUME_POINTER_STOPPED_TIME) {
2963 #if DEBUG_VELOCITY
2964 ALOGD("VelocityTracker: stopped for %0.3f ms, clearing state.",
2965@@ -236,20 +231,18 @@
2966 }
2967 mLastEventTime = eventTime;
2968
2969- mCurrentPointerIdBits = idBits;
2970- if (mActivePointerId < 0 || !idBits.hasBit(mActivePointerId)) {
2971- mActivePointerId = idBits.isEmpty() ? -1 : idBits.firstMarkedBit();
2972+ mCurrentPointerIds = ids;
2973+ if (mActivePointerId < 0 || !ids.contains(mActivePointerId)) {
2974+ mActivePointerId = ids.isEmpty() ? -1 : ids.first();
2975 }
2976
2977- mStrategy->addMovement(eventTime, idBits, positions);
2978+ mStrategy->addMovement(eventTime, ids, positions);
2979
2980 #if DEBUG_VELOCITY
2981- ALOGD("VelocityTracker: addMovement eventTime=%lld, idBits=0x%08x, activePointerId=%d",
2982- eventTime, idBits.value, mActivePointerId);
2983- for (BitSet32 iterBits(idBits); !iterBits.isEmpty(); ) {
2984- uint32_t id = iterBits.firstMarkedBit();
2985- uint32_t index = idBits.getIndexOfBit(id);
2986- iterBits.clearBit(id);
2987+ ALOGD("VelocityTracker: addMovement eventTime=%lld, ids.cont()=%d, activePointerId=%d",
2988+ eventTime, ids.count(), mActivePointerId);
2989+ size_t index = 0;
2990+ ids.forEach([&](int32_t id) {
2991 Estimator estimator;
2992 getEstimator(id, &estimator);
2993 ALOGD(" %d: position (%0.3f, %0.3f), "
2994@@ -259,6 +252,7 @@
2995 vectorToString(estimator.xCoeff, estimator.degree + 1).string(),
2996 vectorToString(estimator.yCoeff, estimator.degree + 1).string(),
2997 estimator.confidence);
2998+ ++index;
2999 }
3000 #endif
3001 }
3002@@ -276,9 +270,9 @@
3003 // Start a new movement trace for a pointer that just went down.
3004 // We do this on down instead of on up because the client may want to query the
3005 // final velocity for a pointer that just went up.
3006- BitSet32 downIdBits;
3007- downIdBits.markBit(event->getPointerId(event->getActionIndex()));
3008- clearPointers(downIdBits);
3009+ IntSet downIds;
3010+ downIds.insert(event->getPointerId(event->getActionIndex()));
3011+ clearPointers(downIds);
3012 break;
3013 }
3014 case AMOTION_EVENT_ACTION_MOVE:
3015@@ -301,14 +295,14 @@
3016 pointerCount = MAX_POINTERS;
3017 }
3018
3019- BitSet32 idBits;
3020+ IntSet ids;
3021 for (size_t i = 0; i < pointerCount; i++) {
3022- idBits.markBit(event->getPointerId(i));
3023+ ids.insert(event->getPointerId(i));
3024 }
3025
3026 uint32_t pointerIndex[MAX_POINTERS];
3027 for (size_t i = 0; i < pointerCount; i++) {
3028- pointerIndex[i] = idBits.getIndexOfBit(event->getPointerId(i));
3029+ pointerIndex[i] = ids.indexOf(event->getPointerId(i));
3030 }
3031
3032 nsecs_t eventTime;
3033@@ -322,7 +316,7 @@
3034 positions[index].x = event->getHistoricalX(i, h);
3035 positions[index].y = event->getHistoricalY(i, h);
3036 }
3037- addMovement(eventTime, idBits, positions);
3038+ addMovement(eventTime, ids, positions);
3039 }
3040
3041 eventTime = event->getEventTime();
3042@@ -331,7 +325,7 @@
3043 positions[index].x = event->getX(i);
3044 positions[index].y = event->getY(i);
3045 }
3046- addMovement(eventTime, idBits, positions);
3047+ addMovement(eventTime, ids, positions);
3048 }
3049
3050 bool VelocityTracker::getVelocity(uint32_t id, float* outVx, float* outVy) const {
3051@@ -367,15 +361,14 @@
3052
3053 void LeastSquaresVelocityTrackerStrategy::clear() {
3054 mIndex = 0;
3055- mMovements[0].idBits.clear();
3056-}
3057-
3058-void LeastSquaresVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
3059- BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value);
3060- mMovements[mIndex].idBits = remainingIdBits;
3061-}
3062-
3063-void LeastSquaresVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
3064+ mMovements[0].ids.clear();
3065+}
3066+
3067+void LeastSquaresVelocityTrackerStrategy::clearPointers(const IntSet &ids) {
3068+ mMovements[mIndex].ids.remove(ids);
3069+}
3070+
3071+void LeastSquaresVelocityTrackerStrategy::addMovement(nsecs_t eventTime, const IntSet &ids,
3072 const VelocityTracker::Position* positions) {
3073 if (++mIndex == HISTORY_SIZE) {
3074 mIndex = 0;
3075@@ -383,9 +376,9 @@
3076
3077 Movement& movement = mMovements[mIndex];
3078 movement.eventTime = eventTime;
3079- movement.idBits = idBits;
3080- uint32_t count = idBits.count();
3081- for (uint32_t i = 0; i < count; i++) {
3082+ movement.ids = ids;
3083+ size_t count = ids.count();
3084+ for (size_t i = 0; i < count; i++) {
3085 movement.positions[i] = positions[i];
3086 }
3087 }
3088@@ -570,7 +563,7 @@
3089 const Movement& newestMovement = mMovements[mIndex];
3090 do {
3091 const Movement& movement = mMovements[index];
3092- if (!movement.idBits.hasBit(id)) {
3093+ if (!movement.ids.contains(id)) {
3094 break;
3095 }
3096
3097@@ -702,36 +695,44 @@
3098 }
3099
3100 void IntegratingVelocityTrackerStrategy::clear() {
3101- mPointerIdBits.clear();
3102-}
3103-
3104-void IntegratingVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
3105- mPointerIdBits.value &= ~idBits.value;
3106-}
3107-
3108-void IntegratingVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
3109+ mPointerIds.clear();
3110+}
3111+
3112+void IntegratingVelocityTrackerStrategy::clearPointers(const IntSet &ids) {
3113+ mPointerIds.remove(ids);
3114+}
3115+
3116+void IntegratingVelocityTrackerStrategy::addMovement(nsecs_t eventTime, const IntSet &ids,
3117 const VelocityTracker::Position* positions) {
3118- uint32_t index = 0;
3119- for (BitSet32 iterIdBits(idBits); !iterIdBits.isEmpty();) {
3120- uint32_t id = iterIdBits.clearFirstMarkedBit();
3121- State& state = mPointerState[id];
3122- const VelocityTracker::Position& position = positions[index++];
3123- if (mPointerIdBits.hasBit(id)) {
3124- updateState(state, eventTime, position.x, position.y);
3125- } else {
3126- initState(state, eventTime, position.x, position.y);
3127- }
3128+
3129+ {
3130+ auto pointerIdsIt = mPointerIds.begin();
3131+ uint32_t index = 0;
3132+
3133+ for_each(ids.begin(), ids.end(), [&](int32_t id) {
3134+ State& state = mPointerState[id];
3135+ const VelocityTracker::Position& position = positions[index++];
3136+
3137+ while (*pointerIdsIt < id && pointerIdsIt != mPointerIds.end())
3138+ pointerIdsIt++;
3139+
3140+ if (pointerIdsIt != mPointerIds.end() && *pointerIdsIt == id) {
3141+ updateState(state, eventTime, position.x, position.y);
3142+ } else {
3143+ initState(state, eventTime, position.x, position.y);
3144+ }
3145+ });
3146 }
3147
3148- mPointerIdBits = idBits;
3149+ mPointerIds = ids;
3150 }
3151
3152 bool IntegratingVelocityTrackerStrategy::getEstimator(uint32_t id,
3153 VelocityTracker::Estimator* outEstimator) const {
3154 outEstimator->clear();
3155
3156- if (mPointerIdBits.hasBit(id)) {
3157- const State& state = mPointerState[id];
3158+ if (mPointerIds.contains(id)) {
3159+ const State& state = mPointerState.at(id);
3160 populateEstimator(state, outEstimator);
3161 return true;
3162 }
3163@@ -823,15 +824,14 @@
3164
3165 void LegacyVelocityTrackerStrategy::clear() {
3166 mIndex = 0;
3167- mMovements[0].idBits.clear();
3168-}
3169-
3170-void LegacyVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
3171- BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value);
3172- mMovements[mIndex].idBits = remainingIdBits;
3173-}
3174-
3175-void LegacyVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
3176+ mMovements[0].ids.clear();
3177+}
3178+
3179+void LegacyVelocityTrackerStrategy::clearPointers(const IntSet &ids) {
3180+ mMovements[mIndex].ids.remove(ids);
3181+}
3182+
3183+void LegacyVelocityTrackerStrategy::addMovement(nsecs_t eventTime, const IntSet &ids,
3184 const VelocityTracker::Position* positions) {
3185 if (++mIndex == HISTORY_SIZE) {
3186 mIndex = 0;
3187@@ -839,11 +839,8 @@
3188
3189 Movement& movement = mMovements[mIndex];
3190 movement.eventTime = eventTime;
3191- movement.idBits = idBits;
3192- uint32_t count = idBits.count();
3193- for (uint32_t i = 0; i < count; i++) {
3194- movement.positions[i] = positions[i];
3195- }
3196+ movement.ids = ids;
3197+ memcpy(movement.positions, positions, sizeof(VelocityTracker::Position) * ids.count());
3198 }
3199
3200 bool LegacyVelocityTrackerStrategy::getEstimator(uint32_t id,
3201@@ -851,7 +848,7 @@
3202 outEstimator->clear();
3203
3204 const Movement& newestMovement = mMovements[mIndex];
3205- if (!newestMovement.idBits.hasBit(id)) {
3206+ if (!newestMovement.ids.contains(id)) {
3207 return false; // no data
3208 }
3209
3210@@ -862,7 +859,7 @@
3211 do {
3212 uint32_t nextOldestIndex = (oldestIndex == 0 ? HISTORY_SIZE : oldestIndex) - 1;
3213 const Movement& nextOldestMovement = mMovements[nextOldestIndex];
3214- if (!nextOldestMovement.idBits.hasBit(id)
3215+ if (!nextOldestMovement.ids.contains(id)
3216 || nextOldestMovement.eventTime < minTime) {
3217 break;
3218 }
3219
3220=== modified file 'CMakeLists.txt'
3221--- CMakeLists.txt 2013-11-06 03:17:35 +0000
3222+++ CMakeLists.txt 2013-11-25 03:07:43 +0000
3223@@ -28,7 +28,7 @@
3224
3225 set(MIR_VERSION_MAJOR 0)
3226 set(MIR_VERSION_MINOR 1)
3227-set(MIR_VERSION_PATCH 1)
3228+set(MIR_VERSION_PATCH 2)
3229
3230 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
3231
3232
3233=== modified file 'debian/changelog'
3234--- debian/changelog 2013-11-20 07:36:15 +0000
3235+++ debian/changelog 2013-11-25 03:07:43 +0000
3236@@ -1,3 +1,96 @@
3237+mir (0.1.2-0ubuntu1) UNRELEASED; urgency=low
3238+
3239+ * New upstream release 0.1.2
3240+ - graphics: android: improve interface for mga::DisplayDevice so its
3241+ just concerned with rendering and posting.
3242+ - surfaces: rename "surfaces" component to "scene".
3243+ - surfaces, shell: Migrate Session data model from shell to surfaces.
3244+ - graphics: change fill_ipc_package() to use real pointers.
3245+ - mir_client_library.h: Fix typo "do and locking" should be "do any
3246+ locking".
3247+ - API enumerations cleanup: Remove slightly misleading *_enum_max_
3248+ values, and replace them with more accurate plural forms.
3249+ - test_android_communication_package: Do not expect opened fd to be >0,
3250+ we may have closed stdin making this a valid value (LP: #1247718).
3251+ - Update docs about running Mir on the desktop to mention new package
3252+ ubuntu-desktop-mir.
3253+ - offscreen: Add a display that renders its output to offscreen buffers
3254+ - graphics: android: fix regression for hwc1.0 devices introduced in r1228
3255+ (LP: #1252433).
3256+ - OffscreenPlatform provides the services that the offscreen display
3257+ needs from the Platform.
3258+ - graphics: android: consolidate the GLContexts classes in use.
3259+ - Fix uninitialized variable causing random drm_auth_magic test
3260+ failures. (LP: #1252144).
3261+ - Add a fullyish functional Udev wrapper. This currently sits in
3262+ graphics/gbm, but will be moved to the top-level when input device
3263+ detection migrates.
3264+ - Add resizing support to example code; demo-shell and clients.
3265+ - eglapp: Clarify messages about pixel formats (LP: #1168304).
3266+ - Adds support to the MirMotionEvent under pointer_coordinates called
3267+ tool_type. This will allow clients to tell what type of tool is
3268+ being used, from mouse/finger/etc. (LP: #1252498)
3269+ - client,frontend: Report the real available surface pixel formats to
3270+ clients. (LP: #1240833)
3271+ - graphics: android: 1) change hwc1.1 to make use of sync fences during
3272+ the compositor's gl renderloop. Note that we no longer wait for the
3273+ render to complete, we pass this responsibility to the driver and the
3274+ kernel. 2) support nexus 10. (LP: #1252173) (LP: #1203268)
3275+ - shell: don't publish SurfacesContainer - it can be private to shell.
3276+ - gbm: Don't mess up the VT mode on setup failure Only restore the
3277+ previous VT mode during shutdown if it was VT_AUTO.
3278+ - Fix a crash due to a failed eglMakeCurrent() call when in nested mode.
3279+ - shell: unity-mir uses shell::FocusSetter - make the header public again
3280+ - Add resize support to client surfaces (mir::client::MirSurface).
3281+ - graphics: android: support 'old aka 2012' nexus 7 hwc (nvidia tegra3
3282+ SoC) better. (LP: #1231917)
3283+ - Add resize support to *ClientBuffer classes. Now always get dimensions
3284+ from the latest buffer package.
3285+ - android: support driver hooks for the Mali T604 (present in nexus 10)
3286+ - Add width and height to the protocol Buffer messages, in preparation
3287+ for resizable surfaces.
3288+ - surfaces, shell, logging, tests: don't publish headers
3289+ that can be private to surfaces. surfaces/basic_surface.h,
3290+ surfaces/surface_controller.h and shell/surface_builder.h
3291+ - examples: Restore GL framebuffer binding when destroying the render
3292+ target
3293+ - examples, surfaces, shell: remove render_surfaces dependency on
3294+ BasicSurface
3295+ - geometry: remove implementation of streaming operators from headers
3296+ (LP: #1247820)
3297+ - Eliminate the registration order focus sequence, folding it's
3298+ functionality in to the session container.
3299+ - Ensure the session mediator releases acquired buffer resources before
3300+ attempting to acquire a new buffer on behalf of the client. This fixes
3301+ performance regression (LP: #1249210).
3302+ - Some cleanups to test_client_input.cpp.
3303+ - Factor out a bunch of "ClientConfigCommon".
3304+ - Small cleanup to session container test to increase encapsulation.
3305+ - shell, surfaces: Another step in "fixing" the surfaces hierarchies -
3306+ only publish interfaces and putting the data model into surfaces.
3307+ - graphics: android: HWC1.1 use EGL to get further information about
3308+ the framebuffer pixel format.
3309+ - Fix FTBS using use_debflags=ON (building for android-armhf).
3310+ (LP: #1248014)
3311+ - Add a client input receiver report.
3312+ - doc: doxygen 1.8.4 complains about an obsolete config so ran "doxygen
3313+ u Doxyfile.in".
3314+ - Implement resize() for the server-side Surface classes.
3315+ - android: clean up mga::DisplayBuffer and mga::DisplayBufferFactory
3316+ - Add resize() support to BufferStream, in preparation for resizable
3317+ surfaces.
3318+ - Merge metadata changes from the newly reconstructed lp:mir
3319+ - tests: Deduplicate mg::GraphicBufferAllocator stubs.
3320+ - examples: Remove spurious use of mir/shell/surface.h.
3321+ - frontend: remove ClientTrackingSurface from the Surface class
3322+ hierarchy
3323+ - Bumping ABI on server to libmirserver11.
3324+ - Don't mention "Renderable". That interface hasn't existed for quite
3325+ some time now.
3326+ - android-input: Assign more unique touch ids
3327+
3328+ -- Kevin Gunn <kevin.gunn@canonical.com> Fri, 22 Nov 2013 12:34:52 -0600
3329+
3330 mir (0.1.1+14.04.20131120-0ubuntu1) trusty; urgency=low
3331
3332 [ Daniel van Vugt ]
3333
3334=== modified file 'debian/control'
3335--- debian/control 2013-11-06 03:17:35 +0000
3336+++ debian/control 2013-11-25 03:07:43 +0000
3337@@ -69,7 +69,7 @@
3338 .
3339 Contains the protocol's definition files.
3340
3341-Package: libmirserver10
3342+Package: libmirserver11
3343 Section: libs
3344 Architecture: i386 amd64 armhf arm64
3345 Multi-Arch: same
3346@@ -115,7 +115,7 @@
3347 Architecture: i386 amd64 armhf arm64
3348 Multi-Arch: same
3349 Pre-Depends: ${misc:Pre-Depends}
3350-Depends: libmirserver10 (= ${binary:Version}),
3351+Depends: libmirserver11 (= ${binary:Version}),
3352 libmirprotobuf-dev (= ${binary:Version}),
3353 mircommon-dev (= ${binary:Version}),
3354 libglm-dev,
3355
3356=== renamed file 'debian/libmirserver10.install' => 'debian/libmirserver11.install'
3357--- debian/libmirserver10.install 2013-11-06 03:17:35 +0000
3358+++ debian/libmirserver11.install 2013-11-25 03:07:43 +0000
3359@@ -1,1 +1,1 @@
3360-usr/lib/*/libmirserver.so.10
3361+usr/lib/*/libmirserver.so.11
3362
3363=== modified file 'debian/rules' (properties changed: -x to +x)
3364=== modified file 'doc/Doxyfile.in'
3365--- doc/Doxyfile.in 2013-07-02 11:27:33 +0000
3366+++ doc/Doxyfile.in 2013-11-25 03:07:43 +0000
3367@@ -1,14 +1,16 @@
3368-# Doxyfile 1.8.1.2
3369+# Doxyfile 1.8.4
3370
3371 # This file describes the settings to be used by the documentation system
3372-# doxygen (www.doxygen.org) for a project
3373+# doxygen (www.doxygen.org) for a project.
3374 #
3375-# All text after a hash (#) is considered a comment and will be ignored
3376+# All text after a double hash (##) is considered a comment and is placed
3377+# in front of the TAG it is preceding .
3378+# All text after a hash (#) is considered a comment and will be ignored.
3379 # The format is:
3380 # TAG = value [value, ...]
3381 # For lists items can also be appended using:
3382 # TAG += value [value, ...]
3383-# Values that contain spaces should be placed between quotes (" ")
3384+# Values that contain spaces should be placed between quotes (" ").
3385
3386 #---------------------------------------------------------------------------
3387 # Project related configuration options
3388@@ -70,9 +72,9 @@
3389 # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
3390 # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
3391 # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
3392-# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
3393-# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
3394-# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
3395+# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian,
3396+# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic,
3397+# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
3398
3399 OUTPUT_LANGUAGE = English
3400
3401@@ -136,7 +138,9 @@
3402 # only done if one of the specified strings matches the left-hand part of
3403 # the path. The tag can be used to show relative paths in the file list.
3404 # If left blank the directory from which doxygen is run is used as the
3405-# path to strip.
3406+# path to strip. Note that you specify absolute paths here, but also
3407+# relative paths, which will be relative from the directory where doxygen is
3408+# started.
3409
3410 STRIP_FROM_PATH = @CMAKE_CURRENT_SOURCE_DIR@
3411
3412@@ -239,14 +243,15 @@
3413 OPTIMIZE_OUTPUT_VHDL = NO
3414
3415 # Doxygen selects the parser to use depending on the extension of the files it
3416-# parses. With this tag you can assign which parser to use for a given extension.
3417-# Doxygen has a built-in mapping, but you can override or extend it using this
3418-# tag. The format is ext=language, where ext is a file extension, and language
3419-# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
3420-# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
3421-# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
3422-# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
3423-# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
3424+# parses. With this tag you can assign which parser to use for a given
3425+# extension. Doxygen has a built-in mapping, but you can override or extend it
3426+# using this tag. The format is ext=language, where ext is a file extension,
3427+# and language is one of the parsers supported by doxygen: IDL, Java,
3428+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
3429+# C++. For instance to make doxygen treat .inc files as Fortran files (default
3430+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
3431+# that for custom extensions you also need to set FILE_PATTERNS otherwise the
3432+# files are not read by doxygen.
3433
3434 EXTENSION_MAPPING =
3435
3436@@ -259,6 +264,13 @@
3437
3438 MARKDOWN_SUPPORT = YES
3439
3440+# When enabled doxygen tries to link words that correspond to documented
3441+# classes, or namespaces to their corresponding documentation. Such a link can
3442+# be prevented in individual cases by by putting a % sign in front of the word
3443+# or globally by setting AUTOLINK_SUPPORT to NO.
3444+
3445+AUTOLINK_SUPPORT = YES
3446+
3447 # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
3448 # to include (a tag file for) the STL sources as input, then you should
3449 # set this tag to YES in order to let doxygen match functions declarations and
3450@@ -279,10 +291,10 @@
3451
3452 SIP_SUPPORT = NO
3453
3454-# For Microsoft's IDL there are propget and propput attributes to indicate getter
3455-# and setter methods for a property. Setting this option to YES (the default)
3456-# will make doxygen replace the get and set methods by a property in the
3457-# documentation. This will only work if the methods are indeed getting or
3458+# For Microsoft's IDL there are propget and propput attributes to indicate
3459+# getter and setter methods for a property. Setting this option to YES (the
3460+# default) will make doxygen replace the get and set methods by a property in
3461+# the documentation. This will only work if the methods are indeed getting or
3462 # setting a simple type. If this is not the case, or you want to show the
3463 # methods anyway, you should set this option to NO.
3464
3465@@ -311,11 +323,11 @@
3466 INLINE_GROUPED_CLASSES = NO
3467
3468 # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
3469-# unions with only public data fields will be shown inline in the documentation
3470-# of the scope in which they are defined (i.e. file, namespace, or group
3471-# documentation), provided this scope is documented. If set to NO (the default),
3472-# structs, classes, and unions are shown on a separate page (for HTML and Man
3473-# pages) or section (for LaTeX and RTF).
3474+# unions with only public data fields or simple typedef fields will be shown
3475+# inline in the documentation of the scope in which they are defined (i.e. file,
3476+# namespace, or group documentation), provided this scope is documented. If set
3477+# to NO (the default), structs, classes, and unions are shown on a separate
3478+# page (for HTML and Man pages) or section (for LaTeX and RTF).
3479
3480 INLINE_SIMPLE_STRUCTS = NO
3481
3482@@ -329,30 +341,14 @@
3483
3484 TYPEDEF_HIDES_STRUCT = NO
3485
3486-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
3487-# determine which symbols to keep in memory and which to flush to disk.
3488-# When the cache is full, less often used symbols will be written to disk.
3489-# For small to medium size projects (<1000 input files) the default value is
3490-# probably good enough. For larger projects a too small cache size can cause
3491-# doxygen to be busy swapping symbols to and from disk most of the time
3492-# causing a significant performance penalty.
3493-# If the system has enough physical memory increasing the cache will improve the
3494-# performance by keeping more symbols in memory. Note that the value works on
3495-# a logarithmic scale so increasing the size by one will roughly double the
3496-# memory usage. The cache size is given by this formula:
3497-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
3498-# corresponding to a cache size of 2^16 = 65536 symbols.
3499-
3500-SYMBOL_CACHE_SIZE = 0
3501-
3502-# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
3503-# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
3504-# their name and scope. Since this can be an expensive process and often the
3505-# same symbol appear multiple times in the code, doxygen keeps a cache of
3506-# pre-resolved symbols. If the cache is too small doxygen will become slower.
3507-# If the cache is too large, memory is wasted. The cache size is given by this
3508-# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
3509-# corresponding to a cache size of 2^16 = 65536 symbols.
3510+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
3511+# cache is used to resolve symbols given their name and scope. Since this can
3512+# be an expensive process and often the same symbol appear multiple times in
3513+# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too
3514+# small doxygen will become slower. If the cache is too large, memory is wasted.
3515+# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid
3516+# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536
3517+# symbols.
3518
3519 LOOKUP_CACHE_SIZE = 0
3520
3521@@ -363,7 +359,7 @@
3522 # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
3523 # documentation are documented, even if no documentation was available.
3524 # Private class members and static file members will be hidden unless
3525-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
3526+# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES
3527
3528 EXTRACT_ALL = YES
3529
3530@@ -544,7 +540,8 @@
3531 GENERATE_DEPRECATEDLIST= YES
3532
3533 # The ENABLED_SECTIONS tag can be used to enable conditional
3534-# documentation sections, marked by \if sectionname ... \endif.
3535+# documentation sections, marked by \if section-label ... \endif
3536+# and \cond section-label ... \endcond blocks.
3537
3538 ENABLED_SECTIONS =
3539
3540@@ -571,7 +568,8 @@
3541 SHOW_FILES = YES
3542
3543 # Set the SHOW_NAMESPACES tag to NO to disable the generation of the
3544-# Namespaces page. This will remove the Namespaces entry from the Quick Index
3545+# Namespaces page.
3546+# This will remove the Namespaces entry from the Quick Index
3547 # and from the Folder Tree View (if specified). The default is YES.
3548
3549 SHOW_NAMESPACES = YES
3550@@ -601,7 +599,8 @@
3551 # requires the bibtex tool to be installed. See also
3552 # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
3553 # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
3554-# feature you need bibtex and perl available in the search path.
3555+# feature you need bibtex and perl available in the search path. Do not use
3556+# file names with spaces, bibtex cannot handle them.
3557
3558 CITE_BIB_FILES =
3559
3560@@ -757,7 +756,11 @@
3561 # wildcard * is used, a substring. Examples: ANamespace, AClass,
3562 # AClass::ANamespace, ANamespace::*Test
3563
3564-EXCLUDE_SYMBOLS = android google mfd mgg mp
3565+EXCLUDE_SYMBOLS = android \
3566+ google \
3567+ mfd \
3568+ mgg \
3569+ mp
3570
3571 # The EXAMPLE_PATH tag can be used to specify one or more files or
3572 # directories that contain example code fragments that are included (see
3573@@ -790,14 +793,19 @@
3574 # by executing (via popen()) the command <filter> <input-file>, where <filter>
3575 # is the value of the INPUT_FILTER tag, and <input-file> is the name of an
3576 # input file. Doxygen will then use the output that the filter program writes
3577-# to standard output. If FILTER_PATTERNS is specified, this tag will be
3578-# ignored.
3579+# to standard output.
3580+# If FILTER_PATTERNS is specified, this tag will be ignored.
3581+# Note that the filter must not add or remove lines; it is applied before the
3582+# code is scanned, but not when the output code is generated. If lines are added
3583+# or removed, the anchors will not be placed correctly.
3584
3585 INPUT_FILTER =
3586
3587 # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
3588-# basis. Doxygen will compare the file name with each pattern and apply the
3589-# filter if there is a match. The filters are a list of the form:
3590+# basis.
3591+# Doxygen will compare the file name with each pattern and apply the
3592+# filter if there is a match.
3593+# The filters are a list of the form:
3594 # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
3595 # info on how filters are used. If FILTER_PATTERNS is empty or if
3596 # non of the patterns match the file name, INPUT_FILTER is applied.
3597@@ -818,6 +826,13 @@
3598
3599 FILTER_SOURCE_PATTERNS =
3600
3601+# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that
3602+# is part of the input, its contents will be placed on the main page
3603+# (index.html). This can be useful if you have a project on for instance GitHub
3604+# and want reuse the introduction page also for the doxygen output.
3605+
3606+USE_MDFILE_AS_MAINPAGE =
3607+
3608 #---------------------------------------------------------------------------
3609 # configuration options related to source browsing
3610 #---------------------------------------------------------------------------
3611@@ -855,7 +870,8 @@
3612 # If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
3613 # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
3614 # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
3615-# link to the source code. Otherwise they will link to the documentation.
3616+# link to the source code.
3617+# Otherwise they will link to the documentation.
3618
3619 REFERENCES_LINK_SOURCE = YES
3620
3621@@ -920,7 +936,7 @@
3622 # The HTML_HEADER tag can be used to specify a personal HTML header for
3623 # each generated HTML page. If it is left blank doxygen will generate a
3624 # standard header. Note that when using a custom header you are responsible
3625-# for the proper inclusion of any scripts and style sheets that doxygen
3626+# for the proper inclusion of any scripts and style sheets that doxygen
3627 # needs, which is dependent on the configuration options used.
3628 # It is advised to generate a default header using "doxygen -w html
3629 # header.html footer.html stylesheet.css YourConfigFile" and then modify
3630@@ -938,18 +954,27 @@
3631
3632 # The HTML_STYLESHEET tag can be used to specify a user-defined cascading
3633 # style sheet that is used by each HTML page. It can be used to
3634-# fine-tune the look of the HTML output. If the tag is left blank doxygen
3635-# will generate a default style sheet. Note that doxygen will try to copy
3636-# the style sheet file to the HTML output directory, so don't put your own
3637-# style sheet in the HTML output directory as well, or it will be erased!
3638+# fine-tune the look of the HTML output. If left blank doxygen will
3639+# generate a default style sheet. Note that it is recommended to use
3640+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
3641+# tag will in the future become obsolete.
3642
3643 HTML_STYLESHEET =
3644+
3645+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
3646+# user-defined cascading style sheet that is included after the standard
3647+# style sheets created by doxygen. Using this option one can overrule
3648+# certain style aspects. This is preferred over using HTML_STYLESHEET
3649+# since it does not replace the standard style sheet and is therefor more
3650+# robust against future updates. Doxygen will copy the style sheet file to
3651+# the output directory.
3652+
3653 HTML_EXTRA_STYLESHEET = @CMAKE_BINARY_DIR@/doc/extra.css
3654
3655 # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
3656 # other source files which should be copied to the HTML output directory. Note
3657 # that these files will be copied to the base HTML output directory. Use the
3658-# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
3659+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
3660 # files. In the HTML_STYLESHEET file, use the file name only. Also note that
3661 # the files will be copied as-is; there are no commands or markers available.
3662
3663@@ -1030,9 +1055,9 @@
3664
3665 DOCSET_BUNDLE_ID = org.doxygen.Project
3666
3667-# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
3668-# the documentation publisher. This should be a reverse domain-name style
3669-# string, e.g. com.mycompany.MyDocSet.documentation.
3670+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
3671+# identify the documentation publisher. This should be a reverse domain-name
3672+# style string, e.g. com.mycompany.MyDocSet.documentation.
3673
3674 DOCSET_PUBLISHER_ID = org.doxygen.Publisher
3675
3676@@ -1138,7 +1163,7 @@
3677 QHG_LOCATION =
3678
3679 # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
3680-# will be generated, which together with the HTML files, form an Eclipse help
3681+# will be generated, which together with the HTML files, form an Eclipse help
3682 # plugin. To install this plugin and make it available under the help contents
3683 # menu in Eclipse, the contents of the directory containing the HTML and XML
3684 # files needs to be copied into the plugins directory of eclipse. The name of
3685@@ -1217,13 +1242,21 @@
3686
3687 USE_MATHJAX = NO
3688
3689+# When MathJax is enabled you can set the default output format to be used for
3690+# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and
3691+# SVG. The default value is HTML-CSS, which is slower, but has the best
3692+# compatibility.
3693+
3694+MATHJAX_FORMAT = HTML-CSS
3695+
3696 # When MathJax is enabled you need to specify the location relative to the
3697 # HTML output directory using the MATHJAX_RELPATH option. The destination
3698 # directory should contain the MathJax.js script. For instance, if the mathjax
3699 # directory is located at the same level as the HTML output directory, then
3700 # MATHJAX_RELPATH should be ../mathjax. The default value points to
3701 # the MathJax Content Delivery Network so you can quickly see the result without
3702-# installing MathJax. However, it is strongly recommended to install a local
3703+# installing MathJax.
3704+# However, it is strongly recommended to install a local
3705 # copy of MathJax from http://www.mathjax.org before deployment.
3706
3707 MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
3708@@ -1233,6 +1266,11 @@
3709
3710 MATHJAX_EXTENSIONS =
3711
3712+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript
3713+# pieces of code that will be used on startup of the MathJax code.
3714+
3715+MATHJAX_CODEFILE =
3716+
3717 # When the SEARCHENGINE tag is enabled doxygen will generate a search box
3718 # for the HTML output. The underlying search engine uses javascript
3719 # and DHTML and should work on any modern browser. Note that when using
3720@@ -1244,15 +1282,55 @@
3721 SEARCHENGINE = YES
3722
3723 # When the SERVER_BASED_SEARCH tag is enabled the search engine will be
3724-# implemented using a PHP enabled web server instead of at the web client
3725-# using Javascript. Doxygen will generate the search PHP script and index
3726-# file to put on the web server. The advantage of the server
3727-# based approach is that it scales better to large projects and allows
3728-# full text search. The disadvantages are that it is more difficult to setup
3729-# and does not have live searching capabilities.
3730+# implemented using a web server instead of a web client using Javascript.
3731+# There are two flavours of web server based search depending on the
3732+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
3733+# searching and an index file used by the script. When EXTERNAL_SEARCH is
3734+# enabled the indexing and searching needs to be provided by external tools.
3735+# See the manual for details.
3736
3737 SERVER_BASED_SEARCH = NO
3738
3739+# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP
3740+# script for searching. Instead the search results are written to an XML file
3741+# which needs to be processed by an external indexer. Doxygen will invoke an
3742+# external search engine pointed to by the SEARCHENGINE_URL option to obtain
3743+# the search results. Doxygen ships with an example indexer (doxyindexer) and
3744+# search engine (doxysearch.cgi) which are based on the open source search
3745+# engine library Xapian. See the manual for configuration details.
3746+
3747+EXTERNAL_SEARCH = NO
3748+
3749+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
3750+# which will returned the search results when EXTERNAL_SEARCH is enabled.
3751+# Doxygen ships with an example search engine (doxysearch) which is based on
3752+# the open source search engine library Xapian. See the manual for configuration
3753+# details.
3754+
3755+SEARCHENGINE_URL =
3756+
3757+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
3758+# search data is written to a file for indexing by an external tool. With the
3759+# SEARCHDATA_FILE tag the name of this file can be specified.
3760+
3761+SEARCHDATA_FILE = searchdata.xml
3762+
3763+# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the
3764+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
3765+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
3766+# projects and redirect the results back to the right project.
3767+
3768+EXTERNAL_SEARCH_ID =
3769+
3770+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
3771+# projects other than the one defined by this configuration file, but that are
3772+# all added to the same external search index. Each project needs to have a
3773+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id
3774+# of to a relative location where the documentation can be found.
3775+# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ...
3776+
3777+EXTRA_SEARCH_MAPPINGS =
3778+
3779 #---------------------------------------------------------------------------
3780 # configuration options related to the LaTeX output
3781 #---------------------------------------------------------------------------
3782@@ -1290,7 +1368,7 @@
3783
3784 # The PAPER_TYPE tag can be used to set the paper type that is used
3785 # by the printer. Possible values are: a4, letter, legal and
3786-# executive. If left blank a4wide will be used.
3787+# executive. If left blank a4 will be used.
3788
3789 PAPER_TYPE = a4
3790
3791@@ -1313,6 +1391,13 @@
3792
3793 LATEX_FOOTER =
3794
3795+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images
3796+# or other source files which should be copied to the LaTeX output directory.
3797+# Note that the files will be copied as-is; there are no commands or markers
3798+# available.
3799+
3800+LATEX_EXTRA_FILES =
3801+
3802 # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
3803 # is prepared for conversion to pdf (using ps2pdf). The pdf file will
3804 # contain links (just like the HTML output) instead of page references
3805@@ -1458,6 +1543,21 @@
3806 XML_PROGRAMLISTING = YES
3807
3808 #---------------------------------------------------------------------------
3809+# configuration options related to the DOCBOOK output
3810+#---------------------------------------------------------------------------
3811+
3812+# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files
3813+# that can be used to generate PDF.
3814+
3815+GENERATE_DOCBOOK = NO
3816+
3817+# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put.
3818+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
3819+# front of it. If left blank docbook will be used as the default path.
3820+
3821+DOCBOOK_OUTPUT = docbook
3822+
3823+#---------------------------------------------------------------------------
3824 # configuration options for the AutoGen Definitions output
3825 #---------------------------------------------------------------------------
3826
3827@@ -1488,8 +1588,10 @@
3828 PERLMOD_LATEX = NO
3829
3830 # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
3831-# nicely formatted so it can be parsed by a human reader. This is useful
3832-# if you want to understand what is going on. On the other hand, if this
3833+# nicely formatted so it can be parsed by a human reader.
3834+# This is useful
3835+# if you want to understand what is going on.
3836+# On the other hand, if this
3837 # tag is set to NO the size of the Perl module output will be much smaller
3838 # and Perl will parse it just the same.
3839
3840@@ -1575,9 +1677,11 @@
3841 # The TAGFILES option can be used to specify one or more tagfiles. For each
3842 # tag file the location of the external documentation should be added. The
3843 # format of a tag file without this location is as follows:
3844-# TAGFILES = file1 file2 ...
3845+#
3846+# TAGFILES = file1 file2 ...
3847 # Adding location for the tag files is done as follows:
3848-# TAGFILES = file1=loc1 "file2 = loc2" ...
3849+#
3850+# TAGFILES = file1=loc1 "file2 = loc2" ...
3851 # where "loc1" and "loc2" can be relative or absolute paths
3852 # or URLs. Note that each tag file must have a unique name (where the name does
3853 # NOT include the path). If a tag file is not located in the directory in which
3854@@ -1602,6 +1706,12 @@
3855
3856 EXTERNAL_GROUPS = YES
3857
3858+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed
3859+# in the related pages index. If set to NO, only the current project's
3860+# pages will be listed.
3861+
3862+EXTERNAL_PAGES = YES
3863+
3864 # The PERL_PATH should be the absolute path and name of the perl script
3865 # interpreter (i.e. the result of `which perl').
3866
3867@@ -1698,7 +1808,7 @@
3868 # the class node. If there are many fields or methods and many nodes the
3869 # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
3870 # threshold limits the number of items for each type to make the size more
3871-# managable. Set this to 0 for no limit. Note that the threshold may be
3872+# manageable. Set this to 0 for no limit. Note that the threshold may be
3873 # exceeded by 50% before the limit is enforced.
3874
3875 UML_LIMIT_NUM_FIELDS = 10
3876
3877=== modified file 'doc/component_reports.md'
3878--- doc/component_reports.md 2013-11-06 03:17:35 +0000
3879+++ doc/component_reports.md 2013-11-25 03:07:43 +0000
3880@@ -24,7 +24,7 @@
3881 legacy-input-report | log
3882 msg-processor-report | log,lttng
3883 session-mediator-report | log
3884-surfaces-report | log
3885+scene-report | log
3886
3887 For example, to enable the LTTng input report, one could either use the
3888 `--input-report=lttng` command-line option to the server, or set the
3889@@ -40,6 +40,7 @@
3890 Report | Handlers
3891 ------------------- | --------
3892 rpc-report | log,lttng
3893+input-receiver | log
3894
3895 For example, to enable the logging RPC report, one should set the
3896 `MIR_CLIENT_RPC_REPORT=log` environment variable.
3897
3898=== modified file 'doc/installing_prebuilt_on_pc.md'
3899--- doc/installing_prebuilt_on_pc.md 2013-11-06 03:17:35 +0000
3900+++ doc/installing_prebuilt_on_pc.md 2013-11-25 03:07:43 +0000
3901@@ -4,7 +4,12 @@
3902 Install Ubuntu 13.10 or later if you haven't done so already. Uninstall any
3903 proprietary drivers (-nvidia, -fglrx) and reboot on the FOSS drivers.
3904
3905-Install Mir:
3906+Install Mir in Ubuntu 13.10:
3907
3908 sudo apt-get update
3909 sudo apt-get install mir-demos unity-system-compositor
3910+
3911+Install Mir in Ubuntu 14.04 or later:
3912+
3913+ sudo apt-get update
3914+ sudo apt-get install mir-demos ubuntu-desktop-mir
3915
3916=== modified file 'doc/using_mir_on_pc.md'
3917--- doc/using_mir_on_pc.md 2013-11-06 03:17:35 +0000
3918+++ doc/using_mir_on_pc.md 2013-11-25 03:07:43 +0000
3919@@ -31,12 +31,14 @@
3920 include lightdm, Mesa and the Xorg drivers). The easiest way is to run Ubuntu
3921 13.10 or later.
3922
3923-If you have installed unity-system-compositor it will have created a file in
3924-/etc/lightdm/lightdm.conf.d/10-unity-system-compositor.conf to run XMir. If you
3925-have build from source, to run X sessions under Mir, with Mir acting as the
3926-system compositor, create the file
3927-/etc/lightdm/lightdm.conf.d/10-unity-system-compositor.conf to look to look like
3928-this:
3929+If you are running Ubuntu 13.10, additionally install unity-system-compositor.
3930+If you are running Ubuntu 14.04 or later, instead install ubuntu-desktop-mir.
3931+These packages will install dependencies you need and will create a file in
3932+/etc/lightdm/lightdm.conf.d/10-unity-system-compositor.conf.
3933+
3934+If you have instead built from source, to set up the system compositor, create
3935+/etc/lightdm/lightdm.conf.d/10-unity-system-compositor.conf yourself and make
3936+it look like this:
3937
3938 [SeatDefaults]
3939 type=unity
3940
3941=== modified file 'examples/CMakeLists.txt'
3942--- examples/CMakeLists.txt 2013-09-23 13:37:44 +0000
3943+++ examples/CMakeLists.txt 2013-11-25 03:07:43 +0000
3944@@ -114,6 +114,7 @@
3945 target_link_libraries(mir_demo_standalone_render_surfaces
3946 mirserver
3947 mirshell
3948+ mirsharedgeometry
3949 ${Boost_LIBRARIES}
3950 )
3951
3952
3953=== modified file 'examples/buffer_render_target.cpp'
3954--- examples/buffer_render_target.cpp 2013-08-28 03:41:48 +0000
3955+++ examples/buffer_render_target.cpp 2013-11-25 03:07:43 +0000
3956@@ -27,7 +27,7 @@
3957 namespace mt = mir::tools;
3958
3959 mt::BufferRenderTarget::BufferRenderTarget(mg::Buffer& buffer)
3960- : buffer(buffer)
3961+ : buffer(buffer), old_fbo(), old_viewport()
3962 {
3963 /*
3964 * With the new lazy buffer allocation method, we may be executing inside
3965@@ -35,12 +35,14 @@
3966 * we change...
3967 */
3968 glGetIntegerv(GL_VIEWPORT, old_viewport);
3969+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_fbo);
3970 resources.setup(buffer);
3971 }
3972
3973 mt::BufferRenderTarget::~BufferRenderTarget()
3974 {
3975 glFinish();
3976+ glBindFramebuffer(GL_FRAMEBUFFER, old_fbo);
3977 glViewport(old_viewport[0], old_viewport[1],
3978 old_viewport[2], old_viewport[3]);
3979 }
3980
3981=== modified file 'examples/buffer_render_target.h'
3982--- examples/buffer_render_target.h 2013-08-28 03:41:48 +0000
3983+++ examples/buffer_render_target.h 2013-11-25 03:07:43 +0000
3984@@ -58,6 +58,7 @@
3985
3986 Resources resources;
3987 mir::graphics::Buffer& buffer;
3988+ GLint old_fbo;
3989 GLint old_viewport[4];
3990 };
3991
3992
3993=== modified file 'examples/demo-inprocess-surface-client/inprocess_egl_client.cpp'
3994--- examples/demo-inprocess-surface-client/inprocess_egl_client.cpp 2013-11-06 03:17:35 +0000
3995+++ examples/demo-inprocess-surface-client/inprocess_egl_client.cpp 2013-11-25 03:07:43 +0000
3996@@ -21,7 +21,7 @@
3997
3998 #include "mir/main_loop.h"
3999 #include "mir/shell/focus_controller.h"
4000-#include "mir/shell/surface.h"
4001+#include "mir/frontend/surface.h"
4002 #include "mir/shell/surface_creation_parameters.h"
4003 #include "mir/shell/session.h"
4004 #include "mir/frontend/session.h"
4005@@ -47,7 +47,6 @@
4006 #include <signal.h>
4007
4008 namespace mf = mir::frontend;
4009-namespace mc = mir::compositor;
4010 namespace msh = mir::shell;
4011 namespace mg = mir::graphics;
4012 namespace me = mir::examples;
4013
4014=== modified file 'examples/demo-shell/demo_shell.cpp'
4015--- examples/demo-shell/demo_shell.cpp 2013-11-06 03:17:35 +0000
4016+++ examples/demo-shell/demo_shell.cpp 2013-11-25 03:07:43 +0000
4017@@ -24,7 +24,6 @@
4018
4019 #include "mir/run_mir.h"
4020 #include "mir/report_exception.h"
4021-#include "mir/shell/session_container.h"
4022 #include "mir/graphics/display.h"
4023 #include "mir/input/composite_event_filter.h"
4024
4025
4026=== modified file 'examples/demo-shell/window_manager.cpp'
4027--- examples/demo-shell/window_manager.cpp 2013-11-06 03:17:35 +0000
4028+++ examples/demo-shell/window_manager.cpp 2013-11-25 03:07:43 +0000
4029@@ -14,6 +14,7 @@
4030 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4031 *
4032 * Authored by: Robert Carr <robert.carr@canonical.com>
4033+ * Daniel van Vugt <daniel.van.vugt@canonical.com>
4034 */
4035
4036 #include "window_manager.h"
4037@@ -29,6 +30,7 @@
4038
4039 #include <cassert>
4040 #include <cstdlib>
4041+#include <cmath>
4042
4043 namespace me = mir::examples;
4044 namespace msh = mir::shell;
4045@@ -41,7 +43,7 @@
4046 }
4047
4048 me::WindowManager::WindowManager()
4049- : max_fingers(0)
4050+ : old_pinch_diam(0.0f), max_fingers(0)
4051 {
4052 }
4053
4054@@ -60,6 +62,9 @@
4055 compositor = cptor;
4056 }
4057
4058+namespace
4059+{
4060+
4061 mir::geometry::Point average_pointer(MirMotionEvent const& motion)
4062 {
4063 using namespace mir;
4064@@ -79,6 +84,36 @@
4065 return Point{x, y};
4066 }
4067
4068+float measure_pinch(MirMotionEvent const& motion,
4069+ mir::geometry::Displacement& dir)
4070+{
4071+ int count = static_cast<int>(motion.pointer_count);
4072+ int max = 0;
4073+
4074+ for (int i = 0; i < count; i++)
4075+ {
4076+ for (int j = 0; j < i; j++)
4077+ {
4078+ int dx = motion.pointer_coordinates[i].x -
4079+ motion.pointer_coordinates[j].x;
4080+ int dy = motion.pointer_coordinates[i].y -
4081+ motion.pointer_coordinates[j].y;
4082+
4083+ int sqr = dx*dx + dy*dy;
4084+
4085+ if (sqr > max)
4086+ {
4087+ max = sqr;
4088+ dir = mir::geometry::Displacement{dx, dy};
4089+ }
4090+ }
4091+ }
4092+
4093+ return sqrtf(max); // return pinch diameter
4094+}
4095+
4096+} // namespace
4097+
4098 bool me::WindowManager::handle(MirEvent const& event)
4099 {
4100 // TODO: Fix android configuration and remove static hack ~racarr
4101@@ -87,6 +122,8 @@
4102 assert(display);
4103 assert(compositor);
4104
4105+ bool handled = false;
4106+
4107 if (event.key.type == mir_event_type_key &&
4108 event.key.action == mir_key_action_down)
4109 {
4110@@ -148,22 +185,73 @@
4111 (event.motion.modifiers & mir_key_modifier_alt ||
4112 fingers >= 3))
4113 {
4114+ geometry::Displacement pinch_dir;
4115+ auto pinch_diam =
4116+ measure_pinch(event.motion, pinch_dir);
4117+
4118 // Start of a gesture: When the latest finger/button goes down
4119 if (action == mir_motion_action_down ||
4120 action == mir_motion_action_pointer_down)
4121 {
4122- relative_click = cursor - surf->top_left();
4123 click = cursor;
4124- }
4125- else if (event.motion.action == mir_motion_action_move)
4126- { // Movement is happening with one or more fingers/button down
4127- geometry::Point abs = cursor - relative_click;
4128- if (max_fingers <= 3) // Avoid accidental movement
4129- {
4130- surf->move_to(abs);
4131- return true;
4132- }
4133- }
4134+ handled = true;
4135+ }
4136+ else if (event.motion.action == mir_motion_action_move &&
4137+ max_fingers <= 3) // Avoid accidental movement
4138+ {
4139+ geometry::Displacement drag = cursor - old_cursor;
4140+
4141+ if (event.motion.button_state ==
4142+ mir_motion_button_tertiary)
4143+ { // Resize by mouse middle button
4144+ int width = old_size.width.as_int() +
4145+ drag.dx.as_int();
4146+ int height = old_size.height.as_int() +
4147+ drag.dy.as_int();
4148+ if (width <= 0) width = 1;
4149+ if (height <= 0) height = 1;
4150+ surf->resize({width, height});
4151+ }
4152+ else
4153+ { // Move surface (by mouse or 3 fingers)
4154+ surf->move_to(old_pos + drag);
4155+ }
4156+
4157+ if (fingers == 3)
4158+ { // Resize by pinch/zoom
4159+ float diam_delta = pinch_diam - old_pinch_diam;
4160+ /*
4161+ * Resize vector (dx,dy) has length=diam_delta and
4162+ * direction=pinch_dir, so solve for (dx,dy)...
4163+ */
4164+ float lenlen = diam_delta * diam_delta;
4165+ int x = pinch_dir.dx.as_int();
4166+ int y = pinch_dir.dy.as_int();
4167+ int xx = x * x;
4168+ int yy = y * y;
4169+ int xxyy = xx + yy;
4170+ int dx = sqrtf(lenlen * xx / xxyy);
4171+ int dy = sqrtf(lenlen * yy / xxyy);
4172+ if (diam_delta < 0.0f)
4173+ {
4174+ dx = -dx;
4175+ dy = -dy;
4176+ }
4177+
4178+ int width = old_size.width.as_int() + dx;
4179+ int height = old_size.height.as_int() + dy;
4180+ if (width <= 0) width = 1;
4181+ if (height <= 0) height = 1;
4182+ surf->resize({width, height});
4183+ }
4184+
4185+ handled = true;
4186+ }
4187+
4188+ old_pos = surf->top_left();
4189+ old_size = surf->size();
4190+ old_pinch_diam = pinch_diam;
4191+ old_cursor = cursor;
4192 }
4193 }
4194
4195@@ -173,9 +261,9 @@
4196 if (abs(dir.dx.as_int()) >= min_swipe_distance)
4197 {
4198 focus_controller->focus_next();
4199- return true;
4200+ handled = true;
4201 }
4202 }
4203 }
4204- return false;
4205+ return handled;
4206 }
4207
4208=== modified file 'examples/demo-shell/window_manager.h'
4209--- examples/demo-shell/window_manager.h 2013-11-06 03:17:35 +0000
4210+++ examples/demo-shell/window_manager.h 2013-11-25 03:07:43 +0000
4211@@ -21,6 +21,7 @@
4212
4213 #include "mir/input/event_filter.h"
4214 #include "mir/geometry/displacement.h"
4215+#include "mir/geometry/size.h"
4216
4217 #include <memory>
4218
4219@@ -62,8 +63,11 @@
4220 std::shared_ptr<graphics::Display> display;
4221 std::shared_ptr<compositor::Compositor> compositor;
4222
4223- geometry::Displacement relative_click; // Click location in window space
4224- geometry::Point click; // Click location in screen space
4225+ geometry::Point click;
4226+ geometry::Point old_pos;
4227+ geometry::Point old_cursor;
4228+ geometry::Size old_size;
4229+ float old_pinch_diam;
4230 int max_fingers; // Maximum number of fingers touched during gesture
4231 };
4232
4233
4234=== modified file 'examples/demo_input_filter.cpp'
4235--- examples/demo_input_filter.cpp 2013-08-28 03:41:48 +0000
4236+++ examples/demo_input_filter.cpp 2013-11-25 03:07:43 +0000
4237@@ -32,6 +32,21 @@
4238
4239 struct PrintingEventFilter : public mi::EventFilter
4240 {
4241+ void print_motion_event(MirMotionEvent const& ev)
4242+ {
4243+ std::cout << "Motion Event time=" << ev.event_time
4244+ << " pointer_count=" << ev.pointer_count << std::endl;
4245+
4246+ for (size_t i = 0; i < ev.pointer_count; ++i)
4247+ {
4248+ std::cout << " "
4249+ << " id=" << ev.pointer_coordinates[i].id
4250+ << " pos=(" << ev.pointer_coordinates[i].x << ", " << ev.pointer_coordinates[i].y << ")"
4251+ << std::endl;
4252+ }
4253+ std::cout << "----------------" << std::endl << std::endl;
4254+ }
4255+
4256 bool handle(MirEvent const& ev) override
4257 {
4258 // TODO: Enhance printing
4259@@ -42,8 +57,7 @@
4260 }
4261 else if (ev.type == mir_event_type_motion)
4262 {
4263- std::cout << "Handling motion event (time, pointer0_x, pointer0_y): " << ev.motion.event_time << " "
4264- << ev.motion.pointer_coordinates[0].x << " " << ev.motion.pointer_coordinates[0].y << std::endl;
4265+ print_motion_event(ev.motion);
4266 }
4267 return false;
4268 }
4269@@ -56,7 +70,7 @@
4270 event_filter(std::make_shared<PrintingEventFilter>())
4271 {
4272 }
4273-
4274+
4275 std::shared_ptr<mi::CompositeEventFilter> the_composite_event_filter() override
4276 {
4277 auto composite_filter = ServerConfiguration::the_composite_event_filter();
4278@@ -69,10 +83,18 @@
4279
4280 }
4281
4282+
4283+#include <std/MirLog.h>
4284+void my_write_to_log(int /*prio*/, char const* buffer)
4285+{
4286+ printf("%s\n", buffer);
4287+}
4288+
4289 int main(int argc, char const* argv[])
4290 try
4291 {
4292 DemoServerConfiguration config(argc, argv);
4293+ mir::write_to_log = my_write_to_log;
4294
4295 mir::run_mir(config, [](mir::DisplayServer&) {/* empty init */});
4296 return 0;
4297
4298=== modified file 'examples/eglapp.c'
4299--- examples/eglapp.c 2013-10-07 09:21:27 +0000
4300+++ examples/eglapp.c 2013-11-25 03:07:43 +0000
4301@@ -23,6 +23,7 @@
4302 #include <signal.h>
4303 #include <time.h>
4304 #include <EGL/egl.h>
4305+#include <GLES2/gl2.h>
4306
4307 #include <xkbcommon/xkbcommon-keysyms.h>
4308
4309@@ -75,6 +76,7 @@
4310 time_t now = time(NULL);
4311 time_t dtime;
4312 int dcount;
4313+ EGLint width, height;
4314
4315 if (!running)
4316 return;
4317@@ -90,6 +92,14 @@
4318 lasttime = now;
4319 lastcount = count;
4320 }
4321+
4322+ /* This is one way to handle window resizing. But in future it would be
4323+ better to have resize events coming from the server */
4324+ if (eglQuerySurface(egldisplay, eglsurface, EGL_WIDTH, &width) &&
4325+ eglQuerySurface(egldisplay, eglsurface, EGL_HEIGHT, &height))
4326+ {
4327+ glViewport(0, 0, width, height);
4328+ }
4329 }
4330
4331 static void mir_eglapp_handle_input(MirSurface* surface, MirEvent const* ev, void* context)
4332@@ -300,12 +310,11 @@
4333
4334 const MirDisplayMode *mode = &output->modes[output->current_mode];
4335
4336- const unsigned int max_formats = 10;
4337- unsigned int format[max_formats];
4338+ unsigned int format[mir_pixel_formats];
4339 unsigned int nformats;
4340
4341 mir_connection_get_available_surface_formats(connection,
4342- format, max_formats, &nformats);
4343+ format, mir_pixel_formats, &nformats);
4344
4345 surfaceparm.pixel_format = format[0];
4346 for (unsigned int f = 0; f < nformats; f++)
4347@@ -322,18 +331,17 @@
4348 }
4349 }
4350
4351- printf("Connected to display: resolution (%dx%d), position(%dx%d), "
4352- "supports %d pixel formats\n",
4353+ printf("Current active output is %dx%d %+d%+d\n",
4354 mode->horizontal_resolution, mode->vertical_resolution,
4355- output->position_x, output->position_y,
4356- output->num_output_formats);
4357+ output->position_x, output->position_y);
4358
4359 surfaceparm.width = *width > 0 ? *width : mode->horizontal_resolution;
4360 surfaceparm.height = *height > 0 ? *height : mode->vertical_resolution;
4361
4362 mir_display_config_destroy(display_config);
4363
4364- printf("Using pixel format #%d\n", surfaceparm.pixel_format);
4365+ printf("Server supports %d of %d surface pixel formats. Using format: %d\n",
4366+ nformats, mir_pixel_formats, surfaceparm.pixel_format);
4367 unsigned int bpp = get_bpp(surfaceparm.pixel_format);
4368 EGLint attribs[] =
4369 {
4370
4371=== modified file 'examples/progressbar.c'
4372--- examples/progressbar.c 2013-08-27 08:52:43 +0000
4373+++ examples/progressbar.c 2013-11-25 03:07:43 +0000
4374@@ -33,6 +33,12 @@
4375 uint8_t r, g, b, a;
4376 } Color;
4377
4378+static const Color blue = {0, 0, 255, 255};
4379+static const Color white = {255, 255, 255, 255};
4380+
4381+static const Color *const foreground = &white;
4382+static const Color *const background = &blue;
4383+
4384 static volatile sig_atomic_t running = 1;
4385
4386 static void shutdown(int signum)
4387@@ -178,6 +184,7 @@
4388 MirGraphicsRegion backbuffer;
4389
4390 mir_surface_get_graphics_region(surface, &backbuffer);
4391+ clear_region(&backbuffer, background);
4392 copy_region(&backbuffer, canvas);
4393 mir_surface_swap_buffers_sync(surface);
4394 }
4395@@ -264,8 +271,6 @@
4396
4397 while (running)
4398 {
4399- static const Color background = {0, 0, 255, 255};
4400- static const Color foreground = {255, 255, 255, 255};
4401 static const int width = 8;
4402 static const int space = 1;
4403 const int grid = width + 2 * space;
4404@@ -275,11 +280,11 @@
4405 const int y = (t / row) * grid + space;
4406
4407 if (t % square == 0)
4408- clear_region(&canvas, &background);
4409+ clear_region(&canvas, background);
4410
4411 t = (t + 1) % square;
4412
4413- draw_box(&canvas, x, y, width, &foreground);
4414+ draw_box(&canvas, x, y, width, foreground);
4415
4416 redraw(surf, &canvas);
4417 usleep(sleep_usec);
4418
4419=== modified file 'examples/render_surfaces.cpp'
4420--- examples/render_surfaces.cpp 2013-11-06 03:17:35 +0000
4421+++ examples/render_surfaces.cpp 2013-11-25 03:07:43 +0000
4422@@ -27,8 +27,8 @@
4423 #include "mir/graphics/cursor.h"
4424 #include "mir/graphics/display.h"
4425 #include "mir/graphics/display_buffer.h"
4426-#include "mir/shell/surface_builder.h"
4427-#include "mir/surfaces/surface.h"
4428+#include "mir/shell/surface_factory.h"
4429+#include "mir/shell/surface.h"
4430 #include "mir/run_mir.h"
4431 #include "mir/report_exception.h"
4432
4433@@ -49,7 +49,7 @@
4434
4435 namespace mg = mir::graphics;
4436 namespace mc = mir::compositor;
4437-namespace ms = mir::surfaces;
4438+namespace ms = mir::scene;
4439 namespace mf = mir::frontend;
4440 namespace msh = mir::shell;
4441 namespace mi = mir::input;
4442@@ -185,13 +185,13 @@
4443 {
4444 public:
4445 Moveable() {}
4446- Moveable(ms::Surface& s, const geom::Size& display_size,
4447+ Moveable(std::shared_ptr<msh::Surface> const& s, const geom::Size& display_size,
4448 float dx, float dy, const glm::vec3& rotation_axis, float alpha_offset)
4449- : surface(&s), display_size(display_size),
4450- x{static_cast<float>(s.top_left().x.as_uint32_t())},
4451- y{static_cast<float>(s.top_left().y.as_uint32_t())},
4452- w{static_cast<float>(s.size().width.as_uint32_t())},
4453- h{static_cast<float>(s.size().height.as_uint32_t())},
4454+ : surface(s), display_size(display_size),
4455+ x{static_cast<float>(s->top_left().x.as_uint32_t())},
4456+ y{static_cast<float>(s->top_left().y.as_uint32_t())},
4457+ w{static_cast<float>(s->size().width.as_uint32_t())},
4458+ h{static_cast<float>(s->size().height.as_uint32_t())},
4459 dx{dx},
4460 dy{dy},
4461 rotation_axis{rotation_axis},
4462@@ -233,7 +233,7 @@
4463 }
4464
4465 private:
4466- ms::Surface* surface;
4467+ std::shared_ptr<msh::Surface> surface;
4468 geom::Size display_size;
4469 float x;
4470 float y;
4471@@ -387,7 +387,7 @@
4472 std::cout << "Rendering " << moveables.size() << " surfaces" << std::endl;
4473
4474 auto const display = the_display();
4475- auto const surface_builder = the_surface_builder();
4476+ auto const surface_factory = the_scene_surface_factory();
4477 /* TODO: Get proper configuration */
4478 geom::Rectangles view_area;
4479 display->for_each_display_buffer([&view_area](mg::DisplayBuffer const& db)
4480@@ -406,18 +406,20 @@
4481 int i = 0;
4482 for (auto& m : moveables)
4483 {
4484- std::shared_ptr<ms::Surface> s = surface_builder->create_surface(
4485+ auto const s = surface_factory->create_surface(
4486 nullptr,
4487 msh::a_surface().of_size(surface_size)
4488 .of_pixel_format(surface_pf)
4489- .of_buffer_usage(mg::BufferUsage::hardware)
4490- ).lock();
4491+ .of_buffer_usage(mg::BufferUsage::hardware),
4492+ mf::SurfaceId(), {});
4493
4494 /*
4495- * Let the system know that the surface is suitable for rendering
4496- * (i.e., that it contains buffers with valid contents).
4497+ * We call advance_client_buffer() twice so that the surface is
4498+ * considers the first buffer to be posted.
4499+ * (TODO There must be a better way!)
4500 */
4501- s->flag_for_render();
4502+ s->advance_client_buffer();
4503+ s->advance_client_buffer();
4504
4505 /*
4506 * Place each surface at a different starting location and give it a
4507@@ -427,7 +429,7 @@
4508 uint32_t const y = h * (0.5 + 0.25 * sin(i * angular_step)) - surface_side / 2.0;
4509
4510 s->move_to({x, y});
4511- m = Moveable(*s, display_size,
4512+ m = Moveable(s, display_size,
4513 cos(0.1f + i * M_PI / 6.0f) * w / 3.0f,
4514 sin(0.1f + i * M_PI / 6.0f) * h / 3.0f,
4515 glm::vec3{(i % 3 == 0) * 1.0f, (i % 3 == 1) * 1.0f, (i % 3 == 2) * 1.0f},
4516
4517=== modified file 'include/client/mir_toolkit/mir_client_library.h'
4518--- include/client/mir_toolkit/mir_client_library.h 2013-08-28 03:41:48 +0000
4519+++ include/client/mir_toolkit/mir_client_library.h 2013-11-25 03:07:43 +0000
4520@@ -207,7 +207,7 @@
4521 /**
4522 * Set the event handler to be called when events arrive for a surface.
4523 * \warning event_handler could be called from another thread. You must do
4524- * and locking appropriate to protect your data accessed in the
4525+ * any locking appropriate to protect your data accessed in the
4526 * callback. There is also a chance that different events will be
4527 * called back in different threads, for the same surface,
4528 * simultaneously.
4529
4530=== added file 'include/platform/mir/graphics/basic_platform.h'
4531--- include/platform/mir/graphics/basic_platform.h 1970-01-01 00:00:00 +0000
4532+++ include/platform/mir/graphics/basic_platform.h 2013-11-25 03:07:43 +0000
4533@@ -0,0 +1,45 @@
4534+/*
4535+ * Copyright © 2013 Canonical Ltd.
4536+ *
4537+ * This program is free software: you can redistribute it and/or modify it
4538+ * under the terms of the GNU Lesser General Public License version 3,
4539+ * as published by the Free Software Foundation.
4540+ *
4541+ * This program is distributed in the hope that it will be useful,
4542+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4543+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4544+ * GNU Lesser General Public License for more details.
4545+ *
4546+ * You should have received a copy of the GNU Lesser General Public License
4547+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4548+ *
4549+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
4550+ */
4551+
4552+#ifndef MIR_GRAPHICS_BASIC_PLATFORM_H_
4553+#define MIR_GRAPHICS_BASIC_PLATFORM_H_
4554+
4555+#include <EGL/egl.h>
4556+
4557+namespace mir
4558+{
4559+namespace graphics
4560+{
4561+
4562+class BasicPlatform
4563+{
4564+public:
4565+ virtual ~BasicPlatform() = default;
4566+
4567+ virtual EGLNativeDisplayType egl_native_display() const = 0;
4568+
4569+protected:
4570+ BasicPlatform() = default;
4571+ BasicPlatform(BasicPlatform const&) = delete;
4572+ BasicPlatform& operator=(BasicPlatform const&) = delete;
4573+};
4574+
4575+}
4576+}
4577+
4578+#endif /* MIR_GRAPHICS_BASIC_PLATFORM_H_ */
4579
4580=== modified file 'include/platform/mir/graphics/buffer_ipc_packer.h'
4581--- include/platform/mir/graphics/buffer_ipc_packer.h 2013-09-11 05:21:22 +0000
4582+++ include/platform/mir/graphics/buffer_ipc_packer.h 2013-11-25 03:07:43 +0000
4583@@ -20,6 +20,7 @@
4584 #define MIR_GRAPHICS_BUFFER_IPC_PACKER_H_
4585
4586 #include "mir/geometry/dimensions.h"
4587+#include "mir/geometry/size.h"
4588
4589 namespace mir
4590 {
4591@@ -34,6 +35,7 @@
4592 virtual void pack_data(int) = 0;
4593 virtual void pack_stride(geometry::Stride) = 0;
4594 virtual void pack_flags(unsigned int) = 0;
4595+ virtual void pack_size(geometry::Size const& size) = 0;
4596
4597 protected:
4598 BufferIPCPacker() {}
4599
4600=== modified file 'include/platform/mir/graphics/egl_resources.h'
4601--- include/platform/mir/graphics/egl_resources.h 2013-08-28 03:41:48 +0000
4602+++ include/platform/mir/graphics/egl_resources.h 2013-11-25 03:07:43 +0000
4603@@ -30,6 +30,8 @@
4604 {
4605 public:
4606 EGLContextStore(EGLDisplay egl_display, EGLContext egl_context);
4607+ EGLContextStore(EGLContextStore&&);
4608+
4609 ~EGLContextStore() noexcept;
4610
4611 operator EGLContext() const;
4612@@ -38,14 +40,18 @@
4613 EGLContextStore(EGLContextStore const&) = delete;
4614 EGLContextStore& operator=(EGLContextStore const&) = delete;
4615
4616- EGLDisplay const egl_display_;
4617- EGLContext const egl_context_;
4618+ EGLDisplay egl_display_;
4619+ EGLContext egl_context_;
4620 };
4621
4622 class EGLSurfaceStore
4623 {
4624 public:
4625+ enum AllowNoSurface { DisallowNoSurface, AllowNoSurface };
4626+ EGLSurfaceStore(EGLDisplay egl_display, EGLSurface egl_surface,
4627+ enum AllowNoSurface allow_no_surface);
4628 EGLSurfaceStore(EGLDisplay egl_display, EGLSurface egl_surface);
4629+ EGLSurfaceStore(EGLSurfaceStore&&);
4630
4631 ~EGLSurfaceStore() noexcept;
4632
4633@@ -55,8 +61,8 @@
4634 EGLSurfaceStore(EGLSurfaceStore const&) = delete;
4635 EGLSurfaceStore& operator=(EGLSurfaceStore const&) = delete;
4636
4637- EGLDisplay const egl_display_;
4638- EGLSurface const egl_surface_;
4639+ EGLDisplay egl_display_;
4640+ EGLSurface egl_surface_;
4641 };
4642
4643 }
4644
4645=== modified file 'include/platform/mir/graphics/native_platform.h'
4646--- include/platform/mir/graphics/native_platform.h 2013-10-23 09:33:59 +0000
4647+++ include/platform/mir/graphics/native_platform.h 2013-11-25 03:07:43 +0000
4648@@ -52,7 +52,7 @@
4649
4650 virtual std::shared_ptr<InternalClient> create_internal_client() = 0;
4651
4652- virtual void fill_ipc_package(std::shared_ptr<BufferIPCPacker> const& packer, std::shared_ptr<Buffer> const& buffer) const = 0;
4653+ virtual void fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const = 0;
4654
4655 virtual ~NativePlatform() = default;
4656 NativePlatform(NativePlatform const&) = delete;
4657
4658=== modified file 'include/platform/mir/graphics/platform.h'
4659--- include/platform/mir/graphics/platform.h 2013-08-28 03:41:48 +0000
4660+++ include/platform/mir/graphics/platform.h 2013-11-25 03:07:43 +0000
4661@@ -20,6 +20,8 @@
4662 #ifndef MIR_GRAPHICS_PLATFORM_H_
4663 #define MIR_GRAPHICS_PLATFORM_H_
4664
4665+#include "basic_platform.h"
4666+
4667 #include <memory>
4668
4669 namespace mir
4670@@ -57,7 +59,7 @@
4671 * Interface to platform specific support for graphics operations.
4672 * \ingroup platform_enablement
4673 */
4674-class Platform
4675+class Platform : public BasicPlatform
4676 {
4677 public:
4678 Platform() = default;
4679@@ -97,8 +99,7 @@
4680 * \param [in] packer the object providing the packing functionality
4681 * \param [in] buffer the buffer to fill the IPC package for
4682 */
4683- virtual void fill_ipc_package(std::shared_ptr<BufferIPCPacker> const& packer,
4684- std::shared_ptr<graphics::Buffer> const& buffer) const = 0;
4685+ virtual void fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const = 0;
4686
4687 /**
4688 * Creates the in-process client support object.
4689
4690=== modified file 'include/server/mir/compositor/buffer_stream.h'
4691--- include/server/mir/compositor/buffer_stream.h 2013-11-06 03:17:35 +0000
4692+++ include/server/mir/compositor/buffer_stream.h 2013-11-25 03:07:43 +0000
4693@@ -47,6 +47,7 @@
4694 virtual std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() = 0;
4695 virtual geometry::PixelFormat get_stream_pixel_format() = 0;
4696 virtual geometry::Size stream_size() = 0;
4697+ virtual void resize(geometry::Size const& size) = 0;
4698 virtual void allow_framedropping(bool) = 0;
4699 virtual void force_requests_to_complete() = 0;
4700 };
4701
4702=== modified file 'include/server/mir/compositor/scene.h'
4703--- include/server/mir/compositor/scene.h 2013-11-06 03:17:35 +0000
4704+++ include/server/mir/compositor/scene.h 2013-11-25 03:07:43 +0000
4705@@ -75,7 +75,7 @@
4706 * Scene changes.
4707 *
4708 * The supplied callback should not directly or indirectly (e.g.,
4709- * by changing a property of a Renderable) change the state of
4710+ * by changing a property of a surface) change the state of
4711 * the Scene, otherwise a deadlock may occur.
4712 */
4713 virtual void set_change_callback(std::function<void()> const& f) = 0;
4714
4715=== modified file 'include/server/mir/default_configuration_options.h'
4716--- include/server/mir/default_configuration_options.h 2013-11-06 03:17:35 +0000
4717+++ include/server/mir/default_configuration_options.h 2013-11-25 03:07:43 +0000
4718@@ -35,12 +35,13 @@
4719 static char const* const display_report_opt;
4720 static char const* const legacy_input_report_opt;
4721 static char const* const connector_report_opt;
4722- static char const* const surfaces_report_opt;
4723+ static char const* const scene_report_opt;
4724 static char const* const input_report_opt;
4725 static char const* const host_socket_opt;
4726 static char const* const standalone_opt;
4727 static char const* const frontend_threads;
4728 static char const* const name_opt;
4729+ static char const* const offscreen_opt;
4730
4731 static char const* const glog;
4732 static char const* const glog_stderrthreshold;
4733
4734=== modified file 'include/server/mir/default_server_configuration.h'
4735--- include/server/mir/default_server_configuration.h 2013-11-06 03:17:35 +0000
4736+++ include/server/mir/default_server_configuration.h 2013-11-25 03:07:43 +0000
4737@@ -55,37 +55,36 @@
4738 namespace shell
4739 {
4740 class SurfaceFactory;
4741-class SurfaceBuilder;
4742 class SurfaceController;
4743 class InputTargeter;
4744-class SessionContainer;
4745 class FocusSetter;
4746-class FocusSequence;
4747 class PlacementStrategy;
4748 class SessionListener;
4749 class FocusController;
4750-class SessionManager;
4751-class PixelBuffer;
4752-class SnapshotStrategy;
4753 class DisplayLayout;
4754 class SurfaceConfigurator;
4755+}
4756+namespace time
4757+{
4758+class TimeSource;
4759+}
4760+namespace scene
4761+{
4762+class BroadcastingSessionEventSink;
4763+class BufferStreamFactory;
4764 class MediatingDisplayChanger;
4765+class PixelBuffer;
4766+class SessionContainer;
4767 class SessionEventSink;
4768 class SessionEventHandlerRegister;
4769-class BroadcastingSessionEventSink;
4770-}
4771-namespace time
4772-{
4773-class TimeSource;
4774-}
4775-namespace surfaces
4776-{
4777-class BufferStreamFactory;
4778+class SessionManager;
4779+class SnapshotStrategy;
4780+class SurfaceBuilder;
4781 class SurfaceStackModel;
4782 class SurfaceStack;
4783 class SurfaceController;
4784 class InputRegistrar;
4785-class SurfacesReport;
4786+class SceneReport;
4787 }
4788 namespace graphics
4789 {
4790@@ -186,40 +185,32 @@
4791 * configurable interfaces for modifying shell
4792 * @{ */
4793 virtual std::shared_ptr<shell::SurfaceFactory> the_shell_surface_factory();
4794- virtual std::shared_ptr<shell::SessionContainer> the_shell_session_container();
4795+ virtual std::shared_ptr<shell::SurfaceFactory> the_scene_surface_factory();
4796 virtual std::shared_ptr<shell::FocusSetter> the_shell_focus_setter();
4797- virtual std::shared_ptr<shell::FocusSequence> the_shell_focus_sequence();
4798 virtual std::shared_ptr<shell::PlacementStrategy> the_shell_placement_strategy();
4799 virtual std::shared_ptr<shell::SessionListener> the_shell_session_listener();
4800- virtual std::shared_ptr<shell::PixelBuffer> the_shell_pixel_buffer();
4801- virtual std::shared_ptr<shell::SnapshotStrategy> the_shell_snapshot_strategy();
4802 virtual std::shared_ptr<shell::DisplayLayout> the_shell_display_layout();
4803 virtual std::shared_ptr<shell::SurfaceConfigurator> the_shell_surface_configurator();
4804- virtual std::shared_ptr<shell::SessionEventSink> the_shell_session_event_sink();
4805- virtual std::shared_ptr<shell::SessionEventHandlerRegister> the_shell_session_event_handler_register();
4806 virtual std::shared_ptr<shell::SurfaceController> the_shell_surface_controller();
4807 /** @} */
4808
4809- /** @name shell configuration - dependencies
4810- * dependencies of shell on the rest of the Mir
4811- * @{ */
4812- virtual std::shared_ptr<shell::SurfaceBuilder> the_surface_builder();
4813- virtual std::shared_ptr<surfaces::SurfaceController> the_surface_controller();
4814-
4815- /** @} */
4816-
4817-
4818- /** @name surfaces configuration - customization
4819- * configurable interfaces for modifying surfaces
4820- * @{ */
4821- virtual std::shared_ptr<surfaces::SurfaceStackModel> the_surface_stack_model();
4822- virtual std::shared_ptr<surfaces::SurfacesReport> the_surfaces_report();
4823- /** @} */
4824-
4825- /** @name surfaces configuration - dependencies
4826- * dependencies of surfaces on the rest of the Mir
4827- * @{ */
4828- virtual std::shared_ptr<surfaces::BufferStreamFactory> the_buffer_stream_factory();
4829+ /** @name internal scene configuration
4830+ * builder functions used in the default implementation.
4831+ * The interfaces returned are not published, so the functions are only useful in tests
4832+ * @{ */
4833+ virtual std::shared_ptr<scene::PixelBuffer> the_pixel_buffer();
4834+ virtual std::shared_ptr<scene::SnapshotStrategy> the_snapshot_strategy();
4835+ virtual std::shared_ptr<scene::SessionContainer> the_session_container();
4836+ virtual std::shared_ptr<scene::SessionEventSink> the_session_event_sink();
4837+ virtual std::shared_ptr<scene::SessionEventHandlerRegister> the_session_event_handler_register();
4838+ virtual std::shared_ptr<scene::SurfaceStackModel> the_surface_stack_model();
4839+ /** @} */
4840+
4841+ /** @name scene configuration - dependencies
4842+ * dependencies of scene on the rest of the Mir
4843+ * @{ */
4844+ virtual std::shared_ptr<scene::BufferStreamFactory> the_buffer_stream_factory();
4845+ virtual std::shared_ptr<scene::SceneReport> the_scene_report();
4846 /** @} */
4847
4848
4849@@ -227,7 +218,7 @@
4850 * @{ */
4851 virtual std::shared_ptr<input::InputReport> the_input_report();
4852 virtual std::shared_ptr<input::CompositeEventFilter> the_composite_event_filter();
4853- virtual std::shared_ptr<surfaces::InputRegistrar> the_input_registrar();
4854+ virtual std::shared_ptr<scene::InputRegistrar> the_input_registrar();
4855 virtual std::shared_ptr<shell::InputTargeter> the_input_targeter();
4856 virtual std::shared_ptr<input::CursorListener> the_cursor_listener();
4857 virtual std::shared_ptr<input::InputRegion> the_input_region();
4858@@ -241,20 +232,15 @@
4859
4860 virtual std::shared_ptr<time::TimeSource> the_time_source();
4861
4862- virtual std::shared_ptr<shell::SessionManager> the_session_manager();
4863-
4864 protected:
4865 using DefaultConfigurationOptions::the_options;
4866 using DefaultConfigurationOptions::add_options;
4867 using DefaultConfigurationOptions::parse_options;
4868
4869 virtual std::shared_ptr<input::InputChannelFactory> the_input_channel_factory();
4870- virtual std::shared_ptr<shell::MediatingDisplayChanger> the_mediating_display_changer();
4871- virtual std::shared_ptr<shell::BroadcastingSessionEventSink> the_broadcasting_session_event_sink();
4872+ virtual std::shared_ptr<scene::MediatingDisplayChanger> the_mediating_display_changer();
4873
4874 CachedPtr<frontend::Connector> connector;
4875- CachedPtr<shell::SessionManager> session_manager;
4876-
4877
4878 CachedPtr<input::InputConfiguration> input_configuration;
4879
4880@@ -262,7 +248,7 @@
4881 CachedPtr<input::CompositeEventFilter> composite_event_filter;
4882 CachedPtr<input::InputManager> input_manager;
4883 CachedPtr<input::InputRegion> input_region;
4884- CachedPtr<surfaces::InputRegistrar> input_registrar;
4885+ CachedPtr<scene::InputRegistrar> input_registrar;
4886 CachedPtr<shell::InputTargeter> input_targeter;
4887 CachedPtr<input::CursorListener> cursor_listener;
4888 CachedPtr<graphics::Platform> graphics_platform;
4889@@ -279,17 +265,17 @@
4890 CachedPtr<frontend::SessionCreator> session_creator;
4891 CachedPtr<compositor::RendererFactory> renderer_factory;
4892 CachedPtr<compositor::BufferStreamFactory> buffer_stream_factory;
4893- CachedPtr<surfaces::SurfaceStack> surface_stack;
4894- CachedPtr<surfaces::SurfacesReport> surfaces_report;
4895+ CachedPtr<scene::SurfaceStack> surface_stack;
4896+ CachedPtr<scene::SceneReport> scene_report;
4897
4898 CachedPtr<shell::SurfaceFactory> shell_surface_factory;
4899- CachedPtr<shell::SessionContainer> shell_session_container;
4900+ CachedPtr<shell::SurfaceFactory> scene_surface_factory;
4901+ CachedPtr<scene::SessionContainer> session_container;
4902 CachedPtr<shell::FocusSetter> shell_focus_setter;
4903- CachedPtr<shell::FocusSequence> shell_focus_sequence;
4904 CachedPtr<shell::PlacementStrategy> shell_placement_strategy;
4905 CachedPtr<shell::SessionListener> shell_session_listener;
4906- CachedPtr<shell::PixelBuffer> shell_pixel_buffer;
4907- CachedPtr<shell::SnapshotStrategy> shell_snapshot_strategy;
4908+ CachedPtr<scene::PixelBuffer> pixel_buffer;
4909+ CachedPtr<scene::SnapshotStrategy> snapshot_strategy;
4910 CachedPtr<shell::DisplayLayout> shell_display_layout;
4911 CachedPtr<shell::SurfaceConfigurator> shell_surface_configurator;
4912 CachedPtr<compositor::DisplayBufferCompositorFactory> display_buffer_compositor_factory;
4913@@ -297,26 +283,35 @@
4914 CachedPtr<compositor::Compositor> compositor;
4915 CachedPtr<logging::Logger> logger;
4916 CachedPtr<graphics::DisplayReport> display_report;
4917- CachedPtr<surfaces::SurfaceController> surface_controller;
4918 CachedPtr<time::TimeSource> time_source;
4919 CachedPtr<MainLoop> main_loop;
4920 CachedPtr<ServerStatusListener> server_status_listener;
4921 CachedPtr<graphics::DisplayConfigurationPolicy> display_configuration_policy;
4922 CachedPtr<graphics::nested::HostConnection> host_connection;
4923- CachedPtr<input::NestedInputRelay> nested_input_relay;
4924- CachedPtr<shell::MediatingDisplayChanger> mediating_display_changer;
4925- CachedPtr<shell::BroadcastingSessionEventSink> broadcasting_session_event_sink;
4926+ CachedPtr<scene::MediatingDisplayChanger> mediating_display_changer;
4927
4928 private:
4929 std::shared_ptr<input::EventFilter> const default_filter;
4930-
4931 // the communications interface to use
4932 virtual std::shared_ptr<frontend::ProtobufIpcFactory> the_ipc_factory(
4933 std::shared_ptr<frontend::Shell> const& shell,
4934 std::shared_ptr<graphics::GraphicBufferAllocator> const& allocator);
4935
4936 virtual std::string the_socket_file() const;
4937- std::shared_ptr<input::NestedInputRelay> the_nested_input_relay();
4938+
4939+ // The following caches and factory functions are internal to the
4940+ // default implementations of corresponding the Mir components
4941+ CachedPtr<scene::BroadcastingSessionEventSink> broadcasting_session_event_sink;
4942+ CachedPtr<input::NestedInputRelay> nested_input_relay;
4943+ CachedPtr<scene::SurfaceController> surface_controller;
4944+ CachedPtr<scene::SessionManager> session_manager;
4945+
4946+ std::shared_ptr<scene::BroadcastingSessionEventSink> the_broadcasting_session_event_sink();
4947+ std::shared_ptr<input::NestedInputRelay> the_nested_input_relay();
4948+ std::shared_ptr<scene::SessionManager> the_session_manager();
4949+ std::shared_ptr<scene::SurfaceBuilder> the_surface_builder();
4950+ std::shared_ptr<scene::SurfaceController> the_surface_controller();
4951+ std::function<void()> force_threads_to_unblock_callback();
4952 };
4953 }
4954
4955
4956=== modified file 'include/server/mir/frontend/shell.h'
4957--- include/server/mir/frontend/shell.h 2013-08-28 03:41:48 +0000
4958+++ include/server/mir/frontend/shell.h 2013-11-25 03:07:43 +0000
4959@@ -36,7 +36,7 @@
4960 class Shell
4961 {
4962 public:
4963- virtual ~Shell() {}
4964+ virtual ~Shell() = default;
4965
4966 virtual std::shared_ptr<Session> open_session(
4967 std::string const& name, std::shared_ptr<EventSink> const& sink) = 0;
4968@@ -44,7 +44,7 @@
4969
4970 virtual SurfaceId create_surface_for(std::shared_ptr<Session> const& session,
4971 shell::SurfaceCreationParameters const& params) = 0;
4972-
4973+
4974 virtual void handle_surface_created(std::shared_ptr<Session> const& session) = 0;
4975
4976 protected:
4977
4978=== modified file 'include/server/mir/frontend/surface.h'
4979--- include/server/mir/frontend/surface.h 2013-10-15 08:53:10 +0000
4980+++ include/server/mir/frontend/surface.h 2013-11-25 03:07:43 +0000
4981@@ -25,6 +25,8 @@
4982 #include "mir/geometry/size.h"
4983 #include "mir_toolkit/common.h"
4984
4985+#include <glm/glm.hpp>
4986+
4987 #include <memory>
4988
4989 namespace mir
4990@@ -55,12 +57,7 @@
4991 virtual geometry::Size size() const = 0;
4992 virtual geometry::PixelFormat pixel_format() const = 0;
4993
4994- /// Submit the current client buffer, return the next client buffer
4995- ///
4996- /// \param [out] need_ipc: True if the buffer content must be sent via IPC
4997- /// False if only the buffer's ID must be sent.
4998- /// \returns The next client buffer
4999- virtual std::shared_ptr<graphics::Buffer> advance_client_buffer(bool& need_full_ipc) = 0;
5000+ virtual std::shared_ptr<graphics::Buffer> advance_client_buffer() = 0;
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches