From 60283fb1407fcd1de0586c960ed8d106f59483e9 Mon Sep 17 00:00:00 2001 From: Nathanael Sensfelder Date: Fri, 27 Dec 2019 17:06:53 +0100 Subject: Got a clue about the pesky "SYN" messages. I must not have read libevdev's documentation well enough. Hopefully this new approach will work better. The risk would be that the conversion takes too long and properly handling all events leads to an increasing lag between the physical and the virtual device. I should probably add an option to let users indicate they would prefer dropping missed events. --- include/relabsd/device/physical_device.h | 36 ++-- src/device/physical/physical_device.c | 231 ++++++++++++++++++++++++++ src/device/physical_device.c | 275 ------------------------------- src/device/virtual/virtual_device.c | 272 ++++++++++++++++++++++++++++++ src/device/virtual_device.c | 272 ------------------------------ src/server/communication_thread.c | 1 - src/server/conversion_main_loop.c | 129 ++++++++------- src/server/interruption.c | 23 +++ 8 files changed, 618 insertions(+), 621 deletions(-) create mode 100644 src/device/physical/physical_device.c delete mode 100644 src/device/physical_device.c create mode 100644 src/device/virtual/virtual_device.c delete mode 100644 src/device/virtual_device.c create mode 100644 src/server/interruption.c diff --git a/include/relabsd/device/physical_device.h b/include/relabsd/device/physical_device.h index 17866f7..6b44802 100644 --- a/include/relabsd/device/physical_device.h +++ b/include/relabsd/device/physical_device.h @@ -2,10 +2,10 @@ #include -struct relabsd_input +struct relabsd_physical_device { - struct libevdev * dev; - int fd; + struct libevdev * libevdev; + int file; int timed_out; }; @@ -13,17 +13,20 @@ struct relabsd_input * Returns -1 on (fatal) error, * 0 on success. * - * 'input' does not need to be initialized, as the function will to that for + * 'device' does not need to be initialized, as the function will to that for * you (on success). * On success, 'input' will need to be closed. */ -int relabsd_input_open +int relabsd_physical_device_open ( - struct relabsd_input * const input, - const struct relabsd_config * const conf + const char filename [const restrict static 1], + struct relabsd_physical_device device [const restrict static 1] ); -void relabsd_input_close (const struct relabsd_input * const input); +void relabsd_physical_device_close +( + const struct relabsd_physical_device device [const restrict static 1] +); /* * Returns -1 on (warning) error, @@ -33,18 +36,15 @@ void relabsd_input_close (const struct relabsd_input * const input); * do that for you (on success). * Requires 'input' to be open. */ -int relabsd_input_read +int relabsd_physical_device_read ( - const struct relabsd_input * const input, - unsigned int * const input_type, - unsigned int * const input_code, - int * const input_value + const struct relabsd_physical_device device [const restrict static 1], + unsigned int input_type [const restrict static 1], + unsigned int input_code [const restrict static 1], + int input_value [const restrict static 1] ); -int relabsd_input_wait_for_next_event +int relabsd_physical_device_is_late ( - const struct relabsd_input * const input, - const struct relabsd_config * const config + const struct relabsd_physical_device device [const restrict static 1] ); - -#endif diff --git a/src/device/physical/physical_device.c b/src/device/physical/physical_device.c new file mode 100644 index 0000000..7023791 --- /dev/null +++ b/src/device/physical/physical_device.c @@ -0,0 +1,231 @@ +/**** POSIX *******************************************************************/ +#include +#include +#include +#include + +/**** LIBEVDEV ****************************************************************/ +#include + +/**** RELABSD *****************************************************************/ +#include + +/******************************************************************************/ +/**** LOCAL FUNCTIONS *********************************************************/ +/******************************************************************************/ +/* + * Ensures that the input device has enabled the EV_REL axes mentioned + * in the configuration file. + * + * Returns -1 on (fatal) error, + * 0 all configured axes are accounted for. + */ +static int check_for_axes +( + const struct libevdev * const dev, + const struct relabsd_config * const conf +) +{ + int i, device_is_valid; + unsigned int rel_code; + + device_is_valid = 1; + + for (i = RELABSD_VALID_AXES_COUNT; i --> 0;) + { + if (conf->axis[i].enabled) + { + rel_code = relabsd_axis_to_rel((enum relabsd_axis) i); + + if (!libevdev_has_event_code(dev, EV_REL, rel_code)) + { + RELABSD_FATAL + ( + "Input device has no relative %s axis, yet the configuration " + "file asks to convert it.", + relabsd_axis_to_name((enum relabsd_axis) i) + ); + + device_is_valid = 0; + } + } + } + + return (device_is_valid - 1); +} + +/* + * Ensures that the input device is compatible with the config file. + * + * Returns -1 on (fatal) error, + * 0 is the device is compatible. + */ +static int device_is_compatible +( + const struct libevdev * const dev, + const struct relabsd_config * const conf +) +{ + + + return 0; +} + +/******************************************************************************/ +/**** EXPORTED FUNCTIONS ******************************************************/ +/******************************************************************************/ +int relabsd_physical_device_compatibility_test +( + const struct relabsd_physical_device device [const restrict static 1], + const struct relabsd_parameters parameters [const restrict static 0], + const int verbose +) +{ + if (!libevdev_has_event_type(device->libevdev, EV_REL)) + { + RELABSD_S_FATAL("The physical device has no relative axes."); + + return -1; + } + + if + ( + (parameters != (const struct relabsd_parameters *) NULL) + && (check_for_axes(device->libevdev, parameters, verbose) < 0) + ) + { + RELABSD_S_FATAL + ( + "Issue with the physical device's axes (or lack thereof), or their" + " compatibility with the requested configuration." + ); + + return -2; + } + + return 0; +} + +int relabsd_physical_device_open +( + const char filename [const restrict static 1], + struct relabsd_physical_device device [const restrict static 1] +) +{ + int err; + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Opening physical device..."); + + errno = 0; + device->file = open(filename, O_RDONLY); + device->is_late = 0; + + if (device->file == -1) + { + RELABSD_FATAL + ( + "Could not open physical device '%s' in read only mode: %s.", + filename, + strerror(errno) + ); + + return -1; + } + + err = libevdev_new_from_fd(device->file, &(device->libevdev)); + + if (err != 0) + { + RELABSD_FATAL + ( + "libevdev could not open physical device '%s': %s.", + filename, + strerror(-err) + ); + + close(device->file); + + return -1; + } + + return 0; +} + +void relabsd_physical_device_close +( + const struct relabsd_physical_device device [const restrict static 1] +) +{ + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Closing input device..."); + + libevdev_free(device->libevdev); + + errno = 0; + + if (close(device->file) == -1) + { + RELABSD_ERROR + ( + "Could not properly close the input device: %s.", + strerror(errno) + ); + } +} + +int relabsd_physical_device_read +( + const struct relabsd_physical_device device [const restrict static 1], + unsigned int input_type [const restrict static 1], + unsigned int input_code [const restrict static 1], + int input_value [const restrict static 1] +) +{ + int returned_code; + struct input_event event; + + returned_code = + libevdev_next_event + ( + device->libevdev, + device->is_late ? LIBEVDEV_READ_FLAG_SYNC : LIBEVDEV_READ_FLAG_NORMAL, + &event + ); + + switch (returned_code) + { + case LIBEVDEV_READ_STATUS_SUCCESS: + RELABSD_DEBUG + ( + RELABSD_DEBUG_REAL_EVENTS, + "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 1; + + case LIBEVDEV_READ_STATUS_SYNC: + /* There are old events waiting to be read. */ + device->is_late = 1; + + return 0; + + case -EAGAIN: + device->is_late = 0; + + return -1; + } +} + +int relabsd_physical_device_is_late +( + const struct relabsd_physical_device device [const restrict static 1] +) +{ + return device->is_late; +} diff --git a/src/device/physical_device.c b/src/device/physical_device.c deleted file mode 100644 index 7e365da..0000000 --- a/src/device/physical_device.c +++ /dev/null @@ -1,275 +0,0 @@ -/**** RELABSD *****************************************************************/ -#include -#include -#include -#include - -/**** LIBEVDEV ****************************************************************/ -#include - -/**** RELABSD *****************************************************************/ -#include - -/* - * Ensures that the input device has enabled the EV_REL axes mentioned - * in the configuration file. - * - * Returns -1 on (fatal) error, - * 0 all configured axes are accounted for. - */ -static int check_for_axes -( - const struct libevdev * const dev, - const struct relabsd_config * const conf -) -{ - int i, device_is_valid; - unsigned int rel_code; - - device_is_valid = 1; - - for (i = RELABSD_VALID_AXES_COUNT; i --> 0;) - { - if (conf->axis[i].enabled) - { - rel_code = relabsd_axis_to_rel((enum relabsd_axis) i); - - if (!libevdev_has_event_code(dev, EV_REL, rel_code)) - { - RELABSD_FATAL - ( - "Input device has no relative %s axis, yet the configuration " - "file asks to convert it.", - relabsd_axis_to_name((enum relabsd_axis) i) - ); - - device_is_valid = 0; - } - } - } - - return (device_is_valid - 1); -} - -/* - * Ensures that the input device is compatible with the config file. - * - * Returns -1 on (fatal) error, - * 0 is the device is compatible. - */ -static int device_is_compatible -( - const struct libevdev * const dev, - const struct relabsd_config * const conf -) -{ - if (!libevdev_has_event_type(dev, EV_REL)) - { - RELABSD_S_FATAL("Input device has no relative axis."); - - return -1; - } - - if (check_for_axes(dev, conf) < 0) - { - return -1; - } - - return 0; -} - -int relabsd_physical_device_open -( - struct relabsd_physical_device * const input, - const struct relabsd_config * const conf -) -{ - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Opening input device..."); - - input->fd = open(conf->input_file, O_RDONLY); - - if (input->fd < 0) - { - RELABSD_FATAL - ( - "Could not open device '%s' in read only mode: %s.", - conf->input_file, - strerror(errno) - ); - - return -1; - } - - if - ( - libevdev_new_from_fd(input->fd, &(input->dev)) < 0 - ) - { - RELABSD_FATAL - ( - "libevdev could not open '%s': %s.", - conf->input_file, - strerror(errno) - ); - - close(input->fd); - - return -1; - } - - if (device_is_compatible(input->dev, conf) < 0) - { - return -1; - } - - return 0; -} - -void relabsd_physical_device_close (const struct relabsd_physical_device * const input) -{ - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Closing input device..."); - - libevdev_free(input->dev); - close(input->fd); -} - -int relabsd_physical_device_read -( - const struct relabsd_physical_device * const input, - unsigned int * const input_type, - unsigned int * const input_code, - int * const input_value -) -{ - int rc; - struct input_event event; - - /* - if (libevdev_has_event_pending(input->dev) == 0) - { - return -1; - } - */ - rc = - libevdev_next_event - ( - input->dev, - (LIBEVDEV_READ_FLAG_NORMAL | LIBEVDEV_READ_FLAG_BLOCKING), - &event - ); - - /* TODO: Look into LIBEVDEV_READ_STATUS_SYNC, handle it. */ - /* - if (rc == LIBEVDEV_READ_STATUS_SYNC) - { - handle_syn_dropped(input->dev); - } - else - */ - if (rc != LIBEVDEV_READ_STATUS_SUCCESS) - { - RELABSD_WARNING("[INPUT] Could not get next event: %s.", strerror(-rc)); - - return -1; - } - - RELABSD_DEBUG - ( - RELABSD_DEBUG_REAL_EVENTS, - "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; -} - -int relabsd_physical_device_wait_for_next_event -( - const struct relabsd_physical_device * const input, - const struct relabsd_config * const config -) -{ - int ready_fds; - const int old_errno = errno; - fd_set ready_to_read; - struct timeval curr_timeout; - - FD_ZERO(&ready_to_read); - FD_SET(input->fd, &ready_to_read); - - /* call to select may alter timeout */ - memcpy - ( - (void *) &(curr_timeout), - (const void *) &(config->timeout), - sizeof(struct timeval) - ); - - errno = 0; - - RELABSD_S_ERROR - ( - "Waiting for input to be ready..." - ); - - ready_fds = select - ( - (input->fd + 1), - &ready_to_read, - (fd_set *) NULL, - (fd_set *) NULL, - (input->timed_out) ? NULL : &(curr_timeout) - ); - - if (errno != 0) - { - RELABSD_ERROR - ( - "Unable to wait for timeout: %s (errno: %d).", - strerror(errno), - errno - ); - - if (errno == EINTR) - { - /* Signal interruption? */ - } - else - { - /* TODO: error message */ - } - - errno = old_errno; - - return -1; - } - - if (ready_fds == -1) - { - /* TODO: error message */ - - RELABSD_S_ERROR - ( - "Unable to wait for timeout, yet errno was not set to anything." - ); - - errno = old_errno; - - return -1; - } - - RELABSD_ERROR - ( - "Input is ready, ready_fds = %d", ready_fds - ); - - errno = old_errno; - - return ready_fds; -} diff --git a/src/device/virtual/virtual_device.c b/src/device/virtual/virtual_device.c new file mode 100644 index 0000000..19d1097 --- /dev/null +++ b/src/device/virtual/virtual_device.c @@ -0,0 +1,272 @@ + + +static void replace_rel_axes +( + struct relabsd_virtual_device * const dev, + const struct relabsd_config * const config +) +{ + int i; + struct input_absinfo absinfo; + unsigned int abs_code, rel_code; + + for (i = RELABSD_VALID_AXES_COUNT; i --> 0;) + { + if (config->axis[i].enabled) + { + rel_code = relabsd_axis_to_rel((enum relabsd_axis) i); + abs_code = relabsd_axis_to_abs((enum relabsd_axis) i); + + relabsd_config_get_absinfo(config, (enum relabsd_axis) i, &absinfo); + libevdev_disable_event_code(dev->dev, EV_REL, rel_code); + libevdev_enable_event_code(dev->dev, EV_ABS, abs_code, &absinfo); + } + } + +} + +static int rename_device +( + struct libevdev * const dev, + const struct relabsd_config * const config +) +{ + size_t new_name_size; + char * new_name; + const char * real_name; + + /* +2: One for the \0, one for the space between prefix and 'real_name'. */ + new_name_size = strlen(RELABSD_DEVICE_PREFIX) + 2; + + if (config->device_name == (char *) NULL) + { + /* XXX + * "The name is never NULL but it may be the empty string." + * I'm assuming that since they use the term 'string', it is \0 + * terminated. + */ + real_name = libevdev_get_name(dev); + } + else + { + real_name = config->device_name; + } + + new_name_size += strlen(real_name); + + new_name = (char *) calloc(new_name_size, sizeof(char)); + + if (new_name == (char *) NULL) + { + RELABSD_ERROR + ( + "Attempt at allocating memory to create the virtual device's name " + "failed: %s.", + strerror(errno) + ); + + /* This frees whatever came from 'libevdev_get_name'. */ + libevdev_set_name(dev, RELABSD_DEVICE_PREFIX); + + return -1; + } + + if + ( + snprintf + ( + new_name, + new_name_size, + "%s %s", + RELABSD_DEVICE_PREFIX, + real_name + ) + != ((int) (new_name_size - 1)) + ) + { + /* This makes for a great message when strerror(errno) returns SUCCESS. */ + RELABSD_ERROR + ( + "Something unexpected happened while renaming the virtual device: %s.", + strerror(errno) + ); + + /* This frees whatever came from 'libevdev_get_name'. */ + libevdev_set_name(dev, RELABSD_DEVICE_PREFIX); + + free((void *) new_name); + + return -1; + } + + /* This frees whatever came from 'libevdev_get_name'. */ + libevdev_set_name(dev, new_name); + free((void *) new_name); + + return 0; +} + +int relabsd_virtual_device_create +( + struct relabsd_virtual_device * const dev, + const struct relabsd_config * const config +) +{ + int fd; + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Creating virtual device..."); + + fd = open(config->input_file, O_RDONLY); + + if (fd < 0) + { + RELABSD_FATAL + ( + "Could not open device '%s' in read only mode: %s.", + config->input_file, + strerror(errno) + ); + + return -1; + } + + if (libevdev_new_from_fd(fd, &(dev->dev)) < 0) + { + RELABSD_FATAL + ( + "libevdev could not open '%s': '%s'.", + config->input_file, + strerror(errno) + ); + + close(fd); + + return -1; + } + + if (rename_device(dev->dev, config) < 0) + { + libevdev_free(dev->dev); + close(fd); + + return -1; + } + + libevdev_enable_event_type(dev->dev, EV_ABS); + + replace_rel_axes(dev, config); + + if + ( + libevdev_uinput_create_from_device + ( + dev->dev, + /* See top of the file. */ + RELABSD_UINPUT_OPEN_MANAGED, + &(dev->uidev) + ) + < 0 + ) + { + RELABSD_FATAL("Could not create relabsd device: %s.", strerror(errno)); + + libevdev_free(dev->dev); + + close(fd); + + return -1; + } + + close(fd); + + return 0; +} + +void relabsd_virtual_device_destroy (const struct relabsd_virtual_device * const dev) +{ + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Destroying virtual device..."); + + libevdev_uinput_destroy(dev->uidev); + libevdev_free(dev->dev); +} + +int relabsd_virtual_device_write_evdev_event +( + const struct relabsd_virtual_device * const dev, + unsigned int const type, + unsigned int const code, + int const value +) +{ + RELABSD_DEBUG + ( + RELABSD_DEBUG_VIRTUAL_EVENTS, + "Sending event: {type = %s; code = %s; value = %d}.", + libevdev_event_type_get_name(type), + libevdev_event_code_get_name(type, code), + value + ); + + /* + * We'll also send the 'EV_SYN' events when we receive them from the input + * device. + * OPTIMIZE: prevent 'EV_SYN' from being sent if we haven't sent any new + * values. (It might not be worth it though) + */ + if (libevdev_uinput_write_event(dev->uidev, type, code, value) == 0) + { + /* FIXME: + * Why does activating the timeout trigger the EV_KEYS event to not be + * followed by EV_SYN? + */ + if (type == EV_KEY) + { + libevdev_uinput_write_event + ( + dev->uidev, + EV_SYN, + SYN_REPORT, + 0 + ); + } + + return 0; + } + + return -1; +} + +void relabsd_virtual_device_set_axes_to_zero +( + const struct relabsd_virtual_device * const dev, + const struct relabsd_config * const config +) +{ + int i; + + for (i = 0; i < RELABSD_VALID_AXES_COUNT; ++i) + { + if (config->axis[i].enabled) + { + relabsd_virtual_device_write_evdev_event + ( + dev, + EV_ABS, + relabsd_axis_to_abs((enum relabsd_axis) i), + 0 + ); + } + } + + /* + * Also send a SYN event when the axes have been modified. + */ + libevdev_uinput_write_event + ( + dev->uidev, + EV_SYN, + SYN_REPORT, + 0 + ); +} + diff --git a/src/device/virtual_device.c b/src/device/virtual_device.c deleted file mode 100644 index 19d1097..0000000 --- a/src/device/virtual_device.c +++ /dev/null @@ -1,272 +0,0 @@ - - -static void replace_rel_axes -( - struct relabsd_virtual_device * const dev, - const struct relabsd_config * const config -) -{ - int i; - struct input_absinfo absinfo; - unsigned int abs_code, rel_code; - - for (i = RELABSD_VALID_AXES_COUNT; i --> 0;) - { - if (config->axis[i].enabled) - { - rel_code = relabsd_axis_to_rel((enum relabsd_axis) i); - abs_code = relabsd_axis_to_abs((enum relabsd_axis) i); - - relabsd_config_get_absinfo(config, (enum relabsd_axis) i, &absinfo); - libevdev_disable_event_code(dev->dev, EV_REL, rel_code); - libevdev_enable_event_code(dev->dev, EV_ABS, abs_code, &absinfo); - } - } - -} - -static int rename_device -( - struct libevdev * const dev, - const struct relabsd_config * const config -) -{ - size_t new_name_size; - char * new_name; - const char * real_name; - - /* +2: One for the \0, one for the space between prefix and 'real_name'. */ - new_name_size = strlen(RELABSD_DEVICE_PREFIX) + 2; - - if (config->device_name == (char *) NULL) - { - /* XXX - * "The name is never NULL but it may be the empty string." - * I'm assuming that since they use the term 'string', it is \0 - * terminated. - */ - real_name = libevdev_get_name(dev); - } - else - { - real_name = config->device_name; - } - - new_name_size += strlen(real_name); - - new_name = (char *) calloc(new_name_size, sizeof(char)); - - if (new_name == (char *) NULL) - { - RELABSD_ERROR - ( - "Attempt at allocating memory to create the virtual device's name " - "failed: %s.", - strerror(errno) - ); - - /* This frees whatever came from 'libevdev_get_name'. */ - libevdev_set_name(dev, RELABSD_DEVICE_PREFIX); - - return -1; - } - - if - ( - snprintf - ( - new_name, - new_name_size, - "%s %s", - RELABSD_DEVICE_PREFIX, - real_name - ) - != ((int) (new_name_size - 1)) - ) - { - /* This makes for a great message when strerror(errno) returns SUCCESS. */ - RELABSD_ERROR - ( - "Something unexpected happened while renaming the virtual device: %s.", - strerror(errno) - ); - - /* This frees whatever came from 'libevdev_get_name'. */ - libevdev_set_name(dev, RELABSD_DEVICE_PREFIX); - - free((void *) new_name); - - return -1; - } - - /* This frees whatever came from 'libevdev_get_name'. */ - libevdev_set_name(dev, new_name); - free((void *) new_name); - - return 0; -} - -int relabsd_virtual_device_create -( - struct relabsd_virtual_device * const dev, - const struct relabsd_config * const config -) -{ - int fd; - - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Creating virtual device..."); - - fd = open(config->input_file, O_RDONLY); - - if (fd < 0) - { - RELABSD_FATAL - ( - "Could not open device '%s' in read only mode: %s.", - config->input_file, - strerror(errno) - ); - - return -1; - } - - if (libevdev_new_from_fd(fd, &(dev->dev)) < 0) - { - RELABSD_FATAL - ( - "libevdev could not open '%s': '%s'.", - config->input_file, - strerror(errno) - ); - - close(fd); - - return -1; - } - - if (rename_device(dev->dev, config) < 0) - { - libevdev_free(dev->dev); - close(fd); - - return -1; - } - - libevdev_enable_event_type(dev->dev, EV_ABS); - - replace_rel_axes(dev, config); - - if - ( - libevdev_uinput_create_from_device - ( - dev->dev, - /* See top of the file. */ - RELABSD_UINPUT_OPEN_MANAGED, - &(dev->uidev) - ) - < 0 - ) - { - RELABSD_FATAL("Could not create relabsd device: %s.", strerror(errno)); - - libevdev_free(dev->dev); - - close(fd); - - return -1; - } - - close(fd); - - return 0; -} - -void relabsd_virtual_device_destroy (const struct relabsd_virtual_device * const dev) -{ - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Destroying virtual device..."); - - libevdev_uinput_destroy(dev->uidev); - libevdev_free(dev->dev); -} - -int relabsd_virtual_device_write_evdev_event -( - const struct relabsd_virtual_device * const dev, - unsigned int const type, - unsigned int const code, - int const value -) -{ - RELABSD_DEBUG - ( - RELABSD_DEBUG_VIRTUAL_EVENTS, - "Sending event: {type = %s; code = %s; value = %d}.", - libevdev_event_type_get_name(type), - libevdev_event_code_get_name(type, code), - value - ); - - /* - * We'll also send the 'EV_SYN' events when we receive them from the input - * device. - * OPTIMIZE: prevent 'EV_SYN' from being sent if we haven't sent any new - * values. (It might not be worth it though) - */ - if (libevdev_uinput_write_event(dev->uidev, type, code, value) == 0) - { - /* FIXME: - * Why does activating the timeout trigger the EV_KEYS event to not be - * followed by EV_SYN? - */ - if (type == EV_KEY) - { - libevdev_uinput_write_event - ( - dev->uidev, - EV_SYN, - SYN_REPORT, - 0 - ); - } - - return 0; - } - - return -1; -} - -void relabsd_virtual_device_set_axes_to_zero -( - const struct relabsd_virtual_device * const dev, - const struct relabsd_config * const config -) -{ - int i; - - for (i = 0; i < RELABSD_VALID_AXES_COUNT; ++i) - { - if (config->axis[i].enabled) - { - relabsd_virtual_device_write_evdev_event - ( - dev, - EV_ABS, - relabsd_axis_to_abs((enum relabsd_axis) i), - 0 - ); - } - } - - /* - * Also send a SYN event when the axes have been modified. - */ - libevdev_uinput_write_event - ( - dev->uidev, - EV_SYN, - SYN_REPORT, - 0 - ); -} - diff --git a/src/server/communication_thread.c b/src/server/communication_thread.c index 2ed1aae..2da54d2 100644 --- a/src/server/communication_thread.c +++ b/src/server/communication_thread.c @@ -23,7 +23,6 @@ void * posix_main_loop (void * params) /******************************************************************************/ /**** EXPORTED FUNCTIONS ******************************************************/ /******************************************************************************/ - int relabsd_server_create_communication_thread ( struct relabsd_server server [const static 1] diff --git a/src/server/conversion_main_loop.c b/src/server/conversion_main_loop.c index 0180e80..b5b97db 100644 --- a/src/server/conversion_main_loop.c +++ b/src/server/conversion_main_loop.c @@ -10,15 +10,6 @@ #include "input.h" #include "relabsd_device.h" -static int RELABSD_RUN = 1; - -static void interrupt (int unused_mandatory_parameter) -{ - RELABSD_RUN = 0; - - RELABSD_S_WARNING("Interrupted, will exit at the next input device event."); -} - static void handle_relative_axis_event ( struct relabsd_config * const conf, @@ -108,66 +99,94 @@ static void convert_input } } -static int set_signal_handlers () +int relabsd_server_conversion_loop +( + struct relabsd_server server [const static 1] +) { - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Setting signal handlers."); - - if (signal(SIGINT, interrupt) == SIG_ERR) - { - RELABSD_S_FATAL("Unable to set the SIGINT signal handler."); - - return -1; - } - return 0; } -/* -int main (int argc, char ** argv) -{ - struct relabsd_config conf; - struct relabsd_input input; - struct relabsd_device dev; - - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "relabsd started."); - if (set_signal_handlers() < 0) +int wait_for_next_event +( + const struct relabsd_physical_device * const input, + const struct relabsd_config * const config +) +{ + int ready_fds; + const int old_errno = errno; + fd_set ready_to_read; + struct timeval curr_timeout; + + FD_ZERO(&ready_to_read); + FD_SET(input->fd, &ready_to_read); + + /* call to select may alter timeout */ + memcpy + ( + (void *) &(curr_timeout), + (const void *) &(config->timeout), + sizeof(struct timeval) + ); + + errno = 0; + + RELABSD_S_ERROR + ( + "Waiting for input to be ready..." + ); + + ready_fds = select + ( + (input->fd + 1), + &ready_to_read, + (fd_set *) NULL, + (fd_set *) NULL, + (input->timed_out) ? NULL : &(curr_timeout) + ); + + if (errno != 0) { - return -1; - } + RELABSD_ERROR + ( + "Unable to wait for timeout: %s (errno: %d).", + strerror(errno), + errno + ); + + if (errno == EINTR) + { + /* Signal interruption? */ + } + else + { + /* TODO: error message */ + } - if (relabsd_config_parse(&conf, argc, argv) < 0) - { - return -2; - } + errno = old_errno; - if (relabsd_input_open(&input, &conf) < 0) - { - return -3; + return -1; } - if (relabsd_device_create(&dev, &conf) < 0) + if (ready_fds == -1) { - return -4; - } - - convert_input(&conf, &input, &dev); + /* TODO: error message */ - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Terminating..."); + RELABSD_S_ERROR + ( + "Unable to wait for timeout, yet errno was not set to anything." + ); - relabsd_device_destroy(&dev); - relabsd_input_close(&input); + errno = old_errno; - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Done."); + return -1; + } - return 0; -} -*/ + RELABSD_ERROR + ( + "Input is ready, ready_fds = %d", ready_fds + ); -int relabsd_server_conversion_loop -( - struct relabsd_server server [const static 1] -) -{ - return 0; + return ready_fds; } diff --git a/src/server/interruption.c b/src/server/interruption.c new file mode 100644 index 0000000..6eb7827 --- /dev/null +++ b/src/server/interruption.c @@ -0,0 +1,23 @@ +static int RELABSD_RUN = 1; + +static void interrupt (int unused_mandatory_parameter) +{ + RELABSD_RUN = 0; + + RELABSD_S_WARNING("Interrupted, will exit at the next input device event."); +} + +static int set_signal_handlers () +{ + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Setting signal handlers."); + + if (signal(SIGINT, interrupt) == SIG_ERR) + { + RELABSD_S_FATAL("Unable to set the SIGINT signal handler."); + + return -1; + } + + return 0; +} + -- cgit v1.2.3-70-g09d2