summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBoris Faure <billiob@gmail.com>2015-02-15 20:32:16 +0100
committerBoris Faure <billiob@gmail.com>2015-02-21 11:40:10 +0100
commit76e9ae6481d968d489aa694e810ca4798a9dcf38 (patch)
treede3ed303c6aaabe041af3802ce62396ac24f43e1 /src
parent6762578ace9a7a036636aeb28710c925ddf07dc1 (diff)
do an HTTP HEAD to get media type when poping media
Diffstat (limited to 'src')
-rw-r--r--src/bin/media.c19
-rw-r--r--src/bin/media.h1
-rw-r--r--src/bin/termio.c16
-rw-r--r--src/bin/win.c176
-rw-r--r--src/bin/win.h2
5 files changed, 188 insertions, 26 deletions
diff --git a/src/bin/media.c b/src/bin/media.c
index c0bfc26..c0ed0d0 100644
--- a/src/bin/media.c
+++ b/src/bin/media.c
@@ -1426,3 +1426,22 @@ media_control_get(Evas_Object *obj)
1426 if (!sd) return NULL; 1426 if (!sd) return NULL;
1427 return sd->o_ctrl; 1427 return sd->o_ctrl;
1428} 1428}
1429
1430void
1431media_unknown_handle(const char *handler, const char *src)
1432{
1433 const char *cmd;
1434 char buf[PATH_MAX];
1435 char *escaped;
1436
1437 cmd = "xdg-open";
1438 escaped = ecore_file_escape_name(src);
1439 if (!escaped)
1440 return;
1441 if (handler && *handler)
1442 cmd = handler;
1443 snprintf(buf, sizeof(buf), "%s %s", cmd, escaped);
1444 free(escaped);
1445
1446 ecore_exe_run(buf, NULL);
1447}
diff --git a/src/bin/media.h b/src/bin/media.h
index 8b5d082..48b5c16 100644
--- a/src/bin/media.h
+++ b/src/bin/media.h
@@ -38,5 +38,6 @@ void media_stop(Evas_Object *obj);
38const char *media_get(const Evas_Object *obj); 38const char *media_get(const Evas_Object *obj);
39Media_Type media_src_type_get(const char *src); 39Media_Type media_src_type_get(const char *src);
40Evas_Object *media_control_get(Evas_Object *obj); 40Evas_Object *media_control_get(Evas_Object *obj);
41void media_unknown_handle(const char *handler, const char *src);
41 42
42#endif 43#endif
diff --git a/src/bin/termio.c b/src/bin/termio.c
index 0414ffa..789c314 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -833,20 +833,8 @@ _activate_link(Evas_Object *obj, Eina_Bool may_inline)
833 type = media_src_type_get(sd->link.string); 833 type = media_src_type_get(sd->link.string);
834 if (may_inline && _should_inline(obj)) 834 if (may_inline && _should_inline(obj))
835 { 835 {
836 if ((type == MEDIA_TYPE_IMG) || 836 evas_object_smart_callback_call(obj, "popup", NULL);
837 (type == MEDIA_TYPE_SCALE) || 837 handled = EINA_TRUE;
838 (type == MEDIA_TYPE_EDJE))
839 {
840 // XXX: begin fetch of url, once done, show
841 evas_object_smart_callback_call(obj, "popup", NULL);
842 handled = EINA_TRUE;
843 }
844 else if (type == MEDIA_TYPE_MOV)
845 {
846 // XXX: if no http:// add
847 evas_object_smart_callback_call(obj, "popup", NULL);
848 handled = EINA_TRUE;
849 }
850 } 838 }
851 if (!handled) 839 if (!handled)
852 { 840 {
diff --git a/src/bin/win.c b/src/bin/win.c
index 6de4db8..f6a4124 100644
--- a/src/bin/win.c
+++ b/src/bin/win.c
@@ -56,6 +56,7 @@ struct _Term
56 struct { 56 struct {
57 int x, y; 57 int x, y;
58 } down; 58 } down;
59 int refcnt;
59 unsigned char focused : 1; 60 unsigned char focused : 1;
60 unsigned char hold : 1; 61 unsigned char hold : 1;
61 unsigned char unswallowed : 1; 62 unsigned char unswallowed : 1;
@@ -363,7 +364,7 @@ win_free(Win *wn)
363 wins = eina_list_remove(wins, wn); 364 wins = eina_list_remove(wins, wn);
364 EINA_LIST_FREE(wn->terms, term) 365 EINA_LIST_FREE(wn->terms, term)
365 { 366 {
366 term_free(term); 367 term_unref(term);
367 } 368 }
368 if (wn->cmdbox_del_timer) 369 if (wn->cmdbox_del_timer)
369 { 370 {
@@ -542,7 +543,7 @@ main_close(Evas_Object *win, Evas_Object *term)
542 } 543 }
543 l = eina_list_data_find_list(sp->terms, tm); 544 l = eina_list_data_find_list(sp->terms, tm);
544 _term_resize_track_stop(sp); 545 _term_resize_track_stop(sp);
545 term_free(tm); 546 term_unref(tm);
546 if (l) 547 if (l)
547 { 548 {
548 if (tm == sp->term) 549 if (tm == sp->term)
@@ -601,7 +602,7 @@ main_close(Evas_Object *win, Evas_Object *term)
601 _term_resize_track_stop(sp); 602 _term_resize_track_stop(sp);
602 edje_object_part_unswallow(sp->wn->base, sp->term->bg); 603 edje_object_part_unswallow(sp->wn->base, sp->term->bg);
603 l = eina_list_data_find_list(sp->terms, tm); 604 l = eina_list_data_find_list(sp->terms, tm);
604 term_free(tm); 605 term_unref(tm);
605 if (l) 606 if (l)
606 { 607 {
607 if (tm == sp->term) 608 if (tm == sp->term)
@@ -1541,18 +1542,17 @@ _cb_media_loop(void *data, Evas_Object *obj EINA_UNUSED, void *info EINA_UNUSED)
1541} 1542}
1542 1543
1543static void 1544static void
1544_popmedia_show(Term *term, const char *src) 1545_popmedia_show(Term *term, const char *src, Media_Type type)
1545{ 1546{
1546 Evas_Object *o; 1547 Evas_Object *o;
1547 Config *config = termio_config_get(term->term); 1548 Config *config = termio_config_get(term->term);
1548 Media_Type type;
1549 1549
1550 if (!config) return; 1550 EINA_SAFETY_ON_NULL_RETURN(config);
1551 ty_dbus_link_hide(); 1551 ty_dbus_link_hide();
1552 if (term->popmedia) 1552 if (term->popmedia)
1553 { 1553 {
1554 const char *s; 1554 const char *s;
1555 1555
1556 EINA_LIST_FREE(term->popmedia_queue, s) 1556 EINA_LIST_FREE(term->popmedia_queue, s)
1557 { 1557 {
1558 eina_stringshare_del(s); 1558 eina_stringshare_del(s);
@@ -1563,7 +1563,6 @@ _popmedia_show(Term *term, const char *src)
1563 return; 1563 return;
1564 } 1564 }
1565 termio_mouseover_suspend_pushpop(term->term, 1); 1565 termio_mouseover_suspend_pushpop(term->term, 1);
1566 type = media_src_type_get(src);
1567 term->popmedia = o = media_add(win_evas_object_get(term->wn), 1566 term->popmedia = o = media_add(win_evas_object_get(term->wn),
1568 src, config, MEDIA_POP, type); 1567 src, config, MEDIA_POP, type);
1569 term->popmedia_deleted = EINA_FALSE; 1568 term->popmedia_deleted = EINA_FALSE;
@@ -1592,6 +1591,142 @@ _popmedia_show(Term *term, const char *src)
1592 } 1591 }
1593} 1592}
1594 1593
1594/* TODO: XXX: should be s/13/14 */
1595#define HAVE_ECORE_CON_URL_HTTP_HEAD \
1596 ((ECORE_VERSION_MAJOR > 1) || (ECORE_VERSION_MINOR >= 13))
1597
1598#if HAVE_ECORE_CON_URL_HTTP_HEAD
1599typedef struct _Ty_Http_Head {
1600 const char *handler;
1601 const char *src;
1602 Ecore_Con_Url *url;
1603 Ecore_Event_Handler *url_complete;
1604 Term *term;
1605} Ty_Http_Head;
1606
1607static void
1608_ty_http_head_delete(Ty_Http_Head *ty_head)
1609{
1610 eina_stringshare_del(ty_head->handler);
1611 eina_stringshare_del(ty_head->src);
1612 ecore_con_url_free(ty_head->url);
1613 ecore_event_handler_del(ty_head->url_complete);
1614 edje_object_signal_emit(ty_head->term->bg, "done", "terminology");
1615 term_unref(ty_head->term);
1616
1617 free(ty_head);
1618}
1619
1620static Eina_Bool
1621_media_http_head_complete(void *data, int kind EINA_UNUSED, void *event_info)
1622{
1623 Ecore_Con_Event_Url_Complete *ev = event_info;
1624 Ty_Http_Head *ty_head = data;
1625 const Eina_List *headers, *l;
1626 Media_Type type = MEDIA_TYPE_UNKNOWN;
1627 char *str;
1628
1629 if (ev->status != 200)
1630 goto error;
1631 headers = ecore_con_url_response_headers_get(ev->url_con);
1632 EINA_LIST_FOREACH(headers, l, str)
1633 {
1634#define _CONTENT_TYPE_HDR "Content-Type: "
1635#define _LOCATION_HDR "Location: "
1636 if (!strncmp(str, _LOCATION_HDR, strlen(_LOCATION_HDR)))
1637 {
1638 unsigned int len;
1639
1640 str += strlen(_LOCATION_HDR);
1641 eina_stringshare_del(ty_head->src);
1642
1643 /* skip the crlf */
1644 len = strlen(str);
1645 if (len <= 2)
1646 goto error;
1647
1648 ty_head->src = eina_stringshare_add_length(str, len - 2);
1649 if (!ty_head->src)
1650 goto error;
1651 }
1652 else if (!strncmp(str, _CONTENT_TYPE_HDR, strlen(_CONTENT_TYPE_HDR)))
1653 {
1654 str += strlen(_CONTENT_TYPE_HDR);
1655 if (!strncmp(str, "image/", strlen("image/")))
1656 {
1657 type = MEDIA_TYPE_IMG;
1658 }
1659 else if (!strncmp(str, "video/", strlen("video/")))
1660 {
1661 type = MEDIA_TYPE_MOV;
1662 }
1663 if (type != MEDIA_TYPE_UNKNOWN)
1664 {
1665 _popmedia_show(ty_head->term, ty_head->src, type);
1666 break;
1667 }
1668 }
1669#undef _CONTENT_TYPE_HDR
1670#undef _LOCATION_HDR
1671 }
1672
1673 _ty_http_head_delete(ty_head);
1674 return EINA_TRUE;
1675error:
1676 media_unknown_handle(ty_head->handler, ty_head->src);
1677 _ty_http_head_delete(ty_head);
1678 return EINA_TRUE;
1679}
1680#endif
1681
1682static void
1683_popmedia(Term *term, const char *src)
1684{
1685 Media_Type type;
1686 Config *config = termio_config_get(term->term);
1687
1688#if HAVE_ECORE_CON_URL_HTTP_HEAD
1689 Ty_Http_Head *ty_head = calloc(1, sizeof(Ty_Http_Head));
1690 if (!ty_head)
1691 return;
1692
1693 if (config->helper.local.general && config->helper.local.general[0])
1694 {
1695 ty_head->handler = eina_stringshare_add(config->helper.local.general);
1696 if (!ty_head->handler)
1697 goto error;
1698 }
1699 ty_head->src = eina_stringshare_add(src);
1700 if (!ty_head->src)
1701 goto error;
1702 ty_head->url = ecore_con_url_new(src);
1703 if (!ty_head->url)
1704 goto error;
1705 if (!ecore_con_url_head(ty_head->url))
1706 goto error;
1707 ty_head->url_complete = ecore_event_handler_add
1708 (ECORE_CON_EVENT_URL_COMPLETE, _media_http_head_complete, ty_head);
1709 if (!ty_head->url_complete)
1710 goto error;
1711 ty_head->term = term;
1712 edje_object_signal_emit(term->bg, "busy", "terminology");
1713 term_ref(term);
1714
1715 return;
1716
1717error:
1718 _ty_http_head_delete(ty_head);
1719#endif
1720
1721 type = media_src_type_get(src);
1722 if (type == MEDIA_TYPE_UNKNOWN) {
1723 media_unknown_handle(config->helper.local.general, src);
1724 } else {
1725 _popmedia_show(term, src, type);
1726 }
1727}
1728
1729
1595static void 1730static void
1596_term_miniview_check(Term *term) 1731_term_miniview_check(Term *term)
1597{ 1732{
@@ -1657,7 +1792,7 @@ _popmedia_queue_process(Term *term)
1657 term->popmedia_queue = eina_list_remove_list(term->popmedia_queue, 1792 term->popmedia_queue = eina_list_remove_list(term->popmedia_queue,
1658 term->popmedia_queue); 1793 term->popmedia_queue);
1659 if (!src) return; 1794 if (!src) return;
1660 _popmedia_show(term, src); 1795 _popmedia(term, src);
1661 eina_stringshare_del(src); 1796 eina_stringshare_del(src);
1662} 1797}
1663 1798
@@ -1676,7 +1811,7 @@ _cb_popup(void *data, Evas_Object *obj EINA_UNUSED, void *event)
1676 const char *src = event; 1811 const char *src = event;
1677 if (!src) src = termio_link_get(term->term); 1812 if (!src) src = termio_link_get(term->term);
1678 if (!src) return; 1813 if (!src) return;
1679 _popmedia_show(term, src); 1814 _popmedia(term, src);
1680} 1815}
1681 1816
1682static void 1817static void
@@ -1733,7 +1868,7 @@ _cb_command(void *data, Evas_Object *obj EINA_UNUSED, void *event)
1733 { 1868 {
1734 if (cmd[1] == 'n') // now 1869 if (cmd[1] == 'n') // now
1735 { 1870 {
1736 _popmedia_show(term, cmd + 2); 1871 _popmedia(term, cmd + 2);
1737 } 1872 }
1738 else if (cmd[1] == 'q') // queue it to display after current one 1873 else if (cmd[1] == 'q') // queue it to display after current one
1739 { 1874 {
@@ -2601,6 +2736,22 @@ _cb_exited(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2601 } 2736 }
2602} 2737}
2603 2738
2739void
2740term_ref(Term *term)
2741{
2742 term->refcnt++;
2743}
2744
2745void term_unref(Term *term)
2746{
2747 EINA_SAFETY_ON_NULL_RETURN(term);
2748
2749 term->refcnt--;
2750 if (term->refcnt <= 0)
2751 {
2752 term_free(term);
2753 }
2754}
2604 2755
2605Term * 2756Term *
2606term_new(Win *wn, Config *config, const char *cmd, 2757term_new(Win *wn, Config *config, const char *cmd,
@@ -2611,9 +2762,10 @@ term_new(Win *wn, Config *config, const char *cmd,
2611 Evas_Object *o; 2762 Evas_Object *o;
2612 Evas *canvas = evas_object_evas_get(wn->win); 2763 Evas *canvas = evas_object_evas_get(wn->win);
2613 Edje_Message_Int msg; 2764 Edje_Message_Int msg;
2614 2765
2615 term = calloc(1, sizeof(Term)); 2766 term = calloc(1, sizeof(Term));
2616 if (!term) return NULL; 2767 if (!term) return NULL;
2768 term_ref(term);
2617 2769
2618 if (!config) abort(); 2770 if (!config) abort();
2619 2771
diff --git a/src/bin/win.h b/src/bin/win.h
index fc2b0b1..e4e4507 100644
--- a/src/bin/win.h
+++ b/src/bin/win.h
@@ -40,6 +40,8 @@ void win_term_swallow(Win *wn, Term *term);
40void win_add_split(Win *wn, Term *term); 40void win_add_split(Win *wn, Term *term);
41void win_sizing_handle(Win *wn); 41void win_sizing_handle(Win *wn);
42 42
43void term_ref(Term *term);
44void term_unref(Term *term);
43Term *term_next_get(Term *term); 45Term *term_next_get(Term *term);
44Term *term_prev_get(Term *term); 46Term *term_prev_get(Term *term);
45void term_next(Term *term); 47void term_next(Term *term);