~oif-packaging/evemu/oneiric

« back to all changes in this revision

Viewing changes to src/evemu.c

  • Committer: Francis Ginther
  • Date: 2012-08-20 16:17:58 UTC
  • mfrom: (0.1.32 1.0.5)
  • mto: (14.1.2 oneiric)
  • mto: This revision was merged to the branch mainline in revision 15.
  • Revision ID: francis.ginther@canonical.com-20120820161758-5ht9bd2rgdg3v6hj
Tags: upstream-1.0.5.1
ImportĀ upstreamĀ versionĀ 1.0.5.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 *
3
 
 * evemu - Kernel device emulation
4
 
 *
5
 
 * Copyright (C) 2010, 2011 Canonical Ltd.
6
 
 *
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.
11
 
 *
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.
16
 
 *
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/>.
19
 
 *
20
 
 * Copyright (C) 2010 Henrik Rydberg <rydberg@euromail.se>
21
 
 *
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:
28
 
 *
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
31
 
 * Software.
32
 
 *
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.
40
 
 *
41
 
 ****************************************************************************/
42
 
 
43
 
#include "evemu-impl.h"
44
 
#include <stdlib.h>
45
 
#include <string.h>
46
 
#include <stdio.h>
47
 
#include <fcntl.h>
48
 
#include <errno.h>
49
 
#include <poll.h>
50
 
#include <ctype.h>
51
 
#include <unistd.h>
52
 
 
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)
62
 
#endif
63
 
 
64
 
#define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
65
 
 
66
 
static void copy_bits(unsigned char *mask, const unsigned long *bits, int bytes)
67
 
{
68
 
        int i;
69
 
        for (i = 0; i < bytes; i++) {
70
 
                int pos = 8 * (i % sizeof(long));
71
 
                mask[i] = (bits[i / sizeof(long)] >> pos) & 0xff;
72
 
        }
73
 
}
74
 
 
75
 
struct evemu_device *evemu_new(const char *name)
76
 
{
77
 
        struct evemu_device *dev = calloc(1, sizeof(struct evemu_device));
78
 
 
79
 
        if (dev) {
80
 
                dev->version = EVEMU_VERSION;
81
 
                evemu_set_name(dev, name);
82
 
        }
83
 
 
84
 
        return dev;
85
 
}
86
 
 
87
 
void evemu_delete(struct evemu_device *dev)
88
 
{
89
 
        free(dev);
90
 
}
91
 
 
92
 
unsigned int evemu_get_version(const struct evemu_device *dev)
93
 
{
94
 
        return dev->version;
95
 
}
96
 
 
97
 
const char *evemu_get_name(const struct evemu_device *dev)
98
 
{
99
 
        return dev->name;
100
 
}
101
 
 
102
 
void evemu_set_name(struct evemu_device *dev, const char *name)
103
 
{
104
 
        if (name && strlen(name) < sizeof(dev->name))
105
 
                strcpy(dev->name, name);
106
 
}
107
 
 
108
 
unsigned int evemu_get_id_bustype(const struct evemu_device *dev)
109
 
{
110
 
        return dev->id.bustype;
111
 
}
112
 
 
113
 
unsigned int evemu_get_id_vendor(const struct evemu_device *dev)
114
 
{
115
 
        return dev->id.vendor;
116
 
}
117
 
 
118
 
unsigned int evemu_get_id_product(const struct evemu_device *dev)
119
 
{
120
 
        return dev->id.product;
121
 
}
122
 
 
123
 
unsigned int evemu_get_id_version(const struct evemu_device *dev)
124
 
{
125
 
        return dev->id.version;
126
 
}
127
 
 
128
 
int evemu_get_abs_minimum(const struct evemu_device *dev, int code)
129
 
{
130
 
        return dev->abs[code].minimum;
131
 
}
132
 
 
133
 
int evemu_get_abs_maximum(const struct evemu_device *dev, int code)
134
 
{
135
 
        return dev->abs[code].maximum;
136
 
}
137
 
 
138
 
int evemu_get_abs_fuzz(const struct evemu_device *dev, int code)
139
 
{
140
 
        return dev->abs[code].fuzz;
141
 
}
142
 
 
143
 
int evemu_get_abs_flat(const struct evemu_device *dev, int code)
144
 
{
145
 
        return dev->abs[code].flat;
146
 
}
147
 
 
148
 
int evemu_get_abs_resolution(const struct evemu_device *dev, int code)
149
 
{
150
 
        return dev->abs[code].resolution;
151
 
}
152
 
 
153
 
int evemu_has_prop(const struct evemu_device *dev, int code)
154
 
{
155
 
        return (dev->prop[code >> 3] >> (code & 7)) & 1;
156
 
}
157
 
 
158
 
int evemu_has_event(const struct evemu_device *dev, int type, int code)
159
 
{
160
 
        return (dev->mask[type][code >> 3] >> (code & 7)) & 1;
161
 
}
162
 
 
163
 
int evemu_extract(struct evemu_device *dev, int fd)
164
 
{
165
 
        unsigned long bits[64];
166
 
        int rc, i;
167
 
 
168
 
        memset(dev, 0, sizeof(*dev));
169
 
 
170
 
        SYSCALL(rc = ioctl(fd, EVIOCGNAME(sizeof(dev->name)), dev->name));
171
 
        if (rc < 0)
172
 
                return rc;
173
 
        for (i = 0; i < sizeof(dev->name); i++)
174
 
                if (isspace(dev->name[i]))
175
 
                        dev->name[i] = '-';
176
 
 
177
 
        SYSCALL(rc = ioctl(fd, EVIOCGID, &dev->id));
178
 
        if (rc < 0)
179
 
                return rc;
180
 
 
181
 
        SYSCALL(rc = ioctl(fd, EVIOCGPROP(sizeof(bits)), bits));
182
 
        if (rc >= 0) {
183
 
                copy_bits(dev->prop, bits, rc);
184
 
                dev->pbytes = rc;
185
 
        }
186
 
 
187
 
        for (i = 0; i < EV_CNT; i++) {
188
 
                SYSCALL(rc = ioctl(fd, EVIOCGBIT(i, sizeof(bits)), bits));
189
 
                if (rc < 0)
190
 
                        continue;
191
 
                copy_bits(dev->mask[i], bits, rc);
192
 
                dev->mbytes[i] = rc;
193
 
        }
194
 
 
195
 
        for (i = 0; i < ABS_CNT; i++) {
196
 
                if (!evemu_has_event(dev, EV_ABS, i))
197
 
                        continue;
198
 
                SYSCALL(rc = ioctl(fd, EVIOCGABS(i), &dev->abs[i]));
199
 
                if (rc < 0)
200
 
                        return rc;
201
 
        }
202
 
 
203
 
        return 0;
204
 
}
205
 
 
206
 
static void write_prop(FILE * fp, const unsigned char *mask, int bytes)
207
 
{
208
 
        int i;
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]);
213
 
}
214
 
 
215
 
static void write_mask(FILE * fp, int index,
216
 
                       const unsigned char *mask, int bytes)
217
 
{
218
 
        int i;
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]);
223
 
}
224
 
 
225
 
static void write_abs(FILE *fp, int index, const struct input_absinfo *abs)
226
 
{
227
 
        fprintf(fp, "A: %02x %d %d %d %d\n", index,
228
 
                abs->minimum, abs->maximum, abs->fuzz, abs->flat);
229
 
}
230
 
 
231
 
int evemu_write(const struct evemu_device *dev, FILE *fp)
232
 
{
233
 
        int i;
234
 
 
235
 
        fprintf(fp, "N: %s\n", dev->name);
236
 
 
237
 
        fprintf(fp, "I: %04x %04x %04x %04x\n",
238
 
                dev->id.bustype, dev->id.vendor,
239
 
                dev->id.product, dev->id.version);
240
 
 
241
 
        write_prop(fp, dev->prop, dev->pbytes);
242
 
 
243
 
        for (i = 0; i < EV_CNT; i++)
244
 
                write_mask(fp, i, dev->mask[i], dev->mbytes[i]);
245
 
 
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]);
249
 
 
250
 
        return 0;
251
 
}
252
 
 
253
 
static void read_prop(struct evemu_device *dev, FILE *fp)
254
 
{
255
 
        unsigned int mask[8];
256
 
        int i;
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];
262
 
        }
263
 
}
264
 
 
265
 
static void read_mask(struct evemu_device *dev, FILE *fp)
266
 
{
267
 
        unsigned int mask[8];
268
 
        int index, i;
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];
274
 
        }
275
 
}
276
 
 
277
 
static void read_abs(struct evemu_device *dev, FILE *fp)
278
 
{
279
 
        struct input_absinfo abs;
280
 
        int index;
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;
284
 
}
285
 
 
286
 
int evemu_read(struct evemu_device *dev, FILE *fp)
287
 
{
288
 
        unsigned bustype, vendor, product, version;
289
 
        int ret;
290
 
 
291
 
        memset(dev, 0, sizeof(*dev));
292
 
 
293
 
        ret = fscanf(fp, "N: %s\n", dev->name);
294
 
        if (ret <= 0)
295
 
                return ret;
296
 
 
297
 
        ret = fscanf(fp, "I: %04x %04x %04x %04x\n",
298
 
                     &bustype, &vendor, &product, &version);
299
 
        if (ret <= 0)
300
 
                return ret;
301
 
 
302
 
        dev->id.bustype = bustype;
303
 
        dev->id.vendor = vendor;
304
 
        dev->id.product = product;
305
 
        dev->id.version = version;
306
 
 
307
 
        read_prop(dev, fp);
308
 
 
309
 
        read_mask(dev, fp);
310
 
 
311
 
        read_abs(dev, fp);
312
 
 
313
 
        return 1;
314
 
}
315
 
 
316
 
int evemu_write_event(FILE *fp, const struct input_event *ev)
317
 
{
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);
321
 
}
322
 
 
323
 
int evemu_record(FILE *fp, int fd, int ms)
324
 
{
325
 
        struct pollfd fds = { fd, POLLIN, 0 };
326
 
        struct input_event ev;
327
 
        int ret;
328
 
 
329
 
        while (poll(&fds, 1, ms) > 0) {
330
 
                SYSCALL(ret = read(fd, &ev, sizeof(ev)));
331
 
                if (ret < 0)
332
 
                        return ret;
333
 
                if (ret == sizeof(ev))
334
 
                        evemu_write_event(fp, &ev);
335
 
        }
336
 
 
337
 
        return 0;
338
 
}
339
 
 
340
 
int evemu_read_event(FILE *fp, struct input_event *ev)
341
 
{
342
 
        unsigned long sec;
343
 
        unsigned usec, type, code;
344
 
        int value;
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;
349
 
        ev->type = type;
350
 
        ev->code = code;
351
 
        ev->value = value;
352
 
        return ret;
353
 
}
354
 
 
355
 
int evemu_read_event_realtime(FILE *fp, struct input_event *ev,
356
 
                              struct timeval *evtime)
357
 
{
358
 
        unsigned long usec;
359
 
        int ret;
360
 
 
361
 
        ret = evemu_read_event(fp, ev);
362
 
        if (ret <= 0)
363
 
                return ret;
364
 
 
365
 
        if (evtime) {
366
 
                if (!evtime->tv_sec)
367
 
                        *evtime = ev->time;
368
 
                usec = 1000000L * (ev->time.tv_sec - evtime->tv_sec);
369
 
                usec += ev->time.tv_usec - evtime->tv_usec;
370
 
                if (usec > 500) {
371
 
                        usleep(usec);
372
 
                        *evtime = ev->time;
373
 
                }
374
 
        }
375
 
 
376
 
        return ret;
377
 
}
378
 
 
379
 
int evemu_play(FILE *fp, int fd)
380
 
{
381
 
        struct input_event ev;
382
 
        struct timeval evtime;
383
 
        int ret;
384
 
 
385
 
        memset(&evtime, 0, sizeof(evtime));
386
 
        while (evemu_read_event_realtime(fp, &ev, &evtime) > 0)
387
 
                SYSCALL(ret = write(fd, &ev, sizeof(ev)));
388
 
 
389
 
        return 0;
390
 
}
391
 
 
392
 
static int set_prop_bit(int fd, int code)
393
 
{
394
 
        int ret;
395
 
        SYSCALL(ret = ioctl(fd, UI_SET_PROPBIT, code));
396
 
        return ret;
397
 
}
398
 
 
399
 
static int set_event_bit(int fd, int type, int code)
400
 
{
401
 
        int ret = 0;
402
 
 
403
 
        switch(type) {
404
 
        case EV_SYN:
405
 
                SYSCALL(ret = ioctl(fd, UI_SET_EVBIT, code));
406
 
                break;
407
 
        case EV_KEY:
408
 
                SYSCALL(ret = ioctl(fd, UI_SET_KEYBIT, code));
409
 
                break;
410
 
        case EV_REL:
411
 
                SYSCALL(ret = ioctl(fd, UI_SET_RELBIT, code));
412
 
                break;
413
 
        case EV_ABS:
414
 
                SYSCALL(ret = ioctl(fd, UI_SET_ABSBIT, code));
415
 
                break;
416
 
        case EV_MSC:
417
 
                SYSCALL(ret = ioctl(fd, UI_SET_MSCBIT, code));
418
 
                break;
419
 
        case EV_LED:
420
 
                SYSCALL(ret = ioctl(fd, UI_SET_LEDBIT, code));
421
 
                break;
422
 
        case EV_SND:
423
 
                SYSCALL(ret = ioctl(fd, UI_SET_SNDBIT, code));
424
 
                break;
425
 
        case EV_FF:
426
 
                SYSCALL(ret = ioctl(fd, UI_SET_FFBIT, code));
427
 
                break;
428
 
        case EV_SW:
429
 
                SYSCALL(ret = ioctl(fd, UI_SET_SWBIT, code));
430
 
                break;
431
 
        }
432
 
 
433
 
        return ret;
434
 
}
435
 
 
436
 
static int set_prop(const struct evemu_device *dev, int fd)
437
 
{
438
 
        int bits = 8 * dev->pbytes;
439
 
        int ret, i;
440
 
        for (i = 0; i < bits; i++) {
441
 
                if (!evemu_has_prop(dev, i))
442
 
                        continue;
443
 
                ret = set_prop_bit(fd, i);
444
 
                if (ret < 0)
445
 
                        return ret;
446
 
        }
447
 
        return 0;
448
 
}
449
 
 
450
 
static int set_mask(const struct evemu_device *dev, int type, int fd)
451
 
{
452
 
        int bits = 8 * dev->mbytes[type];
453
 
        int ret, i;
454
 
        for (i = 0; i < bits; i++) {
455
 
                if (!evemu_has_event(dev, type, i))
456
 
                        continue;
457
 
                ret = set_event_bit(fd, type, i);
458
 
                if (ret < 0)
459
 
                        return ret;
460
 
        }
461
 
        return 0;
462
 
}
463
 
 
464
 
int evemu_create(const struct evemu_device *dev, int fd)
465
 
{
466
 
        struct uinput_user_dev udev;
467
 
        int ret, i;
468
 
 
469
 
        memset(&udev, 0, sizeof(udev));
470
 
        memcpy(udev.name, dev->name, sizeof(udev.name));
471
 
        udev.id = dev->id;
472
 
        for (i = 0; i < ABS_CNT; i++) {
473
 
                if (!evemu_has_event(dev, EV_ABS, i))
474
 
                        continue;
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;
479
 
        }
480
 
 
481
 
        ret = set_prop(dev, fd);
482
 
        if (ret < 0)
483
 
                return ret;
484
 
 
485
 
        for (i = 0; i < EV_CNT; i++) {
486
 
                ret = set_mask(dev, i, fd);
487
 
                if (ret < 0)
488
 
                        return ret;
489
 
        }
490
 
 
491
 
        SYSCALL(ret = write(fd, &udev, sizeof(udev)));
492
 
        if (ret < 0)
493
 
                return ret;
494
 
 
495
 
        SYSCALL(ret = ioctl(fd, UI_DEV_CREATE, NULL));
496
 
        return ret;
497
 
}
498
 
 
499
 
void evemu_destroy(int fd)
500
 
{
501
 
        int ret;
502
 
        SYSCALL(ret = ioctl(fd, UI_DEV_DESTROY, NULL));
503
 
}