Drop semicolons after getter/setter macros
[platform/upstream/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         free(dev);
123 }
124
125 int
126 uinput_device_get_fd(const struct uinput_device *dev)
127 {
128         return dev->dev_fd;
129 }
130
131 const char*
132 uinput_device_get_devnode(const struct uinput_device *dev)
133 {
134         return libevdev_uinput_get_devnode(dev->uidev);
135 }
136
137 int
138 uinput_device_create(struct uinput_device* d)
139 {
140         int rc;
141         int fd;
142         const char *devnode;
143
144         fd = open("/dev/uinput", O_RDWR);
145         if (fd < 0)
146                 goto error;
147
148         d->uinput_fd = fd;
149
150         rc = libevdev_uinput_create_from_device(d->d, fd, &d->uidev);
151         if (rc != 0)
152                 goto error;
153
154         devnode = libevdev_uinput_get_devnode(d->uidev);
155         if (devnode == NULL)
156                 goto error;
157
158         d->dev_fd = open(devnode, O_RDWR);
159         if (d->dev_fd == -1)
160                 goto error;
161
162         /* write abs resolution now */
163         if (libevdev_has_event_type(d->d, EV_ABS)) {
164                 int  code;
165                 for (code = 0; code < ABS_CNT; code++) {
166                         const struct input_absinfo *abs;
167
168                         /* can't change slots */
169                         if (code == ABS_MT_SLOT)
170                                 continue;
171
172                         abs = libevdev_get_abs_info(d->d, code);
173                         if (!abs)
174                                 continue;
175
176                         rc = ioctl(d->dev_fd, EVIOCSABS(code), abs);
177                         if (rc < 0) {
178                                 printf("error %s for code %d\n", strerror(-rc), code);
179                                 goto error;
180                         }
181                 }
182         }
183
184         return 0;
185
186 error:
187         if (d->dev_fd != -1)
188                 close(d->dev_fd);
189         if (d->uinput_fd != -1)
190                 close(d->uinput_fd);
191         return -errno;
192
193 }
194
195 int uinput_device_set_name(struct uinput_device *dev, const char *name)
196 {
197         libevdev_set_name(dev->d, name);
198         return 0;
199 }
200
201 int uinput_device_set_ids(struct uinput_device *dev, const struct input_id *ids)
202 {
203         libevdev_set_id_product(dev->d, ids->product);
204         libevdev_set_id_vendor(dev->d, ids->vendor);
205         libevdev_set_id_bustype(dev->d, ids->bustype);
206         libevdev_set_id_version(dev->d, ids->version);
207         return 0;
208 }
209
210 int
211 uinput_device_set_bit(struct uinput_device* dev, unsigned int bit)
212 {
213         return libevdev_enable_event_type(dev->d, bit);
214 }
215
216 int
217 uinput_device_set_prop(struct uinput_device *dev, unsigned int prop)
218 {
219         return libevdev_enable_property(dev->d, prop);
220 }
221
222 int
223 uinput_device_set_event_bit(struct uinput_device* dev, unsigned int type, unsigned int code)
224 {
225         return libevdev_enable_event_code(dev->d, type, code, NULL);
226 }
227
228 int
229 uinput_device_set_event_bits_v(struct uinput_device *dev, va_list args)
230 {
231         int type, code;
232         int rc = 0;
233
234         do {
235                 type = va_arg(args, int);
236                 if (type == -1)
237                         break;
238                 code = va_arg(args, int);
239                 if (code == -1)
240                         break;
241                 rc = libevdev_enable_event_code(dev->d, type, code, NULL);
242         } while (rc == 0);
243
244         return rc;
245 }
246
247 int
248 uinput_device_set_event_bits(struct uinput_device *dev, ...)
249 {
250         int rc;
251         va_list args;
252         va_start(args, dev);
253         rc = uinput_device_set_event_bits_v(dev, args);
254         va_end(args);
255
256         return rc;
257 }
258
259 int
260 uinput_device_set_abs_bit(struct uinput_device* dev, unsigned int code, const struct input_absinfo *absinfo)
261 {
262         return libevdev_enable_event_code(dev->d, EV_ABS, code, absinfo);
263 }
264
265 int
266 uinput_device_event(const struct uinput_device *dev, unsigned int type, unsigned int code, int value)
267 {
268         return libevdev_uinput_write_event(dev->uidev, type, code, value);
269 }
270
271 int uinput_device_event_multiple_v(const struct uinput_device* dev, va_list args)
272 {
273         int type, code, value;
274         int rc = 0;
275
276         do {
277                 type = va_arg(args, int);
278                 if (type == -1)
279                         break;
280                 code = va_arg(args, int);
281                 if (code == -1)
282                         break;
283                 value = va_arg(args, int);
284                 rc = uinput_device_event(dev, type, code, value);
285         } while (rc == 0);
286
287         return rc;
288 }
289
290 int uinput_device_event_multiple(const struct uinput_device* dev, ...)
291 {
292         int rc;
293         va_list args;
294         va_start(args, dev);
295         rc = uinput_device_event_multiple_v(dev, args);
296         va_end(args);
297         return rc;
298 }