Back to home page

OSCL-LXR

 
 

    


0001 =============
0002 uinput module
0003 =============
0004 
0005 Introduction
0006 ============
0007 
0008 uinput is a kernel module that makes it possible to emulate input devices
0009 from userspace. By writing to /dev/uinput (or /dev/input/uinput) device, a
0010 process can create a virtual input device with specific capabilities. Once
0011 this virtual device is created, the process can send events through it,
0012 that will be delivered to userspace and in-kernel consumers.
0013 
0014 Interface
0015 =========
0016 
0017 ::
0018 
0019   linux/uinput.h
0020 
0021 The uinput header defines ioctls to create, set up, and destroy virtual
0022 devices.
0023 
0024 libevdev
0025 ========
0026 
0027 libevdev is a wrapper library for evdev devices that provides interfaces to
0028 create uinput devices and send events. libevdev is less error-prone than
0029 accessing uinput directly, and should be considered for new software.
0030 
0031 For examples and more information about libevdev:
0032 https://www.freedesktop.org/software/libevdev/doc/latest/
0033 
0034 Examples
0035 ========
0036 
0037 Keyboard events
0038 ---------------
0039 
0040 This first example shows how to create a new virtual device, and how to
0041 send a key event. All default imports and error handlers were removed for
0042 the sake of simplicity.
0043 
0044 .. code-block:: c
0045 
0046    #include <linux/uinput.h>
0047 
0048    void emit(int fd, int type, int code, int val)
0049    {
0050       struct input_event ie;
0051 
0052       ie.type = type;
0053       ie.code = code;
0054       ie.value = val;
0055       /* timestamp values below are ignored */
0056       ie.time.tv_sec = 0;
0057       ie.time.tv_usec = 0;
0058 
0059       write(fd, &ie, sizeof(ie));
0060    }
0061 
0062    int main(void)
0063    {
0064       struct uinput_setup usetup;
0065 
0066       int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
0067 
0068 
0069       /*
0070        * The ioctls below will enable the device that is about to be
0071        * created, to pass key events, in this case the space key.
0072        */
0073       ioctl(fd, UI_SET_EVBIT, EV_KEY);
0074       ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
0075 
0076       memset(&usetup, 0, sizeof(usetup));
0077       usetup.id.bustype = BUS_USB;
0078       usetup.id.vendor = 0x1234; /* sample vendor */
0079       usetup.id.product = 0x5678; /* sample product */
0080       strcpy(usetup.name, "Example device");
0081 
0082       ioctl(fd, UI_DEV_SETUP, &usetup);
0083       ioctl(fd, UI_DEV_CREATE);
0084 
0085       /*
0086        * On UI_DEV_CREATE the kernel will create the device node for this
0087        * device. We are inserting a pause here so that userspace has time
0088        * to detect, initialize the new device, and can start listening to
0089        * the event, otherwise it will not notice the event we are about
0090        * to send. This pause is only needed in our example code!
0091        */
0092       sleep(1);
0093 
0094       /* Key press, report the event, send key release, and report again */
0095       emit(fd, EV_KEY, KEY_SPACE, 1);
0096       emit(fd, EV_SYN, SYN_REPORT, 0);
0097       emit(fd, EV_KEY, KEY_SPACE, 0);
0098       emit(fd, EV_SYN, SYN_REPORT, 0);
0099 
0100       /*
0101        * Give userspace some time to read the events before we destroy the
0102        * device with UI_DEV_DESTROY.
0103        */
0104       sleep(1);
0105 
0106       ioctl(fd, UI_DEV_DESTROY);
0107       close(fd);
0108 
0109       return 0;
0110    }
0111 
0112 Mouse movements
0113 ---------------
0114 
0115 This example shows how to create a virtual device that behaves like a physical
0116 mouse.
0117 
0118 .. code-block:: c
0119 
0120    #include <linux/uinput.h>
0121 
0122    /* emit function is identical to of the first example */
0123 
0124    int main(void)
0125    {
0126       struct uinput_setup usetup;
0127       int i = 50;
0128 
0129       int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
0130 
0131       /* enable mouse button left and relative events */
0132       ioctl(fd, UI_SET_EVBIT, EV_KEY);
0133       ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
0134 
0135       ioctl(fd, UI_SET_EVBIT, EV_REL);
0136       ioctl(fd, UI_SET_RELBIT, REL_X);
0137       ioctl(fd, UI_SET_RELBIT, REL_Y);
0138 
0139       memset(&usetup, 0, sizeof(usetup));
0140       usetup.id.bustype = BUS_USB;
0141       usetup.id.vendor = 0x1234; /* sample vendor */
0142       usetup.id.product = 0x5678; /* sample product */
0143       strcpy(usetup.name, "Example device");
0144 
0145       ioctl(fd, UI_DEV_SETUP, &usetup);
0146       ioctl(fd, UI_DEV_CREATE);
0147 
0148       /*
0149        * On UI_DEV_CREATE the kernel will create the device node for this
0150        * device. We are inserting a pause here so that userspace has time
0151        * to detect, initialize the new device, and can start listening to
0152        * the event, otherwise it will not notice the event we are about
0153        * to send. This pause is only needed in our example code!
0154        */
0155       sleep(1);
0156 
0157       /* Move the mouse diagonally, 5 units per axis */
0158       while (i--) {
0159          emit(fd, EV_REL, REL_X, 5);
0160          emit(fd, EV_REL, REL_Y, 5);
0161          emit(fd, EV_SYN, SYN_REPORT, 0);
0162          usleep(15000);
0163       }
0164 
0165       /*
0166        * Give userspace some time to read the events before we destroy the
0167        * device with UI_DEV_DESTROY.
0168        */
0169       sleep(1);
0170 
0171       ioctl(fd, UI_DEV_DESTROY);
0172       close(fd);
0173 
0174       return 0;
0175    }
0176 
0177 
0178 uinput old interface
0179 --------------------
0180 
0181 Before uinput version 5, there wasn't a dedicated ioctl to set up a virtual
0182 device. Programs supporting older versions of uinput interface need to fill
0183 a uinput_user_dev structure and write it to the uinput file descriptor to
0184 configure the new uinput device. New code should not use the old interface
0185 but interact with uinput via ioctl calls, or use libevdev.
0186 
0187 .. code-block:: c
0188 
0189    #include <linux/uinput.h>
0190 
0191    /* emit function is identical to of the first example */
0192 
0193    int main(void)
0194    {
0195       struct uinput_user_dev uud;
0196       int version, rc, fd;
0197 
0198       fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
0199       rc = ioctl(fd, UI_GET_VERSION, &version);
0200 
0201       if (rc == 0 && version >= 5) {
0202          /* use UI_DEV_SETUP */
0203          return 0;
0204       }
0205 
0206       /*
0207        * The ioctls below will enable the device that is about to be
0208        * created, to pass key events, in this case the space key.
0209        */
0210       ioctl(fd, UI_SET_EVBIT, EV_KEY);
0211       ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
0212 
0213       memset(&uud, 0, sizeof(uud));
0214       snprintf(uud.name, UINPUT_MAX_NAME_SIZE, "uinput old interface");
0215       write(fd, &uud, sizeof(uud));
0216 
0217       ioctl(fd, UI_DEV_CREATE);
0218 
0219       /*
0220        * On UI_DEV_CREATE the kernel will create the device node for this
0221        * device. We are inserting a pause here so that userspace has time
0222        * to detect, initialize the new device, and can start listening to
0223        * the event, otherwise it will not notice the event we are about
0224        * to send. This pause is only needed in our example code!
0225        */
0226       sleep(1);
0227 
0228       /* Key press, report the event, send key release, and report again */
0229       emit(fd, EV_KEY, KEY_SPACE, 1);
0230       emit(fd, EV_SYN, SYN_REPORT, 0);
0231       emit(fd, EV_KEY, KEY_SPACE, 0);
0232       emit(fd, EV_SYN, SYN_REPORT, 0);
0233 
0234       /*
0235        * Give userspace some time to read the events before we destroy the
0236        * device with UI_DEV_DESTROY.
0237        */
0238       sleep(1);
0239 
0240       ioctl(fd, UI_DEV_DESTROY);
0241 
0242       close(fd);
0243       return 0;
0244    }
0245