elm: convert downloads to efl_net_dialer_http.
Remove Elm_Url and use efl_net_dialer_http with an efl_io_copier to fetch stuff. The code was also slightly improved, particularly in elm_photocam destruction be explicit and clear the grid before deleting... this will ensure any pending preload are stopped before we remove the backing memory.
This commit is contained in:
parent
6062109707
commit
fa8630a9b1
|
@ -638,7 +638,6 @@ lib_elementary_libelementary_la_SOURCES = \
|
|||
lib/elementary/elm_toolbar.c \
|
||||
lib/elementary/elm_transit.c \
|
||||
lib/elementary/elm_util.c \
|
||||
lib/elementary/elm_url.c \
|
||||
lib/elementary/efl_ui_video.c \
|
||||
lib/elementary/elm_view_list.c \
|
||||
lib/elementary/elm_view_form.c \
|
||||
|
|
|
@ -46,6 +46,7 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = {
|
|||
|
||||
static Eina_Bool _key_action_activate(Evas_Object *obj, const char *params);
|
||||
static Eina_Bool _efl_ui_image_smart_internal_file_set(Eo *obj, Efl_Ui_Image_Data *sd, const char *file, const Eina_File *f, const char *key);
|
||||
static void _efl_ui_image_remote_copier_cancel(Eo *obj, Efl_Ui_Image_Data *sd);
|
||||
|
||||
static const Elm_Action key_actions[] = {
|
||||
{"activate", _key_action_activate},
|
||||
|
@ -561,10 +562,10 @@ _efl_ui_image_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Image_Data *sd)
|
|||
ecore_timer_del(sd->anim_timer);
|
||||
evas_object_del(sd->img);
|
||||
_prev_img_del(sd);
|
||||
if (sd->remote) _elm_url_cancel(sd->remote);
|
||||
free(sd->remote_data);
|
||||
eina_stringshare_del(sd->key);
|
||||
_async_cancel(sd);
|
||||
if (sd->remote.copier) _efl_ui_image_remote_copier_cancel(obj, sd);
|
||||
if (sd->remote.binbuf) ELM_SAFE_FREE(sd->remote.binbuf, eina_binbuf_free);
|
||||
ELM_SAFE_FREE(sd->remote.key, eina_stringshare_del);
|
||||
efl_canvas_group_del(efl_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
|
@ -832,11 +833,15 @@ _efl_ui_image_efl_file_mmap_set(Eo *obj, Efl_Ui_Image_Data *sd,
|
|||
{
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
if (sd->remote) _elm_url_cancel(sd->remote);
|
||||
sd->remote = NULL;
|
||||
|
||||
_async_cancel(sd);
|
||||
|
||||
/* stop preloading as it may hit to-be-freed memory */
|
||||
if (sd->preload_status == EFL_UI_IMAGE_PRELOADING)
|
||||
evas_object_image_preload(sd->img, EINA_TRUE);
|
||||
|
||||
if (sd->remote.copier) _efl_ui_image_remote_copier_cancel(obj, sd);
|
||||
if (sd->remote.binbuf) ELM_SAFE_FREE(sd->remote.binbuf, eina_binbuf_free);
|
||||
|
||||
if (!sd->async_enable)
|
||||
ret = _efl_ui_image_smart_internal_file_set(obj, sd, eina_file_filename_get(file), file, key);
|
||||
else
|
||||
|
@ -895,30 +900,66 @@ _efl_ui_image_smart_internal_file_set(Eo *obj, Efl_Ui_Image_Data *sd,
|
|||
}
|
||||
|
||||
static void
|
||||
_efl_ui_image_smart_download_done(void *data, Elm_Url *url, Eina_Binbuf *download)
|
||||
_efl_ui_image_remote_copier_del(void *data EINA_UNUSED, const Efl_Event *event)
|
||||
{
|
||||
Eo *dialer = efl_io_copier_source_get(event->object);
|
||||
efl_del(dialer);
|
||||
}
|
||||
|
||||
static void
|
||||
_efl_ui_image_remote_copier_cancel(Eo *obj EINA_UNUSED, Efl_Ui_Image_Data *sd)
|
||||
{
|
||||
Eo *copier = sd->remote.copier;
|
||||
|
||||
if (!copier) return;
|
||||
/* copier is flagged as close_on_destructor, thus:
|
||||
* efl_del()
|
||||
* -> efl_io_closer_close()
|
||||
* -> "done" event
|
||||
* -> _efl_ui_image_remote_copier_done()
|
||||
*
|
||||
* flag sd->remote.copier = NULL so _efl_ui_image_remote_copier_done()
|
||||
* knows about it.
|
||||
*/
|
||||
sd->remote.copier = NULL;
|
||||
efl_del(copier);
|
||||
}
|
||||
|
||||
static void
|
||||
_efl_ui_image_remote_copier_done(void *data, const Efl_Event *event EINA_UNUSED)
|
||||
{
|
||||
Eo *obj = data;
|
||||
Efl_Ui_Image_Data *sd = efl_data_scope_get(obj, MY_CLASS);
|
||||
Eina_File *f;
|
||||
size_t length;
|
||||
Eo *dialer;
|
||||
const char *url;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
free(sd->remote_data);
|
||||
length = eina_binbuf_length_get(download);
|
||||
sd->remote_data = eina_binbuf_string_steal(download);
|
||||
f = eina_file_virtualize(_elm_url_get(url),
|
||||
sd->remote_data, length,
|
||||
/* we're called from _efl_ui_image_remote_copier_cancel() */
|
||||
if (!sd->remote.copier) return;
|
||||
|
||||
/* stop preloading as it may hit to-be-freed memory */
|
||||
if (sd->preload_status == EFL_UI_IMAGE_PRELOADING)
|
||||
evas_object_image_preload(sd->img, EINA_TRUE);
|
||||
|
||||
if (sd->remote.binbuf) eina_binbuf_free(sd->remote.binbuf);
|
||||
sd->remote.binbuf = efl_io_copier_binbuf_steal(sd->remote.copier);
|
||||
|
||||
dialer = efl_io_copier_source_get(sd->remote.copier);
|
||||
url = efl_net_dialer_address_dial_get(dialer);
|
||||
f = eina_file_virtualize(url,
|
||||
eina_binbuf_string_get(sd->remote.binbuf),
|
||||
eina_binbuf_length_get(sd->remote.binbuf),
|
||||
EINA_FALSE);
|
||||
ret = _efl_ui_image_smart_internal_file_set(obj, sd, _elm_url_get(url), f, sd->key);
|
||||
|
||||
ret = _efl_ui_image_smart_internal_file_set(obj, sd, url, f, sd->remote.key);
|
||||
eina_file_close(f);
|
||||
|
||||
sd->remote = NULL;
|
||||
if (!ret)
|
||||
{
|
||||
Efl_Ui_Image_Error err = { 0, EINA_TRUE };
|
||||
|
||||
free(sd->remote_data);
|
||||
sd->remote_data = NULL;
|
||||
ELM_SAFE_FREE(sd->remote.binbuf, eina_binbuf_free);
|
||||
evas_object_smart_callback_call(obj, SIG_DOWNLOAD_ERROR, &err);
|
||||
}
|
||||
else
|
||||
|
@ -931,45 +972,117 @@ _efl_ui_image_smart_download_done(void *data, Elm_Url *url, Eina_Binbuf *downloa
|
|||
evas_object_smart_callback_call(obj, SIG_DOWNLOAD_DONE, NULL);
|
||||
}
|
||||
|
||||
ELM_SAFE_FREE(sd->key, eina_stringshare_del);
|
||||
ELM_SAFE_FREE(sd->remote.key, eina_stringshare_del);
|
||||
ELM_SAFE_FREE(sd->remote.copier, efl_del);
|
||||
}
|
||||
|
||||
static void
|
||||
_efl_ui_image_smart_download_cancel(void *data, Elm_Url *url EINA_UNUSED, int error)
|
||||
_efl_ui_image_remote_copier_error(void *data, const Efl_Event *event)
|
||||
{
|
||||
Eo *obj = data;
|
||||
Efl_Ui_Image_Data *sd = efl_data_scope_get(obj, MY_CLASS);
|
||||
Efl_Ui_Image_Error err = { error, EINA_FALSE };
|
||||
Eina_Error *perr = event->info;
|
||||
Efl_Ui_Image_Error err = { *perr, EINA_FALSE };
|
||||
|
||||
evas_object_smart_callback_call(obj, SIG_DOWNLOAD_ERROR, &err);
|
||||
|
||||
sd->remote = NULL;
|
||||
ELM_SAFE_FREE(sd->key, eina_stringshare_del);
|
||||
_efl_ui_image_remote_copier_cancel(obj, sd);
|
||||
ELM_SAFE_FREE(sd->remote.key, eina_stringshare_del);
|
||||
}
|
||||
|
||||
static void
|
||||
_efl_ui_image_smart_download_progress(void *data, Elm_Url *url EINA_UNUSED, double now, double total)
|
||||
_efl_ui_image_remote_copier_progress(void *data, const Efl_Event *event)
|
||||
{
|
||||
Eo *obj = data;
|
||||
Efl_Ui_Image_Progress progress;
|
||||
uint64_t now, total;
|
||||
|
||||
efl_io_copier_progress_get(event->object, &now, NULL, &total);
|
||||
|
||||
progress.now = now;
|
||||
progress.total = total;
|
||||
evas_object_smart_callback_call(obj, SIG_DOWNLOAD_PROGRESS, &progress);
|
||||
}
|
||||
|
||||
static const char *remote_uri[] = {
|
||||
"http://", "https://", "ftp://"
|
||||
EFL_CALLBACKS_ARRAY_DEFINE(_efl_ui_image_remote_copier_cbs,
|
||||
{ EFL_EVENT_DEL, _efl_ui_image_remote_copier_del },
|
||||
{ EFL_IO_COPIER_EVENT_DONE, _efl_ui_image_remote_copier_done },
|
||||
{ EFL_IO_COPIER_EVENT_ERROR, _efl_ui_image_remote_copier_error },
|
||||
{ EFL_IO_COPIER_EVENT_PROGRESS, _efl_ui_image_remote_copier_progress });
|
||||
|
||||
static Eina_Bool
|
||||
_efl_ui_image_download(Eo *obj, Efl_Ui_Image_Data *sd, const char *url, const char *key)
|
||||
{
|
||||
Eo *dialer;
|
||||
Efl_Ui_Image_Error img_err = { ENOSYS, EINA_FALSE };
|
||||
Eina_Error err;
|
||||
|
||||
dialer = efl_add(EFL_NET_DIALER_HTTP_CLASS, obj,
|
||||
efl_net_dialer_http_allow_redirects_set(efl_added, EINA_TRUE));
|
||||
EINA_SAFETY_ON_NULL_GOTO(dialer, error_dialer);
|
||||
|
||||
sd->remote.copier = efl_add(EFL_IO_COPIER_CLASS, obj,
|
||||
efl_io_copier_source_set(efl_added, dialer),
|
||||
efl_io_closer_close_on_destructor_set(efl_added, EINA_TRUE),
|
||||
efl_event_callback_array_add(efl_added, _efl_ui_image_remote_copier_cbs(), obj));
|
||||
EINA_SAFETY_ON_NULL_GOTO(sd->remote.copier, error_copier);
|
||||
eina_stringshare_replace(&sd->remote.key, key);
|
||||
|
||||
err = efl_net_dialer_dial(dialer, url);
|
||||
if (err)
|
||||
{
|
||||
img_err.status = err;
|
||||
ERR("Could not download %s: %s", url, eina_error_msg_get(err));
|
||||
evas_object_smart_callback_call(obj, SIG_DOWNLOAD_ERROR, &img_err);
|
||||
goto error_dial;
|
||||
}
|
||||
return EINA_TRUE;
|
||||
|
||||
error_dial:
|
||||
evas_object_smart_callback_call(obj, SIG_DOWNLOAD_ERROR, &img_err);
|
||||
_efl_ui_image_remote_copier_cancel(obj, sd);
|
||||
return EINA_FALSE;
|
||||
|
||||
error_copier:
|
||||
efl_del(dialer);
|
||||
error_dialer:
|
||||
evas_object_smart_callback_call(obj, SIG_DOWNLOAD_ERROR, &img_err);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static const Eina_Slice remote_uri[] = {
|
||||
EINA_SLICE_STR_LITERAL("http://"),
|
||||
EINA_SLICE_STR_LITERAL("https://"),
|
||||
EINA_SLICE_STR_LITERAL("ftp://"),
|
||||
{ }
|
||||
};
|
||||
|
||||
static inline Eina_Bool
|
||||
_efl_ui_image_is_remote(const char *file)
|
||||
{
|
||||
Eina_Slice s = EINA_SLICE_STR(file);
|
||||
const Eina_Slice *itr;
|
||||
|
||||
for (itr = remote_uri; itr->mem; itr++)
|
||||
if (eina_slice_startswith(s, *itr))
|
||||
return EINA_TRUE;
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_ui_image_efl_file_file_set(Eo *obj, Efl_Ui_Image_Data *sd, const char *file, const char *key)
|
||||
{
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
unsigned int i;
|
||||
|
||||
if (sd->remote) _elm_url_cancel(sd->remote);
|
||||
sd->remote = NULL;
|
||||
_async_cancel(sd);
|
||||
|
||||
/* stop preloading as it may hit to-be-freed memory */
|
||||
if (sd->preload_status == EFL_UI_IMAGE_PRELOADING)
|
||||
evas_object_image_preload(sd->img, EINA_TRUE);
|
||||
|
||||
if (sd->remote.copier) _efl_ui_image_remote_copier_cancel(obj, sd);
|
||||
if (sd->remote.binbuf) ELM_SAFE_FREE(sd->remote.binbuf, eina_binbuf_free);
|
||||
|
||||
if (sd->anim)
|
||||
{
|
||||
|
@ -978,27 +1091,16 @@ _efl_ui_image_efl_file_file_set(Eo *obj, Efl_Ui_Image_Data *sd, const char *file
|
|||
sd->anim = EINA_FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof (remote_uri) / sizeof (remote_uri[0]); ++i)
|
||||
if (file && !strncmp(remote_uri[i], file, strlen(remote_uri[i])))
|
||||
if (_efl_ui_image_is_remote(file))
|
||||
{
|
||||
// Found a remote target !
|
||||
evas_object_hide(sd->img);
|
||||
sd->remote = _elm_url_download(file,
|
||||
_efl_ui_image_smart_download_done,
|
||||
_efl_ui_image_smart_download_cancel,
|
||||
_efl_ui_image_smart_download_progress,
|
||||
obj);
|
||||
if (sd->remote)
|
||||
if (_efl_ui_image_download(obj, sd, file, key))
|
||||
{
|
||||
evas_object_smart_callback_call(obj, SIG_DOWNLOAD_START, NULL);
|
||||
eina_stringshare_replace(&sd->key, key);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
_async_cancel(sd);
|
||||
|
||||
if (!sd->async_enable)
|
||||
ret = _efl_ui_image_smart_internal_file_set(obj, sd, file, NULL, key);
|
||||
else
|
||||
|
|
|
@ -48,9 +48,12 @@ struct _Efl_Ui_Image_Data
|
|||
Evas_Object *prev_img;
|
||||
Ecore_Timer *anim_timer;
|
||||
|
||||
Elm_Url *remote;
|
||||
|
||||
struct {
|
||||
Eo *copier;
|
||||
Eina_Binbuf *binbuf;
|
||||
const char *key;
|
||||
void *remote_data;
|
||||
} remote;
|
||||
|
||||
double scale;
|
||||
double frame_duration;
|
||||
|
|
|
@ -85,6 +85,7 @@ static Eina_Error PHOTO_FILE_LOAD_ERROR_UNKNOWN_FORMAT;
|
|||
|
||||
static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
|
||||
static Eina_Bool _key_action_zoom(Evas_Object *obj, const char *params);
|
||||
static void _elm_photocam_remote_copier_cancel(Eo *obj, Elm_Photocam_Data *sd);
|
||||
|
||||
static const Elm_Action key_actions[] = {
|
||||
{"move", _key_action_move},
|
||||
|
@ -1461,14 +1462,15 @@ _elm_photocam_efl_canvas_group_group_del(Eo *obj, Elm_Photocam_Data *sd)
|
|||
|
||||
EINA_LIST_FREE(sd->grids, g)
|
||||
{
|
||||
_grid_clear(obj, g);
|
||||
free(g->grid);
|
||||
free(g);
|
||||
}
|
||||
ELM_SAFE_FREE(sd->pan_obj, evas_object_del);
|
||||
|
||||
if (sd->f) eina_file_close(sd->f);
|
||||
free(sd->remote_data);
|
||||
if (sd->remote) _elm_url_cancel(sd->remote);
|
||||
if (sd->remote.copier) _elm_photocam_remote_copier_cancel(obj, sd);
|
||||
if (sd->remote.binbuf) ELM_SAFE_FREE(sd->remote.binbuf, eina_binbuf_free);
|
||||
eina_stringshare_del(sd->file);
|
||||
ecore_job_del(sd->calc_job);
|
||||
ecore_timer_del(sd->scr_timer);
|
||||
|
@ -1596,29 +1598,62 @@ _internal_file_set(Eo *obj, Elm_Photocam_Data *sd, const char *file, Eina_File *
|
|||
}
|
||||
|
||||
static void
|
||||
_elm_photocam_download_done(void *data, Elm_Url *url EINA_UNUSED, Eina_Binbuf *download)
|
||||
_elm_photocam_remote_copier_del(void *data EINA_UNUSED, const Efl_Event *event)
|
||||
{
|
||||
Eo *dialer = efl_io_copier_source_get(event->object);
|
||||
efl_del(dialer);
|
||||
}
|
||||
|
||||
static void
|
||||
_elm_photocam_remote_copier_cancel(Eo *obj EINA_UNUSED, Elm_Photocam_Data *sd)
|
||||
{
|
||||
Eo *copier = sd->remote.copier;
|
||||
|
||||
if (!copier) return;
|
||||
/* copier is flagged as close_on_destructor, thus:
|
||||
* efl_del()
|
||||
* -> efl_io_closer_close()
|
||||
* -> "done" event
|
||||
* -> _elm_photocam_remote_copier_done()
|
||||
*
|
||||
* flag sd->remote.copier = NULL so _elm_photocam_remote_copier_done()
|
||||
* knows about it.
|
||||
*/
|
||||
sd->remote.copier = NULL;
|
||||
efl_del(copier);
|
||||
}
|
||||
|
||||
static void
|
||||
_elm_photocam_remote_copier_done(void *data, const Efl_Event *event EINA_UNUSED)
|
||||
{
|
||||
Eo *obj = data;
|
||||
Elm_Photocam_Data *sd = efl_data_scope_get(obj, MY_CLASS);
|
||||
Eina_File *f;
|
||||
size_t length;
|
||||
Eo *dialer;
|
||||
const char *url;
|
||||
Evas_Load_Error ret = EVAS_LOAD_ERROR_NONE;
|
||||
|
||||
free(sd->remote_data);
|
||||
length = eina_binbuf_length_get(download);
|
||||
sd->remote_data = eina_binbuf_string_steal(download);
|
||||
f = eina_file_virtualize(_elm_url_get(url),
|
||||
sd->remote_data, length,
|
||||
/* we're called from _elm_photocam_remote_copier_cancel() */
|
||||
if (!sd->remote.copier) return;
|
||||
|
||||
if (sd->remote.binbuf) eina_binbuf_free(sd->remote.binbuf);
|
||||
sd->remote.binbuf = efl_io_copier_binbuf_steal(sd->remote.copier);
|
||||
|
||||
dialer = efl_io_copier_source_get(sd->remote.copier);
|
||||
url = efl_net_dialer_address_dial_get(dialer);
|
||||
f = eina_file_virtualize(url,
|
||||
eina_binbuf_string_get(sd->remote.binbuf),
|
||||
eina_binbuf_length_get(sd->remote.binbuf),
|
||||
EINA_FALSE);
|
||||
_internal_file_set(obj, sd, _elm_url_get(url), f, &ret);
|
||||
|
||||
_internal_file_set(obj, sd, url, f, &ret);
|
||||
eina_file_close(f);
|
||||
|
||||
if (ret != EVAS_LOAD_ERROR_NONE)
|
||||
{
|
||||
Elm_Photocam_Error err = { 0, EINA_TRUE };
|
||||
|
||||
free(sd->remote_data);
|
||||
sd->remote_data = NULL;
|
||||
ELM_SAFE_FREE(sd->remote.binbuf, eina_binbuf_free);
|
||||
efl_event_callback_legacy_call
|
||||
(obj, ELM_PHOTOCAM_EVENT_DOWNLOAD_ERROR, &err);
|
||||
}
|
||||
|
@ -1628,26 +1663,29 @@ _elm_photocam_download_done(void *data, Elm_Url *url EINA_UNUSED, Eina_Binbuf *d
|
|||
(obj, ELM_PHOTOCAM_EVENT_DOWNLOAD_DONE, NULL);
|
||||
}
|
||||
|
||||
sd->remote = NULL;
|
||||
ELM_SAFE_FREE(sd->remote.copier, efl_del);
|
||||
}
|
||||
|
||||
static void
|
||||
_elm_photocam_download_cancel(void *data, Elm_Url *url EINA_UNUSED, int error)
|
||||
_elm_photocam_remote_copier_error(void *data, const Efl_Event *event)
|
||||
{
|
||||
Eo *obj = data;
|
||||
Elm_Photocam_Data *sd = efl_data_scope_get(obj, MY_CLASS);
|
||||
Elm_Photocam_Error err = { error, EINA_FALSE };
|
||||
Eina_Error *perr = event->info;
|
||||
Elm_Photocam_Error err = { *perr, EINA_FALSE };
|
||||
|
||||
efl_event_callback_legacy_call(obj, ELM_PHOTOCAM_EVENT_DOWNLOAD_ERROR, &err);
|
||||
|
||||
sd->remote = NULL;
|
||||
_elm_photocam_remote_copier_cancel(obj, sd);
|
||||
}
|
||||
|
||||
static void
|
||||
_elm_photocam_download_progress(void *data, Elm_Url *url EINA_UNUSED, double now, double total)
|
||||
_elm_photocam_remote_copier_progress(void *data, const Efl_Event *event)
|
||||
{
|
||||
Eo *obj = data;
|
||||
Elm_Photocam_Progress progress;
|
||||
uint64_t now, total;
|
||||
|
||||
efl_io_copier_progress_get(event->object, &now, NULL, &total);
|
||||
|
||||
progress.now = now;
|
||||
progress.total = total;
|
||||
|
@ -1655,15 +1693,75 @@ _elm_photocam_download_progress(void *data, Elm_Url *url EINA_UNUSED, double now
|
|||
(obj, ELM_PHOTOCAM_EVENT_DOWNLOAD_PROGRESS, &progress);
|
||||
}
|
||||
|
||||
static const char *remote_uri[] = {
|
||||
"http://", "https://", "ftp://"
|
||||
EFL_CALLBACKS_ARRAY_DEFINE(_elm_photocam_remote_copier_cbs,
|
||||
{ EFL_EVENT_DEL, _elm_photocam_remote_copier_del },
|
||||
{ EFL_IO_COPIER_EVENT_DONE, _elm_photocam_remote_copier_done },
|
||||
{ EFL_IO_COPIER_EVENT_ERROR, _elm_photocam_remote_copier_error },
|
||||
{ EFL_IO_COPIER_EVENT_PROGRESS, _elm_photocam_remote_copier_progress });
|
||||
|
||||
static Eina_Bool
|
||||
_elm_photocam_download(Eo *obj, Elm_Photocam_Data *sd, const char *url)
|
||||
{
|
||||
Eo *dialer;
|
||||
Elm_Photocam_Error img_err = { ENOSYS, EINA_FALSE };
|
||||
Eina_Error err;
|
||||
|
||||
dialer = efl_add(EFL_NET_DIALER_HTTP_CLASS, obj,
|
||||
efl_net_dialer_http_allow_redirects_set(efl_added, EINA_TRUE));
|
||||
EINA_SAFETY_ON_NULL_GOTO(dialer, error_dialer);
|
||||
|
||||
sd->remote.copier = efl_add(EFL_IO_COPIER_CLASS, obj,
|
||||
efl_io_copier_source_set(efl_added, dialer),
|
||||
efl_io_closer_close_on_destructor_set(efl_added, EINA_TRUE),
|
||||
efl_event_callback_array_add(efl_added, _elm_photocam_remote_copier_cbs(), obj));
|
||||
EINA_SAFETY_ON_NULL_GOTO(sd->remote.copier, error_copier);
|
||||
|
||||
err = efl_net_dialer_dial(dialer, url);
|
||||
if (err)
|
||||
{
|
||||
img_err.status = err;
|
||||
ERR("Could not download %s: %s", url, eina_error_msg_get(err));
|
||||
evas_object_smart_callback_call(obj, SIG_DOWNLOAD_ERROR, &img_err);
|
||||
goto error_dial;
|
||||
}
|
||||
return EINA_TRUE;
|
||||
|
||||
error_dial:
|
||||
evas_object_smart_callback_call(obj, SIG_DOWNLOAD_ERROR, &img_err);
|
||||
_elm_photocam_remote_copier_cancel(obj, sd);
|
||||
return EINA_FALSE;
|
||||
|
||||
error_copier:
|
||||
efl_del(dialer);
|
||||
error_dialer:
|
||||
evas_object_smart_callback_call(obj, SIG_DOWNLOAD_ERROR, &img_err);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static const Eina_Slice remote_uri[] = {
|
||||
EINA_SLICE_STR_LITERAL("http://"),
|
||||
EINA_SLICE_STR_LITERAL("https://"),
|
||||
EINA_SLICE_STR_LITERAL("ftp://"),
|
||||
{ }
|
||||
};
|
||||
|
||||
static inline Eina_Bool
|
||||
_elm_photocam_is_remote(const char *file)
|
||||
{
|
||||
Eina_Slice s = EINA_SLICE_STR(file);
|
||||
const Eina_Slice *itr;
|
||||
|
||||
for (itr = remote_uri; itr->mem; itr++)
|
||||
if (eina_slice_startswith(s, *itr))
|
||||
return EINA_TRUE;
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Evas_Load_Error
|
||||
_elm_photocam_file_set_internal(Eo *obj, Elm_Photocam_Data *sd, const char *file)
|
||||
{
|
||||
Evas_Load_Error ret = EVAS_LOAD_ERROR_NONE;
|
||||
unsigned int i;
|
||||
|
||||
_grid_clear_all(obj);
|
||||
_elm_photocam_zoom_reset(obj, sd);
|
||||
|
@ -1676,27 +1774,19 @@ _elm_photocam_file_set_internal(Eo *obj, Elm_Photocam_Data *sd, const char *file
|
|||
if (sd->f) eina_file_close(sd->f);
|
||||
sd->f = NULL;
|
||||
|
||||
free(sd->remote_data);
|
||||
if (sd->remote) _elm_url_cancel(sd->remote);
|
||||
sd->remote = NULL;
|
||||
if (sd->remote.copier) _elm_photocam_remote_copier_cancel(obj, sd);
|
||||
if (sd->remote.binbuf) ELM_SAFE_FREE(sd->remote.binbuf, eina_binbuf_free);
|
||||
|
||||
sd->preload_num = 0;
|
||||
|
||||
for (i = 0; i < sizeof (remote_uri) / sizeof (remote_uri[0]); ++i)
|
||||
if (!strncmp(remote_uri[i], file, strlen(remote_uri[i])))
|
||||
if (_elm_photocam_is_remote(file))
|
||||
{
|
||||
// Found a remote target !
|
||||
sd->remote = _elm_url_download(file,
|
||||
_elm_photocam_download_done,
|
||||
_elm_photocam_download_cancel,
|
||||
_elm_photocam_download_progress,
|
||||
obj);
|
||||
if (sd->remote)
|
||||
if (_elm_photocam_download(obj, sd, file))
|
||||
{
|
||||
efl_event_callback_legacy_call
|
||||
(obj, ELM_PHOTOCAM_EVENT_DOWNLOAD_START, NULL);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
_internal_file_set(obj, sd, file, NULL, &ret);
|
||||
|
|
|
@ -552,18 +552,6 @@ void *_elm_icon_signal_callback_del(Evas_Object *obj,
|
|||
void _efl_ui_image_sizing_eval(Evas_Object *obj);
|
||||
/* end of DEPRECATED */
|
||||
|
||||
|
||||
/* Elm helper to download content */
|
||||
typedef struct _Elm_Url Elm_Url;
|
||||
|
||||
typedef void (*Elm_Url_Done)(void *data, Elm_Url *url, Eina_Binbuf *download);
|
||||
typedef void (*Elm_Url_Cancel)(void *data, Elm_Url *url, int error);
|
||||
typedef void (*Elm_Url_Progress)(void *data, Elm_Url *url, double now, double total);
|
||||
|
||||
Elm_Url *_elm_url_download(const char *url, Elm_Url_Done done_cb, Elm_Url_Cancel cancel_cb, Elm_Url_Progress progress_cb, const void *data);
|
||||
void _elm_url_cancel(Elm_Url *r);
|
||||
const char *_elm_url_get(Elm_Url *r);
|
||||
|
||||
Eina_Bool _elm_config_accel_preference_parse(const char *pref, Eina_Stringshare **accel, int *gl_depth, int *gl_stencil, int *gl_msaa);
|
||||
|
||||
extern char *_elm_appname;
|
||||
|
|
|
@ -1,152 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "elementary_config.h"
|
||||
#endif
|
||||
|
||||
#include <Elementary.h>
|
||||
#include "elm_priv.h"
|
||||
|
||||
struct _Elm_Url
|
||||
{
|
||||
const char *url;
|
||||
|
||||
struct {
|
||||
Elm_Url_Done done;
|
||||
Elm_Url_Cancel cancel;
|
||||
Elm_Url_Progress progress;
|
||||
} cb;
|
||||
|
||||
const void *data;
|
||||
|
||||
Ecore_Con_Url *target;
|
||||
Eina_Binbuf *download;
|
||||
|
||||
struct {
|
||||
Ecore_Event_Handler *progress;
|
||||
Ecore_Event_Handler *done;
|
||||
Ecore_Event_Handler *data;
|
||||
} handler;
|
||||
};
|
||||
|
||||
static void
|
||||
_elm_url_free(Elm_Url *r)
|
||||
{
|
||||
ecore_con_url_free(r->target);
|
||||
eina_binbuf_free(r->download);
|
||||
ecore_event_handler_del(r->handler.progress);
|
||||
ecore_event_handler_del(r->handler.done);
|
||||
ecore_event_handler_del(r->handler.data);
|
||||
eina_stringshare_del(r->url);
|
||||
free(r);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_elm_url_progress(void *data, int type EINA_UNUSED, void *event)
|
||||
{
|
||||
Ecore_Con_Event_Url_Progress *url_progress = event;
|
||||
Elm_Url *r = data;
|
||||
|
||||
if (url_progress->url_con != r->target) return EINA_TRUE;
|
||||
|
||||
r->cb.progress((void*) r->data, r, url_progress->down.now, url_progress->down.total);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_elm_url_done(void *data, int type EINA_UNUSED, void *event)
|
||||
{
|
||||
Ecore_Con_Event_Url_Complete *url_complete = event;
|
||||
Elm_Url *r = data;
|
||||
|
||||
if (url_complete->url_con != r->target) return EINA_TRUE;
|
||||
|
||||
if (url_complete->status == 200)
|
||||
{
|
||||
r->cb.done((void*) r->data, r, r->download);
|
||||
}
|
||||
else
|
||||
{
|
||||
r->cb.cancel((void*) r->data, r, url_complete->status);
|
||||
}
|
||||
|
||||
_elm_url_free(r);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_elm_url_data(void *data, int type EINA_UNUSED, void *event)
|
||||
{
|
||||
Ecore_Con_Event_Url_Data *url_data = event;
|
||||
Elm_Url *r = data;
|
||||
|
||||
if (url_data->url_con != r->target) return EINA_TRUE;
|
||||
|
||||
eina_binbuf_append_length(r->download, url_data->data, url_data->size);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
Elm_Url *
|
||||
_elm_url_download(const char *url, Elm_Url_Done done_cb, Elm_Url_Cancel cancel_cb, Elm_Url_Progress progress_cb, const void *data)
|
||||
{
|
||||
Ecore_Con_Url *target;
|
||||
Elm_Url *r;
|
||||
|
||||
ecore_con_url_init();
|
||||
|
||||
target = ecore_con_url_new(url);
|
||||
if (!target) goto on_error;
|
||||
|
||||
#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
|
||||
if (getuid() == geteuid())
|
||||
#endif
|
||||
{
|
||||
if (getenv("http_proxy")) ecore_con_url_proxy_set(target, getenv("http_proxy"));
|
||||
if (getenv("https_proxy")) ecore_con_url_proxy_set(target, getenv("https_proxy"));
|
||||
if (getenv("ftp_proxy")) ecore_con_url_proxy_set(target, getenv("ftp_proxy"));
|
||||
}
|
||||
|
||||
r = malloc(sizeof (Elm_Url));
|
||||
if (!r) goto on_error;
|
||||
|
||||
r->url = eina_stringshare_add(url);
|
||||
r->cb.done = done_cb;
|
||||
r->cb.cancel = cancel_cb;
|
||||
r->cb.progress = progress_cb;
|
||||
r->data = data;
|
||||
|
||||
r->download = eina_binbuf_new();
|
||||
r->target = target;
|
||||
r->handler.progress = ecore_event_handler_add(ECORE_CON_EVENT_URL_PROGRESS, _elm_url_progress, r);
|
||||
r->handler.done = ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, _elm_url_done, r);
|
||||
r->handler.data = ecore_event_handler_add(ECORE_CON_EVENT_URL_DATA, _elm_url_data, r);
|
||||
|
||||
if (!ecore_con_url_get(r->target))
|
||||
{
|
||||
_elm_url_free(r);
|
||||
cancel_cb((void*) data, NULL, -1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return r;
|
||||
|
||||
on_error:
|
||||
ecore_con_url_shutdown();
|
||||
|
||||
cancel_cb((void*) data, NULL, -1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_elm_url_cancel(Elm_Url *r)
|
||||
{
|
||||
r->cb.cancel((void*) r->data, r, 0);
|
||||
_elm_url_free(r);
|
||||
}
|
||||
|
||||
const char *
|
||||
_elm_url_get(Elm_Url *r)
|
||||
{
|
||||
return r->url;
|
||||
}
|
|
@ -87,8 +87,11 @@ struct _Elm_Photocam_Data
|
|||
const char *file;
|
||||
Eina_File *f;
|
||||
|
||||
Elm_Url *remote;
|
||||
void *remote_data;
|
||||
struct
|
||||
{
|
||||
Eo *copier;
|
||||
Eina_Binbuf *binbuf;
|
||||
} remote;
|
||||
|
||||
Ecore_Job *calc_job;
|
||||
Ecore_Timer *scr_timer;
|
||||
|
|
Loading…
Reference in New Issue