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