Compare commits

...

3 Commits

Author SHA1 Message Date
Michaël Bouchaud (yoz) a128042fce Imfos: In the end I will not keep this name. The project became bigger.
Now the modules take a new turn. The new goal of this module is to track
human activity and environments.
2016-09-05 03:39:46 +02:00
Michaël Bouchaud (yoz) e94857af3a Introduce a new module to detect your presence in front of the screen.
It's a first step but I need to rework the screensaver policy in enlightenment
to launch the webcam just before the screensaver. We need to get enough time
to detect your head and cancel the screensaver. The panel config setting need
some love too, but it's more trivial.

@feature
2016-08-10 19:20:54 +02:00
Michaël Bouchaud (yoz) 11b027a5d1 e_screensaver: allow the cancel of the screensaver on X 2016-08-10 19:20:54 +02:00
15 changed files with 1206 additions and 0 deletions

View File

@ -41,6 +41,7 @@ AC_USE_SYSTEM_EXTENSIONS
AC_PROG_MKDIR_P
AC_C_BIGENDIAN
AC_PROG_CC_C99
AC_PROG_CXX
AM_PROG_CC_C_O
AC_FUNC_ALLOCA
@ -811,6 +812,13 @@ define([CHECK_MODULE_WL_WEEKEYBOARD],
])
AM_CONDITIONAL([HAVE_WL_WEEKEYBOARD], [test "x${WL_WEEKEYBOARD}" = "xtrue"])
AM_CONDITIONAL(HAVE_IMFOS, false)
define([CHECK_MODULE_IMFOS],
[
AC_E_CHECK_PKG(IMFOS, [ libv4l2 opencv ], [], [])
])
AC_E_OPTIONAL_MODULE([ibar], true)
AC_E_OPTIONAL_MODULE([clock], true)
AC_E_OPTIONAL_MODULE([pager], true)
@ -871,6 +879,7 @@ AC_E_OPTIONAL_MODULE([geolocation], true)
AC_E_OPTIONAL_MODULE([xwayland], $have_wayland_dep, [CHECK_MODULE_XWAYLAND])
AC_E_OPTIONAL_MODULE([wireless], true)
AC_E_OPTIONAL_MODULE([time], true)
AC_E_OPTIONAL_MODULE([imfos], true, [CHECK_MODULE_IMFOS])
if test "x${HAVE_WL_X11}" != "xyes" && test "x${have_wayland}" = "xyes" && test "x${HAVE_XWAYLAND}" != "xyes"; then
AC_DEFINE_UNQUOTED([HAVE_WAYLAND_ONLY],[1],[enable wayland-only version of enlightenment])
@ -1082,6 +1091,7 @@ src/modules/packagekit/module.desktop
src/modules/wl_desktop_shell/module.desktop
src/modules/wireless/module.desktop
src/modules/time/module.desktop
src/modules/imfos/module.desktop
data/xsession/enlightenment.desktop
data/etc/sysactions.conf
data/units/enlightenment.service

View File

@ -547,6 +547,8 @@ e_screensaver_notidle(void)
}
else if (_e_screensaver_timeout)
_e_screensaver_timer = ecore_timer_add(_e_screensaver_timeout, _e_screensaver_idle_timeout_cb, (void*)1);
#else
ecore_x_screensaver_reset();
#endif
}

View File

@ -130,3 +130,5 @@ include src/modules/Makefile_geolocation.mk
include src/modules/Makefile_wireless.mk
include src/modules/Makefile_time.mk
include src/modules/Makefile_imfos.mk

26
src/modules/Makefile_imfos.mk Executable file
View File

@ -0,0 +1,26 @@
EXTRA_DIST += src/modules/imfos/module.desktop.in
if USE_MODULE_IMFOS
imfosdir = $(MDIR)/imfos
imfos_DATA = src/modules/imfos/module.desktop
imfospkgdir = $(MDIR)/imfos/$(MODULE_ARCH)
imfospkg_LTLIBRARIES = src/modules/imfos/module.la
src_modules_imfos_module_la_LIBADD = $(MOD_LIBS) @IMFOS_LIBS@
src_modules_imfos_module_la_CPPFLAGS = $(MOD_CPPFLAGS) @IMFOS_CFLAGS@
src_modules_imfos_module_la_LDFLAGS = $(MOD_LDFLAGS)
src_modules_imfos_module_la_SOURCES = src/modules/imfos/e_mod_main.h \
src/modules/imfos/e_mod_main.c \
src/modules/imfos/e_mod_config.c \
src/modules/imfos/imfos_devices.c \
src/modules/imfos/imfos_devices.h \
src/modules/imfos/imfos_v4l.c \
src/modules/imfos/imfos_v4l.h \
src/modules/imfos/imfos_face.cpp \
src/modules/imfos/imfos_face.h
PHONIES += imfos install-imfos
imfos: $(imfospkg_LTLIBRARIES) $(imfos_DATA)
install-imfos: install-imfosDATA install-imfospkgLTLIBRARIES
endif

238
src/modules/imfos/e_mod_config.c Executable file
View File

@ -0,0 +1,238 @@
#include <e.h>
#include <Eeze.h>
#include "e_mod_main.h"
#include "imfos_devices.h"
typedef struct _Imfos_Config_Panel
{
Evas_Object *main;
Evas_Object *current;
Imfos_Device *dev;
Imfos_Device *config;
} Imfos_Config_Panel;
static void _v4l_create(void);
static void _device_create(void);
static void *_create_data(E_Config_Dialog *cfd);
static void _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
static void _fill_data(E_Config_Dialog_Data *cfdata);
static Evas_Object *_basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
static int _apply(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
Imfos_Config_Panel *_tmp_cfg = NULL;
static Evas_Object *_imfos_cam_widget = NULL;
int flipped = EINA_FALSE;
EAPI E_Config_Dialog *
e_mod_config_imfos(Evas_Object *parent, const char *params EINA_UNUSED)
{
E_Config_Dialog *cfd = NULL;
E_Config_Dialog_View *v = NULL;
char buf[PATH_MAX];
if (e_config_dialog_find("Imfos", "advanced/Imfos")) return NULL;
v = E_NEW(E_Config_Dialog_View, 1);
if (!v) return NULL;
v->create_cfdata = _create_data;
v->free_cfdata = _free_data;
v->basic.create_widgets = _basic_create;
v->basic.apply_cfdata = _apply;
/* Icon */
cfd = e_config_dialog_new(NULL, "Imfos module", "Imfos", "advanced/Imfos",
NULL, 0, v, NULL);
return cfd;
}
static void *
_create_data(E_Config_Dialog *cfd)
{
_tmp_cfg = calloc(1, sizeof(Imfos_Config_Panel));
return NULL;
}
static void
_free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
{
free(_tmp_cfg->config);
free(_tmp_cfg);
_tmp_cfg = NULL;
_imfos_cam_widget = NULL;
}
static void
_fill_data(E_Config_Dialog_Data *cfdata)
{
}
static void
_imfos_device_changed(void *data)
{
Imfos_Device *dev;
dev = data;
if (_tmp_cfg->dev)
imfos_devices_cancel(_tmp_cfg->dev);
_tmp_cfg->dev = dev;
_tmp_cfg->config = malloc(sizeof(Imfos_Device));
/* Warning just a copy ! */
memcpy(_tmp_cfg->config, dev, sizeof(Imfos_Device));
if (_tmp_cfg->current)
evas_object_del(_tmp_cfg->current);
_tmp_cfg->current = e_widget_list_add(evas_object_evas_get(_tmp_cfg->main), 0, 0);
e_widget_list_object_append(_tmp_cfg->main, _tmp_cfg->current, 1, 0, 0.5);
_device_create();
printf ("sel %s\n", dev->name);
}
static void
_imfos_cam_widget_delete(void *data, Evas *evas, Evas_Object *obj, void *event_info)
{
Imfos_Device *dev;
dev = data;
printf("deleting cam widget\n");
dev->param.v4l.cam = NULL;
imfos_devices_cancel(dev);
}
static void
_fill_devices(Evas *evas, Evas_Object *list)
{
const Eina_List *devices, *l;
Imfos_Device *dev;
char buf[1024];
Evas_Object *o;
EINA_LIST_FOREACH(imfos_config->devices, l, dev)
{
snprintf(buf, sizeof(buf), "%s(%s)", dev->name, dev->dev_name);
e_widget_ilist_append(list, NULL, buf, _imfos_device_changed, dev, NULL);
printf("dev %s(%s)\n", dev->name, dev->dev_name);
}
e_widget_ilist_selected_set(list, 1);
_imfos_device_changed(eina_list_data_get(imfos_config->devices));
}
static void
_v4l_create(void)
{
Evas_Object *o;
Evas *evas;
Evas_Object *list;
list = _tmp_cfg->current;
evas = evas_object_evas_get(_tmp_cfg->current);
printf("V4l panel\n");
o = evas_object_image_filled_add(evas);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_min_set(o, 320, 240);
e_widget_list_object_append(list, o, 1, 1, 0.5);
_tmp_cfg->dev->param.v4l.cam = o;
// if (_tmp_cfg->config->enabled)
// imfos_devices_run(_tmp_cfg->dev);
evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _imfos_cam_widget_delete, _tmp_cfg->dev);
o = e_widget_check_add(evas, "Flip camera", &flipped);
e_widget_list_object_append(list, o, 1, 0, 0.5);
o = e_widget_check_add(evas, "Set as the fallback", &flipped);
e_widget_list_object_append(list, o, 1, 0, 0.5);
}
static void
_device_create(void)
{
Evas_Object *o;
Evas *evas;
Evas_Object *list;
char buf[4096];
list = _tmp_cfg->current;
evas = evas_object_evas_get(_tmp_cfg->current);
printf("Device Create\n");
o = e_widget_check_add(evas, "Enabled",
(int *)&_tmp_cfg->config->enabled);
e_widget_list_object_append(list, o, 1, 0, 0.0);
snprintf(buf, sizeof(buf), "Name : %s", _tmp_cfg->config->name);
o = e_widget_label_add(evas, buf);
e_widget_list_object_append(list, o, 1, 0, 0.0);
snprintf(buf, sizeof(buf), "System path : %s", _tmp_cfg->config->syspath);
o = e_widget_label_add(evas, buf);
e_widget_list_object_append(list, o, 1, 0, 0.0);
snprintf(buf, sizeof(buf), "Device path : %s", _tmp_cfg->config->dev_name);
o = e_widget_label_add(evas, buf);
e_widget_list_object_append(list, o, 1, 0, 0.0);
o = e_widget_check_add(evas, "Lock the device path",
(int *)&_tmp_cfg->config->dev_name_locked);
e_widget_list_object_append(list, o, 1, 0, 0.0);
_v4l_create();
o = e_widget_slider_add(evas, 1, 0, "Priority : %d", -100.0, 100.0, 5.0, 50,
NULL, &_tmp_cfg->config->priority, 110);
e_widget_list_object_append(list, o, 1, 0, 0.5);
o = e_widget_check_add(evas, "async", (int *)&_tmp_cfg->config->async);
e_widget_list_object_append(list, o, 1, 0, 0.5);
o = e_widget_check_add(evas, "Timeout", (int *)&_tmp_cfg->config->timeout_enabled);
e_widget_list_object_append(list, o, 1, 0, 0.5);
o = e_widget_slider_add(evas, 1, 0, "Timeout (%2.0f)", 0.0, 64580.0, 5.0, 0,
NULL, &_tmp_cfg->config->timeout, 110);
e_widget_list_object_append(list, o, 1, 0, 0.5);
// o = e_widget_radio_group_new((int*) &(_tmp_cfg->config->powersave_min_state));
// e_widget_list_object_append(list, o, 1, 0, 0.5);
o = e_widget_check_add(evas, "Force the login when detected",
(int*)&_tmp_cfg->config->auto_login);
e_widget_list_object_append(list, o, 1, 0, 0.5);
o = e_widget_check_add(evas, "Force the logoff when missmatch",
(int*)&_tmp_cfg->config->auto_logout);
e_widget_list_object_append(list, o, 1, 0, 0.5);
o = e_widget_check_add(evas, "Report the screensaver when detected",
(int*)&_tmp_cfg->config->auto_screen_on);
e_widget_list_object_append(list, o, 1, 0, 0.5);
o = e_widget_check_add(evas, "Enable the screensaver when missmatch",
(int*)&_tmp_cfg->config->auto_screen_off);
e_widget_list_object_append(list, o, 1, 0, 0.5);
/*
powersave_min_state
*/
}
static Evas_Object *
_basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
{
Evas_Object *list, *list_cam, *devices_list, *o;
_tmp_cfg->main = e_widget_list_add(evas, 0, 1);
o = e_widget_ilist_add(evas, 0, 0, NULL);
e_widget_ilist_multi_select_set(o, EINA_FALSE);
evas_object_size_hint_min_set(o, 160, 240);
e_widget_list_object_append(_tmp_cfg->main, o, 1, 0, 0.5);
evas_object_show(o);
_fill_devices(evas, o);
return _tmp_cfg->main;
}
static int
_apply(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
{
}

View File

@ -0,0 +1,6 @@
#ifndef _E_MOD_CONFIG_H
#define _E_MOD_CONFIG_H
EAPI E_Config_Dialog *e_mod_config_imfos(Evas_Object *parent, const char *params);
#endif /* _E_MOD_CONFIG_H */

113
src/modules/imfos/e_mod_main.c Executable file
View File

@ -0,0 +1,113 @@
#include "e_mod_main.h"
#include "e_mod_config.h"
#include "imfos_v4l.h"
#include "imfos_devices.h"
#define IMFOS_TIMEOUT 10
static E_Config_DD *_conf_edd = NULL;
static E_Config_DD *_conf_edd_device = NULL;
static Ecore_Timer *_imfos_timer = NULL;
Imfos_Config *imfos_config = NULL;
static E_Config_DD *imfos_config_edd = NULL;
EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Imfos" };
static void _e_mod_imfos(void);
static Eina_Bool _run(void *);
static Eina_Bool
_run(void *data EINA_UNUSED)
{
// imfos_v4l_run(imfos_config);
}
EAPI void *
e_modapi_init(E_Module *m)
{
printf("Loading ...\n");
_conf_edd = E_CONFIG_DD_NEW("Config", Imfos_Config);
_conf_edd_device = E_CONFIG_DD_NEW("Device", Imfos_Device);
#undef T
#undef D
#define T Imfos_Device
#define D _conf_edd_device
E_CONFIG_VAL(D, T, enabled, INT);
E_CONFIG_VAL(D, T, name, STR);
E_CONFIG_VAL(D, T, dev_name, STR);
E_CONFIG_VAL(D, T, dev_name_locked, INT);
E_CONFIG_VAL(D, T, capacities, INT);
E_CONFIG_VAL(D, T, powersave_min_state, INT);
E_CONFIG_VAL(D, T, priority, INT);
E_CONFIG_VAL(D, T, async, INT);
E_CONFIG_VAL(D, T, timeout, INT);
E_CONFIG_VAL(D, T, auto_screen_on, INT);
E_CONFIG_VAL(D, T, auto_screen_off, INT);
E_CONFIG_VAL(D, T, auto_logout, INT);
E_CONFIG_VAL(D, T, auto_login, INT);
E_CONFIG_VAL(D, T, catch_time_average, INT);
E_CONFIG_VAL(D, T, catch_count, INT);
E_CONFIG_VAL(D, T, param.v4l.flip, INT);
E_CONFIG_VAL(D, T, param.v4l.init_time_average, INT);
E_CONFIG_VAL(D, T, param.wifi.ssid, STR);
E_CONFIG_VAL(D, T, param.bluetooth.id, STR);
#undef T
#undef D
#define T Imfos_Config
#define D _conf_edd
E_CONFIG_VAL(D, T, config_version, UINT);
E_CONFIG_LIST(D, T, devices, _conf_edd_device);
imfos_config = e_config_domain_load("module.imfos", _conf_edd);
if ((!imfos_config)
|| (imfos_config->config_version != IMFOS_CONFIG_VERSION))
E_FREE(imfos_config);
if (!imfos_config)
{
imfos_config = calloc(1, sizeof(Imfos_Config));
imfos_config->config_version = IMFOS_CONFIG_VERSION;
}
/*
E_CONFIG_LIMIT(imfos_config->poll_interval, 1, 3600);
E_CONFIG_LIMIT(imfos_config->poll_interval_max, 1, 3600);
E_CONFIG_LIMIT(imfos_config->poll_interval_powersave, 1, 3600);
*/
imfos_devices_init();
imfos_v4l_init();
e_configure_registry_category_add("advanced", 80, _("Advanced"), NULL,
"preferences-advanced");
e_configure_registry_item_add("advanced/imfos", 20, "Imfos", NULL,
"preference-imfos", e_mod_config_imfos);
e_config_domain_save("module.imfos", _conf_edd, imfos_config);
// _imfos_timer = ecore_timer_add(50.0, _run, NULL);
return m;
}
EAPI int
e_modapi_shutdown(E_Module *m EINA_UNUSED)
{
e_configure_registry_item_del("advanced/imfos");
e_configure_registry_category_del("advanced");
ecore_timer_del(_imfos_timer);
E_CONFIG_DD_FREE(_conf_edd);
E_CONFIG_DD_FREE(_conf_edd_device);
free(imfos_config);
imfos_v4l_shutdown();
imfos_devices_shutdown();
return 1;
}
EAPI int
e_modapi_save(E_Module *m EINA_UNUSED)
{
e_config_domain_save("module.imfos", _conf_edd, imfos_config);
return 1;
}

37
src/modules/imfos/e_mod_main.h Executable file
View File

@ -0,0 +1,37 @@
#ifndef _E_MOD_MAIN_H
#define _E_MOD_MAIN_H
#include <e.h>
#include "imfos_devices.h"
#define IMFOS_CONFIG_VERSION 1
#ifdef _cplusplus
extern "C++"
#endif
int imfos_face_search(char *data, int width, int height, int stride);
enum _Imfos_Orient
{
IMFOS_ORIENT_DEFAULT,
IMFOS_ORIENT_90,
IMFOS_ORIENT_180,
IMFOS_ORIENT_270
};
typedef struct _Config_Item Config_Item;
typedef struct _Imfos_Config Imfos_Config;
typedef enum _Imfos_Orient Imfos_Orient;
struct _Imfos_Config
{
unsigned int config_version;
Eina_List *devices;
E_Config_Dialog *cfd;
};
extern Imfos_Config *imfos_config;
#endif /* _E_MOD_MAIN_H */

View File

@ -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;
}

View File

@ -0,0 +1,60 @@
#ifndef IMFOS_DEVICES_H_
#define IMFOS_DEVICES_H_
#include <e.h>
typedef struct _Imfos_Device
{
const char *syspath;
const char *name;
const char *dev_name;
int type;
Ecore_Thread *thread;
int capacities;
int poll_interval;
int powersave_min_state;
int priority;
int timeout;
double time_start;
double last_catch;
int catch_count;
int catch_time_average;
Eina_Bool init_time_fixed;
Eina_Bool catched;
Eina_Bool async;
Eina_Bool auto_screen_on;
Eina_Bool auto_screen_off;
Eina_Bool auto_logout;
Eina_Bool auto_login;
Eina_Bool timeout_enabled;
Eina_Bool found;
Eina_Bool enabled;
Eina_Bool dev_name_locked;
struct
{
struct
{
Evas_Object *cam;
Eina_Bool flip;
int init_time;
int init_time_average;
} v4l;
struct
{
const char *ssid;
} wifi;
struct
{
const char *id;
} bluetooth;
} param;
} Imfos_Device;
void imfos_devices_init(void);
void imfos_devices_shutdown(void);
Eina_Bool imfos_devices_run(Imfos_Device *dev);
Eina_Bool imfos_devices_cancel(Imfos_Device *dev);
Eina_Bool imfos_devices_timeout(Imfos_Device *dev);
#endif /* IMFOS_DEVICES_H_ */

View File

@ -0,0 +1,35 @@
#define HAVE_OPENCV
#ifdef HAVE_OPENCV
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#endif
#include <Eina.h>
#include "imfos_face.h"
using namespace cv;
#define FACE_CASCADE_FILE_PATH "/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml"
int
imfos_face_search(char *data, int width, int height, int stride)
{
#ifdef HAVE_OPENCV
std::vector<Rect> faces;
CascadeClassifier face_cascade;
Mat frame_gray;
Mat mat(height, width, CV_8UC1, data, width + stride);
if (!face_cascade.load(FACE_CASCADE_FILE_PATH)) return 0;
face_cascade.detectMultiScale(mat, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30));
printf("Detect %d?\n",faces.size());
return (faces.size() > 0) ? 1 : 0;
#else
return 0;
#endif
}

13
src/modules/imfos/imfos_face.h Executable file
View File

@ -0,0 +1,13 @@
#ifndef IMFOS_FACE_SEARCH_
#define IMFOS_FACE_SEARCH_
#ifdef __cplusplus
extern "C" {
#endif
int imfos_face_search(char *data, int width, int height, int stride);
#ifdef __cplusplus
}
#endif
#endif

355
src/modules/imfos/imfos_v4l.c Executable file
View File

@ -0,0 +1,355 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <linux/videodev2.h>
#include <libv4l2.h>
#include <Eeze.h>
#include <e.h>
#include "e_mod_main.h"
#include <Ecore.h>
#include <Evas.h>
#include "imfos_v4l.h"
//#include "imfos_face.h"
#include <e.h>
#define CLEAR(x) memset(&(x), 0, sizeof(x))
static int _imfos_xioctl(int fh, int request, void *arg);
static Eina_Bool _imfos_v4l_image_transform(Evas_Object *cam, void *data, size_t size);
static void _imfos_v4l_takeshot(void *data, Ecore_Thread *thread);
static void _imfos_v4l_end(void *data, Ecore_Thread *thread);
static void _imfos_v4l_cancel(void *data, Ecore_Thread *thread);
static Ecore_Animator *_imfos_v4l_anim = NULL;
static int _width;
static int _height;
static int _size;
static void *_img = NULL;
static void *_img_y = NULL;
static int _2126[256];
static int _7152[256];
static int _0722[256];
struct buffer {
void *start;
size_t length;
};
static int
_imfos_xioctl(int fh, int request, void *arg)
{
int r;
do
{
r = v4l2_ioctl(fh, request, arg);
} while (r == -1 && ((errno == EINTR) || (errno == EAGAIN)));
if (r == -1)
{
fprintf(stderr, "error %d, %s\n", errno, strerror(errno));
return 1;
}
return 0;
}
static Eina_Bool
_imfos_v4l_frame_anim(void *data)
{
_imfos_v4l_anim = NULL;
evas_object_image_pixels_dirty_set(data, 1);
return EINA_FALSE;
}
static Eina_Bool
_imfos_v4l_image_transform(Evas_Object *cam, void *data, size_t size)
{
unsigned char *b, *cb, *cyb;
size_t i;
unsigned int percent;
percent = 0;
if (cam)
{
if (!_img)
{
evas_object_image_pixels_get_callback_set(cam, NULL, NULL);
evas_object_image_alpha_set(cam, 0);
evas_object_image_colorspace_set(cam, EVAS_COLORSPACE_ARGB8888);
evas_object_image_size_set(cam, _width, _height);
_img = evas_object_image_data_get(cam, 1);
}
}
if (!_img_y)
_img_y = malloc(_width * _height);
b = data;
cb = _img;
cyb = _img_y;
for (i = 0; i < size; i += 3)
{
*cyb = (char)((_2126[b[2]] + _7152[b[1]] + _0722[b[0]]) >> 8);
if (*cyb > 16)
++percent;
if (cam)
{
cb[3] = 255;
cb[2] = b[0];
cb[1] = b[1];
cb[0] = b[2];
cb += 4;
}
b += 3;
cyb += 1;
}
if (cam)
{
if (!_imfos_v4l_anim)
_imfos_v4l_anim = ecore_animator_add(_imfos_v4l_frame_anim, cam);
evas_object_image_data_set(cam, _img);
evas_object_image_data_update_add(cam, 0, 0, _width, _height);
evas_object_image_pixels_dirty_set(cam, 0);
}
// printf("percent %d%%\n", (percent * 100)/ (_width * _height));
return (percent > (size / 10));
}
void
imfos_v4l_run(Imfos_Device *conf)
{
struct v4l2_format fmt;
struct v4l2_buffer buf;
struct v4l2_requestbuffers req;
enum v4l2_buf_type type;
fd_set fds;
struct timeval tv;
int r, fd = -1;
unsigned int i, n_buffers;
char out_name[256];
FILE *fout;
struct buffer *buffers;
Eina_Bool stop;
double time_start;
double loop_time_start;
double loop_time_cur;
double loop_time_avg = 0.0;
stop = EINA_FALSE;
fprintf(stderr, "imfos thread %s\n", conf->dev_name);
fd = v4l2_open(conf->dev_name, O_RDWR | O_NONBLOCK, 0);
if (fd < 0) {
perror("Cannot open device");
return;
}
CLEAR(fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 640;
fmt.fmt.pix.height = 480;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
//fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_GREY;
_imfos_xioctl(fd, VIDIOC_S_FMT, &fmt);
if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24) {
fprintf(stderr, "Libv4l didn't accept RGB24 format. Can't proceed.\n");
switch (fmt.fmt.pix.pixelformat) {
case V4L2_PIX_FMT_ARGB32:
printf("argb32\n");
break;
case V4L2_PIX_FMT_RGB24:
case V4L2_PIX_FMT_BGR24:
printf("rgb24\n");
break;
case V4L2_PIX_FMT_Y4:
printf("y4\n");
break;
case V4L2_PIX_FMT_Y6:
printf("y6\n");
break;
case V4L2_PIX_FMT_Y10:
printf("y10\n");
break;
case V4L2_PIX_FMT_Y12:
printf("y12\n");
break;
case V4L2_PIX_FMT_Y16:
printf("y16\n");
break;
case V4L2_PIX_FMT_GREY:
printf("grey\n");
break;
default:
printf("%d\n", fmt.fmt.pix.pixelformat);
}
}
if ((fmt.fmt.pix.width != 640) || (fmt.fmt.pix.height != 480))
printf("Warning: driver is sending image at %dx%d\n",
fmt.fmt.pix.width, fmt.fmt.pix.height);
if (conf->param.v4l.cam)
{
printf("Sizing object %d %d\n", _width, _height);
evas_object_image_colorspace_set(conf->param.v4l.cam, EVAS_COLORSPACE_ARGB8888);
evas_object_image_size_set(conf->param.v4l.cam, _width, _height);
}
CLEAR(req);
req.count = 2;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
_imfos_xioctl(fd, VIDIOC_REQBUFS, &req);
buffers = calloc(req.count, sizeof(*buffers));
for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
_imfos_xioctl(fd, VIDIOC_QUERYBUF, &buf);
buffers[n_buffers].length = buf.length;
buffers[n_buffers].start = v4l2_mmap(NULL, buf.length,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start) {
perror("mmap");
return;
}
}
for (i = 0; i < n_buffers; ++i) {
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
_imfos_xioctl(fd, VIDIOC_QBUF, &buf);
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
_imfos_xioctl(fd, VIDIOC_STREAMON, &type);
for (i = 0; ; ++i) {
loop_time_start = ecore_time_get();
//fprintf(stderr, "try %d\n", i);
do {
FD_ZERO(&fds);
FD_SET(fd, &fds);
/* Timeout. */
tv.tv_sec = 2;
tv.tv_usec = 0;
r = select(fd + 1, &fds, NULL, NULL, &tv);
} while ((r == -1 && (errno = EINTR)));
if (r == -1) {
perror("select");
goto v4l_close;
}
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
_imfos_xioctl(fd, VIDIOC_DQBUF, &buf);
_width = fmt.fmt.pix.width;
_height = fmt.fmt.pix.height;
_size = buf.bytesused;
// printf("copy %d %d %d - %d\n", buf.bytesused,
// _width * _height * 2, _width, _height);
if (_imfos_v4l_image_transform(conf->param.v4l.cam, buffers[buf.index].start,
buf.bytesused))
{
/*
if (imfos_face_search(_img_y, _width, _height, 0))
{
stop = EINA_TRUE;
e_screensaver_notidle();
fprintf(stderr, "I saw you !\n");
}
*/
}
_imfos_xioctl(fd, VIDIOC_QBUF, &buf);
/*
fprintf(stderr, "imfos %.8f %.8f\n",
ecore_time_get() - time_start,
loop_time_avg);
*/
if (stop) break;
if (imfos_devices_timeout(conf))
break;
}
// if (stop)
// e_screensaver_notidle();
v4l_close:
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
_imfos_xioctl(fd, VIDIOC_STREAMOFF, &type);
for (i = 0; i < n_buffers; ++i)
v4l2_munmap(buffers[i].start, buffers[i].length);
v4l2_close(fd);
fprintf(stderr, "v4l close %d\n", stop);
}
void
imfos_v4l_clean(Imfos_Device *conf)
{
fprintf(stderr, "v4l end\n");
if (_imfos_v4l_anim)
ecore_animator_del(_imfos_v4l_anim);
_imfos_v4l_anim = NULL;
if (conf->param.v4l.cam)
{
evas_object_image_size_set(conf->param.v4l.cam, 1, 1);
evas_object_image_data_set(conf->param.v4l.cam, NULL);
}
free(_img_y);
_img_y = NULL;
_img = NULL;
}
static void
_imfos_v4l_cancel(void *data, Ecore_Thread *thread)
{
printf("v4l cancel\n");
}
void
imfos_v4l_init(void)
{
unsigned int i;
for (i = 0; i < 256; i++)
{
_2126[i] = 0.2116 * 256 * i;
_7152[i] = 0.7152 * 256 * i;
_0722[i] = 0.0722 * 256 * i;
}
}
void
imfos_v4l_shutdown(void)
{
}

11
src/modules/imfos/imfos_v4l.h Executable file
View File

@ -0,0 +1,11 @@
#ifndef IMFOS_V4L_H_
#define IMFOS_V4L_H_
#include "e_mod_main.h"
void imfos_v4l_init(void);
void imfos_v4l_shutdown(void);
void imfos_v4l_run(Imfos_Device *dev);
void imfos_v4l_clean(Imfos_Device *dev);
#endif /* IMFOS_V4L_H_ */

View File

@ -0,0 +1,8 @@
[Desktop Entry]
Encoding=UTF-8
Type=Link
Name=Imfos
Comment=I'm front of screen
Icon=e-module-clock
X-Enlightenment-ModuleType=utils