| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src/relabsd_device.c')
| -rw-r--r-- | src/relabsd_device.c | 137 | 
1 files changed, 137 insertions, 0 deletions
| diff --git a/src/relabsd_device.c b/src/relabsd_device.c new file mode 100644 index 0000000..7d2b761 --- /dev/null +++ b/src/relabsd_device.c @@ -0,0 +1,137 @@ +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> + +#include "error.h" +#include "axis.h" +#include "config.h" + +#include "relabsd_device.h" + +/* LIBEVDEV_UINPUT_OPEN_MANAGED is not defined on my machine. */ +#ifndef LIBEVDEV_UINPUT_OPEN_MANAGED +   #warning "libevdev did not define LIBEVDEV_UINPUT_OPEN_MANAGED, "\ +            "using value '-2' instead." +   #define LIBEVDEV_UINPUT_OPEN_MANAGED -2 +#endif + +static void replace_rel_axis +( +   struct relabsd_device * const dev, +   const struct relabsd_config * const config, +   struct input_absinfo * const absinfo, +   unsigned int rel_code +) +{ +   enum relabsd_axis rad_code; +   unsigned int abs_code; + +   rad_code = relabsd_axis_convert_evdev_rel(rel_code, &abs_code); + +   relabsd_config_get_absinfo(config, rad_code, absinfo); +   libevdev_disable_event_code(dev->dev, EV_REL, rel_code); +   libevdev_enable_event_code(dev->dev, EV_ABS, abs_code, absinfo); +} + +int relabsd_device_create +( +   struct relabsd_device * const dev, +   const struct relabsd_config * const config +) +{ +   struct input_absinfo absinfo; +   int fd; + +   fd = open(config->input_file, O_RDONLY); + +   if (fd < 0) +   { +      _FATAL +      ( +         "Could not open device %s in read only mode:", +         config->input_file, +         strerror(errno) +      ); + +      return -1; +   } + +   if +   ( +      libevdev_new_from_fd(fd, &(dev->dev)) < 0 +   ) +   { +      _FATAL +      ( +         "libevdev could not open %s:", +         config->input_file, +         strerror(errno) +      ); + +      close(fd); + +      return -1; +   } + +   libevdev_set_name(dev->dev, config->device_name); + +   libevdev_enable_event_type(dev->dev, EV_ABS); + +   replace_rel_axis(dev, config, &absinfo, REL_X); +   replace_rel_axis(dev, config, &absinfo, REL_Y); +   replace_rel_axis(dev, config, &absinfo, REL_Z); +   replace_rel_axis(dev, config, &absinfo, REL_RX); +   replace_rel_axis(dev, config, &absinfo, REL_RY); +   replace_rel_axis(dev, config, &absinfo, REL_RZ); + +   if +   ( +       libevdev_uinput_create_from_device +       ( +         dev->dev, +         LIBEVDEV_UINPUT_OPEN_MANAGED, +         &(dev->uidev) +       ) +       < 0 +   ) +   { +      _FATAL("Could not create relabsd device: %s.", strerror(errno)); + +      libevdev_free(dev->dev); + +      close(fd); + +      return -1; +   } + +   close(fd); + +   return 0; +} + +void relabsd_device_destroy (const struct relabsd_device * const dev) +{ +   libevdev_uinput_destroy(dev->uidev); +   libevdev_free(dev->dev); +} + +int relabsd_device_write_evdev_event +( +   const struct relabsd_device * const dev, +   unsigned int const type, +   unsigned int const code, +   int const value +) +{ +   if +   ( +      (libevdev_uinput_write_event(dev->uidev, type, code, value) == 0) +      && (libevdev_uinput_write_event(dev->uidev, EV_SYN, SYN_REPORT, 0) == 0) +   ) +   { +      return 0; +   } + +   return -1; +} | 


