src/bin/server/e_tizen_launch_effect.c \
src/bin/server/e_tizen_launch_appinfo.c \
src/bin/server/e_tizen_display_policy.c \
+src/bin/server/e_surface_view.c \
src/bin/windowmgr/services/e_service_gesture.c \
src/bin/windowmgr/services/e_service_lockscreen.c \
src/bin/windowmgr/services/e_service_quickpanel.c \
#include "e_view_client_intern.h"
#include "e_comp_wl_input_thread_intern.h"
#include "e_seat_intern.h"
+#include "e_surface_view_intern.h"
#include <tizen-extension-server-protocol.h>
#include <relative-pointer-unstable-v1-server-protocol.h>
ds_log_init(DS_DBG, _e_comp_wl_ds_log_handler);
- if (!e_compositor_init(comp_wl->wl.disp))
+ if (!e_surface_view_module_init(comp_wl->wl.disp))
{
ERR("Failed to initialize compositor");
goto comp_err;
}
}
-EINTERN void
-e_comp_wl_client_surface_pending_commit(E_Client *ec)
-{
- if (e_object_is_del(E_OBJECT(ec))) return;
-
- e_comp_wl_surface_commit(ec);
-
- _e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_SURFACE_COMMIT, ec);
-}
-
EINTERN void
e_comp_wl_client_evas_init(E_Client *ec)
{
EINTERN void e_comp_wl_client_surface_pending_buffer_set(E_Client *ec, E_Comp_Wl_Buffer *buffer, int32_t sx, int32_t sy);
EINTERN void e_comp_wl_client_opaque_region_set(E_Client *ec, pixman_region32_t *region);
EINTERN void e_comp_wl_client_input_region_set(E_Client *ec, pixman_region32_t *region);
-EINTERN void e_comp_wl_client_surface_pending_commit(E_Client *ec);
EINTERN Eina_Bool e_comp_wl_client_subsurface_cyclic_reference_check(E_Client *ec, E_Client *parent);
EINTERN void e_comp_wl_client_subsurface_commit_to_cache(E_Client *ec);
struct ds_tizen_surface_exporter *surface_exporter;
Eina_Hash *exported_surfaces;
- E_Client_Hook *new_client_hook;
struct wl_listener new_surface;
struct wl_listener display_destroy;
struct wl_listener new_exported_surface;
+
+ struct
+ {
+ struct wl_signal destroy;
+ struct wl_signal new_surface;
+ } events;
};
typedef enum
static void _e_compositor_cb_display_destroy(struct wl_listener *listener, void *data);
static void _e_compositor_cb_new_surface(struct wl_listener *listener, void *data);
-static void _e_compositor_cb_new_client(void *data EINA_UNUSED, E_Client *ec);
static Eina_Bool _e_compositor_surface_exporter_init(E_Compositor *comp, struct wl_display *display);
static void _e_compositor_surface_exporter_finalize(E_Compositor *comp);
-static E_Surface *_e_surface_create(E_Client *ec);
+static E_Surface *_e_surface_create(struct ds_surface *ds_surface);
static E_Surface *_e_surface_from_ds_surface(struct ds_surface *ds_surface);
static void _e_surface_destroy(E_Surface *surface);
static void _e_surface_ds_surface_set(E_Surface *surface, struct ds_surface *ds_surface);
if (!comp)
return EINA_FALSE;
+ wl_signal_init(&comp->events.destroy);
+ wl_signal_init(&comp->events.new_surface);
+
comp->ds_compositor = ds_compositor_create(display);
if (!comp->ds_compositor)
{
ds_compositor_add_new_surface_listener(comp->ds_compositor,
&comp->new_surface);
- comp->new_client_hook = e_client_hook_add(E_CLIENT_HOOK_NEW_CLIENT,
- _e_compositor_cb_new_client,
- NULL);
-
comp->display_destroy.notify = _e_compositor_cb_display_destroy;
wl_display_add_destroy_listener(display, &comp->display_destroy);
return EINA_TRUE;
}
+EINTERN void
+e_compositor_destroy_listener_add(struct wl_listener *listener)
+{
+ EINA_SAFETY_ON_NULL_RETURN(e_compositor);
+
+ wl_signal_add(&e_compositor->events.destroy, listener);
+}
+
+EINTERN void
+e_compositor_new_surface_listener_add(struct wl_listener *listener)
+{
+ EINA_SAFETY_ON_NULL_RETURN(e_compositor);
+
+ wl_signal_add(&e_compositor->events.new_surface, listener);
+}
+
EINTERN uint32_t
e_compositor_surface_export(E_Surface *surface)
{
surface->pending.committed |= E_SURFACE_STATE_PRESENTATION_TIME_FEEDBACK;
}
+EINTERN void
+e_surface_ec_set(E_Surface *surface, E_Client *ec)
+{
+ assert(surface->ec == NULL);
+ assert(ec->comp_data == NULL);
+
+ ELOGF("SURFACE", "E_Surface(%p): Set E_Client", surface->ec, surface);
+
+ ec->comp_data = &surface->base;
+
+ surface->ec = ec;
+ surface->client_del_hook = e_client_hook_add(E_CLIENT_HOOK_DEL, _e_surface_cb_client_del, surface);
+}
+
EINTERN E_Subsurface *
e_subsurface_try_from_surface(E_Surface *surface)
{
static void
_e_compositor_cb_display_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
{
+ wl_signal_emit(&e_compositor->events.destroy, NULL);
+
_e_compositor_surface_exporter_finalize(e_compositor);
wl_list_remove(&e_compositor->display_destroy.link);
wl_list_remove(&e_compositor->new_surface.link);
- e_client_hook_del(e_compositor->new_client_hook);
E_FREE(e_compositor);
}
-static E_Client *
-_e_comp_wl_client_usable_get(pid_t pid, E_Pixmap *ep)
-{
- /* NOTE: this will return usable E_Client for a surface of specified process
- * by pid. it doesn't care whatever this surfaces is for but care only what
- * is owner process of the surface.
- */
-
- E_Client *ec;
-
- /* find launchscreen client list */
- ec = e_comp_launchscrn_ec_find_by_pid(pid);
- if (!ec)
- return NULL;
-
- EINA_SAFETY_ON_FALSE_RETURN_VAL(ec->comp_data == NULL, NULL);
-
- e_comp_launchscrn_ec_remove(ec);
-
- e_client_pixmap_replace(ec, ep);
-
- if (ec->internal)
- ec->internal = 0;
-
- /* to set-up comp data */
- _e_compositor_cb_new_client(NULL, ec);
- ec->ignored = 0;
- if (!ec->comp_data) return NULL;
- e_comp_wl_client_evas_init(ec);
-
- ELOGF("COMP", "Reusable ec. new_pixmap:%p", ec, ec->pixmap);
- e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_REUSE, ec);
-
- return ec;
-}
-
static void
_e_compositor_cb_new_surface(struct wl_listener *listener, void *data)
{
struct ds_surface *ds_surface = data;
- E_Client *ec = NULL;
- E_Pixmap *ep;
- struct wl_resource *surface_resource;
- pid_t pid;
+ E_Surface *surface;
TRACE_DS_BEGIN(COMP_WL:NEW SURFACE CB);
- surface_resource = ds_surface_get_wl_resource(ds_surface);
-
- /* try to create new pixmap */
- if (!(ep = e_pixmap_new(E_PIXMAP_TYPE_WL, surface_resource)))
+ surface = _e_surface_create(ds_surface);
+ if (!surface)
{
- ERR("Could not create new pixmap");
- TRACE_DS_END();
+ ERR("Failed to create E_Surface for ds_surface(%p)", ds_surface);
return;
}
+ wl_signal_emit(&e_compositor->events.new_surface, surface);
- wl_client_get_credentials(wl_resource_get_client(surface_resource), &pid, NULL, NULL);
- if (!(ec = _e_comp_wl_client_usable_get(pid, ep)))
- {
- ec = e_client_new(ep, 0, 0);
- if (!ec)
- goto end;
- }
-
- if (!ec->netwm.pid)
- ec->netwm.pid = pid;
- if (ec->new_client)
- {
- E_Comp *comp = e_comp_get();
- comp->new_clients--;
- }
- ec->new_client = 0;
- if ((!ec->client.w) && (ec->client.h))
- ec->client.w = ec->client.h = 1;
-
- e_comp_wl_client_surface_set(ec, surface_resource);
- ec->icccm.accepts_focus = 1;
- wl_list_init(&ec->comp_data->pointer_constraints);
-
- _e_surface_ds_surface_set(e_surface_from_ec(ec), ds_surface);
+ assert(surface->ec);
- DBG("\tUsing Client: %p", ec);
-end:
TRACE_DS_END();
}
eina_hash_add(compositor->exported_surfaces, &id, surface);
}
-static void
-_e_compositor_cb_new_client(void *data EINA_UNUSED, E_Client *ec)
-{
- E_Surface *surface;
-
- /* make sure this is a wayland client */
- if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
-
- TRACE_DS_BEGIN(COMP_WL:CLIENT NEW HOOK);
-
- surface = _e_surface_create(ec);
- if (!surface)
- {
- ERR("Could not create E_Surface");
- TRACE_DS_END();
- return;
- }
-
- ec->comp_data = &surface->base;
-
- /* set initial client properties */
- ec->argb = EINA_FALSE;
- ec->redirected = ec->ignored = 1;
- ec->border_size = 0;
-
- /* NB: could not find a better place to do this, BUT for internal windows,
- * we need to set delete_request else the close buttons on the frames do
- * basically nothing */
- if (ec->internal)
- ec->icccm.delete_request = EINA_TRUE;
-
- g_mutex_init(&ec->comp_data->surface_mutex);
-
- TRACE_DS_END();
-}
-
static Eina_Bool
_e_compositor_surface_exporter_init(E_Compositor *comp, struct wl_display *display)
{
}
static E_Surface *
-_e_surface_create(E_Client *ec)
+_e_surface_create(struct ds_surface *ds_surface)
{
E_Surface *surface;
if (!surface)
return NULL;
- e_object_ref(E_OBJECT(ec));
- surface->ec = ec;
+ _e_surface_ds_surface_set(surface, ds_surface);
wl_signal_init(&surface->events.destroy);
wl_signal_init(&surface->events.parent_destroy);
e_presentation_time_container_init(&surface->base.presentation_container);
- surface->client_del_hook = e_client_hook_add(E_CLIENT_HOOK_DEL,
- _e_surface_cb_client_del,
- surface);
+ wl_list_init(&surface->base.pointer_constraints);
- ELOGF("COMPOSITOR", "Create E_Surface %p", ec, surface);
+ g_mutex_init(&surface->base.surface_mutex);
+
+ ELOGF("COMPOSITOR", "Create E_Surface %p", NULL, surface);
return surface;
}
g_mutex_clear(&surface->base.surface_mutex);
- surface->ec->comp_data = NULL;
- e_object_unref(E_OBJECT(surface->ec));
free(surface);
}
static void
_e_surface_commit(E_Surface *surface)
{
- e_comp_wl_client_surface_pending_commit(surface->ec);
+ e_comp_wl_surface_commit(surface->ec);
+ e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_SURFACE_COMMIT, surface->ec);
}
static void
_e_surface_destroy(surface);
+ ec->comp_data = NULL;
+
TRACE_DS_END();
}
typedef struct _E_Subsurface E_Subsurface;
Eina_Bool e_compositor_init(struct wl_display *display);
+void e_compositor_destroy_listener_add(struct wl_listener *listener);
+void e_compositor_new_surface_listener_add(struct wl_listener *listener);
uint32_t e_compositor_surface_export(E_Surface *surface);
E_Surface *e_compositor_exported_surface_lookup(uint32_t id);
--- /dev/null
+#ifndef E_COMPOSITOR_PRIVATE_H
+#define E_COMPOSITOR_PRIVATE_H
+
+#include "e_compositor_intern.h"
+
+void e_surface_ec_set(E_Surface *surface, E_Client *ec);
+
+#endif
--- /dev/null
+#include "e_log.h"
+#include "e_types.h"
+#include "e_comp_intern.h"
+#include "e_comp_wl_intern.h"
+#include "e_comp_wl_subsurface_intern.h"
+#include "e_comp_wl_rsm_intern.h"
+#include "e_compositor_private.h"
+#include "e_surface_view_intern.h"
+
+#include <stdlib.h>
+#include <wayland-util.h>
+
+#ifdef ESV_ERR
+#undef ESV_ERR
+#endif
+
+#ifdef ESV_INF
+#undef ESV_INF
+#endif
+
+#define ESV_ERR(f, x...) ERR(f, ##x)
+#define ESV_INF(f, ec, x...) ELOGF("SVIEW", f, ec, ##x)
+
+typedef struct
+{
+ struct wl_listener compositor_destroy;
+ struct wl_listener new_surface;
+} E_Surface_View_Module;
+
+struct _E_Surface_View
+{
+ E_Surface *surface;
+ E_Client *ec;
+
+ struct wl_listener surface_destroy;
+};
+
+static E_Surface_View_Module *e_module;
+
+static void
+_surface_view_surface_unset(E_Surface_View *view)
+{
+ wl_list_remove(&view->surface_destroy.link);
+ view->surface = NULL;
+}
+
+static void
+_surface_view_destroy(E_Surface_View *view)
+{
+ ESV_INF("Destroy E_Surface_View(%p)", view->ec, view);
+
+ _surface_view_surface_unset(view);
+ free(view);
+}
+
+static void
+_surface_view_cb_surface_destroy(struct wl_listener *listener, void *data)
+{
+ E_Surface_View *view = wl_container_of(listener, view, surface_destroy);
+
+ _surface_view_destroy(view);
+}
+
+static void
+_surface_view_surface_set(E_Surface_View *view, E_Surface *surface)
+{
+ view->surface = surface;
+
+ view->surface_destroy.notify = _surface_view_cb_surface_destroy;
+ e_surface_destroy_listener_add(surface, &view->surface_destroy);
+}
+
+static E_Client *
+_launchscreen_ec_find(struct wl_resource *surface_resource)
+{
+ E_Client *launchscreen_ec;
+ pid_t pid;
+
+ wl_client_get_credentials(wl_resource_get_client(surface_resource), &pid, NULL, NULL);
+ launchscreen_ec = e_comp_launchscrn_ec_find_by_pid(pid);
+ if (!launchscreen_ec)
+ return NULL;
+
+ assert(launchscreen_ec->comp_data == NULL);
+
+ e_comp_launchscrn_ec_remove(launchscreen_ec);
+
+ return launchscreen_ec;
+}
+
+static void
+_surface_view_ec_set(E_Surface_View *view, E_Client *ec)
+{
+ view->ec = ec;
+ e_surface_ec_set(view->surface, ec);
+
+ ec->argb = EINA_FALSE;
+ ec->redirected = ec->ignored = 1;
+ ec->border_size = 0;
+
+ /* NB: could not find a better place to do this, BUT for internal windows,
+ * we need to set delete_request else the close buttons on the frames do
+ * basically nothing */
+ if (ec->internal)
+ ec->icccm.delete_request = EINA_TRUE;
+}
+
+static void
+_surface_view_launchscreen_ec_reuse(E_Surface_View *view, E_Client *ec, E_Pixmap *pixmap)
+{
+ e_client_pixmap_replace(ec, pixmap);
+
+ ec->internal = 0;
+ _surface_view_ec_set(view, ec);
+ ec->ignored = 0;
+
+ e_comp_wl_client_evas_init(ec);
+
+ ESV_INF("Reuse launchscreen E_Client: pixmap(%p)", ec, ec->pixmap);
+
+ e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_REUSE, ec);
+}
+
+typedef struct
+{
+ E_Surface_View *view;
+ E_Pixmap *pixmap;
+} E_Client_New_Hook_Data;
+
+static E_Client_Hook *e_client_new_hook;
+
+static void
+_surface_view_cb_new_client(void *data, E_Client *ec)
+{
+ E_Client_New_Hook_Data *hook_data = data;
+
+ assert(hook_data->pixmap == ec->pixmap);
+
+ _surface_view_ec_set(hook_data->view, ec);
+
+ E_FREE_FUNC(e_client_new_hook, e_client_hook_del);
+}
+
+static Eina_Bool
+_surface_view_new_ec_add(E_Surface_View *view, E_Pixmap *pixmap)
+{
+ E_Client_New_Hook_Data data = {
+ .view = view,
+ .pixmap = pixmap,
+ };
+ e_client_new_hook = e_client_hook_add(E_CLIENT_HOOK_NEW_CLIENT, _surface_view_cb_new_client, &data);
+
+ return !!e_client_new(pixmap, 0, 0);
+}
+
+static Eina_Bool
+_surface_view_ec_add(E_Surface_View *view)
+{
+ struct wl_resource *surface_resource;
+ E_Pixmap *pixmap;
+ E_Client *ec;
+
+ surface_resource = e_surface_resource_get(view->surface);
+ pixmap = e_pixmap_new(E_PIXMAP_TYPE_WL, surface_resource);
+ if (!pixmap)
+ {
+ ESV_ERR("Could not create new pixmap");
+ return EINA_FALSE;
+ }
+
+ ec = _launchscreen_ec_find(surface_resource);
+ if (ec)
+ {
+ _surface_view_launchscreen_ec_reuse(view, ec, pixmap);
+ return EINA_TRUE;
+ }
+
+ return _surface_view_new_ec_add(view, pixmap);
+}
+
+static void
+_surface_view_ec_init(E_Surface_View *view)
+{
+ E_Client *ec = view->ec;
+ struct wl_resource *surface_resource = e_surface_resource_get(view->surface);
+
+ if (!ec->netwm.pid)
+ wl_client_get_credentials(wl_resource_get_client(surface_resource), &ec->netwm.pid, NULL, NULL);
+
+ if (ec->new_client)
+ e_comp_get()->new_clients--;
+ ec->new_client = 0;
+
+ if ((!ec->client.w) && (!ec->client.h))
+ ec->client.w = ec->client.h = 1;
+
+ e_comp_wl_client_surface_set(ec, surface_resource);
+
+ ec->icccm.accepts_focus = 1;
+}
+
+static E_Surface_View *
+_surface_view_create(E_Surface *surface)
+{
+ E_Surface_View *view;
+
+ view = calloc(1, sizeof(*view));
+ if (!view)
+ return NULL;
+
+ _surface_view_surface_set(view, surface);
+
+ if (!_surface_view_ec_add(view))
+ {
+ ESV_ERR("Failed to add E_Client to E_Surface_View: surface(%p)", surface);
+ _surface_view_surface_unset(view);
+ free(view);
+ return NULL;
+ }
+ _surface_view_ec_init(view);
+
+ ESV_INF("Create E_Surface_View(%p): surface(%p)", e_surface_ec_get(surface), view, surface);
+
+ return view;
+}
+
+static void
+_module_cb_new_surface(struct wl_listener *listener, void *data)
+{
+ E_Surface *surface = data;
+
+ if (!_surface_view_create(surface))
+ ESV_ERR("Failed to create E_Surface_View for E_Surface(%p)", surface);
+}
+
+static void
+_module_cb_compositor_destroy(struct wl_listener *listener, void *data)
+{
+ wl_list_remove(&e_module->compositor_destroy.link);
+ wl_list_remove(&e_module->new_surface.link);
+ E_FREE(e_module);
+}
+
+EINTERN Eina_Bool
+e_surface_view_module_init(struct wl_display *display)
+{
+ E_Surface_View_Module *module;
+
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(e_compositor_init(display), EINA_FALSE);
+
+ if (e_module)
+ return EINA_TRUE;
+
+ module = calloc(1, sizeof(*module));
+ if (!module)
+ return EINA_FALSE;
+
+ module->compositor_destroy.notify = _module_cb_compositor_destroy;
+ e_compositor_destroy_listener_add(&module->compositor_destroy);
+
+ module->new_surface.notify = _module_cb_new_surface;
+ e_compositor_new_surface_listener_add(&module->new_surface);
+
+ e_module = module;
+
+ return EINA_TRUE;
+}
--- /dev/null
+#ifndef E_SURFACE_VIEW_H
+#define E_SURFACE_VIEW_H
+
+#include "e_compositor_intern.h"
+
+typedef struct _E_Surface_View E_Surface_View;
+
+Eina_Bool e_surface_view_module_init(struct wl_display *display);
+
+#endif