diff options
author | Boris Faure <billiob@gmail.com> | 2015-02-15 20:32:16 +0100 |
---|---|---|
committer | Boris Faure <billiob@gmail.com> | 2015-02-21 11:40:10 +0100 |
commit | 76e9ae6481d968d489aa694e810ca4798a9dcf38 (patch) | |
tree | de3ed303c6aaabe041af3802ce62396ac24f43e1 /src | |
parent | 6762578ace9a7a036636aeb28710c925ddf07dc1 (diff) |
do an HTTP HEAD to get media type when poping media
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/media.c | 19 | ||||
-rw-r--r-- | src/bin/media.h | 1 | ||||
-rw-r--r-- | src/bin/termio.c | 16 | ||||
-rw-r--r-- | src/bin/win.c | 176 | ||||
-rw-r--r-- | src/bin/win.h | 2 |
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 | |||
1430 | void | ||
1431 | media_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); | |||
38 | const char *media_get(const Evas_Object *obj); | 38 | const char *media_get(const Evas_Object *obj); |
39 | Media_Type media_src_type_get(const char *src); | 39 | Media_Type media_src_type_get(const char *src); |
40 | Evas_Object *media_control_get(Evas_Object *obj); | 40 | Evas_Object *media_control_get(Evas_Object *obj); |
41 | void 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 | ||
1543 | static void | 1544 | static 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 | ||
1599 | typedef 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 | |||
1607 | static 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 | |||
1620 | static 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; | ||
1675 | error: | ||
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 | |||
1682 | static 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 | |||
1717 | error: | ||
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 | |||
1595 | static void | 1730 | static 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 | ||
1682 | static void | 1817 | static 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 | ||
2739 | void | ||
2740 | term_ref(Term *term) | ||
2741 | { | ||
2742 | term->refcnt++; | ||
2743 | } | ||
2744 | |||
2745 | void 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 | ||
2605 | Term * | 2756 | Term * |
2606 | term_new(Win *wn, Config *config, const char *cmd, | 2757 | term_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); | |||
40 | void win_add_split(Win *wn, Term *term); | 40 | void win_add_split(Win *wn, Term *term); |
41 | void win_sizing_handle(Win *wn); | 41 | void win_sizing_handle(Win *wn); |
42 | 42 | ||
43 | void term_ref(Term *term); | ||
44 | void term_unref(Term *term); | ||
43 | Term *term_next_get(Term *term); | 45 | Term *term_next_get(Term *term); |
44 | Term *term_prev_get(Term *term); | 46 | Term *term_prev_get(Term *term); |
45 | void term_next(Term *term); | 47 | void term_next(Term *term); |