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