libevdev: uinput device creation

Loading...
Searching...
No Matches
uinput device creation

Creation of uinput devices based on existing libevdev devices. More...

## Functions
int | libevdev_uinput_create_from_device (const struct libevdev *dev, int uinput_fd, struct libevdev_uinput **uinput_dev)
| Create a uinput device based on the given libevdev device.
void | libevdev_uinput_destroy (struct libevdev_uinput *uinput_dev)
| Destroy a previously created uinput device and free associated memory.
int | libevdev_uinput_get_fd (const struct libevdev_uinput *uinput_dev)
| Return the file descriptor used to create this uinput device.
const char * | libevdev_uinput_get_syspath (struct libevdev_uinput *uinput_dev)
| Return the syspath representing this uinput device.
const char * | libevdev_uinput_get_devnode (struct libevdev_uinput *uinput_dev)
| Return the device node representing this uinput device.
int | libevdev_uinput_write_event (const struct libevdev_uinput *uinput_dev, unsigned int type, unsigned int code, int value)
| Post an event through the uinput device.

## Detailed Description

Creation of uinput devices based on existing libevdev devices.

These functions help to create uinput devices that emulate libevdev devices. In the simplest form it serves to duplicate an existing device:

int err;
int fd, uifd;
struct libevdev *dev;
struct libevdev_uinput *uidev;
fd = open("/dev/input/event0", O_RDONLY);
if (fd < 0)
return -errno;
err = libevdev_new_from_fd(fd, &dev);
if (err != 0)
return err;
uifd = open("/dev/uinput", O_RDWR);
if (uifd < 0)
return -errno;
err = libevdev_uinput_create_from_device(dev, uifd, &uidev);
if (err != 0)
return err;
// post a REL_X event
err = libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
if (err != 0)
return err;
err = libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
if (err != 0)
return err;
libevdev_uinput_destroy(uidev);
libevdev_free(dev);
close(uifd);
close(fd);
libevdev_new_from_fd
int libevdev_new_from_fd(int fd, struct libevdev **dev)
Initialize a new libevdev device from the given fd.
libevdev_free
void libevdev_free(struct libevdev *dev)
Clean up and free the libevdev struct.
libevdev_uinput_write_event
int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev, unsigned int type, unsigned int code, int value)
Post an event through the uinput device.
libevdev_uinput_destroy
void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev)
Destroy a previously created uinput device and free associated memory.
libevdev_uinput_create_from_device
int libevdev_uinput_create_from_device(const struct libevdev *dev, int uinput_fd, struct libevdev_uinput **uinput_dev)
Create a uinput device based on the given libevdev device.

Alternatively, a device can be constructed from scratch:

int err;
struct libevdev *dev;
struct libevdev_uinput *uidev;
dev = libevdev_new();
libevdev_set_name(dev, "test device");
libevdev_enable_event_type(dev, EV_REL);
libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
libevdev_enable_event_type(dev, EV_KEY);
libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
libevdev_enable_event_code(dev, EV_KEY, BTN_MIDDLE, NULL);
libevdev_enable_event_code(dev, EV_KEY, BTN_RIGHT, NULL);
err = libevdev_uinput_create_from_device(dev,
LIBEVDEV_UINPUT_OPEN_MANAGED,
&uidev);
if (err != 0)
return err;
// ... do something ...
libevdev_uinput_destroy(uidev);
libevdev_new
struct libevdev * libevdev_new(void)
Initialize a new libevdev device.
libevdev_enable_event_code
int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code, const void *data)
Forcibly enable an event code on this device, even if the underlying device does not support it.
libevdev_enable_event_type
int libevdev_enable_event_type(struct libevdev *dev, unsigned int type)
Forcibly enable an event type on this device, even if the underlying device does not support it.
libevdev_set_name
void libevdev_set_name(struct libevdev *dev, const char *name)
Change the device's name as returned by libevdev_get_name().
LIBEVDEV_UINPUT_OPEN_MANAGED
@ LIBEVDEV_UINPUT_OPEN_MANAGED
let libevdev open and close /dev/uinput
Definition libevdev-uinput.h:114

## Function Documentation

## ◆ libevdev_uinput_create_from_device()

int libevdev_uinput_create_from_device | ( | const struct libevdev * | dev,
|  | int | uinput_fd,
|  | struct libevdev_uinput ** | uinput_dev )

Create a uinput device based on the given libevdev device.

The uinput device will be an exact copy of the libevdev device, minus the bits that uinput doesn't allow to be set.

If uinput_fd is LIBEVDEV_UINPUT_OPEN_MANAGED, libevdev_uinput_create_from_device() will open `/dev/uinput` in read/write mode and manage the file descriptor. Otherwise, uinput_fd must be opened by the caller and opened with the appropriate permissions.

The device's lifetime is tied to the uinput file descriptor, closing it will destroy the uinput device. You should call libevdev_uinput_destroy() before closing the file descriptor to free allocated resources. A file descriptor can only create one uinput device at a time; the second device will fail with -EINVAL.

You don't need to keep the file descriptor variable around, libevdev_uinput_get_fd() will return it when needed.

Note
  Due to limitations in the uinput kernel module, REP_DELAY and REP_PERIOD will default to the kernel defaults, not to the ones set in the source device.
  On FreeBSD, if the UI_GET_SYSNAME ioctl() fails, there is no other way to get a device, and the function call will fail.

Parameters

  | dev | The device to duplicate
  | uinput_fd | LIBEVDEV_UINPUT_OPEN_MANAGED or a file descriptor to `/dev/uinput`,
  [out] | uinput_dev | The newly created libevdev device.

Returns
  0 on success or a negative errno on failure. On failure, the value of uinput_dev is unmodified.

See also
  libevdev_uinput_destroy

## ◆ libevdev_uinput_destroy()

void libevdev_uinput_destroy | ( | struct libevdev_uinput * | uinput_dev | ) |

Destroy a previously created uinput device and free associated memory.

If the device was opened with LIBEVDEV_UINPUT_OPEN_MANAGED, libevdev_uinput_destroy() also closes the file descriptor. Otherwise, the fd is left as-is and must be closed by the caller.

Parameters

  uinput_dev | A previously created uinput device.

## ◆ libevdev_uinput_get_devnode()

const char * libevdev_uinput_get_devnode | ( | struct libevdev_uinput * | uinput_dev | ) |

Return the device node representing this uinput device.

This relies on libevdev_uinput_get_syspath() to provide a valid syspath. See libevdev_uinput_get_syspath() for more details.

Note
  This function may return NULL. libevdev may have to guess the syspath and the device node. See libevdev_uinput_get_syspath() for details.
  On FreeBSD, this function can not return NULL. libudev uses the UI_GET_SYSNAME ioctl to get the device node on this platform and if that fails, the call to libevdev_uinput_create_from_device() fails.

Parameters

  uinput_dev | A previously created uinput device.

Returns
  The device node for this device, in the form of /dev/input/eventN

See also
  libevdev_uinput_get_syspath

## ◆ libevdev_uinput_get_fd()

int libevdev_uinput_get_fd | ( | const struct libevdev_uinput * | uinput_dev | ) |

Return the file descriptor used to create this uinput device.

This is the fd pointing to /dev/uinput. This file descriptor may be used to write events that are emitted by the uinput device. Closing this file descriptor will destroy the uinput device, you should call libevdev_uinput_destroy() first to free allocated resources.

Parameters

  uinput_dev | A previously created uinput device.

Returns
  The file descriptor used to create this device

## ◆ libevdev_uinput_get_syspath()

const char * libevdev_uinput_get_syspath | ( | struct libevdev_uinput * | uinput_dev | ) |

Return the syspath representing this uinput device.

If the UI_GET_SYSNAME ioctl is not available, libevdev makes an educated guess. The UI_GET_SYSNAME ioctl is available since Linux 3.15.

The syspath returned is the one of the input node itself (e.g. /sys/devices/virtual/input/input123), not the syspath of the device node returned with libevdev_uinput_get_devnode().

Note
  This function may return NULL if UI_GET_SYSNAME is not available. In that case, libevdev uses ctime and the device name to guess devices. To avoid false positives, wait at least 1.5s between creating devices that have the same name.
  FreeBSD does not have sysfs, on FreeBSD this function always returns NULL.

Parameters

  uinput_dev | A previously created uinput device.

Returns
  The syspath for this device, including the preceding /sys

See also
  libevdev_uinput_get_devnode

## ◆ libevdev_uinput_write_event()

int libevdev_uinput_write_event | ( | const struct libevdev_uinput * | uinput_dev,
|  | unsigned int | type,
|  | unsigned int | code,
|  | int | value )

Post an event through the uinput device.

It is the caller's responsibility that any event sequence is terminated with an EV_SYN/SYN_REPORT/0 event. Otherwise, listeners on the device node will not see the events until the next EV_SYN event is posted.

Parameters

  uinput_dev | A previously created uinput device.
  type | Event type (EV_ABS, EV_REL, etc.)
  code | Event code (ABS_X, REL_Y, etc.)
  value | The event value

Returns
  0 on success or a negative errno on error