From be1b11ca28dbaeaaab4fd8f308ec31029d104397 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Thu, 4 Feb 2016 23:59:22 +0900 Subject: [PATCH] e - video bgs - allow selection of video files for wallpapers this allows video files to be played for wapapers - they loop and run indefinitely. it is a special video object that shares the same source across all outputs, so if you have the same video set, on 2 screens (or desktops) then it's only decoded once and uses proxies to ducplicate. this works in the pager too (it uses proxies). this is for amusement and fun and ... because we can. :) --- src/bin/Makefile.mk | 2 + src/bin/e_bg.c | 21 +- src/bin/e_includes.h | 1 + src/bin/e_video.c | 353 ++++++++++++++++++ src/bin/e_video.h | 10 + src/bin/e_widget_bgpreview.c | 117 ++++-- .../conf_theme/e_int_config_wallpaper.c | 18 +- 7 files changed, 490 insertions(+), 32 deletions(-) create mode 100644 src/bin/e_video.c create mode 100644 src/bin/e_video.h diff --git a/src/bin/Makefile.mk b/src/bin/Makefile.mk index 5d41bc88f..6935c627f 100644 --- a/src/bin/Makefile.mk +++ b/src/bin/Makefile.mk @@ -165,6 +165,7 @@ src/bin/e_toolbar.h \ src/bin/e_update.h \ src/bin/e_user.h \ src/bin/e_utils.h \ +src/bin/e_video.h \ src/bin/e_widget_aspect.h \ src/bin/e_widget_button.h \ src/bin/e_widget_check.h \ @@ -325,6 +326,7 @@ src/bin/e_toolbar.c \ src/bin/e_update.c \ src/bin/e_user.c \ src/bin/e_utils.c \ +src/bin/e_video.c \ src/bin/e_widget_aspect.c \ src/bin/e_widget_button.c \ src/bin/e_widget.c \ diff --git a/src/bin/e_bg.c b/src/bin/e_bg.c index 8775e7622..4f47255d2 100644 --- a/src/bin/e_bg.c +++ b/src/bin/e_bg.c @@ -196,6 +196,8 @@ e_bg_zone_update(E_Zone *zone, E_Bg_Transition transition) const char *trans = ""; E_Desk *desk; + printf("UP %p trans %i\n", zone, transition); + if (transition == E_BG_TRANSITION_START) trans = e_config->transition_start; else if (transition == E_BG_TRANSITION_DESK) trans = e_config->transition_desk; @@ -211,10 +213,15 @@ e_bg_zone_update(E_Zone *zone, E_Bg_Transition transition) if (zone->bg_object) { - const char *pfile = ""; + const char *pfile = NULL; edje_object_file_get(zone->bg_object, &pfile, NULL); - if (!e_util_strcmp(pfile, bgfile)) goto end; + if (!pfile) e_icon_file_get(zone->bg_object, &pfile, NULL); + if (!pfile) pfile = e_video_file_get(zone->bg_object); + if (pfile) + { + if (!e_util_strcmp(pfile, bgfile)) goto end; + } } if (transition == E_BG_TRANSITION_NONE) @@ -252,12 +259,20 @@ e_bg_zone_update(E_Zone *zone, E_Bg_Transition transition) if (edje_object_data_get(o, "noanimation")) edje_object_animation_set(o, EINA_FALSE); } - else + else if ((eina_str_has_extension(bgfile, ".gif")) || + (eina_str_has_extension(bgfile, ".png")) || + (eina_str_has_extension(bgfile, ".jpg")) || + (eina_str_has_extension(bgfile, ".jpeg")) || + (eina_str_has_extension(bgfile, ".bmp"))) { o = e_icon_add(e_comp->evas); e_icon_file_key_set(o, bgfile, NULL); e_icon_fill_inside_set(o, 0); } + else + { + o = e_video_add(e_comp->evas, bgfile, EINA_FALSE); + } evas_object_data_set(o, "e_zone", zone); evas_object_repeat_events_set(o, 1); zone->bg_object = o; diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index b82853f11..9bf0fc0e5 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -56,6 +56,7 @@ #include "e_configure.h" #include "e_about.h" #include "e_theme_about.h" +#include "e_video.h" #include "e_widget.h" #include "e_widget_check.h" #include "e_widget_radio.h" diff --git a/src/bin/e_video.c b/src/bin/e_video.c new file mode 100644 index 000000000..e913473ef --- /dev/null +++ b/src/bin/e_video.c @@ -0,0 +1,353 @@ +#include "e.h" + +typedef struct _Video Video; + +struct _Video +{ + Evas_Object_Smart_Clipped_Data __clipped_data; + Evas_Object *clip, *o_vid; + Eina_Bool lowqual : 1; +}; + +typedef struct _Vidimg Vidimg; + +struct _Vidimg +{ + Evas_Object *obj; + Eina_List *copies; + int iw, ih, piw, pih; + Ecore_Job *restart_job; + Ecore_Event_Handler *offhandler; + Ecore_Event_Handler *onhandler; + Ecore_Timer *offtimer; +}; + +static Evas_Smart *_smart = NULL; +static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL; + +static Eina_List *vidimgs = NULL; + +static void _ob_resize(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h); + +static void +_cb_vid_frame(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + Vidimg *vi = data; + Eina_List *l; + Evas_Object *o, *oimg; + + EINA_LIST_FOREACH(vi->copies, l, o) + { + Evas_Coord ox, oy, ow, oh; + Video *sd; + + obj = evas_object_data_get(o, "obj"); + oimg = emotion_object_image_get(vi->obj); + evas_object_image_source_set(o, oimg); + evas_object_image_source_clip_set(o, EINA_FALSE); + evas_object_image_source_visible_set(o, EINA_FALSE); + sd = evas_object_smart_data_get(obj); + evas_object_geometry_get(obj, &ox, &oy, &ow, &oh); + evas_object_show(sd->o_vid); + evas_object_show(sd->clip); + _ob_resize(obj, ox, oy, ow, oh); + } +} + +static void +_cb_vid_resize(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + Vidimg *vi = data; + Eina_List *l; + Evas_Object *o; + + EINA_LIST_FOREACH(vi->copies, l, o) + { + Evas_Coord ox, oy, ow, oh; + + obj = evas_object_data_get(o, "obj"); + evas_object_geometry_get(obj, &ox, &oy, &ow, &oh); + _ob_resize(obj, ox, oy, ow, oh); + } +} + +static void +_cb_restart(void *data) +{ + Vidimg *vi = data; + + vi->restart_job = NULL; + emotion_object_position_set(vi->obj, 0.0); + emotion_object_play_set(vi->obj, EINA_TRUE); +} + +static void +_cb_vid_stop(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + Vidimg *vi = data; + + if (vi->restart_job) ecore_job_del(vi->restart_job); + vi->restart_job = ecore_job_add(_cb_restart, vi); +} + +static Eina_Bool +vidimg_cb_suspend(void *data) +{ + Vidimg *vi = data; + + vi->offtimer = NULL; + emotion_object_play_set(vi->obj, EINA_FALSE); + return EINA_FALSE; +} + +static Eina_Bool +vidimg_cb_screensaver_off(void *data, int type EINA_UNUSED, void *event EINA_UNUSED) +{ + Vidimg *vi = data; + + if (vi->offtimer) + { + ecore_timer_del(vi->offtimer); + vi->offtimer = NULL; + } + else + { + emotion_object_play_set(vi->obj, EINA_TRUE); + } + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +vidimg_cb_screensaver_on(void *data, int type EINA_UNUSED, void *event EINA_UNUSED) +{ + Vidimg *vi = data; + + if (vi->offtimer) ecore_timer_del(vi->offtimer); + vi->offtimer = ecore_timer_add(10.0, vidimg_cb_suspend, vi); + return ECORE_CALLBACK_PASS_ON; +} + +static Evas_Object * +vidimg_find(Evas_Object *obj, const char *file) +{ + Eina_List *l; + Evas_Object *o, *oimg, *oproxy; + + EINA_LIST_FOREACH(vidimgs, l, o) + { + if (evas_object_evas_get(o) == evas_object_evas_get(obj)) + { + const char *f = emotion_object_file_get(o); + + if ((f) && (file) && (!strcmp(f, file))) + { + Vidimg *vi = evas_object_data_get(o, "vidimg"); + oproxy = evas_object_image_filled_add(evas_object_evas_get(obj)); + evas_object_data_set(oproxy, "source", o); + oimg = emotion_object_image_get(o); + evas_object_image_source_set(oproxy, oimg); + evas_object_image_source_clip_set(oproxy, EINA_FALSE); + evas_object_image_source_visible_set(oproxy, EINA_FALSE); + vi->copies = eina_list_append(vi->copies, oproxy); + evas_object_data_set(oproxy, "obj", obj); + return oproxy; + } + } + } + return NULL; +} + +static Evas_Object * +vidimg_video_add(Evas_Object *obj, const char *file) +{ + Evas_Object *o; + Vidimg *vi; + + emotion_init(); + o = emotion_object_add(evas_object_evas_get(obj)); + if (!emotion_object_init(o, "gstreamer1")) + { + evas_object_del(o); + return NULL; + } + vi = calloc(1, sizeof(Vidimg)); + vi->obj = o; + vi->offhandler = ecore_event_handler_add(E_EVENT_SCREENSAVER_OFF, vidimg_cb_screensaver_off, vi); + vi->onhandler = ecore_event_handler_add(E_EVENT_SCREENSAVER_ON, vidimg_cb_screensaver_on, vi); + evas_object_data_set(o, "vidimg", vi); + evas_object_smart_callback_add(o, "frame_decode", _cb_vid_frame, vi); + evas_object_smart_callback_add(o, "frame_resize", _cb_vid_resize, vi); + evas_object_smart_callback_add(o, "decode_stop", _cb_vid_stop, vi); + emotion_object_file_set(o, file); + emotion_object_audio_mute_set(o, EINA_TRUE); + emotion_object_keep_aspect_set(o, EMOTION_ASPECT_KEEP_NONE); + emotion_object_play_set(o, EINA_TRUE); + evas_object_pass_events_set(o, EINA_TRUE); + evas_object_move(o, -999, -999); + evas_object_resize(o, 9, 0); + evas_object_show(o); + vidimgs = eina_list_append(vidimgs, o); + return o; +} + +static void +vidimg_release(Evas_Object *o) +{ + Vidimg *vi; + Evas_Object *src = evas_object_data_get(o, "source"); + if (!src) return; + vi = evas_object_data_get(src, "vidimg"); + vi->copies = eina_list_remove(vi->copies, o); + if (!vi->copies) + { + vidimgs = eina_list_remove(vidimgs, src); + evas_object_data_del(src, "vidimg"); + if (vi->restart_job) ecore_job_del(vi->restart_job); + ecore_event_handler_del(vi->offhandler); + ecore_event_handler_del(vi->onhandler); + if (vi->offtimer) ecore_timer_del(vi->offtimer); + free(vi); + evas_object_del(src); + emotion_shutdown(); + } +} + + + + + +static void +_ob_resize(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) +{ + Video *sd = evas_object_smart_data_get(obj); + if (!sd) return; + evas_object_move(sd->o_vid, x, y); + evas_object_resize(sd->o_vid, w, h); +} + +static void _smart_calculate(Evas_Object *obj); + +static void +_smart_add(Evas_Object *obj) +{ + Video *sd; + Evas_Object *o; + + sd = calloc(1, sizeof(Video)); + EINA_SAFETY_ON_NULL_RETURN(sd); + evas_object_smart_data_set(obj, sd); + + _parent_sc.add(obj); + + o = evas_object_rectangle_add(evas_object_evas_get(obj)); + evas_object_smart_member_add(o, obj); + sd->clip = o; + evas_object_color_set(o, 255, 255, 255, 255); +} + +static void +_smart_del(Evas_Object *obj) +{ + Video *sd = evas_object_smart_data_get(obj); + if (!sd) return; + if (sd->clip) evas_object_del(sd->clip); + + vidimg_release(sd->o_vid); + + _parent_sc.del(obj); +} + +static void +_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) +{ + Video *sd = evas_object_smart_data_get(obj); + Evas_Coord ox, oy, ow, oh; + if (!sd) return; + evas_object_geometry_get(obj, &ox, &oy, &ow, &oh); + if ((ow == w) && (oh == h)) return; + evas_object_smart_changed(obj); + evas_object_resize(sd->clip, ow, oh); +} + +static void +_smart_calculate(Evas_Object *obj) +{ + Video *sd = evas_object_smart_data_get(obj); + Evas_Coord ox, oy, ow, oh; + + if (!sd) return; + evas_object_geometry_get(obj, &ox, &oy, &ow, &oh); + _ob_resize(obj, ox, oy, ow, oh); + evas_object_move(sd->clip, ox, oy); + evas_object_resize(sd->clip, ow, oh); +} + +static void +_smart_move(Evas_Object *obj, Evas_Coord x EINA_UNUSED, Evas_Coord y EINA_UNUSED) +{ + Video *sd = evas_object_smart_data_get(obj); + if (!sd) return; + evas_object_smart_changed(obj); +} + +static void +_smart_init(void) +{ + static Evas_Smart_Class sc; + + evas_object_smart_clipped_smart_set(&_parent_sc); + sc = _parent_sc; + sc.name = "video"; + sc.version = EVAS_SMART_CLASS_VERSION; + sc.add = _smart_add; + sc.del = _smart_del; + sc.resize = _smart_resize; + sc.move = _smart_move; + sc.calculate = _smart_calculate; + _smart = evas_smart_class_new(&sc); +} + +E_API Evas_Object * +e_video_add(Evas_Object *parent, const char *file, Eina_Bool lowq) +{ + Evas *e; + Evas_Object *obj, *o; + Video *sd; + + EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + e = evas_object_evas_get(parent); + if (!e) return NULL; + + if (!_smart) _smart_init(); + obj = evas_object_smart_add(e, _smart); + sd = evas_object_smart_data_get(obj); + if (!sd) return obj; + + sd->lowqual = lowq; + + o = sd->o_vid = vidimg_find(obj, file); + if (!o) + { + o = vidimg_video_add(obj, file); + if (!o) return obj; + o = sd->o_vid = vidimg_find(obj, file); + if (!o) return obj; + } + evas_object_smart_member_add(o, obj); + evas_object_clip_set(o, sd->clip); + evas_object_image_smooth_scale_set(o, !sd->lowqual); + return obj; +} + +E_API const char * +e_video_file_get(Evas_Object *obj) +{ + Video *sd; + Evas_Object *src; + + if (evas_object_smart_smart_get(obj) != _smart) return NULL; + if (!(sd = evas_object_smart_data_get(obj))) return NULL; + src = evas_object_data_get(sd->o_vid, "source"); + if (src) return emotion_object_file_get(src); + return NULL; +} diff --git a/src/bin/e_video.h b/src/bin/e_video.h new file mode 100644 index 000000000..5b9821974 --- /dev/null +++ b/src/bin/e_video.h @@ -0,0 +1,10 @@ +#ifdef E_TYPEDEFS +#else +# ifndef E_VIDEO_H +# define E_VIDEO_H + +E_API Evas_Object *e_video_add(Evas_Object *parent, const char *file, Eina_Bool lowq); +E_API const char *e_video_file_get(Evas_Object *obj); + +# endif +#endif diff --git a/src/bin/e_widget_bgpreview.c b/src/bin/e_widget_bgpreview.c index c4dbb207d..b07dbad6a 100644 --- a/src/bin/e_widget_bgpreview.c +++ b/src/bin/e_widget_bgpreview.c @@ -10,7 +10,7 @@ struct _E_Widget_Data typedef struct _E_Widget_Desk_Data E_Widget_Desk_Data; struct _E_Widget_Desk_Data { - Evas_Object *icon, *thumb, *live; + Evas_Object *icon, *thumb, *live, *cont; int zone, x, y; Ecore_Event_Handler *bg_upd_hdl; Ecore_Job *resize_job; @@ -84,6 +84,7 @@ E_API Evas_Object * e_widget_bgpreview_desk_add(Evas *e, E_Zone *zone, int x, int y) { E_Widget_Desk_Data *dd; + Evas_Object *o; const char *bgfile; bgfile = e_bg_file_get(zone->num, x, y); @@ -93,23 +94,46 @@ e_widget_bgpreview_desk_add(Evas *e, E_Zone *zone, int x, int y) dd->x = x; dd->y = y; - dd->live = e_livethumb_add(e); + dd->cont = evas_object_table_add(e); - dd->thumb = edje_object_add(e_livethumb_evas_get(dd->live)); - edje_object_file_set(dd->thumb, bgfile, "e/desktop/background"); - _bgpreview_viewport_update(dd->thumb, zone, x, y); - e_livethumb_thumb_set(dd->live, dd->thumb); - evas_object_show(dd->thumb); + if (eina_str_has_extension(bgfile, ".edj")) + { + dd->live = e_livethumb_add(e); + dd->thumb = o = edje_object_add(e_livethumb_evas_get(dd->live)); + edje_object_file_set(o, bgfile, "e/desktop/background"); + _bgpreview_viewport_update(o, zone, x, y); + e_livethumb_thumb_set(dd->live, o); + evas_object_show(dd->thumb); + } + else if ((eina_str_has_extension(bgfile, ".gif")) || + (eina_str_has_extension(bgfile, ".png")) || + (eina_str_has_extension(bgfile, ".jpg")) || + (eina_str_has_extension(bgfile, ".jpeg")) || + (eina_str_has_extension(bgfile, ".bmp"))) + { + dd->live = o = e_icon_add(e); + e_icon_file_key_set(o, bgfile, NULL); + e_icon_fill_inside_set(o, 0); + } + else + { + dd->live = o = e_video_add(e, bgfile, EINA_TRUE); + } eina_stringshare_del(bgfile); - evas_object_data_set(dd->live, "desk_data", dd); - evas_object_event_callback_add(dd->live, EVAS_CALLBACK_FREE, _e_wid_data_del, dd); - evas_object_event_callback_add(dd->live, EVAS_CALLBACK_RESIZE, _e_wid_livethumb_resize, dd); + evas_object_size_hint_weight_set(dd->live, 1, 1); + evas_object_size_hint_align_set(dd->live, -1, -1); + evas_object_table_pack(dd->cont, dd->live, 0, 0, 1, 1); + evas_object_show(dd->live); + + evas_object_data_set(dd->cont, "desk_data", dd); + evas_object_event_callback_add(dd->cont, EVAS_CALLBACK_DEL, _e_wid_data_del, dd); + evas_object_event_callback_add(dd->cont, EVAS_CALLBACK_RESIZE, _e_wid_livethumb_resize, dd); dd->bg_upd_hdl = ecore_event_handler_add(E_EVENT_BG_UPDATE, _e_wid_cb_bg_update, dd); - return dd->live; + return dd->cont; } E_API void @@ -139,25 +163,28 @@ _e_wid_livethumb_resize_job(void *data) E_Zone *zone; int w, h; - zone = e_comp_object_util_zone_get(dd->live); - if (!zone) zone = eina_list_data_get(e_comp->zones); - evas_object_geometry_get(dd->live, NULL, NULL, &w, &h); - if ((w != zone->w) || (h != zone->h)) + if (dd->thumb) { - w *= 2; - h *= 2; - if (w > 128) + zone = e_comp_object_util_zone_get(dd->live); + if (!zone) zone = eina_list_data_get(e_comp->zones); + evas_object_geometry_get(dd->live, NULL, NULL, &w, &h); + if ((w != zone->w) || (h != zone->h)) { - w = 128; - h = (zone->h * w) / zone->w; - } - if (h > 128) - { - h = 128; - w = (zone->w * h) / zone->h; + w *= 2; + h *= 2; + if (w > 128) + { + w = 128; + h = (zone->h * w) / zone->w; + } + if (h > 128) + { + h = 128; + w = (zone->w * h) / zone->h; + } } + e_livethumb_vsize_set(dd->live, w, h); } - e_livethumb_vsize_set(dd->live, w, h); dd->resize_job = NULL; } @@ -326,12 +353,46 @@ _e_wid_cb_bg_update(void *data, int type, void *event) { E_Zone *zone; const char *bgfile; + Evas_Object *o; + Evas *e = evas_object_evas_get(dd->cont); zone = e_comp_zone_number_get(dd->zone); bgfile = e_bg_file_get(dd->zone, dd->x, dd->y); - edje_object_file_set(dd->thumb, bgfile, "e/desktop/background"); - if (zone) _bgpreview_viewport_update(dd->thumb, zone, dd->x, dd->y); + + if (dd->thumb) evas_object_del(dd->thumb); + dd->thumb = NULL; + if (dd->live) evas_object_del(dd->live); + dd->live = NULL; + + if (eina_str_has_extension(bgfile, ".edj")) + { + dd->live = e_livethumb_add(e); + dd->thumb = o = edje_object_add(e_livethumb_evas_get(dd->live)); + edje_object_file_set(o, bgfile, "e/desktop/background"); + _bgpreview_viewport_update(o, zone, dd->x, dd->y); + e_livethumb_thumb_set(dd->live, o); + evas_object_show(dd->thumb); + } + else if ((eina_str_has_extension(bgfile, ".gif")) || + (eina_str_has_extension(bgfile, ".png")) || + (eina_str_has_extension(bgfile, ".jpg")) || + (eina_str_has_extension(bgfile, ".jpeg")) || + (eina_str_has_extension(bgfile, ".bmp"))) + { + dd->live = o = e_icon_add(e); + e_icon_file_key_set(o, bgfile, NULL); + e_icon_fill_inside_set(o, 0); + } + else + { + dd->live = o = e_video_add(e, bgfile, EINA_TRUE); + } eina_stringshare_del(bgfile); + + evas_object_size_hint_weight_set(dd->live, 1, 1); + evas_object_size_hint_align_set(dd->live, -1, -1); + evas_object_table_pack(dd->cont, dd->live, 0, 0, 1, 1); + evas_object_show(dd->live); } return ECORE_CALLBACK_PASS_ON; diff --git a/src/modules/conf_theme/e_int_config_wallpaper.c b/src/modules/conf_theme/e_int_config_wallpaper.c index 9b0f1cbbb..599c6662e 100644 --- a/src/modules/conf_theme/e_int_config_wallpaper.c +++ b/src/modules/conf_theme/e_int_config_wallpaper.c @@ -514,7 +514,23 @@ _basic_apply(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) if (!cfdata->bg) return 0; cw = cfd->data; - if (!eina_str_has_extension(cfdata->bg, ".edj")) + if ((!eina_str_has_extension(cfdata->bg, ".edj")) && + (!eina_str_has_extension(cfdata->bg, ".gif")) && + (!eina_str_has_extension(cfdata->bg, ".png")) && + (!eina_str_has_extension(cfdata->bg, ".jpg")) && + (!eina_str_has_extension(cfdata->bg, ".jpeg")) && + (!eina_str_has_extension(cfdata->bg, ".mp4")) && + (!eina_str_has_extension(cfdata->bg, ".m4v")) && + (!eina_str_has_extension(cfdata->bg, ".mp2")) && + (!eina_str_has_extension(cfdata->bg, ".mpg")) && + (!eina_str_has_extension(cfdata->bg, ".mpeg")) && + (!eina_str_has_extension(cfdata->bg, ".avi")) && + (!eina_str_has_extension(cfdata->bg, ".mov")) && + (!eina_str_has_extension(cfdata->bg, ".ogg")) && + (!eina_str_has_extension(cfdata->bg, ".ogv")) && + (!eina_str_has_extension(cfdata->bg, ".ts")) && + (!eina_str_has_extension(cfdata->bg, ".mov")) + ) { cfdata->import = e_import_config_dialog_show(cfd->dia->win, cfdata->bg, (Ecore_End_Cb)_apply_import_ok, NULL); e_object_del_attach_func_set(E_OBJECT(cfdata->import), _apply_import_del);