• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Copyright © 2013 Red Hat, Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to
7  * deal in the Software without restriction, including without limitation the
8  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9  * sell copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 #ifndef LIBEVDEV_UINPUT_H
26 #define LIBEVDEV_UINPUT_H
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 #include <libevdev/libevdev.h>
33 
34 struct libevdev_uinput;
35 
36 /**
37  * @defgroup uinput uinput device creation
38  *
39  * Creation of uinput devices based on existing libevdev devices. These functions
40  * help to create uinput devices that emulate libevdev devices. In the simplest
41  * form it serves to duplicate an existing device:
42  *
43  * @code
44  * int err;
45  * int fd, uifd;
46  * struct libevdev *dev;
47  * struct libevdev_uinput *uidev;
48  *
49  * fd = open("/dev/input/event0", O_RDONLY);
50  * if (fd < 0)
51  *     return -errno;
52  *
53  * err = libevdev_new_from_fd(fd, &dev);
54  * if (err != 0)
55  *     return err;
56  *
57  * uifd = open("/dev/uinput", O_RDWR);
58  * if (uifd < 0)
59  *     return -errno;
60  *
61  * err = libevdev_uinput_create_from_device(dev, uifd, &uidev);
62  * if (err != 0)
63  *     return err;
64  *
65  * // post a REL_X event
66  * err = libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
67  * if (err != 0)
68  *     return err;
69  * err = libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
70  * if (err != 0)
71  *     return err;
72  *
73  * libevdev_uinput_destroy(uidev);
74  * libevdev_free(dev);
75  * close(uifd);
76  * close(fd);
77  *
78  * @endcode
79  *
80  * Alternatively, a device can be constructed from scratch:
81  *
82  * @code
83  * int err;
84  * struct libevdev *dev;
85  * struct libevdev_uinput *uidev;
86  *
87  * dev = libevdev_new();
88  * libevdev_set_name(dev, "test device");
89  * libevdev_enable_event_type(dev, EV_REL);
90  * libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
91  * libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
92  * libevdev_enable_event_type(dev, EV_KEY);
93  * libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
94  * libevdev_enable_event_code(dev, EV_KEY, BTN_MIDDLE, NULL);
95  * libevdev_enable_event_code(dev, EV_KEY, BTN_RIGHT, NULL);
96  *
97  * err = libevdev_uinput_create_from_device(dev,
98  *                                          LIBEVDEV_UINPUT_OPEN_MANAGED,
99  *                                          &uidev);
100  * if (err != 0)
101  *     return err;
102  *
103  * // ... do something ...
104  *
105  * libevdev_uinput_destroy(uidev);
106  *
107  * @endcode
108  */
109 
110 enum libevdev_uinput_open_mode {
111 	/* intentionally -2 to avoid code like below from accidentally working:
112 		fd = open("/dev/uinput", O_RDWR); // fails, fd is -1
113 		libevdev_uinput_create_from_device(dev, fd, &uidev); // may hide the error */
114 	LIBEVDEV_UINPUT_OPEN_MANAGED = -2  /**< let libevdev open and close @c /dev/uinput */
115 };
116 
117 /**
118  * @ingroup uinput
119  *
120  * Create a uinput device based on the given libevdev device. The uinput device
121  * will be an exact copy of the libevdev device, minus the bits that uinput doesn't
122  * allow to be set.
123  *
124  * If uinput_fd is @ref LIBEVDEV_UINPUT_OPEN_MANAGED, libevdev_uinput_create_from_device()
125  * will open @c /dev/uinput in read/write mode and manage the file descriptor.
126  * Otherwise, uinput_fd must be opened by the caller and opened with the
127  * appropriate permissions.
128  *
129  * The device's lifetime is tied to the uinput file descriptor, closing it will
130  * destroy the uinput device. You should call libevdev_uinput_destroy() before
131  * closing the file descriptor to free allocated resources.
132  * A file descriptor can only create one uinput device at a time; the second device
133  * will fail with -EINVAL.
134  *
135  * You don't need to keep the file descriptor variable around,
136  * libevdev_uinput_get_fd() will return it when needed.
137  *
138  * @note Due to limitations in the uinput kernel module, REP_DELAY and
139  * REP_PERIOD will default to the kernel defaults, not to the ones set in the
140  * source device.
141  *
142  * @note On FreeBSD, if the UI_GET_SYSNAME ioctl() fails, there is no other way
143  * to get a device, and the function call will fail.
144  *
145  * @param dev The device to duplicate
146  * @param uinput_fd @ref LIBEVDEV_UINPUT_OPEN_MANAGED or a file descriptor to @c /dev/uinput,
147  * @param[out] uinput_dev The newly created libevdev device.
148  *
149  * @return 0 on success or a negative errno on failure. On failure, the value of
150  * uinput_dev is unmodified.
151  *
152  * @see libevdev_uinput_destroy
153  */
154 int libevdev_uinput_create_from_device(const struct libevdev *dev,
155 				       int uinput_fd,
156 				       struct libevdev_uinput **uinput_dev);
157 
158 /**
159  * @ingroup uinput
160  *
161  * Destroy a previously created uinput device and free associated memory.
162  *
163  * If the device was opened with @ref LIBEVDEV_UINPUT_OPEN_MANAGED,
164  * libevdev_uinput_destroy() also closes the file descriptor. Otherwise, the
165  * fd is left as-is and must be closed by the caller.
166  *
167  * @param uinput_dev A previously created uinput device.
168  */
169 void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev);
170 
171 /**
172  * @ingroup uinput
173  *
174  * Return the file descriptor used to create this uinput device. This is the
175  * fd pointing to <strong>/dev/uinput</strong>. This file descriptor may be used to write
176  * events that are emitted by the uinput device.
177  * Closing this file descriptor will destroy the uinput device, you should
178  * call libevdev_uinput_destroy() first to free allocated resources.
179  *
180  * @param uinput_dev A previously created uinput device.
181  *
182  * @return The file descriptor used to create this device
183  */
184 int libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev);
185 
186 /**
187  * @ingroup uinput
188  *
189  * Return the syspath representing this uinput device. If the UI_GET_SYSNAME
190  * ioctl is not available, libevdev makes an educated guess.
191  * The UI_GET_SYSNAME ioctl is available since Linux 3.15.
192  *
193  * The syspath returned is the one of the input node itself
194  * (e.g. /sys/devices/virtual/input/input123), not the syspath of the device
195  * node returned with libevdev_uinput_get_devnode().
196  *
197  * @note This function may return NULL if UI_GET_SYSNAME is not available.
198  * In that case, libevdev uses ctime and the device name to guess devices.
199  * To avoid false positives, wait at least 1.5s between creating devices that
200  * have the same name.
201  *
202  * @note FreeBSD does not have sysfs, on FreeBSD this function always returns
203  * NULL.
204  *
205  * @param uinput_dev A previously created uinput device.
206  * @return The syspath for this device, including the preceding /sys
207  *
208  * @see libevdev_uinput_get_devnode
209  */
210 const char* libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev);
211 
212 /**
213  * @ingroup uinput
214  *
215  * Return the device node representing this uinput device.
216  *
217  * This relies on libevdev_uinput_get_syspath() to provide a valid syspath.
218  * See libevdev_uinput_get_syspath() for more details.
219  *
220  * @note This function may return NULL. libevdev may have to guess the
221  * syspath and the device node. See libevdev_uinput_get_syspath() for details.
222  *
223  * @note On FreeBSD, this function can not return NULL. libudev uses the
224  * UI_GET_SYSNAME ioctl to get the device node on this platform and if that
225  * fails, the call to libevdev_uinput_create_from_device() fails.
226  *
227  * @param uinput_dev A previously created uinput device.
228  * @return The device node for this device, in the form of /dev/input/eventN
229  *
230  * @see libevdev_uinput_get_syspath
231  */
232 const char* libevdev_uinput_get_devnode(struct libevdev_uinput *uinput_dev);
233 
234 /**
235  * @ingroup uinput
236  *
237  * Post an event through the uinput device. It is the caller's responsibility
238  * that any event sequence is terminated with an EV_SYN/SYN_REPORT/0 event.
239  * Otherwise, listeners on the device node will not see the events until the
240  * next EV_SYN event is posted.
241  *
242  * @param uinput_dev A previously created uinput device.
243  * @param type Event type (EV_ABS, EV_REL, etc.)
244  * @param code Event code (ABS_X, REL_Y, etc.)
245  * @param value The event value
246  * @return 0 on success or a negative errno on error
247  */
248 int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev,
249 				unsigned int type,
250 				unsigned int code,
251 				int value);
252 #ifdef __cplusplus
253 }
254 #endif
255 
256 #endif /* LIBEVDEV_UINPUT_H */
257