Mir

Merge lp:~kdub/mir/n7-support into lp:mir/0.1

Proposed by Kevin DuBois
Status: Superseded
Proposed branch: lp:~kdub/mir/n7-support
Merge into: lp:mir/0.1
Diff against target: 20671 lines (+6569/-4994)
329 files modified
3rd_party/android-input/android/CMakeLists.txt (+1/-0)
3rd_party/android-input/android/frameworks/base/include/androidfw/Input.h (+5/-2)
3rd_party/android-input/android/frameworks/base/include/androidfw/InputTransport.h (+10/-7)
3rd_party/android-input/android/frameworks/base/include/androidfw/IntSet.h (+104/-0)
3rd_party/android-input/android/frameworks/base/include/androidfw/VelocityControl.h (+2/-0)
3rd_party/android-input/android/frameworks/base/include/androidfw/VelocityTracker.h (+24/-22)
3rd_party/android-input/android/frameworks/base/services/input/InputDevice.cpp (+6/-3)
3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp (+40/-33)
3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.h (+6/-6)
3rd_party/android-input/android/frameworks/base/services/input/InputEventPrinter.h (+138/-0)
3rd_party/android-input/android/frameworks/base/services/input/InputListener.h (+1/-1)
3rd_party/android-input/android/frameworks/base/services/input/InputReader.cpp (+409/-354)
3rd_party/android-input/android/frameworks/base/services/input/InputReader.h (+68/-40)
3rd_party/android-input/android/frameworks/base/services/input/InputTransport.cpp (+8/-8)
3rd_party/android-input/android/frameworks/base/services/input/IntSet.cpp (+123/-0)
3rd_party/android-input/android/frameworks/base/services/input/PointerController.cpp (+5/-8)
3rd_party/android-input/android/frameworks/base/services/input/PointerController.h (+2/-5)
3rd_party/android-input/android/frameworks/base/services/input/VelocityControl.cpp (+2/-2)
3rd_party/android-input/android/frameworks/base/services/input/VelocityTracker.cpp (+80/-83)
CMakeLists.txt (+1/-1)
debian/changelog (+7/-4)
debian/control (+2/-2)
debian/libmirserver11.install (+1/-1)
doc/Doxyfile.in (+192/-82)
doc/building_source_for_android.md (+4/-4)
doc/component_reports.md (+3/-0)
doc/installing_prebuilt_on_pc.md (+2/-2)
doc/using_mir_on_pc.md (+6/-4)
examples/demo-inprocess-surface-client/demo_inprocess_surface_client.cpp (+2/-1)
examples/demo-inprocess-surface-client/inprocess_egl_client.cpp (+12/-11)
examples/demo-inprocess-surface-client/inprocess_egl_client.h (+9/-11)
examples/demo-shell/demo_shell.cpp (+0/-5)
examples/demo-shell/window_manager.cpp (+2/-9)
examples/demo-shell/window_manager.h (+0/-3)
examples/demo_input_filter.cpp (+25/-3)
examples/image_renderer.cpp (+59/-5)
examples/render_surfaces.cpp (+19/-16)
examples/render_to_fb.cpp (+1/-4)
include/client/mir_toolkit/mir_client_library_drm.h (+14/-0)
include/platform/mir/graphics/nested_context.h (+3/-0)
include/server/mir/compositor/buffer_stream.h (+6/-5)
include/server/mir/compositor/scene.h (+3/-6)
include/server/mir/default_configuration_options.h (+2/-0)
include/server/mir/default_server_configuration.h (+10/-1)
include/server/mir/frontend/surface.h (+2/-21)
include/server/mir/shell/application_session.h (+3/-0)
include/server/mir/shell/focus_controller.h (+6/-2)
include/server/mir/shell/session.h (+1/-0)
include/server/mir/shell/session_manager.h (+3/-0)
include/server/mir/shell/surface.h (+16/-68)
include/server/mir/shell/surface_builder.h (+3/-3)
include/server/mir/shell/surface_controller.h (+2/-2)
include/server/mir/surfaces/basic_surface.h (+40/-48)
include/server/mir/surfaces/buffer_stream_factory.h (+3/-4)
include/server/mir/surfaces/surface_controller.h (+6/-6)
include/server/mir/surfaces/surfaces_report.h (+60/-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/test/mir_test/draw/android_graphics.h (+1/-1)
include/test/mir_test_doubles/mock_android_framebuffer_window.h (+0/-46)
include/test/mir_test_doubles/mock_buffer_bundle.h (+1/-0)
include/test/mir_test_doubles/mock_buffer_stream.h (+3/-2)
include/test/mir_test_doubles/mock_display_device.h (+6/-6)
include/test/mir_test_doubles/mock_egl.h (+17/-0)
include/test/mir_test_doubles/mock_focus_setter.h (+1/-1)
include/test/mir_test_doubles/mock_frontend_surface.h (+1/-1)
include/test/mir_test_doubles/mock_hwc_composer_device_1.h (+8/-0)
include/test/mir_test_doubles/mock_shell_session.h (+2/-0)
include/test/mir_test_doubles/mock_surface.h (+3/-3)
include/test/mir_test_doubles/mock_surface_controller.h (+1/-1)
include/test/mir_test_doubles/mock_surface_renderer.h (+4/-3)
include/test/mir_test_doubles/mock_surface_state.h (+1/-0)
include/test/mir_test_doubles/null_session_event_sink.h (+1/-1)
include/test/mir_test_doubles/null_snapshot_strategy.h (+1/-1)
include/test/mir_test_doubles/stub_buffer_allocator.h (+1/-9)
include/test/mir_test_doubles/stub_buffer_stream.h (+6/-2)
include/test/mir_test_doubles/stub_display_buffer_factory.h (+75/-0)
include/test/mir_test_doubles/stub_display_device.h (+12/-10)
include/test/mir_test_doubles/stub_driver_interpreter.h (+75/-0)
include/test/mir_test_doubles/stub_ipc_factory.h (+2/-2)
include/test/mir_test_doubles/stub_shell_session.h (+4/-0)
include/test/mir_test_doubles/stub_surface.h (+1/-1)
include/test/mir_test_doubles/stub_surface_builder.h (+12/-6)
include/test/mir_test_doubles/stub_surface_controller.h (+1/-1)
src/client/CMakeLists.txt (+1/-0)
src/client/default_connection_configuration.cpp (+20/-2)
src/client/default_connection_configuration.h (+9/-0)
src/client/logging/input_receiver_report.cpp (+125/-0)
src/client/logging/input_receiver_report.h (+54/-0)
src/client/lttng/CMakeLists.txt (+5/-4)
src/client/mir_client_library.cpp (+29/-8)
src/client/mir_connection.cpp (+16/-0)
src/client/mir_connection.h (+4/-0)
src/platform/graphics/CMakeLists.txt (+0/-1)
src/server/CMakeLists.txt (+2/-1)
src/server/compositor/CMakeLists.txt (+1/-0)
src/server/compositor/buffer_bundle.h (+1/-0)
src/server/compositor/buffer_stream_factory.cpp (+3/-3)
src/server/compositor/buffer_stream_factory.h (+1/-1)
src/server/compositor/buffer_stream_surfaces.cpp (+6/-1)
src/server/compositor/buffer_stream_surfaces.h (+3/-2)
src/server/compositor/bypass.cpp (+2/-2)
src/server/compositor/bypass.h (+3/-3)
src/server/compositor/default_configuration.cpp (+85/-0)
src/server/compositor/default_display_buffer_compositor.cpp (+3/-3)
src/server/compositor/default_display_buffer_compositor_factory.cpp (+3/-3)
src/server/compositor/default_display_buffer_compositor_factory.h (+2/-0)
src/server/compositor/gl_renderer.cpp (+2/-2)
src/server/compositor/gl_renderer.h (+2/-2)
src/server/compositor/gl_renderer_factory.cpp (+1/-1)
src/server/compositor/gl_renderer_factory.h (+1/-1)
src/server/compositor/multi_threaded_compositor.cpp (+1/-1)
src/server/compositor/occlusion.cpp (+1/-1)
src/server/compositor/occlusion.h (+1/-1)
src/server/compositor/renderer.h (+2/-5)
src/server/compositor/rendering_operator.cpp (+2/-3)
src/server/compositor/rendering_operator.h (+2/-2)
src/server/compositor/switching_bundle.cpp (+20/-3)
src/server/compositor/switching_bundle.h (+12/-3)
src/server/default_configuration_options.cpp (+6/-0)
src/server/default_server_configuration.cpp (+0/-672)
src/server/frontend/CMakeLists.txt (+1/-0)
src/server/frontend/default_configuration.cpp (+97/-2)
src/server/frontend/global_event_sender.cpp (+1/-1)
src/server/frontend/global_event_sender.h (+1/-1)
src/server/frontend/protobuf_message_processor.cpp (+1/-1)
src/server/frontend/protobuf_session_creator.cpp (+1/-1)
src/server/frontend/resource_cache.cpp (+1/-1)
src/server/frontend/session_mediator.cpp (+53/-32)
src/server/frontend/session_mediator.h (+4/-1)
src/server/frontend/session_mediator_android.cpp (+1/-1)
src/server/frontend/session_mediator_gbm.cpp (+1/-1)
src/server/frontend/surface.cpp (+1/-16)
src/server/frontend/unauthorized_display_changer.cpp (+5/-6)
src/server/frontend/unauthorized_display_changer.h (+4/-4)
src/server/graphics/CMakeLists.txt (+7/-0)
src/server/graphics/android/CMakeLists.txt (+1/-2)
src/server/graphics/android/android_display.cpp (+52/-12)
src/server/graphics/android/android_display.h (+13/-10)
src/server/graphics/android/android_display_buffer_factory.h (+6/-12)
src/server/graphics/android/android_display_factory.cpp (+0/-96)
src/server/graphics/android/android_display_factory.h (+0/-57)
src/server/graphics/android/android_framebuffer_window.cpp (+0/-78)
src/server/graphics/android/android_framebuffer_window.h (+0/-50)
src/server/graphics/android/android_framebuffer_window_query.h (+0/-44)
src/server/graphics/android/android_platform.cpp (+24/-12)
src/server/graphics/android/android_platform.h (+8/-2)
src/server/graphics/android/display_buffer.cpp (+80/-0)
src/server/graphics/android/display_buffer.h (+60/-0)
src/server/graphics/android/display_buffer_factory.cpp (+66/-90)
src/server/graphics/android/display_buffer_factory.h (+23/-7)
src/server/graphics/android/display_device.h (+7/-8)
src/server/graphics/android/display_resource_factory.h (+16/-14)
src/server/graphics/android/fb_device.cpp (+1/-3)
src/server/graphics/android/fb_device.h (+2/-2)
src/server/graphics/android/hwc10_device.cpp (+10/-13)
src/server/graphics/android/hwc10_device.h (+9/-6)
src/server/graphics/android/hwc11_device.cpp (+55/-12)
src/server/graphics/android/hwc11_device.h (+5/-6)
src/server/graphics/android/hwc_common_device.cpp (+1/-17)
src/server/graphics/android/hwc_common_device.h (+4/-8)
src/server/graphics/android/hwc_layerlist.cpp (+74/-102)
src/server/graphics/android/hwc_layerlist.h (+46/-59)
src/server/graphics/android/resource_factory.cpp (+63/-60)
src/server/graphics/android/resource_factory.h (+24/-23)
src/server/graphics/android/server_render_window.cpp (+2/-2)
src/server/graphics/android/server_render_window.h (+3/-3)
src/server/graphics/default_configuration.cpp (+146/-0)
src/server/graphics/default_display_configuration_policy.cpp (+6/-6)
src/server/graphics/default_display_configuration_policy.h (+3/-6)
src/server/graphics/gbm/native_gbm_platform.cpp (+1/-0)
src/server/graphics/nested/host_connection.cpp (+3/-3)
src/server/graphics/nested/host_connection.h (+1/-1)
src/server/graphics/nested/nested_display.cpp (+30/-20)
src/server/graphics/nested/nested_display.h (+1/-1)
src/server/graphics/nested/nested_platform.cpp (+11/-2)
src/server/graphics/nested/nested_platform.h (+1/-1)
src/server/input/CMakeLists.txt (+1/-0)
src/server/input/android/dummy_android_pointer_controller.h (+2/-4)
src/server/input/default_configuration.cpp (+128/-0)
src/server/input/display_input_region.cpp (+1/-1)
src/server/input/event_filter_chain.cpp (+1/-1)
src/server/input/nested_input_configuration.cpp (+2/-2)
src/server/input/nested_input_relay.cpp (+1/-1)
src/server/input/null_input_configuration.cpp (+1/-1)
src/server/logging/CMakeLists.txt (+2/-0)
src/server/logging/connector_report.cpp (+1/-1)
src/server/logging/default_configuration.cpp (+112/-0)
src/server/logging/display_report.cpp (+4/-3)
src/server/logging/session_mediator_report.cpp (+1/-1)
src/server/logging/surfaces_report.cpp (+119/-0)
src/server/logging/surfaces_report.h (+56/-0)
src/server/lttng/CMakeLists.txt (+5/-4)
src/server/shell/CMakeLists.txt (+1/-3)
src/server/shell/application_session.cpp (+1/-1)
src/server/shell/broadcasting_session_event_sink.cpp (+1/-1)
src/server/shell/broadcasting_session_event_sink.h (+2/-2)
src/server/shell/consuming_placement_strategy.cpp (+1/-1)
src/server/shell/default_configuration.cpp (+202/-0)
src/server/shell/default_focus_mechanism.cpp (+1/-1)
src/server/shell/default_focus_mechanism.h (+1/-1)
src/server/shell/default_session_container.cpp (+1/-1)
src/server/shell/gl_pixel_buffer.cpp (+1/-1)
src/server/shell/gl_pixel_buffer.h (+1/-1)
src/server/shell/graphics_display_layout.cpp (+1/-1)
src/server/shell/mediating_display_changer.cpp (+2/-2)
src/server/shell/organising_surface_factory.cpp (+1/-1)
src/server/shell/registration_order_focus_sequence.cpp (+1/-1)
src/server/shell/registration_order_focus_sequence.h (+1/-1)
src/server/shell/session_manager.cpp (+3/-3)
src/server/shell/threaded_snapshot_strategy.cpp (+2/-2)
src/server/shell/threaded_snapshot_strategy.h (+1/-1)
src/server/surfaces/CMakeLists.txt (+4/-0)
src/server/surfaces/default_configuration.cpp (+111/-0)
src/server/surfaces/mutable_surface_state.h (+1/-0)
src/server/surfaces/surface.cpp (+33/-9)
src/server/surfaces/surface.h (+81/-0)
src/server/surfaces/surface_allocator.cpp (+10/-8)
src/server/surfaces/surface_allocator.h (+6/-3)
src/server/surfaces/surface_controller.cpp (+4/-4)
src/server/surfaces/surface_data.cpp (+10/-0)
src/server/surfaces/surface_data.h (+1/-0)
src/server/surfaces/surface_factory.h (+2/-2)
src/server/surfaces/surface_impl.cpp (+37/-29)
src/server/surfaces/surface_impl.h (+110/-0)
src/server/surfaces/surface_source.cpp (+6/-9)
src/server/surfaces/surface_source.h (+13/-10)
src/server/surfaces/surface_stack.cpp (+33/-18)
src/server/surfaces/surface_stack.h (+11/-8)
src/server/surfaces/surface_stack_model.h (+4/-4)
src/server/surfaces/surfaces_report.cpp (+27/-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)
tests/acceptance-tests/CMakeLists.txt (+1/-0)
tests/acceptance-tests/test_client_input.cpp (+2/-2)
tests/acceptance-tests/test_client_library_drm.cpp (+59/-0)
tests/acceptance-tests/test_display_configuration.cpp (+3/-17)
tests/acceptance-tests/test_focus_selection.cpp (+3/-3)
tests/acceptance-tests/test_server_shutdown.cpp (+15/-10)
tests/acceptance-tests/test_surfaces_with_output_id.cpp (+1/-1)
tests/integration-tests/compositor/test_buffer_stream.cpp (+77/-5)
tests/integration-tests/compositor/test_swapping_swappers.cpp (+1/-1)
tests/integration-tests/graphics/android/test_display_integration.cpp (+36/-105)
tests/integration-tests/graphics/android/test_internal_client.cpp (+16/-9)
tests/integration-tests/graphics/gbm/test_buffer_integration.cpp (+6/-10)
tests/integration-tests/shell/test_session.cpp (+8/-19)
tests/integration-tests/shell/test_session_manager.cpp (+5/-6)
tests/integration-tests/test_display_info.cpp (+7/-13)
tests/integration-tests/test_drm_auth_magic.cpp (+2/-17)
tests/integration-tests/test_error_reporting.cpp (+2/-2)
tests/integration-tests/test_surface_first_frame_sync.cpp (+3/-3)
tests/integration-tests/test_surfaceloop.cpp (+9/-20)
tests/integration-tests/test_swapinterval.cpp (+7/-6)
tests/mir-stress/src/client.h (+1/-1)
tests/mir_test_doubles/mock_egl.cpp (+1/-1)
tests/mir_test_framework/testing_server_options.cpp (+9/-14)
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/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_client_mir_surface.cpp (+1/-1)
tests/unit-tests/client/test_mir_connection.cpp (+48/-1)
tests/unit-tests/compositor/test_buffer_stream.cpp (+14/-3)
tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp (+5/-5)
tests/unit-tests/compositor/test_gl_renderer.cpp (+4/-4)
tests/unit-tests/compositor/test_multi_threaded_compositor.cpp (+1/-1)
tests/unit-tests/compositor/test_rendering_operator.cpp (+2/-3)
tests/unit-tests/compositor/test_switching_bundle.cpp (+149/-22)
tests/unit-tests/frontend/CMakeLists.txt (+1/-0)
tests/unit-tests/frontend/stress_protobuf_communicator.cpp (+1/-1)
tests/unit-tests/frontend/test_global_event_sender.cpp (+1/-1)
tests/unit-tests/frontend/test_protobuf_reports_errors.cpp (+1/-1)
tests/unit-tests/frontend/test_protobuf_sends_fds.cpp (+1/-1)
tests/unit-tests/frontend/test_protobuf_surface_apis.cpp (+1/-1)
tests/unit-tests/frontend/test_published_socket_connector.cpp (+1/-1)
tests/unit-tests/frontend/test_resource_cache.cpp (+1/-1)
tests/unit-tests/frontend/test_session_mediator.cpp (+6/-12)
tests/unit-tests/frontend/test_session_mediator_android.cpp (+4/-18)
tests/unit-tests/frontend/test_session_mediator_gbm.cpp (+5/-19)
tests/unit-tests/frontend/test_unauthorized_display_changer.cpp (+3/-4)
tests/unit-tests/graphics/android/CMakeLists.txt (+2/-3)
tests/unit-tests/graphics/android/test_android_display_factory.cpp (+0/-210)
tests/unit-tests/graphics/android/test_android_fb.cpp (+179/-499)
tests/unit-tests/graphics/android/test_android_framebuffer_window.cpp (+0/-283)
tests/unit-tests/graphics/android/test_android_platform.cpp (+7/-4)
tests/unit-tests/graphics/android/test_display_buffer_factory.cpp (+214/-0)
tests/unit-tests/graphics/android/test_fb_device.cpp (+35/-34)
tests/unit-tests/graphics/android/test_hwc10_device.cpp (+27/-47)
tests/unit-tests/graphics/android/test_hwc11_device.cpp (+75/-47)
tests/unit-tests/graphics/android/test_hwc_device.cpp (+30/-88)
tests/unit-tests/graphics/android/test_hwc_display.cpp (+115/-94)
tests/unit-tests/graphics/android/test_hwc_layerlist.cpp (+99/-134)
tests/unit-tests/graphics/android/test_resource_factory.cpp (+65/-73)
tests/unit-tests/graphics/android/test_server_interpreter.cpp (+16/-18)
tests/unit-tests/graphics/gbm/test_gbm_display.cpp (+2/-2)
tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp (+1/-1)
tests/unit-tests/graphics/gbm/test_gbm_display_multi_monitor.cpp (+1/-1)
tests/unit-tests/graphics/gbm/test_native_gbm_platform.cpp (+12/-0)
tests/unit-tests/graphics/test_default_display_configuration_policy.cpp (+1/-1)
tests/unit-tests/graphics/test_display.cpp (+12/-26)
tests/unit-tests/input/android/test_android_input_lexicon.cpp (+14/-0)
tests/unit-tests/input/test_display_input_region.cpp (+1/-1)
tests/unit-tests/input/test_event_filter_chain.cpp (+1/-1)
tests/unit-tests/logging/test_display_report.cpp (+3/-2)
tests/unit-tests/options/test_program_option.cpp (+4/-4)
tests/unit-tests/shell/CMakeLists.txt (+0/-3)
tests/unit-tests/shell/test_broadcasting_session_event_sink.cpp (+1/-1)
tests/unit-tests/shell/test_consuming_placement_strategy.cpp (+1/-1)
tests/unit-tests/shell/test_default_focus_mechanism.cpp (+3/-3)
tests/unit-tests/shell/test_gl_pixel_buffer.cpp (+1/-1)
tests/unit-tests/shell/test_graphics_display_layout.cpp (+1/-1)
tests/unit-tests/shell/test_mediating_display_changer.cpp (+2/-2)
tests/unit-tests/shell/test_organising_surface_factory.cpp (+1/-1)
tests/unit-tests/shell/test_registration_order_focus_sequence.cpp (+3/-3)
tests/unit-tests/shell/test_session_manager.cpp (+8/-8)
tests/unit-tests/shell/test_the_session_container_implementation.cpp (+2/-2)
tests/unit-tests/shell/test_threaded_snapshot_strategy.cpp (+2/-2)
tests/unit-tests/surfaces/CMakeLists.txt (+1/-0)
tests/unit-tests/surfaces/test_surface.cpp (+70/-19)
tests/unit-tests/surfaces/test_surface_allocator.cpp (+1/-1)
tests/unit-tests/surfaces/test_surface_controller.cpp (+6/-6)
tests/unit-tests/surfaces/test_surface_data.cpp (+18/-0)
tests/unit-tests/surfaces/test_surface_impl.cpp (+39/-33)
tests/unit-tests/surfaces/test_surface_stack.cpp (+83/-36)
tools/setup-partial-armhf-chroot.sh (+17/-17)
To merge this branch: bzr merge lp:~kdub/mir/n7-support
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Mir development team Pending
Review via email: mp+194576@code.launchpad.net

Commit message

graphics: android: support 'old aka 2012' nexus 7 hwc (nvidia tegra3 SoC) better.

Description of the change

graphics: android: support 'old aka 2012' nexus 7 hwc (nvidia tegra3 SoC) better.

improve hwc1.0 support to avert segfaulting on mir startup with hwc1.0 on tegra 3.
Mir demo clients seem to work well. Unity8 is still affected by lp:1238695

improve HWCLayerList class a bit as well. Before it was just made one layer on construction, now you can use an initializer list to have multiple layers.

These are hwc1.0 changes primarily, so I gave a basic sanity test to:
Galaxy Nexus (hwc1.0)
Nexus 7 (hwc1.0)
Nexus 4 (hwc1.1)

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '3rd_party/android-input/android/CMakeLists.txt'
2--- 3rd_party/android-input/android/CMakeLists.txt 2013-10-15 08:53:10 +0000
3+++ 3rd_party/android-input/android/CMakeLists.txt 2013-11-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +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-08 19:16:38 +0000
2909@@ -27,7 +27,7 @@
2910 #include <limits.h>
2911
2912 #include <androidfw/VelocityTracker.h>
2913-#include <std/BitSet.h>
2914+#include <androidfw/IntSet.h>
2915 #include <std/String8.h>
2916 #include <std/Timers.h>
2917 #include <std/Log.h>
2918@@ -109,7 +109,7 @@
2919 const char* VelocityTracker::DEFAULT_STRATEGY = "lsq2";
2920
2921 VelocityTracker::VelocityTracker(const char* strategy) :
2922- mLastEventTime(0), mCurrentPointerIdBits(0), mActivePointerId(-1) {
2923+ mLastEventTime(0), mActivePointerId(-1) {
2924 char value[PROPERTY_VALUE_MAX];
2925
2926 // Allow the default strategy to be overridden using a system property for debugging.
2927@@ -202,29 +202,24 @@
2928 }
2929
2930 void VelocityTracker::clear() {
2931- mCurrentPointerIdBits.clear();
2932+ mCurrentPointerIds.clear();
2933 mActivePointerId = -1;
2934
2935 mStrategy->clear();
2936 }
2937
2938-void VelocityTracker::clearPointers(BitSet32 idBits) {
2939- BitSet32 remainingIdBits(mCurrentPointerIdBits.value & ~idBits.value);
2940- mCurrentPointerIdBits = remainingIdBits;
2941+void VelocityTracker::clearPointers(const IntSet &ids) {
2942+ mCurrentPointerIds.remove(ids);
2943
2944- if (mActivePointerId >= 0 && idBits.hasBit(mActivePointerId)) {
2945- mActivePointerId = !remainingIdBits.isEmpty() ? remainingIdBits.firstMarkedBit() : -1;
2946+ if (mActivePointerId >= 0 && ids.contains(mActivePointerId)) {
2947+ mActivePointerId = !mCurrentPointerIds.isEmpty() ? mCurrentPointerIds.first() : -1;
2948 }
2949
2950- mStrategy->clearPointers(idBits);
2951+ mStrategy->clearPointers(ids);
2952 }
2953
2954-void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions) {
2955- while (idBits.count() > MAX_POINTERS) {
2956- idBits.clearLastMarkedBit();
2957- }
2958-
2959- if ((mCurrentPointerIdBits.value & idBits.value)
2960+void VelocityTracker::addMovement(nsecs_t eventTime, const IntSet &ids, const Position* positions) {
2961+ if (!(mCurrentPointerIds & ids).isEmpty()
2962 && eventTime >= mLastEventTime + ASSUME_POINTER_STOPPED_TIME) {
2963 #if DEBUG_VELOCITY
2964 ALOGD("VelocityTracker: stopped for %0.3f ms, clearing state.",
2965@@ -236,20 +231,18 @@
2966 }
2967 mLastEventTime = eventTime;
2968
2969- mCurrentPointerIdBits = idBits;
2970- if (mActivePointerId < 0 || !idBits.hasBit(mActivePointerId)) {
2971- mActivePointerId = idBits.isEmpty() ? -1 : idBits.firstMarkedBit();
2972+ mCurrentPointerIds = ids;
2973+ if (mActivePointerId < 0 || !ids.contains(mActivePointerId)) {
2974+ mActivePointerId = ids.isEmpty() ? -1 : ids.first();
2975 }
2976
2977- mStrategy->addMovement(eventTime, idBits, positions);
2978+ mStrategy->addMovement(eventTime, ids, positions);
2979
2980 #if DEBUG_VELOCITY
2981- ALOGD("VelocityTracker: addMovement eventTime=%lld, idBits=0x%08x, activePointerId=%d",
2982- eventTime, idBits.value, mActivePointerId);
2983- for (BitSet32 iterBits(idBits); !iterBits.isEmpty(); ) {
2984- uint32_t id = iterBits.firstMarkedBit();
2985- uint32_t index = idBits.getIndexOfBit(id);
2986- iterBits.clearBit(id);
2987+ ALOGD("VelocityTracker: addMovement eventTime=%lld, ids.cont()=%d, activePointerId=%d",
2988+ eventTime, ids.count(), mActivePointerId);
2989+ size_t index = 0;
2990+ ids.forEach([&](int32_t id) {
2991 Estimator estimator;
2992 getEstimator(id, &estimator);
2993 ALOGD(" %d: position (%0.3f, %0.3f), "
2994@@ -259,6 +252,7 @@
2995 vectorToString(estimator.xCoeff, estimator.degree + 1).string(),
2996 vectorToString(estimator.yCoeff, estimator.degree + 1).string(),
2997 estimator.confidence);
2998+ ++index;
2999 }
3000 #endif
3001 }
3002@@ -276,9 +270,9 @@
3003 // Start a new movement trace for a pointer that just went down.
3004 // We do this on down instead of on up because the client may want to query the
3005 // final velocity for a pointer that just went up.
3006- BitSet32 downIdBits;
3007- downIdBits.markBit(event->getPointerId(event->getActionIndex()));
3008- clearPointers(downIdBits);
3009+ IntSet downIds;
3010+ downIds.insert(event->getPointerId(event->getActionIndex()));
3011+ clearPointers(downIds);
3012 break;
3013 }
3014 case AMOTION_EVENT_ACTION_MOVE:
3015@@ -301,14 +295,14 @@
3016 pointerCount = MAX_POINTERS;
3017 }
3018
3019- BitSet32 idBits;
3020+ IntSet ids;
3021 for (size_t i = 0; i < pointerCount; i++) {
3022- idBits.markBit(event->getPointerId(i));
3023+ ids.insert(event->getPointerId(i));
3024 }
3025
3026 uint32_t pointerIndex[MAX_POINTERS];
3027 for (size_t i = 0; i < pointerCount; i++) {
3028- pointerIndex[i] = idBits.getIndexOfBit(event->getPointerId(i));
3029+ pointerIndex[i] = ids.indexOf(event->getPointerId(i));
3030 }
3031
3032 nsecs_t eventTime;
3033@@ -322,7 +316,7 @@
3034 positions[index].x = event->getHistoricalX(i, h);
3035 positions[index].y = event->getHistoricalY(i, h);
3036 }
3037- addMovement(eventTime, idBits, positions);
3038+ addMovement(eventTime, ids, positions);
3039 }
3040
3041 eventTime = event->getEventTime();
3042@@ -331,7 +325,7 @@
3043 positions[index].x = event->getX(i);
3044 positions[index].y = event->getY(i);
3045 }
3046- addMovement(eventTime, idBits, positions);
3047+ addMovement(eventTime, ids, positions);
3048 }
3049
3050 bool VelocityTracker::getVelocity(uint32_t id, float* outVx, float* outVy) const {
3051@@ -367,15 +361,14 @@
3052
3053 void LeastSquaresVelocityTrackerStrategy::clear() {
3054 mIndex = 0;
3055- mMovements[0].idBits.clear();
3056-}
3057-
3058-void LeastSquaresVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
3059- BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value);
3060- mMovements[mIndex].idBits = remainingIdBits;
3061-}
3062-
3063-void LeastSquaresVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
3064+ mMovements[0].ids.clear();
3065+}
3066+
3067+void LeastSquaresVelocityTrackerStrategy::clearPointers(const IntSet &ids) {
3068+ mMovements[mIndex].ids.remove(ids);
3069+}
3070+
3071+void LeastSquaresVelocityTrackerStrategy::addMovement(nsecs_t eventTime, const IntSet &ids,
3072 const VelocityTracker::Position* positions) {
3073 if (++mIndex == HISTORY_SIZE) {
3074 mIndex = 0;
3075@@ -383,9 +376,9 @@
3076
3077 Movement& movement = mMovements[mIndex];
3078 movement.eventTime = eventTime;
3079- movement.idBits = idBits;
3080- uint32_t count = idBits.count();
3081- for (uint32_t i = 0; i < count; i++) {
3082+ movement.ids = ids;
3083+ size_t count = ids.count();
3084+ for (size_t i = 0; i < count; i++) {
3085 movement.positions[i] = positions[i];
3086 }
3087 }
3088@@ -570,7 +563,7 @@
3089 const Movement& newestMovement = mMovements[mIndex];
3090 do {
3091 const Movement& movement = mMovements[index];
3092- if (!movement.idBits.hasBit(id)) {
3093+ if (!movement.ids.contains(id)) {
3094 break;
3095 }
3096
3097@@ -702,36 +695,44 @@
3098 }
3099
3100 void IntegratingVelocityTrackerStrategy::clear() {
3101- mPointerIdBits.clear();
3102-}
3103-
3104-void IntegratingVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
3105- mPointerIdBits.value &= ~idBits.value;
3106-}
3107-
3108-void IntegratingVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
3109+ mPointerIds.clear();
3110+}
3111+
3112+void IntegratingVelocityTrackerStrategy::clearPointers(const IntSet &ids) {
3113+ mPointerIds.remove(ids);
3114+}
3115+
3116+void IntegratingVelocityTrackerStrategy::addMovement(nsecs_t eventTime, const IntSet &ids,
3117 const VelocityTracker::Position* positions) {
3118- uint32_t index = 0;
3119- for (BitSet32 iterIdBits(idBits); !iterIdBits.isEmpty();) {
3120- uint32_t id = iterIdBits.clearFirstMarkedBit();
3121- State& state = mPointerState[id];
3122- const VelocityTracker::Position& position = positions[index++];
3123- if (mPointerIdBits.hasBit(id)) {
3124- updateState(state, eventTime, position.x, position.y);
3125- } else {
3126- initState(state, eventTime, position.x, position.y);
3127- }
3128+
3129+ {
3130+ auto pointerIdsIt = mPointerIds.begin();
3131+ uint32_t index = 0;
3132+
3133+ for_each(ids.begin(), ids.end(), [&](int32_t id) {
3134+ State& state = mPointerState[id];
3135+ const VelocityTracker::Position& position = positions[index++];
3136+
3137+ while (*pointerIdsIt < id && pointerIdsIt != mPointerIds.end())
3138+ pointerIdsIt++;
3139+
3140+ if (pointerIdsIt != mPointerIds.end() && *pointerIdsIt == id) {
3141+ updateState(state, eventTime, position.x, position.y);
3142+ } else {
3143+ initState(state, eventTime, position.x, position.y);
3144+ }
3145+ });
3146 }
3147
3148- mPointerIdBits = idBits;
3149+ mPointerIds = ids;
3150 }
3151
3152 bool IntegratingVelocityTrackerStrategy::getEstimator(uint32_t id,
3153 VelocityTracker::Estimator* outEstimator) const {
3154 outEstimator->clear();
3155
3156- if (mPointerIdBits.hasBit(id)) {
3157- const State& state = mPointerState[id];
3158+ if (mPointerIds.contains(id)) {
3159+ const State& state = mPointerState.at(id);
3160 populateEstimator(state, outEstimator);
3161 return true;
3162 }
3163@@ -823,15 +824,14 @@
3164
3165 void LegacyVelocityTrackerStrategy::clear() {
3166 mIndex = 0;
3167- mMovements[0].idBits.clear();
3168-}
3169-
3170-void LegacyVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
3171- BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value);
3172- mMovements[mIndex].idBits = remainingIdBits;
3173-}
3174-
3175-void LegacyVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
3176+ mMovements[0].ids.clear();
3177+}
3178+
3179+void LegacyVelocityTrackerStrategy::clearPointers(const IntSet &ids) {
3180+ mMovements[mIndex].ids.remove(ids);
3181+}
3182+
3183+void LegacyVelocityTrackerStrategy::addMovement(nsecs_t eventTime, const IntSet &ids,
3184 const VelocityTracker::Position* positions) {
3185 if (++mIndex == HISTORY_SIZE) {
3186 mIndex = 0;
3187@@ -839,11 +839,8 @@
3188
3189 Movement& movement = mMovements[mIndex];
3190 movement.eventTime = eventTime;
3191- movement.idBits = idBits;
3192- uint32_t count = idBits.count();
3193- for (uint32_t i = 0; i < count; i++) {
3194- movement.positions[i] = positions[i];
3195- }
3196+ movement.ids = ids;
3197+ memcpy(movement.positions, positions, sizeof(VelocityTracker::Position) * ids.count());
3198 }
3199
3200 bool LegacyVelocityTrackerStrategy::getEstimator(uint32_t id,
3201@@ -851,7 +848,7 @@
3202 outEstimator->clear();
3203
3204 const Movement& newestMovement = mMovements[mIndex];
3205- if (!newestMovement.idBits.hasBit(id)) {
3206+ if (!newestMovement.ids.contains(id)) {
3207 return false; // no data
3208 }
3209
3210@@ -862,7 +859,7 @@
3211 do {
3212 uint32_t nextOldestIndex = (oldestIndex == 0 ? HISTORY_SIZE : oldestIndex) - 1;
3213 const Movement& nextOldestMovement = mMovements[nextOldestIndex];
3214- if (!nextOldestMovement.idBits.hasBit(id)
3215+ if (!nextOldestMovement.ids.contains(id)
3216 || nextOldestMovement.eventTime < minTime) {
3217 break;
3218 }
3219
3220=== modified file 'CMakeLists.txt'
3221--- CMakeLists.txt 2013-10-21 07:47:44 +0000
3222+++ CMakeLists.txt 2013-11-08 19:16:38 +0000
3223@@ -28,7 +28,7 @@
3224
3225 set(MIR_VERSION_MAJOR 0)
3226 set(MIR_VERSION_MINOR 1)
3227-set(MIR_VERSION_PATCH 0)
3228+set(MIR_VERSION_PATCH 1)
3229
3230 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
3231
3232
3233=== modified file 'debian/changelog'
3234--- debian/changelog 2013-11-05 09:36:37 +0000
3235+++ debian/changelog 2013-11-08 19:16:38 +0000
3236@@ -1,3 +1,9 @@
3237+mir (0.1.1-0ubuntu1) UNRELEASED; urgency=low
3238+
3239+ * Bump version to 0.1.1
3240+
3241+ -- Daniel van Vugt <daniel.van.vugt@canonical.com> Wed, 30 Oct 2013 11:46:13 +0800
3242+
3243 mir (0.1.0+14.04.20131030-0ubuntu1) trusty; urgency=low
3244
3245 [ Ubuntu daily release ]
3246@@ -13,9 +19,6 @@
3247 server crashes without the timeout, rendering it needless anyway.
3248 (LP: #1245958)
3249
3250- [ Ubuntu daily release ]
3251- * Automatic snapshot from revision 1163
3252-
3253 -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 30 Oct 2013 18:37:21 +0000
3254
3255 mir (0.1.0+14.04.20131028-0ubuntu1) trusty; urgency=low
3256@@ -117,7 +120,7 @@
3257 #1244192)
3258
3259 [ Ubuntu daily release ]
3260- * Automatic snapshot from revision 1161
3261+ * Automatic snapshot from revision 1160
3262
3263 -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 28 Oct 2013 02:04:31 +0000
3264
3265
3266=== modified file 'debian/control'
3267--- debian/control 2013-10-21 16:02:28 +0000
3268+++ debian/control 2013-11-08 19:16:38 +0000
3269@@ -69,7 +69,7 @@
3270 .
3271 Contains the protocol's definition files.
3272
3273-Package: libmirserver9
3274+Package: libmirserver11
3275 Section: libs
3276 Architecture: i386 amd64 armhf arm64
3277 Multi-Arch: same
3278@@ -115,7 +115,7 @@
3279 Architecture: i386 amd64 armhf arm64
3280 Multi-Arch: same
3281 Pre-Depends: ${misc:Pre-Depends}
3282-Depends: libmirserver9 (= ${binary:Version}),
3283+Depends: libmirserver11 (= ${binary:Version}),
3284 libmirprotobuf-dev (= ${binary:Version}),
3285 mircommon-dev (= ${binary:Version}),
3286 libglm-dev,
3287
3288=== renamed file 'debian/libmirserver9.install' => 'debian/libmirserver11.install'
3289--- debian/libmirserver9.install 2013-10-21 17:49:01 +0000
3290+++ debian/libmirserver11.install 2013-11-08 19:16:38 +0000
3291@@ -1,1 +1,1 @@
3292-usr/lib/*/libmirserver.so.9
3293+usr/lib/*/libmirserver.so.11
3294
3295=== modified file 'doc/Doxyfile.in'
3296--- doc/Doxyfile.in 2013-07-02 11:27:33 +0000
3297+++ doc/Doxyfile.in 2013-11-08 19:16:38 +0000
3298@@ -1,14 +1,16 @@
3299-# Doxyfile 1.8.1.2
3300+# Doxyfile 1.8.4
3301
3302 # This file describes the settings to be used by the documentation system
3303-# doxygen (www.doxygen.org) for a project
3304+# doxygen (www.doxygen.org) for a project.
3305 #
3306-# All text after a hash (#) is considered a comment and will be ignored
3307+# All text after a double hash (##) is considered a comment and is placed
3308+# in front of the TAG it is preceding .
3309+# All text after a hash (#) is considered a comment and will be ignored.
3310 # The format is:
3311 # TAG = value [value, ...]
3312 # For lists items can also be appended using:
3313 # TAG += value [value, ...]
3314-# Values that contain spaces should be placed between quotes (" ")
3315+# Values that contain spaces should be placed between quotes (" ").
3316
3317 #---------------------------------------------------------------------------
3318 # Project related configuration options
3319@@ -70,9 +72,9 @@
3320 # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
3321 # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
3322 # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
3323-# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
3324-# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
3325-# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
3326+# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian,
3327+# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic,
3328+# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
3329
3330 OUTPUT_LANGUAGE = English
3331
3332@@ -136,7 +138,9 @@
3333 # only done if one of the specified strings matches the left-hand part of
3334 # the path. The tag can be used to show relative paths in the file list.
3335 # If left blank the directory from which doxygen is run is used as the
3336-# path to strip.
3337+# path to strip. Note that you specify absolute paths here, but also
3338+# relative paths, which will be relative from the directory where doxygen is
3339+# started.
3340
3341 STRIP_FROM_PATH = @CMAKE_CURRENT_SOURCE_DIR@
3342
3343@@ -239,14 +243,15 @@
3344 OPTIMIZE_OUTPUT_VHDL = NO
3345
3346 # Doxygen selects the parser to use depending on the extension of the files it
3347-# parses. With this tag you can assign which parser to use for a given extension.
3348-# Doxygen has a built-in mapping, but you can override or extend it using this
3349-# tag. The format is ext=language, where ext is a file extension, and language
3350-# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
3351-# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
3352-# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
3353-# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
3354-# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
3355+# parses. With this tag you can assign which parser to use for a given
3356+# extension. Doxygen has a built-in mapping, but you can override or extend it
3357+# using this tag. The format is ext=language, where ext is a file extension,
3358+# and language is one of the parsers supported by doxygen: IDL, Java,
3359+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
3360+# C++. For instance to make doxygen treat .inc files as Fortran files (default
3361+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
3362+# that for custom extensions you also need to set FILE_PATTERNS otherwise the
3363+# files are not read by doxygen.
3364
3365 EXTENSION_MAPPING =
3366
3367@@ -259,6 +264,13 @@
3368
3369 MARKDOWN_SUPPORT = YES
3370
3371+# When enabled doxygen tries to link words that correspond to documented
3372+# classes, or namespaces to their corresponding documentation. Such a link can
3373+# be prevented in individual cases by by putting a % sign in front of the word
3374+# or globally by setting AUTOLINK_SUPPORT to NO.
3375+
3376+AUTOLINK_SUPPORT = YES
3377+
3378 # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
3379 # to include (a tag file for) the STL sources as input, then you should
3380 # set this tag to YES in order to let doxygen match functions declarations and
3381@@ -279,10 +291,10 @@
3382
3383 SIP_SUPPORT = NO
3384
3385-# For Microsoft's IDL there are propget and propput attributes to indicate getter
3386-# and setter methods for a property. Setting this option to YES (the default)
3387-# will make doxygen replace the get and set methods by a property in the
3388-# documentation. This will only work if the methods are indeed getting or
3389+# For Microsoft's IDL there are propget and propput attributes to indicate
3390+# getter and setter methods for a property. Setting this option to YES (the
3391+# default) will make doxygen replace the get and set methods by a property in
3392+# the documentation. This will only work if the methods are indeed getting or
3393 # setting a simple type. If this is not the case, or you want to show the
3394 # methods anyway, you should set this option to NO.
3395
3396@@ -311,11 +323,11 @@
3397 INLINE_GROUPED_CLASSES = NO
3398
3399 # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
3400-# unions with only public data fields will be shown inline in the documentation
3401-# of the scope in which they are defined (i.e. file, namespace, or group
3402-# documentation), provided this scope is documented. If set to NO (the default),
3403-# structs, classes, and unions are shown on a separate page (for HTML and Man
3404-# pages) or section (for LaTeX and RTF).
3405+# unions with only public data fields or simple typedef fields will be shown
3406+# inline in the documentation of the scope in which they are defined (i.e. file,
3407+# namespace, or group documentation), provided this scope is documented. If set
3408+# to NO (the default), structs, classes, and unions are shown on a separate
3409+# page (for HTML and Man pages) or section (for LaTeX and RTF).
3410
3411 INLINE_SIMPLE_STRUCTS = NO
3412
3413@@ -329,30 +341,14 @@
3414
3415 TYPEDEF_HIDES_STRUCT = NO
3416
3417-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
3418-# determine which symbols to keep in memory and which to flush to disk.
3419-# When the cache is full, less often used symbols will be written to disk.
3420-# For small to medium size projects (<1000 input files) the default value is
3421-# probably good enough. For larger projects a too small cache size can cause
3422-# doxygen to be busy swapping symbols to and from disk most of the time
3423-# causing a significant performance penalty.
3424-# If the system has enough physical memory increasing the cache will improve the
3425-# performance by keeping more symbols in memory. Note that the value works on
3426-# a logarithmic scale so increasing the size by one will roughly double the
3427-# memory usage. The cache size is given by this formula:
3428-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
3429-# corresponding to a cache size of 2^16 = 65536 symbols.
3430-
3431-SYMBOL_CACHE_SIZE = 0
3432-
3433-# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
3434-# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
3435-# their name and scope. Since this can be an expensive process and often the
3436-# same symbol appear multiple times in the code, doxygen keeps a cache of
3437-# pre-resolved symbols. If the cache is too small doxygen will become slower.
3438-# If the cache is too large, memory is wasted. The cache size is given by this
3439-# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
3440-# corresponding to a cache size of 2^16 = 65536 symbols.
3441+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
3442+# cache is used to resolve symbols given their name and scope. Since this can
3443+# be an expensive process and often the same symbol appear multiple times in
3444+# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too
3445+# small doxygen will become slower. If the cache is too large, memory is wasted.
3446+# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid
3447+# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536
3448+# symbols.
3449
3450 LOOKUP_CACHE_SIZE = 0
3451
3452@@ -363,7 +359,7 @@
3453 # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
3454 # documentation are documented, even if no documentation was available.
3455 # Private class members and static file members will be hidden unless
3456-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
3457+# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES
3458
3459 EXTRACT_ALL = YES
3460
3461@@ -544,7 +540,8 @@
3462 GENERATE_DEPRECATEDLIST= YES
3463
3464 # The ENABLED_SECTIONS tag can be used to enable conditional
3465-# documentation sections, marked by \if sectionname ... \endif.
3466+# documentation sections, marked by \if section-label ... \endif
3467+# and \cond section-label ... \endcond blocks.
3468
3469 ENABLED_SECTIONS =
3470
3471@@ -571,7 +568,8 @@
3472 SHOW_FILES = YES
3473
3474 # Set the SHOW_NAMESPACES tag to NO to disable the generation of the
3475-# Namespaces page. This will remove the Namespaces entry from the Quick Index
3476+# Namespaces page.
3477+# This will remove the Namespaces entry from the Quick Index
3478 # and from the Folder Tree View (if specified). The default is YES.
3479
3480 SHOW_NAMESPACES = YES
3481@@ -601,7 +599,8 @@
3482 # requires the bibtex tool to be installed. See also
3483 # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
3484 # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
3485-# feature you need bibtex and perl available in the search path.
3486+# feature you need bibtex and perl available in the search path. Do not use
3487+# file names with spaces, bibtex cannot handle them.
3488
3489 CITE_BIB_FILES =
3490
3491@@ -757,7 +756,11 @@
3492 # wildcard * is used, a substring. Examples: ANamespace, AClass,
3493 # AClass::ANamespace, ANamespace::*Test
3494
3495-EXCLUDE_SYMBOLS = android google mfd mgg mp
3496+EXCLUDE_SYMBOLS = android \
3497+ google \
3498+ mfd \
3499+ mgg \
3500+ mp
3501
3502 # The EXAMPLE_PATH tag can be used to specify one or more files or
3503 # directories that contain example code fragments that are included (see
3504@@ -790,14 +793,19 @@
3505 # by executing (via popen()) the command <filter> <input-file>, where <filter>
3506 # is the value of the INPUT_FILTER tag, and <input-file> is the name of an
3507 # input file. Doxygen will then use the output that the filter program writes
3508-# to standard output. If FILTER_PATTERNS is specified, this tag will be
3509-# ignored.
3510+# to standard output.
3511+# If FILTER_PATTERNS is specified, this tag will be ignored.
3512+# Note that the filter must not add or remove lines; it is applied before the
3513+# code is scanned, but not when the output code is generated. If lines are added
3514+# or removed, the anchors will not be placed correctly.
3515
3516 INPUT_FILTER =
3517
3518 # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
3519-# basis. Doxygen will compare the file name with each pattern and apply the
3520-# filter if there is a match. The filters are a list of the form:
3521+# basis.
3522+# Doxygen will compare the file name with each pattern and apply the
3523+# filter if there is a match.
3524+# The filters are a list of the form:
3525 # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
3526 # info on how filters are used. If FILTER_PATTERNS is empty or if
3527 # non of the patterns match the file name, INPUT_FILTER is applied.
3528@@ -818,6 +826,13 @@
3529
3530 FILTER_SOURCE_PATTERNS =
3531
3532+# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that
3533+# is part of the input, its contents will be placed on the main page
3534+# (index.html). This can be useful if you have a project on for instance GitHub
3535+# and want reuse the introduction page also for the doxygen output.
3536+
3537+USE_MDFILE_AS_MAINPAGE =
3538+
3539 #---------------------------------------------------------------------------
3540 # configuration options related to source browsing
3541 #---------------------------------------------------------------------------
3542@@ -855,7 +870,8 @@
3543 # If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
3544 # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
3545 # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
3546-# link to the source code. Otherwise they will link to the documentation.
3547+# link to the source code.
3548+# Otherwise they will link to the documentation.
3549
3550 REFERENCES_LINK_SOURCE = YES
3551
3552@@ -920,7 +936,7 @@
3553 # The HTML_HEADER tag can be used to specify a personal HTML header for
3554 # each generated HTML page. If it is left blank doxygen will generate a
3555 # standard header. Note that when using a custom header you are responsible
3556-# for the proper inclusion of any scripts and style sheets that doxygen
3557+# for the proper inclusion of any scripts and style sheets that doxygen
3558 # needs, which is dependent on the configuration options used.
3559 # It is advised to generate a default header using "doxygen -w html
3560 # header.html footer.html stylesheet.css YourConfigFile" and then modify
3561@@ -938,18 +954,27 @@
3562
3563 # The HTML_STYLESHEET tag can be used to specify a user-defined cascading
3564 # style sheet that is used by each HTML page. It can be used to
3565-# fine-tune the look of the HTML output. If the tag is left blank doxygen
3566-# will generate a default style sheet. Note that doxygen will try to copy
3567-# the style sheet file to the HTML output directory, so don't put your own
3568-# style sheet in the HTML output directory as well, or it will be erased!
3569+# fine-tune the look of the HTML output. If left blank doxygen will
3570+# generate a default style sheet. Note that it is recommended to use
3571+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
3572+# tag will in the future become obsolete.
3573
3574 HTML_STYLESHEET =
3575+
3576+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
3577+# user-defined cascading style sheet that is included after the standard
3578+# style sheets created by doxygen. Using this option one can overrule
3579+# certain style aspects. This is preferred over using HTML_STYLESHEET
3580+# since it does not replace the standard style sheet and is therefor more
3581+# robust against future updates. Doxygen will copy the style sheet file to
3582+# the output directory.
3583+
3584 HTML_EXTRA_STYLESHEET = @CMAKE_BINARY_DIR@/doc/extra.css
3585
3586 # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
3587 # other source files which should be copied to the HTML output directory. Note
3588 # that these files will be copied to the base HTML output directory. Use the
3589-# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
3590+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
3591 # files. In the HTML_STYLESHEET file, use the file name only. Also note that
3592 # the files will be copied as-is; there are no commands or markers available.
3593
3594@@ -1030,9 +1055,9 @@
3595
3596 DOCSET_BUNDLE_ID = org.doxygen.Project
3597
3598-# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
3599-# the documentation publisher. This should be a reverse domain-name style
3600-# string, e.g. com.mycompany.MyDocSet.documentation.
3601+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
3602+# identify the documentation publisher. This should be a reverse domain-name
3603+# style string, e.g. com.mycompany.MyDocSet.documentation.
3604
3605 DOCSET_PUBLISHER_ID = org.doxygen.Publisher
3606
3607@@ -1138,7 +1163,7 @@
3608 QHG_LOCATION =
3609
3610 # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
3611-# will be generated, which together with the HTML files, form an Eclipse help
3612+# will be generated, which together with the HTML files, form an Eclipse help
3613 # plugin. To install this plugin and make it available under the help contents
3614 # menu in Eclipse, the contents of the directory containing the HTML and XML
3615 # files needs to be copied into the plugins directory of eclipse. The name of
3616@@ -1217,13 +1242,21 @@
3617
3618 USE_MATHJAX = NO
3619
3620+# When MathJax is enabled you can set the default output format to be used for
3621+# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and
3622+# SVG. The default value is HTML-CSS, which is slower, but has the best
3623+# compatibility.
3624+
3625+MATHJAX_FORMAT = HTML-CSS
3626+
3627 # When MathJax is enabled you need to specify the location relative to the
3628 # HTML output directory using the MATHJAX_RELPATH option. The destination
3629 # directory should contain the MathJax.js script. For instance, if the mathjax
3630 # directory is located at the same level as the HTML output directory, then
3631 # MATHJAX_RELPATH should be ../mathjax. The default value points to
3632 # the MathJax Content Delivery Network so you can quickly see the result without
3633-# installing MathJax. However, it is strongly recommended to install a local
3634+# installing MathJax.
3635+# However, it is strongly recommended to install a local
3636 # copy of MathJax from http://www.mathjax.org before deployment.
3637
3638 MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
3639@@ -1233,6 +1266,11 @@
3640
3641 MATHJAX_EXTENSIONS =
3642
3643+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript
3644+# pieces of code that will be used on startup of the MathJax code.
3645+
3646+MATHJAX_CODEFILE =
3647+
3648 # When the SEARCHENGINE tag is enabled doxygen will generate a search box
3649 # for the HTML output. The underlying search engine uses javascript
3650 # and DHTML and should work on any modern browser. Note that when using
3651@@ -1244,15 +1282,55 @@
3652 SEARCHENGINE = YES
3653
3654 # When the SERVER_BASED_SEARCH tag is enabled the search engine will be
3655-# implemented using a PHP enabled web server instead of at the web client
3656-# using Javascript. Doxygen will generate the search PHP script and index
3657-# file to put on the web server. The advantage of the server
3658-# based approach is that it scales better to large projects and allows
3659-# full text search. The disadvantages are that it is more difficult to setup
3660-# and does not have live searching capabilities.
3661+# implemented using a web server instead of a web client using Javascript.
3662+# There are two flavours of web server based search depending on the
3663+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
3664+# searching and an index file used by the script. When EXTERNAL_SEARCH is
3665+# enabled the indexing and searching needs to be provided by external tools.
3666+# See the manual for details.
3667
3668 SERVER_BASED_SEARCH = NO
3669
3670+# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP
3671+# script for searching. Instead the search results are written to an XML file
3672+# which needs to be processed by an external indexer. Doxygen will invoke an
3673+# external search engine pointed to by the SEARCHENGINE_URL option to obtain
3674+# the search results. Doxygen ships with an example indexer (doxyindexer) and
3675+# search engine (doxysearch.cgi) which are based on the open source search
3676+# engine library Xapian. See the manual for configuration details.
3677+
3678+EXTERNAL_SEARCH = NO
3679+
3680+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
3681+# which will returned the search results when EXTERNAL_SEARCH is enabled.
3682+# Doxygen ships with an example search engine (doxysearch) which is based on
3683+# the open source search engine library Xapian. See the manual for configuration
3684+# details.
3685+
3686+SEARCHENGINE_URL =
3687+
3688+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
3689+# search data is written to a file for indexing by an external tool. With the
3690+# SEARCHDATA_FILE tag the name of this file can be specified.
3691+
3692+SEARCHDATA_FILE = searchdata.xml
3693+
3694+# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the
3695+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
3696+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
3697+# projects and redirect the results back to the right project.
3698+
3699+EXTERNAL_SEARCH_ID =
3700+
3701+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
3702+# projects other than the one defined by this configuration file, but that are
3703+# all added to the same external search index. Each project needs to have a
3704+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id
3705+# of to a relative location where the documentation can be found.
3706+# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ...
3707+
3708+EXTRA_SEARCH_MAPPINGS =
3709+
3710 #---------------------------------------------------------------------------
3711 # configuration options related to the LaTeX output
3712 #---------------------------------------------------------------------------
3713@@ -1290,7 +1368,7 @@
3714
3715 # The PAPER_TYPE tag can be used to set the paper type that is used
3716 # by the printer. Possible values are: a4, letter, legal and
3717-# executive. If left blank a4wide will be used.
3718+# executive. If left blank a4 will be used.
3719
3720 PAPER_TYPE = a4
3721
3722@@ -1313,6 +1391,13 @@
3723
3724 LATEX_FOOTER =
3725
3726+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images
3727+# or other source files which should be copied to the LaTeX output directory.
3728+# Note that the files will be copied as-is; there are no commands or markers
3729+# available.
3730+
3731+LATEX_EXTRA_FILES =
3732+
3733 # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
3734 # is prepared for conversion to pdf (using ps2pdf). The pdf file will
3735 # contain links (just like the HTML output) instead of page references
3736@@ -1458,6 +1543,21 @@
3737 XML_PROGRAMLISTING = YES
3738
3739 #---------------------------------------------------------------------------
3740+# configuration options related to the DOCBOOK output
3741+#---------------------------------------------------------------------------
3742+
3743+# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files
3744+# that can be used to generate PDF.
3745+
3746+GENERATE_DOCBOOK = NO
3747+
3748+# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put.
3749+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
3750+# front of it. If left blank docbook will be used as the default path.
3751+
3752+DOCBOOK_OUTPUT = docbook
3753+
3754+#---------------------------------------------------------------------------
3755 # configuration options for the AutoGen Definitions output
3756 #---------------------------------------------------------------------------
3757
3758@@ -1488,8 +1588,10 @@
3759 PERLMOD_LATEX = NO
3760
3761 # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
3762-# nicely formatted so it can be parsed by a human reader. This is useful
3763-# if you want to understand what is going on. On the other hand, if this
3764+# nicely formatted so it can be parsed by a human reader.
3765+# This is useful
3766+# if you want to understand what is going on.
3767+# On the other hand, if this
3768 # tag is set to NO the size of the Perl module output will be much smaller
3769 # and Perl will parse it just the same.
3770
3771@@ -1575,9 +1677,11 @@
3772 # The TAGFILES option can be used to specify one or more tagfiles. For each
3773 # tag file the location of the external documentation should be added. The
3774 # format of a tag file without this location is as follows:
3775-# TAGFILES = file1 file2 ...
3776+#
3777+# TAGFILES = file1 file2 ...
3778 # Adding location for the tag files is done as follows:
3779-# TAGFILES = file1=loc1 "file2 = loc2" ...
3780+#
3781+# TAGFILES = file1=loc1 "file2 = loc2" ...
3782 # where "loc1" and "loc2" can be relative or absolute paths
3783 # or URLs. Note that each tag file must have a unique name (where the name does
3784 # NOT include the path). If a tag file is not located in the directory in which
3785@@ -1602,6 +1706,12 @@
3786
3787 EXTERNAL_GROUPS = YES
3788
3789+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed
3790+# in the related pages index. If set to NO, only the current project's
3791+# pages will be listed.
3792+
3793+EXTERNAL_PAGES = YES
3794+
3795 # The PERL_PATH should be the absolute path and name of the perl script
3796 # interpreter (i.e. the result of `which perl').
3797
3798@@ -1698,7 +1808,7 @@
3799 # the class node. If there are many fields or methods and many nodes the
3800 # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
3801 # threshold limits the number of items for each type to make the size more
3802-# managable. Set this to 0 for no limit. Note that the threshold may be
3803+# manageable. Set this to 0 for no limit. Note that the threshold may be
3804 # exceeded by 50% before the limit is enforced.
3805
3806 UML_LIMIT_NUM_FIELDS = 10
3807
3808=== modified file 'doc/building_source_for_android.md'
3809--- doc/building_source_for_android.md 2013-06-14 19:08:45 +0000
3810+++ doc/building_source_for_android.md 2013-11-08 19:16:38 +0000
3811@@ -52,17 +52,17 @@
3812 compile and run code, and is well suited for a development workflow.
3813
3814 - Be sure that the cross compiler that you are using matches the target
3815- environment. (eg, make sure you're using the saucy toolchain if you're
3816- targeting a saucy phablet image) You can specify the toolchain version
3817+ environment. (eg, make sure you're using the trusty toolchain if you're
3818+ targeting a trusty phablet image) You can specify the toolchain version
3819 thusly:
3820
3821- $ apt-get install g++-arm-linux-gnueabihf/saucy
3822+ $ apt-get install g++-arm-linux-gnueabihf/trusty
3823
3824 - Get access to armhf packages via apt-get. On an amd64/ia32 system, you can
3825 do this by adding a file like the one below to /etc/apt/sources.list.d/
3826
3827 #example sources.list with armhf dependencies
3828- deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ saucy main restricted universe multiverse
3829+ deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ trusty main restricted universe multiverse
3830
3831 Then you should run:
3832
3833
3834=== modified file 'doc/component_reports.md'
3835--- doc/component_reports.md 2013-08-29 03:48:16 +0000
3836+++ doc/component_reports.md 2013-11-08 19:16:38 +0000
3837@@ -18,11 +18,13 @@
3838
3839 Report | Handlers
3840 ----------------------- | --------
3841+connector-report | log
3842 display-report | log
3843 input-report | log,lttng
3844 legacy-input-report | log
3845 msg-processor-report | log,lttng
3846 session-mediator-report | log
3847+surfaces-report | log
3848
3849 For example, to enable the LTTng input report, one could either use the
3850 `--input-report=lttng` command-line option to the server, or set the
3851@@ -38,6 +40,7 @@
3852 Report | Handlers
3853 ------------------- | --------
3854 rpc-report | log,lttng
3855+input-receiver | log
3856
3857 For example, to enable the logging RPC report, one should set the
3858 `MIR_CLIENT_RPC_REPORT=log` environment variable.
3859
3860=== modified file 'doc/installing_prebuilt_on_pc.md'
3861--- doc/installing_prebuilt_on_pc.md 2013-08-28 03:41:48 +0000
3862+++ doc/installing_prebuilt_on_pc.md 2013-11-08 19:16:38 +0000
3863@@ -1,8 +1,8 @@
3864 Installing pre-built packages on a PC {#installing_prebuilt_on_pc}
3865 =====================================
3866
3867-Install saucy if you haven't done so already. Uninstall any proprietary
3868-drivers (-nvidia, -fglrx) and reboot on the FOSS drivers.
3869+Install Ubuntu 13.10 or later if you haven't done so already. Uninstall any
3870+proprietary drivers (-nvidia, -fglrx) and reboot on the FOSS drivers.
3871
3872 Install Mir:
3873
3874
3875=== modified file 'doc/using_mir_on_pc.md'
3876--- doc/using_mir_on_pc.md 2013-09-19 13:24:22 +0000
3877+++ doc/using_mir_on_pc.md 2013-11-08 19:16:38 +0000
3878@@ -15,19 +15,21 @@
3879 lsmod | grep drm
3880
3881 Before you can use Mir you need to ensure you have the proper custom Mesa
3882-build installed. If you are running Ubuntu saucy
3883+build installed. If you are running Ubuntu 13.10 or later
3884 (see \ref installing_prebuilt_on_pc), you should be good to go.
3885
3886 If you built Mir from source code (see \ref building_source_for_pc), you
3887 need to ensure you are using the proper Mesa at runtime. You can do that by
3888-installing the Mesa packages from saucy or by building the custom Mesa yourself
3889-and ensuring it can be found by Mir, e.g., by using LD_LIBRARY_PATH.
3890+installing the Mesa packages from Ubuntu 13.10 (or later) or by building the
3891+custom Mesa yourself and ensuring it can be found by Mir, e.g., by using
3892+LD_LIBRARY_PATH.
3893
3894 Using Mir as system compositor with X
3895 -------------------------------------
3896
3897 Note: for this to work you need to have Mir and all its dependencies (which
3898-include lightdm, Mesa and the Xorg drivers). The easiest way is to run saucy.
3899+include lightdm, Mesa and the Xorg drivers). The easiest way is to run Ubuntu
3900+13.10 or later.
3901
3902 If you have installed unity-system-compositor it will have created a file in
3903 /etc/lightdm/lightdm.conf.d/10-unity-system-compositor.conf to run XMir. If you
3904
3905=== modified file 'examples/demo-inprocess-surface-client/demo_inprocess_surface_client.cpp'
3906--- examples/demo-inprocess-surface-client/demo_inprocess_surface_client.cpp 2013-08-28 03:41:48 +0000
3907+++ examples/demo-inprocess-surface-client/demo_inprocess_surface_client.cpp 2013-11-08 19:16:38 +0000
3908@@ -49,7 +49,8 @@
3909 {
3910 client = std::make_shared<me::InprocessEGLClient>(
3911 config.the_graphics_platform(),
3912- config.the_session_manager());
3913+ config.the_frontend_shell(),
3914+ config.the_focus_controller());
3915 });
3916 ///\internal [main_tag]
3917
3918
3919=== modified file 'examples/demo-inprocess-surface-client/inprocess_egl_client.cpp'
3920--- examples/demo-inprocess-surface-client/inprocess_egl_client.cpp 2013-09-19 13:24:22 +0000
3921+++ examples/demo-inprocess-surface-client/inprocess_egl_client.cpp 2013-11-08 19:16:38 +0000
3922@@ -20,11 +20,12 @@
3923 #include "example_egl_helper.h"
3924
3925 #include "mir/main_loop.h"
3926-#include "mir/shell/session_manager.h"
3927-#include "mir/shell/surface.h"
3928+#include "mir/shell/focus_controller.h"
3929+#include "mir/frontend/surface.h"
3930 #include "mir/shell/surface_creation_parameters.h"
3931 #include "mir/shell/session.h"
3932 #include "mir/frontend/session.h"
3933+#include "mir/frontend/shell.h"
3934 #include "mir/geometry/size.h"
3935 #include "mir/graphics/buffer_properties.h"
3936 #include "mir/graphics/platform.h"
3937@@ -46,18 +47,19 @@
3938 #include <signal.h>
3939
3940 namespace mf = mir::frontend;
3941-namespace mc = mir::compositor;
3942 namespace msh = mir::shell;
3943 namespace mg = mir::graphics;
3944 namespace me = mir::examples;
3945 namespace mircv = mir::input::receiver;
3946 namespace geom = mir::geometry;
3947
3948-me::InprocessEGLClient::InprocessEGLClient(std::shared_ptr<mg::Platform> const& graphics_platform,
3949- std::shared_ptr<msh::SessionManager> const& session_manager)
3950+me::InprocessEGLClient::InprocessEGLClient(
3951+ std::shared_ptr<mg::Platform> const& graphics_platform,
3952+ std::shared_ptr<frontend::Shell> const& shell,
3953+ std::shared_ptr<shell::FocusController> const& focus_controller)
3954 : graphics_platform(graphics_platform),
3955-
3956- session_manager(session_manager),
3957+ shell(shell),
3958+ focus_controller(focus_controller),
3959 client_thread(std::mem_fn(&InprocessEGLClient::thread_loop), this),
3960 terminate(false)
3961 {
3962@@ -66,7 +68,7 @@
3963 me::InprocessEGLClient::~InprocessEGLClient()
3964 {
3965 terminate = true;
3966- auto session = session_manager->focussed_application().lock();
3967+ auto session = focus_controller->focussed_application().lock();
3968 if (session)
3969 session->force_requests_to_complete();
3970 client_thread.join();
3971@@ -91,10 +93,9 @@
3972 .of_size(surface_size)
3973 .of_buffer_usage(mg::BufferUsage::hardware)
3974 .of_pixel_format(geom::PixelFormat::argb_8888);
3975- auto session = session_manager->open_session("Inprocess client",
3976- std::make_shared<NullEventSink>());
3977+ auto session = shell->open_session("Inprocess client", std::make_shared<NullEventSink>());
3978 // TODO: Why do we get an ID? ~racarr
3979- auto surface = session->get_surface(session_manager->create_surface_for(session, params));
3980+ auto surface = session->get_surface(shell->create_surface_for(session, params));
3981
3982 auto input_platform = mircv::InputPlatform::create();
3983 input_thread = input_platform->create_input_thread(
3984
3985=== modified file 'examples/demo-inprocess-surface-client/inprocess_egl_client.h'
3986--- examples/demo-inprocess-surface-client/inprocess_egl_client.h 2013-08-28 03:41:48 +0000
3987+++ examples/demo-inprocess-surface-client/inprocess_egl_client.h 2013-11-08 19:16:38 +0000
3988@@ -35,14 +35,9 @@
3989 class InputReceiverThread;
3990 }
3991 }
3992-namespace graphics
3993-{
3994-class Platform;
3995-}
3996-namespace shell
3997-{
3998-class SessionManager;
3999-}
4000+namespace graphics { class Platform; }
4001+namespace shell { class FocusController; }
4002+namespace frontend { class Shell; }
4003
4004 namespace examples
4005 {
4006@@ -51,8 +46,10 @@
4007 class InprocessEGLClient
4008 {
4009 public:
4010- InprocessEGLClient(std::shared_ptr<graphics::Platform> const& graphics_platform,
4011- std::shared_ptr<shell::SessionManager> const& session_manager);
4012+ InprocessEGLClient(
4013+ std::shared_ptr<graphics::Platform> const& graphics_platform,
4014+ std::shared_ptr<frontend::Shell> const& shell,
4015+ std::shared_ptr<shell::FocusController> const& focus_controller);
4016
4017 ~InprocessEGLClient();
4018
4019@@ -62,7 +59,8 @@
4020
4021 private:
4022 std::shared_ptr<graphics::Platform> const graphics_platform;
4023- std::shared_ptr<shell::SessionManager> const session_manager;
4024+ std::shared_ptr<frontend::Shell> const shell;
4025+ std::shared_ptr<shell::FocusController> const focus_controller;
4026
4027 std::thread client_thread;
4028
4029
4030=== modified file 'examples/demo-shell/demo_shell.cpp'
4031--- examples/demo-shell/demo_shell.cpp 2013-09-17 18:40:01 +0000
4032+++ examples/demo-shell/demo_shell.cpp 2013-11-08 19:16:38 +0000
4033@@ -24,11 +24,7 @@
4034
4035 #include "mir/run_mir.h"
4036 #include "mir/report_exception.h"
4037-#include "mir/shell/session_manager.h"
4038-#include "mir/shell/registration_order_focus_sequence.h"
4039-#include "mir/shell/default_focus_mechanism.h"
4040 #include "mir/shell/session_container.h"
4041-#include "mir/shell/organising_surface_factory.h"
4042 #include "mir/graphics/display.h"
4043 #include "mir/input/composite_event_filter.h"
4044
4045@@ -97,7 +93,6 @@
4046 // We use this strange two stage initialization to avoid a circular dependency between the EventFilters
4047 // and the SessionStore
4048 wm->set_focus_controller(config.the_focus_controller());
4049- wm->set_session_manager(config.the_session_manager());
4050 wm->set_display(config.the_display());
4051 wm->set_compositor(config.the_compositor());
4052 });
4053
4054=== modified file 'examples/demo-shell/window_manager.cpp'
4055--- examples/demo-shell/window_manager.cpp 2013-09-17 19:46:15 +0000
4056+++ examples/demo-shell/window_manager.cpp 2013-11-08 19:16:38 +0000
4057@@ -19,7 +19,6 @@
4058 #include "window_manager.h"
4059
4060 #include "mir/shell/focus_controller.h"
4061-#include "mir/shell/session_manager.h"
4062 #include "mir/shell/session.h"
4063 #include "mir/shell/surface.h"
4064 #include "mir/graphics/display.h"
4065@@ -51,12 +50,6 @@
4066 focus_controller = controller;
4067 }
4068
4069-void me::WindowManager::set_session_manager(
4070- std::shared_ptr<msh::SessionManager> const& sm)
4071-{
4072- session_manager = sm;
4073-}
4074-
4075 void me::WindowManager::set_display(std::shared_ptr<mg::Display> const& dpy)
4076 {
4077 display = dpy;
4078@@ -130,7 +123,7 @@
4079 }
4080 }
4081 else if (event.type == mir_event_type_motion &&
4082- session_manager)
4083+ focus_controller)
4084 {
4085 geometry::Point cursor = average_pointer(event.motion);
4086
4087@@ -138,7 +131,7 @@
4088 MirMotionAction action = static_cast<MirMotionAction>(event.motion.action & ~0xff00);
4089
4090 std::shared_ptr<msh::Session> app =
4091- session_manager->focussed_application().lock();
4092+ focus_controller->focussed_application().lock();
4093
4094 int fingers = static_cast<int>(event.motion.pointer_count);
4095
4096
4097=== modified file 'examples/demo-shell/window_manager.h'
4098--- examples/demo-shell/window_manager.h 2013-09-17 18:40:01 +0000
4099+++ examples/demo-shell/window_manager.h 2013-11-08 19:16:38 +0000
4100@@ -29,7 +29,6 @@
4101 namespace shell
4102 {
4103 class FocusController;
4104-class SessionManager;
4105 }
4106 namespace graphics
4107 {
4108@@ -49,7 +48,6 @@
4109 ~WindowManager() = default;
4110
4111 void set_focus_controller(std::shared_ptr<shell::FocusController> const& focus_controller);
4112- void set_session_manager(std::shared_ptr<shell::SessionManager> const& sm);
4113 void set_display(std::shared_ptr<graphics::Display> const& display);
4114 void set_compositor(std::shared_ptr<compositor::Compositor> const& compositor);
4115
4116@@ -61,7 +59,6 @@
4117
4118 private:
4119 std::shared_ptr<shell::FocusController> focus_controller;
4120- std::shared_ptr<shell::SessionManager> session_manager;
4121 std::shared_ptr<graphics::Display> display;
4122 std::shared_ptr<compositor::Compositor> compositor;
4123
4124
4125=== modified file 'examples/demo_input_filter.cpp'
4126--- examples/demo_input_filter.cpp 2013-08-28 03:41:48 +0000
4127+++ examples/demo_input_filter.cpp 2013-11-08 19:16:38 +0000
4128@@ -32,6 +32,21 @@
4129
4130 struct PrintingEventFilter : public mi::EventFilter
4131 {
4132+ void print_motion_event(MirMotionEvent const& ev)
4133+ {
4134+ std::cout << "Motion Event time=" << ev.event_time
4135+ << " pointer_count=" << ev.pointer_count << std::endl;
4136+
4137+ for (size_t i = 0; i < ev.pointer_count; ++i)
4138+ {
4139+ std::cout << " "
4140+ << " id=" << ev.pointer_coordinates[i].id
4141+ << " pos=(" << ev.pointer_coordinates[i].x << ", " << ev.pointer_coordinates[i].y << ")"
4142+ << std::endl;
4143+ }
4144+ std::cout << "----------------" << std::endl << std::endl;
4145+ }
4146+
4147 bool handle(MirEvent const& ev) override
4148 {
4149 // TODO: Enhance printing
4150@@ -42,8 +57,7 @@
4151 }
4152 else if (ev.type == mir_event_type_motion)
4153 {
4154- std::cout << "Handling motion event (time, pointer0_x, pointer0_y): " << ev.motion.event_time << " "
4155- << ev.motion.pointer_coordinates[0].x << " " << ev.motion.pointer_coordinates[0].y << std::endl;
4156+ print_motion_event(ev.motion);
4157 }
4158 return false;
4159 }
4160@@ -56,7 +70,7 @@
4161 event_filter(std::make_shared<PrintingEventFilter>())
4162 {
4163 }
4164-
4165+
4166 std::shared_ptr<mi::CompositeEventFilter> the_composite_event_filter() override
4167 {
4168 auto composite_filter = ServerConfiguration::the_composite_event_filter();
4169@@ -69,10 +83,18 @@
4170
4171 }
4172
4173+
4174+#include <std/MirLog.h>
4175+void my_write_to_log(int /*prio*/, char const* buffer)
4176+{
4177+ printf("%s\n", buffer);
4178+}
4179+
4180 int main(int argc, char const* argv[])
4181 try
4182 {
4183 DemoServerConfiguration config(argc, argv);
4184+ mir::write_to_log = my_write_to_log;
4185
4186 mir::run_mir(config, [](mir::DisplayServer&) {/* empty init */});
4187 return 0;
4188
4189=== modified file 'examples/image_renderer.cpp'
4190--- examples/image_renderer.cpp 2013-03-21 03:32:59 +0000
4191+++ examples/image_renderer.cpp 2013-11-08 19:16:38 +0000
4192@@ -87,11 +87,68 @@
4193 BOOST_THROW_EXCEPTION(std::runtime_error(object_info_err));
4194 }
4195
4196+class GLState
4197+{
4198+public:
4199+ GLState(GLint attrib_loc)
4200+ : attrib_loc{attrib_loc}
4201+ {
4202+ glGetIntegerv(GL_CURRENT_PROGRAM, &program);
4203+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture);
4204+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buffer);
4205+ glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture_unit);
4206+ if (attrib_loc >= 0)
4207+ {
4208+ glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &attrib_enabled);
4209+ glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_SIZE, &attrib_size);
4210+ glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_TYPE, &attrib_type);
4211+ glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &attrib_normalized);
4212+ glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &attrib_stride);
4213+ glGetVertexAttribPointerv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_POINTER, &attrib_pointer);
4214+ }
4215+ }
4216+
4217+ GLState() : GLState{invalid_attrib_loc} {}
4218+
4219+ ~GLState()
4220+ {
4221+ glUseProgram(program);
4222+ glBindTexture(GL_TEXTURE_2D, texture);
4223+ glBindBuffer(GL_ARRAY_BUFFER, buffer);
4224+ glActiveTexture(active_texture_unit);
4225+ if (attrib_loc >= 0)
4226+ {
4227+ glVertexAttribPointer(attrib_loc, attrib_size, attrib_type,
4228+ attrib_normalized, attrib_stride, attrib_pointer);
4229+ if (attrib_enabled)
4230+ glEnableVertexAttribArray(attrib_loc);
4231+ else
4232+ glDisableVertexAttribArray(attrib_loc);
4233+ }
4234+ }
4235+
4236+private:
4237+ static GLint const invalid_attrib_loc = -1;
4238+ GLint program = 0;
4239+ GLint texture = 0;
4240+ GLint buffer = 0;
4241+ GLint active_texture_unit = 0;
4242+ GLint attrib_loc = invalid_attrib_loc;
4243+ GLint attrib_enabled = 0;
4244+ GLint attrib_size = 0;
4245+ GLint attrib_type = 0;
4246+ GLint attrib_normalized = 0;
4247+ GLint attrib_stride = 0;
4248+ GLvoid* attrib_pointer = nullptr;
4249+};
4250+
4251 }
4252
4253 mt::ImageRenderer::ImageRenderer(const uint8_t* pixel_data, mir::geometry::Size size,
4254 uint32_t bytes_per_pixel)
4255 {
4256+ GLState gl_state;
4257+
4258 resources.setup();
4259
4260 /* Upload the texture */
4261@@ -173,7 +230,6 @@
4262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4263
4264 glUniform1i(tex_loc, 0);
4265- glBindTexture(GL_TEXTURE_2D, 0);
4266
4267 /* Create VBO */
4268 glGenBuffers(1, &vertex_attribs_vbo);
4269@@ -181,14 +237,13 @@
4270 glBindBuffer(GL_ARRAY_BUFFER, vertex_attribs_vbo);
4271 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_attribs),
4272 glm::value_ptr(vertex_attribs[0]), GL_STATIC_DRAW);
4273-
4274- glBindBuffer(GL_ARRAY_BUFFER, 0);
4275- glUseProgram(0);
4276 }
4277
4278
4279 void mt::ImageRenderer::render()
4280 {
4281+ GLState gl_state(resources.position_attr_loc);
4282+
4283 glUseProgram(resources.program);
4284
4285 glActiveTexture(GL_TEXTURE0);
4286@@ -202,5 +257,4 @@
4287 /* Draw */
4288 glEnableVertexAttribArray(resources.position_attr_loc);
4289 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
4290- glDisableVertexAttribArray(resources.position_attr_loc);
4291 }
4292
4293=== modified file 'examples/render_surfaces.cpp'
4294--- examples/render_surfaces.cpp 2013-10-15 08:53:10 +0000
4295+++ examples/render_surfaces.cpp 2013-11-08 19:16:38 +0000
4296@@ -16,7 +16,7 @@
4297 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
4298 */
4299
4300-#include "mir/compositor/default_display_buffer_compositor_factory.h"
4301+#include "mir/compositor/display_buffer_compositor_factory.h"
4302 #include "mir/compositor/display_buffer_compositor.h"
4303 #include "mir/graphics/graphic_buffer_allocator.h"
4304 #include "mir/frontend/connector.h"
4305@@ -28,7 +28,9 @@
4306 #include "mir/graphics/display.h"
4307 #include "mir/graphics/display_buffer.h"
4308 #include "mir/shell/surface_builder.h"
4309-#include "mir/surfaces/surface.h"
4310+// Just the following three functions stop render_surfaces.cpp using shell::Surface
4311+// flag_for_render(), set_rotation() and set_alpha()
4312+#include "mir/surfaces/basic_surface.h"
4313 #include "mir/run_mir.h"
4314 #include "mir/report_exception.h"
4315
4316@@ -55,6 +57,7 @@
4317 namespace mi = mir::input;
4318 namespace geom = mir::geometry;
4319 namespace mt = mir::tools;
4320+namespace me = mir::examples;
4321
4322 ///\page render_surfaces-example render_surfaces.cpp: A simple program using the mir library.
4323 ///\tableofcontents
4324@@ -184,7 +187,7 @@
4325 {
4326 public:
4327 Moveable() {}
4328- Moveable(ms::Surface& s, const geom::Size& display_size,
4329+ Moveable(ms::BasicSurface& s, const geom::Size& display_size,
4330 float dx, float dy, const glm::vec3& rotation_axis, float alpha_offset)
4331 : surface(&s), display_size(display_size),
4332 x{static_cast<float>(s.top_left().x.as_uint32_t())},
4333@@ -232,7 +235,7 @@
4334 }
4335
4336 private:
4337- ms::Surface* surface;
4338+ ms::BasicSurface* surface;
4339 geom::Size display_size;
4340 float x;
4341 float y;
4342@@ -248,7 +251,7 @@
4343
4344 ///\internal [RenderSurfacesServerConfiguration_tag]
4345 // Extend the default configuration to manage moveables.
4346-class RenderSurfacesServerConfiguration : public mir::examples::ServerConfiguration
4347+class RenderSurfacesServerConfiguration : public me::ServerConfiguration
4348 {
4349 public:
4350 RenderSurfacesServerConfiguration(int argc, char const** argv)
4351@@ -349,32 +352,32 @@
4352 uint32_t frames;
4353 };
4354
4355- class RenderSurfacesDisplayBufferCompositorFactory : public mc::DefaultDisplayBufferCompositorFactory
4356+ class RenderSurfacesDisplayBufferCompositorFactory : public mc::DisplayBufferCompositorFactory
4357 {
4358 public:
4359 RenderSurfacesDisplayBufferCompositorFactory(
4360- std::shared_ptr<mc::Scene> const& scene,
4361- std::shared_ptr<mc::RendererFactory> const& renderer_factory,
4362- std::shared_ptr<mc::OverlayRenderer> const& overlay_renderer,
4363+ std::shared_ptr<mc::DisplayBufferCompositorFactory> const& factory,
4364 std::vector<Moveable>& moveables)
4365- : DefaultDisplayBufferCompositorFactory{scene, renderer_factory, overlay_renderer},
4366+ : factory{factory},
4367 moveables(moveables)
4368 {
4369 }
4370
4371 std::unique_ptr<mc::DisplayBufferCompositor> create_compositor_for(mg::DisplayBuffer& display_buffer)
4372 {
4373- auto cs = DefaultDisplayBufferCompositorFactory::create_compositor_for(display_buffer);
4374- auto raw = new RenderSurfacesDisplayBufferCompositor(std::move(cs), moveables);
4375+ auto compositor = factory->create_compositor_for(display_buffer);
4376+ auto raw = new RenderSurfacesDisplayBufferCompositor(
4377+ std::move(compositor), moveables);
4378 return std::unique_ptr<RenderSurfacesDisplayBufferCompositor>(raw);
4379 }
4380+
4381+ private:
4382+ std::shared_ptr<mc::DisplayBufferCompositorFactory> const factory;
4383 std::vector<Moveable>& moveables;
4384 };
4385
4386 return std::make_shared<RenderSurfacesDisplayBufferCompositorFactory>(
4387- the_scene(),
4388- the_renderer_factory(),
4389- the_overlay_renderer(),
4390+ me::ServerConfiguration::the_display_buffer_compositor_factory(),
4391 moveables);
4392 }
4393 ///\internal [RenderSurfacesDisplayBufferCompositor_tag]
4394@@ -405,7 +408,7 @@
4395 int i = 0;
4396 for (auto& m : moveables)
4397 {
4398- std::shared_ptr<ms::Surface> s = surface_builder->create_surface(
4399+ std::shared_ptr<ms::BasicSurface> s = surface_builder->create_surface(
4400 nullptr,
4401 msh::a_surface().of_size(surface_size)
4402 .of_pixel_format(surface_pf)
4403
4404=== modified file 'examples/render_to_fb.cpp'
4405--- examples/render_to_fb.cpp 2013-09-19 13:24:22 +0000
4406+++ examples/render_to_fb.cpp 2013-11-08 19:16:38 +0000
4407@@ -21,8 +21,6 @@
4408 #include "mir/default_server_configuration.h"
4409 #include "mir/graphics/display.h"
4410 #include "mir/graphics/display_buffer.h"
4411-#include "mir/graphics/default_display_configuration_policy.h"
4412-#include "mir/graphics/platform.h"
4413 #include "mir/report_exception.h"
4414
4415 #include <csignal>
4416@@ -56,8 +54,7 @@
4417
4418 mir::DefaultServerConfiguration conf{argc, argv};
4419
4420- auto platform = conf.the_graphics_platform();
4421- auto display = platform->create_display(std::make_shared<mg::DefaultDisplayConfigurationPolicy>());
4422+ auto display = conf.the_display();
4423
4424 mir::draw::glAnimationBasic gl_animation;
4425
4426
4427=== modified file 'include/client/mir_toolkit/mir_client_library_drm.h'
4428--- include/client/mir_toolkit/mir_client_library_drm.h 2013-05-30 03:50:54 +0000
4429+++ include/client/mir_toolkit/mir_client_library_drm.h 2013-11-08 19:16:38 +0000
4430@@ -27,6 +27,8 @@
4431 extern "C" {
4432 #endif
4433
4434+struct gbm_device;
4435+
4436 typedef void (*mir_drm_auth_magic_callback)(int status, void *context);
4437
4438 /* Authenticates a DRM magic cookie */
4439@@ -35,6 +37,18 @@
4440 mir_drm_auth_magic_callback callback,
4441 void *context);
4442
4443+/**
4444+ * Set the gbm_device to be used by the EGL implementation.
4445+ * This is required if the application needs to create EGLImages from
4446+ * gbm buffers objects created on that gbm device.
4447+ * \param [in] connection The connection
4448+ * \param [in] dev The gbm_device to set
4449+ * \return A non-zero value if the operation was successful,
4450+ * 0 otherwise
4451+ */
4452+int mir_connection_drm_set_gbm_device(MirConnection* connection,
4453+ struct gbm_device* dev);
4454+
4455 #ifdef __cplusplus
4456 }
4457 /**@}*/
4458
4459=== modified file 'include/platform/mir/graphics/nested_context.h'
4460--- include/platform/mir/graphics/nested_context.h 2013-10-23 09:33:59 +0000
4461+++ include/platform/mir/graphics/nested_context.h 2013-11-08 19:16:38 +0000
4462@@ -21,6 +21,8 @@
4463
4464 #include <vector>
4465
4466+struct gbm_device;
4467+
4468 namespace mir
4469 {
4470 namespace graphics
4471@@ -33,6 +35,7 @@
4472
4473 virtual std::vector<int> platform_fd_items() = 0;
4474 virtual void drm_auth_magic(int magic) = 0;
4475+ virtual void drm_set_gbm_device(struct gbm_device* dev) = 0;
4476
4477 protected:
4478 NestedContext() = default;
4479
4480=== renamed file 'include/server/mir/surfaces/buffer_stream.h' => 'include/server/mir/compositor/buffer_stream.h'
4481--- include/server/mir/surfaces/buffer_stream.h 2013-08-28 03:41:48 +0000
4482+++ include/server/mir/compositor/buffer_stream.h 2013-11-08 19:16:38 +0000
4483@@ -17,8 +17,8 @@
4484 * Kevin DuBois <kevin.dubois@canonical.com>
4485 */
4486
4487-#ifndef MIR_SURFACES_BUFFER_STREAM_H_
4488-#define MIR_SURFACES_BUFFER_STREAM_H_
4489+#ifndef MIR_COMPOSITOR_BUFFER_STREAM_H_
4490+#define MIR_COMPOSITOR_BUFFER_STREAM_H_
4491
4492 #include "mir/geometry/size.h"
4493 #include "mir/geometry/pixel_format.h"
4494@@ -33,13 +33,13 @@
4495 class Buffer;
4496 }
4497
4498-namespace surfaces
4499+namespace compositor
4500 {
4501
4502 class BufferStream
4503 {
4504 public:
4505- virtual ~BufferStream() {/* TODO: make nothrow */}
4506+ virtual ~BufferStream() = default;
4507
4508 virtual std::shared_ptr<graphics::Buffer> secure_client_buffer() = 0;
4509 virtual std::shared_ptr<graphics::Buffer>
4510@@ -47,6 +47,7 @@
4511 virtual std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() = 0;
4512 virtual geometry::PixelFormat get_stream_pixel_format() = 0;
4513 virtual geometry::Size stream_size() = 0;
4514+ virtual void resize(geometry::Size const& size) = 0;
4515 virtual void allow_framedropping(bool) = 0;
4516 virtual void force_requests_to_complete() = 0;
4517 };
4518@@ -54,4 +55,4 @@
4519 }
4520 }
4521
4522-#endif /* MIR_SURFACES_BUFFER_STREAM_H_ */
4523+#endif /* MIR_COMPOSITOR_BUFFER_STREAM_H_ */
4524
4525=== modified file 'include/server/mir/compositor/scene.h'
4526--- include/server/mir/compositor/scene.h 2013-10-16 07:57:33 +0000
4527+++ include/server/mir/compositor/scene.h 2013-11-08 19:16:38 +0000
4528@@ -26,12 +26,9 @@
4529
4530 namespace mir
4531 {
4532-namespace surfaces
4533+namespace compositor
4534 {
4535 class BufferStream;
4536-}
4537-namespace compositor
4538-{
4539 class CompositingCriteria;
4540
4541 class FilterForScene
4542@@ -52,7 +49,7 @@
4543 public:
4544 virtual ~OperatorForScene() {}
4545
4546- virtual void operator()(CompositingCriteria const&, surfaces::BufferStream&) = 0;
4547+ virtual void operator()(CompositingCriteria const&, BufferStream&) = 0;
4548
4549 protected:
4550 OperatorForScene() = default;
4551@@ -78,7 +75,7 @@
4552 * Scene changes.
4553 *
4554 * The supplied callback should not directly or indirectly (e.g.,
4555- * by changing a property of a Renderable) change the state of
4556+ * by changing a property of a surface) change the state of
4557 * the Scene, otherwise a deadlock may occur.
4558 */
4559 virtual void set_change_callback(std::function<void()> const& f) = 0;
4560
4561=== modified file 'include/server/mir/default_configuration_options.h'
4562--- include/server/mir/default_configuration_options.h 2013-10-23 09:02:02 +0000
4563+++ include/server/mir/default_configuration_options.h 2013-11-08 19:16:38 +0000
4564@@ -35,10 +35,12 @@
4565 static char const* const display_report_opt;
4566 static char const* const legacy_input_report_opt;
4567 static char const* const connector_report_opt;
4568+ static char const* const surfaces_report_opt;
4569 static char const* const input_report_opt;
4570 static char const* const host_socket_opt;
4571 static char const* const standalone_opt;
4572 static char const* const frontend_threads;
4573+ static char const* const name_opt;
4574
4575 static char const* const glog;
4576 static char const* const glog_stderrthreshold;
4577
4578=== modified file 'include/server/mir/default_server_configuration.h'
4579--- include/server/mir/default_server_configuration.h 2013-11-05 09:36:37 +0000
4580+++ include/server/mir/default_server_configuration.h 2013-11-08 19:16:38 +0000
4581@@ -85,6 +85,7 @@
4582 class SurfaceStack;
4583 class SurfaceController;
4584 class InputRegistrar;
4585+class SurfacesReport;
4586 }
4587 namespace graphics
4588 {
4589@@ -105,6 +106,7 @@
4590 class CursorListener;
4591 class InputRegion;
4592 class NestedInputRelay;
4593+class EventHandler;
4594 }
4595
4596 namespace logging
4597@@ -138,7 +140,7 @@
4598 virtual std::shared_ptr<compositor::RendererFactory> the_renderer_factory();
4599 virtual std::shared_ptr<graphics::DisplayConfigurationPolicy> the_display_configuration_policy();
4600 virtual std::shared_ptr<graphics::nested::HostConnection> the_host_connection();
4601- virtual std::shared_ptr<input::NestedInputRelay> the_nested_input_relay();
4602+ virtual std::shared_ptr<input::EventFilter> the_nested_event_filter();
4603 /** @} */
4604
4605 /** @name graphics configuration - dependencies
4606@@ -184,6 +186,7 @@
4607 * configurable interfaces for modifying shell
4608 * @{ */
4609 virtual std::shared_ptr<shell::SurfaceFactory> the_shell_surface_factory();
4610+ virtual std::shared_ptr<shell::SurfaceFactory> the_surfaces_surface_factory();
4611 virtual std::shared_ptr<shell::SessionContainer> the_shell_session_container();
4612 virtual std::shared_ptr<shell::FocusSetter> the_shell_focus_setter();
4613 virtual std::shared_ptr<shell::FocusSequence> the_shell_focus_sequence();
4614@@ -195,6 +198,7 @@
4615 virtual std::shared_ptr<shell::SurfaceConfigurator> the_shell_surface_configurator();
4616 virtual std::shared_ptr<shell::SessionEventSink> the_shell_session_event_sink();
4617 virtual std::shared_ptr<shell::SessionEventHandlerRegister> the_shell_session_event_handler_register();
4618+ virtual std::shared_ptr<shell::SurfaceController> the_shell_surface_controller();
4619 /** @} */
4620
4621 /** @name shell configuration - dependencies
4622@@ -210,6 +214,7 @@
4623 * configurable interfaces for modifying surfaces
4624 * @{ */
4625 virtual std::shared_ptr<surfaces::SurfaceStackModel> the_surface_stack_model();
4626+ virtual std::shared_ptr<surfaces::SurfacesReport> the_surfaces_report();
4627 /** @} */
4628
4629 /** @name surfaces configuration - dependencies
4630@@ -276,7 +281,10 @@
4631 CachedPtr<compositor::RendererFactory> renderer_factory;
4632 CachedPtr<compositor::BufferStreamFactory> buffer_stream_factory;
4633 CachedPtr<surfaces::SurfaceStack> surface_stack;
4634+ CachedPtr<surfaces::SurfacesReport> surfaces_report;
4635+
4636 CachedPtr<shell::SurfaceFactory> shell_surface_factory;
4637+ CachedPtr<shell::SurfaceFactory> surfaces_surface_factory;
4638 CachedPtr<shell::SessionContainer> shell_session_container;
4639 CachedPtr<shell::FocusSetter> shell_focus_setter;
4640 CachedPtr<shell::FocusSequence> shell_focus_sequence;
4641@@ -310,6 +318,7 @@
4642 std::shared_ptr<graphics::GraphicBufferAllocator> const& allocator);
4643
4644 virtual std::string the_socket_file() const;
4645+ std::shared_ptr<input::NestedInputRelay> the_nested_input_relay();
4646 };
4647 }
4648
4649
4650=== modified file 'include/server/mir/frontend/surface.h'
4651--- include/server/mir/frontend/surface.h 2013-10-15 08:53:10 +0000
4652+++ include/server/mir/frontend/surface.h 2013-11-08 19:16:38 +0000
4653@@ -55,12 +55,7 @@
4654 virtual geometry::Size size() const = 0;
4655 virtual geometry::PixelFormat pixel_format() const = 0;
4656
4657- /// Submit the current client buffer, return the next client buffer
4658- ///
4659- /// \param [out] need_ipc: True if the buffer content must be sent via IPC
4660- /// False if only the buffer's ID must be sent.
4661- /// \returns The next client buffer
4662- virtual std::shared_ptr<graphics::Buffer> advance_client_buffer(bool& need_full_ipc) = 0;
4663+ virtual std::shared_ptr<graphics::Buffer> advance_client_buffer() = 0;
4664
4665 virtual bool supports_input() const = 0;
4666 virtual int client_input_fd() const = 0;
4667@@ -75,21 +70,7 @@
4668
4669 auto as_internal_surface(std::shared_ptr<Surface> const& surface)
4670 -> std::shared_ptr<graphics::InternalSurface>;
4671-
4672-class ClientTrackingSurface : public Surface
4673-{
4674-public:
4675- ClientTrackingSurface();
4676- virtual ~ClientTrackingSurface() = default;
4677-
4678- virtual std::shared_ptr<graphics::Buffer> advance_client_buffer(bool& need_full_ipc) override;
4679-
4680- virtual std::shared_ptr<graphics::Buffer> advance_client_buffer() = 0;
4681-private:
4682- std::shared_ptr<ClientBufferTracker> client_tracker;
4683-};
4684-
4685-}
4686+}
4687 }
4688
4689
4690
4691=== removed directory 'include/server/mir/graphics/nested'
4692=== modified file 'include/server/mir/shell/application_session.h'
4693--- include/server/mir/shell/application_session.h 2013-08-28 03:41:48 +0000
4694+++ include/server/mir/shell/application_session.h 2013-11-08 19:16:38 +0000
4695@@ -36,6 +36,9 @@
4696 class SnapshotStrategy;
4697 class SessionListener;
4698
4699+// TODO make private to shell
4700+// This first needs unity-mir and unit-system_compositor to be updated to use Session
4701+// and that first needs -c 1167 of development-branch to land on lp:mir
4702 class ApplicationSession : public Session
4703 {
4704 public:
4705
4706=== modified file 'include/server/mir/shell/focus_controller.h'
4707--- include/server/mir/shell/focus_controller.h 2013-08-28 03:41:48 +0000
4708+++ include/server/mir/shell/focus_controller.h 2013-11-08 19:16:38 +0000
4709@@ -19,18 +19,22 @@
4710 #ifndef MIR_SHELL_FOCUS_CONTROLLER_H_
4711 #define MIR_SHELL_FOCUS_CONTROLLER_H_
4712
4713+#include <memory>
4714+
4715 namespace mir
4716 {
4717-
4718 namespace shell
4719 {
4720+class Session;
4721
4722 class FocusController
4723 {
4724 public:
4725- virtual ~FocusController() {}
4726+ virtual ~FocusController() = default;
4727
4728 virtual void focus_next() = 0;
4729+ virtual std::weak_ptr<Session> focussed_application() const = 0;
4730+ virtual void set_focus_to(std::shared_ptr<Session> const& focus) = 0;
4731
4732 protected:
4733 FocusController() = default;
4734
4735=== modified file 'include/server/mir/shell/session.h'
4736--- include/server/mir/shell/session.h 2013-08-28 03:41:48 +0000
4737+++ include/server/mir/shell/session.h 2013-11-08 19:16:38 +0000
4738@@ -37,6 +37,7 @@
4739
4740 virtual void take_snapshot(SnapshotCallback const& snapshot_taken) = 0;
4741 virtual std::shared_ptr<Surface> default_surface() const = 0;
4742+ virtual void set_lifecycle_state(MirLifecycleState state) = 0;
4743 };
4744
4745 }
4746
4747=== modified file 'include/server/mir/shell/session_manager.h'
4748--- include/server/mir/shell/session_manager.h 2013-08-28 03:41:48 +0000
4749+++ include/server/mir/shell/session_manager.h 2013-11-08 19:16:38 +0000
4750@@ -48,6 +48,9 @@
4751 class SessionListener;
4752 struct SurfaceCreationParameters;
4753
4754+// TODO make private to shell
4755+// This first needs unity-mir to be updated to use FocusController
4756+// and that first needs -c 1175 of development-branch to land on lp:mir
4757 class SessionManager : public frontend::Shell, public shell::FocusController
4758 {
4759 public:
4760
4761=== modified file 'include/server/mir/shell/surface.h'
4762--- include/server/mir/shell/surface.h 2013-10-15 08:53:10 +0000
4763+++ include/server/mir/shell/surface.h 2013-11-08 19:16:38 +0000
4764@@ -21,87 +21,35 @@
4765 #define MIR_SHELL_SURFACE_H_
4766
4767 #include "mir/shell/surface_buffer_access.h"
4768+#include "mir/geometry/rectangle.h"
4769 #include "mir/frontend/surface.h"
4770-#include "mir/frontend/surface_id.h"
4771-#include "mir/surfaces/surface.h"
4772-
4773-#include "mir_toolkit/common.h"
4774
4775 #include <string>
4776+#include <vector>
4777
4778 namespace mir
4779 {
4780-namespace frontend
4781-{
4782-class EventSink;
4783-}
4784 namespace shell
4785 {
4786 class InputTargeter;
4787-class Session;
4788-class SurfaceBuilder;
4789-class SurfaceConfigurator;
4790 class SurfaceController;
4791-struct SurfaceCreationParameters;
4792
4793-class Surface : public frontend::ClientTrackingSurface, public shell::SurfaceBufferAccess
4794+class Surface : public frontend::Surface, public shell::SurfaceBufferAccess
4795 {
4796 public:
4797- Surface(
4798- Session* session,
4799- std::shared_ptr<SurfaceBuilder> const& builder,
4800- std::shared_ptr<SurfaceConfigurator> const& configurator,
4801- SurfaceCreationParameters const& params,
4802- frontend::SurfaceId id,
4803- std::shared_ptr<frontend::EventSink> const& event_sink);
4804-
4805- ~Surface() noexcept;
4806-
4807- virtual void hide();
4808- virtual void show();
4809-
4810- virtual void force_requests_to_complete();
4811-
4812- virtual std::string name() const;
4813-
4814- virtual void move_to(geometry::Point const& top_left);
4815-
4816- virtual geometry::Size size() const;
4817- virtual geometry::Point top_left() const;
4818-
4819- virtual geometry::PixelFormat pixel_format() const;
4820-
4821- virtual void with_most_recent_buffer_do(
4822- std::function<void(graphics::Buffer&)> const& exec);
4823- virtual std::shared_ptr<graphics::Buffer> advance_client_buffer();
4824-
4825- virtual bool supports_input() const;
4826- virtual int client_input_fd() const;
4827-
4828- virtual int configure(MirSurfaceAttrib attrib, int value);
4829- virtual MirSurfaceType type() const;
4830- virtual MirSurfaceState state() const;
4831-
4832- virtual void take_input_focus(std::shared_ptr<InputTargeter> const& targeter);
4833- virtual void set_input_region(std::vector<geometry::Rectangle> const& region);
4834-
4835- virtual void allow_framedropping(bool);
4836-
4837- virtual void raise(std::shared_ptr<SurfaceController> const& controller);
4838-private:
4839- bool set_type(MirSurfaceType t); // Use configure() to make public changes
4840- bool set_state(MirSurfaceState s);
4841- void notify_change(MirSurfaceAttrib attrib, int value);
4842-
4843- std::shared_ptr<SurfaceBuilder> const builder;
4844- std::shared_ptr<SurfaceConfigurator> const configurator;
4845- std::shared_ptr<mir::surfaces::Surface> const surface;
4846-
4847- frontend::SurfaceId const id;
4848- std::shared_ptr<frontend::EventSink> const event_sink;
4849-
4850- MirSurfaceType type_value;
4851- MirSurfaceState state_value;
4852+ virtual void hide() = 0;
4853+ virtual void show() = 0;
4854+ virtual void move_to(geometry::Point const& top_left) = 0;
4855+ virtual geometry::Point top_left() const = 0;
4856+
4857+ virtual void take_input_focus(std::shared_ptr<InputTargeter> const& targeter) = 0;
4858+ virtual void set_input_region(std::vector<geometry::Rectangle> const& region) = 0;
4859+
4860+ virtual void allow_framedropping(bool) = 0;
4861+
4862+ virtual void raise(std::shared_ptr<SurfaceController> const& controller) = 0;
4863+
4864+ virtual void resize(geometry::Size const& size) = 0;
4865 };
4866 }
4867 }
4868
4869=== modified file 'include/server/mir/shell/surface_builder.h'
4870--- include/server/mir/shell/surface_builder.h 2013-08-28 03:41:48 +0000
4871+++ include/server/mir/shell/surface_builder.h 2013-11-08 19:16:38 +0000
4872@@ -24,7 +24,7 @@
4873
4874 namespace mir
4875 {
4876-namespace surfaces { class Surface; }
4877+namespace surfaces { class BasicSurface; }
4878
4879 namespace shell
4880 {
4881@@ -34,9 +34,9 @@
4882 class SurfaceBuilder
4883 {
4884 public:
4885- virtual std::weak_ptr<surfaces::Surface> create_surface(Session* session, SurfaceCreationParameters const& params) = 0;
4886+ virtual std::weak_ptr<surfaces::BasicSurface> create_surface(Session* session, SurfaceCreationParameters const& params) = 0;
4887
4888- virtual void destroy_surface(std::weak_ptr<surfaces::Surface> const& surface) = 0;
4889+ virtual void destroy_surface(std::weak_ptr<surfaces::BasicSurface> const& surface) = 0;
4890 protected:
4891 SurfaceBuilder() = default;
4892 virtual ~SurfaceBuilder() {} // should be "= default;" but that causes "noexcept" spread
4893
4894=== modified file 'include/server/mir/shell/surface_controller.h'
4895--- include/server/mir/shell/surface_controller.h 2013-07-29 23:14:57 +0000
4896+++ include/server/mir/shell/surface_controller.h 2013-11-08 19:16:38 +0000
4897@@ -26,7 +26,7 @@
4898 {
4899 namespace surfaces
4900 {
4901-class Surface;
4902+class BasicSurface;
4903 }
4904
4905 namespace shell
4906@@ -35,7 +35,7 @@
4907 class SurfaceController
4908 {
4909 public:
4910- virtual void raise(std::weak_ptr<surfaces::Surface> const& surface) = 0;
4911+ virtual void raise(std::weak_ptr<surfaces::BasicSurface> const& surface) = 0;
4912
4913 protected:
4914 SurfaceController() = default;
4915
4916=== renamed file 'include/server/mir/surfaces/surface.h' => 'include/server/mir/surfaces/basic_surface.h'
4917--- include/server/mir/surfaces/surface.h 2013-08-29 09:20:06 +0000
4918+++ include/server/mir/surfaces/basic_surface.h 2013-11-08 19:16:38 +0000
4919@@ -16,8 +16,8 @@
4920 * Authored by: Thomas Voss <thomas.voss@canonical.com>
4921 */
4922
4923-#ifndef MIR_SURFACES_SURFACE_H_
4924-#define MIR_SURFACES_SURFACE_H_
4925+#ifndef MIR_SURFACES_BASIC_SURFACE_H_
4926+#define MIR_SURFACES_BASIC_SURFACE_H_
4927
4928 #include "mir/geometry/pixel_format.h"
4929 #include "mir/geometry/rectangle.h"
4930@@ -34,6 +34,7 @@
4931 {
4932 class CompositingCriteria;
4933 struct BufferIPCPackage;
4934+class BufferStream;
4935 }
4936 namespace graphics
4937 {
4938@@ -46,57 +47,48 @@
4939 }
4940 namespace surfaces
4941 {
4942-class SurfaceState;
4943-class BufferStream;
4944-
4945-// TODO this is ideally an implementation class. It is only in a public header
4946-// TODO because it is used in some example code (which probably needs rethinking).
4947-class Surface
4948+class BasicSurface
4949 {
4950 public:
4951- Surface(std::shared_ptr<surfaces::SurfaceState> const& surface_state,
4952- std::shared_ptr<BufferStream> const& buffer_stream,
4953- std::shared_ptr<input::InputChannel> const& input_channel);
4954-
4955- ~Surface();
4956-
4957- std::string const& name() const;
4958- void move_to(geometry::Point const& top_left);
4959- void set_rotation(float degrees, glm::vec3 const& axis);
4960- void set_alpha(float alpha);
4961- void set_hidden(bool is_hidden);
4962-
4963- /* From Renderable */
4964- geometry::Point top_left() const;
4965- geometry::Size size() const;
4966-
4967- geometry::PixelFormat pixel_format() const;
4968-
4969- std::shared_ptr<graphics::Buffer> snapshot_buffer() const;
4970- std::shared_ptr<graphics::Buffer> advance_client_buffer();
4971- void force_requests_to_complete();
4972- void flag_for_render();
4973-
4974- bool supports_input() const;
4975- int client_input_fd() const;
4976- void allow_framedropping(bool);
4977- std::shared_ptr<input::InputChannel> input_channel() const;
4978-
4979- void set_input_region(std::vector<geometry::Rectangle> const& input_rectangles);
4980-
4981- std::shared_ptr<compositor::CompositingCriteria> compositing_criteria();
4982-
4983- std::shared_ptr<BufferStream> buffer_stream() const;
4984-
4985- std::shared_ptr<input::Surface> input_surface() const;
4986+ BasicSurface() = default;
4987+ virtual ~BasicSurface() = default;
4988+
4989+ virtual std::string const& name() const = 0;
4990+ virtual void move_to(geometry::Point const& top_left) = 0;
4991+ virtual void set_rotation(float degrees, glm::vec3 const& axis) = 0;
4992+ virtual void set_alpha(float alpha) = 0;
4993+ virtual void set_hidden(bool is_hidden) = 0;
4994+
4995+ virtual geometry::Point top_left() const = 0;
4996+ virtual geometry::Size size() const = 0;
4997+
4998+ virtual geometry::PixelFormat pixel_format() const = 0;
4999+
5000+ virtual std::shared_ptr<graphics::Buffer> snapshot_buffer() const = 0;
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches