From e84c21469d0ba1ff477f3b30912135b3c42fa2bd Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 14 Oct 2014 12:31:15 -0400 Subject: [PATCH] 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; -}