xref: /aosp_15_r20/external/libchrome-gestures/include/scaling_filter_interpreter.h (revision aed3e5085e770be5b69ce25295ecf6ddf906af95)
1 // Copyright 2012 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <gtest/gtest.h>  // for FRIEND_TEST
6 
7 #include "include/filter_interpreter.h"
8 #include "include/gestures.h"
9 #include "include/prop_registry.h"
10 #include "include/tracer.h"
11 
12 #ifndef GESTURES_SCALING_FILTER_INTERPRETER_H_
13 #define GESTURES_SCALING_FILTER_INTERPRETER_H_
14 
15 namespace gestures {
16 
17 // This interpreter scales both incoming hardware state and outgoing gesture
18 // objects to make it easier for library code to do interpretation work.
19 
20 // Incoming hardware events are in the units of touchpad pixels, which may
21 // not be square. We convert these to a same-sized touchpad such that
22 // the units are mm with a (0,0) origin. Correspondingly, we convert the
23 // gestures from mm units to screen pixels.
24 
25 // For example, say we have a touchpad that has these properties:
26 // size: 100m x 60mm, left/right: 133/10279, top/bottom: 728/5822.
27 // This class will scale/translate it, so that the next Interpreter is told
28 // the hardware has these properties:
29 // size: 100m x 60mm, left/right: 0.0/100.0, top/bottom: 0.0/60.0.
30 // Incoming hardware states will be scaled in transit.
31 
32 // Also, the screen DPI will be scaled, so that it exactly matches the
33 // touchpad, by having 1 dot per mm. Thus, the screen DPI told to the next
34 // Interpreter will be 25.4.
35 // Outgoing gesture objects will be scaled in transit to what the screen
36 // actually uses.
37 
38 // This interpreter can be configured to compute surface area in square mm
39 // from pressure data or from touch major and minor, as some hardware prefers
40 // reporting pressure data but some other touch major and minor.
41 //
42 // When the pressure is converted (based on properties) to surface area, the
43 // two properties allow a configuration file to specify a linear relationship
44 // between pressure and surface area.
45 
46 class ScalingFilterInterpreter : public FilterInterpreter {
47   FRIEND_TEST(ScalingFilterInterpreterTest, SimpleTest);
48   FRIEND_TEST(ScalingFilterInterpreterTest, TouchMajorAndMinorTest);
49  public:
50   // Takes ownership of |next|:
51   ScalingFilterInterpreter(PropRegistry* prop_reg,
52                            Interpreter* next,
53                            Tracer* tracer,
54                            GestureInterpreterDeviceClass devclass);
~ScalingFilterInterpreter()55   virtual ~ScalingFilterInterpreter() {}
56 
57   virtual void Initialize(const HardwareProperties* hwprops,
58                           Metrics* metrics, MetricsProperties* mprops,
59                           GestureConsumer* consumer);
60  protected:
61   virtual void SyncInterpretImpl(HardwareState& hwstate, stime_t* timeout);
62 
63  private:
64   void ScaleHardwareState(HardwareState& hwstate);
65   void ScaleMouseHardwareState(HardwareState& hwstate);
66   void ScaleTouchpadHardwareState(HardwareState& hwstate);
67   void ConsumeGesture(const Gesture& gs);
68   void FilterLowPressure(HardwareState& hwstate);
69   void FilterZeroArea(HardwareState& hwstate);
70   bool IsMouseDevice(GestureInterpreterDeviceClass devclass);
71   bool IsPointingStick(GestureInterpreterDeviceClass devclass);
72   bool IsTouchpadDevice(GestureInterpreterDeviceClass devclass);
73 
74   float tp_x_scale_, tp_y_scale_;
75   float tp_x_translate_, tp_y_translate_;
76 
77   float screen_x_scale_, screen_y_scale_;
78 
79   // When orientation_scale_ = 0, no orientation is provided from kernel.
80   float orientation_scale_;
81 
82   HardwareProperties friendly_props_;
83 
84   // When set to true, scroll and swipe gesture directions are inverted.
85   BoolProperty invert_scrolling_and_swiping_;
86 
87   // When set to true, only scroll gesture directions are inverted.
88   BoolProperty invert_scrolling_only_;
89 
90   // Output surface area (sq. mm) =
91   // if surface_area_from_pressure_
92   //   input pressure * pressure_scale_ + pressure_translate_
93   // else
94   //   if input touch_major != 0 and input touch_minor != 0
95   //     pi / 4 * output touch_major * output touch_minor
96   //   else if input touch_major != 0
97   //     pi / 4 * output touch_major^2
98   //   else
99   //     0
100   BoolProperty surface_area_from_pressure_;
101 
102   BoolProperty use_touch_size_for_haptic_pad_;
103 
104   // Touchpad device output bias (pixels).
105   DoubleProperty tp_x_bias_;
106   DoubleProperty tp_y_bias_;
107 
108   DoubleProperty pressure_scale_;
109   DoubleProperty pressure_translate_;
110   DoubleProperty pressure_threshold_;
111   // if true, the low pressure touch will be ignored.
112   // if false, or doesn't exist, the low pressure touch will be converted
113   // to touch with pressure 1.0
114   BoolProperty filter_low_pressure_;
115 
116   // If true, adjust touch count to match finger count when scaling
117   // input state. This can help avoid being considered a T5R2 pad.
118   BoolProperty force_touch_count_to_match_finger_count_;
119 
120   DoubleProperty mouse_cpi_;
121 
122   // XInput properties that we use to identify the device type in Chrome for
123   // all CMT devices. We put them here for now because they are not large
124   // enough to constitute a stand-alone class.
125   // TODO(sheckylin): Find a better place for them.
126 
127   // If the device is mouse. Note that a device can both be a mouse and a
128   // touchpad at the same time (e.g. a multi-touch mouse).
129   BoolProperty device_mouse_;
130 
131   // If the device is a pointing stick (e.g. a TrackPoint).
132   BoolProperty device_pointing_stick_;
133 
134   // If the device is touchpad. It would be false if it is a regular mouse
135   // running the CMT driver.
136   BoolProperty device_touchpad_;
137 };
138 
139 }  // namespace gestures
140 
141 #endif  // GESTURES_SCALING_FILTER_INTERPRETER_H_
142