2014-08-04 09:58:49 -07:00
|
|
|
#define E_COMP_WL
|
2014-05-09 02:51:08 -07:00
|
|
|
#include "e.h"
|
2014-08-04 09:58:49 -07:00
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
#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;
|
2014-07-16 07:54:57 -07:00
|
|
|
static Eina_List *subcomp_handlers = NULL;
|
2014-05-09 02:51:08 -07:00
|
|
|
static Eina_Hash *clients_win_hash = NULL;
|
|
|
|
static Ecore_Idle_Enterer *_client_idler = NULL;
|
|
|
|
static Eina_List *_idle_clients = NULL;
|
2014-07-16 07:54:57 -07:00
|
|
|
static Eina_Bool restacking = EINA_FALSE;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-17 11:36:48 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-06-17 11:12:31 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-06-13 05:18:22 -07:00
|
|
|
static void
|
2014-06-13 05:27:33 -07:00
|
|
|
_e_comp_wl_client_event_free(void *d EINA_UNUSED, void *event)
|
2014-06-13 05:18:22 -07:00
|
|
|
{
|
2014-06-13 05:27:33 -07:00
|
|
|
E_Event_Client *ev;
|
2014-06-13 05:18:22 -07:00
|
|
|
|
2014-06-13 05:27:33 -07:00
|
|
|
if (!(ev = event)) return;
|
2014-06-13 05:18:22 -07:00
|
|
|
e_object_unref(E_OBJECT(ev->ec));
|
|
|
|
free(ev);
|
|
|
|
}
|
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
static void
|
|
|
|
_e_comp_wl_buffer_pending_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
E_Comp_Client_Data *cd;
|
2014-06-10 13:43:18 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (!(cd = container_of(listener, E_Comp_Client_Data,
|
2014-06-19 06:31:07 -07:00
|
|
|
pending.buffer_destroy)))
|
|
|
|
return;
|
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
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;
|
|
|
|
|
2014-06-19 06:31:07 -07:00
|
|
|
if (!(buffer = container_of(listener, E_Comp_Wl_Buffer, destroy_listener)))
|
|
|
|
return;
|
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
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);
|
|
|
|
|
2014-06-12 06:09:41 -07:00
|
|
|
if (!(buffer = E_NEW(E_Comp_Wl_Buffer, 1))) return NULL;
|
2014-06-10 13:43:18 -07:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
static void
|
|
|
|
_e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
static E_Comp_Wl_Subsurf *
|
|
|
|
_e_comp_wl_client_subsurf_data_get(E_Client *ec)
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
return ec->comp_data->sub.cdata;
|
2014-07-16 07:54:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
static void
|
2014-06-10 13:43:18 -07:00
|
|
|
_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)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
E_Pixmap *cp;
|
|
|
|
E_Client *ec;
|
2014-06-19 06:31:07 -07:00
|
|
|
E_Comp_Wl_Buffer *buffer = NULL;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
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)
|
2014-06-10 13:43:18 -07:00
|
|
|
{
|
|
|
|
if (!(buffer = _e_comp_wl_buffer_get(buffer_resource)))
|
|
|
|
{
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (!ec->comp_data) return;
|
2014-06-10 13:43:18 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->pending.buffer)
|
|
|
|
wl_list_remove(&ec->comp_data->pending.buffer_destroy.link);
|
2014-06-10 13:43:18 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
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;
|
2014-06-10 13:43:18 -07:00
|
|
|
|
|
|
|
if (buffer)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
struct wl_shm_buffer *b;
|
|
|
|
|
2014-08-26 11:06:57 -07:00
|
|
|
/* 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;
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->pending.w = wl_shm_buffer_get_width(b);
|
|
|
|
ec->comp_data->pending.h = wl_shm_buffer_get_height(b);
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
wl_signal_add(&buffer->destroy_signal,
|
2014-08-04 09:58:49 -07:00
|
|
|
&ec->comp_data->pending.buffer_destroy);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2014-06-10 13:43:18 -07:00
|
|
|
Eina_Tiler *tmp;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2014-07-10 06:38:30 -07:00
|
|
|
tmp = eina_tiler_new(ec->w ?: w, ec->h ?: h);
|
2014-06-10 13:43:18 -07:00
|
|
|
eina_tiler_tile_size_set(tmp, 1, 1);
|
|
|
|
eina_tiler_rect_add(tmp, &(Eina_Rectangle){x, y, w, h});
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
eina_tiler_union(ec->comp_data->pending.damage, tmp);
|
2014-06-10 13:43:18 -07:00
|
|
|
|
|
|
|
eina_tiler_free(tmp);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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 */
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->frames =
|
|
|
|
eina_list_remove(ec->comp_data->frames, resource);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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 */
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->frames = eina_list_prepend(ec->comp_data->frames, res);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2014-06-10 13:43:18 -07:00
|
|
|
Eina_Tiler *tmp;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
if (!(tmp = wl_resource_get_user_data(region_resource)))
|
|
|
|
return;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
eina_tiler_union(ec->comp_data->pending.opaque, tmp);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
eina_tiler_clear(ec->comp_data->pending.opaque);
|
|
|
|
eina_tiler_rect_add(ec->comp_data->pending.opaque,
|
2014-06-10 13:43:18 -07:00
|
|
|
&(Eina_Rectangle){0, 0, ec->client.w, ec->client.h});
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2014-06-10 13:43:18 -07:00
|
|
|
Eina_Tiler *tmp;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
if (!(tmp = wl_resource_get_user_data(region_resource)))
|
|
|
|
return;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
eina_tiler_union(ec->comp_data->pending.input, tmp);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
2014-06-10 13:43:18 -07:00
|
|
|
else
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
eina_tiler_clear(ec->comp_data->pending.input);
|
|
|
|
eina_tiler_rect_add(ec->comp_data->pending.input,
|
2014-06-10 13:43:18 -07:00
|
|
|
&(Eina_Rectangle){0, 0, ec->client.w, ec->client.h});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
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)
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
sub_cdata->parent->comp_data->sub.list
|
|
|
|
= eina_list_remove(sub_cdata->parent->comp_data->sub.list, ec);
|
2014-07-16 07:54:57 -07:00
|
|
|
sub_cdata->parent = NULL;
|
|
|
|
}
|
|
|
|
|
2014-08-04 07:20:45 -07:00
|
|
|
e_comp_wl_buffer_reference(&sub_cdata->cached.buffer_ref, NULL);
|
2014-07-16 07:54:57 -07:00
|
|
|
|
|
|
|
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);
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->sub.cdata = NULL;
|
2014-07-16 07:54:57 -07:00
|
|
|
e_object_del(E_OBJECT(ec));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_subsurface_destroy(struct wl_resource *resource)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
E_Client *ec;
|
2014-07-16 07:54:57 -07:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2014-07-29 05:49:07 -07:00
|
|
|
while (sub_cdata)
|
2014-07-16 07:54:57 -07:00
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
E_Comp_Client_Data *cdata;
|
2014-07-16 07:54:57 -07:00
|
|
|
E_Comp_Wl_Subsurf *sub_cdata;
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (!(cdata = ec->comp_data)) return;
|
2014-07-16 07:54:57 -07:00
|
|
|
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;
|
2014-08-04 07:20:45 -07:00
|
|
|
e_comp_wl_buffer_reference(&sub_cdata->cached.buffer_ref,
|
2014-07-16 07:54:57 -07:00
|
|
|
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)
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
E_Comp_Client_Data *cdata;
|
2014-07-16 07:54:57 -07:00
|
|
|
E_Comp_Wl_Subsurf *sub_cdata;
|
|
|
|
E_Pixmap *cp;
|
2014-06-10 13:43:18 -07:00
|
|
|
Eina_Tiler *src, *tmp;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (!(cdata = ec->comp_data)) return;
|
2014-07-16 07:54:57 -07:00
|
|
|
if (!(sub_cdata = cdata->sub.cdata)) return;
|
|
|
|
if (!(cp = ec->pixmap)) return;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
if (sub_cdata->cached.new_attach)
|
|
|
|
{
|
2014-08-04 07:20:45 -07:00
|
|
|
e_comp_wl_buffer_reference(&cdata->buffer_ref,
|
2014-07-16 07:54:57 -07:00
|
|
|
sub_cdata->cached.buffer_ref.buffer);
|
2014-08-27 05:24:26 -07:00
|
|
|
if (cdata->pending.buffer)
|
|
|
|
e_pixmap_resource_set(cp,
|
|
|
|
cdata->pending.buffer->resource);
|
|
|
|
else
|
|
|
|
e_pixmap_resource_set(cp, NULL);
|
2014-07-16 07:54:57 -07:00
|
|
|
e_pixmap_usable_set(cp, (cdata->pending.buffer != NULL));
|
|
|
|
}
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
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 */
|
2014-09-04 09:48:29 -07:00
|
|
|
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);
|
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
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;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
if (!(cp = ec->pixmap)) return;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->pending.new_attach)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-08-04 07:20:45 -07:00
|
|
|
e_comp_wl_buffer_reference(&ec->comp_data->buffer_ref,
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->pending.buffer);
|
2014-08-27 05:24:26 -07:00
|
|
|
if (ec->comp_data->pending.buffer)
|
|
|
|
e_pixmap_resource_set(cp,
|
|
|
|
ec->comp_data->pending.buffer->resource);
|
|
|
|
else
|
|
|
|
e_pixmap_resource_set(cp, NULL);
|
2014-08-04 09:58:49 -07:00
|
|
|
e_pixmap_usable_set(cp, (ec->comp_data->pending.buffer != NULL));
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
e_pixmap_dirty(cp);
|
|
|
|
e_pixmap_refresh(cp);
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if ((ec->comp_data->shell.surface) &&
|
|
|
|
(ec->comp_data->shell.configure))
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->pending.new_attach)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
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,
|
2014-07-16 07:54:57 -07:00
|
|
|
ec->client.x, ec->client.y,
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->pending.w,
|
|
|
|
ec->comp_data->pending.h);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-05 07:16:16 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->pending.new_attach)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
if (!ec->comp_data->pending.buffer)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->mapped)
|
2014-07-03 07:43:02 -07:00
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
if ((ec->comp_data->shell.surface) &&
|
|
|
|
(ec->comp_data->shell.unmap))
|
|
|
|
ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
|
2014-07-03 07:43:02 -07:00
|
|
|
}
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
2014-07-03 07:43:02 -07:00
|
|
|
else
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
if (!ec->comp_data->mapped)
|
2014-07-03 07:43:02 -07:00
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
if ((ec->comp_data->shell.surface) &&
|
|
|
|
(ec->comp_data->shell.map))
|
|
|
|
ec->comp_data->shell.map(ec->comp_data->shell.surface);
|
2014-07-03 07:43:02 -07:00
|
|
|
}
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
/* reset pending buffer */
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->pending.buffer)
|
|
|
|
wl_list_remove(&ec->comp_data->pending.buffer_destroy.link);
|
2014-06-10 13:43:18 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
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;
|
2014-06-10 13:43:18 -07:00
|
|
|
|
2014-07-17 23:46:42 -07:00
|
|
|
/* 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});
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
src = eina_tiler_intersection(ec->comp_data->pending.opaque, tmp);
|
2014-07-17 23:46:42 -07:00
|
|
|
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);
|
2014-08-04 09:58:49 -07:00
|
|
|
eina_tiler_clear(ec->comp_data->pending.opaque);
|
2014-07-17 23:46:42 -07:00
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
/* handle surface damages */
|
|
|
|
if ((!ec->comp->nocomp) && (ec->frame))
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-06-10 13:43:18 -07:00
|
|
|
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});
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
src = eina_tiler_intersection(ec->comp_data->pending.damage, tmp);
|
2014-06-10 13:43:18 -07:00
|
|
|
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);
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
eina_tiler_clear(ec->comp_data->pending.damage);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
2014-07-17 23:46:42 -07:00
|
|
|
/* handle input regions */
|
2014-06-10 13:43:18 -07:00
|
|
|
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});
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
src = eina_tiler_intersection(ec->comp_data->pending.input, tmp);
|
2014-06-10 13:43:18 -07:00
|
|
|
if (src)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-06-10 13:43:18 -07:00
|
|
|
Eina_Rectangle *rect;
|
|
|
|
Eina_Iterator *itr;
|
|
|
|
int i = 0;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
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);
|
|
|
|
|
2014-07-17 23:46:42 -07:00
|
|
|
if (ec->shape_input_rects)
|
2014-07-16 07:54:57 -07:00
|
|
|
{
|
2014-07-17 23:46:42 -07:00
|
|
|
EINA_ITERATOR_FOREACH(itr, rect)
|
|
|
|
{
|
|
|
|
ec->shape_input_rects[i] =
|
|
|
|
*(Eina_Rectangle *)((char *)rect);
|
2014-07-16 07:54:57 -07:00
|
|
|
|
2014-07-17 23:46:42 -07:00
|
|
|
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;
|
2014-06-10 13:43:18 -07:00
|
|
|
|
2014-07-17 23:46:42 -07:00
|
|
|
i++;
|
|
|
|
}
|
2014-06-10 13:43:18 -07:00
|
|
|
}
|
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
eina_iterator_free(itr);
|
2014-06-10 13:43:18 -07:00
|
|
|
eina_tiler_free(src);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
eina_tiler_free(tmp);
|
2014-08-04 09:58:49 -07:00
|
|
|
eina_tiler_clear(ec->comp_data->pending.input);
|
2014-06-10 13:43:18 -07:00
|
|
|
|
|
|
|
/* #ifndef HAVE_WAYLAND_ONLY */
|
|
|
|
/* e_comp_object_input_area_set(ec->frame, rect->x, rect->y, */
|
|
|
|
/* rect->w, rect->h); */
|
|
|
|
/* #endif */
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
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);
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
|
2014-07-16 07:54:57 -07:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->client.w = ec->comp_data->pending.w;
|
|
|
|
ec->client.h = ec->comp_data->pending.h;
|
2014-07-16 07:54:57 -07:00
|
|
|
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);
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
|
2014-07-16 07:54:57 -07:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
|
2014-07-16 07:54:57 -07:00
|
|
|
{
|
|
|
|
if (subc != ec)
|
|
|
|
_e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2014-06-10 13:43:18 -07:00
|
|
|
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});
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
eina_tiler_union(tiler, src);
|
|
|
|
eina_tiler_free(src);
|
|
|
|
}
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-06-10 13:43:18 -07:00
|
|
|
_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)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-06-10 13:43:18 -07:00
|
|
|
Eina_Tiler *tiler;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
if ((tiler = wl_resource_get_user_data(resource)))
|
|
|
|
{
|
|
|
|
Eina_Tiler *src;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
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);
|
|
|
|
}
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2014-06-10 13:43:18 -07:00
|
|
|
Eina_Tiler *tiler;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
if ((tiler = wl_resource_get_user_data(resource)))
|
|
|
|
eina_tiler_free(tiler);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_comp_cb_region_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
|
|
|
|
{
|
2014-06-10 13:43:18 -07:00
|
|
|
E_Comp *c;
|
|
|
|
Eina_Tiler *tiler;
|
2014-05-09 02:51:08 -07:00
|
|
|
struct wl_resource *res;
|
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
if (!(c = e_comp_get(NULL)))
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
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});
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
if (!(res = wl_resource_create(client, &wl_region_interface, 1, id)))
|
|
|
|
{
|
2014-06-10 13:43:18 -07:00
|
|
|
eina_tiler_free(tiler);
|
2014-05-09 02:51:08 -07:00
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
wl_resource_set_implementation(res, &_e_region_interface, tiler,
|
2014-05-09 02:51:08 -07:00
|
|
|
_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);
|
2014-07-16 07:54:57 -07:00
|
|
|
|
|
|
|
E_FREE_LIST(subcomp_handlers, ecore_event_handler_del);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
2014-07-29 13:26:48 -07:00
|
|
|
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;
|
|
|
|
|
2014-08-25 07:22:31 -07:00
|
|
|
// E_COMP_WL_PIXMAP_CHECK continue;
|
|
|
|
|
2014-08-05 07:16:16 -07:00
|
|
|
if (ec->post_resize)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
2014-07-29 13:26:48 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-07-16 07:54:57 -07:00
|
|
|
E_Client *ec;
|
|
|
|
E_Client *subc;
|
|
|
|
Eina_List *l;
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
|
|
|
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
|
2014-07-16 07:54:57 -07:00
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
x = ec->x + subc->comp_data->sub.cdata->position.x;
|
|
|
|
y = ec->y + subc->comp_data->sub.cdata->position.y;
|
2014-07-16 07:54:57 -07:00
|
|
|
evas_object_move(subc->frame, x, y);
|
|
|
|
}
|
2014-07-29 13:26:48 -07:00
|
|
|
|
|
|
|
ec->post_move = EINA_FALSE;
|
|
|
|
_e_comp_wl_client_idler_add(ec);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_e_comp_wl_cb_client_iconify(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-07-16 07:54:57 -07:00
|
|
|
E_Event_Client *ev;
|
|
|
|
E_Client *ec, *subc;
|
|
|
|
Eina_List *l;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
ev = event;
|
|
|
|
if (!(ec = ev->ec)) return ECORE_CALLBACK_PASS_ON;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK ECORE_CALLBACK_PASS_ON;
|
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
if (_e_comp_wl_client_subsurf_data_get(ec))
|
|
|
|
{
|
|
|
|
ec = _e_comp_wl_subsurface_root_get(ec);
|
|
|
|
if (!ec->iconic) e_client_iconify(ec);
|
|
|
|
}
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
|
2014-07-16 07:54:57 -07:00
|
|
|
{
|
|
|
|
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)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-07-16 07:54:57 -07:00
|
|
|
E_Event_Client *ev;
|
|
|
|
E_Client *ec, *subc;
|
|
|
|
Eina_List *l;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
ev = event;
|
|
|
|
if (!(ec = ev->ec)) return ECORE_CALLBACK_PASS_ON;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK ECORE_CALLBACK_PASS_ON;
|
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
if (_e_comp_wl_client_subsurf_data_get(ec))
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-07-16 07:54:57 -07:00
|
|
|
ec = _e_comp_wl_subsurface_root_get(ec);
|
|
|
|
if (ec->iconic) e_client_uniconify(ec);
|
|
|
|
}
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
|
2014-07-16 07:54:57 -07:00
|
|
|
{
|
|
|
|
if (!subc->iconic) continue;
|
|
|
|
e_client_uniconify(subc);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
static const struct wl_compositor_interface _e_comp_interface =
|
|
|
|
{
|
|
|
|
_e_comp_wl_comp_cb_surface_create,
|
|
|
|
_e_comp_wl_comp_cb_region_create
|
|
|
|
};
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
static void
|
2014-07-16 07:54:57 -07:00
|
|
|
_e_comp_wl_cb_bind_compositor(struct wl_client *client, void *data, uint32_t version, uint32_t id)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
E_Comp *comp;
|
|
|
|
struct wl_resource *res;
|
|
|
|
|
|
|
|
if (!(comp = data)) return;
|
|
|
|
|
|
|
|
res =
|
2014-07-16 07:54:57 -07:00
|
|
|
wl_resource_create(client, &wl_compositor_interface, MIN(version, 3), id);
|
2014-05-09 02:51:08 -07:00
|
|
|
if (!res)
|
|
|
|
{
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
wl_resource_set_implementation(res, &_e_comp_interface, comp, NULL);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_cb_del(E_Comp *comp)
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
E_Comp_Data *cdata;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-05-15 02:46:16 -07:00
|
|
|
cdata = comp->wl_comp_data;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
E_Comp_Data *cdata;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2014-06-24 09:55:01 -07:00
|
|
|
/* dispatch any pending main loop events */
|
|
|
|
wl_event_loop_dispatch(cdata->wl.loop, 0);
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_e_comp_wl_cb_idle(void *data)
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
E_Comp_Data *cdata;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
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;
|
2014-08-04 09:58:49 -07:00
|
|
|
E_Comp_Data *cdata;
|
2014-07-15 06:54:55 -07:00
|
|
|
Eina_Bool have_shell = EINA_FALSE;
|
|
|
|
Eina_Bool have_xwayland = EINA_FALSE;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
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")))
|
2014-07-15 06:54:55 -07:00
|
|
|
{
|
|
|
|
if ((mod = e_module_new("wl_desktop_shell")))
|
|
|
|
{
|
|
|
|
e_module_enable(mod);
|
|
|
|
have_shell = EINA_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
have_shell = EINA_TRUE;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-07-15 06:54:55 -07:00
|
|
|
/* load xwayland module */
|
|
|
|
if (!(mod = e_module_find("xwayland")))
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-07-15 06:54:55 -07:00
|
|
|
if ((mod = e_module_new("xwayland")))
|
|
|
|
{
|
|
|
|
e_module_enable(mod);
|
|
|
|
have_xwayland = EINA_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
have_xwayland = EINA_TRUE;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-07-15 06:54:55 -07:00
|
|
|
if ((have_shell) && (have_xwayland))
|
|
|
|
{
|
2014-05-09 02:51:08 -07:00
|
|
|
/* 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;
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->first_draw_tmr = NULL;
|
2014-05-09 02:51:08 -07:00
|
|
|
e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2014-07-16 07:54:57 -07:00
|
|
|
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;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-08-04 09:58:49 -07:00
|
|
|
if ((!ec->comp_data->sub.list) &&
|
2014-07-16 07:54:57 -07:00
|
|
|
(!_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);
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
parent->comp_data->sub.restack_target = ec;
|
2014-07-16 07:54:57 -07:00
|
|
|
_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;
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
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;
|
2014-07-16 07:54:57 -07:00
|
|
|
_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;
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
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;
|
2014-07-16 07:54:57 -07:00
|
|
|
_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;
|
2014-08-03 06:40:15 -07:00
|
|
|
ec->lock_border = EINA_TRUE;
|
2014-07-16 07:54:57 -07:00
|
|
|
ec->lock_focus_in = ec->lock_focus_out = EINA_TRUE;
|
|
|
|
ec->netwm.state.skip_taskbar = EINA_TRUE;
|
|
|
|
ec->netwm.state.skip_pager = EINA_TRUE;
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->surface = surface_resource;
|
|
|
|
ec->comp_data->sub.cdata = sub_cdata;
|
2014-07-16 07:54:57 -07:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
E_Comp_Client_Data *cdata;
|
2014-07-16 07:54:57 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
cdata = pc->comp_data;
|
2014-07-16 07:54:57 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (!ec->comp_data)
|
2014-07-16 07:54:57 -07:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_e_comp_wl_compositor_create(void)
|
|
|
|
{
|
|
|
|
E_Comp *comp;
|
2014-08-04 09:58:49 -07:00
|
|
|
E_Comp_Data *cdata;
|
2014-05-09 02:51:08 -07:00
|
|
|
char buff[PATH_MAX];
|
2014-05-15 02:46:16 -07:00
|
|
|
/* char *rules, *model, *layout; */
|
2014-05-09 02:51:08 -07:00
|
|
|
int fd = 0;
|
|
|
|
|
|
|
|
/* get the current compositor */
|
2014-05-15 02:46:16 -07:00
|
|
|
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);
|
|
|
|
}
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
/* check compositor type and make sure it's Wayland */
|
|
|
|
/* if (comp->comp_type != E_PIXMAP_TYPE_WL) return EINA_FALSE; */
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
cdata = E_NEW(E_Comp_Data, 1);
|
2014-05-15 02:46:16 -07:00
|
|
|
comp->wl_comp_data = cdata;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
/* setup wayland display environment variable */
|
|
|
|
snprintf(buff, sizeof(buff), "%s/wayland-0", e_ipc_socket);
|
|
|
|
e_env_set("WAYLAND_DISPLAY", buff);
|
|
|
|
|
|
|
|
/* try to create wayland display */
|
|
|
|
if (!(cdata->wl.disp = wl_display_create()))
|
|
|
|
{
|
|
|
|
ERR("Could not create a Wayland Display: %m");
|
|
|
|
goto disp_err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (wl_display_add_socket(cdata->wl.disp, buff))
|
|
|
|
{
|
|
|
|
ERR("Could not create a Wayland Display: %m");
|
|
|
|
goto disp_err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* setup wayland compositor signals */
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2014-05-15 02:46:16 -07:00
|
|
|
/* #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); */
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
/* 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);
|
|
|
|
|
2014-08-04 11:54:09 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
|
|
|
|
disp_err:
|
|
|
|
e_env_unset("WAYLAND_DISPLAY");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2014-06-13 11:52:00 -07:00
|
|
|
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;
|
2014-06-19 06:31:07 -07:00
|
|
|
_e_comp_wl_client_priority_adjust(ec->netwm.pid, e_config->priority, 1,
|
2014-06-13 11:52:00 -07:00
|
|
|
EINA_FALSE, EINA_TRUE, EINA_FALSE);
|
|
|
|
}
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
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;
|
|
|
|
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
if (!ec->override)
|
|
|
|
e_hints_window_visible_set(ec);
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->frame_update)
|
|
|
|
ec->comp_data->frame_update = EINA_FALSE;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
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;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2014-05-15 02:46:16 -07:00
|
|
|
serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp);
|
|
|
|
EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
2014-08-04 09:58:49 -07:00
|
|
|
wl_pointer_send_enter(res, serial, ec->comp_data->surface,
|
2014-05-09 02:51:08 -07:00
|
|
|
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;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
if (ec->cur_mouse_action) return;
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2014-05-15 02:46:16 -07:00
|
|
|
serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp);
|
|
|
|
EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
2014-08-04 09:58:49 -07:00
|
|
|
wl_pointer_send_leave(res, serial, ec->comp_data->surface);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-05-15 02:46:16 -07:00
|
|
|
ec->comp->wl_comp_data->ptr.button = btn;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2014-05-15 02:46:16 -07:00
|
|
|
serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp);
|
|
|
|
EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
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;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-05-15 02:46:16 -07:00
|
|
|
ec->comp->wl_comp_data->resize.resource = NULL;
|
|
|
|
ec->comp->wl_comp_data->ptr.button = btn;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2014-05-15 02:46:16 -07:00
|
|
|
serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp);
|
|
|
|
EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-23 12:29:36 -07:00
|
|
|
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;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-06-23 12:29:36 -07:00
|
|
|
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);
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2014-06-23 12:29:36 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
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;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
if (ec->cur_mouse_action) return;
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
if (e_client_util_ignored_get(ec)) return;
|
|
|
|
|
2014-05-15 02:46:16 -07:00
|
|
|
ec->comp->wl_comp_data->ptr.x =
|
2014-05-09 02:51:08 -07:00
|
|
|
wl_fixed_from_int(ev->cur.canvas.x - ec->client.x);
|
2014-05-15 02:46:16 -07:00
|
|
|
ec->comp->wl_comp_data->ptr.y =
|
2014-05-09 02:51:08 -07:00
|
|
|
wl_fixed_from_int(ev->cur.canvas.y - ec->client.y);
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2014-05-15 02:46:16 -07:00
|
|
|
EINA_LIST_FOREACH(ec->comp->wl_comp_data->ptr.resources, l, res)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
|
|
|
wl_pointer_send_motion(res, ev->timestamp,
|
2014-05-15 02:46:16 -07:00
|
|
|
ec->comp->wl_comp_data->ptr.x,
|
|
|
|
ec->comp->wl_comp_data->ptr.y);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2014-08-04 09:58:49 -07:00
|
|
|
E_Comp_Data *cdata;
|
2014-05-09 02:51:08 -07:00
|
|
|
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;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
|
|
|
if (!ec->focused) return;
|
|
|
|
|
|
|
|
keycode = (ev->keycode - 8);
|
2014-06-23 09:56:05 -07:00
|
|
|
if (!(cdata = ec->comp->wl_comp_data)) return;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-26 06:19:23 -07:00
|
|
|
end = (uint32_t *)cdata->kbd.keys.data + (cdata->kbd.keys.size / sizeof(*k));
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
for (k = cdata->kbd.keys.data; k < end; k++)
|
2014-06-10 13:43:18 -07:00
|
|
|
{
|
|
|
|
/* ignore server-generated key repeats */
|
|
|
|
if (*k == keycode) return;
|
|
|
|
}
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-26 06:19:23 -07:00
|
|
|
cdata->kbd.keys.size = (const char *)end - (const char *)cdata->kbd.keys.data;
|
2014-05-09 02:51:08 -07:00
|
|
|
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);
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2014-05-15 02:46:16 -07:00
|
|
|
serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp);
|
|
|
|
EINA_LIST_FOREACH(ec->comp->wl_comp_data->kbd.resources, l, res)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
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;
|
2014-08-04 09:58:49 -07:00
|
|
|
E_Comp_Data *cdata;
|
2014-05-09 02:51:08 -07:00
|
|
|
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;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
|
|
|
if (!ec->focused) return;
|
|
|
|
|
|
|
|
keycode = (ev->keycode - 8);
|
2014-06-23 09:56:05 -07:00
|
|
|
if (!(cdata = ec->comp->wl_comp_data)) return;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-26 06:19:23 -07:00
|
|
|
end = (uint32_t *)cdata->kbd.keys.data + (cdata->kbd.keys.size / sizeof(*k));
|
2014-05-09 02:51:08 -07:00
|
|
|
for (k = cdata->kbd.keys.data; k < end; k++)
|
|
|
|
if (*k == keycode) *k = *--end;
|
|
|
|
|
2014-06-26 06:19:23 -07:00
|
|
|
cdata->kbd.keys.size = (const char *)end - (const char *)cdata->kbd.keys.data;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2014-05-09 02:51:08 -07:00
|
|
|
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;
|
2014-08-04 09:58:49 -07:00
|
|
|
E_Comp_Data *cdata;
|
2014-05-09 02:51:08 -07:00
|
|
|
struct wl_resource *res;
|
|
|
|
struct wl_client *wc;
|
|
|
|
Eina_List *l;
|
|
|
|
uint32_t serial, *k;
|
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
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;
|
|
|
|
|
2014-05-15 02:46:16 -07:00
|
|
|
cdata = ec->comp->wl_comp_data;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-13 11:52:00 -07:00
|
|
|
/* priority raise */
|
|
|
|
_e_comp_wl_client_priority_raise(ec);
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
/* update modifier state */
|
|
|
|
wl_array_for_each(k, &cdata->kbd.keys)
|
|
|
|
e_comp_wl_input_keyboard_state_update(cdata, *k, EINA_TRUE);
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2014-05-09 02:51:08 -07:00
|
|
|
serial = wl_display_next_serial(cdata->wl.disp);
|
|
|
|
EINA_LIST_FOREACH(cdata->kbd.resources, l, res)
|
|
|
|
{
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
2014-08-04 09:58:49 -07:00
|
|
|
wl_keyboard_send_enter(res, serial, ec->comp_data->surface,
|
2014-05-09 02:51:08 -07:00
|
|
|
&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;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
2014-06-13 11:52:00 -07:00
|
|
|
/* priority normal */
|
|
|
|
_e_comp_wl_client_priority_normal(ec);
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
/* update modifier state */
|
2014-05-15 02:46:16 -07:00
|
|
|
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);
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2014-05-15 02:46:16 -07:00
|
|
|
serial = wl_display_next_serial(ec->comp->wl_comp_data->wl.disp);
|
|
|
|
EINA_LIST_FOREACH(ec->comp->wl_comp_data->kbd.resources, l, res)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
2014-08-04 09:58:49 -07:00
|
|
|
wl_keyboard_send_leave(res, serial, ec->comp_data->surface);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
if ((ec->shading) || (ec->shaded)) return;
|
|
|
|
if (!e_pixmap_size_changed(ec->pixmap, ec->client.w, ec->client.h))
|
|
|
|
return;
|
|
|
|
|
2014-05-12 06:05:29 -07:00
|
|
|
/* DBG("COMP_WL: Evas Resize: %d %d", ec->client.w, ec->client.h); */
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
ec->post_resize = EINA_TRUE;
|
2014-07-29 13:26:48 -07:00
|
|
|
e_pixmap_dirty(ec->pixmap);
|
|
|
|
e_comp_object_render_update_del(ec->frame);
|
2014-05-09 02:51:08 -07:00
|
|
|
_e_comp_wl_client_idler_add(ec);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-09-05 02:54:45 -07:00
|
|
|
_e_comp_wl_evas_cb_frame_recalc(void *data, Evas_Object *obj, void *event EINA_UNUSED)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
2014-07-29 05:49:07 -07:00
|
|
|
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
if (evas_object_visible_get(obj))
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->frame_update = EINA_FALSE;
|
2014-05-09 02:51:08 -07:00
|
|
|
else
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->frame_update = EINA_TRUE;
|
2014-05-09 02:51:08 -07:00
|
|
|
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;
|
2014-06-17 11:12:31 -07:00
|
|
|
E_Comp *comp;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
if (ec->netwm.ping) e_client_ping(ec);
|
|
|
|
|
2014-05-12 06:05:29 -07:00
|
|
|
/* 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
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2014-06-17 11:12:31 -07:00
|
|
|
comp = ec->comp;
|
2014-05-12 06:05:29 -07:00
|
|
|
|
2014-06-17 11:12:31 -07:00
|
|
|
e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap));
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data)
|
2014-06-17 11:12:31 -07:00
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->reparented)
|
2014-06-17 11:12:31 -07:00
|
|
|
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));
|
2014-05-12 06:05:29 -07:00
|
|
|
|
2014-06-17 11:12:31 -07:00
|
|
|
_e_comp_wl_focus_check(comp);
|
2014-05-12 06:05:29 -07:00
|
|
|
|
2014-06-17 11:12:31 -07:00
|
|
|
/* TODO: Delete request send ??
|
|
|
|
* NB: No such animal wrt wayland */
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_kill_request(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
2014-06-17 11:12:31 -07:00
|
|
|
E_Comp *comp;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-06-17 11:12:31 -07:00
|
|
|
/* if (ec->netwm.ping) e_client_ping(ec); */
|
|
|
|
|
|
|
|
comp = ec->comp;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap));
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->reparented)
|
2014-05-09 02:51:08 -07:00
|
|
|
e_client_comp_hidden_set(ec, EINA_TRUE);
|
|
|
|
}
|
2014-06-17 11:12:31 -07:00
|
|
|
|
|
|
|
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);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->shell.ping)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->shell.surface)
|
|
|
|
ec->comp_data->shell.ping(ec->comp_data->shell.surface);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
evas_object_color_get(obj, NULL, NULL, NULL, &a);
|
|
|
|
if (ec->netwm.opacity == a) return;
|
2014-05-15 02:46:16 -07:00
|
|
|
ec->netwm.opacity = a;
|
2014-05-09 02:51:08 -07:00
|
|
|
ec->netwm.opacity_changed = EINA_TRUE;
|
|
|
|
_e_comp_wl_client_idler_add(ec);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_client_evas_init(E_Client *ec)
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->evas_init) return;
|
|
|
|
ec->comp_data->evas_init = EINA_TRUE;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
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);
|
2014-06-23 12:29:36 -07:00
|
|
|
evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_WHEEL,
|
|
|
|
_e_comp_wl_evas_cb_mouse_wheel, ec);
|
2014-05-09 02:51:08 -07:00
|
|
|
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)
|
|
|
|
{
|
2014-06-23 06:42:50 -07:00
|
|
|
/* FIXME: No Way to get "initial attributes" of a wayland window */
|
2014-05-15 02:46:16 -07:00
|
|
|
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)))
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-05-15 02:46:16 -07:00
|
|
|
e_comp_ignore_win_add(E_PIXMAP_TYPE_WL, e_client_util_win_get(ec));
|
|
|
|
e_object_del(E_OBJECT(ec));
|
|
|
|
return EINA_FALSE;
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
2014-06-17 09:50:48 -07:00
|
|
|
if ((!e_client_util_ignored_get(ec)) &&
|
|
|
|
(!ec->internal) && (!ec->internal_ecore_evas))
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->need_reparent = EINA_TRUE;
|
2014-06-17 09:50:48 -07:00
|
|
|
EC_CHANGED(ec);
|
|
|
|
ec->take_focus = !starting;
|
|
|
|
}
|
2014-07-29 10:30:15 -07:00
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
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)
|
|
|
|
{
|
2014-06-10 13:49:18 -07:00
|
|
|
/* FIXME: need way to determine if shape has changed */
|
2014-05-09 02:51:08 -07:00
|
|
|
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;
|
|
|
|
|
2014-05-15 02:46:16 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK ECORE_CALLBACK_RENEW;
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
_e_comp_wl_client_evas_init(ec);
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
2014-05-12 06:05:29 -07:00
|
|
|
/* 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; */
|
|
|
|
/* } */
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_e_comp_wl_cb_client_prop(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
|
|
|
{
|
2014-05-15 02:46:16 -07:00
|
|
|
E_Client *ec;
|
2014-05-09 02:51:08 -07:00
|
|
|
E_Event_Client_Property *ev;
|
|
|
|
|
|
|
|
ev = event;
|
2014-07-29 13:26:48 -07:00
|
|
|
/* if (!(ev->property & E_CLIENT_PROPERTY_ICON)) return ECORE_CALLBACK_RENEW; */
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-05-15 02:46:16 -07:00
|
|
|
ec = ev->ec;
|
|
|
|
E_COMP_WL_PIXMAP_CHECK ECORE_CALLBACK_RENEW;
|
|
|
|
|
|
|
|
if (ec->desktop)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-05-15 02:46:16 -07:00
|
|
|
if (!ec->exe_inst) e_exec_phony(ec);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if ((!ec->already_unparented) && (ec->comp_data->reparented))
|
2014-06-17 11:36:48 -07:00
|
|
|
_e_comp_wl_focus_down_set(ec);
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
ec->already_unparented = EINA_TRUE;
|
2014-05-12 06:05:29 -07:00
|
|
|
win = e_pixmap_window_get(ec->pixmap);
|
2014-05-09 02:51:08 -07:00
|
|
|
eina_hash_del_by_key(clients_win_hash, &win);
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
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);
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->reparented)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->sub.list)
|
2014-07-16 07:54:57 -07:00
|
|
|
{
|
|
|
|
E_Client *subc;
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
EINA_LIST_FREE(ec->comp_data->sub.list, subc)
|
2014-07-16 07:54:57 -07:00
|
|
|
_e_comp_wl_subsurface_destroy_internal(subc);
|
|
|
|
}
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
E_FREE_FUNC(ec->comp_data->first_draw_tmr, ecore_timer_del);
|
2014-05-12 06:05:29 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
E_FREE(ec->comp_data);
|
|
|
|
ec->comp_data = NULL;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-17 11:36:48 -07:00
|
|
|
_e_comp_wl_focus_check(ec->comp);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_cb_hook_client_new(void *data EINA_UNUSED, E_Client *ec)
|
|
|
|
{
|
|
|
|
uint64_t win;
|
|
|
|
|
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
|
|
|
|
2014-05-12 06:05:29 -07:00
|
|
|
win = e_pixmap_window_get(ec->pixmap);
|
2014-05-09 02:51:08 -07:00
|
|
|
ec->ignored = e_comp_ignore_win_find(win);
|
|
|
|
|
2014-06-19 06:31:07 -07:00
|
|
|
/* NB: could not find a better place to do this, BUT for internal windows,
|
2014-05-12 06:05:29 -07:00
|
|
|
* 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;
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data = E_NEW(E_Comp_Client_Data, 1);
|
2014-06-10 13:43:18 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->pending.damage = eina_tiler_new(ec->w, ec->h);
|
|
|
|
eina_tiler_tile_size_set(ec->comp_data->pending.damage, 1, 1);
|
2014-06-10 13:43:18 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->pending.input = eina_tiler_new(ec->w, ec->h);
|
|
|
|
eina_tiler_tile_size_set(ec->comp_data->pending.input, 1, 1);
|
2014-06-10 13:43:18 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->pending.opaque = eina_tiler_new(ec->w, ec->h);
|
|
|
|
eina_tiler_tile_size_set(ec->comp_data->pending.opaque, 1, 1);
|
2014-06-10 13:43:18 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->pending.buffer_destroy.notify =
|
2014-06-10 13:43:18 -07:00
|
|
|
_e_comp_wl_buffer_pending_cb_destroy;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->mapped = EINA_FALSE;
|
2014-05-12 06:05:29 -07:00
|
|
|
ec->changes.shape = EINA_TRUE;
|
|
|
|
ec->changes.shape_input = EINA_TRUE;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
if (!_e_comp_wl_client_new_helper(ec)) return;
|
2014-07-29 13:26:48 -07:00
|
|
|
|
|
|
|
ec->comp_data->first_damage = ec->internal;
|
|
|
|
/* ec->comp_data->first_damage = ((ec->internal) || (ec->override)); */
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
eina_hash_add(clients_win_hash, &win, ec);
|
|
|
|
e_hints_client_list_set();
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->first_draw_tmr =
|
2014-05-09 02:51:08 -07:00
|
|
|
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)
|
|
|
|
{
|
2014-06-13 05:27:33 -07:00
|
|
|
E_Event_Client_Property *ev;
|
2014-06-23 13:47:53 -07:00
|
|
|
Eina_Bool move = EINA_FALSE;
|
|
|
|
Eina_Bool resize = EINA_FALSE;
|
|
|
|
int x, y, w, h;
|
2014-06-13 05:27:33 -07:00
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
|
|
|
|
2014-07-29 10:30:15 -07:00
|
|
|
if ((ec->changes.prop) && (ec->netwm.fetch.state))
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
e_hints_window_state_get(ec);
|
|
|
|
ec->netwm.fetch.state = EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2014-07-29 10:30:15 -07:00
|
|
|
if ((ec->changes.prop) && (ec->e.fetch.state))
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
e_hints_window_e_state_get(ec);
|
|
|
|
ec->e.fetch.state = EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2014-07-29 10:30:15 -07:00
|
|
|
if ((ec->changes.prop) && (ec->netwm.fetch.type))
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
e_hints_window_type_get(ec);
|
|
|
|
if (((!ec->lock_border) || (!ec->border.name)) &&
|
2014-08-04 09:58:49 -07:00
|
|
|
(ec->comp_data->reparented))
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
2014-06-19 11:56:58 -07:00
|
|
|
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");
|
|
|
|
}
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
if (ec->tooltip)
|
|
|
|
{
|
2014-06-19 11:56:58 -07:00
|
|
|
ec->focus_policy_override = E_FOCUS_CLICK;
|
2014-05-09 02:51:08 -07:00
|
|
|
ec->icccm.accepts_focus = EINA_FALSE;
|
|
|
|
eina_stringshare_replace(&ec->bordername, "borderless");
|
|
|
|
}
|
|
|
|
else if (ec->internal)
|
|
|
|
{
|
2014-06-18 11:49:55 -07:00
|
|
|
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);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
2014-06-13 05:27:33 -07:00
|
|
|
ev = E_NEW(E_Event_Client_Property, 1);
|
|
|
|
|
2014-06-13 05:18:22 -07:00
|
|
|
ev->ec = ec;
|
|
|
|
e_object_ref(E_OBJECT(ec));
|
|
|
|
ev->property = E_CLIENT_PROPERTY_NETWM_STATE;
|
2014-06-13 05:27:33 -07:00
|
|
|
ecore_event_add(E_EVENT_CLIENT_PROPERTY, ev,
|
|
|
|
_e_comp_wl_client_event_free, NULL);
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
ec->netwm.fetch.type = EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO: vkbd, etc */
|
|
|
|
|
2014-06-10 13:43:18 -07:00
|
|
|
/* FIXME: Update ->changes.shape code for recent switch to eina_tiler */
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-07-29 10:30:15 -07:00
|
|
|
if ((ec->changes.prop) && (ec->netwm.update.state))
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
e_hints_window_state_set(ec);
|
|
|
|
if (((!ec->lock_border) || (!ec->border.name)) &&
|
|
|
|
(!(((ec->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))) &&
|
2014-08-04 09:58:49 -07:00
|
|
|
(ec->comp_data->reparented))
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-06-23 13:47:53 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-06-18 11:49:55 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
ec->changes.prop = EINA_FALSE;
|
|
|
|
if (ec->changes.icon)
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->reparented) return;
|
|
|
|
ec->comp_data->change_icon = EINA_TRUE;
|
2014-05-09 02:51:08 -07:00
|
|
|
ec->changes.icon = EINA_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_cb_hook_client_pre_frame(void *data EINA_UNUSED, E_Client *ec)
|
|
|
|
{
|
2014-05-15 02:46:16 -07:00
|
|
|
uint64_t parent;
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-15 02:46:16 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (!ec->comp_data->need_reparent) return;
|
2014-05-15 02:46:16 -07:00
|
|
|
|
2014-06-23 13:47:53 -07:00
|
|
|
/* WRN("Client Needs New Parent in Pre Frame"); */
|
2014-05-15 02:46:16 -07:00
|
|
|
|
|
|
|
parent = e_client_util_pwin_get(ec);
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
ec->border_size = 0;
|
2014-05-15 02:46:16 -07:00
|
|
|
e_pixmap_parent_window_set(ec->pixmap, parent);
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
/* if (ec->shaped_input) */
|
|
|
|
/* { */
|
|
|
|
/* DBG("\tClient Shaped Input"); */
|
|
|
|
/* } */
|
|
|
|
|
2014-07-29 13:26:48 -07:00
|
|
|
eina_hash_add(clients_win_hash, &parent, ec);
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
if (ec->visible)
|
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->set_win_type)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-06-18 11:49:55 -07:00
|
|
|
if (ec->internal_ecore_evas)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-08-03 06:40:15 -07:00
|
|
|
int type = ECORE_WL_WINDOW_TYPE_TOPLEVEL;
|
|
|
|
|
2014-06-18 11:49:55 -07:00
|
|
|
switch (ec->netwm.type)
|
|
|
|
{
|
|
|
|
case E_WINDOW_TYPE_DIALOG:
|
2014-06-23 06:42:50 -07:00
|
|
|
/* 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;
|
2014-06-18 11:49:55 -07:00
|
|
|
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;
|
|
|
|
}
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-06-18 11:49:55 -07:00
|
|
|
ecore_evas_wayland_type_set(ec->internal_ecore_evas, type);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->set_win_type = EINA_FALSE;
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-15 02:46:16 -07:00
|
|
|
/* TODO */
|
|
|
|
/* focus_setup */
|
|
|
|
e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, parent);
|
|
|
|
e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, parent);
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
_e_comp_wl_client_evas_init(ec);
|
|
|
|
|
|
|
|
if ((ec->netwm.ping) && (!ec->ping_poller))
|
|
|
|
e_client_ping(ec);
|
|
|
|
|
2014-05-15 02:46:16 -07:00
|
|
|
if (ec->visible) evas_object_show(ec->frame);
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->need_reparent = EINA_FALSE;
|
2014-05-09 02:51:08 -07:00
|
|
|
ec->redirected = EINA_TRUE;
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->change_icon)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
ec->changes.icon = EINA_TRUE;
|
|
|
|
EC_CHANGED(ec);
|
|
|
|
}
|
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp_data->change_icon = EINA_FALSE;
|
|
|
|
ec->comp_data->reparented = EINA_TRUE;
|
2014-05-15 02:46:16 -07:00
|
|
|
|
|
|
|
/* _e_comp_wl_evas_cb_comp_hidden(ec, NULL, NULL); */
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2014-06-18 11:49:55 -07:00
|
|
|
if (ec->changes.internal_state)
|
|
|
|
{
|
|
|
|
E_Win *win;
|
|
|
|
|
|
|
|
if ((win = ecore_evas_data_get(ec->internal_ecore_evas, "E_Win")))
|
|
|
|
{
|
|
|
|
if (win->state.centered)
|
2014-07-29 13:26:48 -07:00
|
|
|
e_comp_object_util_center(ec->frame);
|
2014-06-18 11:49:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-09 02:51:08 -07:00
|
|
|
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;
|
|
|
|
|
2014-05-15 02:46:16 -07:00
|
|
|
if ((ec->comp->wl_comp_data->restack) && (!ec->comp->new_clients))
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
|
|
|
e_hints_client_stacking_set();
|
2014-05-15 02:46:16 -07:00
|
|
|
ec->comp->wl_comp_data->restack = EINA_FALSE;
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_cb_hook_client_focus_set(void *data EINA_UNUSED, E_Client *ec)
|
|
|
|
{
|
2014-08-25 07:22:31 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->shell.activate)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->shell.surface)
|
|
|
|
ec->comp_data->shell.activate(ec->comp_data->shell.surface);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
2014-06-17 11:12:31 -07:00
|
|
|
|
|
|
|
/* 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);
|
2014-07-09 08:06:25 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp->wl_comp_data->kbd.focus != ec->comp_data->surface)
|
2014-07-09 08:06:25 -07:00
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
ec->comp->wl_comp_data->kbd.focus = ec->comp_data->surface;
|
2014-07-09 08:06:25 -07:00
|
|
|
e_comp_wl_data_device_keyboard_focus_set(ec->comp->wl_comp_data);
|
|
|
|
}
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_cb_hook_client_focus_unset(void *data EINA_UNUSED, E_Client *ec)
|
|
|
|
{
|
2014-05-15 02:46:16 -07:00
|
|
|
E_COMP_WL_PIXMAP_CHECK;
|
2014-05-09 02:51:08 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->shell.deactivate)
|
2014-05-09 02:51:08 -07:00
|
|
|
{
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp_data->shell.surface)
|
|
|
|
ec->comp_data->shell.deactivate(ec->comp_data->shell.surface);
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
2014-06-17 11:12:31 -07:00
|
|
|
|
|
|
|
_e_comp_wl_focus_check(ec->comp);
|
2014-07-09 08:06:25 -07:00
|
|
|
|
2014-08-04 09:58:49 -07:00
|
|
|
if (ec->comp->wl_comp_data->kbd.focus == ec->comp_data->surface)
|
2014-07-09 08:06:25 -07:00
|
|
|
ec->comp->wl_comp_data->kbd.focus = NULL;
|
2014-05-09 02:51:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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 */
|
2014-06-12 06:07:21 -07:00
|
|
|
clients_win_hash = eina_hash_int64_new(NULL);
|
2014-05-09 02:51:08 -07:00
|
|
|
|
|
|
|
/* 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, */
|
2014-05-12 06:05:29 -07:00
|
|
|
/* _e_comp_wl_cb_client_zone_set, NULL); */
|
2014-05-09 02:51:08 -07:00
|
|
|
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)
|
|
|
|
{
|
2014-07-29 05:49:07 -07:00
|
|
|
/* client was already deleted */
|
2014-05-09 02:51:08 -07:00
|
|
|
e_pixmap_free(cp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
e_object_del(E_OBJECT(ec));
|
|
|
|
}
|
2014-08-04 07:20:45 -07:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|