evdev-binary 1.9.3__cp314-cp314-musllinux_1_2_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- evdev/__init__.py +39 -0
- evdev/_ecodes.cpython-314-x86_64-linux-musl.so +0 -0
- evdev/_input.cpython-314-x86_64-linux-musl.so +0 -0
- evdev/_uinput.cpython-314-x86_64-linux-musl.so +0 -0
- evdev/device.py +440 -0
- evdev/ecodes.py +3885 -0
- evdev/ecodes_runtime.py +111 -0
- evdev/eventio.py +152 -0
- evdev/eventio_async.py +106 -0
- evdev/events.py +192 -0
- evdev/evtest.py +181 -0
- evdev/ff.py +198 -0
- evdev/genecodes_c.py +147 -0
- evdev/genecodes_py.py +54 -0
- evdev/input.c +580 -0
- evdev/py.typed +0 -0
- evdev/uinput.c +417 -0
- evdev/uinput.py +375 -0
- evdev/util.py +146 -0
- evdev_binary-1.9.3.dist-info/METADATA +48 -0
- evdev_binary-1.9.3.dist-info/RECORD +24 -0
- evdev_binary-1.9.3.dist-info/WHEEL +5 -0
- evdev_binary-1.9.3.dist-info/licenses/LICENSE +29 -0
- evdev_binary-1.9.3.dist-info/top_level.txt +1 -0
evdev/uinput.c
ADDED
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
#include <Python.h>
|
|
2
|
+
|
|
3
|
+
#include <stdio.h>
|
|
4
|
+
#include <string.h>
|
|
5
|
+
#include <errno.h>
|
|
6
|
+
#include <sys/types.h>
|
|
7
|
+
#include <sys/stat.h>
|
|
8
|
+
#include <fcntl.h>
|
|
9
|
+
#include <unistd.h>
|
|
10
|
+
|
|
11
|
+
#ifdef __FreeBSD__
|
|
12
|
+
#include <dev/evdev/input.h>
|
|
13
|
+
#include <dev/evdev/uinput.h>
|
|
14
|
+
#else
|
|
15
|
+
#include <linux/input.h>
|
|
16
|
+
#include <linux/uinput.h>
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
#ifndef input_event_sec
|
|
20
|
+
#define input_event_sec time.tv_sec
|
|
21
|
+
#define input_event_usec time.tv_usec
|
|
22
|
+
#endif
|
|
23
|
+
|
|
24
|
+
// Workaround for installing on kernels newer than 4.4.
|
|
25
|
+
#ifndef FF_MAX_EFFECTS
|
|
26
|
+
#define FF_MAX_EFFECTS FF_GAIN;
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
int _uinput_close(int fd)
|
|
30
|
+
{
|
|
31
|
+
if (ioctl(fd, UI_DEV_DESTROY) < 0) {
|
|
32
|
+
int oerrno = errno;
|
|
33
|
+
close(fd);
|
|
34
|
+
errno = oerrno;
|
|
35
|
+
return -1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return close(fd);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
static PyObject *
|
|
43
|
+
uinput_open(PyObject *self, PyObject *args)
|
|
44
|
+
{
|
|
45
|
+
const char* devnode;
|
|
46
|
+
|
|
47
|
+
int ret = PyArg_ParseTuple(args, "s", &devnode);
|
|
48
|
+
if (!ret) return NULL;
|
|
49
|
+
|
|
50
|
+
int fd = open(devnode, O_RDWR | O_NONBLOCK);
|
|
51
|
+
if (fd < 0) {
|
|
52
|
+
PyErr_SetString(PyExc_OSError, "could not open uinput device in write mode");
|
|
53
|
+
return NULL;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return Py_BuildValue("i", fd);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
static PyObject *
|
|
61
|
+
uinput_set_phys(PyObject *self, PyObject *args)
|
|
62
|
+
{
|
|
63
|
+
int fd;
|
|
64
|
+
const char* phys;
|
|
65
|
+
|
|
66
|
+
int ret = PyArg_ParseTuple(args, "is", &fd, &phys);
|
|
67
|
+
if (!ret) return NULL;
|
|
68
|
+
|
|
69
|
+
if (ioctl(fd, UI_SET_PHYS, phys) < 0)
|
|
70
|
+
goto on_err;
|
|
71
|
+
|
|
72
|
+
Py_RETURN_NONE;
|
|
73
|
+
|
|
74
|
+
on_err:
|
|
75
|
+
_uinput_close(fd);
|
|
76
|
+
PyErr_SetFromErrno(PyExc_OSError);
|
|
77
|
+
return NULL;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static PyObject *
|
|
81
|
+
uinput_set_prop(PyObject *self, PyObject *args)
|
|
82
|
+
{
|
|
83
|
+
int fd;
|
|
84
|
+
uint16_t prop;
|
|
85
|
+
|
|
86
|
+
int ret = PyArg_ParseTuple(args, "ih", &fd, &prop);
|
|
87
|
+
if (!ret) return NULL;
|
|
88
|
+
|
|
89
|
+
if (ioctl(fd, UI_SET_PROPBIT, prop) < 0)
|
|
90
|
+
goto on_err;
|
|
91
|
+
|
|
92
|
+
Py_RETURN_NONE;
|
|
93
|
+
|
|
94
|
+
on_err:
|
|
95
|
+
_uinput_close(fd);
|
|
96
|
+
PyErr_SetFromErrno(PyExc_OSError);
|
|
97
|
+
return NULL;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static PyObject *
|
|
101
|
+
uinput_get_sysname(PyObject *self, PyObject *args)
|
|
102
|
+
{
|
|
103
|
+
int fd;
|
|
104
|
+
char sysname[64];
|
|
105
|
+
|
|
106
|
+
int ret = PyArg_ParseTuple(args, "i", &fd);
|
|
107
|
+
if (!ret) return NULL;
|
|
108
|
+
|
|
109
|
+
#ifdef UI_GET_SYSNAME
|
|
110
|
+
if (ioctl(fd, UI_GET_SYSNAME(sizeof(sysname)), &sysname) < 0)
|
|
111
|
+
goto on_err;
|
|
112
|
+
|
|
113
|
+
return Py_BuildValue("s", &sysname);
|
|
114
|
+
#endif
|
|
115
|
+
|
|
116
|
+
on_err:
|
|
117
|
+
PyErr_SetFromErrno(PyExc_OSError);
|
|
118
|
+
return NULL;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Different kernel versions have different device setup methods. You can read
|
|
122
|
+
// more about it here:
|
|
123
|
+
// https://github.com/torvalds/linux/commit/052876f8e5aec887d22c4d06e54aa5531ffcec75
|
|
124
|
+
|
|
125
|
+
// Setup function for kernel >= v4.5
|
|
126
|
+
#if defined(UI_DEV_SETUP) && defined(UI_ABS_SETUP)
|
|
127
|
+
static PyObject *
|
|
128
|
+
uinput_setup(PyObject *self, PyObject *args) {
|
|
129
|
+
int fd, len, i;
|
|
130
|
+
uint16_t vendor, product, version, bustype;
|
|
131
|
+
uint32_t max_effects;
|
|
132
|
+
|
|
133
|
+
PyObject *absinfo = NULL, *item = NULL;
|
|
134
|
+
|
|
135
|
+
struct uinput_abs_setup abs_setup;
|
|
136
|
+
|
|
137
|
+
const char* name;
|
|
138
|
+
int ret = PyArg_ParseTuple(args, "isHHHHOI", &fd, &name, &vendor,
|
|
139
|
+
&product, &version, &bustype, &absinfo, &max_effects);
|
|
140
|
+
if (!ret) return NULL;
|
|
141
|
+
|
|
142
|
+
// Setup absinfo:
|
|
143
|
+
len = PyList_Size(absinfo);
|
|
144
|
+
for (i=0; i<len; i++) {
|
|
145
|
+
|
|
146
|
+
// item -> (ABS_X, 0, 255, 0, 0, 0, 0)
|
|
147
|
+
item = PyList_GetItem(absinfo, i);
|
|
148
|
+
|
|
149
|
+
memset(&abs_setup, 0, sizeof(abs_setup)); // Clear struct
|
|
150
|
+
abs_setup.code = PyLong_AsLong(PyList_GetItem(item, 0));
|
|
151
|
+
abs_setup.absinfo.value = PyLong_AsLong(PyList_GetItem(item, 1));
|
|
152
|
+
abs_setup.absinfo.minimum = PyLong_AsLong(PyList_GetItem(item, 2));
|
|
153
|
+
abs_setup.absinfo.maximum = PyLong_AsLong(PyList_GetItem(item, 3));
|
|
154
|
+
abs_setup.absinfo.fuzz = PyLong_AsLong(PyList_GetItem(item, 4));
|
|
155
|
+
abs_setup.absinfo.flat = PyLong_AsLong(PyList_GetItem(item, 5));
|
|
156
|
+
abs_setup.absinfo.resolution = PyLong_AsLong(PyList_GetItem(item, 6));
|
|
157
|
+
|
|
158
|
+
if(ioctl(fd, UI_ABS_SETUP, &abs_setup) < 0)
|
|
159
|
+
goto on_err;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Setup evdev:
|
|
163
|
+
struct uinput_setup usetup;
|
|
164
|
+
|
|
165
|
+
memset(&usetup, 0, sizeof(usetup));
|
|
166
|
+
strncpy(usetup.name, name, sizeof(usetup.name) - 1);
|
|
167
|
+
usetup.id.vendor = vendor;
|
|
168
|
+
usetup.id.product = product;
|
|
169
|
+
usetup.id.version = version;
|
|
170
|
+
usetup.id.bustype = bustype;
|
|
171
|
+
usetup.ff_effects_max = max_effects;
|
|
172
|
+
|
|
173
|
+
if(ioctl(fd, UI_DEV_SETUP, &usetup) < 0)
|
|
174
|
+
goto on_err;
|
|
175
|
+
|
|
176
|
+
Py_RETURN_NONE;
|
|
177
|
+
|
|
178
|
+
on_err:
|
|
179
|
+
_uinput_close(fd);
|
|
180
|
+
PyErr_SetFromErrno(PyExc_OSError);
|
|
181
|
+
return NULL;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Fallback setup function (Linux <= 4.5 and FreeBSD).
|
|
185
|
+
#else
|
|
186
|
+
static PyObject *
|
|
187
|
+
uinput_setup(PyObject *self, PyObject *args) {
|
|
188
|
+
int fd, len, i, abscode;
|
|
189
|
+
uint16_t vendor, product, version, bustype;
|
|
190
|
+
uint32_t max_effects;
|
|
191
|
+
|
|
192
|
+
PyObject *absinfo = NULL, *item = NULL;
|
|
193
|
+
|
|
194
|
+
struct uinput_user_dev uidev;
|
|
195
|
+
const char* name;
|
|
196
|
+
|
|
197
|
+
int ret = PyArg_ParseTuple(args, "isHHHHOI", &fd, &name, &vendor,
|
|
198
|
+
&product, &version, &bustype, &absinfo, &max_effects);
|
|
199
|
+
if (!ret) return NULL;
|
|
200
|
+
|
|
201
|
+
memset(&uidev, 0, sizeof(uidev));
|
|
202
|
+
strncpy(uidev.name, name, sizeof(uidev.name) - 1);
|
|
203
|
+
uidev.id.vendor = vendor;
|
|
204
|
+
uidev.id.product = product;
|
|
205
|
+
uidev.id.version = version;
|
|
206
|
+
uidev.id.bustype = bustype;
|
|
207
|
+
uidev.ff_effects_max = max_effects;
|
|
208
|
+
|
|
209
|
+
len = PyList_Size(absinfo);
|
|
210
|
+
for (i=0; i<len; i++) {
|
|
211
|
+
// item -> (ABS_X, 0, 255, 0, 0, 0, 0)
|
|
212
|
+
item = PyList_GetItem(absinfo, i);
|
|
213
|
+
abscode = (int)PyLong_AsLong(PyList_GetItem(item, 0));
|
|
214
|
+
|
|
215
|
+
/* min/max/fuzz/flat start from index 2 because index 1 is value */
|
|
216
|
+
uidev.absmin[abscode] = PyLong_AsLong(PyList_GetItem(item, 2));
|
|
217
|
+
uidev.absmax[abscode] = PyLong_AsLong(PyList_GetItem(item, 3));
|
|
218
|
+
uidev.absfuzz[abscode] = PyLong_AsLong(PyList_GetItem(item, 4));
|
|
219
|
+
uidev.absflat[abscode] = PyLong_AsLong(PyList_GetItem(item, 5));
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (write(fd, &uidev, sizeof(uidev)) != sizeof(uidev))
|
|
223
|
+
goto on_err;
|
|
224
|
+
|
|
225
|
+
Py_RETURN_NONE;
|
|
226
|
+
|
|
227
|
+
on_err:
|
|
228
|
+
_uinput_close(fd);
|
|
229
|
+
PyErr_SetFromErrno(PyExc_OSError);
|
|
230
|
+
return NULL;
|
|
231
|
+
}
|
|
232
|
+
#endif
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
static PyObject *
|
|
236
|
+
uinput_create(PyObject *self, PyObject *args)
|
|
237
|
+
{
|
|
238
|
+
int fd;
|
|
239
|
+
|
|
240
|
+
int ret = PyArg_ParseTuple(args, "i", &fd);
|
|
241
|
+
if (!ret) return NULL;
|
|
242
|
+
|
|
243
|
+
if (ioctl(fd, UI_DEV_CREATE) < 0)
|
|
244
|
+
goto on_err;
|
|
245
|
+
|
|
246
|
+
Py_RETURN_NONE;
|
|
247
|
+
|
|
248
|
+
on_err:
|
|
249
|
+
_uinput_close(fd);
|
|
250
|
+
PyErr_SetFromErrno(PyExc_OSError);
|
|
251
|
+
return NULL;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
static PyObject *
|
|
256
|
+
uinput_close(PyObject *self, PyObject *args)
|
|
257
|
+
{
|
|
258
|
+
int fd;
|
|
259
|
+
|
|
260
|
+
int ret = PyArg_ParseTuple(args, "i", &fd);
|
|
261
|
+
if (!ret) return NULL;
|
|
262
|
+
|
|
263
|
+
if (_uinput_close(fd) < 0) {
|
|
264
|
+
PyErr_SetFromErrno(PyExc_OSError);
|
|
265
|
+
return NULL;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
Py_RETURN_NONE;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
static PyObject *
|
|
273
|
+
uinput_write(PyObject *self, PyObject *args)
|
|
274
|
+
{
|
|
275
|
+
int fd, type, code, value;
|
|
276
|
+
|
|
277
|
+
int ret = PyArg_ParseTuple(args, "iiii", &fd, &type, &code, &value);
|
|
278
|
+
if (!ret) return NULL;
|
|
279
|
+
|
|
280
|
+
struct input_event event;
|
|
281
|
+
struct timeval tval;
|
|
282
|
+
memset(&event, 0, sizeof(event));
|
|
283
|
+
gettimeofday(&tval, 0);
|
|
284
|
+
event.input_event_usec = tval.tv_usec;
|
|
285
|
+
event.input_event_sec = tval.tv_sec;
|
|
286
|
+
event.type = type;
|
|
287
|
+
event.code = code;
|
|
288
|
+
event.value = value;
|
|
289
|
+
|
|
290
|
+
if (write(fd, &event, sizeof(event)) != sizeof(event)) {
|
|
291
|
+
// @todo: elaborate
|
|
292
|
+
// PyErr_SetString(PyExc_OSError, "error writing event to uinput device");
|
|
293
|
+
PyErr_SetFromErrno(PyExc_OSError);
|
|
294
|
+
return NULL;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
Py_RETURN_NONE;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
static PyObject *
|
|
302
|
+
uinput_enable_event(PyObject *self, PyObject *args)
|
|
303
|
+
{
|
|
304
|
+
int fd;
|
|
305
|
+
uint16_t type, code;
|
|
306
|
+
unsigned long req;
|
|
307
|
+
|
|
308
|
+
int ret = PyArg_ParseTuple(args, "ihh", &fd, &type, &code);
|
|
309
|
+
if (!ret) return NULL;
|
|
310
|
+
|
|
311
|
+
switch (type) {
|
|
312
|
+
case EV_KEY: req = UI_SET_KEYBIT; break;
|
|
313
|
+
case EV_ABS: req = UI_SET_ABSBIT; break;
|
|
314
|
+
case EV_REL: req = UI_SET_RELBIT; break;
|
|
315
|
+
case EV_MSC: req = UI_SET_MSCBIT; break;
|
|
316
|
+
case EV_SW: req = UI_SET_SWBIT; break;
|
|
317
|
+
case EV_LED: req = UI_SET_LEDBIT; break;
|
|
318
|
+
case EV_FF: req = UI_SET_FFBIT; break;
|
|
319
|
+
case EV_SND: req = UI_SET_SNDBIT; break;
|
|
320
|
+
default:
|
|
321
|
+
errno = EINVAL;
|
|
322
|
+
goto on_err;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (ioctl(fd, UI_SET_EVBIT, type) < 0)
|
|
326
|
+
goto on_err;
|
|
327
|
+
|
|
328
|
+
if (ioctl(fd, req, code) < 0)
|
|
329
|
+
goto on_err;
|
|
330
|
+
|
|
331
|
+
Py_RETURN_NONE;
|
|
332
|
+
|
|
333
|
+
on_err:
|
|
334
|
+
_uinput_close(fd);
|
|
335
|
+
PyErr_SetFromErrno(PyExc_OSError);
|
|
336
|
+
return NULL;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
int _uinput_begin_upload(int fd, struct uinput_ff_upload *upload)
|
|
340
|
+
{
|
|
341
|
+
return ioctl(fd, UI_BEGIN_FF_UPLOAD, upload);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
int _uinput_end_upload(int fd, struct uinput_ff_upload *upload)
|
|
345
|
+
{
|
|
346
|
+
return ioctl(fd, UI_END_FF_UPLOAD, upload);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
int _uinput_begin_erase(int fd, struct uinput_ff_erase *upload)
|
|
350
|
+
{
|
|
351
|
+
return ioctl(fd, UI_BEGIN_FF_ERASE, upload);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
int _uinput_end_erase(int fd, struct uinput_ff_erase *upload)
|
|
355
|
+
{
|
|
356
|
+
return ioctl(fd, UI_END_FF_ERASE, upload);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
static PyMethodDef MethodTable[] = {
|
|
361
|
+
{ "open", uinput_open, METH_VARARGS,
|
|
362
|
+
"Open uinput device node."},
|
|
363
|
+
|
|
364
|
+
{ "setup", uinput_setup, METH_VARARGS,
|
|
365
|
+
"Set an uinput device up."},
|
|
366
|
+
|
|
367
|
+
{ "create", uinput_create, METH_VARARGS,
|
|
368
|
+
"Create an uinput device."},
|
|
369
|
+
|
|
370
|
+
{ "close", uinput_close, METH_VARARGS,
|
|
371
|
+
"Destroy uinput device."},
|
|
372
|
+
|
|
373
|
+
{ "write", uinput_write, METH_VARARGS,
|
|
374
|
+
"Write event to uinput device."},
|
|
375
|
+
|
|
376
|
+
{ "enable", uinput_enable_event, METH_VARARGS,
|
|
377
|
+
"Enable a type of event."},
|
|
378
|
+
|
|
379
|
+
{ "set_phys", uinput_set_phys, METH_VARARGS,
|
|
380
|
+
"Set physical path"},
|
|
381
|
+
|
|
382
|
+
{ "get_sysname", uinput_get_sysname, METH_VARARGS,
|
|
383
|
+
"Obtain the sysname of the uinput device."},
|
|
384
|
+
|
|
385
|
+
{ "set_prop", uinput_set_prop, METH_VARARGS,
|
|
386
|
+
"Set device input property"},
|
|
387
|
+
|
|
388
|
+
{ NULL, NULL, 0, NULL}
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
static struct PyModuleDef moduledef = {
|
|
392
|
+
PyModuleDef_HEAD_INIT,
|
|
393
|
+
"_uinput",
|
|
394
|
+
"Python bindings for parts of linux/uinput.c",
|
|
395
|
+
-1, /* m_size */
|
|
396
|
+
MethodTable, /* m_methods */
|
|
397
|
+
NULL, /* m_reload */
|
|
398
|
+
NULL, /* m_traverse */
|
|
399
|
+
NULL, /* m_clear */
|
|
400
|
+
NULL, /* m_free */
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
static PyObject *
|
|
404
|
+
moduleinit(void)
|
|
405
|
+
{
|
|
406
|
+
PyObject* m = PyModule_Create(&moduledef);
|
|
407
|
+
if (m == NULL) return NULL;
|
|
408
|
+
|
|
409
|
+
PyModule_AddIntConstant(m, "maxnamelen", UINPUT_MAX_NAME_SIZE);
|
|
410
|
+
return m;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
PyMODINIT_FUNC
|
|
414
|
+
PyInit__uinput(void)
|
|
415
|
+
{
|
|
416
|
+
return moduleinit();
|
|
417
|
+
}
|