summaryrefslogtreecommitdiff
path: root/src/edje_external
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@gmail.com>2013-01-10 03:43:32 +0000
committerGustavo Sverzut Barbieri <barbieri@gmail.com>2013-01-10 03:43:32 +0000
commitdfb84c1657bfb14a5236b881193b81f4c0b8a69b (patch)
treeb51b210fc88a21eec8e5907b8bbfe12ebc669f90 /src/edje_external
parent532284dbbe4259a9f2291f44d3eff376849e8031 (diff)
efl: merge emotion.
this one was quite a huge work, but hopefully it's correct. NOTES: * removed vlc generic module, it should go into a separate package. * gstreamer is enabled by default (see --disable-gstreamer) * xine is disabled by default (see --enable-gstreamer) * generic is always built statically if supported * gstreamer and xine can't be configured as static (just lacks command line options, build system supports it) * v4l2 is enabled by default on linux if eeze is built (see --disable-v4l2) * emotion_test moved to src/tests/emotion and depends on EFL_ENABLE_TESTS (--with-tests), but is still installed if enabled. TODO (need your help!): * fix warnings with gstreamer and xine engine * call engine shutdown functions if building as static * remove direct usage of PACKAGE_*_DIR and use eina_prefix * add eina_prefix checkme file as evas and others * add support for $EFL_RUN_IN_TREE * create separate package for emotion_generic_modules * check docs hierarchy (doxygen is segv'in here) SVN revision: 82501
Diffstat (limited to 'src/edje_external')
-rw-r--r--src/edje_external/emotion/emotion.c516
1 files changed, 516 insertions, 0 deletions
diff --git a/src/edje_external/emotion/emotion.c b/src/edje_external/emotion/emotion.c
new file mode 100644
index 0000000..7ae0a0e
--- /dev/null
+++ b/src/edje_external/emotion/emotion.c
@@ -0,0 +1,516 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <Edje.h>
6
7#include "Emotion.h"
8
9typedef struct _External_Emotion_Params External_Emotion_Params;
10typedef struct _External_Emotion_Signals_Proxy_Context External_Emotion_Signals_Proxy_Context;
11
12struct _External_Emotion_Params
13{
14#define _STR(M) const char *M
15#define _BOOL(M) Eina_Bool M:1; Eina_Bool M##_exists:1
16#define _INT(M) int M; Eina_Bool M##_exists:1
17#define _DOUBLE(M) double M; Eina_Bool M##_exists:1
18 _STR(file);
19 _BOOL(play);
20 _DOUBLE(position);
21 _BOOL(smooth_scale);
22 _DOUBLE(audio_volume);
23 _BOOL(audio_mute);
24 _INT(audio_channel);
25 _BOOL(video_mute);
26 _INT(video_channel);
27 _BOOL(spu_mute);
28 _INT(spu_channel);
29 _INT(chapter);
30 _DOUBLE(play_speed);
31 _DOUBLE(play_length);
32 //_INT(vis);
33#undef _STR
34#undef _BOOL
35#undef _INT
36#undef _DOUBLE
37};
38
39struct _External_Emotion_Signals_Proxy_Context
40{
41 const char *emission;
42 const char *source;
43 Evas_Object *edje;
44};
45
46static int _log_dom = -1;
47#define CRITICAL(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__)
48#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
49#define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
50#define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
51#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
52
53static const char *_external_emotion_engines[] = {
54#ifdef EMOTION_BUILD_XINE
55 "xine",
56#endif
57#ifdef EMOTION_BUILD_GSTREAMER
58 "gstreamer",
59#endif
60#ifdef EMOTION_BUILD_GENERIC
61 "generic",
62#endif
63 NULL,
64};
65
66static const char _external_emotion_engine_def[] =
67#if defined(EMOTION_BUILD_XINE)
68 "xine";
69#elif defined(EMOTION_BUILD_GSTREAMER)
70 "gstreamer";
71#elif defined(EMOTION_BUILD_GENERIC)
72 "generic";
73#else
74 "impossible";
75#endif
76
77static void
78_external_emotion_signal_proxy_free_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
79{
80 External_Emotion_Signals_Proxy_Context *ctxt = data;
81 free(ctxt);
82}
83
84static void
85_external_emotion_signal_proxy_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
86{
87 External_Emotion_Signals_Proxy_Context *ctxt = data;
88 // TODO: Is it worth to check Evas_Smart_Cb_Description and do something
89 // TODO: with event_info given its description?
90 edje_object_signal_emit(ctxt->edje, ctxt->emission, ctxt->source);
91}
92
93static Evas_Object *
94_external_emotion_add(void *data EINA_UNUSED, Evas *evas, Evas_Object *edje EINA_UNUSED, const Eina_List *params, const char *part_name)
95{
96 const Evas_Smart_Cb_Description **cls_descs, **inst_descs;
97 unsigned int cls_count, inst_count, total;
98 External_Emotion_Signals_Proxy_Context *ctxt;
99 Evas_Object *obj;
100 const char *engine;
101
102 if (!edje_external_param_choice_get(params, "engine", &engine))
103 engine = NULL;
104 if (!engine) engine = _external_emotion_engine_def;
105
106 obj = emotion_object_add(evas);
107 if (!emotion_object_init(obj, engine))
108 {
109 ERR("failed to initialize emotion with engine '%s'.", engine);
110 return NULL;
111 }
112
113 evas_object_smart_callbacks_descriptions_get
114 (obj, &cls_descs, &cls_count, &inst_descs, &inst_count);
115
116 total = cls_count + inst_count;
117 if (!total) goto end;
118 ctxt = malloc(sizeof(External_Emotion_Signals_Proxy_Context) * total);
119 if (!ctxt) goto end;
120 evas_object_event_callback_add
121 (obj, EVAS_CALLBACK_DEL, _external_emotion_signal_proxy_free_cb, ctxt);
122
123 for (; cls_count > 0; cls_count--, cls_descs++, ctxt++)
124 {
125 const Evas_Smart_Cb_Description *d = *cls_descs;
126 ctxt->emission = d->name;
127 ctxt->source = part_name;
128 ctxt->edje = edje;
129 evas_object_smart_callback_add
130 (obj, d->name, _external_emotion_signal_proxy_cb, ctxt);
131 }
132
133 for (; inst_count > 0; inst_count--, inst_descs++, ctxt++)
134 {
135 const Evas_Smart_Cb_Description *d = *inst_descs;
136 ctxt->emission = d->name;
137 ctxt->source = part_name;
138 ctxt->edje = edje;
139 evas_object_smart_callback_add
140 (obj, d->name, _external_emotion_signal_proxy_cb, ctxt);
141 }
142
143 end:
144 return obj;
145}
146
147static void
148_external_emotion_signal(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *signal, const char *source)
149{
150 DBG("External Signal received: '%s' '%s'", signal, source);
151}
152
153static void
154_external_emotion_state_set(void *data EINA_UNUSED, Evas_Object *obj, const void *from_params, const void *to_params, float pos EINA_UNUSED)
155{
156 const External_Emotion_Params *p;
157
158 if (to_params) p = to_params;
159 else if (from_params) p = from_params;
160 else return;
161
162#define _STR(M) if (p->M) emotion_object_##M##_set(obj, p->M)
163#define _BOOL(M) if (p->M##_exists) emotion_object_##M##_set(obj, p->M)
164#define _INT(M) if (p->M##_exists) emotion_object_##M##_set(obj, p->M)
165#define _DOUBLE(M) if (p->M##_exists) emotion_object_##M##_set(obj, p->M)
166 _STR(file);
167 _BOOL(play);
168 //_DOUBLE(position);
169 if (p->position_exists)
170 WRN("position should not be set from state description! Ignored.");
171 _BOOL(smooth_scale);
172 _DOUBLE(audio_volume);
173 _BOOL(audio_mute);
174 _INT(audio_channel);
175 _BOOL(video_mute);
176 _INT(video_channel);
177 _BOOL(spu_mute);
178 _INT(spu_channel);
179 _INT(chapter);
180 _DOUBLE(play_speed);
181 if (p->play_length_exists) ERR("play_length is read-only");
182 //_INT(vis);
183#undef _STR
184#undef _BOOL
185#undef _INT
186#undef _DOUBLE
187}
188
189static Eina_Bool
190_external_emotion_param_set(void *data EINA_UNUSED, Evas_Object *obj, const Edje_External_Param *param)
191{
192 if (!strcmp(param->name, "engine"))
193 {
194 // TODO
195 WRN("engine is a property that can be set only at object creation!");
196 return EINA_FALSE;
197 }
198
199#define _STR(M) \
200 else if (!strcmp(param->name, #M)) \
201 { \
202 if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING) \
203 { \
204 emotion_object_##M##_set(obj, param->s); \
205 return EINA_TRUE; \
206 } \
207 }
208#define _BOOL(M) \
209 else if (!strcmp(param->name, #M)) \
210 { \
211 if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL) \
212 { \
213 emotion_object_##M##_set(obj, param->i); \
214 return EINA_TRUE; \
215 } \
216 }
217#define _INT(M) \
218 else if (!strcmp(param->name, #M)) \
219 { \
220 if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT) \
221 { \
222 emotion_object_##M##_set(obj, param->i); \
223 return EINA_TRUE; \
224 } \
225 }
226#define _DOUBLE(M) \
227 else if (!strcmp(param->name, #M)) \
228 { \
229 if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE) \
230 { \
231 emotion_object_##M##_set(obj, param->d); \
232 return EINA_TRUE; \
233 } \
234 }
235
236 if (0) {} // so else if works...
237 _STR(file)
238 _BOOL(play)
239 _DOUBLE(position)
240 _BOOL(smooth_scale)
241 _DOUBLE(audio_volume)
242 _BOOL(audio_mute)
243 _INT(audio_channel)
244 _BOOL(video_mute)
245 _INT(video_channel)
246 _BOOL(spu_mute)
247 _INT(spu_channel)
248 _INT(chapter)
249 _DOUBLE(play_speed)
250 else if (!strcmp(param->name, "play_length"))
251 {
252 ERR("play_length is read-only");
253 return EINA_FALSE;
254 }
255 //_INT(vis);
256#undef _STR
257#undef _BOOL
258#undef _INT
259#undef _DOUBLE
260
261 ERR("unknown parameter '%s' of type '%s'",
262 param->name, edje_external_param_type_str(param->type));
263
264 return EINA_FALSE;
265}
266
267static Eina_Bool
268_external_emotion_param_get(void *data EINA_UNUSED, const Evas_Object *obj, Edje_External_Param *param)
269{
270#define _STR(M) \
271 else if (!strcmp(param->name, #M)) \
272 { \
273 if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING) \
274 { \
275 param->s = emotion_object_##M##_get(obj); \
276 return EINA_TRUE; \
277 } \
278 }
279#define _BOOL(M) \
280 else if (!strcmp(param->name, #M)) \
281 { \
282 if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL) \
283 { \
284 param->i = emotion_object_##M##_get(obj); \
285 return EINA_TRUE; \
286 } \
287 }
288#define _INT(M) \
289 else if (!strcmp(param->name, #M)) \
290 { \
291 if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT) \
292 { \
293 param->i = emotion_object_##M##_get(obj); \
294 return EINA_TRUE; \
295 } \
296 }
297#define _DOUBLE(M) \
298 else if (!strcmp(param->name, #M)) \
299 { \
300 if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE) \
301 { \
302 param->d = emotion_object_##M##_get(obj); \
303 return EINA_TRUE; \
304 } \
305 }
306
307 if (0) {} // so else if works...
308 _STR(file)
309 _BOOL(play)
310 _DOUBLE(position)
311 _BOOL(smooth_scale)
312 _DOUBLE(audio_volume)
313 _BOOL(audio_mute)
314 _INT(audio_channel)
315 _BOOL(video_mute)
316 _INT(video_channel)
317 _BOOL(spu_mute)
318 _INT(spu_channel)
319 _INT(chapter)
320 _DOUBLE(play_speed)
321 _DOUBLE(play_length)
322 //_INT(vis)
323#undef _STR
324#undef _BOOL
325#undef _INT
326#undef _DOUBLE
327
328 ERR("unknown parameter '%s' of type '%s'",
329 param->name, edje_external_param_type_str(param->type));
330
331 return EINA_FALSE;
332}
333
334static void *
335_external_emotion_params_parse(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const Eina_List *params)
336{
337 const Edje_External_Param *param;
338 const Eina_List *l;
339 External_Emotion_Params *p = calloc(1, sizeof(External_Emotion_Params));
340 if (!p) return NULL;
341
342 EINA_LIST_FOREACH(params, l, param)
343 {
344#define _STR(M) \
345 if (!strcmp(param->name, #M)) p->M = eina_stringshare_add(param->s)
346#define _BOOL(M) \
347 if (!strcmp(param->name, #M)) \
348 { \
349 p->M = param->i; \
350 p->M##_exists = EINA_TRUE; \
351 }
352#define _INT(M) \
353 if (!strcmp(param->name, #M)) \
354 { \
355 p->M = param->i; \
356 p->M##_exists = EINA_TRUE; \
357 }
358#define _DOUBLE(M) \
359 if (!strcmp(param->name, #M)) \
360 { \
361 p->M = param->d; \
362 p->M##_exists = EINA_TRUE; \
363 }
364
365 _STR(file);
366 _BOOL(play);
367 _DOUBLE(position);
368 _BOOL(smooth_scale);
369 _DOUBLE(audio_volume);
370 _BOOL(audio_mute);
371 _INT(audio_channel);
372 _BOOL(video_mute);
373 _INT(video_channel);
374 _BOOL(spu_mute);
375 _INT(spu_channel);
376 _INT(chapter);
377 _DOUBLE(play_speed);
378 _DOUBLE(play_length);
379 //_INT(vis);
380#undef _STR
381#undef _BOOL
382#undef _INT
383#undef _DOUBLE
384 }
385
386 return p;
387}
388
389static void
390_external_emotion_params_free(void *params)
391{
392 External_Emotion_Params *p = params;
393
394#define _STR(M) eina_stringshare_del(p->M)
395#define _BOOL(M) do {} while (0)
396#define _INT(M) do {} while (0)
397#define _DOUBLE(M) do {} while (0)
398 _STR(file);
399 _BOOL(play);
400 _DOUBLE(position);
401 _BOOL(smooth_scale);
402 _DOUBLE(audio_volume);
403 _BOOL(audio_mute);
404 _INT(audio_channel);
405 _BOOL(video_mute);
406 _INT(video_channel);
407 _BOOL(spu_mute);
408 _INT(spu_channel);
409 _INT(chapter);
410 _DOUBLE(play_speed);
411 _DOUBLE(play_length);
412 //_INT(vis);
413#undef _STR
414#undef _BOOL
415#undef _INT
416#undef _DOUBLE
417 free(p);
418}
419
420static const char *
421_external_emotion_label_get(void *data EINA_UNUSED)
422{
423 return "Emotion";
424}
425
426static Evas_Object *
427_external_emotion_icon_add(void *data EINA_UNUSED, Evas *e)
428{
429 Evas_Object *ic;
430 int w = 0, h = 0;
431
432 ic = edje_object_add(e);
433 edje_object_file_set(ic, PACKAGE_DATA_DIR"/data/icon.edj", "icon");
434 edje_object_size_min_get(ic, &w, &h);
435 if (w < 1) w = 20;
436 if (h < 1) h = 10;
437 evas_object_size_hint_min_set(ic, w, h);
438 evas_object_size_hint_max_set(ic, w, h);
439
440 return ic;
441}
442
443static const char *
444_external_emotion_translate(void *data EINA_UNUSED, const char *orig)
445{
446 // in future, mark all params as translatable and use dgettext()
447 // with "emotion" text domain here.
448 return orig;
449}
450
451static Edje_External_Param_Info _external_emotion_params[] = {
452 EDJE_EXTERNAL_PARAM_INFO_CHOICE_FULL
453 ("engine", _external_emotion_engine_def, _external_emotion_engines),
454 EDJE_EXTERNAL_PARAM_INFO_STRING("file"),
455 EDJE_EXTERNAL_PARAM_INFO_BOOL_DEFAULT("play", EINA_FALSE),
456 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("position"),
457 EDJE_EXTERNAL_PARAM_INFO_BOOL_DEFAULT("smooth_scale", EINA_FALSE),
458 EDJE_EXTERNAL_PARAM_INFO_DOUBLE_DEFAULT("audio_volume", 0.9),
459 EDJE_EXTERNAL_PARAM_INFO_BOOL_DEFAULT("audio_mute", EINA_FALSE),
460 EDJE_EXTERNAL_PARAM_INFO_INT_DEFAULT("audio_channel", 0),
461 EDJE_EXTERNAL_PARAM_INFO_BOOL_DEFAULT("video_mute", EINA_FALSE),
462 EDJE_EXTERNAL_PARAM_INFO_INT_DEFAULT("video_channel", 0),
463 EDJE_EXTERNAL_PARAM_INFO_BOOL_DEFAULT("spu_mute", EINA_FALSE),
464 EDJE_EXTERNAL_PARAM_INFO_INT_DEFAULT("spu_channel", 0),
465 EDJE_EXTERNAL_PARAM_INFO_INT("chapter"),
466 EDJE_EXTERNAL_PARAM_INFO_DOUBLE_DEFAULT("play_speed", 1.0),
467 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("play_length"),
468 //EDJE_EXTERNAL_PARAM_INFO_CHOICE_FULL("vis", ...),
469 EDJE_EXTERNAL_PARAM_INFO_SENTINEL
470};
471
472static const Edje_External_Type _external_emotion_type = {
473 .abi_version = EDJE_EXTERNAL_TYPE_ABI_VERSION,
474 .module = "emotion",
475 .module_name = "Emotion",
476 .add = _external_emotion_add,
477 .state_set = _external_emotion_state_set,
478 .signal_emit = _external_emotion_signal,
479 .param_set = _external_emotion_param_set,
480 .param_get = _external_emotion_param_get,
481 .params_parse = _external_emotion_params_parse,
482 .params_free = _external_emotion_params_free,
483 .label_get = _external_emotion_label_get,
484 .description_get = NULL,
485 .icon_add = _external_emotion_icon_add,
486 .preview_add = NULL,
487 .translate = _external_emotion_translate,
488 .parameters_info = _external_emotion_params,
489 .data = NULL
490};
491
492static Edje_External_Type_Info _external_emotion_types[] =
493{
494 {"emotion", &_external_emotion_type},
495 {NULL, NULL}
496};
497
498static Eina_Bool
499external_emotion_mod_init(void)
500{
501 _log_dom = eina_log_domain_register
502 ("emotion-externals", EINA_COLOR_LIGHTBLUE);
503 edje_external_type_array_register(_external_emotion_types);
504 return EINA_TRUE;
505}
506
507static void
508external_emotion_mod_shutdown(void)
509{
510 edje_external_type_array_unregister(_external_emotion_types);
511 eina_log_domain_unregister(_log_dom);
512 _log_dom = -1;
513}
514
515EINA_MODULE_INIT(external_emotion_mod_init);
516EINA_MODULE_SHUTDOWN(external_emotion_mod_shutdown);