diff --git a/src/libinput-util.c b/src/libinput-util.c index 3a9c8db5..a383fa17 100644 --- a/src/libinput-util.c +++ b/src/libinput-util.c @@ -234,3 +234,33 @@ parse_trackpoint_accel_property(const char *prop) return accel; } + +/** + * Parses a simple dimension string in the form of "10x40". The two + * numbers must be positive integers in decimal notation. + * On success, the two numbers are stored in w and h. On failure, w and h + * are unmodified. + * + * @param prop The value of the property + * @param w Returns the first component of the dimension + * @param h Returns the second component of the dimension + * @return true on success, false otherwise + */ +bool +parse_dimension_property(const char *prop, size_t *w, size_t *h) +{ + int x, y; + + if (!prop) + return false; + + if (sscanf(prop, "%dx%d", &x, &y) != 2) + return false; + + if (x < 0 || y < 0) + return false; + + *w = (size_t)x; + *h = (size_t)y; + return true; +} diff --git a/src/libinput-util.h b/src/libinput-util.h index 00c93fe0..f27bcfd4 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -296,6 +297,7 @@ enum ratelimit_state ratelimit_test(struct ratelimit *r); int parse_mouse_dpi_property(const char *prop); int parse_mouse_wheel_click_angle_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); static inline double vector_length(double x, double y) diff --git a/test/misc.c b/test/misc.c index 0cffa227..2a2a63a8 100644 --- a/test/misc.c +++ b/test/misc.c @@ -584,6 +584,52 @@ START_TEST(trackpoint_accel_parser) } END_TEST +struct parser_test_dimension { + char *tag; + bool success; + int x, y; +}; + +START_TEST(dimension_prop_parser) +{ + struct parser_test_dimension tests[] = { + { "10x10", true, 10, 10 }, + { "1x20", true, 1, 20 }, + { "1x8000", true, 1, 8000 }, + { "238492x428210", true, 238492, 428210 }, + { "0x0", true, 0, 0 }, + { "-10x10", false, 0, 0 }, + { "-1", false, 0, 0 }, + { "1x-99", false, 0, 0 }, + { "0", false, 0, 0 }, + { "100", false, 0, 0 }, + { "", false, 0, 0 }, + { "abd", false, 0, 0 }, + { "xabd", false, 0, 0 }, + { "0xaf", false, 0, 0 }, + { "0x0x", true, 0, 0 }, + { "x10", false, 0, 0 }, + { NULL, false, 0, 0 } + }; + int i; + size_t x, y; + bool success; + + for (i = 0; tests[i].tag != NULL; i++) { + x = y = 0xad; + success = parse_dimension_property(tests[i].tag, &x, &y); + ck_assert(success == tests[i].success); + if (success) { + ck_assert_int_eq(x, tests[i].x); + ck_assert_int_eq(y, tests[i].y); + } else { + ck_assert_int_eq(x, 0xad); + ck_assert_int_eq(y, 0xad); + } + } +} +END_TEST + void litest_setup_tests(void) { @@ -602,4 +648,5 @@ litest_setup_tests(void) litest_add_no_device("misc:parser", dpi_parser); litest_add_no_device("misc:parser", wheel_click_parser); litest_add_no_device("misc:parser", trackpoint_accel_parser); + litest_add_no_device("misc:parser", dimension_prop_parser); }