1 ============= 1 ============= 2 uinput module 2 uinput module 3 ============= 3 ============= 4 4 5 Introduction 5 Introduction 6 ============ 6 ============ 7 7 8 uinput is a kernel module that makes it possib 8 uinput is a kernel module that makes it possible to emulate input devices 9 from userspace. By writing to /dev/uinput (or 9 from userspace. By writing to /dev/uinput (or /dev/input/uinput) device, a 10 process can create a virtual input device with 10 process can create a virtual input device with specific capabilities. Once 11 this virtual device is created, the process ca 11 this virtual device is created, the process can send events through it, 12 that will be delivered to userspace and in-ker 12 that will be delivered to userspace and in-kernel consumers. 13 13 14 Interface 14 Interface 15 ========= 15 ========= 16 16 17 :: 17 :: 18 18 19 linux/uinput.h 19 linux/uinput.h 20 20 21 The uinput header defines ioctls to create, se 21 The uinput header defines ioctls to create, set up, and destroy virtual 22 devices. 22 devices. 23 23 24 libevdev 24 libevdev 25 ======== 25 ======== 26 26 27 libevdev is a wrapper library for evdev device 27 libevdev is a wrapper library for evdev devices that provides interfaces to 28 create uinput devices and send events. libevde 28 create uinput devices and send events. libevdev is less error-prone than 29 accessing uinput directly, and should be consi 29 accessing uinput directly, and should be considered for new software. 30 30 31 For examples and more information about libevd 31 For examples and more information about libevdev: 32 https://www.freedesktop.org/software/libevdev/ 32 https://www.freedesktop.org/software/libevdev/doc/latest/ 33 33 34 Examples 34 Examples 35 ======== 35 ======== 36 36 37 Keyboard events 37 Keyboard events 38 --------------- 38 --------------- 39 39 40 This first example shows how to create a new v 40 This first example shows how to create a new virtual device, and how to 41 send a key event. All default imports and erro 41 send a key event. All default imports and error handlers were removed for 42 the sake of simplicity. 42 the sake of simplicity. 43 43 44 .. code-block:: c 44 .. code-block:: c 45 45 46 #include <linux/uinput.h> 46 #include <linux/uinput.h> 47 47 48 void emit(int fd, int type, int code, int v 48 void emit(int fd, int type, int code, int val) 49 { 49 { 50 struct input_event ie; 50 struct input_event ie; 51 51 52 ie.type = type; 52 ie.type = type; 53 ie.code = code; 53 ie.code = code; 54 ie.value = val; 54 ie.value = val; 55 /* timestamp values below are ignored */ 55 /* timestamp values below are ignored */ 56 ie.time.tv_sec = 0; 56 ie.time.tv_sec = 0; 57 ie.time.tv_usec = 0; 57 ie.time.tv_usec = 0; 58 58 59 write(fd, &ie, sizeof(ie)); 59 write(fd, &ie, sizeof(ie)); 60 } 60 } 61 61 62 int main(void) 62 int main(void) 63 { 63 { 64 struct uinput_setup usetup; 64 struct uinput_setup usetup; 65 65 66 int fd = open("/dev/uinput", O_WRONLY | 66 int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); 67 67 68 68 69 /* 69 /* 70 * The ioctls below will enable the devi 70 * The ioctls below will enable the device that is about to be 71 * created, to pass key events, in this 71 * created, to pass key events, in this case the space key. 72 */ 72 */ 73 ioctl(fd, UI_SET_EVBIT, EV_KEY); 73 ioctl(fd, UI_SET_EVBIT, EV_KEY); 74 ioctl(fd, UI_SET_KEYBIT, KEY_SPACE); 74 ioctl(fd, UI_SET_KEYBIT, KEY_SPACE); 75 75 76 memset(&usetup, 0, sizeof(usetup)); 76 memset(&usetup, 0, sizeof(usetup)); 77 usetup.id.bustype = BUS_USB; 77 usetup.id.bustype = BUS_USB; 78 usetup.id.vendor = 0x1234; /* sample ven 78 usetup.id.vendor = 0x1234; /* sample vendor */ 79 usetup.id.product = 0x5678; /* sample pr 79 usetup.id.product = 0x5678; /* sample product */ 80 strcpy(usetup.name, "Example device"); 80 strcpy(usetup.name, "Example device"); 81 81 82 ioctl(fd, UI_DEV_SETUP, &usetup); 82 ioctl(fd, UI_DEV_SETUP, &usetup); 83 ioctl(fd, UI_DEV_CREATE); 83 ioctl(fd, UI_DEV_CREATE); 84 84 85 /* 85 /* 86 * On UI_DEV_CREATE the kernel will crea 86 * On UI_DEV_CREATE the kernel will create the device node for this 87 * device. We are inserting a pause here 87 * device. We are inserting a pause here so that userspace has time 88 * to detect, initialize the new device, 88 * to detect, initialize the new device, and can start listening to 89 * the event, otherwise it will not noti 89 * the event, otherwise it will not notice the event we are about 90 * to send. This pause is only needed in 90 * to send. This pause is only needed in our example code! 91 */ 91 */ 92 sleep(1); 92 sleep(1); 93 93 94 /* Key press, report the event, send key 94 /* Key press, report the event, send key release, and report again */ 95 emit(fd, EV_KEY, KEY_SPACE, 1); 95 emit(fd, EV_KEY, KEY_SPACE, 1); 96 emit(fd, EV_SYN, SYN_REPORT, 0); 96 emit(fd, EV_SYN, SYN_REPORT, 0); 97 emit(fd, EV_KEY, KEY_SPACE, 0); 97 emit(fd, EV_KEY, KEY_SPACE, 0); 98 emit(fd, EV_SYN, SYN_REPORT, 0); 98 emit(fd, EV_SYN, SYN_REPORT, 0); 99 99 100 /* 100 /* 101 * Give userspace some time to read the 101 * Give userspace some time to read the events before we destroy the 102 * device with UI_DEV_DESTROY. !! 102 * device with UI_DEV_DESTOY. 103 */ 103 */ 104 sleep(1); 104 sleep(1); 105 105 106 ioctl(fd, UI_DEV_DESTROY); 106 ioctl(fd, UI_DEV_DESTROY); 107 close(fd); 107 close(fd); 108 108 109 return 0; 109 return 0; 110 } 110 } 111 111 112 Mouse movements 112 Mouse movements 113 --------------- 113 --------------- 114 114 115 This example shows how to create a virtual dev 115 This example shows how to create a virtual device that behaves like a physical 116 mouse. 116 mouse. 117 117 118 .. code-block:: c 118 .. code-block:: c 119 119 120 #include <linux/uinput.h> 120 #include <linux/uinput.h> 121 121 122 /* emit function is identical to of the fir 122 /* emit function is identical to of the first example */ 123 123 124 int main(void) 124 int main(void) 125 { 125 { 126 struct uinput_setup usetup; 126 struct uinput_setup usetup; 127 int i = 50; 127 int i = 50; 128 128 129 int fd = open("/dev/uinput", O_WRONLY | 129 int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); 130 130 131 /* enable mouse button left and relative 131 /* enable mouse button left and relative events */ 132 ioctl(fd, UI_SET_EVBIT, EV_KEY); 132 ioctl(fd, UI_SET_EVBIT, EV_KEY); 133 ioctl(fd, UI_SET_KEYBIT, BTN_LEFT); 133 ioctl(fd, UI_SET_KEYBIT, BTN_LEFT); 134 134 135 ioctl(fd, UI_SET_EVBIT, EV_REL); 135 ioctl(fd, UI_SET_EVBIT, EV_REL); 136 ioctl(fd, UI_SET_RELBIT, REL_X); 136 ioctl(fd, UI_SET_RELBIT, REL_X); 137 ioctl(fd, UI_SET_RELBIT, REL_Y); 137 ioctl(fd, UI_SET_RELBIT, REL_Y); 138 138 139 memset(&usetup, 0, sizeof(usetup)); 139 memset(&usetup, 0, sizeof(usetup)); 140 usetup.id.bustype = BUS_USB; 140 usetup.id.bustype = BUS_USB; 141 usetup.id.vendor = 0x1234; /* sample ven 141 usetup.id.vendor = 0x1234; /* sample vendor */ 142 usetup.id.product = 0x5678; /* sample pr 142 usetup.id.product = 0x5678; /* sample product */ 143 strcpy(usetup.name, "Example device"); 143 strcpy(usetup.name, "Example device"); 144 144 145 ioctl(fd, UI_DEV_SETUP, &usetup); 145 ioctl(fd, UI_DEV_SETUP, &usetup); 146 ioctl(fd, UI_DEV_CREATE); 146 ioctl(fd, UI_DEV_CREATE); 147 147 148 /* 148 /* 149 * On UI_DEV_CREATE the kernel will crea 149 * On UI_DEV_CREATE the kernel will create the device node for this 150 * device. We are inserting a pause here 150 * device. We are inserting a pause here so that userspace has time 151 * to detect, initialize the new device, 151 * to detect, initialize the new device, and can start listening to 152 * the event, otherwise it will not noti 152 * the event, otherwise it will not notice the event we are about 153 * to send. This pause is only needed in 153 * to send. This pause is only needed in our example code! 154 */ 154 */ 155 sleep(1); 155 sleep(1); 156 156 157 /* Move the mouse diagonally, 5 units pe 157 /* Move the mouse diagonally, 5 units per axis */ 158 while (i--) { 158 while (i--) { 159 emit(fd, EV_REL, REL_X, 5); 159 emit(fd, EV_REL, REL_X, 5); 160 emit(fd, EV_REL, REL_Y, 5); 160 emit(fd, EV_REL, REL_Y, 5); 161 emit(fd, EV_SYN, SYN_REPORT, 0); 161 emit(fd, EV_SYN, SYN_REPORT, 0); 162 usleep(15000); 162 usleep(15000); 163 } 163 } 164 164 165 /* 165 /* 166 * Give userspace some time to read the 166 * Give userspace some time to read the events before we destroy the 167 * device with UI_DEV_DESTROY. !! 167 * device with UI_DEV_DESTOY. 168 */ 168 */ 169 sleep(1); 169 sleep(1); 170 170 171 ioctl(fd, UI_DEV_DESTROY); 171 ioctl(fd, UI_DEV_DESTROY); 172 close(fd); 172 close(fd); 173 173 174 return 0; 174 return 0; 175 } 175 } 176 176 177 177 178 uinput old interface 178 uinput old interface 179 -------------------- 179 -------------------- 180 180 181 Before uinput version 5, there wasn't a dedica 181 Before uinput version 5, there wasn't a dedicated ioctl to set up a virtual 182 device. Programs supporting older versions of !! 182 device. Programs supportinf older versions of uinput interface need to fill 183 a uinput_user_dev structure and write it to th 183 a uinput_user_dev structure and write it to the uinput file descriptor to 184 configure the new uinput device. New code shou 184 configure the new uinput device. New code should not use the old interface 185 but interact with uinput via ioctl calls, or u 185 but interact with uinput via ioctl calls, or use libevdev. 186 186 187 .. code-block:: c 187 .. code-block:: c 188 188 189 #include <linux/uinput.h> 189 #include <linux/uinput.h> 190 190 191 /* emit function is identical to of the fir 191 /* emit function is identical to of the first example */ 192 192 193 int main(void) 193 int main(void) 194 { 194 { 195 struct uinput_user_dev uud; 195 struct uinput_user_dev uud; 196 int version, rc, fd; 196 int version, rc, fd; 197 197 198 fd = open("/dev/uinput", O_WRONLY | O_NO 198 fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); 199 rc = ioctl(fd, UI_GET_VERSION, &version) 199 rc = ioctl(fd, UI_GET_VERSION, &version); 200 200 201 if (rc == 0 && version >= 5) { 201 if (rc == 0 && version >= 5) { 202 /* use UI_DEV_SETUP */ 202 /* use UI_DEV_SETUP */ 203 return 0; 203 return 0; 204 } 204 } 205 205 206 /* 206 /* 207 * The ioctls below will enable the devi 207 * The ioctls below will enable the device that is about to be 208 * created, to pass key events, in this 208 * created, to pass key events, in this case the space key. 209 */ 209 */ 210 ioctl(fd, UI_SET_EVBIT, EV_KEY); 210 ioctl(fd, UI_SET_EVBIT, EV_KEY); 211 ioctl(fd, UI_SET_KEYBIT, KEY_SPACE); 211 ioctl(fd, UI_SET_KEYBIT, KEY_SPACE); 212 212 213 memset(&uud, 0, sizeof(uud)); 213 memset(&uud, 0, sizeof(uud)); 214 snprintf(uud.name, UINPUT_MAX_NAME_SIZE, 214 snprintf(uud.name, UINPUT_MAX_NAME_SIZE, "uinput old interface"); 215 write(fd, &uud, sizeof(uud)); 215 write(fd, &uud, sizeof(uud)); 216 216 217 ioctl(fd, UI_DEV_CREATE); 217 ioctl(fd, UI_DEV_CREATE); 218 218 219 /* 219 /* 220 * On UI_DEV_CREATE the kernel will crea 220 * On UI_DEV_CREATE the kernel will create the device node for this 221 * device. We are inserting a pause here 221 * device. We are inserting a pause here so that userspace has time 222 * to detect, initialize the new device, 222 * to detect, initialize the new device, and can start listening to 223 * the event, otherwise it will not noti 223 * the event, otherwise it will not notice the event we are about 224 * to send. This pause is only needed in 224 * to send. This pause is only needed in our example code! 225 */ 225 */ 226 sleep(1); 226 sleep(1); 227 227 228 /* Key press, report the event, send key 228 /* Key press, report the event, send key release, and report again */ 229 emit(fd, EV_KEY, KEY_SPACE, 1); 229 emit(fd, EV_KEY, KEY_SPACE, 1); 230 emit(fd, EV_SYN, SYN_REPORT, 0); 230 emit(fd, EV_SYN, SYN_REPORT, 0); 231 emit(fd, EV_KEY, KEY_SPACE, 0); 231 emit(fd, EV_KEY, KEY_SPACE, 0); 232 emit(fd, EV_SYN, SYN_REPORT, 0); 232 emit(fd, EV_SYN, SYN_REPORT, 0); 233 233 234 /* 234 /* 235 * Give userspace some time to read the 235 * Give userspace some time to read the events before we destroy the 236 * device with UI_DEV_DESTROY. !! 236 * device with UI_DEV_DESTOY. 237 */ 237 */ 238 sleep(1); 238 sleep(1); 239 239 240 ioctl(fd, UI_DEV_DESTROY); 240 ioctl(fd, UI_DEV_DESTROY); 241 241 242 close(fd); 242 close(fd); 243 return 0; 243 return 0; 244 } 244 } 245 245
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.