Skip to content

Commit 99f4ea7

Browse files
author
Robin Müller
committed
Cleaned up code
- moved gesture detection to separate module - splited gesture detection into multiple functions
1 parent c669faa commit 99f4ea7

File tree

3 files changed

+164
-120
lines changed

3 files changed

+164
-120
lines changed

src/gesture_detection.c

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#include <stdint.h>
2+
#include <stdio.h>
3+
#include <unistd.h>
4+
#include <math.h>
5+
6+
#include <linux/input.h>
7+
8+
#include "gesture_detection.h"
9+
10+
struct point_t {
11+
int x;
12+
int y;
13+
};
14+
15+
struct mt_slots_t {
16+
uint8_t active;
17+
struct point_t points[2];
18+
};
19+
20+
struct gesture_start_t {
21+
struct point_t point;
22+
uint32_t distance;
23+
};
24+
25+
static int test_grab(int fd) {
26+
int rc;
27+
rc = ioctl(fd, EVIOCGRAB, (void*)1);
28+
if (!rc) {
29+
ioctl(fd, EVIOCGRAB, (void*)0);
30+
}
31+
return rc;
32+
}
33+
34+
static void init_gesture(struct point_t slot_points[2],
35+
uint8_t finger_count,
36+
struct gesture_start_t *gesture_start) {
37+
int32_t x_distance, y_distance;
38+
gesture_start->point.x = slot_points[0].x;
39+
gesture_start->point.y = slot_points[0].y;
40+
41+
if (finger_count == 2) {
42+
x_distance = slot_points[0].x - slot_points[1].x;
43+
y_distance = slot_points[0].y - slot_points[1].y;
44+
gesture_start->distance = (uint32_t) sqrt((x_distance * x_distance) + (y_distance * y_distance));
45+
}
46+
}
47+
48+
static uint8_t process_key_event(struct input_event event) {
49+
uint8_t finger_count;
50+
if (event.value == 1) {
51+
switch (event.code) {
52+
case BTN_TOOL_FINGER:
53+
finger_count = 1;
54+
break;
55+
case BTN_TOOL_DOUBLETAP:
56+
finger_count = 2;
57+
break;
58+
case BTN_TOOL_TRIPLETAP:
59+
finger_count = 3;
60+
break;
61+
case BTN_TOOL_QUADTAP:
62+
finger_count = 4;
63+
break;
64+
case BTN_TOOL_QUINTTAP:
65+
finger_count = 5;
66+
break;
67+
default:
68+
finger_count = 0;
69+
}
70+
} else if (event.value == 0 && event.code == BTN_TOOL_FINGER) {
71+
finger_count = 0;
72+
}
73+
return finger_count;
74+
}
75+
76+
static void process_abs_event(struct input_event event,
77+
struct mt_slots_t *mt_slots) {
78+
if (event.code == ABS_MT_SLOT) {
79+
mt_slots->active = event.value;
80+
} else if (mt_slots->active < 2) {
81+
switch (event.code) {
82+
case ABS_MT_POSITION_X:
83+
mt_slots->points[mt_slots->active].x = event.value;
84+
break;
85+
case ABS_MT_POSITION_Y:
86+
mt_slots->points[mt_slots->active].y = event.value;
87+
break;
88+
}
89+
}
90+
}
91+
92+
static void process_syn_event(struct input_event event,
93+
struct gesture_start_t gesture_start,
94+
struct point_t slot_points[2],
95+
uint8_t *finger_count) {
96+
if (*finger_count > 0 && event.code == SYN_REPORT) {
97+
int32_t x_distance, y_distance;
98+
x_distance = gesture_start.point.x - slot_points[0].x;
99+
y_distance = gesture_start.point.y - slot_points[0].y;
100+
if (fabs(x_distance) > fabs(y_distance)) {
101+
if (x_distance > 500) {
102+
printf("%d fingers left\n", *finger_count);
103+
*finger_count = 0;
104+
} else if (x_distance < -500) {
105+
printf("%d fingers right\n", *finger_count);
106+
*finger_count = 0;
107+
}
108+
} else {
109+
if (y_distance > 300) {
110+
printf("%d fingers up\n", *finger_count);
111+
*finger_count = 0;
112+
} else if (y_distance < -300) {
113+
printf("%d fingers down\n", *finger_count);
114+
*finger_count = 0;
115+
}
116+
}
117+
}
118+
}
119+
120+
void print_events(int fd) {
121+
struct input_event ev[64];
122+
int i, rd;
123+
uint8_t finger_count;
124+
struct gesture_start_t gesture_start;
125+
struct mt_slots_t mt_slots;
126+
127+
if (test_grab(fd) < 0) {
128+
return;
129+
}
130+
131+
while (1) {
132+
rd = read(fd, ev, sizeof(struct input_event) * 64);
133+
134+
if (rd < (int) sizeof(struct input_event)) {
135+
printf("expected %d bytes, got %d\n", (int) sizeof(struct input_event), rd);
136+
return;
137+
}
138+
139+
for (i = 0; i < rd / sizeof(struct input_event); i++) {
140+
switch(ev[i].type) {
141+
case EV_KEY:
142+
finger_count = process_key_event(ev[i]);
143+
if (finger_count > 0) {
144+
init_gesture(mt_slots.points, finger_count, &gesture_start);
145+
}
146+
break;
147+
case EV_ABS:
148+
process_abs_event(ev[i], &mt_slots);
149+
break;
150+
case EV_SYN:
151+
process_syn_event(ev[i], gesture_start, mt_slots.points, &finger_count);
152+
break;
153+
}
154+
}
155+
}
156+
}

src/gesture_detection.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef GESTURE_DETECTION_H_
2+
#define GESTURE_DETECTION_H_
3+
4+
void print_events(int fd);
5+
6+
#endif // GESTURE_DETECTION_H_

src/main.c

Lines changed: 2 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -4,130 +4,14 @@
44
#include <unistd.h>
55
#include <fcntl.h>
66
#include <errno.h>
7-
#include <stdlib.h>
8-
#include <stdint.h>
9-
107

118
#include <linux/input.h>
129

1310
#include "common.h"
1411
#include "gestures_device.h"
12+
#include "gesture_detection.h"
1513

1614

17-
int finger_count = 0;
18-
19-
typedef struct t_point {
20-
int x;
21-
int y;
22-
} point;
23-
24-
point start_point;
25-
26-
int active_slot;
27-
28-
static int test_grab(int fd) {
29-
int rc;
30-
rc = ioctl(fd, EVIOCGRAB, (void*)1);
31-
if (!rc) {
32-
ioctl(fd, EVIOCGRAB, (void*)0);
33-
}
34-
return rc;
35-
}
36-
37-
void set_start_point(int fd) {
38-
struct input_mt_request_layout {
39-
uint32_t code;
40-
int32_t values[2];
41-
} data;
42-
data.code = ABS_MT_POSITION_X;
43-
if (ioctl(fd, EVIOCGMTSLOTS(sizeof(data)), &data) < 0) {
44-
return;
45-
}
46-
start_point.x = data.values[0];
47-
data.code = ABS_MT_POSITION_Y;
48-
if (ioctl(fd, EVIOCGMTSLOTS(sizeof(data)), &data) < 0) {
49-
return;
50-
}
51-
start_point.y = data.values[0];
52-
}
53-
54-
static void print_events(int fd) {
55-
struct input_event ev[64];
56-
int i, rd;
57-
58-
while (1) {
59-
rd = read(fd, ev, sizeof(struct input_event) * 64);
60-
61-
if (rd < (int) sizeof(struct input_event)) {
62-
printf("expected %d bytes, got %d\n", (int) sizeof(struct input_event), rd);
63-
return;
64-
}
65-
66-
for (i = 0; i < rd / sizeof(struct input_event); i++) {
67-
if (ev[i].type == EV_KEY) {
68-
if (ev[i].value == 1) {
69-
switch (ev[i].code) {
70-
case BTN_TOOL_FINGER:
71-
finger_count = 1;
72-
set_start_point(fd);
73-
break;
74-
case BTN_TOOL_DOUBLETAP:
75-
finger_count = 2;
76-
set_start_point(fd);
77-
break;
78-
case BTN_TOOL_TRIPLETAP:
79-
finger_count = 3;
80-
set_start_point(fd);
81-
break;
82-
case BTN_TOOL_QUADTAP:
83-
finger_count = 4;
84-
set_start_point(fd);
85-
break;
86-
case BTN_TOOL_QUINTTAP:
87-
finger_count = 5;
88-
set_start_point(fd);
89-
break;
90-
default:
91-
finger_count = 0;
92-
}
93-
} else if (ev[i].value == 0 && BTN_TOOL_FINGER) {
94-
finger_count = 0;
95-
}
96-
}
97-
98-
if (finger_count > 0 && ev[i].type == EV_ABS) {
99-
if (ev[i].code == ABS_MT_SLOT) {
100-
active_slot = ev[i].value;
101-
} else if (active_slot == 0) {
102-
int difference;
103-
switch (ev[i].code) {
104-
case ABS_MT_POSITION_X:
105-
difference = start_point.x - ev[i].value;
106-
if (difference > 500) {
107-
printf("%d fingers left\n", finger_count);
108-
finger_count = 0;
109-
} else if (difference < -500) {
110-
printf("%d fingers right\n", finger_count);
111-
finger_count = 0;
112-
}
113-
break;
114-
case ABS_MT_POSITION_Y:
115-
difference = start_point.y - ev[i].value;
116-
if (difference > 300) {
117-
printf("%d fingers up\n", finger_count);
118-
finger_count = 0;
119-
} else if (difference < -300) {
120-
printf("%d fingers down\n", finger_count);
121-
finger_count = 0;
122-
}
123-
break;
124-
}
125-
}
126-
}
127-
}
128-
}
129-
}
130-
13115
int main(int argc, char *argv[]) {
13216
int_array *keys = new_int_array(1);
13317
keys->data[0] = KEY_D;
@@ -143,9 +27,7 @@ int main(int argc, char *argv[]) {
14327
if (fd < 0) {
14428
die("error: open");
14529
}
146-
if (!test_grab(fd)) {
147-
print_events(fd);
148-
}
30+
print_events(fd);
14931
close(fd);
15032
}
15133
return 0;

0 commit comments

Comments
 (0)