| summaryrefslogtreecommitdiff |
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2015-09-02 10:57:48 +0200 |
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2015-09-02 10:57:48 +0200 |
| commit | 265053e2a4394b20d82aa1170ec3a9901f437d81 (patch) | |
| tree | 022440b6bc0d1ad36e36429573ec17e589fb791c | |
| parent | d9656cc86505b6f2bba57e04a4c99430a945a70d (diff) | |
Adds some comments, as well as minor code improvements.
| -rw-r--r-- | src/axis.c | 7 | ||||
| -rw-r--r-- | src/axis.h | 21 | ||||
| -rw-r--r-- | src/config.c | 224 | ||||
| -rw-r--r-- | src/config.h | 31 | ||||
| -rw-r--r-- | src/input.c | 24 | ||||
| -rw-r--r-- | src/input.h | 16 | ||||
| -rw-r--r-- | src/main.c | 79 | ||||
| -rw-r--r-- | src/pervasive.h | 1 | ||||
| -rw-r--r-- | src/relabsd_device.c | 18 | ||||
| -rw-r--r-- | src/relabsd_device.h | 22 |
10 files changed, 357 insertions, 86 deletions
@@ -4,7 +4,12 @@ #include "axis.h" -enum relabsd_axis relabsd_axis_name_to_enum (char * const name) +/* + * Implementation note: _IS_PREFIX, as its name implies, is checking for a + * prefix, not an equal value. This could cause issues if there were axes + * with name prefixed by another axis name. + */ +enum relabsd_axis relabsd_axis_name_to_enum (const char * const name) { if (_IS_PREFIX("X", name)) { @@ -12,8 +12,27 @@ enum relabsd_axis RELABSD_UNKNOWN }; -enum relabsd_axis relabsd_axis_name_to_enum (char * const name); +/* + * Returns the relabsd_axis whose name is 'name', according to the configuration + * file syntax. + * RELABSD_UNKNOWN is returned for any name that didn't match any other + * possibility. + **/ +enum relabsd_axis relabsd_axis_name_to_enum (const char * const name); + +/* + * Gives an string representation of an relabsd_axis. + * "??" is returned for RELABSD_UNKNOWN. + * Returned values should be coherent with the configuration file syntax. + **/ char * relabsd_axis_enum_to_name (enum relabsd_axis const e); + +/* + * Gives the relabsd_axis and EV_ABS event code equivalent to an EV_REL event + * code. + * If the returned relabsd_axis is RELABSD_UNKNOWN, no value is inserted into + * 'abs_code'. + **/ enum relabsd_axis relabsd_axis_convert_evdev_rel ( unsigned int const rel_code, diff --git a/src/config.c b/src/config.c index 1699811..2c860b9 100644 --- a/src/config.c +++ b/src/config.c @@ -6,9 +6,30 @@ #include "axis.h" #include "config.h" +/* + * "errno is never set to zero by any system call or library function." + * This file makes use of this, by setting it to zero and checking if + * it was modified after calling an function (I'm guessing this is common + * practice, but I think it's worth explaining). + * Following the principle of least astonishment, if a function sets errno to + * zero, it will not return before setting it back either to its previous + * value or to a arbitrary nonzero value. + */ + +/* + * Returns -1 on error, + * 0 on EOF, + * 1 on newline. + */ static int reach_next_line_or_eof (FILE * const f) { + int prev_errno; char c; + + prev_errno = errno; + + errno = 0; + c = getc(f); while ((c != '\n') && c != EOF) @@ -16,15 +37,28 @@ static int reach_next_line_or_eof (FILE * const f) c = getc(f); } - if (c == EOF) + if (errno != 0) { + errno = prev_errno; + return -1; } - return 0; + errno = prev_errno; + + if (c == EOF) + { + return 0; + } + + return 1; } -static int all_axis_are_configured (const int * const axis_is_configured) +/* + * Returns -1 on if an axis has not been configured, + * 0 otherwise. + */ +static int all_axes_are_configured (const int * const axis_is_configured) { int i; @@ -45,15 +79,21 @@ static int all_axis_are_configured (const int * const axis_is_configured) return 0; } +/* + * Returns -1 on (fatal) error, + * 0 on succes. + * On failure, 'axis_is_configured' is untouched. + * On success, the corresponding 'axis_is_configured' is set to 1. + */ static int parse_axis_configuration_line ( struct relabsd_config * const conf, FILE * const f, int * const axis_is_configured, - char * const buffer + const char * const buffer ) { - int valc; + int valc, prev_errno; enum relabsd_axis axis; axis = relabsd_axis_name_to_enum(buffer); @@ -69,25 +109,42 @@ static int parse_axis_configuration_line 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) - ); + prev_errno = errno; + errno = 0; + + 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 - ); + if (errno == 0) + { + _FATAL + ( + "[CONFIG] Unexpected end of file while reading axis '%s'.", + buffer + ); + } + else + { + _FATAL + ( + "[CONFIG] An error occured while reading axis '%s': %s.", + buffer, + strerror(errno) + ); + } + + errno = prev_errno; return -1; } @@ -99,13 +156,57 @@ static int parse_axis_configuration_line buffer ); + errno = prev_errno; + return -1; } + errno = prev_errno; + axis_is_configured[axis] = 1; + return 0; } +/* + * Returns -1 on (fatal) error, + * 0 on EOF, + * 1 on newline. + */ +static int read_config_line +( + struct relabsd_config * const conf, + FILE * const f, + int * const axis_is_configured, + const char * const prefix +) +{ + if (!_IS_PREFIX("#", prefix)) + { + if + ( + parse_axis_configuration_line + ( + conf, + f, + axis_is_configured, + prefix + ) + < 0 + ) + { + /* Fatal error. */ + return -1; + } + } + + return reach_next_line_or_eof(f); +} + +/* + * Returns -1 on (fatal) error, + * 0 on success. + */ static int read_config_file ( struct relabsd_config * const conf, @@ -115,11 +216,11 @@ static int read_config_file FILE * f; int axis_is_configured[6]; char buffer[3]; - int test; + int continue_reading, prev_errno; buffer[2] = '\0'; - memset(axis_is_configured, 0, 6 * sizeof(int)); + memset(axis_is_configured, 0, (6 * sizeof(int))); f = fopen(filename, "r"); @@ -134,43 +235,37 @@ static int read_config_file return -1; } + prev_errno = errno; errno = 0; - while ((test = fscanf(f, "%2s", buffer)) > 0) + continue_reading = 1; + + while ((continue_reading == 1) && (fscanf(f, "%2s", buffer) != EOF)) { - if (_IS_PREFIX("#", buffer)) - { - if (reach_next_line_or_eof(f) < 0) - { - break; - } - } - else + switch (read_config_line(conf, f, axis_is_configured, buffer)) { - if - ( - parse_axis_configuration_line - ( - conf, - f, - axis_is_configured, - buffer - ) - < 0 - ) - { + case 1: + /* Everything is going well. */ break; - } - if (reach_next_line_or_eof(f) < 0) - { + case 0: + /* EOF reached. */ + continue_reading = 0; break; - } + + case -1: + /* A fatal error occured. */ + errno = prev_errno; + + fclose(f); + return -1; } } - if (test < 0 && errno != 0) + if (errno != 0) { + /* An error happened in the while loop condition. */ + _FATAL ( "[CONFIG] Error while reading file: %s, last read '%s'.", @@ -178,14 +273,18 @@ static int read_config_file buffer ); + errno = prev_errno; + fclose(f); return -1; } + errno = prev_errno; + fclose(f); - if (all_axis_are_configured(axis_is_configured) < 0) + if (all_axes_are_configured(axis_is_configured) < 0) { return -1; } @@ -193,11 +292,14 @@ static int read_config_file return 0; } -int relabsd_config_parse +/* + * Returns -1 on (fatal) error, + * 0 on valid usage. + */ +static int check_usage ( - struct relabsd_config * const conf, int const argc, - char ** const argv + char * const * const argv ) { if ((argc < 3) || (argc > 4)) @@ -211,6 +313,21 @@ int relabsd_config_parse return -1; } + return 0; +} + +int relabsd_config_parse +( + struct relabsd_config * const conf, + int const argc, + char * const * const argv +) +{ + if (check_usage(argc, argv) < 0) + { + return -1; + } + if (argc == 3) { conf->device_name = "relabsd device"; @@ -237,6 +354,7 @@ int relabsd_config_allows int const value ) { + /* TODO */ return 1; }; diff --git a/src/config.h b/src/config.h index ffdfebb..558ea98 100644 --- a/src/config.h +++ b/src/config.h @@ -15,23 +15,41 @@ struct relabsd_config_axis }; /* - * There are no relabsd_config_free function so be careful about using dynamic + * There is 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; + const char * input_file; + const char * device_name; struct relabsd_config_axis axis[6]; }; +/* + * Parses the invocation parameters and the config file into 'conf'. + * + * Returns -1 on (fatal) error, + * 0 on successfully parsed config. + * + * 'conf' does not need to be initialized, as the function will only write to + * it. + * As one would expect, argc is the number of elements in argv. + */ int relabsd_config_parse ( struct relabsd_config * const conf, int const argc, - char ** const argv + char * const * const argv ); +/* + * This function aims at preventing us from emitting values that are incoherent + * with our REV_ABS axis configuration, such as the axis' minimum or maximum + * values. + * + * Returns 1 if 'conf' allows the axis to have this value, + * 0 otherwise. + */ int relabsd_config_allows ( const struct relabsd_config * const conf, @@ -39,6 +57,11 @@ int relabsd_config_allows int const value ); +/* + * Copies all the ABS event parameters of 'axis' into 'absinfo'. + * 'absinfo' does not need to be initialized, as the function will only write to + * it. + */ void relabsd_config_get_absinfo ( const struct relabsd_config * const conf, diff --git a/src/input.c b/src/input.c index eb7b013..aafb9a3 100644 --- a/src/input.c +++ b/src/input.c @@ -8,6 +8,12 @@ #include "input.h" +/* + * Ensures that the input device has enabled an given EV_REL axis. + * + * Returns -1 on (fatal) error, + * 0 is the axis is enabled. + */ static int check_for_axis ( const struct libevdev * const dev, @@ -25,6 +31,12 @@ static int check_for_axis return 0; } +/* + * Ensures that the input defice is at least 6DOF. + * + * Returns -1 on (fatal) error, + * 0 is the device is compatible. + */ static int device_is_compatible (const struct libevdev * const dev) { if (!libevdev_has_event_type(dev, EV_REL)) @@ -44,6 +56,10 @@ static int device_is_compatible (const struct libevdev * const dev) | (check_for_axis(dev, "RZ", REL_RZ) < 0) ) { + /* + * Note the '|' instead of '||': we want to inform the user of all the + * axes we require. + */ return -1; } @@ -122,11 +138,15 @@ int relabsd_input_read &event ); - /*if (rc == LIBEVDEV_READ_STATUS_SYNC) + /* 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) + else + */ + if (rc != LIBEVDEV_READ_STATUS_SUCCESS) { _WARNING("[INPUT] Could not get next event: %s.", strerror(-rc)); diff --git a/src/input.h b/src/input.h index 03b5c5a..4a23c27 100644 --- a/src/input.h +++ b/src/input.h @@ -9,6 +9,14 @@ struct relabsd_input int fd; }; +/* + * Returns -1 on (fatal) error, + * 0 on success. + * + * 'input' 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 ( struct relabsd_input * const input, @@ -17,6 +25,14 @@ int relabsd_input_open void relabsd_input_close (const struct relabsd_input * const input); +/* + * Returns -1 on (warning) error, + * 0 on successful read. + * + * The 'input_*' parameters do not need to be initialized, as the function will + * do that for you (on success). + * Requires 'input' to be open. + */ int relabsd_input_read ( const struct relabsd_input * const input, @@ -19,6 +19,44 @@ static void interrupt (int signal_id) _S_WARNING("Interrupted, will exit at the next input device event."); } +static void handle_relative_axis_event +( + const struct relabsd_config * const conf, + const struct relabsd_device * const dev, + unsigned int const input_type, + unsigned int const input_code, + int const value +) +{ + unsigned int abs_code; + enum relabsd_axis rad_code; + + rad_code = relabsd_axis_convert_evdev_rel(input_code, &abs_code); + + if (rad_code == RELABSD_UNKNOWN) + { + /* + * EV_REL events that do not concern an axis that was explicitly + * configured are retransmitted as is. + */ + relabsd_device_write_evdev_event + ( + dev, + input_type, + input_code, + value + ); + } + else if (relabsd_config_allows(conf, rad_code, value)) + { + /* + * This filters out events which are inconsistent with 'conf', such as + * values higher than the axis' configured maximum. + */ + relabsd_device_write_evdev_event(dev, EV_ABS, abs_code, value); + } +} + static void convert_input ( const struct relabsd_config * const conf, @@ -27,37 +65,28 @@ static void convert_input ) { 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) { + /* + * The next event should not be retransmitted, or some kind of error + * happened. + */ + /* TODO: error handling. */ 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); - } + /* We might have to convert the event. */ + handle_relative_axis_event(conf, dev, input_type, input_code, value); } else { + /* Any other event is retransmitted as is. */ relabsd_device_write_evdev_event ( dev, @@ -69,16 +98,26 @@ static void convert_input } } +static int set_signal_handlers () +{ + if (signal(SIGINT, interrupt) == SIG_ERR) + { + _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; - if (signal(SIGINT, interrupt) == SIG_ERR) + if (set_signal_handlers() < 0) { - _S_FATAL("Unable to set the SIGINT signal handler."); - return -1; } diff --git a/src/pervasive.h b/src/pervasive.h index 8a8449a..ee04b08 100644 --- a/src/pervasive.h +++ b/src/pervasive.h @@ -8,6 +8,7 @@ #define _ISOLATE(a) do {a} while (0) +/* strncmp stops at '\0' and strlen does not count '\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 index 7d2b761..ced74d8 100644 --- a/src/relabsd_device.c +++ b/src/relabsd_device.c @@ -9,11 +9,17 @@ #include "relabsd_device.h" -/* LIBEVDEV_UINPUT_OPEN_MANAGED is not defined on my machine. */ +/* + LIBEVDEV_UINPUT_OPEN_MANAGED is not defined on my machines. + It is not my place to define it, so I'll avoid the issue by defining my own + constant. +*/ #ifndef LIBEVDEV_UINPUT_OPEN_MANAGED - #warning "libevdev did not define LIBEVDEV_UINPUT_OPEN_MANAGED, "\ - "using value '-2' instead." - #define LIBEVDEV_UINPUT_OPEN_MANAGED -2 + #pragma message "[WARNING] libevdev did not define "\ + "LIBEVDEV_UINPUT_OPEN_MANAGED, using value '-2' instead." + #define RELABSD_UINPUT_OPEN_MANAGED -2 +#else + #define RELABSD_UINPUT_OPEN_MANAGED LIBEVDEV_UINPUT_OPEN_MANAGED #endif static void replace_rel_axis @@ -90,7 +96,8 @@ int relabsd_device_create libevdev_uinput_create_from_device ( dev->dev, - LIBEVDEV_UINPUT_OPEN_MANAGED, + /* See top of the file. */ + RELABSD_UINPUT_OPEN_MANAGED, &(dev->uidev) ) < 0 @@ -124,6 +131,7 @@ int relabsd_device_write_evdev_event int const value ) { + /* OPTIMIZE: Should we really send 'EV_SYN' after every event? */ if ( (libevdev_uinput_write_event(dev->uidev, type, code, value) == 0) diff --git a/src/relabsd_device.h b/src/relabsd_device.h index 35a4830..b3f2d51 100644 --- a/src/relabsd_device.h +++ b/src/relabsd_device.h @@ -12,6 +12,21 @@ struct relabsd_device struct libevdev_uinput * uidev; }; +/* + * - Clones the (real) input device. + * - Adds ABS event support to the clone. + * - Adds the ABS axis described in 'config' to the clone (overwriting if + * needed). + * - Disables the associated REL events from the clone. + * + * Returns -1 on (fatal) error, + * 0 on success. + * + * 'dev' does not need to be initialized, as the function will to that for you + * (on success). + * On success, 'dev' will need to be closed. + * This opens the (real) input device in read only mode to copy its properties. + */ int relabsd_device_create ( struct relabsd_device * const dev, @@ -20,6 +35,13 @@ int relabsd_device_create void relabsd_device_destroy (const struct relabsd_device * const dev); +/* + * Write an event to 'dev'. At this time, every event written to 'dev' is + * followed by an EV_SYN event. + * + * Returns 0 if both the event and the EV_SYN were successful, + * -1 if either failed. + */ int relabsd_device_write_evdev_event ( const struct relabsd_device * const dev, |


