33
33
34
34
#include "gesture_detection.h"
35
35
36
+ // FIXME use 2 for SCROLL_FINGER_COUNT as soon as possible
37
+ #define SCROLL_FINGER_COUNT 4
38
+
39
+
36
40
typedef struct point {
37
41
int x ;
38
42
int y ;
@@ -43,6 +47,15 @@ typedef struct mt_slots {
43
47
point_t points [2 ];
44
48
} mt_slots_t ;
45
49
50
+ typedef struct scroll {
51
+ point_t last_point ;
52
+ struct input_event last_x_abs_event ;
53
+ struct input_event last_y_abs_event ;
54
+ double x_velocity ;
55
+ double y_velocity ;
56
+ int32_t width ;
57
+ } scroll_t ;
58
+
46
59
typedef struct gesture_start {
47
60
point_t point ;
48
61
uint32_t distance ;
@@ -51,6 +64,7 @@ typedef struct gesture_start {
51
64
mt_slots_t mt_slots ;
52
65
gesture_start_t gesture_start ;
53
66
uint8_t finger_count ;
67
+ scroll_t scroll ;
54
68
55
69
static int test_grab (int fd ) {
56
70
int rc ;
@@ -70,9 +84,14 @@ static void init_gesture() {
70
84
x_distance = mt_slots .points [0 ].x - mt_slots .points [1 ].x ;
71
85
y_distance = mt_slots .points [0 ].y - mt_slots .points [1 ].y ;
72
86
gesture_start .distance = (uint32_t ) sqrt ((x_distance * x_distance ) + (y_distance * y_distance ));
87
+ scroll .width = 0 ;
88
+ scroll .last_point = mt_slots .points [0 ];
73
89
}
74
90
}
75
91
92
+ /*
93
+ * @return number of fingers on touch device
94
+ */
76
95
static uint8_t process_key_event (struct input_event event ) {
77
96
uint8_t finger_count ;
78
97
if (event .value == 1 ) {
@@ -101,32 +120,66 @@ static uint8_t process_key_event(struct input_event event) {
101
120
return finger_count ;
102
121
}
103
122
123
+ /*
124
+ * @return velocity in distance per milliseconds
125
+ */
126
+ static double calcualte_velocity (struct input_event event1 , struct input_event event2 ) {
127
+ int32_t distance = event2 .value - event1 .value ;
128
+ double time_delta =
129
+ event2 .time .tv_sec * 1000 + event2 .time .tv_usec / 1000 - event1 .time .tv_sec * 1000 - event1 .time .tv_usec / 1000 ;
130
+ return distance / time_delta ;
131
+ }
132
+
104
133
static void process_abs_event (struct input_event event ) {
105
134
if (event .code == ABS_MT_SLOT ) {
106
135
mt_slots .active = event .value ;
107
136
} else if (mt_slots .active < 2 ) {
108
137
switch (event .code ) {
109
138
case ABS_MT_POSITION_X :
139
+ if (mt_slots .active == 0 ) {
140
+ if (scroll .last_x_abs_event .type == EV_ABS && scroll .last_x_abs_event .code == ABS_MT_POSITION_X ) {
141
+ scroll .x_velocity = calcualte_velocity (event , scroll .last_x_abs_event );
142
+ }
143
+ scroll .last_x_abs_event = event ;
144
+ scroll .last_point .x = mt_slots .points [0 ].x ;
145
+ }
110
146
mt_slots .points [mt_slots .active ].x = event .value ;
111
147
break ;
112
148
case ABS_MT_POSITION_Y :
149
+ if (mt_slots .active == 0 ) {
150
+ if (scroll .last_y_abs_event .type == EV_ABS && scroll .last_y_abs_event .code == ABS_MT_POSITION_Y ) {
151
+ scroll .y_velocity = calcualte_velocity (scroll .last_y_abs_event , event );
152
+ }
153
+ scroll .last_y_abs_event = event ;
154
+ scroll .last_point .y = mt_slots .points [0 ].y ;
155
+ }
113
156
mt_slots .points [mt_slots .active ].y = event .value ;
114
157
break ;
115
158
}
116
159
}
117
160
}
118
161
119
- static void set_syn_event (struct input_event * syn_event ) {
120
- memset (syn_event , 0 , sizeof (struct input_event ));
121
- syn_event -> type = EV_SYN ;
122
- syn_event -> code = SYN_REPORT ;
162
+ static void set_input_event (struct input_event * input_event , int type , int code , int value ) {
163
+ memset (input_event , 0 , sizeof (struct input_event ));
164
+ input_event -> type = type ;
165
+ input_event -> code = code ;
166
+ input_event -> value = value ;
123
167
}
124
168
125
- static void set_key_event (struct input_event * key_event , int code , int value ) {
126
- memset (key_event , 0 , sizeof (struct input_event ));
127
- key_event -> type = EV_KEY ;
128
- key_event -> code = code ;
129
- key_event -> value = value ;
169
+ #define set_syn_event (syn_event ) set_input_event(syn_event, EV_SYN, SYN_REPORT, 0)
170
+ #define set_key_event (key_event , code , value ) set_input_event(key_event, EV_KEY, code, value)
171
+ #define set_rel_event (rel_event , code , value ) set_input_event(rel_event, EV_REL, code, value)
172
+
173
+ static input_event_array_t * do_scroll (int32_t distance , int32_t delta , int rel_code ) {
174
+ input_event_array_t * result = NULL ;
175
+ scroll .width += distance ;
176
+ if (fabs (scroll .width ) > delta ) {
177
+ result = new_input_event_array (2 );
178
+ set_rel_event (& result -> data [0 ], rel_code , scroll .width / delta );
179
+ set_syn_event (& result -> data [1 ]);
180
+ scroll .width %= delta ;
181
+ }
182
+ return result ;
130
183
}
131
184
132
185
static input_event_array_t * process_syn_event (struct input_event event ,
@@ -140,16 +193,24 @@ static input_event_array_t *process_syn_event(struct input_event event,
140
193
x_distance = gesture_start .point .x - mt_slots .points [0 ].x ;
141
194
y_distance = gesture_start .point .y - mt_slots .points [0 ].y ;
142
195
if (fabs (x_distance ) > fabs (y_distance )) {
143
- if (x_distance > thresholds .x ) {
144
- direction = LEFT ;
145
- } else if (x_distance < - thresholds .x ) {
146
- direction = RIGHT ;
196
+ if (!(config .scroll .horz && finger_count == SCROLL_FINGER_COUNT )) {
197
+ if (x_distance > thresholds .x ) {
198
+ direction = LEFT ;
199
+ } else if (x_distance < - thresholds .x ) {
200
+ direction = RIGHT ;
201
+ }
202
+ } else {
203
+ result = do_scroll (scroll .last_point .x - mt_slots .points [0 ].x , config .scroll .horz_delta , REL_HWHEEL );
147
204
}
148
205
} else {
149
- if (y_distance > thresholds .y ) {
150
- direction = UP ;
151
- } else if (y_distance < - thresholds .y ) {
152
- direction = DOWN ;
206
+ if (!(config .scroll .vert && finger_count == SCROLL_FINGER_COUNT )) {
207
+ if (y_distance > thresholds .y ) {
208
+ direction = UP ;
209
+ } else if (y_distance < - thresholds .y ) {
210
+ direction = DOWN ;
211
+ }
212
+ } else {
213
+ result = do_scroll (mt_slots .points [0 ].y - scroll .last_point .y , config .scroll .vert_delta , REL_WHEEL );
153
214
}
154
215
}
155
216
if (direction != NONE ) {
0 commit comments