1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
/* See LICENSE file for copyright and license details. */
#include "common.h"
int
libgamepad_open_device(struct libgamepad_device *devicep, int dirfd, const char *path, int mode)
{
int err;
unsigned int i;
uint16_t n;
struct input_id id;
devicep->fd = dirfd;
devicep->internals = NULL;
devicep->buttons = NULL;
devicep->absolute_axes = NULL;
devicep->relative_axes = NULL;
memset(devicep->force_feedback_support, 0, sizeof(devicep->force_feedback_support));
devicep->internals = calloc(1, sizeof(*devicep->internals));
if (!devicep->internals)
return -1;
if (path && *path) {
devicep->fd = openat(dirfd, path, mode);
if (devicep->fd < 0) {
libgamepad_close_device(devicep);
return -1;
}
devicep->internals->close_fd = 1;
}
if (ioctl(devicep->fd, EVIOCGID, &id)) {
libgamepad_close_device(devicep);
return -1;
}
err = libevdev_new_from_fd(devicep->fd, &devicep->internals->dev);
if (err < 0) {
libgamepad_close_device(devicep);
errno = -err;
return -1;
}
devicep->name = libevdev_get_name(devicep->internals->dev);
devicep->unique_id = libevdev_get_uniq(devicep->internals->dev);
devicep->physical_location = libevdev_get_phys(devicep->internals->dev);
devicep->bus_type = (unsigned int)id.bustype;
devicep->vendor = (unsigned int)id.vendor;
devicep->product = (unsigned int)id.product;
devicep->version = (unsigned int)id.version;
devicep->nbuttons = 0;
for (i = 0; i < KEY_CNT; i++) {
devicep->button_map[i] = -1;
if (libevdev_has_event_code(devicep->internals->dev, EV_KEY, i))
devicep->button_map[i] = (int16_t)devicep->nbuttons++;
}
devicep->nabsolute_axes = 0;
for (i = 0; i < ABS_CNT; i++) {
devicep->absolute_axis_map[i] = -1;
if (libevdev_has_event_code(devicep->internals->dev, EV_ABS, i))
devicep->absolute_axis_map[i] = (int16_t)devicep->nabsolute_axes++;
}
devicep->nrelative_axes = 0;
for (i = 0; i < REL_CNT; i++) {
devicep->relative_axis_map[i] = -1;
if (libevdev_has_event_code(devicep->internals->dev, EV_REL, i))
devicep->relative_axis_map[i] = (int16_t)devicep->nrelative_axes++;
}
for (i = 0; i < FF_CNT; i++)
if (libevdev_has_event_code(devicep->internals->dev, EV_FF, i))
devicep->force_feedback_support[i / 8] |= (uint8_t)(1 << (i & 7));
if (devicep->nbuttons) {
devicep->buttons = calloc(devicep->nbuttons, sizeof(*devicep->buttons));
if (!devicep->buttons)
goto fail;
for (i = 0, n = 0; i < KEY_CNT; i++)
if (devicep->button_map[i] >= 0)
devicep->buttons[n++] = (uint16_t)i;
}
if (devicep->nabsolute_axes) {
devicep->absolute_axes = calloc(devicep->nabsolute_axes, sizeof(*devicep->absolute_axes));
if (!devicep->absolute_axes)
goto fail;
for (i = 0, n = 0; i < ABS_CNT; i++)
if (devicep->absolute_axis_map[i] >= 0)
devicep->absolute_axes[n++] = (uint16_t)i;
}
if (devicep->nrelative_axes) {
devicep->relative_axes = calloc(devicep->nrelative_axes, sizeof(*devicep->relative_axes));
if (!devicep->relative_axes)
goto fail;
for (i = 0, n = 0; i < REL_CNT; i++)
if (devicep->relative_axis_map[i] >= 0)
devicep->relative_axes[n++] = (uint16_t)i;
}
return 0;
fail:
libgamepad_close_device(devicep);
return -1;
}
|