37
37
38
38
// FIXME use 2 for SCROLL_FINGER_COUNT as soon as possible
39
39
#define SCROLL_FINGER_COUNT 4
40
- #define SCROLL_SLOW_DOWN_FACTOR -0.01
40
+ #define SCROLL_SLOW_DOWN_FACTOR -0.006
41
41
42
42
typedef struct point {
43
43
int x ;
@@ -63,6 +63,12 @@ typedef struct gesture_start {
63
63
uint32_t distance ;
64
64
} gesture_start_t ;
65
65
66
+ typedef struct scroll_thread_params {
67
+ uint8_t delta ;
68
+ int code ;
69
+ void (* callback )(input_event_array_t * );
70
+ } scroll_thread_params_t ;
71
+
66
72
mt_slots_t mt_slots ;
67
73
gesture_start_t gesture_start ;
68
74
uint8_t finger_count ;
@@ -136,27 +142,38 @@ static double calcualte_velocity(struct input_event event1, struct input_event e
136
142
137
143
static void process_abs_event (struct input_event event ) {
138
144
if (event .code == ABS_MT_SLOT ) {
145
+ // store the current mt_slot
139
146
mt_slots .active = event .value ;
140
147
} else if (mt_slots .active < 2 ) {
141
148
switch (event .code ) {
142
149
case ABS_MT_POSITION_X :
150
+ // if finger count matches SCROLL_FINGER_COUNT and the ABS_MT_POSITION_X is for the first finger
151
+ // the scroll data need to be updated
143
152
if (mt_slots .active == 0 && finger_count == SCROLL_FINGER_COUNT ) {
153
+ // check wether a correct input event was set to scroll.last_x_abs_event
144
154
if (scroll .last_x_abs_event .type == EV_ABS && scroll .last_x_abs_event .code == ABS_MT_POSITION_X ) {
145
- scroll .x_velocity = calcualte_velocity (event , scroll .last_x_abs_event );
155
+ // invert the velocity to scroll to the correct direction as a positive x direction
156
+ // on the touchpad mean scroll left (negative scroll direction)
157
+ scroll .x_velocity = - calcualte_velocity (scroll .last_x_abs_event , event );
146
158
}
147
159
scroll .last_x_abs_event = event ;
148
160
scroll .last_point .x = mt_slots .points [0 ].x ;
149
161
}
162
+ // store the current x position for the current mt_slot
150
163
mt_slots .points [mt_slots .active ].x = event .value ;
151
164
break ;
152
165
case ABS_MT_POSITION_Y :
166
+ // if finger count matches SCROLL_FINGER_COUNT and the ABS_MT_POSITION_Y is for the first finger
167
+ // the scroll data need to be updated
153
168
if (mt_slots .active == 0 && finger_count == SCROLL_FINGER_COUNT ) {
169
+ // check wether a correct input event was set to scroll.last_y_abs_event
154
170
if (scroll .last_y_abs_event .type == EV_ABS && scroll .last_y_abs_event .code == ABS_MT_POSITION_Y ) {
155
171
scroll .y_velocity = calcualte_velocity (scroll .last_y_abs_event , event );
156
172
}
157
173
scroll .last_y_abs_event = event ;
158
174
scroll .last_point .y = mt_slots .points [0 ].y ;
159
175
}
176
+ // store the current y position for the current mt_slot
160
177
mt_slots .points [mt_slots .active ].y = event .value ;
161
178
break ;
162
179
}
@@ -176,7 +193,10 @@ static void set_input_event(struct input_event *input_event, int type, int code,
176
193
177
194
static input_event_array_t * do_scroll (double distance , int32_t delta , int rel_code ) {
178
195
input_event_array_t * result = NULL ;
196
+ // increment the scroll width by the current moved distance
179
197
scroll .width += distance ;
198
+ // a scroll width of delta means scroll one "scroll-unit" therefore a scroll event
199
+ // can be first triggered if the absolute value of scroll.width exeeded delta
180
200
if (fabs (scroll .width ) > delta ) {
181
201
result = new_input_event_array (2 );
182
202
int width = (int )(scroll .width / delta );
@@ -198,6 +218,8 @@ static input_event_array_t *process_syn_event(struct input_event event,
198
218
x_distance = gesture_start .point .x - mt_slots .points [0 ].x ;
199
219
y_distance = gesture_start .point .y - mt_slots .points [0 ].y ;
200
220
if (fabs (x_distance ) > fabs (y_distance )) {
221
+ // only check for the finger_count LEFT and RIGHT gestures if horizontal scrolling is
222
+ // disabled and the the finger_count doesn't match SCROLL_FINGER_COUNT
201
223
if (!(config .scroll .horz && finger_count == SCROLL_FINGER_COUNT )) {
202
224
if (x_distance > thresholds .x ) {
203
225
direction = LEFT ;
@@ -208,6 +230,8 @@ static input_event_array_t *process_syn_event(struct input_event event,
208
230
result = do_scroll (scroll .last_point .x - mt_slots .points [0 ].x , config .scroll .horz_delta , REL_HWHEEL );
209
231
}
210
232
} else {
233
+ // only check for the finger_count UP and DOWN gestures if horizontal scrolling is
234
+ // disabled and the the finger_count doesn't match SCROLL_FINGER_COUNT
211
235
if (!(config .scroll .vert && finger_count == SCROLL_FINGER_COUNT )) {
212
236
if (y_distance > thresholds .y ) {
213
237
direction = UP ;
@@ -250,34 +274,35 @@ static int32_t get_axix_threshold(int fd, int axis, uint8_t percentage) {
250
274
return (absinfo .maximum - absinfo .minimum ) * percentage / 100 ;
251
275
}
252
276
253
- typedef struct scroll_thread_params {
254
- uint8_t delta ;
255
- int code ;
256
- void (* callback )(input_event_array_t * );
257
- } scroll_thread_params_t ;
277
+ #define slowdown_scroll (velocity , thread_params ) \
278
+ while (velocity != 0) { \
279
+ struct timespec tim = { \
280
+ .tv_sec = 0, \
281
+ .tv_nsec = 5000000 \
282
+ };\
283
+ nanosleep(&tim, NULL); \
284
+ input_event_array_t *events = do_scroll(velocity * 5, thread_params->delta, thread_params->code); \
285
+ if (events) { \
286
+ thread_params->callback(events); \
287
+ } \
288
+ free(events); \
289
+ double new_velocity = SCROLL_SLOW_DOWN_FACTOR * 5 + fabs(velocity); \
290
+ if (new_velocity < 0) { \
291
+ new_velocity = 0; \
292
+ } \
293
+ if (velocity > 0) { \
294
+ velocity = new_velocity; \
295
+ } else { \
296
+ velocity = -new_velocity; \
297
+ } \
298
+ }
258
299
259
300
static void * scroll_thread_function (void * val ) {
260
- while (scroll .y_velocity != 0 ) {
261
- struct timespec tim = {
262
- .tv_sec = 0 ,
263
- .tv_nsec = 5000000
264
- };
265
- nanosleep (& tim , NULL );
266
- scroll_thread_params_t * params = ((scroll_thread_params_t * )val );
267
- input_event_array_t * events = do_scroll (scroll .y_velocity * 5 , params -> delta , REL_WHEEL );
268
- if (events ) {
269
- params -> callback (events );
270
- }
271
- free (events );
272
- double new_velocity = SCROLL_SLOW_DOWN_FACTOR * 5 + fabs (scroll .y_velocity );
273
- if (new_velocity < 0 ) {
274
- new_velocity = 0 ;
275
- }
276
- if (scroll .y_velocity > 0 ) {
277
- scroll .y_velocity = new_velocity ;
278
- } else {
279
- scroll .y_velocity = - new_velocity ;
280
- }
301
+ scroll_thread_params_t * params = ((scroll_thread_params_t * )val );
302
+ if (params -> code == REL_WHEEL ) {
303
+ slowdown_scroll (scroll .y_velocity , params );
304
+ } else if (params -> code == REL_HWHEEL ) {
305
+ slowdown_scroll (scroll .x_velocity , params );
281
306
}
282
307
return NULL ;
283
308
}
@@ -290,7 +315,7 @@ void process_events(int fd, configuration_t config, void (*callback)(input_event
290
315
thresholds .x = get_axix_threshold (fd , ABS_X , config .horz_threshold_percentage );
291
316
thresholds .y = get_axix_threshold (fd , ABS_Y , config .vert_threshold_percentage );
292
317
293
- pthread_t thread = NULL ;
318
+ pthread_t scroll_thread = NULL ;
294
319
295
320
if (thresholds .x < 0 || thresholds .y < 0 ) {
296
321
return ;
@@ -313,17 +338,24 @@ void process_events(int fd, configuration_t config, void (*callback)(input_event
313
338
case EV_KEY :
314
339
finger_count = process_key_event (ev [i ]);
315
340
if (finger_count > 0 ) {
341
+ if (scroll_thread ) {
342
+ pthread_cancel (scroll_thread );
343
+ }
316
344
init_gesture ();
317
345
} else if (scroll .x_velocity != 0 || scroll .y_velocity != 0 ) {
318
- if (thread ) {
319
- pthread_cancel (thread );
320
- }
321
346
scroll_thread_params_t params = {
322
- .delta = config .scroll .vert_delta ,
323
347
.callback = callback
324
348
};
325
- pthread_create (& thread , NULL , & scroll_thread_function , (void * ) & params );
326
-
349
+ if (fabs (scroll .x_velocity * config .scroll .horz_delta ) > fabs (scroll .y_velocity * config .scroll .vert_delta )) {
350
+ params .delta = config .scroll .horz_delta ;
351
+ params .code = REL_HWHEEL ;
352
+ scroll .y_velocity = 0 ;
353
+ } else {
354
+ params .delta = config .scroll .vert_delta ;
355
+ params .code = REL_WHEEL ;
356
+ scroll .x_velocity = 0 ;
357
+ }
358
+ pthread_create (& scroll_thread , NULL , & scroll_thread_function , (void * ) & params );
327
359
}
328
360
break ;
329
361
case EV_ABS :
0 commit comments