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