1
/*****************************************************************************
3
* evemu - Kernel device emulation
5
* Copyright (C) 2010, 2011 Canonical Ltd.
7
* This program is free software: you can redistribute it and/or modify it
8
* under the terms of the GNU General Public License as published by the
9
* Free Software Foundation, either version 3 of the License, or (at your
10
* option) any later version.
12
* This program is distributed in the hope that it will be useful, but
13
* WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* General Public License for more details.
17
* You should have received a copy of the GNU General Public License along
18
* with this program. If not, see <http://www.gnu.org/licenses/>.
20
* Copyright (C) 2010 Henrik Rydberg <rydberg@euromail.se>
22
* Permission is hereby granted, free of charge, to any person obtaining a
23
* copy of this software and associated documentation files (the "Software"),
24
* to deal in the Software without restriction, including without limitation
25
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
26
* and/or sell copies of the Software, and to permit persons to whom the
27
* Software is furnished to do so, subject to the following conditions:
29
* The above copyright notice and this permission notice (including the next
30
* paragraph) shall be included in all copies or substantial portions of the
33
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
36
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
38
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
39
* DEALINGS IN THE SOFTWARE.
41
****************************************************************************/
43
#include "evemu-impl.h"
53
#ifndef UI_SET_PROPBIT
54
#define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
55
#define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len)
56
#define INPUT_PROP_POINTER 0x00
57
#define INPUT_PROP_DIRECT 0x01
58
#define INPUT_PROP_BUTTONPAD 0x02
59
#define INPUT_PROP_SEMI_MT 0x03
60
#define INPUT_PROP_MAX 0x1f
61
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
64
#define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
66
static void copy_bits(unsigned char *mask, const unsigned long *bits, int bytes)
69
for (i = 0; i < bytes; i++) {
70
int pos = 8 * (i % sizeof(long));
71
mask[i] = (bits[i / sizeof(long)] >> pos) & 0xff;
75
struct evemu_device *evemu_new(const char *name)
77
struct evemu_device *dev = calloc(1, sizeof(struct evemu_device));
80
dev->version = EVEMU_VERSION;
81
evemu_set_name(dev, name);
87
void evemu_delete(struct evemu_device *dev)
92
unsigned int evemu_get_version(const struct evemu_device *dev)
97
const char *evemu_get_name(const struct evemu_device *dev)
102
void evemu_set_name(struct evemu_device *dev, const char *name)
104
if (name && strlen(name) < sizeof(dev->name))
105
strcpy(dev->name, name);
108
unsigned int evemu_get_id_bustype(const struct evemu_device *dev)
110
return dev->id.bustype;
113
unsigned int evemu_get_id_vendor(const struct evemu_device *dev)
115
return dev->id.vendor;
118
unsigned int evemu_get_id_product(const struct evemu_device *dev)
120
return dev->id.product;
123
unsigned int evemu_get_id_version(const struct evemu_device *dev)
125
return dev->id.version;
128
int evemu_get_abs_minimum(const struct evemu_device *dev, int code)
130
return dev->abs[code].minimum;
133
int evemu_get_abs_maximum(const struct evemu_device *dev, int code)
135
return dev->abs[code].maximum;
138
int evemu_get_abs_fuzz(const struct evemu_device *dev, int code)
140
return dev->abs[code].fuzz;
143
int evemu_get_abs_flat(const struct evemu_device *dev, int code)
145
return dev->abs[code].flat;
148
int evemu_get_abs_resolution(const struct evemu_device *dev, int code)
150
return dev->abs[code].resolution;
153
int evemu_has_prop(const struct evemu_device *dev, int code)
155
return (dev->prop[code >> 3] >> (code & 7)) & 1;
158
int evemu_has_event(const struct evemu_device *dev, int type, int code)
160
return (dev->mask[type][code >> 3] >> (code & 7)) & 1;
163
int evemu_extract(struct evemu_device *dev, int fd)
165
unsigned long bits[64];
168
memset(dev, 0, sizeof(*dev));
170
SYSCALL(rc = ioctl(fd, EVIOCGNAME(sizeof(dev->name)), dev->name));
173
for (i = 0; i < sizeof(dev->name); i++)
174
if (isspace(dev->name[i]))
177
SYSCALL(rc = ioctl(fd, EVIOCGID, &dev->id));
181
SYSCALL(rc = ioctl(fd, EVIOCGPROP(sizeof(bits)), bits));
183
copy_bits(dev->prop, bits, rc);
187
for (i = 0; i < EV_CNT; i++) {
188
SYSCALL(rc = ioctl(fd, EVIOCGBIT(i, sizeof(bits)), bits));
191
copy_bits(dev->mask[i], bits, rc);
195
for (i = 0; i < ABS_CNT; i++) {
196
if (!evemu_has_event(dev, EV_ABS, i))
198
SYSCALL(rc = ioctl(fd, EVIOCGABS(i), &dev->abs[i]));
206
static void write_prop(FILE * fp, const unsigned char *mask, int bytes)
209
for (i = 0; i < bytes; i += 8)
210
fprintf(fp, "P: %02x %02x %02x %02x %02x %02x %02x %02x\n",
211
mask[i], mask[i + 1], mask[i + 2], mask[i + 3],
212
mask[i + 4], mask[i + 5], mask[i + 6], mask[i + 7]);
215
static void write_mask(FILE * fp, int index,
216
const unsigned char *mask, int bytes)
219
for (i = 0; i < bytes; i += 8)
220
fprintf(fp, "B: %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
221
index, mask[i], mask[i + 1], mask[i + 2], mask[i + 3],
222
mask[i + 4], mask[i + 5], mask[i + 6], mask[i + 7]);
225
static void write_abs(FILE *fp, int index, const struct input_absinfo *abs)
227
fprintf(fp, "A: %02x %d %d %d %d\n", index,
228
abs->minimum, abs->maximum, abs->fuzz, abs->flat);
231
int evemu_write(const struct evemu_device *dev, FILE *fp)
235
fprintf(fp, "N: %s\n", dev->name);
237
fprintf(fp, "I: %04x %04x %04x %04x\n",
238
dev->id.bustype, dev->id.vendor,
239
dev->id.product, dev->id.version);
241
write_prop(fp, dev->prop, dev->pbytes);
243
for (i = 0; i < EV_CNT; i++)
244
write_mask(fp, i, dev->mask[i], dev->mbytes[i]);
246
for (i = 0; i < ABS_CNT; i++)
247
if (evemu_has_event(dev, EV_ABS, i))
248
write_abs(fp, i, &dev->abs[i]);
253
static void read_prop(struct evemu_device *dev, FILE *fp)
255
unsigned int mask[8];
257
while (fscanf(fp, "P: %02x %02x %02x %02x %02x %02x %02x %02x\n",
258
mask + 0, mask + 1, mask + 2, mask + 3,
259
mask + 4, mask + 5, mask + 6, mask + 7) > 0) {
260
for (i = 0; i < 8; i++)
261
dev->prop[dev->pbytes++] = mask[i];
265
static void read_mask(struct evemu_device *dev, FILE *fp)
267
unsigned int mask[8];
269
while (fscanf(fp, "B: %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
270
&index, mask + 0, mask + 1, mask + 2, mask + 3,
271
mask + 4, mask + 5, mask + 6, mask + 7) > 0) {
272
for (i = 0; i < 8; i++)
273
dev->mask[index][dev->mbytes[index]++] = mask[i];
277
static void read_abs(struct evemu_device *dev, FILE *fp)
279
struct input_absinfo abs;
281
while (fscanf(fp, "A: %02x %d %d %d %d\n", &index,
282
&abs.minimum, &abs.maximum, &abs.fuzz, &abs.flat) > 0)
283
dev->abs[index] = abs;
286
int evemu_read(struct evemu_device *dev, FILE *fp)
288
unsigned bustype, vendor, product, version;
291
memset(dev, 0, sizeof(*dev));
293
ret = fscanf(fp, "N: %s\n", dev->name);
297
ret = fscanf(fp, "I: %04x %04x %04x %04x\n",
298
&bustype, &vendor, &product, &version);
302
dev->id.bustype = bustype;
303
dev->id.vendor = vendor;
304
dev->id.product = product;
305
dev->id.version = version;
316
int evemu_write_event(FILE *fp, const struct input_event *ev)
318
return fprintf(fp, "E: %lu.%06u %04x %04x %d\n",
319
ev->time.tv_sec, (unsigned)ev->time.tv_usec,
320
ev->type, ev->code, ev->value);
323
int evemu_record(FILE *fp, int fd, int ms)
325
struct pollfd fds = { fd, POLLIN, 0 };
326
struct input_event ev;
329
while (poll(&fds, 1, ms) > 0) {
330
SYSCALL(ret = read(fd, &ev, sizeof(ev)));
333
if (ret == sizeof(ev))
334
evemu_write_event(fp, &ev);
340
int evemu_read_event(FILE *fp, struct input_event *ev)
343
unsigned usec, type, code;
345
int ret = fscanf(fp, "E: %lu.%06u %04x %04x %d\n",
346
&sec, &usec, &type, &code, &value);
347
ev->time.tv_sec = sec;
348
ev->time.tv_usec = usec;
355
int evemu_read_event_realtime(FILE *fp, struct input_event *ev,
356
struct timeval *evtime)
361
ret = evemu_read_event(fp, ev);
368
usec = 1000000L * (ev->time.tv_sec - evtime->tv_sec);
369
usec += ev->time.tv_usec - evtime->tv_usec;
379
int evemu_play(FILE *fp, int fd)
381
struct input_event ev;
382
struct timeval evtime;
385
memset(&evtime, 0, sizeof(evtime));
386
while (evemu_read_event_realtime(fp, &ev, &evtime) > 0)
387
SYSCALL(ret = write(fd, &ev, sizeof(ev)));
392
static int set_prop_bit(int fd, int code)
395
SYSCALL(ret = ioctl(fd, UI_SET_PROPBIT, code));
399
static int set_event_bit(int fd, int type, int code)
405
SYSCALL(ret = ioctl(fd, UI_SET_EVBIT, code));
408
SYSCALL(ret = ioctl(fd, UI_SET_KEYBIT, code));
411
SYSCALL(ret = ioctl(fd, UI_SET_RELBIT, code));
414
SYSCALL(ret = ioctl(fd, UI_SET_ABSBIT, code));
417
SYSCALL(ret = ioctl(fd, UI_SET_MSCBIT, code));
420
SYSCALL(ret = ioctl(fd, UI_SET_LEDBIT, code));
423
SYSCALL(ret = ioctl(fd, UI_SET_SNDBIT, code));
426
SYSCALL(ret = ioctl(fd, UI_SET_FFBIT, code));
429
SYSCALL(ret = ioctl(fd, UI_SET_SWBIT, code));
436
static int set_prop(const struct evemu_device *dev, int fd)
438
int bits = 8 * dev->pbytes;
440
for (i = 0; i < bits; i++) {
441
if (!evemu_has_prop(dev, i))
443
ret = set_prop_bit(fd, i);
450
static int set_mask(const struct evemu_device *dev, int type, int fd)
452
int bits = 8 * dev->mbytes[type];
454
for (i = 0; i < bits; i++) {
455
if (!evemu_has_event(dev, type, i))
457
ret = set_event_bit(fd, type, i);
464
int evemu_create(const struct evemu_device *dev, int fd)
466
struct uinput_user_dev udev;
469
memset(&udev, 0, sizeof(udev));
470
memcpy(udev.name, dev->name, sizeof(udev.name));
472
for (i = 0; i < ABS_CNT; i++) {
473
if (!evemu_has_event(dev, EV_ABS, i))
475
udev.absmax[i] = dev->abs[i].maximum;
476
udev.absmin[i] = dev->abs[i].minimum;
477
udev.absfuzz[i] = dev->abs[i].fuzz;
478
udev.absflat[i] = dev->abs[i].flat;
481
ret = set_prop(dev, fd);
485
for (i = 0; i < EV_CNT; i++) {
486
ret = set_mask(dev, i, fd);
491
SYSCALL(ret = write(fd, &udev, sizeof(udev)));
495
SYSCALL(ret = ioctl(fd, UI_DEV_CREATE, NULL));
499
void evemu_destroy(int fd)
502
SYSCALL(ret = ioctl(fd, UI_DEV_DESTROY, NULL));