aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2019-08-01 20:54:17 +0200
committercbdev <cb@cbcdn.com>2019-08-01 20:54:17 +0200
commita23ce7718ab61e73586d2738329d6bbace0b764b (patch)
treeaf922cd4801b299067d0b871b687de6474a4d4e6
parent4e604b493e0dc855b6ea6978e5cf8e2de5d2b8d5 (diff)
downloadmidimonster-a23ce7718ab61e73586d2738329d6bbace0b764b.tar.gz
midimonster-a23ce7718ab61e73586d2738329d6bbace0b764b.tar.bz2
midimonster-a23ce7718ab61e73586d2738329d6bbace0b764b.zip
Implement evdev relative axis inversion
-rw-r--r--backends/evdev.c15
-rw-r--r--backends/evdev.h1
-rw-r--r--backends/evdev.md8
3 files changed, 22 insertions, 2 deletions
diff --git a/backends/evdev.c b/backends/evdev.c
index 565eb17..7a7913d 100644
--- a/backends/evdev.c
+++ b/backends/evdev.c
@@ -205,8 +205,13 @@ static int evdev_configure_instance(instance* inst, char* option, char* value) {
fprintf(stderr, "Failed to allocate memory\n");
return 1;
}
+ data->relative_axis[data->relative_axes].inverted = 0;
data->relative_axis[data->relative_axes].code = libevdev_event_code_from_name(EV_REL, option + 8);
- data->relative_axis[data->relative_axes].max = strtoul(value, &next_token, 0);
+ data->relative_axis[data->relative_axes].max = strtoll(value, &next_token, 0);
+ if(data->relative_axis[data->relative_axes].max < 0){
+ data->relative_axis[data->relative_axes].max *= -1;
+ data->relative_axis[data->relative_axes].inverted = 1;
+ }
data->relative_axis[data->relative_axes].current = strtoul(next_token, NULL, 0);
if(data->relative_axis[data->relative_axes].code < 0){
fprintf(stderr, "Failed to configure relative axis extents for %s.%s\n", inst->name, option + 8);
@@ -313,6 +318,9 @@ static int evdev_push_event(instance* inst, evdev_instance_data* data, struct in
case EV_REL:
for(axis = 0; axis < data->relative_axes; axis++){
if(data->relative_axis[axis].code == event.code){
+ if(data->relative_axis[axis].inverted){
+ event.value *= -1;
+ }
data->relative_axis[axis].current = clamp(data->relative_axis[axis].current + event.value, data->relative_axis[axis].max, 0);
val.normalised = (double) data->relative_axis[axis].current / (double) data->relative_axis[axis].max;
break;
@@ -374,6 +382,11 @@ static int evdev_handle(size_t num, managed_fd* fds){
read_flags = LIBEVDEV_READ_FLAG_SYNC;
}
+ //exclude synchronization events
+ if(ev.type == EV_SYN){
+ continue;
+ }
+
//handle event
if(evdev_push_event(inst, data, ev)){
return 1;
diff --git a/backends/evdev.h b/backends/evdev.h
index d719631..f89e362 100644
--- a/backends/evdev.h
+++ b/backends/evdev.h
@@ -25,6 +25,7 @@ static int evdev_shutdown();
#endif
typedef struct /*_evdev_relative_axis_config*/ {
+ uint8_t inverted;
int code;
int64_t max;
int64_t current;
diff --git a/backends/evdev.md b/backends/evdev.md
index 995b44c..88dfc85 100644
--- a/backends/evdev.md
+++ b/backends/evdev.md
@@ -38,12 +38,18 @@ If an axis is not used for output, this configuration can be omitted.
For real devices, all of these parameters for every axis can be found by running `evtest` on the device.
To use the input from relative axes in absolute-value based protocols, the backend needs a reference frame to
-convert the relative movements to absolute values.
+convert the relative movements to absolute values. To invert the mapping of the relative axis, specify the `max` value
+as a negative number, for example:
+
+```
+relaxis.REL_X = -1024 512
+```
If relative axes are used without specifying their extents, the channel will generate normalized values
of `0`, `0.5` and `1` for any input less than, equal to and greater than `0`, respectively. As for output, only
the values `-1`, `0` and `1` are generated for the same interval.
+
#### Channel specification
A channel is specified by its event type and event code, separated by `.`. For a complete list of event types and codes