do an HTTP HEAD to get media type when poping media

This commit is contained in:
Boris Faure 2015-02-15 20:32:16 +01:00
parent 6762578ace
commit 76e9ae6481
6 changed files with 260 additions and 26 deletions

View File

@ -225,6 +225,8 @@ collections {
image: "tab_shad_l1.png" COMP;
image: "tab_shad_r0.png" COMP;
image: "tab_shad_r1.png" COMP;
image: "media_busy_knob.png" COMP;
image: "media_busy_spinner.png" COMP;
}
set { name: "bg_shadow";
image { image: "bg_shadow.png" COMP; size: 0 0 200 150; }
@ -1618,6 +1620,76 @@ collections {
target: "popmedia_glintclip";
target: "popmedia_shine";
}
/* media busy */
part { name: "media"; type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 255 255 255 0;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
color: 255 255 255 255;
}
}
part { name: "knob";
clip_to: "media";
mouse_events: 0;
description { state: "default" 0.0;
fixed: 1 1;
image.normal: "media_busy_knob.png";
min: 40 40;
max: 40 40;
align: 1.0 1.0;
}
}
part { name: "knob_spinner";
clip_to: "media";
mouse_events: 0;
description { state: "default" 0.0;
fixed: 1 1;
color: 51 153 255 255;
rel1.to: "knob";
rel2.to: "knob";
image.normal: "media_busy_spinner.png";
map {
on: 1;
smooth: 1;
rotation.center: "knob";
}
}
description { state: "spin" 0.0;
inherit: "default" 0.0;
visible: 1;
map.rotation.z: 360;
}
}
program {
signal: "busy"; source: "terminology";
action: STATE_SET "visible" 0.0;
transition: DECELERATE 0.5;
target: "media";
}
program { name: "spin1";
signal: "busy"; source: "terminology";
action: STATE_SET "spin" 0.0;
transition: LINEAR 0.5;
target: "knob_spinner";
after: "spin2";
}
program { name: "spin2";
action: STATE_SET "default" 0.0;
target: "knob_spinner";
after: "spin1";
}
program {
signal: "done"; source: "terminology";
action: STATE_SET "default" 0.0;
transition: DECELERATE 1.5;
target: "media";
}
}
}

View File

@ -1426,3 +1426,22 @@ media_control_get(Evas_Object *obj)
if (!sd) return NULL;
return sd->o_ctrl;
}
void
media_unknown_handle(const char *handler, const char *src)
{
const char *cmd;
char buf[PATH_MAX];
char *escaped;
cmd = "xdg-open";
escaped = ecore_file_escape_name(src);
if (!escaped)
return;
if (handler && *handler)
cmd = handler;
snprintf(buf, sizeof(buf), "%s %s", cmd, escaped);
free(escaped);
ecore_exe_run(buf, NULL);
}

View File

@ -38,5 +38,6 @@ void media_stop(Evas_Object *obj);
const char *media_get(const Evas_Object *obj);
Media_Type media_src_type_get(const char *src);
Evas_Object *media_control_get(Evas_Object *obj);
void media_unknown_handle(const char *handler, const char *src);
#endif

View File

@ -833,20 +833,8 @@ _activate_link(Evas_Object *obj, Eina_Bool may_inline)
type = media_src_type_get(sd->link.string);
if (may_inline && _should_inline(obj))
{
if ((type == MEDIA_TYPE_IMG) ||
(type == MEDIA_TYPE_SCALE) ||
(type == MEDIA_TYPE_EDJE))
{
// XXX: begin fetch of url, once done, show
evas_object_smart_callback_call(obj, "popup", NULL);
handled = EINA_TRUE;
}
else if (type == MEDIA_TYPE_MOV)
{
// XXX: if no http:// add
evas_object_smart_callback_call(obj, "popup", NULL);
handled = EINA_TRUE;
}
evas_object_smart_callback_call(obj, "popup", NULL);
handled = EINA_TRUE;
}
if (!handled)
{

View File

@ -56,6 +56,7 @@ struct _Term
struct {
int x, y;
} down;
int refcnt;
unsigned char focused : 1;
unsigned char hold : 1;
unsigned char unswallowed : 1;
@ -363,7 +364,7 @@ win_free(Win *wn)
wins = eina_list_remove(wins, wn);
EINA_LIST_FREE(wn->terms, term)
{
term_free(term);
term_unref(term);
}
if (wn->cmdbox_del_timer)
{
@ -542,7 +543,7 @@ main_close(Evas_Object *win, Evas_Object *term)
}
l = eina_list_data_find_list(sp->terms, tm);
_term_resize_track_stop(sp);
term_free(tm);
term_unref(tm);
if (l)
{
if (tm == sp->term)
@ -601,7 +602,7 @@ main_close(Evas_Object *win, Evas_Object *term)
_term_resize_track_stop(sp);
edje_object_part_unswallow(sp->wn->base, sp->term->bg);
l = eina_list_data_find_list(sp->terms, tm);
term_free(tm);
term_unref(tm);
if (l)
{
if (tm == sp->term)
@ -1541,18 +1542,17 @@ _cb_media_loop(void *data, Evas_Object *obj EINA_UNUSED, void *info EINA_UNUSED)
}
static void
_popmedia_show(Term *term, const char *src)
_popmedia_show(Term *term, const char *src, Media_Type type)
{
Evas_Object *o;
Config *config = termio_config_get(term->term);
Media_Type type;
if (!config) return;
EINA_SAFETY_ON_NULL_RETURN(config);
ty_dbus_link_hide();
if (term->popmedia)
{
const char *s;
EINA_LIST_FREE(term->popmedia_queue, s)
{
eina_stringshare_del(s);
@ -1563,7 +1563,6 @@ _popmedia_show(Term *term, const char *src)
return;
}
termio_mouseover_suspend_pushpop(term->term, 1);
type = media_src_type_get(src);
term->popmedia = o = media_add(win_evas_object_get(term->wn),
src, config, MEDIA_POP, type);
term->popmedia_deleted = EINA_FALSE;
@ -1592,6 +1591,142 @@ _popmedia_show(Term *term, const char *src)
}
}
/* TODO: XXX: should be s/13/14 */
#define HAVE_ECORE_CON_URL_HTTP_HEAD \
((ECORE_VERSION_MAJOR > 1) || (ECORE_VERSION_MINOR >= 13))
#if HAVE_ECORE_CON_URL_HTTP_HEAD
typedef struct _Ty_Http_Head {
const char *handler;
const char *src;
Ecore_Con_Url *url;
Ecore_Event_Handler *url_complete;
Term *term;
} Ty_Http_Head;
static void
_ty_http_head_delete(Ty_Http_Head *ty_head)
{
eina_stringshare_del(ty_head->handler);
eina_stringshare_del(ty_head->src);
ecore_con_url_free(ty_head->url);
ecore_event_handler_del(ty_head->url_complete);
edje_object_signal_emit(ty_head->term->bg, "done", "terminology");
term_unref(ty_head->term);
free(ty_head);
}
static Eina_Bool
_media_http_head_complete(void *data, int kind EINA_UNUSED, void *event_info)
{
Ecore_Con_Event_Url_Complete *ev = event_info;
Ty_Http_Head *ty_head = data;
const Eina_List *headers, *l;
Media_Type type = MEDIA_TYPE_UNKNOWN;
char *str;
if (ev->status != 200)
goto error;
headers = ecore_con_url_response_headers_get(ev->url_con);
EINA_LIST_FOREACH(headers, l, str)
{
#define _CONTENT_TYPE_HDR "Content-Type: "
#define _LOCATION_HDR "Location: "
if (!strncmp(str, _LOCATION_HDR, strlen(_LOCATION_HDR)))
{
unsigned int len;
str += strlen(_LOCATION_HDR);
eina_stringshare_del(ty_head->src);
/* skip the crlf */
len = strlen(str);
if (len <= 2)
goto error;
ty_head->src = eina_stringshare_add_length(str, len - 2);
if (!ty_head->src)
goto error;
}
else if (!strncmp(str, _CONTENT_TYPE_HDR, strlen(_CONTENT_TYPE_HDR)))
{
str += strlen(_CONTENT_TYPE_HDR);
if (!strncmp(str, "image/", strlen("image/")))
{
type = MEDIA_TYPE_IMG;
}
else if (!strncmp(str, "video/", strlen("video/")))
{
type = MEDIA_TYPE_MOV;
}
if (type != MEDIA_TYPE_UNKNOWN)
{
_popmedia_show(ty_head->term, ty_head->src, type);
break;
}
}
#undef _CONTENT_TYPE_HDR
#undef _LOCATION_HDR
}
_ty_http_head_delete(ty_head);
return EINA_TRUE;
error:
media_unknown_handle(ty_head->handler, ty_head->src);
_ty_http_head_delete(ty_head);
return EINA_TRUE;
}
#endif
static void
_popmedia(Term *term, const char *src)
{
Media_Type type;
Config *config = termio_config_get(term->term);
#if HAVE_ECORE_CON_URL_HTTP_HEAD
Ty_Http_Head *ty_head = calloc(1, sizeof(Ty_Http_Head));
if (!ty_head)
return;
if (config->helper.local.general && config->helper.local.general[0])
{
ty_head->handler = eina_stringshare_add(config->helper.local.general);
if (!ty_head->handler)
goto error;
}
ty_head->src = eina_stringshare_add(src);
if (!ty_head->src)
goto error;
ty_head->url = ecore_con_url_new(src);
if (!ty_head->url)
goto error;
if (!ecore_con_url_head(ty_head->url))
goto error;
ty_head->url_complete = ecore_event_handler_add
(ECORE_CON_EVENT_URL_COMPLETE, _media_http_head_complete, ty_head);
if (!ty_head->url_complete)
goto error;
ty_head->term = term;
edje_object_signal_emit(term->bg, "busy", "terminology");
term_ref(term);
return;
error:
_ty_http_head_delete(ty_head);
#endif
type = media_src_type_get(src);
if (type == MEDIA_TYPE_UNKNOWN) {
media_unknown_handle(config->helper.local.general, src);
} else {
_popmedia_show(term, src, type);
}
}
static void
_term_miniview_check(Term *term)
{
@ -1657,7 +1792,7 @@ _popmedia_queue_process(Term *term)
term->popmedia_queue = eina_list_remove_list(term->popmedia_queue,
term->popmedia_queue);
if (!src) return;
_popmedia_show(term, src);
_popmedia(term, src);
eina_stringshare_del(src);
}
@ -1676,7 +1811,7 @@ _cb_popup(void *data, Evas_Object *obj EINA_UNUSED, void *event)
const char *src = event;
if (!src) src = termio_link_get(term->term);
if (!src) return;
_popmedia_show(term, src);
_popmedia(term, src);
}
static void
@ -1733,7 +1868,7 @@ _cb_command(void *data, Evas_Object *obj EINA_UNUSED, void *event)
{
if (cmd[1] == 'n') // now
{
_popmedia_show(term, cmd + 2);
_popmedia(term, cmd + 2);
}
else if (cmd[1] == 'q') // queue it to display after current one
{
@ -2601,6 +2736,22 @@ _cb_exited(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
}
}
void
term_ref(Term *term)
{
term->refcnt++;
}
void term_unref(Term *term)
{
EINA_SAFETY_ON_NULL_RETURN(term);
term->refcnt--;
if (term->refcnt <= 0)
{
term_free(term);
}
}
Term *
term_new(Win *wn, Config *config, const char *cmd,
@ -2611,9 +2762,10 @@ term_new(Win *wn, Config *config, const char *cmd,
Evas_Object *o;
Evas *canvas = evas_object_evas_get(wn->win);
Edje_Message_Int msg;
term = calloc(1, sizeof(Term));
if (!term) return NULL;
term_ref(term);
if (!config) abort();

View File

@ -40,6 +40,8 @@ void win_term_swallow(Win *wn, Term *term);
void win_add_split(Win *wn, Term *term);
void win_sizing_handle(Win *wn);
void term_ref(Term *term);
void term_unref(Term *term);
Term *term_next_get(Term *term);
Term *term_prev_get(Term *term);
void term_next(Term *term);