BIG change, api break (again).

watches now return an int value that can be can be bitwise checked with & to reduce usage of strcmp
overall memory allocation should be less (I think), some related bugs fixed along the way
small memory leak in test app that I'm too lazy/blind to figure out
**this should be the last commit that causes an api break


SVN revision: 49118
This commit is contained in:
Mike Blumenkrantz 2010-05-22 01:55:14 +00:00
parent 9317ce25ac
commit 2e71c06192
9 changed files with 694 additions and 594 deletions

View File

@ -2,6 +2,13 @@
#include <Ecore.h>
#include <stdio.h>
/**
* This demo program shows how to use some eeze functions. It roughly
* 1kb as of now, TODO is to fix this but I'm too lazy now and it's only
* a demo.
*/
typedef struct kbdmouse
{
Eina_List *kbds;
@ -11,7 +18,7 @@ typedef struct kbdmouse
static void
/* event will always be a syspath starting with /sys */
catch_events(const char *device, const char *event, void *data, Eeze_Udev_Watch *watch)
catch_events(const char *device, int event, void *data, Eeze_Udev_Watch *watch)
{
kbdmouse *akbdmouse = data;
Eina_List *l;
@ -40,7 +47,7 @@ end:
* we can retrieve them now even though the device has been removed and
* is inaccessible to udev
*/
if (!strcmp(event, "add"))
if ((event & EEZE_UDEV_EVENT_ADD) == EEZE_UDEV_EVENT_ADD)
{
dev = eeze_udev_syspath_get_devpath(device);
type = "plugged in";
@ -52,19 +59,19 @@ end:
}
printf("You %s %s!\n", type, dev);
printf("All tests completed, exiting successfully!\n");
/* and the hash */
eina_hash_free(akbdmouse->hash);
/* now we free the lists */
eina_list_free(akbdmouse->kbds);
eina_list_free(akbdmouse->mice);
/* and the hash */
eina_hash_free(akbdmouse->hash);
/* and the random storage struct */
free(akbdmouse);
/* and quit the main loop */
ecore_main_loop_quit();
/* and delete the watch */
eeze_udev_watch_del(watch);
/* and shut down eudev */
eeze_udev_shutdown();
/* and quit the main loop */
ecore_main_loop_quit();
}
static void

View File

@ -88,9 +88,9 @@
/*bitmasks for watch events*/
#define EEZE_UDEV_EVENT_NONE 0x0000
#define EEZE_UDEV_EVENT_ADD 0x0001
#define EEZE_UDEV_EVENT_REMOVE 0x0001
#define EEZE_UDEV_EVENT_CHANGE 0x0002
#define EEZE_UDEV_EVENT_ONLINE 0x0004
#define EEZE_UDEV_EVENT_REMOVE 0x0002
#define EEZE_UDEV_EVENT_CHANGE 0x0004
#define EEZE_UDEV_EVENT_ONLINE 0x0008
#define EEZE_UDEV_EVENT_OFFLINE 0x0010
/*FIXME: these probably need to be bitmasks with categories*/
@ -143,7 +143,7 @@ extern "C" {
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 Eeze_Udev_Watch *eeze_udev_watch_add(Eeze_Udev_Type type, int event, void(*func)(const char *, int, void *, Eeze_Udev_Watch *), void *user_data);
EAPI void *eeze_udev_watch_del(Eeze_Udev_Watch *watch);
#ifdef __cplusplus

View File

@ -5,6 +5,8 @@
#include <Eeze_Udev.h>
#include "eeze_udev_private.h"
extern _udev *udev;
/**
* @defgroup udev udev
*
@ -16,7 +18,7 @@
*
* @param syspath The syspath of a device, with or without "/sys/"
* @return The syspath of the parent device
*
*
* Return a syspath (/sys/$syspath) for the parent device.
*
* @ingroup udev
@ -24,28 +26,24 @@
EAPI const char *
eeze_udev_syspath_get_parent(const char *syspath)
{
struct udev *udev;
struct udev_device *device, *parent;
_udev_device *device, *parent;
const char *ret;
Eina_Strbuf *sbuf;
if (!syspath) return NULL;
udev = udev_new();
if (!udev) return NULL;
if (!syspath)
return NULL;
sbuf = eina_strbuf_new();
if (!strstr(syspath, "/sys/"))
eina_strbuf_append(sbuf, "/sys/");
eina_strbuf_append(sbuf, syspath);
eina_strbuf_append(sbuf, syspath);
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
parent = udev_device_get_parent(device);
ret = eina_stringshare_add(udev_device_get_property_value(parent, "DEVPATH"));
udev_device_unref(device);
udev_unref(udev);
eina_strbuf_free(sbuf);
return ret;
}
@ -60,34 +58,33 @@ eeze_udev_syspath_get_parent(const char *syspath)
EAPI Eina_List *
eeze_udev_syspath_get_parents(const char *syspath)
{
struct udev *udev;
struct udev_device *child, *parent, *device;
_udev_device *child, *parent, *device;
const char *path;
Eina_Strbuf *sbuf;
Eina_List *devlist = NULL;
if (!syspath) return NULL;
udev = udev_new();
if (!udev) return NULL;
if (!syspath)
return NULL;
sbuf = eina_strbuf_new();
if (!strstr(syspath, "/sys/"))
eina_strbuf_append(sbuf, "/sys/");
eina_strbuf_append(sbuf, syspath);
eina_strbuf_append(sbuf, syspath);
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
if (!(parent = udev_device_get_parent(device)))
return NULL;
for (; parent; child = parent, parent = udev_device_get_parent(child))
{
path = udev_device_get_syspath(parent);
devlist = eina_list_append(devlist, eina_stringshare_add(path));
}
udev_device_unref(device);
udev_unref(udev);
return devlist;
for (; parent; child = parent, parent = udev_device_get_parent(child))
{
path = udev_device_get_syspath(parent);
devlist = eina_list_append(devlist, eina_stringshare_add(path));
}
udev_device_unref(device);
return devlist;
}
/**
@ -95,38 +92,36 @@ eeze_udev_syspath_get_parents(const char *syspath)
*
* @param syspath The /sys/ path with or without the /sys/
* @return A const char* with the /dev/ path or NULL on failure
*
*
* Takes /sys/$PATH and turns it into the corresponding "/dev/x/y".
*
*
* @ingroup udev
*/
EAPI const char *
eeze_udev_syspath_get_devpath(const char *syspath)
{
struct udev *udev;
struct udev_device *device;
const char *name = NULL;
Eina_Strbuf *sbuf;
_udev_device *device;
const char *name = NULL;
Eina_Strbuf *sbuf;
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);
if (!syspath)
return NULL;
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
if (!(name = udev_device_get_property_value(device, "DEVNAME")))
return NULL;
sbuf = eina_strbuf_new();
name = eina_stringshare_add(name);
udev_device_unref(device);
udev_unref(udev);
eina_strbuf_free(sbuf);
if (!strstr(syspath, "/sys/"))
eina_strbuf_append(sbuf, "/sys/");
return name;
eina_strbuf_append(sbuf, syspath);
device = udev_device_new_from_syspath(udev, 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);
eina_strbuf_free(sbuf);
return name;
}
/**
@ -134,37 +129,34 @@ eeze_udev_syspath_get_devpath(const char *syspath)
*
* @param syspath The /sys/ path with or without the /sys/
* @return A const char* with the subsystem of the device or NULL on failure
*
*
* Takes /sys/$PATH and returns the corresponding device subsystem,
* such as "input" for keyboards/mice.
*
*
* @ingroup udev
*/
EAPI const char *
eeze_udev_syspath_get_subsystem(const char *syspath)
{
struct udev *udev;
struct udev_device *device;
const char *subsystem;
Eina_Strbuf *sbuf;
_udev_device *device;
const char *subsystem;
Eina_Strbuf *sbuf;
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);
if (!syspath)
return NULL;
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
subsystem = eina_stringshare_add(udev_device_get_property_value(device, "SUBSYSTEM"));
sbuf = eina_strbuf_new();
udev_device_unref(device);
udev_unref(udev);
eina_strbuf_free(sbuf);
if (!strstr(syspath, "/sys/"))
eina_strbuf_append(sbuf, "/sys/");
return subsystem;
eina_strbuf_append(sbuf, syspath);
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
subsystem =
eina_stringshare_add(udev_device_get_property_value(device, "SUBSYSTEM"));
udev_device_unref(device);
eina_strbuf_free(sbuf);
return subsystem;
}
/**
@ -173,35 +165,33 @@ eeze_udev_syspath_get_subsystem(const char *syspath)
* @param syspath The /sys/ path with or without the /sys/
* @param property The property to get; full list of these is a FIXME
* @return A const char* with the property or NULL on failure
*
*
* @ingroup udev
*/
EAPI const char *
eeze_udev_syspath_get_property(const char *syspath, const char *property)
{
struct udev *udev;
struct udev_device *device;
const char *value = NULL, *test;
Eina_Strbuf *sbuf;
_udev_device *device;
const char *value = NULL, *test;
Eina_Strbuf *sbuf;
if (!syspath || !property) return NULL;
udev = udev_new();
if (!udev) return NULL;
if (!syspath || !property)
return NULL;
sbuf = eina_strbuf_new();
if (!strstr(syspath, "/sys/"))
eina_strbuf_append(sbuf, "/sys/");
eina_strbuf_append(sbuf, syspath);
sbuf = eina_strbuf_new();
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
if ((test = udev_device_get_property_value(device, property)));
value = eina_stringshare_add(test);
if (!strstr(syspath, "/sys/"))
eina_strbuf_append(sbuf, "/sys/");
udev_device_unref(device);
udev_unref(udev);
eina_strbuf_free(sbuf);
eina_strbuf_append(sbuf, syspath);
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
return value;
if ((test = udev_device_get_property_value(device, property)))
value = eina_stringshare_add(test);
udev_device_unref(device);
eina_strbuf_free(sbuf);
return value;
}
/**
@ -210,35 +200,33 @@ eeze_udev_syspath_get_property(const char *syspath, const char *property)
* @param syspath The /sys/ path with or without the /sys/
* @param sysattr The sysattr to get; full list of these is a FIXME
* @return A const char* with the sysattr or NULL on failure
*
*
* @ingroup udev
*/
EAPI const char *
eeze_udev_syspath_get_sysattr(const char *syspath, const char *sysattr)
{
struct udev *udev;
struct udev_device *device;
const char *value = NULL, *test;
Eina_Strbuf *sbuf;
_udev_device *device;
const char *value = NULL, *test;
Eina_Strbuf *sbuf;
if (!syspath || !sysattr) return NULL;
udev = udev_new();
if (!udev) return NULL;
if (!syspath || !sysattr)
return NULL;
sbuf = eina_strbuf_new();
if (!strstr(syspath, "/sys/"))
eina_strbuf_append(sbuf, "/sys/");
eina_strbuf_append(sbuf, syspath);
sbuf = eina_strbuf_new();
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
if ((test = udev_device_get_sysattr_value(device, sysattr)));
value = eina_stringshare_add(test);
if (!strstr(syspath, "/sys/"))
eina_strbuf_append(sbuf, "/sys/");
udev_device_unref(device);
udev_unref(udev);
eina_strbuf_free(sbuf);
eina_strbuf_append(sbuf, syspath);
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
return value;
if ((test = udev_device_get_sysattr_value(device, sysattr)))
value = eina_stringshare_add(test);
udev_device_unref(device);
eina_strbuf_free(sbuf);
return value;
}
/**
@ -246,43 +234,40 @@ eeze_udev_syspath_get_sysattr(const char *syspath, const char *sysattr)
*
* @param devpath The /dev/ path of the device
* @return A const char* which corresponds to the /sys/ path of the device or NULL on failure
*
*
* Takes "/dev/path" and returns the corresponding /sys/ path (without the "/sys/")
*
*
* @ingroup udev
*/
EAPI const char *
eeze_udev_devpath_get_syspath(const char *devpath)
{
struct udev *udev;
struct udev_enumerate *en;
struct udev_list_entry *devs, *cur;
struct udev_device *device;
_udev_enumerate *en;
_udev_list_entry *devs, *cur;
_udev_device *device;
const char *name, *ret;
if (!devpath) return NULL;
udev = udev_new();
if (!udev) return NULL;
en = udev_enumerate_new(udev);
if (!en) return NULL;
if (!devpath)
return NULL;
en = udev_enumerate_new((udev));
if (!en)
return NULL;
udev_enumerate_add_match_property(en, "DEVNAME", devpath);
udev_enumerate_scan_devices(en);
devs = udev_enumerate_get_list_entry(en);
udev_list_entry_foreach(cur, devs)
{
name = udev_list_entry_get_name(cur);
device = udev_device_new_from_syspath(udev, name);
ret = eina_stringshare_add(udev_device_get_sysname(device));
udev_device_unref(device);
break; /*just in case there's more than one somehow*/
break; /*just in case there's more than one somehow */
}
udev_enumerate_unref(en);
udev_unref(udev);
return ret;
udev_enumerate_unref(en);
return ret;
}
/**
@ -290,43 +275,40 @@ eeze_udev_devpath_get_syspath(const char *devpath)
*
* @param devpath The /dev/ path of the device
* @return A const char* with the subsystem of the device or NULL on failure
*
*
* Takes "/dev/path" and returns the subsystem of the device.
*
*
* @ingroup udev
*/
EAPI const char *
eeze_udev_devpath_get_subsystem(const char *devpath)
{
struct udev *udev;
struct udev_enumerate *en;
struct udev_list_entry *devs, *cur;
struct udev_device *device;
_udev_enumerate *en;
_udev_list_entry *devs, *cur;
_udev_device *device;
const char *name, *ret;
if (!devpath) return NULL;
udev = udev_new();
if (!udev) return NULL;
en = udev_enumerate_new(udev);
if (!en) return NULL;
if (!devpath)
return NULL;
en = udev_enumerate_new((udev));
if (!en)
return NULL;
udev_enumerate_add_match_property(en, "DEVNAME", devpath);
udev_enumerate_scan_devices(en);
devs = udev_enumerate_get_list_entry(en);
udev_list_entry_foreach(cur, devs)
{
name = udev_list_entry_get_name(cur);
device = udev_device_new_from_syspath(udev, name);
ret = eina_stringshare_add(udev_device_get_subsystem(device));
udev_device_unref(device);
break; /*just in case there's more than one somehow*/
break; /*just in case there's more than one somehow */
}
udev_enumerate_unref(en);
udev_unref(udev);
return ret;
udev_enumerate_unref(en);
return ret;
}
/**
@ -334,46 +316,48 @@ eeze_udev_devpath_get_subsystem(const char *devpath)
*
* @param syspath The /sys/ path with or without the /sys/
* @return If true, the device is a mouse
*
*
* @ingroup udev
*/
EAPI Eina_Bool
eeze_udev_syspath_is_mouse(const char *syspath)
{
struct udev *udev;
struct udev_device *device;
Eina_Bool mouse = 0;
Eina_Strbuf *sbuf;
const char *test = NULL;
_udev_device *device;
Eina_Bool mouse = 0;
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);
if (!syspath)
return 0;
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
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));
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
mouse = _walk_parents_test_attr(device, "bInterfaceProtocol", "02");
if (!mouse)
{
test = udev_device_get_property_value(device, "ID_CLASS");
if ((test) && (!strcmp(test, "mouse")))
mouse = 1;
}
mouse = _walk_parents_test_attr(device, "bInterfaceProtocol", "02");
if (!mouse)
{
test = udev_device_get_property_value(device, "ID_CLASS");
if ((test) && (!strcmp(test, "mouse")))
mouse = 1;
}
#else
test = udev_device_get_property_value(device, "ID_INPUT_MOUSE");
if (test) mouse = atoi(test);
test = udev_device_get_property_value(device, "ID_INPUT_MOUSE");
if (test)
mouse = atoi(test);
#endif
udev_device_unref(device);
udev_unref(udev);
eina_strbuf_free(sbuf);
return mouse;
udev_device_unref(device);
eina_strbuf_free(sbuf);
return mouse;
}
/**
@ -381,46 +365,48 @@ eeze_udev_syspath_is_mouse(const char *syspath)
*
* @param syspath The /sys/ path with or without the /sys/
* @return If true, the device is a keyboard
*
*
* @ingroup udev
*/
EAPI Eina_Bool
eeze_udev_syspath_is_kbd(const char *syspath)
{
struct udev *udev;
struct udev_device *device;
Eina_Bool kbd = 0;
Eina_Strbuf *sbuf;
const char *test = NULL;
_udev_device *device;
Eina_Bool kbd = 0;
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);
if (!syspath)
return 0;
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
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));
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
kbd = _walk_parents_test_attr(device, "bInterfaceProtocol", "01");
if (!kbd)
{
test = udev_device_get_property_value(device, "ID_CLASS");
if ((test) && (!strcmp(test, "kbd")))
kbd = 1;
}
#else
test = udev_device_get_property_value(device, "ID_INPUT_KEYBOARD");
if (test) kbd = atoi(test);
kbd = _walk_parents_test_attr(device, "bInterfaceProtocol", "01");
if (!kbd)
{
test = udev_device_get_property_value(device, "ID_CLASS");
if ((test) && (!strcmp(test, "kbd")))
kbd = 1;
}
#else
test = udev_device_get_property_value(device, "ID_INPUT_KEYBOARD");
if (test)
kbd = atoi(test);
#endif
udev_device_unref(device);
udev_unref(udev);
eina_strbuf_free(sbuf);
return kbd;
udev_device_unref(device);
eina_strbuf_free(sbuf);
return kbd;
}
/**
@ -428,37 +414,37 @@ eeze_udev_syspath_is_kbd(const char *syspath)
*
* @param syspath The /sys/ path with or without the /sys/
* @return If true, the device is a touchpad
*
*
* @ingroup udev
*/
EAPI Eina_Bool
eeze_udev_syspath_is_touchpad(const char *syspath)
{
struct udev *udev;
struct udev_device *device;
Eina_Bool touchpad = 0;
Eina_Strbuf *sbuf;
_udev_device *device;
Eina_Bool touchpad = 0;
Eina_Strbuf *sbuf;
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);
if (!syspath)
return 0;
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
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));
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
touchpad = _walk_parents_test_attr(device, "resolution", NULL);
touchpad = _walk_parents_test_attr(device, "resolution", NULL);
#else
const char *test;
test = udev_device_get_property_value(device, "ID_INPUT_TOUCHPAD");
if (test) touchpad = atoi(test);
#endif
udev_device_unref(device);
udev_unref(udev);
eina_strbuf_free(sbuf);
const char *test;
test = udev_device_get_property_value(device, "ID_INPUT_TOUCHPAD");
return touchpad;
if (test)
touchpad = atoi(test);
#endif
udev_device_unref(device);
eina_strbuf_free(sbuf);
return touchpad;
}

View File

@ -5,6 +5,7 @@
#include "eeze_udev_private.h"
#include <Eeze_Udev.h>
extern _udev *udev;
/**
* Returns a list of all syspaths that are (or should be) the same
@ -18,68 +19,67 @@
EAPI Eina_List *
eeze_udev_find_similar_from_syspath(const char *syspath)
{
struct udev *udev;
struct udev_device *device;
struct udev_list_entry *devs, *cur;
struct udev_enumerate *en;
_udev_device *device;
_udev_list_entry *devs, *cur;
_udev_enumerate *en;
Eina_List *l, *ret = NULL;
Eina_Strbuf *sbuf;
const char *vendor, *model, *revision, *devname, *dev;
if (!syspath) return NULL;
udev = udev_new();
if (!udev) return NULL;
en = udev_enumerate_new(udev);
if (!syspath)
return NULL;
en = udev_enumerate_new((udev));
if (!en)
{
udev_unref(udev);
return NULL;
}
return NULL;
sbuf = eina_strbuf_new();
if (!strstr(syspath, "/sys/"))
eina_strbuf_append(sbuf, "/sys/");
eina_strbuf_append(sbuf, syspath);
eina_strbuf_append(sbuf, syspath);
device = udev_device_new_from_syspath(udev, syspath);
vendor = udev_device_get_property_value(device, "ID_VENDOR_ID");
if (vendor)
udev_enumerate_add_match_property(en, "ID_VENDOR_ID", vendor);
model = udev_device_get_property_value(device, "ID_MODEL_ID");
if (model)
udev_enumerate_add_match_property(en, "ID_MODEL_ID", model);
revision = udev_device_get_property_value(device, "ID_REVISION");
if (revision)
udev_enumerate_add_match_property(en, "ID_REVISION", revision);
udev_enumerate_scan_devices(en);
udev_device_unref(device);
devs = udev_enumerate_get_list_entry(en);
udev_list_entry_foreach(cur, devs)
{
devname = udev_list_entry_get_name(cur);
/* verify unlisted device */
EINA_LIST_FOREACH(ret, l, dev)
if (!strcmp(dev, devname))
continue;
/* verify unlisted device */
EINA_LIST_FOREACH(ret, l, dev) if (!strcmp(dev, devname))
continue;
ret = eina_list_prepend(ret, eina_stringshare_add(devname));
device = udev_device_new_from_syspath(udev, devname);
/* only device roots have this sysattr,
* and we only need to check parents of the roots
*/
/* only device roots have this sysattr,
* and we only need to check parents of the roots
*/
if (udev_device_get_sysattr_value(device, "idVendor"))
_get_unlisted_parents(ret, device);
_get_unlisted_parents(ret, device);
udev_device_unref(device);
}
}
udev_enumerate_unref(en);
udev_unref(udev);
eina_strbuf_free(sbuf);
return ret;
}
@ -95,42 +95,43 @@ eeze_udev_find_similar_from_syspath(const char *syspath)
* @ingroup udev
*/
EAPI void
eeze_udev_find_unlisted_similar(Eina_List *list)
eeze_udev_find_unlisted_similar(Eina_List * list)
{
struct udev *udev;
struct udev_device *device;
struct udev_list_entry *devs, *cur;
struct udev_enumerate *en;
_udev_device *device;
_udev_list_entry *devs, *cur;
_udev_enumerate *en;
Eina_List *l;
const char *vendor, *model, *revision, *devname, *dev;
if (!list) return;
udev = udev_new();
if (!udev) return;
if (!list)
return;
EINA_LIST_FOREACH(list, l, dev)
{
en = udev_enumerate_new(udev);
if (!en)
{
udev_unref(udev);
return;
}
en = udev_enumerate_new((udev));
if (!en)
return;
device = udev_device_new_from_syspath(udev, dev);
if ((vendor = udev_device_get_property_value(device, "ID_VENDOR_ID")))
udev_enumerate_add_match_property(en, "ID_VENDOR_ID", vendor);
else if ((vendor = udev_device_get_property_value(device, "ID_VENDOR")))
udev_enumerate_add_match_property(en, "ID_VENDOR", vendor);
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);
else if ((model = udev_device_get_property_value(device, "ID_MODEL")))
udev_enumerate_add_match_property(en, "ID_MODEL", model);
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);
udev_device_unref(device);
devs = udev_enumerate_get_list_entry(en);
udev_list_entry_foreach(cur, devs)
{
@ -144,11 +145,9 @@ eeze_udev_find_unlisted_similar(Eina_List *list)
_get_unlisted_parents(list, device);
udev_device_unref(device);
}
}
udev_enumerate_unref(en);
}
udev_unref(udev);
return;
}
@ -158,7 +157,7 @@ eeze_udev_find_unlisted_similar(Eina_List *list)
* @param type A Eeze_Udev_Type or 0
* @param name A filter for the device name or NULL
* @return A Eina_List* of matched devices or NULL on failure
*
*
* Return a list of syspaths (/sys/$syspath) for matching udev devices.
*
* @ingroup udev
@ -166,19 +165,19 @@ eeze_udev_find_unlisted_similar(Eina_List *list)
EAPI Eina_List *
eeze_udev_find_by_type(const Eeze_Udev_Type etype, const char *name)
{
struct udev *udev;
struct udev_enumerate *en;
struct udev_list_entry *devs, *cur;
struct udev_device *device, *parent;
_udev_enumerate *en;
_udev_list_entry *devs, *cur;
_udev_device *device, *parent;
const char *devname, *test;
Eina_List *ret = NULL;
if ((!etype) && (!name)) return NULL;
if ((!etype) && (!name))
return NULL;
udev = udev_new();
if (!udev) return NULL;
en = udev_enumerate_new(udev);
if (!en) return NULL;
en = udev_enumerate_new((udev));
if (!en)
return NULL;
switch (etype)
{
@ -236,67 +235,68 @@ eeze_udev_find_by_type(const Eeze_Udev_Type etype, const char *name)
case EEZE_UDEV_TYPE_IS_IT_HOT_OR_IS_IT_COLD_SENSOR:
udev_enumerate_add_match_subsystem(en, "hwmon");
break;
/*
case EEZE_UDEV_TYPE_ANDROID:
udev_enumerate_add_match_subsystem(en, "block");
udev_enumerate_add_match_property(en, "ID_MODEL", "Android_*");
break;
*/
/*
case EEZE_UDEV_TYPE_ANDROID:
udev_enumerate_add_match_subsystem(en, "block");
udev_enumerate_add_match_property(en, "ID_MODEL", "Android_*");
break;
*/
default:
break;
}
udev_enumerate_scan_devices(en);
devs = udev_enumerate_get_list_entry(en);
udev_list_entry_foreach(cur, devs)
{
devname = udev_list_entry_get_name(cur);
device = udev_device_new_from_syspath(udev, devname);
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_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")))
{
devname = NULL;
for (parent = udev_device_get_parent(device); parent; parent = udev_device_get_parent(parent))/*check for parent*/
if (((test = udev_device_get_sysattr_value(parent, "temp1_input"))))
{
devname = udev_device_get_syspath(parent);
break;
}
{ /* ensure that temp input exists somewhere in this device chain */
if (!_walk_parents_test_attr(device, "temp1_input", NULL))
goto out;
if (!devname)
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")))
{
devname = NULL;
for (parent = udev_device_get_parent(device); parent; parent = udev_device_get_parent(parent)) /*check for parent */
if (((test = udev_device_get_sysattr_value(parent, "temp1_input"))))
{
devname = udev_device_get_syspath(parent);
break;
}
if (!devname)
goto out;
}
}
else if (etype == EEZE_UDEV_TYPE_DRIVE_INTERNAL)
{
if (udev_device_get_property_value(device, "ID_USB_DRIVER"))
goto out;
}
else if (etype == EEZE_UDEV_TYPE_DRIVE_REMOVABLE)
{
if (!(test = udev_device_get_property_value(device, "ID_USB_DRIVER")))
goto out;
}
else
if (etype == EEZE_UDEV_TYPE_DRIVE_INTERNAL)
{
if (udev_device_get_property_value(device, "ID_USB_DRIVER"))
goto out;
}
else
if (etype == EEZE_UDEV_TYPE_DRIVE_REMOVABLE)
{
if (!
(test = udev_device_get_property_value(device, "ID_USB_DRIVER")))
goto out;
}
if (name)
if (!strstr(devname, name))
goto out;
if (!strstr(devname, name))
goto out;
ret = eina_list_append(ret, eina_stringshare_add(devname));
out:
udev_device_unref(device);
}
udev_enumerate_unref(en);
udev_unref(udev);
return ret;
}
udev_enumerate_unref(en);
return ret;
}
/**
@ -306,28 +306,29 @@ out:
* @param type "ID_INPUT_KEY", "ID_INPUT_MOUSE", "ID_INPUT_TOUCHPAD", NULL, etc
* @param name A filter for the device name, or NULL
* @return A Eina_List* of matched devices or NULL on failure
*
*
* Return a list of syspaths (/sys/$syspath) for matching udev devices.
* Requires at least one filter.
*
* @ingroup udev
*/
EAPI Eina_List *
eeze_udev_find_by_filter(const char *subsystem, const char *type, const char *name)
eeze_udev_find_by_filter(const char *subsystem, const char *type,
const char *name)
{
struct udev *udev;
struct udev_enumerate *en;
struct udev_list_entry *devs, *cur;
struct udev_device *device;
_udev_enumerate *en;
_udev_list_entry *devs, *cur;
_udev_device *device;
const char *devname;
Eina_List *ret = NULL;
if ((!subsystem) && (!type) && (!name)) return NULL;
if ((!subsystem) && (!type) && (!name))
return NULL;
udev = udev_new();
if (!udev) return NULL;
en = udev_enumerate_new(udev);
if (!en) return NULL;
en = udev_enumerate_new((udev));
if (!en)
return NULL;
if (subsystem)
udev_enumerate_add_match_subsystem(en, subsystem);
@ -335,67 +336,58 @@ eeze_udev_find_by_filter(const char *subsystem, const char *type, const char *na
udev_enumerate_add_match_property(en, type, "1");
udev_enumerate_scan_devices(en);
devs = udev_enumerate_get_list_entry(en);
udev_list_entry_foreach(cur, devs)
{
devname = udev_list_entry_get_name(cur);
device = udev_device_new_from_syspath(udev, devname);
if (name)
if (!strstr(devname,name))
goto out;
if (!strstr(devname, name))
goto out;
ret = eina_list_append(ret, eina_stringshare_add(devname));
out:
udev_device_unref(device);
}
udev_enumerate_unref(en);
udev_unref(udev);
return ret;
}
udev_enumerate_unref(en);
return ret;
}
/**
* Find a list of devices by a sysattr (and, optionally, a value of that sysattr).
*
*
* @param sysattr The attribute to find
* @param value Optional: the value that the attribute should have
*
*
* @return A list of the devices found with the attribute
*/
EAPI Eina_List *
eeze_udev_find_by_sysattr(const char *sysattr, const char *value)
{
struct udev *udev;
struct udev_enumerate *en;
struct udev_list_entry *devs, *cur;
struct udev_device *device;
_udev_enumerate *en;
_udev_list_entry *devs, *cur;
_udev_device *device;
const char *devname;
Eina_List *ret = NULL;
if (!sysattr) return NULL;
if (!sysattr)
return NULL;
udev = udev_new();
if (!udev) return NULL;
en = udev_enumerate_new(udev);
if (!en) return NULL;
en = udev_enumerate_new((udev));
if (!en)
return NULL;
udev_enumerate_add_match_sysattr(en, sysattr, value);
udev_enumerate_scan_devices(en);
devs = udev_enumerate_get_list_entry(en);
udev_list_entry_foreach(cur, devs)
{
devname = udev_list_entry_get_name(cur);
device = udev_device_new_from_syspath(udev, devname);
ret = eina_list_append(ret, eina_stringshare_add(devname));
udev_device_unref(device);
}
udev_enumerate_unref(en);
udev_unref(udev);
return ret;
}
udev_enumerate_unref(en);
return ret;
}

View File

@ -1,44 +1,56 @@
#include "eeze_udev_private.h"
#include <Eeze_Udev.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
int _e_eeze_udev_log_dom = -1;
int _e_eeze_udev_init_count = 0;
#include <Eeze_Udev.h>
#include "eeze_udev_private.h"
_udev *udev;
int _eeze_udev_log_dom = -1;
int _eeze_udev_init_count = 0;
EAPI int
eeze_udev_init(void)
{
if (++_e_eeze_udev_init_count != 1)
return _e_eeze_udev_init_count;
if (++_eeze_udev_init_count != 1)
return _eeze_udev_init_count;
if (!eina_init())
return --_e_eeze_udev_init_count;
return --_eeze_udev_init_count;
_e_eeze_udev_log_dom = eina_log_domain_register
("eeze_udev", E_EEZE_COLOR_DEFAULT);
if (_e_eeze_udev_log_dom < 0)
_eeze_udev_log_dom = eina_log_domain_register
("eeze_udev", eeze_COLOR_DEFAULT);
if (_eeze_udev_log_dom < 0)
{
EINA_LOG_ERR("Could not register 'eeze_udev' log domain.");
goto fail;
}
return _e_eeze_udev_init_count;
if (!((udev) = udev_new()))
{
EINA_LOG_ERR("Could not initialize udev library!");
goto fail;
}
return _eeze_udev_init_count;
fail:
eina_log_domain_unregister(_e_eeze_udev_log_dom);
_e_eeze_udev_log_dom = -1;
eina_shutdown();
return _e_eeze_udev_init_count;
eina_log_domain_unregister(_eeze_udev_log_dom);
_eeze_udev_log_dom = -1;
eina_shutdown();
return _eeze_udev_init_count;
}
EAPI int
eeze_udev_shutdown(void)
{
if (--_e_eeze_udev_init_count != 0)
return _e_eeze_udev_init_count;
if (--_eeze_udev_init_count != 0)
return _eeze_udev_init_count;
eina_log_domain_unregister(_e_eeze_udev_log_dom);
_e_eeze_udev_log_dom = -1;
udev_unref(udev);
eina_log_domain_unregister(_eeze_udev_log_dom);
_eeze_udev_log_dom = -1;
eina_shutdown();
return _e_eeze_udev_init_count;
return _eeze_udev_init_count;
}

View File

@ -5,42 +5,65 @@
#include <Eeze_Udev.h>
#include "eeze_udev_private.h"
extern _udev *udev;
/**
* copies a device
*/
_udev_device *
_copy_device(_udev_device * device)
{
const char *syspath;
if (!(syspath = udev_device_get_syspath(device)))
return NULL;
return udev_device_new_from_syspath(udev, syspath);
}
/**
* private function to simulate udevadm info -a
* walks up the device tree checking each node for sysattr
* with value $value
*/
Eina_Bool
_walk_parents_test_attr(struct udev_device *device, const char *sysattr, const char* value)
_walk_parents_test_attr(_udev_device * device, const char *sysattr,
const char *value)
{
struct udev_device *parent, *child = device;
_udev_device *parent, *child = device;
const char *test;
if ((test = udev_device_get_sysattr_value(device, sysattr)))
return 1;
parent = udev_device_get_parent(child);
for (; parent; child = parent, parent = udev_device_get_parent(child))
{
if (!(test = udev_device_get_sysattr_value(parent, sysattr)))
continue;
if (!value)
return 1;
else if (!strcmp(test, value))
return 1;
else
if (!strcmp(test, value))
return 1;
}
return 0;
}
const char *
_walk_parents_get_attr(struct udev_device *device, const char *sysattr)
_walk_parents_get_attr(_udev_device * device, const char *sysattr)
{
struct udev_device *parent, *child = device;
_udev_device *parent, *child = device;
const char *test;
if ((test = udev_device_get_sysattr_value(device, sysattr)))
return eina_stringshare_add(test);
parent = udev_device_get_parent(child);
for (; parent; child = parent, parent = udev_device_get_parent(child))
{
if ((test = udev_device_get_sysattr_value(parent, sysattr)))
@ -55,30 +78,39 @@ _walk_parents_get_attr(struct udev_device *device, const char *sysattr)
* stringshare adding all devices that are not in the list
*/
void
_get_unlisted_parents(Eina_List *list, struct udev_device *device)
_get_unlisted_parents(Eina_List * list, _udev_device * device)
{
struct udev_device *parent, *child = device;
const char *test, *devname, *vendor, *vendor2, *model, *model2;
Eina_List *l;
Eina_Bool found;
_udev_device *parent, *child = device;
const char *test, *devname, *vendor, *vendor2, *model, *model2;
Eina_List *l;
Eina_Bool found;
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;
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 (((model && model2) && (strcmp(model, model2))) ||
((vendor && vendor2) && (strcmp(vendor, vendor2))))
if ((!model2 && model) || (model2 && !model) || (!vendor2 && vendor)
|| (vendor2 && !vendor))
break;
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)
{
@ -88,8 +120,10 @@ _get_unlisted_parents(Eina_List *list, struct udev_device *device)
break;
}
}
if (!found)
list = eina_list_prepend(list, eina_stringshare_add(devname));
}
return;
}

View File

@ -1,10 +1,10 @@
#ifndef EEZE_UDEV_PRIVATE_H
#define EEZE_UDEV_PRIVATE_H
#include "Eeze_Udev.h"
#ifndef E_EEZE_COLOR_DEFAULT
#define E_EEZE_COLOR_DEFAULT EINA_COLOR_CYAN
#ifndef eeze_COLOR_DEFAULT
#define eeze_COLOR_DEFAULT EINA_COLOR_CYAN
#endif
extern int _e_eeze_udev_log_dom;
extern int _eeze_udev_log_dom;
#ifdef ERR
#undef ERR
#endif
@ -18,13 +18,20 @@ extern int _e_eeze_udev_log_dom;
#undef DBG
#endif
#define DBG(...) EINA_LOG_DOM_DBG(_e_eeze_udev_log_dom, __VA_ARGS__)
#define INFO(...) EINA_LOG_DOM_INFO(_e_eeze_udev_log_dom, __VA_ARGS__)
#define WARN(...) EINA_LOG_DOM_WARN(_e_eeze_udev_log_dom, __VA_ARGS__)
#define ERR(...) EINA_LOG_DOM_ERR(_e_eeze_udev_log_dom, __VA_ARGS__)
#define DBG(...) EINA_LOG_DOM_DBG(_eeze_udev_log_dom, __VA_ARGS__)
#define INFO(...) EINA_LOG_DOM_INFO(_eeze_udev_log_dom, __VA_ARGS__)
#define WARN(...) EINA_LOG_DOM_WARN(_eeze_udev_log_dom, __VA_ARGS__)
#define ERR(...) EINA_LOG_DOM_ERR(_eeze_udev_log_dom, __VA_ARGS__)
Eina_Bool _walk_parents_test_attr(struct udev_device *device, const char *sysattr, const char* value);
const char *_walk_parents_get_attr(struct udev_device *device, const char *sysattr);
void _get_unlisted_parents(Eina_List *list, struct udev_device *device);
typedef struct udev _udev;
typedef struct udev_list_entry _udev_list_entry;
typedef struct udev_device _udev_device;
typedef struct udev_enumerate _udev_enumerate;
typedef struct udev_monitor _udev_monitor;
Eina_Bool _walk_parents_test_attr(_udev_device *device, const char *sysattr, const char* value);
const char *_walk_parents_get_attr(_udev_device *device, const char *sysattr);
void _get_unlisted_parents(Eina_List *list, _udev_device *device);
_udev_device *_copy_device(_udev_device *device);
#endif

View File

@ -5,6 +5,8 @@
#include <Eeze_Udev.h>
#include "eeze_udev_private.h"
extern _udev *udev;
/**
* Walks up the device chain starting at @p syspath,
* checking each device for @p sysattr with (optional) @p value.
@ -16,45 +18,47 @@
* @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)
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;
_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);
if (!udev)
return 0;
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
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;
}
}
}
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;
@ -69,35 +73,36 @@ eeze_udev_walk_check_sysattr(const char *syspath, const char *sysattr, const cha
*
* @return The value of @p sysattr if found, or NULL
*/
EAPI const char*
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;
_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);
if (!syspath)
return NULL;
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
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;
}
}
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;

View File

@ -5,10 +5,12 @@
#include <Eeze_Udev.h>
#include "eeze_udev_private.h"
extern _udev *udev;
/* opaque */
struct Eeze_Udev_Watch
{
struct udev_monitor *mon;
_udev_monitor *mon;
Ecore_Fd_Handler *handler;
Eeze_Udev_Type type;
};
@ -16,195 +18,245 @@ struct Eeze_Udev_Watch
/* private */
struct _store_data
{
void(*func)(const char *, const char *, void *, Eeze_Udev_Watch *);
void (*func)(const char *, int, void *, Eeze_Udev_Watch *);
void *data;
int event;
struct udev_monitor *mon;
_udev_monitor *mon;
Eeze_Udev_Type type;
Eeze_Udev_Watch *watch;
};
/* private function to further filter watch results based on Eeze_Udev_Type
* specified; helpful for new udev versions, but absolutely required for
* old udev, which does not implement filtering in device monitors.
*/
static int
_get_syspath_from_watch(void *data, Ecore_Fd_Handler *fd_handler)
_get_syspath_from_watch(void *data, Ecore_Fd_Handler * fd_handler)
{
struct _store_data *store = data;
struct udev_device *device, *parent, *tmpdev;
_udev_device *device, *parent, *tmpdev;
const char *ret, *test;
void(*func)(const char *, const char *, void *, Eeze_Udev_Watch *) = store->func;
void (*func)(const char *, int, void *, Eeze_Udev_Watch *) = store->func;
void *sdata = store->data;
Eeze_Udev_Watch *watch = store->watch;
int cap = 0;
int cap = 0, event = 0;
if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
return 1;
device = udev_monitor_receive_device(store->mon);
if (!device) return 1;
if (!device)
return 1;
switch (store->type)
{
case EEZE_UDEV_TYPE_KEYBOARD:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
if ((!(test = udev_device_get_subsystem(device))) || (strcmp(test, "input")))
if ((!(test = udev_device_get_subsystem(device)))
|| (strcmp(test, "input")))
goto error;
test = udev_device_get_property_value(device, "ID_CLASS");
if ((_walk_parents_test_attr(device, "bInterfaceProtocol", "01")) || ((test) && (!strcmp(test, "kbd"))))
if ((_walk_parents_test_attr(device, "bInterfaceProtocol", "01"))
|| ((test) && (!strcmp(test, "kbd"))))
break;
goto error;
#endif
if (!udev_device_get_property_value(device, "ID_INPUT_KEYBOARD"))
goto error;
break;
case EEZE_UDEV_TYPE_MOUSE:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
if ((!(test = udev_device_get_subsystem(device))) || (strcmp(test, "input")))
if ((!(test = udev_device_get_subsystem(device)))
|| (strcmp(test, "input")))
goto error;
test = udev_device_get_property_value(device, "ID_CLASS");
if ((_walk_parents_test_attr(device, "bInterfaceProtocol", "02")) || ((test) && (!strcmp(test, "mouse"))))
if ((_walk_parents_test_attr(device, "bInterfaceProtocol", "02"))
|| ((test) && (!strcmp(test, "mouse"))))
break;
goto error;
#endif
if (!udev_device_get_property_value(device, "ID_INPUT_MOUSE"))
goto error;
break;
case EEZE_UDEV_TYPE_TOUCHPAD:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
if ((!(test = udev_device_get_subsystem(device))) || (strcmp(test, "input")))
if ((!(test = udev_device_get_subsystem(device)))
|| (strcmp(test, "input")))
goto error;
if (_walk_parents_test_attr(device, "resolution", NULL))
break;
goto error;
#endif
if (!udev_device_get_property_value(device, "ID_INPUT_TOUCHPAD"))
goto error;
break;
case EEZE_UDEV_TYPE_DRIVE_MOUNTABLE:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
if ((!(test = udev_device_get_subsystem(device))) || (strcmp(test, "block")))
if ((!(test = udev_device_get_subsystem(device)))
|| (strcmp(test, "block")))
goto error;
#endif
test = udev_device_get_sysattr_value(device, "capability");
if (test) cap = atoi(test);
if (test)
cap = atoi(test);
if (!(test = (udev_device_get_property_value(device, "ID_FS_USAGE"))) ||
(strcmp("filesystem", test)) || (cap == 52))
(strcmp("filesystem", test)) || (cap == 52))
goto error;
break;
case EEZE_UDEV_TYPE_DRIVE_INTERNAL:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
if ((!(test = udev_device_get_subsystem(device))) || (strcmp(test, "block")))
if ((!(test = udev_device_get_subsystem(device)))
|| (strcmp(test, "block")))
goto error;
#endif
if (!(test = udev_device_get_property_value(device, "ID_BUS")) || (strcmp("ata", test)) ||
!(test = udev_device_get_sysattr_value(device, "removable")) || (atoi(test)))
if (!(test = udev_device_get_property_value(device, "ID_BUS"))
|| (strcmp("ata", test))
|| !(test = udev_device_get_sysattr_value(device, "removable"))
|| (atoi(test)))
goto error;
break;
case EEZE_UDEV_TYPE_DRIVE_REMOVABLE:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
if ((!(test = udev_device_get_subsystem(device))) || (strcmp(test, "block")))
if ((!(test = udev_device_get_subsystem(device)))
|| (strcmp(test, "block")))
goto error;
#endif
if ((!(test = udev_device_get_sysattr_value(device, "removable")) || (!atoi(test))) &&
(!(test = udev_device_get_sysattr_value(device, "capability")) || (atoi(test) != 10)))
if ((!(test = udev_device_get_sysattr_value(device, "removable"))
|| (!atoi(test)))
&& (!(test = udev_device_get_sysattr_value(device, "capability"))
|| (atoi(test) != 10)))
goto error;
break;
case EEZE_UDEV_TYPE_DRIVE_CDROM:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
if ((!(test = udev_device_get_subsystem(device))) || (strcmp(test, "block")))
if ((!(test = udev_device_get_subsystem(device)))
|| (strcmp(test, "block")))
goto error;
#endif
if (!udev_device_get_property_value(device, "ID_CDROM"))
goto error;
break;
case EEZE_UDEV_TYPE_POWER_AC:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
if ((!(test = udev_device_get_subsystem(device))) || (strcmp(test, "power_supply")))
if ((!(test = udev_device_get_subsystem(device)))
|| (strcmp(test, "power_supply")))
goto error;
#endif
if (!(test = (udev_device_get_property_value(device, "POWER_SUPPLY_TYPE"))) ||
(strcmp("Mains", test)))
if (!(test = udev_device_get_property_value(device, "POWER_SUPPLY_TYPE"))
|| (strcmp("Mains", test)))
goto error;
break;
case EEZE_UDEV_TYPE_POWER_BAT:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
if ((!(test = udev_device_get_subsystem(device))) || (strcmp(test, "power_supply")))
if ((!(test = udev_device_get_subsystem(device)))
|| (strcmp(test, "power_supply")))
goto error;
#endif
if (!(test = (udev_device_get_property_value(device, "POWER_SUPPLY_TYPE"))) ||
(strcmp("Battery", test)))
if (!(test = udev_device_get_property_value(device, "POWER_SUPPLY_TYPE"))
|| (strcmp("Battery", test)))
goto error;
break;
case EEZE_UDEV_TYPE_IS_IT_HOT_OR_IS_IT_COLD_SENSOR:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
if ((!(test = udev_device_get_subsystem(device))) || (strcmp(test, "hwmon")))
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_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")))
{
tmpdev = NULL;
for (parent = udev_device_get_parent(device); parent; parent = udev_device_get_parent(parent))/*check for parent*/
if (((test = udev_device_get_sysattr_value(parent, "temp1_input"))))
{
tmpdev = parent;
break;
}
}
else
tmpdev = device;
if ((!tmpdev) || !(test = udev_device_get_action(device)) || (!(ret = udev_device_get_syspath(tmpdev))))
if (!_walk_parents_test_attr(device, "temp1_input", NULL))
goto error;
(*func)(eina_stringshare_add(ret), test, sdata, watch);
udev_device_unref(device);
return 1;
/* 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")))
{
for (parent = udev_device_get_parent(device); parent; parent = udev_device_get_parent(parent)) /*check for parent */
if (((test =
udev_device_get_sysattr_value(parent, "temp1_input"))))
{
tmpdev = device;
if (!(device = _copy_device(parent)))
goto error;
udev_device_unref(tmpdev);
break;
}
}
break;
/*
case EEZE_UDEV_TYPE_ANDROID:
udev_monitor_filter_add_match_subsystem_devtype(mon, "input", "usb_interface");
break;
*/
default:
break;
}
if ((!(test = udev_device_get_action(device))) || (!(ret = udev_device_get_syspath(device))))
if ((!(test = udev_device_get_action(device)))
|| (!(ret = udev_device_get_syspath(device))))
goto error;
if (store->event)
{
if (!strcmp(test, "add"))
if (!strcmp(test, "add"))
{
if ((store->event & EEZE_UDEV_EVENT_ADD) != EEZE_UDEV_EVENT_ADD)
goto error;
event |= EEZE_UDEV_EVENT_ADD;
}
else
if (!strcmp(test, "remove"))
{
if ((store->event & ~EEZE_UDEV_EVENT_ADD))
goto error;
}
else if (!strcmp(test, "remove"))
{
if ((store->event & ~EEZE_UDEV_EVENT_REMOVE))
goto error;
}
else if (!strcmp(test, "change"))
{
if ((store->event & ~EEZE_UDEV_EVENT_CHANGE))
goto error;
}
else if (!strcmp(test, "online"))
{
if ((store->event & ~EEZE_UDEV_EVENT_ONLINE))
goto error;
if ((store->event & EEZE_UDEV_EVENT_REMOVE) !=
EEZE_UDEV_EVENT_REMOVE)
goto error;
event |= EEZE_UDEV_EVENT_REMOVE;
}
else
{
if ((store->event & ~EEZE_UDEV_EVENT_OFFLINE))
goto error;
}
if (!strcmp(test, "change"))
{
if ((store->event & EEZE_UDEV_EVENT_CHANGE) !=
EEZE_UDEV_EVENT_CHANGE)
goto error;
event |= EEZE_UDEV_EVENT_CHANGE;
}
else
if (!strcmp(test, "online"))
{
if ((store->event & EEZE_UDEV_EVENT_ONLINE) !=
EEZE_UDEV_EVENT_ONLINE)
goto error;
event |= EEZE_UDEV_EVENT_ONLINE;
}
else
{
if ((store->event & EEZE_UDEV_EVENT_OFFLINE) !=
EEZE_UDEV_EVENT_OFFLINE)
goto error;
event |= EEZE_UDEV_EVENT_OFFLINE;
}
}
(*func)(eina_stringshare_add(ret), eina_stringshare_add(test), sdata, watch);
(*func)(eina_stringshare_add(ret), event, sdata, watch);
error:
udev_device_unref(device);
return 1;
@ -219,28 +271,31 @@ error:
* @param user_data Data to pass to the callback function
*
* @return A watch struct for the watch type specified, or NULL on failure
*
*
* @ingroup udev
*/
EAPI Eeze_Udev_Watch *
eeze_udev_watch_add(Eeze_Udev_Type type, int event, void(*func)(const char *syspath, const char *event, void *data, Eeze_Udev_Watch *watch), void *user_data)
eeze_udev_watch_add(Eeze_Udev_Type type, int event,
void (*func)(const char *syspath, int event, void *data,
Eeze_Udev_Watch * watch), void *user_data)
{
struct udev *udev;
struct udev_monitor *mon;
_udev_monitor *mon;
int fd;
Ecore_Fd_Handler *handler;
Eeze_Udev_Watch *watch;
struct _store_data *store;
if (!(store = calloc(sizeof(struct _store_data), 1))) return NULL;
if (!(store = calloc(sizeof(struct _store_data), 1)))
return NULL;
if (!(watch = malloc(sizeof(Eeze_Udev_Watch))))
goto error;
if (!(udev = udev_new()))
goto error;
if (!(mon = udev_monitor_new_from_netlink(udev, "udev")))
goto error;
#ifndef OLD_UDEV_RRRRRRRRRRRRRR
switch (type)
{
case EEZE_UDEV_TYPE_KEYBOARD:
@ -266,23 +321,26 @@ eeze_udev_watch_add(Eeze_Udev_Type type, int event, void(*func)(const char *sysp
break;
case EEZE_UDEV_TYPE_POWER_AC:
case EEZE_UDEV_TYPE_POWER_BAT:
udev_monitor_filter_add_match_subsystem_devtype(mon, "power_supply", NULL);
udev_monitor_filter_add_match_subsystem_devtype(mon, "power_supply",
NULL);
break;
case EEZE_UDEV_TYPE_IS_IT_HOT_OR_IS_IT_COLD_SENSOR:
udev_monitor_filter_add_match_subsystem_devtype(mon, "hwmon", NULL);
break;
/*
case EEZE_UDEV_TYPE_ANDROID:
udev_monitor_filter_add_match_subsystem_devtype(mon, "input", "usb_interface");
break;
*/
/*
case EEZE_UDEV_TYPE_ANDROID:
udev_monitor_filter_add_match_subsystem_devtype(mon, "input", "usb_interface");
break;
*/
default:
break;
}
#endif
if (udev_monitor_enable_receiving(mon))
goto error;
fd = udev_monitor_get_fd(mon);
store->func = func;
store->data = user_data;
@ -290,19 +348,19 @@ eeze_udev_watch_add(Eeze_Udev_Type type, int event, void(*func)(const char *sysp
store->type = type;
store->watch = watch;
store->event = event;
if (!(handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, _get_syspath_from_watch, store, NULL, NULL)))
if (!(handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ,
_get_syspath_from_watch, store, NULL, NULL)))
goto error;
watch->mon = mon;
watch->handler = handler;
return watch;
error:
free(store);
free(watch);
udev_monitor_unref(mon);
udev_unref(udev);
return NULL;
free(store);
free(watch);
udev_monitor_unref(mon);
return NULL;
}
/**
@ -316,24 +374,23 @@ error:
* @ingroup udev
*/
EAPI void *
eeze_udev_watch_del(Eeze_Udev_Watch *watch)
eeze_udev_watch_del(Eeze_Udev_Watch * watch)
{
struct udev *udev;
struct _store_data *sdata;
void *ret;
if ((!watch) || (!watch->mon) || (!watch->handler)) return NULL;
if ((!watch) || (!watch->mon) || (!watch->handler))
return NULL;
udev = udev_monitor_get_udev(watch->mon);
udev_monitor_unref(watch->mon);
udev_unref(udev);
sdata = ecore_main_fd_handler_del(watch->handler);
if (sdata)
{
ret = sdata->data;
free(sdata);
}
free(watch);
free(watch);
return ret;
}