38
38
#define SCROLL_FINGER_COUNT 2
39
39
#define SCROLL_SLOW_DOWN_FACTOR -0.006
40
40
41
+ #define PI 3.14159265358979323846264338327
42
+ #define PI_1_2 PI / 2
43
+
44
+
41
45
typedef struct point {
42
46
int x ;
43
47
int y ;
@@ -59,7 +63,6 @@ typedef struct scroll {
59
63
60
64
typedef struct gesture_start {
61
65
point_t point ;
62
- uint32_t distance ;
63
66
} gesture_start_t ;
64
67
65
68
typedef struct scroll_thread_params {
@@ -75,6 +78,7 @@ gesture_start_t gesture_start;
75
78
uint8_t finger_count ;
76
79
volatile scroll_t scroll ;
77
80
gesture_t current_gesture ;
81
+ double last_zoom_distance ;
78
82
79
83
static int test_grab (int fd ) {
80
84
int rc ;
@@ -85,22 +89,22 @@ static int test_grab(int fd) {
85
89
return rc ;
86
90
}
87
91
88
- static uint8_t calculate_distance (point_t p1 , point_t p2 ) {
92
+ static double calculate_distance (point_t p1 , point_t p2 ) {
89
93
int32_t x_distance , y_distance ;
90
94
x_distance = p1 .x - p2 .x ;
91
95
y_distance = p1 .y - p2 .y ;
92
- return ( uint32_t ) sqrt ((x_distance * x_distance ) + (y_distance * y_distance ));
96
+ return sqrt ((x_distance * x_distance ) + (y_distance * y_distance ));
93
97
}
94
98
95
99
static void init_gesture () {
96
100
gesture_start .point = mt_slots .points [0 ];
101
+ current_gesture = NO_GESTURE ;
97
102
98
103
if (finger_count == SCROLL_FINGER_COUNT ) {
99
- gesture_start . distance = calculate_distance (mt_slots .points [0 ], mt_slots .points [1 ]);
104
+ last_zoom_distance = calculate_distance (mt_slots .points [0 ], mt_slots .points [1 ]);
100
105
scroll .width = 0 ;
101
106
scroll .x_velocity = 0 ;
102
107
scroll .y_velocity = 0 ;
103
- current_gesture = NO_GESTURE ;
104
108
}
105
109
}
106
110
@@ -212,61 +216,104 @@ static input_event_array_t *do_scroll(double distance, int32_t delta, int rel_co
212
216
return result ;
213
217
}
214
218
215
- /*
216
- * @return a vector that can only have the following values for x and y: -1, 0, 1
217
- */
218
- static point_t create_direction_vector (point_t p1 , point_t p2 ) {
219
- point_t result ;
220
- result .x = p1 .x - p2 .x ;
221
- result .y = p1 .y - p2 .y ;
222
- if (result .x != 0 ) {
223
- result .x /= fabs (result .x );
224
- }
225
- if (result .y != 0 ) {
226
- result .y /= fabs (result .y );
219
+ static input_event_array_t * do_zoom (double distance , int32_t delta ) {
220
+ input_event_array_t * result = NULL ;
221
+ input_event_array_t * tmp = do_scroll (distance , delta , REL_WHEEL );
222
+ if (tmp ) {
223
+ result = new_input_event_array (6 );
224
+ memset (& result -> data [0 ], 0 , sizeof (struct input_event ));
225
+ // press CTRL
226
+ set_key_event (& result -> data [0 ], KEY_LEFTCTRL , 1 );
227
+ set_syn_event (& result -> data [1 ]);
228
+ // copy the rel_event retrieve via do_scroll
229
+ result -> data [2 ] = tmp -> data [0 ];
230
+ set_syn_event (& result -> data [3 ]);
231
+ // release CTRL
232
+ set_key_event (& result -> data [4 ], KEY_LEFTCTRL , 0 );
233
+ set_syn_event (& result -> data [5 ]);
234
+ free (tmp );
227
235
}
228
236
return result ;
229
237
}
230
238
231
- #define determine_gesture (scroll_enabled , v1 , v2 ) \
239
+ static point_t create_vector (point_t p1 , point_t p2 ) {
240
+ point_t result = {
241
+ .x = p1 .x - p2 .x ,
242
+ .y = p1 .y - p2 .y
243
+ };
244
+ return result ;
245
+ }
246
+
247
+ #define determine_gesture (scroll_enabled , vector_direction_difference ) \
232
248
/* if scrolling is enable, the finger_count matches SCROLL_FINGER_COUNT and\
233
249
the direction of the direction vectors for both fingers is equal the current_gesture\
234
250
will be SCROLL*/ \
235
- if (scroll_enabled && finger_count == SCROLL_FINGER_COUNT && v1 != 0 && v1 == v2 ) { \
251
+ if (scroll_enabled && finger_count == SCROLL_FINGER_COUNT && vector_direction_difference < PI_1_2 ) { \
236
252
current_gesture = SCROLL; \
237
253
/* if no scrolling and zooming is enabled or the finger_count does not match\
238
254
SCROLL_FINGER_COUNT the current_gesture will be SWIPE*/ \
239
255
} else if (!scroll_enabled || finger_count != SCROLL_FINGER_COUNT ) { \
240
256
current_gesture = SWIPE ; \
241
257
}
242
258
259
+ static double get_vector_direction (point_t v ) {
260
+ if (v .x == 0 ) {
261
+ if (v .y >= 0 ) {
262
+ return 0 ;
263
+ } else {
264
+ return PI ;
265
+ }
266
+ } else if (v .y == 0 ) {
267
+ if (v .x >= 0 ) {
268
+ return PI / 2 ;
269
+ } else {
270
+ return 3 * PI / 2 ;
271
+ }
272
+ } else if (v .x > 0 ) {
273
+ if (v .y > 0 ) {
274
+ return atan (v .x / v .y );
275
+ } else {
276
+ return PI / 2 + atan (- v .y / v .x );
277
+ }
278
+ } else {
279
+ if (v .y < 0 ) {
280
+ return PI + atan (v .x / v .y );
281
+ } else {
282
+ return 3 * PI / 2 + atan (v .y / - v .x );
283
+ }
284
+ }
285
+ }
286
+
243
287
static input_event_array_t * process_syn_event (struct input_event event ,
244
288
configuration_t config ,
245
289
point_t thresholds ) {
246
290
input_event_array_t * result = NULL ;
247
291
if (finger_count > 0 && event .code == SYN_REPORT ) {
248
292
direction_t direction = NONE ;
249
- point_t v1 ;
250
- point_t v2 ;
293
+ double vector_direction_difference ;
251
294
if (current_gesture == NO_GESTURE ) {
252
- v1 = create_direction_vector (mt_slots .last_points [0 ], mt_slots .points [0 ]);
253
- v2 = create_direction_vector (mt_slots .last_points [1 ], mt_slots .points [1 ]);
295
+ double v1_direction = get_vector_direction (create_vector (mt_slots .last_points [0 ], mt_slots .points [0 ]));
296
+ double v2_direction = get_vector_direction (create_vector (mt_slots .last_points [1 ], mt_slots .points [1 ]));
297
+ vector_direction_difference = fabs (v1_direction - v2_direction );
254
298
// if zooming is enable, the finger_count matches SCROLL_FINGER_COUNT and the direction
255
299
// vectors for both fingers are opposed to each other the current_gesture will be ZOOM
256
- if (config .zoom .enabled && finger_count == SCROLL_FINGER_COUNT && ( v1 . x != v2 . x || v1 . y != v2 . y ) ) {
300
+ if (config .zoom .enabled && finger_count == SCROLL_FINGER_COUNT && vector_direction_difference > PI_1_2 ) {
257
301
current_gesture = ZOOM ;
258
302
}
259
303
}
260
304
261
305
if (current_gesture == ZOOM ) {
262
- printf ("zoom\n" );
306
+ double finger_distance = calculate_distance (mt_slots .points [0 ], mt_slots .points [1 ]);
307
+ // TODO make zoom delta configurable
308
+ result = do_zoom (finger_distance - last_zoom_distance , 200 );
309
+ last_zoom_distance = finger_distance ;
263
310
} else {
264
311
int32_t x_distance , y_distance ;
265
312
x_distance = gesture_start .point .x - mt_slots .points [0 ].x ;
266
313
y_distance = gesture_start .point .y - mt_slots .points [0 ].y ;
267
314
if (fabs (x_distance ) > fabs (y_distance )) {
268
315
if (current_gesture == NO_GESTURE ) {
269
- determine_gesture (config .scroll .horz , v1 . x , v2 . x );
316
+ determine_gesture (config .scroll .horz , vector_direction_difference );
270
317
}
271
318
272
319
if (current_gesture == SWIPE ) {
@@ -280,7 +327,7 @@ static input_event_array_t *process_syn_event(struct input_event event,
280
327
}
281
328
} else {
282
329
if (current_gesture == NO_GESTURE ) {
283
- determine_gesture (config .scroll .vert , v1 . y , v2 . y );
330
+ determine_gesture (config .scroll .vert , vector_direction_difference );
284
331
}
285
332
286
333
if (current_gesture == SWIPE ) {
@@ -397,7 +444,7 @@ void process_events(int fd, configuration_t config, void (*callback)(input_event
397
444
}
398
445
init_gesture ();
399
446
syn_event_skip_counter = 0 ;
400
- } else if (scroll .x_velocity != 0 || scroll .y_velocity != 0 ) {
447
+ } else if (current_gesture == SCROLL && ( scroll .x_velocity != 0 || scroll .y_velocity != 0 ) ) {
401
448
scroll_thread_params_t params = {
402
449
.callback = callback
403
450
};
0 commit comments