@@ -122,57 +122,88 @@ event_unpack(PyObject *self, PyObject *args)
122122
123123 memcpy (& event , data , sizeof (event ));
124124
125- return Py_BuildValue ( "i" , 1 ) ;
125+ Py_RETURN_NONE ;
126126}
127127
128128
129- // An all-in-one function for describing an input device
129+ // Get the event types and event codes that the input device supports
130130static PyObject *
131- ioctl_devinfo (PyObject * self , PyObject * args )
131+ ioctl_capabilities (PyObject * self , PyObject * args )
132132{
133- int fd , i , j , nophys ;
133+ int fd , i , j ;
134+ char ev_bits [EV_MAX /8 ], code_bits [KEY_MAX /8 ];
134135
135- struct input_id iid ;
136- char name [MAX_NAME_SIZE ];
137- char phys [MAX_NAME_SIZE ];
138- char ev_mask [EV_MAX /8 ], key_mask [KEY_MAX /8 ];
136+ int ret = PyArg_ParseTuple (args , "i" , & fd );
137+ if (!ret ) return NULL ;
138+
139+ // @todo: figure out why fd gets zeroed on the ioctls after the
140+ // refactoring and get rid of this workaround
141+ const int _fd = fd ;
139142
140143 // Capabilities is a mapping of supported event types to lists of handled
141- // event codes e.g: {1: [272, 273, 274, 275], 2: [0, 1, 6, 8]}
144+ // evenes e.g: {1: [272, 273, 274, 275], 2: [0, 1, 6, 8]}
142145 PyObject * capabilities = PyDict_New ();
143- PyObject * eventcodes = 0 ;
144- PyObject * capability = 0 ;
145-
146- int ret = PyArg_ParseTuple (args , "ii" , & fd , & nophys );
147- if (!ret ) return NULL ;
146+ PyObject * eventcodes = NULL ;
147+ PyObject * capability = NULL ;
148148
149- memset (& iid , 0 , sizeof (iid ));
150- memset (& ev_mask , 0 , sizeof (ev_mask ));
149+ memset (& ev_bits , 0 , sizeof (ev_bits ));
151150
152- if (ioctl (fd , EVIOCGID , & iid ) < 0 ) goto on_err ;
153- if (ioctl (fd , EVIOCGNAME (sizeof (name )), name ) < 0 ) goto on_err ;
154- if (ioctl (fd , EVIOCGBIT (0 , EV_MAX ), ev_mask ) < 0 ) goto on_err ;
151+ if (ioctl (_fd , EVIOCGBIT (0 , EV_MAX ), ev_bits ) < 0 )
152+ goto on_err ;
155153
156154 // Build a dictionary of the device's capabilities
157155 for (i = 0 ; i < EV_MAX ; i ++ ) {
158- if (test_bit (ev_mask , i )) {
156+ if (test_bit (ev_bits , i )) {
159157 capability = PyLong_FromLong (i );
160158 eventcodes = PyList_New (0 );
161159
162- memset (& key_mask , 0 , sizeof (key_mask ));
163- ioctl (fd , EVIOCGBIT (i , KEY_MAX ), key_mask );
164- for (j = 0 ; j < KEY_MAX ; j ++ )
165- if (test_bit (key_mask , j ))
160+ memset (& code_bits , 0 , sizeof (code_bits ));
161+ ioctl (_fd , EVIOCGBIT (i , KEY_MAX ), code_bits );
162+ for (j = 0 ; j < KEY_MAX ; j ++ ) {
163+ if (test_bit (code_bits , j )) {
166164 PyList_Append (eventcodes , PyLong_FromLong (j ));
165+ }
166+ }
167167
168168 PyDict_SetItem (capabilities , capability , eventcodes );
169169 }
170170 }
171171
172+ return Py_BuildValue ("O" , capabilities );
173+
174+ on_err :
175+ PyErr_SetFromErrno (PyExc_IOError );
176+ return NULL ;
177+ }
178+
179+
180+ // An all-in-one function for describing an input device
181+ static PyObject *
182+ ioctl_devinfo (PyObject * self , PyObject * args )
183+ {
184+ int fd , nophys ;
185+ PyObject * capabilities = NULL ;
186+
187+ struct input_id iid ;
188+ char name [MAX_NAME_SIZE ];
189+ char phys [MAX_NAME_SIZE ];
190+
191+ int ret = PyArg_ParseTuple (args , "ii" , & fd , & nophys );
192+ if (!ret ) return NULL ;
193+
194+ memset (& iid , 0 , sizeof (iid ));
195+
196+ if (ioctl (fd , EVIOCGID , & iid ) < 0 ) goto on_err ;
197+ if (ioctl (fd , EVIOCGNAME (sizeof (name )), name ) < 0 ) goto on_err ;
198+
199+ // Get device capabilities
200+ capabilities = ioctl_capabilities (self , Py_BuildValue ("(i)" , fd ));
201+
172202 // Uinput devices do not have a physical topology associated with them
173- if (!nophys )
174- if (ioctl (fd , EVIOCGPHYS (sizeof (phys )), phys ) < 0 ) goto on_err ;
175- else
203+ if (!nophys ) {
204+ if (ioctl (fd , EVIOCGPHYS (sizeof (phys )), phys ) < 0 )
205+ goto on_err ;
206+ } else
176207 phys [0 ] = ' ' ;
177208
178209 return Py_BuildValue ("hhhhssO" , iid .bustype , iid .vendor , iid .product , iid .version ,
@@ -183,11 +214,13 @@ ioctl_devinfo(PyObject *self, PyObject *args)
183214 return NULL ;
184215}
185216
217+
186218static PyMethodDef MethodTable [] = {
187- { "unpack" , event_unpack , METH_VARARGS , "unpack a single input event" },
188- { "ioctl_devinfo" , ioctl_devinfo , METH_VARARGS , "fetch input device info" },
189- { "device_read" , device_read , METH_VARARGS , "read an input event from a device" },
190- { "device_read_many" , device_read_many , METH_VARARGS , "read all available input events from a device" },
219+ { "unpack" , event_unpack , METH_VARARGS , "unpack a single input event" },
220+ { "ioctl_devinfo" , ioctl_devinfo , METH_VARARGS , "fetch input device info" },
221+ { "ioctl_capabilities" , ioctl_capabilities , METH_VARARGS , "fetch input device capabilities" },
222+ { "device_read" , device_read , METH_VARARGS , "read an input event from a device" },
223+ { "device_read_many" , device_read_many , METH_VARARGS , "read all available input events from a device" },
191224
192225 { NULL , NULL , 0 , NULL }
193226};
0 commit comments