}
EINTERN void
+e_comp_wl_client_surface_pending_frame_callback_add(E_Client *ec, struct wl_resource *callback_resource)
+{
+ ec->comp_data->pending.frames = eina_list_prepend(ec->comp_data->pending.frames, callback_resource);
+}
+
+EINTERN void
+e_comp_wl_client_surface_frame_callback_remove(E_Client *ec, struct wl_resource *callback_resource)
+{
+ E_Comp_Wl_Subsurf_Data *sdata;
+
+ if (!ec->comp_data)
+ return;
+
+ if (ec->comp_data->frames)
+ {
+ ec->comp_data->frames =
+ eina_list_remove(ec->comp_data->frames, callback_resource);
+ }
+
+ if (ec->comp_data->pending.frames)
+ {
+ ec->comp_data->pending.frames =
+ eina_list_remove(ec->comp_data->pending.frames, callback_resource);
+ }
+
+ sdata = ec->comp_data->sub.data;
+ if ((sdata) && (sdata->cached.frames))
+ {
+ sdata->cached.frames =
+ eina_list_remove(sdata->cached.frames, callback_resource);
+ }
+}
+
+EINTERN void
e_comp_wl_client_surface_pending_commit(E_Client *ec)
{
if (e_object_is_del(E_OBJECT(ec))) return;
EINTERN void e_comp_wl_client_surface_pending_buffer_set(E_Client *ec, E_Comp_Wl_Buffer *buffer, int32_t sx, int32_t sy);
EINTERN void e_comp_wl_client_surface_pending_opaque_region_set(E_Client *ec, Eina_Tiler *region);
EINTERN void e_comp_wl_client_surface_pending_input_region_set(E_Client *ec, Eina_Tiler *region);
+EINTERN void e_comp_wl_client_surface_pending_frame_callback_add(E_Client *ec, struct wl_resource *callback_resource);
+EINTERN void e_comp_wl_client_surface_frame_callback_remove(E_Client *ec, struct wl_resource *callback_resource);
EINTERN void e_comp_wl_client_surface_pending_commit(E_Client *ec);
EINTERN Eina_Bool e_comp_wl_client_subsurface_cyclic_reference_check(E_Client *ec, E_Client *parent);
typedef struct _E_Compositor E_Compositor;
typedef struct _E_Subsurface E_Subsurface;
typedef struct _E_Subsurface_View E_Subsurface_View;
+typedef struct _E_Frame_Callback E_Frame_Callback;
struct _E_Compositor
{
{
wl_callback_send_done(resource, (unsigned int)(ecore_loop_time_get() * 1000));
wl_resource_destroy(resource);
- surface->base.frames = eina_list_remove_list(surface->base.frames, l);
}
}
}
static void
+_frame_callback_cb_destroy(struct wl_listener *listener, void *data)
+{
+ struct wl_resource *resource = data;
+ E_Frame_Callback *frame_callback;
+
+ frame_callback = wl_container_of(listener, frame_callback, destroy);
+ e_comp_wl_client_surface_frame_callback_remove(frame_callback->ec, resource);
+ e_object_unref(E_OBJECT(frame_callback->ec));
+ free(frame_callback);
+}
+
+static void
_e_surface_pending_frame_callback_update(E_Surface *surface)
{
struct ds_surface *ds_surface = surface->ds_surface;
- struct wl_resource *resource, *tmp;
+ E_Client *ec = surface->ec;
+ E_Frame_Callback *frame_callback;
+ struct wl_resource *resource;
- wl_resource_for_each_safe(resource, tmp, &ds_surface->current.frame_callback_list)
+ wl_resource_for_each(resource, &ds_surface->current.frame_callback_list)
{
- wl_list_remove(wl_resource_get_link(resource));
- wl_list_init(wl_resource_get_link(resource));
- surface->base.pending.frames = eina_list_prepend(surface->base.pending.frames, resource);
+ frame_callback = E_NEW(E_Frame_Callback, 1);
+ if (!frame_callback)
+ continue;
+
+ e_object_ref(E_OBJECT(ec));
+ frame_callback->ec = ec;
+
+ frame_callback->destroy.notify = _frame_callback_cb_destroy;
+ wl_resource_add_destroy_listener(resource, &frame_callback->destroy);
+
+ e_comp_wl_client_surface_pending_frame_callback_add(ec, resource);
}
+
+ wl_list_init(&ds_surface->current.frame_callback_list);
}
static void