summaryrefslogtreecommitdiff
path: root/src/evemu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/evemu.c')
-rw-r--r--src/evemu.c94
1 files changed, 83 insertions, 11 deletions
diff --git a/src/evemu.c b/src/evemu.c
index 53bda86..32f8f06 100644
--- a/src/evemu.c
+++ b/src/evemu.c
@@ -34,6 +34,17 @@
34#include <errno.h> 34#include <errno.h>
35#include <poll.h> 35#include <poll.h>
36 36
37#ifndef UI_SET_PROPBIT
38#define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
39#define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len)
40#define INPUT_PROP_POINTER 0x00
41#define INPUT_PROP_DIRECT 0x01
42#define INPUT_PROP_BUTTONPAD 0x02
43#define INPUT_PROP_SEMI_MT 0x03
44#define INPUT_PROP_MAX 0x1f
45#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
46#endif
47
37#define SYSCALL(call) while (((call) == -1) && (errno == EINTR)) 48#define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
38 49
39static void copy_bits(unsigned char *mask, const unsigned long *bits, int bytes) 50static void copy_bits(unsigned char *mask, const unsigned long *bits, int bytes)
@@ -68,7 +79,12 @@ const char *evemu_get_name(const struct evemu_device *dev)
68 return dev->name; 79 return dev->name;
69} 80}
70 81
71int evemu_has(const struct evemu_device *dev, int type, int code) 82int evemu_has_prop(const struct evemu_device *dev, int code)
83{
84 return (dev->prop[code >> 3] >> (code & 7)) & 1;
85}
86
87int evemu_has_event(const struct evemu_device *dev, int type, int code)
72{ 88{
73 return (dev->mask[type][code >> 3] >> (code & 7)) & 1; 89 return (dev->mask[type][code >> 3] >> (code & 7)) & 1;
74} 90}
@@ -91,16 +107,22 @@ int evemu_extract(struct evemu_device *dev, int fd)
91 if (rc < 0) 107 if (rc < 0)
92 return rc; 108 return rc;
93 109
110 SYSCALL(rc = ioctl(fd, EVIOCGPROP(sizeof(bits)), bits));
111 if (rc >= 0) {
112 copy_bits(dev->prop, bits, rc);
113 dev->pbytes = rc;
114 }
115
94 for (i = 0; i < EV_CNT; i++) { 116 for (i = 0; i < EV_CNT; i++) {
95 SYSCALL(rc = ioctl(fd, EVIOCGBIT(i, sizeof(bits)), bits)); 117 SYSCALL(rc = ioctl(fd, EVIOCGBIT(i, sizeof(bits)), bits));
96 if (rc < 0) 118 if (rc < 0)
97 continue; 119 continue;
98 copy_bits(dev->mask[i], bits, rc); 120 copy_bits(dev->mask[i], bits, rc);
99 dev->bytes[i] = rc; 121 dev->mbytes[i] = rc;
100 } 122 }
101 123
102 for (i = 0; i < ABS_CNT; i++) { 124 for (i = 0; i < ABS_CNT; i++) {
103 if (!evemu_has(dev, EV_ABS, i)) 125 if (!evemu_has_event(dev, EV_ABS, i))
104 continue; 126 continue;
105 SYSCALL(rc = ioctl(fd, EVIOCGABS(i), &dev->abs[i])); 127 SYSCALL(rc = ioctl(fd, EVIOCGABS(i), &dev->abs[i]));
106 if (rc < 0) 128 if (rc < 0)
@@ -110,6 +132,15 @@ int evemu_extract(struct evemu_device *dev, int fd)
110 return 0; 132 return 0;
111} 133}
112 134
135static void write_prop(FILE * fp, const unsigned char *mask, int bytes)
136{
137 int i;
138 for (i = 0; i < bytes; i += 8)
139 fprintf(fp, "P: %02x %02x %02x %02x %02x %02x %02x %02x\n",
140 mask[i], mask[i + 1], mask[i + 2], mask[i + 3],
141 mask[i + 4], mask[i + 5], mask[i + 6], mask[i + 7]);
142}
143
113static void write_mask(FILE * fp, int index, 144static void write_mask(FILE * fp, int index,
114 const unsigned char *mask, int bytes) 145 const unsigned char *mask, int bytes)
115{ 146{
@@ -136,14 +167,28 @@ int evemu_write(const struct evemu_device *dev, FILE *fp)
136 dev->id.bustype, dev->id.vendor, 167 dev->id.bustype, dev->id.vendor,
137 dev->id.product, dev->id.version); 168 dev->id.product, dev->id.version);
138 169
170 write_prop(fp, dev->prop, dev->pbytes);
171
139 for (i = 0; i < EV_CNT; i++) 172 for (i = 0; i < EV_CNT; i++)
140 write_mask(fp, i, dev->mask[i], dev->bytes[i]); 173 write_mask(fp, i, dev->mask[i], dev->mbytes[i]);
141 174
142 for (i = 0; i < ABS_CNT; i++) 175 for (i = 0; i < ABS_CNT; i++)
143 if (evemu_has(dev, EV_ABS, i)) 176 if (evemu_has_event(dev, EV_ABS, i))
144 write_abs(fp, i, &dev->abs[i]); 177 write_abs(fp, i, &dev->abs[i]);
145} 178}
146 179
180static void read_prop(struct evemu_device *dev, FILE *fp)
181{
182 unsigned int mask[8];
183 int i;
184 while (fscanf(fp, "P: %02x %02x %02x %02x %02x %02x %02x %02x\n",
185 mask + 0, mask + 1, mask + 2, mask + 3,
186 mask + 4, mask + 5, mask + 6, mask + 7) > 0) {
187 for (i = 0; i < 8; i++)
188 dev->prop[dev->pbytes++] = mask[i];
189 }
190}
191
147static void read_mask(struct evemu_device *dev, FILE *fp) 192static void read_mask(struct evemu_device *dev, FILE *fp)
148{ 193{
149 unsigned int mask[8]; 194 unsigned int mask[8];
@@ -152,7 +197,7 @@ static void read_mask(struct evemu_device *dev, FILE *fp)
152 &index, mask + 0, mask + 1, mask + 2, mask + 3, 197 &index, mask + 0, mask + 1, mask + 2, mask + 3,
153 mask + 4, mask + 5, mask + 6, mask + 7) > 0) { 198 mask + 4, mask + 5, mask + 6, mask + 7) > 0) {
154 for (i = 0; i < 8; i++) 199 for (i = 0; i < 8; i++)
155 dev->mask[index][dev->bytes[index]++] = mask[i]; 200 dev->mask[index][dev->mbytes[index]++] = mask[i];
156 } 201 }
157} 202}
158 203
@@ -186,6 +231,8 @@ int evemu_read(struct evemu_device *dev, FILE *fp)
186 dev->id.product = product; 231 dev->id.product = product;
187 dev->id.version = version; 232 dev->id.version = version;
188 233
234 read_prop(dev, fp);
235
189 read_mask(dev, fp); 236 read_mask(dev, fp);
190 237
191 read_abs(dev, fp); 238 read_abs(dev, fp);
@@ -254,7 +301,14 @@ int evemu_play(FILE *fp, int fd)
254 return 0; 301 return 0;
255} 302}
256 303
257static int set_bit(int fd, int type, int code) 304static int set_prop_bit(int fd, int code)
305{
306 int ret;
307 SYSCALL(ret = ioctl(fd, UI_SET_PROPBIT, code));
308 return ret;
309}
310
311static int set_event_bit(int fd, int type, int code)
258{ 312{
259 int ret = 0; 313 int ret = 0;
260 314
@@ -291,14 +345,28 @@ static int set_bit(int fd, int type, int code)
291 return ret; 345 return ret;
292} 346}
293 347
348static int set_prop(const struct evemu_device *dev, int fd)
349{
350 int bits = 8 * dev->pbytes;
351 int ret, i;
352 for (i = 0; i < bits; i++) {
353 if (!evemu_has_prop(dev, i))
354 continue;
355 ret = set_prop_bit(fd, i);
356 if (ret < 0)
357 return ret;
358 }
359 return 0;
360}
361
294static int set_mask(const struct evemu_device *dev, int type, int fd) 362static int set_mask(const struct evemu_device *dev, int type, int fd)
295{ 363{
296 int bits = 8 * dev->bytes[type]; 364 int bits = 8 * dev->mbytes[type];
297 int ret, i; 365 int ret, i;
298 for (i = 0; i < bits; i++) { 366 for (i = 0; i < bits; i++) {
299 if (!evemu_has(dev, type, i)) 367 if (!evemu_has_event(dev, type, i))
300 continue; 368 continue;
301 ret = set_bit(fd, type, i); 369 ret = set_event_bit(fd, type, i);
302 if (ret < 0) 370 if (ret < 0)
303 return ret; 371 return ret;
304 } 372 }
@@ -314,7 +382,7 @@ int evemu_create(const struct evemu_device *dev, int fd)
314 memcpy(udev.name, dev->name, sizeof(udev.name)); 382 memcpy(udev.name, dev->name, sizeof(udev.name));
315 udev.id = dev->id; 383 udev.id = dev->id;
316 for (i = 0; i < ABS_CNT; i++) { 384 for (i = 0; i < ABS_CNT; i++) {
317 if (!evemu_has(dev, EV_ABS, i)) 385 if (!evemu_has_event(dev, EV_ABS, i))
318 continue; 386 continue;
319 udev.absmax[i] = dev->abs[i].maximum; 387 udev.absmax[i] = dev->abs[i].maximum;
320 udev.absmin[i] = dev->abs[i].minimum; 388 udev.absmin[i] = dev->abs[i].minimum;
@@ -322,6 +390,10 @@ int evemu_create(const struct evemu_device *dev, int fd)
322 udev.absflat[i] = dev->abs[i].flat; 390 udev.absflat[i] = dev->abs[i].flat;
323 } 391 }
324 392
393 ret = set_prop(dev, fd);
394 if (ret < 0)
395 return ret;
396
325 for (i = 0; i < EV_CNT; i++) { 397 for (i = 0; i < EV_CNT; i++) {
326 ret = set_mask(dev, i, fd); 398 ret = set_mask(dev, i, fd);
327 if (ret < 0) 399 if (ret < 0)