forked from enlightenment/efl
pretty huge overhaul:
test app should be a bit more robust now udev compat code is done (I think?) added udev walk functions for easier device checking fixed some potential segv in cases where errors checking was not complete enough SVN revision: 49081
This commit is contained in:
parent
0cae05c2a8
commit
e13e6ce071
|
@ -60,9 +60,11 @@ AS_IF(
|
|||
[PKG_CHECK_MODULES(UDEV, libudev, [], [enable_eeze_udev="no"])]
|
||||
)
|
||||
|
||||
udev_version=$(pkg-config udev --version | cut -d. -f2)
|
||||
if test $udev_version -lt 23;then
|
||||
AC_DEFINE([OLD_UDEV_RRRRRRRRRRRRRR],[1],[compat functionality for udev < 0.23])
|
||||
udev_version=$(pkg-config libudev --modversion)
|
||||
|
||||
if test $udev_version -lt 142;then
|
||||
AC_MSG_WARN([Old udev version detected, enabling compat code])
|
||||
AC_DEFINE([OLD_UDEV_RRRRRRRRRRRRRR],[1],[compat functionality for udev < 142])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([BUILD_EEZE_UDEV], [test "x${enable_eeze_udev}" = "xyes"])
|
||||
|
|
|
@ -16,23 +16,19 @@ catch_events(const char *device, const char *event, void *data, Eeze_Udev_Watch
|
|||
kbdmouse *akbdmouse = data;
|
||||
Eina_List *l;
|
||||
const char *name, *dev, *type;
|
||||
int new = 0;
|
||||
|
||||
/* the device that comes through will be prefixed by "/sys"
|
||||
* but the saved name will not, so we check for the saved name
|
||||
* inside the device name
|
||||
*/
|
||||
EINA_LIST_FOREACH(akbdmouse->kbds, l, name)
|
||||
if (strstr(device, name)) goto end;
|
||||
if (strncmp(device + 5, name, strlen(device + 5) - 8)) goto end;
|
||||
EINA_LIST_FOREACH(akbdmouse->mice, l, name)
|
||||
if (strstr(device, name)) goto end;
|
||||
if (strncmp(device + 5, name, strlen(device + 5) - 8)) goto end;
|
||||
|
||||
/* check to see if the device was just plugged in */
|
||||
if (eeze_udev_syspath_is_kbd(device) || eeze_udev_syspath_is_mouse(device))
|
||||
{
|
||||
new = 1;
|
||||
goto end;
|
||||
}
|
||||
goto end;
|
||||
/* if we reach here, the device is neither a keyboard nor a mouse that we saw
|
||||
* previously, so we print a moderately amusing message and bail
|
||||
*/
|
||||
|
@ -44,7 +40,7 @@ end:
|
|||
* we can retrieve them now even though the device has been removed and
|
||||
* is inaccessible to udev
|
||||
*/
|
||||
if (new)
|
||||
if (!strcmp(event, "add"))
|
||||
{
|
||||
dev = eeze_udev_syspath_get_devpath(device);
|
||||
type = "plugged in";
|
||||
|
@ -119,8 +115,7 @@ int main()
|
|||
{ /* add the devpath to the hash for use in the cb later */
|
||||
if ((check = eeze_udev_syspath_get_devpath(name)))
|
||||
eina_hash_direct_add(hash, name, check); /* get a property using the device's syspath */
|
||||
if ((check = eeze_udev_syspath_get_property(name, "ID_VENDOR")))
|
||||
printf("Found mouse %s with vendor: %s\n", name, check);
|
||||
printf("Found mouse %s with vendor: %s\n", name, eeze_udev_walk_get_sysattr(name, "manufacturer"));
|
||||
}
|
||||
/* we save this list for later, because once a device is unplugged it can
|
||||
* no longer be detected by udev, and any related properties are unusable unless
|
||||
|
|
|
@ -140,6 +140,9 @@ extern "C" {
|
|||
EAPI Eina_Bool eeze_udev_syspath_is_kbd(const char *syspath);
|
||||
EAPI Eina_Bool eeze_udev_syspath_is_touchpad(const char *syspath);
|
||||
|
||||
EAPI Eina_Bool eeze_udev_walk_check_sysattr(const char *syspath, const char *sysattr, const char *value);
|
||||
EAPI const char *eeze_udev_walk_get_sysattr(const char *syspath, const char *sysattr);
|
||||
|
||||
EAPI Eeze_Udev_Watch *eeze_udev_watch_add(Eeze_Udev_Type type, int event, void(*func)(const char *, const char *, void *, Eeze_Udev_Watch *), void *user_data);
|
||||
EAPI void *eeze_udev_watch_del(Eeze_Udev_Watch *watch);
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ eeze_udev.c \
|
|||
eeze_udev_watch.c \
|
||||
eeze_udev_main.c \
|
||||
eeze_udev_find.c \
|
||||
eeze_udev_walk.c \
|
||||
eeze_udev_private.c
|
||||
|
||||
libeeze_udev_la_LIBADD = @ECORE_LIBS@ @UDEV_LIBS@
|
||||
|
|
|
@ -118,9 +118,10 @@ eeze_udev_syspath_get_devpath(const char *syspath)
|
|||
eina_strbuf_append(sbuf, syspath);
|
||||
|
||||
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
|
||||
if ((udev_device_get_property_value(device, "DEVNAME")))
|
||||
name = eina_stringshare_add(eina_strbuf_string_get(sbuf));
|
||||
if (!(name = udev_device_get_property_value(device, "DEVNAME")))
|
||||
return NULL;
|
||||
|
||||
name = eina_stringshare_add(name);
|
||||
udev_device_unref(device);
|
||||
udev_unref(udev);
|
||||
eina_strbuf_free(sbuf);
|
||||
|
@ -356,7 +357,7 @@ eeze_udev_syspath_is_mouse(const char *syspath)
|
|||
|
||||
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
|
||||
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
|
||||
mouse = _walk_parents_for_attr(device, "bInterfaceProtocol", "02");
|
||||
mouse = _walk_parents_test_attr(device, "bInterfaceProtocol", "02");
|
||||
if (!mouse)
|
||||
{
|
||||
test = udev_device_get_property_value(device, "ID_CLASS");
|
||||
|
@ -403,7 +404,7 @@ eeze_udev_syspath_is_kbd(const char *syspath)
|
|||
|
||||
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
|
||||
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
|
||||
kbd = _walk_parents_for_attr(device, "bInterfaceProtocol", "01");
|
||||
kbd = _walk_parents_test_attr(device, "bInterfaceProtocol", "01");
|
||||
if (!kbd)
|
||||
{
|
||||
test = udev_device_get_property_value(device, "ID_CLASS");
|
||||
|
@ -437,7 +438,6 @@ eeze_udev_syspath_is_touchpad(const char *syspath)
|
|||
struct udev_device *device;
|
||||
Eina_Bool touchpad = 0;
|
||||
Eina_Strbuf *sbuf;
|
||||
const char *test = NULL;
|
||||
|
||||
if (!syspath) return 0;
|
||||
udev = udev_new();
|
||||
|
@ -450,7 +450,7 @@ eeze_udev_syspath_is_touchpad(const char *syspath)
|
|||
|
||||
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
|
||||
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
|
||||
touchpad = _walk_parents_for_attr(device, "resolution", NULL);
|
||||
touchpad = _walk_parents_test_attr(device, "resolution", NULL);
|
||||
#else
|
||||
test = udev_device_get_property_value(device, "ID_INPUT_TOUCHPAD");
|
||||
if (test) touchpad = atoi(test);
|
||||
|
@ -461,45 +461,3 @@ eeze_udev_syspath_is_touchpad(const char *syspath)
|
|||
|
||||
return touchpad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks up the device chain starting at @p syspath,
|
||||
* checking each device for @p sysattr with (optional) @p value.
|
||||
*
|
||||
* @param syspath The /sys/ path of the device to start at, with or without the /sys/
|
||||
* @param sysattr The attribute to find
|
||||
* @param value OPTIONAL: The value that @p sysattr should have, or NULL
|
||||
*
|
||||
* @return If the sysattr (with value) is found, returns TRUE. Else, false.
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
eeze_udev_syspath_check_sysattr(const char *syspath, const char *sysattr, const char *value)
|
||||
{
|
||||
struct udev *udev;
|
||||
struct udev_device *device, *child, *parent;
|
||||
Eina_Strbuf *sbuf;
|
||||
const char *test = NULL;
|
||||
|
||||
if (!syspath) return 0;
|
||||
udev = udev_new();
|
||||
if (!udev) return 0;
|
||||
|
||||
sbuf = eina_strbuf_new();
|
||||
if (!strstr(syspath, "/sys/"))
|
||||
eina_strbuf_append(sbuf, "/sys/");
|
||||
eina_strbuf_append(sbuf, syspath);
|
||||
|
||||
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
|
||||
|
||||
for (parent = device; parent; child = parent, parent = udev_device_get_parent(child))
|
||||
{
|
||||
if ((test = udev_device_get_sysattr_value(parent, sysattr)))
|
||||
if ((value) && (!strcmp(test, value)))
|
||||
{
|
||||
eina_strbuf_free(sbuf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
eina_strbuf_free(sbuf);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -117,14 +117,15 @@ eeze_udev_find_unlisted_similar(Eina_List *list)
|
|||
return;
|
||||
}
|
||||
device = udev_device_new_from_syspath(udev, dev);
|
||||
vendor = udev_device_get_property_value(device, "ID_VENDOR_ID");
|
||||
if (vendor)
|
||||
if ((vendor = udev_device_get_property_value(device, "ID_VENDOR_ID")))
|
||||
udev_enumerate_add_match_property(en, "ID_VENDOR_ID", vendor);
|
||||
model = udev_device_get_property_value(device, "ID_MODEL_ID");
|
||||
if (model)
|
||||
else if ((vendor = udev_device_get_property_value(device, "ID_VENDOR")))
|
||||
udev_enumerate_add_match_property(en, "ID_VENDOR", vendor);
|
||||
if ((model = udev_device_get_property_value(device, "ID_MODEL_ID")))
|
||||
udev_enumerate_add_match_property(en, "ID_MODEL_ID", model);
|
||||
revision = udev_device_get_property_value(device, "ID_REVISION");
|
||||
if (revision)
|
||||
else if ((model = udev_device_get_property_value(device, "ID_MODEL")))
|
||||
udev_enumerate_add_match_property(en, "ID_MODEL", model);
|
||||
if ((revision = udev_device_get_property_value(device, "ID_REVISION")))
|
||||
udev_enumerate_add_match_property(en, "ID_REVISION", revision);
|
||||
|
||||
udev_enumerate_scan_devices(en);
|
||||
|
@ -185,15 +186,25 @@ eeze_udev_find_by_type(const Eeze_Udev_Type etype, const char *name)
|
|||
break;
|
||||
case EEZE_UDEV_TYPE_KEYBOARD:
|
||||
udev_enumerate_add_match_subsystem(en, "input");
|
||||
#ifndef OLD_UDEV_RRRRRRRRRRRRRR
|
||||
udev_enumerate_add_match_property(en, "ID_INPUT_KEYBOARD", "1");
|
||||
#else
|
||||
udev_enumerate_add_match_property(en, "ID_CLASS", "kbd");
|
||||
#endif
|
||||
break;
|
||||
case EEZE_UDEV_TYPE_MOUSE:
|
||||
udev_enumerate_add_match_subsystem(en, "input");
|
||||
#ifndef OLD_UDEV_RRRRRRRRRRRRRR
|
||||
udev_enumerate_add_match_property(en, "ID_INPUT_MOUSE", "1");
|
||||
#else
|
||||
udev_enumerate_add_match_property(en, "ID_CLASS", "mouse");
|
||||
#endif
|
||||
break;
|
||||
case EEZE_UDEV_TYPE_TOUCHPAD:
|
||||
udev_enumerate_add_match_subsystem(en, "input");
|
||||
#ifndef OLD_UDEV_RRRRRRRRRRRRRR
|
||||
udev_enumerate_add_match_property(en, "ID_INPUT_TOUCHPAD", "1");
|
||||
#endif
|
||||
break;
|
||||
case EEZE_UDEV_TYPE_DRIVE_MOUNTABLE:
|
||||
udev_enumerate_add_match_subsystem(en, "block");
|
||||
|
@ -245,7 +256,7 @@ eeze_udev_find_by_type(const Eeze_Udev_Type etype, const char *name)
|
|||
|
||||
if (etype == EEZE_UDEV_TYPE_IS_IT_HOT_OR_IS_IT_COLD_SENSOR)
|
||||
{/* ensure that temp input exists somewhere in this device chain */
|
||||
if (!_walk_parents_for_attr(device, "temp1_input", NULL))
|
||||
if (!_walk_parents_test_attr(device, "temp1_input", NULL))
|
||||
goto out;
|
||||
/* if device is not the one which has the temp input, we must go up the chain */
|
||||
if (!(test = udev_device_get_sysattr_value(device, "temp1_input")))
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* with value $value
|
||||
*/
|
||||
Eina_Bool
|
||||
_walk_parents_for_attr(struct udev_device *device, const char *sysattr, const char* value)
|
||||
_walk_parents_test_attr(struct udev_device *device, const char *sysattr, const char* value)
|
||||
{
|
||||
struct udev_device *parent, *child = device;
|
||||
const char *test;
|
||||
|
@ -44,20 +44,22 @@ _get_unlisted_parents(Eina_List *list, struct udev_device *device)
|
|||
Eina_List *l;
|
||||
Eina_Bool found;
|
||||
|
||||
vendor = udev_device_get_property_value(child, "ID_VENDOR_ID");
|
||||
model = udev_device_get_property_value(child, "ID_MODEL_ID");
|
||||
if (!(vendor = udev_device_get_property_value(child, "ID_VENDOR_ID")))
|
||||
vendor = udev_device_get_property_value(child, "ID_VENDOR");
|
||||
if (!(model = udev_device_get_property_value(child, "ID_MODEL_ID")))
|
||||
model = udev_device_get_property_value(child, "ID_MODEL");
|
||||
parent = udev_device_get_parent(child);
|
||||
for (; parent; child = parent, parent = udev_device_get_parent(child))
|
||||
{
|
||||
found = 0;
|
||||
model2 = udev_device_get_property_value(parent, "ID_MODEL_ID");
|
||||
vendor2 = udev_device_get_property_value(parent, "ID_VENDOR_ID");
|
||||
if ((!model2 && model) || (model2 && !model))
|
||||
if (!(vendor2 = udev_device_get_property_value(child, "ID_VENDOR_ID")))
|
||||
vendor2 = udev_device_get_property_value(child, "ID_VENDOR");
|
||||
if (!(model2 = udev_device_get_property_value(child, "ID_MODEL_ID")))
|
||||
model2 = udev_device_get_property_value(child, "ID_MODEL");
|
||||
if ((!model2 && model) || (model2 && !model) || (!vendor2 && vendor) || (vendor2 && !vendor))
|
||||
break;
|
||||
else if ((!vendor2 && vendor) || (vendor2 && !vendor))
|
||||
break;
|
||||
else if (strcmp(model, model2) ||
|
||||
strcmp(vendor, vendor2))
|
||||
else if (((model && model2) && (strcmp(model, model2))) ||
|
||||
((vendor && vendor2) && (strcmp(vendor, vendor2))))
|
||||
break;
|
||||
devname = udev_device_get_syspath(parent);
|
||||
EINA_LIST_FOREACH(list, l, test)
|
||||
|
|
|
@ -24,7 +24,7 @@ extern int _e_eeze_udev_log_dom;
|
|||
#define ERR(...) EINA_LOG_DOM_ERR(_e_eeze_udev_log_dom, __VA_ARGS__)
|
||||
|
||||
/* from watch.c */
|
||||
Eina_Bool _walk_parents_for_attr(struct udev_device *device, const char *sysattr, const char* value);
|
||||
Eina_Bool _walk_parents_test_attr(struct udev_device *device, const char *sysattr, const char* value);
|
||||
void _get_unlisted_parents(Eina_List *list, struct udev_device *device);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <Eeze_Udev.h>
|
||||
#include "eeze_udev_private.h"
|
||||
|
||||
/**
|
||||
* Walks up the device chain starting at @p syspath,
|
||||
* checking each device for @p sysattr with (optional) @p value.
|
||||
*
|
||||
* @param syspath The /sys/ path of the device to start at, with or without the /sys/
|
||||
* @param sysattr The attribute to find
|
||||
* @param value OPTIONAL: The value that @p sysattr should have, or NULL
|
||||
*
|
||||
* @return If the sysattr (with value) is found, returns TRUE. Else, false.
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
eeze_udev_walk_check_sysattr(const char *syspath, const char *sysattr, const char *value)
|
||||
{
|
||||
struct udev *udev;
|
||||
struct udev_device *device, *child, *parent;
|
||||
Eina_Strbuf *sbuf;
|
||||
const char *test = NULL;
|
||||
|
||||
if (!syspath) return 0;
|
||||
udev = udev_new();
|
||||
if (!udev) return 0;
|
||||
|
||||
sbuf = eina_strbuf_new();
|
||||
if (!strstr(syspath, "/sys/"))
|
||||
eina_strbuf_append(sbuf, "/sys/");
|
||||
eina_strbuf_append(sbuf, syspath);
|
||||
|
||||
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
|
||||
|
||||
for (parent = device; parent; child = parent, parent = udev_device_get_parent(child))
|
||||
{
|
||||
if ((test = udev_device_get_sysattr_value(parent, sysattr)))
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
if (!strcmp(test, value))
|
||||
{
|
||||
eina_strbuf_free(sbuf);
|
||||
udev_device_unref(device);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eina_strbuf_free(sbuf);
|
||||
udev_device_unref(device);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
eina_strbuf_free(sbuf);
|
||||
udev_device_unref(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks up the device chain starting at @p syspath,
|
||||
* checking each device for @p sysattr, and returns the value if found.
|
||||
*
|
||||
* @param syspath The /sys/ path of the device to start at, with or without the /sys/
|
||||
* @param sysattr The attribute to find
|
||||
*
|
||||
* @return The value of @p sysattr if found, or NULL
|
||||
*/
|
||||
EAPI const char*
|
||||
eeze_udev_walk_get_sysattr(const char *syspath, const char *sysattr)
|
||||
{
|
||||
struct udev *udev;
|
||||
struct udev_device *device, *child, *parent;
|
||||
Eina_Strbuf *sbuf;
|
||||
const char *test = NULL;
|
||||
|
||||
if (!syspath) return NULL;
|
||||
udev = udev_new();
|
||||
if (!udev) return NULL;
|
||||
|
||||
sbuf = eina_strbuf_new();
|
||||
if (!strstr(syspath, "/sys/"))
|
||||
eina_strbuf_append(sbuf, "/sys/");
|
||||
eina_strbuf_append(sbuf, syspath);
|
||||
|
||||
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
|
||||
|
||||
for (parent = device; parent; child = parent, parent = udev_device_get_parent(child))
|
||||
{
|
||||
if ((test = udev_device_get_sysattr_value(parent, sysattr)))
|
||||
{
|
||||
eina_strbuf_free(sbuf);
|
||||
test = eina_stringshare_add(test);
|
||||
udev_device_unref(device);
|
||||
return test;
|
||||
}
|
||||
}
|
||||
eina_strbuf_free(sbuf);
|
||||
udev_device_unref(device);
|
||||
return NULL;
|
||||
}
|
|
@ -52,7 +52,7 @@ _get_syspath_from_watch(void *data, Ecore_Fd_Handler *fd_handler)
|
|||
if ((!(test = udev_device_get_subsystem(device))) || (strcmp(test, "input")))
|
||||
goto error;
|
||||
test = udev_device_get_property_value(device, "ID_CLASS");
|
||||
if ((_walk_parents_for_attr(device, "bInterfaceProtocol", "01")) || ((test) && (!strcmp(test, "kbd"))))
|
||||
if ((_walk_parents_test_attr(device, "bInterfaceProtocol", "01")) || ((test) && (!strcmp(test, "kbd"))))
|
||||
break;
|
||||
goto error;
|
||||
#endif
|
||||
|
@ -64,7 +64,7 @@ _get_syspath_from_watch(void *data, Ecore_Fd_Handler *fd_handler)
|
|||
if ((!(test = udev_device_get_subsystem(device))) || (strcmp(test, "input")))
|
||||
goto error;
|
||||
test = udev_device_get_property_value(device, "ID_CLASS");
|
||||
if ((_walk_parents_for_attr(device, "bInterfaceProtocol", "02")) || ((test) && (!strcmp(test, "mouse"))))
|
||||
if ((_walk_parents_test_attr(device, "bInterfaceProtocol", "02")) || ((test) && (!strcmp(test, "mouse"))))
|
||||
break;
|
||||
goto error;
|
||||
#endif
|
||||
|
@ -75,7 +75,7 @@ _get_syspath_from_watch(void *data, Ecore_Fd_Handler *fd_handler)
|
|||
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
|
||||
if ((!(test = udev_device_get_subsystem(device))) || (strcmp(test, "input")))
|
||||
goto error;
|
||||
if (_walk_parents_for_attr(device, "resolution", NULL))
|
||||
if (_walk_parents_test_attr(device, "resolution", NULL))
|
||||
break;
|
||||
goto error;
|
||||
#endif
|
||||
|
@ -142,7 +142,7 @@ _get_syspath_from_watch(void *data, Ecore_Fd_Handler *fd_handler)
|
|||
if ((!(test = udev_device_get_subsystem(device))) || (strcmp(test, "hwmon")))
|
||||
goto error;
|
||||
#endif /* have to do stuff up here since we need info from the parent */
|
||||
if (!_walk_parents_for_attr(device, "temp1_input", NULL))
|
||||
if (!_walk_parents_test_attr(device, "temp1_input", NULL))
|
||||
goto error;
|
||||
/* if device is not the one which has the temp input, we must go up the chain */
|
||||
if (!(test = udev_device_get_sysattr_value(device, "temp1_input")))
|
||||
|
|
Loading…
Reference in New Issue