Skip to content

Commit f8a4a19

Browse files
committed
factor capability query functionality out of ioctl_devinfo
1 parent 6bed5e0 commit f8a4a19

File tree

1 file changed

+64
-31
lines changed

1 file changed

+64
-31
lines changed

evdev/input.c

Lines changed: 64 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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
130130
static 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+
186218
static 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

Comments
 (0)