Mir

Merge lp:~raof/mir/fix-1253876 into lp:mir/0.1

Proposed by Chris Halse Rogers
Status: Superseded
Proposed branch: lp:~raof/mir/fix-1253876
Merge into: lp:mir/0.1
Diff against target: 28040 lines (+9686/-6876)
375 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)
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 (+150/-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 (+64/-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:~raof/mir/fix-1253876
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Daniel van Vugt Needs Resubmitting
Review via email: mp+196222@code.launchpad.net

Commit message

GBMDisplayTest: Timeout and fail the test rather than hanging indefinitely

Description of the change

GBMDisplayTest: Timeout and fail the test rather than hanging indefinitely

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Wrong diff, wrong target branch :)

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '3rd_party/android-input/android/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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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-22 04:49:56 +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 'debian/control'
3221--- debian/control 2013-11-06 03:17:35 +0000
3222+++ debian/control 2013-11-22 04:49:56 +0000
3223@@ -69,7 +69,7 @@
3224 .
3225 Contains the protocol's definition files.
3226
3227-Package: libmirserver10
3228+Package: libmirserver11
3229 Section: libs
3230 Architecture: i386 amd64 armhf arm64
3231 Multi-Arch: same
3232@@ -115,7 +115,7 @@
3233 Architecture: i386 amd64 armhf arm64
3234 Multi-Arch: same
3235 Pre-Depends: ${misc:Pre-Depends}
3236-Depends: libmirserver10 (= ${binary:Version}),
3237+Depends: libmirserver11 (= ${binary:Version}),
3238 libmirprotobuf-dev (= ${binary:Version}),
3239 mircommon-dev (= ${binary:Version}),
3240 libglm-dev,
3241
3242=== renamed file 'debian/libmirserver10.install' => 'debian/libmirserver11.install'
3243--- debian/libmirserver10.install 2013-11-06 03:17:35 +0000
3244+++ debian/libmirserver11.install 2013-11-22 04:49:56 +0000
3245@@ -1,1 +1,1 @@
3246-usr/lib/*/libmirserver.so.10
3247+usr/lib/*/libmirserver.so.11
3248
3249=== modified file 'debian/rules' (properties changed: -x to +x)
3250=== modified file 'doc/Doxyfile.in'
3251--- doc/Doxyfile.in 2013-07-02 11:27:33 +0000
3252+++ doc/Doxyfile.in 2013-11-22 04:49:56 +0000
3253@@ -1,14 +1,16 @@
3254-# Doxyfile 1.8.1.2
3255+# Doxyfile 1.8.4
3256
3257 # This file describes the settings to be used by the documentation system
3258-# doxygen (www.doxygen.org) for a project
3259+# doxygen (www.doxygen.org) for a project.
3260 #
3261-# All text after a hash (#) is considered a comment and will be ignored
3262+# All text after a double hash (##) is considered a comment and is placed
3263+# in front of the TAG it is preceding .
3264+# All text after a hash (#) is considered a comment and will be ignored.
3265 # The format is:
3266 # TAG = value [value, ...]
3267 # For lists items can also be appended using:
3268 # TAG += value [value, ...]
3269-# Values that contain spaces should be placed between quotes (" ")
3270+# Values that contain spaces should be placed between quotes (" ").
3271
3272 #---------------------------------------------------------------------------
3273 # Project related configuration options
3274@@ -70,9 +72,9 @@
3275 # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
3276 # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
3277 # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
3278-# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
3279-# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
3280-# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
3281+# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian,
3282+# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic,
3283+# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
3284
3285 OUTPUT_LANGUAGE = English
3286
3287@@ -136,7 +138,9 @@
3288 # only done if one of the specified strings matches the left-hand part of
3289 # the path. The tag can be used to show relative paths in the file list.
3290 # If left blank the directory from which doxygen is run is used as the
3291-# path to strip.
3292+# path to strip. Note that you specify absolute paths here, but also
3293+# relative paths, which will be relative from the directory where doxygen is
3294+# started.
3295
3296 STRIP_FROM_PATH = @CMAKE_CURRENT_SOURCE_DIR@
3297
3298@@ -239,14 +243,15 @@
3299 OPTIMIZE_OUTPUT_VHDL = NO
3300
3301 # Doxygen selects the parser to use depending on the extension of the files it
3302-# parses. With this tag you can assign which parser to use for a given extension.
3303-# Doxygen has a built-in mapping, but you can override or extend it using this
3304-# tag. The format is ext=language, where ext is a file extension, and language
3305-# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
3306-# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
3307-# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
3308-# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
3309-# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
3310+# parses. With this tag you can assign which parser to use for a given
3311+# extension. Doxygen has a built-in mapping, but you can override or extend it
3312+# using this tag. The format is ext=language, where ext is a file extension,
3313+# and language is one of the parsers supported by doxygen: IDL, Java,
3314+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
3315+# C++. For instance to make doxygen treat .inc files as Fortran files (default
3316+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
3317+# that for custom extensions you also need to set FILE_PATTERNS otherwise the
3318+# files are not read by doxygen.
3319
3320 EXTENSION_MAPPING =
3321
3322@@ -259,6 +264,13 @@
3323
3324 MARKDOWN_SUPPORT = YES
3325
3326+# When enabled doxygen tries to link words that correspond to documented
3327+# classes, or namespaces to their corresponding documentation. Such a link can
3328+# be prevented in individual cases by by putting a % sign in front of the word
3329+# or globally by setting AUTOLINK_SUPPORT to NO.
3330+
3331+AUTOLINK_SUPPORT = YES
3332+
3333 # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
3334 # to include (a tag file for) the STL sources as input, then you should
3335 # set this tag to YES in order to let doxygen match functions declarations and
3336@@ -279,10 +291,10 @@
3337
3338 SIP_SUPPORT = NO
3339
3340-# For Microsoft's IDL there are propget and propput attributes to indicate getter
3341-# and setter methods for a property. Setting this option to YES (the default)
3342-# will make doxygen replace the get and set methods by a property in the
3343-# documentation. This will only work if the methods are indeed getting or
3344+# For Microsoft's IDL there are propget and propput attributes to indicate
3345+# getter and setter methods for a property. Setting this option to YES (the
3346+# default) will make doxygen replace the get and set methods by a property in
3347+# the documentation. This will only work if the methods are indeed getting or
3348 # setting a simple type. If this is not the case, or you want to show the
3349 # methods anyway, you should set this option to NO.
3350
3351@@ -311,11 +323,11 @@
3352 INLINE_GROUPED_CLASSES = NO
3353
3354 # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
3355-# unions with only public data fields will be shown inline in the documentation
3356-# of the scope in which they are defined (i.e. file, namespace, or group
3357-# documentation), provided this scope is documented. If set to NO (the default),
3358-# structs, classes, and unions are shown on a separate page (for HTML and Man
3359-# pages) or section (for LaTeX and RTF).
3360+# unions with only public data fields or simple typedef fields will be shown
3361+# inline in the documentation of the scope in which they are defined (i.e. file,
3362+# namespace, or group documentation), provided this scope is documented. If set
3363+# to NO (the default), structs, classes, and unions are shown on a separate
3364+# page (for HTML and Man pages) or section (for LaTeX and RTF).
3365
3366 INLINE_SIMPLE_STRUCTS = NO
3367
3368@@ -329,30 +341,14 @@
3369
3370 TYPEDEF_HIDES_STRUCT = NO
3371
3372-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
3373-# determine which symbols to keep in memory and which to flush to disk.
3374-# When the cache is full, less often used symbols will be written to disk.
3375-# For small to medium size projects (<1000 input files) the default value is
3376-# probably good enough. For larger projects a too small cache size can cause
3377-# doxygen to be busy swapping symbols to and from disk most of the time
3378-# causing a significant performance penalty.
3379-# If the system has enough physical memory increasing the cache will improve the
3380-# performance by keeping more symbols in memory. Note that the value works on
3381-# a logarithmic scale so increasing the size by one will roughly double the
3382-# memory usage. The cache size is given by this formula:
3383-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
3384-# corresponding to a cache size of 2^16 = 65536 symbols.
3385-
3386-SYMBOL_CACHE_SIZE = 0
3387-
3388-# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
3389-# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
3390-# their name and scope. Since this can be an expensive process and often the
3391-# same symbol appear multiple times in the code, doxygen keeps a cache of
3392-# pre-resolved symbols. If the cache is too small doxygen will become slower.
3393-# If the cache is too large, memory is wasted. The cache size is given by this
3394-# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
3395-# corresponding to a cache size of 2^16 = 65536 symbols.
3396+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
3397+# cache is used to resolve symbols given their name and scope. Since this can
3398+# be an expensive process and often the same symbol appear multiple times in
3399+# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too
3400+# small doxygen will become slower. If the cache is too large, memory is wasted.
3401+# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid
3402+# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536
3403+# symbols.
3404
3405 LOOKUP_CACHE_SIZE = 0
3406
3407@@ -363,7 +359,7 @@
3408 # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
3409 # documentation are documented, even if no documentation was available.
3410 # Private class members and static file members will be hidden unless
3411-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
3412+# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES
3413
3414 EXTRACT_ALL = YES
3415
3416@@ -544,7 +540,8 @@
3417 GENERATE_DEPRECATEDLIST= YES
3418
3419 # The ENABLED_SECTIONS tag can be used to enable conditional
3420-# documentation sections, marked by \if sectionname ... \endif.
3421+# documentation sections, marked by \if section-label ... \endif
3422+# and \cond section-label ... \endcond blocks.
3423
3424 ENABLED_SECTIONS =
3425
3426@@ -571,7 +568,8 @@
3427 SHOW_FILES = YES
3428
3429 # Set the SHOW_NAMESPACES tag to NO to disable the generation of the
3430-# Namespaces page. This will remove the Namespaces entry from the Quick Index
3431+# Namespaces page.
3432+# This will remove the Namespaces entry from the Quick Index
3433 # and from the Folder Tree View (if specified). The default is YES.
3434
3435 SHOW_NAMESPACES = YES
3436@@ -601,7 +599,8 @@
3437 # requires the bibtex tool to be installed. See also
3438 # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
3439 # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
3440-# feature you need bibtex and perl available in the search path.
3441+# feature you need bibtex and perl available in the search path. Do not use
3442+# file names with spaces, bibtex cannot handle them.
3443
3444 CITE_BIB_FILES =
3445
3446@@ -757,7 +756,11 @@
3447 # wildcard * is used, a substring. Examples: ANamespace, AClass,
3448 # AClass::ANamespace, ANamespace::*Test
3449
3450-EXCLUDE_SYMBOLS = android google mfd mgg mp
3451+EXCLUDE_SYMBOLS = android \
3452+ google \
3453+ mfd \
3454+ mgg \
3455+ mp
3456
3457 # The EXAMPLE_PATH tag can be used to specify one or more files or
3458 # directories that contain example code fragments that are included (see
3459@@ -790,14 +793,19 @@
3460 # by executing (via popen()) the command <filter> <input-file>, where <filter>
3461 # is the value of the INPUT_FILTER tag, and <input-file> is the name of an
3462 # input file. Doxygen will then use the output that the filter program writes
3463-# to standard output. If FILTER_PATTERNS is specified, this tag will be
3464-# ignored.
3465+# to standard output.
3466+# If FILTER_PATTERNS is specified, this tag will be ignored.
3467+# Note that the filter must not add or remove lines; it is applied before the
3468+# code is scanned, but not when the output code is generated. If lines are added
3469+# or removed, the anchors will not be placed correctly.
3470
3471 INPUT_FILTER =
3472
3473 # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
3474-# basis. Doxygen will compare the file name with each pattern and apply the
3475-# filter if there is a match. The filters are a list of the form:
3476+# basis.
3477+# Doxygen will compare the file name with each pattern and apply the
3478+# filter if there is a match.
3479+# The filters are a list of the form:
3480 # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
3481 # info on how filters are used. If FILTER_PATTERNS is empty or if
3482 # non of the patterns match the file name, INPUT_FILTER is applied.
3483@@ -818,6 +826,13 @@
3484
3485 FILTER_SOURCE_PATTERNS =
3486
3487+# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that
3488+# is part of the input, its contents will be placed on the main page
3489+# (index.html). This can be useful if you have a project on for instance GitHub
3490+# and want reuse the introduction page also for the doxygen output.
3491+
3492+USE_MDFILE_AS_MAINPAGE =
3493+
3494 #---------------------------------------------------------------------------
3495 # configuration options related to source browsing
3496 #---------------------------------------------------------------------------
3497@@ -855,7 +870,8 @@
3498 # If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
3499 # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
3500 # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
3501-# link to the source code. Otherwise they will link to the documentation.
3502+# link to the source code.
3503+# Otherwise they will link to the documentation.
3504
3505 REFERENCES_LINK_SOURCE = YES
3506
3507@@ -920,7 +936,7 @@
3508 # The HTML_HEADER tag can be used to specify a personal HTML header for
3509 # each generated HTML page. If it is left blank doxygen will generate a
3510 # standard header. Note that when using a custom header you are responsible
3511-# for the proper inclusion of any scripts and style sheets that doxygen
3512+# for the proper inclusion of any scripts and style sheets that doxygen
3513 # needs, which is dependent on the configuration options used.
3514 # It is advised to generate a default header using "doxygen -w html
3515 # header.html footer.html stylesheet.css YourConfigFile" and then modify
3516@@ -938,18 +954,27 @@
3517
3518 # The HTML_STYLESHEET tag can be used to specify a user-defined cascading
3519 # style sheet that is used by each HTML page. It can be used to
3520-# fine-tune the look of the HTML output. If the tag is left blank doxygen
3521-# will generate a default style sheet. Note that doxygen will try to copy
3522-# the style sheet file to the HTML output directory, so don't put your own
3523-# style sheet in the HTML output directory as well, or it will be erased!
3524+# fine-tune the look of the HTML output. If left blank doxygen will
3525+# generate a default style sheet. Note that it is recommended to use
3526+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
3527+# tag will in the future become obsolete.
3528
3529 HTML_STYLESHEET =
3530+
3531+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
3532+# user-defined cascading style sheet that is included after the standard
3533+# style sheets created by doxygen. Using this option one can overrule
3534+# certain style aspects. This is preferred over using HTML_STYLESHEET
3535+# since it does not replace the standard style sheet and is therefor more
3536+# robust against future updates. Doxygen will copy the style sheet file to
3537+# the output directory.
3538+
3539 HTML_EXTRA_STYLESHEET = @CMAKE_BINARY_DIR@/doc/extra.css
3540
3541 # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
3542 # other source files which should be copied to the HTML output directory. Note
3543 # that these files will be copied to the base HTML output directory. Use the
3544-# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
3545+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
3546 # files. In the HTML_STYLESHEET file, use the file name only. Also note that
3547 # the files will be copied as-is; there are no commands or markers available.
3548
3549@@ -1030,9 +1055,9 @@
3550
3551 DOCSET_BUNDLE_ID = org.doxygen.Project
3552
3553-# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
3554-# the documentation publisher. This should be a reverse domain-name style
3555-# string, e.g. com.mycompany.MyDocSet.documentation.
3556+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
3557+# identify the documentation publisher. This should be a reverse domain-name
3558+# style string, e.g. com.mycompany.MyDocSet.documentation.
3559
3560 DOCSET_PUBLISHER_ID = org.doxygen.Publisher
3561
3562@@ -1138,7 +1163,7 @@
3563 QHG_LOCATION =
3564
3565 # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
3566-# will be generated, which together with the HTML files, form an Eclipse help
3567+# will be generated, which together with the HTML files, form an Eclipse help
3568 # plugin. To install this plugin and make it available under the help contents
3569 # menu in Eclipse, the contents of the directory containing the HTML and XML
3570 # files needs to be copied into the plugins directory of eclipse. The name of
3571@@ -1217,13 +1242,21 @@
3572
3573 USE_MATHJAX = NO
3574
3575+# When MathJax is enabled you can set the default output format to be used for
3576+# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and
3577+# SVG. The default value is HTML-CSS, which is slower, but has the best
3578+# compatibility.
3579+
3580+MATHJAX_FORMAT = HTML-CSS
3581+
3582 # When MathJax is enabled you need to specify the location relative to the
3583 # HTML output directory using the MATHJAX_RELPATH option. The destination
3584 # directory should contain the MathJax.js script. For instance, if the mathjax
3585 # directory is located at the same level as the HTML output directory, then
3586 # MATHJAX_RELPATH should be ../mathjax. The default value points to
3587 # the MathJax Content Delivery Network so you can quickly see the result without
3588-# installing MathJax. However, it is strongly recommended to install a local
3589+# installing MathJax.
3590+# However, it is strongly recommended to install a local
3591 # copy of MathJax from http://www.mathjax.org before deployment.
3592
3593 MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
3594@@ -1233,6 +1266,11 @@
3595
3596 MATHJAX_EXTENSIONS =
3597
3598+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript
3599+# pieces of code that will be used on startup of the MathJax code.
3600+
3601+MATHJAX_CODEFILE =
3602+
3603 # When the SEARCHENGINE tag is enabled doxygen will generate a search box
3604 # for the HTML output. The underlying search engine uses javascript
3605 # and DHTML and should work on any modern browser. Note that when using
3606@@ -1244,15 +1282,55 @@
3607 SEARCHENGINE = YES
3608
3609 # When the SERVER_BASED_SEARCH tag is enabled the search engine will be
3610-# implemented using a PHP enabled web server instead of at the web client
3611-# using Javascript. Doxygen will generate the search PHP script and index
3612-# file to put on the web server. The advantage of the server
3613-# based approach is that it scales better to large projects and allows
3614-# full text search. The disadvantages are that it is more difficult to setup
3615-# and does not have live searching capabilities.
3616+# implemented using a web server instead of a web client using Javascript.
3617+# There are two flavours of web server based search depending on the
3618+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
3619+# searching and an index file used by the script. When EXTERNAL_SEARCH is
3620+# enabled the indexing and searching needs to be provided by external tools.
3621+# See the manual for details.
3622
3623 SERVER_BASED_SEARCH = NO
3624
3625+# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP
3626+# script for searching. Instead the search results are written to an XML file
3627+# which needs to be processed by an external indexer. Doxygen will invoke an
3628+# external search engine pointed to by the SEARCHENGINE_URL option to obtain
3629+# the search results. Doxygen ships with an example indexer (doxyindexer) and
3630+# search engine (doxysearch.cgi) which are based on the open source search
3631+# engine library Xapian. See the manual for configuration details.
3632+
3633+EXTERNAL_SEARCH = NO
3634+
3635+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
3636+# which will returned the search results when EXTERNAL_SEARCH is enabled.
3637+# Doxygen ships with an example search engine (doxysearch) which is based on
3638+# the open source search engine library Xapian. See the manual for configuration
3639+# details.
3640+
3641+SEARCHENGINE_URL =
3642+
3643+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
3644+# search data is written to a file for indexing by an external tool. With the
3645+# SEARCHDATA_FILE tag the name of this file can be specified.
3646+
3647+SEARCHDATA_FILE = searchdata.xml
3648+
3649+# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the
3650+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
3651+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
3652+# projects and redirect the results back to the right project.
3653+
3654+EXTERNAL_SEARCH_ID =
3655+
3656+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
3657+# projects other than the one defined by this configuration file, but that are
3658+# all added to the same external search index. Each project needs to have a
3659+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id
3660+# of to a relative location where the documentation can be found.
3661+# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ...
3662+
3663+EXTRA_SEARCH_MAPPINGS =
3664+
3665 #---------------------------------------------------------------------------
3666 # configuration options related to the LaTeX output
3667 #---------------------------------------------------------------------------
3668@@ -1290,7 +1368,7 @@
3669
3670 # The PAPER_TYPE tag can be used to set the paper type that is used
3671 # by the printer. Possible values are: a4, letter, legal and
3672-# executive. If left blank a4wide will be used.
3673+# executive. If left blank a4 will be used.
3674
3675 PAPER_TYPE = a4
3676
3677@@ -1313,6 +1391,13 @@
3678
3679 LATEX_FOOTER =
3680
3681+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images
3682+# or other source files which should be copied to the LaTeX output directory.
3683+# Note that the files will be copied as-is; there are no commands or markers
3684+# available.
3685+
3686+LATEX_EXTRA_FILES =
3687+
3688 # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
3689 # is prepared for conversion to pdf (using ps2pdf). The pdf file will
3690 # contain links (just like the HTML output) instead of page references
3691@@ -1458,6 +1543,21 @@
3692 XML_PROGRAMLISTING = YES
3693
3694 #---------------------------------------------------------------------------
3695+# configuration options related to the DOCBOOK output
3696+#---------------------------------------------------------------------------
3697+
3698+# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files
3699+# that can be used to generate PDF.
3700+
3701+GENERATE_DOCBOOK = NO
3702+
3703+# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put.
3704+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
3705+# front of it. If left blank docbook will be used as the default path.
3706+
3707+DOCBOOK_OUTPUT = docbook
3708+
3709+#---------------------------------------------------------------------------
3710 # configuration options for the AutoGen Definitions output
3711 #---------------------------------------------------------------------------
3712
3713@@ -1488,8 +1588,10 @@
3714 PERLMOD_LATEX = NO
3715
3716 # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
3717-# nicely formatted so it can be parsed by a human reader. This is useful
3718-# if you want to understand what is going on. On the other hand, if this
3719+# nicely formatted so it can be parsed by a human reader.
3720+# This is useful
3721+# if you want to understand what is going on.
3722+# On the other hand, if this
3723 # tag is set to NO the size of the Perl module output will be much smaller
3724 # and Perl will parse it just the same.
3725
3726@@ -1575,9 +1677,11 @@
3727 # The TAGFILES option can be used to specify one or more tagfiles. For each
3728 # tag file the location of the external documentation should be added. The
3729 # format of a tag file without this location is as follows:
3730-# TAGFILES = file1 file2 ...
3731+#
3732+# TAGFILES = file1 file2 ...
3733 # Adding location for the tag files is done as follows:
3734-# TAGFILES = file1=loc1 "file2 = loc2" ...
3735+#
3736+# TAGFILES = file1=loc1 "file2 = loc2" ...
3737 # where "loc1" and "loc2" can be relative or absolute paths
3738 # or URLs. Note that each tag file must have a unique name (where the name does
3739 # NOT include the path). If a tag file is not located in the directory in which
3740@@ -1602,6 +1706,12 @@
3741
3742 EXTERNAL_GROUPS = YES
3743
3744+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed
3745+# in the related pages index. If set to NO, only the current project's
3746+# pages will be listed.
3747+
3748+EXTERNAL_PAGES = YES
3749+
3750 # The PERL_PATH should be the absolute path and name of the perl script
3751 # interpreter (i.e. the result of `which perl').
3752
3753@@ -1698,7 +1808,7 @@
3754 # the class node. If there are many fields or methods and many nodes the
3755 # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
3756 # threshold limits the number of items for each type to make the size more
3757-# managable. Set this to 0 for no limit. Note that the threshold may be
3758+# manageable. Set this to 0 for no limit. Note that the threshold may be
3759 # exceeded by 50% before the limit is enforced.
3760
3761 UML_LIMIT_NUM_FIELDS = 10
3762
3763=== modified file 'doc/component_reports.md'
3764--- doc/component_reports.md 2013-11-06 03:17:35 +0000
3765+++ doc/component_reports.md 2013-11-22 04:49:56 +0000
3766@@ -24,7 +24,7 @@
3767 legacy-input-report | log
3768 msg-processor-report | log,lttng
3769 session-mediator-report | log
3770-surfaces-report | log
3771+scene-report | log
3772
3773 For example, to enable the LTTng input report, one could either use the
3774 `--input-report=lttng` command-line option to the server, or set the
3775@@ -40,6 +40,7 @@
3776 Report | Handlers
3777 ------------------- | --------
3778 rpc-report | log,lttng
3779+input-receiver | log
3780
3781 For example, to enable the logging RPC report, one should set the
3782 `MIR_CLIENT_RPC_REPORT=log` environment variable.
3783
3784=== modified file 'doc/installing_prebuilt_on_pc.md'
3785--- doc/installing_prebuilt_on_pc.md 2013-11-06 03:17:35 +0000
3786+++ doc/installing_prebuilt_on_pc.md 2013-11-22 04:49:56 +0000
3787@@ -4,7 +4,12 @@
3788 Install Ubuntu 13.10 or later if you haven't done so already. Uninstall any
3789 proprietary drivers (-nvidia, -fglrx) and reboot on the FOSS drivers.
3790
3791-Install Mir:
3792+Install Mir in Ubuntu 13.10:
3793
3794 sudo apt-get update
3795 sudo apt-get install mir-demos unity-system-compositor
3796+
3797+Install Mir in Ubuntu 14.04 or later:
3798+
3799+ sudo apt-get update
3800+ sudo apt-get install mir-demos ubuntu-desktop-mir
3801
3802=== modified file 'doc/using_mir_on_pc.md'
3803--- doc/using_mir_on_pc.md 2013-11-06 03:17:35 +0000
3804+++ doc/using_mir_on_pc.md 2013-11-22 04:49:56 +0000
3805@@ -31,12 +31,14 @@
3806 include lightdm, Mesa and the Xorg drivers). The easiest way is to run Ubuntu
3807 13.10 or later.
3808
3809-If you have installed unity-system-compositor it will have created a file in
3810-/etc/lightdm/lightdm.conf.d/10-unity-system-compositor.conf to run XMir. If you
3811-have build from source, to run X sessions under Mir, with Mir acting as the
3812-system compositor, create the file
3813-/etc/lightdm/lightdm.conf.d/10-unity-system-compositor.conf to look to look like
3814-this:
3815+If you are running Ubuntu 13.10, additionally install unity-system-compositor.
3816+If you are running Ubuntu 14.04 or later, instead install ubuntu-desktop-mir.
3817+These packages will install dependencies you need and will create a file in
3818+/etc/lightdm/lightdm.conf.d/10-unity-system-compositor.conf.
3819+
3820+If you have instead built from source, to set up the system compositor, create
3821+/etc/lightdm/lightdm.conf.d/10-unity-system-compositor.conf yourself and make
3822+it look like this:
3823
3824 [SeatDefaults]
3825 type=unity
3826
3827=== modified file 'examples/CMakeLists.txt'
3828--- examples/CMakeLists.txt 2013-09-23 13:37:44 +0000
3829+++ examples/CMakeLists.txt 2013-11-22 04:49:56 +0000
3830@@ -114,6 +114,7 @@
3831 target_link_libraries(mir_demo_standalone_render_surfaces
3832 mirserver
3833 mirshell
3834+ mirsharedgeometry
3835 ${Boost_LIBRARIES}
3836 )
3837
3838
3839=== modified file 'examples/buffer_render_target.cpp'
3840--- examples/buffer_render_target.cpp 2013-08-28 03:41:48 +0000
3841+++ examples/buffer_render_target.cpp 2013-11-22 04:49:56 +0000
3842@@ -27,7 +27,7 @@
3843 namespace mt = mir::tools;
3844
3845 mt::BufferRenderTarget::BufferRenderTarget(mg::Buffer& buffer)
3846- : buffer(buffer)
3847+ : buffer(buffer), old_fbo(), old_viewport()
3848 {
3849 /*
3850 * With the new lazy buffer allocation method, we may be executing inside
3851@@ -35,12 +35,14 @@
3852 * we change...
3853 */
3854 glGetIntegerv(GL_VIEWPORT, old_viewport);
3855+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_fbo);
3856 resources.setup(buffer);
3857 }
3858
3859 mt::BufferRenderTarget::~BufferRenderTarget()
3860 {
3861 glFinish();
3862+ glBindFramebuffer(GL_FRAMEBUFFER, old_fbo);
3863 glViewport(old_viewport[0], old_viewport[1],
3864 old_viewport[2], old_viewport[3]);
3865 }
3866
3867=== modified file 'examples/buffer_render_target.h'
3868--- examples/buffer_render_target.h 2013-08-28 03:41:48 +0000
3869+++ examples/buffer_render_target.h 2013-11-22 04:49:56 +0000
3870@@ -58,6 +58,7 @@
3871
3872 Resources resources;
3873 mir::graphics::Buffer& buffer;
3874+ GLint old_fbo;
3875 GLint old_viewport[4];
3876 };
3877
3878
3879=== modified file 'examples/demo-inprocess-surface-client/inprocess_egl_client.cpp'
3880--- examples/demo-inprocess-surface-client/inprocess_egl_client.cpp 2013-11-06 03:17:35 +0000
3881+++ examples/demo-inprocess-surface-client/inprocess_egl_client.cpp 2013-11-22 04:49:56 +0000
3882@@ -21,7 +21,7 @@
3883
3884 #include "mir/main_loop.h"
3885 #include "mir/shell/focus_controller.h"
3886-#include "mir/shell/surface.h"
3887+#include "mir/frontend/surface.h"
3888 #include "mir/shell/surface_creation_parameters.h"
3889 #include "mir/shell/session.h"
3890 #include "mir/frontend/session.h"
3891@@ -47,7 +47,6 @@
3892 #include <signal.h>
3893
3894 namespace mf = mir::frontend;
3895-namespace mc = mir::compositor;
3896 namespace msh = mir::shell;
3897 namespace mg = mir::graphics;
3898 namespace me = mir::examples;
3899
3900=== modified file 'examples/demo-shell/demo_shell.cpp'
3901--- examples/demo-shell/demo_shell.cpp 2013-11-06 03:17:35 +0000
3902+++ examples/demo-shell/demo_shell.cpp 2013-11-22 04:49:56 +0000
3903@@ -24,7 +24,6 @@
3904
3905 #include "mir/run_mir.h"
3906 #include "mir/report_exception.h"
3907-#include "mir/shell/session_container.h"
3908 #include "mir/graphics/display.h"
3909 #include "mir/input/composite_event_filter.h"
3910
3911
3912=== modified file 'examples/demo-shell/window_manager.cpp'
3913--- examples/demo-shell/window_manager.cpp 2013-11-06 03:17:35 +0000
3914+++ examples/demo-shell/window_manager.cpp 2013-11-22 04:49:56 +0000
3915@@ -14,6 +14,7 @@
3916 * along with this program. If not, see <http://www.gnu.org/licenses/>.
3917 *
3918 * Authored by: Robert Carr <robert.carr@canonical.com>
3919+ * Daniel van Vugt <daniel.van.vugt@canonical.com>
3920 */
3921
3922 #include "window_manager.h"
3923@@ -29,6 +30,7 @@
3924
3925 #include <cassert>
3926 #include <cstdlib>
3927+#include <cmath>
3928
3929 namespace me = mir::examples;
3930 namespace msh = mir::shell;
3931@@ -41,7 +43,7 @@
3932 }
3933
3934 me::WindowManager::WindowManager()
3935- : max_fingers(0)
3936+ : old_pinch_diam(0.0f), max_fingers(0)
3937 {
3938 }
3939
3940@@ -60,6 +62,9 @@
3941 compositor = cptor;
3942 }
3943
3944+namespace
3945+{
3946+
3947 mir::geometry::Point average_pointer(MirMotionEvent const& motion)
3948 {
3949 using namespace mir;
3950@@ -79,6 +84,36 @@
3951 return Point{x, y};
3952 }
3953
3954+float measure_pinch(MirMotionEvent const& motion,
3955+ mir::geometry::Displacement& dir)
3956+{
3957+ int count = static_cast<int>(motion.pointer_count);
3958+ int max = 0;
3959+
3960+ for (int i = 0; i < count; i++)
3961+ {
3962+ for (int j = 0; j < i; j++)
3963+ {
3964+ int dx = motion.pointer_coordinates[i].x -
3965+ motion.pointer_coordinates[j].x;
3966+ int dy = motion.pointer_coordinates[i].y -
3967+ motion.pointer_coordinates[j].y;
3968+
3969+ int sqr = dx*dx + dy*dy;
3970+
3971+ if (sqr > max)
3972+ {
3973+ max = sqr;
3974+ dir = mir::geometry::Displacement{dx, dy};
3975+ }
3976+ }
3977+ }
3978+
3979+ return sqrtf(max); // return pinch diameter
3980+}
3981+
3982+} // namespace
3983+
3984 bool me::WindowManager::handle(MirEvent const& event)
3985 {
3986 // TODO: Fix android configuration and remove static hack ~racarr
3987@@ -87,6 +122,8 @@
3988 assert(display);
3989 assert(compositor);
3990
3991+ bool handled = false;
3992+
3993 if (event.key.type == mir_event_type_key &&
3994 event.key.action == mir_key_action_down)
3995 {
3996@@ -148,22 +185,73 @@
3997 (event.motion.modifiers & mir_key_modifier_alt ||
3998 fingers >= 3))
3999 {
4000+ geometry::Displacement pinch_dir;
4001+ auto pinch_diam =
4002+ measure_pinch(event.motion, pinch_dir);
4003+
4004 // Start of a gesture: When the latest finger/button goes down
4005 if (action == mir_motion_action_down ||
4006 action == mir_motion_action_pointer_down)
4007 {
4008- relative_click = cursor - surf->top_left();
4009 click = cursor;
4010- }
4011- else if (event.motion.action == mir_motion_action_move)
4012- { // Movement is happening with one or more fingers/button down
4013- geometry::Point abs = cursor - relative_click;
4014- if (max_fingers <= 3) // Avoid accidental movement
4015- {
4016- surf->move_to(abs);
4017- return true;
4018- }
4019- }
4020+ handled = true;
4021+ }
4022+ else if (event.motion.action == mir_motion_action_move &&
4023+ max_fingers <= 3) // Avoid accidental movement
4024+ {
4025+ geometry::Displacement drag = cursor - old_cursor;
4026+
4027+ if (event.motion.button_state ==
4028+ mir_motion_button_tertiary)
4029+ { // Resize by mouse middle button
4030+ int width = old_size.width.as_int() +
4031+ drag.dx.as_int();
4032+ int height = old_size.height.as_int() +
4033+ drag.dy.as_int();
4034+ if (width <= 0) width = 1;
4035+ if (height <= 0) height = 1;
4036+ surf->resize({width, height});
4037+ }
4038+ else
4039+ { // Move surface (by mouse or 3 fingers)
4040+ surf->move_to(old_pos + drag);
4041+ }
4042+
4043+ if (fingers == 3)
4044+ { // Resize by pinch/zoom
4045+ float diam_delta = pinch_diam - old_pinch_diam;
4046+ /*
4047+ * Resize vector (dx,dy) has length=diam_delta and
4048+ * direction=pinch_dir, so solve for (dx,dy)...
4049+ */
4050+ float lenlen = diam_delta * diam_delta;
4051+ int x = pinch_dir.dx.as_int();
4052+ int y = pinch_dir.dy.as_int();
4053+ int xx = x * x;
4054+ int yy = y * y;
4055+ int xxyy = xx + yy;
4056+ int dx = sqrtf(lenlen * xx / xxyy);
4057+ int dy = sqrtf(lenlen * yy / xxyy);
4058+ if (diam_delta < 0.0f)
4059+ {
4060+ dx = -dx;
4061+ dy = -dy;
4062+ }
4063+
4064+ int width = old_size.width.as_int() + dx;
4065+ int height = old_size.height.as_int() + dy;
4066+ if (width <= 0) width = 1;
4067+ if (height <= 0) height = 1;
4068+ surf->resize({width, height});
4069+ }
4070+
4071+ handled = true;
4072+ }
4073+
4074+ old_pos = surf->top_left();
4075+ old_size = surf->size();
4076+ old_pinch_diam = pinch_diam;
4077+ old_cursor = cursor;
4078 }
4079 }
4080
4081@@ -173,9 +261,9 @@
4082 if (abs(dir.dx.as_int()) >= min_swipe_distance)
4083 {
4084 focus_controller->focus_next();
4085- return true;
4086+ handled = true;
4087 }
4088 }
4089 }
4090- return false;
4091+ return handled;
4092 }
4093
4094=== modified file 'examples/demo-shell/window_manager.h'
4095--- examples/demo-shell/window_manager.h 2013-11-06 03:17:35 +0000
4096+++ examples/demo-shell/window_manager.h 2013-11-22 04:49:56 +0000
4097@@ -21,6 +21,7 @@
4098
4099 #include "mir/input/event_filter.h"
4100 #include "mir/geometry/displacement.h"
4101+#include "mir/geometry/size.h"
4102
4103 #include <memory>
4104
4105@@ -62,8 +63,11 @@
4106 std::shared_ptr<graphics::Display> display;
4107 std::shared_ptr<compositor::Compositor> compositor;
4108
4109- geometry::Displacement relative_click; // Click location in window space
4110- geometry::Point click; // Click location in screen space
4111+ geometry::Point click;
4112+ geometry::Point old_pos;
4113+ geometry::Point old_cursor;
4114+ geometry::Size old_size;
4115+ float old_pinch_diam;
4116 int max_fingers; // Maximum number of fingers touched during gesture
4117 };
4118
4119
4120=== modified file 'examples/demo_input_filter.cpp'
4121--- examples/demo_input_filter.cpp 2013-08-28 03:41:48 +0000
4122+++ examples/demo_input_filter.cpp 2013-11-22 04:49:56 +0000
4123@@ -32,6 +32,21 @@
4124
4125 struct PrintingEventFilter : public mi::EventFilter
4126 {
4127+ void print_motion_event(MirMotionEvent const& ev)
4128+ {
4129+ std::cout << "Motion Event time=" << ev.event_time
4130+ << " pointer_count=" << ev.pointer_count << std::endl;
4131+
4132+ for (size_t i = 0; i < ev.pointer_count; ++i)
4133+ {
4134+ std::cout << " "
4135+ << " id=" << ev.pointer_coordinates[i].id
4136+ << " pos=(" << ev.pointer_coordinates[i].x << ", " << ev.pointer_coordinates[i].y << ")"
4137+ << std::endl;
4138+ }
4139+ std::cout << "----------------" << std::endl << std::endl;
4140+ }
4141+
4142 bool handle(MirEvent const& ev) override
4143 {
4144 // TODO: Enhance printing
4145@@ -42,8 +57,7 @@
4146 }
4147 else if (ev.type == mir_event_type_motion)
4148 {
4149- std::cout << "Handling motion event (time, pointer0_x, pointer0_y): " << ev.motion.event_time << " "
4150- << ev.motion.pointer_coordinates[0].x << " " << ev.motion.pointer_coordinates[0].y << std::endl;
4151+ print_motion_event(ev.motion);
4152 }
4153 return false;
4154 }
4155@@ -56,7 +70,7 @@
4156 event_filter(std::make_shared<PrintingEventFilter>())
4157 {
4158 }
4159-
4160+
4161 std::shared_ptr<mi::CompositeEventFilter> the_composite_event_filter() override
4162 {
4163 auto composite_filter = ServerConfiguration::the_composite_event_filter();
4164@@ -69,10 +83,18 @@
4165
4166 }
4167
4168+
4169+#include <std/MirLog.h>
4170+void my_write_to_log(int /*prio*/, char const* buffer)
4171+{
4172+ printf("%s\n", buffer);
4173+}
4174+
4175 int main(int argc, char const* argv[])
4176 try
4177 {
4178 DemoServerConfiguration config(argc, argv);
4179+ mir::write_to_log = my_write_to_log;
4180
4181 mir::run_mir(config, [](mir::DisplayServer&) {/* empty init */});
4182 return 0;
4183
4184=== modified file 'examples/eglapp.c'
4185--- examples/eglapp.c 2013-10-07 09:21:27 +0000
4186+++ examples/eglapp.c 2013-11-22 04:49:56 +0000
4187@@ -23,6 +23,7 @@
4188 #include <signal.h>
4189 #include <time.h>
4190 #include <EGL/egl.h>
4191+#include <GLES2/gl2.h>
4192
4193 #include <xkbcommon/xkbcommon-keysyms.h>
4194
4195@@ -75,6 +76,7 @@
4196 time_t now = time(NULL);
4197 time_t dtime;
4198 int dcount;
4199+ EGLint width, height;
4200
4201 if (!running)
4202 return;
4203@@ -90,6 +92,14 @@
4204 lasttime = now;
4205 lastcount = count;
4206 }
4207+
4208+ /* This is one way to handle window resizing. But in future it would be
4209+ better to have resize events coming from the server */
4210+ if (eglQuerySurface(egldisplay, eglsurface, EGL_WIDTH, &width) &&
4211+ eglQuerySurface(egldisplay, eglsurface, EGL_HEIGHT, &height))
4212+ {
4213+ glViewport(0, 0, width, height);
4214+ }
4215 }
4216
4217 static void mir_eglapp_handle_input(MirSurface* surface, MirEvent const* ev, void* context)
4218@@ -300,12 +310,11 @@
4219
4220 const MirDisplayMode *mode = &output->modes[output->current_mode];
4221
4222- const unsigned int max_formats = 10;
4223- unsigned int format[max_formats];
4224+ unsigned int format[mir_pixel_formats];
4225 unsigned int nformats;
4226
4227 mir_connection_get_available_surface_formats(connection,
4228- format, max_formats, &nformats);
4229+ format, mir_pixel_formats, &nformats);
4230
4231 surfaceparm.pixel_format = format[0];
4232 for (unsigned int f = 0; f < nformats; f++)
4233@@ -322,18 +331,17 @@
4234 }
4235 }
4236
4237- printf("Connected to display: resolution (%dx%d), position(%dx%d), "
4238- "supports %d pixel formats\n",
4239+ printf("Current active output is %dx%d %+d%+d\n",
4240 mode->horizontal_resolution, mode->vertical_resolution,
4241- output->position_x, output->position_y,
4242- output->num_output_formats);
4243+ output->position_x, output->position_y);
4244
4245 surfaceparm.width = *width > 0 ? *width : mode->horizontal_resolution;
4246 surfaceparm.height = *height > 0 ? *height : mode->vertical_resolution;
4247
4248 mir_display_config_destroy(display_config);
4249
4250- printf("Using pixel format #%d\n", surfaceparm.pixel_format);
4251+ printf("Server supports %d of %d surface pixel formats. Using format: %d\n",
4252+ nformats, mir_pixel_formats, surfaceparm.pixel_format);
4253 unsigned int bpp = get_bpp(surfaceparm.pixel_format);
4254 EGLint attribs[] =
4255 {
4256
4257=== modified file 'examples/progressbar.c'
4258--- examples/progressbar.c 2013-08-27 08:52:43 +0000
4259+++ examples/progressbar.c 2013-11-22 04:49:56 +0000
4260@@ -33,6 +33,12 @@
4261 uint8_t r, g, b, a;
4262 } Color;
4263
4264+static const Color blue = {0, 0, 255, 255};
4265+static const Color white = {255, 255, 255, 255};
4266+
4267+static const Color *const foreground = &white;
4268+static const Color *const background = &blue;
4269+
4270 static volatile sig_atomic_t running = 1;
4271
4272 static void shutdown(int signum)
4273@@ -178,6 +184,7 @@
4274 MirGraphicsRegion backbuffer;
4275
4276 mir_surface_get_graphics_region(surface, &backbuffer);
4277+ clear_region(&backbuffer, background);
4278 copy_region(&backbuffer, canvas);
4279 mir_surface_swap_buffers_sync(surface);
4280 }
4281@@ -264,8 +271,6 @@
4282
4283 while (running)
4284 {
4285- static const Color background = {0, 0, 255, 255};
4286- static const Color foreground = {255, 255, 255, 255};
4287 static const int width = 8;
4288 static const int space = 1;
4289 const int grid = width + 2 * space;
4290@@ -275,11 +280,11 @@
4291 const int y = (t / row) * grid + space;
4292
4293 if (t % square == 0)
4294- clear_region(&canvas, &background);
4295+ clear_region(&canvas, background);
4296
4297 t = (t + 1) % square;
4298
4299- draw_box(&canvas, x, y, width, &foreground);
4300+ draw_box(&canvas, x, y, width, foreground);
4301
4302 redraw(surf, &canvas);
4303 usleep(sleep_usec);
4304
4305=== modified file 'examples/render_surfaces.cpp'
4306--- examples/render_surfaces.cpp 2013-11-06 03:17:35 +0000
4307+++ examples/render_surfaces.cpp 2013-11-22 04:49:56 +0000
4308@@ -27,8 +27,8 @@
4309 #include "mir/graphics/cursor.h"
4310 #include "mir/graphics/display.h"
4311 #include "mir/graphics/display_buffer.h"
4312-#include "mir/shell/surface_builder.h"
4313-#include "mir/surfaces/surface.h"
4314+#include "mir/shell/surface_factory.h"
4315+#include "mir/shell/surface.h"
4316 #include "mir/run_mir.h"
4317 #include "mir/report_exception.h"
4318
4319@@ -49,7 +49,7 @@
4320
4321 namespace mg = mir::graphics;
4322 namespace mc = mir::compositor;
4323-namespace ms = mir::surfaces;
4324+namespace ms = mir::scene;
4325 namespace mf = mir::frontend;
4326 namespace msh = mir::shell;
4327 namespace mi = mir::input;
4328@@ -185,13 +185,13 @@
4329 {
4330 public:
4331 Moveable() {}
4332- Moveable(ms::Surface& s, const geom::Size& display_size,
4333+ Moveable(std::shared_ptr<msh::Surface> const& s, const geom::Size& display_size,
4334 float dx, float dy, const glm::vec3& rotation_axis, float alpha_offset)
4335- : surface(&s), display_size(display_size),
4336- x{static_cast<float>(s.top_left().x.as_uint32_t())},
4337- y{static_cast<float>(s.top_left().y.as_uint32_t())},
4338- w{static_cast<float>(s.size().width.as_uint32_t())},
4339- h{static_cast<float>(s.size().height.as_uint32_t())},
4340+ : surface(s), display_size(display_size),
4341+ x{static_cast<float>(s->top_left().x.as_uint32_t())},
4342+ y{static_cast<float>(s->top_left().y.as_uint32_t())},
4343+ w{static_cast<float>(s->size().width.as_uint32_t())},
4344+ h{static_cast<float>(s->size().height.as_uint32_t())},
4345 dx{dx},
4346 dy{dy},
4347 rotation_axis{rotation_axis},
4348@@ -233,7 +233,7 @@
4349 }
4350
4351 private:
4352- ms::Surface* surface;
4353+ std::shared_ptr<msh::Surface> surface;
4354 geom::Size display_size;
4355 float x;
4356 float y;
4357@@ -387,7 +387,7 @@
4358 std::cout << "Rendering " << moveables.size() << " surfaces" << std::endl;
4359
4360 auto const display = the_display();
4361- auto const surface_builder = the_surface_builder();
4362+ auto const surface_factory = the_scene_surface_factory();
4363 /* TODO: Get proper configuration */
4364 geom::Rectangles view_area;
4365 display->for_each_display_buffer([&view_area](mg::DisplayBuffer const& db)
4366@@ -406,18 +406,20 @@
4367 int i = 0;
4368 for (auto& m : moveables)
4369 {
4370- std::shared_ptr<ms::Surface> s = surface_builder->create_surface(
4371+ auto const s = surface_factory->create_surface(
4372 nullptr,
4373 msh::a_surface().of_size(surface_size)
4374 .of_pixel_format(surface_pf)
4375- .of_buffer_usage(mg::BufferUsage::hardware)
4376- ).lock();
4377+ .of_buffer_usage(mg::BufferUsage::hardware),
4378+ mf::SurfaceId(), {});
4379
4380 /*
4381- * Let the system know that the surface is suitable for rendering
4382- * (i.e., that it contains buffers with valid contents).
4383+ * We call advance_client_buffer() twice so that the surface is
4384+ * considers the first buffer to be posted.
4385+ * (TODO There must be a better way!)
4386 */
4387- s->flag_for_render();
4388+ s->advance_client_buffer();
4389+ s->advance_client_buffer();
4390
4391 /*
4392 * Place each surface at a different starting location and give it a
4393@@ -427,7 +429,7 @@
4394 uint32_t const y = h * (0.5 + 0.25 * sin(i * angular_step)) - surface_side / 2.0;
4395
4396 s->move_to({x, y});
4397- m = Moveable(*s, display_size,
4398+ m = Moveable(s, display_size,
4399 cos(0.1f + i * M_PI / 6.0f) * w / 3.0f,
4400 sin(0.1f + i * M_PI / 6.0f) * h / 3.0f,
4401 glm::vec3{(i % 3 == 0) * 1.0f, (i % 3 == 1) * 1.0f, (i % 3 == 2) * 1.0f},
4402
4403=== modified file 'include/client/mir_toolkit/mir_client_library.h'
4404--- include/client/mir_toolkit/mir_client_library.h 2013-08-28 03:41:48 +0000
4405+++ include/client/mir_toolkit/mir_client_library.h 2013-11-22 04:49:56 +0000
4406@@ -207,7 +207,7 @@
4407 /**
4408 * Set the event handler to be called when events arrive for a surface.
4409 * \warning event_handler could be called from another thread. You must do
4410- * and locking appropriate to protect your data accessed in the
4411+ * any locking appropriate to protect your data accessed in the
4412 * callback. There is also a chance that different events will be
4413 * called back in different threads, for the same surface,
4414 * simultaneously.
4415
4416=== added file 'include/platform/mir/graphics/basic_platform.h'
4417--- include/platform/mir/graphics/basic_platform.h 1970-01-01 00:00:00 +0000
4418+++ include/platform/mir/graphics/basic_platform.h 2013-11-22 04:49:56 +0000
4419@@ -0,0 +1,45 @@
4420+/*
4421+ * Copyright © 2013 Canonical Ltd.
4422+ *
4423+ * This program is free software: you can redistribute it and/or modify it
4424+ * under the terms of the GNU Lesser General Public License version 3,
4425+ * as published by the Free Software Foundation.
4426+ *
4427+ * This program is distributed in the hope that it will be useful,
4428+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4429+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4430+ * GNU Lesser General Public License for more details.
4431+ *
4432+ * You should have received a copy of the GNU Lesser General Public License
4433+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4434+ *
4435+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
4436+ */
4437+
4438+#ifndef MIR_GRAPHICS_BASIC_PLATFORM_H_
4439+#define MIR_GRAPHICS_BASIC_PLATFORM_H_
4440+
4441+#include <EGL/egl.h>
4442+
4443+namespace mir
4444+{
4445+namespace graphics
4446+{
4447+
4448+class BasicPlatform
4449+{
4450+public:
4451+ virtual ~BasicPlatform() = default;
4452+
4453+ virtual EGLNativeDisplayType egl_native_display() const = 0;
4454+
4455+protected:
4456+ BasicPlatform() = default;
4457+ BasicPlatform(BasicPlatform const&) = delete;
4458+ BasicPlatform& operator=(BasicPlatform const&) = delete;
4459+};
4460+
4461+}
4462+}
4463+
4464+#endif /* MIR_GRAPHICS_BASIC_PLATFORM_H_ */
4465
4466=== modified file 'include/platform/mir/graphics/buffer_ipc_packer.h'
4467--- include/platform/mir/graphics/buffer_ipc_packer.h 2013-09-11 05:21:22 +0000
4468+++ include/platform/mir/graphics/buffer_ipc_packer.h 2013-11-22 04:49:56 +0000
4469@@ -20,6 +20,7 @@
4470 #define MIR_GRAPHICS_BUFFER_IPC_PACKER_H_
4471
4472 #include "mir/geometry/dimensions.h"
4473+#include "mir/geometry/size.h"
4474
4475 namespace mir
4476 {
4477@@ -34,6 +35,7 @@
4478 virtual void pack_data(int) = 0;
4479 virtual void pack_stride(geometry::Stride) = 0;
4480 virtual void pack_flags(unsigned int) = 0;
4481+ virtual void pack_size(geometry::Size const& size) = 0;
4482
4483 protected:
4484 BufferIPCPacker() {}
4485
4486=== modified file 'include/platform/mir/graphics/egl_resources.h'
4487--- include/platform/mir/graphics/egl_resources.h 2013-08-28 03:41:48 +0000
4488+++ include/platform/mir/graphics/egl_resources.h 2013-11-22 04:49:56 +0000
4489@@ -30,6 +30,8 @@
4490 {
4491 public:
4492 EGLContextStore(EGLDisplay egl_display, EGLContext egl_context);
4493+ EGLContextStore(EGLContextStore&&);
4494+
4495 ~EGLContextStore() noexcept;
4496
4497 operator EGLContext() const;
4498@@ -38,14 +40,18 @@
4499 EGLContextStore(EGLContextStore const&) = delete;
4500 EGLContextStore& operator=(EGLContextStore const&) = delete;
4501
4502- EGLDisplay const egl_display_;
4503- EGLContext const egl_context_;
4504+ EGLDisplay egl_display_;
4505+ EGLContext egl_context_;
4506 };
4507
4508 class EGLSurfaceStore
4509 {
4510 public:
4511+ enum AllowNoSurface { DisallowNoSurface, AllowNoSurface };
4512+ EGLSurfaceStore(EGLDisplay egl_display, EGLSurface egl_surface,
4513+ enum AllowNoSurface allow_no_surface);
4514 EGLSurfaceStore(EGLDisplay egl_display, EGLSurface egl_surface);
4515+ EGLSurfaceStore(EGLSurfaceStore&&);
4516
4517 ~EGLSurfaceStore() noexcept;
4518
4519@@ -55,8 +61,8 @@
4520 EGLSurfaceStore(EGLSurfaceStore const&) = delete;
4521 EGLSurfaceStore& operator=(EGLSurfaceStore const&) = delete;
4522
4523- EGLDisplay const egl_display_;
4524- EGLSurface const egl_surface_;
4525+ EGLDisplay egl_display_;
4526+ EGLSurface egl_surface_;
4527 };
4528
4529 }
4530
4531=== modified file 'include/platform/mir/graphics/native_platform.h'
4532--- include/platform/mir/graphics/native_platform.h 2013-10-23 09:33:59 +0000
4533+++ include/platform/mir/graphics/native_platform.h 2013-11-22 04:49:56 +0000
4534@@ -52,7 +52,7 @@
4535
4536 virtual std::shared_ptr<InternalClient> create_internal_client() = 0;
4537
4538- virtual void fill_ipc_package(std::shared_ptr<BufferIPCPacker> const& packer, std::shared_ptr<Buffer> const& buffer) const = 0;
4539+ virtual void fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const = 0;
4540
4541 virtual ~NativePlatform() = default;
4542 NativePlatform(NativePlatform const&) = delete;
4543
4544=== modified file 'include/platform/mir/graphics/platform.h'
4545--- include/platform/mir/graphics/platform.h 2013-08-28 03:41:48 +0000
4546+++ include/platform/mir/graphics/platform.h 2013-11-22 04:49:56 +0000
4547@@ -20,6 +20,8 @@
4548 #ifndef MIR_GRAPHICS_PLATFORM_H_
4549 #define MIR_GRAPHICS_PLATFORM_H_
4550
4551+#include "basic_platform.h"
4552+
4553 #include <memory>
4554
4555 namespace mir
4556@@ -57,7 +59,7 @@
4557 * Interface to platform specific support for graphics operations.
4558 * \ingroup platform_enablement
4559 */
4560-class Platform
4561+class Platform : public BasicPlatform
4562 {
4563 public:
4564 Platform() = default;
4565@@ -97,8 +99,7 @@
4566 * \param [in] packer the object providing the packing functionality
4567 * \param [in] buffer the buffer to fill the IPC package for
4568 */
4569- virtual void fill_ipc_package(std::shared_ptr<BufferIPCPacker> const& packer,
4570- std::shared_ptr<graphics::Buffer> const& buffer) const = 0;
4571+ virtual void fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const = 0;
4572
4573 /**
4574 * Creates the in-process client support object.
4575
4576=== modified file 'include/server/mir/compositor/buffer_stream.h'
4577--- include/server/mir/compositor/buffer_stream.h 2013-11-06 03:17:35 +0000
4578+++ include/server/mir/compositor/buffer_stream.h 2013-11-22 04:49:56 +0000
4579@@ -47,6 +47,7 @@
4580 virtual std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() = 0;
4581 virtual geometry::PixelFormat get_stream_pixel_format() = 0;
4582 virtual geometry::Size stream_size() = 0;
4583+ virtual void resize(geometry::Size const& size) = 0;
4584 virtual void allow_framedropping(bool) = 0;
4585 virtual void force_requests_to_complete() = 0;
4586 };
4587
4588=== modified file 'include/server/mir/compositor/scene.h'
4589--- include/server/mir/compositor/scene.h 2013-11-06 03:17:35 +0000
4590+++ include/server/mir/compositor/scene.h 2013-11-22 04:49:56 +0000
4591@@ -75,7 +75,7 @@
4592 * Scene changes.
4593 *
4594 * The supplied callback should not directly or indirectly (e.g.,
4595- * by changing a property of a Renderable) change the state of
4596+ * by changing a property of a surface) change the state of
4597 * the Scene, otherwise a deadlock may occur.
4598 */
4599 virtual void set_change_callback(std::function<void()> const& f) = 0;
4600
4601=== modified file 'include/server/mir/default_configuration_options.h'
4602--- include/server/mir/default_configuration_options.h 2013-11-06 03:17:35 +0000
4603+++ include/server/mir/default_configuration_options.h 2013-11-22 04:49:56 +0000
4604@@ -35,12 +35,13 @@
4605 static char const* const display_report_opt;
4606 static char const* const legacy_input_report_opt;
4607 static char const* const connector_report_opt;
4608- static char const* const surfaces_report_opt;
4609+ static char const* const scene_report_opt;
4610 static char const* const input_report_opt;
4611 static char const* const host_socket_opt;
4612 static char const* const standalone_opt;
4613 static char const* const frontend_threads;
4614 static char const* const name_opt;
4615+ static char const* const offscreen_opt;
4616
4617 static char const* const glog;
4618 static char const* const glog_stderrthreshold;
4619
4620=== modified file 'include/server/mir/default_server_configuration.h'
4621--- include/server/mir/default_server_configuration.h 2013-11-06 03:17:35 +0000
4622+++ include/server/mir/default_server_configuration.h 2013-11-22 04:49:56 +0000
4623@@ -55,37 +55,36 @@
4624 namespace shell
4625 {
4626 class SurfaceFactory;
4627-class SurfaceBuilder;
4628 class SurfaceController;
4629 class InputTargeter;
4630-class SessionContainer;
4631 class FocusSetter;
4632-class FocusSequence;
4633 class PlacementStrategy;
4634 class SessionListener;
4635 class FocusController;
4636-class SessionManager;
4637-class PixelBuffer;
4638-class SnapshotStrategy;
4639 class DisplayLayout;
4640 class SurfaceConfigurator;
4641+}
4642+namespace time
4643+{
4644+class TimeSource;
4645+}
4646+namespace scene
4647+{
4648+class BroadcastingSessionEventSink;
4649+class BufferStreamFactory;
4650 class MediatingDisplayChanger;
4651+class PixelBuffer;
4652+class SessionContainer;
4653 class SessionEventSink;
4654 class SessionEventHandlerRegister;
4655-class BroadcastingSessionEventSink;
4656-}
4657-namespace time
4658-{
4659-class TimeSource;
4660-}
4661-namespace surfaces
4662-{
4663-class BufferStreamFactory;
4664+class SessionManager;
4665+class SnapshotStrategy;
4666+class SurfaceBuilder;
4667 class SurfaceStackModel;
4668 class SurfaceStack;
4669 class SurfaceController;
4670 class InputRegistrar;
4671-class SurfacesReport;
4672+class SceneReport;
4673 }
4674 namespace graphics
4675 {
4676@@ -186,40 +185,32 @@
4677 * configurable interfaces for modifying shell
4678 * @{ */
4679 virtual std::shared_ptr<shell::SurfaceFactory> the_shell_surface_factory();
4680- virtual std::shared_ptr<shell::SessionContainer> the_shell_session_container();
4681+ virtual std::shared_ptr<shell::SurfaceFactory> the_scene_surface_factory();
4682 virtual std::shared_ptr<shell::FocusSetter> the_shell_focus_setter();
4683- virtual std::shared_ptr<shell::FocusSequence> the_shell_focus_sequence();
4684 virtual std::shared_ptr<shell::PlacementStrategy> the_shell_placement_strategy();
4685 virtual std::shared_ptr<shell::SessionListener> the_shell_session_listener();
4686- virtual std::shared_ptr<shell::PixelBuffer> the_shell_pixel_buffer();
4687- virtual std::shared_ptr<shell::SnapshotStrategy> the_shell_snapshot_strategy();
4688 virtual std::shared_ptr<shell::DisplayLayout> the_shell_display_layout();
4689 virtual std::shared_ptr<shell::SurfaceConfigurator> the_shell_surface_configurator();
4690- virtual std::shared_ptr<shell::SessionEventSink> the_shell_session_event_sink();
4691- virtual std::shared_ptr<shell::SessionEventHandlerRegister> the_shell_session_event_handler_register();
4692 virtual std::shared_ptr<shell::SurfaceController> the_shell_surface_controller();
4693 /** @} */
4694
4695- /** @name shell configuration - dependencies
4696- * dependencies of shell on the rest of the Mir
4697- * @{ */
4698- virtual std::shared_ptr<shell::SurfaceBuilder> the_surface_builder();
4699- virtual std::shared_ptr<surfaces::SurfaceController> the_surface_controller();
4700-
4701- /** @} */
4702-
4703-
4704- /** @name surfaces configuration - customization
4705- * configurable interfaces for modifying surfaces
4706- * @{ */
4707- virtual std::shared_ptr<surfaces::SurfaceStackModel> the_surface_stack_model();
4708- virtual std::shared_ptr<surfaces::SurfacesReport> the_surfaces_report();
4709- /** @} */
4710-
4711- /** @name surfaces configuration - dependencies
4712- * dependencies of surfaces on the rest of the Mir
4713- * @{ */
4714- virtual std::shared_ptr<surfaces::BufferStreamFactory> the_buffer_stream_factory();
4715+ /** @name internal scene configuration
4716+ * builder functions used in the default implementation.
4717+ * The interfaces returned are not published, so the functions are only useful in tests
4718+ * @{ */
4719+ virtual std::shared_ptr<scene::PixelBuffer> the_pixel_buffer();
4720+ virtual std::shared_ptr<scene::SnapshotStrategy> the_snapshot_strategy();
4721+ virtual std::shared_ptr<scene::SessionContainer> the_session_container();
4722+ virtual std::shared_ptr<scene::SessionEventSink> the_session_event_sink();
4723+ virtual std::shared_ptr<scene::SessionEventHandlerRegister> the_session_event_handler_register();
4724+ virtual std::shared_ptr<scene::SurfaceStackModel> the_surface_stack_model();
4725+ /** @} */
4726+
4727+ /** @name scene configuration - dependencies
4728+ * dependencies of scene on the rest of the Mir
4729+ * @{ */
4730+ virtual std::shared_ptr<scene::BufferStreamFactory> the_buffer_stream_factory();
4731+ virtual std::shared_ptr<scene::SceneReport> the_scene_report();
4732 /** @} */
4733
4734
4735@@ -227,7 +218,7 @@
4736 * @{ */
4737 virtual std::shared_ptr<input::InputReport> the_input_report();
4738 virtual std::shared_ptr<input::CompositeEventFilter> the_composite_event_filter();
4739- virtual std::shared_ptr<surfaces::InputRegistrar> the_input_registrar();
4740+ virtual std::shared_ptr<scene::InputRegistrar> the_input_registrar();
4741 virtual std::shared_ptr<shell::InputTargeter> the_input_targeter();
4742 virtual std::shared_ptr<input::CursorListener> the_cursor_listener();
4743 virtual std::shared_ptr<input::InputRegion> the_input_region();
4744@@ -241,20 +232,15 @@
4745
4746 virtual std::shared_ptr<time::TimeSource> the_time_source();
4747
4748- virtual std::shared_ptr<shell::SessionManager> the_session_manager();
4749-
4750 protected:
4751 using DefaultConfigurationOptions::the_options;
4752 using DefaultConfigurationOptions::add_options;
4753 using DefaultConfigurationOptions::parse_options;
4754
4755 virtual std::shared_ptr<input::InputChannelFactory> the_input_channel_factory();
4756- virtual std::shared_ptr<shell::MediatingDisplayChanger> the_mediating_display_changer();
4757- virtual std::shared_ptr<shell::BroadcastingSessionEventSink> the_broadcasting_session_event_sink();
4758+ virtual std::shared_ptr<scene::MediatingDisplayChanger> the_mediating_display_changer();
4759
4760 CachedPtr<frontend::Connector> connector;
4761- CachedPtr<shell::SessionManager> session_manager;
4762-
4763
4764 CachedPtr<input::InputConfiguration> input_configuration;
4765
4766@@ -262,7 +248,7 @@
4767 CachedPtr<input::CompositeEventFilter> composite_event_filter;
4768 CachedPtr<input::InputManager> input_manager;
4769 CachedPtr<input::InputRegion> input_region;
4770- CachedPtr<surfaces::InputRegistrar> input_registrar;
4771+ CachedPtr<scene::InputRegistrar> input_registrar;
4772 CachedPtr<shell::InputTargeter> input_targeter;
4773 CachedPtr<input::CursorListener> cursor_listener;
4774 CachedPtr<graphics::Platform> graphics_platform;
4775@@ -279,17 +265,17 @@
4776 CachedPtr<frontend::SessionCreator> session_creator;
4777 CachedPtr<compositor::RendererFactory> renderer_factory;
4778 CachedPtr<compositor::BufferStreamFactory> buffer_stream_factory;
4779- CachedPtr<surfaces::SurfaceStack> surface_stack;
4780- CachedPtr<surfaces::SurfacesReport> surfaces_report;
4781+ CachedPtr<scene::SurfaceStack> surface_stack;
4782+ CachedPtr<scene::SceneReport> scene_report;
4783
4784 CachedPtr<shell::SurfaceFactory> shell_surface_factory;
4785- CachedPtr<shell::SessionContainer> shell_session_container;
4786+ CachedPtr<shell::SurfaceFactory> scene_surface_factory;
4787+ CachedPtr<scene::SessionContainer> session_container;
4788 CachedPtr<shell::FocusSetter> shell_focus_setter;
4789- CachedPtr<shell::FocusSequence> shell_focus_sequence;
4790 CachedPtr<shell::PlacementStrategy> shell_placement_strategy;
4791 CachedPtr<shell::SessionListener> shell_session_listener;
4792- CachedPtr<shell::PixelBuffer> shell_pixel_buffer;
4793- CachedPtr<shell::SnapshotStrategy> shell_snapshot_strategy;
4794+ CachedPtr<scene::PixelBuffer> pixel_buffer;
4795+ CachedPtr<scene::SnapshotStrategy> snapshot_strategy;
4796 CachedPtr<shell::DisplayLayout> shell_display_layout;
4797 CachedPtr<shell::SurfaceConfigurator> shell_surface_configurator;
4798 CachedPtr<compositor::DisplayBufferCompositorFactory> display_buffer_compositor_factory;
4799@@ -297,26 +283,35 @@
4800 CachedPtr<compositor::Compositor> compositor;
4801 CachedPtr<logging::Logger> logger;
4802 CachedPtr<graphics::DisplayReport> display_report;
4803- CachedPtr<surfaces::SurfaceController> surface_controller;
4804 CachedPtr<time::TimeSource> time_source;
4805 CachedPtr<MainLoop> main_loop;
4806 CachedPtr<ServerStatusListener> server_status_listener;
4807 CachedPtr<graphics::DisplayConfigurationPolicy> display_configuration_policy;
4808 CachedPtr<graphics::nested::HostConnection> host_connection;
4809- CachedPtr<input::NestedInputRelay> nested_input_relay;
4810- CachedPtr<shell::MediatingDisplayChanger> mediating_display_changer;
4811- CachedPtr<shell::BroadcastingSessionEventSink> broadcasting_session_event_sink;
4812+ CachedPtr<scene::MediatingDisplayChanger> mediating_display_changer;
4813
4814 private:
4815 std::shared_ptr<input::EventFilter> const default_filter;
4816-
4817 // the communications interface to use
4818 virtual std::shared_ptr<frontend::ProtobufIpcFactory> the_ipc_factory(
4819 std::shared_ptr<frontend::Shell> const& shell,
4820 std::shared_ptr<graphics::GraphicBufferAllocator> const& allocator);
4821
4822 virtual std::string the_socket_file() const;
4823- std::shared_ptr<input::NestedInputRelay> the_nested_input_relay();
4824+
4825+ // The following caches and factory functions are internal to the
4826+ // default implementations of corresponding the Mir components
4827+ CachedPtr<scene::BroadcastingSessionEventSink> broadcasting_session_event_sink;
4828+ CachedPtr<input::NestedInputRelay> nested_input_relay;
4829+ CachedPtr<scene::SurfaceController> surface_controller;
4830+ CachedPtr<scene::SessionManager> session_manager;
4831+
4832+ std::shared_ptr<scene::BroadcastingSessionEventSink> the_broadcasting_session_event_sink();
4833+ std::shared_ptr<input::NestedInputRelay> the_nested_input_relay();
4834+ std::shared_ptr<scene::SessionManager> the_session_manager();
4835+ std::shared_ptr<scene::SurfaceBuilder> the_surface_builder();
4836+ std::shared_ptr<scene::SurfaceController> the_surface_controller();
4837+ std::function<void()> force_threads_to_unblock_callback();
4838 };
4839 }
4840
4841
4842=== modified file 'include/server/mir/frontend/shell.h'
4843--- include/server/mir/frontend/shell.h 2013-08-28 03:41:48 +0000
4844+++ include/server/mir/frontend/shell.h 2013-11-22 04:49:56 +0000
4845@@ -36,7 +36,7 @@
4846 class Shell
4847 {
4848 public:
4849- virtual ~Shell() {}
4850+ virtual ~Shell() = default;
4851
4852 virtual std::shared_ptr<Session> open_session(
4853 std::string const& name, std::shared_ptr<EventSink> const& sink) = 0;
4854@@ -44,7 +44,7 @@
4855
4856 virtual SurfaceId create_surface_for(std::shared_ptr<Session> const& session,
4857 shell::SurfaceCreationParameters const& params) = 0;
4858-
4859+
4860 virtual void handle_surface_created(std::shared_ptr<Session> const& session) = 0;
4861
4862 protected:
4863
4864=== modified file 'include/server/mir/frontend/surface.h'
4865--- include/server/mir/frontend/surface.h 2013-10-15 08:53:10 +0000
4866+++ include/server/mir/frontend/surface.h 2013-11-22 04:49:56 +0000
4867@@ -25,6 +25,8 @@
4868 #include "mir/geometry/size.h"
4869 #include "mir_toolkit/common.h"
4870
4871+#include <glm/glm.hpp>
4872+
4873 #include <memory>
4874
4875 namespace mir
4876@@ -55,12 +57,7 @@
4877 virtual geometry::Size size() const = 0;
4878 virtual geometry::PixelFormat pixel_format() const = 0;
4879
4880- /// Submit the current client buffer, return the next client buffer
4881- ///
4882- /// \param [out] need_ipc: True if the buffer content must be sent via IPC
4883- /// False if only the buffer's ID must be sent.
4884- /// \returns The next client buffer
4885- virtual std::shared_ptr<graphics::Buffer> advance_client_buffer(bool& need_full_ipc) = 0;
4886+ virtual std::shared_ptr<graphics::Buffer> advance_client_buffer() = 0;
4887
4888 virtual bool supports_input() const = 0;
4889 virtual int client_input_fd() const = 0;
4890@@ -75,21 +72,7 @@
4891
4892 auto as_internal_surface(std::shared_ptr<Surface> const& surface)
4893 -> std::shared_ptr<graphics::InternalSurface>;
4894-
4895-class ClientTrackingSurface : public Surface
4896-{
4897-public:
4898- ClientTrackingSurface();
4899- virtual ~ClientTrackingSurface() = default;
4900-
4901- virtual std::shared_ptr<graphics::Buffer> advance_client_buffer(bool& need_full_ipc) override;
4902-
4903- virtual std::shared_ptr<graphics::Buffer> advance_client_buffer() = 0;
4904-private:
4905- std::shared_ptr<ClientBufferTracker> client_tracker;
4906-};
4907-
4908-}
4909+}
4910 }
4911
4912
4913
4914=== modified file 'include/server/mir/input/android/dispatcher_input_configuration.h'
4915--- include/server/mir/input/android/dispatcher_input_configuration.h 2013-09-10 16:42:04 +0000
4916+++ include/server/mir/input/android/dispatcher_input_configuration.h 2013-11-22 04:49:56 +0000
4917@@ -90,7 +90,7 @@
4918 std::shared_ptr<input::InputReport> const& input_report);
4919 virtual ~DispatcherInputConfiguration();
4920
4921- std::shared_ptr<surfaces::InputRegistrar> the_input_registrar();
4922+ std::shared_ptr<scene::InputRegistrar> the_input_registrar();
4923 std::shared_ptr<shell::InputTargeter> the_input_targeter();
4924 std::shared_ptr<input::InputManager> the_input_manager();
4925
4926
4927=== modified file 'include/server/mir/input/input_configuration.h'
4928--- include/server/mir/input/input_configuration.h 2013-05-24 19:27:37 +0000
4929+++ include/server/mir/input/input_configuration.h 2013-11-22 04:49:56 +0000
4930@@ -23,7 +23,7 @@
4931
4932 namespace mir
4933 {
4934-namespace surfaces
4935+namespace scene
4936 {
4937 class InputRegistrar;
4938 }
4939@@ -41,7 +41,7 @@
4940 public:
4941 virtual ~InputConfiguration() {}
4942
4943- virtual std::shared_ptr<surfaces::InputRegistrar> the_input_registrar() = 0;
4944+ virtual std::shared_ptr<scene::InputRegistrar> the_input_registrar() = 0;
4945 virtual std::shared_ptr<shell::InputTargeter> the_input_targeter() = 0;
4946 virtual std::shared_ptr<input::InputManager> the_input_manager() = 0;
4947
4948
4949=== renamed directory 'include/server/mir/surfaces' => 'include/server/mir/scene'
4950=== modified file 'include/server/mir/scene/buffer_stream_factory.h'
4951--- include/server/mir/surfaces/buffer_stream_factory.h 2013-11-06 03:17:35 +0000
4952+++ include/server/mir/scene/buffer_stream_factory.h 2013-11-22 04:49:56 +0000
4953@@ -18,8 +18,8 @@
4954 * Thomas Voss <thomas.voss@canonical.com>
4955 */
4956
4957-#ifndef MIR_SURFACES_BUFFER_STREAM_FACTORY_H_
4958-#define MIR_SURFACES_BUFFER_STREAM_FACTORY_H_
4959+#ifndef MIR_SCENE_BUFFER_STREAM_FACTORY_H_
4960+#define MIR_SCENE_BUFFER_STREAM_FACTORY_H_
4961
4962 #include <memory>
4963
4964@@ -28,7 +28,7 @@
4965 namespace compositor { class BufferStream; }
4966 namespace graphics { struct BufferProperties; }
4967
4968-namespace surfaces
4969+namespace scene
4970 {
4971 class BufferStreamFactory
4972 {
4973@@ -47,4 +47,4 @@
4974 }
4975 }
4976
4977-#endif // MIR_SURFACES_BUFFER_STREAM_FACTORY_H_
4978+#endif // MIR_SCENE_BUFFER_STREAM_FACTORY_H_
4979
4980=== modified file 'include/server/mir/scene/depth_id.h'
4981--- include/server/mir/surfaces/depth_id.h 2013-08-28 03:41:48 +0000
4982+++ include/server/mir/scene/depth_id.h 2013-11-22 04:49:56 +0000
4983@@ -16,14 +16,14 @@
4984 * Authored By: Robert Carr <racarr@canonical.com>
4985 */
4986
4987-#ifndef MIR_SURFACES_DEPTH_ID_H_
4988-#define MIR_SURFACES_DEPTH_ID_H_
4989+#ifndef MIR_SCENE_DEPTH_ID_H_
4990+#define MIR_SCENE_DEPTH_ID_H_
4991
4992 #include "mir/int_wrapper.h"
4993
4994 namespace mir
4995 {
4996-namespace surfaces
4997+namespace scene
4998 {
4999 namespace detail { struct DepthIdIdTag; }
5000
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches