tizen 2.4 release
[framework/uifw/libevdev.git] / test / test-common-uinput.c
1 /*
2  * Copyright © 2013 Red Hat, Inc.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22
23 #include <config.h>
24 #include <fcntl.h>
25 #include <poll.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include <errno.h>
30 #include <linux/uinput.h>
31 #include <dirent.h>
32
33 #include <libevdev/libevdev.h>
34 #include <libevdev/libevdev-int.h>
35 #include <libevdev/libevdev-util.h>
36 #include <libevdev/libevdev-uinput.h>
37
38 #include "test-common-uinput.h"
39
40 #define SYS_INPUT_DIR "/sys/class/input"
41 #define DEV_INPUT_DIR "/dev/input/"
42
43 struct uinput_device
44 {
45         struct libevdev *d; /* lazy, it has all the accessors */
46         struct libevdev_uinput *uidev;
47         int dev_fd; /* open fd to the devnode */
48         int uinput_fd;
49 };
50
51 struct uinput_device*
52 uinput_device_new(const char *name)
53 {
54         struct uinput_device *dev;
55
56         dev = calloc(1, sizeof(*dev));
57         if (!dev)
58                 return NULL;
59
60         dev->d = libevdev_new();
61         dev->dev_fd = -1;
62         dev->uinput_fd = -1;
63
64         if (name)
65                 libevdev_set_name(dev->d, name);
66
67         return dev;
68 }
69
70 int
71 uinput_device_new_with_events_v(struct uinput_device **d, const char *name, const struct input_id *id, va_list args)
72 {
73         int rc;
74         struct uinput_device *dev;
75
76         dev = uinput_device_new(name);
77         if (!dev)
78                 return -ENOMEM;
79         if (id != DEFAULT_IDS)
80                 uinput_device_set_ids(dev, id);
81
82         rc = uinput_device_set_event_bits_v(dev, args);
83
84         if (rc == 0)
85                 rc = uinput_device_create(dev);
86
87         if (rc != 0) {
88                 uinput_device_free(dev);
89                 dev = NULL;
90         } else
91                 *d = dev;
92
93         return rc;
94 }
95
96 int
97 uinput_device_new_with_events(struct uinput_device **d, const char *name, const struct input_id *id, ...)
98 {
99         int rc;
100         va_list args;
101
102         va_start(args, id);
103         rc = uinput_device_new_with_events_v(d, name, id, args);
104         va_end(args);
105
106         return rc;
107 }
108
109 void
110 uinput_device_free(struct uinput_device *dev)
111 {
112         if (!dev)
113                 return;
114
115         if (dev->uinput_fd != -1) {
116                 ioctl(dev->uinput_fd, UI_DEV_DESTROY, NULL);
117                 close(dev->uinput_fd);
118         }
119         if (dev->dev_fd != -1)
120                 close(dev->dev_fd);
121         libevdev_free(dev->d);
122         libevdev_uinput_destroy(dev->uidev);
123         free(dev);
124 }
125
126 int
127 uinput_device_get_fd(const struct uinput_device *dev)
128 {
129         return dev->dev_fd;
130 }
131
132 const char*
133 uinput_device_get_devnode(const struct uinput_device *dev)
134 {
135         return libevdev_uinput_get_devnode(dev->uidev);
136 }
137
138 int
139 uinput_device_create(struct uinput_device* d)
140 {
141         int rc;
142         int fd;
143         const char *devnode;
144
145         fd = open("/dev/uinput", O_RDWR);
146         if (fd < 0)
147                 goto error;
148
149         d->uinput_fd = fd;
150
151         rc = libevdev_uinput_create_from_device(d->d, fd, &d->uidev);
152         if (rc != 0)
153                 goto error;
154
155         devnode = libevdev_uinput_get_devnode(d->uidev);
156         if (devnode == NULL)
157                 goto error;
158
159         d->dev_fd = open(devnode, O_RDWR);
160         if (d->dev_fd == -1)
161                 goto error;
162
163         /* write abs resolution now */
164         if (libevdev_has_event_type(d->d, EV_ABS)) {
165                 int  code;
166                 for (code = 0; code < ABS_CNT; code++) {
167                         const struct input_absinfo *abs;
168
169                         /* can't change slots */
170                         if (code == ABS_MT_SLOT)
171                                 continue;
172
173                         abs = libevdev_get_abs_info(d->d, code);
174                         if (!abs)
175                                 continue;
176
177                         rc = ioctl(d->dev_fd, EVIOCSABS(code), abs);
178                         if (rc < 0) {
179                                 printf("error %s for code %d\n", strerror(-rc), code);
180                                 goto error;
181                         }
182                 }
183         }
184
185         return 0;
186
187 error:
188         if (d->dev_fd != -1)
189                 close(d->dev_fd);
190         if (d->uinput_fd != -1)
191                 close(d->uinput_fd);
192         return -errno;
193
194 }
195
196 int uinput_device_set_name(struct uinput_device *dev, const char *name)
197 {
198         libevdev_set_name(dev->d, name);
199         return 0;
200 }
201
202 int uinput_device_set_ids(struct uinput_device *dev, const struct input_id *ids)
203 {
204         libevdev_set_id_product(dev->d, ids->product);
205         libevdev_set_id_vendor(dev->d, ids->vendor);
206         libevdev_set_id_bustype(dev->d, ids->bustype);
207         libevdev_set_id_version(dev->d, ids->version);
208         return 0;
209 }
210
211 int
212 uinput_device_set_bit(struct uinput_device* dev, unsigned int bit)
213 {
214         return libevdev_enable_event_type(dev->d, bit);
215 }
216
217 int
218 uinput_device_set_prop(struct uinput_device *dev, unsigned int prop)
219 {
220         return libevdev_enable_property(dev->d, prop);
221 }
222
223 int
224 uinput_device_set_event_bit(struct uinput_device* dev, unsigned int type, unsigned int code)
225 {
226         return libevdev_enable_event_code(dev->d, type, code, NULL);
227 }
228
229 int
230 uinput_device_set_event_bits_v(struct uinput_device *dev, va_list args)
231 {
232         int type, code;
233         int rc = 0;
234
235         do {
236                 type = va_arg(args, int);
237                 if (type == -1)
238                         break;
239                 code = va_arg(args, int);
240                 if (code == -1)
241                         break;
242                 rc = libevdev_enable_event_code(dev->d, type, code, NULL);
243         } while (rc == 0);
244
245         return rc;
246 }
247
248 int
249 uinput_device_set_event_bits(struct uinput_device *dev, ...)
250 {
251         int rc;
252         va_list args;
253         va_start(args, dev);
254         rc = uinput_device_set_event_bits_v(dev, args);
255         va_end(args);
256
257         return rc;
258 }
259
260 int
261 uinput_device_set_abs_bit(struct uinput_device* dev, unsigned int code, const struct input_absinfo *absinfo)
262 {
263         return libevdev_enable_event_code(dev->d, EV_ABS, code, absinfo);
264 }
265
266 int
267 uinput_device_event(const struct uinput_device *dev, unsigned int type, unsigned int code, int value)
268 {
269         return libevdev_uinput_write_event(dev->uidev, type, code, value);
270 }
271
272 int uinput_device_event_multiple_v(const struct uinput_device* dev, va_list args)
273 {
274         int type, code, value;
275         int rc = 0;
276
277         do {
278                 type = va_arg(args, int);
279                 if (type == -1)
280                         break;
281                 code = va_arg(args, int);
282                 if (code == -1)
283                         break;
284                 value = va_arg(args, int);
285                 rc = uinput_device_event(dev, type, code, value);
286         } while (rc == 0);
287
288         return rc;
289 }
290
291 int uinput_device_event_multiple(const struct uinput_device* dev, ...)
292 {
293         int rc;
294         va_list args;
295         va_start(args, dev);
296         rc = uinput_device_event_multiple_v(dev, args);
297         va_end(args);
298         return rc;
299 }