0526bb1f07d830f4cfc96f8159fab7eeb47dc8c4
[profile/ivi/emotion.git] / src / lib / emotion_smart.c
1 #include "emotion_private.h"
2 #include "Emotion.h"
3
4 #define E_SMART_OBJ_GET(smart, o, type) \
5      { \
6         char *_e_smart_str; \
7         \
8         if (!o) return; \
9         smart = evas_object_smart_data_get(o); \
10         if (!smart) return; \
11         _e_smart_str = (char *)evas_object_type_get(o); \
12         if (!_e_smart_str) return; \
13         if (strcmp(_e_smart_str, type)) return; \
14      }
15
16 #define E_SMART_OBJ_GET_RETURN(smart, o, type, ret) \
17    { \
18       char *_e_smart_str; \
19       \
20       if (!o) return ret; \
21       smart = evas_object_smart_data_get(o); \
22       if (!smart) return ret; \
23       _e_smart_str = (char *)evas_object_type_get(o); \
24       if (!_e_smart_str) return ret; \
25       if (strcmp(_e_smart_str, type)) return ret; \
26    }
27
28 #define DBG(...) EINA_LOG_DOM_DBG(_log_domain, __VA_ARGS__)
29 #define INF(...) EINA_LOG_DOM_INFO(_log_domain, __VA_ARGS__)
30 #define WRN(...) EINA_LOG_DOM_WARN(_log_domain, __VA_ARGS__)
31 #define ERR(...) EINA_LOG_DOM_ERR(_log_domain, __VA_ARGS__)
32 #define CRITICAL(...) EINA_LOG_DOM_CRIT(_log_domain, __VA_ARGS__)
33
34 #define E_OBJ_NAME "emotion_object"
35
36 typedef struct _Smart_Data Smart_Data;
37
38 struct _Smart_Data
39 {
40    Emotion_Video_Module  *module;
41    void                  *video;
42
43    char                  *module_name;
44
45    char          *file;
46    Evas_Object   *obj;
47    double         ratio;
48    double         pos;
49    double         seek_pos;
50    double         len;
51
52    Ecore_Job     *job;
53
54    unsigned char  play : 1;
55    unsigned char  seek : 1;
56    unsigned char  seeking : 1;
57
58    char *title;
59    struct {
60       char   *info;
61       double  stat;
62    } progress;
63    struct {
64       char *file;
65       int   num;
66    } ref;
67    struct {
68       int button_num;
69       int button;
70    } spu;
71
72    Emotion_Module_Options module_options;
73 };
74
75 static void _mouse_move(void *data, Evas *ev, Evas_Object *obj, void *event_info);
76 static void _mouse_down(void *data, Evas *ev, Evas_Object *obj, void *event_info);
77 static void _pos_set_job(void *data);
78 static void _pixels_get(void *data, Evas_Object *obj);
79
80 static void _smart_init(void);
81 static void _smart_add(Evas_Object * obj);
82 static void _smart_del(Evas_Object * obj);
83 static void _smart_move(Evas_Object * obj, Evas_Coord x, Evas_Coord y);
84 static void _smart_resize(Evas_Object * obj, Evas_Coord w, Evas_Coord h);
85 static void _smart_show(Evas_Object * obj);
86 static void _smart_hide(Evas_Object * obj);
87 static void _smart_color_set(Evas_Object * obj, int r, int g, int b, int a);
88 static void _smart_clip_set(Evas_Object * obj, Evas_Object * clip);
89 static void _smart_clip_unset(Evas_Object * obj);
90
91 /**********************************/
92 /* Globals for the E Video Object */
93 /**********************************/
94 static Evas_Smart  *smart = NULL;
95 static Eina_Hash *_backends = NULL;
96 static Eina_Array *_modules = NULL;
97 static int _log_domain = -1;
98
99 static const char *_backend_priority[] = {
100   "xine",
101   "gstreamer",
102   "vlc"
103 };
104
105 static const char SIG_FRAME_DECODE[] = "frame_decode";
106 static const char SIG_POSITION_UPDATE[] = "position_update";
107 static const char SIG_LENGTH_CHANGE[] = "length_change";
108 static const char SIG_FRAME_RESIZE[] = "frame_resize";
109 static const char SIG_DECODE_STOP[] = "decode_stop";
110 static const char SIG_PLAYBACK_STARTED[] = "playback_started";
111 static const char SIG_PLAYBACK_FINISHED[] = "playback_finished";
112 static const char SIG_AUDIO_LEVEL_CHANGE[] = "audio_level_change";
113 static const char SIG_CHANNELS_CHANGE[] = "channels_change";
114 static const char SIG_TITLE_CHANGE[] = "title_change";
115 static const char SIG_PROGRESS_CHANGE[] = "progress_change";
116 static const char SIG_REF_CHANGE[] = "ref_change";
117 static const char SIG_BUTTON_NUM_CHANGE[] = "button_num_change";
118 static const char SIG_BUTTON_CHANGE[] = "button_change";
119 static const char SIG_OPEN_DONE[] = "open_done";
120 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
121   {SIG_FRAME_DECODE, ""},
122   {SIG_POSITION_UPDATE, ""},
123   {SIG_LENGTH_CHANGE, ""},
124   {SIG_FRAME_RESIZE, ""},
125   {SIG_DECODE_STOP, ""},
126   {SIG_PLAYBACK_STARTED, ""},
127   {SIG_PLAYBACK_FINISHED, ""},
128   {SIG_AUDIO_LEVEL_CHANGE, ""},
129   {SIG_CHANNELS_CHANGE, ""},
130   {SIG_TITLE_CHANGE, ""},
131   {SIG_PROGRESS_CHANGE, ""},
132   {SIG_REF_CHANGE, ""},
133   {SIG_BUTTON_NUM_CHANGE, ""},
134   {SIG_BUTTON_CHANGE, ""},
135   {SIG_OPEN_DONE, ""},
136   {NULL, NULL}
137 };
138
139
140 EAPI Eina_Bool
141  _emotion_module_register(const char *name, Emotion_Module_Open open, Emotion_Module_Close close)
142 {
143    Eina_Emotion_Plugins *plugin;
144
145    plugin = malloc(sizeof (Eina_Emotion_Plugins));
146    if (!plugin) return EINA_FALSE;
147
148    plugin->open = open;
149    plugin->close = close;
150
151    return eina_hash_add(_backends, name, plugin);
152 }
153
154 EAPI Eina_Bool
155 _emotion_module_unregister(const char *name)
156 {
157    return eina_hash_del(_backends, name, NULL);
158 }
159
160 static const char *
161 _emotion_module_open(const char *name, Evas_Object *obj, Emotion_Video_Module **mod, void **video)
162 {
163    Eina_Emotion_Plugins *plugin;
164    Smart_Data *sd;
165    unsigned int index = 0;
166
167    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
168    if (!_backends)
169      {
170         ERR("No backend loaded");
171         return NULL;
172      }
173
174    /* FIXME: Always look for a working backend. */
175  retry:
176    if (!name || index > 0)
177      name = _backend_priority[index++];
178
179    plugin = eina_hash_find(_backends, name);
180    if (!plugin)
181      {
182         if (index != 0 && index < (sizeof (_backend_priority) / sizeof (char*)))
183           goto retry;
184
185         ERR("No backend loaded");
186         return EINA_FALSE;
187      }
188
189    if (plugin->open(obj, (const Emotion_Video_Module **) mod, video, &(sd->module_options)))
190      {
191         if (*mod)
192           {
193              (*mod)->plugin = plugin;
194              return name;
195           }
196      }
197
198    if (index != 0 && index < (sizeof (_backend_priority) / sizeof (char*)))
199      goto retry;
200
201    ERR("Unable to load module: %s", name);
202
203    return NULL;
204 }
205
206 static void
207 _emotion_module_close(Emotion_Video_Module *mod, void *video)
208 {
209    if (!mod) return;
210    if (mod->plugin->close && video)
211      mod->plugin->close(mod, video);
212    /* FIXME: we can't go dlclosing here as a thread still may be running from
213     * the module - this in theory will leak- but it shouldnt be too bad and
214     * mean that once a module is dlopened() it cant be closed - its refcount
215     * will just keep going up
216     */
217 }
218
219 /*******************************/
220 /* Externally accessible calls */
221 /*******************************/
222
223
224
225 EAPI Evas_Object *
226 emotion_object_add(Evas *evas)
227 {
228    _smart_init();
229    return evas_object_smart_add(evas, smart);
230 }
231
232 EAPI void
233 emotion_object_module_option_set(Evas_Object *obj, const char *opt, const char *val)
234 {
235    Smart_Data *sd;
236
237    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
238    if ((!opt) || (!val)) return;
239    if (!strcmp(opt, "video"))
240      {
241         if (!strcmp(val, "off")) sd->module_options.no_video = EINA_TRUE;
242      }
243    else if (!strcmp(opt, "audio"))
244      {
245         if (!strcmp(val, "off")) sd->module_options.no_audio = EINA_TRUE;
246      }
247 }
248
249 EAPI Eina_Bool
250 emotion_object_init(Evas_Object *obj, const char *module_filename)
251 {
252    Smart_Data *sd;
253    char *file;
254
255    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
256
257    if ((sd->module_name) && module_filename && (!strcmp(sd->module_name, module_filename)))
258      return EINA_TRUE;
259    free(sd->module_name);
260    sd->module_name = NULL;
261
262    file = sd->file;
263    sd->file = NULL;
264
265    free(sd->title);
266    sd->title = NULL;
267    free(sd->progress.info);
268    sd->progress.info = NULL;
269    sd->progress.stat = 0.0;
270    free(sd->ref.file);
271    sd->ref.file = NULL;
272    sd->ref.num = 0;
273    sd->spu.button_num = 0;
274    sd->spu.button = -1;
275    sd->ratio = 1.0;
276    sd->pos = 0;
277    sd->seek_pos = 0;
278    sd->len = 0;
279
280    ecore_init();
281
282    _emotion_module_close(sd->module, sd->video);
283    sd->module = NULL;
284    sd->video = NULL;
285
286    module_filename = _emotion_module_open(module_filename, obj, &sd->module, &sd->video);
287    if (!module_filename)
288      return EINA_FALSE;
289
290    sd->module_name = strdup(module_filename);
291
292    if (file)
293      {
294         emotion_object_file_set(obj, file);
295         free(file);
296      }
297
298    return EINA_TRUE;
299 }
300
301 EAPI void
302 emotion_object_file_set(Evas_Object *obj, const char *file)
303 {
304    Smart_Data *sd;
305
306    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
307
308    DBG("file=%s", file);
309    if (!sd->module) return;
310
311    if ((file) && (sd->file) && (!strcmp(file, sd->file))) return;
312    if ((file) && (file[0] != 0))
313      {
314         int w, h;
315
316         free(sd->file);
317         sd->file = strdup(file);
318         sd->module->file_close(sd->video);
319         evas_object_image_size_set(sd->obj, 0, 0);
320         if (!sd->module->file_open(sd->file, obj, sd->video))
321           return;
322         sd->module->size_get(sd->video, &w, &h);
323         evas_object_image_size_set(sd->obj, w, h);
324         sd->ratio = sd->module->ratio_get(sd->video);
325         sd->pos = 0.0;
326         if (sd->play) sd->module->play(sd->video, 0.0);
327      }
328    else
329      {
330         if (sd->video && sd->module)
331           {
332              sd->module->file_close(sd->video);
333              evas_object_image_size_set(sd->obj, 0, 0);
334           }
335         free(sd->file);
336         sd->file = NULL;
337      }
338 }
339
340 EAPI const char *
341 emotion_object_file_get(const Evas_Object *obj)
342 {
343    Smart_Data *sd;
344
345    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
346    return sd->file;
347 }
348
349 EAPI void
350 emotion_object_play_set(Evas_Object *obj, Eina_Bool play)
351 {
352    Smart_Data *sd;
353
354    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
355    DBG("play=%hhu, was=%hhu", play, sd->play);
356    if (play == sd->play) return;
357    if (!sd->module) return;
358    if (!sd->video) return;
359    sd->play = play;
360    if (sd->play) sd->module->play(sd->video, sd->pos);
361    else sd->module->stop(sd->video);
362 }
363
364 EAPI Eina_Bool
365 emotion_object_play_get(const Evas_Object *obj)
366 {
367    Smart_Data *sd;
368
369    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
370    if (!sd->video) return EINA_FALSE;
371
372    return sd->play;
373 }
374
375 EAPI void
376 emotion_object_position_set(Evas_Object *obj, double sec)
377 {
378    Smart_Data *sd;
379
380    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
381    DBG("sec=%f", sec);
382    if (!sd->module) return;
383    if (!sd->video) return;
384    sd->seek_pos = sec;
385    sd->seek = 1;
386    sd->pos = sd->seek_pos;
387    if (sd->job) ecore_job_del(sd->job);
388    sd->job = ecore_job_add(_pos_set_job, obj);
389 }
390
391 EAPI double
392 emotion_object_position_get(const Evas_Object *obj)
393 {
394    Smart_Data *sd;
395
396    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0);
397    if (!sd->module) return 0.0;
398    if (!sd->video) return 0.0;
399    if (!sd->module->pos_get) return 0.0;
400    sd->pos = sd->module->pos_get(sd->video);
401    return sd->pos;
402 }
403
404 EAPI Eina_Bool
405 emotion_object_seekable_get(const Evas_Object *obj)
406 {
407    Smart_Data *sd;
408
409    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
410    if (!sd->module) return EINA_FALSE;
411    if (!sd->video) return EINA_FALSE;
412    return sd->module->seekable(sd->video);
413 }
414
415 EAPI Eina_Bool
416 emotion_object_video_handled_get(const Evas_Object *obj)
417 {
418    Smart_Data *sd;
419
420    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
421    if (!sd->module) return EINA_FALSE;
422    if (!sd->video) return EINA_FALSE;
423    return sd->module->video_handled(sd->video);
424 }
425
426 EAPI Eina_Bool
427 emotion_object_audio_handled_get(const Evas_Object *obj)
428 {
429    Smart_Data *sd;
430
431    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
432    if (!sd->module) return EINA_FALSE;
433    if (!sd->video) return EINA_FALSE;
434    return sd->module->audio_handled(sd->video);
435 }
436
437 EAPI double
438 emotion_object_play_length_get(const Evas_Object *obj)
439 {
440    Smart_Data *sd;
441
442    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0);
443    if (!sd->module) return 0.0;
444    if (!sd->video) return 0.0;
445    sd->len = sd->module->len_get(sd->video);
446    return sd->len;
447 }
448
449 EAPI void
450 emotion_object_size_get(const Evas_Object *obj, int *iw, int *ih)
451 {
452    Smart_Data *sd;
453
454    if (iw) *iw = 0;
455    if (ih) *ih = 0;
456    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
457    evas_object_image_size_get(sd->obj, iw, ih);
458 }
459
460 /**
461  * Sets whether to use of high-quality image scaling algorithm
462  * of the given video object.
463  *
464  * When enabled, a higher quality video scaling algorithm is used when
465  * scaling videos to sizes other than the source video. This gives
466  * better results but is more computationally expensive.
467  *
468  * @param obj The given video object.
469  * @param smooth Whether to use smooth scale or not.
470  */
471 EAPI void
472 emotion_object_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth)
473 {
474    Smart_Data *sd;
475
476    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
477    evas_object_image_smooth_scale_set(sd->obj, smooth);
478 }
479
480 /**
481  * Gets whether the high-quality image scaling algorithm
482  * of the given video object is used.
483  *
484  * @return Whether the smooth scale is used or not.
485  */
486 EAPI Eina_Bool
487 emotion_object_smooth_scale_get(const Evas_Object *obj)
488 {
489    Smart_Data *sd;
490
491    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
492    return evas_object_image_smooth_scale_get(sd->obj);
493 }
494
495 EAPI double
496 emotion_object_ratio_get(const Evas_Object *obj)
497 {
498    Smart_Data *sd;
499
500    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 1.0);
501    if (!sd->module) return 0.0;
502    if (!sd->video) return 0.0;
503    return sd->ratio;
504 }
505
506 /**
507  * Send a control event to the DVD.
508  */
509 EAPI void
510 emotion_object_event_simple_send(Evas_Object *obj, Emotion_Event ev)
511 {
512    Smart_Data *sd;
513
514    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
515    if (!sd->module) return;
516    if (!sd->video) return;
517    sd->module->event_feed(sd->video, ev);
518 }
519
520 EAPI void
521 emotion_object_audio_volume_set(Evas_Object *obj, double vol)
522 {
523    Smart_Data *sd;
524
525    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
526    DBG("vol=%f", vol);
527    if (!sd->module) return;
528    if (!sd->video) return;
529    sd->module->audio_channel_volume_set(sd->video, vol);
530 }
531
532 EAPI double
533 emotion_object_audio_volume_get(const Evas_Object *obj)
534 {
535    Smart_Data *sd;
536
537    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 1.0);
538    if (!sd->module) return 0.0;
539    if (!sd->video) return 0.0;
540    return sd->module->audio_channel_volume_get(sd->video);
541 }
542
543 EAPI void
544 emotion_object_audio_mute_set(Evas_Object *obj, Eina_Bool mute)
545 {
546    Smart_Data *sd;
547
548    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
549    DBG("mute=%hhu", mute);
550    if (!sd->module) return;
551    if (!sd->video) return;
552    sd->module->audio_channel_mute_set(sd->video, mute);
553 }
554
555 EAPI Eina_Bool
556 emotion_object_audio_mute_get(const Evas_Object *obj)
557 {
558    Smart_Data *sd;
559
560    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
561    if (!sd->module) return EINA_FALSE;
562    if (!sd->video) return EINA_FALSE;
563    return sd->module->audio_channel_mute_get(sd->video);
564 }
565
566 EAPI int
567 emotion_object_audio_channel_count(const Evas_Object *obj)
568 {
569    Smart_Data *sd;
570
571    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
572    if (!sd->module) return 0;
573    if (!sd->video) return 0;
574    return sd->module->audio_channel_count(sd->video);
575 }
576
577 EAPI const char *
578 emotion_object_audio_channel_name_get(const Evas_Object *obj, int channel)
579 {
580    Smart_Data *sd;
581
582    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
583    if (!sd->module) return NULL;
584    if (!sd->video) return NULL;
585    return sd->module->audio_channel_name_get(sd->video, channel);
586 }
587
588 EAPI void
589 emotion_object_audio_channel_set(Evas_Object *obj, int channel)
590 {
591    Smart_Data *sd;
592
593    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
594    DBG("channel=%d", channel);
595    if (!sd->module) return;
596    if (!sd->video) return;
597    sd->module->audio_channel_set(sd->video, channel);
598 }
599
600 EAPI int
601 emotion_object_audio_channel_get(const Evas_Object *obj)
602 {
603    Smart_Data *sd;
604
605    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
606    if (!sd->module) return 0;
607    if (!sd->video) return 0;
608    return sd->module->audio_channel_get(sd->video);
609 }
610
611 EAPI void
612 emotion_object_video_mute_set(Evas_Object *obj, Eina_Bool mute)
613 {
614    Smart_Data *sd;
615
616    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
617    DBG("mute=%hhu", mute);
618    if (!sd->module) return;
619    if (!sd->video) return;
620    sd->module->video_channel_mute_set(sd->video, mute);
621 }
622
623 EAPI Eina_Bool
624 emotion_object_video_mute_get(const Evas_Object *obj)
625 {
626    Smart_Data *sd;
627
628    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
629    if (!sd->module) return EINA_FALSE;
630    if (!sd->video) return EINA_FALSE;
631    return sd->module->video_channel_mute_get(sd->video);
632 }
633
634 EAPI int
635 emotion_object_video_channel_count(const Evas_Object *obj)
636 {
637    Smart_Data *sd;
638
639    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
640    if (!sd->module) return EINA_FALSE;
641    if (!sd->video) return EINA_FALSE;
642    return sd->module->video_channel_count(sd->video);
643 }
644
645 EAPI const char *
646 emotion_object_video_channel_name_get(const Evas_Object *obj, int channel)
647 {
648    Smart_Data *sd;
649
650    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
651    if (!sd->module) return NULL;
652    if (!sd->video) return NULL;
653    return sd->module->video_channel_name_get(sd->video, channel);
654 }
655
656 EAPI void
657 emotion_object_video_channel_set(Evas_Object *obj, int channel)
658 {
659    Smart_Data *sd;
660
661    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
662    DBG("channel=%d", channel);
663    if (!sd->module) return;
664    if (!sd->video) return;
665    sd->module->video_channel_set(sd->video, channel);
666 }
667
668 EAPI int
669 emotion_object_video_channel_get(const Evas_Object *obj)
670 {
671    Smart_Data *sd;
672
673    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
674    if (!sd->module) return 0;
675    if (!sd->video) return 0;
676    return sd->module->video_channel_get(sd->video);
677 }
678
679 EAPI void
680 emotion_object_spu_mute_set(Evas_Object *obj, Eina_Bool mute)
681 {
682    Smart_Data *sd;
683
684    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
685    DBG("mute=%hhu", mute);
686    if (!sd->module) return;
687    if (!sd->video) return;
688    sd->module->spu_channel_mute_set(sd->video, mute);
689 }
690
691 EAPI Eina_Bool
692 emotion_object_spu_mute_get(const Evas_Object *obj)
693 {
694    Smart_Data *sd;
695
696    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
697    if (!sd->module) return EINA_FALSE;
698    if (!sd->video) return EINA_FALSE;
699    return sd->module->spu_channel_mute_get(sd->video);
700 }
701
702 EAPI int
703 emotion_object_spu_channel_count(const Evas_Object *obj)
704 {
705    Smart_Data *sd;
706
707    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
708    if (!sd->module) return 0;
709    if (!sd->video) return 0;
710    return sd->module->spu_channel_count(sd->video);
711 }
712
713 EAPI const char *
714 emotion_object_spu_channel_name_get(const Evas_Object *obj, int channel)
715 {
716    Smart_Data *sd;
717
718    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
719    if (!sd->module) return NULL;
720    if (!sd->video) return NULL;
721    return sd->module->spu_channel_name_get(sd->video, channel);
722 }
723
724 EAPI void
725 emotion_object_spu_channel_set(Evas_Object *obj, int channel)
726 {
727    Smart_Data *sd;
728
729    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
730    DBG("channel=%d", channel);
731    if (!sd->module) return;
732    if (!sd->video) return;
733    sd->module->spu_channel_set(sd->video, channel);
734 }
735
736 EAPI int
737 emotion_object_spu_channel_get(const Evas_Object *obj)
738 {
739    Smart_Data *sd;
740
741    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
742    if (!sd->module) return 0;
743    if (!sd->video) return 0;
744    return sd->module->spu_channel_get(sd->video);
745 }
746
747 EAPI int
748 emotion_object_chapter_count(const Evas_Object *obj)
749 {
750    Smart_Data *sd;
751
752    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
753    if (!sd->module) return 0;
754    if (!sd->video) return 0;
755    return sd->module->chapter_count(sd->video);
756 }
757
758 EAPI void
759 emotion_object_chapter_set(Evas_Object *obj, int chapter)
760 {
761    Smart_Data *sd;
762
763    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
764    DBG("chapter=%d", chapter);
765    if (!sd->module) return;
766    if (!sd->video) return;
767    sd->module->chapter_set(sd->video, chapter);
768 }
769
770 EAPI int
771 emotion_object_chapter_get(const Evas_Object *obj)
772 {
773    Smart_Data *sd;
774
775    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
776    if (!sd->module) return 0;
777    if (!sd->video) return 0;
778    return sd->module->chapter_get(sd->video);
779 }
780
781 EAPI const char *
782 emotion_object_chapter_name_get(const Evas_Object *obj, int chapter)
783 {
784    Smart_Data *sd;
785
786    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
787    if (!sd->module) return NULL;
788    if (!sd->video) return NULL;
789    return sd->module->chapter_name_get(sd->video, chapter);
790 }
791
792 EAPI void
793 emotion_object_play_speed_set(Evas_Object *obj, double speed)
794 {
795    Smart_Data *sd;
796
797    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
798    DBG("speed=%f", speed);
799    if (!sd->module) return;
800    if (!sd->video) return;
801    sd->module->speed_set(sd->video, speed);
802 }
803
804 EAPI double
805 emotion_object_play_speed_get(const Evas_Object *obj)
806 {
807    Smart_Data *sd;
808
809    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0);
810    if (!sd->module) return 0.0;
811    if (!sd->video) return 0.0;
812    return sd->module->speed_get(sd->video);
813 }
814
815 EAPI void
816 emotion_object_eject(Evas_Object *obj)
817 {
818    Smart_Data *sd;
819
820    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
821    if (!sd->module) return;
822    if (!sd->video) return;
823    sd->module->eject(sd->video);
824 }
825
826 EAPI const char *
827 emotion_object_title_get(const Evas_Object *obj)
828 {
829    Smart_Data *sd;
830
831    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
832    return sd->title;
833 }
834
835 EAPI const char *
836 emotion_object_progress_info_get(const Evas_Object *obj)
837 {
838    Smart_Data *sd;
839
840    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
841    return sd->progress.info;
842 }
843
844 EAPI double
845 emotion_object_progress_status_get(const Evas_Object *obj)
846 {
847    Smart_Data *sd;
848
849    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0);
850    return sd->progress.stat;
851 }
852
853 EAPI const char *
854 emotion_object_ref_file_get(const Evas_Object *obj)
855 {
856    Smart_Data *sd;
857
858    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
859    return sd->ref.file;
860 }
861
862 EAPI int
863 emotion_object_ref_num_get(const Evas_Object *obj)
864 {
865    Smart_Data *sd;
866
867    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
868    return sd->ref.num;
869 }
870
871 EAPI int
872 emotion_object_spu_button_count_get(const Evas_Object *obj)
873 {
874    Smart_Data *sd;
875
876    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
877    return sd->spu.button_num;
878 }
879
880 EAPI int
881 emotion_object_spu_button_get(const Evas_Object *obj)
882 {
883    Smart_Data *sd;
884
885    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
886    return sd->spu.button;
887 }
888
889 EAPI const char *
890 emotion_object_meta_info_get(const Evas_Object *obj, Emotion_Meta_Info meta)
891 {
892    Smart_Data *sd;
893
894    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
895    if (!sd->module) return NULL;
896    if (!sd->video) return NULL;
897    switch (meta)
898      {
899       case EMOTION_META_INFO_TRACK_TITLE:
900         return sd->module->meta_get(sd->video, META_TRACK_TITLE);
901         break;
902       case EMOTION_META_INFO_TRACK_ARTIST:
903         return sd->module->meta_get(sd->video, META_TRACK_ARTIST);
904         break;
905       case EMOTION_META_INFO_TRACK_ALBUM:
906         return sd->module->meta_get(sd->video, META_TRACK_ALBUM);
907         break;
908       case EMOTION_META_INFO_TRACK_YEAR:
909         return sd->module->meta_get(sd->video, META_TRACK_YEAR);
910         break;
911       case EMOTION_META_INFO_TRACK_GENRE:
912         return sd->module->meta_get(sd->video, META_TRACK_GENRE);
913         break;
914       case EMOTION_META_INFO_TRACK_COMMENT:
915         return sd->module->meta_get(sd->video, META_TRACK_COMMENT);
916         break;
917       case EMOTION_META_INFO_TRACK_DISC_ID:
918         return sd->module->meta_get(sd->video, META_TRACK_DISCID);
919         break;
920       default:
921         break;
922      }
923    return NULL;
924 }
925
926 EAPI void
927 emotion_object_vis_set(Evas_Object *obj, Emotion_Vis visualization)
928 {
929    Smart_Data *sd;
930
931    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
932    DBG("visualization=%d", visualization);
933    if (!sd->module) return;
934    if (!sd->video) return;
935    if (!sd->module->vis_set) return;
936    sd->module->vis_set(sd->video, visualization);
937 }
938
939 EAPI Emotion_Vis
940 emotion_object_vis_get(const Evas_Object *obj)
941 {
942    Smart_Data *sd;
943
944    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EMOTION_VIS_NONE);
945    if (!sd->module) return EMOTION_VIS_NONE;
946    if (!sd->video) return EMOTION_VIS_NONE;
947    if (!sd->module->vis_get) return EMOTION_VIS_NONE;
948    return sd->module->vis_get(sd->video);
949 }
950
951 EAPI Eina_Bool
952 emotion_object_vis_supported(const Evas_Object *obj, Emotion_Vis visualization)
953 {
954    Smart_Data *sd;
955
956    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
957    if (!sd->module) return EINA_FALSE;
958    if (!sd->video) return EINA_FALSE;
959    if (!sd->module->vis_supported) return EINA_FALSE;
960    return sd->module->vis_supported(sd->video, visualization);
961 }
962
963
964
965 /*****************************/
966 /* Utility calls for modules */
967 /*****************************/
968
969 EAPI void *
970 _emotion_video_get(const Evas_Object *obj)
971 {
972    Smart_Data *sd;
973
974    E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
975    return sd->video;
976 }
977
978 EAPI void
979 _emotion_frame_new(Evas_Object *obj)
980 {
981    Smart_Data *sd;
982
983    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
984 //   printf("pix get set 1 %p\n", sd->obj);
985    evas_object_image_pixels_dirty_set(sd->obj, 1);
986    evas_object_smart_callback_call(obj, SIG_FRAME_DECODE, NULL);
987 }
988
989 EAPI void
990 _emotion_video_pos_update(Evas_Object *obj, double pos, double len)
991 {
992    Smart_Data *sd;
993    int npos = 0, nlen = 0;
994
995    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
996    if (pos != sd->pos) npos = 1;
997    if (len != sd->len) nlen = 1;
998    sd->pos = pos;
999    sd->len = len;
1000    if (npos) evas_object_smart_callback_call(obj, SIG_POSITION_UPDATE, NULL);
1001    if (nlen) evas_object_smart_callback_call(obj, SIG_LENGTH_CHANGE, NULL);
1002 }
1003
1004 EAPI void
1005 _emotion_frame_resize(Evas_Object *obj, int w, int h, double ratio)
1006 {
1007    Smart_Data *sd;
1008    int iw, ih;
1009    int changed = 0;
1010
1011    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1012    evas_object_image_size_get(sd->obj, &iw, &ih);
1013    if ((w != iw) || (h != ih))
1014      {
1015         if (h > 0) sd->ratio  = (double)w / (double)h;
1016         else sd->ratio = 1.0;
1017         evas_object_image_size_set(sd->obj, w, h);
1018         changed = 1;
1019      }
1020    if (ratio != sd->ratio)
1021      {
1022         sd->ratio = ratio;
1023         changed = 1;
1024      }
1025    if (changed) evas_object_smart_callback_call(obj, SIG_FRAME_RESIZE, NULL);
1026 }
1027
1028 EAPI void
1029 _emotion_decode_stop(Evas_Object *obj)
1030 {
1031    Smart_Data *sd;
1032
1033    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1034    if (sd->play)
1035      {
1036         sd->play = 0;
1037         evas_object_smart_callback_call(obj, SIG_DECODE_STOP, NULL);
1038      }
1039 }
1040
1041 EAPI void
1042 _emotion_open_done(Evas_Object *obj)
1043 {
1044    evas_object_smart_callback_call(obj, SIG_OPEN_DONE, NULL);
1045 }
1046
1047 EAPI void
1048 _emotion_playback_started(Evas_Object *obj)
1049 {
1050    evas_object_smart_callback_call(obj, SIG_PLAYBACK_STARTED, NULL);
1051 }
1052
1053 EAPI void
1054 _emotion_playback_finished(Evas_Object *obj)
1055 {
1056    evas_object_smart_callback_call(obj, SIG_PLAYBACK_FINISHED, NULL);
1057 }
1058
1059 EAPI void
1060 _emotion_audio_level_change(Evas_Object *obj)
1061 {
1062    evas_object_smart_callback_call(obj, SIG_AUDIO_LEVEL_CHANGE, NULL);
1063 }
1064
1065 EAPI void
1066 _emotion_channels_change(Evas_Object *obj)
1067 {
1068    Smart_Data *sd;
1069
1070    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1071    evas_object_smart_callback_call(obj, SIG_CHANNELS_CHANGE, NULL);
1072 }
1073
1074 EAPI void
1075 _emotion_title_set(Evas_Object *obj, char *title)
1076 {
1077    Smart_Data *sd;
1078
1079    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1080    free(sd->title);
1081    sd->title = strdup(title);
1082    evas_object_smart_callback_call(obj, SIG_TITLE_CHANGE, NULL);
1083 }
1084
1085 EAPI void
1086 _emotion_progress_set(Evas_Object *obj, char *info, double stat)
1087 {
1088    Smart_Data *sd;
1089
1090    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1091    free(sd->progress.info);
1092    sd->progress.info = strdup(info);
1093    sd->progress.stat = stat;
1094    evas_object_smart_callback_call(obj, SIG_PROGRESS_CHANGE, NULL);
1095 }
1096
1097 EAPI void
1098 _emotion_file_ref_set(Evas_Object *obj, const char *file, int num)
1099 {
1100    Smart_Data *sd;
1101
1102    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1103    free(sd->ref.file);
1104    sd->ref.file = strdup(file);
1105    sd->ref.num = num;
1106    evas_object_smart_callback_call(obj, SIG_REF_CHANGE, NULL);
1107 }
1108
1109 EAPI void
1110 _emotion_spu_button_num_set(Evas_Object *obj, int num)
1111 {
1112    Smart_Data *sd;
1113
1114    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1115    sd->spu.button_num = num;
1116    evas_object_smart_callback_call(obj, SIG_BUTTON_NUM_CHANGE, NULL);
1117 }
1118
1119 EAPI void
1120 _emotion_spu_button_set(Evas_Object *obj, int button)
1121 {
1122    Smart_Data *sd;
1123
1124    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1125    sd->spu.button = button;
1126    evas_object_smart_callback_call(obj, SIG_BUTTON_CHANGE, NULL);
1127 }
1128
1129 EAPI void
1130 _emotion_seek_done(Evas_Object *obj)
1131 {
1132    Smart_Data *sd;
1133
1134    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1135    if (sd->seeking)
1136      {
1137         sd->seeking = 0;
1138         if (sd->seek) emotion_object_position_set(obj, sd->seek_pos);
1139      }
1140 }
1141
1142
1143
1144 /****************************/
1145 /* Internal object routines */
1146 /****************************/
1147
1148 static void
1149 _mouse_move(void *data, Evas *ev __UNUSED__, Evas_Object *obj, void *event_info)
1150 {
1151    Evas_Event_Mouse_Move *e;
1152    Smart_Data *sd;
1153    int x, y, iw, ih;
1154    Evas_Coord ox, oy, ow, oh;
1155
1156    e = event_info;
1157    sd = data;
1158    if (!sd->module) return;
1159    if (!sd->video) return;
1160    evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
1161    evas_object_image_size_get(obj, &iw, &ih);
1162    if ((iw < 1) || (ih < 1)) return;
1163    x = (((int)e->cur.canvas.x - ox) * iw) / ow;
1164    y = (((int)e->cur.canvas.y - oy) * ih) / oh;
1165    sd->module->event_mouse_move_feed(sd->video, x, y);
1166 }
1167
1168 static void
1169 _mouse_down(void *data, Evas *ev __UNUSED__, Evas_Object *obj, void *event_info)
1170 {
1171    Evas_Event_Mouse_Down *e;
1172    Smart_Data *sd;
1173    int x, y, iw, ih;
1174    Evas_Coord ox, oy, ow, oh;
1175
1176    e = event_info;
1177    sd = data;
1178    if (!sd->module) return;
1179    if (!sd->video) return;
1180    evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
1181    evas_object_image_size_get(obj, &iw, &ih);
1182    if ((iw < 1) || (ih < 1)) return;
1183    x = (((int)e->canvas.x - ox) * iw) / ow;
1184    y = (((int)e->canvas.y - oy) * ih) / oh;
1185    sd->module->event_mouse_button_feed(sd->video, 1, x, y);
1186 }
1187
1188 static void
1189 _pos_set_job(void *data)
1190 {
1191    Evas_Object *obj;
1192    Smart_Data *sd;
1193
1194    obj = data;
1195    E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1196    sd->job = NULL;
1197    if (sd->seeking) return;
1198    if (sd->seek)
1199      {
1200         sd->seeking = 1;
1201         sd->module->pos_set(sd->video, sd->seek_pos);
1202         sd->seek = 0;
1203      }
1204 }
1205
1206 /* called by evas when it needs pixels for the image object */
1207 static void
1208 _pixels_get(void *data, Evas_Object *obj)
1209 {
1210    int iw, ih, w, h;
1211    Smart_Data *sd;
1212    Emotion_Format format;
1213    unsigned char *bgra_data;
1214
1215    sd = data;
1216    evas_object_image_size_get(obj, &iw, &ih);
1217    sd->module->video_data_size_get(sd->video, &w, &h);
1218    w = (w >> 1) << 1;
1219    h = (h >> 1) << 1;
1220    if ((w != iw) || (h != ih))
1221      {
1222         evas_object_image_colorspace_set(obj, EVAS_COLORSPACE_YCBCR422P601_PL);
1223         evas_object_image_alpha_set(obj, 0);
1224         evas_object_image_size_set(obj, w, h);
1225         iw = w;
1226         ih = h;
1227      }
1228    if ((iw < 1) || (ih < 1))
1229      {
1230 //      printf("pix get set 0 (1)\n");
1231         evas_object_image_pixels_dirty_set(obj, 0);
1232      }
1233    else
1234      {
1235         format = sd->module->format_get(sd->video);
1236         if ((format == EMOTION_FORMAT_YV12) || (format == EMOTION_FORMAT_I420))
1237           {
1238              unsigned char **rows;
1239
1240              evas_object_image_colorspace_set(obj, EVAS_COLORSPACE_YCBCR422P601_PL);
1241              rows = evas_object_image_data_get(obj, 1);
1242              if (rows)
1243                {
1244                   if (sd->module->yuv_rows_get(sd->video, iw, ih,
1245                                                rows,
1246                                                &rows[ih],
1247                                                &rows[ih + (ih / 2)]))
1248                     evas_object_image_data_update_add(obj, 0, 0, iw, ih);
1249                }
1250              evas_object_image_data_set(obj, rows);
1251 //           printf("pix get set 0 (2)\n");
1252              evas_object_image_pixels_dirty_set(obj, 0);
1253           }
1254         else if (format == EMOTION_FORMAT_BGRA)
1255           {
1256              if (sd->module->bgra_data_get(sd->video, &bgra_data))
1257                {
1258                   evas_object_image_data_set(obj, bgra_data);
1259 //                printf("pix get set 0 (3)\n");
1260                   evas_object_image_pixels_dirty_set(obj, 0);
1261                }
1262           }
1263      }
1264 // no need for this because on any new frame decode info from the decoder
1265 // module, the previous "current frame" is released (done) for us anyway
1266 //   sd->module->frame_done(sd->video);
1267
1268 /*
1269    evas_object_image_size_get(obj, &iw, &ih);
1270    sd->module->video_data_size_get(sd->video, &w, &h);
1271    if ((w != iw) || (h != ih))
1272      {
1273         evas_object_image_size_set(obj, w, h);
1274         iw = w;
1275         ih = h;
1276      }
1277    format = sd->module->format_get(sd->video);
1278    if ((format == EMOTION_FORMAT_YV12) || (format == EMOTION_FORMAT_I420))
1279      {
1280         unsigned char **rows;
1281         Evas_Pixel_Import_Source ps;
1282
1283         ps.format = EVAS_PIXEL_FORMAT_YUV420P_601;
1284         ps.w = iw;
1285         ps.h = ih;
1286
1287         ps.rows = malloc(ps.h * 2 * sizeof(void *));
1288         if (!ps.rows)
1289           {
1290              sd->module->frame_done(sd->video);
1291              return;
1292           }
1293
1294         rows = (unsigned char **)ps.rows;
1295
1296         if (sd->module->yuv_rows_get(sd->video, iw, ih,
1297                                      rows,
1298                                      &rows[ps.h],
1299                                      &rows[ps.h + (ps.h / 2)]))
1300           evas_object_image_pixels_import(obj, &ps);
1301         evas_object_image_pixels_dirty_set(obj, 0);
1302         free(ps.rows);
1303      }
1304    else if (format == EMOTION_FORMAT_BGRA)
1305      {
1306         if (sd->module->bgra_data_get(sd->video, &bgra_data));
1307           {
1308              evas_object_image_data_set(obj, bgra_data);
1309              evas_object_image_pixels_dirty_set(obj, 0);
1310           }
1311      }
1312    sd->module->frame_done(sd->video);
1313  */
1314 }
1315
1316 /*******************************************/
1317 /* Internal smart object required routines */
1318 /*******************************************/
1319 #ifdef EMOTION_STATIC_BUILD_XINE
1320 Eina_Bool xine_module_init(void);
1321 #endif
1322 #ifdef EMOTION_STATIC_BUILD_VLC
1323 Eina_Bool vlc_module_init(void);
1324 #endif
1325 #ifdef EMOTION_STATIC_BUILD_GSTREAMER
1326 Eina_Bool gstreamer_module_init(void);
1327 #endif
1328
1329 static void
1330 _smart_init(void)
1331 {
1332    char *path;
1333
1334    if (smart) return;
1335      {
1336         eina_init();
1337
1338         _log_domain = eina_log_domain_register("emotion", EINA_COLOR_LIGHTCYAN);
1339         if (_log_domain < 0)
1340           {
1341              EINA_LOG_CRIT("Could not register log domain 'emotion'");
1342              eina_shutdown();
1343              return;
1344           }
1345
1346         _backends = eina_hash_string_small_new(free);
1347
1348         _modules = eina_module_list_get(NULL, PACKAGE_LIB_DIR "/emotion/", 0, NULL, NULL);
1349
1350         path = eina_module_environment_path_get("HOME", "/.emotion/");
1351         _modules = eina_module_list_get(_modules, path, 0, NULL, NULL);
1352         if (path) free(path);
1353
1354         path = eina_module_environment_path_get("EMOTION_MODULES_DIR", "/emotion/");
1355         _modules = eina_module_list_get(_modules, path, 0, NULL, NULL);
1356         if (path) free(path);
1357
1358         path = eina_module_symbol_path_get(emotion_object_add, "/emotion/");
1359         _modules = eina_module_list_get(_modules, path, 0, NULL, NULL);
1360         if (path) free(path);
1361
1362         if (!_modules)
1363           {
1364              ERR("No module found!");
1365              return;
1366           }
1367
1368         eina_module_list_load(_modules);
1369
1370         /* Init static module */
1371 #ifdef EMOTION_STATIC_BUILD_XINE
1372         xine_module_init();
1373 #endif
1374 #ifdef EMOTION_STATIC_BUILD_VLC
1375         vlc_module_init();
1376 #endif
1377 #ifdef EMOTION_STATIC_BUILD_GSTREAMER
1378         gstreamer_module_init();
1379 #endif
1380
1381         static Evas_Smart_Class sc =
1382           EVAS_SMART_CLASS_INIT_NAME_VERSION(E_OBJ_NAME);
1383         if (!sc.add)
1384           {
1385              sc.add = _smart_add;
1386              sc.del = _smart_del;
1387              sc.move = _smart_move;
1388              sc.resize = _smart_resize;
1389              sc.show = _smart_show;
1390              sc.hide = _smart_hide;
1391              sc.color_set = _smart_color_set;
1392              sc.clip_set = _smart_clip_set;
1393              sc.clip_unset = _smart_clip_unset;
1394              sc.callbacks = _smart_callbacks;
1395           }
1396         smart = evas_smart_class_new(&sc);
1397      }
1398 }
1399
1400 static void
1401 _smart_add(Evas_Object * obj)
1402 {
1403    Smart_Data *sd;
1404    unsigned int *pixel;
1405
1406    sd = calloc(1, sizeof(Smart_Data));
1407    if (!sd) return;
1408    sd->obj = evas_object_image_add(evas_object_evas_get(obj));
1409    evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, sd);
1410    evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, sd);
1411    evas_object_image_pixels_get_callback_set(sd->obj, _pixels_get, sd);
1412    evas_object_smart_member_add(sd->obj, obj);
1413    sd->ratio = 1.0;
1414    sd->spu.button = -1;
1415    evas_object_image_alpha_set(sd->obj, 0);
1416    pixel = evas_object_image_data_get(sd->obj, 1);
1417    if (pixel)
1418      {
1419         *pixel = 0xff000000;
1420         evas_object_image_data_set(obj, pixel);
1421      }
1422    evas_object_smart_data_set(obj, sd);
1423 }
1424
1425 static void
1426 _smart_del(Evas_Object * obj)
1427 {
1428    Smart_Data *sd;
1429
1430    sd = evas_object_smart_data_get(obj);
1431    if (!sd) return;
1432    if (sd->video) sd->module->file_close(sd->video);
1433    _emotion_module_close(sd->module, sd->video);
1434    evas_object_del(sd->obj);
1435    free(sd->file);
1436    free(sd->module_name);
1437    if (sd->job) ecore_job_del(sd->job);
1438    free(sd->progress.info);
1439    free(sd->ref.file);
1440    free(sd);
1441
1442    ecore_shutdown();
1443 }
1444
1445 static void
1446 _smart_move(Evas_Object * obj, Evas_Coord x, Evas_Coord y)
1447 {
1448    Smart_Data *sd;
1449
1450    sd = evas_object_smart_data_get(obj);
1451    if (!sd) return;
1452    evas_object_move(sd->obj, x, y);
1453 }
1454
1455 static void
1456 _smart_resize(Evas_Object * obj, Evas_Coord w, Evas_Coord h)
1457 {
1458    Smart_Data *sd;
1459
1460    sd = evas_object_smart_data_get(obj);
1461    if (!sd) return;
1462    evas_object_image_fill_set(sd->obj, 0, 0, w, h);
1463    evas_object_resize(sd->obj, w, h);
1464 }
1465
1466 static void
1467 _smart_show(Evas_Object * obj)
1468 {
1469    Smart_Data *sd;
1470
1471    sd = evas_object_smart_data_get(obj);
1472    if (!sd) return;
1473    evas_object_show(sd->obj);
1474
1475 }
1476
1477 static void
1478 _smart_hide(Evas_Object * obj)
1479 {
1480    Smart_Data *sd;
1481
1482    sd = evas_object_smart_data_get(obj);
1483    if (!sd) return;
1484    evas_object_hide(sd->obj);
1485 }
1486
1487 static void
1488 _smart_color_set(Evas_Object * obj, int r, int g, int b, int a)
1489 {
1490    Smart_Data *sd;
1491
1492    sd = evas_object_smart_data_get(obj);
1493    if (!sd) return;
1494    evas_object_color_set(sd->obj, r, g, b, a);
1495 }
1496
1497 static void
1498 _smart_clip_set(Evas_Object * obj, Evas_Object * clip)
1499 {
1500    Smart_Data *sd;
1501
1502    sd = evas_object_smart_data_get(obj);
1503    if (!sd) return;
1504    evas_object_clip_set(sd->obj, clip);
1505 }
1506
1507 static void
1508 _smart_clip_unset(Evas_Object * obj)
1509 {
1510    Smart_Data *sd;
1511
1512    sd = evas_object_smart_data_get(obj);
1513    if (!sd) return;
1514    evas_object_clip_unset(sd->obj);
1515 }