implement ioctl()

This commit is contained in:
illiliti
2020-07-13 02:16:37 +03:00
parent a50690071e
commit 93e84c2c4b
3 changed files with 45 additions and 22 deletions

View File

@@ -16,4 +16,4 @@ TODO
----
* [ ] implement hotplugging support
* [ ] remove [dirty hack](https://github.com/illiliti/libudev-zero/blob/e76f9b282442505bd6b0b08b411679aae1581fa5/udev_device.c#L383). use ioctl()
* [x] remove [dirty hack](https://github.com/illiliti/libudev-zero/blob/e76f9b282442505bd6b0b08b411679aae1581fa5/udev_device.c#L383). use ioctl()

View File

@@ -4,8 +4,9 @@
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <fnmatch.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/input.h>
#include <sys/sysmacros.h>
#include "udev.h"
@@ -378,12 +379,16 @@ void udev_device_set_properties_from_uevent(struct udev_device *udev_device)
fclose(file);
}
// TODO extract INPUT properties using libevdev or direct ioctl's(complex), HELP WANTED!
// Very very very dirty hack to detect INPUT properties. False positives are guaranteed
int test_bit(unsigned long int arr[], int bit)
{
return arr[bit / LONG_BIT] & (1 << (bit % LONG_BIT));
}
void udev_device_set_properties_from_ioctl(struct udev_device *udev_device)
{
const char *name, *subsystem;
struct udev_device *parent;
unsigned long int bits[96], key_bits[96], rel_bits[96], abs_bits[96];
const char *subsystem;
int fd;
subsystem = udev_device_get_subsystem(udev_device);
@@ -392,27 +397,44 @@ void udev_device_set_properties_from_ioctl(struct udev_device *udev_device)
}
udev_list_entry_add(&udev_device->properties, "ID_INPUT", "1");
name = udev_device_get_sysattr_value(udev_device, "name");
if (!name) {
parent = udev_device_get_parent(udev_device);
name = udev_device_get_sysattr_value(parent, "name");
fd = open(udev_device_get_devnode(udev_device), O_RDONLY);
if (!name) {
return;
if (fd == -1) {
return;
}
if (ioctl(fd, EVIOCGBIT(0, sizeof(bits)), &bits) == -1 ||
ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), &key_bits) == -1 ||
ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bits)), &rel_bits) == -1 ||
ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), &abs_bits) == -1) {
return;
}
if (test_bit(bits, EV_SW)) {
udev_list_entry_add(&udev_device->properties, "ID_INPUT_SWITCH", "1");
}
if (test_bit(bits, EV_KEY) && test_bit(key_bits, KEY_ENTER)) {
udev_list_entry_add(&udev_device->properties, "ID_INPUT_KEY", "1");
udev_list_entry_add(&udev_device->properties, "ID_INPUT_KEYBOARD", "1");
}
if (test_bit(bits, EV_REL) && test_bit(rel_bits, REL_Y) && test_bit(rel_bits, REL_X) &&
test_bit(key_bits, BTN_MOUSE)) {
udev_list_entry_add(&udev_device->properties, "ID_INPUT_MOUSE", "1");
}
if (test_bit(bits, EV_ABS) && test_bit(abs_bits, ABS_Y) && test_bit(abs_bits, ABS_X)) {
if (test_bit(key_bits, BTN_TOOL_FINGER) && !test_bit(key_bits, BTN_TOOL_PEN)) {
udev_list_entry_add(&udev_device->properties, "ID_INPUT_TOUCHPAD", "1");
}
else if (test_bit(key_bits, BTN_MOUSE)) {
udev_list_entry_add(&udev_device->properties, "ID_INPUT_MOUSE", "1");
}
}
// Your mind will be dead after reading this code
if (fnmatch("*[Mm][Ou][Uu][Ss][Ee]*", name, 0) == 0) {
udev_list_entry_add(&udev_device->properties, "ID_INPUT_MOUSE", "1");
}
else if (fnmatch("*[Tt][Oo][Uu][Cc][Hh][Pp][Aa][Dd]*", name, 0) == 0) {
udev_list_entry_add(&udev_device->properties, "ID_INPUT_TOUCHPAD", "1");
}
else if (fnmatch("*[Kk][Ee][Yy][Bb][Oo][Aa][Rr][Dd]*", name, 0) == 0) {
udev_list_entry_add(&udev_device->properties, "ID_INPUT_KEYBOARD", "1");
}
close(fd);
}
UDEV_EXPORT struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath)

View File

@@ -1,3 +1,4 @@
int test_bit(unsigned long int arr[], int bit);
const char *udev_device_read_symlink(struct udev_device *udev_device, const char *name);
void udev_device_set_properties_from_uevent(struct udev_device *udev_device);
void udev_device_set_properties_from_ioctl(struct udev_device *udev_device);