// Copyright 2012 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include // for FRIEND_TEST #include "include/filter_interpreter.h" #include "include/gestures.h" #include "include/prop_registry.h" #include "include/tracer.h" #ifndef GESTURES_SCALING_FILTER_INTERPRETER_H_ #define GESTURES_SCALING_FILTER_INTERPRETER_H_ namespace gestures { // This interpreter scales both incoming hardware state and outgoing gesture // objects to make it easier for library code to do interpretation work. // Incoming hardware events are in the units of touchpad pixels, which may // not be square. We convert these to a same-sized touchpad such that // the units are mm with a (0,0) origin. Correspondingly, we convert the // gestures from mm units to screen pixels. // For example, say we have a touchpad that has these properties: // size: 100m x 60mm, left/right: 133/10279, top/bottom: 728/5822. // This class will scale/translate it, so that the next Interpreter is told // the hardware has these properties: // size: 100m x 60mm, left/right: 0.0/100.0, top/bottom: 0.0/60.0. // Incoming hardware states will be scaled in transit. // Also, the screen DPI will be scaled, so that it exactly matches the // touchpad, by having 1 dot per mm. Thus, the screen DPI told to the next // Interpreter will be 25.4. // Outgoing gesture objects will be scaled in transit to what the screen // actually uses. // This interpreter can be configured to compute surface area in square mm // from pressure data or from touch major and minor, as some hardware prefers // reporting pressure data but some other touch major and minor. // // When the pressure is converted (based on properties) to surface area, the // two properties allow a configuration file to specify a linear relationship // between pressure and surface area. class ScalingFilterInterpreter : public FilterInterpreter { FRIEND_TEST(ScalingFilterInterpreterTest, SimpleTest); FRIEND_TEST(ScalingFilterInterpreterTest, TouchMajorAndMinorTest); public: // Takes ownership of |next|: ScalingFilterInterpreter(PropRegistry* prop_reg, Interpreter* next, Tracer* tracer, GestureInterpreterDeviceClass devclass); virtual ~ScalingFilterInterpreter() {} virtual void Initialize(const HardwareProperties* hwprops, Metrics* metrics, MetricsProperties* mprops, GestureConsumer* consumer); protected: virtual void SyncInterpretImpl(HardwareState& hwstate, stime_t* timeout); private: void ScaleHardwareState(HardwareState& hwstate); void ScaleMouseHardwareState(HardwareState& hwstate); void ScaleTouchpadHardwareState(HardwareState& hwstate); void ConsumeGesture(const Gesture& gs); void FilterLowPressure(HardwareState& hwstate); void FilterZeroArea(HardwareState& hwstate); bool IsMouseDevice(GestureInterpreterDeviceClass devclass); bool IsPointingStick(GestureInterpreterDeviceClass devclass); bool IsTouchpadDevice(GestureInterpreterDeviceClass devclass); float tp_x_scale_, tp_y_scale_; float tp_x_translate_, tp_y_translate_; float screen_x_scale_, screen_y_scale_; // When orientation_scale_ = 0, no orientation is provided from kernel. float orientation_scale_; HardwareProperties friendly_props_; // When set to true, scroll and swipe gesture directions are inverted. BoolProperty invert_scrolling_and_swiping_; // When set to true, only scroll gesture directions are inverted. BoolProperty invert_scrolling_only_; // Output surface area (sq. mm) = // if surface_area_from_pressure_ // input pressure * pressure_scale_ + pressure_translate_ // else // if input touch_major != 0 and input touch_minor != 0 // pi / 4 * output touch_major * output touch_minor // else if input touch_major != 0 // pi / 4 * output touch_major^2 // else // 0 BoolProperty surface_area_from_pressure_; BoolProperty use_touch_size_for_haptic_pad_; // Touchpad device output bias (pixels). DoubleProperty tp_x_bias_; DoubleProperty tp_y_bias_; DoubleProperty pressure_scale_; DoubleProperty pressure_translate_; DoubleProperty pressure_threshold_; // if true, the low pressure touch will be ignored. // if false, or doesn't exist, the low pressure touch will be converted // to touch with pressure 1.0 BoolProperty filter_low_pressure_; // If true, adjust touch count to match finger count when scaling // input state. This can help avoid being considered a T5R2 pad. BoolProperty force_touch_count_to_match_finger_count_; DoubleProperty mouse_cpi_; // XInput properties that we use to identify the device type in Chrome for // all CMT devices. We put them here for now because they are not large // enough to constitute a stand-alone class. // TODO(sheckylin): Find a better place for them. // If the device is mouse. Note that a device can both be a mouse and a // touchpad at the same time (e.g. a multi-touch mouse). BoolProperty device_mouse_; // If the device is a pointing stick (e.g. a TrackPoint). BoolProperty device_pointing_stick_; // If the device is touchpad. It would be false if it is a regular mouse // running the CMT driver. BoolProperty device_touchpad_; }; } // namespace gestures #endif // GESTURES_SCALING_FILTER_INTERPRETER_H_