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