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