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 *
4746uinput_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-
153141static 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