2013-06-14 07:36:11 -07:00
|
|
|
#include "e_mod_main.h"
|
2013-06-17 08:06:43 -07:00
|
|
|
#ifdef HAVE_EMOTION
|
|
|
|
# include <Emotion.h>
|
|
|
|
#endif
|
2013-06-14 07:36:11 -07:00
|
|
|
|
|
|
|
#define IMAGE_FETCH_TRIES 5
|
|
|
|
|
2013-06-18 02:13:08 -07:00
|
|
|
/**
|
|
|
|
* https://phab.enlightenment.org/w/teamwork_api/
|
|
|
|
*/
|
|
|
|
|
2013-06-14 07:36:11 -07:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
const char *sha1;
|
|
|
|
unsigned long long timestamp;
|
2013-06-17 08:06:43 -07:00
|
|
|
Eina_Bool video;
|
2013-06-14 07:36:11 -07:00
|
|
|
} Media_Cache;
|
|
|
|
|
|
|
|
typedef struct Media_Cache_List
|
|
|
|
{
|
|
|
|
Eina_List *cache;
|
2013-06-17 08:06:43 -07:00
|
|
|
Eina_Bool video;
|
2013-06-14 07:36:11 -07:00
|
|
|
} Media_Cache_List;
|
|
|
|
|
|
|
|
typedef struct Media
|
|
|
|
{
|
|
|
|
EINA_INLIST;
|
|
|
|
Ecore_Con_Url *client;
|
|
|
|
Eina_Binbuf *buf;
|
|
|
|
const char *addr;
|
|
|
|
unsigned long long timestamp;
|
|
|
|
unsigned int tries;
|
2013-06-17 08:06:43 -07:00
|
|
|
Ecore_Thread *video_thread;
|
2013-06-18 01:28:07 -07:00
|
|
|
Eina_Stringshare *tmpfile;
|
2013-06-17 08:06:43 -07:00
|
|
|
Eina_Bool video;
|
2013-06-14 07:36:11 -07:00
|
|
|
Eina_Bool dummy : 1;
|
|
|
|
Eina_Bool valid : 1;
|
|
|
|
Eina_Bool show : 1;
|
|
|
|
} Media;
|
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
MEDIA_CACHE_TYPE_IMAGE,
|
|
|
|
MEDIA_CACHE_TYPE_VIDEO,
|
|
|
|
} Media_Cache_Type;
|
|
|
|
|
|
|
|
static Eet_File *media[2] = {NULL};
|
2013-06-14 07:36:11 -07:00
|
|
|
static Eet_File *dummies = NULL;
|
|
|
|
static Eet_Data_Descriptor *cleaner_edd = NULL;
|
|
|
|
static Eet_Data_Descriptor *cache_edd = NULL;
|
2013-06-17 08:06:43 -07:00
|
|
|
static Ecore_Idler *media_cleaner[2] = {NULL};
|
2013-06-14 07:36:11 -07:00
|
|
|
static Eina_List *handlers = NULL;
|
2013-06-17 08:06:43 -07:00
|
|
|
static Media_Cache_List *tw_cache_list[2] = {NULL};
|
2013-06-14 07:36:11 -07:00
|
|
|
|
|
|
|
static Evas_Point last_coords = {0};
|
|
|
|
|
2013-06-19 00:14:23 -07:00
|
|
|
static Ecore_Window tw_win = 0;
|
|
|
|
|
2013-06-14 07:36:11 -07:00
|
|
|
static Ecore_Timer *tw_hide_timer = NULL;
|
|
|
|
|
|
|
|
static Eldbus_Service_Interface *tw_dbus_iface = NULL;
|
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
#ifdef HAVE_EMOTION
|
|
|
|
static Eina_Stringshare *tw_tmpfile = NULL;
|
|
|
|
static int tw_tmpfd = -1;
|
|
|
|
static Ecore_Thread *tw_tmpthread = NULL;
|
|
|
|
static Media *tw_tmpthread_media = NULL;
|
|
|
|
#endif
|
|
|
|
|
2013-06-14 07:36:11 -07:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
TEAMWORK_LINK_TYPE_NONE,
|
|
|
|
TEAMWORK_LINK_TYPE_LOCAL_FILE,
|
|
|
|
TEAMWORK_LINK_TYPE_LOCAL_DIRECTORY,
|
|
|
|
TEAMWORK_LINK_TYPE_REMOTE
|
|
|
|
} Teamwork_Link_Type;
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
TEAMWORK_SIGNAL_LINK_DOWNLOADING,
|
|
|
|
TEAMWORK_SIGNAL_LINK_PROGRESS,
|
|
|
|
TEAMWORK_SIGNAL_LINK_COMPLETE,
|
|
|
|
TEAMWORK_SIGNAL_LINK_INVALID,
|
|
|
|
} Teamwork_Signal;
|
|
|
|
|
|
|
|
static const Eldbus_Signal tw_signals[] =
|
|
|
|
{
|
|
|
|
[TEAMWORK_SIGNAL_LINK_DOWNLOADING] = {"LinkDownloading", ELDBUS_ARGS({"s", "URI"}, {"u", "Timestamp"}), 0},
|
|
|
|
[TEAMWORK_SIGNAL_LINK_PROGRESS] = {"LinkProgress", ELDBUS_ARGS({"s", "URI"}, {"u", "Timestamp"}, {"d", "Percent Completion"}), 0},
|
|
|
|
[TEAMWORK_SIGNAL_LINK_COMPLETE] = {"LinkComplete", ELDBUS_ARGS({"s", "URI"}, {"u", "Timestamp"}), 0},
|
|
|
|
[TEAMWORK_SIGNAL_LINK_INVALID] = {"LinkInvalid", ELDBUS_ARGS({"s", "URI"}, {"u", "Timestamp"}), 0},
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
static void tw_show(Media *i);
|
|
|
|
static void tw_show_local_file(const char *uri);
|
|
|
|
static void tw_show_local_dir(const char *uri);
|
2013-06-17 08:06:43 -07:00
|
|
|
static int tw_media_add(const char *url, Eina_Binbuf *buf, unsigned long long timestamp, Eina_Bool video);
|
2013-06-14 07:36:11 -07:00
|
|
|
static void download_media_cleanup(void);
|
|
|
|
static void tw_dummy_add(const char *url);
|
|
|
|
static Eina_Bool tw_dummy_check(const char *url);
|
2013-06-17 08:06:43 -07:00
|
|
|
static void tw_media_ping(const char *url, unsigned long long timestamp, Eina_Bool video);
|
|
|
|
static Eina_Binbuf *tw_media_get(const char *url, unsigned long long timestamp, Eina_Bool *video);
|
2013-06-14 07:36:11 -07:00
|
|
|
static Eina_Bool tw_idler_start(void);
|
|
|
|
|
|
|
|
static void
|
|
|
|
dbus_signal_link_complete(Media *i)
|
|
|
|
{
|
|
|
|
unsigned int u = ecore_time_unix_get();
|
|
|
|
if (i->show) tw_show(i);
|
|
|
|
i->show = 0;
|
|
|
|
eldbus_service_signal_emit(tw_dbus_iface, TEAMWORK_SIGNAL_LINK_COMPLETE, i->addr, u);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dbus_signal_link_invalid(Media *i)
|
|
|
|
{
|
|
|
|
unsigned int u = ecore_time_unix_get();
|
|
|
|
eldbus_service_signal_emit(tw_dbus_iface, TEAMWORK_SIGNAL_LINK_INVALID, i->addr, u);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dbus_signal_link_progress(Media *i, double pr)
|
|
|
|
{
|
|
|
|
unsigned int u = ecore_time_unix_get();
|
2013-06-17 08:06:43 -07:00
|
|
|
|
2013-06-14 07:36:11 -07:00
|
|
|
eldbus_service_signal_emit(tw_dbus_iface, TEAMWORK_SIGNAL_LINK_PROGRESS, i->addr, u, pr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dbus_signal_link_downloading(Media *i)
|
|
|
|
{
|
|
|
|
unsigned int u = ecore_time_unix_get();
|
|
|
|
eldbus_service_signal_emit(tw_dbus_iface, TEAMWORK_SIGNAL_LINK_DOWNLOADING, i->addr, u);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
download_media_complete(void *data, int type EINA_UNUSED, Ecore_Con_Event_Url_Complete *ev)
|
|
|
|
{
|
|
|
|
Media *i;
|
|
|
|
|
|
|
|
if (data != tw_mod) return ECORE_CALLBACK_RENEW;
|
|
|
|
i = ecore_con_url_data_get(ev->url_con);
|
|
|
|
if (!i) return ECORE_CALLBACK_RENEW;
|
|
|
|
if (!i->valid) return ECORE_CALLBACK_RENEW;
|
|
|
|
i->timestamp = (unsigned long long)ecore_time_unix_get();
|
2013-06-17 08:06:43 -07:00
|
|
|
if (tw_media_add(i->addr, i->buf, i->timestamp, i->video) == 1)
|
2013-06-14 07:36:11 -07:00
|
|
|
tw_mod->media_size += eina_binbuf_length_get(i->buf);
|
|
|
|
E_FREE_FUNC(i->client, ecore_con_url_free);
|
|
|
|
dbus_signal_link_complete(i);
|
|
|
|
download_media_cleanup();
|
2013-06-19 00:14:23 -07:00
|
|
|
DBG("MEDIA CACHE: %zu bytes", tw_mod->media_size);
|
2013-06-14 07:36:11 -07:00
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
download_media_data(void *data, int type EINA_UNUSED, Ecore_Con_Event_Url_Data *ev)
|
|
|
|
{
|
|
|
|
Media *i;
|
|
|
|
|
|
|
|
if (data != tw_mod) return ECORE_CALLBACK_RENEW;
|
|
|
|
i = ecore_con_url_data_get(ev->url_con);
|
|
|
|
if (!i) return ECORE_CALLBACK_RENEW;
|
|
|
|
if (i->dummy) return ECORE_CALLBACK_RENEW;
|
|
|
|
if (!i->buf) i->buf = eina_binbuf_new();
|
|
|
|
eina_binbuf_append_length(i->buf, ev->data, ev->size);
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2013-06-17 08:06:43 -07:00
|
|
|
download_media_status(void *data, int t EINA_UNUSED, Ecore_Con_Event_Url_Progress *ev)
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
|
|
|
int status;
|
|
|
|
const char *h;
|
|
|
|
Media *i;
|
|
|
|
const Eina_List *l;
|
|
|
|
|
|
|
|
if (data != tw_mod) return ECORE_CALLBACK_RENEW;
|
|
|
|
i = ecore_con_url_data_get(ev->url_con);
|
|
|
|
if (!i) return ECORE_CALLBACK_RENEW;
|
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
if (i->valid)
|
|
|
|
{
|
|
|
|
dbus_signal_link_progress(i, ev->down.now / ev->down.total);
|
|
|
|
return ECORE_CALLBACK_RENEW; //already checked
|
|
|
|
}
|
2013-06-14 07:36:11 -07:00
|
|
|
status = ecore_con_url_status_code_get(ev->url_con);
|
|
|
|
if (!status) return ECORE_CALLBACK_RENEW; //not ready yet
|
2013-06-17 08:06:43 -07:00
|
|
|
if (ev->down.total / 1024 / 1024 > tw_config->allowed_media_fetch_size)
|
|
|
|
{
|
|
|
|
DBG("Media larger than allowed!");
|
|
|
|
goto invalid;
|
|
|
|
}
|
2013-06-14 07:36:11 -07:00
|
|
|
DBG("%i code for media: %s", status, i->addr);
|
|
|
|
if (status != 200)
|
|
|
|
{
|
|
|
|
E_FREE_FUNC(i->buf, eina_binbuf_free);
|
|
|
|
E_FREE_FUNC(i->client, ecore_con_url_free);
|
|
|
|
if ((status >= 400) || (status <= 300)) goto dummy;
|
|
|
|
if (++i->tries < IMAGE_FETCH_TRIES)
|
|
|
|
{
|
|
|
|
i->client = ecore_con_url_new(i->addr);
|
|
|
|
ecore_con_url_data_set(i->client, i);
|
|
|
|
if (!ecore_con_url_get(i->client)) goto dummy;
|
|
|
|
}
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
EINA_LIST_FOREACH(ecore_con_url_response_headers_get(ev->url_con), l, h)
|
|
|
|
{
|
2013-06-17 08:06:43 -07:00
|
|
|
const char *type;
|
|
|
|
|
2013-06-14 07:36:11 -07:00
|
|
|
if (strncasecmp(h, "Content-Type: ", sizeof("Content-Type: ") - 1)) continue;
|
2013-06-17 08:06:43 -07:00
|
|
|
type = h + sizeof("Content-Type: ") - 1;
|
|
|
|
i->video = ((!strncasecmp(type, "video/", 6)) || (!strncasecmp(type, "application/ogg", sizeof("application/ogg") -1)));
|
|
|
|
if (i->video) break;
|
|
|
|
if (strncasecmp(type, "image/", 6)) goto dummy;
|
|
|
|
break;
|
2013-06-14 07:36:11 -07:00
|
|
|
}
|
|
|
|
i->valid = !i->dummy;
|
|
|
|
if (i->valid) dbus_signal_link_progress(i, ev->down.now / ev->down.total);
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
dummy:
|
|
|
|
dbus_signal_link_invalid(i);
|
|
|
|
tw_dummy_add(i->addr);
|
|
|
|
i->dummy = EINA_TRUE;
|
2013-06-17 08:06:43 -07:00
|
|
|
invalid:
|
2013-06-14 07:36:11 -07:00
|
|
|
E_FREE_FUNC(i->buf, eina_binbuf_free);
|
|
|
|
E_FREE_FUNC(i->client, ecore_con_url_free);
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
download_media_sort_cb(Media *a, Media *b)
|
|
|
|
{
|
|
|
|
long long diff;
|
|
|
|
diff = a->timestamp - b->timestamp;
|
|
|
|
if (diff < 0) return -1;
|
|
|
|
if (!diff) return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Media *
|
|
|
|
download_media_add(const char *url)
|
|
|
|
{
|
|
|
|
Media *i;
|
|
|
|
unsigned long long t;
|
2013-06-17 08:06:43 -07:00
|
|
|
Eina_Bool add = EINA_FALSE;
|
2013-06-14 07:36:11 -07:00
|
|
|
|
|
|
|
t = (unsigned long long)ecore_time_unix_get();
|
|
|
|
|
|
|
|
i = eina_hash_find(tw_mod->media, url);
|
|
|
|
if (i)
|
|
|
|
{
|
|
|
|
if (i->buf)
|
|
|
|
{
|
|
|
|
i->timestamp = t;
|
2013-06-17 08:06:43 -07:00
|
|
|
tw_media_ping(url, i->timestamp, i->video);
|
2013-06-14 07:36:11 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* randomly deleted during cache pruning */
|
2013-06-17 08:06:43 -07:00
|
|
|
i->buf = tw_media_get(url, t, &i->video);
|
|
|
|
if (i->buf) tw_mod->media_size += eina_binbuf_length_get(i->buf);
|
2013-06-14 07:36:11 -07:00
|
|
|
}
|
2013-06-17 08:06:43 -07:00
|
|
|
if (i->buf)
|
|
|
|
{
|
|
|
|
tw_mod->media_list = eina_inlist_promote(tw_mod->media_list, EINA_INLIST_GET(i));
|
|
|
|
download_media_cleanup();
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!i)
|
|
|
|
{
|
|
|
|
if (tw_dummy_check(url)) return NULL;
|
|
|
|
if (tw_config->disable_media_fetch) return NULL;
|
|
|
|
add = EINA_TRUE;
|
|
|
|
i = calloc(1, sizeof(Media));
|
|
|
|
i->addr = eina_stringshare_add(url);
|
|
|
|
i->buf = tw_media_get(url, t, &i->video);
|
|
|
|
}
|
2013-06-14 07:36:11 -07:00
|
|
|
if (i->buf)
|
|
|
|
tw_mod->media_size += eina_binbuf_length_get(i->buf);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
i->client = ecore_con_url_new(url);
|
|
|
|
ecore_con_url_data_set(i->client, i);
|
|
|
|
ecore_con_url_get(i->client);
|
|
|
|
dbus_signal_link_downloading(i);
|
|
|
|
}
|
2013-06-17 08:06:43 -07:00
|
|
|
if (!add) return i;
|
2013-06-14 07:36:11 -07:00
|
|
|
eina_hash_direct_add(tw_mod->media, url, i);
|
|
|
|
tw_mod->media_list = eina_inlist_sorted_insert(tw_mod->media_list, EINA_INLIST_GET(i), (Eina_Compare_Cb)download_media_sort_cb);
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
download_media_free(Media *i)
|
|
|
|
{
|
|
|
|
if (!i) return;
|
|
|
|
tw_mod->media_list = eina_inlist_remove(tw_mod->media_list, EINA_INLIST_GET(i));
|
|
|
|
if (i->client) ecore_con_url_free(i->client);
|
|
|
|
if (i->buf) eina_binbuf_free(i->buf);
|
2013-06-18 01:28:07 -07:00
|
|
|
if (i->tmpfile) ecore_file_unlink(i->tmpfile);
|
|
|
|
eina_stringshare_del(i->tmpfile);
|
2013-06-14 07:36:11 -07:00
|
|
|
eina_stringshare_del(i->addr);
|
|
|
|
free(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
download_media_cleanup(void)
|
|
|
|
{
|
|
|
|
Media *i;
|
|
|
|
Eina_Inlist *l;
|
|
|
|
|
|
|
|
if (tw_config->allowed_media_age)
|
|
|
|
{
|
|
|
|
if (tw_config->allowed_media_size < 0) return;
|
|
|
|
if ((size_t)tw_config->allowed_media_size > (tw_mod->media_size / 1024 / 1024)) return;
|
|
|
|
}
|
|
|
|
if (!tw_mod->media_list) return;
|
|
|
|
l = tw_mod->media_list->last;
|
|
|
|
while (l)
|
|
|
|
{
|
|
|
|
i = EINA_INLIST_CONTAINER_GET(l, Media);
|
|
|
|
l = l->prev;
|
|
|
|
if (!i->buf) continue;
|
2013-06-17 08:06:43 -07:00
|
|
|
if (i->video_thread) continue; //ignore currently-threaded media
|
2013-06-14 07:36:11 -07:00
|
|
|
/* only free the buffers here where possible to avoid having to deal with multiple list entries */
|
|
|
|
if (tw_mod->media_size && (tw_mod->media_size >= eina_binbuf_length_get(i->buf)))
|
|
|
|
tw_mod->media_size -= eina_binbuf_length_get(i->buf);
|
|
|
|
E_FREE_FUNC(i->buf, eina_binbuf_free);
|
|
|
|
if (!tw_config->allowed_media_age)
|
|
|
|
/* if caching is disabled, just delete */
|
|
|
|
eina_hash_del_by_key(tw_mod->media, i->addr);
|
|
|
|
if ((size_t)tw_config->allowed_media_size > (tw_mod->media_size / 1024 / 1024))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Teamwork_Link_Type
|
|
|
|
dbus_link_uri_local_type_get(const char *uri)
|
|
|
|
{
|
|
|
|
size_t len = strlen(uri);
|
|
|
|
|
|
|
|
if (uri[len - 1] == '/') return TEAMWORK_LINK_TYPE_LOCAL_DIRECTORY;
|
|
|
|
return TEAMWORK_LINK_TYPE_LOCAL_FILE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Teamwork_Link_Type
|
|
|
|
dbus_link_uri_type_get(const char *uri)
|
|
|
|
{
|
|
|
|
if (!uri[0]) return TEAMWORK_LINK_TYPE_NONE; //invalid
|
|
|
|
if (uri[0] == '/') return dbus_link_uri_local_type_get(uri + 1); //probably a file?
|
|
|
|
if ((!strncasecmp(uri, "http://", 7)) || (!strncasecmp(uri, "https://", 8))) return TEAMWORK_LINK_TYPE_REMOTE;
|
|
|
|
if (!strncmp(uri, "file://", 7)) return dbus_link_uri_local_type_get(uri + 7);
|
|
|
|
WRN("Unknown link type for '%s'", uri);
|
|
|
|
return TEAMWORK_LINK_TYPE_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eldbus_Message *
|
|
|
|
dbus_link_detect_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
|
|
|
|
{
|
|
|
|
const char *uri;
|
|
|
|
unsigned int t;
|
|
|
|
|
|
|
|
if (!tw_config->allowed_media_age) goto out;
|
|
|
|
if (!eldbus_message_arguments_get(msg, "su", &uri, &t)) goto out;
|
|
|
|
|
|
|
|
if (dbus_link_uri_type_get(uri) == TEAMWORK_LINK_TYPE_REMOTE)
|
|
|
|
download_media_add(uri);
|
|
|
|
out:
|
|
|
|
return eldbus_message_method_return_new(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dbus_link_show_helper(const char *uri, Eina_Bool signal_open)
|
|
|
|
{
|
|
|
|
Teamwork_Link_Type type;
|
|
|
|
|
|
|
|
if (tw_mod->pop && (!e_util_strcmp(e_object_data_get(E_OBJECT(tw_mod->pop)), uri))) return;
|
|
|
|
type = dbus_link_uri_type_get(uri);
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case TEAMWORK_LINK_TYPE_NONE: break;
|
|
|
|
case TEAMWORK_LINK_TYPE_LOCAL_DIRECTORY:
|
|
|
|
if (signal_open) tw_show_local_dir(uri);
|
|
|
|
break;
|
|
|
|
case TEAMWORK_LINK_TYPE_LOCAL_FILE:
|
|
|
|
tw_show_local_file(uri);
|
|
|
|
break;
|
|
|
|
case TEAMWORK_LINK_TYPE_REMOTE:
|
|
|
|
{
|
|
|
|
Media *i;
|
|
|
|
|
|
|
|
i = eina_hash_find(tw_mod->media, uri);
|
|
|
|
if (!i)
|
|
|
|
{
|
|
|
|
if (tw_dummy_check(uri)) break;
|
|
|
|
i = download_media_add(uri);
|
|
|
|
if (i)
|
|
|
|
{
|
|
|
|
if (i->buf) tw_show(i);
|
|
|
|
else if (i->dummy) break;
|
|
|
|
else i->show = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!i->dummy) tw_show(i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-06-17 01:03:21 -07:00
|
|
|
if (tw_mod->pop) tw_mod->force = signal_open;
|
2013-06-14 07:36:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Eldbus_Message *
|
|
|
|
dbus_link_show_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
|
|
|
|
{
|
|
|
|
const char *uri;
|
|
|
|
|
|
|
|
if (eldbus_message_arguments_get(msg, "s", &uri))
|
|
|
|
{
|
2013-06-19 00:14:23 -07:00
|
|
|
tw_win = 0;
|
2013-06-14 07:36:11 -07:00
|
|
|
last_coords.x = last_coords.y = -1;
|
|
|
|
dbus_link_show_helper(uri, 1);
|
|
|
|
}
|
|
|
|
return eldbus_message_method_return_new(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eldbus_Message *
|
|
|
|
dbus_link_hide_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
|
|
|
|
{
|
|
|
|
const char *uri;
|
|
|
|
|
|
|
|
if (eldbus_message_arguments_get(msg, "s", &uri))
|
|
|
|
{
|
|
|
|
if (tw_mod->pop && (!tw_mod->sticky) && (!e_util_strcmp(e_object_data_get(E_OBJECT(tw_mod->pop)), uri)))
|
2013-06-17 01:03:21 -07:00
|
|
|
{
|
|
|
|
tw_hide(NULL);
|
|
|
|
tw_mod->force = 0;
|
|
|
|
}
|
2013-06-14 07:36:11 -07:00
|
|
|
}
|
|
|
|
return eldbus_message_method_return_new(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eldbus_Message *
|
|
|
|
dbus_link_mouse_in_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
|
|
|
|
{
|
|
|
|
const char *uri;
|
|
|
|
unsigned int t;
|
2013-06-19 00:14:23 -07:00
|
|
|
int64_t win;
|
2013-06-14 07:36:11 -07:00
|
|
|
|
2013-06-19 00:14:23 -07:00
|
|
|
if (eldbus_message_arguments_get(msg, "suxii", &uri, &t, &win, &last_coords.x, &last_coords.y))
|
2013-06-18 01:28:07 -07:00
|
|
|
{
|
2013-06-19 00:14:23 -07:00
|
|
|
tw_win = win;
|
2013-06-18 01:28:07 -07:00
|
|
|
dbus_link_show_helper(uri, 0);
|
|
|
|
tw_mod->hidden = 0;
|
|
|
|
}
|
2013-06-14 07:36:11 -07:00
|
|
|
return eldbus_message_method_return_new(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eldbus_Message *
|
|
|
|
dbus_link_mouse_out_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
|
|
|
|
{
|
|
|
|
const char *uri;
|
|
|
|
unsigned int t;
|
2013-06-19 00:14:23 -07:00
|
|
|
int64_t win;
|
2013-06-14 07:36:11 -07:00
|
|
|
|
2013-06-19 00:14:23 -07:00
|
|
|
if (eldbus_message_arguments_get(msg, "suxii", &uri, &t, &win, &last_coords.x, &last_coords.y))
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
2013-06-17 08:06:43 -07:00
|
|
|
if (tw_mod->pop && (!tw_mod->sticky) &&
|
2013-06-30 23:58:47 -07:00
|
|
|
(
|
|
|
|
#ifdef HAVE_EMOTION
|
|
|
|
(tw_tmpfile && (!e_util_strcmp(e_object_data_get(E_OBJECT(tw_mod->pop)), tw_tmpfile))) ||
|
|
|
|
#endif
|
|
|
|
(!e_util_strcmp(e_object_data_get(E_OBJECT(tw_mod->pop)), uri))
|
|
|
|
))
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
|
|
|
if (tw_config->mouse_out_delay)
|
|
|
|
{
|
|
|
|
if (tw_hide_timer) ecore_timer_reset(tw_hide_timer);
|
|
|
|
else tw_hide_timer = ecore_timer_add(tw_config->mouse_out_delay, tw_hide, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
tw_hide(NULL);
|
2013-06-17 01:03:21 -07:00
|
|
|
tw_mod->force = 0;
|
2013-06-14 07:36:11 -07:00
|
|
|
}
|
2013-06-30 23:58:47 -07:00
|
|
|
#ifdef HAVE_EMOTION
|
2013-06-18 01:28:07 -07:00
|
|
|
else if (tw_tmpthread || tw_tmpfile)
|
|
|
|
tw_hide(NULL);
|
2013-06-30 23:58:47 -07:00
|
|
|
#endif
|
|
|
|
tw_mod->hidden = !tw_mod->pop;
|
2013-06-14 07:36:11 -07:00
|
|
|
}
|
|
|
|
return eldbus_message_method_return_new(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eldbus_Message *
|
|
|
|
dbus_link_open_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
|
|
|
|
{
|
|
|
|
const char *uri;
|
|
|
|
|
|
|
|
if (eldbus_message_arguments_get(msg, "s", &uri))
|
|
|
|
{
|
|
|
|
char *sb;
|
|
|
|
size_t size = 4096, len = sizeof(E_BINDIR "/enlightenment_open ") - 1;
|
|
|
|
|
|
|
|
sb = malloc(size);
|
|
|
|
memcpy(sb, E_BINDIR "/enlightenment_open ", len);
|
|
|
|
sb = e_util_string_append_quoted(sb, &size, &len, uri);
|
|
|
|
ecore_exe_run(sb, NULL);
|
|
|
|
free(sb);
|
|
|
|
}
|
|
|
|
return eldbus_message_method_return_new(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static const Eldbus_Method tw_methods[] = {
|
|
|
|
{ "LinkDetect", ELDBUS_ARGS({"s", "URI"}, {"u", "Timestamp"}), NULL, dbus_link_detect_cb },
|
2013-06-19 00:14:23 -07:00
|
|
|
{ "LinkMouseIn", ELDBUS_ARGS({"s", "URI"}, {"u", "Timestamp"}, {"x", "Window ID"}, {"i", "X Coordinate"}, {"i", "Y Coordinate"}), NULL, dbus_link_mouse_in_cb },
|
|
|
|
{ "LinkMouseOut", ELDBUS_ARGS({"s", "URI"}, {"u", "Timestamp"}, {"x", "Window ID"}, {"i", "X Coordinate"}, {"i", "Y Coordinate"}), NULL, dbus_link_mouse_out_cb },
|
2013-06-14 07:36:11 -07:00
|
|
|
{ "LinkShow", ELDBUS_ARGS({"s", "URI"}), NULL, dbus_link_show_cb },
|
|
|
|
{ "LinkHide", ELDBUS_ARGS({"s", "URI"}), NULL, dbus_link_hide_cb },
|
|
|
|
{ "LinkOpen", ELDBUS_ARGS({"s", "URI"}), NULL, dbus_link_open_cb },
|
|
|
|
{ }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const Eldbus_Service_Interface_Desc tw_desc =
|
|
|
|
{
|
|
|
|
"org.enlightenment.wm.Teamwork", tw_methods, tw_signals
|
|
|
|
};
|
|
|
|
|
|
|
|
static Eet_Data_Descriptor *
|
|
|
|
media_cache_edd_new(void)
|
|
|
|
{
|
|
|
|
Eet_Data_Descriptor *edd;
|
|
|
|
Eet_Data_Descriptor_Class eddc;
|
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Media_Cache);
|
|
|
|
edd = eet_data_descriptor_stream_new(&eddc);
|
|
|
|
#define ADD(name, type) \
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Media_Cache, #name, name, EET_T_##type)
|
|
|
|
|
|
|
|
ADD(sha1, INLINED_STRING);
|
|
|
|
ADD(timestamp, ULONG_LONG);
|
2013-06-17 08:06:43 -07:00
|
|
|
ADD(video, UCHAR);
|
2013-06-14 07:36:11 -07:00
|
|
|
#undef ADD
|
|
|
|
return edd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
media_cache_compare(Media_Cache *a, Media_Cache *b)
|
|
|
|
{
|
|
|
|
long long diff;
|
|
|
|
diff = a->timestamp - b->timestamp;
|
|
|
|
if (diff < 0) return -1;
|
|
|
|
if (!diff) return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-06-17 08:06:43 -07:00
|
|
|
media_cache_add(const char *sha1, unsigned long long timestamp, Eina_Bool video)
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
|
|
|
Media_Cache *ic;
|
2013-06-17 08:06:43 -07:00
|
|
|
if (!tw_cache_list[0]) return;
|
2013-06-14 07:36:11 -07:00
|
|
|
ic = malloc(sizeof(Media_Cache));
|
|
|
|
ic->sha1 = eina_stringshare_ref(sha1);
|
|
|
|
ic->timestamp = timestamp;
|
2013-06-17 08:06:43 -07:00
|
|
|
ic->video = video;
|
|
|
|
tw_cache_list[video]->cache = eina_list_sorted_insert(tw_cache_list[video]->cache, (Eina_Compare_Cb)media_cache_compare, ic);
|
2013-06-14 07:36:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-06-17 08:06:43 -07:00
|
|
|
media_cache_del(const char *sha1, Eina_Bool video)
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
|
|
|
Eina_List *l, *l2;
|
|
|
|
Media_Cache *ic;
|
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
if (!tw_cache_list[0]) return;
|
|
|
|
EINA_LIST_FOREACH_SAFE(tw_cache_list[video]->cache, l, l2, ic)
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
|
|
|
if (ic->sha1 == sha1) continue;
|
2013-06-17 08:06:43 -07:00
|
|
|
tw_cache_list[video]->cache = eina_list_remove_list(tw_cache_list[video]->cache, l);
|
2013-06-14 07:36:11 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-06-17 08:06:43 -07:00
|
|
|
media_cache_update(const char *sha1, unsigned long long timestamp, Eina_Bool video)
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
|
|
|
Media_Cache *ic;
|
|
|
|
Eina_List *l;
|
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
if (!tw_cache_list[video]) return;
|
|
|
|
EINA_LIST_FOREACH(tw_cache_list[video]->cache, l, ic)
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
|
|
|
if (ic->sha1 != sha1) continue;
|
|
|
|
ic->timestamp = timestamp;
|
|
|
|
break;
|
|
|
|
}
|
2013-06-17 08:06:43 -07:00
|
|
|
tw_cache_list[video]->cache = eina_list_sort(tw_cache_list[video]->cache, 0, (Eina_Compare_Cb)media_cache_compare);
|
2013-06-14 07:36:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2013-06-17 08:06:43 -07:00
|
|
|
media_cleaner_cb(void *data)
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
|
|
|
unsigned long long now;
|
2013-06-17 08:06:43 -07:00
|
|
|
Media_Cache_List *mcl = data;
|
2013-06-14 07:36:11 -07:00
|
|
|
Media_Cache *ic;
|
|
|
|
Eina_List *l, *l2;
|
|
|
|
int cleaned = 0;
|
2013-06-17 08:06:43 -07:00
|
|
|
if ((!cleaner_edd) || (!cache_edd) || (tw_config->allowed_media_age < 0) || (!mcl) || (!mcl->cache))
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
2013-06-17 08:06:43 -07:00
|
|
|
media_cleaner[mcl->video] = NULL;
|
2013-06-14 07:36:11 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tw_config->allowed_media_age)
|
|
|
|
{
|
|
|
|
now = (unsigned long long)ecore_time_unix_get();
|
|
|
|
now -= tw_config->allowed_media_age * 24 * 60 * 60;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
now = ULONG_LONG_MAX;
|
2013-06-17 08:06:43 -07:00
|
|
|
EINA_LIST_FOREACH_SAFE(mcl->cache, l, l2, ic)
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
|
|
|
/* only clean up to 3 entries at a time to ensure responsiveness */
|
|
|
|
if (cleaned >= 3) break;
|
|
|
|
if (ic->timestamp >= now)
|
|
|
|
{
|
|
|
|
/* stop the idler for now to avoid pointless spinning */
|
|
|
|
ecore_timer_add(24 * 60 * 60, (Ecore_Task_Cb)tw_idler_start, NULL);
|
2013-06-17 08:06:43 -07:00
|
|
|
media_cleaner[mcl->video] = NULL;
|
|
|
|
tw_cache_list[mcl->video] = mcl;
|
2013-06-14 07:36:11 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2013-06-17 08:06:43 -07:00
|
|
|
eet_delete(media[mcl->video], ic->sha1);
|
|
|
|
mcl->cache = eina_list_remove_list(mcl->cache, l);
|
2013-06-14 07:36:11 -07:00
|
|
|
eina_stringshare_del(ic->sha1);
|
|
|
|
free(ic);
|
|
|
|
cleaned++;
|
|
|
|
}
|
2013-06-17 08:06:43 -07:00
|
|
|
tw_cache_list[mcl->video] = mcl;
|
2013-06-14 07:36:11 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tw_dummy_add(const char *url)
|
|
|
|
{
|
|
|
|
if (!dummies) return;
|
|
|
|
eet_write(dummies, url, "0", 1, 0);
|
2013-06-19 00:14:23 -07:00
|
|
|
DBG("Added new dummy for url %s", url);
|
2013-06-14 07:36:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
tw_dummy_check(const char *url)
|
|
|
|
{
|
|
|
|
char **list;
|
|
|
|
int lsize;
|
|
|
|
|
|
|
|
if (!dummies) return EINA_FALSE;
|
|
|
|
list = eet_list(dummies, url, &lsize);
|
|
|
|
if (lsize)
|
|
|
|
{
|
|
|
|
free(list);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2013-06-17 08:06:43 -07:00
|
|
|
tw_media_add(const char *url, Eina_Binbuf *buf, unsigned long long timestamp, Eina_Bool video)
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
|
|
|
const char *sha1;
|
|
|
|
int lsize;
|
|
|
|
char **list;
|
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
if (!media[video]) return -1;
|
2013-06-14 07:36:11 -07:00
|
|
|
if (!tw_config->allowed_media_age) return 0; //disk caching disabled
|
|
|
|
|
|
|
|
sha1 = sha1_encode(eina_binbuf_string_get(buf), eina_binbuf_length_get(buf));
|
2013-06-19 00:14:23 -07:00
|
|
|
DBG("Media: %s - %s", url, sha1);
|
2013-06-14 07:36:11 -07:00
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
list = eet_list(media[video], url, &lsize);
|
2013-06-14 07:36:11 -07:00
|
|
|
if (lsize)
|
|
|
|
{
|
2013-06-17 08:06:43 -07:00
|
|
|
/* should never happen; corruption likely */
|
|
|
|
eet_delete(media[video], url);
|
2013-06-14 07:36:11 -07:00
|
|
|
free(list);
|
|
|
|
}
|
2013-06-17 08:06:43 -07:00
|
|
|
list = eet_list(media[video], sha1, &lsize);
|
2013-06-14 07:36:11 -07:00
|
|
|
if (lsize)
|
|
|
|
{
|
2013-06-17 08:06:43 -07:00
|
|
|
eet_alias(media[video], url, sha1, 0);
|
|
|
|
eet_sync(media[video]);
|
2013-06-19 00:14:23 -07:00
|
|
|
DBG("Added new alias for media %s", sha1);
|
2013-06-14 07:36:11 -07:00
|
|
|
eina_stringshare_del(sha1);
|
|
|
|
free(list);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
eet_write(media[video], sha1, eina_binbuf_string_get(buf), eina_binbuf_length_get(buf), 0);
|
|
|
|
eet_alias(media[video], url, sha1, 0);
|
|
|
|
eet_sync(media[video]);
|
|
|
|
media_cache_add(sha1, timestamp, video);
|
2013-06-19 00:14:23 -07:00
|
|
|
DBG("Added new media with length %zu: %s", eina_binbuf_length_get(buf), sha1);
|
2013-06-14 07:36:11 -07:00
|
|
|
eina_stringshare_del(sha1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-17 08:06:43 -07:00
|
|
|
tw_media_del(const char *url, Eina_Bool video)
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
|
|
|
const char *alias;
|
2013-06-17 08:06:43 -07:00
|
|
|
if (!media[video]) return;
|
|
|
|
alias = eet_alias_get(media[video], url);
|
|
|
|
eet_delete(media[video], alias);
|
|
|
|
media_cache_del(alias, video);
|
2013-06-14 07:36:11 -07:00
|
|
|
eina_stringshare_del(alias);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Binbuf *
|
2013-06-17 08:06:43 -07:00
|
|
|
tw_media_get(const char *url, unsigned long long timestamp, Eina_Bool *video)
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
|
|
|
unsigned char *img;
|
|
|
|
Eina_Binbuf *buf = NULL;
|
|
|
|
const char *alias;
|
|
|
|
char **list;
|
2013-06-17 08:06:43 -07:00
|
|
|
int size, lsize;
|
2013-06-14 07:36:11 -07:00
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
for (*video = 0; *video <= MEDIA_CACHE_TYPE_VIDEO; (*video)++)
|
|
|
|
{
|
|
|
|
if (!media[*video]) return NULL;
|
2013-06-14 07:36:11 -07:00
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
list = eet_list(media[*video], url, &lsize);
|
|
|
|
if (!lsize) continue;
|
|
|
|
free(list);
|
2013-06-14 07:36:11 -07:00
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
img = eet_read(media[*video], url, &size);
|
|
|
|
alias = eet_alias_get(media[*video], url);
|
|
|
|
buf = eina_binbuf_manage_new_length(img, size);
|
|
|
|
media_cache_update(alias, timestamp, *video);
|
2013-06-14 07:36:11 -07:00
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
eina_stringshare_del(alias);
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
return NULL;
|
2013-06-14 07:36:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-06-17 08:06:43 -07:00
|
|
|
tw_media_ping(const char *url, unsigned long long timestamp, Eina_Bool video)
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
|
|
|
const char *alias;
|
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
if (!media[video]) return;
|
2013-06-14 07:36:11 -07:00
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
alias = eet_alias_get(media[video], url);
|
|
|
|
media_cache_update(alias, timestamp, video);
|
2013-06-14 07:36:11 -07:00
|
|
|
|
|
|
|
eina_stringshare_del(alias);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
tw_idler_start(void)
|
|
|
|
{
|
2013-06-17 08:06:43 -07:00
|
|
|
if (!media[0]) return EINA_FALSE;
|
|
|
|
media_cleaner[0] = ecore_idler_add((Ecore_Task_Cb)media_cleaner_cb, tw_cache_list[0]);
|
|
|
|
media_cleaner[1] = ecore_idler_add((Ecore_Task_Cb)media_cleaner_cb, tw_cache_list[1]);
|
2013-06-14 07:36:11 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tw_popup_del(void *obj)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(e_object_data_get(obj));
|
|
|
|
}
|
|
|
|
|
|
|
|
EINTERN void
|
|
|
|
tw_popup_opacity_set(void)
|
|
|
|
{
|
|
|
|
if (tw_mod->pop && tw_mod->pop->cw)
|
|
|
|
e_comp_win_opacity_set(tw_mod->pop->cw, lround((double)255 * (tw_config->popup_opacity / 100.)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tw_show_helper(Evas_Object *o, int w, int h)
|
|
|
|
{
|
|
|
|
int px, py, pw, ph;
|
|
|
|
double ratio = tw_config->popup_size / 100.;
|
|
|
|
|
|
|
|
E_FREE_FUNC(tw_mod->pop, e_object_del);
|
|
|
|
tw_mod->sticky = 0;
|
|
|
|
tw_mod->pop = e_popup_new(e_zone_current_get(e_util_container_current_get()), 0, 0, 1, 1);
|
|
|
|
e_popup_ignore_events_set(tw_mod->pop, 1);
|
|
|
|
pw = MIN(w, (ratio * (double)tw_mod->pop->zone->w));
|
|
|
|
pw = MIN(pw, tw_mod->pop->zone->w);
|
|
|
|
if (pw == w) ph = h;
|
|
|
|
else
|
|
|
|
ph = lround((double)(pw * h) / ((double)w));
|
|
|
|
if (ph > tw_mod->pop->zone->h)
|
|
|
|
{
|
|
|
|
ph = tw_mod->pop->zone->h;
|
|
|
|
pw = lround((double)(ph * w) / ((double)h));
|
|
|
|
}
|
|
|
|
e_widget_preview_size_set(o, pw, ph);
|
2013-06-15 16:57:53 -07:00
|
|
|
e_widget_preview_vsize_set(o, pw, ph);
|
2013-06-14 07:36:11 -07:00
|
|
|
e_popup_layer_set(tw_mod->pop, E_COMP_CANVAS_LAYER_POPUP, 0);
|
|
|
|
|
2013-06-19 00:14:23 -07:00
|
|
|
if ((!tw_win) && (last_coords.x == last_coords.y) && (last_coords.x == -1))
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
|
|
|
px = lround(ratio * (double)tw_mod->pop->zone->w) - (pw / 2);
|
|
|
|
py = lround(ratio * (double)tw_mod->pop->zone->h) - (ph / 2);
|
|
|
|
if (px + pw > tw_mod->pop->zone->w)
|
|
|
|
px = tw_mod->pop->zone->w - pw;
|
|
|
|
if (py + ph > tw_mod->pop->zone->h)
|
|
|
|
py = tw_mod->pop->zone->h - ph;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-06-19 00:14:23 -07:00
|
|
|
E_Border *bd = e_border_find_by_client_window(tw_win);
|
2013-06-21 07:01:14 -07:00
|
|
|
int x, y;
|
|
|
|
|
|
|
|
x = bd->x + bd->client_inset.l + last_coords.x;
|
|
|
|
y = bd->y + bd->client_inset.t + last_coords.y;
|
2013-06-14 07:36:11 -07:00
|
|
|
/* prefer tooltip left of last_coords */
|
2013-06-21 07:01:14 -07:00
|
|
|
px = x - pw - 3;
|
2013-06-14 07:36:11 -07:00
|
|
|
/* if it's offscreen, try right of last_coords */
|
2013-06-21 07:01:14 -07:00
|
|
|
if (px < 0) px = x + 3;
|
2013-06-14 07:36:11 -07:00
|
|
|
/* fuck this, stick it right on the last_coords */
|
|
|
|
if (px + pw + 3 > tw_mod->pop->zone->w)
|
2013-06-21 07:01:14 -07:00
|
|
|
px = (x / 2) - (pw / 2);
|
2013-06-14 07:36:11 -07:00
|
|
|
/* give up */
|
|
|
|
if (px < 0) px = 0;
|
|
|
|
|
|
|
|
/* prefer tooltip above last_coords */
|
2013-06-21 07:01:14 -07:00
|
|
|
py = y - ph - 3;
|
2013-06-14 07:36:11 -07:00
|
|
|
/* if it's offscreen, try below last_coords */
|
2013-06-21 07:01:14 -07:00
|
|
|
if (py < 0) py = y + 3;
|
2013-06-14 07:36:11 -07:00
|
|
|
/* fuck this, stick it right on the last_coords */
|
|
|
|
if (py + ph + 3 > tw_mod->pop->zone->h)
|
2013-06-21 07:01:14 -07:00
|
|
|
py = (y / 2) - (ph / 2);
|
2013-06-14 07:36:11 -07:00
|
|
|
/* give up */
|
|
|
|
if (py < 0) py = 0;
|
|
|
|
}
|
|
|
|
e_popup_move_resize(tw_mod->pop, px, py, pw, ph);
|
|
|
|
e_popup_content_set(tw_mod->pop, o);
|
|
|
|
e_popup_show(tw_mod->pop);
|
|
|
|
tw_popup_opacity_set();
|
|
|
|
E_OBJECT_DEL_SET(tw_mod->pop, tw_popup_del);
|
|
|
|
}
|
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
#ifdef HAVE_EMOTION
|
2013-06-18 01:28:07 -07:00
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
stupid_obj_del_workaround_hack(void *data)
|
|
|
|
{
|
|
|
|
evas_object_del(data);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tw_video_closed_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
|
|
{
|
|
|
|
evas_object_hide(obj);
|
|
|
|
evas_object_hide(data);
|
|
|
|
ecore_timer_add(3.0, stupid_obj_del_workaround_hack, data);
|
|
|
|
if (!tw_tmpfile) return;
|
|
|
|
eina_stringshare_replace(&tw_tmpfile, NULL);
|
|
|
|
}
|
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
static void
|
|
|
|
tw_video_opened_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
|
|
{
|
|
|
|
int iw, ih, w, h;
|
|
|
|
double ratio = tw_config->popup_size / 100.;
|
|
|
|
E_Zone *zone;
|
|
|
|
|
2013-06-18 01:28:07 -07:00
|
|
|
if (tw_mod->hidden && (!tw_mod->sticky) && (!tw_mod->force))
|
|
|
|
{
|
|
|
|
tw_video_closed_cb(data, obj, NULL);
|
|
|
|
return;
|
|
|
|
}
|
2013-06-17 08:06:43 -07:00
|
|
|
emotion_object_size_get(obj, &iw, &ih);
|
|
|
|
|
|
|
|
zone = e_zone_current_get(e_util_container_current_get());
|
|
|
|
w = MIN(zone->w, (ratio * (double)zone->w));
|
|
|
|
ratio = emotion_object_ratio_get(obj);
|
|
|
|
if (ratio > 0.0) iw = (ih * ratio) + 0.5;
|
|
|
|
if (iw < 1) iw = 1;
|
|
|
|
if (ih < 1) ih = 1;
|
|
|
|
|
|
|
|
h = (w * ih) / iw;
|
|
|
|
e_widget_preview_extern_object_set(data, obj);
|
|
|
|
tw_show_helper(data, w, h);
|
|
|
|
e_popup_object_add(tw_mod->pop, obj);
|
|
|
|
e_object_data_set(E_OBJECT(tw_mod->pop), eina_stringshare_add(emotion_object_file_get(obj)));
|
|
|
|
evas_object_smart_callback_del_full(obj, "frame_decode", tw_video_opened_cb, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tw_video_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
|
|
{
|
|
|
|
if (emotion_object_file_get(obj) != tw_tmpfile) return;
|
|
|
|
if (!tw_tmpfile) return;
|
|
|
|
eina_stringshare_replace(&tw_tmpfile, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tw_show_video(Evas_Object *prev, const char *uri)
|
|
|
|
{
|
|
|
|
Evas_Object *o;
|
|
|
|
|
|
|
|
o = emotion_object_add(e_widget_preview_evas_get(prev));
|
|
|
|
#if (EMOTION_VERSION_MAJOR > 1) || (EMOTION_VERSION_MINOR >= 8)
|
|
|
|
emotion_object_init(o, "vlc");
|
|
|
|
#else
|
|
|
|
emotion_object_init(o, NULL);
|
|
|
|
#endif
|
|
|
|
emotion_object_file_set(o, uri);
|
|
|
|
emotion_object_play_set(o, EINA_TRUE);
|
|
|
|
evas_object_smart_callback_add(o, "frame_decode", tw_video_opened_cb, prev);
|
2013-06-18 01:28:07 -07:00
|
|
|
evas_object_smart_callback_add(o, "decode_stop", tw_video_closed_cb, prev);
|
2013-06-17 08:06:43 -07:00
|
|
|
evas_object_resize(o, 1, 1);
|
|
|
|
if (uri == tw_tmpfile)
|
|
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, tw_video_del_cb, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tw_video_thread_cancel_cb(void *data, Ecore_Thread *eth)
|
|
|
|
{
|
|
|
|
Media *i;
|
|
|
|
|
|
|
|
if (ecore_thread_local_data_find(eth, "dead")) return;
|
|
|
|
i = data;
|
|
|
|
tw_tmpthread = i->video_thread = NULL;
|
|
|
|
tw_tmpthread_media = NULL;
|
|
|
|
close(tw_tmpfd);
|
|
|
|
tw_tmpfd = -1;
|
|
|
|
download_media_cleanup();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tw_video_thread_done_cb(void *data, Ecore_Thread *eth)
|
|
|
|
{
|
|
|
|
Media *i;
|
|
|
|
Evas_Object *prev;
|
|
|
|
|
|
|
|
if (ecore_thread_local_data_find(eth, "dead")) return;
|
|
|
|
i = data;
|
|
|
|
tw_tmpthread = i->video_thread = NULL;
|
|
|
|
tw_tmpthread_media = NULL;
|
|
|
|
close(tw_tmpfd);
|
|
|
|
tw_tmpfd = -1;
|
2013-06-18 01:28:07 -07:00
|
|
|
i->tmpfile = eina_stringshare_ref(tw_tmpfile);
|
2013-06-17 08:06:43 -07:00
|
|
|
prev = e_widget_preview_add(e_util_comp_current_get()->evas, 50, 50);
|
|
|
|
tw_show_video(prev, tw_tmpfile);
|
|
|
|
download_media_cleanup();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tw_video_thread_cb(void *data, Ecore_Thread *eth)
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
Media *i;
|
|
|
|
const void *buf;
|
|
|
|
size_t pos = 0, tot;
|
|
|
|
|
|
|
|
if (ecore_thread_local_data_find(eth, "dead")) return;
|
|
|
|
i = data;
|
|
|
|
fd = (intptr_t)ecore_thread_global_data_find("teamwork_media_file");
|
|
|
|
|
|
|
|
if (ftruncate(fd, 0))
|
|
|
|
{
|
|
|
|
ERR("TRUNCATE FAILED: %s", strerror(errno));
|
2013-06-18 01:28:07 -07:00
|
|
|
ecore_thread_cancel(eth);
|
2013-06-17 08:06:43 -07:00
|
|
|
return; //fail if file can't be zeroed
|
|
|
|
}
|
|
|
|
tot = eina_binbuf_length_get(i->buf);
|
|
|
|
buf = eina_binbuf_string_get(i->buf);
|
|
|
|
while (pos < tot)
|
|
|
|
{
|
|
|
|
unsigned int num = 4096;
|
|
|
|
|
|
|
|
if (pos + num >= tot)
|
|
|
|
num = tot - pos;
|
2013-06-18 01:28:07 -07:00
|
|
|
if (write(fd, buf + pos, num) < 0)
|
|
|
|
{
|
|
|
|
ERR("WRITE FAILED: %s", strerror(errno));
|
|
|
|
ecore_thread_cancel(eth);
|
|
|
|
return;
|
|
|
|
}
|
2013-06-17 08:06:43 -07:00
|
|
|
pos += num;
|
|
|
|
if (ecore_thread_local_data_find(eth, "dead")) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2013-06-14 07:36:11 -07:00
|
|
|
static void
|
|
|
|
tw_show(Media *i)
|
|
|
|
{
|
|
|
|
Evas_Object *o, *ic, *prev;
|
|
|
|
int w, h;
|
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
if (!i->buf) i->buf = tw_media_get(i->addr, ecore_time_unix_get(), &i->video);
|
|
|
|
if (!i->buf)
|
|
|
|
{
|
|
|
|
download_media_add(i->addr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#ifdef HAVE_EMOTION
|
|
|
|
if (i->video)
|
|
|
|
{
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
const char *tmp;
|
|
|
|
|
2013-06-18 00:05:02 -07:00
|
|
|
if (tw_config->disable_video) return;
|
2013-06-18 01:28:07 -07:00
|
|
|
while (i->tmpfile)
|
|
|
|
{
|
|
|
|
if (!ecore_file_exists(i->tmpfile))
|
|
|
|
{
|
|
|
|
eina_stringshare_replace(&i->tmpfile, NULL);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (tw_tmpthread)
|
|
|
|
{
|
|
|
|
ecore_thread_local_data_add(tw_tmpthread, "dead", (void*)1, NULL, 0);
|
|
|
|
E_FREE_FUNC(tw_tmpthread, ecore_thread_cancel);
|
|
|
|
tw_tmpthread_media->video_thread = NULL;
|
|
|
|
}
|
|
|
|
if (tw_tmpfd != -1)
|
|
|
|
{
|
|
|
|
close(tw_tmpfd);
|
|
|
|
tw_tmpfd = -1;
|
|
|
|
}
|
|
|
|
eina_stringshare_del(tw_tmpfile);
|
|
|
|
tw_tmpfile = eina_stringshare_ref(i->tmpfile);
|
|
|
|
prev = e_widget_preview_add(e_util_comp_current_get()->evas, 50, 50);
|
|
|
|
tw_show_video(prev, tw_tmpfile);
|
|
|
|
return;
|
|
|
|
}
|
2013-06-17 08:06:43 -07:00
|
|
|
tmp = getenv("XDG_RUNTIME_DIR");
|
|
|
|
if (!tmp) tmp = "/tmp";
|
|
|
|
snprintf(buf, sizeof(buf), "%s/teamwork-%s-XXXXXX", tmp, ecore_file_file_get(i->addr));
|
|
|
|
if (tw_tmpfile)
|
|
|
|
{
|
|
|
|
if (tw_tmpthread)
|
|
|
|
{
|
|
|
|
ecore_thread_local_data_add(tw_tmpthread, "dead", (void*)1, NULL, 0);
|
|
|
|
E_FREE_FUNC(tw_tmpthread, ecore_thread_cancel);
|
|
|
|
tw_tmpthread_media->video_thread = NULL;
|
|
|
|
}
|
|
|
|
close(tw_tmpfd);
|
|
|
|
}
|
|
|
|
tw_tmpfd = mkstemp(buf);
|
|
|
|
eina_stringshare_replace(&tw_tmpfile, buf);
|
|
|
|
if (tw_tmpfd < 0)
|
|
|
|
{
|
2013-06-19 00:14:23 -07:00
|
|
|
ERR("ERROR: %s", strerror(errno));
|
2013-06-17 08:06:43 -07:00
|
|
|
download_media_cleanup();
|
|
|
|
eina_stringshare_replace(&tw_tmpfile, NULL);
|
|
|
|
tw_tmpthread_media = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
tw_tmpthread_media = i;
|
|
|
|
ecore_thread_global_data_add("teamwork_media_file", (intptr_t*)(long)tw_tmpfd, NULL, 0);
|
|
|
|
i->video_thread = tw_tmpthread = ecore_thread_run(tw_video_thread_cb, tw_video_thread_done_cb, tw_video_thread_cancel_cb, i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
prev = e_widget_preview_add(e_util_comp_current_get()->evas, 50, 50);
|
|
|
|
o = evas_object_image_filled_add(e_widget_preview_evas_get(prev));
|
|
|
|
evas_object_image_memfile_set(o, (void*)eina_binbuf_string_get(i->buf), eina_binbuf_length_get(i->buf), NULL, NULL);
|
|
|
|
evas_object_image_size_get(o, &w, &h);
|
|
|
|
ic = e_icon_add(e_widget_preview_evas_get(prev));
|
|
|
|
e_icon_image_object_set(ic, o);
|
|
|
|
}
|
2013-06-14 07:36:11 -07:00
|
|
|
e_widget_preview_extern_object_set(prev, ic);
|
|
|
|
tw_show_helper(prev, w, h);
|
|
|
|
e_object_data_set(E_OBJECT(tw_mod->pop), eina_stringshare_ref(i->addr));
|
|
|
|
e_popup_object_add(tw_mod->pop, ic);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tw_show_local_dir(const char *uri)
|
|
|
|
{
|
|
|
|
E_Action *act;
|
|
|
|
|
|
|
|
act = e_action_find("fileman");
|
|
|
|
if (act) act->func.go(NULL, uri);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tw_show_local_file(const char *uri)
|
|
|
|
{
|
|
|
|
Evas_Object *o, *prev;
|
|
|
|
int w, h;
|
2013-06-17 08:06:43 -07:00
|
|
|
Eina_Bool video = EINA_FALSE;
|
2013-06-14 07:36:11 -07:00
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
#ifdef HAVE_EMOTION
|
|
|
|
video = emotion_object_extension_may_play_get(uri);
|
|
|
|
#endif
|
2013-06-18 00:05:02 -07:00
|
|
|
if (video)
|
|
|
|
{
|
|
|
|
if (tw_config->disable_video) return;
|
|
|
|
}
|
|
|
|
else
|
2013-06-17 08:06:43 -07:00
|
|
|
{
|
|
|
|
if (!evas_object_image_extension_can_load_get(uri)) return;
|
|
|
|
}
|
2013-06-14 07:36:11 -07:00
|
|
|
prev = e_widget_preview_add(e_util_comp_current_get()->evas, 50, 50);
|
2013-06-17 08:06:43 -07:00
|
|
|
#ifdef HAVE_EMOTION
|
|
|
|
if (video)
|
|
|
|
{
|
|
|
|
tw_show_video(prev, uri);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
o = e_icon_add(e_widget_preview_evas_get(prev));
|
|
|
|
e_icon_file_set(o, uri);
|
|
|
|
e_icon_preload_set(o, 1);
|
|
|
|
e_icon_size_get(o, &w, &h);
|
|
|
|
}
|
2013-06-14 07:36:11 -07:00
|
|
|
e_widget_preview_extern_object_set(prev, o);
|
|
|
|
tw_show_helper(prev, w, h);
|
|
|
|
e_popup_object_add(tw_mod->pop, o);
|
|
|
|
e_object_data_set(E_OBJECT(tw_mod->pop), eina_stringshare_add(uri));
|
|
|
|
}
|
|
|
|
|
2013-06-17 01:13:47 -07:00
|
|
|
static Eina_Bool
|
|
|
|
focus_out(void *data EINA_UNUSED, int type EINA_UNUSED, E_Event_Border_Focus_Out *ev EINA_UNUSED)
|
|
|
|
{
|
|
|
|
if (!tw_mod->pop) return ECORE_CALLBACK_RENEW;
|
|
|
|
if (e_config->focus_policy == E_FOCUS_CLICK) return ECORE_CALLBACK_RENEW;
|
2013-06-17 01:19:04 -07:00
|
|
|
if (tw_mod->force || tw_mod->sticky) return ECORE_CALLBACK_RENEW;
|
2013-06-17 01:13:47 -07:00
|
|
|
if (tw_config->mouse_out_delay)
|
|
|
|
{
|
|
|
|
if (tw_hide_timer) ecore_timer_reset(tw_hide_timer);
|
|
|
|
else tw_hide_timer = ecore_timer_add(tw_config->mouse_out_delay, tw_hide, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
tw_hide(NULL);
|
|
|
|
tw_mod->force = 0;
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
2013-06-14 07:36:11 -07:00
|
|
|
EINTERN Eina_Bool
|
|
|
|
tw_hide(void *d EINA_UNUSED)
|
|
|
|
{
|
2013-06-30 23:58:47 -07:00
|
|
|
#ifdef HAVE_EMOTION
|
2013-06-18 01:28:07 -07:00
|
|
|
if (tw_tmpthread)
|
|
|
|
{
|
|
|
|
ecore_thread_local_data_add(tw_tmpthread, "dead", (void*)1, NULL, 0);
|
|
|
|
E_FREE_FUNC(tw_tmpthread, ecore_thread_cancel);
|
|
|
|
tw_tmpthread_media->video_thread = NULL;
|
|
|
|
}
|
|
|
|
if (tw_tmpfd != -1)
|
|
|
|
{
|
|
|
|
close(tw_tmpfd);
|
|
|
|
tw_tmpfd = -1;
|
|
|
|
}
|
2013-06-30 23:58:47 -07:00
|
|
|
eina_stringshare_replace(&tw_tmpfile, NULL);
|
|
|
|
#endif
|
2013-06-19 00:14:23 -07:00
|
|
|
tw_win = 0;
|
2013-06-14 07:36:11 -07:00
|
|
|
E_FREE_FUNC(tw_mod->pop, e_object_del);
|
|
|
|
last_coords.x = last_coords.y = 0;
|
|
|
|
E_FREE_FUNC(tw_hide_timer, ecore_timer_del);
|
|
|
|
download_media_cleanup();
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
EINTERN int
|
|
|
|
e_tw_init(void)
|
|
|
|
{
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
Eet_Data_Descriptor_Class eddc;
|
|
|
|
|
|
|
|
tw_dbus_iface = e_msgbus_interface_attach(&tw_desc);
|
|
|
|
|
2013-06-17 08:06:43 -07:00
|
|
|
e_user_dir_concat_static(buf, "images/tw_cache_images.eet");
|
|
|
|
media[MEDIA_CACHE_TYPE_IMAGE] = eet_open(buf, EET_FILE_MODE_READ_WRITE);
|
|
|
|
if (!media[MEDIA_CACHE_TYPE_IMAGE])
|
|
|
|
{
|
|
|
|
ERR("Could not open image cache file!");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
e_user_dir_concat_static(buf, "images/tw_cache_video.eet");
|
|
|
|
media[MEDIA_CACHE_TYPE_VIDEO] = eet_open(buf, EET_FILE_MODE_READ_WRITE);
|
|
|
|
if (!media[MEDIA_CACHE_TYPE_VIDEO])
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
2013-06-17 08:06:43 -07:00
|
|
|
ERR("Could not open video cache file!");
|
|
|
|
E_FREE_FUNC(media[MEDIA_CACHE_TYPE_IMAGE], eet_close);
|
2013-06-14 07:36:11 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
cache_edd = media_cache_edd_new();
|
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Media_Cache_List);
|
|
|
|
cleaner_edd = eet_data_descriptor_file_new(&eddc);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_LIST(cleaner_edd, Media_Cache_List, "cache", cache, cache_edd);
|
2013-06-17 08:06:43 -07:00
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(cleaner_edd, Media_Cache_List, "video", video, EET_T_UCHAR);
|
|
|
|
tw_cache_list[MEDIA_CACHE_TYPE_IMAGE] = eet_data_read(media[MEDIA_CACHE_TYPE_IMAGE], cleaner_edd, "media_cache");
|
|
|
|
if (!tw_cache_list[MEDIA_CACHE_TYPE_IMAGE])
|
|
|
|
tw_cache_list[MEDIA_CACHE_TYPE_IMAGE] = E_NEW(Media_Cache_List, 1);
|
|
|
|
tw_cache_list[MEDIA_CACHE_TYPE_VIDEO] = eet_data_read(media[MEDIA_CACHE_TYPE_VIDEO], cleaner_edd, "media_cache");
|
|
|
|
if (!tw_cache_list[MEDIA_CACHE_TYPE_VIDEO])
|
|
|
|
{
|
|
|
|
tw_cache_list[MEDIA_CACHE_TYPE_VIDEO] = E_NEW(Media_Cache_List, 1);
|
|
|
|
tw_cache_list[MEDIA_CACHE_TYPE_VIDEO]->video = 1;
|
|
|
|
}
|
2013-06-14 07:36:11 -07:00
|
|
|
|
|
|
|
e_user_dir_concat_static(buf, "images/dummies.eet");
|
|
|
|
dummies = eet_open(buf, EET_FILE_MODE_READ_WRITE);
|
|
|
|
|
|
|
|
E_LIST_HANDLER_APPEND(handlers, ECORE_CON_EVENT_URL_COMPLETE, download_media_complete, tw_mod);
|
|
|
|
E_LIST_HANDLER_APPEND(handlers, ECORE_CON_EVENT_URL_PROGRESS, download_media_status, tw_mod);
|
|
|
|
E_LIST_HANDLER_APPEND(handlers, ECORE_CON_EVENT_URL_DATA, download_media_data, tw_mod);
|
2013-06-17 01:13:47 -07:00
|
|
|
E_LIST_HANDLER_APPEND(handlers, E_EVENT_BORDER_FOCUS_OUT, focus_out, tw_mod);
|
2013-06-14 07:36:11 -07:00
|
|
|
|
|
|
|
tw_mod->media = eina_hash_string_superfast_new((Eina_Free_Cb)download_media_free);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
EINTERN void
|
|
|
|
e_tw_shutdown(void)
|
|
|
|
{
|
2013-06-17 08:06:43 -07:00
|
|
|
unsigned int x;
|
2013-06-14 07:36:11 -07:00
|
|
|
E_FREE_LIST(handlers, ecore_event_handler_del);
|
2013-06-17 08:06:43 -07:00
|
|
|
for (x = 0; x <= MEDIA_CACHE_TYPE_VIDEO; x++)
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
2013-06-17 08:06:43 -07:00
|
|
|
if (media[x])
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
2013-06-17 08:06:43 -07:00
|
|
|
if (tw_cache_list[x])
|
2013-06-14 07:36:11 -07:00
|
|
|
{
|
2013-06-17 08:06:43 -07:00
|
|
|
Media_Cache *ic;
|
|
|
|
eet_data_write(media[x], cleaner_edd, "media_cache", tw_cache_list[x], 1);
|
|
|
|
EINA_LIST_FREE(tw_cache_list[x]->cache, ic)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(ic->sha1);
|
|
|
|
free(ic);
|
|
|
|
}
|
|
|
|
free(tw_cache_list[x]);
|
2013-06-14 07:36:11 -07:00
|
|
|
}
|
2013-06-17 08:06:43 -07:00
|
|
|
E_FREE_FUNC(media[x], eet_close);
|
2013-06-14 07:36:11 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
E_FREE_FUNC(tw_dbus_iface, eldbus_service_interface_unregister);
|
|
|
|
E_FREE_FUNC(dummies, eet_close);
|
|
|
|
E_FREE_FUNC(cleaner_edd, eet_data_descriptor_free);
|
|
|
|
E_FREE_FUNC(cache_edd, eet_data_descriptor_free);
|
2013-06-17 08:06:43 -07:00
|
|
|
#ifdef HAVE_EMOTION
|
|
|
|
if (tw_tmpfd != -1)
|
|
|
|
{
|
|
|
|
close(tw_tmpfd);
|
|
|
|
tw_tmpfd = -1;
|
|
|
|
}
|
|
|
|
eina_stringshare_replace(&tw_tmpfile, NULL);
|
|
|
|
E_FREE_FUNC(tw_tmpthread, ecore_thread_cancel);
|
|
|
|
tw_tmpthread_media = NULL;
|
|
|
|
#endif
|
2013-06-14 07:36:11 -07:00
|
|
|
tw_hide(NULL);
|
|
|
|
last_coords.x = last_coords.y = 0;
|
|
|
|
eina_hash_free(tw_mod->media);
|
|
|
|
E_FREE_FUNC(tw_mod->pop, e_object_del);
|
|
|
|
}
|