| summaryrefslogtreecommitdiff | 
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2015-09-01 22:48:51 +0200 | 
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2015-09-01 22:48:51 +0200 | 
| commit | 1af58bb8886673ac115f019094853fa763e79187 (patch) | |
| tree | c2ab030898e74288f82c557287272546a990e932 /src | |
Initial commit.
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | src/axis.c | 99 | ||||
| -rw-r--r-- | src/axis.h | 23 | ||||
| -rw-r--r-- | src/config.c | 256 | ||||
| -rw-r--r-- | src/config.h | 49 | ||||
| -rw-r--r-- | src/error.h | 123 | ||||
| -rw-r--r-- | src/input.c | 150 | ||||
| -rw-r--r-- | src/input.h | 28 | ||||
| -rw-r--r-- | src/main.c | 110 | ||||
| -rw-r--r-- | src/pervasive.h | 13 | ||||
| -rw-r--r-- | src/relabsd_device.c | 137 | ||||
| -rw-r--r-- | src/relabsd_device.h | 31 | 
12 files changed, 1029 insertions, 0 deletions
| diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..98af72c --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,10 @@ +set( +   SRC_FILES ${SRC_FILES} +   ${CMAKE_CURRENT_SOURCE_DIR}/main.c +   ${CMAKE_CURRENT_SOURCE_DIR}/config.c +   ${CMAKE_CURRENT_SOURCE_DIR}/input.c +   ${CMAKE_CURRENT_SOURCE_DIR}/axis.c +   ${CMAKE_CURRENT_SOURCE_DIR}/relabsd_device.c +) + +set(SRC_FILES ${SRC_FILES} PARENT_SCOPE) diff --git a/src/axis.c b/src/axis.c new file mode 100644 index 0000000..1ba09f0 --- /dev/null +++ b/src/axis.c @@ -0,0 +1,99 @@ +#include <libevdev/libevdev.h> + +#include "pervasive.h" + +#include "axis.h" + +enum relabsd_axis relabsd_axis_name_to_enum (char * const name) +{ +   if (_IS_PREFIX("X", name)) +   { +      return RELABSD_X; +   } +   else if (_IS_PREFIX("Y", name)) +   { +      return RELABSD_Y; +   } +   else if (_IS_PREFIX("Z", name)) +   { +      return RELABSD_Z; +   } +   else if (_IS_PREFIX("RX", name)) +   { +      return RELABSD_RX; +   } +   else if (_IS_PREFIX("RY", name)) +   { +      return RELABSD_RY; +   } +   else if (_IS_PREFIX("RZ", name)) +   { +      return RELABSD_RZ; +   } + +   return RELABSD_UNKNOWN; +} + +char * relabsd_axis_enum_to_name (enum relabsd_axis const e) +{ +   switch (e) +   { +      case RELABSD_X: +         return "X"; + +      case RELABSD_Y: +         return "Y"; + +      case RELABSD_Z: +         return "Z"; + +      case RELABSD_RX: +         return "RX"; + +      case RELABSD_RY: +         return "RY"; + +      case RELABSD_RZ: +         return "RZ"; + +      case RELABSD_UNKNOWN: +         return "??"; +   } +} + +enum relabsd_axis relabsd_axis_convert_evdev_rel +( +   unsigned int const rel_code, +   unsigned int * const abs_code +) +{ +   switch (rel_code) +   { +      case REL_X: +         *abs_code = ABS_X; +         return RELABSD_X; + +      case REL_Y: +         *abs_code = ABS_Y; +         return RELABSD_Y; + +      case REL_Z: +         *abs_code = ABS_Z; +         return RELABSD_Z; + +      case REL_RX: +         *abs_code = ABS_RX; +         return RELABSD_RX; + +      case REL_RY: +         *abs_code = ABS_RY; +         return RELABSD_RY; + +      case REL_RZ: +         *abs_code = ABS_RZ; +         return RELABSD_RZ; + +      default: +         return RELABSD_UNKNOWN; +   } +} diff --git a/src/axis.h b/src/axis.h new file mode 100644 index 0000000..6d4f7f5 --- /dev/null +++ b/src/axis.h @@ -0,0 +1,23 @@ +#ifndef RELABSD_AXIS_H +#define RELABSD_AXIS_H + +enum relabsd_axis +{ +   RELABSD_X, +   RELABSD_Y, +   RELABSD_Z, +   RELABSD_RX, +   RELABSD_RY, +   RELABSD_RZ, +   RELABSD_UNKNOWN +}; + +enum relabsd_axis relabsd_axis_name_to_enum (char * const name); +char * relabsd_axis_enum_to_name (enum relabsd_axis const e); +enum relabsd_axis relabsd_axis_convert_evdev_rel +( +   unsigned int const rel_code, +   unsigned int * const abs_code +); + +#endif diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..1699811 --- /dev/null +++ b/src/config.c @@ -0,0 +1,256 @@ +#include <errno.h> +#include <string.h> + +#include "error.h" +#include "pervasive.h" +#include "axis.h" +#include "config.h" + +static int reach_next_line_or_eof (FILE * const f) +{ +   char c; +   c = getc(f); + +   while ((c != '\n') && c != EOF) +   { +      c = getc(f); +   } + +   if (c == EOF) +   { +      return -1; +   } + +   return 0; +} + +static int all_axis_are_configured (const int * const axis_is_configured) +{ +   int i; + +   for (i = 0; i < 6; ++i) +   { +      if (axis_is_configured[i] == 0) +      { +         _FATAL +         ( +            "[CONFIG] Axis '%s' is not configured.", +            relabsd_axis_enum_to_name((enum relabsd_axis) i) +         ); + +         return -1; +      } +   } + +   return 0; +} + +static int parse_axis_configuration_line +( +   struct relabsd_config * const conf, +   FILE * const f, +   int * const axis_is_configured, +   char * const buffer +) +{ +   int valc; +   enum relabsd_axis axis; + +   axis = relabsd_axis_name_to_enum(buffer); + +   if (axis == RELABSD_UNKNOWN) +   { +      _FATAL +      ( +         "[CONFIG] Unknown axis '%s'.", +         buffer +      ); + +      return -1; +   } + +    valc = +      fscanf +      ( +         f, +         "%d %d %d %d %d", +         &(conf->axis[axis].min), +         &(conf->axis[axis].max), +         &(conf->axis[axis].fuzz), +         &(conf->axis[axis].flat), +         &(conf->axis[axis].resolution) +      ); + +   if (valc == EOF) +   { +      _FATAL +      ( +         "[CONFIG] Unexpected end of file while reading axis '%s'.", +         buffer +      ); + +      return -1; +   } +   else if (valc < 5) +   { +      _FATAL +      ( +         "[CONFIG] Invalid parameter count for axis '%s'.", +         buffer +      ); + +      return -1; +   } + +   axis_is_configured[axis] = 1; +   return 0; +} + +static int read_config_file +( +   struct relabsd_config * const conf, +   char * const filename +) +{ +   FILE * f; +   int axis_is_configured[6]; +   char buffer[3]; +   int test; + +   buffer[2] = '\0'; + +   memset(axis_is_configured, 0, 6 * sizeof(int)); + +   f = fopen(filename, "r"); + +   if (f == (FILE *) NULL) +   { +      _FATAL +      ( +         "[CONFIG] Could not open file: %s.", +         strerror(errno) +      ); + +      return -1; +   } + +   errno = 0; + +   while ((test = fscanf(f, "%2s", buffer)) > 0) +   { +      if (_IS_PREFIX("#", buffer)) +      { +         if (reach_next_line_or_eof(f) < 0) +         { +            break; +         } +      } +      else +      { +         if +         ( +            parse_axis_configuration_line +            ( +               conf, +               f, +               axis_is_configured, +               buffer +            ) +            < 0 +         ) +         { +            break; +         } + +         if (reach_next_line_or_eof(f) < 0) +         { +            break; +         } +      } +   } + +   if (test < 0 && errno != 0) +   { +      _FATAL +      ( +         "[CONFIG] Error while reading file: %s, last read '%s'.", +         strerror(errno), +         buffer +      ); + +      fclose(f); + +      return -1; +   } + +   fclose(f); + +   if (all_axis_are_configured(axis_is_configured) < 0) +   { +      return -1; +   } + +   return 0; +} + +int relabsd_config_parse +( +   struct relabsd_config * const conf, +   int const argc, +   char ** const argv +) +{ +   if ((argc < 3) || (argc > 4)) +   { +      _FATAL +      ( +         "Usage: %s input_device config_file [<relabsd_device_name>]", +         argv[0] +      ); + +      return -1; +   } + +   if (argc == 3) +   { +      conf->device_name = "relabsd device"; +   } +   else +   { +      conf->device_name = argv[3]; +   } + +   conf->input_file = argv[1]; + +   if (read_config_file(conf, argv[2]) < 0) +   { +      return -1; +   } + +   return 0; +} + +int relabsd_config_allows +( +   const struct relabsd_config * const conf, +   enum relabsd_axis const axis, +   int const value +) +{ +   return 1; +}; + +void relabsd_config_get_absinfo +( +   const struct relabsd_config * const conf, +   enum relabsd_axis const axis, +   struct input_absinfo * const absinfo +) +{ +   absinfo->value = (__s32) 0; +   absinfo->minimum = (__s32) conf->axis[axis].min; +   absinfo->maximum = (__s32) conf->axis[axis].max; +   absinfo->fuzz = (__s32) conf->axis[axis].fuzz; +   absinfo->flat = (__s32) conf->axis[axis].flat; +   absinfo->resolution = (__s32) conf->axis[axis].resolution; +} diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..ffdfebb --- /dev/null +++ b/src/config.h @@ -0,0 +1,49 @@ +#ifndef RELABSD_CONFIG_H +#define RELABSD_CONFIG_H + +#include <libevdev/libevdev.h> + +#include "axis.h" + +struct relabsd_config_axis +{ +   int min; +   int max; +   int fuzz; +   int flat; +   int resolution; +}; + +/* + * There are no relabsd_config_free function so be careful about using dynamic + * memory for input_file or device_name. + */ +struct relabsd_config +{ +   char * input_file; +   char * device_name; +   struct relabsd_config_axis axis[6]; +}; + +int relabsd_config_parse +( +   struct relabsd_config * const conf, +   int const argc, +   char ** const argv +); + +int relabsd_config_allows +( +   const struct relabsd_config * const conf, +   enum relabsd_axis const axis, +   int const value +); + +void relabsd_config_get_absinfo +( +   const struct relabsd_config * const conf, +   enum relabsd_axis const axis, +   struct input_absinfo * const absinfo +); + +#endif diff --git a/src/error.h b/src/error.h new file mode 100644 index 0000000..aa85e63 --- /dev/null +++ b/src/error.h @@ -0,0 +1,123 @@ +#ifndef RELABSD_ERROR_H +#define RELABSD_ERROR_H + +#include <stdio.h> + +#include "config.h" +#include "pervasive.h" + +#define _HIGHEST_DEBUG_LVL 100 + +#define _DEBUG_LVL                           _HIGHEST_DEBUG_LVL +#define _ENABLE_WARNINGS_OUTPUT              1 +#define _ENABLE_RUNTIME_ERRORS_OUTPUT        1 +#define _ENABLE_PROGRAMMING_ERRORS_OUTPUT    1 +#define _ENABLE_FATAL_ERROR_OUTPUT           1 +#define _ENABLE_ERROR_LOCATION               0 + +#if _ENABLE_ERROR_LOCATION +   #define _LOCATION "[" __FILE__ "][" _TO_STRING(__LINE__) "]" +#else +   #define _LOCATION "" +#endif + +#define _PRINT_STDERR(symbol, str, ...)\ +   fprintf(stderr, "[" symbol "]" _LOCATION " " str "\n", __VA_ARGS__); + +#define _DEBUG(level, str, ...)\ +   _ISOLATE\ +   (\ +      if (level < _DEBUG_LVL)\ +      {\ +         _PRINT_STDERR("D", str, __VA_ARGS__);\ +      }\ +   ) + + +#define _WARNING(str, ...)\ +   _ISOLATE\ +   (\ +      if (_ENABLE_WARNINGS_OUTPUT)\ +      {\ +         _PRINT_STDERR("W", str, __VA_ARGS__);\ +      }\ +   ) + +#define _ERROR(str, ...)\ +   _ISOLATE\ +   (\ +      if (_ENABLE_RUNTIME_ERRORS_OUTPUT)\ +      {\ +         _PRINT_STDERR("E", str, __VA_ARGS__);\ +      }\ +   ) + +#define _PROG_ERROR(str, ...)\ +   _ISOLATE\ +   (\ +      if (_ENABLE_PROGRAMMING_ERRORS_OUTPUT)\ +      {\ +         _PRINT_STDERR("P", str, __VA_ARGS__);\ +      }\ +   ) + +#define _FATAL(str, ...)\ +   _ISOLATE\ +   (\ +     if (_ENABLE_FATAL_ERROR_OUTPUT)\ +      {\ +         _PRINT_STDERR("F", str, __VA_ARGS__);\ +      }\ +   ) + +/* For outputs without dynamic content (static). ******************************/ + +#define _PRINT_S_STDERR(symbol, str)\ +   fprintf(stderr, "[" symbol "]" _LOCATION " " str "\n"); + +#define _S_DEBUG(level, str)\ +   _ISOLATE\ +   (\ +      if (level < _DEBUG_LVL)\ +      {\ +         _PRINT_S_STDERR("D", str);\ +      }\ +   ) + +#define _S_WARNING(str)\ +   _ISOLATE\ +   (\ +      if (_ENABLE_WARNINGS_OUTPUT)\ +      {\ +         _PRINT_S_STDERR("W", str);\ +      }\ +   ) + +#define _S_ERROR(str)\ +   _ISOLATE\ +   (\ +      if (_ENABLE_RUNTIME_ERRORS_OUTPUT)\ +      {\ +         _PRINT_S_STDERR("E", str);\ +      }\ +   ) + +#define _S_PROG_ERROR(str)\ +   _ISOLATE\ +   (\ +      if (_ENABLE_PROGRAMMING_ERRORS_OUTPUT)\ +      {\ +         _PRINT_S_STDERR("P", str);\ +      }\ +   ) + +#define _S_FATAL(str)\ +   _ISOLATE\ +   (\ +     if (_ENABLE_FATAL_ERROR_OUTPUT)\ +      {\ +         _PRINT_S_STDERR("F", str);\ +      }\ +   ) + +#endif diff --git a/src/input.c b/src/input.c new file mode 100644 index 0000000..eb7b013 --- /dev/null +++ b/src/input.c @@ -0,0 +1,150 @@ +#include <fcntl.h> +#include <errno.h> +#include <string.h> + +#include <libevdev/libevdev.h> + +#include "error.h" + +#include "input.h" + +static int check_for_axis +( +   const struct libevdev * const dev, +   const char * axis_name, +   const unsigned int axis_id +) +{ +   if (!libevdev_has_event_code(dev, EV_REL, axis_id)) +   { +      _FATAL("Input device has no %s axis.", axis_name); + +      return -1; +   } + +   return 0; +} + +static int device_is_compatible (const struct libevdev * const dev) +{ +   if (!libevdev_has_event_type(dev, EV_REL)) +   { +      _S_FATAL("Input device has no relative axis."); + +      return -1; +   } + +   if +   ( +      (check_for_axis(dev, "X", REL_X) < 0) +      | (check_for_axis(dev, "Y", REL_Y) < 0) +      | (check_for_axis(dev, "Z", REL_Z) < 0) +      | (check_for_axis(dev, "RX", REL_RX) < 0) +      | (check_for_axis(dev, "RY", REL_RY) < 0) +      | (check_for_axis(dev, "RZ", REL_RZ) < 0) +   ) +   { +      return -1; +   } + +   return 0; +} + +int relabsd_input_open +( +   struct relabsd_input * const input, +   const char * const filename +) +{ +   input->fd = open(filename, O_RDONLY); + +   if (input->fd < 0) +   { +      _FATAL +      ( +         "Could not open device %s in read only mode:", +         filename, +         strerror(errno) +      ); + +      return -1; +   } + +   if +   ( +      libevdev_new_from_fd(input->fd, &(input->dev)) < 0 +   ) +   { +      _FATAL +      ( +         "libevdev could not open %s:", +         filename, +         strerror(errno) +      ); + +      close(input->fd); + +      return -1; +   } + +   if (device_is_compatible(input->dev) < 0) +   { +      _FATAL("%s is not compatible with relabsd.", filename); + +      return -1; +   } + +   return 0; +} + +void relabsd_input_close (const struct relabsd_input * const input) +{ +   libevdev_free(input->dev); +   close(input->fd); +} + +int relabsd_input_read +( +   const struct relabsd_input * const input, +   unsigned int * const input_type, +   unsigned int * const input_code, +   int * const input_value +) +{ +   int rc; +   struct input_event event; + +   rc = +      libevdev_next_event +      ( +         input->dev, +         (LIBEVDEV_READ_FLAG_NORMAL | LIBEVDEV_READ_FLAG_BLOCKING), +         &event +      ); + +   /*if (rc == LIBEVDEV_READ_STATUS_SYNC) +   { +      handle_syn_dropped(input->dev); +   } +   else*/ if (rc != LIBEVDEV_READ_STATUS_SUCCESS) +   { +      _WARNING("[INPUT] Could not get next event: %s.", strerror(-rc)); + +      return -1; +   } + +   _DEBUG +   ( +      90, +      "[INPUT] Valid event received: {type = %s; code = %s; value = %d}.", +       libevdev_event_type_get_name(event.type), +       libevdev_event_code_get_name(event.type, event.code), +       event.value +   ); + +   *input_type = event.type; +   *input_code = event.code; +   *input_value = event.value; + +   return 0; +} diff --git a/src/input.h b/src/input.h new file mode 100644 index 0000000..03b5c5a --- /dev/null +++ b/src/input.h @@ -0,0 +1,28 @@ +#ifndef RELABSD_INPUT_H +#define RELABSD_INPUT_H + +#include <libevdev/libevdev.h> + +struct relabsd_input +{ +   struct libevdev * dev; +   int fd; +}; + +int relabsd_input_open +( +   struct relabsd_input * const input, +   const char * const filename +); + +void relabsd_input_close (const struct relabsd_input * const input); + +int relabsd_input_read +( +   const struct relabsd_input * const input, +   unsigned int * const input_type, +   unsigned int * const input_code, +   int * const input_value +); + +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..b60a074 --- /dev/null +++ b/src/main.c @@ -0,0 +1,110 @@ +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> + +#include "pervasive.h" +#include "error.h" +#include "config.h" +#include "input.h" +#include "relabsd_device.h" + +static int RELABSD_RUN = 1; + +static void interrupt (int signal_id) +{ +   RELABSD_RUN = 0; + +   _S_WARNING("Interrupted, will exit at the next input device event."); +} + +static void convert_input +( +   const struct relabsd_config * const conf, +   const struct relabsd_input * const input, +   const struct relabsd_device * const dev +) +{ +   unsigned int input_type, input_code, abs_code; +   enum relabsd_axis rad_code; +   int value; + +   while (RELABSD_RUN == 1) +   { +      if (relabsd_input_read(input, &input_type, &input_code, &value) < 0) +      { +         continue; +      } + +      if (input_type == EV_REL) +      { +         rad_code = relabsd_axis_convert_evdev_rel(input_code, &abs_code); + +         if (rad_code == RELABSD_UNKNOWN) +         { +            relabsd_device_write_evdev_event +            ( +               dev, +               input_type, +               input_code, +               value +            ); +         } +         else if (relabsd_config_allows(conf, rad_code, value)) +         { +            relabsd_device_write_evdev_event(dev, EV_ABS, abs_code, value); +         } +      } +      else +      { +         relabsd_device_write_evdev_event +         ( +            dev, +            input_type, +            input_code, +            value +         ); +      } +   } +} + +int main (int argc, char ** argv) +{ +   struct relabsd_config conf; +   struct relabsd_input input; +   struct relabsd_device dev; + +   if (signal(SIGINT, interrupt) == SIG_ERR) +   { +      _S_FATAL("Unable to set the SIGINT signal handler."); + +      return -1; +   } + +   if (relabsd_config_parse(&conf, argc, argv) < 0) +   { +      return -2; +   } + +   if (relabsd_input_open(&input, conf.input_file) < 0) +   { +      return -3; +   } + +   if (relabsd_device_create(&dev, &conf) < 0) +   { +      return -4; +   } + +   _S_DEBUG(10, "Converting inputs..."); + +   convert_input(&conf, &input, &dev); + +   _S_DEBUG(10, "Terminating..."); + +   relabsd_device_destroy(&dev); +   relabsd_input_close(&input); + +   return 0; +} diff --git a/src/pervasive.h b/src/pervasive.h new file mode 100644 index 0000000..8a8449a --- /dev/null +++ b/src/pervasive.h @@ -0,0 +1,13 @@ +#ifndef RELABSD_PERVASIVE_H +#define RELABSD_PERVASIVE_H + +#include <string.h> + +#define __TO_STRING(x) #x +#define _TO_STRING(x) __TO_STRING(x) + +#define _ISOLATE(a) do {a} while (0) + +#define _IS_PREFIX(a, b) (strncmp(a, b, strlen(a)) == 0) + +#endif 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; +} diff --git a/src/relabsd_device.h b/src/relabsd_device.h new file mode 100644 index 0000000..35a4830 --- /dev/null +++ b/src/relabsd_device.h @@ -0,0 +1,31 @@ +#ifndef RELABSD_RELABSD_DEVICE_H +#define RELABSD_RELABSD_DEVICE_H + +#include <libevdev/libevdev.h> + +#include "config.h" +#include "input.h" + +struct relabsd_device +{ +   struct libevdev * dev; +   struct libevdev_uinput * uidev; +}; + +int relabsd_device_create +( +   struct relabsd_device * const dev, +   const struct relabsd_config * const config +); + +void relabsd_device_destroy (const struct relabsd_device * const dev); + +int relabsd_device_write_evdev_event +( +   const struct relabsd_device * const dev, +   unsigned int const type, +   unsigned int const code, +   int const value +); + +#endif | 


