1 #include "emotion_private.h"
4 #ifdef EMOTION_HAVE_EEZE
8 # include <sys/ioctl.h>
10 # include <linux/videodev2.h>
19 EAPI int EMOTION_WEBCAM_UPDATE = 0;
24 const char *extension;
27 #define MATCHING(Ext) \
30 static const struct ext_match_s matchs[] =
31 { /* map extensions to know if it's a emotion playable content for good first-guess tries */
82 _emotion_object_extension_can_play_generic_get(const void *data __UNUSED__, const char *file)
87 length = eina_stringshare_strlen(file) + 1;
88 if (length < 5) return EINA_FALSE;
90 for (i = 0; i < sizeof (matchs) / sizeof (struct ext_match_s); ++i)
92 if (matchs[i].length > length) continue;
94 if (!strcasecmp(matchs[i].extension,
95 file + length - matchs[i].length))
103 emotion_object_extension_may_play_fast_get(const char *file)
105 if (!file) return EINA_FALSE;
106 return _emotion_object_extension_can_play_generic_get(NULL, file);
110 emotion_object_extension_may_play_get(const char *file)
115 if (!file) return EINA_FALSE;
116 tmp = eina_stringshare_add(file);
117 result = emotion_object_extension_may_play_fast_get(tmp);
118 eina_stringshare_del(tmp);
123 typedef struct _Emotion_Webcams Emotion_Webcams;
125 struct _Emotion_Webcams
130 struct _Emotion_Webcam
140 const char *filename;
143 static int _emotion_webcams_count = 0;
144 static Eet_Data_Descriptor *_webcam_edd;
145 static Eet_Data_Descriptor *_webcams_edd;
147 static Emotion_Webcams *_emotion_webcams = NULL;
148 static Eet_File *_emotion_webcams_file = NULL;
150 static Eet_Data_Descriptor *
151 _emotion_webcams_data(void)
153 Eet_Data_Descriptor_Class eddc;
155 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Emotion_Webcam);
156 _webcam_edd = eet_data_descriptor_file_new(&eddc);
157 EET_DATA_DESCRIPTOR_ADD_BASIC(_webcam_edd, Emotion_Webcam, "device", device, EET_T_STRING);
158 EET_DATA_DESCRIPTOR_ADD_BASIC(_webcam_edd, Emotion_Webcam, "name", name, EET_T_STRING);
159 EET_DATA_DESCRIPTOR_ADD_BASIC(_webcam_edd, Emotion_Webcam, "custom", custom, EET_T_STRING);
160 EET_DATA_DESCRIPTOR_ADD_BASIC(_webcam_edd, Emotion_Webcam, "filename", filename, EET_T_STRING);
162 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Emotion_Webcams);
163 _webcams_edd = eet_data_descriptor_file_new(&eddc);
164 EET_DATA_DESCRIPTOR_ADD_LIST(_webcams_edd, Emotion_Webcams, "webcams", webcams, _webcam_edd);
169 #ifdef EMOTION_HAVE_EEZE
170 static Eeze_Udev_Watch *eeze_watcher = NULL;
173 emotion_webcam_destroy(Emotion_Webcam *ew)
177 eina_stringshare_del(ew->syspath);
178 eina_stringshare_del(ew->device);
179 eina_stringshare_del(ew->name);
185 _emotion_check_device(Emotion_Webcam *ew)
188 Emotion_Webcam *check;
190 struct v4l2_capability caps;
196 if (!ew->device) goto on_error;
198 fd = open(ew->filename, O_RDONLY);
199 if (fd < 0) goto on_error;
201 if (ioctl(fd, VIDIOC_QUERYCAP, &caps) == -1) goto on_error;
203 /* Likely not a webcam */
204 if (!caps.capabilities & V4L2_CAP_VIDEO_CAPTURE) goto on_error;
205 if (caps.capabilities & V4L2_CAP_TUNER
206 || caps.capabilities & V4L2_CAP_RADIO
207 || caps.capabilities & V4L2_CAP_MODULATOR)
210 EINA_LIST_FOREACH(_emotion_webcams->webcams, l, check)
211 if (check->device == ew->device)
214 _emotion_webcams->webcams = eina_list_append(_emotion_webcams->webcams, ew);
216 EINA_REFCOUNT_INIT(ew);
222 fprintf(stderr, "'%s' is not a webcam ['%s']\n", ew->name, strerror(errno));
223 eina_stringshare_del(ew->syspath);
224 eina_stringshare_del(ew->device);
225 eina_stringshare_del(ew->name);
229 static Emotion_Webcam *
230 _emotion_webcam_new(const char *syspath)
232 Emotion_Webcam *test;
236 test = malloc(sizeof (Emotion_Webcam));
237 if (!test) return NULL;
240 test->syspath = eina_stringshare_ref(syspath);
241 test->name = eeze_udev_syspath_get_sysattr(syspath, "name");
243 device = eeze_udev_syspath_get_property(syspath, "DEVNAME");
244 local = alloca(eina_stringshare_strlen(device) + 8);
245 snprintf(local, eina_stringshare_strlen(device) + 8, "v4l2://%s", device);
246 test->device = eina_stringshare_add(local);
247 eina_stringshare_del(device);
248 test->filename = test->device + 7;
254 _emotion_enumerate_all_webcams(void)
259 devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_V4L, NULL);
261 EINA_LIST_FREE(devices, syspath)
263 Emotion_Webcam *test;
265 test = _emotion_webcam_new(syspath);
266 if (test) _emotion_check_device(test);
268 eina_stringshare_del(syspath);
273 _emotion_eeze_events(const char *syspath,
275 void *data __UNUSED__,
276 Eeze_Udev_Watch *watcher __UNUSED__)
278 if (ev == EEZE_UDEV_EVENT_REMOVE)
280 Emotion_Webcam *check;
283 EINA_LIST_FOREACH(_emotion_webcams->webcams, l, check)
284 if (check->syspath == syspath)
286 _emotion_webcams->webcams = eina_list_remove_list(_emotion_webcams->webcams, l);
287 EINA_REFCOUNT_UNREF(check)
288 emotion_webcam_destroy(check);
292 else if (ev == EEZE_UDEV_EVENT_ADD)
294 Emotion_Webcam *test;
296 test = _emotion_webcam_new(syspath);
297 if (test) _emotion_check_device(test);
299 ecore_event_add(EMOTION_WEBCAM_UPDATE, NULL, NULL, NULL);
309 if (_emotion_webcams_count++) return EINA_TRUE;
311 snprintf(buffer, 4096, "%s/emotion.cfg", PACKAGE_DATA_DIR);
312 _emotion_webcams_file = eet_open(buffer, EET_FILE_MODE_READ);
313 if (_emotion_webcams_file)
315 Eet_Data_Descriptor *edd;
317 edd = _emotion_webcams_data();
319 _emotion_webcams = eet_data_read(_emotion_webcams_file, edd, "config");
321 eet_data_descriptor_free(_webcams_edd); _webcams_edd = NULL;
322 eet_data_descriptor_free(_webcam_edd); _webcam_edd = NULL;
325 if (!_emotion_webcams)
327 _emotion_webcams = calloc(1, sizeof (Emotion_Webcams));
328 if (!_emotion_webcams) return EINA_FALSE;
331 #ifdef EMOTION_HAVE_EEZE
332 EMOTION_WEBCAM_UPDATE = ecore_event_type_new();
336 _emotion_enumerate_all_webcams();
338 eeze_watcher = eeze_udev_watch_add(EEZE_UDEV_TYPE_V4L,
339 (EEZE_UDEV_EVENT_ADD | EEZE_UDEV_EVENT_REMOVE),
340 _emotion_eeze_events, NULL);
347 emotion_shutdown(void)
351 if (--_emotion_webcams_count) return EINA_TRUE;
353 EINA_LIST_FREE(_emotion_webcams->webcams, ew)
355 /* There is currently no way to refcount from the outside, this help, but could lead to some issue */
356 EINA_REFCOUNT_UNREF(ew)
357 emotion_webcam_destroy(ew);
359 free(_emotion_webcams);
360 _emotion_webcams = NULL;
362 if (_emotion_webcams_file)
364 /* As long as there is no one reference any pointer, you are safe */
365 eet_close(_emotion_webcams_file);
366 _emotion_webcams_file = NULL;
369 #ifdef EMOTION_HAVE_EEZE
370 eeze_udev_watch_del(eeze_watcher);
379 EAPI const Eina_List *
380 emotion_webcams_get(void)
382 return _emotion_webcams->webcams;
386 emotion_webcam_name_get(const Emotion_Webcam *ew)
388 if (!ew) return NULL;
394 emotion_webcam_device_get(const Emotion_Webcam *ew)
396 if (!ew) return NULL;
402 emotion_webcam_custom_get(const char *device)
404 const Emotion_Webcam *ew;
407 EINA_LIST_FOREACH(_emotion_webcams->webcams, l, ew)
408 if (ew->device && strcmp(device, ew->device) == 0)