1212#include <linux/uinput.h>
1313
1414
15- static int uinput_fd = -1 ;
15+ int _uinput_close (int fd )
16+ {
17+ if (ioctl (fd , UI_DEV_DESTROY ) < 0 ) {
18+ int oerrno = errno ;
19+ close (fd );
20+ errno = oerrno ;
21+ return -1 ;
22+ }
1623
17- static void _uinput_close (void ) {
18- if (uinput_fd >= 0 ) {
19- close (uinput_fd );
20- uinput_fd = -1 ;
21- }
24+ return close (fd );
2225}
2326
2427
2528static PyObject *
2629uinput_open (PyObject * self , PyObject * args )
2730{
28- struct uinput_user_dev uidev ;
31+ const char * devnode ;
2932
30- __u16 vendor , product , version ;
31- const char * name ;
32- const char * uinputdev_fn ;
33-
34- int ret = PyArg_ParseTuple (args , "shhhs" , & name , & vendor , & product , & version , & uinputdev_fn );
33+ int ret = PyArg_ParseTuple (args , "s" , & devnode );
3534 if (!ret ) return NULL ;
3635
37- uinput_fd = open (uinputdev_fn , O_WRONLY | O_NONBLOCK );
38- if (uinput_fd < 0 ) {
36+ int fd = open (devnode , O_WRONLY | O_NONBLOCK );
37+ if (fd < 0 ) {
3938 PyErr_SetString (PyExc_IOError , "could not open uinput device in write mode" );
4039 return NULL ;
4140 }
4241
42+ return Py_BuildValue ("i" , fd );
43+ }
44+
45+
46+ static PyObject *
47+ uinput_create (PyObject * self , PyObject * args ) {
48+ int fd ;
49+ __u16 vendor , product , version , bustype ;
50+
51+ struct uinput_user_dev uidev ;
52+ const char * name ;
53+
54+ int ret = PyArg_ParseTuple (args , "ishhhh" , & fd , & name , & vendor ,
55+ & product , & version , & bustype );
56+ if (!ret ) return NULL ;
57+
4358 memset (& uidev , 0 , sizeof (uidev ));
4459 strncpy (uidev .name , name , UINPUT_MAX_NAME_SIZE );
45- uidev .id .bustype = BUS_USB ;
4660 uidev .id .vendor = vendor ;
4761 uidev .id .product = product ;
4862 uidev .id .version = version ;
63+ uidev .id .bustype = bustype ;
4964
50- if (write (uinput_fd , & uidev , sizeof (uidev )) != sizeof (uidev ))
51- goto on_err ;
52-
53- if (ioctl (uinput_fd , UI_SET_EVBIT , EV_KEY ) < 0 )
65+ if (write (fd , & uidev , sizeof (uidev )) != sizeof (uidev ))
5466 goto on_err ;
5567
56- int i ;
57- for (i = 0 ; i < KEY_MAX && uinput_fd ; i ++ ) {
58- if (ioctl (uinput_fd , UI_SET_KEYBIT , i ) < 0 )
59- goto on_err ;
60- }
68+ /* if (ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0) */
69+ /* goto on_err; */
70+ /* int i; */
71+ /* for (i=0; i<KEY_MAX && fd; i++) { */
72+ /* if (ioctl(fd, UI_SET_KEYBIT, i) < 0) */
73+ /* goto on_err; */
74+ /* } */
6175
62- if (ioctl (uinput_fd , UI_DEV_CREATE ) < 0 )
76+ if (ioctl (fd , UI_DEV_CREATE ) < 0 )
6377 goto on_err ;
6478
65- return Py_BuildValue ("i" , uinput_fd );
79+
80+ return Py_BuildValue ("i" , 1 );
6681
6782 on_err :
68- _uinput_close ();
83+ _uinput_close (fd );
6984 PyErr_SetFromErrno (PyExc_IOError );
7085 return NULL ;
7186}
7287
88+
7389static PyObject *
7490uinput_close (PyObject * self , PyObject * args )
7591{
@@ -78,15 +94,15 @@ uinput_close(PyObject *self, PyObject *args)
7894 int ret = PyArg_ParseTuple (args , "i" , & fd );
7995 if (!ret ) return NULL ;
8096
81- ret = ioctl (fd , UI_DEV_DESTROY );
82- if (ret < 0 ) {
97+ if (_uinput_close (fd ) < 0 ) {
8398 PyErr_SetFromErrno (PyExc_IOError );
8499 return NULL ;
85100 }
86101
87102 return Py_BuildValue ("i" , 1 );
88103}
89104
105+
90106static PyObject *
91107uinput_write (PyObject * self , PyObject * args )
92108{
@@ -97,31 +113,79 @@ uinput_write(PyObject *self, PyObject *args)
97113
98114 struct input_event event ;
99115 memset (& event , 0 , sizeof (event ));
116+ gettimeofday (& event .time , 0 );
100117 event .type = type ;
101118 event .code = code ;
102119 event .value = value ;
103120
104121 if (write (fd , & event , sizeof (event )) != sizeof (event )) {
105- PyErr_SetString (PyExc_IOError , "error writing event to uinput device" ); // @todo: elaborate
122+ // @todo: elaborate
123+ PyErr_SetString (PyExc_IOError , "error writing event to uinput device" );
106124 return NULL ;
107- }
125+ }
108126
109127 return Py_BuildValue ("i" , 1 );
110128}
111129
130+
131+ static PyObject *
132+ uinput_enable_event (PyObject * self , PyObject * args )
133+ {
134+ int fd ;
135+ __u16 type , code ;
136+ unsigned long req ;
137+
138+ int ret = PyArg_ParseTuple (args , "ihh" , & fd , & type , & code );
139+ if (!ret ) return NULL ;
140+
141+ switch (type ) {
142+ case EV_KEY : req = UI_SET_KEYBIT ; break ;
143+ case EV_ABS : req = UI_SET_ABSBIT ; break ;
144+ case EV_REL : req = UI_SET_RELBIT ; break ;
145+ case EV_MSC : req = UI_SET_MSCBIT ; break ;
146+ case EV_SW : req = UI_SET_SWBIT ; break ;
147+ case EV_LED : req = UI_SET_LEDBIT ; break ;
148+ case EV_FF : req = UI_SET_FFBIT ; break ;
149+ case EV_SND : req = UI_SET_SNDBIT ; break ;
150+ default :
151+ errno = EINVAL ;
152+ goto on_err ;
153+ }
154+
155+ if (ioctl (fd , UI_SET_EVBIT , type ) < 0 )
156+ goto on_err ;
157+
158+ if (ioctl (fd , req , code ) < 0 )
159+ goto on_err ;
160+
161+ return Py_BuildValue ("i" , 1 );
162+
163+ on_err :
164+ _uinput_close (fd );
165+ PyErr_SetFromErrno (PyExc_IOError );
166+ return NULL ;
167+ }
168+
169+
112170#define MODULE_NAME "_uinput"
113171#define MODULE_HELP "Python bindings for parts of linux/uinput.c"
114172
115173static PyMethodDef MethodTable [] = {
116174 { "open" , uinput_open , METH_VARARGS ,
117- "Create uinput device." },
175+ "Open uinput device node." },
176+
177+ { "create" , uinput_create , METH_VARARGS ,
178+ "Create an uinput device." },
118179
119180 { "close" , uinput_close , METH_VARARGS ,
120181 "Destroy uinput device." },
121182
122183 { "write" , uinput_write , METH_VARARGS ,
123184 "Write event to uinput device." },
124185
186+ { "enable" , uinput_enable_event , METH_VARARGS ,
187+ "Enable a type of event." },
188+
125189 { NULL , NULL , 0 , NULL }
126190};
127191
0 commit comments