Skip to content

Commit cbf6dac

Browse files
committed
Add possibility to auto-detect the multi touch input device
1 parent 0a72111 commit cbf6dac

File tree

7 files changed

+122
-45
lines changed

7 files changed

+122
-45
lines changed

configure.ac

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,7 @@ AC_CHECK_HEADERS([linux/input.h linux/uinput.h], [], [AC_MSG_ERROR([The linux he
2020

2121
# Checks for typedefs, structures, and compiler characteristics.
2222
AC_CHECK_HEADER_STDBOOL
23-
AC_TYPE_INT32_T
2423
AC_TYPE_SIZE_T
25-
AC_TYPE_UINT32_T
26-
AC_TYPE_UINT8_T
2724

2825
# Checks for library functions.
2926
AC_FUNC_MALLOC

src/configuraion.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
char *directions[4] = { "up", "down", "left", "right" };
3535

3636
static void clean_config(configuration_t *config) {
37-
int32_t i, j, k;
37+
int i, j, k;
3838
for (i = 0; i < MAX_FINGERS; i++) {
3939
for (j = 0; j < DIRECTIONS_COUNT; j++) {
4040
for (k = 0; k < MAX_KEYS_PER_GESTURE; k++) {
@@ -47,7 +47,7 @@ static void clean_config(configuration_t *config) {
4747
static void fill_keys_array(int (*keys_array)[MAX_KEYS_PER_GESTURE], char *keys) {
4848
if (keys) {
4949
char *ptr = strtok(keys, "+");
50-
uint8_t i = 0;
50+
unsigned int i = 0;
5151
while (ptr) {
5252
if (i >= MAX_KEYS_PER_GESTURE) {
5353
fprintf(stderr, "error: for each gesture only %d keystrokes are allowed\n", MAX_KEYS_PER_GESTURE);
@@ -75,23 +75,22 @@ configuration_t read_config(const char *filename) {
7575
strcpy(result.touch_device_path, touch_device_path);
7676
}
7777
} else {
78-
errno = EINVAL;
79-
die("error: no touch device defined");
78+
result.touch_device_path = NULL;
8079
}
81-
result.retries = (uint8_t) iniparser_getint(ini, "general:retries", 2);
82-
result.retry_delay = (uint8_t) iniparser_getint(ini, "general:retrydelay", 5);
80+
result.retries = (unsigned int) iniparser_getint(ini, "general:retries", 2);
81+
result.retry_delay = (unsigned int) iniparser_getint(ini, "general:retrydelay", 5);
8382
result.scroll.vert = iniparser_getboolean(ini, "scroll:vertical", false);
8483
result.scroll.horz = iniparser_getboolean(ini, "scroll:horizontal", false);
85-
result.scroll.vert_delta = (int8_t) iniparser_getint(ini, "scroll:verticaldelta", 79);
86-
result.scroll.horz_delta = (int8_t) iniparser_getint(ini, "scroll:horizontaldelta", 30);
84+
result.scroll.vert_delta = (int) iniparser_getint(ini, "scroll:verticaldelta", 79);
85+
result.scroll.horz_delta = (int) iniparser_getint(ini, "scroll:horizontaldelta", 30);
8786
result.scroll.invert_vert = iniparser_getboolean(ini, "scroll:invertvertical", false);
8887
result.scroll.invert_horz = iniparser_getboolean(ini, "scroll:inverthorizontal", false);
8988
result.vert_threshold_percentage = iniparser_getint(ini, "thresholds:vertical", 15);
9089
result.horz_threshold_percentage = iniparser_getint(ini, "thresholds:horizontal", 15);
9190
result.zoom.enabled = iniparser_getboolean(ini, "zoom:enabled", false);
92-
result.zoom.delta = (uint8_t) iniparser_getint(ini, "zoom:delta", 200);
91+
result.zoom.delta = (unsigned int) iniparser_getint(ini, "zoom:delta", 200);
9392

94-
uint8_t i, j;
93+
unsigned int i, j;
9594
for (i = 0; i < MAX_FINGERS; i++) {
9695
for (j = 0; j < DIRECTIONS_COUNT; j++) {
9796
char ini_key[16];

src/configuraion.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,22 @@ typedef struct keys_array {
4141

4242
typedef struct configuration {
4343
char *touch_device_path;
44-
uint8_t retries;
45-
uint8_t retry_delay;
44+
unsigned int retries;
45+
unsigned int retry_delay;
4646
struct scroll_options {
4747
bool vert;
4848
bool horz;
49-
int8_t vert_delta;
50-
int8_t horz_delta;
49+
int vert_delta;
50+
int horz_delta;
5151
bool invert_vert;
5252
bool invert_horz;
5353
} scroll;
5454
struct zoom_options {
5555
bool enabled;
56-
uint8_t delta;
56+
unsigned int delta;
5757
} zoom;
58-
uint8_t vert_threshold_percentage;
59-
uint8_t horz_threshold_percentage;
58+
unsigned int vert_threshold_percentage;
59+
unsigned int horz_threshold_percentage;
6060
keys_array_t swipe_keys[MAX_FINGERS][DIRECTIONS_COUNT];
6161
} configuration_t;
6262

src/gesture_detection.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ typedef struct point {
4949
} point_t;
5050

5151
typedef struct mt_slots {
52-
uint8_t active;
52+
unsigned int active;
5353
point_t points[2];
5454
point_t last_points[2];
5555
} mt_slots_t;
@@ -67,7 +67,7 @@ typedef struct gesture_start {
6767
} gesture_start_t;
6868

6969
typedef struct scroll_thread_params {
70-
uint8_t delta;
70+
unsigned int delta;
7171
int code;
7272
bool invert;
7373
void (*callback)(input_event_array_t*);
@@ -77,7 +77,7 @@ typedef enum gesture { NO_GESTURE, SCROLL, ZOOM, SWIPE } gesture_t;
7777

7878
mt_slots_t mt_slots;
7979
gesture_start_t gesture_start;
80-
uint8_t finger_count;
80+
unsigned int finger_count;
8181
volatile scroll_t scroll;
8282
gesture_t current_gesture;
8383
double last_zoom_distance;
@@ -93,7 +93,7 @@ static int test_grab(int fd) {
9393
}
9494

9595
static double calculate_distance(point_t p1, point_t p2) {
96-
int32_t x_distance, y_distance;
96+
int x_distance, y_distance;
9797
x_distance = p1.x - p2.x;
9898
y_distance = p1.y - p2.y;
9999
return sqrt((x_distance * x_distance) + (y_distance * y_distance));
@@ -123,8 +123,8 @@ static void init_gesture() {
123123
/*
124124
* @return number of fingers on touch device
125125
*/
126-
static uint8_t process_key_event(struct input_event event) {
127-
uint8_t finger_count;
126+
static unsigned int process_key_event(struct input_event event) {
127+
unsigned int finger_count;
128128
if (event.value == 1 && !is_click) {
129129
switch (event.code) {
130130
case BTN_TOOL_FINGER:
@@ -166,7 +166,7 @@ static uint8_t process_key_event(struct input_event event) {
166166
* @return velocity in distance per milliseconds
167167
*/
168168
static double calcualte_velocity(struct input_event event1, struct input_event event2) {
169-
int32_t distance = event2.value - event1.value;
169+
int distance = event2.value - event1.value;
170170
double time_delta =
171171
event2.time.tv_sec * 1000 + event2.time.tv_usec / 1000 - event1.time.tv_sec * 1000 - event1.time.tv_usec / 1000;
172172
return distance / time_delta;
@@ -223,7 +223,7 @@ static void set_input_event(struct input_event *input_event, int type, int code,
223223
#define set_key_event(key_event, code, value) set_input_event(key_event, EV_KEY, code, value)
224224
#define set_rel_event(rel_event, code, value) set_input_event(rel_event, EV_REL, code, value)
225225

226-
static input_event_array_t *do_scroll(double distance, int32_t delta, int rel_code, bool invert) {
226+
static input_event_array_t *do_scroll(double distance, int delta, int rel_code, bool invert) {
227227
input_event_array_t *result = NULL;
228228
// increment the scroll width by the current moved distance
229229
scroll.width += distance * (invert ? -1 : 1);
@@ -239,7 +239,7 @@ static input_event_array_t *do_scroll(double distance, int32_t delta, int rel_co
239239
return result;
240240
}
241241

242-
static input_event_array_t *do_zoom(double distance, int32_t delta) {
242+
static input_event_array_t *do_zoom(double distance, int delta) {
243243
input_event_array_t *result = NULL;
244244
input_event_array_t *tmp = do_scroll(distance, delta, REL_WHEEL, false);
245245
if (tmp) {
@@ -320,7 +320,7 @@ static bool check_mt_slots() {
320320
return result;
321321
}
322322

323-
uint32_t syn_counter = 0;
323+
unsigned int syn_counter = 0;
324324

325325
static input_event_array_t *process_syn_event(struct input_event event,
326326
configuration_t config,
@@ -354,7 +354,7 @@ static input_event_array_t *process_syn_event(struct input_event event,
354354
}
355355
last_zoom_distance = finger_distance;
356356
} else {
357-
int32_t x_distance, y_distance;
357+
int x_distance, y_distance;
358358
x_distance = gesture_start.point.x - mt_slots.points[0].x;
359359
y_distance = gesture_start.point.y - mt_slots.points[0].y;
360360
if (fabs(x_distance) > fabs(y_distance)) {
@@ -388,7 +388,7 @@ static input_event_array_t *process_syn_event(struct input_event event,
388388
}
389389
}
390390
if (direction != NONE) {
391-
uint8_t i;
391+
unsigned int i;
392392
for (i = MAX_KEYS_PER_GESTURE; i > 0; i--) {
393393
int key = config.swipe_keys[FINGER_TO_INDEX(finger_count)][direction].keys[i - 1];
394394
if (key > 0) {
@@ -411,15 +411,15 @@ static input_event_array_t *process_syn_event(struct input_event event,
411411
return result ? result : new_input_event_array(0);
412412
}
413413

414-
static int32_t get_axix_threshold(int fd, int axis, uint8_t percentage) {
414+
static int get_axix_threshold(int fd, int axis, unsigned int percentage) {
415415
struct input_absinfo absinfo;
416416
if (ioctl(fd, EVIOCGABS(axis), &absinfo) < 0) {
417417
return -1;
418418
}
419419
return (absinfo.maximum - absinfo.minimum) * percentage / 100;
420420
}
421421

422-
static int32_t get_axix_offset(int fd, int axis) {
422+
static int get_axix_offset(int fd, int axis) {
423423
struct input_absinfo absinfo;
424424
if (ioctl(fd, EVIOCGABS(axis), &absinfo) < 0) {
425425
return -1;
@@ -472,7 +472,7 @@ void process_events(int fd, configuration_t config, void (*callback)(input_event
472472
offsets.x = get_axix_offset(fd, ABS_X);
473473
offsets.y = get_axix_offset(fd, ABS_Y);
474474

475-
pthread_t scroll_thread = NULL;
475+
pthread_t scroll_thread = (pthread_t) NULL;
476476

477477
if (thresholds.x < 0 || thresholds.y < 0) {
478478
return;

src/gestures_device.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ int destroy_uinput(int fd) {
8181
}
8282

8383
void send_events(int fd, input_event_array_t *input_events) {
84-
uint8_t i;
84+
unsigned int i;
8585
if (input_events->length > 0) {
8686
for (i = 0; i < input_events->length; i++) {
8787
if (write(fd, &input_events->data[i], sizeof(struct input_event)) < 0) {

src/keys.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ struct key keys[KEYS_COUNT] = {
446446
};
447447

448448
int get_key_code(char *key_name) {
449-
uint32_t low, high, mid;
449+
unsigned int low, high, mid;
450450
low = 0;
451451
high = KEYS_COUNT - 1;
452452
while (low <= high) {

src/main.c

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,34 @@
2828
#include <unistd.h>
2929
#include <fcntl.h>
3030
#include <errno.h>
31+
#include <dirent.h>
3132

3233
#include <linux/input.h>
3334

3435
#include "common.h"
3536
#include "gestures_device.h"
3637
#include "gesture_detection.h"
3738

39+
40+
#define DEV_INPUT_EVENT "/dev/input"
41+
#define EVENT_DEV_NAME "event"
42+
43+
#define BITS_PER_LONG (sizeof(long) * 8)
44+
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
45+
#define OFF(x) ((x)%BITS_PER_LONG)
46+
#define BIT(x) (1UL<<OFF(x))
47+
#define LONG(x) ((x)/BITS_PER_LONG)
48+
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
49+
3850
int uinput_fd, touch_device_fd;
3951

4052
static void execute_events(input_event_array_t *input_events) {
4153
send_events(uinput_fd, input_events);
4254
}
4355

4456
static int_array_t *get_keys_array(configuration_t config) {
45-
uint8_t i, j, k;
46-
uint8_t keys_count = 0;
57+
unsigned int i, j, k;
58+
unsigned int keys_count = 0;
4759
int_array_t *keys = new_int_array(MAX_FINGERS * DIRECTIONS_COUNT * MAX_KEYS_PER_GESTURE);
4860
for (i = 0; i < MAX_FINGERS; i++) {
4961
for (j = 0; j < DIRECTIONS_COUNT; j++) {
@@ -59,27 +71,96 @@ static int_array_t *get_keys_array(configuration_t config) {
5971
return keys;
6072
}
6173

74+
static int is_event_device(const struct dirent *dir) {
75+
return strncmp(EVENT_DEV_NAME, dir->d_name, 5) == 0;
76+
}
77+
78+
static bool check_device(char *device_name) {
79+
char filename[64];
80+
int fd = -1;
81+
char name[256] = "???";
82+
unsigned long bit[NBITS(KEY_MAX)];
83+
84+
snprintf(filename, sizeof(filename), "%s/%s", DEV_INPUT_EVENT, device_name);
85+
fd = open(filename, O_RDONLY);
86+
if (fd < 0) {
87+
return false;
88+
}
89+
90+
memset(bit, 0, sizeof(bit));
91+
ioctl(fd, EVIOCGBIT(EV_KEY, KEY_MAX), bit);
92+
93+
ioctl(fd, EVIOCGNAME(sizeof(name)), name);
94+
close(fd);
95+
96+
if (test_bit(BTN_TOOL_QUINTTAP, bit)) {
97+
printf("Found multi-touch input device: %s\n", name);
98+
return true;
99+
}
100+
101+
return false;
102+
}
103+
104+
static char* scan_devices(void) {
105+
struct dirent **namelist;
106+
107+
int devnum = -1;
108+
int ndev = scandir(DEV_INPUT_EVENT, &namelist, is_event_device, alphasort);
109+
if (ndev <= 0) {
110+
return NULL;
111+
}
112+
113+
for (int i = 0; i < ndev; i++) {
114+
if (devnum == -1 && check_device(namelist[i]->d_name)) {
115+
sscanf(namelist[i]->d_name, "event%i", &devnum);
116+
}
117+
free(namelist[i]);
118+
}
119+
120+
if (devnum == -1) {
121+
return NULL;
122+
}
123+
124+
char *filename = (char*) malloc(64 * sizeof(char));
125+
sprintf(filename, "%s/%s%i", DEV_INPUT_EVENT, EVENT_DEV_NAME, devnum);
126+
return filename;
127+
}
128+
129+
static int open_touch_device(configuration_t config, int retry) {
130+
if (config.touch_device_path) {
131+
printf("Looking for input device: %s (Attempt %i/%i)\n", config.touch_device_path, retry + 1, config.retries + 1);
132+
return open(config.touch_device_path, O_RDONLY);
133+
} else {
134+
printf("Looking for multi-touch input device: (Attempt %i/%i)\n", retry + 1, config.retries + 1);
135+
char *filename = scan_devices();
136+
if (filename) {
137+
return open(filename, O_RDONLY);
138+
} else {
139+
return -1;
140+
}
141+
}
142+
}
143+
62144
int main(int argc, char *argv[]) {
63145
if (argc > 1) {
64146
configuration_t config = read_config(argv[1]);
65147
int_array_t *keys = get_keys_array(config);
66148
uinput_fd = init_uinput(keys);
67149
free(keys);
68150

69-
int8_t retries = 0;
70-
while (retries < config.retries + 1) {
71-
printf("Looking for input device: %s (Attempt %i/%i)\n", config.touch_device_path, retries + 1, config.retries + 1);
72-
touch_device_fd = open(config.touch_device_path, O_RDONLY);
151+
int retry = 0;
152+
while (retry < config.retries + 1) {
153+
touch_device_fd = open_touch_device(config, retry);
73154
if (touch_device_fd > 0) {
74155
break;
75156
}
76157
sleep(config.retry_delay);
77-
retries++;
158+
retry++;
78159
}
79160
if (touch_device_fd < 0) {
80161
die("Failed to open input device");
81162
}
82-
printf("Opened input device: %s\n", config.touch_device_path);
163+
printf("Opened input device\n");
83164
process_events(touch_device_fd, config, &execute_events);
84165

85166
close(touch_device_fd);

0 commit comments

Comments
 (0)