{
Evas_Cache_Target *tmp = im->targets;
- // FIXME: bug bug bug bug. hrrrm.
- // FIXME: this is a little bad if obj gets deleted before preload
- // async event comes in... boom!
evas_async_events_put(tmp->target, EVAS_CALLBACK_IMAGE_PRELOADED, NULL,
(void (*)(void*, Evas_Callback_Type, void*))evas_object_event_callback_call);
im->targets = (Evas_Cache_Target*) eina_inlist_remove(EINA_INLIST_GET(im->targets), EINA_INLIST_GET(im->targets));
if (running)
{
pthread_mutex_lock(&mutex);
+ if (target) evas_async_target_del(target);
if (ie->flags.preload)
{
if (current == ie)
else
{
Evas_Cache_Preload *l;
+
EINA_INLIST_FOREACH(preload, l)
{
if (l->ie == ie)
while (ie->targets)
{
tg = ie->targets;
+ evas_async_target_del(tg->target);
ie->targets = (Evas_Cache_Target*) eina_inlist_remove(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg));
free(tg);
}
static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
typedef struct _Evas_Event_Async Evas_Event_Async;
+
struct _Evas_Event_Async
{
const void *target;
Evas_Callback_Type type;
};
+static int queue_num = 0;
+static int queue_alloc = 0;
+static Evas_Event_Async *queue = NULL;
+
int
evas_async_events_init(void)
{
int filedes[2];
-
+
_init_evas_event++;
if (_init_evas_event > 1) return _init_evas_event;
-
+
if (pipe(filedes) == -1)
{
_init_evas_event = 0;
return 0;
}
-
+
_fd_read = filedes[0];
_fd_write = filedes[1];
-
+
fcntl(_fd_read, F_SETFL, O_NONBLOCK);
-
+
return _init_evas_event;
}
{
_init_evas_event--;
if (_init_evas_event > 0) return _init_evas_event;
-
+
close(_fd_read);
close(_fd_write);
_fd_read = -1;
return _init_evas_event;
}
+int
+evas_async_target_del(const void *target)
+{
+ int i, j, d = 0;
+
+ pthread_mutex_lock(&_mutex);
+ if (queue)
+ {
+ for (i = 0; i < queue_num; i++)
+ {
+ if (queue[i].target == target)
+ {
+ for (j = i + 1; j < queue_num; j++)
+ memcpy(&(queue[j - 1]), &(queue[j]), sizeof(Evas_Event_Async));
+ i--;
+ queue_num--;
+ d++;
+ }
+ }
+ if (queue_num == 0)
+ {
+ free(queue);
+ queue = NULL;
+ queue_alloc = 0;
+ }
+ }
+ pthread_mutex_unlock(&_mutex);
+ return d;
+}
+
#endif
/**
evas_async_events_process(void)
{
#ifdef BUILD_ASYNC_EVENTS
- static Evas_Event_Async current;
- static int size = 0;
+ Evas_Event_Async *ev;
+ unsigned char buf[1];
+ int i;
int check;
int count = 0;
-
+
if (_fd_read == -1) return 0;
-
+
+ pthread_mutex_lock(&_mutex);
do
{
- check = read(_fd_read, ((char*) ¤t) + size, sizeof(current) - size);
-
- if (check > 0)
- {
- size += check;
- if (size == sizeof(current))
- {
- if (current.func) current.func((void*) current.target, current.type, current.event_info);
- size = 0;
- count++;
- }
- }
+ check = read(_fd_read, buf, 1);
}
while (check > 0);
-
+
+ if (queue)
+ {
+ for (i = 0; i < queue_num; i++)
+ {
+ ev = &(queue[i]);
+ if (ev->func) ev->func((void *)ev->target, ev->type, ev->event_info);
+ count++;
+ }
+ free(queue);
+ queue = NULL;
+ queue_num = 0;
+ queue_alloc = 0;
+ }
+ pthread_mutex_unlock(&_mutex);
+
if (check < 0)
switch (errno)
{
- case EBADF:
- case EINVAL:
- case EIO:
- case EISDIR:
- _fd_read = -1;
+ case EBADF:
+ case EINVAL:
+ case EIO:
+ case EISDIR:
+ _fd_read = -1;
}
-
+
evas_cache_pending_process();
return count;
#else
}
/**
- * Insert asynchronous events on the canvas.
+* Insert asynchronous events on the canvas.
*
* @param target The target to be affected by the events.
* @param type The type of callback function.
evas_async_events_put(const void *target, Evas_Callback_Type type, void *event_info, void (*func)(void *target, Evas_Callback_Type type, void *event_info))
{
#ifdef BUILD_ASYNC_EVENTS
- Evas_Event_Async new;
+ Evas_Event_Async *ev;
ssize_t check;
- int offset = 0;
Eina_Bool result = EINA_FALSE;
if (!func) return 0;
if (_fd_write == -1) return 0;
- memset(&new, 0, sizeof (new));
-
- new.func = func;
- new.target = target;
- new.type = type;
- new.event_info = event_info;
-
pthread_mutex_lock(&_mutex);
+
+ queue_num++;
+ if (queue_num > queue_alloc)
+ {
+ Evas_Event_Async *q2;
+
+ queue_alloc += 32; // 32 slots at a time for async events
+ q2 = realloc(queue, queue_alloc * sizeof(Evas_Event_Async));
+ if (!q2)
+ {
+ queue_alloc -= 32;
+ queue_num--;
+ return 0;
+ }
+ queue = q2;
+ }
+ ev = &(queue[queue_num - 1]);
+ memset(ev, 0, sizeof(Evas_Event_Async));
+ ev->func = func;
+ ev->target = target;
+ ev->type = type;
+ ev->event_info = event_info;
- do {
- check = write(_fd_write, ((char*)&new) + offset, sizeof(new) - offset);
- offset += check;
- } while (offset != sizeof(new) && (errno == EINTR || errno == EAGAIN));
+ do
+ {
+ unsigned char buf[1] = { 0xf0 };
+ check = write(_fd_write, buf, 1);
+ } while ((check != 1) && ((errno == EINTR) || (errno == EAGAIN)));
- if (offset == sizeof(new))
+ if (check == 1)
result = EINA_TRUE;
else
switch (errno)
{
- case EBADF:
- case EINVAL:
- case EIO:
- case EPIPE:
- _fd_write = -1;
+ case EBADF:
+ case EINVAL:
+ case EIO:
+ case EPIPE:
+ _fd_write = -1;
}
-
+
pthread_mutex_unlock(&_mutex);
-
return result;
#else
func(target, type, event_info);
-
return EINA_TRUE;
#endif
}
o->prev.file = NULL;
o->prev.key = NULL;
if (o->engine_data)
- obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
- o->engine_data);
+ {
+ obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
+ o->engine_data,
+ obj);
+ obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
+ o->engine_data);
+ }
o->load_error = EVAS_LOAD_ERROR_NONE;
lo.scale_down_by = o->load_opts.scale_down_by;
lo.dpi = o->load_opts.dpi;
}
EAPI void
-evas_object_image_fill_transform_set (Evas_Object *obj, Evas_Transform *t)
+evas_object_image_fill_transform_set(Evas_Object *obj, Evas_Transform *t)
{
Evas_Object_Image *o;
/*FIXME: To be documented*/
EAPI void
-evas_object_image_fill_transform_get (const Evas_Object *obj, Evas_Transform *t)
+evas_object_image_fill_transform_get(const Evas_Object *obj, Evas_Transform *t)
{
Evas_Object_Image *o;
if (o->cur.file) eina_stringshare_del(o->cur.file);
if (o->cur.key) eina_stringshare_del(o->cur.key);
if (o->engine_data)
- obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
- o->engine_data);
+ {
+ obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
+ o->engine_data,
+ obj);
+ obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
+ o->engine_data);
+ }
o->engine_data = NULL;
o->magic = 0;
EINA_LIST_FREE(o->pixel_updates, r)