Skip to content

Commit 48084fe

Browse files
author
Robin Müller
committed
Added funtionality for scrolling
- added new configuration parameters for horz and vert delta - send EV_REL events if corresponding delta values are exceeded - added functionality to calculate the scroll velocity to implement a smooth scroll stop later
1 parent c3f2d2d commit 48084fe

File tree

3 files changed

+88
-21
lines changed

3 files changed

+88
-21
lines changed

src/configuraion.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,10 @@ configuration_t read_config(const char *filename) {
7878
errno = EINVAL;
7979
die("error: no touch device defined");
8080
}
81-
result.vert_scroll = iniparser_getboolean(ini, "scroll:vertical", false);
82-
result.horz_scroll = iniparser_getboolean(ini, "scroll:horizontal", false);
81+
result.scroll.vert = iniparser_getboolean(ini, "scroll:vertical", false);
82+
result.scroll.horz = iniparser_getboolean(ini, "scroll:horizontal", false);
83+
result.scroll.vert_delta = (uint8_t) iniparser_getint(ini, "scroll:verticaldelta", 79);
84+
result.scroll.horz_delta = (uint8_t) iniparser_getint(ini, "scroll:horizontaldelta", 30);
8385
result.vert_threshold_percentage = iniparser_getint(ini, "thresholds:vertical", 15);
8486
result.horz_threshold_percentage = iniparser_getint(ini, "thresholds:horizontal", 15);
8587

src/configuraion.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,12 @@ typedef struct keys_array {
4141

4242
typedef struct configuration {
4343
char *touch_device_path;
44-
bool vert_scroll;
45-
bool horz_scroll;
44+
struct scroll_options {
45+
bool vert;
46+
bool horz;
47+
uint8_t vert_delta;
48+
uint8_t horz_delta;
49+
} scroll;
4650
uint8_t vert_threshold_percentage;
4751
uint8_t horz_threshold_percentage;
4852
keys_array_t swipe_keys[MAX_FINGERS][DIRECTIONS_COUNT];

src/gesture_detection.c

Lines changed: 78 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333

3434
#include "gesture_detection.h"
3535

36+
// FIXME use 2 for SCROLL_FINGER_COUNT as soon as possible
37+
#define SCROLL_FINGER_COUNT 4
38+
39+
3640
typedef struct point {
3741
int x;
3842
int y;
@@ -43,6 +47,15 @@ typedef struct mt_slots {
4347
point_t points[2];
4448
} mt_slots_t;
4549

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+
4659
typedef struct gesture_start {
4760
point_t point;
4861
uint32_t distance;
@@ -51,6 +64,7 @@ typedef struct gesture_start {
5164
mt_slots_t mt_slots;
5265
gesture_start_t gesture_start;
5366
uint8_t finger_count;
67+
scroll_t scroll;
5468

5569
static int test_grab(int fd) {
5670
int rc;
@@ -70,9 +84,14 @@ static void init_gesture() {
7084
x_distance = mt_slots.points[0].x - mt_slots.points[1].x;
7185
y_distance = mt_slots.points[0].y - mt_slots.points[1].y;
7286
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];
7389
}
7490
}
7591

92+
/*
93+
* @return number of fingers on touch device
94+
*/
7695
static uint8_t process_key_event(struct input_event event) {
7796
uint8_t finger_count;
7897
if (event.value == 1) {
@@ -101,32 +120,66 @@ static uint8_t process_key_event(struct input_event event) {
101120
return finger_count;
102121
}
103122

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+
104133
static void process_abs_event(struct input_event event) {
105134
if (event.code == ABS_MT_SLOT) {
106135
mt_slots.active = event.value;
107136
} else if (mt_slots.active < 2) {
108137
switch (event.code) {
109138
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+
}
110146
mt_slots.points[mt_slots.active].x = event.value;
111147
break;
112148
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+
}
113156
mt_slots.points[mt_slots.active].y = event.value;
114157
break;
115158
}
116159
}
117160
}
118161

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;
123167
}
124168

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;
130183
}
131184

132185
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,
140193
x_distance = gesture_start.point.x - mt_slots.points[0].x;
141194
y_distance = gesture_start.point.y - mt_slots.points[0].y;
142195
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);
147204
}
148205
} 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);
153214
}
154215
}
155216
if (direction != NONE) {

0 commit comments

Comments
 (0)