1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #else
4 #define EFL_BETA_API_SUPPORT
5 #endif
6 
7 #include <Eo.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 
12 #include <Evas.h>
13 #include <Ecore.h>
14 #include <Ecore_Getopt.h>
15 #include <Ecore_Evas.h>
16 #include <Edje.h>
17 
18 #include "Emotion.h"
19 
20 static const Ecore_Getopt options = {
21    "emotion_test",
22    "%prog [options] <filename>",
23    "1.0.0",
24    "(C) 2011-2014 Enlightenment",
25    "BSD\nThis is a 3 clause bsd bla bla",
26    "a simple test program for emotion.",
27    1,
28    {
29       ECORE_GETOPT_STORE_STR('e', "engine", "ecore-evas engine to use"),
30       ECORE_GETOPT_CALLBACK_NOARGS('E', "list-engines", "list ecore-evas engines",
31                                    ecore_getopt_callback_ecore_evas_list_engines, NULL),
32       ECORE_GETOPT_CALLBACK_ARGS('g', "geometry", "geometry to use in x:y:w:h form.", "X:Y:W:H",
33                                  ecore_getopt_callback_geometry_parse, NULL),
34       ECORE_GETOPT_STORE_STR('b', "backend", "backend to use"),
35       ECORE_GETOPT_STORE_INT('v', "vis", "visualization type"),
36       ECORE_GETOPT_STORE_TRUE('w', "webcams", "show all the available v4l streams"),
37       ECORE_GETOPT_STORE_TRUE('r', "reflex", "show video reflex effect"),
38       ECORE_GETOPT_STORE_TRUE('l', "loop", "restart the video when end reached"),
39       ECORE_GETOPT_STORE_TRUE('p', "position", "start the video from last know position"),
40       ECORE_GETOPT_VERSION('V', "version"),
41       ECORE_GETOPT_COPYRIGHT('R', "copyright"),
42       ECORE_GETOPT_LICENSE('L', "license"),
43       ECORE_GETOPT_HELP('h', "help"),
44       ECORE_GETOPT_SENTINEL
45    }
46 };
47 
48 typedef struct _Frame_Data Frame_Data;
49 
50 struct _Frame_Data
51 {
52    unsigned char moving : 1;
53    unsigned char resizing : 1;
54    int        button;
55    Evas_Coord x, y;
56 };
57 
58 static void bg_key_down(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED);
59 
60 
61 static Evas_Object *o_bg = NULL;
62 
63 static Ecore_Evas  *ecore_evas = NULL;
64 static Evas        *evas       = NULL;
65 static int          startw     = 800;
66 static int          starth     = 600;
67 
68 static Eina_List   *video_objs = NULL;
69 static Emotion_Vis  vis        = EMOTION_VIS_NONE;
70 static unsigned char reflex    = 0;
71 static unsigned char loop      = 0;
72 static unsigned char last_position_load  = 0;
73 static const char  *theme_file = NULL;
74 
75 static void
bg_resize(Evas_Coord w,Evas_Coord h)76 bg_resize(Evas_Coord w, Evas_Coord h)
77 {
78    efl_gfx_entity_size_set(o_bg, EINA_SIZE2D(w,  h));
79 }
80 
81 static void
main_resize(Ecore_Evas * ee)82 main_resize(Ecore_Evas *ee)
83 {
84    Evas_Coord w, h;
85 
86    evas_output_viewport_get(ecore_evas_get(ee), NULL, NULL, &w, &h);
87    bg_resize(w, h);
88 }
89 
90 static Eina_Bool
main_signal_exit(void * data EINA_UNUSED,int ev_type EINA_UNUSED,void * ev EINA_UNUSED)91 main_signal_exit(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
92 {
93    Evas_Object *o;
94 
95    ecore_main_loop_quit();
96    EINA_LIST_FREE(video_objs, o)
97      {
98         emotion_object_last_position_save(o);
99         efl_del(o);
100      }
101    return EINA_TRUE;
102 }
103 
104 static void
main_delete_request(Ecore_Evas * ee EINA_UNUSED)105 main_delete_request(Ecore_Evas *ee EINA_UNUSED)
106 {
107    ecore_main_loop_quit();
108 }
109 
110 static void
bg_setup(void)111 bg_setup(void)
112 {
113    o_bg = efl_add(EFL_CANVAS_LAYOUT_CLASS, evas);
114    efl_file_simple_load(o_bg, theme_file, "background");
115    efl_gfx_entity_position_set(o_bg, EINA_POSITION2D(0, 0));
116    efl_gfx_entity_size_set(o_bg, EINA_SIZE2D(startw,  starth));
117    efl_gfx_stack_layer_set(o_bg, -999);
118    efl_gfx_entity_visible_set(o_bg, EINA_TRUE);
119    evas_object_focus_set(o_bg, EINA_TRUE);
120    efl_event_callback_add(o_bg, EFL_EVENT_KEY_DOWN, bg_key_down, NULL);
121 }
122 
123 static void
broadcast_event(Emotion_Event ev)124 broadcast_event(Emotion_Event ev)
125 {
126    Eina_List *l;
127    Evas_Object *obj;
128 
129    EINA_LIST_FOREACH(video_objs, l, obj)
130      emotion_object_event_simple_send(obj, ev);
131 }
132 
133 static void
bg_key_down(void * data EINA_UNUSED,const Efl_Event * event)134 bg_key_down(void *data EINA_UNUSED, const Efl_Event *event)
135 {
136    Efl_Input_Key *ev = event->info;
137    Eina_List *l;
138    Evas_Object *o;
139    const char *keyname = efl_input_key_name_get(ev);
140 
141    if (!keyname) return;
142 
143    if      (!strcmp(keyname, "Escape"))
144      ecore_main_loop_quit();
145    else if (!strcmp(keyname, "Up"))
146      broadcast_event(EMOTION_EVENT_UP);
147    else if (!strcmp(keyname, "Down"))
148      broadcast_event(EMOTION_EVENT_DOWN);
149    else if (!strcmp(keyname, "Left"))
150      broadcast_event(EMOTION_EVENT_LEFT);
151    else if (!strcmp(keyname, "Right"))
152      broadcast_event(EMOTION_EVENT_RIGHT);
153    else if (!strcmp(keyname, "Return"))
154      broadcast_event(EMOTION_EVENT_SELECT);
155    else if (!strcmp(keyname, "m"))
156      broadcast_event(EMOTION_EVENT_MENU1);
157    else if (!strcmp(keyname, "Prior"))
158      broadcast_event(EMOTION_EVENT_PREV);
159    else if (!strcmp(keyname, "Next"))
160      broadcast_event(EMOTION_EVENT_NEXT);
161    else if (!strcmp(keyname, "0"))
162      broadcast_event(EMOTION_EVENT_0);
163    else if (!strcmp(keyname, "1"))
164      broadcast_event(EMOTION_EVENT_1);
165    else if (!strcmp(keyname, "2"))
166      broadcast_event(EMOTION_EVENT_2);
167    else if (!strcmp(keyname, "3"))
168      broadcast_event(EMOTION_EVENT_3);
169    else if (!strcmp(keyname, "4"))
170      broadcast_event(EMOTION_EVENT_4);
171    else if (!strcmp(keyname, "5"))
172      broadcast_event(EMOTION_EVENT_5);
173    else if (!strcmp(keyname, "6"))
174      broadcast_event(EMOTION_EVENT_6);
175    else if (!strcmp(keyname, "7"))
176      broadcast_event(EMOTION_EVENT_7);
177    else if (!strcmp(keyname, "8"))
178      broadcast_event(EMOTION_EVENT_8);
179    else if (!strcmp(keyname, "9"))
180      broadcast_event(EMOTION_EVENT_9);
181    else if (!strcmp(keyname, "-"))
182      broadcast_event(EMOTION_EVENT_10);
183    else if (!strcmp(keyname, "v"))
184      {
185         EINA_LIST_FOREACH(video_objs, l, o)
186           {
187              if (emotion_object_video_mute_get(o))
188                emotion_object_video_mute_set(o, EINA_FALSE);
189              else
190                emotion_object_video_mute_set(o, EINA_TRUE);
191           }
192      }
193    else if (!strcmp(keyname, "a"))
194      {
195         EINA_LIST_FOREACH(video_objs, l, o)
196           {
197             if (emotion_object_audio_mute_get(o))
198               {
199                  emotion_object_audio_mute_set(o, EINA_FALSE);
200                  printf("unmute\n");
201               }
202             else
203               {
204                  emotion_object_audio_mute_set(o, EINA_TRUE);
205                  printf("mute\n");
206               }
207           }
208      }
209    else if (!strcmp(keyname, "i"))
210      {
211         EINA_LIST_FOREACH(video_objs, l, o)
212           {
213              printf("audio channels: %i\n", emotion_object_audio_channel_count(o));
214              printf("video channels: %i\n", emotion_object_video_channel_count(o));
215              printf("spu channels: %i\n", emotion_object_spu_channel_count(o));
216              printf("seekable: %i\n", emotion_object_seekable_get(o));
217           }
218      }
219    else if (!strcmp(keyname, "f"))
220      {
221        if (!ecore_evas_fullscreen_get(ecore_evas))
222          ecore_evas_fullscreen_set(ecore_evas, EINA_TRUE);
223        else
224          ecore_evas_fullscreen_set(ecore_evas, EINA_FALSE);
225      }
226    else if (!strcmp(keyname, "d"))
227      {
228         if (!ecore_evas_avoid_damage_get(ecore_evas))
229           ecore_evas_avoid_damage_set(ecore_evas, EINA_TRUE);
230         else
231           ecore_evas_avoid_damage_set(ecore_evas, EINA_FALSE);
232      }
233    else if (!strcmp(keyname, "s"))
234      {
235         if (!ecore_evas_shaped_get(ecore_evas))
236           {
237              ecore_evas_shaped_set(ecore_evas, EINA_TRUE);
238              evas_object_hide(o_bg);
239           }
240         else
241           {
242              ecore_evas_shaped_set(ecore_evas, EINA_FALSE);
243              evas_object_show(o_bg);
244           }
245      }
246    else if (!strcmp(keyname, "b"))
247      {
248         if (!ecore_evas_borderless_get(ecore_evas))
249           ecore_evas_borderless_set(ecore_evas, EINA_TRUE);
250         else
251           ecore_evas_borderless_set(ecore_evas, EINA_FALSE);
252      }
253    else if (!strcmp(keyname, "q"))
254      {
255         ecore_main_loop_quit();
256         while (video_objs)
257           {
258              printf("del obj!\n");
259              evas_object_del(video_objs->data);
260              video_objs = eina_list_remove_list(video_objs, video_objs);
261              printf("done\n");
262           }
263      }
264    else if (!strcmp(keyname, "z"))
265      {
266         vis = (vis + 1) % EMOTION_VIS_LAST;
267         printf("new visualization: %d\n", vis);
268 
269         EINA_LIST_FOREACH(video_objs, l, o)
270           {
271              Eina_Bool supported;
272 
273              supported = emotion_object_vis_supported(o, vis);
274              if (supported)
275                emotion_object_vis_set(o, vis);
276              else
277                {
278                   const char *file;
279 
280                   file = emotion_object_file_get(o);
281                   printf("object %p (%s) does not support visualization %d\n",
282                   o, file, vis);
283                }
284           }
285      }
286    else
287      {
288         printf("UNHANDLED: %s\n", keyname);
289      }
290 }
291 
292 static void
_oe_free_cb(void * data,const Efl_Event * event EINA_UNUSED)293 _oe_free_cb(void *data, const Efl_Event *event EINA_UNUSED)
294 {
295    free(data);
296 }
297 
298 static void
video_obj_time_changed(Evas_Object * obj,Evas_Object * edje)299 video_obj_time_changed(Evas_Object *obj, Evas_Object *edje)
300 {
301    double pos, len, scale;
302    char buf[256];
303    int ph, pm, ps, pf, lh, lm, ls;
304 
305    pos = emotion_object_position_get(obj);
306    len = emotion_object_play_length_get(obj);
307    scale = (len > 0.0) ? pos / len : 0.0;
308    efl_ui_drag_value_set(efl_part(edje, "video_progress"), scale, 0.0);
309 
310    lh = len / 3600;
311    lm = len / 60 - (lh * 60);
312    ls = len - (lh * 3600) - (lm * 60);
313 
314    ph = pos / 3600;
315    pm = pos / 60 - (ph * 60);
316    ps = pos - (ph * 3600) - (pm * 60);
317 
318    pf = pos * 100 - (ps * 100) - (pm * 60 * 100) - (ph * 60 * 60 * 100);
319 
320    snprintf(buf, sizeof(buf), "%i:%02i:%02i.%02i / %i:%02i:%02i",
321             ph, pm, ps, pf, lh, lm, ls);
322    efl_text_set(efl_part(edje, "video_progress_txt"), buf);
323 }
324 
325 static void
video_obj_frame_decode_cb(void * data,const Efl_Event * event)326 video_obj_frame_decode_cb(void *data, const Efl_Event *event)
327 {
328    video_obj_time_changed(event->object, data);
329 
330    if (0)
331      {
332         double t;
333         static double pt = 0.0;
334         t = ecore_time_get();
335         printf("FPS: %3.3f\n", 1.0 / (t - pt));
336         pt = t;
337      }
338 }
339 
340 static void
video_obj_frame_resize_cb(void * data,const Efl_Event * event)341 video_obj_frame_resize_cb(void *data, const Efl_Event *event)
342 {
343    Evas_Object *oe;
344    int iw, ih;
345    Evas_Coord w, h;
346    double ratio;
347 
348    oe = data;
349    emotion_object_size_get(event->object, &iw, &ih);
350    ratio = emotion_object_ratio_get(event->object);
351    printf("HANDLE %ix%i @ %3.3f\n", iw, ih, ratio);
352    if (ratio > 0.0) iw = (ih * ratio) + 0.5;
353    evas_object_size_hint_min_set(event->object, iw, ih);
354    edje_object_part_swallow(oe, "video_swallow", event->object);
355    edje_object_size_min_calc(oe, &w, &h);
356    efl_gfx_entity_size_set(oe, EINA_SIZE2D(w,  h));
357    evas_object_size_hint_min_set(event->object, 0, 0);
358    edje_object_part_swallow(oe, "video_swallow", event->object);
359 }
360 
361 static void
video_obj_length_change_cb(void * data,const Efl_Event * event)362 video_obj_length_change_cb(void *data, const Efl_Event *event)
363 {
364    printf("len change!\n");
365    video_obj_time_changed(event->object, data);
366 }
367 
368 static void
video_obj_position_update_cb(void * data,const Efl_Event * event)369 video_obj_position_update_cb(void *data, const Efl_Event *event)
370 {
371    printf("pos up!\n");
372    video_obj_time_changed(event->object, data);
373 }
374 
375 static void
video_obj_stopped_cb(void * data EINA_UNUSED,const Efl_Event * event)376 video_obj_stopped_cb(void *data EINA_UNUSED, const Efl_Event *event)
377 {
378    printf("video stopped!!!\n");
379    if (loop)
380      {
381         emotion_object_position_set(event->object, 0.0);
382         emotion_object_play_set(event->object, EINA_TRUE);
383      }
384 }
385 
386 static void
video_obj_channels_cb(void * data EINA_UNUSED,const Efl_Event * event)387 video_obj_channels_cb(void *data EINA_UNUSED, const Efl_Event *event)
388 {
389    printf("channels changed: [AUD %i][VID %i][SPU %i]\n",
390           emotion_object_audio_channel_count(event->object),
391           emotion_object_video_channel_count(event->object),
392           emotion_object_spu_channel_count(event->object));
393 }
394 
395 static void
video_obj_title_cb(void * data EINA_UNUSED,const Efl_Event * event)396  video_obj_title_cb(void *data EINA_UNUSED, const Efl_Event *event)
397 {
398    printf("video title to: \"%s\"\n", emotion_object_title_get(event->object));
399 }
400 
401 static void
video_obj_progress_cb(void * data EINA_UNUSED,const Efl_Event * event)402 video_obj_progress_cb(void *data EINA_UNUSED, const Efl_Event *event)
403 {
404    printf("progress: \"%s\" %3.3f\n",
405           emotion_object_progress_info_get(event->object),
406           emotion_object_progress_status_get(event->object));
407 }
408 
409 static void
video_obj_ref_cb(void * data EINA_UNUSED,const Efl_Event * event)410 video_obj_ref_cb(void *data EINA_UNUSED, const Efl_Event *event)
411 {
412    printf("video ref to: \"%s\" %i\n",
413           emotion_object_ref_file_get(event->object),
414           emotion_object_ref_num_get(event->object));
415 }
416 
417 static void
video_obj_button_num_cb(void * data EINA_UNUSED,const Efl_Event * event)418 video_obj_button_num_cb(void *data EINA_UNUSED, const Efl_Event *event)
419 {
420    printf("video spu buttons to: %i\n",
421           emotion_object_spu_button_count_get(event->object));
422 }
423 
424 static void
video_obj_button_cb(void * data EINA_UNUSED,const Efl_Event * event)425 video_obj_button_cb(void *data EINA_UNUSED, const Efl_Event *event)
426 {
427    printf("video selected spu button: %i\n",
428           emotion_object_spu_button_get(event->object));
429 }
430 
431 static void
video_obj_signal_play_cb(void * data,Evas_Object * o,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)432 video_obj_signal_play_cb(void *data, Evas_Object *o, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
433 {
434    Evas_Object *ov = data;
435    emotion_object_play_set(ov, EINA_TRUE);
436    efl_layout_signal_emit(o, "video_state", "play");
437 }
438 
439 static void
video_obj_signal_pause_cb(void * data,Evas_Object * o,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)440 video_obj_signal_pause_cb(void *data, Evas_Object *o, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
441 {
442    Evas_Object *ov = data;
443    emotion_object_play_set(ov, EINA_FALSE);
444    efl_layout_signal_emit(o, "video_state", "pause");
445 }
446 
447 static void
video_obj_signal_stop_cb(void * data,Evas_Object * o,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)448 video_obj_signal_stop_cb(void *data, Evas_Object *o, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
449 {
450    Evas_Object *ov = data;
451    emotion_object_play_set(ov, EINA_FALSE);
452    emotion_object_position_set(ov, 0.0);
453    efl_layout_signal_emit(o, "video_state", "stop");
454 }
455 
456 static void
video_obj_signal_jump_cb(void * data,Evas_Object * o,const char * emission EINA_UNUSED,const char * source)457 video_obj_signal_jump_cb(void *data, Evas_Object *o, const char *emission EINA_UNUSED, const char *source)
458 {
459    Evas_Object *ov = data;
460    double len;
461    double x, y;
462 
463    efl_ui_drag_value_get(efl_part(o, source), &x, &y);
464    len = emotion_object_play_length_get(ov);
465    emotion_object_position_set(ov, x * len);
466 }
467 
468 static void
video_obj_signal_alpha_cb(void * data,Evas_Object * o,const char * emission EINA_UNUSED,const char * source)469 video_obj_signal_alpha_cb(void *data, Evas_Object *o, const char *emission EINA_UNUSED, const char *source)
470 {
471    Evas_Object *ov = data;
472    double alpha;
473    double x, y;
474    char buf[256];
475 
476    efl_ui_drag_value_get(efl_part(o, source), &x, &y);
477    alpha = 255 * y;
478    efl_gfx_color_set(ov, alpha, alpha, alpha, alpha);
479    snprintf(buf, sizeof(buf), "alpha %.0f", alpha);
480    efl_text_set(efl_part(o, "video_alpha_txt"), buf);
481 }
482 
483 static void
video_obj_signal_vol_cb(void * data,Evas_Object * o,const char * emission EINA_UNUSED,const char * source)484 video_obj_signal_vol_cb(void *data, Evas_Object *o, const char *emission EINA_UNUSED, const char *source)
485 {
486    Evas_Object *ov = data;
487    double vol;
488    char buf[256];
489 
490    efl_ui_drag_value_get(efl_part(o, source), NULL, &vol);
491    emotion_object_audio_volume_set(ov, vol);
492    snprintf(buf, sizeof(buf), "vol %.2f", vol);
493    efl_text_set(efl_part(o, "video_volume_txt"), buf);
494 }
495 
496 static void
video_obj_signal_frame_move_start_cb(void * data EINA_UNUSED,Evas_Object * o,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)497 video_obj_signal_frame_move_start_cb(void *data EINA_UNUSED, Evas_Object *o, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
498 {
499    Frame_Data *fd;
500    Evas_Coord x, y;
501 
502    fd = efl_key_data_get(o, "frame_data");
503    if (!fd) return;
504    fd->moving = 1;
505    evas_pointer_canvas_xy_get(evas_object_evas_get(o), &x, &y);
506    fd->x = x;
507    fd->y = y;
508    efl_gfx_stack_raise_to_top(o);
509 }
510 
511 static void
video_obj_signal_frame_move_stop_cb(void * data EINA_UNUSED,Evas_Object * o,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)512 video_obj_signal_frame_move_stop_cb(void *data EINA_UNUSED, Evas_Object *o, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
513 {
514    Frame_Data *fd;
515 
516    fd = efl_key_data_get(o, "frame_data");
517    if (!fd) return;
518    fd->moving = 0;
519 }
520 
521 static void
video_obj_signal_frame_resize_start_cb(void * data EINA_UNUSED,Evas_Object * o,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)522 video_obj_signal_frame_resize_start_cb(void *data EINA_UNUSED, Evas_Object *o, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
523 {
524    Frame_Data *fd;
525    Evas_Coord x, y;
526 
527    fd = efl_key_data_get(o, "frame_data");
528    if (!fd) return;
529    fd->resizing = 1;
530    evas_pointer_canvas_xy_get(evas_object_evas_get(o), &x, &y);
531    fd->x = x;
532    fd->y = y;
533    efl_gfx_stack_raise_to_top(o);
534 }
535 
536 static void
video_obj_signal_frame_resize_stop_cb(void * data EINA_UNUSED,Evas_Object * o,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)537 video_obj_signal_frame_resize_stop_cb(void *data EINA_UNUSED, Evas_Object *o, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
538 {
539    Frame_Data *fd;
540 
541    fd = efl_key_data_get(o, "frame_data");
542    if (!fd) return;
543    fd->resizing = 0;
544 }
545 
546 static void
video_obj_signal_frame_move_cb(void * data EINA_UNUSED,Evas_Object * o,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)547 video_obj_signal_frame_move_cb(void *data EINA_UNUSED, Evas_Object *o, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
548 {
549    Frame_Data *fd;
550 
551    fd = efl_key_data_get(o, "frame_data");
552    if (!fd) return;
553    if (fd->moving)
554      {
555         Evas_Coord x, y;
556         Eina_Position2D pos;
557 
558         evas_pointer_canvas_xy_get(evas_object_evas_get(o), &x, &y);
559         pos = efl_gfx_entity_position_get(o);
560         pos.x += (x - fd->x);
561         pos.y += (y - fd->y);
562         efl_gfx_entity_position_set(o, pos);
563         fd->x = x;
564         fd->y = y;
565      }
566    else if (fd->resizing)
567      {
568         Evas_Coord x, y;
569         Eina_Size2D sz;
570 
571         evas_pointer_canvas_xy_get(evas_object_evas_get(o), &x, &y);
572         sz = efl_gfx_entity_size_get(o);
573         evas_object_resize(o, sz.w + (x - fd->x), sz.h + (y - fd->y));
574         fd->x = x;
575         fd->y = y;
576      }
577 }
578 
579 EFL_CALLBACKS_ARRAY_DEFINE(emotion_object_test_callbacks,
580        { EFL_CANVAS_VIDEO_EVENT_FRAME_DECODE, video_obj_frame_decode_cb },
581        { EFL_CANVAS_VIDEO_EVENT_FRAME_RESIZE, video_obj_frame_resize_cb },
582        { EFL_CANVAS_VIDEO_EVENT_LENGTH_CHANGE, video_obj_length_change_cb },
583        { EFL_CANVAS_VIDEO_EVENT_POSITION_CHANGE, video_obj_position_update_cb },
584        { EFL_CANVAS_VIDEO_EVENT_PLAYBACK_STOP, video_obj_stopped_cb },
585        { EFL_CANVAS_VIDEO_EVENT_CHANNELS_CHANGE, video_obj_channels_cb },
586        { EFL_CANVAS_VIDEO_EVENT_TITLE_CHANGE, video_obj_title_cb },
587        { EFL_CANVAS_VIDEO_EVENT_PROGRESS_CHANGE, video_obj_progress_cb },
588        { EFL_CANVAS_VIDEO_EVENT_REF_CHANGE, video_obj_ref_cb },
589        { EFL_CANVAS_VIDEO_EVENT_BUTTON_NUM_CHANGE, video_obj_button_num_cb },
590        { EFL_CANVAS_VIDEO_EVENT_BUTTON_CHANGE, video_obj_button_cb }
591 );
592 
593 static void
init_video_object(const char * module_filename,const char * filename)594 init_video_object(const char *module_filename, const char *filename)
595 {
596    Evas_Object *o, *oe;
597    Evas_Coord w, h, offset;
598    Frame_Data *fd;
599 
600    /* basic video object setup */
601    o = emotion_object_add(evas);
602    if ((module_filename) && (!emotion_object_init(o, module_filename)))
603      return;
604    emotion_object_vis_set(o, vis);
605    if (!emotion_object_file_set(o, filename))
606      return;
607    if (last_position_load)
608      emotion_object_last_position_load(o);
609    emotion_object_play_set(o, 1);
610    emotion_object_audio_volume_set(o, 0.5);
611    evas_object_move(o, 0, 0);
612    evas_object_resize(o, 320, 240);
613    emotion_object_smooth_scale_set(o, 1);
614    evas_object_show(o);
615 
616    video_objs = eina_list_append(video_objs, o);
617    /* end basic video setup. all the rest here is just to be fancy */
618 
619 
620    fd = calloc(1, sizeof(Frame_Data));
621    if (!fd) exit(1);
622 
623    oe = efl_add(EFL_CANVAS_LAYOUT_CLASS, evas);
624    efl_event_callback_add(oe, EFL_EVENT_DEL, _oe_free_cb, fd);
625    efl_key_data_set(oe, "frame_data", fd);
626    efl_file_simple_load(oe, theme_file, reflex ? "video_controller/reflex" : "video_controller");
627    edje_object_part_swallow(oe, "video_swallow", o);
628 
629    offset = 20 * (eina_list_count(video_objs) - 1);
630    efl_gfx_entity_position_set(oe, EINA_POSITION2D(offset, offset));
631    edje_object_size_min_calc(oe, &w, &h);
632    efl_gfx_entity_size_set(oe, EINA_SIZE2D(w,  h));
633 
634    efl_event_callback_array_add(o, emotion_object_test_callbacks(), oe);
635 
636    efl_layout_signal_callback_add(oe, "video_control", "play", o, video_obj_signal_play_cb, NULL);
637    efl_layout_signal_callback_add(oe, "video_control", "pause", o, video_obj_signal_pause_cb, NULL);
638    efl_layout_signal_callback_add(oe, "video_control", "stop", o, video_obj_signal_stop_cb, NULL);
639    efl_layout_signal_callback_add(oe, "drag", "video_progress", o, video_obj_signal_jump_cb, NULL);
640    efl_layout_signal_callback_add(oe, "drag", "video_alpha", o, video_obj_signal_alpha_cb, NULL);
641    efl_layout_signal_callback_add(oe, "drag", "video_volume", o, video_obj_signal_vol_cb, NULL);
642    efl_layout_signal_callback_add(oe, "frame_move", "start", oe, video_obj_signal_frame_move_start_cb, NULL);
643    efl_layout_signal_callback_add(oe, "frame_move", "stop", oe, video_obj_signal_frame_move_stop_cb, NULL);
644    efl_layout_signal_callback_add(oe, "frame_resize", "start", oe, video_obj_signal_frame_resize_start_cb, NULL);
645    efl_layout_signal_callback_add(oe, "frame_resize", "stop", oe, video_obj_signal_frame_resize_stop_cb, NULL);
646    efl_layout_signal_callback_add(oe, "mouse, move", "*", oe, video_obj_signal_frame_move_cb, NULL);
647    efl_ui_drag_value_set(efl_part(oe, "video_alpha"), 0.0, 1.0);
648    efl_text_set(efl_part(oe, "video_alpha_txt"), "alpha 255");
649    efl_ui_drag_value_set(efl_part(oe, "video_volume"), 0.0, 0.5);
650    efl_text_set(efl_part(oe, "video_volume_txt"), "vol 0.50");
651    efl_layout_signal_emit(oe, "video_state", "play");
652    efl_gfx_entity_visible_set(oe, EINA_TRUE);
653 }
654 
655 int
main(int argc,char ** argv)656 main(int argc, char **argv)
657 {
658    int args;
659    Eina_Rectangle     geometry = {0, 0, startw, starth};
660    char              *engine = NULL;
661    char              *backend = NULL;
662    Eina_Bool          webcams = EINA_FALSE;
663    int                visual = EMOTION_VIS_NONE;
664    unsigned char      help = 0;
665    unsigned char      engines_listed = 0;
666    Ecore_Getopt_Value values[] = {
667       ECORE_GETOPT_VALUE_STR(engine),
668       ECORE_GETOPT_VALUE_BOOL(engines_listed),
669       ECORE_GETOPT_VALUE_PTR_CAST(geometry),
670       ECORE_GETOPT_VALUE_STR(backend),
671       ECORE_GETOPT_VALUE_INT(visual),
672       ECORE_GETOPT_VALUE_BOOL(webcams),
673       ECORE_GETOPT_VALUE_BOOL(reflex),
674       ECORE_GETOPT_VALUE_BOOL(loop),
675       ECORE_GETOPT_VALUE_BOOL(last_position_load),
676       ECORE_GETOPT_VALUE_NONE,
677       ECORE_GETOPT_VALUE_NONE,
678       ECORE_GETOPT_VALUE_NONE,
679       ECORE_GETOPT_VALUE_BOOL(help),
680       ECORE_GETOPT_VALUE_NONE
681     };
682 
683    // init ecore_evas
684    if (!ecore_evas_init())
685      return -1;
686 
687    // init edje
688    if (!edje_init())
689      goto shutdown_ecore_evas;
690    edje_frametime_set(1.0 / 30.0);
691 
692    // search the theme file
693    struct stat st;
694    if (stat(PACKAGE_BUILD_DIR"/src/tests/emotion/data/theme.edj", &st) == 0)
695       theme_file = PACKAGE_BUILD_DIR"/src/tests/emotion/data/theme.edj";
696    else if (stat(PACKAGE_DATA_DIR"/data/theme.edj", &st) == 0)
697       theme_file = PACKAGE_DATA_DIR"/data/theme.edj";
698    else
699      {
700         printf("Cannot find the theme file\n");
701         goto shutdown_edje;
702      }
703    printf("theme file: %s\n", theme_file);
704 
705    // parse command line arguments
706    ecore_app_args_set(argc, (const char **)argv);
707    args = ecore_getopt_parse(&options, values, argc, argv);
708    if (args < 0) goto shutdown_edje;
709    else if (help) goto shutdown_edje;
710    else if (engines_listed) goto shutdown_edje;
711    else if ((args == argc) && (!webcams))
712      {
713         printf("must provide at least one file to play!\n");
714         goto shutdown_edje;
715      }
716    if (geometry.w == 0) geometry.w = 320;
717    if (geometry.h == 0) geometry.h = 240;
718    vis = visual;
719 
720    printf("evas engine: %s\n", engine ? engine : "<auto>");
721    printf("emotion backend: %s\n", backend ? backend : "<auto>");
722    printf("vis: %d\n", vis);
723    printf("geometry: %d %d %dx%d\n", geometry.x, geometry.y, geometry.w, geometry.h);
724 
725    ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, main_signal_exit, NULL);
726 
727    // create the ecore_evas window
728    ecore_evas = ecore_evas_new(engine, geometry.x, geometry.y,
729                                geometry.w, geometry.h, NULL);
730    if (!ecore_evas) goto shutdown_edje;
731    ecore_evas_callback_delete_request_set(ecore_evas, main_delete_request);
732    ecore_evas_callback_resize_set(ecore_evas, main_resize);
733    ecore_evas_title_set(ecore_evas, "Evas Media Test Program");
734    ecore_evas_name_class_set(ecore_evas, "evas_media_test", "main");
735    ecore_evas_show(ecore_evas);
736    evas = ecore_evas_get(ecore_evas);
737    evas_image_cache_set(evas, 8 * 1024 * 1024);
738    evas_font_cache_set(evas, 1 * 1024 * 1024);
739 
740    // init emotion
741    emotion_init();
742 
743    // create the checkboard background edje object
744    bg_setup();
745 
746    // open files and webcams
747    for (; args < argc; args++)
748      init_video_object(backend, argv[args]);
749 
750    if (webcams)
751      {
752         const Eina_List *wl, *l;
753         Emotion_Webcam *webcam;
754 
755         wl = emotion_webcams_get();
756         EINA_LIST_FOREACH(wl, l, webcam)
757           {
758              printf("Playing stream: '%s' url: '%s'\n",
759                      emotion_webcam_name_get(webcam),
760                      emotion_webcam_device_get(webcam));
761              init_video_object(backend, emotion_webcam_device_get(webcam));
762           }
763      }
764 
765    // start the main loop
766    ecore_main_loop_begin();
767 
768    // shutdown
769    main_signal_exit(NULL, 0, NULL);
770 
771    emotion_shutdown();
772    ecore_evas_free(ecore_evas);
773    ecore_evas_shutdown();
774    edje_shutdown();
775 
776    return 0;
777 
778  shutdown_edje:
779    edje_shutdown();
780  shutdown_ecore_evas:
781    ecore_evas_shutdown();
782 
783    return -1;
784 }
785