diff --git a/src/libinput-util.h b/src/libinput-util.h index 11c4f5c2..4488fbff 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -84,4 +84,26 @@ zalloc(size_t size) return calloc(1, size); } +/* This bitfield helper implementation is taken from from libevdev-util.h, + * except that it has been modified to work with arrays of unsigned chars + */ + +static inline int +bit_is_set(const unsigned char *array, int bit) +{ + return !!(array[bit / 8] & (1 << (bit % 8))); +} + +static inline void +set_bit(unsigned char *array, int bit) +{ + array[bit / 8] |= (1 << (bit % 8)); +} + +static inline void +clear_bit(unsigned char *array, int bit) +{ + array[bit / 8] &= ~(1 << (bit % 8)); +} + #endif /* LIBINPUT_UTIL_H */ diff --git a/test/misc.c b/test/misc.c index 133bdb60..9ff31753 100644 --- a/test/misc.c +++ b/test/misc.c @@ -29,6 +29,7 @@ #include #include "litest.h" +#include "libinput-util.h" static int open_restricted(const char *path, int flags, void *data) { @@ -371,12 +372,50 @@ START_TEST(event_conversion_touch) } END_TEST +START_TEST(bitfield_helpers) +{ + /* This value has a bit set on all of the word boundaries we want to + * test: 0, 1, 7, 8, 31, 32, and 33 + */ + unsigned char read_bitfield[] = { 0x83, 0x1, 0x0, 0x80, 0x3 }; + unsigned char write_bitfield[ARRAY_LENGTH(read_bitfield)]; + size_t i; + + /* Now check that the bitfield we wrote to came out to be the same as + * the bitfield we were writing from */ + for (i = 0; i < ARRAY_LENGTH(read_bitfield) * 8; i++) { + switch (i) { + case 0: + case 1: + case 7: + case 8: + case 31: + case 32: + case 33: + ck_assert(bit_is_set(read_bitfield, i)); + set_bit(write_bitfield, i); + break; + default: + ck_assert(!bit_is_set(read_bitfield, i)); + clear_bit(write_bitfield, i); + break; + } + } + + ck_assert_int_eq(memcmp(read_bitfield, + write_bitfield, + sizeof(read_bitfield)), + 0); +} +END_TEST + int main (int argc, char **argv) { litest_add_no_device("events:conversion", event_conversion_device_notify); litest_add_no_device("events:conversion", event_conversion_pointer); litest_add_no_device("events:conversion", event_conversion_pointer_abs); litest_add_no_device("events:conversion", event_conversion_key); litest_add_no_device("events:conversion", event_conversion_touch); + litest_add_no_device("bitfield_helpers", bitfield_helpers); return litest_run(argc, argv); }