summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2015-09-02 15:55:11 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2015-09-02 15:55:11 +0200
commit26b95c0953b8024d487897bf2aaaf1a8836f23a7 (patch)
treeb6370c9eb56ab664f3ab1680dcca586b922f1ea6
parent60b7a25bf38dce957c937ff602c1c812faff8b0f (diff)
relabsd is no longer limited to 6DOF devices.
-rw-r--r--src/axis.c163
-rw-r--r--src/axis.h49
-rw-r--r--src/config.c88
-rw-r--r--src/config.h16
-rw-r--r--src/input.c74
-rw-r--r--src/input.h4
-rw-r--r--src/main.c46
-rw-r--r--src/relabsd_device.c40
8 files changed, 321 insertions, 159 deletions
diff --git a/src/axis.c b/src/axis.c
index d883f42..34340f7 100644
--- a/src/axis.c
+++ b/src/axis.c
@@ -3,13 +3,14 @@
#include "pervasive.h"
#include "axis.h"
+#include "error.h"
/*
* 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)
+enum relabsd_axis relabsd_axis_from_name (const char * const name)
{
if (_IS_PREFIX("X", name))
{
@@ -35,11 +36,19 @@ enum relabsd_axis relabsd_axis_name_to_enum (const char * const name)
{
return RELABSD_RZ;
}
+ else if (_IS_PREFIX("WL", name))
+ {
+ return RELABSD_WHEEL;
+ }
+ else if (_IS_PREFIX("MC", name))
+ {
+ return RELABSD_MISC;
+ }
return RELABSD_UNKNOWN;
}
-char * relabsd_axis_enum_to_name (enum relabsd_axis const e)
+char * relabsd_axis_to_name (enum relabsd_axis const e)
{
switch (e)
{
@@ -61,6 +70,12 @@ char * relabsd_axis_enum_to_name (enum relabsd_axis const e)
case RELABSD_RZ:
return "RZ";
+ case RELABSD_WHEEL:
+ return "WL";
+
+ case RELABSD_MISC:
+ return "MC";
+
case RELABSD_UNKNOWN:
return "??";
}
@@ -98,6 +113,150 @@ enum relabsd_axis relabsd_axis_convert_evdev_rel
*abs_code = ABS_RZ;
return RELABSD_RZ;
+ case REL_WHEEL:
+ *abs_code = ABS_WHEEL;
+ return RELABSD_WHEEL;
+
+ case REL_MISC:
+ *abs_code = ABS_MISC;
+ return RELABSD_MISC;
+
+ default:
+ return RELABSD_UNKNOWN;
+ }
+}
+
+unsigned int relabsd_axis_to_rel (enum relabsd_axis const e)
+{
+ switch (e)
+ {
+ case RELABSD_X:
+ return REL_X;
+
+ case RELABSD_Y:
+ return REL_Y;
+
+ case RELABSD_Z:
+ return REL_Z;
+
+ case RELABSD_RX:
+ return REL_RX;
+
+ case RELABSD_RY:
+ return REL_RY;
+
+ case RELABSD_RZ:
+ return REL_RZ;
+
+ case RELABSD_WHEEL:
+ return REL_WHEEL;
+
+ case RELABSD_MISC:
+ return REL_MISC;
+
+ case RELABSD_UNKNOWN:
+ _S_PROG_ERROR("relabsd_axis_to_rel(RELABSD_UNKNOWN) is forbidden.");
+ return REL_MAX;
+ }
+}
+
+unsigned int relabsd_axis_to_abs (enum relabsd_axis const e)
+{
+ switch (e)
+ {
+ case RELABSD_X:
+ return ABS_X;
+
+ case RELABSD_Y:
+ return ABS_Y;
+
+ case RELABSD_Z:
+ return ABS_Z;
+
+ case RELABSD_RX:
+ return ABS_RX;
+
+ case RELABSD_RY:
+ return ABS_RY;
+
+ case RELABSD_RZ:
+ return ABS_RZ;
+
+ case RELABSD_WHEEL:
+ return ABS_WHEEL;
+
+ case RELABSD_MISC:
+ return ABS_MISC;
+
+ case RELABSD_UNKNOWN:
+ _S_PROG_ERROR("relabsd_axis_to_abs(RELABSD_UNKNOWN) is forbidden.");
+ return ABS_MAX;
+ }
+}
+
+/*
+ * Returns the relabsd_axis equivalent of a EV_REL/EV_ABS code.
+ */
+enum relabsd_axis relabsd_axis_from_rel (unsigned int const rel)
+{
+ switch (rel)
+ {
+ case REL_X:
+ return RELABSD_X;
+
+ case REL_Y:
+ return RELABSD_Y;
+
+ case REL_Z:
+ return RELABSD_Z;
+
+ case REL_RX:
+ return RELABSD_RX;
+
+ case REL_RY:
+ return RELABSD_RY;
+
+ case REL_RZ:
+ return RELABSD_RZ;
+
+ case REL_WHEEL:
+ return RELABSD_WHEEL;
+
+ case REL_MISC:
+ return RELABSD_MISC;
+
+ default:
+ return RELABSD_UNKNOWN;
+ }
+}
+enum relabsd_axis relabsd_axis_from_abs (unsigned int const abs)
+{
+ switch (abs)
+ {
+ case ABS_X:
+ return RELABSD_X;
+
+ case ABS_Y:
+ return RELABSD_Y;
+
+ case ABS_Z:
+ return RELABSD_Z;
+
+ case ABS_RX:
+ return RELABSD_RX;
+
+ case ABS_RY:
+ return RELABSD_RY;
+
+ case ABS_RZ:
+ return RELABSD_RZ;
+
+ case ABS_WHEEL:
+ return RELABSD_WHEEL;
+
+ case ABS_MISC:
+ return RELABSD_MISC;
+
default:
return RELABSD_UNKNOWN;
}
diff --git a/src/axis.h b/src/axis.h
index d2200de..2c4ea72 100644
--- a/src/axis.h
+++ b/src/axis.h
@@ -1,6 +1,9 @@
#ifndef RELABSD_AXIS_H
#define RELABSD_AXIS_H
+/* Number of axes that can be configured. */
+#define RELABSD_VALID_AXES_COUNT 8
+
enum relabsd_axis
{
RELABSD_X,
@@ -9,34 +12,50 @@ enum relabsd_axis
RELABSD_RX,
RELABSD_RY,
RELABSD_RZ,
+ RELABSD_WHEEL,
+ RELABSD_MISC,
RELABSD_UNKNOWN
};
-/*
- * 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,
unsigned int * const abs_code
);
+/*
+ * Returns the EV_REL/EV_ABS equivalent of 'e'.
+ * There is no equivalent for RELABSD_UNKNOWN, so 'e' is forbidden from
+ * taking this value.
+ */
+unsigned int relabsd_axis_to_rel (enum relabsd_axis const e);
+unsigned int relabsd_axis_to_abs (enum relabsd_axis const e);
+
+/*
+ * Returns the relabsd_axis equivalent of a EV_REL/EV_ABS code.
+ */
+enum relabsd_axis relabsd_axis_from_rel (unsigned int const rel);
+enum relabsd_axis relabsd_axis_from_abs (unsigned int const abs);
+
+/*
+ * 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_from_name (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_to_name (enum relabsd_axis const e);
#endif
diff --git a/src/config.c b/src/config.c
index 2c860b9..3fdea03 100644
--- a/src/config.c
+++ b/src/config.c
@@ -55,48 +55,20 @@ static int reach_next_line_or_eof (FILE * const f)
}
/*
- * 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;
-
- 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;
-}
-
-/*
* 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,
const char * const buffer
)
{
int valc, prev_errno;
enum relabsd_axis axis;
- axis = relabsd_axis_name_to_enum(buffer);
+ axis = relabsd_axis_from_name(buffer);
if (axis == RELABSD_UNKNOWN)
{
@@ -163,7 +135,7 @@ static int parse_axis_configuration_line
errno = prev_errno;
- axis_is_configured[axis] = 1;
+ conf->axis[axis].enabled = 1;
return 0;
}
@@ -177,23 +149,12 @@ 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
- )
+ if (parse_axis_configuration_line(conf, f, prefix) < 0)
{
/* Fatal error. */
return -1;
@@ -214,14 +175,11 @@ static int read_config_file
)
{
FILE * f;
- int axis_is_configured[6];
char buffer[3];
int continue_reading, prev_errno;
buffer[2] = '\0';
- memset(axis_is_configured, 0, (6 * sizeof(int)));
-
f = fopen(filename, "r");
if (f == (FILE *) NULL)
@@ -242,7 +200,7 @@ static int read_config_file
while ((continue_reading == 1) && (fscanf(f, "%2s", buffer) != EOF))
{
- switch (read_config_line(conf, f, axis_is_configured, buffer))
+ switch (read_config_line(conf, f, buffer))
{
case 1:
/* Everything is going well. */
@@ -284,11 +242,6 @@ static int read_config_file
fclose(f);
- if (all_axes_are_configured(axis_is_configured) < 0)
- {
- return -1;
- }
-
return 0;
}
@@ -316,6 +269,16 @@ static int check_usage
return 0;
}
+static void init_axes_config (struct relabsd_config * const conf)
+{
+ int i;
+
+ for (i = RELABSD_VALID_AXES_COUNT; i --> 0;)
+ {
+ conf->axis[i].enabled = 0;
+ }
+}
+
int relabsd_config_parse
(
struct relabsd_config * const conf,
@@ -339,6 +302,8 @@ int relabsd_config_parse
conf->input_file = argv[1];
+ init_axes_config(conf);
+
if (read_config_file(conf, argv[2]) < 0)
{
return -1;
@@ -347,14 +312,29 @@ int relabsd_config_parse
return 0;
}
-int relabsd_config_allows
+int relabsd_config_filter
(
const struct relabsd_config * const conf,
enum relabsd_axis const axis,
- int const value
+ int * const value
)
{
- /* TODO */
+ if ((axis == RELABSD_UNKNOWN) || !conf->axis[axis].enabled)
+ {
+ return 0;
+ }
+
+ if (*value < conf->axis[axis].min)
+ {
+ *value = conf->axis[axis].min;
+ }
+ else if (*value > conf->axis[axis].max)
+ {
+ *value = conf->axis[axis].max;
+ }
+
+ /* TODO: handle the other properties. */
+
return 1;
};
diff --git a/src/config.h b/src/config.h
index 558ea98..1ede1f3 100644
--- a/src/config.h
+++ b/src/config.h
@@ -7,6 +7,7 @@
struct relabsd_config_axis
{
+ int enabled;
int min;
int max;
int fuzz;
@@ -22,7 +23,7 @@ struct relabsd_config
{
const char * input_file;
const char * device_name;
- struct relabsd_config_axis axis[6];
+ struct relabsd_config_axis axis[RELABSD_VALID_AXES_COUNT];
};
/*
@@ -47,14 +48,19 @@ int relabsd_config_parse
* 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.
+ * Returns 1 if 'conf' allows the value to be emitted,
+ * 0 if 'conf' wants the event to be transmitted as is.
+ * -1 if 'conf' doesn't want the event to be transmitted.
+ *
+ * If the return value is 0, this function will not have altered the value at
+ * 'value'. Otherwise, this function can have altered it to match its
+ * requierements.
*/
-int relabsd_config_allows
+int relabsd_config_filter
(
const struct relabsd_config * const conf,
enum relabsd_axis const axis,
- int const value
+ int * const value
);
/*
diff --git a/src/input.c b/src/input.c
index aafb9a3..2cba397 100644
--- a/src/input.c
+++ b/src/input.c
@@ -5,39 +5,63 @@
#include <libevdev/libevdev.h>
#include "error.h"
+#include "axis.h"
+#include "config.h"
#include "input.h"
/*
- * Ensures that the input device has enabled an given EV_REL axis.
+ * Ensures that the input device has enabled the EV_REL axes mentioned
+ * in the configuration file.
*
* Returns -1 on (fatal) error,
- * 0 is the axis is enabled.
+ * 0 all configured axes are accounted for.
*/
-static int check_for_axis
+static int check_for_axes
(
const struct libevdev * const dev,
- const char * axis_name,
- const unsigned int axis_id
+ const struct relabsd_config * const conf
)
{
- if (!libevdev_has_event_code(dev, EV_REL, axis_id))
- {
- _FATAL("Input device has no %s axis.", axis_name);
+ int i, device_is_valid;
+ unsigned int rel_code;
- return -1;
+ 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))
+ {
+ _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 0;
+ return (device_is_valid - 1);
}
/*
- * Ensures that the input defice is at least 6DOF.
+ * 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)
+static int device_is_compatible
+(
+ const struct libevdev * const dev,
+ const struct relabsd_config * const conf
+)
{
if (!libevdev_has_event_type(dev, EV_REL))
{
@@ -46,20 +70,8 @@ static int device_is_compatible (const struct libevdev * const dev)
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)
- )
+ if (check_for_axes(dev, conf) < 0)
{
- /*
- * Note the '|' instead of '||': we want to inform the user of all the
- * axes we require.
- */
return -1;
}
@@ -69,17 +81,17 @@ static int device_is_compatible (const struct libevdev * const dev)
int relabsd_input_open
(
struct relabsd_input * const input,
- const char * const filename
+ const struct relabsd_config * const conf
)
{
- input->fd = open(filename, O_RDONLY);
+ input->fd = open(conf->input_file, O_RDONLY);
if (input->fd < 0)
{
_FATAL
(
"Could not open device %s in read only mode:",
- filename,
+ conf->input_file,
strerror(errno)
);
@@ -94,7 +106,7 @@ int relabsd_input_open
_FATAL
(
"libevdev could not open %s:",
- filename,
+ conf->input_file,
strerror(errno)
);
@@ -103,10 +115,8 @@ int relabsd_input_open
return -1;
}
- if (device_is_compatible(input->dev) < 0)
+ if (device_is_compatible(input->dev, conf) < 0)
{
- _FATAL("%s is not compatible with relabsd.", filename);
-
return -1;
}
diff --git a/src/input.h b/src/input.h
index 4a23c27..2be236c 100644
--- a/src/input.h
+++ b/src/input.h
@@ -3,6 +3,8 @@
#include <libevdev/libevdev.h>
+#include "config.h"
+
struct relabsd_input
{
struct libevdev * dev;
@@ -20,7 +22,7 @@ struct relabsd_input
int relabsd_input_open
(
struct relabsd_input * const input,
- const char * const filename
+ const struct relabsd_config * const conf
);
void relabsd_input_close (const struct relabsd_input * const input);
diff --git a/src/main.c b/src/main.c
index 2dc42db..ebfe065 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,7 +25,7 @@ static void handle_relative_axis_event
const struct relabsd_device * const dev,
unsigned int const input_type,
unsigned int const input_code,
- int const value
+ int value
)
{
unsigned int abs_code;
@@ -33,27 +33,21 @@ static void handle_relative_axis_event
rad_code = relabsd_axis_convert_evdev_rel(input_code, &abs_code);
- if (rad_code == RELABSD_UNKNOWN)
+ switch (relabsd_config_filter(conf, rad_code, &value))
{
- /*
- * 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);
+ case -1:
+ /* 'conf' doesn't want the event to be transmitted. */
+ break;
+
+ case 0:
+ /* 'conf' wants the event to be transmitted as is. */
+ relabsd_device_write_evdev_event(dev, input_type, input_code, value);
+ break;
+
+ case 1:
+ /* 'conf' allows the value to be emitted */
+ relabsd_device_write_evdev_event(dev, EV_ABS, abs_code, value);
+ break;
}
}
@@ -87,13 +81,7 @@ static void convert_input
else
{
/* Any other event is retransmitted as is. */
- relabsd_device_write_evdev_event
- (
- dev,
- input_type,
- input_code,
- value
- );
+ relabsd_device_write_evdev_event(dev, input_type, input_code, value);
}
}
}
@@ -126,7 +114,7 @@ int main (int argc, char ** argv)
return -2;
}
- if (relabsd_input_open(&input, conf.input_file) < 0)
+ if (relabsd_input_open(&input, &conf) < 0)
{
return -3;
}
diff --git a/src/relabsd_device.c b/src/relabsd_device.c
index ced74d8..eb4da8b 100644
--- a/src/relabsd_device.c
+++ b/src/relabsd_device.c
@@ -22,22 +22,29 @@
#define RELABSD_UINPUT_OPEN_MANAGED LIBEVDEV_UINPUT_OPEN_MANAGED
#endif
-static void replace_rel_axis
+static void replace_rel_axes
(
struct relabsd_device * const dev,
- const struct relabsd_config * const config,
- struct input_absinfo * const absinfo,
- unsigned int rel_code
+ const struct relabsd_config * const config
)
{
- enum relabsd_axis rad_code;
- unsigned int abs_code;
+ int i;
+ struct input_absinfo absinfo;
+ unsigned int abs_code, rel_code;
- rad_code = relabsd_axis_convert_evdev_rel(rel_code, &abs_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);
+ }
+ }
- 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
@@ -46,7 +53,6 @@ int relabsd_device_create
const struct relabsd_config * const config
)
{
- struct input_absinfo absinfo;
int fd;
fd = open(config->input_file, O_RDONLY);
@@ -63,10 +69,7 @@ int relabsd_device_create
return -1;
}
- if
- (
- libevdev_new_from_fd(fd, &(dev->dev)) < 0
- )
+ if (libevdev_new_from_fd(fd, &(dev->dev)) < 0)
{
_FATAL
(
@@ -84,12 +87,7 @@ int relabsd_device_create
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);
+ replace_rel_axes(dev, config);
if
(