diff --git a/src/libei-device.c b/src/libei-device.c index 6b1e6cd..8f80a1b 100644 --- a/src/libei-device.c +++ b/src/libei-device.c @@ -1195,6 +1195,18 @@ ei_device_get_region(struct ei_device *device, size_t index) return list_nth_entry(struct ei_region, &device->regions, link, index); } +_public_ struct ei_region * +ei_device_get_region_at(struct ei_device *device, double x, double y) +{ + struct ei_region *r; + + list_for_each(r, &device->regions, link) { + if (ei_region_contains(r, x, y)) + return r; + } + return NULL; +} + static inline void ei_device_resume_scrolling(struct ei_device *device, double x, double y) { diff --git a/src/libei.h b/src/libei.h index 3294abd..2980d28 100644 --- a/src/libei.h +++ b/src/libei.h @@ -1158,6 +1158,17 @@ ei_device_has_capability(struct ei_device *device, struct ei_region * ei_device_get_region(struct ei_device *device, size_t index); +/** + * @ingroup libei-device + * + * Return the region that contains the given point x/y (in desktop-wide + * coordinates) or NULL if the coordinates are outside all regions. + * + * @since 1.1 + */ +struct ei_region * +ei_device_get_region_at(struct ei_device *device, double x, double y); + /** * @ingroup libei-region */ diff --git a/src/libeis-device.c b/src/libeis-device.c index 83dc2d9..9501b2b 100644 --- a/src/libeis-device.c +++ b/src/libeis-device.c @@ -193,6 +193,18 @@ eis_device_get_region(struct eis_device *device, size_t index) return list_nth_entry(struct eis_region, &device->regions, link, index); } +_public_ struct eis_region * +eis_device_get_region_at(struct eis_device *device, double x, double y) +{ + struct eis_region *r; + + list_for_each(r, &device->regions, link) { + if (eis_region_contains(r, x, y)) + return r; + } + return NULL; +} + _public_ struct eis_client * eis_device_get_client(struct eis_device *device) { diff --git a/src/libeis.h b/src/libeis.h index 6264962..f88d928 100644 --- a/src/libeis.h +++ b/src/libeis.h @@ -953,6 +953,17 @@ eis_region_add(struct eis_region *region); struct eis_region * eis_device_get_region(struct eis_device *device, size_t index); +/** + * @ingroup libeis-device + * + * Return the region that contains the given point x/y (in desktop-wide + * coordinates) or NULL if the coordinates are outside all regions. + * + * @since 1.1 + */ +struct eis_region * +eis_device_get_region_at(struct eis_device *device, double x, double y); + /** * @ingroup libeis-region */ diff --git a/test/test-ei-device.c b/test/test-ei-device.c index 5929968..7c8ac90 100644 --- a/test/test-ei-device.c +++ b/test/test-ei-device.c @@ -543,7 +543,7 @@ MUNIT_TEST(test_ei_device_regions) with_client(peck) { struct ei_device *device = peck_ei_get_default_pointer_absolute(peck); - struct ei_region *r; + struct ei_region *r, *r2; r = ei_device_get_region(device, 0); munit_assert_int(ei_region_get_width(r), ==, 100); @@ -552,6 +552,11 @@ MUNIT_TEST(test_ei_device_regions) munit_assert_int(ei_region_get_y(r), ==, 400); munit_assert_double_equal(ei_region_get_physical_scale(r), 1.0, 2 /* precision */); + r2 = ei_device_get_region_at(device, 300, 400); + munit_assert_ptr_equal(r, r2); + r2 = ei_device_get_region_at(device, 350, 450); + munit_assert_ptr_equal(r, r2); + r = ei_device_get_region(device, 1); munit_assert_int(ei_region_get_width(r), ==, 500); munit_assert_int(ei_region_get_height(r), ==, 600); @@ -559,6 +564,9 @@ MUNIT_TEST(test_ei_device_regions) munit_assert_int(ei_region_get_y(r), ==, 800); munit_assert_double_equal(ei_region_get_physical_scale(r), 3.9, 2 /* precision */); + r2 = ei_device_get_region_at(device, 750, 850); + munit_assert_ptr_equal(r, r2); + r = ei_device_get_region(device, 2); munit_assert_int(ei_region_get_width(r), ==, 900); munit_assert_int(ei_region_get_height(r), ==, 1000); @@ -566,7 +574,12 @@ MUNIT_TEST(test_ei_device_regions) munit_assert_int(ei_region_get_y(r), ==, 1200); munit_assert_double_equal(ei_region_get_physical_scale(r), 0.3, 2 /* precision */); + r2 = ei_device_get_region_at(device, 1999, 2199); + munit_assert_ptr_equal(r, r2); + munit_assert_ptr_null(ei_device_get_region_at(device, 2000, 2200)); /* at the edge */ + munit_assert_ptr_null(ei_device_get_region(device, 3)); + munit_assert_ptr_null(ei_device_get_region_at(device, 0, 100)); } return MUNIT_OK;