summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2015-02-25 13:14:30 -0500
committerChris Michael <cp.michael@samsung.com>2015-02-25 13:20:00 -0500
commitada31f3bfacb8816997b680b62de28dbbb03827c (patch)
tree2bb2b451358e6eb64ad4a135170e30b3f25f3c89
parent3fd618ffaa6583fe5323ae709e4baa595f069d24 (diff)
downloadenlightenment-ada31f3bfacb8816997b680b62de28dbbb03827c.tar.gz
start work on fixing resize issue
Signed-off-by: Chris Michael <cp.michael@samsung.com>
-rw-r--r--src/bin/e_comp_wl.c977
-rw-r--r--src/bin/e_pixmap.c243
2 files changed, 511 insertions, 709 deletions
diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index c0605d8804..4dccdc22bb 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -654,7 +654,27 @@ _e_comp_wl_evas_cb_color_set(void *data, Evas_Object *obj, void *event EINA_UNUS
ec->netwm.opacity_changed = EINA_TRUE;
}
-static void
+static void
+_e_comp_wl_buffer_reference_cb_destroy(struct wl_listener *listener, void *data)
+{
+ E_Comp_Wl_Buffer_Ref *ref;
+
+ ref = container_of(listener, E_Comp_Wl_Buffer_Ref, destroy_listener);
+ if ((E_Comp_Wl_Buffer *)data != ref->buffer) return;
+ ref->buffer = NULL;
+}
+
+static void
+_e_comp_wl_buffer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
+{
+ E_Comp_Wl_Buffer *buffer;
+
+ buffer = container_of(listener, E_Comp_Wl_Buffer, destroy_listener);
+ wl_signal_emit(&buffer->destroy_signal, buffer);
+ free(buffer);
+}
+
+static void
_e_comp_wl_client_evas_init(E_Client *ec)
{
if (ec->comp_data->evas_init) return;
@@ -888,102 +908,299 @@ _e_comp_wl_cb_input_event(void *data EINA_UNUSED, int type, void *ev)
return ECORE_CALLBACK_RENEW;
}
-static void
-_e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
+static void
+_e_comp_wl_surface_state_size_update(E_Client *ec, E_Comp_Wl_Surface_State *state)
{
- E_Pixmap *ep;
+ int w = 0, h = 0;
+ double scale = 0.0;
- DBG("Surface Cb Destroy: %d", wl_resource_get_id(resource));
+ if (!ec->comp_data->buffer_ref.buffer)
+ {
+ state->bw = 0;
+ state->bh = 0;
+ return;
+ }
- /* unset the pixmap resource */
- if ((ep = wl_resource_get_user_data(resource)))
- e_pixmap_resource_set(ep, NULL);
+ scale = e_comp->wl_comp_data->output.scale;
+ switch (e_comp->wl_comp_data->output.transform)
+ {
+ case WL_OUTPUT_TRANSFORM_90:
+ case WL_OUTPUT_TRANSFORM_270:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ w = ec->comp_data->buffer_ref.buffer->h / scale;
+ h = ec->comp_data->buffer_ref.buffer->w / scale;
+ break;
+ default:
+ w = ec->comp_data->buffer_ref.buffer->w / scale;
+ h = ec->comp_data->buffer_ref.buffer->h / scale;
+ break;
+ }
- /* destroy this resource */
- wl_resource_destroy(resource);
+ state->bw = w;
+ state->bh = h;
}
-static void
-_e_comp_wl_surface_cb_attach(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
+static void
+_e_comp_wl_surface_state_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
{
- E_Pixmap *ep;
- E_Client *ec;
+ E_Comp_Wl_Surface_State *state;
- /* get the e_pixmap reference */
- if (!(ep = wl_resource_get_user_data(resource))) return;
+ state =
+ container_of(listener, E_Comp_Wl_Surface_State, buffer_destroy_listener);
+ state->buffer = NULL;
+}
- /* try to find the associated e_client */
- if (!(ec = e_pixmap_client_get(ep)))
+static void
+_e_comp_wl_surface_state_init(E_Comp_Wl_Surface_State *state, int w, int h)
+{
+ state->new_attach = EINA_FALSE;
+ state->buffer = NULL;
+ state->buffer_destroy_listener.notify =
+ _e_comp_wl_surface_state_cb_buffer_destroy;
+ state->sx = state->sy = 0;
+
+ state->input = eina_tiler_new(w, h);
+ eina_tiler_tile_size_set(state->input, 1, 1);
+
+ state->opaque = eina_tiler_new(w, h);
+ eina_tiler_tile_size_set(state->opaque, 1, 1);
+}
+
+static void
+_e_comp_wl_surface_state_finish(E_Comp_Wl_Surface_State *state)
+{
+ struct wl_resource *cb;
+ Eina_Rectangle *dmg;
+
+ EINA_LIST_FREE(state->frames, cb)
+ wl_resource_destroy(cb);
+
+ EINA_LIST_FREE(state->damages, dmg)
+ eina_rectangle_free(dmg);
+
+ if (state->opaque) eina_tiler_free(state->opaque);
+ state->opaque = NULL;
+
+ if (state->input) eina_tiler_free(state->input);
+ state->input = NULL;
+
+ if (state->buffer) wl_list_remove(&state->buffer_destroy_listener.link);
+ state->buffer = NULL;
+}
+
+static void
+_e_comp_wl_surface_state_buffer_set(E_Comp_Wl_Surface_State *state, E_Comp_Wl_Buffer *buffer)
+{
+ if (state->buffer == buffer) return;
+ if (state->buffer)
+ wl_list_remove(&state->buffer_destroy_listener.link);
+ state->buffer = buffer;
+ if (state->buffer)
+ wl_signal_add(&state->buffer->destroy_signal,
+ &state->buffer_destroy_listener);
+}
+
+static void
+_e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
+{
+ Eina_Bool first = EINA_FALSE;
+ Eina_Rectangle *dmg;
+ Eina_List *l;
+ struct wl_resource *cb;
+
+ first = !e_pixmap_usable_get(ec->pixmap);
+
+ if (state->new_attach)
+ e_comp_wl_surface_attach(ec, state->buffer);
+
+ _e_comp_wl_surface_state_buffer_set(state, NULL);
+
+ if (!e_pixmap_usable_get(ec->pixmap))
{
- ERR("\t\tCould not find client from pixmap %p", ep);
- return;
+ if (ec->comp_data->mapped)
+ {
+ if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap))
+ ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
+ else
+ {
+ evas_object_hide(ec->frame);
+ ec->comp_data->mapped = evas_object_visible_get(ec->frame);
+ }
+ }
+ }
+ else
+ {
+ if (!ec->comp_data->mapped)
+ {
+ if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.map))
+ ec->comp_data->shell.map(ec->comp_data->shell.surface);
+ else
+ {
+ evas_object_show(ec->frame);
+ ec->comp_data->mapped = evas_object_visible_get(ec->frame);
+ }
+ }
}
- /* check if client is being deleted */
- if (e_object_is_del(E_OBJECT(ec)))
+ if (state->new_attach)
{
- DBG("\tE_Client scheduled for deletion");
- return;
+ Eina_Bool placed = EINA_TRUE;
+ int x = 0, y = 0;
+
+ _e_comp_wl_surface_state_size_update(ec, &ec->comp_data->pending);
+
+ if (ec->changes.pos)
+ e_comp_object_frame_xy_adjust(ec->frame, ec->x, ec->y, &x, &y);
+ else
+ x = ec->client.x, y = ec->client.y;
+
+ if (ec->new_client) placed = ec->placed;
+
+ if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.configure))
+ ec->comp_data->shell.configure(ec->comp_data->shell.surface,
+ x, y, state->bw, state->bh);
+ else
+ e_client_util_move_resize_without_frame(ec, x, y, state->bw, state->bh);
+
+ if (ec->new_client)
+ ec->placed = placed;
+ else if ((first) && (ec->placed))
+ {
+ ec->x = ec->y = 0;
+ ec->placed = EINA_FALSE;
+ ec->new_client = EINA_TRUE;
+ }
}
- /* check for valid comp_data */
- if (!ec->comp_data)
+ state->sx = 0;
+ state->sy = 0;
+ state->new_attach = EINA_FALSE;
+
+ if (!ec->comp_data->mapped) goto unmapped;
+
+ /* put state damages into surface */
+ if ((!ec->comp->nocomp) && (ec->frame))
{
- ERR("\tE_Client has no comp data");
- return;
+ EINA_LIST_FREE(state->damages, dmg)
+ {
+ e_comp_object_damage(ec->frame, dmg->x, dmg->y, dmg->w, dmg->h);
+ eina_rectangle_free(dmg);
+ }
}
- /* DBG("Surface Attach: %d", wl_resource_get_id(resource)); */
+ /* put state opaque into surface */
+ if (state->opaque)
+ {
+ Eina_Rectangle *rect;
+ Eina_Iterator *itr;
- /* reset client pending information */
- ec->comp_data->pending.x = sx;
- ec->comp_data->pending.y = sy;
- ec->comp_data->pending.w = 0;
- ec->comp_data->pending.h = 0;
- ec->comp_data->pending.buffer = buffer_resource;
- ec->comp_data->pending.new_attach = EINA_TRUE;
+ itr = eina_tiler_iterator_new(state->opaque);
+ EINA_ITERATOR_FOREACH(itr, rect)
+ {
+ e_pixmap_image_opaque_set(ec->pixmap, rect->x, rect->y,
+ rect->w, rect->h);
+ break;
+ }
- if (buffer_resource)
+ eina_iterator_free(itr);
+ }
+ else
+ e_pixmap_image_opaque_set(ec->pixmap, 0, 0, 0, 0);
+
+ /* put state input into surface */
+ if (state->input)
{
- struct wl_shm_buffer *shmb;
+ Eina_Tiler *src, *tmp;
- /* check for this resource being a shm buffer */
- if ((shmb = wl_shm_buffer_get(buffer_resource)))
+ tmp = eina_tiler_new(state->bw, state->bh);
+ eina_tiler_tile_size_set(tmp, 1, 1);
+ eina_tiler_rect_add(tmp,
+ &(Eina_Rectangle){0, 0, state->bw, state->bh});
+ if ((src = eina_tiler_intersection(state->input, tmp)))
{
- /* update pending size */
- ec->comp_data->pending.w = wl_shm_buffer_get_width(shmb);
- ec->comp_data->pending.h = wl_shm_buffer_get_height(shmb);
+ Eina_Rectangle *rect;
+ Eina_Iterator *itr;
+
+ itr = eina_tiler_iterator_new(src);
+ EINA_ITERATOR_FOREACH(itr, rect)
+ e_comp_object_input_area_set(ec->frame, rect->x, rect->y,
+ rect->w, rect->h);
+
+ eina_iterator_free(itr);
+ eina_tiler_free(src);
}
+ else
+ e_comp_object_input_area_set(ec->frame, 0, 0, ec->w, ec->h);
+
+ eina_tiler_free(tmp);
}
+
+ /* insert state frame callbacks into comp_data->frames
+ * NB: This clears state->frames list */
+ EINA_LIST_FOREACH(state->frames, l, cb)
+ eina_list_move(&ec->comp_data->frames, &state->frames, cb);
+
+ return;
+
+unmapped:
+ /* clear pending damages */
+ EINA_LIST_FREE(state->damages, dmg)
+ eina_rectangle_free(dmg);
+
+ /* clear input tiler */
+ if (state->input)
+ eina_tiler_clear(state->input);
}
-static void
-_e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h)
+static void
+_e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
+{
+ DBG("Surface Cb Destroy: %d", wl_resource_get_id(resource));
+ wl_resource_destroy(resource);
+}
+
+static void
+_e_comp_wl_surface_cb_attach(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
{
E_Pixmap *ep;
E_Client *ec;
- Eina_Rectangle *dmg = NULL;
+ E_Comp_Wl_Buffer *buffer = NULL;
- /* get the e_pixmap reference */
if (!(ep = wl_resource_get_user_data(resource))) return;
+ if (!(ec = e_pixmap_client_get(ep))) return;
+ if (e_object_is_del(E_OBJECT(ec))) return;
- /* try to find the associated e_client */
- if (!(ec = e_pixmap_client_get(ep)))
+ if (buffer_resource)
{
- ERR("\tCould not find client from pixmap %p", ep);
- return;
+ if (!(buffer = e_comp_wl_buffer_get(buffer_resource)))
+ {
+ ERR("Could not get buffer from resource");
+ wl_client_post_no_memory(client);
+ return;
+ }
}
- if (e_object_is_del(E_OBJECT(ec))) return;
- if (!ec->comp_data) return;
+ _e_comp_wl_surface_state_buffer_set(&ec->comp_data->pending, buffer);
- /* DBG("Surface Cb Damage: %d", wl_resource_get_id(resource)); */
- /* DBG("\tGeom: %d %d %d %d", x, y, w, h); */
+ ec->comp_data->pending.sx = sx;
+ ec->comp_data->pending.sy = sy;
+ ec->comp_data->pending.new_attach = EINA_TRUE;
+}
+
+static void
+_e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h)
+{
+ E_Pixmap *ep;
+ E_Client *ec;
+ Eina_Rectangle *dmg = NULL;
+
+ if (!(ep = wl_resource_get_user_data(resource))) return;
+ if (!(ec = e_pixmap_client_get(ep))) return;
+ if (e_object_is_del(E_OBJECT(ec))) return;
- /* create new damage rectangle */
if (!(dmg = eina_rectangle_new(x, y, w, h))) return;
- /* add damage rectangle to list of pending damages */
ec->comp_data->pending.damages =
eina_list_append(ec->comp_data->pending.damages, dmg);
}
@@ -994,11 +1211,10 @@ _e_comp_wl_frame_cb_destroy(struct wl_resource *resource)
E_Client *ec;
if (!(ec = wl_resource_get_user_data(resource))) return;
-
if (e_object_is_del(E_OBJECT(ec))) return;
- /* remove this frame callback */
- ec->comp_data->frames = eina_list_remove(ec->comp_data->frames, resource);
+ ec->comp_data->frames =
+ eina_list_remove(ec->comp_data->frames, resource);
}
static void
@@ -1009,14 +1225,7 @@ _e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resour
struct wl_resource *res;
if (!(ep = wl_resource_get_user_data(resource))) return;
-
- /* try to find the associated e_client */
- if (!(ec = e_pixmap_client_get(ep)))
- {
- ERR("\tCould not find client from pixmap %p", ep);
- return;
- }
-
+ if (!(ec = e_pixmap_client_get(ep))) return;
if (e_object_is_del(E_OBJECT(ec))) return;
/* create frame callback */
@@ -1029,8 +1238,8 @@ _e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resour
wl_resource_set_implementation(res, NULL, ec, _e_comp_wl_frame_cb_destroy);
- /* append this frame callback to the client list */
- ec->comp_data->frames = eina_list_append(ec->comp_data->frames, res);
+ ec->comp_data->pending.frames =
+ eina_list_prepend(ec->comp_data->pending.frames, res);
}
static void
@@ -1039,40 +1248,27 @@ _e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, st
E_Pixmap *ep;
E_Client *ec;
- /* get the e_pixmap reference */
if (!(ep = wl_resource_get_user_data(resource))) return;
-
- /* try to find the associated e_client */
- if (!(ec = e_pixmap_client_get(ep)))
- {
- ERR("\tCould not find client from pixmap %p", ep);
- return;
- }
-
- /* trap for clients which are being deleted */
+ if (!(ec = e_pixmap_client_get(ep))) return;
if (e_object_is_del(E_OBJECT(ec))) return;
if (region_resource)
{
Eina_Tiler *tmp;
- Eina_Iterator *it;
- Eina_Rectangle *rect;
- /* try to get the tiler from the region resource */
if (!(tmp = wl_resource_get_user_data(region_resource)))
return;
- it = eina_tiler_iterator_new(tmp);
- EINA_ITERATOR_FOREACH(it, rect)
+ eina_tiler_union(ec->comp_data->pending.opaque, tmp);
+ }
+ else
+ {
+ if (ec->comp_data->pending.opaque)
{
- e_pixmap_image_opaque_set(ec->pixmap, rect->x, rect->y, rect->w, rect->h);
- break;
+ eina_tiler_clear(ec->comp_data->pending.opaque);
+ /* eina_tiler_free(ec->comp_data->pending.opaque); */
}
-
- eina_iterator_free(it);
}
- else
- e_pixmap_image_opaque_set(ec->pixmap, 0, 0, 0, 0);
}
static void
@@ -1081,25 +1277,14 @@ _e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, str
E_Pixmap *ep;
E_Client *ec;
- /* get the e_pixmap reference */
if (!(ep = wl_resource_get_user_data(resource))) return;
-
- /* try to find the associated e_client */
- if (!(ec = e_pixmap_client_get(ep)))
- {
- ERR("\tCould not find client from pixmap %p", ep);
- return;
- }
-
- /* trap for clients which are being deleted */
+ if (!(ec = e_pixmap_client_get(ep))) return;
if (e_object_is_del(E_OBJECT(ec))) return;
- eina_tiler_clear(ec->comp_data->pending.input);
if (region_resource)
{
Eina_Tiler *tmp;
- /* try to get the tiler from the region resource */
if (!(tmp = wl_resource_get_user_data(region_resource)))
return;
@@ -1116,38 +1301,15 @@ static void
_e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
{
E_Pixmap *ep;
- E_Client *ec, *subc;
- Eina_List *l;
+ E_Client *ec;
- /* get the e_pixmap reference */
if (!(ep = wl_resource_get_user_data(resource))) return;
-
- /* try to find the associated e_client */
- if (!(ec = e_pixmap_client_get(ep)))
- {
- ERR("\tCould not find client from pixmap %p", ep);
- return;
- }
-
- /* trap for clients which are being deleted */
+ if (!(ec = e_pixmap_client_get(ep))) return;
if (e_object_is_del(E_OBJECT(ec))) return;
- /* DBG("Surface Commit: %d", wl_resource_get_id(resource)); */
+ e_comp_wl_surface_commit(ec);
- /* call the subsurface commit function
- *
- * NB: Returns true on success */
- if (e_comp_wl_subsurface_commit(ec)) return;
-
- /* handle actual surface commit */
- if (!e_comp_wl_surface_commit(ec))
- ERR("Failed to commit surface: %d", wl_resource_get_id(resource));
-
- EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
- {
- if (ec != subc)
- _e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
- }
+ /* TODO: subsurface parent commit ? */
}
static void
@@ -1607,172 +1769,83 @@ _e_comp_wl_subsurface_commit_from_cache(E_Client *ec)
i++;
}
}
+=======
+>>>>>>> start work on fixing resize issue
- eina_iterator_free(itr);
- eina_tiler_free(src);
- }
+ wl_resource_set_implementation(res, &_e_comp_interface, comp, NULL);
+}
- eina_tiler_free(tmp);
- eina_tiler_clear(sdata->cached.input);
- }
+static void
+_e_comp_wl_compositor_cb_del(E_Comp *comp)
+{
+ E_Comp_Data *cdata;
- return;
+ /* get existing compositor data */
+ if (!(cdata = comp->wl_comp_data)) return;
-unmap:
+ /* delete fd handler */
+ if (cdata->fd_hdlr) ecore_main_fd_handler_del(cdata->fd_hdlr);
- /* surface is not visible, clear damages */
- EINA_LIST_FREE(sdata->cached.damages, dmg)
- eina_rectangle_free(dmg);
+ eina_list_free(cdata->output.resources);
- /* clear pending input regions */
- if (sdata->cached.input)
- eina_tiler_clear(sdata->cached.input);
+ /* free allocated data structure */
+ free(cdata);
}
-static void
-_e_comp_wl_subsurface_parent_commit(E_Client *ec, Eina_Bool parent_synchronized)
+static void
+_e_comp_wl_subsurface_destroy(struct wl_resource *resource)
{
- E_Client *parent;
- E_Comp_Wl_Subsurf_Data *sdata;
-
- if (!(sdata = ec->comp_data->sub.data)) return;
- if (!(parent = sdata->parent)) return;
+}
- if (sdata->position.set)
- {
- evas_object_move(ec->frame, parent->x + sdata->position.x,
- parent->y + sdata->position.y);
- sdata->position.set = EINA_FALSE;
- }
+static Eina_Bool
+_e_comp_wl_subsurface_synchronized_get(E_Comp_Wl_Subsurf_Data *sdata)
+{
+ return EINA_FALSE;
+}
- if ((parent_synchronized) || (sdata->synchronized))
- {
- E_Client *subc;
- Eina_List *l;
+static void
+_e_comp_wl_subsurface_commit_to_cache(E_Client *ec)
+{
+}
- if (sdata->cached.has_data)
- _e_comp_wl_subsurface_commit_from_cache(ec);
+static void
+_e_comp_wl_subsurface_commit_from_cache(E_Client *ec)
+{
+}
- EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
- {
- if (ec != subc)
- _e_comp_wl_subsurface_parent_commit(subc, EINA_TRUE);
- }
- }
+static void
+_e_comp_wl_subsurface_parent_commit(E_Client *ec, Eina_Bool parent_synchronized)
+{
}
static void
_e_comp_wl_subsurface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
{
- wl_resource_destroy(resource);
}
static void
_e_comp_wl_subsurface_cb_position_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y)
{
- E_Client *ec;
- E_Comp_Wl_Subsurf_Data *sdata;
-
- DBG("Subsurface Cb Position Set: %d", wl_resource_get_id(resource));
-
- /* try to get the client from resource data */
- if (!(ec = wl_resource_get_user_data(resource))) return;
-
- if (!(sdata = ec->comp_data->sub.data)) return;
-
- sdata->position.x = x;
- sdata->position.y = y;
- sdata->position.set = EINA_TRUE;
}
static void
_e_comp_wl_subsurface_cb_place_above(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *sibling_resource)
{
- E_Client *ec, *ecs;
- E_Client *parent;
-
- DBG("Subsurface Cb Place Above: %d", wl_resource_get_id(resource));
-
- /* try to get the client from resource data */
- if (!(ec = wl_resource_get_user_data(resource))) return;
-
- if (!ec->comp_data->sub.data) return;
-
- /* try to get the client from the sibling resource */
- if (!(ecs = wl_resource_get_user_data(sibling_resource))) return;
-
- if (!ecs->comp_data->sub.data) return;
-
- if (!(parent = ec->comp_data->sub.data->parent)) return;
-
- parent->comp_data->sub.list =
- eina_list_remove(parent->comp_data->sub.list, ec);
-
- parent->comp_data->sub.list =
- eina_list_append_relative(parent->comp_data->sub.list, ec, ecs);
-
- parent->comp_data->sub.restack_target = parent;
}
static void
_e_comp_wl_subsurface_cb_place_below(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *sibling_resource)
{
- E_Client *ec, *ecs;
- E_Client *parent;
-
- DBG("Subsurface Cb Place Below: %d", wl_resource_get_id(resource));
-
- /* try to get the client from resource data */
- if (!(ec = wl_resource_get_user_data(resource))) return;
-
- if (!ec->comp_data->sub.data) return;
-
- /* try to get the client from the sibling resource */
- if (!(ecs = wl_resource_get_user_data(sibling_resource))) return;
-
- if (!ecs->comp_data->sub.data) return;
-
- if (!(parent = ec->comp_data->sub.data->parent)) return;
-
- parent->comp_data->sub.list =
- eina_list_remove(parent->comp_data->sub.list, ec);
-
- parent->comp_data->sub.list =
- eina_list_prepend_relative(parent->comp_data->sub.list, ec, ecs);
-
- parent->comp_data->sub.restack_target = parent;
}
static void
_e_comp_wl_subsurface_cb_sync_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
{
- E_Client *ec;
- E_Comp_Wl_Subsurf_Data *sdata;
-
- DBG("Subsurface Cb Sync Set: %d", wl_resource_get_id(resource));
-
- /* try to get the client from resource data */
- if (!(ec = wl_resource_get_user_data(resource))) return;
-
- if (!(sdata = ec->comp_data->sub.data)) return;
-
- sdata->synchronized = EINA_TRUE;
}
static void
_e_comp_wl_subsurface_cb_desync_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
{
- E_Client *ec;
- E_Comp_Wl_Subsurf_Data *sdata;
-
- DBG("Subsurface Cb Desync Set: %d", wl_resource_get_id(resource));
-
- /* try to get the client from resource data */
- if (!(ec = wl_resource_get_user_data(resource))) return;
-
- if (!(sdata = ec->comp_data->sub.data)) return;
-
- sdata->synchronized = EINA_FALSE;
}
static const struct wl_subsurface_interface _e_subsurface_interface =
@@ -1788,165 +1861,16 @@ static const struct wl_subsurface_interface _e_subsurface_interface =
static Eina_Bool
_e_comp_wl_subsurface_create(E_Client *ec, E_Client *epc, uint32_t id, struct wl_resource *surface_resource)
{
- struct wl_client *client;
- struct wl_resource *res;
- E_Comp_Wl_Subsurf_Data *sdata;
-
- /* try to get the wayland client from the surface resource */
- if (!(client = wl_resource_get_client(surface_resource)))
- {
- ERR("Could not get client from resource %d",
- wl_resource_get_id(surface_resource));
- return EINA_FALSE;
- }
-
- /* try to allocate subsurface data */
- if (!(sdata = E_NEW(E_Comp_Wl_Subsurf_Data, 1)))
- {
- ERR("Could not allocate space for subsurface data");
- goto dat_err;
- }
-
- /* try to create the subsurface resource */
- if (!(res = wl_resource_create(client, &wl_subsurface_interface, 1, id)))
- {
- ERR("Failed to create subsurface resource");
- wl_resource_post_no_memory(surface_resource);
- goto res_err;
- }
-
- /* set resource implementation */
- wl_resource_set_implementation(res, &_e_subsurface_interface, ec,
- _e_comp_wl_subsurface_destroy);
-
- /* set subsurface data properties */
- sdata->resource = res;
- sdata->synchronized = EINA_TRUE;
- sdata->parent = epc;
-
- /* create subsurface tilers */
- sdata->cached.input = eina_tiler_new(ec->w, ec->h);
- eina_tiler_tile_size_set(sdata->cached.input, 1, 1);
-
- /* set subsurface client properties */
- ec->borderless = EINA_TRUE;
- ec->argb = EINA_TRUE;
- ec->lock_border = EINA_TRUE;
- ec->lock_focus_in = ec->lock_focus_out = EINA_TRUE;
- ec->netwm.state.skip_taskbar = EINA_TRUE;
- ec->netwm.state.skip_pager = EINA_TRUE;
-
- if (epc)
- {
- if (epc->comp_data)
- {
- /* append this client to the parents subsurface list */
- epc->comp_data->sub.list =
- eina_list_append(epc->comp_data->sub.list, ec);
- }
-
- /* TODO: add callbacks ?? */
- }
-
- ec->comp_data->surface = surface_resource;
- ec->comp_data->sub.data = sdata;
-
- return EINA_TRUE;
-
-res_err:
- free(sdata);
-dat_err:
- return EINA_FALSE;
}
static void
_e_comp_wl_subcompositor_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
{
- wl_resource_destroy(resource);
-
- /* TODO: destroy iconify/uniconify handlers */
}
static void
_e_comp_wl_subcompositor_cb_subsurface_get(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource, struct wl_resource *parent_resource)
{
- E_Pixmap *ep, *epp;
- E_Client *ec, *epc = NULL;
- static const char where[] = "get_subsurface: wl_subsurface@";
-
- DBG("Subcompositor Create Subsurface for Surface: %d",
- wl_resource_get_id(surface_resource));
-
- /* try to get the surface pixmap */
- if (!(ep = wl_resource_get_user_data(surface_resource)))
- {
- wl_resource_post_error(resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
- "%s%d: wl_surface@%d is invalid.", where, id,
- wl_resource_get_id(surface_resource));
- return;
- }
-
- /* try to get the parent pixmap */
- if (!(epp = wl_resource_get_user_data(parent_resource)))
- {
- wl_resource_post_error(resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
- "%s%d: wl_surface@%d is invalid.", where, id,
- wl_resource_get_id(parent_resource));
- return;
- }
-
- if (ep == epp)
- {
- wl_resource_post_error(resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
- "%s%d: wl_surface@%d cannot be its own parent",
- where, id, wl_resource_get_id(surface_resource));
- return;
- }
-
- /* try to find the associated e_client */
- if (!(ec = e_pixmap_client_get(ep)))
- ERR("\tCould not find client from pixmap %p", ep);
-
- if (!ec)
- {
- /* no client exists for this pixmap yet */
- if (!(ec = e_client_new(NULL, ep, 0, 0)))
- {
- ERR("Failed to create new client");
- wl_resource_post_no_memory(resource);
- return;
- }
-
- if (ec->comp_data)
- ec->comp_data->surface = surface_resource;
- }
- else
- {
- /* trap for clients which are being deleted */
- if (e_object_is_del(E_OBJECT(ec))) return;
- }
-
- /* try to find the parents associated e_client */
- if (!(epc = e_pixmap_client_get(epp)))
- ERR("\tCould not find client from pixmap %p", epp);
-
- /* trap for clients which are being deleted */
- if ((epc) && (e_object_is_del(E_OBJECT(epc)))) return;
-
- /* check if this surface is already a sub-surface */
- if ((ec->comp_data) && (ec->comp_data->sub.data))
- {
- wl_resource_post_error(resource,
- WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
- "%s%d: wl_surface@%d is already a sub-surface",
- where, id, wl_resource_get_id(surface_resource));
- return;
- }
-
- /* try to create a new subsurface */
- if (!_e_comp_wl_subsurface_create(ec, epc, id, surface_resource))
- ERR("Failed to create subsurface for surface %d",
- wl_resource_get_id(surface_resource));
}
static const struct wl_subcompositor_interface _e_subcomp_interface =
@@ -2002,9 +1926,9 @@ _e_comp_wl_client_cb_new(void *data EINA_UNUSED, E_Client *ec)
return;
}
- /* create client tilers */
- ec->comp_data->pending.input = eina_tiler_new(ec->w, ec->h);
- eina_tiler_tile_size_set(ec->comp_data->pending.input, 1, 1);
+ wl_signal_init(&ec->comp_data->destroy_signal);
+
+ _e_comp_wl_surface_state_init(&ec->comp_data->pending, ec->w, ec->h);
/* set initial client properties */
ec->argb = EINA_TRUE;
@@ -2032,28 +1956,18 @@ _e_comp_wl_client_cb_new(void *data EINA_UNUSED, E_Client *ec)
static void
_e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
{
- /* uint64_t win; */
- Eina_Rectangle *dmg;
+ /* Eina_Rectangle *dmg; */
+ struct wl_resource *cb;
/* make sure this is a wayland client */
E_COMP_WL_PIXMAP_CHECK;
- /* get window id from pixmap */
- /* win = e_pixmap_window_get(ec->pixmap); */
- /* eina_hash_del_by_key(clients_win_hash, &win); */
-
if ((!ec->already_unparented) && (ec->comp_data->reparented))
_e_comp_wl_focus_down_set(ec);
ec->already_unparented = EINA_TRUE;
if (ec->comp_data->reparented)
{
- /* get the parent window */
- /* win = e_client_util_pwin_get(ec); */
-
- /* remove the parent from the hash */
- /* eina_hash_del_by_key(clients_win_hash, &win); */
-
/* reset pixmap parent window */
e_pixmap_parent_window_set(ec->pixmap, 0);
}
@@ -2064,16 +1978,23 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
ec->parent->modal = NULL;
}
- /* the client is getting deleted, which means the pixmap will be getting
- * freed. We need to unset the surface user data */
- if (ec->comp_data->surface)
- wl_resource_set_user_data(ec->comp_data->surface, NULL);
+ wl_signal_emit(&ec->comp_data->destroy_signal, &ec->comp_data->surface);
- EINA_LIST_FREE(ec->comp_data->pending.damages, dmg)
- eina_rectangle_free(dmg);
+ _e_comp_wl_surface_state_finish(&ec->comp_data->pending);
+
+ e_comp_wl_buffer_reference(&ec->comp_data->buffer_ref, NULL);
+
+ /* EINA_LIST_FREE(ec->comp_data->damages, dmg) */
+ /* eina_rectangle_free(dmg); */
+
+ /* if (ec->comp_data->opaque) eina_tiler_free(ec->comp_data->opaque); */
+ /* if (ec->comp_data->input) eina_tiler_free(ec->comp_data->input); */
- if (ec->comp_data->pending.input)
- eina_tiler_free(ec->comp_data->pending.input);
+ EINA_LIST_FREE(ec->comp_data->frames, cb)
+ wl_resource_destroy(cb);
+
+ if (ec->comp_data->surface)
+ wl_resource_set_user_data(ec->comp_data->surface, NULL);
E_FREE(ec->comp_data);
@@ -2377,6 +2298,9 @@ _e_comp_wl_compositor_create(void)
wl_signal_init(&cdata->signals.surface.activate);
wl_signal_init(&cdata->signals.surface.kill);
+ cdata->output.transform = WL_OUTPUT_TRANSFORM_NORMAL;
+ cdata->output.scale = e_scale;
+
/* try to add compositor to wayland globals */
if (!wl_global_create(cdata->wl.disp, &wl_compositor_interface,
COMPOSITOR_VERSION, comp,
@@ -2579,9 +2503,6 @@ e_comp_wl_shutdown(void)
/* free handlers */
E_FREE_LIST(handlers, ecore_event_handler_del);
- /* free the clients win hash */
- /* E_FREE_FUNC(clients_win_hash, eina_hash_free); */
-
/* shutdown ecore_wayland */
ecore_wl_shutdown();
}
@@ -2597,185 +2518,121 @@ e_comp_wl_surface_create(struct wl_client *client, int version, uint32_t id)
return ret;
}
-EINTERN Eina_Bool
-e_comp_wl_surface_commit(E_Client *ec)
+EINTERN void
+e_comp_wl_surface_attach(E_Client *ec, E_Comp_Wl_Buffer *buffer)
{
- E_Pixmap *ep;
- Eina_Rectangle *dmg;
- Eina_Tiler *src, *tmp;
- Eina_Bool first;
+ e_comp_wl_buffer_reference(&ec->comp_data->buffer_ref, buffer);
- if (!(ep = ec->pixmap)) return EINA_FALSE;
- _e_comp_wl_client_evas_init(ec);
- if (ec->focused && ec->comp_data->focus_update)
- _e_comp_wl_client_focus(ec);
+ /* set usable early because shell module checks this */
+ e_pixmap_usable_set(ec->pixmap, (buffer != NULL));
+ e_pixmap_resource_set(ec->pixmap, buffer);
+ e_pixmap_dirty(ec->pixmap);
- first = !e_pixmap_usable_get(ep);
- /* mark the pixmap as usable or not */
- e_pixmap_usable_set(ep, (ec->comp_data->pending.buffer != NULL));
+ /* e_pixmap_image_clear(ec->pixmap, EINA_FALSE); */
- /* mark the pixmap as dirty */
- e_pixmap_dirty(ep);
+ _e_comp_wl_surface_state_size_update(ec, &ec->comp_data->pending);
+}
- e_pixmap_image_clear(ep, EINA_FALSE);
- e_pixmap_resource_set(ep, ec->comp_data->pending.buffer);
+EINTERN Eina_Bool
+e_comp_wl_surface_commit(E_Client *ec)
+{
+ _e_comp_wl_surface_state_commit(ec, &ec->comp_data->pending);
- /* refresh pixmap */
- if (e_pixmap_refresh(ep))
+ /* TODO: commit_subsurface_order */
+
+ /* schedule repaint */
+ if (e_pixmap_refresh(ec->pixmap))
{
e_comp->post_updates = eina_list_append(e_comp->post_updates, ec);
e_object_ref(E_OBJECT(ec));
}
- /* check if we need to map this surface */
- if (ec->comp_data->pending.buffer)
+ if (!e_pixmap_usable_get(ec->pixmap))
{
- /* if this surface is not mapped yet, map it */
- if (!ec->comp_data->mapped)
+ if (ec->comp_data->mapped)
{
- /* if the client has a shell map, call it */
- if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.map))
- ec->comp_data->shell.map(ec->comp_data->shell.surface);
+ if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap))
+ ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
else
{
- evas_object_show(ec->frame);
+ evas_object_hide(ec->frame);
ec->comp_data->mapped = evas_object_visible_get(ec->frame);
}
}
}
else
{
- /* no pending buffer to attach. unmap the surface */
- if (ec->comp_data->mapped)
+ if (!ec->comp_data->mapped)
{
- /* if the client has a shell map, call it */
- if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap))
- ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
+ if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.map))
+ ec->comp_data->shell.map(ec->comp_data->shell.surface);
else
{
- evas_object_hide(ec->frame);
+ evas_object_show(ec->frame);
ec->comp_data->mapped = evas_object_visible_get(ec->frame);
}
}
}
- /* check for any pending attachments */
- if (ec->comp_data->pending.new_attach)
- {
- int x, y, nw, nh;
- Eina_Bool placed = EINA_TRUE;;
-
- e_pixmap_size_get(ec->pixmap, &nw, &nh);
- if (ec->changes.pos)
- e_comp_object_frame_xy_adjust(ec->frame, ec->x, ec->y, &x, &y);
- else
- x = ec->client.x, y = ec->client.y;
- if (ec->new_client)
- placed = ec->placed;
- /* if the client has a shell configure, call it */
- if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.configure))
- ec->comp_data->shell.configure(ec->comp_data->shell.surface, x, y, nw, nh);
- else
- e_client_util_move_resize_without_frame(ec, x, y, nw, nh);
- if (ec->new_client)
- ec->placed = placed;
- else if (first && ec->placed)
- {
- ec->x = ec->y = 0;
- ec->placed = 0;
- ec->new_client = 1;
- }
- }
+ return EINA_TRUE;
+}
- if (!ec->comp_data->mapped)
- {
- DBG("\tSurface Not Mapped. Skip to Unmapped");
- goto unmap;
- }
+EINTERN Eina_Bool
+e_comp_wl_subsurface_commit(E_Client *ec)
+{
+ return EINA_FALSE;
+}
- /* commit any pending damages */
- if ((!ec->comp->nocomp) && (ec->frame))
+EINTERN void
+e_comp_wl_buffer_reference(E_Comp_Wl_Buffer_Ref *ref, E_Comp_Wl_Buffer *buffer)
+{
+ if ((ref->buffer) && (buffer != ref->buffer))
{
- EINA_LIST_FREE(ec->comp_data->pending.damages, dmg)
+ ref->buffer->busy--;
+ if (ref->buffer->busy == 0)
{
- e_comp_object_damage(ec->frame, dmg->x, dmg->y, dmg->w, dmg->h);
- eina_rectangle_free(dmg);
+ if (!wl_resource_get_client(ref->buffer->resource)) return;
+ wl_resource_queue_event(ref->buffer->resource, WL_BUFFER_RELEASE);
}
+ wl_list_remove(&ref->destroy_listener.link);
}
- /* handle pending input */
- if (ec->comp_data->pending.input)
+ if ((buffer) && (buffer != ref->buffer))
{
- tmp = eina_tiler_new(ec->w, ec->h);
- eina_tiler_tile_size_set(tmp, 1, 1);
- eina_tiler_rect_add(tmp,
- &(Eina_Rectangle){0, 0, ec->client.w, ec->client.h});
-
- if ((src = eina_tiler_intersection(ec->comp_data->pending.input, tmp)))
- {
- Eina_Rectangle *rect;
- Eina_Iterator *itr;
-
- itr = eina_tiler_iterator_new(src);
- /* this should be exactly 1 rect */
- EINA_ITERATOR_FOREACH(itr, rect)
- e_comp_object_input_area_set(ec->frame, rect->x, rect->y, rect->w, rect->h);
-
- eina_iterator_free(itr);
- eina_tiler_free(src);
- }
- else
- e_comp_object_input_area_set(ec->frame, 0, 0, ec->w, ec->h);
-
- eina_tiler_free(tmp);
+ buffer->busy++;
+ wl_signal_add(&buffer->destroy_signal, &ref->destroy_listener);
}
- return EINA_TRUE;
-
-unmap:
-
- /* surface is not visible, clear damages */
- EINA_LIST_FREE(ec->comp_data->pending.damages, dmg)
- eina_rectangle_free(dmg);
-
- /* clear pending input regions */
- if (ec->comp_data->pending.input)
- eina_tiler_clear(ec->comp_data->pending.input);
-
- return EINA_TRUE;
+ ref->buffer = buffer;
+ ref->destroy_listener.notify = _e_comp_wl_buffer_reference_cb_destroy;
}
-EINTERN Eina_Bool
-e_comp_wl_subsurface_commit(E_Client *ec)
+EAPI E_Comp_Wl_Buffer *
+e_comp_wl_buffer_get(struct wl_resource *resource)
{
- E_Comp_Wl_Subsurf_Data *sdata;
+ E_Comp_Wl_Buffer *buffer;
+ struct wl_listener *listener;
+ struct wl_shm_buffer *shmbuff;
- /* check for valid subcompositor data */
- if (!(sdata = ec->comp_data->sub.data)) return EINA_FALSE;
+ listener =
+ wl_resource_get_destroy_listener(resource, _e_comp_wl_buffer_cb_destroy);
+ if (listener)
+ return container_of(listener, E_Comp_Wl_Buffer, destroy_listener);
- if (_e_comp_wl_subsurface_synchronized_get(sdata))
- _e_comp_wl_subsurface_commit_to_cache(ec);
- else
- {
- E_Client *subc;
- Eina_List *l;
+ if (!(shmbuff = wl_shm_buffer_get(resource))) return NULL;
- if (sdata->cached.has_data)
- {
- _e_comp_wl_subsurface_commit_to_cache(ec);
- _e_comp_wl_subsurface_commit_from_cache(ec);
- }
- else
- e_comp_wl_surface_commit(ec);
+ buffer = E_NEW(E_Comp_Wl_Buffer, 1);
+ if (!buffer) return NULL;
- EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
- {
- if (ec != subc)
- _e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
- }
- }
+ buffer->w = wl_shm_buffer_get_width(shmbuff);
+ buffer->h = wl_shm_buffer_get_height(shmbuff);
- return EINA_TRUE;
+ buffer->resource = resource;
+ wl_signal_init(&buffer->destroy_signal);
+ buffer->destroy_listener.notify = _e_comp_wl_buffer_cb_destroy;
+ wl_resource_add_destroy_listener(resource, &buffer->destroy_listener);
+
+ return buffer;
}
EAPI double
diff --git a/src/bin/e_pixmap.c b/src/bin/e_pixmap.c
index 9a84e0b8eb..fd28b6a82c 100644
--- a/src/bin/e_pixmap.c
+++ b/src/bin/e_pixmap.c
@@ -32,8 +32,9 @@ struct _E_Pixmap
#endif
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- struct wl_resource *resource;
- Eina_List *resource_cache;
+ E_Comp_Wl_Buffer_Ref buffer_ref;
+ struct wl_listener buffer_destroy_listener;
+ void *data;
Eina_Rectangle opaque;
#endif
@@ -44,9 +45,12 @@ struct _E_Pixmap
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
static void
-_e_pixmap_resource_free(struct wl_resource *pixres)
+_e_pixmap_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
{
- if (pixres) wl_buffer_send_release(pixres);
+ E_Pixmap *cp;
+
+ cp = container_of(listener, E_Pixmap, buffer_destroy_listener);
+ cp->buffer_destroy_listener.notify = NULL;
}
#endif
@@ -70,13 +74,19 @@ _e_pixmap_clear(E_Pixmap *cp, Eina_Bool cache)
break;
case E_PIXMAP_TYPE_WL:
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- if (cp->resource)
+ if (cp->buffer_destroy_listener.notify)
{
- e_pixmap_image_clear(cp, cache);
+ wl_list_remove(&cp->buffer_destroy_listener.link);
+ cp->buffer_destroy_listener.notify = NULL;
}
+
+ e_comp_wl_buffer_reference(&cp->buffer_ref, NULL);
+
+ (void)cache;
#endif
break;
- default: break;
+ default:
+ break;
}
}
@@ -110,17 +120,6 @@ _e_pixmap_free(E_Pixmap *cp)
break;
case E_PIXMAP_TYPE_WL:
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- if (!cp->resource_cache) break;
- if (cp->client)
- eina_list_free(cp->resource_cache);
- else
- {
- void *i;
-
- EINA_LIST_FREE(cp->resource_cache, i)
- _e_pixmap_resource_free(i);
- }
- cp->resource_cache = NULL;
#endif
break;
default:
@@ -173,52 +172,6 @@ _e_pixmap_find(E_Pixmap_Type type, va_list *l)
return NULL;
}
-#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
-static void
-_e_pixmap_update_wl(E_Pixmap *cp)
-{
- if (!cp) return;
- cp->w = cp->h = 0;
- if (cp->resource)
- {
- struct wl_shm_buffer *buffer;
- uint32_t format;
-
- if (!(buffer = wl_shm_buffer_get(cp->resource))) return;
-
- format = wl_shm_buffer_get_format(buffer);
- switch (format)
- {
- /* TOOD: add more cases */
- case WL_SHM_FORMAT_ARGB8888:
- case WL_SHM_FORMAT_ARGB4444:
- case WL_SHM_FORMAT_ABGR4444:
- case WL_SHM_FORMAT_RGBA4444:
- case WL_SHM_FORMAT_BGRA4444:
- case WL_SHM_FORMAT_ARGB1555:
- case WL_SHM_FORMAT_ABGR1555:
- case WL_SHM_FORMAT_RGBA5551:
- case WL_SHM_FORMAT_BGRA5551:
- case WL_SHM_FORMAT_ABGR8888:
- case WL_SHM_FORMAT_RGBA8888:
- case WL_SHM_FORMAT_BGRA8888:
- case WL_SHM_FORMAT_ARGB2101010:
- case WL_SHM_FORMAT_ABGR2101010:
- case WL_SHM_FORMAT_RGBA1010102:
- case WL_SHM_FORMAT_BGRA1010102:
- case WL_SHM_FORMAT_AYUV:
- cp->image_argb = EINA_TRUE;
- break;
- default:
- cp->image_argb = EINA_FALSE;
- break;
- }
- cp->w = wl_shm_buffer_get_width(buffer);
- cp->h = wl_shm_buffer_get_height(buffer);
- }
-}
-#endif
-
EAPI int
e_pixmap_free(E_Pixmap *cp)
{
@@ -437,30 +390,7 @@ e_pixmap_refresh(E_Pixmap *cp)
break;
case E_PIXMAP_TYPE_WL:
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- {
- E_Comp_Wl_Client_Data *cd = NULL;
- int pw = 0, ph = 0;
-
- if (cp->client)
- {
- cd = (E_Comp_Wl_Client_Data *)cp->client->comp_data;
- /* pw = cp->client->client.w; */
- /* ph = cp->client->client.h; */
- }
-
- success = !!cp->resource;
- if (!success) break;
-
- if ((cd) && (cd->pending.w) && (cd->pending.h))
- {
- pw = cd->pending.w;
- ph = cd->pending.h;
- }
-
- success = ((pw > 0) && (ph > 0));
- if (success)
- _e_pixmap_update_wl(cp);
- }
+ success = ((cp->w > 0) && (cp->h > 0));
#endif
break;
default:
@@ -558,7 +488,7 @@ e_pixmap_resource_get(E_Pixmap *cp)
return NULL;
}
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- return cp->resource;
+ return cp->buffer_ref.buffer;
#endif
return NULL;
}
@@ -568,9 +498,54 @@ e_pixmap_resource_set(E_Pixmap *cp, void *resource)
{
if ((!cp) || (cp->type != E_PIXMAP_TYPE_WL)) return;
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- cp->resource = resource;
+ {
+ E_Comp_Wl_Buffer *buffer;
+ struct wl_shm_buffer *shm_buffer;
+
+ buffer = (E_Comp_Wl_Buffer *)resource;
+ e_comp_wl_buffer_reference(&cp->buffer_ref, buffer);
+
+ if (cp->buffer_destroy_listener.notify)
+ {
+ wl_list_remove(&cp->buffer_destroy_listener.link);
+ cp->buffer_destroy_listener.notify = NULL;
+ }
+
+ cp->w = cp->h = 0;
+ cp->image_argb = EINA_FALSE;
+
+ if (!buffer) return;
+
+ if (!(shm_buffer = wl_shm_buffer_get(buffer->resource)))
+ {
+ WRN("Cannot get shm buffer from buffer resource");
+ e_comp_wl_buffer_reference(&cp->buffer_ref, NULL);
+ return;
+ }
+
+ buffer->shm_buffer = shm_buffer;
+ cp->w = buffer->w;
+ cp->h = buffer->h;
+ /* buffer->w = cp->w = wl_shm_buffer_get_width(shm_buffer); */
+ /* buffer->h = cp->h = wl_shm_buffer_get_height(shm_buffer); */
+
+ switch (wl_shm_buffer_get_format(shm_buffer))
+ {
+ case WL_SHM_FORMAT_ARGB8888:
+ cp->image_argb = EINA_TRUE;
+ break;
+ default:
+ cp->image_argb = EINA_FALSE;
+ break;
+ }
+
+ cp->data = wl_shm_buffer_get_data(shm_buffer);
+
+ cp->buffer_destroy_listener.notify = _e_pixmap_cb_buffer_destroy;
+ wl_signal_add(&buffer->destroy_signal, &cp->buffer_destroy_listener);
+ }
#else
- (void) resource;
+ (void)resource;
#endif
}
@@ -631,7 +606,7 @@ e_pixmap_image_clear(E_Pixmap *cp, Eina_Bool cache)
if (!cp->image) return;
#endif
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- if (!cp->resource) return;
+ if (!cp->buffer_ref.buffer) return;
#endif
}
@@ -656,23 +631,6 @@ e_pixmap_image_clear(E_Pixmap *cp, Eina_Bool cache)
break;
case E_PIXMAP_TYPE_WL:
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- if (cache)
- {
- void *i;
-
- EINA_LIST_FREE(cp->resource_cache, i)
- _e_pixmap_resource_free(i);
- }
- else
- {
- if (eina_list_data_find(cp->resource_cache, cp->resource) !=
- cp->resource)
- {
- cp->resource_cache =
- eina_list_append(cp->resource_cache, cp->resource);
- cp->resource = NULL;
- }
- }
#endif
break;
default:
@@ -709,8 +667,8 @@ e_pixmap_image_refresh(E_Pixmap *cp)
break;
case E_PIXMAP_TYPE_WL:
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- _e_pixmap_update_wl(cp);
- return ((cp->w > 0) && (cp->h > 0));
+ /* FIXME */
+ return EINA_TRUE;
#endif
break;
default:
@@ -730,7 +688,7 @@ e_pixmap_image_exists(const E_Pixmap *cp)
return !!cp->image;
#endif
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- return (cp->resource != NULL);
+ return (cp->buffer_ref.buffer != NULL);
#endif
return EINA_FALSE;
@@ -749,7 +707,7 @@ e_pixmap_image_is_argb(const E_Pixmap *cp)
#endif
case E_PIXMAP_TYPE_WL:
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- return ((cp->resource != NULL) && (cp->image_argb));
+ return ((cp->buffer_ref.buffer != NULL) && (cp->image_argb));
#endif
default: break;
}
@@ -771,20 +729,7 @@ e_pixmap_image_data_get(E_Pixmap *cp)
break;
case E_PIXMAP_TYPE_WL:
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- if (cp->resource)
- {
- struct wl_shm_buffer *buffer;
- void *data = NULL;
-
- if (!(buffer = wl_shm_buffer_get(cp->resource)))
- return NULL;
-
- wl_shm_buffer_begin_access(buffer);
- data = wl_shm_buffer_get_data(buffer);
- wl_shm_buffer_end_access(buffer);
-
- return data;
- }
+ return cp->data;
#endif
break;
default:
@@ -814,18 +759,17 @@ e_pixmap_image_data_argb_convert(E_Pixmap *cp, void *pix, void *ipix, Eina_Recta
case E_PIXMAP_TYPE_WL:
if (cp->image_argb) return EINA_TRUE;
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- if (cp->resource)
+ if (cp->buffer_ref.buffer)
{
- /* TOOD: add more cases */
- struct wl_shm_buffer *buffer;
+ struct wl_shm_buffer *shm_buffer;
uint32_t format;
int i, x, y;
unsigned int *src, *dst;
- if (!(buffer = wl_shm_buffer_get(cp->resource)))
- return EINA_FALSE;
+ shm_buffer = wl_shm_buffer_get(cp->buffer_ref.buffer->resource);
+ if (!shm_buffer) return EINA_FALSE;
- format = wl_shm_buffer_get_format(buffer);
+ format = wl_shm_buffer_get_format(shm_buffer);
if (format == WL_SHM_FORMAT_XRGB8888)
{
dst = (unsigned int *)pix;
@@ -839,9 +783,9 @@ e_pixmap_image_data_argb_convert(E_Pixmap *cp, void *pix, void *ipix, Eina_Recta
}
pix = (void *)dst;
}
- }
- return EINA_TRUE;
+ return EINA_TRUE;
+ }
#endif
break;
default:
@@ -865,20 +809,6 @@ e_pixmap_image_draw(E_Pixmap *cp, const Eina_Rectangle *r)
break;
case E_PIXMAP_TYPE_WL:
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- {
- E_Comp_Wl_Client_Data *cd;
- struct wl_resource *cb;
-
- if ((!cp->client) || (!cp->client->comp_data))
- return EINA_FALSE;
-
- cd = (E_Comp_Wl_Client_Data*)cp->client->comp_data;
- EINA_LIST_FREE(cd->frames, cb)
- {
- wl_callback_send_done(cb, ecore_time_unix_get());
- wl_resource_destroy(cb);
- }
- }
#endif
(void) r;
return EINA_TRUE;
@@ -888,6 +818,21 @@ e_pixmap_image_draw(E_Pixmap *cp, const Eina_Rectangle *r)
return EINA_FALSE;
}
+EAPI void
+e_pixmap_image_draw_done(E_Pixmap *cp)
+{
+ EINA_SAFETY_ON_NULL_RETURN(cp);
+
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+ struct wl_shm_buffer *shm_buffer;
+
+ shm_buffer = wl_shm_buffer_get(cp->buffer_ref.buffer->resource);
+ if (!shm_buffer) return;
+
+ wl_shm_buffer_end_access(shm_buffer);
+#endif
+}
+
EAPI void
e_pixmap_image_opaque_set(E_Pixmap *cp, int x, int y, int w, int h)
{