enlightenment/src/modules/imfos/imfos_devices.c

291 lines
6.9 KiB
C

#include "e_mod_main.h"
#include "imfos_devices.h"
#include "imfos_v4l.h"
#include <Eeze.h>
static Imfos_Device *_imfos_devices_add(const char *syspath, int type);
static void _imfos_devices_del(Imfos_Device *dev);
static void _imfos_devices_eeze_events(const char *syspath, Eeze_Udev_Event ev, void *data, Eeze_Udev_Watch *watch);
static Eina_List *_delayed_jobs = NULL;
static Eeze_Udev_Watch *_eeze_watcher = NULL;
static Imfos_Device *
_imfos_devices_new(const char *syspath)
{
Imfos_Device *dev;
dev = calloc(1, sizeof(Imfos_Device));
dev->syspath = eina_stringshare_ref(syspath);
dev->name = eeze_udev_syspath_get_sysattr(syspath, "name");
dev->dev_name = eeze_udev_syspath_get_property(syspath, "DEVNAME");
printf("New device %s(%s)\n", dev->name, dev->dev_name);
return dev;
}
static void
_imfos_devices_del(Imfos_Device *dev)
{
eina_stringshare_del(dev->syspath);
eina_stringshare_del(dev->name);
eina_stringshare_del(dev->dev_name);
free(dev);
}
static Eina_Bool
_imfos_devices_check_capabilities(const char *syspath, const char *dev_name)
{
/* TODO check capacities */
return EINA_TRUE;
}
static Imfos_Device *
_imfos_devices_add(const char *syspath, int type)
{
Eina_List *l;
Imfos_Device *dev;
const char *name;
const char *dev_name;
name = eeze_udev_syspath_get_sysattr(syspath, "name");
dev_name = eeze_udev_syspath_get_property(syspath, "DEVNAME");
printf("New device %s(%s) know(%d)\n", name, dev_name, eina_list_count(imfos_config->devices));
EINA_LIST_FOREACH(imfos_config->devices, l, dev)
{
if (dev->name == name)
{
printf("Found by name %s\n");
break;
}
}
if (dev)
{
printf("Updating device %s\n", name);
dev->syspath = eina_stringshare_ref(syspath);
dev->dev_name = dev_name;
dev->type = type;
eina_stringshare_del(name);
}
else
{
if (_imfos_devices_check_capabilities(syspath, dev_name))
{
printf("First time\n");
dev = calloc(1, sizeof(Imfos_Device));
dev->syspath = eina_stringshare_ref(syspath);
dev->name = name;
dev->type = type;
dev->dev_name = dev_name;
imfos_config->devices =
eina_list_append(imfos_config->devices, dev);
}
else
{
eina_stringshare_del(name);
eina_stringshare_del(dev_name);
}
}
return dev;
}
static void
_imfos_device_remove(Imfos_Device *dev)
{
eina_stringshare_del(dev->syspath);
dev->syspath = NULL;
if (!dev->dev_name_locked)
{
eina_stringshare_del(dev->dev_name);
dev->dev_name = NULL;
}
if (dev->thread) ecore_thread_cancel(dev->thread);
}
static void
_imfos_devices_eeze_events(const char *syspath, Eeze_Udev_Event ev,
void *data EINA_UNUSED,
Eeze_Udev_Watch *watch EINA_UNUSED)
{
Imfos_Device *dev;
Eina_List *l;
if (ev == EEZE_UDEV_EVENT_ADD)
{
dev = _imfos_devices_add(syspath, EEZE_UDEV_TYPE_V4L);
}
else if (ev == EEZE_UDEV_EVENT_REMOVE)
{
EINA_LIST_FOREACH(imfos_config->devices, l, dev)
{
if (dev->syspath == syspath)
{
_imfos_device_remove(dev);
break;
}
}
}
}
void
imfos_devices_init(void)
{
Eina_List *devices;
const char *syspath;
devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_V4L, NULL);
EINA_LIST_FREE(devices, syspath)
{
_imfos_devices_add(syspath, EEZE_UDEV_TYPE_V4L);
eina_stringshare_del(syspath);
}
/*
devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_KEYBOARD, NULL);
devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_MOUSE, NULL);
devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_NET, NULL);
*/
devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_BLUETOOTH, NULL);
EINA_LIST_FREE(devices, syspath)
{
_imfos_devices_add(syspath, EEZE_UDEV_TYPE_BLUETOOTH);
eina_stringshare_del(syspath);
}
devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_DRIVE_REMOVABLE, NULL);
EINA_LIST_FREE(devices, syspath)
{
_imfos_devices_add(syspath, EEZE_UDEV_TYPE_DRIVE_REMOVABLE);
eina_stringshare_del(syspath);
}
devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_V4L, NULL);
_eeze_watcher = eeze_udev_watch_add(EEZE_UDEV_TYPE_V4L,
(EEZE_UDEV_EVENT_ADD | EEZE_UDEV_EVENT_REMOVE),
_imfos_devices_eeze_events, NULL);
}
void
imfos_devices_shutdown(void)
{
Imfos_Device *dev;
eeze_udev_watch_del(_eeze_watcher);
}
Eina_Bool
imfos_devices_timeout(Imfos_Device *dev)
{
double loop_time;
if (dev->timeout > 0)
{
loop_time = ecore_time_get() - dev->time_start;
if (loop_time > dev->timeout)
{
printf("timeout\n");
return EINA_TRUE;
}
}
return ecore_thread_check(dev->thread);
}
static void
_imfos_devices_thread_run(void *data, Ecore_Thread *thread)
{
Imfos_Device *dev;
dev = data;
dev->catched = EINA_FALSE;
dev->time_start = ecore_time_get();
imfos_v4l_run(dev);
}
static void
_imfos_device_run(void)
{
Eina_List *l;
Imfos_Device *dev;
EINA_LIST_FOREACH(_delayed_jobs, l, dev)
{
if (!dev->thread)
{
imfos_devices_run(dev);
_delayed_jobs = eina_list_remove_list(_delayed_jobs, l);
break;
}
}
}
static void
_imfos_devices_thread_clean(void *data, Ecore_Thread *thread)
{
Imfos_Device *dev;
double catch_time;
dev = data;
printf("Imfos thread End\n");
if (dev->catched)
{
catch_time = dev->time_start - ecore_time_get();
dev->catch_time_average =
((dev->catch_time_average * dev->catch_count) + catch_time)
/ (dev->catch_count + 1);
++dev->catch_count;
}
imfos_v4l_clean(dev);
dev->thread = NULL;
_imfos_device_run();
}
static void
_imfos_devices_thread_cancel(void *data, Ecore_Thread *thread)
{
printf("Imfos thread cancel\n");
}
Eina_Bool
imfos_devices_run(Imfos_Device *dev)
{
Ecore_Thread *thread;
if (dev->thread)
{
ecore_thread_cancel(dev->thread);
if (!dev->async)
{
_delayed_jobs = eina_list_append(_delayed_jobs, dev);
return EINA_TRUE;
}
}
dev->thread = ecore_thread_run(_imfos_devices_thread_run,
_imfos_devices_thread_clean,
_imfos_devices_thread_clean,
dev);
return EINA_FALSE;
}
Eina_Bool
imfos_devices_cancel(Imfos_Device *dev)
{
if (dev->thread)
{
ecore_thread_cancel(dev->thread);
return EINA_TRUE;
}
return EINA_FALSE;
}