From 45d0b3400740927e68f28fc6f5c1db65c9a48743 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Wed, 29 Jun 2011 17:30:19 +0000 Subject: [PATCH] emotion: restore/save last know position for file. SVN revision: 60825 --- legacy/emotion/configure.ac | 37 ++++ legacy/emotion/src/bin/emotion_test_main.c | 11 +- legacy/emotion/src/lib/Emotion.h | 3 + legacy/emotion/src/lib/Makefile.am | 3 +- legacy/emotion/src/lib/emotion_smart.c | 216 ++++++++++++++++++--- 5 files changed, 233 insertions(+), 37 deletions(-) diff --git a/legacy/emotion/configure.ac b/legacy/emotion/configure.ac index 88c1bd6de5..bfddc57efe 100644 --- a/legacy/emotion/configure.ac +++ b/legacy/emotion/configure.ac @@ -177,6 +177,28 @@ case "$host_os" in esac AC_SUBST(lt_enable_auto_import) +### Check for extended attribute + +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include +#include + ]], + [[ +size_t tmp = listxattr("/", NULL, 0); +tmp = getxattr("/", "user.ethumb.md5", NULL, 0); +setxattr("/", "user.ethumb.md5", NULL, 0, 0); + ]])], + [ + AC_DEFINE(HAVE_XATTR, 1, [Define to 1 if you have 'listxattr', 'setxattr' and 'getxattr']) + have_xattr="yes" + ], + [have_xattr="no"]) + +AC_MSG_CHECKING([for Xattr]) +AC_MSG_RESULT([${have_xattr}]) ### Modules @@ -192,6 +214,18 @@ if test "x${enable_xine}" = "xno" && test "x${enable_gstreamer}" = "xno"; then AC_MSG_ERROR([Xine or Gstreamer backends must be selected to build Emotion]) fi +PKG_CHECK_MODULES([EIO], + [eio], + [ + have_eio="yes" + AC_DEFINE(HAVE_EIO, 1, [Use EIO for asynchronous file access]) + requirement_emotion="eio ${requirement_emotion}" + ], + [have_eio="no"]) + +AM_CONDITIONAL([HAVE_EIO], [test "x${have_eio}" = "xyes"]) + + AC_SUBST(requirement_emotion) #disabled vlc @@ -234,6 +268,9 @@ echo " edje_cc..............: ${edje_cc}" echo echo " Edje EXTERNAL support: ${have_edje_external}" echo +echo " Xattr................: ${have_xattr}" +echo " Eio..................: ${have_eio}" +echo echo "Compilation............: make (or gmake)" echo " CPPFLAGS.............: $CPPFLAGS" echo " CFLAGS...............: $CFLAGS" diff --git a/legacy/emotion/src/bin/emotion_test_main.c b/legacy/emotion/src/bin/emotion_test_main.c index 9625e8882c..f7902a2a25 100644 --- a/legacy/emotion/src/bin/emotion_test_main.c +++ b/legacy/emotion/src/bin/emotion_test_main.c @@ -77,13 +77,13 @@ main_resize(Ecore_Evas *ee) static Eina_Bool main_signal_exit(void *data __UNUSED__, int ev_type __UNUSED__, void *ev __UNUSED__) { + Evas_Object *o; + ecore_main_loop_quit(); - while (video_objs) + EINA_LIST_FREE(video_objs, o) { - printf("del obj!\n"); - evas_object_del(video_objs->data); - video_objs = eina_list_remove_list(video_objs, video_objs); - printf("done\n"); + emotion_object_last_position_save(o); + evas_object_del(o); } return EINA_TRUE; } @@ -564,6 +564,7 @@ init_video_object(const char *module_filename, const char *filename) { return; } + emotion_object_last_position_load(o); emotion_object_play_set(o, 1); evas_object_move(o, 0, 0); evas_object_resize(o, 320, 240); diff --git a/legacy/emotion/src/lib/Emotion.h b/legacy/emotion/src/lib/Emotion.h index 9a2b4f8136..f84153728f 100644 --- a/legacy/emotion/src/lib/Emotion.h +++ b/legacy/emotion/src/lib/Emotion.h @@ -174,6 +174,9 @@ EAPI void emotion_object_vis_set (Evas_Object *obj, Emotio EAPI Emotion_Vis emotion_object_vis_get (const Evas_Object *obj); EAPI Eina_Bool emotion_object_vis_supported (const Evas_Object *obj, Emotion_Vis visualization); +EAPI void emotion_object_last_position_load (Evas_Object *obj); +EAPI void emotion_object_last_position_save (Evas_Object *obj); + EAPI Eina_Bool emotion_object_extension_can_play_get(const Evas_Object *obj, const char *file); EAPI Eina_Bool emotion_object_extension_can_play_fast_get(const Evas_Object *obj, const char *file); diff --git a/legacy/emotion/src/lib/Makefile.am b/legacy/emotion/src/lib/Makefile.am index 96eabdd6b9..cf2dadce1e 100644 --- a/legacy/emotion/src/lib/Makefile.am +++ b/legacy/emotion/src/lib/Makefile.am @@ -9,6 +9,7 @@ AM_CPPFLAGS = \ -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ @EMOTION_CPPFLAGS@ \ @EMOTION_CFLAGS@ \ +@EIO_CFLAGS@ \ @EFL_EMOTION_BUILD@ if EMOTION_STATIC_BUILD_XINE @@ -46,7 +47,7 @@ libemotion_la_SOURCES += \ $(top_srcdir)/src/modules/vlc/emotion_vlc.c endif -libemotion_la_LIBADD = @EMOTION_LIBS@ +libemotion_la_LIBADD = @EMOTION_LIBS@ @EIO_LIBS@ if EMOTION_STATIC_BUILD_XINE libemotion_la_LIBADD += @XINE_LIBS@ diff --git a/legacy/emotion/src/lib/emotion_smart.c b/legacy/emotion/src/lib/emotion_smart.c index c9451d30de..c84d60c513 100644 --- a/legacy/emotion/src/lib/emotion_smart.c +++ b/legacy/emotion/src/lib/emotion_smart.c @@ -2,9 +2,11 @@ #include "Emotion.h" #ifdef HAVE_EIO +# include # include #else # ifdef HAVE_XATTR +# include # include # endif #endif @@ -45,6 +47,7 @@ typedef struct _Smart_Data Smart_Data; struct _Smart_Data { + EINA_REFCOUNT; Emotion_Video_Module *module; void *video; @@ -80,6 +83,8 @@ struct _Smart_Data #ifdef HAVE_EIO Eio_File *load_xattr; Eio_File *save_xattr; + + const char *time_seek; #endif Emotion_Module_Options module_options; @@ -172,16 +177,45 @@ _emotion_image_data_zero(Evas_Object *img) evas_object_image_data_set(img, data); } +static void +_emotion_module_close(Emotion_Video_Module *mod, void *video) +{ + if (!mod) return; + if (mod->plugin->close && video) + mod->plugin->close(mod, video); + /* FIXME: we can't go dlclosing here as a thread still may be running from + * the module - this in theory will leak- but it shouldnt be too bad and + * mean that once a module is dlopened() it cant be closed - its refcount + * will just keep going up + */ +} + +static void +_smart_data_free(Smart_Data *sd) +{ + if (sd->video) sd->module->file_close(sd->video); + _emotion_module_close(sd->module, sd->video); + evas_object_del(sd->obj); + eina_stringshare_del(sd->file); + free(sd->module_name); + if (sd->job) ecore_job_del(sd->job); + free(sd->progress.info); + free(sd->ref.file); + free(sd); + + ecore_shutdown(); +} + EAPI Eina_Bool -_emotion_module_register(const char *name, Emotion_Module_Open open, Emotion_Module_Close close) +_emotion_module_register(const char *name, Emotion_Module_Open mod_open, Emotion_Module_Close mod_close) { Eina_Emotion_Plugins *plugin; plugin = malloc(sizeof (Eina_Emotion_Plugins)); if (!plugin) return EINA_FALSE; - plugin->open = open; - plugin->close = close; + plugin->open = mod_open; + plugin->close = mod_close; return eina_hash_add(_backends, name, plugin); } @@ -241,19 +275,6 @@ _emotion_module_open(const char *name, Evas_Object *obj, Emotion_Video_Module ** return NULL; } -static void -_emotion_module_close(Emotion_Video_Module *mod, void *video) -{ - if (!mod) return; - if (mod->plugin->close && video) - mod->plugin->close(mod, video); - /* FIXME: we can't go dlclosing here as a thread still may be running from - * the module - this in theory will leak- but it shouldnt be too bad and - * mean that once a module is dlopened() it cant be closed - its refcount - * will just keep going up - */ -} - /*******************************/ /* Externally accessible calls */ /*******************************/ @@ -315,8 +336,6 @@ emotion_object_init(Evas_Object *obj, const char *module_filename) sd->seek_pos = 0; sd->len = 0; - ecore_init(); - _emotion_module_close(sd->module, sd->video); sd->module = NULL; sd->video = NULL; @@ -1002,6 +1021,147 @@ emotion_object_vis_supported(const Evas_Object *obj, Emotion_Vis visualization) return sd->module->vis_supported(sd->video, visualization); } +#ifdef HAVE_EIO +static void +_eio_load_xattr_cleanup(Smart_Data *sd) +{ + sd->load_xattr = NULL; + + EINA_REFCOUNT_UNREF(sd) + _smart_data_free(sd); +} + +static void +_eio_load_xattr_done(void *data, Eio_File *handler __UNUSED__, const char *xattr_data, unsigned int xattr_size) +{ + Smart_Data *sd = data; + + if (xattr_size < 128 && xattr_data[xattr_size] == '\0') + { + long long int m = 0; + long int e = 0; + + eina_convert_atod(xattr_data, xattr_size, &m, &e); + emotion_object_position_set(evas_object_smart_parent_get(sd->obj), ldexp((double)m, e)); + } + + _eio_load_xattr_cleanup(sd); +} + +static void +_eio_load_xattr_error(void *data, Eio_File *handler __UNUSED__, int err __UNUSED__) +{ + Smart_Data *sd = data; + + _eio_load_xattr_cleanup(sd); +} +#endif + +EAPI void +emotion_object_last_position_load(Evas_Object *obj) +{ + Smart_Data *sd; + const char *tmp; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + if (!sd->file) return ; + + if (!strncmp(sd->file, "file://", 7)) + tmp = sd->file + 7; + else if (!strstr(sd->file, "://")) + tmp = sd->file; + else + return ; + +#ifdef HAVE_EIO + if (sd->load_xattr) return ; + + EINA_REFCOUNT_REF(sd); + + sd->load_xattr = eio_file_xattr_get(tmp, "user.e.time_seek", _eio_load_xattr_done, _eio_load_xattr_error, sd); +#else +# ifdef HAVE_XATTR + { + char double_to_string[128]; + ssize_t sz; + long long int m = 0; + long int e = 0; + + sz = getxattr(tmp, "user.e.time_seek", double_to_string, 128); + if (sz <= 0 || sz > 128 || double_to_string[sz] != '\0') + return ; + + eina_convert_atod(double_to_string, 128, &m, &e); + emotion_object_position_set(obj, ldexp((double)m, e)); + } +# endif +#endif +} + +#ifdef HAVE_EIO +static void +_eio_save_xattr_cleanup(Smart_Data *sd) +{ + sd->save_xattr = NULL; + eina_stringshare_del(sd->time_seek); + sd->time_seek = NULL; + + EINA_REFCOUNT_UNREF(sd) + _smart_data_free(sd); +} + +static void +_eio_save_xattr_done(void *data, Eio_File *handler __UNUSED__) +{ + Smart_Data *sd = data; + + _eio_save_xattr_cleanup(sd); +} + +static void +_eio_save_xattr_error(void *data, Eio_File *handler __UNUSED__, int err __UNUSED__) +{ + Smart_Data *sd = data; + + _eio_save_xattr_cleanup(sd); +} +#endif + +EAPI void +emotion_object_last_position_save(Evas_Object *obj) +{ + Smart_Data *sd; + const char *tmp; + char double_to_string[128]; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + if (!sd->file) return ; + + if (!strncmp(sd->file, "file://", 7)) + tmp = sd->file + 7; + else if (!strstr(sd->file, "://")) + tmp = sd->file; + else + return ; + + eina_convert_dtoa(emotion_object_position_get(obj), double_to_string); + +#ifdef HAVE_EIO + if (sd->save_xattr) return ; + + EINA_REFCOUNT_REF(sd); + + sd->time_seek = eina_stringshare_add(double_to_string); + sd->save_xattr = eio_file_xattr_set(tmp, "user.e.time_seek", + sd->time_seek, eina_stringshare_strlen(sd->time_seek) + 1, 0, + _eio_save_xattr_done, _eio_save_xattr_error, sd); +#else +# ifdef HAVE_XATTR + setxattr(tmp, "user.e.time_seek", double_to_string, strlen(double_to_string), 0); +# endif +#endif +} + EAPI Eina_Bool emotion_object_extension_can_play_fast_get(const Evas_Object *obj, const char *file) { @@ -1257,14 +1417,14 @@ _emotion_title_set(Evas_Object *obj, char *title) } EAPI void -_emotion_progress_set(Evas_Object *obj, char *info, double stat) +_emotion_progress_set(Evas_Object *obj, char *info, double st) { Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); free(sd->progress.info); sd->progress.info = strdup(info); - sd->progress.stat = stat; + sd->progress.stat = st; evas_object_smart_callback_call(obj, SIG_PROGRESS_CHANGE, NULL); } @@ -1581,6 +1741,7 @@ _smart_add(Evas_Object * obj) sd = calloc(1, sizeof(Smart_Data)); if (!sd) return; + EINA_REFCOUNT_INIT(sd); sd->obj = evas_object_image_add(evas_object_evas_get(obj)); evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, sd); evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, sd); @@ -1596,6 +1757,8 @@ _smart_add(Evas_Object * obj) evas_object_image_data_set(obj, pixel); } evas_object_smart_data_set(obj, sd); + + ecore_init(); } static void @@ -1605,17 +1768,8 @@ _smart_del(Evas_Object * obj) sd = evas_object_smart_data_get(obj); if (!sd) return; - if (sd->video) sd->module->file_close(sd->video); - _emotion_module_close(sd->module, sd->video); - evas_object_del(sd->obj); - eina_stringshare_del(sd->file); - free(sd->module_name); - if (sd->job) ecore_job_del(sd->job); - free(sd->progress.info); - free(sd->ref.file); - free(sd); - - ecore_shutdown(); + EINA_REFCOUNT_UNREF(sd) + _smart_data_free(sd); } static void