diff --git a/src/Makefile_Ecore_Wl2.am b/src/Makefile_Ecore_Wl2.am index 462e8aac06..0dc3dec507 100644 --- a/src/Makefile_Ecore_Wl2.am +++ b/src/Makefile_Ecore_Wl2.am @@ -12,6 +12,7 @@ lib/ecore_wl2/subsurface-client-protocol.h \ lib/ecore_wl2/subsurface-protocol.c \ lib/ecore_wl2/xdg-shell-client-protocol.h \ lib/ecore_wl2/xdg-shell-protocol.c \ +lib/ecore_wl2/ecore_wl2_subsurf.c \ lib/ecore_wl2/ecore_wl2_dnd.c \ lib/ecore_wl2/ecore_wl2_window.c \ lib/ecore_wl2/ecore_wl2_input.c \ diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index 0ebaaa865c..d2fbae53a1 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -28,7 +28,7 @@ /* extern "C" { */ /* # endif */ -typedef struct _Ecore_Wl2_Subsurf Ecore_Wl2_Subsurf; +typedef struct _Ecore_Wl2_Subsurface Ecore_Wl2_Subsurface; # ifndef _ECORE_WL2_WINDOW_PREDEF typedef struct _Ecore_Wl2_Window Ecore_Wl2_Window; @@ -164,6 +164,7 @@ EAPI extern int ECORE_WL2_EVENT_WINDOW_CONFIGURE; * @li @ref Ecore_Wl2_Init_Group * @li @ref Ecore_Wl2_Display_Group * @li @ref Ecore_Wl2_Window_Group + * @li @ref Ecore_Wl2_Subsurface_Group */ /** @@ -573,6 +574,22 @@ EAPI Eina_Bool ecore_wl2_dnd_selection_clear(Ecore_Wl2_Input *input); /* TODO: doxy */ EAPI void ecore_wl2_input_ungrab(Ecore_Wl2_Input *input); +/** + * Create and return a new subsurface. + * + * Create a new surface (and subsurface interface), with the parent surface + * being the one associated with the given @param win. + * + * The @param win must be visible, otherwise there will be no surface created + * for it yet. + * + * @return the allocated and initialized Ecore_Wl2_Subsurface object, or + * NULL on failure + * + * @ingroup Ecore_Wl2_Subsurface_Group + */ +EAPI Ecore_Wl2_Subsurface *ecore_wl2_subsurface_new(Ecore_Wl2_Window *window); + /* # ifdef __cplusplus */ /* } */ /* # endif */ diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h index 34af1e044f..4adf17f0c2 100644 --- a/src/lib/ecore_wl2/ecore_wl2_private.h +++ b/src/lib/ecore_wl2/ecore_wl2_private.h @@ -114,7 +114,7 @@ struct _Ecore_Wl2_Window Eina_Rectangle geometry; Eina_Rectangle opaque; - Eina_Rectangle input; + Eina_Rectangle input_rect; Ecore_Wl2_Window_Type type; @@ -267,4 +267,6 @@ void _ecore_wl2_dnd_drop(Ecore_Wl2_Input *input); void _ecore_wl2_dnd_selection(Ecore_Wl2_Input *input, struct wl_data_offer *offer); void _ecore_wl2_dnd_del(Ecore_Wl2_Dnd_Source *source); +void _ecore_wl2_subsurf_free(Ecore_Wl2_Subsurface *subsurf); + #endif diff --git a/src/lib/ecore_wl2/ecore_wl2_subsurf.c b/src/lib/ecore_wl2/ecore_wl2_subsurf.c new file mode 100644 index 0000000000..90a934364a --- /dev/null +++ b/src/lib/ecore_wl2/ecore_wl2_subsurf.c @@ -0,0 +1,71 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "ecore_wl2_private.h" + +void +_ecore_wl2_subsurf_free(Ecore_Wl2_Subsurface *subsurf) +{ + Ecore_Wl2_Window *parent; + + if (subsurf->wl.subsurface) wl_subsurface_destroy(subsurf->wl.subsurface); + if (subsurf->wl.surface) wl_surface_destroy(subsurf->wl.surface); + + parent = subsurf->parent; + if (parent) + { + parent->subsurfs = + eina_inlist_remove(parent->subsurfs, EINA_INLIST_GET(subsurf)); + } + + free(subsurf); +} + +EAPI Ecore_Wl2_Subsurface * +ecore_wl2_subsurface_new(Ecore_Wl2_Window *window) +{ + Ecore_Wl2_Display *display; + Ecore_Wl2_Subsurface *subsurf; + + EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(window->surface, NULL); + + display = window->display; + + EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.compositor, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.subcompositor, NULL); + + subsurf = calloc(1, sizeof(Ecore_Wl2_Subsurface)); + if (!subsurf) return NULL; + + subsurf->parent = window; + + subsurf->wl.surface = wl_compositor_create_surface(display->wl.compositor); + if (!subsurf->wl.surface) + { + ERR("Failed to create surface: %m"); + goto surf_err; + } + + subsurf->wl.subsurface = + wl_subcompositor_get_subsurface(display->wl.subcompositor, + subsurf->wl.surface, window->surface); + if (!subsurf->wl.subsurface) + { + ERR("Could not create subsurface: %m"); + goto sub_surf_err; + } + + window->subsurfs = + eina_inlist_append(window->subsurfs, EINA_INLIST_GET(subsurf)); + + return subsurf; + +sub_surf_err: + wl_surface_destroy(subsurf->wl.surface); + +surf_err: + free(subsurf); + return NULL; +} diff --git a/src/lib/ecore_wl2/ecore_wl2_window.c b/src/lib/ecore_wl2/ecore_wl2_window.c index 2f4c10af77..71c542557a 100644 --- a/src/lib/ecore_wl2/ecore_wl2_window.c +++ b/src/lib/ecore_wl2/ecore_wl2_window.c @@ -404,6 +404,8 @@ ecore_wl2_window_free(Ecore_Wl2_Window *window) { Ecore_Wl2_Display *display; Ecore_Wl2_Input *input; + Ecore_Wl2_Subsurface *subsurf; + Eina_Inlist *tmp; EINA_SAFETY_ON_NULL_RETURN(window); @@ -425,7 +427,8 @@ ecore_wl2_window_free(Ecore_Wl2_Window *window) if (window->anim_cb) wl_callback_destroy(window->anim_cb); - /* TODO: destroy subsurfaces */ + EINA_INLIST_FOREACH_SAFE(window->subsurfs, tmp, subsurf) + _ecore_wl2_subsurf_free(subsurf); ecore_wl2_window_hide(window); @@ -627,10 +630,10 @@ ecore_wl2_window_input_region_set(Ecore_Wl2_Window *window, int x, int y, int w, EINA_SAFETY_ON_NULL_RETURN(window); - window->input.x = x; - window->input.y = y; - window->input.w = w; - window->input.h = h; + window->input_rect.x = x; + window->input_rect.y = y; + window->input_rect.w = w; + window->input_rect.h = h; if (window->type == ECORE_WL2_WINDOW_TYPE_DND) return;