Merge lp:~oif-team/evemu/trunk.prop into lp:evemu

Proposed by Henrik Rydberg
Status: Merged
Merged at revision: 11
Proposed branch: lp:~oif-team/evemu/trunk.prop
Merge into: lp:evemu
Diff against target: 450 lines (+199/-66)
6 files modified
include/evemu.h (+15/-20)
src/evemu-impl.h (+20/-0)
src/evemu.c (+112/-11)
tools/evemu-describe.c (+12/-7)
tools/evemu-device.c (+28/-20)
tools/evemu-echo.c (+12/-8)
To merge this branch: bzr merge lp:~oif-team/evemu/trunk.prop
Reviewer Review Type Date Requested Status
Chase Douglas (community) Approve
Review via email: mp+44372@code.launchpad.net

Description of the change

Support the upcoming device properties.

To post a comment you must log in.
Revision history for this message
Chase Douglas (chasedouglas) wrote :

Seems good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/evemu.h'
2--- include/evemu.h 2010-09-18 17:10:11 +0000
3+++ include/evemu.h 2010-12-21 17:21:49 +0000
4@@ -26,28 +26,23 @@
5 *
6 ****************************************************************************/
7
8-#ifndef _EVPLAY_H
9-#define _EVPLAY_H
10+#ifndef _EVEMU_H
11+#define _EVEMU_H
12
13-#include <linux/uinput.h>
14 #include <stdio.h>
15-
16-#define EVPLAY_NBITS KEY_CNT
17-#define EVPLAY_NBYTES ((EVPLAY_NBITS + 7) / 8)
18-
19-struct evemu_device {
20- char name[UINPUT_MAX_NAME_SIZE];
21- struct input_id id;
22- unsigned char mask[EV_CNT][EVPLAY_NBYTES];
23- int bytes[EV_CNT];
24- struct input_absinfo abs[ABS_CNT];
25-};
26-
27-static inline int evemu_has(const struct evemu_device *dev,
28- int type, int code)
29-{
30- return (dev->mask[type][code >> 3] >> (code & 7)) & 1;
31-}
32+#include <errno.h>
33+#include <linux/input.h>
34+
35+#define EVEMU_VERSION_MAJOR 1
36+#define EVEMU_VERSION_MINOR 1
37+
38+struct evemu_device *evemu_new(const char *name);
39+void evemu_delete(struct evemu_device *dev);
40+
41+const char *evemu_get_name(const struct evemu_device *dev);
42+
43+int evemu_has_prop(const struct evemu_device *dev, int code);
44+int evemu_has_event(const struct evemu_device *dev, int type, int code);
45
46 int evemu_extract(struct evemu_device *dev, int fd);
47 int evemu_write(const struct evemu_device *dev, FILE *fp);
48
49=== added file 'src/evemu-impl.h'
50--- src/evemu-impl.h 1970-01-01 00:00:00 +0000
51+++ src/evemu-impl.h 2010-12-21 17:21:49 +0000
52@@ -0,0 +1,20 @@
53+#ifndef _EVEMU_IMPL_H
54+#define _EVEMU_IMPL_H
55+
56+#include <evemu.h>
57+#include <linux/uinput.h>
58+
59+#define EVPLAY_NBITS KEY_CNT
60+#define EVPLAY_NBYTES ((EVPLAY_NBITS + 7) / 8)
61+
62+struct evemu_device {
63+ int version_major, version_minor;
64+ char name[UINPUT_MAX_NAME_SIZE];
65+ struct input_id id;
66+ unsigned char prop[EVPLAY_NBYTES];
67+ unsigned char mask[EV_CNT][EVPLAY_NBYTES];
68+ int pbytes, mbytes[EV_CNT];
69+ struct input_absinfo abs[ABS_CNT];
70+};
71+
72+#endif
73
74=== modified file 'src/evemu.c'
75--- src/evemu.c 2010-09-19 07:54:48 +0000
76+++ src/evemu.c 2010-12-21 17:21:49 +0000
77@@ -26,13 +26,25 @@
78 *
79 ****************************************************************************/
80
81-#include "evemu.h"
82+#include "evemu-impl.h"
83+#include <stdlib.h>
84 #include <string.h>
85 #include <stdio.h>
86 #include <fcntl.h>
87 #include <errno.h>
88 #include <poll.h>
89
90+#ifndef UI_SET_PROPBIT
91+#define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
92+#define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len)
93+#define INPUT_PROP_POINTER 0x00
94+#define INPUT_PROP_DIRECT 0x01
95+#define INPUT_PROP_BUTTONPAD 0x02
96+#define INPUT_PROP_SEMI_MT 0x03
97+#define INPUT_PROP_MAX 0x1f
98+#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
99+#endif
100+
101 #define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
102
103 static void copy_bits(unsigned char *mask, const unsigned long *bits, int bytes)
104@@ -44,6 +56,39 @@
105 }
106 }
107
108+struct evemu_device *evemu_new(const char *name)
109+{
110+ struct evemu_device *dev = calloc(1, sizeof(struct evemu_device));
111+
112+ dev->version_major = EVEMU_VERSION_MAJOR;
113+ dev->version_minor = EVEMU_VERSION_MINOR;
114+
115+ if (name && strlen(name) < sizeof(dev->name))
116+ strcpy(dev->name, name);
117+
118+ return dev;
119+}
120+
121+void evemu_delete(struct evemu_device *dev)
122+{
123+ free(dev);
124+}
125+
126+const char *evemu_get_name(const struct evemu_device *dev)
127+{
128+ return dev->name;
129+}
130+
131+int evemu_has_prop(const struct evemu_device *dev, int code)
132+{
133+ return (dev->prop[code >> 3] >> (code & 7)) & 1;
134+}
135+
136+int evemu_has_event(const struct evemu_device *dev, int type, int code)
137+{
138+ return (dev->mask[type][code >> 3] >> (code & 7)) & 1;
139+}
140+
141 int evemu_extract(struct evemu_device *dev, int fd)
142 {
143 unsigned long bits[64];
144@@ -62,16 +107,22 @@
145 if (rc < 0)
146 return rc;
147
148+ SYSCALL(rc = ioctl(fd, EVIOCGPROP(sizeof(bits)), bits));
149+ if (rc >= 0) {
150+ copy_bits(dev->prop, bits, rc);
151+ dev->pbytes = rc;
152+ }
153+
154 for (i = 0; i < EV_CNT; i++) {
155 SYSCALL(rc = ioctl(fd, EVIOCGBIT(i, sizeof(bits)), bits));
156 if (rc < 0)
157 continue;
158 copy_bits(dev->mask[i], bits, rc);
159- dev->bytes[i] = rc;
160+ dev->mbytes[i] = rc;
161 }
162
163 for (i = 0; i < ABS_CNT; i++) {
164- if (!evemu_has(dev, EV_ABS, i))
165+ if (!evemu_has_event(dev, EV_ABS, i))
166 continue;
167 SYSCALL(rc = ioctl(fd, EVIOCGABS(i), &dev->abs[i]));
168 if (rc < 0)
169@@ -81,6 +132,15 @@
170 return 0;
171 }
172
173+static void write_prop(FILE * fp, const unsigned char *mask, int bytes)
174+{
175+ int i;
176+ for (i = 0; i < bytes; i += 8)
177+ fprintf(fp, "P: %02x %02x %02x %02x %02x %02x %02x %02x\n",
178+ mask[i], mask[i + 1], mask[i + 2], mask[i + 3],
179+ mask[i + 4], mask[i + 5], mask[i + 6], mask[i + 7]);
180+}
181+
182 static void write_mask(FILE * fp, int index,
183 const unsigned char *mask, int bytes)
184 {
185@@ -107,14 +167,28 @@
186 dev->id.bustype, dev->id.vendor,
187 dev->id.product, dev->id.version);
188
189+ write_prop(fp, dev->prop, dev->pbytes);
190+
191 for (i = 0; i < EV_CNT; i++)
192- write_mask(fp, i, dev->mask[i], dev->bytes[i]);
193+ write_mask(fp, i, dev->mask[i], dev->mbytes[i]);
194
195 for (i = 0; i < ABS_CNT; i++)
196- if (evemu_has(dev, EV_ABS, i))
197+ if (evemu_has_event(dev, EV_ABS, i))
198 write_abs(fp, i, &dev->abs[i]);
199 }
200
201+static void read_prop(struct evemu_device *dev, FILE *fp)
202+{
203+ unsigned int mask[8];
204+ int i;
205+ while (fscanf(fp, "P: %02x %02x %02x %02x %02x %02x %02x %02x\n",
206+ mask + 0, mask + 1, mask + 2, mask + 3,
207+ mask + 4, mask + 5, mask + 6, mask + 7) > 0) {
208+ for (i = 0; i < 8; i++)
209+ dev->prop[dev->pbytes++] = mask[i];
210+ }
211+}
212+
213 static void read_mask(struct evemu_device *dev, FILE *fp)
214 {
215 unsigned int mask[8];
216@@ -123,7 +197,7 @@
217 &index, mask + 0, mask + 1, mask + 2, mask + 3,
218 mask + 4, mask + 5, mask + 6, mask + 7) > 0) {
219 for (i = 0; i < 8; i++)
220- dev->mask[index][dev->bytes[index]++] = mask[i];
221+ dev->mask[index][dev->mbytes[index]++] = mask[i];
222 }
223 }
224
225@@ -157,6 +231,8 @@
226 dev->id.product = product;
227 dev->id.version = version;
228
229+ read_prop(dev, fp);
230+
231 read_mask(dev, fp);
232
233 read_abs(dev, fp);
234@@ -225,7 +301,14 @@
235 return 0;
236 }
237
238-static int set_bit(int fd, int type, int code)
239+static int set_prop_bit(int fd, int code)
240+{
241+ int ret;
242+ SYSCALL(ret = ioctl(fd, UI_SET_PROPBIT, code));
243+ return ret;
244+}
245+
246+static int set_event_bit(int fd, int type, int code)
247 {
248 int ret = 0;
249
250@@ -262,14 +345,28 @@
251 return ret;
252 }
253
254+static int set_prop(const struct evemu_device *dev, int fd)
255+{
256+ int bits = 8 * dev->pbytes;
257+ int ret, i;
258+ for (i = 0; i < bits; i++) {
259+ if (!evemu_has_prop(dev, i))
260+ continue;
261+ ret = set_prop_bit(fd, i);
262+ if (ret < 0)
263+ return ret;
264+ }
265+ return 0;
266+}
267+
268 static int set_mask(const struct evemu_device *dev, int type, int fd)
269 {
270- int bits = 8 * dev->bytes[type];
271+ int bits = 8 * dev->mbytes[type];
272 int ret, i;
273 for (i = 0; i < bits; i++) {
274- if (!evemu_has(dev, type, i))
275+ if (!evemu_has_event(dev, type, i))
276 continue;
277- ret = set_bit(fd, type, i);
278+ ret = set_event_bit(fd, type, i);
279 if (ret < 0)
280 return ret;
281 }
282@@ -285,7 +382,7 @@
283 memcpy(udev.name, dev->name, sizeof(udev.name));
284 udev.id = dev->id;
285 for (i = 0; i < ABS_CNT; i++) {
286- if (!evemu_has(dev, EV_ABS, i))
287+ if (!evemu_has_event(dev, EV_ABS, i))
288 continue;
289 udev.absmax[i] = dev->abs[i].maximum;
290 udev.absmin[i] = dev->abs[i].minimum;
291@@ -293,6 +390,10 @@
292 udev.absflat[i] = dev->abs[i].flat;
293 }
294
295+ ret = set_prop(dev, fd);
296+ if (ret < 0)
297+ return ret;
298+
299 for (i = 0; i < EV_CNT; i++) {
300 ret = set_mask(dev, i, fd);
301 if (ret < 0)
302
303=== modified file 'tools/evemu-describe.c'
304--- tools/evemu-describe.c 2010-09-18 17:10:11 +0000
305+++ tools/evemu-describe.c 2010-12-21 17:21:49 +0000
306@@ -26,22 +26,27 @@
307 *
308 ****************************************************************************/
309
310-#include "evemu.h"
311+#include <evemu.h>
312 #include <stdio.h>
313 #include <fcntl.h>
314 #include <string.h>
315
316 static int describe_device(int fd)
317 {
318- struct evemu_device dev;
319- int ret;
320+ struct evemu_device *dev;
321+ int ret = -ENOMEM;
322
323- ret = evemu_extract(&dev, fd);
324+ dev = evemu_new(0);
325+ if (!dev)
326+ goto out;
327+ ret = evemu_extract(dev, fd);
328 if (ret)
329- return ret;
330- evemu_write(&dev, stdout);
331+ goto out;
332
333- return 0;
334+ evemu_write(dev, stdout);
335+out:
336+ evemu_delete(dev);
337+ return ret;
338 }
339
340 int main(int argc, char *argv[])
341
342=== modified file 'tools/evemu-device.c'
343--- tools/evemu-device.c 2010-09-23 15:53:46 +0000
344+++ tools/evemu-device.c 2010-12-21 17:21:49 +0000
345@@ -50,7 +50,7 @@
346 ret = read(fd, name, sizeof(name));
347 if (ret > 0)
348 name[ret - 1] = 0;
349- if (!strcmp(dev->name, name))
350+ if (!strcmp(evemu_get_name(dev), name))
351 sprintf(node, "/dev/input/event%d", i + 1);
352 close(fd);
353 }
354@@ -58,7 +58,7 @@
355 fd = open(node, O_RDONLY);
356 if (fd < 0)
357 return;
358- fprintf(stdout, "%s: %s\n", dev->name, node);
359+ fprintf(stdout, "%s: %s\n", evemu_get_name(dev), node);
360 fflush(stdout);
361 while ((ret = read(fd, data, sizeof(data))) > 0);
362 close(fd);
363@@ -66,28 +66,36 @@
364
365 static int evemu_device(FILE *fp)
366 {
367- struct evemu_device dev;
368- int ret, fd;
369-
370- ret = evemu_read(&dev, fp);
371+ struct evemu_device *dev;
372+ char name[64];
373+ int ret = -ENOMEM;
374+ int fd;
375+
376+ sprintf(name, "evemu-%d", getpid());
377+
378+ dev = evemu_new(name);
379+ if (!dev)
380+ goto out;
381+ ret = evemu_read(dev, fp);
382 if (ret <= 0)
383- return ret;
384-
385- sprintf(dev.name, "evemu-%d", getpid());
386-
387- fd = open(UINPUT_NODE, O_WRONLY);
388- if (fd < 0)
389- return fd;
390- ret = evemu_create(&dev, fd);
391- if (ret < 0)
392- return ret;
393-
394- hold_device(&dev);
395-
396+ goto out;
397+
398+ ret = fd = open(UINPUT_NODE, O_WRONLY);
399+ if (ret < 0)
400+ goto out;
401+
402+ ret = evemu_create(dev, fd);
403+ if (ret < 0)
404+ goto out_close;
405+ hold_device(dev);
406 evemu_destroy(fd);
407+
408+out_close:
409 close(fd);
410+out:
411+ evemu_delete(dev);
412
413- return 0;
414+ return ret;
415 }
416
417 int main(int argc, char *argv[])
418
419=== modified file 'tools/evemu-echo.c'
420--- tools/evemu-echo.c 2010-09-18 17:10:11 +0000
421+++ tools/evemu-echo.c 2010-12-21 17:21:49 +0000
422@@ -33,16 +33,20 @@
423
424 static int evemu_echo_describe(FILE *fp)
425 {
426- struct evemu_device dev;
427- int ret;
428+ struct evemu_device *dev;
429+ int ret = -ENOMEM;
430
431- ret = evemu_read(&dev, fp);
432+ dev = evemu_new(0);
433+ if (!dev)
434+ goto out;
435+ ret = evemu_read(dev, fp);
436 if (ret <= 0)
437- return ret;
438-
439- evemu_write(&dev, stdout);
440-
441- return 0;
442+ goto out;
443+
444+ evemu_write(dev, stdout);
445+out:
446+ evemu_delete(dev);
447+ return ret;
448 }
449
450 static int evemu_echo_event(FILE *fp)

Subscribers

People subscribed via source and target branches

to all changes: