All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] Docs: Input: initial uinput documentation
@ 2017-03-24  3:34 Marcos Paulo de Souza
  2017-03-24  3:34 ` [PATCH v2] Documentation: Input: Add " Marcos Paulo de Souza
  2017-03-24 21:17 ` [PATCH v2] Docs: Input: initial " Jonathan Corbet
  0 siblings, 2 replies; 9+ messages in thread
From: Marcos Paulo de Souza @ 2017-03-24  3:34 UTC (permalink / raw)
  To: corbet, linux-doc, dmitry.torokhov, linux-input,
	benjamin.tissoires, peter.hutterer
  Cc: Marcos Paulo de Souza

Hi guys,

this is the second iteration of this patch. The first version can be checked
here[1]. A special thanks to Peter Hutterer who dug the last patch and suggested
a lot of changes , hopefully, all addressed in this version.

[1] https://lkml.org/lkml/2017/3/21/929

Thanks,

Marcos Paulo de Souza (1):
  Documentation: Input: Add uinput documentation

 Documentation/input/uinput.rst | 196 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 196 insertions(+)
 create mode 100644 Documentation/input/uinput.rst

-- 
2.9.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2] Documentation: Input: Add uinput documentation
  2017-03-24  3:34 [PATCH v2] Docs: Input: initial uinput documentation Marcos Paulo de Souza
@ 2017-03-24  3:34 ` Marcos Paulo de Souza
  2017-03-24  4:39   ` Peter Hutterer
  2017-03-24 21:17 ` [PATCH v2] Docs: Input: initial " Jonathan Corbet
  1 sibling, 1 reply; 9+ messages in thread
From: Marcos Paulo de Souza @ 2017-03-24  3:34 UTC (permalink / raw)
  To: corbet, linux-doc, dmitry.torokhov, linux-input,
	benjamin.tissoires, peter.hutterer
  Cc: Marcos Paulo de Souza, linux-kernel

Signed-off-by: Marcos Paulo de Souza <marcos.souza.org@gmail.com>
---
 Documentation/input/uinput.rst | 196 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 196 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..eb79b77
--- /dev/null
+++ b/Documentation/input/uinput.rst
@@ -0,0 +1,196 @@
+=============
+uinput module
+=============
+
+Introduction
+============
+
+uinput is a kernel module that makes possible to create and handle input devices
+from userspace. By writing to the module's /dev/uinput (or /dev/input/uinput), a
+process can create a virtual device with specific capabilities.
+Once created, the process can send events through that virtual device.
+
+Interface
+=========
+
+::
+
+  linux/uinput.h
+
+The uinput header defines ioctls to create, setup and destroy virtual devices.
+
+libevdev
+========
+
+libevdev is a wrapper library for evdev devices, making uinput setup easier
+by skipping a lot of ioctl calls. When dealing with uinput, libevdev is the best
+alternative over accessing uinput directly, and it is less error prone.
+
+For examples and more information about libevdev:
+https://cgit.freedesktop.org/libevdev
+
+Examples
+========
+
+1.0 Keyboard events
+-------------------
+
+This first example shows how to create a new virtual device and how to send a
+key event. 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;
+
+        ie.type = type;
+        ie.code = code;
+        ie.value = val;
+        /* below timestamp values are ignored */
+        ie.time.tv_sec = 0;
+        ie.time.tv_usec = 0;
+
+        write(fd, &ie, sizeof(ie));
+   }
+
+   int main() {
+        struct uinput_setup usetup;
+
+        fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
+
+        /* the ioctls below enables the to be created device to key
+         * events, in this case the space key
+         **/
+        ioctl(fd, UI_SET_EVBIT, EV_KEY);
+        ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
+
+        memset(&usetup, 0, sizeof(usetup));
+        usetup.id.bustype = BUS_USB;
+        usetup.id.vendor = 0x1234; /* sample vendor */
+        strcpy(usetup.name, "Example device");
+
+        ioctl(fd, UI_DEV_SETUP, &usetup);
+        ioctl(fd, UI_DEV_CREATE);
+
+        /* UI_DEV_CREATE causes the kernel to create the device nodes for this
+         * device. Insert a pause so that userspace has time to detect,
+         * initialize the new device, and can start to listen to events from
+         * this device
+         **/
+
+        /* 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);
+
+        ioctl(fd, UI_DEV_DESTROY);
+        close(fd);
+
+        return 0;
+   }
+
+2.0 Mouse movements
+-------------------
+
+This example shows how to create a virtual device that behaves like a physical
+mouse.
+
+.. code-block:: c
+
+    #include <linux/uinput.h>
+
+    /* emit function is identical to of the first example */
+
+    struct uinput_setup usetup;
+    int i = 50;
+
+    fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
+
+    /* enable mouse button left and relative events */
+    ioctl(fd, UI_SET_EVBIT, EV_KEY);
+    ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
+
+    ioctl(fd, UI_SET_EVBIT, EV_REL);
+    ioctl(fd, UI_SET_RELBIT, REL_X);
+    ioctl(fd, UI_SET_RELBIT, REL_Y);
+
+    memset(&usetup, 0, sizeof(usetup));
+    usetup.id.bustype = BUS_USB;
+    usetup.id.vendor = 0x1234; /* sample vendor */
+    strcpy(usetup.name, "Example device");
+
+    ioctl(fd, UI_DEV_SETUP, &usetup);
+    ioctl(fd, UI_DEV_CREATE);
+
+    /* UI_DEV_CREATE causes the kernel to create the device nodes for this
+     * device. Insert a pause so that userspace has time to detect,
+     * initialize the new device, and can start to listen to events from
+     * this device
+     **/
+
+    /* moves the mouse diagonally, 5 units per axis */
+    while (i--) {
+        emit(EV_REL, REL_X, 5);
+        emit(EV_REL, REL_Y, 5);
+        emit(EV_SYN, SYN_REPORT, 0);
+        usleep(15000);
+    }
+
+    ioctl(fd, UI_DEV_DESTROY);
+    close(fd);
+
+    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
+
+    #include <linux/uinput.h>
+
+    /* emit function is identical to of the first example */
+
+    struct uinput_user_dev uud;
+
+    fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
+
+    /* the ioctls below enables the to be created device to key
+     * events, in this case the space key
+     **/
+    ioctl(fd, UI_SET_EVBIT, EV_KEY);
+    ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
+
+    memset(&uud, 0, sizeof(uud));
+    snprintf(uud.name, UINPUT_MAX_NAME_SIZE, "uinput old interface");
+    write(fd, &uud, sizeof(uud));
+
+    ioctl(fd, UI_DEV_CREATE);
+
+    /* UI_DEV_CREATE causes the kernel to create the device nodes for this
+     * device. Insert a pause so that userspace has time to detect,
+     * initialize the new device, and can start to listen to events from
+     * this device
+     **/
+
+    /* 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);
+
+    ioctl(fd, UI_DEV_DESTROY);
+    close(fd);
+
+    return 0;
+
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] Documentation: Input: Add uinput documentation
  2017-03-24  3:34 ` [PATCH v2] Documentation: Input: Add " Marcos Paulo de Souza
@ 2017-03-24  4:39   ` Peter Hutterer
  2017-03-26 16:21     ` Marcos Paulo de Souza
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Hutterer @ 2017-03-24  4:39 UTC (permalink / raw)
  To: Marcos Paulo de Souza
  Cc: corbet, linux-doc, dmitry.torokhov, linux-input,
	benjamin.tissoires, linux-kernel

as usual, reading through these things multiple times means one spots a
couple of different things. sorry about that.

On Fri, Mar 24, 2017 at 12:34:59AM -0300, Marcos Paulo de Souza wrote:
> Signed-off-by: Marcos Paulo de Souza <marcos.souza.org@gmail.com>
> ---
>  Documentation/input/uinput.rst | 196 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 196 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..eb79b77
> --- /dev/null
> +++ b/Documentation/input/uinput.rst
> @@ -0,0 +1,196 @@
> +=============
> +uinput module
> +=============
> +
> +Introduction
> +============
> +
> +uinput is a kernel module that makes possible to create and handle input devices

typo: makes *it* possible.

replace "to create and handle" with "to emulate", the rest is in the next
sentence anyway

> +from userspace. By writing to the module's /dev/uinput (or /dev/input/uinput), a
> +process can create a virtual device with specific capabilities.
> +Once created, the process can send events through that virtual device.
> +
> +Interface
> +=========
> +
> +::
> +
> +  linux/uinput.h
> +
> +The uinput header defines ioctls to create, setup and destroy virtual devices.
> +
> +libevdev
> +========
> +
> +libevdev is a wrapper library for evdev devices, making uinput setup easier
> +by skipping a lot of ioctl calls. When dealing with uinput, libevdev is the best
> +alternative over accessing uinput directly, and it is less error prone.

"libevdev is a wrapper library for evdev devices that provides interfaces to
create uinput devices and send events. libevdev is less error-prone than
accessing uinput directly and should be considered for new software".

> +
> +For examples and more information about libevdev:
> +https://cgit.freedesktop.org/libevdev
> +

Please use https://www.freedesktop.org/software/libevdev/doc/latest/
(which needs a link to the git repo, I'll fix that in a minute)

> +Examples
> +========
> +
> +1.0 Keyboard events
> +-------------------
> +
> +This first example shows how to create a new virtual device and how to send a
> +key event. 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;
> +
> +        ie.type = type;
> +        ie.code = code;
> +        ie.value = val;
> +        /* below timestamp values are ignored */
> +        ie.time.tv_sec = 0;
> +        ie.time.tv_usec = 0;
> +
> +        write(fd, &ie, sizeof(ie));
> +   }
> +
> +   int main() {
> +        struct uinput_setup usetup;
> +
> +        fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
> +
> +        /* the ioctls below enables the to be created device to key
> +         * events, in this case the space key
> +         **/

the comment terminator doesn't look right

> +        ioctl(fd, UI_SET_EVBIT, EV_KEY);
> +        ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
> +
> +        memset(&usetup, 0, sizeof(usetup));
> +        usetup.id.bustype = BUS_USB;
> +        usetup.id.vendor = 0x1234; /* sample vendor */

add a sample product id too please

> +        strcpy(usetup.name, "Example device");
> +
> +        ioctl(fd, UI_DEV_SETUP, &usetup);
> +        ioctl(fd, UI_DEV_CREATE);
> +
> +        /* UI_DEV_CREATE causes the kernel to create the device nodes for this

"On UI_DEV_CREATE the kernel creates the device nodes..."

> +         * device. Insert a pause so that userspace has time to detect,
> +         * initialize the new device, and can start to listen to events from
> +         * this device
> +         **/

the comment terminator doesn't look right

note: the actual pause is missing now :)

> +
> +        /* 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);

come to think of it, you probably need a pause here too, iirc a caller may
get ENODEV before reading the key events otherwise.

> +
> +        ioctl(fd, UI_DEV_DESTROY);
> +        close(fd);
> +
> +        return 0;
> +   }
> +
> +2.0 Mouse movements
> +-------------------
> +
> +This example shows how to create a virtual device that behaves like a physical
> +mouse.
> +
> +.. code-block:: c
> +
> +    #include <linux/uinput.h>
> +
> +    /* emit function is identical to of the first example */
> +
> +    struct uinput_setup usetup;
> +    int i = 50;
> +
> +    fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
> +
> +    /* enable mouse button left and relative events */
> +    ioctl(fd, UI_SET_EVBIT, EV_KEY);
> +    ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
> +
> +    ioctl(fd, UI_SET_EVBIT, EV_REL);
> +    ioctl(fd, UI_SET_RELBIT, REL_X);
> +    ioctl(fd, UI_SET_RELBIT, REL_Y);
> +
> +    memset(&usetup, 0, sizeof(usetup));
> +    usetup.id.bustype = BUS_USB;
> +    usetup.id.vendor = 0x1234; /* sample vendor */
> +    strcpy(usetup.name, "Example device");
> +
> +    ioctl(fd, UI_DEV_SETUP, &usetup);
> +    ioctl(fd, UI_DEV_CREATE);
> +
> +    /* UI_DEV_CREATE causes the kernel to create the device nodes for this
> +     * device. Insert a pause so that userspace has time to detect,
> +     * initialize the new device, and can start to listen to events from
> +     * this device
> +     **/
> +
> +    /* moves the mouse diagonally, 5 units per axis */
> +    while (i--) {
> +        emit(EV_REL, REL_X, 5);
> +        emit(EV_REL, REL_Y, 5);
> +        emit(EV_SYN, SYN_REPORT, 0);
> +        usleep(15000);
> +    }
> +
> +    ioctl(fd, UI_DEV_DESTROY);
> +    close(fd);
> +
> +    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.

I think this should really include the version check.

Cheers,
   Peter

> +
> +.. code-block:: c
> +
> +    #include <linux/uinput.h>
> +
> +    /* emit function is identical to of the first example */
> +
> +    struct uinput_user_dev uud;
> +
> +    fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
> +
> +    /* the ioctls below enables the to be created device to key
> +     * events, in this case the space key
> +     **/
> +    ioctl(fd, UI_SET_EVBIT, EV_KEY);
> +    ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
> +
> +    memset(&uud, 0, sizeof(uud));
> +    snprintf(uud.name, UINPUT_MAX_NAME_SIZE, "uinput old interface");
> +    write(fd, &uud, sizeof(uud));
> +
> +    ioctl(fd, UI_DEV_CREATE);
> +
> +    /* UI_DEV_CREATE causes the kernel to create the device nodes for this
> +     * device. Insert a pause so that userspace has time to detect,
> +     * initialize the new device, and can start to listen to events from
> +     * this device
> +     **/
> +
> +    /* 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);
> +
> +    ioctl(fd, UI_DEV_DESTROY);
> +    close(fd);
> +
> +    return 0;
> +
> -- 
> 2.9.3
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] Docs: Input: initial uinput documentation
  2017-03-24  3:34 [PATCH v2] Docs: Input: initial uinput documentation Marcos Paulo de Souza
  2017-03-24  3:34 ` [PATCH v2] Documentation: Input: Add " Marcos Paulo de Souza
@ 2017-03-24 21:17 ` Jonathan Corbet
  2017-03-26 16:41   ` Marcos Paulo de Souza
  1 sibling, 1 reply; 9+ messages in thread
From: Jonathan Corbet @ 2017-03-24 21:17 UTC (permalink / raw)
  To: Marcos Paulo de Souza
  Cc: linux-doc, dmitry.torokhov, linux-input, benjamin.tissoires,
	peter.hutterer

On Fri, 24 Mar 2017 00:34:58 -0300
Marcos Paulo de Souza <marcos.souza.org@gmail.com> wrote:

> this is the second iteration of this patch. The first version can be checked
> here[1]. A special thanks to Peter Hutterer who dug the last patch and suggested
> a lot of changes , hopefully, all addressed in this version.

This seems like a good start.  Of course, I have a couple of comments...

1) RST documentation is good, but it really needs to be hooked into the
   docs build with the rest.  In this case, it needs to go into the
   application developer's manual.  The only slight snag is ... well ...
   that manual doesn't quite exist yet.  Once this is ready, if it comes
   through me tree, I can follow it with a patch creating that manual and
   moving this section into it.

2) We don't normally put in section numbers manually in RST documents,
   since Sphinx will do that for us.

3) Section 3.0 covers the old interface.  I'm not sure we need that in 
   documentation in current kernels which, by definition, have the
   current interface.

Thanks,

jon

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] Documentation: Input: Add uinput documentation
  2017-03-24  4:39   ` Peter Hutterer
@ 2017-03-26 16:21     ` Marcos Paulo de Souza
  2017-03-26 22:52       ` Peter Hutterer
  0 siblings, 1 reply; 9+ messages in thread
From: Marcos Paulo de Souza @ 2017-03-26 16:21 UTC (permalink / raw)
  To: Peter Hutterer
  Cc: corbet, linux-doc, dmitry.torokhov, linux-input,
	benjamin.tissoires, linux-kernel

On Fri, Mar 24, 2017 at 02:39:13PM +1000, Peter Hutterer wrote:
> as usual, reading through these things multiple times means one spots a
> couple of different things. sorry about that.
> 
> On Fri, Mar 24, 2017 at 12:34:59AM -0300, Marcos Paulo de Souza wrote:
> > Signed-off-by: Marcos Paulo de Souza <marcos.souza.org@gmail.com>
> > ---
> >  Documentation/input/uinput.rst | 196 +++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 196 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..eb79b77
> > --- /dev/null
> > +++ b/Documentation/input/uinput.rst
> > @@ -0,0 +1,196 @@
> > +=============
> > +uinput module
> > +=============
> > +
> > +Introduction
> > +============
> > +
> > +uinput is a kernel module that makes possible to create and handle input devices
> 
> typo: makes *it* possible.
> 
> replace "to create and handle" with "to emulate", the rest is in the next
> sentence anyway

Fixed.

> 
> > +from userspace. By writing to the module's /dev/uinput (or /dev/input/uinput), a
> > +process can create a virtual device with specific capabilities.
> > +Once created, the process can send events through that virtual device.
> > +
> > +Interface
> > +=========
> > +
> > +::
> > +
> > +  linux/uinput.h
> > +
> > +The uinput header defines ioctls to create, setup and destroy virtual devices.
> > +
> > +libevdev
> > +========
> > +
> > +libevdev is a wrapper library for evdev devices, making uinput setup easier
> > +by skipping a lot of ioctl calls. When dealing with uinput, libevdev is the best
> > +alternative over accessing uinput directly, and it is less error prone.
> 
> "libevdev is a wrapper library for evdev devices that provides interfaces to
> create uinput devices and send events. libevdev is less error-prone than
> accessing uinput directly and should be considered for new software".

Much better. Fixed.

> 
> > +
> > +For examples and more information about libevdev:
> > +https://cgit.freedesktop.org/libevdev
> > +
> 
> Please use https://www.freedesktop.org/software/libevdev/doc/latest/
> (which needs a link to the git repo, I'll fix that in a minute)

Fixed.

> 
> > +Examples
> > +========
> > +
> > +1.0 Keyboard events
> > +-------------------
> > +
> > +This first example shows how to create a new virtual device and how to send a
> > +key event. 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;
> > +
> > +        ie.type = type;
> > +        ie.code = code;
> > +        ie.value = val;
> > +        /* below timestamp values are ignored */
> > +        ie.time.tv_sec = 0;
> > +        ie.time.tv_usec = 0;
> > +
> > +        write(fd, &ie, sizeof(ie));
> > +   }
> > +
> > +   int main() {
> > +        struct uinput_setup usetup;
> > +
> > +        fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
> > +
> > +        /* the ioctls below enables the to be created device to key
> > +         * events, in this case the space key
> > +         **/
> 
> the comment terminator doesn't look right

Fixed.

> 
> > +        ioctl(fd, UI_SET_EVBIT, EV_KEY);
> > +        ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
> > +
> > +        memset(&usetup, 0, sizeof(usetup));
> > +        usetup.id.bustype = BUS_USB;
> > +        usetup.id.vendor = 0x1234; /* sample vendor */
> 
> add a sample product id too please
Added.

> 
> > +        strcpy(usetup.name, "Example device");
> > +
> > +        ioctl(fd, UI_DEV_SETUP, &usetup);
> > +        ioctl(fd, UI_DEV_CREATE);
> > +
> > +        /* UI_DEV_CREATE causes the kernel to create the device nodes for this
> 
> "On UI_DEV_CREATE the kernel creates the device nodes..."
Fixed.

> 
> > +         * device. Insert a pause so that userspace has time to detect,
> > +         * initialize the new device, and can start to listen to events from
> > +         * this device
> > +         **/
> 
> the comment terminator doesn't look right
> 
> note: the actual pause is missing now :)

I thought you wanted just the warning, but ok, I added back the sleep
call :)

> 
> > +
> > +        /* 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);
> 
> come to think of it, you probably need a pause here too, iirc a caller may
> get ENODEV before reading the key events otherwise.

We need a sleep call after each emitted event?

> 
> > +
> > +        ioctl(fd, UI_DEV_DESTROY);
> > +        close(fd);
> > +
> > +        return 0;
> > +   }
> > +
> > +2.0 Mouse movements
> > +-------------------
> > +
> > +This example shows how to create a virtual device that behaves like a physical
> > +mouse.
> > +
> > +.. code-block:: c
> > +
> > +    #include <linux/uinput.h>
> > +
> > +    /* emit function is identical to of the first example */
> > +
> > +    struct uinput_setup usetup;
> > +    int i = 50;
> > +
> > +    fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
> > +
> > +    /* enable mouse button left and relative events */
> > +    ioctl(fd, UI_SET_EVBIT, EV_KEY);
> > +    ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
> > +
> > +    ioctl(fd, UI_SET_EVBIT, EV_REL);
> > +    ioctl(fd, UI_SET_RELBIT, REL_X);
> > +    ioctl(fd, UI_SET_RELBIT, REL_Y);
> > +
> > +    memset(&usetup, 0, sizeof(usetup));
> > +    usetup.id.bustype = BUS_USB;
> > +    usetup.id.vendor = 0x1234; /* sample vendor */
> > +    strcpy(usetup.name, "Example device");
> > +
> > +    ioctl(fd, UI_DEV_SETUP, &usetup);
> > +    ioctl(fd, UI_DEV_CREATE);
> > +
> > +    /* UI_DEV_CREATE causes the kernel to create the device nodes for this
> > +     * device. Insert a pause so that userspace has time to detect,
> > +     * initialize the new device, and can start to listen to events from
> > +     * this device
> > +     **/
> > +
> > +    /* moves the mouse diagonally, 5 units per axis */
> > +    while (i--) {
> > +        emit(EV_REL, REL_X, 5);
> > +        emit(EV_REL, REL_Y, 5);
> > +        emit(EV_SYN, SYN_REPORT, 0);
> > +        usleep(15000);
> > +    }
> > +
> > +    ioctl(fd, UI_DEV_DESTROY);
> > +    close(fd);
> > +
> > +    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.
> 
> I think this should really include the version check.

Uhg, I forgot this one again. Fixed here.

Sending a new version soon.

> 
> Cheers,
>    Peter
> 
> > +
> > +.. code-block:: c
> > +
> > +    #include <linux/uinput.h>
> > +
> > +    /* emit function is identical to of the first example */
> > +
> > +    struct uinput_user_dev uud;
> > +
> > +    fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
> > +
> > +    /* the ioctls below enables the to be created device to key
> > +     * events, in this case the space key
> > +     **/
> > +    ioctl(fd, UI_SET_EVBIT, EV_KEY);
> > +    ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
> > +
> > +    memset(&uud, 0, sizeof(uud));
> > +    snprintf(uud.name, UINPUT_MAX_NAME_SIZE, "uinput old interface");
> > +    write(fd, &uud, sizeof(uud));
> > +
> > +    ioctl(fd, UI_DEV_CREATE);
> > +
> > +    /* UI_DEV_CREATE causes the kernel to create the device nodes for this
> > +     * device. Insert a pause so that userspace has time to detect,
> > +     * initialize the new device, and can start to listen to events from
> > +     * this device
> > +     **/
> > +
> > +    /* 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);
> > +
> > +    ioctl(fd, UI_DEV_DESTROY);
> > +    close(fd);
> > +
> > +    return 0;
> > +
> > -- 
> > 2.9.3
> > 

-- 
Thanks,
	Marcos

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] Docs: Input: initial uinput documentation
  2017-03-24 21:17 ` [PATCH v2] Docs: Input: initial " Jonathan Corbet
@ 2017-03-26 16:41   ` Marcos Paulo de Souza
  2017-03-26 23:08     ` Peter Hutterer
  0 siblings, 1 reply; 9+ messages in thread
From: Marcos Paulo de Souza @ 2017-03-26 16:41 UTC (permalink / raw)
  To: Jonathan Corbet
  Cc: linux-doc, dmitry.torokhov, linux-input, benjamin.tissoires,
	peter.hutterer

Hi Jon,

On Fri, Mar 24, 2017 at 03:17:03PM -0600, Jonathan Corbet wrote:
> On Fri, 24 Mar 2017 00:34:58 -0300
> Marcos Paulo de Souza <marcos.souza.org@gmail.com> wrote:
> 
> > this is the second iteration of this patch. The first version can be checked
> > here[1]. A special thanks to Peter Hutterer who dug the last patch and suggested
> > a lot of changes , hopefully, all addressed in this version.
> 
> This seems like a good start.  Of course, I have a couple of comments...
> 
> 1) RST documentation is good, but it really needs to be hooked into the
>    docs build with the rest.  In this case, it needs to go into the
>    application developer's manual.  The only slight snag is ... well ...
>    that manual doesn't quite exist yet.  Once this is ready, if it comes
>    through me tree, I can follow it with a patch creating that manual and
>    moving this section into it.

Sounds good. If you want, I can verify and add this new page as well.

> 
> 2) We don't normally put in section numbers manually in RST documents,
>    since Sphinx will do that for us.

Great, fixed here.

> 
> 3) Section 3.0 covers the old interface.  I'm not sure we need that in 
>    documentation in current kernels which, by definition, have the
>    current interface.

Currently both interces can be used in mainline, but this can be nice to have for users
who still run older kernels. But I can remove if you strongly disagree.

> 
> Thanks,
> 
> jon

Thanks for the revision!

-- 
Thanks,
	Marcos

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] Documentation: Input: Add uinput documentation
  2017-03-26 16:21     ` Marcos Paulo de Souza
@ 2017-03-26 22:52       ` Peter Hutterer
  2017-03-27  2:23         ` Marcos Paulo de Souza
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Hutterer @ 2017-03-26 22:52 UTC (permalink / raw)
  To: Marcos Paulo de Souza
  Cc: corbet, linux-doc, dmitry.torokhov, linux-input,
	benjamin.tissoires, linux-kernel

On Sun, Mar 26, 2017 at 01:21:14PM -0300, Marcos Paulo de Souza wrote:
> On Fri, Mar 24, 2017 at 02:39:13PM +1000, Peter Hutterer wrote:
> > as usual, reading through these things multiple times means one spots a
> > couple of different things. sorry about that.
> > 
> > On Fri, Mar 24, 2017 at 12:34:59AM -0300, Marcos Paulo de Souza wrote:
> > > Signed-off-by: Marcos Paulo de Souza <marcos.souza.org@gmail.com>
> > > ---
> > >  Documentation/input/uinput.rst | 196 +++++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 196 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..eb79b77
> > > --- /dev/null
> > > +++ b/Documentation/input/uinput.rst
> > > @@ -0,0 +1,196 @@
> > > +=============
> > > +uinput module
> > > +=============
> > > +
> > > +Introduction
> > > +============
> > > +
> > > +uinput is a kernel module that makes possible to create and handle input devices
> > 
> > typo: makes *it* possible.
> > 
> > replace "to create and handle" with "to emulate", the rest is in the next
> > sentence anyway
> 
> Fixed.
> 
> > 
> > > +from userspace. By writing to the module's /dev/uinput (or /dev/input/uinput), a
> > > +process can create a virtual device with specific capabilities.
> > > +Once created, the process can send events through that virtual device.
> > > +
> > > +Interface
> > > +=========
> > > +
> > > +::
> > > +
> > > +  linux/uinput.h
> > > +
> > > +The uinput header defines ioctls to create, setup and destroy virtual devices.
> > > +
> > > +libevdev
> > > +========
> > > +
> > > +libevdev is a wrapper library for evdev devices, making uinput setup easier
> > > +by skipping a lot of ioctl calls. When dealing with uinput, libevdev is the best
> > > +alternative over accessing uinput directly, and it is less error prone.
> > 
> > "libevdev is a wrapper library for evdev devices that provides interfaces to
> > create uinput devices and send events. libevdev is less error-prone than
> > accessing uinput directly and should be considered for new software".
> 
> Much better. Fixed.
> 
> > 
> > > +
> > > +For examples and more information about libevdev:
> > > +https://cgit.freedesktop.org/libevdev
> > > +
> > 
> > Please use https://www.freedesktop.org/software/libevdev/doc/latest/
> > (which needs a link to the git repo, I'll fix that in a minute)
> 
> Fixed.
> 
> > 
> > > +Examples
> > > +========
> > > +
> > > +1.0 Keyboard events
> > > +-------------------
> > > +
> > > +This first example shows how to create a new virtual device and how to send a
> > > +key event. 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;
> > > +
> > > +        ie.type = type;
> > > +        ie.code = code;
> > > +        ie.value = val;
> > > +        /* below timestamp values are ignored */
> > > +        ie.time.tv_sec = 0;
> > > +        ie.time.tv_usec = 0;
> > > +
> > > +        write(fd, &ie, sizeof(ie));
> > > +   }
> > > +
> > > +   int main() {
> > > +        struct uinput_setup usetup;
> > > +
> > > +        fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
> > > +
> > > +        /* the ioctls below enables the to be created device to key
> > > +         * events, in this case the space key
> > > +         **/
> > 
> > the comment terminator doesn't look right
> 
> Fixed.
> 
> > 
> > > +        ioctl(fd, UI_SET_EVBIT, EV_KEY);
> > > +        ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
> > > +
> > > +        memset(&usetup, 0, sizeof(usetup));
> > > +        usetup.id.bustype = BUS_USB;
> > > +        usetup.id.vendor = 0x1234; /* sample vendor */
> > 
> > add a sample product id too please
> Added.
> 
> > 
> > > +        strcpy(usetup.name, "Example device");
> > > +
> > > +        ioctl(fd, UI_DEV_SETUP, &usetup);
> > > +        ioctl(fd, UI_DEV_CREATE);
> > > +
> > > +        /* UI_DEV_CREATE causes the kernel to create the device nodes for this
> > 
> > "On UI_DEV_CREATE the kernel creates the device nodes..."
> Fixed.
> 
> > 
> > > +         * device. Insert a pause so that userspace has time to detect,
> > > +         * initialize the new device, and can start to listen to events from
> > > +         * this device
> > > +         **/
> > 
> > the comment terminator doesn't look right
> > 
> > note: the actual pause is missing now :)
> 
> I thought you wanted just the warning, but ok, I added back the sleep
> call :)

better to have something that can be copy-pasted and works than expecting
people to add misc bits.

> > > +
> > > +        /* 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);
> > 
> > come to think of it, you probably need a pause here too, iirc a caller may
> > get ENODEV before reading the key events otherwise.
> 
> We need a sleep call after each emitted event?

no, I think we need a sleep between the final emit and the
UI_DEV_DESTROY, otherwise those events may not get delivered (not 100%
sure).

Cheers,
   Peter

> 
> > 
> > > +
> > > +        ioctl(fd, UI_DEV_DESTROY);
> > > +        close(fd);
> > > +
> > > +        return 0;
> > > +   }
> > > +
> > > +2.0 Mouse movements
> > > +-------------------
> > > +
> > > +This example shows how to create a virtual device that behaves like a physical
> > > +mouse.
> > > +
> > > +.. code-block:: c
> > > +
> > > +    #include <linux/uinput.h>
> > > +
> > > +    /* emit function is identical to of the first example */
> > > +
> > > +    struct uinput_setup usetup;
> > > +    int i = 50;
> > > +
> > > +    fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
> > > +
> > > +    /* enable mouse button left and relative events */
> > > +    ioctl(fd, UI_SET_EVBIT, EV_KEY);
> > > +    ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
> > > +
> > > +    ioctl(fd, UI_SET_EVBIT, EV_REL);
> > > +    ioctl(fd, UI_SET_RELBIT, REL_X);
> > > +    ioctl(fd, UI_SET_RELBIT, REL_Y);
> > > +
> > > +    memset(&usetup, 0, sizeof(usetup));
> > > +    usetup.id.bustype = BUS_USB;
> > > +    usetup.id.vendor = 0x1234; /* sample vendor */
> > > +    strcpy(usetup.name, "Example device");
> > > +
> > > +    ioctl(fd, UI_DEV_SETUP, &usetup);
> > > +    ioctl(fd, UI_DEV_CREATE);
> > > +
> > > +    /* UI_DEV_CREATE causes the kernel to create the device nodes for this
> > > +     * device. Insert a pause so that userspace has time to detect,
> > > +     * initialize the new device, and can start to listen to events from
> > > +     * this device
> > > +     **/
> > > +
> > > +    /* moves the mouse diagonally, 5 units per axis */
> > > +    while (i--) {
> > > +        emit(EV_REL, REL_X, 5);
> > > +        emit(EV_REL, REL_Y, 5);
> > > +        emit(EV_SYN, SYN_REPORT, 0);
> > > +        usleep(15000);
> > > +    }
> > > +
> > > +    ioctl(fd, UI_DEV_DESTROY);
> > > +    close(fd);
> > > +
> > > +    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.
> > 
> > I think this should really include the version check.
> 
> Uhg, I forgot this one again. Fixed here.
> 
> Sending a new version soon.
> 
> > 
> > Cheers,
> >    Peter
> > 
> > > +
> > > +.. code-block:: c
> > > +
> > > +    #include <linux/uinput.h>
> > > +
> > > +    /* emit function is identical to of the first example */
> > > +
> > > +    struct uinput_user_dev uud;
> > > +
> > > +    fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
> > > +
> > > +    /* the ioctls below enables the to be created device to key
> > > +     * events, in this case the space key
> > > +     **/
> > > +    ioctl(fd, UI_SET_EVBIT, EV_KEY);
> > > +    ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
> > > +
> > > +    memset(&uud, 0, sizeof(uud));
> > > +    snprintf(uud.name, UINPUT_MAX_NAME_SIZE, "uinput old interface");
> > > +    write(fd, &uud, sizeof(uud));
> > > +
> > > +    ioctl(fd, UI_DEV_CREATE);
> > > +
> > > +    /* UI_DEV_CREATE causes the kernel to create the device nodes for this
> > > +     * device. Insert a pause so that userspace has time to detect,
> > > +     * initialize the new device, and can start to listen to events from
> > > +     * this device
> > > +     **/
> > > +
> > > +    /* 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);
> > > +
> > > +    ioctl(fd, UI_DEV_DESTROY);
> > > +    close(fd);
> > > +
> > > +    return 0;
> > > +
> > > -- 
> > > 2.9.3
> > > 
> 
> -- 
> Thanks,
> 	Marcos

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] Docs: Input: initial uinput documentation
  2017-03-26 16:41   ` Marcos Paulo de Souza
@ 2017-03-26 23:08     ` Peter Hutterer
  0 siblings, 0 replies; 9+ messages in thread
From: Peter Hutterer @ 2017-03-26 23:08 UTC (permalink / raw)
  To: Marcos Paulo de Souza
  Cc: Jonathan Corbet, linux-doc, dmitry.torokhov, linux-input,
	benjamin.tissoires

On Sun, Mar 26, 2017 at 01:41:08PM -0300, Marcos Paulo de Souza wrote:
> Hi Jon,
> 
> On Fri, Mar 24, 2017 at 03:17:03PM -0600, Jonathan Corbet wrote:
> > On Fri, 24 Mar 2017 00:34:58 -0300
> > Marcos Paulo de Souza <marcos.souza.org@gmail.com> wrote:
> > 
> > > this is the second iteration of this patch. The first version can be checked
> > > here[1]. A special thanks to Peter Hutterer who dug the last patch and suggested
> > > a lot of changes , hopefully, all addressed in this version.
> > 
> > This seems like a good start.  Of course, I have a couple of comments...
> > 
> > 1) RST documentation is good, but it really needs to be hooked into the
> >    docs build with the rest.  In this case, it needs to go into the
> >    application developer's manual.  The only slight snag is ... well ...
> >    that manual doesn't quite exist yet.  Once this is ready, if it comes
> >    through me tree, I can follow it with a patch creating that manual and
> >    moving this section into it.
> 
> Sounds good. If you want, I can verify and add this new page as well.
> 
> > 
> > 2) We don't normally put in section numbers manually in RST documents,
> >    since Sphinx will do that for us.
> 
> Great, fixed here.
> 
> > 
> > 3) Section 3.0 covers the old interface.  I'm not sure we need that in 
> >    documentation in current kernels which, by definition, have the
> >    current interface.
> 
> Currently both interces can be used in mainline, but this can be nice to have for users
> who still run older kernels. But I can remove if you strongly disagree.

Given the kernel's policy for retiring interfaces, the old interface will be
available forever. But at this point you shouldn't be writing new software
against the old interface.

Cheers,
   Peter

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] Documentation: Input: Add uinput documentation
  2017-03-26 22:52       ` Peter Hutterer
@ 2017-03-27  2:23         ` Marcos Paulo de Souza
  0 siblings, 0 replies; 9+ messages in thread
From: Marcos Paulo de Souza @ 2017-03-27  2:23 UTC (permalink / raw)
  To: Peter Hutterer
  Cc: corbet, linux-doc, dmitry.torokhov, linux-input,
	benjamin.tissoires, linux-kernel

On Mon, Mar 27, 2017 at 08:52:58AM +1000, Peter Hutterer wrote:
> On Sun, Mar 26, 2017 at 01:21:14PM -0300, Marcos Paulo de Souza wrote:
> > On Fri, Mar 24, 2017 at 02:39:13PM +1000, Peter Hutterer wrote:
> > > as usual, reading through these things multiple times means one spots a
> > > couple of different things. sorry about that.
> > > 
> > > On Fri, Mar 24, 2017 at 12:34:59AM -0300, Marcos Paulo de Souza wrote:
> > > > Signed-off-by: Marcos Paulo de Souza <marcos.souza.org@gmail.com>
> > > > ---
> > > >  Documentation/input/uinput.rst | 196 +++++++++++++++++++++++++++++++++++++++++
> > > >  1 file changed, 196 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..eb79b77
> > > > --- /dev/null
> > > > +++ b/Documentation/input/uinput.rst
> > > > @@ -0,0 +1,196 @@
> > > > +=============
> > > > +uinput module
> > > > +=============
> > > > +
> > > > +Introduction
> > > > +============
> > > > +
> > > > +uinput is a kernel module that makes possible to create and handle input devices
> > > 
> > > typo: makes *it* possible.
> > > 
> > > replace "to create and handle" with "to emulate", the rest is in the next
> > > sentence anyway
> > 
> > Fixed.
> > 
> > > 
> > > > +from userspace. By writing to the module's /dev/uinput (or /dev/input/uinput), a
> > > > +process can create a virtual device with specific capabilities.
> > > > +Once created, the process can send events through that virtual device.
> > > > +
> > > > +Interface
> > > > +=========
> > > > +
> > > > +::
> > > > +
> > > > +  linux/uinput.h
> > > > +
> > > > +The uinput header defines ioctls to create, setup and destroy virtual devices.
> > > > +
> > > > +libevdev
> > > > +========
> > > > +
> > > > +libevdev is a wrapper library for evdev devices, making uinput setup easier
> > > > +by skipping a lot of ioctl calls. When dealing with uinput, libevdev is the best
> > > > +alternative over accessing uinput directly, and it is less error prone.
> > > 
> > > "libevdev is a wrapper library for evdev devices that provides interfaces to
> > > create uinput devices and send events. libevdev is less error-prone than
> > > accessing uinput directly and should be considered for new software".
> > 
> > Much better. Fixed.
> > 
> > > 
> > > > +
> > > > +For examples and more information about libevdev:
> > > > +https://cgit.freedesktop.org/libevdev
> > > > +
> > > 
> > > Please use https://www.freedesktop.org/software/libevdev/doc/latest/
> > > (which needs a link to the git repo, I'll fix that in a minute)
> > 
> > Fixed.
> > 
> > > 
> > > > +Examples
> > > > +========
> > > > +
> > > > +1.0 Keyboard events
> > > > +-------------------
> > > > +
> > > > +This first example shows how to create a new virtual device and how to send a
> > > > +key event. 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;
> > > > +
> > > > +        ie.type = type;
> > > > +        ie.code = code;
> > > > +        ie.value = val;
> > > > +        /* below timestamp values are ignored */
> > > > +        ie.time.tv_sec = 0;
> > > > +        ie.time.tv_usec = 0;
> > > > +
> > > > +        write(fd, &ie, sizeof(ie));
> > > > +   }
> > > > +
> > > > +   int main() {
> > > > +        struct uinput_setup usetup;
> > > > +
> > > > +        fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
> > > > +
> > > > +        /* the ioctls below enables the to be created device to key
> > > > +         * events, in this case the space key
> > > > +         **/
> > > 
> > > the comment terminator doesn't look right
> > 
> > Fixed.
> > 
> > > 
> > > > +        ioctl(fd, UI_SET_EVBIT, EV_KEY);
> > > > +        ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
> > > > +
> > > > +        memset(&usetup, 0, sizeof(usetup));
> > > > +        usetup.id.bustype = BUS_USB;
> > > > +        usetup.id.vendor = 0x1234; /* sample vendor */
> > > 
> > > add a sample product id too please
> > Added.
> > 
> > > 
> > > > +        strcpy(usetup.name, "Example device");
> > > > +
> > > > +        ioctl(fd, UI_DEV_SETUP, &usetup);
> > > > +        ioctl(fd, UI_DEV_CREATE);
> > > > +
> > > > +        /* UI_DEV_CREATE causes the kernel to create the device nodes for this
> > > 
> > > "On UI_DEV_CREATE the kernel creates the device nodes..."
> > Fixed.
> > 
> > > 
> > > > +         * device. Insert a pause so that userspace has time to detect,
> > > > +         * initialize the new device, and can start to listen to events from
> > > > +         * this device
> > > > +         **/
> > > 
> > > the comment terminator doesn't look right
> > > 
> > > note: the actual pause is missing now :)
> > 
> > I thought you wanted just the warning, but ok, I added back the sleep
> > call :)
> 
> better to have something that can be copy-pasted and works than expecting
> people to add misc bits.

Absolutely.

> 
> > > > +
> > > > +        /* 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);
> > > 
> > > come to think of it, you probably need a pause here too, iirc a caller may
> > > get ENODEV before reading the key events otherwise.
> > 
> > We need a sleep call after each emitted event?
> 
> no, I think we need a sleep between the final emit and the
> UI_DEV_DESTROY, otherwise those events may not get delivered (not 100%
> sure).

I can add another comment and another sleep call, if this helps. Adding then in the next submission.

> 
> Cheers,
>    Peter
> 
> > 
> > > 
> > > > +
> > > > +        ioctl(fd, UI_DEV_DESTROY);
> > > > +        close(fd);
> > > > +
> > > > +        return 0;
> > > > +   }
> > > > +
> > > > +2.0 Mouse movements
> > > > +-------------------
> > > > +
> > > > +This example shows how to create a virtual device that behaves like a physical
> > > > +mouse.
> > > > +
> > > > +.. code-block:: c
> > > > +
> > > > +    #include <linux/uinput.h>
> > > > +
> > > > +    /* emit function is identical to of the first example */
> > > > +
> > > > +    struct uinput_setup usetup;
> > > > +    int i = 50;
> > > > +
> > > > +    fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
> > > > +
> > > > +    /* enable mouse button left and relative events */
> > > > +    ioctl(fd, UI_SET_EVBIT, EV_KEY);
> > > > +    ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
> > > > +
> > > > +    ioctl(fd, UI_SET_EVBIT, EV_REL);
> > > > +    ioctl(fd, UI_SET_RELBIT, REL_X);
> > > > +    ioctl(fd, UI_SET_RELBIT, REL_Y);
> > > > +
> > > > +    memset(&usetup, 0, sizeof(usetup));
> > > > +    usetup.id.bustype = BUS_USB;
> > > > +    usetup.id.vendor = 0x1234; /* sample vendor */
> > > > +    strcpy(usetup.name, "Example device");
> > > > +
> > > > +    ioctl(fd, UI_DEV_SETUP, &usetup);
> > > > +    ioctl(fd, UI_DEV_CREATE);
> > > > +
> > > > +    /* UI_DEV_CREATE causes the kernel to create the device nodes for this
> > > > +     * device. Insert a pause so that userspace has time to detect,
> > > > +     * initialize the new device, and can start to listen to events from
> > > > +     * this device
> > > > +     **/
> > > > +
> > > > +    /* moves the mouse diagonally, 5 units per axis */
> > > > +    while (i--) {
> > > > +        emit(EV_REL, REL_X, 5);
> > > > +        emit(EV_REL, REL_Y, 5);
> > > > +        emit(EV_SYN, SYN_REPORT, 0);
> > > > +        usleep(15000);
> > > > +    }
> > > > +
> > > > +    ioctl(fd, UI_DEV_DESTROY);
> > > > +    close(fd);
> > > > +
> > > > +    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.
> > > 
> > > I think this should really include the version check.
> > 
> > Uhg, I forgot this one again. Fixed here.
> > 
> > Sending a new version soon.
> > 
> > > 
> > > Cheers,
> > >    Peter
> > > 
> > > > +
> > > > +.. code-block:: c
> > > > +
> > > > +    #include <linux/uinput.h>
> > > > +
> > > > +    /* emit function is identical to of the first example */
> > > > +
> > > > +    struct uinput_user_dev uud;
> > > > +
> > > > +    fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
> > > > +
> > > > +    /* the ioctls below enables the to be created device to key
> > > > +     * events, in this case the space key
> > > > +     **/
> > > > +    ioctl(fd, UI_SET_EVBIT, EV_KEY);
> > > > +    ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
> > > > +
> > > > +    memset(&uud, 0, sizeof(uud));
> > > > +    snprintf(uud.name, UINPUT_MAX_NAME_SIZE, "uinput old interface");
> > > > +    write(fd, &uud, sizeof(uud));
> > > > +
> > > > +    ioctl(fd, UI_DEV_CREATE);
> > > > +
> > > > +    /* UI_DEV_CREATE causes the kernel to create the device nodes for this
> > > > +     * device. Insert a pause so that userspace has time to detect,
> > > > +     * initialize the new device, and can start to listen to events from
> > > > +     * this device
> > > > +     **/
> > > > +
> > > > +    /* 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);
> > > > +
> > > > +    ioctl(fd, UI_DEV_DESTROY);
> > > > +    close(fd);
> > > > +
> > > > +    return 0;
> > > > +
> > > > -- 
> > > > 2.9.3
> > > > 
> > 
> > -- 
> > Thanks,
> > 	Marcos

-- 
Thanks,
	Marcos

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-03-27  2:32 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-24  3:34 [PATCH v2] Docs: Input: initial uinput documentation Marcos Paulo de Souza
2017-03-24  3:34 ` [PATCH v2] Documentation: Input: Add " Marcos Paulo de Souza
2017-03-24  4:39   ` Peter Hutterer
2017-03-26 16:21     ` Marcos Paulo de Souza
2017-03-26 22:52       ` Peter Hutterer
2017-03-27  2:23         ` Marcos Paulo de Souza
2017-03-24 21:17 ` [PATCH v2] Docs: Input: initial " Jonathan Corbet
2017-03-26 16:41   ` Marcos Paulo de Souza
2017-03-26 23:08     ` Peter Hutterer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.