Skip to content

Commit fb8553a

Browse files
committed
wip
1 parent 3ebe549 commit fb8553a

5 files changed

Lines changed: 135 additions & 142 deletions

File tree

bin/fftest-uinput-test.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
'''
5+
evdev example - uinput force feedback event monitor
6+
'''
7+
8+
from __future__ import print_function
9+
import time, sys
10+
11+
from evdev import UInput, UInputError, ecodes
12+
13+
14+
cap = {
15+
ecodes.EV_FF: [
16+
ecodes.FF_CONSTANT,
17+
ecodes.FF_PERIODIC,
18+
ecodes.FF_RAMP,
19+
ecodes.FF_SPRING,
20+
ecodes.FF_FRICTION,
21+
ecodes.FF_DAMPER,
22+
# ecodes.FF_RUMBLE,
23+
ecodes.FF_INERTIA,
24+
]
25+
}
26+
27+
ui = UInput(cap, ff_effects_max=10)
28+
29+
try:
30+
print('uinput device created - run "fftest %s" to test' % ui.device.fn)
31+
except AttributeError:
32+
print('error: could not find corresponding /dev/input/eventXX device - check permissions')
33+
sys.exit(1)
34+
35+
print('waiting for events:')
36+
ui.read_loop()
37+
# while True:
38+
# status, event = ui.read()
39+
40+
# if status is not None:
41+
# print(event)
42+
# # if status == ecodes.FF_STATUS_PLAYING:
43+
# # print("rumble playing")
44+
# # elif status == ecodes.FF_STATUS_STOPPED:
45+
# # print("rumble stopped")
46+
# # else:
47+
# # print("received an unknown event!")
48+
49+
# time.sleep(0.2)

bin/rumbletest.py

Lines changed: 0 additions & 39 deletions
This file was deleted.

doc/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747

4848
# General information about the project.
4949
project = u'python-evdev'
50-
copyright = u'2012-2013, Georgi Valkov'
50+
copyright = u'2012-2014, Georgi Valkov'
5151

5252
# The version info for the project you're documenting, acts as replacement for
5353
# |version| and |release|, also used in various other places throughout the

evdev/uinput.c

Lines changed: 36 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
#include <linux/uinput.h>
1313

1414

15-
int _uinput_close(int fd)
16-
{
15+
int _uinput_close(int fd) {
1716
if (ioctl(fd, UI_DEV_DESTROY) < 0) {
1817
int oerrno = errno;
1918
close(fd);
@@ -47,15 +46,18 @@ static PyObject *
4746
uinput_create(PyObject *self, PyObject *args) {
4847
int fd, len, i, abscode;
4948
__u16 vendor, product, version, bustype;
49+
__u32 ff_effects_max;
5050

5151
PyObject *absinfo = NULL, *item = NULL;
5252

5353
struct uinput_user_dev uidev;
5454
const char* name;
5555

56-
int ret = PyArg_ParseTuple(args, "ishhhhO", &fd, &name, &vendor,
57-
&product, &version, &bustype, &absinfo);
58-
if (!ret) return NULL;
56+
int ret = PyArg_ParseTuple(args, "ishhhhOi", &fd, &name, &vendor,
57+
&product, &version, &bustype, &absinfo,
58+
&ff_effects_max);
59+
if (!ret)
60+
return NULL;
5961

6062
memset(&uidev, 0, sizeof(uidev));
6163
strncpy(uidev.name, name, UINPUT_MAX_NAME_SIZE);
@@ -64,6 +66,9 @@ uinput_create(PyObject *self, PyObject *args) {
6466
uidev.id.version = version;
6567
uidev.id.bustype = bustype;
6668

69+
// force-feedback-capable driver
70+
uidev.ff_effects_max = ff_effects_max;
71+
6772
len = PyList_Size(absinfo);
6873
for (i=0; i<len; i++) {
6974
// item -> (ABS_X, 0, 255, 0, 0)
@@ -76,25 +81,9 @@ uinput_create(PyObject *self, PyObject *args) {
7681
uidev.absflat[abscode] = PyLong_AsLong(PyList_GetItem(item, 4));
7782
}
7883

79-
uidev.ff_effects_max = 1;
80-
81-
if (ioctl(fd, UI_SET_EVBIT, EV_FF) < 0)
82-
goto on_err;
83-
84-
if (ioctl(fd, UI_SET_FFBIT, FF_RUMBLE) < 0)
85-
goto on_err;
86-
8784
if (write(fd, &uidev, sizeof(uidev)) != sizeof(uidev))
8885
goto on_err;
8986

90-
/* if (ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0) */
91-
/* goto on_err; */
92-
/* int i; */
93-
/* for (i=0; i<KEY_MAX && fd; i++) { */
94-
/* if (ioctl(fd, UI_SET_KEYBIT, i) < 0) */
95-
/* goto on_err; */
96-
/* } */
97-
9887
if (ioctl(fd, UI_DEV_CREATE) < 0)
9988
goto on_err;
10089

@@ -149,56 +138,24 @@ uinput_write(PyObject *self, PyObject *args)
149138
Py_RETURN_NONE;
150139
}
151140

152-
153141
static PyObject *
154-
uinput_read(PyObject *self, PyObject *args)
142+
uinput_upload_effect(PyObject *self, PyObject *args)
155143
{
156144
int fd;
157-
158-
int ret = PyArg_ParseTuple(args, "i", &fd);
145+
__u32 request_id;
146+
int ret = PyArg_ParseTuple(args, "ii", &fd, &request_id);
159147
if (!ret) return NULL;
160148

161-
size_t len;
162-
struct input_event event;
163-
164149
struct uinput_ff_upload upload;
165-
struct uinput_ff_erase erase;
166-
167-
len = read(fd, &event, sizeof(event));
168-
if (len == -1) {
169-
if (errno == EAGAIN) {
170-
// No events available
171-
Py_RETURN_NONE;
172-
} else {
173-
PyErr_SetFromErrno(PyExc_IOError);
174-
return NULL;
175-
}
176-
} else if (len != sizeof(event)) {
150+
151+
upload.request_id = request_id;
152+
if (ioctl(fd, UI_BEGIN_FF_UPLOAD, &upload) < 0)
177153
return NULL;
178-
}
179154

180-
switch (event.type) {
181-
case EV_UINPUT:
182-
switch (event.code) {
183-
case UI_FF_UPLOAD:
184-
upload.request_id = event.value;
185-
if (ioctl(fd, UI_BEGIN_FF_UPLOAD, &upload) < 0) return NULL;
186-
if (ioctl(fd, UI_END_FF_UPLOAD, &upload) < 0) return NULL;
187-
return Py_BuildValue("i", UI_FF_UPLOAD);
188-
189-
case UI_FF_ERASE:
190-
erase.request_id = event.value;
191-
if (ioctl(fd, UI_BEGIN_FF_ERASE, &erase) < 0) return NULL;
192-
if (ioctl(fd, UI_END_FF_ERASE, &erase) < 0) return NULL;
193-
return Py_BuildValue("i", UI_FF_ERASE);
194-
195-
default: break;
196-
}
197-
198-
default: break;
199-
}
155+
if (ioctl(fd, UI_END_FF_UPLOAD, &upload) < 0)
156+
return NULL;
200157

201-
Py_RETURN_NONE;
158+
return Py_BuildValue("s#", &upload.effect, sizeof(struct ff_effect));
202159
}
203160

204161

@@ -241,27 +198,27 @@ uinput_enable_event(PyObject *self, PyObject *args)
241198
}
242199

243200

244-
#define MODULE_NAME "_uinput"
245-
#define MODULE_HELP "Python bindings for parts of linux/uinput.c"
246-
247-
static PyMethodDef MethodTable[] = {
248-
{ "open", uinput_open, METH_VARARGS,
249-
"Open uinput device node."},
250-
251-
{ "create", uinput_create, METH_VARARGS,
252-
"Create an uinput device."},
201+
// static PyObject *
202+
// uinput_enable_ff_bit(PyObject *self, PyObject *args)
203+
// {
204+
// int fd;
205+
// unsigned long req;
253206

254-
{ "close", uinput_close, METH_VARARGS,
255-
"Destroy uinput device."},
207+
// int ret = PyArg_ParseTuple(args, "ihh", &fd, &type, &code);
208+
// if (!ret) return NULL;
209+
// }
256210

257-
{ "write", uinput_write, METH_VARARGS,
258-
"Write event to uinput device."},
259211

260-
{ "read", uinput_read, METH_VARARGS,
261-
"Read event from uinput device."},
212+
#define MODULE_NAME "_uinput"
213+
#define MODULE_HELP "Python bindings for parts of linux/uinput.c"
262214

263-
{ "enable", uinput_enable_event, METH_VARARGS,
264-
"Enable a type of event."},
215+
static PyMethodDef MethodTable[] = {
216+
{ "open", uinput_open, METH_VARARGS, "Open uinput device node."},
217+
{ "create", uinput_create, METH_VARARGS, "Create an uinput device."},
218+
{ "close", uinput_close, METH_VARARGS, "Destroy uinput device."},
219+
{ "write", uinput_write, METH_VARARGS, "Write event to uinput device."},
220+
{ "upload_effect", uinput_upload_effect, METH_VARARGS, ""},
221+
{ "enable", uinput_enable_event, METH_VARARGS, "Enable a type of event."},
265222

266223
{ NULL, NULL, 0, NULL}
267224
};

0 commit comments

Comments
 (0)