| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_LIB_UI_INPUT_DEVICE_STATE_H_ |
| #define SRC_LIB_UI_INPUT_DEVICE_STATE_H_ |
| |
| #include <fuchsia/math/cpp/fidl.h> |
| #include <fuchsia/ui/input/cpp/fidl.h> |
| #include <lib/fit/function.h> |
| #include <lib/zx/time.h> |
| #include <stdint.h> |
| |
| #include <vector> |
| |
| #include <hid/hid.h> |
| #include <hid/usages.h> |
| |
| #include "src/lib/fxl/memory/ref_counted.h" |
| #include "src/lib/fxl/memory/weak_ptr.h" |
| |
| namespace ui_input { |
| |
| using OnEventCallback = fit::function<void(fuchsia::ui::input::InputEvent event)>; |
| |
| // In contrast to keyboard and mouse devices, which require extra state to |
| // correctly interpret their data, sensor devices are simpler, so we just pass |
| // through the raw InputReport. We do need a device_id to understand which |
| // sensor the report came from. |
| using OnSensorEventCallback = |
| fit::function<void(uint32_t device_id, fuchsia::ui::input::InputReport event)>; |
| |
| using OnMediaButtonsEventCallback = fit::function<void(fuchsia::ui::input::InputReport event)>; |
| |
| class DeviceState; |
| |
| class State { |
| public: |
| void OnRegistered() {} |
| void OnUnregistered() {} |
| }; |
| |
| class KeyboardState : public State { |
| public: |
| KeyboardState(DeviceState* device_state); |
| void Update(fuchsia::ui::input::InputReport report); |
| |
| private: |
| void SendEvent(fuchsia::ui::input::KeyboardEventPhase phase, uint32_t key, uint64_t modifiers, |
| uint64_t timestamp); |
| void Repeat(uint64_t sequence); |
| void ScheduleRepeat(uint64_t sequence, zx::duration delta); |
| |
| DeviceState* device_state_; |
| const keychar_t* keymap_; // assigned to a global static qwerty_map or dvorak_map |
| |
| std::vector<uint32_t> keys_; |
| std::vector<uint32_t> repeat_keys_; |
| uint64_t modifiers_ = 0; |
| uint64_t repeat_sequence_ = 0; |
| |
| fxl::WeakPtrFactory<KeyboardState> weak_ptr_factory_; |
| }; |
| |
| class MouseState : public State { |
| public: |
| MouseState(DeviceState* device_state) : device_state_(device_state) {} |
| void Update(fuchsia::ui::input::InputReport report, fuchsia::math::Size display_size); |
| void OnRegistered(); |
| void OnUnregistered(); |
| |
| private: |
| void SendEvent(float rel_x, float rel_y, int64_t timestamp, |
| fuchsia::ui::input::PointerEventPhase phase, uint32_t buttons); |
| |
| DeviceState* device_state_; |
| uint8_t buttons_ = 0; |
| fuchsia::math::PointF position_; |
| }; |
| |
| class StylusState : public State { |
| public: |
| StylusState(DeviceState* device_state) : device_state_(device_state) {} |
| void Update(fuchsia::ui::input::InputReport report, fuchsia::math::Size display_size); |
| |
| private: |
| void SendEvent(int64_t timestamp, fuchsia::ui::input::PointerEventPhase phase, |
| fuchsia::ui::input::PointerEventType type, float x, float y, uint32_t buttons); |
| |
| DeviceState* device_state_; |
| bool stylus_down_ = false; |
| bool stylus_in_range_ = false; |
| bool inverted_stylus_ = false; |
| fuchsia::ui::input::PointerEvent stylus_; |
| }; |
| |
| class TouchscreenState : public State { |
| public: |
| TouchscreenState(DeviceState* device_state) : device_state_(device_state) {} |
| void Update(fuchsia::ui::input::InputReport report, fuchsia::math::Size display_size); |
| |
| private: |
| DeviceState* device_state_; |
| std::vector<fuchsia::ui::input::PointerEvent> pointers_; |
| }; |
| |
| class SensorState : public State { |
| public: |
| SensorState(DeviceState* device_state) : device_state_(device_state) {} |
| void Update(fuchsia::ui::input::InputReport report); |
| |
| private: |
| DeviceState* device_state_; |
| // TODO(fxbug.dev/23853): Remember sampling frequency and physical units. |
| }; |
| |
| class MediaButtonState : public State { |
| public: |
| MediaButtonState(DeviceState* device_state) : device_state_(device_state) {} |
| void Update(fuchsia::ui::input::InputReport report); |
| |
| private: |
| DeviceState* device_state_; |
| }; |
| |
| class DeviceState { |
| public: |
| DeviceState(uint32_t device_id, fuchsia::ui::input::DeviceDescriptor* descriptor, |
| OnEventCallback callback); |
| DeviceState(uint32_t device_id, fuchsia::ui::input::DeviceDescriptor* descriptor, |
| OnSensorEventCallback callback); |
| DeviceState(uint32_t device_id, fuchsia::ui::input::DeviceDescriptor* descriptor, |
| OnMediaButtonsEventCallback callback); |
| ~DeviceState(); |
| |
| void OnRegistered(); |
| void OnUnregistered(); |
| |
| void Update(fuchsia::ui::input::InputReport report, fuchsia::math::Size display_size); |
| |
| uint32_t device_id() { return device_id_; } |
| const OnEventCallback& callback() { return callback_; } |
| const OnSensorEventCallback& sensor_callback() { return sensor_callback_; } |
| const OnMediaButtonsEventCallback& media_buttons_callback() { return media_buttons_callback_; } |
| |
| fuchsia::ui::input::KeyboardDescriptor* keyboard_descriptor() { |
| return descriptor_->keyboard.get(); |
| } |
| fuchsia::ui::input::MouseDescriptor* mouse_descriptor() { return descriptor_->mouse.get(); } |
| fuchsia::ui::input::StylusDescriptor* stylus_descriptor() { return descriptor_->stylus.get(); } |
| fuchsia::ui::input::TouchscreenDescriptor* touchscreen_descriptor() { |
| return descriptor_->touchscreen.get(); |
| } |
| fuchsia::ui::input::SensorDescriptor* sensor_descriptor() { return descriptor_->sensor.get(); } |
| fuchsia::ui::input::MediaButtonsDescriptor* media_buttons_descriptor() { |
| return descriptor_->media_buttons.get(); |
| } |
| |
| private: |
| uint32_t device_id_; |
| fuchsia::ui::input::DeviceDescriptor* descriptor_; |
| |
| KeyboardState keyboard_; |
| MouseState mouse_; |
| StylusState stylus_; |
| TouchscreenState touchscreen_; |
| OnEventCallback callback_; |
| |
| SensorState sensor_; |
| OnSensorEventCallback sensor_callback_; |
| |
| OnMediaButtonsEventCallback media_buttons_callback_; |
| MediaButtonState media_buttons_; |
| }; |
| |
| } // namespace ui_input |
| |
| #endif // SRC_LIB_UI_INPUT_DEVICE_STATE_H_ |