diff --git a/legacy/emotion/src/lib/emotion_main.c b/legacy/emotion/src/lib/emotion_main.c new file mode 100644 index 0000000000..8a5a055ddd --- /dev/null +++ b/legacy/emotion/src/lib/emotion_main.c @@ -0,0 +1,320 @@ +#include "emotion_private.h" +#include "Emotion.h" + +#ifdef EMOTION_HAVE_EEZE +#include +#include +#include +# include +# include + +# include +# include +#endif + +EAPI int EMOTION_WEBCAM_UPDATE = 0; + +struct ext_match_s +{ + unsigned int length; + const char *extension; +}; + +#define MATCHING(Ext) \ + { sizeof (Ext), Ext } + +static const struct ext_match_s matchs[] = +{ /* map extensions to know if it's a emotion playable content for good first-guess tries */ + MATCHING(".264"), + MATCHING(".3g2"), + MATCHING(".3gp"), + MATCHING(".3gp2"), + MATCHING(".3gpp"), + MATCHING(".3gpp2"), + MATCHING(".3p2"), + MATCHING(".asf"), + MATCHING(".avi"), + MATCHING(".bdm"), + MATCHING(".bdmv"), + MATCHING(".clpi"), + MATCHING(".clp"), + MATCHING(".fla"), + MATCHING(".flv"), + MATCHING(".m1v"), + MATCHING(".m2v"), + MATCHING(".m2t"), + MATCHING(".m4v"), + MATCHING(".mkv"), + MATCHING(".mov"), + MATCHING(".mp2"), + MATCHING(".mp2ts"), + MATCHING(".mp4"), + MATCHING(".mpe"), + MATCHING(".mpeg"), + MATCHING(".mpg"), + MATCHING(".mpl"), + MATCHING(".mpls"), + MATCHING(".mts"), + MATCHING(".mxf"), + MATCHING(".nut"), + MATCHING(".nuv"), + MATCHING(".ogg"), + MATCHING(".ogm"), + MATCHING(".ogv"), + MATCHING(".rm"), + MATCHING(".rmj"), + MATCHING(".rmm"), + MATCHING(".rms"), + MATCHING(".rmx"), + MATCHING(".rmvb"), + MATCHING(".swf"), + MATCHING(".ts"), + MATCHING(".weba"), + MATCHING(".webm"), + MATCHING(".wmv") +}; + +Eina_Bool +_emotion_object_extension_can_play_generic_get(const void *data __UNUSED__, const char *file) +{ + unsigned int length; + unsigned int i; + + length = eina_stringshare_strlen(file) + 1; + if (length < 5) return EINA_FALSE; + + for (i = 0; i < sizeof (matchs) / sizeof (struct ext_match_s); ++i) + { + if (matchs[i].length > length) continue; + + if (!strcasecmp(matchs[i].extension, + file + length - matchs[i].length)) + return EINA_TRUE; + } + + return EINA_FALSE; +} + +EAPI Eina_Bool +emotion_object_extension_may_play_fast_get(const char *file) +{ + if (!file) return EINA_FALSE; + return _emotion_object_extension_can_play_generic_get(NULL, file); +} + +EAPI Eina_Bool +emotion_object_extension_may_play_get(const char *file) +{ + const char *tmp; + Eina_Bool result; + + if (!file) return EINA_FALSE; + tmp = eina_stringshare_add(file); + result = emotion_object_extension_may_play_fast_get(tmp); + eina_stringshare_del(tmp); + + return result; +} + +#ifdef EMOTION_HAVE_EEZE +struct _Emotion_Webcam +{ + EINA_REFCOUNT; + + const char *syspath; + const char *device; + const char *name; +}; + +static int _emotion_webcams_count = 0; +static Eina_List *_emotion_webcams = NULL; +static Eeze_Udev_Watch *eeze_watcher = NULL; + +static void +emotion_webcam_destroy(Emotion_Webcam *ew) +{ + eina_stringshare_del(ew->syspath); + eina_stringshare_del(ew->device); + eina_stringshare_del(ew->name); + free(ew); +} + +static void +_emotion_check_device(Emotion_Webcam *ew) +{ + Emotion_Webcam *check; + Eina_List *l; + struct v4l2_capability caps; + int fd; + + if (!ew) return ; + if (!ew->device) goto on_error; + + fd = open(ew->device, O_RDONLY); + if (!fd) goto on_error; + + if (ioctl(fd, VIDIOC_QUERYCAP, &caps) == -1) goto on_error; + + /* Likely not a webcam */ + if (!caps.capabilities & V4L2_CAP_VIDEO_CAPTURE) goto on_error; + if (caps.capabilities & V4L2_CAP_TUNER + || caps.capabilities & V4L2_CAP_RADIO + || caps.capabilities & V4L2_CAP_MODULATOR) + goto on_error; + + EINA_LIST_FOREACH(_emotion_webcams, l, check) + if (check->device == ew->device) + goto on_error; + + _emotion_webcams = eina_list_append(_emotion_webcams, ew); + + EINA_REFCOUNT_INIT(ew); + + return ; + + on_error: + fprintf(stderr, "'%s' is not a webcam\n", ew->name); + eina_stringshare_del(ew->syspath); + eina_stringshare_del(ew->device); + eina_stringshare_del(ew->name); + free(ew); +} + +static Emotion_Webcam * +_emotion_webcam_new(const char *syspath) +{ + Emotion_Webcam *test; + + test = malloc(sizeof (Emotion_Webcam)); + if (!test) return NULL; + + test->syspath = eina_stringshare_ref(syspath); + test->device = eeze_udev_syspath_get_property(syspath, "DEVNAME"); + test->name = eeze_udev_syspath_get_sysattr(syspath, "name"); + + return test; +} + +static void +_emotion_enumerate_all_webcams(void) +{ + Eina_List *devices; + const char *syspath; + + devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_V4L, NULL); + + EINA_LIST_FREE(devices, syspath) + { + Emotion_Webcam *test; + + test = _emotion_webcam_new(syspath); + if (test) _emotion_check_device(test); + + eina_stringshare_del(syspath); + } +} + +static void +_emotion_eeze_events(const char *syspath, + Eeze_Udev_Event ev, + void *data, + Eeze_Udev_Watch *watcher) +{ + if (ev == EEZE_UDEV_EVENT_REMOVE) + { + Emotion_Webcam *check; + Eina_List *l; + + EINA_LIST_FOREACH(_emotion_webcams, l, check) + if (check->syspath == syspath) + { + _emotion_webcams = eina_list_remove_list(_emotion_webcams, l); + EINA_REFCOUNT_UNREF(check) + emotion_webcam_destroy(check); + break ; + } + } + else if (ev == EEZE_UDEV_EVENT_ADD) + { + Emotion_Webcam *test; + + test = _emotion_webcam_new(syspath); + if (test) _emotion_check_device(test); + } + ecore_event_add(EMOTION_WEBCAM_UPDATE, NULL, NULL, NULL); +} + +#endif + +EAPI Eina_Bool +emotion_init(void) +{ +#ifdef EMOTION_HAVE_EEZE + if (_emotion_webcams_count++) return EINA_TRUE; + + EMOTION_WEBCAM_UPDATE = ecore_event_type_new(); + + eeze_init(); + + _emotion_enumerate_all_webcams(); + + eeze_watcher = eeze_udev_watch_add(EEZE_UDEV_TYPE_V4L, + (EEZE_UDEV_EVENT_ADD | EEZE_UDEV_EVENT_REMOVE), + _emotion_eeze_events, NULL); + + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} + +EAPI Eina_Bool +emotion_shutdown(void) +{ +#ifdef EMOTION_HAVE_EEZE + if (--_emotion_webcams_count) return EINA_TRUE; + + eeze_udev_watch_del(eeze_watcher); + eeze_watcher = NULL; + + eeze_shutdown(); + + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} + +EAPI const Eina_List * +emotion_webcams_get(void) +{ +#ifdef EMOTION_HAVE_EEZE + return _emotion_webcams; +#else + return NULL; +#endif +} + +EAPI const char * +emotion_webcam_name_get(Emotion_Webcam *ew) +{ + if (!ew) return NULL; + +#ifdef EMOTION_HAVE_EEZE + return ew->name; +#else + return NULL; +#endif +} + +EAPI const char * +emotion_webcam_device_get(Emotion_Webcam *ew) +{ + if (!ew) return NULL; + +#ifdef EMOTION_HAVE_EEZE + return ew->device; +#else + return NULL; +#endif +}