aboutsummaryrefslogtreecommitdiffstats
path: root/src/modules/imfos/imfos_devices.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/imfos/imfos_devices.c')
-rw-r--r--src/modules/imfos/imfos_devices.c290
1 files changed, 290 insertions, 0 deletions
diff --git a/src/modules/imfos/imfos_devices.c b/src/modules/imfos/imfos_devices.c
new file mode 100644
index 000000000..5f7b46052
--- /dev/null
+++ b/src/modules/imfos/imfos_devices.c
@@ -0,0 +1,290 @@
+#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;
+}