lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20170322025820.4108-2-marcos.souza.org@gmail.com>
Date:   Tue, 21 Mar 2017 23:58:17 -0300
From:   Marcos Paulo de Souza <marcos.souza.org@...il.com>
To:     corbet@....net, linux-doc@...r.kernel.org,
        dmitry.torokhov@...il.com, linux-input@...r.kernel.org,
        benjamin.tissoires@...hat.com, peter.hutterer@...-t.net
Cc:     Marcos Paulo de Souza <marcos.souza.org@...il.com>,
        linux-kernel@...r.kernel.org
Subject: [PATCH] Documentation: Input: Add uinput documentation

Signed-off-by: Marcos Paulo de Souza <marcos.souza.org@...il.com>
---
 Documentation/input/uinput.rst | 158 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 158 insertions(+)
 create mode 100644 Documentation/input/uinput.rst

diff --git a/Documentation/input/uinput.rst b/Documentation/input/uinput.rst
new file mode 100644
index 0000000..8d59c98
--- /dev/null
+++ b/Documentation/input/uinput.rst
@@ -0,0 +1,158 @@
+=============
+uinput module
+=============
+
+Introduction
+============
+
+uinput is a kernel module that makes possible create and handle input devices from userspace. By using /dev/uinput (or /dev/input/uinput), a process can create virtual devices and emit events like key pressing, mouse movements and joystick buttons.
+
+Interface
+=========
+
+::
+
+  linux/uinput.h
+
+The uinput header defines ioctl request keys to create, setup and destroy virtual devices, along with ioctls specific to uinput devices, like enabling events and keys to be send to the kernel.
+
+Examples
+========
+
+1.0 Keyboard events
+-------------------
+
+This first example shows how to create a new virtual device and how to send a key event as well as a physical keyboard. All default imports and error handlers were removed for the sake of simplicity.
+
+.. code-block:: c
+
+   #include <linux/uinput.h>
+
+   int fd;
+
+   void emit(int type, int code, int val)
+   {
+        struct input_event ie;
+        memset(&ie, 0, sizeof(ie));
+        ie.type = type;
+        ie.code = code;
+        ie.value = val;
+
+        if (write(fd, &ie, sizeof(ie)) < 0) {
+                perror("write2");
+                exit(1);
+        }
+   }
+
+   int main() {
+        struct input_id uid;
+        struct uinput_setup usetup;
+
+        fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
+        ioctl(fd, UI_SET_EVBIT, EV_KEY);
+        ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
+
+        memset(&uid, 0, sizeof(iod));
+        memset(&usetup, 0, sizeof(usetup));
+        usetup.id = uid;
+        strcpy(usetup.name, "ex_device");
+
+        ioctl(fd, UI_DEV_SETUP, &usetup);
+        ioctl(fd, UI_DEV_CREATE);
+
+        /* wait some time until the Window Manager can get the reference for the
+         * new virtual device to receive data from
+         * */
+        sleep(1);
+
+        /* send key press, report the event, send key release, and report again */
+        emit(EV_KEY, KEY_SPACE, 1);
+        emit(EV_SYN, SYN_REPORT, 0);
+        emit(EV_KEY, KEY_SPACE, 0);
+        emit(EV_SYN, SYN_REPORT, 0);
+
+        close(fd);
+
+        return 0;
+   }
+
+2.0 Mouse movements
+-------------------
+
+This example shows how to create a virtual device who behaves like a physical mouse.
+
+.. code-block:: c
+
+    int i = 50;
+
+    /* emit function is the same of the example above */
+
+    void emit_rel(int code, int val, int syn)
+    {
+            emit(EV_REL, code, val);
+            if (syn)
+                    emit(EV_SYN, SYN_REPORT, 0);
+    }
+
+    /* ...open uinput file as shown in the previous example... */
+
+    /* enable mouse button left and relative events. This makes the Window Manager to interpret this
+     * device as a physical mouse
+     */
+    if (ioctl(fd, UI_SET_EVBIT, EV_KEY) == -1) {
+            perror("ioctl0");
+            exit(1);
+    }
+
+    if (ioctl(fd, UI_SET_KEYBIT, BTN_LEFT) == -1) {
+            perror("ioctl0.1");
+            exit(1);
+    }
+
+    if (ioctl(fd, UI_SET_EVBIT, EV_REL) == -1) {
+            perror("ioctl1");
+            exit(1);
+    }
+
+    if (ioctl(fd, UI_SET_RELBIT, REL_X) == -1) {
+            perror("ioctl2");
+            exit(1);
+    }
+
+    if (ioctl(fd, UI_SET_RELBIT, REL_Y) == -1) {
+            perror("ioctl3");
+            exit(1);
+    }
+
+    /* ...device setup, device create... */
+
+    /* Give some time for the Window Manager to get events of the new virtual device */
+    sleep(1);
+
+    /* moves the mouse diagonally, 5 units per axis */
+    while (i--) {
+                emit_rel(REL_X, 5, 0);
+                emit_rel(REL_Y, 5, 1);
+                usleep(15000);
+    }
+
+    /* device destroy, device close */
+    return 0;
+
+3.0 uinput old interface
+------------------------
+
+Before kernel 4.5, uinput didn't have an ioctl to setup a virtual device. When running a version prior to 4.5, the user needs to fill a different struct and call write on the uinput file descriptor.
+
+.. code-block:: c
+
+        /* add include of uinput header */
+        struct uinput_user_dev uud;
+
+        /* open uinput device, and set the proper events */
+
+        memset(&uud, 0 sizeof(uud));
+        snprintf(uud.name, UINPUT_MAX_NAME_SIZE, "uinput_old_style");
+        write(fd, &uud, sizeof(uud));
+
+        /* call DEV_CREATE ioctl, and emit the events */
-- 
2.9.3

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ