@@ -33,7 +33,7 @@ uinput_open(PyObject *self, PyObject *args)
3333 int ret = PyArg_ParseTuple (args , "s" , & devnode );
3434 if (!ret ) return NULL ;
3535
36- int fd = open (devnode , O_WRONLY | O_NONBLOCK );
36+ int fd = open (devnode , O_RDWR | O_NONBLOCK );
3737 if (fd < 0 ) {
3838 PyErr_SetString (PyExc_IOError , "could not open uinput device in write mode" );
3939 return NULL ;
@@ -76,6 +76,14 @@ uinput_create(PyObject *self, PyObject *args) {
7676 uidev .absflat [abscode ] = PyLong_AsLong (PyList_GetItem (item , 4 ));
7777 }
7878
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+
7987 if (write (fd , & uidev , sizeof (uidev )) != sizeof (uidev ))
8088 goto on_err ;
8189
@@ -142,6 +150,58 @@ uinput_write(PyObject *self, PyObject *args)
142150}
143151
144152
153+ static PyObject *
154+ uinput_read (PyObject * self , PyObject * args )
155+ {
156+ int fd ;
157+
158+ int ret = PyArg_ParseTuple (args , "i" , & fd );
159+ if (!ret ) return NULL ;
160+
161+ size_t len ;
162+ struct input_event event ;
163+
164+ 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 )) {
177+ return NULL ;
178+ }
179+
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+ }
200+
201+ Py_RETURN_NONE ;
202+ }
203+
204+
145205static PyObject *
146206uinput_enable_event (PyObject * self , PyObject * args )
147207{
@@ -197,6 +257,9 @@ static PyMethodDef MethodTable[] = {
197257 { "write" , uinput_write , METH_VARARGS ,
198258 "Write event to uinput device." },
199259
260+ { "read" , uinput_read , METH_VARARGS ,
261+ "Read event from uinput device." },
262+
200263 { "enable" , uinput_enable_event , METH_VARARGS ,
201264 "Enable a type of event." },
202265
0 commit comments