From e84c21469d0ba1ff477f3b30912135b3c42fa2bd Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 12:31:15 -0400 Subject: [PATCH 01/84] remove old wayland compositor file Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 3301 ------------------------------------------- 1 file changed, 3301 deletions(-) delete mode 100644 src/bin/e_comp_wl.c diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c deleted file mode 100644 index 6128892e9..000000000 --- a/src/bin/e_comp_wl.c +++ /dev/null @@ -1,3301 +0,0 @@ -#define E_COMP_WL -#include "e.h" - - -#define E_COMP_WL_PIXMAP_CHECK \ - if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return - -/* local variables */ -static Eina_List *handlers = NULL; -static Eina_List *subcomp_handlers = NULL; -static Eina_Hash *clients_win_hash = NULL; -static Ecore_Idle_Enterer *_client_idler = NULL; -static Eina_List *_idle_clients = NULL; -static Eina_Bool restacking = EINA_FALSE; - -static void -_e_comp_wl_focus_down_set(E_Client *ec) -{ - Ecore_Window win = 0; - - win = e_client_util_pwin_get(ec); - e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, win); - e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, win); -} - -static void -_e_comp_wl_focus_check(E_Comp *comp) -{ - E_Client *ec; - - if (stopping) return; - ec = e_client_focused_get(); - if ((!ec) || (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL)) - e_grabinput_focus(comp->ee_win, E_FOCUS_METHOD_PASSIVE); -} - -static void -_e_comp_wl_client_event_free(void *d EINA_UNUSED, void *event) -{ - E_Event_Client *ev; - - if (!(ev = event)) return; - e_object_unref(E_OBJECT(ev->ec)); - free(ev); -} - -static void -_e_comp_wl_buffer_pending_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED) -{ - E_Comp_Client_Data *cd; - - if (!(cd = container_of(listener, E_Comp_Client_Data, - pending.buffer_destroy))) - return; - - cd->pending.buffer = NULL; -} - -static void -_e_comp_wl_buffer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED) -{ - E_Comp_Wl_Buffer *buffer; - - if (!(buffer = container_of(listener, E_Comp_Wl_Buffer, destroy_listener))) - return; - - wl_signal_emit(&buffer->destroy_signal, buffer); - free(buffer); -} - -static E_Comp_Wl_Buffer * -_e_comp_wl_buffer_get(struct wl_resource *resource) -{ - E_Comp_Wl_Buffer *buffer; - struct wl_listener *listener; - - 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 (!(buffer = E_NEW(E_Comp_Wl_Buffer, 1))) return NULL; - - 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; -} - -static void -_e_comp_wl_buffer_reference_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED) -{ - E_Comp_Wl_Buffer_Ref *ref; - - if (!(ref = container_of(listener, E_Comp_Wl_Buffer_Ref, destroy_listener))) - return; - - ref->buffer = NULL; -} - -static void -_e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static E_Comp_Wl_Subsurf * -_e_comp_wl_client_subsurf_data_get(E_Client *ec) -{ - return ec->comp_data->sub.cdata; -} - -static E_Client * -_e_comp_wl_subsurface_parent_get(E_Client *ec) -{ - E_Comp_Wl_Subsurf *sub_cdata; - - if (!(sub_cdata = _e_comp_wl_client_subsurf_data_get(ec))) return NULL; - - return sub_cdata->parent; -} - -static void -_e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer_resource, int32_t sx, int32_t sy) -{ - E_Pixmap *cp; - E_Client *ec; - E_Comp_Wl_Buffer *buffer = NULL; - - if (!(cp = wl_resource_get_user_data(resource))) return; - - /* try to find the E client for this surface */ - if (!(ec = e_pixmap_client_get(cp))) - ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, e_pixmap_window_get(cp)); - - if ((!ec) || (e_object_is_del(E_OBJECT(ec)))) return; - - if (buffer_resource) - { - if (!(buffer = _e_comp_wl_buffer_get(buffer_resource))) - { - wl_client_post_no_memory(client); - return; - } - } - - if (!ec->comp_data) return; - - if (ec->comp_data->pending.buffer) - wl_list_remove(&ec->comp_data->pending.buffer_destroy.link); - - 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; - ec->comp_data->pending.new_attach = EINA_TRUE; - - if (buffer) - { - struct wl_shm_buffer *b; - - /* trap return of shm_buffer_get as it Can fail if the buffer is not - * an shm buffer (ie: egl buffer) */ - if (!(b = wl_shm_buffer_get(buffer_resource))) return; - - ec->comp_data->pending.w = wl_shm_buffer_get_width(b); - ec->comp_data->pending.h = wl_shm_buffer_get_height(b); - - wl_signal_add(&buffer->destroy_signal, - &ec->comp_data->pending.buffer_destroy); - } -} - -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 *cp; - E_Client *ec; - Eina_Tiler *tmp; - - if (!(cp = wl_resource_get_user_data(resource))) return; - - /* try to find the E client for this surface */ - if (!(ec = e_pixmap_client_get(cp))) - ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, e_pixmap_window_get(cp)); - - if ((!ec) || (e_object_is_del(E_OBJECT(ec)))) return; - - tmp = eina_tiler_new(ec->w ?: w, ec->h ?: h); - eina_tiler_tile_size_set(tmp, 1, 1); - eina_tiler_rect_add(tmp, &(Eina_Rectangle){x, y, w, h}); - - eina_tiler_union(ec->comp_data->pending.damage, tmp); - - eina_tiler_free(tmp); -} - -static void -_e_comp_wl_surface_cb_frame_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 from the list */ - ec->comp_data->frames = - eina_list_remove(ec->comp_data->frames, resource); -} - -static void -_e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resource, uint32_t callback) -{ - E_Pixmap *cp; - E_Client *ec; - struct wl_resource *res; - - if (!(cp = wl_resource_get_user_data(resource))) return; - - /* try to find the E client for this surface */ - if (!(ec = e_pixmap_client_get(cp))) - ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, e_pixmap_window_get(cp)); - - if ((!ec) || (e_object_is_del(E_OBJECT(ec)))) return; - - /* create frame callback */ - res = wl_resource_create(client, &wl_callback_interface, 1, callback); - if (!res) - { - wl_resource_post_no_memory(resource); - return; - } - - wl_resource_set_implementation(res, NULL, ec, - _e_comp_wl_surface_cb_frame_destroy); - - /* add this frame callback to the client */ - ec->comp_data->frames = eina_list_prepend(ec->comp_data->frames, res); -} - -static void -_e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource) -{ - E_Pixmap *cp; - E_Client *ec; - - /* DBG("E_Surface Opaque Region Set"); */ - - if (!(cp = wl_resource_get_user_data(resource))) return; - - /* try to find the E client for this surface */ - if (!(ec = e_pixmap_client_get(cp))) - ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, e_pixmap_window_get(cp)); - - if ((!ec) || (e_object_is_del(E_OBJECT(ec)))) return; - - if (region_resource) - { - Eina_Tiler *tmp; - - if (!(tmp = wl_resource_get_user_data(region_resource))) - return; - - eina_tiler_union(ec->comp_data->pending.opaque, tmp); - } - else - { - eina_tiler_clear(ec->comp_data->pending.opaque); - eina_tiler_rect_add(ec->comp_data->pending.opaque, - &(Eina_Rectangle){0, 0, ec->client.w, ec->client.h}); - } -} - -static void -_e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource) -{ - E_Pixmap *cp; - E_Client *ec; - - if (!(cp = wl_resource_get_user_data(resource))) return; - - /* try to find the E client for this surface */ - if (!(ec = e_pixmap_client_get(cp))) - ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, e_pixmap_window_get(cp)); - - if ((!ec) || (e_object_is_del(E_OBJECT(ec)))) return; - - if (region_resource) - { - Eina_Tiler *tmp; - - if (!(tmp = wl_resource_get_user_data(region_resource))) - return; - - eina_tiler_union(ec->comp_data->pending.input, tmp); - } - else - { - eina_tiler_clear(ec->comp_data->pending.input); - eina_tiler_rect_add(ec->comp_data->pending.input, - &(Eina_Rectangle){0, 0, ec->client.w, ec->client.h}); - } -} - -static void -_e_comp_wl_subsurface_destroy_internal(E_Client *ec) -{ - E_Comp_Wl_Subsurf *sub_cdata; - - sub_cdata = _e_comp_wl_client_subsurf_data_get(ec); - if (!sub_cdata) return; - - if (sub_cdata->resource) - { - if (sub_cdata->parent) - { - sub_cdata->parent->comp_data->sub.list - = eina_list_remove(sub_cdata->parent->comp_data->sub.list, ec); - sub_cdata->parent = NULL; - } - - e_comp_wl_buffer_reference(&sub_cdata->cached.buffer_ref, NULL); - - if (sub_cdata->cached.damage) - eina_tiler_free(sub_cdata->cached.damage); - if (sub_cdata->cached.input) - eina_tiler_free(sub_cdata->cached.input); - if (sub_cdata->cached.opaque) - eina_tiler_free(sub_cdata->cached.opaque); - } - - free(sub_cdata); - ec->comp_data->sub.cdata = NULL; - e_object_del(E_OBJECT(ec)); -} - -static void -_e_comp_wl_subsurface_destroy(struct wl_resource *resource) -{ - E_Client *ec; - - if (!(ec = wl_resource_get_user_data(resource))) return; - - _e_comp_wl_subsurface_destroy_internal(ec); -} - -static E_Client * -_e_comp_wl_subsurface_root_get(E_Client *ec) -{ - E_Client *parent = NULL; - - if (!_e_comp_wl_client_subsurf_data_get(ec)) return ec; - if (!(parent = _e_comp_wl_subsurface_parent_get(ec))) return ec; - - return _e_comp_wl_subsurface_root_get(parent); -} - -static Eina_Bool -_e_comp_wl_subsurface_is_synchronized(E_Comp_Wl_Subsurf *sub_cdata) -{ - while (sub_cdata) - { - if (sub_cdata->synchronized) return EINA_TRUE; - - if (!sub_cdata->parent) return EINA_FALSE; - - sub_cdata = _e_comp_wl_client_subsurf_data_get(sub_cdata->parent); - } - - return EINA_FALSE; -} - -static void -_e_comp_wl_subsurface_commit_to_cache(E_Client *ec) -{ - E_Comp_Client_Data *cdata; - E_Comp_Wl_Subsurf *sub_cdata; - - if (!(cdata = ec->comp_data)) return; - if (!(sub_cdata = cdata->sub.cdata)) return; - - // copy pending damage to cache, and clear pending damage. - eina_tiler_union(sub_cdata->cached.damage, cdata->pending.damage); - eina_tiler_clear(cdata->pending.damage); - - if (cdata->pending.new_attach) - { - sub_cdata->cached.new_attach = EINA_TRUE; - e_comp_wl_buffer_reference(&sub_cdata->cached.buffer_ref, - cdata->pending.buffer); - } - - sub_cdata->cached.x = cdata->pending.x; - sub_cdata->cached.y = cdata->pending.y; - cdata->pending.x = 0; - cdata->pending.y = 0; - cdata->pending.new_attach = EINA_FALSE; - - sub_cdata->cached.opaque = eina_tiler_new(ec->w, ec->h); - eina_tiler_union(sub_cdata->cached.opaque, cdata->pending.opaque); - - sub_cdata->cached.input = eina_tiler_new(ec->w, ec->h); - eina_tiler_union(sub_cdata->cached.input, cdata->pending.input); - - sub_cdata->cached.has_data = EINA_TRUE; -} - -static void -_e_comp_wl_subsurface_commit_from_cache(E_Client *ec) -{ - E_Comp_Client_Data *cdata; - E_Comp_Wl_Subsurf *sub_cdata; - E_Pixmap *cp; - Eina_Tiler *src, *tmp; - - if (!(cdata = ec->comp_data)) return; - if (!(sub_cdata = cdata->sub.cdata)) return; - if (!(cp = ec->pixmap)) return; - - if (sub_cdata->cached.new_attach) - { - e_comp_wl_buffer_reference(&cdata->buffer_ref, - sub_cdata->cached.buffer_ref.buffer); - if (cdata->pending.buffer) - e_pixmap_resource_set(cp, - cdata->pending.buffer->resource); - else - e_pixmap_resource_set(cp, NULL); - e_pixmap_usable_set(cp, (cdata->pending.buffer != NULL)); - } - - e_pixmap_dirty(cp); - e_pixmap_refresh(cp); - - if (sub_cdata->cached.new_attach) - { - if (sub_cdata->cached.buffer_ref.buffer) - { - if (cdata->mapped) - { - if ((cdata->shell.surface) && - (cdata->shell.unmap)) - cdata->shell.unmap(cdata->shell.surface); - } - } - else - { - if (!cdata->mapped) - { - if ((cdata->shell.surface) && - (cdata->shell.map)) - cdata->shell.map(cdata->shell.surface); - } - } - } - - sub_cdata->cached.x = 0; - sub_cdata->cached.y = 0; - sub_cdata->cached.has_data = EINA_FALSE; - sub_cdata->cached.new_attach = EINA_FALSE; - - if ((!ec->comp->nocomp) && (ec->frame)) - { - 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}); - - src = eina_tiler_intersection(sub_cdata->cached.damage, tmp); - if (src) - { - Eina_Rectangle *rect; - Eina_Iterator *itr; - - itr = eina_tiler_iterator_new(src); - EINA_ITERATOR_FOREACH(itr, rect) - { - e_comp_object_damage(ec->frame, - rect->x, rect->y, rect->w, rect->h); - } - eina_iterator_free(itr); - eina_tiler_free(src); - } - eina_tiler_free(tmp); - eina_tiler_clear(sub_cdata->cached.damage); - } - - /* handle surface opaque region */ - 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}); - - src = eina_tiler_intersection(sub_cdata->cached.opaque, tmp); - if (src) - { - Eina_Rectangle *rect; - Eina_Iterator *itr; - int i = 0; - - ec->shape_rects_num = 0; - - itr = eina_tiler_iterator_new(src); - EINA_ITERATOR_FOREACH(itr, rect) - { - ec->shape_rects_num += 1; - } - - ec->shape_rects = - malloc(sizeof(Eina_Rectangle) * ec->shape_rects_num); - - if (!ec->shape_rects) - { - eina_iterator_free(itr); - eina_tiler_free(src); - eina_tiler_free(tmp); - return; - } - EINA_ITERATOR_FOREACH(itr, rect) - { - ec->shape_rects[i] = *(Eina_Rectangle *)((char *)rect); - - ec->shape_rects[i].x = rect->x; - ec->shape_rects[i].y = rect->y; - ec->shape_rects[i].w = rect->w; - ec->shape_rects[i].h = rect->h; - - i++; - } - - eina_iterator_free(itr); - eina_tiler_free(src); - } - - eina_tiler_free(tmp); - eina_tiler_clear(sub_cdata->cached.opaque); - - 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}); - - src = eina_tiler_intersection(sub_cdata->cached.input, tmp); - if (src) - { - Eina_Rectangle *rect; - Eina_Iterator *itr; - int i = 0; - - ec->shape_input_rects_num = 0; - - itr = eina_tiler_iterator_new(src); - EINA_ITERATOR_FOREACH(itr, rect) - { - ec->shape_input_rects_num += 1; - } - - ec->shape_input_rects = - malloc(sizeof(Eina_Rectangle) * ec->shape_input_rects_num); - - if (!ec->shape_input_rects) - { - eina_iterator_free(itr); - eina_tiler_free(src); - eina_tiler_free(tmp); - return; - } - - EINA_ITERATOR_FOREACH(itr, rect) - { - ec->shape_input_rects[i] = - *(Eina_Rectangle *)((char *)rect); - - ec->shape_input_rects[i].x = rect->x; - ec->shape_input_rects[i].y = rect->y; - ec->shape_input_rects[i].w = rect->w; - ec->shape_input_rects[i].h = rect->h; - - i++; - } - - eina_iterator_free(itr); - eina_tiler_free(src); - } - - eina_tiler_free(tmp); - eina_tiler_clear(sub_cdata->cached.input); - - ec->changes.shape_input = EINA_TRUE; - EC_CHANGED(ec); -} - -static void -_e_comp_wl_surface_commit(E_Client *ec) -{ - E_Pixmap *cp; - Eina_Tiler *src, *tmp; - - if (!(cp = ec->pixmap)) return; - - if (ec->comp_data->pending.new_attach) - { - e_comp_wl_buffer_reference(&ec->comp_data->buffer_ref, - ec->comp_data->pending.buffer); - if (ec->comp_data->pending.buffer) - e_pixmap_resource_set(cp, - ec->comp_data->pending.buffer->resource); - else - e_pixmap_resource_set(cp, NULL); - e_pixmap_usable_set(cp, (ec->comp_data->pending.buffer != NULL)); - } - - e_pixmap_dirty(cp); - e_pixmap_refresh(cp); - - if ((ec->comp_data->shell.surface) && - (ec->comp_data->shell.configure)) - { - if (ec->comp_data->pending.new_attach) - { - if ((ec->client.w != ec->comp_data->pending.w) || - (ec->client.h != ec->comp_data->pending.h)) - ec->comp_data->shell.configure(ec->comp_data->shell.surface, - ec->client.x, ec->client.y, - ec->comp_data->pending.w, - ec->comp_data->pending.h); - } - } - - if (ec->comp_data) - { - if (ec->comp_data->pending.damage) - eina_tiler_area_size_set(ec->comp_data->pending.damage, - ec->client.w, ec->client.h); - - if (ec->comp_data->pending.input) - eina_tiler_area_size_set(ec->comp_data->pending.input, - ec->client.w, ec->client.h); - - if (ec->comp_data->pending.opaque) - eina_tiler_area_size_set(ec->comp_data->pending.opaque, - ec->client.w, ec->client.h); - } - - if (ec->comp_data->pending.new_attach) - { - if (!ec->comp_data->pending.buffer) - { - 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 - { - 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); - } - } - } - - /* reset pending buffer */ - if (ec->comp_data->pending.buffer) - wl_list_remove(&ec->comp_data->pending.buffer_destroy.link); - - ec->comp_data->pending.x = 0; - ec->comp_data->pending.y = 0; - ec->comp_data->pending.w = 0; - ec->comp_data->pending.h = 0; - ec->comp_data->pending.buffer = NULL; - ec->comp_data->pending.new_attach = EINA_FALSE; - - /* handle surface opaque region */ - 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}); - - src = eina_tiler_intersection(ec->comp_data->pending.opaque, tmp); - if (src) - { - Eina_Rectangle *rect; - Eina_Iterator *itr; - int i = 0; - - ec->shape_rects_num = 0; - - itr = eina_tiler_iterator_new(src); - EINA_ITERATOR_FOREACH(itr, rect) - { - ec->shape_rects_num += 1; - } - - ec->shape_rects = - malloc(sizeof(Eina_Rectangle) * ec->shape_rects_num); - - if (ec->shape_rects) - { - EINA_ITERATOR_FOREACH(itr, rect) - { - ec->shape_rects[i] = *(Eina_Rectangle *)((char *)rect); - - ec->shape_rects[i].x = rect->x; - ec->shape_rects[i].y = rect->y; - ec->shape_rects[i].w = rect->w; - ec->shape_rects[i].h = rect->h; - - i++; - } - } - - eina_iterator_free(itr); - eina_tiler_free(src); - } - - eina_tiler_free(tmp); - eina_tiler_clear(ec->comp_data->pending.opaque); - - /* handle surface damages */ - if ((!ec->comp->nocomp) && (ec->frame)) - { - 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}); - - src = eina_tiler_intersection(ec->comp_data->pending.damage, tmp); - if (src) - { - Eina_Rectangle *rect; - Eina_Iterator *itr; - - itr = eina_tiler_iterator_new(src); - EINA_ITERATOR_FOREACH(itr, rect) - { - e_comp_object_damage(ec->frame, - rect->x, rect->y, rect->w, rect->h); - } - eina_iterator_free(itr); - eina_tiler_free(src); - } - - eina_tiler_free(tmp); - - eina_tiler_clear(ec->comp_data->pending.damage); - } - - /* handle input regions */ - 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}); - - src = eina_tiler_intersection(ec->comp_data->pending.input, tmp); - if (src) - { - Eina_Rectangle *rect; - Eina_Iterator *itr; - int i = 0; - - ec->shape_input_rects_num = 0; - - itr = eina_tiler_iterator_new(src); - EINA_ITERATOR_FOREACH(itr, rect) - { - ec->shape_input_rects_num += 1; - } - - ec->shape_input_rects = - malloc(sizeof(Eina_Rectangle) * ec->shape_input_rects_num); - - if (ec->shape_input_rects) - { - EINA_ITERATOR_FOREACH(itr, rect) - { - ec->shape_input_rects[i] = - *(Eina_Rectangle *)((char *)rect); - - ec->shape_input_rects[i].x = rect->x; - ec->shape_input_rects[i].y = rect->y; - ec->shape_input_rects[i].w = rect->w; - ec->shape_input_rects[i].h = rect->h; - - i++; - } - } - - eina_iterator_free(itr); - eina_tiler_free(src); - } - - eina_tiler_free(tmp); - eina_tiler_clear(ec->comp_data->pending.input); - -/* #ifndef HAVE_WAYLAND_ONLY */ -/* e_comp_object_input_area_set(ec->frame, rect->x, rect->y, */ -/* rect->w, rect->h); */ -/* #endif */ -} - -static void -_e_comp_wl_subsurface_parent_commit(E_Client *ec, Eina_Bool parent_is_synchronized) -{ - E_Client *parent, *subc; - E_Comp_Wl_Subsurf *sub_cdata; - Eina_List *l; - - if (!(parent = _e_comp_wl_subsurface_parent_get(ec))) return; - if (!(sub_cdata = _e_comp_wl_client_subsurf_data_get(ec))) return; - - if (sub_cdata->position.set) - { - evas_object_move(ec->frame, - parent->x + sub_cdata->position.x, - parent->y + sub_cdata->position.y); - sub_cdata->position.set = EINA_FALSE; - } - - if ((parent_is_synchronized) || (sub_cdata->synchronized)) - { - if (sub_cdata->cached.has_data) - _e_comp_wl_subsurface_commit_from_cache(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_commit(E_Client *ec) -{ - E_Client *subc; - E_Comp_Wl_Subsurf *sub_cdata; - Eina_List *l; - int w, h; - - sub_cdata = _e_comp_wl_client_subsurf_data_get(ec); - if (!sub_cdata) return; - - ec->client.w = ec->comp_data->pending.w; - ec->client.h = ec->comp_data->pending.h; - evas_object_geometry_get(ec->frame, NULL, NULL, &w, &h); - - if ((ec->client.w != w) || (ec->client.h != h)) - evas_object_resize(ec->frame, ec->client.w, ec->client.h); - - if ((!ec->iconic) && - (!evas_object_visible_get(ec->frame))) - evas_object_show(ec->frame); - - if (_e_comp_wl_subsurface_is_synchronized(sub_cdata)) - _e_comp_wl_subsurface_commit_to_cache(ec); - else - { - if (sub_cdata->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); - - EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc) - { - if (ec != subc) - _e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE); - } - } -} - -static void -_e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - E_Pixmap *cp; - E_Client *ec, *subc; - Eina_List *l; - - if (!(cp = wl_resource_get_user_data(resource))) return; - - /* try to find the E client for this surface */ - if (!(ec = e_pixmap_client_get(cp))) - ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, e_pixmap_window_get(cp)); - - if ((!ec) || (e_object_is_del(E_OBJECT(ec)))) - return; - - if (_e_comp_wl_client_subsurf_data_get(ec)) - { - // ec for subsurface. - _e_comp_wl_subsurface_commit(ec); - return; - } - - // ec for main surface. - _e_comp_wl_surface_commit(ec); - - EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc) - { - if (subc != ec) - _e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE); - } -} - -static void -_e_comp_wl_surface_cb_buffer_transform_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int32_t transform EINA_UNUSED) -{ - DBG("Surface Buffer Transform"); -} - -static void -_e_comp_wl_surface_cb_buffer_scale_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int32_t scale EINA_UNUSED) -{ - DBG("Surface Buffer Scale"); -} - -static const struct wl_surface_interface _e_comp_wl_surface_interface = -{ - _e_comp_wl_surface_cb_destroy, - _e_comp_wl_surface_cb_attach, - _e_comp_wl_surface_cb_damage, - _e_comp_wl_surface_cb_frame, - _e_comp_wl_surface_cb_opaque_region_set, - _e_comp_wl_surface_cb_input_region_set, - _e_comp_wl_surface_cb_commit, - _e_comp_wl_surface_cb_buffer_transform_set, - _e_comp_wl_surface_cb_buffer_scale_set -}; - -static void -_e_comp_wl_comp_cb_surface_create(struct wl_client *client, struct wl_resource *resource, uint32_t id) -{ - E_Comp *comp; - E_Pixmap *cp; - struct wl_resource *res; - uint64_t wid; - pid_t pid; - - /* DBG("COMP_WL: Create Surface: %d", id); */ - - if (!(comp = wl_resource_get_user_data(resource))) return; - - res = - e_comp_wl_surface_create(client, wl_resource_get_version(resource), id); - if (!res) - { - wl_resource_post_no_memory(resource); - return; - } - - /* get the client pid and generate a pixmap id */ - wl_client_get_credentials(client, &pid, NULL, NULL); - wid = e_comp_wl_id_get(pid, id); - - /* see if we already have a pixmap for this surface */ - if (!(cp = e_pixmap_find(E_PIXMAP_TYPE_WL, wid))) - { - /* try to create a new pixmap for this surface */ - if (!(cp = e_pixmap_new(E_PIXMAP_TYPE_WL, wid))) - { - wl_resource_destroy(res); - wl_resource_post_no_memory(resource); - return; - } - } - - /* set reference to pixmap so we can fetch it later */ - wl_resource_set_user_data(res, cp); - - /* emit surface create signal */ - wl_signal_emit(&comp->wl_comp_data->signals.surface.create, res); -} - -static void -_e_comp_wl_region_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -_e_comp_wl_region_cb_add(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h) -{ - Eina_Tiler *tiler; - - if ((tiler = wl_resource_get_user_data(resource))) - { - Eina_Tiler *src; - - src = eina_tiler_new(w, h); - eina_tiler_tile_size_set(src, 1, 1); - eina_tiler_rect_add(src, &(Eina_Rectangle){x, y, w, h}); - - eina_tiler_union(tiler, src); - eina_tiler_free(src); - } -} - -static void -_e_comp_wl_region_cb_subtract(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h) -{ - Eina_Tiler *tiler; - - if ((tiler = wl_resource_get_user_data(resource))) - { - Eina_Tiler *src; - - src = eina_tiler_new(w, h); - eina_tiler_tile_size_set(src, 1, 1); - eina_tiler_rect_add(src, &(Eina_Rectangle){x, y, w, h}); - - eina_tiler_subtract(tiler, src); - eina_tiler_free(src); - } -} - -static const struct wl_region_interface _e_region_interface = -{ - _e_comp_wl_region_cb_destroy, - _e_comp_wl_region_cb_add, - _e_comp_wl_region_cb_subtract -}; - -static void -_e_comp_wl_comp_cb_region_destroy(struct wl_resource *resource) -{ - Eina_Tiler *tiler; - - if ((tiler = wl_resource_get_user_data(resource))) - eina_tiler_free(tiler); -} - -static void -_e_comp_wl_comp_cb_region_create(struct wl_client *client, struct wl_resource *resource, uint32_t id) -{ - E_Comp *c; - Eina_Tiler *tiler; - struct wl_resource *res; - - if (!(c = e_comp_get(NULL))) - { - wl_resource_post_no_memory(resource); - return; - } - - if (!(tiler = eina_tiler_new(c->man->w, c->man->h))) - { - wl_resource_post_no_memory(resource); - return; - } - - eina_tiler_tile_size_set(tiler, 1, 1); - eina_tiler_rect_add(tiler, - &(Eina_Rectangle){0, 0, c->man->w, c->man->h}); - - if (!(res = wl_resource_create(client, &wl_region_interface, 1, id))) - { - eina_tiler_free(tiler); - wl_resource_post_no_memory(resource); - return; - } - - wl_resource_set_implementation(res, &_e_region_interface, tiler, - _e_comp_wl_comp_cb_region_destroy); -} - -static void -_e_comp_wl_subcomp_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - wl_resource_destroy(resource); - - E_FREE_LIST(subcomp_handlers, ecore_event_handler_del); -} - -static void -_e_comp_wl_subsurface_restack(E_Client *ec) -{ - E_Client *subc, *below = NULL; - Eina_List *l; - - if (!ec->comp_data->sub.list) return; - - EINA_LIST_REVERSE_FOREACH(ec->comp_data->sub.list, l, subc) - { - if (subc->iconic) continue; - if (below) - evas_object_stack_below(subc->frame, below->frame); - else - evas_object_stack_above(subc->frame, ec->frame); - below = subc; - - if (subc->comp_data->sub.list) - _e_comp_wl_subsurface_restack(subc); - } -} - -static Eina_Bool -_e_comp_wl_client_idler(void *data EINA_UNUSED) -{ - E_Client *ec; - E_Comp *comp; - const Eina_List *l; - - EINA_LIST_FREE(_idle_clients, ec) - { - if ((e_object_is_del(E_OBJECT(ec))) || (!ec->comp_data)) continue; - -// E_COMP_WL_PIXMAP_CHECK continue; - - if ((ec->post_resize) && (!ec->maximized)) - { - if ((ec->comp_data) && (ec->comp_data->shell.configure_send)) - ec->comp_data->shell.configure_send(ec->comp_data->shell.surface, - ec->comp->wl_comp_data->resize.edges, - ec->w, ec->h); - } - - ec->post_move = 0; - ec->post_resize = 0; - - if (ec->comp_data->sub.restack_target) - { - if (ec->layer_block) continue; - - // for blocking evas object restack callback. - restacking = EINA_TRUE; - if (ec->comp_data->sub.restack_target != ec) - evas_object_stack_below(ec->frame, ec->comp_data->sub.restack_target->frame); - _e_comp_wl_subsurface_restack(ec); - ec->comp_data->sub.restack_target = NULL; - restacking = EINA_FALSE; - } - } - - EINA_LIST_FOREACH(e_comp_list(), l, comp) - { - if ((comp->wl_comp_data->restack) && (!comp->new_clients)) - { - e_hints_client_stacking_set(); - comp->wl_comp_data->restack = EINA_FALSE; - } - } - - _client_idler = NULL; - return EINA_FALSE; -} - -static void -_e_comp_wl_client_idler_add(E_Client *ec) -{ - if (!_client_idler) - _client_idler = ecore_idle_enterer_add(_e_comp_wl_client_idler, NULL); - - if (!ec) CRI("ACK!"); - - if (!eina_list_data_find(_idle_clients, ec)) - _idle_clients = eina_list_append(_idle_clients, ec); -} - -static void -_e_comp_wl_evas_cb_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - E_Client *ec; - E_Client *subc; - Eina_List *l; - int x, y; - - if (!(ec = data)) return; - - E_COMP_WL_PIXMAP_CHECK; - - EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc) - { - x = ec->x + subc->comp_data->sub.cdata->position.x; - y = ec->y + subc->comp_data->sub.cdata->position.y; - evas_object_move(subc->frame, x, y); - } - - ec->post_move = EINA_FALSE; - _e_comp_wl_client_idler_add(ec); -} - -static Eina_Bool -_e_comp_wl_cb_client_iconify(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - E_Event_Client *ev; - E_Client *ec, *subc; - Eina_List *l; - - ev = event; - if (!(ec = ev->ec)) return ECORE_CALLBACK_PASS_ON; - - E_COMP_WL_PIXMAP_CHECK ECORE_CALLBACK_PASS_ON; - - if (_e_comp_wl_client_subsurf_data_get(ec)) - { - ec = _e_comp_wl_subsurface_root_get(ec); - if (!ec->iconic) e_client_iconify(ec); - } - - EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc) - { - if (subc->iconic) continue; - e_client_iconify(subc); - } - - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_e_comp_wl_cb_client_uniconify(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - E_Event_Client *ev; - E_Client *ec, *subc; - Eina_List *l; - - ev = event; - if (!(ec = ev->ec)) return ECORE_CALLBACK_PASS_ON; - - E_COMP_WL_PIXMAP_CHECK ECORE_CALLBACK_PASS_ON; - - if (_e_comp_wl_client_subsurf_data_get(ec)) - { - ec = _e_comp_wl_subsurface_root_get(ec); - if (ec->iconic) e_client_uniconify(ec); - } - - EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc) - { - if (!subc->iconic) continue; - e_client_uniconify(subc); - } - - return ECORE_CALLBACK_PASS_ON; -} - -static const struct wl_compositor_interface _e_comp_interface = -{ - _e_comp_wl_comp_cb_surface_create, - _e_comp_wl_comp_cb_region_create -}; - -static void -_e_comp_wl_cb_bind_compositor(struct wl_client *client, void *data, uint32_t version, uint32_t id) -{ - E_Comp *comp; - struct wl_resource *res; - - if (!(comp = data)) return; - - res = - wl_resource_create(client, &wl_compositor_interface, MIN(version, 3), id); - if (!res) - { - wl_client_post_no_memory(client); - return; - } - - wl_resource_set_implementation(res, &_e_comp_interface, comp, NULL); -} - -static void -_e_comp_wl_cb_del(E_Comp *comp) -{ - E_Comp_Data *cdata; - - cdata = comp->wl_comp_data; - - e_comp_wl_data_manager_shutdown(cdata); - e_comp_wl_input_shutdown(cdata); - - /* delete idler to flush clients */ - if (cdata->idler) ecore_idler_del(cdata->idler); - - /* delete fd handler to listen for wayland main loop events */ - if (cdata->fd_hdlr) ecore_main_fd_handler_del(cdata->fd_hdlr); - - /* delete the wayland display */ - if (cdata->wl.disp) wl_display_destroy(cdata->wl.disp); - - free(cdata); -} - -static Eina_Bool -_e_comp_wl_cb_read(void *data, Ecore_Fd_Handler *hdl EINA_UNUSED) -{ - E_Comp_Data *cdata; - - if (!(cdata = data)) return ECORE_CALLBACK_RENEW; - if (!cdata->wl.disp) return ECORE_CALLBACK_RENEW; - - /* flush any pending client events */ - /* wl_display_flush_clients(cdata->wl.disp); */ - - /* dispatch any pending main loop events */ - wl_event_loop_dispatch(cdata->wl.loop, 0); - - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_e_comp_wl_cb_idle(void *data) -{ - E_Comp_Data *cdata; - - if (!(cdata = data)) return ECORE_CALLBACK_RENEW; - if (!cdata->wl.disp) return ECORE_CALLBACK_RENEW; - - /* flush any pending client events */ - wl_display_flush_clients(cdata->wl.disp); - - /* dispatch any pending main loop events */ - /* wl_event_loop_dispatch(cdata->wl.loop, 0); */ - - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_e_comp_wl_cb_module_idle(void *data) -{ - E_Module *mod = NULL; - E_Comp_Data *cdata; - - if (!(cdata = data)) return ECORE_CALLBACK_RENEW; - - if (e_module_loading_get()) return ECORE_CALLBACK_RENEW; - - /* FIXME: make which shell to load configurable */ - if (!(mod = e_module_find("wl_desktop_shell"))) - mod = e_module_new("wl_desktop_shell"); - - if (mod) - { - e_module_enable(mod); - - /* dispatch any pending main loop events */ - wl_event_loop_dispatch(cdata->wl.loop, 0); - - return ECORE_CALLBACK_CANCEL; - } - - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_e_comp_wl_cb_first_draw(void *data) -{ - E_Client *ec; - - if (!(ec = data)) return EINA_TRUE; - ec->comp_data->first_draw_tmr = NULL; - e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h); - return EINA_FALSE; -} - -static void -_e_comp_wl_evas_cb_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - E_Client *ec; - E_Client *parent; - - if (restacking) return; - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - if ((!ec->comp_data->sub.list) && - (!_e_comp_wl_client_subsurf_data_get(ec))) return; - - parent = ec; - if (_e_comp_wl_client_subsurf_data_get(ec)) - parent = _e_comp_wl_subsurface_root_get(ec); - - parent->comp_data->sub.restack_target = ec; - _e_comp_wl_client_idler_add(parent); -} - -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 *sub_cdata; - - if (!(ec = wl_resource_get_user_data(resource))) return; - if (!(sub_cdata = _e_comp_wl_client_subsurf_data_get(ec))) return; - - sub_cdata->position.x = x; - sub_cdata->position.y = y; - sub_cdata->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 *parent; - E_Client *ec; - E_Client *sibling; - - if (!(ec = wl_resource_get_user_data(resource))) return; - if (!(sibling = wl_resource_get_user_data(sibling_resource))) return; - if ((!_e_comp_wl_client_subsurf_data_get(ec)) || - (!_e_comp_wl_client_subsurf_data_get(sibling))) return; - if (_e_comp_wl_subsurface_parent_get(ec) != - _e_comp_wl_subsurface_parent_get(sibling)) return; - if (!(parent = _e_comp_wl_subsurface_parent_get(ec))) 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, sibling); - parent->comp_data->sub.restack_target = parent; - _e_comp_wl_client_idler_add(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 *parent; - E_Client *ec; - E_Client *sibling; - - if (!(ec = wl_resource_get_user_data(resource))) return; - if (!(sibling = wl_resource_get_user_data(sibling_resource))) return; - if ((!_e_comp_wl_client_subsurf_data_get(ec)) || - (!_e_comp_wl_client_subsurf_data_get(sibling))) return; - if (_e_comp_wl_subsurface_parent_get(ec) != - _e_comp_wl_subsurface_parent_get(sibling)) return; - if (!(parent = _e_comp_wl_subsurface_parent_get(ec))) 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, sibling); - parent->comp_data->sub.restack_target = parent; - _e_comp_wl_client_idler_add(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 *sub_cdata; - - if (!(ec = wl_resource_get_user_data(resource))) return; - if (!(sub_cdata = _e_comp_wl_client_subsurf_data_get(ec))) return; - - sub_cdata->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 *sub_cdata; - - if (!(ec = wl_resource_get_user_data(resource))) return; - if (!(sub_cdata = _e_comp_wl_client_subsurf_data_get(ec))) return; - - sub_cdata->synchronized = EINA_FALSE; -} - -static const struct wl_subsurface_interface _e_comp_wl_subsurface_interface = -{ - _e_comp_wl_subsurface_cb_destroy, - _e_comp_wl_subsurface_cb_position_set, - _e_comp_wl_subsurface_cb_place_above, - _e_comp_wl_subsurface_cb_place_below, - _e_comp_wl_subsurface_cb_sync_set, - _e_comp_wl_subsurface_cb_desync_set -}; - -static Eina_Bool -_e_comp_wl_subsurface_create(E_Client *ec, E_Client *pc, uint32_t id, struct wl_resource *surface_resource) -{ - E_Comp_Wl_Subsurf *sub_cdata; - struct wl_client *client; - - if (!(client = wl_resource_get_client(surface_resource))) return EINA_FALSE; - - sub_cdata = E_NEW(E_Comp_Wl_Subsurf, 1); - if (!sub_cdata) return EINA_FALSE; - - sub_cdata->resource = wl_resource_create(client, &wl_subsurface_interface, 1, id); - if (!sub_cdata->resource) - { - free(sub_cdata); - return EINA_FALSE; - } - wl_resource_set_implementation(sub_cdata->resource, - &_e_comp_wl_subsurface_interface, ec, - _e_comp_wl_subsurface_destroy); - - sub_cdata->synchronized = EINA_TRUE; - sub_cdata->parent = pc; - - sub_cdata->cached.damage = eina_tiler_new(1, 1); - eina_tiler_tile_size_set(sub_cdata->cached.damage, 1, 1); - - sub_cdata->cached.input = eina_tiler_new(1, 1); - eina_tiler_tile_size_set(sub_cdata->cached.damage, 1, 1); - - sub_cdata->cached.opaque = eina_tiler_new(1, 1); - eina_tiler_tile_size_set(sub_cdata->cached.damage, 1, 1); - - 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; - ec->comp_data->surface = surface_resource; - ec->comp_data->sub.cdata = sub_cdata; - - evas_object_pass_events_set(ec->frame, EINA_TRUE); - evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESTACK, - _e_comp_wl_evas_cb_restack, ec); - - if (pc) - { - E_Comp_Client_Data *cdata; - - cdata = pc->comp_data; - if (cdata) - cdata->sub.list = eina_list_append(cdata->sub.list, ec); - - evas_object_event_callback_add(pc->frame, EVAS_CALLBACK_MOVE, - _e_comp_wl_evas_cb_move, pc); - evas_object_event_callback_add(pc->frame, EVAS_CALLBACK_RESTACK, - _e_comp_wl_evas_cb_restack, pc); - } - - return EINA_TRUE; -} - -static void -_e_comp_wl_subcomp_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 *pp, *ep; - E_Client *ec, *pc; - static const char where[] = "get_subsurface: wl_subsurface@"; - - if (!(pp = 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 = 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; - } - - if (pp == ep) - { - 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; - } - - if (!(ec = e_pixmap_client_get(ep))) - ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ep)); - - if (!ec) - { - if (!(ec = e_client_new(e_util_comp_current_get(), ep, 1, 0))) - { - wl_resource_post_no_memory(resource); - return; - } - } - else if (_e_comp_wl_client_subsurf_data_get(ec)) - { - 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; - } - - if (!ec->comp_data) - { - e_object_del(E_OBJECT(ec)); - return; - } - - pc = e_pixmap_client_get(pp); - if (!_e_comp_wl_subsurface_create(ec, pc, id, surface_resource)) - { - e_object_del(E_OBJECT(ec)); - return; - } -} - -static const struct wl_subcompositor_interface _e_subcomp_interface = -{ - _e_comp_wl_subcomp_cb_destroy, - _e_comp_wl_subcomp_cb_subsurface_get -}; - -static void -_e_comp_wl_cb_bind_subcompositor(struct wl_client *client, void *data, uint32_t version, uint32_t id) -{ - E_Comp *comp; - struct wl_resource *res; - - if (!(comp = data)) return; - - res = - wl_resource_create(client, &wl_subcompositor_interface, - MIN(version, 1), id); - if (!res) - { - wl_client_post_no_memory(client); - return; - } - - wl_resource_set_implementation(res, &_e_subcomp_interface, comp, NULL); - - E_LIST_HANDLER_APPEND(subcomp_handlers, E_EVENT_CLIENT_ICONIFY, - _e_comp_wl_cb_client_iconify, NULL); - E_LIST_HANDLER_APPEND(subcomp_handlers, E_EVENT_CLIENT_UNICONIFY, - _e_comp_wl_cb_client_uniconify, NULL); -} - -static Eina_Bool -_e_comp_wl_compositor_create(void) -{ - E_Comp *comp; - E_Comp_Data *cdata; - const char *name; - /* char *rules, *model, *layout; */ - int fd = 0; - - /* get the current compositor */ - if (!(comp = e_comp_get(NULL))) - { - comp = e_comp_new(); - comp->comp_type = E_PIXMAP_TYPE_WL; - E_OBJECT_DEL_SET(comp, _e_comp_wl_cb_del); - } - - /* check compositor type and make sure it's Wayland */ - /* if (comp->comp_type != E_PIXMAP_TYPE_WL) return EINA_FALSE; */ - - cdata = E_NEW(E_Comp_Data, 1); - comp->wl_comp_data = cdata; - - /* try to create wayland display */ - if (!(cdata->wl.disp = wl_display_create())) - { - ERR("Could not create a Wayland Display: %m"); - goto disp_err; - } - - if (!(name = wl_display_add_socket_auto(cdata->wl.disp))) - { - ERR("Could not create a Wayland Display: %m"); - goto disp_err; - } - - /* setup wayland display environment variable */ - e_env_set("WAYLAND_DISPLAY", name); - - /* setup wayland compositor signals */ - wl_signal_init(&cdata->signals.surface.create); - wl_signal_init(&cdata->signals.surface.activate); - wl_signal_init(&cdata->signals.surface.kill); - - /* NB: So far, we don't need ANY of these... */ - /* wl_signal_init(&cdata->signals.destroy); */ - /* wl_signal_init(&cdata->signals.activate); */ - /* wl_signal_init(&cdata->signals.transform); */ - /* wl_signal_init(&cdata->signals.kill); */ - /* wl_signal_init(&cdata->signals.idle); */ - /* wl_signal_init(&cdata->signals.wake); */ - /* wl_signal_init(&cdata->signals.session); */ - /* wl_signal_init(&cdata->signals.seat.created); */ - /* wl_signal_init(&cdata->signals.seat.destroyed); */ - /* wl_signal_init(&cdata->signals.seat.moved); */ - /* wl_signal_init(&cdata->signals.output.created); */ - /* wl_signal_init(&cdata->signals.output.destroyed); */ - /* wl_signal_init(&cdata->signals.output.moved); */ - - /* try to add compositor to wayland display globals */ - if (!wl_global_create(cdata->wl.disp, &wl_compositor_interface, 3, - comp, _e_comp_wl_cb_bind_compositor)) - { - ERR("Could not add compositor to globals: %m"); - goto disp_err; - } - - /* try to add subcompositor to wayland display globals */ - if (!wl_global_create(cdata->wl.disp, &wl_subcompositor_interface, 1, - comp, _e_comp_wl_cb_bind_subcompositor)) - { - ERR("Could not add compositor to globals: %m"); - goto disp_err; - } - - /* try to init data manager */ - if (!e_comp_wl_data_manager_init(cdata)) - { - ERR("Could not initialize data manager"); - goto disp_err; - } - - /* try to init input (keyboard & pointer) */ - if (!e_comp_wl_input_init(cdata)) - { - ERR("Could not initialize input"); - goto disp_err; - } - -/* #ifndef HAVE_WAYLAND_ONLY */ -/* if (getenv("DISPLAY")) */ -/* { */ -/* E_Config_XKB_Layout *ekbd; */ -/* Ecore_X_Atom xkb = 0; */ -/* Ecore_X_Window root = 0; */ -/* int len = 0; */ -/* unsigned char *dat; */ - -/* if ((ekbd = e_xkb_layout_get())) */ -/* { */ -/* model = strdup(ekbd->model); */ -/* layout = strdup(ekbd->name); */ -/* } */ - -/* root = ecore_x_window_root_first_get(); */ -/* xkb = ecore_x_atom_get("_XKB_RULES_NAMES"); */ -/* ecore_x_window_prop_property_get(root, xkb, ECORE_X_ATOM_STRING, */ -/* 1024, &dat, &len); */ -/* if ((dat) && (len > 0)) */ -/* { */ -/* rules = (char *)dat; */ -/* dat += strlen((const char *)dat) + 1; */ -/* if (!model) model = strdup((const char *)dat); */ -/* dat += strlen((const char *)dat) + 1; */ -/* if (!layout) layout = strdup((const char *)dat); */ -/* } */ -/* } */ -/* #endif */ - - /* fallback */ - /* if (!rules) rules = strdup("evdev"); */ - /* if (!model) model = strdup("pc105"); */ - /* if (!layout) layout = strdup("us"); */ - - /* update compositor keymap */ - /* e_comp_wl_input_keymap_set(cdata, rules, model, layout); */ - - /* TODO: init text backend */ - - /* initialize shm mechanism */ - wl_display_init_shm(cdata->wl.disp); - - /* check for gl rendering */ - if ((e_comp_gl_get()) && - (e_comp_config_get()->engine == E_COMP_ENGINE_GL)) - { - /* TODO: setup gl ? */ - } - - /* get the wayland display's event loop */ - cdata->wl.loop= wl_display_get_event_loop(cdata->wl.disp); - - /* get the file descriptor of the main loop */ - fd = wl_event_loop_get_fd(cdata->wl.loop); - - /* add an fd handler to listen for wayland main loop events */ - cdata->fd_hdlr = - ecore_main_fd_handler_add(fd, ECORE_FD_READ | ECORE_FD_WRITE, - _e_comp_wl_cb_read, cdata, NULL, NULL); - - /* add an idler to flush clients */ - cdata->idler = ecore_idle_enterer_add(_e_comp_wl_cb_idle, cdata); - - /* setup module idler to load shell module */ - ecore_idler_add(_e_comp_wl_cb_module_idle, cdata); - - if (comp->comp_type == E_PIXMAP_TYPE_X) - { - e_comp_wl_input_pointer_enabled_set(comp->wl_comp_data, EINA_TRUE); - e_comp_wl_input_keyboard_enabled_set(comp->wl_comp_data, EINA_TRUE); - } - - return EINA_TRUE; - -disp_err: - e_env_unset("WAYLAND_DISPLAY"); - return EINA_FALSE; -} - -static void -_e_comp_wl_client_priority_adjust(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_child, Eina_Bool do_child) -{ - int n; - - n = set; - if (use_adj) n = (getpriority(PRIO_PROCESS, pid) + adj); - setpriority(PRIO_PROCESS, pid, n); - - if (do_child) - { - Eina_List *files; - char *file, buff[PATH_MAX]; - FILE *f; - int pid2, ppid; - - files = ecore_file_ls("/proc"); - EINA_LIST_FREE(files, file) - { - if (isdigit(file[0])) - { - snprintf(buff, sizeof(buff), "/proc/%s/stat", file); - if ((f = fopen(buff, "r"))) - { - pid2 = -1; - ppid = -1; - if (fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid) == 2) - { - fclose(f); - if (ppid == pid) - { - if (adj_child) - _e_comp_wl_client_priority_adjust(pid2, set, - adj, EINA_TRUE, - adj_child, do_child); - else - _e_comp_wl_client_priority_adjust(pid2, set, - adj, use_adj, - adj_child, do_child); - } - } - else - fclose(f); - } - } - free(file); - } - } -} - -static void -_e_comp_wl_client_priority_raise(E_Client *ec) -{ - if (ec->netwm.pid <= 0) return; - if (ec->netwm.pid == getpid()) return; - _e_comp_wl_client_priority_adjust(ec->netwm.pid, - e_config->priority - 1, -1, - EINA_FALSE, EINA_TRUE, EINA_FALSE); -} - -static void -_e_comp_wl_client_priority_normal(E_Client *ec) -{ - if (ec->netwm.pid <= 0) return; - if (ec->netwm.pid == getpid()) return; - _e_comp_wl_client_priority_adjust(ec->netwm.pid, e_config->priority, 1, - EINA_FALSE, EINA_TRUE, EINA_FALSE); -} - -static void -_e_comp_wl_evas_cb_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) -{ - E_Client *ec, *tmp; - Eina_List *l; - - if (!(ec = data)) return; - - E_COMP_WL_PIXMAP_CHECK; - - if (!ec->override) - e_hints_window_visible_set(ec); - - if (ec->comp_data->frame_update) - ec->comp_data->frame_update = EINA_FALSE; - - EINA_LIST_FOREACH(ec->e.state.video_child, l, tmp) - evas_object_show(tmp->frame); -} - -static void -_e_comp_wl_evas_cb_hide(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) -{ - E_Client *ec, *tmp; - Eina_List *l; - - if (!(ec = data)) return; - - EINA_LIST_FOREACH(ec->e.state.video_child, l, tmp) - evas_object_hide(tmp->frame); -} - -static void -_e_comp_wl_evas_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Client *ec; - Evas_Event_Mouse_In *ev; - struct wl_resource *res; - struct wl_client *wc; - Eina_List *l; - uint32_t serial; - - ev = event; - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - if (e_object_is_del(E_OBJECT(ec))) return; - - wc = wl_resource_get_client(ec->comp_data->surface); - serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp); - EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res) - { - if (!e_comp_wl_input_pointer_check(res)) continue; - if (wl_resource_get_client(res) != wc) continue; - wl_pointer_send_enter(res, serial, ec->comp_data->surface, - wl_fixed_from_int(ev->canvas.x), - wl_fixed_from_int(ev->canvas.y)); - } -} - -static void -_e_comp_wl_evas_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) -{ - E_Client *ec; - struct wl_resource *res; - struct wl_client *wc; - Eina_List *l; - uint32_t serial; - - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - if (ec->cur_mouse_action) return; - if (e_object_is_del(E_OBJECT(ec))) return; - - wc = wl_resource_get_client(ec->comp_data->surface); - serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp); - EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res) - { - if (!e_comp_wl_input_pointer_check(res)) continue; - if (wl_resource_get_client(res) != wc) continue; - wl_pointer_send_leave(res, serial, ec->comp_data->surface); - } -} - -static void -_e_comp_wl_evas_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Client *ec; - Evas_Event_Mouse_Down *ev; - struct wl_resource *res; - struct wl_client *wc; - Eina_List *l; - uint32_t serial, btn; - - ev = event; - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - if (ec->cur_mouse_action) return; - if (e_object_is_del(E_OBJECT(ec))) return; - if (e_client_util_ignored_get(ec)) return; - - switch (ev->button) - { - case 1: - btn = BTN_LEFT; - break; - case 2: - btn = BTN_MIDDLE; - break; - case 3: - btn = BTN_RIGHT; - break; - default: - btn = ev->button; - break; - } - - ec->comp->wl_comp_data->ptr.button = btn; - - wc = wl_resource_get_client(ec->comp_data->surface); - serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp); - EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res) - { - if (!e_comp_wl_input_pointer_check(res)) continue; - if (wl_resource_get_client(res) != wc) continue; - wl_pointer_send_button(res, serial, ev->timestamp, btn, - WL_POINTER_BUTTON_STATE_PRESSED); - } -} - -static void -_e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Client *ec; - Evas_Event_Mouse_Up *ev; - struct wl_resource *res; - struct wl_client *wc; - Eina_List *l; - uint32_t serial, btn; - - ev = event; - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - if (ec->cur_mouse_action) return; - if (e_object_is_del(E_OBJECT(ec))) return; - if (e_client_util_ignored_get(ec)) return; - - switch (ev->button) - { - case 1: - btn = BTN_LEFT; - break; - case 2: - btn = BTN_MIDDLE; - break; - case 3: - btn = BTN_RIGHT; - break; - default: - btn = ev->button; - break; - } - - ec->comp->wl_comp_data->resize.edges = 0; - ec->comp->wl_comp_data->resize.resource = NULL; - ec->comp->wl_comp_data->ptr.button = btn; - - wc = wl_resource_get_client(ec->comp_data->surface); - serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp); - EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res) - { - if (!e_comp_wl_input_pointer_check(res)) continue; - if (wl_resource_get_client(res) != wc) continue; - wl_pointer_send_button(res, serial, ev->timestamp, btn, - WL_POINTER_BUTTON_STATE_RELEASED); - } -} - -static void -_e_comp_wl_evas_cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Client *ec; - Evas_Event_Mouse_Wheel *ev; - struct wl_resource *res; - struct wl_client *wc; - Eina_List *l; - uint32_t axis, dir; - - ev = event; - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - if (ec->cur_mouse_action) return; - if (e_object_is_del(E_OBJECT(ec))) return; - if (e_client_util_ignored_get(ec)) return; - - if (ev->direction == 0) - axis = WL_POINTER_AXIS_VERTICAL_SCROLL; - else - axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL; - - if (ev->z < 0) - dir = -wl_fixed_from_int(abs(ev->z)); - else - dir = wl_fixed_from_int(ev->z); - - wc = wl_resource_get_client(ec->comp_data->surface); - EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res) - { - if (!e_comp_wl_input_pointer_check(res)) continue; - if (wl_resource_get_client(res) != wc) continue; - wl_pointer_send_axis(res, ev->timestamp, axis, dir); - } -} - -static void -_e_comp_wl_evas_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Client *ec; - Evas_Event_Mouse_Move *ev; - struct wl_resource *res; - struct wl_client *wc; - Eina_List *l; - - ev = event; - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - if (ec->cur_mouse_action) return; - if (e_object_is_del(E_OBJECT(ec))) return; - if (e_client_util_ignored_get(ec)) return; - - ec->comp->wl_comp_data->ptr.x = - wl_fixed_from_int(ev->cur.canvas.x - ec->client.x); - ec->comp->wl_comp_data->ptr.y = - wl_fixed_from_int(ev->cur.canvas.y - ec->client.y); - - wc = wl_resource_get_client(ec->comp_data->surface); - EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res) - { - if (!e_comp_wl_input_pointer_check(res)) continue; - if (wl_resource_get_client(res) != wc) continue; - wl_pointer_send_motion(res, ev->timestamp, - ec->comp->wl_comp_data->ptr.x, - ec->comp->wl_comp_data->ptr.y); - } -} - -static void -_e_comp_wl_evas_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Client *ec; - E_Comp_Data *cdata; - Evas_Event_Key_Down *ev; - uint32_t serial, *end, *k, keycode; - struct wl_resource *res; - struct wl_client *wc; - Eina_List *l; - - ev = event; - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - if (e_object_is_del(E_OBJECT(ec))) return; - - if (!ec->focused) return; - - keycode = (ev->keycode - 8); - if (!(cdata = ec->comp->wl_comp_data)) return; - - end = (uint32_t *)cdata->kbd.keys.data + (cdata->kbd.keys.size / sizeof(*k)); - - for (k = cdata->kbd.keys.data; k < end; k++) - { - /* ignore server-generated key repeats */ - if (*k == keycode) return; - } - - cdata->kbd.keys.size = (const char *)end - (const char *)cdata->kbd.keys.data; - k = wl_array_add(&cdata->kbd.keys, sizeof(*k)); - *k = keycode; - - /* update modifier state */ - e_comp_wl_input_keyboard_state_update(cdata, keycode, EINA_TRUE); - - wc = wl_resource_get_client(ec->comp_data->surface); - serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp); - EINA_LIST_FOREACH(ec->comp->wl_comp_data->kbd.resources, l, res) - { - if (wl_resource_get_client(res) != wc) continue; - wl_keyboard_send_key(res, serial, ev->timestamp, - keycode, WL_KEYBOARD_KEY_STATE_PRESSED); - } -} - -static void -_e_comp_wl_evas_cb_key_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Client *ec; - E_Comp_Data *cdata; - Evas_Event_Key_Up *ev; - uint32_t serial, *end, *k, keycode; - struct wl_resource *res; - struct wl_client *wc; - Eina_List *l; - - ev = event; - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - if (e_object_is_del(E_OBJECT(ec))) return; - - if (!ec->focused) return; - - keycode = (ev->keycode - 8); - if (!(cdata = ec->comp->wl_comp_data)) return; - - end = (uint32_t *)cdata->kbd.keys.data + (cdata->kbd.keys.size / sizeof(*k)); - for (k = cdata->kbd.keys.data; k < end; k++) - if (*k == keycode) *k = *--end; - - cdata->kbd.keys.size = (const char *)end - (const char *)cdata->kbd.keys.data; - - wc = wl_resource_get_client(ec->comp_data->surface); - serial = wl_display_next_serial(cdata->wl.disp); - EINA_LIST_FOREACH(cdata->kbd.resources, l, res) - { - if (wl_resource_get_client(res) != wc) continue; - wl_keyboard_send_key(res, serial, ev->timestamp, - keycode, WL_KEYBOARD_KEY_STATE_RELEASED); - } - - /* update modifier state */ - e_comp_wl_input_keyboard_state_update(cdata, keycode, EINA_FALSE); -} - -static void -_e_comp_wl_evas_cb_focus_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) -{ - E_Client *ec, *focused; - E_Comp_Data *cdata; - struct wl_resource *res; - struct wl_client *wc; - Eina_List *l; - uint32_t serial, *k; - - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - if (e_object_is_del(E_OBJECT(ec))) return; - - /* block refocus attempts on iconic clients - * these result from iconifying a client during a grab */ - if (ec->iconic) return; - - /* block spurious focus events - * not sure if correct, but seems necessary to use pointer focus... */ - focused = e_client_focused_get(); - if (focused && (ec != focused)) return; - - cdata = ec->comp->wl_comp_data; - - /* priority raise */ - _e_comp_wl_client_priority_raise(ec); - - /* update modifier state */ - wl_array_for_each(k, &cdata->kbd.keys) - e_comp_wl_input_keyboard_state_update(cdata, *k, EINA_TRUE); - - wc = wl_resource_get_client(ec->comp_data->surface); - serial = wl_display_next_serial(cdata->wl.disp); - EINA_LIST_FOREACH(cdata->kbd.resources, l, res) - { - if (wl_resource_get_client(res) != wc) continue; - wl_keyboard_send_enter(res, serial, ec->comp_data->surface, - &cdata->kbd.keys); - } -} - -static void -_e_comp_wl_evas_cb_focus_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) -{ - E_Client *ec; - struct wl_resource *res; - struct wl_client *wc; - Eina_List *l; - uint32_t serial, *k; - - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - if (e_object_is_del(E_OBJECT(ec))) return; - - /* priority normal */ - _e_comp_wl_client_priority_normal(ec); - - /* update modifier state */ - wl_array_for_each(k, &ec->comp->wl_comp_data->kbd.keys) - e_comp_wl_input_keyboard_state_update(ec->comp->wl_comp_data, *k, EINA_FALSE); - - wc = wl_resource_get_client(ec->comp_data->surface); - serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp); - EINA_LIST_FOREACH(ec->comp->wl_comp_data->kbd.resources, l, res) - { - if (wl_resource_get_client(res) != wc) continue; - wl_keyboard_send_leave(res, serial, ec->comp_data->surface); - } -} - -static void -_e_comp_wl_evas_cb_resize(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) -{ - E_Client *ec; - - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - if ((ec->shading) || (ec->shaded)) return; - if (!e_pixmap_size_changed(ec->pixmap, ec->client.w, ec->client.h)) - return; - - /* DBG("COMP_WL: Evas Resize: %d %d", ec->client.w, ec->client.h); */ - - ec->post_resize = EINA_TRUE; - e_pixmap_dirty(ec->pixmap); - e_comp_object_render_update_del(ec->frame); - _e_comp_wl_client_idler_add(ec); -} - -static void -_e_comp_wl_evas_cb_frame_recalc(void *data, Evas_Object *obj, void *event EINA_UNUSED) -{ - E_Client *ec; - - if (!(ec = data)) return; - - E_COMP_WL_PIXMAP_CHECK; - if (evas_object_visible_get(obj)) - ec->comp_data->frame_update = EINA_FALSE; - else - ec->comp_data->frame_update = EINA_TRUE; - ec->post_move = ec->post_resize = EINA_TRUE; - _e_comp_wl_client_idler_add(ec); -} - -/* static void */ -/* _e_comp_wl_evas_cb_comp_hidden(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) */ -/* { */ -/* E_Client *ec; */ - -/* if (!(ec = data)) return; */ -/* #warning FIXME Implement Evas Comp Hidden */ -/* } */ - -static void -_e_comp_wl_evas_cb_delete_request(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) -{ - E_Client *ec; - E_Comp *comp; - - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - if (ec->netwm.ping) e_client_ping(ec); - - /* FIXME !!! - * - * This is a HUGE problem for internal windows... - * - * IF we delete the client here, then we cannot reopen some internal - * dialogs (configure, etc, etc) ... - * - * BUT, if we don't handle delete_request Somehow, then the close button on - * the frame does Nothing - * - */ - - comp = ec->comp; - - e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap)); - if (ec->comp_data) - { - if (ec->comp_data->reparented) - e_client_comp_hidden_set(ec, EINA_TRUE); - } - - evas_object_pass_events_set(ec->frame, EINA_TRUE); - if (ec->visible) evas_object_hide(ec->frame); - if (!ec->internal) e_object_del(E_OBJECT(ec)); - - _e_comp_wl_focus_check(comp); - - /* TODO: Delete request send ?? - * NB: No such animal wrt wayland */ -} - -static void -_e_comp_wl_evas_cb_kill_request(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) -{ - E_Client *ec; - E_Comp *comp; - - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - /* if (ec->netwm.ping) e_client_ping(ec); */ - - comp = ec->comp; - - e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap)); - if (ec->comp_data) - { - if (ec->comp_data->reparented) - e_client_comp_hidden_set(ec, EINA_TRUE); - } - - evas_object_pass_events_set(ec->frame, EINA_TRUE); - if (ec->visible) evas_object_hide(ec->frame); - if (!ec->internal) e_object_del(E_OBJECT(ec)); - - _e_comp_wl_focus_check(comp); -} - -static void -_e_comp_wl_evas_cb_ping(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) -{ - E_Client *ec; - - if (!(ec = data)) return; - - E_COMP_WL_PIXMAP_CHECK; - if (ec->comp_data->shell.ping) - { - if (ec->comp_data->shell.surface) - ec->comp_data->shell.ping(ec->comp_data->shell.surface); - } -} - -static void -_e_comp_wl_evas_cb_color_set(void *data, Evas_Object *obj, void *event EINA_UNUSED) -{ - E_Client *ec; - int a = 0; - - if (!(ec = data)) return; - E_COMP_WL_PIXMAP_CHECK; - evas_object_color_get(obj, NULL, NULL, NULL, &a); - if (ec->netwm.opacity == a) return; - ec->netwm.opacity = a; - ec->netwm.opacity_changed = EINA_TRUE; - _e_comp_wl_client_idler_add(ec); -} - -static void -_e_comp_wl_client_evas_init(E_Client *ec) -{ - if (ec->comp_data->evas_init) return; - ec->comp_data->evas_init = EINA_TRUE; - - evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW, - _e_comp_wl_evas_cb_show, ec); - evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE, - _e_comp_wl_evas_cb_hide, ec); - - /* we need to hook evas mouse events for wayland clients */ - evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_IN, - _e_comp_wl_evas_cb_mouse_in, ec); - evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_OUT, - _e_comp_wl_evas_cb_mouse_out, ec); - evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_DOWN, - _e_comp_wl_evas_cb_mouse_down, ec); - evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_UP, - _e_comp_wl_evas_cb_mouse_up, ec); - evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_WHEEL, - _e_comp_wl_evas_cb_mouse_wheel, ec); - evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_MOVE, - _e_comp_wl_evas_cb_mouse_move, ec); - - evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_KEY_DOWN, - _e_comp_wl_evas_cb_key_down, ec); - evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_KEY_UP, - _e_comp_wl_evas_cb_key_up, ec); - - evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_FOCUS_IN, - _e_comp_wl_evas_cb_focus_in, ec); - evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_FOCUS_OUT, - _e_comp_wl_evas_cb_focus_out, ec); - - if (!ec->override) - { - evas_object_smart_callback_add(ec->frame, "client_resize", - _e_comp_wl_evas_cb_resize, ec); - } - - evas_object_smart_callback_add(ec->frame, "frame_recalc_done", - _e_comp_wl_evas_cb_frame_recalc, ec); - evas_object_smart_callback_add(ec->frame, "delete_request", - _e_comp_wl_evas_cb_delete_request, ec); - evas_object_smart_callback_add(ec->frame, "kill_request", - _e_comp_wl_evas_cb_kill_request, ec); - evas_object_smart_callback_add(ec->frame, "ping", - _e_comp_wl_evas_cb_ping, ec); - evas_object_smart_callback_add(ec->frame, "color_set", - _e_comp_wl_evas_cb_color_set, ec); - - /* TODO: these will need to send_configure */ - /* evas_object_smart_callback_add(ec->frame, "fullscreen_zoom", */ - /* _e_comp_wl_evas_cb_resize, ec); */ - /* evas_object_smart_callback_add(ec->frame, "unfullscreen_zoom", */ - /* _e_comp_wl_evas_cb_resize, ec); */ -} - -static Eina_Bool -_e_comp_wl_client_new_helper(E_Client *ec) -{ - /* FIXME: No Way to get "initial attributes" of a wayland window */ - ec->border_size = 0; - - ec->placed |= ec->override; - ec->icccm.accepts_focus = ((!ec->override) && (!ec->input_only)); - - if ((ec->override) && ((ec->x == -77) && (ec->y == -777))) - { - e_comp_ignore_win_add(E_PIXMAP_TYPE_WL, e_client_util_win_get(ec)); - e_object_del(E_OBJECT(ec)); - return EINA_FALSE; - } - - if ((!e_client_util_ignored_get(ec)) && - (!ec->internal) && (!ec->internal_ecore_evas)) - { - ec->comp_data->need_reparent = EINA_TRUE; - EC_CHANGED(ec); - ec->take_focus = !starting; - } - - ec->new_client ^= ec->override; - - if (e_pixmap_size_changed(ec->pixmap, ec->client.w, ec->client.h)) - { - ec->changes.size = EINA_TRUE; - EC_CHANGED(ec); - } - - return EINA_TRUE; -} - -static Eina_Bool -_e_comp_wl_client_shape_check(E_Client *ec) -{ - /* FIXME: need way to determine if shape has changed */ - ec->shape_changed = EINA_TRUE; - e_comp_shape_queue(ec->comp); - return EINA_TRUE; -} - -static Eina_Bool -_e_comp_wl_cb_comp_object_add(void *data EINA_UNUSED, int type EINA_UNUSED, E_Event_Comp_Object *ev) -{ - E_Client *ec; - - ec = e_comp_object_client_get(ev->comp_object); - - /* NB: Don't check re_manage here as we need evas events for mouse */ - if ((!ec) || (e_object_is_del(E_OBJECT(ec)))) - return ECORE_CALLBACK_RENEW; - - E_COMP_WL_PIXMAP_CHECK ECORE_CALLBACK_RENEW; - - _e_comp_wl_client_evas_init(ec); - - return ECORE_CALLBACK_RENEW; -} - -/* static Eina_Bool */ -/* _e_comp_wl_cb_client_zone_set(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) */ -/* { */ -/* E_Event_Client *ev; */ -/* E_Client *ec; */ - -/* DBG("CLIENT ZONE SET !!!"); */ - -/* ev = event; */ -/* if (!(ec = ev->ec)) return ECORE_CALLBACK_RENEW; */ -/* if (e_object_is_del(E_OBJECT(ec))) return ECORE_CALLBACK_RENEW; */ -/* E_COMP_WL_PIXMAP_CHECK ECORE_CALLBACK_RENEW; */ - -/* DBG("\tClient Zone: %d", (ec->zone != NULL)); */ - -/* return ECORE_CALLBACK_RENEW; */ -/* } */ - -static Eina_Bool -_e_comp_wl_cb_client_prop(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - E_Client *ec; - E_Event_Client_Property *ev; - - ev = event; - /* if (!(ev->property & E_CLIENT_PROPERTY_ICON)) return ECORE_CALLBACK_RENEW; */ - - ec = ev->ec; - E_COMP_WL_PIXMAP_CHECK ECORE_CALLBACK_RENEW; - - if (ec->desktop) - { - if (!ec->exe_inst) e_exec_phony(ec); - } - - return ECORE_CALLBACK_RENEW; -} - -static void -_e_comp_wl_cb_hook_client_move_end(void *data EINA_UNUSED, E_Client *ec) -{ - E_COMP_WL_PIXMAP_CHECK; - - /* DBG("COMP_WL HOOK CLIENT MOVE END !!"); */ - - /* unset pointer */ - /* e_pointer_type_pop(e_comp_get(ec)->pointer, ec, "move"); */ - - /* ec->post_move = EINA_TRUE; */ - /* _e_comp_wl_client_idler_add(ec); */ -} - -static void -_e_comp_wl_cb_hook_client_del(void *data EINA_UNUSED, E_Client *ec) -{ - uint64_t win; - - E_COMP_WL_PIXMAP_CHECK; - - if ((!ec->already_unparented) && (ec->comp_data->reparented)) - _e_comp_wl_focus_down_set(ec); - - ec->already_unparented = EINA_TRUE; - win = e_pixmap_window_get(ec->pixmap); - eina_hash_del_by_key(clients_win_hash, &win); - - if (ec->comp_data->pending.damage) - eina_tiler_free(ec->comp_data->pending.damage); - if (ec->comp_data->pending.input) - eina_tiler_free(ec->comp_data->pending.input); - if (ec->comp_data->pending.opaque) - eina_tiler_free(ec->comp_data->pending.opaque); - - if (ec->comp_data->reparented) - { - win = e_client_util_pwin_get(ec); - eina_hash_del_by_key(clients_win_hash, &win); - e_pixmap_parent_window_set(ec->pixmap, 0); - } - - if ((ec->parent) && (ec->parent->modal == ec)) - { - ec->parent->lock_close = EINA_FALSE; - ec->parent->modal = NULL; - } - - if (ec->comp_data->sub.list) - { - E_Client *subc; - - EINA_LIST_FREE(ec->comp_data->sub.list, subc) - _e_comp_wl_subsurface_destroy_internal(subc); - } - - E_FREE_FUNC(ec->comp_data->first_draw_tmr, ecore_timer_del); - - E_FREE(ec->comp_data); - ec->comp_data = NULL; - - _e_comp_wl_focus_check(ec->comp); -} - -static void -_e_comp_wl_cb_hook_client_new(void *data EINA_UNUSED, E_Client *ec) -{ - uint64_t win; - - E_COMP_WL_PIXMAP_CHECK; - - win = e_pixmap_window_get(ec->pixmap); - ec->ignored = e_comp_ignore_win_find(win); - - /* NB: could not find a better place to do this, BUT for internal windows, - * we need to set delete_request else the close buttons on the frames do - * basically nothing */ - if (ec->internal) ec->icccm.delete_request = EINA_TRUE; - - ec->comp_data = E_NEW(E_Comp_Client_Data, 1); - - ec->comp_data->pending.damage = eina_tiler_new(ec->w, ec->h); - eina_tiler_tile_size_set(ec->comp_data->pending.damage, 1, 1); - - ec->comp_data->pending.input = eina_tiler_new(ec->w, ec->h); - eina_tiler_tile_size_set(ec->comp_data->pending.input, 1, 1); - - ec->comp_data->pending.opaque = eina_tiler_new(ec->w, ec->h); - eina_tiler_tile_size_set(ec->comp_data->pending.opaque, 1, 1); - - ec->comp_data->pending.buffer_destroy.notify = - _e_comp_wl_buffer_pending_cb_destroy; - - ec->comp_data->mapped = EINA_FALSE; - ec->changes.shape = EINA_TRUE; - ec->changes.shape_input = EINA_TRUE; - - if (!_e_comp_wl_client_new_helper(ec)) return; - - ec->comp_data->first_damage = ec->internal; - /* ec->comp_data->first_damage = ((ec->internal) || (ec->override)); */ - - eina_hash_add(clients_win_hash, &win, ec); - e_hints_client_list_set(); - - ec->comp_data->first_draw_tmr = - ecore_timer_add(e_comp_config_get()->first_draw_delay, - _e_comp_wl_cb_first_draw, ec); -} - -static void -_e_comp_wl_cb_hook_client_eval_fetch(void *data EINA_UNUSED, E_Client *ec) -{ - E_Event_Client_Property *ev; - Eina_Bool move = EINA_FALSE; - Eina_Bool resize = EINA_FALSE; - int x, y, w, h; - - E_COMP_WL_PIXMAP_CHECK; - - if ((ec->changes.prop) && (ec->netwm.fetch.state)) - { - e_hints_window_state_get(ec); - ec->netwm.fetch.state = EINA_FALSE; - } - - if ((ec->changes.prop) && (ec->e.fetch.state)) - { - e_hints_window_e_state_get(ec); - ec->e.fetch.state = EINA_FALSE; - } - - if ((ec->changes.prop) && (ec->netwm.fetch.type)) - { - e_hints_window_type_get(ec); - if (((!ec->lock_border) || (!ec->border.name)) && - (ec->comp_data->reparented)) - { - ec->border.changed = EINA_TRUE; - EC_CHANGED(ec); - } - - if ((ec->netwm.type == E_WINDOW_TYPE_DOCK) || (ec->tooltip)) - { - if (!ec->netwm.state.skip_pager) - { - ec->netwm.state.skip_pager = EINA_TRUE; - ec->netwm.update.state = EINA_TRUE; - } - if (!ec->netwm.state.skip_taskbar) - { - ec->netwm.state.skip_taskbar = EINA_TRUE; - ec->netwm.update.state = EINA_TRUE; - } - } - else if (ec->netwm.type == E_WINDOW_TYPE_DESKTOP) - { - ec->focus_policy_override = E_FOCUS_CLICK; - if (!ec->netwm.state.skip_pager) - { - ec->netwm.state.skip_pager = EINA_TRUE; - ec->netwm.update.state = EINA_TRUE; - } - if (!ec->netwm.state.skip_taskbar) - { - ec->netwm.state.skip_taskbar = EINA_TRUE; - ec->netwm.update.state = EINA_TRUE; - } - if (!e_client_util_ignored_get(ec)) - ec->border.changed = ec->borderless = EINA_TRUE; - } - else if ((ec->netwm.type == E_WINDOW_TYPE_MENU) || - (ec->netwm.type == E_WINDOW_TYPE_POPUP_MENU) || - (ec->netwm.type == E_WINDOW_TYPE_DROPDOWN_MENU)) - { - ec->netwm.state.skip_pager = EINA_TRUE; - ec->netwm.update.state = EINA_TRUE; - ec->netwm.state.skip_taskbar = EINA_TRUE; - ec->netwm.update.state = EINA_TRUE; - ec->focus_policy_override = E_FOCUS_CLICK; - ec->icccm.accepts_focus = EINA_FALSE; - eina_stringshare_replace(&ec->bordername, "borderless"); - } - - if (ec->tooltip) - { - ec->focus_policy_override = E_FOCUS_CLICK; - ec->icccm.accepts_focus = EINA_FALSE; - eina_stringshare_replace(&ec->bordername, "borderless"); - } - else if (ec->internal) - { - Ecore_Wl_Window *wwin; - - DBG("CLIENT EVAL INTERNAL WINDOW"); - - /* FIXME: BORDERLESS INTERNAL OVERRIDE WINDOWS - * - * ie: logout window */ - wwin = ecore_evas_wayland_window_get(ec->internal_ecore_evas); - if (ec->dialog) - { - Ecore_Wl_Window *pwin; - - pwin = ecore_evas_wayland_window_get(ec->comp->ee); - ecore_wl_window_parent_set(wwin, pwin); - } - else - ecore_wl_window_parent_set(wwin, NULL); - } - - ev = E_NEW(E_Event_Client_Property, 1); - - ev->ec = ec; - e_object_ref(E_OBJECT(ec)); - ev->property = E_CLIENT_PROPERTY_NETWM_STATE; - ecore_event_add(E_EVENT_CLIENT_PROPERTY, ev, - _e_comp_wl_client_event_free, NULL); - - ec->netwm.fetch.type = EINA_FALSE; - } - - /* TODO: vkbd, etc */ - - /* FIXME: Update ->changes.shape code for recent switch to eina_tiler */ - - if ((ec->changes.prop) && (ec->netwm.update.state)) - { - e_hints_window_state_set(ec); - if (((!ec->lock_border) || (!ec->border.name)) && - (!(((ec->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))) && - (ec->comp_data->reparented)) - { - ec->border.changed = EINA_TRUE; - EC_CHANGED(ec); - } - - if (ec->parent) - { - if (ec->netwm.state.modal) - { - ec->parent->modal = ec; - if (ec->parent->focused) - evas_object_focus_set(ec->frame, EINA_TRUE); - } - } - else if (ec->leader) - { - if (ec->netwm.state.modal) - { - ec->leader->modal = ec; - if (ec->leader->focused) - evas_object_focus_set(ec->frame, EINA_TRUE); - else - { - Eina_List *l; - E_Client *child; - - EINA_LIST_FOREACH(ec->leader->group, l, child) - { - if ((child != ec) && (child->focused)) - evas_object_focus_set(ec->frame, EINA_TRUE); - } - } - } - } - ec->netwm.update.state = EINA_FALSE; - } - - x = ec->x; - y = ec->y; - w = ec->client.w; - h = ec->client.h; - - if ((ec->changes.pos) && (!ec->lock_client_location)) - { - int zx, zy, zw, zh; - - e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh); - - if (e_config->screen_limits == E_SCREEN_LIMITS_WITHIN) - { - x = E_CLAMP(ec->x, zx, zx + zw - ec->w); - y = E_CLAMP(ec->y, zy, zy + zh - ec->h); - } - } - - e_comp_object_frame_wh_adjust(ec->frame, w, h, &w, &h); - move = ((x != ec->x) || (y != ec->y)); - resize = ((w != ec->w) || (h != ec->h)); - - if ((move) && (!ec->lock_client_location)) - { - if ((ec->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE) - { - E_Zone *zone; - - ec->saved.x = x; - ec->saved.y = y; - - zone = e_comp_zone_xy_get(ec->comp, x, y); - if (zone && ((zone->x) || (zone->y))) - { - ec->saved.x -= zone->x; - ec->saved.y -= zone->y; - } - } - else - { - /* client is completely outside the screen, policy does not allow */ - if (((!E_INTERSECTS(x, y, ec->w, ec->h, ec->comp->man->x, ec->comp->man->y, ec->comp->man->w - 5, ec->comp->man->h - 5)) && - (e_config->screen_limits != E_SCREEN_LIMITS_COMPLETELY)) || - /* client is partly outside the zone, policy does not allow */ - (((!E_INSIDE(x, y, ec->comp->man->x, ec->comp->man->y, ec->comp->man->w - 5, ec->comp->man->h - 5)) && - (!E_INSIDE(x + ec->w, y, ec->comp->man->x, ec->comp->man->y, ec->comp->man->w - 5, ec->comp->man->h - 5)) && - (!E_INSIDE(x, y + ec->h, ec->comp->man->x, ec->comp->man->y, ec->comp->man->w - 5, ec->comp->man->h - 5)) && - (!E_INSIDE(x + ec->w, y + ec->h, ec->comp->man->x, ec->comp->man->y, ec->comp->man->w - 5, ec->comp->man->h - 5))) && - (e_config->screen_limits == E_SCREEN_LIMITS_WITHIN)) - ) - e_comp_object_util_center(ec->frame); - else - evas_object_move(ec->frame, x, y); - } - } - - if (((resize) && (!ec->lock_client_size)) && - ((move) || ((!ec->maximized) && (!ec->fullscreen)))) - { - if ((ec->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE) - { - ec->saved.w = w; - ec->saved.h = h; - } - else - evas_object_resize(ec->frame, w, h); - } - - if (ec->icccm.fetch.transient_for) - { - if (ec->parent) - { - evas_object_layer_set(ec->frame, ec->parent->layer); - if (ec->netwm.state.modal) - { - ec->parent->modal = ec; - ec->parent->lock_close = EINA_TRUE; - } - - if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) || - (ec->parent->focused && - (e_config->focus_setting == - E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED))) - ec->take_focus = EINA_TRUE; - } - - ec->icccm.fetch.transient_for = EINA_FALSE; - } - - ec->changes.prop = EINA_FALSE; - if (ec->changes.icon) - { - if (ec->comp_data->reparented) return; - ec->comp_data->change_icon = EINA_TRUE; - ec->changes.icon = EINA_FALSE; - } -} - -static void -_e_comp_wl_cb_hook_client_pre_frame(void *data EINA_UNUSED, E_Client *ec) -{ - uint64_t parent; - - E_COMP_WL_PIXMAP_CHECK; - - if (!ec->comp_data->need_reparent) return; - - /* WRN("Client Needs New Parent in Pre Frame"); */ - - parent = e_client_util_pwin_get(ec); - - ec->border_size = 0; - e_pixmap_parent_window_set(ec->pixmap, parent); - - /* if (ec->shaped_input) */ - /* { */ - /* DBG("\tClient Shaped Input"); */ - /* } */ - - eina_hash_add(clients_win_hash, &parent, ec); - - if (ec->visible) - { - if (ec->comp_data->set_win_type) - { - if (ec->internal_ecore_evas) - { - int type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; - - switch (ec->netwm.type) - { - case E_WINDOW_TYPE_DIALOG: - /* NB: If there is No transient set, then dialogs get - * treated as Normal Toplevel windows */ - if (ec->icccm.transient_for) - type = ECORE_WL_WINDOW_TYPE_TRANSIENT; - break; - case E_WINDOW_TYPE_DESKTOP: - type = ECORE_WL_WINDOW_TYPE_FULLSCREEN; - break; - case E_WINDOW_TYPE_DND: - type = ECORE_WL_WINDOW_TYPE_DND; - break; - case E_WINDOW_TYPE_MENU: - case E_WINDOW_TYPE_DROPDOWN_MENU: - case E_WINDOW_TYPE_POPUP_MENU: - type = ECORE_WL_WINDOW_TYPE_MENU; - break; - case E_WINDOW_TYPE_NORMAL: - default: - break; - } - - ecore_evas_wayland_type_set(ec->internal_ecore_evas, type); - } - - ec->comp_data->set_win_type = EINA_FALSE; - } - } - - /* TODO */ - /* focus_setup */ - e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, parent); - e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, parent); - - _e_comp_wl_client_evas_init(ec); - - if ((ec->netwm.ping) && (!ec->ping_poller)) - e_client_ping(ec); - - if (ec->visible) evas_object_show(ec->frame); - - ec->comp_data->need_reparent = EINA_FALSE; - ec->redirected = EINA_TRUE; - - if (ec->comp_data->change_icon) - { - ec->changes.icon = EINA_TRUE; - EC_CHANGED(ec); - } - - ec->comp_data->change_icon = EINA_FALSE; - ec->comp_data->reparented = EINA_TRUE; - - /* _e_comp_wl_evas_cb_comp_hidden(ec, NULL, NULL); */ -} - -static void -_e_comp_wl_cb_hook_client_post_new(void *data EINA_UNUSED, E_Client *ec) -{ - E_COMP_WL_PIXMAP_CHECK; - - if (ec->need_shape_merge) ec->need_shape_merge = EINA_FALSE; - - if (ec->changes.internal_state) - { - E_Win *win; - - if ((win = ecore_evas_data_get(ec->internal_ecore_evas, "E_Win"))) - { - if (win->state.centered) - e_comp_object_util_center(ec->frame); - } - - ec->changes.internal_state = EINA_FALSE; - } - - if (ec->changes.internal_props) - { - E_Win *win; - - if ((win = ecore_evas_data_get(ec->internal_ecore_evas, "E_Win"))) - { - ecore_evas_size_min_set(ec->internal_ecore_evas, - win->min_w, win->min_h); - ecore_evas_size_max_set(ec->internal_ecore_evas, - win->max_w, win->max_h); - ecore_evas_size_base_set(ec->internal_ecore_evas, - win->base_w, win->base_h); - ecore_evas_size_step_set(ec->internal_ecore_evas, - win->step_x, win->step_y); - /* TODO: handle aspect */ - - ec->changes.internal_props = EINA_FALSE; - } - } - - if (ec->need_shape_export) - { - _e_comp_wl_client_shape_check(ec); - ec->need_shape_export = EINA_FALSE; - } -} - -static void -_e_comp_wl_cb_hook_client_eval_end(void *data EINA_UNUSED, E_Client *ec) -{ - E_COMP_WL_PIXMAP_CHECK; - - if ((ec->comp->wl_comp_data->restack) && (!ec->comp->new_clients)) - { - e_hints_client_stacking_set(); - ec->comp->wl_comp_data->restack = EINA_FALSE; - } -} - -static void -_e_comp_wl_cb_hook_client_focus_set(void *data EINA_UNUSED, E_Client *ec) -{ - E_COMP_WL_PIXMAP_CHECK; - - /* send configure */ - if (ec->comp_data->shell.configure_send) - { - if (ec->comp_data->shell.surface) - ec->comp_data->shell.configure_send(ec->comp_data->shell.surface, - 0, 0, 0); - } - - /* FIXME: This seems COMPLETELY wrong !! (taken from e_comp_x) - * - * We are getting focus on the client, WHY ON EARTH would we want to focus - * the compositor window Even IF the client pixmap is not Wl ?? */ - - /* if ((e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL)) */ - /* { */ - /* e_grabinput_focus(ec->comp->ee_win, E_FOCUS_METHOD_PASSIVE); */ - /* return; */ - /* } */ - - if ((ec->icccm.take_focus) && (ec->icccm.accepts_focus)) - e_grabinput_focus(e_client_util_win_get(ec), - E_FOCUS_METHOD_LOCALLY_ACTIVE); - else if (!ec->icccm.accepts_focus) - e_grabinput_focus(e_client_util_win_get(ec), - E_FOCUS_METHOD_GLOBALLY_ACTIVE); - else if (!ec->icccm.take_focus) - e_grabinput_focus(e_client_util_win_get(ec), E_FOCUS_METHOD_PASSIVE); - - if (ec->comp->wl_comp_data->kbd.focus != ec->comp_data->surface) - { - ec->comp->wl_comp_data->kbd.focus = ec->comp_data->surface; - e_comp_wl_data_device_keyboard_focus_set(ec->comp->wl_comp_data); - } -} - -static void -_e_comp_wl_cb_hook_client_focus_unset(void *data EINA_UNUSED, E_Client *ec) -{ - E_COMP_WL_PIXMAP_CHECK; - - /* send configure */ - if (ec->comp_data->shell.configure_send) - { - if (ec->comp_data->shell.surface) - ec->comp_data->shell.configure_send(ec->comp_data->shell.surface, - 0, 0, 0); - } - - _e_comp_wl_focus_check(ec->comp); - - if (ec->comp->wl_comp_data->kbd.focus == ec->comp_data->surface) - ec->comp->wl_comp_data->kbd.focus = NULL; -} - -EAPI Eina_Bool -e_comp_wl_init(void) -{ - /* set gl available */ - if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_WAYLAND_EGL)) - e_comp_gl_set(EINA_TRUE); - - /* try to create a wayland compositor */ - if (!_e_comp_wl_compositor_create()) - { - e_error_message_show(_("Enlightenment cannot create a Wayland Compositor!\n")); - return EINA_FALSE; - } - - /* set ecore_wayland in server mode - * NB: this is done before init so that ecore_wayland does not stall while - * waiting for compositor to be created */ - /* ecore_wl_server_mode_set(EINA_TRUE); */ - - /* try to initialize ecore_wayland */ - if (!ecore_wl_init(NULL)) - { - e_error_message_show(_("Enlightenment cannot initialize Ecore_Wayland!\n")); - return EINA_FALSE; - } - - /* create hash to store client windows */ - clients_win_hash = eina_hash_int64_new(NULL); - - /* setup event handlers for e events */ - E_LIST_HANDLER_APPEND(handlers, E_EVENT_COMP_OBJECT_ADD, - _e_comp_wl_cb_comp_object_add, NULL); - /* E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_ZONE_SET, */ - /* _e_comp_wl_cb_client_zone_set, NULL); */ - E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_PROPERTY, - _e_comp_wl_cb_client_prop, NULL); - - /* setup client hooks */ - /* e_client_hook_add(E_CLIENT_HOOK_DESK_SET, _cb, NULL); */ - /* e_client_hook_add(E_CLIENT_HOOK_RESIZE_BEGIN, _cb, NULL); */ - /* e_client_hook_add(E_CLIENT_HOOK_RESIZE_END, _cb, NULL); */ - /* e_client_hook_add(E_CLIENT_HOOK_MOVE_BEGIN, */ - /* _e_comp_wl_cb_hook_client_move_begin, NULL); */ - e_client_hook_add(E_CLIENT_HOOK_MOVE_END, - _e_comp_wl_cb_hook_client_move_end, NULL); - e_client_hook_add(E_CLIENT_HOOK_DEL, - _e_comp_wl_cb_hook_client_del, NULL); - e_client_hook_add(E_CLIENT_HOOK_NEW_CLIENT, - _e_comp_wl_cb_hook_client_new, NULL); - e_client_hook_add(E_CLIENT_HOOK_EVAL_FETCH, - _e_comp_wl_cb_hook_client_eval_fetch, NULL); - e_client_hook_add(E_CLIENT_HOOK_EVAL_PRE_FRAME_ASSIGN, - _e_comp_wl_cb_hook_client_pre_frame, NULL); - e_client_hook_add(E_CLIENT_HOOK_EVAL_POST_NEW_CLIENT, - _e_comp_wl_cb_hook_client_post_new, NULL); - e_client_hook_add(E_CLIENT_HOOK_EVAL_END, - _e_comp_wl_cb_hook_client_eval_end, NULL); - /* e_client_hook_add(E_CLIENT_HOOK_UNREDIRECT, _cb, NULL); */ - /* e_client_hook_add(E_CLIENT_HOOK_REDIRECT, _cb, NULL); */ - e_client_hook_add(E_CLIENT_HOOK_FOCUS_SET, - _e_comp_wl_cb_hook_client_focus_set, NULL); - e_client_hook_add(E_CLIENT_HOOK_FOCUS_UNSET, - _e_comp_wl_cb_hook_client_focus_unset, NULL); - - /* TODO: e_desklock_hooks ?? */ - - return EINA_TRUE; -} - -EINTERN void -e_comp_wl_shutdown(void) -{ - /* delete event handlers */ - E_FREE_LIST(handlers, ecore_event_handler_del); - - /* delete client window hash */ - E_FREE_FUNC(clients_win_hash, eina_hash_free); - - /* shutdown ecore_wayland */ - ecore_wl_shutdown(); -} - -EINTERN struct wl_resource * -e_comp_wl_surface_create(struct wl_client *client, int version, uint32_t id) -{ - struct wl_resource *ret = NULL; - - if ((ret = wl_resource_create(client, &wl_surface_interface, version, id))) - wl_resource_set_implementation(ret, &_e_comp_wl_surface_interface, - NULL, e_comp_wl_surface_destroy); - - return ret; -} - -EINTERN void -e_comp_wl_surface_destroy(struct wl_resource *resource) -{ - E_Pixmap *cp; - E_Client *ec; - - if (!(cp = wl_resource_get_user_data(resource))) return; - - /* try to find the E client for this surface */ - if (!(ec = e_pixmap_client_get(cp))) - ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, e_pixmap_window_get(cp)); - - if (!ec) - { - /* client was already deleted */ - e_pixmap_free(cp); - return; - } - - e_object_del(E_OBJECT(ec)); -} - -EINTERN void -e_comp_wl_buffer_reference(E_Comp_Wl_Buffer_Ref *ref, E_Comp_Wl_Buffer *buffer) -{ - if ((ref->buffer) && (buffer != ref->buffer)) - { - ref->buffer->busy--; - - if (ref->buffer->busy == 0) - wl_resource_queue_event(ref->buffer->resource, WL_BUFFER_RELEASE); - - wl_list_remove(&ref->destroy_listener.link); - } - - if ((buffer) && (buffer != ref->buffer)) - { - buffer->busy++; - wl_signal_add(&buffer->destroy_signal, &ref->destroy_listener); - } - - ref->buffer = buffer; - ref->destroy_listener.notify = _e_comp_wl_buffer_reference_cb_destroy; -} - -EAPI struct wl_signal -e_comp_wl_surface_signal_get(E_Comp *comp) -{ - return comp->wl_comp_data->signals.surface.create; -} From 054b87dc0d29605ff4ac3779669cfacc315e30b6 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 13:33:08 -0400 Subject: [PATCH 02/84] remove useless return Signed-off-by: Chris Michael --- src/bin/e_comp_wl_data.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/bin/e_comp_wl_data.c b/src/bin/e_comp_wl_data.c index fcfcd798a..bccfdb5eb 100644 --- a/src/bin/e_comp_wl_data.c +++ b/src/bin/e_comp_wl_data.c @@ -661,10 +661,7 @@ _e_comp_wl_clipboard_selection_set(struct wl_listener *listener EINA_UNUSED, voi cdata->selection.serial, p[0]); if (!cdata->clipboard.source) - { - close(p[0]); - return; - } + close(p[0]); } static void From 6a06b8d7f22a13cac4d56fd903cf081d1f0e8f97 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 13:52:26 -0400 Subject: [PATCH 03/84] add start of new compositor Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/bin/e_comp_wl.c diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c new file mode 100644 index 000000000..e99b1f1a5 --- /dev/null +++ b/src/bin/e_comp_wl.c @@ -0,0 +1,33 @@ +#define E_COMP_WL +#include "e.h" + +#define COMPOSITOR_VERSION 3 + +#define E_COMP_WL_PIXMAP_CHECK \ + if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return + +/* public functions */ +EAPI Eina_Bool +e_comp_wl_init(void) +{ + return EINA_FALSE; +} + +EAPI struct wl_signal +e_comp_wl_surface_create_signal_get(E_Comp *comp) +{ + return comp->wl_comp_data->signals.surface.create; +} + +/* internal functions */ +EINTERN void +e_comp_wl_shutdown(void) +{ + +} + +EINTERN struct wl_resource * +e_comp_wl_surface_create(struct wl_client *client, int version, uint32_t id) +{ + return NULL; +} From 5137277c93de21857cd91c24fc2cb060c9029b2d Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 13:53:25 -0400 Subject: [PATCH 04/84] set comp_gl if we have the correct engines available Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index e99b1f1a5..d8dc40732 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -10,6 +10,11 @@ EAPI Eina_Bool e_comp_wl_init(void) { + /* set gl available if we have ecore_evas support */ + if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_WAYLAND_EGL) || + ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_DRM)) + e_comp_gl_set(EINA_TRUE); + return EINA_FALSE; } From 62471b5b5be4f4ab59a7f8585cdbc89cd16296c0 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:03:15 -0400 Subject: [PATCH 05/84] add functions to create new compositor Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index d8dc40732..30b631e66 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -6,6 +6,38 @@ #define E_COMP_WL_PIXMAP_CHECK \ if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return +/* local functions */ +static void +_e_comp_wl_cb_del(E_Comp *comp) +{ + E_Comp_Data *cdata; + + /* get existing compositor data */ + if (!(cdata = comp->wl_comp_data)) return; + + /* free allocated data structure */ + free(cdata); +} + +static Eina_Bool +_e_comp_wl_compositor_create(void) +{ + E_Comp *comp; + + /* check for existing compositor. create if needed */ + if (!(comp = e_comp_get(NULL))) + { + comp = e_comp_new(); + comp->comp_type = E_PIXMAP_TYPE_WL; + E_OBJECT_DEL_SET(comp, _e_comp_wl_cb_del); + } + + /* create new compositor data */ + cdata = E_NEW(E_Comp_Data, 1); + + return EINA_TRUE; +} + /* public functions */ EAPI Eina_Bool e_comp_wl_init(void) @@ -15,7 +47,14 @@ e_comp_wl_init(void) ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_DRM)) e_comp_gl_set(EINA_TRUE); - return EINA_FALSE; + /* try to create a wayland compositor */ + if (!_e_comp_wl_compositor_create()) + { + e_error_message_show(_("Enlightenment cannot create a Wayland Compositor!\n")); + return EINA_FALSE; + } + + return EINA_TRUE; } EAPI struct wl_signal From edc0037655a3356dc2561753da8aa26613bdff21 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:07:38 -0400 Subject: [PATCH 06/84] add code to setup wayland logging function Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 30b631e66..81cdb328e 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -7,6 +7,12 @@ if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return /* local functions */ +static void +_e_comp_wl_log_cb_print(const char *format, va_list args) +{ + INF("WL: ", format, args); +} + static void _e_comp_wl_cb_del(E_Comp *comp) { @@ -35,6 +41,9 @@ _e_comp_wl_compositor_create(void) /* create new compositor data */ cdata = E_NEW(E_Comp_Data, 1); + /* set wayland log handler */ + wl_log_set_handler_server(_e_comp_wl_log_cb_print); + return EINA_TRUE; } From 6c76d16a33f0e0a92fb4082ae2bd330885a96a69 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:09:58 -0400 Subject: [PATCH 07/84] add code to create new wayland display Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 81cdb328e..694f2751b 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -44,7 +44,18 @@ _e_comp_wl_compositor_create(void) /* set wayland log handler */ wl_log_set_handler_server(_e_comp_wl_log_cb_print); + /* try to create a wayland display */ + if (!(cdata->wl.disp = wl_display_create())) + { + ERR("Could not create a Wayland display: %m"); + goto disp_err; + } + return EINA_TRUE; + +disp_err: + free(cdata); + return EINA_FALSE; } /* public functions */ From aff78ea8a7f453438d47439708cceb5a8ad11bf0 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:12:32 -0400 Subject: [PATCH 08/84] add code to create wayland display socket Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 694f2751b..015a447b5 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -29,6 +29,7 @@ static Eina_Bool _e_comp_wl_compositor_create(void) { E_Comp *comp; + const char *name; /* check for existing compositor. create if needed */ if (!(comp = e_comp_get(NULL))) @@ -51,8 +52,20 @@ _e_comp_wl_compositor_create(void) goto disp_err; } + /* try to setup wayland socket */ + if (!(name = wl_display_add_socket_auto(cdata->wl.disp))) + { + ERR("Could not create Wayland display socket: %m"); + goto sock_err; + } + + /* set wayland display environment variable */ + e_env_set("WAYLAND_DISPLAY", name); + return EINA_TRUE; +sock_err: + wl_display_destroy(cdata->wl.disp); disp_err: free(cdata); return EINA_FALSE; From de917436fd8dad12c09ba8b18194235d4436ee86 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:13:22 -0400 Subject: [PATCH 09/84] add code to setup wayland compositor signals Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 015a447b5..377ee4d18 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -62,6 +62,11 @@ _e_comp_wl_compositor_create(void) /* set wayland display environment variable */ e_env_set("WAYLAND_DISPLAY", name); + /* initialize compositor signals */ + wl_signal_init(&cdata->signals.surface.create); + wl_signal_init(&cdata->signals.surface.activate); + wl_signal_init(&cdata->signals.surface.kill); + return EINA_TRUE; sock_err: From 59338704daa86f9a4facc9b1c156da31ff1f6c13 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:20:33 -0400 Subject: [PATCH 10/84] add code to create and bind the wayland compositor Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 377ee4d18..c26034dda 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -13,6 +13,24 @@ _e_comp_wl_log_cb_print(const char *format, va_list args) INF("WL: ", format, args); } +static void +_e_comp_wl_compositor_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) +{ + E_Comp *comp; + struct wl_resource *res; + + if (!(comp = data)) return; + + if (!(res = + wl_resource_create(client, &wl_compositor_interface, + MIN(version, COMPOSITOR_VERSION), id))) + { + ERR("Could not create compositor resource: %m"); + wl_client_post_no_memory(client); + return; + } +} + static void _e_comp_wl_cb_del(E_Comp *comp) { @@ -67,8 +85,19 @@ _e_comp_wl_compositor_create(void) wl_signal_init(&cdata->signals.surface.activate); wl_signal_init(&cdata->signals.surface.kill); + /* try to add compositor to wayland globals */ + if (!wl_global_create(cdata->wl.disp, &wl_compositor_interface, + COMPOSITOR_VERSION, comp, + _e_comp_wl_compositor_cb_bind)) + { + ERR("Could not add compositor to wayland globals: %m"); + goto comp_global_err; + } + return EINA_TRUE; +comp_global_err: + e_env_unset("WAYLAND_DISPLAY"); sock_err: wl_display_destroy(cdata->wl.disp); disp_err: From a4db6d6485ffbf770899b67a880f446cee37c7d9 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:21:02 -0400 Subject: [PATCH 11/84] rename compositor delete callback Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index c26034dda..42f508a59 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -32,7 +32,7 @@ _e_comp_wl_compositor_cb_bind(struct wl_client *client, void *data, uint32_t ver } static void -_e_comp_wl_cb_del(E_Comp *comp) +_e_comp_wl_compositor_cb_del(E_Comp *comp) { E_Comp_Data *cdata; @@ -54,7 +54,7 @@ _e_comp_wl_compositor_create(void) { comp = e_comp_new(); comp->comp_type = E_PIXMAP_TYPE_WL; - E_OBJECT_DEL_SET(comp, _e_comp_wl_cb_del); + E_OBJECT_DEL_SET(comp, _e_comp_wl_compositor_cb_del); } /* create new compositor data */ From c776f016e3c48d5478dc3af2441bafd0cf0a88ea Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:21:48 -0400 Subject: [PATCH 12/84] add function call to initialize shm Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 42f508a59..47bafabba 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -94,6 +94,9 @@ _e_comp_wl_compositor_create(void) goto comp_global_err; } + /* initialize shm mechanism */ + wl_display_init_shm(cdata->wl.disp); + return EINA_TRUE; comp_global_err: From 1005a6d299957c16b733b8f2bdd7ae7afb4e2f36 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:40:02 -0400 Subject: [PATCH 13/84] add code to integrate wayland event loop with ecore_main loop Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 47bafabba..d558e6f72 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -13,6 +13,30 @@ _e_comp_wl_log_cb_print(const char *format, va_list args) INF("WL: ", format, args); } +static Eina_Bool +_e_comp_wl_cb_read(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED) +{ + E_Comp_Data *cdata; + + if (!(cdata = data)) return ECORE_CALLBACK_RENEW; + + /* dispatch pending wayland events */ + wl_event_loop_dispatch(cdata->wl.loop, 0); + + return ECORE_CALLBACK_RENEW; +} + +static void +_e_comp_wl_cb_prepare(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED) +{ + E_Comp_Data *cdata; + + if (!(cdata = data)) return; + + /* flush pending client events */ + wl_display_flush_clients(cdata->wl.disp); +} + static void _e_comp_wl_compositor_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) { @@ -48,6 +72,7 @@ _e_comp_wl_compositor_create(void) { E_Comp *comp; const char *name; + int fd = 0; /* check for existing compositor. create if needed */ if (!(comp = e_comp_get(NULL))) @@ -97,6 +122,19 @@ _e_comp_wl_compositor_create(void) /* initialize shm mechanism */ wl_display_init_shm(cdata->wl.disp); + /* get the wayland display loop */ + cdata->wl.loop = wl_display_get_event_loop(cdata->wl.disp); + + /* get the file descriptor of the wayland event loop */ + fd = wl_event_loop_get_fd(cdata->wl.loop); + + /* create a listener for wayland main loop events */ + cdata->fd_hdlr = + ecore_main_fd_handler_add(fd, (ECORE_FD_READ | ECORE_FD_ERROR), + _e_comp_wl_cb_read, cdata, NULL, NULL); + ecore_main_fd_handler_prepare_callback_set(cdata->fd_hdlr, + _e_comp_wl_cb_prepare, cdata); + return EINA_TRUE; comp_global_err: From 8010e7d8b9159a69bcd30ec76dba11ed73675150 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:44:21 -0400 Subject: [PATCH 14/84] add code to load desktop shell module Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index d558e6f72..3d34ed2ab 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -37,6 +37,33 @@ _e_comp_wl_cb_prepare(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED) wl_display_flush_clients(cdata->wl.disp); } +static Eina_Bool +_e_comp_wl_cb_module_idle(void *data) +{ + E_Comp_Data *cdata; + E_Module *mod = NULL; + + if (!(cdata = data)) return ECORE_CALLBACK_RENEW; + + /* check if we are still loading modules */ + if (e_module_loading_get()) return ECORE_CALLBACK_RENEW; + + if (!(mod = e_module_find("wl_desktop_shell"))) + mod = e_module_new("wl_desktop_shell"); + + if (mod) + { + e_module_enable(mod); + + /* FIXME: NB: + * Do we need to dispatch pending wl events here ?? */ + + return ECORE_CALLBACK_CANCEL; + } + + return ECORE_CALLBACK_RENEW; +} + static void _e_comp_wl_compositor_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) { @@ -135,6 +162,9 @@ _e_comp_wl_compositor_create(void) ecore_main_fd_handler_prepare_callback_set(cdata->fd_hdlr, _e_comp_wl_cb_prepare, cdata); + /* setup module idler to load shell mmodule */ + ecore_idler_add(_e_comp_wl_cb_module_idle, cdata); + return EINA_TRUE; comp_global_err: From 8637842cf9962f096791d2f2e6d4880db3324632 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:47:32 -0400 Subject: [PATCH 15/84] add code to initialize data manager Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 3d34ed2ab..582316232 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -146,6 +146,13 @@ _e_comp_wl_compositor_create(void) goto comp_global_err; } + /* try to init data manager */ + if (!e_comp_wl_data_manager_init(cdata)) + { + ERR("Could not initialize data manager"); + goto data_err; + } + /* initialize shm mechanism */ wl_display_init_shm(cdata->wl.disp); @@ -167,6 +174,7 @@ _e_comp_wl_compositor_create(void) return EINA_TRUE; +data_err: comp_global_err: e_env_unset("WAYLAND_DISPLAY"); sock_err: From 708e2557300aa1e5374942394467580f114b1955 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:49:05 -0400 Subject: [PATCH 16/84] add code to initialze input Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 582316232..ec43eeea4 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -153,6 +153,13 @@ _e_comp_wl_compositor_create(void) goto data_err; } + /* try to init input */ + if (!e_comp_wl_input_init(cdata)) + { + ERR("Could not initialize input"); + goto input_err; + } + /* initialize shm mechanism */ wl_display_init_shm(cdata->wl.disp); @@ -174,6 +181,8 @@ _e_comp_wl_compositor_create(void) return EINA_TRUE; +input_err: + e_comp_wl_data_manager_shutdown(cdata); data_err: comp_global_err: e_env_unset("WAYLAND_DISPLAY"); From 29c89083bd71e366a248f7e2d54de461b5cbf0d7 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:50:27 -0400 Subject: [PATCH 17/84] add code to setup input & keyboard if we are using an X compositor Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index ec43eeea4..f5aa57175 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -179,6 +179,12 @@ _e_comp_wl_compositor_create(void) /* setup module idler to load shell mmodule */ ecore_idler_add(_e_comp_wl_cb_module_idle, cdata); + if (comp->comp_type == E_PIXMAP_TYPE_X) + { + e_comp_wl_input_pointer_enabled_set(cdata, EINA_TRUE); + e_comp_wl_input_keyboard_enabled_set(cdata, EINA_TRUE); + } + return EINA_TRUE; input_err: From 0342998c793fa6ea5db18cbb811a2236a0fe0f90 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:50:58 -0400 Subject: [PATCH 18/84] set compositor wayland data Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index f5aa57175..cac381841 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -185,6 +185,9 @@ _e_comp_wl_compositor_create(void) e_comp_wl_input_keyboard_enabled_set(cdata, EINA_TRUE); } + /* set compositor wayland data */ + comp->wl_comp_data = cdata; + return EINA_TRUE; input_err: From 234953ad3e674e5833575a0a0da5605005ce7f17 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:52:20 -0400 Subject: [PATCH 19/84] add code to initialize Ecore_Wayland Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index cac381841..dcd4f1c65 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -218,6 +218,13 @@ e_comp_wl_init(void) return EINA_FALSE; } + /* try to init ecore_wayland */ + if (!ecore_wl_init(NULL)) + { + e_error_message_show(_("Enlightenment cannot initialize Ecore_Wayland!\n")); + return EINA_FALSE; + } + return EINA_TRUE; } From e0d301fdb681db1e597266179e0bcd4bec0e06d8 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:53:06 -0400 Subject: [PATCH 20/84] add call to shutdown Ecore_Wayland Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index dcd4f1c65..7861ae00d 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -238,7 +238,8 @@ e_comp_wl_surface_create_signal_get(E_Comp *comp) EINTERN void e_comp_wl_shutdown(void) { - + /* shutdown ecore_wayland */ + ecore_wl_shutdown(); } EINTERN struct wl_resource * From fd42a4ec984b7d2a84c8125abbbf05860dc897ad Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 14:57:22 -0400 Subject: [PATCH 21/84] Fix missing variable compiler warning Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 7861ae00d..9a116cebd 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -98,6 +98,7 @@ static Eina_Bool _e_comp_wl_compositor_create(void) { E_Comp *comp; + E_Comp_Data *cdata; const char *name; int fd = 0; From 8d54d20f8a0384629b1772ab9f22a83c55402e47 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 15:12:17 -0400 Subject: [PATCH 22/84] Fix printing of wayland log output Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 9a116cebd..1c9f69456 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -10,7 +10,7 @@ static void _e_comp_wl_log_cb_print(const char *format, va_list args) { - INF("WL: ", format, args); + EINA_LOG_DOM_INFO(e_log_dom, format, args); } static Eina_Bool From 7aab9b24a506d426c490b54a08772418a9009f67 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 15:17:56 -0400 Subject: [PATCH 23/84] start on actual compositor interface code Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 1c9f69456..d1bc6f377 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -64,6 +64,28 @@ _e_comp_wl_cb_module_idle(void *data) return ECORE_CALLBACK_RENEW; } +static void +_e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_resource *resource, uint32_t id) +{ + E_Comp *comp; + + if (!(comp = wl_resource_get_user_data(resource))) return; +} + +static void +_e_comp_wl_compositor_cb_region_create(struct wl_client *client, struct wl_resource *resource, uint32_t id) +{ + E_Comp *comp; + + if (!(comp = wl_resource_get_user_data(resource))) return; +} + +static const struct wl_compositor_interface _e_comp_interface = +{ + _e_comp_wl_compositor_cb_surface_create, + _e_comp_wl_compositor_cb_region_create +}; + static void _e_comp_wl_compositor_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) { @@ -80,6 +102,8 @@ _e_comp_wl_compositor_cb_bind(struct wl_client *client, void *data, uint32_t ver wl_client_post_no_memory(client); return; } + + wl_resource_set_implementation(res, &_e_comp_interface, comp, NULL); } static void From 0e525db048514421a94788e492acae2ce51672fa Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 15:49:53 -0400 Subject: [PATCH 24/84] rename surface signal get function Signed-off-by: Chris Michael --- src/bin/e_comp_wl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h index 2f1b2c38b..31384f670 100644 --- a/src/bin/e_comp_wl.h +++ b/src/bin/e_comp_wl.h @@ -273,7 +273,7 @@ EINTERN struct wl_resource *e_comp_wl_surface_create(struct wl_client *client, i EINTERN void e_comp_wl_surface_destroy(struct wl_resource *resource); EINTERN void e_comp_wl_buffer_reference(E_Comp_Wl_Buffer_Ref *ref, E_Comp_Wl_Buffer *buffer); -EAPI struct wl_signal e_comp_wl_surface_signal_get(E_Comp *comp); +EAPI struct wl_signal e_comp_wl_surface_create_signal_get(E_Comp *comp); static inline uint64_t e_comp_wl_id_get(uint32_t client, uint32_t surface) From d350217ed5940b8a29e91987910c8d46e8f8a708 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 17:29:25 -0400 Subject: [PATCH 25/84] remove debug noise in comp_wl_data Signed-off-by: Chris Michael --- src/bin/e_comp_wl_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/e_comp_wl_data.c b/src/bin/e_comp_wl_data.c index bccfdb5eb..f247a23f6 100644 --- a/src/bin/e_comp_wl_data.c +++ b/src/bin/e_comp_wl_data.c @@ -393,7 +393,7 @@ _e_comp_wl_data_manager_cb_device_get(struct wl_client *client, struct wl_resour E_Comp_Data *cdata; struct wl_resource *res; - DBG("Data Manager Device Get"); + /* DBG("Data Manager Device Get"); */ /* try to get the compositor data */ if (!(cdata = wl_resource_get_user_data(seat_resource))) return; From 8963b3ff8894d3a3fa135d5f6cd263915d70d97a Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 17:44:56 -0400 Subject: [PATCH 26/84] add start of surface implementation code Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 127 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index d1bc6f377..c88279252 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -64,12 +64,130 @@ _e_comp_wl_cb_module_idle(void *data) return ECORE_CALLBACK_RENEW; } +static void +_e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +_e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer_resource, int32_t sx, int32_t sy) +{ + +} + +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_frame(struct wl_client *client, struct wl_resource *resource, uint32_t callback) +{ + +} + +static void +_e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource) +{ + +} + +static void +_e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource) +{ + +} + +static void +_e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) +{ + +} + +static void +_e_comp_wl_surface_cb_buffer_transform_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int32_t transform EINA_UNUSED) +{ + DBG("Surface Buffer Transform"); +} + +static void +_e_comp_wl_surface_cb_buffer_scale_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int32_t scale EINA_UNUSED) +{ + DBG("Surface Buffer Scale"); +} + +static const struct wl_surface_interface _e_surface_interface = +{ + _e_comp_wl_surface_cb_destroy, + _e_comp_wl_surface_cb_attach, + _e_comp_wl_surface_cb_damage, + _e_comp_wl_surface_cb_frame, + _e_comp_wl_surface_cb_opaque_region_set, + _e_comp_wl_surface_cb_input_region_set, + _e_comp_wl_surface_cb_commit, + _e_comp_wl_surface_cb_buffer_transform_set, + _e_comp_wl_surface_cb_buffer_scale_set +}; + static void _e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_resource *resource, uint32_t id) { E_Comp *comp; + struct wl_resource *res; + uint64_t wid; + pid_t pid; + E_Pixmap *ep; if (!(comp = wl_resource_get_user_data(resource))) return; + + DBG("Compositor Cb Surface Create: %d", id); + + /* try to create an internal surface */ + if (!(res = wl_resource_create(client, &wl_surface_interface, + wl_resource_get_version(resource), id))) + { + ERR("Could not create compositor surface"); + wl_resource_post_no_memory(resource); + return; + } + + /* FIXME: set callback ? */ + /* set implementation on resource */ + wl_resource_set_implementation(res, &_e_surface_interface, NULL, NULL); +// _callback); + + DBG("\tCreated Resource: %d", wl_resource_get_id(res)); + + /* set implementation */ + + /* get the client pid and generate a pixmap id */ + wl_client_get_credentials(client, &pid, NULL, NULL); + wid = e_comp_wl_id_get(pid, id); + + DBG("\tClient Pid: %d", pid); + + /* check for existing pixmap */ + if (!(ep = e_pixmap_find(E_PIXMAP_TYPE_WL, wid))) + { + /* try to create new pixmap */ + if (!(ep = e_pixmap_new(E_PIXMAP_TYPE_WL, wid))) + { + ERR("Could not create new pixmap"); + wl_resource_destroy(res); + wl_resource_post_no_memory(resource); + return; + } + } + + DBG("\tUsing Pixmap: %llu", wid); + + /* set reference to pixmap so we can fetch it later */ + wl_resource_set_user_data(res, ep); + + /* emit surface create signal */ + wl_signal_emit(&comp->wl_comp_data->signals.surface.create, res); } static void @@ -270,5 +388,12 @@ e_comp_wl_shutdown(void) EINTERN struct wl_resource * e_comp_wl_surface_create(struct wl_client *client, int version, uint32_t id) { - return NULL; + struct wl_resource *ret = NULL; + + if ((ret = wl_resource_create(client, &wl_surface_interface, version, id))) + { + DBG("Created Surface: %d", wl_resource_get_id(ret)); + } + + return ret; } From a4e6ea3348d599afce2ac0894ceaac58363abbab Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 17:46:07 -0400 Subject: [PATCH 27/84] add call to delete fd handler when we close the compositor Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index c88279252..f1f764e09 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -232,6 +232,9 @@ _e_comp_wl_compositor_cb_del(E_Comp *comp) /* get existing compositor data */ if (!(cdata = comp->wl_comp_data)) return; + /* delete fd handler */ + if (cdata->fd_hdlr) ecore_main_fd_handler_del(cdata->fd_hdlr); + /* free allocated data structure */ free(cdata); } From 7ace049cfbc53cee52b9631782f9aeac6a4e11aa Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 15 Oct 2014 02:47:56 -0400 Subject: [PATCH 28/84] unset pixmap resource when surface resource is destroyed Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index f1f764e09..e03fa1140 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -6,6 +6,12 @@ #define E_COMP_WL_PIXMAP_CHECK \ if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return +/* Resource Data Mapping: (wl_resource_user_data_get) + * + * wl_surface == e_pixmap + * + */ + /* local functions */ static void _e_comp_wl_log_cb_print(const char *format, va_list args) @@ -67,6 +73,13 @@ _e_comp_wl_cb_module_idle(void *data) static void _e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) { + E_Pixmap *ep; + + /* unset the pixmap resource */ + if ((ep = wl_resource_user_data_get(resource))) + e_pixmap_resource_set(ep, NULL); + + /* destroy this resource */ wl_resource_destroy(resource); } @@ -153,15 +166,13 @@ _e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_reso return; } + DBG("\tCreated Resource: %d", wl_resource_get_id(res)); + /* FIXME: set callback ? */ /* set implementation on resource */ wl_resource_set_implementation(res, &_e_surface_interface, NULL, NULL); // _callback); - DBG("\tCreated Resource: %d", wl_resource_get_id(res)); - - /* set implementation */ - /* get the client pid and generate a pixmap id */ wl_client_get_credentials(client, &pid, NULL, NULL); wid = e_comp_wl_id_get(pid, id); From ccee62d069bcb2ced5e94c59bc767c2ac5db604f Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 15 Oct 2014 06:53:45 -0400 Subject: [PATCH 29/84] Fix compile errors. Implement start of buffer code Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 72 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index e03fa1140..645d6066c 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -6,7 +6,7 @@ #define E_COMP_WL_PIXMAP_CHECK \ if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return -/* Resource Data Mapping: (wl_resource_user_data_get) +/* Resource Data Mapping: (wl_resource_get_user_data) * * wl_surface == e_pixmap * @@ -70,13 +70,66 @@ _e_comp_wl_cb_module_idle(void *data) return ECORE_CALLBACK_RENEW; } +static void +_e_comp_wl_buffer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED) +{ + E_Comp_Wl_Buffer *buffer; + + DBG("Buffer Cb Destroy"); + + /* try to get the buffer from the listener */ + if ((buffer = container_of(listener, E_Comp_Wl_Buffer, destroy_listener))) + { + DBG("\tEmit buffer destroy signal"); + /* emit the destroy signal */ + wl_signal_emit(&buffer->destroy_signal, buffer); + + /* FIXME: Investigate validity of this + * + * I think this could be a problem because the destroy signal + * uses the buffer as the 'data', so anything that catches + * this signal is going to run into problems if we free */ + free(buffer); + } +} + +static E_Comp_Wl_Buffer * +_e_comp_wl_buffer_get(struct wl_resource *resource) +{ + E_Comp_Wl_Buffer *buffer; + struct wl_listener *listener; + + /* try to get the destroy listener from this resource */ + listener = + wl_resource_get_destroy_listener(resource, _e_comp_wl_buffer_cb_destroy); + + /* if we have the destroy listener, return the E_Comp_Wl_Buffer */ + if (listener) + return container_of(listener, E_Comp_Wl_Buffer, destroy_listener); + + /* no destroy listener on this resource, try to create new buffer */ + if (!(buffer = E_NEW(E_Comp_Wl_Buffer, 1))) return NULL; + + /* initialize buffer structure */ + buffer->resource = resource; + wl_signal_init(&buffer->destroy_signal); + + /* setup buffer destroy callback */ + buffer->destroy_listener.notify = _e_comp_wl_buffer_cb_destroy; + wl_resource_add_destroy_listener(resource, &buffer->destroy_listener); + + return buffer; +} + static void _e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) { E_Pixmap *ep; + DBG("Surface Cb Destroy: %d", wl_resource_get_id(resource)); + /* unset the pixmap resource */ - if ((ep = wl_resource_user_data_get(resource))) + if ((ep = wl_resource_get_user_data(resource))) e_pixmap_resource_set(ep, NULL); /* destroy this resource */ @@ -86,37 +139,36 @@ _e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_re static void _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer_resource, int32_t sx, int32_t sy) { - } 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) { - + DBG("Surface Cb Damage"); } static void _e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resource, uint32_t callback) { - + DBG("Surface Cb Frame"); } static void _e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource) { - + DBG("Surface Opaque Region Set"); } static void _e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource) { - + DBG("Surface Input Region Set"); } static void _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) { - + DBG("Surface Commit"); } static void @@ -162,7 +214,7 @@ _e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_reso wl_resource_get_version(resource), id))) { ERR("Could not create compositor surface"); - wl_resource_post_no_memory(resource); + wl_client_post_no_memory(client); return; } @@ -187,7 +239,7 @@ _e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_reso { ERR("Could not create new pixmap"); wl_resource_destroy(res); - wl_resource_post_no_memory(resource); + wl_client_post_no_memory(client); return; } } From 1dc1be5a7f0a96d9222d3cd0da7dcf71fb31aef6 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 15 Oct 2014 06:54:45 -0400 Subject: [PATCH 30/84] Implement code for surfaced attach Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 645d6066c..f29d08e44 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -139,6 +139,87 @@ _e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_re static void _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer_resource, int32_t sx, int32_t sy) { + E_Pixmap *ep; + uint64_t pixid; + E_Client *ec; + + DBG("Surface Attach: %d", wl_resource_get_id(resource)); + + /* get the e_pixmap reference */ + if (!(ep = wl_resource_get_user_data(resource))) return; + + pixid = e_pixmap_window_get(ep); + DBG("\tSurface has Pixmap: %llu", pixid); + + /* try to find the associated e_client */ + if (!(ec = e_pixmap_client_get(ep))) + { + if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) + { + ERR("\tCould not find client from pixmap %llu", pixid); + return; + } + } + + /* check if client is being deleted */ + if (e_object_is_del(E_OBJECT(ec))) + { + DBG("\tE_Client scheduled for deletion"); + return; + } + + /* check for valid comp_data */ + if (!ec->comp_data) + { + ERR("\tE_Client has no comp data"); + return; + } + + /* clear any pending buffer + * + * NB: This will call any buffer_destroy function associated */ + if (ec->comp_data->pending.buffer) + wl_list_remove(&ec->comp_data->pending.buffer_destroy.link); + + /* reset client pending information */ + ec->comp_data->pending.x = 0; + ec->comp_data->pending.y = 0; + ec->comp_data->pending.w = 0; + ec->comp_data->pending.h = 0; + ec->comp_data->pending.buffer = NULL; + ec->comp_data->pending.new_attach = EINA_TRUE; + + if (buffer_resource) + { + E_Comp_Wl_Buffer *buffer = NULL; + struct wl_shm_buffer *shmb; + + /* try to get the E_Comp_Wl_Buffer */ + if (!(buffer = _e_comp_wl_buffer_get(buffer_resource))) + { + ERR("\tCould not get E_Comp_Wl_Buffer"); + wl_client_post_no_memory(client); + return; + } + + /* since we have a valid buffer, set pending properties */ + ec->comp_data->pending.x = sx; + ec->comp_data->pending.y = sy; + ec->comp_data->pending.buffer = buffer; + + /* check for this resource being a shm buffer */ + if ((shmb = wl_shm_buffer_get(buffer_resource))) + { + /* 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); + } + + /* add buffer destroy signal so we get notified when this buffer + * gets destroyed (callback set in buffer_get function) */ + wl_signal_add(&buffer->destroy_signal, + &ec->comp_data->pending.buffer_destroy); + } } static void From e655abfaa4e664f2a83de999f402af7b5b4392b1 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 15 Oct 2014 06:57:16 -0400 Subject: [PATCH 31/84] Add code to create the clients window hash Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index f29d08e44..35be654e2 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -12,6 +12,9 @@ * */ +/* local variables */ +static Eina_Hash *clients_win_hash = NULL; + /* local functions */ static void _e_comp_wl_log_cb_print(const char *format, va_list args) @@ -515,6 +518,9 @@ e_comp_wl_init(void) return EINA_FALSE; } + /* create hash to store clients */ + clients_win_hash = eina_hash_int64_new(NULL); + return EINA_TRUE; } @@ -528,6 +534,9 @@ e_comp_wl_surface_create_signal_get(E_Comp *comp) EINTERN void e_comp_wl_shutdown(void) { + /* free the clients win hash */ + E_FREE_FUNC(clients_win_hash, eina_hash_free); + /* shutdown ecore_wayland */ ecore_wl_shutdown(); } From 8c661bb7fbae09e46321996848cb43e97b17d90b Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 15 Oct 2014 08:01:14 -0400 Subject: [PATCH 32/84] add code to hook the client new event Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 60 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 35be654e2..03d54bd40 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -386,6 +386,63 @@ _e_comp_wl_compositor_cb_del(E_Comp *comp) free(cdata); } +static void +_e_comp_wl_client_cb_new(void *data EINA_UNUSED, E_Client *ec) +{ + uint64_t win; + + DBG("Comp Hook Client New"); + + /* make sure this is a wayland client */ + E_COMP_WL_PIXMAP_CHECK; + + /* get window id from pixmap */ + win = e_pixmap_window_get(ec->pixmap); + + /* ignore fake root windows */ + if ((ec->override) && ((ec->x == -77) && (ec->y == -77))) + { + e_comp_ignore_win_add(E_PIXMAP_TYPE_WL, win); + e_object_del(E_OBJECT(ec)); + return; + } + + if (!(ec->comp_data = E_NEW(E_Comp_Client_Data, 1))) + { + ERR("Could not allocate new client data structure"); + return; + } + + /* set initial client properties */ + ec->ignored = e_comp_ignore_win_find(win); + ec->border_size = 0; + ec->placed |= ec->override; + ec->new_client ^= ec->override; + ec->icccm.accepts_focus = ((!ec->override) && (!ec->input_only)); + + /* NB: could not find a better place to do this, BUT for internal windows, + * we need to set delete_request else the close buttons on the frames do + * basically nothing */ + if (ec->internal) ec->icccm.delete_request = EINA_TRUE; + + /* set initial client data properties */ + ec->comp_data->mapped = EINA_FALSE; + ec->comp_data->first_damage = ((ec->internal) || (ec->override)); + + if ((!e_client_util_ignored_get(ec)) && + (!ec->internal) && (!ec->internal_ecore_evas)) + { + ec->comp_data->need_reparent = EINA_TRUE; + ec->take_focus = !starting; + } + + /* add this client to the hash */ + eina_hash_add(clients_win_hash, &win, ec); + e_hints_client_list_set(); + + /* TODO: first draw timer ? */ +} + static Eina_Bool _e_comp_wl_compositor_create(void) { @@ -521,6 +578,9 @@ e_comp_wl_init(void) /* create hash to store clients */ clients_win_hash = eina_hash_int64_new(NULL); + /* add hooks to catch e_client events */ + e_client_hook_add(E_CLIENT_HOOK_NEW_CLIENT, _e_comp_wl_client_cb_new, NULL); + return EINA_TRUE; } From 988c875162dc7baf629c6cbe6b2404aaedbfc1c1 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 15 Oct 2014 08:07:56 -0400 Subject: [PATCH 33/84] add hooks for client delete Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 03d54bd40..4ae589240 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -443,6 +443,46 @@ _e_comp_wl_client_cb_new(void *data EINA_UNUSED, E_Client *ec) /* TODO: first draw timer ? */ } +static void +_e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec) +{ + uint64_t win; + + DBG("Comp Hook Client Del"); + + /* 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); + + /* TODO: Focus set down */ + + 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); + } + + if ((ec->parent) && (ec->parent->modal == ec)) + { + ec->parent->lock_close = EINA_FALSE; + ec->parent->modal = NULL; + } + + E_FREE(ec->comp_data); + + /* TODO */ +} + static Eina_Bool _e_comp_wl_compositor_create(void) { @@ -580,6 +620,7 @@ e_comp_wl_init(void) /* add hooks to catch e_client events */ e_client_hook_add(E_CLIENT_HOOK_NEW_CLIENT, _e_comp_wl_client_cb_new, NULL); + e_client_hook_add(E_CLIENT_HOOK_DEL, _e_comp_wl_client_cb_del, NULL); return EINA_TRUE; } From bac72a83f3070e25632840a9ac38a8b46c1b0a3b Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 15 Oct 2014 10:43:55 -0400 Subject: [PATCH 34/84] add internal function prototype for surface commit Signed-off-by: Chris Michael --- src/bin/e_comp_wl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h index 31384f670..d535d6704 100644 --- a/src/bin/e_comp_wl.h +++ b/src/bin/e_comp_wl.h @@ -271,6 +271,7 @@ EINTERN void e_comp_wl_shutdown(void); EINTERN struct wl_resource *e_comp_wl_surface_create(struct wl_client *client, int version, uint32_t id); EINTERN void e_comp_wl_surface_destroy(struct wl_resource *resource); +EINTERN Eina_Bool e_comp_wl_surface_commit(E_Client *ec); EINTERN void e_comp_wl_buffer_reference(E_Comp_Wl_Buffer_Ref *ref, E_Comp_Wl_Buffer *buffer); EAPI struct wl_signal e_comp_wl_surface_create_signal_get(E_Comp *comp); From d3e232b51e19607511a53543e06bc3abdd0b25d7 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 15 Oct 2014 10:44:10 -0400 Subject: [PATCH 35/84] Start on surface commit code and improve some debugging messages Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 109 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 7 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 4ae589240..e4a0dfeda 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -228,43 +228,72 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resou 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) { - DBG("Surface Cb Damage"); + DBG("Surface Cb Damage: %d", wl_resource_get_id(resource)); } static void _e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resource, uint32_t callback) { - DBG("Surface Cb Frame"); + DBG("Surface Cb Frame: %d", wl_resource_get_id(resource)); } static void _e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource) { - DBG("Surface Opaque Region Set"); + DBG("Surface Opaque Region Set: %d", wl_resource_get_id(resource)); } static void _e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource) { - DBG("Surface Input Region Set"); + DBG("Surface Input Region Set: %d", wl_resource_get_id(resource)); } static void _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) { - DBG("Surface Commit"); + E_Pixmap *ep; + uint64_t pixid; + E_Client *ec; + + DBG("Surface Commit: %d", wl_resource_get_id(resource)); + + /* get the e_pixmap reference */ + if (!(ep = wl_resource_get_user_data(resource))) return; + + pixid = e_pixmap_window_get(ep); + DBG("\tSurface has Pixmap: %llu", pixid); + + /* try to find the associated e_client */ + if (!(ec = e_pixmap_client_get(ep))) + { + if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) + { + ERR("\tCould not find client from pixmap %llu", pixid); + return; + } + } + + /* trap for clients which are being deleted */ + if (e_object_is_del(E_OBJECT(ec))) return; + + /* handle actual surface commit */ + if (!e_comp_wl_surface_commit(ec)) + { + ERR("Failed to commit surface: %d", wl_resource_get_id(resource)); + } } static void _e_comp_wl_surface_cb_buffer_transform_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int32_t transform EINA_UNUSED) { - DBG("Surface Buffer Transform"); + DBG("Surface Buffer Transform: %d", wl_resource_get_id(resource)); } static void _e_comp_wl_surface_cb_buffer_scale_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int32_t scale EINA_UNUSED) { - DBG("Surface Buffer Scale"); + DBG("Surface Buffer Scale: %d", wl_resource_get_id(resource)); } static const struct wl_surface_interface _e_surface_interface = @@ -654,3 +683,69 @@ 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) +{ + E_Pixmap *ep; + + if (!(ep = ec->pixmap)) return EINA_FALSE; + + if (ec->comp_data->pending.new_attach) + { + /* TODO: buffer reference */ + + if (ec->comp_data->pending.buffer) + e_pixmap_resource_set(ep, ec->comp_data->pending.buffer->resource); + else + e_pixmap_resource_set(ep, NULL); + + e_pixmap_usable_set(ep, (ec->comp_data->pending.buffer != NULL)); + } + + /* mark the pixmap as dirty */ + e_pixmap_dirty(ep); + + /* check for any pending attachments */ + if (ec->comp_data->pending.new_attach) + { + /* check if the pending size is different than the client size */ + if ((ec->client.w != ec->comp_data->pending.w) || + (ec->client.h != ec->comp_data->pending.h)) + { + /* 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, + ec->client.x, ec->client.y, + ec->comp_data->pending.w, + ec->comp_data->pending.h); + } + } + + /* check if we need to map this surface */ + if (ec->comp_data->pending.buffer) + { + /* if this surface is not mapped yet, map it */ + 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); + } + } + else + { + /* no pending buffer to attach. unmap the surface */ + 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); + } + } + + /* TODO: Handle pending regions */ + + return EINA_TRUE; +} From 12d1b5e40f00e7ab0fdb722a4838a88ab0e1de58 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:21:12 -0400 Subject: [PATCH 36/84] change damages to be a list Signed-off-by: Chris Michael --- src/bin/e_comp_wl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h index d535d6704..6e8a06ee4 100644 --- a/src/bin/e_comp_wl.h +++ b/src/bin/e_comp_wl.h @@ -244,7 +244,7 @@ struct _E_Comp_Wl_Client_Data E_Comp_Wl_Buffer *buffer; struct wl_listener buffer_destroy; Eina_Bool new_attach : 1; - Eina_Tiler *damage; + Eina_List *damages; Eina_Tiler *input; Eina_Tiler *opaque; } pending; From ed649f2ab3baf4b76b162c2c811ee4da15ddbc68 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:21:33 -0400 Subject: [PATCH 37/84] add code to handle regions (creating, destroying, setting) Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 109 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 3 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index e4a0dfeda..aa75c5171 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -279,9 +279,7 @@ _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_res /* handle actual surface commit */ if (!e_comp_wl_surface_commit(ec)) - { - ERR("Failed to commit surface: %d", wl_resource_get_id(resource)); - } + ERR("Failed to commit surface: %d", wl_resource_get_id(resource)); } static void @@ -366,12 +364,110 @@ _e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_reso wl_signal_emit(&comp->wl_comp_data->signals.surface.create, res); } +static void +_e_comp_wl_region_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) +{ + DBG("Region Destroy: %d", wl_resource_get_id(resource)); + wl_resource_destroy(resource); +} + +static void +_e_comp_wl_region_cb_add(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h) +{ + Eina_Tiler *tiler; + + DBG("Region Add: %d", wl_resource_get_id(resource)); + DBG("\tGeom: %d %d %d %d", x, y, w, h); + + /* get the tiler from the resource */ + if ((tiler = wl_resource_get_user_data(resource))) + { + Eina_Tiler *src; + + src = eina_tiler_new(w, h); + eina_tiler_tile_size_set(src, 1, 1); + eina_tiler_rect_add(src, &(Eina_Rectangle){x, y, w, h}); + eina_tiler_union(tiler, src); + eina_tiler_free(src); + } +} + +static void +_e_comp_wl_region_cb_subtract(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h) +{ + Eina_Tiler *tiler; + + DBG("Region Subtract: %d", wl_resource_get_id(resource)); + DBG("\tGeom: %d %d %d %d", x, y, w, h); + + /* get the tiler from the resource */ + if ((tiler = wl_resource_get_user_data(resource))) + { + Eina_Tiler *src; + + src = eina_tiler_new(w, h); + eina_tiler_tile_size_set(src, 1, 1); + eina_tiler_rect_add(src, &(Eina_Rectangle){x, y, w, h}); + + eina_tiler_subtract(tiler, src); + eina_tiler_free(src); + } +} + +static const struct wl_region_interface _e_region_interface = +{ + _e_comp_wl_region_cb_destroy, + _e_comp_wl_region_cb_add, + _e_comp_wl_region_cb_subtract +}; + +static void +_e_comp_wl_compositor_cb_region_destroy(struct wl_resource *resource) +{ + Eina_Tiler *tiler; + + DBG("Compositor Region Destroy: %d", wl_resource_get_id(resource)); + + if ((tiler = wl_resource_get_user_data(resource))) + eina_tiler_free(tiler); +} + static void _e_comp_wl_compositor_cb_region_create(struct wl_client *client, struct wl_resource *resource, uint32_t id) { E_Comp *comp; + Eina_Tiler *tiler; + struct wl_resource *res; + /* get the compositor from the resource */ if (!(comp = wl_resource_get_user_data(resource))) return; + + DBG("Region Create: %d", wl_resource_get_id(resource)); + + /* try to create new tiler */ + if (!(tiler = eina_tiler_new(comp->man->w, comp->man->h))) + { + ERR("Could not create Eina_Tiler"); + wl_resource_post_no_memory(resource); + return; + } + + /* set tiler size */ + eina_tiler_tile_size_set(tiler, 1, 1); + + /* add rectangle to tiler */ + eina_tiler_rect_add(tiler, + &(Eina_Rectangle){0, 0, comp->man->w, comp->man->h}); + + if (!(res = wl_resource_create(client, &wl_region_interface, 1, id))) + { + ERR("\tFailed to create region resource"); + wl_resource_post_no_memory(resource); + return; + } + + wl_resource_set_implementation(res, &_e_region_interface, tiler, + _e_comp_wl_compositor_cb_region_destroy); } static const struct wl_compositor_interface _e_comp_interface = @@ -442,6 +538,13 @@ _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); + + ec->comp_data->pending.opaque = eina_tiler_new(ec->w, ec->h); + eina_tiler_tile_size_set(ec->comp_data->pending.opaque, 1, 1); + /* set initial client properties */ ec->ignored = e_comp_ignore_win_find(win); ec->border_size = 0; From fb9e9934cf28c62cccf536d6a671dba0607e54ec Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:22:58 -0400 Subject: [PATCH 38/84] Add code to handle setting surface damages Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index aa75c5171..b362058d3 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -228,7 +228,46 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resou 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; + uint64_t pixid; + E_Client *ec; + Eina_Rectangle *dmg = NULL; + int pw, ph; + DBG("Surface Cb Damage: %d", wl_resource_get_id(resource)); + DBG("\tGeom: %d %d %d %d", x, y, w, h); + + /* get the e_pixmap reference */ + if (!(ep = wl_resource_get_user_data(resource))) return; + + pixid = e_pixmap_window_get(ep); + DBG("\tSurface has Pixmap: %llu", pixid); + + /* try to find the associated e_client */ + if (!(ec = e_pixmap_client_get(ep))) + { + if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) + { + ERR("\tCould not find client from pixmap %llu", pixid); + return; + } + } + + if (!ec->comp_data) return; + + e_pixmap_size_get(ep, &pw, &ph); + DBG("\tPixmap Size: %d %d", pw, ph); + + DBG("\tPending Size: %d %d", ec->comp_data->pending.w, + ec->comp_data->pending.h); + + DBG("\tE Client Size: %d %d", ec->client.w, ec->client.h); + DBG("\tE Size: %d %d", ec->w, ec->h); + + dmg = eina_rectangle_new(x, y, w, h); + + ec->comp_data->pending.damages = + eina_list_append(ec->comp_data->pending.damages, dmg); } static void From 5b2d5a58f63a4e226c3ecb5f1aac86d779150938 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:23:41 -0400 Subject: [PATCH 39/84] add code to handle setting surface opaque region Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index b362058d3..4117a834f 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -279,7 +279,43 @@ _e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resour static void _e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource) { + E_Pixmap *ep; + uint64_t pixid; + E_Client *ec; + DBG("Surface Opaque Region Set: %d", wl_resource_get_id(resource)); + + /* 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))) + { + if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) + { + ERR("\tCould not find client from pixmap %llu", pixid); + return; + } + } + + /* trap for clients which are being deleted */ + if (e_object_is_del(E_OBJECT(ec))) return; + + if (region_resource) + { + Eina_Tiler *tmp; + + if (!(tmp = wl_resource_get_user_data(region_resource))) + return; + + eina_tiler_union(ec->comp_data->pending.opaque, tmp); + } + else + { + eina_tiler_clear(ec->comp_data->pending.opaque); + eina_tiler_rect_add(ec->comp_data->pending.opaque, + &(Eina_Rectangle){0, 0, ec->client.w, ec->client.h}); + } } static void From 53f21f997c0fe50a9a46815fad78d4468611fb28 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:24:03 -0400 Subject: [PATCH 40/84] add code to handle setting surface input region Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 4117a834f..1a3f1dc77 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -321,7 +321,43 @@ _e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, st static void _e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource) { + E_Pixmap *ep; + uint64_t pixid; + E_Client *ec; + DBG("Surface Input Region Set: %d", wl_resource_get_id(resource)); + + /* 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))) + { + if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) + { + ERR("\tCould not find client from pixmap %llu", pixid); + return; + } + } + + /* trap for clients which are being deleted */ + if (e_object_is_del(E_OBJECT(ec))) return; + + if (region_resource) + { + Eina_Tiler *tmp; + + if (!(tmp = wl_resource_get_user_data(region_resource))) + return; + + eina_tiler_union(ec->comp_data->pending.input, tmp); + } + else + { + eina_tiler_clear(ec->comp_data->pending.input); + eina_tiler_rect_add(ec->comp_data->pending.input, + &(Eina_Rectangle){0, 0, ec->client.w, ec->client.h}); + } } static void From a6cb5bfe6c67bc381266705fea74d3958c6ece97 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:24:59 -0400 Subject: [PATCH 41/84] add code to handle pending damages during surface commit Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 1a3f1dc77..af528edff 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -902,6 +902,7 @@ EINTERN Eina_Bool e_comp_wl_surface_commit(E_Client *ec) { E_Pixmap *ep; + Eina_Rectangle *dmg; if (!(ep = ec->pixmap)) return EINA_FALSE; @@ -961,5 +962,15 @@ e_comp_wl_surface_commit(E_Client *ec) /* TODO: Handle pending regions */ + /* commit any pending damages */ + if ((!ec->comp->nocomp) && (ec->frame)) + { + EINA_LIST_FREE(ec->comp_data->pending.damages, dmg) + { + e_comp_object_damage(ec->frame, dmg->x, dmg->y, dmg->w, dmg->h); + eina_rectangle_free(dmg); + } + } + return EINA_TRUE; } From d5bb9f9e8a449608be6e0ebf942d6803097fdd75 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:25:51 -0400 Subject: [PATCH 42/84] add code to handle pending opaque regions during surface commit Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 47 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index af528edff..f15c444ed 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -903,6 +903,7 @@ e_comp_wl_surface_commit(E_Client *ec) { E_Pixmap *ep; Eina_Rectangle *dmg; + Eina_Tiler *src, *tmp; if (!(ep = ec->pixmap)) return EINA_FALSE; @@ -960,7 +961,51 @@ e_comp_wl_surface_commit(E_Client *ec) } } - /* TODO: Handle pending regions */ + /* handle pending opaque */ + if (ec->comp_data->pending.opaque) + { + 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.opaque, tmp))) + { + Eina_Rectangle *rect; + Eina_Iterator *itr; + int i = 0; + + ec->shape_rects_num = 0; + + itr = eina_tiler_iterator_new(src); + EINA_ITERATOR_FOREACH(itr, rect) + ec->shape_rects_num += 1; + + ec->shape_rects = + malloc(sizeof(Eina_Rectangle) * ec->shape_rects_num); + + if (ec->shape_rects) + { + EINA_ITERATOR_FOREACH(itr, rect) + { + ec->shape_rects[i] = *(Eina_Rectangle *)((char *)rect); + + ec->shape_rects[i].x = rect->x; + ec->shape_rects[i].y = rect->y; + ec->shape_rects[i].w = rect->w; + ec->shape_rects[i].h = rect->h; + + i++; + } + } + + eina_iterator_free(itr); + eina_tiler_free(src); + } + + eina_tiler_free(tmp); + eina_tiler_clear(ec->comp_data->pending.opaque); + } /* commit any pending damages */ if ((!ec->comp->nocomp) && (ec->frame)) From e099e338586f91b43092bba467c2600f3c8d8bba Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:26:18 -0400 Subject: [PATCH 43/84] add code to handle pending input regions during surface commit Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index f15c444ed..9b6a32fe0 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -1017,5 +1017,52 @@ e_comp_wl_surface_commit(E_Client *ec) } } + /* handle pending input */ + if (ec->comp_data->pending.input) + { + 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; + int i = 0; + + ec->shape_input_rects_num = 0; + + itr = eina_tiler_iterator_new(src); + EINA_ITERATOR_FOREACH(itr, rect) + ec->shape_input_rects_num += 1; + + ec->shape_input_rects = + malloc(sizeof(Eina_Rectangle) * ec->shape_input_rects_num); + + if (ec->shape_input_rects) + { + EINA_ITERATOR_FOREACH(itr, rect) + { + ec->shape_input_rects[i] = + *(Eina_Rectangle *)((char *)rect); + + ec->shape_input_rects[i].x = rect->x; + ec->shape_input_rects[i].y = rect->y; + ec->shape_input_rects[i].w = rect->w; + ec->shape_input_rects[i].h = rect->h; + + i++; + } + } + + eina_iterator_free(itr); + eina_tiler_free(src); + } + + eina_tiler_free(tmp); + eina_tiler_clear(ec->comp_data->pending.opaque); + } + return EINA_TRUE; } From cf61ded0c5760627f4cc1333d3fc92fb098df2da Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:28:24 -0400 Subject: [PATCH 44/84] update resource data comment Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 9b6a32fe0..fd603bb3f 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -9,6 +9,7 @@ /* Resource Data Mapping: (wl_resource_get_user_data) * * wl_surface == e_pixmap + * wl_region == eina_tiler * */ From 6ff00a346c27382800499eee5435cb8544b60a55 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:32:13 -0400 Subject: [PATCH 45/84] add some comments about fetching resource data Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index fd603bb3f..b6b25283f 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -265,8 +265,10 @@ _e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_res DBG("\tE Client Size: %d %d", ec->client.w, ec->client.h); DBG("\tE Size: %d %d", ec->w, ec->h); + /* create new damage rectangle */ dmg = eina_rectangle_new(x, y, w, h); + /* add damage rectangle to list of pending damages */ ec->comp_data->pending.damages = eina_list_append(ec->comp_data->pending.damages, dmg); } @@ -306,6 +308,7 @@ _e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, st { Eina_Tiler *tmp; + /* try to get the tiler from the region resource */ if (!(tmp = wl_resource_get_user_data(region_resource))) return; @@ -348,6 +351,7 @@ _e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, str { Eina_Tiler *tmp; + /* try to get the tiler from the region resource */ if (!(tmp = wl_resource_get_user_data(region_resource))) return; @@ -540,6 +544,7 @@ _e_comp_wl_compositor_cb_region_destroy(struct wl_resource *resource) DBG("Compositor Region Destroy: %d", wl_resource_get_id(resource)); + /* try to get the tiler from the region resource */ if ((tiler = wl_resource_get_user_data(resource))) eina_tiler_free(tiler); } From 9faf1e57d2410e25927b2fa71a86fc875f2f02f1 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:37:45 -0400 Subject: [PATCH 46/84] cleanup any remaning damage rectangles when we delete the client Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index b6b25283f..0481e9fea 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -696,6 +696,7 @@ static void _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec) { uint64_t win; + Eina_Rectangle *dmg; DBG("Comp Hook Client Del"); @@ -727,9 +728,10 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec) ec->parent->modal = NULL; } - E_FREE(ec->comp_data); + EINA_LIST_FREE(ec->comp_data->pending.damage, dmg) + eina_rectangle_free(dmg); - /* TODO */ + E_FREE(ec->comp_data); } static Eina_Bool From 6acad9508d7317bad17b0dc598d633ef1bd4df7e Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:38:39 -0400 Subject: [PATCH 47/84] cleanup any pending opaque regions when we delete the client Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 0481e9fea..8c32e6a15 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -728,6 +728,9 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec) ec->parent->modal = NULL; } + if (ec->comp_data->pending.opaque) + eina_tiler_free(ec->comp_data->pending.opaque); + EINA_LIST_FREE(ec->comp_data->pending.damage, dmg) eina_rectangle_free(dmg); From 128d1f1d05744e25d2f24690b9ca7c31ac3be102 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:39:03 -0400 Subject: [PATCH 48/84] cleanup any pending input regions when we delete the client Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 8c32e6a15..c2ab33336 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -734,6 +734,9 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec) EINA_LIST_FREE(ec->comp_data->pending.damage, dmg) eina_rectangle_free(dmg); + if (ec->comp_data->pending.input) + eina_tiler_free(ec->comp_data->pending.input); + E_FREE(ec->comp_data); } From c3a9474ae966a74e0a0a76b8c49c7b46f540bde4 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:39:41 -0400 Subject: [PATCH 49/84] update todo Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index c2ab33336..8b9814470 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -738,6 +738,8 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec) eina_tiler_free(ec->comp_data->pending.input); E_FREE(ec->comp_data); + + /* TODO: focus check */ } static Eina_Bool From 830239c60f1be00eb5e690c7472e2e9bd6773940 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 11:44:46 -0400 Subject: [PATCH 50/84] fix typo Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 8b9814470..26f5bc1d9 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -731,7 +731,7 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec) if (ec->comp_data->pending.opaque) eina_tiler_free(ec->comp_data->pending.opaque); - EINA_LIST_FREE(ec->comp_data->pending.damage, dmg) + EINA_LIST_FREE(ec->comp_data->pending.damages, dmg) eina_rectangle_free(dmg); if (ec->comp_data->pending.input) From 270a394d45843c9405c5148437bf97eb2e749376 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 12:18:50 -0400 Subject: [PATCH 51/84] add listener for comp_object_add event so we can setup evas callbacks for a client. Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 26f5bc1d9..c3df52221 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -15,6 +15,7 @@ /* local variables */ static Eina_Hash *clients_win_hash = NULL; +static Eina_List *handlers = NULL; /* local functions */ static void @@ -74,6 +75,35 @@ _e_comp_wl_cb_module_idle(void *data) return ECORE_CALLBACK_RENEW; } +static void +_e_comp_wl_client_evas_init(E_Client *ec) +{ + ec->comp_data->evas_init = EINA_TRUE; +} + +static Eina_Bool +_e_comp_wl_cb_comp_object_add(void *data EINA_UNUSED, int type EINA_UNUSED, E_Event_Comp_Object *ev) +{ + E_Client *ec; + + /* try to get the client from the object */ + if (!(ec = e_comp_object_client_get(ev->comp_object))) + return ECORE_CALLBACK_RENEW; + + /* check for client being deleted */ + if (e_object_is_del(E_OBJECT(ec))) return ECORE_CALLBACK_RENEW; + + /* check for wayland pixmap */ + E_COMP_WL_PIXMAP_CHECK ECORE_CALLBACK_RENEW; + + DBG("Comp Object Added For Pixmap: %llu", e_pixmap_window_get(ec->pixmap)); + + /* if we have not setup evas callbacks for this client, do it */ + if (!ec->comp_data->evas_init) _e_comp_wl_client_evas_init(ec); + + return ECORE_CALLBACK_RENEW; +} + static void _e_comp_wl_buffer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED) { @@ -877,6 +907,10 @@ e_comp_wl_init(void) /* create hash to store clients */ clients_win_hash = eina_hash_int64_new(NULL); + /* add event handlers to catch E events */ + E_LIST_HANDLER_APPEND(handlers, E_EVENT_COMP_OBJECT_ADD, + _e_comp_wl_cb_comp_object_add, NULL); + /* add hooks to catch e_client events */ e_client_hook_add(E_CLIENT_HOOK_NEW_CLIENT, _e_comp_wl_client_cb_new, NULL); e_client_hook_add(E_CLIENT_HOOK_DEL, _e_comp_wl_client_cb_del, NULL); @@ -894,6 +928,9 @@ e_comp_wl_surface_create_signal_get(E_Comp *comp) EINTERN void 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); From 22b793a96fd3f2b914e8e3bc4918035d6395139b Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 12:20:44 -0400 Subject: [PATCH 52/84] fetch pixmap id in opaque & input region set functions Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index c3df52221..73b46b117 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -321,6 +321,9 @@ _e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, st /* get the e_pixmap reference */ if (!(ep = wl_resource_get_user_data(resource))) return; + pixid = e_pixmap_window_get(ep); + DBG("\tSurface has Pixmap: %llu", pixid); + /* try to find the associated e_client */ if (!(ec = e_pixmap_client_get(ep))) { @@ -364,6 +367,9 @@ _e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, str /* get the e_pixmap reference */ if (!(ep = wl_resource_get_user_data(resource))) return; + pixid = e_pixmap_window_get(ep); + DBG("\tSurface has Pixmap: %llu", pixid); + /* try to find the associated e_client */ if (!(ec = e_pixmap_client_get(ep))) { From f64a570569289b6e5163d44f4649005720915d94 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 12:25:59 -0400 Subject: [PATCH 53/84] add hoook for evas show callback and show any video childs Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 73b46b117..32e718848 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -75,9 +75,29 @@ _e_comp_wl_cb_module_idle(void *data) return ECORE_CALLBACK_RENEW; } +static void +_e_comp_wl_evas_cb_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + E_Client *ec, *tmp; + Eina_List *l; + + if (!(ec = data)) return; + + /* check for wayland pixmap */ + E_COMP_WL_PIXMAP_CHECK; + + if (!ec->override) e_hints_window_visible_set(ec); + + EINA_LIST_FOREACH(ec->e.state.video_child, l, tmp) + evas_object_show(tmp->frame); +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW, + _e_comp_wl_evas_cb_show, ec); + ec->comp_data->evas_init = EINA_TRUE; } From 7675825f61b4d15591ca3cd14fa2319c552644f0 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 12:28:37 -0400 Subject: [PATCH 54/84] add hook for evas callback hide so we can hide any video children Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 32e718848..360ec661b 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -83,20 +83,31 @@ _e_comp_wl_evas_cb_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EIN if (!(ec = data)) return; - /* check for wayland pixmap */ - E_COMP_WL_PIXMAP_CHECK; - if (!ec->override) e_hints_window_visible_set(ec); EINA_LIST_FOREACH(ec->e.state.video_child, l, tmp) evas_object_show(tmp->frame); } +static void +_e_comp_wl_evas_cb_hide(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + E_Client *ec, *tmp; + Eina_List *l; + + if (!(ec = data)) return; + + EINA_LIST_FOREACH(ec->e.state.video_child, l, tmp) + evas_object_hide(tmp->frame); +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW, _e_comp_wl_evas_cb_show, ec); + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE, + _e_comp_wl_evas_cb_hide, ec); ec->comp_data->evas_init = EINA_TRUE; } From 2696821734d9b819dbdd91a43127c2fddb278da2 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 12:56:40 -0400 Subject: [PATCH 55/84] add callback for mouse in on the client. Fix improper tiler_clear in surface_commit function. Add fast-path in surface commit to skip processing regions & damage if the client is not visible. Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 56 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 360ec661b..54b35b332 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -101,6 +101,34 @@ _e_comp_wl_evas_cb_hide(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EIN evas_object_hide(tmp->frame); } +static void +_e_comp_wl_evas_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + E_Client *ec; + Evas_Event_Mouse_In *ev; + struct wl_resource *res; + struct wl_client *wc; + Eina_List *l; + uint32_t serial; + + ev = event; + if (!(ec = data)) return; + if (e_object_is_del(E_OBJECT(ec))) return; + + DBG("Mouse In On Surface: %d", wl_resource_get_id(ec->comp_data->surface)); + + wc = wl_resource_get_client(ec->comp_data->surface); + serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp); + EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res) + { + if (!e_comp_wl_input_pointer_check(res)) continue; + if (wl_resource_get_client(res) != wc) continue; + wl_pointer_send_enter(res, serial, ec->comp_data->surface, + wl_fixed_from_int(ev->canvas.x), + wl_fixed_from_int(ev->canvas.y)); + } +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { @@ -109,6 +137,10 @@ _e_comp_wl_client_evas_init(E_Client *ec) evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE, _e_comp_wl_evas_cb_hide, ec); + /* setup input callbacks */ + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_IN, + _e_comp_wl_evas_cb_mouse_in, ec); + ec->comp_data->evas_init = EINA_TRUE; } @@ -221,7 +253,7 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resou { if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) { - ERR("\tCould not find client from pixmap %llu", pixid); + ERR("\t\tCould not find client from pixmap %llu", pixid); return; } } @@ -524,6 +556,7 @@ _e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_reso wid = e_comp_wl_id_get(pid, id); DBG("\tClient Pid: %d", pid); + DBG("\tWl Id: %llu", wid); /* check for existing pixmap */ if (!(ep = e_pixmap_find(E_PIXMAP_TYPE_WL, wid))) @@ -1051,6 +1084,12 @@ e_comp_wl_surface_commit(E_Client *ec) } } + if (!ec->visible) + { + DBG("\tSurface Not Visible. Skip to Unmapped"); + goto unmap; + } + /* handle pending opaque */ if (ec->comp_data->pending.opaque) { @@ -1151,8 +1190,21 @@ e_comp_wl_surface_commit(E_Client *ec) } eina_tiler_free(tmp); - eina_tiler_clear(ec->comp_data->pending.opaque); + eina_tiler_clear(ec->comp_data->pending.input); } return EINA_TRUE; + +unmap: + /* clear pending opaque regions */ + eina_tiler_clear(ec->comp_data->pending.opaque); + + /* surface is not visible, clear damages */ + EINA_LIST_FREE(ec->comp_data->pending.damages, dmg) + eina_rectangle_free(dmg); + + /* clear pending input regions */ + eina_tiler_clear(ec->comp_data->pending.input); + + return EINA_TRUE; } From 2bd389f47cd6947e0ab304eabafde8e793024d51 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 12:58:33 -0400 Subject: [PATCH 56/84] remove some debug messages Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 54b35b332..ad339a733 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -326,7 +326,6 @@ _e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_res uint64_t pixid; E_Client *ec; Eina_Rectangle *dmg = NULL; - int pw, ph; DBG("Surface Cb Damage: %d", wl_resource_get_id(resource)); DBG("\tGeom: %d %d %d %d", x, y, w, h); @@ -335,7 +334,6 @@ _e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_res if (!(ep = wl_resource_get_user_data(resource))) return; pixid = e_pixmap_window_get(ep); - DBG("\tSurface has Pixmap: %llu", pixid); /* try to find the associated e_client */ if (!(ec = e_pixmap_client_get(ep))) @@ -349,15 +347,6 @@ _e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_res if (!ec->comp_data) return; - e_pixmap_size_get(ep, &pw, &ph); - DBG("\tPixmap Size: %d %d", pw, ph); - - DBG("\tPending Size: %d %d", ec->comp_data->pending.w, - ec->comp_data->pending.h); - - DBG("\tE Client Size: %d %d", ec->client.w, ec->client.h); - DBG("\tE Size: %d %d", ec->w, ec->h); - /* create new damage rectangle */ dmg = eina_rectangle_new(x, y, w, h); @@ -555,9 +544,6 @@ _e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_reso wl_client_get_credentials(client, &pid, NULL, NULL); wid = e_comp_wl_id_get(pid, id); - DBG("\tClient Pid: %d", pid); - DBG("\tWl Id: %llu", wid); - /* check for existing pixmap */ if (!(ep = e_pixmap_find(E_PIXMAP_TYPE_WL, wid))) { From 122d47e6e90874b05b14b0b3ac49c808bce8ba20 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 13:06:24 -0400 Subject: [PATCH 57/84] add evas callback for mouse out on a surface Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index ad339a733..961535a93 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -129,6 +129,31 @@ _e_comp_wl_evas_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj } } +static void +_e_comp_wl_evas_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + E_Client *ec; + struct wl_resource *res; + struct wl_client *wc; + Eina_List *l; + uint32_t serial; + + if (!(ec = data)) return; + if (ec->cur_mouse_action) return; + if (e_object_is_del(E_OBJECT(ec))) return; + + DBG("Mouse Out On Surface: %d", wl_resource_get_id(ec->comp_data->surface)); + + wc = wl_resource_get_client(ec->comp_data->surface); + serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp); + EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res) + { + if (!e_comp_wl_input_pointer_check(res)) continue; + if (wl_resource_get_client(res) != wc) continue; + wl_pointer_send_leave(res, serial, ec->comp_data->surface); + } +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { @@ -140,6 +165,8 @@ _e_comp_wl_client_evas_init(E_Client *ec) /* setup input callbacks */ evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_IN, _e_comp_wl_evas_cb_mouse_in, ec); + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_OUT, + _e_comp_wl_evas_cb_mouse_out, ec); ec->comp_data->evas_init = EINA_TRUE; } From 5eb9ce9f346fc9e9a24757499aaca617740953ec Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 13:08:22 -0400 Subject: [PATCH 58/84] add evas callback for mouse move on a surface Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 961535a93..282580513 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -154,6 +154,37 @@ _e_comp_wl_evas_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *ob } } +static void +_e_comp_wl_evas_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) +{ + E_Client *ec; + Evas_Event_Mouse_Move *ev; + struct wl_resource *res; + struct wl_client *wc; + Eina_List *l; + + ev = event; + if (!(ec = data)) return; + if (ec->cur_mouse_action) return; + if (e_object_is_del(E_OBJECT(ec))) return; + if (e_client_util_ignored_get(ec)) return; + + ec->comp->wl_comp_data->ptr.x = + wl_fixed_from_int(ev->cur.canvas.x - ec->client.x); + ec->comp->wl_comp_data->ptr.y = + wl_fixed_from_int(ev->cur.canvas.y - ec->client.y); + + wc = wl_resource_get_client(ec->comp_data->surface); + EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res) + { + if (!e_comp_wl_input_pointer_check(res)) continue; + if (wl_resource_get_client(res) != wc) continue; + wl_pointer_send_motion(res, ev->timestamp, + ec->comp->wl_comp_data->ptr.x, + ec->comp->wl_comp_data->ptr.y); + } +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { @@ -167,6 +198,8 @@ _e_comp_wl_client_evas_init(E_Client *ec) _e_comp_wl_evas_cb_mouse_in, ec); evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_OUT, _e_comp_wl_evas_cb_mouse_out, ec); + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_MOVE, + _e_comp_wl_evas_cb_mouse_move, ec); ec->comp_data->evas_init = EINA_TRUE; } From c5d50e050a0bc3162ec3e24422240f77ea7ceea4 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 17:10:01 -0400 Subject: [PATCH 59/84] add evas callback function for mouse down event Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 282580513..1796b40e6 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -185,6 +185,51 @@ _e_comp_wl_evas_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *o } } +static void +_e_comp_wl_evas_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) +{ + E_Client *ec; + Evas_Event_Mouse_Down *ev; + struct wl_resource *res; + struct wl_client *wc; + Eina_List *l; + uint32_t serial, btn; + + ev = event; + if (!(ec = data)) return; + if (ec->cur_mouse_action) return; + if (e_object_is_del(E_OBJECT(ec))) return; + if (e_client_util_ignored_get(ec)) return; + + switch (ev->button) + { + case 1: + btn = BTN_LEFT; + break; + case 2: + btn = BTN_MIDDLE; + break; + case 3: + btn = BTN_RIGHT; + break; + default: + btn = ev->button; + break; + } + + ec->comp->wl_comp_data->ptr.button = btn; + + wc = wl_resource_get_client(ec->comp_data->surface); + serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp); + EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res) + { + if (!e_comp_wl_input_pointer_check(res)) continue; + if (wl_resource_get_client(res) != wc) continue; + wl_pointer_send_button(res, serial, ev->timestamp, btn, + WL_POINTER_BUTTON_STATE_PRESSED); + } +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { @@ -200,6 +245,8 @@ _e_comp_wl_client_evas_init(E_Client *ec) _e_comp_wl_evas_cb_mouse_out, ec); evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_wl_evas_cb_mouse_move, ec); + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_DOWN, + _e_comp_wl_evas_cb_mouse_down, ec); ec->comp_data->evas_init = EINA_TRUE; } From 3b45f205a21927873eebb65aacb59e2b36631bed Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 17:11:43 -0400 Subject: [PATCH 60/84] add evas callbacks for mouse up event Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 1796b40e6..93b086a33 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -230,6 +230,53 @@ _e_comp_wl_evas_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o } } +static void +_e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) +{ + E_Client *ec; + Evas_Event_Mouse_Up *ev; + struct wl_resource *res; + struct wl_client *wc; + Eina_List *l; + uint32_t serial, btn; + + ev = event; + if (!(ec = data)) return; + if (ec->cur_mouse_action) return; + if (e_object_is_del(E_OBJECT(ec))) return; + if (e_client_util_ignored_get(ec)) return; + + switch (ev->button) + { + case 1: + btn = BTN_LEFT; + break; + case 2: + btn = BTN_MIDDLE; + break; + case 3: + btn = BTN_RIGHT; + break; + default: + btn = ev->button; + break; + } + + ec->comp->wl_comp_data->resize.edges = 0; + ec->comp->wl_comp_data->resize.resource = NULL; + ec->comp->wl_comp_data->ptr.button = btn; + + wc = wl_resource_get_client(ec->comp_data->surface); + serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp); + EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res) + { + if (!e_comp_wl_input_pointer_check(res)) continue; + if (wl_resource_get_client(res) != wc) continue; + wl_pointer_send_button(res, serial, ev->timestamp, btn, + WL_POINTER_BUTTON_STATE_RELEASED); + } +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { @@ -247,6 +294,8 @@ _e_comp_wl_client_evas_init(E_Client *ec) _e_comp_wl_evas_cb_mouse_move, ec); evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_wl_evas_cb_mouse_down, ec); + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_UP, + _e_comp_wl_evas_cb_mouse_up, ec); ec->comp_data->evas_init = EINA_TRUE; } From 8cf2100e740258b7a5a5ecacb4cabe094f956d31 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 17:13:15 -0400 Subject: [PATCH 61/84] add evas callbacks for mouse wheel event Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 93b086a33..60c9b35c1 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -277,6 +277,41 @@ _e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj } } +static void +_e_comp_wl_evas_cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) +{ + E_Client *ec; + Evas_Event_Mouse_Wheel *ev; + struct wl_resource *res; + struct wl_client *wc; + Eina_List *l; + uint32_t axis, dir; + + ev = event; + if (!(ec = data)) return; + if (ec->cur_mouse_action) return; + if (e_object_is_del(E_OBJECT(ec))) return; + if (e_client_util_ignored_get(ec)) return; + + if (ev->direction == 0) + axis = WL_POINTER_AXIS_VERTICAL_SCROLL; + else + axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL; + + if (ev->z < 0) + dir = -wl_fixed_from_int(abs(ev->z)); + else + dir = wl_fixed_from_int(ev->z); + + wc = wl_resource_get_client(ec->comp_data->surface); + EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res) + { + if (!e_comp_wl_input_pointer_check(res)) continue; + if (wl_resource_get_client(res) != wc) continue; + wl_pointer_send_axis(res, ev->timestamp, axis, dir); + } +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { @@ -296,6 +331,8 @@ _e_comp_wl_client_evas_init(E_Client *ec) _e_comp_wl_evas_cb_mouse_down, ec); evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_UP, _e_comp_wl_evas_cb_mouse_up, ec); + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_WHEEL, + _e_comp_wl_evas_cb_mouse_wheel, ec); ec->comp_data->evas_init = EINA_TRUE; } From c9fe774f23d4082e27a5570738c3a344b5982e31 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 17:14:52 -0400 Subject: [PATCH 62/84] add evas callback for key down event Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 60c9b35c1..485c2f90a 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -312,6 +312,51 @@ _e_comp_wl_evas_cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object * } } +static void +_e_comp_wl_evas_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) +{ + E_Client *ec; + E_Comp_Data *cdata; + Evas_Event_Key_Down *ev; + uint32_t serial, *end, *k, keycode; + struct wl_resource *res; + struct wl_client *wc; + Eina_List *l; + + ev = event; + if (!(ec = data)) return; + if (e_object_is_del(E_OBJECT(ec))) return; + + if (!ec->focused) return; + + keycode = (ev->keycode - 8); + if (!(cdata = ec->comp->wl_comp_data)) return; + + end = (uint32_t *)cdata->kbd.keys.data + (cdata->kbd.keys.size / sizeof(*k)); + + for (k = cdata->kbd.keys.data; k < end; k++) + { + /* ignore server-generated key repeats */ + if (*k == keycode) return; + } + + cdata->kbd.keys.size = (const char *)end - (const char *)cdata->kbd.keys.data; + k = wl_array_add(&cdata->kbd.keys, sizeof(*k)); + *k = keycode; + + /* update modifier state */ + e_comp_wl_input_keyboard_state_update(cdata, keycode, EINA_TRUE); + + wc = wl_resource_get_client(ec->comp_data->surface); + serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp); + EINA_LIST_FOREACH(ec->comp->wl_comp_data->kbd.resources, l, res) + { + if (wl_resource_get_client(res) != wc) continue; + wl_keyboard_send_key(res, serial, ev->timestamp, + keycode, WL_KEYBOARD_KEY_STATE_PRESSED); + } +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { @@ -333,6 +378,8 @@ _e_comp_wl_client_evas_init(E_Client *ec) _e_comp_wl_evas_cb_mouse_up, ec); evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_wl_evas_cb_mouse_wheel, ec); + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_KEY_DOWN, + _e_comp_wl_evas_cb_key_down, ec); ec->comp_data->evas_init = EINA_TRUE; } From 438bb716892612a9ec6bb6f636edc7345bb2e05b Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Thu, 16 Oct 2014 17:16:52 -0400 Subject: [PATCH 63/84] add evas callback for key up events Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 485c2f90a..559ce1ce9 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -357,6 +357,45 @@ _e_comp_wl_evas_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj } } +static void +_e_comp_wl_evas_cb_key_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) +{ + E_Client *ec; + E_Comp_Data *cdata; + Evas_Event_Key_Up *ev; + uint32_t serial, *end, *k, keycode; + struct wl_resource *res; + struct wl_client *wc; + Eina_List *l; + + ev = event; + if (!(ec = data)) return; + if (e_object_is_del(E_OBJECT(ec))) return; + + if (!ec->focused) return; + + keycode = (ev->keycode - 8); + if (!(cdata = ec->comp->wl_comp_data)) return; + + end = (uint32_t *)cdata->kbd.keys.data + (cdata->kbd.keys.size / sizeof(*k)); + for (k = cdata->kbd.keys.data; k < end; k++) + if (*k == keycode) *k = *--end; + + cdata->kbd.keys.size = (const char *)end - (const char *)cdata->kbd.keys.data; + + wc = wl_resource_get_client(ec->comp_data->surface); + serial = wl_display_next_serial(cdata->wl.disp); + EINA_LIST_FOREACH(cdata->kbd.resources, l, res) + { + if (wl_resource_get_client(res) != wc) continue; + wl_keyboard_send_key(res, serial, ev->timestamp, + keycode, WL_KEYBOARD_KEY_STATE_RELEASED); + } + + /* update modifier state */ + e_comp_wl_input_keyboard_state_update(cdata, keycode, EINA_FALSE); +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { @@ -380,6 +419,8 @@ _e_comp_wl_client_evas_init(E_Client *ec) _e_comp_wl_evas_cb_mouse_wheel, ec); evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_KEY_DOWN, _e_comp_wl_evas_cb_key_down, ec); + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_KEY_UP, + _e_comp_wl_evas_cb_key_up, ec); ec->comp_data->evas_init = EINA_TRUE; } From 36ff31e6b446c4a66e1a30cc775fade42187d502 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Fri, 17 Oct 2014 04:39:58 -0400 Subject: [PATCH 64/84] add evas callback for delete_request and fix printf warnings for uint64_t Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 67 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 559ce1ce9..90aabb35f 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -1,6 +1,10 @@ #define E_COMP_WL #include "e.h" +/* handle include for printing uint64_t */ +#define __STDC_FORMAT_MACROS +#include + #define COMPOSITOR_VERSION 3 #define E_COMP_WL_PIXMAP_CHECK \ @@ -396,6 +400,42 @@ _e_comp_wl_evas_cb_key_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj E e_comp_wl_input_keyboard_state_update(cdata, keycode, EINA_FALSE); } +static void +_e_comp_wl_evas_cb_delete_request(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + E_Client *ec; + + if (!(ec = data)) return; + if (ec->netwm.ping) e_client_ping(ec); + + /* FIXME !!! + * + * This is a HUGE problem for internal windows... + * + * IF we delete the client here, then we cannot reopen some internal + * dialogs (configure, etc, etc) ... + * + * BUT, if we don't handle delete_request Somehow, then the close button on + * the frame does Nothing + */ + + e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap)); + if (ec->comp_data) + { + if (ec->comp_data->reparented) + e_client_comp_hidden_set(ec, EINA_TRUE); + } + + evas_object_pass_events_set(ec->frame, EINA_TRUE); + if (ec->visible) evas_object_hide(ec->frame); + if (!ec->internal) e_object_del(E_OBJECT(ec)); + + // _e_comp_wl_focus_check(comp); + + /* TODO: Delete request send ?? + * NB: No such animal wrt wayland */ +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { @@ -422,6 +462,10 @@ _e_comp_wl_client_evas_init(E_Client *ec) evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_KEY_UP, _e_comp_wl_evas_cb_key_up, ec); + /* setup delete/kill callbacks */ + evas_object_smart_callback_add(ec->frame, "delete_request", + _e_comp_wl_evas_cb_delete_request, ec); + ec->comp_data->evas_init = EINA_TRUE; } @@ -440,7 +484,8 @@ _e_comp_wl_cb_comp_object_add(void *data EINA_UNUSED, int type EINA_UNUSED, E_Ev /* check for wayland pixmap */ E_COMP_WL_PIXMAP_CHECK ECORE_CALLBACK_RENEW; - DBG("Comp Object Added For Pixmap: %llu", e_pixmap_window_get(ec->pixmap)); + DBG("Comp Object Added For Pixmap: %"PRIu64"", + e_pixmap_window_get(ec->pixmap)); /* if we have not setup evas callbacks for this client, do it */ if (!ec->comp_data->evas_init) _e_comp_wl_client_evas_init(ec); @@ -527,14 +572,14 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resou if (!(ep = wl_resource_get_user_data(resource))) return; pixid = e_pixmap_window_get(ep); - DBG("\tSurface has Pixmap: %llu", pixid); + DBG("\tSurface has Pixmap: %"PRIu64"", pixid); /* try to find the associated e_client */ if (!(ec = e_pixmap_client_get(ep))) { if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) { - ERR("\t\tCould not find client from pixmap %llu", pixid); + ERR("\t\tCould not find client from pixmap %"PRIu64"", pixid); return; } } @@ -621,7 +666,7 @@ _e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_res { if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) { - ERR("\tCould not find client from pixmap %llu", pixid); + ERR("\tCould not find client from pixmap %"PRIu64"", pixid); return; } } @@ -655,14 +700,14 @@ _e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, st if (!(ep = wl_resource_get_user_data(resource))) return; pixid = e_pixmap_window_get(ep); - DBG("\tSurface has Pixmap: %llu", pixid); + DBG("\tSurface has Pixmap: %"PRIu64"", pixid); /* try to find the associated e_client */ if (!(ec = e_pixmap_client_get(ep))) { if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) { - ERR("\tCould not find client from pixmap %llu", pixid); + ERR("\tCould not find client from pixmap %"PRIu64"", pixid); return; } } @@ -701,14 +746,14 @@ _e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, str if (!(ep = wl_resource_get_user_data(resource))) return; pixid = e_pixmap_window_get(ep); - DBG("\tSurface has Pixmap: %llu", pixid); + DBG("\tSurface has Pixmap: %"PRIu64, pixid); /* try to find the associated e_client */ if (!(ec = e_pixmap_client_get(ep))) { if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) { - ERR("\tCould not find client from pixmap %llu", pixid); + ERR("\tCould not find client from pixmap %"PRIu64, pixid); return; } } @@ -747,14 +792,14 @@ _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_res if (!(ep = wl_resource_get_user_data(resource))) return; pixid = e_pixmap_window_get(ep); - DBG("\tSurface has Pixmap: %llu", pixid); + DBG("\tSurface has Pixmap: %"PRIu64, pixid); /* try to find the associated e_client */ if (!(ec = e_pixmap_client_get(ep))) { if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) { - ERR("\tCould not find client from pixmap %llu", pixid); + ERR("\tCould not find client from pixmap %"PRIu64, pixid); return; } } @@ -838,7 +883,7 @@ _e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_reso } } - DBG("\tUsing Pixmap: %llu", wid); + DBG("\tUsing Pixmap: %"PRIu64, wid); /* set reference to pixmap so we can fetch it later */ wl_resource_set_user_data(res, ep); From 241ad6a7893a0644ef3c7beb22cbfc2d2df2cee4 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Fri, 17 Oct 2014 04:41:32 -0400 Subject: [PATCH 65/84] add evas callback for kill request Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 90aabb35f..b9604b595 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -436,6 +436,28 @@ _e_comp_wl_evas_cb_delete_request(void *data, Evas_Object *obj EINA_UNUSED, void * NB: No such animal wrt wayland */ } +static void +_e_comp_wl_evas_cb_kill_request(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + E_Client *ec; + + if (!(ec = data)) return; + /* if (ec->netwm.ping) e_client_ping(ec); */ + + e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap)); + if (ec->comp_data) + { + if (ec->comp_data->reparented) + e_client_comp_hidden_set(ec, EINA_TRUE); + } + + evas_object_pass_events_set(ec->frame, EINA_TRUE); + if (ec->visible) evas_object_hide(ec->frame); + if (!ec->internal) e_object_del(E_OBJECT(ec)); + + // _e_comp_wl_focus_check(comp); +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { @@ -465,6 +487,8 @@ _e_comp_wl_client_evas_init(E_Client *ec) /* setup delete/kill callbacks */ evas_object_smart_callback_add(ec->frame, "delete_request", _e_comp_wl_evas_cb_delete_request, ec); + evas_object_smart_callback_add(ec->frame, "kill_request", + _e_comp_wl_evas_cb_kill_request, ec); ec->comp_data->evas_init = EINA_TRUE; } From 59e431d8383618bf4260732b51af06ae3437eb45 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Fri, 17 Oct 2014 04:43:11 -0400 Subject: [PATCH 66/84] add evas callback for ping event Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index b9604b595..fd6a4e926 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -458,6 +458,20 @@ _e_comp_wl_evas_cb_kill_request(void *data, Evas_Object *obj EINA_UNUSED, void * // _e_comp_wl_focus_check(comp); } +static void +_e_comp_wl_evas_cb_ping(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + E_Client *ec; + + if (!(ec = data)) return; + + if (ec->comp_data->shell.ping) + { + if (ec->comp_data->shell.surface) + ec->comp_data->shell.ping(ec->comp_data->shell.surface); + } +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { @@ -490,6 +504,10 @@ _e_comp_wl_client_evas_init(E_Client *ec) evas_object_smart_callback_add(ec->frame, "kill_request", _e_comp_wl_evas_cb_kill_request, ec); + /* setup ping callback */ + evas_object_smart_callback_add(ec->frame, "ping", + _e_comp_wl_evas_cb_ping, ec); + ec->comp_data->evas_init = EINA_TRUE; } From 65b397a84f39df75c20a65dabf7420847ca0de70 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Fri, 17 Oct 2014 04:44:40 -0400 Subject: [PATCH 67/84] add evas callback for color_set Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index fd6a4e926..42b2f4180 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -472,6 +472,20 @@ _e_comp_wl_evas_cb_ping(void *data, Evas_Object *obj EINA_UNUSED, void *event EI } } +static void +_e_comp_wl_evas_cb_color_set(void *data, Evas_Object *obj, void *event EINA_UNUSED) +{ + E_Client *ec; + int a = 0; + + if (!(ec = data)) return; + evas_object_color_get(obj, NULL, NULL, NULL, &a); + if (ec->netwm.opacity == a) return; + ec->netwm.opacity = a; + ec->netwm.opacity_changed = EINA_TRUE; + // _e_comp_wl_client_idler_add(ec); +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { @@ -508,6 +522,9 @@ _e_comp_wl_client_evas_init(E_Client *ec) evas_object_smart_callback_add(ec->frame, "ping", _e_comp_wl_evas_cb_ping, ec); + evas_object_smart_callback_add(ec->frame, "color_set", + _e_comp_wl_evas_cb_color_set, ec); + ec->comp_data->evas_init = EINA_TRUE; } From 7ea9df0f532a107c71dc21273908b684bb47bd45 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Fri, 17 Oct 2014 04:47:57 -0400 Subject: [PATCH 68/84] add evas callback for client resize Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 42b2f4180..e69dd012b 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -486,6 +486,27 @@ _e_comp_wl_evas_cb_color_set(void *data, Evas_Object *obj, void *event EINA_UNUS // _e_comp_wl_client_idler_add(ec); } +static void +_e_comp_wl_evas_cb_resize(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + E_Client *ec; + + if (!(ec = data)) return; + if ((ec->shading) || (ec->shaded)) return; + + DBG("Evas Resize Surface %d", + wl_resource_get_id(ec->comp_data->shell.surface)); + DBG("\tNew Size: %d %d", ec->client.w, ec->client.h); + +// if (!e_pixmap_size_changed(ec->pixmap, ec->client.w, ec->client.h)) +// return; + + ec->post_resize = EINA_TRUE; + /* e_pixmap_dirty(ec->pixmap); */ + e_comp_object_render_update_del(ec->frame); + // _e_comp_wl_client_idler_add(ec); +} + static void _e_comp_wl_client_evas_init(E_Client *ec) { @@ -525,6 +546,12 @@ _e_comp_wl_client_evas_init(E_Client *ec) evas_object_smart_callback_add(ec->frame, "color_set", _e_comp_wl_evas_cb_color_set, ec); + if (!ec->override) + { + evas_object_smart_callback_add(ec->frame, "client_resize", + _e_comp_wl_evas_cb_resize, ec); + } + ec->comp_data->evas_init = EINA_TRUE; } From 72dac4e75181a716b1ef938c9b5d470242c9906e Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Fri, 17 Oct 2014 05:16:30 -0400 Subject: [PATCH 69/84] add callbacks for client focus/unfocus Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 85 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 6 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index e69dd012b..ee98e44f7 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -22,6 +22,27 @@ static Eina_Hash *clients_win_hash = NULL; static Eina_List *handlers = NULL; /* local functions */ +static void +_e_comp_wl_focus_down_set(E_Client *ec) +{ + Ecore_Window win = 0; + + win = e_client_util_pwin_get(ec); + e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, win); + e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, win); +} + +static void +_e_comp_wl_focus_check(E_Comp *comp) +{ + E_Client *ec; + + if (stopping) return; + ec = e_client_focused_get(); + if ((!ec) || (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL)) + e_grabinput_focus(comp->ee_win, E_FOCUS_METHOD_PASSIVE); +} + static void _e_comp_wl_log_cb_print(const char *format, va_list args) { @@ -430,7 +451,7 @@ _e_comp_wl_evas_cb_delete_request(void *data, Evas_Object *obj EINA_UNUSED, void if (ec->visible) evas_object_hide(ec->frame); if (!ec->internal) e_object_del(E_OBJECT(ec)); - // _e_comp_wl_focus_check(comp); + _e_comp_wl_focus_check(ec->comp); /* TODO: Delete request send ?? * NB: No such animal wrt wayland */ @@ -455,7 +476,7 @@ _e_comp_wl_evas_cb_kill_request(void *data, Evas_Object *obj EINA_UNUSED, void * if (ec->visible) evas_object_hide(ec->frame); if (!ec->internal) e_object_del(E_OBJECT(ec)); - // _e_comp_wl_focus_check(comp); + _e_comp_wl_focus_check(ec->comp); } static void @@ -584,11 +605,11 @@ _e_comp_wl_buffer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSE { E_Comp_Wl_Buffer *buffer; - DBG("Buffer Cb Destroy"); - /* try to get the buffer from the listener */ if ((buffer = container_of(listener, E_Comp_Wl_Buffer, destroy_listener))) { + DBG("Buffer Cb Destroy: %d", wl_resource_get_id(buffer->resource)); + DBG("\tEmit buffer destroy signal"); /* emit the destroy signal */ wl_signal_emit(&buffer->destroy_signal, buffer); @@ -619,6 +640,8 @@ _e_comp_wl_buffer_get(struct wl_resource *resource) /* no destroy listener on this resource, try to create new buffer */ if (!(buffer = E_NEW(E_Comp_Wl_Buffer, 1))) return NULL; + DBG("Create New Buffer: %d", wl_resource_get_id(resource)); + /* initialize buffer structure */ buffer->resource = resource; wl_signal_init(&buffer->destroy_signal); @@ -1205,7 +1228,8 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec) win = e_pixmap_window_get(ec->pixmap); eina_hash_del_by_key(clients_win_hash, &win); - /* TODO: Focus set down */ + 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) @@ -1237,7 +1261,51 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec) E_FREE(ec->comp_data); - /* TODO: focus check */ + _e_comp_wl_focus_check(ec->comp); +} + +static void +_e_comp_wl_client_cb_focus_set(void *data EINA_UNUSED, E_Client *ec) +{ + /* send configure */ + if (ec->comp_data->shell.configure_send) + { + if (ec->comp_data->shell.surface) + ec->comp_data->shell.configure_send(ec->comp_data->shell.surface, + 0, 0, 0); + } + + if ((ec->icccm.take_focus) && (ec->icccm.accepts_focus)) + e_grabinput_focus(e_client_util_win_get(ec), + E_FOCUS_METHOD_LOCALLY_ACTIVE); + else if (!ec->icccm.accepts_focus) + e_grabinput_focus(e_client_util_win_get(ec), + E_FOCUS_METHOD_GLOBALLY_ACTIVE); + else if (!ec->icccm.take_focus) + e_grabinput_focus(e_client_util_win_get(ec), E_FOCUS_METHOD_PASSIVE); + + if (ec->comp->wl_comp_data->kbd.focus != ec->comp_data->surface) + { + ec->comp->wl_comp_data->kbd.focus = ec->comp_data->surface; + e_comp_wl_data_device_keyboard_focus_set(ec->comp->wl_comp_data); + } +} + +static void +_e_comp_wl_client_cb_focus_unset(void *data EINA_UNUSED, E_Client *ec) +{ + /* send configure */ + if (ec->comp_data->shell.configure_send) + { + if (ec->comp_data->shell.surface) + ec->comp_data->shell.configure_send(ec->comp_data->shell.surface, + 0, 0, 0); + } + + _e_comp_wl_focus_check(ec->comp); + + if (ec->comp->wl_comp_data->kbd.focus == ec->comp_data->surface) + ec->comp->wl_comp_data->kbd.focus = NULL; } static Eina_Bool @@ -1383,6 +1451,11 @@ e_comp_wl_init(void) e_client_hook_add(E_CLIENT_HOOK_NEW_CLIENT, _e_comp_wl_client_cb_new, NULL); e_client_hook_add(E_CLIENT_HOOK_DEL, _e_comp_wl_client_cb_del, NULL); + e_client_hook_add(E_CLIENT_HOOK_FOCUS_SET, + _e_comp_wl_client_cb_focus_set, NULL); + e_client_hook_add(E_CLIENT_HOOK_FOCUS_UNSET, + _e_comp_wl_client_cb_focus_unset, NULL); + return EINA_TRUE; } From e04343eaaabdea30608dc1f7e33b1d7aef1d9fde Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Fri, 17 Oct 2014 05:17:41 -0400 Subject: [PATCH 70/84] add checks in client focus/unfocus to test for wayland client Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index ee98e44f7..f5348dd6c 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -1267,6 +1267,8 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec) static void _e_comp_wl_client_cb_focus_set(void *data EINA_UNUSED, E_Client *ec) { + E_COMP_WL_PIXMAP_CHECK; + /* send configure */ if (ec->comp_data->shell.configure_send) { @@ -1294,6 +1296,8 @@ _e_comp_wl_client_cb_focus_set(void *data EINA_UNUSED, E_Client *ec) static void _e_comp_wl_client_cb_focus_unset(void *data EINA_UNUSED, E_Client *ec) { + E_COMP_WL_PIXMAP_CHECK; + /* send configure */ if (ec->comp_data->shell.configure_send) { From b410042f7fa29cb23d0f65cc777bca27945c2a7f Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Fri, 17 Oct 2014 05:18:39 -0400 Subject: [PATCH 71/84] remove debug messages for mouse in/out Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index f5348dd6c..9920a75ac 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -140,8 +140,6 @@ _e_comp_wl_evas_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj if (!(ec = data)) return; if (e_object_is_del(E_OBJECT(ec))) return; - DBG("Mouse In On Surface: %d", wl_resource_get_id(ec->comp_data->surface)); - wc = wl_resource_get_client(ec->comp_data->surface); serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp); EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res) @@ -167,8 +165,6 @@ _e_comp_wl_evas_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *ob if (ec->cur_mouse_action) return; if (e_object_is_del(E_OBJECT(ec))) return; - DBG("Mouse Out On Surface: %d", wl_resource_get_id(ec->comp_data->surface)); - wc = wl_resource_get_client(ec->comp_data->surface); serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp); EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res) From 3cf2088ee7bb8e8b6894fc17bb85d3dd891c63ce Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Fri, 17 Oct 2014 05:21:28 -0400 Subject: [PATCH 72/84] fix formatting Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 9920a75ac..ae21a9be8 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -564,10 +564,8 @@ _e_comp_wl_client_evas_init(E_Client *ec) _e_comp_wl_evas_cb_color_set, ec); if (!ec->override) - { - evas_object_smart_callback_add(ec->frame, "client_resize", - _e_comp_wl_evas_cb_resize, ec); - } + evas_object_smart_callback_add(ec->frame, "client_resize", + _e_comp_wl_evas_cb_resize, ec); ec->comp_data->evas_init = EINA_TRUE; } @@ -1485,9 +1483,7 @@ e_comp_wl_surface_create(struct wl_client *client, int version, uint32_t id) struct wl_resource *ret = NULL; if ((ret = wl_resource_create(client, &wl_surface_interface, version, id))) - { - DBG("Created Surface: %d", wl_resource_get_id(ret)); - } + DBG("Created Surface: %d", wl_resource_get_id(ret)); return ret; } From 4b1e0e589e86e424b4bf909a9c5446ab81f5422b Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Mon, 20 Oct 2014 12:22:30 -0400 Subject: [PATCH 73/84] e-comp-wl: Comment out EGL include This fixes a build error from evas engine already including EGL headers Signed-off-by: Chris Michael --- src/bin/e_comp_wl.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h index 6e8a06ee4..19f6bc2ec 100644 --- a/src/bin/e_comp_wl.h +++ b/src/bin/e_comp_wl.h @@ -13,10 +13,10 @@ # include -# ifdef HAVE_WAYLAND_EGL -# include -# define GL_GLEXT_PROTOTYPES -# endif +/* # ifdef HAVE_WAYLAND_EGL */ +/* # include */ +/* # define GL_GLEXT_PROTOTYPES */ +/* # endif */ # ifdef __linux__ # include From 87d9872b4c576cb17c117b67e74975d3b0a7c3ce Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Mon, 20 Oct 2014 17:04:48 -0400 Subject: [PATCH 74/84] e-comp-wl: Que a buffer release after we have committed the pending buffer Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index ae21a9be8..043b1ce0a 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -701,11 +701,13 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resou return; } - /* clear any pending buffer - * - * NB: This will call any buffer_destroy function associated */ + /* clear any pending buffer */ if (ec->comp_data->pending.buffer) - wl_list_remove(&ec->comp_data->pending.buffer_destroy.link); + wl_resource_queue_event(ec->comp_data->pending.buffer->resource, + WL_BUFFER_RELEASE); + + /* if (ec->comp_data->pending.buffer) */ + /* wl_list_remove(&ec->comp_data->pending.buffer_destroy.link); */ /* reset client pending information */ ec->comp_data->pending.x = 0; @@ -713,7 +715,7 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resou ec->comp_data->pending.w = 0; ec->comp_data->pending.h = 0; ec->comp_data->pending.buffer = NULL; - ec->comp_data->pending.new_attach = EINA_TRUE; + ec->comp_data->pending.new_attach = EINA_FALSE; if (buffer_resource) { @@ -732,7 +734,8 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resou ec->comp_data->pending.x = sx; ec->comp_data->pending.y = sy; ec->comp_data->pending.buffer = buffer; - + ec->comp_data->pending.new_attach = EINA_TRUE; + /* check for this resource being a shm buffer */ if ((shmb = wl_shm_buffer_get(buffer_resource))) { @@ -743,8 +746,8 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resou /* add buffer destroy signal so we get notified when this buffer * gets destroyed (callback set in buffer_get function) */ - wl_signal_add(&buffer->destroy_signal, - &ec->comp_data->pending.buffer_destroy); + /* wl_signal_add(&buffer->destroy_signal, */ + /* &ec->comp_data->pending.buffer_destroy); */ } } @@ -774,10 +777,11 @@ _e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_res } } + if (e_object_is_del(E_OBJECT(ec))) return; if (!ec->comp_data) return; /* create new damage rectangle */ - dmg = eina_rectangle_new(x, y, w, h); + if (!(dmg = eina_rectangle_new(x, y, w, h))) return; /* add damage rectangle to list of pending damages */ ec->comp_data->pending.damages = @@ -1499,8 +1503,6 @@ e_comp_wl_surface_commit(E_Client *ec) if (ec->comp_data->pending.new_attach) { - /* TODO: buffer reference */ - if (ec->comp_data->pending.buffer) e_pixmap_resource_set(ep, ec->comp_data->pending.buffer->resource); else @@ -1508,6 +1510,11 @@ e_comp_wl_surface_commit(E_Client *ec) e_pixmap_usable_set(ep, (ec->comp_data->pending.buffer != NULL)); } + else + { + e_pixmap_resource_set(ep, NULL); + e_pixmap_usable_set(ep, (ec->comp_data->pending.buffer != NULL)); + } /* mark the pixmap as dirty */ e_pixmap_dirty(ep); @@ -1551,6 +1558,18 @@ e_comp_wl_surface_commit(E_Client *ec) } } + if (ec->comp_data->pending.buffer) + wl_resource_queue_event(ec->comp_data->pending.buffer->resource, + WL_BUFFER_RELEASE); + + /* reset client pending information */ + ec->comp_data->pending.x = 0; + ec->comp_data->pending.y = 0; + ec->comp_data->pending.w = 0; + ec->comp_data->pending.h = 0; + ec->comp_data->pending.buffer = NULL; + ec->comp_data->pending.new_attach = EINA_FALSE; + if (!ec->visible) { DBG("\tSurface Not Visible. Skip to Unmapped"); From d2360f569cc1f3268b31cfb8bf9cb7318be351b4 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 22 Oct 2014 11:44:48 -0400 Subject: [PATCH 75/84] e-comp-wl: Remove resize.width & height from structure Signed-off-by: Chris Michael --- src/bin/e_comp_wl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h index 19f6bc2ec..3d46d6339 100644 --- a/src/bin/e_comp_wl.h +++ b/src/bin/e_comp_wl.h @@ -188,7 +188,6 @@ struct _E_Comp_Wl_Data struct { struct wl_resource *resource; - int32_t width, height; uint32_t edges; } resize; From 458ce8e86fd4f497197d43246400b148a13053f1 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 22 Oct 2014 11:45:22 -0400 Subject: [PATCH 76/84] remove call to release compositor buffer reference in e_pixmap. This is handled differently now. Signed-off-by: Chris Michael --- src/bin/e_pixmap.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/bin/e_pixmap.c b/src/bin/e_pixmap.c index ed8552ec1..fb34f1814 100644 --- a/src/bin/e_pixmap.c +++ b/src/bin/e_pixmap.c @@ -619,12 +619,6 @@ e_pixmap_image_clear(E_Pixmap *cp, Eina_Bool cache) wl_callback_send_done(cb, (ecore_loop_time_get() * 1000)); wl_resource_destroy(cb); } - - /* post a buffer release */ - /* TODO: FIXME: We need a way to determine if the client wants to - * keep the buffer or not. If so, then we should Not be setting NULL - * here as this will essentially release the buffer */ - e_comp_wl_buffer_reference(&cd->buffer_ref, NULL); } #endif break; From 1203b36635ddff89fd0670703a6782d4feda2221 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 22 Oct 2014 11:47:53 -0400 Subject: [PATCH 77/84] wl_desktop_shell: Remove resize.width/height compositor data fields. Add some debugging print outs. Don't check client size compared to new size. Signed-off-by: Chris Michael --- src/modules/wl_desktop_shell/e_mod_main.c | 31 +++++++++++++---------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/modules/wl_desktop_shell/e_mod_main.c b/src/modules/wl_desktop_shell/e_mod_main.c index a7d2b0b36..28942cbc7 100644 --- a/src/modules/wl_desktop_shell/e_mod_main.c +++ b/src/modules/wl_desktop_shell/e_mod_main.c @@ -224,10 +224,10 @@ _e_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resou return; } + DBG("Comp Resize Edges Set: %d", edges); + cdata->resize.resource = resource; cdata->resize.edges = edges; - cdata->resize.width = ec->client.w; - cdata->resize.height = ec->client.h; cdata->ptr.grab_x = cdata->ptr.x; cdata->ptr.grab_y = cdata->ptr.y; @@ -480,7 +480,7 @@ _e_shell_surface_configure(struct wl_resource *resource, Evas_Coord x, Evas_Coor ec->changes.pos = EINA_TRUE; } - if ((ec->client.w != w) || (ec->client.h != h)) +// if ((ec->client.w != w) || (ec->client.h != h)) { ec->client.w = w; ec->client.h = h; @@ -641,8 +641,8 @@ _e_xdg_shell_surface_configure_send(struct wl_resource *resource, uint32_t edges uint32_t *s; uint32_t serial; - DBG("XDG_SHELL: Surface Configure Send: %d \t%d %d", - wl_resource_get_id(resource), width, height); + DBG("XDG_SHELL: Surface Configure Send: %d \t%d %d\tEdges: %d", + wl_resource_get_id(resource), width, height, edges); /* get the client for this resource */ if (!(ec = wl_resource_get_user_data(resource))) @@ -668,7 +668,6 @@ _e_xdg_shell_surface_configure_send(struct wl_resource *resource, uint32_t edges if (edges != 0) { - DBG("\tResizing"); s = wl_array_add(&states, sizeof(*s)); *s = XDG_SURFACE_STATE_RESIZING; } @@ -828,7 +827,8 @@ _e_xdg_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_r E_Comp_Data *cdata; E_Binding_Event_Mouse_Button ev; - /* DBG("XDG_SHELL: Surface Resize"); */ + DBG("XDG_SHELL: Surface Resize: %d\tEdges: %d", + wl_resource_get_id(resource), edges); /* get the client for this resource */ if (!(ec = wl_resource_get_user_data(resource))) @@ -853,10 +853,10 @@ _e_xdg_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_r return; } + DBG("Comp Resize Edges Set: %d", edges); + cdata->resize.resource = resource; cdata->resize.edges = edges; - cdata->resize.width = ec->client.w; - cdata->resize.height = ec->client.h; cdata->ptr.grab_x = cdata->ptr.x; cdata->ptr.grab_y = cdata->ptr.y; @@ -1032,8 +1032,8 @@ _e_xdg_shell_surface_configure(struct wl_resource *resource, Evas_Coord x, Evas_ { E_Client *ec; - /* DBG("XDG_SHELL: Surface Configure: %d \t%d %d %d %d", */ - /* wl_resource_get_id(resource), x, y, w, h); */ + DBG("XDG_SHELL: Surface Configure: %d \t%d %d %d %d", + wl_resource_get_id(resource), x, y, w, h); /* get the client for this resource */ if (!(ec = wl_resource_get_user_data(resource))) @@ -1044,6 +1044,8 @@ _e_xdg_shell_surface_configure(struct wl_resource *resource, Evas_Coord x, Evas_ return; } + DBG("\tClient Size: %d %d", ec->client.w, ec->client.h); + if (ec->parent) { if ((ec->netwm.type == E_WINDOW_TYPE_MENU) || @@ -1064,7 +1066,7 @@ _e_xdg_shell_surface_configure(struct wl_resource *resource, Evas_Coord x, Evas_ ec->changes.pos = EINA_TRUE; } - if ((ec->client.w != w) || (ec->client.h != h)) +// if ((ec->client.w != w) || (ec->client.h != h)) { ec->client.w = w; ec->client.h = h; @@ -1073,7 +1075,10 @@ _e_xdg_shell_surface_configure(struct wl_resource *resource, Evas_Coord x, Evas_ ec->changes.size = EINA_TRUE; } - if (ec->changes.pos) EC_CHANGED(ec); + /* TODO: ack configure ?? */ + + if ((ec->changes.pos) || (ec->changes.size)) + EC_CHANGED(ec); } static void From 1fd35b0636dcad90c3f67defbb538f3e7779c6b6 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 22 Oct 2014 11:49:28 -0400 Subject: [PATCH 78/84] wl_desktop_shell: Remove silly debug message Signed-off-by: Chris Michael --- src/modules/wl_desktop_shell/e_mod_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/modules/wl_desktop_shell/e_mod_main.c b/src/modules/wl_desktop_shell/e_mod_main.c index 28942cbc7..71d4f5476 100644 --- a/src/modules/wl_desktop_shell/e_mod_main.c +++ b/src/modules/wl_desktop_shell/e_mod_main.c @@ -853,8 +853,6 @@ _e_xdg_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_r return; } - DBG("Comp Resize Edges Set: %d", edges); - cdata->resize.resource = resource; cdata->resize.edges = edges; cdata->ptr.grab_x = cdata->ptr.x; From 1bc93687db301f59cb825931eb0c4dbafe8d4ee5 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 22 Oct 2014 11:50:41 -0400 Subject: [PATCH 79/84] e_comp_wl: Cleanup resizing of wayland clients. This hooks into various resize callbacks to set/unset the resize edges and to update the surface size. Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 180 ++++++++++++++++++++++++++++++-------------- 1 file changed, 124 insertions(+), 56 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 043b1ce0a..7d523da25 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -283,8 +283,6 @@ _e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj break; } - ec->comp->wl_comp_data->resize.edges = 0; - ec->comp->wl_comp_data->resize.resource = NULL; ec->comp->wl_comp_data->ptr.button = btn; wc = wl_resource_get_client(ec->comp_data->surface); @@ -500,28 +498,6 @@ _e_comp_wl_evas_cb_color_set(void *data, Evas_Object *obj, void *event EINA_UNUS if (ec->netwm.opacity == a) return; ec->netwm.opacity = a; ec->netwm.opacity_changed = EINA_TRUE; - // _e_comp_wl_client_idler_add(ec); -} - -static void -_e_comp_wl_evas_cb_resize(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) -{ - E_Client *ec; - - if (!(ec = data)) return; - if ((ec->shading) || (ec->shaded)) return; - - DBG("Evas Resize Surface %d", - wl_resource_get_id(ec->comp_data->shell.surface)); - DBG("\tNew Size: %d %d", ec->client.w, ec->client.h); - -// if (!e_pixmap_size_changed(ec->pixmap, ec->client.w, ec->client.h)) -// return; - - ec->post_resize = EINA_TRUE; - /* e_pixmap_dirty(ec->pixmap); */ - e_comp_object_render_update_del(ec->frame); - // _e_comp_wl_client_idler_add(ec); } static void @@ -563,10 +539,6 @@ _e_comp_wl_client_evas_init(E_Client *ec) evas_object_smart_callback_add(ec->frame, "color_set", _e_comp_wl_evas_cb_color_set, ec); - if (!ec->override) - evas_object_smart_callback_add(ec->frame, "client_resize", - _e_comp_wl_evas_cb_resize, ec); - ec->comp_data->evas_init = EINA_TRUE; } @@ -585,9 +557,6 @@ _e_comp_wl_cb_comp_object_add(void *data EINA_UNUSED, int type EINA_UNUSED, E_Ev /* check for wayland pixmap */ E_COMP_WL_PIXMAP_CHECK ECORE_CALLBACK_RENEW; - DBG("Comp Object Added For Pixmap: %"PRIu64"", - e_pixmap_window_get(ec->pixmap)); - /* if we have not setup evas callbacks for this client, do it */ if (!ec->comp_data->evas_init) _e_comp_wl_client_evas_init(ec); @@ -604,7 +573,6 @@ _e_comp_wl_buffer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSE { DBG("Buffer Cb Destroy: %d", wl_resource_get_id(buffer->resource)); - DBG("\tEmit buffer destroy signal"); /* emit the destroy signal */ wl_signal_emit(&buffer->destroy_signal, buffer); @@ -715,7 +683,7 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resou ec->comp_data->pending.w = 0; ec->comp_data->pending.h = 0; ec->comp_data->pending.buffer = NULL; - ec->comp_data->pending.new_attach = EINA_FALSE; + ec->comp_data->pending.new_attach = EINA_TRUE; if (buffer_resource) { @@ -734,7 +702,6 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resou ec->comp_data->pending.x = sx; ec->comp_data->pending.y = sy; ec->comp_data->pending.buffer = buffer; - ec->comp_data->pending.new_attach = EINA_TRUE; /* check for this resource being a shm buffer */ if ((shmb = wl_shm_buffer_get(buffer_resource))) @@ -742,12 +709,9 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resou /* 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); + DBG("\tPending Size: %d %d", + ec->comp_data->pending.w, ec->comp_data->pending.h); } - - /* add buffer destroy signal so we get notified when this buffer - * gets destroyed (callback set in buffer_get function) */ - /* wl_signal_add(&buffer->destroy_signal, */ - /* &ec->comp_data->pending.buffer_destroy); */ } } @@ -1310,6 +1274,109 @@ _e_comp_wl_client_cb_focus_unset(void *data EINA_UNUSED, E_Client *ec) ec->comp->wl_comp_data->kbd.focus = NULL; } +static void +_e_comp_wl_client_cb_resize_begin(void *data EINA_UNUSED, E_Client *ec) +{ + int pw, ph; + + E_COMP_WL_PIXMAP_CHECK; + + DBG("Client Resize Begin"); + DBG("\tClient Size: %d %d", ec->client.w, ec->client.h); + + e_pixmap_size_get(ec->pixmap, &pw, &ph); + DBG("\tPixmap Size: %d %d", pw, ph); + + switch (ec->resize_mode) + { + case E_POINTER_RESIZE_T: // 1 + DBG("\tResize From Top"); + ec->comp->wl_comp_data->resize.edges = 1; + break; + case E_POINTER_RESIZE_B: // 2 + DBG("\tResize From Bottom"); + ec->comp->wl_comp_data->resize.edges = 2; + break; + case E_POINTER_RESIZE_L: // 4 + DBG("\tResize From Left"); + ec->comp->wl_comp_data->resize.edges = 4; + break; + case E_POINTER_RESIZE_R: // 8 + DBG("\tResize From Right"); + ec->comp->wl_comp_data->resize.edges = 8; + break; + case E_POINTER_RESIZE_TL: // 5 + DBG("\tResize From Top Left"); + ec->comp->wl_comp_data->resize.edges = 5; + break; + case E_POINTER_RESIZE_TR: // 9 + DBG("\tResize From Top Right"); + ec->comp->wl_comp_data->resize.edges = 9; + break; + case E_POINTER_RESIZE_BL: // 6 + DBG("\tResize From Bottom Left"); + ec->comp->wl_comp_data->resize.edges = 6; + break; + case E_POINTER_RESIZE_BR: // 10 + DBG("\tResize From Bottom Right"); + ec->comp->wl_comp_data->resize.edges = 10; + break; + default: + ec->comp->wl_comp_data->resize.edges = 0; + break; + } +} + +static void +_e_comp_wl_client_cb_resize_update(void *data EINA_UNUSED, E_Client *ec) +{ + int pw, ph; + + E_COMP_WL_PIXMAP_CHECK; + + DBG("Client Resize Update"); + DBG("\tClient Size: %d %d", ec->client.w, ec->client.h); + + e_pixmap_size_get(ec->pixmap, &pw, &ph); + DBG("\tPixmap Size: %d %d", pw, ph); + + if ((ec->comp_data) && (ec->comp_data->shell.configure_send)) + { + DBG("\tSend Configure: %d %d\tEdges: %d", pw, ph, + ec->comp->wl_comp_data->resize.edges); + ec->comp_data->shell.configure_send(ec->comp_data->shell.surface, + ec->comp->wl_comp_data->resize.edges, + pw, ph); + } +} + +static void +_e_comp_wl_client_cb_resize_end(void *data EINA_UNUSED, E_Client *ec) +{ + int pw, ph; + + E_COMP_WL_PIXMAP_CHECK; + + DBG("Client Resize End"); + DBG("\tClient Size: %d %d", ec->client.w, ec->client.h); + + e_pixmap_size_get(ec->pixmap, &pw, &ph); + DBG("\tPixmap Size: %d %d", pw, ph); + + ec->comp->wl_comp_data->resize.edges = 0; + ec->comp->wl_comp_data->resize.resource = NULL; + + if (ec->pending_resize) + { + DBG("\tPending Resize"); + EC_CHANGED(ec); + ec->changes.pos = 1; + ec->changes.size = 1; + } + + E_FREE_LIST(ec->pending_resize, free); +} + static Eina_Bool _e_comp_wl_compositor_create(void) { @@ -1458,6 +1525,13 @@ e_comp_wl_init(void) e_client_hook_add(E_CLIENT_HOOK_FOCUS_UNSET, _e_comp_wl_client_cb_focus_unset, NULL); + e_client_hook_add(E_CLIENT_HOOK_RESIZE_BEGIN, + _e_comp_wl_client_cb_resize_begin, NULL); + e_client_hook_add(E_CLIENT_HOOK_RESIZE_UPDATE, + _e_comp_wl_client_cb_resize_update, NULL); + e_client_hook_add(E_CLIENT_HOOK_RESIZE_END, + _e_comp_wl_client_cb_resize_end, NULL); + return EINA_TRUE; } @@ -1501,20 +1575,13 @@ e_comp_wl_surface_commit(E_Client *ec) if (!(ep = ec->pixmap)) return EINA_FALSE; - if (ec->comp_data->pending.new_attach) - { - if (ec->comp_data->pending.buffer) - e_pixmap_resource_set(ep, ec->comp_data->pending.buffer->resource); - else - e_pixmap_resource_set(ep, NULL); - - e_pixmap_usable_set(ep, (ec->comp_data->pending.buffer != NULL)); - } + if (ec->comp_data->pending.buffer) + e_pixmap_resource_set(ep, ec->comp_data->pending.buffer->resource); else - { - e_pixmap_resource_set(ep, NULL); - e_pixmap_usable_set(ep, (ec->comp_data->pending.buffer != NULL)); - } + e_pixmap_resource_set(ep, NULL); + + /* mark the pixmap as usable or not */ + e_pixmap_usable_set(ep, (ec->comp_data->pending.buffer != NULL)); /* mark the pixmap as dirty */ e_pixmap_dirty(ep); @@ -1526,6 +1593,11 @@ e_comp_wl_surface_commit(E_Client *ec) if ((ec->client.w != ec->comp_data->pending.w) || (ec->client.h != ec->comp_data->pending.h)) { + DBG("\tSurface Commit Sizes Different"); + DBG("\t\tClient Size: %d %d", ec->client.w, ec->client.h); + DBG("\t\tPending Size: %d %d", + ec->comp_data->pending.w, ec->comp_data->pending.h); + /* if the client has a shell configure, call it */ if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.configure)) @@ -1558,10 +1630,6 @@ e_comp_wl_surface_commit(E_Client *ec) } } - if (ec->comp_data->pending.buffer) - wl_resource_queue_event(ec->comp_data->pending.buffer->resource, - WL_BUFFER_RELEASE); - /* reset client pending information */ ec->comp_data->pending.x = 0; ec->comp_data->pending.y = 0; From 89ae4607c9cc02a5339571cace4d727b5429cdc8 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 22 Oct 2014 12:06:36 -0400 Subject: [PATCH 80/84] e_comp_wl: Add hooks for focus in/out events so we can set wayland focus Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 84 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 7d523da25..1ed46ff88 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -415,6 +415,84 @@ _e_comp_wl_evas_cb_key_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj E e_comp_wl_input_keyboard_state_update(cdata, keycode, EINA_FALSE); } +static void +_e_comp_wl_evas_cb_focus_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + E_Client *ec, *focused; + E_Comp_Data *cdata; + struct wl_resource *res; + struct wl_client *wc; + uint32_t serial, *k; + Eina_List *l; + + if (!(ec = data)) return; + if (e_object_is_del(E_OBJECT(ec))) return; + if (ec->iconic) return; + + E_COMP_WL_PIXMAP_CHECK; + + /* block spurious focus events */ + focused = e_client_focused_get(); + if ((focused) && (ec != focused)) return; + + DBG("Focus In On Surface: %d", + wl_resource_get_id(ec->comp_data->surface)); + + /* TODO: Priority raise */ + + cdata = ec->comp->wl_comp_data; + + /* update keyboard modifier state */ + wl_array_for_each(k, &cdata->kbd.keys) + e_comp_wl_input_keyboard_state_update(cdata, *k, EINA_TRUE); + + /* send keyboard_enter to all keyboard resources */ + wc = wl_resource_get_client(ec->comp_data->surface); + serial = wl_display_next_serial(cdata->wl.disp); + EINA_LIST_FOREACH(cdata->kbd.resources, l, res) + { + if (wl_resource_get_client(res) != wc) continue; + wl_keyboard_send_enter(res, serial, ec->comp_data->surface, + &cdata->kbd.keys); + } +} + +static void +_e_comp_wl_evas_cb_focus_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + E_Client *ec; + E_Comp_Data *cdata; + struct wl_resource *res; + struct wl_client *wc; + uint32_t serial, *k; + Eina_List *l; + + if (!(ec = data)) return; + if (e_object_is_del(E_OBJECT(ec))) return; + + E_COMP_WL_PIXMAP_CHECK; + + DBG("Focus Out On Surface: %d", + wl_resource_get_id(ec->comp_data->surface)); + + /* TODO: set normal priority */ + + cdata = ec->comp->wl_comp_data; + + /* update keyboard modifier state */ + wl_array_for_each(k, &cdata->kbd.keys) + e_comp_wl_input_keyboard_state_update(cdata, *k, EINA_FALSE); + + /* send keyboard_leave to all keyboard resources */ + wc = wl_resource_get_client(ec->comp_data->surface); + serial = wl_display_next_serial(cdata->wl.disp); + EINA_LIST_FOREACH(cdata->kbd.resources, l, res) + { + if (wl_resource_get_client(res) != wc) continue; + wl_keyboard_send_leave(res, serial, ec->comp_data->surface); + } +} + static void _e_comp_wl_evas_cb_delete_request(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) { @@ -526,6 +604,12 @@ _e_comp_wl_client_evas_init(E_Client *ec) evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_KEY_UP, _e_comp_wl_evas_cb_key_up, ec); + + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_FOCUS_IN, + _e_comp_wl_evas_cb_focus_in, ec); + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_FOCUS_OUT, + _e_comp_wl_evas_cb_focus_out, ec); + /* setup delete/kill callbacks */ evas_object_smart_callback_add(ec->frame, "delete_request", _e_comp_wl_evas_cb_delete_request, ec); From c0c911af91db561fea0641d3fdfda8a6cee3d18d Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 22 Oct 2014 12:16:31 -0400 Subject: [PATCH 81/84] e_comp_wl: Implement surface frame callback support Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 1ed46ff88..3a67c9b7e 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -836,10 +836,61 @@ _e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_res eina_list_append(ec->comp_data->pending.damages, dmg); } +static void +_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; + + DBG("Frame Cb Destroy: %d", wl_resource_get_id(resource)); + + /* remove this frame callback */ + ec->comp_data->frames = eina_list_remove(ec->comp_data->frames, resource); +} + static void _e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resource, uint32_t callback) { + E_Pixmap *ep; + E_Client *ec; + struct wl_resource *res; + DBG("Surface Cb Frame: %d", wl_resource_get_id(resource)); + + if (!(ep = wl_resource_get_user_data(resource))) return; + + /* try to find the associated e_client */ + if (!(ec = e_pixmap_client_get(ep))) + { + uint64_t pixid; + + pixid = e_pixmap_window_get(ep); + DBG("\tSurface has Pixmap: %"PRIu64"", pixid); + + if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) + { + ERR("\tCould not find client from pixmap %"PRIu64"", pixid); + return; + } + } + + if (e_object_is_del(E_OBJECT(ec))) return; + + /* create frame callback */ + if (!(res = + wl_resource_create(client, &wl_callback_interface, 1, callback))) + { + wl_resource_post_no_memory(resource); + return; + } + + 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); } static void From 240d651d2f67c4d94db1ade12f1731e155b417bd Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Fri, 31 Oct 2014 12:26:50 -0400 Subject: [PATCH 82/84] send wl_buffer release after we have drawn this pixmap Signed-off-by: Chris Michael --- src/bin/e_pixmap.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bin/e_pixmap.c b/src/bin/e_pixmap.c index fb34f1814..b4b639a14 100644 --- a/src/bin/e_pixmap.c +++ b/src/bin/e_pixmap.c @@ -620,6 +620,12 @@ e_pixmap_image_clear(E_Pixmap *cp, Eina_Bool cache) wl_resource_destroy(cb); } } + + if (cache) + { + if (cp->resource) wl_buffer_send_release(cp->resource); + cp->resource = NULL; + } #endif break; default: From 770b3e5f26eac500f1e3c8f31bce318959ebd141 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Fri, 31 Oct 2014 12:27:41 -0400 Subject: [PATCH 83/84] change comp_wl_data structure to store the wl_resource of the client buffer. No longer dealing with reference buffers. Signed-off-by: Chris Michael --- src/bin/e_comp_wl.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h index 3d46d6339..591328ca6 100644 --- a/src/bin/e_comp_wl.h +++ b/src/bin/e_comp_wl.h @@ -240,8 +240,7 @@ struct _E_Comp_Wl_Client_Data struct { int32_t x, y, w, h; - E_Comp_Wl_Buffer *buffer; - struct wl_listener buffer_destroy; + struct wl_resource *buffer; Eina_Bool new_attach : 1; Eina_List *damages; Eina_Tiler *input; From db795bbb5de6078e3a361e19c6b332620f526d6e Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Fri, 31 Oct 2014 12:33:09 -0400 Subject: [PATCH 84/84] e-comp-wl: Make new compositor functional. - Remove client_window_hash (not needed). - Add hook for evas resize and update surface (configure_send) during resize. - Remove old buffer_refenerce mechanism - Refresh pixmap on surface commit Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 285 +++++++++++++------------------------------- 1 file changed, 84 insertions(+), 201 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 3a67c9b7e..d455b5830 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -18,7 +18,7 @@ */ /* local variables */ -static Eina_Hash *clients_win_hash = NULL; +/* static Eina_Hash *clients_win_hash = NULL; */ static Eina_List *handlers = NULL; /* local functions */ @@ -435,9 +435,6 @@ _e_comp_wl_evas_cb_focus_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj focused = e_client_focused_get(); if ((focused) && (ec != focused)) return; - DBG("Focus In On Surface: %d", - wl_resource_get_id(ec->comp_data->surface)); - /* TODO: Priority raise */ cdata = ec->comp->wl_comp_data; @@ -472,9 +469,6 @@ _e_comp_wl_evas_cb_focus_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *ob E_COMP_WL_PIXMAP_CHECK; - DBG("Focus Out On Surface: %d", - wl_resource_get_id(ec->comp_data->surface)); - /* TODO: set normal priority */ cdata = ec->comp->wl_comp_data; @@ -493,6 +487,21 @@ _e_comp_wl_evas_cb_focus_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *ob } } +static void +_e_comp_wl_evas_cb_resize(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + E_Client *ec; + + if (!(ec = data)) return; + + E_COMP_WL_PIXMAP_CHECK; + + if ((ec->comp_data) && (ec->comp_data->shell.configure_send)) + ec->comp_data->shell.configure_send(ec->comp_data->shell.surface, + ec->comp->wl_comp_data->resize.edges, + ec->client.w, ec->client.h); +} + static void _e_comp_wl_evas_cb_delete_request(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) { @@ -610,6 +619,12 @@ _e_comp_wl_client_evas_init(E_Client *ec) evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_FOCUS_OUT, _e_comp_wl_evas_cb_focus_out, ec); + if (!ec->override) + { + evas_object_smart_callback_add(ec->frame, "client_resize", + _e_comp_wl_evas_cb_resize, ec); + } + /* setup delete/kill callbacks */ evas_object_smart_callback_add(ec->frame, "delete_request", _e_comp_wl_evas_cb_delete_request, ec); @@ -647,58 +662,6 @@ _e_comp_wl_cb_comp_object_add(void *data EINA_UNUSED, int type EINA_UNUSED, E_Ev return ECORE_CALLBACK_RENEW; } -static void -_e_comp_wl_buffer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED) -{ - E_Comp_Wl_Buffer *buffer; - - /* try to get the buffer from the listener */ - if ((buffer = container_of(listener, E_Comp_Wl_Buffer, destroy_listener))) - { - DBG("Buffer Cb Destroy: %d", wl_resource_get_id(buffer->resource)); - - /* emit the destroy signal */ - wl_signal_emit(&buffer->destroy_signal, buffer); - - /* FIXME: Investigate validity of this - * - * I think this could be a problem because the destroy signal - * uses the buffer as the 'data', so anything that catches - * this signal is going to run into problems if we free */ - free(buffer); - } -} - -static E_Comp_Wl_Buffer * -_e_comp_wl_buffer_get(struct wl_resource *resource) -{ - E_Comp_Wl_Buffer *buffer; - struct wl_listener *listener; - - /* try to get the destroy listener from this resource */ - listener = - wl_resource_get_destroy_listener(resource, _e_comp_wl_buffer_cb_destroy); - - /* if we have the destroy listener, return the E_Comp_Wl_Buffer */ - if (listener) - return container_of(listener, E_Comp_Wl_Buffer, destroy_listener); - - /* no destroy listener on this resource, try to create new buffer */ - if (!(buffer = E_NEW(E_Comp_Wl_Buffer, 1))) return NULL; - - DBG("Create New Buffer: %d", wl_resource_get_id(resource)); - - /* initialize buffer structure */ - buffer->resource = resource; - wl_signal_init(&buffer->destroy_signal); - - /* setup buffer destroy callback */ - buffer->destroy_listener.notify = _e_comp_wl_buffer_cb_destroy; - wl_resource_add_destroy_listener(resource, &buffer->destroy_listener); - - return buffer; -} - static void _e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) { @@ -715,10 +678,9 @@ _e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_re } static void -_e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer_resource, int32_t sx, int32_t sy) +_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; - uint64_t pixid; E_Client *ec; DBG("Surface Attach: %d", wl_resource_get_id(resource)); @@ -726,12 +688,12 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resou /* get the e_pixmap reference */ if (!(ep = wl_resource_get_user_data(resource))) return; - pixid = e_pixmap_window_get(ep); - DBG("\tSurface has Pixmap: %"PRIu64"", pixid); - /* try to find the associated e_client */ if (!(ec = e_pixmap_client_get(ep))) { + uint64_t pixid; + + pixid = e_pixmap_window_get(ep); if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) { ERR("\t\tCould not find client from pixmap %"PRIu64"", pixid); @@ -753,39 +715,17 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resou return; } - /* clear any pending buffer */ - if (ec->comp_data->pending.buffer) - wl_resource_queue_event(ec->comp_data->pending.buffer->resource, - WL_BUFFER_RELEASE); - - /* if (ec->comp_data->pending.buffer) */ - /* wl_list_remove(&ec->comp_data->pending.buffer_destroy.link); */ - /* reset client pending information */ - ec->comp_data->pending.x = 0; - ec->comp_data->pending.y = 0; + 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 = NULL; + ec->comp_data->pending.buffer = buffer_resource; ec->comp_data->pending.new_attach = EINA_TRUE; if (buffer_resource) { - E_Comp_Wl_Buffer *buffer = NULL; struct wl_shm_buffer *shmb; - - /* try to get the E_Comp_Wl_Buffer */ - if (!(buffer = _e_comp_wl_buffer_get(buffer_resource))) - { - ERR("\tCould not get E_Comp_Wl_Buffer"); - wl_client_post_no_memory(client); - return; - } - - /* since we have a valid buffer, set pending properties */ - ec->comp_data->pending.x = sx; - ec->comp_data->pending.y = sy; - ec->comp_data->pending.buffer = buffer; /* check for this resource being a shm buffer */ if ((shmb = wl_shm_buffer_get(buffer_resource))) @@ -793,8 +733,6 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client, struct wl_resource *resou /* 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); - DBG("\tPending Size: %d %d", - ec->comp_data->pending.w, ec->comp_data->pending.h); } } } @@ -803,7 +741,6 @@ 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; - uint64_t pixid; E_Client *ec; Eina_Rectangle *dmg = NULL; @@ -813,11 +750,12 @@ _e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_res /* get the e_pixmap reference */ if (!(ep = wl_resource_get_user_data(resource))) return; - pixid = e_pixmap_window_get(ep); - /* try to find the associated e_client */ if (!(ec = e_pixmap_client_get(ep))) { + uint64_t pixid; + + pixid = e_pixmap_window_get(ep); if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) { ERR("\tCould not find client from pixmap %"PRIu64"", pixid); @@ -845,8 +783,6 @@ _e_comp_wl_frame_cb_destroy(struct wl_resource *resource) if (e_object_is_del(E_OBJECT(ec))) return; - DBG("Frame Cb Destroy: %d", wl_resource_get_id(resource)); - /* remove this frame callback */ ec->comp_data->frames = eina_list_remove(ec->comp_data->frames, resource); } @@ -858,8 +794,6 @@ _e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resour E_Client *ec; struct wl_resource *res; - DBG("Surface Cb Frame: %d", wl_resource_get_id(resource)); - if (!(ep = wl_resource_get_user_data(resource))) return; /* try to find the associated e_client */ @@ -868,8 +802,6 @@ _e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resour uint64_t pixid; pixid = e_pixmap_window_get(ep); - DBG("\tSurface has Pixmap: %"PRIu64"", pixid); - if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) { ERR("\tCould not find client from pixmap %"PRIu64"", pixid); @@ -897,20 +829,17 @@ static void _e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource) { E_Pixmap *ep; - uint64_t pixid; E_Client *ec; - DBG("Surface Opaque Region Set: %d", wl_resource_get_id(resource)); - /* get the e_pixmap reference */ if (!(ep = wl_resource_get_user_data(resource))) return; - pixid = e_pixmap_window_get(ep); - DBG("\tSurface has Pixmap: %"PRIu64"", pixid); - /* try to find the associated e_client */ if (!(ec = e_pixmap_client_get(ep))) { + uint64_t pixid; + + pixid = e_pixmap_window_get(ep); if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) { ERR("\tCould not find client from pixmap %"PRIu64"", pixid); @@ -943,20 +872,17 @@ static void _e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource) { E_Pixmap *ep; - uint64_t pixid; E_Client *ec; - DBG("Surface Input Region Set: %d", wl_resource_get_id(resource)); - /* get the e_pixmap reference */ if (!(ep = wl_resource_get_user_data(resource))) return; - pixid = e_pixmap_window_get(ep); - DBG("\tSurface has Pixmap: %"PRIu64, pixid); - /* try to find the associated e_client */ if (!(ec = e_pixmap_client_get(ep))) { + uint64_t pixid; + + pixid = e_pixmap_window_get(ep); if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) { ERR("\tCould not find client from pixmap %"PRIu64, pixid); @@ -989,7 +915,6 @@ static void _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) { E_Pixmap *ep; - uint64_t pixid; E_Client *ec; DBG("Surface Commit: %d", wl_resource_get_id(resource)); @@ -997,12 +922,12 @@ _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_res /* get the e_pixmap reference */ if (!(ep = wl_resource_get_user_data(resource))) return; - pixid = e_pixmap_window_get(ep); - DBG("\tSurface has Pixmap: %"PRIu64, pixid); - /* try to find the associated e_client */ if (!(ec = e_pixmap_client_get(ep))) { + uint64_t pixid; + + pixid = e_pixmap_window_get(ep); if (!(ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, pixid))) { ERR("\tCould not find client from pixmap %"PRIu64, pixid); @@ -1067,7 +992,6 @@ _e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_reso DBG("\tCreated Resource: %d", wl_resource_get_id(res)); - /* FIXME: set callback ? */ /* set implementation on resource */ wl_resource_set_implementation(res, &_e_surface_interface, NULL, NULL); // _callback); @@ -1304,7 +1228,7 @@ _e_comp_wl_client_cb_new(void *data EINA_UNUSED, E_Client *ec) } /* add this client to the hash */ - eina_hash_add(clients_win_hash, &win, ec); + /* eina_hash_add(clients_win_hash, &win, ec); */ e_hints_client_list_set(); /* TODO: first draw timer ? */ @@ -1313,7 +1237,7 @@ _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; + /* uint64_t win; */ Eina_Rectangle *dmg; DBG("Comp Hook Client Del"); @@ -1322,8 +1246,8 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec) 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); + /* 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); @@ -1332,10 +1256,10 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec) if (ec->comp_data->reparented) { /* get the parent window */ - win = e_client_util_pwin_get(ec); + /* win = e_client_util_pwin_get(ec); */ /* remove the parent from the hash */ - eina_hash_del_by_key(clients_win_hash, &win); + /* eina_hash_del_by_key(clients_win_hash, &win); */ /* reset pixmap parent window */ e_pixmap_parent_window_set(ec->pixmap, 0); @@ -1347,6 +1271,10 @@ _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 */ + wl_resource_set_user_data(ec->comp_data->surface, NULL); + if (ec->comp_data->pending.opaque) eina_tiler_free(ec->comp_data->pending.opaque); @@ -1412,76 +1340,44 @@ _e_comp_wl_client_cb_focus_unset(void *data EINA_UNUSED, E_Client *ec) static void _e_comp_wl_client_cb_resize_begin(void *data EINA_UNUSED, E_Client *ec) { - int pw, ph; - E_COMP_WL_PIXMAP_CHECK; - DBG("Client Resize Begin"); - DBG("\tClient Size: %d %d", ec->client.w, ec->client.h); - - e_pixmap_size_get(ec->pixmap, &pw, &ph); - DBG("\tPixmap Size: %d %d", pw, ph); - switch (ec->resize_mode) { case E_POINTER_RESIZE_T: // 1 - DBG("\tResize From Top"); ec->comp->wl_comp_data->resize.edges = 1; break; case E_POINTER_RESIZE_B: // 2 - DBG("\tResize From Bottom"); ec->comp->wl_comp_data->resize.edges = 2; break; case E_POINTER_RESIZE_L: // 4 - DBG("\tResize From Left"); ec->comp->wl_comp_data->resize.edges = 4; break; case E_POINTER_RESIZE_R: // 8 - DBG("\tResize From Right"); ec->comp->wl_comp_data->resize.edges = 8; break; case E_POINTER_RESIZE_TL: // 5 - DBG("\tResize From Top Left"); ec->comp->wl_comp_data->resize.edges = 5; break; case E_POINTER_RESIZE_TR: // 9 - DBG("\tResize From Top Right"); ec->comp->wl_comp_data->resize.edges = 9; break; case E_POINTER_RESIZE_BL: // 6 - DBG("\tResize From Bottom Left"); ec->comp->wl_comp_data->resize.edges = 6; break; case E_POINTER_RESIZE_BR: // 10 - DBG("\tResize From Bottom Right"); ec->comp->wl_comp_data->resize.edges = 10; break; default: ec->comp->wl_comp_data->resize.edges = 0; break; } -} - -static void -_e_comp_wl_client_cb_resize_update(void *data EINA_UNUSED, E_Client *ec) -{ - int pw, ph; - - E_COMP_WL_PIXMAP_CHECK; - - DBG("Client Resize Update"); - DBG("\tClient Size: %d %d", ec->client.w, ec->client.h); - - e_pixmap_size_get(ec->pixmap, &pw, &ph); - DBG("\tPixmap Size: %d %d", pw, ph); if ((ec->comp_data) && (ec->comp_data->shell.configure_send)) { - DBG("\tSend Configure: %d %d\tEdges: %d", pw, ph, - ec->comp->wl_comp_data->resize.edges); ec->comp_data->shell.configure_send(ec->comp_data->shell.surface, ec->comp->wl_comp_data->resize.edges, - pw, ph); + ec->client.w, ec->client.h); } } @@ -1490,20 +1386,16 @@ _e_comp_wl_client_cb_resize_end(void *data EINA_UNUSED, E_Client *ec) { int pw, ph; + if (e_object_is_del(E_OBJECT(ec))) return; + E_COMP_WL_PIXMAP_CHECK; - DBG("Client Resize End"); - DBG("\tClient Size: %d %d", ec->client.w, ec->client.h); - - e_pixmap_size_get(ec->pixmap, &pw, &ph); - DBG("\tPixmap Size: %d %d", pw, ph); - ec->comp->wl_comp_data->resize.edges = 0; ec->comp->wl_comp_data->resize.resource = NULL; if (ec->pending_resize) { - DBG("\tPending Resize"); + EC_CHANGED(ec); ec->changes.pos = 1; ec->changes.size = 1; @@ -1645,7 +1537,7 @@ e_comp_wl_init(void) } /* create hash to store clients */ - clients_win_hash = eina_hash_int64_new(NULL); + /* clients_win_hash = eina_hash_int64_new(NULL); */ /* add event handlers to catch E events */ E_LIST_HANDLER_APPEND(handlers, E_EVENT_COMP_OBJECT_ADD, @@ -1662,8 +1554,6 @@ e_comp_wl_init(void) e_client_hook_add(E_CLIENT_HOOK_RESIZE_BEGIN, _e_comp_wl_client_cb_resize_begin, NULL); - e_client_hook_add(E_CLIENT_HOOK_RESIZE_UPDATE, - _e_comp_wl_client_cb_resize_update, NULL); e_client_hook_add(E_CLIENT_HOOK_RESIZE_END, _e_comp_wl_client_cb_resize_end, NULL); @@ -1684,7 +1574,7 @@ e_comp_wl_shutdown(void) E_FREE_LIST(handlers, ecore_event_handler_del); /* free the clients win hash */ - E_FREE_FUNC(clients_win_hash, eina_hash_free); + /* E_FREE_FUNC(clients_win_hash, eina_hash_free); */ /* shutdown ecore_wayland */ ecore_wl_shutdown(); @@ -1711,36 +1601,35 @@ e_comp_wl_surface_commit(E_Client *ec) if (!(ep = ec->pixmap)) return EINA_FALSE; if (ec->comp_data->pending.buffer) - e_pixmap_resource_set(ep, ec->comp_data->pending.buffer->resource); - else - e_pixmap_resource_set(ep, NULL); + { + /* set pixmap resource */ + e_pixmap_resource_set(ep, ec->comp_data->pending.buffer); - /* mark the pixmap as usable or not */ - e_pixmap_usable_set(ep, (ec->comp_data->pending.buffer != NULL)); + /* mark the pixmap as usable or not */ + e_pixmap_usable_set(ep, (ec->comp_data->pending.buffer != NULL)); + } /* mark the pixmap as dirty */ e_pixmap_dirty(ep); + e_pixmap_refresh(ep); + /* check for any pending attachments */ if (ec->comp_data->pending.new_attach) { - /* check if the pending size is different than the client size */ - if ((ec->client.w != ec->comp_data->pending.w) || - (ec->client.h != ec->comp_data->pending.h)) - { - DBG("\tSurface Commit Sizes Different"); - DBG("\t\tClient Size: %d %d", ec->client.w, ec->client.h); - DBG("\t\tPending Size: %d %d", - ec->comp_data->pending.w, ec->comp_data->pending.h); - - /* 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, - ec->client.x, ec->client.y, - ec->comp_data->pending.w, - ec->comp_data->pending.h); - } + int nw, nh; + + nw = ec->client.w; + nh = ec->client.h; + if (nw == 0) nw = ec->comp_data->pending.w; + if (nh == 0) nh = ec->comp_data->pending.h; + + /* 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, + ec->client.x, ec->client.y, + nw, nh); } /* check if we need to map this surface */ @@ -1765,17 +1654,9 @@ e_comp_wl_surface_commit(E_Client *ec) } } - /* reset client pending information */ - ec->comp_data->pending.x = 0; - ec->comp_data->pending.y = 0; - ec->comp_data->pending.w = 0; - ec->comp_data->pending.h = 0; - ec->comp_data->pending.buffer = NULL; - ec->comp_data->pending.new_attach = EINA_FALSE; - - if (!ec->visible) + if (!ec->comp_data->mapped) { - DBG("\tSurface Not Visible. Skip to Unmapped"); + DBG("\tSurface Not Mapped. Skip to Unmapped"); goto unmap; } @@ -1886,14 +1767,16 @@ e_comp_wl_surface_commit(E_Client *ec) unmap: /* clear pending opaque regions */ - eina_tiler_clear(ec->comp_data->pending.opaque); + if (ec->comp_data->pending.opaque) + eina_tiler_clear(ec->comp_data->pending.opaque); /* surface is not visible, clear damages */ EINA_LIST_FREE(ec->comp_data->pending.damages, dmg) eina_rectangle_free(dmg); /* clear pending input regions */ - eina_tiler_clear(ec->comp_data->pending.input); + if (ec->comp_data->pending.input) + eina_tiler_clear(ec->comp_data->pending.input); return EINA_TRUE; }