summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/evdev.c26
-rw-r--r--src/libinput-util.c38
-rw-r--r--src/libinput-util.h1
-rw-r--r--test/test-misc.c55
4 files changed, 99 insertions, 21 deletions
diff --git a/src/evdev.c b/src/evdev.c
index b8d8b75a..d5b36ab8 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -3052,37 +3052,21 @@ evdev_device_calibrate(struct evdev_device *device,
void
evdev_read_calibration_prop(struct evdev_device *device)
{
- const char *calibration_values;
+ const char *prop;
float calibration[6];
- int idx;
- char **strv;
- calibration_values =
- udev_device_get_property_value(device->udev_device,
- "LIBINPUT_CALIBRATION_MATRIX");
+ prop = udev_device_get_property_value(device->udev_device,
+ "LIBINPUT_CALIBRATION_MATRIX");
- if (calibration_values == NULL)
+ if (prop == NULL)
return;
if (!device->abs.absinfo_x || !device->abs.absinfo_y)
return;
- strv = strv_from_string(calibration_values, " ");
- if (!strv)
+ if (!parse_calibration_property(prop, calibration))
return;
- for (idx = 0; idx < 6; idx++) {
- double v;
- if (strv[idx] == NULL || !safe_atod(strv[idx], &v)) {
- strv_free(strv);
- return;
- }
-
- calibration[idx] = v;
- }
-
- strv_free(strv);
-
evdev_device_set_default_calibration(device, calibration);
log_info(evdev_libinput_context(device),
"Applying calibration: %f %f %f %f %f %f\n",
diff --git a/src/libinput-util.c b/src/libinput-util.c
index aa69a37b..d75955cf 100644
--- a/src/libinput-util.c
+++ b/src/libinput-util.c
@@ -278,6 +278,44 @@ parse_dimension_property(const char *prop, size_t *w, size_t *h)
return true;
}
+/**
+ * Parses a set of 6 space-separated floats.
+ *
+ * @param prop The string value of the property
+ * @param calibration Returns the six components
+ * @return true on success, false otherwise
+ */
+bool
+parse_calibration_property(const char *prop, float calibration_out[6])
+{
+ int idx;
+ char **strv;
+ float calibration[6];
+
+ if (!prop)
+ return false;
+
+ strv = strv_from_string(prop, " ");
+ if (!strv)
+ return false;
+
+ for (idx = 0; idx < 6; idx++) {
+ double v;
+ if (strv[idx] == NULL || !safe_atod(strv[idx], &v)) {
+ strv_free(strv);
+ return false;
+ }
+
+ calibration[idx] = v;
+ }
+
+ strv_free(strv);
+
+ memcpy(calibration_out, calibration, sizeof(calibration));
+
+ return true;
+}
+
bool
parse_switch_reliability_property(const char *prop,
enum switch_reliability *reliability)
diff --git a/src/libinput-util.h b/src/libinput-util.h
index 1d03ce13..459c6c4c 100644
--- a/src/libinput-util.h
+++ b/src/libinput-util.h
@@ -376,6 +376,7 @@ int parse_mouse_wheel_click_angle_property(const char *prop);
int parse_mouse_wheel_click_count_property(const char *prop);
double parse_trackpoint_accel_property(const char *prop);
bool parse_dimension_property(const char *prop, size_t *width, size_t *height);
+bool parse_calibration_property(const char *prop, float calibration[6]);
enum switch_reliability {
RELIABILITY_UNKNOWN,
diff --git a/test/test-misc.c b/test/test-misc.c
index 36cabdcf..3f4b2290 100644
--- a/test/test-misc.c
+++ b/test/test-misc.c
@@ -947,6 +947,60 @@ START_TEST(reliability_prop_parser)
}
END_TEST
+struct parser_test_calibration {
+ char *prop;
+ bool success;
+ float values[6];
+};
+
+START_TEST(calibration_prop_parser)
+{
+#define DEFAULT_VALUES { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 }
+ const float untouched[6] = DEFAULT_VALUES;
+ struct parser_test_calibration tests[] = {
+ { "", false, DEFAULT_VALUES },
+ { "banana", false, DEFAULT_VALUES },
+ { "1 2 3 a 5 6", false, DEFAULT_VALUES },
+ { "2", false, DEFAULT_VALUES },
+ { "2 3 4 5 6", false, DEFAULT_VALUES },
+ { "1 2 3 4 5 6", true, DEFAULT_VALUES },
+ { "6.00012 3.244 4.238 5.2421 6.0134 8.860", true,
+ { 6.00012, 3.244, 4.238, 5.2421, 6.0134, 8.860 }},
+ { "0xff 2 3 4 5 6", true,
+ { 255, 2, 3, 4, 5, 6 }},
+ { NULL, false, DEFAULT_VALUES }
+ };
+ bool success;
+ float calibration[6];
+ int rc;
+ int i;
+
+ for (i = 0; tests[i].prop != NULL; i++) {
+ memcpy(calibration, untouched, sizeof(calibration));
+
+ success = parse_calibration_property(tests[i].prop,
+ calibration);
+ ck_assert_int_eq(success, tests[i].success);
+ if (success)
+ rc = memcmp(tests[i].values,
+ calibration,
+ sizeof(calibration));
+ else
+ rc = memcmp(untouched,
+ calibration,
+ sizeof(calibration));
+ ck_assert_int_eq(rc, 0);
+ }
+
+ memcpy(calibration, untouched, sizeof(calibration));
+
+ success = parse_calibration_property(NULL, calibration);
+ ck_assert(success == false);
+ rc = memcmp(untouched, calibration, sizeof(calibration));
+ ck_assert_int_eq(rc, 0);
+}
+END_TEST
+
START_TEST(time_conversion)
{
ck_assert_int_eq(us(10), 10);
@@ -1220,6 +1274,7 @@ litest_setup_tests_misc(void)
litest_add_no_device("misc:parser", trackpoint_accel_parser);
litest_add_no_device("misc:parser", dimension_prop_parser);
litest_add_no_device("misc:parser", reliability_prop_parser);
+ litest_add_no_device("misc:parser", calibration_prop_parser);
litest_add_no_device("misc:parser", safe_atoi_test);
litest_add_no_device("misc:parser", safe_atod_test);
litest_add_no_device("misc:parser", strsplit_test);